This is patch 4 of 4 implementing support for SMTPUTF8 (RFC 6531).

RFC6532 support already worked: rfc822*.c already parsed messages in
exactly the way RFC6532 wants.

Thanks for Arnt Gulbrandsen for the original patch.

-- 
Kevin J. McCarthy
GPG Fingerprint: 8975 A9B3 3AA3 7910 385C  5308 ADEF 7684 8031 6BDA
http://www.8t8.us/configs/gpg-key-transition-statement.txt
# HG changeset patch
# User Kevin McCarthy <[email protected]>
# Date 1447713419 28800
#      Mon Nov 16 14:36:59 2015 -0800
# Node ID 33a294afd7d66776fcf0b9c79c49ac361747e638
# Parent  5e172867c5f9256a11ca308ed728d79c032e86de
Implement SMTPUTF8 capability support in smtp.c

This is patch 4 of 4 implementing support for SMTPUTF8 (RFC 6531).

RFC6532 support already worked: rfc822*.c already parsed messages in
exactly the way RFC6532 wants.

Thanks for Arnt Gulbrandsen for the original patch.

diff --git a/smtp.c b/smtp.c
--- a/smtp.c
+++ b/smtp.c
@@ -56,16 +56,17 @@
 #define SMTP_AUTH_UNAVAIL 1
 #define SMTP_AUTH_FAIL    -1
 
 enum {
   STARTTLS,
   AUTH,
   DSN,
   EIGHTBITMIME,
+  SMTPUTF8,
 
   CAPMAX
 };
 
 #ifdef USE_SASL
 static int smtp_auth (CONNECTION* conn);
 static int smtp_auth_sasl (CONNECTION* conn, const char* mechanisms);
 #endif
@@ -117,16 +118,18 @@
       mutt_bit_set (Capabilities, AUTH);
       FREE (&AuthMechs);
       AuthMechs = safe_strdup (buf + 9);
     }
     else if (!ascii_strncasecmp ("DSN", buf + 4, 3))
       mutt_bit_set (Capabilities, DSN);
     else if (!ascii_strncasecmp ("STARTTLS", buf + 4, 8))
       mutt_bit_set (Capabilities, STARTTLS);
+    else if (!ascii_strncasecmp ("SMTPUTF8", buf + 4, 8))
+      mutt_bit_set (Capabilities, SMTPUTF8);
 
     if (smtp_code (buf, n, &n) < 0)
       return smtp_err_code;
 
   } while (buf[3] == '-');
 
   if (smtp_success (n) || n == smtp_continue)
     return 0;
@@ -231,16 +234,44 @@
     return smtp_err_write;
 
   if ((r = smtp_get_resp (conn)))
     return r;
 
   return 0;
 }
 
+
+/* Returns 1 if a contains at least one 8-bit character, 0 if none do.
+ */
+static int
+address_uses_unicode(const char * a) {
+  while(a && *a > 0 && *a < 128)
+    a++;
+  if(a && *a)
+    return 1;
+  return 0;
+}
+
+
+/* Returns 1 if any address in a contains at least one 8-bit
+ * character, 0 if none do.
+ */
+static int
+addresses_use_unicode(const ADDRESS* a) {
+  while (a)
+  {
+    if(a->mailbox && !a->group && address_uses_unicode(a->mailbox))
+      return 1;
+    a = a->next;
+  }
+  return 0;
+}
+
+
 int
 mutt_smtp_send (const ADDRESS* from, const ADDRESS* to, const ADDRESS* cc,
                 const ADDRESS* bcc, const char *msgfile, int eightbit)
 {
   CONNECTION *conn;
   ACCOUNT account;
   const char* envfrom;
   char buf[1024];
@@ -277,16 +308,22 @@
     ret = snprintf (buf, sizeof (buf), "MAIL FROM:<%s>", envfrom);
     if (eightbit && mutt_bit_isset (Capabilities, EIGHTBITMIME))
     {
       safe_strncat (buf, sizeof (buf), " BODY=8BITMIME", 15);
       ret += 14;
     }
     if (DsnReturn && mutt_bit_isset (Capabilities, DSN))
       ret += snprintf (buf + ret, sizeof (buf) - ret, " RET=%s", DsnReturn);
+    if (mutt_bit_isset (Capabilities, SMTPUTF8) &&
+       (address_uses_unicode(envfrom) ||
+        addresses_use_unicode(to) ||
+        addresses_use_unicode(cc) ||
+        addresses_use_unicode(bcc)))
+      ret += snprintf (buf + ret, sizeof (buf) - ret, " SMTPUTF8");
     safe_strncat (buf, sizeof (buf), "\r\n", 3);
     if (mutt_socket_write (conn, buf) == -1)
     {
       ret = smtp_err_write;
       break;
     }
     if ((ret = smtp_get_resp (conn)))
       break;

Attachment: signature.asc
Description: PGP signature

Reply via email to