#!/usr/bin/perl -w

# Skrypt wysyłający SMS-y na wszystkie polskie sieci przez bramkę
# www.idea.pl, portal "mbox" (tj. z koniecznością logowania).
# https://www.idea.pl/portal/map/map
# Napisany w Perlu. 
# Wymaga: perl + LWP + SSL (RPM-y dla RedHat: perl-libwww, perl-crypt-SSLeay).
#
# (c) 2003 Jacek Fiok <jfiok@jfiok.org>; http://sms.jfiok.org
#
# wysyła wiadomości: do 640 znaków; wszystkie polskie sieci.
#
# Podziękowania dla:
# - Spley <spley@home.pl>
# - Maciej Krzyzanowski <spider@popnet.pl>

use strict;
use HTTP::Request::Common;
use HTTP::Cookies;
use LWP::UserAgent;
use Crypt::SSLeay;
# use LWP::Debug qw(+ -conns);
# LWP::Debug::trace('send()');

# ----------------------- pomocnicze -------------------------
my $debug = 0;				# czy "tryb gadatliwy"
my $mode = 0;				# czy pracujemy z raportami doręczenia
my $wait_secs = 0;			# opóźnienie oczekiwania na raport

sub debug { if ($debug) { print "[", shift, "]\n"; } }

sub zakoncz {
  my ($tekst, $ret) = @_;
  print "$tekst\n";
  exit $ret;
}

# format struktury danych:
# string który możemy znaleźć w odpowiedzi z serwera =>
# [co należy z niego wywnioskować-opis, kod powrotu ze skryptu ]
my %odpowiedzi = (
	"Skrzynka wiadomości" => ["Wszystko OK", 0],
	"Zły numer" => ["Zły numer!", 2],
	"został wyczerpany" => ["Limit wiadomości na dziś przekroczony!", 3]
);

# główna procedurka analizująca odpowiedź serwera
# jeśli nie umiemy nic wywnioskować -> rzucamy [Nieznana Odpowiedz, 127]
sub analizujWynik {
	my $res = $_[0];
	my $searchString;
	my @val;
	while ( ($searchString, @val) = each (%odpowiedzi) ) {
	  if ($res =~ /$searchString/ ) {
		  print $odpowiedzi{$searchString}[0], "\n";
		  exit $odpowiedzi{$searchString}[1];
	  }		  
	}
	# jeśli nie znaleziono w opisach
	print "Nieznana odpowiedź:\n$res\n";
	exit 127;
}

# getCookie ($nazwa) -> wartość cookie; wymaga: $cookie_jar.
my $ckey = "";
my $cval = "";
my $cookie_jar = HTTP::Cookies->new;
# zwraca wartość ciasteczka dla podanej nazwy klucza
sub cookieScanner {
	# my $i; for ($i=0; $i<5; $i++) { print $i, " : ", $_[$i], "\n"; }
	($ckey eq $_[1]) and $cval = $_[2]; 
}
sub getCookie {
	$cval = "";
	$ckey = shift;
	$cookie_jar->scan (\&cookieScanner);
	return $cval;
}

my $ua = new LWP::UserAgent;
$ua->timeout(30);
$ua->agent("Mozilla/5.0 Galeon/1.2.7 (X11; Linux i686; U;) Gecko/20021216");
$ua->env_proxy();
$ua->cookie_jar($cookie_jar);

# odwiedza stronę $_[0]; w razie błędu wychodzi z tekstem $_[1] i kodem $_[2].
# w zmiennej globalnej $res ląduje HTML -- wynik zapytania.
my $res; my $req;
sub visit {
        $res = $ua->request (GET $_[0]);
        if (!($res->is_success)) { zakoncz($_[1], $_[2]); }
}
# ----------------------- main() -----------------------------

select(STDERR); $| = 1;     # make unbuffered
select(STDOUT); $| = 1;     # make unbuffered

if ($#ARGV != 3 ) { die "Zła ilość parametrów - podaj numer i treść sms-a"; }

my $numer = $ARGV[0];
my $tresc = $ARGV[1];
my $username = $ARGV[2];
my $password = $ARGV[3];
 
$numer =~ s/^\+48//;
$numer =~ s/^00//;

push @{ $ua->requests_redirectable }, 'POST';

# --------- konwersacja -----------

# 1. get sms-index
visit ("http://www.idea.pl/portal/map/map", 
       "Błąd przy otwieraniu formularza [1]", 1);

# 2. send the POST login form
#my $par1 = 'https://www.idea.pl/portal/map/map/homeo;SID='.getCookie ("SID").'?_DARGS=/portal/layoutTemplates/html/header_files/login.jsp';
my $par1 = 'https://www.idea.pl/portal/map/map/one;SID='.getCookie ("SID").'?_DARGS=/portal/layoutTemplates/html/header_files/login.jsp';

debug ("Logging in: ".$par1);
#my $par1 = 'https://www.idea.pl/portal/map/map/homeo?_DARGS=/portal/layoutTemplates/html/header_files/login.jsp';
#debug ("Logging in: ".$par1);

$req = POST $par1, [
	'dyncharset' => 'UTF-8',
	'_D:password' => " ",
	'password' => $password,
	'_D:login' => " ",
	'login' => $username,
	'/amg/ptk/map/core/formhandlers/AdvancedProfileFormHandler.value.login' => $username,
	'_D:/amg/ptk/map/core/formhandlers/AdvancedProfileFormHandler.value.login'  => " ",
	'/amg/ptk/map/core/formhandlers/AdvancedProfileFormHandler.value.password' => $password,
	'_D:/amg/ptk/map/core/formhandlers/AdvancedProfileFormHandler.value.password' => " ",
	'/amg/ptk/map/core/formhandlers/AdvancedProfileFormHandler.login.x' => 0,
	'/amg/ptk/map/core/formhandlers/AdvancedProfileFormHandler.login.y' => 0,
#	'_D:/amg/ptk/map/core/formhandlers/AdvancedProfileFormHandler.login' => " ",
#	"/amg/ptk/map/core/formhandlers/AdvancedProfileFormHandler.extractDefaultValuesFromProfile" => "false",
#	"_D:/amg/ptk/map/core/formhandlers/AdvancedProfileFormHandler.extractDefaultValuesFromProfile" => " ",
#	"/amg/ptk/map/core/formhandlers/AdvancedProfileFormHandler.loginSuccessURL" => "http://www.idea.pl/portal/map/map/pim",
#	"_D:/amg/ptk/map/core/formhandlers/AdvancedProfileFormHandler.loginSuccessURL" => " ",
#	"/amg/ptk/map/core/formhandlers/AdvancedProfileFormHandler.loginErrorURL" => "http://www.idea.pl/portal/map/map",
	"_D:/amg/ptk/map/core/formhandlers/AdvancedProfileFormHandler.login" => " ",
	"/amg/ptk/map/core/formhandlers/AdvancedProfileFormHandler.extractDefaultValuesFromProfile" => "false",
	"_D:/amg/ptk/map/core/formhandlers/AdvancedProfileFormHandler.extractDefaultValuesFromProfile" => " ",
	"/amg/ptk/map/core/formhandlers/AdvancedProfileFormHandler.loginSuccessURL" => "http://www.idea.pl/portal/map/map/pim;SID=".getCookie("SID"),
	"_D:/amg/ptk/map/core/formhandlers/AdvancedProfileFormHandler.loginSuccessURL" => " ",
	"/amg/ptk/map/core/formhandlers/AdvancedProfileFormHandler.loginErrorURL" => "http://www.idea.pl/portal/map/map;SID=".getCookie("SID"),
	"_D:/amg/ptk/map/core/formhandlers/AdvancedProfileFormHandler.loginErrorURL" => " ",
	
#	"/amg/ptk/map/core/formhandlers/AdvancedProfileFormHandler.currentUrl" => "/portal/map/map/one?_requestid=".getCookie("VisitorId"),
#	"_D:/amg/ptk/map/core/formhandlers/AdvancedProfileFormHandler.currentUrl" => " ",
	"/amg/ptk/map/core/formhandlers/AdvancedProfileFormHandler.currentPageName" => "One/Home",
	"_D:/amg/ptk/map/core/formhandlers/AdvancedProfileFormHandler.currentPageName" => " ",
	
	"_DARGS" => "/portal/layoutTemplates/html/header_files/login.jsp"
];


$req->referer ("http://www.idea.pl/");
$res = $ua->request($req);
if (!($res->is_success)) { zakoncz("Błąd przy logowaniu [2]", 1); }
#if (($res->content =~ /Nieprawidłowe hasło/) or (!($res->content =~ /Dziś jest/))) { zakoncz("Błąd przy logowaniu - nieprawidłowe hasło? [2]", 1); } 
if (($res->content =~ /Nieprawidłowe hasło/) or (!($res->content =~ /Twoje SMSy:/))) { zakoncz("Błąd przy logowaniu - nieprawidłowe hasło? [2]", 1); } 

debug ("zalogowany");

my $sms_zostalo = 666;
if ($res->content =~ /Twoje SMSy.*\n[^>]+>([^<]+)</) { $sms_zostalo = eval ($1); }
if ($sms_zostalo == 666) { zakoncz ("Nie mogę odczytać ilości dostępnych SMSów", 1); }
if ($sms_zostalo == 0) { zakoncz ("Limit wiadomości na ten miesiąc przekroczony", 3); }

visit ('http://www.idea.pl/portal/map/map/message_box?mbox_folder=INBOX&mbox_view=messageslist', "Błąd przy otwarciu skrzynki SMS [3]", 1);
visit ('http://www.idea.pl/portal/map/map/message_box?mbox_view=newsms&mbox_edit=new', "Błąd przy otwarciu formularza SMS [4]", 1);

debug ("przed wysłaniem POST");

# _DARGS=/gear/mapmessagebox/smsform.jsp na WWW jest i w GET string i w POST :)
$req = POST 'http://www.idea.pl/portal/map/map/message_box?_DARGS=/gear/mapmessagebox/smsform.jsp', [
'_dyncharset' => "ISO8859_2",
'/amg/ptk/map/messagebox/formhandlers/MessageFormHandler.type' => "sms",
'_D:/amg/ptk/map/messagebox/formhandlers/MessageFormHandler.type' => " ",
'/amg/ptk/map/messagebox/formhandlers/MessageFormHandler.errorURL' => '/portal/map/map/message_box?mbox_view=newsms',
'_D:/amg/ptk/map/messagebox/formhandlers/MessageFormHandler.errorURL'  => " ",
'/amg/ptk/map/messagebox/formhandlers/MessageFormHandler.successURL' => '/portal/map/map/message_box?mbox_view=messageslist',
'_D:/amg/ptk/map/messagebox/formhandlers/MessageFormHandler.successURL' => " ",
'/amg/ptk/map/messagebox/formhandlers/MessageFormHandler.to' => $numer,
'_D:/amg/ptk/map/messagebox/formhandlers/MessageFormHandler.to' => " ",
'_D:/amg/ptk/map/messagebox/formhandlers/MessageFormHandler.body' => " ",
'/amg/ptk/map/messagebox/formhandlers/MessageFormHandler.body' => $tresc,
'counter' => (640 - length($tresc)),
'/amg/ptk/map/messagebox/formhandlers/MessageFormHandler.create.x' => 0,
'/amg/ptk/map/messagebox/formhandlers/MessageFormHandler.create.y' => 0,
'_D:/amg/ptk/map/messagebox/formhandlers/MessageFormHandler.create' => " ",
'_DARGS' => '/gear/mapmessagebox/smsform.jsp'
];
$req->referer('http://www.idea.pl/portal/map/map/message_box?mbox_view=newsms&mbox_edit=new');

debug ("dotarłem OK do końca procedury, wysyłam...");

$res = $ua->request($req);
if (!($res->is_success)) { zakoncz("Błąd przy ostatecznym wysyłaniu SMS [5]", 1);
}
# analizujWynik ($res->content);

my $sms_zostalo2 = 666;
if ($res->content =~ /Twoje SMSy.*\n[^>]+>([^<]+)</) { $sms_zostalo2 = eval ($1); }
if ($sms_zostalo2 == 666) { zakoncz ("Nie mogę odczytać ilości dostępnych SMSów", 1); }
if ($sms_zostalo > $sms_zostalo2) {
	zakoncz ("Wszystko OK; pozostały limit wiadomości: ".$sms_zostalo2, 0); 
} else {
	zakoncz ("Wiadomość wysłana, ale STATUS NIEZNANY (pozostały limit: ".$sms_zostalo2.").", 0);
}

# TODO: to obsługuje raporty doręczenia!!!
# http://www.idea.pl/portal/map/map/message_box?mbox_view=sentmessageslist

