summaryrefslogtreecommitdiff
path: root/ucspi-tcp-0.88/tcprules.c
diff options
context:
space:
mode:
Diffstat (limited to 'ucspi-tcp-0.88/tcprules.c')
-rw-r--r--ucspi-tcp-0.88/tcprules.c175
1 files changed, 175 insertions, 0 deletions
diff --git a/ucspi-tcp-0.88/tcprules.c b/ucspi-tcp-0.88/tcprules.c
new file mode 100644
index 0000000..a684ac5
--- /dev/null
+++ b/ucspi-tcp-0.88/tcprules.c
@@ -0,0 +1,175 @@
+#include "strerr.h"
+#include "stralloc.h"
+#include "getln.h"
+#include "buffer.h"
+#include "exit.h"
+#include "fmt.h"
+#include "byte.h"
+#include "cdb_make.h"
+
+#define FATAL "tcprules: fatal: "
+
+unsigned long linenum = 0;
+char *fntemp;
+char *fn;
+
+stralloc line = {0};
+int match = 1;
+
+stralloc address = {0};
+stralloc data = {0};
+stralloc key = {0};
+
+struct cdb_make c;
+
+void nomem(void)
+{
+ strerr_die2x(111,FATAL,"out of memory");
+}
+void usage(void)
+{
+ strerr_die1x(100,"tcprules: usage: tcprules rules.cdb rules.tmp");
+}
+void die_bad(void)
+{
+ if (!stralloc_0(&line)) nomem();
+ strerr_die3x(100,FATAL,"unable to parse this line: ",line.s);
+}
+void die_write(void)
+{
+ strerr_die4sys(111,FATAL,"unable to write to ",fntemp,": ");
+}
+
+char strnum[FMT_ULONG];
+stralloc sanum = {0};
+
+void getnum(char *buf,int len,unsigned long *u)
+{
+ if (!stralloc_copyb(&sanum,buf,len)) nomem();
+ if (!stralloc_0(&sanum)) nomem();
+ if (sanum.s[scan_ulong(sanum.s,u)]) die_bad();
+}
+
+void doaddressdata(void)
+{
+ int i;
+ int left;
+ int right;
+ unsigned long bot;
+ unsigned long top;
+
+ if (byte_chr(address.s,address.len,'=') == address.len)
+ if (byte_chr(address.s,address.len,'@') == address.len) {
+ i = byte_chr(address.s,address.len,'-');
+ if (i < address.len) {
+ left = byte_rchr(address.s,i,'.');
+ if (left == i) left = 0; else ++left;
+
+ ++i;
+ right = i + byte_chr(address.s + i,address.len - i,'.');
+
+ getnum(address.s + left,i - 1 - left,&bot);
+ getnum(address.s + i,right - i,&top);
+ if (top > 255) top = 255;
+
+ while (bot <= top) {
+ if (!stralloc_copyb(&key,address.s,left)) nomem();
+ if (!stralloc_catb(&key,strnum,fmt_ulong(strnum,bot))) nomem();
+ if (!stralloc_catb(&key,address.s + right,address.len - right)) nomem();
+ if (cdb_make_add(&c,key.s,key.len,data.s,data.len) == -1) die_write();
+ ++bot;
+ }
+
+ return;
+ }
+ }
+
+ if (cdb_make_add(&c,address.s,address.len,data.s,data.len) == -1) die_write();
+}
+
+main(int argc,char **argv)
+{
+ int colon;
+ char *x;
+ int len;
+ int fd;
+ int i;
+ char ch;
+
+ fn = argv[1];
+ if (!fn) usage();
+ fntemp = argv[2];
+ if (!fntemp) usage();
+
+ fd = open_trunc(fntemp);
+ if (fd == -1)
+ strerr_die4sys(111,FATAL,"unable to create ",fntemp,": ");
+ if (cdb_make_start(&c,fd) == -1) die_write();
+
+ while (match) {
+ if (getln(buffer_0,&line,&match,'\n') == -1)
+ strerr_die2sys(111,FATAL,"unable to read input: ");
+
+ x = line.s; len = line.len;
+
+ if (!len) break;
+ if (x[0] == '#') continue;
+ if (x[0] == '\n') continue;
+
+ while (len) {
+ ch = x[len - 1];
+ if (ch != '\n') if (ch != ' ') if (ch != '\t') break;
+ --len;
+ }
+ line.len = len; /* for die_bad() */
+
+ colon = byte_chr(x,len,':');
+ if (colon == len) continue;
+
+ if (!stralloc_copyb(&address,x,colon)) nomem();
+ if (!stralloc_copys(&data,"")) nomem();
+
+ x += colon + 1; len -= colon + 1;
+
+ if ((len >= 4) && byte_equal(x,4,"deny")) {
+ if (!stralloc_catb(&data,"D",2)) nomem();
+ x += 4; len -= 4;
+ }
+ else if ((len >= 5) && byte_equal(x,5,"allow")) {
+ x += 5; len -= 5;
+ }
+ else
+ die_bad();
+
+ while (len)
+ switch(*x) {
+ case ',':
+ i = byte_chr(x,len,'=');
+ if (i == len) die_bad();
+ if (!stralloc_catb(&data,"+",1)) nomem();
+ if (!stralloc_catb(&data,x + 1,i)) nomem();
+ x += i + 1; len -= i + 1;
+ if (!len) die_bad();
+ ch = *x;
+ x += 1; len -= 1;
+ i = byte_chr(x,len,ch);
+ if (i == len) die_bad();
+ if (!stralloc_catb(&data,x,i)) nomem();
+ if (!stralloc_0(&data)) nomem();
+ x += i + 1; len -= i + 1;
+ break;
+ default:
+ die_bad();
+ }
+
+ doaddressdata();
+ }
+
+ if (cdb_make_finish(&c) == -1) die_write();
+ if (fsync(fd) == -1) die_write();
+ if (close(fd) == -1) die_write(); /* NFS stupidity */
+ if (rename(fntemp,fn))
+ strerr_die6sys(111,FATAL,"unable to move ",fntemp," to ",fn,": ");
+
+ _exit(0);
+}