[rancid] Re: Nortel Alteons (UNCLASSIFIED)

Roeun, Don T Mr CTR USA HRC don.t.roeun at us.army.mil
Thu Jul 23 16:31:37 UTC 2009


Classification:  UNCLASSIFIED 
Caveats: NONE

Hi Bill,

What needs to be modified to use alogin?  As of right now, I have all of
my logins for Cisco & Alteon gear in .cloginrc. 12 of 14 alteons are
backing up correctly.  Do alteon logins need to be in a separate file?
I really appreciate your help.

-----Original Message-----
From: Bill Petrisko [mailto:bill at limelightnetworks.com] 
Sent: Thursday, July 23, 2009 12:06 PM
To: Roeun, Don T Mr CTR USA HRC
Subject: Re: [rancid] Nortel Alteons (UNCLASSIFIED)

On Thu, 23 Jul 2009, Roeun, Don T Mr CTR USA HRC wrote:

> Classification:  UNCLASSIFIED
> Caveats: NONE
>  
> We have a total of 14 Nortel Alteons, and clogin fails on a couple of 
> them.  I tried testing with bin/clogin 5x in a row and it is hit or 
> miss, sometimes it works and sometimes it doesn't.  I can see the 
> username get filled in but not the password.  When it fails with 
> clogin, I can always connect straight to the device from the rancid 
> box outside of clogin using the same credentials.  I tested it 5 times

> on a single device & it worked once or twice.  This is only happening 
> on 2 of the 14 Alteons that we have.  Any thoughts?
> 
> cloginrc:
> 
> #Alteons#
> add user a184-* {password}
> add userprompt a184-* {"Enter radius username"} add userpassword 
> a184-* {password} add passprompt a184-* {"Enter radius password"}
> 
> log:
> 
> a184-dmz13: missed cmd(s): /info/sys,/cfg/dump
> > a184-dmz13: End of run not found
> > /*
> > a184-dmz14: missed cmd(s): /info/sys,/cfg/dump
> > a184-dmz14: End of run not found


Not sure if this will help, but we used to use a modified version of
clogin (we called it "alogin") for collecting from alteon boxes:

also below is the "arancid" we used with it....

bill



#!/usr/bin/expect --
##
##
## Copyright (C) 1997-2001 by Henry Kilmer, Erik Sherk and Pete Whiting.
## All rights reserved.
##
## This software may be freely copied, modified and redistributed
without ## fee for non-commerical purposes provided that this copyright
notice is ## preserved intact on all copies and modified copies.
##
## There is no warranty or other guarantee of fitness of this software.
## It is provided solely "as is". The author(s) disclaim(s) all ##
responsibility and liability with respect to this software's usage ## or
its effect upon hardware, computer systems, other software, or ##
anything else.
##
##
#
# alogin - Alteon WebOS switch login
#
# afort at choqolat.org is responsible for this particular mess # (andrew
fort) #

# Usage line
set usage "Usage: $argv0 \[-c command\] \ \[-Evar=x\] \[-f
cloginrc-file\] \ \[-s script-file\] \[-t timeout\] \[-u username\] \
\[-v vty-password\] \[-x command-file\] \ \[-y ssh_cypher_type\] router
\[router...\]\n"

# env(CLOGIN) may contain:
#	x == do not set xterm banner or name

# Password file
set password_file $env(HOME)/.cloginrc
# Default is to login to the router
set do_command 0
set do_script 0
# The default is to automatically enable set enable 1 # The default is
that you login non-enabled (tacacs can have you login already enabled)
set autoenable 0 # The default is to look in the password file to find
the passwords.  This # tracks if we receive them on the command line.
set do_passwd 1

# Find the user in the ENV, or use the unix userid.
if {[ info exists env(CISCO_USER) ] } {
    set default_user $env(CISCO_USER)
} elseif {[ info exists env(USER) ]} {
    set default_user $env(USER)
} else {
    # This uses "id" which I think is portable.  At least it has existed
    # (without options) on all machines/OSes I've been on recently -
    # unlike whoami or id -nu.
    if [ catch {exec id} reason ] {
	send_error "Error: could not exec id: $reason\n"
	exit 1
    } 
    regexp {\(([^)]*)} "$reason" junk default_user
}   

# Sometimes routers take awhile to answer (the default is 10 sec) set
timeout 45

# Process the command line
for {set i 0} {$i < $argc} {incr i} {
    set arg [lindex $argv $i]

    switch  -glob -- $arg {
	# Username
	-u* -
	-U* {
	    if {! [  regexp .\[uU\](.+) $arg ignore user]} {
		incr i
		set username [ lindex $argv $i ]
	    }
	# VTY Password
	} -v* -
	-v* {
	    if {! [  regexp .\[vV\](.+) $arg ignore passwd]} {
		incr i
		set passwd [ lindex $argv $i ]
	    }
	    set do_passwd 0
	# Enable Username
	} -w* -
	-W* {
	# ignore -w
	# Environment variable to pass to -s scripts
	} -E*
	{
	    if {[ regexp .\[E\](.+)=(.+) $arg ignore varname varvalue]}
{
		incr i
		set E$varname $varvalue
	    } else {
		send_user "Error: invalid format for -E in $arg\n"
		exit 1
	    }
	# Enable Password
	} -e*
	{
	# ignore -e
	# Command to run.
	} -c* -
	-C* {
	    if {! [  regexp .\[cC\](.+) $arg ignore command]} {
		incr i
		set command [ lindex $argv $i ]
	    }
	    set do_command 1
	# Expect script to run.
	} -s* -
	-S* {
	    if {! [  regexp .\[sS\](.+) $arg ignore sfile]} {
		incr i
		set sfile [ lindex $argv $i ]
	    }
	    if { ! [ file readable $sfile ] } {
		send_user "Error: Can't read $sfile\n"
		exit 1
	    }
	    set do_script 1
	# 'ssh -c' cypher type
	} -y* -
	-Y* {
	    if {! [  regexp .\[eE\](.+) $arg ignore cypher]} {
		incr i
		set cypher [ lindex $argv $i ]
	    }
	# alternate cloginrc file
	} -f* -
	-F* {
	    if {! [ regexp .\[fF\](.+) $arg ignore password_file]} {
		incr i
		set password_file [ lindex $argv $i ]
	    }
	# Timeout
	} -t* -
	-T* {
	    if {! [ regexp .\[tT\](.+) $arg ignore timeout]} {
		incr i
	        set timeout [ lindex $argv $i ]
	    }
	# Command file
	} -x* -
	-X {
	    if {! [  regexp .\[xX\](.+) $arg ignore cmd_file]} {
		incr i
		set cmd_file [ lindex $argv $i ]
	    }
	    if [ catch {set cmd_fd [open $cmd_file r]} reason ] {
		send_user "\nError: $reason\n"
		exit 1
	    }
	    set cmd_text [read $cmd_fd]
	    close $cmd_fd
	    set command [join [split $cmd_text \n] \;]
	    set do_command 1
	# Do we enable?
	} -noenable {
	# ignore -noenable
	# Does tacacs automatically enable us?
	} -autoenable {
	# ignore -autoenable
	} -* {
	    send_user "Error: Unknown argument! $arg\n"
	    send_user $usage
	    exit 1
	} default {
	    break
	}
    }
}
# Process routers...no routers listed is an error.
if { $i == $argc } {
    send_user "Error: $usage"
}

# Only be quiet if we are running a script (it can log its output # on
its own) if { $do_script } {
    log_user 0
} else {
    log_user 1
}

#
# Done configuration/variable setting.  Now run with it...
#

# Sets Xterm title if interactive...if its an xterm and the user cares
proc label { host } {
    global env
    # if CLOGIN has an 'x' in it, don't set the xterm name/banner
    if [info exists env(CLOGIN)] {
	if {[string first "x" $env(CLOGIN)] != -1} { return }
    }
    # take host from ENV(TERM)
    if [info exists env(TERM)] {
	if [regexp \^(xterm|vs) $env(TERM) ignore ] {
	    send_user "\033]1;[lindex [split $host "."] 0]\a"
	    send_user "\033]2;$host\a"
	}
    }
}

# This is a helper function to make the password file easier to #
maintain.  Using this the password file has the form:
# add password sl*	pete cow
# add password at*	steve
# add password *	hanky-pie
proc add {var args} { global int_$var ; lappend int_$var $args} proc
include {args} {
    global env
    regsub -all "(^{|}$)" $args {} args
    if { [ regexp "^/" $args ignore ] == 0 } {
	set args $env(HOME)/$args
    }
    source_password_file $args
}

proc find {var router} {
    upvar int_$var list
    if { [info exists list] } {
	foreach line $list {
	    if { [string match [lindex $line 0] $router ] } {
		return [lrange $line 1 end]
	    }
	}
    }
    return {}
}

# Loads the password file.  Note that as this file is tcl, and that # it
is sourced, the user better know what to put in there, as it # could
install more than just password info...  I will assume however, # that a
"bad guy" could just as easy put such code in the clogin # script, so I
will leave .cloginrc as just an extention of that script proc
source_password_file { password_file } {
    global env
    if { ! [file exists $password_file] } {
	send_user "Error: password file ($password_file) does not
exist\n"
	exit 1
    }
    file stat $password_file fileinfo
    if { [expr ($fileinfo(mode) & 007)] != 0000 } {
	send_user "Error: $password_file must not be world
readable/writable\n"
	exit 1
    }
    if [ catch {source $password_file} reason ] {
	send_user "Error: $reason\n"
	exit 1
    }
}

# Log into the router.
proc login { router user userpswd passwd prompt cmethod cyphertype } {
    global spawn_id in_proc do_command do_script
    global u_prompt p_prompt
    set in_proc 1
    set uprompt_seen 0

    # try each of the connection methods in $cmethod until one is
successful
    set progs [llength $cmethod]
    foreach prog [lrange $cmethod 0 end] {
	if [string match "telnet*" $prog] {
	    regexp {telnet(:([^[:space:]]+))*} $prog command suffix port
	    if {"$port" == ""} {
		set retval [ catch {spawn telnet $router} reason ]
	    } else {
		set retval [ catch {spawn telnet $router $port} reason ]
	    }
	    if { $retval } {
		send_user "\nError: telnet failed: $reason\n"
		exit 1
	    }
        } elseif ![string compare $prog "ssh"] {
            if [ catch {spawn ssh -c $cyphertype -x -l $user $router}
reason ] {
                send_user "Error: ssh failed: $reason\n"
                exit 1
            }
        } elseif ![string compare $prog "rsh"] {
            if [ catch {spawn rsh -l $user $router} reason ] {
                send_user "Error: rsh failed: $reason\n"
                exit 1
            }
        } else {
            puts "ERROR: unknown connection method: $prog"
            return 1
        }
        incr progs -1
        sleep 0.3

    # This helps cleanup each expect clause.
    expect_after {
	timeout {
	    send_user "\nError: TIMEOUT reached\n"
	    catch {close}; wait
	    if { $in_proc} {
		return 1
	    } else {
		continue
	    }
	} eof {
	    send_user "\nError: EOF received\n"
	    catch {close}; wait
	    if { $in_proc} {
		return 1
	    } else {
		continue
	    }
	}
    }

    expect {
	"Connection refused" {
	    close; wait
	    sleep 0.3
		expect eof
		send_user "Error: Connection Refused\n"; wait; return 1
	} eof { send_user "Error: Couldn't login\n"; wait; return 1
	} "Unknown host\r\n" {
	    expect eof
	    send_user "Error: Unknown host\n"; wait; return 1
	} "Host is unreachable" {
	    expect eof
	    send_user "Error: Host Unreachable!\n"; wait; return 1
	} "No address associated with name" {
	    expect eof
	    send_user "Error: Unknown host\n"; wait; return 1
	}
	-re "$u_prompt"			{
					  send "$user\r"
					  set uprompt_seen 1
					  exp_continue
					}
	-re "$p_prompt"			{
					  sleep 1
					  if {$uprompt_seen == 1} {
						send "$userpswd\r"
					  } else {
						send "$passwd\r"
					  }
					  exp_continue
					}
	-re "^Confirm seeing above note" {
					  send "y\r"
					  exp_continue
					}
	"Password incorrect"	{ send_user "Error: Check your password
for $router\n";
				  catch {close}; wait; return 1 }
	-re "$prompt"	{ break; }
	denied		{ send_user "Error: Check your passwd for
$router\n"
			    if { $do_command || $do_script } {
			      send "exit\r"
			      wait
			      return 1
			  } else {
			      return 1
			  }
			}
	"\r\n"		{ exp_continue; }
    }
  }
    set in_proc 0
    return 0
}

# Run commands given on the command line.
proc run_commands { prompt command } {
    global in_proc
    set in_proc 1

    send "lines 0\r"
    expect -re $prompt {}

    regsub -all "\[)(]" $prompt {\\&} reprompt

    # Is this a multi-command?
    if [ string match "*\;*" "$command" ] {
	set commands [split $command \;]
	set num_commands [llength $commands]
	for {set i 0} {$i < $num_commands} { incr i} {
	    send "[subst -nocommands [lindex $commands $i]]\r"
	    expect {
		-re "^\[^\n\r]*$reprompt"	{}
		-re "^\[^\n\r ]*>>.*$reprompt"	{ exp_continue }
		-re "\[\n\r]+"			{ exp_continue }
	    }
	}
    } else {
	send "[subst -nocommands $command]\r"
	expect {
		-re "^\[^\n\r]*$reprompt"	{}
		-re "^\[^\n\r ]*>>.*$reprompt"	{ exp_continue }
		-re "\[\n\r]+"			{ exp_continue }
	}
    }
    send "exit\r"
    expect {
	-re "^WARNING: There are unsaved configuration changes."
 	{
		send "y\r"
		exp_continue
	}
	"\n" { exp_continue }
	"\[^\n\r *]*Session terminated" { return 0 }
	timeout { return 0 }
	eof { return 0 }
    }
    set in_proc 0
}

#
# For each router... (this is main loop) # source_password_file
$password_file set in_proc 0 foreach router [lrange $argv $i end] {
    set router [string tolower $router]
    send_user "$router\n"

    # Figure out prompt.
    set prompt ">> \[^\r\n]*\[#|>] "
    # alteon only "enables" based on the password used at login time
    set autoenable 1
    set enable 0

    # Figure out passwords
    if { $do_passwd } {
      set pswd [find password $router]
      if { [llength $pswd] == 0 } {
	send_user "Error - no password for $router in $password_file.\n"
	continue
      }
      set passwd [lindex $pswd 0]
    }

    # Figure out username
    if {[info exists username]} {
      # command line username
      set ruser $username
    } else {
      set ruser [find user $router]
      if { "$ruser" == "" } { set ruser $default_user }
    }

    # Figure out username's password (if different from the vty
password)
    if {[info exists userpasswd]} {
      # command line username
      set userpswd $userpasswd
    } else {
      set userpswd [find userpassword $router]
      if { "$userpswd" == "" } { set userpswd $passwd }
    }

    # Figure out prompts
    set u_prompt [find userprompt $router]
    if { "$u_prompt" == "" } { set u_prompt "(Username|login|  Login):"
}
    set p_prompt [find passprompt $router]
    if { "$p_prompt" == "" } { set p_prompt "\[Pp]assword:" }

    # Figure out cypher type
    if {[info exists cypher]} {
      # command line cypher type
      set cyphertype $cypher
    } else {
      set cyphertype [find cyphertype $router]
      if { "$cyphertype" == "" } { set cyphertype "3des" }
    }

    # Figure out connection method
    set cmethod [find method $router]
    if { "$cmethod" == "" } { set cmethod {{telnet} {ssh}} }

    # Login to the router
    if {[login $router $ruser $userpswd $passwd $prompt $cmethod
$cyphertype]} {
	continue
    }

    if { $do_command } {
	if {[run_commands $prompt $command]} {
	    continue
	}
    } elseif { $do_script } {
	send "lines 0\r"
	expect -re $prompt	{}
	source $sfile
	close
    } else {
	label $router
	log_user 1
	interact
    }

    # End of for each router
    wait
    sleep 0.3
}
exit 0






and arancid:


#!/usr/bin/perl
##
## Hacked version of rancid for Alteon WebOS switches ## tested with:
ad3 v8.1.18 ## afort at choqolat.org (andrew fort) ## ## ## Copyright (C)
1997-2001 by Henry Kilmer.
## All rights reserved.
##
## This software may be freely copied, modified and redistributed
without ## fee for non-commerical purposes provided that this copyright
notice is ## preserved intact on all copies and modified copies.
##
## There is no warranty or other guarantee of fitness of this software.
## It is provided solely "as is". The author(s) disclaim(s) all ##
responsibility and liability with respect to this software's usage ## or
its effect upon hardware, computer systems, other software, or ##
anything else.
##
##
#
#  RANCID - Really Awesome New Cisco confIg Differ
#           
# arancid - Alteon WebOS plugin for rancid # # usage: arancid [-d] [-l]
[-f filename | $host] # use Getopt::Std; getopts('dflm'); $log = $opt_l;
$debug = $opt_d; $file = $opt_f; $host = $ARGV[0]; $clean_run = 0;
$found_end = 0; $prompt = "#";
$timeo = 90;			# clogin timeout in seconds

# This routine is used to print out the router configuration sub
ProcessHistory {
    my($new_hist_tag,$new_command,$command_string, at string)=(@_);
    if((($new_hist_tag ne $hist_tag) || ($new_command ne $command))
       && defined %history) {
	print eval "$command \%history";
	undef %history;
    }
    if (($new_hist_tag) && ($new_command) && ($command_string)) {
	if ($history{$command_string}) {
	    $history{$command_string} =
"$history{$command_string}@string";
	} else {
	    $history{$command_string} = "@string";
	}
    } elsif (($new_hist_tag) && ($new_command)) {
	$history{++$#history} = "@string";
    } else {
	print "@string";
    }
    $hist_tag = $new_hist_tag;
    $command = $new_command;
    1;
}

sub numerically { $a <=> $b; }

# This is a sort routing that will sort numerically on the # keys of a
hash as if it were a normal array.
sub keynsort {
    local(%lines)=@_;
    local($i) = 0;
    local(@sorted_lines);
    foreach $key (sort numerically keys(%lines)) {
	$sorted_lines[$i] = $lines{$key};
	$i++;
    }
    @sorted_lines;
}

# This is a sort routing that will sort on the # keys of a hash as if it
were a normal array.
sub keysort {
    local(%lines)=@_;
    local($i) = 0;
    local(@sorted_lines);
    foreach $key (sort keys(%lines)) {
	$sorted_lines[$i] = $lines{$key};
	$i++;
    }
    @sorted_lines;
}

# This is a sort routing that will sort on the # values of a hash as if
it were a normal array.
sub valsort{
    local(%lines)=@_;
    local($i) = 0;
    local(@sorted_lines);
    foreach $key (sort values %lines) {
	$sorted_lines[$i] = $key;
	$i++;
    }
    @sorted_lines;
}

# This is a numerical sort routing (ascending).
sub numsort {
    local(%lines)=@_;
    local($i) = 0;
    local(@sorted_lines);
    foreach $num (sort {$a <=> $b} keys %lines) {
	$sorted_lines[$i] = $lines{$num};
	$i++;
    }
    @sorted_lines;
}

# This is a sort routine that will sort on the # ip address when the ip
address is anywhere in # the strings.
sub ipsort {
    local(%lines)=@_;
    local($i) = 0;
    local(@sorted_lines);
    foreach $addr (sort sortbyipaddr keys %lines) {
	$sorted_lines[$i] = $lines{$addr};
	$i++;
    }
    @sorted_lines;
}

# 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]));
}
sub sortbyipaddr {
    &ipaddrval($a) <=> &ipaddrval($b);
}

# This routine parses "/info/sys" (cf. show version) sub ShowVersion {
	print STDERR "    In ShowVersion: $_" if ($debug);

	while (<INPUT>)  {
	    tr/\015//d;
	    last if (/^>>.*$prompt/);
	    next if(/^(\s*|\s*$cmd\s*)$/);  
		
	/^(ACEdirector.*|ACEswitch.*|Alteon.*)/i && 
	  ProcessHistory("COMMENTS","keysort","A1", "\/\*Model: $1\n")
&& next;
	/^Software Version\s+(.*?)\s\((.*)\)/i &&
	  ProcessHistory("COMMENTS","keysort","B1", "\/\*Image:
Software: $1 ($2)\n") && next;
	/^Hardware Part No:\s+(.*?)\s+/i &&
	  ProcessHistory("COMMENTS","keysort","A2", "\/\*Hardware part
no: $1\n") && next;
	/^MAC
address:\s+([0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:
[0-9a-f]{2})/i &&
	  ProcessHistory("COMMENTS","keysort","C1", "\/\*Base MAC
address: $1\n") && next; 
	}
	return(0);
}

# This routine processes a "/cfg/dump"
sub WriteTerm {
    print STDERR "    In WriteTerm: $_" if ($debug);

    # eat the header line
    #$junk = <INPUT>;

    # now just copy it verbatim to the history file
    $is_bwm = 0;
    while (<INPUT>) {
        tr/\015//d;
        last if(/^>>.*$prompt/);
	chop;
	if (/(rcomm|wcomm|t1com|t2com)(\s+)(.*)/ && 
		defined($ENV{'NOCOMMSTR'})) {
	    ProcessHistory("","","","\/\*\t$1$2\"<removed>\"\n") &&
next;
	}
	
	if (/^\/c\/bwm\/cont (\d+)/) {
	    $cur_bwm_item = $1;
	    $is_bwm = 1;
	} elsif (/^\/c\/bwm\/pol (\d+)/) {
	    $cur_bwm_item = $1;
	    $is_bwm = 2;
	} elsif (/^\/c/ || /^\s*resv/) {
	    if ($is_bwm == 2) {
		if (!$got_hard{$cur_bwm_item}) {
		    ProcessHistory("","","","\/\*\thard <dynamic>\n");
		}
		if (!$got_soft{$cur_bwm_item}) {
		    ProcessHistory("","","","\/\*\tsoft <dynamic>\n");
		}
	    }
	    $is_bwm = 0;
	}
	
	if (/name \"DYN/ && ($is_bwm == 1)) {
	    $is_dyn{$cur_bwm_item} = 1;
	} elsif (/^(\s*(hard|soft) )/ && ($is_bwm == 2) && exists
$is_dyn{$cur_bwm_item}) {
	    $limit_type = $2;
	    $limit_line = $1;
	    if ($limit_type eq 'hard') {
		$got_hard{$cur_bwm_item} = 1;
	    } elsif ($limit_type eq 'soft') {
		if (!$got_hard{$cur_bwm_item}) {
		    ProcessHistory("","","","\/\*\thard <dynamic>\n");
		}
		$got_soft{$cur_bwm_item} = 1;
	    }
	    ProcessHistory("","","","\/\*${limit_line}<dynamic>\n") &&
next;
	}
	
	/^(\s+.{2,3}pw )\S+/ &&
	    ProcessHistory("","","","\/\*$1<removed>\n") && next;
	/^(\/cfg\/sys\/sshd\/scpadm\s+)(.*)/ &&
	    ProcessHistory("","","","\/\*$1<removed>\n") && next;
	next if (/^\/\* Configuration dump taken/i);
	next if (/^\/\* Version.*Base MAC.*/i);

		if (/^\/?script end/) { 
		$found_end = 1; 
		ProcessHistory("","","","$_\n");
		return(1);
		}

	ProcessHistory("","","","$_\n");
    }
    return(0);
}

# dummy function
sub DoNothing {print STDOUT;}

# Main
%commands=(
	'/info/sys'		=> "ShowVersion",
	'/cfg/dump'		=> "WriteTerm",
);
# keys() doesnt return things in the order entered and the order of the
# cmds is important (show version first and write term last). pita
@commands=(
	"/info/sys",
	"/cfg/dump",
);
$cisco_cmds=join(";", at commands);
$cmds_regexp=join("|", at commands);

open(OUTPUT,">$host.new") || die "Can't open $host.new for writing:
$!\n"; select(OUTPUT); # make OUTPUT unbuffered if debugging if ($debug)
{ $| = 1; }

if ($file) {
    print STDERR "opening file $host\n" if ($debug);
    print STDOUT "opening file $host\n" if ($log);
    open(INPUT,"<$host") || die "open failed for $host: $!\n"; } else {
    print STDERR "executing alogin -t $timeo -c\"$cisco_cmds\" $host\n"
if ($debug);
    print STDOUT "executing alogin -t $timeo -c\"$cisco_cmds\" $host\n"
if ($log);
    if (defined($ENV{NOPIPE})) {
	system "alogin -t $timeo -c \"$cisco_cmds\" $host </dev/null >
$host.raw 2>&1" || die "alogin failed for $host: $!\n";
	open(INPUT, "< $host.raw") || die "alogin failed for $host:
$!\n";
    } else {
	open(INPUT,"alogin -t $timeo -c \"$cisco_cmds\" $host </dev/null
|") || die "alogin failed for $host: $!\n";
    }
}

ProcessHistory("","","","\/\*RANCID-CONTENT-TYPE: alteon\n\/\*\n");
ProcessHistory("COMMENTS","keysort","B0","\/\*\n");
ProcessHistory("COMMENTS","keysort","F0","\/\*\n");
TOP: while(<INPUT>) {
    tr/\015//d;
    if (/^>>.*$prompt exit/) {
      $clean_run=1;
      last;
    }

    while (/>>.*$prompt\s*($cmds_regexp)\s*$/) {
        $cmd = $1;
        if (!defined($prompt)) {$prompt = ($_ =~ /^([^#]+#)/)[0]; }
	print STDERR ("HIT COMMAND:$_") if ($debug);
	if (!defined($commands{$cmd})) {
	    print STDERR "$host: found unexpected command - \"$cmd\"\n";
	    $clean_run = 0;
            last TOP;
	}
	$rval = &{$commands{$cmd}};
	delete($commands{$cmd});
	if ($rval == -1) {
	    $clean_run = 0;
	    last TOP;
	}
    }
}
print STDOUT "Done $logincmd: $_\n" if ($log); # Flush History
ProcessHistory("","","",""); # Cleanup close(INPUT); close(OUTPUT);

if (defined($ENV{NOPIPE})) {
    unlink("$host.raw") if (! $debug);
}

# check for completeness
if (scalar(%commands) || !$clean_run || !$found_end) {
    if (scalar(%commands)) {
	printf(STDOUT "$host: missed cmd(s): %s\n", join(',',
keys(%commands)));
	printf(STDERR "$host: missed cmd(s): %s\n", join(',',
keys(%commands))) if ($debug);
    }
    if (!$clean_run || !$found_end) {
	print STDOUT "$host: End of run not found\n";
	print STDERR "$host: End of run not found\n" if ($debug);
	system("/usr/bin/tail -1 $host.new");
    }
    unlink "$host.new" if (! $debug);
}
Classification:  UNCLASSIFIED 
Caveats: NONE



More information about the Rancid-discuss mailing list