]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
Remove billing dir, those files don't belong there
authorArran Cudbard-Bell <a.cudbardb@freeradius.org>
Fri, 20 Sep 2013 11:55:30 +0000 (12:55 +0100)
committerArran Cudbard-Bell <a.cudbardb@freeradius.org>
Fri, 20 Sep 2013 15:30:00 +0000 (16:30 +0100)
src/billing/README [deleted file]
src/billing/cisco_h323_db_sample_functions-postgres.sql [deleted file]
src/billing/clarent2db.pl [deleted file]
src/billing/clarent_db_schema-postgres.sql [deleted file]
src/billing/h323detail2db.pl [deleted file]

diff --git a/src/billing/README b/src/billing/README
deleted file mode 100644 (file)
index a6acabd..0000000
+++ /dev/null
@@ -1,87 +0,0 @@
-$Id$
-
-       VOIP ACCOUNTING WITH CISCO VSA
-
-INTRODUCTION
-
-Cisco VoIP gateways can use radius accounting to log call records,
-however FreeRadius in it's default configuration is not very well
-suited to the job as the default database config is designed with
-standard dial-up ISP Authentication and Post billing in mind.
-The typical configuration on FreeRadius with a MySQL backend will
-not handle the load of accounting for multiple Cisco gateways
-under full utilisation.
-The default database config also thows away all non-standard
-RADIUS attributes which infact contains alot of highly useful
-information pertinent to VoIP.
-
-The good news is that with a few modifications to the configuration
-files and the use of Postgresql (or another heavy duty SQL server)
-insead of MySQL FreeRadius can be made into a reliable, flexible
-and scalable (and free!) billing solution for VoIP providors.
-
-MySQL cannot be used as the configuration relies on the connect and
-disconnect time as reported by the Cisco gatways (Cisco VSA
-attributes "h323-connect-time" and "h323-disconnect-time") and
-MySQL limited date handling does not recognise full Cisco date
-stamps time as a valid "datetime". (While Oracle and possibly some
-other high end DBs should support Cisco time format they have not
-been tested at this time). MySQL could possibly be supported in
-future but it would require extra pre-processing by a FreeRADIUS
-module to do so and there is no plan currently to implement this,
-although working code that implements this would be happily accepted.
-
-This reliance on VSA records REQUIRES that all cisco devices be
-configured to send VSA attributes. This system is not known to work
-with any non-cisco equipment, although it is theoretically possible
-for non-cisco equipment to implement Cisco VSA attributes...
-
-This is required as the default FreeRadius SQL configuration (where
-RADIUS "Start" records are INSERTed into the database, and then
-UPDATEd with information from the associated "Stop" record) does not
-scale as well as this solution which strictly uses INSERTs. As call
-start and stop times are not contained in "standard" radius
-attributes (They are added/updated by FreeRadius when the record is
-logged in the default configuration.)
-
-This REQUIRES all equipment be kept is timesync with the use on NTP
-otherwise similtaneous records from different gateways may have
-differing timestamps.
-
-CONFIGURATION
-
-* Install and configure FreeRadius as appropriate for your system.
-* Test that FreeRadius is recieving accounting records from your
-  gateway. Do not proceed until you are certain this is working.
-
-* Configure all the NASes to send VSA attributes. On older Ciscos
-  use one of the following commands (depending if you are using 
-  SIP or H323):
-       "gw-accounting h323 vsa"
-       "gw-accounting sip vsa"
-  On Ciscos with newer versions of IOS need both of the following commands:
-       "gw-accounting aaa"
-       "radius-server vsa send"
-
-* Create a Database to hold your billing records. ie:
-       "createdb radius"
-
-* Import the SQL schema to your database. ie:
-       "psql radius < cisco_h323_db_schema-postgres.sql"
-
-* In /etc/raddb/radiusd.conf set "with_cisco_vsa_hack = yes"
-
-* In /etc/raddb/radiusd.conf add "$INCLUDE  ${confdir}/pgsql-voip.conf"
-  (You can find the correct section by searching for "sql.conf")
-
-* In /etc/raddb/radiusd.conf add "pgsql-voip" to the "accounting { }" section.
-
-* (re)Start radiusd
-
-
-If you wish to do RADIUS SQL Authentication using the same database, you
-must use src/modules/rlm_sql/drivers/rlm_sql_postgresql/db_postgresql.sql
-as well as this schema. This is left as an excercise for the reader.
-
-   -- Peter Nixon [ codemonkey@peternixon.net ]
-
diff --git a/src/billing/cisco_h323_db_sample_functions-postgres.sql b/src/billing/cisco_h323_db_sample_functions-postgres.sql
deleted file mode 100644 (file)
index f38ee74..0000000
+++ /dev/null
@@ -1,191 +0,0 @@
--- $Id$
-
--- create plpgsql language
-CREATE FUNCTION "plpgsql_call_handler" () RETURNS LANGUAGE_HANDLER AS '$libdir/plpgsql' LANGUAGE C;
-CREATE TRUSTED LANGUAGE "plpgsql" HANDLER "plpgsql_call_handler";
-
-
-CREATE OR REPLACE FUNCTION chop_number(VARCHAR) RETURNS VARCHAR AS '
- DECLARE
-     original_number ALIAS FOR $1;
-     new_number VARCHAR;
- BEGIN
-        new_number := split_part(original_number,''#'',2);
-        IF new_number = '''' THEN
-         RETURN original_number;
-        ELSE RETURN new_number;
-     END IF;
- END;
-' LANGUAGE 'plpgsql';
-
-CREATE OR REPLACE FUNCTION chop_number_country(VARCHAR) RETURNS VARCHAR AS '
- DECLARE
-     original_number ALIAS FOR $1;
-     new_number VARCHAR;
-     clean_number VARCHAR;
- BEGIN
-        new_number := split_part(original_number,''#'',2);
-        IF new_number = '''' THEN
-         clean_number := original_number;
-        ELSE clean_number := new_number;
-        END IF;
-        IF substring(clean_number from 1 for 2) = ''00'' THEN
-          RETURN substring(clean_number from 3 for 2);
-        ELSIF substring(clean_number from 1 for 1) = ''0'' THEN
-          RETURN '''';
-        ELSE
-          RETURN substring(clean_number from 1 for 2);
-        END IF;
- END;
-' LANGUAGE 'plpgsql';
-
-CREATE OR REPLACE FUNCTION chop_number_city(VARCHAR) RETURNS VARCHAR AS '
- DECLARE
-     original_number ALIAS FOR $1;
-     new_number VARCHAR;
-     clean_number VARCHAR;
- BEGIN
-        new_number := split_part(original_number,''#'',2);
-        IF new_number = '''' THEN
-         clean_number := original_number;
-        ELSE clean_number := new_number;
-        END IF;
-        IF substring(clean_number from 1 for 2) = ''00'' THEN
-          RETURN substring(clean_number from 5 for 3);
-        ELSIF substring(clean_number from 1 for 1) = ''0'' THEN
-          RETURN substring(clean_number from 2 for 3);
-        ELSE
-          RETURN substring(clean_number from 3 for 3);
-        END IF;
- END;
-' LANGUAGE 'plpgsql';
-
-CREATE OR REPLACE FUNCTION chop_number_number(VARCHAR) RETURNS VARCHAR AS '
- DECLARE
-     original_number ALIAS FOR $1;
-     new_number VARCHAR;
-     clean_number VARCHAR;
- BEGIN
-        new_number := split_part(original_number,''#'',2);
-        IF new_number = '''' THEN
-         clean_number := original_number;
-        ELSE clean_number := new_number;
-        END IF;
-        IF substring(clean_number from 1 for 2) = ''00'' THEN
-          RETURN substring(clean_number from 8 for 11);
-        ELSIF substring(clean_number from 1 for 1) = ''0'' THEN
-          RETURN substring(clean_number from 5 for 11);
-        ELSE
-          RETURN substring(clean_number from 6 for 11);
-        END IF
- END;
-' LANGUAGE 'plpgsql';
-
--- Some sample database VIEWs to simplify billing queries.
-
-CREATE OR REPLACE VIEW StartVoIPd AS
-SELECT DISTINCT ON(h323SetupTime, CallID) * FROM StartVoIP;
-
-CREATE OR REPLACE VIEW StopVoIPd AS
-SELECT DISTINCT ON(h323SetupTime, CallID) * FROM StopVoIP;
-
-
-CREATE OR REPLACE VIEW call_history_csps2 AS
-SELECT StartVoIP.h323ConnectTime, StopVoIP.h323DisconnectTime, (EXTRACT(EPOCH FROM(StopVoIP.h323DisconnectTime - StartVoIP.h323ConnectTime)))::BIGINT AS CallLength, StopVoIP.CalledStationId AS Number, StopVoIP.UserName AS UserName, StopVoIP.CallingStationId AS caller_id, StopVoIP.CallID
-FROM StopVoIPd AS StopVoIP LEFT OUTER JOIN StartVoIPd AS StartVoIP
-ON (StopVoIP.CallID = StartVoIP.CallID)
-WHERE StopVoIP.NASIPAddress = '212.50.54.122'
-ORDER BY StartVoIP.h323ConnectTime;
-
-CREATE OR REPLACE VIEW call_history_csps AS
-SELECT CAST ((h323DisconnectTime::date AT TIME ZONE 'UTC') AS date) AS Date, CAST ((h323DisconnectTime AT TIME ZONE 'UTC') AS time without time zone) AS Time, AcctSessionTime AS Length, CalledStationId AS Number, UserName AS UserName, CallingStationId AS caller_id, CallID
-FROM StopVoIP
-WHERE NASIPAddress = '212.50.54.122';
-
-CREATE OR REPLACE VIEW call_history AS
-SELECT CAST ((h323SetupTime::date AT TIME ZONE 'UTC') AS date) AS Date, CAST ((h323SetupTime AT TIME ZONE 'UTC') AS time without time zone) AS Time, AcctSessionTime AS Length, CalledStationId AS Number, UserName AS UserName, CallingStationId AS caller_id, H323RemoteAddress, NASIPAddress, CallID
-FROM StopVoIP;
-
-CREATE OR REPLACE VIEW call_history AS
-SELECT CAST ((pots.h323SetupTime::date AT TIME ZONE 'UTC') AS date) AS Date, CAST ((pots.h323SetupTime AT TIME ZONE 'UTC') AS time without time zone) AS Time, pots.AcctSessionTime AS Length, pots.CalledStationId AS Number, ip.H323RemoteAddress AS cust_ip, ip.NASIPAddress AS gw_ip
-FROM StopTelephony AS pots LEFT OUTER JOIN StopVoIP AS ip
-ON (pots.CallID = ip.CallID);
-
-CREATE OR REPLACE VIEW call_history_customer AS
-SELECT Date, Time, Length, Number, cust_ip, gw_ip, CustomerIP.Company AS Company
-FROM call_history LEFT OUTER JOIN customerip
-ON (call_history.cust_ip = CustomerIP.IpAddr);
-
-CREATE OR REPLACE VIEW customerip AS
-SELECT gw.cust_gw AS IpAddr, cust.company AS Company, cust.customer AS Customer, gw.location AS Location
-FROM customers  AS cust, cust_gw AS gw
-WHERE cust.cust_id = gw.cust_id;
-
-CREATE OR REPLACE VIEW VoIP AS
-SELECT RadAcctId AS ID, NASIPAddress AS GWIP, AcctSessionTime AS Call_Seconds, chop_number_country(CalledStationId) AS Country, chop_number_city(CalledStationId) AS City,chop_number_number(CalledStationId) AS Number, chop_number(CalledStationId) AS Original_Number, EXTRACT(YEAR FROM (h323setuptime AT TIME ZONE 'UTC')) AS Year, EXTRACT(MONTH FROM (h323setuptime AT TIME ZONE 'UTC')) AS Month, EXTRACT(DAY FROM (h323setuptime AT TIME ZONE 'UTC')) AS Day, CAST ((h323SetupTime AT TIME ZONE 'UTC') AS time without time zone) AS Time, h323DisconnectCause AS error_code, H323RemoteAddress AS Remote_IP, CallID
-FROM StopVoIP;
-
-CREATE OR REPLACE VIEW Telephony AS
-SELECT RadAcctId AS ID, NASIPAddress AS GWIP, AcctSessionTime AS Call_Seconds, chop_number_country(CalledStationId) AS Country, chop_number_city(CalledStationId) AS City,chop_number_number(CalledStationId) AS Number, chop_number(CalledStationId) AS Original_Number, EXTRACT(YEAR FROM (h323setuptime AT TIME ZONE 'UTC')) AS Year, EXTRACT(MONTH FROM (h323setuptime AT TIME ZONE 'UTC')) AS Month, EXTRACT(DAY FROM (h323setuptime AT TIME ZONE 'UTC')) AS Day, CAST ((h323SetupTime AT TIME ZONE 'UTC') AS time without time zone) AS Time, h323DisconnectCause AS error_code, split_part(split_part(CiscoNASPort,':',1),' ',2) AS PRI, split_part(CiscoNASPort,':',3) AS PRI_channel, CiscoNASPort AS isdn_port, CallID AS ConfID
-FROM StopTelephony;
-
-CREATE OR REPLACE VIEW calls AS
-SELECT Date, Time, Length, Number, cust_ip, gw_ip
-FROM call_history
-WHERE Length > 0
-ORDER BY Date, Time, Number, Length, cust_ip ASC;
-
-CREATE OR REPLACE VIEW call_history_daily AS
-SELECT pots.h323ConnectTime, pots.AcctSessionTime, pots.CalledStationId, ip.H323RemoteAddress, pots.NASIPAddress
-FROM StopTelephony AS pots, StopVoIP AS ip
-WHERE pots.h323connecttime BETWEEN DATE'YESTERDAY' AND DATE'TODAY' AND pots.h323ConfID = ip.h323ConfID
-ORDER BY h323ConnectTime, CalledStationId ASC;
-
-CREATE OR REPLACE VIEW call_errors AS
-SELECT pots.h323ConnectTime, pots.AcctSessionTime, pots.CalledStationId, ip.H323RemoteAddress, pots.NASIPAddress
-FROM StopTelephony  AS pots, StopVoIP AS ip
-WHERE pots.h323ConfID = ip.h323ConfID AND ip.h323disconnectcause <> 0 AND ip.h323disconnectcause <> 10
-AND ip.h323disconnectcause <> 11 AND ip.h323disconnectcause <> 13
-ORDER BY H323ConnectTime, CalledStationId, H323RemoteAddress ASC;
-
-
-
-CREATE OR REPLACE FUNCTION VoIPInsertRecord(StopVoIP.UserName%TYPE, StopVoIP.NASIPAddress%TYPE, StopVoIP.AcctSessionTime%TYPE,
-StopVoIP.AcctInputOctets%TYPE, StopVoIP.AcctOutputOctets%TYPE, StopVoIP.CalledStationId%TYPE, StopVoIP.CallingStationId%TYPE,
-StopVoIP.AcctDelayTime%TYPE, StopVoIP.h323CallOrigin%TYPE, StopVoIP.h323SetupTime%TYPE, StopVoIP.h323ConnectTime%TYPE, StopVoIP.h323DisconnectTime%TYPE,
-StopVoIP.h323DisconnectCause%TYPE, StopVoIP.H323RemoteAddress%TYPE, StopVoIP.H323VoiceQuality%TYPE, StopVoIP.h323ConfID%TYPE) RETURNS BOOLEAN AS '
-DECLARE
-    key1 ALIAS FOR $10;
-    key2 ALIAS FOR $2;
-    key3 ALIAS FOR $16;
-BEGIN
-        PERFORM radacctid FROM StopVoIP WHERE h323SetupTime = $10 AND NASIPAddress = $2 AND CallID = $16;
-        IF NOT FOUND THEN
-               INSERT into StopVoIP (
-                UserName, NASIPAddress, AcctSessionTime, AcctInputOctets, AcctOutputOctets, CalledStationId, CallingStationId,
-                AcctDelayTime, h323callorigin, h323setuptime, h323connecttime, h323disconnecttime, h323disconnectcause,
-               H323RemoteAddress, h323voicequality, CallID) VALUES($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16);
-       RETURN true;
-        END IF;
-        RETURN false;
-END;
-' LANGUAGE 'plpgsql';
-
-CREATE OR REPLACE FUNCTION TelephonyInsertRecord(StopTelephony.UserName%TYPE, StopTelephony.NASIPAddress%TYPE, StopTelephony.AcctSessionTime%TYPE,
-    StopTelephony.AcctInputOctets%TYPE, StopTelephony.AcctOutputOctets%TYPE, StopTelephony.CalledStationId%TYPE, StopTelephony.CallingStationId%TYPE,
-    StopTelephony.AcctDelayTime%TYPE, StopTelephony.CiscoNASPort%TYPE, StopTelephony.h323CallOrigin%TYPE, StopTelephony.h323SetupTime%TYPE,
-    StopTelephony.h323ConnectTime%TYPE, StopTelephony.h323DisconnectTime%TYPE, StopTelephony.h323DisconnectCause%TYPE,
-    StopTelephony.H323VoiceQuality%TYPE, StopTelephony.CallID%TYPE) RETURNS BOOLEAN AS '
-DECLARE
-BEGIN
-        PERFORM radacctid FROM StopTelephony WHERE h323SetupTime = $11 AND NASIPAddress = $2 AND CallID = $16;
-        IF NOT FOUND THEN
-               INSERT into StopTelephony (
-                UserName, NASIPAddress, AcctSessionTime, AcctInputOctets, AcctOutputOctets, CalledStationId, CallingStationId,
-                AcctDelayTime, CiscoNASPort, h323callorigin, h323setuptime, h323connecttime, h323disconnecttime, h323disconnectcause,
-               h323voicequality, CallID) VALUES($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16);
-       RETURN true;
-        END IF;
-        RETURN false;
-END;
-' LANGUAGE 'plpgsql';
diff --git a/src/billing/clarent2db.pl b/src/billing/clarent2db.pl
deleted file mode 100755 (executable)
index 94ef5ed..0000000
+++ /dev/null
@@ -1,308 +0,0 @@
-#!/usr/bin/perl
-#
-# syslog2db - Extract Clarent VoIP CDRs from billing_record files and
-# insert them into a Postgresql database.
-#
-# Author:       Peter Nixon <codemonkey@peternixon.net>
-# Date:         2003-05-07
-# Summary:      Clarent, VoIP, CDR, database, postgresql
-# Copyright:    2002, Peter Nixon <codemonkey@peternixon.net>
-# Copy Policy:  Free to copy and distribute provided all headers are left
-#               intact and no charge is made for this program.  I would
-#               appreciate copies of any modifications to the script.
-# URL:          http://www.peternixon.net/code/
-#
-# $Id$
-
-
-# Modules we use to make things easier
-use POSIX;
-require DBI;
-require Getopt::Long;
-use Carp;
-#use Symbol;
-#use Time::Local;
-#use strict;   # Errrm. That looks like effort :-)
-
-
-# Program and File locations
-# gzcat - 'cat for .gz / gzip files'
-# If you don't have gzcat and do have gzip then use: ln gzip gzcat
-my $GZCAT = "/usr/bin/zcat";
-# zcat - 'cat for .Z / compressed files'
-my $ZCAT = "/usr/bin/zcat";
-# bzcat - 'cat for .bz2 files'
-my $BZCAT = "/usr/bin/bzcat";
-
-#### You should not have to modify anything below here
-
-$| = 1;        #Unbuffered output
-my $progname = "clarent2db.pl";
-my $progname_long = "Clarent Billing Record to DB Importer";
-my $version = 0.2;
-
-# Set up some basic variables
-my $double_match_no = 0; my $verbose = 0; my $recordno = 0; my $fileno = 0; my $lineno = 0;
-my $starttime = time();
-
-
-# Database Information
-my $database    = "clarent";
-my $defaulthostname    = "localhost";
-my $port        = "3306";
-my $user        = "postgres";
-my $password    = "";
-
-# Defaults
-my $defaulttimezone = "UTC";
-my $defaultyear = 2003;
-my $dbh;
-
-my %working_record = ();
-
-my %months_map = (
-    'Jan' => '01', 'Feb' => '02', 'Mar' => '03',
-    'Apr' => '04', 'May' => '05', 'Jun' => '06',
-    'Jul' => '07', 'Aug' => '08', 'Sep' => '09',
-    'Oct' => '10', 'Nov' => '11', 'Dec' => '12',
-    'jan' => '01', 'feb' => '02', 'mar' => '03',
-    'apr' => '04', 'may' => '05', 'jun' => '06',
-    'jul' => '07', 'aug' => '08', 'sep' => '09',
-    'oct' => '10', 'nov' => '11', 'dec' => '12',
-);
-
-sub db_connect {
-        my $hostname = shift;
-        if ($verbose > 1) { print "DEBUG: Connecting to Database Server: $hostname\n" }
-        if ($hostname eq 'localhost') {
-        if ($verbose > 1) { print "DEBUG: localhost connection so using UNIX socket instead of network socket.\n" }
-                $dbh = DBI->connect("DBI:Pg:dbname=$database", "$user", "$password")
-                        or die "Couldn't connect to database: " . DBI->errstr;
-        }
-        else {
-                $dbh = DBI->connect("DBI:Pg:dbname=$database;host=$hostname", "$user", "$password")
-                        or die "Couldn't connect to database: " . DBI->errstr;
-        }
-}
-
-sub db_disconnect {
-        ### Now, disconnect from the database
-        if ($verbose > 1) { print "DEBUG: Disconnecting from Database Server\n" }
-        $dbh->disconnect
-            or warn "Disconnection failed: $DBI::errstr\n";
-}
-
-sub db_read {
-        $passno++;
-        if ($verbose > 0) { print "Record: $passno) Conf ID: $working_record{h323confid}   Start Time: $working_record{start_time} IP: $working_record{ip_addr_egress} Call Length: $working_record{duration}\n"; }
-        my $sth = $dbh->prepare("SELECT ID FROM billing_record
-                WHERE start_time = ?
-                AND ip_addr_ingress = ?
-                AND h323confid = ?")
-                or die "Couldn't prepare statement: " . $dbh->errstr;
-
-          my @data;
-          $sth->execute($working_record{start_time}, $working_record{ip_addr_ingress}, $working_record{h323confid})             # Execute the query
-            or die "Couldn't execute statement: " . $sth->errstr;
-           my $returned_rows = $sth->rows;
-
-          if ($sth->rows == 0) {
-                &db_insert;
-          } elsif ($sth->rows == 1) {
-                if ($verbose > 0) { print "Exists in DB.\n"; }
-          } else {
-                $double_match_no++;
-                # FIXME: Log this somewhere!
-                print "********* More than One Match! We have a problem!\n";
-          }
-
-        $sth->finish;
-
-}
-
-sub db_insert {
-        $sth2 = $dbh->prepare("INSERT into billing_record (local_SetupTime, start_time, duration, service_code, phone_number,
-               ip_addr_ingress, ip_addr_egress, bill_type, disconnect_reason, extended_reason_code, dialed_number, codec, h323ConfID, port_number)
-                values(?,?,?,?,?,?,?,?,?,?,?,?,?,?)");
-
-         $sth2->execute($working_record{local_setuptime}, $working_record{start_time}, $working_record{duration},
-               $working_record{service_code}, $working_record{phone_number}, $working_record{ip_addr_ingress}, $working_record{ip_addr_egress},
-               $working_record{bill_type}, $working_record{disconnect_reason}, $working_record{extended_reason_code}, $working_record{dialed_number},
-               $working_record{codec}, $working_record{h323confid}, $working_record{port_number});
-        #my $returned_rows = $sth2->rows;
-        if ($verbose > 0) { print "$sth2->rows rows added to DB\n"; }
-        $sth2->finish();
-
-}
-
-sub file_read {
-        my $filename = shift;
-        if ($verbose > 1) { print "DEBUG: Reading detail file: $filename\n" }
-        if ( $filename =~ /.gz$/ ) {
-                open (FILE, "$GZCAT $filename |") || warn "read_detailfile(\"$filename\"): $!\n";
-        } elsif ( $filename =~ /.Z$/ ) {
-                open (FILE, "$ZCAT $filename |") || warn "read_detailfile(\"$filename\"): $!\n";
-        } elsif ( $filename =~ /.bz2$/ ) {
-                open (FILE, "$BZCAT $filename |") || warn "read_detailfile(\"$filename\"): $!\n";
-        } else {
-                open (FILE, "<$filename") || warn "read_detailfile(\"$filename\"): $!\n";
-        }
-        $valid_input = (eof(FILE) ? 0 : 1);
-        if ($verbose > 1) { print "DEBUG: Starting to read records from $filename\n"; }
-        while($valid_input) {
-                $valid_input = 0 if (eof(FILE));
-                if ($verbose > 2) { print "DEBUG: Reading Record\n"; }
-                $_ = <FILE>;
-               $lineno++;
-                if ($verbose > 1) { print "DEBUG Raw Record: $_"; }
-               #&record_mangle($_);
-               &record_match($_);
-        }
-}
-
-sub record_match($) {
-       chomp($_);
-
-        # Spilt the Call record up into fields
-        my @callrecord = split(/,/, $_);
-
-       if (scalar(@callrecord) == 70) {        # Check that we have the right number of fields for a Clarent record
-               if ($verbose > 1) { print "DEBUG: Clean Record: @callrecord\n"; }
-               $recordno++; %working_record = ();
-               $working_record{local_setuptime} = clarent2normaltime($callrecord[0]);
-                $working_record{start_time} = $callrecord[3];  # This is in Unix timestamp format, relative to the originating gateway.
-                                                               # It is therefore useless unless ALL gateways are set with the same timezone,
-                                                               # so I don't bother to convert it to datetime format.
-                $working_record{duration} = $callrecord[4];
-                $working_record{service_code} = $callrecord[5];
-                $working_record{phone_number} = $callrecord[6];
-                $working_record{ip_addr_ingress} = $callrecord[7];
-                $working_record{ip_addr_egress} = $callrecord[8];
-                $working_record{h323confid} = $callrecord[9];
-                $working_record{bill_type} = $callrecord[12];
-                $working_record{disconnect_reason} = $callrecord[15];
-                $working_record{extended_reason_code} = $callrecord[16];
-                $working_record{port_number} = $callrecord[21];
-                $working_record{dialed_number} = $callrecord[60];
-                $working_record{codec} = $callrecord[67];
-
-               &db_read;
-
-       } else { if ($verbose > 1) { print "DEBUG: ERROR: Record is not in Clarent format: $str\n"; } }
-
-
-}
-
-sub clarent2normaltime($) {
-        if ( /^
-            (\S{3})\/(\d+)\/(\d{4})     # Month Day Year
-            \s
-            (\d+):(\d+):(\d+)           # Hour Min Sec
-            \s
-            (\d{4})                     # msec??
-            \s
-            \w*?:?                      # RESEND: (Discarded)
-            \s?
-            \S{1}                       # U (Discarded) FIXME: does anyone know what this value means??
-            /x ) {
-                my $month = $months_map{$1}; defined $month or croak "ERROR: Unknown month \"$1\"\n";
-                my $days = $2;
-                my $years = $3;
-                my $hours = $4;
-                my $minutes = $5;
-                my $seconds = $6;
-                return "$years-$month-$days $hours:$minutes:$seconds";
-        } else {
-            if ($verbose > 0) { print "ERROR: Not in Clarent time format: $str\n"; }
-        };
-
-}
-
-sub print_usage_info {
-        print "\n";
-        my $leader = "$progname_long Ver: $version Usage Information";
-        my $underbar = $leader;
-        $underbar =~ s/./-/g;
-        print "$leader\n$underbar\n";
-        print "\n";
-        print "  Syntax:   $progname [ options ] file\n";
-        print "\n";
-        print "    -h --help                        Show this usage information\n";
-        print "    -v --verbose                     Turn on verbose\n";
-        print "    -x --debug                       Turn on debugging\n";
-        print "    -V --version                     Show version and copyright\n";
-        print "    -H --host                        Database host to connect to (Default: localhost)\n";
-        print "\n";
-}
-
-sub main {
-        # Parse the command line for options
-        if (!scalar(@ARGV)) {
-                &print_usage_info();
-                exit(SUCCESS);
-        };
-       my $quiet = 0;
-
-        # See the Getopt::Long man page for details on the syntax of this line
-        @valid_opts = ("h|help", "V|version", "f|file=s", "x|debug", "v|verbose+" => \$verbose, "q|quiet+" => \$quiet, "D|date=s", "H|host=s", "p|procedure");
-        Getopt::Long::Configure("no_getopt_compat", "bundling", "no_ignore_case");
-        Getopt::Long::GetOptions(@valid_opts);
-
-        # Post-parse the options stuff
-        select STDOUT; $| = 1;
-        if ($opt_V) {
-                # Do not edit this variable.  It is updated automatically by CVS when you commit
-                my $rcs_info = 'CVS Revision $Revision$ created on $Date$ by $Author$ ';
-
-                $rcs_info =~ s/\$\s*Revision: (\S+) \$/$1/;
-                $rcs_info =~ s/\$\s*Date: (\S+) (\S+) \$/$1 at $2/;
-                $rcs_info =~ s/\$\s*Author: (\S+) \$ /$1/;
-
-                print "\n";
-                print "$progname Version $version by Peter Nixon <codemonkey\@peternixon.net>\n";
-                print "Copyright (c) 2003 Peter Nixon\n";
-                print "  ($rcs_info)\n";
-                print "\n";
-                return SUCCESS;
-        } elsif ($opt_h) {
-                &print_usage_info();
-                exit(SUCCESS);
-        }
-
-        if ($opt_x) {
-                print "DEBUG: Debug mode is enabled.\n";
-                $verbose = 2;
-        } elsif ($quiet) { $verbose -= $quiet; }
-
-        if (@ARGV) {
-                if ($opt_H) { &db_connect($opt_H);
-                } else { &db_connect($defaulthostname); }
-
-               if (scalar(@ARGV) > 1) {
-                       foreach $file (@ARGV) {                 # Loop through the defined files
-                               $fileno++;
-                               &file_read($file);
-                       }
-               } else {
-                       $file = @ARGV[0];
-                               &file_read($file);
-               }
-               if ($verbose >= 0) {
-                       my $runtime = (time() - $starttime);
-                       if ($runtime < 1) { $runtime = 0.5; }           # Prevent divide-by-zero errors
-                       my $speed = ($recordno / $runtime);
-                       if ($fileno > 1) {
-                               print "\n$recordno records from $lineno lines in $fileno files were processed in ~$runtime seconds (~$speed records/sec)\n";
-                       } else {
-                               print "\n$recordno records from $lineno lines in $file were processed in ~$runtime seconds (~$speed records/sec)\n";
-                       }
-               }
-
-                &db_disconnect;
-        } else {
-                print "ERROR: Please specify one or more detail files to import.\n";
-                exit(FAILURE);
-        }
-}
-
-exit &main();
diff --git a/src/billing/clarent_db_schema-postgres.sql b/src/billing/clarent_db_schema-postgres.sql
deleted file mode 100644 (file)
index 58a864c..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Id: postgresql.conf,v 1.8.2.11 2003/07/15 11:15:43 pnixon Exp $
- *
- * --- Peter Nixon [ codemonkey@peternixon.net ]
- * This is a custom SQL schema for doing Clarent VoIP accounting
- * Clarents don't support RADIUS but I use this along with the other
- * files in this directory to do billing so it can live here :-)
- *
- */
-
-CREATE TABLE billing_record (
-  Id BIGSERIAL PRIMARY KEY,
-  local_SetupTime timestamp,
-  start_time NUMERIC(11),
-  duration INTEGER,
-  service_code CHAR(1),
-  phone_number VARCHAR(24),
-  ip_addr_ingress INET,
-  ip_addr_egress INET,
-  bill_type CHAR(1),
-  disconnect_reason CHAR(2),
-  extended_reason_code CHAR(2),
-  dialed_number VARCHAR(30),
-  port_number INTEGER,
-  codec VARCHAR(20),
-  h323ConfID VARCHAR(64)
-);
-create UNIQUE index combo on billing_record (start_time, ip_addr_ingress, h323ConfID);
diff --git a/src/billing/h323detail2db.pl b/src/billing/h323detail2db.pl
deleted file mode 100755 (executable)
index 28ff402..0000000
+++ /dev/null
@@ -1,458 +0,0 @@
-#!/usr/bin/perl
-#
-# Author:       Peter Nixon <codemonkey@peternixon.net>
-# Summary:      Extract information from Radius detail log and
-#              compare/insert/update a Postgresql database.
-# Copy Policy:  GNU Public Licence Version 2
-# URL:          http://www.peternixon.net/code/
-# Supported:    PostgreSQL (tested on version 7.2, 7.3, 7.4 and 8) and FreeRadius
-# Copyright:    2004 Peter Nixon http://www.petenixon.net
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of Version 2 of the GNU General Public License as
-# published by the Free Software Foundation.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# $Id$
-#
-
-
-
-# Modules that we use to get things done.
-require DBI;
-require Getopt::Long;
-
-## Program and File locations
-# gzcat - 'cat for .gz / gzip files'
-# If you don't have gzcat and do have gzip then use: ln gzip gzcat
-$GZCAT = "/usr/bin/zcat";
-# zcat - 'cat for .Z / compressed files'
-$ZCAT = "/usr/bin/zcat";
-# bzcat - 'cat for .bz2 files'
-$BZCAT = "/usr/bin/bzcat";
-
-
-# Default Variables
-$database    = "radius";
-$port        = "3306";
-$user        = "postgres";
-$password    = "";
-
-
-
-#### You should not have to modify anything below here
-$progname = "H323 Detail2DB";
-$version = 2.2;
-
-# Set up some basic variables
-my $passno = 0; my $duplicates = 0; my $verbose = 0; my %duplicate_records = ();
-my $starttime = time();
-
-
-sub db_connect {
-       my $hostname = shift;
-       if ($verbose > 1) { print "DEBUG: Connecting to Database Host: $hostname\n" }
-       if ($hostname eq 'localhost') {
-       if ($verbose > 1) { print "DEBUG: localhost connection so using UNIX socket instead of network socket.\n" }
-               $dbh = DBI->connect("DBI:Pg:dbname=$database", "$user", "$password")
-                       or die "Couldn't connect to database: " . DBI->errstr;
-       } else {
-               $dbh = DBI->connect("DBI:Pg:dbname=$database;host=$hostname", "$user", "$password")
-                       or die "Couldn't connect to database: " . DBI->errstr;
-       }
-}
-
-sub db_disconnect {
-       my $hostname = shift;
-       if ($verbose > 1) { print "DEBUG: Disconnecting from Database Host: $hostname\n" }
-       $dbh->disconnect                # Disconnect from the database
-           or warn "Disconnection failed: $DBI::errstr\n";
-}
-
-sub process_duplicates {
-       if ($verbose > 1) { print "DEBUG: Now processing $duplicates duplicate records\n" }
-       foreach my $a1 ( keys %duplicate_records ) {
-               print "$a1:\n";
-               for my $a2 ( keys %{ $duplicate_records{$a1} } ) {
-                       print "\t$a2 = $duplicate_records{$a1}{$a2}\n";
-               }
-       print "\n";
-       }
-}
-
-
-sub procedure_insert {         # FIXME: Does not work with current SQL schema. Use standard method
-       if ($verbose > 0) { print "Record: $passno) Conf ID: $h323_conf_id   Setup Time: $h323_setup_time  Call Length: $AcctSessionTime   "; }
-       if ($h323_call_type eq 'VoIP') {
-        $sth2 = $dbh->prepare("SELECT VoIPInsertRecord('$UserName', '$NasIPAddress', '$AcctSessionTime', '$AcctInputOctets', '$AcctOutputOctets',
-               '$Called_Station_Id', '$Calling_Station_Id', '$AcctDelayTime', '$h323_call_origin', '$h323_setup_time',
-               '$h323_connect_time','$h323_disconnect_time', '$h323_disconnect_cause', (NULLIF('$h323_remote_address', '')::inet), '$h323_voice_quality', '$h323_conf_id')");
-       }
-       elsif ($h323_call_type eq 'Telephony') {
-        $sth2 = $dbh->prepare("SELECT TelephonyInsertRecord('$UserName', '$NasIPAddress', '$AcctSessionTime', '$AcctInputOctets', '$AcctOutputOctets',
-               '$Called_Station_Id', '$Calling_Station_Id', '$AcctDelayTime', '$Cisco_NAS_Port', '$h323_call_origin',
-               '$h323_setup_time', '$h323_connect_time','$h323_disconnect_time', '$h323_disconnect_cause', '$h323_voice_quality', '$h323_conf_id')");
-       } else { print "ERROR: Unsupported h323calltype \"$h323_call_type\"\n" }
-       $sth2->execute();
-
-       if ($verbose > 0) { print "sent to DB\n"; }
-       $sth2->finish();
-}
-
-sub db_insert {
-       if ($h323_call_type eq 'VoIP') {
-        $sth2 = $dbh->prepare("INSERT into StopVoIP (
-               AcctTime, UserName, NASIPAddress, AcctSessionTime, AcctInputOctets, AcctOutputOctets,
-               CalledStationId, CallingStationId, AcctDelayTime, H323RemoteAddress, h323gwid, h323callorigin,
-               callid, h323connecttime, h323disconnectcause, h323disconnecttime, h323setuptime, h323voicequality)
-               values(($Timestamp)::abstime, '$UserName', '$NasIPAddress', '$AcctSessionTime', '$AcctInputOctets',
-               '$AcctOutputOctets', '$Called_Station_Id', '$Calling_Station_Id', '$AcctDelayTime',
-               NULLIF('$h323_remote_address', '')::INET, '$h323_gw_id','$h323_call_origin', '$h323_conf_id',
-               NULLIF('$h323_connect_time', '')::TIMESTAMPTZ, '$h323_disconnect_cause',
-               NULLIF('$h323_disconnect_time', '')::TIMESTAMPTZ, NULLIF('$h323_setup_time', '')::TIMESTAMPTZ,
-               NULLIF('$h323_voice_quality','')::INT4)");
-
-       }
-       elsif ($h323_call_type eq 'Telephony') {
-        $sth2 = $dbh->prepare("INSERT into StopTelephony (
-               AcctTime, UserName, NASIPAddress, AcctSessionTime,
-                AcctInputOctets, AcctOutputOctets, CalledStationId, CallingStationId, AcctDelayTime,
-                CiscoNASPort, h323callorigin, callid, h323connecttime, h323disconnectcause, h323disconnecttime, h323setuptime, h323voicequality)
-                values(($Timestamp)::abstime, '$UserName', '$NasIPAddress', '$AcctSessionTime', '$AcctInputOctets', '$AcctOutputOctets',
-                '$Called_Station_Id', '$Calling_Station_Id', '$AcctDelayTime', '$Cisco_NAS_Port', '$h323_call_origin', '$h323_conf_id',
-               '$h323_connect_time', '$h323_disconnect_cause', '$h323_disconnect_time', '$h323_setup_time', '$h323_voice_quality')");
-       } else {
-               if ($h323_call_type) { print "ERROR: Unsupported h323calltype: \"$h323_call_type\"\n"; }
-               else { print "ERROR: Missing \"h323calltype\". This doesn't appear to be a VoIP record."; }
-               return;         # Not a VoIP record. Bailout
-        }
-       $sth2->execute();
-       #my $returned_rows = $sth2->rows;
-       if ($verbose > 0) { print "added to DB\n"; }
-       $sth2->finish();
-}
-
-## This sub can be used to update data in an existing database if you have some fields not in the Database.
-sub db_update {
-       my $sth2= $dbh->prepare("UPDATE radacct SET CalledStationId = '$Called_Station_Id',
-               AcctTerminateCause = '$AcctTerminateCause', H323RemoteAddress = '$h323_remote_address',
-               AcctStatusType = '$AcctStatusType', callid = '$h323_conf_id', h323calltype = '$h323_call_type',
-               CiscoNASPort = '$Cisco_NAS_Port', h323disconnectcause = '$h323_disconnect_cause',
-               h323connecttime = '$h323_connect_time', h323disconnecttime = '$h323_disconnect_time',
-               h323setuptime = '$h323_setup_time' WHERE AcctSessionId = 'AcctSessionId' AND UserName = '$UserName'
-               AND NASIPAddress = '$NasIPAddress' AND h323confid = '$h323_conf_id'");
-        $sth2->execute();
-        my $returned_rows = $sth2->rows;
-       if ($verbose > 0) { print " $returned_rows record(s) updated\n" }
-        $sth2->finish();
-
-}
-
-sub db_read {
-       if ($verbose > 0) { print "Record: $passno) ConfID: $h323_conf_id Timestamp: $radius_record_timestamp Length: $AcctSessionTime "; }
-       my $sth = $dbh->prepare("SELECT RadAcctId FROM Stop$h323_call_type
-               WHERE AcctTime = ($Timestamp)::abstime
-               AND NASIPAddress = '$NasIPAddress'
-               AND callid = '$h323_conf_id'")
-                or die "\nCouldn't prepare statement: " . $dbh->errstr . "\n";
-
-       my @data;
-       $sth->execute()             # Execute the query
-               or die "\nCouldn't execute statement: " . $sth->errstr . "\n";
-       my $returned_rows = $sth->rows;
-
-          if ($sth->rows == 0) {
-               &db_insert;     # It's a new record. All systems go.
-          } elsif ($sth->rows == 1) {
-                if ($verbose > 0) { print "already in DB.\n"; }
-               # FIXME: Make updates an option!
-                #while (@data = $sth->fetchrow_array()) {
-                #my $dbAcctSessionId = $data[1];
-               ##&db_update;
-                #}
-          } else {
-               $duplicates++;   # FIXME: Log this somewhere!
-                print "********* More than One Match! We have a problem!\n";
-          }
-
-       $sth->finish;
-}
-
-sub process_record {
-       $radius_record_timestamp = @record[0];
-       chomp $radius_record_timestamp;
-       if ($verbose > 1) { print "DEBUG: Processing new record with time: $radius_record_timestamp \n"; }
-       # Clear the variables we use so that we don't have rubbish from the last loop
-       $UserName=""; $NasPort=""; $NasPortType="";
-       $NasIPAddress = ""; $AcctStatusType=""; $AcctSessionTime="";
-       $AcctInputOctets=""; $AcctOutputOctets=""; $AcctTerminateCause="";
-       $ServiceType=""; $FramedProtocol=""; $FramedIPAddress="";
-       $Timestamp=""; $AcctDelayTime=0; $ConnectInfo=""; $Called_Station_Id="";
-       $SQL_User_Name=""; $Cisco_NAS_Port=""; $Client_IP_Address="";
-       $h323_remote_address=""; $h323_disconnect_cause=""; $h323_gw_id="";
-       $h323_conf_id=""; $h323_call_type=""; $h323_disconnect_time="";
-       $h323_connect_time=""; $h323_setup_time=""; $Calling_Station_Id="";
-       $h323_call_origin=""; $h323_voice_quality=""; $h323_gw_id="";
-
-       foreach (@record) {             # Parse the lines of data into variables.
-
-       # Initial cleanup of junk from the line of data
-       s/^\s+//;       # Strip leading spaces.
-       s/^Quintum-//;  # Strip leading "Quintum-".
-       chomp;          # Strip trailing CR
-
-       $AcctStatusType = $_ if s/Acct-Status-Type = //;
-       if ($AcctStatusType eq "Stop") {                # All the data we need is in Stop records.
-       } elsif ($AcctStatusType eq "Start") {
-               if ($verbose > 1) { print "DEBUG: Skipping \"Start\" record\n"; }
-               return;
-       } elsif ($AcctStatusType eq "Alive"){
-               if ($verbose > 1) { print "DEBUG: Skipping \"Alive\" record\n"; }
-               return;
-       };
-
-       $UserName = $_ if s/User-Name = //;
-       $NasIPAddress = $_ if s/NAS-IP-Address = //;
-       $AcctSessionTime = $_ if s/Acct-Session-Time = //;
-       $AcctInputOctets = $_ if s/Acct-Input-Octets = //;
-       $AcctOutputOctets = $_ if s/Acct-Output-Octets = //;
-       $AcctDelayTime = $_ if s/Acct-Delay-Time = //;
-       $Called_Station_Id = $_ if s/Called-Station-Id = //;
-       $Calling_Station_Id = $_ if s/Calling-Station-Id = //;
-       $Cisco_NAS_Port = $_ if s/Cisco-NAS-Port = //;
-       $Timestamp = $_ if s/Timestamp = //;
-       if (s/h323-call-type = \"h323-call-type=//) {
-                        $h323_call_type = substr($_, 0, -1);
-                } elsif (s/h323-call-type = //) {
-                        $h323_call_type = $_;
-            };
-       if (s/h323-remote-address = \"h323-remote-address=//) {
-                       $h323_remote_address = $_;
-               } elsif (s/h323-remote-address = //) {
-                       $h323_remote_address = $_;
-           };
-       if (s/h323-disconnect-cause = \"h323-disconnect-cause=//) {
-                        $h323_disconnect_cause = $_;
-                } elsif (s/h323-disconnect-cause = //) {
-                        $h323_disconnect_cause = $_;
-            };
-       if (s/h323-conf-id = \"h323-conf-id=//) {
-                        $h323_conf_id = substr($_, 0, -1);
-                } elsif (s/h323-conf-id = //) {
-                        $h323_conf_id = $_;
-            };
-       if (s/h323-connect-time = \"h323-connect-time=//) {
-                        $h323_connect_time = substr($_, 0, -1);
-                } elsif (s/h323-connect-time = //) {
-                        $h323_connect_time = $_;
-            };
-       if (s/h323-disconnect-time = \"h323-disconnect-time=//) {
-                        $h323_disconnect_time = substr($_, 0, -1);
-                } elsif (s/h323-disconnect-time = //) {
-                        $h323_disconnect_time = $_;
-            };
-       if (s/h323-setup-time = \"h323-setup-time=//) {
-                        $h323_setup_time = substr($_, 0, -1);
-                } elsif (s/h323-setup-time = //) {
-                        $h323_setup_time = $_;
-            };
-        if (s/h323-call-origin = \"h323-call-origin=//) {
-                        $h323_call_origin = substr($_, 0, -1);
-                } elsif (s/h323-call-origin = //) {
-                        $h323_call_origin = $_;
-            };
-        if (s/h323-gw-id = \"h323-gw-id=//) {
-                        $h323_gw_id = substr($_, 0, -1);
-                } elsif (s/h323-gw-id = //) {
-                        $h323_gw_id = $_;
-            };
-        if (s/h323-voice-quality = \"h323-voice-quality=//) {
-                        $h323_voice_quality = substr($_, 0, -1);
-                } elsif (s/h323-voice-quality = //) {
-                        $h323_voice_quality = $_;
-            };
-                # FIXME: ugh, definitely look into using backreference.
-                # something like s/(\S+)\s*=\s*\1/\1 = / or so
-         }
-
-
-       # Remove quotation marks from a bunch of different fields (Stupid Cisco)
-       $UserName =~ s/\"//g;
-       $h323_remote_address =~ s/\"//g;
-       $Called_Station_Id =~ s/\"//g;
-       $h323_disconnect_cause =~ s/\"//g;
-       $h323_setup_time =~ s/\"//g;
-       $h323_connect_time =~ s/\"//g;
-       $h323_disconnect_time =~ s/\"//g;
-       $h323_conf_id =~ s/\"//g;
-       $h323_call_type =~ s/\"//g;
-       $h323_call_origin =~ s/\"//g;
-       $h323_voice_quality =~ s/\"//g;
-       $Cisco_NAS_Port =~ s/\"//g;
-
-       # Remove Remove . from the start of time fields (routers that have lost ntp timesync temporarily)
-       $h323_setup_time =~ s/^\.*//;
-       $h323_connect_time =~ s/^\.*//;
-       $h323_disconnect_time =~ s/^\.*//;
-
-       # Ignore broken fields from some stupid, non-cisco gateways (They shall remain nameless)
-       if ($h323_connect_time eq "0") { $h323_connect_time = "" };
-       if ($h323_disconnect_time eq "0") { $h323_disconnect_time = "" };
-
-       # If its a valid record continue onto the database functions
-       # FIXME: More checks needed here.
-       if ($h323_call_type) {
-               $passno++;
-               #@duplicate_records{$passno} += @record;
-               if (&procedure_get()) { &procedure_insert; }
-               else { &db_read; }
-       } else { if ($verbose > 1) { print "DEBUG: Skipping non-h323 record\n"; } }
-}
-
-sub read_record {
-       my $keepreading = 1;
-       @record = ();
-       while ($keepreading) {
-               $_ = <DETAIL>;
-               print "$_" if ($verbose > 1);
-               if ( /^$/ ) {
-                       $keepreading = 0;       # End of record
-               } else {
-                       $record[++$#record] = $_;
-               }
-       }
-       &process_record;
-}
-
-sub read_detailfile {
-       my $file_starttime = time(); my $filename = shift; my @record = (); my $record_no = 0;
-       if ($verbose > 1) { print "DEBUG: Reading detail file: $filename\n" }
-       if ((-r $filename) != 1) {              # test if the file exists and is readable
-               if ($verbose >= 0) { print "INFO: Skipping file \"$filename\" as it is not readable or does not exist.\n" }
-               return;
-        }
-       if ( $filename =~ /.gz$/ ) {            # Deal with compressed files
-               open (DETAIL, "$GZCAT $filename |") || warn "read_detailfile(\"$filename\"): $!\n";
-       } elsif ( $filename =~ /.Z$/ ) {
-               open (DETAIL, "$ZCAT $filename |") || warn "read_detailfile(\"$filename\"): $!\n";
-       } elsif ( $filename =~ /.bz2$/ ) {
-               open (DETAIL, "$BZCAT $filename |") || warn "read_detailfile(\"$filename\"): $!\n";
-       } else {
-               open (DETAIL, "<$filename") || warn "read_detailfile(\"$filename\"): $!\n";
-       }
-       $valid_input = (eof(DETAIL) ? 0 : 1);
-       if ($verbose > 1) { print "DEBUG: Starting to read records from $filename\n"; }
-       while($valid_input) {
-               $valid_input = 0 if (eof(DETAIL));
-               if ($verbose > 1) { print "DEBUG: Reading Record\n"; }
-               &read_record;
-               $record_no++;
-       }
-       my $file_runtime = (time() - $file_starttime);
-       if ($file_runtime < 1) { $file_runtime = 1; }
-       my $file_speed = ($record_no / $file_runtime);
-        if ($verbose >= 0) { print "\n $record_no total records read from $filename were processed in $file_runtime seconds ($file_speed records/sec) \n"; }
-}
-
-sub print_usage_info {
-       print "\n";
-       $leader = "$progname $version Usage Information";
-       $underbar = $leader;
-       $underbar =~ s/./-/g;
-       print "$leader\n$underbar\n";
-       print "\n";
-       print "  Syntax:   h323detail2db.pl [ options ] detailfile(s)\n";
-       print "\n";
-       print "    -d --database                    Database to use\n";
-       print "    -h --help                        Show this usage information\n";
-       print "    -H --host                        Database host to connect to (Default: localhost)\n";
-       print "    -p --procedure                   Use Postgresql stored procedure (BROKEN!)\n";
-       print "    -q --quiet                       Turn on quiet mode (No Output)\n";
-       print "    -v --verbose                     Turn on verbose\n";
-       print "    -V --version                     Show version and copyright\n";
-       print "    -x --debug                       Turn on debugging\n";
-       print "\n";
-}
-
-sub procedure_get() {
-        return $stored_procedure;
-}
-
-sub procedure_set($) {
-        $stored_procedure = $_[0];
-}
-
-
-sub main {
-        # Parse the command line for options
-        if (!scalar(@ARGV)) {
-               &print_usage_info();
-               exit(SUCCESS);
-       };
-
-       # See the Getopt::Long man page for details on the syntax of this line
-       @valid_opts = ("h|help", "V|version", "f|file=s", "x|debug", "d|database=s", "v|verbose+" => \$verbose, "q|quiet+" => \$quiet, "D|date=s", "H|host=s", "p|procedure");
-       Getopt::Long::Configure("no_getopt_compat", "bundling", "no_ignore_case");
-       Getopt::Long::GetOptions(@valid_opts);
-
-       # Post-parse the options stuff
-       select STDOUT; $| = 1;
-       if ($opt_V) {
-               # Do not edit this variable.  It is updated automatically by CVS when you commit
-               my $rcs_info = 'CVS Revision $Revision$ created on $Date$ by $Author$ ';
-
-               $rcs_info =~ s/\$\s*Revision: (\S+) \$/$1/;
-               $rcs_info =~ s/\$\s*Date: (\S+) (\S+) \$/$1 at $2/;
-               $rcs_info =~ s/\$\s*Author: (\S+) \$ /$1/;
-
-               print "\n";
-               print "$progname Version $version by Peter Nixon - http://www.peternixon.net/\n";
-               print "Copyright (c) 2002-2004 Peter Nixon\n";
-               print "  ($rcs_info)\n";
-               print "\n";
-               return SUCCESS;
-       } elsif ($opt_h) {
-               &print_usage_info();
-               exit(SUCCESS);
-       }
-
-       if ($opt_x) {
-               print "DEBUG: Debug mode is enabled.\n";
-               $verbose = 2;
-       } elsif ($quiet) { $verbose -= $quiet; }
-       &procedure_set($opt_p);
-       if ($opt_d) {
-               if ($verbose > 0) { print "Using database \"$opt_d\" instead of default database \"$database\"\n"; }
-               $database = $opt_d;
-       }
-
-       if (@ARGV) {
-               my $db_host;
-               if ($opt_H) { $db_host = $opt_H; }
-               else { $db_host = "localhost"; }
-               &db_connect($db_host);
-
-               # Loop through the defined files
-               foreach $file (@ARGV) {
-                       &read_detailfile($file);
-               }
-               &process_duplicates;
-               &db_disconnect($db_host);
-
-               my $runtime = (time() - $starttime);
-               if ($runtime < 1) { $runtime = 1; }
-               my $speed = ($passno / $runtime);
-               if ($verbose >= 0) { print "\n $passno valid records were processed in $runtime seconds ($speed records/sec) \n"; }
-       } else {
-               print "ERROR: Please specify one or more detail file(s) to import.\n";
-               exit(FAILURE);
-       }
-
-}
-
-
-exit &main();