summaryrefslogtreecommitdiffstats
path: root/plugins/ommail
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/ommail')
-rw-r--r--plugins/ommail/ommail.c191
1 files changed, 102 insertions, 89 deletions
diff --git a/plugins/ommail/ommail.c b/plugins/ommail/ommail.c
index 0a781e10..910b371a 100644
--- a/plugins/ommail/ommail.c
+++ b/plugins/ommail/ommail.c
@@ -13,7 +13,7 @@
*
* File begun on 2008-04-04 by RGerhards
*
- * Copyright 2008-2012 Adiscon GmbH.
+ * Copyright 2008-2013 Adiscon GmbH.
*
* This file is part of rsyslog.
*
@@ -82,13 +82,21 @@ typedef struct _instanceData {
uchar *pszSrvPort;
uchar *pszFrom;
toRcpt_t *lstRcpt;
+ } smtp;
+ } md; /* mode-specific data */
+} instanceData;
+
+typedef struct wrkrInstanceData {
+ instanceData *pData;
+ union {
+ struct {
char RcvBuf[1024]; /* buffer for receiving server responses */
size_t lenRcvBuf;
size_t iRcvBuf; /* current index into the rcvBuf (buf empty if iRcvBuf == lenRcvBuf) */
int sock; /* socket to this server (most important when we do multiple msgs per mail) */
} smtp;
} md; /* mode-specific data */
-} instanceData;
+} wrkrInstanceData_t;
typedef struct configSettings_s {
toRcpt_t *lstRcpt;
@@ -112,7 +120,7 @@ ENDinitConfVars
/* forward definitions (as few as possible) */
static rsRetVal Send(int sock, char *msg, size_t len);
-static rsRetVal readResponse(instanceData *pData, int *piState, int iExpected);
+static rsRetVal readResponse(wrkrInstanceData_t *pWrkrData, int *piState, int iExpected);
/* helpers for handling the recipient lists */
@@ -163,24 +171,22 @@ finalize_it:
* iStatusToCheck < 0 means no checking should happen
*/
static rsRetVal
-WriteRcpts(instanceData *pData, uchar *pszOp, size_t lenOp, int iStatusToCheck)
+WriteRcpts(wrkrInstanceData_t *pWrkrData, uchar *pszOp, size_t lenOp, int iStatusToCheck)
{
toRcpt_t *pRcpt;
int iState;
DEFiRet;
- assert(pData != NULL);
- assert(pszOp != NULL);
assert(lenOp != 0);
- for(pRcpt = pData->md.smtp.lstRcpt ; pRcpt != NULL ; pRcpt = pRcpt->pNext) {
+ for(pRcpt = pWrkrData->pData->md.smtp.lstRcpt ; pRcpt != NULL ; pRcpt = pRcpt->pNext) {
dbgprintf("Sending '%s: <%s>'\n", pszOp, pRcpt->pszTo);
- CHKiRet(Send(pData->md.smtp.sock, (char*)pszOp, lenOp));
- CHKiRet(Send(pData->md.smtp.sock, ":<", sizeof(":<") - 1));
- CHKiRet(Send(pData->md.smtp.sock, (char*)pRcpt->pszTo, strlen((char*)pRcpt->pszTo)));
- CHKiRet(Send(pData->md.smtp.sock, ">\r\n", sizeof(">\r\n") - 1));
+ CHKiRet(Send(pWrkrData->md.smtp.sock, (char*)pszOp, lenOp));
+ CHKiRet(Send(pWrkrData->md.smtp.sock, ":<", sizeof(":<") - 1));
+ CHKiRet(Send(pWrkrData->md.smtp.sock, (char*)pRcpt->pszTo, strlen((char*)pRcpt->pszTo)));
+ CHKiRet(Send(pWrkrData->md.smtp.sock, ">\r\n", sizeof(">\r\n") - 1));
if(iStatusToCheck >= 0)
- CHKiRet(readResponse(pData, &iState, iStatusToCheck));
+ CHKiRet(readResponse(pWrkrData, &iState, iStatusToCheck));
}
finalize_it:
@@ -193,6 +199,11 @@ CODESTARTcreateInstance
ENDcreateInstance
+BEGINcreateWrkrInstance
+CODESTARTcreateWrkrInstance
+ENDcreateWrkrInstance
+
+
BEGINisCompatibleWithFeature
CODESTARTisCompatibleWithFeature
if(eFeat == sFEATURERepeatedMsgReduction)
@@ -203,17 +214,19 @@ ENDisCompatibleWithFeature
BEGINfreeInstance
CODESTARTfreeInstance
if(pData->iMode == 0) {
- if(pData->md.smtp.pszSrv != NULL)
- free(pData->md.smtp.pszSrv);
- if(pData->md.smtp.pszSrvPort != NULL)
- free(pData->md.smtp.pszSrvPort);
- if(pData->md.smtp.pszFrom != NULL)
- free(pData->md.smtp.pszFrom);
+ free(pData->md.smtp.pszSrv);
+ free(pData->md.smtp.pszSrvPort);
+ free(pData->md.smtp.pszFrom);
lstRcptDestruct(pData->md.smtp.lstRcpt);
}
ENDfreeInstance
+BEGINfreeWrkrInstance
+CODESTARTfreeWrkrInstance
+ENDfreeWrkrInstance
+
+
BEGINdbgPrintInstInfo
CODESTARTdbgPrintInstInfo
printf("mail"); /* TODO: extend! */
@@ -229,16 +242,16 @@ ENDdbgPrintInstInfo
* rgerhards, 2008-04-04
*/
static rsRetVal
-getRcvChar(instanceData *pData, char *pC)
+getRcvChar(wrkrInstanceData_t *pWrkrData, char *pC)
{
DEFiRet;
ssize_t lenBuf;
- assert(pData != NULL);
- if(pData->md.smtp.iRcvBuf == pData->md.smtp.lenRcvBuf) { /* buffer empty? */
+ if(pWrkrData->md.smtp.iRcvBuf == pWrkrData->md.smtp.lenRcvBuf) { /* buffer empty? */
/* yes, we need to read the next server response */
do {
- lenBuf = recv(pData->md.smtp.sock, pData->md.smtp.RcvBuf, sizeof(pData->md.smtp.RcvBuf), 0);
+ lenBuf = recv(pWrkrData->md.smtp.sock, pWrkrData->md.smtp.RcvBuf,
+ sizeof(pWrkrData->md.smtp.RcvBuf), 0);
if(lenBuf == 0) {
ABORT_FINALIZE(RS_RET_NO_MORE_DATA);
} else if(lenBuf < 0) {
@@ -247,15 +260,15 @@ getRcvChar(instanceData *pData, char *pC)
}
} else {
/* good read */
- pData->md.smtp.iRcvBuf = 0;
- pData->md.smtp.lenRcvBuf = lenBuf;
+ pWrkrData->md.smtp.iRcvBuf = 0;
+ pWrkrData->md.smtp.lenRcvBuf = lenBuf;
}
} while(lenBuf < 1);
}
/* when we reach this point, we have a non-empty buffer */
- *pC = pData->md.smtp.RcvBuf[pData->md.smtp.iRcvBuf++];
+ *pC = pWrkrData->md.smtp.RcvBuf[pWrkrData->md.smtp.iRcvBuf++];
finalize_it:
RETiRet;
@@ -266,14 +279,14 @@ finalize_it:
* rgerhards, 2008-04-08
*/
static rsRetVal
-serverDisconnect(instanceData *pData)
+serverDisconnect(wrkrInstanceData_t *pWrkrData)
{
DEFiRet;
- assert(pData != NULL);
+ assert(pWrkrData != NULL);
- if(pData->md.smtp.sock != -1) {
- close(pData->md.smtp.sock);
- pData->md.smtp.sock = -1;
+ if(pWrkrData->md.smtp.sock != -1) {
+ close(pWrkrData->md.smtp.sock);
+ pWrkrData->md.smtp.sock = -1;
}
RETiRet;
@@ -284,16 +297,17 @@ serverDisconnect(instanceData *pData)
* rgerhards, 2008-04-04
*/
static rsRetVal
-serverConnect(instanceData *pData)
+serverConnect(wrkrInstanceData_t *pWrkrData)
{
struct addrinfo *res = NULL;
struct addrinfo hints;
char *smtpPort;
char *smtpSrv;
char errStr[1024];
-
+ instanceData *pData;
DEFiRet;
- assert(pData != NULL);
+
+ pData = pWrkrData->pData;
if(pData->md.smtp.pszSrv == NULL)
smtpSrv = "127.0.0.1";
@@ -313,12 +327,12 @@ serverConnect(instanceData *pData)
ABORT_FINALIZE(RS_RET_IO_ERROR);
}
- if((pData->md.smtp.sock = socket(res->ai_family, res->ai_socktype, res->ai_protocol)) == -1) {
+ if((pWrkrData->md.smtp.sock = socket(res->ai_family, res->ai_socktype, res->ai_protocol)) == -1) {
dbgprintf("couldn't create send socket, reason %s", rs_strerror_r(errno, errStr, sizeof(errStr)));
ABORT_FINALIZE(RS_RET_IO_ERROR);
}
- if(connect(pData->md.smtp.sock, res->ai_addr, res->ai_addrlen) != 0) {
+ if(connect(pWrkrData->md.smtp.sock, res->ai_addr, res->ai_addrlen) != 0) {
dbgprintf("create tcp connection failed, reason %s", rs_strerror_r(errno, errStr, sizeof(errStr)));
ABORT_FINALIZE(RS_RET_IO_ERROR);
}
@@ -328,9 +342,9 @@ finalize_it:
freeaddrinfo(res);
if(iRet != RS_RET_OK) {
- if(pData->md.smtp.sock != -1) {
- close(pData->md.smtp.sock);
- pData->md.smtp.sock = -1;
+ if(pWrkrData->md.smtp.sock != -1) {
+ close(pWrkrData->md.smtp.sock);
+ pWrkrData->md.smtp.sock = -1;
}
}
@@ -374,7 +388,7 @@ finalize_it:
* The body is special in that we must escape a leading dot inside a line
*/
static rsRetVal
-bodySend(instanceData *pData, char *msg, size_t len)
+bodySend(wrkrInstanceData_t *pWrkrData, char *msg, size_t len)
{
DEFiRet;
char szBuf[2048];
@@ -383,12 +397,12 @@ bodySend(instanceData *pData, char *msg, size_t len)
int bHadCR = 0;
int bInStartOfLine = 1;
- assert(pData != NULL);
+ assert(pWrkrData != NULL);
assert(msg != NULL);
for(iSrc = 0 ; iSrc < len ; ++iSrc) {
if(iBuf >= sizeof(szBuf) - 1) { /* one is reserved for our extra dot */
- CHKiRet(Send(pData->md.smtp.sock, szBuf, iBuf));
+ CHKiRet(Send(pWrkrData->md.smtp.sock, szBuf, iBuf));
iBuf = 0;
}
szBuf[iBuf++] = msg[iSrc];
@@ -413,7 +427,7 @@ bodySend(instanceData *pData, char *msg, size_t len)
}
if(iBuf > 0) { /* incomplete buffer to send (the *usual* case)? */
- CHKiRet(Send(pData->md.smtp.sock, szBuf, iBuf));
+ CHKiRet(Send(pWrkrData->md.smtp.sock, szBuf, iBuf));
}
finalize_it:
@@ -424,17 +438,17 @@ finalize_it:
/* read response line from server
*/
static rsRetVal
-readResponseLn(instanceData *pData, char *pLn, size_t lenLn)
+readResponseLn(wrkrInstanceData_t *pWrkrData, char *pLn, size_t lenLn)
{
DEFiRet;
size_t i = 0;
char c;
- assert(pData != NULL);
+ assert(pWrkrData != NULL);
assert(pLn != NULL);
do {
- CHKiRet(getRcvChar(pData, &c));
+ CHKiRet(getRcvChar(pWrkrData, &c));
if(c == '\n')
break;
if(i < (lenLn - 1)) /* if line is too long, we simply discard the rest */
@@ -453,18 +467,18 @@ finalize_it:
* rgerhards, 2008-04-07
*/
static rsRetVal
-readResponse(instanceData *pData, int *piState, int iExpected)
+readResponse(wrkrInstanceData_t *pWrkrData, int *piState, int iExpected)
{
DEFiRet;
int bCont;
char buf[128];
- assert(pData != NULL);
+ assert(pWrkrData != NULL);
assert(piState != NULL);
bCont = 1;
do {
- CHKiRet(readResponseLn(pData, buf, sizeof(buf)));
+ CHKiRet(readResponseLn(pWrkrData, buf, sizeof(buf)));
/* note: the code below is not 100% clean as we may have received less than 4 characters.
* However, as we have a fixed size this will not create a vulnerability. An error will
* also most likely be generated, so it is quite acceptable IMHO -- rgerhards, 2008-04-08
@@ -506,64 +520,65 @@ mkSMTPTimestamp(uchar *pszBuf, size_t lenBuf)
* rgerhards, 2008-04-04
*/
static rsRetVal
-sendSMTP(instanceData *pData, uchar *body, uchar *subject)
+sendSMTP(wrkrInstanceData_t *pWrkrData, uchar *body, uchar *subject)
{
DEFiRet;
int iState; /* SMTP state */
+ instanceData *pData;
uchar szDateBuf[64];
- assert(pData != NULL);
+ pData = pWrkrData->pData;
- CHKiRet(serverConnect(pData));
- CHKiRet(readResponse(pData, &iState, 220));
+ CHKiRet(serverConnect(pWrkrData));
+ CHKiRet(readResponse(pWrkrData, &iState, 220));
- CHKiRet(Send(pData->md.smtp.sock, "HELO ", 5));
- CHKiRet(Send(pData->md.smtp.sock, (char*)glbl.GetLocalHostName(), strlen((char*)glbl.GetLocalHostName())));
- CHKiRet(Send(pData->md.smtp.sock, "\r\n", sizeof("\r\n") - 1));
- CHKiRet(readResponse(pData, &iState, 250));
+ CHKiRet(Send(pWrkrData->md.smtp.sock, "HELO ", 5));
+ CHKiRet(Send(pWrkrData->md.smtp.sock, (char*)glbl.GetLocalHostName(), strlen((char*)glbl.GetLocalHostName())));
+ CHKiRet(Send(pWrkrData->md.smtp.sock, "\r\n", sizeof("\r\n") - 1));
+ CHKiRet(readResponse(pWrkrData, &iState, 250));
- CHKiRet(Send(pData->md.smtp.sock, "MAIL FROM:<", sizeof("MAIL FROM:<") - 1));
- CHKiRet(Send(pData->md.smtp.sock, (char*)pData->md.smtp.pszFrom, strlen((char*)pData->md.smtp.pszFrom)));
- CHKiRet(Send(pData->md.smtp.sock, ">\r\n", sizeof(">\r\n") - 1));
- CHKiRet(readResponse(pData, &iState, 250));
+ CHKiRet(Send(pWrkrData->md.smtp.sock, "MAIL FROM:<", sizeof("MAIL FROM:<") - 1));
+ CHKiRet(Send(pWrkrData->md.smtp.sock, (char*)pData->md.smtp.pszFrom, strlen((char*)pData->md.smtp.pszFrom)));
+ CHKiRet(Send(pWrkrData->md.smtp.sock, ">\r\n", sizeof(">\r\n") - 1));
+ CHKiRet(readResponse(pWrkrData, &iState, 250));
- CHKiRet(WriteRcpts(pData, (uchar*)"RCPT TO", sizeof("RCPT TO") - 1, 250));
+ CHKiRet(WriteRcpts(pWrkrData, (uchar*)"RCPT TO", sizeof("RCPT TO") - 1, 250));
- CHKiRet(Send(pData->md.smtp.sock, "DATA\r\n", sizeof("DATA\r\n") - 1));
- CHKiRet(readResponse(pData, &iState, 354));
+ CHKiRet(Send(pWrkrData->md.smtp.sock, "DATA\r\n", sizeof("DATA\r\n") - 1));
+ CHKiRet(readResponse(pWrkrData, &iState, 354));
/* now come the data part */
/* header */
mkSMTPTimestamp(szDateBuf, sizeof(szDateBuf));
- CHKiRet(Send(pData->md.smtp.sock, (char*)szDateBuf, strlen((char*)szDateBuf)));
+ CHKiRet(Send(pWrkrData->md.smtp.sock, (char*)szDateBuf, strlen((char*)szDateBuf)));
- CHKiRet(Send(pData->md.smtp.sock, "From: <", sizeof("From: <") - 1));
- CHKiRet(Send(pData->md.smtp.sock, (char*)pData->md.smtp.pszFrom, strlen((char*)pData->md.smtp.pszFrom)));
- CHKiRet(Send(pData->md.smtp.sock, ">\r\n", sizeof(">\r\n") - 1));
+ CHKiRet(Send(pWrkrData->md.smtp.sock, "From: <", sizeof("From: <") - 1));
+ CHKiRet(Send(pWrkrData->md.smtp.sock, (char*)pData->md.smtp.pszFrom, strlen((char*)pData->md.smtp.pszFrom)));
+ CHKiRet(Send(pWrkrData->md.smtp.sock, ">\r\n", sizeof(">\r\n") - 1));
- CHKiRet(WriteRcpts(pData, (uchar*)"To", sizeof("To") - 1, -1));
+ CHKiRet(WriteRcpts(pWrkrData, (uchar*)"To", sizeof("To") - 1, -1));
- CHKiRet(Send(pData->md.smtp.sock, "Subject: ", sizeof("Subject: ") - 1));
- CHKiRet(Send(pData->md.smtp.sock, (char*)subject, strlen((char*)subject)));
- CHKiRet(Send(pData->md.smtp.sock, "\r\n", sizeof("\r\n") - 1));
+ CHKiRet(Send(pWrkrData->md.smtp.sock, "Subject: ", sizeof("Subject: ") - 1));
+ CHKiRet(Send(pWrkrData->md.smtp.sock, (char*)subject, strlen((char*)subject)));
+ CHKiRet(Send(pWrkrData->md.smtp.sock, "\r\n", sizeof("\r\n") - 1));
- CHKiRet(Send(pData->md.smtp.sock, "X-Mailer: rsyslog-immail\r\n", sizeof("x-mailer: rsyslog-immail\r\n") - 1));
+ CHKiRet(Send(pWrkrData->md.smtp.sock, "X-Mailer: rsyslog-immail\r\n", sizeof("x-mailer: rsyslog-immail\r\n") - 1));
- CHKiRet(Send(pData->md.smtp.sock, "\r\n", sizeof("\r\n") - 1)); /* indicate end of header */
+ CHKiRet(Send(pWrkrData->md.smtp.sock, "\r\n", sizeof("\r\n") - 1)); /* indicate end of header */
/* body */
if(pData->bEnableBody)
- CHKiRet(bodySend(pData, (char*)body, strlen((char*) body)));
+ CHKiRet(bodySend(pWrkrData, (char*)body, strlen((char*) body)));
/* end of data, back to envelope transaction */
- CHKiRet(Send(pData->md.smtp.sock, "\r\n.\r\n", sizeof("\r\n.\r\n") - 1));
- CHKiRet(readResponse(pData, &iState, 250));
+ CHKiRet(Send(pWrkrData->md.smtp.sock, "\r\n.\r\n", sizeof("\r\n.\r\n") - 1));
+ CHKiRet(readResponse(pWrkrData, &iState, 250));
- CHKiRet(Send(pData->md.smtp.sock, "QUIT\r\n", sizeof("QUIT\r\n") - 1));
- CHKiRet(readResponse(pData, &iState, 221));
+ CHKiRet(Send(pWrkrData->md.smtp.sock, "QUIT\r\n", sizeof("QUIT\r\n") - 1));
+ CHKiRet(readResponse(pWrkrData, &iState, 221));
/* we are finished, a new connection is created for each request, so let's close it now */
- CHKiRet(serverDisconnect(pData));
+ CHKiRet(serverDisconnect(pWrkrData));
finalize_it:
RETiRet;
@@ -583,8 +598,8 @@ finalize_it:
*/
BEGINtryResume
CODESTARTtryResume
- CHKiRet(serverConnect(pData));
- CHKiRet(serverDisconnect(pData)); /* if we fail, we will never reach this line */
+ CHKiRet(serverConnect(pWrkrData));
+ CHKiRet(serverDisconnect(pWrkrData)); /* if we fail, we will never reach this line */
finalize_it:
if(iRet == RS_RET_IO_ERROR)
iRet = RS_RET_SUSPENDED;
@@ -593,17 +608,14 @@ ENDtryResume
BEGINdoAction
CODESTARTdoAction
- dbgprintf(" Mail\n");
+ DBGPRINTF(" Mail\n");
- /* forward */
- if(pData->bHaveSubject)
- iRet = sendSMTP(pData, ppString[0], ppString[1]);
- else
- iRet = sendSMTP(pData, ppString[0], (uchar*)"message from rsyslog");
+ iRet = sendSMTP(pWrkrData, ppString[0],
+ (pWrkrData->pData->bHaveSubject) ?
+ ppString[1] : (uchar*)"message from rsyslog");
if(iRet != RS_RET_OK) {
- /* error! */
- dbgprintf("error sending mail, suspending\n");
+ DBGPRINTF("error sending mail, suspending\n");
iRet = RS_RET_SUSPENDED;
}
ENDdoAction
@@ -689,6 +701,7 @@ ENDmodExit
BEGINqueryEtryPt
CODESTARTqueryEtryPt
CODEqueryEtryPt_STD_OMOD_QUERIES
+CODEqueryEtryPt_STD_OMOD8_QUERIES
CODEqueryEtryPt_STD_CONF2_CNFNAME_QUERIES
ENDqueryEtryPt