Back to index

citadel  8.12
Functions | Variables
serv_smtpeventclient.c File Reference
#include "sysdep.h"
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <termios.h>
#include <fcntl.h>
#include <signal.h>
#include <pwd.h>
#include <errno.h>
#include <sys/types.h>
#include <syslog.h>
#include <time.h>
#include <sys/wait.h>
#include <ctype.h>
#include <string.h>
#include <limits.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <libcitadel.h>
#include "citadel.h"
#include "server.h"
#include "citserver.h"
#include "support.h"
#include "config.h"
#include "control.h"
#include "user_ops.h"
#include "database.h"
#include "msgbase.h"
#include "internet_addressing.h"
#include "genstamp.h"
#include "domain.h"
#include "clientsocket.h"
#include "locate_host.h"
#include "citadel_dirs.h"
#include "ctdl_module.h"
#include "smtp_util.h"
#include "event_client.h"
#include "smtpqueue.h"
#include "smtp_clienthandlers.h"

Go to the source code of this file.

Functions

void DeleteSmtpOutMsg (void *v)
eNextState SMTP_C_Shutdown (AsyncIO *IO)
eNextState SMTP_C_Timeout (AsyncIO *IO)
eNextState SMTP_C_ConnFail (AsyncIO *IO)
eNextState SMTP_C_DispatchReadDone (AsyncIO *IO)
eNextState SMTP_C_DispatchWriteDone (AsyncIO *IO)
eNextState SMTP_C_DNSFail (AsyncIO *IO)
eNextState SMTP_C_Terminate (AsyncIO *IO)
eNextState SMTP_C_TerminateDB (AsyncIO *IO)
eReadState SMTP_C_ReadServerStatus (AsyncIO *IO)
 lineread Handler; understands when to read more SMTP lines, and when this is a one-lined reply.
eNextState mx_connect_ip (AsyncIO *IO)
eNextState get_one_mx_host_ip (AsyncIO *IO)
eNextState FinalizeMessageSend_DB (AsyncIO *IO)
eNextState Terminate (AsyncIO *IO)
eNextState FinalizeMessageSend (SmtpOutMsg *Msg)
eNextState FailOneAttempt (AsyncIO *IO)
void SetConnectStatus (AsyncIO *IO)
eNextState get_one_mx_host_ip_done (AsyncIO *IO)
eNextState smtp_resolve_mx_record_done (AsyncIO *IO)
eNextState resolve_mx_records (AsyncIO *IO)
SmtpOutMsgnew_smtp_outmsg (OneQueItem *MyQItem, MailQEntry *MyQEntry, int MsgCount)
void smtp_try_one_queue_entry (OneQueItem *MyQItem, MailQEntry *MyQEntry, StrBuf *MsgText, int KeepMsgText, int MsgCount)
void SMTPSetTimeout (eNextState NextTCPState, SmtpOutMsg *Msg)
void LogDebugEnableSMTPClient (const int n)
 CTDL_MODULE_INIT (smtp_eventclient)

Variables

int SMTPClientDebugEnabled = 0

Function Documentation

CTDL_MODULE_INIT ( smtp_eventclient  )

Definition at line 791 of file serv_smtpeventclient.c.

{
       if (!threading)
              CtdlRegisterDebugFlagHook(HKEY("smtpeventclient"), LogDebugEnableSMTPClient, &SMTPClientDebugEnabled);
       return "smtpeventclient";
}

Here is the call graph for this function:

void DeleteSmtpOutMsg ( void *  v)

Definition at line 94 of file serv_smtpeventclient.c.

{
       SmtpOutMsg *Msg = v;
       AsyncIO *IO = &Msg->IO;
       EV_syslog(LOG_DEBUG, "%s Exit\n", __FUNCTION__);

       /* these are kept in our own space and free'd below */
       Msg->IO.ConnectMe = NULL;

       ares_free_data(Msg->AllMX);
       if (Msg->HostLookup.VParsedDNSReply != NULL)
              Msg->HostLookup.DNSReplyFree(Msg->HostLookup.VParsedDNSReply);
       FreeURL(&Msg->Relay);
       FreeStrBuf(&Msg->msgtext);
       FreeAsyncIOContents(&Msg->IO);
       memset (Msg, 0, sizeof(SmtpOutMsg)); /* just to be shure... */
       free(Msg);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 224 of file serv_smtpeventclient.c.

{
       SmtpOutMsg *Msg = IO->Data;

       if (Msg->MyQEntry->Status == 2)
              return eAbort;

       /*
        * possible ways here:
        * - connection timeout
        * - dns lookup failed
        */
       StopClientWatchers(IO, 1);

       if (Msg->pCurrRelay != NULL)
              Msg->pCurrRelay = Msg->pCurrRelay->Next;

       if (Msg->pCurrRelay == NULL) {
              EVS_syslog(LOG_DEBUG, "%s Aborting\n", __FUNCTION__);
              return eAbort;
       }
       if (Msg->pCurrRelay->IsIP) {
              EVS_syslog(LOG_DEBUG, "%s connecting IP\n", __FUNCTION__);
              return mx_connect_ip(IO);
       }
       else {
              EVS_syslog(LOG_DEBUG,
                        "%s resolving next MX Record\n",
                        __FUNCTION__);
              return get_one_mx_host_ip(IO);
       }
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 218 of file serv_smtpeventclient.c.

{
       /* hand over to DB Queue */
       return QueueDBOperation(&Msg->IO, FinalizeMessageSend_DB);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 132 of file serv_smtpeventclient.c.

{
       const char *Status;
       SmtpOutMsg *Msg = IO->Data;
       
       if (Msg->MyQEntry->Status == 2) 
              Status = "Delivery successful.";
       else if (Msg->MyQEntry->Status == 5) 
              Status = "Delivery failed permanently; giving up.";
       else
              Status = "Delivery failed temporarily; will retry later.";
                     
       EVS_syslog(LOG_INFO,
                 "%s Time[%fs] Recipient <%s> @ <%s> (%s) Status message: %s\n",
                 Status,
                 Msg->IO.Now - Msg->IO.StartIO,
                 Msg->user,
                 Msg->node,
                 Msg->name,
                 ChrPtr(Msg->MyQEntry->StatusMessage));


       Msg->IDestructQueItem = DecreaseQReference(Msg->MyQItem);

       Msg->nRemain = CountActiveQueueEntries(Msg->MyQItem);

       if (Msg->MyQEntry->Active && 
           CheckQEntryIsBounce(Msg->MyQEntry))
       {
              /* are we casue for a bounce mail? */
              Msg->MyQItem->SendBounceMail |= (1<<Msg->MyQEntry->Status);
       }

       if ((Msg->nRemain > 0) || Msg->IDestructQueItem)
              Msg->QMsgData = SerializeQueueItem(Msg->MyQItem);
       else
              Msg->QMsgData = NULL;

       /*
        * Uncompleted delivery instructions remain, so delete the old
        * instructions and replace with the updated ones.
        */
       EVS_syslog(LOG_DEBUG, "%ld", Msg->MyQItem->QueMsgID);
       CtdlDeleteMessages(SMTP_SPOOLOUT_ROOM, &Msg->MyQItem->QueMsgID, 1, "");
       Msg->MyQItem->QueMsgID = -1;

       if (Msg->IDestructQueItem)
              smtpq_do_bounce(Msg->MyQItem, Msg->msgtext);

       if (Msg->nRemain > 0)
       {
              struct CtdlMessage *msg;
              msg = malloc(sizeof(struct CtdlMessage));
              memset(msg, 0, sizeof(struct CtdlMessage));
              msg->cm_magic = CTDLMESSAGE_MAGIC;
              msg->cm_anon_type = MES_NORMAL;
              msg->cm_format_type = FMT_RFC822;
              msg->cm_fields['M'] = SmashStrBuf(&Msg->QMsgData);
              msg->cm_fields['U'] = strdup("QMSG");
              Msg->MyQItem->QueMsgID =
                     CtdlSubmitMsg(msg, NULL, SMTP_SPOOLOUT_ROOM, QP_EADDR);
              EVS_syslog(LOG_DEBUG, "%ld", Msg->MyQItem->QueMsgID);
              CtdlFreeMessage(msg);
       }
       else {
              CtdlDeleteMessages(SMTP_SPOOLOUT_ROOM,
                               &Msg->MyQItem->MessageID,
                               1,
                               "");
              FreeStrBuf(&Msg->QMsgData);
       }

       RemoveContext(Msg->IO.CitContext);
       return eAbort;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 379 of file serv_smtpeventclient.c.

{
       SmtpOutMsg * Msg = IO->Data;
       /*
        * here we start with the lookup of one host. it might be...
        * - the relay host *sigh*
        * - the direct hostname if there was no mx record
        * - one of the mx'es
        */

       EVS_syslog(LOG_DEBUG, "%s\n", __FUNCTION__);

       EVS_syslog(LOG_DEBUG,
                "looking up %s-Record %s : %d ...\n",
                (Msg->pCurrRelay->IPv6)? "aaaa": "a",
                Msg->pCurrRelay->Host,
                Msg->pCurrRelay->Port);

       if (!QueueQuery((Msg->pCurrRelay->IPv6)? ns_t_aaaa : ns_t_a,
                     Msg->pCurrRelay->Host,
                     &Msg->IO,
                     &Msg->HostLookup,
                     get_one_mx_host_ip_done))
       {
              Msg->MyQEntry->Status = 5;
              StrBufPrintf(Msg->MyQEntry->StatusMessage,
                          "No MX hosts found for <%s>", Msg->node);
              Msg->IO.NextState = eTerminateConnection;
              return IO->NextState;
       }
       IO->NextState = eReadDNSReply;
       return IO->NextState;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 319 of file serv_smtpeventclient.c.

{
       SmtpOutMsg *Msg = IO->Data;
       struct hostent *hostent;

       IO->ConnectMe = Msg->pCurrRelay;

       QueryCbDone(IO);
       EVS_syslog(LOG_DEBUG, "%s Time[%fs]\n",
                 __FUNCTION__,
                 IO->Now - IO->DNS.Start);

       hostent = Msg->HostLookup.VParsedDNSReply;
       if ((Msg->HostLookup.DNSStatus == ARES_SUCCESS) &&
           (hostent != NULL) ) {
              memset(&Msg->pCurrRelay->Addr, 0, sizeof(struct in6_addr));
              if (Msg->pCurrRelay->IPv6) {
                     memcpy(&Msg->pCurrRelay->Addr.sin6_addr.s6_addr,
                            &hostent->h_addr_list[0],
                            sizeof(struct in6_addr));

                     Msg->pCurrRelay->Addr.sin6_family =
                            hostent->h_addrtype;
                     Msg->pCurrRelay->Addr.sin6_port =
                            htons(Msg->IO.ConnectMe->Port);
              }
              else {
                     struct sockaddr_in *addr;
                     /*
                      * Bypass the ns lookup result like this:
                      * IO->Addr.sin_addr.s_addr = inet_addr("127.0.0.1");
                      * addr->sin_addr.s_addr =
                      *   htonl((uint32_t)&hostent->h_addr_list[0]);
                      */

                     addr = (struct sockaddr_in*) &Msg->pCurrRelay->Addr;

                     memcpy(&addr->sin_addr.s_addr,
                            hostent->h_addr_list[0],
                            sizeof(uint32_t));

                     addr->sin_family = hostent->h_addrtype;
                     addr->sin_port   = htons(Msg->IO.ConnectMe->Port);
              }
              Msg->mx_host = Msg->pCurrRelay->Host;
              if (Msg->HostLookup.VParsedDNSReply != NULL) {
                     Msg->HostLookup.DNSReplyFree(Msg->HostLookup.VParsedDNSReply);
                     Msg->HostLookup.VParsedDNSReply = NULL;
              }
              return mx_connect_ip(IO);
       }
       else {
              if (Msg->HostLookup.VParsedDNSReply != NULL) {
                     Msg->HostLookup.DNSReplyFree(Msg->HostLookup.VParsedDNSReply);
                     Msg->HostLookup.VParsedDNSReply = NULL;
              }
              return FailOneAttempt(IO);
       }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void LogDebugEnableSMTPClient ( const int  n)

Definition at line 786 of file serv_smtpeventclient.c.

Here is the caller graph for this function:

Definition at line 302 of file serv_smtpeventclient.c.

{
       SmtpOutMsg *Msg = IO->Data;

       EVS_syslog(LOG_DEBUG, "%s\n", __FUNCTION__);

       IO->ConnectMe = Msg->pCurrRelay;
       Msg->State = eConnectMX;

       SetConnectStatus(IO);

       return EvConnectSock(IO,
                          SMTP_C_ConnTimeout,
                          SMTP_C_ReadTimeouts[0],
                          1);
}

Here is the call graph for this function:

Here is the caller graph for this function:

SmtpOutMsg* new_smtp_outmsg ( OneQueItem MyQItem,
MailQEntry MyQEntry,
int  MsgCount 
)

Definition at line 527 of file serv_smtpeventclient.c.

{
       SmtpOutMsg * Msg;

       Msg = (SmtpOutMsg *) malloc(sizeof(SmtpOutMsg));
       if (Msg == NULL)
              return NULL;
       memset(Msg, 0, sizeof(SmtpOutMsg));

       Msg->n                = MsgCount;
       Msg->MyQEntry         = MyQEntry;
       Msg->MyQItem          = MyQItem;
       Msg->pCurrRelay       = MyQItem->URL;

       InitIOStruct(&Msg->IO,
                   Msg,
                   eReadMessage,
                   SMTP_C_ReadServerStatus,
                   SMTP_C_DNSFail,
                   SMTP_C_DispatchWriteDone,
                   SMTP_C_DispatchReadDone,
                   SMTP_C_Terminate,
                   SMTP_C_TerminateDB,
                   SMTP_C_ConnFail,
                   SMTP_C_Timeout,
                   SMTP_C_Shutdown);

       Msg->IO.ErrMsg = Msg->MyQEntry->StatusMessage;

       return Msg;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 500 of file serv_smtpeventclient.c.

{
       SmtpOutMsg * Msg = IO->Data;

       EVS_syslog(LOG_DEBUG, "%s\n", __FUNCTION__);
       /* start resolving MX records here. */
       if (!QueueQuery(ns_t_mx,
                     Msg->node,
                     &Msg->IO,
                     &Msg->MxLookup,
                     smtp_resolve_mx_record_done))
       {
              Msg->MyQEntry->Status = 5;
              StrBufPrintf(Msg->MyQEntry->StatusMessage,
                          "No MX hosts found for <%s>", Msg->node);
              return IO->NextState;
       }
       Msg->IO.NextState = eReadDNSReply;
       return IO->NextState;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void SetConnectStatus ( AsyncIO IO)

Definition at line 258 of file serv_smtpeventclient.c.

{
       SmtpOutMsg *Msg = IO->Data;
       char buf[256];
       void *src;

       buf[0] = '\0';

       if (IO->ConnectMe->IPv6) {
              src = &IO->ConnectMe->Addr.sin6_addr;
       }
       else {
              struct sockaddr_in *addr;

              addr = (struct sockaddr_in *)&IO->ConnectMe->Addr;
              src = &addr->sin_addr.s_addr;
       }

       inet_ntop((IO->ConnectMe->IPv6)?AF_INET6:AF_INET,
                src,
                buf,
                sizeof(buf));

       if (Msg->mx_host == NULL)
              Msg->mx_host = "<no MX-Record>";

       EVS_syslog(LOG_INFO,
                "connecting to %s [%s]:%d ...\n",
                Msg->mx_host,
                buf,
                Msg->IO.ConnectMe->Port);

       Msg->MyQEntry->Status = 4;
       StrBufPrintf(Msg->MyQEntry->StatusMessage,
                   "Timeout while connecting %s [%s]:%d ",
                   Msg->mx_host,
                   buf,
                   Msg->IO.ConnectMe->Port);
       Msg->IO.NextState = eConnect;
}

Here is the caller graph for this function:

Definition at line 726 of file serv_smtpeventclient.c.

{
       SmtpOutMsg *Msg = IO->Data;

       Msg->MyQEntry->Status = 4;
       EVS_syslog(LOG_DEBUG, "%s\n", __FUNCTION__);
       StrBufPlain(IO->ErrMsg, CKEY(ReadErrors[Msg->State]));
       return FailOneAttempt(IO);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 673 of file serv_smtpeventclient.c.

{
       EVS_syslog(LOG_DEBUG, "%s\n", __FUNCTION__);
       SmtpOutMsg *Msg = IO->Data;
       eNextState rc;

       rc = ReadHandlers[Msg->State](Msg);
       if (rc != eAbort)
       {
              Msg->State++;
              SMTPSetTimeout(rc, Msg);
       }
       return rc;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 687 of file serv_smtpeventclient.c.

{
       EVS_syslog(LOG_DEBUG, "%s\n", __FUNCTION__);
       SmtpOutMsg *Msg = IO->Data;
       eNextState rc;

       rc = SendHandlers[Msg->State](Msg);
       SMTPSetTimeout(rc, Msg);
       return rc;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 735 of file serv_smtpeventclient.c.

{
       SmtpOutMsg *Msg = IO->Data;
       Msg->MyQEntry->Status = 4;
       EVS_syslog(LOG_DEBUG, "%s\n", __FUNCTION__);
       return FailOneAttempt(IO);
}

Here is the call graph for this function:

Here is the caller graph for this function:

eReadState SMTP_C_ReadServerStatus ( AsyncIO IO)

lineread Handler; understands when to read more SMTP lines, and when this is a one-lined reply.

read new from socket...

done for now...

WHUT? todo: shut down!

Definition at line 758 of file serv_smtpeventclient.c.

{
       eReadState Finished = eBufferNotEmpty;

       while (Finished == eBufferNotEmpty) {
              Finished = StrBufChunkSipLine(IO->IOBuf, &IO->RecvBuf);

              switch (Finished) {
              case eMustReadMore: 
                     return Finished;
                     break;
              case eBufferNotEmpty: /* shouldn't happen... */
              case eReadSuccess: 
                     if (StrLength(IO->IOBuf) < 4)
                            continue;
                     if (ChrPtr(IO->IOBuf)[3] == '-')
                            Finished = eBufferNotEmpty;
                     else
                            return Finished;
                     break;
              case eReadFail: 

                     break;
              }
       }
       return Finished;
}

Here is the caller graph for this function:

Definition at line 742 of file serv_smtpeventclient.c.

{
       EVS_syslog(LOG_DEBUG, "%s\n", __FUNCTION__);
       SmtpOutMsg *Msg = IO->Data;

       Msg->MyQEntry->Status = 3;
       StrBufPlain(Msg->MyQEntry->StatusMessage,
                  HKEY("server shutdown during message submit."));
       return FinalizeMessageSend(Msg);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 702 of file serv_smtpeventclient.c.

{
       SmtpOutMsg *Msg = IO->Data;

       EVS_syslog(LOG_DEBUG, "%s\n", __FUNCTION__);
       return FinalizeMessageSend(Msg);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 709 of file serv_smtpeventclient.c.

{
       EVS_syslog(LOG_DEBUG, "%s\n", __FUNCTION__);
       return Terminate(IO);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 714 of file serv_smtpeventclient.c.

{
       SmtpOutMsg *Msg = IO->Data;

       Msg->MyQEntry->Status = 4;
       EVS_syslog(LOG_DEBUG, "%s\n", __FUNCTION__);
       StrBufPlain(IO->ErrMsg, CKEY(ReadErrors[Msg->State]));
       if (Msg->State > eRCPT)
              return eAbort;
       else
              return FailOneAttempt(IO);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 417 of file serv_smtpeventclient.c.

{
       SmtpOutMsg * Msg = IO->Data;
       ParsedURL **pp;

       QueryCbDone(IO);

       EVS_syslog(LOG_DEBUG, "%s Time[%fs]\n",
                 __FUNCTION__,
                 IO->Now - IO->DNS.Start);

       pp = &Msg->Relay;
       while ((pp != NULL) && (*pp != NULL) && ((*pp)->Next != NULL))
              pp = &(*pp)->Next;

       if ((IO->DNS.Query->DNSStatus == ARES_SUCCESS) &&
           (IO->DNS.Query->VParsedDNSReply != NULL))
       { /* ok, we found mx records. */

              Msg->CurrMX
                     = Msg->AllMX
                     = IO->DNS.Query->VParsedDNSReply;
              while (Msg->CurrMX) {
                     int i;
                     for (i = 0; i < 2; i++) {
                            ParsedURL *p;

                            p = (ParsedURL*) malloc(sizeof(ParsedURL));
                            memset(p, 0, sizeof(ParsedURL));
                            p->Priority = Msg->CurrMX->priority;
                            p->IsIP = 0;
                            p->Port = DefaultMXPort;
                            p->IPv6 = i == 1;
                            p->Host = Msg->CurrMX->host;
                            if (*pp == NULL)
                                   *pp = p;
                            else {
                                   ParsedURL *ppp = *pp;

                                   while ((ppp->Next != NULL) &&
                                          (ppp->Next->Priority <= p->Priority))
                                          ppp = ppp->Next;
                                   if ((ppp == *pp) &&
                                       (ppp->Priority > p->Priority)) {
                                          p->Next = *pp;
                                          *pp = p;
                                   }
                                   else {
                                          p->Next = ppp->Next;
                                          ppp->Next = p;
                                   }
                            }
                     }
                     Msg->CurrMX    = Msg->CurrMX->next;
              }
              Msg->CXFlags   = Msg->CXFlags & F_HAVE_MX;
       }
       else { /* else fall back to the plain hostname */
              int i;
              for (i = 0; i < 2; i++) {
                     ParsedURL *p;

                     p = (ParsedURL*) malloc(sizeof(ParsedURL));
                     memset(p, 0, sizeof(ParsedURL));
                     p->IsIP = 0;
                     p->Port = DefaultMXPort;
                     p->IPv6 = i == 1;
                     p->Host = Msg->node;

                     *pp = p;
                     pp = &p->Next;
              }
              Msg->CXFlags   = Msg->CXFlags & F_DIRECT;
       }
       if (Msg->MyQItem->FallBackHost != NULL)
       {
              Msg->MyQItem->FallBackHost->Next = *pp;
              *pp = Msg->MyQItem->FallBackHost;
       }
       Msg->pCurrRelay = Msg->Relay;
       return get_one_mx_host_ip(IO);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void smtp_try_one_queue_entry ( OneQueItem MyQItem,
MailQEntry MyQEntry,
StrBuf *  MsgText,
int  KeepMsgText,
int  MsgCount 
)

Definition at line 561 of file serv_smtpeventclient.c.

{
       SmtpOutMsg *Msg;

       SMTPC_syslog(LOG_DEBUG, "%s\n", __FUNCTION__);

       Msg = new_smtp_outmsg(MyQItem, MyQEntry, MsgCount);
       if (Msg == NULL) {
              SMTPC_syslog(LOG_DEBUG, "%s Failed to alocate message context.\n", __FUNCTION__);
              if (KeepMsgText) 
                     FreeStrBuf (&MsgText);
              return;
       }
       if (KeepMsgText) Msg->msgtext = MsgText;
       else           Msg->msgtext = NewStrBufDup(MsgText);

       if (smtp_resolve_recipients(Msg)) {

              safestrncpy(
                     ((CitContext *)Msg->IO.CitContext)->cs_host,
                     Msg->node,
                     sizeof(((CitContext *)
                            Msg->IO.CitContext)->cs_host));

              SMTPC_syslog(LOG_DEBUG, "Starting: [%ld] <%s> CC <%d> \n",
                          Msg->MyQItem->MessageID,
                          ChrPtr(Msg->MyQEntry->Recipient),
                          ((CitContext*)Msg->IO.CitContext)->cs_pid);
              if (Msg->pCurrRelay == NULL)
                     QueueEventContext(&Msg->IO,
                                     resolve_mx_records);
              else { /* oh... via relay host */
                     if (Msg->pCurrRelay->IsIP) {
                            QueueEventContext(&Msg->IO,
                                            mx_connect_ip);
                     }
                     else {
                            /* uneducated admin has chosen to
                               add DNS to the equation... */
                            QueueEventContext(&Msg->IO,
                                            get_one_mx_host_ip);
                     }
              }
       }
       else {
              /* No recipients? well fail then. */
              if (Msg->MyQEntry != NULL) {
                     Msg->MyQEntry->Status = 5;
                     StrBufPlain(Msg->MyQEntry->StatusMessage,
                                HKEY("Invalid Recipient!"));
              }
              FinalizeMessageSend_DB(&Msg->IO);
              DeleteSmtpOutMsg(&Msg->IO);
       }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void SMTPSetTimeout ( eNextState  NextTCPState,
SmtpOutMsg Msg 
)

Definition at line 631 of file serv_smtpeventclient.c.

{
       double Timeout = 0.0;
       AsyncIO *IO = &Msg->IO;

       EVS_syslog(LOG_DEBUG, "%s\n", __FUNCTION__);

       switch (NextTCPState) {
       case eSendFile:
       case eSendReply:
       case eSendMore:
              Timeout = SMTP_C_SendTimeouts[Msg->State];
              if (Msg->State == eDATABody) {
                     /* if we're sending a huge message,
                      * we need more time.
                      */
                     Timeout += StrLength(Msg->msgtext) / 512;
              }
              break;
       case eReadMessage:
              Timeout = SMTP_C_ReadTimeouts[Msg->State];
              if (Msg->State == eDATATerminateBody) {
                     /*
                      * some mailservers take a nap before accepting
                      * the message content inspection and such.
                      */
                     Timeout += StrLength(Msg->msgtext) / 512;
              }
              break;
       case eSendDNSQuery:
       case eReadDNSReply:
       case eDBQuery:
       case eReadFile:
       case eReadMore:
       case eReadPayload:
       case eConnect:
       case eTerminateConnection:
       case eAbort:
              return;
       }
       SetNextTimeout(&Msg->IO, Timeout);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 208 of file serv_smtpeventclient.c.

{
       SmtpOutMsg *Msg = IO->Data;

       if (Msg->IDestructQueItem)
              RemoveQItem(Msg->MyQItem);

       DeleteSmtpOutMsg(Msg);
       return eAbort;
}

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

Definition at line 93 of file serv_smtpeventclient.c.