Commit 4b30e617 4b30e617e722e25ed508953648dc2c0b936aa80a by Sergey Poznyakoff

mailer: minor improvement

Be more liberal when guessing sender and recipient names. Tolerate
deviations from RFC822.

* libmailutils/mailer/mailer.c (copy_fragment)
(recover_email, safe_address_create): New functions.
(_set_from, _set_to): Use safe_address_create.
1 parent 30b5656d
...@@ -51,6 +51,8 @@ ...@@ -51,6 +51,8 @@
51 #include <mailutils/util.h> 51 #include <mailutils/util.h>
52 #include <mailutils/mime.h> 52 #include <mailutils/mime.h>
53 #include <mailutils/io.h> 53 #include <mailutils/io.h>
54 #include <mailutils/cctype.h>
55 #include <mailutils/parse822.h>
54 56
55 #include <mailutils/sys/mailer.h> 57 #include <mailutils/sys/mailer.h>
56 58
...@@ -325,6 +327,83 @@ save_fcc (mu_message_t msg) ...@@ -325,6 +327,83 @@ save_fcc (mu_message_t msg)
325 } 327 }
326 328
327 static int 329 static int
330 copy_fragment (char **pretender, const char *p, const char *q)
331 {
332 size_t len = q - p + 1;
333 *pretender = malloc (len + 1);
334 if (!*pretender)
335 return ENOMEM;
336 memcpy (*pretender, p, len);
337 (*pretender)[len] = 0;
338 return 0;
339 }
340
341 /* Try to extract from STRING a portion that looks like an email address */
342 static int
343 recover_email (const char *string, char **pretender)
344 {
345 char *p, *q;
346
347 p = strchr (string, '<');
348 if (p)
349 {
350 q = strchr (p, '>');
351 if (q)
352 return copy_fragment (pretender, p, q);
353 }
354 p = mu_str_skip_class (string, MU_CTYPE_SPACE);
355 if (*p && mu_parse822_is_atom_char (*p))
356 {
357 q = p;
358 while (*++q && (mu_parse822_is_atom_char (*q) || *q == '.'))
359 ;
360 if (*q == '@')
361 while (*++q && (mu_parse822_is_atom_char (*q) || *q == '.'))
362 ;
363 q--;
364 if (q > p)
365 return copy_fragment (pretender, p, q);
366 }
367 return MU_ERR_NOENT;
368 }
369
370 static int
371 safe_address_create (mu_address_t *paddr, const char *addr_str,
372 const char *who)
373 {
374 int status = mu_address_create (paddr, addr_str);
375 if (status == MU_ERR_BAD_822_FORMAT)
376 {
377 int rc;
378 char *p;
379
380 mu_debug (MU_DEBCAT_MAILER, MU_DEBUG_ERROR,
381 ("bad %s address: %s", who, addr_str));
382 rc = recover_email (addr_str, &p);
383 if (rc && rc != MU_ERR_NOENT)
384 mu_debug (MU_DEBCAT_MAILER, MU_DEBUG_ERROR,
385 ("%s address recovery failed: %s", who, mu_strerror (rc)));
386 else
387 {
388 mu_debug (MU_DEBCAT_MAILER, MU_DEBUG_TRACE1,
389 ("recovered possible %s address: %s", who, p));
390 rc = mu_address_create (paddr, p);
391 if (rc == 0)
392 status = 0;
393 else if (rc == MU_ERR_BAD_822_FORMAT)
394 mu_debug (MU_DEBCAT_MAILER, MU_DEBUG_TRACE1,
395 ("%s address guess failed", who));
396 else
397 mu_debug (MU_DEBCAT_MAILER, MU_DEBUG_ERROR,
398 ("cannot convert %s address '%s': %s",
399 who, p, mu_strerror (rc)));
400 free (p);
401 }
402 }
403 return status;
404 }
405
406 static int
328 _set_from (mu_address_t *pfrom, mu_message_t msg, mu_address_t from, 407 _set_from (mu_address_t *pfrom, mu_message_t msg, mu_address_t from,
329 mu_mailer_t mailer) 408 mu_mailer_t mailer)
330 { 409 {
...@@ -393,7 +472,7 @@ _set_from (mu_address_t *pfrom, mu_message_t msg, mu_address_t from, ...@@ -393,7 +472,7 @@ _set_from (mu_address_t *pfrom, mu_message_t msg, mu_address_t from,
393 /* FIXME: should we add the From: header? */ 472 /* FIXME: should we add the From: header? */
394 break; 473 break;
395 } 474 }
396 status = mu_address_create (pfrom, mail_from); 475 status = safe_address_create (pfrom, mail_from, "sender");
397 } 476 }
398 477
399 return status; 478 return status;
...@@ -427,7 +506,7 @@ _set_to (mu_address_t *paddr, mu_message_t msg, mu_address_t to, ...@@ -427,7 +506,7 @@ _set_to (mu_address_t *paddr, mu_message_t msg, mu_address_t to,
427 mu_debug (MU_DEBCAT_MAILER, MU_DEBUG_TRACE, 506 mu_debug (MU_DEBCAT_MAILER, MU_DEBUG_TRACE,
428 ("mu_mailer_send_message(): using RCPT TO: %s", 507 ("mu_mailer_send_message(): using RCPT TO: %s",
429 rcpt_to)); 508 rcpt_to));
430 status = mu_address_create (paddr, rcpt_to); 509 status = safe_address_create (paddr, rcpt_to, "recipient");
431 } 510 }
432 511
433 return status; 512 return status;
......