www.gusucode.com > VC++版的邮件服务器源程序源码程序 > VC++版的邮件服务器源程序源码程序\code\AliasDomain.cpp
/* * 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. * Download by http://www.NewXing.com * 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 "ShBlocks.h" #include "ResLocks.h" #include "StrUtils.h" #include "SList.h" #include "BuffSock.h" #include "MailConfig.h" #include "MessQueue.h" #include "MailSvr.h" #include "MiscUtils.h" #include "SvrUtils.h" #include "POP3GwLink.h" #include "ExtAliases.h" #include "UsrUtils.h" #include "UsrAuth.h" #include "TabIndex.h" #include "MailDomains.h" #include "AliasDomain.h" #define ADOMAIN_FILE "aliasdomain.tab" #define WILD_ADOMAIN_HASH 0 #define ADOMAIN_LINE_MAX 512 struct ADomainScanData { char szTmpDBFile[SYS_MAX_PATH]; FILE *pDBFile; char **ppszStrings; }; static bool ADomIsWildAlias(char const *pszAlias); static int ADomCalcAliasHash(char const *const *ppszTabTokens, int const *piFieldsIdx, SYS_UINT32 * puHashVal, bool bCaseSens); static int ADomRebuildADomainIndexes(char const *pszADomainFilePath); static char *ADomGetADomainFilePath(char *pszADomainFilePath, int iMaxPath); static int ADomLookupDomainLK(const char *pszADomainFilePath, const char *pszADomain, char *pszDomain, bool bWildMatch); static int iIdxADomain_Alias[] = { adomADomain, INDEX_SEQUENCE_TERMINATOR }; static bool ADomIsWildAlias(char const *pszAlias) { return ((strchr(pszAlias, '*') != NULL) || (strchr(pszAlias, '?') != NULL)); } static int ADomCalcAliasHash(char const *const *ppszTabTokens, int const *piFieldsIdx, SYS_UINT32 * puHashVal, bool bCaseSens) { /////////////////////////////////////////////////////////////////////////////// // This will group wild alias ( * ? ) /////////////////////////////////////////////////////////////////////////////// int iFieldsCount = StrStringsCount(ppszTabTokens); if ((iFieldsCount > adomADomain) && ADomIsWildAlias(ppszTabTokens[adomADomain])) { *puHashVal = WILD_ADOMAIN_HASH; return (0); } return (TbixCalculateHash(ppszTabTokens, piFieldsIdx, puHashVal, bCaseSens)); } int ADomCheckDomainsIndexes(void) { char szADomainFilePath[SYS_MAX_PATH] = ""; ADomGetADomainFilePath(szADomainFilePath, sizeof(szADomainFilePath)); /////////////////////////////////////////////////////////////////////////////// // Align RmtDomain-RmtName index /////////////////////////////////////////////////////////////////////////////// if (TbixCheckIndex(szADomainFilePath, iIdxADomain_Alias, false, ADomCalcAliasHash) < 0) return (ErrGetErrorCode()); return (0); } static int ADomRebuildADomainIndexes(char const *pszADomainFilePath) { /////////////////////////////////////////////////////////////////////////////// // Rebuild RmtDomain-RmtName index /////////////////////////////////////////////////////////////////////////////// if (TbixCreateIndex(pszADomainFilePath, iIdxADomain_Alias, false, ADomCalcAliasHash) < 0) return (ErrGetErrorCode()); return (0); } static char *ADomGetADomainFilePath(char *pszADomainFilePath, int iMaxPath) { CfgGetRootPath(pszADomainFilePath, iMaxPath); StrNCat(pszADomainFilePath, ADOMAIN_FILE, iMaxPath); return (pszADomainFilePath); } static int ADomLookupDomainLK(const char *pszADomainFilePath, const char *pszADomain, char *pszDomain, bool bWildMatch) { /////////////////////////////////////////////////////////////////////////////// // Lookup record using the specified index ( lookup precise aliases ) /////////////////////////////////////////////////////////////////////////////// char **ppszTabTokens = TbixLookup(pszADomainFilePath, iIdxADomain_Alias, false, pszADomain, NULL); if (ppszTabTokens != NULL) { if (pszDomain != NULL) StrNCpy(pszDomain, ppszTabTokens[adomDomain], MAX_HOST_NAME); StrFreeStrings(ppszTabTokens); return (1); } /////////////////////////////////////////////////////////////////////////////// // We can stop here if wild alias matching is not required /////////////////////////////////////////////////////////////////////////////// if (!bWildMatch) return (0); /////////////////////////////////////////////////////////////////////////////// // Lookup record using the specified index ( lookup wild aliases grouped // under WILD_ADOMAIN_HASH hash key ) /////////////////////////////////////////////////////////////////////////////// INDEX_HANDLE hIndexLookup = TbixOpenHandle(pszADomainFilePath, iIdxADomain_Alias, WILD_ADOMAIN_HASH); if (hIndexLookup != INVALID_INDEX_HANDLE) { int iNumRecords = TbixLookedUpRecords(hIndexLookup); for (int ii = 0; ii < iNumRecords; ii++) { char **ppszTabTokens = TbixGetRecord(hIndexLookup, ii); if (ppszTabTokens == NULL) continue; int iFieldsCount = StrStringsCount(ppszTabTokens); if ((iFieldsCount >= adomMax) && StrIWildMatch(pszADomain, ppszTabTokens[adomADomain])) { if (pszDomain != NULL) StrNCpy(pszDomain, ppszTabTokens[adomDomain], MAX_HOST_NAME); StrFreeStrings(ppszTabTokens); TbixCloseHandle(hIndexLookup); return (1); } StrFreeStrings(ppszTabTokens); } TbixCloseHandle(hIndexLookup); } return (0); } int ADomLookupDomain(const char *pszADomain, char *pszDomain, bool bWildMatch) { char szADomainFilePath[SYS_MAX_PATH] = ""; ADomGetADomainFilePath(szADomainFilePath, sizeof(szADomainFilePath)); char szResLock[SYS_MAX_PATH] = ""; RLCK_HANDLE hResLock = RLckLockSH(CfgGetBasedPath(szADomainFilePath, szResLock, sizeof(szResLock))); if (hResLock == INVALID_RLCK_HANDLE) return (0); int iLookupResult = ADomLookupDomainLK(szADomainFilePath, pszADomain, pszDomain, bWildMatch); RLckUnlockSH(hResLock); return (iLookupResult); } int ADomAddADomain(char const *pszADomain, char const *pszDomain) { char szADomainFilePath[SYS_MAX_PATH] = ""; ADomGetADomainFilePath(szADomainFilePath, sizeof(szADomainFilePath)); char szResLock[SYS_MAX_PATH] = ""; RLCK_HANDLE hResLock = RLckLockEX(CfgGetBasedPath(szADomainFilePath, szResLock, sizeof(szResLock))); if (hResLock == INVALID_RLCK_HANDLE) return (ErrGetErrorCode()); FILE *pDomainsFile = fopen(szADomainFilePath, "r+t"); if (pDomainsFile == NULL) { RLckUnlockEX(hResLock); ErrSetErrorCode(ERR_ADOMAIN_FILE_NOT_FOUND); return (ERR_ADOMAIN_FILE_NOT_FOUND); } char szADomainLine[ADOMAIN_LINE_MAX] = ""; while (MscFGets(szADomainLine, sizeof(szADomainLine) - 1, pDomainsFile) != NULL) { char **ppszStrings = StrGetTabLineStrings(szADomainLine); if (ppszStrings == NULL) continue; int iFieldsCount = StrStringsCount(ppszStrings); if ((iFieldsCount >= adomMax) && (stricmp(pszADomain, ppszStrings[adomADomain]) == 0)) { StrFreeStrings(ppszStrings); fclose(pDomainsFile); RLckUnlockEX(hResLock); ErrSetErrorCode(ERR_ADOMAIN_EXIST); return (ERR_ADOMAIN_EXIST); } StrFreeStrings(ppszStrings); } fseek(pDomainsFile, 0, SEEK_END); fprintf(pDomainsFile, "\"%s\"\t\"%s\"\n", pszADomain, pszDomain); fclose(pDomainsFile); /////////////////////////////////////////////////////////////////////////////// // Rebuild indexes /////////////////////////////////////////////////////////////////////////////// if (ADomRebuildADomainIndexes(szADomainFilePath) < 0) { ErrorPush(); RLckUnlockEX(hResLock); return (ErrorPop()); } RLckUnlockEX(hResLock); return (0); } int ADomRemoveADomain(char const *pszADomain) { char szADomainFilePath[SYS_MAX_PATH] = ""; ADomGetADomainFilePath(szADomainFilePath, sizeof(szADomainFilePath)); char szTmpFile[SYS_MAX_PATH] = ""; SysGetTmpFile(szTmpFile); char szResLock[SYS_MAX_PATH] = ""; RLCK_HANDLE hResLock = RLckLockEX(CfgGetBasedPath(szADomainFilePath, szResLock, sizeof(szResLock))); if (hResLock == INVALID_RLCK_HANDLE) { ErrorPush(); CheckRemoveFile(szTmpFile); return (ErrorPop()); } FILE *pDomainsFile = fopen(szADomainFilePath, "rt"); if (pDomainsFile == NULL) { RLckUnlockEX(hResLock); CheckRemoveFile(szTmpFile); ErrSetErrorCode(ERR_ADOMAIN_FILE_NOT_FOUND); return (ERR_ADOMAIN_FILE_NOT_FOUND); } FILE *pTmpFile = fopen(szTmpFile, "wt"); if (pTmpFile == NULL) { fclose(pDomainsFile); RLckUnlockEX(hResLock); CheckRemoveFile(szTmpFile); ErrSetErrorCode(ERR_FILE_CREATE, szTmpFile); return (ERR_FILE_CREATE); } int iADomainFound = 0; char szADomainLine[ADOMAIN_LINE_MAX] = ""; while (MscFGets(szADomainLine, sizeof(szADomainLine) - 1, pDomainsFile) != NULL) { char **ppszStrings = StrGetTabLineStrings(szADomainLine); if (ppszStrings == NULL) continue; int iFieldsCount = StrStringsCount(ppszStrings); if ((iFieldsCount >= adomMax) && (stricmp(pszADomain, ppszStrings[adomADomain]) == 0)) { ++iADomainFound; } else fprintf(pTmpFile, "%s\n", szADomainLine); StrFreeStrings(ppszStrings); } fclose(pDomainsFile); fclose(pTmpFile); if (iADomainFound == 0) { SysRemove(szTmpFile); RLckUnlockEX(hResLock); ErrSetErrorCode(ERR_ADOMAIN_NOT_FOUND); return (ERR_ADOMAIN_NOT_FOUND); } char szTmpADomainFilePath[SYS_MAX_PATH] = ""; sprintf(szTmpADomainFilePath, "%s.tmp", szADomainFilePath); if (MscMoveFile(szADomainFilePath, szTmpADomainFilePath) < 0) { ErrorPush(); RLckUnlockEX(hResLock); return (ErrorPop()); } if (MscMoveFile(szTmpFile, szADomainFilePath) < 0) { ErrorPush(); MscMoveFile(szTmpADomainFilePath, szADomainFilePath); RLckUnlockEX(hResLock); return (ErrorPop()); } SysRemove(szTmpADomainFilePath); /////////////////////////////////////////////////////////////////////////////// // Rebuild indexes /////////////////////////////////////////////////////////////////////////////// if (ADomRebuildADomainIndexes(szADomainFilePath) < 0) { ErrorPush(); RLckUnlockEX(hResLock); return (ErrorPop()); } RLckUnlockEX(hResLock); return (0); } int ADomRemoveLinkedDomains(char const *pszDomain) { char szADomainFilePath[SYS_MAX_PATH] = ""; ADomGetADomainFilePath(szADomainFilePath, sizeof(szADomainFilePath)); char szTmpFile[SYS_MAX_PATH] = ""; SysGetTmpFile(szTmpFile); char szResLock[SYS_MAX_PATH] = ""; RLCK_HANDLE hResLock = RLckLockEX(CfgGetBasedPath(szADomainFilePath, szResLock, sizeof(szResLock))); if (hResLock == INVALID_RLCK_HANDLE) { ErrorPush(); CheckRemoveFile(szTmpFile); return (ErrorPop()); } FILE *pDomainsFile = fopen(szADomainFilePath, "rt"); if (pDomainsFile == NULL) { RLckUnlockEX(hResLock); CheckRemoveFile(szTmpFile); ErrSetErrorCode(ERR_ADOMAIN_FILE_NOT_FOUND); return (ERR_ADOMAIN_FILE_NOT_FOUND); } FILE *pTmpFile = fopen(szTmpFile, "wt"); if (pTmpFile == NULL) { fclose(pDomainsFile); RLckUnlockEX(hResLock); CheckRemoveFile(szTmpFile); ErrSetErrorCode(ERR_FILE_CREATE, szTmpFile); return (ERR_FILE_CREATE); } int iDomainFound = 0; char szADomainLine[ADOMAIN_LINE_MAX] = ""; while (MscFGets(szADomainLine, sizeof(szADomainLine) - 1, pDomainsFile) != NULL) { char **ppszStrings = StrGetTabLineStrings(szADomainLine); if (ppszStrings == NULL) continue; int iFieldsCount = StrStringsCount(ppszStrings); if ((iFieldsCount >= adomMax) && (stricmp(pszDomain, ppszStrings[adomDomain]) == 0)) { ++iDomainFound; } else fprintf(pTmpFile, "%s\n", szADomainLine); StrFreeStrings(ppszStrings); } fclose(pDomainsFile); fclose(pTmpFile); if (iDomainFound == 0) { SysRemove(szTmpFile); RLckUnlockEX(hResLock); return (0); } char szTmpADomainFilePath[SYS_MAX_PATH] = ""; sprintf(szTmpADomainFilePath, "%s.tmp", szADomainFilePath); if (MscMoveFile(szADomainFilePath, szTmpADomainFilePath) < 0) { ErrorPush(); RLckUnlockEX(hResLock); return (ErrorPop()); } if (MscMoveFile(szTmpFile, szADomainFilePath) < 0) { ErrorPush(); MscMoveFile(szTmpADomainFilePath, szADomainFilePath); RLckUnlockEX(hResLock); return (ErrorPop()); } SysRemove(szTmpADomainFilePath); /////////////////////////////////////////////////////////////////////////////// // Rebuild indexes /////////////////////////////////////////////////////////////////////////////// if (ADomRebuildADomainIndexes(szADomainFilePath) < 0) { ErrorPush(); RLckUnlockEX(hResLock); return (ErrorPop()); } RLckUnlockEX(hResLock); return (0); } int ADomGetADomainFileSnapShot(const char *pszFileName) { char szADomainFilePath[SYS_MAX_PATH] = ""; ADomGetADomainFilePath(szADomainFilePath, sizeof(szADomainFilePath)); char szResLock[SYS_MAX_PATH] = ""; RLCK_HANDLE hResLock = RLckLockSH(CfgGetBasedPath(szADomainFilePath, szResLock, sizeof(szResLock))); if (hResLock == INVALID_RLCK_HANDLE) return (ErrGetErrorCode()); if (MscCopyFile(pszFileName, szADomainFilePath) < 0) { ErrorPush(); RLckUnlockSH(hResLock); return (ErrorPop()); } RLckUnlockSH(hResLock); return (0); } ADOMAIN_HANDLE ADomOpenDB(void) { ADomainScanData *pDSD = (ADomainScanData *) SysAlloc(sizeof(ADomainScanData)); if (pDSD == NULL) return (INVALID_ADOMAIN_HANDLE); SysGetTmpFile(pDSD->szTmpDBFile); if (ADomGetADomainFileSnapShot(pDSD->szTmpDBFile) < 0) { CheckRemoveFile(pDSD->szTmpDBFile); SysFree(pDSD); return (INVALID_ADOMAIN_HANDLE); } if ((pDSD->pDBFile = fopen(pDSD->szTmpDBFile, "rt")) == NULL) { SysRemove(pDSD->szTmpDBFile); SysFree(pDSD); return (INVALID_ADOMAIN_HANDLE); } pDSD->ppszStrings = NULL; return ((ADOMAIN_HANDLE) pDSD); } void ADomCloseDB(ADOMAIN_HANDLE hDomainsDB) { ADomainScanData *pDSD = (ADomainScanData *) hDomainsDB; fclose(pDSD->pDBFile); SysRemove(pDSD->szTmpDBFile); if (pDSD->ppszStrings != NULL) StrFreeStrings(pDSD->ppszStrings); SysFree(pDSD); } char const *const *ADomGetFirstDomain(ADOMAIN_HANDLE hDomainsDB) { ADomainScanData *pDSD = (ADomainScanData *) hDomainsDB; rewind(pDSD->pDBFile); if (pDSD->ppszStrings != NULL) StrFreeStrings(pDSD->ppszStrings), pDSD->ppszStrings = NULL; char szADomainLine[ADOMAIN_LINE_MAX] = ""; while (MscFGets(szADomainLine, sizeof(szADomainLine) - 1, pDSD->pDBFile) != NULL) { char **ppszStrings = StrGetTabLineStrings(szADomainLine); if (ppszStrings == NULL) continue; int iFieldsCount = StrStringsCount(ppszStrings); if (iFieldsCount >= adomMax) return (pDSD->ppszStrings = ppszStrings); StrFreeStrings(ppszStrings); } return (NULL); } char const *const *ADomGetNextDomain(ADOMAIN_HANDLE hDomainsDB) { ADomainScanData *pDSD = (ADomainScanData *) hDomainsDB; if (pDSD->ppszStrings != NULL) StrFreeStrings(pDSD->ppszStrings), pDSD->ppszStrings = NULL; char szADomainLine[ADOMAIN_LINE_MAX] = ""; while (MscFGets(szADomainLine, sizeof(szADomainLine) - 1, pDSD->pDBFile) != NULL) { char **ppszStrings = StrGetTabLineStrings(szADomainLine); if (ppszStrings == NULL) continue; int iFieldsCount = StrStringsCount(ppszStrings); if (iFieldsCount >= adomMax) return (pDSD->ppszStrings = ppszStrings); StrFreeStrings(ppszStrings); } return (NULL); }