IRRd-Discuss
Date Prev | Date Next |
Date Index |
Thread Index |
Author Index |
Historical
irrdcacher
- From: Jens-s. Voeckler
- Date: Tue Oct 27 06:13:42 1998
Feasgar math,
I experienced a little trouble with the irrdcacher script, part of which
was due to the (now discouraged) perl4 socket handling. I changed the
portion necessary to use Socket, even though IO::Socket would be
preferable. Now perl5 is required. Also changed the PATH to (a) include
/opt/gnu/bin where wget resides, and (b) dirname($0), where the script
resides. Otherwise I got complaints that ripe2rpsl wasn't found. Hope this
is useful.
Le deagh dhùrachd,
Dipl.-Ing. Jens-S. Vöckler (voeckler@rvs.uni-hannover.de)
Institute for Computer Networks and Distributed Systems
University of Hanover, Germany; +49 511 762 4726
#!/bin/perl
#
# This prog is designed to be called from a cron job to update
# the cache for use by irrd. This prog updates the cache
# by ftp'ing remote db's/registries.
# The output can be easily parsed
# from a checker script or output-filter script. Fatal error messages
# are all prefixed with the tag 'ERROR:'. The 'ERROR'
# line gives a description and location of the fatal error. 'WARN'
# msg's are also given in non-fatal situations.
#
require 5.003;
use Getopt::Std;
use Socket;
use File::Basename;
$ENV{PATH} = '/opt/gnu/bin:' . $ENV{PATH} . ':' . dirname($0);
local($wd,$db)=(`pwd`);
chop($wd);
if ($wd =~ /^\s*$/) {
$wd = `/bin/pwd`;
chop($wd);
if ($wd =~ /^\s*$/) {
print "Could not determine current working directory, exit!\n";
exit;
}
}
if (!getopts('p:h:w:s:SCc:')) {
print "ERROR: unknown command-line option or missing flag parm!\n";
&usage();
exit;
}
&usage() if ($#ARGV < 0);
# canonicalize db names
# want *.db, eg, mci.db
foreach $j (@ARGV) {
if ($j !~ /CURRENTSERIAL$/i &&
$j =~ /^(ans|mci|radb|ripe|canet)/i) {
($j = $1) =~ tr/A-Z/a-z/;
$j .= '.db';
push(@DB, $j);
}
else {
push (@OTHERS, $j);
}
}
# load default values
# remove possible trailing '/'
($CACHEDIR = $wd) =~ s/\/$//;
$IRRD_HOST = 'localhost';
$IRRD_PORT = 43 ;
$FTPSVR='ftp.ra.net';
$FTPPTH='routing.arbiter/radb/dbase';
if ($opt_w) {
$ENV{PATH} =~ s/:$//;
$ENV{PATH} .= ":$opt_w";
$opt_w =~ s/\/$//;
print "path-($ENV{PATH})\n";
}
if ($opt_s) {
if ($opt_s =~ /(\S+):(\S+)/) {
print "opt_s-($opt_s)\n";
$FTPSVR = $1;
($FTPPTH = $2) =~ s/\/$//;
print "svr-($FTPSVR) pth-($FTPPTH)\n";
}
else {
print "Please specify the ftp server and remote path as 'server:path'\n";
print "eg, ' ftp.ra.net:/routing.arbiter/radb/dbase'\n";
exit;
}
}
if ($opt_c) {
# remove possible trailing '/'
($CACHEDIR = $opt_c) =~ s/\/$//;
if ($CACHEDIR eq '.') { $CACHEDIR=$wd; }
if ($CACHEDIR eq '..') { ($CACHEDIR = $wd) =~ s/(.*)\/\S+$/$1/; }
}
$IRRD_HOST = $opt_h if ($opt_h);
$IRRD_PORT = $opt_p if ($opt_p);
foreach $db (@DB) {
# $FTPPTH="routing.arbiter/radb/dbase/".$db.'.gz';
$ftppth = $FTPPTH.'/'.$db.'.gz';
&updateDBs($db, $ftppth);
}
foreach $db (@OTHERS) {
# $FTPPTH="routing.arbiter/radb/dbase/".$db;
$ftppth = $FTPPTH.'/'.$db;
&updateBLOBs($db, $ftppth);
}
sub usage {
print "usage: $0 [options] files...\n\n";
print "options: -h irrd host name (default localhost)\n";
print " -p irrd port (default 43)\n";
print " -s ftp server and remote directory (default 'ftp.ra.net:routing.arbiter/radb')\n";
print " -w add component to your default search path\n";
print " -c cache path (default ./)\n";
print " -S suppress the cache refresh signal to irrd\n";
print " -C do RPSL conversion\n\n";
print "example: $0 -p 5555 -h sumo.merit.edu radb mci RADB.CURRENTSERIAL\n";
print "\nspecial note: If you are running via cron be sure to use the '-w' flag\n";
exit;
}
#
# Ftp the list of db's specified on the command line
# into the cache area. Send a refresh signal
# to irrd.
#
sub updateDBs {
local($i, $fpath)=@_;
local($msg);
# make a backup db copy in case we need to roll back
if ($opt_C) {
if (system("cp -f $CACHEDIR/$i $CACHEDIR/$i.bak")!=0) {
print "ERROR: updateDBs: Can't make db backup ($CACHEDIR/$i.bak) reason-($!)";
next;
}
}
$msg=&ftpDbNonSplit($i, $fpath);
# print "ftpDbNonSplit returns msg-($msg)\n";
if ($msg=~/ERROR/) {
print "$msg\n";
}
else {
if ($msg ne '') {
print "$msg\n";
}
if ($opt_C) {
$msg=`ripe2rpsl < $CACHEDIR/$i > $CACHEDIR/$i.tmp`;
if ($msg ne '') {
unlink ("$CACHEDIR/$i.tmp");
`mv -f $CACHEDIR/$i.bak $CACHEDIR/$i`;
print "$msg\n";
next;
}
if (system("mv -f $CACHEDIR/$i.tmp $CACHEDIR/$i")!=0) {
print "ERROR: updateDBs: Can't move rpsl db from-($CACHEDIR/$i.tmp) to-($CACHEDIR/$i)";
`mv -f $CACHEDIR/$i.bak $CACHEDIR/$i`;
next;
}
unlink ("$CACHEDIR/$i.bak");
}
if (!$opt_S) {
$i=~s/(\S+)\.db$/$1/;
if (($msg=&rebuildIndex("!B$i")) ne '') {
print "ERROR: $db cache updated but index rebuild error.\n";
print "$msg\n";
}
}
}
}
sub updateBLOBs {
local($remdb, $fpath)=@_;
local($msg);
$msg=&ftpBlob($remdb, $fpath);
# print "ftpDbNonSplit returns msg-($msg)\n";
if ($msg ne '') {
print "$msg\n";
}
}
sub ftpBlob {
local($db, $ftpt)=@_;
local($tmpdir,$msg)=("$CACHEDIR/tmp",'');
# do we have write permission to the cache directory?
return "ERROR: ftpBlob() doesn't have write permission to ($CACHEDIR)!" if (!-w $CACHEDIR);
# Remove old $tmpdir/$db.gz if one is lying around
unlink(glob("$tmpdir/$db"));
# Create a 'tmp' directory to ftp the db's into
return $msg
if (($msg=&myCreateDir($tmpdir,"$tmpdir/$db","ftpBlob()")) ne '');
# ftp the cache file to $tmpdir work area
if (($msg=&importBlob($FTPSVR,$ftpt,$db,$tmpdir)) ne '') {
&backout(\$msg,"ftpBlob()",$tmpdir);
return $msg;
}
if (system("mv -f $tmpdir/$db $CACHEDIR/$db")!=0) {
$msg="ERROR: ftpBlob: Can't move db from-($tmpdir/$db) to-($CACHEDIR/$db)";
&backout(\$msg,"ftpBlob()",$tmpdir,"$tmpdir/$db");
return $msg;
}
# Get rid of temp file and rm $tmpdir directory
&backout(\$msg,"ftpBlob()",$tmpdir,"$tmpdir/$db");
return $msg;
}
sub importBlob {
local($ftpsvr,$ftppth,$locfile,$locdir)=@_;
local($outm,$m);
# print "Inside the new wget routine...\n";
# print "ftpsvr-($ftpsvr) ftppth-($ftppth) db-($db) locdir-($locdir)\n";
$outm=`wget --passive-ftp -P $locdir ftp://$ftpsvr/$ftppth 2>&1`;
# print "wget blob out-($outm) returning...\n";
# back out if not all of the ftp files were retrieved
if ($outm!~/${locfile}\'\s+saved/) {
if ($outm ne '') {
return "ERROR: importBlob() unsuccessful ftp $locfile reason-($outm)";
}
else {
return "ERROR: importBlob() unsuccessful ftp $locfile";
}
}
return '';
}
#
# This routine ftp's db's from a remote site and places
# it into the cache area. ftpDbNonSplit() will return "ERROR..."
# for operation fail, "WARN..." for operation success but something
# unusual happened and return '' the null message for operation success.
#
sub ftpDbNonSplit {
local($db, $ftpfile)=@_;
local($tmpdir,$msg)=("$CACHEDIR/tmp",'');
# do we have write permission to the cache directory?
return "ERROR: ftpDbNonSplit() doesn't have write permission to ($CACHEDIR)!" if (!-w $CACHEDIR);
# Remove old $tmpdir/$db.gz if one is lying around
unlink(glob("$tmpdir/$db.gz*"));
# Create a 'tmp' directory to ftp the db's into
return $msg
if (($msg=&myCreateDir($tmpdir,"$tmpdir/$db","ftpDbNonSplit()")) ne '');
# ftp the cache file to $tmpdir work area
if (($msg=&importDB($FTPSVR,$ftpfile,$db,$tmpdir)) ne '') {
&backout(\$msg,"ftpNonDbSplit()",$tmpdir);
return $msg;
}
if (system("mv -f $tmpdir/$db $CACHEDIR/$db")!=0) {
$msg="ERROR: ftpDbNonSplit: Can't move db from-($tmpdir/$db) to-($CACHEDIR/$db)";
&backout(\$msg,"ftpNonDbSplit()",$tmpdir,"$tmpdir/$db");
return $msg;
}
# Get rid of temp file and rm $tmpdir directory
&backout(\$msg,"ftpNonDbSplit()",$tmpdir,"$tmpdir/$db");
return $msg;
}
sub importDB {
local($ftpsvr,$ftppth,$locfile,$locdir)=@_;
local($outm,$m);
# print "Inside the new wget routine...\n";
# print "ftpsvr-($ftpsvr) ftppth-($ftppth) db-($db) locdir-($locdir)\n";
$outm=`wget --passive-ftp -P $locdir ftp://$ftpsvr/$ftppth 2>&1`;
# print "wget out-($outm) returning...\n";
# back out if not all of the ftp files were retrieved
if ($outm!~/${locfile}\.gz\'\s+saved/) {
return "ERROR: importDB() unsuccessful ftp $locfile.gz reason-($outm)";
}
# if (my_system ("gunzip $locdir/$locfile.gz")!=0) {
# $m="ERROR: importDB() Can't unzip ($locdir/$locfile.gz)!";
# $m=$m."\n"."WARN: importDB() Can't remove ($locdir/$locfile.gz)! reason-($!)\n" if (!unlink("$locdir/$locfile.gz"));
# return $m;
# }
if (system("gunzip $locdir/$locfile.gz")!=0) {
$m="ERROR: importDB() Can't unzip ($locdir/$locfile.gz)!";
$m=$m."\n"."WARN: importDB() Can't remove ($locdir/$locfile.gz)! reason-($!)\n" if (!unlink("$locdir/$locfile.gz"));
return $m;
}
return '';
}
sub rebuildIndex ($) {
local($cmd) = @_;
local($whoishost,$port) = ($IRRD_HOST,$IRRD_PORT);
local($sockaddr,$name,$aliases,$type,$len,$thataddr,$proto,$that);
print "\nEnter rebuildIndex()...\n";
print "cmd-($cmd)\n";
print "host-($IRRD_HOST) port-($IRRD_PORT)\n";
my ($name,$aliases,$type,$len,$thataddr) = gethostbyname($whoishost);
my $proto = getprotobyname('tcp');
socket(S,AF_INET,SOCK_STREAM,$proto) ||
return "ERROR: socket failed($cmd)\n";
connect(S,sockaddr_in($port,$thataddr));
select(S); $| = 1; select(STDOUT);
print S "$cmd\n";
$devnull=<S>;
print S "!q\n";
$devnull=<S>;
close(S);
return '';
}
#
# Create directory $dir
# Directory permissions must allow read and write
# $fname is the file we want to create so it cannot
# already exist (ie, must be able to remove if it does
# exist).
#
sub myCreateDir {
local($dir,$fname,$tag)=@_;
# Create a tmp directory to ftp the db's to
if (-d $dir) {
unlink($fname);
if (-e $fname) {
return "ERROR: $tag Can't remove old $fname!";
}
# check if I can cd and write to $dir
if (!-w $dir || !-x $dir) {
return "ERROR: $tag doesn't have write and/or excute permission to ($dir)!";
}
}
else {
if (!mkdir($dir, 0750)) {
return "ERROR: $tag Can't mkdir($dir)-($!)!";
}
}
return '';
}
#
# This routine backs out of the temp dir that was used to
# ftp files into.
# rm files in @rmfiles (they must be full names, else default dir will
# be used). $m is the initial message (could be non-null), $tag is
# the name of the calling routine. $newdir is the dir to cd to and
# $rmdir is the dir to be removed.
#
sub backout {
local($m,$tag,$rmdir,@rmfiles)=@_;
foreach $f (@rmfiles) {
unlink($f);
}
if (!chdir($CACHEDIR)) {
$$m=$$m."\n"."WARN: $tag Can't cd to ($CACHEDIR) ($!)";
}
if (!rmdir($rmdir)) {
$$m=$$m."\n"."WARN: $tag Can't remove dir '$rmdir' reason-($!)\n";
}
}
sub my_system {
local ($command)=@_;
print "enter my_system ($command)\n";
if (system("$command")!=0) {
print "my_system() fail, try-($w_opt)...\n";
if ($w_opt) {
if (system("$w_opt/$command")==0) {
print "my_system() success, w_opt worked!\n";
return 0
}
}
print "my_system() fail, w_opt no work!\n";
return 1;
}
return 0; # maintain similar return code as "system()"
}
|