"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "src/server/core/email.cpp" between
netxms-3.8.382.tar.gz and netxms-3.8.405.tar.gz

About: NetXMS is a multi-platform open source network management and monitoring system.

email.cpp  (netxms-3.8.382):email.cpp  (netxms-3.8.405)
/* /*
** NetXMS - Network Management System ** NetXMS - Network Management System
** Copyright (C) 2003-2019 Victor Kirhenshtein ** Copyright (C) 2003-2021 Victor Kirhenshtein
** **
** This program is free software; you can redistribute it and/or modify ** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by ** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or ** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version. ** (at your option) any later version.
** **
** This program is distributed in the hope that it will be useful, ** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of ** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details. ** GNU General Public License for more details.
skipping to change at line 25 skipping to change at line 25
** You should have received a copy of the GNU General Public License ** You should have received a copy of the GNU General Public License
** along with this program; if not, write to the Free Software ** along with this program; if not, write to the Free Software
** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
** **
** File: email.cpp ** File: email.cpp
** **
**/ **/
#include "nxcore.h" #include "nxcore.h"
#define DEBUG_TAG _T("smtp")
/** /**
* Receive buffer size * Receive buffer size
*/ */
#define SMTP_BUFFER_SIZE 1024 #define SMTP_BUFFER_SIZE 1024
/** /**
* Sender errors * Sender errors
*/ */
#define SMTP_ERR_SUCCESS 0 #define SMTP_ERR_SUCCESS 0
#define SMTP_ERR_BAD_SERVER_NAME 1 #define SMTP_ERR_BAD_SERVER_NAME 1
skipping to change at line 172 skipping to change at line 174
{ {
if (header != NULL) if (header != NULL)
snprintf(buffer, bufferSize, "%s: %s\r\n", header, data); snprintf(buffer, bufferSize, "%s: %s\r\n", header, data);
else else
strlcpy(buffer, data, bufferSize); strlcpy(buffer, data, bufferSize);
} }
return buffer; return buffer;
} }
/** /**
* Send command to server
*/
static inline void SmtpSend(SOCKET hSocket, char *command)
{
SendEx(hSocket, command, strlen(command), 0, nullptr);
char *cr = strchr(command, '\r');
if (cr != nullptr)
*cr = 0;
nxlog_debug_tag(DEBUG_TAG, 8, _T("SMTP SEND: %hs"), command);
}
/**
* Send command to server
*/
static inline void SmtpSend2(SOCKET hSocket, const char *command, const TCHAR *d
isplayText)
{
SendEx(hSocket, command, strlen(command), 0, nullptr);
nxlog_debug_tag(DEBUG_TAG, 8, _T("SMTP SEND: %s"), displayText);
}
/**
* Send e-mail * Send e-mail
*/ */
static UINT32 SendMail(const char *pszRcpt, const char *pszSubject, const char * pszText, const char *encoding, bool isHtml, bool isUtf8) static UINT32 SendMail(const char *pszRcpt, const char *pszSubject, const char * pszText, const char *encoding, bool isHtml, bool isUtf8)
{ {
TCHAR smtpServer[256]; TCHAR smtpServer[256];
char fromName[256], fromAddr[256], localHostName[256]; char fromName[256], fromAddr[256], localHostName[256];
ConfigReadStr(_T("SMTP.Server"), smtpServer, 256, _T("localhost")); ConfigReadStr(_T("SMTP.Server"), smtpServer, 256, _T("localhost"));
ConfigReadStrA(_T("SMTP.FromAddr"), fromAddr, 256, "netxms@localhost"); ConfigReadStrA(_T("SMTP.FromAddr"), fromAddr, 256, "netxms@localhost");
if (isUtf8) if (isUtf8)
{ {
skipping to change at line 219 skipping to change at line 242
SOCKET hSocket = ConnectToHost(addr, smtpPort, 3000); SOCKET hSocket = ConnectToHost(addr, smtpPort, 3000);
if (hSocket == INVALID_SOCKET) if (hSocket == INVALID_SOCKET)
return SMTP_ERR_COMM_FAILURE; return SMTP_ERR_COMM_FAILURE;
char szBuffer[SMTP_BUFFER_SIZE]; char szBuffer[SMTP_BUFFER_SIZE];
size_t nBufPos = 0; size_t nBufPos = 0;
int iState = STATE_INITIAL; int iState = STATE_INITIAL;
while((iState != STATE_FINISHED) && (iState != STATE_ERROR)) while((iState != STATE_FINISHED) && (iState != STATE_ERROR))
{ {
int iResp = GetSMTPResponse(hSocket, szBuffer, &nBufPos); int iResp = GetSMTPResponse(hSocket, szBuffer, &nBufPos);
DbgPrintf(8, _T("SMTP RESPONSE: %03d (state=%d)"), iResp, iState); nxlog_debug_tag(DEBUG_TAG, 8, _T("SMTP RESPONSE: %03d (state=%d)"), iResp, iState);
if (iResp > 0) if (iResp > 0)
{ {
switch(iState) switch(iState)
{ {
case STATE_INITIAL: case STATE_INITIAL:
// Server should send 220 text after connect // Server should send 220 text after connect
if (iResp == 220) if (iResp == 220)
{ {
iState = STATE_HELLO; iState = STATE_HELLO;
char command[280]; char command[280];
snprintf(command, 280, "HELO %s\r\n", localHostName); snprintf(command, 280, "HELO %s\r\n", localHostName);
SendEx(hSocket, command, strlen(command), 0, nullptr); SmtpSend(hSocket, command);
} }
else else
{ {
iState = STATE_ERROR; iState = STATE_ERROR;
} }
break; break;
case STATE_HELLO: case STATE_HELLO:
// Server should respond with 250 text to our HELO command // Server should respond with 250 text to our HELO command
if (iResp == 250) if (iResp == 250)
{ {
iState = STATE_FROM; iState = STATE_FROM;
snprintf(szBuffer, SMTP_BUFFER_SIZE, "MAIL FROM: <%s>\r\n", fr omAddr); snprintf(szBuffer, SMTP_BUFFER_SIZE, "MAIL FROM: <%s>\r\n", fr omAddr);
SendEx(hSocket, szBuffer, strlen(szBuffer), 0, NULL); SmtpSend(hSocket, szBuffer);
} }
else else
{ {
iState = STATE_ERROR; iState = STATE_ERROR;
} }
break; break;
case STATE_FROM: case STATE_FROM:
// Server should respond with 250 text to our MAIL FROM command // Server should respond with 250 text to our MAIL FROM command
if (iResp == 250) if (iResp == 250)
{ {
iState = STATE_RCPT; iState = STATE_RCPT;
snprintf(szBuffer, SMTP_BUFFER_SIZE, "RCPT TO: <%s>\r\n", pszR cpt); snprintf(szBuffer, SMTP_BUFFER_SIZE, "RCPT TO: <%s>\r\n", pszR cpt);
SendEx(hSocket, szBuffer, strlen(szBuffer), 0, NULL); SmtpSend(hSocket, szBuffer);
} }
else else
{ {
iState = STATE_ERROR; iState = STATE_ERROR;
} }
break; break;
case STATE_RCPT: case STATE_RCPT:
// Server should respond with 250 text to our RCPT TO command // Server should respond with 250 text to our RCPT TO command
if (iResp == 250) if (iResp == 250)
{ {
iState = STATE_DATA; iState = STATE_DATA;
SendEx(hSocket, "DATA\r\n", 6, 0, NULL); SmtpSend2(hSocket, "DATA\r\n", _T("DATA"));
} }
else else
{ {
iState = STATE_ERROR; iState = STATE_ERROR;
} }
break; break;
case STATE_DATA: case STATE_DATA:
// Server should respond with 354 text to our DATA command // Server should respond with 354 text to our DATA command
if (iResp == 354) if (iResp == 354)
{ {
iState = STATE_MAIL_BODY; iState = STATE_MAIL_BODY;
// Mail headers // Mail headers
// from // from
char from[512]; char from[512];
snprintf(szBuffer, SMTP_BUFFER_SIZE, "From: \"%s\" <%s>\r\n", EncodeHeader(NULL, encoding, fromName, from, 512), fromAddr); snprintf(szBuffer, SMTP_BUFFER_SIZE, "From: \"%s\" <%s>\r\n", EncodeHeader(NULL, encoding, fromName, from, 512), fromAddr);
SendEx(hSocket, szBuffer, strlen(szBuffer), 0, NULL); SmtpSend(hSocket, szBuffer);
// to // to
snprintf(szBuffer, SMTP_BUFFER_SIZE, "To: <%s>\r\n", pszRcpt); snprintf(szBuffer, SMTP_BUFFER_SIZE, "To: <%s>\r\n", pszRcpt);
SendEx(hSocket, szBuffer, strlen(szBuffer), 0, NULL); SmtpSend(hSocket, szBuffer);
// subject // subject
EncodeHeader("Subject", encoding, pszSubject, szBuffer, SMTP_B UFFER_SIZE); EncodeHeader("Subject", encoding, pszSubject, szBuffer, SMTP_B UFFER_SIZE);
SendEx(hSocket, szBuffer, strlen(szBuffer), 0, NULL); SmtpSend(hSocket, szBuffer);
// date // date
time_t currentTime; time_t currentTime;
struct tm *pCurrentTM; struct tm *pCurrentTM;
time(&currentTime); time(&currentTime);
#ifdef HAVE_LOCALTIME_R #ifdef HAVE_LOCALTIME_R
struct tm currentTM; struct tm currentTM;
localtime_r(&currentTime, &currentTM); localtime_r(&currentTime, &currentTM);
pCurrentTM = &currentTM; pCurrentTM = &currentTM;
#else #else
skipping to change at line 324 skipping to change at line 347
effectiveBias = tzi.Bias + tzi.StandardBias; effectiveBias = tzi.Bias + tzi.StandardBias;
break; break;
case TIME_ZONE_ID_DAYLIGHT: case TIME_ZONE_ID_DAYLIGHT:
effectiveBias = tzi.Bias + tzi.DaylightBias; effectiveBias = tzi.Bias + tzi.DaylightBias;
break; break;
case TIME_ZONE_ID_UNKNOWN: case TIME_ZONE_ID_UNKNOWN:
effectiveBias = tzi.Bias; effectiveBias = tzi.Bias;
break; break;
default: // error default: // error
effectiveBias = 0; effectiveBias = 0;
DbgPrintf(4, _T("GetTimeZoneInformation() call failed")) ; nxlog_debug_tag(DEBUG_TAG, 4, _T("GetTimeZoneInformation () call failed"));
break; break;
} }
int offset = abs(effectiveBias); int offset = abs(effectiveBias);
sprintf(&szBuffer[strlen(szBuffer)], "%c%02d%02d\r\n", effecti veBias <= 0 ? '+' : '-', offset / 60, offset % 60); sprintf(&szBuffer[strlen(szBuffer)], "%c%02d%02d\r\n", effecti veBias <= 0 ? '+' : '-', offset / 60, offset % 60);
#else #else
strftime(szBuffer, sizeof(szBuffer), "Date: %a, %d %b %Y %H:%M :%S %z\r\n", pCurrentTM); strftime(szBuffer, sizeof(szBuffer), "Date: %a, %d %b %Y %H:%M :%S %z\r\n", pCurrentTM);
#endif #endif
SendEx(hSocket, szBuffer, strlen(szBuffer), 0, NULL); SmtpSend(hSocket, szBuffer);
// content-type // content-type
snprintf(szBuffer, SMTP_BUFFER_SIZE, snprintf(szBuffer, SMTP_BUFFER_SIZE,
"Content-Type: text/%s; charset=%s\r\n" "Content-Type: text/%s; charset=%s\r\n"
"Content-Transfer-Encoding: 8bit\r\n\r\n", i sHtml ? "html" : "plain", encoding); "Content-Transfer-Encoding: 8bit\r\n\r\n", i sHtml ? "html" : "plain", encoding);
SendEx(hSocket, szBuffer, strlen(szBuffer), 0, NULL); SendEx(hSocket, szBuffer, strlen(szBuffer), 0, NULL);
// Mail body // Mail body
SendEx(hSocket, pszText, strlen(pszText), 0, NULL); SendEx(hSocket, pszText, strlen(pszText), 0, NULL);
SendEx(hSocket, "\r\n.\r\n", 5, 0, NULL); SendEx(hSocket, "\r\n.\r\n", 5, 0, NULL);
} }
else else
{ {
iState = STATE_ERROR; iState = STATE_ERROR;
} }
break; break;
case STATE_MAIL_BODY: case STATE_MAIL_BODY:
// Server should respond with 250 to our mail body // Server should respond with 250 to our mail body
if (iResp == 250) if (iResp == 250)
{ {
iState = STATE_QUIT; iState = STATE_QUIT;
SendEx(hSocket, "QUIT\r\n", 6, 0, NULL); SmtpSend2(hSocket, "QUIT\r\n", _T("QUIT"));
} }
else else
{ {
iState = STATE_ERROR; iState = STATE_ERROR;
} }
break; break;
case STATE_QUIT: case STATE_QUIT:
// Server should respond with 221 text to our QUIT command // Server should respond with 221 text to our QUIT command
if (iResp == 221) if (iResp == 221)
{ {
skipping to change at line 404 skipping to change at line 427
{ {
static const TCHAR *m_szErrorText[] = static const TCHAR *m_szErrorText[] =
{ {
_T("Sent successfully"), _T("Sent successfully"),
_T("Unable to resolve SMTP server name"), _T("Unable to resolve SMTP server name"),
_T("Communication failure"), _T("Communication failure"),
_T("SMTP conversation failure") _T("SMTP conversation failure")
}; };
ThreadSetName("Mailer"); ThreadSetName("Mailer");
DbgPrintf(1, _T("SMTP mailer thread started")); nxlog_debug_tag(DEBUG_TAG, 1, _T("SMTP mailer thread started"));
while(1) while(1)
{ {
MAIL_ENVELOPE *pEnvelope = s_mailerQueue.getOrBlock(); MAIL_ENVELOPE *pEnvelope = s_mailerQueue.getOrBlock();
if (pEnvelope == INVALID_POINTER_VALUE) if (pEnvelope == INVALID_POINTER_VALUE)
break; break;
nxlog_debug(6, _T("SMTP(%p): new envelope, rcpt=%hs"), pEnvelope, pEnvelope->rcptAddr); nxlog_debug_tag(DEBUG_TAG, 6, _T("SMTP(%p): new envelope, rcpt=%h s"), pEnvelope, pEnvelope->rcptAddr);
UINT32 dwResult = SendMail(pEnvelope->rcptAddr, pEnvelope->subject, pEnvel ope->text, pEnvelope->encoding, pEnvelope->isHtml, pEnvelope->isUtf8); UINT32 dwResult = SendMail(pEnvelope->rcptAddr, pEnvelope->subject, pEnvel ope->text, pEnvelope->encoding, pEnvelope->isHtml, pEnvelope->isUtf8);
if (dwResult != SMTP_ERR_SUCCESS) if (dwResult != SMTP_ERR_SUCCESS)
{ {
pEnvelope->retryCount--; pEnvelope->retryCount--;
DbgPrintf(6, _T("SMTP(%p): Failed to send e-mail, remaini ng retries: %d"), pEnvelope, pEnvelope->retryCount); nxlog_debug_tag(DEBUG_TAG, 6, _T("SMTP(%p): Failed to sen d e-mail, remaining retries: %d"), pEnvelope, pEnvelope->retryCount);
if (pEnvelope->retryCount > 0) if (pEnvelope->retryCount > 0)
{ {
// Try posting again // Try posting again
s_mailerQueue.put(pEnvelope); s_mailerQueue.put(pEnvelope);
} }
else else
{ {
PostSystemEvent(EVENT_SMTP_FAILURE, g_dwMgmtNode, "dsmm", dwResult, PostSystemEvent(EVENT_SMTP_FAILURE, g_dwMgmtNode, "dsmm", dwResult,
m_szErrorText[dwResult], pEnvelope->rcptAddr, pEnvelope->subject); m_szErrorText[dwResult], pEnvelope->rcptAddr, pEnvelope->subject);
MemFree(pEnvelope->text); MemFree(pEnvelope->text);
MemFree(pEnvelope); MemFree(pEnvelope);
} }
} }
else else
{ {
DbgPrintf(6, _T("SMTP(%p): mail sent successfully"), pEnv elope); nxlog_debug_tag(DEBUG_TAG, 6, _T("SMTP(%p): mail sent suc cessfully"), pEnvelope);
MemFree(pEnvelope->text); MemFree(pEnvelope->text);
MemFree(pEnvelope); MemFree(pEnvelope);
} }
} }
return THREAD_OK; return THREAD_OK;
} }
/** /**
* Initialize mailer subsystem * Initialize mailer subsystem
*/ */
 End of changes. 18 change blocks. 
16 lines changed or deleted 40 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)