From: Mark Wooding Date: Thu, 16 Mar 2006 23:16:15 +0000 (+0000) Subject: Merge branch 'nail' X-Git-Tag: mdw/1.03-5^0 X-Git-Url: https://git.distorted.org.uk/~mdw/qmail/commitdiff_plain/5794b37af853f8e487dc5f7c2a83220b3899f596?hp=5373b260c0d8b51ad88c73a4d81017db03e5a998 Merge branch 'nail' * nail: addrcheck: Don't spew userv error messages at SMTP clients. addrcheck: Strip off the domain part before passing to userv service. addrcheck: Add commentary for the functions, because I'm confused. --- diff --git a/.gitignore b/.gitignore index 60532c2..f4c3f19 100644 --- a/.gitignore +++ b/.gitignore @@ -166,3 +166,4 @@ tcp-env tcp-env.0 tcp-environ.0 uint32.h +qmail-valid-addresses.0 diff --git a/debian/.gitignore b/debian/.gitignore index 0f1983d..2caa678 100644 --- a/debian/.gitignore +++ b/debian/.gitignore @@ -1,3 +1,6 @@ files qmail-src tmp +mini-qmail +mini-qmail.substvars +substvars diff --git a/debian/changelog b/debian/changelog index c85d4b9..6d7a1eb 100644 --- a/debian/changelog +++ b/debian/changelog @@ -3,6 +3,7 @@ qmail (1.03-5) unstable; urgency=low * make it build again. * add mini-qmail package. * support checking of recipient mailboxes in qmail-smtpd. + * import verh and qmqpc patches from ezmlm-idx. -- Mark Wooding Mon, 2 May 2005 14:44:12 +0100 diff --git a/debian/control b/debian/control index 9bd4434..ac47580 100644 --- a/debian/control +++ b/debian/control @@ -1,5 +1,5 @@ Source: qmail -Maintainer: Mark Wooding +Maintainer: Mark Wooding Section: mail Priority: extra Standards-Version: 2.1.2.2 diff --git a/debian/rules b/debian/rules index 6316dc9..b9ceed6 100755 --- a/debian/rules +++ b/debian/rules @@ -1,6 +1,11 @@ #!/usr/bin/make -f # +mdw-setup: + upstream=`git-describe djb | sed 's:^djb/::'`; \ + dir=qmail_$$upstream.orig; \ + git-tar-tree djb $$dir | gzip -9c >../$$dir.tar.gz + build: $(checkdir) if fgrep QMAIL/bin *.sh >/dev/null; then \ @@ -116,11 +121,13 @@ endef binary: binary-indep binary-arch -source diff: - @echo >&2 'source and diff are obsolete - use dpkg-source -b'; false +source: clean mdw-setup + dir=`pwd | sed 's:^.*/::'`; \ + cd ..; \ + dpkg-source -b -i'(?:^|/)\.git(?:$$|/)' $$dir checkroot: $(checkdir) test "`whoami`" = root -.PHONY: binary binary-arch binary-indep clean checkroot +.PHONY: binary binary-arch binary-indep clean checkroot source mdw-setup diff --git a/error.h b/error.h index 01bd3dc..5d98c6b 100644 --- a/error.h +++ b/error.h @@ -1,7 +1,7 @@ #ifndef ERROR_H #define ERROR_H -extern int errno; +#include extern int error_intr; extern int error_nomem; diff --git a/qmail-local.c b/qmail-local.c index cd01602..ec4e5e7 100644 --- a/qmail-local.c +++ b/qmail-local.c @@ -63,6 +63,51 @@ stralloc ueo = {0}; stralloc cmds = {0}; stralloc messline = {0}; stralloc foo = {0}; +stralloc qsender = {0}; +stralloc tmpline = {0}; +char *verhhost = (char *)0; +char *verhlocal = (char *)0; +int flagheader,flagdobody; +unsigned int i; + +int verhline(sa) +stralloc *sa; +/* substitutes ##L => recipient local, ##H => recipient host if VERP sender */ +/* returns 0 normally, -1 on out-of-memory */ +{ + register char *cp; + char *cpnext,*cpafter; + + if (!verhlocal) return 0; /* no VERP SENDER */ + cp = sa->s; + cpnext = sa->s; + cpafter = cp + sa->len; + tmpline.len = 0; /* clear */ + for (;;) { + while (cp < cpafter && *cp++ != '#'); + if (cp + 1 < cpafter && *cp == '#') { /* found '##' */ + cp++; + if (*cp == 'L') { /* ##L */ + if (!stralloc_catb(&tmpline,cpnext,cp - cpnext - 2)) return -1; + cp++; + cpnext = cp; + if (!stralloc_cats(&tmpline,verhlocal)) return -1; + } else if (*cp == 'H') { /* ##H */ + if (!stralloc_catb(&tmpline,cpnext,cp - cpnext - 2)) return -1; + cp++; + cpnext = cp; + if (!stralloc_cats(&tmpline,verhhost)) return -1; + } + } + if (cp >= cpafter) { + if (tmpline.len) { /* true if we've done any substitutions */ + if (!stralloc_catb(&tmpline,cpnext,cpafter - cpnext)) return -1; + if (!stralloc_copy(sa,&tmpline)) return -1; + } + return 0; + } + } +} char buf[1024]; char outbuf[1024]; @@ -82,6 +127,7 @@ char *dir; char host[64]; char *s; int loop; + int match; struct stat st; int fd; substdio ss; @@ -117,11 +163,27 @@ char *dir; if (substdio_put(&ssout,rpline.s,rpline.len) == -1) goto fail; if (substdio_put(&ssout,dtline.s,dtline.len) == -1) goto fail; - switch(substdio_copy(&ssout,&ss)) - { - case -2: tryunlinktmp(); _exit(4); - case -3: goto fail; - } + flagheader = 1; + flagdobody = 0; + do { /* for VERH */ + if (getln(&ss,&messline,&match,'\n') != 0) + { tryunlinktmp(); _exit(4); } + if (flagheader) { + if (match && messline.len == 1) { + flagheader = 0; + if (!flagdobody) verhlocal = (char *)0; + } + if (messline.s[0] == '#') { /* continue in body */ + flagdobody = 1; /* remove leading '#' */ + for (i = 1; i < messline.len; i++) + messline.s[i - 1] = messline.s[i]; + messline.len--; /* always >= 1 from \n */ + } + } + if (verhlocal) + if (verhline(&messline) == -1) goto fail; + if (substdio_put(&ssout,messline.s,messline.len) == -1) goto fail; + } while (match); if (substdio_flush(&ssout) == -1) goto fail; if (fsync(fd) == -1) goto fail; @@ -193,6 +255,8 @@ char *fn; substdio_fdbuf(&ss,read,0,buf,sizeof(buf)); substdio_fdbuf(&ssout,write,fd,outbuf,sizeof(outbuf)); + flagheader = 1; + flagdobody = 0; if (substdio_put(&ssout,ufline.s,ufline.len)) goto writeerrs; if (substdio_put(&ssout,rpline.s,rpline.len)) goto writeerrs; if (substdio_put(&ssout,dtline.s,dtline.len)) goto writeerrs; @@ -207,6 +271,20 @@ char *fn; if (!match && !messline.len) break; if (gfrom(messline.s,messline.len)) if (substdio_bput(&ssout,">",1)) goto writeerrs; + if (flagheader) { + if (match && messline.len == 1) { + if (!flagdobody) verhlocal = (char *)0; + flagheader = 0; + } + if (messline.s[0] == '#') { /* continue in body */ + flagdobody = 1; /* remove leading '#' */ + for (i = 1; i < messline.len; i++) + messline.s[i - 1] = messline.s[i]; + messline.len--; + } + } + if (verhlocal) + if (verhline(&messline) == -1) goto writeerrs; if (substdio_bput(&ssout,messline.s,messline.len)) goto writeerrs; if (!match) { @@ -276,9 +354,24 @@ char **recips; if (qmail_open(&qqt) == -1) temp_fork(); mailforward_qp = qmail_qp(&qqt); qmail_put(&qqt,dtline.s,dtline.len); + flagheader = 1; do { if (getln(&ss,&messline,&match,'\n') != 0) { qmail_fail(&qqt); break; } + if (flagheader) { + if (match && messline.len == 1) { + flagheader = 0; + if (!flagdobody) verhlocal = (char *)0; + } + if (messline.s[0] == '#') { /* continue in body */ + flagdobody = 1; /* remove leading '#' */ + for (i = 1; i < messline.len; i++) + messline.s[i - 1] = messline.s[i]; + messline.len--; + } + } + if (verhlocal) + if (verhline(&messline) == -1) { qmail_fail(&qqt); break; } qmail_put(&qqt,messline.s,messline.len); } while (match); @@ -458,6 +551,7 @@ char **argv; datetime_sec starttime; int flagforwardonly; char *x; + char *cplast; umask(077); sig_pipeignore(); @@ -518,9 +612,9 @@ char **argv; if (!env_put2("SENDER",sender)) temp_nomem(); - if (!quote2(&foo,sender)) temp_nomem(); + if (!quote2(&qsender,sender)) temp_nomem(); if (!stralloc_copys(&rpline,"Return-Path: <")) temp_nomem(); - if (!stralloc_cat(&rpline,&foo)) temp_nomem(); + if (!stralloc_cat(&rpline,&qsender)) temp_nomem(); for (i = 0;i < rpline.len;++i) if (rpline.s[i] == '\n') rpline.s[i] = '_'; if (!stralloc_cats(&rpline,">\n")) temp_nomem(); @@ -528,6 +622,33 @@ char **argv; if (!stralloc_0(&foo)) temp_nomem(); if (!env_put2("RPLINE",foo.s)) temp_nomem(); + i = byte_rchr(qsender.s,qsender.len,'@'); /* for VERH */ + if (i != qsender.len) { /* got @ */ + cplast = qsender.s + i; + *cplast = '\0'; + if (qsender.s[i = str_rchr(qsender.s,'=')]) { /* got = */ + qsender.s[i] = '\0'; + cplast = qsender.s + i; + verhhost = qsender.s + i + 1; + i = str_rchr(qsender.s,'-'); + if (qsender.s[i] == '-') { + for (;;) { + if (case_starts(qsender.s + i + 1,"return-")) { + verhlocal = qsender.s + i + 9 + str_chr(qsender.s + i + 8,'-'); + /* here to avoid work if not VERP */ + /* verhhost not used if verhlocal=0 */ + for (x = verhlocal; x < cplast; x++) + if (*x == '\n') *x = '_'; /* \n would ruin */ + break; + } + j = byte_rchr(qsender.s,i,'-'); + if (j == i) break; + i = j; + } + } + } + } + if (!stralloc_copys(&ufline,"From ")) temp_nomem(); if (*sender) { diff --git a/qmail-qmqpc.8 b/qmail-qmqpc.8 index e11a15e..d8fbbb5 100644 --- a/qmail-qmqpc.8 +++ b/qmail-qmqpc.8 @@ -3,6 +3,9 @@ qmail-qmqpc \- queue a mail message via QMQP .SH SYNOPSIS .B qmail-qmqpc +[ +.I server +[...] ] .SH DESCRIPTION .B qmail-qmqpc offers the same interface as @@ -16,6 +19,13 @@ installation, .B qmail-queue is replaced with a symbolic link to .BR qmail-qmqpc . + +If one or more server IP addresses +are specified on the command line, +.B qmail-qmqpc +will ignore the control files and instead use the QMQP servers specified on the +command line. + .SH "CONTROL FILES" .TP 5 .I qmqpservers @@ -23,6 +33,7 @@ IP addresses of QMQP servers, one address per line. .B qmail-qmqpc will try each address in turn until it establishes a QMQP connection or runs out of addresses. + .SH "SEE ALSO" qmail-control(5), qmail-queue(8), diff --git a/qmail-qmqpc.c b/qmail-qmqpc.c index d5adf05..88de856 100644 --- a/qmail-qmqpc.c +++ b/qmail-qmqpc.c @@ -135,25 +135,36 @@ char *server; stralloc servers = {0}; -main() +main(argc,argv) +int argc; +char **argv; { int i; int j; sig_pipeignore(); - if (chdir(auto_qmail) == -1) die_home(); - if (control_init() == -1) die_control(); - if (control_readfile(&servers,"control/qmqpservers",0) != 1) die_control(); + if (!argv[1]) { /* std behavior */ + if (chdir(auto_qmail) == -1) die_home(); + if (control_init() == -1) die_control(); + if (control_readfile(&servers,"control/qmqpservers",0) != 1) die_control(); - getmess(); + getmess(); - i = 0; - for (j = 0;j < servers.len;++j) - if (!servers.s[j]) { - doit(servers.s + i); - i = j + 1; - } + i = 0; + for (j = 0;j < servers.len;++j) + if (!servers.s[j]) { + doit(servers.s + i); + i = j + 1; + } + } else { /* servers on cmd line */ + + getmess(); + + i = 1; + while (argv[i]) + doit(argv[i++]); + } _exit(lasterror); } diff --git a/qmail-remote.c b/qmail-remote.c index 7d65473..864dee2 100644 --- a/qmail-remote.c +++ b/qmail-remote.c @@ -189,19 +189,68 @@ char *append; zerodie(); } +stralloc verh = {0}; /* quoted recipient */ +int flagverh; /* argc */ +char *vp; /* argv[3] */ + void blast() { + unsigned int posat, i; + int flagdobody,flagheader; int r; char ch; + posat = 0; /* stays 0 if no VERH */ + flagdobody = 0; /* => 0 at first blank line */ + flagheader = 1; + if (flagverh == 4) { /* only if single recipient */ + if (!quote2(&verh,vp)) temp_nomem(); /* non-canonicalized */ + for (i = 0; i < verh.len; i++) /* \n would destroy message */ + if (verh.s[i] == '\n') verh.s[i] = '_'; + posat = byte_rchr(verh.s,verh.len,'@'); /* posat=0 if no VERH */ + if (posat == verh.len) posat = 0; + } for (;;) { r = substdio_get(&ssin,&ch,1); if (r == 0) break; if (r == -1) temp_read(); if (ch == '.') substdio_put(&smtpto,".",1); + if (flagheader) { + if (ch == '\n') { /* header ends */ + flagheader = 0; + if (!flagdobody) posat = 0; + } else if (ch == '#') { /* # starting line => VERH ... */ + flagdobody = 1; /* continues in body and ... */ + continue; /* character is suppressed. */ + } + } while (ch != '\n') { - substdio_put(&smtpto,&ch,1); + if (ch == '#' && posat) { /* ... # */ + r = substdio_get(&ssin,&ch,1); + if (r == 0) perm_partialline(); + if (r == -1) temp_read(); + if (ch == '#') { /* ... ## */ + register char ch1; + ch1 = *substdio_peek(&ssin); + if (ch1 != 'L' && ch1 != 'H') { /* ... ##x x!=L x!=H */ + substdio_put(&smtpto,"#",1); + continue; + } + r = substdio_get(&ssin,&ch,1); + if (r == 0) perm_partialline(); + if (r == -1) temp_read(); + if (ch == 'L') /* ... ##L */ + substdio_put(&smtpto,verh.s,posat); + else /* ... ##H */ + substdio_put(&smtpto,verh.s + posat + 1,verh.len - posat - 1); + } else { + substdio_put(&smtpto,"#",1); + if (ch == '\n') break; + substdio_put(&smtpto,&ch,1); + } + } else + substdio_put(&smtpto,&ch,1); r = substdio_get(&ssin,&ch,1); if (r == 0) perm_partialline(); if (r == -1) temp_read(); @@ -341,6 +390,8 @@ char **argv; sig_pipeignore(); if (argc < 4) perm_usage(); + flagverh = argc; + vp = argv[3]; if (chdir(auto_qmail) == -1) temp_chdir(); getcontrols();