Back to index

courier  0.68.2
Defines | Functions | Variables
comsubmitclient.c File Reference
#include "courier_lib_config.h"
#include "courier.h"
#include "libexecdir.h"
#include "waitlib/waitlib.h"
#include "comsubmitclient.h"
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <ctype.h>
#include <string.h>
#include <signal.h>

Go to the source code of this file.

Defines

#define PRINT_RESPONSE   1
#define PRINT_CRLF   2
#define PRINT_ERRORS   4

Functions

static RETSIGTYPE sighandler (int signum)
void submit_set_teergrube (void(*funcarg)(void))
static int submit_wait_noreset ()
int submit_wait ()
int submit_fork_virtual (char **args, char **env, void(*func)(const char *))
void submit_log_error_prefix (void(*func)(void))
int submit_fork (char **args, char **env, void(*func)(const char *))
static int read_resp_oneline (char *errcode, int doprint)
static int readresponse (int doprint)
int submit_readrc ()
int submit_readrcprint ()
int submit_readrcprinterr ()
int submit_readrcprintcrlf ()
void submit_write_message (const char *msg)
static RETSIGTYPE sigtrap (int signum)
void submit_cancel_async ()
void submit_cancel ()

Variables

static void(* printfunc )(const char *)
static void(* teergrubefunc )(void) = NULL
static pid_t submit_pid
FILE * submit_to
FILE * fromsubmit
static int submit_error
static void(* log_error_prefix_func )(void)
static int alarmflag

Define Documentation

#define PRINT_CRLF   2

Definition at line 35 of file comsubmitclient.c.

#define PRINT_ERRORS   4

Definition at line 36 of file comsubmitclient.c.

#define PRINT_RESPONSE   1

Definition at line 34 of file comsubmitclient.c.


Function Documentation

static int read_resp_oneline ( char *  errcode,
int  doprint 
) [static]

Definition at line 249 of file comsubmitclient.c.

{
       static char linebuf[BUFSIZ];
       char   *c;
       int    rc;
       char   prev_errcode=errcode[0];

       if (submit_error ||
              fgets(linebuf, sizeof(linebuf), fromsubmit) == NULL)
       {
       const char *errmsg="Service temporarily unavailable.";

              if (!errcode[0])
                     strcpy(errcode, "432");

              if (!submit_error)
              {
                     submit_error=1;
                     clog_msg_start_err();
                     clog_msg_str("submitclient: EOF from submit.");
#if 0
                     {
                            const char *p=getenv("TCPREMOTEIP");

                            if (p)
                            {
                                   clog_msg_str(" (ip: ");
                                   clog_msg_str(p);
                                   clog_msg_str(")");
                            }
                     }
#endif
                     clog_msg_send();
              }
              if (doprint)
              {
                     (*printfunc)(errcode);
                     (*printfunc)(" ");
                     (*printfunc)(errmsg);
                     (*printfunc)(doprint & PRINT_CRLF ? "\r\n":"\n");
                     (*printfunc)(0);
              }
              return(-1);
       }

       if (!isdigit((int)(unsigned char)linebuf[0]) ||
              !isdigit((int)(unsigned char)linebuf[1]) ||
              !isdigit((int)(unsigned char)linebuf[2]) ||
              (errcode[0] && strncmp(errcode, linebuf, 3)) ||
              (linebuf[3] != ' ' && linebuf[3] != '-'))
       {
       char   *p;

              clog_msg_start_err();
              clog_msg_str("submitclient: bad response from submit: ");
              if ((p=strchr(linebuf, '\n')) != 0)       *p=0;
              clog_msg_str(linebuf);
              if (p) *p='\n';
              clog_msg_send();

              if (!errcode[0])
                     strcpy(errcode, "432");
              if (doprint)
              {
                     (*printfunc)(errcode);
                     (*printfunc)(" ");
              }
              submit_error=1;
              rc=1;
       }
       else
       {
              if (!errcode[0])
              {
                     memcpy(errcode, linebuf, 3);
                     errcode[3]=0;
              }
              rc=0;
              if (linebuf[3] == ' ')      rc=1;
       }

       if ((c=strchr(linebuf, '\n')) != NULL)    *c=0;

       switch (errcode[0])  {
       case '1':
       case '2':
       case '3':
              if (doprint & PRINT_ERRORS)
                     doprint=0;
              break;
       default:
              if (prev_errcode == 0 && errcode[0] == '5' &&
                  teergrubefunc)
              {
                     (*teergrubefunc)();
              }

              if (log_error_prefix_func)
              {
                     clog_msg_start_err();
                     (*log_error_prefix_func)();
                     clog_msg_str(linebuf);
                     clog_msg_send();
              }
       }

       if (doprint)
              (*printfunc)(linebuf);

       if (!c)
       {
       int    ch;
       int    n=0;
       char   buf[256];

              while ((ch=getc(fromsubmit)) != '\n')
              {
                     if (ch < 0)
                     {
                            submit_error=1;
                            clog_msg_start_err();
                            clog_msg_str("submitclient: EOF from submit.");
#if 0
                            {
                                   const char *p=getenv("TCPREMOTEIP");

                                   if (p)
                                   {
                                          clog_msg_str(" (ip: ");
                                          clog_msg_str(p);
                                          clog_msg_str(")");
                                   }
                            }
#endif
                            clog_msg_send();
                            break;
                     }
                     if (doprint)
                     {
                            buf[n++]=ch;
                            if (n == sizeof(buf)-1)
                            {
                                   buf[n]=0;
                                   (*printfunc)(buf);
                                   n=0;
                            }
                     }
              }
              if (doprint)
              {
                     buf[n]=0;
                     (*printfunc)(buf);
              }
       }

       if (doprint)
       {
              (*printfunc)(doprint & PRINT_CRLF ? "\r\n":"\n");
              (*printfunc)(0);
       }
       return (rc);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int readresponse ( int  doprint) [static]

Definition at line 419 of file comsubmitclient.c.

{
char   errbuf[4];
int    rc;

       errbuf[0]=0;
       do
       {
              rc=read_resp_oneline(errbuf, doprint);
       } while (rc == 0);
       switch (errbuf[0])   {
       case '4':
              return (-4);
       case '5':
              return (-5);
       }
       return (0);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static RETSIGTYPE sighandler ( int  signum) [static]

Definition at line 38 of file comsubmitclient.c.

{
       submit_cancel_async();
       signal(signum, SIG_DFL);
       kill(getpid(), signum);
       _exit(0);
#if    RETSIGTYPE != void
       return (0);
#endif
}

Here is the call graph for this function:

Here is the caller graph for this function:

static RETSIGTYPE sigtrap ( int  signum) [static]

Definition at line 471 of file comsubmitclient.c.

{
       alarmflag=1;
       signal(SIGALRM, sigtrap);
       alarm(1);
#if RETSIGTYPE != void
       return (0);
#endif
}

Here is the caller graph for this function:

void submit_cancel ( )

Definition at line 497 of file comsubmitclient.c.

{
       submit_cancel_async();
       fclose(submit_to);
       fclose(fromsubmit);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 481 of file comsubmitclient.c.

{
char   buf[256];

       kill(submit_pid, SIGTERM);
       alarmflag=0;
       signal(SIGALRM, sigtrap);
       alarm(10);
       while (read(fileno(fromsubmit), buf, sizeof(buf)) > 0)
              ;
       alarm(0);
       signal(SIGALRM, SIG_DFL);
       if (alarmflag)       kill(submit_pid, SIGKILL);
       (void)submit_wait_noreset();
}

Here is the call graph for this function:

Here is the caller graph for this function:

int submit_fork ( char **  args,
char **  env,
void(*)(const char *)  func 
)

Definition at line 196 of file comsubmitclient.c.

{
       size_t i, j;
       const char *p=config_get_local_vhost();
       char **newargs;
       int rc;
       char *q=0;

       if (!p || !*p)
              return submit_fork_virtual(args, env, func);

       for (i=0; args[i]; ++i)
              ;

       newargs=malloc((i+2)*sizeof(char *));

       for (i=j=0; (newargs[j]=args[i]) != 0; ++i, ++j)
       {
              if (i == 0)
              {
                     ++j;
                     strcat(strcpy((q=newargs[j]=
                                   malloc(strlen(p)+10)),
                                  "-vhost="), p);
              }
       }
       rc=submit_fork_virtual(newargs, env, func);

       free(newargs);
       if (q) free(q);
       return rc;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int submit_fork_virtual ( char **  args,
char **  env,
void(*)(const char *)  func 
)

Definition at line 99 of file comsubmitclient.c.

{
int    pipe0[2], pipe1[2];

       printfunc=func;

       submit_error=1;
       log_error_prefix_func=0;
       if (pipe(pipe0))
       {
              clog_msg_start_err();
              clog_msg_str(strerror(errno));
              clog_msg_send();
              return (-1);
       }
       if (pipe(pipe1))
       {
              close(pipe0[0]);
              close(pipe0[1]);
              clog_msg_start_err();
              clog_msg_str(strerror(errno));
              clog_msg_send();
              return (-1);
       }

       submit_pid=fork();
       if ( submit_pid == 0)
       {
       static char execfailed[]="400 Unable to submit message - service temporarily unavailable.\n";

              close(pipe0[1]);
              close(pipe1[0]);
              dup2(pipe0[0], 0);
              dup2(pipe1[1], 1);
              close(pipe0[0]);
              close(pipe1[1]);

              if (chdir(courierdir()))
                     exit(1);

              execve( LIBEXECDIR "/courier/submit", args, env );

              clog_msg_start_err();
              clog_msg_str(strerror(errno));
              clog_msg_send();
              if (write(1, execfailed, sizeof(execfailed)-1) != 1)
                     ; /* ignore */
              exit(1);
       }
       close(pipe0[0]);
       close(pipe1[1]);

       if (submit_pid == -1)
       {
              clog_msg_start_err();
              clog_msg_str(strerror(errno));
              clog_msg_send();
              close(pipe0[1]);
              close(pipe1[0]);
              return (-1);
       }
       if (fcntl(pipe0[1], F_SETFD, FD_CLOEXEC) ||
           (submit_to=fdopen(pipe0[1], "w")) == NULL)
       {
              clog_msg_start_err();
              clog_msg_str(strerror(errno));
              clog_msg_send();
              close(pipe0[1]);
              close(pipe1[0]);
              (void)submit_wait_noreset();
              return (-1);
       }

       if (fcntl(pipe1[0], F_SETFD, FD_CLOEXEC) ||
           (fromsubmit=fdopen(pipe1[0], "r")) == NULL)
       {
              clog_msg_start_err();
              clog_msg_str(strerror(errno));
              clog_msg_send();
              fclose(submit_to);
              close(pipe1[0]);
              (void)submit_wait_noreset();
              return (-1);
       }
       submit_error=0;
       signal(SIGINT, sighandler);
       signal(SIGTERM, sighandler);
       signal(SIGHUP, sighandler);
       return (0);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void submit_log_error_prefix ( void(*)(void)  func)

Definition at line 191 of file comsubmitclient.c.

Here is the caller graph for this function:

int submit_readrc ( )

Definition at line 438 of file comsubmitclient.c.

{
       return (readresponse(0));
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 443 of file comsubmitclient.c.

Here is the call graph for this function:

Definition at line 453 of file comsubmitclient.c.

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 448 of file comsubmitclient.c.

{
       return (readresponse(PRINT_ERRORS));
}

Here is the call graph for this function:

Here is the caller graph for this function:

void submit_set_teergrube ( void(*)(void)  funcarg)

Definition at line 49 of file comsubmitclient.c.

{
       teergrubefunc=funcarg;
}

Here is the caller graph for this function:

int submit_wait ( )

Definition at line 74 of file comsubmitclient.c.

{
int    rc=submit_wait_noreset();

       signal(SIGINT, SIG_DFL);
       signal(SIGHUP, SIG_DFL);
       signal(SIGTERM, SIG_DFL);
       return (rc);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int submit_wait_noreset ( ) [static]

Definition at line 60 of file comsubmitclient.c.

{
int    wait_stat;
pid_t  wait_pid;

       while ((wait_pid=wait(&wait_stat)) != submit_pid)
       {
              if (wait_pid == -1 && errno == ECHILD)    return (-1);
       }
       if (WIFEXITED(wait_stat) && WEXITSTATUS(wait_stat) == 0)
              return (0);
       return (-1);
}

Here is the caller graph for this function:

void submit_write_message ( const char *  msg)

Definition at line 458 of file comsubmitclient.c.

{
       if (submit_error)    return;
       for ( ; *msg; msg++)
              if (*msg != '\r' && *msg != '\n')
                     putc(*msg, submit_to);
       putc('\n', submit_to);
       fflush(submit_to);
       if (ferror(submit_to))      submit_error=1;
}

Here is the caller graph for this function:


Variable Documentation

int alarmflag [static]

Definition at line 469 of file comsubmitclient.c.

FILE* fromsubmit

Definition at line 30 of file comsubmitclient.c.

void(* log_error_prefix_func)(void) [static]

Definition at line 32 of file comsubmitclient.c.

void(* printfunc)(const char *) [static]

Definition at line 25 of file comsubmitclient.c.

int submit_error [static]

Definition at line 31 of file comsubmitclient.c.

pid_t submit_pid [static]

Definition at line 28 of file comsubmitclient.c.

FILE* submit_to

Definition at line 29 of file comsubmitclient.c.

void(* teergrubefunc)(void) = NULL [static]

Definition at line 26 of file comsubmitclient.c.