www.gusucode.com > VC++版的邮件服务器源程序源码程序 > VC++版的邮件服务器源程序源码程序\code\ExtAliases.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 "UsrUtils.h" #include "TabIndex.h" #include "ExtAliases.h" #define SVR_EXT_ALIAS_FILE "extaliases.tab" #define ALIAS_TABLE_LINE_MAX 1024 enum ExtAliasFields { ealRmtDomain = 0, ealRmtName, ealDomain, ealName, ealMax }; struct ExAlDBScanData { char szTmpDBFile[SYS_MAX_PATH]; FILE *pDBFile; }; static int ExAlRebuildAliasIndexes(char const *pszAliasFilePath); static char *ExAlGetTableFilePath(char *pszLnkFilePath, int iMaxPath); static ExtAlias *ExAlGetAliasFromStrings(char **ppszStrings); static int ExAlWriteAlias(FILE * pAliasFile, ExtAlias * pExtAlias); static int iIdxExAlias_RmtDomain_RmtName[] = { ealRmtDomain, ealRmtName, INDEX_SEQUENCE_TERMINATOR }; int ExAlCheckAliasIndexes(void) { char szAliasFilePath[SYS_MAX_PATH] = ""; ExAlGetTableFilePath(szAliasFilePath, sizeof(szAliasFilePath)); /////////////////////////////////////////////////////////////////////////////// // Align RmtDomain-RmtName index /////////////////////////////////////////////////////////////////////////////// if (TbixCheckIndex(szAliasFilePath, iIdxExAlias_RmtDomain_RmtName, false) < 0) return (ErrGetErrorCode()); return (0); } static int ExAlRebuildAliasIndexes(char const *pszAliasFilePath) { /////////////////////////////////////////////////////////////////////////////// // Rebuild RmtDomain-RmtName index /////////////////////////////////////////////////////////////////////////////// if (TbixCreateIndex(pszAliasFilePath, iIdxExAlias_RmtDomain_RmtName, false) < 0) return (ErrGetErrorCode()); return (0); } static char *ExAlGetTableFilePath(char *pszLnkFilePath, int iMaxPath) { CfgGetRootPath(pszLnkFilePath, iMaxPath); StrNCat(pszLnkFilePath, SVR_EXT_ALIAS_FILE, iMaxPath); return (pszLnkFilePath); } static ExtAlias *ExAlGetAliasFromStrings(char **ppszStrings) { int iFieldsCount = StrStringsCount(ppszStrings); if (iFieldsCount < ealMax) return (NULL); ExtAlias *pExtAlias = (ExtAlias *) SysAlloc(sizeof(ExtAlias)); if (pExtAlias == NULL) return (NULL); pExtAlias->pszRmtDomain = SysStrDup(ppszStrings[ealRmtDomain]); pExtAlias->pszRmtName = SysStrDup(ppszStrings[ealRmtName]); pExtAlias->pszDomain = SysStrDup(ppszStrings[ealDomain]); pExtAlias->pszName = SysStrDup(ppszStrings[ealName]); return (pExtAlias); } ExtAlias *ExAlAllocAlias(void) { ExtAlias *pExtAlias = (ExtAlias *) SysAlloc(sizeof(ExtAlias)); if (pExtAlias == NULL) return (NULL); pExtAlias->pszRmtDomain = NULL; pExtAlias->pszRmtName = NULL; pExtAlias->pszDomain = NULL; pExtAlias->pszName = NULL; return (pExtAlias); } void ExAlFreeAlias(ExtAlias * pExtAlias) { if (pExtAlias->pszDomain != NULL) SysFree(pExtAlias->pszDomain); if (pExtAlias->pszName != NULL) SysFree(pExtAlias->pszName); if (pExtAlias->pszRmtDomain != NULL) SysFree(pExtAlias->pszRmtDomain); if (pExtAlias->pszRmtName != NULL) SysFree(pExtAlias->pszRmtName); SysFree(pExtAlias); } static int ExAlWriteAlias(FILE * pAliasFile, ExtAlias * pExtAlias) { /////////////////////////////////////////////////////////////////////////////// // Remote domain /////////////////////////////////////////////////////////////////////////////// char *pszQuoted = StrQuote(pExtAlias->pszRmtDomain, '"'); if (pszQuoted == NULL) return (ErrGetErrorCode()); fprintf(pAliasFile, "%s\t", pszQuoted); SysFree(pszQuoted); /////////////////////////////////////////////////////////////////////////////// // Remote user /////////////////////////////////////////////////////////////////////////////// pszQuoted = StrQuote(pExtAlias->pszRmtName, '"'); if (pszQuoted == NULL) return (ErrGetErrorCode()); fprintf(pAliasFile, "%s\t", pszQuoted); SysFree(pszQuoted); /////////////////////////////////////////////////////////////////////////////// // Domain /////////////////////////////////////////////////////////////////////////////// pszQuoted = StrQuote(pExtAlias->pszDomain, '"'); if (pszQuoted == NULL) return (ErrGetErrorCode()); fprintf(pAliasFile, "%s\t", pszQuoted); SysFree(pszQuoted); /////////////////////////////////////////////////////////////////////////////// // Local user /////////////////////////////////////////////////////////////////////////////// pszQuoted = StrQuote(pExtAlias->pszName, '"'); if (pszQuoted == NULL) return (ErrGetErrorCode()); fprintf(pAliasFile, "%s\n", pszQuoted); SysFree(pszQuoted); return (0); } int ExAlAddAlias(ExtAlias * pExtAlias) { char szAliasFilePath[SYS_MAX_PATH] = ""; ExAlGetTableFilePath(szAliasFilePath, sizeof(szAliasFilePath)); char szResLock[SYS_MAX_PATH] = ""; RLCK_HANDLE hResLock = RLckLockEX(CfgGetBasedPath(szAliasFilePath, szResLock, sizeof(szResLock))); if (hResLock == INVALID_RLCK_HANDLE) return (ErrGetErrorCode()); FILE *pAliasFile = fopen(szAliasFilePath, "r+t"); if (pAliasFile == NULL) { RLckUnlockEX(hResLock); ErrSetErrorCode(ERR_EXTALIAS_FILE_NOT_FOUND); return (ERR_EXTALIAS_FILE_NOT_FOUND); } char szAliasLine[ALIAS_TABLE_LINE_MAX] = ""; while (MscFGets(szAliasLine, sizeof(szAliasLine) - 1, pAliasFile) != NULL) { char **ppszStrings = StrGetTabLineStrings(szAliasLine); if (ppszStrings == NULL) continue; int iFieldsCount = StrStringsCount(ppszStrings); if ((iFieldsCount >= ealMax) && (stricmp(pExtAlias->pszDomain, ppszStrings[ealDomain]) == 0) && (stricmp(pExtAlias->pszName, ppszStrings[ealName]) == 0) && (stricmp(pExtAlias->pszRmtDomain, ppszStrings[ealRmtDomain]) == 0) && (stricmp(pExtAlias->pszRmtName, ppszStrings[ealRmtName]) == 0)) { StrFreeStrings(ppszStrings); fclose(pAliasFile); RLckUnlockEX(hResLock); ErrSetErrorCode(ERR_EXTALIAS_EXIST); return (ERR_EXTALIAS_EXIST); } StrFreeStrings(ppszStrings); } fseek(pAliasFile, 0, SEEK_END); if (ExAlWriteAlias(pAliasFile, pExtAlias) < 0) { fclose(pAliasFile); RLckUnlockEX(hResLock); ErrSetErrorCode(ERR_WRITE_EXTALIAS_FILE); return (ERR_WRITE_EXTALIAS_FILE); } fclose(pAliasFile); /////////////////////////////////////////////////////////////////////////////// // Rebuild indexes /////////////////////////////////////////////////////////////////////////////// if (ExAlRebuildAliasIndexes(szAliasFilePath) < 0) { ErrorPush(); RLckUnlockEX(hResLock); return (ErrorPop()); } RLckUnlockEX(hResLock); return (0); } ExtAlias *ExAlGetAlias(char const *pszRmtDomain, char const *pszRmtName) { char szAliasFilePath[SYS_MAX_PATH] = ""; ExAlGetTableFilePath(szAliasFilePath, sizeof(szAliasFilePath)); char szResLock[SYS_MAX_PATH] = ""; RLCK_HANDLE hResLock = RLckLockSH(CfgGetBasedPath(szAliasFilePath, szResLock, sizeof(szResLock))); if (hResLock == INVALID_RLCK_HANDLE) return (NULL); /////////////////////////////////////////////////////////////////////////////// // Lookup record using the specified index /////////////////////////////////////////////////////////////////////////////// char **ppszTabTokens = TbixLookup(szAliasFilePath, iIdxExAlias_RmtDomain_RmtName, false, pszRmtDomain, pszRmtName, NULL); if (ppszTabTokens == NULL) { RLckUnlockSH(hResLock); ErrSetErrorCode(ERR_EXTALIAS_NOT_FOUND); return (NULL); } ExtAlias *pExtAlias = ExAlGetAliasFromStrings(ppszTabTokens); StrFreeStrings(ppszTabTokens); RLckUnlockSH(hResLock); return (pExtAlias); } int ExAlRemoveAlias(ExtAlias * pExtAlias) { char szAliasFilePath[SYS_MAX_PATH] = ""; ExAlGetTableFilePath(szAliasFilePath, sizeof(szAliasFilePath)); char szTmpFile[SYS_MAX_PATH] = ""; SysGetTmpFile(szTmpFile); char szResLock[SYS_MAX_PATH] = ""; RLCK_HANDLE hResLock = RLckLockEX(CfgGetBasedPath(szAliasFilePath, szResLock, sizeof(szResLock))); if (hResLock == INVALID_RLCK_HANDLE) return (ErrGetErrorCode()); FILE *pAliasFile = fopen(szAliasFilePath, "rt"); if (pAliasFile == NULL) { RLckUnlockEX(hResLock); ErrSetErrorCode(ERR_EXTALIAS_FILE_NOT_FOUND); return (ERR_EXTALIAS_FILE_NOT_FOUND); } FILE *pTmpFile = fopen(szTmpFile, "wt"); if (pTmpFile == NULL) { fclose(pAliasFile); RLckUnlockEX(hResLock); ErrSetErrorCode(ERR_FILE_CREATE); return (ERR_FILE_CREATE); } int iAliasFound = 0; char szAliasLine[ALIAS_TABLE_LINE_MAX] = ""; while (MscFGets(szAliasLine, sizeof(szAliasLine) - 1, pAliasFile) != NULL) { char **ppszStrings = StrGetTabLineStrings(szAliasLine); if (ppszStrings == NULL) continue; int iFieldsCount = StrStringsCount(ppszStrings); if ((iFieldsCount >= ealMax) && (stricmp(pExtAlias->pszDomain, ppszStrings[ealDomain]) == 0) && (stricmp(pExtAlias->pszName, ppszStrings[ealName]) == 0) && (stricmp(pExtAlias->pszRmtDomain, ppszStrings[ealRmtDomain]) == 0) && (stricmp(pExtAlias->pszRmtName, ppszStrings[ealRmtName]) == 0)) { ++iAliasFound; } else fprintf(pTmpFile, "%s\n", szAliasLine); StrFreeStrings(ppszStrings); } fclose(pAliasFile); fclose(pTmpFile); if (iAliasFound == 0) { SysRemove(szTmpFile); RLckUnlockEX(hResLock); ErrSetErrorCode(ERR_EXTALIAS_NOT_FOUND); return (ERR_EXTALIAS_NOT_FOUND); } char szTmpAliasFilePath[SYS_MAX_PATH] = ""; SysSNPrintf(szTmpAliasFilePath, sizeof(szTmpAliasFilePath) - 1, "%s.tmp", szAliasFilePath); if (MscMoveFile(szAliasFilePath, szTmpAliasFilePath) < 0) { RLckUnlockEX(hResLock); return (ErrGetErrorCode()); } if (MscMoveFile(szTmpFile, szAliasFilePath) < 0) { MscMoveFile(szTmpAliasFilePath, szAliasFilePath); RLckUnlockEX(hResLock); return (ErrGetErrorCode()); } SysRemove(szTmpAliasFilePath); /////////////////////////////////////////////////////////////////////////////// // Rebuild indexes /////////////////////////////////////////////////////////////////////////////// if (ExAlRebuildAliasIndexes(szAliasFilePath) < 0) { ErrorPush(); RLckUnlockEX(hResLock); return (ErrorPop()); } RLckUnlockEX(hResLock); return (0); } int ExAlRemoveUserAliases(const char *pszDomain, const char *pszName) { char szAliasFilePath[SYS_MAX_PATH] = ""; ExAlGetTableFilePath(szAliasFilePath, sizeof(szAliasFilePath)); char szTmpFile[SYS_MAX_PATH] = ""; SysGetTmpFile(szTmpFile); char szResLock[SYS_MAX_PATH] = ""; RLCK_HANDLE hResLock = RLckLockEX(CfgGetBasedPath(szAliasFilePath, szResLock, sizeof(szResLock))); if (hResLock == INVALID_RLCK_HANDLE) { ErrorPush(); CheckRemoveFile(szTmpFile); return (ErrorPop()); } FILE *pAliasFile = fopen(szAliasFilePath, "rt"); if (pAliasFile == NULL) { RLckUnlockEX(hResLock); CheckRemoveFile(szTmpFile); ErrSetErrorCode(ERR_EXTALIAS_FILE_NOT_FOUND); return (ERR_EXTALIAS_FILE_NOT_FOUND); } FILE *pTmpFile = fopen(szTmpFile, "wt"); if (pTmpFile == NULL) { fclose(pAliasFile); RLckUnlockEX(hResLock); CheckRemoveFile(szTmpFile); ErrSetErrorCode(ERR_FILE_CREATE); return (ERR_FILE_CREATE); } int iAliasFound = 0; char szAliasLine[ALIAS_TABLE_LINE_MAX] = ""; while (MscFGets(szAliasLine, sizeof(szAliasLine) - 1, pAliasFile) != NULL) { char **ppszStrings = StrGetTabLineStrings(szAliasLine); if (ppszStrings == NULL) continue; int iFieldsCount = StrStringsCount(ppszStrings); if ((iFieldsCount >= ealMax) && (stricmp(pszDomain, ppszStrings[ealDomain]) == 0) && (stricmp(pszName, ppszStrings[ealName]) == 0)) { ++iAliasFound; } else fprintf(pTmpFile, "%s\n", szAliasLine); StrFreeStrings(ppszStrings); } fclose(pAliasFile); fclose(pTmpFile); if (iAliasFound == 0) { SysRemove(szTmpFile); RLckUnlockEX(hResLock); return (0); } char szTmpAliasFilePath[SYS_MAX_PATH] = ""; SysSNPrintf(szTmpAliasFilePath, sizeof(szTmpAliasFilePath) - 1, "%s.tmp", szAliasFilePath); if (MscMoveFile(szAliasFilePath, szTmpAliasFilePath) < 0) { ErrorPush(); RLckUnlockEX(hResLock); return (ErrorPop()); } if (MscMoveFile(szTmpFile, szAliasFilePath) < 0) { ErrorPush(); MscMoveFile(szTmpAliasFilePath, szAliasFilePath); RLckUnlockEX(hResLock); return (ErrorPop()); } SysRemove(szTmpAliasFilePath); /////////////////////////////////////////////////////////////////////////////// // Rebuild indexes /////////////////////////////////////////////////////////////////////////////// if (ExAlRebuildAliasIndexes(szAliasFilePath) < 0) { ErrorPush(); RLckUnlockEX(hResLock); return (ErrorPop()); } RLckUnlockEX(hResLock); return (0); } int ExAlRemoveDomainAliases(const char *pszDomain) { char szAliasFilePath[SYS_MAX_PATH] = ""; ExAlGetTableFilePath(szAliasFilePath, sizeof(szAliasFilePath)); char szTmpFile[SYS_MAX_PATH] = ""; SysGetTmpFile(szTmpFile); char szResLock[SYS_MAX_PATH] = ""; RLCK_HANDLE hResLock = RLckLockEX(CfgGetBasedPath(szAliasFilePath, szResLock, sizeof(szResLock))); if (hResLock == INVALID_RLCK_HANDLE) { ErrorPush(); CheckRemoveFile(szTmpFile); return (ErrorPop()); } FILE *pAliasFile = fopen(szAliasFilePath, "rt"); if (pAliasFile == NULL) { RLckUnlockEX(hResLock); CheckRemoveFile(szTmpFile); ErrSetErrorCode(ERR_EXTALIAS_FILE_NOT_FOUND); return (ERR_EXTALIAS_FILE_NOT_FOUND); } FILE *pTmpFile = fopen(szTmpFile, "wt"); if (pTmpFile == NULL) { fclose(pAliasFile); RLckUnlockEX(hResLock); CheckRemoveFile(szTmpFile); ErrSetErrorCode(ERR_FILE_CREATE); return (ERR_FILE_CREATE); } int iAliasFound = 0; char szAliasLine[ALIAS_TABLE_LINE_MAX] = ""; while (MscFGets(szAliasLine, sizeof(szAliasLine) - 1, pAliasFile) != NULL) { char **ppszStrings = StrGetTabLineStrings(szAliasLine); if (ppszStrings == NULL) continue; int iFieldsCount = StrStringsCount(ppszStrings); if ((iFieldsCount >= ealMax) && (stricmp(pszDomain, ppszStrings[ealDomain]) == 0)) { ++iAliasFound; } else fprintf(pTmpFile, "%s\n", szAliasLine); StrFreeStrings(ppszStrings); } fclose(pAliasFile); fclose(pTmpFile); if (iAliasFound == 0) { SysRemove(szTmpFile); RLckUnlockEX(hResLock); return (0); } char szTmpAliasFilePath[SYS_MAX_PATH] = ""; SysSNPrintf(szTmpAliasFilePath, sizeof(szTmpAliasFilePath) - 1, "%s.tmp", szAliasFilePath); if (MscMoveFile(szAliasFilePath, szTmpAliasFilePath) < 0) { ErrorPush(); SysRemove(szTmpFile); RLckUnlockEX(hResLock); return (ErrorPop()); } if (MscMoveFile(szTmpFile, szAliasFilePath) < 0) { ErrorPush(); MscMoveFile(szTmpAliasFilePath, szAliasFilePath); SysRemove(szTmpFile); RLckUnlockEX(hResLock); return (ErrorPop()); } SysRemove(szTmpAliasFilePath); /////////////////////////////////////////////////////////////////////////////// // Rebuild indexes /////////////////////////////////////////////////////////////////////////////// if (ExAlRebuildAliasIndexes(szAliasFilePath) < 0) { ErrorPush(); RLckUnlockEX(hResLock); return (ErrorPop()); } RLckUnlockEX(hResLock); return (0); } int ExAlGetDBFileSnapShot(const char *pszFileName) { char szAliasFilePath[SYS_MAX_PATH] = ""; ExAlGetTableFilePath(szAliasFilePath, sizeof(szAliasFilePath)); char szResLock[SYS_MAX_PATH] = ""; RLCK_HANDLE hResLock = RLckLockSH(CfgGetBasedPath(szAliasFilePath, szResLock, sizeof(szResLock))); if (hResLock == INVALID_RLCK_HANDLE) return (ErrGetErrorCode()); if (MscCopyFile(pszFileName, szAliasFilePath) < 0) { RLckUnlockSH(hResLock); return (ErrGetErrorCode()); } RLckUnlockSH(hResLock); return (0); } EXAL_HANDLE ExAlOpenDB(void) { ExAlDBScanData *pGLSD = (ExAlDBScanData *) SysAlloc(sizeof(ExAlDBScanData)); if (pGLSD == NULL) return (INVALID_EXAL_HANDLE); SysGetTmpFile(pGLSD->szTmpDBFile); if (ExAlGetDBFileSnapShot(pGLSD->szTmpDBFile) < 0) { SysFree(pGLSD); return (INVALID_EXAL_HANDLE); } if ((pGLSD->pDBFile = fopen(pGLSD->szTmpDBFile, "rt")) == NULL) { SysRemove(pGLSD->szTmpDBFile); SysFree(pGLSD); return (INVALID_EXAL_HANDLE); } return ((EXAL_HANDLE) pGLSD); } void ExAlCloseDB(EXAL_HANDLE hLinksDB) { ExAlDBScanData *pGLSD = (ExAlDBScanData *) hLinksDB; fclose(pGLSD->pDBFile); SysRemove(pGLSD->szTmpDBFile); SysFree(pGLSD); } ExtAlias *ExAlGetFirstAlias(EXAL_HANDLE hLinksDB) { ExAlDBScanData *pGLSD = (ExAlDBScanData *) hLinksDB; rewind(pGLSD->pDBFile); ExtAlias *pExtAlias = NULL; char szAliasLine[ALIAS_TABLE_LINE_MAX] = ""; while ((pExtAlias == NULL) && (MscFGets(szAliasLine, sizeof(szAliasLine) - 1, pGLSD->pDBFile) != NULL)) { char **ppszStrings = StrGetTabLineStrings(szAliasLine); if (ppszStrings == NULL) continue; int iFieldsCount = StrStringsCount(ppszStrings); if (iFieldsCount >= ealMax) pExtAlias = ExAlGetAliasFromStrings(ppszStrings); StrFreeStrings(ppszStrings); } return (pExtAlias); } ExtAlias *ExAlGetNextAlias(EXAL_HANDLE hLinksDB) { ExAlDBScanData *pGLSD = (ExAlDBScanData *) hLinksDB; ExtAlias *pExtAlias = NULL; char szAliasLine[ALIAS_TABLE_LINE_MAX] = ""; while ((pExtAlias == NULL) && (MscFGets(szAliasLine, sizeof(szAliasLine) - 1, pGLSD->pDBFile) != NULL)) { char **ppszStrings = StrGetTabLineStrings(szAliasLine); if (ppszStrings == NULL) continue; int iFieldsCount = StrStringsCount(ppszStrings); if (iFieldsCount >= ealMax) pExtAlias = ExAlGetAliasFromStrings(ppszStrings); StrFreeStrings(ppszStrings); } return (pExtAlias); }