Index: trunk/dports/mail/mutt-devel/Portfile
===================================================================
--- trunk/dports/mail/mutt-devel/Portfile	(revision 15434)
+++ trunk/dports/mail/mutt-devel/Portfile	(revision 15438)
@@ -1,3 +1,3 @@
-# $Id: Portfile,v 1.27 2005/10/11 12:22:25 yeled Exp $
+# $Id: Portfile,v 1.28 2005/12/12 04:45:59 yeled Exp $
 
 PortSystem 1.0
@@ -165,10 +165,10 @@
 		configure.args-append --enable-smtp
 		if {[variant_isset cvs]} {
-				patchfiles-append	patch-cvs20051003.bc.smtp
+				patchfiles-append	patch-cvs20051112.bc.smtp
 		} else {
 				patch_sites-append	http://mutt.kublai.com/patches/
-				patchfiles-append	patch-1.5.11.bc.smtp.11
-				checksums-append	patch-1.5.11.bc.smtp.11 md5 \
-					cff0fcc448d66143ae699aacc1c7d2a8
+				patchfiles-append	patch-1.5.11.bc.smtp.13
+				checksums-append	patch-1.5.11.bc.smtp.13 md5 \
+					6b4cbad03a647ea5a903ffc5b1cecbb5
 				depends_build-append	port:autoconf
 		}
Index: trunk/dports/mail/mutt-devel/files/patch-cvs20051003.bc.smtp
===================================================================
--- trunk/dports/mail/mutt-devel/files/patch-cvs20051003.bc.smtp	(revision 15434)
+++ 	(revision )
@@ -1,882 +1,0 @@
-diff -r ad8150eee6fd Makefile.am
---- a/Makefile.am	Mon Oct  3 07:52:36 2005
-+++ b/Makefile.am	Mon Oct  3 20:18:16 2005
-@@ -61,7 +61,7 @@
- EXTRA_mutt_SOURCES = account.c md5c.c mutt_sasl.c mutt_socket.c mutt_ssl.c \
- 	mutt_tunnel.c pop.c pop_auth.c pop_lib.c smime.c pgp.c pgpinvoke.c pgpkey.c \
- 	pgplib.c sha1.c pgpmicalg.c gnupgparse.c resize.c dotlock.c remailer.c \
--	browser.h mbyte.h remailer.h url.h \
-+	smtp.c browser.h mbyte.h remailer.h url.h \
- 	crypt-mod-pgp-classic.c crypt-mod-smime-classic.c \
- 	pgppacket.c mutt_idna.h hcache.c mutt_ssl_gnutls.c \
- 	crypt-gpgme.c crypt-mod-pgp-gpgme.c crypt-mod-smime-gpgme.c
-diff -r ad8150eee6fd account.c
---- a/account.c	Mon Oct  3 07:52:36 2005
-+++ b/account.c	Mon Oct  3 20:18:16 2005
-@@ -123,6 +123,16 @@
-   }
- #endif
- 
-+#ifdef USE_SMTP
-+  if (account->type == M_ACCT_TYPE_SMTP)
-+  {
-+    if (account->flags & M_ACCT_SSL)
-+      url->scheme = U_SMTPS;
-+    else
-+      url->scheme = U_SMTP;
-+  }
-+#endif
-+
-   url->host = account->host;
-   if (account->flags & M_ACCT_PORT)
-     url->port = account->port;
-diff -r ad8150eee6fd account.h
---- a/account.h	Mon Oct  3 07:52:36 2005
-+++ b/account.h	Mon Oct  3 20:18:16 2005
-@@ -28,7 +28,8 @@
- {
-   M_ACCT_TYPE_NONE = 0,
-   M_ACCT_TYPE_IMAP,
--  M_ACCT_TYPE_POP
-+  M_ACCT_TYPE_POP,
-+  M_ACCT_TYPE_SMTP
- };
- 
- /* account flags */
-diff -r ad8150eee6fd configure.in
---- a/configure.in	Mon Oct  3 07:52:36 2005
-+++ b/configure.in	Mon Oct  3 20:18:16 2005
-@@ -516,6 +516,13 @@
-         fi
- ])
- AM_CONDITIONAL(BUILD_IMAP, test x$need_imap = xyes)
-+
-+AC_ARG_ENABLE(smtp, AC_HELP_STRING([--enable-smtp], [include internal SMTP relay support]),
-+	[if test $enableval = yes; then
-+		AC_DEFINE(USE_SMTP, 1, [Include internal SMTP relay support])
-+            	MUTT_LIB_OBJECTS="$MUTT_LIB_OBJECTS smtp.o"
-+		need_socket="yes"
-+	fi])
- 
- dnl -- end socket dependencies --
- 
-diff -r ad8150eee6fd globals.h
---- a/globals.h	Mon Oct  3 07:52:36 2005
-+++ b/globals.h	Mon Oct  3 20:18:16 2005
-@@ -112,6 +112,10 @@
- WHERE char *Shell;
- WHERE char *Signature;
- WHERE char *SimpleSearch;
-+#if USE_SMTP
-+WHERE char *SmtpUrl INITVAL (NULL);
-+WHERE char *SmtpAuthenticators INITVAL (NULL);
-+#endif /* USE_SMTP */
- WHERE char *Spoolfile;
- WHERE char *SpamSep;
- #if defined(USE_SSL) || defined(USE_GNUTLS)
-diff -r ad8150eee6fd init.h
---- a/init.h	Mon Oct  3 07:52:36 2005
-+++ b/init.h	Mon Oct  3 20:18:16 2005
-@@ -91,6 +91,9 @@
- # endif
- # ifndef USE_POP
- #  define USE_POP
-+# endif
-+# ifndef USE_SMTP
-+#  define USE_SMTP
- # endif
- # ifndef USE_SSL
- #  define USE_SSL
-@@ -2504,6 +2507,34 @@
-   ** messages from the current folder.  The default is to pause one second, so 
-   ** a value of zero for this option suppresses the pause.
-   */
-+#if USE_SMTP
-+  { "smtp_url",		DT_STR, R_NONE, UL &SmtpUrl, UL 0 },
-+  /*
-+  ** .pp
-+  ** Defines the SMTP ``smart'' host where sent messages should relayed for
-+  ** delivery. This should take the form of an SMTP URL, eg:
-+  ** .pp
-+  **   smtp[s]://[user[:pass]@]host[:port]/
-+  ** .pp
-+  ** Setting this variable overrides the value of the ``$$sendmail''
-+  ** variable.
-+  */
-+# ifdef USE_SASL
-+  { "smtp_authenticators", DT_STR, R_NONE, UL &SmtpAuthenticators, UL 0 },
-+  /*
-+   ** .pp
-+   ** This is a colon-delimited list of authentication methods mutt may
-+   ** attempt to use to log in to an SMTP server, in the order mutt should
-+   ** try them.  Authentication methods are any SASL mechanism, eg 
-+   ** 'digest-md5', 'gssapi' or 'cram-md5'.
-+   ** This parameter is case-insensitive. If this parameter is unset
-+   ** (the default) mutt will try all available methods, in order from
-+   ** most-secure to least-secure.
-+   ** .pp
-+   ** Example: set smtp_authenticators="digest-md5:cram-md5"
-+   */
-+# endif /* USE_SASL */
-+#endif /* USE_SMTP */
-   { "sort",		DT_SORT, R_INDEX|R_RESORT, UL &Sort, SORT_DATE },
-   /*
-   ** .pp
-diff -r ad8150eee6fd main.c
---- a/main.c	Mon Oct  3 07:52:36 2005
-+++ b/main.c	Mon Oct  3 20:18:16 2005
-@@ -257,6 +257,12 @@
-         "-USE_IMAP  "
- #endif
- 
-+#ifdef USE_SMTP
-+	"+USE_SMTP  "
-+#else
-+	"-USE_SMTP  "
-+#endif
-+
- #ifdef USE_GSS
- 	"+USE_GSS  "
- #else
-diff -r ad8150eee6fd mutt_sasl.c
---- a/mutt_sasl.c	Mon Oct  3 07:52:36 2005
-+++ b/mutt_sasl.c	Mon Oct  3 20:18:16 2005
-@@ -182,42 +182,44 @@
-     case M_ACCT_TYPE_POP:
-       service = "pop";
-       break;
-+    case M_ACCT_TYPE_SMTP:
-+      service = "smtp";
-+      break;
-     default:
--      dprint (1, (debugfile, "mutt_sasl_client_new: account type unset\n"));
-+      mutt_error (_("Unknown SASL profile"));
-       return -1;
-   }
- 
-   size = sizeof (local);
--  if (getsockname (conn->fd, (struct sockaddr *)&local, &size)){
--    dprint (1, (debugfile, "mutt_sasl_client_new: getsockname for local failed\n"));
-+  if (getsockname (conn->fd, (struct sockaddr *)&local, &size)) {
-+    mutt_error (_("SASL failed to get local IP address"));
-     return -1;
-   }
-   else 
--  if (iptostring((struct sockaddr *)&local, size, iplocalport, IP_PORT_BUFLEN) != SASL_OK){
--    dprint (1, (debugfile, "mutt_sasl_client_new: iptostring for local failed\n"));
-+  if (iptostring((struct sockaddr *)&local, size, iplocalport, IP_PORT_BUFLEN) != SASL_OK) {
-+    mutt_error (_("SASL failed to parse local IP address"));
-     return -1;
-   }
-   
-   size = sizeof (remote);
-   if (getpeername (conn->fd, (struct sockaddr *)&remote, &size)){
--    dprint (1, (debugfile, "mutt_sasl_client_new: getsockname for remote failed\n"));
-+    mutt_error (_("SASL failed to get remote IP address"));
-     return -1;
-   }
-   else 
-   if (iptostring((struct sockaddr *)&remote, size, ipremoteport, IP_PORT_BUFLEN) != SASL_OK){
--    dprint (1, (debugfile, "mutt_sasl_client_new: iptostring for remote failed\n"));
--    return -1;
--  }
--
--  dprint(1,(debugfile, "local ip: %s, remote ip:%s\n", iplocalport, ipremoteport));
-+    mutt_error (_("SASL failed to parse remote IP address"));
-+    return -1;
-+  }
-+
-+  dprint(2, (debugfile, "local ip: %s, remote ip:%s\n", iplocalport, ipremoteport));
-   
-   rc = sasl_client_new (service, conn->account.host, iplocalport, ipremoteport,
-     mutt_sasl_get_callbacks (&conn->account), 0, saslconn);
- 
-   if (rc != SASL_OK)
-   {
--    dprint (1, (debugfile,
--      "mutt_sasl_client_new: Error allocating SASL connection\n"));
-+    mutt_error (_("Error allocating SASL connection"));
-     return -1;
-   }
- 
-@@ -232,8 +234,7 @@
-   secprops.security_flags |= SASL_SEC_NOPLAINTEXT;
-   if (sasl_setprop (*saslconn, SASL_SEC_PROPS, &secprops) != SASL_OK)
-   {
--    dprint (1, (debugfile,
--      "mutt_sasl_client_new: Error setting security properties\n"));
-+    mutt_error (_("Error setting SASL security properties"));
-     return -1;
-   }
- 
-@@ -243,13 +244,13 @@
-     dprint (2, (debugfile, "External SSF: %d\n", conn->ssf));
-     if (sasl_setprop (*saslconn, SASL_SSF_EXTERNAL, &(conn->ssf)) != SASL_OK)
-     {
--      dprint (1, (debugfile, "mutt_sasl_client_new: Error setting external properties\n"));
-+      mutt_error (_("Error setting SASL external security strength"));
-       return -1;
-     }
-     dprint (2, (debugfile, "External authentication name: %s\n", conn->account.user));
-     if (sasl_setprop (*saslconn, SASL_AUTH_EXTERNAL, conn->account.user) != SASL_OK)
--     {
--      dprint (1, (debugfile, "mutt_sasl_client_new: Error setting external properties\n"));
-+    {
-+      mutt_error (_("Error setting SASL external user name"));
-       return -1;
-     }
-   }
-diff -r ad8150eee6fd mutt_socket.h
---- a/mutt_socket.h	Mon Oct  3 07:52:36 2005
-+++ b/mutt_socket.h	Mon Oct  3 20:18:16 2005
-@@ -56,7 +56,7 @@
- int mutt_socket_readchar (CONNECTION *conn, char *c);
- #define mutt_socket_readln(A,B,C) mutt_socket_readln_d(A,B,C,M_SOCK_LOG_CMD)
- int mutt_socket_readln_d (char *buf, size_t buflen, CONNECTION *conn, int dbg);
--#define mutt_socket_write(A,B) mutt_socket_write_d(A,B,M_SOCK_LOG_CMD);
-+#define mutt_socket_write(A,B) mutt_socket_write_d(A,B,M_SOCK_LOG_CMD)
- int mutt_socket_write_d (CONNECTION *conn, const char *buf, int dbg);
- 
- /* stupid hack for imap_logout_all */
-diff -r ad8150eee6fd protos.h
---- a/protos.h	Mon Oct  3 07:52:36 2005
-+++ b/protos.h	Mon Oct  3 20:18:16 2005
-@@ -342,6 +342,10 @@
- int _mutt_save_message (HEADER *, CONTEXT *, int, int, int);
- int mutt_save_message (HEADER *, int, int, int, int *);
- int mutt_search_command (int, int);
-+#ifdef USE_SMTP
-+int mutt_smtp_send (const ADDRESS *, const ADDRESS *, const ADDRESS *,
-+                    const ADDRESS *, const char *, int);
-+#endif
- int mutt_strwidth (const char *);
- int mutt_compose_menu (HEADER *, char *, size_t, HEADER *);
- int mutt_thread_set_flag (HEADER *, int, int, int);
-diff -r ad8150eee6fd send.c
---- a/send.c	Mon Oct  3 07:52:36 2005
-+++ b/send.c	Mon Oct  3 20:18:16 2005
-@@ -996,8 +996,16 @@
-     return mix_send_message (msg->chain, tempfile);
- #endif
- 
-+#if USE_SMTP
-+  if (SmtpUrl)
-+      return mutt_smtp_send (msg->env->from, msg->env->to, msg->env->cc,
-+                             msg->env->bcc, tempfile,
-+                             (msg->content->encoding == ENC8BIT));
-+#endif /* USE_SMTP */
-+
-   i = mutt_invoke_sendmail (msg->env->from, msg->env->to, msg->env->cc, 
--			    msg->env->bcc, tempfile, (msg->content->encoding == ENC8BIT));
-+			    msg->env->bcc, tempfile,
-+                            (msg->content->encoding == ENC8BIT));
-   return (i);
- }
- 
-diff -r ad8150eee6fd sendlib.c
---- a/sendlib.c	Mon Oct  3 07:52:36 2005
-+++ b/sendlib.c	Mon Oct  3 20:18:16 2005
-@@ -2178,6 +2178,12 @@
-     mutt_copy_bytes (fp, f, h->content->length);
-     fclose (f);
- 
-+#if USE_SMTP
-+    if (SmtpUrl)
-+      ret = mutt_smtp_send (env_from, to, NULL, NULL, tempfile,
-+                            h->content->encoding == ENC8BIT);
-+    else
-+#endif /* USE_SMTP */
-     ret = mutt_invoke_sendmail (env_from, to, NULL, NULL, tempfile,
- 			  	h->content->encoding == ENC8BIT);
-   }
-diff -r ad8150eee6fd url.c
---- a/url.c	Mon Oct  3 07:52:36 2005
-+++ b/url.c	Mon Oct  3 20:18:16 2005
-@@ -37,10 +37,12 @@
-   { "file", 	U_FILE },
-   { "imap", 	U_IMAP },
-   { "imaps", 	U_IMAPS },
--  { "pop",  	U_POP  },
--  { "pops", 	U_POPS  },
-+  { "pop",  	U_POP },
-+  { "pops", 	U_POPS },
-   { "mailto",	U_MAILTO },
--  { NULL,	U_UNKNOWN}
-+  { "smtp",     U_SMTP },
-+  { "smtps",    U_SMTPS },
-+  { NULL,	U_UNKNOWN }
- };
- 
- 
-diff -r ad8150eee6fd url.h
---- a/url.h	Mon Oct  3 07:52:36 2005
-+++ b/url.h	Mon Oct  3 20:18:16 2005
-@@ -8,6 +8,8 @@
-   U_POPS,
-   U_IMAP,
-   U_IMAPS,
-+  U_SMTP,
-+  U_SMTPS,
-   U_MAILTO,
-   U_UNKNOWN
- }
-diff -r ad8150eee6fd smtp.c
---- /dev/null	Mon Oct  3 07:52:36 2005
-+++ b/smtp.c	Mon Oct  3 20:18:16 2005
-@@ -0,0 +1,556 @@
-+/* mutt - text oriented MIME mail user agent
-+ * Copyright (C) 2002 Michael R. Elkins <me@mutt.org>
-+ * Copyright (C) 2005 Brendan Cully <brendan@kublai.com>
-+ * 
-+ *     This program is free software; you can redistribute it and/or modify
-+ *     it under the terms of the GNU General Public License as published by
-+ *     the Free Software Foundation; either version 2 of the License, or
-+ *     (at your option) any later version.
-+ * 
-+ *     This program is distributed in the hope that it will be useful,
-+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ *     GNU General Public License for more details.
-+ * 
-+ *     You should have received a copy of the GNU General Public License
-+ *     along with this program; if not, write to the Free Software
-+ *     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
-+ */
-+
-+/* This file contains code for direct SMTP delivery of email messages. */
-+
-+#if HAVE_CONFIG_H
-+#include "config.h"
-+#endif
-+
-+#include "mutt.h"
-+#include "mutt_curses.h"
-+#include "mutt_socket.h"
-+#if defined(USE_SSL) || defined(USE_GNUTLS)
-+# include "mutt_ssl.h"
-+#endif
-+#ifdef USE_SASL
-+#include "mutt_sasl.h"
-+
-+#include <sasl/sasl.h>
-+#include <sasl/saslutil.h>
-+#endif
-+
-+#include <netdb.h>
-+#include <stdio.h>
-+#include <sys/stat.h>
-+
-+#define smtp_success(x) ((x)/100 == 2)
-+#define smtp_ready 334
-+#define smtp_continue 354
-+
-+#define smtp_err_read -2
-+#define smtp_err_write -3
-+
-+#define SMTP_PORT 25
-+#define SMTPS_PORT 465
-+
-+#define SMTP_AUTH_SUCCESS 0
-+#define SMTP_AUTH_UNAVAIL 1
-+#define SMTP_AUTH_FAIL    -1
-+
-+enum {
-+  STARTTLS,
-+  AUTH,
-+  DSN,
-+  EIGHTBITMIME,
-+
-+  CAPMAX
-+};
-+
-+#ifdef USE_SASL
-+static int smtp_auth (CONNECTION* conn);
-+static int smtp_auth_sasl (CONNECTION* conn, const char* mechanisms);
-+#endif
-+
-+static int smtp_fill_account (ACCOUNT* account);
-+static int smtp_open (CONNECTION* conn);
-+
-+static int Esmtp = 0;
-+static char* AuthMechs = NULL;
-+static unsigned char Capabilities[(CAPMAX + 7)/ 8];
-+
-+/* Reads a command response from the SMTP server.
-+ * Returns:
-+ * 0	on success (2xx code) or continue (354 code)
-+ * -1	write error, or any other response code
-+ */
-+static int
-+smtp_get_resp (CONNECTION * conn)
-+{
-+  int n;
-+  char buf[1024];
-+
-+  do {
-+    n = mutt_socket_readln (buf, sizeof (buf), conn);
-+    if (n == -1)
-+      return smtp_err_read;
-+    n = atoi (buf);
-+
-+    if (!ascii_strncasecmp ("8BITMIME", buf + 4, 8))
-+      mutt_bit_set (Capabilities, EIGHTBITMIME);
-+    else if (!ascii_strncasecmp ("AUTH", buf + 4, 4))
-+    {
-+      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);
-+  } while (buf[3] == '-');
-+
-+  if (smtp_success (n) || n == smtp_continue)
-+    return 0;
-+
-+  mutt_error (_("SMTP session failed: %s"), buf);
-+    return -1;
-+}
-+
-+static int
-+smtp_rcpt_to (CONNECTION * conn, const ADDRESS * a)
-+{
-+  char buf[1024];
-+  int r;
-+
-+  while (a)
-+  {
-+    if (mutt_bit_isset (Capabilities, DSN) && DsnNotify)
-+      snprintf (buf, sizeof (buf), "RCPT TO:<%s> NOTIFY=%s\r\n",
-+                a->mailbox, DsnNotify);
-+    else
-+      snprintf (buf, sizeof (buf), "RCPT TO:<%s>\r\n", a->mailbox);
-+    if (mutt_socket_write (conn, buf) == -1)
-+      return smtp_err_write;
-+    if ((r = smtp_get_resp (conn)))
-+      return r;
-+    a = a->next;
-+  }
-+
-+  return 0;
-+}
-+
-+static int
-+smtp_data (CONNECTION * conn, const char *msgfile)
-+{
-+  char buf[1024];
-+  FILE *fp = 0;
-+  progress_t progress;
-+  struct stat st;
-+  int r;
-+  size_t buflen;
-+
-+  fp = fopen (msgfile, "r");
-+  if (!fp)
-+  {
-+    mutt_error ("SMTP session failed: unable to open %s", msgfile);
-+    return -1;
-+  }
-+  stat (msgfile, &st);
-+  progress.msg = _("Sending message...");
-+  progress.size = st.st_size;
-+  mutt_progress_bar (&progress, 0);
-+  
-+  snprintf (buf, sizeof (buf), "DATA\r\n");
-+  if (mutt_socket_write (conn, buf) == -1)
-+  {
-+    fclose (fp);
-+    return smtp_err_write;
-+  }
-+  if ((r = smtp_get_resp (conn)))
-+  {
-+    fclose (fp);
-+    return r;
-+  }
-+  
-+  while (fgets (buf, sizeof (buf) - 1, fp))
-+  {
-+    buflen = mutt_strlen (buf);
-+    if (buflen && buf[buflen-1] == '\n'
-+	&& (buflen == 1 || buf[buflen - 2] != '\r'))
-+      snprintf (buf + buflen - 1, sizeof (buf) - buflen + 1, "\r\n");
-+    if (buf[0] == '.')
-+    {
-+      if (mutt_socket_write_d (conn, ".", 3) == -1)
-+      {
-+        fclose (fp);
-+        return smtp_err_write;
-+      }
-+    }
-+    if (mutt_socket_write_d (conn, buf, 3) == -1)
-+    {
-+      fclose (fp);
-+      return smtp_err_write;
-+    }
-+
-+    mutt_progress_bar (&progress, ftell (fp));
-+  }
-+  fclose (fp);
-+
-+  /* terminate the message body */
-+  if (mutt_socket_write (conn, ".\r\n") == -1)
-+    return smtp_err_write;
-+
-+  if ((r = smtp_get_resp (conn)))
-+    return r;
-+
-+  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;
-+  int ret = -1;
-+  char buf[1024];
-+
-+  if (smtp_fill_account (&account) < 0)
-+    return ret;
-+
-+  if (!(conn = mutt_conn_find (NULL, &account)))
-+    return -1;
-+
-+  Esmtp = eightbit;
-+
-+  do
-+  {
-+    /* send our greeting */
-+    if (( ret = smtp_open (conn)))
-+      break;
-+    FREE (&AuthMechs);
-+
-+    /* send the sender's address */
-+    ret = snprintf (buf, sizeof (buf), "MAIL FROM:<%s>",
-+                    EnvFrom ? EnvFrom->mailbox : from->mailbox);
-+    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);
-+    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;
-+
-+    /* send the recipient list */
-+    if ((ret = smtp_rcpt_to (conn, to)) || (ret = smtp_rcpt_to (conn, cc))
-+        || (ret = smtp_rcpt_to (conn, bcc)))
-+      break;
-+
-+    /* send the message data */
-+    if ((ret = smtp_data (conn, msgfile)))
-+      break;
-+
-+    mutt_socket_write (conn, "QUIT\r\n");
-+
-+    ret = 0;
-+  }
-+  while (0);
-+
-+  if (conn)
-+    mutt_socket_close (conn);
-+
-+  if (ret == smtp_err_read)
-+    mutt_error (_("SMTP session failed: read error"));
-+  else if (ret == smtp_err_write)
-+    mutt_error (_("SMTP session failed: write error"));
-+
-+  return ret;
-+}
-+
-+static int smtp_fill_account (ACCOUNT* account)
-+{
-+  static unsigned short SmtpPort = 0;
-+
-+  struct servent* service;
-+  ciss_url_t url;
-+  char* urlstr;
-+
-+  account->flags = 0;
-+  account->port = 0;
-+  account->type = M_ACCT_TYPE_SMTP;
-+
-+  urlstr = safe_strdup (SmtpUrl);
-+  url_parse_ciss (&url, urlstr);
-+  if ((url.scheme != U_SMTP && url.scheme != U_SMTPS)
-+      || mutt_account_fromurl (account, &url) < 0)
-+  {
-+    FREE (&urlstr);
-+    mutt_error (_("Invalid SMTP URL: %s"), SmtpUrl);
-+    mutt_sleep (1);
-+    return -1;
-+  }
-+  FREE (&urlstr);
-+  
-+  if (url.scheme == U_SMTPS)
-+    account->flags |= M_ACCT_SSL;
-+
-+  if (!account->port)
-+  {
-+    if (account->flags & M_ACCT_SSL)
-+      account->port = SMTPS_PORT;
-+    else
-+    {
-+      if (!SmtpPort)
-+      {
-+        service = getservbyname ("smtp", "tcp");
-+        if (service)
-+          SmtpPort = ntohs (service->s_port);
-+        else
-+          SmtpPort = SMTP_PORT;
-+        dprint (3, (debugfile, "Using default SMTP port %d\n", SmtpPort));
-+      }
-+      account->port = SmtpPort;
-+    }
-+  }
-+
-+  return 0;
-+}
-+
-+static int smtp_helo (CONNECTION* conn)
-+{
-+  char buf[LONG_STRING];
-+
-+  memset (Capabilities, 0, sizeof (Capabilities));
-+
-+  if (!Esmtp)
-+  {
-+    /* if TLS or AUTH are requested, use EHLO */
-+    if (conn->account.flags & M_ACCT_USER)
-+      Esmtp = 1;
-+#if defined(USE_SSL) || defined(USE_GNUTLS)
-+    if (option (OPTSSLFORCETLS) || quadoption (OPT_SSLSTARTTLS) != M_NO)
-+      Esmtp = 1;
-+#endif
-+  }
-+
-+  snprintf (buf, sizeof (buf), "%s %s\r\n", Esmtp ? "EHLO" : "HELO", Fqdn);
-+  /* XXX there should probably be a wrapper in mutt_socket.c that
-+    * repeatedly calls conn->write until all data is sent.  This
-+    * currently doesn't check for a short write.
-+    */
-+  if (mutt_socket_write (conn, buf) == -1)
-+    return smtp_err_write;
-+  return smtp_get_resp (conn);
-+}
-+
-+static int smtp_open (CONNECTION* conn)
-+{
-+  int rc;
-+
-+  if (mutt_socket_open (conn))
-+    return -1;
-+
-+  /* get greeting string */
-+  if ((rc = smtp_get_resp (conn)))
-+    return rc;
-+  
-+  if ((rc = smtp_helo (conn)))
-+    return rc;
-+
-+#if defined(USE_SSL) || defined(USE_GNUTLS)
-+  if (conn->ssf)
-+    rc = M_NO;
-+  else if (option (OPTSSLFORCETLS))
-+    rc = M_YES;
-+  else if (mutt_bit_isset (Capabilities, STARTTLS) &&
-+           (rc = query_quadoption (OPT_SSLSTARTTLS,
-+                                   _("Secure connection with TLS?"))) == -1)
-+    return rc;
-+  
-+  if (rc == M_YES)
-+  {
-+    if (mutt_socket_write (conn, "STARTTLS\r\n") < 0)
-+      return smtp_err_write;
-+    if ((rc = smtp_get_resp (conn)))
-+      return rc;
-+    
-+#ifdef USE_SSL
-+    if (mutt_ssl_starttls (conn))
-+#elif USE_GNUTLS
-+    if (mutt_gnutls_starttls (conn))
-+#endif
-+    {
-+      mutt_error (_("Could not negotiate TLS connection"));
-+      mutt_sleep (1);
-+      return -1;
-+    }
-+
-+    /* re-EHLO to get authentication mechanisms */
-+    if ((rc = smtp_helo (conn)))
-+      return rc;
-+  }
-+#endif
-+
-+  if (conn->account.flags & M_ACCT_USER)
-+  {
-+    if (!mutt_bit_isset (Capabilities, AUTH))
-+    {
-+      mutt_error (_("SMTP server does not support authentication"));
-+      mutt_sleep (1);
-+      return -1;
-+    }
-+
-+#ifdef USE_SASL
-+    return smtp_auth (conn);
-+#else
-+    mutt_error (_("SMTP authentication requires SASL"));
-+    mutt_sleep (1);
-+    return -1;
-+#endif /* USE_SASL */
-+  }
-+
-+  return 0;
-+}
-+
-+#ifdef USE_SASL
-+static int smtp_auth (CONNECTION* conn)
-+{
-+  int r = SMTP_AUTH_UNAVAIL;
-+
-+  if (SmtpAuthenticators && *SmtpAuthenticators)
-+  {
-+    char* methods = safe_strdup (SmtpAuthenticators);
-+    char* method;
-+    char* delim;
-+
-+    for (method = methods; method; method = delim)
-+    {
-+      delim = strchr (method, ':');
-+      if (delim)
-+	*delim++ = '\0';
-+      if (! method[0])
-+	continue;
-+      
-+      dprint (2, (debugfile, "smtp_authenticate: Trying method %s\n", method));
-+
-+      if ((r = smtp_auth_sasl (conn, method)) != SMTP_AUTH_UNAVAIL)
-+        break;
-+    }
-+
-+    FREE (&methods);
-+  }
-+  else
-+    r = smtp_auth_sasl (conn, AuthMechs);
-+  
-+  if (r == SMTP_AUTH_UNAVAIL)
-+  {
-+    mutt_error (_("No authenticators available"));
-+    mutt_sleep (1);
-+  }
-+  
-+  return r == SMTP_AUTH_SUCCESS ? 0 : -1;
-+}
-+
-+static int smtp_auth_sasl (CONNECTION* conn, const char* mechlist)
-+{
-+  sasl_conn_t* saslconn;
-+  sasl_interact_t* interaction = NULL;
-+  const char* mech;
-+  const char* data = NULL;
-+  unsigned int len;
-+  char buf[HUGE_STRING];
-+  int rc, saslrc;
-+
-+  if (mutt_sasl_client_new (conn, &saslconn) < 0)
-+    return SMTP_AUTH_FAIL;
-+
-+  do
-+  {
-+    rc = sasl_client_start (saslconn, mechlist, &interaction, &data, &len, &mech);
-+    if (rc == SASL_INTERACT)
-+      mutt_sasl_interact (interaction);
-+  }
-+  while (rc == SASL_INTERACT);
-+
-+  if (rc != SASL_OK && rc != SASL_CONTINUE)
-+  {
-+    dprint (2, (debugfile, "smtp_auth_sasl: %s unavailable\n", mech));
-+    sasl_dispose (&saslconn);
-+    return SMTP_AUTH_UNAVAIL;
-+  }
-+  
-+  mutt_message (_("Authenticating (%s)..."), mech);
-+
-+  snprintf (buf, sizeof (buf), "AUTH %s", mech);
-+  if (len)
-+  {
-+    strncat (buf, " ", sizeof (buf));
-+    if (sasl_encode64 (data, len, buf + mutt_strlen (buf),
-+                       sizeof (buf) - mutt_strlen (buf), &len) != SASL_OK)
-+    {
-+      dprint (1, (debugfile, "smtp_auth_sasl: error base64-encoding client response.\n"));
-+      goto fail;
-+    }
-+  }
-+  strncat (buf, "\r\n", sizeof (buf));
-+
-+  do {
-+    if (mutt_socket_write (conn, buf) < 0)
-+      goto fail;
-+    if (mutt_socket_readln (buf, sizeof (buf), conn) < 0)
-+      goto fail;
-+    rc = atoi(buf);
-+    
-+    if (rc != smtp_ready)
-+      break;
-+
-+    if (sasl_decode64 (buf+4, strlen (buf+4), buf, sizeof (buf), &len) != SASL_OK)
-+    {
-+      dprint (1, (debugfile, "smtp_auth_sasl: error base64-decoding server response.\n"));
-+      goto fail;
-+    }
-+
-+    do
-+    {
-+      saslrc = sasl_client_step (saslconn, buf, len, &interaction, &data, &len);
-+      if (saslrc == SASL_INTERACT)
-+        mutt_sasl_interact (interaction);
-+    }
-+    while (saslrc == SASL_INTERACT);
-+
-+    if (len)
-+    {
-+      if (sasl_encode64 (data, len, buf, sizeof (buf), &len) != SASL_OK)
-+      {
-+        dprint (1, (debugfile, "smtp_auth_sasl: error base64-encoding client response.\n"));
-+        goto fail;
-+      }
-+    }
-+    strfcpy (buf + len, "\r\n", sizeof (buf) - len);
-+  } while (rc == smtp_ready);
-+
-+  if (smtp_success (rc))
-+  {
-+    mutt_sasl_setup_conn (conn, saslconn);
-+    return SMTP_AUTH_SUCCESS;
-+  }
-+  else if (SmtpAuthenticators && *SmtpAuthenticators)
-+  {
-+    /* if we're given a mech list to attempt, failure means try the next */
-+    dprint (2, (debugfile, "smtp_auth_sasl: %s failed\n", mech));
-+    sasl_dispose (&saslconn);
-+    return SMTP_AUTH_UNAVAIL;
-+  }
-+
-+fail:
-+  mutt_error (_("SASL authentication failed"));
-+  mutt_sleep (1);
-+  sasl_dispose (&saslconn);
-+  return SMTP_AUTH_FAIL;
-+}
-+#endif /* USE_SASL */
Index: trunk/dports/mail/mutt-devel/files/patch-cvs20051112.bc.smtp
===================================================================
--- trunk/dports/mail/mutt-devel/files/patch-cvs20051112.bc.smtp	(revision 15438)
+++ trunk/dports/mail/mutt-devel/files/patch-cvs20051112.bc.smtp	(revision 15438)
@@ -0,0 +1,934 @@
+diff -r ede30c9816d5 Makefile.am
+--- a/Makefile.am	Sat Nov 12 06:45:36 2005
++++ b/Makefile.am	Sat Nov 12 10:33:03 2005
+@@ -61,7 +61,7 @@
+ EXTRA_mutt_SOURCES = account.c md5c.c mutt_sasl.c mutt_socket.c mutt_ssl.c \
+ 	mutt_tunnel.c pop.c pop_auth.c pop_lib.c smime.c pgp.c pgpinvoke.c pgpkey.c \
+ 	pgplib.c sha1.c pgpmicalg.c gnupgparse.c resize.c dotlock.c remailer.c \
+-	browser.h mbyte.h remailer.h url.h \
++	smtp.c browser.h mbyte.h remailer.h url.h \
+ 	crypt-mod-pgp-classic.c crypt-mod-smime-classic.c \
+ 	pgppacket.c mutt_idna.h hcache.c mutt_ssl_gnutls.c \
+ 	crypt-gpgme.c crypt-mod-pgp-gpgme.c crypt-mod-smime-gpgme.c
+diff -r ede30c9816d5 account.c
+--- a/account.c	Sat Nov 12 06:45:36 2005
++++ b/account.c	Sat Nov 12 10:33:03 2005
+@@ -123,6 +123,16 @@
+   }
+ #endif
+ 
++#ifdef USE_SMTP
++  if (account->type == M_ACCT_TYPE_SMTP)
++  {
++    if (account->flags & M_ACCT_SSL)
++      url->scheme = U_SMTPS;
++    else
++      url->scheme = U_SMTP;
++  }
++#endif
++
+   url->host = account->host;
+   if (account->flags & M_ACCT_PORT)
+     url->port = account->port;
+diff -r ede30c9816d5 account.h
+--- a/account.h	Sat Nov 12 06:45:36 2005
++++ b/account.h	Sat Nov 12 10:33:03 2005
+@@ -28,7 +28,8 @@
+ {
+   M_ACCT_TYPE_NONE = 0,
+   M_ACCT_TYPE_IMAP,
+-  M_ACCT_TYPE_POP
++  M_ACCT_TYPE_POP,
++  M_ACCT_TYPE_SMTP
+ };
+ 
+ /* account flags */
+diff -r ede30c9816d5 configure.in
+--- a/configure.in	Sat Nov 12 06:45:36 2005
++++ b/configure.in	Sat Nov 12 10:33:03 2005
+@@ -514,6 +514,13 @@
+         fi
+ ])
+ AM_CONDITIONAL(BUILD_IMAP, test x$need_imap = xyes)
++
++AC_ARG_ENABLE(smtp, AC_HELP_STRING([--enable-smtp], [include internal SMTP relay support]),
++	[if test $enableval = yes; then
++		AC_DEFINE(USE_SMTP, 1, [Include internal SMTP relay support])
++            	MUTT_LIB_OBJECTS="$MUTT_LIB_OBJECTS smtp.o"
++		need_socket="yes"
++	fi])
+ 
+ dnl -- end socket dependencies --
+ 
+diff -r ede30c9816d5 globals.h
+--- a/globals.h	Sat Nov 12 06:45:36 2005
++++ b/globals.h	Sat Nov 12 10:33:03 2005
+@@ -112,6 +112,10 @@
+ WHERE char *Shell;
+ WHERE char *Signature;
+ WHERE char *SimpleSearch;
++#if USE_SMTP
++WHERE char *SmtpUrl INITVAL (NULL);
++WHERE char *SmtpAuthenticators INITVAL (NULL);
++#endif /* USE_SMTP */
+ WHERE char *Spoolfile;
+ WHERE char *SpamSep;
+ #if defined(USE_SSL) || defined(USE_GNUTLS)
+diff -r ede30c9816d5 init.h
+--- a/init.h	Sat Nov 12 06:45:36 2005
++++ b/init.h	Sat Nov 12 10:33:03 2005
+@@ -91,6 +91,9 @@
+ # endif
+ # ifndef USE_POP
+ #  define USE_POP
++# endif
++# ifndef USE_SMTP
++#  define USE_SMTP
+ # endif
+ # ifndef USE_SSL
+ #  define USE_SSL
+@@ -2507,6 +2510,34 @@
+   ** messages from the current folder.  The default is to pause one second, so 
+   ** a value of zero for this option suppresses the pause.
+   */
++#if USE_SMTP
++  { "smtp_url",		DT_STR, R_NONE, UL &SmtpUrl, UL 0 },
++  /*
++  ** .pp
++  ** Defines the SMTP ``smart'' host where sent messages should relayed for
++  ** delivery. This should take the form of an SMTP URL, eg:
++  ** .pp
++  **   smtp[s]://[user[:pass]@]host[:port]/
++  ** .pp
++  ** Setting this variable overrides the value of the ``$$sendmail''
++  ** variable.
++  */
++# ifdef USE_SASL
++  { "smtp_authenticators", DT_STR, R_NONE, UL &SmtpAuthenticators, UL 0 },
++  /*
++   ** .pp
++   ** This is a colon-delimited list of authentication methods mutt may
++   ** attempt to use to log in to an SMTP server, in the order mutt should
++   ** try them.  Authentication methods are any SASL mechanism, eg
++   ** 'digest-md5', 'gssapi' or 'cram-md5'.
++   ** This parameter is case-insensitive. If this parameter is unset
++   ** (the default) mutt will try all available methods, in order from
++   ** most-secure to least-secure.
++   ** .pp
++   ** Example: set smtp_authenticators="digest-md5:cram-md5"
++   */
++# endif /* USE_SASL */
++#endif /* USE_SMTP */
+   { "sort",		DT_SORT, R_INDEX|R_RESORT, UL &Sort, SORT_DATE },
+   /*
+   ** .pp
+@@ -2902,7 +2933,10 @@
+   /*
+   ** .pp
+   ** Controls whether mutt writes out the Bcc header when preparing
+-  ** messages to be sent.  Exim users may wish to unset this.
++  ** messages to be sent.  Exim users may wish to unset this. If mutt
++  ** is set to deliver directly via SMTP (see ``$$smtp_url''), this
++  ** option does nothing: mutt will never write out the BCC header
++  ** in this case.
+   */
+   /*--*/
+   { NULL }
+diff -r ede30c9816d5 main.c
+--- a/main.c	Sat Nov 12 06:45:36 2005
++++ b/main.c	Sat Nov 12 10:33:03 2005
+@@ -257,6 +257,12 @@
+         "-USE_IMAP  "
+ #endif
+ 
++#ifdef USE_SMTP
++	"+USE_SMTP  "
++#else
++	"-USE_SMTP  "
++#endif
++
+ #ifdef USE_GSS
+ 	"+USE_GSS  "
+ #else
+diff -r ede30c9816d5 mutt_sasl.c
+--- a/mutt_sasl.c	Sat Nov 12 06:45:36 2005
++++ b/mutt_sasl.c	Sat Nov 12 10:33:03 2005
+@@ -182,42 +182,44 @@
+     case M_ACCT_TYPE_POP:
+       service = "pop";
+       break;
++    case M_ACCT_TYPE_SMTP:
++      service = "smtp";
++      break;
+     default:
+-      dprint (1, (debugfile, "mutt_sasl_client_new: account type unset\n"));
++      mutt_error (_("Unknown SASL profile"));
+       return -1;
+   }
+ 
+   size = sizeof (local);
+-  if (getsockname (conn->fd, (struct sockaddr *)&local, &size)){
+-    dprint (1, (debugfile, "mutt_sasl_client_new: getsockname for local failed\n"));
++  if (getsockname (conn->fd, (struct sockaddr *)&local, &size)) {
++    mutt_error (_("SASL failed to get local IP address"));
+     return -1;
+   }
+   else 
+-  if (iptostring((struct sockaddr *)&local, size, iplocalport, IP_PORT_BUFLEN) != SASL_OK){
+-    dprint (1, (debugfile, "mutt_sasl_client_new: iptostring for local failed\n"));
++  if (iptostring((struct sockaddr *)&local, size, iplocalport, IP_PORT_BUFLEN) != SASL_OK) {
++    mutt_error (_("SASL failed to parse local IP address"));
+     return -1;
+   }
+   
+   size = sizeof (remote);
+   if (getpeername (conn->fd, (struct sockaddr *)&remote, &size)){
+-    dprint (1, (debugfile, "mutt_sasl_client_new: getsockname for remote failed\n"));
++    mutt_error (_("SASL failed to get remote IP address"));
+     return -1;
+   }
+   else 
+   if (iptostring((struct sockaddr *)&remote, size, ipremoteport, IP_PORT_BUFLEN) != SASL_OK){
+-    dprint (1, (debugfile, "mutt_sasl_client_new: iptostring for remote failed\n"));
+-    return -1;
+-  }
+-
+-  dprint(1,(debugfile, "local ip: %s, remote ip:%s\n", iplocalport, ipremoteport));
++    mutt_error (_("SASL failed to parse remote IP address"));
++    return -1;
++  }
++
++  dprint(2, (debugfile, "local ip: %s, remote ip:%s\n", iplocalport, ipremoteport));
+   
+   rc = sasl_client_new (service, conn->account.host, iplocalport, ipremoteport,
+     mutt_sasl_get_callbacks (&conn->account), 0, saslconn);
+ 
+   if (rc != SASL_OK)
+   {
+-    dprint (1, (debugfile,
+-      "mutt_sasl_client_new: Error allocating SASL connection\n"));
++    mutt_error (_("Error allocating SASL connection"));
+     return -1;
+   }
+ 
+@@ -232,8 +234,7 @@
+   secprops.security_flags |= SASL_SEC_NOPLAINTEXT;
+   if (sasl_setprop (*saslconn, SASL_SEC_PROPS, &secprops) != SASL_OK)
+   {
+-    dprint (1, (debugfile,
+-      "mutt_sasl_client_new: Error setting security properties\n"));
++    mutt_error (_("Error setting SASL security properties"));
+     return -1;
+   }
+ 
+@@ -243,13 +244,13 @@
+     dprint (2, (debugfile, "External SSF: %d\n", conn->ssf));
+     if (sasl_setprop (*saslconn, SASL_SSF_EXTERNAL, &(conn->ssf)) != SASL_OK)
+     {
+-      dprint (1, (debugfile, "mutt_sasl_client_new: Error setting external properties\n"));
++      mutt_error (_("Error setting SASL external security strength"));
+       return -1;
+     }
+     dprint (2, (debugfile, "External authentication name: %s\n", conn->account.user));
+     if (sasl_setprop (*saslconn, SASL_AUTH_EXTERNAL, conn->account.user) != SASL_OK)
+-     {
+-      dprint (1, (debugfile, "mutt_sasl_client_new: Error setting external properties\n"));
++    {
++      mutt_error (_("Error setting SASL external user name"));
+       return -1;
+     }
+   }
+diff -r ede30c9816d5 mutt_socket.h
+--- a/mutt_socket.h	Sat Nov 12 06:45:36 2005
++++ b/mutt_socket.h	Sat Nov 12 10:33:03 2005
+@@ -56,7 +56,7 @@
+ int mutt_socket_readchar (CONNECTION *conn, char *c);
+ #define mutt_socket_readln(A,B,C) mutt_socket_readln_d(A,B,C,M_SOCK_LOG_CMD)
+ int mutt_socket_readln_d (char *buf, size_t buflen, CONNECTION *conn, int dbg);
+-#define mutt_socket_write(A,B) mutt_socket_write_d(A,B,M_SOCK_LOG_CMD);
++#define mutt_socket_write(A,B) mutt_socket_write_d(A,B,M_SOCK_LOG_CMD)
+ int mutt_socket_write_d (CONNECTION *conn, const char *buf, int dbg);
+ 
+ /* stupid hack for imap_logout_all */
+diff -r ede30c9816d5 protos.h
+--- a/protos.h	Sat Nov 12 06:45:36 2005
++++ b/protos.h	Sat Nov 12 10:33:03 2005
+@@ -343,6 +343,10 @@
+ int _mutt_save_message (HEADER *, CONTEXT *, int, int, int);
+ int mutt_save_message (HEADER *, int, int, int, int *);
+ int mutt_search_command (int, int);
++#ifdef USE_SMTP
++int mutt_smtp_send (const ADDRESS *, const ADDRESS *, const ADDRESS *,
++                    const ADDRESS *, const char *, int);
++#endif
+ int mutt_strwidth (const char *);
+ int mutt_compose_menu (HEADER *, char *, size_t, HEADER *);
+ int mutt_thread_set_flag (HEADER *, int, int, int);
+diff -r ede30c9816d5 send.c
+--- a/send.c	Sat Nov 12 06:45:36 2005
++++ b/send.c	Sat Nov 12 10:33:03 2005
+@@ -962,18 +962,30 @@
+   char tempfile[_POSIX_PATH_MAX];
+   FILE *tempfp;
+   int i;
++#ifdef USE_SMTP
++  short old_write_bcc;
++#endif
+   
+   /* Write out the message in MIME form. */
+   mutt_mktemp (tempfile);
+   if ((tempfp = safe_fopen (tempfile, "w")) == NULL)
+     return (-1);
+ 
++#ifdef USE_SMTP
++  old_write_bcc = option (OPTWRITEBCC);
++  if (SmtpUrl)
++    unset_option (OPTWRITEBCC);
++#endif
+ #ifdef MIXMASTER
+   mutt_write_rfc822_header (tempfp, msg->env, msg->content, 0, msg->chain ? 1 : 0);
+ #endif
+ #ifndef MIXMASTER
+   mutt_write_rfc822_header (tempfp, msg->env, msg->content, 0, 0);
+ #endif
++#ifdef USE_SMTP
++  if (old_write_bcc)
++    set_option (OPTWRITEBCC);
++#endif
+   
+   fputc ('\n', tempfp); /* tie off the header. */
+ 
+@@ -996,8 +1008,16 @@
+     return mix_send_message (msg->chain, tempfile);
+ #endif
+ 
++#if USE_SMTP
++  if (SmtpUrl)
++      return mutt_smtp_send (msg->env->from, msg->env->to, msg->env->cc,
++                             msg->env->bcc, tempfile,
++                             (msg->content->encoding == ENC8BIT));
++#endif /* USE_SMTP */
++
+   i = mutt_invoke_sendmail (msg->env->from, msg->env->to, msg->env->cc, 
+-			    msg->env->bcc, tempfile, (msg->content->encoding == ENC8BIT));
++			    msg->env->bcc, tempfile,
++                            (msg->content->encoding == ENC8BIT));
+   return (i);
+ }
+ 
+diff -r ede30c9816d5 sendlib.c
+--- a/sendlib.c	Sat Nov 12 06:45:36 2005
++++ b/sendlib.c	Sat Nov 12 10:33:03 2005
+@@ -2178,6 +2178,12 @@
+     mutt_copy_bytes (fp, f, h->content->length);
+     fclose (f);
+ 
++#if USE_SMTP
++    if (SmtpUrl)
++      ret = mutt_smtp_send (env_from, to, NULL, NULL, tempfile,
++                            h->content->encoding == ENC8BIT);
++    else
++#endif /* USE_SMTP */
+     ret = mutt_invoke_sendmail (env_from, to, NULL, NULL, tempfile,
+ 			  	h->content->encoding == ENC8BIT);
+   }
+@@ -2428,7 +2434,7 @@
+     rewind (tempfp);
+     while (fgets (sasha, sizeof (sasha), tempfp) != NULL)
+       lines++;
+-    fprintf (msg->fp, "Content-Length: " OFF_T_FMT "\n", ftello (tempfp));
++    fprintf (msg->fp, "Content-Length: " OFF_T_FMT "\n", (LOFF_T) ftell (tempfp));
+     fprintf (msg->fp, "Lines: %d\n\n", lines);
+ 
+     /* copy the body and clean up */
+diff -r ede30c9816d5 url.c
+--- a/url.c	Sat Nov 12 06:45:36 2005
++++ b/url.c	Sat Nov 12 10:33:03 2005
+@@ -37,10 +37,12 @@
+   { "file", 	U_FILE },
+   { "imap", 	U_IMAP },
+   { "imaps", 	U_IMAPS },
+-  { "pop",  	U_POP  },
+-  { "pops", 	U_POPS  },
++  { "pop",  	U_POP },
++  { "pops", 	U_POPS },
+   { "mailto",	U_MAILTO },
+-  { NULL,	U_UNKNOWN}
++  { "smtp",     U_SMTP },
++  { "smtps",    U_SMTPS },
++  { NULL,	U_UNKNOWN }
+ };
+ 
+ 
+diff -r ede30c9816d5 url.h
+--- a/url.h	Sat Nov 12 06:45:36 2005
++++ b/url.h	Sat Nov 12 10:33:03 2005
+@@ -8,6 +8,8 @@
+   U_POPS,
+   U_IMAP,
+   U_IMAPS,
++  U_SMTP,
++  U_SMTPS,
+   U_MAILTO,
+   U_UNKNOWN
+ }
+diff -r ede30c9816d5 smtp.c
+--- /dev/null	Sat Nov 12 06:45:36 2005
++++ b/smtp.c	Sat Nov 12 10:33:03 2005
+@@ -0,0 +1,556 @@
++/* mutt - text oriented MIME mail user agent
++ * Copyright (C) 2002 Michael R. Elkins <me@mutt.org>
++ * Copyright (C) 2005 Brendan Cully <brendan@kublai.com>
++ *
++ *     This program is free software; you can redistribute it and/or modify
++ *     it under the terms of the GNU General Public License as published by
++ *     the Free Software Foundation; either version 2 of the License, or
++ *     (at your option) any later version.
++ *
++ *     This program is distributed in the hope that it will be useful,
++ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
++ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ *     GNU General Public License for more details.
++ *
++ *     You should have received a copy of the GNU General Public License
++ *     along with this program; if not, write to the Free Software
++ *     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
++ */
++
++/* This file contains code for direct SMTP delivery of email messages. */
++
++#if HAVE_CONFIG_H
++#include "config.h"
++#endif
++
++#include "mutt.h"
++#include "mutt_curses.h"
++#include "mutt_socket.h"
++#if defined(USE_SSL) || defined(USE_GNUTLS)
++# include "mutt_ssl.h"
++#endif
++#ifdef USE_SASL
++#include "mutt_sasl.h"
++
++#include <sasl/sasl.h>
++#include <sasl/saslutil.h>
++#endif
++
++#include <netdb.h>
++#include <stdio.h>
++#include <sys/stat.h>
++
++#define smtp_success(x) ((x)/100 == 2)
++#define smtp_ready 334
++#define smtp_continue 354
++
++#define smtp_err_read -2
++#define smtp_err_write -3
++
++#define SMTP_PORT 25
++#define SMTPS_PORT 465
++
++#define SMTP_AUTH_SUCCESS 0
++#define SMTP_AUTH_UNAVAIL 1
++#define SMTP_AUTH_FAIL    -1
++
++enum {
++  STARTTLS,
++  AUTH,
++  DSN,
++  EIGHTBITMIME,
++
++  CAPMAX
++};
++
++#ifdef USE_SASL
++static int smtp_auth (CONNECTION* conn);
++static int smtp_auth_sasl (CONNECTION* conn, const char* mechanisms);
++#endif
++
++static int smtp_fill_account (ACCOUNT* account);
++static int smtp_open (CONNECTION* conn);
++
++static int Esmtp = 0;
++static char* AuthMechs = NULL;
++static unsigned char Capabilities[(CAPMAX + 7)/ 8];
++
++/* Reads a command response from the SMTP server.
++ * Returns:
++ * 0	on success (2xx code) or continue (354 code)
++ * -1	write error, or any other response code
++ */
++static int
++smtp_get_resp (CONNECTION * conn)
++{
++  int n;
++  char buf[1024];
++
++  do {
++    n = mutt_socket_readln (buf, sizeof (buf), conn);
++    if (n == -1)
++      return smtp_err_read;
++    n = atoi (buf);
++
++    if (!ascii_strncasecmp ("8BITMIME", buf + 4, 8))
++      mutt_bit_set (Capabilities, EIGHTBITMIME);
++    else if (!ascii_strncasecmp ("AUTH", buf + 4, 4))
++    {
++      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);
++  } while (buf[3] == '-');
++
++  if (smtp_success (n) || n == smtp_continue)
++    return 0;
++
++  mutt_error (_("SMTP session failed: %s"), buf);
++    return -1;
++}
++
++static int
++smtp_rcpt_to (CONNECTION * conn, const ADDRESS * a)
++{
++  char buf[1024];
++  int r;
++
++  while (a)
++  {
++    if (mutt_bit_isset (Capabilities, DSN) && DsnNotify)
++      snprintf (buf, sizeof (buf), "RCPT TO:<%s> NOTIFY=%s\r\n",
++                a->mailbox, DsnNotify);
++    else
++      snprintf (buf, sizeof (buf), "RCPT TO:<%s>\r\n", a->mailbox);
++    if (mutt_socket_write (conn, buf) == -1)
++      return smtp_err_write;
++    if ((r = smtp_get_resp (conn)))
++      return r;
++    a = a->next;
++  }
++
++  return 0;
++}
++
++static int
++smtp_data (CONNECTION * conn, const char *msgfile)
++{
++  char buf[1024];
++  FILE *fp = 0;
++  progress_t progress;
++  struct stat st;
++  int r;
++  size_t buflen;
++
++  fp = fopen (msgfile, "r");
++  if (!fp)
++  {
++    mutt_error ("SMTP session failed: unable to open %s", msgfile);
++    return -1;
++  }
++  stat (msgfile, &st);
++  progress.msg = _("Sending message...");
++  progress.size = st.st_size;
++  mutt_progress_bar (&progress, 0);
++
++  snprintf (buf, sizeof (buf), "DATA\r\n");
++  if (mutt_socket_write (conn, buf) == -1)
++  {
++    fclose (fp);
++    return smtp_err_write;
++  }
++  if ((r = smtp_get_resp (conn)))
++  {
++    fclose (fp);
++    return r;
++  }
++
++  while (fgets (buf, sizeof (buf) - 1, fp))
++  {
++    buflen = mutt_strlen (buf);
++    if (buflen && buf[buflen-1] == '\n'
++	&& (buflen == 1 || buf[buflen - 2] != '\r'))
++      snprintf (buf + buflen - 1, sizeof (buf) - buflen + 1, "\r\n");
++    if (buf[0] == '.')
++    {
++      if (mutt_socket_write_d (conn, ".", 3) == -1)
++      {
++        fclose (fp);
++        return smtp_err_write;
++      }
++    }
++    if (mutt_socket_write_d (conn, buf, 3) == -1)
++    {
++      fclose (fp);
++      return smtp_err_write;
++    }
++
++    mutt_progress_bar (&progress, ftell (fp));
++  }
++  fclose (fp);
++
++  /* terminate the message body */
++  if (mutt_socket_write (conn, ".\r\n") == -1)
++    return smtp_err_write;
++
++  if ((r = smtp_get_resp (conn)))
++    return r;
++
++  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;
++  int ret = -1;
++  char buf[1024];
++
++  if (smtp_fill_account (&account) < 0)
++    return ret;
++
++  if (!(conn = mutt_conn_find (NULL, &account)))
++    return -1;
++
++  Esmtp = eightbit;
++
++  do
++  {
++    /* send our greeting */
++    if (( ret = smtp_open (conn)))
++      break;
++    FREE (&AuthMechs);
++
++    /* send the sender's address */
++    ret = snprintf (buf, sizeof (buf), "MAIL FROM:<%s>",
++                    EnvFrom ? EnvFrom->mailbox : from->mailbox);
++    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);
++    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;
++
++    /* send the recipient list */
++    if ((ret = smtp_rcpt_to (conn, to)) || (ret = smtp_rcpt_to (conn, cc))
++        || (ret = smtp_rcpt_to (conn, bcc)))
++      break;
++
++    /* send the message data */
++    if ((ret = smtp_data (conn, msgfile)))
++      break;
++
++    mutt_socket_write (conn, "QUIT\r\n");
++
++    ret = 0;
++  }
++  while (0);
++
++  if (conn)
++    mutt_socket_close (conn);
++
++  if (ret == smtp_err_read)
++    mutt_error (_("SMTP session failed: read error"));
++  else if (ret == smtp_err_write)
++    mutt_error (_("SMTP session failed: write error"));
++
++  return ret;
++}
++
++static int smtp_fill_account (ACCOUNT* account)
++{
++  static unsigned short SmtpPort = 0;
++
++  struct servent* service;
++  ciss_url_t url;
++  char* urlstr;
++
++  account->flags = 0;
++  account->port = 0;
++  account->type = M_ACCT_TYPE_SMTP;
++
++  urlstr = safe_strdup (SmtpUrl);
++  url_parse_ciss (&url, urlstr);
++  if ((url.scheme != U_SMTP && url.scheme != U_SMTPS)
++      || mutt_account_fromurl (account, &url) < 0)
++  {
++    FREE (&urlstr);
++    mutt_error (_("Invalid SMTP URL: %s"), SmtpUrl);
++    mutt_sleep (1);
++    return -1;
++  }
++  FREE (&urlstr);
++
++  if (url.scheme == U_SMTPS)
++    account->flags |= M_ACCT_SSL;
++
++  if (!account->port)
++  {
++    if (account->flags & M_ACCT_SSL)
++      account->port = SMTPS_PORT;
++    else
++    {
++      if (!SmtpPort)
++      {
++        service = getservbyname ("smtp", "tcp");
++        if (service)
++          SmtpPort = ntohs (service->s_port);
++        else
++          SmtpPort = SMTP_PORT;
++        dprint (3, (debugfile, "Using default SMTP port %d\n", SmtpPort));
++      }
++      account->port = SmtpPort;
++    }
++  }
++
++  return 0;
++}
++
++static int smtp_helo (CONNECTION* conn)
++{
++  char buf[LONG_STRING];
++
++  memset (Capabilities, 0, sizeof (Capabilities));
++
++  if (!Esmtp)
++  {
++    /* if TLS or AUTH are requested, use EHLO */
++    if (conn->account.flags & M_ACCT_USER)
++      Esmtp = 1;
++#if defined(USE_SSL) || defined(USE_GNUTLS)
++    if (option (OPTSSLFORCETLS) || quadoption (OPT_SSLSTARTTLS) != M_NO)
++      Esmtp = 1;
++#endif
++  }
++
++  snprintf (buf, sizeof (buf), "%s %s\r\n", Esmtp ? "EHLO" : "HELO", Fqdn);
++  /* XXX there should probably be a wrapper in mutt_socket.c that
++    * repeatedly calls conn->write until all data is sent.  This
++    * currently doesn't check for a short write.
++    */
++  if (mutt_socket_write (conn, buf) == -1)
++    return smtp_err_write;
++  return smtp_get_resp (conn);
++}
++
++static int smtp_open (CONNECTION* conn)
++{
++  int rc;
++
++  if (mutt_socket_open (conn))
++    return -1;
++
++  /* get greeting string */
++  if ((rc = smtp_get_resp (conn)))
++    return rc;
++
++  if ((rc = smtp_helo (conn)))
++    return rc;
++
++#if defined(USE_SSL) || defined(USE_GNUTLS)
++  if (conn->ssf)
++    rc = M_NO;
++  else if (option (OPTSSLFORCETLS))
++    rc = M_YES;
++  else if (mutt_bit_isset (Capabilities, STARTTLS) &&
++           (rc = query_quadoption (OPT_SSLSTARTTLS,
++                                   _("Secure connection with TLS?"))) == -1)
++    return rc;
++
++  if (rc == M_YES)
++  {
++    if (mutt_socket_write (conn, "STARTTLS\r\n") < 0)
++      return smtp_err_write;
++    if ((rc = smtp_get_resp (conn)))
++      return rc;
++
++#ifdef USE_SSL
++    if (mutt_ssl_starttls (conn))
++#elif USE_GNUTLS
++    if (mutt_gnutls_starttls (conn))
++#endif
++    {
++      mutt_error (_("Could not negotiate TLS connection"));
++      mutt_sleep (1);
++      return -1;
++    }
++
++    /* re-EHLO to get authentication mechanisms */
++    if ((rc = smtp_helo (conn)))
++      return rc;
++  }
++#endif
++
++  if (conn->account.flags & M_ACCT_USER)
++  {
++    if (!mutt_bit_isset (Capabilities, AUTH))
++    {
++      mutt_error (_("SMTP server does not support authentication"));
++      mutt_sleep (1);
++      return -1;
++    }
++
++#ifdef USE_SASL
++    return smtp_auth (conn);
++#else
++    mutt_error (_("SMTP authentication requires SASL"));
++    mutt_sleep (1);
++    return -1;
++#endif /* USE_SASL */
++  }
++
++  return 0;
++}
++
++#ifdef USE_SASL
++static int smtp_auth (CONNECTION* conn)
++{
++  int r = SMTP_AUTH_UNAVAIL;
++
++  if (SmtpAuthenticators && *SmtpAuthenticators)
++  {
++    char* methods = safe_strdup (SmtpAuthenticators);
++    char* method;
++    char* delim;
++
++    for (method = methods; method; method = delim)
++    {
++      delim = strchr (method, ':');
++      if (delim)
++	*delim++ = '\0';
++      if (! method[0])
++	continue;
++
++      dprint (2, (debugfile, "smtp_authenticate: Trying method %s\n", method));
++
++      if ((r = smtp_auth_sasl (conn, method)) != SMTP_AUTH_UNAVAIL)
++        break;
++    }
++
++    FREE (&methods);
++  }
++  else
++    r = smtp_auth_sasl (conn, AuthMechs);
++
++  if (r == SMTP_AUTH_UNAVAIL)
++  {
++    mutt_error (_("No authenticators available"));
++    mutt_sleep (1);
++  }
++
++  return r == SMTP_AUTH_SUCCESS ? 0 : -1;
++}
++
++static int smtp_auth_sasl (CONNECTION* conn, const char* mechlist)
++{
++  sasl_conn_t* saslconn;
++  sasl_interact_t* interaction = NULL;
++  const char* mech;
++  const char* data = NULL;
++  unsigned int len;
++  char buf[HUGE_STRING];
++  int rc, saslrc;
++
++  if (mutt_sasl_client_new (conn, &saslconn) < 0)
++    return SMTP_AUTH_FAIL;
++
++  do
++  {
++    rc = sasl_client_start (saslconn, mechlist, &interaction, &data, &len, &mech);
++    if (rc == SASL_INTERACT)
++      mutt_sasl_interact (interaction);
++  }
++  while (rc == SASL_INTERACT);
++
++  if (rc != SASL_OK && rc != SASL_CONTINUE)
++  {
++    dprint (2, (debugfile, "smtp_auth_sasl: %s unavailable\n", mech));
++    sasl_dispose (&saslconn);
++    return SMTP_AUTH_UNAVAIL;
++  }
++
++  mutt_message (_("Authenticating (%s)..."), mech);
++
++  snprintf (buf, sizeof (buf), "AUTH %s", mech);
++  if (len)
++  {
++    strncat (buf, " ", sizeof (buf));
++    if (sasl_encode64 (data, len, buf + mutt_strlen (buf),
++                       sizeof (buf) - mutt_strlen (buf), &len) != SASL_OK)
++    {
++      dprint (1, (debugfile, "smtp_auth_sasl: error base64-encoding client response.\n"));
++      goto fail;
++    }
++  }
++  strncat (buf, "\r\n", sizeof (buf));
++
++  do {
++    if (mutt_socket_write (conn, buf) < 0)
++      goto fail;
++    if (mutt_socket_readln (buf, sizeof (buf), conn) < 0)
++      goto fail;
++    rc = atoi(buf);
++
++    if (rc != smtp_ready)
++      break;
++
++    if (sasl_decode64 (buf+4, strlen (buf+4), buf, sizeof (buf), &len) != SASL_OK)
++    {
++      dprint (1, (debugfile, "smtp_auth_sasl: error base64-decoding server response.\n"));
++      goto fail;
++    }
++
++    do
++    {
++      saslrc = sasl_client_step (saslconn, buf, len, &interaction, &data, &len);
++      if (saslrc == SASL_INTERACT)
++        mutt_sasl_interact (interaction);
++    }
++    while (saslrc == SASL_INTERACT);
++
++    if (len)
++    {
++      if (sasl_encode64 (data, len, buf, sizeof (buf), &len) != SASL_OK)
++      {
++        dprint (1, (debugfile, "smtp_auth_sasl: error base64-encoding client response.\n"));
++        goto fail;
++      }
++    }
++    strfcpy (buf + len, "\r\n", sizeof (buf) - len);
++  } while (rc == smtp_ready);
++
++  if (smtp_success (rc))
++  {
++    mutt_sasl_setup_conn (conn, saslconn);
++    return SMTP_AUTH_SUCCESS;
++  }
++  else if (SmtpAuthenticators && *SmtpAuthenticators)
++  {
++    /* if we're given a mech list to attempt, failure means try the next */
++    dprint (2, (debugfile, "smtp_auth_sasl: %s failed\n", mech));
++    sasl_dispose (&saslconn);
++    return SMTP_AUTH_UNAVAIL;
++  }
++
++fail:
++  mutt_error (_("SASL authentication failed"));
++  mutt_sleep (1);
++  sasl_dispose (&saslconn);
++  return SMTP_AUTH_FAIL;
++}
++#endif /* USE_SASL */
