Commit 2f6f7b4f 2f6f7b4fc2230352e8ff742b9999672dec35236b by Sergey Poznyakoff

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.
1 parent 1417084b
...@@ -106,6 +106,9 @@ extern int mu_header_aget_value_n (mu_header_t, const char *, int, char **); ...@@ -106,6 +106,9 @@ 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 108
109 int mu_header_sget_firstof (mu_header_t hdr, char **names,
110 const char **pval, int *pidx);
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 *,
111 int, mu_address_t *); 114 int, mu_address_t *);
......
...@@ -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 38
39 extern int mu_url_sget_user (const mu_url_t, const char **); 39 int mu_url_sget_user (const mu_url_t, const char **);
40 extern int mu_url_aget_user (const mu_url_t, char **); 40 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 *); 41 int mu_url_get_user (const mu_url_t, char *, size_t, size_t *);
42 42
43 extern int mu_url_get_secret (const mu_url_t url, mu_secret_t *psecret); 43 int mu_url_get_secret (const mu_url_t url, mu_secret_t *psecret);
44 44
45 extern int mu_url_sget_auth (const mu_url_t, const char **); 45 int mu_url_sget_auth (const mu_url_t, const char **);
46 extern int mu_url_aget_auth (const mu_url_t, char **); 46 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 *); 47 int mu_url_get_auth (const mu_url_t, char *, size_t, size_t *);
48 48
49 extern int mu_url_sget_host (const mu_url_t, const char **); 49 int mu_url_sget_host (const mu_url_t, const char **);
50 extern int mu_url_aget_host (const mu_url_t, char **); 50 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 *); 51 int mu_url_get_host (const mu_url_t, char *, size_t, size_t *);
52 52
53 extern int mu_url_sget_path (const mu_url_t, const char **); 53 int mu_url_sget_path (const mu_url_t, const char **);
54 extern int mu_url_aget_path (const mu_url_t, char **); 54 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 *); 55 int mu_url_get_path (const mu_url_t, char *, size_t, size_t *);
56 56
57 extern int mu_url_sget_query (const mu_url_t url, size_t *qc, char ***qv); 57 int mu_url_sget_query (const mu_url_t url, size_t *qc, char ***qv);
58 extern int mu_url_aget_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 59
60 extern int mu_url_get_port (const mu_url_t, long *); 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 67
68 extern int mu_url_set_scheme (mu_url_t url, const char *scheme); 68 int mu_url_expand_path (mu_url_t url);
69 const char *mu_url_to_string (const mu_url_t);
69 70
70 extern int mu_url_is_scheme (mu_url_t, const char *scheme); 71 int mu_url_set_scheme (mu_url_t url, const char *scheme);
71 72
72 extern int mu_url_is_same_scheme (mu_url_t, mu_url_t); 73 int mu_url_is_scheme (mu_url_t, const char *scheme);
73 extern 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);
75 extern 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);
77 74
78 extern char *mu_url_decode_len (const char *s, size_t len); 75 int mu_url_is_same_scheme (mu_url_t, mu_url_t);
79 extern char *mu_url_decode (const char *s); 76 int mu_url_is_same_user (mu_url_t, mu_url_t);
77 int mu_url_is_same_path (mu_url_t, mu_url_t);
78 int mu_url_is_same_host (mu_url_t, mu_url_t);
79 int mu_url_is_same_port (mu_url_t, mu_url_t);
80 80
81 extern int mu_url_is_ticket (mu_url_t ticket, mu_url_t url); 81 char *mu_url_decode_len (const char *s, size_t len);
82 extern int mu_url_init (mu_url_t url, int port, const char *scheme); 82 char *mu_url_decode (const char *s);
83
84 int mu_url_is_ticket (mu_url_t ticket, mu_url_t url);
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)
......
...@@ -25,6 +25,7 @@ libmailbox_la_SOURCES = \ ...@@ -25,6 +25,7 @@ libmailbox_la_SOURCES = \
25 body.c\ 25 body.c\
26 envelope.c\ 26 envelope.c\
27 folder.c\ 27 folder.c\
28 hdrfirst.c\
28 hdritr.c\ 29 hdritr.c\
29 header.c\ 30 header.c\
30 message.c\ 31 message.c\
......
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);
462 if (status == 0)
463 {
464 status = mu_address_sget_email (address, 1, &sender);
465 if (status == 0)
460 { 466 {
461 struct mu_auth_data *auth = mu_get_auth_by_uid (getuid ()); 467 size_t n = strlen (sender);
462 const char *sender = auth ? auth->name : "unknown";
463 n = strlen (sender);
464 if (buf && len > 0) 468 if (buf && len > 0)
465 { 469 {
466 len--; /* One for the null. */ 470 len--; /* One for the null. */
467 n = (n < len) ? n : len; 471 n = (n < len) ? n : len;
468 memcpy (buf, auth->name, n); 472 memcpy (buf, sender, n);
469 buf[n] = '\0'; 473 buf[n] = '\0';
470 } 474 }
475 if (pnwrite)
476 *pnwrite = n;
477 }
478 mu_address_destroy (&address);
479 }
480
471 if (auth) 481 if (auth)
472 mu_auth_data_free (auth); 482 mu_auth_data_free (auth);
473 }
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
342 *pfrom = NULL;
343 340
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;
345 mu_envelope_t env;
346 const char *mail_from;
348 347
349 if ((status = mu_message_get_header (msg, &header)) != 0) 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,17 +384,19 @@ _set_from (mu_address_t *pfrom, mu_message_t msg, mu_address_t from, ...@@ -379,17 +384,19 @@ _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
387 {
382 MU_DEBUG (mailer->debug, MU_DEBUG_ERROR, 388 MU_DEBUG (mailer->debug, MU_DEBUG_ERROR,
383 "mu_mailer_send_message(): no user's address, failing\n"); 389 "mu_mailer_send_message(): "
384 390 "no user's address, failing\n");
385 if (!mail_from)
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 }
398 else
399 *pfrom = NULL;
393 400
394 return status; 401 return status;
395 } 402 }
......
...@@ -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;
252
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 }
141 291
142 status = mu_url_sget_user (mbox->url, &rcpt);
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
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))
156 mu_url_sget_host (mbox->url, &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,
......