s/qmail 4.2.29a
Next generation secure email transport
Loading...
Searching...
No Matches
qmail-mfrules.c
Go to the documentation of this file.
1#include <sys/stat.h>
2#include <stdio.h> // rename
3#include "logmsg.h"
4#include "stralloc.h"
5#include "buffer.h"
6#include "getln.h"
7#include "exit.h"
8#include <unistd.h>
9#include "open.h"
10#include "auto_qmail.h"
11#include "cdbmake.h"
12#include "fmt.h"
13#include "scan.h"
14#include "byte.h"
15#include "case.h"
16
17#define WHO "qmail-mfrules"
18
19int rename(const char *,const char *); // stdio.h
20
21stralloc address = {0};
22stralloc data = {0};
23stralloc key = {0};
24stralloc line = {0};
25
26char inbuf[1024];
27buffer bi;
28
29int fd;
31int match = 1;
32
33struct cdb_make cdb;
34
36{
37 logmsg(WHO,112,FATAL,"out of memory");
38}
40{
41 if (!stralloc_0(&line)) die_nomem();
42 logmsg(WHO,100,ERROR,B("unable to parse this line: ",line.s));
43}
45{
46 logmsg(WHO,111,ERROR,"unable to read control/mailfromrules");
47}
49{
50 logmsg(WHO,111,ERROR,"unable to write to control/mailfromrules.tmp");
51}
52
53char strnum[FMT_ULONG];
54stralloc sanum = {0};
55
56void getnum(char *buf,int len,unsigned long *u)
57{
58 if (!stralloc_copyb(&sanum,buf,len)) die_nomem();
59 if (!stralloc_0(&sanum)) die_nomem();
60 if (sanum.s[scan_ulong(sanum.s,u)]) die_parse();
61}
62
64{
65 int i;
66 int left;
67 int right;
68 unsigned long bot;
69 unsigned long top;
70
71 if (byte_chr(address.s,address.len,'=') == address.len)
72 if (byte_chr(address.s,address.len,'@') == address.len) {
73 i = byte_chr(address.s,address.len,'-');
74 if (i < address.len) {
75 left = byte_rchr(address.s,i,'.');
76 if (left == i) left = 0; else ++left;
77
78 ++i;
79 right = i + byte_chr(address.s + i,address.len - i,'.');
80
81 getnum(address.s + left,i - 1 - left,&bot);
82 getnum(address.s + i,right - i,&top);
83 if (top > 255) top = 255;
84
85 while (bot <= top) {
86 if (!stralloc_copyb(&key,address.s,left)) die_nomem();
87 if (!stralloc_catb(&key,strnum,fmt_ulong(strnum,bot))) die_nomem();
88 if (!stralloc_catb(&key,address.s + right,address.len - right)) die_nomem();
89 case_lowerb(key.s,key.len);
90 if (cdb_make_add(&cdb,key.s,key.len,data.s,data.len) == -1) die_write();
91 ++bot;
92 }
93
94 return;
95 }
96 }
97
98 case_lowerb(address.s,address.len);
99 case_lowerb(data.s,data.len);
100 if (cdb_make_add(&cdb,address.s,address.len,data.s,data.len) == -1) die_write();
101}
102
103int main()
104{
105 int amper;
106 int i;
107 int len;
108 char *x;
109 char ch;
110
111 umask(033);
112 if (chdir(auto_qmail) == -1)
113 logmsg(WHO,111,ERROR,B("unable to chdir to: ",auto_qmail));
114
115 fd = open_read("control/mailfromrules");
116 if (fd == -1) die_read();
117
118 buffer_init(&bi,read,fd,inbuf,sizeof(inbuf));
119
120 fdtemp = open_trunc("control/mailfromrules.tmp");
121 if (fdtemp == -1) die_write();
122
123 if (cdb_make_start(&cdb,fdtemp) == -1) die_write();
124
125 while (match) {
126 if (getln(&bi,&line,&match,'\n') != 0) die_read();
127
128 x = line.s; len = line.len;
129
130 if (!len) break;
131 if (x[0] == '#') continue;
132 if (x[0] == '\n') continue;
133
134 while (len) {
135 ch = x[len - 1];
136 if (ch != '\n') if (ch != ' ') if (ch != '\t') break;
137 --len;
138 }
139 line.len = len; /* for die_parse() */
140
141 amper = byte_chr(x,len,'&');
142 if (!amper) die_parse();
143 if (amper) if (amper == len || amper < 2) die_parse();
144
145 if (!stralloc_copyb(&address,x,amper)) die_nomem();
146 if (!stralloc_copys(&data,"")) die_nomem();
147
148 x = line.s + amper + 1; len = line.len - amper - 1;
149
150 while (len) {
151 if (len < 3) die_parse(); /* input checks */
152 if ( *x == ',' || *x == ' ' || *x == '\t') die_parse();
153 i = byte_chr(x,len,','); /* &addr1,addr2,.. */
154 if (i > 0 && i < len) {
155 if (!stralloc_catb(&data,"+",1)) die_nomem();
156 if (!stralloc_catb(&data,x,i)) die_nomem();
157 x += i + 1; len -= i + 1; }
158 else {
159 if (!stralloc_catb(&data,"+",1)) die_nomem();
160 if (!stralloc_catb(&data,x,len)) die_nomem();
161 len = 0; }
162 }
164 }
165
166 if (cdb_make_finish(&cdb) == -1) die_write();
167 if (fsync(fdtemp) == -1) die_write();
168 if (close(fdtemp) == -1) die_write(); /* NFS stupidity */
169 if (rename("control/mailfromrules.tmp","control/mailfromrules.cdb") == -1)
170 logmsg(WHO,111,ERROR,"unable to move control/mailfromrules.tmp to control/mailfromrules.cdb");
171
172 _exit(0);
173}
char auto_qmail[]
int stralloc_copys(stralloc *, char const *)
void _exit()
char buf[100+FMT_ULONG]
Definition: hier.c:10
stralloc key
Definition: qmail-mfrules.c:23
struct cdb_make cdb
Definition: qmail-mfrules.c:33
void die_parse()
Definition: qmail-mfrules.c:39
void die_nomem()
Definition: qmail-mfrules.c:35
char inbuf[1024]
Definition: qmail-mfrules.c:26
char strnum[FMT_ULONG]
Definition: qmail-mfrules.c:53
int rename(const char *, const char *)
stralloc address
Definition: qmail-mfrules.c:21
void doaddressdata()
Definition: qmail-mfrules.c:63
int fd
Definition: qmail-mfrules.c:29
void die_write()
Definition: qmail-mfrules.c:48
stralloc data
Definition: qmail-mfrules.c:22
void die_read()
Definition: qmail-mfrules.c:44
stralloc line
Definition: qmail-mfrules.c:24
stralloc sanum
Definition: qmail-mfrules.c:54
buffer bi
Definition: qmail-mfrules.c:27
int match
Definition: qmail-mfrules.c:31
#define WHO
Definition: qmail-mfrules.c:17
int fdtemp
Definition: qmail-mfrules.c:30
int main()
void getnum(char *buf, int len, unsigned long *u)
Definition: qmail-mfrules.c:56