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