#!/usr/bin/perl -w
use strict;
use LWP::Simple;
use HTML::TableExtract;
use Net::AIM;

my $aim_un = 'nazwa konta AIM';
my $aim_pw = 'haso na AIM';

# bazowy adres URL analizowanej witryny oraz
# adres URL strony z list bugtraq.
my $base_url = "http://www.security-focus.com";
my $url      = "http://www.security-focus.com/archive/1";

# pobieramy dane.
my $html_file = get($url) or die "$!\n";

# tworzymy dat ISO.
my ($day, $month, $year) = (localtime)[3..5];
$year += 1900; my $date = "$year-$month-$day";

# Interesujce nas dane s w tabeli, tabela ma nagwki,
# wic moemy opisa nagwki i za pomoc TableExtract pobra
wszystkie znajdujce si pod tymi nagwkami dane. Nasz kod
# HTML nie moe ulec zmianie, wic w formatach wynikowych moemy 
# skorzysta z hiperczy. zaczynamy analiz:
my $table_extract =
   HTML::TableExtract->new(
     headers   => [qw(Date Subject Author)],
     keep_html => 1 );
$table_extract->parse($html_file);

# analizujemy interesujce nas dane, wstawiamy je 
# do stosownej struktury danych.
my @parsed_rows; my $ctr = 0;
foreach my $table ($table_extract->table_states) {
   foreach my $cols ($table->rows) {
      @$cols[0] =~ m|(\d+/\d+/\d+)|;
      my %parsed_cols = ( "date" => $1 );

      # linki z tematem s w drugiej kolumnie, analizujemy niepotrzebny
      # kod HTML i pobieramy znaczniki <a>. Linki tematu maj adresy
      # wzgldne, wic musimy je rozwin. Moglibymy te uy moduw
      # URI::URL, HTML::Element, HTML::Parse i tak dalej.
      @$cols[1] =~ s/ class="[\w\s]*"//;
      @$cols[1] =~ m|(<a href="(.*)">(.*)</a>)|;
      $parsed_cols{"subject_html"} = "<a href=\"$base_url$2\">$3</a>";
      $parsed_cols{"subject_url"}  = "$base_url$2";
      $parsed_cols{"subject"}      = $3;

      # linki autorw s w trzeciej kolumnie; postpujemy analogicznie.
      @$cols[2] =~ s/ class="[\w\s]*"//;
      @$cols[2] =~ m|(<a href="mailto:(.*@.*)">(.*)</a>)|;
      $parsed_cols{"author_html"}  = $1;
      $parsed_cols{"author_email"} = $2;
      $parsed_cols{"author"}       = $3;

      # wstawiamy wszystkie informacje do tablicy tablic
      # asocjacyjnych, aby atwiej byo je pobiera.
      $parsed_rows[$ctr++] = \%parsed_cols;
   }
}

# tworzymy poczenie AIM.
my $aim = Net::AIM->new;
$aim->newconn(Screenname=>$aim_un,Password=>$aim_pw)
                or die "Niemoliwe poczenie z AIM.";
my $conn = $aim->getconn(  );

# przygotowujemy procedur obsugi komunikatw.
$conn->set_handler('im_in', \&on_im);
$conn->set_handler('error', \&on_error);
print "Zalogowany do AIM!\n\n";
$aim->start;

# przychodzce.
sub on_im {

    my ($aim, $evt, $from, $to) = @_;
    my $args = $evt->args(  );
    ($from, my $friend, my $msg) = @$args;

    # proste usuwanie kodu HTML.
    $msg =~ s/<(.|\n)+?>//g;

    # jeli uytkownik wysya nam komunikat "bugtraq",
    # odsyamy mu nasze dane.
    if( $msg =~ /bugtraq/ ) {

         # wysyamy pozycj po pozycji.
         foreach my $cols (@parsed_rows)  {

             # formatujemy pobrane dane.
             my $line = "$cols->{date} $cols->{subject} ".
                           "$cols->{subject_url}";

             # aby nie przekroczy ograniczenia prdkoci...
             sleep(2); $aim->send_im($from, $line);
         }
    } # jeli nie wiemy, o czym mowa, ostrzeenie.
    else { $aim->send_im($from, "Rozumiem tylko 'bugtraq'!"); }
}

# ups!
sub on_error {
    my ($self, $evt) = @_;
    my ($error, @stuff) = @{$evt->args(  )};

    # Przeoenie numeru bdu na komunikat angielski,
    # nastpnie filtr i okazujemy w STDERR.
    my $errstr = $evt->trans($error);
    $errstr =~ s/\$(\d+)/$stuff[$1]/ge;
    print "ERROR: $errstr\n";
}

