do_str("me",0,"undefined! Uh-oh","My name is ");
do_lst("percenthack","The percent hack is not allowed.","The percent hack is allowed for user%host@",".");
do_str("plusdomain",1,"plusdomain","Plus domain name is ");
+ do_lst("qmqpservers","No QMQP servers.","QMQP server: ",".");
do_int("queuelifetime","604800","Message lifetime in the queue is "," seconds");
- do_lst("rcpthosts","SMTP clients may send messages to any recipient.","SMTP clients may send messages to recipients at ",".");
- do_lst("recipientmap","No redirections.","Redirection: ","");
+
+ if (do_lst("rcpthosts","SMTP clients may send messages to any recipient.","SMTP clients may send messages to recipients at ","."))
+ do_lst("morercpthosts","No effect.","SMTP clients may send messages to recipients at ",".");
+ else
+ do_lst("morercpthosts","No rcpthosts; morercpthosts is irrelevant.","No rcpthosts; doesn't matter that morercpthosts has ",".");
+ /* XXX: check morercpthosts.cdb contents */
+ substdio_puts(subfdout,"\nmorercpthosts.cdb: ");
+ if (stat("morercpthosts",&stmrh) == -1)
+ if (stat("morercpthosts.cdb",&stmrhcdb) == -1)
+ substdio_puts(subfdout,"(Default.) No effect.\n");
+ else
+ substdio_puts(subfdout,"Oops! morercpthosts.cdb exists but morercpthosts doesn't.\n");
+ else
+ if (stat("morercpthosts.cdb",&stmrhcdb) == -1)
+ substdio_puts(subfdout,"Oops! morercpthosts exists but morercpthosts.cdb doesn't.\n");
+ else
+ if (stmrh.st_mtime > stmrhcdb.st_mtime)
+ substdio_puts(subfdout,"Oops! morercpthosts.cdb is older than morercpthosts.\n");
+ else
+ substdio_puts(subfdout,"Modified recently enough; hopefully up to date.\n");
+
+ do_lst("relayhosts","No relayhosts","Relay host: ","");
do_str("smtpgreeting",1,"smtpgreeting","SMTP greeting: 220 ");
do_lst("smtproutes","No artificial SMTP routes.","SMTP route: ","");
do_int("timeoutconnect","60","SMTP client connection timeout is "," seconds");
if (str_equal(d->d_name,"localiphost")) continue;
if (str_equal(d->d_name,"locals")) continue;
if (str_equal(d->d_name,"me")) continue;
+ if (str_equal(d->d_name,"morercpthosts")) continue;
+ if (str_equal(d->d_name,"morercpthosts.cdb")) continue;
if (str_equal(d->d_name,"percenthack")) continue;
if (str_equal(d->d_name,"plusdomain")) continue;
+ if (str_equal(d->d_name,"qmqpservers")) continue;
if (str_equal(d->d_name,"queuelifetime")) continue;
if (str_equal(d->d_name,"rcpthosts")) continue;
- if (str_equal(d->d_name,"recipientmap")) continue;
+ if (str_equal(d->d_name,"relayhosts")) continue;
if (str_equal(d->d_name,"smtpgreeting")) continue;
if (str_equal(d->d_name,"smtproutes")) continue;
if (str_equal(d->d_name,"timeoutconnect")) continue;
char *local;
char *relayclient;
-void dohelo(arg) char *arg;
-{
- if (!stralloc_copys(&helohost,arg)) outofmem();
- if (!stralloc_0(&helohost)) outofmem();
-}
+stralloc helohost = {0};
+char *fakehelo; /* pointer into helohost, or 0 */
-void getenvs()
-{
- remoteip = env_get("TCPREMOTEIP");
- if (!remoteip) remoteip = "unknown";
- local = env_get("TCPLOCALHOST");
- if (!local) local = env_get("TCPLOCALIP");
- if (!local) local = "unknown";
- remotehost = env_get("TCPREMOTEHOST");
- if (!remotehost) remotehost = "unknown";
- remoteinfo = env_get("TCPREMOTEINFO");
- relayclient = env_get("RELAYCLIENT");
- if (!relayclient && relayhostsok) {
- int j;
- int l = str_len(remotehost);
- relayclient = constmap(&maprelayhosts, remotehost, l);
- if (!relayclient) for (j = 0; j < l; ++j) {
- if (remotehost[j] == '.' &&
- (relayclient = constmap(&maprelayhosts,
- remotehost + j,
- l - j)) != 0)
- break;
- }
- }
- dohelo(remotehost);
+void dohelo(arg) char *arg; {
+ if (!stralloc_copys(&helohost,arg)) die_nomem();
+ if (!stralloc_0(&helohost)) die_nomem();
+ fakehelo = case_diffs(remotehost,helohost.s) ? helohost.s : 0;
}
-void straynewline()
-{
- out("451 \
-Put ,E=\\r\\n at the end of Mether, Mtcp, or Msmtp in sendmail.cf \
-if you are using Solaris 2.5 (fixed in 2.5.1). \
-I cannot accept messages with stray newlines. \
-Many SMTP servers will time out waiting for \\r\\n.\\r\\n.\
-\r\n");
- die();
-}
+int liphostok = 0;
+stralloc liphost = {0};
++int relayhostsok = 0;
++stralloc relayhosts = {0};
++struct constmap maprelayhosts;
+int bmfok = 0;
+stralloc bmf = {0};
+struct constmap mapbmf;
-void blast(ssfrom,hops)
-substdio *ssfrom;
-int *hops;
+void setup()
{
- char ch;
- int state;
- int flaginheader;
- int pos; /* number of bytes since most recent \n, if fih */
- int flagmaybex; /* 1 if this line might match RECEIVED, if fih */
- int flagmaybey; /* 1 if this line might match \r\n, if fih */
- int flagmaybez; /* 1 if this line might match DELIVERED, if fih */
-
- state = 1;
- *hops = 0;
- flaginheader = 1;
- pos = 0; flagmaybex = flagmaybey = flagmaybez = 1;
- for (;;)
- {
- if (substdio_get(ssfrom,&ch,1) <= 0) die();
- if (flaginheader)
- {
- if (pos < 9)
- {
- if (ch != "delivered"[pos]) if (ch != "DELIVERED"[pos]) flagmaybez = 0;
- if (flagmaybez) if (pos == 8) ++*hops;
- if (pos < 8)
- if (ch != "received"[pos]) if (ch != "RECEIVED"[pos]) flagmaybex = 0;
- if (flagmaybex) if (pos == 7) ++*hops;
- if (pos < 2) if (ch != "\r\n"[pos]) flagmaybey = 0;
- if (flagmaybey) if (pos == 1) flaginheader = 0;
- }
- ++pos;
- if (ch == '\n') { pos = 0; flagmaybex = flagmaybey = flagmaybez = 1; }
- }
- switch(state)
- {
- case 0:
- if (ch == '\n') straynewline();
- if (ch == '\r') { state = 4; continue; }
- break;
- case 1: /* \r\n */
- if (ch == '\n') straynewline();
- if (ch == '.') { state = 2; continue; }
- if (ch == '\r') { state = 4; continue; }
- state = 0;
- break;
- case 2: /* \r\n + . */
- if (ch == '\n') straynewline();
- if (ch == '\r') { state = 3; continue; }
- state = 0;
- break;
- case 3: /* \r\n + .\r */
- if (ch == '\n') return;
- qmail_put(&qqt,".\r",2);
- if (ch == '\r') { state = 4; continue; }
- state = 0;
- break;
- case 4: /* + \r */
- if (ch == '\n') { state = 1; break; }
- if (ch != '\r') { qmail_put(&qqt,"\r",1); state = 0; }
+ char *x;
+ unsigned long u;
+
+ if (control_init() == -1) die_control();
+ if (control_rldef(&greeting,"control/smtpgreeting",1,(char *) 0) != 1)
+ die_control();
+ liphostok = control_rldef(&liphost,"control/localiphost",1,(char *) 0);
+ if (liphostok == -1) die_control();
+ if (control_readint(&timeout,"control/timeoutsmtpd") == -1) die_control();
+ if (timeout <= 0) timeout = 1;
+
+ if (rcpthosts_init() == -1) die_control();
+
+ bmfok = control_readfile(&bmf,"control/badmailfrom",0);
+ if (bmfok == -1) die_control();
+ if (bmfok)
+ if (!constmap_init(&mapbmf,bmf.s,bmf.len,0)) die_nomem();
++
++ switch (control_readfile(&relayhosts, "control/relayhosts", 0)) {
++ case -1:
++ die_control();
++ case 1:
++ relayhostsok = 1;
++ if (!constmap_init(&maprelayhosts, relayhosts.s, relayhosts.len, 1))
++ die_nomem();
++ }
++
+
+ if (control_readint(&databytes,"control/databytes") == -1) die_control();
+ x = env_get("DATABYTES");
+ if (x) { scan_ulong(x,&u); databytes = u; }
+ if (!(databytes + 1)) --databytes;
+
+ remoteip = env_get("TCPREMOTEIP");
+ if (!remoteip) remoteip = "unknown";
+ local = env_get("TCPLOCALHOST");
+ if (!local) local = env_get("TCPLOCALIP");
+ if (!local) local = "unknown";
+ remotehost = env_get("TCPREMOTEHOST");
+ if (!remotehost) remotehost = "unknown";
+ remoteinfo = env_get("TCPREMOTEINFO");
+ relayclient = env_get("RELAYCLIENT");
++ if (!relayclient && relayhostsok) {
++ int j;
++ int l = str_len(remotehost);
++ relayclient = constmap(&maprelayhosts, remotehost, l);
++ if (!relayclient) for (j = 0; j < l; ++j) {
++ if (remotehost[j] == '.' &&
++ (relayclient = constmap(&maprelayhosts,
++ remotehost + j,
++ l - j)) != 0)
++ break;
+ }
- qmail_put(&qqt,&ch,1);
+ }
+ dohelo(remotehost);
}
+
+stralloc addr = {0}; /* will be 0-terminated, if addrparse returns 1 */
+
int addrparse(arg)
char *arg;
{