summaryrefslogtreecommitdiff
path: root/sqmail-4.3.07/src/qmail-mfrules.c
diff options
context:
space:
mode:
Diffstat (limited to 'sqmail-4.3.07/src/qmail-mfrules.c')
-rw-r--r--sqmail-4.3.07/src/qmail-mfrules.c173
1 files changed, 173 insertions, 0 deletions
diff --git a/sqmail-4.3.07/src/qmail-mfrules.c b/sqmail-4.3.07/src/qmail-mfrules.c
new file mode 100644
index 0000000..e8cfc94
--- /dev/null
+++ b/sqmail-4.3.07/src/qmail-mfrules.c
@@ -0,0 +1,173 @@
+#include <sys/stat.h>
+#include <stdio.h> // rename
+#include "logmsg.h"
+#include "stralloc.h"
+#include "buffer.h"
+#include "getln.h"
+#include "exit.h"
+#include <unistd.h>
+#include "open.h"
+#include "auto_qmail.h"
+#include "cdbmake.h"
+#include "fmt.h"
+#include "scan.h"
+#include "byte.h"
+#include "case.h"
+
+#define WHO "qmail-mfrules"
+
+int rename(const char *,const char *); // stdio.h
+
+stralloc address = {0};
+stralloc data = {0};
+stralloc key = {0};
+stralloc line = {0};
+
+char inbuf[1024];
+buffer bi;
+
+int fd;
+int fdtemp;
+int match = 1;
+
+struct cdb_make cdb;
+
+void die_nomem()
+{
+ logmsg(WHO,112,FATAL,"out of memory");
+}
+void die_parse()
+{
+ if (!stralloc_0(&line)) die_nomem();
+ logmsg(WHO,100,ERROR,B("unable to parse this line: ",line.s));
+}
+void die_read()
+{
+ logmsg(WHO,111,ERROR,"unable to read control/mailfromrules");
+}
+void die_write()
+{
+ logmsg(WHO,111,ERROR,"unable to write to control/mailfromrules.tmp");
+}
+
+char strnum[FMT_ULONG];
+stralloc sanum = {0};
+
+void getnum(char *buf,int len,unsigned long *u)
+{
+ if (!stralloc_copyb(&sanum,buf,len)) die_nomem();
+ if (!stralloc_0(&sanum)) die_nomem();
+ if (sanum.s[scan_ulong(sanum.s,u)]) die_parse();
+}
+
+void doaddressdata()
+{
+ 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)) die_nomem();
+ if (!stralloc_catb(&key,strnum,fmt_ulong(strnum,bot))) die_nomem();
+ if (!stralloc_catb(&key,address.s + right,address.len - right)) die_nomem();
+ case_lowerb(key.s,key.len);
+ if (cdb_make_add(&cdb,key.s,key.len,data.s,data.len) == -1) die_write();
+ ++bot;
+ }
+
+ return;
+ }
+ }
+
+ case_lowerb(address.s,address.len);
+ case_lowerb(data.s,data.len);
+ if (cdb_make_add(&cdb,address.s,address.len,data.s,data.len) == -1) die_write();
+}
+
+int main()
+{
+ int amper;
+ int i;
+ int len;
+ char *x;
+ char ch;
+
+ umask(033);
+ if (chdir(auto_qmail) == -1)
+ logmsg(WHO,111,ERROR,B("unable to chdir to: ",auto_qmail));
+
+ fd = open_read("control/mailfromrules");
+ if (fd == -1) die_read();
+
+ buffer_init(&bi,read,fd,inbuf,sizeof(inbuf));
+
+ fdtemp = open_trunc("control/mailfromrules.tmp");
+ if (fdtemp == -1) die_write();
+
+ if (cdb_make_start(&cdb,fdtemp) == -1) die_write();
+
+ while (match) {
+ if (getln(&bi,&line,&match,'\n') != 0) die_read();
+
+ 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_parse() */
+
+ amper = byte_chr(x,len,'&');
+ if (!amper) die_parse();
+ if (amper) if (amper == len || amper < 2) die_parse();
+
+ if (!stralloc_copyb(&address,x,amper)) die_nomem();
+ if (!stralloc_copys(&data,"")) die_nomem();
+
+ x = line.s + amper + 1; len = line.len - amper - 1;
+
+ while (len) {
+ if (len < 3) die_parse(); /* input checks */
+ if ( *x == ',' || *x == ' ' || *x == '\t') die_parse();
+ i = byte_chr(x,len,','); /* &addr1,addr2,.. */
+ if (i > 0 && i < len) {
+ if (!stralloc_catb(&data,"+",1)) die_nomem();
+ if (!stralloc_catb(&data,x,i)) die_nomem();
+ x += i + 1; len -= i + 1; }
+ else {
+ if (!stralloc_catb(&data,"+",1)) die_nomem();
+ if (!stralloc_catb(&data,x,len)) die_nomem();
+ len = 0; }
+ }
+ doaddressdata();
+ }
+
+ if (cdb_make_finish(&cdb) == -1) die_write();
+ if (fsync(fdtemp) == -1) die_write();
+ if (close(fdtemp) == -1) die_write(); /* NFS stupidity */
+ if (rename("control/mailfromrules.tmp","control/mailfromrules.cdb") == -1)
+ logmsg(WHO,111,ERROR,"unable to move control/mailfromrules.tmp to control/mailfromrules.cdb");
+
+ _exit(0);
+}