#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); }