annotate src/context.cpp @ 21:09564d4acd9e stable-1-0-8

patches from Marco d'Itri for postfix
author Carl Byington <carl@five-ten-sg.com>
date Fri, 24 Dec 2010 15:13:18 -0800
parents b24369330483
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
616666e2f34c initial version
carl
parents:
diff changeset
1 /*
616666e2f34c initial version
carl
parents:
diff changeset
2
13
75e1a9bcbc2e gpl3, add removal option for original recipients
carl
parents: 11
diff changeset
3 Copyright (c) 2007 Carl Byington - 510 Software Group, released under
75e1a9bcbc2e gpl3, add removal option for original recipients
carl
parents: 11
diff changeset
4 the GPL version 3 or any later version at your choice available at
75e1a9bcbc2e gpl3, add removal option for original recipients
carl
parents: 11
diff changeset
5 http://www.gnu.org/licenses/gpl-3.0.txt
0
616666e2f34c initial version
carl
parents:
diff changeset
6
616666e2f34c initial version
carl
parents:
diff changeset
7 */
616666e2f34c initial version
carl
parents:
diff changeset
8
616666e2f34c initial version
carl
parents:
diff changeset
9 #include "includes.h"
616666e2f34c initial version
carl
parents:
diff changeset
10
19
b24369330483 Fedora 9 compile and const correctness.
Carl Byington <carl@five-ten-sg.com>
parents: 17
diff changeset
11 const char *token_envfrom;
b24369330483 Fedora 9 compile and const correctness.
Carl Byington <carl@five-ten-sg.com>
parents: 17
diff changeset
12 const char *token_include;
b24369330483 Fedora 9 compile and const correctness.
Carl Byington <carl@five-ten-sg.com>
parents: 17
diff changeset
13 const char *token_lbrace;
b24369330483 Fedora 9 compile and const correctness.
Carl Byington <carl@five-ten-sg.com>
parents: 17
diff changeset
14 const char *token_rbrace;
b24369330483 Fedora 9 compile and const correctness.
Carl Byington <carl@five-ten-sg.com>
parents: 17
diff changeset
15 const char *token_rcptto;
b24369330483 Fedora 9 compile and const correctness.
Carl Byington <carl@five-ten-sg.com>
parents: 17
diff changeset
16 const char *token_remove;
b24369330483 Fedora 9 compile and const correctness.
Carl Byington <carl@five-ten-sg.com>
parents: 17
diff changeset
17 const char *token_semi;
0
616666e2f34c initial version
carl
parents:
diff changeset
18
616666e2f34c initial version
carl
parents:
diff changeset
19 string_set all_strings; // owns all the strings, only modified by the config loader thread
616666e2f34c initial version
carl
parents:
diff changeset
20 const int maxlen = 1000; // used for snprintf buffers
616666e2f34c initial version
carl
parents:
diff changeset
21
616666e2f34c initial version
carl
parents:
diff changeset
22 CONFIG::CONFIG() {
616666e2f34c initial version
carl
parents:
diff changeset
23 reference_count = 0;
616666e2f34c initial version
carl
parents:
diff changeset
24 generation = 0;
616666e2f34c initial version
carl
parents:
diff changeset
25 load_time = 0;
616666e2f34c initial version
carl
parents:
diff changeset
26 }
616666e2f34c initial version
carl
parents:
diff changeset
27
616666e2f34c initial version
carl
parents:
diff changeset
28
616666e2f34c initial version
carl
parents:
diff changeset
29 CONFIG::~CONFIG() {
616666e2f34c initial version
carl
parents:
diff changeset
30 }
616666e2f34c initial version
carl
parents:
diff changeset
31
616666e2f34c initial version
carl
parents:
diff changeset
32
19
b24369330483 Fedora 9 compile and const correctness.
Carl Byington <carl@five-ten-sg.com>
parents: 17
diff changeset
33 bool CONFIG::find(const char *needle, string_set &haystack) {
13
75e1a9bcbc2e gpl3, add removal option for original recipients
carl
parents: 11
diff changeset
34 string_set::iterator i = haystack.find(needle);
75e1a9bcbc2e gpl3, add removal option for original recipients
carl
parents: 11
diff changeset
35 if (i != haystack.end()) return true; // found user@domain.tld key
21
09564d4acd9e patches from Marco d'Itri for postfix
Carl Byington <carl@five-ten-sg.com>
parents: 19
diff changeset
36 const char *x = strchr(needle, '@');
0
616666e2f34c initial version
carl
parents:
diff changeset
37 if (x) {
616666e2f34c initial version
carl
parents:
diff changeset
38 x++;
616666e2f34c initial version
carl
parents:
diff changeset
39 i = haystack.find(x);
13
75e1a9bcbc2e gpl3, add removal option for original recipients
carl
parents: 11
diff changeset
40 if (i != haystack.end()) return true; // found domain.tld key
21
09564d4acd9e patches from Marco d'Itri for postfix
Carl Byington <carl@five-ten-sg.com>
parents: 19
diff changeset
41 string userpart(needle, x-needle);
09564d4acd9e patches from Marco d'Itri for postfix
Carl Byington <carl@five-ten-sg.com>
parents: 19
diff changeset
42 i = haystack.find(userpart.c_str());
13
75e1a9bcbc2e gpl3, add removal option for original recipients
carl
parents: 11
diff changeset
43 if (i != haystack.end()) return true; // found user@ key
75e1a9bcbc2e gpl3, add removal option for original recipients
carl
parents: 11
diff changeset
44 }
75e1a9bcbc2e gpl3, add removal option for original recipients
carl
parents: 11
diff changeset
45 return false;
75e1a9bcbc2e gpl3, add removal option for original recipients
carl
parents: 11
diff changeset
46 }
75e1a9bcbc2e gpl3, add removal option for original recipients
carl
parents: 11
diff changeset
47
75e1a9bcbc2e gpl3, add removal option for original recipients
carl
parents: 11
diff changeset
48
19
b24369330483 Fedora 9 compile and const correctness.
Carl Byington <carl@five-ten-sg.com>
parents: 17
diff changeset
49 const char *CONFIG::find(const char *needle, string_map &haystack) {
13
75e1a9bcbc2e gpl3, add removal option for original recipients
carl
parents: 11
diff changeset
50 string_map::iterator i = haystack.find(needle);
75e1a9bcbc2e gpl3, add removal option for original recipients
carl
parents: 11
diff changeset
51 if (i != haystack.end()) return (*i).second; // found user@domain.tld key
21
09564d4acd9e patches from Marco d'Itri for postfix
Carl Byington <carl@five-ten-sg.com>
parents: 19
diff changeset
52 const char *x = strchr(needle, '@');
13
75e1a9bcbc2e gpl3, add removal option for original recipients
carl
parents: 11
diff changeset
53 if (x) {
75e1a9bcbc2e gpl3, add removal option for original recipients
carl
parents: 11
diff changeset
54 x++;
75e1a9bcbc2e gpl3, add removal option for original recipients
carl
parents: 11
diff changeset
55 i = haystack.find(x);
75e1a9bcbc2e gpl3, add removal option for original recipients
carl
parents: 11
diff changeset
56 if (i != haystack.end()) return (*i).second; // found domain.tld key
21
09564d4acd9e patches from Marco d'Itri for postfix
Carl Byington <carl@five-ten-sg.com>
parents: 19
diff changeset
57 string userpart(needle, x-needle);
09564d4acd9e patches from Marco d'Itri for postfix
Carl Byington <carl@five-ten-sg.com>
parents: 19
diff changeset
58 i = haystack.find(userpart.c_str());
13
75e1a9bcbc2e gpl3, add removal option for original recipients
carl
parents: 11
diff changeset
59 if (i != haystack.end()) return (*i).second; // found user@ key
0
616666e2f34c initial version
carl
parents:
diff changeset
60 }
616666e2f34c initial version
carl
parents:
diff changeset
61 return NULL;
616666e2f34c initial version
carl
parents:
diff changeset
62 }
616666e2f34c initial version
carl
parents:
diff changeset
63
616666e2f34c initial version
carl
parents:
diff changeset
64
616666e2f34c initial version
carl
parents:
diff changeset
65 void CONFIG::dump() {
616666e2f34c initial version
carl
parents:
diff changeset
66 printf("rcpt_to {\n");
616666e2f34c initial version
carl
parents:
diff changeset
67 for (string_map::iterator i=rcpt_to.begin(); i!=rcpt_to.end(); i++) {
19
b24369330483 Fedora 9 compile and const correctness.
Carl Byington <carl@five-ten-sg.com>
parents: 17
diff changeset
68 const char *to = (*i).first;
b24369330483 Fedora 9 compile and const correctness.
Carl Byington <carl@five-ten-sg.com>
parents: 17
diff changeset
69 const char *target = (*i).second;
13
75e1a9bcbc2e gpl3, add removal option for original recipients
carl
parents: 11
diff changeset
70 if (!target) target = "\"\"";
75e1a9bcbc2e gpl3, add removal option for original recipients
carl
parents: 11
diff changeset
71 bool rem = find_remove(to);
75e1a9bcbc2e gpl3, add removal option for original recipients
carl
parents: 11
diff changeset
72 printf(" %s \t %s%s;\n", to, target, (rem) ? " remove" : "");
0
616666e2f34c initial version
carl
parents:
diff changeset
73 }
616666e2f34c initial version
carl
parents:
diff changeset
74 printf("};\n");
616666e2f34c initial version
carl
parents:
diff changeset
75 printf("env_from {\n");
616666e2f34c initial version
carl
parents:
diff changeset
76 for (string_map::iterator i=env_from.begin(); i!=env_from.end(); i++) {
19
b24369330483 Fedora 9 compile and const correctness.
Carl Byington <carl@five-ten-sg.com>
parents: 17
diff changeset
77 const char *from = (*i).first;
b24369330483 Fedora 9 compile and const correctness.
Carl Byington <carl@five-ten-sg.com>
parents: 17
diff changeset
78 const char *target = (*i).second;
13
75e1a9bcbc2e gpl3, add removal option for original recipients
carl
parents: 11
diff changeset
79 if (!target) target = "\"\"";
75e1a9bcbc2e gpl3, add removal option for original recipients
carl
parents: 11
diff changeset
80 printf(" %s \t %s;\n", from, target);
0
616666e2f34c initial version
carl
parents:
diff changeset
81 }
616666e2f34c initial version
carl
parents:
diff changeset
82 printf("};\n");
616666e2f34c initial version
carl
parents:
diff changeset
83 }
616666e2f34c initial version
carl
parents:
diff changeset
84
616666e2f34c initial version
carl
parents:
diff changeset
85
616666e2f34c initial version
carl
parents:
diff changeset
86 ////////////////////////////////////////////////
616666e2f34c initial version
carl
parents:
diff changeset
87 // helper to discard the strings held by a string_set
616666e2f34c initial version
carl
parents:
diff changeset
88 //
616666e2f34c initial version
carl
parents:
diff changeset
89 void discard(string_set &s) {
616666e2f34c initial version
carl
parents:
diff changeset
90 for (string_set::iterator i=s.begin(); i!=s.end(); i++) {
19
b24369330483 Fedora 9 compile and const correctness.
Carl Byington <carl@five-ten-sg.com>
parents: 17
diff changeset
91 free((void*)*i);
0
616666e2f34c initial version
carl
parents:
diff changeset
92 }
616666e2f34c initial version
carl
parents:
diff changeset
93 s.clear();
616666e2f34c initial version
carl
parents:
diff changeset
94 }
616666e2f34c initial version
carl
parents:
diff changeset
95
616666e2f34c initial version
carl
parents:
diff changeset
96
616666e2f34c initial version
carl
parents:
diff changeset
97 ////////////////////////////////////////////////
616666e2f34c initial version
carl
parents:
diff changeset
98 // helper to register a string in a string set
616666e2f34c initial version
carl
parents:
diff changeset
99 //
19
b24369330483 Fedora 9 compile and const correctness.
Carl Byington <carl@five-ten-sg.com>
parents: 17
diff changeset
100 const char* register_string(string_set &s, const char *name) {
0
616666e2f34c initial version
carl
parents:
diff changeset
101 string_set::iterator i = s.find(name);
616666e2f34c initial version
carl
parents:
diff changeset
102 if (i != s.end()) return *i;
616666e2f34c initial version
carl
parents:
diff changeset
103 char *x = strdup(name);
616666e2f34c initial version
carl
parents:
diff changeset
104 s.insert(x);
616666e2f34c initial version
carl
parents:
diff changeset
105 return x;
616666e2f34c initial version
carl
parents:
diff changeset
106 }
616666e2f34c initial version
carl
parents:
diff changeset
107
616666e2f34c initial version
carl
parents:
diff changeset
108
616666e2f34c initial version
carl
parents:
diff changeset
109 ////////////////////////////////////////////////
616666e2f34c initial version
carl
parents:
diff changeset
110 // register a global string
616666e2f34c initial version
carl
parents:
diff changeset
111 //
19
b24369330483 Fedora 9 compile and const correctness.
Carl Byington <carl@five-ten-sg.com>
parents: 17
diff changeset
112 const char* register_string(const char *name) {
0
616666e2f34c initial version
carl
parents:
diff changeset
113 return register_string(all_strings, name);
616666e2f34c initial version
carl
parents:
diff changeset
114 }
616666e2f34c initial version
carl
parents:
diff changeset
115
616666e2f34c initial version
carl
parents:
diff changeset
116
616666e2f34c initial version
carl
parents:
diff changeset
117 ////////////////////////////////////////////////
13
75e1a9bcbc2e gpl3, add removal option for original recipients
carl
parents: 11
diff changeset
118 // clear all global strings, helper for valgrind checking
75e1a9bcbc2e gpl3, add removal option for original recipients
carl
parents: 11
diff changeset
119 //
75e1a9bcbc2e gpl3, add removal option for original recipients
carl
parents: 11
diff changeset
120 void clear_strings() {
75e1a9bcbc2e gpl3, add removal option for original recipients
carl
parents: 11
diff changeset
121 discard(all_strings);
75e1a9bcbc2e gpl3, add removal option for original recipients
carl
parents: 11
diff changeset
122 }
75e1a9bcbc2e gpl3, add removal option for original recipients
carl
parents: 11
diff changeset
123
75e1a9bcbc2e gpl3, add removal option for original recipients
carl
parents: 11
diff changeset
124
75e1a9bcbc2e gpl3, add removal option for original recipients
carl
parents: 11
diff changeset
125 ////////////////////////////////////////////////
0
616666e2f34c initial version
carl
parents:
diff changeset
126 //
19
b24369330483 Fedora 9 compile and const correctness.
Carl Byington <carl@five-ten-sg.com>
parents: 17
diff changeset
127 bool tsa(TOKEN &tok, const char *token);
b24369330483 Fedora 9 compile and const correctness.
Carl Byington <carl@five-ten-sg.com>
parents: 17
diff changeset
128 bool tsa(TOKEN &tok, const char *token) {
b24369330483 Fedora 9 compile and const correctness.
Carl Byington <carl@five-ten-sg.com>
parents: 17
diff changeset
129 const char *have = tok.next();
0
616666e2f34c initial version
carl
parents:
diff changeset
130 if (have == token) return true;
616666e2f34c initial version
carl
parents:
diff changeset
131 tok.token_error(token, have);
616666e2f34c initial version
carl
parents:
diff changeset
132 return false;
616666e2f34c initial version
carl
parents:
diff changeset
133 }
616666e2f34c initial version
carl
parents:
diff changeset
134
616666e2f34c initial version
carl
parents:
diff changeset
135
616666e2f34c initial version
carl
parents:
diff changeset
136 ////////////////////////////////////////////////
616666e2f34c initial version
carl
parents:
diff changeset
137 //
616666e2f34c initial version
carl
parents:
diff changeset
138 bool parse_rcpt_to(TOKEN &tok, CONFIG &dc);
616666e2f34c initial version
carl
parents:
diff changeset
139 bool parse_rcpt_to(TOKEN &tok, CONFIG &dc) {
616666e2f34c initial version
carl
parents:
diff changeset
140 if (!tsa(tok, token_lbrace)) return false;
616666e2f34c initial version
carl
parents:
diff changeset
141 while (true) {
19
b24369330483 Fedora 9 compile and const correctness.
Carl Byington <carl@five-ten-sg.com>
parents: 17
diff changeset
142 const char *have = tok.next();
0
616666e2f34c initial version
carl
parents:
diff changeset
143 if (!have) break;
616666e2f34c initial version
carl
parents:
diff changeset
144 if (have == token_rbrace) break;
19
b24369330483 Fedora 9 compile and const correctness.
Carl Byington <carl@five-ten-sg.com>
parents: 17
diff changeset
145 const char *target = tok.next();
13
75e1a9bcbc2e gpl3, add removal option for original recipients
carl
parents: 11
diff changeset
146 dc.add_to(have, target);
75e1a9bcbc2e gpl3, add removal option for original recipients
carl
parents: 11
diff changeset
147 target = tok.next();
75e1a9bcbc2e gpl3, add removal option for original recipients
carl
parents: 11
diff changeset
148 if (target == token_remove) {
75e1a9bcbc2e gpl3, add removal option for original recipients
carl
parents: 11
diff changeset
149 dc.add_remove(have);
75e1a9bcbc2e gpl3, add removal option for original recipients
carl
parents: 11
diff changeset
150 target = tok.next();
0
616666e2f34c initial version
carl
parents:
diff changeset
151 }
13
75e1a9bcbc2e gpl3, add removal option for original recipients
carl
parents: 11
diff changeset
152 if (target != token_semi) {
75e1a9bcbc2e gpl3, add removal option for original recipients
carl
parents: 11
diff changeset
153 tok.token_error(token_semi, target);
75e1a9bcbc2e gpl3, add removal option for original recipients
carl
parents: 11
diff changeset
154 break;
0
616666e2f34c initial version
carl
parents:
diff changeset
155 }
616666e2f34c initial version
carl
parents:
diff changeset
156 }
616666e2f34c initial version
carl
parents:
diff changeset
157 return tsa(tok, token_semi);
616666e2f34c initial version
carl
parents:
diff changeset
158 }
616666e2f34c initial version
carl
parents:
diff changeset
159
616666e2f34c initial version
carl
parents:
diff changeset
160
616666e2f34c initial version
carl
parents:
diff changeset
161 ////////////////////////////////////////////////
616666e2f34c initial version
carl
parents:
diff changeset
162 //
616666e2f34c initial version
carl
parents:
diff changeset
163 bool parse_env_from(TOKEN &tok, CONFIG &dc);
616666e2f34c initial version
carl
parents:
diff changeset
164 bool parse_env_from(TOKEN &tok, CONFIG &dc) {
616666e2f34c initial version
carl
parents:
diff changeset
165 if (!tsa(tok, token_lbrace)) return false;
616666e2f34c initial version
carl
parents:
diff changeset
166 while (true) {
19
b24369330483 Fedora 9 compile and const correctness.
Carl Byington <carl@five-ten-sg.com>
parents: 17
diff changeset
167 const char *have = tok.next();
0
616666e2f34c initial version
carl
parents:
diff changeset
168 if (!have) break;
616666e2f34c initial version
carl
parents:
diff changeset
169 if (have == token_rbrace) break;
616666e2f34c initial version
carl
parents:
diff changeset
170 if (have == token_semi) {
616666e2f34c initial version
carl
parents:
diff changeset
171 // optional separators
616666e2f34c initial version
carl
parents:
diff changeset
172 }
616666e2f34c initial version
carl
parents:
diff changeset
173 else {
19
b24369330483 Fedora 9 compile and const correctness.
Carl Byington <carl@five-ten-sg.com>
parents: 17
diff changeset
174 const char *target = tok.next();
0
616666e2f34c initial version
carl
parents:
diff changeset
175 dc.add_from(have, target);
616666e2f34c initial version
carl
parents:
diff changeset
176 }
616666e2f34c initial version
carl
parents:
diff changeset
177 }
616666e2f34c initial version
carl
parents:
diff changeset
178 return tsa(tok, token_semi);
616666e2f34c initial version
carl
parents:
diff changeset
179 }
616666e2f34c initial version
carl
parents:
diff changeset
180
616666e2f34c initial version
carl
parents:
diff changeset
181
616666e2f34c initial version
carl
parents:
diff changeset
182 ////////////////////////////////////////////////
616666e2f34c initial version
carl
parents:
diff changeset
183 // parse a config file
616666e2f34c initial version
carl
parents:
diff changeset
184 //
19
b24369330483 Fedora 9 compile and const correctness.
Carl Byington <carl@five-ten-sg.com>
parents: 17
diff changeset
185 bool load_conf(CONFIG &dc, const char *fn) {
0
616666e2f34c initial version
carl
parents:
diff changeset
186 TOKEN tok(fn, &dc.config_files);
616666e2f34c initial version
carl
parents:
diff changeset
187 while (true) {
19
b24369330483 Fedora 9 compile and const correctness.
Carl Byington <carl@five-ten-sg.com>
parents: 17
diff changeset
188 const char *have = tok.next();
0
616666e2f34c initial version
carl
parents:
diff changeset
189 if (!have) break;
616666e2f34c initial version
carl
parents:
diff changeset
190 if (have == token_envfrom) {
616666e2f34c initial version
carl
parents:
diff changeset
191 if (!parse_env_from(tok, dc)) {
616666e2f34c initial version
carl
parents:
diff changeset
192 tok.token_error("load_conf() failed to parse env_from");
616666e2f34c initial version
carl
parents:
diff changeset
193 return false;
616666e2f34c initial version
carl
parents:
diff changeset
194 }
616666e2f34c initial version
carl
parents:
diff changeset
195 }
616666e2f34c initial version
carl
parents:
diff changeset
196 else if (have == token_rcptto) {
616666e2f34c initial version
carl
parents:
diff changeset
197 if (!parse_rcpt_to(tok, dc)) {
616666e2f34c initial version
carl
parents:
diff changeset
198 tok.token_error("load_conf() failed to parse rcpt_to");
616666e2f34c initial version
carl
parents:
diff changeset
199 return false;
616666e2f34c initial version
carl
parents:
diff changeset
200 }
616666e2f34c initial version
carl
parents:
diff changeset
201 }
616666e2f34c initial version
carl
parents:
diff changeset
202 else {
3
01268466f0dc initial version
carl
parents: 0
diff changeset
203 tok.token_error("env_from/rcpt_to", have);
0
616666e2f34c initial version
carl
parents:
diff changeset
204 return false;
616666e2f34c initial version
carl
parents:
diff changeset
205 }
616666e2f34c initial version
carl
parents:
diff changeset
206 }
616666e2f34c initial version
carl
parents:
diff changeset
207 return true;
616666e2f34c initial version
carl
parents:
diff changeset
208 }
616666e2f34c initial version
carl
parents:
diff changeset
209
616666e2f34c initial version
carl
parents:
diff changeset
210
616666e2f34c initial version
carl
parents:
diff changeset
211 ////////////////////////////////////////////////
616666e2f34c initial version
carl
parents:
diff changeset
212 // init the tokens
616666e2f34c initial version
carl
parents:
diff changeset
213 //
616666e2f34c initial version
carl
parents:
diff changeset
214 void token_init() {
616666e2f34c initial version
carl
parents:
diff changeset
215 token_envfrom = register_string("env_from");
3
01268466f0dc initial version
carl
parents: 0
diff changeset
216 token_include = register_string("include");
0
616666e2f34c initial version
carl
parents:
diff changeset
217 token_lbrace = register_string("{");
616666e2f34c initial version
carl
parents:
diff changeset
218 token_rbrace = register_string("}");
616666e2f34c initial version
carl
parents:
diff changeset
219 token_rcptto = register_string("rcpt_to");
13
75e1a9bcbc2e gpl3, add removal option for original recipients
carl
parents: 11
diff changeset
220 token_remove = register_string("remove");
0
616666e2f34c initial version
carl
parents:
diff changeset
221 token_semi = register_string(";");
616666e2f34c initial version
carl
parents:
diff changeset
222 }