summaryrefslogtreecommitdiffstats
path: root/bin/cssrancid.in
diff options
context:
space:
mode:
Diffstat (limited to 'bin/cssrancid.in')
-rw-r--r--bin/cssrancid.in144
1 files changed, 79 insertions, 65 deletions
diff --git a/bin/cssrancid.in b/bin/cssrancid.in
index 27049df..294f400 100644
--- a/bin/cssrancid.in
+++ b/bin/cssrancid.in
@@ -1,8 +1,9 @@
#! @PERLV_PATH@
##
-## $Id: cssrancid.in,v 1.4 2004/01/11 03:49:13 heas Exp $
+## $Id: cssrancid.in,v 1.13 2006/10/05 04:27:42 heas Exp $
##
-## Copyright (C) 1997-2004 by Terrapin Communications, Inc.
+## @PACKAGE@ @VERSION@
+## Copyright (C) 1997-2006 by Terrapin Communications, Inc.
## All rights reserved.
##
## This software may be freely copied, modified and redistributed
@@ -21,25 +22,30 @@
#
# RANCID - Really Awesome New Cisco confIg Differ
#
-# usage: rancid [-d] [-l] [-f filename | $host]
+# usage: rancid [-dV] [-l] [-f filename | hostname]
#
use Getopt::Std;
-getopts('dfl');
+getopts('dflV');
+if ($opt_V) {
+ print "@PACKAGE@ @VERSION@\n";
+ exit(0);
+}
$log = $opt_l;
$debug = $opt_d;
$file = $opt_f;
$host = $ARGV[0];
$clean_run = 0;
$found_end = 0;
-$timeo = 90; # clogin timeout in seconds
+$timeo = 90; # clogin timeout in seconds
-my(%filter_pwds); # password filtering mode
+my(@commandtable, %commands, @commands);# command lists
+my(%filter_pwds); # password filtering mode
# This routine is used to print out the router configuration
sub ProcessHistory {
- my($new_hist_tag,$new_command,$command_string,@string)=(@_);
- if((($new_hist_tag ne $hist_tag) || ($new_command ne $command))
- && defined %history) {
+ my($new_hist_tag,$new_command,$command_string,@string) = (@_);
+ if ((($new_hist_tag ne $hist_tag) || ($new_command ne $command))
+ && defined %history) {
print eval "$command \%history";
undef %history;
}
@@ -64,7 +70,7 @@ sub numerically { $a <=> $b; }
# This is a sort routine that will sort numerically on the
# keys of a hash as if it were a normal array.
sub keynsort {
- local(%lines)=@_;
+ local(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $key (sort numerically keys(%lines)) {
@@ -77,7 +83,7 @@ sub keynsort {
# This is a sort routine that will sort on the
# keys of a hash as if it were a normal array.
sub keysort {
- local(%lines)=@_;
+ local(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $key (sort keys(%lines)) {
@@ -90,7 +96,7 @@ sub keysort {
# This is a sort routine that will sort on the
# values of a hash as if it were a normal array.
sub valsort{
- local(%lines)=@_;
+ local(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $key (sort values %lines) {
@@ -102,7 +108,7 @@ sub valsort{
# This is a numerical sort routine (ascending).
sub numsort {
- local(%lines)=@_;
+ local(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $num (sort {$a <=> $b} keys %lines) {
@@ -116,7 +122,7 @@ sub numsort {
# ip address when the ip address is anywhere in
# the strings.
sub ipsort {
- local(%lines)=@_;
+ local(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $addr (sort sortbyipaddr keys %lines) {
@@ -129,7 +135,7 @@ sub ipsort {
# These two routines will sort based upon IP addresses
sub ipaddrval {
my(@a) = ($_[0] =~ m#^(\d+)\.(\d+)\.(\d+)\.(\d+)$#);
- $a[3]+256*($a[2]+256*($a[1]+256*$a[0]));
+ $a[3] + 256 * ($a[2] + 256 * ($a[1] +256 * $a[0]));
}
sub sortbyipaddr {
&ipaddrval($a) <=> &ipaddrval($b);
@@ -141,7 +147,6 @@ sub ShowVersion {
while (<INPUT>) {
tr/\015//d;
- study;
last if(/^$prompt/);
next if(/^(\s*|\s*$cmd\s*)$/);
return(-1) if (/command authorization failed/i);
@@ -254,6 +259,8 @@ sub ShowVersion {
sub TermLength {
# Dummy subroutine.. need to set term length differently for CSS
# boxes as term length 0 doesnt work correctly. POS.
+ print STDERR " In TermLength: $_" if ($debug);
+ $_ = <INPUT>;
return(0);
}
@@ -264,6 +271,8 @@ sub CopyProfile {
## of couse breaks the interaction... strangely enough tho
## in a failover environment, only the secondary behaves this
## way.. the primary lets you log out and does not complain.
+ print STDERR " In CopyProfile: $_" if ($debug);
+ $_ = <INPUT>;
return(0);
}
@@ -283,15 +292,16 @@ sub ShowBoot {
return(1) if /Ambiguous command/i;
# return(1) if /(Invalid input detected|Type help or )/;
return(1) if /(Open device \S+ failed|Error opening \S+:)/;
+ next if (/\*\* BOOT CONFIG /);
next if /CONFGEN variable/;
if (!defined($H0)) {
$H0=1; ProcessHistory("COMMENTS","keysort","H0","!\n");
}
if ($type !~ /^(12[04]|7)/) {
if ($type !~ /^(29|35)00/) {
- ProcessHistory("COMMENTS","keysort","H2","!BootFlash: $_");
+ ProcessHistory("COMMENTS","keysort","H2","!BootFlash: $_");
} else {
- ProcessHistory("COMMENTS","keysort","H1","!Variable: $_");
+ ProcessHistory("COMMENTS","keysort","H1","!Variable: $_");
}
} elsif (/variable/) {
ProcessHistory("COMMENTS","keysort","H1","!Variable: $_");
@@ -305,17 +315,18 @@ sub ShowBoot {
# This routine processes a "show run"
sub ShowRun {
print STDERR " In ShowRun: $_" if ($debug);
- my($lineauto) = 0;
+ my($lines) = 0;
while (<INPUT>) {
tr/\015//d;
- study;
- last if(/^$prompt/);
+ if(/^$prompt/) {
+ $found_end = 1 if ($lines > 4);
+ return(1);
+ }
return(-1) if (/command authorization failed/i);
# the pager can not be disabled per-session on the PIX
s/^<-+ More -+>\s*//;
/Non-Volatile memory is in use/ && return(-1); # NvRAM is locked
- $lineauto = 0 if (/^[^ ]/);
# skip the crap
if (/^(##+$|(Building|Current) configuration)/i) {
while (<INPUT>) {
@@ -335,14 +346,14 @@ sub ShowRun {
/^! (Last configuration|NVRAM config last)/ && next;
## CSS specific....
/Generated on/ && next;
+ $lines++;
# Dog gone Cool matches to process the rest of the config
/^tftp-server flash / && next; # kill any tftp remains
/^ntp clock-period / && next; # kill ntp clock-period
/^ length / && next; # kill length on serial lines
/^ width / && next; # kill width on serial lines
- $lineauto = 1 if /^ modem auto/;
- /^ speed / && $lineauto && next; # kill speed on serial lines
+ /^ speed / && next; # kill speed on serial lines
/^ clockrate / && next; # kill clockrate on serial interfaces
if (/^(enable )?(password|passwd) / && $filter_pwds >= 1) {
ProcessHistory("ENABLE","","","!$1$2 <removed>\n");
@@ -360,11 +371,9 @@ sub ShowRun {
}
next;
}
- if (/^username (\S+)(\s.*)? password ((\d) \S+|\S+)/) {
- if ($filter_pwds == 2) {
- ProcessHistory("USER","keysort","$1","!username $1$2 password <removed>\n");
- } elsif ($filter_pwds == 1 && $4 ne "5"){
- ProcessHistory("USER","keysort","$1","!username $1$2 password <removed>\n");
+ if (/\s*username (\S+)(\s.*)? (des-password|password) (\S+|\S+)/) {
+ if ($filter_pwds >= 1) {
+ ProcessHistory("USER","keysort","$1","! username $1$2 $3 <removed>$'\n");
} else {
ProcessHistory("USER","keysort","$1","$_");
}
@@ -537,11 +546,6 @@ sub ShowRun {
# catch anything that wasnt matched above.
ProcessHistory("","","","$_");
- # end of config. the ": " game is for the PIX
- if (/^(: +)?end$/ || /CSS.*#/ || /$prompt/ ) {
- $found_end = 1;
- return(1);
- }
}
return(0);
}
@@ -550,25 +554,30 @@ sub ShowRun {
sub DoNothing {print STDOUT;}
# Main
-%commands=(
- 'term length 65535' => "TermLength",
- 'copy profile user-profile' => "CopyProfile",
- 'show version' => "ShowVersion",
- 'show boot' => "ShowBoot",
- 'show run' => "ShowRun"
-);
-# keys() doesnt return things in the order entered and the order of the
-# cmds is important (show version first and show run last). pita
-@commands=(
- "term length 65535",
- "copy profile user-profile",
- "show version",
- "show boot",
- "show run"
+@commandtable = (
+ {'term length 65535' => 'TermLength'},
+ {'copy profile user-profile' => 'CopyProfile'},
+ {'show version' => 'ShowVersion'},
+ {'show boot' => 'ShowBoot'},
+ {'show run' => 'ShowRun'}
);
+# Use an array to preserve the order of the commands and a hash for mapping
+# commands to the subroutine and track commands that have been completed.
+@commands = map(keys(%$_), @commandtable);
+%commands = map(%$_, @commandtable);
+
$cisco_cmds=join(";",@commands);
$cmds_regexp=join("|",@commands);
+if (length($host) == 0) {
+ if ($file) {
+ print(STDERR "Too few arguments: file name required\n");
+ exit(1);
+ } else {
+ print(STDERR "Too few arguments: host name required\n");
+ exit(1);
+ }
+}
open(OUTPUT,">$host.new") || die "Can't open $host.new for writing: $!\n";
select(OUTPUT);
# make OUTPUT unbuffered if debugging
@@ -590,7 +599,7 @@ if ($file) {
}
# determine password filtering mode
-if ($ENV{"FILTER_PWDS"} =~ /no/i) {
+if ($ENV{"FILTER_PWDS"} =~ /no/i) {
$filter_pwds = 0;
} elsif ($ENV{"FILTER_PWDS"} =~ /all/i) {
$filter_pwds = 2;
@@ -599,11 +608,12 @@ if ($ENV{"FILTER_PWDS"} =~ /no/i) {
}
ProcessHistory("","","","!RANCID-CONTENT-TYPE: cisco-css\n!\n");
-ProcessHistory("COMMENTS","keysort","B0","!\n");
-ProcessHistory("COMMENTS","keysort","F0","!\n");
-ProcessHistory("COMMENTS","keysort","G0","!\n");
+#ProcessHistory("COMMENTS","keysort","B0","!\n");
+#ProcessHistory("COMMENTS","keysort","F0","!\n");
+#ProcessHistory("COMMENTS","keysort","G0","!\n");
TOP: while(<INPUT>) {
+NEXT:
tr/\015//d;
if (/\#\s?exit/) {
$clean_run=1;
@@ -615,23 +625,27 @@ TOP: while(<INPUT>) {
$clean_run=0;
last;
}
- while (/#\s*($cmds_regexp)\s*$/) {
+ if (/#\s*($cmds_regexp)\s*$/) {
$cmd = $1;
- if (!defined($prompt)) {$prompt = ($_ =~ /^([^#]+#)/)[0]; }
+ if (!defined($prompt)) {
+ $prompt = ($_ =~ /^([^#]+#)/)[0];
+ $prompt =~ s/([][}{)(\\])/\\$1/g;
+ print STDERR ("PROMPT MATCH: $prompt\n") if ($debug);
+ }
print STDERR ("HIT COMMAND:$_") if ($debug);
if (! defined($commands{$cmd})) {
print STDERR "$host: found unexpected command - \"$cmd\"\n";
- # $clean_run = 0;
- # last TOP;
- next TOP;
- } else {
- $rval = &{$commands{$cmd}};
- delete($commands{$cmd});
- if ($rval == -1) {
- $clean_run = 0;
- last TOP;
- }
+ $clean_run = 0;
+ last TOP;
+ }
+ $rval = &{$commands{$cmd}};
+ delete($commands{$cmd});
+ if ($rval == -1) {
+ $clean_run = 0;
+ last TOP;
}
+ # the function may have read the next prompt/cmd line
+ goto NEXT;
}
}
print STDOUT "Done $logincmd: $_\n" if ($log);