3
## radsqlrelay.pl This program tails a SQL logfile and forwards
4
## the queries to a database server. Used to
5
## replicate accounting records to one (central)
6
## database, even if the database has extended
9
## Version: $Id: radsqlrelay,v 1.4.2.2 2006/08/17 12:20:41 nbk Exp $
11
## Author: Nicolas Baradakis <nicolas.baradakis@cegetel.net>
13
## Copyright (C) 2005 Cegetel
15
## This program is free software; you can redistribute it and/or
16
## modify it under the terms of the GNU General Public License
17
## as published by the Free Software Foundation; either version 2
18
## of the License, or (at your option) any later version.
20
## This program is distributed in the hope that it will be useful,
21
## but WITHOUT ANY WARRANTY; without even the implied warranty of
22
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23
## GNU General Public License for more details.
25
## You should have received a copy of the GNU General Public License
26
## along with this program; if not, write to the Free Software
27
## Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
33
use POSIX qw(:unistd_h :errno_h);
45
# /!\ OS-dependent structure
52
# c2ph says: typedef='s2 l2 i', sizeof=16
53
my $FLOCK_STRUCT = 's2l2i';
57
my ($fh, $start, $len) = @_;
58
$start = 0 unless defined $start;
59
$len = 0 unless defined $len;
61
#type whence start till pid
62
my $packed = pack($FLOCK_STRUCT, F_WRLCK, SEEK_SET, $start, $len, 0);
63
if (fcntl($fh, F_SETLKW, $packed)) { return 1 }
70
usage: radsqlrelay [options] file_path
72
-? Print this help message.
73
-1 One-shot mode: push the file to database and exit.
74
-b database Name of the database to use.
75
-d sql_driver Driver to use: mysql, pg, oracle.
76
-h host Connect to host.
77
-P port Port number to use for connection.
78
-p passord Password to use when connecting to server.
79
-u user User for login.
89
$dbh = DBI->connect($dbinfo->{base}, $dbinfo->{user}, $dbinfo->{pass},
90
{ RaiseError => 0, PrintError => 0,
95
$dbinfo->{handle} = $dbh;
100
my ($dbinfo, $path) = @_;
102
unless (-e $path.'.work') {
103
until (rename($path, $path.'.work')) {
106
return if $need_exit;
108
print STDERR "error: Couldn't move $path to $path.work: $!\n";
114
open(FILE, "+< $path.work") or die "error: Couldn't open $path.work: $!\n";
115
setlock(\*FILE) or die "error: Couldn't lock $path.work: $!\n";
118
chomp(my $query = $_);
119
until ($dbinfo->{handle}->do($query)) {
120
print $dbinfo->{handle}->errstr."\n";
121
if ($dbinfo->{handle}->ping) {
124
print "error: Lost connection to database\n";
125
$dbinfo->{handle}->disconnect;
126
connect_wait($dbinfo);
131
unlink($path.'.work');
132
close(FILE); # and unlock
144
my $ret = getopts("b:d:fh:P:p:u:x1?", \%args);
145
if (!$ret or @ARGV != 1) {
155
if (lc($args{d}) eq 'mysql') {
156
$data_source = "DBI:mysql:database=$args{b};host=$args{h}";
157
} elsif (lc($args{d}) eq 'pg') {
158
$data_source = "DBI:Pg:dbname=$args{b};host=$args{h}";
159
} elsif (lc($args{d}) eq 'oracle') {
160
$data_source = "DBI:Oracle:$args{b}";
162
print STDERR "error: SQL driver not supported yet: $args{d}\n";
165
$data_source .= ";port=$args{P}" if $args{'P'};
167
$SIG{INT} = \&got_signal;
168
$SIG{TERM} = \&got_signal;
171
base => $data_source,
175
connect_wait(\%dbinfo);
177
my $path = shift @ARGV;
180
process_file(\%dbinfo, $path);
181
last if ($args{1} || $need_exit);
185
$dbinfo{handle}->disconnect;