Improve the algorithm of obtaining sender name from messages.
* include/mailutils/header.h: Remove unnecessary externs. (mu_url_sget_param, mu_url_aget_param): New protos. * libmailutils/base/url.c (mu_url_sget_param, mu_url_aget_param): New functions. * libmailutils/mailbox/hdrfirst.c: New file. * libmailutils/mailbox/Makefile.am (libmailbox_la_SOURCES): Add hdrfirst.c. * libmailutils/mailbox/message.c (message_envelope_sender): Try to restore the envelope sender from X-Envelope-Sender, X-Envelope-From, X-Original-Sender, and From headers, in that order. * libmailutils/mailer/mailer.c (_set_from): Try to obtain sender from the message envelope. If that fails, fall back to the From header. * libproto/mailer/mbox.c (parse_received, guess_message_recipient): New static functions. (remote_mbox_append_message): Get recipient address from the first of X-Envelope-To, Delivered-To, X-Original-To headers, in that order. If that fails, try to deduce it from the Received header. If that fails too, fall back to the To header. If recipient-headers URL parameter is defined, its value (a comma-separated list of names) overrides this list. The strip-domain parameter, if present, instructs the function to strip domain part from the recipient address before resolving it. The domain parameter, if present, supplies the domain name which overrides the domain obtained from the URL.
Showing
8 changed files
with
389 additions
and
103 deletions
... | @@ -105,6 +105,9 @@ extern int mu_header_get_value_n (mu_header_t, const char *, int, char *, | ... | @@ -105,6 +105,9 @@ extern int mu_header_get_value_n (mu_header_t, const char *, int, char *, |
105 | extern int mu_header_aget_value_n (mu_header_t, const char *, int, char **); | 105 | extern int mu_header_aget_value_n (mu_header_t, const char *, int, char **); |
106 | #define mu_header_aget_value(header, name, pptr) \ | 106 | #define mu_header_aget_value(header, name, pptr) \ |
107 | mu_header_aget_value_n (header, name, 1, pptr) | 107 | mu_header_aget_value_n (header, name, 1, pptr) |
108 | |||
109 | int mu_header_sget_firstof (mu_header_t hdr, char **names, | ||
110 | const char **pval, int *pidx); | ||
108 | 111 | ||
109 | /* Get field values as an mu_address_t. */ | 112 | /* Get field values as an mu_address_t. */ |
110 | extern int mu_header_get_address_n (mu_header_t, const char *, | 113 | extern int mu_header_get_address_n (mu_header_t, const char *, | ... | ... |
... | @@ -25,61 +25,64 @@ | ... | @@ -25,61 +25,64 @@ |
25 | extern "C" { | 25 | extern "C" { |
26 | #endif | 26 | #endif |
27 | 27 | ||
28 | extern int mu_url_create (mu_url_t *, const char *name); | 28 | int mu_url_create (mu_url_t *, const char *name); |
29 | extern int mu_url_dup (mu_url_t old_url, mu_url_t *new_url); | 29 | int mu_url_dup (mu_url_t old_url, mu_url_t *new_url); |
30 | extern int mu_url_uplevel (mu_url_t url, mu_url_t *upurl); | 30 | int mu_url_uplevel (mu_url_t url, mu_url_t *upurl); |
31 | 31 | ||
32 | extern void mu_url_destroy (mu_url_t *); | 32 | void mu_url_destroy (mu_url_t *); |
33 | extern int mu_url_parse (mu_url_t); | 33 | int mu_url_parse (mu_url_t); |
34 | 34 | ||
35 | extern int mu_url_sget_scheme (const mu_url_t, const char **); | 35 | int mu_url_sget_scheme (const mu_url_t, const char **); |
36 | extern int mu_url_aget_scheme (const mu_url_t, char **); | 36 | int mu_url_aget_scheme (const mu_url_t, char **); |
37 | extern int mu_url_get_scheme (const mu_url_t, char *, size_t, size_t *); | 37 | int mu_url_get_scheme (const mu_url_t, char *, size_t, size_t *); |
38 | |||
39 | extern int mu_url_sget_user (const mu_url_t, const char **); | ||
40 | extern int mu_url_aget_user (const mu_url_t, char **); | ||
41 | extern int mu_url_get_user (const mu_url_t, char *, size_t, size_t *); | ||
42 | 38 | ||
43 | extern int mu_url_get_secret (const mu_url_t url, mu_secret_t *psecret); | 39 | int mu_url_sget_user (const mu_url_t, const char **); |
44 | 40 | int mu_url_aget_user (const mu_url_t, char **); | |
45 | extern int mu_url_sget_auth (const mu_url_t, const char **); | 41 | int mu_url_get_user (const mu_url_t, char *, size_t, size_t *); |
46 | extern int mu_url_aget_auth (const mu_url_t, char **); | ||
47 | extern int mu_url_get_auth (const mu_url_t, char *, size_t, size_t *); | ||
48 | 42 | ||
49 | extern int mu_url_sget_host (const mu_url_t, const char **); | 43 | int mu_url_get_secret (const mu_url_t url, mu_secret_t *psecret); |
50 | extern int mu_url_aget_host (const mu_url_t, char **); | ||
51 | extern int mu_url_get_host (const mu_url_t, char *, size_t, size_t *); | ||
52 | |||
53 | extern int mu_url_sget_path (const mu_url_t, const char **); | ||
54 | extern int mu_url_aget_path (const mu_url_t, char **); | ||
55 | extern int mu_url_get_path (const mu_url_t, char *, size_t, size_t *); | ||
56 | 44 | ||
57 | extern int mu_url_sget_query (const mu_url_t url, size_t *qc, char ***qv); | 45 | int mu_url_sget_auth (const mu_url_t, const char **); |
58 | extern int mu_url_aget_query (const mu_url_t url, size_t *qc, char ***qv); | 46 | int mu_url_aget_auth (const mu_url_t, char **); |
59 | 47 | int mu_url_get_auth (const mu_url_t, char *, size_t, size_t *); | |
60 | extern int mu_url_get_port (const mu_url_t, long *); | 48 | |
49 | int mu_url_sget_host (const mu_url_t, const char **); | ||
50 | int mu_url_aget_host (const mu_url_t, char **); | ||
51 | int mu_url_get_host (const mu_url_t, char *, size_t, size_t *); | ||
52 | |||
53 | int mu_url_sget_path (const mu_url_t, const char **); | ||
54 | int mu_url_aget_path (const mu_url_t, char **); | ||
55 | int mu_url_get_path (const mu_url_t, char *, size_t, size_t *); | ||
56 | |||
57 | int mu_url_sget_query (const mu_url_t url, size_t *qc, char ***qv); | ||
58 | int mu_url_aget_query (const mu_url_t url, size_t *qc, char ***qv); | ||
59 | |||
60 | int mu_url_get_port (const mu_url_t, long *); | ||
61 | 61 | ||
62 | int mu_url_sget_fvpairs (const mu_url_t url, size_t *fvc, char ***fvp); | 62 | int mu_url_sget_fvpairs (const mu_url_t url, size_t *fvc, char ***fvp); |
63 | int mu_url_aget_fvpairs (const mu_url_t url, size_t *pfvc, char ***pfvp); | 63 | int mu_url_aget_fvpairs (const mu_url_t url, size_t *pfvc, char ***pfvp); |
64 | 64 | ||
65 | extern int mu_url_expand_path (mu_url_t url); | 65 | int mu_url_sget_param (const mu_url_t url, const char *param, const char **val); |
66 | extern const char *mu_url_to_string (const mu_url_t); | 66 | int mu_url_aget_param (const mu_url_t url, const char *param, char **val); |
67 | |||
68 | extern int mu_url_set_scheme (mu_url_t url, const char *scheme); | ||
69 | 67 | ||
70 | extern int mu_url_is_scheme (mu_url_t, const char *scheme); | 68 | int mu_url_expand_path (mu_url_t url); |
69 | const char *mu_url_to_string (const mu_url_t); | ||
70 | |||
71 | int mu_url_set_scheme (mu_url_t url, const char *scheme); | ||
72 | |||
73 | int mu_url_is_scheme (mu_url_t, const char *scheme); | ||
71 | 74 | ||
72 | extern int mu_url_is_same_scheme (mu_url_t, mu_url_t); | 75 | int mu_url_is_same_scheme (mu_url_t, mu_url_t); |
73 | extern int mu_url_is_same_user (mu_url_t, mu_url_t); | 76 | int mu_url_is_same_user (mu_url_t, mu_url_t); |
74 | extern int mu_url_is_same_path (mu_url_t, mu_url_t); | 77 | int mu_url_is_same_path (mu_url_t, mu_url_t); |
75 | extern int mu_url_is_same_host (mu_url_t, mu_url_t); | 78 | int mu_url_is_same_host (mu_url_t, mu_url_t); |
76 | extern int mu_url_is_same_port (mu_url_t, mu_url_t); | 79 | int mu_url_is_same_port (mu_url_t, mu_url_t); |
77 | 80 | ||
78 | extern char *mu_url_decode_len (const char *s, size_t len); | 81 | char *mu_url_decode_len (const char *s, size_t len); |
79 | extern char *mu_url_decode (const char *s); | 82 | char *mu_url_decode (const char *s); |
80 | 83 | ||
81 | extern int mu_url_is_ticket (mu_url_t ticket, mu_url_t url); | 84 | int mu_url_is_ticket (mu_url_t ticket, mu_url_t url); |
82 | extern int mu_url_init (mu_url_t url, int port, const char *scheme); | 85 | int mu_url_init (mu_url_t url, int port, const char *scheme); |
83 | 86 | ||
84 | #ifdef __cplusplus | 87 | #ifdef __cplusplus |
85 | } | 88 | } | ... | ... |
... | @@ -764,6 +764,48 @@ mu_url_sget_fvpairs (const mu_url_t url, size_t *fvc, char ***fvp) | ... | @@ -764,6 +764,48 @@ mu_url_sget_fvpairs (const mu_url_t url, size_t *fvc, char ***fvp) |
764 | } | 764 | } |
765 | 765 | ||
766 | int | 766 | int |
767 | mu_url_sget_param (const mu_url_t url, const char *param, const char **val) | ||
768 | { | ||
769 | size_t fvc; | ||
770 | char **fvp; | ||
771 | int status = mu_url_sget_fvpairs (url, &fvc, &fvp); | ||
772 | |||
773 | if (status) | ||
774 | return status; | ||
775 | |||
776 | if (fvc) | ||
777 | { | ||
778 | size_t i; | ||
779 | |||
780 | for (i = 0; i < fvc; i++) | ||
781 | { | ||
782 | const char *p; | ||
783 | char *q; | ||
784 | |||
785 | for (p = param, q = fvp[i]; *p && *q && *p == *q; p++, q++) | ||
786 | ; | ||
787 | if (*p == 0) | ||
788 | { | ||
789 | if (*q == 0) | ||
790 | { | ||
791 | if (val) | ||
792 | *val = q; | ||
793 | return 0; | ||
794 | } | ||
795 | else if (*q == '=') | ||
796 | { | ||
797 | if (val) | ||
798 | *val = q + 1; | ||
799 | return 0; | ||
800 | } | ||
801 | } | ||
802 | } | ||
803 | } | ||
804 | |||
805 | return MU_ERR_NOENT; | ||
806 | } | ||
807 | |||
808 | int | ||
767 | mu_url_aget_fvpairs (const mu_url_t url, size_t *pfvc, char ***pfvp) | 809 | mu_url_aget_fvpairs (const mu_url_t url, size_t *pfvc, char ***pfvp) |
768 | { | 810 | { |
769 | size_t fvc, i; | 811 | size_t fvc, i; |
... | @@ -792,6 +834,21 @@ mu_url_aget_fvpairs (const mu_url_t url, size_t *pfvc, char ***pfvp) | ... | @@ -792,6 +834,21 @@ mu_url_aget_fvpairs (const mu_url_t url, size_t *pfvc, char ***pfvp) |
792 | } | 834 | } |
793 | 835 | ||
794 | int | 836 | int |
837 | mu_url_aget_param (const mu_url_t url, const char *param, char **val) | ||
838 | { | ||
839 | const char *s; | ||
840 | int status = mu_url_sget_param (url, param, &s); | ||
841 | |||
842 | if (status == 0) | ||
843 | { | ||
844 | *val = strdup (s); | ||
845 | if (!*val) | ||
846 | status = ENOMEM; | ||
847 | } | ||
848 | return status; | ||
849 | } | ||
850 | |||
851 | int | ||
795 | mu_url_get_port (const mu_url_t url, long *pport) | 852 | mu_url_get_port (const mu_url_t url, long *pport) |
796 | { | 853 | { |
797 | if (url == NULL) | 854 | if (url == NULL) | ... | ... |
libmailutils/mailbox/hdrfirst.c
0 → 100644
1 | /* GNU Mailutils -- a suite of utilities for electronic mail | ||
2 | Copyright (C) 2010 Free Software Foundation, Inc. | ||
3 | |||
4 | This library is free software; you can redistribute it and/or | ||
5 | modify it under the terms of the GNU Lesser General Public | ||
6 | License as published by the Free Software Foundation; either | ||
7 | version 3 of the License, or (at your option) any later version. | ||
8 | |||
9 | This library is distributed in the hope that it will be useful, | ||
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
12 | Lesser General Public License for more details. | ||
13 | |||
14 | You should have received a copy of the GNU Lesser General | ||
15 | Public License along with this library. If not, see | ||
16 | <http://www.gnu.org/licenses/>. */ | ||
17 | |||
18 | #ifdef HAVE_CONFIG_H | ||
19 | # include <config.h> | ||
20 | #endif | ||
21 | |||
22 | #include <stdlib.h> | ||
23 | #include <mailutils/types.h> | ||
24 | #include <mailutils/header.h> | ||
25 | #include <mailutils/errno.h> | ||
26 | |||
27 | int | ||
28 | mu_header_sget_firstof (mu_header_t hdr, char **names, | ||
29 | const char **pval, int *pidx) | ||
30 | { | ||
31 | int status; | ||
32 | const char *s = NULL; | ||
33 | int i; | ||
34 | |||
35 | for (i = 0; names[i]; i++) | ||
36 | { | ||
37 | status = mu_header_sget_value (hdr, names[i], &s); | ||
38 | if (status == 0 && *s != 0) | ||
39 | { | ||
40 | if (pval) | ||
41 | *pval = s; | ||
42 | if (pidx) | ||
43 | *pidx = i; | ||
44 | return 0; | ||
45 | } | ||
46 | } | ||
47 | return MU_ERR_NOENT; | ||
48 | } |
... | @@ -429,52 +429,59 @@ message_envelope_sender (mu_envelope_t envelope, char *buf, size_t len, | ... | @@ -429,52 +429,59 @@ message_envelope_sender (mu_envelope_t envelope, char *buf, size_t len, |
429 | size_t *pnwrite) | 429 | size_t *pnwrite) |
430 | { | 430 | { |
431 | mu_message_t msg = mu_envelope_get_owner (envelope); | 431 | mu_message_t msg = mu_envelope_get_owner (envelope); |
432 | mu_header_t header = NULL; | 432 | mu_header_t header; |
433 | size_t n = 0; | ||
434 | int status; | 433 | int status; |
434 | const char *sender; | ||
435 | struct mu_auth_data *auth = NULL; | ||
436 | static char *hdrnames[] = { | ||
437 | "X-Envelope-Sender", | ||
438 | "X-Envelope-From", | ||
439 | "X-Original-Sender", | ||
440 | "From", | ||
441 | NULL | ||
442 | }; | ||
443 | mu_address_t address = NULL; | ||
435 | 444 | ||
436 | if (msg == NULL) | 445 | if (msg == NULL) |
437 | return EINVAL; | 446 | return EINVAL; |
438 | 447 | ||
439 | /* Can it be extracted from the From: */ | 448 | /* First, try the header */ |
440 | mu_message_get_header (msg, &header); | 449 | status = mu_message_get_header (msg, &header); |
441 | status = mu_header_get_value (header, MU_HEADER_FROM, NULL, 0, &n); | 450 | if (status) |
442 | if (status == 0 && n != 0) | 451 | return status; |
452 | status = mu_header_sget_firstof (header, hdrnames, &sender, NULL); | ||
453 | if (status) | ||
443 | { | 454 | { |
444 | char *sender; | 455 | auth = mu_get_auth_by_uid (getuid ()); |
445 | mu_address_t address = NULL; | 456 | if (!auth) |
446 | sender = calloc (1, n + 1); | 457 | return MU_ERR_NOENT; |
447 | if (sender == NULL) | 458 | sender = auth->name; |
448 | return ENOMEM; | ||
449 | mu_header_get_value (header, MU_HEADER_FROM, sender, n + 1, NULL); | ||
450 | if (mu_address_create (&address, sender) == 0) | ||
451 | mu_address_get_email (address, 1, buf, n + 1, pnwrite); | ||
452 | free (sender); | ||
453 | mu_address_destroy (&address); | ||
454 | return 0; | ||
455 | } | 459 | } |
456 | else if (status == EAGAIN) | ||
457 | return status; | ||
458 | 460 | ||
459 | /* oops! We are still here */ | 461 | status = mu_address_create (&address, sender); |
460 | { | 462 | if (status == 0) |
461 | struct mu_auth_data *auth = mu_get_auth_by_uid (getuid ()); | 463 | { |
462 | const char *sender = auth ? auth->name : "unknown"; | 464 | status = mu_address_sget_email (address, 1, &sender); |
463 | n = strlen (sender); | 465 | if (status == 0) |
464 | if (buf && len > 0) | 466 | { |
465 | { | 467 | size_t n = strlen (sender); |
466 | len--; /* One for the null. */ | 468 | if (buf && len > 0) |
467 | n = (n < len) ? n : len; | 469 | { |
468 | memcpy (buf, auth->name, n); | 470 | len--; /* One for the null. */ |
469 | buf[n] = '\0'; | 471 | n = (n < len) ? n : len; |
470 | } | 472 | memcpy (buf, sender, n); |
471 | if (auth) | 473 | buf[n] = '\0'; |
472 | mu_auth_data_free (auth); | 474 | } |
473 | } | 475 | if (pnwrite) |
476 | *pnwrite = n; | ||
477 | } | ||
478 | mu_address_destroy (&address); | ||
479 | } | ||
480 | |||
481 | if (auth) | ||
482 | mu_auth_data_free (auth); | ||
474 | 483 | ||
475 | if (pnwrite) | 484 | return status; |
476 | *pnwrite = n; | ||
477 | return 0; | ||
478 | } | 485 | } |
479 | 486 | ||
480 | 487 | ... | ... |
... | @@ -41,6 +41,7 @@ | ... | @@ -41,6 +41,7 @@ |
41 | #include <mailutils/stream.h> | 41 | #include <mailutils/stream.h> |
42 | #include <mailutils/url.h> | 42 | #include <mailutils/url.h> |
43 | #include <mailutils/header.h> | 43 | #include <mailutils/header.h> |
44 | #include <mailutils/envelope.h> | ||
44 | #include <mailutils/body.h> | 45 | #include <mailutils/body.h> |
45 | #include <mailutils/mailbox.h> | 46 | #include <mailutils/mailbox.h> |
46 | #include <mailutils/message.h> | 47 | #include <mailutils/message.h> |
... | @@ -336,20 +337,27 @@ _set_from (mu_address_t *pfrom, mu_message_t msg, mu_address_t from, | ... | @@ -336,20 +337,27 @@ _set_from (mu_address_t *pfrom, mu_message_t msg, mu_address_t from, |
336 | mu_mailer_t mailer) | 337 | mu_mailer_t mailer) |
337 | { | 338 | { |
338 | int status = 0; | 339 | int status = 0; |
339 | char *mail_from; | ||
340 | mu_header_t header = NULL; | ||
341 | 340 | ||
342 | *pfrom = NULL; | ||
343 | |||
344 | /* Get MAIL_FROM from FROM, the message, or the environment. */ | 341 | /* Get MAIL_FROM from FROM, the message, or the environment. */ |
345 | if (!from) | 342 | if (!from) |
346 | { | 343 | { |
347 | const char *type; | 344 | const char *type; |
348 | 345 | mu_envelope_t env; | |
349 | if ((status = mu_message_get_header (msg, &header)) != 0) | 346 | const char *mail_from; |
347 | |||
348 | status = mu_message_get_envelope (msg, &env); | ||
349 | if (status) | ||
350 | return status; | 350 | return status; |
351 | 351 | ||
352 | status = mu_header_aget_value (header, MU_HEADER_FROM, &mail_from); | 352 | status = mu_envelope_sget_sender (env, &mail_from); |
353 | if (status) | ||
354 | { | ||
355 | mu_header_t header; | ||
356 | status = mu_message_get_header (msg, &header); | ||
357 | if (status) | ||
358 | return status; | ||
359 | status = mu_header_sget_value (header, MU_HEADER_FROM, &mail_from); | ||
360 | } | ||
353 | 361 | ||
354 | switch (status) | 362 | switch (status) |
355 | { | 363 | { |
... | @@ -361,9 +369,6 @@ _set_from (mu_address_t *pfrom, mu_message_t msg, mu_address_t from, | ... | @@ -361,9 +369,6 @@ _set_from (mu_address_t *pfrom, mu_message_t msg, mu_address_t from, |
361 | MU_DEBUG1 (mailer->debug, MU_DEBUG_TRACE, | 369 | MU_DEBUG1 (mailer->debug, MU_DEBUG_TRACE, |
362 | "mu_mailer_send_message(): using From: %s\n", | 370 | "mu_mailer_send_message(): using From: %s\n", |
363 | mail_from); | 371 | mail_from); |
364 | |||
365 | status = mu_address_create (pfrom, mail_from); | ||
366 | free (mail_from); | ||
367 | break; | 372 | break; |
368 | 373 | ||
369 | case MU_ERR_NOENT: | 374 | case MU_ERR_NOENT: |
... | @@ -379,18 +384,20 @@ _set_from (mu_address_t *pfrom, mu_message_t msg, mu_address_t from, | ... | @@ -379,18 +384,20 @@ _set_from (mu_address_t *pfrom, mu_message_t msg, mu_address_t from, |
379 | "mu_mailer_send_message(): using user's address: %s\n", | 384 | "mu_mailer_send_message(): using user's address: %s\n", |
380 | mail_from); | 385 | mail_from); |
381 | else | 386 | else |
382 | MU_DEBUG (mailer->debug, MU_DEBUG_ERROR, | 387 | { |
383 | "mu_mailer_send_message(): no user's address, failing\n"); | 388 | MU_DEBUG (mailer->debug, MU_DEBUG_ERROR, |
384 | 389 | "mu_mailer_send_message(): " | |
385 | if (!mail_from) | 390 | "no user's address, failing\n"); |
386 | return errno; | 391 | return errno; |
387 | 392 | } | |
388 | status = mu_address_create (pfrom, mail_from); | ||
389 | /* FIXME: should we add the From: header? */ | 393 | /* FIXME: should we add the From: header? */ |
390 | break; | 394 | break; |
391 | } | 395 | } |
396 | status = mu_address_create (pfrom, mail_from); | ||
392 | } | 397 | } |
393 | 398 | else | |
399 | *pfrom = NULL; | ||
400 | |||
394 | return status; | 401 | return status; |
395 | } | 402 | } |
396 | 403 | ... | ... |
... | @@ -29,6 +29,10 @@ | ... | @@ -29,6 +29,10 @@ |
29 | #include <mailutils/mailer.h> | 29 | #include <mailutils/mailer.h> |
30 | #include <mailutils/url.h> | 30 | #include <mailutils/url.h> |
31 | #include <mailutils/util.h> | 31 | #include <mailutils/util.h> |
32 | #include <mailutils/argcv.h> | ||
33 | #include <mailutils/message.h> | ||
34 | #include <mailutils/envelope.h> | ||
35 | #include <mailutils/header.h> | ||
32 | #include <mailutils/sys/mailbox.h> | 36 | #include <mailutils/sys/mailbox.h> |
33 | #include <mailutils/sys/mailer.h> | 37 | #include <mailutils/sys/mailer.h> |
34 | 38 | ||
... | @@ -116,6 +120,113 @@ mkaddr (mu_mailbox_t mbox, mu_property_t property, | ... | @@ -116,6 +120,113 @@ mkaddr (mu_mailbox_t mbox, mu_property_t property, |
116 | return 0; | 120 | return 0; |
117 | } | 121 | } |
118 | 122 | ||
123 | static int | ||
124 | parse_received (mu_header_t hdr, char **sptr) | ||
125 | { | ||
126 | const char *recv; | ||
127 | int wc, i; | ||
128 | char **ws; | ||
129 | enum { rcv_init, rcv_from, rcv_by, rcv_for } state; | ||
130 | int status; | ||
131 | char *s; | ||
132 | size_t len; | ||
133 | |||
134 | status = mu_header_sget_value (hdr, MU_HEADER_RECEIVED, &recv); | ||
135 | if (status) | ||
136 | return status; | ||
137 | status = mu_argcv_get (recv, NULL, NULL, &wc, &ws); | ||
138 | if (status) | ||
139 | return status; | ||
140 | |||
141 | state = rcv_init; | ||
142 | for (i = 0; i < wc && state != rcv_for; i++) | ||
143 | { | ||
144 | switch (state) | ||
145 | { | ||
146 | case rcv_init: | ||
147 | if (strcmp (ws[i], "from") == 0) | ||
148 | state = rcv_from; | ||
149 | break; | ||
150 | |||
151 | case rcv_from: | ||
152 | if (strcmp (ws[i], "by") == 0) | ||
153 | state = rcv_by; | ||
154 | break; | ||
155 | |||
156 | case rcv_by: | ||
157 | if (strcmp (ws[i], "for") == 0) | ||
158 | state = rcv_for; | ||
159 | break; | ||
160 | |||
161 | default: | ||
162 | break; | ||
163 | } | ||
164 | } | ||
165 | |||
166 | if (state != rcv_for || ws[i] == NULL) | ||
167 | return MU_ERR_NOENT; | ||
168 | |||
169 | s = ws[i]; | ||
170 | len = strlen (s); | ||
171 | if (s[len - 1] == ';') | ||
172 | len--; | ||
173 | if (s[0] == '<' && s[len - 1] == '>') | ||
174 | { | ||
175 | s++; | ||
176 | len--; | ||
177 | } | ||
178 | *sptr = malloc (len); | ||
179 | if (!*sptr) | ||
180 | status = ENOMEM; | ||
181 | else | ||
182 | { | ||
183 | memcpy (*sptr, s, len); | ||
184 | (*sptr)[len - 1] = 0; | ||
185 | } | ||
186 | mu_argcv_free (wc, ws); | ||
187 | return status; | ||
188 | } | ||
189 | |||
190 | static int | ||
191 | guess_message_recipient (mu_message_t msg, char **hdrname, char **pptr) | ||
192 | { | ||
193 | mu_header_t hdr; | ||
194 | int status; | ||
195 | char *s = NULL; | ||
196 | |||
197 | status = mu_message_get_header (msg, &hdr); | ||
198 | if (status) | ||
199 | return status; | ||
200 | |||
201 | /* First, try an easy way. */ | ||
202 | if (hdrname) | ||
203 | { | ||
204 | int i; | ||
205 | for (i = 0; hdrname[i]; i++) | ||
206 | { | ||
207 | status = mu_header_aget_value (hdr, hdrname[i], &s); | ||
208 | if (status == 0 && *s != 0) | ||
209 | break; | ||
210 | } | ||
211 | } | ||
212 | else | ||
213 | status = MU_ERR_NOENT; | ||
214 | |||
215 | if (status == MU_ERR_NOENT) | ||
216 | { | ||
217 | status = parse_received (hdr, &s); | ||
218 | if (status) | ||
219 | status = mu_header_aget_value (hdr, MU_HEADER_TO, &s); | ||
220 | } | ||
221 | |||
222 | if (status) | ||
223 | return status; | ||
224 | |||
225 | *pptr = s; | ||
226 | |||
227 | return 0; | ||
228 | } | ||
229 | |||
119 | 230 | ||
120 | static int | 231 | static int |
121 | remote_mbox_append_message (mu_mailbox_t mbox, mu_message_t msg) | 232 | remote_mbox_append_message (mu_mailbox_t mbox, mu_message_t msg) |
... | @@ -137,9 +248,47 @@ remote_mbox_append_message (mu_mailbox_t mbox, mu_message_t msg) | ... | @@ -137,9 +248,47 @@ remote_mbox_append_message (mu_mailbox_t mbox, mu_message_t msg) |
137 | mkaddr (mbox, property, "TO", &to); | 248 | mkaddr (mbox, property, "TO", &to); |
138 | if (!to) | 249 | if (!to) |
139 | { | 250 | { |
140 | const char *rcpt; | 251 | char *rcpt; |
141 | 252 | ||
142 | status = mu_url_sget_user (mbox->url, &rcpt); | 253 | status = mu_url_aget_user (mbox->url, &rcpt); |
254 | if (status == MU_ERR_NOENT) | ||
255 | { | ||
256 | static char *hdrnames[] = { | ||
257 | "X-Envelope-To", | ||
258 | "Delivered-To", | ||
259 | "X-Original-To", | ||
260 | NULL | ||
261 | }; | ||
262 | const char *hstr; | ||
263 | int hc; | ||
264 | char **hv; | ||
265 | |||
266 | if (mu_url_sget_param (mbox->url, "recipient-headers", &hstr) == 0) | ||
267 | { | ||
268 | if (*hstr == 0) | ||
269 | { | ||
270 | hc = 0; | ||
271 | hv = NULL; | ||
272 | } | ||
273 | else | ||
274 | { | ||
275 | status = mu_argcv_get_np (hstr, strlen (hstr), ",", NULL, 0, | ||
276 | &hc, &hv, NULL); | ||
277 | if (status) | ||
278 | return status; | ||
279 | } | ||
280 | } | ||
281 | else | ||
282 | { | ||
283 | hc = 0; | ||
284 | hv = hdrnames; | ||
285 | } | ||
286 | |||
287 | status = guess_message_recipient (msg, hv, &rcpt); | ||
288 | if (hc) | ||
289 | mu_argcv_free (hc, hv); | ||
290 | } | ||
291 | |||
143 | if (status != MU_ERR_NOENT) | 292 | if (status != MU_ERR_NOENT) |
144 | { | 293 | { |
145 | const char *host; | 294 | const char *host; |
... | @@ -148,16 +297,27 @@ remote_mbox_append_message (mu_mailbox_t mbox, mu_message_t msg) | ... | @@ -148,16 +297,27 @@ remote_mbox_append_message (mu_mailbox_t mbox, mu_message_t msg) |
148 | if (status) | 297 | if (status) |
149 | { | 298 | { |
150 | MU_DEBUG1 (mbox->debug, MU_DEBUG_ERROR, | 299 | MU_DEBUG1 (mbox->debug, MU_DEBUG_ERROR, |
151 | "failed to get recipient from the url: %s\n", | 300 | "failed to get recipient: %s\n", |
152 | mu_strerror (status)); | 301 | mu_strerror (status)); |
153 | return status; | 302 | return status; |
154 | } | 303 | } |
155 | 304 | ||
156 | mu_url_sget_host (mbox->url, &host); | 305 | /* Get additional parameters */ |
306 | status = mu_url_sget_param (mbox->url, "strip-domain", NULL); | ||
307 | if (status == 0) | ||
308 | { | ||
309 | char *q = strchr (rcpt, '@'); | ||
310 | if (q) | ||
311 | *q = 0; | ||
312 | } | ||
313 | |||
314 | status = mu_url_sget_param (mbox->url, "domain", &host); | ||
315 | if (!(status == 0 && *host)) | ||
316 | mu_url_sget_host (mbox->url, &host); | ||
157 | hint.domain = (char*) host; | 317 | hint.domain = (char*) host; |
158 | status = mu_address_create_hint (&to, rcpt, &hint, | 318 | status = mu_address_create_hint (&to, rcpt, &hint, |
159 | MU_ADDR_HINT_DOMAIN); | 319 | MU_ADDR_HINT_DOMAIN); |
160 | 320 | free (rcpt); | |
161 | if (status) | 321 | if (status) |
162 | { | 322 | { |
163 | MU_DEBUG3 (mbox->debug, MU_DEBUG_ERROR, | 323 | MU_DEBUG3 (mbox->debug, MU_DEBUG_ERROR, | ... | ... |
-
Please register or sign in to post a comment