-
Notifications
You must be signed in to change notification settings - Fork 44
/
Copy pathrancid.in
150 lines (137 loc) · 4.23 KB
/
rancid.in
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
#! @PERLV_PATH@
##
## @PACKAGE@ @VERSION@
@copyright@
#
# RANCID - Really Awesome New Cisco confIg Differ
#
# rancid - generalized rancid module; command schedule is derived from the
# rancid.types.{base,conf} configurations.
#
# usage: rancid [-dhltCV] -t device_type [-f filename | hostname]
#
use 5.010;
use strict 'vars';
use warnings;
no warnings 'uninitialized';
use Exporter;
use Getopt::Std;
our($opt_d, $opt_f, $opt_h, $opt_l, $opt_t, $opt_C, $opt_V);
getopts('dfhlt:CV');
BEGIN {
push(@INC, "@pkglibdir@");
}
use rancid;
our @ISA = qw(Exporter rancid);
sub usage()
{
print STDERR "rancid [-dhlCV] -t device_type [-f filename | hostname]\n";
exit 64;
}
if ($opt_h) {
usage();
}
# basic initialization
rancidinit();
# load device type spec, build @commandtable and load modules
if (loadtype($devtype)) {
die "Couldn't load device type spec for $rancid::devtype\n";
}
if (! defined($script)) {
die "script not defined for device type $rancid::devtype\n";
}
if (! defined($lscript)) {
die "login script not defined for device type $rancid::devtype\n";
}
# if the first word of $script is not us (this script), exec the given
# script.
my(@script) = split(/\s+/, $script);
if (which($script[0]) ne which($0)) {
# -[hCV] are not handled; they will have already been handled earlier.
push(@script, "-d") if $opt_d;
push(@script, "-l") if $opt_l;
push(@script, "-f") if $opt_f;
push(@script, $host);
if ($debug) {
print(STDERR "device script ($script[0]) does not appear to be me ($0)".
": exec(". join(" ", @script) .")\n");
}
# there is no way to prevent an error msg from exec such that the die error
# is the only one displayed, without also leaving the child without a
# working STDERR.
exec(join(" ", @script)) || die "exec($script[0]) failed: $!\n";
}
# check that inloop, the input/main loop, is defined
if (!defined($inloop) || length($inloop) < 1) {
die "inloop is not configured for device type $devtype";
}
# open the temporary file for the digested output
open(OUTPUT,">$host.new") || die "Can't open $host.new for writing: $!\n";
select(OUTPUT);
if (length($#modules)) {
my($module);
foreach $module (@modules) {
(my $file = $module) =~ s/::/\//g;
my($err) = 0;
# call module->init(); we expect 0 as success, as god intended it
eval "\$err = ". $module ."::init();";
if ($@) {
printf(STDERR "loadtype: initializing $module failed: %s\n", $@);
exit 1;
} elsif ($err) {
printf(STDERR "loadtype: %s::init() returned failure\n", $module);
exit 1;
}
}
}
# open the input; a pre-collected file or start a login for a login stream or
# temporary file
if ($file) {
print(STDERR "opening file $host\n") if ($debug || $log);
open(INPUT,"<$host") || die "open failed for $host: $!\n";
} else {
my $cstr = $commandstr;
$cstr =~ s/\"/\\\"/g;
print(STDERR "executing $lscript -t $timeo -c\"$cstr\" $host\n") if ($debug || $log);
system "$lscript -t $timeo -c \"$cstr\" $host </dev/null > $host.raw 2>&1" || die "clogin failed for $host: $!\n";
open(INPUT, "< $host.raw") || die "clogin failed for $host: $!\n";
}
# loop over the input using the provided input/main loop
eval($inloop ."(*INPUT, *OUTPUT);") && die "${inloop} failed: $@\n";
print STDOUT "Done $lscript: $_\n" if ($log);
# Flush History
ProcessHistory("","","","");
# Cleanup
close(INPUT);
close(OUTPUT);
unlink("$host.raw") if (! $debug);
# check for completeness
if (scalar(%commands) || !$clean_run || !$found_end) {
if (scalar(keys %commands) eq $commandcnt) {
printf(STDERR "$host: missed cmd(s): all commands\n");
} elsif (scalar(%commands)) {
my($count, $i) = 0;
for ($i = 0; $i < $#commands; $i++) {
if ($commands{$commands[$i]}) {
if (!$count) {
printf(STDERR "$host: missed cmd(s): %s", $commands[$i]);
} else {
printf(STDERR ", %s", $commands[$i]);
}
$count++;
}
}
if ($count) {
printf(STDERR "\n");
}
}
if (!$clean_run || !$found_end) {
print(STDERR "$host: End of run not found\n");
if ($debug) {
print(STDERR "$host: clean_run is false\n") if (!$clean_run);
print(STDERR "$host: found_end is false\n") if (!$found_end);
}
system("/usr/bin/tail -1 $host.new");
}
unlink "$host.new" if (! $debug);
}