Back to index

courier  0.68.2
Functions | Variables
moduledel.c File Reference
#include "moduledel.h"
#include "courier.h"
#include "maxlongsize.h"
#include "waitlib/waitlib.h"
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <time.h>
#include <signal.h>
#include <sys/types.h>

Go to the source code of this file.

Functions

char ** module_parsecols (char *p)
struct moduledelmodule_parsedel (char **cols)
char * module_getline (int(*get_func)(void *), void *ptr)
static int get_stdin (void *dummy)
struct moduledelmodule_getdel ()
void module_completed (unsigned i, unsigned n)
static void terminated (pid_t p, int s)
static RETSIGTYPE childsig (int)
void module_blockset ()
void module_blockclr ()
void module_restore ()
void module_init (void(*func)(unsigned, unsigned))
static pid_t module_fork_common (unsigned delid, unsigned *slotptr, int dorelease)
void module_delivery_timeout (time_t n)
pid_t module_fork_noblock (unsigned delid, unsigned *slotptr)
pid_t module_fork (unsigned delid, unsigned *slotptr)
void module_signal (int signum)

Variables

static char * linebuf = 0
static size_t linebufsize = 0
static char ** cols = 0
static size_t colcnt = 0
unsigned module_nchildren
unsigned * module_delids
pid_t * module_pids
time_t * module_timeout
int * module_sig
static time_t delivery_timeout = 0
static void(* childfunc )(unsigned, unsigned)

Function Documentation

static RETSIGTYPE childsig ( int  n) [static]

Definition at line 257 of file moduledel.c.

{
       n=n;

       wait_reap(terminated, childsig);

#if    RETSIGTYPE != void
       return (0);
#endif
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int get_stdin ( void *  dummy) [static]

Definition at line 126 of file moduledel.c.

{
       static char stdin_buf[256];
       static char *stdin_p=NULL;
       static size_t stdin_left=0;

       while (stdin_left == 0)
       {
              time_t currentTime=time(NULL);
              time_t nextTime=0;
              size_t i;
              fd_set fds;
              struct timeval tv;

              if (delivery_timeout)
                     for (i=0; i<module_nchildren; i++)
                     {
                            size_t n;

                            if (module_pids[i] < 0)
                                   continue;

                            if (module_timeout[i] <= currentTime)
                            {
                                   clog_msg_start_err();
                                   clog_msg_str("Error: stuck delivery,"
                                               " PID ");
                                   clog_msg_uint(module_pids[i]);
                                   clog_msg_str(", sending signal ");
                                   clog_msg_uint(module_sig[i]);
                                   clog_msg_send();

                                   module_timeout[i]=currentTime+10;
                                   kill(-module_pids[i], module_sig[i]);
                                   module_sig[i]=SIGKILL;
                                   continue;
                            }

                            n=module_timeout[i] - currentTime;

                            if (nextTime == 0 || n < nextTime)
                                   nextTime=n;
                     }

              FD_ZERO(&fds);
              FD_SET(0, &fds);
              tv.tv_sec=nextTime;
              tv.tv_usec=0;

              if (select(1, &fds, NULL, NULL, nextTime ? &tv:NULL) > 0)
              {
                     int n=read(0, stdin_buf, sizeof(stdin_buf));

                     if (n <= 0)
                            break;
                     
                     stdin_p=stdin_buf;
                     stdin_left=n;
              }
       }

       if (stdin_left == 0)
              return EOF;

       --stdin_left;
       return (int)(unsigned char)*stdin_p++;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void module_blockclr ( )

Definition at line 247 of file moduledel.c.

Here is the call graph for this function:

Here is the caller graph for this function:

void module_blockset ( )

Definition at line 242 of file moduledel.c.

{
       wait_block();
}

Here is the call graph for this function:

Here is the caller graph for this function:

void module_completed ( unsigned  i,
unsigned  n 
)

Definition at line 205 of file moduledel.c.

{
char   buf[MAXLONGSIZE+1];
char   *p;
unsigned c;

       i=i;
       p=buf+MAXLONGSIZE-1;
       *p='\n';
       p[1]=0;
       c=1;
       do
       {
              *--p= (n % 10) + '0';
              ++c;
       } while ((n=n / 10) != 0);
       if (write (1, p, c) != c)
              ;
}

Here is the caller graph for this function:

void module_delivery_timeout ( time_t  n)

Definition at line 348 of file moduledel.c.

Here is the caller graph for this function:

pid_t module_fork ( unsigned  delid,
unsigned *  slotptr 
)

Definition at line 358 of file moduledel.c.

{
pid_t  pid;

       module_blockset();

       pid=module_fork_common(delid, slotptr, 1);

       if (pid)
              module_blockclr();
       return (pid);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static pid_t module_fork_common ( unsigned  delid,
unsigned *  slotptr,
int  dorelease 
) [static]

Definition at line 295 of file moduledel.c.

{
pid_t  pid;
unsigned n;
static unsigned idx=0;

       if (slotptr)
              idx= *slotptr;
       else
       {
              for (n=0; n<module_nchildren; n++)
              {
                     if (module_pids[idx] < 0)   break;
                     if (++idx >= module_nchildren)     idx=0;
              }

              if (n == module_nchildren)
              {
                     clog_msg_start_err();
                     clog_msg_str(
                     "Internal error - no available process slots.");
                     clog_msg_send();
                     exit(1);
              }
       }

       if ((pid=fork()) == -1)
              return (pid);

       if (pid)
       {
              time_t n=0;

              module_pids[idx]=pid;
              module_delids[idx]=delid;

              if (delivery_timeout)
              {
                     time(&n);
                     n += delivery_timeout;
              }
              module_timeout[idx] = n;
              module_sig[idx] = SIGTERM;
       }
       else
       {
              module_restore();
       }

       return (pid);
}

Here is the call graph for this function:

Here is the caller graph for this function:

pid_t module_fork_noblock ( unsigned  delid,
unsigned *  slotptr 
)

Definition at line 353 of file moduledel.c.

{
       return (module_fork_common(delid, slotptr, 0));
}

Here is the call graph for this function:

Here is the caller graph for this function:

struct moduledel* module_getdel ( ) [read]

Definition at line 194 of file moduledel.c.

{
char   **cols;
char   *line=module_getline( &get_stdin, 0);

       if (!line)    return (0);

       if ((cols=module_parsecols(linebuf)) == 0)       return (0);
       return (module_parsedel(cols));
}

Here is the call graph for this function:

Here is the caller graph for this function:

char* module_getline ( int(*)(void *)  get_func,
void *  ptr 
)

Definition at line 95 of file moduledel.c.

{
size_t n;
int    c;

       for (n=0; ; n++)
       {
              do
              {
                     errno=0;
                     c= (*get_func)(ptr);
              } while (c == EOF && errno == EINTR);

              if (n >= linebufsize)
              {
                     if ((linebuf=(char *)
                            (linebufsize ? realloc(linebuf,
                                   linebufsize += 256):
                                   malloc(linebufsize += 256))) == 0)
                            clog_msg_errno();
              }

              if (c == '\n' || c == EOF)  break;

              linebuf[n]=c;
       }
       linebuf[n]=0;
       if (c == EOF && n == 0)     return (0);
       return (linebuf);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void module_init ( void(*)(unsigned, unsigned)  func)

Definition at line 268 of file moduledel.c.

{
const  char *p=getenv("MAXDELS");
unsigned n;

       if (!p)       p="0";

       if (!func)
              func= &module_completed;

       module_nchildren=atol(p);
       if (module_nchildren <= 0)  module_nchildren=1;

       if ((module_pids=malloc(module_nchildren*sizeof(*module_pids))) == 0 ||
           (module_delids=malloc(module_nchildren*sizeof(*module_delids))) == 0 ||
           (module_timeout=malloc(module_nchildren*sizeof(*module_timeout)))
           == 0 ||
           (module_sig=malloc(module_nchildren*sizeof(*module_sig))) == 0)
              clog_msg_errno();

       for (n=0; n<module_nchildren; n++)
              module_pids[n]= -1;

       childfunc=func;
       signal(SIGCHLD, childsig);
}

Here is the call graph for this function:

Here is the caller graph for this function:

char** module_parsecols ( char *  p)

Definition at line 47 of file moduledel.c.

{
unsigned l;
size_t ncols=1;
size_t n;

       for (l=0; p[l]; l++)
              if (p[l] == '\t')    ++ncols;

       if (ncols >= colcnt)
       {
              colcnt=ncols+10;
              cols=(char **)(cols ? realloc(cols, colcnt*sizeof(char *))
                            : malloc(colcnt*sizeof(char *)));
       }
       ncols=1;
       cols[0]=linebuf;
       for (n=0; p[n]; n++)
              if (p[n] == '\t')
                     cols[ncols++]=p+n+1;
       cols[ncols]=0;
       if (ncols < 6)       return (0);
       return (cols);
}

Here is the caller graph for this function:

struct moduledel* module_parsedel ( char **  cols) [read]

Definition at line 72 of file moduledel.c.

{
size_t n;
const char *cp;
static struct moduledel msginfo;

       for (n=1; cols[n]; n++)
              cols[n][-1]=0;

       cp=cols[0];
       msginfo.inum=0;
       while (*cp >= '0' && *cp <= '9')
              msginfo.inum = msginfo.inum*10 + (*cp++ - '0');
       msginfo.msgid=cols[1];

       msginfo.sender=cols[2];
       msginfo.delid=cols[3];
       msginfo.host=cols[4];
       msginfo.receipients=&cols[5];
       msginfo.nreceipients=(n - 5)/2;
       return (&msginfo);
}

Here is the caller graph for this function:

void module_restore ( )

Definition at line 252 of file moduledel.c.

{
       wait_restore();
}

Here is the call graph for this function:

Here is the caller graph for this function:

void module_signal ( int  signum)

Definition at line 371 of file moduledel.c.

{
       unsigned n;

       module_blockset();

       for (n=0; n<module_nchildren; n++)
              if (module_pids[n] > 0)
              {
                     kill(module_pids[n], signum);
              }
       module_blockclr();
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void terminated ( pid_t  p,
int  s 
) [static]

Definition at line 227 of file moduledel.c.

{
int    n;

       for (n=0; n<module_nchildren; n++)
              if (module_pids[n] == p)
              {
                     module_pids[n]= -1;
                     (*childfunc)(n, module_delids[n]);
                     break;
              }
}

Here is the caller graph for this function:


Variable Documentation

void(* childfunc)(unsigned, unsigned) [static]

Definition at line 225 of file moduledel.c.

size_t colcnt = 0 [static]

Definition at line 38 of file moduledel.c.

char** cols = 0 [static]

Definition at line 37 of file moduledel.c.

time_t delivery_timeout = 0 [static]

Definition at line 45 of file moduledel.c.

char* linebuf = 0 [static]

Definition at line 35 of file moduledel.c.

size_t linebufsize = 0 [static]

Definition at line 36 of file moduledel.c.

unsigned* module_delids

Definition at line 41 of file moduledel.c.

unsigned module_nchildren

Definition at line 40 of file moduledel.c.

pid_t* module_pids

Definition at line 42 of file moduledel.c.

int* module_sig

Definition at line 44 of file moduledel.c.

time_t* module_timeout

Definition at line 43 of file moduledel.c.