Проверка почты на Perl

Программа проверяет наличие новой почты. Проверяется кол-во сообщений. Если стало больше — у вас новое сообщение. Код писался с оглядкой на «читателя», поэтому, возможно, комментируются и очевидные места. Программа получает на вход параметры SERVER USER PASSWORD TIME. Последнее — время, через которое повторяются проверки. Программа работает по принципу «пока не остановишь».

При написании использовалась утилита zenity(отрисовка графического окна), о которой уже писалось ранее. Соединение с серврером идёт по протоколу POP 3, с которым можно ознакомится здесь. При запуске программа говорит нам, что у нас новое письмо… Это баг. Мне лень его править. Возникает он из-за того, что по-началу $count — наш счётчик писем нулевой.

Ещё один момент: адрес сервера, на котором находится сервер вашей почты, может(и скорее всего) не совпадать с адресом POP 3 сервера. К примеру, для mail.ru следует запрашивать pop3.mail.ru, для yandex.ru — pop.yandex.ru, у нашего местного «мегасайта» e1.ru , так вообще mail.e1.ru. Как узнать? — Спрашивайте на своих серверах. А вообще, это обычно на них публикуется…

Код подкрашен утилитой code2html

#!/usr/bin/perl
#
# Made by Helios aka h15 from UseUnix.RU
#
# параметры: Server User Pass Time

use strict; # Эта прагма не даст вам писать "неправильно", т.е. следит за
            # объявлением переменных и прочими делами.

use IO::Socket; # Для работы с сокетами высокого уровня.

my($count, $sock); # Глобальные переменные. Count - кол-во сообщений (именно
# так мы проверяем наличие нового), sock - сокет, который у нас один на всё.

while(1){ # Запускаем "вечный" цикл
    pop3_conn(@ARGV[0..2])? # коннектимся к серверу (+авторизация)
        print "[+] Permissoin allowed!\n": # Получилось!
        die "[-] Permission denied\n";     # Не получилось.

    check_for_new_mail(@ARGV[0..2]); # Непосредственно проверялка.

    &quit; # Выходим (по протоколу POP 3)

    sleep $ARGV[3]; # ReUse timer
# P.S. В @ARGV лежат параметры, передаваемые программе, начиная с нуля.
}

########################### Подпрограммы ###########################

# Подпрограмма выдаёт вход на консоль и в информационное окно (создавая его)
#
sub alert {
    my $msg = shift;
    print "[!] $msg\n";
# текст, заключённый в `` будет исполнен в командной строке.
    `zenity --info --title="Сообщение" --text="$msg"`;
# Информацию по утилите zenity можно найти здесь:
# http://useunix.ru/zenity-sozdanie-gtk-interfejsov-pryamo-iz-konsoli/
}

sub quit {
    print $sock "QUIT\n"; # Выходим
    my $answ = <$sock>;
    print "[i] Quit\n";
}

# Подпрограмма проверяет положительность ответа сервера
# На вход идёт ответ сервера
# На выходе - 0, если ответ положительный, 1 - в противном случае.
#
sub Chk {
    my $is = substr shift, 0, 1; # Берём 1ый символ
    return $is eq '+' ? 0 : 1;   # Если это "+" - возвращаем 0, иначе - 1
}

# Подпрограмма создаёт соединение с сервером, авторизуется
# Вход - Сервер, Юзер, Пароль
# Выход - 1, в случае успеха, 0 - в противном.
#
sub pop3_conn {
    my($srv, $user, $pass) = @_;
# Коннектимся к серверу $srv по TCP на порт 110 (порт протокола POP3). Т.е.
# создаём сокет(пару IP,ПОРТ).
#
# PeerPort можно было поставить "POP3" или "110", а можно и так, как сделали мы.
    $sock = IO::Socket::INET->new( # Сделали $sock глобальной.
        PeerAddr => $srv,
        Proto    => "tcp",
        PeerPort => "POP3 (110)"
    )   and print "[+] Connected!\n"
        or  die "[-] Can't connect to $srv\n";
# Ну, и, как обычно, если не смогли соединиться (вернули 0), умираем.

# Авторизуемся (по протоколу POP3)
    my $answ = <$sock>;        # Получаем приглашение авторизации
    return if Chk $answ;    # Проверяем положительный ли ответ пришёл

    print $sock "USER $user\n"; # Шлём на сервер user'а
    $answ = <$sock>;
    return if Chk $answ;

    print $sock "PASS $pass\n"; # Шлём пароль
    $answ = <$sock>;
    return if Chk $answ;

    1 # Возвращаем TRUE. Во всех предыдущих return летел FALSE.
}

sub get_mail_num {
    my($srv, $user, $pass, $err_cnt) = @_; # $err_cnt остаётся неинициированным
STAT:
# Если 10 раз не вышло переподключиться - ломаемся.
    alert("Smth broke... Sorry, $user.") and die("[-] Smth broke... Sorry.\n") if ++$err_cnt > 10;
    print $sock "STAT\n"; # Шлём на сервер запрос кол-ва сообщений и их размера.
    my $answ = <$sock>;
    pop3_conn(@_) and redo STAT if Chk $answ; # При ошибке, переустанавливаем соединение

    $answ =~ /^\s*\+\w+\s+(\d+)\s+/; # Достаем и ответа число писем

    $1 # Результат поиска лежит здесь, его возвращаем
}

# Подпрограмма проверяет наличие новых сообщений по кол-ву писем.
# Вход: Server, User, Password
# Выхода нет...
#
sub check_for_new_mail {
    my($srv, $user, $pass) = @_;
    my $mails = get_mail_num @_;
    if ($mails > $count){
        alert("New mail for $user");
        $count = $mails;
    }

    print "[i] Mail counter = $count\n";
}
Мне понравилась эта заметка:
"Имидж" дороже денег
Сравнение iPhone 6 и iPhone 5
Как MacBook, но не Mac
Ноутбук Dell XPS 15 L521X
Sony Extra Bass
Отзыв на наушники Sony Extra Bass
Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

*

Можно использовать следующие HTML-теги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>