Filter.cpp
上传用户:woshihumen
上传日期:2013-07-18
资源大小:484k
文件大小:23k
- /*
- * XMail by Davide Libenzi ( Intranet and Internet mail server )
- * Copyright (C) 1999,..,2004 Davide Libenzi
- *
- * 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
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Davide Libenzi <davidel@xmailserver.org>
- *
- */
- #include "SysInclude.h"
- #include "SysDep.h"
- #include "SvrDefines.h"
- #include "SList.h"
- #include "ShBlocks.h"
- #include "StrUtils.h"
- #include "BuffSock.h"
- #include "MiscUtils.h"
- #include "ResLocks.h"
- #include "BuffSock.h"
- #include "SvrUtils.h"
- #include "UsrUtils.h"
- #include "MessQueue.h"
- #include "SMAILUtils.h"
- #include "QueueUtils.h"
- #include "MailDomains.h"
- #include "SMTPUtils.h"
- #include "ExtAliases.h"
- #include "UsrMailList.h"
- #include "Filter.h"
- #include "MailConfig.h"
- #include "AppDefines.h"
- #include "MailSvr.h"
- #define FILTER_LOG_FILE "filters"
- #define FILTER_STORAGE_DIR "filters"
- #define FILTER_SELECT_MAX 128
- #define FILTER_DB_LINE_MAX 512
- #define FILTER_LINE_MAX 1024
- struct FilterMsgInfo {
- char szSender[MAX_ADDR_NAME];
- char szRecipient[MAX_ADDR_NAME];
- SYS_INET_ADDR LocalAddr;
- SYS_INET_ADDR RemoteAddr;
- char szSpoolFile[SYS_MAX_PATH];
- char szAuthName[MAX_ADDR_NAME];
- };
- static int FilLogExec(FilterMsgInfo const &FMI, char const * const *ppszExec,
- int iExecResult, int iExitCode, char const *pszType,
- char const *pszInfo);
- static int FilLoadMsgInfo(SPLF_HANDLE hFSpool, FilterMsgInfo & FMI);
- static void FilFreeMsgInfo(FilterMsgInfo & FMI);
- static int FilGetFilePath(char const *pszMode, char *pszFilePath, int iMaxPath);
- static int FilAddFilter(char **ppszFilters, int &iNumFilters, char const *pszFilterName);
- static int FilSelectFilters(char const *pszFilterFilePath, char const *pszMode,
- FilterMsgInfo const &FMI, char **ppszFilters, int iMaxFilters);
- static void FilFreeFilters(char **ppszFilters, int iNumFilters);
- static int FilGetFilterPath(char const *pszFileName, char *pszFilePath, int iMaxPath);
- static int FilPreExec(FilterMsgInfo const &FMI, FilterTokens *pToks, char **ppszPEError);
- static int FilApplyFilter(char const *pszFilterPath, SPLF_HANDLE hFSpool,
- QUEUE_HANDLE hQueue, QMSG_HANDLE hMessage, FilterMsgInfo const &FMI,
- char const *pszType);
- static int FilFilterMacroSubstitutes(char **ppszCmdTokens, SPLF_HANDLE hFSpool,
- FilterMsgInfo const &FMI);
- int FilLogFilter(FilterLogInfo const *pFLI)
- {
- char szTime[256] = "";
- MscGetTimeNbrString(szTime, sizeof(szTime) - 1);
- RLCK_HANDLE hResLock = RLckLockEX(SVR_LOGS_DIR SYS_SLASH_STR FILTER_LOG_FILE);
- if (hResLock == INVALID_RLCK_HANDLE)
- return (ErrGetErrorCode());
- char szLocIP[128] = "???.???.???.???";
- char szRmtIP[128] = "???.???.???.???";
- MscFileLog(FILTER_LOG_FILE, ""%s""
- "t"%s""
- "t"%s""
- "t"%s""
- "t"%s""
- "t"%s""
- "t"%s""
- "t"%d""
- "t"%d""
- "t"%s""
- "n", pFLI->pszSender, pFLI->pszRecipient, SysInetNToA(pFLI->LocalAddr, szLocIP),
- SysInetNToA(pFLI->RemoteAddr, szRmtIP), szTime, pFLI->pszType, pFLI->pszInfo,
- pFLI->iExecResult, pFLI->iExitCode, pFLI->ppszExec[0]);
- RLckUnlockEX(hResLock);
- return (0);
- }
- static int FilLogExec(FilterMsgInfo const &FMI, char const * const *ppszExec,
- int iExecResult, int iExitCode, char const *pszType,
- char const *pszInfo)
- {
- FilterLogInfo FLI;
- FLI.pszSender = FMI.szSender;
- FLI.pszRecipient = FMI.szRecipient;
- FLI.LocalAddr = FMI.LocalAddr;
- FLI.RemoteAddr = FMI.RemoteAddr;
- FLI.ppszExec = ppszExec;
- FLI.iExecResult = iExecResult;
- FLI.iExitCode = iExitCode;
- FLI.pszType = pszType;
- FLI.pszInfo = pszInfo != NULL ? pszInfo: "";
- return (FilLogFilter(&FLI));
- }
- static int FilLoadMsgInfo(SPLF_HANDLE hFSpool, FilterMsgInfo & FMI)
- {
- UserInfo *pUI;
- char const *const *ppszInfo = USmlGetInfo(hFSpool);
- char const *const *ppszFrom = USmlGetMailFrom(hFSpool);
- char const *const *ppszRcpt = USmlGetRcptTo(hFSpool);
- char const *pszSpoolFile = USmlGetSpoolFilePath(hFSpool);
- int iFromDomains = StrStringsCount(ppszFrom);
- int iRcptDomains = StrStringsCount(ppszRcpt);
- char szUser[MAX_ADDR_NAME] = "";
- char szDomain[MAX_ADDR_NAME] = "";
- ZeroData(FMI);
- if ((iFromDomains > 0) &&
- (USmtpSplitEmailAddr(ppszFrom[iFromDomains - 1], szUser, szDomain) == 0)) {
- if ((pUI = UsrGetUserByNameOrAlias(szDomain, szUser)) != NULL) {
- UsrGetAddress(pUI, FMI.szSender);
- UsrFreeUserInfo(pUI);
- } else
- StrSNCpy(FMI.szSender, ppszFrom[iFromDomains - 1]);
- } else
- SetEmptyString(FMI.szSender);
- if ((iRcptDomains > 0) &&
- (USmtpSplitEmailAddr(ppszRcpt[iRcptDomains - 1], szUser, szDomain) == 0)) {
- if ((pUI = UsrGetUserByNameOrAlias(szDomain, szUser)) != NULL) {
- UsrGetAddress(pUI, FMI.szRecipient);
- UsrFreeUserInfo(pUI);
- } else
- StrSNCpy(FMI.szRecipient, ppszRcpt[iRcptDomains - 1]);
- } else
- SetEmptyString(FMI.szRecipient);
- if ((MscGetServerAddress(ppszInfo[smiServerAddr], FMI.LocalAddr) < 0) ||
- (MscGetServerAddress(ppszInfo[smiClientAddr], FMI.RemoteAddr) < 0))
- return (ErrGetErrorCode());
- StrSNCpy(FMI.szSpoolFile, pszSpoolFile);
- if (USmlMessageAuth(hFSpool, FMI.szAuthName, sizeof(FMI.szAuthName) - 1) < 0)
- SetEmptyString(FMI.szAuthName);
- return (0);
- }
- static void FilFreeMsgInfo(FilterMsgInfo & FMI)
- {
- }
- char *FilGetFilterRejMessage(char const *pszSpoolFile)
- {
- FILE *pFile;
- char szRejFilePath[SYS_MAX_PATH] = "";
- char szRejMsg[512] = "";
- SysSNPrintf(szRejFilePath, sizeof(szRejFilePath) - 1, "%s.rej", pszSpoolFile);
- if ((pFile = fopen(szRejFilePath, "rb")) == NULL)
- return NULL;
- MscFGets(szRejMsg, sizeof(szRejMsg) - 1, pFile);
- fclose(pFile);
- SysRemove(szRejFilePath);
- return (SysStrDup(szRejMsg));
- }
- static int FilGetFilePath(char const *pszMode, char *pszFilePath, int iMaxPath)
- {
- char szMailRootPath[SYS_MAX_PATH] = "";
- CfgGetRootPath(szMailRootPath, sizeof(szMailRootPath));
- SysSNPrintf(pszFilePath, iMaxPath - 1, "%sfilters.%s.tab", szMailRootPath, pszMode);
- return (0);
- }
- static int FilAddFilter(char **ppszFilters, int &iNumFilters, char const *pszFilterName)
- {
- for (int ii = 0; ii < iNumFilters; ii++)
- if (strcmp(ppszFilters[ii], pszFilterName) == 0)
- return (0);
- if ((ppszFilters[iNumFilters] = SysStrDup(pszFilterName)) == NULL)
- return (ErrGetErrorCode());
- iNumFilters++;
- return (0);
- }
- static int FilSelectFilters(char const *pszFilterFilePath, char const *pszMode,
- FilterMsgInfo const &FMI, char **ppszFilters, int iMaxFilters)
- {
- ///////////////////////////////////////////////////////////////////////////////
- // Share lock the filter table file
- ///////////////////////////////////////////////////////////////////////////////
- char szResLock[SYS_MAX_PATH] = "";
- RLCK_HANDLE hResLock = RLckLockSH(CfgGetBasedPath(pszFilterFilePath, szResLock,
- sizeof(szResLock)));
- if (hResLock == INVALID_RLCK_HANDLE)
- return (ErrGetErrorCode());
- ///////////////////////////////////////////////////////////////////////////////
- // Get local and remote IP addresses
- ///////////////////////////////////////////////////////////////////////////////
- NET_ADDRESS LocalAddr;
- NET_ADDRESS RemoteAddr;
- SysGetAddrAddress(FMI.LocalAddr, LocalAddr);
- SysGetAddrAddress(FMI.RemoteAddr, RemoteAddr);
- ///////////////////////////////////////////////////////////////////////////////
- // Open the filter database. Fail smootly if the file does not exist
- ///////////////////////////////////////////////////////////////////////////////
- FILE *pFile = fopen(pszFilterFilePath, "rt");
- if (pFile == NULL) {
- RLckUnlockSH(hResLock);
- return (0);
- }
- int iNumFilters = 0;
- char szLine[FILTER_DB_LINE_MAX] = "";
- while ((iNumFilters < iMaxFilters) &&
- (MscGetConfigLine(szLine, sizeof(szLine) - 1, pFile) != NULL)) {
- char **ppszTokens = StrGetTabLineStrings(szLine);
- if (ppszTokens == NULL)
- continue;
- int iFieldsCount = StrStringsCount(ppszTokens);
- if ((iFieldsCount >= filMax) &&
- StrIWildMatch(FMI.szSender, ppszTokens[filSender]) &&
- StrIWildMatch(FMI.szRecipient, ppszTokens[filRecipient])) {
- AddressFilter AFRemote;
- AddressFilter AFLocal;
- if ((MscLoadAddressFilter(&ppszTokens[filRemoteAddr], 1, AFRemote) == 0)
- && MscAddressMatch(AFRemote, RemoteAddr) &&
- (MscLoadAddressFilter(&ppszTokens[filLocalAddr], 1, AFLocal) == 0) &&
- MscAddressMatch(AFLocal, LocalAddr)) {
- FilAddFilter(ppszFilters, iNumFilters, ppszTokens[filFileName]);
- }
- }
- StrFreeStrings(ppszTokens);
- }
- fclose(pFile);
- RLckUnlockSH(hResLock);
- return (iNumFilters);
- }
- static void FilFreeFilters(char **ppszFilters, int iNumFilters)
- {
- for (iNumFilters--; iNumFilters >= 0; iNumFilters--)
- SysFree(ppszFilters[iNumFilters]);
- }
- static int FilGetFilterPath(char const *pszFileName, char *pszFilePath, int iMaxPath)
- {
- char szMailRootPath[SYS_MAX_PATH] = "";
- CfgGetRootPath(szMailRootPath, sizeof(szMailRootPath));
- SysSNPrintf(pszFilePath, iMaxPath - 1, "%s%s%s%s",
- szMailRootPath, FILTER_STORAGE_DIR, SYS_SLASH_STR, pszFileName);
- return (0);
- }
- int FilExecPreParse(FilterExecCtx *pCtx, char **ppszPEError)
- {
- int i;
- char **ppszEToks;
- char const *pszEx = pCtx->pToks->ppszCmdTokens[0];
- if ((pCtx->pToks->iTokenCount < 1) || (*pszEx != '!'))
- return (0);
- pCtx->pToks->iTokenCount--;
- pCtx->pToks->ppszCmdTokens++;
- if ((ppszEToks = StrTokenize(pszEx + 1, ",")) == NULL)
- return (ErrGetErrorCode());
- for (i = 0; ppszEToks[i] != NULL; i++) {
- char *pszVar = ppszEToks[i], *pszVal;
- if ((pszVal = strchr(pszVar, '=')) != NULL)
- *pszVal++ = ' ';
- if (strcmp(pszVar, "aex") == 0) {
- if (!IsEmptyString(pCtx->pszAuthName)) {
- StrFreeStrings(ppszEToks);
- *ppszPEError = SysStrDup("EXCL");
- return (-1);
- }
- }
- }
- StrFreeStrings(ppszEToks);
- return (0);
- }
- static int FilPreExec(FilterMsgInfo const &FMI, FilterTokens *pToks, char **ppszPEError)
- {
- FilterExecCtx FCtx;
- FCtx.pToks = pToks;
- FCtx.pszAuthName = FMI.szAuthName;
- return (FilExecPreParse(&FCtx, ppszPEError));
- }
- static int FilApplyFilter(char const *pszFilterPath, SPLF_HANDLE hFSpool,
- QUEUE_HANDLE hQueue, QMSG_HANDLE hMessage, FilterMsgInfo const &FMI,
- char const *pszType)
- {
- ///////////////////////////////////////////////////////////////////////////////
- // Share lock the filter file
- ///////////////////////////////////////////////////////////////////////////////
- char szResLock[SYS_MAX_PATH] = "";
- RLCK_HANDLE hResLock = RLckLockSH(CfgGetBasedPath(pszFilterPath, szResLock,
- sizeof(szResLock)));
- if (hResLock == INVALID_RLCK_HANDLE)
- return (ErrGetErrorCode());
- ///////////////////////////////////////////////////////////////////////////////
- // This should not happen but if it happens we let the message pass through
- ///////////////////////////////////////////////////////////////////////////////
- FILE *pFiltFile = fopen(pszFilterPath, "rt");
- if (pFiltFile == NULL) {
- RLckUnlockSH(hResLock);
- return (0);
- }
- ///////////////////////////////////////////////////////////////////////////////
- // Filter this message
- ///////////////////////////////////////////////////////////////////////////////
- char szFiltLine[FILTER_LINE_MAX] = "";
- while (MscGetConfigLine(szFiltLine, sizeof(szFiltLine) - 1, pFiltFile) != NULL) {
- char **ppszCmdTokens = StrGetTabLineStrings(szFiltLine);
- if (ppszCmdTokens == NULL)
- continue;
- int iFieldsCount = StrStringsCount(ppszCmdTokens);
- if (iFieldsCount < 1) {
- StrFreeStrings(ppszCmdTokens);
- continue;
- }
- ///////////////////////////////////////////////////////////////////////////////
- // Perform pre-exec filtering (like exec exclude if authenticated, ...)
- ///////////////////////////////////////////////////////////////////////////////
- char *pszPEError = NULL;
- FilterTokens Toks;
- Toks.ppszCmdTokens = ppszCmdTokens;
- Toks.iTokenCount = iFieldsCount;
- if (FilPreExec(FMI, &Toks, &pszPEError) < 0) {
- if (bFilterLogEnabled)
- FilLogExec(FMI, Toks.ppszCmdTokens, -1,
- -1, pszType, pszPEError);
- if (pszPEError != NULL)
- SysFree(pszPEError);
- StrFreeStrings(ppszCmdTokens);
- continue;
- }
- ///////////////////////////////////////////////////////////////////////////////
- // Do filter line macro substitution
- ///////////////////////////////////////////////////////////////////////////////
- FilFilterMacroSubstitutes(Toks.ppszCmdTokens, hFSpool, FMI);
- ///////////////////////////////////////////////////////////////////////////////
- // Time to fire the external executable ...
- ///////////////////////////////////////////////////////////////////////////////
- int iExitCode = -1;
- int iExitFlags = 0;
- int iExecResult = SysExec(Toks.ppszCmdTokens[0], &Toks.ppszCmdTokens[0],
- iFilterTimeout, FILTER_PRIORITY, &iExitCode);
- ///////////////////////////////////////////////////////////////////////////////
- // Log the operation, if requested.
- ///////////////////////////////////////////////////////////////////////////////
- if (bFilterLogEnabled)
- FilLogExec(FMI, Toks.ppszCmdTokens, iExecResult,
- iExitCode, pszType, NULL);
- if (iExecResult == 0) {
- SysLogMessage(LOG_LEV_MESSAGE,
- "Filter run: Sender = "%s" Recipient = "%s" Filter = "%s" Retcode = %dn",
- FMI.szSender, FMI.szRecipient, Toks.ppszCmdTokens[0],
- iExitCode);
- ///////////////////////////////////////////////////////////////////////////////
- // Separate code from flags
- ///////////////////////////////////////////////////////////////////////////////
- iExitFlags = iExitCode & FILTER_FLAGS_MASK;
- iExitCode &= ~FILTER_FLAGS_MASK;
- if ((iExitCode == FILTER_OUT_EXITCODE) ||
- (iExitCode == FILTER_OUT_NN_EXITCODE) ||
- (iExitCode == FILTER_OUT_NNF_EXITCODE)) {
- fclose(pFiltFile);
- RLckUnlockSH(hResLock);
- ///////////////////////////////////////////////////////////////////////////////
- // Filter out message
- ///////////////////////////////////////////////////////////////////////////////
- char *pszRejMsg = FilGetFilterRejMessage(FMI.szSpoolFile);
- if (iExitCode == FILTER_OUT_EXITCODE)
- QueUtNotifyPermErrDelivery(hQueue, hMessage, NULL,
- (pszRejMsg !=
- NULL) ? pszRejMsg :
- ErrGetErrorString
- (ERR_FILTERED_MESSAGE),
- NULL, true);
- else if (iExitCode == FILTER_OUT_NN_EXITCODE)
- QueCleanupMessage(hQueue, hMessage,
- !QueUtRemoveSpoolErrors());
- else
- QueCleanupMessage(hQueue, hMessage, false);
- StrFreeStrings(ppszCmdTokens);
- if (pszRejMsg != NULL)
- SysFree(pszRejMsg);
- ErrSetErrorCode(ERR_FILTERED_MESSAGE);
- return (ERR_FILTERED_MESSAGE);
- } else if (iExitCode == FILTER_MODIFY_EXITCODE) {
- ///////////////////////////////////////////////////////////////////////////////
- // Filter modified the message, we need to reload the spool handle
- ///////////////////////////////////////////////////////////////////////////////
- if (USmlReloadHandle(hFSpool) < 0) {
- ErrorPush();
- fclose(pFiltFile);
- RLckUnlockSH(hResLock);
- SysLogMessage(LOG_LEV_MESSAGE,
- "Filter error [ Modified message corrupted ]: Sender = "%s" Recipient = "%s" (%s)n",
- FMI.szSender, FMI.szRecipient,
- Toks.ppszCmdTokens[0]);
- QueUtErrLogMessage(hQueue, hMessage,
- "Filter error [ Modified message corrupted ]: Sender = "%s" Recipient = "%s" (%s)n",
- FMI.szSender, FMI.szRecipient,
- Toks.ppszCmdTokens[0]);
- QueCleanupMessage(hQueue, hMessage, true);
- StrFreeStrings(ppszCmdTokens);
- return (ErrorPop());
- }
- }
- } else {
- SysLogMessage(LOG_LEV_ERROR,
- "Filter error (%d): Sender = "%s" Recipient = "%s" Filter = "%s"n",
- iExecResult, FMI.szSender, FMI.szRecipient,
- Toks.ppszCmdTokens[0]);
- QueUtErrLogMessage(hQueue, hMessage,
- "Filter error (%d): Sender = "%s" Recipient = "%s" Filter = "%s"n",
- iExecResult, FMI.szSender, FMI.szRecipient,
- Toks.ppszCmdTokens[0]);
- }
- StrFreeStrings(ppszCmdTokens);
- ///////////////////////////////////////////////////////////////////////////////
- // Filter list processing break required ?
- ///////////////////////////////////////////////////////////////////////////////
- if (iExitFlags & FILTER_FLAGS_BREAK) {
- fclose(pFiltFile);
- RLckUnlockSH(hResLock);
- return (1);
- }
- }
- fclose(pFiltFile);
- RLckUnlockSH(hResLock);
- return (0);
- }
- int FilFilterMessage(SPLF_HANDLE hFSpool, QUEUE_HANDLE hQueue,
- QMSG_HANDLE hMessage, char const *pszMode)
- {
- ///////////////////////////////////////////////////////////////////////////////
- // Get filter file path and returns immediately if no file is defined
- ///////////////////////////////////////////////////////////////////////////////
- char szFilterFilePath[SYS_MAX_PATH] = "";
- FilGetFilePath(pszMode, szFilterFilePath, sizeof(szFilterFilePath));
- if (!SysExistFile(szFilterFilePath))
- return (0);
- ///////////////////////////////////////////////////////////////////////////////
- // Load the message info
- ///////////////////////////////////////////////////////////////////////////////
- FilterMsgInfo FMI;
- if (FilLoadMsgInfo(hFSpool, FMI) < 0)
- return (ErrGetErrorCode());
- ///////////////////////////////////////////////////////////////////////////////
- // Select applicable filters
- ///////////////////////////////////////////////////////////////////////////////
- int iNumFilters;
- char *pszFilters[FILTER_SELECT_MAX];
- if ((iNumFilters = FilSelectFilters(szFilterFilePath, pszMode, FMI, pszFilters,
- CountOf(pszFilters))) < 0) {
- ErrorPush();
- FilFreeMsgInfo(FMI);
- return (ErrorPop());
- }
- ///////////////////////////////////////////////////////////////////////////////
- // Sequentially apply each selected filter
- ///////////////////////////////////////////////////////////////////////////////
- for (int ii = 0; ii < iNumFilters; ii++) {
- int iFilterResult;
- char szFilterPath[SYS_MAX_PATH] = "";
- FilGetFilterPath(pszFilters[ii], szFilterPath, sizeof(szFilterPath));
- if ((iFilterResult =
- FilApplyFilter(szFilterPath, hFSpool, hQueue, hMessage,
- FMI, pszMode)) < 0) {
- ErrorPush();
- FilFreeFilters(pszFilters, iNumFilters);
- FilFreeMsgInfo(FMI);
- return (ErrorPop());
- }
- ///////////////////////////////////////////////////////////////////////////////
- // A return code greater than zero means exit filter processing loop soon
- ///////////////////////////////////////////////////////////////////////////////
- if (iFilterResult > 0)
- break;
- }
- FilFreeFilters(pszFilters, iNumFilters);
- FilFreeMsgInfo(FMI);
- return (0);
- }
- static int FilFilterMacroSubstitutes(char **ppszCmdTokens, SPLF_HANDLE hFSpool,
- FilterMsgInfo const &FMI)
- {
- char const *const *ppszInfo = USmlGetInfo(hFSpool);
- char const *pszSMTPDomain = USmlGetSMTPDomain(hFSpool);
- char const *const *ppszFrom = USmlGetMailFrom(hFSpool);
- char const *const *ppszRcpt = USmlGetRcptTo(hFSpool);
- char const *pszSmtpMessageID = USmlGetSmtpMessageID(hFSpool);
- char const *pszMessageID = USmlGetSpoolFile(hFSpool);
- int iFromDomains = StrStringsCount(ppszFrom);
- int iRcptDomains = StrStringsCount(ppszRcpt);
- FileSection FS;
- ///////////////////////////////////////////////////////////////////////////////
- // This function retrieve the spool file message section and sync the content.
- // This is necessary before passing the file name to external programs
- ///////////////////////////////////////////////////////////////////////////////
- if (USmlGetMsgFileSection(hFSpool, FS) < 0)
- return (ErrGetErrorCode());
- for (int ii = 0; ppszCmdTokens[ii] != NULL; ii++) {
- if (strcmp(ppszCmdTokens[ii], "@@FROM") == 0) {
- char *pszNewValue =
- SysStrDup((iFromDomains > 0) ? ppszFrom[iFromDomains - 1] : "");
- if (pszNewValue == NULL)
- return (ErrGetErrorCode());
- SysFree(ppszCmdTokens[ii]);
- ppszCmdTokens[ii] = pszNewValue;
- } else if (strcmp(ppszCmdTokens[ii], "@@RCPT") == 0) {
- char *pszNewValue =
- SysStrDup((iRcptDomains > 0) ? ppszRcpt[iRcptDomains - 1] : "");
- if (pszNewValue == NULL)
- return (ErrGetErrorCode());
- SysFree(ppszCmdTokens[ii]);
- ppszCmdTokens[ii] = pszNewValue;
- } else if (strcmp(ppszCmdTokens[ii], "@@RFROM") == 0) {
- char *pszNewValue = SysStrDup(FMI.szSender);
- if (pszNewValue == NULL)
- return (ErrGetErrorCode());
- SysFree(ppszCmdTokens[ii]);
- ppszCmdTokens[ii] = pszNewValue;
- } else if (strcmp(ppszCmdTokens[ii], "@@RRCPT") == 0) {
- char *pszNewValue = SysStrDup(FMI.szRecipient);
- if (pszNewValue == NULL)
- return (ErrGetErrorCode());
- SysFree(ppszCmdTokens[ii]);
- ppszCmdTokens[ii] = pszNewValue;
- } else if (strcmp(ppszCmdTokens[ii], "@@FILE") == 0) {
- char *pszNewValue = SysStrDup(FS.szFilePath);
- if (pszNewValue == NULL)
- return (ErrGetErrorCode());
- SysFree(ppszCmdTokens[ii]);
- ppszCmdTokens[ii] = pszNewValue;
- } else if (strcmp(ppszCmdTokens[ii], "@@MSGID") == 0) {
- char *pszNewValue = SysStrDup(pszMessageID);
- if (pszNewValue == NULL)
- return (ErrGetErrorCode());
- SysFree(ppszCmdTokens[ii]);
- ppszCmdTokens[ii] = pszNewValue;
- } else if (strcmp(ppszCmdTokens[ii], "@@MSGREF") == 0) {
- char *pszNewValue = SysStrDup(pszSmtpMessageID);
- if (pszNewValue == NULL)
- return (ErrGetErrorCode());
- SysFree(ppszCmdTokens[ii]);
- ppszCmdTokens[ii] = pszNewValue;
- } else if (strcmp(ppszCmdTokens[ii], "@@LOCALADDR") == 0) {
- char *pszNewValue = SysStrDup(ppszInfo[smiServerAddr]);
- if (pszNewValue == NULL)
- return (ErrGetErrorCode());
- SysFree(ppszCmdTokens[ii]);
- ppszCmdTokens[ii] = pszNewValue;
- } else if (strcmp(ppszCmdTokens[ii], "@@REMOTEADDR") == 0) {
- char *pszNewValue = SysStrDup(ppszInfo[smiClientAddr]);
- if (pszNewValue == NULL)
- return (ErrGetErrorCode());
- SysFree(ppszCmdTokens[ii]);
- ppszCmdTokens[ii] = pszNewValue;
- } else if (strcmp(ppszCmdTokens[ii], "@@USERAUTH") == 0) {
- char *pszNewValue = SysStrDup(IsEmptyString(FMI.szAuthName) ? "-":
- FMI.szAuthName);
- if (pszNewValue == NULL)
- return (ErrGetErrorCode());
- SysFree(ppszCmdTokens[ii]);
- ppszCmdTokens[ii] = pszNewValue;
- }
- }
- return (0);
- }