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 )