Mail-QmailRemoteXS

 view release on metacpan or  search on metacpan

qmailrem/qmail-send.c  view on Meta::CPAN

#include <sys/types.h>
#include <sys/stat.h>
#include "readwrite.h"
#include "sig.h"
#include "direntry.h"
#include "control.h"
#include "select.h"
#include "open.h"
#include "seek.h"
#include "exit.h"
#include "lock.h"
#include "ndelay.h"
#include "now.h"
#include "getln.h"
#include "substdio.h"
#include "alloc.h"
#include "error.h"
#include "stralloc.h"
#include "str.h"
#include "byte.h"
#include "fmt.h"
#include "scan.h"
#include "case.h"
#include "auto_qmail.h"
#include "trigger.h"
#include "newfield.h"
#include "quote.h"
#include "qmail.h"
#include "qsutil.h"
#include "prioq.h"
#include "constmap.h"
#include "fmtqfn.h"
#include "readsubdir.h"

/* critical timing feature #1: if not triggered, do not busy-loop */
/* critical timing feature #2: if triggered, respond within fixed time */
/* important timing feature: when triggered, respond instantly */
#define SLEEP_TODO 1500 /* check todo/ every 25 minutes in any case */
#define SLEEP_FUZZ 1 /* slop a bit on sleeps to avoid zeno effect */
#define SLEEP_FOREVER 86400 /* absolute maximum time spent in select() */
#define SLEEP_CLEANUP 76431 /* time between cleanups */
#define SLEEP_SYSFAIL 123
#define OSSIFIED 129600 /* 36 hours; _must_ exceed q-q's DEATH (24 hours) */

int lifetime = 604800;

stralloc percenthack = {0};
struct constmap mappercenthack;
stralloc locals = {0};
struct constmap maplocals;
stralloc vdoms = {0};
struct constmap mapvdoms;
stralloc envnoathost = {0};
stralloc bouncefrom = {0};
stralloc bouncehost = {0};
stralloc doublebounceto = {0};
stralloc doublebouncehost = {0};

char strnum2[FMT_ULONG];
char strnum3[FMT_ULONG];

#define CHANNELS 2
char *chanaddr[CHANNELS] = { "local/", "remote/" };
char *chanstatusmsg[CHANNELS] = { " local ", " remote " };
char *tochan[CHANNELS] = { " to local ", " to remote " };
int chanfdout[CHANNELS] = { 1, 3 };
int chanfdin[CHANNELS] = { 2, 4 };
int chanskip[CHANNELS] = { 10, 20 };

int flagexitasap = 0; void sigterm() { flagexitasap = 1; }
int flagrunasap = 0; void sigalrm() { flagrunasap = 1; }
int flagreadasap = 0; void sighup() { flagreadasap = 1; }

void cleandied() { log1("alert: oh no! lost qmail-clean connection! dying...\n");
 flagexitasap = 1; }

int flagspawnalive[CHANNELS];
void spawndied(c) int c; { log1("alert: oh no! lost spawn connection! dying...\n");
 flagspawnalive[c] = 0; flagexitasap = 1; }

#define REPORTMAX 10000

datetime_sec recent;


/* this file is too long ----------------------------------------- FILENAMES */

stralloc fn = {0};
stralloc fn2 = {0};
char fnmake_strnum[FMT_ULONG];

void fnmake_init()
{
 while (!stralloc_ready(&fn,FMTQFN)) nomem();
 while (!stralloc_ready(&fn2,FMTQFN)) nomem();

qmailrem/qmail-send.c  view on Meta::CPAN

 /* XXX: could allow a bigger buffer; say 10 recipients */
 if (comm_buf[c].s && comm_buf[c].len) return 0;
 return 1;
}

void comm_write(c,delnum,id,sender,recip)
int c;
int delnum;
unsigned long id;
char *sender;
char *recip;
{
 char ch;
 if (comm_buf[c].s && comm_buf[c].len) return;
 while (!stralloc_copys(&comm_buf[c],"")) nomem();
 ch = delnum;
 while (!stralloc_append(&comm_buf[c],&ch)) nomem();
 fnmake_split(id);
 while (!stralloc_cats(&comm_buf[c],fn.s)) nomem();
 while (!stralloc_0(&comm_buf[c])) nomem();
 senderadd(&comm_buf[c],sender,recip);
 while (!stralloc_0(&comm_buf[c])) nomem();
 while (!stralloc_cats(&comm_buf[c],recip)) nomem();
 while (!stralloc_0(&comm_buf[c])) nomem();
 comm_pos[c] = 0;
}

void comm_selprep(nfds,wfds)
int *nfds;
fd_set *wfds;
{
 int c;
 for (c = 0;c < CHANNELS;++c)
   if (flagspawnalive[c])
     if (comm_buf[c].s && comm_buf[c].len)
      {
       FD_SET(chanfdout[c],wfds);
       if (*nfds <= chanfdout[c])
         *nfds = chanfdout[c] + 1;
      }
}

void comm_do(wfds)
fd_set *wfds;
{
 int c;
 for (c = 0;c < CHANNELS;++c)
   if (flagspawnalive[c])
     if (comm_buf[c].s && comm_buf[c].len)
       if (FD_ISSET(chanfdout[c],wfds))
        {
         int w;
         int len;
         len = comm_buf[c].len;
         w = write(chanfdout[c],comm_buf[c].s + comm_pos[c],len - comm_pos[c]);
         if (w <= 0)
	  {
	   if ((w == -1) && (errno == error_pipe))
	     spawndied(c);
	   else
	     continue; /* kernel select() bug; can't avoid busy-looping */
	  }
	 else
	  {
	   comm_pos[c] += w;
	   if (comm_pos[c] == len)
	     comm_buf[c].len = 0;
	  }
        }
}


/* this file is too long ------------------------------------------ CLEANUPS */

int flagcleanup; /* if 1, cleanupdir is initialized and ready */
readsubdir cleanupdir;
datetime_sec cleanuptime;

void cleanup_init()
{
 flagcleanup = 0;
 cleanuptime = now();
}

void cleanup_selprep(wakeup)
datetime_sec *wakeup;
{
 if (flagcleanup) *wakeup = 0;
 if (*wakeup > cleanuptime) *wakeup = cleanuptime;
}

void cleanup_do()
{
 char ch;
 struct stat st;
 unsigned long id;

 if (!flagcleanup)
  {
   if (recent < cleanuptime) return;
   readsubdir_init(&cleanupdir,"mess",pausedir);
   flagcleanup = 1;
  }

 switch(readsubdir_next(&cleanupdir,&id))
  {
   case 1:
     break;
   case 0:
     flagcleanup = 0;
     cleanuptime = recent + SLEEP_CLEANUP;
   default:
     return;
  }

 fnmake_mess(id);
 if (stat(fn.s,&st) == -1) return; /* probably qmail-queue deleted it */
 if (recent <= st.st_atime + OSSIFIED) return;

 fnmake_info(id);
 if (stat(fn.s,&st) == 0) return;



( run in 3.534 seconds using v1.01-cache-2.11-cpan-5a3173703d6 )