After several hours of hair pulling, I finally rectified an issue sending mail via Smartermail 6.0 using PHP's "mail" function. The exact same (crappy) code worked fine on the old freeBSD box, running PHP 4.9 and Apache. But when I migrated the same code to Windows 2008 running IIS7, PHP 4.9 (just to save me potential hassle with upgrading to 5.x), and Smartermail 6.0, I would get delivery log entries like this:
13:48:47 [60090] Delivery started for < at 1:48:47 PM
13:48:47 [60091] Delivery started for < at 1:48:47 PM
13:48:50 [60091] Skipping spam checks: No local recipients
13:48:50 [60090] Skipping spam checks: No local recipients
13:48:53 [60091] Sending remote mail for <
13:48:53 [60091] Connecting to 72.9.148.220
13:48:53 [60090] Sending remote mail for <
13:48:53 [60091] Connection to 72.9.148.220 from 69.24.65.218:55153 succeeded
13:48:53 [60091] RSP: 220-secure.extentions.net ESMTP Exim 4.69 #1 Fri, 11 Sep 2009 14:48:51 -0500
13:48:53 [60091] RSP: 220-We do not authorize the use of this system to transport unsolicited,
13:48:53 [60091] RSP: 220 and/or bulk e-mail.
13:48:53 [60091] CMD: EHLO maso165.gearhost.us.com
13:48:53 [60091] RSP: 250-secure.extentions.net Hello maso165.gearhost.us.com [69.24.65.218]
13:48:53 [60091] RSP: 250-SIZE 52428800
13:48:53 [60091] RSP: 250-PIPELINING
13:48:53 [60091] RSP: 250-AUTH PLAIN LOGIN
13:48:53 [60091] RSP: 250-STARTTLS
13:48:53 [60091] RSP: 250 HELP
13:48:53 [60091] CMD: MAIL FROM:<<> SIZE=899
13:48:53 [60091] RSP: 501 <<>: missing or malformed local part
13:48:53 [60091] CMD: QUIT
Googling turned up lots of Ruby dudes and dudettes who were encountering the same error trying to send mail via SMTP in Ruby, only since they were using a Ruby class to do it, the true cause of the problem was out of their reach. In a nutshell, the error is generated by a malformed "FROM" address. After trying all manner of experimentation, I finally rectified the issue by removing the space between the colon and the header variables. Here's the original code that created the mail headers, and broke my send attempt:
$headers = "From: $MailFrom\r\n";
$headers .= "Return-path: $MailFrom\r\n";
$headers .= "Errors-to: $MailFrom\r\n";
$headers .= "MIME-Version: 1.0\r\n";
$headers .= "Content-Type: text/html; charset=iso-8859-7\r\n";
$headers .= "X-Sender: $MailFrom\r\n";
$headers .= "X-Priority: 3\r\n";
$headers .= "X-MSMail-Priority: Normal\r\n";
$headers .= "X-Mailer: PHP ".phpversion()."\r\n";
Here's what the working version of that snippet looks like:
$headers = "From:$MailFrom\r\n";
$headers .= "Return-path:$MailFrom\r\n";
$headers .= "Errors-to:$MailFrom\r\n";
$headers .= "MIME-Version: 1.0\r\n";
$headers .= "Content-Type: text/html; charset=iso-8859-7\r\n";
$headers .= "X-Sender:$MailFrom\r\n";
$headers .= "X-Priority: 3\r\n";
$headers .= "X-MSMail-Priority: Normal\r\n";
$headers .= "X-Mailer: PHP ".phpversion()."\r\n";
So, if you are encountering a 501 error, check your code to ensure that you don't have any extra characters or spaces in your values, such as square brackets, extra opening or closing pointy brackets (< >), and the like.
Just for entertainment purposes and to give you something to wag your head at, let me show you the complete code my predecessor wrote to generate the email headers and values:
$BCCx = 0;
$Ectr = 0;
$BCCx = "";
$MastStr = " ";
while($Row=mysql_fetch_array($Result)) {
$Bemail = $Row[EMail];
if (strpos($Bemail,"@")>0) {
$BCCctr = $BCCctr + 1;
$Ectr = $Ectr + 1;
if ( strpos($Bemail,";")> 0) {
$xx = strpos($Bemail,";");
$Bemail = substr($Bemail,0,$xx) . "," . substr($Bemail,$xx+1);
}
$dbug = $dbug . "$Row[LastName], $Row[FirstName] ";
$BCCx = $BCCx . ", " . $Bemail;
$MastStr .= "<br><br>" . $Row[EMail] . " .. " . trim($Row[LastName]) . ", " . trim($Row[FirstName]) . " .... d:" . $Row[daytimephone] . " .. n:" . $Row[eveningphone] . " .. cell:" . $Row[cellphone];
}
if ($BCCctr == 150) {
$BCCctr = 0;
$MailJay = "$Row[EMail]";
$Subject = $_POST['SubjectLine'];
$Strx = $_POST['MessageLine'];
$MailFrom = $ReplyEmailx;
print("<br>mail command done S:$Subject*B:$Strx*<br>");
if ( strpos($MailJay,";")> 0) {
$xx = strpos($MailJay,";");
$MailJay = substr($MailJay,0,$xx) . "," . substr($MailJay,$xx+1);
}
$MailJay = "administrator@somedomain.com"; // new Aug 2004
$headers = "From:$MailFrom\r\n";
$headers .= "Return-path: $MailFrom\r\n";
$headers .= "Errors-to: $MailFrom\r\n";
$headers .= "MIME-Version: 1.0\r\n";
$headers .= "Content-Type: text/html; charset=iso-8859-7\r\n";
$headers .= "X-Sender: $MailFrom\r\n";
$headers .= "X-Priority: 3\r\n";
$headers .= "X-MSMail-Priority: Normal\r\n";
$headers .= "X-Mailer: PHP ".phpversion()."\r\n";
$headers .= "BCC:$BCCx\r\n\r\n";
$Mheaders = $Mheaders . "<br>" . $headers;
$BCCx = "";
while (strpos($Subject,"'")>0) { $xx = strpos($Subject,"'");
$Subject = substr($Subject,0,$xx) . substr($Subject,$xx+1);
}
while (strpos($Subject,'"')>0) { $xx = strpos($Subject,'"');
$Subject = substr($Subject,0,$xx) . substr($Subject,$xx+1);
}
while (strpos($Strx,"'")>0) { $xx = strpos($Strx,"'");
$Strx = substr($Strx,0,$xx) . substr($Strx,$xx+1);
}
while (strpos($Strx,'"')>0) { $xx = strpos($Strx,'"');
$Strx = substr($Strx,0,$xx) . substr($Strx,$xx+1);
}
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
mail($MailJay, $Subject, $Strx, $headers, "-f $MailFrom");