netqmail-qregex-20040601-vrt.patch

qregex is maintained by:
Andrew St. Jean
andrew@arda.homeunix.net
www.arda.homeunix.net/store/qmail/

Original qregex patch written by:
Evan Borgstrom
evan at unixpimps dot org

validrcptto is:
maintained at www3.sympatico.ca/humungusfungus/code/
written based on badrcptto patches by Ward Vandewege and Andrew McCarthy

DESCRIPTION:
netqmail-qregex-vrt.patch is a combination of qregex (20040601) and validrcptto.
The two patches conflict on patching, because they change some identical parts
of qmail cord. In addition, I modified validrcptto so that control/validrcptto
file can handle REGEX pattern to match envelope RCPTs, taking advantage of
qregex machine.

HOW TO USE THIS PATCH:
* Do "./collate.sh" netqmail as usual.
* cd to netqmail-souce-dir/netqmail-1.05 and issue:
 patch -p1 < where/netqmail-qregex-vrt/patch/is

qregex-20040601.patch

Changelog
2004 06 01
Updated README.qregex.

2004 03 17
Added the badhelo control file. This allows qregex to do pattern matching
againt the HELO host name presented by the smtp client.

Plugged a memory leak. The two stralloc structures in the bmcheck function in
qmail-smtpd have been made static. This prevents the structures from
allocating new memory every time the bmcheck function is called.

2004 02 07
Qregex now ignores empty envelope senders ('mail from' command). Empty envelope
senders will not be compared to any regular expressions in the badmailfrom
control file and will always be accepted by qregex. Prior to this version it
was possible to write regular expressions that would reject mail with empty
envelope senders.

diff -urN netqmail-1.05.org/Makefile netqmail-1.05/Makefile
--- netqmail-1.05.org/Makefile	Thu Sep  9 01:13:24 2004
+++ netqmail-1.05/Makefile	Thu Sep  9 01:14:50 2004
@@ -1532,16 +1532,16 @@
 	./compile qmail-showctl.c
 
 qmail-smtpd: \
-load qmail-smtpd.o rcpthosts.o commands.o timeoutread.o \
+load qmail-smtpd.o rcpthosts.o qregex.o commands.o timeoutread.o \
 timeoutwrite.o ip.o ipme.o ipalloc.o control.o constmap.o received.o \
 date822fmt.o now.o qmail.o cdb.a 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 \
+open.a sig.a case.a env.a stralloc.a alloc.a strerr.a substdio.a error.a str.a \
 fs.a auto_qmail.o socket.lib
-	./load qmail-smtpd rcpthosts.o commands.o timeoutread.o \
+	./load qmail-smtpd qregex.o rcpthosts.o commands.o timeoutread.o \
 	timeoutwrite.o ip.o ipme.o ipalloc.o control.o constmap.o \
 	received.o date822fmt.o now.o qmail.o cdb.a 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  `cat \
+	alloc.a strerr.a substdio.a error.a str.a fs.a auto_qmail.o  `cat \
 	socket.lib`
 
 qmail-smtpd.0: \
@@ -1681,6 +1681,10 @@
 constmap.h stralloc.h gen_alloc.h rcpthosts.h
 	./compile rcpthosts.c
 
+qregex.o: \
+compile qregex.c qregex.h
+	./compile qregex.c
+
 readsubdir.o: \
 compile readsubdir.c readsubdir.h direntry.h fmt.h scan.h str.h \
 auto_split.h
diff -urN netqmail-1.05.org/README.qregex netqmail-1.05/README.qregex
--- netqmail-1.05.org/README.qregex	Thu Jan  1 09:00:00 1970
+++ netqmail-1.05/README.qregex	Thu Sep  9 01:14:50 2004
@@ -0,0 +1,173 @@
+QREGEX (v2) 20040601 - README June 1, 2004
+A Regular Expression matching patch for qmail 1.03 and netqmail
+
+
+OVERVIEW:
+
+qregex adds the ability to match address evelopes via Regular Expressions (REs)
+in the qmail-smtpd process. It has the abiltiy to match `helo/ehlo` (host name),
+`mail from` (envelope sender), and `rcpt to` (envelope recipient) commands.
+It follows all the base rules that are set out with qmail (ie using control
+files) so it makes for easy integretion into an existing setup (see the
+install instructions for more info). The v2 is specified because qregex was
+re-written to better conform to the security guarantee set forth by the author
+of qmail. The original version used stdio.h and stdlib.h for reading the
+control files whereas v2 now uses all stralloc functions which are much more
+regulated against buffer overruns and the like.
+See: http://cr.yp.to/qmail/guarantee.html
+
+NEW FEATURES:
+
+Features added to qregex since its creation are:
+
+1. Performs pattern matching on the helo/ehlo host name. Setting the
+   NOBADHELO environment variable prevents the host name from being
+   compared to the patterns in the badhelo control file.
+
+2. Matches to patterns in the badhelo, badmailfrom, and badmailto control
+   files are logged.
+
+3. Matching is case insensitive.
+
+4. qregex ignores empty envelope senders. An empty envelope sender is not
+   compared to the patterns in the badmailfrom control file and is always
+   accepted.
+
+
+
+PLATFORMS:
+
+qregex has been built and tested on the following platforms. I'm sure it won't
+have any problems on any platform that qmail will run on (providing they have
+a regex interface) but if you run into problems let me know.
+
+	- OpenBSD 3.x
+	- FreeBSD 4.x
+	- Mandrake Linux 9.x
+	- SuSE Linux 8.x
+
+
+
+INSTALLATION INSTRUCTIONS:
+
+Installation is very simple, there is only one requirement. You need to use the
+GNU version of the patch utility (http://www.gnu.org/software/patch/patch.html).
+(For Solaris 8 users it is installed as 'gpatch')
+
+- If this is a new setup.
+Unpack the qmail archive, cd into the qmail-1.03 directory and run
+"patch < /path/to/qregex-<version>.patch". Follow the instructions as per the
+included qmail INSTALL file. Once you are done come back to this file and read
+the section on the control files.
+
+If you are using netqmail, then unpack the netqmail archive. Run the collate.sh
+script and cd into the resulting netqmail-<version> directory. From there, run
+"patch < /path/to/qregex-<version>.patch". Complete the netqmail installation
+normally. Once you are done, come back to this file and read the section on the
+control files.
+
+- If this is an existing setup.
+FIRST: create your control files (see below).
+cd into your existing qmail or netqmail source directory. Run
+"patch < /path/to/qregex-<version>.patch" then "make qmail-smtpd". Now run
+./qmail-smtpd and test your new rules to make sure they work as expected.
+
+Install the new binary by cd'ing to /var/qmail/bin and as root (in one command)
+copy the existing binary to 'qmail-smtpd.old' and copy the new binary from the
+source directory to 'qmail-smtpd'.
+(ex. cp qmail-smtpd qmail-smtpd.old && cp ~/qmail-1.03/qmail-smtpd qmail-smtpd)
+
+You can also optionally just run "make setup check" as it will install the
+updated documentation and man pages provided with this patch. Stopping qmail
+before doing the "make setup check" is always a good idea.
+
+
+LOGGING:
+
+qregex will log matches to the patterns in the badhelo, badmailfrom, and
+badmailto control files. Log messages will take these three forms depending
+on which control file was matched:
+
+qmail-smtpd: badhelo: <host> at <remote IP>
+
+qmail-smtpd: badmailfrom: <sender address> at <remote IP>
+
+qmail-smtpd: badmailto: <rcpt address> at <remote IP>
+
+
+CONTROL FILES:
+
+qregex provides you with three new control files.
+The first (which really isn't new) is "control/badmailfrom". This file
+originally matched addresses statically and now contains your REs for matching
+from the 'mail from' command.
+The other two are "control/badmailto" and "control/badhelo". They are exactly
+the same as the first except that they match against the 'rcpt to' and 
+'helo/ehlo' commands respectively.
+
+If you prefer you can symlink the badmailfrom and badmailto control files
+(ln -s badmailfrom badmailto) and only maintain two sets of rules. Beware
+this might cause problems in certain setups.
+        
+	Here's an example "badhelo" file.
+	-----------------------------------
+	# block host strings with no dot (not a FQDN)
+	!\.
+	-----------------------------------
+	
+	An example "badmailfrom" file.
+	-----------------------------------
+	# this will drop everything containing the string
+	# bad.domain.com or Bad.Domain.Com or BAD.domain.COM
+	bad\.domain\.com
+	# force users to fully qualify themselves
+	# (i.e. deny "user", accept "user@domain")
+	!@
+	-----------------------------------
+
+	And "badmailto" (a litte more interesting)
+	-----------------------------------
+	# must not contain invalid characters, brakets or multiple @'s
+	[!%#:*^(){}]
+	@.*@
+	-----------------------------------
+
+Also you can use the non-RE character '!' to start an RE as a signal to qregex
+to negate the action. As used above in the badmailfrom file, by negating the '@'
+symbol qregex will signal qmail-smtpd to deny the 'mail from' command whenever
+the address doesn't contain an @ symbol. When used inside a bracket expression,
+the '!' character looses this special meaning. This is shown in the badmailto
+example.
+
+
+INTERNALS:
+
+qregex (or regexmatch as the function is called) will be called during the
+`helo/ehlo`, `rcpt to` and `mail from` handling routines in "qmail-smtpd.c".
+When called, it will read the proper control file then one by one compile and
+execute the regex on the string passed into qmail-smtpd. If the regex matches
+it returns TRUE (1) and the qmail-smtpd process will deny the user the ability
+to continue. If you change anything and think it betters this patch please
+send me a new diff file so I can take a peek.
+
+
+CONTACT:
+qregex is maintained by:
+	Andrew St. Jean
+	andrew@arda.homeunix.net
+	www.arda.homeunix.net/store/qmail/
+
+Documentation (manpage updates) and qmail-showctl patch added by:
+	Jeremy Kitchen	
+	kitchen at scriptkitchen dot com
+	http://www.scriptkitchen.com/qmail
+
+badhelo additions supplied by:
+	Alex Pleiner
+	alex@zeitform.de
+	zeitform Internet Dienste
+	http://www.zeitform.de/
+
+Original qregex patch written by:
+	Evan Borgstrom
+	evan at unixpimps dot org
diff -urN netqmail-1.05.org/TARGETS netqmail-1.05/TARGETS
--- netqmail-1.05.org/TARGETS	Mon Jun 15 19:53:16 1998
+++ netqmail-1.05/TARGETS	Thu Sep  9 01:14:50 2004
@@ -252,6 +252,7 @@
 qmail-qmtpd
 qmail-smtpd.o
 qmail-smtpd
+qregex.o
 sendmail.o
 sendmail
 tcp-env.o
diff -urN netqmail-1.05.org/hier.c netqmail-1.05/hier.c
--- netqmail-1.05.org/hier.c	Mon Jun 15 19:53:16 1998
+++ netqmail-1.05/hier.c	Thu Sep  9 01:14:50 2004
@@ -76,6 +76,7 @@
   c(auto_qmail,"boot","binm3+df",auto_uido,auto_gidq,0755);
 
   c(auto_qmail,"doc","FAQ",auto_uido,auto_gidq,0644);
+  c(auto_qmail,"doc","README.qregex",auto_uido,auto_gidq,0644);
   c(auto_qmail,"doc","UPGRADE",auto_uido,auto_gidq,0644);
   c(auto_qmail,"doc","SENDMAIL",auto_uido,auto_gidq,0644);
   c(auto_qmail,"doc","INSTALL",auto_uido,auto_gidq,0644);
diff -urN netqmail-1.05.org/install-big.c netqmail-1.05/install-big.c
--- netqmail-1.05.org/install-big.c	Mon Jun 15 19:53:16 1998
+++ netqmail-1.05/install-big.c	Thu Sep  9 01:14:50 2004
@@ -76,6 +76,7 @@
   c(auto_qmail,"boot","binm3+df",auto_uido,auto_gidq,0755);
 
   c(auto_qmail,"doc","FAQ",auto_uido,auto_gidq,0644);
+  c(auto_qmail,"doc","README.qregex",auto_uido,auto_gidq,0644);
   c(auto_qmail,"doc","UPGRADE",auto_uido,auto_gidq,0644);
   c(auto_qmail,"doc","SENDMAIL",auto_uido,auto_gidq,0644);
   c(auto_qmail,"doc","INSTALL",auto_uido,auto_gidq,0644);
diff -urN netqmail-1.05.org/qmail-control.9 netqmail-1.05/qmail-control.9
--- netqmail-1.05.org/qmail-control.9	Mon Jun 15 19:53:16 1998
+++ netqmail-1.05/qmail-control.9	Thu Sep  9 01:14:50 2004
@@ -20,7 +20,9 @@
 
 Comments are allowed
 in
+.IR badhelo ,
 .IR badmailfrom ,
+.IR badmailto ,
 .IR locals ,
 .IR percenthack ,
 .IR qmqpservers ,
@@ -40,7 +42,9 @@
 .ta 5c 10c
 control	default	used by
 
+.I badhelo	\fR(none)	\fRqmail-smtpd
 .I badmailfrom	\fR(none)	\fRqmail-smtpd
+.I badmailto	\fR(none)	\fRqmail-smtpd
 .I bouncefrom	\fRMAILER-DAEMON	\fRqmail-send
 .I bouncehost	\fIme	\fRqmail-send
 .I concurrencylocal	\fR10	\fRqmail-send
diff -urN netqmail-1.05.org/qmail-showctl.c netqmail-1.05/qmail-showctl.c
--- netqmail-1.05.org/qmail-showctl.c	Mon Jun 15 19:53:16 1998
+++ netqmail-1.05/qmail-showctl.c	Thu Sep  9 01:14:50 2004
@@ -214,7 +214,9 @@
     _exit(111);
   }
 
-  do_lst("badmailfrom","Any MAIL FROM is allowed.",""," not accepted in MAIL FROM.");
+  do_lst("badhelo","Any HELO host name is allowed.",""," HELO host name denied if it matches this pattern.");
+  do_lst("badmailfrom","Any MAIL FROM is allowed.",""," MAIL FROM denied if it matches this pattern.");
+  do_lst("badmailto","No RCPT TO are specifically denied.",""," RCPT TO denied if it matches this pattern.");
   do_str("bouncefrom",0,"MAILER-DAEMON","Bounce user name is ");
   do_str("bouncehost",1,"bouncehost","Bounce host name is ");
   do_int("concurrencylocal","10","Local concurrency is ","");
@@ -267,7 +269,9 @@
     if (str_equal(d->d_name,"..")) continue;
     if (str_equal(d->d_name,"bouncefrom")) continue;
     if (str_equal(d->d_name,"bouncehost")) continue;
+    if (str_equal(d->d_name,"badhelo")) continue;
     if (str_equal(d->d_name,"badmailfrom")) continue;
+    if (str_equal(d->d_name,"badmailto")) continue;
     if (str_equal(d->d_name,"bouncefrom")) continue;
     if (str_equal(d->d_name,"bouncehost")) continue;
     if (str_equal(d->d_name,"concurrencylocal")) continue;
diff -urN netqmail-1.05.org/qmail-smtpd.8 netqmail-1.05/qmail-smtpd.8
--- netqmail-1.05.org/qmail-smtpd.8	Mon Jun 15 19:53:16 1998
+++ netqmail-1.05/qmail-smtpd.8	Thu Sep  9 01:14:50 2004
@@ -37,11 +37,25 @@
 even though such messages violate the SMTP protocol.
 .SH "CONTROL FILES"
 .TP 5
+.I badhelo
+Unacceptable HELO/EHLO host names.
+.B qmail-smtpd
+will reject every recipient address for a message if
+the host name is listed in, 
+or matches a POSIX regular expression pattern listed in,
+.IR badhelo .
+If the NOBADHELO environment variable is set, then the 
+contents of 
+.IR badhelo 
+will be ignored.
+For more information, please have a look at doc/README.qregex.
+.TP 5
 .I badmailfrom
 Unacceptable envelope sender addresses.
 .B qmail-smtpd
 will reject every recipient address for a message
-if the envelope sender address is listed in
+if the envelope sender address is listed in, or matches a POSIX regular expression
+pattern listed in,
 .IR badmailfrom .
 A line in
 .I badmailfrom
@@ -49,6 +63,16 @@
 .BR @\fIhost ,
 meaning every address at
 .IR host .
+For more information, please have a look at doc/README.qregex.
+.TP 5
+.I badmailto
+Unacceptable recipient addresses.
+.B qmail-smtpd
+will reject every recipient address for a message if the recipient address
+is listed in,
+or matches a POSIX regular expression pattern listed in,
+.IR badmailto .
+For more information, please have a look at doc/README.qregex.
 .TP 5
 .I databytes
 Maximum number of bytes allowed in a message,
diff -urN netqmail-1.05.org/qmail-smtpd.c netqmail-1.05/qmail-smtpd.c
--- netqmail-1.05.org/qmail-smtpd.c	Thu Sep  9 01:13:24 2004
+++ netqmail-1.05/qmail-smtpd.c	Thu Sep  9 01:40:22 2004
@@ -23,6 +23,13 @@
 #include "timeoutread.h"
 #include "timeoutwrite.h"
 #include "commands.h"
+#include "qregex.h"
+#include "strerr.h"
+
+#define BMCHECK_BMF 0
+#define BMCHECK_BMT 1
+#define BMCHECK_BHELO 2
+#define BMCHECK_VRT 3
 
 #define MAXHOPS 100
 unsigned int databytes = 0;
@@ -49,7 +56,10 @@
 void die_ipme() { out("421 unable to figure out my IP addresses (#4.3.0)\r\n"); flush(); _exit(1); }
 void straynewline() { out("451 See http://pobox.com/~djb/docs/smtplf.html.\r\n"); flush(); _exit(1); }
 
-void err_bmf() { out("553 sorry, your envelope sender is in my badmailfrom list (#5.7.1)\r\n"); }
+void err_bmf() { out("553 sorry, your envelope sender has been denied (#5.7.1)\r\n"); }
+void err_bmt() { out("553 sorry, your envelope recipient has been denied (#5.7.1)\r\n"); }
+void err_bhelo() { out("553 sorry, your HELO host name has been denied (#5.7.1)\r\n"); }
+void err_vrt() { out("553 sorry, your envelope recipient has been denied (#5.7.1)\r\n"); }
 void err_nogateway() { out("553 sorry, that domain isn't in my list of allowed rcpthosts (#5.7.1)\r\n"); }
 void err_unimpl(arg) char *arg; { out("502 unimplemented (#5.5.1)\r\n"); }
 void err_syntax() { out("555 syntax error (#5.5.4)\r\n"); }
@@ -93,9 +103,18 @@
 
 int liphostok = 0;
 stralloc liphost = {0};
+
 int bmfok = 0;
 stralloc bmf = {0};
-struct constmap mapbmf;
+
+int bmtok = 0;
+stralloc bmt = {0};
+
+int bhelook = 0;
+stralloc bhelo = {0};
+
+int vrtok = 0;
+stralloc vrt = {0};
 
 void setup()
 {
@@ -114,8 +133,16 @@
 
   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();
+
+  bmtok = control_readfile(&bmt,"control/badmailto",0);
+  if (bmtok == -1) die_control();
+
+  vrtok = control_readfile(&vrt,"control/validrcptto",0);
+  if (vrtok == -1) die_control();
+
+  bhelook = control_readfile(&bhelo, "control/badhelo",0);
+  if (bhelook == -1) die_control();
+  if (env_get("NOBADHELO")) bhelook = 0;
  
   if (control_readint(&databytes,"control/databytes") == -1) die_control();
   x = env_get("DATABYTES");
@@ -197,14 +224,46 @@
   return 1;
 }
 
-int bmfcheck()
+int bmcheck(which) int which;
 {
-  int j;
-  if (!bmfok) return 0;
-  if (constmap(&mapbmf,addr.s,addr.len - 1)) return 1;
-  j = byte_rchr(addr.s,addr.len,'@');
-  if (j < addr.len)
-    if (constmap(&mapbmf,addr.s + j,addr.len - j - 1)) return 1;
+  int i = 0;
+  int j = 0;
+  int x = 0;
+  int negate = 0;
+  static stralloc bmb = {0};
+  static stralloc curregex = {0};
+
+  if (which == BMCHECK_BMF) {
+    if (!stralloc_copy(&bmb,&bmf)) die_nomem();
+  } else if (which == BMCHECK_BMT) {
+    if (!stralloc_copy(&bmb,&bmt)) die_nomem();
+  } else if (which == BMCHECK_BHELO) {
+    if (!stralloc_copy(&bmb,&bhelo)) die_nomem();
+  } else if (which == BMCHECK_VRT) {
+    if (!stralloc_copy(&bmb,&vrt)) die_nomem();
+  } else {
+    die_control();
+  }
+
+  while (j < bmb.len) {
+    i = j;
+    while ((bmb.s[i] != '\0') && (i < bmb.len)) i++;
+    if (bmb.s[j] == '!') {
+      negate = 1;
+      j++;
+    }
+    if (!stralloc_copyb(&curregex,bmb.s + j,(i - j))) die_nomem();
+    if (!stralloc_0(&curregex)) die_nomem();
+    if (which == BMCHECK_BHELO) {
+      x = matchregex(helohost.s, curregex.s);
+    } else {
+      x = matchregex(addr.s, curregex.s);
+    }
+    if ((negate) && (x == 0)) return 1;
+    if (!(negate) && (x > 0)) return 1;
+    j = i + 1;
+    negate = 0;
+  }
   return 0;
 }
 
@@ -218,7 +277,10 @@
 
 
 int seenmail = 0;
-int flagbarf; /* defined if seenmail */
+int flagbarfbmf; /* defined if seenmail */
+int flagbarfbmt;
+int flagbarfbhelo;
+int flagbarfvrt;
 stralloc mailfrom = {0};
 stralloc rcptto = {0};
 
@@ -226,11 +288,13 @@
 {
   smtp_greet("250 "); out("\r\n");
   seenmail = 0; dohelo(arg);
+  if (bhelook) flagbarfbhelo = bmcheck(BMCHECK_BHELO);
 }
 void smtp_ehlo(arg) char *arg;
 {
   smtp_greet("250-"); out("\r\n250-PIPELINING\r\n250 8BITMIME\r\n");
   seenmail = 0; dohelo(arg);
+  if (bhelook) flagbarfbhelo = bmcheck(BMCHECK_BHELO);
 }
 void smtp_rset(arg) char *arg;
 {
@@ -240,7 +304,8 @@
 void smtp_mail(arg) char *arg;
 {
   if (!addrparse(arg)) { err_syntax(); return; }
-  flagbarf = bmfcheck();
+  flagbarfbmf = 0; /* bmcheck is skipped for empty envelope senders */
+  if ((addr.len != 1) && (bmfok)) flagbarfbmf = bmcheck(BMCHECK_BMF);
   seenmail = 1;
   if (!stralloc_copys(&rcptto,"")) die_nomem();
   if (!stralloc_copys(&mailfrom,addr.s)) die_nomem();
@@ -250,7 +315,30 @@
 void smtp_rcpt(arg) char *arg; {
   if (!seenmail) { err_wantmail(); return; }
   if (!addrparse(arg)) { err_syntax(); return; }
-  if (flagbarf) { err_bmf(); return; }
+  if (flagbarfbhelo) {
+    strerr_warn4("qmail-smtpd: badhelo: ",helohost.s," at ",remoteip,0);
+    err_bhelo();
+    return;
+  }
+  if (flagbarfbmf) {
+    strerr_warn4("qmail-smtpd: badmailfrom: ",mailfrom.s," at ",remoteip,0);
+    err_bmf();
+    return;
+  }
+  if (bmtok) { flagbarfbmt = bmcheck(BMCHECK_BMT); }
+  if (flagbarfbmt) {
+    strerr_warn4("qmail-smtpd: badmailto: ",addr.s," at ",remoteip,0);
+    err_bmt();
+    return;
+  }
+  if (vrtok) { flagbarfvrt = bmcheck(BMCHECK_VRT); }
+  if (!flagbarfvrt) {
+    if (!relayclient) {
+      strerr_warn4("qmail-smtpd: validrcptto: ",addr.s," at ",remoteip,0);
+      err_vrt();
+      return;
+    }
+  }
   if (relayclient) {
     --addr.len;
     if (!stralloc_cats(&addr,relayclient)) die_nomem();
diff -urN netqmail-1.05.org/qregex.c netqmail-1.05/qregex.c
--- netqmail-1.05.org/qregex.c	Thu Jan  1 09:00:00 1970
+++ netqmail-1.05/qregex.c	Thu Sep  9 01:14:50 2004
@@ -0,0 +1,57 @@
+/*
+ * qregex (v2)
+ * $Id: qregex.c,v 2.1 2001/12/28 07:05:21 evan Exp $
+ *
+ * Author  : Evan Borgstrom (evan at unixpimps dot org)
+ * Created : 2001/12/14 23:08:16
+ * Modified: $Date: 2001/12/28 07:05:21 $
+ * Revision: $Revision: 2.1 $
+ *
+ * Do POSIX regex matching on addresses for anti-relay / spam control.
+ * It logs to the maillog
+ * See the qregex-readme file included with this tarball.
+ * If you didn't get this file in a tarball please see the following URL:
+ *  http://www.unixpimps.org/software/qregex
+ *
+ * qregex.c is released under a BSD style copyright.
+ * See http://www.unixpimps.org/software/qregex/copyright.html
+ *
+ * Note: this revision follows the coding guidelines set forth by the rest of
+ *       the qmail code and that described at the following URL.
+ *       http://cr.yp.to/qmail/guarantee.html
+ * 
+ */
+
+#include <sys/types.h>
+#include <regex.h>
+#include "qregex.h"
+
+#define REGCOMP(X,Y)    regcomp(&X, Y, REG_EXTENDED|REG_ICASE)
+#define REGEXEC(X,Y)    regexec(&X, Y, (size_t)0, (regmatch_t *)0, (int)0)
+
+int matchregex(char *text, char *regex) {
+  regex_t qreg;
+  int retval = 0;
+
+
+  /* build the regex */
+  if ((retval = REGCOMP(qreg, regex)) != 0) {
+    regfree(&qreg);
+    return(-retval);
+  }
+
+  /* execute the regex */
+  if ((retval = REGEXEC(qreg, text)) != 0) {
+    /* did we just not match anything? */
+    if (retval == REG_NOMATCH) {
+      regfree(&qreg);
+      return(0);
+    }
+    regfree(&qreg);
+    return(-retval);
+  }
+
+  /* signal the match */
+  regfree(&qreg);
+  return(1);
+}
diff -urN netqmail-1.05.org/qregex.h netqmail-1.05/qregex.h
--- netqmail-1.05.org/qregex.h	Thu Jan  1 09:00:00 1970
+++ netqmail-1.05/qregex.h	Thu Sep  9 01:14:50 2004
@@ -0,0 +1,5 @@
+/* simple header file for the matchregex prototype */
+#ifndef _QREGEX_H_
+#define _QREGEX_H_
+int matchregex(char *text, char *regex);
+#endif
