masqmail
diff src/accept.c @ 388:aa40710f09fe
Refactoring and code layouting.
author | markus schnalke <meillo@marmaro.de> |
---|---|
date | Sat, 18 Feb 2012 13:37:40 +0100 |
parents | 5781ba87df95 |
children | 9b93c0a3bd8c |
line diff
1.1 --- a/src/accept.c Sat Feb 18 12:35:12 2012 +0100 1.2 +++ b/src/accept.c Sat Feb 18 13:37:40 2012 +0100 1.3 @@ -32,7 +32,8 @@ 1.4 static gchar* 1.5 string_base62(gchar *res, guint value, gchar len) 1.6 { 1.7 - static gchar base62_chars[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; 1.8 + static gchar base62_chars[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" 1.9 + "abcdefghijklmnopqrstuvwxyz"; 1.10 gchar *p = res + len; 1.11 *p = '\0'; 1.12 while (p > res) { 1.13 @@ -49,7 +50,6 @@ 1.14 ** The -t option: With the ACC_RCPT_FROM_HEAD flag the addrs found found 1.15 ** in To/Cc/Bcc headers are added to the recipient list. 1.16 */ 1.17 - 1.18 accept_error 1.19 accept_message_stream(FILE *in, message *msg, guint flags) 1.20 { 1.21 @@ -60,14 +60,14 @@ 1.22 gint line_cnt = 0, data_size = 0; 1.23 1.24 line = g_malloc(line_size); 1.25 - line[0] = '\0'; 1.26 + *line = '\0'; 1.27 1.28 - while (TRUE) { 1.29 - int len = read_sockline1(in, &line, &line_size, 5 * 60, READSOCKL_CVT_CRLF); 1.30 - 1.31 + while (1) { 1.32 + int len = read_sockline1(in, &line, &line_size, 5 * 60, 1.33 + READSOCKL_CVT_CRLF); 1.34 line1 = line; 1.35 1.36 - if ((line[0] == '.') && (!(flags & ACC_DOT_IGNORE))) { 1.37 + if ((*line == '.') && (!(flags & ACC_DOT_IGNORE))) { 1.38 if (line[1] == '\n') { 1.39 g_free(line); 1.40 break; 1.41 @@ -75,17 +75,17 @@ 1.42 line1++; 1.43 } 1.44 1.45 - if ((len == -1) && (flags & (ACC_DOT_IGNORE | ACC_NODOT_RELAX))) { 1.46 - /* we got an EOF, and the last line was not terminated by a CR */ 1.47 + if (len==-1 && (flags & (ACC_DOT_IGNORE | ACC_NODOT_RELAX))) { 1.48 + /* at EOF but last line was not terminated by CR */ 1.49 + /* some MUAs allow unterminated lines */ 1.50 gint len1 = strlen(line1); 1.51 - if (len1 > 0) { /* == 0 is 'normal' (EOF after a CR) */ 1.52 - if (line1[len1 - 1] != '\n') { /* some mail clients allow unterminated lines */ 1.53 - line1[len1] = '\n'; 1.54 - line1[len1 + 1] = '\0'; 1.55 - msg->data_list = g_list_prepend(msg->data_list, g_strdup(line1)); 1.56 - data_size += strlen(line1); 1.57 - line_cnt++; 1.58 - } 1.59 + if (len1 > 0 && line1[len1-1] != '\n') { 1.60 + line1[len1] = '\n'; 1.61 + line1[len1+1] = '\0'; 1.62 + msg->data_list = g_list_prepend(msg->data_list, 1.63 + g_strdup(line1)); 1.64 + data_size += strlen(line1); 1.65 + line_cnt++; 1.66 } 1.67 break; 1.68 1.69 @@ -111,45 +111,44 @@ 1.70 } 1.71 1.72 if (in_headers) { 1.73 - 1.74 /* some pop servers send the 'From ' line, skip it: */ 1.75 - if (!msg->hdr_list && strncmp(line1, "From ", 5) == 0) { 1.76 + if (!msg->hdr_list && strncmp(line1, "From ", 5)==0) { 1.77 continue; 1.78 } 1.79 1.80 - if (line1[0] == ' ' || line1[0] == '\t') { 1.81 + if (*line1 == ' ' || *line1 == '\t') { 1.82 /* continuation of 'folded' header: */ 1.83 if (hdr) { 1.84 char *cp; 1.85 - cp = g_strconcat(hdr->header, line1, NULL); 1.86 - hdr->value = cp + (hdr->value - hdr->header); 1.87 + cp = g_strconcat(hdr->header, line1, 1.88 + NULL); 1.89 + hdr->value = cp + (hdr->value - 1.90 + hdr->header); 1.91 free(hdr->header); 1.92 hdr->header = cp; 1.93 } 1.94 - 1.95 - } else if (line1[0] == '\n') { 1.96 + } else if (*line1 == '\n') { 1.97 /* an empty line marks end of headers */ 1.98 in_headers = FALSE; 1.99 + 1.100 + } else if ((hdr = get_header(line1))) { 1.101 + /* another header */ 1.102 + msg->hdr_list = g_list_append(msg->hdr_list, hdr); 1.103 } else { 1.104 - /* in all other cases we expect another header */ 1.105 - if ((hdr = get_header(line1))) { 1.106 - msg->hdr_list = g_list_append(msg->hdr_list, hdr); 1.107 - } else { 1.108 - /* 1.109 - ** if get_header() returns NULL, 1.110 - ** no header was recognized, 1.111 - ** so this seems to be the first 1.112 - ** data line of a broken mailer 1.113 - ** which does not send an empty 1.114 - ** line after the headers 1.115 - */ 1.116 - in_headers = FALSE; 1.117 - msg->data_list = g_list_prepend(msg->data_list, g_strdup(line1)); 1.118 - } 1.119 + /* 1.120 + ** Should be another header but none was 1.121 + ** recognized, so this seems to be the first 1.122 + ** data line of a broken mailer which does 1.123 + ** not add an empty line after the headers. 1.124 + */ 1.125 + in_headers = FALSE; 1.126 + msg->data_list = g_list_prepend(msg->data_list, 1.127 + g_strdup(line1)); 1.128 } 1.129 } else { 1.130 /* message body */ 1.131 - msg->data_list = g_list_prepend(msg->data_list, g_strdup(line1)); 1.132 + msg->data_list = g_list_prepend(msg->data_list, 1.133 + g_strdup(line1)); 1.134 data_size += strlen(line1); 1.135 line_cnt++; 1.136 } 1.137 @@ -160,18 +159,17 @@ 1.138 data_size, conf.max_msg_size); 1.139 return AERR_SIZE; 1.140 } 1.141 - 1.142 } 1.143 - 1.144 - DEBUG(4) debugf("received %d lines of data (%d bytes)\n", line_cnt, data_size); 1.145 + DEBUG(4) debugf("received %d lines of data (%d bytes)\n", 1.146 + line_cnt, data_size); 1.147 1.148 if (!msg->data_list) { 1.149 - /* make sure data list is not NULL: */ 1.150 + /* make sure data list is not NULL */ 1.151 msg->data_list = g_list_append(NULL, g_strdup("")); 1.152 } 1.153 msg->data_list = g_list_reverse(msg->data_list); 1.154 1.155 - /* we get here after we succesfully received the mail data */ 1.156 + /* we have succesfully received the mail data */ 1.157 1.158 msg->data_size = data_size; 1.159 msg->received_time = time(NULL); 1.160 @@ -179,17 +177,239 @@ 1.161 return AERR_OK; 1.162 } 1.163 1.164 +static void 1.165 +ensure_return_path(message *msg) 1.166 +{ 1.167 + GList *hdr_list; 1.168 + header *hdr; 1.169 + gchar *addr; 1.170 + 1.171 + if (msg->return_path) { 1.172 + return; 1.173 + } 1.174 + 1.175 + DEBUG(3) debugf("return_path == NULL\n"); 1.176 + 1.177 + hdr_list = find_header(msg->hdr_list, HEAD_SENDER, NULL); 1.178 + if (!hdr_list) { 1.179 + hdr_list = find_header(msg->hdr_list, HEAD_FROM, NULL); 1.180 + } 1.181 + if (hdr_list) { 1.182 + hdr = (header *) (g_list_first(hdr_list)->data); 1.183 + 1.184 + DEBUG(5) debugf("hdr->value = '%s'\n", hdr->value); 1.185 + 1.186 + addr = g_strdup(hdr->value); 1.187 + g_strchomp(addr); 1.188 + msg->return_path = create_address_qualified(addr, 1.189 + FALSE, msg->received_host); 1.190 + if (msg->return_path) { 1.191 + DEBUG(3) debugf("setting return_path to %s\n", 1.192 + addr_string(msg->return_path)); 1.193 + msg->hdr_list = g_list_append(msg->hdr_list, 1.194 + create_header(HEAD_UNKNOWN, 1.195 + "X-Warning: return path set from %s " 1.196 + "address\n", 1.197 + (hdr->id == HEAD_SENDER) ? 1.198 + "Sender:" : "From:")); 1.199 + } 1.200 + g_free(addr); 1.201 + } 1.202 + if (!msg->return_path) { 1.203 + /* no Sender: or From: or create_address_qualified failed */ 1.204 + msg->return_path = create_address_qualified("postmaster", 1.205 + TRUE, conf.host_name); 1.206 + DEBUG(3) debugf("setting return_path to %s\n", 1.207 + addr_string(msg->return_path)); 1.208 + msg->hdr_list = g_list_append(msg->hdr_list, 1.209 + create_header(HEAD_UNKNOWN, 1.210 + "X-Warning: real return path is unknown\n")); 1.211 + } 1.212 +} 1.213 + 1.214 +static accept_error 1.215 +scan_headers(message *msg, guint flags) 1.216 +{ 1.217 + gboolean has_id = FALSE; 1.218 + gboolean has_date = FALSE; 1.219 + gboolean has_sender = FALSE; 1.220 + gboolean has_from = FALSE; 1.221 + gboolean has_to_or_cc = FALSE; 1.222 + GList *hdr_node, *hdr_node_next; 1.223 + header *hdr; 1.224 + 1.225 + for (hdr_node = g_list_first(msg->hdr_list); hdr_node; 1.226 + hdr_node = hdr_node_next) { 1.227 + hdr_node_next = g_list_next(hdr_node); 1.228 + hdr = ((header *) (hdr_node->data)); 1.229 + DEBUG(5) debugf("scanning headers: %s", hdr->header); 1.230 + switch (hdr->id) { 1.231 + case HEAD_MESSAGE_ID: 1.232 + has_id = TRUE; 1.233 + break; 1.234 + case HEAD_DATE: 1.235 + has_date = TRUE; 1.236 + break; 1.237 + case HEAD_FROM: 1.238 + has_from = TRUE; 1.239 + break; 1.240 + case HEAD_SENDER: 1.241 + has_sender = TRUE; 1.242 + break; 1.243 + case HEAD_TO: 1.244 + case HEAD_CC: 1.245 + has_to_or_cc = TRUE; 1.246 + /* fall through */ 1.247 + case HEAD_BCC: 1.248 + if (flags & ACC_RCPT_FROM_HEAD) { 1.249 + /* -t option (see comment above) */ 1.250 + DEBUG(5) debugf("hdr->value = %s\n", 1.251 + hdr->value); 1.252 + if (hdr->value) { 1.253 + msg->rcpt_list = addr_list_append_rfc822(msg->rcpt_list, hdr->value, conf.host_name); 1.254 + } 1.255 + } 1.256 + if (hdr->id == HEAD_BCC) { 1.257 + DEBUG(3) debugf("removing 'Bcc' header\n"); 1.258 + msg->hdr_list = g_list_remove_link(msg->hdr_list, hdr_node); 1.259 + g_list_free_1(hdr_node); 1.260 + destroy_header(hdr); 1.261 + } 1.262 + break; 1.263 + case HEAD_ENVELOPE_TO: 1.264 + if (flags & ACC_SAVE_ENVELOPE_TO) { 1.265 + DEBUG(3) debugf("creating 'X-Orig-Envelope-To' header\n"); 1.266 + msg->hdr_list = g_list_prepend(msg->hdr_list, 1.267 + create_header(HEAD_UNKNOWN, 1.268 + "X-Orig-Envelope-To: %s", 1.269 + hdr->value)); 1.270 + } 1.271 + DEBUG(3) debugf("removing 'Envelope-To' header\n"); 1.272 + msg->hdr_list = g_list_remove_link(msg->hdr_list, 1.273 + hdr_node); 1.274 + g_list_free_1(hdr_node); 1.275 + destroy_header(hdr); 1.276 + break; 1.277 + case HEAD_RETURN_PATH: 1.278 + if (flags & ACC_MAIL_FROM_HEAD) { 1.279 + /* usually POP3 accept */ 1.280 + msg->return_path = create_address_qualified(hdr->value, TRUE, msg->received_host); 1.281 + DEBUG(3) debugf("setting return_path to %s\n", 1.282 + addr_string(msg->return_path)); 1.283 + } 1.284 + DEBUG(3) debugf("removing 'Return-Path' header\n"); 1.285 + msg->hdr_list = g_list_remove_link(msg->hdr_list, 1.286 + hdr_node); 1.287 + g_list_free_1(hdr_node); 1.288 + destroy_header(hdr); 1.289 + break; 1.290 + default: 1.291 + break; /* make compiler happy */ 1.292 + } 1.293 + } 1.294 + 1.295 + /* 1.296 + ** TODO: do we still need this as we don't fetch 1.297 + ** mail anymore? 1.298 + ** This can happen for pop3 accept only and if no 1.299 + ** Return-Path: header was given 1.300 + */ 1.301 + ensure_return_path(msg); 1.302 + 1.303 + /* here we should have our recipients, fail if not: */ 1.304 + if (!msg->rcpt_list) { 1.305 + logwrite(LOG_WARNING, "no recipients found in message\n"); 1.306 + return AERR_NORCPT; 1.307 + } 1.308 + 1.309 + if (!has_sender && !has_from) { 1.310 + DEBUG(3) debugf("adding 'From:' header\n"); 1.311 + if (msg->full_sender_name) { 1.312 + msg->hdr_list = g_list_append(msg->hdr_list, 1.313 + create_header(HEAD_FROM, 1.314 + "From: \"%s\" <%s@%s>\n", 1.315 + msg->full_sender_name, 1.316 + msg->return_path->local_part, 1.317 + msg->return_path->domain)); 1.318 + } else { 1.319 + msg->hdr_list = g_list_append(msg->hdr_list, 1.320 + create_header(HEAD_FROM, 1.321 + "From: <%s@%s>\n", 1.322 + msg->return_path->local_part, 1.323 + msg->return_path->domain)); 1.324 + } 1.325 + } 1.326 + if (!has_to_or_cc) { 1.327 + DEBUG(3) debugf("no To: or Cc: header, hence adding " 1.328 + "`To: undisclosed recipients:;'\n"); 1.329 + msg->hdr_list = g_list_append(msg->hdr_list, 1.330 + create_header(HEAD_TO, 1.331 + "To: undisclosed-recipients:;\n")); 1.332 + } 1.333 + if (!has_date) { 1.334 + DEBUG(3) debugf("adding 'Date:' header\n"); 1.335 + msg->hdr_list = g_list_append(msg->hdr_list, 1.336 + create_header(HEAD_DATE, "Date: %s\n", 1.337 + rec_timestamp())); 1.338 + } 1.339 + if (!has_id) { 1.340 + DEBUG(3) debugf("adding 'Message-ID:' header\n"); 1.341 + msg->hdr_list = g_list_append(msg->hdr_list, 1.342 + create_header(HEAD_MESSAGE_ID, 1.343 + "Message-ID: <%s@%s>\n", 1.344 + msg->uid, conf.host_name)); 1.345 + } 1.346 + 1.347 + return AERR_OK; 1.348 +} 1.349 + 1.350 +static void 1.351 +add_received_hdr(message *msg) 1.352 +{ 1.353 + gchar *for_string = NULL; 1.354 + header *hdr = NULL; 1.355 + address *addr; 1.356 + 1.357 + DEBUG(3) debugf("adding 'Received:' header\n"); 1.358 + if (g_list_length(msg->rcpt_list) == 1) { 1.359 + /* The `for' part only if exactly one rcpt is present */ 1.360 + addr = (address *) (g_list_first(msg->rcpt_list)->data); 1.361 + for_string = g_strdup_printf("\n\tfor %s", addr_string(addr)); 1.362 + } 1.363 + if (!msg->received_host) { 1.364 + /* received locally */ 1.365 + hdr = create_header(HEAD_RECEIVED, 1.366 + "Received: by %s (%s %s, from userid %d)\n" 1.367 + "\tid %s%s; %s\n", 1.368 + conf.host_name, PACKAGE, VERSION, geteuid(), 1.369 + msg->uid, 1.370 + for_string ? for_string : "", rec_timestamp()); 1.371 + } else { 1.372 + /* received from remote */ 1.373 + DEBUG(5) debugf("adding 'Received:' header (5)\n"); 1.374 + hdr = create_header(HEAD_RECEIVED, 1.375 + "Received: from %s\n" 1.376 + "\tby %s with %s (%s %s)\n" 1.377 + "\tid %s%s; %s\n", 1.378 + msg->received_host, conf.host_name, 1.379 + prot_names[msg->received_prot], PACKAGE, 1.380 + VERSION, msg->uid, 1.381 + for_string ? for_string : "", rec_timestamp()); 1.382 + } 1.383 + msg->hdr_list = g_list_prepend(msg->hdr_list, hdr); 1.384 + if (for_string) { 1.385 + g_free(for_string); 1.386 + } 1.387 +} 1.388 + 1.389 accept_error 1.390 accept_message_prepare(message *msg, guint flags) 1.391 { 1.392 - struct passwd *passwd = NULL; 1.393 - time_t rec_time = time(NULL); 1.394 - 1.395 DEBUG(5) debugf("accept_message_prepare()\n"); 1.396 1.397 - /* create unique message id */ 1.398 + /* generate unique message id */ 1.399 msg->uid = g_malloc(14); 1.400 - string_base62(msg->uid, rec_time, 6); 1.401 + string_base62(msg->uid, time(NULL), 6); 1.402 msg->uid[6] = '-'; 1.403 string_base62(msg->uid + 7, getpid(), 3); 1.404 msg->uid[10] = '-'; 1.405 @@ -198,193 +418,26 @@ 1.406 1.407 /* if local, get password entry and set return path if missing */ 1.408 if (!msg->received_host) { 1.409 + struct passwd *passwd = NULL; 1.410 + 1.411 passwd = g_memdup(getpwuid(geteuid()), sizeof(struct passwd)); 1.412 msg->ident = g_strdup(passwd->pw_name); 1.413 if (!msg->return_path) { 1.414 - gchar *path = g_strdup_printf("<%s@%s>", passwd->pw_name, conf.host_name); 1.415 - DEBUG(3) debugf("setting return_path for local accept: %s\n", path); 1.416 + gchar *path = g_strdup_printf("<%s@%s>", 1.417 + passwd->pw_name, conf.host_name); 1.418 + DEBUG(3) debugf("setting return_path for local " 1.419 + "accept: %s\n", path); 1.420 msg->return_path = create_address(path, TRUE); 1.421 g_free(path); 1.422 } 1.423 } 1.424 1.425 - /* scan headers */ 1.426 - { 1.427 - gboolean has_id = FALSE; 1.428 - gboolean has_date = FALSE; 1.429 - gboolean has_sender = FALSE; 1.430 - gboolean has_from = FALSE; 1.431 - gboolean has_to_or_cc = FALSE; 1.432 - GList *hdr_node, *hdr_node_next; 1.433 - header *hdr; 1.434 - 1.435 - for (hdr_node = g_list_first(msg->hdr_list); 1.436 - hdr_node; 1.437 - hdr_node = hdr_node_next) { 1.438 - hdr_node_next = g_list_next(hdr_node); 1.439 - hdr = ((header *) (hdr_node->data)); 1.440 - DEBUG(5) debugf("scanning headers: %s", hdr->header); 1.441 - switch (hdr->id) { 1.442 - case HEAD_MESSAGE_ID: 1.443 - has_id = TRUE; 1.444 - break; 1.445 - case HEAD_DATE: 1.446 - has_date = TRUE; 1.447 - break; 1.448 - case HEAD_FROM: 1.449 - has_from = TRUE; 1.450 - break; 1.451 - case HEAD_SENDER: 1.452 - has_sender = TRUE; 1.453 - break; 1.454 - case HEAD_TO: 1.455 - case HEAD_CC: 1.456 - has_to_or_cc = TRUE; 1.457 - /* fall through */ 1.458 - case HEAD_BCC: 1.459 - if (flags & ACC_RCPT_FROM_HEAD) { 1.460 - /* -t option (see comment above) */ 1.461 - DEBUG(5) debugf("hdr->value = %s\n", hdr->value); 1.462 - if (hdr->value) { 1.463 - msg->rcpt_list = addr_list_append_rfc822(msg->rcpt_list, hdr->value, conf.host_name); 1.464 - } 1.465 - } 1.466 - if (hdr->id == HEAD_BCC) { 1.467 - DEBUG(3) debugf("removing 'Bcc' header\n"); 1.468 - msg->hdr_list = g_list_remove_link(msg->hdr_list, hdr_node); 1.469 - g_list_free_1(hdr_node); 1.470 - destroy_header(hdr); 1.471 - } 1.472 - break; 1.473 - case HEAD_ENVELOPE_TO: 1.474 - if (flags & ACC_SAVE_ENVELOPE_TO) { 1.475 - DEBUG(3) debugf("creating 'X-Orig-Envelope-To' header\n"); 1.476 - msg->hdr_list = g_list_prepend(msg->hdr_list, create_header(HEAD_UNKNOWN, 1.477 - "X-Orig-Envelope-To: %s", hdr->value)); 1.478 - } 1.479 - DEBUG(3) debugf("removing 'Envelope-To' header\n"); 1.480 - msg->hdr_list = g_list_remove_link(msg->hdr_list, hdr_node); 1.481 - g_list_free_1(hdr_node); 1.482 - destroy_header(hdr); 1.483 - break; 1.484 - case HEAD_RETURN_PATH: 1.485 - if (flags & ACC_MAIL_FROM_HEAD) { 1.486 - /* usually POP3 accept */ 1.487 - msg->return_path = create_address_qualified(hdr->value, TRUE, msg->received_host); 1.488 - DEBUG(3) debugf("setting return_path to %s\n", addr_string(msg->return_path)); 1.489 - } 1.490 - DEBUG(3) debugf("removing 'Return-Path' header\n"); 1.491 - msg->hdr_list = g_list_remove_link(msg->hdr_list, hdr_node); 1.492 - g_list_free_1(hdr_node); 1.493 - destroy_header(hdr); 1.494 - break; 1.495 - default: 1.496 - break; /* make compiler happy */ 1.497 - } 1.498 - } 1.499 - 1.500 - if (!msg->return_path) { 1.501 - /* 1.502 - ** TODO: do we still need this as we don't fetch 1.503 - ** mail anymore? 1.504 - ** This can happen for pop3 accept only and if no 1.505 - ** Return-Path: header was given 1.506 - */ 1.507 - GList *hdr_list; 1.508 - header *hdr; 1.509 - 1.510 - DEBUG(3) debugf("return_path == NULL\n"); 1.511 - 1.512 - hdr_list = find_header(msg->hdr_list, HEAD_SENDER, NULL); 1.513 - if (!hdr_list) { 1.514 - hdr_list = find_header(msg->hdr_list, HEAD_FROM, NULL); 1.515 - } 1.516 - if (hdr_list) { 1.517 - gchar *addr; 1.518 - hdr = (header *) (g_list_first(hdr_list)->data); 1.519 - 1.520 - DEBUG(5) debugf("hdr->value = '%s'\n", hdr->value); 1.521 - 1.522 - addr = g_strdup(hdr->value); 1.523 - g_strchomp(addr); 1.524 - 1.525 - msg->return_path = create_address_qualified(addr, FALSE, msg->received_host); 1.526 - if (msg->return_path) { 1.527 - DEBUG(3) debugf("setting return_path to %s\n", addr_string(msg->return_path)); 1.528 - 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:")); 1.529 - } 1.530 - g_free(addr); 1.531 - } 1.532 - if (!msg->return_path) { 1.533 - /* no Sender: or From: or 1.534 - create_address_qualified failed */ 1.535 - msg->return_path = create_address_qualified("postmaster", TRUE, conf.host_name); 1.536 - DEBUG(3) debugf("setting return_path to %s\n", addr_string(msg->return_path)); 1.537 - msg->hdr_list = g_list_append(msg->hdr_list, create_header(HEAD_UNKNOWN, "X-Warning: real return path is unknown\n")); 1.538 - } 1.539 - } 1.540 - 1.541 - /* here we should have our recipients, fail if not: */ 1.542 - if (!msg->rcpt_list) { 1.543 - logwrite(LOG_WARNING, "no recipients found in message\n"); 1.544 - return AERR_NORCPT; 1.545 - } 1.546 - 1.547 - if (!has_sender && !has_from) { 1.548 - DEBUG(3) debugf("adding 'From:' header\n"); 1.549 - if (msg->full_sender_name) { 1.550 - msg->hdr_list = g_list_append(msg->hdr_list, create_header(HEAD_FROM, "From: \"%s\" <%s@%s>\n", msg->full_sender_name, msg->return_path->local_part, msg->return_path->domain)); 1.551 - } else { 1.552 - msg->hdr_list = g_list_append(msg->hdr_list, create_header(HEAD_FROM, "From: <%s@%s>\n", msg->return_path->local_part, msg->return_path->domain)); 1.553 - } 1.554 - } 1.555 - if (!has_to_or_cc) { 1.556 - DEBUG(3) debugf("no To: or Cc: header, hence adding `To: undisclosed recipients:;'\n"); 1.557 - msg->hdr_list = g_list_append(msg->hdr_list, create_header(HEAD_TO, "To: undisclosed-recipients:;\n")); 1.558 - } 1.559 - if (!has_date) { 1.560 - DEBUG(3) debugf("adding 'Date:' header\n"); 1.561 - msg->hdr_list = g_list_append(msg->hdr_list, create_header(HEAD_DATE, "Date: %s\n", rec_timestamp())); 1.562 - } 1.563 - if (!has_id) { 1.564 - DEBUG(3) debugf("adding 'Message-ID:' header\n"); 1.565 - msg->hdr_list = g_list_append(msg->hdr_list, create_header(HEAD_MESSAGE_ID, "Message-ID: <%s@%s>\n", msg->uid, conf.host_name)); 1.566 - } 1.567 + if (scan_headers(msg, flags) == AERR_NORCPT) { 1.568 + return AERR_NORCPT; 1.569 } 1.570 1.571 - /* Received header: */ 1.572 - /* At this point because we have to know the rcpts for the 'for' part */ 1.573 - /* The `for' part will only be used if exactly one rcpt is present. */ 1.574 - gchar *for_string = NULL; 1.575 - header *hdr = NULL; 1.576 - 1.577 - DEBUG(3) debugf("adding 'Received:' header\n"); 1.578 - 1.579 - if (g_list_length(msg->rcpt_list) == 1) { 1.580 - address *addr = (address *) (g_list_first(msg->rcpt_list)->data); 1.581 - for_string = g_strdup_printf("\n\tfor %s", addr_string(addr)); 1.582 - } 1.583 - 1.584 - if (!msg->received_host) { 1.585 - /* received locally */ 1.586 - hdr = create_header(HEAD_RECEIVED, 1.587 - "Received: by %s (%s %s, from userid %d)\n\tid %s%s; %s\n", 1.588 - conf.host_name, PACKAGE, VERSION, geteuid(), 1.589 - msg->uid, for_string ? for_string : "", rec_timestamp()); 1.590 - } else { 1.591 - /* received from remote */ 1.592 - DEBUG(5) debugf("adding 'Received:' header (5)\n"); 1.593 - hdr = create_header(HEAD_RECEIVED, 1.594 - "Received: from %s\n\tby %s with %s (%s %s)\n\tid %s%s; %s\n", 1.595 - msg->received_host, 1.596 - conf.host_name, prot_names[msg->received_prot], PACKAGE, 1.597 - VERSION, msg->uid, for_string ? for_string : "", 1.598 - rec_timestamp()); 1.599 - } 1.600 - msg->hdr_list = g_list_prepend(msg->hdr_list, hdr); 1.601 - 1.602 - if (for_string) 1.603 - g_free(for_string); 1.604 + /* after the hdrs are scanned because we need to know the rcpts */ 1.605 + add_received_hdr(msg); 1.606 1.607 return AERR_OK; 1.608 }