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