PX : code

Download this code


<?php

/*
 Originally 
 By: Jon S. Stevens jon@clearink.com
 Copyright 1998 Jon S. Stevens, Clear Ink
 This code has all the normal disclaimers.
 It is free for any use, just keep the credits intact.

 Enacements and modifications:

           By:  Shane Y. Gibson  shane@tuna.org
 Organization:  The Unix Network Archives (http://www.tuna.org./)
         Date:  November 16th, 1998
      Changes:  Added **all** comments, as original code lacked them.
                Added some return codes to include a bit more description
                for useability.

 I disclaim nothing...nor do I claim anything...but
 it would be nice if you included this disclaimer...

*/

/*  This function takes in an email address (say 'shane@tuna.org')
 *  and tests to see if it's a valid email address.
 *
 *  An array with the results is passed back to the caller.
 *
 *  Possible result codes for the array items are:
 *
 *  Item 0:  [true|false]        true for valid email address
 *                    false for NON-valid email address
 *
 *  Item 1:  [SMTP Code]        if a valid MX mail server found, then
 *                    fill this array in with failed SMTP
 *                    reply codes
 *
 *  Item 2:  [true|false]        true for valid mail server found for
 *                    host/domain
 *                    false if no valid mail server found
 *
 *  Item 3:  [MX server]        if a valid MX host was found and
 *                    connected to then fill in this item 
 *                    with the MX server hostname
 *
 *  EXAMPLE code for use is at the very end of this function.
 */

function validateEmail $email )
{
    
// used for SMTP HELO argument
    
global $SERVER_NAME;  

    
// initialize our return array, populating with default values
    
$return = array ( false"""""" );

    
// assign our user part and domain parts respectively to seperate             // variables
    
list ( $user$domain )  = split "@"$email);
    
    
// split up the domain name into sub-parts
    
$arr explode "."$domain );

    
// figure out how many parts to the host/domain name portion there are
    
$count count $arr );

    
// get our Top-Level Domain portion (i.e. foobar.org)
    
$tld $arr[$count 2] . "." $arr[$count 1];

    
// check that an MX record exists for Top-Level Domain, and if so
    // start our email address checking
    
if ( checkdnsrr $tld"MX" ) )
    {
        
// Okay...valid dns reverse record; test that MX record for 
        // host exists, and then fill the 'mxhosts' and 'weight'
        // arrays with the correct information
        //
        
if ( getmxrr $tld$mxhosts$weight ) )
        {
            
// sift through the 'mxhosts' connecting to each host
            
for ( $i 0$i count $mxhosts ); $i++ )
            {
                
// open socket on port 25 to mxhosts, setting                         // returned file pointer to the variable 'fp'
                
$fp fsockopen $mxhosts[$i], 25 );

                
// if the 'fp' was set, then goto work
                
if ( $fp )
                {
                    
// work variables
                    
$s 0;
                    
$c 0;
                    
$out "";
        
                    
// set our created socket for 'fp' to     
                    // non-blocking mode
                    // so our fgets() calls will return
                    // right away
                    
set_socket_blocking $fpfalse );

                    
// as long as our 'out' variable has a
                    // null value ("")
                    // keep looping (do) until we get
                    // something
                    //
                    
do
                    {
                        
// output of the stream assigned
                        // to 'out' variable
                        
$out fgets $fp2500 );

                        
// if we get an "220" code (service ready code (i.e greeting))
                        // increment our work (code (c)) variable, and null
                        // out our output variable for a later loop test
                        //
                        
if ( ereg "^220"$out ) )
                        {
                            
$s 0;
                            
$out "";
                            
$c++;
                            
$return[2] = true;
                            
$return[3] = $mxhosts[$i];
                        }
                        
// elseif c is greater than 0
                        // and 'out' is null (""), 
                        // we got a code back from some
                        // server, and we've passed
                        // through this loop at least
                        // once
                        //
                        
else if ( ( $c ) && ( $out == "" ) )
                        { 
                            
$return[2] = true;
                            break; 
                        }

                        
// else increment our 's'
                        // counter
                        
else
                        { 
$s++;    }
                    
                        
// and if 's' is 9999, break, to
                        // keep from looping
                        // infinetly
                        
if ( $s == 9999 ) { break; }
                    
                    } while ( 
$out == "" );

                    
// reset our file pointer to blocking
                    // mode, so we wait
                    // for communication to finish before 
                    // moving on...
                    
set_socket_blocking $fptrue );

                    
// talk to the MX mail server,
                    // validating ourself (HELO)
                    
fputs $fp"HELO $SERVER_NAME\n" );

                    
// get the mail servers reply, assign to
                    // 'output' (ignored)
                    
$output fgets $fp2000 );

                    
// give a bogus "MAIL FROM:" header to
                    // the server
                    
fputs $fp"MAIL FROM: <info@" $tld ">\n" );

                    
// get output again (ignored)
                    
$output fgets $fp2000 );

                    
// give RCPT TO: header for the email
                    // address we are testing
                    
fputs $fp"RCPT TO: <$email>\n" );                

                    
// get final output for validity testing
                    // (used)
                    
$output fgets $fp2000 );

                    
// test the reply code from the mail
                    // server for the 250 (okay) code
                    
if ( ereg "^250"$output ) )
                    {
                        
// set our true/false(ness)
                        // array item for testing
                        
$return[0] = true;
                    }
                    else
                    {
                        
// otherwise, bogus address,
                        // fillin the 2nd array item
                        // with the mail servers reply
                        // code for user to test if they
                        // want
                        
$return[0] = false;
                        
$return[1] = $output;
                    }
                
                    
// tell the mail server we are done
                    // talking to it
                    
fputs $fp"QUIT\n" );

                    
// close the file pointer
                    
fclose$fp );

                    
// if we got a good value break,
                    // otherwise, we'll keep
                    // trying MX records until we get a good
                    // value, or we
                    // exhaust our possible MX servers
                    
if ( $return[0] == true )
                    { break; }
                }
            }
        }
    } else {
    
// No MX record appears for the specified Top-Level Domain; possibly
    // an invalid host/domain name was specified.
        
$return[0] = false;
        
$return[1] = "Invalid email address (bad domain name)";
        
$return[2] = false;
    } 
// end if checkdnsrr()

    // return the array for the user to test against
    
return $return;
}
?>

<?php
    
// Here is an example chunk of code...  Normally, you'd call the
    // validate email with a form or some other method to provide
    // the input email address
    //
    //  NOTE:  You need to delete the /* and */ comment entries

/*  
// Minimal HTML code to test validateEmail() function.  Save this
// to a file to test...try different email addresses in the
// 'email_address' variable field to see how it behaves.
//
<html>
<head>
<tilte> Validate an email address. </title>
</head>

<body bgcolor="#000000" TEXT="#FFFFCC" LINK="#33CCFF" VLINK="#9999CC" ALINK="#FFFF00">

// Assumes that you put the validateEmail() function in a file 
// named "validateEmail.php3", which is in the current directory
<?php  include( "validateEmail.php3" ); 

    $email_address = "shane@tuna.org";
    $val_results = array( "", "" );

    $val_results = validateEmail( $email_address ); 

    if ( $val_results[0] == true )
        {
            $value = "<font color=\"green\">a valid</font>";
        } else {
            $value = "<font color=\"red\">not a valid</font>";
        }

   // print debugging info
    print( "<br>Debugging Info:<br><br>" );
    print( "<pre>" );
    print( "(valid/not valid)                   <font color=\"white\">value</font> is: " . $value. "<br>");
    print( "(true/false valid email)   <font color=\"white\">val_results[0]</font> is: " . $val_results[0] . "<br>");
    print( "(SMTP code if false)       <font color=\"white\">val_results[1]</font> is: " . $val_results[1] . "<br>");
    print( "(true/false valid MX host) <font color=\"white\">val_results[2]</font> is: " . $val_results[2] . "<br>");
    print( "(MX host that answered)    <font color=\"white\">val_results[3]</font> is: " . $val_results[3] . "<br>");
    print( "</pre>" );
    print( "<pre>true is represented by a 1 (one)<br>false is represented by null output</pre><br>");
    // end debugging info

    print( "The address <font color=\"white\"><tt>" . $email_address . "</tt></font> is " . $value . " email address.");
*/
    
?>

</body>
</html>

Comments or questions?
PX is running PHP 5.2.17
Thanks to Miranda Productions for hosting and bandwidth.
Use of any code from PX is at your own risk.