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
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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 [-d sql_driver] [-b database] [-h host] [-u user] [-p password] [-1] 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.
76 -h host Connect to host.
77 -p passord Password to use when connecting to server.
78 -u user User for login.
88 $dbh = DBI->connect($dbinfo->{base}, $dbinfo->{user}, $dbinfo->{pass},
89 { RaiseError => 0, PrintError => 0,
94 $dbinfo->{handle} = $dbh;
99 my ($dbinfo, $path) = @_;
101 until (rename($path, $path.'.work')) {
104 return if $need_exit;
106 print STDERR "error: Couldn't move $path to $path.work: $!\n";
111 open(FILE, "+< $path.work") or die "error: Couldn't open $path.work: $!\n";
112 setlock(\*FILE) or die "error: Couldn't lock $path.work: $!\n";
115 chomp(my $query = $_);
116 until ($dbinfo->{handle}->do($query)) {
117 print $dbinfo->{handle}->errstr."\n";
118 if ($dbinfo->{handle}->ping) {
121 print "error: Lost connection to database\n";
122 $dbinfo->{handle}->disconnect;
123 connect_wait($dbinfo);
128 unlink($path.'.work');
129 close(FILE); # and unlock #
141 my $ret = getopts("d:b:fh:u:p:x1?", \%args);
142 if (!$ret or @ARGV != 1) {
152 if ($args{d} eq 'mysql') {
153 $data_source = "DBI:mysql:database=$args{b};host=$args{h}";
154 } elsif ($args{d} eq 'pg') {
155 $data_source = "DBI:Pg:dbname=$args{b};host=$args{h}";
157 print STDERR "error: SQL driver not supported yet: $args{d}\n";
161 $SIG{INT} = \&got_signal;
162 $SIG{TERM} = \&got_signal;
165 base => $data_source,
169 connect_wait(\%dbinfo);
171 my $path = shift @ARGV;
173 if (-e $path.'.work') {
174 process_file(\%dbinfo, $path.'.work');
178 process_file(\%dbinfo, $path);
179 last if ($args{1} || $need_exit);
183 $dbinfo{handle}->disconnect;