#!/usr/bin/perl
#checks for valid email address
#usage validemail <file containing email addresses>
use warnings;
use strict;
use Mail::CheckUser;
use Parallel::ForkManager;
use Fcntl qw/:flock :seek/;
use FileHandle;
my $pm=new Parallel::ForkManager(20);
my $addrfile = $ARGV[0] || die
"Usage validemail <file containing email addresses>
Will return two files: goodmails.csv and badmails.csv.
If these files exits already they will be deleted.";
my ($is_valid, $host, $x, @mx, $add, @adds);
#custom words that make emails invalid to you
my @custom = qw/
postmaster
webmaster
/;
my $regex = join "|", @custom;
$regex = qr/$regex/;
open (EMAILS, "$addrfile");
#remove troublesome windows /r characters
#and leading whitespace
while (<EMAILS>){
$_ =~ s/\015//;
$_ =~ s/^\s*//;
chomp $_;
push @adds, $_;
}
close (EMAILS);
#warning, I will delete existing files
open (BADADDR, ">badmails.csv") || die;
open (GOODADDR, ">goodmails.csv") || die;
#to prevent strange writing problems
#when running threads we must set the
#write buffers see
#to prevent strange writing problems
#when running threads we must set the
#write buffers see
#http://www.perlmonks.org/index.pl?node_id=348465
autoflush BADADDR 1;
autoflush GOODADDR 1;
#remove custom regexes
$x = 0;
while ($x <= $#adds){
if ($adds[$x] =~ m/$regex/){
splice @adds, $x, 1;
}else{
$x++;
}
}
#when using Mail::UserCheck set
#these variables
#timeout on DNS and SMTP network checks
$Mail::CheckUser::Timeout = 10;
foreach $add (@adds){
$pm->start and next;
if (Mail::CheckUser::check_email($add)){
writeaddr(*GOODADDR, $add); #address is good
$pm->finish;
}else{
writeaddr(*BADADDR, $add); #address is bad
$pm->finish;
}
}
$pm->wait_all_children;
close (BADADDR);
close (GOODADDR);
sub writeaddr{
my $FH = $_[0];
my $address = $_[1];
flock $FH, LOCK_EX or die "Flock failed: $!\n";
seek $FH, 0, 2 or die "Seek failed: $!\n";
print $FH "$address\n";
flock $FH, LOCK_UN or die "unFlock failed: $!\n";
}
|