Page 2 of 2

Posted: Mon Jul 25, 2005 6:47 am
by pilau
Oho.
That's what it says:

"The sender of this message, xrewxpilau@hotmail.com, could not be verified by Sender ID. Learn more about Sender ID."

Posted: Mon Jul 25, 2005 6:54 am
by Roja
pilau wrote:Oho.
That's what it says:

"The sender of this message, xrewxpilau@hotmail.com, could not be verified by Sender ID. Learn more about Sender ID."
No. We need the complete headers. Thats just one tiny snippet. There is more hiding under the covers.

Posted: Mon Jul 25, 2005 6:55 am
by pilau
Okay, got it:

Received: from clust03-www01.powweb.com ([66.152.98.31]) by mc2-f14.hotmail.com with Microsoft SMTPSVC(6.0.3790.211); Mon, 25 Jul 2005 04:50:59 -0700
Received: by clust03-www01.powweb.com (Postfix, from userid 83752)id BC55215E3C; Mon, 25 Jul 2005 04:51:01 -0700 (PDT)
X-Message-Info: JGTYoYF78jEsKai3YZEdFgS7dLO4q2PrABoQhwytce0=
Return-Path: wormiverseweb@clust03-www01.powweb.com
X-OriginalArrivalTime: 25 Jul 2005 11:50:59.0447 (UTC) FILETIME=[1FD44870:01C5910F]

Posted: Mon Jul 25, 2005 7:14 am
by bokehman
Hotmail will put the mail in the junk folder if it doesn't have these headers:

Return-Path: <sender@sender_domain.com>
Message-ID: <unique_message_id@mail-server-PTR-or-domain.com>

Posted: Mon Jul 25, 2005 7:20 am
by pilau
How do I create these/add those to my Mail() function?

Posted: Mon Jul 25, 2005 7:24 am
by Roja
pilau wrote:Okay, got it:

Received: from clust03-www01.powweb.com ([66.152.98.31]) by mc2-f14.hotmail.com with Microsoft SMTPSVC(6.0.3790.211); Mon, 25 Jul 2005 04:50:59 -0700
Received: by clust03-www01.powweb.com (Postfix, from userid 83752)id BC55215E3C; Mon, 25 Jul 2005 04:51:01 -0700 (PDT)
X-Message-Info: JGTYoYF78jEsKai3YZEdFgS7dLO4q2PrABoQhwytce0=
Return-Path: wormiverseweb@clust03-www01.powweb.com
X-OriginalArrivalTime: 25 Jul 2005 11:50:59.0447 (UTC) FILETIME=[1FD44870:01C5910F]
Thats it? No others?

Posted: Mon Jul 25, 2005 7:26 am
by Roja
bokehman wrote:Hotmail will put the mail in the junk folder if it doesn't have these headers:

Return-Path: <sender@sender_domain.com>
Message-ID: <unique_message_id@mail-server-PTR-or-domain.com>
Return path is set, and message-id should not be required to avoid junking.

Posted: Mon Jul 25, 2005 7:36 am
by bokehman
Well I removed the message ID from my mail for a test. When removed the mail goes straight to the junk folder.

Posted: Mon Jul 25, 2005 8:31 am
by Roja
bokehman wrote:Well I removed the message ID from my mail for a test. When removed the mail goes straight to the junk folder.
Interesting. Good to know.. guess MS is leading the way in oddball mail borking in more than one way. :)

I use phpmailer - mind sharing how you add the message-id in php with mail()?

Posted: Mon Jul 25, 2005 8:57 am
by bokehman
It is entered anywhere before the first multi part boundry (if you are using one). That header should be written by the mail server (which may be doing it incorrectly). My test mail was sent using fsockopen() not mail(). That way I know exactly what the mail does and does not contain and my script can be set so you can see the complete exchange between the local server and the remote mailserver. I don't know if you added this header in mail() whether the mailserver would overwrite it.

If you want to see my fsockopen() mail script I would be happy to post it. It's great for testing.

Posted: Mon Jul 25, 2005 9:02 am
by pilau
Yeah, please post it.

Posted: Mon Jul 25, 2005 9:15 am
by bokehman

Code: Select all

<?php

// For debug output (ie to see the exchange) add ?debug to the url for example 
// http://www.domain.com/mailer.php?debug

// Fill in the following variables!

// $email = fill in the recipient
$email = '';

// $email_from = fill in the the sender
$email_from = '';

// $localhost should be the PTR for the server this mailer  
// script is being run on. If this is not correct many 
// mailservers will incorrectly reject mail from you. If 
//you do not know the PTR of your webserver you can look 
// look it up here by entering your domain name: 
// http://myhomewebserver.co.uk/PTR_from_domain.php
$localhost = '';

// Fill in the subject
$subject = 'Subject';

// Fill in email body text. Can include html tags.
$email_body = 'body text';

// Attachments
// Any attachment should look like the following and include
// the file name and the path. Add as many as you like.
// $attachments[] = 'c:/path/to/file/filename.ext';
// $attachments[] = 'c:/path/to/another/file/another-filename.ext';


// HTML mail
// Set to TRUE for HTML email or FALSE for plain text email
$html = FALSE;

// Send the email. Returns true on success or false on failure
email($email, $email_from, $subject, $email_body, $localhost, $html, $attachments);

//////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////
///////////////// NO NEED TO CHANGE ANYTHING AFTER THIS BOUNDRY //////////////////////
//////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////


function email($email, $email_from, $subject, $email_body, $localhost, $html = NULL, &$attachments = NULL){
if (!function_exists('getmxrr')){
		function getmxrr($hostname, &$mxhosts, &$weight = NULL)
		{
 		  $mxhosts = array();
  		 exec('nslookup -type=mx '.$hostname, $result);
   		$result = implode("\r\n", $result);
  		 preg_match_all("'^.*MX preference = (\d{1,10}), mail exchanger = (.*)$'simU", $result, $mx_matches);
  		 if (count($mx_matches[2]) > 0)
  		     {
			   foreach($mx_matches[2] as $key => $value){
					$mx_matches[2][$key] = trim($value);
				}
	 		  array_multisort($mx_matches[1], $mx_matches[2]);
     		  $mxhosts = $mx_matches[2];
     		  if (!is_null($weight))
       		    {
      		     $weight = $mx_matches[1];
       		    }
      		 return True;
   		    }
  		 else
   		    {
   		    return False;
   		    }
		}
	}

if (!function_exists('mime_content_type')){
	function mime_content_type($file){
		@$size = getimagesize($file);
		if($size[mime]){
			return($size[mime]);
		}
		return('application/octet-stream');
	}
}


// Build mime or plain content
function mime_content($email, $email_from, $subject, $email_body, $localhost, $html = NULL, &$attachments = NULL)
{
	// Generate a boundary string
	$mime_boundary = "mime_boundry_multipart/mixed".md5(time())."x";
	$alternative_mime_boundary = "mime_boundry_multipart/alternative_".md5(time())."x";

	$content = "Date: ".date('D, d M Y H:i:s O')."\n".
				"Subject: $subject\n".
				"To: $email\n".
				"From: $email_from\n".
				"Return-Path: <$email_from>\n".
				"Message-ID: <".base64_encode(microtime())."@$localhost>\n".
				"MIME-Version: 1.0\n";
				
	if(count($attachments) > 0){
		$content  .= "Content-Type: multipart/mixed;\n" .
  		             " boundary=\"{$mime_boundary}\"\n\n";
             
			if($html == TRUE){
				$content  .= "This is a multi-part message in MIME format.\n\n".
							 "--{$mime_boundary}\n".
							 "Content-Type: multipart/alternative;\n".
							 " boundary=\"{$alternative_mime_boundary}\"\n\n".
							 "--{$alternative_mime_boundary}\n".
							 "Content-Type: text/plain; charset=ISO-8859-1; format=flowed\n".
							 "Content-Transfer-Encoding: 7bit\n\n".
							 strip_tags($email_body)."\n\n".					
							 "--{$alternative_mime_boundary}\n".
							 "Content-Type: text/html; charset=ISO-8859-1\n".
							 "Content-Transfer-Encoding: 7bit\n\n".
							 "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\n".
							 "<html>\n".
							 "<head>\n".
						 	 " <meta content=\"text/html;charset=ISO-8859-1\" http-equiv=\"Content-Type\">\n".
						 	 " <title></title>\n".
							 "</head>\n".
							 "<body>\n".
							 $email_body."\n".
							 "</body>\n".
							 "</html>\n\n".
							 "--{$alternative_mime_boundary}--\n";
						 }else{
				$content  .= "This is a multi-part message in MIME format.\n\n".
							 "--{$mime_boundary}\n".
							 "Content-Type: text/plain; charset=ISO-8859-1; format=flowed\n" .
      		     			 "Content-Transfer-Encoding: 7bit\n\n" .
      		    			 strip_tags($email_body)."\n\n";  
      					 }
		
	

			// Deal with attachments array 
			if(count($attachments) > 0){
				foreach($attachments as $key => $value){
					$mime_type = mime_content_type($value);
					if(is_file($value)){
						if(ereg('^image', $mime_type)){
							$disposition = 'inline';
						}else{
							$disposition = 'attachment';
						}
						$filesize = filesize($value);
						$file = fopen($value,'rb');
						$data = fread($file,$filesize);
						fclose($file);

						// Base64 encode the file data
						$data = chunk_split(base64_encode($data));
						$value = pathinfo($value);
						$content    .=  "--{$mime_boundary}\n" .
										"Content-Type: $mime_type;\n" .
										" name=\"{$value[basename]}\"\n" .
										"Content-Transfer-Encoding: base64\n" .
										"Content-Disposition: $disposition;\n" .
										" filename=\"{$value[basename]}\"\n\n" .
										$data . "\n";
					}
				}
			}

			$content .= "--{$mime_boundary}--\n";             


			
			
	}elseif($html == TRUE){
		   $content  .= "MIME-Version: 1.0\n" .
 		             	"Content-Type: multipart/alternative;\n".
						" boundary=\"{$alternative_mime_boundary}\"\n\n".
						"--{$alternative_mime_boundary}\n".
						"Content-Type: text/plain; charset=ISO-8859-1; format=flowed\n".
						"Content-Transfer-Encoding: 7bit\n\n".
						strip_tags($email_body)."\n\n".					
						"--{$alternative_mime_boundary}\n".
						"Content-Type: text/html; charset=ISO-8859-1\n".
						"Content-Transfer-Encoding: 7bit\n\n".
						"<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\n".
						"<html>\n".
						"<head>\n".
						" <meta content=\"text/html;charset=ISO-8859-1\" http-equiv=\"Content-Type\">\n".
						" <title></title>\n".
						"</head>\n".
						"<body>\n".
						$email_body."\n".
						"</body>\n".
						"</html>\n\n".
						"--{$alternative_mime_boundary}--\n";
			
			
	}else{
		$content .= "Content-Type: text/plain; charset=ISO-8859-1; format=flowed\n" .
					"Content-Transfer-Encoding: 7bit\n\n" .
					strip_tags($email_body)."\n";
	}
	return($content);
}


function send_email($email, $email_from, $content, $localhost)
{
	// For debug output add ?debug to the url for example 
	// http://www.domain.com/mailer.php?debug

	$return = FALSE;
	
	// It is quite easy to go over the 30 second default of PHP when sending mail.
	ini_set('max_execution_time', '60');  

    // Extract the mail server name from the email address.
    list ($user, $domain) = split ("@", $email);
    if(getmxrr($domain, $mxhost)){  
        $ConnectAddress = $mxhost[0];
    }else{
	    $debug[] = 'No MX record found.'; 
	    $debug[] = 'Trying to connect using domain.';
        $ConnectAddress = $domain;
    }
    if(gethostbynamel($ConnectAddress) === FALSE){
	    $debug[] = 'Domain cannot be found.';
	    if(isset($_GET['debug'])){
            foreach($debug as $line){
				echo $line.'<br>';
			}
		}
	   return FALSE;
    }
    // Try to open a socket with the remote mail server address.
    if($ConnectAddress == $domain){
    	$connect = @fsockopen($ConnectAddress, 25, $errno, $errstr, 5);
	}else{
		$tries = count($mxhost);
		$i = 0;
		$connect = @fsockopen($mxhost[$i], 25, $errno, $errstr, 5);
		while(!$connect && !$tries == 0){
			$i++;
			$connect = @fsockopen($mxhost[$i], 25, $errno, $errstr, 5);
			$debug[] = 'Connect failed. Trying \'<i>'.$mxhost[$i].'</i>\'...<br />';
			flush();
			$tries--;
			
		}
	}
	
	if ($connect)
    {	
        stream_set_timeout($connect, 10);
	    $out = fgets($connect, 1024);
	    $debug[] = 'Remote: '.$out;
        if (ereg("^220", $out))
        {
            
	        $debug[] = "Local: EHLO $localhost\r\n";
	        fputs ($connect, "EHLO $localhost\r\n");
	        $out = fgets ( $connect, 1024 );
            while(!ereg('^250', $out)&&(!empty($out))){
		        $debug[] = 'Remote: '.$out;
		        stream_set_timeout($connect, 0, 5000);	
		        $out = fgets ( $connect, 1024 );
		        stream_set_timeout($connect, 10);
	        }
	        for($tries = 15; $tries > 0; $tries--){
		    	if(ereg('^250', $out)){
					$debug[] = 'Remote: '.$out;
					$for_loop_hop = $out;
				}elseif(empty($out)){
					    usleep(100000); 
				}else{
				    $debug[] = 'Remote: '.$out;
			    }
			    stream_set_timeout($connect, 0, 5000);
			    $out = fgets($connect, 1024);
			    stream_set_timeout($connect, 10);
	 	   }
			if(!ereg('^250', $for_loop_hop)){
				$debug[] = 'No 250';
		            if(isset($_GET['debug'])){
                		foreach($debug as $line){
							echo $line.'<br>';
						}
					}
	            	return FALSE;
            }
			$debug[] = htmlspecialchars("Local: MAIL FROM: <{$email_from}>\r\n");
	        fputs ($connect, "MAIL FROM: <{$email_from}>\r\n");
            $from = fgets ( $connect, 1024 );
            $debug[] = htmlspecialchars('Remote: '.$from);
            $debug[] = htmlspecialchars("Local: RCPT TO: <{$email}>\r\n");
	        fputs ($connect, "RCPT TO: <{$email}>\r\n");
            $to = fgets ($connect, 1024);
            $debug[] = htmlspecialchars('Remote: '.$to);
            if (!ereg ("^250", $from) || !ereg ("^250", $to)){
                $debug[] = 'No 250';
	            if(isset($_GET['debug'])){
                		foreach($debug as $line){
							echo $line.'<br>';
						}
					}
	            	return FALSE;
            }else{
	           $debug[] = "Local: DATA\r\n";
	           fputs($connect,"DATA\r\n");
	           stream_set_timeout($connect,20);
		       $fgets = fgets($connect,512);
		       $debug[] = 'Remote: '.htmlspecialchars($fgets);
		       if (!ereg("^354", $fgets)){
                	$debug[] = 'No 354';
	            	if(isset($_GET['debug'])){
                		foreach($debug as $line){
							echo $line.'<br>';
						}
					}
	            	return FALSE;
            	}
				$debug[] = "Local: ".nl2br(htmlspecialchars($content))."\r\n.\r\n";
	            fputs($connect, "$content\r\n.\r\n");
				$fgets = fgets($connect,512);
		        $debug[] = 'Remote: '.$fgets;
		        if (ereg("^250", $fgets)){
			        $return = TRUE;
			        $debug[] = "Local: QUIT\r\n";
	                fputs($connect,"QUIT\r\n");
			        $fgets = fgets($connect,512);
		        	$debug[] = 'Remote: '.$fgets;
	        	}else{
		        	$debug[] = "QUIT\r\n";
	                fputs($connect,"Local: QUIT\r\n");
			        $fgets = fgets($connect,512);
			        $debug[] = 'Remote: '.$fgets;
		        }
            }
        }
    }
    
	if(isset($_GET['debug'])){
		foreach($debug as $line){
			echo $line.'<br>';
		}
	}return($return);
}


$content = mime_content($email, $email_from, $subject, $email_body, $localhost, $html, $attachments);
$return = send_email($email, $email_from, $content, $localhost);
return($return);
}

?>

Posted: Tue Jul 26, 2005 2:05 am
by pilau
Uh, way too advanced for me. I still can't even get the hang on cookies!

Posted: Tue Jul 26, 2005 3:16 am
by bokehman
It's not complicated at all. Every function in php is made up of some amount of code. If you call mail() it must have similar code in the background. If you wanted to use that function just put it in a file: for example mailer.php and then when you wanted to use it all you would do is insert the following in your script:

Code: Select all

$email = '';
$email_from = '';
$subject = '';
$email_body = '';
$localhost = $_SERVER['HTTP_HOST'];


require_once('mailer.php');
email($email, $email_from, $subject, $email_body, $localhost);

Posted: Tue Jul 26, 2005 6:06 am
by pilau
Warning: A huge gasp of understanding is on it's way!

Ohhhhhhhhhhhhhhhhh!
Now I get it.

Thanks.

(And now I got a very different problem, which requiers a second post. Thanks again.)