1#!/usr/local/bin/perl 2## 3## @PACKAGE@ @VERSION@ 4@copyright@ 5# 6# RANCID - Really Awesome New Cisco confIg Differ 7# 8# plogin - poly-login; use router.db files and rancid.{base,types}.conf 9# configurations to determine which login script to execute. 10# 11use 5.0010; 12use strict 'vars'; 13use warnings; 14no warnings 'uninitialized'; 15use Exporter; 16use Getopt::Long; 17# use Getopt::Long qw(:config no_ignore_case bundling); 18Getopt::Long::Configure ("bundling", "no_ignore_case"); 19our($opt_d, $opt_S, $opt_V, $opt_autoenable, $opt_noenable, $opt_c, @opt_E, 20 $opt_e, $opt_f, $opt_h, $opt_i, $opt_m, $opt_M, $opt_p, $opt_r, $opt_s, 21 $opt_t, $opt_u, $opt_v, $opt_w, $opt_x, $opt_y, $opt_z); 22GetOptions('d' => \$opt_d, 'S' => \$opt_S, 'V' => \$opt_V, 23 'autoenable' => \$opt_autoenable, 'noenable' => \$opt_noenable, 24 'c=s' => \$opt_c, "E=s@" => \@opt_E, 'e=s' => \$opt_e, 'f=s' => \$opt_f, 25 'h' => \$opt_h, 'i' => \$opt_i, 'm' => \$opt_m, 'M' => \$opt_M, 26 'p=s' => \$opt_p, 'r=s' => \$opt_r, 's=s' => \$opt_s, 't=s' => \$opt_t, 27 'u=s' => \$opt_u, 'v=s' => \$opt_v, 'w=s' => \$opt_w, 'x=s' => \$opt_x, 28 'y=s' => \$opt_y, 'z=s' => \$opt_z); 29my($BASEDIR, $LIST_OF_GROUPS, $cmd, $i, $j, @routers); 30BEGIN { 31 push(@INC, "@pkglibdir@"); 32} 33use rancid; 34our @ISA = qw(Exporter rancid); 35 36sub usage() 37{ 38 print STDERR "plogin [-dSV] [-autoenable] [-noenable] [-c command] [-Evar=x] [-e enable-password] [-f cloginrc-file] [-p user-password] [-r passphrase] [-s script-file] [-t timeout] [-u username] [-v vty-password] [-w enable-username] [-x command-file] [-y ssh_cypher_type] [-z device_type] router [router...]\n"; 39 exit 64; 40} 41 42# make OUTPUT unbuffered if debugging 43if ($opt_d) { $| = 1; } 44 45if ($opt_h) { 46 usage(); 47} 48 49# option handling initialization 50if ($opt_V) { 51 print "plogin: @PACKAGE@ @VERSION@\n"; 52 # do not exit; exec the script with -V and it will exit 53} 54$cmd .= " -d" if ($opt_d); 55$cmd .= " -i" if ($opt_i); 56$cmd .= " -m" if ($opt_m); 57$cmd .= " -M" if ($opt_M); 58$cmd .= " -S" if ($opt_S); 59$cmd .= " -V" if ($opt_V); 60$cmd .= " -autoenable" if ($opt_autoenable); 61$cmd .= " -noenable" if ($opt_noenable); 62$cmd .= " -c '$opt_c'" if (length($opt_c)); 63foreach $i (@opt_E) { 64 $cmd .= " -E$i"; 65} 66$cmd .= " -e '$opt_e'" if (length($opt_e)); 67$cmd .= " -f '$opt_f'" if (length($opt_f)); 68$cmd .= " -p '$opt_p'" if (length($opt_p)); 69$cmd .= " -r '$opt_r'" if (length($opt_r)); 70$cmd .= " -s '$opt_s'" if (length($opt_s)); 71$cmd .= " -t $opt_s" if (length($opt_t)); 72$cmd .= " -u '$opt_u'" if (length($opt_u)); 73$cmd .= " -v '$opt_v'" if (length($opt_v)); 74$cmd .= " -w '$opt_w'" if (length($opt_w)); 75$cmd .= " -x '$opt_x'" if (length($opt_x)); 76$cmd .= " -y '$opt_y'" if (length($opt_y)); 77$devtype = $opt_z; 78foreach $i (@ARGV) { 79 $cmd .= " $i"; 80 push(@routers, $i); 81} 82 83# what is the device type, supplied or looked-up 84if ($opt_z) { 85 $devtype = $opt_z; 86} else { 87 # Look in router.dbs for device type. 88 # read rancid.conf for BASEDIR and LIST_OF_GROUPS? 89 my($ENVFILE) = "@sysconfdir@/rancid.conf"; 90 open(INPUT, "< $ENVFILE") || die "Could not open $ENVFILE: $!"; 91 close(INPUT); 92 open(INPUT, 93 "sh -c \'. $ENVFILE; echo \"BASEDIR=\$BASEDIR\"; echo \"LIST_OF_GROUPS=\$LIST_OF_GROUPS\"\' |") || 94 die "Could not open $ENVFILE: $!"; 95 while (<INPUT>) { 96 chomp; 97 s/#.$//; 98 s/^\s+//; 99 my($varname, $value) = split('='); 100 if ($varname eq "BASEDIR") { 101 $BASEDIR = $value; 102 } 103 if ($varname eq "LIST_OF_GROUPS") { 104 $LIST_OF_GROUPS = $value; 105 $LIST_OF_GROUPS =~ s/^\s+//; 106 $LIST_OF_GROUPS =~ s/\s+$//; 107 } 108 } 109 close(INPUT); 110 111 # read each router.db for the routername and thus the devtype 112 foreach $i (split(/\s+/, $LIST_OF_GROUPS)) { 113 if (!open(INPUT, "< $BASEDIR/$i/router.db")) { 114 warn "Could not open $BASEDIR/$i/router.db: $!"; 115 next; 116 } 117 while (<INPUT>) { 118 chomp; 119 s/#.$//; 120 s/^\s+//; 121 my($router, $type, $state) = split('\;'); 122 foreach $j (@routers) { 123 if ($router eq $j) { 124 $devtype = $type; 125 close(INPUT); 126 goto FOUND; 127 } 128 } 129 } 130 close(INPUT); 131 } 132} 133 134FOUND: 135if (length($devtype) < 1) { 136 die "Couldn't find device type by hostname in router.dbs\n"; 137} 138 139# load device type spec, build @commandtable and load modules 140if (loadtype($devtype)) { 141 die "Couldn't load device type spec for $rancid::devtype\n"; 142} 143if (! defined($lscript)) { 144 die "login script not defined for device type $rancid::devtype\n"; 145} 146exec($lscript . " $cmd") || 147printf(STDERR "exec($lscript) failed router manufacturer $devtype: $!\n"); 148exit(-1); 149