On Thu, 10 Jun 2004, [EMAIL PROTECTED] wrote:

> Why not use /var/qmail/control/rewrite?  I already use it with
> new-inject; the logic should not be too hard to implement for
> rewriting envelope recipients' domains as well BEFORE they are checked
> in the LDAP directory.

Claudio and all,

attached is my (VERY crude) patch attempting to install rewrite
support into qmail-smtpd.  The patch is UNTESTED, but it compiles
cleanly.  The rewrite is done on the sender and the recipient in the
right places (I think), right before the LDAP lookup.

It uses rwhconfig.[ch], rewritehost.[ch], and some other files from
mess822.  Nothing too bad, since a lot of those files are shared
between mess822 and qmail itself.

I am very rusty with my C, plus I don't know Claudio's coding
conventions and intentions, so I didn't try to thoroughly implement
and test the rewriting.  Rather, I tried to show a proof of concept
about how the rewriting support will work, rewriting sender and
recipient addresses under the right conditions.  I hope Claudio or
someone else will find it useful as a starting point and finish the
rewriting support.

Leandro's recently posted question about alternate domains shows that
there's a need for this patch besides just me, even though there are
makeshift solutions (in lifewithqmail.org/ldap) when only 1-5 domains
need to be handled in a special way.

Thanks
Ted

diff -Naur qmail-ldap-20040401/Makefile qmail-ldap-20040401-rewrite/Makefile
--- qmail-ldap-20040401/Makefile	2004-06-25 11:16:01.000000000 -0400
+++ qmail-ldap-20040401-rewrite/Makefile	2004-06-25 13:06:34.000000000 -0400
@@ -175,7 +175,7 @@
 	control.o qldap.a constmap.o getln.a strerr.a substdio.a stralloc.a \
 	env.a alloc.a str.a case.a fs.a error.a open.a prot.o auto_uids.o \
 	auto_qmail.o $(LDAPLIBS) $(SHADOWLIBS)
-	
+
 auth_smtp.o: \
 compile auth_smtp.c byte.h env.h error.h exit.h output.h qldap.h \
 qldap-debug.h qldap-errno.h qmail-ldap.h read-ctrl.h str.h stralloc.h \
@@ -1500,12 +1500,12 @@
 	./load qmail-forward qmail.o control.o now.o env.a fd.a wait.a \
 	open.a getln.a seek.a strerr.a stralloc.a alloc.a substdio.a \
 	error.a str.a fs.a auto_qmail.o
-	
+
 qmail-forward.o: \
 compile qmail-forward.c auto_qmail.h control.h error.h fmt.h getln.h now.h \
 qmail.h seek.h str.h stralloc.h strerr.h substdio.h
 	./compile $(LDAPFLAGS) qmail-forward.c
-	
+
 qmail-getpw: \
 load qmail-getpw.o case.a substdio.a error.a str.a fs.a auto_break.o \
 auto_usera.o
@@ -2012,7 +2012,7 @@
 	now.o date822fmt.o datetime.a mailmaker.o mailmagic.o case.a getln.a \
 	qmail.o getopt.a seek.a fd.a wait.a sig.a open.a stralloc.a env.a \
 	alloc.a strerr.a substdio.a error.a str.a fs.a auto_qmail.o
-	
+
 qmail-secretary.o: \
 compile qmail-secretary.c uint32.h base64.h byte.h case.h digest_sha1.h \
 env.h error.h fmt.h getln.h mailmagic.h now.h open.h seek.h sgetopt.h \
@@ -2073,12 +2073,12 @@
 	./compile qmail-showctl.c
 
 qmail-smtpd: \
-load qmail-smtpd.o rcpthosts.o commands.o timeoutread.o rbl.o \
+load stralloc_num.o strerr_sys.o rewritehost.o rwhconfig.o config.o qmail-smtpd.o rcpthosts.o commands.o timeoutread.o rbl.o \
 timeoutwrite.o ip.o ipme.o ipalloc.o control.o constmap.o received.o \
 date822fmt.o now.o qmail.o execcheck.o cdb.a smtpcall.o coe.o fd.a wait.a \
 datetime.a getln.a open.a sig.a case.a env.a stralloc.a alloc.a \
 substdio.a error.a str.a fs.a auto_qmail.o dns.lib socket.lib
-	./load qmail-smtpd rcpthosts.o commands.o timeoutread.o rbl.o \
+	./load qmail-smtpd stralloc_num.o strerr_sys.o rewritehost.o rwhconfig.o config.o rcpthosts.o commands.o timeoutread.o rbl.o \
 	timeoutwrite.o ip.o ipme.o ipalloc.o control.o constmap.o \
 	received.o date822fmt.o now.o qmail.o execcheck.o cdb.a \
 	smtpcall.o coe.o fd.a wait.a datetime.a getln.a open.a sig.a \
diff -Naur qmail-ldap-20040401/TARGETS qmail-ldap-20040401-rewrite/TARGETS
--- qmail-ldap-20040401/TARGETS	2004-06-25 11:16:01.000000000 -0400
+++ qmail-ldap-20040401-rewrite/TARGETS	2004-06-25 11:45:51.000000000 -0400
@@ -461,5 +461,8 @@
 qmail.run
 rbl.o
 read-ctrl.o
+config.o
 readwrite.o
+rewritehost.o
+rwhconfig.o
 smtpcall.o
diff -Naur qmail-ldap-20040401/config.3 qmail-ldap-20040401-rewrite/config.3
--- qmail-ldap-20040401/config.3	1969-12-31 19:00:00.000000000 -0500
+++ qmail-ldap-20040401-rewrite/config.3	2004-06-25 11:41:10.000000000 -0400
@@ -0,0 +1,120 @@
+.TH config 3
+.SH NAME
+config \- read optional configuration data
+.SH SYNTAX
+.B #include <config.h>
+
+int \fBconfig\fP(&\fIc\fR);
+.br
+stralloc *\fBconfig_data\fP(&\fIc\fR);
+
+int \fBconfig_default\fP(&\fIc\fR,\fIs\fR);
+.br
+int \fBconfig_copy\fP(&\fIc\fR,&\fId\fR);
+.br
+int \fBconfig_env\fP(&\fIc\fR,\fIs\fR);
+.br
+int \fBconfig_readline\fP(&\fIc\fR,\fIs\fR);
+.br
+int \fBconfig_readfile\fP(&\fIc\fR,\fIs\fR);
+
+config_str \fIc\fR = CONFIG_STR;
+.br
+config_str \fId\fR = CONFIG_STR;
+
+char *\fIs\fR;
+.SH DESCRIPTION
+A
+.B config_str
+such as
+.I c
+holds an optional configuration string
+in dynamically allocated memory.
+
+The configuration string is stored inside a
+.BR stralloc .
+.B config_data
+returns a pointer to the
+.BR stralloc .
+
+.B config
+returns 1 if
+.I c
+has been configured,
+0 otherwise.
+
+Initially
+.I c
+is set to 
+.BR CONFIG_STR ,
+which is unconfigured.
+.SH "READING CONFIGURATION"
+The following functions attempt to configure
+.IR c .
+They return 0 without changing
+.I c
+if
+.I c
+is already configured;
+otherwise they configure
+.I c
+and return 0 if configuration data is supplied;
+otherwise they leave
+.I c
+unconfigured and return 0.
+They return -1,
+leaving
+.I c
+unconfigured,
+if a temporary error (out of memory, I/O error, etc.) occurs.
+
+.B config_default
+configures
+.I c
+as a copy of the \e0-terminated string
+.IR s ,
+if
+.I s
+is not the zero pointer.
+
+.B config_copy
+configures
+.I c
+as a copy of
+.I d
+if
+.I d
+is configured.
+
+.B config_env
+configures
+.I c
+as a copy of
+the first environment variable named
+.IR s ,
+if the environment has such a variable.
+
+.B config_readline
+configures
+.I c
+as the first line of the file named
+.IR s ,
+if that file exists.
+It removes any trailing spaces or tabs from the line.
+It also converts every \e0 inside the line to \en,
+so that the string can be used as a \e0-terminated string after
+.BR stralloc_0 .
+
+.B config_readfile
+configures
+.I c
+as the entire contents of the file named
+.IR s ,
+if that file exists.
+For each line, it removes any trailing spaces or tabs,
+converts every \e0 inside the line to \en,
+and puts a \e0 at the end of the line
+(even if the line was originally a partial final line).
+It skips blank lines and lines beginning with #.
+.SH "SEE ALSO"
+stralloc(3)
diff -Naur qmail-ldap-20040401/config.c qmail-ldap-20040401-rewrite/config.c
--- qmail-ldap-20040401/config.c	1969-12-31 19:00:00.000000000 -0500
+++ qmail-ldap-20040401-rewrite/config.c	2004-06-25 11:54:40.000000000 -0400
@@ -0,0 +1,125 @@
+#include "open.h"
+#include "readwrite2.h"
+#include "substdio.h"
+#include "error.h"
+#include "getln.h"
+#include "stralloc.h"
+#include "config.h"
+#include "env.h"
+
+int config_default(c,s)
+config_str *c;
+char *s;
+{
+  if (c->flagconf) return 0;
+  if (!s) return 0;
+  if (!stralloc_copys(&c->sa,s)) return -1;
+  c->flagconf = 1;
+  return 0;
+}
+
+int config_copy(c,d)
+config_str *c;
+config_str *d;
+{
+  if (c->flagconf) return 0;
+  if (!d->flagconf) return 0;
+  if (!stralloc_copy(&c->sa,&d->sa)) return -1;
+  c->flagconf = 1;
+  return 0;
+}
+
+int config_env(c,s)
+config_str *c;
+char *s;
+{
+  if (c->flagconf) return 0;
+  s = env_get(s);
+  if (!s) return 0;
+  if (!stralloc_copys(&c->sa,s)) return -1;
+  c->flagconf = 1;
+  return 0;
+}
+
+static void process(sa)
+stralloc *sa;
+{
+  int i;
+
+  while (sa->len > 0)
+    switch(sa->s[sa->len - 1]) {
+      case '\n': case ' ': case '\t':
+	--sa->len; break;
+      default:
+	for (i = 0;i < sa->len;++i)
+	  if (sa->s[i] == 0)
+	    sa->s[i] = '\n';
+	return;
+    }
+}
+
+static char inbuf[128];
+static stralloc line = {0};
+
+int config_readline(c,fn)
+config_str *c;
+char *fn;
+{
+  substdio ss;
+  int fd;
+  int match;
+
+  if (c->flagconf) return 0;
+
+  fd = open_read(fn);
+  if (fd == -1) {
+    if (errno == error_noent) return 0;
+    return -1;
+  }
+  substdio_fdbuf(&ss,read,fd,inbuf,sizeof inbuf);
+
+  if (getln(&ss,&line,&match,'\n') == -1) {
+    close(fd);
+    return -1;
+  }
+  close(fd);
+ 
+  process(&line);
+  if (!stralloc_copy(&c->sa,&line)) return -1;
+  c->flagconf = 1;
+  return 0;
+}
+
+int config_readfile(c,fn)
+config_str *c;
+char *fn;
+{
+  substdio ss;
+  int fd;
+  int match;
+
+  if (c->flagconf) return 0;
+
+  if (!stralloc_copys(&c->sa,"")) return -1;
+
+  fd = open_read(fn);
+  if (fd == -1) {
+    if (errno == error_noent) return 0;
+    return -1;
+  }
+  substdio_fdbuf(&ss,read,fd,inbuf,sizeof inbuf);
+
+  for (;;) {
+    if (getln(&ss,&line,&match,'\n') == -1) { close(fd); return -1; }
+    process(&line);
+    if (!stralloc_0(&line)) { close(fd); return -1; }
+    if (line.s[0])
+      if (line.s[0] != '#')
+	if (!stralloc_cat(&c->sa,&line)) { close(fd); return -1; }
+    if (!match) break;
+  }
+  close(fd);
+
+  c->flagconf = 1;
+  return 0;
+}
diff -Naur qmail-ldap-20040401/config.h qmail-ldap-20040401-rewrite/config.h
--- qmail-ldap-20040401/config.h	1969-12-31 19:00:00.000000000 -0500
+++ qmail-ldap-20040401-rewrite/config.h	2004-06-25 11:41:10.000000000 -0400
@@ -0,0 +1,22 @@
+#ifndef CONFIG_H
+#define CONFIG_H
+
+#include "stralloc.h"
+
+typedef struct {
+  stralloc sa;
+  int flagconf;
+} config_str;
+
+#define CONFIG_STR {{0},0}
+
+#define config(c) ((c)->flagconf)
+#define config_data(c) (&((c)->sa))
+
+extern int config_default();
+extern int config_copy();
+extern int config_env();
+extern int config_readline();
+extern int config_readfile();
+
+#endif
diff -Naur qmail-ldap-20040401/qmail-smtpd.c qmail-ldap-20040401-rewrite/qmail-smtpd.c
--- qmail-ldap-20040401/qmail-smtpd.c	2004-06-25 11:16:04.000000000 -0400
+++ qmail-ldap-20040401-rewrite/qmail-smtpd.c	2004-06-25 11:54:30.000000000 -0400
@@ -41,6 +41,18 @@
 #include <zlib.h>
 #endif
 
+#define SMTP_REWRITE 1
+
+#ifdef SMTP_REWRITE
+#include "config.h"
+#include "rewritehost.h"
+#include "rwhconfig.h"
+stralloc idappend = {0};
+stralloc addr_rewrite = {0};
+config_str rewrite = CONFIG_STR;
+#define SMTP_REWRITE_LOGLEVEL 2
+#endif
+
 #define MAXHOPS 100
 #define MAXLINELEN 10000
 unsigned long databytes = 0;
@@ -958,6 +970,10 @@
     if (!goodmailaddr()) { /* good mail addrs go through anyway */
       if (addrlocals()) {
 	char *s;
+	#ifdef SMTP_REWRITE
+	if(!rewrite_address())
+	  logline(SMTP_REWRITE_LOGLEVEL, "rewrote sender address according to rewrite rules");
+	#endif
         switch (ldaplookup(addr.s, &s)) {
           case 1: /* valid */
             break;
@@ -1083,6 +1099,10 @@
       if (addrlocals()) {
 	char *s;
 	logline(3,"recipient verify, recipient is local");
+	#ifdef SMTP_REWRITE
+	if(!rewrite_address())
+	  logline(SMTP_REWRITE_LOGLEVEL, "rewrote recipient address according to rewrite rules");
+	#endif
         switch (ldaplookup(addr.s, &s)) {
           case 1: /* valid */
 	    logline(3,"recipient verify OK");
@@ -1116,6 +1136,27 @@
   out("250 ok\r\n");
 }
 
+#ifdef SMTP_REWRITE
+
+/* Note this function operates on the global addr variable */
+int rewrite_address(void)
+{
+  if (rwhconfig(&rewrite,&idappend) == -1)
+    {
+      logline(SMTP_REWRITE_LOGLEVEL, "rwhconfig failed, not rewriting address");
+      return 1;
+    }
+  else
+    {
+      if (!stralloc_copy(&addr_rewrite,&addr)) die_nomem();
+      if (!rewritehost_addr(&addr_rewrite,addr.s,addr.len,config_data(&rewrite))) die_nomem();
+      if (!stralloc_0(&addr_rewrite)) die_nomem();
+      if (!stralloc_copy(&addr,&addr_rewrite)) die_nomem();
+    }
+  return 0;
+}
+#endif
+
 #ifdef DATA_COMPRESS
 z_stream stream;
 char zbuf[4096];
diff -Naur qmail-ldap-20040401/readwrite2.h qmail-ldap-20040401-rewrite/readwrite2.h
--- qmail-ldap-20040401/readwrite2.h	1969-12-31 19:00:00.000000000 -0500
+++ qmail-ldap-20040401-rewrite/readwrite2.h	2004-06-25 11:53:57.000000000 -0400
@@ -0,0 +1,7 @@
+#ifndef READWRITE_H
+#define READWRITE_H
+
+extern int read();
+extern int write();
+
+#endif
diff -Naur qmail-ldap-20040401/rewritehost.3 qmail-ldap-20040401-rewrite/rewritehost.3
--- qmail-ldap-20040401/rewritehost.3	1969-12-31 19:00:00.000000000 -0500
+++ qmail-ldap-20040401-rewrite/rewritehost.3	2004-06-25 11:42:21.000000000 -0400
@@ -0,0 +1,82 @@
+.TH rewritehost 3
+.SH NAME
+rewritehost \- make syntactic changes to host names
+.SH SYNTAX
+.B #include <rewritehost.h>
+
+int \fBrewritehost\fP(&\fIout\fR,\fIbuf\fR,\fIlen\fR,&\fIrules\fR);
+.br
+int \fBrewritehost_addr\fP(&\fIout\fR,\fIbuf\fR,\fIlen\fR,&\fIrules\fR);
+.br
+int \fBrewritehost_list\fP(&\fIout\fR,\fIbuf\fR,\fIlen\fR,&\fIrules\fR);
+
+stralloc \fIrules\fR;
+.br
+stralloc \fIout\fR;
+.br
+char *\fIbuf\fR;
+.br
+unsigned int \fIlen\fR;
+.SH DESCRIPTION
+.B rewritehost
+reads a host name from
+.I buf
+of length
+.IR len ,
+rewrites it according to instructions in
+.IR rules ,
+and puts the rewritten host name into
+.IR out .
+.I rules
+is a series of \e0-terminated instructions;
+see
+.BR rewriting (5)
+for the instruction format.
+
+.B rewritehost_addr
+reads an address in the form
+.I [EMAIL PROTECTED]
+from
+.I buf
+of length
+.IR len .
+It rewrites
+.I host
+according to instructions in
+.IR rules ,
+unless both
+.I user
+and
+.I host
+are empty,
+in which case it rewrites the address as the empty string.
+It puts the rewritten address into
+.IR out .
+.B rewritehost_addr
+accepts
+.I user
+as a synonym for
+.I user\fB@
+with an empty host name.
+
+.B rewritehost_list
+reads an address list from
+.I buf
+of length
+.IR len ,
+rewrites each address in the list
+according to instructions in
+.IR rules ,
+and puts the rewritten address list into
+.IR out .
+The address list consists of \e0-terminated chunks;
+a chunk is either an address preceded by a plus sign,
+or a comment preceded by a left parenthesis.
+.B rewritehost_list
+copies comments without change.
+
+Each function returns 1 if it succeeds,
+0 if it runs out of memory.
+.SH "SEE ALSO"
+stralloc(3),
+rewriting(5)
diff -Naur qmail-ldap-20040401/rewritehost.c qmail-ldap-20040401-rewrite/rewritehost.c
--- qmail-ldap-20040401/rewritehost.c	1969-12-31 19:00:00.000000000 -0500
+++ qmail-ldap-20040401-rewrite/rewritehost.c	2004-06-25 11:42:21.000000000 -0400
@@ -0,0 +1,112 @@
+#include "stralloc.h"
+#include "str.h"
+#include "case.h"
+#include "rewritehost.h"
+
+static stralloc work = {0};
+
+static int doit(rule)
+char *rule;
+{
+  int colon;
+  char ch;
+  int prefixlen;
+
+  ch = *rule++;
+  if ((ch != '?') && (ch != '=') && (ch != '*') && (ch != '-')) return 1;
+  colon = str_chr(rule,':');
+  if (!rule[colon]) return 1;
+  if (work.len < colon) return 1;
+
+  prefixlen = work.len - colon;
+  if ((ch == '=') && prefixlen) return 1;
+  if (case_diffb(rule,colon,work.s + prefixlen)) return 1;
+
+  if (ch == '?') {
+    if (byte_chr(work.s,prefixlen,'.') < prefixlen) return 1;
+    if (byte_chr(work.s,prefixlen,'[') < prefixlen) return 1;
+    if (byte_chr(work.s,prefixlen,']') < prefixlen) return 1;
+  }
+
+  work.len = prefixlen;
+  if (ch == '-') work.len = 0;
+
+  return stralloc_cats(&work,rule + colon + 1);
+}
+
+static int appendwork(out,rules)
+stralloc *out;
+stralloc *rules;
+{
+  int i;
+  int j;
+
+  for (j = i = 0;j < rules->len;++j)
+    if (!rules->s[j]) {
+      if (!doit(rules->s + i)) return 0;
+      i = j + 1;
+    }
+  return stralloc_cat(out,&work);
+}
+
+static int appendaddr(out,in,len,rules)
+stralloc *out;
+char *in;
+unsigned int len;
+stralloc *rules;
+{
+  int at;
+
+  at = byte_chr(in,len,'@');
+  if (!at) if (len <= 1) return 1;
+  if (!stralloc_catb(out,in,at)) return 0;
+  if (!stralloc_append(out,"@")) return 0;
+  if (at < len) ++at;
+  if (!stralloc_copyb(&work,in + at,len - at)) return 0;
+  return appendwork(out,rules);
+}
+
+int rewritehost(out,in,len,rules)
+stralloc *out;
+char *in;
+unsigned int len;
+stralloc *rules;
+{
+  if (!stralloc_copys(out,"")) return 0;
+  if (!stralloc_copyb(&work,in,len)) return 0;
+  return appendwork(out,rules);
+}
+
+int rewritehost_addr(out,in,len,rules)
+stralloc *out;
+char *in;
+unsigned int len;
+stralloc *rules;
+{
+  if (!stralloc_copys(out,"")) return 0;
+  return appendaddr(out,in,len,rules);
+}
+
+int rewritehost_list(out,in,len,rules)
+stralloc *out;
+char *in;
+unsigned int len;
+stralloc *rules;
+{
+  int i;
+  int j;
+
+  if (!stralloc_copys(out,"")) return 0;
+  for (j = i = 0;j < len;++j)
+    if (!in[j]) {
+      if (in[i] == '+') {
+	if (!stralloc_append(out,"+")) return 0;
+	if (!appendaddr(out,in + i + 1,j - i - 1,rules)) return 0;
+	if (!stralloc_0(out)) return 0;
+      }
+      else
+	if (!stralloc_catb(out,in + i,j - i + 1)) return 0;
+      i = j + 1;
+    }
+  return 1;
+}
diff -Naur qmail-ldap-20040401/rewritehost.h qmail-ldap-20040401-rewrite/rewritehost.h
--- qmail-ldap-20040401/rewritehost.h	1969-12-31 19:00:00.000000000 -0500
+++ qmail-ldap-20040401-rewrite/rewritehost.h	2004-06-25 11:42:21.000000000 -0400
@@ -0,0 +1,8 @@
+#ifndef REWRITEHOST_H
+#define REWRITEHOST_H
+
+extern int rewritehost();
+extern int rewritehost_addr();
+extern int rewritehost_list();
+
+#endif
diff -Naur qmail-ldap-20040401/rwhconfig.c qmail-ldap-20040401-rewrite/rwhconfig.c
--- qmail-ldap-20040401/rwhconfig.c	1969-12-31 19:00:00.000000000 -0500
+++ qmail-ldap-20040401-rewrite/rwhconfig.c	2004-06-25 11:42:30.000000000 -0400
@@ -0,0 +1,77 @@
+#include "rewritehost.h"
+#include "stralloc.h"
+#include "config.h"
+#include "strerr.h"
+#include "rwhconfig.h"
+#include "auto_qmail.h"
+
+struct strerr rwhconfig_err;
+
+static stralloc tmp = {0};
+static config_str me = CONFIG_STR;
+static config_str defaultdomain = CONFIG_STR;
+static config_str defaulthost = CONFIG_STR;
+static config_str plusdomain = CONFIG_STR;
+static config_str idhost = CONFIG_STR;
+
+int rwhconfig(rewrite,idappend)
+config_str *rewrite;
+stralloc *idappend;
+{
+  if (config_readline(&me,"control/me") == -1)
+    STRERR_SYS3(-1,rwhconfig_err,"unable to read ",auto_qmail,"/control/me: ")
+
+  if (!config(rewrite))
+    if (config_readfile(rewrite,"control/rewrite") == -1)
+      STRERR_SYS3(-1,rwhconfig_err,"unable to read ",auto_qmail,"/control/rewrite: ")
+
+  if (!config(rewrite)) {
+    if (config_env(&defaulthost,"QMAILDEFAULTHOST") == -1) goto nomem;
+    if (config_readline(&defaulthost,"control/defaulthost") == -1)
+      STRERR_SYS3(-1,rwhconfig_err,"unable to read ",auto_qmail,"/control/defaulthost: ")
+    if (config_copy(&defaulthost,&me) == -1) goto nomem;
+    if (config_default(&defaulthost,"DEFAULTHOST") == -1) goto nomem;
+  
+    if (config_env(&defaultdomain,"QMAILDEFAULTDOMAIN") == -1) goto nomem;
+    if (config_readline(&defaultdomain,"control/defaultdomain") == -1)
+      STRERR_SYS3(-1,rwhconfig_err,"unable to read ",auto_qmail,"/control/defaultdomain: ")
+    if (config_copy(&defaultdomain,&me) == -1) goto nomem;
+    if (config_default(&defaultdomain,"DEFAULTDOMAIN") == -1) goto nomem;
+  
+    if (config_env(&plusdomain,"QMAILPLUSDOMAIN") == -1) goto nomem;
+    if (config_readline(&plusdomain,"control/plusdomain") == -1)
+      STRERR_SYS3(-1,rwhconfig_err,"unable to read ",auto_qmail,"/control/plusdomain: ")
+    if (config_copy(&plusdomain,&me) == -1) goto nomem;
+    if (config_default(&plusdomain,"PLUSDOMAIN") == -1) goto nomem;
+  
+    if (!stralloc_copys(config_data(rewrite),"*.:")) goto nomem;
+    if (!stralloc_0(config_data(rewrite))) goto nomem;
+    if (!stralloc_cats(config_data(rewrite),"=:")) goto nomem;
+    if (!stralloc_cat(config_data(rewrite),config_data(&defaulthost))) goto nomem;
+    if (!stralloc_0(config_data(rewrite))) goto nomem;
+    if (!stralloc_cats(config_data(rewrite),"*+:.")) goto nomem;
+    if (!stralloc_cat(config_data(rewrite),config_data(&plusdomain))) goto nomem;
+    if (!stralloc_0(config_data(rewrite))) goto nomem;
+    if (!stralloc_cats(config_data(rewrite),"?:.")) goto nomem;
+    if (!stralloc_cat(config_data(rewrite),config_data(&defaultdomain))) goto nomem;
+    if (!stralloc_0(config_data(rewrite))) goto nomem;
+  }
+
+  if (config_env(&idhost,"QMAILIDHOST") == -1) goto nomem;
+  if (config_readline(&idhost,"control/idhost") == -1)
+    STRERR_SYS3(-1,rwhconfig_err,"unable to read ",auto_qmail,"/control/idhost: ")
+  if (config_copy(&idhost,&me) == -1) goto nomem;
+  if (config_default(&idhost,"IDHOST") == -1) goto nomem;
+
+  if (!rewritehost(&tmp,config_data(&idhost)->s,config_data(&idhost)->len,config_data(rewrite))) goto nomem;
+
+  if (!stralloc_copys(idappend,".")) goto nomem;
+  if (!stralloc_catint(idappend,(int) getpid())) goto nomem;
+  if (!stralloc_cats(idappend,".qmail@")) goto nomem;
+  if (!stralloc_cat(idappend,&tmp)) goto nomem;
+
+  return 0;
+
+  nomem:
+  STRERR_SYS(-1,rwhconfig_err,0)
+}
diff -Naur qmail-ldap-20040401/rwhconfig.h qmail-ldap-20040401-rewrite/rwhconfig.h
--- qmail-ldap-20040401/rwhconfig.h	1969-12-31 19:00:00.000000000 -0500
+++ qmail-ldap-20040401-rewrite/rwhconfig.h	2004-06-25 11:42:30.000000000 -0400
@@ -0,0 +1,9 @@
+#ifndef RWHCONFIG_H
+#define RWHCONFIG_H
+
+#include "strerr.h"
+
+extern struct strerr rwhconfig_err;
+extern int rwhconfig();
+
+#endif
diff -Naur qmail-ldap-20040401/stralloc.h qmail-ldap-20040401-rewrite/stralloc.h
--- qmail-ldap-20040401/stralloc.h	2004-06-25 11:16:09.000000000 -0400
+++ qmail-ldap-20040401-rewrite/stralloc.h	2004-06-25 13:04:38.000000000 -0400
@@ -18,4 +18,12 @@
 
 #define stralloc_0(sa) stralloc_append(sa,"")
 
+extern int stralloc_catulong0();
+extern int stralloc_catlong0();
+
+#define stralloc_catlong(sa,l) (stralloc_catlong0((sa),(l),0))
+#define stralloc_catuint0(sa,i,n) (stralloc_catulong0((sa),(unsigned long) (i),(n)))
+#define stralloc_catint0(sa,i,n) (stralloc_catlong0((sa),(long) (i),(n)))
+#define stralloc_catint(sa,i) (stralloc_catlong0((sa),(long) (i),0))
+
 #endif
diff -Naur qmail-ldap-20040401/stralloc_num.c qmail-ldap-20040401-rewrite/stralloc_num.c
--- qmail-ldap-20040401/stralloc_num.c	1969-12-31 19:00:00.000000000 -0500
+++ qmail-ldap-20040401-rewrite/stralloc_num.c	2004-06-25 11:59:36.000000000 -0400
@@ -0,0 +1,35 @@
+#include "stralloc.h"
+
+int stralloc_catulong0(sa,u,n)
+stralloc *sa;
+unsigned long u;
+unsigned int n;
+{
+  unsigned int len;
+  unsigned long q;
+  char *s;
+
+  len = 1;
+  q = u;
+  while (q > 9) { ++len; q /= 10; }
+  if (len < n) len = n;
+
+  if (!stralloc_readyplus(sa,len)) return 0;
+  s = sa->s + sa->len;
+  sa->len += len;
+  while (len) { s[--len] = '0' + (u % 10); u /= 10; }
+
+  return 1;
+}
+
+int stralloc_catlong0(sa,l,n)
+stralloc *sa;
+long l;
+unsigned int n;
+{
+  if (l < 0) {
+    if (!stralloc_append(sa,"-")) return 0;
+    l = -l;
+  }
+  return stralloc_catulong0(sa,l,n);
+}

Reply via email to