--- ipme.c.orig  1998-06-15
+++ ipme.c       2007-03-21
--- .././qmail-1.03/ipme.c	Mon Jun 15 12:53:16 1998
+++ ../qmail-1.03.2418/ipme.c	Mon Nov 22 21:55:35 2004
@@ -14,6 +14,10 @@
 #include "ipalloc.h"
 #include "stralloc.h"
 #include "ipme.h"
+#include "substdio.h"
+#include "readwrite.h"
+
+#define MOREIPME
 
 static int ipmeok = 0;
 ipalloc ipme = {0};
@@ -31,6 +35,14 @@
 
 static stralloc buf = {0};
 
+#ifdef MOREIPME
+#define ipme_init_retclean(ret) { \
+  if (notipme.ix) alloc_free(notipme.ix); \
+  if (moreipme.ix) alloc_free(moreipme.ix); \
+  if (buf.s) alloc_free(buf.s); \
+  return ret; }
+#endif
+
 int ipme_init()
 {
   struct ifconf ifc;
@@ -40,17 +52,48 @@
   int len;
   int s;
   struct ip_mx ix;
+
+#ifdef MOREIPME
+  ipalloc notipme = {0};
+  ipalloc moreipme = {0};
+  int i;
  
   if (ipmeok) return 1;
+  if (!ipalloc_readyplus(&ipme,0)) ipme_init_retclean(0);
+  if (!ipalloc_readyplus(&notipme,0)) ipme_init_retclean(0);
+  if (!ipalloc_readyplus(&moreipme,0)) ipme_init_retclean(0);
+#else
+  if (ipmeok) return 1;
   if (!ipalloc_readyplus(&ipme,0)) return 0;
+#endif
   ipme.len = 0;
   ix.pref = 0;
- 
+
+#ifdef MOREIPME
+  if (!ipme_readipfile(&notipme, "control/notipme")) ipme_init_retclean(0);
+#endif
+
+  /* 0.0.0.0 is a special address which always refers to
+   * "this host, this network", according to RFC 1122, Sec. 3.2.1.3a.
+  */
+  byte_copy(&ix.ip,4,"\0\0\0\0");
+
+#ifdef MOREIPME
+  if ((s = socket(AF_INET,SOCK_STREAM,0)) == -1) ipme_init_retclean(-1);
+  if (!ipme_append_unless(&ix,&notipme)) ipme_init_retclean(0);
+#else
+  if (!ipalloc_append(&ipme,&ix)) { return 0; }
+
   if ((s = socket(AF_INET,SOCK_STREAM,0)) == -1) return -1;
+#endif
  
   len = 256;
   for (;;) {
-    if (!stralloc_ready(&buf,len)) { close(s); return 0; }
+#ifdef MOREIPME
+    if (!stralloc_ready(&buf,len)) { close(s); ipme_init_retclean(0); }
+#else
+  if (!stralloc_ready(&buf,len)) { close(s); return 0; }
+#endif
     buf.len = 0;
     ifc.ifc_buf = buf.s;
     ifc.ifc_len = len;
@@ -59,7 +102,11 @@
         buf.len = ifc.ifc_len;
         break;
       }
+#ifdef MOREIPME
+    if (len > 200000) { close(s);  ipme_init_retclean(-1); }
+#else
     if (len > 200000) { close(s); return -1; }
+#endif
     len += 100 + (len >> 2);
   }
   x = buf.s;
@@ -74,7 +121,11 @@
       byte_copy(&ix.ip,4,&sin->sin_addr);
       if (ioctl(s,SIOCGIFFLAGS,x) == 0)
         if (ifr->ifr_flags & IFF_UP)
+#ifdef MOREIPME
+          if (!ipme_append_unless(&ix,&notipme)) { close(s);  ipme_init_retclean(0); }
+#else
           if (!ipalloc_append(&ipme,&ix)) { close(s); return 0; }
+#endif
     }
 #else
     len = sizeof(*ifr);
@@ -84,12 +135,64 @@
 	  if (ifr->ifr_addr.sa_family == AF_INET) {
 	    sin = (struct sockaddr_in *) &ifr->ifr_addr;
 	    byte_copy(&ix.ip,4,&sin->sin_addr);
-	    if (!ipalloc_append(&ipme,&ix)) { close(s); return 0; }
+#ifdef MOREIPME
+            if (!ipme_append_unless(&ix,&notipme)) { close(s);  ipme_init_retclean(0); }
+#else
+            if (!ipalloc_append(&ipme,&ix)) { close(s); return 0; }
+#endif
 	  }
 #endif
     x += len;
   }
   close(s);
+
+#ifdef MOREIPME
+  if (!ipme_readipfile(&moreipme, "control/moreipme"))  ipme_init_retclean(0);
+  for(i = 0;i < moreipme.len;++i)
+    if (!ipme_append_unless(&moreipme.ix[i],&notipme))  ipme_init_retclean(0);
+
+  ipmeok = 1;
+  ipme_init_retclean(1);
+}
+
+
+int ipme_readipfile(ipa, fn)
+  ipalloc *ipa;
+  char *fn;
+{
+  int fd = -1;
+  char inbuf[1024];
+  substdio ss;
+  stralloc l = {0};
+  int match;
+  struct ip_mx ix;
+  int ret = 1;
+
+  if ( (fd = open_read(fn)) != -1) {
+    substdio_fdbuf(&ss, read, fd, inbuf, sizeof(inbuf));
+    while ( (getln(&ss,&l,&match,'\n') != -1) && (match || l.len) ) {
+      l.len--;
+      if (!stralloc_0(&l)) { ret = 0; break; }
+      if (!ip_scan(l.s, &ix.ip)) continue;
+      if (!ipalloc_append(ipa,&ix)) { ret = 0; break; }
+    }
+    if (l.s) alloc_free(l.s);
+    if ( (fd >= 0) && (close(fd) == -1) )
+      ret = 0;
+  }
+  return ret;
+}
+
+int ipme_append_unless(ix, notip)
+  struct ip_mx *ix;
+  struct ipalloc *notip;
+{
+  int i;
+  for (i = 0;i < notip->len;++i)
+    if (byte_equal(&notip->ix[i].ip,4,&ix->ip)) return 1;
+  return ipalloc_append(&ipme, ix);
+#else
   ipmeok = 1;
   return 1;
+#endif
 }


syntax highlighted by Code2HTML, v. 0.9.1