mirror of
https://github.com/Yetangitu/ampache
synced 2025-10-04 18:29:40 +02:00
663 lines
33 KiB
PHP
663 lines
33 KiB
PHP
<?php
|
|
/* vim:set tabstop=8 softtabstop=8 shiftwidth=8 noexpandtab: */
|
|
/*
|
|
validateEmail.php
|
|
version 2.0
|
|
by Clay Loveless <clay@killersoft.com>
|
|
|
|
|
|
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.
|
|
|
|
Enhancements 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.
|
|
|
|
By: berber
|
|
Organization: webdev.berber.co.il
|
|
Date: April 10th, 1999
|
|
Changes: - The script now handles all kinds of domains (not only @xxx.yyy) as before.
|
|
- Added a debugging mode which also works as a verbose mode.
|
|
|
|
By: Frank Vogel vogel@simec.com
|
|
Organization: Simec Corp. (http://www.simec.com)
|
|
Date: June 13th, 2000
|
|
Changes: - Check for MX records for each qualification step of the domain name
|
|
- Use nobody@$SERVER_NAME as MAIL FROM: argument
|
|
Disclaimers: I disclaim nothing...nor do I claim anything...but
|
|
it would be nice if you included this disclaimer...
|
|
|
|
|
|
NOTE: berber and Frank Vogel made some of the same changes regarding
|
|
domain name checking to seperate versions of Shane Gibson's validateEmail variant.
|
|
Their changes have been merged into version 2.0.
|
|
|
|
|
|
By: Clay Loveless <clay@killersoft.com>
|
|
Organization: KillerSoft < http://www.killersoft.com/ >
|
|
Date: March 12th, 2002
|
|
Changes: - Added 'Preferences' section, enabling several variables to be easily set
|
|
- Changed "nobody@$SERVER_NAME" for MAIL FROM: argument to be
|
|
"$from@$serverName" - set via Preferences section
|
|
- Signifcantly enhanced berber's 'debug' mode. It has become 'Verbose' mode
|
|
to ease debugging.
|
|
- Made 'Verbose' mode a function argument. Call validateEmail($email,1) to enable.
|
|
- Added environment detection - 'Verbose' output is adaptable to command-line
|
|
execution and embedded web execution.
|
|
- Added $socketTimeout Preferences variable for controlling how long we'll wait
|
|
during fsockopen() to any given host.
|
|
- Added $waitTimeout Preferences variable to control how long we'll wait for
|
|
a server we've successfully connected with to actually respond with an SMTP greeting.
|
|
Note -- this is a complete replacement of the previous "wait" method of simply
|
|
increasing a counter, which proved extremely inadequate in testing on sluggish hosts.
|
|
- Added $mxcutoff Preferences variable to control how many MX hosts we're willing to
|
|
talk to before calling it quits. (So we're not required to hear "no" from 14
|
|
hotmail.com mail servers if we don't want to.)
|
|
- Added routine to check SMTP server greeting line for ESTMP, and respond accordingly
|
|
with EHLO.
|
|
- Added routines to listen for multi-line output from servers.
|
|
- Fixed all commands ending in "\n" to end in "\r\n" as specified by accurate SMTP
|
|
communication. THIS FIXES THE "HANG" PROBLEM EXPERIENCED WITH MANY MAIL SERVERS,
|
|
INCLUDING AOL.COM. (See Disclaimers about AOL.com connections, though ...)
|
|
- Added support for Jeffrey E.F. Friedl's definitive email format regex, translated
|
|
from perl into PHP. Will reject email addresses with invalid formatting before
|
|
opening any server connections.
|
|
- Changed initial "listening" routine to listen for one of two SMTP greeting responses
|
|
(220 or 421) instead of just listening for anything. validateEmail is now well-behaved
|
|
if a 421 "temporary rejection" code is received.
|
|
- Assorted optimizations -- using explode() instead of split(), preg_match()
|
|
instead of ereg(), etc.
|
|
- Improved error reporting on failures.
|
|
- Fixed typos in comments. : )
|
|
- Modified comments where Shane Gibson's were no longer needed or accurate (due to changes).
|
|
Added the comments for features that didn't exist in Shane's version.
|
|
- Incremented version number.
|
|
|
|
Disclaimers: - All additions and modifications Copyright 2002 KillerSoft.com.
|
|
- Program is free for any use as long as these notes & credits remain intact.
|
|
- Yes, I know there is no foolproof way to validate an e-mail address. But this is better than
|
|
nothing.
|
|
- Yes, I know that fewer and fewer mail servers are supporting the type of connection
|
|
and validation that this script performs. There are still a hell of a lot more of them
|
|
that DO support it than those that DON'T. Yes, this may change over time.
|
|
- This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
|
without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
- By using this code you agree to indemnify Clay Loveless, KillerSoft, and Crawlspace, Inc.
|
|
from any liability that might arise from its use.
|
|
- Use at your own risk. This may not work for you. It may produce results other than what you'd expect,
|
|
or even prefer.
|
|
- AOL.COM Disclaimer: As of this release, mail servers operated by AOL.com (netscape.com,
|
|
aol.com, cs.com, anything with aoltw.net, just to name a few) return "250" (recipient OK) codes for
|
|
_any_ address you throw at them. Bounces for invalid recipients are handled and sent out
|
|
through alternate means. So -- this script won't help you in validating AOL.com (and affiliated)
|
|
e-mail addresses. BUT ... at least it won't choke/hang on them either, as previous versions
|
|
of this script would.
|
|
|
|
- Please send bugs, comments or suggestions to info@killersoft.com!
|
|
*/
|
|
|
|
/* 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
|
|
* IF no MX mail server found or connected to,
|
|
* errors will be explained in this response.
|
|
*
|
|
* Possible Internal error messages:
|
|
* Invalid email address (bad domain name) [ default message from the old days ]
|
|
* fsockopen error $errno: $errstr
|
|
* 554 No MX records found for $domain
|
|
* 554 No DNS reverse record found for $domain
|
|
*
|
|
* (554 Response code borrowed from ESMTP's "Transaction failed" response)
|
|
*
|
|
* 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 available at:
|
|
* http://www.killersoft.com/contrib/
|
|
*/
|
|
|
|
function validateEmail ( $email, $verbose=0 ) {
|
|
global $SERVER_NAME;
|
|
|
|
// DEFINE PREFERENCES
|
|
|
|
// Passed along with the HELO/EHLO statement.
|
|
// Leave blank to use $SERVER_NAME.
|
|
// Note that most modern MTAs will ignore (but require) whatever you say here ...
|
|
// the server will determine your domain via other means.
|
|
$mail_check = Config::get('mail_check');
|
|
$mail_check = $mail_check ? $mail_check : 'strict';
|
|
if ($mail_check == 'strict' && strncmp(PHP_OS, 'WIN', 3) === true) {
|
|
$mail_check = "easy";
|
|
}
|
|
|
|
$serverName = Config::get('mail_domain');
|
|
$serverName = $serverNam ? $serverName : 'example.com';
|
|
|
|
// MAIL FROM -- who's asking?
|
|
// Good values: nobody, postmaster, info, buckwheat, gumby
|
|
$from = Config::get('mail_user');
|
|
$from = $from ? $from : 'info';
|
|
|
|
// fsockopen() timeout - in seconds
|
|
$socketTimeout = 15;
|
|
|
|
// waitTimeout - how long we'll wait for a server to respond after
|
|
// a successful connection. In seconds.
|
|
// Recommended to keep this above 35 seconds - some servers are really slow.
|
|
$waitTimeout = 50;
|
|
|
|
// MX Server cutoff
|
|
// Some hosts (like hotmail.com) have MANY MX hosts -- 12 or more.
|
|
// Set this to a number where you'd like to say "I get the picture"
|
|
// ... so you don't wind up having to hit EVERY MX host.
|
|
$mxcutoff = 15;
|
|
|
|
// END OF PREFERENCES
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// DO NOT EDIT BELOW THIS LINE
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
// Default initiation statement
|
|
$send = "HELO";
|
|
|
|
// Let's give good commands
|
|
$CRLF = "\r\n";
|
|
|
|
// Make a few adjustments for verbose mode
|
|
if ( $verbose ) {
|
|
|
|
// Version
|
|
$version = "validateEmail 2.0 - http://killersoft.com/contrib/";
|
|
|
|
// Start stopwatch
|
|
list ( $msecStart, $secStart ) = explode ( " ", microtime() );
|
|
|
|
// Adjust verbose output format
|
|
// for php.cgi or webserver interface
|
|
$sapi_type = php_sapi_name();
|
|
if ( $sapi_type == "cgi" ) {
|
|
// format < >
|
|
$leftCarrot = "<";
|
|
$rightCarrot = ">";
|
|
// set type of "new line"
|
|
$vNL = "echo \"\n\";";
|
|
// verbose Flush Only
|
|
$vFlush = "";
|
|
// output for debugging
|
|
eval("echo \"Internal: $version - running as ".AddSlashes($sapi_type)."\"; $vNL");
|
|
} else {
|
|
// format < >
|
|
$leftCarrot = "<";
|
|
$rightCarrot = ">";
|
|
// set type of "new line" ... flush output for web browsing
|
|
echo "<pre>";
|
|
$vNL = "echo \"\n\"; flush();";
|
|
// verbose Flush Only
|
|
$vFlush = "flush();";
|
|
// output for debugging
|
|
eval("echo \"Internal: $version - running as ".AddSlashes($sapi_type)."\"; $vNL");
|
|
}
|
|
}
|
|
|
|
// How we'll identify ourselves in SMTP HELO/EHLO argument
|
|
if ( $serverName == "" ) $serverName = "$SERVER_NAME";
|
|
if ( $serverName == "" ) $serverName = "localhost";
|
|
|
|
// Initialize return values with default
|
|
$return[0] = false;
|
|
$return[1] = "Invalid email address (bad domain name)";
|
|
$return[2] = false;
|
|
$return[3] = "";
|
|
|
|
// make sure that we're dealing with a valid email address format
|
|
$isValid = true; // just in case validateEmailFormat is not available
|
|
if ( function_exists('validateEmailFormat') ) $isValid = validateEmailFormat ( $email );
|
|
|
|
// abort if necessary
|
|
if ( !$isValid ) {
|
|
if ( $verbose ) eval("echo \"Internal: $email format is invalid! Quitting ...\"; $vNL");
|
|
return $return;
|
|
|
|
} else {
|
|
if ( $verbose ) eval("echo \"Internal: $email is a valid RFC 822 formatted address\"; $vNL");
|
|
|
|
// assign our user part and domain parts respectively to seperate
|
|
// variables
|
|
list ( $user, $domain ) = explode ( "@", $email );
|
|
if ( $verbose ) {
|
|
eval("echo \"Internal: user ..... $user\"; $vNL");
|
|
eval("echo \"Internal: domain ... $domain\"; $vNL");
|
|
}
|
|
|
|
// split up the domain into sub-parts
|
|
$arr = explode ( ".", $domain );
|
|
|
|
// figure out how many parts there are in the host/domain name portion
|
|
$count = count ( $arr );
|
|
|
|
// flag to indicate success
|
|
$bSuccess = false;
|
|
|
|
// we try this for each qualification step of domain name
|
|
// (from full qualified to TopLevel)
|
|
for ( $i = 0; $i < $count - 1 && !$bSuccess; $i = $i + 1 ) {
|
|
|
|
// create the domain name
|
|
$domain = "";
|
|
for ( $j = $i; $j < $count; $j = $j + 1 ) {
|
|
$domain = $domain . $arr[$j];
|
|
if ( $j < $count - 1 )
|
|
// tack on the last dot
|
|
$domain = $domain . ".";
|
|
}
|
|
if ( $verbose ) eval("echo \"Internal: checking DNS for $domain ... \"; $vNL");
|
|
|
|
// Strict Mail Check
|
|
if($mail_check == "strict") {
|
|
// check that an MX record exists for Top-Level domain
|
|
// If it exists, start our email address checking
|
|
if (function_exists('checkdnsrr')) {
|
|
if ( checkdnsrr ( $domain, "MX" ) ) {
|
|
|
|
// Okay -- we've got a valid DNS reverse record.
|
|
if ( $verbose ) eval("echo \"Internal: ... Check DNS RR OK!\"; $vNL");
|
|
// Test that MX record for host exists,
|
|
// then fill 'mxhosts' and 'weight' arrays with correct info
|
|
if ( getmxrr ( $domain, $mxhosts, $weight ) ) {
|
|
|
|
// Now we've got MX records
|
|
if ( $verbose ) {
|
|
eval("echo \"Internal: MX LOOKUP RESULTS:\"; $vNL");
|
|
for ( $i = 0; $i < count ( $mxhosts ); $i++) {
|
|
eval("echo \" $mxhosts[$i]\"; $vNL");
|
|
}
|
|
}
|
|
// sift through the 'mxhosts', connecting to each one
|
|
// ONLY until we get a good match
|
|
$mxcount = count( $mxhosts );
|
|
// determine our MX host cutoff
|
|
$mxstop = ($mxcount > $mxcutoff) ? $mxcutoff : $mxcount;
|
|
for ( $i = 0; $i < $mxstop ; $i++ ) {
|
|
|
|
// open socket on port 25 to mxhost, setting
|
|
// returned socket pointer to $sp
|
|
if( $verbose ) eval("echo \"Internal: attempting to open $mxhosts[$i] ...\"; $vNL");
|
|
$sp = fsockopen ( $mxhosts[$i], 25, $errno, $errstr, $socketTimeout);
|
|
|
|
// Greeting Code default
|
|
// Sets default greeting code to 421, just in case we
|
|
// don't ever hear ANYTHING from this host.
|
|
// If we hear nothing, we'll want to skip it.
|
|
$greetCode = "421";
|
|
|
|
// if $sp connection is good, let's rock on
|
|
if ( $sp ) {
|
|
if ( $verbose ) {
|
|
eval("echo \"* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\"; $vNL");
|
|
eval("echo \"Internal: socket open to $mxhosts[$i]\"; $vNL");
|
|
}
|
|
// work variables
|
|
$waitMarker = 0;
|
|
$msec = 0; // milisec count
|
|
$tsec = 0; // tensec count
|
|
$out = "";
|
|
|
|
// set our created socket for $sp to
|
|
// non-blocking mode so that our fgets()
|
|
// calls will return with a quickness
|
|
set_socket_blocking ( $sp, false );
|
|
|
|
// as long as our 'out' variable does not begin
|
|
// with a valid SMTP greeting (220 or 421),
|
|
// keep looping (do) until we get something
|
|
do {
|
|
|
|
// prepare for clean debug output if necessary
|
|
// (puts a line break after the waitMarkers)
|
|
if ( $verbose && $msec > 0 ) {
|
|
$elapsed = $tsec + ($msec/4);
|
|
$clean = "echo \"($elapsed seconds)\"; $vNL";
|
|
}
|
|
// output of the stream assigned to
|
|
// 'out' variable
|
|
$out = fgets ( $sp, 2500 );
|
|
|
|
// Check for multi-line output (###-)
|
|
if ( preg_match ( "/^2..-/", $out ) ) {
|
|
$end = false;
|
|
while ( !$end ) {
|
|
// keep listening
|
|
$line = fgets ( $sp, 2500 );
|
|
$out .= $line;
|
|
if ( preg_match ( "/^2.. /", $line ) ) {
|
|
// the last line of output shouldn't
|
|
// have a dash after the response code
|
|
$end = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( $verbose && $out != "" ) eval("$clean echo \"Server: ".AddSlashes($out)."\"; $vNL");
|
|
|
|
// if we get a "220" code (service ready),
|
|
// we're ready to rock on
|
|
if ( substr ( $out, 0, 3 ) == "220" ) {
|
|
if ( $verbose ) eval("echo \"Internal: service ready on $mxhosts[$i] ... moving on\"; $vNL");
|
|
$return[2] = true;
|
|
$return[3] = "$mxhosts[$i]";
|
|
// determine if we should speak in terms of HELO or EHLO
|
|
if ( preg_match ( "/ESMTP/", $out ) ) {
|
|
$send = "HELO";
|
|
} else {
|
|
$send = "HELO";
|
|
}
|
|
|
|
// Set Greeting Code
|
|
$greetCode = "220";
|
|
|
|
}
|
|
|
|
// else if ...
|
|
// Perhaps we've gotten a 421 Temporarily Refused error
|
|
else if ( substr ( $out, 0, 3 ) == "421" ) {
|
|
|
|
//if ( $verbose ) echo " ... moving on\n";
|
|
if ( $verbose ) eval("echo \"Internal: $mxhosts[$i] temporarily rejected connection. (421 response)\"; $vNL");
|
|
$return[2] = false;
|
|
// Set Greeting Code
|
|
$greetCode = "421";
|
|
break; // get out of this loop
|
|
|
|
}
|
|
|
|
// increase our waitTimeout counters
|
|
// if we still haven't heard anything ...
|
|
// Note that the time looping isn't an exact science
|
|
// with usleep or the Windows hack ... but
|
|
// it's in the ballpark. Close enough.
|
|
if ( $out == "" && $msec < $waitTimeout ) {
|
|
|
|
// wait for a quarter of a second
|
|
if ( $verbose ) {
|
|
if ( $msec == 0 ) {
|
|
eval("echo \"Internal: Waiting: one '.' ~ 0.25 seconds of waiting\"; $vNL");
|
|
}
|
|
eval("echo \".\"; $vFlush");
|
|
$waitMarker++;
|
|
if ( $waitMarker == 40 ) {
|
|
// ten seconds
|
|
$tsec += 10;
|
|
eval("echo \" ($tsec seconds)\"; $vNL");
|
|
$waitMarker = 0;
|
|
}
|
|
}
|
|
$msec = $msec + 0.25;
|
|
usleep(250000);
|
|
|
|
} elseif ( $msec == $waitTimeout ) {
|
|
|
|
// let's get out of here. Toooo sloooooww ...
|
|
if ( $verbose ) eval("$clean echo \"Internal: !! we've waited $waitTimeout seconds !!\nbreaking ...\"; $vNL");
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
// end of 'do' loop
|
|
} while ( substr ( $out, 0, 3 ) != "220" );
|
|
|
|
// Make sure we got a "220" greetCode
|
|
// before we start shoveling requests
|
|
// at this server.
|
|
if ( $greetCode == "220" ) {
|
|
|
|
// reset our file pointer to blocking mode,
|
|
// so we can wait for communication to finish
|
|
// before moving on ...
|
|
set_socket_blocking ( $sp, true );
|
|
|
|
// talk to the MX mail server, attempt to validate
|
|
// ourself. Use "HELO" or "EHLO", as determined above
|
|
fputs ( $sp, "$send $serverName"."$CRLF" );
|
|
if ( $verbose ) eval("echo \"Client: $send $serverName\"; $vNL");
|
|
|
|
// get the mail server's reply, check it
|
|
//
|
|
$originalOutput = fgets ( $sp, 2500 );
|
|
// Check for multi-line positive output
|
|
if ( preg_match ( "/^...-/", $originalOutput ) ) {
|
|
$end = false;
|
|
while ( !$end ) {
|
|
// keep listening
|
|
$line = fgets ( $sp, 2500 );
|
|
$originalOutput .= $line;
|
|
if ( preg_match ( "/^... /", $line ) ) {
|
|
// the last line of output shouldn't
|
|
// have a dash after the response code
|
|
$end = true;
|
|
}
|
|
}
|
|
}
|
|
if ( $verbose ) eval("echo \"Server: ".AddSlashes($originalOutput)."\"; $vNL");
|
|
|
|
|
|
// if there's a HELP option, let's see it
|
|
if ( $verbose ) {
|
|
if( preg_match( "/250.HELP/m", $originalOutput ) && $verbose == true ) {
|
|
|
|
eval("echo \"Internal: VERBOSE-MODE ONLY: Getting the HELP output\"; $vNL");
|
|
// Get the output of the HELP command
|
|
fputs ( $sp, "HELP"."$CRLF" );
|
|
if ( $verbose ) eval("echo \"Client: HELP\"; $vNL");
|
|
// Get output again
|
|
$output = fgets ( $sp, 2500 );
|
|
// Check for multi-line positive output
|
|
if ( preg_match ( "/^...-/", $output ) ) {
|
|
$end = false;
|
|
while ( !$end ) {
|
|
// keep listening
|
|
$line = fgets ( $sp, 2500 );
|
|
$output .= $line;
|
|
if ( preg_match ( "/^... /", $line ) ) {
|
|
// the last line of output shouldn't
|
|
// have a dash after the response code
|
|
$end = true;
|
|
}
|
|
}
|
|
}
|
|
if ( $verbose ) eval("echo \"Server: ".AddSlashes($output)."\"; $vNL");
|
|
|
|
}
|
|
}
|
|
|
|
// Give the MAIL FROM: header to the server
|
|
fputs ( $sp, "MAIL FROM: <$from" . "@" . "$serverName" . ">"."$CRLF");
|
|
if ( $verbose ) eval("echo \"Client: MAIL FROM: $leftCarrot"."$from" . "@" . "$serverName" . "$rightCarrot\"; $vNL");
|
|
|
|
// Get output again
|
|
$output = fgets ( $sp, 2500 );
|
|
// Check for multi-line positive output
|
|
if ( preg_match ( "/^...-/", $output ) ) {
|
|
$end = false;
|
|
while ( !$end ) {
|
|
// keep listening
|
|
$line = fgets ( $sp, 2500 );
|
|
$output .= $line;
|
|
if ( preg_match ( "/^... /", $line ) ) {
|
|
// the last line of output shouldn't
|
|
// have a dash after the response code
|
|
$end = true;
|
|
}
|
|
}
|
|
}
|
|
if ( $verbose ) eval("echo \"Server: ".AddSlashes($output)."\"; $vNL");
|
|
|
|
// Give the RCPT TO: header for the email address we're testing
|
|
fputs ( $sp, "RCPT TO: <$email>"."$CRLF" );
|
|
if ( $verbose ) eval("echo \"Client: RCPT TO: $leftCarrot"."$email"."$rightCarrot\"; $vNL");
|
|
|
|
// Get output again
|
|
// This will be the one we check for validity
|
|
$output = fgets ( $sp, 2500 );
|
|
// Check for multi-line positive output
|
|
if ( preg_match ( "/^...-/", $output ) ) {
|
|
$end = false;
|
|
while ( !$end ) {
|
|
// keep listening
|
|
$line = fgets ( $sp, 2500 );
|
|
$output .= $line;
|
|
if ( preg_match ( "/^... /", $line ) ) {
|
|
// the last line of output shouldn't
|
|
// have a dash after the response code
|
|
$end = true;
|
|
}
|
|
}
|
|
}
|
|
if ( $verbose ) eval("echo \"Server: ".AddSlashes($output)."\"; $vNL");
|
|
|
|
// test the last reply code from the mail server
|
|
// for the 250 (okay) response
|
|
if ( substr ( $output, 0, 3 ) == "250" ) {
|
|
|
|
// set our true/false(ness)
|
|
// array item for testing
|
|
$return[0] = true;
|
|
$return[1] = $output;
|
|
if ( $verbose ) eval("echo \"Internal: Check for 250 ... Recipient OK\"; $vNL");
|
|
|
|
} else {
|
|
|
|
// we didn't get a 250
|
|
// may be a bogus address
|
|
if ( $verbose ) eval("echo \"Internal: Check for 250 ... Response did not begin with 250!\"; $vNL");
|
|
// fill in 2nd array item with mail server's
|
|
// reply for user to test if they want
|
|
$return[0] = false;
|
|
$return[1] = $output;
|
|
|
|
}
|
|
|
|
// tell the mail server we're done
|
|
fputs ( $sp, "QUIT"."$CRLF" );
|
|
if ( $verbose ) {
|
|
eval("echo \"Client: QUIT\"; $vNL");
|
|
eval("echo \"* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\"; $vNL $vNL");
|
|
}
|
|
|
|
// close the socket/file pointer
|
|
fclose ( $sp );
|
|
|
|
// If we got a good response back on RCPT TO,
|
|
// break here
|
|
// Otherwise, keep trying MX servers until we
|
|
// get a good response or run out of MX servers
|
|
// to try.
|
|
if ( $return[0] == true ) {
|
|
if ( $verbose ) {
|
|
eval("echo \"Internal: Recipient is OK - thanks, $mxhosts[$i]!\"; $vNL");
|
|
eval("echo \"Internal: Stop checking MX hosts ...\"; $vNL");
|
|
}
|
|
$bSuccess = true;
|
|
break;
|
|
}
|
|
|
|
} else {
|
|
|
|
// greetCode wasn't "220"
|
|
// we better skip this one and move on
|
|
if ( $verbose ) eval("echo \"Internal: SKIPPING $mxhosts[$i] -- never got 220 welcome\"; $vNL");
|
|
// close out this connection
|
|
fclose ( $sp );
|
|
|
|
} // end of greetCode check
|
|
|
|
} else {
|
|
// $sp socket pointer was false -- couldn't open it
|
|
if ( $verbose ) {
|
|
eval("echo \"* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\"; $vNL");
|
|
eval("echo \"Internal: could not open socket to $mxhosts[$i]!\"; $vNL");
|
|
eval("echo \"fsockopen error $errno: $errstr\"; $vNL");
|
|
eval("echo \"* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\"; $vNL $vNL");
|
|
}
|
|
$return[0] = false;
|
|
$return[1] = "fsockopen error $errno: $errstr";
|
|
} // end of $sp check
|
|
|
|
} // end for $mxhosts
|
|
|
|
} // getmxrr test
|
|
else {
|
|
// getmxrr failed
|
|
if ( $verbose ) eval("echo \"Internal: No MX reverse records found for $domain\"; $vNL");
|
|
$return[0] = false;
|
|
$return[1] = "554 No MX records found for $domain";
|
|
} // end getmxrr test
|
|
|
|
} // continue checkdnsrr test
|
|
else {
|
|
if ( $verbose ) eval("echo \"Internal: No DNS Reverse Record available!\"; $vNL");
|
|
$return[0] = false;
|
|
$return[1] = "554 No DNS reverse record found for $domain";
|
|
} // end checkdnsrr test
|
|
|
|
} // if function doesn't exist
|
|
} elseif ($mail_check == "easy") { // easy email address check
|
|
$pattern = "/^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,3})$/";
|
|
if(preg_match($pattern, $email)) {
|
|
$return[0] = true;
|
|
$return[1] = "OK";
|
|
} else {
|
|
$return[0] = false;
|
|
$return[1] = "NG";
|
|
}
|
|
} else { // Nothing to do
|
|
$return[0] = true;
|
|
$return[1] = "No Check";
|
|
}
|
|
|
|
} // end walking through each domain possibility
|
|
|
|
} // end isValid
|
|
|
|
// output elapsed time if Verbose
|
|
if ( $verbose ) {
|
|
list ( $msecStop, $secStop ) = explode ( " ", microtime() );
|
|
$elapsedTime = (double)($secStop + $msecStop) - ($secStart + $msecStart);
|
|
$elapsedTime = number_format($elapsedTime,3);
|
|
eval("echo \"Internal: VERBOSE-MODE execution time: $elapsedTime seconds (silent mode somewhat faster)\"; $vNL");
|
|
if ( $sapi_type != "cgi" ) echo "</pre>";
|
|
}
|
|
|
|
// return the array for the user to test against
|
|
return $return;
|
|
|
|
} // END validateEmail-2.0
|
|
|
|
?>
|