#!/usr/bin/perl # # Asterisk(tm) Calling Card Platform # # Copyright (C) 2004, Digium, Inc. # # Mark Spencer ) { chomp; my ($var, $val) = split(/\s*\=\s*/); $config{$var} = $val; } close(CFG); } sub users_load_config() { open(CFG, ") { chomp; my ($var, $val) = split(/\s*\=\s*/); $users_config{$var} = $val; } close(CFG); } sub users_connect_db() { my $users_dsn = "DBI:mysql:database=$users_config{'dbname'};host=$users_config{'dbhost'}"; $users_dbh->disconnect if $users_dbh; $users_dbh = DBI->connect($users_dsn, $users_config{'dbuser'}, $users_config{'dbpass'}); } sub connect_db() { my $dsn = "DBI:mysql:database=$config{'dbname'};host=$config{'dbhost'}"; $dbh->disconnect if $dbh; $dbh = DBI->connect($dsn, $config{'dbuser'}, $config{'dbpass'}); } sub users_create_db() { my $users_drh = DBI->install_driver("mysql"); return -1 unless $users_drh; return -1 unless $users_drh->func('createdb', $users_config{'dbname'}, $users_config{'dbhost'}, $users_config{'dbuser'}, $users_config{'dbpass'}, 'admin'); users_connect_db(); return -1 unless $users_dbh; return -1 unless $users_dbh->do("CREATE TABLE sipfriends (name CHAR(40) NOT NULL PRIMARY KEY, username CHAR(40), secret CHAR(40) NOT NULL, context char(40) NOT NULL, ipaddr char(20) NOT NULL, port INTEGER(6) NOT NULL default '0', regseconds INTEGER(11))"); return -1 unless $users_dbh->do("CREATE TABLE iaxfriends (name CHAR(40) PRIMARY KEY, secret CHAR(40), context CHAR(40), ipaddr CHAR(20), port INTEGER(6), regseconds INTEGER(11) NOT NULL)"); return 0; } sub create_db() { my $drh = DBI->install_driver("mysql"); return -1 unless $drh; return -1 unless $drh->func('createdb', $config{'dbname'}, $config{'dbhost'}, $config{'dbuser'}, $config{'dbpass'}, 'admin'); connect_db(); return -1 unless $dbh; return -1 unless $dbh->do("CREATE TABLE brands (name CHAR(40) PRIMARY KEY, language CHAR(10), publishednum CHAR(40), did char(40), markup INTEGER, inc INTEGER, fee INTEGER, days INTEGER)"); return -1 unless $dbh->do("CREATE TABLE cards (number CHAR(20) PRIMARY KEY, language CHAR(10), facevalue INTEGER, used INTEGER NOT NULL, inc INTEGER NOT NULL, markup INTEGER NOT NULL, creation TIMESTAMP, firstuse TIMESTAMP, expiration TIMESTAMP, inuse INTEGER, brand CHAR(40), nextfee INTEGER, pin INTEGER)"); return -1 unless $dbh->do("CREATE TABLE trunks (name CHAR(40) PRIMARY KEY, tech CHAR(10), path CHAR(40) NOT NULL)"); return -1 unless $dbh->do("CREATE TABLE routes (pattern CHAR(40) PRIMARY KEY, comment CHAR(80), trunks CHAR(80), connectcost INTEGER NOT NULL, includedseconds INTEGER NOT NULL, cost INTEGER NOT NULL)"); return -1 unless $dbh->do("CREATE TABLE cdrs (cardnum CHAR(40), callerid char(80), callednum CHAR(80), trunk CHAR(40), disposition CHAR(20), billseconds INTEGER, billcost INTEGER)"); return 0; } sub update_db() { $dbh->do("ALTER TABLE cdrs ADD COLUMN callstart CHAR(24)"); $dbh->do("ALTER TABLE cards ADD COLUMN pin INTEGER"); $dbh->do("ALTER TABLE cards ADD COLUMN expiration TIMESTAMP"); $dbh->do("ALTER TABLE cards ADD COLUMN creation TIMESTAMP"); $dbh->do("ALTER TABLE cards ADD COLUMN firstuse TIMESTAMP"); $dbh->do("ALTER TABLE cards ADD COLUMN nextfee INTEGER"); $dbh->do("ALTER TABLE cards ADD COLUMN brand CHAR(40)"); $dbh->do("ALTER TABLE cards ADD COLUMN pin INTEGER"); return 0; } sub save_config() { my $tmp; open(CFG, ">/var/lib/astcc/astcc-config.conf"); print CFG ";\n; Automatically created by astcc-admin.cgi.\n;\n"; foreach $tmp (keys %config) { print CFG "$tmp = $config{$tmp}\n"; } close(CFG); } sub users_save_config() { my $tmp; open(CFG, ">/var/lib/astcc/users-astcc-config.conf"); print CFG ";\n; Automatically created by astcc-admin.cgi.\n;\n"; foreach $tmp (keys %users_config) { print CFG "$tmp = $users_config{$tmp}\n"; } close(CFG); } sub build_menu() { my ($selected) = @_; my $body; my $tmp; my $bgcolor, $fgcolor; $body = "\n"; foreach $tmp (@modes) { if ($tmp eq $selected) { if (($tmp eq "Configure") && !$dbh) { $bgcolor = "#ff4400"; } else { $bgcolor = "#ff8800"; } $fgcolor = "#ffffff"; } else { if (($tmp eq "Configure") && !$dbh) { $bgcolor = "#cc0000"; } else { $bgcolor = "#ccccff"; } $fgcolor = "#999999"; } $body .= "\n"; } $body .= "
" . "" . "  $tmp" . "
\n"; return $body; } sub build_home() { return "
Welcome to the Asterisk™ Calling Card Admin. Please select " . "a function from the menu on the left.
" } sub list_brands() { my $sth; my @brandlist; my $row; $sth = $dbh->prepare("SELECT name FROM brands"); $sth->execute; while($row = $sth->fetchrow_hashref) { push @brandlist, $row->{name}; } $sth->finish; if ($#brandlist > -1) { return popup_menu(-name => "brand", -values => \@brandlist); } return ""; } sub list_cards() { my $sth; my @cardlist; my $row; $sth = $dbh->prepare("SELECT number FROM cards"); $sth->execute; while($row = $sth->fetchrow_hashref) { push @cardlist, $row->{number}; } $sth->finish; return @cardlist; } sub list_trunks() { my $sth; my @trunklist; my $row; my ($name, $def) = @_; $sth = $dbh->prepare("SELECT name FROM trunks"); $sth->execute; while($row = $sth->fetchrow_hashref) { push @trunklist, $row->{name}; } $sth->finish; if ($#trunklist > -1) { unshift(@trunklist, ""); return popup_menu(-name => "$name", -values => \@trunklist, -default => $def); } return ""; } sub count_cards() { my ($clause) = @_; my $row; my $res; $sth = $dbh->prepare("SELECT COUNT(*) FROM cards $clause"); $sth->execute; $row = $sth->fetchrow_hashref; $res = $row->{"COUNT(*)"}; $sth->finish; return $res; } sub isunique() { my ($number) = @_; my $clause = "WHERE number = " . $dbh->quote($number); my $count = &count_cards($clause); return 1 if $count == "0"; return 0; } sub findunique() { my $number; for (;;) { $number = int(rand() * 9000 + 1000) . int(rand() * 9000 + 1000) . int(rand() * 9000 + 1000) . int(rand() * 9000 + 1000) . int(rand() * 9000 + 1000); if ($config{'startingdigit'} ne "" && $config{'startingdigit'} ne "0") { $startingdigit = substr($number, 0, 1); if ($startingdigit == $config{'startingdigit'}) { $number = substr($number, 0, $config{'cardlength'}); return $number if (&isunique($number)); } } else { $number = substr($number, 0, $config{'cardlength'}); return $number if (&isunique($number)); } } } sub addcard() { my ($number, $language, $seconds, $inc, $markup, $brand, $nextfee) = @_; my $pin = &findunique; my $pin = substr($pin, 0, $config{'pinlength'}); my $tmp = "INSERT INTO cards (number,language,inc,facevalue,markup,used,brand,nextfee,pin) VALUES (" . $dbh->quote($number) . ", " . $dbh->quote($language) . ", " . $dbh->quote($inc) . ", " . $dbh->quote($seconds) . ", " . $dbh->quote($markup) . ",0,". $dbh->quote($brand) ."," . $dbh->quote($nextfee) . ", " . $dbh->quote($pin) . ")"; $dbh->do($tmp) || print "$tmp failed"; } sub generatecards() { my ($count, $pennies, $brand, $customnum) = @_; my $row; my $x; my $number; my $status = ""; my ($language, $inc, $markup); # Retrieve brand specifications my $sth = $dbh->prepare("SELECT * FROM brands WHERE name = " . $dbh->quote($brand)); $sth->execute; if ($config{'email'} eq "YES") { open (EMAIL, "| $config{mailprog} $config{emailadd} -s 'New Card(s) Created'") || die "Error - could not write to $config{mailprog}\n"; print EMAIL "You have added $count $brand card(s) in the amount of $pennies cents. \n\n"; } if ($row = $sth->fetchrow_hashref) { ($language, $inc, $markup, $nextfee) = ($row->{language}, $row->{inc}, $row->{markup}, $row->{days}); } $sth->finish; # add cards -- face value is in 1/100 of a penny for ($x=0; $x < $count; $x++) { if ($customnum ne '') { $number = $customnum; } else { $number = &findunique; } &addcard($number, $language, $pennies * 100, $inc, $markup, $brand, $nextfee); if ($config{'email'} eq "YES") { print EMAIL "Number: $number Pin: $pin \n"; } $status .= "Number: $number Pin: $pin
"; } if ($config{'email'} eq "YES") { print EMAIL ".\n"; close (EMAIL); } return $status; } sub users_generatecards() { my ($pennies, $users_email, $iax, $sip) = @_; my $brand = $users_config{brand}; # my $pennies = $auto_pennies; my $count = 1; my $row; my $x; my $number; my $status = ""; my ($language, $inc, $markup); # Retrieve brand specifications my $sth = $dbh->prepare("SELECT * FROM brands WHERE name = " . $dbh->quote($brand)); $sth->execute; if ($users_config{'email'} eq "YES") { open (EMAIL_ADMIN, "| $users_config{mailprog} $users_config{emailadd} -s 'New Cards Created'") || die "Error - could not write to $users_config{mailprog}\n"; print EMAIL_ADMIN "You have added $count $brand cards in the amount of $auto_pennies cents. \n\n"; } open (USERS_EMAIL, "| $users_config{mailprog} $users_email -s 'Your Account Has Been Added'") || die "Error - could not write to $users_config{mailprog}\n"; print USERS_EMAIL "Thank you for your patronage. Your account has been added\n"; if ($row = $sth->fetchrow_hashref) { ($language, $inc, $markup) = ($row->{language}, $row->{inc}, $row->{markup}); } $sth->finish; # add cards -- face value is in 1/100 of a penny # for ($x=0; $x < $count; $x++) { $number = &findunique; &addcard($number, $language, $pennies * 100, $inc, $markup); $secret = &findunique; if ($users_config{'email'} eq "YES") { print EMAIL_ADMIN "Account Number: $number \n"; print EMAIL_ADMIN "Password: $secret \n"; print EMAIL_ADMIN "Balance (Pennies): $pennies \n"; print EMAIL_ADMIN "Pin: $pin \n"; } print USERS_EMAIL "Account Number: $number \n"; print USERS_EMAIL "Password: $secret \n"; print USERS_EMAIL "Balance (cents): $pennies \n"; print USERS_EMAIL "Pin: $pin \n"; if ($sip eq "y" ) { &add_sip_user($number, $secret); } if ($iax eq "y" ) { &add_iax_user($number, $secret); } # } if ($users_config{'email'} eq "YES") { print EMAIL_ADMIN ".\n"; close (EMAIL_ADMIN); } print USERS_EMAIL ".\n"; close (USERS_EMAIL); $date = localtime(); print "Your account: $number has been created. "; print "Your password is $secret. "; print "Your accounts has $pennies cents on it. "; print "You will receive an email containing this "; print "in the next few minutes."; } sub getcard() { my ($cardno) = @_; my $res; $sth = $dbh->prepare("SELECT * FROM cards WHERE number=" . $dbh->quote($cardno)); $sth->execute; $res = $sth->fetchrow_hashref; $sth->finish; return $res; } sub build_cards() { my $total, $used; my $pennies, $count, $brand; return "Cannot edit cards until database is configured" unless $dbh; my $brands = list_brands(); return "Please define at least one brand before creating cards" unless $brands; if (param('action') eq "Generate...") { $count = param('count'); $pennies = param('pennies'); $brand = param('brand'); if ($count < 1) { $status = "Can't generate fewer than one card\n"; } elsif ($pennies < 1) { $status = "Can't generate cards of fewer than one penny\n"; } else { $status = &generatecards($count, $pennies, $brand); } }elsif (param('action') eq "Generate_Custom...") { my $count = 1; my $pennies = param('custom_pennies'); my $brand = param('brand'); my $cardnumber = param('customnum'); if ($pennies < 1) { $status = "Can't generate cards of fewer than one penny\n"; } else { $status = &generatecards($count, $pennies, $brand, $cardnumber); } } elsif (param('action') eq "Drop...") { if ($dbh->do("DELETE FROM cards WHERE number = " . $dbh->quote(param('number')))) { $status = "Dropped card " . param('number') . "'."; } else { $status = "Unable to drop card ". param('number') . "'."; } } elsif (param('action') eq "Refill...") { $cardinfo = &getcard(param('refillnum')); $number = $cardinfo->{number}; $newfacevalue = $cardinfo->{facevalue} + (param('refillpennies') * 100); if ($dbh->do("UPDATE cards SET facevalue=" . $dbh->quote($newfacevalue) . " WHERE number=" . $dbh->quote($cardinfo->{number}))) { $status = "Refilled card " . param('refillnum') . "'."; } else { $status = "Unable to Refill card". param('refillnum') . "'."; } } elsif (param('action') eq "Reset...") { $number = param('resetnum'); $newstatus = 0; if ($dbh->do("UPDATE cards SET inuse=" . $dbh->quote($newstatus) . " WHERE number=" . $dbh->quote($number))) { $status = "Reset card " . param('resetnum') . "'."; } else { $status = "Unable to Reset card ". param('resetnum') . "'."; } } $total = &count_cards(); $used = &count_cards("WHERE firstuse > 0"); $status = "$status
" . "$total cards outstanding, $used of which have been used"; $body = ""; $body .= ""; $body .= ""; $body .= ""; $body .= ""; $body .= ""; $body .= ""; $body .= ""; $body .= "
" . start_form . "$status
Create  " . hidden(-name => "mode", -value => "Cards") . textfield(-name => "count", -size => 8) . " " . $brands . "  cards of  " . textfield(-name => "pennies", -size => 8) . "  pennies  " . submit(-name => "action", -value => "Generate...") . "
Create Custom Numbered " . hidden(-name => "mode", -value => "Cards") . textfield(-name => "customnum", -size => 20) . " " . $brands . "  cards of  " . textfield(-name => "custom_pennies", -size => 8) . "  pennies  " . submit(-name => "action", -value => "Generate_Custom...") . "
Add Money to Card  " . hidden(-name => "mode", -value => "Cards") . textfield(-name => "refillnum", -size => 20) . "  In the Amount of   " . textfield(-name => "refillpennies", -size => 8) . "  pennies  " . submit(-name => "action", -value => "Refill...") . "
Get information on card  " . hidden(-name => "mode", -value => "Cards") . textfield(-name => "cardnum", -size => 20) . "    " . submit(-name => "action", -value => "Information...") . "
Delete card  " . hidden(-name => "mode", -value => "Cards") . textfield(-name => "number", -size => 20) . "    " . submit(-name => "action", -value => "Drop...") . "
Reset in use info on card  " . hidden(-name => "mode", -value => "Cards") . textfield(-name => "resetnum", -size => 20) . "    " . submit(-name => "action", -value => "Reset...") . "
List Cards  " . hidden(-name => "mode", -value => "Cards") . submit(-name => "action", -value => "List_Cards...") . "
"; $cardnum = param('cardnum'); if ((param('action') eq "Information...") && length(param('cardnum'))) { my $cardinfo; my $status; $cardinfo = &getcard(param('cardnum')); if ($cardinfo->{'number'}) { $status = "Card  " . param('cardnum') . "   has used  " . "$cardinfo->{used}" . "  of  " . "$cardinfo->{facevalue}  units\n"; } else { $status = "No such card number '" . param('cardnum') . "' found!\n"; } $body .= ""; $body .= "" . $status . "\n"; if ($cardinfo->{'number'}) { $body .= "\n"; my $sth = $dbh->prepare("SELECT * FROM cdrs WHERE cardnum=" . $dbh->quote($cardinfo->{'number'})); my $res; my $count; my $callerid; $sth->execute; while(($res = $sth->fetchrow_hashref)) { $callerid = $res->{callerid}; $callerid = "<unknown>" unless $callerid; $count++; if (!($count % 2)) { $color = "#ccffcc"; } else { $color = "#ffffcc"; } $body .= "" . ""; } } $body .= "
Caller*IDCalled NumberTrunkDispositionBillable SecondsBilled Cost
$callerid$res->{callednum}$res->{trunk}$res->{disposition}$res->{billseconds}$res->{billcost}
"; } elsif (param('action') eq "List_Cards...") { my $cardinfo; my $status; @cardlist = &list_cards(); $body .= ""; $body .= "" . $status . "\n"; $body .= "\n"; foreach (@cardlist) { $cardnum = $_; $cardinfo = &getcard($cardnum); if ($cardinfo->{'number'}) { $count++; if (!($count % 2)) { $color = "#ccffcc"; } else { $color = "#ffffcc"; } $body .= "\n"; } } $body .= "
Card NumberBrandAmount UsedFace ValueMarkupCreationFirst UseExpirationIn UsePin
$cardnum$cardinfo->{brand}$cardinfo->{used}$cardinfo->{facevalue}$cardinfo->{markup}$cardinfo->{creation}$cardinfo->{firstuse}$cardinfo->{expiration}$cardinfo->{inuse}$cardinfo->{pin}"; $body .= "
"; } return $body; } sub build_brands() { my $sth; my $count; my $color; my $tmp; my $editing; my $creating; my $status = " "; return "Cannot edit brands until database is configured" unless $dbh; # # Find what we're editing if anything # if (param("action") eq "Yes, drop it") { if ($dbh->do("DELETE FROM brands WHERE name = " . $dbh->quote(param('dropitem')))) { $status = "Dropped brand '" . param('dropitem') . "'."; } else { $status = "Unable to drop brand '" . param('dropitem') . "'."; } } for ($x=1;length(param("item$x"));$x++) { if (param("action$x") eq "Edit...") { $editing = param("item$x"); } elsif (param("action$x") eq "Add...") { $editing = param("item$x"); $creating = "yes"; $status = "Creating new entry $x"; } elsif (param("action$x") eq "Save...") { if ($dbh->do("UPDATE brands SET name=" . $dbh->quote(param("newname$x")) . " WHERE name=" . $dbh->quote(param("item$x")))) { $tmp = "REPLACE INTO brands (name,language,inc,publishednum,did,markup,days,fee) VALUES (" . $dbh->quote(param("newname$x")) . ", " . $dbh->quote(param("newlang$x")) . ", " . $dbh->quote(param("newinc$x")) . ", " . $dbh->quote(param("newpub$x")) . ", " . $dbh->quote(param("newdid$x")) . ", " . $dbh->quote(param("newmarkup$x")) . ", " . $dbh->quote(param("newdays$x")) . ", " . $dbh->quote(param("newfees$x")) . ")"; if ($dbh->do($tmp)) { $status = "Brand '" . param("newname$x") . "' has been updated"; } else { $status = "Brand '" . param("newname$x") . "' FAILED to update ($tmp)!"; } } else { $status = "Name is already in use!"; } } elsif (param("action$x") eq "Create...") { $tmp = "INSERT INTO brands (name,language,inc,publishednum,did,markup,days,fee) VALUES (" . $dbh->quote(param("newname$x")) . ", " . $dbh->quote(param("newlang$x")) . ", " . $dbh->quote(param("newinc$x")) . ", " . $dbh->quote(param("newpub$x")) . ", " . $dbh->quote(param("newdid$x")) . ", " . $dbh->quote(param("newmarkup$x")) . ", " . $dbh->quote(param("newdays$x")) . ", " . $dbh->quote(param("newfees$x")) . ")"; if ($dbh->do($tmp)) { $status = "Brand '" . param("newname$x") . "' has been created"; } else { $status = "Brand '" . param("newname$x") . "' FAILED to create ($tmp)!"; } } elsif (param("action$x") eq "Drop...") { $status = "Are you sure you want to delete the brand '" . param("item$x") . "'?
" . hidden(-name => "dropitem", -value => param("item$x")) . submit(-name => "action", -value => "Yes, drop it") . "   " . submit(-name => "action", -value => "Cancel"); $editing = "dropping something"; } } $sth = $dbh->prepare('SELECT * FROM brands'); $sth->execute || return "Something is wrong with the brands database\n"; $body = "" . "" . start_form . "$status\n" . "\n"; while($row = $sth->fetchrow_hashref) { $count++; if (!($count % 2)) { $color = "#ccffcc"; } else { $color = "#ffffcc"; } Delete("newname$count"); Delete("item$count"); if ($editing eq $row->{name}) { $body .= ""; $body .= ""; } else { $body .= "" . "" . "" . "\n"; } } $sth->finish; $count++; if ($creating) { $body .= ""; $body .= ""; } if (!$editing) { $body .= "\n"; $body .= "\n"; } $body .= "
" . hidden(-name => 'mode', -value => 'Brands') . "Brand NameLanguagePublished NumberDIDIncService Fee (cents)Service Fee DaysMarkup (in 1/100 of 1%)
" . hidden(-name => "item$count", -value => $row->{name}) . textfield(-name => "newname$count", -size=> 10, -default => $row->{name}) . "" . popup_menu(-name => "newlang$count", -values => \@languages, -default=>$row->{language}) . "" . textfield(-name => "newpub$count", -size => 15, -default => $row->{publishednum}) . "" . textfield(-name => "newdid$count", -size => 10, -default => $row->{did}) . "" . popup_menu(-name => "newinc$count", -values => \@incs, -default => $row->{inc}) . "" . textfield(-name => "newfees$count", -size => 2, -default => $row->{fee}) . "" . textfield(-name => "newdays$count", -size => 2, -default => $row->{days}) . "" . textfield(-name => "newmarkup$count", -size => 5, -default => $row->{markup}) . "" . submit(-name => "action$count", -value => 'Save...') . submit(-name => "action$count", -value => 'Cancel...'); $body .= "
" . hidden(-name => "item$count", -value => $row->{name}) . "$row->{name}$row->{language}$row->{publishednum}$row->{did}$row->{inc}$row->{fee}$row->{days}$row->{markup}"; if (!$editing) { $body .= submit(-name => "action$count", -value => 'Edit...') . submit(-name => "action$count", -value => 'Drop...'); } else { $body .= " "; } $body .= "
" . hidden(-name => "item$count", -value => $row->{name}) . textfield(-name => "newname$count", -size=> 10) . "" . popup_menu(-name => "newlang$count", -values => \@languages) . "" . textfield(-name => "newpub$count", -size => 15) . "" . textfield(-name => "newdid$count", -size => 10) . "" . popup_menu(-name => "newinc$count", -values => \@incs) . "" . textfield(-name => "newfees$count", -size => 2) . "" . textfield(-name => "newdays$count", -size => 2) . "" . textfield(-name => "newmarkup$count", -size => 5) . "" . submit(-name => "action$count", -value => 'Create...') . submit(-name => "action$count", -value => 'Cancel...'); $body .= "

 " . hidden(-name => "item$count", -value => "new") . "" . submit(-name => "action$count", -value => "Add...") . "
\n"; return $body; } sub build_trunks() { my $sth; my $count; my $color; my $tmp; my $editing; my $creating; my $status = " "; return "Cannot edit trunks until database is configured" unless $dbh; # # Find what we're editing if anything # if (param("action") eq "Yes, drop it") { if ($dbh->do("DELETE FROM trunks WHERE name = " . $dbh->quote(param('dropitem')))) { $status = "Dropped trunk '" . param('dropitem') . "'."; } else { $status = "Unable to drop trunk '" . param('dropitem') . "'."; } } for ($x=1;length(param("item$x"));$x++) { if (param("action$x") eq "Edit...") { $editing = param("item$x"); } elsif (param("action$x") eq "Add...") { $editing = param("item$x"); $creating = "yes"; $status = "Creating new entry $x"; } elsif (param("action$x") eq "Save...") { if ($dbh->do("UPDATE trunks SET name=" . $dbh->quote(param("newname$x")) . " WHERE name=" . $dbh->quote(param("item$x")))) { $tmp = "REPLACE INTO trunks (name,tech,path) VALUES (" . $dbh->quote(param("newname$x")) . ", " . $dbh->quote(param("newtech$x")) . ", " . $dbh->quote(param("newpath$x")) . ")"; if ($dbh->do($tmp)) { $status = "Trunk '" . param("newname$x") . "' has been updated"; } else { $status = "Trunk '" . param("newname$x") . "' FAILED to update ($tmp)!"; } } else { $status = "Name is already in use!"; } } elsif (param("action$x") eq "Create...") { $tmp = "INSERT INTO trunks (name,tech,path) VALUES (" . $dbh->quote(param("newname$x")) . ", " . $dbh->quote(param("newtech$x")) . ", " . $dbh->quote(param("newpath$x")) . ")"; if ($dbh->do($tmp)) { $status = "Trunk '" . param("newname$x") . "' has been created"; } else { $status = "Trunk '" . param("newname$x") . "' FAILED to create ($tmp)!"; } } elsif (param("action$x") eq "Drop...") { $status = "Are you sure you want to delete the trunk '" . param("item$x") . "' and all routes that use it?
" . hidden(-name => "dropitem", -value => param("item$x")) . submit(-name => "action", -value => "Yes, drop it") . "   " . submit(-name => "action", -value => "Cancel"); $editing = "dropping something"; } } $sth = $dbh->prepare('SELECT * FROM trunks'); $sth->execute || return "Something is wrong with the trunks database\n"; $body = "" . "" . start_form . "$status\n" . "\n"; while($row = $sth->fetchrow_hashref) { $count++; Delete("newname$count"); Delete("item$count"); if (!($count % 2)) { $color = "#ccffcc"; } else { $color = "#ffffcc"; } if ($editing eq $row->{name}) { $body .= ""; $body .= ""; } else { $body .= "" . "" . "\n"; } } $sth->finish; $count++; if ($creating) { $body .= ""; $body .= ""; } if (!$editing) { $body .= "\n"; $body .= "\n"; } $body .= "
" . hidden(-name => 'mode', -value => 'Trunks') . "Trunk NameTechnologyPeer/Trunk
" . hidden(-name => "item$count", -value => $row->{name}) . textfield(-name => "newname$count", -size=> 10, -default => $row->{name}) . "" . popup_menu(-name => "newtech$count", -values => \@techs, -default=>$row->{tech}) . "" . textfield(-name => "newpath$count", -size => 15, -default => $row->{path}) . "" . submit(-name => "action$count", -value => 'Save...') . submit(-name => "action$count", -value => 'Cancel...'); $body .= "
" . hidden(-name => "item$count", -value => $row->{name}) . "$row->{name}$row->{tech}$row->{path}"; if (!$editing) { $body .= submit(-name => "action$count", -value => 'Edit...') . submit(-name => "action$count", -value => 'Drop...'); } else { $body .= " "; } $body .= "
" . hidden(-name => "item$count", -value => $row->{name}) . textfield(-name => "newname$count", -size=> 10) . "" . popup_menu(-name => "newtech$count", -values => \@techs) . "" . textfield(-name => "newpath$count", -size => 15) . "" . submit(-name => "action$count", -value => 'Create...') . submit(-name => "action$count", -value => 'Cancel...'); $body .= "

 " . hidden(-name => "item$count", -value => "new") . "" . submit(-name => "action$count", -value => "Add...") . "
\n"; return $body; } sub find_newtrunks() { my ($base) = @_; my $x; my $res = ""; my (@trunks); for ($x=1;length(param("$base-${x}"));$x++) { push @trunks, param("$base-${x}") if param("$base-${x}") ne ""; } return join(':',@trunks); } sub build_routes() { my $sth; my $count; my $color; my $tmp; my $editing; my $creating; my $trunks; my $newtrunks; my $status = " "; my (@oldtrunks); return "Cannot edit routes until database is configured" unless $dbh; my $trunks = list_trunks(); return "Please define at least one trunk before creating routes" unless $trunks; # # Find what we're editing if anything # if (param("action") eq "Yes, drop it") { if ($dbh->do("DELETE FROM routes WHERE pattern = " . $dbh->quote(param('dropitem')))) { $status = "Dropped route '" . param('dropitem') . "'."; } else { $status = "Unable to drop route '" . param('dropitem') . "'."; } } for ($x=1;length(param("item$x"));$x++) { $newtrunks = &find_newtrunks("newtrunk$x"); if (param("action$x") eq "Edit...") { $editing = param("item$x"); } elsif (param("action$x") eq "Add...") { $editing = param("item$x"); $creating = "yes"; $status = "Creating new entry $x"; } elsif (param("action$x") eq "Save...") { if ($dbh->do("UPDATE routes SET pattern=" . $dbh->quote(param("newpat$x")) . " WHERE pattern=" . $dbh->quote(param("item$x")))) { $tmp = "REPLACE INTO routes (pattern,comment,trunks,connectcost, includedseconds, cost) VALUES (" . $dbh->quote(param("newpat$x")) . ", " . $dbh->quote(param("newcomment$x")) . ", " . $dbh->quote($newtrunks) . ", " . $dbh->quote(param("newconnect$x")) . ", " . $dbh->quote(param("newincluded$x")) . ", " . $dbh->quote(param("newcost$x")) . ")"; if ($dbh->do($tmp)) { $status = "Pattern '" . param("newpat$x") . "' has been updated"; } else { $status = "Pattern '" . param("newpat$x") . "' FAILED to update ($tmp)!"; } } else { $status = "Pattern already exists!"; } } elsif (param("action$x") eq "Create...") { $tmp = "INSERT INTO routes (pattern,comment,trunks,connectcost, includedseconds, cost) VALUES (" . $dbh->quote(param("newpat$x")) . ", " . $dbh->quote(param("newcomment$x")) . ", " . $dbh->quote($newtrunks) . ", " . $dbh->quote(param("newconnect$x")) . ", " . $dbh->quote(param("newincluded$x")) . ", " . $dbh->quote(param("newcost$x")) . ")"; if ($dbh->do($tmp)) { $status = "Pattern '" . param("newpat$x") . "' has been created"; } else { $status = "Pattern '" . param("newpat$x") . "' FAILED to create ($tmp)!"; } } elsif (param("action$x") eq "Drop...") { $status = "Are you sure you want to delete the pattern '" . param("item$x") . "'?
" . hidden(-name => "dropitem", -value => param("item$x")) . submit(-name => "action", -value => "Yes, drop it") . "   " . submit(-name => "action", -value => "Cancel"); $editing = "dropping something"; } } $sth = $dbh->prepare('SELECT * FROM routes'); $sth->execute || return "Something is wrong with the routes database\n"; $body = "" . "\n" . "\n" . "\n"; while($row = $sth->fetchrow_hashref) { $count++; @oldtrunks = split(/:/, $row->{trunks}); Delete("newpat$count"); Delete("item$count"); if (!($count % 2)) { $color = "#ccffcc"; } else { $color = "#ffffcc"; } if ($editing eq $row->{pattern}) { $body .= ""; $body .= ""; } else { $body .= "" . "" . "\n"; } } $sth->finish; $count++; if ($creating) { $body .= ""; $body .= ""; } if (!$editing) { $body .= "\n"; $body .= "\n"; } $body .= "
" . start_form . "$status
Pattern is a REGEX". "All costs are in 1/100 of a penny
" . hidden(-name => 'mode', -value => 'Routes') . "PatternCommentTrunksConnect FeeInc. SecondsCost per additional minute
" . hidden(-name => "item$count", -value => $row->{pattern}) . textfield(-name => "newpat$count", -size=> 8, -default => $row->{pattern}) . "" . textfield(-name => "newcomment$count", -size=> 20, -default => $row->{comment}) . "" . "1" . &list_trunks("newtrunk$count-1", $oldtrunks[0]) . "
" . "2" . &list_trunks("newtrunk$count-2", $oldtrunks[1]) . "
" . "3" . &list_trunks("newtrunk$count-3", $oldtrunks[2]) . "
" . "4" . &list_trunks("newtrunk$count-4", $oldtrunks[3]) . "
" . textfield(-name => "newconnect$count", -size => 5, -default => $row->{connectcost}) . "" . textfield(-name => "newincluded$count", -size => 5, -default => $row->{includedseconds}) . "" . textfield(-name => "newcost$count", -size => 5, -default => $row->{cost}) . "" . submit(-name => "action$count", -value => 'Save...') . submit(-name => "action$count", -value => 'Cancel...'); $body .= "
" . hidden(-name => "item$count", -value => $row->{pattern}) . "$row->{pattern}$row->{comment}$row->{trunks}$row->{connectcost}$row->{includedseconds}$row->{cost}"; if (!$editing) { $body .= submit(-name => "action$count", -value => 'Edit...') . submit(-name => "action$count", -value => 'Drop...'); } else { $body .= " "; } $body .= "
" . hidden(-name => "item$count", -value => $row->{name}) . textfield(-name => "newpat$count", -size=> 8) . "" . textfield(-name => "newcomment$count", -size=> 20) . "" . "1" . &list_trunks("newtrunk$count-1") . "
" . "2" . &list_trunks("newtrunk$count-2") . "
" . "3" . &list_trunks("newtrunk$count-3") . "
" . "4" . &list_trunks("newtrunk$count-4") . "
" . textfield(-name => "newconnect$count", -size => 5, default => 0) . "" . textfield(-name => "newincluded$count", -size => 5, default => 0) . "" . textfield(-name => "newcost$count", -size => 5, -default => 0) . "" . submit(-name => "action$count", -value => 'Create...') . submit(-name => "action$count", -value => 'Cancel...'); $body .= "

 " . hidden(-name => "item$count", -value => "new") . "" . submit(-name => "action$count", -value => "Add...") . "
\n"; return $body; } sub build_configure() { my $body = start_form; my $activity = "
"; my $action = param('action'); if (($action eq "Save") || ($action eq "Create Database") || ($action eq "Update Database")) { $config{dbuser} = param('dbuser'); $config{dbpass} = param('dbpass'); $config{dbname} = param('dbname'); $config{dbhost} = param('dbhost'); $config{cardlength} = param('cardlength'); $config{startingdigit} = param('startingdigit'); $config{email} = param('email'); $config{emailadd} = param('emailadd'); $config{mailprog} = param('mailprog'); $config{friendsdb} = param('friendsdb'); $config{maintverbose} = param('maintverbose'); $config{maintcdr} = param('maintcdr'); $config{maintname} = param('maintname'); $config{pinstatus} = param('pinstatus'); $config{pinlength} = param('pinlength'); $config{debug} = param('debug'); &save_config(); $activity = "Configuration saved..."; if ($action eq "Create Database") { if (!&create_db()) {i $activity = "Database created!"; } else { $activity = "Database creation failed!"; } } elsif ($action eq "Update Database") { if (!&update_db()) {i $activity = "Database Updated!"; } else { $activity = "Database Update failed!"; } } &connect_db; } $body .= hidden(-name => 'mode', -default => 'Configure'); $body .= ""; $body .= "\n"; $body .= ""; $body .= ""; $body .= ""; $body .= ""; $body .= ""; $body .= ""; $body .= ""; $body .= ""; $body .= ""; $body .= ""; $body .= ""; $body .= ""; $body .= ""; $body .= ""; $body .= ""; $body .= ""; $body .= ""; $body .= ""; $body .= ""; $body .= "
Database Configuration
$activity
Host" . textfield(-name => 'dbhost', -default => $config{dbhost}) . "
Username" . textfield(-name => 'dbuser', -default => $config{dbuser}) . "
Password" . textfield(-name => 'dbpass', -default => $config{dbpass}) . "
Database" . textfield(-name => 'dbname', -default => $config{dbname}) . "
Card Length (4-20) " . textfield(-name => 'cardlength', -default => $config{cardlength}) . "
Card Starting Number -
Enter 0 if Not Required " . textfield(-name => 'startingdigit', -default => $config{startingdigit}) . "
Email New Card Info (YES/NO) " . textfield(-name => 'email', -default => $config{email}) . "
Admin Email" . textfield(-name => 'emailadd', -default => $config{emailadd}) . "
Email Program" . textfield(-name => 'mailprog', -default => $config{mailprog}) . "
Enable Iax/Sip Friends DB (YES/NO) " . textfield(-name => 'friendsdb', -default => $config{friendsdb}) . "
Verbose account maintainence (YES/NO) " . textfield(-name => 'maintverbose', -default => $config{maintverbose}) . "
Modify CDR to show maintainence fee (YES/NO) " . textfield(-name => 'maintcdr', -default => $config{maintcdr}) . "
CDR Text for maintainence fee" . textfield(-name => 'maintname', -default => $config{maintname}) . "
Pin Length (4-20) " . textfield(-name => 'pinlength', -default => $config{pinlength}) . "
Require Pins (Yes/NO)" . textfield(-name => 'pinstatus', -default => $config{pinstatus}) . "
Debug Mode" . popup_menu(-name => "debug", -values => \@yesno, -default=> $config{debug}) . "
 " . submit(-name => 'action', -value => 'Save') . "" . submit( -name => 'action', -value => 'Create Database') . " 
 " . submit(-name => 'action', -value => 'Update Database') . " 
"; return $body; } sub build_user_configure() { my $body = start_form; my $activity = "
"; my $action = param('action'); if (($action eq "Save") || ($action eq "Create Database")) { $users_config{dbuser} = param('dbuser'); $users_config{dbpass} = param('dbpass'); $users_config{dbname} = param('dbname'); $users_config{dbhost} = param('dbhost'); $users_config{iax_context} = param('iax_context'); $users_config{sip_context} = param('sip_context'); $users_config{iax_port} = param('iax_port'); $users_config{sip_port} = param('sip_port'); $users_config{regseconds} = param('regseconds'); $users_config{brand} = param('brand'); $users_config{emailadd} = param('emailadd'); $users_config{mailprog} = param('mailprog'); &users_save_config(); $activity = "Configuration saved..."; if ($action eq "Create Database") { if (!&users_create_db()) {i $activity = "Database created!"; } else { $activity = "Database creation failed!"; } } &users_connect_db; } $body .= hidden(-name => 'mode', -default => 'Users_Configure'); $body .= ""; $body .= "\n"; $body .= ""; $body .= ""; $body .= ""; $body .= ""; $body .= ""; $body .= ""; $body .= ""; $body .= ""; $body .= ""; $body .= ""; $body .= ""; $body .= ""; $body .= ""; $body .= "
Database Configuration
$activity
Host" . textfield(-name => 'dbhost', -default => $users_config{dbhost}) . "
Username" . textfield(-name => 'dbuser', -default => $users_config{dbuser}) . "
Password" . textfield(-name => 'dbpass', -default => $users_config{dbpass}) . "
Database" . textfield(-name => 'dbname', -default => $users_config{dbname}) . "
Default SIP Context " . textfield(-name => 'sip_context', -default => $users_config{sip_context}) . "
Default IAX Context " . textfield(-name => 'iax_context', -default => $users_config{iax_context}) . "
Default SIP Port " . textfield(-name => 'sip_port', -default => $users_config{sip_port}) . "
Default IAX Port " . textfield(-name => 'iax_port', -default => $users_config{iax_port}) . "
Default Reg Seconds " . textfield(-name => 'regseconds', -default => $users_config{regseconds}) . "
Default Brand " . textfield(-name => 'brand', -default => $users_config{brand}) . "
Admin Email" . textfield(-name => 'emailadd', -default => $users_config{emailadd}) . "
Email Program" . textfield(-name => 'mailprog', -default => $users_config{mailprog}) . "
 " . submit(-name => 'action', -value => 'Save') . "" . submit( -name => 'action', -value => 'Create Database') . " 
"; return $body; } sub add_sip_user() { my ($name, $secret) = @_; my $username = $name; my $context = $users_config{sip_context}; my $port = $users_config{sip_port}; my $regseconds = $users_config{regseconds}; my $brand = $users_config{brand}; my $ipaddr = "dynamic"; $tmp = "INSERT INTO sipfriends (name,username,secret,context,ipaddr,port,regseconds) VALUES (" . $users_dbh->quote($name) . ", " .$users_dbh->quote($username) . ", " . $users_dbh->quote($secret) . ", " .$users_dbh->quote($context) . ", " . $users_dbh->quote($ipaddr) . ", " . $users_dbh->quote($port) . ", " . $users_dbh->quote($regseconds).")"; $users_dbh->do($tmp) || print "$tmp failed"; } sub add_iax_user() { my ($name, $secret) = @_; my $context = $users_config{iax_context}; my $port = $users_config{iax_port}; my $regseconds = $users_config{regseconds}; my $ipaddr = "dynamic"; $tmp = "INSERT INTO iaxfriends (name,secret,context,ipaddr,port,regseconds) VALUES (" . $users_dbh->quote($name) . ", " . $users_dbh->quote($secret) . ", " .$users_dbh->quote($context) . ", " . $users_dbh->quote($ipaddr) . ", " . $users_dbh->quote($port) . ", " . $users_dbh->quote($regseconds).")"; $users_dbh->do($tmp) || print "$tmp failed"; } sub build_iax_friends() { my $sth; my $count; my $color; my $tmp; my $editing; my $creating; my $status = " "; return "Cannot edit IAX users until database is configured" unless $users_dbh; # # Find what we're editing if anything # if (param("action") eq "Yes, drop it") { if ($users_dbh->do("DELETE FROM iaxfriends WHERE name = " . $users_dbh->quote(param('dropitem')))) { $status = "Dropped user '" . param('dropitem') . "'."; } else { $status = "Unable to drop user '" . param('dropitem') . "'."; } } for ($x=1;length(param("item$x"));$x++) { if (param("action$x") eq "Edit...") { $editing = param("item$x"); } elsif (param("action$x") eq "Add...") { $editing = param("item$x"); $creating = "yes"; $status = "Creating new entry $x"; } elsif (param("action$x") eq "Save...") { if ($users_dbh->do("UPDATE iaxfriends SET name=" . $users_dbh->quote(param("newname$x")) . " WHERE name=" . $users_dbh->quote(param("item$x")))) { $tmp = "REPLACE INTO iaxfriends (name,secret,context,ipaddr,port,regseconds) VALUES (" . $users_dbh->quote(param("newname$x")) . ", " . $users_dbh->quote(param("newsecret$x")) . ", " . $users_dbh->quote(param("newcontext$x")) . ", " . $users_dbh->quote(param("newipaddr$x")) . ", " . $users_dbh->quote(param("newport$x")) . ", " . $users_dbh->quote(param("newregseconds$x")) . ")"; if ($users_dbh->do($tmp)) { $status = "User '" . param("newname$x") . "' has been updated"; } else { $status = "User '" . param("newname$x") . "' FAILED to update ($tmp)!"; } } else { $status = "Name is already in use!"; } } elsif (param("action$x") eq "Create...") { $tmp = "INSERT INTO iaxfriends (name,secret,context,ipaddr,port,regseconds) VALUES (" . $users_dbh->quote(param("newname$x")) . ", " . $users_dbh->quote(param("newsecret$x")) . ", " . $users_dbh->quote(param("newcontext$x")) . ", " . $users_dbh->quote(param("newipaddr$x")) . ", " . $users_dbh->quote(param("newport$x")) . ", " . $users_dbh->quote(param("newregseconds$x")) . ")"; if ($users_dbh->do($tmp)) { $status = "User '" . param("newname$x") . "' has been created"; } else { $status = "User '" . param("newname$x") . "' FAILED to create ($tmp)!"; } } elsif (param("action$x") eq "Drop...") { $status = "Are you sure you want to delete the user '" . param("item$x") . "'?
" . hidden(-name => "dropitem", -value => param("item$x")) . submit(-name => "action", -value => "Yes, drop it") . "   " . submit(-name => "action", -value => "Cancel"); $editing = "dropping something"; } } $sth = $users_dbh->prepare('SELECT * FROM iaxfriends'); $sth->execute || return "Something is wrong with the iaxfriends database\n"; $body = "" . "" . start_form . "$status\n" . "\n"; while($row = $sth->fetchrow_hashref) { $count++; if (!($count % 2)) { $color = "#ccffcc"; } else { $color = "#ffffcc"; } Delete("newname$count"); Delete("item$count"); if ($editing eq $row->{name}) { $body .= ""; $body .= ""; } else { $body .= "" . "" . "" . "\n"; } } $sth->finish; $count++; if ($creating) { $body .= ""; $body .= ""; } if (!$editing) { $body .= "\n"; $body .= "\n"; } $body .= "
" . hidden(-name => 'mode', -value => 'iaxfriends') . "User NameSecretContextIP AddressPortReg Seconds
" . hidden(-name => "item$count", -value => $row->{name}) . textfield(-name => "newname$count", -size=> 10, -default => $row->{name}) . "" . textfield(-name => "newsecret$count", -size=> 10, -default=>$row->{secret}) . "" . textfield(-name => "newcontext$count", -size => 15, -default => $row->{context}) . "" . textfield(-name => "newipaddr$count", -size => 10, -default => $row->{ipaddr}) . "" . textfield(-name => "newport$count", -size => 10, -default => $row->{port}) . "" . textfield(-name => "newregseconds$count", -size => 5, -default => $row->{regseconds}) . "" . submit(-name => "action$count", -value => 'Save...') . submit(-name => "action$count", -value => 'Cancel...'); $body .= "
" . hidden(-name => "item$count", -value => $row->{name}) . "$row->{name}$row->{secret}$row->{context}$row->{ipaddr}$row->{port}$row->{regseconds}"; if (!$editing) { $body .= submit(-name => "action$count", -value => 'Edit...') . submit(-name => "action$count", -value => 'Drop...'); } else { $body .= " "; } $body .= "
" . hidden(-name => "item$count", -value => $row->{name}) . textfield(-name => "newname$count", -size=> 10) . "" . textfield(-name => "newsecret$count", -size => 10) . "" . textfield(-name => "newcontext$count", -size => 15) . "" . textfield(-name => "newipaddr$count", -size => 10) . "" . textfield(-name => "newport$count", -size => 10) . "" . textfield(-name => "newregseconds$count", -size => 5) . "" . submit(-name => "action$count", -value => 'Create...') . submit(-name => "action$count", -value => 'Cancel...'); $body .= "

 " . hidden(-name => "item$count", -value => "new") . "" . submit(-name => "action$count", -value => "Add...") . "
\n"; return $body; } sub build_sip_friends() { my $sth; my $count; my $color; my $tmp; my $editing; my $creating; my $status = " "; return "Cannot edit SIP users until database is configured" unless $users_dbh; # # Find what we're editing if anything # if (param("action") eq "Yes, drop it") { if ($users_dbh->do("DELETE FROM sipfriends WHERE name = " . $users_dbh->quote(param('dropitem')))) { $status = "Dropped user '" . param('dropitem') . "'."; } else { $status = "Unable to drop user '" . param('dropitem') . "'."; } } for ($x=1;length(param("item$x"));$x++) { if (param("action$x") eq "Edit...") { $editing = param("item$x"); } elsif (param("action$x") eq "Add...") { $editing = param("item$x"); $creating = "yes"; $status = "Creating new entry $x"; } elsif (param("action$x") eq "Save...") { if ($users_dbh->do("UPDATE sipfriends SET name=" . $users_dbh->quote(param("newname$x")) . " WHERE name=" . $users_dbh->quote(param("item$x")))) { $tmp = "REPLACE INTO sipfriends (name,username,secret,context,ipaddr,port,regseconds) VALUES (" . $users_dbh->quote(param("newname$x")) . ", " . $users_dbh->quote(param("newusername$x")) . ", " . $users_dbh->quote(param("newsecret$x")) . ", " . $users_dbh->quote(param("newcontext$x")) . ", " . $users_dbh->quote(param("newipaddr$x")) . ", " . $users_dbh->quote(param("newport$x")) . ", " . $users_dbh->quote(param("newregseconds$x")) . ")"; if ($users_dbh->do($tmp)) { $status = "User '" . param("newname$x") . "' has been updated"; } else { $status = "User '" . param("newname$x") . "' FAILED to update ($tmp)!"; } } else { $status = "Name is already in use!"; } } elsif (param("action$x") eq "Create...") { $tmp = "INSERT INTO sipfriends (name,username,secret,context,ipaddr,port,regseconds) VALUES (" . $users_dbh->quote(param("newname$x")) . ", " . $users_dbh->quote(param("newusername$x")) . ", " . $users_dbh->quote(param("newsecret$x")) . ", " . $users_dbh->quote(param("newcontext$x")) . ", " . $users_dbh->quote(param("newipaddr$x")) . ", " . $users_dbh->quote(param("newport$x")) . ", " . $users_dbh->quote(param("newregseconds$x")) . ")"; if ($users_dbh->do($tmp)) { $status = "User '" . param("newname$x") . "' has been created"; } else { $status = "User '" . param("newname$x") . "' FAILED to create ($tmp)!"; } } elsif (param("action$x") eq "Drop...") { $status = "Are you sure you want to delete the user '" . param("item$x") . "'?
" . hidden(-name => "dropitem", -value => param("item$x")) . submit(-name => "action", -value => "Yes, drop it") . "   " . submit(-name => "action", -value => "Cancel"); $editing = "dropping something"; } } $sth = $users_dbh->prepare('SELECT * FROM sipfriends'); $sth->execute || return "Something is wrong with the sipfriends database\n"; $body = "" . "" . start_form . "$status\n" . "\n"; while($row = $sth->fetchrow_hashref) { $count++; if (!($count % 2)) { $color = "#ccffcc"; } else { $color = "#ffffcc"; } Delete("newname$count"); Delete("item$count"); if ($editing eq $row->{name}) { $body .= ""; $body .= ""; } else { $body .= "" . "" . "" . "\n"; } } $sth->finish; $count++; if ($creating) { $body .= ""; $body .= ""; } if (!$editing) { $body .= "\n"; $body .= "\n"; } $body .= "
" . hidden(-name => 'mode', -value => 'sipfriends') . "Name User NameSecretContextIP AddressPortReg Seconds
" . hidden(-name => "item$count", -value => $row->{name}) . textfield(-name => "newname$count", -size=> 10, -default => $row->{name}) . "" . textfield(-name => "newusername$count", -size=> 10, -default => $row->{username}) . "" . textfield(-name => "newsecret$count", -size=> 10, -default=>$row->{secret}) . "" . textfield(-name => "newcontext$count", -size => 15, -default => $row->{context}) . "" . textfield(-name => "newipaddr$count", -size => 10, -default => $row->{ipaddr}) . "" . textfield(-name => "newport$count", -size => 10, -default => $row->{port}) . "" . textfield(-name => "newregseconds$count", -size => 5, -default => $row->{regseconds}) . "" . submit(-name => "action$count", -value => 'Save...') . submit(-name => "action$count", -value => 'Cancel...'); $body .= "
" . hidden(-name => "item$count", -value => $row->{name}) . "$row->{name}$row->{username}$row->{secret}$row->{context}$row->{ipaddr}$row->{port}$row->{regseconds}"; if (!$editing) { $body .= submit(-name => "action$count", -value => 'Edit...') . submit(-name => "action$count", -value => 'Drop...'); } else { $body .= " "; } $body .= "
" . hidden(-name => "item$count", -value => $row->{name}) . textfield(-name => "newname$count", -size=> 10) . "" . textfield(-name => "newusername$count", -size=> 10) . "" . textfield(-name => "newsecret$count", -size => 10) . "" . textfield(-name => "newcontext$count", -size => 15) . "" . textfield(-name => "newipaddr$count", -size => 10) . "" . textfield(-name => "newport$count", -size => 10) . "" . textfield(-name => "newregseconds$count", -size => 5) . "" . submit(-name => "action$count", -value => 'Create...') . submit(-name => "action$count", -value => 'Cancel...'); $body .= "

 " . hidden(-name => "item$count", -value => "new") . "" . submit(-name => "action$count", -value => "Add...") . "
\n"; return $body; } sub build_calc_charge() { my ($total, $used, $pennies, $count, $brand, $language, $inc, $markup); return "Cannot calculate charges until database is configured" unless $dbh; my $brands = &list_brands(); return "Please define at least one brand before creating cards" unless $brands; if (param('action') eq "Calc_Rate...") { $phoneno = param('Number'); $minutes = param('Minutes'); $seconds = $minutes * 60; $brand = param('brand'); # Retrieve brand specifications my $sth = $dbh->prepare("SELECT * FROM brands WHERE name = " . $dbh->quote($brand)); $sth->execute; if ($row = $sth->fetchrow_hashref) { ($language, $increment, $markup) = ($row->{language}, $row->{inc}, $row->{markup}); } $sth->finish; $charge = &calccost($phoneno, $seconds,$increment,$markup); eval { $charge = $charge / 10000 }; $status = "Charge for $minutes to $phoneno \n"; $status .= "will be $charge \n"; } $body = ""; $body .= ""; $body .= "
" . start_form . "$status
Brand:" . $brands . " Phone Number  " . hidden(-name => "mode", -value => "Cards") . textfield(-name => "Number", -size => 20) . "    " . textfield(-name => "Minutes", -size => 4) . "  Minutes  " . submit(-name => "action", -value => "Calc_Rate...") . "
"; return $body; } sub calccost() { my ($number, $answeredtime, $increment, $markup) = @_; my $numdata = &getphone($number); $adjcost = ($numdata->{cost} * (10000 + $markup)) / 10000; $adjconn = ($numdata->{connectcost} * (10000 + $markup)) / 10000; my $cost; my $adjtime = eval { $adjtime = int((($answeredtime - $numdata->{includedseconds}) + $increment - 1) / $increment) * $increment; return $adjtime }; if ($adjtime < 0) { $adjtime = 0; } print STDERR "Adjusted time is $adjtime, cost is $adjcost with $adjconn fee\n"; eval { $cost = int($adjcost * $adjtime / 60) }; $cost += $adjconn; print STDERR "Total cost is $cost\n"; return $cost; } sub getphone() { my ($number) = @_; my $sth = $dbh->prepare("SELECT * FROM routes WHERE " . $dbh->quote($number) . " RLIKE pattern ORDER BY LENGTH(pattern) DESC"); $sth->execute; $res = $sth->fetchrow_hashref; $sth->finish; return $res; } sub build_body() { my ($mode) = @_; my $body; return &build_home() if ($mode eq "Home"); return &build_cards() if ($mode eq "Cards"); return &build_configure() if ($mode eq "Configure"); return &build_brands() if ($mode eq "Brands"); return &build_trunks() if ($mode eq "Trunks"); return &build_routes() if ($mode eq "Routes"); return &build_calc_charge() if ($mode eq "Calc_Charge"); if ($config{'friendsdb'} eq "YES") { return &build_user_configure() if ($mode eq "Users_Configure"); return &build_iax_friends() if ($mode eq "IAX_Friends"); return &build_sip_friends() if ($mode eq "SIP_Friends"); } elsif ($config{'friendsdb'} ne "YES") { return "

Not Configured!

\n" if ($mode eq "Users_Configure"); return "

Not Configured!

\n" if ($mode eq "IAX_Friends"); return "

Not Configured!

\n" if ($mode eq "SIP_Friends"); } return "

Not yet implemented!

\n"; } my $body, $menu; my $mode = param("mode"); my $pn = param("pn"); my $em = param("em"); my $md = param("md"); my $iax = param("iax"); my $sip = param("sip"); &load_config; &connect_db; if ($config{'friendsdb'} eq "YES") { &users_load_config; &users_connect_db; } $msg = " "; if ($md eq "Auto") { &users_generatecards($pn, $em, $iax, $sip); } else { $mode = "Home" unless grep(/^$mode$/, @modes); $body = &build_body($mode); $menu = &build_menu($mode); $msg = "Database unavailable -- please check configuration" unless $dbh; print "Asterisk™ Calling Card manager: $mode\n"; print "\n"; print " "; print " "; print "\n"; print "
Asterisk™ Calling Card Admin: $mode" . "
$msg
$menu$body

$copyright
\n"; }