summaryrefslogtreecommitdiff
path: root/src/rcpthosts.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/rcpthosts.c')
-rw-r--r--src/rcpthosts.c70
1 files changed, 70 insertions, 0 deletions
diff --git a/src/rcpthosts.c b/src/rcpthosts.c
new file mode 100644
index 0000000..2242249
--- /dev/null
+++ b/src/rcpthosts.c
@@ -0,0 +1,70 @@
+#include "cdbread.h"
+#include "byte.h"
+#include "open.h"
+#include "error.h"
+#include "exit.h"
+#include "control.h"
+#include "constmap.h"
+#include "stralloc.h"
+#include "case.h"
+#include "close.h"
+#include "fd.h"
+#include "rcpthosts.h"
+
+static int flagrh = 0;
+static int flagmrh = 0;
+static stralloc rh = {0};
+static struct constmap maprh;
+static int fdmrh;
+
+static struct cdb cdb;
+
+int rcpthosts_init()
+{
+ flagrh = control_readfile(&rh,"control/rcpthosts",0);
+ if (flagrh != 1) return flagrh;
+ if (!constmap_init(&maprh,rh.s,rh.len,0)) return flagrh = -1;
+ fdmrh = open_read("control/morercpthosts.cdb");
+ if (fdmrh == -1) if (errno != ENOENT) return flagmrh = -1;
+ if (fdmrh > 0) flagmrh = 1;
+ return 0;
+}
+
+static stralloc host = {0};
+
+int rcpthosts(char *buf, int len)
+{
+ int j;
+ int r;
+
+ if (flagrh != 1) return 1;
+
+ j = byte_rchr(buf,len,'@');
+ if (j >= len) return 1; /* presumably envnoathost is acceptable */
+
+ ++j; buf += j; len -= j;
+
+ if (!stralloc_copyb(&host,buf,len)) return -1;
+ buf = host.s;
+ case_lowerb(buf,len);
+
+ for (j = 0; j < len; ++j)
+ if (!j || (buf[j] == '.'))
+ if (constmap(&maprh,buf + j,len - j)) return 1;
+
+ if (flagmrh == 1) {
+ fdmrh = open_read("control/morercpthosts.cdb");
+ if (fdmrh == -1) if (errno == ENOENT) return 0;
+ cdb_init(&cdb,fdmrh);
+
+ for (j = 0; j < len ;++j)
+ if (!j || (buf[j] == '.')) {
+ r = cdb_find(&cdb,buf + j,len - j);
+ if (r) { cdb_free(&cdb); close(fdmrh); return r; }
+ }
+ cdb_free(&cdb);
+ close(fdmrh);
+ }
+
+ return 0;
+}