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