Example:

Connect to (mailserver) via telnet at port 25, receive:

Trying 127.0.0.1...
Connected to xxxx (x.x.x.x).
Escape character is '^]'.
220-mailserver ESMTP Exim 4.69 #1 Sun, 04 Apr 2010 22:52:51 -0500
220-We do not authorize the use of this system to transport unsolicited,
220 and/or bulk e-mail.

The current code uses fgets() a single time to get the 220 status indicating the server is ok.

The code then HELO, MAIL FROM, and RCPT TO each time using fgets() to retrieve the server's result.

The problem comes because the server has returned multiple lines of 220 and at least one of the tests following the HELO (in my case, the MAIL FROM) will return 220 instead of an expected OK code. The verification then bails (giving the user benefit-of-doubt)

Since fgets() returns only a single line of code, here is my workaround:

if (ereg("^220", $out = fgets($connect, 1024))) {
// OK, we have a SMTP connection
+ while ($out != ""):
+ $out = fgets($connect, 1024);
+ endwhile;
break;

Probably not the cleanest code, but it's needed to work around a server that returns more than one 220 line....

I have verified that this is working by adding this at the end of my code:

// Everything OK
+ watchdog('email_verify', "Everything OK with email address: $mail");
return;

Comments

Title:does not parse a multi-line 220 (after HELO) correctlydoes not parse a multi-line 220 (after connection) correctly

found a timeout in the fgets() (at least I think that's where it's at) because the server is waiting for input.

Revised:

// OK, we have a SMTP connection
stream_set_timeout($connect, 4); // Only wait 4 seconds for something to happen
while (ereg("^220", $out)) {
$out = fgets($connect, 1024);
}

Works for me now, so I'm not going to work this any further.

stream_set_timeout($connect, 1); $sockinfo = stream_get_meta_data($connect);
      while ( ($out = fread($connect, 8192)) && !($sockinfo['timed_out']) ) { $sockinfo = stream_get_meta_data($connect); }

my workaround.