From a434cb43e807753730d815096464c9c7cb3f1596 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sat, 20 Feb 2010 21:56:48 +0000 Subject: - 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. --- CHANGES | 7 +++++++ RELEASE-NOTES | 1 + lib/smtp.c | 37 +++++++++++++++++++++++++++++++++++++ lib/smtp.h | 1 + tests/ftpserver.pl | 1 + 5 files changed, 47 insertions(+) diff --git a/CHANGES b/CHANGES index 0a1607a8b..28f20475c 100644 --- 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. diff --git a/RELEASE-NOTES b/RELEASE-NOTES index 52f855bf8..43380c2a0 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -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: diff --git a/lib/smtp.c b/lib/smtp.c index 7e3d4670c..f879651c6 100644 --- a/lib/smtp.c +++ b/lib/smtp.c @@ -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; diff --git a/lib/smtp.h b/lib/smtp.h index cc581d4d5..02cd467f5 100644 --- a/lib/smtp.h +++ b/lib/smtp.h @@ -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; diff --git a/tests/ftpserver.pl b/tests/ftpserver.pl index bc868cfd2..8c1692464 100644 --- a/tests/ftpserver.pl +++ b/tests/ftpserver.pl @@ -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"; } -- cgit v1.2.3