#!/usr/bin/perl

################################################################
#
# o2-sms.pl, v2.0beta
#
# Copyright (c) 2002-04 Leonhard Fellermayr <leo@rockdiebu.de>
# All rights reserved.
#
################################################################

# -------------- used packages

use strict;
use URI::Escape;
use LWP::UserAgent;
use HTTP::Request::Common;
use HTTP::Cookies;

# --------------- your login data at O2 - please set

my $o2_vorwahl  = '0179';
my $o2_nummer   = '1234567';
my $o2_kennwort = 'lessssssecret';

# --------------- URLs of O2 online interface

my $base_url       = 'http://web2sms.o2online.de/';
my $login_url      = 'https://login.o2online.de/login/pa/jsp/login.jsp';
my $login_referrer = $login_url . '?scheme=http&server=web2sms.o2online.de&port=80&url=/web2sms/jsp/default.jsp';
my $sms_main_url   = $base_url . 'web2sms/jsp/default.jsp';
my $sms_post_url   = $sms_main_url . '?check=1';
my $sms_main2_url  = $base_url . 'web2sms/jsp/result1.jsp';
my $sms_post2_url  = $base_url . 'web2sms/jsp/result2.jsp';

my $text_maxlen       = 780;	# max length when sending to other cellphones
my $text_maxlen_wired = 160;	# max length when doing "Text-to-speech"

# known german cellphone prefixes (everything else is assumed "wired")
my @mobilePrefixes = qw ('0179','0176','0160','0162','0163','0170','0171','0172','0173','0174','0175','0177','0178','01505','01511','01520','01566','0151');

# --------------- fake one of these user agents via rand() call below

my %agents = (   0 => 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)',
                 1 => 'Mozilla/4.0 (compatible; MSIE 5.0; Windows 98; DigExt)',
                 2 => 'Mozilla/5.0 Galeon/1.2.5 (X11; Linux i686; U;) Gecko/20020606',
                 3 => 'Mozilla/4.0 (compatible; MSIE 5.0; Windows 2000) Opera 6.04  [en]',
                 4 => 'Mozilla/4.0 (compatible; MSIE 5.5; Windows 98; Win 9x 4.90)',
                 5 => 'Mozilla/5.0 (Windows; U; Windows NT 5.1; de-DE; rv:1.7b) Gecko/20040421',
                 6 => 'Mozilla 4.0 (compatible; MSIE 5.01; Windows NT 5.0)',
                 7 => 'Mozilla/4.0 (compatible; MSIE 6.0; Windows 98)',
                 8 => 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 4.0; LVR)',
                 9 => 'Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)',
                10 => 'Mozilla/5.0 (X11; U; Linux i586; en-US; rv:1.1b) Gecko/20020722'
             );

# --------------- get command line arguments

if ($#ARGV < 0) {
	&syntax ();
	exit (0);
}

my $send_flash = '';
if ($ARGV[0] =~ /-f/) {
	$send_flash = 'on';
	shift (@ARGV);
}

my $send_prefix      = $ARGV[0];
my $send_number      = $ARGV[1];

shift (@ARGV); shift (@ARGV);

my $send_messagetext = join (" ", @ARGV);

# --------------- check if this message goes to wired network

my $wired = 0;
foreach (@mobilePrefixes) {
	$wired = 1 if ($_ == $send_prefix);
}

# --------------- perform some checks on given data

if (($wired) && (length($send_messagetext)) > $text_maxlen_wired) {
	raiseErr (1, 'Message goes as Message-To-Speech to wired network - message text only can have up to ' . $text_maxlen_wired . ' chars.');
}
elsif (length ($send_messagetext) > $text_maxlen) {
	raiseErr (2, 'Message text is too long - can have up to ' . $text_maxlen . ' chars.');
}
elsif ($send_prefix =~ /^[^0]/) {
	raiseErr (3, 'Prefix must start with 0.');
}
elsif ($send_prefix =~ /^\d0/) {
	raiseErr (4, 'Only can send nationally.');
}
elsif ((length($send_prefix) < 3) || (length($send_prefix) > 5)) {
	raiseErr (5, 'Please enter a prefix between 3 and 5 digits.');
}
elsif ((length($send_number) < 4) || (length($send_number) > 12)) {
	raiseErr (6, 'Please enter a number between 4 and 12 digits.'),
}
elsif ($send_prefix =~ /[^0-9]/) {
	raiseErr (7, 'Prefix may contain only digits.');
}
elsif ($send_number =~ /[^0-9]/) {
	raiseErr (8, 'Number may contain only digits.');
}

# --------------- set up a new user agent object

my $ua = new LWP::UserAgent;
my $response;

# --------------- fake a real user agent

my $max = -1;
$max++ foreach (keys %agents);
$ua->agent ($agents{int (rand ($max))});

# --------------- enable cookie transport

my $cookies = new HTTP::Cookies;
$ua->cookie_jar ($cookies);

# --------------- 1. get base URL

$response = $ua->request (GET $base_url);

# --------------- 2. post LOGIN data

$response = $ua->post (
  $login_url,
  [
	'vorwahl'              => $o2_vorwahl,
	'pin_fld_login'        => $o2_nummer,
	'pin_fld_passwd_clear' => $o2_kennwort,
	'appl'                 => 'web2sms.o2online.de',
	'login'                => 'login',
	'hID'                  => '07'
  ],
);

# --------------- 3. go to SMS main page (meta redir)

$response = $ua->request (GET $sms_main_url);

# --------------- 4. post SMS data

my $response = $ua->post (
  $sms_post_url,
  [
	'prefix'       => $send_prefix,
	'msisdn'       => $send_number,
	'messagetext'  => $send_messagetext,
	'anzahl'       => length ($send_messagetext),
	'flash'        => $send_flash,
	'phonebook'    => '',
	'friendlyname' => ''
  ],
);

# --------------- 5. get AGB confirmation page

$response = $ua->request (GET $sms_main2_url);

# --------------- 6. post confirmation

$response = $ua->post ($sms_post2_url);

########################################################################################

sub syntax () 
{
	print<<EOT;

Syntax: o2-sms.pl [-f] <prefix> <number> <message text>

This script is intended for customers of O2 Germany that have an account at
www.o2online.de. These are able to send SMS via the WWW gateway at less
cost. o2-sms.pl brings this service down to your UNIX shell.

Use -f option to send flash SMS (will pop up on the recipient's display
immediately).

Message text can have up to 780 chars. NOTE: SMS to wired recipients are
limited to 160 chars, as they are being sent as "text-to-speech".

EOT
}

sub raiseErr ($$)
{
	my $exitNo = shift;
	my $errText = shift;

	&syntax ();
	print "ERROR: $errText\n\n";
	exit ($exitNo);
}
	
