s/qmail 4.2.29a
Next generation secure email transport
Loading...
Searching...
No Matches
newinclude.c
Go to the documentation of this file.
1#include <sys/stat.h>
2#include <unistd.h>
3#include <stdio.h> // rename
4#include "buffer.h"
5#include "logmsg.h"
6#include "genalloc.h"
7#include "stralloc.h"
8#include "getln.h"
9#include "open.h"
10#include "token822.h"
11#include "control.h"
12#include "auto_qmail.h"
13#include "byte.h"
14#include "env.h"
15
16#define WHO "newinclude"
17
18int rename(const char *,const char *); // stdio.h
19
20void nomem()
21{
22 logmsg(WHO,111,FATAL,"out of memory");
23}
24void usage()
25{
26 logmsg(WHO,100,USAGE,"newinclude list");
27}
28
29char *fnlist;
30char listbuf[1024];
31buffer bi;
32
33stralloc bin = {0};
34#define fnbin bin.s
35stralloc tmp = {0};
36#define fntmp tmp.s
37char tmpbuf[1024];
38buffer bt;
39
40
41void readerr()
42{
43 logmsg(WHO,111,FATAL,B("unable to read: ",fnlist));
44}
46{
47 logmsg(WHO,111,FATAL,B("unable to write to ",fntmp));
48}
49
50static void out(char *s,int len)
51{
52 if (buffer_put(&bt,s,len) == -1) writeerr();
53}
54
55void doincl(buf,len)
56char *buf;
57int len;
58{
59 if (!len)
60 logmsg(WHO,111,FATAL,"empty :include: filenames not permitted");
61 if (byte_chr(buf,len,'\n') != len)
62 logmsg(WHO,111,FATAL,"newlines not permitted in :include: filenames");
63 if (byte_chr(buf,len,'\0') != len)
64 logmsg(WHO,111,FATAL,"NUL not permitted in :include: filenames");
65 if ((buf[0] != '.') && (buf[0] != '/'))
66 out("./",2);
67 out(buf,len);
68 out("",1);
69}
70
71void dorecip(buf,len)
72char *buf;
73int len;
74{
75 if (!len)
76 logmsg(WHO,111,FATAL,"empty recipient addresses not permitted");
77 if (byte_chr(buf,len,'\n') != len)
78 logmsg(WHO,111,FATAL,"newlines not permitted in recipient addresses");
79 if (byte_chr(buf,len,'\0') != len)
80 logmsg(WHO,111,FATAL,"NUL not permitted in recipient addresses");
81 if (len > 800)
82 logmsg(WHO,111,FATAL,"addresses must be under 800 bytes");
83 if ((buf[len - 1] == ' ') || (buf[len - 1] == '\t'))
84 logmsg(WHO,111,FATAL,"spaces and tabs not permitted at ends of addresses");
85 out("&",1);
86 out(buf,len);
87 out("",1);
88}
89
90
92{
93 logmsg(WHO,111,FATAL,"unable to read controls");
94}
95
96stralloc me = {0};
97stralloc defaulthost = {0};
98stralloc defaultdomain = {0};
99stralloc plusdomain = {0};
100
102{
103 int r;
104 int fddir;
105 char *x;
106
107 fddir = open_read(".");
108 if (fddir == -1)
109 logmsg(WHO,111,FATAL,"unable to open current directory");
110
111 if (chdir(auto_qmail) == -1)
112 logmsg(WHO,111,FATAL,B("unable to chdir to: ",auto_qmail));
113
114 r = control_readline(&me,"control/me");
115 if (r == -1) die_control();
116 if (!r) if (!stralloc_copys(&me,"me")) nomem();
117
118 r = control_readline(&defaultdomain,"control/defaultdomain");
119 if (r == -1) die_control();
120 if (!r) if (!stralloc_copy(&defaultdomain,&me)) nomem();
121 x = env_get("QMAILDEFAULTDOMAIN");
122 if (x) if (!stralloc_copys(&defaultdomain,x)) nomem();
123
124 r = control_readline(&defaulthost,"control/defaulthost");
125 if (r == -1) die_control();
126 if (!r) if (!stralloc_copy(&defaulthost,&me)) nomem();
127 x = env_get("QMAILDEFAULTHOST");
128 if (x) if (!stralloc_copys(&defaulthost,x)) nomem();
129
130 r = control_readline(&plusdomain,"control/plusdomain");
131 if (r == -1) die_control();
132 if (!r) if (!stralloc_copy(&plusdomain,&me)) nomem();
133 x = env_get("QMAILPLUSDOMAIN");
134 if (x) if (!stralloc_copys(&plusdomain,x)) nomem();
135
136 if (fchdir(fddir) == -1)
137 logmsg(WHO,111,FATAL,"unable to set current directory");
138}
139
140stralloc cbuf = {0};
141token822_alloc toks = {0};
142token822_alloc tokaddr = {0};
143stralloc address = {0};
144
146{
148 if (token822_unquote(&address,&tokaddr) != 1) nomem();
149 tokaddr.len = 0;
150 doincl(address.s,address.len);
151}
152
154{
155 int i;
156 int j;
157 int flaghasat;
158
160 if (token822_unquote(&address,&tokaddr) != 1) nomem();
161
162 flaghasat = 0;
163 for (i = 0;i < tokaddr.len;++i)
164 if (tokaddr.t[i].type == TOKEN822_AT)
165 flaghasat = 1;
166
167 tokaddr.len = 0;
168
169 if (!address.len) return;
170
171 if (!flaghasat)
172 if (address.s[0] == '/') {
173 if (!stralloc_0(&address)) nomem();
174 logmsg(WHO,111,FATAL,B("file delivery for ",address.s," not supported"));
175 }
176 if (!flaghasat)
177 if (address.s[0] == '|') {
178 if (!stralloc_0(&address)) nomem();
179 logmsg(WHO,111,FATAL,B("program delivery for ",address.s," not supported"));
180 }
181
182 if (!flaghasat) {
183 if (!stralloc_cats(&address,"@")) nomem();
184 if (!stralloc_cat(&address,&defaulthost)) nomem();
185 }
186 if (address.s[address.len - 1] == '+') {
187 address.s[address.len - 1] = '.';
188 if (!stralloc_cat(&address,&plusdomain)) nomem();
189 }
190 j = 0;
191 for (i = 0;i < address.len;++i) if (address.s[i] == '@') j = i;
192 for (i = j;i < address.len;++i) if (address.s[i] == '.') break;
193 if (i == address.len) {
194 if (!stralloc_cats(&address,".")) nomem();
195 if (!stralloc_cat(&address,&defaultdomain)) nomem();
196 }
197
198 dorecip(address.s,address.len);
199}
200
201
202stralloc line = {0};
204
206{
207 if (!stralloc_0(&line)) nomem();
208 logmsg(WHO,111,FATAL,B("unable to parse this line: ",line.s));
209}
210
212{
213 int wordok;
214 struct token822 *t;
215 struct token822 *beginning;
216
217 switch (token822_parse(&toks,&line,&cbuf)) {
218 case -1: nomem();
219 case 0: parseerr();
220 }
221
222 beginning = toks.t;
223 t = toks.t + toks.len;
224 wordok = 1;
225
226 if (!token822_readyplus(&tokaddr,1)) nomem();
227 tokaddr.len = 0;
228
229 while (t > beginning)
230 switch ((--t)->type) {
231 case TOKEN822_SEMI:
232 break; /*XXX*/
233 case TOKEN822_COLON:
234 if (t >= beginning + 2)
235 if (t[-2].type == TOKEN822_COLON)
236 if (t[-1].type == TOKEN822_ATOM)
237 if (t[-1].slen == 7)
238 if (!byte_diff(t[-1].s,7,"include")) {
239 gotincl();
240 t -= 2;
241 }
242 break; /*XXX*/
243 case TOKEN822_RIGHT:
244 if (tokaddr.len) gotaddr();
245 while ((t > beginning) && (t[-1].type != TOKEN822_LEFT))
246 if (!token822_append(&tokaddr,--t)) nomem();
247 gotaddr();
248 if (t <= beginning) parseerr();
249 --t;
250 while ((t > beginning) && ((t[-1].type == TOKEN822_COMMENT) || (t[-1].type == TOKEN822_ATOM) || (t[-1].type == TOKEN822_QUOTE) || (t[-1].type == TOKEN822_AT) || (t[-1].type == TOKEN822_DOT)))
251 --t;
252 wordok = 0;
253 continue;
255 if (!wordok) if (tokaddr.len) gotaddr();
256 wordok = 0;
257 if (!token822_append(&tokaddr,t)) nomem();
258 continue;
259 case TOKEN822_COMMENT:
260 /* comment is lexically a space; shouldn't affect wordok */
261 break;
262 case TOKEN822_COMMA:
263 if (tokaddr.len) gotaddr();
264 wordok = 1;
265 break;
266 default:
267 wordok = 1;
268 if (!token822_append(&tokaddr,t)) nomem();
269 continue;
270 }
271 if (tokaddr.len) gotaddr();
272}
273
274
275int main(argc,argv)
276int argc;
277char **argv;
278{
279 int fd;
280
281 umask(033);
282 readcontrols();
283
284 fnlist = argv[1]; if (!fnlist) usage();
285
286 if (!stralloc_copys(&bin,fnlist)) nomem();
287 if (!stralloc_cats(&bin,".bin")) nomem();
288 if (!stralloc_0(&bin)) nomem();
289
290 if (!stralloc_copys(&tmp,fnlist)) nomem();
291 if (!stralloc_cats(&tmp,".tmp")) nomem();
292 if (!stralloc_0(&tmp)) nomem();
293
294 fd = open_read(fnlist);
295 if (fd == -1) readerr();
296 buffer_init(&bi,read,fd,listbuf,sizeof(listbuf));
297
298 fd = open_trunc(fntmp);
299 if (fd == -1) writeerr();
300 buffer_init(&bt,write,fd,tmpbuf,sizeof(tmpbuf));
301
302 for (;;) {
303 if (getln(&bi,&line,&match,'\n') == -1) readerr();
304 if (!line.len) break;
305 if (line.s[0] != '#') parseline();
306 if (!match) break;
307 }
308
309 if (buffer_flush(&bt) == -1) writeerr();
310 if (fsync(fd) == -1) writeerr();
311 if (close(fd) == -1) writeerr(); /* NFS stupidity */
312
313 if (rename(fntmp,fnbin) == -1)
314 logmsg(WHO,111,FATAL,B("unable to move ",fntmp," to: ",fnbin));
315
316 _exit(0);
317}
char auto_qmail[]
int main()
Definition: chkshsgr.c:6
int control_readline(stralloc *sa, char *fn)
Definition: control.c:52
int stralloc_copys(stralloc *, char const *)
stralloc out
Definition: dnscname.c:12
void _exit()
char buf[100+FMT_ULONG]
Definition: hier.c:10
stralloc me
Definition: newinclude.c:96
stralloc defaulthost
Definition: newinclude.c:97
void die_control()
Definition: newinclude.c:91
void doincl(char *buf, int len)
Definition: newinclude.c:55
void dorecip(char *buf, int len)
Definition: newinclude.c:71
char tmpbuf[1024]
Definition: newinclude.c:37
void usage()
Definition: newinclude.c:24
stralloc cbuf
Definition: newinclude.c:140
#define fnbin
Definition: newinclude.c:34
token822_alloc toks
Definition: newinclude.c:141
int rename(const char *, const char *)
stralloc address
Definition: newinclude.c:143
void readcontrols()
Definition: newinclude.c:101
#define fntmp
Definition: newinclude.c:36
void parseerr()
Definition: newinclude.c:205
void readerr()
Definition: newinclude.c:41
char listbuf[1024]
Definition: newinclude.c:30
char * fnlist
Definition: newinclude.c:29
void nomem()
Definition: newinclude.c:20
stralloc tmp
Definition: newinclude.c:35
stralloc line
Definition: newinclude.c:202
buffer bi
Definition: newinclude.c:31
token822_alloc tokaddr
Definition: newinclude.c:142
stralloc plusdomain
Definition: newinclude.c:99
void gotincl()
Definition: newinclude.c:145
void writeerr()
Definition: newinclude.c:45
int match
Definition: newinclude.c:203
stralloc defaultdomain
Definition: newinclude.c:98
void parseline()
Definition: newinclude.c:211
#define WHO
Definition: newinclude.c:16
stralloc bin
Definition: newinclude.c:33
buffer bt
Definition: newinclude.c:38
void gotaddr()
Definition: newinclude.c:153
int fd
int j
Definition: qmail-send.c:920
int slen
Definition: token822.h:9
char * s
Definition: token822.h:8
int type
Definition: token822.h:7
int token822_parse(token822_alloc *ta, stralloc *sa, stralloc *buf)
Definition: token822.c:216
#define TOKEN822_ATOM
Definition: token822.h:24
#define TOKEN822_COMMENT
Definition: token822.h:27
#define TOKEN822_RIGHT
Definition: token822.h:29
#define TOKEN822_LEFT
Definition: token822.h:28
#define TOKEN822_COMMA
Definition: token822.h:31
void token822_reverse()
#define TOKEN822_AT
Definition: token822.h:30
int token822_append()
int token822_readyplus()
#define TOKEN822_SEMI
Definition: token822.h:32
int token822_unquote()
#define TOKEN822_DOT
Definition: token822.h:34
#define TOKEN822_COLON
Definition: token822.h:33
#define TOKEN822_LITERAL
Definition: token822.h:26
#define TOKEN822_QUOTE
Definition: token822.h:25
void write()