Merge branch 'nail' mdw/1.03-5
authorMark Wooding <mdw@distorted.org.uk>
Thu, 16 Mar 2006 23:16:15 +0000 (23:16 +0000)
committerMark Wooding <mdw@distorted.org.uk>
Thu, 16 Mar 2006 23:16:15 +0000 (23:16 +0000)
* 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.

.gitignore
debian/.gitignore
debian/changelog
debian/control
debian/rules
error.h
qmail-local.c
qmail-qmqpc.8
qmail-qmqpc.c
qmail-remote.c

index 60532c2..f4c3f19 100644 (file)
@@ -166,3 +166,4 @@ tcp-env
 tcp-env.0
 tcp-environ.0
 uint32.h
+qmail-valid-addresses.0
index 0f1983d..2caa678 100644 (file)
@@ -1,3 +1,6 @@
 files
 qmail-src
 tmp
+mini-qmail
+mini-qmail.substvars
+substvars
index c85d4b9..6d7a1eb 100644 (file)
@@ -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 <mdw@nsict.org>  Mon,  2 May 2005 14:44:12 +0100
 
index 9bd4434..ac47580 100644 (file)
@@ -1,5 +1,5 @@
 Source: qmail
-Maintainer: Mark Wooding <mdw@nsict.org>
+Maintainer: Mark Wooding <mdw@distorted.org.uk>
 Section: mail
 Priority: extra
 Standards-Version: 2.1.2.2
index 6316dc9..b9ceed6 100755 (executable)
@@ -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 (file)
--- a/error.h
+++ b/error.h
@@ -1,7 +1,7 @@
 #ifndef ERROR_H
 #define ERROR_H
 
-extern int errno;
+#include <errno.h>
 
 extern int error_intr;
 extern int error_nomem;
index cd01602..ec4e5e7 100644 (file)
@@ -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)
   {
index e11a15e..d8fbbb5 100644 (file)
@@ -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),
index d5adf05..88de856 100644 (file)
@@ -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);
 }
index 7d65473..864dee2 100644 (file)
@@ -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();