--- 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(¬ipme,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(¬ipme, "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,¬ipme)) 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,¬ipme)) { 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,¬ipme)) { 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],¬ipme)) 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(¬ip->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