Иногда программисту приходится сталкиваться с определенными ситуациями, которые сводятся к приему какой-либо информации. Она может носить как верный, так и неверный характер. Яркий пример такого случая - запрос E-mail адреса со стороны клиента. Требуется наиболее точно определить достоверность этого адреса. Что примечательно, решения у этой задачи нет, так как проверить E-mail адрес на 100% точность невозможно. Сам "синтаксис" адреса может быть правильным, но адреса может не существовать
в принципе.
Попробуем решить данную задачу, хоть это и невозможно на все 100%. Подступов может быть несколько. Все зависит от сложности проекта и последствий
на случай, если адрес окажется некорректным.
Самое простое - проверка синтаксиса E-mail адреса. По сути, адрес представляет собой три части: имя пользователя, имя хоста и домен. Требования к этим частям следующие: имя юзера не должно содержать спецсимволов, ровно как и весь адрес. Юзер и хост, хост и домен должны быть разделены собакой и точкой соответственно.
Реализуем это программно. Вот код, который проверяет адрес на валидность.
#!/usr/bin/perl
## Проверка E-mail адреса на правильность
#!/usr/bin/perl
chomp($email=
if ($email=~/(\w+)\@(\w+)\.(\w+)/) {
print "E-mail верный\n"
} else {
print "E-mail неверный\n"
}
exit;
Все это работает, даже при такой банальной проверке. Но, еще раз скажу, проверка синтаксиса это только начало. Основная проверка должна показать истинность или ложь E-mail адреса, основываясь на показания сервера. Эти показания могут быть получены с smtpd, причем если доступна команда vrfy, которая показывает, есть ли данный E-mail в системе. Как ты понимаешь, использование vrfy небезопасно, поэтому большинство админов делают эту команду недоступной. Но тем не менее, я расскажу как проверить адрес используя 25 порт.
Для осуществления задуманного, нам необходимо наличие модуля Net::DNS, который достанет MX для заданного хоста. Затем, осуществим соединение с MX-сервером и получим данные (если таковые имеются). Если команда отключена - просто завершим работу скрипта.
Итак, собственно код:
#!/usr/bin/perl
use strict;
use IO::Socket;
use Sys::Hostname; ## Заюзаем модуль определения хоста и сокеты
my $mx=0;
eval {
require Net::DNS; ## подгрузим модуль DNS
Net::DNS->import("mx");
$mx=1;
}
foreach $addr (@ARGV) {
($name,$host)=split(/\@/,$addr); ## Пропарсим командную строку на наличие адресов для проверки
my @hostnames;
@hosts = map {$_->exchange } mx($host) if $mx; ## Если модуль DNS был подгружен - узнаем MX
@hosts=($host) unless @hosts; ## Иначе подразумеваем, что MX и есть хост
foreach $host (@hosts) {
$sock=IO::Socket::INET->new("$host:25"); ## Создаем соединение для каждого хоста
$sock->autoflush(1); ## Вырубим буферайз
print $sock "HELO ".hostname()."\015\012";
print $sock "VRFY $host\015\012";
print $sock "QUIT\015\012"; ## Проверим адрес VRFY
while($sock) {
/^220\b/ && next; ## Если все ок - выведем данные
/^221\b/ && last; ## Иначе - использование VRFY невозможно
s/250\b[\-\s]+//;
print;
}
close($sock); ## Закроем сокет
}
Таким образом можно добиться проверки адреса на валидность, уже подтвержденную сервером. Тебе осталось лишь корректно обработать данные, которые скажет сервер и делать выводы о правильности мыльника.
Но еще раз замечу, что данная задача не может быть решена
до конца, ибо корректный мыльник опознать довольно проблематично...