Mercurial > masqmail
comparison src/alias.c @ 390:68ae9182059c
Refactoring and code layouting.
author | markus schnalke <meillo@marmaro.de> |
---|---|
date | Sat, 18 Feb 2012 13:50:02 +0100 |
parents | a408411ff8df |
children | c7cc3c03193c |
comparison
equal
deleted
inserted
replaced
389:bc9a7845b53a | 390:68ae9182059c |
---|---|
26 { | 26 { |
27 GList *dom_node; | 27 GList *dom_node; |
28 GList *addr_node; | 28 GList *addr_node; |
29 address *a; | 29 address *a; |
30 | 30 |
31 if (addr->domain == NULL) { | 31 if (!addr->domain) { |
32 return TRUE; | 32 return TRUE; |
33 } | 33 } |
34 foreach(conf.local_hosts, dom_node) { | 34 foreach(conf.local_hosts, dom_node) { |
35 /* Note: FNM_CASEFOLD is a GNU extension */ | 35 /* Note: FNM_CASEFOLD is a GNU extension */ |
36 if (fnmatch(dom_node->data, addr->domain, FNM_CASEFOLD) != 0) { | 36 if (fnmatch(dom_node->data, addr->domain, FNM_CASEFOLD)!=0) { |
37 /* no match, try next */ | 37 /* no match, try next */ |
38 continue; | 38 continue; |
39 } | 39 } |
40 foreach(conf.not_local_addresses, addr_node) { | 40 foreach(conf.not_local_addresses, addr_node) { |
41 a = create_address_qualified(addr_node->data, TRUE, conf.host_name); | 41 a = create_address_qualified(addr_node->data, TRUE, |
42 DEBUG(6) debugf("not_local_addresses: addr_node->data=%s a->address=%s\n", | 42 conf.host_name); |
43 DEBUG(6) debugf("not_local_addresses: " | |
44 "addr_node->data=%s a->address=%s\n", | |
43 addr_node->data, a->address); | 45 addr_node->data, a->address); |
44 if (addr_isequal(a, addr, conf.localpartcmp)) { | 46 if (addr_isequal(a, addr, conf.localpartcmp)) { |
47 /* also in not_local_addresses */ | |
45 destroy_address(a); | 48 destroy_address(a); |
46 /* in local_hosts but also in not_local_addresses */ | |
47 return FALSE; | 49 return FALSE; |
48 } | 50 } |
49 destroy_address(a); | 51 destroy_address(a); |
50 } | 52 } |
51 /* in local_hosts */ | 53 /* in local_hosts */ |
52 return TRUE; | 54 return TRUE; |
53 } | 55 } |
54 foreach(conf.local_addresses, addr_node) { | 56 foreach(conf.local_addresses, addr_node) { |
55 a = create_address_qualified(addr_node->data, TRUE, conf.host_name); | 57 a = create_address_qualified(addr_node->data, TRUE, |
56 DEBUG(6) debugf("local_addresses: addr_node->data=%s a->address=%s\n", | 58 conf.host_name); |
59 DEBUG(6) debugf("local_addresses: addr_node->data=%s " | |
60 "a->address=%s\n", | |
57 addr_node->data, a->address); | 61 addr_node->data, a->address); |
58 if (addr_isequal(a, addr, conf.localpartcmp)) { | 62 if (addr_isequal(a, addr, conf.localpartcmp)) { |
63 /* in local_addresses */ | |
59 destroy_address(a); | 64 destroy_address(a); |
60 /* in local_addresses */ | |
61 return TRUE; | 65 return TRUE; |
62 } | 66 } |
63 destroy_address(a); | 67 destroy_address(a); |
64 } | 68 } |
65 return FALSE; | 69 return FALSE; |
71 GList *list = NULL; | 75 GList *list = NULL; |
72 gchar buf[256]; | 76 gchar buf[256]; |
73 gchar *p, *q; | 77 gchar *p, *q; |
74 | 78 |
75 p = line; | 79 p = line; |
76 while (*p != '\0') { | 80 while (*p) { |
77 q = buf; | 81 q = buf; |
78 while (isspace(*p)) | 82 while (isspace(*p)) { |
79 p++; | 83 p++; |
84 } | |
80 if (*p != '"') { | 85 if (*p != '"') { |
81 while (*p && (*p != ',') && (q < buf + 255)) | 86 while (*p && (*p != ',') && (q < buf + 255)) { |
82 *(q++) = *(p++); | 87 *(q++) = *(p++); |
88 } | |
83 *q = '\0'; | 89 *q = '\0'; |
84 } else { | 90 } else { |
85 gboolean escape = FALSE; | 91 gboolean escape = FALSE; |
86 p++; | 92 p++; |
87 while (*p && (*p != '"' || escape) && (q < buf + 255)) { | 93 while (*p && (*p != '"' || escape) && (q < buf+255)) { |
88 if ((*p == '\\') && !escape) | 94 if ((*p == '\\') && !escape) { |
89 escape = TRUE; | 95 escape = TRUE; |
90 else { | 96 } else { |
91 escape = FALSE; | 97 escape = FALSE; |
92 *(q++) = *p; | 98 *(q++) = *p; |
93 } | 99 } |
94 p++; | 100 p++; |
95 } | 101 } |
96 *q = '\0'; | 102 *q = '\0'; |
97 while (*p && (*p != ',')) | 103 while (*p && (*p != ',')) { |
98 p++; | 104 p++; |
105 } | |
99 } | 106 } |
100 list = g_list_append(list, g_strdup(g_strchomp(buf))); | 107 list = g_list_append(list, g_strdup(g_strchomp(buf))); |
101 if (*p) | 108 if (*p) { |
102 p++; | 109 p++; |
110 } | |
103 } | 111 } |
104 return list; | 112 return list; |
105 } | 113 } |
106 | 114 |
107 static int | 115 static int |
108 globaliascmp(const char *pattern, const char *addr) | 116 globaliascmp(const char *pattern, const char *addr) |
109 { | 117 { |
110 if (conf.localpartcmp==strcasecmp) { | 118 if (conf.localpartcmp == strcasecmp) { |
111 return fnmatch(pattern, addr, FNM_CASEFOLD); | 119 return fnmatch(pattern, addr, FNM_CASEFOLD); |
112 } else if (strncasecmp(addr, "postmaster", 10)==0) { | 120 } else if (strncasecmp(addr, "postmaster", 10)==0) { |
113 /* | 121 /* postmaster must always be matched caseless |
114 ** postmaster must always be matched caseless | 122 ** see RFC 822 and RFC 5321 */ |
115 ** see RFC 822 and RFC 5321 | |
116 */ | |
117 return fnmatch(pattern, addr, FNM_CASEFOLD); | 123 return fnmatch(pattern, addr, FNM_CASEFOLD); |
118 } else { | 124 } else { |
119 /* case-sensitive */ | 125 /* case-sensitive */ |
120 return fnmatch(pattern, addr, 0); | 126 return fnmatch(pattern, addr, 0); |
121 } | 127 } |
140 if (doglob) { | 146 if (doglob) { |
141 val = (gchar *) table_find_func(alias_table, addr->address, | 147 val = (gchar *) table_find_func(alias_table, addr->address, |
142 globaliascmp); | 148 globaliascmp); |
143 | 149 |
144 } else if (strcasecmp(addr->local_part, "postmaster") == 0) { | 150 } else if (strcasecmp(addr->local_part, "postmaster") == 0) { |
145 /* | 151 /* postmaster must always be matched caseless |
146 ** postmaster must always be matched caseless | 152 ** see RFC 822 and RFC 5321 */ |
147 ** see RFC 822 and RFC 5321 | |
148 */ | |
149 val = (gchar *) table_find_func(alias_table, addr->local_part, | 153 val = (gchar *) table_find_func(alias_table, addr->local_part, |
150 strcasecmp); | 154 strcasecmp); |
151 } else { | 155 } else { |
152 val = (gchar *) table_find_func(alias_table, addr->local_part, | 156 val = (gchar *) table_find_func(alias_table, addr->local_part, |
153 conf.localpartcmp); | 157 conf.localpartcmp); |
169 address *alias_addr; | 173 address *alias_addr; |
170 | 174 |
171 DEBUG(6) debugf("alias: processing '%s'\n", val); | 175 DEBUG(6) debugf("alias: processing '%s'\n", val); |
172 | 176 |
173 if (val[0] == '\\') { | 177 if (val[0] == '\\') { |
174 DEBUG(5) debugf("alias: '%s' is marked as final, hence completed\n", val); | 178 DEBUG(5) debugf("alias: '%s' is marked as final, " |
175 alias_addr = create_address_qualified(val+1, TRUE, conf.host_name); | 179 "hence completed\n", val); |
180 alias_addr = create_address_qualified(val+1, TRUE, | |
181 conf.host_name); | |
176 g_free(val); | 182 g_free(val); |
177 DEBUG(6) debugf("alias: address generated: '%s'\n", | 183 DEBUG(6) debugf("alias: address generated: '%s'\n", |
178 alias_addr->address); | 184 alias_addr->address); |
179 alias_list = g_list_append(alias_list, alias_addr); | 185 alias_list = g_list_append(alias_list, alias_addr); |
180 continue; | 186 continue; |
181 } | 187 } |
182 | 188 |
183 if (val[0] == '|') { | 189 if (val[0] == '|') { |
184 DEBUG(5) debugf("alias: '%s' is a pipe address\n", val); | 190 DEBUG(5) debugf("alias: '%s' is a pipe address\n", |
191 val); | |
185 alias_addr = create_address_pipe(val); | 192 alias_addr = create_address_pipe(val); |
186 g_free(val); | 193 g_free(val); |
187 DEBUG(6) debugf("alias: pipe generated: %s\n", | 194 DEBUG(6) debugf("alias: pipe generated: %s\n", |
188 alias_addr->local_part); | 195 alias_addr->local_part); |
189 alias_list = g_list_append(alias_list, alias_addr); | 196 alias_list = g_list_append(alias_list, alias_addr); |
190 continue; | 197 continue; |
191 } | 198 } |
192 | 199 |
193 alias_addr = create_address_qualified(val, TRUE, conf.host_name); | 200 alias_addr = create_address_qualified(val, TRUE, |
201 conf.host_name); | |
194 g_free(val); | 202 g_free(val); |
195 | 203 |
196 if (!addr_is_local(alias_addr)) { | 204 if (!addr_is_local(alias_addr)) { |
197 DEBUG(5) debugf("alias: '%s' is non-local, hence completed\n", | 205 DEBUG(5) debugf("alias: '%s' is non-local, " |
206 "hence completed\n", | |
198 alias_addr->address); | 207 alias_addr->address); |
199 alias_list = g_list_append(alias_list, alias_addr); | 208 alias_list = g_list_append(alias_list, alias_addr); |
200 continue; | 209 continue; |
201 } | 210 } |
202 | 211 |
203 /* addr is local and to expand at this point */ | 212 /* addr is local and to expand at this point */ |
204 /* but first ... search in parents for loops: */ | 213 /* but first ... search in parents for loops: */ |
205 if (addr_isequal_parent(addr, alias_addr, conf.localpartcmp)) { | 214 if (addr_isequal_parent(addr, alias_addr, conf.localpartcmp)) { |
206 /* loop detected, ignore this path */ | 215 /* loop detected, ignore this path */ |
207 logwrite(LOG_ALERT, "alias: detected loop, hence ignoring '%s'\n", | 216 logwrite(LOG_ALERT, "alias: detected loop, " |
208 alias_addr->local_part); | 217 "hence ignoring '%s'\n", |
218 alias_addr->local_part); | |
209 continue; | 219 continue; |
210 } | 220 } |
211 alias_addr->parent = addr; | 221 alias_addr->parent = addr; |
212 | 222 |
213 /* recurse */ | 223 /* recurse */ |
238 rcpt_node; | 248 rcpt_node; |
239 rcpt_node=g_list_next(rcpt_node)) { | 249 rcpt_node=g_list_next(rcpt_node)) { |
240 | 250 |
241 addr = (address *) (rcpt_node->data); | 251 addr = (address *) (rcpt_node->data); |
242 if (addr_is_local(addr)) { | 252 if (addr_is_local(addr)) { |
243 DEBUG(5) debugf("alias: (orig rcpt addr) expand local '%s'\n", | 253 DEBUG(5) debugf("alias: (orig rcpt addr) " |
244 doglob ? addr->address : addr->local_part); | 254 "expand local '%s'\n", |
255 doglob ? addr->address : | |
256 addr->local_part); | |
245 alias_list = expand_one(alias_table, addr, doglob); | 257 alias_list = expand_one(alias_table, addr, doglob); |
246 if (alias_list) { | 258 if (alias_list) { |
247 done_list = g_list_concat(done_list, alias_list); | 259 done_list = g_list_concat(done_list, |
260 alias_list); | |
248 } | 261 } |
249 } else { | 262 } else { |
250 DEBUG(5) debugf("alias: (orig rcpt addr) don't expand non-local '%s'\n", | 263 DEBUG(5) debugf("alias: (orig rcpt addr) don't " |
264 "expand non-local '%s'\n", | |
251 addr->address); | 265 addr->address); |
252 done_list = g_list_append(done_list, addr); | 266 done_list = g_list_append(done_list, addr); |
253 } | 267 } |
254 } | 268 } |
255 | 269 |
257 if (!non_rcpt_list) { | 271 if (!non_rcpt_list) { |
258 return done_list; | 272 return done_list; |
259 } | 273 } |
260 | 274 |
261 /* delete addresses of non_rcpt_list from done_list */ | 275 /* delete addresses of non_rcpt_list from done_list */ |
262 for (rcpt_node = g_list_first(done_list); rcpt_node; rcpt_node = rcpt_node_next) { | 276 for (rcpt_node = g_list_first(done_list); rcpt_node; |
277 rcpt_node = rcpt_node_next) { | |
263 address *addr = (address *) (rcpt_node->data); | 278 address *addr = (address *) (rcpt_node->data); |
264 GList *non_node; | 279 GList *non_node; |
265 | 280 |
266 rcpt_node_next = g_list_next(rcpt_node); | 281 rcpt_node_next = g_list_next(rcpt_node); |
267 foreach(non_rcpt_list, non_node) { | 282 foreach(non_rcpt_list, non_node) { |
268 address *non_addr = (address *) (non_node->data); | 283 address *non_addr = (address *) (non_node->data); |
269 if (addr_isequal(addr, non_addr, conf.localpartcmp)) { | 284 if (addr_isequal(addr, non_addr, conf.localpartcmp)) { |
270 done_list = g_list_remove_link(done_list, rcpt_node); | 285 done_list = g_list_remove_link(done_list, |
286 rcpt_node); | |
271 g_list_free_1(rcpt_node); | 287 g_list_free_1(rcpt_node); |
272 /* | 288 /* |
273 ** this address is still in the children | 289 ** this address is still in the children |
274 ** lists of the original address, simply | 290 ** lists of the original address, simply |
275 ** mark them delivered | 291 ** mark them delivered |