Mercurial > masqmail
comparison src/accept.c @ 10:26e34ae9a3e3
changed indention and line wrapping to a more consistent style
author | meillo@marmaro.de |
---|---|
date | Mon, 27 Oct 2008 16:23:10 +0100 |
parents | 08114f7dcc23 |
children | 49dab67fe461 |
comparison
equal
deleted
inserted
replaced
9:31cc8a89cb74 | 10:26e34ae9a3e3 |
---|---|
17 */ | 17 */ |
18 | 18 |
19 #include "masqmail.h" | 19 #include "masqmail.h" |
20 #include "readsock.h" | 20 #include "readsock.h" |
21 | 21 |
22 gchar *prot_names[] = | 22 gchar *prot_names[] = { |
23 "local", | |
24 "bsmtp", | |
25 "smtp", | |
26 "esmtp", | |
27 "pop3", | |
28 "apop", | |
29 "(unknown)" /* should not happen, but better than crashing. */ | |
30 }; | |
31 | |
32 static gchar* | |
33 string_base62(gchar * res, guint value, gchar len) | |
23 { | 34 { |
24 "local", | 35 static gchar base62_chars[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; |
25 "bsmtp", | 36 gchar *p = res + len; |
26 "smtp", | 37 *p = 0; |
27 "esmtp", | 38 while (p > res) { |
28 "pop3", | 39 *(--p) = base62_chars[value % 62]; |
29 "apop", | 40 value /= 62; |
30 "(unknown)" /* should not happen, but better than crashing. */ | 41 } |
31 }; | 42 return res; |
32 | 43 } |
33 static | 44 |
34 gchar *string_base62(gchar *res, guint value, gchar len) | 45 static gint |
46 _g_list_addr_isequal(gconstpointer a, gconstpointer b) | |
35 { | 47 { |
36 static gchar base62_chars[] = | 48 address *addr1 = (address *) a; |
37 "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; | 49 address *addr2 = (address *) b; |
38 gchar *p = res + len; | 50 int ret; |
39 *p = 0; | 51 |
40 while (p > res){ | 52 if ((ret = strcasecmp(addr1->domain, addr2->domain)) == 0) |
41 *(--p) = base62_chars[value % 62]; | 53 return strcmp(addr1->local_part, addr2->local_part); |
42 value /= 62; | 54 else |
43 } | 55 return ret; |
44 return res; | |
45 } | |
46 | |
47 static gint _g_list_addr_isequal(gconstpointer a, gconstpointer b) | |
48 { | |
49 address *addr1 = (address *)a; | |
50 address *addr2 = (address *)b; | |
51 int ret; | |
52 | |
53 if((ret = strcasecmp(addr1->domain, addr2->domain)) == 0) | |
54 return strcmp(addr1->local_part, addr2->local_part); | |
55 else | |
56 return ret; | |
57 } | 56 } |
58 | 57 |
59 /* accept message from anywhere. | 58 /* accept message from anywhere. |
60 A locally originating message is indicated by msg->recieved_host == NULL | 59 A locally originating message is indicated by msg->recieved_host == NULL |
61 | 60 |
62 If the flags ACC_DEL_RCPTS is set, recipients in the msg->rcpt_list is | 61 If the flags ACC_DEL_RCPTS is set, recipients in the msg->rcpt_list is |
63 copied and items occuring in it will be removed from the newly constructed | 62 copied and items occuring in it will be removed from the newly constructed |
64 (from To/Cc/Bcc headers if ACC_RCPT_TO is set) rcpt_list. | 63 (from To/Cc/Bcc headers if ACC_RCPT_TO is set) rcpt_list. |
65 */ | 64 */ |
66 | 65 |
67 accept_error accept_message_stream(FILE *in, message *msg, guint flags) | 66 accept_error |
67 accept_message_stream(FILE * in, message * msg, guint flags) | |
68 { | 68 { |
69 gchar *line, *line1; | 69 gchar *line, *line1; |
70 int line_size = MAX_DATALINE; | 70 int line_size = MAX_DATALINE; |
71 gboolean in_headers = TRUE; | 71 gboolean in_headers = TRUE; |
72 header *hdr = NULL; | 72 header *hdr = NULL; |
73 gint line_cnt = 0, data_size = 0; | 73 gint line_cnt = 0, data_size = 0; |
74 | 74 |
75 line = g_malloc(line_size); | 75 line = g_malloc(line_size); |
76 line[0] = 0; | 76 line[0] = 0; |
77 | 77 |
78 while(TRUE){ | 78 while (TRUE) { |
79 int len = read_sockline1(in, &line, &line_size, 5*60, READSOCKL_CVT_CRLF); | 79 int len = read_sockline1(in, &line, &line_size, 5 * 60, READSOCKL_CVT_CRLF); |
80 | 80 |
81 line1 = line; | 81 line1 = line; |
82 | 82 |
83 if((line[0] == '.') && (!(flags & ACC_NODOT_TERM))){ | 83 if ((line[0] == '.') && (!(flags & ACC_NODOT_TERM))) { |
84 if(line[1] == '\n'){ | 84 if (line[1] == '\n') { |
85 g_free(line); | 85 g_free(line); |
86 break; | 86 break; |
87 } | 87 } |
88 line1++; | 88 line1++; |
89 } | 89 } |
90 | 90 |
91 if(len <= 0){ | 91 if (len <= 0) { |
92 if((len == -1) && ((flags & ACC_NODOT_TERM) || (flags & ACC_NODOT_RELAX))){ | 92 if ((len == -1) && ((flags & ACC_NODOT_TERM) || (flags & ACC_NODOT_RELAX))) { |
93 /* we got an EOF, and the last line was not terminated by a CR */ | 93 /* we got an EOF, and the last line was not terminated by a CR */ |
94 gint len1 = strlen(line1); | 94 gint len1 = strlen(line1); |
95 if(len1 > 0){ /* == 0 is 'normal' (EOF after a CR) */ | 95 if (len1 > 0) { /* == 0 is 'normal' (EOF after a CR) */ |
96 if(line1[len1-1] != '\n'){ /* some mail clients allow unterminated lines */ | 96 if (line1[len1 - 1] != '\n') { /* some mail clients allow unterminated lines */ |
97 line1[len1] = '\n'; | 97 line1[len1] = '\n'; |
98 line1[len1+1] = 0; | 98 line1[len1 + 1] = 0; |
99 msg->data_list = g_list_prepend(msg->data_list, g_strdup(line1)); | 99 msg->data_list = g_list_prepend(msg->data_list, g_strdup(line1)); |
100 data_size += strlen(line1); | 100 data_size += strlen(line1); |
101 line_cnt++; | 101 line_cnt++; |
102 } | 102 } |
103 } | 103 } |
104 break; | 104 break; |
105 }else{ | 105 } else { |
106 g_free(line); | 106 g_free(line); |
107 if(len == -1){ | 107 if (len == -1) { |
108 return AERR_EOF; | 108 return AERR_EOF; |
109 }else if(len == -2){ | 109 } else if (len == -2) { |
110 /* should not happen any more */ | 110 /* should not happen any more */ |
111 return AERR_OVERFLOW; | 111 return AERR_OVERFLOW; |
112 }else if(len == -3){ | 112 } else if (len == -3) { |
113 return AERR_TIMEOUT; | 113 return AERR_TIMEOUT; |
114 }else{ | 114 } else { |
115 /* does not happen */ | 115 /* does not happen */ |
116 DEBUG(5) debugf("read_sockline returned %d\n", len); | 116 DEBUG(5) debugf("read_sockline returned %d\n", len); |
117 return AERR_UNKNOWN; | 117 return AERR_UNKNOWN; |
118 } | 118 } |
119 } | 119 } |
120 } | 120 } else { |
121 else{ | 121 if (in_headers) { |
122 if(in_headers){ | 122 |
123 | 123 /* some pop servers send the 'From ' line, skip it: */ |
124 /* some pop servers send the 'From ' line, skip it: */ | 124 if (msg->hdr_list == NULL) |
125 if(msg->hdr_list == NULL) | 125 if (strncmp(line1, "From ", 5) == 0) |
126 if(strncmp(line1, "From ", 5) == 0) | 126 continue; |
127 continue; | 127 |
128 | 128 if (line1[0] == ' ' || line1[0] == '\t') { |
129 if(line1[0] == ' ' || line1[0] == '\t'){ | 129 /* continuation of 'folded' header: */ |
130 /* continuation of 'folded' header: */ | 130 if (hdr) { |
131 if(hdr){ | 131 hdr->header = |
132 hdr->header = g_strconcat(hdr->header, line1, NULL); | 132 g_strconcat(hdr->header, line1, NULL); |
133 } | 133 } |
134 | 134 |
135 }else if(line1[0] == '\n'){ | 135 } else if (line1[0] == '\n') { |
136 /* an empty line marks end of headers */ | 136 /* an empty line marks end of headers */ |
137 in_headers = FALSE; | 137 in_headers = FALSE; |
138 }else{ | 138 } else { |
139 /* in all other cases we expect another header */ | 139 /* in all other cases we expect another header */ |
140 if((hdr = get_header(line1))) | 140 if ((hdr = get_header(line1))) |
141 msg->hdr_list = g_list_append(msg->hdr_list, hdr); | 141 msg->hdr_list = g_list_append(msg->hdr_list, hdr); |
142 else{ | 142 else { |
143 /* if get_header() returns NULL, no header was recognized, | 143 /* if get_header() returns NULL, no header was recognized, |
144 so this seems to be the first data line of a broken mailer | 144 so this seems to be the first data line of a broken mailer |
145 which does not send an empty line after the headers */ | 145 which does not send an empty line after the headers */ |
146 in_headers = FALSE; | 146 in_headers = FALSE; |
147 msg->data_list = g_list_prepend(msg->data_list, g_strdup(line1)); | 147 msg->data_list = g_list_prepend(msg->data_list, g_strdup(line1)); |
148 } | 148 } |
149 } | 149 } |
150 }else{ | 150 } else { |
151 msg->data_list = g_list_prepend(msg->data_list, g_strdup(line1)); | 151 msg->data_list = g_list_prepend(msg->data_list, g_strdup(line1)); |
152 data_size += strlen(line1); | 152 data_size += strlen(line1); |
153 line_cnt++; | 153 line_cnt++; |
154 } | 154 } |
155 } | 155 } |
156 } | 156 } |
157 | 157 |
158 if(msg->data_list != NULL) | 158 if (msg->data_list != NULL) |
159 msg->data_list = g_list_reverse(msg->data_list); | 159 msg->data_list = g_list_reverse(msg->data_list); |
160 else | 160 else |
161 /* make sure data list is not NULL: */ | 161 /* make sure data list is not NULL: */ |
162 msg->data_list = g_list_append(NULL, g_strdup("")); | 162 msg->data_list = g_list_append(NULL, g_strdup("")); |
163 | 163 |
164 DEBUG(4) debugf("received %d lines of data (%d bytes)\n", | 164 DEBUG(4) debugf("received %d lines of data (%d bytes)\n", line_cnt, data_size); |
165 line_cnt, data_size); | 165 /* we get here after we succesfully received the mail data */ |
166 /* we get here after we succesfully | 166 |
167 received the mail data */ | 167 msg->data_size = data_size; |
168 | 168 msg->received_time = time(NULL); |
169 msg->data_size = data_size; | 169 |
170 msg->received_time = time(NULL); | 170 return AERR_OK; |
171 | |
172 return AERR_OK; | |
173 } | 171 } |
174 | 172 |
175 accept_error accept_message_prepare(message *msg, guint flags) | 173 accept_error |
174 accept_message_prepare(message * msg, guint flags) | |
176 { | 175 { |
177 struct passwd *passwd = NULL; | 176 struct passwd *passwd = NULL; |
178 GList *non_rcpt_list = NULL; | 177 GList *non_rcpt_list = NULL; |
179 time_t rec_time = time(NULL); | 178 time_t rec_time = time(NULL); |
180 | 179 |
181 DEBUG(5) debugf("accept_message_prepare()\n"); | 180 DEBUG(5) debugf("accept_message_prepare()\n"); |
182 | 181 |
183 /* create unique message id */ | 182 /* create unique message id */ |
184 msg->uid = g_malloc(14); | 183 msg->uid = g_malloc(14); |
185 | 184 |
186 string_base62(msg->uid, rec_time, 6); | 185 string_base62(msg->uid, rec_time, 6); |
187 msg->uid[6] = '-'; | 186 msg->uid[6] = '-'; |
188 string_base62(&(msg->uid[7]), getpid(), 3); | 187 string_base62(&(msg->uid[7]), getpid(), 3); |
189 msg->uid[10] = '-'; | 188 msg->uid[10] = '-'; |
190 string_base62(&(msg->uid[11]), msg->transfer_id, 2); | 189 string_base62(&(msg->uid[11]), msg->transfer_id, 2); |
191 msg->uid[13] = 0; | 190 msg->uid[13] = 0; |
192 | 191 |
193 /* if local, get password entry */ | 192 /* if local, get password entry */ |
194 if(msg->received_host == NULL){ | 193 if (msg->received_host == NULL) { |
195 passwd = g_memdup(getpwuid(geteuid()), sizeof(struct passwd)); | 194 passwd = g_memdup(getpwuid(geteuid()), sizeof(struct passwd)); |
196 msg->ident = g_strdup(passwd->pw_name); | 195 msg->ident = g_strdup(passwd->pw_name); |
197 } | 196 } |
198 | 197 |
199 /* set return path if local */ | 198 /* set return path if local */ |
200 if(msg->return_path == NULL){ | 199 if (msg->return_path == NULL) { |
201 | 200 |
202 if(msg->received_host == NULL){ | 201 if (msg->received_host == NULL) { |
203 gchar *path = g_strdup_printf("<%s@%s>", | 202 gchar *path = g_strdup_printf("<%s@%s>", passwd->pw_name, conf.host_name); |
204 passwd->pw_name, conf.host_name); | 203 DEBUG(3) debugf("setting return_path for local accept: %s\n", path); |
205 DEBUG(3) debugf("setting return_path for local accept: %s\n", path); | 204 msg->return_path = create_address(path, TRUE); |
206 msg->return_path = create_address(path, TRUE); | 205 g_free(path); |
207 g_free(path); | 206 } |
208 } | 207 } |
209 } | 208 |
210 | 209 /* -t option */ |
211 /* -t option */ | 210 if (flags & ACC_DEL_RCPTS) { |
212 if(flags & ACC_DEL_RCPTS){ | 211 non_rcpt_list = msg->rcpt_list; |
213 non_rcpt_list = msg->rcpt_list; | 212 msg->rcpt_list = NULL; |
214 msg->rcpt_list = NULL; | 213 } |
215 } | 214 |
216 | 215 /* scan headers */ |
217 /* scan headers */ | 216 { |
218 { | 217 gboolean has_id = FALSE; |
219 gboolean has_id = FALSE; | 218 gboolean has_date = FALSE; |
220 gboolean has_date = FALSE; | 219 gboolean has_sender = FALSE; |
221 gboolean has_sender = FALSE; | 220 gboolean has_from = FALSE; |
222 gboolean has_from = FALSE; | 221 gboolean has_rcpt = FALSE; |
223 gboolean has_rcpt = FALSE; | 222 gboolean has_to_or_cc = FALSE; |
224 gboolean has_to_or_cc = FALSE; | 223 GList *hdr_node, *hdr_node_next; |
225 GList *hdr_node, *hdr_node_next; | 224 header *hdr; |
226 header *hdr; | 225 |
227 | 226 for (hdr_node = g_list_first(msg->hdr_list); |
228 for(hdr_node = g_list_first(msg->hdr_list); | 227 hdr_node != NULL; hdr_node = hdr_node_next) { |
229 hdr_node != NULL; | 228 hdr_node_next = g_list_next(hdr_node); |
230 hdr_node = hdr_node_next){ | 229 hdr = ((header *) (hdr_node->data)); |
231 hdr_node_next = g_list_next(hdr_node); | 230 DEBUG(5) debugf("scanning headers: %s", hdr->header); |
232 hdr = ((header *)(hdr_node->data)); | 231 switch (hdr->id) { |
233 DEBUG(5) debugf("scanning headers: %s", hdr->header); | 232 case HEAD_MESSAGE_ID: |
234 switch(hdr->id){ | 233 has_id = TRUE; |
235 case HEAD_MESSAGE_ID: | 234 break; |
236 has_id = TRUE; break; | 235 case HEAD_DATE: |
237 case HEAD_DATE: | 236 has_date = TRUE; |
238 has_date = TRUE; break; | 237 break; |
239 case HEAD_FROM: | 238 case HEAD_FROM: |
240 has_from = TRUE; | 239 has_from = TRUE; |
241 break; | 240 break; |
242 case HEAD_SENDER: | 241 case HEAD_SENDER: |
243 has_sender = TRUE; | 242 has_sender = TRUE; |
244 break; | 243 break; |
245 case HEAD_TO: | 244 case HEAD_TO: |
246 case HEAD_CC: | 245 case HEAD_CC: |
247 case HEAD_BCC: | 246 case HEAD_BCC: |
248 has_rcpt = TRUE; | 247 has_rcpt = TRUE; |
249 if(flags & ACC_RCPT_FROM_HEAD){ | 248 if (flags & ACC_RCPT_FROM_HEAD) { |
250 DEBUG(5) debugf("hdr->value = %s\n", hdr->value); | 249 DEBUG(5) debugf("hdr->value = %s\n", hdr->value); |
251 if(hdr->value){ | 250 if (hdr->value) { |
252 msg->rcpt_list = | 251 msg->rcpt_list = addr_list_append_rfc822(msg->rcpt_list, hdr->value, conf.host_name); |
253 addr_list_append_rfc822(msg->rcpt_list, hdr->value, conf.host_name); | 252 } |
254 } | 253 } |
255 } | 254 if ((flags & ACC_DEL_BCC) && (hdr->id == HEAD_BCC)) { |
256 if((flags & ACC_DEL_BCC) && (hdr->id == HEAD_BCC)){ | 255 DEBUG(3) debugf("removing 'Bcc' header\n"); |
257 DEBUG(3) debugf("removing 'Bcc' header\n"); | 256 msg->hdr_list = g_list_remove_link(msg->hdr_list, hdr_node); |
258 msg->hdr_list = g_list_remove_link(msg->hdr_list, hdr_node); | 257 g_list_free_1(hdr_node); |
259 g_list_free_1(hdr_node); | 258 destroy_header(hdr); |
260 destroy_header(hdr); | 259 } else |
261 }else | 260 has_to_or_cc = TRUE; |
262 has_to_or_cc = TRUE; | 261 break; |
263 break; | 262 case HEAD_ENVELOPE_TO: |
264 case HEAD_ENVELOPE_TO: | 263 if (flags & ACC_SAVE_ENVELOPE_TO) { |
265 if(flags & ACC_SAVE_ENVELOPE_TO){ | 264 DEBUG(3) debugf("creating 'X-Orig-Envelope-To' header\n"); |
266 DEBUG(3) debugf("creating 'X-Orig-Envelope-To' header\n"); | 265 msg->hdr_list = g_list_prepend(msg->hdr_list, create_header(HEAD_UNKNOWN, "X-Orig-Envelope-to: %s", hdr->value)); |
267 msg->hdr_list = | 266 } |
268 g_list_prepend(msg->hdr_list, | 267 DEBUG(3) debugf("removing 'Envelope-To' header\n"); |
269 create_header(HEAD_UNKNOWN, | 268 msg->hdr_list = g_list_remove_link(msg->hdr_list, hdr_node); |
270 "X-Orig-Envelope-to: %s", hdr->value)); | 269 g_list_free_1(hdr_node); |
271 } | 270 destroy_header(hdr); |
272 DEBUG(3) debugf("removing 'Envelope-To' header\n"); | 271 break; |
273 msg->hdr_list = g_list_remove_link(msg->hdr_list, hdr_node); | 272 case HEAD_RETURN_PATH: |
274 g_list_free_1(hdr_node); | 273 if (flags & ACC_MAIL_FROM_HEAD) { |
275 destroy_header(hdr); | 274 /* usually POP3 accept */ |
276 break; | 275 msg->return_path = create_address_qualified(hdr->value, TRUE, msg->received_host); |
277 case HEAD_RETURN_PATH: | 276 DEBUG(3) debugf("setting return_path to %s\n", addr_string(msg->return_path)); |
278 if(flags & ACC_MAIL_FROM_HEAD){ | 277 } |
279 /* usually POP3 accept */ | 278 DEBUG(3) debugf("removing 'Return-Path' header\n"); |
280 msg->return_path = create_address_qualified(hdr->value, TRUE, msg->received_host); | 279 msg->hdr_list = g_list_remove_link(msg->hdr_list, hdr_node); |
281 DEBUG(3) debugf("setting return_path to %s\n", | 280 g_list_free_1(hdr_node); |
282 addr_string(msg->return_path)); | 281 destroy_header(hdr); |
283 } | 282 break; |
284 DEBUG(3) debugf("removing 'Return-Path' header\n"); | 283 default: |
285 msg->hdr_list = g_list_remove_link(msg->hdr_list, hdr_node); | 284 break; /* make compiler happy */ |
286 g_list_free_1(hdr_node); | 285 } |
287 destroy_header(hdr); | 286 } |
288 break; | 287 |
289 default: | 288 if (msg->return_path == NULL) { |
290 break; /* make compiler happy */ | 289 /* this can happen for pop3 accept only and if no Return-path: header was given */ |
291 } | 290 GList *hdr_list; |
292 } | 291 header *hdr; |
293 | 292 |
294 if(msg->return_path == NULL){ | 293 DEBUG(3) debugf("return_path == NULL\n"); |
295 /* this can happen for pop3 accept only | 294 |
296 and if no Return-path: header was given */ | 295 hdr_list = find_header(msg->hdr_list, HEAD_SENDER, NULL); |
297 GList *hdr_list; | 296 if (!hdr_list) |
298 header *hdr; | 297 hdr_list = find_header(msg->hdr_list, HEAD_FROM, NULL); |
299 | 298 if (hdr_list) { |
300 DEBUG(3) debugf("return_path == NULL\n"); | 299 gchar *addr; |
301 | 300 hdr = (header *) (g_list_first(hdr_list)->data); |
302 hdr_list = find_header(msg->hdr_list, HEAD_SENDER, NULL); | 301 |
303 if(!hdr_list) hdr_list = find_header(msg->hdr_list, HEAD_FROM, NULL); | 302 DEBUG(5) debugf("hdr->value = '%s'\n", hdr->value); |
304 if(hdr_list){ | 303 |
305 gchar *addr; | 304 addr = g_strdup(hdr->value); |
306 hdr = (header *)(g_list_first(hdr_list)->data); | 305 g_strchomp(addr); |
307 | 306 |
308 DEBUG(5) debugf("hdr->value = '%s'\n", hdr->value); | 307 if ((msg->return_path = create_address_qualified(addr, FALSE, msg->received_host)) != NULL) { |
309 | 308 DEBUG(3) debugf("setting return_path to %s\n", addr_string(msg->return_path)); |
310 addr = g_strdup(hdr->value); | 309 msg->hdr_list = g_list_append(msg->hdr_list, create_header(HEAD_UNKNOWN, "X-Warning: return path set from %s address\n", hdr->id == HEAD_SENDER ? "Sender:" : "From:")); |
311 g_strchomp(addr); | 310 } |
312 | 311 g_free(addr); |
313 if((msg->return_path = | 312 } |
314 create_address_qualified(addr, FALSE, msg->received_host)) | 313 if (msg->return_path == NULL) { /* no Sender: or From: or create_address_qualified failed */ |
315 != NULL){ | 314 msg->return_path = create_address_qualified("postmaster", TRUE, conf.host_name); |
316 DEBUG(3) debugf("setting return_path to %s\n", addr_string(msg->return_path)); | 315 DEBUG(3) debugf("setting return_path to %s\n", addr_string(msg->return_path)); |
317 msg->hdr_list = | 316 msg->hdr_list = g_list_append(msg->hdr_list, create_header(HEAD_UNKNOWN, "X-Warning: real return path is unkown\n")); |
318 g_list_append(msg->hdr_list, | 317 } |
319 create_header(HEAD_UNKNOWN, | 318 } |
320 "X-Warning: return path set from %s address\n", | 319 |
321 hdr->id == HEAD_SENDER ? "Sender:" : "From:")); | 320 if (flags & ACC_DEL_RCPTS) { |
322 } | 321 GList *rcpt_node; |
323 g_free(addr); | 322 foreach(non_rcpt_list, rcpt_node) { |
324 } | 323 address *rcpt = (address *) (rcpt_node->data); |
325 if(msg->return_path == NULL){ /* no Sender: or From: or create_address_qualified failed */ | 324 GList *node; |
326 msg->return_path = create_address_qualified("postmaster", TRUE, conf.host_name); | 325 if ((node = g_list_find_custom(msg->rcpt_list, rcpt, _g_list_addr_isequal))) { |
327 DEBUG(3) debugf("setting return_path to %s\n", addr_string(msg->return_path)); | 326 DEBUG(3) debugf("removing rcpt address %s\n", addr_string(node->data)); |
328 msg->hdr_list = | 327 msg->rcpt_list = g_list_remove_link(msg->rcpt_list, node); |
329 g_list_append(msg->hdr_list, | 328 destroy_address((address *) (node->data)); |
330 create_header(HEAD_UNKNOWN, | 329 g_list_free_1(node); |
331 "X-Warning: real return path is unkown\n")); | 330 } |
332 } | 331 } |
333 } | 332 } |
334 | 333 |
335 if(flags & ACC_DEL_RCPTS){ | 334 /* here we should have our recipients, fail if not: */ |
336 GList *rcpt_node; | 335 if (msg->rcpt_list == NULL) { |
337 foreach(non_rcpt_list, rcpt_node){ | 336 logwrite(LOG_WARNING, "no recipients found in message\n"); |
338 address *rcpt = (address *)(rcpt_node->data); | 337 return AERR_NORCPT; |
339 GList *node; | 338 } |
340 if((node = g_list_find_custom(msg->rcpt_list, rcpt, | 339 |
341 _g_list_addr_isequal))){ | 340 if (!(has_sender || has_from)) { |
342 DEBUG(3) debugf("removing rcpt address %s\n", addr_string(node->data)); | 341 DEBUG(3) debugf("adding 'From' header\n"); |
343 | 342 msg->hdr_list = g_list_append(msg->hdr_list, |
344 msg->rcpt_list = g_list_remove_link(msg->rcpt_list, node); | 343 msg->full_sender_name |
345 destroy_address((address *)(node->data)); | 344 ? |
346 g_list_free_1(node); | 345 create_header(HEAD_FROM, |
347 } | 346 "From: \"%s\" <%s@%s>\n", |
348 } | 347 msg->full_sender_name, |
349 } | 348 msg->return_path->local_part, |
350 | 349 msg->return_path-> |
351 /* here we should have our recipients, fail if not: */ | 350 domain) |
352 if(msg->rcpt_list == NULL){ | 351 : |
353 logwrite(LOG_WARNING, "no recipients found in message\n"); | 352 create_header(HEAD_FROM, "From: <%s@%s>\n", |
354 return AERR_NORCPT; | 353 msg->return_path->local_part, |
355 } | 354 msg->return_path->domain) |
356 | 355 ); |
357 if(!(has_sender || has_from)){ | 356 } |
358 DEBUG(3) debugf("adding 'From' header\n"); | 357 if ((flags & ACC_HEAD_FROM_RCPT) && !has_rcpt) { |
359 msg->hdr_list = | 358 GList *node; |
360 g_list_append(msg->hdr_list, | 359 DEBUG(3) debugf("adding 'To' header(s)\n"); |
361 msg->full_sender_name ? | 360 for (node = g_list_first(msg->rcpt_list); node; node = g_list_next(node)) { |
362 create_header(HEAD_FROM, "From: \"%s\" <%s@%s>\n", | 361 msg->hdr_list = g_list_append(msg->hdr_list, create_header(HEAD_TO, "To: %s\n", addr_string(msg-> return_path))); |
363 msg->full_sender_name, | 362 } |
364 msg->return_path->local_part, | 363 } |
365 msg->return_path->domain) : | 364 if ((flags & ACC_DEL_BCC) && !has_to_or_cc) { |
366 create_header(HEAD_FROM, "From: <%s@%s>\n", | 365 /* Bcc headers have been removed, and there are no remaining rcpt headers */ |
367 msg->return_path->local_part, | 366 DEBUG(3) debugf("adding empty 'Bcc:' header\n"); |
368 msg->return_path->domain) | 367 msg->hdr_list = g_list_append(msg->hdr_list, create_header(HEAD_BCC, "Bcc:\n")); |
369 ); | 368 } |
370 } | 369 if (!has_date) { |
371 if((flags & ACC_HEAD_FROM_RCPT) && !has_rcpt){ | 370 DEBUG(3) debugf("adding 'Date:' header\n"); |
372 GList *node; | 371 msg->hdr_list = g_list_append(msg->hdr_list, create_header(HEAD_DATE, "Date: %s\n", rec_timestamp())); |
373 DEBUG(3) debugf("adding 'To' header(s)\n"); | 372 } |
374 for(node = g_list_first(msg->rcpt_list); | 373 if (!has_id) { |
375 node; | 374 DEBUG(3) debugf("adding 'Message-ID:' header\n"); |
376 node = g_list_next(node)){ | 375 msg->hdr_list = g_list_append(msg->hdr_list, create_header(HEAD_MESSAGE_ID, "Message-ID: <%s@%s>\n", msg->uid, conf.host_name)); |
377 msg->hdr_list = | 376 } |
378 g_list_append(msg->hdr_list, | 377 } |
379 create_header(HEAD_TO, "To: %s\n", addr_string(msg->return_path))); | 378 |
380 } | 379 /* Received header: */ |
381 } | 380 /* At this point because we have to know the rcpts for the 'for' part */ |
382 if((flags & ACC_DEL_BCC) && !has_to_or_cc){ | 381 if (!(flags & ACC_NO_RECVD_HDR)) { |
383 /* Bcc headers have been removed, and there are no remaining rcpt headers */ | 382 gchar *for_string = NULL; |
384 DEBUG(3) debugf("adding empty 'Bcc:' header\n"); | 383 header *hdr = NULL; |
385 msg->hdr_list = | 384 |
386 g_list_append(msg->hdr_list, create_header(HEAD_BCC, "Bcc:\n")); | 385 DEBUG(3) debugf("adding 'Received:' header\n"); |
387 } | 386 |
388 if(!has_date){ | 387 if (g_list_length(msg->rcpt_list) == 1) { |
389 DEBUG(3) debugf("adding 'Date:' header\n"); | 388 address *addr = (address *) (g_list_first(msg->rcpt_list)->data); |
390 msg->hdr_list = | 389 for_string = g_strdup_printf(" for %s", addr_string(addr)); |
391 g_list_append(msg->hdr_list, | 390 } |
392 create_header(HEAD_DATE, "Date: %s\n", rec_timestamp())); | 391 |
393 } | 392 if (msg->received_host == NULL) { |
394 if(!has_id){ | 393 hdr = create_header(HEAD_RECEIVED, |
395 DEBUG(3) debugf("adding 'Message-ID:' header\n"); | 394 "Received: from %s by %s" |
396 msg->hdr_list = | 395 " with %s (%s %s) id %s%s;" |
397 g_list_append(msg->hdr_list, | 396 " %s\n", |
398 create_header(HEAD_MESSAGE_ID, | 397 passwd->pw_name, conf.host_name, |
399 "Message-ID: <%s@%s>\n", | 398 prot_names[msg->received_prot], |
400 msg->uid, conf.host_name)); | 399 PACKAGE, VERSION, |
401 } | 400 msg->uid, for_string ? for_string : "", |
402 } | 401 rec_timestamp()); |
403 | 402 } else { |
404 /* Received header: */ | |
405 /* At this point because we have to know the rcpts for the 'for' part */ | |
406 if(!(flags & ACC_NO_RECVD_HDR)){ | |
407 gchar *for_string = NULL; | |
408 header *hdr = NULL; | |
409 | |
410 DEBUG(3) debugf("adding 'Received:' header\n"); | |
411 | |
412 if(g_list_length(msg->rcpt_list) == 1){ | |
413 address *addr = (address *)(g_list_first(msg->rcpt_list)->data); | |
414 for_string = g_strdup_printf(" for %s", addr_string(addr)); | |
415 } | |
416 | |
417 if(msg->received_host == NULL){ | |
418 hdr = create_header(HEAD_RECEIVED, | |
419 "Received: from %s by %s" | |
420 " with %s (%s %s) id %s%s;" | |
421 " %s\n", | |
422 passwd->pw_name, conf.host_name, | |
423 prot_names[msg->received_prot], | |
424 PACKAGE, VERSION, | |
425 msg->uid, for_string ? for_string : "", | |
426 rec_timestamp()); | |
427 }else{ | |
428 #ifdef ENABLE_IDENT | 403 #ifdef ENABLE_IDENT |
429 DEBUG(5) debugf("adding 'Received:' header (5)\n"); | 404 DEBUG(5) debugf("adding 'Received:' header (5)\n"); |
430 hdr = create_header(HEAD_RECEIVED, | 405 hdr = create_header(HEAD_RECEIVED, |
431 "Received: from %s (ident=%s) by %s" | 406 "Received: from %s (ident=%s) by %s" |
432 " with %s (%s %s) id %s%s;" | 407 " with %s (%s %s) id %s%s;" |
433 " %s\n", | 408 " %s\n", |
434 msg->received_host, | 409 msg->received_host, |
435 msg->ident ? msg->ident : "unknown", | 410 msg->ident ? msg->ident : "unknown", |
436 conf.host_name, | 411 conf.host_name, |
437 prot_names[msg->received_prot], | 412 prot_names[msg->received_prot], |
438 PACKAGE, VERSION, | 413 PACKAGE, VERSION, |
439 msg->uid, for_string ? for_string : "", | 414 msg->uid, for_string ? for_string : "", |
440 rec_timestamp()); | 415 rec_timestamp()); |
441 #else | 416 #else |
442 hdr = create_header(HEAD_RECEIVED, | 417 hdr = create_header(HEAD_RECEIVED, |
443 "Received: from %s by %s" | 418 "Received: from %s by %s" |
444 " with %s (%s %s) id %s%s;" | 419 " with %s (%s %s) id %s%s;" |
445 " %s\n", | 420 " %s\n", |
446 msg->received_host, | 421 msg->received_host, |
447 conf.host_name, | 422 conf.host_name, |
448 prot_names[msg->received_prot], | 423 prot_names[msg->received_prot], |
449 PACKAGE, VERSION, | 424 PACKAGE, VERSION, |
450 msg->uid, for_string ? for_string : "", | 425 msg->uid, for_string ? for_string : "", |
451 rec_timestamp()); | 426 rec_timestamp()); |
452 #endif | 427 #endif |
453 } | 428 } |
454 header_fold(hdr); | 429 header_fold(hdr); |
455 msg->hdr_list = g_list_prepend(msg->hdr_list, hdr); | 430 msg->hdr_list = g_list_prepend(msg->hdr_list, hdr); |
456 | 431 |
457 if(for_string) g_free(for_string); | 432 if (for_string) |
458 } | 433 g_free(for_string); |
459 | 434 } |
460 /* write message to spool: */ | 435 |
461 /* accept is no longer responsible for this | 436 /* write message to spool: */ |
462 if(!spool_write(msg, TRUE)) | 437 /* accept is no longer responsible for this |
463 return AERR_NOSPOOL; | 438 if(!spool_write(msg, TRUE)) |
464 */ | 439 return AERR_NOSPOOL; |
465 return AERR_OK; | 440 */ |
441 return AERR_OK; | |
466 } | 442 } |
467 | 443 |
468 accept_error accept_message(FILE *in, message *msg, guint flags) | 444 accept_error |
445 accept_message(FILE * in, message * msg, guint flags) | |
469 { | 446 { |
470 accept_error err; | 447 accept_error err; |
471 | 448 |
472 err = accept_message_stream(in, msg, flags); | 449 err = accept_message_stream(in, msg, flags); |
473 if(err == AERR_OK) | 450 if (err == AERR_OK) |
474 err = accept_message_prepare(msg, flags); | 451 err = accept_message_prepare(msg, flags); |
475 | 452 |
476 return err; | 453 return err; |
477 } | 454 } |
478 |