struct constmap mappercenthack;
stralloc locals = {0};
struct constmap maplocals;
-stralloc redir = {0};
-struct constmap mapredir;
stralloc vdoms = {0};
struct constmap mapvdoms;
stralloc envnoathost = {0};
stralloc bouncehost = {0};
stralloc doublebounceto = {0};
stralloc doublebouncehost = {0};
+stralloc control_idhost = {0};
char strnum2[FMT_ULONG];
char strnum3[FMT_ULONG];
#define CHANNELS 2
char *chanaddr[CHANNELS] = { "local/", "remote/" };
-char *channodelmsg[CHANNELS] = {
- "local deliveries will be put on hold\n"
-, "remote deliveries will be put on hold\n"
-};
+char *chanstatusmsg[CHANNELS] = { " local ", " remote " };
char *tochan[CHANNELS] = { " to local ", " to remote " };
int chanfdout[CHANNELS] = { 1, 3 };
int chanfdin[CHANNELS] = { 2, 4 };
int j;
char *x;
static stralloc addr = {0};
- static stralloc domain = {0};
+ int at;
if (!stralloc_copys(&rwline,"T")) return 0;
if (!stralloc_copys(&addr,recip)) return 0;
addr.s[i] = '@';
}
- if (x = constmap(&mapredir,addr.s,addr.len))
- if (x[str_chr(x,'@')])
- if (!stralloc_copys(&addr,x)) return 0;
+ at = byte_rchr(addr.s,addr.len,'@');
- i = byte_rchr(addr.s,addr.len,'@');
- if (!stralloc_copyb(&domain,addr.s + i + 1,addr.len - i - 1)) return 0;
- addr.len = i;
-
- if (constmap(&maplocals,domain.s,domain.len)) {
+ if (constmap(&maplocals,addr.s + at + 1,addr.len - at - 1)) {
if (!stralloc_cat(&rwline,&addr)) return 0;
- if (!stralloc_cats(&rwline,"@")) return 0;
- if (!stralloc_cat(&rwline,&domain)) return 0;
if (!stralloc_0(&rwline)) return 0;
return 1;
}
- for (i = 0;i <= domain.len;++i)
- if ((i == 0) || (i == domain.len) || (domain.s[i] == '.'))
- if (x = constmap(&mapvdoms,domain.s + i,domain.len - i)) {
+ for (i = 0;i <= addr.len;++i)
+ if (!i || (i == at + 1) || (i == addr.len) || ((i > at) && (addr.s[i] == '.')))
+ if (x = constmap(&mapvdoms,addr.s + i,addr.len - i)) {
if (!*x) break;
if (!stralloc_cats(&rwline,x)) return 0;
if (!stralloc_cats(&rwline,"-")) return 0;
if (!stralloc_cat(&rwline,&addr)) return 0;
- if (!stralloc_cats(&rwline,"@")) return 0;
- if (!stralloc_cat(&rwline,&domain)) return 0;
if (!stralloc_0(&rwline)) return 0;
return 1;
}
if (!stralloc_cat(&rwline,&addr)) return 0;
- if (!stralloc_cats(&rwline,"@")) return 0;
- if (!stralloc_cat(&rwline,&domain)) return 0;
if (!stralloc_0(&rwline)) return 0;
return 2;
}
while (!newfield_datemake(now())) nomem();
qmail_put(&qqt,newfield_date.s,newfield_date.len);
+ while (!newfield_msgidmake(control_idhost.s,control_idhost.len,now()))
+ nomem();
+ qmail_put(&qqt,newfield_msgid.s,newfield_msgid.len);
qmail_puts(&qqt,"From: ");
while (!quote("ed,&bouncefrom)) nomem();
qmail_put(&qqt,quoted.s,quoted.len);
qmail_from(&qqt,bouncesender);
qmail_to(&qqt,bouncerecip);
- if (qmail_close(&qqt))
+ if (*qmail_close(&qqt))
{ log1("warning: trouble injecting bounce message, will try later\n"); return 0; }
strnum2[fmt_ulong(strnum2,id)] = 0;
unsigned long masterdelid = 1;
unsigned int concurrency[CHANNELS] = { 10, 20 };
+unsigned int concurrencyused[CHANNELS] = { 0, 0 };
struct del *d[CHANNELS];
stralloc dline[CHANNELS];
char delbuf[2048];
+void del_status()
+{
+ int c;
+
+ log1("status:");
+ for (c = 0;c < CHANNELS;++c) {
+ strnum2[fmt_ulong(strnum2,(unsigned long) concurrencyused[c])] = 0;
+ strnum3[fmt_ulong(strnum3,(unsigned long) concurrency[c])] = 0;
+ log2(chanstatusmsg[c],strnum2);
+ log2("/",strnum3);
+ }
+ if (flagexitasap) log1(" exitasap");
+ log1("\n");
+}
+
void del_init()
{
int c;
dline[c].s = 0;
while (!stralloc_copys(&dline[c],"")) nomem();
}
+ del_status();
}
int del_canexit()
{
- int i;
int c;
for (c = 0;c < CHANNELS;++c)
if (flagspawnalive[c]) /* if dead, nothing we can do about its jobs */
- for (i = 0;i < concurrency[c];++i)
- if (d[c][i].used) return 0;
+ if (concurrencyused[c]) return 0;
return 1;
}
-static int del_lastsaid = 0;
-
-void del_saywhynoexit()
-{
- int i;
- int c;
- int n;
- n = 0;
- for (c = 0;c < CHANNELS;++c)
- if (flagspawnalive[c])
- for (i = 0;i < concurrency[c];++i)
- if (d[c][i].used)
- ++n;
- if (!del_lastsaid || (n < del_lastsaid))
- {
- strnum2[fmt_ulong(strnum2,(unsigned long) n)] = 0;
- log3("number of deliveries left before exiting: ",strnum2,"\n");
- del_lastsaid = n;
- }
-}
-
int del_avail(c)
int c;
{
- int i;
-
- if (!flagspawnalive[c]) return 0;
- if (!comm_canwrite(c)) return 0;
- for (i = 0;i < concurrency[c];++i) if (!d[c][i].used) return 1;
- return 0;
+ return flagspawnalive[c] && comm_canwrite(c) && (concurrencyused[c] < concurrency[c]);
}
void del_start(j,mpos,recip)
d[c][i].j = j; ++jo[j].refs;
d[c][i].delid = masterdelid++;
d[c][i].mpos = mpos;
- d[c][i].used = 1;
+ d[c][i].used = 1; ++concurrencyused[c];
comm_write(c,i,jo[j].id,jo[j].sender.s,recip);
log3(": msg ",strnum3,tochan[c]);
logsafe(recip);
log1("\n");
+ del_status();
}
void markdone(c,id,pos)
log3("delivery ",strnum3,": report mangled, will defer\n");
}
job_close(d[c][delnum].j);
- d[c][delnum].used = 0;
+ d[c][delnum].used = 0; --concurrencyused[c];
+ del_status();
}
dline[c].len = 0;
}
if (!stralloc_cats(&doublebounceto,"@")) return 0;
if (!stralloc_cat(&doublebounceto,&doublebouncehost)) return 0;
if (!stralloc_0(&doublebounceto)) return 0;
+ if (control_rldef(&control_idhost, "control/idhost",1,"idhost") != 1)
+ return 0;
if (control_readfile(&locals,"control/locals",1) != 1) return 0;
if (!constmap_init(&maplocals,locals.s,locals.len,0)) return 0;
switch(control_readfile(&percenthack,"control/percenthack",0))
case 0: if (!constmap_init(&mappercenthack,"",0,0)) return 0; break;
case 1: if (!constmap_init(&mappercenthack,percenthack.s,percenthack.len,0)) return 0; break;
}
- switch(control_readfile(&redir,"control/recipientmap",0))
- {
- case -1: return 0;
- case 0: if (!constmap_init(&mapredir,"",0,1)) return 0; break;
- case 1: if (!constmap_init(&mapredir,redir.s,redir.len,1)) return 0; break;
- }
switch(control_readfile(&vdoms,"control/virtualdomains",0))
{
case -1: return 0;
numjobs += concurrency[c];
}
- log1("running\n");
-
fnmake_init();
- for (c = 0;c < CHANNELS;++c)
- if (!concurrency[c])
- log1(channodelmsg[c]);
-
comm_init();
pqstart();
while (!flagexitasap || !del_canexit())
{
- if (flagexitasap) del_saywhynoexit();
-
recent = now();
if (flagrunasap) { flagrunasap = 0; pqrun(); }
}
}
pqfinish();
- log1("exiting\n");
+ log1("status: exiting\n");
_exit(0);
}