Index: docs/RESOURCES
===================================================================
RCS file: /cvsroot/curl/curl/docs/RESOURCES,v
retrieving revision 1.14
diff -u -r1.14 RESOURCES
--- docs/RESOURCES	14 Feb 2010 19:43:28 -0000	1.14
+++ docs/RESOURCES	19 Feb 2010 16:06:59 -0000
@@ -66,7 +66,10 @@
 
   RFC 2818 - HTTP Over TLS (TLS is the successor to SSL)
 
+  RFC 2821 - SMTP protocol
+
   RFC 2964 - Use of HTTP State Management
 
   RFC 2965 - HTTP State Management Mechanism. Cookies. Obsoletes RFC2109
 
+  RFC 3207 - SMTP over TLS
Index: lib/smtp.c
===================================================================
RCS file: /cvsroot/curl/curl/lib/smtp.c,v
retrieving revision 1.11
diff -u -r1.11 smtp.c
--- lib/smtp.c	12 Feb 2010 22:23:47 -0000	1.11
+++ lib/smtp.c	19 Feb 2010 17:01:03 -0000
@@ -19,6 +19,7 @@
  * KIND, either express or implied.
  *
  * RFC2821 SMTP protocol
+ * RFC3207 SMTP over TLS
  *
  * $Id: smtp.c,v 1.11 2010-02-12 22:23:47 bagder Exp $
  ***************************************************************************/
@@ -228,6 +229,7 @@
     "STOP",
     "SERVERGREET",
     "EHLO",
+    "HELO",
     "STARTTLS",
     "MAIL",
     "RCPT",
@@ -252,11 +254,26 @@
 
   /* send EHLO */
   result = Curl_pp_sendf(&conn->proto.smtpc.pp, "EHLO %s", smtpc->domain);
+
   if(result)
     return result;
 
   state(conn, SMTP_EHLO);
+  return CURLE_OK;
+}
+
+static CURLcode smtp_state_helo(struct connectdata *conn)
+{
+  CURLcode result;
+  struct smtp_conn *smtpc = &conn->proto.smtpc;
+
+  /* send HELO */
+  result = Curl_pp_sendf(&conn->proto.smtpc.pp, "HELO %s", smtpc->domain);
+
+  if(result)
+    return result;
 
+  state(conn, SMTP_HELO);
   return CURLE_OK;
 }
 
@@ -277,9 +294,13 @@
   struct SessionHandle *data = conn->data;
   (void)instate; /* no use for this yet */
 
-  if(smtpcode != 'O') {
-    failf(data, "STARTTLS denied. %c", smtpcode);
-    result = CURLE_LOGIN_DENIED;
+  if(smtpcode != 220) {
+    if(data->set.ftp_ssl == CURLUSESSL_TRY)
+      state(conn, SMTP_STOP);
+    else {
+      failf(data, "STARTTLS denied. %c", smtpcode);
+      result = CURLE_LOGIN_DENIED;
+    }
   }
   else {
     /* Curl_ssl_connect is BLOCKING */
@@ -289,7 +310,6 @@
       result = smtp_state_ehlo(conn);
     }
   }
-  state(conn, SMTP_STOP);
   return result;
 }
 
@@ -304,12 +324,44 @@
   (void)instate; /* no use for this yet */
 
   if(smtpcode/100 != 2) {
+    if(data->set.ftp_ssl > CURLUSESSL_TRY && !conn->ssl[FIRSTSOCKET].use)
+      result = smtp_state_helo(conn);
+    else {
+      failf(data, "Access denied: %d", smtpcode);
+      result = CURLE_LOGIN_DENIED;
+    }
+  } 
+  else if(data->set.ftp_ssl && !conn->ssl[FIRSTSOCKET].use) {
+    /* We don't have a SSL/TLS connection yet, but SSL is requested. Switch
+       to TLS connection now */
+    result = Curl_pp_sendf(&conn->proto.smtpc.pp, "STARTTLS", NULL);
+    state(conn, SMTP_STARTTLS);
+  }
+  else {
+    /* end the connect phase */
+    state(conn, SMTP_STOP);
+  }
+  return result;
+}
+
+/* for HELO responses */
+static CURLcode smtp_state_helo_resp(struct connectdata *conn,
+                                     int smtpcode,
+                                     smtpstate instate)
+{
+  CURLcode result = CURLE_OK;
+  struct SessionHandle *data = conn->data;
+
+  (void)instate; /* no use for this yet */
+
+  if(smtpcode/100 != 2) {
     failf(data, "Access denied: %d", smtpcode);
     result = CURLE_LOGIN_DENIED;
+  } 
+  else {
+    /* end the connect phase */
+    state(conn, SMTP_STOP);
   }
-
-  /* end the connect phase */
-  state(conn, SMTP_STOP);
   return result;
 }
 
@@ -452,14 +504,7 @@
         return CURLE_FTP_WEIRD_SERVER_REPLY;
       }
 
-      if(data->set.ftp_ssl && !conn->ssl[FIRSTSOCKET].use) {
-        /* We don't have a SSL/TLS connection yet, but SSL is requested. Switch
-           to TLS connection now */
-        result = Curl_pp_sendf(&smtpc->pp, "STARTTLS", NULL);
-        state(conn, SMTP_STARTTLS);
-      }
-      else
-        result = smtp_state_ehlo(conn);
+      result = smtp_state_ehlo(conn);
       if(result)
         return result;
       break;
@@ -468,6 +513,10 @@
       result = smtp_state_ehlo_resp(conn, smtpcode, smtpc->state);
       break;
 
+    case SMTP_HELO:
+      result = smtp_state_helo_resp(conn, smtpcode, smtpc->state);
+      break;
+
     case SMTP_MAIL:
       result = smtp_state_mail_resp(conn, smtpcode, smtpc->state);
       break;
@@ -567,6 +616,10 @@
   const char *path = conn->data->state.path;
   int len;
 
+#ifdef HAVE_GETHOSTNAME
+    char localhost[1024 + 1];
+#endif
+
   *done = FALSE; /* default to not done yet */
 
   /* If there already is a protocol-specific struct allocated for this
@@ -630,8 +683,14 @@
   pp->endofresp = smtp_endofresp;
   pp->conn = conn;
 
-  if(!*path)
+  if(!*path) {
+#ifdef HAVE_GETHOSTNAME
+    if(!gethostname(localhost, sizeof localhost))
+      path = localhost;
+    else
+#endif
     path = "localhost";
+  }
 
   /* url decode the path and use it as domain with EHLO */
   smtpc->domain = curl_easy_unescape(conn->data, path, 0, &len);
Index: lib/smtp.h
===================================================================
RCS file: /cvsroot/curl/curl/lib/smtp.h,v
retrieving revision 1.5
diff -u -r1.5 smtp.h
--- lib/smtp.h	12 Feb 2010 22:23:47 -0000	1.5
+++ lib/smtp.h	19 Feb 2010 15:51:36 -0000
@@ -33,6 +33,7 @@
   SMTP_SERVERGREET, /* waiting for the initial greeting immediately after
                        a connect */
   SMTP_EHLO,
+  SMTP_HELO,
   SMTP_STARTTLS,
   SMTP_MAIL, /* MAIL FROM */
   SMTP_RCPT, /* RCPT TO */

