#!/usr/bin/perl

# http://www.nanpa.com/nanp1/allutlzd.zip
use strict;
use Socket;
use Carp;
use IO::Handle;
use IO::Socket;

my $port = 4573;
my $sendmail = "/usr/sbin/sendmail -t";

chdir '/'                 or die "Can't chdir to /: $!";
umask 0;

$|=1;

# Setup some variables
my %AGI; my $tests = 0; my $fail = 0; my $pass = 0;

sub checkresult {
	my ($res) = @_;
	my $retval;
	$tests++;
	chomp $res;
	if ($res =~ /^200/) {
		$res =~ /result=(-?\d+)/;
		if (!length($1)) {
			print STDERR "FAIL ($res)\n";
			$fail++;
		} else {
			print STDERR "PASS ($1)\n";
			$pass++;
		}
	} else {
		print STDERR "FAIL (unexpected result '$res')\n";
		$fail++;
	}
}

  my %nanpa;
  my @countrycodes;
  my %countryinfo;

  print("Loading NANPA data: ");
  open (NANPA, "/data/allutlzd.txt") or die("Cannot open NANPA file");
  while (my $npline = <NANPA>) {
  	my @npdata = split(/\t/, $npline);
	$nanpa{$npdata[1]}{'state'} = $npdata[0];
	$nanpa{$npdata[1]}{'company'} = $npdata[3];
	$nanpa{$npdata[1]}{'ratecenter'} = $npdata[4];
  }
  close(NANPA);
  print "done\n";

  print("Loading allcodes data: ");
  open (NANPA, "/data/allcodes.txt") or die("Cannot open allcodes file");
  while (my $line = <NANPA>) {
  	my @data = split(/\t/, $line);
	$data[0] =~ s/-| //g;
	$data[1] =~ s/\r|\n//g;
	$data[2] =~ s/\r|\n//g;

	push (@countrycodes, @data[0]);
	$countryinfo{$data[0]}{'country'} = $data[1];
	$countryinfo{$data[0]}{'region'} = $data[2];
  }
  close(NANPA);
  print "done\n";

  # Has to be sorted 
  @countrycodes = sort {$a cmp $b} (@countrycodes); 

defined(my $pid = fork)   or die "Can't fork: $!";
exit if $pid;
#setsid                    or die "Can't start a new session: $!";


socket(SERVER, PF_INET, SOCK_STREAM, 0);
setsockopt(SERVER, SOL_SOCKET, SO_REUSEADDR, pack("l", 1));
bind(SERVER, sockaddr_in($port, INADDR_ANY)) || die("can't bind\n");
listen(SERVER, SOMAXCONN);

open STDIN, '/dev/null'   or die "Can't read /dev/null: $!";
open STDOUT, '>/dev/null' or die "Can't write to /dev/null: $!";
open STDERR, '>/dev/null' or die "Can't write to /dev/null: $!";


for(;;) {
	my $line;
	my $realnum;
	my $state = "??";
	my $city = "?";
	my $raddr = accept(CLIENT, SERVER);
	my ($s, $p) = sockaddr_in($raddr);
	CLIENT->autoflush(1);
	while(<CLIENT>) {
		chomp;
		last unless length($_);
		if (/^agi_(\w+)\:\s+(.*)$/) {
			$AGI{$1} = $2;
		}
	}

	if ($AGI{request} =~ /line=([0-9])/) {
		$line = $1;
	}

	$realnum = $AGI{callerid};


		if ($realnum =~ /^00(.+)$/) {
			       $realnum = "+" . $1;
		}
		if ($realnum =~ /^0([12].+)$/) {
			$realnum = "+44" . $1;
		}

	if ($realnum =~ m/^\+1([0-9][0-9][0-9])([0-9][0-9][0-9])/)
	{
	   $userid = $nanpa{"$1-$2"}{'state'}."/".$nanpa{"$1-$2"}{'ratecenter'} if (!$userid);
	  
	  $state = $nanpa{"$1-$2"}{'state'};
	  $city = $nanpa{"$1-$2"}{'ratecenter'};
	} else {
		foreach (@countrycodes) {
			my $code = $_;
			my $code2 = $_;
			if ($code =~ m/^\+([0-9]+)/) {
			 	if ($realnum =~ m/^\+$1/) {
					$state = $countryinfo{$code2}{'country'};
					$city = $countryinfo{$code2}{'region'};
				}
			}
		}
	}

	open(SENDMAIL, "|$sendmail") or die "Cannot open $sendmail: $!"; 
	print SENDMAIL "Subject: Incoming call on line $line / $realnum ($userid) $state $city\n"; 
	print SENDMAIL "To: someone\@somewhere.com\n"; 
	print SENDMAIL "Content-type: text/plain\n\n"; 

	print SENDMAIL "AGI Environment Dump from $s:$p --\n";
	foreach my $i (sort keys %AGI) {
		print SENDMAIL " -- $i = $AGI{$i}\n";
	}
	close(SENDMAIL);

	print CLIENT "SET CALLERID $line$AGI{callerid}\n";
	my $result = <CLIENT>;
	&checkresult($result);
	close(CLIENT);
}
