On Sun, 18 Nov 2001, Jan Patorra wrote:

> hi,
>
> > Try to stop XMail, then use sendmail to create spool/local files ( check
> > if they exist ) and then start XMail is debug mode ( you don't need
> > --debug in Linux, only  -Md ... ).
> > Look at the console messages.

Replace this file inside the source dir, rebuild and repeat the test
showing me the messages.




- Davide



-- Attached file included as plaintext by Listar --
-- File: LMAILSvr.cpp

/*
 *  XMail by Davide Libenzi ( Intranet and Internet mail server )
 *  Copyright (C) 1999,2000,2001  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 <[EMAIL PROTECTED]>
 *
 */


#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 "MessQueue.h"
#include "SvrUtils.h"
#include "UsrUtils.h"
#include "SMTPUtils.h"
#include "SMAILUtils.h"
#include "ExtAliases.h"
#include "UsrMailList.h"
#include "MailConfig.h"
#include "LMAILSvr.h"
#include "AppDefines.h"
#include "MailSvr.h"








#define LMAIL_SERVER_NAME           "[" APP_NAME_VERSION_OS_STR " LMAIL Server]"
#define LOCAL_SPOOL_DIR             "local"
#define LMAIL_LOG_FILE              "lmail"













static LMAILConfig *LMAILGetConfigCopy(SHB_HANDLE hShbLMAIL);
static int      LMAILThreadCountAdd(long lCount, SHB_HANDLE hShbLMAIL,
                        LMAILConfig * pLMAILCfg = NULL);
static int      LMAILLogEnabled(SHB_HANDLE hShbLMAIL, LMAILConfig * pLMAILCfg = NULL);
static int      LMAILProcessLocalSpool(SHB_HANDLE hShbLMAIL, long lThreadId);
static int      LMAILGetFilesSnapShot(LMAILConfig * pLMAILCfg, long lThreadId,
                        char *pszSSFileName);
static int      LMAILRemoveProcessed(LMAILConfig * pLMAILCfg, char const * 
pszListFileName);
static int      LMAILProcessList(LMAILConfig * pLMAILCfg, long lThreadId,
                        char const * pszSSFileName);
static int      LMAILSubmitLocalFile(LMAILConfig * pLMAILCfg, const char *pszMailFile,
                        long lThreadId, char const * pszSMTPDomain);
static int      LMAILAddReceived(FILE * pSpoolFile, char const * pszSMTPDomain,
                        char const * pszMailFrom, char const * pszRcptTo,
                        char const * pszTime);
static int      LMAILLogMessage(char const * pszMailFile, char const * pszSMTPDomain,
                        char const * pszMessageID);











char           *LMAILGetSpoolDir(char *pszSpoolPath)
{

    SvrGetSpoolDir(pszSpoolPath);

    AppendSlash(pszSpoolPath);

    strcat(pszSpoolPath, LOCAL_SPOOL_DIR);

    return (pszSpoolPath);

}



static LMAILConfig *LMAILGetConfigCopy(SHB_HANDLE hShbLMAIL)
{

    LMAILConfig    *pLMAILCfg = (LMAILConfig *) ShbLock(hShbLMAIL);

    if (pLMAILCfg == NULL)
        return (NULL);

    LMAILConfig    *pNewLMAILCfg = (LMAILConfig *) SysAlloc(sizeof(LMAILConfig));

    if (pNewLMAILCfg != NULL)
        memcpy(pNewLMAILCfg, pLMAILCfg, sizeof(LMAILConfig));

    ShbUnlock(hShbLMAIL);

    return (pNewLMAILCfg);

}



static int      LMAILThreadCountAdd(long lCount, SHB_HANDLE hShbLMAIL,
                        LMAILConfig * pLMAILCfg)
{

    int             iDoUnlock = 0;

    if (pLMAILCfg == NULL)
    {
        if ((pLMAILCfg = (LMAILConfig *) ShbLock(hShbLMAIL)) == NULL)
            return (ErrGetErrorCode());

        ++iDoUnlock;
    }

    pLMAILCfg->lThreadCount += lCount;

    if (iDoUnlock)
        ShbUnlock(hShbLMAIL);

    return (0);

}



static int      LMAILLogEnabled(SHB_HANDLE hShbLMAIL, LMAILConfig * pLMAILCfg)
{

    int             iDoUnlock = 0;

    if (pLMAILCfg == NULL)
    {
        if ((pLMAILCfg = (LMAILConfig *) ShbLock(hShbLMAIL)) == NULL)
            return (ErrGetErrorCode());

        ++iDoUnlock;
    }

    unsigned long   ulFlags = pLMAILCfg->ulFlags;

    if (iDoUnlock)
        ShbUnlock(hShbLMAIL);

    return ((ulFlags & LMAILF_LOG_ENABLED) ? 1 : 0);

}



unsigned int    LMAILThreadProc(void *pThreadData)
{

    LMAILConfig    *pLMAILCfg = (LMAILConfig *) ShbLock(hShbLMAIL);

    if (pLMAILCfg == NULL)
    {
        ErrorPush();
        SysLogMessage(LOG_LEV_ERROR, "%s\n", ErrGetErrorString());
        return (ErrorPop());
    }

///////////////////////////////////////////////////////////////////////////////
//  Get thread id and sleep timeout
///////////////////////////////////////////////////////////////////////////////
    int             iSleepTimeout = pLMAILCfg->iSleepTimeout;
    long            lThreadId = pLMAILCfg->lThreadCount;

///////////////////////////////////////////////////////////////////////////////
//  Increase thread count
///////////////////////////////////////////////////////////////////////////////
    LMAILThreadCountAdd(+1, hShbLMAIL, pLMAILCfg);

    ShbUnlock(hShbLMAIL);


    SysLogMessage(LOG_LEV_MESSAGE, "LMAIL thread [%02ld] started\n", lThreadId);

    for (;;)
    {
///////////////////////////////////////////////////////////////////////////////
//  Check shutdown condition
///////////////////////////////////////////////////////////////////////////////
        pLMAILCfg = (LMAILConfig *) ShbLock(hShbLMAIL);

        if ((pLMAILCfg == NULL) || (pLMAILCfg->ulFlags & LMAILF_STOP_SERVER))
        {
            SysLogMessage(LOG_LEV_MESSAGE, "LMAIL thread [%02ld] exiting\n", 
lThreadId);

            if (pLMAILCfg != NULL)
                ShbUnlock(hShbLMAIL);
            break;
        }

        ShbUnlock(hShbLMAIL);

///////////////////////////////////////////////////////////////////////////////
//  Process local spool files
///////////////////////////////////////////////////////////////////////////////
        int             iProcessResult = LMAILProcessLocalSpool(hShbLMAIL, lThreadId);

        if (iProcessResult == ERR_NO_LOCAL_SPOOL_FILES)
            SysSleep(iSleepTimeout);

    }

///////////////////////////////////////////////////////////////////////////////
//  Decrease thread count
///////////////////////////////////////////////////////////////////////////////
    LMAILThreadCountAdd(-1, hShbLMAIL);


    SysLogMessage(LOG_LEV_MESSAGE, "LMAIL thread [%02ld] stopped\n", lThreadId);

    return (0);

}



static int      LMAILProcessLocalSpool(SHB_HANDLE hShbLMAIL, long lThreadId)
{

    LMAILConfig    *pLMAILCfg = LMAILGetConfigCopy(hShbLMAIL);

    if (pLMAILCfg == NULL)
        return (ErrGetErrorCode());


    char            szSSFileName[SYS_MAX_PATH] = "";

    if (LMAILGetFilesSnapShot(pLMAILCfg, lThreadId, szSSFileName) < 0)
    {
        ErrorPush();
        SysFree(pLMAILCfg);
        return (ErrorPop());
    }


    if (LMAILProcessList(pLMAILCfg, lThreadId, szSSFileName) < 0)
    {
        ErrorPush();
        SysRemove(szSSFileName);
        SysFree(pLMAILCfg);
        return (ErrorPop());
    }


    LMAILRemoveProcessed(pLMAILCfg, szSSFileName);

    SysRemove(szSSFileName);

    SysFree(pLMAILCfg);

    return (0);

}



static int      LMAILGetFilesSnapShot(LMAILConfig * pLMAILCfg, long lThreadId,
                        char *pszSSFileName)
{

    char            szSpoolDir[SYS_MAX_PATH] = "";

    LMAILGetSpoolDir(szSpoolDir);


///////////////////////////////////////////////////////////////////////////////
//  Share lock local spool directory
///////////////////////////////////////////////////////////////////////////////
    char            szResLock[SYS_MAX_PATH] = "";
    RLCK_HANDLE     hResLock = RLckLockSH(CfgGetBasedPath(szSpoolDir, szResLock));

    if (hResLock == INVALID_RLCK_HANDLE)
        return (ErrGetErrorCode());


    SysGetTmpFile(pszSSFileName);

    FILE           *pSSFile = fopen(pszSSFileName, "wb");

    if (pSSFile == NULL)
    {
        ErrorPush();
        RLckUnlockSH(hResLock);
        return (ErrorPop());
    }


    int             iFileCount = 0;
    char            szSpoolFileName[SYS_MAX_PATH] = "";
    FSCAN_HANDLE    hFileScan = MscFirstFile(szSpoolDir, 0, szSpoolFileName);

    if (hFileScan != INVALID_FSCAN_HANDLE)
    {
        do
        {
            SYS_UINT32      uHashValue = MscHashString(szSpoolFileName, 
strlen(szSpoolFileName));

            if ((uHashValue % (SYS_UINT32) pLMAILCfg->lNumThreads) == (SYS_UINT32) 
lThreadId)
            {
                fprintf(pSSFile, "%s\r\n", szSpoolFileName);

                ++iFileCount;
            }

        } while (MscNextFile(hFileScan, szSpoolFileName));

        MscCloseFindFile(hFileScan);
    }

    fclose(pSSFile);

    RLckUnlockSH(hResLock);


    if (iFileCount == 0)
    {
        SysRemove(pszSSFileName);
        SetEmptyString(pszSSFileName);

        ErrSetErrorCode(ERR_NO_LOCAL_SPOOL_FILES);
        return (ERR_NO_LOCAL_SPOOL_FILES);
    }


    return (0);

}



static int      LMAILRemoveProcessed(LMAILConfig * pLMAILCfg, char const * 
pszListFileName)
{

    char            szSpoolDir[SYS_MAX_PATH] = "";

    LMAILGetSpoolDir(szSpoolDir);


///////////////////////////////////////////////////////////////////////////////
//  Share lock local spool directory
///////////////////////////////////////////////////////////////////////////////
    char            szResLock[SYS_MAX_PATH] = "";
    RLCK_HANDLE     hResLock = RLckLockEX(CfgGetBasedPath(szSpoolDir, szResLock));

    if (hResLock == INVALID_RLCK_HANDLE)
        return (ErrGetErrorCode());


    FILE           *pSSFile = fopen(pszListFileName, "rb");

    if (pSSFile == NULL)
    {
        ErrorPush();
        RLckUnlockEX(hResLock);
        return (ErrorPop());
    }

    char            szSpoolFileName[SYS_MAX_PATH] = "";

    while (MscGetString(pSSFile, szSpoolFileName, sizeof(szSpoolFileName) - 1) != NULL)
    {
        char            szSpoolFilePath[SYS_MAX_PATH] = "";

        sprintf(szSpoolFilePath, "%s%s%s", szSpoolDir, SYS_SLASH_STR, szSpoolFileName);

        CheckRemoveFile(szSpoolFilePath);
    }

    fclose(pSSFile);

    RLckUnlockEX(hResLock);

    return (0);

}



static int      LMAILProcessList(LMAILConfig * pLMAILCfg, long lThreadId,
                        char const * pszSSFileName)
{

    char            szSpoolDir[SYS_MAX_PATH] = "";

    LMAILGetSpoolDir(szSpoolDir);

///////////////////////////////////////////////////////////////////////////////
//  Retrieve SMTP domain
///////////////////////////////////////////////////////////////////////////////
    SVRCFG_HANDLE   hSvrConfig = SvrGetConfigHandle();

    if (hSvrConfig == INVALID_SVRCFG_HANDLE)
        return (ErrGetErrorCode());

    char            szSMTPDomain[MAX_HOST_NAME] = "localdomain";
    char           *pszDefDomain = SvrGetConfigVar(hSvrConfig, "RootDomain");

    if (pszDefDomain != NULL)
    {
        StrSNCpy(szSMTPDomain, pszDefDomain);

        SysFree(pszDefDomain);
    }

    SvrReleaseConfigHandle(hSvrConfig);


    FILE           *pSSFile = fopen(pszSSFileName, "rb");

    if (pSSFile == NULL)
        return (ErrGetErrorCode());


    char            szSpoolFileName[SYS_MAX_PATH] = "";

    while (MscGetString(pSSFile, szSpoolFileName, sizeof(szSpoolFileName) - 1) != NULL)
    {
        char            szSpoolFilePath[SYS_MAX_PATH] = "";

        sprintf(szSpoolFilePath, "%s%s%s", szSpoolDir, SYS_SLASH_STR, szSpoolFileName);

        if (LMAILSubmitLocalFile(pLMAILCfg, szSpoolFilePath, lThreadId, szSMTPDomain) 
< 0)
        {
            SysLogMessage(LOG_LEV_ERROR, "LMAIL [%02ld] error ( \"%s\" ): %s\n",
                    lThreadId, ErrGetErrorString(), szSpoolFilePath);

        }
        else
        {
            SysLogMessage(LOG_LEV_MESSAGE, "LMAIL [%02ld] file processed: %s\n",
                    lThreadId, szSpoolFilePath);

        }

    }

    fclose(pSSFile);

    return (0);

}



static int      LMAILSubmitLocalFile(LMAILConfig * pLMAILCfg, const char *pszMailFile,
                        long lThreadId, char const * pszSMTPDomain)
{

    FILE           *pMailFile = fopen(pszMailFile, "rb");

    if (pMailFile == NULL)
    {
        ErrSetErrorCode(ERR_FILE_OPEN);
        return (ERR_FILE_OPEN);
    }

///////////////////////////////////////////////////////////////////////////////
//  Get a message ID
///////////////////////////////////////////////////////////////////////////////
    SYS_UINT64      uMessageID;
    char            szMessageID[128] = "";

    if (SvrGetMessageID(&uMessageID) < 0)
    {
        ErrorPush();
        fclose(pMailFile);
        return (ErrorPop());
    }

    sprintf(szMessageID, "L" SYS_LLX_FMT, uMessageID);

///////////////////////////////////////////////////////////////////////////////
//  Get current time
///////////////////////////////////////////////////////////////////////////////
    char            szTime[256] = "";

    MscGetTimeStr(szTime, sizeof(szTime) - 1);

///////////////////////////////////////////////////////////////////////////////
//  Log current opeartion
///////////////////////////////////////////////////////////////////////////////
    if (LMAILLogEnabled(SHB_INVALID_HANDLE, pLMAILCfg))
        LMAILLogMessage(pszMailFile, pszSMTPDomain, szMessageID);

///////////////////////////////////////////////////////////////////////////////
//  Search mail data start
///////////////////////////////////////////////////////////////////////////////
    char            szSpoolLine[MAX_SPOOL_LINE] = "";

    while (MscGetString(pMailFile, szSpoolLine, sizeof(szSpoolLine) - 1) != NULL)
        if (IsEmptyString(szSpoolLine))
            break;

    if (feof(pMailFile))
    {
        fclose(pMailFile);
        ErrSetErrorCode(ERR_INVALID_SPOOL_FILE, pszMailFile);
        return (ERR_INVALID_SPOOL_FILE);
    }

///////////////////////////////////////////////////////////////////////////////
//  Get the offset at which the message data begin and rewind the file
///////////////////////////////////////////////////////////////////////////////
    unsigned long   ulMsgOffset = (unsigned long) ftell(pMailFile);

    rewind(pMailFile);

///////////////////////////////////////////////////////////////////////////////
//  Read "MAIL FROM:" ( 1th row of the smtp-mail file )
///////////////////////////////////////////////////////////////////////////////
    char            szMailFrom[MAX_SPOOL_LINE] = "";

    if ((MscGetString(pMailFile, szMailFrom, sizeof(szMailFrom) - 1) == NULL) ||
            (StrINComp(szMailFrom, MAIL_FROM_STR) != 0))
    {
        fclose(pMailFile);
        ErrSetErrorCode(ERR_INVALID_SPOOL_FILE, pszMailFile);
        return (ERR_INVALID_SPOOL_FILE);
    }


///////////////////////////////////////////////////////////////////////////////
//  Read "RCPT TO:" ( 2nd[,...] row(s) of the local-mail file )
///////////////////////////////////////////////////////////////////////////////
    while ((MscGetString(pMailFile, szSpoolLine, sizeof(szSpoolLine) - 1) != NULL) &&
            !IsEmptyString(szSpoolLine))
    {
///////////////////////////////////////////////////////////////////////////////
//  Get message handle
///////////////////////////////////////////////////////////////////////////////
        QMSG_HANDLE     hMessage = QueCreateMessage(hSpoolQueue);

        if (hMessage == INVALID_QMSG_HANDLE)
        {
            ErrorPush();
            fclose(pMailFile);
            return (ErrorPop());
        }

        char            szQueueFilePath[SYS_MAX_PATH] = "";

        QueGetFilePath(hSpoolQueue, hMessage, szQueueFilePath);


        FILE           *pSpoolFile = fopen(szQueueFilePath, "wb");

        if (pSpoolFile == NULL)
        {
            QueCleanupMessage(hSpoolQueue, hMessage);
            QueCloseMessage(hSpoolQueue, hMessage);
            fclose(pMailFile);
            ErrSetErrorCode(ERR_FILE_CREATE);
            return (ERR_FILE_CREATE);
        }


///////////////////////////////////////////////////////////////////////////////
//  Write SMTP domain
///////////////////////////////////////////////////////////////////////////////
        fprintf(pSpoolFile, "%s\r\n", pszSMTPDomain);

///////////////////////////////////////////////////////////////////////////////
//  Write message ID
///////////////////////////////////////////////////////////////////////////////
        fprintf(pSpoolFile, "%s\r\n", szMessageID);

///////////////////////////////////////////////////////////////////////////////
//  Write "MAIL FROM:"
///////////////////////////////////////////////////////////////////////////////
        fprintf(pSpoolFile, "%s\r\n", szMailFrom);

///////////////////////////////////////////////////////////////////////////////
//  Write "RCPT TO:"
///////////////////////////////////////////////////////////////////////////////
        fprintf(pSpoolFile, "%s\r\n", szSpoolLine);

///////////////////////////////////////////////////////////////////////////////
//  Write SPOOL_FILE_DATA_START
///////////////////////////////////////////////////////////////////////////////
        fprintf(pSpoolFile, "%s\r\n", SPOOL_FILE_DATA_START);

///////////////////////////////////////////////////////////////////////////////
//  Write "Received:" tag
///////////////////////////////////////////////////////////////////////////////
        LMAILAddReceived(pSpoolFile, pszSMTPDomain, szMailFrom, szSpoolLine, szTime);

///////////////////////////////////////////////////////////////////////////////
//  Write mail data, saving and restoring the current file pointer
///////////////////////////////////////////////////////////////////////////////
        unsigned long   ulCurrOffset = (unsigned long) ftell(pMailFile);

        if (MscCopyFile(pSpoolFile, pMailFile, ulMsgOffset, (unsigned long) -1) < 0)
        {
            ErrorPush();
            fclose(pSpoolFile);
            QueCleanupMessage(hSpoolQueue, hMessage);
            QueCloseMessage(hSpoolQueue, hMessage);
            fclose(pMailFile);
            return (ErrorPop());
        }

        if (SysFileSync(pSpoolFile) < 0)
        {
            ErrorPush();
            fclose(pSpoolFile);
            QueCleanupMessage(hSpoolQueue, hMessage);
            QueCloseMessage(hSpoolQueue, hMessage);
            fclose(pMailFile);
            return (ErrorPop());
        }

        if (fclose(pSpoolFile))
        {
            QueCleanupMessage(hSpoolQueue, hMessage);
            QueCloseMessage(hSpoolQueue, hMessage);
            fclose(pMailFile);
            ErrSetErrorCode(ERR_FILE_WRITE, szQueueFilePath);
            return (ERR_FILE_WRITE);
        }

        fseek(pMailFile, ulCurrOffset, SEEK_SET);

///////////////////////////////////////////////////////////////////////////////
//  Transfer file to the spool
///////////////////////////////////////////////////////////////////////////////
        if (QueCommitMessage(hSpoolQueue, hMessage) < 0)
        {
            ErrorPush();
            QueCleanupMessage(hSpoolQueue, hMessage);
            QueCloseMessage(hSpoolQueue, hMessage);
            fclose(pMailFile);
            return (ErrorPop());
        }
    }

    fclose(pMailFile);

    return (0);

}



static int      LMAILAddReceived(FILE * pSpoolFile, char const * pszSMTPDomain,
                        char const * pszMailFrom, char const * pszRcptTo,
                        char const * pszTime)
{

    char            szFrom[MAX_SMTP_ADDRESS] = "",
                    szRcpt[MAX_SMTP_ADDRESS] = "";

    if ((USmlParseAddress(pszMailFrom, NULL, 0, szFrom, sizeof(szFrom) - 1) < 0) ||
            (USmlParseAddress(pszRcptTo, NULL, 0, szRcpt, sizeof(szRcpt) - 1) < 0))
        return (ErrGetErrorCode());


///////////////////////////////////////////////////////////////////////////////
//  Add "Received:" tag
///////////////////////////////////////////////////////////////////////////////
    fprintf(pSpoolFile,
            "Received: from /spool/local\r\n"
            "\tby %s with %s\r\n"
            "\tfor <%s> from <%s>;\r\n"
            "\t%s\r\n", pszSMTPDomain, LMAIL_SERVER_NAME, szRcpt, szFrom, pszTime);

    return (0);

}



static int      LMAILLogMessage(char const * pszMailFile, char const * pszSMTPDomain,
                        char const * pszMessageID)
{

    char            szTime[256] = "";

    MscGetTimeNbrString(szTime, sizeof(szTime) - 1);

    char            szLocalFile[SYS_MAX_PATH] = "";

    MscGetFileName(pszMailFile, szLocalFile);


    RLCK_HANDLE     hResLock = RLckLockEX(SVR_LOGS_DIR SYS_SLASH_STR LMAIL_LOG_FILE);

    if (hResLock == INVALID_RLCK_HANDLE)
        return (ErrGetErrorCode());


    MscFileLog(LMAIL_LOG_FILE,
            "\"%s\""
            "\t\"%s\""
            "\t\"%s\""
            "\t\"%s\""
            "\n", pszSMTPDomain, szLocalFile, pszMessageID, szTime);


    RLckUnlockEX(hResLock);

    return (0);

}

-
To unsubscribe from this list: send the line "unsubscribe xmail" in
the body of a message to [EMAIL PROTECTED]
For general help: send the line "help" in the body of a message to
[EMAIL PROTECTED]

Reply via email to