#!/usr/bin/perl

################################################################
#
# o2-sms.pl  (2010-05-01)
#
# (c) 2010  Mathias Adam <m.adam@adamis.de>
#
# Original version:
#
# 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_login    = '';
my $o2_kennwort = '';

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

my $base_url       = 'https://login.o2online.de/loginRegistration/loginAction' .
			'.do?_flowId=' . 'login&o2_type=asp&o2_label=login/co' .
			'mcenter-login&scheme=http&port=80&server=email.' .
			'o2online.de&url=%2Fssomanager.osp%3FAPIID%3DAUT' .
			'H-WEBSSO%26TargetApp%3D%2Fsms_new.osp%3F%26o2_type%3' .
			'Durl%26o2_label%3Dweb2sms-o2online';
my $login_url      = 'https://login.o2online.de/loginRegistration/loginAction.do';
#my $login_referrer = $login_url . '?scheme=http&server=web2sms.o2online.de&port=80&url=/web2sms/jsp/default.jsp';
my $sms_main_url   = 'https://email.o2online.de/ssomanager.osp?APIID=AUTH-WEBSSO&' .
			'TargetApp=/sms_new.osp%3f&o2_type=url&o2_label=web2sms-o2online';
my $sms_main2_url  = 'https://email.o2online.de/smscenter_new.osp?Autocompletion=1&MsgContentID=-1';
my $sms_post_url   = 'https://email.o2online.de/smscenter_send.osp';

my $text_maxlen       = 1800;	# 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');
#TODO: wired check is more complicated now since send_prefix isn't a separate argument anymore

# --------------- 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_number = 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

warn("Message has more than $text_maxlen_wired chars, might cause problems with some (e.g. wired) recipients.\n")
	if (length($send_messagetext) > $text_maxlen_wired);

#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.');
#}
if (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)) {	# TODO: welche Randbedingungen gelten?
#	raiseErr (6, 'Please enter a number between 4 and 12 digits.'),
#}
elsif ($send_number !~ /^\+[0-9]*(,\+[0-9]*)*$/) {
	raiseErr (7, 'Number may contain only digits except the first char must be "+".');
}

# --------------- 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);

#printf($response->content);

# --------------- 1b. get Flow Execution Key from response

$response->content =~ /name=\"_flowExecutionKey\" value=\"(.*)\" \/>/;
my $flowExecutionKey = $1;

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

$response = $ua->post (
  $login_url,
  [
	'_flowExecutionKey'	=> $flowExecutionKey,
	'loginName'		=> $o2_login,
	'password'		=> $o2_kennwort,
	'_eventId'		=> 'login'
  ],
);

#printf($response->content);

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

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

# --------------- 3b. get New SMS page (session ID, etc.)

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

#printf($response->content);
# das hier liefert das <form name=\"frmSMS\"...,
# vgl. getSendPostRequest in 02_webSMSsend/webSMSsend-0.4.5-src/NetworkHandler.java

$response->content =~ /<span class=\"FREESMS\"><strong>Frei-SMS: (.+) Web2SMS noch in diesem Monat mit Ihrem Internet-Pack inklusive!<\/strong><\/span><br>/;
my $remSMSstring = $1;

print("noch $remSMSstring SMS frei diesen Monat\n");

$response->content =~ /<input type=\"Hidden\" name=\"SID\" value=\"(.*)\"/;
my $argumentSID = $1;
#print("SID=$argumentSID\n");

$response->content =~ /<input type=\"Hidden\" name=\"RURL\" value=\"(.*)\"/;
my $argumentRURL = $1;
#print("RURL=$argumentRURL\n");

$response->content =~ /<input type=\"Hidden\" name=\"REF\" value=\"(.*)\"/;
my $argumentREF = $1;
#print("REF=$argumentREF\n");

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

my $response = $ua->post (
  $sms_post_url,
  [
	'SID'			=> $argumentSID,
	'MsgContentID'		=> '-1',
        'FlagDLR'		=> '0',
        'FlagFlash'		=> '0',
        'FlagAnonymous'		=> '0',
        'FlagDefSender'		=> '0',
        'FlagVCal'		=> '0',
        'FlagVCard'		=> '0',
        'CID'			=> '-1',
        'DID'			=> '-1',
        'RepeatStartDate'	=> '2010,1,17,4,00,00',		# TODO
        'RepeatEndDate'		=> '2010,1,17,4,00,00',		# TODO
        'RepeatType'		=> '0',
        'RepeatEndType'		=> '0',
        'FolderID'		=> '0',
        'SMSToNormalized'	=> '',
        'FID'			=> '',
        'RURL'			=> $argumentRURL,
        'REF'			=> $argumentREF,

	'SMSTo'			=> $send_number,
	'SMSText'		=> $send_messagetext,
	'SMSFrom'		=> '',
	'Frequency'		=> '5'
  ],
);

#printf($response->content);

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

sub syntax () 
{
	print<<EOT;

Syntax: o2-sms.pl [-f] <number>[,<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 1800 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);
}
	
