- I made the SMTP code expect a 250 response back from the server after the
authorDaniel Stenberg <daniel@haxx.se>
Sat, 20 Feb 2010 21:56:48 +0000 (21:56 +0000)
committerDaniel Stenberg <daniel@haxx.se>
Sat, 20 Feb 2010 21:56:48 +0000 (21:56 +0000)
  full DATA has been sent, and I modified the test SMTP server to also send
  that response. As usual, the DONE operation that is made after a completed
  transfer is still not doable in a non-blocking way so this waiting for 250
  is unfortunately made blockingly.

CHANGES
RELEASE-NOTES
lib/smtp.c
lib/smtp.h
tests/ftpserver.pl

diff --git a/CHANGES b/CHANGES
index 0a1607a..28f2047 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -6,6 +6,13 @@
 
                                   Changelog
 
+Daniel Stenberg (20 Feb 2010)
+- I made the SMTP code expect a 250 response back from the server after the
+  full DATA has been sent, and I modified the test SMTP server to also send
+  that response. As usual, the DONE operation that is made after a completed
+  transfer is still not doable in a non-blocking way so this waiting for 250
+  is unfortunately made blockingly.
+
 Yang Tse (14 Feb 2010)
 - Overhauled test suite getpart() function. Fixing potential out of bounds
   stack and memory overwrites triggered with huge test case definitions.
index 52f855b..43380c2 100644 (file)
@@ -17,6 +17,7 @@ This release includes the following bugfixes:
  o multiple recepients with SMTP
  o fixed the CURL_FORMAT_* defines when building with cmake
  o missing quote in libcurl.m4
+ o SMTP: now waits for 250 after the DATA transfer
 
 This release includes the following known bugs:
 
index 7e3d467..f879651 100644 (file)
@@ -232,6 +232,7 @@ static void state(struct connectdata *conn,
     "MAIL",
     "RCPT",
     "DATA",
+    "POSTDATA",
     "QUIT",
     /* LAST */
   };
@@ -424,6 +425,25 @@ static CURLcode smtp_state_data_resp(struct connectdata *conn,
   return result;
 }
 
+/* for the POSTDATA response, which is received after the entire DATA
+   part has been sent off to the server */
+static CURLcode smtp_state_postdata_resp(struct connectdata *conn,
+                                     int smtpcode,
+                                     smtpstate instate)
+{
+  CURLcode result = CURLE_OK;
+  struct SessionHandle *data = conn->data;
+  struct FTP *smtp = data->state.proto.smtp;
+
+  (void)instate; /* no use for this yet */
+
+  if(smtpcode != 250)
+    result = CURLE_RECV_ERROR;
+
+  state(conn, SMTP_STOP);
+  return result;
+}
+
 static CURLcode smtp_statemach_act(struct connectdata *conn)
 {
   CURLcode result;
@@ -484,6 +504,10 @@ static CURLcode smtp_statemach_act(struct connectdata *conn)
       result = smtp_state_data_resp(conn, smtpcode, smtpc->state);
       break;
 
+    case SMTP_POSTDATA:
+      result = smtp_state_postdata_resp(conn, smtpcode, smtpc->state);
+      break;
+
     case SMTP_QUIT:
       /* fallthrough, just stop! */
     default:
@@ -691,6 +715,19 @@ static CURLcode smtp_done(struct connectdata *conn, CURLcode status,
                         SMTP_EOB_LEN,       /* buffer size */
                         &bytes_written);    /* actually sent away */
 
+
+  if(status == CURLE_OK) {
+    state(conn, SMTP_POSTDATA);
+    /* run the state-machine
+
+       TODO: when the multi interface is used, this _really_ should be using
+       the smtp_multi_statemach function but we have no general support for
+       non-blocking DONE operations, not in the multi state machine and with
+       Curl_done() invokes on several places in the code!
+    */
+    result = smtp_easy_statemach(conn);
+  }
+
   /* clear these for next connection */
   smtp->transfer = FTPTRANSFER_BODY;
 
index cc581d4..02cd467 100644 (file)
@@ -37,6 +37,7 @@ typedef enum {
   SMTP_MAIL, /* MAIL FROM */
   SMTP_RCPT, /* RCPT TO */
   SMTP_DATA,
+  SMTP_POSTDATA,
   SMTP_QUIT,
   SMTP_LAST  /* never used */
 } smtpstate;
index bc868cf..8c16924 100644 (file)
@@ -545,6 +545,7 @@ sub DATA_smtp {
         print FILE "$ulsize bytes would've been stored here\n";
     }
     close(FILE);
+    sendcontrol "250 OK, data received!\r\n";
     logmsg "received $ulsize bytes upload\n";
 
 }