rancid-2.3.8/README100644 015615 000000 00000030702 11342156272 0007343Rancid is a "Really Awesome New Cisco confIg Differ" developed to maintain CVS controlled copies of router configs. *** The Following Information is Very Important **** Rancid 2.3 introduces a new directory layout. It has been changed to more closely follow the standard path hierarchy, which is defined by the FHS standard and autoconf, and/or make these locations more easily configurable within rancid. The obvious advantage of this is making rancid more easily packagable; i.e.: NetBSD pkgsrc, FreeBSD port, Linux RPM, etc. Please please please please read the UPGRADING file for more information. ********** The following is the packing list for Rancid, excluding files supporting configure (autoconf) and make. .in is stripped from the files below by configure as substitutions are completed: README This file. README.lg Information about the Looking Glass. BUGS Bug list. CHANGES List of changes to Rancid. COPYING RANCID license. FAQ Frequently Asked Questions Todo Partial list of what needs to be done. UPGRADING Notes on upgrading rancid to a new version. cloginrc.sample TCL commands to set passwords, usernames etc. used by clogin and jlogin. See cloginrc(5) etc/ lg.conf.sample Sample Looking Glass configuration rancid.conf.sample Sample RANCID configuration bin/ clogin.in Expect script that logs into routers and either presents an interactive shell, runs a set of commands, or runs another expect script. It handles Cisco, Extreme, Force10, Juniper E-series, Procket, Redback, Zebra/MRT. control_rancid.in Builds router list, calls rancid on each router and handles cvs routines. hpuifilter.c HP procurve login filter - see hlogin(1). par.in Parallel processing of commands - any commands. rancid-cvs.in Creates all of the CVS and config directories. rancid-run.in Script designed to be run from cron. rancid-fe.in Chooses between rancid/[abefhjrx]rancid/cat5rancid. rancid.in Runs commands on cisco routers and processes the output. agmrancid.in Version of rancid.in for Cisco Anomaly Guard Module (AGM) arancid.in Version of rancid.in for Alteon switches. brancid.in Version of rancid.in for baynet/nortel routers. cat5rancid.in Version of rancid.in for Cisco Catalyst switches. cssrancid.in Version of rancid.in for Cisco CSS switches. erancid.in Version of rancid.in for ADC EZ-T3 muxes. f10rancid.in Version of rancid.in for Force10 routers. f5rancid.in Version of rancid.in for F5 BigIPs. fnrancid.in Version of rancid.in for Fortinet Firewalls. francid.in Version of rancid.in for Foundry switches. hrancid.in Version of rancid.in for HP Procurve switches. htrancid.in Version of rancid.in for Hitatchi routers. jerancid.in Version of rancid.in for Juniper E-series routers. jrancid.in Version of rancid.in for Juniper routers. mrancid.in Version of rancid.in for MRT daemons. nrancid.in Version of rancid.in for Netscreen firewalls. nsrancid.in Version of rancid.in for Netscalars. prancid.in Version of rancid.in for Procket routers. rivancid.in Version of rancid.in for Riverstone routers. rrancid.in Version of rancid.in for Redback routers. srancid.in Version of rancid.in for SMC switches. tntrancid.in Version of rancid.in for TNT access servers. xrancid.in Version of rancid.in for Extreme switches. zrancid.in Version of rancid.in for Zebra routers. alogin.in Version of clogin.in for Alteon switches. blogin.in Version of clogin.in for baynet/Nortel routers. elogin.in Version of clogin.in for ADC EZ-T3 muxes. flogin.in Version of clogin.in for Foundry switches. If foundry cleaned-up their bloody UI, clogin should do the job. hlogin.in Version of clogin.in for HP procurve switches. htlogin.in Version of clogin.in for Hitatchi routers. jlogin.in Version of clogin.in for Juniper routers. nlogin.in Version of clogin.in for Netscreen firewalls. nslogin.in Version of clogin.in for Netscalars. rivlogin.in Version of clogin.in for Riverstone routers. tntlogin.in Version of clogin.in for TNT access servers. man/ man pages share/ Readmes, samples, utilities, contribs, etc include/ Include files and rancid version.h Also see rancid_intro(1), rancid(1), and clogin(1). The following (non-exhaustive list) are included as part of the installation and configuration tools: Makefile.am processed by automake to produce Makefile.in Makefile.in processed by configure to produce Makefile acinclude.m4 sets some GNU autoconf options aclocal.m4 Output of GNU autoconf script configure GNU autoconf script configure.in Input file for autoconf to procide configure depcomp part of GNU autoconf install-sh GNU autoconf shell script to simulate BSD style install missing part of GNU autoconf mkinstalldirs GNU autoconf shell script to make installation directories rancid will also need to have the following packages: cvs Code revision system available from prep.ai.mit.edu:/pub/gnu gnudiff gnudiff provides the uni-diff (-u) option. If you do not have a diff that supports -u, configure will set-up rancid to use 'diff -c' or 'diff -C'. perl5 perl version 5 or greater available from www.cpan.org expect http://expect.nist.gov/ We highly suggest that you stick to expect 5.24.1 (or so). This seems to work best. Note that you need to have the accompanying tcl &/ tk. svn Code revision system, an alternative to cvs. Available from http://subversion.tigris.org/tarballs/. Use the configure option --with-svn to configure for Subversion. tcl Required by expect. Bill Fenner (now maintained by others) has a cgi script for interacting with CVS repositories via a web interface. This provides a great way to view rancid diffs and full configs, especially for those unfamiliar with cvs. The package is not included, but can be found here: http://www.freebsd.org/projects/cvsweb.html Quick Installation Guide (an example): 1) ./configure [--prefix=] By default, rancid will be installed under /usr/local/rancid (the default "prefix"). This can be overridden with the --prefix option. E.g.: ./configure --prefix=/home/rancid Rancid uses autoconf's "localstatedir" as the location of it's logs, CVS or Subversion respository, and directories where it's groups are placed. The user who will run rancid (from cron, etc) will need write access to these directories. By default, this is /var, or /home/rancid/var following the example above. We realize that this is not optimal, but it follows the standards. We suggest that this be altered to include the package name, like so: ./configure --prefix=/home/rancid \ --localstatedir=/home/rancid/var/rancid The user who will run rancid must have write permission in "localstatedir". See ./configure --help for other configure options. 2) make install 3) Modify /rancid.conf (e.g.: /etc/rancid.conf). The variable LIST_OF_GROUPS is a space delimited list of router "groups". E.g.: LIST_OF_GROUPS="backbone aggregation switches" 4) Put .cloginrc in the home directory of the user who will run rancid. .cloginrc must be not be readable/writable/executable by "others", i.e.: .cloginrc must be mode 0600 or 0640. 5) Modify .cloginrc. Test to make sure that you can log into every router. Note: the juniper user you use *must* log into a cli shell (which is the default on a juniper). See the file cloginrc.sample, located in (/share/rancid), for examples and good starting point. Also take a look at the cloginrc manual page, 'man -M /man cloginrc'. 6) Modify /etc/aliases Rancid sends the diffs and other administrative emails to rancid- and problems to rancid-admin-, where is the "GROUP" of routers. This way you can separate your backbone routers from your access routers or separate based upon network etc... Different router uses forced different people being interested in router "groups" - thus this setup. Make sure email to rancid- works. /etc/aliases can be maintainable by Majordomo stuff, but make sure the user that runs rancid can post to the list. The Precedence header set to bulk or junk *hopefully* avoids replies from auto-responders and vacation type mail filters. The --enable-mail-plus option to configure will set each of the "rancid-" addresses mentioned above to "rancid+". See sendmail's operation manual for more information on handling of '+'. The --enable-adminmail-plus configure option will set each of the "rancid-admin-" addresses mentioned above to "rancid-admin+". If this option is not used, the value of --enable-mail-plus is assumed. That is, the addresses will be "rancid+", if it is specified. 7) Run rancid-cvs. This creates all of the necessary directories and config files for each of the groups in LIST_OF_GROUPS and imports them into CVS (or Subversion). This will also be run each time a new group is added. Do not create the directories or CVS repository manually, allow rancid-cvs do it. Also see 'man -M /man rancid-cvs'. 8) For each "group", modify the router.db file in the group directory. The file is of the form "router:mfg:state" where "router" is the name (we use FQDN) of the router, mfg is the manufacturer from the set of (cat5|cisco|juniper) (see router.db.5 for a complete list and description), and "state" is either up or down. Each router listed as "up" will have the configuration grabbed. Note: manufacturer cat5 is intended only for cisco catalyst switches running catalyst (not IOS) code. e.g.: //router.db: cisco-router.domain.com:cisco:up adc-mux.domain.com:ezt3:up foundry-switch-router.domain.com:foundry:up juniper-router.domain.com:juniper:up redback-dsl-router.domain.com:redback:down extreme-switch.domain.com:extreme:down 9) For first-time users or new installations, run bin/rancid-run (with no arguments) and check the resulting log file(s) (in logs/*) for errors. Repeat until there are no errors. 10) Put rancid-run in cron to be called however often you want it to run for each group (rancid-run []). If you run it less often than once/hour, check the setting of OLDTIME in etc/rancid.conf. E.g.: # run config differ hourly 1 * * * * /bin/rancid-run # clean out config differ logs 50 23 * * * /usr/bin/find /logs -type f -mtime +2 -exec rm {} \; 11) Note: If you are using any of these programs (other than rancid-run) out of cron, make sure that you set your $PATH correctly so that they work. E.g.: if you are using clogin, it can call id, telnet, ssh, and/or rsh. configure already makes sure that $PATH is set correctly in etc/rancid.conf for rancid-run, so you could use the $PATH from there. e.g.: 50 23 * * * . /rancid.conf; clogin -c 'sh vers' router 12) Send any bugs, suggestions or updates to rancid@shrubbery.net. See the web page at http://www.shrubbery.net/rancid. We have created the standard mailing lists for those interested; rancid-announce@shrubbery.net and rancid-discuss@shrubbery.net. Subscribe by sending an email whose body contains "subscribe rancid-" to majordomo@shrubbery.net. If you are reporting problems, please include the version of rancid, expect, and your OS in the email. Problem with clogin/telnet hanging within rancid or scripts? If you have experienced rancid (or more precisely, telnet) hanging on a solaris 2.6 box; check to be sure you have the following two o/s patches installed (see showrev -p). There may be more recent versions of these patches and they are likely included with 2.7 and 2.8: Patch-ID# 105529-08 Keywords: security tcp rlogin TCP ACK FIN packet listen Synopsis: SunOS 5.6: /kernel/drv/tcp patch Patch-ID# 105786-11 Keywords: security ip tcp_priv_stream routing ip_enable_group_ifs ndd Synopsis: SunOS 5.6: /kernel/drv/ip patch Another contributor to rancid "hanging", with or without the o/s patches mentioned above, is a bug in expect/tcl. We've noticed that expect (from 5.24.1 forward), and whatever tcl happens to compile with it, exhibits a problem on Linux and Solaris where rancid's scripts hang waiting for input from the device. Patches to expect are available on the rancid web page. Also, for rancid 2.3 and later, changes were made to the login scripts which use some more elaborate regexes that have failed with expect versions prior to 5.40. While 5.40 works, it still seems to need the patch offered on the rancid web page for Linux and Solaris. See www.shrubbery.net/rancid for additional notes on this. rancid-2.3.8/acinclude.m4100644 015615 000000 00000000051 11342156272 0010646AUTOMAKE_OPTIONS=no-dependencies foreign rancid-2.3.8/configure.in100644 015615 000000 00000033417 11661273443 0011006dnl Process this file with autoconf to produce a configure script. AC_PREREQ(2.13) AC_INIT(CHANGES) dnl VERSION needs to be updated such that 'make dist' uses the correct dnl filename for the directory name and tarball. VERSION=`sed -n 's/.*version.*"\(.*\)".*/\1/p' $srcdir/include/version.h.in|tr -d ' '` PACKAGE=`sed -n 's/.*package.*"\(.*\)".*/\1/p' $srcdir/include/version.h.in|tr -d ' '` AC_SUBST(VERSION) AC_SUBST(PACKAGE) COPYYEARS="1997-2011" AC_SUBST(COPYYEARS) AM_INIT_AUTOMAKE($PACKAGE, $VERSION, rancid@shrubbery.net) dnl default install location AC_PREFIX_DEFAULT(/usr/local/rancid) dnl AM_MAINTAINER_MODE() dnl AC_CONFIG_SUBDIRS(util) # make sure MAKE sets ${MAKE} AC_PATH_PROG(MAKE,gmake,no) if test $MAKE = no; then unset ac_cv_path_MAKE AC_PATH_PROG(MAKE,make,no) if test $MAKE = no; then AC_MSG_ERROR([can't locate a make.]) exit 1 fi fi AC_PROG_MAKE_SET() # compiler specifics AC_PROG_CC AM_C_PROTOTYPES AC_PROG_CPP AC_C_CONST AC_C_INLINE AC_C_STRINGIZE # check includes/headers AC_HEADER_STDC AC_CHECK_HEADERS(ctype.h errno.h fcntl.h limits.h pty.h malloc.h memory.h \ siginfo.h string.h strings.h stropts.h sys/types.h \ sys/wait.h unistd.h util.h) AC_CHECK_HEADERS(sysexits.h) # check functions AC_CHECK_FUNCS(memcpy memmove memset strerror strchr \ strrchr strstr strtok strrtok index rindex unsetenv) AC_CHECK_FUNCS(openpty, openpty=1, openpty=0) # openpty() is not in the default libraries. See if it is in some other lib. if test $openpty = 0; then for lib in util; do AC_CHECK_LIB($lib, openpty, [AC_DEFINE(HAVE_OPENPTY) LIBS="$LIBS -l$lib"; openpty=1; break]) done fi # If we dont have openpty, then look for /dev/ptmx for use by our own # openpty(). if test $openpty = 0; then # This check (partially) comes from expect's configure AC_MSG_CHECKING([for SVR4 style pty allocation]) AH_TEMPLATE(HAVE_PTMX, "define this if your o/s has /dev/ptmx") if test -r /dev/ptmx ; then AC_MSG_RESULT(yes) AC_DEFINE(HAVE_PTMX) # Some systems need libpt.a to use /dev/ptmx AC_CHECK_FUNCS(ptsname) if test $ac_cv_func_ptsname+set != set; then # ptsname is not in the default libraries. for lib in pt; do AC_CHECK_LIB($lib, ptsname, [LIBS="$LIBS -l$lib"; break]) done fi else AC_MSG_RESULT(no) fi # In OSF/1 case, SVR4 are somewhat different. # Gregory Depp 17Aug93 AC_MSG_CHECKING([for OSF/1 style pty allocation]) AH_TEMPLATE(HAVE_PTMX_OSF, "define this for OSF/1 ptmx") if test -r /dev/ptmx_bsd ; then AC_DEFINE(HAVE_PTMX_OSF) AC_MSG_RESULT(yes) else AC_MSG_RESULT(no) fi fi dnl AC_FUNC_VPRINTF # type checks AC_TYPE_SIGNAL AC_TYPE_SIZE_T # Package-specific options/knobs # # Check if user wants us to create LOCALSTATEDIR. If it's a package-system, # they might create it themselves for book-keeping sake; eg: NetBSD AC_MSG_CHECKING([whether to create the local state directory at install time]) AC_ARG_ENABLE(mk-localstatedir, AS_HELP_STRING([--enable-mk-localstatedir], [enable creation of the local state directory at install time (default: yes)]), [if test "$enable_mk_localstatedir" = yes; then AC_MSG_RESULT(yes) else AC_MSG_RESULT(no) fi], [AC_MSG_RESULT(yes) enable_mk_localstatedir="yes" ]) AM_CONDITIONAL([MK_LCLSTATEDIR], [test "${enable_mk_localstatedir}" = yes]) # Check if user wants us to install sample configurations into the sysconfdir. AC_MSG_CHECKING([whether to install sample .conf files in sysconfdir]) AC_ARG_ENABLE(conf-install, AS_HELP_STRING([--enable-conf-install], [enable install of sample .conf files in sysconfdir (default: yes)]), [if test "$enable_conf_install" = yes; then AC_MSG_RESULT(yes) else AC_MSG_RESULT(no) fi], [AC_MSG_RESULT(yes) enable_conf_install="yes" ]) AM_CONDITIONAL([CONF_INSTALL], [test "${enable_conf_install}" = yes]) # Configure for subversion revision control system instead of CVS. SVN_FSTYPE="--fs-type fsfs" AC_MSG_CHECKING([whether subversion]) AC_ARG_WITH(svn, AS_HELP_STRING([--with-svn=fstype], [use subversion instead of cvs, with optional svn fstype (fsfs|bdb)]), [ case "$withval" in yes) AC_MSG_RESULT(yes) RCSSYS="svn" ;; fsfs) AC_MSG_RESULT([yes fstype fsfs]) RCSSYS="svn" SVN_FSTYPE="--fs-type fsfs" ;; bdb) AC_MSG_RESULT([yes fstype bdb]) RCSSYS="svn" SVN_FSTYPE="--fs-type bdb" ;; no) AC_MSG_RESULT(no) RCSSYS="cvs" ;; *) AC_MSG_ERROR([unknown svn fs-type $withval]) esac ], [AC_MSG_RESULT(no) RCSSYS="cvs" ]) AC_SUBST(RCSSYS) AC_SUBST(SVN_FSTYPE) rd_cv_RCSSYS=$RCSSYS # Check for a preference for using mail addresses like rancid+group # instead of the standard rancid-group AC_MSG_CHECKING([whether mail addresses should be in the rancid+ form]) AC_ARG_ENABLE(mail-plus, AS_HELP_STRING([--enable-mail-plus], [enable mail to rancid+ addresses, instead of rancid-]), [if test "$enable_mail_plus" = yes; then AC_MSG_RESULT(yes) MAILPLUS="rancid+" AC_SUBST(MAILPLUS) else AC_MSG_RESULT(no) MAILPLUS="rancid-" AC_SUBST(MAILPLUS) fi], [AC_MSG_RESULT(no) MAILPLUS="rancid-" AC_SUBST(MAILPLUS) ]) rd_cv_MAILPLUS=$MAILPLUS # Check for a preference for using mail addresses like rancid+admin-group # instead of the standard rancid-admin-group AC_MSG_CHECKING([whether admin mail addresses should be in the rancid-admin+ form]) AC_ARG_ENABLE(adminmail-plus, AS_HELP_STRING([--enable-adminmail-plus], [enable mail to rancid-admin+ addresses, instead of rancid-admin-]), [if test "$enable_adminmail_plus" = yes; then AC_MSG_RESULT([rancid-admin+]) ADMINMAILPLUS="rancid-admin+" AC_SUBST(ADMINMAILPLUS) else AC_MSG_RESULT([${MAILPLUS}admin-]) ADMINMAILPLUS="${MAILPLUS}admin-" AC_SUBST(ADMINMAILPLUS) fi], [AC_MSG_RESULT([${MAILPLUS}admin-]) ADMINMAILPLUS="${MAILPLUS}admin-" AC_SUBST(ADMINMAILPLUS) ]) rd_cv_ADMINMAILPLUS=$ADMINMAILPLUS AC_PATH_PROG(DIRNAME,dirname,no) # locate GNU diff (one supporting the -u option) AC_MSG_CHECKING([for a diff(1) that supports -u]) _DIFF_PATH=`echo $PATH:${prefix}/bin:/usr/bin:/usr/pkg/bin:/usr/local/bin:/usr/gnu/bin:/usr/contrib/bin | sed -e 's/:/ /g'` for _diff in ${_DIFF_PATH} ; do if test -e ${_diff}/diff ; then ${_diff}/diff -u -4 /dev/null /dev/null > /dev/null 2>&1 if test $? -ne 0; then # linux/gnu shit has to change options that have been around # since organized religion; see if -U 4 works. ${_diff}/diff -U 4 /dev/null /dev/null > /dev/null 2>&1 if test $? -ne 0; then if test "${ADIFF}" = "" ; then ADIFF="${_diff}/diff" ADIFF_CMD="diff -c -4" fi else DIFF="${_diff}/diff" DIFF_CMD="diff -U 4" break fi else DIFF="${_diff}/diff" DIFF_CMD="diff -u -4" break fi fi done if test "$DIFF" = "" ; then DIFF=$ADIFF DIFF_CMD=$ADIFF_CMD fi if test "$DIFF" = "" ; then AC_MSG_ERROR([can't locate diff.]) fi AC_MSG_RESULT([${DIFF_CMD}]) rd_cv_DIFF=$DIFF AC_SUBST(DIFF) rd_cv_DIFF_CMD=$DIFF_CMD AC_SUBST(DIFF_CMD) AC_PATH_PROG(SENDMAIL,sendmail,no, /usr/sbin:/usr/bin:/usr/lib) # Find an appropriate tar for use in "dist" targets. A "best guess" # is good enough -- if we can't find GNU tar, we don't really care. AC_CHECK_PROGS(TAR, gnutar gtar tar) AC_CHECK_PROGS(AUTOMAKE, automake) dnl locate perl 5 and expect. AC_PROG_INSTALL AC_PATH_PROG(PERLV_PATH,perl5,no) if test $PERLV_PATH = no; then unset ac_cv_path_PERLV_PATH AC_PATH_PROG(PERLV_PATH,perl,no) if test $PERLV_PATH = no; then AC_MSG_ERROR([can't locate a suitable perl5.]) exit 1 else $PERLV_PATH -e 'require 5;' if test $? -ne 0 ; then AC_MSG_ERROR([can't locate a suitable perl5.]) exit 1 fi fi fi AC_SUBST(PERLV_PATH) PERLV=`basename $PERLV_PATH` AC_SUBST(PERLV) AC_PATH_PROG(EXPECT_PATH,expect,no) if test $EXPECT_PATH = no; then AC_MSG_ERROR([can't locate expect.]) fi AC_SUBST(EXPECT_PATH) # locate ping and it's syntax AC_PATH_PROG(PING_PATH,[ping],[no], [$PATH$PATH_SEPARATOR/sbin$PATH_SEPARATOR/usr/sbin]) if test $PING_PATH = no; then AC_MSG_ERROR([can't locate ping.]) exit 1 fi # ping seems to take one of two formats for count (N) # BSD: ping -c N host # SVR: ping host N $PING_PATH -c 1 -v 127.0.0.1 > /dev/null 2>&1 if test $? -eq 0 ; then LG_PING_CMD="$PING_PATH -c 1" else $PING_PATH 127.0.0.1 56 1 > /dev/null 2>&1 if test $? -eq 0 ; then LG_PING_CMD="$PING_PATH" else # cygwin using windows ping? $PING_PATH -n 1 127.0.0.1 > /dev/null 2>&1 if test $? -eq 0 ; then LG_PING_CMD="$PING_PATH -n 1" else AC_MSG_ERROR([can't figure out how to pass count == 1 to $PING_PATH.]) exit 1 fi fi fi AC_SUBST(LG_PING_CMD) rd_cv_lg_ping_cmd=$LG_PING_CMD # locate tools to build $PATH for rancid.conf. order is significant. want # to be sure that we pick up the the proper diff and ucbmail in # etc/rancid.conf. ENV_PATH="`dirname $PERLV_PATH`:`dirname $EXPECT_PATH`:`dirname $SENDMAIL`" ENV_PATH="$ENV_PATH:`dirname $DIRNAME`:`dirname $DIFF`" if test $RCSSYS = "cvs" ; then AC_PATH_PROG(CVS,cvs,no) ENV_PATH="$ENV_PATH:`dirname $ac_cv_path_CVS`" else AC_PATH_PROG(SVN,svn,no) ENV_PATH="$ENV_PATH:`dirname $ac_cv_path_SVN`" fi AC_PATH_PROG(COMM,comm,no) ENV_PATH="$ENV_PATH:`dirname $ac_cv_path_COMM`" AC_PATH_PROG(FIND,find,no) ENV_PATH="$ENV_PATH:`dirname $ac_cv_path_FIND`" AC_PATH_PROG(GREP,grep,no) ENV_PATH="$ENV_PATH:`dirname $ac_cv_path_GREP`" AC_PATH_PROG(ID,id,no) ENV_PATH="$ENV_PATH:`dirname $ac_cv_path_ID`" AC_PATH_PROG(MKDIR,mkdir,no) ENV_PATH="$ENV_PATH:`dirname $ac_cv_path_MKDIR`" AC_PATH_PROG(RSH,rsh,no) ENV_PATH="$ENV_PATH:`dirname $ac_cv_path_RSH`" AC_PATH_PROG(SORT,sort,no) ENV_PATH="$ENV_PATH:`dirname $ac_cv_path_SORT`" AC_PATH_PROG(SSH,ssh,no) ENV_PATH="$ENV_PATH:`dirname $ac_cv_path_SSH`" AC_PATH_PROG(TELNET,telnet,no) ENV_PATH="$ENV_PATH:`dirname $ac_cv_path_TELNET`" AC_PATH_PROG(TOUCH,touch,no) ENV_PATH="$ENV_PATH:`dirname $ac_cv_path_TOUCH`" ENV_PATH="$ENV_PATH:/usr/local/bin:/usr/bin" AC_SUBST(ENV_PATH) ENV_PATH=`echo $ENV_PATH | $PERLV_PATH -e 'foreach $x(split(":",<>)){next unless (length($x));push(@F, $x),$seen{$x}=1 unless (defined $seen{$x});}print join(":",@F);'` ac_cv_env_path=$ENV_PATH AC_SUBST(ENV_PATH) AC_CONFIG_FILES(Makefile) AC_CONFIG_FILES(bin/Makefile) AC_CONFIG_FILES(etc/Makefile) AC_CONFIG_FILES(include/Makefile) AC_CONFIG_FILES(man/Makefile) AC_CONFIG_FILES(share/Makefile) AC_CONFIG_FILES(include/version.h) # this is not a header in the sense of # AC_CONFIG_HEADERS will cause # autoheader to overwrite it, while all # want is simple variable replacement # autoheader bits AH_TOP([ #ifndef CONFIG_H #define CONFIG_H 1 ]) AH_BOTTOM([ /* damned linux... */ #ifdef LINUX # define _GNU_SOURCE #endif #ifndef __P # if STDC_HEADERS # define __P(a) a # else # define __P(a) () # endif #endif #if HAVE_STDLIB_H # include #endif #if HAVE_UNISTD_H # include # include #elif HAVE_SYS_TYPES_H # include #endif #if HAVE_ERRNO_H # include #endif extern int errno; #if HAVE_STRING_H # include #endif #if HAVE_STRINGS_H # include #endif #if ! HAVE_STRERROR # define strerror(n) sys_errlist[n]; #endif #if HAVE_SYS_WAIT_H # include #endif #ifndef WEXITSTATUS # define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8) #endif #ifndef WIFEXITED # define WIFEXITED(stat_val) (((stat_val) & 255) == 0) #endif #if HAVE_MEMSET # define bzero(p,s) memset(p, 0, s) # define bcopy(s,d,l) memcpy(d, s, l) #endif #if HAVE_INDEX && ! HAVE_STRCHR # define index(s,c) strchr(s,c) #endif #if HAVE_SYSEXITS_H # include #else /* missing sysexits.h */ # define EX_OK 0 # define EX_USAGE 64 /* command line usage error */ # define EX_NOINPUT 66 /* cannot open input */ # define EX_TEMPFAIL 75 /* temp failure */ # define EX_OSERR 71 /* system error */ # define EX_CANTCREAT 73 /* can't create (user) output file */ # define EX_IOERR 74 /* input/output error */ # define EX_CONFIG 78 /* configuration error */ #endif #endif /* CONFIG_H */ ]) AC_CONFIG_HEADERS(include/config.h) AC_CONFIG_FILES(bin/control_rancid bin/par bin/rancid-fe, [chmod a+x $ac_file]) AC_CONFIG_FILES(bin/agmrancid, [chmod a+x $ac_file]) AC_CONFIG_FILES(bin/alogin bin/arancid, [chmod a+x $ac_file]) AC_CONFIG_FILES(bin/arrancid, [chmod a+x $ac_file]) AC_CONFIG_FILES(bin/avologin bin/avorancid, [chmod a+x $ac_file]) AC_CONFIG_FILES(bin/blogin bin/brancid, [chmod a+x $ac_file]) AC_CONFIG_FILES(bin/cat5rancid bin/clogin bin/rancid, [chmod a+x $ac_file]) AC_CONFIG_FILES(bin/cssrancid, [chmod a+x $ac_file]) AC_CONFIG_FILES(bin/elogin bin/erancid, [chmod a+x $ac_file]) AC_CONFIG_FILES(bin/f5rancid, [chmod a+x $ac_file]) AC_CONFIG_FILES(bin/f10rancid, [chmod a+x $ac_file]) AC_CONFIG_FILES(bin/flogin bin/francid, [chmod a+x $ac_file]) AC_CONFIG_FILES(bin/fnlogin bin/fnrancid, [chmod a+x $ac_file]) AC_CONFIG_FILES(bin/hlogin bin/hrancid, [chmod a+x $ac_file]) AC_CONFIG_FILES(bin/htlogin bin/htrancid, [chmod a+x $ac_file]) AC_CONFIG_FILES(bin/jlogin bin/jrancid bin/jerancid, [chmod a+x $ac_file]) AC_CONFIG_FILES(bin/mrancid bin/mrvlogin bin/mrvrancid, [chmod a+x $ac_file]) AC_CONFIG_FILES(bin/mtrancid bin/mtlogin, [chmod a+x $ac_file]) AC_CONFIG_FILES(bin/nlogin bin/nrancid, [chmod a+x $ac_file]) AC_CONFIG_FILES(bin/nslogin bin/nsrancid, [chmod a+x $ac_file]) AC_CONFIG_FILES(bin/nxrancid, [chmod a+x $ac_file]) AC_CONFIG_FILES(bin/prancid, [chmod a+x $ac_file]) AC_CONFIG_FILES(bin/rivlogin bin/rivrancid, [chmod a+x $ac_file]) AC_CONFIG_FILES(bin/rrancid, [chmod a+x $ac_file]) AC_CONFIG_FILES(bin/srancid, [chmod a+x $ac_file]) AC_CONFIG_FILES(bin/tlogin, [chmod a+x $ac_file]) AC_CONFIG_FILES(bin/tntlogin bin/tntrancid, [chmod a+x $ac_file]) AC_CONFIG_FILES(bin/trancid, [chmod a+x $ac_file]) AC_CONFIG_FILES(bin/xrancid, [chmod a+x $ac_file]) AC_CONFIG_FILES(bin/xrrancid, [chmod a+x $ac_file]) AC_CONFIG_FILES(bin/zrancid, [chmod a+x $ac_file]) AC_CONFIG_FILES(share/rtrfilter, [chmod a+x $ac_file]) AC_OUTPUT() rancid-2.3.8/aclocal.m4100644 015615 000000 00000104775 11661274062 0010341# generated automatically by aclocal 1.11.1 -*- Autoconf -*- # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, # 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.65],, [m4_warning([this file was generated for autoconf 2.65. You have another version of autoconf. It may work, but is not guaranteed to. If you have problems, you may need to regenerate the build system entirely. To do so, use the procedure documented by the package, typically `autoreconf'.])]) # Copyright (C) 2002, 2003, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_AUTOMAKE_VERSION(VERSION) # ---------------------------- # Automake X.Y traces this macro to ensure aclocal.m4 has been # generated from the m4 files accompanying Automake X.Y. # (This private macro should not be called outside this file.) AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version='1.11' dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to dnl require some minimum version. Point them to the right macro. m4_if([$1], [1.11.1], [], [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl ]) # _AM_AUTOCONF_VERSION(VERSION) # ----------------------------- # aclocal traces this macro to find the Autoconf version. # This is a private macro too. Using m4_define simplifies # the logic in aclocal, which can simply ignore this definition. m4_define([_AM_AUTOCONF_VERSION], []) # AM_SET_CURRENT_AUTOMAKE_VERSION # ------------------------------- # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. # This function is AC_REQUIREd by AM_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], [AM_AUTOMAKE_VERSION([1.11.1])dnl m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) # AM_AUX_DIR_EXPAND -*- Autoconf -*- # Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets # $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to # `$srcdir', `$srcdir/..', or `$srcdir/../..'. # # Of course, Automake must honor this variable whenever it calls a # tool from the auxiliary directory. The problem is that $srcdir (and # therefore $ac_aux_dir as well) can be either absolute or relative, # depending on how configure is run. This is pretty annoying, since # it makes $ac_aux_dir quite unusable in subdirectories: in the top # source directory, any form will work fine, but in subdirectories a # relative path needs to be adjusted first. # # $ac_aux_dir/missing # fails when called from a subdirectory if $ac_aux_dir is relative # $top_srcdir/$ac_aux_dir/missing # fails if $ac_aux_dir is absolute, # fails when called from a subdirectory in a VPATH build with # a relative $ac_aux_dir # # The reason of the latter failure is that $top_srcdir and $ac_aux_dir # are both prefixed by $srcdir. In an in-source build this is usually # harmless because $srcdir is `.', but things will broke when you # start a VPATH build or use an absolute $srcdir. # # So we could use something similar to $top_srcdir/$ac_aux_dir/missing, # iff we strip the leading $srcdir from $ac_aux_dir. That would be: # am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` # and then we would define $MISSING as # MISSING="\${SHELL} $am_aux_dir/missing" # This will work as long as MISSING is not called from configure, because # unfortunately $(top_srcdir) has no meaning in configure. # However there are other variables, like CC, which are often used in # configure, and could therefore not use this "fixed" $ac_aux_dir. # # Another solution, used here, is to always expand $ac_aux_dir to an # absolute PATH. The drawback is that using absolute paths prevent a # configured tree to be moved without reconfiguration. AC_DEFUN([AM_AUX_DIR_EXPAND], [dnl Rely on autoconf to set up CDPATH properly. AC_PREREQ([2.50])dnl # expand $ac_aux_dir to an absolute path am_aux_dir=`cd $ac_aux_dir && pwd` ]) # AM_CONDITIONAL -*- Autoconf -*- # Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005, 2006, 2008 # Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 9 # AM_CONDITIONAL(NAME, SHELL-CONDITION) # ------------------------------------- # Define a conditional. AC_DEFUN([AM_CONDITIONAL], [AC_PREREQ(2.52)dnl ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl AC_SUBST([$1_TRUE])dnl AC_SUBST([$1_FALSE])dnl _AM_SUBST_NOTMAKE([$1_TRUE])dnl _AM_SUBST_NOTMAKE([$1_FALSE])dnl m4_define([_AM_COND_VALUE_$1], [$2])dnl if $2; then $1_TRUE= $1_FALSE='#' else $1_TRUE='#' $1_FALSE= fi AC_CONFIG_COMMANDS_PRE( [if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then AC_MSG_ERROR([[conditional "$1" was never defined. Usually this means the macro was only invoked conditionally.]]) fi])]) # Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2009 # Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 10 # There are a few dirty hacks below to avoid letting `AC_PROG_CC' be # written in clear, in which case automake, when reading aclocal.m4, # will think it sees a *use*, and therefore will trigger all it's # C support machinery. Also note that it means that autoscan, seeing # CC etc. in the Makefile, will ask for an AC_PROG_CC use... # _AM_DEPENDENCIES(NAME) # ---------------------- # See how the compiler implements dependency checking. # NAME is "CC", "CXX", "GCJ", or "OBJC". # We try a few techniques and use that to set a single cache variable. # # We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was # modified to invoke _AM_DEPENDENCIES(CC); we would have a circular # dependency, and given that the user is not expected to run this macro, # just rely on AC_PROG_CC. AC_DEFUN([_AM_DEPENDENCIES], [AC_REQUIRE([AM_SET_DEPDIR])dnl AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl AC_REQUIRE([AM_MAKE_INCLUDE])dnl AC_REQUIRE([AM_DEP_TRACK])dnl ifelse([$1], CC, [depcc="$CC" am_compiler_list=], [$1], CXX, [depcc="$CXX" am_compiler_list=], [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'], [$1], UPC, [depcc="$UPC" am_compiler_list=], [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'], [depcc="$$1" am_compiler_list=]) AC_CACHE_CHECK([dependency style of $depcc], [am_cv_$1_dependencies_compiler_type], [if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named `D' -- because `-MD' means `put the output # in D'. mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_$1_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` fi am__universal=false m4_case([$1], [CC], [case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac], [CXX], [case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac]) for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with # Solaris 8's {/usr,}/bin/sh. touch sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with `-c' and `-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle `-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # after this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvisualcpp | msvcmsys) # This compiler won't grok `-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_$1_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_$1_dependencies_compiler_type=none fi ]) AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) AM_CONDITIONAL([am__fastdep$1], [ test "x$enable_dependency_tracking" != xno \ && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) ]) # AM_SET_DEPDIR # ------------- # Choose a directory name for dependency files. # This macro is AC_REQUIREd in _AM_DEPENDENCIES AC_DEFUN([AM_SET_DEPDIR], [AC_REQUIRE([AM_SET_LEADING_DOT])dnl AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl ]) # AM_DEP_TRACK # ------------ AC_DEFUN([AM_DEP_TRACK], [AC_ARG_ENABLE(dependency-tracking, [ --disable-dependency-tracking speeds up one-time build --enable-dependency-tracking do not reject slow dependency extractors]) if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' fi AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) AC_SUBST([AMDEPBACKSLASH])dnl _AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl ]) # Generate code to set up dependency tracking. -*- Autoconf -*- # Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008 # Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. #serial 5 # _AM_OUTPUT_DEPENDENCY_COMMANDS # ------------------------------ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], [{ # Autoconf 2.62 quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. case $CONFIG_FILES in *\'*) eval set x "$CONFIG_FILES" ;; *) set x $CONFIG_FILES ;; esac shift for mf do # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. # We used to match only the files named `Makefile.in', but # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. # Grep'ing the whole file is not good either: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then dirpart=`AS_DIRNAME("$mf")` else continue fi # Extract the definition of DEPDIR, am__include, and am__quote # from the Makefile without running `make'. DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue am__include=`sed -n 's/^am__include = //p' < "$mf"` test -z "am__include" && continue am__quote=`sed -n 's/^am__quote = //p' < "$mf"` # When using ansi2knr, U may be empty or an underscore; expand it U=`sed -n 's/^U = //p' < "$mf"` # Find all dependency output files, they are included files with # $(DEPDIR) in their names. We invoke sed twice because it is the # simplest approach to changing $(DEPDIR) to its actual value in the # expansion. for file in `sed -n " s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue fdir=`AS_DIRNAME(["$file"])` AS_MKDIR_P([$dirpart/$fdir]) # echo "creating $dirpart/$file" echo '# dummy' > "$dirpart/$file" done done } ])# _AM_OUTPUT_DEPENDENCY_COMMANDS # AM_OUTPUT_DEPENDENCY_COMMANDS # ----------------------------- # This macro should only be invoked once -- use via AC_REQUIRE. # # This code is only required when automatic dependency tracking # is enabled. FIXME. This creates each `.P' file that we will # need in order to bootstrap the dependency handling code. AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], [AC_CONFIG_COMMANDS([depfiles], [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) ]) # Do all the work for Automake. -*- Autoconf -*- # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, # 2005, 2006, 2008, 2009 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 16 # This macro actually does too much. Some checks are only needed if # your package does certain things. But this isn't really a big deal. # AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) # AM_INIT_AUTOMAKE([OPTIONS]) # ----------------------------------------------- # The call with PACKAGE and VERSION arguments is the old style # call (pre autoconf-2.50), which is being phased out. PACKAGE # and VERSION should now be passed to AC_INIT and removed from # the call to AM_INIT_AUTOMAKE. # We support both call styles for the transition. After # the next Automake release, Autoconf can make the AC_INIT # arguments mandatory, and then we can depend on a new Autoconf # release and drop the old call support. AC_DEFUN([AM_INIT_AUTOMAKE], [AC_PREREQ([2.62])dnl dnl Autoconf wants to disallow AM_ names. We explicitly allow dnl the ones we care about. m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl AC_REQUIRE([AC_PROG_INSTALL])dnl if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl # test to see if srcdir already configured if test -f $srcdir/config.status; then AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) fi fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi AC_SUBST([CYGPATH_W]) # Define the identity of the package. dnl Distinguish between old-style and new-style calls. m4_ifval([$2], [m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl AC_SUBST([PACKAGE], [$1])dnl AC_SUBST([VERSION], [$2])], [_AM_SET_OPTIONS([$1])dnl dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. m4_if(m4_ifdef([AC_PACKAGE_NAME], 1)m4_ifdef([AC_PACKAGE_VERSION], 1), 11,, [m4_fatal([AC_INIT should be called with package and version arguments])])dnl AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl _AM_IF_OPTION([no-define],, [AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl # Some tools Automake needs. AC_REQUIRE([AM_SANITY_CHECK])dnl AC_REQUIRE([AC_ARG_PROGRAM])dnl AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version}) AM_MISSING_PROG(AUTOCONF, autoconf) AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version}) AM_MISSING_PROG(AUTOHEADER, autoheader) AM_MISSING_PROG(MAKEINFO, makeinfo) AC_REQUIRE([AM_PROG_INSTALL_SH])dnl AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl AC_REQUIRE([AM_PROG_MKDIR_P])dnl # We need awk for the "check" target. The system "awk" is bad on # some platforms. AC_REQUIRE([AC_PROG_AWK])dnl AC_REQUIRE([AC_PROG_MAKE_SET])dnl AC_REQUIRE([AM_SET_LEADING_DOT])dnl _AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], [_AM_PROG_TAR([v7])])]) _AM_IF_OPTION([no-dependencies],, [AC_PROVIDE_IFELSE([AC_PROG_CC], [_AM_DEPENDENCIES(CC)], [define([AC_PROG_CC], defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl AC_PROVIDE_IFELSE([AC_PROG_CXX], [_AM_DEPENDENCIES(CXX)], [define([AC_PROG_CXX], defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl AC_PROVIDE_IFELSE([AC_PROG_OBJC], [_AM_DEPENDENCIES(OBJC)], [define([AC_PROG_OBJC], defn([AC_PROG_OBJC])[_AM_DEPENDENCIES(OBJC)])])dnl ]) _AM_IF_OPTION([silent-rules], [AC_REQUIRE([AM_SILENT_RULES])])dnl dnl The `parallel-tests' driver may need to know about EXEEXT, so add the dnl `am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This macro dnl is hooked onto _AC_COMPILER_EXEEXT early, see below. AC_CONFIG_COMMANDS_PRE(dnl [m4_provide_if([_AM_COMPILER_EXEEXT], [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl ]) dnl Hook into `_AC_COMPILER_EXEEXT' early to learn its expansion. Do not dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further dnl mangled by Autoconf and run in a shell conditional statement. m4_define([_AC_COMPILER_EXEEXT], m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) # When config.status generates a header, we must update the stamp-h file. # This file resides in the same directory as the config header # that is generated. The stamp files are numbered to have different names. # Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the # loop where config.status creates the headers, so we can generate # our stamp files there. AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], [# Compute $1's index in $config_headers. _am_arg=$1 _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $_am_arg | $_am_arg:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) # Copyright (C) 2001, 2003, 2005, 2008 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_INSTALL_SH # ------------------ # Define $install_sh. AC_DEFUN([AM_PROG_INSTALL_SH], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl if test x"${install_sh}" != xset; then case $am_aux_dir in *\ * | *\ *) install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; *) install_sh="\${SHELL} $am_aux_dir/install-sh" esac fi AC_SUBST(install_sh)]) # Copyright (C) 2003, 2005 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 2 # Check whether the underlying file-system supports filenames # with a leading dot. For instance MS-DOS doesn't. AC_DEFUN([AM_SET_LEADING_DOT], [rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null AC_SUBST([am__leading_dot])]) # Check to see how 'make' treats includes. -*- Autoconf -*- # Copyright (C) 2001, 2002, 2003, 2005, 2009 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 4 # AM_MAKE_INCLUDE() # ----------------- # Check to see how make treats includes. AC_DEFUN([AM_MAKE_INCLUDE], [am_make=${MAKE-make} cat > confinc << 'END' am__doit: @echo this is the am__doit target .PHONY: am__doit END # If we don't find an include directive, just comment out the code. AC_MSG_CHECKING([for style of include used by $am_make]) am__include="#" am__quote= _am_result=none # First try GNU make style include. echo "include confinc" > confmf # Ignore all kinds of additional output from `make'. case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=include am__quote= _am_result=GNU ;; esac # Now try BSD make style include. if test "$am__include" = "#"; then echo '.include "confinc"' > confmf case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=.include am__quote="\"" _am_result=BSD ;; esac fi AC_SUBST([am__include]) AC_SUBST([am__quote]) AC_MSG_RESULT([$_am_result]) rm -f confinc confmf ]) # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- # Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005, 2008 # Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 6 # AM_MISSING_PROG(NAME, PROGRAM) # ------------------------------ AC_DEFUN([AM_MISSING_PROG], [AC_REQUIRE([AM_MISSING_HAS_RUN]) $1=${$1-"${am_missing_run}$2"} AC_SUBST($1)]) # AM_MISSING_HAS_RUN # ------------------ # Define MISSING if not defined so far and test if it supports --run. # If it does, set am_missing_run to use it, otherwise, to nothing. AC_DEFUN([AM_MISSING_HAS_RUN], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([missing])dnl if test x"${MISSING+set}" != xset; then case $am_aux_dir in *\ * | *\ *) MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; *) MISSING="\${SHELL} $am_aux_dir/missing" ;; esac fi # Use eval to expand $SHELL if eval "$MISSING --run true"; then am_missing_run="$MISSING --run " else am_missing_run= AC_MSG_WARN([`missing' script is too old or missing]) fi ]) # Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_MKDIR_P # --------------- # Check for `mkdir -p'. AC_DEFUN([AM_PROG_MKDIR_P], [AC_PREREQ([2.60])dnl AC_REQUIRE([AC_PROG_MKDIR_P])dnl dnl Automake 1.8 to 1.9.6 used to define mkdir_p. We now use MKDIR_P, dnl while keeping a definition of mkdir_p for backward compatibility. dnl @MKDIR_P@ is magic: AC_OUTPUT adjusts its value for each Makefile. dnl However we cannot define mkdir_p as $(MKDIR_P) for the sake of dnl Makefile.ins that do not define MKDIR_P, so we do our own dnl adjustment using top_builddir (which is defined more often than dnl MKDIR_P). AC_SUBST([mkdir_p], ["$MKDIR_P"])dnl case $mkdir_p in [[\\/$]]* | ?:[[\\/]]*) ;; */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; esac ]) # Helper functions for option handling. -*- Autoconf -*- # Copyright (C) 2001, 2002, 2003, 2005, 2008 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 4 # _AM_MANGLE_OPTION(NAME) # ----------------------- AC_DEFUN([_AM_MANGLE_OPTION], [[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) # _AM_SET_OPTION(NAME) # ------------------------------ # Set option NAME. Presently that only means defining a flag for this option. AC_DEFUN([_AM_SET_OPTION], [m4_define(_AM_MANGLE_OPTION([$1]), 1)]) # _AM_SET_OPTIONS(OPTIONS) # ---------------------------------- # OPTIONS is a space-separated list of Automake options. AC_DEFUN([_AM_SET_OPTIONS], [m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) # _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) # ------------------------------------------- # Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. AC_DEFUN([_AM_IF_OPTION], [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) # Copyright (C) 1996, 1997, 1998, 2000, 2001, 2002, 2003, 2005, 2006 # Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 5 AC_DEFUN([AM_C_PROTOTYPES], [AC_REQUIRE([AC_C_PROTOTYPES]) if test "$ac_cv_prog_cc_stdc" != no; then U= ANSI2KNR= else U=_ ANSI2KNR=./ansi2knr fi # Ensure some checks needed by ansi2knr itself. AC_REQUIRE([AC_HEADER_STDC]) AC_CHECK_HEADERS([string.h]) AC_SUBST([U])dnl AC_SUBST([ANSI2KNR])dnl _AM_SUBST_NOTMAKE([ANSI2KNR])dnl ]) AU_DEFUN([fp_C_PROTOTYPES], [AM_C_PROTOTYPES]) # Check to make sure that the build environment is sane. -*- Autoconf -*- # Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005, 2008 # Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 5 # AM_SANITY_CHECK # --------------- AC_DEFUN([AM_SANITY_CHECK], [AC_MSG_CHECKING([whether build environment is sane]) # Just in case sleep 1 echo timestamp > conftest.file # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' ' case `pwd` in *[[\\\"\#\$\&\'\`$am_lf]]*) AC_MSG_ERROR([unsafe absolute working directory name]);; esac case $srcdir in *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) AC_MSG_ERROR([unsafe srcdir value: `$srcdir']);; esac # Do `set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` if test "$[*]" = "X"; then # -L didn't work. set X `ls -t "$srcdir/configure" conftest.file` fi rm -f conftest.file if test "$[*]" != "X $srcdir/configure conftest.file" \ && test "$[*]" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken alias in your environment]) fi test "$[2]" = conftest.file ) then # Ok. : else AC_MSG_ERROR([newly created file is older than distributed files! Check your system clock]) fi AC_MSG_RESULT(yes)]) # Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_INSTALL_STRIP # --------------------- # One issue with vendor `install' (even GNU) is that you can't # specify the program used to strip binaries. This is especially # annoying in cross-compiling environments, where the build's strip # is unlikely to handle the host's binaries. # Fortunately install-sh will honor a STRIPPROG variable, so we # always use install-sh in `make install-strip', and initialize # STRIPPROG with the value of the STRIP variable (set by the user). AC_DEFUN([AM_PROG_INSTALL_STRIP], [AC_REQUIRE([AM_PROG_INSTALL_SH])dnl # Installed binaries are usually stripped using `strip' when the user # run `make install-strip'. However `strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the `STRIP' environment variable to overrule this program. dnl Don't test for $cross_compiling = yes, because it might be `maybe'. if test "$cross_compiling" != no; then AC_CHECK_TOOL([STRIP], [strip], :) fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" AC_SUBST([INSTALL_STRIP_PROGRAM])]) # Copyright (C) 2006, 2008 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 2 # _AM_SUBST_NOTMAKE(VARIABLE) # --------------------------- # Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. # This macro is traced by Automake. AC_DEFUN([_AM_SUBST_NOTMAKE]) # AM_SUBST_NOTMAKE(VARIABLE) # --------------------------- # Public sister of _AM_SUBST_NOTMAKE. AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) # Check how to create a tarball. -*- Autoconf -*- # Copyright (C) 2004, 2005 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 2 # _AM_PROG_TAR(FORMAT) # -------------------- # Check how to create a tarball in format FORMAT. # FORMAT should be one of `v7', `ustar', or `pax'. # # Substitute a variable $(am__tar) that is a command # writing to stdout a FORMAT-tarball containing the directory # $tardir. # tardir=directory && $(am__tar) > result.tar # # Substitute a variable $(am__untar) that extract such # a tarball read from stdin. # $(am__untar) < result.tar AC_DEFUN([_AM_PROG_TAR], [# Always define AMTAR for backward compatibility. AM_MISSING_PROG([AMTAR], [tar]) m4_if([$1], [v7], [am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'], [m4_case([$1], [ustar],, [pax],, [m4_fatal([Unknown tar format])]) AC_MSG_CHECKING([how to create a $1 tar archive]) # Loop over all known methods to create a tar archive until one works. _am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' _am_tools=${am_cv_prog_tar_$1-$_am_tools} # Do not fold the above two line into one, because Tru64 sh and # Solaris sh will not grok spaces in the rhs of `-'. for _am_tool in $_am_tools do case $_am_tool in gnutar) for _am_tar in tar gnutar gtar; do AM_RUN_LOG([$_am_tar --version]) && break done am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' am__untar="$_am_tar -xf -" ;; plaintar) # Must skip GNU tar: if it does not support --format= it doesn't create # ustar tarball either. (tar --version) >/dev/null 2>&1 && continue am__tar='tar chf - "$$tardir"' am__tar_='tar chf - "$tardir"' am__untar='tar xf -' ;; pax) am__tar='pax -L -x $1 -w "$$tardir"' am__tar_='pax -L -x $1 -w "$tardir"' am__untar='pax -r' ;; cpio) am__tar='find "$$tardir" -print | cpio -o -H $1 -L' am__tar_='find "$tardir" -print | cpio -o -H $1 -L' am__untar='cpio -i -H $1 -d' ;; none) am__tar=false am__tar_=false am__untar=false ;; esac # If the value was cached, stop now. We just wanted to have am__tar # and am__untar set. test -n "${am_cv_prog_tar_$1}" && break # tar/untar a dummy directory, and stop if the command works rm -rf conftest.dir mkdir conftest.dir echo GrepMe > conftest.dir/file AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) rm -rf conftest.dir if test -s conftest.tar; then AM_RUN_LOG([$am__untar /dev/null 2>&1 && break fi done rm -rf conftest.dir AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) AC_MSG_RESULT([$am_cv_prog_tar_$1])]) AC_SUBST([am__tar]) AC_SUBST([am__untar]) ]) # _AM_PROG_TAR m4_include([acinclude.m4]) rancid-2.3.8/Makefile.am100644 015615 000000 00000003416 11535733223 0010522## Process this file with automake to produce Makefile.in ## A Makefile.in is supplied, in case you do not have automake. ## $Id: Makefile.am 2286 2011-02-16 18:27:13Z heas $ ## ## Copyright (C) 1997-2008 by Terrapin Communications, Inc. ## All rights reserved. ## ## This software may be freely copied, modified and redistributed ## without fee for non-commerical purposes provided that this license ## remains intact and unmodified with any RANCID distribution. ## ## 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. ## ## Except where noted otherwise, rancid was written by and is maintained by ## Henry Kilmer, John Heasley, Andrew Partan, and Pete Whiting. ## AUTOMAKE_OPTIONS=foreign no-dependencies @SET_MAKE@ pkgdata_DATA = COPYING CHANGES FAQ README README.lg UPGRADING cloginrc.sample EXTRA_DIST = BUGS Todo configure install-sh \ mkinstalldirs Makefile.in Todo $(pkgdata_DATA) #DIST_COMMON = # '.' is here (and at the beginnging of the macro) so that distclean-recursive # will run make distclean in . after the other dirs (preserving Makefile) and # mkinstalldirs will create the install destination before descending into # the subdirs. SUBDIRS = . include etc bin man share # sysconfdir is here because etc/Makefile uses a script to be careful about # installing rancid.conf, not over-writing an existing one. DIRS2_CREATE=$(DESTDIR)$(prefix) $(DESTDIR)$(sysconfdir) if MK_LCLSTATEDIR DIRS2_CREATE+=$(DESTDIR)$(localstatedir) endif install-data-hook: $(mkinstalldirs) $(DIRS2_CREATE); distclean-local: -rm -rf $(top_srcdir)/autom4te.cache rancid-2.3.8/Makefile.in100644 015615 000000 00000057742 11661274064 0010551# Makefile.in generated by automake 1.11.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, # Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : @MK_LCLSTATEDIR_TRUE@am__append_1 = $(DESTDIR)$(localstatedir) subdir = . DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \ $(srcdir)/Makefile.in $(top_srcdir)/configure COPYING depcomp \ install-sh missing mkinstalldirs ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ configure.lineno config.status.lineno mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_HEADER = $(top_builddir)/include/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = depcomp = am__depfiles_maybe = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ html-recursive info-recursive install-data-recursive \ install-dvi-recursive install-exec-recursive \ install-html-recursive install-info-recursive \ install-pdf-recursive install-ps-recursive install-recursive \ installcheck-recursive installdirs-recursive pdf-recursive \ ps-recursive uninstall-recursive am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__installdirs = "$(DESTDIR)$(pkgdatadir)" DATA = $(pkgdata_DATA) RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \ distdir dist dist-all distcheck ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) am__remove_distdir = \ { test ! -d "$(distdir)" \ || { find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ && rm -fr "$(distdir)"; }; } am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" DIST_ARCHIVES = $(distdir).tar.gz GZIP_ENV = --best distuninstallcheck_listfiles = find . -type f -print distcleancheck_listfiles = find . -type f -print ACLOCAL = @ACLOCAL@ ADMINMAILPLUS = @ADMINMAILPLUS@ AMTAR = @AMTAR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ COMM = @COMM@ COPYYEARS = @COPYYEARS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CVS = @CVS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DIFF = @DIFF@ DIFF_CMD = @DIFF_CMD@ DIRNAME = @DIRNAME@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ENV_PATH = @ENV_PATH@ EXEEXT = @EXEEXT@ EXPECT_PATH = @EXPECT_PATH@ FIND = @FIND@ GREP = @GREP@ ID = @ID@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LG_PING_CMD = @LG_PING_CMD@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAILPLUS = @MAILPLUS@ MAKE = @MAKE@ MAKEINFO = @MAKEINFO@ MKDIR = @MKDIR@ MKDIR_P = @MKDIR_P@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERLV = @PERLV@ PERLV_PATH = @PERLV_PATH@ PING_PATH = @PING_PATH@ RCSSYS = @RCSSYS@ RSH = @RSH@ SENDMAIL = @SENDMAIL@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SORT = @SORT@ SSH = @SSH@ STRIP = @STRIP@ SVN = @SVN@ SVN_FSTYPE = @SVN_FSTYPE@ TAR = @TAR@ TELNET = @TELNET@ TOUCH = @TOUCH@ U = @U@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build_alias = @build_alias@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host_alias = @host_alias@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ AUTOMAKE_OPTIONS = foreign no-dependencies pkgdata_DATA = COPYING CHANGES FAQ README README.lg UPGRADING cloginrc.sample EXTRA_DIST = BUGS Todo configure install-sh \ mkinstalldirs Makefile.in Todo $(pkgdata_DATA) #DIST_COMMON = # '.' is here (and at the beginnging of the macro) so that distclean-recursive # will run make distclean in . after the other dirs (preserving Makefile) and # mkinstalldirs will create the install destination before descending into # the subdirs. SUBDIRS = . include etc bin man share # sysconfdir is here because etc/Makefile uses a script to be careful about # installing rancid.conf, not over-writing an existing one. DIRS2_CREATE = $(DESTDIR)$(prefix) $(DESTDIR)$(sysconfdir) \ $(am__append_1) all: all-recursive .SUFFIXES: am--refresh: @: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ echo ' cd $(srcdir) && $(AUTOMAKE) --foreign'; \ $(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ echo ' $(SHELL) ./config.status'; \ $(SHELL) ./config.status;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) $(SHELL) ./config.status --recheck $(top_srcdir)/configure: $(am__configure_deps) $(am__cd) $(srcdir) && $(AUTOCONF) $(ACLOCAL_M4): $(am__aclocal_m4_deps) $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) $(am__aclocal_m4_deps): install-pkgdataDATA: $(pkgdata_DATA) @$(NORMAL_INSTALL) test -z "$(pkgdatadir)" || $(MKDIR_P) "$(DESTDIR)$(pkgdatadir)" @list='$(pkgdata_DATA)'; test -n "$(pkgdatadir)" || list=; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgdatadir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgdatadir)" || exit $$?; \ done uninstall-pkgdataDATA: @$(NORMAL_UNINSTALL) @list='$(pkgdata_DATA)'; test -n "$(pkgdatadir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ test -n "$$files" || exit 0; \ echo " ( cd '$(DESTDIR)$(pkgdatadir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(pkgdatadir)" && rm -f $$files # This directory's subdirectories are mostly independent; you can cd # into them and run `make' without going through this Makefile. # To change the values of `make' variables: instead of editing Makefiles, # (1) if the variable is set in `config.status', edit `config.status' # (which will cause the Makefiles to be regenerated when you run `make'); # (2) otherwise, pass the desired values on the `make' command line. $(RECURSIVE_TARGETS): @fail= failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ list='$(SUBDIRS)'; for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" $(RECURSIVE_CLEAN_TARGETS): @fail= failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ rev=''; for subdir in $$list; do \ if test "$$subdir" = "."; then :; else \ rev="$$subdir $$rev"; \ fi; \ done; \ rev="$$rev ."; \ target=`echo $@ | sed s/-recursive//`; \ for subdir in $$rev; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done && test -z "$$fail" tags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ done ctags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ done ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) $(am__remove_distdir) test -d "$(distdir)" || mkdir "$(distdir)" @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done -test -n "$(am__skip_mode_fix)" \ || find "$(distdir)" -type d ! -perm -755 \ -exec chmod u+rwx,go+rx {} \; -o \ ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ || chmod -R a+r "$(distdir)" dist-gzip: distdir tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz $(am__remove_distdir) dist-bzip2: distdir tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2 $(am__remove_distdir) dist-lzma: distdir tardir=$(distdir) && $(am__tar) | lzma -9 -c >$(distdir).tar.lzma $(am__remove_distdir) dist-xz: distdir tardir=$(distdir) && $(am__tar) | xz -c >$(distdir).tar.xz $(am__remove_distdir) dist-tarZ: distdir tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z $(am__remove_distdir) dist-shar: distdir shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz $(am__remove_distdir) dist-zip: distdir -rm -f $(distdir).zip zip -rq $(distdir).zip $(distdir) $(am__remove_distdir) dist dist-all: distdir tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz $(am__remove_distdir) # This target untars the dist file and tries a VPATH configuration. Then # it guarantees that the distribution is self-contained by making another # tarfile. distcheck: dist case '$(DIST_ARCHIVES)' in \ *.tar.gz*) \ GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\ *.tar.bz2*) \ bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ *.tar.lzma*) \ lzma -dc $(distdir).tar.lzma | $(am__untar) ;;\ *.tar.xz*) \ xz -dc $(distdir).tar.xz | $(am__untar) ;;\ *.tar.Z*) \ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ *.shar.gz*) \ GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\ *.zip*) \ unzip $(distdir).zip ;;\ esac chmod -R a-w $(distdir); chmod a+w $(distdir) mkdir $(distdir)/_build mkdir $(distdir)/_inst chmod a-w $(distdir) test -d $(distdir)/_build || exit 0; \ dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ && am__cwd=`pwd` \ && $(am__cd) $(distdir)/_build \ && ../configure --srcdir=.. --prefix="$$dc_install_base" \ $(DISTCHECK_CONFIGURE_FLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) dvi \ && $(MAKE) $(AM_MAKEFLAGS) check \ && $(MAKE) $(AM_MAKEFLAGS) install \ && $(MAKE) $(AM_MAKEFLAGS) installcheck \ && $(MAKE) $(AM_MAKEFLAGS) uninstall \ && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ distuninstallcheck \ && chmod -R a-w "$$dc_install_base" \ && ({ \ (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ } || { rm -rf "$$dc_destdir"; exit 1; }) \ && rm -rf "$$dc_destdir" \ && $(MAKE) $(AM_MAKEFLAGS) dist \ && rm -rf $(DIST_ARCHIVES) \ && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ && cd "$$am__cwd" \ || exit 1 $(am__remove_distdir) @(echo "$(distdir) archives ready for distribution: "; \ list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' distuninstallcheck: @$(am__cd) '$(distuninstallcheck_dir)' \ && test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \ || { echo "ERROR: files left after uninstall:" ; \ if test -n "$(DESTDIR)"; then \ echo " (check DESTDIR support)"; \ fi ; \ $(distuninstallcheck_listfiles) ; \ exit 1; } >&2 distcleancheck: distclean @if test '$(srcdir)' = . ; then \ echo "ERROR: distcleancheck can only run from a VPATH build" ; \ exit 1 ; \ fi @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ || { echo "ERROR: files left in build directory after distclean:" ; \ $(distcleancheck_listfiles) ; \ exit 1; } >&2 check-am: all-am check: check-recursive all-am: Makefile $(DATA) installdirs: installdirs-recursive installdirs-am: for dir in "$(DESTDIR)$(pkgdatadir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic mostlyclean-am distclean: distclean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -f Makefile distclean-am: clean-am distclean-generic distclean-local \ distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-pkgdataDATA @$(NORMAL_INSTALL) $(MAKE) $(AM_MAKEFLAGS) install-data-hook install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -rf $(top_srcdir)/autom4te.cache -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: uninstall-pkgdataDATA .MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) ctags-recursive \ install-am install-data-am install-strip tags-recursive .PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ all all-am am--refresh check check-am clean clean-generic \ ctags ctags-recursive dist dist-all dist-bzip2 dist-gzip \ dist-lzma dist-shar dist-tarZ dist-xz dist-zip distcheck \ distclean distclean-generic distclean-local distclean-tags \ distcleancheck distdir distuninstallcheck dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-data-hook install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-pkgdataDATA install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic pdf pdf-am ps ps-am tags \ tags-recursive uninstall uninstall-am uninstall-pkgdataDATA @SET_MAKE@ install-data-hook: $(mkinstalldirs) $(DIRS2_CREATE); distclean-local: -rm -rf $(top_srcdir)/autom4te.cache # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: rancid-2.3.8/configure100755 015615 000000 00000665356 11661274064 0010421#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.65. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, # 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, # Inc. # # # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH if test "x$CONFIG_SHELL" = x; then as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST else case \`(set -o) 2>/dev/null\` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi " as_required="as_fn_return () { (exit \$1); } as_fn_success () { as_fn_return 0; } as_fn_failure () { as_fn_return 1; } as_fn_ret_success () { return 0; } as_fn_ret_failure () { return 1; } exitcode=0 as_fn_success || { exitcode=1; echo as_fn_success failed.; } as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : else exitcode=1; echo positional parameters were not saved. fi test x\$exitcode = x0 || exit 1" as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 test \$(( 1 + 1 )) = 2 || exit 1" if (eval "$as_required") 2>/dev/null; then : as_have_required=yes else as_have_required=no fi if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_found=false for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. as_found=: case $as_dir in #( /*) for as_base in sh bash ksh sh5; do # Try only shells that exist, to save several forks. as_shell=$as_dir/$as_base if { test -f "$as_shell" || test -f "$as_shell.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : CONFIG_SHELL=$as_shell as_have_required=yes if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : break 2 fi fi done;; esac as_found=false done $as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : CONFIG_SHELL=$SHELL as_have_required=yes fi; } IFS=$as_save_IFS if test "x$CONFIG_SHELL" != x; then : # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV export CONFIG_SHELL exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"} fi if test x$as_have_required = xno; then : $as_echo "$0: This script requires a shell more modern than all" $as_echo "$0: the shells that I found on your system." if test x${ZSH_VERSION+set} = xset ; then $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" $as_echo "$0: be upgraded to zsh 4.3.4 or later." else $as_echo "$0: Please tell bug-autoconf@gnu.org about your system, $0: including any error possibly output before this $0: message. Then install a modern shell, or manually run $0: the script under such a shell if you do have one." fi exit 1 fi fi fi SHELL=${CONFIG_SHELL-/bin/sh} export SHELL # Unset more variables known to interfere with behavior of common tools. CLICOLOR_FORCE= GREP_OPTIONS= unset CLICOLOR_FORCE GREP_OPTIONS ## --------------------- ## ## M4sh Shell Functions. ## ## --------------------- ## # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error "cannot create directory $as_dir" } # as_fn_mkdir_p # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith # as_fn_error ERROR [LINENO LOG_FD] # --------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with status $?, using 1 if that was 0. as_fn_error () { as_status=$?; test $as_status -eq 0 && as_status=1 if test "$3"; then as_lineno=${as_lineno-"$2"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $1" >&$3 fi $as_echo "$as_me: error: $1" >&2 as_fn_exit $as_status } # as_fn_error if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits as_lineno_1=$LINENO as_lineno_1a=$LINENO as_lineno_2=$LINENO as_lineno_2a=$LINENO eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -p'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -p' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi else as_ln_s='cp -p' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi if test -x / >/dev/null 2>&1; then as_test_x='test -x' else if ls -dL / >/dev/null 2>&1; then as_ls_L_option=L else as_ls_L_option= fi as_test_x=' eval sh -c '\'' if test -d "$1"; then test -d "$1/."; else case $1 in #( -*)set "./$1";; esac; case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( ???[sx]*):;;*)false;;esac;fi '\'' sh ' fi as_executable_p=$as_test_x # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" test -n "$DJDIR" || exec 7<&0 &1 # Name of the host. # hostname on some systems (SVR3.2, Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` # # Initializations. # ac_default_prefix=/usr/local ac_clean_files= ac_config_libobj_dir=. LIBOBJS= cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= # Identity of this package. PACKAGE_NAME= PACKAGE_TARNAME= PACKAGE_VERSION= PACKAGE_STRING= PACKAGE_BUGREPORT= PACKAGE_URL= ac_unique_file="CHANGES" ac_default_prefix=/usr/local/rancid # Factoring default headers for most tests. ac_includes_default="\ #include #ifdef HAVE_SYS_TYPES_H # include #endif #ifdef HAVE_SYS_STAT_H # include #endif #ifdef STDC_HEADERS # include # include #else # ifdef HAVE_STDLIB_H # include # endif #endif #ifdef HAVE_STRING_H # if !defined STDC_HEADERS && defined HAVE_MEMORY_H # include # endif # include #endif #ifdef HAVE_STRINGS_H # include #endif #ifdef HAVE_INTTYPES_H # include #endif #ifdef HAVE_STDINT_H # include #endif #ifdef HAVE_UNISTD_H # include #endif" ac_subst_vars='am__EXEEXT_FALSE am__EXEEXT_TRUE LTLIBOBJS LIBOBJS ENV_PATH TOUCH TELNET SSH SORT RSH MKDIR ID FIND COMM SVN CVS LG_PING_CMD PING_PATH EXPECT_PATH PERLV PERLV_PATH TAR SENDMAIL DIFF_CMD DIFF DIRNAME ADMINMAILPLUS MAILPLUS SVN_FSTYPE RCSSYS CONF_INSTALL_FALSE CONF_INSTALL_TRUE MK_LCLSTATEDIR_FALSE MK_LCLSTATEDIR_TRUE ANSI2KNR U EGREP GREP CPP am__fastdepCC_FALSE am__fastdepCC_TRUE CCDEPMODE AMDEPBACKSLASH AMDEP_FALSE AMDEP_TRUE am__quote am__include DEPDIR OBJEXT EXEEXT ac_ct_CC CPPFLAGS LDFLAGS CFLAGS CC MAKE am__untar am__tar AMTAR am__leading_dot SET_MAKE AWK mkdir_p MKDIR_P INSTALL_STRIP_PROGRAM STRIP install_sh MAKEINFO AUTOHEADER AUTOMAKE AUTOCONF ACLOCAL CYGPATH_W am__isrc INSTALL_DATA INSTALL_SCRIPT INSTALL_PROGRAM COPYYEARS PACKAGE VERSION target_alias host_alias build_alias LIBS ECHO_T ECHO_N ECHO_C DEFS mandir localedir libdir psdir pdfdir dvidir htmldir infodir docdir oldincludedir includedir localstatedir sharedstatedir sysconfdir datadir datarootdir libexecdir sbindir bindir program_transform_name prefix exec_prefix PACKAGE_URL PACKAGE_BUGREPORT PACKAGE_STRING PACKAGE_VERSION PACKAGE_TARNAME PACKAGE_NAME PATH_SEPARATOR SHELL' ac_subst_files='' ac_user_opts=' enable_option_checking enable_dependency_tracking enable_mk_localstatedir enable_conf_install with_svn enable_mail_plus enable_adminmail_plus ' ac_precious_vars='build_alias host_alias target_alias CC CFLAGS LDFLAGS LIBS CPPFLAGS CPP' # Initialize some variables set by options. ac_init_help= ac_init_version=false ac_unrecognized_opts= ac_unrecognized_sep= # The variables have the same names as the options, with # dashes changed to underlines. cache_file=/dev/null exec_prefix=NONE no_create= no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= verbose= x_includes=NONE x_libraries=NONE # Installation directory options. # These are left unexpanded so users can "make install exec_prefix=/foo" # and all the variables that are supposed to be based on exec_prefix # by default will actually change. # Use braces instead of parens because sh, perl, etc. also accept them. # (The list follows the same order as the GNU Coding Standards.) bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datarootdir='${prefix}/share' datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE}' infodir='${datarootdir}/info' htmldir='${docdir}' dvidir='${docdir}' pdfdir='${docdir}' psdir='${docdir}' libdir='${exec_prefix}/lib' localedir='${datarootdir}/locale' mandir='${datarootdir}/man' ac_prev= ac_dashdash= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval $ac_prev=\$ac_option ac_prev= continue fi case $ac_option in *=*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; *) ac_optarg=yes ;; esac # Accept the important Cygnus configure options, so we can diagnose typos. case $ac_dashdash$ac_option in --) ac_dashdash=yes ;; -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir=$ac_optarg ;; -build | --build | --buil | --bui | --bu) ac_prev=build_alias ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build_alias=$ac_optarg ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file=$ac_optarg ;; --config-cache | -C) cache_file=config.cache ;; -datadir | --datadir | --datadi | --datad) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=*) datadir=$ac_optarg ;; -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ | --dataroo | --dataro | --datar) ac_prev=datarootdir ;; -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) datarootdir=$ac_optarg ;; -disable-* | --disable-*) ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=no ;; -docdir | --docdir | --docdi | --doc | --do) ac_prev=docdir ;; -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) docdir=$ac_optarg ;; -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) ac_prev=dvidir ;; -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) dvidir=$ac_optarg ;; -enable-* | --enable-*) ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=\$ac_optarg ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix=$ac_optarg ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he | -h) ac_init_help=long ;; -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) ac_init_help=recursive ;; -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) ac_init_help=short ;; -host | --host | --hos | --ho) ac_prev=host_alias ;; -host=* | --host=* | --hos=* | --ho=*) host_alias=$ac_optarg ;; -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) ac_prev=htmldir ;; -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ | --ht=*) htmldir=$ac_optarg ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir=$ac_optarg ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir=$ac_optarg ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir=$ac_optarg ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir=$ac_optarg ;; -localedir | --localedir | --localedi | --localed | --locale) ac_prev=localedir ;; -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) localedir=$ac_optarg ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst | --locals) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) localstatedir=$ac_optarg ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir=$ac_optarg ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c | -n) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir=$ac_optarg ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix=$ac_optarg ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix=$ac_optarg ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix=$ac_optarg ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name=$ac_optarg ;; -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) ac_prev=pdfdir ;; -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) pdfdir=$ac_optarg ;; -psdir | --psdir | --psdi | --psd | --ps) ac_prev=psdir ;; -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) psdir=$ac_optarg ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir=$ac_optarg ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir=$ac_optarg ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site=$ac_optarg ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir=$ac_optarg ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir=$ac_optarg ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target_alias ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target_alias=$ac_optarg ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers | -V) ac_init_version=: ;; -with-* | --with-*) ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=\$ac_optarg ;; -without-* | --without-*) ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=no ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes=$ac_optarg ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; -*) as_fn_error "unrecognized option: \`$ac_option' Try \`$0 --help' for more information." ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. case $ac_envvar in #( '' | [0-9]* | *[!_$as_cr_alnum]* ) as_fn_error "invalid variable name: \`$ac_envvar'" ;; esac eval $ac_envvar=\$ac_optarg export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} ;; esac done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` as_fn_error "missing argument to $ac_option" fi if test -n "$ac_unrecognized_opts"; then case $enable_option_checking in no) ;; fatal) as_fn_error "unrecognized options: $ac_unrecognized_opts" ;; *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; esac fi # Check all directory arguments for consistency. for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ libdir localedir mandir do eval ac_val=\$$ac_var # Remove trailing slashes. case $ac_val in */ ) ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` eval $ac_var=\$ac_val;; esac # Be sure to have absolute directory names. case $ac_val in [\\/$]* | ?:[\\/]* ) continue;; NONE | '' ) case $ac_var in *prefix ) continue;; esac;; esac as_fn_error "expected an absolute directory name for --$ac_var: $ac_val" done # There might be people who depend on the old broken behavior: `$host' # used to hold the argument of --host etc. # FIXME: To remove some day. build=$build_alias host=$host_alias target=$target_alias # FIXME: To remove some day. if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe $as_echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. If a cross compiler is detected then cross compile mode will be used." >&2 elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi fi ac_tool_prefix= test -n "$host_alias" && ac_tool_prefix=$host_alias- test "$silent" = yes && exec 6>/dev/null ac_pwd=`pwd` && test -n "$ac_pwd" && ac_ls_di=`ls -di .` && ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || as_fn_error "working directory cannot be determined" test "X$ac_ls_di" = "X$ac_pwd_ls_di" || as_fn_error "pwd does not report name of working directory" # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then the parent directory. ac_confdir=`$as_dirname -- "$as_myself" || $as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_myself" : 'X\(//\)[^/]' \| \ X"$as_myself" : 'X\(//\)$' \| \ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_myself" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` srcdir=$ac_confdir if test ! -r "$srcdir/$ac_unique_file"; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r "$srcdir/$ac_unique_file"; then test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." as_fn_error "cannot find sources ($ac_unique_file) in $srcdir" fi ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" ac_abs_confdir=`( cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error "$ac_msg" pwd)` # When building in place, set srcdir=. if test "$ac_abs_confdir" = "$ac_pwd"; then srcdir=. fi # Remove unnecessary trailing slashes from srcdir. # Double slashes in file names in object file debugging info # mess up M-x gdb in Emacs. case $srcdir in */) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; esac for ac_var in $ac_precious_vars; do eval ac_env_${ac_var}_set=\${${ac_var}+set} eval ac_env_${ac_var}_value=\$${ac_var} eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} eval ac_cv_env_${ac_var}_value=\$${ac_var} done # # Report the --help message. # if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF \`configure' configures this package to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. Configuration: -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit -q, --quiet, --silent do not print \`checking...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or \`..'] Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, \`make install' will install all the files in \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify an installation prefix other than \`$ac_default_prefix' using \`--prefix', for instance \`--prefix=\$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] --datadir=DIR read-only architecture-independent data [DATAROOTDIR] --infodir=DIR info documentation [DATAROOTDIR/info] --localedir=DIR locale-dependent data [DATAROOTDIR/locale] --mandir=DIR man documentation [DATAROOTDIR/man] --docdir=DIR documentation root [DATAROOTDIR/doc/PACKAGE] --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] --psdir=DIR ps documentation [DOCDIR] _ACEOF cat <<\_ACEOF Program names: --program-prefix=PREFIX prepend PREFIX to installed program names --program-suffix=SUFFIX append SUFFIX to installed program names --program-transform-name=PROGRAM run sed PROGRAM on installed program names _ACEOF fi if test -n "$ac_init_help"; then cat <<\_ACEOF Optional Features: --disable-option-checking ignore unrecognized --enable/--with options --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --disable-dependency-tracking speeds up one-time build --enable-dependency-tracking do not reject slow dependency extractors --enable-mk-localstatedir enable creation of the local state directory at install time (default: yes) --enable-conf-install enable install of sample .conf files in sysconfdir (default: yes) --enable-mail-plus enable mail to rancid+ addresses, instead of rancid- --enable-adminmail-plus enable mail to rancid-admin+ addresses, instead of rancid-admin- Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --with-svn=fstype use subversion instead of cvs, with optional svn fstype (fsfs|bdb) Some influential environment variables: CC C compiler command CFLAGS C compiler flags LDFLAGS linker flags, e.g. -L if you have libraries in a nonstandard directory LIBS libraries to pass to the linker, e.g. -l CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if you have headers in a nonstandard directory CPP C preprocessor Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. Report bugs to the package provider. _ACEOF ac_status=$? fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue test -d "$ac_dir" || { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || continue ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix cd "$ac_dir" || { ac_status=$?; continue; } # Check for guested configure. if test -f "$ac_srcdir/configure.gnu"; then echo && $SHELL "$ac_srcdir/configure.gnu" --help=recursive elif test -f "$ac_srcdir/configure"; then echo && $SHELL "$ac_srcdir/configure" --help=recursive else $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi || ac_status=$? cd "$ac_pwd" || { ac_status=$?; break; } done fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF configure generated by GNU Autoconf 2.65 Copyright (C) 2009 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF exit fi ## ------------------------ ## ## Autoconf initialization. ## ## ------------------------ ## # ac_fn_c_try_compile LINENO # -------------------------- # Try to compile conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} as_fn_set_status $ac_retval } # ac_fn_c_try_compile # ac_fn_c_try_cpp LINENO # ---------------------- # Try to preprocess conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_cpp () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} as_fn_set_status $ac_retval } # ac_fn_c_try_cpp # ac_fn_c_try_run LINENO # ---------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. Assumes # that executables *can* be run. ac_fn_c_try_run () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then : ac_retval=0 else $as_echo "$as_me: program exited with status $ac_status" >&5 $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=$ac_status fi rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} as_fn_set_status $ac_retval } # ac_fn_c_try_run # ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists, giving a warning if it cannot be compiled using # the include files in INCLUDES and setting the cache variable VAR # accordingly. ac_fn_c_check_header_mongrel () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : $as_echo_n "(cached) " >&6 fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } else # Is the header compilable? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 $as_echo_n "checking $2 usability... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_header_compiler=yes else ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 $as_echo_n "checking $2 presence... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <$2> _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : ac_header_preproc=yes else ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 $as_echo "$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( yes:no: ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ;; no:yes:* ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : $as_echo_n "(cached) " >&6 else eval "$3=\$ac_header_compiler" fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} } # ac_fn_c_check_header_mongrel # ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists and can be compiled using the include files in # INCLUDES, setting the cache variable VAR accordingly. ac_fn_c_check_header_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} } # ac_fn_c_check_header_compile # ac_fn_c_try_link LINENO # ----------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_link () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext conftest$ac_exeext if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would # interfere with the next link command; also delete a directory that is # left behind by Apple's compiler. We do this before executing the actions. rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} as_fn_set_status $ac_retval } # ac_fn_c_try_link # ac_fn_c_check_func LINENO FUNC VAR # ---------------------------------- # Tests whether FUNC exists, setting the cache variable VAR accordingly ac_fn_c_check_func () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Define $2 to an innocuous variant, in case declares $2. For example, HP-UX 11i declares gettimeofday. */ #define $2 innocuous_$2 /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $2 (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $2 /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $2 (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$2 || defined __stub___$2 choke me #endif int main () { return $2 (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} } # ac_fn_c_check_func # ac_fn_c_check_type LINENO TYPE VAR INCLUDES # ------------------------------------------- # Tests whether TYPE exists after having included INCLUDES, setting cache # variable VAR accordingly. ac_fn_c_check_type () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : $as_echo_n "(cached) " >&6 else eval "$3=no" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { if (sizeof ($2)) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { if (sizeof (($2))) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else eval "$3=yes" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} } # ac_fn_c_check_type cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by $as_me, which was generated by GNU Autoconf 2.65. Invocation command line was $ $0 $@ _ACEOF exec 5>>config.log { cat <<_ASUNAME ## --------- ## ## Platform. ## ## --------- ## hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` /bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` /bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` /usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` /bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` /bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` _ASUNAME as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. $as_echo "PATH: $as_dir" done IFS=$as_save_IFS } >&5 cat >&5 <<_ACEOF ## ----------- ## ## Core tests. ## ## ----------- ## _ACEOF # Keep a trace of the command line. # Strip out --no-create and --no-recursion so they do not pile up. # Strip out --silent because we don't want to record it for future runs. # Also quote any args containing shell meta-characters. # Make two passes to allow for proper duplicate-argument suppression. ac_configure_args= ac_configure_args0= ac_configure_args1= ac_must_keep_next=false for ac_pass in 1 2 do for ac_arg do case $ac_arg in -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) continue ;; *\'*) ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; 2) as_fn_append ac_configure_args1 " '$ac_arg'" if test $ac_must_keep_next = true; then ac_must_keep_next=false # Got value, back to normal. else case $ac_arg in *=* | --config-cache | -C | -disable-* | --disable-* \ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ | -with-* | --with-* | -without-* | --without-* | --x) case "$ac_configure_args0 " in "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; esac ;; -* ) ac_must_keep_next=true ;; esac fi as_fn_append ac_configure_args " '$ac_arg'" ;; esac done done { ac_configure_args0=; unset ac_configure_args0;} { ac_configure_args1=; unset ac_configure_args1;} # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there # would cause problems or look ugly. # WARNING: Use '\'' to represent an apostrophe within the trap. # WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. trap 'exit_status=$? # Save into config.log some information that might help in debugging. { echo cat <<\_ASBOX ## ---------------- ## ## Cache variables. ## ## ---------------- ## _ASBOX echo # The following way of writing the cache mishandles newlines in values, ( for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( *${as_nl}ac_space=\ *) sed -n \ "s/'\''/'\''\\\\'\'''\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" ;; #( *) sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) echo cat <<\_ASBOX ## ----------------- ## ## Output variables. ## ## ----------------- ## _ASBOX echo for ac_var in $ac_subst_vars do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo if test -n "$ac_subst_files"; then cat <<\_ASBOX ## ------------------- ## ## File substitutions. ## ## ------------------- ## _ASBOX echo for ac_var in $ac_subst_files do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo fi if test -s confdefs.h; then cat <<\_ASBOX ## ----------- ## ## confdefs.h. ## ## ----------- ## _ASBOX echo cat confdefs.h echo fi test "$ac_signal" != 0 && $as_echo "$as_me: caught signal $ac_signal" $as_echo "$as_me: exit $exit_status" } >&5 rm -f core *.core core.conftest.* && rm -f -r conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status ' 0 for ac_signal in 1 2 13 15; do trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal done ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -f -r conftest* confdefs.h $as_echo "/* confdefs.h */" > confdefs.h # Predefined preprocessor variables. cat >>confdefs.h <<_ACEOF #define PACKAGE_NAME "$PACKAGE_NAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_TARNAME "$PACKAGE_TARNAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_VERSION "$PACKAGE_VERSION" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_STRING "$PACKAGE_STRING" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_URL "$PACKAGE_URL" _ACEOF # Let the site file select an alternate cache file if it wants to. # Prefer an explicitly selected file to automatically selected ones. ac_site_file1=NONE ac_site_file2=NONE if test -n "$CONFIG_SITE"; then ac_site_file1=$CONFIG_SITE elif test "x$prefix" != xNONE; then ac_site_file1=$prefix/share/config.site ac_site_file2=$prefix/etc/config.site else ac_site_file1=$ac_default_prefix/share/config.site ac_site_file2=$ac_default_prefix/etc/config.site fi for ac_site_file in "$ac_site_file1" "$ac_site_file2" do test "x$ac_site_file" = xNONE && continue if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 $as_echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" fi done if test -r "$cache_file"; then # Some versions of bash will fail to source /dev/null (special files # actually), so we avoid doing that. DJGPP emulates it as a regular file. if test /dev/null != "$cache_file" && test -f "$cache_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 $as_echo "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . "$cache_file";; *) . "./$cache_file";; esac fi else { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 $as_echo "$as_me: creating cache $cache_file" >&6;} >$cache_file fi # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false for ac_var in $ac_precious_vars; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set eval ac_old_val=\$ac_cv_env_${ac_var}_value eval ac_new_val=\$ac_env_${ac_var}_value case $ac_old_set,$ac_new_set in set,) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then # differences in whitespace do not lead to failure. ac_old_val_w=`echo x $ac_old_val` ac_new_val_w=`echo x $ac_new_val` if test "$ac_old_val_w" != "$ac_new_val_w"; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 $as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} ac_cache_corrupted=: else { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 $as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} eval $ac_var=\$ac_old_val fi { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 $as_echo "$as_me: former value: \`$ac_old_val'" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 $as_echo "$as_me: current value: \`$ac_new_val'" >&2;} fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. *) as_fn_append ac_configure_args " '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 $as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} as_fn_error "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 fi ## -------------------- ## ## Main body of script. ## ## -------------------- ## ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu VERSION=`sed -n 's/.*version.*"\(.*\)".*/\1/p' $srcdir/include/version.h.in|tr -d ' '` PACKAGE=`sed -n 's/.*package.*"\(.*\)".*/\1/p' $srcdir/include/version.h.in|tr -d ' '` COPYYEARS="1997-2011" am__api_version='1.11' ac_aux_dir= for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do for ac_t in install-sh install.sh shtool; do if test -f "$ac_dir/$ac_t"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/$ac_t -c" break 2 fi done done if test -z "$ac_aux_dir"; then as_fn_error "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 fi # These three variables are undocumented and unsupported, # and are intended to be withdrawn in a future Autoconf release. # They can cause serious problems if a builder's source tree is in a directory # whose full name contains unusual characters. ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: # SysV /etc/install, /usr/sbin/install # SunOS /usr/etc/install # IRIX /sbin/install # AIX /bin/install # AmigaOS /C/install, which installs bootblocks on floppy discs # AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag # AFS /usr/afsws/bin/install, which mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # OS/2's system install, which has a completely different semantic # ./install, which can be erroneously created by make from ./install.sh. # Reject install programs that cannot install multiple files. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 $as_echo_n "checking for a BSD-compatible install... " >&6; } if test -z "$INSTALL"; then if test "${ac_cv_path_install+set}" = set; then : $as_echo_n "(cached) " >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. # Account for people who put trailing slashes in PATH elements. case $as_dir/ in #(( ./ | .// | /[cC]/* | \ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ /usr/ucb/* ) ;; *) # OSF1 and SCO ODT 3.0 have their own names for install. # Don't use installbsd from OSF since it installs stuff as root # by default. for ac_prog in ginstall scoinst install; do for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then if test $ac_prog = install && grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. : elif test $ac_prog = install && grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # program-specific install script used by HP pwplus--don't use. : else rm -rf conftest.one conftest.two conftest.dir echo one > conftest.one echo two > conftest.two mkdir conftest.dir if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && test -s conftest.one && test -s conftest.two && test -s conftest.dir/conftest.one && test -s conftest.dir/conftest.two then ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" break 3 fi fi fi done done ;; esac done IFS=$as_save_IFS rm -rf conftest.one conftest.two conftest.dir fi if test "${ac_cv_path_install+set}" = set; then INSTALL=$ac_cv_path_install else # As a last resort, use the slow shell script. Don't cache a # value for INSTALL within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. INSTALL=$ac_install_sh fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 $as_echo "$INSTALL" >&6; } # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 $as_echo_n "checking whether build environment is sane... " >&6; } # Just in case sleep 1 echo timestamp > conftest.file # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' ' case `pwd` in *[\\\"\#\$\&\'\`$am_lf]*) as_fn_error "unsafe absolute working directory name" "$LINENO" 5;; esac case $srcdir in *[\\\"\#\$\&\'\`$am_lf\ \ ]*) as_fn_error "unsafe srcdir value: \`$srcdir'" "$LINENO" 5;; esac # Do `set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` if test "$*" = "X"; then # -L didn't work. set X `ls -t "$srcdir/configure" conftest.file` fi rm -f conftest.file if test "$*" != "X $srcdir/configure conftest.file" \ && test "$*" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". as_fn_error "ls -t appears to fail. Make sure there is not a broken alias in your environment" "$LINENO" 5 fi test "$2" = conftest.file ) then # Ok. : else as_fn_error "newly created file is older than distributed files! Check your system clock" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } test "$program_prefix" != NONE && program_transform_name="s&^&$program_prefix&;$program_transform_name" # Use a double $ so make ignores it. test "$program_suffix" != NONE && program_transform_name="s&\$&$program_suffix&;$program_transform_name" # Double any \ or $. # By default was `s,x,x', remove it if useless. ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` # expand $ac_aux_dir to an absolute path am_aux_dir=`cd $ac_aux_dir && pwd` if test x"${MISSING+set}" != xset; then case $am_aux_dir in *\ * | *\ *) MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; *) MISSING="\${SHELL} $am_aux_dir/missing" ;; esac fi # Use eval to expand $SHELL if eval "$MISSING --run true"; then am_missing_run="$MISSING --run " else am_missing_run= { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`missing' script is too old or missing" >&5 $as_echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;} fi if test x"${install_sh}" != xset; then case $am_aux_dir in *\ * | *\ *) install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; *) install_sh="\${SHELL} $am_aux_dir/install-sh" esac fi # Installed binaries are usually stripped using `strip' when the user # run `make install-strip'. However `strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the `STRIP' environment variable to overrule this program. if test "$cross_compiling" != no; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. set dummy ${ac_tool_prefix}strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_STRIP+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$STRIP"; then ac_cv_prog_STRIP="$STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi STRIP=$ac_cv_prog_STRIP if test -n "$STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 $as_echo "$STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_STRIP"; then ac_ct_STRIP=$STRIP # Extract the first word of "strip", so it can be a program name with args. set dummy strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_STRIP"; then ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_STRIP="strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP if test -n "$ac_ct_STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 $as_echo "$ac_ct_STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_STRIP" = x; then STRIP=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac STRIP=$ac_ct_STRIP fi else STRIP="$ac_cv_prog_STRIP" fi fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 $as_echo_n "checking for a thread-safe mkdir -p... " >&6; } if test -z "$MKDIR_P"; then if test "${ac_cv_path_mkdir+set}" = set; then : $as_echo_n "(cached) " >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in mkdir gmkdir; do for ac_exec_ext in '' $ac_executable_extensions; do { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; } || continue case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( 'mkdir (GNU coreutils) '* | \ 'mkdir (coreutils) '* | \ 'mkdir (fileutils) '4.1*) ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext break 3;; esac done done done IFS=$as_save_IFS fi test -d ./--version && rmdir ./--version if test "${ac_cv_path_mkdir+set}" = set; then MKDIR_P="$ac_cv_path_mkdir -p" else # As a last resort, use the slow shell script. Don't cache a # value for MKDIR_P within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. MKDIR_P="$ac_install_sh -d" fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 $as_echo "$MKDIR_P" >&6; } mkdir_p="$MKDIR_P" case $mkdir_p in [\\/$]* | ?:[\\/]*) ;; */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; esac for ac_prog in gawk mawk nawk awk do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_AWK+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$AWK"; then ac_cv_prog_AWK="$AWK" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_AWK="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AWK=$ac_cv_prog_AWK if test -n "$AWK"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 $as_echo "$AWK" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$AWK" && break done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 $as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } set x ${MAKE-make} ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` if { as_var=ac_cv_prog_make_${ac_make}_set; eval "test \"\${$as_var+set}\" = set"; }; then : $as_echo_n "(cached) " >&6 else cat >conftest.make <<\_ACEOF SHELL = /bin/sh all: @echo '@@@%%%=$(MAKE)=@@@%%%' _ACEOF # GNU make sometimes prints "make[1]: Entering...", which would confuse us. case `${MAKE-make} -f conftest.make 2>/dev/null` in *@@@%%%=?*=@@@%%%*) eval ac_cv_prog_make_${ac_make}_set=yes;; *) eval ac_cv_prog_make_${ac_make}_set=no;; esac rm -f conftest.make fi if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } SET_MAKE= else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } SET_MAKE="MAKE=${MAKE-make}" fi rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." am__isrc=' -I$(srcdir)' # test to see if srcdir already configured if test -f $srcdir/config.status; then as_fn_error "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 fi fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi # Define the identity of the package. PACKAGE=$PACKAGE VERSION=$VERSION # Some tools Automake needs. ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} # We need awk for the "check" target. The system "awk" is bad on # some platforms. # Always define AMTAR for backward compatibility. AMTAR=${AMTAR-"${am_missing_run}tar"} am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -' # make sure MAKE sets ${MAKE} # Extract the first word of "gmake", so it can be a program name with args. set dummy gmake; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_path_MAKE+set}" = set; then : $as_echo_n "(cached) " >&6 else case $MAKE in [\\/]* | ?:[\\/]*) ac_cv_path_MAKE="$MAKE" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_MAKE="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_MAKE" && ac_cv_path_MAKE="no" ;; esac fi MAKE=$ac_cv_path_MAKE if test -n "$MAKE"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAKE" >&5 $as_echo "$MAKE" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test $MAKE = no; then unset ac_cv_path_MAKE # Extract the first word of "make", so it can be a program name with args. set dummy make; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_path_MAKE+set}" = set; then : $as_echo_n "(cached) " >&6 else case $MAKE in [\\/]* | ?:[\\/]*) ac_cv_path_MAKE="$MAKE" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_MAKE="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_MAKE" && ac_cv_path_MAKE="no" ;; esac fi MAKE=$ac_cv_path_MAKE if test -n "$MAKE"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAKE" >&5 $as_echo "$MAKE" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test $MAKE = no; then as_fn_error "can't locate a make." "$LINENO" 5 exit 1 fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 $as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } set x ${MAKE-make} ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` if { as_var=ac_cv_prog_make_${ac_make}_set; eval "test \"\${$as_var+set}\" = set"; }; then : $as_echo_n "(cached) " >&6 else cat >conftest.make <<\_ACEOF SHELL = /bin/sh all: @echo '@@@%%%=$(MAKE)=@@@%%%' _ACEOF # GNU make sometimes prints "make[1]: Entering...", which would confuse us. case `${MAKE-make} -f conftest.make 2>/dev/null` in *@@@%%%=?*=@@@%%%*) eval ac_cv_prog_make_${ac_make}_set=yes;; *) eval ac_cv_prog_make_${ac_make}_set=no;; esac rm -f conftest.make fi if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } SET_MAKE= else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } SET_MAKE="MAKE=${MAKE-make}" fi # compiler specifics ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_CC+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="${ac_tool_prefix}gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_ac_ct_CC+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CC="gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_CC+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="${ac_tool_prefix}cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_CC+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# != 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then for ac_prog in cl.exe do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_CC+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC for ac_prog in cl.exe do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_ac_ct_CC+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CC="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_CC" && break done if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi fi fi test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error "no acceptable C compiler found in \$PATH See \`config.log' for more details." "$LINENO" 5; } # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 $as_echo_n "checking whether the C compiler works... " >&6; } ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` # The possible output files: ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" ac_rmfiles= for ac_file in $ac_files do case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; * ) ac_rmfiles="$ac_rmfiles $ac_file";; esac done rm -f $ac_rmfiles if { { ac_try="$ac_link_default" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link_default") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. # So ignore a value of `no', otherwise this would lead to `EXEEXT = no' # in a Makefile. We should not override ac_cv_exeext if it was cached, # so that the user can short-circuit this test for compilers unknown to # Autoconf. for ac_file in $ac_files '' do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; [ab].out ) # We found the default executable, but exeext='' is most # certainly right. break;; *.* ) if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; then :; else ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` fi # We set ac_cv_exeext here because the later test for it is not # safe: cross compilers may not add the suffix if given an `-o' # argument, so we may need to know it at that point already. # Even if this section looks crufty: it has the advantage of # actually working. break;; * ) break;; esac done test "$ac_cv_exeext" = no && ac_cv_exeext= else ac_file='' fi if test -z "$ac_file"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { as_fn_set_status 77 as_fn_error "C compiler cannot create executables See \`config.log' for more details." "$LINENO" 5; }; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 $as_echo_n "checking for C compiler default output file name... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 $as_echo "$ac_file" >&6; } ac_exeext=$ac_cv_exeext rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 $as_echo_n "checking for suffix of executables... " >&6; } if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # If both `conftest.exe' and `conftest' are `present' (well, observable) # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will # work properly (i.e., refer to `conftest.exe'), while it won't with # `rm'. for ac_file in conftest.exe conftest conftest.*; do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` break;; * ) break;; esac done else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error "cannot compute suffix of executables: cannot compile and link See \`config.log' for more details." "$LINENO" 5; } fi rm -f conftest conftest$ac_cv_exeext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 $as_echo "$ac_cv_exeext" >&6; } rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { FILE *f = fopen ("conftest.out", "w"); return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF ac_clean_files="$ac_clean_files conftest.out" # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 $as_echo_n "checking whether we are cross compiling... " >&6; } if test "$cross_compiling" != yes; then { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if { ac_try='./conftest$ac_cv_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error "cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details." "$LINENO" 5; } fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 $as_echo "$cross_compiling" >&6; } rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 $as_echo_n "checking for suffix of object files... " >&6; } if test "${ac_cv_objext+set}" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.o conftest.obj if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : for ac_file in conftest.o conftest.obj conftest.*; do test -f "$ac_file" || continue; case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` break;; esac done else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error "cannot compute suffix of object files: cannot compile See \`config.log' for more details." "$LINENO" 5; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 $as_echo "$ac_cv_objext" >&6; } OBJEXT=$ac_cv_objext ac_objext=$OBJEXT { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 $as_echo_n "checking whether we are using the GNU C compiler... " >&6; } if test "${ac_cv_c_compiler_gnu+set}" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_compiler_gnu=yes else ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 $as_echo "$ac_cv_c_compiler_gnu" >&6; } if test $ac_compiler_gnu = yes; then GCC=yes else GCC= fi ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 $as_echo_n "checking whether $CC accepts -g... " >&6; } if test "${ac_cv_prog_cc_g+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes ac_cv_prog_cc_g=no CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes else CFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 $as_echo "$ac_cv_prog_cc_g" >&6; } if test "$ac_test_CFLAGS" = set; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 $as_echo_n "checking for $CC option to accept ISO C89... " >&6; } if test "${ac_cv_prog_cc_c89+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_cv_prog_cc_c89=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not '\xHH' hex character constants. These don't provoke an error unfortunately, instead are silently treated as 'x'. The following induces an error, until -std is added to get proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an array size at least. It's necessary to write '\x00'==0 to get something that's true only with -std. */ int osf4_cc_array ['\x00' == 0 ? 1 : -1]; /* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters inside strings and character constants. */ #define FOO(x) 'x' int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); int argc; char **argv; int main () { return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ; return 0; } _ACEOF for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_c89=$ac_arg fi rm -f core conftest.err conftest.$ac_objext test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi # AC_CACHE_VAL case "x$ac_cv_prog_cc_c89" in x) { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 $as_echo "none needed" >&6; } ;; xno) { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 $as_echo "unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c89" { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 $as_echo "$ac_cv_prog_cc_c89" >&6; } ;; esac if test "x$ac_cv_prog_cc_c89" != xno; then : fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu DEPDIR="${am__leading_dot}deps" ac_config_commands="$ac_config_commands depfiles" am_make=${MAKE-make} cat > confinc << 'END' am__doit: @echo this is the am__doit target .PHONY: am__doit END # If we don't find an include directive, just comment out the code. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5 $as_echo_n "checking for style of include used by $am_make... " >&6; } am__include="#" am__quote= _am_result=none # First try GNU make style include. echo "include confinc" > confmf # Ignore all kinds of additional output from `make'. case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=include am__quote= _am_result=GNU ;; esac # Now try BSD make style include. if test "$am__include" = "#"; then echo '.include "confinc"' > confmf case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=.include am__quote="\"" _am_result=BSD ;; esac fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5 $as_echo "$_am_result" >&6; } rm -f confinc confmf # Check whether --enable-dependency-tracking was given. if test "${enable_dependency_tracking+set}" = set; then : enableval=$enable_dependency_tracking; fi if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' fi if test "x$enable_dependency_tracking" != xno; then AMDEP_TRUE= AMDEP_FALSE='#' else AMDEP_TRUE='#' AMDEP_FALSE= fi depcc="$CC" am_compiler_list= { $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 $as_echo_n "checking dependency style of $depcc... " >&6; } if test "${am_cv_CC_dependencies_compiler_type+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named `D' -- because `-MD' means `put the output # in D'. mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_CC_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` fi am__universal=false case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with # Solaris 8's {/usr,}/bin/sh. touch sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with `-c' and `-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle `-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # after this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvisualcpp | msvcmsys) # This compiler won't grok `-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_CC_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_CC_dependencies_compiler_type=none fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 $as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type if test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then am__fastdepCC_TRUE= am__fastdepCC_FALSE='#' else am__fastdepCC_TRUE='#' am__fastdepCC_FALSE= fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for function prototypes" >&5 $as_echo_n "checking for function prototypes... " >&6; } if test "$ac_cv_prog_cc_c89" != no; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } $as_echo "#define PROTOTYPES 1" >>confdefs.h $as_echo "#define __PROTOTYPES 1" >>confdefs.h else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 $as_echo_n "checking how to run the C preprocessor... " >&6; } # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if test "${ac_cv_prog_CPP+set}" = set; then : $as_echo_n "(cached) " >&6 else # Double quotes because CPP needs to be expanded for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" do ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.err conftest.$ac_ext if $ac_preproc_ok; then : break fi done ac_cv_prog_CPP=$CPP fi CPP=$ac_cv_prog_CPP else ac_cv_prog_CPP=$CPP fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 $as_echo "$CPP" >&6; } ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error "C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details." "$LINENO" 5; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 $as_echo_n "checking for grep that handles long lines and -e... " >&6; } if test "${ac_cv_path_GREP+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -z "$GREP"; then ac_path_GREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in grep ggrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue # Check for GNU ac_path_GREP and select it if it is found. # Check for GNU $ac_path_GREP case `"$ac_path_GREP" --version 2>&1` in *GNU*) ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'GREP' >> "conftest.nl" "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_GREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_GREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_GREP"; then as_fn_error "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_GREP=$GREP fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 $as_echo "$ac_cv_path_GREP" >&6; } GREP="$ac_cv_path_GREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 $as_echo_n "checking for egrep... " >&6; } if test "${ac_cv_path_EGREP+set}" = set; then : $as_echo_n "(cached) " >&6 else if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 then ac_cv_path_EGREP="$GREP -E" else if test -z "$EGREP"; then ac_path_EGREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in egrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue # Check for GNU ac_path_EGREP and select it if it is found. # Check for GNU $ac_path_EGREP case `"$ac_path_EGREP" --version 2>&1` in *GNU*) ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'EGREP' >> "conftest.nl" "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_EGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_EGREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_EGREP"; then as_fn_error "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_EGREP=$EGREP fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 $as_echo "$ac_cv_path_EGREP" >&6; } EGREP="$ac_cv_path_EGREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 $as_echo_n "checking for ANSI C header files... " >&6; } if test "${ac_cv_header_stdc+set}" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_header_stdc=yes else ac_cv_header_stdc=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "memchr" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "free" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : : else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #if ((' ' & 0x0FF) == 0x020) # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #else # define ISLOWER(c) \ (('a' <= (c) && (c) <= 'i') \ || ('j' <= (c) && (c) <= 'r') \ || ('s' <= (c) && (c) <= 'z')) # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) #endif #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) return 2; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : else ac_cv_header_stdc=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 $as_echo "$ac_cv_header_stdc" >&6; } if test $ac_cv_header_stdc = yes; then $as_echo "#define STDC_HEADERS 1" >>confdefs.h fi # On IRIX 5.3, sys/types and inttypes.h are conflicting. for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ inttypes.h stdint.h unistd.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default " eval as_val=\$$as_ac_Header if test "x$as_val" = x""yes; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done if test "$ac_cv_prog_cc_stdc" != no; then U= ANSI2KNR= else U=_ ANSI2KNR=./ansi2knr fi # Ensure some checks needed by ansi2knr itself. for ac_header in string.h do : ac_fn_c_check_header_mongrel "$LINENO" "string.h" "ac_cv_header_string_h" "$ac_includes_default" if test "x$ac_cv_header_string_h" = x""yes; then : cat >>confdefs.h <<_ACEOF #define HAVE_STRING_H 1 _ACEOF fi done ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 $as_echo_n "checking how to run the C preprocessor... " >&6; } # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if test "${ac_cv_prog_CPP+set}" = set; then : $as_echo_n "(cached) " >&6 else # Double quotes because CPP needs to be expanded for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" do ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.err conftest.$ac_ext if $ac_preproc_ok; then : break fi done ac_cv_prog_CPP=$CPP fi CPP=$ac_cv_prog_CPP else ac_cv_prog_CPP=$CPP fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 $as_echo "$CPP" >&6; } ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error "C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details." "$LINENO" 5; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5 $as_echo_n "checking for an ANSI C-conforming const... " >&6; } if test "${ac_cv_c_const+set}" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { /* FIXME: Include the comments suggested by Paul. */ #ifndef __cplusplus /* Ultrix mips cc rejects this. */ typedef int charset[2]; const charset cs; /* SunOS 4.1.1 cc rejects this. */ char const *const *pcpcc; char **ppc; /* NEC SVR4.0.2 mips cc rejects this. */ struct point {int x, y;}; static struct point const zero = {0,0}; /* AIX XL C 1.02.0.0 rejects this. It does not let you subtract one const X* pointer from another in an arm of an if-expression whose if-part is not a constant expression */ const char *g = "string"; pcpcc = &g + (g ? g-g : 0); /* HPUX 7.0 cc rejects these. */ ++pcpcc; ppc = (char**) pcpcc; pcpcc = (char const *const *) ppc; { /* SCO 3.2v4 cc rejects this. */ char *t; char const *s = 0 ? (char *) 0 : (char const *) 0; *t++ = 0; if (s) return 0; } { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ int x[] = {25, 17}; const int *foo = &x[0]; ++foo; } { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ typedef const int *iptr; iptr p = 0; ++p; } { /* AIX XL C 1.02.0.0 rejects this saying "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ struct s { int j; const int *ap[3]; }; struct s *b; b->j = 5; } { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ const int foo = 10; if (!foo) return 0; } return !cs[0] && !zero.x; #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_c_const=yes else ac_cv_c_const=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_const" >&5 $as_echo "$ac_cv_c_const" >&6; } if test $ac_cv_c_const = no; then $as_echo "#define const /**/" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for inline" >&5 $as_echo_n "checking for inline... " >&6; } if test "${ac_cv_c_inline+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_cv_c_inline=no for ac_kw in inline __inline__ __inline; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifndef __cplusplus typedef int foo_t; static $ac_kw foo_t static_foo () {return 0; } $ac_kw foo_t foo () {return 0; } #endif _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_c_inline=$ac_kw fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext test "$ac_cv_c_inline" != no && break done fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_inline" >&5 $as_echo "$ac_cv_c_inline" >&6; } case $ac_cv_c_inline in inline | yes) ;; *) case $ac_cv_c_inline in no) ac_val=;; *) ac_val=$ac_cv_c_inline;; esac cat >>confdefs.h <<_ACEOF #ifndef __cplusplus #define inline $ac_val #endif _ACEOF ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for preprocessor stringizing operator" >&5 $as_echo_n "checking for preprocessor stringizing operator... " >&6; } if test "${ac_cv_c_stringize+set}" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #define x(y) #y char *s = x(teststring); _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "#teststring" >/dev/null 2>&1; then : ac_cv_c_stringize=no else ac_cv_c_stringize=yes fi rm -f conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_stringize" >&5 $as_echo "$ac_cv_c_stringize" >&6; } if test $ac_cv_c_stringize = yes; then $as_echo "#define HAVE_STRINGIZE 1" >>confdefs.h fi # check includes/headers { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 $as_echo_n "checking for ANSI C header files... " >&6; } if test "${ac_cv_header_stdc+set}" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_header_stdc=yes else ac_cv_header_stdc=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "memchr" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "free" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : : else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #if ((' ' & 0x0FF) == 0x020) # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #else # define ISLOWER(c) \ (('a' <= (c) && (c) <= 'i') \ || ('j' <= (c) && (c) <= 'r') \ || ('s' <= (c) && (c) <= 'z')) # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) #endif #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) return 2; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : else ac_cv_header_stdc=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 $as_echo "$ac_cv_header_stdc" >&6; } if test $ac_cv_header_stdc = yes; then $as_echo "#define STDC_HEADERS 1" >>confdefs.h fi for ac_header in ctype.h errno.h fcntl.h limits.h pty.h malloc.h memory.h \ siginfo.h string.h strings.h stropts.h sys/types.h \ sys/wait.h unistd.h util.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" eval as_val=\$$as_ac_Header if test "x$as_val" = x""yes; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in sysexits.h do : ac_fn_c_check_header_mongrel "$LINENO" "sysexits.h" "ac_cv_header_sysexits_h" "$ac_includes_default" if test "x$ac_cv_header_sysexits_h" = x""yes; then : cat >>confdefs.h <<_ACEOF #define HAVE_SYSEXITS_H 1 _ACEOF fi done # check functions for ac_func in memcpy memmove memset strerror strchr \ strrchr strstr strtok strrtok index rindex unsetenv do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" eval as_val=\$$as_ac_var if test "x$as_val" = x""yes; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done for ac_func in openpty do : ac_fn_c_check_func "$LINENO" "openpty" "ac_cv_func_openpty" if test "x$ac_cv_func_openpty" = x""yes; then : cat >>confdefs.h <<_ACEOF #define HAVE_OPENPTY 1 _ACEOF openpty=1 else openpty=0 fi done # openpty() is not in the default libraries. See if it is in some other lib. if test $openpty = 0; then for lib in util; do as_ac_Lib=`$as_echo "ac_cv_lib_$lib''_openpty" | $as_tr_sh` { $as_echo "$as_me:${as_lineno-$LINENO}: checking for openpty in -l$lib" >&5 $as_echo_n "checking for openpty in -l$lib... " >&6; } if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-l$lib $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char openpty (); int main () { return openpty (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : eval "$as_ac_Lib=yes" else eval "$as_ac_Lib=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi eval ac_res=\$$as_ac_Lib { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval as_val=\$$as_ac_Lib if test "x$as_val" = x""yes; then : $as_echo "#define HAVE_OPENPTY 1" >>confdefs.h LIBS="$LIBS -l$lib"; openpty=1; break fi done fi # If we dont have openpty, then look for /dev/ptmx for use by our own # openpty(). if test $openpty = 0; then # This check (partially) comes from expect's configure { $as_echo "$as_me:${as_lineno-$LINENO}: checking for SVR4 style pty allocation" >&5 $as_echo_n "checking for SVR4 style pty allocation... " >&6; } if test -r /dev/ptmx ; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } $as_echo "#define HAVE_PTMX 1" >>confdefs.h # Some systems need libpt.a to use /dev/ptmx for ac_func in ptsname do : ac_fn_c_check_func "$LINENO" "ptsname" "ac_cv_func_ptsname" if test "x$ac_cv_func_ptsname" = x""yes; then : cat >>confdefs.h <<_ACEOF #define HAVE_PTSNAME 1 _ACEOF fi done if test $ac_cv_func_ptsname+set != set; then # ptsname is not in the default libraries. for lib in pt; do as_ac_Lib=`$as_echo "ac_cv_lib_$lib''_ptsname" | $as_tr_sh` { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ptsname in -l$lib" >&5 $as_echo_n "checking for ptsname in -l$lib... " >&6; } if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-l$lib $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char ptsname (); int main () { return ptsname (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : eval "$as_ac_Lib=yes" else eval "$as_ac_Lib=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi eval ac_res=\$$as_ac_Lib { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval as_val=\$$as_ac_Lib if test "x$as_val" = x""yes; then : LIBS="$LIBS -l$lib"; break fi done fi else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # In OSF/1 case, SVR4 are somewhat different. # Gregory Depp 17Aug93 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for OSF/1 style pty allocation" >&5 $as_echo_n "checking for OSF/1 style pty allocation... " >&6; } if test -r /dev/ptmx_bsd ; then $as_echo "#define HAVE_PTMX_OSF 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi # type checks { $as_echo "$as_me:${as_lineno-$LINENO}: checking return type of signal handlers" >&5 $as_echo_n "checking return type of signal handlers... " >&6; } if test "${ac_cv_type_signal+set}" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { return *(signal (0, 0)) (0) == 1; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_type_signal=int else ac_cv_type_signal=void fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_signal" >&5 $as_echo "$ac_cv_type_signal" >&6; } cat >>confdefs.h <<_ACEOF #define RETSIGTYPE $ac_cv_type_signal _ACEOF ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default" if test "x$ac_cv_type_size_t" = x""yes; then : else cat >>confdefs.h <<_ACEOF #define size_t unsigned int _ACEOF fi # Package-specific options/knobs # # Check if user wants us to create LOCALSTATEDIR. If it's a package-system, # they might create it themselves for book-keeping sake; eg: NetBSD { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to create the local state directory at install time" >&5 $as_echo_n "checking whether to create the local state directory at install time... " >&6; } # Check whether --enable-mk-localstatedir was given. if test "${enable_mk_localstatedir+set}" = set; then : enableval=$enable_mk_localstatedir; if test "$enable_mk_localstatedir" = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } enable_mk_localstatedir="yes" fi if test "${enable_mk_localstatedir}" = yes; then MK_LCLSTATEDIR_TRUE= MK_LCLSTATEDIR_FALSE='#' else MK_LCLSTATEDIR_TRUE='#' MK_LCLSTATEDIR_FALSE= fi # Check if user wants us to install sample configurations into the sysconfdir. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to install sample .conf files in sysconfdir" >&5 $as_echo_n "checking whether to install sample .conf files in sysconfdir... " >&6; } # Check whether --enable-conf-install was given. if test "${enable_conf_install+set}" = set; then : enableval=$enable_conf_install; if test "$enable_conf_install" = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } enable_conf_install="yes" fi if test "${enable_conf_install}" = yes; then CONF_INSTALL_TRUE= CONF_INSTALL_FALSE='#' else CONF_INSTALL_TRUE='#' CONF_INSTALL_FALSE= fi # Configure for subversion revision control system instead of CVS. SVN_FSTYPE="--fs-type fsfs" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether subversion" >&5 $as_echo_n "checking whether subversion... " >&6; } # Check whether --with-svn was given. if test "${with_svn+set}" = set; then : withval=$with_svn; case "$withval" in yes) { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } RCSSYS="svn" ;; fsfs) { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes fstype fsfs" >&5 $as_echo "yes fstype fsfs" >&6; } RCSSYS="svn" SVN_FSTYPE="--fs-type fsfs" ;; bdb) { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes fstype bdb" >&5 $as_echo "yes fstype bdb" >&6; } RCSSYS="svn" SVN_FSTYPE="--fs-type bdb" ;; no) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } RCSSYS="cvs" ;; *) as_fn_error "unknown svn fs-type $withval" "$LINENO" 5 esac else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } RCSSYS="cvs" fi rd_cv_RCSSYS=$RCSSYS # Check for a preference for using mail addresses like rancid+group # instead of the standard rancid-group { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether mail addresses should be in the rancid+ form" >&5 $as_echo_n "checking whether mail addresses should be in the rancid+ form... " >&6; } # Check whether --enable-mail-plus was given. if test "${enable_mail_plus+set}" = set; then : enableval=$enable_mail_plus; if test "$enable_mail_plus" = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } MAILPLUS="rancid+" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } MAILPLUS="rancid-" fi else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } MAILPLUS="rancid-" fi rd_cv_MAILPLUS=$MAILPLUS # Check for a preference for using mail addresses like rancid+admin-group # instead of the standard rancid-admin-group { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether admin mail addresses should be in the rancid-admin+ form" >&5 $as_echo_n "checking whether admin mail addresses should be in the rancid-admin+ form... " >&6; } # Check whether --enable-adminmail-plus was given. if test "${enable_adminmail_plus+set}" = set; then : enableval=$enable_adminmail_plus; if test "$enable_adminmail_plus" = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: rancid-admin+" >&5 $as_echo "rancid-admin+" >&6; } ADMINMAILPLUS="rancid-admin+" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${MAILPLUS}admin-" >&5 $as_echo "${MAILPLUS}admin-" >&6; } ADMINMAILPLUS="${MAILPLUS}admin-" fi else { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${MAILPLUS}admin-" >&5 $as_echo "${MAILPLUS}admin-" >&6; } ADMINMAILPLUS="${MAILPLUS}admin-" fi rd_cv_ADMINMAILPLUS=$ADMINMAILPLUS # Extract the first word of "dirname", so it can be a program name with args. set dummy dirname; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_path_DIRNAME+set}" = set; then : $as_echo_n "(cached) " >&6 else case $DIRNAME in [\\/]* | ?:[\\/]*) ac_cv_path_DIRNAME="$DIRNAME" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_DIRNAME="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_DIRNAME" && ac_cv_path_DIRNAME="no" ;; esac fi DIRNAME=$ac_cv_path_DIRNAME if test -n "$DIRNAME"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DIRNAME" >&5 $as_echo "$DIRNAME" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # locate GNU diff (one supporting the -u option) { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a diff(1) that supports -u" >&5 $as_echo_n "checking for a diff(1) that supports -u... " >&6; } _DIFF_PATH=`echo $PATH:${prefix}/bin:/usr/bin:/usr/pkg/bin:/usr/local/bin:/usr/gnu/bin:/usr/contrib/bin | sed -e 's/:/ /g'` for _diff in ${_DIFF_PATH} ; do if test -e ${_diff}/diff ; then ${_diff}/diff -u -4 /dev/null /dev/null > /dev/null 2>&1 if test $? -ne 0; then # linux/gnu shit has to change options that have been around # since organized religion; see if -U 4 works. ${_diff}/diff -U 4 /dev/null /dev/null > /dev/null 2>&1 if test $? -ne 0; then if test "${ADIFF}" = "" ; then ADIFF="${_diff}/diff" ADIFF_CMD="diff -c -4" fi else DIFF="${_diff}/diff" DIFF_CMD="diff -U 4" break fi else DIFF="${_diff}/diff" DIFF_CMD="diff -u -4" break fi fi done if test "$DIFF" = "" ; then DIFF=$ADIFF DIFF_CMD=$ADIFF_CMD fi if test "$DIFF" = "" ; then as_fn_error "can't locate diff." "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${DIFF_CMD}" >&5 $as_echo "${DIFF_CMD}" >&6; } rd_cv_DIFF=$DIFF rd_cv_DIFF_CMD=$DIFF_CMD # Extract the first word of "sendmail", so it can be a program name with args. set dummy sendmail; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_path_SENDMAIL+set}" = set; then : $as_echo_n "(cached) " >&6 else case $SENDMAIL in [\\/]* | ?:[\\/]*) ac_cv_path_SENDMAIL="$SENDMAIL" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_dummy="/usr/sbin:/usr/bin:/usr/lib" for as_dir in $as_dummy do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_SENDMAIL="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_SENDMAIL" && ac_cv_path_SENDMAIL="no" ;; esac fi SENDMAIL=$ac_cv_path_SENDMAIL if test -n "$SENDMAIL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $SENDMAIL" >&5 $as_echo "$SENDMAIL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # Find an appropriate tar for use in "dist" targets. A "best guess" # is good enough -- if we can't find GNU tar, we don't really care. for ac_prog in gnutar gtar tar do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_TAR+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$TAR"; then ac_cv_prog_TAR="$TAR" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_TAR="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi TAR=$ac_cv_prog_TAR if test -n "$TAR"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $TAR" >&5 $as_echo "$TAR" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$TAR" && break done for ac_prog in automake do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_AUTOMAKE+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$AUTOMAKE"; then ac_cv_prog_AUTOMAKE="$AUTOMAKE" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_AUTOMAKE="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AUTOMAKE=$ac_cv_prog_AUTOMAKE if test -n "$AUTOMAKE"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AUTOMAKE" >&5 $as_echo "$AUTOMAKE" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$AUTOMAKE" && break done # Extract the first word of "perl5", so it can be a program name with args. set dummy perl5; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_path_PERLV_PATH+set}" = set; then : $as_echo_n "(cached) " >&6 else case $PERLV_PATH in [\\/]* | ?:[\\/]*) ac_cv_path_PERLV_PATH="$PERLV_PATH" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_PERLV_PATH="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_PERLV_PATH" && ac_cv_path_PERLV_PATH="no" ;; esac fi PERLV_PATH=$ac_cv_path_PERLV_PATH if test -n "$PERLV_PATH"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PERLV_PATH" >&5 $as_echo "$PERLV_PATH" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test $PERLV_PATH = no; then unset ac_cv_path_PERLV_PATH # Extract the first word of "perl", so it can be a program name with args. set dummy perl; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_path_PERLV_PATH+set}" = set; then : $as_echo_n "(cached) " >&6 else case $PERLV_PATH in [\\/]* | ?:[\\/]*) ac_cv_path_PERLV_PATH="$PERLV_PATH" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_PERLV_PATH="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_PERLV_PATH" && ac_cv_path_PERLV_PATH="no" ;; esac fi PERLV_PATH=$ac_cv_path_PERLV_PATH if test -n "$PERLV_PATH"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PERLV_PATH" >&5 $as_echo "$PERLV_PATH" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test $PERLV_PATH = no; then as_fn_error "can't locate a suitable perl5." "$LINENO" 5 exit 1 else $PERLV_PATH -e 'require 5;' if test $? -ne 0 ; then as_fn_error "can't locate a suitable perl5." "$LINENO" 5 exit 1 fi fi fi PERLV=`basename $PERLV_PATH` # Extract the first word of "expect", so it can be a program name with args. set dummy expect; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_path_EXPECT_PATH+set}" = set; then : $as_echo_n "(cached) " >&6 else case $EXPECT_PATH in [\\/]* | ?:[\\/]*) ac_cv_path_EXPECT_PATH="$EXPECT_PATH" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_EXPECT_PATH="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_EXPECT_PATH" && ac_cv_path_EXPECT_PATH="no" ;; esac fi EXPECT_PATH=$ac_cv_path_EXPECT_PATH if test -n "$EXPECT_PATH"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $EXPECT_PATH" >&5 $as_echo "$EXPECT_PATH" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test $EXPECT_PATH = no; then as_fn_error "can't locate expect." "$LINENO" 5 fi # locate ping and it's syntax # Extract the first word of "ping", so it can be a program name with args. set dummy ping; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_path_PING_PATH+set}" = set; then : $as_echo_n "(cached) " >&6 else case $PING_PATH in [\\/]* | ?:[\\/]*) ac_cv_path_PING_PATH="$PING_PATH" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/sbin$PATH_SEPARATOR/usr/sbin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_PING_PATH="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_PING_PATH" && ac_cv_path_PING_PATH="no" ;; esac fi PING_PATH=$ac_cv_path_PING_PATH if test -n "$PING_PATH"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PING_PATH" >&5 $as_echo "$PING_PATH" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test $PING_PATH = no; then as_fn_error "can't locate ping." "$LINENO" 5 exit 1 fi # ping seems to take one of two formats for count (N) # BSD: ping -c N host # SVR: ping host N $PING_PATH -c 1 -v 127.0.0.1 > /dev/null 2>&1 if test $? -eq 0 ; then LG_PING_CMD="$PING_PATH -c 1" else $PING_PATH 127.0.0.1 56 1 > /dev/null 2>&1 if test $? -eq 0 ; then LG_PING_CMD="$PING_PATH" else # cygwin using windows ping? $PING_PATH -n 1 127.0.0.1 > /dev/null 2>&1 if test $? -eq 0 ; then LG_PING_CMD="$PING_PATH -n 1" else as_fn_error "can't figure out how to pass count == 1 to $PING_PATH." "$LINENO" 5 exit 1 fi fi fi rd_cv_lg_ping_cmd=$LG_PING_CMD # locate tools to build $PATH for rancid.conf. order is significant. want # to be sure that we pick up the the proper diff and ucbmail in # etc/rancid.conf. ENV_PATH="`dirname $PERLV_PATH`:`dirname $EXPECT_PATH`:`dirname $SENDMAIL`" ENV_PATH="$ENV_PATH:`dirname $DIRNAME`:`dirname $DIFF`" if test $RCSSYS = "cvs" ; then # Extract the first word of "cvs", so it can be a program name with args. set dummy cvs; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_path_CVS+set}" = set; then : $as_echo_n "(cached) " >&6 else case $CVS in [\\/]* | ?:[\\/]*) ac_cv_path_CVS="$CVS" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_CVS="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_CVS" && ac_cv_path_CVS="no" ;; esac fi CVS=$ac_cv_path_CVS if test -n "$CVS"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CVS" >&5 $as_echo "$CVS" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi ENV_PATH="$ENV_PATH:`dirname $ac_cv_path_CVS`" else # Extract the first word of "svn", so it can be a program name with args. set dummy svn; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_path_SVN+set}" = set; then : $as_echo_n "(cached) " >&6 else case $SVN in [\\/]* | ?:[\\/]*) ac_cv_path_SVN="$SVN" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_SVN="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_SVN" && ac_cv_path_SVN="no" ;; esac fi SVN=$ac_cv_path_SVN if test -n "$SVN"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $SVN" >&5 $as_echo "$SVN" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi ENV_PATH="$ENV_PATH:`dirname $ac_cv_path_SVN`" fi # Extract the first word of "comm", so it can be a program name with args. set dummy comm; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_path_COMM+set}" = set; then : $as_echo_n "(cached) " >&6 else case $COMM in [\\/]* | ?:[\\/]*) ac_cv_path_COMM="$COMM" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_COMM="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_COMM" && ac_cv_path_COMM="no" ;; esac fi COMM=$ac_cv_path_COMM if test -n "$COMM"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $COMM" >&5 $as_echo "$COMM" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi ENV_PATH="$ENV_PATH:`dirname $ac_cv_path_COMM`" # Extract the first word of "find", so it can be a program name with args. set dummy find; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_path_FIND+set}" = set; then : $as_echo_n "(cached) " >&6 else case $FIND in [\\/]* | ?:[\\/]*) ac_cv_path_FIND="$FIND" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_FIND="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_FIND" && ac_cv_path_FIND="no" ;; esac fi FIND=$ac_cv_path_FIND if test -n "$FIND"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $FIND" >&5 $as_echo "$FIND" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi ENV_PATH="$ENV_PATH:`dirname $ac_cv_path_FIND`" # Extract the first word of "grep", so it can be a program name with args. set dummy grep; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_path_GREP+set}" = set; then : $as_echo_n "(cached) " >&6 else case $GREP in [\\/]* | ?:[\\/]*) ac_cv_path_GREP="$GREP" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_GREP="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_GREP" && ac_cv_path_GREP="no" ;; esac fi GREP=$ac_cv_path_GREP if test -n "$GREP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GREP" >&5 $as_echo "$GREP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi ENV_PATH="$ENV_PATH:`dirname $ac_cv_path_GREP`" # Extract the first word of "id", so it can be a program name with args. set dummy id; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_path_ID+set}" = set; then : $as_echo_n "(cached) " >&6 else case $ID in [\\/]* | ?:[\\/]*) ac_cv_path_ID="$ID" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_ID="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_ID" && ac_cv_path_ID="no" ;; esac fi ID=$ac_cv_path_ID if test -n "$ID"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ID" >&5 $as_echo "$ID" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi ENV_PATH="$ENV_PATH:`dirname $ac_cv_path_ID`" # Extract the first word of "mkdir", so it can be a program name with args. set dummy mkdir; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_path_MKDIR+set}" = set; then : $as_echo_n "(cached) " >&6 else case $MKDIR in [\\/]* | ?:[\\/]*) ac_cv_path_MKDIR="$MKDIR" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_MKDIR="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_MKDIR" && ac_cv_path_MKDIR="no" ;; esac fi MKDIR=$ac_cv_path_MKDIR if test -n "$MKDIR"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR" >&5 $as_echo "$MKDIR" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi ENV_PATH="$ENV_PATH:`dirname $ac_cv_path_MKDIR`" # Extract the first word of "rsh", so it can be a program name with args. set dummy rsh; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_path_RSH+set}" = set; then : $as_echo_n "(cached) " >&6 else case $RSH in [\\/]* | ?:[\\/]*) ac_cv_path_RSH="$RSH" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_RSH="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_RSH" && ac_cv_path_RSH="no" ;; esac fi RSH=$ac_cv_path_RSH if test -n "$RSH"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RSH" >&5 $as_echo "$RSH" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi ENV_PATH="$ENV_PATH:`dirname $ac_cv_path_RSH`" # Extract the first word of "sort", so it can be a program name with args. set dummy sort; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_path_SORT+set}" = set; then : $as_echo_n "(cached) " >&6 else case $SORT in [\\/]* | ?:[\\/]*) ac_cv_path_SORT="$SORT" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_SORT="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_SORT" && ac_cv_path_SORT="no" ;; esac fi SORT=$ac_cv_path_SORT if test -n "$SORT"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $SORT" >&5 $as_echo "$SORT" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi ENV_PATH="$ENV_PATH:`dirname $ac_cv_path_SORT`" # Extract the first word of "ssh", so it can be a program name with args. set dummy ssh; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_path_SSH+set}" = set; then : $as_echo_n "(cached) " >&6 else case $SSH in [\\/]* | ?:[\\/]*) ac_cv_path_SSH="$SSH" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_SSH="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_SSH" && ac_cv_path_SSH="no" ;; esac fi SSH=$ac_cv_path_SSH if test -n "$SSH"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $SSH" >&5 $as_echo "$SSH" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi ENV_PATH="$ENV_PATH:`dirname $ac_cv_path_SSH`" # Extract the first word of "telnet", so it can be a program name with args. set dummy telnet; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_path_TELNET+set}" = set; then : $as_echo_n "(cached) " >&6 else case $TELNET in [\\/]* | ?:[\\/]*) ac_cv_path_TELNET="$TELNET" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_TELNET="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_TELNET" && ac_cv_path_TELNET="no" ;; esac fi TELNET=$ac_cv_path_TELNET if test -n "$TELNET"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $TELNET" >&5 $as_echo "$TELNET" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi ENV_PATH="$ENV_PATH:`dirname $ac_cv_path_TELNET`" # Extract the first word of "touch", so it can be a program name with args. set dummy touch; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_path_TOUCH+set}" = set; then : $as_echo_n "(cached) " >&6 else case $TOUCH in [\\/]* | ?:[\\/]*) ac_cv_path_TOUCH="$TOUCH" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_TOUCH="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_TOUCH" && ac_cv_path_TOUCH="no" ;; esac fi TOUCH=$ac_cv_path_TOUCH if test -n "$TOUCH"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $TOUCH" >&5 $as_echo "$TOUCH" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi ENV_PATH="$ENV_PATH:`dirname $ac_cv_path_TOUCH`" ENV_PATH="$ENV_PATH:/usr/local/bin:/usr/bin" ENV_PATH=`echo $ENV_PATH | $PERLV_PATH -e 'foreach $x(split(":",<>)){next unless (length($x));push(@F, $x),$seen{$x}=1 unless (defined $seen{$x});}print join(":",@F);'` ac_cv_env_path=$ENV_PATH ac_config_files="$ac_config_files Makefile" ac_config_files="$ac_config_files bin/Makefile" ac_config_files="$ac_config_files etc/Makefile" ac_config_files="$ac_config_files include/Makefile" ac_config_files="$ac_config_files man/Makefile" ac_config_files="$ac_config_files share/Makefile" ac_config_files="$ac_config_files include/version.h" # this is not a header in the sense of # AC_CONFIG_HEADERS will cause # autoheader to overwrite it, while all # want is simple variable replacement # autoheader bits ac_config_headers="$ac_config_headers include/config.h" ac_config_files="$ac_config_files bin/control_rancid bin/par bin/rancid-fe" ac_config_files="$ac_config_files bin/agmrancid" ac_config_files="$ac_config_files bin/alogin bin/arancid" ac_config_files="$ac_config_files bin/arrancid" ac_config_files="$ac_config_files bin/avologin bin/avorancid" ac_config_files="$ac_config_files bin/blogin bin/brancid" ac_config_files="$ac_config_files bin/cat5rancid bin/clogin bin/rancid" ac_config_files="$ac_config_files bin/cssrancid" ac_config_files="$ac_config_files bin/elogin bin/erancid" ac_config_files="$ac_config_files bin/f5rancid" ac_config_files="$ac_config_files bin/f10rancid" ac_config_files="$ac_config_files bin/flogin bin/francid" ac_config_files="$ac_config_files bin/fnlogin bin/fnrancid" ac_config_files="$ac_config_files bin/hlogin bin/hrancid" ac_config_files="$ac_config_files bin/htlogin bin/htrancid" ac_config_files="$ac_config_files bin/jlogin bin/jrancid bin/jerancid" ac_config_files="$ac_config_files bin/mrancid bin/mrvlogin bin/mrvrancid" ac_config_files="$ac_config_files bin/mtrancid bin/mtlogin" ac_config_files="$ac_config_files bin/nlogin bin/nrancid" ac_config_files="$ac_config_files bin/nslogin bin/nsrancid" ac_config_files="$ac_config_files bin/nxrancid" ac_config_files="$ac_config_files bin/prancid" ac_config_files="$ac_config_files bin/rivlogin bin/rivrancid" ac_config_files="$ac_config_files bin/rrancid" ac_config_files="$ac_config_files bin/srancid" ac_config_files="$ac_config_files bin/tlogin" ac_config_files="$ac_config_files bin/tntlogin bin/tntrancid" ac_config_files="$ac_config_files bin/trancid" ac_config_files="$ac_config_files bin/xrancid" ac_config_files="$ac_config_files bin/xrrancid" ac_config_files="$ac_config_files bin/zrancid" ac_config_files="$ac_config_files share/rtrfilter" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs, see configure's option --config-cache. # It is not useful on other systems. If it contains results you don't # want to keep, you may remove or edit it. # # config.status only pays attention to the cache file if you give it # the --recheck option to rerun configure. # # `ac_cv_env_foo' variables (set or unset) will be overridden when # loading this file, other *unset* `ac_cv_foo' will be assigned the # following values. _ACEOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, we kill variables containing newlines. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. ( for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space=' '; set) 2>&1` in #( *${as_nl}ac_space=\ *) # `set' does not quote correctly, so add quotes: double-quote # substitution turns \\\\ into \\, and sed turns \\ into \. sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ;; #( *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) | sed ' /^ac_cv_env_/b end t clear :clear s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ t end s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ :end' >>confcache if diff "$cache_file" confcache >/dev/null 2>&1; then :; else if test -w "$cache_file"; then test "x$cache_file" != "x/dev/null" && { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 $as_echo "$as_me: updating cache $cache_file" >&6;} cat confcache >$cache_file else { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 $as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} fi fi rm -f confcache test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' DEFS=-DHAVE_CONFIG_H ac_libobjs= ac_ltlibobjs= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' ac_i=`$as_echo "$ac_i" | sed "$ac_script"` # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR # will be set to the directory where LIBOBJS objects are built. as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs if test -n "$EXEEXT"; then am__EXEEXT_TRUE= am__EXEEXT_FALSE='#' else am__EXEEXT_TRUE='#' am__EXEEXT_FALSE= fi if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then as_fn_error "conditional \"AMDEP\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then as_fn_error "conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${MK_LCLSTATEDIR_TRUE}" && test -z "${MK_LCLSTATEDIR_FALSE}"; then as_fn_error "conditional \"MK_LCLSTATEDIR\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${CONF_INSTALL_TRUE}" && test -z "${CONF_INSTALL_FALSE}"; then as_fn_error "conditional \"CONF_INSTALL\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi : ${CONFIG_STATUS=./config.status} ac_write_fail=0 ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 $as_echo "$as_me: creating $CONFIG_STATUS" >&6;} as_write_fail=0 cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 #! $SHELL # Generated by $as_me. # Run this file to recreate the current configuration. # Compiler output produced by configure, useful for debugging # configure, is in config.log if it exists. debug=false ac_cs_recheck=false ac_cs_silent=false SHELL=\${CONFIG_SHELL-$SHELL} export SHELL _ASEOF cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # as_fn_error ERROR [LINENO LOG_FD] # --------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with status $?, using 1 if that was 0. as_fn_error () { as_status=$?; test $as_status -eq 0 && as_status=1 if test "$3"; then as_lineno=${as_lineno-"$2"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $1" >&$3 fi $as_echo "$as_me: error: $1" >&2 as_fn_exit $as_status } # as_fn_error # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -p'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -p' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi else as_ln_s='cp -p' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error "cannot create directory $as_dir" } # as_fn_mkdir_p if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi if test -x / >/dev/null 2>&1; then as_test_x='test -x' else if ls -dL / >/dev/null 2>&1; then as_ls_L_option=L else as_ls_L_option= fi as_test_x=' eval sh -c '\'' if test -d "$1"; then test -d "$1/."; else case $1 in #( -*)set "./$1";; esac; case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( ???[sx]*):;;*)false;;esac;fi '\'' sh ' fi as_executable_p=$as_test_x # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" exec 6>&1 ## ----------------------------------- ## ## Main body of $CONFIG_STATUS script. ## ## ----------------------------------- ## _ASEOF test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Save the log message, to keep $0 and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" This file was extended by $as_me, which was generated by GNU Autoconf 2.65. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ on `(hostname || uname -n) 2>/dev/null | sed 1q` " _ACEOF case $ac_config_files in *" "*) set x $ac_config_files; shift; ac_config_files=$*;; esac case $ac_config_headers in *" "*) set x $ac_config_headers; shift; ac_config_headers=$*;; esac cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # Files that config.status was made for. config_files="$ac_config_files" config_headers="$ac_config_headers" config_commands="$ac_config_commands" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ac_cs_usage="\ \`$as_me' instantiates files and other configuration actions from templates according to the current configuration. Unless the files and actions are specified as TAGs, all are instantiated by default. Usage: $0 [OPTION]... [TAG]... -h, --help print this help, then exit -V, --version print version number and configuration settings, then exit --config print configuration, then exit -q, --quiet, --silent do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE --header=FILE[:TEMPLATE] instantiate the configuration header FILE Configuration files: $config_files Configuration headers: $config_headers Configuration commands: $config_commands Report bugs to the package provider." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ config.status configured by $0, generated by GNU Autoconf 2.65, with options \\"\$ac_cs_config\\" Copyright (C) 2009 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." ac_pwd='$ac_pwd' srcdir='$srcdir' INSTALL='$INSTALL' MKDIR_P='$MKDIR_P' AWK='$AWK' test -n "\$AWK" || AWK=awk _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # The default lists apply if the user does not specify any file. ac_need_defaults=: while test $# != 0 do case $1 in --*=*) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` ac_shift=: ;; *) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; esac case $ac_option in # Handling of the options. -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) $as_echo "$ac_cs_version"; exit ;; --config | --confi | --conf | --con | --co | --c ) $as_echo "$ac_cs_config"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; esac as_fn_append CONFIG_FILES " '$ac_optarg'" ac_need_defaults=false;; --header | --heade | --head | --hea ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; esac as_fn_append CONFIG_HEADERS " '$ac_optarg'" ac_need_defaults=false;; --he | --h) # Conflict between --help and --header as_fn_error "ambiguous option: \`$1' Try \`$0 --help' for more information.";; --help | --hel | -h ) $as_echo "$ac_cs_usage"; exit ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. -*) as_fn_error "unrecognized option: \`$1' Try \`$0 --help' for more information." ;; *) as_fn_append ac_config_targets " $1" ac_need_defaults=false ;; esac shift done ac_configure_extra_args= if $ac_cs_silent; then exec 6>/dev/null ac_configure_extra_args="$ac_configure_extra_args --silent" fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 if \$ac_cs_recheck; then set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion shift \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 CONFIG_SHELL='$SHELL' export CONFIG_SHELL exec "\$@" fi _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX $as_echo "$ac_log" } >&5 _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # # INIT-COMMANDS # AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Handling of arguments. for ac_config_target in $ac_config_targets do case $ac_config_target in "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; "bin/Makefile") CONFIG_FILES="$CONFIG_FILES bin/Makefile" ;; "etc/Makefile") CONFIG_FILES="$CONFIG_FILES etc/Makefile" ;; "include/Makefile") CONFIG_FILES="$CONFIG_FILES include/Makefile" ;; "man/Makefile") CONFIG_FILES="$CONFIG_FILES man/Makefile" ;; "share/Makefile") CONFIG_FILES="$CONFIG_FILES share/Makefile" ;; "include/version.h") CONFIG_FILES="$CONFIG_FILES include/version.h" ;; "include/config.h") CONFIG_HEADERS="$CONFIG_HEADERS include/config.h" ;; "bin/control_rancid") CONFIG_FILES="$CONFIG_FILES bin/control_rancid" ;; "bin/par") CONFIG_FILES="$CONFIG_FILES bin/par" ;; "bin/rancid-fe") CONFIG_FILES="$CONFIG_FILES bin/rancid-fe" ;; "bin/agmrancid") CONFIG_FILES="$CONFIG_FILES bin/agmrancid" ;; "bin/alogin") CONFIG_FILES="$CONFIG_FILES bin/alogin" ;; "bin/arancid") CONFIG_FILES="$CONFIG_FILES bin/arancid" ;; "bin/arrancid") CONFIG_FILES="$CONFIG_FILES bin/arrancid" ;; "bin/avologin") CONFIG_FILES="$CONFIG_FILES bin/avologin" ;; "bin/avorancid") CONFIG_FILES="$CONFIG_FILES bin/avorancid" ;; "bin/blogin") CONFIG_FILES="$CONFIG_FILES bin/blogin" ;; "bin/brancid") CONFIG_FILES="$CONFIG_FILES bin/brancid" ;; "bin/cat5rancid") CONFIG_FILES="$CONFIG_FILES bin/cat5rancid" ;; "bin/clogin") CONFIG_FILES="$CONFIG_FILES bin/clogin" ;; "bin/rancid") CONFIG_FILES="$CONFIG_FILES bin/rancid" ;; "bin/cssrancid") CONFIG_FILES="$CONFIG_FILES bin/cssrancid" ;; "bin/elogin") CONFIG_FILES="$CONFIG_FILES bin/elogin" ;; "bin/erancid") CONFIG_FILES="$CONFIG_FILES bin/erancid" ;; "bin/f5rancid") CONFIG_FILES="$CONFIG_FILES bin/f5rancid" ;; "bin/f10rancid") CONFIG_FILES="$CONFIG_FILES bin/f10rancid" ;; "bin/flogin") CONFIG_FILES="$CONFIG_FILES bin/flogin" ;; "bin/francid") CONFIG_FILES="$CONFIG_FILES bin/francid" ;; "bin/fnlogin") CONFIG_FILES="$CONFIG_FILES bin/fnlogin" ;; "bin/fnrancid") CONFIG_FILES="$CONFIG_FILES bin/fnrancid" ;; "bin/hlogin") CONFIG_FILES="$CONFIG_FILES bin/hlogin" ;; "bin/hrancid") CONFIG_FILES="$CONFIG_FILES bin/hrancid" ;; "bin/htlogin") CONFIG_FILES="$CONFIG_FILES bin/htlogin" ;; "bin/htrancid") CONFIG_FILES="$CONFIG_FILES bin/htrancid" ;; "bin/jlogin") CONFIG_FILES="$CONFIG_FILES bin/jlogin" ;; "bin/jrancid") CONFIG_FILES="$CONFIG_FILES bin/jrancid" ;; "bin/jerancid") CONFIG_FILES="$CONFIG_FILES bin/jerancid" ;; "bin/mrancid") CONFIG_FILES="$CONFIG_FILES bin/mrancid" ;; "bin/mrvlogin") CONFIG_FILES="$CONFIG_FILES bin/mrvlogin" ;; "bin/mrvrancid") CONFIG_FILES="$CONFIG_FILES bin/mrvrancid" ;; "bin/mtrancid") CONFIG_FILES="$CONFIG_FILES bin/mtrancid" ;; "bin/mtlogin") CONFIG_FILES="$CONFIG_FILES bin/mtlogin" ;; "bin/nlogin") CONFIG_FILES="$CONFIG_FILES bin/nlogin" ;; "bin/nrancid") CONFIG_FILES="$CONFIG_FILES bin/nrancid" ;; "bin/nslogin") CONFIG_FILES="$CONFIG_FILES bin/nslogin" ;; "bin/nsrancid") CONFIG_FILES="$CONFIG_FILES bin/nsrancid" ;; "bin/nxrancid") CONFIG_FILES="$CONFIG_FILES bin/nxrancid" ;; "bin/prancid") CONFIG_FILES="$CONFIG_FILES bin/prancid" ;; "bin/rivlogin") CONFIG_FILES="$CONFIG_FILES bin/rivlogin" ;; "bin/rivrancid") CONFIG_FILES="$CONFIG_FILES bin/rivrancid" ;; "bin/rrancid") CONFIG_FILES="$CONFIG_FILES bin/rrancid" ;; "bin/srancid") CONFIG_FILES="$CONFIG_FILES bin/srancid" ;; "bin/tlogin") CONFIG_FILES="$CONFIG_FILES bin/tlogin" ;; "bin/tntlogin") CONFIG_FILES="$CONFIG_FILES bin/tntlogin" ;; "bin/tntrancid") CONFIG_FILES="$CONFIG_FILES bin/tntrancid" ;; "bin/trancid") CONFIG_FILES="$CONFIG_FILES bin/trancid" ;; "bin/xrancid") CONFIG_FILES="$CONFIG_FILES bin/xrancid" ;; "bin/xrrancid") CONFIG_FILES="$CONFIG_FILES bin/xrrancid" ;; "bin/zrancid") CONFIG_FILES="$CONFIG_FILES bin/zrancid" ;; "share/rtrfilter") CONFIG_FILES="$CONFIG_FILES share/rtrfilter" ;; *) as_fn_error "invalid argument: \`$ac_config_target'" "$LINENO" 5;; esac done # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands fi # Have a temporary directory for convenience. Make it in the build tree # simply because there is no reason against having it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. # Hook for its removal unless debugging. # Note that there is a small window in which the directory will not be cleaned: # after its creation but before its name has been assigned to `$tmp'. $debug || { tmp= trap 'exit_status=$? { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status ' 0 trap 'as_fn_exit 1' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" } || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") } || as_fn_error "cannot create a temporary directory in ." "$LINENO" 5 # Set up the scripts for CONFIG_FILES section. # No need to generate them if there are no CONFIG_FILES. # This happens for instance with `./config.status config.h'. if test -n "$CONFIG_FILES"; then ac_cr=`echo X | tr X '\015'` # On cygwin, bash can eat \r inside `` if the user requested igncr. # But we know of no other shell where ac_cr would be empty at this # point, so we can use a bashism as a fallback. if test "x$ac_cr" = x; then eval ac_cr=\$\'\\r\' fi ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then ac_cs_awk_cr='\r' else ac_cs_awk_cr=$ac_cr fi echo 'BEGIN {' >"$tmp/subs1.awk" && _ACEOF { echo "cat >conf$$subs.awk <<_ACEOF" && echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && echo "_ACEOF" } >conf$$subs.sh || as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_num=`echo "$ac_subst_vars" | grep -c '$'` ac_delim='%!_!# ' for ac_last_try in false false false false false :; do . ./conf$$subs.sh || as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` if test $ac_delim_n = $ac_delim_num; then break elif $ac_last_try; then as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done rm -f conf$$subs.sh cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>"\$tmp/subs1.awk" <<\\_ACAWK && _ACEOF sed -n ' h s/^/S["/; s/!.*/"]=/ p g s/^[^!]*!// :repl t repl s/'"$ac_delim"'$// t delim :nl h s/\(.\{148\}\)..*/\1/ t more1 s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ p n b repl :more1 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t nl :delim h s/\(.\{148\}\)..*/\1/ t more2 s/["\\]/\\&/g; s/^/"/; s/$/"/ p b :more2 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t delim ' >$CONFIG_STATUS || ac_write_fail=1 rm -f conf$$subs.awk cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACAWK cat >>"\$tmp/subs1.awk" <<_ACAWK && for (key in S) S_is_set[key] = 1 FS = "" } { line = $ 0 nfields = split(line, field, "@") substed = 0 len = length(field[1]) for (i = 2; i < nfields; i++) { key = field[i] keylen = length(key) if (S_is_set[key]) { value = S[key] line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) len += length(value) + length(field[++i]) substed = 1 } else len += 1 + keylen } print line } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" else cat fi < "$tmp/subs1.awk" > "$tmp/subs.awk" \ || as_fn_error "could not setup config files machinery" "$LINENO" 5 _ACEOF # VPATH may cause trouble with some makes, so we remove $(srcdir), # ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=/{ s/:*\$(srcdir):*/:/ s/:*\${srcdir}:*/:/ s/:*@srcdir@:*/:/ s/^\([^=]*=[ ]*\):*/\1/ s/:*$// s/^[^=]*=[ ]*$// }' fi cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 fi # test -n "$CONFIG_FILES" # Set up the scripts for CONFIG_HEADERS section. # No need to generate them if there are no CONFIG_HEADERS. # This happens for instance with `./config.status Makefile'. if test -n "$CONFIG_HEADERS"; then cat >"$tmp/defines.awk" <<\_ACAWK || BEGIN { _ACEOF # Transform confdefs.h into an awk script `defines.awk', embedded as # here-document in config.status, that substitutes the proper values into # config.h.in to produce config.h. # Create a delimiter string that does not exist in confdefs.h, to ease # handling of long lines. ac_delim='%!_!# ' for ac_last_try in false false :; do ac_t=`sed -n "/$ac_delim/p" confdefs.h` if test -z "$ac_t"; then break elif $ac_last_try; then as_fn_error "could not make $CONFIG_HEADERS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done # For the awk script, D is an array of macro values keyed by name, # likewise P contains macro parameters if any. Preserve backslash # newline sequences. ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* sed -n ' s/.\{148\}/&'"$ac_delim"'/g t rset :rset s/^[ ]*#[ ]*define[ ][ ]*/ / t def d :def s/\\$// t bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3"/p s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p d :bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3\\\\\\n"\\/p t cont s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p t cont d :cont n s/.\{148\}/&'"$ac_delim"'/g t clear :clear s/\\$// t bsnlc s/["\\]/\\&/g; s/^/"/; s/$/"/p d :bsnlc s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p b cont ' >$CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 for (key in D) D_is_set[key] = 1 FS = "" } /^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { line = \$ 0 split(line, arg, " ") if (arg[1] == "#") { defundef = arg[2] mac1 = arg[3] } else { defundef = substr(arg[1], 2) mac1 = arg[2] } split(mac1, mac2, "(") #) macro = mac2[1] prefix = substr(line, 1, index(line, defundef) - 1) if (D_is_set[macro]) { # Preserve the white space surrounding the "#". print prefix "define", macro P[macro] D[macro] next } else { # Replace #undef with comments. This is necessary, for example, # in the case of _POSIX_SOURCE, which is predefined and required # on some systems where configure will not decide to define it. if (defundef == "undef") { print "/*", prefix defundef, macro, "*/" next } } } { print } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 as_fn_error "could not setup config headers machinery" "$LINENO" 5 fi # test -n "$CONFIG_HEADERS" eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" shift for ac_tag do case $ac_tag in :[FHLC]) ac_mode=$ac_tag; continue;; esac case $ac_mode$ac_tag in :[FHL]*:*);; :L* | :C*:*) as_fn_error "invalid tag \`$ac_tag'" "$LINENO" 5;; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; esac ac_save_IFS=$IFS IFS=: set x $ac_tag IFS=$ac_save_IFS shift ac_file=$1 shift case $ac_mode in :L) ac_source=$1;; :[FH]) ac_file_inputs= for ac_f do case $ac_f in -) ac_f="$tmp/stdin";; *) # Look for the file first in the build tree, then in the source tree # (if the path is not absolute). The absolute path cannot be DOS-style, # because $ac_f cannot contain `:'. test -f "$ac_f" || case $ac_f in [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || as_fn_error "cannot find input file: \`$ac_f'" "$LINENO" 5;; esac case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac as_fn_append ac_file_inputs " '$ac_f'" done # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ configure_input='Generated from '` $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' `' by configure.' if test x"$ac_file" != x-; then configure_input="$ac_file. $configure_input" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 $as_echo "$as_me: creating $ac_file" >&6;} fi # Neutralize special characters interpreted by sed in replacement strings. case $configure_input in #( *\&* | *\|* | *\\* ) ac_sed_conf_input=`$as_echo "$configure_input" | sed 's/[\\\\&|]/\\\\&/g'`;; #( *) ac_sed_conf_input=$configure_input;; esac case $ac_tag in *:-:* | *:-) cat >"$tmp/stdin" \ || as_fn_error "could not create $ac_file" "$LINENO" 5 ;; esac ;; esac ac_dir=`$as_dirname -- "$ac_file" || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir="$ac_dir"; as_fn_mkdir_p ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix case $ac_mode in :F) # # CONFIG_FILE # case $INSTALL in [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; esac ac_MKDIR_P=$MKDIR_P case $MKDIR_P in [\\/$]* | ?:[\\/]* ) ;; */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; esac _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # If the template does not know about datarootdir, expand it. # FIXME: This hack should be removed a few years after 2.60. ac_datarootdir_hack=; ac_datarootdir_seen= ac_sed_dataroot=' /datarootdir/ { p q } /@datadir@/p /@docdir@/p /@infodir@/p /@localedir@/p /@mandir@/p' case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in *datarootdir*) ac_datarootdir_seen=yes;; *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 $as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_datarootdir_hack=' s&@datadir@&$datadir&g s&@docdir@&$docdir&g s&@infodir@&$infodir&g s&@localedir@&$localedir&g s&@mandir@&$mandir&g s&\\\${datarootdir}&$datarootdir&g' ;; esac _ACEOF # Neutralize VPATH when `$srcdir' = `.'. # Shell code in configure.ac might set extrasub. # FIXME: do we really want to maintain this feature? cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_sed_extra="$ac_vpsub $extrasub _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s|@configure_input@|$ac_sed_conf_input|;t t s&@top_builddir@&$ac_top_builddir_sub&;t t s&@top_build_prefix@&$ac_top_build_prefix&;t t s&@srcdir@&$ac_srcdir&;t t s&@abs_srcdir@&$ac_abs_srcdir&;t t s&@top_srcdir@&$ac_top_srcdir&;t t s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t s&@builddir@&$ac_builddir&;t t s&@abs_builddir@&$ac_abs_builddir&;t t s&@abs_top_builddir@&$ac_abs_top_builddir&;t t s&@INSTALL@&$ac_INSTALL&;t t s&@MKDIR_P@&$ac_MKDIR_P&;t t $ac_datarootdir_hack " eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$tmp/subs.awk" >$tmp/out \ || as_fn_error "could not create $ac_file" "$LINENO" 5 test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } && { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } && { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined." >&5 $as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined." >&2;} rm -f "$tmp/stdin" case $ac_file in -) cat "$tmp/out" && rm -f "$tmp/out";; *) rm -f "$ac_file" && mv "$tmp/out" "$ac_file";; esac \ || as_fn_error "could not create $ac_file" "$LINENO" 5 ;; :H) # # CONFIG_HEADER # if test x"$ac_file" != x-; then { $as_echo "/* $configure_input */" \ && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" } >"$tmp/config.h" \ || as_fn_error "could not create $ac_file" "$LINENO" 5 if diff "$ac_file" "$tmp/config.h" >/dev/null 2>&1; then { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 $as_echo "$as_me: $ac_file is unchanged" >&6;} else rm -f "$ac_file" mv "$tmp/config.h" "$ac_file" \ || as_fn_error "could not create $ac_file" "$LINENO" 5 fi else $as_echo "/* $configure_input */" \ && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" \ || as_fn_error "could not create -" "$LINENO" 5 fi # Compute "$ac_file"'s index in $config_headers. _am_arg="$ac_file" _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $_am_arg | $_am_arg:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" || $as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$_am_arg" : 'X\(//\)[^/]' \| \ X"$_am_arg" : 'X\(//\)$' \| \ X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$_am_arg" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'`/stamp-h$_am_stamp_count ;; :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 $as_echo "$as_me: executing $ac_file commands" >&6;} ;; esac case $ac_file$ac_mode in "depfiles":C) test x"$AMDEP_TRUE" != x"" || { # Autoconf 2.62 quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. case $CONFIG_FILES in *\'*) eval set x "$CONFIG_FILES" ;; *) set x $CONFIG_FILES ;; esac shift for mf do # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. # We used to match only the files named `Makefile.in', but # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. # Grep'ing the whole file is not good either: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then dirpart=`$as_dirname -- "$mf" || $as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$mf" : 'X\(//\)[^/]' \| \ X"$mf" : 'X\(//\)$' \| \ X"$mf" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$mf" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` else continue fi # Extract the definition of DEPDIR, am__include, and am__quote # from the Makefile without running `make'. DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue am__include=`sed -n 's/^am__include = //p' < "$mf"` test -z "am__include" && continue am__quote=`sed -n 's/^am__quote = //p' < "$mf"` # When using ansi2knr, U may be empty or an underscore; expand it U=`sed -n 's/^U = //p' < "$mf"` # Find all dependency output files, they are included files with # $(DEPDIR) in their names. We invoke sed twice because it is the # simplest approach to changing $(DEPDIR) to its actual value in the # expansion. for file in `sed -n " s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue fdir=`$as_dirname -- "$file" || $as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$file" : 'X\(//\)[^/]' \| \ X"$file" : 'X\(//\)$' \| \ X"$file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir=$dirpart/$fdir; as_fn_mkdir_p # echo "creating $dirpart/$file" echo '# dummy' > "$dirpart/$file" done done } ;; "bin/control_rancid":F) chmod a+x $ac_file ;; "bin/par":F) chmod a+x $ac_file ;; "bin/rancid-fe":F) chmod a+x $ac_file ;; "bin/agmrancid":F) chmod a+x $ac_file ;; "bin/alogin":F) chmod a+x $ac_file ;; "bin/arancid":F) chmod a+x $ac_file ;; "bin/arrancid":F) chmod a+x $ac_file ;; "bin/avologin":F) chmod a+x $ac_file ;; "bin/avorancid":F) chmod a+x $ac_file ;; "bin/blogin":F) chmod a+x $ac_file ;; "bin/brancid":F) chmod a+x $ac_file ;; "bin/cat5rancid":F) chmod a+x $ac_file ;; "bin/clogin":F) chmod a+x $ac_file ;; "bin/rancid":F) chmod a+x $ac_file ;; "bin/cssrancid":F) chmod a+x $ac_file ;; "bin/elogin":F) chmod a+x $ac_file ;; "bin/erancid":F) chmod a+x $ac_file ;; "bin/f5rancid":F) chmod a+x $ac_file ;; "bin/f10rancid":F) chmod a+x $ac_file ;; "bin/flogin":F) chmod a+x $ac_file ;; "bin/francid":F) chmod a+x $ac_file ;; "bin/fnlogin":F) chmod a+x $ac_file ;; "bin/fnrancid":F) chmod a+x $ac_file ;; "bin/hlogin":F) chmod a+x $ac_file ;; "bin/hrancid":F) chmod a+x $ac_file ;; "bin/htlogin":F) chmod a+x $ac_file ;; "bin/htrancid":F) chmod a+x $ac_file ;; "bin/jlogin":F) chmod a+x $ac_file ;; "bin/jrancid":F) chmod a+x $ac_file ;; "bin/jerancid":F) chmod a+x $ac_file ;; "bin/mrancid":F) chmod a+x $ac_file ;; "bin/mrvlogin":F) chmod a+x $ac_file ;; "bin/mrvrancid":F) chmod a+x $ac_file ;; "bin/mtrancid":F) chmod a+x $ac_file ;; "bin/mtlogin":F) chmod a+x $ac_file ;; "bin/nlogin":F) chmod a+x $ac_file ;; "bin/nrancid":F) chmod a+x $ac_file ;; "bin/nslogin":F) chmod a+x $ac_file ;; "bin/nsrancid":F) chmod a+x $ac_file ;; "bin/nxrancid":F) chmod a+x $ac_file ;; "bin/prancid":F) chmod a+x $ac_file ;; "bin/rivlogin":F) chmod a+x $ac_file ;; "bin/rivrancid":F) chmod a+x $ac_file ;; "bin/rrancid":F) chmod a+x $ac_file ;; "bin/srancid":F) chmod a+x $ac_file ;; "bin/tlogin":F) chmod a+x $ac_file ;; "bin/tntlogin":F) chmod a+x $ac_file ;; "bin/tntrancid":F) chmod a+x $ac_file ;; "bin/trancid":F) chmod a+x $ac_file ;; "bin/xrancid":F) chmod a+x $ac_file ;; "bin/xrrancid":F) chmod a+x $ac_file ;; "bin/zrancid":F) chmod a+x $ac_file ;; "share/rtrfilter":F) chmod a+x $ac_file ;; esac done # for ac_tag as_fn_exit 0 _ACEOF ac_clean_files=$ac_clean_files_save test $ac_write_fail = 0 || as_fn_error "write failure creating $CONFIG_STATUS" "$LINENO" 5 # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. # Unfortunately, on DOS this fails, as config.log is still kept open # by configure, so config.status won't be able to write to it; its # output is simply discarded. So we exec the FD to /dev/null, # effectively closing config.log, so it can be properly (re)opened and # appended to by config.status. When coming back to configure, we # need to make the FD available again. if test "$no_create" != yes; then ac_cs_success=: ac_config_status_args= test "$silent" = yes && ac_config_status_args="$ac_config_status_args --quiet" exec 5>/dev/null $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. $ac_cs_success || as_fn_exit $? fi if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi rancid-2.3.8/COPYING100644 015615 000000 00000004523 11342156272 0007520## Copyright (c) 1997-2010 by Terrapin Communications, Inc. ## All rights reserved. ## ## This code is derived from software contributed to and maintained by ## Terrapin Communications, Inc. by Henry Kilmer, John Heasley, Andrew Partan, ## Pete Whiting, Austin Schutz, and Andrew Fort. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions ## are met: ## 1. Redistributions of source code must retain the above copyright ## notice, this list of conditions and the following disclaimer. ## 2. Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## 3. All advertising materials mentioning features or use of this software ## must display the following acknowledgement: ## This product includes software developed by Terrapin Communications, ## Inc. and its contributors for RANCID. ## 4. Neither the name of Terrapin Communications, Inc. nor the names of its ## contributors may be used to endorse or promote products derived from ## this software without specific prior written permission. ## 5. It is requested that non-binding fixes and modifications be contributed ## back to Terrapin Communications, Inc. ## ## THIS SOFTWARE IS PROVIDED BY Terrapin Communications, INC. AND CONTRIBUTORS ## ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ## TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COMPANY OR CONTRIBUTORS ## BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ## CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ## SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ## INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ## CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ## ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ## POSSIBILITY OF SUCH DAMAGE. # # The expect login scripts were based on Erik Sherk's gwtn, by permission. # # The original looking glass software was written by Ed Kern, provided by # permission and modified beyond recognition. rancid-2.3.8/depcomp100555 015615 000000 00000044267 11454675366 0010067#! /bin/sh # depcomp - compile a program generating dependencies as side-effects scriptversion=2009-04-28.21; # UTC # Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006, 2007, 2009 Free # Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Originally written by Alexandre Oliva . case $1 in '') echo "$0: No command. Try \`$0 --help' for more information." 1>&2 exit 1; ;; -h | --h*) cat <<\EOF Usage: depcomp [--help] [--version] PROGRAM [ARGS] Run PROGRAMS ARGS to compile a file, generating dependencies as side-effects. Environment variables: depmode Dependency tracking mode. source Source file read by `PROGRAMS ARGS'. object Object file output by `PROGRAMS ARGS'. DEPDIR directory where to store dependencies. depfile Dependency file to output. tmpdepfile Temporary file to use when outputing dependencies. libtool Whether libtool is used (yes/no). Report bugs to . EOF exit $? ;; -v | --v*) echo "depcomp $scriptversion" exit $? ;; esac if test -z "$depmode" || test -z "$source" || test -z "$object"; then echo "depcomp: Variables source, object and depmode must be set" 1>&2 exit 1 fi # Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. depfile=${depfile-`echo "$object" | sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} rm -f "$tmpdepfile" # Some modes work just like other modes, but use different flags. We # parameterize here, but still list the modes in the big case below, # to make depend.m4 easier to write. Note that we *cannot* use a case # here, because this file can only contain one case statement. if test "$depmode" = hp; then # HP compiler uses -M and no extra arg. gccflag=-M depmode=gcc fi if test "$depmode" = dashXmstdout; then # This is just like dashmstdout with a different argument. dashmflag=-xM depmode=dashmstdout fi cygpath_u="cygpath -u -f -" if test "$depmode" = msvcmsys; then # This is just like msvisualcpp but w/o cygpath translation. # Just convert the backslash-escaped backslashes to single forward # slashes to satisfy depend.m4 cygpath_u="sed s,\\\\\\\\,/,g" depmode=msvisualcpp fi case "$depmode" in gcc3) ## gcc 3 implements dependency tracking that does exactly what ## we want. Yay! Note: for some reason libtool 1.4 doesn't like ## it if -MD -MP comes after the -MF stuff. Hmm. ## Unfortunately, FreeBSD c89 acceptance of flags depends upon ## the command line argument order; so add the flags where they ## appear in depend2.am. Note that the slowdown incurred here ## affects only configure: in makefiles, %FASTDEP% shortcuts this. for arg do case $arg in -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;; *) set fnord "$@" "$arg" ;; esac shift # fnord shift # $arg done "$@" stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi mv "$tmpdepfile" "$depfile" ;; gcc) ## There are various ways to get dependency output from gcc. Here's ## why we pick this rather obscure method: ## - Don't want to use -MD because we'd like the dependencies to end ## up in a subdir. Having to rename by hand is ugly. ## (We might end up doing this anyway to support other compilers.) ## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like ## -MM, not -M (despite what the docs say). ## - Using -M directly means running the compiler twice (even worse ## than renaming). if test -z "$gccflag"; then gccflag=-MD, fi "$@" -Wp,"$gccflag$tmpdepfile" stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" echo "$object : \\" > "$depfile" alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz ## The second -e expression handles DOS-style file names with drive letters. sed -e 's/^[^:]*: / /' \ -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" ## This next piece of magic avoids the `deleted header file' problem. ## The problem is that when a header file which appears in a .P file ## is deleted, the dependency causes make to die (because there is ## typically no way to rebuild the header). We avoid this by adding ## dummy dependencies for each header file. Too bad gcc doesn't do ## this for us directly. tr ' ' ' ' < "$tmpdepfile" | ## Some versions of gcc put a space before the `:'. On the theory ## that the space means something, we add a space to the output as ## well. ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; hp) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; sgi) if test "$libtool" = yes; then "$@" "-Wp,-MDupdate,$tmpdepfile" else "$@" -MDupdate "$tmpdepfile" fi stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files echo "$object : \\" > "$depfile" # Clip off the initial element (the dependent). Don't try to be # clever and replace this with sed code, as IRIX sed won't handle # lines with more than a fixed number of characters (4096 in # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; # the IRIX cc adds comments like `#:fec' to the end of the # dependency line. tr ' ' ' ' < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \ tr ' ' ' ' >> "$depfile" echo >> "$depfile" # The second pass generates a dummy entry for each header file. tr ' ' ' ' < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ >> "$depfile" else # The sourcefile does not contain any dependencies, so just # store a dummy comment line, to avoid errors with the Makefile # "include basename.Plo" scheme. echo "#dummy" > "$depfile" fi rm -f "$tmpdepfile" ;; aix) # The C for AIX Compiler uses -M and outputs the dependencies # in a .u file. In older versions, this file always lives in the # current directory. Also, the AIX compiler puts `$object:' at the # start of each line; $object doesn't have directory information. # Version 6 uses the directory in both cases. dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` test "x$dir" = "x$object" && dir= base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` if test "$libtool" = yes; then tmpdepfile1=$dir$base.u tmpdepfile2=$base.u tmpdepfile3=$dir.libs/$base.u "$@" -Wc,-M else tmpdepfile1=$dir$base.u tmpdepfile2=$dir$base.u tmpdepfile3=$dir$base.u "$@" -M fi stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" do test -f "$tmpdepfile" && break done if test -f "$tmpdepfile"; then # Each line is of the form `foo.o: dependent.h'. # Do two passes, one to just change these to # `$object: dependent.h' and one to simply `dependent.h:'. sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" # That's a tab and a space in the []. sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" else # The sourcefile does not contain any dependencies, so just # store a dummy comment line, to avoid errors with the Makefile # "include basename.Plo" scheme. echo "#dummy" > "$depfile" fi rm -f "$tmpdepfile" ;; icc) # Intel's C compiler understands `-MD -MF file'. However on # icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c # ICC 7.0 will fill foo.d with something like # foo.o: sub/foo.c # foo.o: sub/foo.h # which is wrong. We want: # sub/foo.o: sub/foo.c # sub/foo.o: sub/foo.h # sub/foo.c: # sub/foo.h: # ICC 7.1 will output # foo.o: sub/foo.c sub/foo.h # and will wrap long lines using \ : # foo.o: sub/foo.c ... \ # sub/foo.h ... \ # ... "$@" -MD -MF "$tmpdepfile" stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" # Each line is of the form `foo.o: dependent.h', # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. # Do two passes, one to just change these to # `$object: dependent.h' and one to simply `dependent.h:'. sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" # Some versions of the HPUX 10.20 sed can't process this invocation # correctly. Breaking it into two sed invocations is a workaround. sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; hp2) # The "hp" stanza above does not work with aCC (C++) and HP's ia64 # compilers, which have integrated preprocessors. The correct option # to use with these is +Maked; it writes dependencies to a file named # 'foo.d', which lands next to the object file, wherever that # happens to be. # Much of this is similar to the tru64 case; see comments there. dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` test "x$dir" = "x$object" && dir= base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` if test "$libtool" = yes; then tmpdepfile1=$dir$base.d tmpdepfile2=$dir.libs/$base.d "$@" -Wc,+Maked else tmpdepfile1=$dir$base.d tmpdepfile2=$dir$base.d "$@" +Maked fi stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile1" "$tmpdepfile2" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" do test -f "$tmpdepfile" && break done if test -f "$tmpdepfile"; then sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile" # Add `dependent.h:' lines. sed -ne '2,${ s/^ *// s/ \\*$// s/$/:/ p }' "$tmpdepfile" >> "$depfile" else echo "#dummy" > "$depfile" fi rm -f "$tmpdepfile" "$tmpdepfile2" ;; tru64) # The Tru64 compiler uses -MD to generate dependencies as a side # effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'. # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put # dependencies in `foo.d' instead, so we check for that too. # Subdirectories are respected. dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` test "x$dir" = "x$object" && dir= base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` if test "$libtool" = yes; then # With Tru64 cc, shared objects can also be used to make a # static library. This mechanism is used in libtool 1.4 series to # handle both shared and static libraries in a single compilation. # With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d. # # With libtool 1.5 this exception was removed, and libtool now # generates 2 separate objects for the 2 libraries. These two # compilations output dependencies in $dir.libs/$base.o.d and # in $dir$base.o.d. We have to check for both files, because # one of the two compilations can be disabled. We should prefer # $dir$base.o.d over $dir.libs/$base.o.d because the latter is # automatically cleaned when .libs/ is deleted, while ignoring # the former would cause a distcleancheck panic. tmpdepfile1=$dir.libs/$base.lo.d # libtool 1.4 tmpdepfile2=$dir$base.o.d # libtool 1.5 tmpdepfile3=$dir.libs/$base.o.d # libtool 1.5 tmpdepfile4=$dir.libs/$base.d # Compaq CCC V6.2-504 "$@" -Wc,-MD else tmpdepfile1=$dir$base.o.d tmpdepfile2=$dir$base.d tmpdepfile3=$dir$base.d tmpdepfile4=$dir$base.d "$@" -MD fi stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" do test -f "$tmpdepfile" && break done if test -f "$tmpdepfile"; then sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" # That's a tab and a space in the []. sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" else echo "#dummy" > "$depfile" fi rm -f "$tmpdepfile" ;; #nosideeffect) # This comment above is used by automake to tell side-effect # dependency tracking mechanisms from slower ones. dashmstdout) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout, regardless of -o. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi # Remove `-o $object'. IFS=" " for arg do case $arg in -o) shift ;; $object) shift ;; *) set fnord "$@" "$arg" shift # fnord shift # $arg ;; esac done test -z "$dashmflag" && dashmflag=-M # Require at least two characters before searching for `:' # in the target name. This is to cope with DOS-style filenames: # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise. "$@" $dashmflag | sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile" rm -f "$depfile" cat < "$tmpdepfile" > "$depfile" tr ' ' ' ' < "$tmpdepfile" | \ ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; dashXmstdout) # This case only exists to satisfy depend.m4. It is never actually # run, as this mode is specially recognized in the preamble. exit 1 ;; makedepend) "$@" || exit $? # Remove any Libtool call if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi # X makedepend shift cleared=no eat=no for arg do case $cleared in no) set ""; shift cleared=yes ;; esac if test $eat = yes; then eat=no continue fi case "$arg" in -D*|-I*) set fnord "$@" "$arg"; shift ;; # Strip any option that makedepend may not understand. Remove # the object too, otherwise makedepend will parse it as a source file. -arch) eat=yes ;; -*|$object) ;; *) set fnord "$@" "$arg"; shift ;; esac done obj_suffix=`echo "$object" | sed 's/^.*\././'` touch "$tmpdepfile" ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" rm -f "$depfile" cat < "$tmpdepfile" > "$depfile" sed '1,2d' "$tmpdepfile" | tr ' ' ' ' | \ ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" "$tmpdepfile".bak ;; cpp) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi # Remove `-o $object'. IFS=" " for arg do case $arg in -o) shift ;; $object) shift ;; *) set fnord "$@" "$arg" shift # fnord shift # $arg ;; esac done "$@" -E | sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' | sed '$ s: \\$::' > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" cat < "$tmpdepfile" >> "$depfile" sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; msvisualcpp) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi IFS=" " for arg do case "$arg" in -o) shift ;; $object) shift ;; "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") set fnord "$@" shift shift ;; *) set fnord "$@" "$arg" shift shift ;; esac done "$@" -E 2>/dev/null | sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile" echo " " >> "$depfile" sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile" rm -f "$tmpdepfile" ;; msvcmsys) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; none) exec "$@" ;; *) echo "Unknown depmode $depmode" 1>&2 exit 1 ;; esac exit 0 # Local Variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: rancid-2.3.8/install-sh100555 015615 000000 00000014733 11454675366 0010511#!/bin/sh # # $NetBSD: install-sh.in,v 1.4 2007/07/12 18:32:50 jlam Exp $ # This script now also installs multiple files, but might choke on installing # multiple files with spaces in the file names. # # install - install a program, script, or datafile # This comes from X11R5 (mit/util/scripts/install.sh). # # Copyright 1991 by the Massachusetts Institute of Technology # # Permission to use, copy, modify, distribute, and sell this software and its # documentation for any purpose is hereby granted without fee, provided that # the above copyright notice appear in all copies and that both that # copyright notice and this permission notice appear in supporting # documentation, and that the name of M.I.T. not be used in advertising or # publicity pertaining to distribution of the software without specific, # written prior permission. M.I.T. makes no representations about the # suitability of this software for any purpose. It is provided "as is" # without express or implied warranty. # # Calling this script install-sh is preferred over install.sh, to prevent # `make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. doit="${DOITPROG-}" # put in absolute paths if you don't have them in your path; or use env. vars. awkprog="${AWKPROG-awk}" mvprog="${MVPROG-mv}" cpprog="${CPPROG-cp}" chmodprog="${CHMODPROG-chmod}" chownprog="${CHOWNPROG-chown}" chgrpprog="${CHGRPPROG-chgrp}" stripprog="${STRIPPROG-strip}" rmprog="${RMPROG-rm}" mkdirprog="${MKDIRPROG-mkdir}" instcmd="$mvprog" pathcompchmodcmd="$chmodprog 755" chmodcmd="$chmodprog 755" chowncmd="" chgrpcmd="" stripcmd="" stripflags="" rmcmd="$rmprog -f" mvcmd="$mvprog" src="" msrc="" dst="" dir_arg="" suffix="" suffixfmt="" while [ x"$1" != x ]; do case $1 in -b) suffix=".old" shift continue;; -B) suffixfmt="$2" shift shift continue;; -c) instcmd="$cpprog" shift continue;; -d) dir_arg=true shift continue;; -m) chmodcmd="$chmodprog $2" shift shift continue;; -o) chowncmd="$chownprog $2" shift shift continue;; -g) chgrpcmd="$chgrpprog $2" shift shift continue;; -s) stripcmd="$stripprog" shift continue;; -S) stripcmd="$stripprog" stripflags="-S $2 $stripflags" shift shift continue;; *) if [ x"$msrc" = x ] then msrc="$dst" else msrc="$msrc $dst" fi src="$dst" dst="$1" shift continue;; esac done if [ x"$dir_arg" = x ] then dstisfile="" if [ ! -d "$dst" ] then if [ x"$msrc" = x"$src" ] then dstisfile=true else echo "install: destination is not a directory" exit 1 fi fi else msrc="$msrc $dst" fi if [ x"$msrc" = x ] then echo "install: no destination specified" exit 1 fi for srcarg in $msrc; do if [ x"$dir_arg" != x ]; then dstarg="$srcarg" else dstarg="$dst" # Waiting for this to be detected by the "$instcmd $srcarg $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if [ -f "$srcarg" ] then doinst="$instcmd" elif [ -d "$srcarg" ] then echo "install: $srcarg: not a regular file" exit 1 elif [ "$srcarg" = "/dev/null" ] then doinst="$cpprog" else echo "install: $srcarg does not exist" exit 1 fi # If destination is a directory, append the input filename; if your system # does not like double slashes in filenames, you may need to add some logic if [ -d "$dstarg" ] then dstarg="$dstarg"/`basename "$srcarg"` fi fi ## this sed command emulates the dirname command dstdir=`echo "$dstarg" | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` # Make sure that the destination directory exists. # this part is taken from Noah Friedman's mkinstalldirs script # Skip lots of stat calls in the usual case. if [ ! -d "$dstdir" ]; then defaultIFS=' ' IFS="${IFS-${defaultIFS}}" oIFS="${IFS}" # Some sh's can't handle IFS=/ for some reason. IFS='%' set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` IFS="${oIFS}" pathcomp='' while [ $# -ne 0 ] ; do pathcomp="${pathcomp}${1}" shift if [ ! -d "${pathcomp}" ] ; then $doit $mkdirprog "${pathcomp}" if [ x"$chowncmd" != x ]; then $doit $chowncmd "${pathcomp}"; else true ; fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "${pathcomp}"; else true ; fi && if [ x"$pathcompchmodcmd" != x ]; then $doit $pathcompchmodcmd "${pathcomp}"; else true ; fi else true fi pathcomp="${pathcomp}/" done fi if [ x"$dir_arg" != x ] then if [ -d "$dstarg" ]; then true else $doit $mkdirprog "$dstarg" && if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dstarg"; else true ; fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dstarg"; else true ; fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dstarg"; else true ; fi fi else if [ x"$dstisfile" = x ] then file=$srcarg else file=$dst fi dstfile=`basename "$file"` dstfinal="$dstdir/$dstfile" # Make a temp file name in the proper directory. dsttmp=$dstdir/#inst.$$# # Make a backup file name in the proper directory. case x$suffixfmt in *%*) suffix=`echo x | $awkprog -v bname="$dstfinal" -v fmt="$suffixfmt" ' { cnt = 0; do { sfx = sprintf(fmt, cnt++); name = bname sfx; } while (system("test -f " name) == 0); print sfx; }' -`;; x) ;; *) suffix="$suffixfmt";; esac dstbackup="$dstfinal$suffix" # Move or copy the file name to the temp name $doit $doinst $srcarg "$dsttmp" && trap "rm -f ${dsttmp}" 0 && # and set any options; do chmod last to preserve setuid bits # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $instcmd $src $dsttmp" command. if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dsttmp"; else true;fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dsttmp"; else true;fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd $stripflags "$dsttmp"; else true;fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dsttmp"; else true;fi && # Now rename the file to the real destination. if [ x"$suffix" != x ] && [ -f "$dstfinal" ] then $doit $mvcmd "$dstfinal" "$dstbackup" else $doit $rmcmd -f "$dstfinal" fi && $doit $mvcmd "$dsttmp" "$dstfinal" fi done && exit 0 rancid-2.3.8/missing100555 015615 000000 00000026233 11454675366 0010102#! /bin/sh # Common stub for a few missing GNU programs while installing. scriptversion=2009-04-28.21; # UTC # Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006, # 2008, 2009 Free Software Foundation, Inc. # Originally by Fran,cois Pinard , 1996. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. if test $# -eq 0; then echo 1>&2 "Try \`$0 --help' for more information" exit 1 fi run=: sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p' sed_minuso='s/.* -o \([^ ]*\).*/\1/p' # In the cases where this matters, `missing' is being run in the # srcdir already. if test -f configure.ac; then configure_ac=configure.ac else configure_ac=configure.in fi msg="missing on your system" case $1 in --run) # Try to run requested program, and just exit if it succeeds. run= shift "$@" && exit 0 # Exit code 63 means version mismatch. This often happens # when the user try to use an ancient version of a tool on # a file that requires a minimum version. In this case we # we should proceed has if the program had been absent, or # if --run hadn't been passed. if test $? = 63; then run=: msg="probably too old" fi ;; -h|--h|--he|--hel|--help) echo "\ $0 [OPTION]... PROGRAM [ARGUMENT]... Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an error status if there is no known handling for PROGRAM. Options: -h, --help display this help and exit -v, --version output version information and exit --run try to run the given command, and emulate it if it fails Supported PROGRAM values: aclocal touch file \`aclocal.m4' autoconf touch file \`configure' autoheader touch file \`config.h.in' autom4te touch the output file, or create a stub one automake touch all \`Makefile.in' files bison create \`y.tab.[ch]', if possible, from existing .[ch] flex create \`lex.yy.c', if possible, from existing .c help2man touch the output file lex create \`lex.yy.c', if possible, from existing .c makeinfo touch the output file tar try tar, gnutar, gtar, then tar without non-portable flags yacc create \`y.tab.[ch]', if possible, from existing .[ch] Version suffixes to PROGRAM as well as the prefixes \`gnu-', \`gnu', and \`g' are ignored when checking the name. Send bug reports to ." exit $? ;; -v|--v|--ve|--ver|--vers|--versi|--versio|--version) echo "missing $scriptversion (GNU Automake)" exit $? ;; -*) echo 1>&2 "$0: Unknown \`$1' option" echo 1>&2 "Try \`$0 --help' for more information" exit 1 ;; esac # normalize program name to check for. program=`echo "$1" | sed ' s/^gnu-//; t s/^gnu//; t s/^g//; t'` # Now exit if we have it, but it failed. Also exit now if we # don't have it and --version was passed (most likely to detect # the program). This is about non-GNU programs, so use $1 not # $program. case $1 in lex*|yacc*) # Not GNU programs, they don't have --version. ;; tar*) if test -n "$run"; then echo 1>&2 "ERROR: \`tar' requires --run" exit 1 elif test "x$2" = "x--version" || test "x$2" = "x--help"; then exit 1 fi ;; *) if test -z "$run" && ($1 --version) > /dev/null 2>&1; then # We have it, but it failed. exit 1 elif test "x$2" = "x--version" || test "x$2" = "x--help"; then # Could not run --version or --help. This is probably someone # running `$TOOL --version' or `$TOOL --help' to check whether # $TOOL exists and not knowing $TOOL uses missing. exit 1 fi ;; esac # If it does not exist, or fails to run (possibly an outdated version), # try to emulate it. case $program in aclocal*) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified \`acinclude.m4' or \`${configure_ac}'. You might want to install the \`Automake' and \`Perl' packages. Grab them from any GNU archive site." touch aclocal.m4 ;; autoconf*) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified \`${configure_ac}'. You might want to install the \`Autoconf' and \`GNU m4' packages. Grab them from any GNU archive site." touch configure ;; autoheader*) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified \`acconfig.h' or \`${configure_ac}'. You might want to install the \`Autoconf' and \`GNU m4' packages. Grab them from any GNU archive site." files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}` test -z "$files" && files="config.h" touch_files= for f in $files; do case $f in *:*) touch_files="$touch_files "`echo "$f" | sed -e 's/^[^:]*://' -e 's/:.*//'`;; *) touch_files="$touch_files $f.in";; esac done touch $touch_files ;; automake*) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'. You might want to install the \`Automake' and \`Perl' packages. Grab them from any GNU archive site." find . -type f -name Makefile.am -print | sed 's/\.am$/.in/' | while read f; do touch "$f"; done ;; autom4te*) echo 1>&2 "\ WARNING: \`$1' is needed, but is $msg. You might have modified some files without having the proper tools for further handling them. You can get \`$1' as part of \`Autoconf' from any GNU archive site." file=`echo "$*" | sed -n "$sed_output"` test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` if test -f "$file"; then touch $file else test -z "$file" || exec >$file echo "#! /bin/sh" echo "# Created by GNU Automake missing as a replacement of" echo "# $ $@" echo "exit 0" chmod +x $file exit 1 fi ;; bison*|yacc*) echo 1>&2 "\ WARNING: \`$1' $msg. You should only need it if you modified a \`.y' file. You may need the \`Bison' package in order for those modifications to take effect. You can get \`Bison' from any GNU archive site." rm -f y.tab.c y.tab.h if test $# -ne 1; then eval LASTARG="\${$#}" case $LASTARG in *.y) SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` if test -f "$SRCFILE"; then cp "$SRCFILE" y.tab.c fi SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` if test -f "$SRCFILE"; then cp "$SRCFILE" y.tab.h fi ;; esac fi if test ! -f y.tab.h; then echo >y.tab.h fi if test ! -f y.tab.c; then echo 'main() { return 0; }' >y.tab.c fi ;; lex*|flex*) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified a \`.l' file. You may need the \`Flex' package in order for those modifications to take effect. You can get \`Flex' from any GNU archive site." rm -f lex.yy.c if test $# -ne 1; then eval LASTARG="\${$#}" case $LASTARG in *.l) SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` if test -f "$SRCFILE"; then cp "$SRCFILE" lex.yy.c fi ;; esac fi if test ! -f lex.yy.c; then echo 'main() { return 0; }' >lex.yy.c fi ;; help2man*) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified a dependency of a manual page. You may need the \`Help2man' package in order for those modifications to take effect. You can get \`Help2man' from any GNU archive site." file=`echo "$*" | sed -n "$sed_output"` test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` if test -f "$file"; then touch $file else test -z "$file" || exec >$file echo ".ab help2man is required to generate this page" exit $? fi ;; makeinfo*) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified a \`.texi' or \`.texinfo' file, or any other file indirectly affecting the aspect of the manual. The spurious call might also be the consequence of using a buggy \`make' (AIX, DU, IRIX). You might want to install the \`Texinfo' package or the \`GNU make' package. Grab either from any GNU archive site." # The file to touch is that specified with -o ... file=`echo "$*" | sed -n "$sed_output"` test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` if test -z "$file"; then # ... or it is the one specified with @setfilename ... infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` file=`sed -n ' /^@setfilename/{ s/.* \([^ ]*\) *$/\1/ p q }' $infile` # ... or it is derived from the source name (dir/f.texi becomes f.info) test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info fi # If the file does not exist, the user really needs makeinfo; # let's fail without touching anything. test -f $file || exit 1 touch $file ;; tar*) shift # We have already tried tar in the generic part. # Look for gnutar/gtar before invocation to avoid ugly error # messages. if (gnutar --version > /dev/null 2>&1); then gnutar "$@" && exit 0 fi if (gtar --version > /dev/null 2>&1); then gtar "$@" && exit 0 fi firstarg="$1" if shift; then case $firstarg in *o*) firstarg=`echo "$firstarg" | sed s/o//` tar "$firstarg" "$@" && exit 0 ;; esac case $firstarg in *h*) firstarg=`echo "$firstarg" | sed s/h//` tar "$firstarg" "$@" && exit 0 ;; esac fi echo 1>&2 "\ WARNING: I can't seem to be able to run \`tar' with the given arguments. You may want to install GNU tar or Free paxutils, or check the command line arguments." exit 1 ;; *) echo 1>&2 "\ WARNING: \`$1' is needed, and is $msg. You might have modified some files without having the proper tools for further handling them. Check the \`README' file, it often tells you about the needed prerequisites for installing this package. You may also peek at any GNU archive site, in case some other package would contain this missing \`$1' program." exit 1 ;; esac exit 0 # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: rancid-2.3.8/mkinstalldirs100555 015615 000000 00000006722 11454675366 0011312#! /bin/sh # mkinstalldirs --- make directory hierarchy scriptversion=2009-04-28.21; # UTC # Original author: Noah Friedman # Created: 1993-05-16 # Public domain. # # This file is maintained in Automake, please report # bugs to or send patches to # . nl=' ' IFS=" "" $nl" errstatus=0 dirmode= usage="\ Usage: mkinstalldirs [-h] [--help] [--version] [-m MODE] DIR ... Create each directory DIR (with mode MODE, if specified), including all leading file name components. Report bugs to ." # process command line arguments while test $# -gt 0 ; do case $1 in -h | --help | --h*) # -h for help echo "$usage" exit $? ;; -m) # -m PERM arg shift test $# -eq 0 && { echo "$usage" 1>&2; exit 1; } dirmode=$1 shift ;; --version) echo "$0 $scriptversion" exit $? ;; --) # stop option processing shift break ;; -*) # unknown option echo "$usage" 1>&2 exit 1 ;; *) # first non-opt arg break ;; esac done for file do if test -d "$file"; then shift else break fi done case $# in 0) exit 0 ;; esac # Solaris 8's mkdir -p isn't thread-safe. If you mkdir -p a/b and # mkdir -p a/c at the same time, both will detect that a is missing, # one will create a, then the other will try to create a and die with # a "File exists" error. This is a problem when calling mkinstalldirs # from a parallel make. We use --version in the probe to restrict # ourselves to GNU mkdir, which is thread-safe. case $dirmode in '') if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then echo "mkdir -p -- $*" exec mkdir -p -- "$@" else # On NextStep and OpenStep, the `mkdir' command does not # recognize any option. It will interpret all options as # directories to create, and then abort because `.' already # exists. test -d ./-p && rmdir ./-p test -d ./--version && rmdir ./--version fi ;; *) if mkdir -m "$dirmode" -p --version . >/dev/null 2>&1 && test ! -d ./--version; then echo "mkdir -m $dirmode -p -- $*" exec mkdir -m "$dirmode" -p -- "$@" else # Clean up after NextStep and OpenStep mkdir. for d in ./-m ./-p ./--version "./$dirmode"; do test -d $d && rmdir $d done fi ;; esac for file do case $file in /*) pathcomp=/ ;; *) pathcomp= ;; esac oIFS=$IFS IFS=/ set fnord $file shift IFS=$oIFS for d do test "x$d" = x && continue pathcomp=$pathcomp$d case $pathcomp in -*) pathcomp=./$pathcomp ;; esac if test ! -d "$pathcomp"; then echo "mkdir $pathcomp" mkdir "$pathcomp" || lasterr=$? if test ! -d "$pathcomp"; then errstatus=$lasterr else if test ! -z "$dirmode"; then echo "chmod $dirmode $pathcomp" lasterr= chmod "$dirmode" "$pathcomp" || lasterr=$? if test ! -z "$lasterr"; then errstatus=$lasterr fi fi fi fi pathcomp=$pathcomp/ done done exit $errstatus # Local Variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: rancid-2.3.8/BUGS100644 015615 000000 00000000046 11342156272 0007144See the the file Todo for known bugs. rancid-2.3.8/Todo100644 015615 000000 00000011540 11342156272 0007312- make *login and login.top.in cmdline options common among all scripts - rivlogin is a mess - why does hlogin fail when the host key is not yet known? eg: unix% ./hlogin procurve procurve spawn hpuifilter -- ssh -c 3des -x -l user procurve Host key verification failed. Error: Couldn't login This happens on solaris only; linux and netbsd seem to be ok. - lg.conf(5) needs the query stuff documented. - configure OLDTIME per-group - could the cloginrc match function do a longest-match search instead of first match? - look at Andreas Dahl's Brocade switch collection scripts - noenable should handle a value properly. i.e.: 1 == noenable, 0 == enable or perhaps don't clear the -noenable cmd-line option. the manpage needs to be fixed as well. see msg from fred jordan. - recent hp procurve s/w does not seem have show flash or show module - would like to have a "pre-login-sequence" cloginrc directive, see rancid-disuss message from mike ethridge 16/may - would like to have a "timeout" cloginrc directive - would like to have a ssh "passphrase" cloginrc directive - would like to have a "login_option" cloginrc directive to specify arbitrary command-line options - possibly a "debug" (exp_internal 1 ?) cloginrc directive? *login -d flag for same? warning about filling logs? - on 6500, show boot and show bootvar produce the same output and both appear in the crunched config. should one be filtered? - fix varargs for knf in util.c - isis filtering for foundry? - hlogin hangs when the procurve does not ask for passwords - share/ tool to prune cvs versions, excluding those with tags, by (all but latest | keep N versions | keep N days/months/years) - extreme collection fails for tacacs-enabled boxen due to diffs in UI - blech! - xrancid should collect both of these: show configuration show configuration detail - FILTER_PWDS knob is not implemented in alteon, bay, ezt3 or redback due to lack of h/w to test against. need help from the community. - should par's -c override an input files' : cmd? - should *login emmit "clogin error:" or "*login error:" to make matches for login failures definitive? - would like hpuifilter to be more friendly to interactive logins - hpuifilter needs to allocate a pseudo terminal to work with ssh Pseudo-terminal will not be allocated because stdin is not a terminal. - rancid with zebra via vtysh? - rancid for unix? - would be nice if it were possible to add additional commands to be run per-platform as a user desires. how could the user also provide a filtering routine? - a format such as {} as the pwd in .cloginrc to indicate *login should prompt the user for the password - implement the bits marked unimplemented in lg.conf - detect 'same' vty configs - ignoring length/width/passwd is a start, but need more - merge clogin and jlogin (or *login !!) into one. possible? - flogin (for foundry) needs more testing and should be integrated with clogin when foundry fixes their UI. - flogin needs to be fixed for the userpasswd bug seen in jlogin 1.17, but this is clouded by the UI mess. - rancid needs to treat the 3600s like the 7Ks and 12Ks... Also, need to allow 12012s, and force 700s to not be treated like 7Ks. - LG should sort routers - LG {requested} command additions - show controllers T3 (data) - handle redback in the looking glass - show ip as-path-access-list - show access-list - show ip community-list - show ip route-map - prancid - lots of GC'ing to be done - prancid - sort logging file by filename. e.g.: logging file messages facility kernel level debugging logging file log facility any level debugging logging file log archive files 10 size 10m logging file messages archive files 10 size 10m then, sort by facility, e.g.: logging file messages facility kernel level debugging logging file messages facility authorization level debugging - should we add CVS ID header to saved configs? configurable option? - idea from andrew fort - cat 2900 extra info uptime is 3 weeks, 3 days, 14 hours, 17 minutes System returned to ROM by power-on System restarted at 15:21:54 UTC Mon Sep 30 2002 System image file is "flash:c2950-i6q4l2-mz.121-9.EA1d.bin" cisco WS-C2950-24 (RC32300) processor (revision B0) with 20821K bytes of memory. Processor board ID FHK0619X2RN Last reset from system-reset Running Standard Image 24 FastEthernet/IEEE 802.3 interface(s) 32K bytes of flash-simulated non-volatile configuration memory. Base ethernet MAC Address: 00:09:B7:50:DE:C0 Motherboard assembly number: 73-5781-10 Power supply part number: 34-0965-01 Motherboard serial number: FOC061903JF Power supply serial number: DAB061735H4 Model revision number: B0 Motherboard revision number: A0 Model number: WS-C2950-24 System serial number: FHK0619X2RN Configuration register is 0xF - Why does nlogin use a gratuitiously different variable name for the device(s) in the main loop? rancid-2.3.8/CHANGES100644 015615 000000 00000114170 11712070510 00074472.3.8 rancid: filter sup-bootflash if sup-bootdisk worked *login: fix match of (yes/no) prompts from ssh rancid: carry-over additional inventory filtering from XR 2.3.7 xrrancid: change some "admin show" sorting to reflect previous code xrrancid: filter useless junk from show inventory mrvrancid: update ShowChassis() for temp filtering in new s/w nrancid: installed memory on Juniper SSG series - Steven Bertsch rancid: missing CR after s/n xrrancid: admin show variables boot clean-up - Per Carlson xrrancid: add admin show install summary, license - Per Carlson xrrancid: fix access-list formatting & sorting rancid: collect show capture & shun for ASA - Josh Ward xrancid: misc patches for XOS - Zenon Mousmoulas rancid-cvs: svn repository handling improvement - Zenon Mousmoulas rancid: filter WPA passwd - Pavel Korovin rancid: add 'show running-config view full' for role cli - Pavel Korovin rancid: filter ppp hostnames (aka usernames) - Pavel Korovin *login: update host key change match for newer ssh clogin: disable pager for XOS-12.3 - Zenon Mousmoulas rancid.conf & control_rancid: support arbitrary subversion URLs as (pre-provisioned) repositories and do not overwrite an existing local repository - Zenon Mousmoulas rancid.conf: add LC_COLLATE - Daniel Schmidt nlogin: add identfile support - Garry Shtern hrancid: match 'logout' in new procurve versions for end of run hrancid: include comment line for procurve parser - Per-Olof Olsson hrancid: collect show config status - mostly from Per-Olof Olsson nxrancid: add show environment fex all fan cmd - Deny IP Any Any *login: dont split $sshcmd nxrancid: Nexus 4000s don't support 'show environment power' - Lee xrrancid: add admin show running - Troy Boudreau arancid: /info/sys -> /info/sys/dump - Tim Frost rancid: correct isakmp key filter - Pan Affa clogin; set terminal width to 132 for both -s and -c clogin: respond to ASA's pager in long login banners - Lee clogin: set terminal width to 132 rancid: match flash memory on likes of Cisco 2811 and 2621XM - Pan Affa import share/rancid-cvspurge - Matthew Grossman rancid: add 'dir /all sup-bootdisk:' for 6500 sup32 - Lee rancid: adjust regex for tacacs key match - Pavel Korovin *login: join sshcmd clogin directive to handle spaces properly mt{login,rancid}: import Microtik module from Chris Boot rancid: ppp password missed on dialer interfaces - noted by Hirofumi Katou arancid: filter "esecret" lines which change with each config display - Ton hlogin: logout from enabled mode instead of exit for -S - Thorsten Hahn hrancid: collect show config files and show tech transceivers - Thorsten Hahn rancid: filter config timestamp on MDS/NX-OS avorancid: collect power management file - from Darius Jan Seroka fnrancid: correct comment character - noted by Gavin McCullagh fnrancid: update system time and conf_file_ver filters - Gavin McCullagh nxrancid: do not require 'show system redundancy status', apparently unsupported on some nexus models. clogin: set terminal width for -c and -s hlogin: stacks prompt for switch number or CR at login, send CR - Per-Olof Olsson 2.3.6 rancid.spec: updated for 2.3.6 - from Florian Koch rancid: fail on error opening nvram: rancid: skip ASA 5520 configuration author line control_rancid: for svn stupidity, run update (yes update) and commit after setting svn:ignore, else . is out of date. rancid: filter auto "rogue ap" configuration - Kevin Nesbitt alogin: adjust match of active alarms msg at login jrancid: patch for master/backup matching on EX series - Sven Engelhardt rancid: update cisco WAE identity string match - from Jim Hock {xr}rancid: summarize DirSlotN() bytes free as GB, else MB. rancid: filter sflog from DirSlotN() for IOS on cisco 10k fnrancid: update recent fortinet software - Diego Ercolani rancid: ignore show flash on IOS XE - Marcus Stoegbauer rancid: copy the dhcp database filter to ShowFlash() - From Lee clogin: Fix pasto in IOS terminal width command. hlogin: -r missing from usage o/p - Per-Olof Olsson clogin: add -r and passphrase/identfile from cloginrc - Per-Olof Olsson francid: remove system uptime line on CER 3000 - Simon Leinen 2.3.5 alogin: respond to active alarms msg at login - Vincent Tamet *rancid: update for grammar deprecated in perl 5.12 *login: handle noenable value consistently, '1' to turn it on configure: look for -n option to ping, for Windows ping (over cygwin) - From Lee rancid: missed case fpr accepting '>' prompt, rather than just '#' xrrancid: filter sequences from ipv4/6 access-lists zrancid: force terminal type vt100 so as not to confuse Linux francid: filter system uptime on new Brocades - Matthias Cramer rancid: filter ASA time-based license noise - Christopher DeRemer rancid: filter command in WriteTerm if echoed - Arjan Oosting configure: specifically look for ping in /sbin & /usr/sbin & fix typo in test operator rancid: handle a few IOS serial number formatting variants - Aaron Rees hpuifilter: change filtering to avoid use of string functions due to a Debian bug. Should be faster too. rancid: adjust show inventory matches for variables WS - Aaron Rees nxrancid: show environment clock and show core vdc-all are not valid commands on all platforms - Ryan West 2.3.4 nrancid: fix serial number matching - Nathan Wallwork nrancid: fix pager prompt filtering - Nathan Wallwork rancid: remove sequences from IPv6 prefix-lists clogin: adjust default ssh password prompt for ExtremeOS 12.3.3.6 - from Sylvain 74 rancid: Accept '>' prompt, rather than just '#' avologin: fix ssh command substitution - Ben O'Hara fnrancid: filter application signature, System Time & conf_file_ver= from GetSystem/GetConf mrvrancid: filter other oscillating info from show version - Ben O'Hara xrrancid: disable timestamps - from Per Carlson hlogin: implement -autoenable for newer hp procurve releases cat5rancid: snmp community may have multiple spaces b/t community name and permissions - from David Adam cat5rancid: filter local user password - from David Adam f5rancid: filter Failover time stamps - from Ben O'Hara hlogin: Add support for ssh identity file & passphrase for newer boxes rancid: split IOS-XR into its own device type: cisco-xr clogin: set term width for catos like for ios. rancid: parse admin show diag for XR better with a separate function hlogin: hpuifilter got omitted from the ssh spawn; replace it. nxrancid: match unknown command errors appropriately & GC some junk carried-over from IOS-rancid. 2.3.3 rancid: check for device busy when opening flash fails, which seems to occur on 6500s when some other command is run. *login: support :port method syntax for ssh and adjust to allow spaces in sshcmd jrancid: fix return values of formatting functions clogin: set terminal width so that o/p is consistent rancid: filter some crud resulting from the change in handling non-empty comment lines rancid: fail if the configuration buffer fills rancid: filter dhcp_[^[:space:].].txt from flash directories, so it does not create constant changes resulting from the ip dhcp database saves. rancid: filter ldap host password on PIX rancid: when compressing consecutive comment lines, only consider empty lines. arancid: handle password filter for HP 1:10Gb Ethernet Blade Switch 5.0.4-Base, running AOS - Tore Anderson *login: add cloginrc timeout directive nrancid: fix control number match - Guillaume RISCHARD rancid: remove ASA coredump* filter - Cisco Bug CSCsz85597, fixed in 8.2(1.2), 8.3(0.0), 100.3(0.3)M f5rancid: adjust fan rpm and config sync time filters for new f5 code - Ben O'Hara rancid: ACE/SANOS report invalid input differently - Michael Stefaniuc rancid: skip leading blank lines in config - Michael Stefaniuc rancid: remove ASA keys such as tacacs and radius - Michael Stefaniuc rancid: match non-space for usernames in "Written by" line - James Davis *rancid: quote meta characters - from Jeremy Singletary rancid: Fail on error msg "% Configuration buffer full" seen on 6500 rancid: Dont filter 'show vlan' on Catalyst 3550/4500s - Jon Lewis import Arista script - from Bill Fenner jerancid: fix for 'show environment all' for filtering with auto-sync on BRASes - from Christophe Fonteyne francid,flogin: edgeiron can not disable the pager and does not offer some commands found on the bigirons rancid: filter coredumpinfo/coredump.cfg found on ASA - rancid-discuss@ f5rancid: fileter HA peer status - from David Stipp WTI scripts from Geert Jan de Groot with a few tweaks jerancid: include standby slots in showversion o/p lg: add code for LG_SINGLE config knob clogin: run_commands() needs do_saveconfig f10rancid: change fan status parsing to handle c300 nxrancid: collect license info; fix 'show env temp' & 'show env power' parsing; drop unused code. change zero-config check to avoid broken awks - from jim buchele 2.3.2 clogin: fix for Extreme prompt handling nxrancid: delete Command: and Time: output f5rancid: install the script and use the device type 'f5' *login: accept -S for "save configuration if prompted" *login: remove uppercase versions of lowercase options tlogin: replace -debug with -d nlogin: cloginrc method handling and login error path fixes clogin: change "(enable)" and/or regex meta-char exscaping so that catalyst logins work properly. hlogin: run_commands exp_continueing when it shouldnt have jerancid: summarize DirSlotN bytes to reduce diffs rancid: catch aborted 'show diag' output on some 7300s. Bug found by Paul Vlaar. rancid: correct/add some filtering for ASA's more system:running-config srancid: filter temperature sensor info for Dell 6428 stacks hpuifilter: Filter \x07 (bell) from output, which the Cisco AGM suddenly started inserting *sometimes*. nxrancid: add "show version build-info". sort snmp-server user. rancid: filter filesize and date of tracelogs dir on IOS-XE rancid: summarize bytes free for IOS-XE like XR nsrancid/nslogin: updates for netscalar version 8 - Marco Schirrmeister f10rancid: updated support for all devices running FTOS: E-Series, C-Series and S-Series - Greg Hankins clogin: force10/SFTOS fixes for username & logout prompts - Doug Hughes f10rancid: SFTOS config end marker has trailing space - Marcus Stoegbauer mrvrancid: support for the MRV fiber switch rancid: collect GSR linecard route memory - Kritian Larsson clogin: new CSS configuration change prompt syntax - Kritian Larsson *login: add -- to other sends that take input from the user *login: terminate send options with -- to avoid interpretation of -'s in arguments - partly from Ric Anderson nxrancid: add support for cisco Nexus boxes; use type cisco-nx rancid: Skip "Cryptochecksum:" line on ASA, PIX, et al hrancid: K.13 s/w changed cmd 'show system information' - Richard Golier rancid: Spot yet another flash disk in show version output. rancid: Some support for Cisco Nexus. rancid: corrupted flash is not a rancid failure - from John Payne rancid.spec: Linux spec file - blame Steve Snodgrass rancid: changes for cisco SAN - from Mark Favas clogin: escape regex grouping atom '()' in the catalyst prompt - From Casey Deccio flogin: handle strange characters like space in prompt w/ the method from clogin for handling regex characters francid: filter SSL secret - From Jethro Binks francid: privlvl 5 does not allow write term, also run show running-config - from Jethro Binks *login: Return/exit non-zero if there are failures for any of the devices on the cmd-line. nslogin: password prompt change in newer code - from Derek Andree hlogin: reformat the prompt matching in run_commands() like cisco, which fixes -x and -c usage in configure mode. avorancid: Avocent (Cyclades) module - from Stephen Griffin f10rancid: updated support for all devices running FTOS: E-Series, C-Series and S-Series - from Greg Hankins jrancid: don't look for passwords in system login class XX permissions [] jrancid: additional filter for M320 rancid: ignore author failure for some data that are collected by different commands and succeeded the first time - from David Luyer *login: add -d to enable expect's debugging configure: make svn fs-type configurable with --with-svn=fstype xrancid: Correct the $prompt regex mangling for XOS - from Tore Anderson f10rancid: E-series support updated - loaner & clues from Greg Hankins rancid: Convert disk/flash free space to MB (from bytes) for IOX/IOS XR accept NO & YES for NOCOMMSTR in rancid.conf Add ACLSORT configuration knob - mostly from Michael Stefaniuc cat5rancid: permit missing CRLF on exit - Michael Stefaniuc cat5rancid: skip show inventory for those without - Michael Stefaniuc agmrancid: show diag can fail shortly after boot rancid: radius/tacacs key filtering on old IOS - from Michael Stefaniuc rancid: Add AS5xxx support from Andre van der Merwe. Changes so the RANCID-CONTENT-TYPE is the same as the documented entry in router.db.5 and the same as the call in rancid-fe. These RANCID-CONTENT-TYPEs changed: brancid from bay to baynet cat5rancid from cisco-cat to cat5 cssrancid from cisco-css to css erancid from adc-ezt3 to ezt3 fnrancid from Fortigate to fortigate hrancid from hp-procurve to hp jerancid from Juniper_ERX to erx srancid from dell to smc f5rancid: F5 BigIPs srancid: SMC/Dell switch support - loaner from Randy Bush *login: Set variables for do_login when both -e and -p/-v are specified - reported by A Dudek *login: recognize the environment variable CLOGINRC, see clogin(1) agmrancid: Cisco AGM/Anomaly Guard Module francid: drop fan speed o/p from show chassis - John Adams clogin: match Cisco CSS's "save config?" prompt - Lance Vermilion jrancid: include show system core-dumps - Michael Lyngbol rancid: filter empty 'show inventory' fields - from Michael Stefaniuc *login: If we timeout while trying to quit in run_commands(), close the connection (ie: file descriptor/tty) gracefully. - from Ed Ravin, adjusted to catch the close. jrancid: Adapt M160 PCG freq rounding to new format - noted by Mark Davis rancid: collect flash size on the FWSM - from Aaron Gee-clough francid: Fix temperature/show chassis filtering for newer Foundry boxes - noted and tested by Gary Roberts rancid: fix Cisco 3825,3845 show version parsing - Michael Stefaniuc clogin/hlogin: use send -h for exit command - Michael Stefaniuc clogin: Answer F10's "unsaved changes" logout prompt - Colin Corbett f10rancid: "Current Conf" begins with ! in recent code - Colin Corbett francid: sort intf "secure" MACs, order fluctuates - noted by Brad Volz francid: filter temperature o/p on the SuperX - Brad Volz convert rancid-fe vendor list to a hash - suggested by Ed Ravin. rancid: new format for PIX 7.0 license string - Aaron Gee-clough rancid: check for 7300 type of routers clogin: older CatOS for 1900s has a CR after the pager prompt clogin & xrancid: Extreme XOS prompt format changed - Tore Anderson User a .cvsignore file to prevent non-cvs'd control files from appearing in cvs update output. rancid: include _ in IOS version strings clogin: reduce the number of leading prompt characters used in run_commands to accomodate change seen in cat6500 12.1(13)E14 - Charles Aresenault hlogin: fix ssh hanging on press any key prompt - Ryan Mooney rancid: more support for HFRs nlogin: fix missing -re option for password matching - Jee Kay lg: fix quoting of juniper command arguments - Richard Doty rancid: also match _ in software image names - Stafford A. Rau nrancid: fix config comment character & more filtering - Stoned Elipot hlogin: look for the 'press any key' prompt after ssh authentication, unlike telnet, where it appears before authentication. hpuifilter: allocate a pty to interact with ssh/telnet, so that we interact with ssh for the password exchange. WARNING: repeated ssh login failures to HP Procurves cause the switch's management interface to lock-up (this includes snmp, ping) and sometimes it will crash. This is with the latest firmware; 5.33 at the time of this writing. *rancid: check hostname, or filename, before opening the output file. rancid: better filtering of {tacacs,radius}-server - Patrick Adlam rancid: better filtering of PIX pager prompt - Aaron Gee-clough rancid: collect show debug - Ed Ravin add subversion support - mostly from Justin Grote clogin: support rsh method - partly from James Stahr collect show inventory raw on rancid and cat5rancid add -ko to cvs diff commands - Michael Shields Add a MAILHEADERS configuration variable for user-defined mail headers rancid: match HSRP group numbers greater than 1 char wide - Ed Ravin nrancid: filter radius secrest - Jee Kay *rancid: collapse the two command list definitions to an array of hashrefs and build the lists from it - Ed Ravin *login: ignore rsh on platforms that do not support it and on those that do (eg: cisco), skip rsh for interactive and script (-s) logins. add MAX_ROUNDS rancid.conf knob - Mardechai Abzug control_rancid: fix adminmailrcpt default - Danny Thomas rancid: correct handling of SNMPv3 host configs - Patrick Adlam rancid: filter nv_hdr file seen on sup720 - Bill Ouchark etc/Makefile.am: support DESTDIR - from Michael Shields rancid: add IOX/CRS support. hrancid: show stack does not apply to all procurves - Eugene Zagrebelny flogin: older foundry o/s has misc spaces preceeding : in username prompt - from mike ethridge A better nlogin & nrancid for NetScreens - help from Stephen Gill jerancid: case fluctuates in "active/standby" - from David Gethings jerancid: filter "please wait" from config - from David Gethings jerancid: filter consecutive periods at top of write term - mark cooper jerancid: fix check for slave RE sync in DirSlotN - from Mark Lovely rancid: collect 6500's sub-module info from show modules jrancid: collect license info & RE Model. Don't collect the license keys as this is only supported on the jseries and running 'show system license keys' on other junipers produces output from *two* commands - 'show system license' AND 'show system licensekeys'. rancid: erroneous space in shared-secret match - from Blaz Zupan nrancid: fix missing brace - from David King lgform: need strftime from POSIX - from Joao Frade rancid: filter multiple-fs file - from Yuval Ben-Ari cssrancid: make this parse the collected output properly rancid: filter & sort IOS AP username passwords - noted by Stafford Rau rancid: parse more variants of 'show diag' output. 2.3.1 jerancid: fail/retry if the RP is syncing to the backup - Dave Mack clogin: cat 19k lacks a space in front of pager prompt - darren @ adam nlogin: correct find(sshcmd) argument - from Samuele Giovanni Tonon lg.cgi: allow :s in arguments for sub-interface from Richard Doty jrancid: filter some more secrets rancid: filter some more secrets francid: bits for Mucho Grande - from Niels Bakker add -- before (telnet|ssh) in call to hpuifilter so that any options for telnet/ssh are not interpretted by hpuifilter look for diff -U if diff -u fails in configure. fix typo in nlogin that made cloginrc password lookups fail. 2.3 The following files have been moved to make rancid more install/pkg/port/rpm friendly. *** bin/env has been moved to etc/rancid.conf *** *** bin/hpfilter has been renamed hpuifilter *** *** util/lg/lg.conf has been moved to etc/lg.conf *** *** util/lg/lg*.cgi have been moved to bin/lg*cgi *** *** bin/create_cvs has been renamed rancid-cvs *** *** bin/do-diffs has been renamed rancid-run *** Note: existing configuration files are *NOT* copied/moved for you bin/rename is no longer shipped with rancid rancid.conf: add MAILDOMAIN knob - from David C. clogin: allow the port to be specified for method ssh jlogin: add cloginrc passphrase directive and order of precedence is cmd-line -r value -> passphrase -> password xrancid: do 'show diag' instead of 'show diagnostics' as the longer version has sometimes timed out. rancid: filter file vlan.dat from show flash on IOS switches rancid: parse cisco 1760's DSP slot show diag output francid: reorder listing of ports in a vlans - from Niels Bakker and Steven Bakker clogin: disable session logging w/ -c on catos - from Jason Ornstein rancid: add Processor ID to save output *login: handle TCL meta-characters in cloginrc directive values francid: correctly parse modules in slots >= 10. from Niels Bakker run cvs delete code even when router.db is empty. Riverstone/Enterasys updates from Andrew Fort rancid.conf: add LOGDIR variable - see rancid.conf(5) rancid: add show spe version and parse FRU show diag output - from Yuval Ben-Ari. add option --enable-adminmail-plus to configure jrancid: collect show chassis alarms rancid: skip show vlan for (3550|4500|7600) - from Andrew Fort rancid: collect 6500 slave sup bootflash - from Andrew Fort rancid: show diag updates for 1700, 3700, etc - help from Michael Haba The Extreme does not have an 'enable' level, so make sure you have 'set autoenable' for it in your .cloginrc so clogin will work. add Cisco CSS support - from Wedge Martin *login: add cloginrc sshcmd directive - idea from steve neighorn rancid: IOS show version changes w/ 12.3 - from Yuval Ben-Ari support for hitachi routers - from Mohacsi Janos strip WS around router.db fields - from Alastair Galloway add goveling of 2600 mainboard port adapter info *login: also check LOGNAME for default username - from Fredrik Thulin jerancid: add matches for "Please wait" to all functions - reported by Dave Mack fnrancid: Fortigate support - from D. Pfleger nlogin: Fix prompt groveling when running a cluster - from D. Pfleger nrancid: filter "set admin user" - from D. Pfleger rancid: do both 'write term' and 'show running-config' and keep the output from the first one that works. As cisco phases out 'write term', this will keep things working. jerancid: filter host ... ftp, encrypted passwords oscillate - reported by Dave Mack. rivlogin: add "User:" as a possible username prompt (u_prompt) for some platforms - from Adam Rothschild cat 3500 s/n and pix failover license - from Rob Evans recognize cisco ContentEngine - from Rob Evans Juniper ERX (jerancid) support, based on 5.0 - thanks to Dan Pfleger, Richard Russman, Zaid, Mike Baker, and Mark Nguyen rancid: drop the "suggested action" portion of GSR LC/RP ROM upgrade warnings. Cisco keeps changing the format; it just is not worth the aggrevation. study causes missed command somehow in redhat9 - from David King filter port security mac entries, from Arnold Nipper add Procket Networks support, "prancid" filter ipsec keys in rancid & jrancid. rancid: collect show idprom backplane (6500 cmd); this could collect more - request from jared mauch rancid: order all 'ip host' commands. rancid: collect show rsp chassis-info rancid: filter HSRP auth and SSA key-string reversable passwords lg: set query/command list in lg.conf, thus allowing individual cmds to {dis,en}abled, and add some multicast and ipv6 queries all of which are disabled by default (for lack of testing) - from Janos Mohacsi cat5rancid: collect 'write term all' for cats that support it - tested by terry kennedy and joe rizzo cat5rancid: regularize escaping of regex operators in switch prompt nsrancid: include "get log setting", as suggested by gael canal. add manpage note about log_user with -s, from mail list discussion xrancid: Handle end of ssh connection a bit better. jrancid: skip master/backup re msgs *rancid: escape regex chars found in prompt xrancid: also collect 'show configuration detail' hlogin: allow the port to be specified for method ssh and add path to hlogin to env(PATH) for locating hpfilter hpfilter: allow >2 arguments so that telnet port number can be passed. rancid: gsr RP slot warning is only 1 line - Russell Heilling add zrancid to handle zebra routing s/w add riverstone support - from Jim Meehan. thanks to Hong Luo for access to a riverstone to test. Kevin Chan reports that this works for Cabletron routers with more recent s/w (~v9.0.3). jrancid: fix handling of reversible keys such that trailing text is not removed rancid: slave/redundancy stuff - from stephen griffin rancid: show version bootstrap format changed in 12.0(23)S rancid: make sure we filter PIX pager prompts xrancid: make xrancid work when the extreme has pending changes. netscaler support - from Anshuman Kanwar. netscreen firewall support - from Stephen Gill rancid: include additional cpu info from show version in !CPU: line. lucent tnt support - from Richard Vander Reyden rancid: skip consecutive comment lines. on some access servers the number of comment lines oscillate. lg.conf: add LG_STYLE variable for style sheet - from Janos Mohacsi also install the FAQ - good idea from Janos Mohacsi's freshport rancid: filter 'cable shared-secret' 2.2.2 *login: fix handling of userprompt et al so that {}'s are used in .cloginrc as they are with every other .cloginrc directive. f10rancid: Fix to pick up new info in show version output. jrancid: Ignore Timecounter "TSC" in show system boot-messages output. rancid: filter tty line speed when configured for auto-configure flogin: bring login() and do_enable() in-line with [cj]login. also match "telnet server disabled" - from brad volz. control_rancid: report devices added to router.db - from Fredrik Thulin also eliminate empty up/down lists. rancid/jrancid: filter isis passwords - partial from Janos Mohacsi lg: make o/p from the lg stream (unbuffered), so one doesnt have to wait for entire o/p from the router in a failing traceroute, for example. suggestion and clues from alexander koch. while here, fix cache handling so 1) it doesnt cache cmds that resulted in an error or otherwise failed and 2) log and run the cmd as normal if there are problems opening a cache file. lg: make logging more consistent. log as defined by LG_LOG if possible and stderr as last resort. it was logging largely to stderr. and make exit-code small (instead of 255); some wait()s only look at the first 3 bits lg: add check in lg.cgi that router name appears in the router.db and is thus accessible. from richard doty. also fix-up a few comments and such. rancid: GSR LC PCA h/w revision now called "design release" on some platforms. CSCdw13295 add util/getipacctg example script - contrib from steve neighorn 2.2.1 rancid: npe400 cpu eeprom info o/p format changed in 12.0.21S1 - spotted by tom campbell fix problem in *login where if there was a login failure we would try to disconnect gracefully (albeit incorrectly). writing to the half-closed socket would not return an error (at least on some platform/expect combinations or even consistently) and expect would hang. add device name to diff mail subject when -r is specified add -m option to do-diffs and control_rancid to allow specific mail recipient. intended for use with -r to trigger diffs off specific events. router.db(5): note that PIX is a 'cisco' - thank kris gulka *login: match openssh prompt for host key to ip key mismatch rancid: add disk/slot2 rancid: 12.2 show c7200 o/p for midplane changed lg: use table inet.0 terse for sh ip route on juniper instead of forwarding-table destination rancid: 12.0S(21) added "FRU" field in show diagbus output. Also look for a couple more things in some show diag output and sort the output a bit better. Also look for 'controler' (cisco can't always spell - thanks to Terry Kennedy for spotting the misspelling). lg: filter ["`'] from args rancid: fix username secret filtering alogin: misplaced brace caused improper return from proc login relax the check ping and traceroute check of hostname arguments such that non-fqdn hosts are allowed. i.e.: just check that arg chars are valid dns chars and leave the resolve errors to the router. Add initial support for Force10. 2.2 rancid: filter vpdn passwords on PIX - from eric greenwood *rancid: handle variable amounts of spaces in front of ' password' correctly. rancid: remove key from "crypto isakmp key". *login: cleanup login() to be more generic and handle openssh password reprompting clogin: fix clogin -x for config mode by adjusting the prompt regex lg.conf: add LG_INFO to append local information to the main form {cat5}rancid: add dir of sup-{bootflash,microcode} for 6500 *rancid: print $host before "missed cmds", "unexpected command", and "End of run" messages. cat5 module type match failed when user module name contained spaces add FILTER_PWDS switch to env(5) add merit MRTd support add -r option to do-diffs and control_rancid brancid: handle []'s in bay prompts and drop lock-address from config - from mark cooper extreme: strip password if config|configure. Strip ^M right after ssh key. Look for BOOTLDR: on ciscos. add par.1 manpage allow a TCP port suffix to telnet in .cloginrc - from Alex Bochannek Fixed RANCID-CONTENT-TYPE to be more consistant. Changes are brancid bay cat5rancid cisco-cat erancid adc-ezt3 jlogin should not look for username@router in .cloginrc filter foundry ssh private key filter '#Time" from catalyst 4 write term display platform specific command in lookingglass results - patch from Janos Mohacsi add support for HP procurve switches, in particular 2524M and 4108gl. thanks to hp for the loaners. filter encrypted passwords on alteon as the change for each display More support for Redbacks. rancid now looks for "[kK] bytes" and "slot|disk". clogin now looks for "login:" as well as "Login:" and escapes "[]" in $prompt. 2.2b8 add PAR_COUNT variable to bin/env for adjusting the number of simultaneous collections. see bin/env (or bin/env.new for those with previous installation) and the env(5) manpage. more work on extreme switch bits + fixes from Alex Bochannek. jlogin: add 1s sleeps to avoid passwords being echo'd before tty noecho is set. richard doty few looking glass fixes brancid: filter uptime and add -all option to config for bayrs version 14. from mordechai abzug jrancid: m160 measured chassis clock MHz fluctuates, trim the decimal places. from Mark A Gebert. par: -x fix for log file monitoring killing xterms. from rdrake. 2.2b7 brancid: patch to filter community strings from Mark Cooper do-diffs: trap'ing SEGV (11) causes error on solaris. 2.2b6 baynetworks/nortel support from Mark Cooper. thanks mark! jlogin was overloading -p's variable causing proc login to fail on 2nd router on cmd-line 2.2b5 fix regex error in clogin affecting catalysts clogin attempts to grope entire prompt after login *login need to catch{} -x cmd file open so expect doesnt puke if there is an error opening the file 2.2b4 add extreme switch bits cisco changed the o/p fmt of h/w info on the 65xx in 12.1.8e PIX520 supplies different more(1) prompt than others. from William R Thomas. fix typo in jlogin. from richard doty. add 2 example expect script for clogin -s handle foundrys and more juniper bits in the lookingglass add LG_STRIP knob to strip login o/p in the lookingglass add LG_BGP_RT knob to {dis}allow heavy o/p sh ip bgp neighbor LG cmds bin/clogin shouldnt insist upon an enable password with -noenable option 2.2b3 bin/rancid changes for cisco 124xx some serial controllers (PAs) have predefined cable-type in show controllers. M8T-V.35 was being missed. modify jlogin to grope the full prompt after login such that -x can be used within configuration mode. note: this turns $prompt into a regexp, WRT -s scripts and -re option for expect's. add -Evar=x option to pass variables to scripts. e.g.: clogin -Evariable=something router... clogin -Evariable=a,b,c [i.e.: an array/list which user splits] 2.2b2 fix jlogin's password/userpassword functionality which broke when cmd-line options were made consistent. add check for config/* files missing from the cvs repository. add 2 juniper config checks to avoid truncation. 1) config should have at least 1 "section" amounting to at least 3 lines and 2) if a mgd version mismatch exists, there may be inaccuracies. convert usage of Mail to sendmail for portability. local .mailrc aliases can no longer be used. bin/alogin and changes (of beta quality) for Alteon WebOS switch from andrew fort. Check for more types of cisco 12000s. Also check for 2600s. jrancid's show chassis hardware needs detail arg in junos 4.4 make *login print \n before errors, so rancid can use an anchored match to find login errors and avoid such matches in router o/p. make *login automatically add host keys with openssh's prompting All routers not listed as 'up' in router.db are considered down. This allows values other than down to mean 'not up'. for use by util/downreport. 2.1 Change default umask to 027 (it was 007) mainly as an attempt to stop people from changing stuff in rancid's CVS store. Only rancid should be updating its CVS store. control_rancid cvs updates router.db before starting a group's collection. configure now has a --enable-mail-plus option to have rancid send mail to rancid+$GROUP instead of to rancd-$GROUP. Patch from davidw@certaintysolutions.com. configure should figure out diff options on it's own. try to get default user from env() and catch exec on id in *login make clean/distclean was missing some files make sure do-diffs cleans up after itself if it exits prematurely ignore case when cvs delete'g removed routers francid/rrancid (foundry/redback) now strip snmp communities like the others, via NOCOMMSTR var in bin/env. add man pages collect 'sh vlan' on cat 6000 - afort@choqolat.org Add 'show vtp status' for the 3500XLs as well. Escape regex meta-chars found in device prompts in *rancid Add "include" directive to include other pwd files via .cloginrc Add "show port ifindex" for the cat5s. Try to detect flash being busy on a cat5. Tag each config file with its 'type'. E.g.: !RANCID-CONTENT-TYPE: cisco fix from afort@staff.webcentral.com.au to lg.cgi to allow prefix-list with numerals. fix lg form's formatting (on some browsers/conditions). Thanks to rrashid@verio.net for the html help. 2.1b add looking glass utility based on Ed Kern's original source. Thanks to Ed for permission to include it with rancid. this is only partially tested. fixed expect foo in *login when .cloginrc is unreadable. Don't sort 'ip name-server' - order matters. 2.0 Better formatting for cisco catalyst [non-ios] switches. Better support the cisco 3500 switches. Get some info out of "show version" for the cat5ks. cat5k "show boot" does variables, not bootflash. Skip more goo from 'write term' on some cat5ks. Collect 'show module' for 6500-ios. Revamp *login's use of .cloginrc's method directive. see cloginrc.sample. Add bits for Cisco PIX. Thanks to joe rizzo@EA for access to a PIX. Sort usernames on ciscos. Get more info out of "show diag" on the GSR. Add "show chassis sfm detail" for the M160. Leave router type in place when telling about changes to router.db. Add autoconf (configure) and makefile bits to automate install and perl/expect replacement 1.6 Add "dir nvram:" to rancid. Add support for ADC EZ T3 mux. adapted from tkenndedy@verio.net's contrib. strip (try to) snmp community strings from cisco and juniper configs if environment variable NOCOMMSTR is set. merge tkennedy@verio.net's support for cisco 2900xl into rancid Ignore "fan spinning at" noise on junipers. 1.5 sync command-line option between clogin / jlogin. jlogin modified: -x passphrase -> -r passphrase -> -x command-file -e encrypt type -> -y ssh_chyper_type add .cloginrc noenable directive to set the cmd-line -noenable option. add .cloginrc userprompt, passprompt, and enableprompt directives to adjust expected cisco router prompts in clogin. see README for info on web interface to rancid CVS repository. Try to detect hung rancid jobs & send email. Add (partial) support for the cat5s. Still need more work on the show output, but it does grab the config. Skip the juniper's kernel version, memory, and fsck output of "show system boot-messages" - fsck output changes every time you boot and the version & memory is better found elsewhere. Delete the cisco ospf authentication and ftp passwords. Get both (juniper) show chassis ssb and scb but only process them once. Get info from show diag for 2600s as well. Catch juniper "command is not valid on the olive" errors. Catch juniper config mismatch between versions of JUNOS. Catch close on EOF in clogin/jlogin/flogin. Don't expand RCS keywords in config files. Catch the case were rancid gets and error and leaves an empty new config file. Make the time to elapse before complaining about unreachable routers be configurable instead of fixed at 24 hrs. The default is now 4 hours. Add -x passphrase to jlogin. You can now set a ssh identity file in .cloginrc for use with jlogin. Handle more errors in jrancid. Also handle changes for JUNOS 4.0 and collect "show system boot-messages" output. rancid now recognizes cisco 12016s and more types of 7200s. It also looks for WARNING messages in show version. And sort ip explicit-paths. 1.4 sort cisco route-maps added (crude) foundry switch bits reworked code to reduce jumps. improvement in speed/cpu util. add bits to cvs delete configs which have been removed from a group's router.db. add support for redback. modified from contrib by scao@verio.net. add support for ssh in clogin modify format of the admin up/down/delete'd msgs. add NOPIPE bin/env var order ARP lists in cisco configs 1.3 update comments re: mail aliases in bin/env add more info/clarification to README for install. 1.2 add more info/clarification to README for install. rename .cloginrc.sample -> cloginrc.sample. clogin patch (courtesy stephen stuart); does two things: - adds a "-x" switch that takes lines from a file and does the same thing as if you'd specified ;-separated commands with -c (newline separates commands). thanks to stephen stuart. - does a subst on commands in run_commands so that expansion of escapes is performed; e.g. you can say "copy rcp://blah slot0:\r" to answer the question that comes after the copy command. rancid-2.3.8/FAQ100644 015615 000000 00000043057 11521622473 0007024Frequently Asked Questions about rancid - last updated 20091111. This FAQ contains information that may not apply directly to versions of rancid prior to 2.3. It also contains paths containing tags such as , which refer to paths that are site-specific and are determined by how rancid was configured at installation time. These are explained briefly in the configure --help output. Below are the defaults used in rancid. PREFIX configure --prefix= option. default: /usr/local/rancid EPREFIX configure --exec-prefix= option. default: BINDIR configure --bindir= option. default: /bin The location of clogin, etc. SYSCONFDIR configure --sysconfdir option. default: /etc The location of rancid.conf, etc. LOCALSTATEDIR configure --localstatedir option. default: /var The location of the CVS repository, log files, etc. The most recent FAQ can be found at http://www.shrubbery.net/rancid/FAQ 1) Platform specific Q. I have a Cisco Catalyst 6500 series switch running the IOS (NOT catOS) software, is the router.db device type cisco or cat5? A. A catalyst running IOS is type "cisco". The 'show version' output will have banner including a phrase similar to "Cisco Internetwork Operating System Software". See the router.db(5) manual page. Q. I have Hybrid Cisco switch, like a cat5k with an RSM. How do I collect both the routing engine and switch configurations? A. Recommended way is to use two entries in the router.db, one for each. For example: cat5k_rsm.domain.com:cisco:up cat5k_sw.domain.com:cat5:up Q. I have a Cisco ??? on which collection stopped working, but clogin works as expected. A. Check if 'write term' produces output. Some IOS combined with large configs and low free memory produce zero 'write term' output, esp. combined with a memory leak. The device will have to be rebooted and/or upgraded. Q. I have a Cisco Catalyst switch. clogin connects, but after receiving the prompt, it stalls until it times out. Why? A. This may be due to your prompt. CatOS does not include an implicit '>' in it's prompt, like IOS does. clogin looks for '>' during login, so specify your prompt with a trailing '>'. Also see cat5rancid(1). For example: cat5k> cat5k> enable Password: cat5k> (enable) Q. Polling a ZebOS box fails from cron, but is successful from the command- line. A. This is the tty/pty handling of either your O/S or ZebOS. Supposedly, changing the TERM in /rancid.conf to the following seems to fix it. TERM=vt100;export TERM COLUMNS=160; LINES=48; export COLUMNS LINES 2) CVS and filesystem permissions WARNING: Be careful when mucking around with the repository! Q. I am new to CVS, where can I find additional information? A. The manual page for CVS is quite complete, but can be be overwhelming even for someone familiar with RCS. There are some excellent resources on the web. See http://en.wikipedia.org/wiki/Concurrent_Versions_System and http://cvshome.org/. Q. Errors are showing up in the logs like: cvs [diff aborted]: there is no version here; run 'cvs checkout' first A. The directory was not imported into CVS properly or was not properly checked out afterward, so CVS control files or directories do not exist. rancid-cvs should always be used to create the directories and perform the CVS work. If it is just the directories that have been created manually, save a copy of the router.db file, then remove the group's directory, use rancid-cvs, and replace the router.db file. If the CVS import was also performed manually, cd to and use 'cvs co ' to create all the CVS control bits. Q. I keep receiving the same diff for a (or set of) devices, but I know the data is not changing repeatedly. Why? A. This is probably a CVS or filesystem permissions problem. Check the log file from the last run for that group for clues first; it may provide the exact cause. Note: It is very important the following be done as the user who normally runs the rancid collection from cron. Check the cvs status of the device's file. example: guelah [2704] cvs status rtr.shrubbery.net =================================================================== File: yogi.shrubbery.net Status: Up-to-date Working revision: 1.197 Tue Jul 10 15:41:16 2001 Repository revision: 1.197 /usr/local/rancid/var/CVS/shrubbery/configs/rtr.shrubbery.net,v Sticky Tag: (none) Sticky Date: (none) Sticky Options: (none) The Status: should be Up-to-date. If the status is "Unknown", then somehow the file has been created without being cvs add'ed. This should be corrected by removing that device's entry from the group's router.db file, run rancid-run, replace the entry in router.db, and run rancid-run again. If the Status is anything else, someone has most likely been touching the files manually. Sane state can be achieved by removing the file and running cvs update to get a fresh copy from the repository. Check the ownership and permissions of the file and directory and the directory and file in the cvs repository (/CVS/). They should be owned by the user who runs rancid-run from cron. At the very least, the directory and files should be writable by the rancid user. Group and world permissions will determined by the umask (default 027), which is set in /rancid.conf. Likely the easiest way to fix the ownership on the cvs repository is chown -R /CVS / Q. I am renaming a device but would like to retain the history in CVS. How is this done? A. CVS does not provide a way (AFAIK) to rename files or to rename or delete directories. The best way is to copy the CVS repository file manually like this (disclaimer: BE VERY CAREFUL mucking around with the repository): % su - rancid_user % cd % echo "new_device_name:device_type:up" >> /router.db % cp -p CVS//configs/old_device_name,v \ CVS//configs/new_device_name,v % cd /configs % cvs update where GROUP is the name of the rancid group that the device is a member of. Once the renaming is complete, remove the old name from the router.db file and leave the CVS clean-up of the old filename to rancid. If one wanted to move a device to a different group and maintain the history, the same procedure would work, substituting the new group name appropriately and editing the router.db of both old and new groups, of course. SVN provides a rename function; but we suggest that you use it's copy function instead, and leave the clean-up of the old name to rancid. So, you would use the copy function (proper substitutions, of course) in place of the cp in the CVS example, then commit the new file. Q. I am new to svn. Where can I find more information? A. The svn so-called "red book" is the definitive guide. http://svnbook.red-bean.com/en/1.5/svn-book.html Q. I am removing a group and would like to remove all traces of it from the rancid directory and the CVS repository. How is this done? A. As far as I know, CVS does not provide a way to remove directories. First, remove the group from /rancid.conf. If rancid is running, wait for it to complete. Then just recursively remove the directory. For example, a group named "fubar": % su - rancid_user % cd % rm -rf fubar CVS/fubar Q. I would like to place my CVS repository on a remote machine. How do I do that? A. Assuming that you're starting fresh, its quite simple. Before running rancid-cvs for the first time, adjust CVS_RSH & CVSROOT in rancid.conf similar to the following: CVS_RSH=ssh; export CVS_RSH CVSROOT="myhost:/fqpn/CVS"; export CVSROOT Note that CVS_RSH is not found in the sample rancid.conf that is distributed with rancid. Q. I need a web interface to the rancid CVS repository, for the CVS unsavvy. A. cvsweb works with rancid. Other similar software may as well. http://www.freebsd.org/projects/cvsweb.html cvsweb.conf: @CVSrepositories = ( 'rancid' => ['RANCID CVS, '/full_path_to_the_RANCID_CVS'], where the path will be /CVS. 3) General Q. I have a (set of) device(s) on which collection fails. How can I debug this? A. Our usual diagnostic procedure for this is: - Make sure that the appropriate *login (example: clogin for cisco) works. This tests to make sure you don't have routing or firewall issues, DNS or hostname errors, that your .cloginrc is correct, your banner does not have some character that *login does not like, and that the *login script doesn't have a bug of some sort. For example: clogin cisco_router Should login to cisco_router and produce a router prompt that you can use normally, as if clogin were not used (i.e.: telnet cisco_router). - See if commands can be executed on the router via clogin. This will exercise the *login functionality needed for rancid. For example: clogin -c 'show version; show diag' cisco_router Should login to cisco_router, run show version and show diag, then disconnect and exit. The output will be displayed on your terminal. - Then see if the correct rancid commands work against the router. For example: rancid cisco_router Should produce a cisco_router.new file (cooked to a golden rancid-style colour) in the current directory. If it does not, try again with the -d option, so that the cisco_router.new file will not be removed if an error is detected. Note: if you have NOPIPE set in your environment, a cisco_router.raw file will be produced that is the raw output of the dialogue with the device. If all of these work, make sure that the device's entry in the group's router.db file is correct and check the group's last log file for errors. Q. I am receiving persistent diffs for up/down/added/deleted devices in router.db, but nothing has changed and the cvs repository is up to date. A. Check that the configure process run during the installation of rancid determined the proper options for diff(1); look for diff in the control_rancid script. If you also run rancid from the command-line, be sure that your locale environment variables are consistent between your interactive and non- interactive (ie: cron) environments. On some O/Ses, the locale will affect the operation of sort(1). Q. Are there any characters in the banner that rancid has problems with OR I changed the device's command prompt and now collection is failing? A. The trickiest part about clogin (et al) is recognizing the prompt correctly. clogin looks for '>' and '#' to figure out if it is logged in or in enable mode. So if you have a '>' or '#' in your login banner (or other motd), then clogin gets confused and will not be able to log in correctly, and thus rancid will fail. Don't use '>' or '#', or whatever the termination character of the given device's prompt is, in your prompt or in your banner or other motd. Q. I use /*login -c to run commands on multiple boxes. Sometimes these are commands that take secondary input, like a filename. How can I enter the data for that secondary prompt? A. Two methods will work. Write an expect script to be used with clogin's -s option, for which a few examples come with rancid like cisco-load.exp. OR provide all the input in one command with the -c option like so: Router#clear counters Clear "show interface" counters on all interfaces [confirm] Router# clogin -c 'clear counters\n' The specific return (\n) will be entered after 'clear counters' followed by the normal return after the command. Some devices apparently eat the linefeed of the typical Unix \r\n sequence and require that a carriage- return be used instead (\r). Q. I would like to collect device configurations every hour, but only receive diffs every Nth collection or every N hours. Is this possible? A. Certainly, but rancid does not provide such a mechanism natively. Two approaches are recommended: 1) Using your preferred mail-list software, add a list with a digest and configure your MTA (example: sendmail) to send diffs to the list. Configure the mail-list software to force the digest at the interval desired. This allows folks to choose which type they prefer, after each collection or every N hours. This method also provides easy methods to archive the diff mail and retrieve previous diffs. 2) Write a script to send diffs, which saves the time it last ran and passes this to the -D option of CVS. Obviously, the first option is the cleanest and most featureful, which is why the script mentioned in the second option is not provided. Q. I'd like to have RANCID automatically begin collection when someone finishes configuring a router. How can I do this? A. Using a syslog watcher script, one can trigger RANCID from the syslog line emitted by, for example, an IOS router after configuration mode is ended. Here's a simple example using the Simple Event Correlator: (http://simple-evcorr.sourceforge.net/) If the syslog line in your logs looks like this (wrapped for readability): Apr 5 09:56:52 acc1.geo269.example.com 72: 000069: *Mar 6 21:40:13.466 \ AEDT: %SYS-5-CONFIG_I: Configured from console by gwbush on vty0 (10.1.1.1) You would use a SEC configuration stanza like this: # example rancid trigger # type=SingleWithSuppress ptype=RegExp pattern=\s\S+:\S+\S+\s(\S+)\.example\.com.*SYS-5-CONFIG_I action=shellcmd /opt/rancid/bin/do-diffs -r $1 window=1800 This will execute the command '/opt/rancid/bin/do-diffs -r acc1.geo269' when it is fed a line like that syslog line. The command will be run at most once every 1800 seconds. If you do not get hostnames in your log lines that match your router.db entries, either fix your reverse DNS or remove the '-r $1' part. Q. I would like to limit the permissions of the rancid user on my devices. Is this possible? A. Strictly speaking, no. Rancid needs permission to read device configuration and other data which is often not available to underprivileged users. However, if you use TACACS+, you can limit the commands that are available to a user. For example, to allow ping and show, but not "show tcp", and nothing else: user = rancid { cmd = "ping" { permit .* } cmd = "show" { deny tcp.* permit .* } # the default is to deny other commands } For RADIUS, Justin Grote suggested privilege levels: http://www.cisco.com/univercd/cc/td/doc/product/software/ios122/122newft/122t/122t13/ftprienh.htm Q. For approximately X hosts (configs) what size server should we be considering - speed and data storage? A. On modern machines it is unlikely you will have issues with disk space or memory - A heavily laden access router with a complex config won't consume more than a few megabytes of disk space for its configs over several years time (roughly 3 times the sum of all the config or */configs/* over 2 years is a decent approximation). Rancid is typically CPU bound if you have adequate network bandwidth. Experience shows rancid takes around 50 Mhz * minutes / device of processing power. This means that a 1Ghz machine can poll: 1000 Mhz * 60 (min/hour) / 50(Mhz min / device) = 1200 devices/hour That's obviously a ball park estimate which varies with many different factors such as the CPU type and the types of devices on your network. Q. How can I run rancid to make the most efficient use of resources (i.e. run in the shortest amount of time)? A. You can adjust PAR_COUNT in rancid.conf to achieve maximum efficiency during polling. You can watch the output of the standard unix command vmstat command during polling to determine whether or not the cpu is being wholly utilized - there should be little idle time and no process blocking (see vmstat). Another simpler method is to look at the time stamps on the rancid log files, and adjust PAR_COUNT until the least amount of time is taken during polling. Make sure all devices are being polled by rancid before using this method - failing devices can extend the amount of time rancid takes to finish by a *LONG* period and throw your times way off. It may help to run rancid niced (man nice) if it will be sharing resources with other processes, as it may eat whatever is available if PAR_COUNT is set high. This is done by changing the crontab to be something like: 5 * * * * nice -19 /usr/local/rancid/bin/rancid-run If you _do_ share resources with other processes but want rancid to run efficiently, probably the vmstat method above will work better - rancid may take a little longer to run but you won't be stepping on other people's toes. Q. I'm still stuck on this problem. Where can I get more help? A. A discussion list is available, rancid-discuss@shrubbery.net. You must be a subscriber to post. Subscribe like this: shell% echo "subscribe" | mail rancid-discuss-request@shrubbery.net Q. What else can I do with rancid? A. The possibilities are endless...rancid is non-toxic when applied properly. see Joe Abley and Stephen Stuart's NANOG presentation: http://www.nanog.org/mtg-0210/abley.html or our NANOG presentation: http://www.shrubbery.net/rancid/NANOG29/ 4) License Q. Please explain the RANCID license. A. Quite simple; read it. It is a slightly modified BSD license; it has an additional clause. rancid-2.3.8/README.lg100644 015615 000000 00000010000 11342156272 0007731This is a looking glass based on Ed Kern's which used to be available on http://nitrous.digex.net/. This version supports cisco, juniper, and foundry, using rancid's [cfj]login to login (so rcmd is not necessary, it can use telnet, ssh, or rsh), and has some additional commands implemented. There are a few cisco commands where either no juniper or foundry equivalent exists or we have not had time to implement yet. packing list: README This file. index.html often the default document the server will load, contains an html redirect to load lgform.cgi lg.conf looking glass configuration file lg.cgi work horse of the looking glass lgform.cgi front-end form for the looking glass engine lgnotes.html user info for the looking glass The looking glass requires the CGI and LockFile-Simple perl modules. these can be retrieved from CPAN, http://www.cpan.org/. CGI's home is ftp://ftp-genome.wi.mit.edu/pub/software/WWW/. It also requires the POSIX module (for strftime) and Sys::Syslog, which I believe comes with perl5 and/or are converted with h2ph(1). basic installation instructions: The configure and make install process will make variable substitutions and install the looking glass bits. Assuming configure was run without directory options, such as --prefix, the default install prefix is /usr/local/rancid. So, the bits will be installed in /usr/local/rancid/etc/lg.conf, /usr/local/rancid/bin, and /usr/local/rancid/share/rancid (i.e.: /etc/lg.conf, etc.). 1) Make the scripts and html files available to your server (httpd) by creating a directory in your server's document root directory (apache's httpd.conf "DocumentRoot" variable). For example: mkdir /usr/local/htdocs/lg Then either: - copy the files /share/rancid/{index.html,lgnotes.html} and /bin/{lg.cgi,lgform.cgi} to /usr/local/htdocs/lg OR - create symlinks from /usr/local/htdocs/lg to each of these files. Note on links: if you use symlinks, you have to configure apache to allow following symlinks. e.g.: % cat /usr/local/htdocs/lg/.htaccess Options FollowSymLinks ExecCGI Note on index.html: index.html is typically the default file loaded when a url ends with a '/'. index.html can be used to redirect this to lgform.cgi using a netscape meta refresh. Though this is supported by many browsers, it is supposedly netscape specific and non-standard. In apache, the same thing can be acheived by altering the default directory index like this: % cat /usr/local/htdocs/lg/.htaccess Options ExecCGI DirectoryIndex lgform.cgi 2) The looking glass scripts need to be able to find and read lg.conf. By default it is installed as /lg.conf (/etc/lg.conf) and the scripts will first look in their CWD (Current Working Directory) and then /lg.conf, if it does not exist in the CWD. However, the LG_CONF environment variable can be used to move it elsewhere. To get LG_CONF into the CGI enviroment, you can use SetEnvIf in apache's httpd.conf. For example: SetEnvIf Request_URI "\/lg/.*.cgi" LG_CONF=/usr/local/htdocs/lg/lg.conf Note: if you have chosen to locate your router.db (or other possibly sensitive files in the http docs heirarchy, you may wish to restrict download permission for these files. Something like: % cat /usr/local/htdocs/lg/.htaccess Order allow,deny Deny from all Satisfy All 3) Edit /lg.conf (usually /etc/lg.conf). See lg.conf(5) for additional information. 4) Set-up cron jobs to rotate the log file and clean out old cache files. See LG_CACHE_DIR & LG_LOG in lg.conf. Something like (YMMV): # rotate lookingglass log #0 0 * * * cd /usr/local/htdocs/lg/tmp; /usr/local/etc/savelog -m 666 -c14 lg.log 0 0 * * * cd /usr/local/htdocs/lg/tmp; /bin/mv lg.log lg.log.0 # clean out the lookingglass cache 0 0 * * * cd /usr/local/htdocs/lg/tmp; /usr/local/bin/find . -type f -maxdepth 1 \( \! -name lg.log\* \) -mtime +1 -exec rm -f {} \; rancid-2.3.8/UPGRADING100644 015615 000000 00000006770 11342156272 0007736Rancid 2.3 introduces a new directory layout. It has been changed to more closely follow the standard path hierarchy, which is defined by the FHS standard and autoconf, and/or make these locations more easily configurable within rancid. The obvious advantage of this is making rancid more easily packagable; i.e.: NetBSD pkgsrc, FreeBSD port, Linux RPM, etc. Make sure your rancid repository is quiet before upgrading; disable rancid cron jobs, wait for running jobs to complete, etc. Autoconf defines the following (see configure --help): Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [/usr/local/rancid] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --datadir=DIR read-only architecture-independent data [PREFIX/share] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --mandir=DIR man documentation [PREFIX/man] Also defined, though not mentioned above, is: pkgdatadir same as datadir, but datadir/rancid File and directory movement: bin/env the rancid configuration file has moved to sysconfdir/rancid.conf util/lg/lg.conf the looking glass configuration has moved to sysconfdir/lg.conf util/lg/lg.cgi util/lg/lgform.cgi the looking glass CGI scripts have moved to bindir util/lg/* the remainder of looking glass html, README, etc files have moved to pkgdatadir util/* misc examples, scripts, etc have moved to pkgdatadir cloginrc.sample moved to pkgdatadir For those upgrading, there is one basic choice to make; to move your CVS repository and logs or not. Prior to rancid 2.3, these were placed in . They are now in "localstatedir". The user who runs rancid will need write access to this directory. To maintain the same location as was used prior to rancid 2.3, provide the --localstatedir option to configure. e.g.: ./configure --localstatedir=/usr/local/rancid /usr/local/rancid is, and has been, the default . To move them elsewhere, accept the default (e.g.: /usr/local/rancid/var) or specify your own and move the existing directories. e.g.: ./configure --localstatedir=/var/rancid make install edit /rancid.conf # merge with your old bin/env # configuration file mv /usr/local/rancid/logs /var/rancid mv /usr/local/rancid/CVS /var/rancid cd /var/rancid su - rancid_user /bin/sh . /rancid.conf for grp in $LIST_OF_GROUPS; do cvs -d /var/rancid/CVS co $grp done Note that the first rancid-run will send messages about routers being added, marked up or down, etc., because the routers.{all,down,up} will have been lost. Afterward, it will be back to normal. Note also that any non-rancid files that may have been placed in these CVS trees will be lost. You have been warned. *** We strongly suggest that if a DIR used as the install prefix, as in --prefix=DIR, is not dedicated to rancid that "/rancid" should be appended to the --localstatedir, as in the example above. Note that not all operating systems have a mv command that will move directories across file systems. It may be necessary to use 'cp -r' or 'tar cf - | (cd ; tar xpf -)'. rancid-2.3.8/cloginrc.sample100644 015615 000000 00000007274 11433155067 0011500# comments are cool, as is whitespace # clogin supports a number of add directives: # password # user # userprompt # userpassword # passprompt # method # noenable # enauser # enableprompt # autoenable # cyphertype # identity # # Details on each of these follows. Also see cloginrc(5). # # add password # # add user # The default user is $USER (i.e.: the user running clogin). # # add userprompt # What the router prints to prompt for the username. # Default: {"(Username|login|user name):"} # # add userpassword # The password for user if different than the password set # using 'add password'. # # add passprompt # What the router prints to prompt for the password. # Default: {"(\[Pp]assword|passwd):"} # # add method {ssh} [...] # Defines, in order, which connection method(s) to use for a device # from the set {ssh,telnet,rsh}. e.g.: add method * {ssh} {telnet} {rsh} # will attempt ssh connection first. if ssh fails with connection # refused (i.e.: not due to authentication failure), then try telnet, # then rsh. # Default: {telnet} {ssh} # # add noenable <1> # equivalent of -noenable on the cmd line to not enable at login. # # add enableprompt # What the router prints to prompt for the enable password. # Default: {"\[Pp]assword:"} # # add enauser # This is only needed if enable asks for a username and this # username is different from what user is set to. # # add autoenable <1/0> # This is used if you are automatically enabled by the login process. # # add cyphertype # Default is 3des. # # add identity # Default is your default ssh identity. # # include # include a secondary .cloginrc file # # # Note: The first match for a hostname takes precedence. #add password sl-bb*-dc cow24 #add password sl-gw*-dc geeks #add password sl* hank dog #add password at* pete cow #add password sdn* mujahid horse #add password icm* peter #add password * anything # #add user sl-gw*-dc twit #add user sdn* sdn_auto #add user sdn-bb* ops_eng #add user * $env(USER) # customer x # these routers ask for a username and password. we automatically get # enable access after successful authentication. add user *.custx.net roger add password *.custx.net {doger} add autoenable *.custx.net 1 # customer y # this is the normal cisco login. a password followed by and enable password. # try ssh first, then rlogin. add password *.custy.net {vector} {victor} add method *.custy.net ssh rlogin # customer z; they use ssh only. add user *.custz.net shirley add password *.custz.net {jive} {surely} add method *.custz.net ssh # the route-server's do not provide enable access. cmdline -noenable # equivalent. add noenable route-server* 1 # all our routers, i.e.: everything else add password * {clearance} {clarence} # set ssh encryption type, dflt: 3des add cyphertype * {3des} # set the username prompt to "router login:" #add userprompt * {"router login:"} # ssh identity for a juniper; used with jlogin add identity my.juniper $env(HOME)/.ssh/juniper # riverstone / enterasys / cabletron (rivlogin) example # these boxes are 'back-to-front' from cisco (i.e., ask # for vty password always, then tac+/radius if configured). # # vty password and last resort (enable) password for rivlogin add password rs3000 {vtypass} {lastresort} # if using tac+ or radius login, include these lines add user rs3000 {monster} add userpassword rs3000 {scary} rancid-2.3.8/include/config.h100644 015615 000000 00000013240 11567540070 0011524/* include/config.h. Generated from config.h.in by configure. */ /* include/config.h.in. Generated from configure.in by autoheader. */ #ifndef CONFIG_H #define CONFIG_H 1 /* Define to 1 if you have the header file. */ #define HAVE_CTYPE_H 1 /* Define to 1 if you have the header file. */ #define HAVE_ERRNO_H 1 /* Define to 1 if you have the header file. */ #define HAVE_FCNTL_H 1 /* Define to 1 if you have the `index' function. */ #define HAVE_INDEX 1 /* Define to 1 if you have the header file. */ #define HAVE_INTTYPES_H 1 /* Define to 1 if you have the header file. */ #define HAVE_LIMITS_H 1 /* Define to 1 if you have the header file. */ #define HAVE_MALLOC_H 1 /* Define to 1 if you have the `memcpy' function. */ #define HAVE_MEMCPY 1 /* Define to 1 if you have the `memmove' function. */ #define HAVE_MEMMOVE 1 /* Define to 1 if you have the header file. */ #define HAVE_MEMORY_H 1 /* Define to 1 if you have the `memset' function. */ #define HAVE_MEMSET 1 /* Define to 1 if you have the `openpty' function. */ #define HAVE_OPENPTY 1 /* "define this if your o/s has /dev/ptmx" */ /* #undef HAVE_PTMX */ /* "define this for OSF/1 ptmx" */ /* #undef HAVE_PTMX_OSF */ /* Define to 1 if you have the `ptsname' function. */ /* #undef HAVE_PTSNAME */ /* Define to 1 if you have the header file. */ /* #undef HAVE_PTY_H */ /* Define to 1 if you have the `rindex' function. */ #define HAVE_RINDEX 1 /* Define to 1 if you have the header file. */ /* #undef HAVE_SIGINFO_H */ /* Define to 1 if you have the header file. */ #define HAVE_STDINT_H 1 /* Define to 1 if you have the header file. */ #define HAVE_STDLIB_H 1 /* Define to 1 if you have the `strchr' function. */ #define HAVE_STRCHR 1 /* Define to 1 if you have the `strerror' function. */ #define HAVE_STRERROR 1 /* Define to 1 if cpp supports the ANSI # stringizing operator. */ #define HAVE_STRINGIZE 1 /* Define to 1 if you have the header file. */ #define HAVE_STRINGS_H 1 /* Define to 1 if you have the header file. */ #define HAVE_STRING_H 1 /* Define to 1 if you have the header file. */ /* #undef HAVE_STROPTS_H */ /* Define to 1 if you have the `strrchr' function. */ #define HAVE_STRRCHR 1 /* Define to 1 if you have the `strrtok' function. */ /* #undef HAVE_STRRTOK */ /* Define to 1 if you have the `strstr' function. */ #define HAVE_STRSTR 1 /* Define to 1 if you have the `strtok' function. */ #define HAVE_STRTOK 1 /* Define to 1 if you have the header file. */ #define HAVE_SYSEXITS_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_STAT_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_TYPES_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_WAIT_H 1 /* Define to 1 if you have the header file. */ #define HAVE_UNISTD_H 1 /* Define to 1 if you have the `unsetenv' function. */ #define HAVE_UNSETENV 1 /* Define to 1 if you have the header file. */ #define HAVE_UTIL_H 1 /* Define to the address where bug reports for this package should be sent. */ #define PACKAGE_BUGREPORT "" /* Define to the full name of this package. */ #define PACKAGE_NAME "" /* Define to the full name and version of this package. */ #define PACKAGE_STRING "" /* Define to the one symbol short name of this package. */ #define PACKAGE_TARNAME "" /* Define to the home page for this package. */ #define PACKAGE_URL "" /* Define to the version of this package. */ #define PACKAGE_VERSION "" /* Define to 1 if the C compiler supports function prototypes. */ #define PROTOTYPES 1 /* Define as the return type of signal handlers (`int' or `void'). */ #define RETSIGTYPE void /* Define to 1 if you have the ANSI C header files. */ #define STDC_HEADERS 1 /* Define like PROTOTYPES; this can be used by system headers. */ #define __PROTOTYPES 1 /* Define to empty if `const' does not conform to ANSI C. */ /* #undef const */ /* Define to `__inline__' or `__inline' if that's what the C compiler calls it, or to nothing if 'inline' is not supported under any name. */ #ifndef __cplusplus /* #undef inline */ #endif /* Define to `unsigned int' if does not define. */ /* #undef size_t */ /* damned linux... */ #ifdef LINUX # define _GNU_SOURCE #endif #ifndef __P # if STDC_HEADERS # define __P(a) a # else # define __P(a) () # endif #endif #if HAVE_STDLIB_H # include #endif #if HAVE_UNISTD_H # include # include #elif HAVE_SYS_TYPES_H # include #endif #if HAVE_ERRNO_H # include #endif extern int errno; #if HAVE_STRING_H # include #endif #if HAVE_STRINGS_H # include #endif #if ! HAVE_STRERROR # define strerror(n) sys_errlist[n]; #endif #if HAVE_SYS_WAIT_H # include #endif #ifndef WEXITSTATUS # define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8) #endif #ifndef WIFEXITED # define WIFEXITED(stat_val) (((stat_val) & 255) == 0) #endif #if HAVE_MEMSET # define bzero(p,s) memset(p, 0, s) # define bcopy(s,d,l) memcpy(d, s, l) #endif #if HAVE_INDEX && ! HAVE_STRCHR # define index(s,c) strchr(s,c) #endif #if HAVE_SYSEXITS_H # include #else /* missing sysexits.h */ # define EX_OK 0 # define EX_USAGE 64 /* command line usage error */ # define EX_NOINPUT 66 /* cannot open input */ # define EX_TEMPFAIL 75 /* temp failure */ # define EX_OSERR 71 /* system error */ # define EX_CANTCREAT 73 /* can't create (user) output file */ # define EX_IOERR 74 /* input/output error */ # define EX_CONFIG 78 /* configuration error */ #endif #endif /* CONFIG_H */ rancid-2.3.8/include/version.h100644 015615 000000 00000000165 11712067165 0011747#ifndef VERSION_H #define VERSION_H /* pkg version */ char package[] = "rancid"; char version[] = "2.3.8"; #endif rancid-2.3.8/include/Makefile.am100644 015615 000000 00000005321 11342156264 0012142## Process this file with automake to produce Makefile.in ## A Makefile.in is supplied, in case you do not have automake. ## $Id: Makefile.am 1853 2007-11-16 01:33:38Z heas $ ## ## Copyright (c) 1997-2007 by Terrapin Communications, Inc. ## All rights reserved. ## ## This code is derived from software contributed to and maintained by ## Terrapin Communications, Inc. by Henry Kilmer, John Heasley, Andrew Partan, ## Pete Whiting, Austin Schutz, and Andrew Fort. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions ## are met: ## 1. Redistributions of source code must retain the above copyright ## notice, this list of conditions and the following disclaimer. ## 2. Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## 3. All advertising materials mentioning features or use of this software ## must display the following acknowledgement: ## This product includes software developed by Terrapin Communications, ## Inc. and its contributors for RANCID. ## 4. Neither the name of Terrapin Communications, Inc. nor the names of its ## contributors may be used to endorse or promote products derived from ## this software without specific prior written permission. ## 5. It is requested that non-binding fixes and modifications be contributed ## back to Terrapin Communications, Inc. ## ## THIS SOFTWARE IS PROVIDED BY Terrapin Communications, INC. AND CONTRIBUTORS ## ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ## TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COMPANY OR CONTRIBUTORS ## BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ## CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ## SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ## INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ## CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ## ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ## POSSIBILITY OF SUCH DAMAGE. # # The expect login scripts were based on Erik Sherk's gwtn, by permission. # # The original looking glass software was written by Ed Kern, provided by # permission and modified beyond recognition. #AUTOMAKE_OPTIONS=foreign no-dependencies AUTOMAKE_OPTIONS=foreign @SET_MAKE@ noinst_HEADERS= config.h version.h # no idea why automake doesnt clean these targets CLEANFILES= stamp-h stamp-h1 all: rancid-2.3.8/include/Makefile.in100644 015615 000000 00000027637 11661274063 0012173# Makefile.in generated by automake 1.11.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, # Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # # The expect login scripts were based on Erik Sherk's gwtn, by permission. # # The original looking glass software was written by Ed Kern, provided by # permission and modified beyond recognition. VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : subdir = include DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \ $(srcdir)/Makefile.in $(srcdir)/config.h.in \ $(srcdir)/version.h.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_HEADER = config.h CONFIG_CLEAN_FILES = version.h CONFIG_CLEAN_VPATH_FILES = SOURCES = DIST_SOURCES = HEADERS = $(noinst_HEADERS) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ADMINMAILPLUS = @ADMINMAILPLUS@ AMTAR = @AMTAR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ COMM = @COMM@ COPYYEARS = @COPYYEARS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CVS = @CVS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DIFF = @DIFF@ DIFF_CMD = @DIFF_CMD@ DIRNAME = @DIRNAME@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ENV_PATH = @ENV_PATH@ EXEEXT = @EXEEXT@ EXPECT_PATH = @EXPECT_PATH@ FIND = @FIND@ GREP = @GREP@ ID = @ID@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LG_PING_CMD = @LG_PING_CMD@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAILPLUS = @MAILPLUS@ MAKE = @MAKE@ MAKEINFO = @MAKEINFO@ MKDIR = @MKDIR@ MKDIR_P = @MKDIR_P@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERLV = @PERLV@ PERLV_PATH = @PERLV_PATH@ PING_PATH = @PING_PATH@ RCSSYS = @RCSSYS@ RSH = @RSH@ SENDMAIL = @SENDMAIL@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SORT = @SORT@ SSH = @SSH@ STRIP = @STRIP@ SVN = @SVN@ SVN_FSTYPE = @SVN_FSTYPE@ TAR = @TAR@ TELNET = @TELNET@ TOUCH = @TOUCH@ U = @U@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build_alias = @build_alias@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host_alias = @host_alias@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ #AUTOMAKE_OPTIONS=foreign no-dependencies AUTOMAKE_OPTIONS = foreign noinst_HEADERS = config.h version.h # no idea why automake doesnt clean these targets CLEANFILES = stamp-h stamp-h1 all: config.h $(MAKE) $(AM_MAKEFLAGS) all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign include/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign include/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): config.h: stamp-h1 @if test ! -f $@; then \ rm -f stamp-h1; \ $(MAKE) $(AM_MAKEFLAGS) stamp-h1; \ else :; fi stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status @rm -f stamp-h1 cd $(top_builddir) && $(SHELL) ./config.status include/config.h $(srcdir)/config.h.in: $(am__configure_deps) ($(am__cd) $(top_srcdir) && $(AUTOHEADER)) rm -f stamp-h1 touch $@ distclean-hdr: -rm -f config.h stamp-h1 version.h: $(top_builddir)/config.status $(srcdir)/version.h.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(HEADERS) config.h installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic distclean-hdr distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: all install-am install-strip .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ ctags distclean distclean-generic distclean-hdr distclean-tags \ distdir dvi dvi-am html html-am info info-am install \ install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \ uninstall-am @SET_MAKE@ all: # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: rancid-2.3.8/include/config.h.in100644 015615 000000 00000012640 11661274075 0012140/* include/config.h.in. Generated from configure.in by autoheader. */ #ifndef CONFIG_H #define CONFIG_H 1 /* Define to 1 if you have the header file. */ #undef HAVE_CTYPE_H /* Define to 1 if you have the header file. */ #undef HAVE_ERRNO_H /* Define to 1 if you have the header file. */ #undef HAVE_FCNTL_H /* Define to 1 if you have the `index' function. */ #undef HAVE_INDEX /* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H /* Define to 1 if you have the header file. */ #undef HAVE_LIMITS_H /* Define to 1 if you have the header file. */ #undef HAVE_MALLOC_H /* Define to 1 if you have the `memcpy' function. */ #undef HAVE_MEMCPY /* Define to 1 if you have the `memmove' function. */ #undef HAVE_MEMMOVE /* Define to 1 if you have the header file. */ #undef HAVE_MEMORY_H /* Define to 1 if you have the `memset' function. */ #undef HAVE_MEMSET /* Define to 1 if you have the `openpty' function. */ #undef HAVE_OPENPTY /* "define this if your o/s has /dev/ptmx" */ #undef HAVE_PTMX /* "define this for OSF/1 ptmx" */ #undef HAVE_PTMX_OSF /* Define to 1 if you have the `ptsname' function. */ #undef HAVE_PTSNAME /* Define to 1 if you have the header file. */ #undef HAVE_PTY_H /* Define to 1 if you have the `rindex' function. */ #undef HAVE_RINDEX /* Define to 1 if you have the header file. */ #undef HAVE_SIGINFO_H /* Define to 1 if you have the header file. */ #undef HAVE_STDINT_H /* Define to 1 if you have the header file. */ #undef HAVE_STDLIB_H /* Define to 1 if you have the `strchr' function. */ #undef HAVE_STRCHR /* Define to 1 if you have the `strerror' function. */ #undef HAVE_STRERROR /* Define to 1 if cpp supports the ANSI # stringizing operator. */ #undef HAVE_STRINGIZE /* Define to 1 if you have the header file. */ #undef HAVE_STRINGS_H /* Define to 1 if you have the header file. */ #undef HAVE_STRING_H /* Define to 1 if you have the header file. */ #undef HAVE_STROPTS_H /* Define to 1 if you have the `strrchr' function. */ #undef HAVE_STRRCHR /* Define to 1 if you have the `strrtok' function. */ #undef HAVE_STRRTOK /* Define to 1 if you have the `strstr' function. */ #undef HAVE_STRSTR /* Define to 1 if you have the `strtok' function. */ #undef HAVE_STRTOK /* Define to 1 if you have the header file. */ #undef HAVE_SYSEXITS_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_STAT_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TYPES_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_WAIT_H /* Define to 1 if you have the header file. */ #undef HAVE_UNISTD_H /* Define to 1 if you have the `unsetenv' function. */ #undef HAVE_UNSETENV /* Define to 1 if you have the header file. */ #undef HAVE_UTIL_H /* Define to the address where bug reports for this package should be sent. */ #undef PACKAGE_BUGREPORT /* Define to the full name of this package. */ #undef PACKAGE_NAME /* Define to the full name and version of this package. */ #undef PACKAGE_STRING /* Define to the one symbol short name of this package. */ #undef PACKAGE_TARNAME /* Define to the home page for this package. */ #undef PACKAGE_URL /* Define to the version of this package. */ #undef PACKAGE_VERSION /* Define to 1 if the C compiler supports function prototypes. */ #undef PROTOTYPES /* Define as the return type of signal handlers (`int' or `void'). */ #undef RETSIGTYPE /* Define to 1 if you have the ANSI C header files. */ #undef STDC_HEADERS /* Define like PROTOTYPES; this can be used by system headers. */ #undef __PROTOTYPES /* Define to empty if `const' does not conform to ANSI C. */ #undef const /* Define to `__inline__' or `__inline' if that's what the C compiler calls it, or to nothing if 'inline' is not supported under any name. */ #ifndef __cplusplus #undef inline #endif /* Define to `unsigned int' if does not define. */ #undef size_t /* damned linux... */ #ifdef LINUX # define _GNU_SOURCE #endif #ifndef __P # if STDC_HEADERS # define __P(a) a # else # define __P(a) () # endif #endif #if HAVE_STDLIB_H # include #endif #if HAVE_UNISTD_H # include # include #elif HAVE_SYS_TYPES_H # include #endif #if HAVE_ERRNO_H # include #endif extern int errno; #if HAVE_STRING_H # include #endif #if HAVE_STRINGS_H # include #endif #if ! HAVE_STRERROR # define strerror(n) sys_errlist[n]; #endif #if HAVE_SYS_WAIT_H # include #endif #ifndef WEXITSTATUS # define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8) #endif #ifndef WIFEXITED # define WIFEXITED(stat_val) (((stat_val) & 255) == 0) #endif #if HAVE_MEMSET # define bzero(p,s) memset(p, 0, s) # define bcopy(s,d,l) memcpy(d, s, l) #endif #if HAVE_INDEX && ! HAVE_STRCHR # define index(s,c) strchr(s,c) #endif #if HAVE_SYSEXITS_H # include #else /* missing sysexits.h */ # define EX_OK 0 # define EX_USAGE 64 /* command line usage error */ # define EX_NOINPUT 66 /* cannot open input */ # define EX_TEMPFAIL 75 /* temp failure */ # define EX_OSERR 71 /* system error */ # define EX_CANTCREAT 73 /* can't create (user) output file */ # define EX_IOERR 74 /* input/output error */ # define EX_CONFIG 78 /* configuration error */ #endif #endif /* CONFIG_H */ rancid-2.3.8/include/version.h.in100644 015615 000000 00000000165 11712046441 0012346#ifndef VERSION_H #define VERSION_H /* pkg version */ char package[] = "rancid"; char version[] = "2.3.8"; #endif rancid-2.3.8/etc/Makefile.am100644 015615 000000 00000011221 11342156264 0011266## Process this file with automake to produce Makefile.in ## A Makefile.in is supplied, in case you do not have automake. ## $Id: Makefile.am 1853 2007-11-16 01:33:38Z heas $ ## ## Copyright (c) 1997-2007 by Terrapin Communications, Inc. ## All rights reserved. ## ## This code is derived from software contributed to and maintained by ## Terrapin Communications, Inc. by Henry Kilmer, John Heasley, Andrew Partan, ## Pete Whiting, Austin Schutz, and Andrew Fort. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions ## are met: ## 1. Redistributions of source code must retain the above copyright ## notice, this list of conditions and the following disclaimer. ## 2. Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## 3. All advertising materials mentioning features or use of this software ## must display the following acknowledgement: ## This product includes software developed by Terrapin Communications, ## Inc. and its contributors for RANCID. ## 4. Neither the name of Terrapin Communications, Inc. nor the names of its ## contributors may be used to endorse or promote products derived from ## this software without specific prior written permission. ## 5. It is requested that non-binding fixes and modifications be contributed ## back to Terrapin Communications, Inc. ## ## THIS SOFTWARE IS PROVIDED BY Terrapin Communications, INC. AND CONTRIBUTORS ## ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ## TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COMPANY OR CONTRIBUTORS ## BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ## CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ## SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ## INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ## CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ## ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ## POSSIBILITY OF SUCH DAMAGE. # # The expect login scripts were based on Erik Sherk's gwtn, by permission. # # The original looking glass software was written by Ed Kern, provided by # permission and modified beyond recognition. #AUTOMAKE_OPTIONS=foreign no-dependencies AUTOMAKE_OPTIONS=foreign pkgdata_DATA= lg.conf.sample rancid.conf.sample EXTRA_DIST= $(pkgdata_DATA:%=%.in) CLEANFILES= $(pkgdata_DATA) if CONF_INSTALL DO_CONF_INSTALL=yes endif install-data-local: all @if test "$(DO_CONF_INSTALL)" = "yes"; then \ if test -f $(DESTDIR)$(sysconfdir)/rancid.conf ; then \ echo ""; \ echo "WARNING: *** $(DESTDIR)$(sysconfdir)/rancid.conf exists. See "; \ echo " *** $(pkgdatadir)/rancid.conf.sample for new"; \ echo " *** examples."; \ echo ""; \ else \ $(INSTALL_DATA) rancid.conf.sample $(DESTDIR)$(sysconfdir)/rancid.conf; \ fi; \ if test -f $(DESTDIR)$(sysconfdir)/lg.conf ; then \ echo ""; \ echo "WARNING: *** $(DESTDIR)$(sysconfdir)/lg.conf exists. See "; \ echo " *** $(pkgdatadir)/lg.conf.sample for new"; \ echo " *** examples."; \ echo ""; \ else \ $(INSTALL_DATA) lg.conf.sample $(DESTDIR)$(sysconfdir)/lg.conf; \ fi; \ fi #clean: # rm -f Makefile rancid.conf $(BIN_DATAS) $(BIN_PROGS) # auto_edit does the autoconf variable substitution. This allows the # substitution to have the full expansion of the variables, e.g.: $sysconfdir # will be /prefix/etc instead of ${prefix}/etc. # # This is a bit of a PITA, but is the method recommended by the autoconf # documentation. auto_edit = sed \ -e 's,@bindir\@,$(bindir),g' \ -e 's,@prefix\@,$(prefix),g' \ -e 's,@localstatedir\@,$(localstatedir),g' \ -e 's,@sysconfdir\@,$(sysconfdir),g' \ -e 's,@EXPECT_PATH\@,$(EXPECT_PATH),g' \ -e 's,@PERLV_PATH\@,$(PERLV_PATH),g' \ -e 's,@ENV_PATH\@,$(ENV_PATH),g' \ -e 's,@RCSSYS\@,$(RCSSYS),g' \ -e 's,@PACKAGE\@,$(PACKAGE),g' \ -e 's,@VERSION\@,$(VERSION),g' lg.conf.sample: Makefile $(srcdir)/lg.conf.sample.in rm -f lg.conf.sample lg.conf.sample.tmp; \ $(auto_edit) $(srcdir)/lg.conf.sample.in >lg.conf.sample.tmp; \ mv lg.conf.sample.tmp lg.conf.sample rancid.conf.sample: Makefile $(srcdir)/rancid.conf.sample.in rm -f rancid.conf.sample rancid.conf.sample.tmp; \ $(auto_edit) $(srcdir)/rancid.conf.sample.in >rancid.conf.sample.tmp; \ mv rancid.conf.sample.tmp rancid.conf.sample rancid-2.3.8/etc/Makefile.in100644 015615 000000 00000032534 11661274063 0011313# Makefile.in generated by automake 1.11.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, # Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # # The expect login scripts were based on Erik Sherk's gwtn, by permission. # # The original looking glass software was written by Ed Kern, provided by # permission and modified beyond recognition. VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : subdir = etc DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_HEADER = $(top_builddir)/include/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = SOURCES = DIST_SOURCES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__installdirs = "$(DESTDIR)$(pkgdatadir)" DATA = $(pkgdata_DATA) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ADMINMAILPLUS = @ADMINMAILPLUS@ AMTAR = @AMTAR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ COMM = @COMM@ COPYYEARS = @COPYYEARS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CVS = @CVS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DIFF = @DIFF@ DIFF_CMD = @DIFF_CMD@ DIRNAME = @DIRNAME@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ENV_PATH = @ENV_PATH@ EXEEXT = @EXEEXT@ EXPECT_PATH = @EXPECT_PATH@ FIND = @FIND@ GREP = @GREP@ ID = @ID@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LG_PING_CMD = @LG_PING_CMD@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAILPLUS = @MAILPLUS@ MAKE = @MAKE@ MAKEINFO = @MAKEINFO@ MKDIR = @MKDIR@ MKDIR_P = @MKDIR_P@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERLV = @PERLV@ PERLV_PATH = @PERLV_PATH@ PING_PATH = @PING_PATH@ RCSSYS = @RCSSYS@ RSH = @RSH@ SENDMAIL = @SENDMAIL@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SORT = @SORT@ SSH = @SSH@ STRIP = @STRIP@ SVN = @SVN@ SVN_FSTYPE = @SVN_FSTYPE@ TAR = @TAR@ TELNET = @TELNET@ TOUCH = @TOUCH@ U = @U@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build_alias = @build_alias@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host_alias = @host_alias@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ #AUTOMAKE_OPTIONS=foreign no-dependencies AUTOMAKE_OPTIONS = foreign pkgdata_DATA = lg.conf.sample rancid.conf.sample EXTRA_DIST = $(pkgdata_DATA:%=%.in) CLEANFILES = $(pkgdata_DATA) @CONF_INSTALL_TRUE@DO_CONF_INSTALL = yes #clean: # rm -f Makefile rancid.conf $(BIN_DATAS) $(BIN_PROGS) # auto_edit does the autoconf variable substitution. This allows the # substitution to have the full expansion of the variables, e.g.: $sysconfdir # will be /prefix/etc instead of ${prefix}/etc. # # This is a bit of a PITA, but is the method recommended by the autoconf # documentation. auto_edit = sed \ -e 's,@bindir\@,$(bindir),g' \ -e 's,@prefix\@,$(prefix),g' \ -e 's,@localstatedir\@,$(localstatedir),g' \ -e 's,@sysconfdir\@,$(sysconfdir),g' \ -e 's,@EXPECT_PATH\@,$(EXPECT_PATH),g' \ -e 's,@PERLV_PATH\@,$(PERLV_PATH),g' \ -e 's,@ENV_PATH\@,$(ENV_PATH),g' \ -e 's,@RCSSYS\@,$(RCSSYS),g' \ -e 's,@PACKAGE\@,$(PACKAGE),g' \ -e 's,@VERSION\@,$(VERSION),g' all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign etc/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign etc/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-pkgdataDATA: $(pkgdata_DATA) @$(NORMAL_INSTALL) test -z "$(pkgdatadir)" || $(MKDIR_P) "$(DESTDIR)$(pkgdatadir)" @list='$(pkgdata_DATA)'; test -n "$(pkgdatadir)" || list=; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgdatadir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgdatadir)" || exit $$?; \ done uninstall-pkgdataDATA: @$(NORMAL_UNINSTALL) @list='$(pkgdata_DATA)'; test -n "$(pkgdatadir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ test -n "$$files" || exit 0; \ echo " ( cd '$(DESTDIR)$(pkgdatadir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(pkgdatadir)" && rm -f $$files tags: TAGS TAGS: ctags: CTAGS CTAGS: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(DATA) installdirs: for dir in "$(DESTDIR)$(pkgdatadir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-data-local install-pkgdataDATA install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-pkgdataDATA .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic distclean \ distclean-generic distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am \ install-data-local install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-pkgdataDATA install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic pdf \ pdf-am ps ps-am uninstall uninstall-am uninstall-pkgdataDATA install-data-local: all @if test "$(DO_CONF_INSTALL)" = "yes"; then \ if test -f $(DESTDIR)$(sysconfdir)/rancid.conf ; then \ echo ""; \ echo "WARNING: *** $(DESTDIR)$(sysconfdir)/rancid.conf exists. See "; \ echo " *** $(pkgdatadir)/rancid.conf.sample for new"; \ echo " *** examples."; \ echo ""; \ else \ $(INSTALL_DATA) rancid.conf.sample $(DESTDIR)$(sysconfdir)/rancid.conf; \ fi; \ if test -f $(DESTDIR)$(sysconfdir)/lg.conf ; then \ echo ""; \ echo "WARNING: *** $(DESTDIR)$(sysconfdir)/lg.conf exists. See "; \ echo " *** $(pkgdatadir)/lg.conf.sample for new"; \ echo " *** examples."; \ echo ""; \ else \ $(INSTALL_DATA) lg.conf.sample $(DESTDIR)$(sysconfdir)/lg.conf; \ fi; \ fi lg.conf.sample: Makefile $(srcdir)/lg.conf.sample.in rm -f lg.conf.sample lg.conf.sample.tmp; \ $(auto_edit) $(srcdir)/lg.conf.sample.in >lg.conf.sample.tmp; \ mv lg.conf.sample.tmp lg.conf.sample rancid.conf.sample: Makefile $(srcdir)/rancid.conf.sample.in rm -f rancid.conf.sample rancid.conf.sample.tmp; \ $(auto_edit) $(srcdir)/rancid.conf.sample.in >rancid.conf.sample.tmp; \ mv rancid.conf.sample.tmp rancid.conf.sample # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: rancid-2.3.8/etc/lg.conf.sample.in100644 015615 000000 00000014363 11342156264 0012402# @PACKAGE@ @VERSION@ # configuration file for the looking glass # # note: these are perl statements! Mind the syntax. "perl -c lg.conf" # should succeed. # # adjust the path to find [cfj]login, telnet, ssh, rsh, etc. # $ENV{PATH}="@prefix@/bin:@ENV_PATH@"; # # # LG_CACHE_DIR is the location of the cache directory. the LG uses this # to hold lock files, the default log file (lg.log), and o/p from # commands that can be very verbose. it defaults to "tmp", # i.e.: relative to the directory where lg.cgi runs in your # server's (httpd) DocumentRoot (e.g.: # /usr/local/www/data/lg/tmp). # #$LG_CACHE_DIR="./tmp"; # # # LG_CACHE_TIME is the number of seconds the LG should cache o/p from certain # commands; those that tend to produce a lot of o/p, such as # 'show ip bgp dampened-paths'. it defaults to 600 seconds # (10 minutes). # #$LG_CACHE_TIME=600; # # # LG_CLOGINRC is the .cloginrc that the LG should use. it defaults to # /.cloginrc. note that the .cloginrc must be readable # by the user or group (UID / GID) that will be running the CGI # and the clogin (and friends) will not allow a world readable # .cloginrc. this is normally the user the server (httpd) runs # under. # #$LG_CLOGINRC="$ENV(HOME)/.cloginrc"; # # # LG_IMAGE is the filename of an image you wish to appear at the top # of the LG pages. it can also be other html goo, like # the first example. this is just handed to print, so \n and # the like will work and mind the character escapes (backslashes). # #$LG_IMAGE="\n FOO"; #$LG_IMAGE="\n"; # # # LG_INFO is info in html format to output at the bottom of main form. # it might be local contact information, disclaimer, etc. this # is just handed to print, so \n and the like will work and mind # the character escapes (backslashes). # #$LG_INFO="For support, contact webmaster"; # # # LG_LOG is either a FQPN (fully qualified path name) or the syslog # facility to use for logging. if not defined, the LG # will log to LG_CACHE_DIR/lg.log. possible syslog facility # values are from the facility codes in /usr/include/syslog.h # minus the 'LOG_' and lower case. # #$LG_LOG="$LG_CACHE_DIR/lg.log"; #$LG_LOG="/tmp/lg.log"; #$LG_LOG="local0"; # # # LG_ROUTERDB is the router.db in rancid's router.db format, listing # the routers and their platform that should be available to # the looking glass. if defined, the LG will use this variable # to find the router.db. if not defined, it will look for it # at //router.db. if it does not exist, it # will build the list from /*/router.db (i.e.: the # router.db's from all your groups). note that if you choose # this last option; the group directories and router.db files' # modes may have to be changed, depending upon the UID/GID of # the user your server (httpd) runs under, since rancid's default # mask is 007 (see etc/rancid.conf). routers not marked 'up' are # skipped. # #$LG_ROUTERDB="@sysconfdir@/router.db"; # # # LG_STYLE define a style sheet to be used for formatting HTML. # #$LG_STYLE="http://www.your.site/style/style.css"; # # # Options: # # LG_AS_REG *** not implemented. # #@LG_AS_REG=(); # # # LG_BGP_RT allows a few bgp commands which can produce long output (heavy # router load), such as sh ip bgp neighbor advertised-routes # would for a transit customer or sh ip b neigh # received-routes would for a transit provider. # #$LG_BGP_RT=1; # # # LG_SINGLE serializes and limits queries per-router to one at a time via # per-router lock files. # #$LG_SINGLE=0; # # LG_STRIP strips login o/p from the looking glass results. Expect # occassionally screws up disabling echo when passwords are # entered (NOTE: SECURITY CONCERN). However, this o/p can be # very useful for debugging clogin/flogin/jlogin problems. # $LG_STRIP=1; # # # Commands/Queries: # Un-comment/Comment the commands that are desired/not desired. # The Commands are separated into a few categories. The value # of each variable is the string which will appear in the # (lgform.cgi) menu. Mind the ,'s within hash assignments. # # The double-commented (##) queries are not implemented or have # not been tested. # $queries = {}; # # Interface queries $queries->{"interface"} = { framerelay => "show frame-relay PVC [DLCI]", interface => "show interface [interface]" }; # # Routing queries $queries->{"routing"} = { damp => "show ip bgp dampened-paths", neighbor => "show ip bgp neighbor ", prefix => "show ip bgp [netmask]", prefixlist => "show ip prefix-list ", regex => "show ip bgp regex ", route => "show ip route [netmask]", routemap => "show route-map ", summary => "show ip bgp summary" }; # # Debug queries $queries->{"debug"} = { log => "Show Logs [ | ]", ping => "ping ", trace => "traceroute " }; # # Multicast queries $queries->{"multicast"} = { mbgp => "Show ip mbgp [netmask]", mbgpsum => "Show ip mbgp summary", # show ip pim interface/show pim interface ## pim_interface => "Show PIM Interfaces", # ???/show pim join (extensive) ## pim_join => "Show PIM Join [group_address]", # show ip mroute/show multicast route [active] ## mroute => "Show Multicast Forwarding Table [active]", # show ip msdp summary/show msdp ## msdp => "Show MSDP Peering Status", # show ip msdp sa cache/show msdp source-active ## msdpsa => "Show MSDP Source Active Table", # show ip sdr|show multicast sessions ## msess => "Show Multicast SDR sessions [detail]", # show ip pim neighbor/show pim neighbors ## pim_neighbor => "Show PIM Neighbors [detail]", # show ip pim rp mapping/show pim rps ## pim_rp => "Show PIM Rendez-vous Points [detail]", # show ip rpf [address] /show multicast rpf [address] ## rpf => "Test Multicast RPF
" }; # # IPv6 commands $queries->{"ipv6"} = { # show bgp ipv6 / ??? ## v6_bgp => "Show IPv6 BGP table"; # show ipv6 interface / show interface ## v6_interface => "Show IPv6 interface parameters [interface]"; # show bgp ipv6 summary / show bgp summary ## v6_summary => "Show IPv6 BGP Summary"; # show ipv6 route / show route table inet6.0 ## v6_route => "Show IPv6 Routes "; }; # # %EOF% rancid-2.3.8/etc/rancid.conf.sample.in100644 015615 000000 00000007255 11665257036 0013251# @PACKAGE@ @VERSION@ # This file sets up the environment used for rancid. see rancid.conf(5) # # This will be site specific # TERM=network;export TERM # # Collating locale LC_COLLATE="POSIX"; export LC_COLLATE # # Create files w/o world read/write/exec permissions, but read/exec permissions # for group. umask 027 # # Under BASEDIR (i.e.: --localstatedir), there will be a "logs" directory for # the logs from rancid and a directory for each group of routers defined in # LIST_OF_GROUPS (below). In addition to these, there will be a "CVS" # directory which is the cvs (or Subversion) repository. # # Use a full path (no sym-links) for BASEDIR. # TMPDIR=/tmp; export TMPDIR # Be careful changing this, it affects CVSROOT below. It should be a FQPN, not # relative. BASEDIR=@localstatedir@; export BASEDIR PATH=@bindir@:@ENV_PATH@; export PATH # Location of the CVS/SVN repository. Be careful changing this. # If RCSSYS is svn, this can be: # - an (absolute) path (a subdirectory of BASEDIR by default). # - any URL that subversion understands, but beware that: # - no attempt will be made to create the repository when running rancid-cvs. # - authentication credentials, if necessary, MUST be cached (see the SVN # book, Ch. 3, Network Model, Caching credentials) before non-interactive # commands can run, e.g. by running rancid-cvs after installation. CVSROOT=$BASEDIR/CVS; export CVSROOT # Location of log files produced by rancid-run(1). LOGDIR=$BASEDIR/logs; export LOGDIR # # Select which RCS system to use, "cvs" (default) or "svn". Do not change # this after CVSROOT has been created with rancid-cvs. Changing between these # requires manual conversions. RCSSYS=@RCSSYS@; export RCSSYS # # if ACLSORT is NO, access-lists will NOT be sorted. #ACLSORT=YES; export ACLSORT # # if NOPIPE is set, temp files will be used instead of a cmd pipe during # collection from the router(s). #NOPIPE=YES; export NOPIPE # # FILTER_PWDS determines which passwords are filtered from configs by the # value set (NO | YES | ALL). see rancid.conf(5). #FILTER_PWDS=YES; export FILTER_PWDS # # if NOCOMMSTR is set, snmp community strings will be stripped from the configs #NOCOMMSTR=YES; export NOCOMMSTR # # How many times failed collections are retried (for each run) before # giving up. Minimum: 1 #MAX_ROUNDS=4; export MAX_ROUNDS # # How many hours should pass before complaining about routers that # can not be reached. The value should be greater than the number # of hours between your rancid-run cron job. Default: 24 #OLDTIME=4; export OLDTIME # # How many hours should pass before complaining that a group's collection # (the age of it's lock file) is hung. #LOCKTIME=4; export LOCKTIME # # The number of devices to collect simultaneously. #PAR_COUNT=5; export PAR_COUNT # # list of rancid groups #LIST_OF_GROUPS="sl joebobisp" # more groups... #LIST_OF_GROUPS="$LIST_OF_GROUPS noc billybobisp" # # For each group, define a list of people to receive the diffs. # in sendmail's /etc/aliases. # rancid-group: joe,moe@foo # rancid-admin-group: hostmaster # be sure to read ../README regarding aliases. # # If your MTA configuration is broken or you want mail to be forwarded to a # domain not the same as the local one, define that domain here. "@" must be # included, as this is simply appended to the usual recipients. It is NOT # appended to recipients specified in rancid-run's -m option. #MAILDOMAIN="@example.com"; export MAILDOMAIN # # By default, rancid mail is marked with precedence "bulk". This may be # changed by setting the MAILHEADERS variable; for example no header by setting # it to "" or adding X- style headers. Individual headers must be separated # by a \n. #MAILHEADERS="Precedence: bulk"; export MAILHEADERS rancid-2.3.8/bin/Makefile.am100644 015615 000000 00000012364 11661274022 0011271## Process this file with automake to produce Makefile.in ## A Makefile.in is supplied, in case you do not have automake. ## $Id: Makefile.am 2334 2011-11-17 21:09:37Z heas $ ## ## Copyright (c) 1997-2008 by Terrapin Communications, Inc. ## All rights reserved. ## ## This code is derived from software contributed to and maintained by ## Terrapin Communications, Inc. by Henry Kilmer, John Heasley, Andrew Partan, ## Pete Whiting, Austin Schutz, and Andrew Fort. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions ## are met: ## 1. Redistributions of source code must retain the above copyright ## notice, this list of conditions and the following disclaimer. ## 2. Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## 3. All advertising materials mentioning features or use of this software ## must display the following acknowledgement: ## This product includes software developed by Terrapin Communications, ## Inc. and its contributors for RANCID. ## 4. Neither the name of Terrapin Communications, Inc. nor the names of its ## contributors may be used to endorse or promote products derived from ## this software without specific prior written permission. ## 5. It is requested that non-binding fixes and modifications be contributed ## back to Terrapin Communications, Inc. ## ## THIS SOFTWARE IS PROVIDED BY Terrapin Communications, INC. AND CONTRIBUTORS ## ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ## TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COMPANY OR CONTRIBUTORS ## BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ## CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ## SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ## INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ## CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ## ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ## POSSIBILITY OF SUCH DAMAGE. # # The expect login scripts were based on Erik Sherk's gwtn, by permission. # # The original looking glass software was written by Ed Kern, provided by # permission and modified beyond recognition. #AUTOMAKE_OPTIONS=foreign no-dependencies AUTOMAKE_OPTIONS=foreign bin_PROGRAMS = hpuifilter bin_SCRIPTS = agmrancid alogin arancid arrancid avologin avorancid blogin \ brancid cat5rancid clogin control_rancid cssrancid elogin erancid \ f5rancid f10rancid flogin fnlogin fnrancid francid hlogin hrancid \ htlogin htrancid jerancid jlogin jrancid mrancid mrvlogin mrvrancid \ mtlogin mtrancid nlogin nrancid nslogin nsrancid nxrancid par prancid \ rancid-fe rancid rivlogin rivrancid rrancid srancid tlogin tntlogin \ tntrancid trancid xrancid xrrancid zrancid bin_SCRIPTS += lg.cgi lgform.cgi rancid-cvs rancid-run EXTRA_DIST= lg.cgi.in lgform.cgi.in rancid-cvs.in rancid-run.in #dist_bin_SCRIPTS= $(bin_SCRIPTS:%=%.in) CLEANFILES= lg.cgi lgform.cgi rancid-cvs rancid-run #CLEANFILES= $(bin_SCRIPTS) hpuifilter_SOURCES = hpuifilter.c #CPPFLAGS += @PG_CPPFLAGS@ #INCLUDES += -I$(top_srcdir)/include @PG_CPPFLAGS@ #INCLUDES += -I$(top_srcdir)/include #CFLAGS += -g CFLAGS = -g -O0 YFLAGS = -d #LFLAGS = -i # no idea why automake doesnt clean these targets #CLEANFILES= y.tab.c y.tab.h lex.yy.c conf.h conf.c conflex.c #clean: # rm -f Makefile env $(BIN_DATAS) $(BIN_PROGS) # auto_edit does the autoconf variable substitution. This allows the # substitution to have the full expansion of the variables, e.g.: $sysconfdir # will be /prefix/etc instead of ${prefix}/etc. # # This is a bit of a PITA, but is the method recommended by the autoconf # documentation. auto_edit = sed \ -e 's,@prefix\@,$(prefix),g' \ -e 's,@localstatedir\@,$(localstatedir),g' \ -e 's,@sysconfdir\@,$(sysconfdir),g' \ -e 's,@EXPECT_PATH\@,$(EXPECT_PATH),g' \ -e 's,@PERLV\@,$(PERLV),g' \ -e 's,@PERLV_PATH\@,$(PERLV_PATH),g' \ -e 's,@LG_PING_CMD\@,$(LG_PING_CMD),g' \ -e 's,@ADMINMAILPLUS\@,$(ADMINMAILPLUS),g' \ -e 's,@MAILPLUS\@,$(MAILPLUS),g' \ -e 's,@PACKAGE\@,$(PACKAGE),g' \ -e 's,@SVN_FSTYPE\@,$(SVN_FSTYPE),g' \ -e 's,@VERSION\@,$(VERSION),g' \ -e 's,@COPYYEARS\@,$(COPYYEARS),g' lg.cgi: Makefile $(srcdir)/lg.cgi.in rm -f lg.cgi lg.cgi.tmp; \ $(auto_edit) $(srcdir)/lg.cgi.in >lg.cgi.tmp; \ chmod +x lg.cgi.tmp; \ mv lg.cgi.tmp lg.cgi lgform.cgi: Makefile $(srcdir)/lgform.cgi.in rm -f lgform.cgi lgform.cgi.tmp; \ $(auto_edit) $(srcdir)/lgform.cgi.in >lgform.cgi.tmp; \ chmod +x lgform.cgi.tmp; \ mv lgform.cgi.tmp lgform.cgi rancid-cvs: Makefile $(srcdir)/rancid-cvs.in rm -f rancid-cvs rancid-cvs.tmp; \ $(auto_edit) $(srcdir)/rancid-cvs.in >rancid-cvs.tmp; \ chmod +x rancid-cvs.tmp; \ mv rancid-cvs.tmp rancid-cvs rancid-run: Makefile $(srcdir)/rancid-run.in rm -f rancid-run rancid-run.tmp; \ $(auto_edit) $(srcdir)/rancid-run.in >rancid-run.tmp; \ chmod +x rancid-run.tmp; \ mv rancid-run.tmp rancid-run $(bin_PROGRAMS) $(bin_SCRIPTS): ../include/version.h rancid-2.3.8/bin/Makefile.in100644 015615 000000 00000066652 11661274063 0011320# Makefile.in generated by automake 1.11.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, # Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # # The expect login scripts were based on Erik Sherk's gwtn, by permission. # # The original looking glass software was written by Ed Kern, provided by # permission and modified beyond recognition. VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : bin_PROGRAMS = hpuifilter$(EXEEXT) subdir = bin DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ $(srcdir)/agmrancid.in $(srcdir)/alogin.in \ $(srcdir)/arancid.in $(srcdir)/arrancid.in \ $(srcdir)/avologin.in $(srcdir)/avorancid.in \ $(srcdir)/blogin.in $(srcdir)/brancid.in \ $(srcdir)/cat5rancid.in $(srcdir)/clogin.in \ $(srcdir)/control_rancid.in $(srcdir)/cssrancid.in \ $(srcdir)/elogin.in $(srcdir)/erancid.in \ $(srcdir)/f10rancid.in $(srcdir)/f5rancid.in \ $(srcdir)/flogin.in $(srcdir)/fnlogin.in $(srcdir)/fnrancid.in \ $(srcdir)/francid.in $(srcdir)/hlogin.in $(srcdir)/hrancid.in \ $(srcdir)/htlogin.in $(srcdir)/htrancid.in \ $(srcdir)/jerancid.in $(srcdir)/jlogin.in $(srcdir)/jrancid.in \ $(srcdir)/mrancid.in $(srcdir)/mrvlogin.in \ $(srcdir)/mrvrancid.in $(srcdir)/mtlogin.in \ $(srcdir)/mtrancid.in $(srcdir)/nlogin.in $(srcdir)/nrancid.in \ $(srcdir)/nslogin.in $(srcdir)/nsrancid.in \ $(srcdir)/nxrancid.in $(srcdir)/par.in $(srcdir)/prancid.in \ $(srcdir)/rancid-fe.in $(srcdir)/rancid.in \ $(srcdir)/rivlogin.in $(srcdir)/rivrancid.in \ $(srcdir)/rrancid.in $(srcdir)/srancid.in $(srcdir)/tlogin.in \ $(srcdir)/tntlogin.in $(srcdir)/tntrancid.in \ $(srcdir)/trancid.in $(srcdir)/xrancid.in \ $(srcdir)/xrrancid.in $(srcdir)/zrancid.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_HEADER = $(top_builddir)/include/config.h CONFIG_CLEAN_FILES = control_rancid par rancid-fe agmrancid alogin \ arancid arrancid avologin avorancid blogin brancid cat5rancid \ clogin rancid cssrancid elogin erancid f5rancid f10rancid \ flogin francid fnlogin fnrancid hlogin hrancid htlogin \ htrancid jlogin jrancid jerancid mrancid mrvlogin mrvrancid \ mtrancid mtlogin nlogin nrancid nslogin nsrancid nxrancid \ prancid rivlogin rivrancid rrancid srancid tlogin tntlogin \ tntrancid trancid xrancid xrrancid zrancid CONFIG_CLEAN_VPATH_FILES = am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(bindir)" PROGRAMS = $(bin_PROGRAMS) am_hpuifilter_OBJECTS = hpuifilter.$(OBJEXT) hpuifilter_OBJECTS = $(am_hpuifilter_OBJECTS) hpuifilter_LDADD = $(LDADD) am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' SCRIPTS = $(bin_SCRIPTS) DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ SOURCES = $(hpuifilter_SOURCES) DIST_SOURCES = $(hpuifilter_SOURCES) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ADMINMAILPLUS = @ADMINMAILPLUS@ AMTAR = @AMTAR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ #CPPFLAGS += @PG_CPPFLAGS@ #INCLUDES += -I$(top_srcdir)/include @PG_CPPFLAGS@ #INCLUDES += -I$(top_srcdir)/include #CFLAGS += -g CFLAGS = -g -O0 COMM = @COMM@ COPYYEARS = @COPYYEARS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CVS = @CVS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DIFF = @DIFF@ DIFF_CMD = @DIFF_CMD@ DIRNAME = @DIRNAME@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ENV_PATH = @ENV_PATH@ EXEEXT = @EXEEXT@ EXPECT_PATH = @EXPECT_PATH@ FIND = @FIND@ GREP = @GREP@ ID = @ID@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LG_PING_CMD = @LG_PING_CMD@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAILPLUS = @MAILPLUS@ MAKE = @MAKE@ MAKEINFO = @MAKEINFO@ MKDIR = @MKDIR@ MKDIR_P = @MKDIR_P@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERLV = @PERLV@ PERLV_PATH = @PERLV_PATH@ PING_PATH = @PING_PATH@ RCSSYS = @RCSSYS@ RSH = @RSH@ SENDMAIL = @SENDMAIL@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SORT = @SORT@ SSH = @SSH@ STRIP = @STRIP@ SVN = @SVN@ SVN_FSTYPE = @SVN_FSTYPE@ TAR = @TAR@ TELNET = @TELNET@ TOUCH = @TOUCH@ U = @U@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build_alias = @build_alias@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host_alias = @host_alias@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ #AUTOMAKE_OPTIONS=foreign no-dependencies AUTOMAKE_OPTIONS = foreign bin_SCRIPTS = agmrancid alogin arancid arrancid avologin avorancid \ blogin brancid cat5rancid clogin control_rancid cssrancid \ elogin erancid f5rancid f10rancid flogin fnlogin fnrancid \ francid hlogin hrancid htlogin htrancid jerancid jlogin \ jrancid mrancid mrvlogin mrvrancid mtlogin mtrancid nlogin \ nrancid nslogin nsrancid nxrancid par prancid rancid-fe rancid \ rivlogin rivrancid rrancid srancid tlogin tntlogin tntrancid \ trancid xrancid xrrancid zrancid lg.cgi lgform.cgi rancid-cvs \ rancid-run EXTRA_DIST = lg.cgi.in lgform.cgi.in rancid-cvs.in rancid-run.in #dist_bin_SCRIPTS= $(bin_SCRIPTS:%=%.in) CLEANFILES = lg.cgi lgform.cgi rancid-cvs rancid-run #CLEANFILES= $(bin_SCRIPTS) hpuifilter_SOURCES = hpuifilter.c YFLAGS = -d #LFLAGS = -i # no idea why automake doesnt clean these targets #CLEANFILES= y.tab.c y.tab.h lex.yy.c conf.h conf.c conflex.c #clean: # rm -f Makefile env $(BIN_DATAS) $(BIN_PROGS) # auto_edit does the autoconf variable substitution. This allows the # substitution to have the full expansion of the variables, e.g.: $sysconfdir # will be /prefix/etc instead of ${prefix}/etc. # # This is a bit of a PITA, but is the method recommended by the autoconf # documentation. auto_edit = sed \ -e 's,@prefix\@,$(prefix),g' \ -e 's,@localstatedir\@,$(localstatedir),g' \ -e 's,@sysconfdir\@,$(sysconfdir),g' \ -e 's,@EXPECT_PATH\@,$(EXPECT_PATH),g' \ -e 's,@PERLV\@,$(PERLV),g' \ -e 's,@PERLV_PATH\@,$(PERLV_PATH),g' \ -e 's,@LG_PING_CMD\@,$(LG_PING_CMD),g' \ -e 's,@ADMINMAILPLUS\@,$(ADMINMAILPLUS),g' \ -e 's,@MAILPLUS\@,$(MAILPLUS),g' \ -e 's,@PACKAGE\@,$(PACKAGE),g' \ -e 's,@SVN_FSTYPE\@,$(SVN_FSTYPE),g' \ -e 's,@VERSION\@,$(VERSION),g' \ -e 's,@COPYYEARS\@,$(COPYYEARS),g' all: all-am .SUFFIXES: .SUFFIXES: .c .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign bin/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign bin/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): control_rancid: $(top_builddir)/config.status $(srcdir)/control_rancid.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ par: $(top_builddir)/config.status $(srcdir)/par.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ rancid-fe: $(top_builddir)/config.status $(srcdir)/rancid-fe.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ agmrancid: $(top_builddir)/config.status $(srcdir)/agmrancid.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ alogin: $(top_builddir)/config.status $(srcdir)/alogin.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ arancid: $(top_builddir)/config.status $(srcdir)/arancid.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ arrancid: $(top_builddir)/config.status $(srcdir)/arrancid.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ avologin: $(top_builddir)/config.status $(srcdir)/avologin.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ avorancid: $(top_builddir)/config.status $(srcdir)/avorancid.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ blogin: $(top_builddir)/config.status $(srcdir)/blogin.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ brancid: $(top_builddir)/config.status $(srcdir)/brancid.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ cat5rancid: $(top_builddir)/config.status $(srcdir)/cat5rancid.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ clogin: $(top_builddir)/config.status $(srcdir)/clogin.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ rancid: $(top_builddir)/config.status $(srcdir)/rancid.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ cssrancid: $(top_builddir)/config.status $(srcdir)/cssrancid.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ elogin: $(top_builddir)/config.status $(srcdir)/elogin.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ erancid: $(top_builddir)/config.status $(srcdir)/erancid.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ f5rancid: $(top_builddir)/config.status $(srcdir)/f5rancid.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ f10rancid: $(top_builddir)/config.status $(srcdir)/f10rancid.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ flogin: $(top_builddir)/config.status $(srcdir)/flogin.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ francid: $(top_builddir)/config.status $(srcdir)/francid.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ fnlogin: $(top_builddir)/config.status $(srcdir)/fnlogin.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ fnrancid: $(top_builddir)/config.status $(srcdir)/fnrancid.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ hlogin: $(top_builddir)/config.status $(srcdir)/hlogin.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ hrancid: $(top_builddir)/config.status $(srcdir)/hrancid.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ htlogin: $(top_builddir)/config.status $(srcdir)/htlogin.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ htrancid: $(top_builddir)/config.status $(srcdir)/htrancid.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ jlogin: $(top_builddir)/config.status $(srcdir)/jlogin.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ jrancid: $(top_builddir)/config.status $(srcdir)/jrancid.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ jerancid: $(top_builddir)/config.status $(srcdir)/jerancid.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ mrancid: $(top_builddir)/config.status $(srcdir)/mrancid.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ mrvlogin: $(top_builddir)/config.status $(srcdir)/mrvlogin.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ mrvrancid: $(top_builddir)/config.status $(srcdir)/mrvrancid.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ mtrancid: $(top_builddir)/config.status $(srcdir)/mtrancid.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ mtlogin: $(top_builddir)/config.status $(srcdir)/mtlogin.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ nlogin: $(top_builddir)/config.status $(srcdir)/nlogin.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ nrancid: $(top_builddir)/config.status $(srcdir)/nrancid.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ nslogin: $(top_builddir)/config.status $(srcdir)/nslogin.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ nsrancid: $(top_builddir)/config.status $(srcdir)/nsrancid.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ nxrancid: $(top_builddir)/config.status $(srcdir)/nxrancid.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ prancid: $(top_builddir)/config.status $(srcdir)/prancid.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ rivlogin: $(top_builddir)/config.status $(srcdir)/rivlogin.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ rivrancid: $(top_builddir)/config.status $(srcdir)/rivrancid.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ rrancid: $(top_builddir)/config.status $(srcdir)/rrancid.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ srancid: $(top_builddir)/config.status $(srcdir)/srancid.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ tlogin: $(top_builddir)/config.status $(srcdir)/tlogin.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ tntlogin: $(top_builddir)/config.status $(srcdir)/tntlogin.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ tntrancid: $(top_builddir)/config.status $(srcdir)/tntrancid.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ trancid: $(top_builddir)/config.status $(srcdir)/trancid.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ xrancid: $(top_builddir)/config.status $(srcdir)/xrancid.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ xrrancid: $(top_builddir)/config.status $(srcdir)/xrrancid.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ zrancid: $(top_builddir)/config.status $(srcdir)/zrancid.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)" @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p; \ then echo "$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) files[d] = files[d] " " $$1; \ else { print "f", $$3 "/" $$4, $$1; } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ } \ ; done uninstall-binPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -e 's/$$/$(EXEEXT)/' `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(bindir)" && rm -f $$files clean-binPROGRAMS: -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) hpuifilter$(EXEEXT): $(hpuifilter_OBJECTS) $(hpuifilter_DEPENDENCIES) @rm -f hpuifilter$(EXEEXT) $(LINK) $(hpuifilter_OBJECTS) $(hpuifilter_LDADD) $(LIBS) install-binSCRIPTS: $(bin_SCRIPTS) @$(NORMAL_INSTALL) test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)" @list='$(bin_SCRIPTS)'; test -n "$(bindir)" || list=; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ if test -f "$$d$$p"; then echo "$$d$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n' \ -e 'h;s|.*|.|' \ -e 'p;x;s,.*/,,;$(transform)' | sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1; } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) { files[d] = files[d] " " $$1; \ if (++n[d] == $(am__install_max)) { \ print "f", d, files[d]; n[d] = 0; files[d] = "" } } \ else { print "f", d "/" $$4, $$1 } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_SCRIPT) $$files '$(DESTDIR)$(bindir)$$dir'"; \ $(INSTALL_SCRIPT) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ } \ ; done uninstall-binSCRIPTS: @$(NORMAL_UNINSTALL) @list='$(bin_SCRIPTS)'; test -n "$(bindir)" || exit 0; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 's,.*/,,;$(transform)'`; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(bindir)" && rm -f $$files mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hpuifilter.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(PROGRAMS) $(SCRIPTS) installdirs: for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(bindir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-binPROGRAMS clean-generic mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-binPROGRAMS install-binSCRIPTS install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-binPROGRAMS uninstall-binSCRIPTS .MAKE: install-am install-strip .PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \ clean-generic ctags distclean distclean-compile \ distclean-generic distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-binPROGRAMS \ install-binSCRIPTS install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-compile mostlyclean-generic pdf pdf-am ps ps-am \ tags uninstall uninstall-am uninstall-binPROGRAMS \ uninstall-binSCRIPTS lg.cgi: Makefile $(srcdir)/lg.cgi.in rm -f lg.cgi lg.cgi.tmp; \ $(auto_edit) $(srcdir)/lg.cgi.in >lg.cgi.tmp; \ chmod +x lg.cgi.tmp; \ mv lg.cgi.tmp lg.cgi lgform.cgi: Makefile $(srcdir)/lgform.cgi.in rm -f lgform.cgi lgform.cgi.tmp; \ $(auto_edit) $(srcdir)/lgform.cgi.in >lgform.cgi.tmp; \ chmod +x lgform.cgi.tmp; \ mv lgform.cgi.tmp lgform.cgi rancid-cvs: Makefile $(srcdir)/rancid-cvs.in rm -f rancid-cvs rancid-cvs.tmp; \ $(auto_edit) $(srcdir)/rancid-cvs.in >rancid-cvs.tmp; \ chmod +x rancid-cvs.tmp; \ mv rancid-cvs.tmp rancid-cvs rancid-run: Makefile $(srcdir)/rancid-run.in rm -f rancid-run rancid-run.tmp; \ $(auto_edit) $(srcdir)/rancid-run.in >rancid-run.tmp; \ chmod +x rancid-run.tmp; \ mv rancid-run.tmp rancid-run $(bin_PROGRAMS) $(bin_SCRIPTS): ../include/version.h # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: rancid-2.3.8/bin/agmrancid.in100644 015615 000000 00000037651 11535733223 0011523#! @PERLV_PATH@ ## ## $Id: agmrancid.in 2279 2011-01-31 22:41:00Z heas $ ## ## @PACKAGE@ @VERSION@ ## Copyright (c) 1997-2008 by Terrapin Communications, Inc. ## All rights reserved. ## ## This code is derived from software contributed to and maintained by ## Terrapin Communications, Inc. by Henry Kilmer, John Heasley, Andrew Partan, ## Pete Whiting, Austin Schutz, and Andrew Fort. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions ## are met: ## 1. Redistributions of source code must retain the above copyright ## notice, this list of conditions and the following disclaimer. ## 2. Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## 3. All advertising materials mentioning features or use of this software ## must display the following acknowledgement: ## This product includes software developed by Terrapin Communications, ## Inc. and its contributors for RANCID. ## 4. Neither the name of Terrapin Communications, Inc. nor the names of its ## contributors may be used to endorse or promote products derived from ## this software without specific prior written permission. ## 5. It is requested that non-binding fixes and modifications be contributed ## back to Terrapin Communications, Inc. ## ## THIS SOFTWARE IS PROVIDED BY Terrapin Communications, INC. AND CONTRIBUTORS ## ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ## TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COMPANY OR CONTRIBUTORS ## BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ## CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ## SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ## INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ## CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ## ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ## POSSIBILITY OF SUCH DAMAGE. # # Amazingly hacked version of Hank's rancid - this one tries to # deal with Cisco AGMs. # # RANCID - Really Awesome New Cisco confIg Differ # # usage: rancid [-dV] [-l] [-f filename | hostname] # use Getopt::Std; 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; $found_version = 0; $found_env = 0; $found_diag = 0; $timeo = 90; # clogin timeout in seconds # the AGM kicks us off if it does not know our terminal type $ENV{'TERM'} = "dumb"; my(@commandtable, %commands, @commands);# command lists my($aclsort) = ("ipsort"); # ACL sorting mode my($filter_commstr); # SNMP community string filtering 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)) && scalar(%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 routine 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 routine 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 routine 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 routine (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 "show version" sub ShowVersion { print STDERR " In ShowVersion: $_" if ($debug); my($slaveslot); while () { tr/\015//d; if (/^$prompt/) { $found_version=1; last}; next if (/^(\s*|\s*$cmd\s*)$/); return(1) if /Line has invalid autocommand /; return(1) if /(Invalid input detected|Type help or )/; return(-1) if (/command authorization failed/i); return(0) if ($found_version); # Only do this routine once # the pager can not be disabled per-session on the PIX if (/^(-+More-+)/i) { my($len) = length($1); s/^$1\s{$len}//; } /^Cisco Anomaly Guard Image /i && ProcessHistory("COMMENTS","keysort","B1", "! $_") && next; /^MDM agent /i && ProcessHistory("COMMENTS","keysort","B1", "! $_") && next; } return(0); } # This routine parses "show diag" # This will create arrarys for hw info. sub ShowDiag { print STDERR " In ShowDiag: $_" if ($debug); while () { tr/\015//d; if (/^$prompt/) { $found_diag=1; last}; next if (/^(\s*|\s*$cmd\s*)$/); return(1) if /Line has invalid autocommand /; return(1) if /(Invalid input detected|Type help or )/; return(-1) if (/general error/i); return(-1) if (/command authorization failed/i); return(0) if ($found_diag); # Only do this routine once return(-1) if (/failed to get counters/i); /^$/ && next; # the pager can not be disabled per-session on the PIX if (/^(-+More-+)/i) { my($len) = length($1); s/^$1\s{$len}//; } /^Cisco Anomaly Guard Image /i && next; /^... ... \d+ \d+:\d+:\d+ \w \d+$/ && next; /^Copyright /i && next; /^All rights /i && next; /sample loss:/i && next; /forward failures /i && next; ProcessHistory("DIAG","keysort","C1","! $_"); } ProcessHistory("DIAG","","","!\n"); return(0); } # This routine processes a "write term" sub WriteTerm { print STDERR " In WriteTerm: $_" if ($debug); my($lineauto,$comment,$linecnt) = (0,0,0); while () { tr/\015//d; last if (/^$prompt/); return(1) if /Line has invalid autocommand /; return(1) if (/(Invalid input detected|Type help or )/i); return(-1) if (/command authorization failed/i); # the pager can not be disabled per-session on the PIX if (/^(-+More-+)/i) { my($len) = length($1); s/^$1\s{$len}//; } /Non-Volatile memory is in use/ && return(-1); # NvRAM is locked return(0) if ($found_end); # Only do this routine once $linecnt++; $lineauto = 0 if (/^[^ ]/); # skip consecutive comment/blank lines to avoid oscillating extra # comment line on some access servers. grrr. if (/^!/ || /^$/) { next if ($comment); ProcessHistory("","","",$_); $comment++; next; } $comment = 0; # 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 /^ clockrate / && next; # kill clockrate on serial interfaces if (/^(enable )?(password|passwd)( level \w+)? encrypted ((.)\S+)/) { if ($filter_pwds >= 2) { ProcessHistory("USER","keysort","$1", "!$1$2$3 encrypted \n"); } elsif ($filter_pwds >= 1 && $5 ne "\$") { ProcessHistory("USER","keysort","$1", "!$1$2$3 encrypted \n"); } else { ProcessHistory("USER","keysort","$1","$_"); } next; } if ((/^(enable )?(password|passwd)( level \w+)? encrypted [^\$]/ && $filter_pwds >= 1) || (/^(enable )?(password|passwd)( level \w+)? encrypted [^\$]/ && $filter_pwds >= 2)) { ProcessHistory("ENABLE","","","!$1$2$3 \n"); next; } if (/^username (\S+)(\s.*)? encrypted ((.)\S+)/) { if ($filter_pwds >= 2) { ProcessHistory("USER","keysort","$1", "!username $1$2 encrypted \n"); } elsif ($filter_pwds >= 1 && $4 ne "\$") { ProcessHistory("USER","keysort","$1", "!username $1$2 encrypted \n"); } else { ProcessHistory("USER","keysort","$1","$_"); } next; } if (/^(\s*)password / && $filter_pwds >= 1) { ProcessHistory("LINE-PASS","","","!$1password \n"); next; } if (/^(\s*)secret / && $filter_pwds >= 2) { ProcessHistory("LINE-PASS","","","!$1secret \n"); next; } # filter out any RCS/CVS tags to avoid confusing local CVS storage s/\$(Revision|Id):/ $1:/; # order arp lists /^arp\s+(\d+\.\d+\.\d+\.\d+)\s+/ && ProcessHistory("ARP","$aclsort","$1","$_") && next; # order logging statements /^logging host (\d+\.\d+\.\d+\.\d+)/ && ProcessHistory("LOGGING","ipsort","$1","$_") && next; # order/prune snmp-server host statements # we only prune lines of the form # snmp-server host a.b.c.d if (/^snmp-server trap-dest (\d+\.\d+\.\d+\.\d+) /) { if ($filter_commstr) { my($ip) = $1; my($line) = "snmp-server host $ip"; my(@tokens) = split(' ', $'); my($token); while ($token = shift(@tokens)) { if ($token eq 'version') { $line .= " " . join(' ', ($token, shift(@tokens))); if ($token eq '3') { $line .= " " . join(' ', ($token, shift(@tokens))); } } elsif ($token eq 'vrf') { $line .= " " . join(' ', ($token, shift(@tokens))); } elsif ($token =~ /^(informs?|traps?|(no)?auth)$/) { $line .= " " . $token; } else { $line = "!$line " . join(' ', ("", join(' ',@tokens))); last; } } ProcessHistory("SNMPSERVERHOST","ipsort","$ip","$line\n"); } else { ProcessHistory("SNMPSERVERHOST","ipsort","$1","$_"); } next; } if (/^(snmp community) (\S+)/) { if ($filter_commstr) { ProcessHistory("SNMPSERVERCOMM","keysort","$_","!$1 $'") && next; } else { ProcessHistory("SNMPSERVERCOMM","keysort","$_","$_") && next; } } # prune tacacs/radius server keys if (/^((tacacs-server|radius-server)\s(\w*[-\s(\s\S+])*\s?key) \d \w+/ && $filter_pwds >= 1) { ProcessHistory("","","","!$1 $'"); next; } # delete ntp auth password - this md5 is a reversable too if (/^(ntp authentication-key \d+ md5) / && $filter_pwds >= 1) { ProcessHistory("","","","!$1 \n"); next; } # order ntp peers/servers if (/^ntp (server|peer) (\d+)\.(\d+)\.(\d+)\.(\d+)/) { $sortkey = sprintf("$1 %03d%03d%03d%03d",$2,$3,$4,$5); ProcessHistory("NTP","keysort",$sortkey,"$_"); next; } # catch anything that wasnt matched above. ProcessHistory("","","","$_"); # end of config. the ": " game is for the PIX if (/^(: +)?end$/) { $found_end = 1; return(1); } } # The AGM lacks a definitive "end of config" marker. If we have seen at # least 5 lines of write term o/p, we can be reasonably sure that we got # the config. if ($linecnt > 5) { $found_end = 1; return(1); } return(0); } # dummy function sub DoNothing {print STDOUT;} # Main @commandtable = ( {'show version' => 'ShowVersion'}, {'show diagnostic-info' => 'ShowDiag'}, {'show running-config' => 'WriteTerm'}, ); # 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("|", map quotemeta($_), @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 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 hlogin -t $timeo -c\"$cisco_cmds\" $host\n" if ($debug); print STDOUT "executing hlogin -t $timeo -c\"$cisco_cmds\" $host\n" if ($log); if (defined($ENV{NOPIPE}) && $ENV{NOPIPE} =~ /^YES/i) { system "hlogin -t $timeo -c \"$cisco_cmds\" $host $host.raw 2>&1" || die "hlogin failed for $host: $!\n"; open(INPUT, "< $host.raw") || die "hlogin failed for $host: $!\n"; } else { open(INPUT,"hlogin -t $timeo -c \"$cisco_cmds\" $host ) { tr/\015//d; if (/[>#]\s?exit$/) { $clean_run=1; last; } if (/^Error:/) { print STDOUT ("$host clogin error: $_"); print STDERR ("$host clogin error: $_") if ($debug); $clean_run=0; last; } while (/#\s*($cmds_regexp)\s*$/) { $cmd = $1; 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; } $rval = &{$commands{$cmd}}; delete($commands{$cmd}); if ($rval == -1) { $clean_run = 0; last TOP; } if (/[>#]\s?exit$/) { $clean_run=1; last; } } } print STDOUT "Done $logincmd: $_\n" if ($log); # Flush History ProcessHistory("","","",""); # Cleanup close(INPUT); close(OUTPUT); if (defined($ENV{NOPIPE}) && $ENV{NOPIPE} =~ /^YES/i) { 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); } rancid-2.3.8/bin/alogin.in100644 015615 000000 00000037557 11712067106 0011051#! @EXPECT_PATH@ -- ## ## $Id: alogin.in 2376 2012-01-31 22:42:14Z heas $ ## ## @PACKAGE@ @VERSION@ ## Copyright (c) @COPYYEARS@ by Terrapin Communications, Inc. ## All rights reserved. ## ## This code is derived from software contributed to and maintained by ## Terrapin Communications, Inc. by Henry Kilmer, John Heasley, Andrew Partan, ## Pete Whiting, Austin Schutz, and Andrew Fort. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions ## are met: ## 1. Redistributions of source code must retain the above copyright ## notice, this list of conditions and the following disclaimer. ## 2. Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## 3. All advertising materials mentioning features or use of this software ## must display the following acknowledgement: ## This product includes software developed by Terrapin Communications, ## Inc. and its contributors for RANCID. ## 4. Neither the name of Terrapin Communications, Inc. nor the names of its ## contributors may be used to endorse or promote products derived from ## this software without specific prior written permission. ## 5. It is requested that non-binding fixes and modifications be contributed ## back to Terrapin Communications, Inc. ## ## THIS SOFTWARE IS PROVIDED BY Terrapin Communications, INC. AND CONTRIBUTORS ## ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ## TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COMPANY OR CONTRIBUTORS ## BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ## CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ## SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ## INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ## CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ## ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ## POSSIBILITY OF SUCH DAMAGE. # # The login expect scripts were based on Erik Sherk's gwtn, by permission. # # alogin - Alteon WebOS switch login # # afort@choqolat.org is responsible for this particular mess # (andrew fort) # # Usage line set usage "Usage: $argv0 \[-dSV\] \[-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 avenable 1 # The default is that you login non-enabled (tacacs can have you login already # enabled) set avautoenable 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 # Save config, if prompted set do_saveconfig 0 # default timeout set timeoutdflt 45 # 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) } elseif {[ info exists env(LOGNAME) ]} { set default_user $env(LOGNAME) } 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 "\nError: could not exec id: $reason\n" exit 1 } regexp {\(([^)]*)} "$reason" junk default_user } if {[ info exists env(CLOGINRC) ]} { set password_file $env(CLOGINRC) } # Process the command line for {set i 0} {$i < $argc} {incr i} { set arg [lindex $argv $i] switch -glob -- $arg { # Expect debug mode -d* { exp_internal 1 # Username } -u* { if {! [ regexp .\[uU\](.+) $arg ignore user]} { incr i set username [ lindex $argv $i ] } # VTY Password } -p* { # ignore -p # ssh passphrase } -r* { # ignore -r # VTY Password } -v* { if {! [ regexp .\[vV\](.+) $arg ignore passwd]} { incr i set passwd [ lindex $argv $i ] } set do_passwd 0 # Version string } -V* { send_user "@PACKAGE@ @VERSION@\n" exit 0 # Enable Username } -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 "\nError: invalid format for -E in $arg\n" exit 1 } # Enable Password } -e* { # ignore -e # Command to run. } -c* { if {! [ regexp .\[cC\](.+) $arg ignore command]} { incr i set command [ lindex $argv $i ] } set do_command 1 # Expect script to run. } -s* { if {! [ regexp .\[sS\](.+) $arg ignore sfile]} { incr i set sfile [ lindex $argv $i ] } if { ! [ file readable $sfile ] } { send_user "\nError: Can't read $sfile\n" exit 1 } set do_script 1 # save config on exit } -S* { set do_saveconfig 1 # 'ssh -c' cypher type } -y* { if {! [ regexp .\[eE\](.+) $arg ignore cypher]} { incr i set cypher [ lindex $argv $i ] } # alternate cloginrc file } -f* { if {! [ regexp .\[fF\](.+) $arg ignore password_file]} { incr i set password_file [ lindex $argv $i ] } # Timeout } -t* { if {! [ regexp .\[tT\](.+) $arg ignore timeout]} { incr i set timeoutdflt [ lindex $argv $i ] } # Command file } -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 "\nError: Unknown argument! $arg\n" send_user $usage exit 1 } default { break } } } # Process routers...no routers listed is an error. if { $i == $argc } { send_user "\nError: $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 "\nError: password file ($password_file) does not exist\n" exit 1 } file stat $password_file fileinfo if { [expr ($fileinfo(mode) & 007)] != 0000 } { send_user "\nError: $password_file must not be world readable/writable\n" exit 1 } if [ catch {source $password_file} reason ] { send_user "\nError: $reason\n" exit 1 } } # Log into the router. # returns: 0 on success, 1 on failure proc login { router user userpswd passwd prompt cmethod cyphertype } { global spawn_id in_proc do_command do_script global u_prompt p_prompt sshcmd 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] { incr progs -1 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" return 1 } } elseif ![string compare $prog "ssh"] { regexp {ssh(:([^[:space:]]+))*} $prog methcmd suffix port set cmd $sshcmd if {"$port" != ""} { set cmd "$cmd -p $port" } set retval [ catch {eval spawn [split "$cmd -c $cyphertype -x -l $user $router" { }]} reason ] if { $retval } { send_user "\nError: $cmd failed: $reason\n" return 1 } } elseif ![string compare $prog "rsh"] { send_error "\nError: unsupported method: rsh\n" if { $progs == 0 } { return 1 } continue; } else { send_user "\nError: unknown connection method: $prog\n" return 1 } sleep 0.3 # This helps cleanup each expect clause. expect_after { timeout { send_user "\nError: TIMEOUT reached\n" catch {close}; catch {wait}; if { $in_proc} { return 1 } else { continue } } eof { send_user "\nError: EOF received\n" catch {close}; catch {wait}; if { $in_proc} { return 1 } else { continue } } } expect { "Connection refused" { catch {close}; catch {wait}; sleep 0.3 expect eof send_user "\nError: Connection Refused\n"; wait; return 1 } eof { send_user "\nError: Couldn't login\n"; wait; return 1 } "Unknown host\r\n" { expect eof send_user "\nError: Unknown host\n"; wait; return 1 } "Host is unreachable" { expect eof send_user "\nError: Host Unreachable!\n"; wait; return 1 } "No address associated with name" { expect eof send_user "\nError: Unknown host\n"; wait; return 1 } -re "(Host key not found |The authenticity of host .* be established).* \\(yes/no\\)\\?" { send "yes\r" send_user "\nHost $router added to the list of known hosts.\n" exp_continue } -re "HOST IDENTIFICATION HAS CHANGED.* \\(yes/no\\)\\?" { send "no\r" send_user "\nError: The host key for $router has changed. Update the SSH known_hosts file accordingly.\n" return 1 } -re "HOST IDENTIFICATION HAS CHANGED\[^\n\r]+" { send_user "\nError: The host key for $router has changed. Update the SSH known_hosts file accordingly.\n" return 1 } -re "Offending key for .* \\(yes/no\\)\\?" { send "no\r" send_user "\nError: host key mismatch for $router. Update the SSH known_hosts file accordingly.\n" return 1 } -re "NOTICE:\[^\n\r]* - display now \[^\n\r]*:" { send "no\r" exp_continue } -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 "\nError: Check your password for $router\n"; catch {close}; catch {wait}; return 1 } -re "$prompt" { break; } denied { send_user "\nError: Check your passwd for $router\n" catch {close}; catch {wait}; 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 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 } } } 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 { catch {close}; catch {wait}; 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 set exitval 0 foreach router [lrange $argv $i end] { set router [string tolower $router] send_user "$router\n" # device timeout set timeout [find timeout $router] if { [llength $timeout] == 0 } { set timeout $timeoutdflt } # 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 "\nError - no password for $router in $password_file.\n" continue } set passwd [join [lindex $pswd 0] ""] } # Figure out username if {[info exists username]} { # command line username set ruser $username } else { set ruser [join [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 [join [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):" } else { set u_prompt [join [lindex $u_prompt 0] ""] } set p_prompt [find passprompt $router] if { "$p_prompt" == "" } { set p_prompt "\[Pp]assword:" } else { set p_prompt [join [lindex $p_prompt 0] ""] } # 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}} } # Figure out the SSH executable name set sshcmd [join [lindex [find sshcmd $router] 0] ""] if { "$sshcmd" == "" } { set sshcmd {ssh} } # Login to the router if {[login $router $ruser $userpswd $passwd $prompt $cmethod $cyphertype]} { incr exitval continue } if { $do_command } { if {[run_commands $prompt $command]} { incr exitval continue } } elseif { $do_script } { send "lines 0\r" expect -re $prompt {} source $sfile catch {close}; } else { label $router log_user 1 interact } # End of for each router catch {wait}; sleep 0.3 } exit $exitval rancid-2.3.8/bin/arancid.in100644 015615 000000 00000024411 11611072653 0011163#! @PERLV_PATH@ ## ## $Id: arancid.in 2315 2011-06-24 19:59:32Z heas $ ## ## @PACKAGE@ @VERSION@ ## Copyright (c) 1997-2008 by Terrapin Communications, Inc. ## All rights reserved. ## ## This code is derived from software contributed to and maintained by ## Terrapin Communications, Inc. by Henry Kilmer, John Heasley, Andrew Partan, ## Pete Whiting, Austin Schutz, and Andrew Fort. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions ## are met: ## 1. Redistributions of source code must retain the above copyright ## notice, this list of conditions and the following disclaimer. ## 2. Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## 3. All advertising materials mentioning features or use of this software ## must display the following acknowledgement: ## This product includes software developed by Terrapin Communications, ## Inc. and its contributors for RANCID. ## 4. Neither the name of Terrapin Communications, Inc. nor the names of its ## contributors may be used to endorse or promote products derived from ## this software without specific prior written permission. ## 5. It is requested that non-binding fixes and modifications be contributed ## back to Terrapin Communications, Inc. ## ## THIS SOFTWARE IS PROVIDED BY Terrapin Communications, INC. AND CONTRIBUTORS ## ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ## TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COMPANY OR CONTRIBUTORS ## BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ## CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ## SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ## INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ## CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ## ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ## POSSIBILITY OF SUCH DAMAGE. # # RANCID - Really Awesome New Cisco confIg Differ # # arancid - Alteon WebOS plugin for rancid # # usage: arancid [-dV] [-l] [-f filename | hostname] # use Getopt::Std; 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; $prompt = "#"; $timeo = 90; # alogin timeout in seconds my(@commandtable, %commands, @commands);# command lists my($aclsort) = ("ipsort"); # ACL sorting mode my($filter_commstr); # SNMP community string filtering 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)) && scalar(%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 routine 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 routine 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 routine 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 routine (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 () { 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 = ; # now just copy it verbatim to the history file while () { tr/\015//d; last if(/^>>.*$prompt/); chop; if (/(rcomm|wcomm|t1com|t2com)(\s+)(.*)/ && $filter_commstr) { ProcessHistory("","","","\/\*\t$1$2\"\"\n") && next; } /^(\s+(.{1,3}pw|pswd) )\S+/ && ProcessHistory("","","","\/\*$1\n") && next; next if (/^\/\* Configuration dump taken/i); next if (/^\/\* Version.*Base MAC.*/i); next if (/^ *esecret /); if (/^\/?script end/) { $found_end = 1; ProcessHistory("","","","$_\n"); return(1); } ProcessHistory("","","","$_\n"); } return(0); } # dummy function sub DoNothing {print STDOUT;} # Main @commandtable = ( {'/info/sys/dump' => 'ShowVersion'}, {'/cfg/dump' => 'WriteTerm'} ); # 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("|", map quotemeta($_), @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 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}) && $ENV{NOPIPE} =~ /^YES/i) { system "alogin -t $timeo -c \"$cisco_cmds\" $host $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 ) { tr/\015//d; if (/^>>.*$prompt exit/) { $clean_run = 1; last; } while (/>>.*$prompt\s*($cmds_regexp)\s*$/) { $cmd = $1; 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; } $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}) && $ENV{NOPIPE} =~ /^YES/i) { 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); } rancid-2.3.8/bin/arrancid.in100644 015615 000000 00000055026 11535733223 0011355#! @PERLV_PATH@ ## ## $Id$ ## ## @PACKAGE@ @VERSION@ ## Copyright (c) 1997-2009 by Terrapin Communications, Inc. ## All rights reserved. ## ## This code is derived from software contributed to and maintained by ## Terrapin Communications, Inc. by Henry Kilmer, John Heasley, Andrew Partan, ## Pete Whiting, Austin Schutz, and Andrew Fort. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions ## are met: ## 1. Redistributions of source code must retain the above copyright ## notice, this list of conditions and the following disclaimer. ## 2. Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## 3. All advertising materials mentioning features or use of this software ## must display the following acknowledgement: ## This product includes software developed by Terrapin Communications, ## Inc. and its contributors for RANCID. ## 4. Neither the name of Terrapin Communications, Inc. nor the names of its ## contributors may be used to endorse or promote products derived from ## this software without specific prior written permission. ## 5. It is requested that non-binding fixes and modifications be contributed ## back to Terrapin Communications, Inc. ## ## THIS SOFTWARE IS PROVIDED BY Terrapin Communications, INC. AND CONTRIBUTORS ## ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ## TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COMPANY OR CONTRIBUTORS ## BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ## CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ## SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ## INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ## CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ## ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ## POSSIBILITY OF SUCH DAMAGE. # # RANCID - Really Awesome New ConfIg Differ # # Rancid for Arista Networks' switches; cisco mode works but # Arista mode is better. # Initial version by Bill Fenner # # usage: arrancid [-dV] [-l] [-f filename | hostname] # use Getopt::Std; getopts('dflV'); if ($opt_V) { print "@PACKAGE@ @VERSION@\n"; exit(0); } $log = $opt_l; $debug = $opt_d; $file = $opt_f; $host = $ARGV[0]; $ios = "IOS"; $clean_run = 0; $found_end = 0; $found_version = 0; $found_env = 0; $found_diag = 0; $timeo = 90; # clogin timeout in seconds my(@commandtable, %commands, @commands);# command lists my($aclsort) = ("ipsort"); # ACL sorting mode my($filter_commstr); # SNMP community string filtering 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)) && scalar(%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 routine 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 routine 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 routine 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 routine (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 "show version" sub ShowVersion { print STDERR " In ShowVersion: $_" if ($debug); while () { tr/\015//d; if (/^$prompt/) { $found_version = 1; last}; next if (/^(\s*|\s*$cmd\s*)$/); return(1) if /^% Invalid input/; return(0) if ($found_version); # Only do this routine once ( $key, $val ) = split( /:\s+/, $_, 2 ); if ( ! $val ) { # Must be the model name if there's no colon ProcessHistory("COMMENTS", "", "", "!Model: $_" ); next; } if ( $key ne 'Uptime' and $key ne 'Free memory' ) { ProcessHistory("COMMENTS", "", "", "!$key: $val" ); } } return(0); } # This routine parses "show env all" sub ShowEnv { print STDERR " In ShowEnv: $_" if ($debug); $fans = 0; $supplies = 0; while () { tr/\015//d; if (/^$prompt/) { $found_env = 1; last}; next if (/^(\s*|\s*$cmd\s*)$/); return(1) if /^% Invalid input/; return(0) if ($found_env); # Only do this routine once if (!defined($E0)) { $E0 = 1; ProcessHistory("COMMENTS","keysort","E0","!\n"); } /^(System \S+ status is|Action on overheat|Airflow)/ && ProcessHistory("COMMENTS","keysort","E0","!$_") && next; if ( /^Fan\s+Status\s+/ ) { $fans = 1; next; } $fans && /^\s*(\d+)\s+(\S+)/ && ProcessHistory("COMMENTS","keysort","E1","!Fan $1: $2\n") && next; if ( /^Supply\s+Model\s+Capacity/ ) { $fans = 0; $supplies = 1; next; } $supplies && /^\s*(\d+)\s+(\S+)\s+(\S+)\s+\S+\s+\S+\s+\S+\s+(\S+)/ && ProcessHistory("COMMENTS","keysort","E2","!Power Supply $1: $2 $3 $4\n" ) && next; } ProcessHistory("COMMENTS","","","!\n"); return(0); } # This routine parses "show boot-config" sub ShowBoot { print STDERR " In ShowBoot: $_" if ($debug); while () { tr/\015//d; last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); return(1) if /^% Invalid input/; if (!defined($B0)) { $B0 = 1; ProcessHistory("COMMENTS","","","!\n"); } ProcessHistory("COMMENTS","","","!$_"); } ProcessHistory("COMMENTS","","","!\n"); return(0); } # This routine parses "show boot-extensions" sub ShowBootExt { print STDERR " In ShowBootExt: $_" if ($debug); while () { tr/\015//d; last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); return(1) if /^% Invalid input/; return(0) if /^% Error displaying /; if (!defined($C0)) { $C0 = 1; ProcessHistory("COMMENTS","","","!\n"); } ProcessHistory("COMMENTS","","","!BootExtension: $_"); } ProcessHistory("COMMENTS","","","!\n"); return(0); } # This routine parses "show extensions" sub ShowExt { print STDERR " In ShowExt: $_" if ($debug); while () { tr/\015//d; last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); return(1) if /^% Invalid input/; return(0) if /^No extensions are available/; if (!defined($D0)) { $D0 = 1; ProcessHistory("COMMENTS","","","!Extensions:\n"); } ProcessHistory("COMMENTS","","","!$_"); } ProcessHistory("COMMENTS","","","!\n"); return(0); } # This routine parses "dir flash:" sub ShowFlash { print STDERR " In ShowFlash: $_" if ($debug); while () { tr/\015//d; last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); return(1) if /^% Invalid input/; # persist changes constantly if you're running ntp, so # skip its updates. /\spersist$/ && next; ProcessHistory("FLASH","","","!Flash: $_"); } ProcessHistory("","","","!\n"); return; } # This routine parses "show inventory". sub ShowInventory { print STDERR " In ShowInventory: $_" if ($debug); while () { tr/\015//d; return if (/^\s*\^$/); last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); return(1) if /^% Invalid input/; ProcessHistory("INVENTORY","","","!$_"); } ProcessHistory("INVENTORY","","","!\n"); return(0); } # This routine processes a "write term" sub WriteTerm { print STDERR " In WriteTerm: $_" if ($debug); while () { tr/\015//d; last if (/^$prompt/); return(1) if /^% Invalid input/; return(0) if ($found_end); # Only do this routine once # Dog gone Cool matches to process the rest of the config # Lots of Cisco-specific stuff here, but leaving it alone for now. /^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 /^ clockrate / && next; # kill clockrate on serial interfaces if (/^(enable )?(password|passwd)( level \d+)? / && $filter_pwds >= 1) { ProcessHistory("ENABLE","","","!$1$2$3 \n"); next; } if (/^(enable secret) / && $filter_pwds >= 2) { ProcessHistory("ENABLE","","","!$1 \n"); next; } if (/^username (\S+)(\s.*)? secret /) { if ($filter_pwds >= 2) { ProcessHistory("USER","keysort","$1", "!username $1$2 secret \n"); } else { ProcessHistory("USER","keysort","$1","$_"); } next; } if (/^username (\S+)(\s.*)? password ((\d) \S+|\S+)/) { if ($filter_pwds >= 2) { ProcessHistory("USER","keysort","$1", "!username $1$2 password \n"); } elsif ($filter_pwds >= 1 && $4 ne "5"){ ProcessHistory("USER","keysort","$1", "!username $1$2 password \n"); } else { ProcessHistory("USER","keysort","$1","$_"); } next; } # cisco AP w/ IOS if (/^(wlccp \S+ username (\S+)(\s.*)? password) (\d \S+|\S+)/) { if ($filter_pwds >= 1) { ProcessHistory("USER","keysort","$2","!$1 \n"); } else { ProcessHistory("USER","keysort","$2","$_"); } next; } if (/^( set session-key (in|out)bound ah \d+ )/ && $filter_pwds >= 1) { ProcessHistory("","","","!$1\n"); next; } if (/^( set session-key (in|out)bound esp \d+ (authenticator|cypher) )/ && $filter_pwds >= 1) { ProcessHistory("","","","!$1\n"); next; } if (/^(\s*)password / && $filter_pwds >= 1) { ProcessHistory("LINE-PASS","","","!$1password \n"); next; } if (/^(\s*)secret / && $filter_pwds >= 2) { ProcessHistory("LINE-PASS","","","!$1secret \n"); next; } if (/^\s*neighbor (\S*) password / && $filter_pwds >= 1) { ProcessHistory("","","","! neighbor $1 password \n"); next; } if (/^(ppp .* password) 7 .*/ && $filter_pwds >= 1) { ProcessHistory("","","","!$1 \n"); next; } if (/^(ip ftp password) / && $filter_pwds >= 1) { ProcessHistory("","","","!$1 \n"); next; } if (/^( ip ospf authentication-key) / && $filter_pwds >= 1) { ProcessHistory("","","","!$1 \n"); next; } # isis passwords appear to be completely plain-text if (/^\s+isis password (\S+)( .*)?/ && $filter_pwds >= 1) { ProcessHistory("","","","!isis password $2\n"); next; } if (/^\s+(domain-password|area-password) (\S+)( .*)?/ && $filter_pwds >= 1) { ProcessHistory("","","","!$1 $3\n"); next; } # this is reversable, despite 'md5' in the cmd if (/^( ip ospf message-digest-key \d+ md5) / && $filter_pwds >= 1) { ProcessHistory("","","","!$1 \n"); next; } # this is also reversable, despite 'md5 encrypted' in the cmd if (/^( message-digest-key \d+ md5 (7|encrypted)) / && $filter_pwds >= 1) { ProcessHistory("","","","!$1 \n"); next; } if (/^((crypto )?isakmp key) \S+ / && $filter_pwds >= 1) { ProcessHistory("","","","!$1 $'"); next; } # filter HSRP passwords if (/^(\s+standby \d+ authentication) / && $filter_pwds >= 1) { ProcessHistory("","","","!$1 \n"); next; } # this appears in "measurement/sla" images if (/^(\s+key-string \d?)/ && $filter_pwds >= 1) { ProcessHistory("","","","!$1 \n"); next; } if (/^( l2tp tunnel \S+ password)/ && $filter_pwds >= 1) { ProcessHistory("","","","!$1 \n"); next; } # i am told these are plain-text on the PIX if (/^(vpdn username (\S+) password)/) { if ($filter_pwds >= 1) { ProcessHistory("USER","keysort","$2","!$1 \n"); } else { ProcessHistory("USER","keysort","$2","$_"); } next; } # ASA/PIX keys in more system:running-config if (/^( pre-shared-key |failover key ).*/ && $filter_pwds >= 1) { ProcessHistory("","","","!$1 $'"); next; } # if (/^( cable shared-secret )/ && $filter_pwds >= 1) { ProcessHistory("","","","!$1 \n"); next; } /fair-queue individual-limit/ && next; # sort ip explicit-paths. if (/^ip explicit-path name (\S+)/) { my($key) = $1; my($expath) = $_; while () { tr/\015//d; last if (/^$prompt/); last if (/^$prompt/ || ! /^(ip explicit-path name |[ !])/); if (/^ip explicit-path name (\S+)/) { ProcessHistory("EXPATH","keysort","$key","$expath"); $key = $1; $expath = $_; } else { $expath .= $_; } } ProcessHistory("EXPATH","keysort","$key","$expath"); } # sort route-maps if (/^route-map (\S+)/) { my($key) = $1; my($routemap) = $_; while () { tr/\015//d; last if (/^$prompt/ || ! /^(route-map |[ !])/); if (/^route-map (\S+)/) { ProcessHistory("ROUTEMAP","keysort","$key","$routemap"); $key = $1; $routemap = $_; } else { $routemap .= $_; } } ProcessHistory("ROUTEMAP","keysort","$key","$routemap"); } # filter out any RCS/CVS tags to avoid confusing local CVS storage s/\$(Revision|Id):/ $1:/; # order access-lists /^access-list\s+(\d\d?)\s+(\S+)\s+(\S+)/ && ProcessHistory("ACL $1 $2","$aclsort","$3","$_") && next; # order extended access-lists /^access-list\s+(\d\d\d)\s+(\S+)\s+ip\s+host\s+(\S+)/ && ProcessHistory("EACL $1 $2","$aclsort","$3","$_") && next; /^access-list\s+(\d\d\d)\s+(\S+)\s+ip\s+(\d\S+)/ && ProcessHistory("EACL $1 $2","$aclsort","$3","$_") && next; /^access-list\s+(\d\d\d)\s+(\S+)\s+ip\s+any/ && ProcessHistory("EACL $1 $2","$aclsort","0.0.0.0","$_") && next; # order arp lists /^arp\s+(\d+\.\d+\.\d+\.\d+)\s+/ && ProcessHistory("ARP","$aclsort","$1","$_") && next; /^ip prefix-list\s+(\S+)\s+seq\s+(\d+)\s+(permit|deny)\s+(\d\S+)(\/.*)$/ && ProcessHistory("PACL $1 $3","$aclsort","$4","ip prefix-list $1 $3 $4$5\n") && next; # order logging statements /^logging (\d+\.\d+\.\d+\.\d+)/ && ProcessHistory("LOGGING","ipsort","$1","$_") && next; # order/prune snmp-server host statements # we only prune lines of the form # snmp-server host a.b.c.d if (/^snmp-server host (\d+\.\d+\.\d+\.\d+) /) { if ($filter_commstr) { my($ip) = $1; my($line) = "snmp-server host $ip"; my(@tokens) = split(' ', $'); my($token); while ($token = shift(@tokens)) { if ($token eq 'version') { $line .= " " . join(' ', ($token, shift(@tokens))); if ($token eq '3') { $line .= " " . join(' ', ($token, shift(@tokens))); } } elsif ($token eq 'vrf') { $line .= " " . join(' ', ($token, shift(@tokens))); } elsif ($token =~ /^(informs?|traps?|(no)?auth)$/) { $line .= " " . $token; } else { $line = "!$line " . join(' ', ("", join(' ',@tokens))); last; } } ProcessHistory("SNMPSERVERHOST","ipsort","$ip","$line\n"); } else { ProcessHistory("SNMPSERVERHOST","ipsort","$1","$_"); } next; } if (/^(snmp-server community) (\S+)/) { if ($filter_commstr) { ProcessHistory("SNMPSERVERCOMM","keysort","$_", "!$1 $'") && next; } else { ProcessHistory("SNMPSERVERCOMM","keysort","$_","$_") && next; } } # prune tacacs/radius server keys if (/^((tacacs|radius)-server\s(\w*[-\s(\s\S+])*\s?key) (\d )?\w+/ && $filter_pwds >= 1) { ProcessHistory("","","","!$1 $'"); next; } # order clns host statements /^clns host \S+ (\S+)/ && ProcessHistory("CLNS","keysort","$1","$_") && next; # order alias statements /^alias / && ProcessHistory("ALIAS","keysort","$_","$_") && next; # delete ntp auth password - this md5 is a reversable too if (/^(ntp authentication-key \d+ md5) / && $filter_pwds >= 1) { ProcessHistory("","","","!$1 \n"); next; } # order ntp peers/servers if (/^ntp (server|peer) (\d+)\.(\d+)\.(\d+)\.(\d+)/) { $sortkey = sprintf("$1 %03d%03d%03d%03d",$2,$3,$4,$5); ProcessHistory("NTP","keysort",$sortkey,"$_"); next; } # order ip host statements /^ip host (\S+) / && ProcessHistory("IPHOST","keysort","$1","$_") && next; # order ip nat source static statements /^ip nat (\S+) source static (\S+)/ && ProcessHistory("IP NAT $1","ipsort","$2","$_") && next; # order atm map-list statements /^\s+ip\s+(\d+\.\d+\.\d+\.\d+)\s+atm-vc/ && ProcessHistory("ATM map-list","ipsort","$1","$_") && next; # order ip rcmd lines /^ip rcmd/ && ProcessHistory("RCMD","keysort","$_","$_") && next; # system controller /^syscon address (\S*) (\S*)/ && ProcessHistory("","","","!syscon address $1 \n") && next; if (/^syscon password (\S*)/ && $filter_pwds >= 1) { ProcessHistory("","","","!syscon password \n"); next; } /^ *Cryptochecksum:/ && next; # catch anything that wasnt matched above. ProcessHistory("","","","$_"); # end of config. if (/^end$/) { $found_end = 1; return(0); } } return(0); } # dummy function sub DoNothing {print STDOUT;} # Main @commandtable = ( {'show version' => 'ShowVersion'}, {'show boot-config' => 'ShowBoot'}, {'show env all' => 'ShowEnv'}, {'dir flash:' => 'ShowFlash'}, {'show inventory' => 'ShowInventory'}, {'show boot-extensions' => 'ShowBootExt'}, {'show extensions' => 'ShowExt'}, {'show running-config' => 'WriteTerm'}, ); # 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); $arista_cmds = join(";",@commands); $cmds_regexp = join("|", map quotemeta($_), @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 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 clogin -t $timeo -c\"$arista_cmds\" $host\n" if ($debug); print STDOUT "executing clogin -t $timeo -c\"$arista_cmds\" $host\n" if ($log); if (defined($ENV{NOPIPE}) && $ENV{NOPIPE} =~ /^YES/i) { system "clogin -t $timeo -c \"$arista_cmds\" $host $host.raw 2>&1" || die "clogin failed for $host: $!\n"; open(INPUT, "< $host.raw") || die "clogin failed for $host: $!\n"; } else { open(INPUT,"clogin -t $timeo -c \"$arista_cmds\" $host ) { tr/\015//d; if (/[>#]\s?exit$/) { $clean_run = 1; last; } if (/^Error:/) { print STDOUT ("$host clogin error: $_"); print STDERR ("$host clogin error: $_") if ($debug); $clean_run = 0; last; } while (/#\s*($cmds_regexp)\s*$/) { $cmd = $1; 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; } $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}) && $ENV{NOPIPE} =~ /^YES/i) { 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); } rancid-2.3.8/bin/avologin.in100644 015615 000000 00000052346 11712067106 0011407#! @EXPECT_PATH@ -- ## ## $Id: avologin.in 2376 2012-01-31 22:42:14Z heas $ ## ## @PACKAGE@ @VERSION@ ## Copyright (c) @COPYYEARS@ by Terrapin Communications, Inc. ## All rights reserved. ## ## This code is derived from software contributed to and maintained by ## Terrapin Communications, Inc. by Henry Kilmer, John Heasley, Andrew Partan, ## Pete Whiting, Austin Schutz, and Andrew Fort. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions ## are met: ## 1. Redistributions of source code must retain the above copyright ## notice, this list of conditions and the following disclaimer. ## 2. Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## 3. All advertising materials mentioning features or use of this software ## must display the following acknowledgement: ## This product includes software developed by Terrapin Communications, ## Inc. and its contributors for RANCID. ## 4. Neither the name of Terrapin Communications, Inc. nor the names of its ## contributors may be used to endorse or promote products derived from ## this software without specific prior written permission. ## 5. It is requested that non-binding fixes and modifications be contributed ## back to Terrapin Communications, Inc. ## ## THIS SOFTWARE IS PROVIDED BY Terrapin Communications, INC. AND CONTRIBUTORS ## ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ## TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COMPANY OR CONTRIBUTORS ## BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ## CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ## SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ## INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ## CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ## ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ## POSSIBILITY OF SUCH DAMAGE. # # The login expect scripts were based on Erik Sherk's gwtn, by permission. # # avologin - Avocent login # # Most options are intuitive for logging into a Avocent/Cyclades term server. # The default is to enable (thus -noenable). Some folks have # setup tacacs to have a user login at priv-lvl = 15 (enabled) # so the -autoenable flag was added for this case (don't go through # the process of enabling and the prompt will be the "#" prompt. # The default username password is the same as the vty password. # # Usage line set usage "Usage: $argv0 \[-dSV\] \[-autoenable\] \[-noenable\] \[-c command\] \ \[-Evar=x\] \[-e enable-password\] \[-f cloginrc-file\] \[-p user-password\] \ \[-s script-file\] \[-t timeout\] \[-u username\] \ \[-v vty-password\] \[-w enable-username\] \[-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 avenable 1 # The default is that you login non-enabled (tacacs can have you login already # enabled) set avautoenable 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 set do_enapasswd 1 # Save config, if prompted set do_saveconfig 0 # Sometimes routers take awhile to answer (the default is 10 sec) set timeoutdflt 45 # 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) } elseif {[info exists env(LOGNAME)]} { set default_user $env(LOGNAME) } 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 "\nError: could not exec id: $reason\n" exit 1 } regexp {\(([^)]*)} "$reason" junk default_user } if {[info exists env(CLOGINRC)]} { set password_file $env(CLOGINRC) } # Process the command line for {set i 0} {$i < $argc} {incr i} { set arg [lindex $argv $i] switch -glob -- $arg { # Expect debug mode -d* { exp_internal 1 # Username } -u* { if {! [regexp .\[uU\](.+) $arg ignore user]} { incr i set username [lindex $argv $i] } # VTY Password } -p* { if {! [regexp .\[pP\](.+) $arg ignore userpasswd]} { incr i set userpasswd [lindex $argv $i] } set do_passwd 0 # ssh passphrase } -r* { # ignore -r # VTY Password } -v* { if {! [regexp .\[vV\](.+) $arg ignore passwd]} { incr i set passwd [lindex $argv $i] } set do_passwd 0 # Version string } -V* { send_user "@PACKAGE@ @VERSION@\n" exit 0 # Enable Username } -w* { if {! [regexp .\[wW\](.+) $arg ignore enauser]} { incr i set enausername [lindex $argv $i] } # Environment variable to pass to -s scripts } -E* { if {[regexp .\[E\](.+)=(.+) $arg ignore varname varvalue]} { set E$varname $varvalue } else { send_user "\nError: invalid format for -E in $arg\n" exit 1 } # Enable Password } -e* { if {! [regexp .\[e\](.+) $arg ignore enapasswd]} { incr i set enapasswd [lindex $argv $i] } set do_enapasswd 0 # Command to run. } -c* { if {! [regexp .\[cC\](.+) $arg ignore command]} { incr i set command [lindex $argv $i] } set do_command 1 # Expect script to run. } -s* { if {! [regexp .\[sS\](.+) $arg ignore sfile]} { incr i set sfile [lindex $argv $i] } if { ! [file readable $sfile] } { send_user "\nError: Can't read $sfile\n" exit 1 } set do_script 1 # save config on exit } -S* { set do_saveconfig 1 # 'ssh -c' cypher type } -y* { if {! [regexp .\[eE\](.+) $arg ignore cypher]} { incr i set cypher [lindex $argv $i] } # alternate cloginrc file } -f* { if {! [regexp .\[fF\](.+) $arg ignore password_file]} { incr i set password_file [lindex $argv $i] } # Timeout } -t* { if {! [regexp .\[tT\](.+) $arg ignore timeout]} { incr i set timeoutdflt [lindex $argv $i] } # Command file } -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 { set avenable 0 # Does tacacs automatically enable us? } -autoenable { set avautoenable 1 set avenable 0 } -* { send_user "\nError: Unknown argument! $arg\n" send_user $usage exit 1 } default { break } } } # Process routers...no routers listed is an error. if { $i == $argc } { send_user "\nError: $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 avologin # 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 "\nError: password file ($password_file) does not exist\n" exit 1 } file stat $password_file fileinfo if { [expr ($fileinfo(mode) & 007)] != 0000 } { send_user "\nError: $password_file must not be world readable/writable\n" exit 1 } if [catch {source $password_file} reason] { send_user "\nError: $reason\n" exit 1 } } # Log into the router. # returns: 0 on success, 1 on failure proc login { router user userpswd passwd enapasswd cmethod cyphertype } { global spawn_id in_proc do_command do_script global prompt u_prompt p_prompt e_prompt sshcmd 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] { incr progs -1 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" return 1 } } elseif [string match "ssh*" $prog] { regexp {ssh(:([^[:space:]]+))*} $prog command suffix port set cmd $sshcmd if {"$port" != ""} { set cmd "$cmd -p $port" } set retval [ catch {eval spawn [split "$cmd -c $cyphertype -x -l $user $router" { }]} reason ] if { $retval } { send_user "\nError: $cmd failed: $reason\n" return 1 } } else { send_user "\nError: unknown connection method: $prog\n" return 1 } sleep 0.3 # This helps cleanup each expect clause. expect_after { timeout { send_user "\nError: TIMEOUT reached\n" catch {close}; catch {wait}; if { $in_proc} { return 1 } else { continue } } eof { send_user "\nError: EOF received\n" catch {close}; catch {wait}; if { $in_proc} { return 1 } else { continue } } } # Here we get a little tricky. There are several possibilities: # the router can ask for a username and passwd and then # talk to the TACACS server to authenticate you, or if the # TACACS server is not working, then it will use the enable # passwd. Or, the router might not have TACACS turned on, # then it will just send the passwd. # if telnet fails with connection refused, try ssh expect { -re "(Connection refused|Secure connection \[^\n\r]+ refused)" { catch {close}; catch {wait}; if !$progs { send_user "\nError: Connection Refused ($prog): $router\n" return 1 } } -re "(Connection closed by|Connection to \[^\n\r]+ closed)" { catch {close}; catch {wait}; if !$progs { send_user "\nError: Connection closed ($prog): $router\n" return 1 } } eof { send_user "\nError: Couldn't login: $router\n"; wait; return 1 } -nocase "unknown host\r" { catch {close}; catch {wait}; send_user "\nError: Unknown host $router\n"; wait; return 1 } "Host is unreachable" { catch {close}; catch {wait}; send_user "\nError: Host Unreachable: $router\n"; wait; return 1 } "No address associated with name" { catch {close}; catch {wait}; send_user "\nError: Unknown host $router\n"; wait; return 1 } -re "(Host key not found |The authenticity of host .* be established).* \\(yes/no\\)\\?" { send "yes\r" send_user "\nHost $router added to the list of known hosts.\n" exp_continue } -re "HOST IDENTIFICATION HAS CHANGED.* \\(yes/no\\)\\?" { send "no\r" send_user "\nError: The host key for $router has changed. Update the SSH known_hosts file accordingly.\n" return 1 } -re "HOST IDENTIFICATION HAS CHANGED\[^\n\r]+" { send_user "\nError: The host key for $router has changed. Update the SSH known_hosts file accordingly.\n" return 1 } -re "Offending key for .* \\(yes/no\\)\\?" { send "no\r" send_user "\nError: host key mismatch for $router. Update the SSH known_hosts file accordingly.\n" return 1 } -re "(denied|Sorry)" { send_user "\nError: Check your passwd for $router\n" catch {close}; catch {wait}; return 1 } "Login failed" { send_user "\nError: Check your passwd for $router\n" return 1 } -re "% (Bad passwords|Authentication failed)" { send_user "\nError: Check your passwd for $router\n" return 1 } -re "@\[^\r\n]+ $p_prompt" { # ssh pwd prompt sleep 1 send -- "$userpswd\r" exp_continue } -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 "$prompt" { break; } "Login invalid" { send_user "\nError: Invalid login: $router\n"; catch {close}; catch {wait}; return 1 } } } set in_proc 0 return 0 } # Enable proc do_enable { enauser enapasswd } { global prompt in_proc global u_prompt e_prompt set in_proc 1 send "/bin/su\r" expect { -re "$u_prompt" { send -- "$enauser\r"; exp_continue} -re "$e_prompt" { send -- "$enapasswd\r"; exp_continue} "#" { set prompt "#" } -re "su: User not allowed access" { send_user "\nError: Enable access not allowed\n"; return 1 } -re "(denied|Sorry|Incorrect)" { # % Access denied - from local auth and poss. others send_user "\nError: Check your Enable passwd\n"; return 1 } "% Error in authentication" { send_user "\nError: Check your Enable passwd\n" return 1 } "% Bad passwords" { send_user "\nError: Check your Enable passwd\n" return 1 } } # We set the prompt variable (above) so script files don't need # to know what it is. 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 # The pager cant be completely disabled send "stty rows 1024\r" # escape any parens in the prompt, such as "(enable)" regsub -all {[)(]} $prompt {\\&} reprompt # XXX # match cisco config mode prompts too, such as router(config-if)#, # but catalyst does not change in this fashion. regsub -all {^(.{1,14}).*([#>])$} $reprompt {\1([^#>\r\n]+)?[#>](\\([^)\\r\\n]+\\))?} reprompt expect { -re $reprompt {} -re "\[\n\r]+" { exp_continue } } # this is the only way i see to get rid of more prompts in o/p..grrrrr log_user 0 set commands [split $command \;] set num_commands [llength $commands] # the pager can not be turned off on the PIX, so we have to look # for the "More" prompt. the extreme is equally obnoxious, with a # global switch in the config. for {set i 0} {$i < $num_commands} { incr i} { send -- "[subst -nocommands [lindex $commands $i]]\r" expect { -re "\b+" { exp_continue } -re "^\[^\n\r *]*$reprompt" { send_user -- "$expect_out(buffer)" } -re "^\[^\n\r]*$reprompt." { send_user -- "$expect_out(buffer)" exp_continue } -re "\[\n\r]+" { send_user -- "$expect_out(buffer)" exp_continue } -re "\[^\r\n]*Press to cont\[^\r\n]*" { send " " # bloody ^[[2K after " " expect { -re "^\[^\r\n]*\r" {} } exp_continue } -re "^ *--More--\[^\n\r]*" { send " " exp_continue } -re "^<-+ More -+>\[^\n\r]*" { send_user -- "$expect_out(buffer)" send " " exp_continue } } } log_user 1 send "exit\r" expect { -re "^\[^\n\r *]*$reprompt" { # the Cisco CE and Jnx ERX # return to non-enabled mode # on exit in enabled mode. send "exit\r" exp_continue; } "Do you wish to save your configuration changes" { send "n\r" exp_continue } -re "\[\n\r]+" { exp_continue } 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 set exitval 0 foreach router [lrange $argv $i end] { set router [string tolower $router] send_user "$router\n" # device timeout set timeout [find timeout $router] if { [llength $timeout] == 0 } { set timeout $timeoutdflt } # Figure out the prompt. # autoenable is off by default. If we have it defined, it was done # on the command line. If it is not specifically set on the command # line, check the password file. if $avautoenable { set autoenable 1 set enable 0 set prompt "#" } else { set ae [find autoenable $router] if { "$ae" == "1" } { set autoenable 1 set enable 0 set prompt "#" } else { set autoenable 0 set enable $avenable set prompt "\\\$" } } # look for noenable option in .cloginrc if { [find noenable $router] == "1" } { set enable 0 } # Figure out passwords if { $do_passwd || $do_enapasswd } { set pswd [find password $router] if { [llength $pswd] == 0 } { send_user "\nError: no password for $router in $password_file.\n" continue } if { $enable && $do_enapasswd && $autoenable == 0 && [llength $pswd] < 2 } { send_user "\nError: no enable password for $router in $password_file.\n" continue } set passwd [join [lindex $pswd 0] ""] set enapasswd [join [lindex $pswd 1] ""] } # Figure out username if {[info exists username]} { # command line username set ruser $username } else { set ruser [join [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 [join [find userpassword $router] ""] if { "$userpswd" == "" } { set userpswd $passwd } } # Figure out enable username if {[info exists enausername]} { # command line enausername set enauser $enausername } else { set enauser [join [find enauser $router] ""] if { "$enauser" == "" } { set enauser $ruser } } # Figure out prompts set u_prompt [find userprompt $router] if { "$u_prompt" == "" } { set u_prompt "(Username|Login|login|user name):" } else { set u_prompt [join [lindex $u_prompt 0] ""] } set p_prompt [find passprompt $router] if { "$p_prompt" == "" } { set p_prompt "(\[Pp]assword|passwd):" } else { set p_prompt [join [lindex $p_prompt 0] ""] } set e_prompt [find enableprompt $router] if { "$e_prompt" == "" } { set e_prompt "\[Pp]assword:" } else { set e_prompt [join [lindex $e_prompt 0] ""] } # 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}} } # Figure out the SSH executable name set sshcmd [join [lindex [find sshcmd $router] 0] ""] if { "$sshcmd" == "" } { set sshcmd {ssh} } # Login to the router if {[login $router $ruser $userpswd $passwd $enapasswd $cmethod $cyphertype]} { # if login failed, move on to the next device incr exitval continue } if { $enable } { if {[do_enable $enauser $enapasswd]} { if { $do_command || $do_script } { incr exitval catch {close}; catch {wait}; continue } } } # we are logged in, now figure out the full prompt send "\r" expect { -re "\[\r\n]+" { exp_continue; } -re "^.+$prompt" { set junk $expect_out(0,string); regsub -all "\[\]\[\$]" $junk {\\&} prompt; } } if { $do_command } { if {[run_commands $prompt $command]} { incr exitval continue } } elseif { $do_script } { # XXX # If the prompt is (enable), then we are on a switch and the # command is "set length 0"; otherwise its "term length 0". if [regexp -- ".*> .*enable" "$prompt"] { #send "set length 0\r" #send "set logging session disable\r" } else { #send "term length 0\r" } expect -re $prompt {} source $sfile catch {close}; } else { label $router log_user 1 interact } # End of for each router catch {wait}; sleep 0.3 } exit $exitval rancid-2.3.8/bin/avorancid.in100644 015615 000000 00000023144 11535733223 0011534#! @PERLV_PATH@ ## ## $Id: avorancid.in 2288 2011-02-17 17:16:50Z heas $ ## ## @PACKAGE@ @VERSION@ ## Copyright (c) 1997-2008 by Terrapin Communications, Inc. ## All rights reserved. ## ## This code is derived from software contributed to and maintained by ## Terrapin Communications, Inc. by Henry Kilmer, John Heasley, Andrew Partan, ## Pete Whiting, Austin Schutz, and Andrew Fort. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions ## are met: ## 1. Redistributions of source code must retain the above copyright ## notice, this list of conditions and the following disclaimer. ## 2. Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## 3. All advertising materials mentioning features or use of this software ## must display the following acknowledgement: ## This product includes software developed by Terrapin Communications, ## Inc. and its contributors for RANCID. ## 4. Neither the name of Terrapin Communications, Inc. nor the names of its ## contributors may be used to endorse or promote products derived from ## this software without specific prior written permission. ## 5. It is requested that non-binding fixes and modifications be contributed ## back to Terrapin Communications, Inc. ## ## THIS SOFTWARE IS PROVIDED BY Terrapin Communications, INC. AND CONTRIBUTORS ## ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ## TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COMPANY OR CONTRIBUTORS ## BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ## CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ## SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ## INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ## CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ## ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ## POSSIBILITY OF SUCH DAMAGE. # # RANCID - Really Awesome New Cisco confIg Differ # # usage: rancid [-dV] [-l] [-f filename | $host] # use Getopt::Std; 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; $found_version = 0; $found_env = 0; $found_diag = 0; $timeo = 90; # avologin timeout in seconds my(@commandtable, %commands, @commands);# command lists my($aclsort) = ("ipsort"); # ACL sorting mode my($filter_commstr); # SNMP community string filtering 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)) && scalar(%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 routine 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 routine 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 routine 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 routine (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 "cat" sub CatFile { print STDERR " In CatFile: $_" if ($debug); $catfile = $1; $catfile =~ s/cat //; ProcessHistory("COMMENTS","","","! $catfile\n"); while () { tr/\015//d; last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); return(-1) if /: Permission denied/; ProcessHistory("COMMENTS","","","$_"); } ProcessHistory("COMMENTS","","","!\n"); if ( $catfile == "/etc/security.opts" ) { $found_end = 1; $clean_run = 1;}; return(0); } # dummy function sub DoNothing {print STDOUT;} # Main @commandtable = ( {'cat /etc/hostname' => 'CatFile'}, {'cat /etc/domainname.conf' => 'CatFile'}, {'cat /etc/resolv.conf' => 'CatFile'}, {'cat /etc/portslave/pslave.conf' => 'CatFile'}, {'cat /etc/passwd' => 'CatFile'}, {'cat /etc/snmp/snmpd.conf' => 'CatFile'}, {'cat /etc/network/ifcfg_eth0' => 'CatFile'}, {'cat /etc/network/st_routes' => 'CatFile'}, {'cat /etc/security.opts' => 'CatFile'}, {'cat /etc/pmdgrp.conf' => 'CatFile'}, ); # 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("|", map quotemeta($_), @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 avologin -t $timeo -c\"$cisco_cmds\" $host\n" if ($debug); print STDOUT "executing avologin -t $timeo -c\"$cisco_cmds\" $host\n" if ($log); if (defined($ENV{NOPIPE}) && $ENV{NOPIPE} =~ /^YES/i) { system "avologin -t $timeo -c \"$cisco_cmds\" $host $host.raw 2>&1" || die "avologin failed for $host: $!\n"; open(INPUT, "< $host.raw") || die "avologin failed for $host: $!\n"; } else { open(INPUT,"avologin -t $timeo -c \"$cisco_cmds\" $host ) { tr/\015//d; if (/[#\$] exit$/) { $clean_run = 1; last; } if (/^Error:/) { print STDOUT ("$host avologin error: $_"); print STDERR ("$host avologin error: $_") if ($debug); $clean_run = 0; last; } while (/[#\$]\s*($cmds_regexp)\s*$/) { $cmd = $1; 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; } $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}) && $ENV{NOPIPE} =~ /^YES/i) { 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); } rancid-2.3.8/bin/blogin.in100644 015615 000000 00000045554 11712067106 0011046#! @EXPECT_PATH@ -- ## ## $Id: blogin.in 2376 2012-01-31 22:42:14Z heas $ ## ## @PACKAGE@ @VERSION@ ## Copyright (c) @COPYYEARS@ by Terrapin Communications, Inc. ## All rights reserved. ## ## This code is derived from software contributed to and maintained by ## Terrapin Communications, Inc. by Henry Kilmer, John Heasley, Andrew Partan, ## Pete Whiting, Austin Schutz, and Andrew Fort. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions ## are met: ## 1. Redistributions of source code must retain the above copyright ## notice, this list of conditions and the following disclaimer. ## 2. Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## 3. All advertising materials mentioning features or use of this software ## must display the following acknowledgement: ## This product includes software developed by Terrapin Communications, ## Inc. and its contributors for RANCID. ## 4. Neither the name of Terrapin Communications, Inc. nor the names of its ## contributors may be used to endorse or promote products derived from ## this software without specific prior written permission. ## 5. It is requested that non-binding fixes and modifications be contributed ## back to Terrapin Communications, Inc. ## ## THIS SOFTWARE IS PROVIDED BY Terrapin Communications, INC. AND CONTRIBUTORS ## ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ## TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COMPANY OR CONTRIBUTORS ## BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ## CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ## SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ## INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ## CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ## ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ## POSSIBILITY OF SUCH DAMAGE. # # The expect login scripts were based on Erik Sherk's gwtn, by permission. # # blogin - Bay Networks(Nortel) login # # Unlike the Cisco's, there is no enable function on the Bay's. Instead # there are seperate User and Manager accounts. A 'system' command exists, # which I am told does nothing. # # The "bcc>" prompt changes to "box#", not "bcc#" after the config command. # # Usage line set usage "Usage: $argv0 \[-dSV\] \[-autoenable\] \[-noenable\] \[-c command\] \ \[-Evar=x\] \[-e enable-password\] \[-f cloginrc-file\] \[-p user-password\] \ \[-s script-file\] \[-t timeout\] \[-u username\] \ \[-v vty-password\] \[-w enable-username\] \[-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 avenable 0 # The default is that you login non-enabled (tacacs can have you login already # enabled) set avautoenable 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 set do_enapasswd 0 # Save config, if prompted set do_saveconfig 0 # Sometimes routers take awhile to answer (the default is 10 sec) set timeoutdflt 45 # 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) } elseif {[ info exists env(LOGNAME) ]} { set default_user $env(LOGNAME) } 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 "\nError: could not exec id: $reason\n" exit 1 } regexp {\(([^)]*)} "$reason" junk default_user } if {[ info exists env(CLOGINRC) ]} { set password_file $env(CLOGINRC) } # Process the command line for {set i 0} {$i < $argc} {incr i} { set arg [lindex $argv $i] switch -glob -- $arg { # Expect debug mode -d* { exp_internal 1 # Username } -u* { if {! [ regexp .\[uU\](.+) $arg ignore user]} { incr i set username [ lindex $argv $i ] } # VTY Password } -p* { if {! [ regexp .\[pP\](.+) $arg ignore userpasswd]} { incr i set userpasswd [ lindex $argv $i ] } set do_passwd 0 # ssh passphrase } -r* { # ignore -r # VTY Password } -v* { if {! [ regexp .\[vV\](.+) $arg ignore passwd]} { incr i set passwd [ lindex $argv $i ] } set do_passwd 0 # Version string } -V* { send_user "@PACKAGE@ @VERSION@\n" exit 0 # Enable Username } -w* { if {! [ regexp .\[wW\](.+) $arg ignore enauser]} { incr i set enausername [ lindex $argv $i ] } # Environment variable to pass to -s scripts } -E* { if {[ regexp .\[E\](.+)=(.+) $arg ignore varname varvalue]} { set E$varname $varvalue } else { send_user "\nError: invalid format for -E in $arg\n" exit 1 } # Enable Password } -e* { if {! [ regexp .\[eE\](.+) $arg ignore enapasswd]} { incr i set enapasswd [ lindex $argv $i ] } set do_enapasswd 0 # Command to run. } -c* { if {! [ regexp .\[cC\](.+) $arg ignore command]} { incr i set command [ lindex $argv $i ] } set do_command 1 # Expect script to run. } -s* { if {! [ regexp .\[sS\](.+) $arg ignore sfile]} { incr i set sfile [ lindex $argv $i ] } if { ! [ file readable $sfile ] } { send_user "\nError: Can't read $sfile\n" exit 1 } set do_script 1 # save config on exit } -S* { set do_saveconfig 1 # 'ssh -c' cypher type } -y* { if {! [ regexp .\[eE\](.+) $arg ignore cypher]} { incr i set cypher [ lindex $argv $i ] } # alternate cloginrc file } -f* { if {! [ regexp .\[fF\](.+) $arg ignore password_file]} { incr i set password_file [ lindex $argv $i ] } # Timeout } -t* { if {! [ regexp .\[tT\](.+) $arg ignore timeout]} { incr i set timeoutdflt [ lindex $argv $i ] } # Command file } -x* { if {! [ regexp .\[xX\](.+) $arg ignore cmd_file]} { incr i set cmd_file [ lindex $argv $i ] } set cmd_fd [open $cmd_file r] set cmd_text [read $cmd_fd] close $cmd_fd set command [join [split $cmd_text \n] \;] set do_command 1 # Do we enable? } -noenable { set avenable 0 # Does tacacs automatically enable us? } -autoenable { set avautoenable 1 set avenable 0 } -* { send_user "\nError: Unknown argument! $arg\n" send_user $usage exit 1 } default { break } } } # Process routers...no routers listed is an error. if { $i == $argc } { send_user "\nError: $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 "\nError: password file ($password_file) does not exist\n" exit 1 } file stat $password_file fileinfo if { [expr ($fileinfo(mode) & 007)] != 0000 } { send_user "\nError: $password_file must not be world readable/writable\n" exit 1 } if [ catch {source $password_file} reason ] { send_user "\nError: $reason\n" exit 1 } } # Log into the router. # returns: 0 on success, 1 on failure proc login { router user userpswd passwd enapasswd prompt cmethod cyphertype } { global spawn_id in_proc do_command do_script global u_prompt p_prompt e_prompt sshcmd set in_proc 1 # try each of the connection methods in $cmethod until one is successful set progs [llength $cmethod] foreach prog [lrange $cmethod 0 end] { incr progs -1 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" return 1 } } elseif ![string compare $prog "ssh"] { regexp {ssh(:([^[:space:]]+))*} $prog methcmd suffix port set cmd $sshcmd if {"$port" != ""} { set cmd "$cmd -p $port" } set retval [ catch {eval spawn [split "$cmd -c $cyphertype -x -l $user $router" { }]} reason ] if { $retval } { send_user "\nError: $cmd failed: $reason\n" return 1 } } elseif ![string compare $prog "rsh"] { send_error "\nError: unsupported method: rsh\n" if { $progs == 0 } { return 1 } continue; } else { send_user "\nError: unknown connection method: $prog\n" return 1 } sleep 0.3 # This helps cleanup each expect clause. expect_after { timeout { send_user "\nError: TIMEOUT reached\n" catch {close}; catch {wait}; if { $in_proc} { return 1 } else { continue } } eof { send_user "\nError: EOF received\n" catch {close}; catch {wait}; if { $in_proc} { return 1 } else { continue } } } # Here we get a little tricky. There are several possibilities: # the router can ask for a username and passwd and then # talk to the TACACS server to authenticate you, or if the # TACACS server is not working, then it will use the enable # passwd. Or, the router might not have TACACS turned on, # then it will just send the passwd. # if telnet fails with connection refused, try ssh expect { -re "(Connection refused|Secure connection \[^\n\r]+ refused|Connection closed by)" { catch {close}; catch {wait}; if !$progs { send_user "\nError: Connection Refused ($prog)\n"; return 1 } } eof { send_user "\nError: Couldn't login\n"; wait; return 1 } -nocase "unknown host\r" { catch {close}; catch {wait}; send_user "\nError: Unknown host\n"; wait; return 1 } "Host is unreachable" { catch {close}; catch {wait}; send_user "\nError: Host Unreachable!\n"; wait; return 1 } "No address associated with name" { catch {close}; catch {wait}; send_user "\nError: Unknown host\n"; wait; return 1 } -re "(Host key not found |The authenticity of host .* be established).* \\(yes/no\\)\\?" { send "yes\r" send_user "\nHost $router added to the list of known hosts.\n" exp_continue } -re "HOST IDENTIFICATION HAS CHANGED.* \\(yes/no\\)\\?" { send "no\r" send_user "\nError: The host key for $router has changed. Update the SSH known_hosts file accordingly.\n" return 1 } -re "HOST IDENTIFICATION HAS CHANGED\[^\n\r]+" { send_user "\nError: The host key for $router has changed. Update the SSH known_hosts file accordingly.\n" return 1 } -re "Offending key for .* \\(yes/no\\)\\?" { send "no\r" send_user "\nError: host key mismatch for $router. Update the SSH known_hosts file accordingly.\n" return 1 } -re "$u_prompt" { send -- "$user\r" expect { eof { send_user "\nError: Couldn't login\n"; wait; return 1 } "Login invalid" { send_user "\nError: Invalid login\n"; catch {close}; catch {wait}; return 1 } -re "$p_prompt" { send -- "$userpswd\r" } "$prompt" { set in_proc 0; return 0 } } exp_continue } -re "$p_prompt" { if ![string compare $prog "ssh"] { send -- "$userpswd\r" } else { send -- "$passwd\r" } expect { eof { send_user "\nError: Couldn't login\n"; wait; return 1 } -re "$e_prompt" { send -- "$enapasswd\r" } "$prompt" { set in_proc 0; return 0 } } exp_continue } "$prompt" { break; } denied { send_user "\nError: Check your passwd for $router\n" catch {close}; catch {wait}; return 1 } "% Bad passwords" {send_user "\nError: Check your passwd for $router\n"; return 1 } } } set in_proc 0 return 0 } # Enable proc do_enable { enauser enapasswd } { global prompt in_proc global u_prompt e_prompt set in_proc 1 send "enable\r" expect { -re "$u_prompt" { send -- "$enauser\r"; exp_continue} -re "$e_prompt" { send -- "$enapasswd\r"; exp_continue} "#" { set prompt "#" } "(enable)" { set prompt "> (enable) " } denied { send_user "\nError: Check your Enable passwd\n" return 1 } "% Bad passwords" { send_user "\nError: Check your Enable passwd\n" return 1 } } # We set the prompt variable (above) so script files don't need # to know what it is. 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 "more off\r" expect $prompt {} regsub -all "\[)(]" $prompt {\\&} reprompt 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 } } } send "logout\r" expect { "\n" { exp_continue } timeout { catch {close}; catch {wait}; 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 set exitval 0 foreach router [lrange $argv $i end] { set router [string tolower $router] send_user "$router\n" # device timeout set timeout [find timeout $router] if { [llength $timeout] == 0 } { set timeout $timeoutdflt } # Figure out prompt. # Since autoenable is off by default, if we have it defined, it # was done on the command line. If it is not specifically set on the # command line, check the password file. if $avautoenable { set autoenable 1 set enable 0 set prompt "#" } else { set ae [find autoenable $router] if { "$ae" == "1" } { set autoenable 1 set enable 0 set prompt "#" } else { set autoenable 0 set enable $avenable set prompt ">" } } # look for noenable option in .cloginrc if { [find noenable $router] == "1" } { set enable 0 } # Figure out passwords if { $do_passwd || $do_enapasswd } { set pswd [find password $router] if { [llength $pswd] == 0 } { send_user "\nError - no password for $router in $password_file.\n" continue } if { $do_enapasswd && $autoenable == 0 && [llength $pswd] < 2 } { send_user "\nError - no enable password for $router in $password_file.\n" continue } set passwd [join [lindex $pswd 0] ""] set enapasswd [join [lindex $pswd 1] ""] } else { set passwd $userpasswd set enapasswd $enapasswd } # Figure out username if {[info exists username]} { # command line username set ruser $username } else { set ruser [join [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 [join [find userpassword $router] ""] if { "$userpswd" == "" } { set userpswd $passwd } } # Figure out enable username if {[info exists enausername]} { # command line enausername set enauser $enausername } else { set enauser [join [find enauser $router] ""] if { "$enauser" == "" } { set enauser $ruser } } # Figure out prompts set u_prompt [find userprompt $router] if { "$u_prompt" == "" } { set u_prompt "(Username|login|user name):" } else { set u_prompt [join [lindex $u_prompt 0] ""] } set p_prompt [find passprompt $router] if { "$p_prompt" == "" } { set p_prompt "(\[Pp]assword|passwd):" } else { set p_prompt [join [lindex $p_prompt 0] ""] } set e_prompt [find enableprompt $router] if { "$e_prompt" == "" } { set e_prompt "\[Pp]assword:" } else { set e_prompt [join [lindex $e_prompt 0] ""] } # 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}} } # Figure out the SSH executable name set sshcmd [join [lindex [find sshcmd $router] 0] ""] if { "$sshcmd" == "" } { set sshcmd {ssh} } # Login to the router if {[login $router $ruser $userpswd $passwd $enapasswd $prompt $cmethod $cyphertype]} { incr exitval continue } if { $enable } { if {[do_enable $enauser $enapasswd]} { if { $do_command || $do_script } { incr exitval catch {close}; catch {wait}; continue } } } if { $do_command } { if {[run_commands $prompt $command]} { incr exitval continue } } elseif { $do_script } { send "more off\r" expect $prompt {} source $sfile catch {close}; } else { label $router log_user 1 interact } # End of for each router catch {wait}; sleep 0.3 } exit $exitval rancid-2.3.8/bin/brancid.in100644 015615 000000 00000023556 11535733223 0011177#! @PERLV_PATH@ ## ## $Id: brancid.in 2279 2011-01-31 22:41:00Z heas $ ## hacked version of Hank's rancid - this one tries to deal with Bay's. ## ## @PACKAGE@ @VERSION@ ## Copyright (c) 1997-2008 by Terrapin Communications, Inc. ## All rights reserved. ## ## This code is derived from software contributed to and maintained by ## Terrapin Communications, Inc. by Henry Kilmer, John Heasley, Andrew Partan, ## Pete Whiting, Austin Schutz, and Andrew Fort. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions ## are met: ## 1. Redistributions of source code must retain the above copyright ## notice, this list of conditions and the following disclaimer. ## 2. Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## 3. All advertising materials mentioning features or use of this software ## must display the following acknowledgement: ## This product includes software developed by Terrapin Communications, ## Inc. and its contributors for RANCID. ## 4. Neither the name of Terrapin Communications, Inc. nor the names of its ## contributors may be used to endorse or promote products derived from ## this software without specific prior written permission. ## 5. It is requested that non-binding fixes and modifications be contributed ## back to Terrapin Communications, Inc. ## ## THIS SOFTWARE IS PROVIDED BY Terrapin Communications, INC. AND CONTRIBUTORS ## ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ## TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COMPANY OR CONTRIBUTORS ## BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ## CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ## SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ## INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ## CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ## ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ## POSSIBILITY OF SUCH DAMAGE. # # RANCID - Really Awesome New Cisco confIg Differ # # usage: rancid [-dV] [-l] [-f filename | hostname] # use Getopt::Std; 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; # blogin timeout in seconds my(@commandtable, %commands, @commands);# command lists my($aclsort) = ("ipsort"); # ACL sorting mode my($filter_commstr); # SNMP community string filtering 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)) && scalar(%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 routine 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 routine 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 routine 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 routine (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 "show config" sub ShowConfig { print STDERR " In ShowConfig: $_" if ($debug); while () { tr/\015//d; last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); next if (/^Reading configuration information/); next if (/^Can\'t find object or class named \"\-all\"\s*$/); next if (/lock-address .*$/); next if (/^\# *uptime +\d+\s*$/); if (/community label /) { if ($filter_commstr) { $_ =~ s/community label .*$/community label /; } } return(1) if /(invalid command name)/; ProcessHistory("","","","$_"); } # ProcessHistory("","","","!$_"); if (/exit$/) { $found_end = 1; return(1); } return(0); } # This routine parses single command's that return no required info sub RunCommand { print STDERR " In RunCommand: $_" if ($debug); while () { tr/\015//d; last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); # prompt may have changed if (/\>/) { $prompt = ($_ =~ /^([^>]+>)/)[0]; $prompt =~ s/([][])/\\$1/g; last; } } return(0) } # dummy function sub DoNothing {print STDOUT;} # Main @commandtable = ( {'bcc' => 'RunCommand'}, {'show config' => 'ShowConfig'}, {'show config -all' => 'ShowConfig'}, {'exit' => 'RunCommand'} ); # 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("|", map quotemeta($_), @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 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 blogin -t $timeo -c\"$cisco_cmds\" $host\n" if ($debug); print STDOUT "executing blogin -t $timeo -c\"$cisco_cmds\" $host\n" if ($log); if (defined($ENV{NOPIPE}) && $ENV{NOPIPE} =~ /^YES/i) { system "blogin -t $timeo -c \"$cisco_cmds\" $host $host.raw 2>&1" || die "blogin failed for $host: $!\n"; open(INPUT, "< $host.raw") || die "blogin failed for $host: $!\n"; } else { open(INPUT,"blogin -t $timeo -c \"$cisco_cmds\" $host ) { tr/\015//d; if ( (/\>\s?logout$/) || $found_end ) { $clean_run=1; last; } if (/^Error:/) { print STDOUT ("$host blogin error: $_"); print STDERR ("$host blogin error: $_") if ($debug); $clean_run=0; last; } while (/>\s*($cmds_regexp)\s*$/) { $cmd = $1; 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; } $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}) && $ENV{NOPIPE} =~ /^YES/i) { 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); } rancid-2.3.8/bin/cat5rancid.in100644 015615 000000 00000111522 11535733223 0011601#! @PERLV_PATH@ ## ## $Id: cat5rancid.in 2279 2011-01-31 22:41:00Z heas $ ## ## @PACKAGE@ @VERSION@ ## Copyright (c) 1997-2008 by Terrapin Communications, Inc. ## All rights reserved. ## ## This code is derived from software contributed to and maintained by ## Terrapin Communications, Inc. by Henry Kilmer, John Heasley, Andrew Partan, ## Pete Whiting, Austin Schutz, and Andrew Fort. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions ## are met: ## 1. Redistributions of source code must retain the above copyright ## notice, this list of conditions and the following disclaimer. ## 2. Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## 3. All advertising materials mentioning features or use of this software ## must display the following acknowledgement: ## This product includes software developed by Terrapin Communications, ## Inc. and its contributors for RANCID. ## 4. Neither the name of Terrapin Communications, Inc. nor the names of its ## contributors may be used to endorse or promote products derived from ## this software without specific prior written permission. ## 5. It is requested that non-binding fixes and modifications be contributed ## back to Terrapin Communications, Inc. ## ## THIS SOFTWARE IS PROVIDED BY Terrapin Communications, INC. AND CONTRIBUTORS ## ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ## TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COMPANY OR CONTRIBUTORS ## BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ## CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ## SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ## INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ## CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ## ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ## POSSIBILITY OF SUCH DAMAGE. # # RANCID - Really Awesome New Cisco confIg Differ # # usage: rancid [-dV] [-l] [-f filename | hostname] # use Getopt::Std; 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 my(@commandtable, %commands, @commands);# command lists my($aclsort) = ("ipsort"); # ACL sorting mode my($filter_commstr); # SNMP community string filtering my($filter_pwds); # password filtering mode my(%modules); # module info (part from sh ver, part from sh module) # 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)) && scalar(%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 routine 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 routine 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 routine 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 routine (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 "show version" sub ShowVersion { print STDERR " In ShowVersion: $_" if ($debug); while () { tr/\015//d; last if(/^$prompt/); next if(/^(\s*|\s*$cmd\s*)$/); /^(\S+) Software, Version\s+(.*)$/ && ProcessHistory("COMMENTS","keysort","F1", "!Image: Software: $2\n") && next; /^(\S+) S\/W compiled on (.*)$/ && ProcessHistory("COMMENTS","keysort","F3", "!Image: Compiled: $1 on $2\n") && next; /^System Bootstrap (Version.*)$/ && ProcessHistory("COMMENTS","keysort","G1", "!Bootstrap: $1\n") && next; if (/^Hardware Version: (\S+) Model: (\S+) Serial #: (\S+)/) { my($proc) = $2; # Really should figure out types of switches here. $type = $2; ProcessHistory("COMMENTS","keysort","A1", "!Chassis type: $proc - a $type switch\n"); ProcessHistory("COMMENTS","keysort","C1", "!Serial Number: $3\n"); ProcessHistory("COMMENTS","keysort","C2", "!Hardware Version: $1\n"); next; } # stuff module h/w, s/w, ports, etc into %module if (/^Mod\s+Port\s+Model/) { ; my($slot); while () { tr/\015//d; last if (/^\s*$/); if (/^(\d+)\s+(\d+)\s+(\S+)\s+(\S+)\s+(\S+)\s?:\s+(\S+)/) { $slot = $1; $modules{$slot}->{ports} = $2; $modules{$slot}->{model} = $3; $modules{$slot}->{serial} = $4; $modules{$slot}->{$5} = $6; # revision info } /^\s+(\S+)\s?:\s+(\S+)/ && ($modules{$slot}->{$1} = $2); } next; } # stuff module h/w, s/w, ports, etc into %module - yet another format if (/^Module\s+Ports\s+Model/) { ; my($slot); while () { tr/\015//d; last if (/^\s*$/); if (/^(\d+)\s+(\d+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+\s+)?(\S+)\s*$/) { $slot = $1; $modules{$slot}->{ports} = $2; $modules{$slot}->{model} = $3; $modules{$slot}->{serial} = $4; $modules{$slot}->{Hw} = $5; $modules{$slot}->{Fw} = $6; $modules{$slot}->{Sw} = $8; $modules{$slot}->{Fw1} = $7; $modules{$slot}->{Fw1} =~ s/\s*$//; if ($modules{$slot}->{Fw1} =~ /^$/) {delete($modules{$slot}->{Fw1});} } } next; } if (/^ DRAM/) { # Eat 2 lines & then get the total dram, flash, & nvram. $_ = ; $_ = ; $_ = ; tr/\015//d; /\S+\s+(\S+)\s+\S+\s+\S+\s+(\S+)\s+\S+\s+\S+\s+(\S+)/ && ProcessHistory("COMMENTS","keysort","B1", "!Memory: dram $1\n") && ProcessHistory("COMMENTS","keysort","B5", "!Memory: flash $2\n") && ProcessHistory("COMMENTS","keysort","B2", "!Memory: nvram $3\n"); next; } if (/^Module DRAM/) { # Eat a line & then get the total dram, flash, & nvram. $_ = ; $_ = ; tr/\015//d; /\S+\s+(\S+)\s+(\S+)\s+(\S+)/ && ProcessHistory("COMMENTS","keysort","B1", "!Memory: dram $1\n") && ProcessHistory("COMMENTS","keysort","B5", "!Memory: flash $2\n") && ProcessHistory("COMMENTS","keysort","B2", "!Memory: nvram $3\n"); next; } } return(0); } # This routine parses "show install active" sub ShowInstallActive { print STDERR " In ShowInstallActive: $_" if ($debug); while () { tr/\015//d; last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); return(1) if /^\s*\^\s*$/; return(1) if /Invalid input detected/; return(1) if /Unknown command/; ProcessHistory("COMMENTS","keysort","F5","!Image: $_") && next; } return(0); } # This routine parses "show env all" sub ShowEnv { # Skip if this is not a 7500, 7200, or 7000. print STDERR " In ShowEnv: $_" if ($debug); while () { tr/\015//d; last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); return(1) if ($type !~ /^7/); if (!defined($E0)) { $E0=1; ProcessHistory("COMMENTS","keysort","E0","!\n"); } if (/^Arbiter type (\d), backplane type (\S+)/) { if (!defined($C0)) { $C0=1; ProcessHistory("COMMENTS","keysort","C0","!\n"); } ProcessHistory("COMMENTS","keysort","C1", "!Enviromental Arbiter Type: $1\n"); ProcessHistory("COMMENTS","keysort","A2", "!Chassis type: $2 backplane\n"); next; } /^\s*(Power .*)/ && ProcessHistory("COMMENTS","keysort","E1","!Power: $1\n") && next; /^\s*(Lower Power .*)/i && ProcessHistory("COMMENTS","keysort","E2","!Power: $1\n") && next; } ProcessHistory("COMMENTS","","","!\n"); return(0); } # This routine parses "show gsr chassis-info" for the gsr # This will create arrarys for hw info. sub ShowGSR { # Skip if this is not a 1200n. print STDERR " In ShowGSR: $_" if ($debug); while () { tr/\015//d; last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); return(1) if ($type !~ /^120/); /^$/ && next; /^\s+Chassis: type (\S+) Fab Ver: (\S+)/ && ProcessHistory("COMMENTS","keysort","D0","!\n") && ProcessHistory("COMMENTS","keysort","D1", "!GSR Chassis type: $1 Fab Ver: $2\n") && next; /^\s+Chassis S\/N: (.*)$/ && ProcessHistory("COMMENTS","keysort","D2", "!GSR Chassis S/N: $1\n") && next; /^\s+PCA: (\S+)\s*rev: (\S+)\s*dev: \S+\s*HW ver: (\S+)$/ && ProcessHistory("COMMENTS","keysort","D3", "!GSR Backplane PCA: $1, rev $2, ver $3\n") && next; /^\s+Backplane S\/N: (\S+)$/ && ProcessHistory("COMMENTS","keysort","D4", "!GSR Backplane S/N: $1\n") && next; } ProcessHistory("COMMENTS","","","!\n"); return(0); } # This routine parses "show boot" sub ShowBoot { print STDERR " In ShowBoot: $_" if ($debug); while () { tr/\015//d; last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); return(1) if /^\s*\^\s*$/; return(1) if /Ambiguous command/i; return(1) if /Invalid input detected/; return(1) if /Unknown command/; return(1) if /(Open device \S+ failed|Error opening \S+:)/; next if /CONFGEN variable/; if (!defined($H0)) { $H0=1; ProcessHistory("COMMENTS","keysort","H0","!\n"); } /^(\S+) variable (.*)$/ && ProcessHistory("COMMENTS","keysort","H1","!Variable: $1 $2\n") && next; if (/^Configuration register is (.*)$/) { $config_register=$1; next; } } ProcessHistory("COMMENTS","","","!\n"); return(0); } # This routine parses "show flash" sub ShowFlash { # skip if this is 7000, 7200, 7500, or 12000. print STDERR " In ShowFlash: $_" if ($debug); while () { tr/\015//d; last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); return(1) if ($type =~ /^(120|7)/); return(1) if /^\s*\^\s*$/; return(1) if /Invalid input detected/; return(-1) if /session in progress. Try again later/; # Flash is busy ProcessHistory("FLASH","","","!Flash: $_"); } ProcessHistory("","","","!\n"); return; } # This routine parses "dir /all ((disk|slot)N|bootflash):" sub DirSlotN { # Skip if this is not a 3600, 7000, 7200, 7500, or 12000. print STDERR " In DirSlotN: $_" if ($debug); my($dev) = (/\s([^\s]+):/); while () { tr/\015//d; last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); return(1) if ($type !~ /^(120|7|36)/); return(1) if /^\s*\^\s*$/; return(1) if /Invalid input detected/; return(1) if /\%Error: No such file or directory/; return(1) if /No space information available/; return(-1) if /\%Error calling/; return(-1) if /: device being squeezed/; # Flash is busy return(1) if /(Open device \S+ failed|Error opening \S+:)/; ProcessHistory("FLASH","","","!Flash: $dev: $_"); } ProcessHistory("","","","!\n"); return(0); } # This routine parses "show controllers" sub ShowContAll { # Skip if this is a 70[01]0, 7500, or 12000. print STDERR " In ShowContAll: $_" if ($debug); while () { tr/\015//d; last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); return(1) if ($type =~ /^(120|7[05])/); if (/^Interface ([^ \n(]*)/) { $INT = "$1, "; next; } /^(BRI unit \d)/ && ProcessHistory("INT","","","!Interface: $1\n") && next; /^LANCE unit \d, NIM/ && ProcessHistory("INT","","","!Interface: $_") && next; /^(LANCE unit \d)/ && ProcessHistory("INT","","","!Interface: $1\n") && next; /(Media Type is \S+),/ && ProcessHistory("INT","","","!\t$1\n"); if (/(M\dT:) show controller:$/) { my($ctlr) = $1; $_ = ; tr/\015//d; s/ subunit \d,//; ProcessHistory("INT","","","!Interface: $ctlr $_"); } if (/^(\S+) : show controller:$/) { my($ctlr) = $1; $_ = ; tr/\015//d; s/ subunit \d,//; ProcessHistory("INT","","","!Interface: $ctlr: $_"); } /^(HD unit \d), idb/ && ProcessHistory("INT","","","!Interface: $1\n") && next; /^HD unit \d, NIM/ && ProcessHistory("INT","","","!Interface: $_") && next; /^buffer size \d+ HD unit \d, (.*)/ && ProcessHistory("INT","","","!\t$1\n") && next; /^AM79970 / && ProcessHistory("INT","","","!Interface: $_") && next; /^buffer size \d+ (Universal Serial: .*)/ && ProcessHistory("INT","","","!\t$1\n") && next; /^Hardware is (.*)/ && ProcessHistory("INT","","","!Interface: $INT$1\n") && next; /^(QUICC Serial unit \d),/ && ProcessHistory("INT","","","!$1\n") && next; /^QUICC Ethernet .*/ && ProcessHistory("INT","","","!$_") && next; /^DTE .*\.$/ && ProcessHistory("INT","","","!\t$_") && next; /^(cable type :.*),/ && ProcessHistory("INT","","","!\t$1\n") && next; /^(.* cable.*), received clockrate \d+$/ && ProcessHistory("INT","","","!\t$1\n") && next; /^.* cable.*$/ && ProcessHistory("INT","","","!\t$_") && next; } return(0); } # This routine parses "show controllers cbus" # Some of this is printed out in ShowDiagbus. sub ShowContCbus { # Skip if this is not a 7000 or 7500. print STDERR " In ShowContCbus: $_" if ($debug); while () { tr/\015//d; last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); return(1) if ($type !~ /^7[05]0/); if (/^\s*slot(\d+): ([^,]+), hw (\S+), sw (\S+), ccb/) { $slot = $1; $board{$slot} = $2; $hwver{$slot} = $3; $hwucode{$slot} = $4; } elsif (/^\s*(\S+) (\d+), hardware version (\S+), microcode version (\S+)/) { $slot = $2; $board{$slot} = $1; $hwver{$slot} = $3; $hwucode{$slot} = $4; } elsif (/(Microcode .*)/) { $ucode{$slot} = $1; } elsif (/(software loaded .*)/) { $ucode{$slot} = $1; } elsif (/(\d+) Kbytes of main memory, (\d+) Kbytes cache memory/) { $hwmemd{$slot} = $1; $hwmemc{$slot} = $2; } elsif (/byte buffers/) { chop; s/^\s*//; $hwbuf{$slot} = $_; } elsif (/Interface (\d+) - (\S+ \S+),/) { $interface = $1; ProcessHistory("HW","","", "!\n!Int $interface: in slot $slot, named $2\n"); next; } elsif (/(\d+) buffer RX queue threshold, (\d+) buffer TX queue limit, buffer size (\d+)/) { ProcessHistory("HW","","","!Int $interface: rxq $1, txq $2, bufsize $3\n"); next; } } return(0); } # This routine parses "show diagbus" # This will create arrarys for hw info. sub ShowDiagbus { # Skip if this is not a 7000, 70[01]0, or 7500. print STDERR " In ShowDiagbus: $_" if ($debug); while () { tr/\015//d; last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); return(1) if ($type !~ /^7[05]/); if (/^\s*Slot (\d+):/i) { $slot = $1; next; } elsif (/^\s*Slot (\d+) \(virtual\):/i) { $slot = $1; next; } elsif (/^\s*(.*Processor.*|.*controller|.*Chassis Interface), HW rev (\S+), board revision (\S+)/i) { $board = $1; $hwver = $2; $boardrev = $3; if ($board =~ /Processor/) { if ($board =~ /7000 Route\/Switch/) { $board = "RSP7000"; } elsif ($board =~ /Route\/Switch Processor (\d)/) { $board = "RSP$1"; } elsif ($board =~ /Route/) { $board = "RP"; } elsif ($board =~ /Silicon Switch/) { $board = "SSP"; } elsif ($board =~ /Switch/) { $board = "SP"; $board = "SSP $sspmem" if $ssp; } elsif ($board =~ /ATM/) { $board = "AIP"; } } elsif ($board =~ /(.*) controller/i) { $board = $1; } # hwucode{$slot} defined in ShowContCbus if (defined $hwucode{$slot}) { ProcessHistory("SLOT","","","!\n!Slot $slot/$board: hvers $hwver rev $boardrev ucode $hwucode{$slot}\n"); } else { ProcessHistory("SLOT","","","!\n!Slot $slot/$board: hvers $hwver rev $boardrev\n"); } # These are also from the ShowContCbus ProcessHistory("SLOT","","","!Slot $slot/$board: $ucode{$slot}\n") if (defined $ucode{$slot}); ProcessHistory("SLOT","","","!Slot $slot/$board: memd $hwmemd{$slot}, cache $hwmemc{$slot}\n") if ((defined $hwmemd{$slot}) && (defined $hwmemc{$slot})); ProcessHistory("SLOT","","","!Slot $slot/$board: $hwbuf{$slot}\n") if (defined $hwbuf{$slot}); next; } /Serial number: (\S+)\s*Part number: (\S+)/ && ProcessHistory("SLOT","","", "!Slot $slot/$board: part $2, serial $1\n") && next; /^\s*Controller Memory Size: (.*)$/ && ProcessHistory("SLOT","","","!Slot $slot/$board: $1\n") && next; if (/PA Bay (\d) Information/) { $pano = $1; if ("PA" =~ /$board/) { ($s,$c) = split(/\//,$board); $board = "$s/$c/PA $pano"; } else { $board =~ s/\/PA \d//; $board = "$board/PA $pano"; } next; } /\s+(.*) PA, (\d) ports?, (\S+)/ && ProcessHistory("SLOT","","","!Slot $slot/$board: type $3, $2 ports\n") && next; /\s+(.*) PA( \(\S+\))?, (\d) ports?/ && ProcessHistory("SLOT","","","!Slot $slot/$board: type $1$2, $3 ports\n") && next; /^\s*HW rev (\S+), Board revision (\S+)/ && ProcessHistory("SLOT","","","!Slot $slot/$board: hvers $1 rev $2\n") && next; /Serial number: (\S+)\s*Part number: (\S+)/ && ProcessHistory("SLOT","","","!Slot $slot/$board: part $2, serial $1\n") && next; } return(0); } # This routine parses "show diag" for the gsr, 7200, 3600, 2600. # This will create arrarys for hw info. sub ShowDiag { # Skip if this is not a 12000. print STDERR " In ShowDiag: $_" if ($debug); while () { tr/\015//d; last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); return(1) if ($type !~ /^(120|720|36|26)/); /^$/ && next; if (!defined($showdiags)) {$showdiags=1; ProcessHistory("SLOT","","","!\n");} s/Port Packet Over SONET/POS/; if (/^\s*SLOT (\d+)\s+\(.*\): (.*)/) { $slot = $1; ProcessHistory("SLOT","","","!Slot $slot: $2\n"); $board = "RP" if (/Route Processor/); $board = "CLK" if (/Clock Scheduler Card/); next; } if (/^\s+PCA:\s+(.*)/){ local($part) = $1; $_ = ; /^\s+HW version (\S+)\s+S\/N (\S+)/ && ProcessHistory("SLOT","","","!Slot $slot/PCA: part $part, serial $2\n") && ProcessHistory("SLOT","","","!Slot $slot/PCA: hvers $1\n"); next; } if (/^\s+MBUS: .*\)\s+(.*)/) { local($tmp) = "!Slot $slot/MBUS: part $1"; $_ = ; /^\s+HW version (\S+)\s+S\/N (\S+)/ && ProcessHistory("SLOT","","","$tmp, serial $2\n") && ProcessHistory("SLOT","","","!Slot $slot/MBUS: hvers $1\n"); next; } if (/^\s+MBUS Agent Software version (.*)/) { local($sw) = $1; local($tail) = "!\n" if ($board =~ /(CLK|RP)/); ProcessHistory("SLOT","","","!Slot $slot/MBUS: software $sw\n$tail"); next; } if (/^\s+DRAM size: (\d+)/) { local($dram) = $1 / 1048576; $_ = ; /^\s+FrFab SDRAM size: (\d+)/ && ProcessHistory("SLOT","","","!Slot $slot/MBUS: $dram Mbytes DRAM, " . $1 / 1024 . " Kbytes SDRAM\n!\n"); next; } # 7200 and 3600 stuff if (/^(Slot)\s+(\d+):/ || /^\s+(WIC|VIC) Slot (\d):/) { if ($1 eq "WIC") { $WIC = "/$2"; } elsif ($1 eq "VIC") { $WIC = "/$2"; } else { $slot = $2; undef($WIC); } $_ = ; tr/\015//d; # clean up hideous 7200 format to look more like 7500 output s/Fast-ethernet on C7200 I\/O card/FE-IO/; s/ with MII or RJ45/-TX/; s/Fast-ethernet /100Base/; s/[)(]//g; /\s+(.*) port adapter,?\s+(\d+)\s+/i && ProcessHistory("SLOT","","","!Slot $slot: type $1, $2 ports\n"); # I/O controller with no interfaces /\s+(.*)\s+port adapter\s*$/i && ProcessHistory("SLOT","","","!Slot $slot: type $1, 0 ports\n"); /\s+(.*)\s+daughter card(.*)$/ && ProcessHistory("SLOT","","","!Slot $slot$WIC: type $1$2\n"); /\s+(FT1)$/ && ProcessHistory("SLOT","","","!Slot $slot$WIC: type $1\n"); next; } /revision\s+(\S+).*revision\s+(\S+)/ && ProcessHistory("SLOT","","","!Slot $slot$WIC: hvers $1 rev $2\n") && next; /number\s+(\S+)\s+Part number\s+(\S+)/ && ProcessHistory("SLOT","","","!Slot $slot$WIC: part $2, serial $1\n!\n") && next; } return(0); } # This routine parses "show inventory". sub ShowInventory { print STDERR " In ShowInventory: $_" if ($debug); while () { tr/\015//d; return if (/^\s*\^$/); last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); return(-1) if (/command authorization failed/i); return(1) if (/Unknown command/); # the pager can not be disabled per-session on the PIX s/^<-+ More -+>\s*//; chomp; # split PID/VID line if (/^(NAME: ".*,) (DESCR: .*)/) { ProcessHistory("INVENTORY","","", sprintf("!%-30s%s\n", $1, $2)); next; } if (/^(PID: \w?) *, (VID: .*), (SN: .*)$/) { ProcessHistory("INVENTORY","","", "!$1\n!$2\n!$3\n"); next; } ProcessHistory("INVENTORY","","","!$_"); } ProcessHistory("INVENTORY","","",""); return(0); } # This routine parses "show module" sub ShowModule { my($slot); print STDERR " In ShowModule: $_" if ($debug); OUTER:while () { tr/\015//d; last if(/^$prompt/); # stuff module type into %module if (/^Mod\s+Slot\s+Ports/) { ; while () { tr/\015//d; last if (/^\s*$/); last OUTER if (/^$prompt/); if (/^Module .*mismatch/) { ProcessHistory("MODWARN","","","!\n! WARNING: $_"); while () { tr/\015//d; last OUTER if (/^\s*$/); last if (/^\d/); ProcessHistory("MODWARN","","","! $_"); } } if (/^(\d+)\s+\d+\s+\d+\s+(.*)\s+\S+\s+\S+\s*$/) { $modules{$1}->{type} = $2; $modules{$1}->{type} =~ s/\s{2,}.*$//; } } next; } # one does it one way... pita if (/^Mod\s+Module-Name\s+Ports/) { ; #my($slot); while () { tr/\015//d; last if (/^\s*$/); last OUTER if (/^$prompt/); if (/^(\d+)\s+(.+\s+)?\d+\s+(.*)\s+\S+\s+(\S+)\s+\S+\s*$/) { $modules{$1}->{serial} = $4; $modules{$1}->{type} = $3; #$modules{$1}->{type} =~ s/\s{2,}.*$//; $modules{$1}->{type} =~ s/\s*$//; } } next; } # daughter boards if (/^Mod\s+Sub-Type/) { ; my($slot, $board); while () { tr/\015//d; last if (/^\s*$/); last OUTER if (/^$prompt/); if (/^(\d+)\s+(\S+.*\s+)?(\S+)\s+(\S+)\s+(\S+)\s*$/) { $board = 0 if ($slot != $1); $slot = $1; $modules{$1}->{daughter}->{$board}->{model} = $3; $modules{$1}->{daughter}->{$board}->{serial} = $4; $modules{$1}->{daughter}->{$board}->{Hw} = $5; $modules{$1}->{daughter}->{$board}->{type} = $2; $modules{$1}->{daughter}->{$board}->{type} =~ s/\s*$//; $board++; } } next; } } # dump the module info foreach $slot (sort numerically keys(%modules)) { my($dboards); ProcessHistory("MODS","","","!\n"); ProcessHistory("MODS","","",sprintf("!Slot $slot: type %s, %d ports\n", $modules{$slot}->{type}, $modules{$slot}->{ports})); delete($modules{$slot}->{ports}); delete($modules{$slot}->{type}); my($model) = sprintf("!Slot $slot: part %s, serial %s\n", $modules{$slot}->{model}, $modules{$slot}->{serial}); delete($modules{$slot}->{model}); delete($modules{$slot}->{serial}); # deal with daughter boards before slot versions if (defined($modules{$slot}->{daughter})) { my($board); foreach $board (sort numerically keys(%{$modules{$slot}->{daughter}})) { $dboards .= sprintf("!Slot $slot/$board: type %s\n", $modules{$slot}->{daughter}->{$board}->{type}); $dboards .= sprintf("!Slot $slot/$board: hvers %s\n", $modules{$slot}->{daughter}->{$board}->{Hw}); $dboards .= sprintf("!Slot $slot/$board: part %s, serial %s\n", $modules{$slot}->{daughter}->{$board}->{model}, $modules{$slot}->{daughter}->{$board}->{serial}); } delete($modules{$slot}->{daughter}); } my($ver); my($i) = 0; ProcessHistory("MODS","","","!Slot $slot:"); foreach $ver (sort keys(%{$modules{$slot}})) { if ($i) {ProcessHistory("MODS","","",",");} ProcessHistory("MODS","","",sprintf(" %s: %s", $ver, $modules{$slot}->{$ver})); $i++; } ProcessHistory("MODS","","","\n"); ProcessHistory("MODS","","",$model); if ($dboards) {ProcessHistory("MODS","","",$dboards);} } } # This routine processes a "show port ifindex" sub ShowPortIfindex { print STDERR " In ShowPortIfindex: $_" if ($debug); ProcessHistory("","","","!\n"); while () { tr/\015//d; last if(/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); return(1) if /^\s*\^\s*$/; return(1) if /Invalid input detected/; return(1) if /Unknown command/; return(1) if /Usage: /; ProcessHistory("","","","! $_"); } } # This routine processes a "write term {all}" sub WriteTerm { print STDERR " In WriteTerm: $_" if ($debug); if (! $found_end) { ProcessHistory("","","","!\n"); } while () { tr/\015//d; last if (/^$prompt/); last if (/^Unknown host /); # error when write term all # is not supported next if (/^\.+$/ | /^$/); return(0) if ($found_end); /Non-Volatile memory is in use/ && return(-1); # NvRAM is locked # skip the crap next if (/^This command shows non-default configurations only./i); next if (/^Use 'write terminal all' to show both default and non/i); if (/^(\.\.+$|##+$|(Building|Current) configuration)/i) { while () { tr/\015//d; next if (/^Current configuration:/i); next if (/^(\.+|[%!].*|\s*)$/); next if (/^ip add.*ipv4:/); # band-aid for 3620 12.0S last; } ProcessHistory("","","","!\n"); if (defined($config_register)) { ProcessHistory("","","","config-register $config_register\n"); } tr/\015//d; } # some versions have other crap mixed in with the bits in the # block above /^! (Last configuration|NVRAM config last)/ && next; /^#Time: / && next; # Dog gone Cool matches to process the rest of the config /^#time: / && next; # kill time: /^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 if (/^enable password / && $filter_pwds >= 1) { ProcessHistory("ENABLE","","","! $1 \n"); next; } if (/^set enablepass / && $filter_pwds >= 2) { ProcessHistory("ENABLE","","","! $1 \n"); next; } if (/^(username .*) password /) { if (/^(username .*) password / && $filter_pwds >= 1) { ProcessHistory("USER","","","! $1 password \n"); } else { ProcessHistory("USER","","","$_\n"); } next; } if (/^(set localuser user .*) password .* (privilege .*)/) { if (/^(set localuser user .*) password .* (privilege .*)/ && $filter_pwds >= 1) { ProcessHistory("","","","! $1 password $2\n"); } else { ProcessHistory("","","","$_\n"); } next; } if (/^set password / && $filter_pwds >= 2) { ProcessHistory("","","","! set password \n"); next; } if (/^(\s*)password / && $filter_pwds >= 1) { ProcessHistory("LINE-PASS","","","!$1password \n"); next; } if (/^\s*neighbor (\S*) password / && $filter_pwds >= 1) { ProcessHistory("","","","! neighbor $1 password \n"); next; } if (/^(ip ftp password) / && $filter_pwds >= 1) { ProcessHistory("","","","!$1 \n"); next; } if (/^( ip ospf authentication-key) / && $filter_pwds >= 1) { ProcessHistory("","","","!$1 \n"); next; } if (/^( ip ospf message-digest-key \d+ md5) / && $filter_pwds >= 1) { ProcessHistory("","","","!$1 \n"); next; } /fair-queue individual-limit/ && next; /^set port security \d+\/\d+ \S+-\S+\-/ && next; # sort ip explicit-paths. if (/^ip explicit-path name (\S+)/) { my($key) = $1; my($expath) = $_; while () { tr/\015//d; last if (/^$prompt/); last if (/^$prompt/ || ! /^(ip explicit-path name |[ !])/); if (/^ip explicit-path name (\S+)/) { ProcessHistory("EXPATH","keysort","$key","$expath"); $key = $1; $expath = $_; } else { $expath .= $_; } } ProcessHistory("EXPATH","keysort","$key","$expath"); } # sort route-maps if (/^route-map (\S+)/) { my($key) = $1; my($routemap) = $_; while () { tr/\015//d; last if (/^$prompt/ || ! /^(route-map |[ !])/); if (/^route-map (\S+)/) { ProcessHistory("ROUTEMAP","keysort","$key","$routemap"); $key = $1; $routemap = $_; } else { $routemap .= $_; } } ProcessHistory("ROUTEMAP","keysort","$key","$routemap"); } # filter out any RCS/CVS tags to avoid confusing local CVS storage s/\$(Revision|Id):/ $1:/; # order access-lists /^access-list\s+(\d\d?)\s+(\S+)\s+(\S+)/ && ProcessHistory("ACL $1 $2","$aclsort","$3","$_") && next; # order extended access-lists /^access-list\s+(\d\d\d)\s+(\S+)\s+ip\s+host\s+(\S+)/ && ProcessHistory("EACL $1 $2","$aclsort","$3","$_") && next; /^access-list\s+(\d\d\d)\s+(\S+)\s+ip\s+(\d\S+)/ && ProcessHistory("EACL $1 $2","$aclsort","$3","$_") && next; /^access-list\s+(\d\d\d)\s+(\S+)\s+ip\s+any/ && ProcessHistory("EACL $1 $2","$aclsort","0.0.0.0","$_") && next; # order arp lists /^set arp\s+(\d+\.\d+\.\d+\.\d+)\s+/ && ProcessHistory("ARP","$aclsort","$1","$_") && next; /^ip prefix-list\s+(\S+)\s+seq\s+(\d+)\s+(permit|deny)\s+(\d\S+)(\/.*)$/ && ProcessHistory("PACL $1 $3","$aclsort","$4","ip prefix-list $1 $3 $4$5\n") && next; # order logging statements /^set logging server (\d+\.\d+\.\d+\.\d+)/ && ProcessHistory("LOGGING","ipsort","$1","$_") && next; # order/prune snmp-server host statements # we only prune lines of the form # snmp-server host a.b.c.d if (/^set snmp trap (\d+\.\d+\.\d+\.\d+) /) { if ($filter_commstr) { ProcessHistory("SNMPSERVERHOST","ipsort","$1","!set snmp trap $1 \n"); } else { ProcessHistory("SNMPSERVERHOST","ipsort","$1","$_"); } next; } if (/^(set snmp community) (\S+)\s+(\S+)/) { if ($filter_commstr) { ProcessHistory("SNMPSERVERCOMM","keysort","$_","!$1 $2 \n"); } else { ProcessHistory("SNMPSERVERCOMM","keysort","$_","$_") } next; } # order tacacs server statements /^set (tacacs) key / && ProcessHistory("","","","!set $1 key \n") && next; /^set tacacs server (\d+\.\d+\.\d+\.\d+)/ && ProcessHistory("TAC","ipsort","$1","$_") && next; # order clns host statements /^clns host \S+ (\S+)/ && ProcessHistory("CLNS","keysort","$1","$_") && next; # order alias statements /^alias / && ProcessHistory("ALIAS","keysort","$_","$_") && next; # delete ntp auth password if (/^(ntp authentication-key \d+ md5) / && $filter_pwds >= 2) { ProcessHistory("","","","!$1 \n"); next; } # order ntp peers/servers if (/^ntp (server|peer) (\d+)\.(\d+)\.(\d+)\.(\d+)/) { $sortkey = sprintf("$1 %03d%03d%03d%03d",$2,$3,$4,$5); ProcessHistory("NTP","keysort",$sortkey,"$_"); next; } # order ip host line statements /^ip host line(\d+)/ && ProcessHistory("IPHOST","numsort","$1","$_") && next; # order ip nat source static statements /^ip nat (\S+) source static (\S+)/ && ProcessHistory("IP NAT $1","ipsort","$2","$_") && next; # order atm map-list statements /^\s+ip\s+(\d+\.\d+\.\d+\.\d+)\s+atm-vc/ && ProcessHistory("ATM map-list","ipsort","$1","$_") && next; # order ip rcmd lines /^ip rcmd/ && ProcessHistory("RCMD","keysort","$_","$_") && next; ProcessHistory("","","","$_"); # end of config if (/^end$/) { $found_end = 1; return(1); } } return(0); } # dummy function sub DoNothing {print STDOUT;} # Main @commandtable = ( {'show version' => 'ShowVersion'}, {'show boot' => 'ShowBoot'}, {'show flash' => 'ShowFlash'}, {'dir bootflash:' => 'DirSlotN'}, {'dir slot0:' => 'DirSlotN'}, {'dir slot1:' => 'DirSlotN'}, {'dir sup-bootflash:' => 'DirSlotN'}, {'dir sup-microcode:' => 'DirSlotN'}, {'show module' => 'ShowModule'}, {'show inventory raw' => 'ShowInventory'}, {'show port ifindex' => 'ShowPortIfindex'}, {'write term all' => 'WriteTerm'}, {'write term' => 'WriteTerm'}, {'show running-config' => 'WriteTerm'} ); # 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("|", map quotemeta($_), @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 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 clogin -t $timeo -c\"$cisco_cmds\" $host\n" if ($debug); print STDOUT "executing clogin -t $timeo -c\"$cisco_cmds\" $host\n" if ($log); if (defined($ENV{NOPIPE}) && $ENV{NOPIPE} =~ /^YES/i) { system "clogin -t $timeo -c \"$cisco_cmds\" $host $host.raw 2>&1" || die "clogin failed for $host: $!\n"; open(INPUT, "< $host.raw") || die "clogin failed for $host: $!\n"; } else { open(INPUT,"clogin -t $timeo -c \"$cisco_cmds\" $host ) { tr/\015//d; if (/> \(enable\) ?exit(?:$|Connection)/) { $clean_run=1; last; } if (/^Error:/) { print STDOUT ("$host clogin error: $_"); print STDERR ("$host clogin error: $_") if ($debug); $clean_run=0; last; } while (/> \(enable\)\s*($cmds_regexp)\s*$/) { $cmd = $1; 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; } $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}) && $ENV{NOPIPE} =~ /^YES/i) { 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); } rancid-2.3.8/bin/clogin.in100644 015615 000000 00000064740 11712067106 0011045#! @EXPECT_PATH@ -- ## ## $Id: clogin.in 2376 2012-01-31 22:42:14Z heas $ ## ## @PACKAGE@ @VERSION@ ## Copyright (c) @COPYYEARS@ by Terrapin Communications, Inc. ## All rights reserved. ## ## This code is derived from software contributed to and maintained by ## Terrapin Communications, Inc. by Henry Kilmer, John Heasley, Andrew Partan, ## Pete Whiting, Austin Schutz, and Andrew Fort. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions ## are met: ## 1. Redistributions of source code must retain the above copyright ## notice, this list of conditions and the following disclaimer. ## 2. Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## 3. All advertising materials mentioning features or use of this software ## must display the following acknowledgement: ## This product includes software developed by Terrapin Communications, ## Inc. and its contributors for RANCID. ## 4. Neither the name of Terrapin Communications, Inc. nor the names of its ## contributors may be used to endorse or promote products derived from ## this software without specific prior written permission. ## 5. It is requested that non-binding fixes and modifications be contributed ## back to Terrapin Communications, Inc. ## ## THIS SOFTWARE IS PROVIDED BY Terrapin Communications, INC. AND CONTRIBUTORS ## ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ## TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COMPANY OR CONTRIBUTORS ## BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ## CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ## SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ## INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ## CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ## ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ## POSSIBILITY OF SUCH DAMAGE. # # The expect login scripts were based on Erik Sherk's gwtn, by permission. # # clogin - Cisco login # # Most options are intuitive for logging into a Cisco router. # The default is to enable (thus -noenable). Some folks have # setup tacacs to have a user login at priv-lvl = 15 (enabled) # so the -autoenable flag was added for this case (don't go through # the process of enabling and the prompt will be the "#" prompt. # The default username password is the same as the vty password. # # Usage line set usage "Usage: $argv0 \[-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\] 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 avenable 1 # The default is that you login non-enabled (tacacs can have you login already # enabled) set avautoenable 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 set do_enapasswd 1 # Save config, if prompted set do_saveconfig 0 # Sometimes routers take awhile to answer (the default is 10 sec) set timeoutdflt 45 # set send_human {.4 .4 .7 .3 5} # 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) } elseif {[info exists env(LOGNAME)]} { set default_user $env(LOGNAME) } 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 "\nError: could not exec id: $reason\n" exit 1 } regexp {\(([^)]*)} "$reason" junk default_user } if {[info exists env(CLOGINRC)]} { set password_file $env(CLOGINRC) } # Process the command line for {set i 0} {$i < $argc} {incr i} { set arg [lindex $argv $i] switch -glob -- $arg { # Expect debug mode -d* { exp_internal 1 # Username } -u* { if {! [regexp .\[uU\](.+) $arg ignore user]} { incr i set username [lindex $argv $i] } # VTY Password } -p* { if {! [regexp .\[pP\](.+) $arg ignore userpasswd]} { incr i set userpasswd [lindex $argv $i] } set do_passwd 0 # ssh passphrase } -r* { if {! [regexp .\[rR\](.+) $arg ignore passphrase]} { incr i set vapassphrase [lindex $argv $i] } # VTY Password } -v* { if {! [regexp .\[vV\](.+) $arg ignore passwd]} { incr i set passwd [lindex $argv $i] } set do_passwd 0 # Version string } -V* { send_user "@PACKAGE@ @VERSION@\n" exit 0 # Enable Username } -w* { if {! [regexp .\[wW\](.+) $arg ignore enauser]} { incr i set enausername [lindex $argv $i] } # Environment variable to pass to -s scripts } -E* { if {[regexp .\[E\](.+)=(.+) $arg ignore varname varvalue]} { set E$varname $varvalue } else { send_user "\nError: invalid format for -E in $arg\n" exit 1 } # Enable Password } -e* { if {! [regexp .\[e\](.+) $arg ignore enapasswd]} { incr i set enapasswd [lindex $argv $i] } set do_enapasswd 0 # Command to run. } -c* { if {! [regexp .\[cC\](.+) $arg ignore command]} { incr i set command [lindex $argv $i] } set do_command 1 # Expect script to run. } -s* { if {! [regexp .\[sS\](.+) $arg ignore sfile]} { incr i set sfile [lindex $argv $i] } if { ! [file readable $sfile] } { send_user "\nError: Can't read $sfile\n" exit 1 } set do_script 1 # save config on exit } -S* { set do_saveconfig 1 # 'ssh -c' cypher type } -y* { if {! [regexp .\[eE\](.+) $arg ignore cypher]} { incr i set cypher [lindex $argv $i] } # alternate cloginrc file } -f* { if {! [regexp .\[fF\](.+) $arg ignore password_file]} { incr i set password_file [lindex $argv $i] } # Timeout } -t* { if {! [regexp .\[tT\](.+) $arg ignore timeout]} { incr i set timeoutdflt [lindex $argv $i] } # Command file } -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 { set avenable 0 # Does tacacs automatically enable us? } -autoenable { set avautoenable 1 set avenable 0 } -* { send_user "\nError: Unknown argument! $arg\n" send_user $usage exit 1 } default { break } } } # Process routers...no routers listed is an error. if { $i == $argc } { send_user "\nError: $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 "\nError: password file ($password_file) does not exist\n" exit 1 } file stat $password_file fileinfo if { [expr ($fileinfo(mode) & 007)] != 0000 } { send_user "\nError: $password_file must not be world readable/writable\n" exit 1 } if [catch {source $password_file} reason] { send_user "\nError: $reason\n" exit 1 } } # Log into the router. # returns: 0 on success, 1 on failure, -1 if rsh was used successfully proc login { router user userpswd passwd enapasswd cmethod cyphertype identfile } { global command spawn_id in_proc do_command do_script platform passphrase global prompt prompt_match u_prompt p_prompt e_prompt sshcmd 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] { incr progs -1 if [string match "telnet*" $prog] { regexp {telnet(:([^[:space:]]+))*} $prog methcmd 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" return 1 } } elseif [string match "ssh*" $prog] { # ssh to the router & try to login with or without an identfile. regexp {ssh(:([^[:space:]]+))*} $prog methcmd suffix port set cmd $sshcmd if {"$port" != ""} { set cmd "$cmd -p $port" } if {"$identfile" != ""} { set cmd "$cmd -i $identfile" } set retval [catch {eval spawn [split "$cmd -c $cyphertype -x -l $user $router" { }]} reason] if { $retval } { send_user "\nError: $cmd failed: $reason\n" return 1 } } elseif ![string compare $prog "rsh"] { if { ! $do_command } { if { [llength $cmethod] == 1 } { send_user "\nError: rsh is an invalid method for -x and " send_user "interactive logins\n" } if { $progs == 0 } { return 1 } continue; } set commands [split $command \;] set num_commands [llength $commands] set rshfail 0 for {set i 0} {$i < $num_commands && !$rshfail} { incr i} { log_user 0 set retval [catch {spawn rsh $user@$router [lindex $commands $i] } reason] if { $retval } { send_user "\nError: rsh failed: $reason\n" log_user 1; return 1 } send_user "$router# [lindex $commands $i]\n" # rcmd does not get a pager and no prompts, so we just have to # look for failures & lines. expect { "Connection refused" { catch {close}; catch {wait}; send_user "\nError: Connection\ Refused ($prog): $router\n" set rshfail 1 } -re "(Connection closed by|Connection to \[^\n\r]+ closed)" { catch {close}; catch {wait}; send_user "\nError: Connection\ closed ($prog): $router\n" set rshfail 1 } "Host is unreachable" { catch {close}; catch {wait}; send_user "\nError: Host Unreachable:\ $router\n" set rshfail 1 } "No address associated with" { catch {close}; catch {wait}; send_user "\nError: Unknown host\ $router\n" set rshfail 1 } -re "\b+" { exp_continue } -re "\[\n\r]+" { send_user -- "$expect_out(buffer)" exp_continue } timeout { catch {close}; catch {wait}; send_user "\nError: TIMEOUT reached\n" set rshfail 1 } eof { catch {close}; catch {wait}; } } log_user 1 } if { $rshfail } { if { !$progs } { return 1 } else { continue } } # fake the end of the session for rancid. send_user "$router# exit\n" # return rsh "success" return -1 } else { send_user "\nError: unknown connection method: $prog\n" return 1 } sleep 0.3 # This helps cleanup each expect clause. expect_after { timeout { send_user "\nError: TIMEOUT reached\n" catch {close}; catch {wait}; if { $in_proc} { return 1 } else { continue } } eof { send_user "\nError: EOF received\n" catch {close}; catch {wait}; if { $in_proc} { return 1 } else { continue } } } # Here we get a little tricky. There are several possibilities: # the router can ask for a username and passwd and then # talk to the TACACS server to authenticate you, or if the # TACACS server is not working, then it will use the enable # passwd. Or, the router might not have TACACS turned on, # then it will just send the passwd. # if telnet fails with connection refused, try ssh expect { -re "^<-+ More -+>\[^\n\r]*" { # ASA will use the pager for long banners send " "; exp_continue } -re "(Connection refused|Secure connection \[^\n\r]+ refused)" { catch {close}; catch {wait}; if !$progs { send_user "\nError: Connection Refused ($prog): $router\n" return 1 } } -re "(Connection closed by|Connection to \[^\n\r]+ closed)" { catch {close}; catch {wait}; if !$progs { send_user "\nError: Connection closed ($prog): $router\n" return 1 } } eof { send_user "\nError: Couldn't login: $router\n"; wait; return 1 } -nocase "unknown host\r" { send_user "\nError: Unknown host $router\n"; catch {close}; catch {wait}; return 1 } "Host is unreachable" { send_user "\nError: Host Unreachable: $router\n"; catch {close}; catch {wait}; return 1 } "No address associated with name" { send_user "\nError: Unknown host $router\n"; catch {close}; catch {wait}; return 1 } -re "(Host key not found |The authenticity of host .* be established).* \\(yes/no\\)\\?" { send "yes\r" send_user "\nHost $router added to the list of known hosts.\n" exp_continue } -re "HOST IDENTIFICATION HAS CHANGED.* \\(yes/no\\)\\?" { send "no\r" send_user "\nError: The host key for $router has changed. Update the SSH known_hosts file accordingly.\n" catch {close}; catch {wait}; return 1 } -re "HOST IDENTIFICATION HAS CHANGED\[^\n\r]+" { send_user "\nError: The host key for $router has changed. Update the SSH known_hosts file accordingly.\n" return 1 } -re "Offending key for .* \\(yes/no\\)\\?" { send "no\r" send_user "\nError: host key mismatch for $router. Update the SSH known_hosts file accordingly.\n" catch {close}; catch {wait}; return 1 } -re "(denied|Sorry)" { send_user "\nError: Check your passwd for $router\n" catch {close}; catch {wait}; return 1 } "Login failed" { send_user "\nError: Check your passwd for $router\n" catch {close}; catch {wait}; return 1 } -re "% (Bad passwords|Authentication failed)" { send_user "\nError: Check your passwd for $router\n" catch {close}; catch {wait}; return 1 } "Press any key to continue" { # send_user "Pressing the ANY key\n" send "\r" exp_continue } -re "Enter Selection: " { # Catalyst 1900s have some lame menu. Enter # K to reach a command-line. send "K\r" exp_continue } -re "Last login:" { exp_continue } -re "@\[^\r\n]+ $p_prompt" { # ssh pwd prompt sleep 1 send -- "$userpswd\r" exp_continue } -re "Enter passphrase.*: " { # sleep briefly to allow time for stty -echo sleep .3 send -- "$passphrase\r" exp_continue } -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 "$prompt" { set prompt_match $expect_out(0,string); break; } "Login invalid" { send_user "\nError: Invalid login: $router\n"; catch {close}; catch {wait}; return 1 } } } set in_proc 0 return 0 } # Enable proc do_enable { enauser enapasswd } { global do_saveconfig in_proc global prompt u_prompt e_prompt set in_proc 1 send "enable\r" expect { -re "$u_prompt" { send -- "$enauser\r"; exp_continue} -re "$e_prompt" { send -- "$enapasswd\r"; exp_continue} "#" { set prompt "#" } "(enable)" { set prompt "> \\(enable\\) " } -re "(denied|Sorry|Incorrect)" { # % Access denied - from local auth and poss. others send_user "\nError: Check your Enable passwd\n"; return 1 } "% Error in authentication" { send_user "\nError: Check your Enable passwd\n" return 1 } "% Bad passwords" { send_user "\nError: Check your Enable passwd\n" return 1 } } # We set the prompt variable (above) so script files don't need # to know what it is. set in_proc 0 return 0 } # Run commands given on the command line. proc run_commands { prompt command } { global do_saveconfig in_proc platform set in_proc 1 # If the prompt is (enable), then we are on a switch and the # command is "set length 0"; otherwise its "terminal length 0". # skip if its an extreme (since the pager can not be disabled on a # per-vty basis). if { [string compare "extreme" "$platform"] } { # match cisco config mode prompts too, such as router(config-if)#, # but catalyst does not change in this fashion. regsub -all {^(.{1,11}).*([#>])$} $prompt {\1([^#>\r\n]+)?[#>](\\([^)\\r\\n]+\\))?} reprompt } else { set reprompt $prompt } # this is the only way i see to get rid of more prompts in o/p..grrrrr log_user 0 set commands [split $command \;] set num_commands [llength $commands] # the pager can not be turned off on the PIX, so we have to look # for the "More" prompt. the extreme is equally obnoxious in pre-12.3 XOS, # with a global switch in the config. for {set i 0} {$i < $num_commands} { incr i} { send -- "[subst -nocommands [lindex $commands $i]]\r" expect { -re "\b+" { exp_continue } -re "^\[^\n\r *]*$reprompt" { send_user -- "$expect_out(buffer)" } -re "^\[^\n\r]*$reprompt." { send_user -- "$expect_out(buffer)" exp_continue } -re "^--More--\[\r\n]+" { # specific match c1900 pager send " " exp_continue } -re "\[^\r\n]*\[\n\r]+" { send_user -- "$expect_out(buffer)" exp_continue } -re "\[^\r\n]*Press to cont\[^\r\n]*" { send " " # bloody ^[[2K after " " expect { -re "^\[^\r\n]*\r" {} } exp_continue } -re "^ *--More--\[^\n\r]*" { send " " exp_continue } -re "^<-+ More -+>\[^\n\r]*" { send_user -- "$expect_out(buffer)" send " " exp_continue } } } log_user 1 if { [string compare "extreme" "$platform"] } { send -h "exit\r" } else { send -h "quit\r" } expect { -re "^\[^\n\r *]*$reprompt" { # the Cisco CE and Jnx ERX # return to non-enabled mode # on exit in enabled mode. send -h "exit\r" exp_continue; } "The system has unsaved changes" { # Force10 SFTOS if {$do_saveconfig} { catch {send "y\r"} } else { catch {send "n\r"} } exp_continue } "Would you like to save them now" { # Force10 if {$do_saveconfig} { catch {send "y\r"} } else { catch {send "n\r"} } exp_continue } -re "(Profile|Configuration) changes have occurred.*" { # Cisco CSS if {$do_saveconfig} { catch {send "y\r"} } else { catch {send "n\r"} } exp_continue } "Do you wish to save your configuration changes" { if {$do_saveconfig} { catch {send "y\r"} } else { catch {send "n\r"} } exp_continue } -re "\[\n\r]+" { exp_continue } timeout { catch {close}; catch {wait}; 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 set exitval 0 set prompt_match "" set enable 0 foreach router [lrange $argv $i end] { set router [string tolower $router] # attempt at platform switching. set platform "" send_user -- "$router\n" # device timeout set timeout [find timeout $router] if { [llength $timeout] == 0 } { set timeout $timeoutdflt } # Default prompt. set prompt "(>|#| \\(enable\\))" # look for noenable option in .cloginrc if { [find noenable $router] == "1" } { set enable 0 } # Figure out passwords if { $do_passwd || $do_enapasswd } { set pswd [find password $router] if { [llength $pswd] == 0 } { send_user -- "\nError: no password for $router in $password_file.\n" continue } if { $enable && $do_enapasswd && $autoenable == 0 && [llength $pswd] < 2 } { send_user -- "\nError: no enable password for $router in $password_file.\n" continue } set passwd [join [lindex $pswd 0] ""] set enapasswd [join [lindex $pswd 1] ""] } else { set passwd $userpasswd set enapasswd $enapasswd } # Figure out username if {[info exists username]} { # command line username set ruser $username } else { set ruser [join [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 [join [find userpassword $router] ""] if { "$userpswd" == "" } { set userpswd $passwd } } # Figure out enable username if {[info exists enausername]} { # command line enausername set enauser $enausername } else { set enauser [join [find enauser $router] ""] if { "$enauser" == "" } { set enauser $ruser } } # Figure out prompts set u_prompt [find userprompt $router] if { "$u_prompt" == "" } { set u_prompt "(Username|Login|login|user name|User):" } else { set u_prompt [join [lindex $u_prompt 0] ""] } set p_prompt [find passprompt $router] if { "$p_prompt" == "" } { set p_prompt "(\[Pp]assword|passwd|Enter password for \[^ :]+):" } else { set p_prompt [join [lindex $p_prompt 0] ""] } set e_prompt [find enableprompt $router] if { "$e_prompt" == "" } { set e_prompt "\[Pp]assword:" } else { set e_prompt [join [lindex $e_prompt 0] ""] } # Figure out identity file to use set identfile [join [lindex [find identity $router] 0] ""] # Figure out passphrase to use if {[info exists avpassphrase]} { set passphrase $avpassphrase } else { set passphrase [join [lindex [find passphrase $router] 0] ""] } if { ! [string length "$passphrase"]} { set passphrase $passwd } # 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}} } # Figure out the SSH executable name set sshcmd [join [lindex [find sshcmd $router] 0] ""] if { "$sshcmd" == "" } { set sshcmd {ssh} } # Login to the router if {[login $router $ruser $userpswd $passwd $enapasswd $cmethod $cyphertype $identfile]} { incr exitval # if login failed or rsh was unsuccessful, move on to the next device continue } # Figure out the prompt. if { [regexp -- "(#| \\(enable\\))" $prompt_match junk] == 1 } { set enable 0 } else { if { $avenable == 0 } { set enable 0 } else { set ne [find noenable $router] set ae [find autoenable $router] if { "$ne" == "1" || "$ae" == "1" || $avautoenable } { set enable 0 } else { set enable 1 } } } if { $enable } { if {[do_enable $enauser $enapasswd]} { if { $do_command || $do_script } { incr exitval catch {close}; catch {wait}; continue } } } # we are logged in, now figure out the full prompt send "\r" expect { -re "\[\r\n]+" { exp_continue; } -re "^(.+\[:.])1 ($prompt)" { # stoopid extreme cmd-line numbers and # prompt based on state of config changes, # which may have an * at the beginning. set junk $expect_out(1,string) regsub -all "^\\\* " $expect_out(1,string) {} junk regsub -all "\[\]\[\(\)]" $junk {\\&} junk; set prompt ".? ?$junk\[0-9]+ $expect_out(2,string)"; set platform "extreme" } -re "^.+$prompt" { set junk $expect_out(0,string); regsub -all "\[\]\[\(\)]" $junk {\\&} prompt; } } if { $do_command || $do_script } { if { [ string compare "extreme" "$platform" ] } { # If the prompt is (enable), then we are on a switch and the # command is "set length 0"; otherwise its "terminal length 0". if [regexp -- ".*> .*enable" "$prompt"] { send "set length 0\r" expect -re $prompt {} send "set width 132\r" expect -re $prompt {} send "set logging session disable\r" } else { send "terminal length 0\r" expect -re $prompt {} send "terminal width 132\r" } expect -re $prompt {} } else { send "disable clipaging\r" expect -re $prompt {} } } if { $do_command } { if {[run_commands $prompt $command]} { incr exitval continue } } elseif { $do_script } { source $sfile catch {close}; } else { label $router log_user 1 interact } # End of for each router catch {wait}; sleep 0.3 } exit $exitval rancid-2.3.8/bin/control_rancid.in100644 015615 000000 00000033636 11512664515 0012577#! /bin/sh ## ## $Id: control_rancid.in 2270 2010-12-09 01:21:32Z heas $ ## ## @PACKAGE@ @VERSION@ ## Copyright (c) 1997-2008 by Terrapin Communications, Inc. ## All rights reserved. ## ## This code is derived from software contributed to and maintained by ## Terrapin Communications, Inc. by Henry Kilmer, John Heasley, Andrew Partan, ## Pete Whiting, Austin Schutz, and Andrew Fort. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions ## are met: ## 1. Redistributions of source code must retain the above copyright ## notice, this list of conditions and the following disclaimer. ## 2. Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## 3. All advertising materials mentioning features or use of this software ## must display the following acknowledgement: ## This product includes software developed by Terrapin Communications, ## Inc. and its contributors for RANCID. ## 4. Neither the name of Terrapin Communications, Inc. nor the names of its ## contributors may be used to endorse or promote products derived from ## this software without specific prior written permission. ## 5. It is requested that non-binding fixes and modifications be contributed ## back to Terrapin Communications, Inc. ## ## THIS SOFTWARE IS PROVIDED BY Terrapin Communications, INC. AND CONTRIBUTORS ## ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ## TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COMPANY OR CONTRIBUTORS ## BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ## CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ## SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ## INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ## CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ## ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ## POSSIBILITY OF SUCH DAMAGE. # # control_rancid $GROUP # # print a usage message to stderr pr_usage() { echo "usage: $0 [-V] [-r device_name] [-m mail rcpt] group" >&2; } # command-line options # -V print version string # -m # -r alt_mailrcpt=0 if [ $# -ge 1 ] ; then while [ 1 ] ; do case $1 in -V) echo "@PACKAGE@ @VERSION@" exit 0 ;; -m) shift # next arg is the mail recipient alt_mailrcpt=1 if [ -z "$mailrcpt" ] ; then mailrcpt="$1" else mailrcpt="$mailrcpt,$1" fi shift ;; -r) shift # next arg is the device name device="$1" shift ;; --) shift; break; ;; -h) pr_usage exit 0 ;; -*) echo "unknown option: $1" >&2 pr_usage exit 1 ;; *) break; ;; esac done fi # Must specify a group on which to run rancid if [ $# -lt 1 ] ; then echo 'must specify group'; exit 1 else GROUP=$1 fi DIR=$BASEDIR/$GROUP TMP=${TMPDIR:=/tmp}/rancid.$GROUP.$$ trap 'rm -fr $TMP;' 1 2 15 # disable noclobber unset noclobber > /dev/null 2>&1 # RCS system RCSSYS=${RCSSYS:=cvs}; if [ $RCSSYS != "cvs" -a $RCSSYS != "svn" ] ; then echo "$RCSSYS is not a valid value for RCSSYS." exit 1 fi # the receipient(s) of diffs & mail options mailrcpt=${mailrcpt:-"@MAILPLUS@${GROUP}${MAILDOMAIN}"}; export mailrcpt adminmailrcpt=${adminmailrcpt:-"@ADMINMAILPLUS@${GROUP}${MAILDOMAIN}"}; export adminmailrcpt set | grep MAILHEADERS= > /dev/null 2>&1 if [ $? -ne 0 ] ; then MAILHEADERS="Precedence: bulk\n"; export MAILHEADERS fi # Number of things par should run in parallel. PAR_COUNT=${PAR_COUNT:-5} # Number of times failed collections should be retried. Minimum 1. MAX_ROUNDS=${MAX_ROUNDS:-4} if [ $MAX_ROUNDS -lt 1 ] ; then echo "Error: MAX_ROUNDS must be at least 1." MAX_ROUNDS=1 fi # Bail if we do not have the necessary info to run if [ ! -d $DIR ] ; then echo "$DIR does not exist." echo "Run bin/rancid-cvs $GROUP to make all of the needed directories." ( echo "To: $adminmailrcpt" echo "Subject: no $GROUP directory" echo "$MAILHEADERS" | awk '{L = "";LN = $0;while (LN ~ /\\n/) { I = index(LN,"\\n");L = L substr(LN,0,I-1) "\n";LN = substr(LN,I+2,length(LN)-I-1);}print L LN;}' echo "" echo "$DIR does not exist." echo "Run bin/rancid-cvs $GROUP to make all of the needed directories." ) | sendmail -t exit 1 fi cd $DIR # create a .cvsignore if [ ! -f .cvsignore ] ; then rm -f .cvsignore cat >.cvsignore < $TMP 2>&1 grep "^C" $TMP > /dev/null if [ $? -eq 0 ] ; then echo "There were $RCSSYS conflicts during update." echo "" cat $TMP rm -f $TMP exit 1 fi rm -f $TMP if [ ! -f $DIR/router.db ] ; then echo "$DIR/router.db does not exist." ( echo "To: $adminmailrcpt" echo "Subject: no $GROUP/router.db file" echo "$MAILHEADERS" | awk '{L = "";LN = $0;while (LN ~ /\\n/) { I = index(LN,"\\n");L = L substr(LN,0,I-1) "\n";LN = substr(LN,I+2,length(LN)-I-1);}print L LN;}' echo "" echo "$DIR/router.db does not exist." ) | sendmail -t exit 1; fi # generate the list of all, up, & down routers cd $DIR trap 'rm -fr routers.db routers.all.new routers.down.new routers.up.new \ routers.mail routers.added routers.deleted $TMP;' 1 2 15 sed -e '/^#/d' -e 's/^ *//' -e 's/ *$//' -e 's/ *: */:/g' router.db | tr '[A-Z]' '[a-z]' | sort -u > routers.db cut -d: -f1,2 routers.db > routers.all.new if [ ! -f routers.all ] ; then touch routers.all; fi @DIFF_CMD@ routers.all routers.all.new > /dev/null 2>&1; RALL=$? @PERLV@ -F: -ane '{$F[2] =~ s/\s*\$//; ($F[0] =~ tr@A-Z@a-z@, print $_) if ($F[2] !~ /^up$/i);}' routers.db > routers.down.new if [ ! -f routers.down ] ; then touch routers.down; fi @DIFF_CMD@ routers.down routers.down.new > /dev/null 2>&1; RDOWN=$? @PERLV@ -F: -ane '{$F[2] =~ s/\s*\$//; ($F[0] =~ tr@A-Z@a-z@, print "$F[0]:$F[1]\n") if ($F[2] =~ /^up$/i);}' routers.db > routers.up.new if [ ! -f routers.up ] ; then touch routers.up; fi @DIFF_CMD@ routers.up routers.up.new > /dev/null 2>&1; RUP=$? if [ $RALL -ne 0 -o $RDOWN -ne 0 -o $RUP -ne 0 ] ; then ( if [ $RUP -ne 0 ] ; then if [ ! -s routers.up ] ; then echo Routers changed to up: sed -e 's/^/ /' routers.up.new echo else WCUP=`comm -13 routers.up routers.up.new | wc -l | \ sed -e 's/^ *\([^ ]*\)/\1/'` if [ $WCUP -gt 0 ] ; then echo Routers changed to up: comm -13 routers.up routers.up.new | sed -e 's/^/ /' echo fi fi fi if [ $RDOWN -ne 0 ] ; then if [ ! -s routers.down ] ; then echo Routers changed to down: sed -e 's/^/ /' routers.down.new echo else WCDOWN=`comm -13 routers.down routers.down.new | wc -l | \ sed -e 's/^ *\([^ ]*\)/\1/'` if [ $WCDOWN -eq 1 ] ; then echo Routers changed to down: comm -13 routers.down routers.down.new | \ sed -e 's/^/ /' echo fi fi fi if [ $RALL -eq 1 ] ; then comm -13 routers.all routers.all.new | sed -e 's/^/ /' \ > routers.added comm -23 routers.all routers.all.new | sed -e 's/^/ /' \ > routers.deleted WCADDED=`wc -l routers.added | sed -e 's/^ *\([^ ]*\) .*$/\1/'` WCDELETED=`wc -l routers.deleted | sed -e 's/^ *\([^ ]*\) .*$/\1/'` if [ $WCADDED -gt 0 ] ; then echo Added routers: cat routers.added echo fi if [ $WCDELETED -gt 0 ] ; then echo Deleted routers: cat routers.deleted echo fi rm -f routers.added routers.deleted fi ) > routers.mail if [ -s routers.mail ] ; then ( echo "To: $adminmailrcpt" echo "Subject: changes in $GROUP routers" echo "$MAILHEADERS" | awk '{L = "";LN = $0;while (LN ~ /\\n/) { I = index(LN,"\\n");L = L substr(LN,0,I-1) "\n";LN = substr(LN,I+2,length(LN)-I-1);}print L LN;}' echo "" cat routers.mail ) | sendmail -t fi rm -f routers.mail cd $DIR/configs # Add new routers to the CVS structure. for router in `comm -13 $DIR/routers.up $DIR/routers.up.new` do OFS=$IFS IFS=: set $router IFS=$OFS router=$1 touch $router if [ $RCSSYS = cvs ] ; then cvs add -ko $router else svn add $router fi $RCSSYS commit -m 'new router' $router echo "Added $router" done echo cd $DIR fi mv -f routers.all.new routers.all if [ $? -ne 0 ] ; then echo "Error: could not rename routers.all.new" fi mv -f routers.down.new routers.down if [ $? -ne 0 ] ; then echo "Error: could not rename routers.down.new" fi mv -f routers.up.new routers.up if [ $? -ne 0 ] ; then echo "Error: could not rename routers.up.new" fi rm -f routers.db trap 'rm -fr $TMP;' 1 2 15 cd $DIR/configs # check for 'up' routers missing in RCS. no idea how this happens to some folks for router in `cut -d: -f1 ../routers.up` ; do if [ $RCSSYS = cvs ] ; then cvs status $router | grep -i 'status: unknown' > /dev/null 2>&1 else svn status $router | grep '^?' > /dev/null 2>&1 fi if [ $? -eq 0 ] ; then touch $router if [ $RCSSYS = cvs ] ; then cvs add -ko $router else svn add $router fi echo "$RCSSYS added missing router $router" fi done echo # delete configs from RCS for routers not listed in routers.up. for router in `find . \( -name \*.new -prune -o -name CVS -prune -o -name .svn -prune \) -o -type f -print | sed -e 's/^.\///'` ; do grep -i "^$router:" ../router.db > /dev/null 2>&1 if [ $? -eq 1 ] ; then rm -f $router $RCSSYS delete $router $RCSSYS commit -m 'deleted router' $router echo "Deleted $router" fi done cd $DIR # no routers, empty list or all 'down' if [ ! -s routers.up ] then # commit router.db $RCSSYS commit -m updates router.db exit; fi # if a device (-r) was specified, see if that device is in this group if [ "X$device" != "X" ] ; then trap 'rm -fr $TMP $DIR/routers.single;' 1 2 15 devlistfile="$DIR/routers.single" grep -i "^$device:" routers.up > $devlistfile if [ $? -eq 1 ] ; then exit; fi else devlistfile="$DIR/routers.up" fi # Now we can actually try to get the configs cd $DIR/configs # The number of processes running at any given time can be # tailored to the specific installation. echo "" echo "Trying to get all of the configs." par -q -n $PAR_COUNT -c "rancid-fe {}" $devlistfile # This section will generate a list of missed routers # and try to grab them again. It will run through # $pass times. pass=$MAX_ROUNDS round=1 if [ -f $DIR/routers.up.missed ] ; then rm -f $DIR/routers.up.missed fi while [ $round -le $pass ] do for router in `cat $devlistfile` do OFS=$IFS IFS=':' set $router IFS=$OFS router=$1; mfg=$2 if [ ! -s $router.new ] then echo "$router:$mfg" >> $DIR/routers.up.missed rm -f $router.new fi done if [ -f $DIR/routers.up.missed ] ; then echo "=====================================" echo "Getting missed routers: round $round." par -q -n $PAR_COUNT -c "rancid-fe \{}" $DIR/routers.up.missed rm -f $DIR/routers.up.missed round=`expr $round + 1` else echo "All routers sucessfully completed." round=`expr $pass + 1` fi done echo # Make sure that no empty/truncated configs are accepted. The remainder are # renamed from device_name.new -> device_name. for router in `cat $devlistfile` do OFS=$IFS IFS=':' set $router IFS=$OFS router=$1; if [ ! -s $router.new ] ; then rm -f $router.new else notcomment=`egrep -v "^[-*\!\;#]|\/\*" $router.new | wc -l` if [ $notcomment -gt 10 ]; then lines=1; else lines=0; fi if [ ! $lines ] ; then rm -f $router.new else mv $router.new $router if [ $? -ne 0 ] ; then echo "Error: could not rename $router.new to $router" rm -f $router.new fi fi fi done # This has been different for different machines... # Diff the directory and then checkin. trap 'rm -fr $TMP $TMP.diff $DIR/routers.single;' 1 2 15 cd $DIR if [ $RCSSYS = "cvs" ] ; then cvs -f @DIFF_CMD@ -ko | sed -e '/^RCS file: /d' -e '/^--- /d' \ -e '/^+++ /d' -e 's/^\([-+ ]\)/\1 /' >$TMP.diff else svn diff | sed -e '/^+++ /d' -e 's/^\([-+ ]\)/\1 /' >$TMP.diff fi if [ $alt_mailrcpt -eq 1 ] ; then subject="router config diffs - courtesy of $mailrcpt" else subject="router config diffs" fi if [ "X$device" != "X" ] ; then $RCSSYS commit -m "updates - courtesy of $mailrcpt" subject="$GROUP/$device $subject" else $RCSSYS commit -m updates subject="$GROUP $subject" fi # Mail out the diffs (if there are any). if [ -s $TMP.diff ] ; then ( echo "To: $mailrcpt" echo "Subject: $subject" echo "$MAILHEADERS" | awk '{L = "";LN = $0;while (LN ~ /\\n/) { I = index(LN,"\\n");L = L substr(LN,0,I-1) "\n";LN = substr(LN,I+2,length(LN)-I-1);}print L LN;}' echo "" cat $TMP.diff ) | sendmail -t fi # If any machines have not been reached within the last $OLDTIME # hours, mail out a list of them. cd $DIR/configs rm -f $DIR/routers.failed if [ "X$OLDTIME" = "X" ] ; then OLDTIME=24 fi @PERLV@ -F: -ane "{\$t = (stat(\$F[0]))[9]; print \`ls -ld \$F[0]\` if (time() - \$t >= $OLDTIME*60*60);}" $devlistfile | sort -u > $DIR/routers.failed if [ -s $DIR/routers.failed ] ; then ( echo "To: $adminmailrcpt" echo "Subject: config fetcher problems - $GROUP" echo "$MAILHEADERS" | awk '{L = "";LN = $0;while (LN ~ /\\n/) { I = index(LN,"\\n");L = L substr(LN,0,I-1) "\n";LN = substr(LN,I+2,length(LN)-I-1);}print L LN;}' echo "" echo "The following routers have not been successfully contacted for" echo "more than $OLDTIME hours." cat $DIR/routers.failed ) | sendmail -t fi # Cleanup rm -f $TMP.diff $DIR/routers.single $DIR/routers.failed trap '' 1 2 15 rancid-2.3.8/bin/cssrancid.in100644 015615 000000 00000055245 11535733223 0011546#! @PERLV_PATH@ ## ## $Id: cssrancid.in 2279 2011-01-31 22:41:00Z heas $ ## ## @PACKAGE@ @VERSION@ ## Copyright (c) 1997-2008 by Terrapin Communications, Inc. ## All rights reserved. ## ## This code is derived from software contributed to and maintained by ## Terrapin Communications, Inc. by Henry Kilmer, John Heasley, Andrew Partan, ## Pete Whiting, Austin Schutz, and Andrew Fort. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions ## are met: ## 1. Redistributions of source code must retain the above copyright ## notice, this list of conditions and the following disclaimer. ## 2. Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## 3. All advertising materials mentioning features or use of this software ## must display the following acknowledgement: ## This product includes software developed by Terrapin Communications, ## Inc. and its contributors for RANCID. ## 4. Neither the name of Terrapin Communications, Inc. nor the names of its ## contributors may be used to endorse or promote products derived from ## this software without specific prior written permission. ## 5. It is requested that non-binding fixes and modifications be contributed ## back to Terrapin Communications, Inc. ## ## THIS SOFTWARE IS PROVIDED BY Terrapin Communications, INC. AND CONTRIBUTORS ## ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ## TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COMPANY OR CONTRIBUTORS ## BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ## CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ## SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ## INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ## CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ## ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ## POSSIBILITY OF SUCH DAMAGE. # # RANCID - Really Awesome New Cisco confIg Differ # # usage: rancid [-dV] [-l] [-f filename | hostname] # use Getopt::Std; 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 my(@commandtable, %commands, @commands);# command lists my($aclsort) = ("ipsort"); # ACL sorting mode my($filter_commstr); # SNMP community string filtering 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)) && scalar(%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 routine 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 routine 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 routine 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 routine (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 "show version" sub ShowVersion { print STDERR " In ShowVersion: $_" if ($debug); while () { tr/\015//d; last if(/^$prompt/); next if(/^(\s*|\s*$cmd\s*)$/); return(-1) if (/command authorization failed/i); if (/^Slave in slot (\d+) is running/) { $slave = " Slave:"; next; } /^Cisco Secure PIX /i && ProcessHistory("COMMENTS","keysort","F1", "!Image: $_") && next; /^IOS .* Software \(([A-Za-z-0-9]*)\), .*Version\s+(.*)$/ && ProcessHistory("COMMENTS","keysort","F1", "!Image:$slave Software: $1, $2\n") && next; /^([A-Za-z-0-9_]*) Synced to mainline version: (.*)$/ && ProcessHistory("COMMENTS","keysort","F2", "!Image:$slave $1 Synced to mainline version: $2\n") && next; /^Compiled (.*)$/ && ProcessHistory("COMMENTS","keysort","F3", "!Image:$slave Compiled: $1\n") && next; /^ROM: (System )?Bootstrap.*(Version.*)$/ && ProcessHistory("COMMENTS","keysort","G1", "!ROM Bootstrap: $2\n") && next; if (/^Hardware:\s+(.*), (.* RAM), CPU (.*)$/) { ProcessHistory("COMMENTS","keysort","A1", "!Chassis type: $1 - a PIX\n"); ProcessHistory("COMMENTS","keysort","A2", "!CPU: $3\n"); ProcessHistory("COMMENTS","keysort","B1", "!Memory: $2\n"); } /^Serial Number:\s+(.*)$/ && ProcessHistory("COMMENTS","keysort","C1", "!$_") && next; /^Activation Key:\s+(.*)$/ && ProcessHistory("COMMENTS","keysort","C2", "!$_") && next; /^ROM: \d+ Bootstrap .*(Version.*)$/ && ProcessHistory("COMMENTS","keysort","G2", "!ROM Image: Bootstrap $1\n!\n") && next; /^ROM: .*(Version.*)$/ && ProcessHistory("COMMENTS","keysort","G3","!ROM Image: $1\n") && next; /^BOOTFLASH: .*(Version.*)$/ && ProcessHistory("COMMENTS","keysort","G4","!BOOTFLASH: $1\n") && next; /^BOOTLDR: .*(Version.*)$/ && ProcessHistory("COMMENTS","keysort","G4","!BOOTLDR: $1\n") && next; /^System image file is "([^\"]*)", booted via (\S*)/ && ProcessHistory("COMMENTS","keysort","F4","!Image: booted $1\n") && next; /^System image file is "([^\"]*)"$/ && ProcessHistory("COMMENTS","keysort","F5","!Image: $1\n") && next; if (/(\S+)\s+\((\S+)\)\s+processor.*with (\S+[kK]) bytes/) { my($proc) = $1; my($cpu) = $2; my($mem) = $3; my($device) = "router"; $type = "CSS"; print STDERR "TYPE = $type\n" if ($debug); ProcessHistory("COMMENTS","keysort","A1", "!Chassis type:$slave $proc - a $type $device\n"); ProcessHistory("COMMENTS","keysort","B1", "!Memory:$slave main $mem\n"); ProcessHistory("COMMENTS","keysort","A3","!CPU:$slave $cpu\n"); next; } if (/(\S+) Silicon\s*Switch Processor/) { if (!defined($C0)) { $C0 = 1; ProcessHistory("COMMENTS","keysort","C0","!\n"); } ProcessHistory("COMMENTS","keysort","C2","!SSP: $1\n"); $ssp = 1; $sspmem = $1; next; } /^(\d+[kK]) bytes of multibus/ && ProcessHistory("COMMENTS","keysort","B2", "!Memory: multibus $1\n") && next; /^(\d+[kK]) bytes of non-volatile/ && ProcessHistory("COMMENTS","keysort","B3", "!Memory: nvram $1\n") && next; /^(\d+[kK]) bytes of flash memory/ && ProcessHistory("COMMENTS","keysort","B5","!Memory: flash $1\n") && next; /^(\d+[kK]) bytes of .*flash partition/ && ProcessHistory("COMMENTS","keysort","B6", "!Memory: flash partition $1\n") && next; /^(\d+[kK]) bytes of Flash internal/ && ProcessHistory("COMMENTS","keysort","B4", "!Memory: bootflash $1\n") && next; if(/^(\d+[kK]) bytes of (Flash|ATA)?.*PCMCIA .*(slot|disk) ?(\d)/i) { ProcessHistory("COMMENTS","keysort","B7", "!Memory: pcmcia $2 $3$4 $1\n"); next; } if(/^WARNING/) { if (!defined($I0)) { $I0 = 1; ProcessHistory("COMMENTS","keysort","I0","!\n"); } ProcessHistory("COMMENTS","keysort","I1","! $_"); # The line after the WARNING is what to do about it. $_ = ; tr/\015//d; ProcessHistory("COMMENTS","keysort","I1","! $_"); } if (/^Configuration register is (.*)$/) { $config_register = $1; next; } } return(0); } # Dummy routine to set term length.... 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); $_ = ; return(0); } # Dummy routine to copy profile... sub CopyProfile { ## Because the term length gets changed twice, the stupid ## box will ask you to save or discard changes. This prompt ## 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); $_ = ; return(0); } # This routine parses "show boot" sub ShowBoot { # Pick up boot variables if 7000/7200/7500/12000/2900/3500; # otherwise pick up bootflash. print STDERR " In ShowBoot: $_" if ($debug); while () { tr/\015//d; last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); return(1) if /^\s*\^\s*$/; return(-1) if (/command authorization failed/i); 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: $_"); } else { ProcessHistory("COMMENTS","keysort","H1","!Variable: $_"); } } elsif (/variable/) { ProcessHistory("COMMENTS","keysort","H1","!Variable: $_"); } } ProcessHistory("COMMENTS","","","!\n"); return(0); } # This routine processes a "show run" sub ShowRun { print STDERR " In ShowRun: $_" if ($debug); my($lines) = 0; while () { tr/\015//d; 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 # skip the crap if (/^(##+$|(Building|Current) configuration)/i) { while () { next if (/^Current configuration\s*:/i); next if (/^:/); next if (/^([%!].*|\s*)$/); next if (/^ip add.*ipv4:/); # band-aid for 3620 12.0S last; } if (defined($config_register)) { ProcessHistory("","","","!\nconfig-register $config_register\n"); } tr/\015//d; } # some versions have other crap mixed in with the bits in the # block above /^! (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 /^ 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 \n"); next; } if (/^(enable secret) / && $filter_pwds >= 2) { ProcessHistory("ENABLE","","","!$1 \n"); next; } if (/^username (\S+)(\s.*)? secret /) { if ($filter_pwds >= 2) { ProcessHistory("USER","keysort","$1","!username $1$2 secret \n"); } else { ProcessHistory("USER","keysort","$1","$_"); } next; } if (/\s*username (\S+)(\s.*)? (des-password|password) (\S+|\S+)/) { if ($filter_pwds >= 1) { ProcessHistory("USER","keysort","$1","! username $1$2 $3 $'\n"); } else { ProcessHistory("USER","keysort","$1","$_"); } next; } if (/^(\s*)password / && $filter_pwds >= 1) { ProcessHistory("LINE-PASS","","","!$1password \n"); next; } if (/^\s*neighbor (\S*) password / && $filter_pwds >= 1) { ProcessHistory("","","","! neighbor $1 password \n"); next; } if (/^(ppp .* password) 7 .*/ && $filter_pwds >= 1) { ProcessHistory("","","","!$1 \n"); next; } if (/^(ip ftp password) / && $filter_pwds >= 1) { ProcessHistory("","","","!$1 \n"); next; } if (/^( ip ospf authentication-key) / && $filter_pwds >= 1) { ProcessHistory("","","","!$1 \n"); next; } # isis passwords appear to be completely plain-text if (/^\s+isis password (\S+)( .*)?/ && $filter_pwds >= 1) { ProcessHistory("","","","!isis password $2\n"); next; } if (/^\s+(domain-password|area-password) (\S+)( .*)?/ && $filter_pwds >= 1) { ProcessHistory("","","","!$1 $2\n"); next; } # this is reversable, despite 'md5' in the cmd if (/^( ip ospf message-digest-key \d+ md5) / && $filter_pwds >= 1) { ProcessHistory("","","","!$1 \n"); next; } if (/^((crypto )?isakmp key) \S+ / && $filter_pwds >= 1) { ProcessHistory("","","","!$1 $'"); next; } # i am told these are plain-text on the PIX if (/^(vpdn username \S+ password)/ && $filter_pwds >= 1) { ProcessHistory("","","","!$1 \n"); next; } /fair-queue individual-limit/ && next; # sort ip explicit-paths. if (/^ip explicit-path name (\S+)/) { my($key) = $1; my($expath) = $_; while () { tr/\015//d; last if (/^$prompt/); last if (/^$prompt/ || ! /^(ip explicit-path name |[ !])/); if (/^ip explicit-path name (\S+)/) { ProcessHistory("EXPATH","keysort","$key","$expath"); $key = $1; $expath = $_; } else { $expath .= $_; } } ProcessHistory("EXPATH","keysort","$key","$expath"); } # sort route-maps if (/^route-map (\S+)/) { my($key) = $1; my($routemap) = $_; while () { tr/\015//d; last if (/^$prompt/ || ! /^(route-map |[ !])/); if (/^route-map (\S+)/) { ProcessHistory("ROUTEMAP","keysort","$key","$routemap"); $key = $1; $routemap = $_; } else { $routemap .= $_; } } ProcessHistory("ROUTEMAP","keysort","$key","$routemap"); } # filter out any RCS/CVS tags to avoid confusing local CVS storage s/\$(Revision|Id):/ $1:/; # order access-lists /^access-list\s+(\d\d?)\s+(\S+)\s+(\S+)/ && ProcessHistory("ACL $1 $2","$aclsort","$3","$_") && next; # order extended access-lists /^access-list\s+(\d\d\d)\s+(\S+)\s+ip\s+host\s+(\S+)/ && ProcessHistory("EACL $1 $2","$aclsort","$3","$_") && next; /^access-list\s+(\d\d\d)\s+(\S+)\s+ip\s+(\d\S+)/ && ProcessHistory("EACL $1 $2","$aclsort","$3","$_") && next; /^access-list\s+(\d\d\d)\s+(\S+)\s+ip\s+any/ && ProcessHistory("EACL $1 $2","$aclsort","0.0.0.0","$_") && next; # order arp lists /^arp\s+(\d+\.\d+\.\d+\.\d+)\s+/ && ProcessHistory("ARP","$aclsort","$1","$_") && next; /^ip prefix-list\s+(\S+)\s+seq\s+(\d+)\s+(permit|deny)\s+(\d\S+)(\/.*)$/ && ProcessHistory("PACL $1 $3","$aclsort","$4","ip prefix-list $1 $3 $4$5\n") && next; # order logging statements /^logging (\d+\.\d+\.\d+\.\d+)/ && ProcessHistory("LOGGING","ipsort","$1","$_") && next; # order/prune snmp-server host statements # we only prune lines of the form # snmp-server host a.b.c.d if (/^snmp-server host (\d+\.\d+\.\d+\.\d+) /) { if ($filter_commstr) { my($ip) = $1; my($line) = "snmp-server host $ip"; my(@tokens) = split(' ', $'); my($token); while ($token = shift(@tokens)) { if ($token eq 'version') { $line .= " " . join(' ', ($token, shift(@tokens))); } elsif ($token =~ /^(informs?|traps?|(no)?auth)$/) { $line .= " " . $token; } else { $line = "!$line " . join(' ', ("", join(' ',@tokens))); last; } } ProcessHistory("SNMPSERVERHOST","ipsort","$ip","$line\n"); } else { ProcessHistory("SNMPSERVERHOST","ipsort","$1","$_"); } next; } if (/^(snmp-server community) (\S+)/) { if ($filter_commstr) { ProcessHistory("SNMPSERVERCOMM","keysort","$_","!$1 $'") && next; } else { ProcessHistory("SNMPSERVERCOMM","keysort","$_","$_") && next; } } # order/prune tacacs/radius server statements if (/^(tacacs-server|radius-server) key / && $filter_pwds >= 1) { ProcessHistory("","","","!$1 key \n"); next; } # order clns host statements /^clns host \S+ (\S+)/ && ProcessHistory("CLNS","keysort","$1","$_") && next; # order alias statements /^alias / && ProcessHistory("ALIAS","keysort","$_","$_") && next; # delete ntp auth password - this md5 is a reversable too if (/^(ntp authentication-key \d+ md5) / && $filter_pwds >= 1) { ProcessHistory("","","","!$1 \n"); next; } # order ntp peers/servers if (/^ntp (server|peer) (\d+)\.(\d+)\.(\d+)\.(\d+)/) { $sortkey = sprintf("$1 %03d%03d%03d%03d",$2,$3,$4,$5); ProcessHistory("NTP","keysort",$sortkey,"$_"); next; } # order ip host line statements /^ip host line(\d+)/ && ProcessHistory("IPHOST","numsort","$1","$_") && next; # order ip nat source static statements /^ip nat (\S+) source static (\S+)/ && ProcessHistory("IP NAT $1","ipsort","$2","$_") && next; # order atm map-list statements /^\s+ip\s+(\d+\.\d+\.\d+\.\d+)\s+atm-vc/ && ProcessHistory("ATM map-list","ipsort","$1","$_") && next; # order ip rcmd lines /^ip rcmd/ && ProcessHistory("RCMD","keysort","$_","$_") && next; # system controller /^syscon address (\S*) (\S*)/ && ProcessHistory("","","","!syscon address $1 \n") && next; if (/^syscon password (\S*)/ && $filter_pwds >= 1) { ProcessHistory("","","","!syscon password \n"); next; } # catch anything that wasnt matched above. ProcessHistory("","","","$_"); } return(0); } # dummy function sub DoNothing {print STDOUT;} # Main @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("|", map quotemeta($_), @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 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 clogin -t $timeo -c\"$cisco_cmds\" $host\n" if ($debug); print STDOUT "executing clogin -t $timeo -c\"$cisco_cmds\" $host\n" if ($log); if (defined($ENV{NOPIPE}) && $ENV{NOPIPE} =~ /^YES/i) { system "clogin -t $timeo -c \"$cisco_cmds\" $host $host.raw 2>&1" || die "clogin failed for $host: $!\n"; open(INPUT, "< $host.raw") || die "clogin failed for $host: $!\n"; } else { open(INPUT,"clogin -t $timeo -c \"$cisco_cmds\" $host ) { NEXT: tr/\015//d; if (/\#\s?exit/) { $clean_run = 1; last; } if (/^Error:/) { print STDOUT ("$host clogin error: $_"); print STDERR ("$host clogin error: $_") if ($debug); $clean_run = 0; last; } if (/#\s*($cmds_regexp)\s*$/) { $cmd = $1; 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; } $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); # Flush History ProcessHistory("","","",""); # Cleanup close(INPUT); close(OUTPUT); if (defined($ENV{NOPIPE}) && $ENV{NOPIPE} =~ /^YES/i) { 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); } rancid-2.3.8/bin/elogin.in100644 015615 000000 00000034611 11662541466 0011053#! @EXPECT_PATH@ -- ## ## $Id: elogin.in 2334 2011-11-17 21:09:37Z heas $ ## ## @PACKAGE@ @VERSION@ ## Copyright (c) @COPYYEARS@ by Terrapin Communications, Inc. ## All rights reserved. ## ## This code is derived from software contributed to and maintained by ## Terrapin Communications, Inc. by Henry Kilmer, John Heasley, Andrew Partan, ## Pete Whiting, Austin Schutz, and Andrew Fort. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions ## are met: ## 1. Redistributions of source code must retain the above copyright ## notice, this list of conditions and the following disclaimer. ## 2. Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## 3. All advertising materials mentioning features or use of this software ## must display the following acknowledgement: ## This product includes software developed by Terrapin Communications, ## Inc. and its contributors for RANCID. ## 4. Neither the name of Terrapin Communications, Inc. nor the names of its ## contributors may be used to endorse or promote products derived from ## this software without specific prior written permission. ## 5. It is requested that non-binding fixes and modifications be contributed ## back to Terrapin Communications, Inc. ## ## THIS SOFTWARE IS PROVIDED BY Terrapin Communications, INC. AND CONTRIBUTORS ## ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ## TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COMPANY OR CONTRIBUTORS ## BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ## CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ## SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ## INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ## CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ## ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ## POSSIBILITY OF SUCH DAMAGE. # # elogin - ADC EZT3 login # # Most options are intuitive for logging into an ADC EZT3 mux. # # Usage line set usage "Usage: $argv0 \[-dSV\] \[-noenable\] \[-c command\] \ \[-Evar=x\] \[-f cloginrc-file\] \[-p user-password\] \ \[-s script-file\] \[-t timeout\] \[-u username\] \ \[-v vty-password\] \[-w enable-username\] \[-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 avenable 1 # The default is that you login non-enabled (tacacs can have you login already # enabled) set avautoenable 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 # Save config, if prompted set do_saveconfig 0 # Sometimes routers take awhile to answer (the default is 10 sec) set timeoutdflt 45 # 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) } elseif {[ info exists env(LOGNAME) ]} { set default_user $env(LOGNAME) } 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 "\nError: could not exec id: $reason\n" exit 1 } regexp {\(([^)]*)} "$reason" junk default_user } if {[ info exists env(CLOGINRC) ]} { set password_file $env(CLOGINRC) } # Process the command line for {set i 0} {$i < $argc} {incr i} { set arg [lindex $argv $i] switch -glob -- $arg { # Expect debug mode -d* { exp_internal 1 # Username } -u* { if {! [ regexp .\[uU\](.+) $arg ignore user]} { incr i set username [ lindex $argv $i ] } # VTY Password } -p* { if {! [ regexp .\[pP\](.+) $arg ignore userpasswd]} { incr i set userpasswd [ lindex $argv $i ] } set do_passwd 0 # ssh passphrase } -r* { # ignore -r # VTY Password } -v* { if {! [ regexp .\[vV\](.+) $arg ignore passwd]} { incr i set passwd [ lindex $argv $i ] } set do_passwd 0 # Version string } -V* { send_user "@PACKAGE@ @VERSION@\n" exit 0 # Enable Username } -w* { # ignore -w # Environment variable to pass to -s scripts } -E* { if {[ regexp .\[E\](.+)=(.+) $arg ignore varname varvalue]} { set E$varname $varvalue } else { send_user "\nError: invalid format for -E in $arg\n" exit 1 } # Enable Password } -e* { # ignore -e # Command to run. } -c* { if {! [ regexp .\[cC\](.+) $arg ignore command]} { incr i set command [ lindex $argv $i ] } set do_command 1 # Expect script to run. } -s* { if {! [ regexp .\[sS\](.+) $arg ignore sfile]} { incr i set sfile [ lindex $argv $i ] } if { ! [ file readable $sfile ] } { send_user "\nError: Can't read $sfile\n" exit 1 } set do_script 1 # save config on exit } -S* { set do_saveconfig 1 # 'ssh -c' cypher type } -y* { if {! [ regexp .\[eE\](.+) $arg ignore cypher]} { incr i set cypher [ lindex $argv $i ] } # alternate cloginrc file } -f* { if {! [ regexp .\[fF\](.+) $arg ignore password_file]} { incr i set password_file [ lindex $argv $i ] } # Timeout } -t* { if {! [ regexp .\[tT\](.+) $arg ignore timeout]} { incr i set timeoutdflt [ lindex $argv $i ] } # Command file } -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 "\nError: Unknown argument! $arg\n" send_user $usage exit 1 } default { break } } } # Process routers...no routers listed is an error. if { $i == $argc } { send_user "\nError: $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 "\nError: password file ($password_file) does not exist\n" exit 1 } file stat $password_file fileinfo if { [expr ($fileinfo(mode) & 007)] != 0000 } { send_user "\nError: $password_file must not be world readable/writable\n" exit 1 } if [ catch {source $password_file} reason ] { send_user "\nError: $reason\n" exit 1 } } # Log into the router. # returns: 0 on success, 1 on failure 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] { incr progs -1 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" return 1 } } elseif ![string compare $prog "ssh"] { send_error "\nError: unsupported method: ssh\n" if { $progs == 0 } { return 1 } continue } elseif ![string compare $prog "rsh"] { send_error "\nError: unsupported method: rsh\n" if { $progs == 0 } { return 1 } continue } else { send_user "\nError: unknown connection method: $prog\n" return 1 } sleep 0.3 # This helps cleanup each expect clause. expect_after { timeout { send_user "\nError: TIMEOUT reached\n" catch {close}; catch {wait}; if { $in_proc} { return 1 } else { continue } } eof { send_user "\nError: EOF received\n" catch {close}; catch {wait}; if { $in_proc} { return 1 } else { continue } } } expect { "Connection refused" { catch {close}; catch {wait}; sleep 0.3 expect eof send_user "\nError: Connection Refused\n"; wait; return 1 } eof { send_user "\nError: Couldn't login\n"; wait; return 1 } "Unknown host\r\n" { expect eof send_user "\nError: Unknown host\n"; wait; return 1 } "Host is unreachable" { expect eof send_user "\nError: Host Unreachable!\n"; wait; return 1 } "No address associated with name" { expect eof send_user "\nError: 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 } "Password incorrect" { send_user "\nError: Check your password for $router\n"; catch {close}; catch {wait}; return 1 } "$prompt" { break; } denied { send_user "\nError: Check your passwd for $router\n" catch {close}; catch {wait}; 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 "screen 0\r" expect $prompt {} regsub -all "\[)(]" $prompt {\\&} reprompt 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." { exp_continue } -re "^\[^\n\r *]*$reprompt" {} -re "\[\n\r]" { exp_continue } } } send "exit\r" expect { "\n" { exp_continue } timeout { catch {close}; catch {wait}; 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 set exitval 0 foreach router [lrange $argv $i end] { set router [string tolower $router] send_user "$router\n" # device timeout set timeout [find timeout $router] if { [llength $timeout] == 0 } { set timeout $timeoutdflt } # Figure out prompt. set prompt "Active) > " set autoenable 1 set enable 0 # Figure out passwords if { $do_passwd } { set pswd [find password $router] if { [llength $pswd] == 0 } { send_user "\nError: no password for $router in $password_file.\n" continue } set passwd [join [lindex $pswd 0] ""] } # Figure out username if {[info exists username]} { # command line username set ruser $username } else { set ruser [join [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 [join [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):" } else { set u_prompt [join [lindex $u_prompt 0] ""] } set p_prompt [find passprompt $router] if { "$p_prompt" == "" } { set p_prompt "\[Pp]assword:" } else { set p_prompt [join [lindex $p_prompt 0] ""] } # 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}} } # Login to the router if {[login $router $ruser $userpswd $passwd $prompt $cmethod $cyphertype]} { incr exitval continue } if { $do_command } { if {[run_commands $prompt $command]} { incr exitval continue } } elseif { $do_script } { send "screen 0\r" expect $prompt {} source $sfile catch {close} } else { label $router log_user 1 interact } # End of for each router catch {wait}; sleep 0.3 } exit $exitval rancid-2.3.8/bin/erancid.in100644 015615 000000 00000024532 11535733223 0011175#! @PERLV_PATH@ ## ## $Id: erancid.in 2279 2011-01-31 22:41:00Z heas $ ## ## @PACKAGE@ @VERSION@ ## Copyright (c) 1997-2008 by Terrapin Communications, Inc. ## All rights reserved. ## ## This code is derived from software contributed to and maintained by ## Terrapin Communications, Inc. by Henry Kilmer, John Heasley, Andrew Partan, ## Pete Whiting, Austin Schutz, and Andrew Fort. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions ## are met: ## 1. Redistributions of source code must retain the above copyright ## notice, this list of conditions and the following disclaimer. ## 2. Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## 3. All advertising materials mentioning features or use of this software ## must display the following acknowledgement: ## This product includes software developed by Terrapin Communications, ## Inc. and its contributors for RANCID. ## 4. Neither the name of Terrapin Communications, Inc. nor the names of its ## contributors may be used to endorse or promote products derived from ## this software without specific prior written permission. ## 5. It is requested that non-binding fixes and modifications be contributed ## back to Terrapin Communications, Inc. ## ## THIS SOFTWARE IS PROVIDED BY Terrapin Communications, INC. AND CONTRIBUTORS ## ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ## TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COMPANY OR CONTRIBUTORS ## BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ## CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ## SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ## INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ## CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ## ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ## POSSIBILITY OF SUCH DAMAGE. # # RANCID - Really Awesome New Cisco confIg Differ # # usage: rancid [-dV] [-l] [-f filename | hostname] # use Getopt::Std; 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; # elogin timeout in seconds my(@commandtable, %commands, @commands);# command lists my($aclsort) = ("ipsort"); # ACL sorting mode my($filter_commstr); # SNMP community string filtering 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)) && scalar(%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 routine 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 routine 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 routine 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 routine (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 "show version" sub ShowVersion { print STDERR " In ShowVersion: $_" if ($debug); ProcessHistory("COMMENTS","keysort","A1", "- Chassis type: EZT3 - an ADC EZT3 M13 multiplexor\n"); while () { tr/\015//d; last if(/Active\) >/); next if(/^(\s*|\s*$cmd\s*)$/); /Boot Version (\S*)/ && ProcessHistory("COMMENTS","keysort","G1", "- ROM Bootstrap: $1\n") && next; /Software Version (\S*)/ && ProcessHistory("COMMENTS","keysort","F1", "- Software: $1\n") && next; } return(0); } # This routine parses "show module" sub ShowModule { print STDERR " In ShowModule: $_" if ($debug); # eat the header line $junk = ; ProcessHistory("SLOT","","","-\n"); # now just copy it verbatim to the history file while () { tr/\015//d; last if(/Active\) >/); last if(/^$/); chop; ProcessHistory("SLOT","","","-$_\n"); } ProcessHistory("SLOT","","","-\n"); } # This routine processes a "write term" sub WriteTerm { print STDERR " In WriteTerm: $_" if ($debug); # eat the header line $junk = ; # now just copy it verbatim to the history file while () { tr/\015//d; last if(/Active\) >/); chop; if (/^\s*snmp/ && $filter_commstr) { /snmp (getcomm|setcomm|trapcomm)(\s+)(\S*)/ && ProcessHistory("","","","- snmp $1$2\"\"\n") && next; } # believe it or not, "-" is the "whole line is comment" command ProcessHistory("","","","$_\n"); } $found_end = 1; return(1); } # dummy function sub DoNothing {print STDOUT;} # Main @commandtable = ( {'version' => 'ShowVersion'}, {'equipment' => 'ShowModule'}, {'config' => 'WriteTerm'} ); # 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("|", map quotemeta($_), @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 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 elogin -t $timeo -c\"$cisco_cmds\" $host\n" if ($debug); print STDOUT "executing elogin -t $timeo -c\"$cisco_cmds\" $host\n" if ($log); if (defined($ENV{NOPIPE}) && $ENV{NOPIPE} =~ /^YES/i) { system "elogin -t $timeo -c \"$cisco_cmds\" $host $host.raw 2>&1" || die "elogin failed for $host: $!\n"; open(INPUT, "< $host.raw") || die "elogin failed for $host: $!\n"; } else { open(INPUT,"elogin -t $timeo -c \"$cisco_cmds\" $host ) { tr/\015//d; if (/Logging out$/) { $clean_run=1; last; } if (/^Error:/) { print STDOUT ("$host elogin error: $_"); print STDERR ("$host elogin error: $_") if ($debug); $clean_run=0; last; } while (/Active\) >\s*($cmds_regexp)\s*$/) { $cmd = $1; 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; } $rval = &{$commands{$cmd}}; delete($commands{$cmd}); if ($rval == -1) { $clean_run = 0; last; } } } print STDOUT "Done $logincmd: $_\n" if ($log); # Flush History ProcessHistory("","","",""); # Cleanup close(INPUT); close(OUTPUT); if (defined($ENV{NOPIPE}) && $ENV{NOPIPE} =~ /^YES/i) { 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); } rancid-2.3.8/bin/f10rancid.in100644 015615 000000 00000052367 11535733223 0011346#! @PERLV_PATH@ ## ## $Id: f10rancid.in 2279 2011-01-31 22:41:00Z heas $ ## ## @PACKAGE@ @VERSION@ ## Copyright (c) 1997-2008 by Terrapin Communications, Inc. ## All rights reserved. ## ## This code is derived from software contributed to and maintained by ## Terrapin Communications, Inc. by Henry Kilmer, John Heasley, Andrew Partan, ## Pete Whiting, Austin Schutz, and Andrew Fort. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions ## are met: ## 1. Redistributions of source code must retain the above copyright ## notice, this list of conditions and the following disclaimer. ## 2. Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## 3. All advertising materials mentioning features or use of this software ## must display the following acknowledgement: ## This product includes software developed by Terrapin Communications, ## Inc. and its contributors for RANCID. ## 4. Neither the name of Terrapin Communications, Inc. nor the names of its ## contributors may be used to endorse or promote products derived from ## this software without specific prior written permission. ## 5. It is requested that non-binding fixes and modifications be contributed ## back to Terrapin Communications, Inc. ## ## THIS SOFTWARE IS PROVIDED BY Terrapin Communications, INC. AND CONTRIBUTORS ## ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ## TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COMPANY OR CONTRIBUTORS ## BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ## CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ## SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ## INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ## CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ## ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ## POSSIBILITY OF SUCH DAMAGE. # # This version of rancid tries to deal with Force10s. # # RANCID - Really Awesome New Cisco confIg Differ # # usage: rancid [-dV] [-l] [-f filename | hostname] # use Getopt::Std; 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 my(@commandtable, %commands, @commands);# command lists my($aclsort) = ("ipsort"); # ACL sorting mode my($filter_commstr); # SNMP community string filtering 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)) && scalar(%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 routine 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 routine 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 routine 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 routine (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 "show version" sub ShowVersion { print STDERR " In ShowVersion: $_" if ($debug); while () { tr/\015//d; last if(/^$prompt/); next if(/^(\s*|\s*$cmd\s*)$/); return(-1) if (/command authorization failed/i); / Type: / && chop && chop && ProcessHistory("COMMENTS","keysort","A1", "!$_\n"); /^.* Version.*$/ && ProcessHistory("COMMENTS","keysort","F1", "!Image: $_") && next; /^Build .*$/ && ProcessHistory("COMMENTS","keysort","F1", "!Image: $_") && next; /^System image file is "([^\"]*)"$/ && ProcessHistory("COMMENTS","keysort","F5", "!Image: $1\n") && next; if (/^(.*\s+Processor)( \d)?:(.*) with (\d+[kK]?) bytes/) { my($cpu) = "$1$2:$3"; my($mem) = int($4 / (1024 * 1024)); my($device) = "Force10"; ProcessHistory("COMMENTS","keysort","B1", "!Memory: $1$2: $mem" . "M\n"); ProcessHistory("COMMENTS","keysort","A3","!CPU: $cpu\n"); next; } # E-Series and C-Series use NVRAM /^(\d+[kK]) bytes of non-volatile/ && ProcessHistory("COMMENTS","keysort","B3", "!Memory: NVRAM $1\n") && next; # S-Series uses boot flash /^(\d+[mM]) bytes of .oot..lash/ && ProcessHistory("COMMENTS","keysort","B3", "!Memory: Flash $1\n") && next; } return(0); } # This routine parses "show boot" sub ShowBoot { print STDERR " In ShowBoot: $_" if ($debug); while () { tr/\015//d; last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); return(1) if /(Invalid input|Type help or )/; return(1) if /( *\^$)/; return(-1) if (/command authorization failed/i); ProcessHistory("COMMENTS","keysort","H0","!Boot Variables: $_"); } ProcessHistory("COMMENTS","","","!\n"); return(0); } # This routine parses "show chassis" sub ShowChassis { print STDERR " In ShowChassis: $_" if ($debug); while () { tr/\015//d; last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); return(1) if /(Invalid input|Type help or )/; return(1) if /( *\^$)/; return(-1) if (/command authorization failed/i); /-----------------------------/ && next; # general stuff that changes /Next Boot/ && next; /Up Time/ && next; /Last Restart/ && next; /Switch Fabric State/ && next; /active / && next; /online / && next; /offline / && next; # E600 AC PSMs /Status : up/ && next; /High line/ && next; # fans if (/Fan\s+Status/i) { ProcessHistory("COMMENTS","keysort","CHASSIS","!Chassis: $_"); while () { tr/\015//d; if (/^$prompt/) { goto OUT; } last if (/^$/); # remove any trailing WS s/\s+$//; next if (/^----+$/); # c150 / c300 style /FanNumber\s+Speed\s+Status/ && ProcessHistory("COMMENTS", "keysort","CHASSIS","!Chassis: FanNumber\tStatus\n") && next; /^\s+(\d)\s+\d+\s+(\S+)/ && ProcessHistory("COMMENTS", "keysort","CHASSIS","!Chassis: $1\t\t$2\n") && next; # e300 /^Status\s+$/ && next; /^\s+(\S+)\s*$/ && ProcessHistory("COMMENTS","keysort", "CHASSIS","!Chassis: $1\n") && next; # e600 style /Status\s+Temp\s+Fan1\s+Fan2\s+Fan3\s+Serial\s/ && next; /^\s+(\S+)\s+\d+C\s+\d+ RPM\s+/ && ProcessHistory("COMMENTS", "keysort","CHASSIS","!Chassis: $1\n") && next; # e1200 style /Tray\s+Status\s+Temp\s+/ && ProcessHistory("COMMENTS", "keysort","CHASSIS","!Chassis: Tray\tStatus\n") && next; /^\s+(\d+)\s+(\S+)\s+(or down|(< )?\d+C\s+)/ && ProcessHistory("COMMENTS","keysort","CHASSIS", "!Chassis: $1\t$2\n") && next; # s50n / s50v style if (/Unit\s+TrayStatus\s+Fan0\s+Fan1\s+/) { ProcessHistory("COMMENTS","keysort","CHASSIS", "!Chassis: $_\n"); # consume the following blank/separator line $_ = ; # the s50n botches its fan status line with the "---..." # separator line w/o a CR, followed by the fan status. we # would normally skip the sparator line, so hack it. s/^------+(\s+)/$1/; tr/\015//d; # the s50v has a blank line following the table header, # loop for that one and continue for the S50n /^\s+$/ && next; } /^\s+\d+\s+\S+\s+\S+\s+\S+\s+\S+\s+/ && ProcessHistory("COMMENTS","keysort","CHASSIS", "!Chassis: $_") && next; } next; } ProcessHistory("COMMENTS","keysort","CHASSIS","!Chassis: $_"); } OUT: ProcessHistory("COMMENTS","keysort","CHASSIS","!\n"); return(0); } # This routine parses "dir /all (flash|slotN):" sub DirSlotN { print STDERR " In DirSlotN: $_" if ($debug); my($dev) = (/\s([^\s]+):/); while () { tr/\015//d; last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); # return(1) if ($type !~ /^(12[40]|7|36)/); return(1) if /^\s*\^\s*$/; return(1) if /(Invalid input|Type help or )/; return(1) if /No such device/i; return(1) if /\% ?Error: No such file or directory/; return(1) if /\% ?Error: The file device is not present/; return(1) if /\% ?Error: The specified file or directory does not exist/; return(1) if /No space information available/; return(-1) if (/command authorization failed/i); return(1) if /(Open device \S+ failed|Error opening \S+:)/; /Directory of/ && next; # clean up totals line if (/.* (\d+) bytes total/) { my($tmp) = int($1 / (1024 * 1024)); s/.* $1 bytes total/$tmp\M total/; } if (/.*\((\d+) bytes free\)/) { my($tmp) = int($1 / (1024 * 1024)); s/$1 bytes free/$tmp\M free/; } s/ +$//g; ProcessHistory("FLASH","","","!Flash: $dev: $_"); } ProcessHistory("","","","!\n"); return(0); } # This routine parses "show inventory" sub ShowInventory { print STDERR " In ShowInventory: $_" if ($debug); while () { tr/\015//d; last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); return(1) if /(Invalid input|Type help or )/; return(-1) if (/command authorization failed/i); /-----------------------------/ && next; ProcessHistory("COMMENTS","keysort","INVENTORY","!Inventory: $_"); } ProcessHistory("COMMENTS","keysort","INVENTORY","!\n"); return(0); } # This routine parses "show vlan" sub ShowVLAN { print STDERR " In ShowVLAN: $_" if ($debug); while () { tr/\015//d; last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); return(1) if /(Invalid input|Type help or )/; return(-1) if (/command authorization failed/i); ProcessHistory("COMMENTS","keysort","VLAN","!VLAN: $_"); } ProcessHistory("COMMENTS","keysort","VLAN","!\n"); return(0); } # This routine processes a "write term" sub WriteTerm { print STDERR " In WriteTerm: $_" if ($debug); while () { tr/\015//d; last if(/^$prompt/); return(-1) if (/command authorization failed/i); # skip crap /^Current Configuration/ && next; # 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 /^ clockrate / && next; # kill clockrate on serial interfaces if (/^(enable )?(password|passwd) / && $filter_pwds >= 1) { ProcessHistory("ENABLE","","","!$1$2 \n"); next; } if (/^(enable secret) / && $filter_pwds >= 2) { ProcessHistory("ENABLE","","","!$1 \n"); next; } if (/^(enable restricted) / && $filter_pwds >= 2) { ProcessHistory("ENABLE","","","!$1 \n"); next; } if (/^username (\S+)(\s.*)? secret /) { if ($filter_pwds >= 2) { ProcessHistory("USER","keysort","$1","!username $1$2 secret \n"); } else { ProcessHistory("USER","keysort","$1","$_"); } next; } if (/^username (\S+)(\s.*)? password ((\d) \S+|\S+)/) { if ($filter_pwds == 2) { ProcessHistory("USER","keysort","$1","!username $1$2 password \n"); } elsif ($filter_pwds == 1 && $4 ne "5"){ ProcessHistory("USER","keysort","$1","!username $1$2 password \n"); } else { ProcessHistory("USER","keysort","$1","$_"); } next; } if (/^(\s*)password / && $filter_pwds >= 1) { ProcessHistory("LINE-PASS","","","!$1password \n"); next; } if (/^\s*neighbor (\S*) password / && $filter_pwds >= 1) { ProcessHistory("","","","! neighbor $1 password \n"); next; } if (/^(ip ftp password) / && $filter_pwds >= 1) { ProcessHistory("","","","!$1 \n"); next; } if (/^(ftp-server username.*password) / && $filter_pwds >= 1) { ProcessHistory("","","","!$1 \n"); next; } if (/^( ip ospf authentication-key) / && $filter_pwds >= 1) { ProcessHistory("","","","!$1 \n"); next; } # this is reversable, despite 'md5' in the cmd if (/^( ip ospf message-digest-key \d+ md5) / && $filter_pwds >= 1) { ProcessHistory("","","","!$1 \n"); next; } # sort route-maps if (/^route-map (\S+)/) { my($key) = $1; my($routemap) = $_; while () { tr/\015//d; last if (/^$prompt/ || ! /^(route-map |[ !])/); if (/^route-map (\S+)/) { ProcessHistory("ROUTEMAP","keysort","$key","$routemap"); $key = $1; $routemap = $_; } else { $routemap .= $_; } } ProcessHistory("ROUTEMAP","keysort","$key","$routemap"); } # filter out any RCS/CVS tags to avoid confusing local CVS storage s/\$(Revision|Id):/ $1:/; # order access-lists /^access-list\s+(\d\d?)\s+(\S+)\s+(\S+)/ && ProcessHistory("ACL $1 $2","$aclsort","$3","$_") && next; # order extended access-lists /^access-list\s+(\d\d\d)\s+(\S+)\s+ip\s+host\s+(\S+)/ && ProcessHistory("EACL $1 $2","$aclsort","$3","$_") && next; /^access-list\s+(\d\d\d)\s+(\S+)\s+ip\s+(\d\S+)/ && ProcessHistory("EACL $1 $2","$aclsort","$3","$_") && next; /^access-list\s+(\d\d\d)\s+(\S+)\s+ip\s+any/ && ProcessHistory("EACL $1 $2","$aclsort","0.0.0.0","$_") && next; # order arp lists /^arp\s+(\d+\.\d+\.\d+\.\d+)\s+/ && ProcessHistory("ARP","$aclsort","$1","$_") && next; /^ip prefix-list\s+(\S+)\s+seq\s+(\d+)\s+(permit|deny)\s+(\d\S+)(\/.*)$/ && ProcessHistory("PACL $1 $3","$aclsort","$4","ip prefix-list $1 $3 $4$5\n") && next; # order logging statements /^logging (\d+\.\d+\.\d+\.\d+)/ && ProcessHistory("LOGGING","ipsort","$1","$_") && next; # order/prune snmp-server host statements # we only prune lines of the form # snmp-server host a.b.c.d if (/^snmp-server host (\d+\.\d+\.\d+\.\d+) /) { if ($filter_commstr) { my($ip) = $1; my($line) = "snmp-server host $ip"; my(@tokens) = split(' ', $'); my($token); while ($token = shift(@tokens)) { if ($token eq 'version') { $line .= " " . join(' ', ($token, shift(@tokens))); } elsif ($token =~ /^(informs?|traps?|(no)?auth)$/) { $line .= " " . $token; } else { $line = "!$line " . join(' ', ("", join(' ',@tokens))); last; } } ProcessHistory("SNMPSERVERHOST","ipsort","$ip","$line\n"); } else { ProcessHistory("SNMPSERVERHOST","ipsort","$1","$_"); } next; } if (/^(snmp-server community) (\S+)/) { if ($filter_commstr) { ProcessHistory("SNMPSERVERCOMM","keysort","$_","!$1 $'") && next; } else { ProcessHistory("SNMPSERVERCOMM","keysort","$_","$_") && next; } } # order/prune tacacs/radius server statements if (/^(tacacs-server|radius-server) key / && $filter_pwds >= 1) { ProcessHistory("","","","!$1 key \n"); next; } # order clns host statements /^clns host \S+ (\S+)/ && ProcessHistory("CLNS","keysort","$1","$_") && next; # delete ntp auth password - this md5 is a reversable too if (/^(ntp authentication-key \d+ md5) / && $filter_pwds >= 1) { ProcessHistory("","","","!$1 \n"); next; } # order ntp peers/servers if (/^ntp (server|peer) (\d+)\.(\d+)\.(\d+)\.(\d+)/) { $sortkey = sprintf("$1 %03d%03d%03d%03d",$2,$3,$4,$5); ProcessHistory("NTP","keysort",$sortkey,"$_"); next; } # order ip host line statements /^ip host line(\d+)/ && ProcessHistory("IPHOST","numsort","$1","$_") && next; # order atm map-list statements /^\s+ip\s+(\d+\.\d+\.\d+\.\d+)\s+atm-vc/ && ProcessHistory("ATM map-list","ipsort","$1","$_") && next; # catch anything that wasnt matched above. ProcessHistory("","","","$_"); # end of config. the ": " game is for the PIX if (/^end *$/) { $found_end = 1; return(0); } } return(0); } # dummy function sub DoNothing {print STDOUT;} # Main @commandtable = ( {'show version' => 'ShowVersion'}, {'show bootvar' => 'ShowBoot'}, {'dir flash:' => 'DirSlotN'}, {'dir slot0:' => 'DirSlotN'}, {'show chassis' => 'ShowChassis'}, {'show system' => 'ShowChassis'}, {'show inventory' => 'ShowInventory'}, {'show vlan' => 'ShowVLAN'}, {'show running' => 'WriteTerm'} ); # 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("|", map quotemeta($_), @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 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 clogin -t $timeo -c\"$cisco_cmds\" $host\n" if ($debug); print STDOUT "executing clogin -t $timeo -c\"$cisco_cmds\" $host\n" if ($log); if (defined($ENV{NOPIPE}) && $ENV{NOPIPE} =~ /^YES/i) { system "clogin -t $timeo -c \"$cisco_cmds\" $host $host.raw 2>&1" || die "clogin failed for $host: $!\n"; open(INPUT, "< $host.raw") || die "clogin failed for $host: $!\n"; } else { open(INPUT,"clogin -t $timeo -c \"$cisco_cmds\" $host ) { tr/\015//d; if (/\#\s?exit$/) { $clean_run=1; last; } if (/^Error:/) { print STDOUT ("$host clogin error: $_"); print STDERR ("$host clogin error: $_") if ($debug); $clean_run=0; last; } while (/#\s*($cmds_regexp)\s*$/) { $cmd = $1; 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; } $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}) && $ENV{NOPIPE} =~ /^YES/i) { 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); } rancid-2.3.8/bin/f5rancid.in100644 015615 000000 00000044614 11535733223 0011266#! @PERLV_PATH@ ## ## $Id: f5rancid.in 2279 2011-01-31 22:41:00Z heas $ ## ## @PACKAGE@ @VERSION@ ## Copyright (c) 1997-2008 by Terrapin Communications, Inc. ## All rights reserved. ## ## This code is derived from software contributed to and maintained by ## Terrapin Communications, Inc. by Henry Kilmer, John Heasley, Andrew Partan, ## Pete Whiting, Austin Schutz, and Andrew Fort. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions ## are met: ## 1. Redistributions of source code must retain the above copyright ## notice, this list of conditions and the following disclaimer. ## 2. Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## 3. All advertising materials mentioning features or use of this software ## must display the following acknowledgement: ## This product includes software developed by Terrapin Communications, ## Inc. and its contributors for RANCID. ## 4. Neither the name of Terrapin Communications, Inc. nor the names of its ## contributors may be used to endorse or promote products derived from ## this software without specific prior written permission. ## 5. It is requested that non-binding fixes and modifications be contributed ## back to Terrapin Communications, Inc. ## ## THIS SOFTWARE IS PROVIDED BY Terrapin Communications, INC. AND CONTRIBUTORS ## ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ## TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COMPANY OR CONTRIBUTORS ## BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ## CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ## SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ## INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ## CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ## ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ## POSSIBILITY OF SUCH DAMAGE. # # This version of rancid tries to deal with F5 BigIPs. # # RANCID - Really Awesome New Cisco confIg Differ # # usage: rancid [-dV] [-l] [-f filename | hostname] # use Getopt::Std; 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 # force a terminal type so as not to confuse the POS $ENV{'TERM'} = "vt100"; my(@commandtable, %commands, @commands);# command lists my($aclsort) = ("ipsort"); # ACL sorting mode my($filter_commstr); # SNMP community string filtering 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)) && scalar(%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 routine 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 routine 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 routine 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 routine (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 "bigpipe base list" sub ShowBaseRun { my($line) = (0); print STDERR " In ShowBaseRun: $_" if ($debug); while () { tr/\015//d; last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); return(1) if /^\s*\^\s*$/; return(1) if /(Invalid input detected|Type help or )/; return(-1) if (/command authorization failed/i); if (!$line++) { ProcessHistory("SHOWBASE","","","#\n#base:\n"); } ProcessHistory("SHOWBASE","","","# $_") && next; } return(0); } # This routine parses "bigpipe db show" sub ShowDb { my($line) = (0); print STDERR " In ShowDb: $_" if ($debug); while () { tr/\015//d; last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); return(1) if /^\s*\^\s*$/; return(1) if /(Invalid input detected|Type help or )/; return(-1) if (/command authorization failed/i); if (!$line++) { ProcessHistory("SHOWDB","","","#\n#database:\n"); } /UCS.LoadTime/ && next; /Configsync\..*Time/ && next; /Configsync.peerupdatedstatus/ && next; /Failover\..*Time/ && next; /LTM.ConfigTime/ && next; if (/^(snmp\..*\.community\..* =) (.+)/i) { if ($filter_commstr) { ProcessHistory("SHOWDB","","","# $1 \n") && next; } else { ProcessHistory("SHOWDB","","","# $1 $2\n") && next; } } ProcessHistory("SHOWDB","","","# $_") && next; } return(0); } # This routine parses "cat /config/bigip.license" sub ShowLicense { my($line) = (0); print STDERR " In ShowLicense: $_" if ($debug); while () { tr/\015//d; # v9 software license does not have CR at EOF s/^#-+($prompt.*)/$1/; last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); return(1) if /^\s*\^\s*$/; return(1) if /(Invalid input detected|Type help or )/; return(-1) if (/command authorization failed/i); if (!$line++) { ProcessHistory("LICENSE","","","#\n#/config/bigip.license:\n"); } ProcessHistory("LICENSE","","","# $_") && next; } return(0); } # This routine parses "bigpipe monitor list all" sub ShowMonitor { my($line) = (0); print STDERR " In ShowMonitor: $_" if ($debug); while () { tr/\015//d; last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); return(1) if /^\s*\^\s*$/; return(1) if /(Invalid input detected|Type help or )/; return(-1) if (/command authorization failed/i); if (!$line++) { ProcessHistory("MONITOR","","","#\n"); } if (/^(snmp\.[^ ]+\.community) = (.+)/i) { if ($filter_commstr) { ProcessHistory("SHOWDB","","","# $1 \n") && next; } else { ProcessHistory("SHOWDB","","","# $1 $2\n") && next; } } if (/^(\s*)password / && $filter_pwds >= 1) { ProcessHistory("LINE-PASS","","","# $1password \n"); next; } ProcessHistory("MONITOR","","","# $_") && next; } return(0); } # This routine parses "bigpipe platform" sub ShowPlatform { print STDERR " In ShowPlatform: $_" if ($debug); while () { tr/\015//d; last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); return(1) if /^\s*\^\s*$/; return(1) if /(Invalid input detected|Type help or )/; return(-1) if (/command authorization failed/i); /fan speed/i && next; /chassis temperature/i && next; /degC/ && next; s/\d+rpm//ig; s/^\|//; /Type: / && ProcessHistory("COMMENTS","keysort","A0", "#Chassis type: $'"); ProcessHistory("COMMENTS","keysort","B1","#$_") && next; } return(0); } # This routine parses "bigpipe profile list" sub ShowProfile { print STDERR " In ShowProfile: $_" if ($debug); while () { tr/\015//d; last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); return(1) if /^\s*\^\s*$/; return(1) if /(Invalid input detected|Type help or )/; return(-1) if (/command authorization failed/i); ProcessHistory("PROFILE","",""," $_") && next; } return(0); } # This routine parses "ls --full-time --color=never /config/ssl/ssl.key" sub ShowSslKey { print STDERR " In ShowSslKey: $_" if ($debug); while () { tr/\015//d; # v9 software license does not have CR at EOF s/^#-+($prompt.*)/$1/; last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); return(1) if /^\s*\^\s*$/; return(1) if /(Invalid input detected|Type help or )/; return(-1) if (/command authorization failed/i); ProcessHistory("SSLKEY","","","# $_") && next; } return(0); } # This routine parses "ls --full-time --color=never /config/ssl/ssl.crt" sub ShowSslCrt { print STDERR " In ShowSslCrt: $_" if ($debug); while () { tr/\015//d; # v9 software license does not have CR at EOF s/^#-+($prompt.*)/$1/; last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); return(1) if /^\s*\^\s*$/; return(1) if /(Invalid input detected|Type help or )/; return(-1) if (/command authorization failed/i); ProcessHistory("SSLCRT","","","# $_") && next; } return(0); } # This routine parses "bigpipe route static show" sub ShowRouteStatic { print STDERR " In ShowRouteStatic: $_" if ($debug); while () { tr/\015//d; last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); return(1) if /^\s*\^\s*$/; return(1) if /(Invalid input detected|Type help or )/; return(-1) if (/command authorization failed/i); ProcessHistory("ROUTE","",""," $_") && next; } return(0); } # This routine parses "bigpipe version" sub ShowVersion { print STDERR " In ShowVersion: $_" if ($debug); while () { tr/\015//d; last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); return(-1) if (/command authorization failed/i); /^kernel:/i && ($_ = ) && ProcessHistory("COMMENTS","keysort","A3","#Image: Kernel: $_") && next; if (/^package:/i) { my($line); while ($_ = ) { tr/\015//d; last if (/:/); last if (/^$prompt/); chomp; $line .= " $_"; } ProcessHistory("COMMENTS","keysort","A2", "#Image: Package:$line\n"); } if (/:/) { ProcessHistory("COMMENTS","keysort","C1","#$_"); } else { ProcessHistory("COMMENTS","keysort","C1","#\t$_"); } } return(0); } # This routine processes a "bigpipe list" sub WriteTerm { my($lines) = 0; print STDERR " In WriteTerm: $_" if ($debug); while () { tr/\015//d; next if (/^\s*$/); # end of config - hopefully. f5 does not have a reliable end-of-config # tag. if (/^$prompt/) { $found_end++; last; } 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 # filter out any RCS/CVS tags to avoid confusing local CVS storage s/\$(Revision|Id):/ $1:/; $lines++; if (/^(enable )?(password|passwd) / && $filter_pwds >= 1) { ProcessHistory("ENABLE","","","! $1$2 \n"); next; } if (/^(enable secret) / && $filter_pwds >= 2) { ProcessHistory("ENABLE","","","# $1 \n"); next; } if (/^username (\S+)(\s.*)? secret /) { if ($filter_pwds >= 2) { ProcessHistory("USER","keysort","$1","# username $1$2 secret \n"); } else { ProcessHistory("USER","keysort","$1","$_"); } next; } if (/^username (\S+)(\s.*)? password ((\d) \S+|\S+)/) { if ($filter_pwds == 2) { ProcessHistory("USER","keysort","$1","# username $1$2 password \n"); } elsif ($filter_pwds == 1 && $4 ne "5"){ ProcessHistory("USER","keysort","$1","# username $1$2 password \n"); } else { ProcessHistory("USER","keysort","$1","$_"); } next; } if (/^(\s*)password / && $filter_pwds >= 1) { ProcessHistory("LINE-PASS","","","# $1password \n"); next; } if (/^\s*neighbor (\S*) password / && $filter_pwds >= 1) { ProcessHistory("","","","# neighbor $1 password \n"); next; } # order logging statements /^logging (\d+\.\d+\.\d+\.\d+)/ && ProcessHistory("LOGGING","ipsort","$1","$_") && next; # order/prune tacacs/radius server statements if (/^(tacacs-server|radius-server) key / && $filter_pwds >= 1) { ProcessHistory("","","","# $1 key \n"); next; } # order clns host statements /^clns host \S+ (\S+)/ && ProcessHistory("CLNS","keysort","$1","$_") && next; # order alias statements /^alias / && ProcessHistory("ALIAS","keysort","$_","$_") && next; # delete ntp auth password - this md5 is a reversable too if (/^(ntp authentication-key \d+ md5) / && $filter_pwds >= 1) { ProcessHistory("","","","# $1 \n"); next; } # order ntp peers/servers if (/^ntp (server|peer) (\d+)\.(\d+)\.(\d+)\.(\d+)/) { $sortkey = sprintf("$1 %03d%03d%03d%03d",$2,$3,$4,$5); ProcessHistory("NTP","keysort",$sortkey,"$_"); next; } # order ip host line statements /^ip host line(\d+)/ && ProcessHistory("IPHOST","numsort","$1","$_") && next; # order ip nat source static statements /^ip nat (\S+) source static (\S+)/ && ProcessHistory("IP NAT $1","ipsort","$2","$_") && next; # catch anything that wasnt matched above. ProcessHistory("","","","$_"); } if ($lines < 3) { printf(STDERR "ERROR: $host configuration appears truncated.\n"); $found_end = 0; return(-1); } return(0); } # dummy function sub DoNothing {print STDOUT;} # Main @commandtable = ( {'bigpipe version' => 'ShowVersion'}, {'bigpipe platform' => 'ShowPlatform'}, {'cat /config/bigip.license' => 'ShowLicense'}, {'bigpipe monitor list all' => 'ShowMonitor'}, {'bigpipe profile list' => 'ShowProfile'}, {'bigpipe base list' => 'ShowBaseRun'}, {'bigpipe db show' => 'ShowDb'}, {'bigpipe route static show' => 'ShowRouteStatic'}, {'ls --full-time --color=never /config/ssl/ssl.crt' => 'ShowSslCrt'}, {'ls --full-time --color=never /config/ssl/ssl.key' => 'ShowSslKey'}, {'bigpipe list' => 'WriteTerm'} ); # 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("|", map quotemeta($_), @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 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 clogin -t $timeo -c\"$cisco_cmds\" $host\n" if ($debug); print STDOUT "executing clogin -t $timeo -c\"$cisco_cmds\" $host\n" if ($log); if (defined($ENV{NOPIPE}) && $ENV{NOPIPE} =~ /^YES/i) { system "clogin -t $timeo -c \"$cisco_cmds\" $host $host.raw 2>&1" || die "clogin failed for $host: $!\n"; open(INPUT, "< $host.raw") || die "clogin failed for $host: $!\n"; } else { open(INPUT,"clogin -t $timeo -c \"$cisco_cmds\" $host ) { tr/\015//d; if (/^Error:/) { print STDOUT ("$host clogin error: $_"); print STDERR ("$host clogin error: $_") if ($debug); $clean_run=0; last; } while (/#\s*($cmds_regexp)\s*$/) { $cmd = $1; 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; } $rval = &{$commands{$cmd}}; delete($commands{$cmd}); if ($rval == -1) { $clean_run = 0; last TOP; } } if (/\#\s?exit$/) { $clean_run=1; last; } } print STDOUT "Done $logincmd: $_\n" if ($log); # Flush History ProcessHistory("","","",""); # Cleanup close(INPUT); close(OUTPUT); if (defined($ENV{NOPIPE}) && $ENV{NOPIPE} =~ /^YES/i) { 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); } rancid-2.3.8/bin/flogin.in100644 015615 000000 00000050224 11712067106 0011040#! @EXPECT_PATH@ -- ## ## $Id: flogin.in 2376 2012-01-31 22:42:14Z heas $ ## ## @PACKAGE@ @VERSION@ ## Copyright (c) @COPYYEARS@ by Terrapin Communications, Inc. ## All rights reserved. ## ## This code is derived from software contributed to and maintained by ## Terrapin Communications, Inc. by Henry Kilmer, John Heasley, Andrew Partan, ## Pete Whiting, Austin Schutz, and Andrew Fort. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions ## are met: ## 1. Redistributions of source code must retain the above copyright ## notice, this list of conditions and the following disclaimer. ## 2. Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## 3. All advertising materials mentioning features or use of this software ## must display the following acknowledgement: ## This product includes software developed by Terrapin Communications, ## Inc. and its contributors for RANCID. ## 4. Neither the name of Terrapin Communications, Inc. nor the names of its ## contributors may be used to endorse or promote products derived from ## this software without specific prior written permission. ## 5. It is requested that non-binding fixes and modifications be contributed ## back to Terrapin Communications, Inc. ## ## THIS SOFTWARE IS PROVIDED BY Terrapin Communications, INC. AND CONTRIBUTORS ## ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ## TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COMPANY OR CONTRIBUTORS ## BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ## CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ## SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ## INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ## CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ## ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ## POSSIBILITY OF SUCH DAMAGE. # # The expect login scripts were based on Erik Sherk's gwtn, by permission. # # flogin - foundry login # # Most options are intuitive for logging into a foundry switch. # this should be the clogin, but foundry can't seem to dislodge # their heads and make the UI consistent. i think the UI # development has been outsourced to Fisher Price. # The default is to enable (thus -noenable). Some folks have # setup tacacs to have a user login at priv-lvl = 15 (enabled) # so the -autoenable flag was added for this case (don't go through # the process of enabling and the prompt will be the "#" prompt. # The default username password is the same as the vty password. # # Usage line set usage "Usage: $argv0 \[-dSV\] \[-autoenable\] \[-noenable\] \ \[-c command\] \[-Evar=x\] \[-e enable-password\] \[-p user-password\] \ \[-f cloginrc-file\] \[-s script-file\] \[-t timeout\] \[-u user\] \ \[-v vty-password\] \[-w enable-username\]\[-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 avenable 1 # The default is that you login non-enabled (tacacs can have you login already # enabled) set avautoenable 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 set do_enapasswd 1 # Save config, if prompted set do_saveconfig 0 # Sometimes routers take awhile to answer (the default is 10 sec) set timeoutdflt 45 # set send_human {.4 .4 .7 .3 5} # 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) } elseif {[ info exists env(LOGNAME) ]} { set default_user $env(LOGNAME) } 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 "\nError: could not exec id: $reason\n" exit 1 } regexp {\(([^)]*)} "$reason" junk default_user } if {[ info exists env(CLOGINRC) ]} { set password_file $env(CLOGINRC) } # Process the command line for {set i 0} {$i < $argc} {incr i} { set arg [lindex $argv $i] switch -glob -- $arg { # Expect debug mode -d* { exp_internal 1 # Username } -u* { if {! [ regexp .\[uU\](.+) $arg ignore user]} { incr i set username [ lindex $argv $i ] } # VTY Password } -p* { if {! [ regexp .\[pP\](.+) $arg ignore userpasswd]} { incr i set userpasswd [ lindex $argv $i ] } set do_passwd 0 # ssh passphrase } -r* { # ignore -r # VTY Password } -v* { if {! [ regexp .\[vV\](.+) $arg ignore passwd]} { incr i set passwd [ lindex $argv $i ] } set do_passwd 0 # Version string } -V* { send_user "@PACKAGE@ @VERSION@\n" exit 0 # Enable Username } -w* { if {! [ regexp .\[wW\](.+) $arg ignore enauser]} { incr i set enausername [ lindex $argv $i ] } # Environment variable to pass to -s scripts } -E* { if {[ regexp .\[E\](.+)=(.+) $arg ignore varname varvalue]} { set E$varname $varvalue } else { send_user "\nError: invalid format for -E in $arg\n" exit 1 } # Enable Password } -e* { if {! [ regexp .\[eE\](.+) $arg ignore enapasswd]} { incr i set enapasswd [ lindex $argv $i ] } set do_enapasswd 0 # Command to run. } -c* { if {! [ regexp .\[cC\](.+) $arg ignore command]} { incr i set command [ lindex $argv $i ] } set do_command 1 # Expect script to run. } -s* { if {! [ regexp .\[sS\](.+) $arg ignore sfile]} { incr i set sfile [ lindex $argv $i ] } if { ! [ file readable $sfile ] } { send_user "\nError: Can't read $sfile\n" exit 1 } set do_script 1 # save config on exit } -S* { set do_saveconfig 1 # cypher type } -y* { if {! [ regexp .\[eE\](.+) $arg ignore cypher]} { incr i set cypher [ lindex $argv $i ] } # alternate cloginrc file } -f* { if {! [ regexp .\[fF\](.+) $arg ignore password_file]} { incr i set password_file [ lindex $argv $i ] } } -t* { incr i set timeoutdflt [ lindex $argv $i ] } -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 { set avenable 0 # Does tacacs automatically enable us? } -autoenable { set avautoenable 1 set avenable 0 } -* { send_user "\nError: Unknown argument! $arg\n" send_user $usage exit 1 } default { break } } } # Process routers...no routers listed is an error. if { $i == $argc } { send_user "\nError: $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 "\nError: password file ($password_file) does not exist\n" exit 1 } file stat $password_file fileinfo if { [expr ($fileinfo(mode) & 007)] != 0000 } { send_user "\nError: $password_file must not be world readable/writable\n" exit 1 } if [ catch {source $password_file} reason ] { send_user "\nError: $reason\n" exit 1 } } # Log into the router. # returns: 0 on success, 1 on failure proc login { router user userpswd passwd enapasswd cmethod cyphertype } { global spawn_id in_proc do_command do_script platform global prompt u_prompt p_prompt e_prompt sshcmd 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] { incr progs -1 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" return 1 } } elseif ![string compare $prog "ssh"] { regexp {ssh(:([^[:space:]]+))*} $prog methcmd suffix port set cmd $sshcmd if {"$port" != ""} { set cmd "$cmd -p $port" } set retval [ catch {eval spawn [split "$cmd -c $cyphertype -x -l $user $router" { }]} reason ] if { $retval } { send_user "\nError: $cmd failed: $reason\n" return 1 } } elseif ![string compare $prog "rsh"] { send_error "\nError: unsupported method: rsh\n" if { $progs == 0 } { return 1 } continue; } else { send_user "\nError: unknown connection method: $prog\n" return 1 } sleep 0.3 # This helps cleanup each expect clause. expect_after { timeout { send_user "\nError: TIMEOUT reached\n" catch {close}; catch {wait}; if { $in_proc} { return 1 } else { continue } } eof { send_user "\nError: EOF received\n" catch {close}; catch {wait}; if { $in_proc} { return 1 } else { continue } } } # Here we get a little tricky. There are several possibilities: # the router can ask for a username and passwd and then # talk to the TACACS server to authenticate you, or if the # TACACS server is not working, then it will use the enable # passwd. Or, the router might not have TACACS turned on, # then it will just send the passwd. # if telnet fails with connection refused, try ssh expect { -re "(Connection refused|Secure connection \[^\n\r]+ refused)" { catch {close}; catch {wait}; if !$progs { send_user "\nError: Connection Refused ($prog): $router\n" return 1 } } -re "(Connection closed by|Connection to \[^\n\r]+ closed)" { catch {close}; catch {wait}; if !$progs { send_user "\nError: Connection closed ($prog): $router\n" return 1 } } -re "Telnet server disabled" { catch {close}; catch {wait}; if !$progs { send_user "\nError: Connection Refused ($prog): $router\n" return 1 } } eof { send_user "\nError: Couldn't login\n"; wait; return 1 } -nocase "unknown host\r" { catch {close}; catch {wait}; send_user "\nError: Unknown host $router\n"; wait; return 1 } "Host is unreachable" { catch {close}; catch {wait}; send_user "\nError: Host Unreachable: $router\n"; wait; return 1 } "No address associated with name" { catch {close}; catch {wait}; send_user "\nError: Unknown host $router\n"; wait; return 1 } -re "(Host key not found |The authenticity of host .* be established).* \\(yes/no\\)\\?" { send -h "yes\r" send_user "\nHost $router added to the list of known hosts.\n" exp_continue } -re "HOST IDENTIFICATION HAS CHANGED.* \\(yes/no\\)\\?" { send -h "no\r" send_user "\nError: The host key for $router has changed. Update the SSH known_hosts file accordingly.\n" return 1 } -re "HOST IDENTIFICATION HAS CHANGED\[^\n\r]+" { send_user "\nError: The host key for $router has changed. Update the SSH known_hosts file accordingly.\n" return 1 } -re "Offending key for .* \\(yes/no\\)\\?" { send -h "no\r" send_user "\nError: host key mismatch for $router. Update the SSH known_hosts file accordingly.\n" return 1 } -re "(denied|Sorry)" { send_user "\nError: Check your passwd for $router\n" catch {close}; catch {wait}; return 1 } "Login failed" { send_user "\nError: Check your passwd for $router\n" return 1 } -re "% (Bad passwords|Authentication failed)" { send_user "\nError: Check your passwd for $router\n" return 1 } -re "@\[^\r\n]+ $p_prompt" { # ssh pwd prompt sleep 1 send -h -- "$userpswd\r" exp_continue } -re "$u_prompt" { send -h -- "$user\r" set uprompt_seen 1 exp_continue } -re "$p_prompt" { sleep 1 if {$uprompt_seen == 1} { send -h -- "$userpswd\r" } else { send -h -- "$passwd\r" } exp_continue } "$prompt" { break; } "Login invalid" { send_user "\nError: Invalid login: $router\n"; catch {close}; catch {wait}; return 1 } } } set in_proc 0 return 0 } # Enable proc do_enable { enauser enapasswd } { global prompt in_proc global u_prompt e_prompt set in_proc 1 sleep 1; # dont go too fast for it now... send -h "enable\r" expect { -re "$u_prompt" { send -h -- "$enauser\r"; exp_continue} -re "$e_prompt" { send -h -- "$enapasswd\r"; exp_continue} "#" { set prompt "#" } "(enable)" { set prompt "> (enable) " } denied { send_user "\nError: Check your Enable passwd\n"; return 1 } "Incorrect username or password" { send_user "\nError: Check your Enable passwd\n"; return 1 } "% Bad passwords" { send_user "\nError: Check your Enable passwd\n"; return 1 } } # We set the prompt variable (above) so script files don't need # to know what it is. 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 -h "skip-page-display\r" expect -re "$prompt" {} set commands [split $command \;] set num_commands [llength $commands] for {set i 0} {$i < $num_commands} { incr i} { send -h -- "[subst -nocommands [lindex $commands $i]]\r" expect { -re "^\[^\n\r]*$prompt." { exp_continue } -re "^\[^\n\r *]*$prompt" {} -re "\[\n\r]" { exp_continue } -- "---More---" { # EdgeIron cant disable pager send " " exp_continue } } } send -h "exit\r" expect { "\n" { exp_continue } -re "^\[^ ]+>" { send -h "exit\r" exp_continue } timeout { catch {close}; catch {wait}; 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 set exitval 0 foreach router [lrange $argv $i end] { set router [string tolower $router] send_user "$router\n" # device timeout set timeout [find timeout $router] if { [llength $timeout] == 0 } { set timeout $timeoutdflt } # Figure out prompt. # Since autoenable is off by default, if we have it defined, it # was done on the command line. If it is not specifically set on the # command line, check the password file. if $avautoenable { set autoenable 1 set enable 0 set prompt "#" } else { set ae [find autoenable $router] if { "$ae" == "1" } { set autoenable 1 set enable 0 set prompt "#" } else { set autoenable 0 set enable $avenable set prompt ">" } } # Figure out passwords if { $do_passwd || $do_enapasswd } { set pswd [find password $router] if { [llength $pswd] == 0 } { send_user "\nError: no password for $router in $password_file.\n" continue } if { $enable && $do_enapasswd && $autoenable == 0 && [llength $pswd] < 2 } { send_user "\nError: no enable password for $router in $password_file.\n" continue } set passwd [join [lindex $pswd 0] ""] set enapasswd [join [lindex $pswd 1] ""] } else { set passwd $userpasswd set enapasswd $enapasswd } # Figure out username if {[info exists username]} { # command line username set ruser $username } else { set ruser [join [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 [join [find userpassword $router] ""] if { "$userpswd" == "" } { set userpswd $passwd } } # Figure out enable username if {[info exists enausername]} { # command line enausername set enauser $enausername } else { set enauser [join [find enauser $router] ""] if { "$enauser" == "" } { set enauser $ruser } } # Figure out prompts set u_prompt [find userprompt $router] if { "$u_prompt" == "" } { set u_prompt "(Username|login|Name|User Name) *:" } else { set u_prompt [join [lindex $u_prompt 0] ""] } set p_prompt [find passprompt $router] if { "$p_prompt" == "" } { set p_prompt "(\[Pp]assword):" } else { set p_prompt [join [lindex $p_prompt 0] ""] } set e_prompt [find enableprompt $router] if { "$e_prompt" == "" } { set e_prompt "\[Pp]assword:" } else { set e_prompt [join [lindex $e_prompt 0] ""] } # Figure out cypher tpye 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}} } # Figure out the SSH executable name set sshcmd [join [lindex [find sshcmd $router] 0] ""] if { "$sshcmd" == "" } { set sshcmd {ssh} } # Login to the router if {[login $router $ruser $userpswd $passwd $enapasswd $cmethod $cyphertype]} { incr exitval continue } if { $enable } { if {[do_enable $enauser $enapasswd]} { if { $do_command || $do_script } { incr exitval catch {close}; catch {wait}; continue } } } # we are logged in, now figure out the full prompt send -h "\r" expect { -re "\[\r\n]+" { exp_continue; } -re "^.+$prompt" { set junk $expect_out(0,string); regsub -all "\[\]\[ ]" $junk {\\&} prompt; } } if { $do_command } { if {[run_commands $prompt $command]} { incr exitval continue } } elseif { $do_script } { # fucking foundry send -h "skip-page-display\r" expect -re $prompt {} source $sfile catch {close}; } else { label $router log_user 1 interact } # End of for each router catch {wait}; sleep 0.3 } exit $exitval rancid-2.3.8/bin/fnlogin.in100644 015615 000000 00000041526 11712066167 0011231#! @EXPECT_PATH@ -- ## ## $Id: fnlogin.in,v 1.51 2009/04/16 21:22:58 heas Exp $ ## patched to accomplish fortinet from nlogin ## by: Daniel G. Epstein ## adapted by: Diego Ercolani ## ## @PACKAGE@ @VERSION@ ## Copyright (c) @COPYYEARS@ by Terrapin Communications, Inc. ## All rights reserved. ## ## This code is derived from software contributed to and maintained by ## Terrapin Communications, Inc. by Henry Kilmer, John Heasley, Andrew Partan, ## Pete Whiting, Austin Schutz, and Andrew Fort. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions ## are met: ## 1. Redistributions of source code must retain the above copyright ## notice, this list of conditions and the following disclaimer. ## 2. Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## 3. All advertising materials mentioning features or use of this software ## must display the following acknowledgement: ## This product includes software developed by Terrapin Communications, ## Inc. and its contributors for RANCID. ## 4. Neither the name of Terrapin Communications, Inc. nor the names of its ## contributors may be used to endorse or promote products derived from ## this software without specific prior written permission. ## 5. It is requested that non-binding fixes and modifications be contributed ## back to Terrapin Communications, Inc. ## ## THIS SOFTWARE IS PROVIDED BY Terrapin Communications, INC. AND CONTRIBUTORS ## ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ## TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COMPANY OR CONTRIBUTORS ## BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ## CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ## SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ## INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ## CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ## ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ## POSSIBILITY OF SUCH DAMAGE. # # The expect login scripts were based on Erik Sherk's gwtn, by permission. # # Netscreen hacks implemented by Stephen Gill . # Fortinet hacks by Daniel G. Epstein # # fnlogin - fortinet login # # Most options are intuitive for logging into a netscreen firewall. # # Misc notes # netscreen does not have the concept of "enable", once logged in, a # users permissions can not change. # Usage line set usage "Usage: $argv0 \[-dSV\] \[-c command\] \[-Evar=x\] \ \[-f cloginrc-file\] \[-p user-password\] \ \[-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 firewall set do_command 0 set do_script 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 set do_enapasswd 1 # Save config, if prompted set do_saveconfig 0 # 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) } elseif {[ info exists env(LOGNAME) ]} { set default_user $env(LOGNAME) } 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 "\nError: could not exec id: $reason\n" exit 1 } regexp {\(([^)]*)} "$reason" junk default_user } if {[ info exists env(CLOGINRC) ]} { set password_file $env(CLOGINRC) } # Sometimes firewall 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 { # Expect debug mode -d* { exp_internal 1 # Username } -u* { if {! [ regexp .\[uU\](.+) $arg ignore user]} { incr i set username [ lindex $argv $i ] } # VTY Password } -p* { if {! [ regexp .\[pP\](.+) $arg ignore userpasswd]} { incr i set userpasswd [ lindex $argv $i ] } set do_passwd 0 # Environment variable to pass to -s scripts } -E* { if {[ regexp .\[E\](.+)=(.+) $arg ignore varname varvalue]} { set E$varname $varvalue } else { send_user "\nError: invalid format for -E in $arg\n" exit 1 } # Command to run. } -c* { if {! [ regexp .\[cC\](.+) $arg ignore command]} { incr i set command [ lindex $argv $i ] } set do_command 1 # Expect script to run. } -s* { if {! [ regexp .\[sS\](.+) $arg ignore sfile]} { incr i set sfile [ lindex $argv $i ] } if { ! [ file readable $sfile ] } { send_user "\nError: Can't read $sfile\n" exit 1 } set do_script 1 # save config on exit } -S* { set do_saveconfig 1 # cypher type } -y* { if {! [ regexp .\[eE\](.+) $arg ignore cypher]} { incr i set cypher [ lindex $argv $i ] } # alternate cloginrc file } -f* { if {! [ regexp .\[fF\](.+) $arg ignore password_file]} { incr i set password_file [ lindex $argv $i ] } } -t* { incr i set timeout [ lindex $argv $i ] } -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 # Version string } -V* { send_user "@PACKAGE@ @VERSION@\n" exit 0 # Does tacacs automatically enable us? } -autoenable { # ignore autoenable } -* { send_user "\nError: Unknown argument! $arg\n" send_user $usage exit 1 } default { break } } } # Process firewalls...no firewalls listed is an error. if { $i == $argc } { send_user "\nError: $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 "\nError: password file ($password_file) does not exist\n" exit 1 } file stat $password_file fileinfo if { [expr ($fileinfo(mode) & 007)] != 0000 } { send_user "\nError: $password_file must not be world readable/writable\n" exit 1 } if [ catch {source $password_file} reason ] { send_user "\nError: $reason\n" exit 1 } } # Log into the firewall. # returns: 0 on success, 1 on failure proc login { router user userpswd passwd enapasswd prompt cmethod cyphertype } { global spawn_id in_proc do_command do_script sshcmd set in_proc 1 set uprompt_seen 0 # Telnet to the firewall & try to login. set progs [llength $cmethod] foreach prog [lrange $cmethod 0 end] { incr progs -1 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" return 1 } } elseif [string match "ssh*" $prog] { regexp {ssh(:([^[:space:]]+))*} $prog methcmd suffix port set cmd $sshcmd if {"$port" == ""} { set cmd "$cmd -p $port" } set retval [ catch {eval spawn [split "$cmd -c $cyphertype -x -l $user $router" { }]} reason ] if { $retval } { send_user "\nError: $cmd failed: $reason\n" return 1 } } elseif ![string compare $prog "rsh"] { send_error "\nError: unsupported method: rsh\n" if { $progs == 0 } { return 1 } continue; } else { send_user "\nError: unknown connection method: $prog\n" return 1 } sleep 0.3 # This helps cleanup each expect clause. expect_after { timeout { send_user "\nError: TIMEOUT reached\n" catch {close}; catch {wait}; if { $in_proc} { return 1 } else { continue } } eof { send_user "\nError: EOF received\n" catch {close}; catch {wait}; if { $in_proc} { return 1 } else { continue } } } # Here we get a little tricky. There are several possibilities: # the firewall can ask for a username and passwd and then # talk to the TACACS server to authenticate you, or if the # TACACS server is not working, then it will use the enable # passwd. Or, the firewall might not have TACACS turned on, # then it will just send the passwd. # if telnet fails with connection refused, try ssh expect { -re "(Connection refused|Secure connection \[^\n\r]+ refused)" { catch {close}; catch {wait}; if !$progs { send_user "\nError: Connection Refused ($prog): $router\n" return 1 } } -re "(Connection closed by|Connection to \[^\n\r]+ closed)" { catch {close}; catch {wait}; if !$progs { send_user "\nError: Connection closed ($prog): $router\n" return 1 } } eof { send_user "\nError: Couldn't login: $router\n"; wait; return 1 } -nocase "unknown host\r" { send_user "\nError: Unknown host $router\n"; catch {close}; catch {wait}; return 1 } "Host is unreachable" { send_user "\nError: Host Unreachable: $router\n"; catch {close}; catch {wait}; return 1 } "No address associated with name" { send_user "\nError: Unknown host $router\n"; catch {close}; catch {wait}; return 1 } -re "(Host key not found |The authenticity of host .* be established).* \\(yes/no\\)\\?" { send "yes\r" send_user "\nHost $router added to the list of known hosts.\n" exp_continue } -re "HOST IDENTIFICATION HAS CHANGED.* \\(yes/no\\)\\?" { send "no\r" send_user "\nError: The host key for $router has changed. Update the SSH known_hosts file accordingly.\n" catch {close}; catch {wait}; return 1 } -re "HOST IDENTIFICATION HAS CHANGED\[^\n\r]+" { send_user "\nError: The host key for $router has changed. Update the SSH known_hosts file accordingly.\n" return 1 } -re "Offending key for .* \\(yes/no\\)\\?" { send "no\r" send_user "\nError: host key mismatch for $router. Update the SSH known_hosts file accordingly.\n" catch {close}; catch {wait}; return 1 } -re "(denied|Sorry)" { send_user "\nError: Check your passwd for $router\n" catch {close}; catch {wait}; return 1 } "Login failed" { send_user "\nError: Check your passwd for $router\n"; catch {close}; catch {wait}; return 1 } -re "(login:)" { sleep 1; send -- "$user\r" set uprompt_seen 1 exp_continue } -re "@\[^\r\n]+\[Pp]assword:" { # ssh pwd prompt sleep 1 send -- "$userpswd\r" exp_continue } "\[Pp]assword:" { sleep 1; if {$uprompt_seen == 1} { send -- "$userpswd\r" } else { send -- "$passwd\r" } exp_continue } -- "$prompt" { break; } } } 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 # Disable output paging. send -- "config system console\r" expect -re $prompt; send -- "set output standard\r" expect -re $prompt; send -- "end\r" expect -re $prompt; 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 "$prompt" { send "\r" sleep 0.5 } -gl "--More--" { send " " exp_continue -re "\[\n\r]+" { exp_continue } } } } expect { -re "$prompt$" { send "exit\r" sleep 0.5 exp_continue } -re "\[\n\r]+" { exp_continue } -gl "Configuration modified, save?" { send "n\r" exp_continue } timeout { catch {close}; catch {wait}; return 0 } eof { return 0 } } set in_proc 0 } # # For each firewall... (this is main loop) # source_password_file $password_file set in_proc 0 set exitval 0 foreach router [lrange $argv $i end] { set router [string tolower $router] send_user "$router\n" # FortiOS 2.x prompts can end in either '#' or '$' set prompt "\[#\\$] " # Figure out passwords if { $do_passwd || $do_enapasswd } { set pswd [find password $router] if { [llength $pswd] == 0 } { send_user "\nError: no password for $router in $password_file.\n" continue } set passwd [join [lindex $pswd 0] ""] set enapasswd [join [lindex $pswd 1] ""] } else { set passwd $userpasswd set enapasswd $enapasswd } # Figure out username if {[info exists username]} { # command line username set ruser $username } else { set ruser [join [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 [join [find userpassword $router] ""] if { "$userpswd" == "" } { set userpswd $passwd } } # 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}} } # Figure out the SSH executable name set sshcmd [join [lindex [find sshcmd $router] 0] ""] if { "$sshcmd" == "" } { set sshcmd {ssh} } # Login to the router if {[login $router $ruser $userpswd $passwd $enapasswd $prompt $cmethod $cyphertype]} { incr exitval continue } # we are logged in, now figure out the full prompt based on what the # device sends us. send "\r" expect { -re "\[\r\n]+" { exp_continue; } -re "^(.+$prompt)" { set junk $expect_out(0,string); } if {[$junk = "(^\\$ $)"]} { set prompt $junk; } else { if {[$junk = "(^# $)"]} { set prompt $junk ; } }; } if { $do_command } { if {[run_commands $prompt $command]} { incr exitval continue } } elseif { $do_script } { # Disable output paging. send "config system console\r" send "set output standard\r" send "end\r" expect -re $prompt {} source $sfile catch {close}; } else { label $router log_user 1 interact } # End of for each firewall catch {wait}; sleep 0.3 } exit $exitval rancid-2.3.8/bin/fnrancid.in100644 015615 000000 00000024377 11535733223 0011363#! @PERLV_PATH@ ## ## $Id: fnrancid.in 2283 2011-02-04 23:15:07Z heas $ ## ## @PACKAGE@ @VERSION@ ## Copyright (c) 1997-2008 by Terrapin Communications, Inc. ## All rights reserved. ## ## This code is derived from software contributed to and maintained by ## Terrapin Communications, Inc. by Henry Kilmer, John Heasley, Andrew Partan, ## Pete Whiting, Austin Schutz, and Andrew Fort. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions ## are met: ## 1. Redistributions of source code must retain the above copyright ## notice, this list of conditions and the following disclaimer. ## 2. Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## 3. All advertising materials mentioning features or use of this software ## must display the following acknowledgement: ## This product includes software developed by Terrapin Communications, ## Inc. and its contributors for RANCID. ## 4. Neither the name of Terrapin Communications, Inc. nor the names of its ## contributors may be used to endorse or promote products derived from ## this software without specific prior written permission. ## 5. It is requested that non-binding fixes and modifications be contributed ## back to Terrapin Communications, Inc. ## ## THIS SOFTWARE IS PROVIDED BY Terrapin Communications, INC. AND CONTRIBUTORS ## ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ## TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COMPANY OR CONTRIBUTORS ## BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ## CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ## SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ## INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ## CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ## ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ## POSSIBILITY OF SUCH DAMAGE. # # A library built on Stephen Gill's Netscreen stuff to accomodate # the Fortinet product line. [d_pfleger@juniper.net] # # RANCID - Really Awesome New Cisco confIg Differ # # usage: rancid [-dV] [-l] [-f filename | hostname] # use Getopt::Std; getopts('dflV'); if ($opt_V) { print "@PACKAGE@ @VERSION@\n"; exit(0); } $log = $opt_l; $debug = $opt_d; #$debug = 1; $file = $opt_f; $host = $ARGV[0]; $found_end = 0; $timeo = 90; # fnlogin timeout in seconds my(@commandtable, %commands, @commands);# command lists my($aclsort) = ("ipsort"); # ACL sorting mode my($filter_commstr); # SNMP community string filtering 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)) && scalar(%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 routine 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 routine 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 routine 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 routine (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 "get system" sub GetSystem { print STDERR " In GetSystem: $_" if ($debug); while () { tr/\015//d; next if /^\s*$/; last if (/$prompt/); next if (/^system time:/i); next if (/^\s*Virus-DB: .*/); next if (/^\s*Extended DB: .*/); next if (/^\s*IPS-DB: .*/); next if (/^FortiClient application signature package:/); ProcessHistory("","","","#$_"); } ProcessHistory("SYSTEM","","","\n"); return(0); } sub GetFile { print STDERR " In GetFile: $_" if ($debug); while () { last if (/$prompt/); } ProcessHistory("FILE","","","\n"); return(0); } sub GetConf { print STDERR " In GetConf: $_" if ($debug); while () { tr/\015//d; next if /^\s*$/; last if (/$prompt/); # System time is fortigate extraction time next if (/^\s*!System time:/); # remove occurrances of conf_file_ver next if (/^#?conf_file_ver=/); # filter variabilities between configurations. password encryption # upon each display of the configuration. if (/^\s*(set [^\s]*)\s(Enc\s[^\s]+)(.*)/i && $filter_pwds > 0 ) { ProcessHistory("ENC","","","#$1 ENC $3\n"); next; } ProcessHistory("","","","$_"); } $found_end = 1; return(1); } # dummy function sub DoNothing {print STDOUT;} # Main @commandtable = ( {'get system status' => 'GetSystem'}, {'show full-configuration' => 'GetConf'} ); # 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("|", map quotemeta($_), @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 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 fnlogin -t $timeo -c\"$cisco_cmds\" $host\n" if ($debug); print STDOUT "executing fnlogin -t $timeo -c\"$cisco_cmds\" $host\n" if ($log); if (defined($ENV{NOPIPE}) && $ENV{NOPIPE} =~ /^YES/i) { system "fnlogin -t $timeo -c \"$cisco_cmds\" $host $host.raw 2>&1" || die "fnlogin failed for $host: $!\n"; open(INPUT, "< $host.raw") || die "fnlogin failed for $host: $!\n"; } else { open(INPUT,"fnlogin -t $timeo -c \"$cisco_cmds\" $host ) { tr/\015//d; if (/^Error:/) { print STDOUT ("$host fnlogin error: $_"); print STDERR ("$host fnlogin error: $_") if ($debug); last; } while (/^.+(#|\$)\s*($cmds_regexp)\s*$/) { $cmd = $2; # - FortiGate prompts end with either '#' or '$'. Further, they may # be prepended with a '~' if the hostname is too long. Therefore, # we need to figure out what our prompt really is. if (!defined($prompt)) { if ($_ =~ m/^.+\~\$/) { $prompt = '\~\$ .*'; } else { if ($_ =~ m/^.+\$/) { $prompt = ' \$ .*'; } else { if ($_ =~ m/^.+\~#/) { $prompt = '\~# .*'; } else { if ($_ =~ m/^.+#/) { $prompt = ' # .*'; } } } } } print STDERR ("HIT COMMAND:$_") if ($debug); if (!defined($commands{$cmd})) { print STDERR "$host: found unexpected command - \"$cmd\"\n"; last TOP; } $rval = &{$commands{$cmd}}; delete($commands{$cmd}); if ($rval == -1) { last TOP; } } } print STDOUT "Done $logincmd: $_\n" if ($log); # Flush History ProcessHistory("","","",""); # Cleanup close(INPUT); close(OUTPUT); if (defined($ENV{NOPIPE}) && $ENV{NOPIPE} =~ /^YES/i) { unlink("$host.raw") if (! $debug); } # check for completeness if (scalar(%commands) || !$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 (!$found_end) { print STDOUT "$found_end: found end\n"; 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); } rancid-2.3.8/bin/francid.in100644 015615 000000 00000036600 11535733223 0011175#! @PERLV_PATH@ ## ## $Id: francid.in 2279 2011-01-31 22:41:00Z heas $ ## ## @PACKAGE@ @VERSION@ ## Copyright (c) 1997-2008 by Terrapin Communications, Inc. ## All rights reserved. ## ## This code is derived from software contributed to and maintained by ## Terrapin Communications, Inc. by Henry Kilmer, John Heasley, Andrew Partan, ## Pete Whiting, Austin Schutz, and Andrew Fort. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions ## are met: ## 1. Redistributions of source code must retain the above copyright ## notice, this list of conditions and the following disclaimer. ## 2. Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## 3. All advertising materials mentioning features or use of this software ## must display the following acknowledgement: ## This product includes software developed by Terrapin Communications, ## Inc. and its contributors for RANCID. ## 4. Neither the name of Terrapin Communications, Inc. nor the names of its ## contributors may be used to endorse or promote products derived from ## this software without specific prior written permission. ## 5. It is requested that non-binding fixes and modifications be contributed ## back to Terrapin Communications, Inc. ## ## THIS SOFTWARE IS PROVIDED BY Terrapin Communications, INC. AND CONTRIBUTORS ## ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ## TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COMPANY OR CONTRIBUTORS ## BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ## CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ## SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ## INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ## CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ## ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ## POSSIBILITY OF SUCH DAMAGE. # # Amazingly hacked version of Hank's rancid - this one tries to # deal with foundrys and foundrys OEM'd by HP as Procurves. # # RANCID - Really Awesome New Cisco confIg Differ # # usage: rancid [-dV] [-l] [-f filename | hostname] # use Getopt::Std; 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; # flogin timeout in seconds my(@commandtable, %commands, @commands);# command lists my($aclsort) = ("ipsort"); # ACL sorting mode my($filter_commstr); # SNMP community string filtering 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)) && scalar(%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 routine 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 routine 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 routine 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 routine (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 "show version" sub ShowVersion { my($slot); print STDERR " In ShowVersion: $_" if ($debug); while () { tr/\015//d; next if /^\s*$/; last if (/^$prompt/); next if (/^(The system |Crash time)/); next if (/^(System|(Active|Standby) Management|LP Slot \d+) uptime is/); # remove uptime on newer switches s/(STACKID \d+)\s+system uptime is.*$/$1/; s/^\s*(HW|SW)/$1/; s/^\s*(Compiled on)/SW: $1/; s/^\s*(\(\d+ bytes\) from )/SW: $1/; #s/^(HW.*)/$1\n/; if (/^SL (\d+)/) { $slot = "Slot $1"; s/^SL \d+/$slot/; } if (/MHz .* processor/) { $slot = "MGMT"; } s/^(\s*\d+ )/$slot:$1/; s/^===*//; ProcessHistory("VERSION","","","!$_"); } ProcessHistory("VERSION","","","!\n"); return(0); } # This routine parses "show chassis" sub ShowChassis { my($skip) = 0; print STDERR " In ShowChassis: $_" if ($debug); while () { tr/\015//d; last if (/^$prompt/); next if (/ from /); next if (/current temperature/i); return(1) if (/^\s+\^$/); # edgeiron invalid command if (/^---/ || /^$/) { # next section reached $skip = 0; } if (/(POWERS|TEMPERATURE READINGS)/) { $skip = 1; } if (/fan controlled temperature:/i || /fan speed switching temperature thresholds/i) { $skip = 1; } if (/THERMAL PLANE/) { $skip = 1; } if (/temperature:/i) { $skip = 1; } s/(Fan \d+ \S+), speed .*/$1/; if (/speed/i) { $skip = 1; } next if $skip; ProcessHistory("CHASSIS","","","! $_"); } ProcessHistory("CHASSIS","","","!\n"); return(0); } # This routine parses "show flash" sub ShowFlash { print STDERR " In ShowFlash: $_" if ($debug); while () { tr/\015//d; last if (/^$prompt/); next if (/^\s*$/); return(1) if (/^\s+\^$/); # edgeiron invalid command ProcessHistory("FLASH","","","!Flash: $_"); } ProcessHistory("","","","!\n"); return; } # This routine parses "show module" sub ShowModule { print STDERR " In ShowModule: $_" if ($debug); while () { tr/\015//d; last if (/^$prompt/); return(1) if (/Invalid input (->|detected)/); return(1) if (/^\s+\^$/); # edgeiron invalid command next if (/^\s*$/); next if (/:\s*$/); ProcessHistory("MODULE","","","!Module: $_"); } ProcessHistory("","","","!\n"); return(0); } # This routine processes a "write term" sub WriteTerm { print STDERR " In WriteTerm: $_" if ($debug); while () { tr/\015//d; return(1) if (/Invalid input (->|detected)/); return(1) if (/^\s+\^$/); # edgeiron invalid command return(0) if ($found_end); # Only do this routine once last if (/^$prompt/); /current configuration\s*:/i && next; /building configuration\.+\s*/i && next; /building running-config, please wait/i && next; # edgeiron /^ver \d+\.\d+/ && next; /^module \d+ / && next; /^ntp clock-period / && next; # kill ntp clock-period /^ length / && next; # kill length on serial lines /^ width / && next; # kill width on serial lines # filter out any RCS/CVS tags to avoid confusing local CVS storage s/\$(Revision|Id):/ $1:/; # sort secure-mac-addresses. Note: There is no way to determine which # have been added dynamically vs statically. Thus, sort them? /secure-mac-address (\S+)/ && ProcessHistory("SECMAC","keysort","$1","$_") && next; # OR filter them? XXX #next if (/secure-mac-address/); # order access-lists /^access-list\s+(\d+)\s+(perm|deny)\s+(\d\S+)(\/\d+)\s*$/ && ProcessHistory("PACL $1 $2","$aclsort","$3","$_") && next; /^access-list\s+(\d\d?)\s+(\S+)\s+(\S+)/ && ProcessHistory("ACL $1 $2","$aclsort","$3","$_") && next; # order extended access-lists /^access-list\s+(\d\d\d)\s+(\S+)\s+ip\s+host\s+(\S+)/ && ProcessHistory("EACL $1 $2","$aclsort","$3","$_") && next; /^access-list\s+(\d\d\d)\s+(\S+)\s+ip\s+(\d\S+)/ && ProcessHistory("EACL $1 $2","$aclsort","$3","$_") && next; /^access-list\s+(\d\d\d)\s+(\S+)\s+ip\s+any/ && ProcessHistory("EACL $1 $2","$aclsort","0.0.0.0","$_") && next; # order arp lists /^arp\s+(\d+\.\d+\.\d+\.\d+)\s+/ && ProcessHistory("ARP","$aclsort","$1","$_") && next; # order logging statements /^logging (\d+\.\d+\.\d+\.\d+)/ && ProcessHistory("LOGGING","ipsort","$1","$_") && next; # order/prune snmp-server host/community statements if (/^(snmp-server host )(\d+\.\d+\.\d+\.\d+)/) { if ($filter_commstr) { ProcessHistory("SNMPSERVERHOST","ipsort","$2","!$1 $2 \n") && next; } else { ProcessHistory("SNMPSERVERHOST","ipsort","$2","$_") && next; } } if (/^(snmp-server community )(\S+)/) { if ($filter_commstr) { ProcessHistory("SNMPSERVERCOMM","keysort","$_","!$1$'") && next; } else { ProcessHistory("SNMPSERVERCOMM","keysort","$_","$_") && next; } } # order tacacs server statements if (/^(tacacs-server key )/ && $filter_pwds >= 1) { ProcessHistory("","","","! $1\n"); next; } # delete ntp auth password if (/^(ntp authentication-key \d+ md5) / && $filter_pwds >= 2) { ProcessHistory("","","","!$1 \n"); next; } # order ntp peers/servers if (/^ntp (server|peer) (\d+)\.(\d+)\.(\d+)\.(\d+)/) { $sortkey = sprintf("$1 %03d%03d%03d%03d",$2,$3,$4,$5); ProcessHistory("NTP","keysort",$sortkey,"$_"); next; } # order ip host line statements /^ip host line(\d+)/ && ProcessHistory("IPHOST","numsort","$1","$_") && next; # order ip nat source static statements /^ip nat (\S+) source static (\S+)/ && ProcessHistory("IP NAT $1","ipsort","$2","$_") && next; # filter ssh public key if (/^(crypto key generate (rsa|dsa) public_key)/ && $filter_pwds >= 2) { ProcessHistory("","","","!$1 \n"); next; } # filter ssh private key if (/^(crypto key generate (rsa|dsa) private_key)/ && $filter_pwds >= 1) { ProcessHistory("","","","!$1 \n"); next; } # filter ssl secret if (/^(crypto-ssl certificate generate secret_data)/ && $filter_pwds >= 1) { ProcessHistory("","","","!$1 \n"); next; } # reorder listing of ports in a vlan if (/^ (?:un)?tagged ethe/) { chomp; s/^\s+//; s/\s+$//; my @list = split /\s+ethe\s+/, $_; my $tagtype = shift @list; while (@list) { ProcessHistory("","","", " $tagtype ethe " . (shift @list) . "\n"); } next; } ProcessHistory("","","","$_"); # end of config if (/^end$/) { $found_end = 1; return(1); } } return(0); } # dummy function sub DoNothing {print STDOUT;} # Main @commandtable = ( {'show version' => 'ShowVersion'}, {'show chassis' => 'ShowChassis'}, {'show module' => 'ShowModule'}, {'show flash' => 'ShowFlash'}, {'write term' => 'WriteTerm'}, {'show running-config' => 'WriteTerm'}, ); # 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("|", map quotemeta($_), @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 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 flogin -t $timeo -c\"$cisco_cmds\" $host\n" if ($debug); print STDOUT "executing flogin -t $timeo -c\"$cisco_cmds\" $host\n" if ($log); if (defined($ENV{NOPIPE}) && $ENV{NOPIPE} =~ /^YES/i) { system "flogin -t $timeo -c \"$cisco_cmds\" $host $host.raw 2>&1" || die "flogin failed for $host: $!\n"; open(INPUT, "< $host.raw") || die "flogin failed for $host: $!\n"; } else { open(INPUT,"flogin -t $timeo -c \"$cisco_cmds\" $host ) { tr/\015//d; if (/\#exit$/) { $clean_run=1; last; } if (/^Error:/) { print STDOUT ("$host flogin error: $_"); print STDERR ("$host flogin error: $_") if ($debug); $clean_run=0; last; } while (/#\s*($cmds_regexp)\s*$/) { $cmd = $1; 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; } $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}) && $ENV{NOPIPE} =~ /^YES/i) { 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 STDERR "$host: End of run not found $clean_run || $found_end\n"; 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); } rancid-2.3.8/bin/hlogin.in100644 015615 000000 00000054711 11712067106 0011047#! @EXPECT_PATH@ -- ## ## $Id: hlogin.in 2376 2012-01-31 22:42:14Z heas $ ## ## @PACKAGE@ @VERSION@ ## Copyright (c) @COPYYEARS@ by Terrapin Communications, Inc. ## All rights reserved. ## ## This code is derived from software contributed to and maintained by ## Terrapin Communications, Inc. by Henry Kilmer, John Heasley, Andrew Partan, ## Pete Whiting, Austin Schutz, and Andrew Fort. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions ## are met: ## 1. Redistributions of source code must retain the above copyright ## notice, this list of conditions and the following disclaimer. ## 2. Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## 3. All advertising materials mentioning features or use of this software ## must display the following acknowledgement: ## This product includes software developed by Terrapin Communications, ## Inc. and its contributors for RANCID. ## 4. Neither the name of Terrapin Communications, Inc. nor the names of its ## contributors may be used to endorse or promote products derived from ## this software without specific prior written permission. ## 5. It is requested that non-binding fixes and modifications be contributed ## back to Terrapin Communications, Inc. ## ## THIS SOFTWARE IS PROVIDED BY Terrapin Communications, INC. AND CONTRIBUTORS ## ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ## TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COMPANY OR CONTRIBUTORS ## BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ## CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ## SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ## INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ## CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ## ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ## POSSIBILITY OF SUCH DAMAGE. # # The expect login scripts were based on Erik Sherk's gwtn, by permission. # # hlogin - hp login # # Most options are intuitive for logging into a Cisco router. # The default is to enable (thus -noenable). Some folks have # setup tacacs to have a user login at priv-lvl = 15 (enabled) # so the -autoenable flag was added for this case (don't go through # the process of enabling and the prompt will be the "#" prompt. # The default username password is the same as the vty password. # # Usage line set usage "Usage: $argv0 \[-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\] 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 avenable 1 # The default is that you login non-enabled (tacacs can have you login already # enabled) set avautoenable 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 set do_enapasswd 1 # Save config, if prompted set do_saveconfig 0 # Sometimes routers take awhile to answer (the default is 10 sec) set timeoutdflt 45 # set send_human {.2 .1 .4 .2 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) } elseif {[ info exists env(LOGNAME) ]} { set default_user $env(LOGNAME) } 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 "\nError: could not exec id: $reason\n" exit 1 } regexp {\(([^)]*)} "$reason" junk default_user } if {[ info exists env(CLOGINRC) ]} { set password_file $env(CLOGINRC) } # Process the command line for {set i 0} {$i < $argc} {incr i} { set arg [lindex $argv $i] switch -glob -- $arg { # Expect debug mode -d* { exp_internal 1 # Username } -u* { if {! [ regexp .\[uU\](.+) $arg ignore user]} { incr i set username [ lindex $argv $i ] } # VTY Password } -p* { if {! [ regexp .\[pP\](.+) $arg ignore userpasswd]} { incr i set userpasswd [ lindex $argv $i ] } set do_passwd 0 # ssh passphrase } -r* { if {! [ regexp .\[rR\](.+) $arg ignore passphrase]} { incr i set vapassphrase [ lindex $argv $i ] } # VTY Password } -v* { if {! [ regexp .\[vV\](.+) $arg ignore passwd]} { incr i set passwd [ lindex $argv $i ] } set do_passwd 0 # Version string } -V* { send_user "@PACKAGE@ @VERSION@\n" exit 0 # Enable Username } -w* { if {! [ regexp .\[wW\](.+) $arg ignore enauser]} { incr i set enausername [ lindex $argv $i ] } # Environment variable to pass to -s scripts } -E* { if {[ regexp .\[E\](.+)=(.+) $arg ignore varname varvalue]} { set E$varname $varvalue } else { send_user "\nError: invalid format for -E in $arg\n" exit 1 } # Enable Password } -e* { if {! [ regexp .\[e\](.+) $arg ignore enapasswd]} { incr i set enapasswd [ lindex $argv $i ] } set do_enapasswd 0 # Command to run. } -c* { if {! [ regexp .\[cC\](.+) $arg ignore command]} { incr i set command [ lindex $argv $i ] } set do_command 1 # Expect script to run. } -s* { if {! [ regexp .\[sS\](.+) $arg ignore sfile]} { incr i set sfile [ lindex $argv $i ] } if { ! [ file readable $sfile ] } { send_user "\nError: Can't read $sfile\n" exit 1 } set do_script 1 # save config on exit } -S* { set do_saveconfig 1 # 'ssh -c' cypher type } -y* { if {! [ regexp .\[eE\](.+) $arg ignore cypher]} { incr i set cypher [ lindex $argv $i ] } # alternate cloginrc file } -f* { if {! [ regexp .\[fF\](.+) $arg ignore password_file]} { incr i set password_file [ lindex $argv $i ] } # Timeout } -t* { if {! [ regexp .\[tT\](.+) $arg ignore timeout]} { incr i set timeoutdflt [ lindex $argv $i ] } # Command file } -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 { set avenable 0 # Does tacacs automatically enable us? } -autoenable { set avautoenable 1 set avenable 0 } -* { send_user "\nError: Unknown argument! $arg\n" send_user $usage exit 1 } default { break } } } # Process routers...no routers listed is an error. if { $i == $argc } { send_user "\nError: $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 "\nError: password file ($password_file) does not exist\n" exit 1 } file stat $password_file fileinfo if { [expr ($fileinfo(mode) & 007)] != 0000 } { send_user "\nError: $password_file must not be world readable/writable\n" exit 1 } if [ catch {source $password_file} reason ] { send_user "\nError: $reason\n" exit 1 } } # Log into the router. # returns: 0 on success, 1 on failure proc login { router user userpswd passwd enapasswd cmethod cyphertype identfile } { global spawn_id in_proc do_command do_script passphrase global prompt u_prompt p_prompt e_prompt sshcmd set in_proc 1 # try each of the connection methods in $cmethod until one is successful set progs [llength $cmethod] foreach prog [lrange $cmethod 0 end] { incr progs -1 regexp {(telnet|ssh)(:([^[:space:]]+))*} $prog command suffix junk port if [string match "telnet*" $prog] { if {"$port" == ""} { set retval [ catch {spawn hpuifilter -- telnet $router} reason ] } else { set retval [ catch {spawn hpuifilter -- telnet $router $port} reason ] } if { $retval } { send_user "\nError: telnet failed: $reason\n" return 1 } } elseif [string match "ssh*" $prog] { # ssh to the router & try to login with or without an identfile. regexp {ssh(:([^[:space:]]+))*} $prog methcmd suffix port set cmd $sshcmd if {"$port" != ""} { set cmd "$cmd -p $port" } if {"$identfile" != ""} { set cmd "$cmd -i $identfile" } set retval [ catch {eval spawn hpuifilter -- [split "$cmd -c $cyphertype -x -l $user $router" { }]} reason ] if { $retval } { send_user "\nError: $cmd failed: $reason\n" return 1 } } elseif ![string compare $prog "rsh"] { send_error "\nError: unsupported method: rsh\n" if { $progs == 0 } { return 1 } continue; } else { send_user "\nError: unknown connection method: $prog\n" return 1 } sleep 0.3 # This helps cleanup each expect clause. expect_after { timeout { send_user "\nError: TIMEOUT reached\n" catch {close}; catch {wait}; if { $in_proc} { return 1 } else { continue } } eof { send_user "\nError: EOF received\n" catch {close}; catch {wait}; if { $in_proc} { return 1 } else { continue } } } # Here we get a little tricky. There are several possibilities: # the router can ask for a username and passwd and then # talk to the TACACS server to authenticate you, or if the # TACACS server is not working, then it will use the enable # passwd. Or, the router might not have TACACS turned on, # then it will just send the passwd. # if telnet fails with connection refused, try ssh expect { "Press any key to continue" { send " " exp_continue } "Enter switch number to connect to or :" { send "\r" exp_continue } -re "(Connection refused|Secure connection \[^\n\r]+ refused|Connection closed by)" { catch {close}; catch {wait}; if !$progs { send_user "\nError: Connection Refused ($prog)\n"; return 1 } } "Host is unreachable" { catch {close}; catch {wait}; send_user "\nError: Host Unreachable!\n"; wait; return 1 } "No address associated with name" { catch {close}; catch {wait}; send_user "\nError: Unknown host\n"; wait; return 1 } -re "(Host key not found |The authenticity of host .* be established).* \\(yes/no\\)\\?" { send "yes\r" send_user "\nHost $router added to the list of known hosts.\n" exp_continue } -re "HOST IDENTIFICATION HAS CHANGED.* \\(yes/no\\)\\?" { send "no\r" send_user "\nError: The host key for $router has changed. Update the SSH known_hosts file accordingly.\n" return 1 } -re "HOST IDENTIFICATION HAS CHANGED\[^\n\r]+" { send_user "\nError: The host key for $router has changed. Update the SSH known_hosts file accordingly.\n" return 1 } -re "Offending key for .* \\(yes/no\\)\\?" { send "no\r" send_user "\nError: host key mismatch for $router. Update the SSH known_hosts file accordingly.\n" return 1 } eof { send_user "\nError: Couldn't login\n"; wait; return 1 } -nocase "unknown host\r" { catch {close}; catch {wait}; send_user "\nError: Unknown host\n"; wait; return 1 } -re "Enter passphrase.*: " { # sleep briefly to allow time for stty -echo sleep 1 send -- "$passphrase\r" exp_continue } -re "$u_prompt" { send -- "$user\r" expect { eof { send_user "\nError: Couldn't login\n"; wait; return 1 } "Login invalid" { send_user "\nError: Invalid login\n"; catch {close}; catch {wait}; return 1 } -re "$p_prompt" { send -- "$userpswd\r" } "$prompt" { set in_proc 0; return 0 } "Press any key to continue" { send " " exp_continue } } exp_continue } -re "$p_prompt" { if ![string compare $prog "ssh"] { send -- "$userpswd\r" } else { send -- "$passwd\r" } expect { eof { send_user "\nError: Couldn't login\n"; wait; return 1 } "Press any key to continue" { send " "; exp_continue } -re "$e_prompt" { send -- "$enapasswd\r" } "$prompt" { set in_proc 0; return 0 } } exp_continue } "$prompt" { break; } denied { send_user "\nError: Check your passwd for $router\n" catch {close}; catch {wait}; return 1 } "% Bad passwords" {send_user "\nError: Check your passwd for $router\n"; return 1 } } } set in_proc 0 return 0 } # Enable proc do_enable { enauser enapasswd } { global prompt in_proc global u_prompt e_prompt set in_proc 1 send "enable\r" expect { -re "$u_prompt" { send -- "$enauser\r"; exp_continue} -re "$e_prompt" { send -- "$enapasswd\r"; exp_continue} "#" { set prompt "#" } "(enable)" { set prompt "> (enable) " } denied { send_user "\nError: Check your Enable passwd\n"; return 1} "% Bad passwords" { send_user "\nError: Check your Enable passwd\n" return 1 } } # We set the prompt variable (above) so script files don't need # to know what it is. set in_proc 0 return 0 } # Run commands given on the command line. proc run_commands { prompt command } { global do_saveconfig in_proc set in_proc 1 # Turn off the pager and escape regex meta characters in the $prompt send "no page\r" regsub -all {[)(]} $prompt {\\&} reprompt regsub -all {^(.{1,11}).*([#>])$} $reprompt {\1([^#>\r\n]+)?[#>](\\([^)\\r\\n]+\\))?} reprompt expect { -re $reprompt {} -re "\[\n\r]+" { exp_continue } } # this is the only way i see to get rid of more prompts in o/p..grrrrr log_user 0 set commands [split $command \;] set num_commands [llength $commands] # if the pager can not be turned off, we have to look for the "More" # prompt. for {set i 0} {$i < $num_commands} { incr i} { send -- "[subst -nocommands [lindex $commands $i]]\r" expect { -re "^\[^\n\r *]*$reprompt" { catch {send_user -- "$expect_out(buffer)"} } -re "^\[^\n\r]*$reprompt " { catch {send_user -- "$expect_out(buffer)"} } -re "\[\n\r]+" { catch {send_user -- "$expect_out(buffer)"} exp_continue } -re "\[^\r\n]*Press to cont\[^\r\n]*" { catch {send " "}; expect { # gag, 2 more prompts -re "\[\r\n]*\r" {} -re "\[^\r\n]*Press to cont\[^\r\n]*" { catch {send " "}; exp_continue } } exp_continue } -re "^<-+ More -+>\[^\n\r]*" { catch {send " "} exp_continue } -re "^-+ MORE -+\[^\n\r]*" { catch {send " "} exp_continue } # 3 flavours of the more prompt, first -More-, then --More-- (for # cisco/riverhead AGM), then with more dashes. -re "^-More-\[^\n\r-]*" { catch {send " "} exp_continue } -re "^--More--\[^\n\r-]*" { catch {send " "} exp_continue } -re "^---+More---+\[^\n\r]*" { catch {send " "} exp_continue } -re "\b+" { exp_continue } } } log_user 1 send -h "logout\r" expect { "Do you want to save current configuration" { if {$do_saveconfig} { catch {send "y\r"} } else { catch {send "n\r"} } exp_continue } "Do you wish to save " { if {$do_saveconfig} { catch {send "y\r"} } else { catch {send "n\r"} } exp_continue } "Do you want to log out" { catch {send "y\r"} exp_continue } -re "\[\r\n]+" { exp_continue } -re "^.+>" { catch {send -h "exit\r"} exp_continue } timeout { catch {close}; catch {wait}; 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 set exitval 0 foreach router [lrange $argv $i end] { set router [string tolower $router] send_user "$router\n" # device timeout set timeout [find timeout $router] if { [llength $timeout] == 0 } { set timeout $timeoutdflt } # Figure out prompt. # Since autoenable is off by default, if we have it defined, it # was done on the command line. If it is not specifically set on the # command line, check the password file. if $avautoenable { set autoenable 1 set enable 0 set prompt "#" } else { set ae [find autoenable $router] if { "$ae" == "1" } { set autoenable 1 set enable 0 set prompt "#" } else { set autoenable 0 set enable $avenable set prompt ">" } } # look for noenable option in .cloginrc if { [find noenable $router] == "1" } { set enable 0 } # Figure out passwords if { $do_passwd || $do_enapasswd } { set pswd [find password $router] if { [llength $pswd] == 0 } { send_user "\nError: no password for $router in $password_file.\n" continue } if { $enable && $do_enapasswd && $autoenable == 0 && [llength $pswd] < 2 } { send_user "\nError: no enable password for $router in $password_file.\n" continue } set passwd [join [lindex $pswd 0] ""] set enapasswd [join [lindex $pswd 1] ""] } else { set passwd $userpasswd set enapasswd $enapasswd } # Figure out username if {[info exists username]} { # command line username set ruser $username } else { set ruser [join [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 [join [find userpassword $router] ""] if { "$userpswd" == "" } { set userpswd $passwd } } # Figure out enable username if {[info exists enausername]} { # command line enausername set enauser $enausername } else { set enauser [join [find enauser $router] ""] if { "$enauser" == "" } { set enauser $ruser } } # Figure out prompts set u_prompt [find userprompt $router] if { "$u_prompt" == "" } { set u_prompt "(Username|login|user name):" } else { set u_prompt [join [lindex $u_prompt 0] ""] } set p_prompt [find passprompt $router] if { "$p_prompt" == "" } { set p_prompt "(\[Pp]assword|passwd):" } else { set p_prompt [join [lindex $p_prompt 0] ""] } set e_prompt [find enableprompt $router] if { "$e_prompt" == "" } { set e_prompt "\[Pp]assword:" } else { set e_prompt [join [lindex $e_prompt 0] ""] } # Figure out identity file to use set identfile [join [lindex [find identity $router] 0] ""] # Figure out passphrase to use if {[info exists avpassphrase]} { set passphrase $avpassphrase } else { set passphrase [join [lindex [find passphrase $router] 0] ""] } if { ! [string length "$passphrase"]} { set passphrase $passwd } # 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}} } # Figure out the SSH executable name set sshcmd [join [lindex [find sshcmd $router] 0] ""] if { "$sshcmd" == "" } { set sshcmd {ssh} } # Adjust our path to find hpuifilter set hpf_path "" regexp {(.*)/[^/]+} $argv0 junk hpf_path if { "$hpf_path" != "" && "$hpf_path" != "." } { append env(PATH) ":$hpf_path" } # Login to the router if {[login $router $ruser $userpswd $passwd $enapasswd $cmethod $cyphertype $identfile]} { incr exitval continue } if { $enable } { if {[do_enable $enauser $enapasswd]} { if { $do_command || $do_script } { incr exitval catch {close}; catch {wait}; continue } } } # we are logged in, now figure out the full prompt send "\r" expect { -re "\[\r\n]+" { exp_continue; } -re "^.+$prompt" { set prompt $expect_out(0,string); } } if { $do_command } { if {[run_commands $prompt $command]} { incr exitval continue } } elseif { $do_script } { # disable the pager send "no page\r" expect -re $prompt {} source $sfile catch {close}; } else { label $router log_user 1 interact } # End of for each router catch {wait}; sleep 0.3 } exit $exitval rancid-2.3.8/bin/hrancid.in100644 015615 000000 00000046604 11653561577 0011220#! @PERLV_PATH@ ## ## $Id: hrancid.in 2328 2011-10-31 18:05:46Z heas $ ## ## @PACKAGE@ @VERSION@ ## Copyright (c) 1997-2008 by Terrapin Communications, Inc. ## All rights reserved. ## ## This code is derived from software contributed to and maintained by ## Terrapin Communications, Inc. by Henry Kilmer, John Heasley, Andrew Partan, ## Pete Whiting, Austin Schutz, and Andrew Fort. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions ## are met: ## 1. Redistributions of source code must retain the above copyright ## notice, this list of conditions and the following disclaimer. ## 2. Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## 3. All advertising materials mentioning features or use of this software ## must display the following acknowledgement: ## This product includes software developed by Terrapin Communications, ## Inc. and its contributors for RANCID. ## 4. Neither the name of Terrapin Communications, Inc. nor the names of its ## contributors may be used to endorse or promote products derived from ## this software without specific prior written permission. ## 5. It is requested that non-binding fixes and modifications be contributed ## back to Terrapin Communications, Inc. ## ## THIS SOFTWARE IS PROVIDED BY Terrapin Communications, INC. AND CONTRIBUTORS ## ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ## TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COMPANY OR CONTRIBUTORS ## BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ## CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ## SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ## INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ## CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ## ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ## POSSIBILITY OF SUCH DAMAGE. # # Amazingly hacked version of Hank's rancid - this one tries to # deal with HP procurves. # # RANCID - Really Awesome New Cisco confIg Differ # # usage: rancid [-dV] [-l] [-f filename | hostname] # use Getopt::Std; 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; # unused - hp lacks an end-of-config tag $timeo = 90; # hlogin timeout in seconds my(@commandtable, %commands, @commands);# command lists my($aclsort) = ("ipsort"); # ACL sorting mode my($filter_commstr); # SNMP community string filtering my($filter_pwds); # password filtering mode my($systeminfo) = 0; # show system-information # 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)) && scalar(%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 routine 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 routine 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 routine 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 routine (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 "show config files" sub ShowConfigFiles { print STDERR " In ShowConfigFiles: $_" if ($debug); while () { tr/\015//d; last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); return(-1) if (/command authorization failed/i); return(1) if /^(Invalid|Ambiguous) input:/i; ProcessHistory("COMMENTS","keysort","H0",";$_"); } return(0); } # This routine parses "show version" sub ShowVersion { print STDERR " In ShowVersion: $_" if ($debug); while () { tr/\015//d; last if(/^$prompt/); next if(/^(\s*|\s*$cmd\s*)$/); return(-1) if (/command authorization failed/i); return(-1) if /^(Invalid|Ambiguous) input:/i; s/^image//i; s/^\s*//g; ProcessHistory("COMMENTS","keysort","C1", ";Image: $_") && next; } return(0); } # This routine parses "show flash" sub ShowFlash { print STDERR " In ShowFlash: $_" if ($debug); while () { tr/\015//d; last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); return(-1) if (/command authorization failed/i); return(1) if /^(Invalid|Ambiguous) input:/i; return(1) if /^\s*\^\s*$/; ProcessHistory("COMMENTS","keysort","D0",";Flash: $_"); } return; } # This routine parses "show system-information" or "show system information" sub ShowSystem { print STDERR " In ShowSystem: $_" if ($debug); if ($systeminfo) { $_ = ; return(0); } while () { tr/\015//d; last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); return(-1) if (/command authorization failed/i); return(0) if /^(Invalid|Ambiguous) input:/i; if (/memory\s+-\s+total\s+:\s+(\S+)/i) { my($mem) = $1; $mem =~ s/,//g; $mem /= (1024 * 1024); ProcessHistory("COMMENTS","keysort","B0",";Memory: " . int($mem) . "M\n"); next; } /serial\s+number\s+:\s+(\S+)/i && ProcessHistory("COMMENTS","keysort","A1",";Serial Number: $1\n"); /firmware\s+revision\s+:\s+(\S+)/i && ProcessHistory("COMMENTS","keysort","C0",";Image: Firmware $1\n"); /rom\s+version\s+:\s+(\S+)/i && ProcessHistory("COMMENTS","keysort","C1",";Image: ROM $1\n"); } $systeminfo = 1; return(0); } # This routine parses "show module". sub ShowModule { print STDERR " In ShowModule: $_" if ($debug); my(@lines); my($slot); while () { tr/\015//d; return if (/^\s*\^$/); last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); return(-1) if (/command authorization failed/i); return(1) if /^(Invalid|Ambiguous) input:/i; ProcessHistory("COMMENTS","keysort","E0","; $_") && next; } return(0); } # This routine parses "show stack" sub ShowStack { print STDERR " In ShowStack: $_" if ($debug); while () { tr/\015//d; last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); return(-1) if (/command authorization failed/i); return(1) if /^(Invalid|Ambiguous) input:/i; s/stacking - (Stacking Status).*/$1/i; s/\s*members unreachable .*$//i; ProcessHistory("COMMENTS","keysort","F0",";$_"); /auto grab/i && last; } return(0); } # This routine parses "show tech transceivers" sub ShowTechTransceivers { print STDERR " In ShowTransceivers: $_" if ($debug); while () { tr/\015//d; last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); return(-1) if (/command authorization failed/i); return(1) if /^(Invalid|Ambiguous) input:/i; s/ Technical Information//i; ProcessHistory("COMMENTS","keysort","G0",";$_"); } return(0); } # This routine parses "show config status" sub ShowConfigStatus { print STDERR " In ShowConfigStatus: $_" if ($debug); while () { tr/\015//d; last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); return(-1) if (/command authorization failed/i); return(1) if /^(Invalid|Ambiguous) input:/i; next if (/^Running configuration is same as /); next if (/^$/); ProcessHistory("COMMENTS","keysort","H0","; $_"); } return(0); } # This routine processes a "write term" sub WriteTerm { print STDERR " In WriteTerm: $_" if ($debug); while () { tr/\015//d; if (/$prompt\s*(exit|logout)\s*$/i) { $clean_run=1; last; } last if(/^$prompt/); return(-1) if (/command authorization failed/i); # the pager can not be disabled per-session s/^<-+ More -+>\s*//; s/^$/;/; # skip the crap /^running configuration:/i && next; # filter out any RCS/CVS tags to avoid confusing local CVS storage s/\$(Revision|Id):/ $1:/; /^; (\S+) configuration editor;/i && ProcessHistory("COMMENTS","keysort","A0",";Chassis type: $1\n") && ProcessHistory("","","",";\n;Running config file:\n$_") && next; # order logging statements - doesnt appear to do syslog as of right now /^logging (\d+\.\d+\.\d+\.\d+)/ && ProcessHistory("LOGGING","ipsort","$1","$_") && next; # no so sure this match is correct. show running doesnt seem to # actually o/p anything after "password (manager|operator)" if (/^(\s*)password (manager|operator)?/ && $filter_pwds >= 1) { ProcessHistory("LINE-PASS","","",";$1password $2 \n"); next; } if (/^(snmp-server community) (\S+)/) { if ($filter_commstr) { ProcessHistory("SNMPSERVERCOMM","keysort","$_", ";$1 $'") && next; } else { ProcessHistory("SNMPSERVERCOMM","keysort","$_","$_") && next; } } # order/prune snmp-server host statements - it actually appears to do # the sortting for us, but just in case it changes ... # we only prune lines of the form # snmp-server host a.b.c.d if (/^snmp-server host (\d+\.\d+\.\d+\.\d+) /) { if ($filter_commstr) { my($ip) = $1; my($line) = "snmp-server host $ip"; my(@tokens) = split(' ', $'); my($token); while ($token = shift(@tokens)) { if ($token eq 'version') { $line .= " " . join(' ', ($token, shift(@tokens))); } elsif ($token =~ /^(informs?|traps?|(no)?auth)$/) { $line .= " " . $token; } else { $line = ";$line " . join(' ', ("", join(' ',@tokens))); last; } } ProcessHistory("SNMPSERVERHOST","ipsort","$ip","$line\n"); } else { ProcessHistory("SNMPSERVERHOST","ipsort","$1","$_"); } next; } # order/prune tacacs/radius server statements if (/^(tacacs-server|radius-server) key / && $filter_pwds >= 1) { ProcessHistory("","","",";$1 key \n"); next; } if (/^(tacacs-server host \d+\.\S+) key / && $filter_pwds >= 1) { ProcessHistory("","","",";$1 key \n"); next; } # prune passwords from stack member statements if (/^(stack member .* password )\S+/ && $filter_pwds >= 1) { ProcessHistory("","","",";$1$'"); next; } # order arp lists /^ip arp\s+(\d+\.\d+\.\d+\.\d+)/ && ProcessHistory("ARP","$aclsort","$1","$_") && next; /^ip prefix-list\s+(\S+)\s+seq\s+(\d+)\s+(permit|deny)\s+(\d\S+)(\/.*)$/ && ProcessHistory("PACL $1 $3","$aclsort","$4","ip prefix-list $1 $3 $4$5\n") && next; # blech!!!! /^auto-tftp / && ProcessHistory("","","",";$_") && next; # the rest are from rancid (i.e.: cisco), but suspect they will someday # be applicable or close to it. /^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 if (/^(enable )?(password|passwd) / && $filter_pwds >= 1) { ProcessHistory("ENABLE","","",";$1$2 \n"); next; } if (/^username (\S+)(\s.*)? password /) { if ($filter_pwds >= 1) { ProcessHistory("USER","keysort","$1",";username $1$2 password \n"); } else { ProcessHistory("USER","keysort","$1","$_"); } next; } if (/^(ip ftp password) / && $filter_pwds >= 1) { ProcessHistory("","","",";$1 \n"); next; } if (/^( ip ospf authentication-key) / && $filter_pwds >= 1) { ProcessHistory("","","",";$1 \n"); next; } if (/^( ip ospf message-digest-key \d+ md5) / && $filter_pwds >= 1) { ProcessHistory("","","",";$1 \n"); next; } # sort route-maps if (/^route-map (\S+)/) { my($key) = $1; my($routemap) = $_; while () { tr/\015//d; last if (/^$prompt/ || ! /^(route-map |[ !])/); if (/^route-map (\S+)/) { ProcessHistory("ROUTEMAP","keysort","$key","$routemap"); $key = $1; $routemap = $_; } else { $routemap .= $_; } } ProcessHistory("ROUTEMAP","keysort","$key","$routemap"); } # order access-lists /^access-list\s+(\d\d?)\s+(\S+)\s+(\S+)/ && ProcessHistory("ACL $1 $2","$aclsort","$3","$_") && next; # order extended access-lists /^access-list\s+(\d\d\d)\s+(\S+)\s+ip\s+host\s+(\S+)/ && ProcessHistory("EACL $1 $2","$aclsort","$3","$_") && next; /^access-list\s+(\d\d\d)\s+(\S+)\s+ip\s+(\d\S+)/ && ProcessHistory("EACL $1 $2","$aclsort","$3","$_") && next; /^access-list\s+(\d\d\d)\s+(\S+)\s+ip\s+any/ && ProcessHistory("EACL $1 $2","$aclsort","0.0.0.0","$_") && next; # order alias statements /^alias / && ProcessHistory("ALIAS","keysort","$_","$_") && next; # delete ntp auth password if (/^(ntp authentication-key \d+ md5) / && $filter_pwds >= 1) { ProcessHistory("","","",";$1 \n"); next; } # order ntp peers/servers if (/^ntp (server|peer) (\d+)\.(\d+)\.(\d+)\.(\d+)/) { $sortkey = sprintf("$1 %03d%03d%03d%03d",$2,$3,$4,$5); ProcessHistory("NTP","keysort",$sortkey,"$_"); next; } # order ip host line statements /^ip host line(\d+)/ && ProcessHistory("IPHOST","numsort","$1","$_") && next; # order ip nat source static statements /^ip nat (\S+) source static (\S+)/ && ProcessHistory("IP NAT $1","ipsort","$2","$_") && next; # order ip rcmd lines /^ip rcmd/ && ProcessHistory("RCMD","keysort","$_","$_") && next; # catch anything that wasnt match above. ProcessHistory("","","","$_"); } return(0); } # dummy function sub DoNothing {print STDOUT;} # Main @commandtable = ( {'show version' => 'ShowVersion'}, {'show flash' => 'ShowFlash'}, {'show system-information' => 'ShowSystem'}, {'show system information' => 'ShowSystem'}, {'show module' => 'ShowModule'}, {'show stack' => 'ShowStack'}, {'show tech transceivers' => 'ShowTechTransceivers'}, {'show config files' => 'ShowConfigFiles'}, {'show config status' => 'ShowConfigStatus'}, {'write term' => 'WriteTerm'} ); # 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("|", map quotemeta($_), @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 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 hlogin -t $timeo -c\"$cisco_cmds\" $host\n" if ($debug); print STDOUT "executing hlogin -t $timeo -c\"$cisco_cmds\" $host\n" if ($log); if (defined($ENV{NOPIPE}) && $ENV{NOPIPE} =~ /^YES/i) { system "hlogin -t $timeo -c \"$cisco_cmds\" $host $host.raw 2>&1" || die "hlogin failed for $host: $!\n"; open(INPUT, "< $host.raw") || die "hlogin failed for $host: $!\n"; } else { open(INPUT,"hlogin -t $timeo -c \"$cisco_cmds\" $host ) { tr/\015//d; if (/$prompt\s*(exit|logout)\s*$/i) { $clean_run=1; last; } if (/^Error:/) { print STDOUT ("$host clogin error: $_"); print STDERR ("$host clogin error: $_") if ($debug); $clean_run=0; last; } while (/#\s*($cmds_regexp)\s*$/) { $cmd = $1; if (!defined($prompt)) { $prompt = ($_ =~ /^([^#]+)/)[0]; $prompt =~ s/([][}{)(\\])/\\$1/g; $prompt .= "[#>]"; 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; } $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}) && $ENV{NOPIPE} =~ /^YES/i) { unlink("$host.raw") if (! $debug); } # check for completeness if (scalar(%commands) || !$clean_run) { 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) { 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); } rancid-2.3.8/bin/htlogin.in100644 015615 000000 00000034505 11662541466 0011244#! @EXPECT_PATH@ -- ## ## $Id: htlogin.in 2334 2011-11-17 21:09:37Z heas $ ## ## @PACKAGE@ @VERSION@ ## Copyright (c) @COPYYEARS@ by Terrapin Communications, Inc. ## All rights reserved. ## ## This code is derived from software contributed to and maintained by ## Terrapin Communications, Inc. by Henry Kilmer, John Heasley, Andrew Partan, ## Pete Whiting, Austin Schutz, and Andrew Fort. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions ## are met: ## 1. Redistributions of source code must retain the above copyright ## notice, this list of conditions and the following disclaimer. ## 2. Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## 3. All advertising materials mentioning features or use of this software ## must display the following acknowledgement: ## This product includes software developed by Terrapin Communications, ## Inc. and its contributors for RANCID. ## 4. Neither the name of Terrapin Communications, Inc. nor the names of its ## contributors may be used to endorse or promote products derived from ## this software without specific prior written permission. ## 5. It is requested that non-binding fixes and modifications be contributed ## back to Terrapin Communications, Inc. ## ## THIS SOFTWARE IS PROVIDED BY Terrapin Communications, INC. AND CONTRIBUTORS ## ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ## TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COMPANY OR CONTRIBUTORS ## BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ## CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ## SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ## INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ## CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ## ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ## POSSIBILITY OF SUCH DAMAGE. # # The expect login scripts were based on Erik Sherk's gwtn, by permission. # # htlogin - Hitachi router login # # Most options are intuitive for logging into an Hitachi router login. # # Usage line set usage "Usage: $argv0 \[-dSV\] \[-noenable\] \[-c command\] \ \[-Evar=x\] \[-f cloginrc-file\] \[-p user-password\] \ \[-s script-file\] \[-t timeout\] \[-u username\] \ \[-v vty-password\] \[-w enable-username\] \[-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 avenable 1 # The default is that you login non-enabled (tacacs can have you login already # enabled) set avautoenable 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 # Save config, if prompted set do_saveconfig 0 # Sometimes routers take awhile to answer (the default is 10 sec) set timeoutdflt 45 # 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) } elseif {[ info exists env(LOGNAME) ]} { set default_user $env(LOGNAME) } 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 "\nError: could not exec id: $reason\n" exit 1 } regexp {\(([^)]*)} "$reason" junk default_user } if {[ info exists env(CLOGINRC) ]} { set password_file $env(CLOGINRC) } # Process the command line for {set i 0} {$i < $argc} {incr i} { set arg [lindex $argv $i] switch -glob -- $arg { # Expect debug mode -d* { exp_internal 1 # Username } -u* { if {! [ regexp .\[uU\](.+) $arg ignore user]} { incr i set username [ lindex $argv $i ] } # VTY Password } -p* { if {! [ regexp .\[pP\](.+) $arg ignore userpasswd]} { incr i set userpasswd [ lindex $argv $i ] } set do_passwd 0 # ssh passphrase } -r* { # ignore -r # VTY Password } -v* { if {! [ regexp .\[vV\](.+) $arg ignore passwd]} { incr i set passwd [ lindex $argv $i ] } set do_passwd 0 # Version string } -V* { send_user "@PACKAGE@ @VERSION@\n" exit 0 # Enable Username } -w* { # ignore -w # Environment variable to pass to -s scripts } -E* { if {[ regexp .\[E\](.+)=(.+) $arg ignore varname varvalue]} { 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* { if {! [ regexp .\[cC\](.+) $arg ignore command]} { incr i set command [ lindex $argv $i ] } set do_command 1 # Expect script to run. } -s* { if {! [ regexp .\[sS\](.+) $arg ignore sfile]} { incr i set sfile [ lindex $argv $i ] } if { ! [ file readable $sfile ] } { send_user "\nError: Can't read $sfile\n" exit 1 } set do_script 1 # save config on exit } -S* { set do_saveconfig 1 # 'ssh -c' cypher type } -y* { if {! [ regexp .\[eE\](.+) $arg ignore cypher]} { incr i set cypher [ lindex $argv $i ] } # alternate cloginrc file } -f* { if {! [ regexp .\[fF\](.+) $arg ignore password_file]} { incr i set password_file [ lindex $argv $i ] } # Timeout } -t* { if {! [ regexp .\[tT\](.+) $arg ignore timeout]} { incr i set timeoutdflt [ lindex $argv $i ] } # Command file } -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 "\nError: Unknown argument! $arg\n" send_user $usage exit 1 } default { break } } } # Process routers...no routers listed is an error. if { $i == $argc } { send_user "\nError: $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 "\nError: password file ($password_file) does not exist\n" exit 1 } file stat $password_file fileinfo if { [expr ($fileinfo(mode) & 007)] != 0000 } { send_user "\nError: $password_file must not be world readable/writable\n" exit 1 } if [ catch {source $password_file} reason ] { send_user "\nError: $reason\n" exit 1 } } # Log into the router. # returns: 0 on success, 1 on failure 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] { incr progs -1 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" return 1 } } elseif ![string compare $prog "ssh"] { send_error "\nError: unsupported method: ssh\n" if { $progs == 0 } { return 1 } continue } elseif ![string compare $prog "rsh"] { send_error "\nError: unsupported method: rsh\n" if { $progs == 0 } { return 1 } continue } else { send_user "\nError: unknown connection method: $prog\n" return 1 } sleep 0.3 # This helps cleanup each expect clause. expect_after { timeout { send_user "\nError: TIMEOUT reached\n" catch {close}; catch {wait}; if { $in_proc} { return 1 } else { continue } } eof { send_user "\nError: EOF received\n" catch {close}; catch {wait}; if { $in_proc} { return 1 } else { continue } } } expect { "Connection refused" { catch {close}; catch {wait}; sleep 0.3 expect eof send_user "\nError: Connection Refused\n"; wait; return 1 } eof { send_user "\nError: Couldn't login\n"; wait; return 1 } "Unknown host\r\n" { expect eof send_user "\nError: Unknown host\n"; wait; return 1 } "Host is unreachable" { expect eof send_user "\nError: Host Unreachable!\n"; wait; return 1 } "No address associated with name" { expect eof send_user "\nError: 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 } "Password incorrect" { send_user "\nError: Check your password for $router\n"; catch {close}; catch {wait}; return 1 } "$prompt" { break; } denied { send_user "\nError: Check your passwd for $router\n" catch {close}; catch {wait}; 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 set commands [split $command \;] set num_commands [llength $commands] for {set i 0} {$i < $num_commands} { incr i} { send -- "[lindex $commands $i]\r" expect { -re "^\[^\n\r]*$prompt" {} -re "^\[^\n\r *]*$prompt" {} -re "\[\n\r]" { exp_continue } } } send "exit\r" expect { "\n" { exp_continue } timeout { catch {close}; catch {wait}; 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 set exitval 0 foreach router [lrange $argv $i end] { set router [string tolower $router] send_user "$router\n" # device timeout set timeout [find timeout $router] if { [llength $timeout] == 0 } { set timeout $timeoutdflt } # Figure out prompt. set prompt "command: " 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 [join [lindex $pswd 0] ""] } # Figure out username if {[info exists username]} { # command line username set ruser $username } else { set ruser [join [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 [join [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):" } else { set u_prompt [join [lindex $u_prompt 0] ""] } set p_prompt [find passprompt $router] if { "$p_prompt" == "" } { set p_prompt "\[Pp]assword:" } else { set p_prompt [join [lindex $p_prompt 0] ""] } # 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}} } # Login to the router if {[login $router $ruser $userpswd $passwd $prompt $cmethod $cyphertype]} { incr exitval continue } if { $do_command } { if {[run_commands $prompt $command]} { incr exitval continue } } elseif { $do_script } { source $sfile catch {close}; } else { label $router log_user 1 interact } # End of for each router catch {wait}; sleep 0.3 } exit $exitval rancid-2.3.8/bin/htrancid.in100644 015615 000000 00000022225 11535733223 0011361#! @PERLV_PATH@ ## ## $Id: htrancid.in 2279 2011-01-31 22:41:00Z heas $ ## ## @PACKAGE@ @VERSION@ ## Copyright (c) 1997-2008 by Terrapin Communications, Inc. ## All rights reserved. ## ## This code is derived from software contributed to and maintained by ## Terrapin Communications, Inc. by Henry Kilmer, John Heasley, Andrew Partan, ## Pete Whiting, Austin Schutz, and Andrew Fort. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions ## are met: ## 1. Redistributions of source code must retain the above copyright ## notice, this list of conditions and the following disclaimer. ## 2. Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## 3. All advertising materials mentioning features or use of this software ## must display the following acknowledgement: ## This product includes software developed by Terrapin Communications, ## Inc. and its contributors for RANCID. ## 4. Neither the name of Terrapin Communications, Inc. nor the names of its ## contributors may be used to endorse or promote products derived from ## this software without specific prior written permission. ## 5. It is requested that non-binding fixes and modifications be contributed ## back to Terrapin Communications, Inc. ## ## THIS SOFTWARE IS PROVIDED BY Terrapin Communications, INC. AND CONTRIBUTORS ## ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ## TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COMPANY OR CONTRIBUTORS ## BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ## CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ## SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ## INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ## CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ## ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ## POSSIBILITY OF SUCH DAMAGE. # # hacked version of Hank's rancid - this one tries to deal with Hitachi's. # # RANCID - Really Awesome New Cisco confIg Differ # # usage: htrancid [-dV] [-l] [-f filename | hostname] # use Getopt::Std; 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; # htlogin timeout in seconds my(@commandtable, %commands, @commands);# command lists my($aclsort) = ("ipsort"); # ACL sorting mode my($filter_commstr); # SNMP community string filtering 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)) && scalar(%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 routine 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 routine 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 routine 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 routine (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 "show config" sub ShowConfig { print STDERR " In ShowConfig: $_" if ($debug); while () { tr/\015//d; last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); ProcessHistory("","","","$_"); } return(0); } # This routine parses single command's that return no required info sub ShowVersion { print STDERR " In ShowVersion: $_" if ($debug); while () { tr/\015//d; last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); } return(0) } # dummy function sub DoNothing {print STDOUT;} # Main @commandtable = ( {'version -a' => 'ShowVersion'}, {'cat /config/router.cnf' => 'ShowConfig'} ); # 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("|", map quotemeta($_), @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 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 htlogin -t $timeo -c\"$cisco_cmds\" $host\n" if ($debug); print STDOUT "executing htlogin -t $timeo -c\"$cisco_cmds\" $host\n" if ($log); if (defined($ENV{NOPIPE}) && $ENV{NOPIPE} =~ /^YES/i) { system "htlogin -t $timeo -c \"$cisco_cmds\" $host $host.raw 2>&1" || die "htlogin failed for $host: $!\n"; open(INPUT, "< $host.raw") || die "htlogin failed for $host: $!\n"; } else { open(INPUT,"htlogin -t $timeo -c \"$cisco_cmds\" $host ) { tr/\015//d; if (/^.*logout$/) { $clean_run=1; last; } if (/^Error:/) { print STDOUT ("$host htlogin error: $_"); print STDERR ("$host htlogin error: $_") if ($debug); $clean_run=0; last; } while (/command:\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}) && $ENV{NOPIPE} =~ /^YES/i) { unlink("$host.raw") if (! $debug); } # check for completeness if (scalar(%commands) || !$clean_run ) { 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 ) { 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); } rancid-2.3.8/bin/jerancid.in100644 015615 000000 00000051567 11661313015 0011350#! @PERLV_PATH@ ## ## $Id: jerancid.in 2336 2011-11-17 21:13:20Z heas $ ## ## @PACKAGE@ @VERSION@ ## Copyright (c) 1997-2008 by Terrapin Communications, Inc. ## All rights reserved. ## ## This code is derived from software contributed to and maintained by ## Terrapin Communications, Inc. by Henry Kilmer, John Heasley, Andrew Partan, ## Pete Whiting, Austin Schutz, and Andrew Fort. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions ## are met: ## 1. Redistributions of source code must retain the above copyright ## notice, this list of conditions and the following disclaimer. ## 2. Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## 3. All advertising materials mentioning features or use of this software ## must display the following acknowledgement: ## This product includes software developed by Terrapin Communications, ## Inc. and its contributors for RANCID. ## 4. Neither the name of Terrapin Communications, Inc. nor the names of its ## contributors may be used to endorse or promote products derived from ## this software without specific prior written permission. ## 5. It is requested that non-binding fixes and modifications be contributed ## back to Terrapin Communications, Inc. ## ## THIS SOFTWARE IS PROVIDED BY Terrapin Communications, INC. AND CONTRIBUTORS ## ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ## TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COMPANY OR CONTRIBUTORS ## BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ## CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ## SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ## INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ## CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ## ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ## POSSIBILITY OF SUCH DAMAGE. # # jerancid - tries to deal with Juniper ERXs. # # RANCID - Really Awesome New Cisco confIg Differ # # usage: rancid [-dV] [-l] [-f filename | hostname] # use Getopt::Std; 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 my(@commandtable, %commands, @commands);# command lists my($aclsort) = ("ipsort"); # ACL sorting mode my($filter_commstr); # SNMP community string filtering 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)) && scalar(%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 routine 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 routine 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 routine 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 routine (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 "show version" sub ShowVersion { print STDERR " In ShowVersion: $_" if ($debug); my($slots); while () { tr/\015//d; last if(/^$prompt/); next if(/^(\s*|\s*$cmd\s*)$/); next if (/^Please wait/i); return(-1) if (/command authorization failed/i); /^Juniper Edge .* (\S+)$/ && ProcessHistory("COMMENTS","keysort","A1", "!Chassis type: $1 - a $_") && next; /^System Release: / && ProcessHistory("COMMENTS","keysort","B1", "!$_") && next; /^\s+(Version: .*)$/ && ProcessHistory("COMMENTS","keysort","B1", "!System $1\n") && next; if (/^(slot .*)\s+slot uptime/i) { ($slots++); ProcessHistory("COMMENTS","keysort","B2", "!\n! $1\n"); next; } /^(--.*) --+$/ && $slots && ProcessHistory("COMMENTS","keysort","B2", "! $1\n") && next; if (/^(\d+\s+(\S+)\s+\S+\s+.*) \S+/ && $slots) { my($line) = $1; if (! ($2 =~ /--+/)) { ProcessHistory("COMMENTS","keysort","B3", "! $line\n"); } next; } } ProcessHistory("COMMENTS","keysort","B4","!\n"); return(0); } # This routine parses "show redundancy" sub ShowRedundancy { print STDERR " In ShowRedundancy: $_" if ($debug); while () { tr/\015//d; last if(/^$prompt/); next if(/^(\s*|\s*$cmd\s*)$/); next if (/^Please wait/i); ProcessHistory("","","","! $_"); } ProcessHistory("","","","!\n"); return(0); } # This routine parses "show environment all" sub ShowEnv { print STDERR " In ShowEnv: $_" if ($debug); while () { tr/\015//d; last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); next if (/^Please wait/i); return(-1) if (/command authorization failed/i); # fail if the RP is amid the auto-sync process if (/auto-sync enabled/ && !/in sync/) { $in_sync = ; $in_sync =~ s/\015//; print STDERR $in_sync if ($debug); return(-1) if ( $in_sync !~ /in sync/); s/^ //; ProcessHistory("COMMENTS","keysort","D1","! $_"); $_ = $in_sync; } # skip the temperature goop if (/processor\s+processor/) { ; ; ; next; } /^\d+\s+\d+\s+\S+/ && next; # strip nvs usage s/, \d+% \S+\)/\)/; s/^ //; ProcessHistory("COMMENTS","keysort","D1","! $_"); } ProcessHistory("COMMENTS","keysort","D1","!\n"); return(0); } # This routine parses "show boot" sub ShowBoot { print STDERR " In ShowBoot: $_" if ($debug); while () { tr/\015//d; last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); next if (/^Please wait/i); next if (/^\s*$/); return(1) if /^\s*\^\s*$/; return(-1) if (/command authorization failed/i); return(1) if /Ambiguous command/i; /System Release:\s+(.*)/ && ProcessHistory("COMMENTS","keysort","C1","!Boot Release: $1\n") && next; /System Configuration:\s+(.*)/ && ProcessHistory("COMMENTS","keysort","C1", "!Boot Configuration: $1\n") && next; ProcessHistory("COMMENTS","keysort","C1","!$_"); } ProcessHistory("COMMENTS","keysort","C1","!\n"); return(0); } # This routine parses "dir" sub DirSlotN { print STDERR " In DirSlotN: $_" if ($debug); my($dev) = (/\s([^\s]+):/); while () { tr/\015//d; last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); next if (/^Please wait/i); next if (/^system\.log/); # fail if the RP is amid the auto-sync process return(-1) if (/active\/standby/i && /not sync/); if (/(\S+:\s+)(\d+)(\s+)(\d+)(\s+)(\d+)/) { my($totlen) = length($2) - 1; my($tot) = $2 / (1024 * 1024); my($freelen) = length($4) - 1; my($free) = $4 / (1024 * 1024); my($usedlen) = length($6) - 1; my($used) = $6 / (1024 * 1024); my($fmt) = sprintf("%%-%dsK%s%%-%dsK%s%%-%dsK", $totlen, $3, $freelen, $5, $usedlen); ProcessHistory("FLASH","","","!Flash: $1" . sprintf($fmt, $tot, $free, $used)); } ProcessHistory("FLASH","","","!Flash: $_"); } ProcessHistory("","","","!\n"); return(0); } # This routine parses "show hardware" sub ShowHardware { print STDERR " In ShowHardware: $_" if ($debug); while () { tr/\015//d; last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); next if (/^Please wait/i); # return(1) if ($type =~ /^(12[40]|7[05])/); return(-1) if (/command authorization failed/i); next if (/^Please wait/i); # wow...a clean table ProcessHistory("","","","!$_"); } ProcessHistory("","","","!\n"); return(0); } # This routine processes a "show configuration" sub WriteTerm { print STDERR " In WriteTerm: $_" if ($debug); my($lineauto) = 0; while () { tr/\015//d; last if(/^$prompt/); next if (/^Please wait/i); return(-1) if (/command authorization failed/i); /Non-Volatile memory is in use/ && return(-1); # NvRAM is locked $lineauto = 0 if (/^[^ ]/); # skip the crap /^! Configuration script /i && next; /^! Copyright /i && next; /^Please wait/i && next; /^(\.+)$/ && next; # Skip variable length pausing dot lines # Dog gone Cool matches to process the rest of the config /^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 /^ clockrate / && next; # kill clockrate on serial interfaces if (/^(enable )?(password|passwd) / && $filter_pwds >= 1) { ProcessHistory("ENABLE","","","!$1$2 \n"); next; } if (/^(enable secret) / && $filter_pwds >= 2) { ProcessHistory("ENABLE","","","!$1 \n"); next; } # XXX: ERX appears to not have local usernames, but leaving these in # case I am wrong. if (/^username (\S+)(\s.*)? secret /) { if ($filter_pwds >= 2) { ProcessHistory("USER","keysort","$1", "!username $1$2 secret \n"); } else { ProcessHistory("USER","keysort","$1","$_"); } next; } if (/^username (\S+)(\s.*)? password ((\d) \S+|\S+)/) { if ($filter_pwds == 2) { ProcessHistory("USER","keysort","$1", "!username $1$2 password \n"); } elsif ($filter_pwds == 1 && $4 ne "5"){ ProcessHistory("USER","keysort","$1", "!username $1$2 password \n"); } else { ProcessHistory("USER","keysort","$1","$_"); } next; } if (/^(\s*)password / && $filter_pwds >= 1) { ProcessHistory("LINE-PASS","","","!$1password \n"); next; } if (/^\s*neighbor (\S*) password / && $filter_pwds >= 1) { ProcessHistory("","","","! neighbor $1 password \n"); next; } if (/^(ppp .* password) 7 .*/ && $filter_pwds >= 1) { ProcessHistory("","","","!$1 \n"); next; } if (/^( ip ospf authentication-key) / && $filter_pwds >= 1) { ProcessHistory("","","","!$1 \n"); next; } # isis interface passwords if (/^(\s+isis authentication-key \S+)( \d)? \S+/ && $filter_pwds >= 1) { ProcessHistory("","","","!$1 $'\n"); next; } if (/^(\s+isis message-digest-key \d+ hmac-md5)( \d)?( \S+)/ && $filter_pwds >= 1) { ProcessHistory("","","","!$1 $'"); next; } # this is reversable, despite 'md5' in the cmd if (/^(\s+ip ospf authentication-key \S+)( \d)? \S+/ && $filter_pwds >= 1) { ProcessHistory("","","","!$1 $'\n"); next; } if (/^(\s+ip ospf message-digest-key \d+ hmac-md5)( \d)?( \S+)/ && $filter_pwds >= 1) { ProcessHistory("","","","!$1 $'"); next; } if (/^( ip ospf message-digest-key \d+ md5) / && $filter_pwds >= 1) { ProcessHistory("","","","!$1 \n"); next; } # filter VRRP passwords if (/^(\s+ip vrrp authentication-key \d+)( \d)? \s+ / && $filter_pwds >= 1) { ProcessHistory("","","","!$1 \n"); next; } # ftp host encrypted password oscillates if (/^(host \S+ \S+ ftp) /) { my($prefix) = $1; if ($filter_pwds >= 1 || /^host \S+ \S+ ftp \d /) { ProcessHistory("","","","!$prefix \n"); next; } } # mpls ldp encrypted password oscillates if (/^(mpls ldp neighbor \S+ password)/) { my($prefix) = $1; if ($filter_pwds >= 1 || /^mpls ldp neighbor \S+ password \d /) { ProcessHistory("","","","!$prefix \n"); next; } } # sort ip explicit-paths. if (/^ip explicit-path name (\S+)/) { my($key) = $1; my($expath) = $_; while () { tr/\015//d; last if (/^$prompt/); last if (/^$prompt/ || ! /^(ip explicit-path name |[ !])/); if (/^ip explicit-path name (\S+)/) { ProcessHistory("EXPATH","keysort","$key","$expath"); $key = $1; $expath = $_; } else { $expath .= $_; } } ProcessHistory("EXPATH","keysort","$key","$expath"); } # sort route-maps if (/^route-map (\S+)/) { my($key) = $1; my($routemap) = $_; while () { tr/\015//d; last if (/^$prompt/ || ! /^(route-map |[ !])/); if (/^route-map (\S+)/) { ProcessHistory("ROUTEMAP","keysort","$key","$routemap"); $key = $1; $routemap = $_; } else { $routemap .= $_; } } ProcessHistory("ROUTEMAP","keysort","$key","$routemap"); } # filter out any RCS/CVS tags to avoid confusing local CVS storage s/\$(Revision|Id):/ $1:/; # order arp lists /^arp\s+(\d+\.\d+\.\d+\.\d+)\s+/ && ProcessHistory("ARP","$aclsort","$1","$_") && next; /^ip prefix-list\s+(\S+)\s+seq\s+(\d+)\s+(permit|deny)\s+(\d\S+)(\/.*)$/ && ProcessHistory("PACL $1 $3","$aclsort","$4", "ip prefix-list $1 $3 $4$5\n") && next; # order/prune snmp-server host statements # we only prune lines of the form # snmp-server host a.b.c.d if (/^snmp-server host (\d+\.\d+\.\d+\.\d+) /) { if ($filter_commstr) { my($ip) = $1; my($line) = "snmp-server host $ip"; my(@tokens) = split(' ', $'); my($token); while ($token = shift(@tokens)) { if ($token eq 'version' || $tokens[0] == 1) { $line .= " " . join(' ', ($token, shift(@tokens))); } elsif ($token =~ /^(informs?|traps?|(no)?auth)$/) { $line .= " " . $token; } else { $line = "!$line " . join(' ', ("", join(' ',@tokens))); last; } } ProcessHistory("SNMPSERVERHOST","ipsort","$ip","$line\n"); } else { ProcessHistory("SNMPSERVERHOST","ipsort","$1","$_"); } next; } if (/^(snmp-server community) (\S+)/) { if ($filter_commstr) { ProcessHistory("SNMPSERVERCOMM","keysort","$_","!$1 $'"); next; } else { ProcessHistory("SNMPSERVERCOMM","keysort","$_","$_") && next; } } # prune tacacs/radius server keys if (/^(tacacs-server|radius-server) key / && $filter_pwds >= 1) { ProcessHistory("","","","!$1 key \n"); next; } if (/^((tacacs-server|radius-server) host \S+ key)( \d)? \S+/ && $filter_pwds >= 1) { ProcessHistory("","","","!$1 $'"); next; } if (/^( key )(\d )?\S+/ && $filter_pwds >= 1) { ProcessHistory("","","","!$1 $'"); next; } # order clns host statements /^clns host \S+ (\S+)/ && ProcessHistory("CLNS","keysort","$1","$_") && next; # order alias statements /^alias / && ProcessHistory("ALIAS","keysort","$_","$_") && next; # filter isis keys if (/^( (area|domain)-message-digest-key \d+ hmac-md5)( \d)? \S+/ && $filter_pwds >= 1) { ProcessHistory("","","","!$1 $'\n"); next; } if (/^( (area|domain)-authentication-key)( \d)? \S+( \d)?/ && $filter_pwds >= 1) { ProcessHistory("","","","!$1 $'\n"); next; } # delete ntp auth password - this md5 is a reversable too if (/^(ntp authentication-key \d+ md5) / && $filter_pwds >= 1) { ProcessHistory("","","","!$1 \n"); next; } # order ntp peers/servers if (/^ntp (server|peer) (\d+)\.(\d+)\.(\d+)\.(\d+)/) { $sortkey = sprintf("$1 %03d%03d%03d%03d",$2,$3,$4,$5); ProcessHistory("NTP","keysort",$sortkey,"$_"); next; } # catch anything that wasnt matched above. ProcessHistory("","","","$_"); # end of config...is a comment. if (/^! end of /i) { $found_end = 1; return(1); } } return(0); } # dummy function sub DoNothing {print STDOUT;} # Main @commandtable = ( {'show version' => 'ShowVersion'}, {'show redundancy' => 'ShowRedundancy'}, {'show boot' => 'ShowBoot'}, {'show environment all' => 'ShowEnv'}, {'dir' => 'DirSlotN'}, {'show hardware' => 'ShowHardware'}, {'show configuration' => 'WriteTerm'} ); # 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); $jnxe_cmds=join(";",@commands); $cmds_regexp = join("|", map quotemeta($_), @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 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 clogin -t $timeo -c\"$jnxe_cmds\" $host\n" if ($debug); print STDOUT "executing clogin -t $timeo -c\"$jnxe_cmds\" $host\n" if ($log); if (defined($ENV{NOPIPE}) && $ENV{NOPIPE} =~ /^YES/i) { system "clogin -t $timeo -c \"$jnxe_cmds\" $host $host.raw 2>&1" || die "clogin failed for $host: $!\n"; open(INPUT, "< $host.raw") || die "clogin failed for $host: $!\n"; } else { open(INPUT,"clogin -t $timeo -c \"$jnxe_cmds\" $host ) { tr/\015//d; if (/\#\s?exit$/) { $clean_run=1; last; } if (/^Error:/) { print STDOUT ("$host clogin error: $_"); print STDERR ("$host clogin error: $_") if ($debug); $clean_run=0; last; } while (/#\s*($cmds_regexp)\s*$/) { $cmd = $1; 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; } $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}) && $ENV{NOPIPE} =~ /^YES/i) { 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); } rancid-2.3.8/bin/jlogin.in100644 015615 000000 00000040402 11712067106 0011041#! @EXPECT_PATH@ -- ## ## $Id: jlogin.in 2376 2012-01-31 22:42:14Z heas $ ## ## @PACKAGE@ @VERSION@ ## Copyright (c) @COPYYEARS@ by Terrapin Communications, Inc. ## All rights reserved. ## ## This code is derived from software contributed to and maintained by ## Terrapin Communications, Inc. by Henry Kilmer, John Heasley, Andrew Partan, ## Pete Whiting, Austin Schutz, and Andrew Fort. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions ## are met: ## 1. Redistributions of source code must retain the above copyright ## notice, this list of conditions and the following disclaimer. ## 2. Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## 3. All advertising materials mentioning features or use of this software ## must display the following acknowledgement: ## This product includes software developed by Terrapin Communications, ## Inc. and its contributors for RANCID. ## 4. Neither the name of Terrapin Communications, Inc. nor the names of its ## contributors may be used to endorse or promote products derived from ## this software without specific prior written permission. ## 5. It is requested that non-binding fixes and modifications be contributed ## back to Terrapin Communications, Inc. ## ## THIS SOFTWARE IS PROVIDED BY Terrapin Communications, INC. AND CONTRIBUTORS ## ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ## TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COMPANY OR CONTRIBUTORS ## BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ## CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ## SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ## INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ## CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ## ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ## POSSIBILITY OF SUCH DAMAGE. # # The expect login scripts were based on Erik Sherk's gwtn, by permission. # # jlogin - juniper login # # Most options are intuitive for logging into a Cisco router. # The default username password is the same as the vty password. # # Usage line set usage "Usage: $argv0 \[-dSV\] \[-c command\] \[-Evar=x\] \ \[-f cloginrc-file\] \[-p user-password\] \[-r passphrase\] \[-s script-file\] \ \[-u username\] \[-t timeout\] \[-x command-file\] \[-y ssh_cypher_type\] \ router \[router...\]\n" # env(CLOGIN) may contain the following chars: # 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 avenable 1 # 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 # Save config, if prompted set do_saveconfig 0 # Sometimes routers take awhile to answer (the default is 10 sec) set timeoutdflt 120 # 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) } elseif {[ info exists env(LOGNAME) ]} { set default_user $env(LOGNAME) } 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 "\nError: could not exec id: $reason\n" exit 1 } regexp {\(([^)]*)} "$reason" junk default_user } if {[ info exists env(CLOGINRC) ]} { set password_file $env(CLOGINRC) } # Process the command line for {set i 0} {$i < $argc} {incr i} { set arg [lindex $argv $i] switch -glob -- $arg { # Command to run. -c* - -C* { if {! [ regexp .\[cC\](.+) $arg ignore command]} { incr i set command [ lindex $argv $i ] } set do_command 1 # Expect debug mode } -d* { exp_internal 1 # Environment variable to pass to -s scripts } -E* { if {[ regexp .\[E\](.+)=(.+) $arg ignore varname varvalue]} { set E$varname $varvalue } else { send_user "\nError: invalid format for -E in $arg\n" exit 1 } # alternate cloginrc file } -f* { if {! [ regexp .\[fF\](.+) $arg ignore password_file]} { incr i set password_file [ lindex $argv $i ] } # user Password } -p* { if {! [ regexp .\[pP\](.+) $arg ignore userpasswd]} { incr i set userpasswd [ lindex $argv $i ] } set do_passwd 0 # ssh passphrase } -r* { if {! [ regexp .\[rR\](.+) $arg ignore passphrase]} { incr i set avpassphrase [ lindex $argv $i ] } # VTY Password } -v* { # ignore -v # Version string } -V* { send_user "@PACKAGE@ @VERSION@\n" exit 0 # Expect script to run. } -s* { if {! [ regexp .\[sS\](.+) $arg ignore sfile]} { incr i set sfile [ lindex $argv $i ] } if { ! [ file readable $sfile ] } { send_user "\nError: Can't read $sfile\n" exit 1 } set do_script 1 # save config on exit } -S* { set do_saveconfig 1 # Timeout } -t* { if {! [ regexp .\[tT\](.+) $arg ignore timeout]} { incr i set timeoutdflt [ lindex $argv $i ] } # Username } -u* { if {! [ regexp .\[uU\](.+) $arg ignore user]} { incr i set username [ lindex $argv $i ] } # command file } -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 # 'ssh -c' cypher type } -y* { if {! [ regexp .\[yY\](.+) $arg ignore cypher]} { incr i set cypher [ lindex $argv $i ] } } -* { send_user "\nError: Unknown argument! $arg\n" send_user $usage exit 1 } default { break } } } # Process routers...no routers listed is an error. if { $i == $argc } { send_user "\nError: $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 "\nError: password file ($password_file) does not exist\n" exit 1 } file stat $password_file fileinfo if { [expr ($fileinfo(mode) & 007)] != 0000 } { send_user "\nError: $password_file must not be world readable/writable\n" exit 1 } if [ catch {source $password_file} reason ] { send_user "\nError: $reason\n" exit 1 } } # Log into the router. # returns: 0 on success, 1 on failure proc login { router user passwd cmethod cyphertype identfile} { global spawn_id in_proc do_command do_script passphrase prompt global sshcmd set in_proc 1 # try each of the connection methods in $cmethod until one is successful set progs [llength $cmethod] foreach prog [lrange $cmethod 0 end] { incr progs -1 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" return 1 } } elseif ![string compare $prog "ssh"] { # ssh to the router & try to login with or without an identfile. # We use two calls to spawn since spawn does not seem to parse # spaces correctly. regexp {ssh(:([^[:space:]]+))*} $prog methcmd suffix port set cmd $sshcmd if {"$port" != ""} { set cmd "$cmd -p $port" } if {"$identfile" != ""} { set cmd "$cmd -i $identfile" } set retval [ catch {eval spawn [split "$cmd -c $cyphertype -x -l $user $router" { }]} reason ] if { $retval } { send_user "\nError: $sshcmd failed: $reason\n" return 1 } } elseif ![string compare $prog "rsh"] { send_error "\nError: unsupported method: rsh\n" if { $progs == 0 } { return 1 } continue } else { send_user "\nError: unknown connection method: $prog\n" return 1 } sleep 0.3 # This helps cleanup each expect clause. expect_after { timeout { send_user "\nError: TIMEOUT reached\n" catch {close}; catch {wait}; if { $in_proc} { return 1 } else { continue } } eof { send_user "\nError: EOF received\n" catch {close}; catch {wait}; if { $in_proc} { return 1 } else { continue } } } # Here we get a little tricky. There are several possibilities: # the router can ask for a username and passwd and then # talk to the TACACS server to authenticate you, or if the # TACACS server is not working, then it will use the enable # passwd. Or, the router might not have TACACS turned on, # then it will just send the passwd. expect { -re "(Connection refused|Secure connection \[^\n\r]+ refused|Connection closed by)" { catch {close}; catch {wait}; if !$progs { send_user "\nError: Connection Refused ($prog)\n"; return 1 } } eof { send_user "\nError: Couldn't login\n"; wait; return 1 } -nocase "unknown host\r\n" { catch {close}; catch {wait}; send_user "\nError: Unknown host\n"; wait; return 1 } "Host is unreachable" { catch {close}; catch {wait}; send_user "\nError: Host Unreachable!\n"; wait; return 1 } "No address associated with name" { catch {close}; catch {wait}; send_user "\nError: Unknown host\n"; wait; return 1 } "Login incorrect" { send_user "\nError: Check your password for $router\n" catch {close}; catch {wait}; return 1 } -re "Enter passphrase.*: " { # sleep briefly to allow time for stty -echo sleep 1 send -- "$passphrase\r" exp_continue } -re "(Host key not found |The authenticity of host .* be established).* \\(yes/no\\)\\?" { send "yes\r" send_user "\nHost $router added to the list of known hosts.\n" exp_continue } -re "HOST IDENTIFICATION HAS CHANGED.* \\(yes/no\\)\\?" { send "no\r" send_user "\nError: The host key for $router has changed. Update the SSH known_hosts file accordingly.\n" return 1 } -re "HOST IDENTIFICATION HAS CHANGED\[^\n\r]+" { send_user "\nError: The host key for $router has changed. Update the SSH known_hosts file accordingly.\n" return 1 } -re "Offending key for .* \\(yes/no\\)\\?" { send "no\r" send_user "\nError: host key mismatch for $router. Update the SSH known_hosts file accordingly.\n" return 1 } -re "(Username|\[\r\n]login):" { send -- "$user\r" exp_continue } "\[Pp]assword:" { sleep 1; send -- "$passwd\r" exp_continue } -re "$prompt" { break; } denied { send_user "\nError: Check your password for $router\n" catch {close}; catch {wait}; return 1 } } } # we are logged in, now figure out the full prompt send "\r" expect { -re "(\r\n|\n)" { exp_continue; } -re "^\[^ ]+$prompt" { set prompt $expect_out(0,string); regsub ">" $prompt "\[#>]" prompt; } } 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 "set cli complete-on-space off\r" expect -re $prompt {} send "set cli screen-length 0\r" expect -re $prompt {} set commands [split $command \;] set num_commands [llength $commands] for {set i 0} {$i < $num_commands} { incr i} { send "[lindex $commands $i]\r" expect { -re "^\[^\n\r *]*$prompt $" {} -re "^\[^\n\r]*$prompt." { exp_continue } -re "(\r\n|\n)" { exp_continue } } } send "quit\r" expect { "\n" { exp_continue } timeout { catch {close}; catch {wait}; 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 set exitval 0 foreach router [lrange $argv $i end] { set router [string tolower $router] send_user "$router\n" # device timeout set timeout [find timeout $router] if { [llength $timeout] == 0 } { set timeout $timeoutdflt } set prompt ">" # Figure out username if {[info exists username]} { # command line username set loginname $username } else { set loginname [join [find user $router] ""] if { "$loginname" == "" } { set loginname $default_user } } # Figure out loginname's password (if different from the vty password) if {[info exists userpasswd]} { # command line passwd set passwd $userpasswd } else { set passwd [join [lindex [find userpassword $router] 0] ""] if { "$passwd" == "" } { set passwd [join [lindex [find password $router] 0] ""] if { "$passwd" == "" } { send_user "\nError: no password for $router in $password_file.\n" continue } } } # Figure out identity file to use set identfile [join [lindex [find identity $router] 0] ""] # Figure out passphrase to use if {[info exists avpassphrase]} { set passphrase $avpassphrase } else { set passphrase [join [lindex [find passphrase $router] 0] ""] } if { ! [string length "$passphrase"]} { set passphrase $passwd } # Figure out ssh cypher type if {[info exists cypher]} { # command line ssh 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}} } # Figure out the SSH executable name set sshcmd [join [lindex [find sshcmd $router] 0] ""] if { "$sshcmd" == "" } { set sshcmd {ssh} } # Login to the router if {[login $router $loginname $passwd $cmethod $cyphertype $identfile]} { incr exitval continue } if { $do_command } { if {[run_commands $prompt $command]} { incr exitval continue } } elseif { $do_script } { send "set cli complete-on-space off\r" expect -re $prompt {} send "set cli screen-length 0\r" expect -re $prompt {} source $sfile catch {close}; } else { label $router log_user 1 interact } # End of for each router catch {wait}; sleep 0.3 } exit $exitval rancid-2.3.8/bin/jrancid.in100644 015615 000000 00000054501 11535733223 0011201#! @PERLV_PATH@ ## ## $Id: jrancid.in 2279 2011-01-31 22:41:00Z heas $ ## ## @PACKAGE@ @VERSION@ ## Copyright (c) 1997-2008 by Terrapin Communications, Inc. ## All rights reserved. ## ## This code is derived from software contributed to and maintained by ## Terrapin Communications, Inc. by Henry Kilmer, John Heasley, Andrew Partan, ## Pete Whiting, Austin Schutz, and Andrew Fort. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions ## are met: ## 1. Redistributions of source code must retain the above copyright ## notice, this list of conditions and the following disclaimer. ## 2. Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## 3. All advertising materials mentioning features or use of this software ## must display the following acknowledgement: ## This product includes software developed by Terrapin Communications, ## Inc. and its contributors for RANCID. ## 4. Neither the name of Terrapin Communications, Inc. nor the names of its ## contributors may be used to endorse or promote products derived from ## this software without specific prior written permission. ## 5. It is requested that non-binding fixes and modifications be contributed ## back to Terrapin Communications, Inc. ## ## THIS SOFTWARE IS PROVIDED BY Terrapin Communications, INC. AND CONTRIBUTORS ## ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ## TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COMPANY OR CONTRIBUTORS ## BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ## CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ## SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ## INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ## CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ## ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ## POSSIBILITY OF SUCH DAMAGE. # # Amazingly hacked version of Hank's rancid - this one tries to # deal with Junipers. # # RANCID - Really Awesome New Cisco confIg Differ # # usage: jrancid [-dV] [-l] [-f filename | hostname] # use Getopt::Std; getopts('dflV'); if ($opt_V) { print "@PACKAGE@ @VERSION@\n"; exit(0); } $debug = $opt_d; $log = $opt_l; $file = $opt_f; $host = $ARGV[0]; $clean_run = 0; $found_end = 0; $timeo = 120; # clogin timeout in seconds my(@commandtable, %commands, @commands);# command lists my($aclsort) = ("ipsort"); # ACL sorting mode my($filter_commstr); # SNMP community string filtering my($filter_pwds); # password filtering mode my($ShowChassisSCB); # Only run ShowChassisSCB() once # 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)) && scalar(%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 routine 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 routine 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 routine 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 routine (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); } ### ### Start of real work ### # This routine parses "show chassis clocks" sub ShowChassisClocks { print STDERR " In ShowChassisClocks: $_" if ($debug); s/^[a-z]+@//; ProcessHistory("","","","# $_"); while () { tr/\015//d; last if (/^$prompt/); next if (/^system (shutdown message from|going down )/i); next if (/^\{(master|backup)(:\d+)?\}/); /error: the chassis subsystem is not running/ && return(-1); /Couldn\'t initiate connection/ && return(-1); /Unrecognized command/ && return(1); /command is not valid/ && return(1); /^\s+\^/ && return(1); /syntax error/ && return(1); # filter decimal places of m160 measured clock MHz if (/Measured frequency/) { s/\..*MHz/ MHz/; } elsif (/^.+\.[0-9]+ MHz$/) { # filter for the m160 (newer format) s/\.[0-9]+ MHz/ MHz/; } elsif (/^(.+)(\.[0-9]+) MHz/) { # filter for T series my($leadlen) = length($1); $x = sprintf(" MHz%".length($2)."s", " "); substr($_, $leadlen, length($2)+4, $x); } # filter timestamps next if (/selected for/i); next if (/selected since/i); next if (/deviation/i); ProcessHistory("","","","# $_"); } return(0); } # This routine parses "show chassis environment" sub ShowChassisEnvironment { print STDERR " In ShowChassisEnvironment: $_" if ($debug); s/^[a-z]+@//; ProcessHistory("","","","# $_"); while () { tr/\015//d; last if (/^$prompt/); return 1 if (/^aborted!/i); next if (/^system (shutdown message from|going down )/i); next if (/^\{(master|backup)(:\d+)?\}/); /error: the chassis subsystem is not running/ && return(-1); /Couldn\'t initiate connection/ && return(-1); /Unrecognized command/ && return(1); /command is not valid/ && return(1); /^\s+\^/ && return(1); /syntax error/ && return(1); / backplane temperature/ && next; /(\s*Power supply.*), temperature/ && ProcessHistory("","","","# $1\n") && next; /(\s*.+) +\d+ degrees C.*$/ && ProcessHistory("","","","# $1\n") && next; /(^.*\S)\s+ Spinning at .*$/ && ProcessHistory("","","","# $1\n") && next; /(^.*\S)\s+Measurement/ && ProcessHistory("","","","# $1\n") && next; ProcessHistory("","","","# $_"); } return(0); } # This routine parses "show chassis firmware" sub ShowChassisFirmware { print STDERR " In ShowChassisFirmware: $_" if ($debug); s/^[a-z]+@//; ProcessHistory("","","","# $_"); while () { tr/\015//d; last if (/^$prompt/); return 1 if (/^aborted!/i); next if (/^system (shutdown message from|going down )/i); next if (/^\{(master|backup)(:\d+)?\}/); /error: the chassis subsystem is not running/ && return(-1); /Couldn\'t initiate connection/ && return(-1); /Unrecognized command/ && return(1); /command is not valid/ && return(1); /^\s+\^/ && return(1); /syntax error/ && return(1); ProcessHistory("","","","# $_"); } return(0); } # This routine parses "show chassis fpc detail" sub ShowChassisFpcDetail { print STDERR " In ShowChassisFpcDetail: $_" if ($debug); s/^[a-z]+@//; ProcessHistory("","","","# $_"); while () { tr/\015//d; last if (/^$prompt/); return 1 if (/^aborted!/i); next if (/^system (shutdown message from|going down )/i); next if (/^\{(master|backup)(:\d+)?\}/); /error: the chassis subsystem is not running/ && return(-1); /Couldn\'t initiate connection/ && return(-1); /Unrecognized command/ && return(1); /command is not valid/ && return(1); /^\s+\^/ && return(1); /syntax error/ && return(1); / Temperature/ && next; / Start time/ && next; / Uptime/ && next; ProcessHistory("","","","# $_"); } return(0); } # This routine parses "show chassis hardware" sub ShowChassisHardware { print STDERR " In ShowChassisHardware: $_" if ($debug); s/^[a-z]+@//; ProcessHistory("","","","# $_"); while () { tr/\015//d; last if (/^$prompt/); return 1 if (/^aborted!/i); next if (/^system (shutdown message from|going down )/i); next if (/^\{(master|backup)(:\d+)?\}/); /error: the chassis subsystem is not running/ && return(-1); /Couldn\'t initiate connection/ && return(-1); /Unrecognized command/ && return(1); /command is not valid/ && return(1); /^\s+\^/ && return(1); /syntax error/ && return(1); ProcessHistory("","","","# $_"); } return(0); } # This routine parses "show chassis routing-engine" # Most output is ignored. sub ShowChassisRoutingEngine { print STDERR " In ShowChassisRoutingEngine: $_" if ($debug); s/^[a-z]+@//; ProcessHistory("","","","# $_"); while () { tr/\015//d; last if (/^$prompt/); next if (/^system (shutdown message from|going down )/i); next if (/^\{(master|backup)(:\d+)?\}/); /error: the chassis subsystem is not running/ && return(-1); /Couldn\'t initiate connection/ && return(-1); /Unrecognized command/ && return(1); /command is not valid/ && return(1); /^\s+\^/ && return(1); /syntax error/ && return(1); /^Routing Engine status:/ && ProcessHistory("","","","# $_") && next; / Slot / && ProcessHistory("","","","# $_") && next; / Current state/ && ProcessHistory("","","","# $_") && next; / Election priority/ && ProcessHistory("","","","# $_") && next; / DRAM/ && ProcessHistory("","","","# $_") && next; / Model/ && ProcessHistory("","","","# $_") && next; / Serial ID/ && ProcessHistory("","","","# $_") && next; /^\s*$/ && ProcessHistory("","","","# $_") && next; } return(0); } # This routine parses "show chassis cfeb", "show chassis feb", "show # chassis scb", "show chassis sfm detail", and "show chassis ssb". # Only do this routine once. sub ShowChassisSCB { print STDERR " In ShowChassisSCB: $_" if ($debug); s/^[a-z]+@//; ProcessHistory("","","","# $_"); while () { tr/\015//d; last if (/^$prompt/); next if (/^system (shutdown message from|going down )/i); next if (/^\{(master|backup)(:\d+)?\}/); return(0) if ($ShowChassisSCB); /error: the chassis subsystem is not running/ && return(-1); /Couldn\'t initiate connection/ && return(-1); /Unrecognized command/ && return(1); /command is not valid/ && return(1); /^\s+\^/ && return(1); /syntax error/ && return(1); / Temperature/ && next; / temperature/ && next; / utilization/ && next; / Start time/ && next; / Uptime/ && next; / (IP|MLPS) routes:/ && next; / used:/ && next; ProcessHistory("","","","# $_"); } $ShowChassisSCB = 1; return(0); } # This routine parses "show chassis alarms" sub ShowChassisAlarms { print STDERR " In ShowChassisAlarms: $_" if ($debug); s/^[a-z]+@//; ProcessHistory("","","","# $_"); while () { tr/\015//d; last if (/^$prompt/); next if (/^system (shutdown message from|going down )/i); next if (/^\{(master|backup)(:\d+)?\}/); /Unrecognized command/ && return(1); /command is not valid/ && return(1); /^\s+\^/ && return(1); /syntax error/ && return(1); ProcessHistory("","","","# $_"); } return(0); } # This routine parses "show system autoinstallation status" sub ShowSystemAutoinstall { print STDERR " In ShowSystemAutoinstall: $_" if ($debug); s/^[a-z]+@//; ProcessHistory("","","","# $_"); while () { tr/\015//d; last if (/^$prompt/); next if (/^system (shutdown message from|going down )/i); next if (/^\{(master|backup)(:\d+)?\}/); /Unrecognized command/ && return(1); /command is not valid/ && return(1); /^\s+\^/ && return(1); /syntax error/ && return(1); ProcessHistory("","","","# $_"); } return(0); } sub ShowSystemCoreDumps { print STDERR " In ShowSystemCoreDumps: $_" if ($debug); s/^[a-z]+@//; ProcessHistory("","","","# $_"); while () { tr/\015//d; last if (/^$prompt/); /Unrecognized command/ && return(1); /command is not valid/ && return(1); /^\s+\^/ && return(1); /syntax error/ && return(1); /^JUNOS / && && next; /No such file or directory$/ && next; ProcessHistory("","","","# $_"); } return(0); } # This routine parses "show system license" sub ShowSystemLicense { print STDERR " In ShowSystemLicense: $_" if ($debug); s/^[a-z]+@//; ProcessHistory("","","","# $_"); while () { tr/\015//d; last if (/^$prompt/); next if (/^system (shutdown message from|going down )/i); next if (/^\{(master|backup)(:\d+)?\}/); /Unrecognized command/ && return(1); /command is not valid/ && return(1); /^\s+\^/ && return(1); /syntax error/ && return(1); ProcessHistory("","","","# $_"); } return(0); } # This routine parses "show system license keys" sub ShowSystemLicenseKeys { print STDERR " In ShowSystemLicenseKeys: $_" if ($debug); s/^[a-z]+@//; ProcessHistory("","","","# $_"); while () { tr/\015//d; last if (/^$prompt/); next if (/^system (shutdown message from|going down )/i); next if (/^\{(master|backup)(:\d+)?\}/); /Unrecognized command/ && return(1); /command is not valid/ && return(1); /^\s+\^/ && return(1); /syntax error/ && return(1); ProcessHistory("","","","# $_"); } return(0); } # This routine parses "show system boot-messages" sub ShowSystemBootMessages { print STDERR " In ShowSystemBootMessages: $_" if ($debug); s/^[a-z]+@//; ProcessHistory("","","","# $_"); while () { tr/\015//d; last if (/^$prompt/); next if (/^system (shutdown message from|going down )/i); next if (/^\{(master|backup)(:\d+)?\}/); /Unrecognized command/ && return(1); /command is not valid/ && return(1); /^\s+\^/ && return(1); /syntax error/ && return(1); /^JUNOS / && && next; /^Timecounter "TSC" / && next; /^real memory / && next; /^avail memory / && next; /^\/dev\// && next; ProcessHistory("","","","# $_"); } return(0); } # This routine parses "show version" sub ShowVersion { print STDERR " In ShowVersion: $_" if ($debug); s/^[a-z]+@//; ProcessHistory("","","","# $_"); while () { tr/\015//d; last if (/^$prompt/); next if (/^\s*$/); next if (/^system (shutdown message from|going down )/i); next if (/^\{(master|backup)(:\d+)?\}/); /^Juniper Networks is:/ && ProcessHistory("","","","# \n# $_") && next; ProcessHistory("","","","# $_"); } ProcessHistory("","","","#\n"); return(0); } # This routine parses "show configuration" sub ShowConfiguration { my($lines) = 0; my($snmp) = 0; print STDERR " In ShowConfiguration: $_" if ($debug); s/^[a-z]+@//; ProcessHistory("","","","# $_"); while () { tr/\015//d; next if (/^\s*$/); # end of config - hopefully. juniper does not have a reliable # end-of-config tag. appears to end with "\nPROMPT>", but not sure. if (/^$prompt/) { $found_end++; last; } next if (/^system (shutdown message from|going down )/i); next if (/^\{(master|backup)(:\d+)?\}/); $lines++; /^database header mismatch: / && return(-1); /^version .*;\d+$/ && return(-1); s/ # SECRET-DATA$//; s/ ## SECRET-DATA$//; # filter snmp community, when in snmp { stanza } /^snmp/ && $snmp++; /^}/ && ($snmp = 0); if ($snmp && /^(\s*)(community|trap-group) [^ ;]+(\s?[;{])$/) { if ($filter_commstr) { $_ = "$1$2 \"\"$3\n"; } } if (/(\s*authentication-key )[^ ;]+/ && $filter_pwds >= 1) { ProcessHistory("","","","#$1$'"); next; } if (/(\s*md5 \d+ key )[^ ;]+/ && $filter_pwds >= 1) { ProcessHistory("","","","#$1$'"); next; } if (/(\s*hello-authentication-key )[^ ;]+/ && $filter_pwds >= 1) { ProcessHistory("","","","#$1$'"); next; } # don't filter this one - there is no secret here. if (/^\s*permissions .* secret /) { ProcessHistory("","","","$_"); next; } if (/^(.*\ssecret )[^ ;]+/ && $filter_pwds >= 1) { ProcessHistory("","","","#$1$'"); next; } if (/(\s+encrypted-password )[^ ;]+/ && $filter_pwds >= 2) { ProcessHistory("","","","#$1$'"); next; } if (/(\s+ssh-(rsa|dsa) )\"/ && $filter_pwds >= 2) { ProcessHistory("","","","#$1;\n"); next; } if (/^(\s+(pre-shared-|)key (ascii-text|hexadecimal) )[^ ;]+/ && $filter_pwds >= 1) { ProcessHistory("","","","#$1$'"); next; } ProcessHistory("","","","$_"); } if ($lines < 3) { printf(STDERR "ERROR: $host configuration appears truncated.\n"); $found_end = 0; return(-1); } return(0); } ### ### End of real work ### # dummy function sub DoNothing {print STDOUT;} # Main @commandtable = ( {'show chassis clocks' => 'ShowChassisClocks'}, {'show chassis environment' => 'ShowChassisEnvironment'}, {'show chassis firmware' => 'ShowChassisFirmware'}, {'show chassis fpc detail' => 'ShowChassisFpcDetail'}, {'show chassis hardware detail' => 'ShowChassisHardware'}, {'show chassis routing-engine' => 'ShowChassisRoutingEngine'}, {'show chassis scb' => 'ShowChassisSCB'}, {'show chassis sfm detail' => 'ShowChassisSCB'}, {'show chassis ssb' => 'ShowChassisSCB'}, {'show chassis feb detail' => 'ShowChassisSCB'}, {'show chassis feb' => 'ShowChassisSCB'}, {'show chassis cfeb' => 'ShowChassisSCB'}, {'show chassis alarms' => 'ShowChassisAlarms'}, # {'show system autoinstallation status' => 'ShowSystemAutoinstall'}, {'show system license' => 'ShowSystemLicense'}, # {'show system license keys' => 'ShowSystemLicenseKeys'}, {'show system boot-messages' => 'ShowSystemBootMessages'}, {'show system core-dumps' => 'ShowSystemCoreDumps'}, {'show version detail' => 'ShowVersion'}, {'show configuration' => 'ShowConfiguration'} ); # 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); $jnx_commands=join(";",@commands); $cmds_regexp = join("|", map quotemeta($_), @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 ($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 echo jlogin -t $timeo -c\"$jnx_commands\" $host\n") if ($debug); print(STDOUT "executing echo jlogin -t $timeo -c\"$jnx_commands\" $host\n") if ($debug); if (defined($ENV{NOPIPE}) && $ENV{NOPIPE} =~ /^YES/i) { system "jlogin -t $timeo -c \"$jnx_commands\" $host $host.raw" || die "jlogin failed for $host: $!\n"; open(INPUT, "< $host.raw") || die "jlogin failed for $host: $!\n"; } else { open(INPUT,"jlogin -t $timeo -c \"$jnx_commands\" $host ) { tr/\015//d; if (/^Error:/) { print STDOUT ("$host jlogin error: $_"); print STDERR ("$host jlogin error: $_") if ($debug); $clean_run=0; last; } if (/System shutdown message/) { print STDOUT ("$host shutdown msg: $_"); print STDERR ("$host shutdown msg: $_") if ($debug); $clean_run = 0; last; } if (/error: cli version does not match Managment Daemon/i) { print STDOUT ("$host mgd version mismatch: $_"); print STDERR ("$host mgd version mismatch: $_") if ($debug); $clean_run = 0; last; } while (/>\s*($cmds_regexp)\s*$/) { $cmd = $1; 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; } $rval = &{$commands{$cmd}}; delete($commands{$cmd}); if ($rval == -1) { $clean_run = 0; last TOP; } } if (/>\s*quit/) { $clean_run=1; last; } } print STDOUT "Done jlogin: $_\n" if ($log); # Flush History ProcessHistory("","","",""); # Cleanup close(INPUT); close(OUTPUT); if (defined($ENV{NOPIPE}) && $ENV{NOPIPE} =~ /^YES/i) { unlink("$host.raw") if (! $debug); } # check for completeness $commands = join(", ", keys(%commands)); 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); } rancid-2.3.8/bin/mrancid.in100644 015615 000000 00000032723 11535733223 0011206#! @PERLV_PATH@ ## ## $Id: mrancid.in 2279 2011-01-31 22:41:00Z heas $ ## ## @PACKAGE@ @VERSION@ ## Copyright (c) 1997-2008 by Terrapin Communications, Inc. ## All rights reserved. ## ## This code is derived from software contributed to and maintained by ## Terrapin Communications, Inc. by Henry Kilmer, John Heasley, Andrew Partan, ## Pete Whiting, Austin Schutz, and Andrew Fort. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions ## are met: ## 1. Redistributions of source code must retain the above copyright ## notice, this list of conditions and the following disclaimer. ## 2. Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## 3. All advertising materials mentioning features or use of this software ## must display the following acknowledgement: ## This product includes software developed by Terrapin Communications, ## Inc. and its contributors for RANCID. ## 4. Neither the name of Terrapin Communications, Inc. nor the names of its ## contributors may be used to endorse or promote products derived from ## this software without specific prior written permission. ## 5. It is requested that non-binding fixes and modifications be contributed ## back to Terrapin Communications, Inc. ## ## THIS SOFTWARE IS PROVIDED BY Terrapin Communications, INC. AND CONTRIBUTORS ## ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ## TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COMPANY OR CONTRIBUTORS ## BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ## CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ## SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ## INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ## CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ## ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ## POSSIBILITY OF SUCH DAMAGE. # # Amazingly hacked version of Hank's rancid - this one tries to # deal with MRTd. # # RANCID - Really Awesome New Cisco confIg Differ # # usage: rancid [-dV] [-l] [-f filename | hostname] # use Getopt::Std; 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 my(@commandtable, %commands, @commands);# command lists my($aclsort) = ("ipsort"); # ACL sorting mode my($filter_commstr); # SNMP community string filtering 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)) && scalar(%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 routine 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 routine 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 routine 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 routine (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 "show version" sub ShowVersion { print STDERR " In ShowVersion: $_" if ($debug); while () { tr/\015//d; last if(/^$prompt/); next if(/^(\s*|\s*$cmd\s*)$/); return(-1) if (/command authorization failed/i); /compiled on /i && next; /UP for /i && next; ProcessHistory("COMMENTS","keysort","A0", "!$_"); } return(0); } # This routine processes a "write term" sub WriteTerm { print STDERR " In WriteTerm: $_" if ($debug); while () { tr/\015//d; if (/$prompt\s*exit\s*$/) { $clean_run=1; last; } last if(/^$prompt/); 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 # filter out any RCS/CVS tags to avoid confusing local CVS storage s/\$(Revision|Id):/ $1:/; if (/^(enable )?(password|passwd) / && $filter_pwds >= 1) { ProcessHistory("ENABLE","","","!$1$2 \n"); next; } if (/^username (\S+)(\s.*)? password /) { if ($filter_pwds >= 1) { ProcessHistory("USER","keysort","$1","!username $1$2 password \n"); } else { ProcessHistory("USER","keysort","$1","$_"); } next; } if (/^(\s*)password / && $filter_pwds >= 1) { ProcessHistory("LINE-PASS","","","!$1password \n"); next; } if (/^\s*neighbor (\S*) password / && $filter_pwds >= 1) { ProcessHistory("","","","! neighbor $1 password \n"); next; } if (/^( ip ospf authentication-key) / && $filter_pwds >= 1) { ProcessHistory("","","","!$1 \n"); next; } if (/^( ip ospf message-digest-key \d+ md5) / && $filter_pwds >= 1) { ProcessHistory("","","","!$1 \n"); next; } # sort route-maps if (/^route-map (\S+)/) { my($key) = $1; my($routemap) = $_; while () { tr/\015//d; last if (/^$prompt/ || ! /^(route-map |[ !])/); if (/^route-map (\S+)/) { ProcessHistory("ROUTEMAP","keysort","$key","$routemap"); $key = $1; $routemap = $_; } else { $routemap .= $_; } } ProcessHistory("ROUTEMAP","keysort","$key","$routemap"); } # catch anything that wasnt match above. ProcessHistory("","","","$_"); next; # order access-lists /^access-list\s+(\d\d?)\s+(\S+)\s+(\S+)/ && ProcessHistory("ACL $1 $2","$aclsort","$3","$_") && next; # order extended access-lists /^access-list\s+(\d\d\d)\s+(\S+)\s+ip\s+host\s+(\S+)/ && ProcessHistory("EACL $1 $2","$aclsort","$3","$_") && next; /^access-list\s+(\d\d\d)\s+(\S+)\s+ip\s+(\d\S+)/ && ProcessHistory("EACL $1 $2","$aclsort","$3","$_") && next; /^access-list\s+(\d\d\d)\s+(\S+)\s+ip\s+any/ && ProcessHistory("EACL $1 $2","$aclsort","0.0.0.0","$_") && next; # order arp lists /^arp\s+(\d+\.\d+\.\d+\.\d+)\s+/ && ProcessHistory("ARP","$aclsort","$1","$_") && next; /^ip prefix-list\s+(\S+)\s+seq\s+(\d+)\s+(permit|deny)\s+(\d\S+)(\/.*)$/ && ProcessHistory("PACL $1 $3","$aclsort","$4","ip prefix-list $1 $3 $4$5\n") && next; # order logging statements /^logging (\d+\.\d+\.\d+\.\d+)/ && ProcessHistory("LOGGING","ipsort","$1","$_") && next; # order/prune snmp-server host statements # we only prune lines of the form # snmp-server host a.b.c.d if (/^snmp-server host (\d+\.\d+\.\d+\.\d+) /) { if ($filter_commstr) { my($ip) = $1; my($line) = "snmp-server host $ip"; my(@tokens) = split(' ', $'); my($token); while ($token = shift(@tokens)) { if ($token eq 'version') { $line .= " " . join(' ', ($token, shift(@tokens))); } elsif ($token =~ /^(informs?|traps?|(no)?auth)$/) { $line .= " " . $token; } else { $line = "!$line " . join(' ', ("", join(' ',@tokens))); last; } } ProcessHistory("SNMPSERVERHOST","ipsort","$ip","$line\n"); } else { ProcessHistory("SNMPSERVERHOST","ipsort","$1","$_"); } next; } if (/^(snmp-server community) (\S+)/) { if ($filter_commstr) { ProcessHistory("SNMPSERVERCOMM","keysort","$_","!$1 $'") && next; } else { ProcessHistory("SNMPSERVERCOMM","keysort","$_","$_") && next; } } # order clns host statements /^clns host \S+ (\S+)/ && ProcessHistory("CLNS","keysort","$1","$_") && next; # order alias statements /^alias / && ProcessHistory("ALIAS","keysort","$_","$_") && next; # order ntp peers/servers if (/^ntp (server|peer) (\d+)\.(\d+)\.(\d+)\.(\d+)/) { $sortkey = sprintf("$1 %03d%03d%03d%03d",$2,$3,$4,$5); ProcessHistory("NTP","keysort",$sortkey,"$_"); next; } # order ip host line statements /^ip host line(\d+)/ && ProcessHistory("IPHOST","numsort","$1","$_") && next; # end of config if (/^(: )?end$/) { $found_end = 1; return(1); } } return(0); } # dummy function sub DoNothing {print STDOUT;} # Main @commandtable = ( {'show version' => 'ShowVersion'}, {'show config' => 'WriteTerm'} ); # 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("|", map quotemeta($_), @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 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 clogin -t $timeo -c\"$cisco_cmds\" $host\n" if ($debug); print STDOUT "executing clogin -t $timeo -c\"$cisco_cmds\" $host\n" if ($log); if (defined($ENV{NOPIPE}) && $ENV{NOPIPE} =~ /^YES/i) { system "clogin -t $timeo -c \"$cisco_cmds\" $host $host.raw 2>&1" || die "clogin failed for $host: $!\n"; open(INPUT, "< $host.raw") || die "clogin failed for $host: $!\n"; } else { open(INPUT,"clogin -t $timeo -c \"$cisco_cmds\" $host ) { tr/\015//d; if (/^Error:/) { print STDOUT ("$host clogin error: $_"); print STDERR ("$host clogin error: $_") if ($debug); $clean_run=0; last; } while (/#\s*($cmds_regexp)\s*$/) { $cmd = $1; if (!defined($prompt)) { $prompt = ($_ =~ /^([^#]+)/)[0]; $prompt =~ s/([][}{)(\\])/\\$1/g; $prompt .= "[#>]"; 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; } $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}) && $ENV{NOPIPE} =~ /^YES/i) { unlink("$host.raw") if (! $debug); } # check for completeness if (scalar(%commands) || !$clean_run) { 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) { 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); } rancid-2.3.8/bin/mrvlogin.in100644 015615 000000 00000053727 11712067106 0011432#! @EXPECT_PATH@ -- ## ## $Id: mrvlogin.in 2376 2012-01-31 22:42:14Z heas $ ## ## @PACKAGE@ @VERSION@ ## Copyright (c) @COPYYEARS@ by Terrapin Communications, Inc. ## All rights reserved. ## ## This code is derived from software contributed to and maintained by ## Terrapin Communications, Inc. by Henry Kilmer, John Heasley, Andrew Partan, ## Pete Whiting, Austin Schutz, and Andrew Fort. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions ## are met: ## 1. Redistributions of source code must retain the above copyright ## notice, this list of conditions and the following disclaimer. ## 2. Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## 3. All advertising materials mentioning features or use of this software ## must display the following acknowledgement: ## This product includes software developed by Terrapin Communications, ## Inc. and its contributors for RANCID. ## 4. Neither the name of Terrapin Communications, Inc. nor the names of its ## contributors may be used to endorse or promote products derived from ## this software without specific prior written permission. ## 5. It is requested that non-binding fixes and modifications be contributed ## back to Terrapin Communications, Inc. ## ## THIS SOFTWARE IS PROVIDED BY Terrapin Communications, INC. AND CONTRIBUTORS ## ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ## TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COMPANY OR CONTRIBUTORS ## BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ## CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ## SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ## INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ## CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ## ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ## POSSIBILITY OF SUCH DAMAGE. # # The expect login scripts were based on Erik Sherk's gwtn, by permission. # # clogin - Cisco login # # Most options are intuitive for logging into a Cisco router. # The default is to enable (thus -noenable). Some folks have # setup tacacs to have a user login at priv-lvl = 15 (enabled) # so the -autoenable flag was added for this case (don't go through # the process of enabling and the prompt will be the "#" prompt. # The default username password is the same as the vty password. # # Usage line set usage "Usage: $argv0 \[-dSV\] \[-autoenable\] \[-noenable\] \[-c command\] \ \[-Evar=x\] \[-e enable-password\] \[-f cloginrc-file\] \[-p user-password\] \ \[-s script-file\] \[-t timeout\] \[-u username\] \ \[-v vty-password\] \[-w enable-username\] \[-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 avenable 1 # The default is that you login non-enabled (tacacs can have you login already # enabled) set avautoenable 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 set do_enapasswd 1 # Save config, if prompted set do_saveconfig 0 # Sometimes routers take awhile to answer (the default is 10 sec) set timeoutdflt 45 # set send_human {.4 .4 .7 .3 5} # 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) } elseif {[ info exists env(LOGNAME) ]} { set default_user $env(LOGNAME) } 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 "\nError: could not exec id: $reason\n" exit 1 } regexp {\(([^)]*)} "$reason" junk default_user } if {[ info exists env(CLOGINRC) ]} { set password_file $env(CLOGINRC) } # Process the command line for {set i 0} {$i < $argc} {incr i} { set arg [lindex $argv $i] switch -glob -- $arg { # Expect debug mode -d* { exp_internal 1 # Username } -u* { if {! [regexp .\[uU\](.+) $arg ignore user]} { incr i set username [ lindex $argv $i ] } # VTY Password } -p* { if {! [regexp .\[pP\](.+) $arg ignore userpasswd]} { incr i set userpasswd [ lindex $argv $i ] } set do_passwd 0 # ssh passphrase } -r* { # ignore -r # VTY Password } -v* { if {! [regexp .\[vV\](.+) $arg ignore passwd]} { incr i set passwd [ lindex $argv $i ] } set do_passwd 0 # Version string } -V* { send_user "@PACKAGE@ @VERSION@\n" exit 0 # Enable Username } -w* { if {! [regexp .\[wW\](.+) $arg ignore enauser]} { incr i set enausername [ lindex $argv $i ] } # Environment variable to pass to -s scripts } -E* { if {[regexp .\[E\](.+)=(.+) $arg ignore varname varvalue]} { set E$varname $varvalue } else { send_user "\nError: invalid format for -E in $arg\n" exit 1 } # Enable Password } -e* { if {! [regexp .\[e\](.+) $arg ignore enapasswd]} { incr i set enapasswd [ lindex $argv $i ] } set do_enapasswd 0 # Command to run. } -c* { if {! [regexp .\[cC\](.+) $arg ignore command]} { incr i set command [ lindex $argv $i ] } set do_command 1 # Expect script to run. } -s* { if {! [regexp .\[sS\](.+) $arg ignore sfile]} { incr i set sfile [ lindex $argv $i ] } if { ! [ file readable $sfile ] } { send_user "\nError: Can't read $sfile\n" exit 1 } set do_script 1 # save config on exit } -S* { set do_saveconfig 1 # 'ssh -c' cypher type } -y* { if {! [regexp .\[eE\](.+) $arg ignore cypher]} { incr i set cypher [ lindex $argv $i ] } # alternate cloginrc file } -f* { if {! [regexp .\[fF\](.+) $arg ignore password_file]} { incr i set password_file [ lindex $argv $i ] } # Timeout } -t* { if {! [regexp .\[tT\](.+) $arg ignore timeout]} { incr i set timeoutdflt [ lindex $argv $i ] } # Command file } -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 { set avenable 0 # Does tacacs automatically enable us? } -autoenable { set avautoenable 1 set avenable 0 } -* { send_user "\nError: Unknown argument! $arg\n" send_user $usage exit 1 } default { break } } } # Process routers...no routers listed is an error. if { $i == $argc } { send_user "\nError: $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 "\nError: password file ($password_file) does not exist\n" exit 1 } file stat $password_file fileinfo if { [expr ($fileinfo(mode) & 007)] != 0000 } { send_user "\nError: $password_file must not be world readable/writable\n" exit 1 } if [ catch {source $password_file} reason ] { send_user "\nError: $reason\n" exit 1 } } # Log into the router. # returns: 0 on success, 1 on failure proc login { router user userpswd passwd enapasswd cmethod cyphertype } { global command spawn_id in_proc do_command do_script global prompt u_prompt p_prompt e_prompt sshcmd 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] { incr progs -1 if [string match "telnet*" $prog] { regexp {telnet(:([^[:space:]]+))*} $prog methcmd 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" return 1 } } elseif [string match "ssh*" $prog] { regexp {ssh(:([^[:space:]]+))*} $prog methcmd suffix port set cmd $sshcmd if {"$port" != ""} { set cmd "$cmd -p $port" } set retval [ catch {eval spawn [split "$cmd -c $cyphertype -x -l $user $router" { }]} reason ] if { $retval } { send_user "\nError: $sshcmd failed: $reason\n" return 1 } } else { send_user "\nError: unknown connection method: $prog\n" return 1 } sleep 0.3 # This helps cleanup each expect clause. expect_after { timeout { send_user "\nError: TIMEOUT reached\n" catch {close}; catch {wait}; if { $in_proc} { return 1 } else { continue } } eof { send_user "\nError: EOF received\n" catch {close}; catch {wait}; if { $in_proc} { return 1 } else { continue } } } # Here we get a little tricky. There are several possibilities: # the router can ask for a username and passwd and then # talk to the TACACS server to authenticate you, or if the # TACACS server is not working, then it will use the enable # passwd. Or, the router might not have TACACS turned on, # then it will just send the passwd. # if telnet fails with connection refused, try ssh expect { -re "(Connection refused|Secure connection \[^\n\r]+ refused)" { catch {close}; catch {wait}; if !$progs { send_user "\nError: Connection Refused ($prog): $router\n" return 1 } } -re "(Connection closed by|Connection to \[^\n\r]+ closed)" { catch {close}; catch {wait}; if !$progs { send_user "\nError: Connection closed ($prog): $router\n" return 1 } } eof { send_user "\nError: Couldn't login: $router\n"; wait; return 1 } -nocase "unknown host\r" { send_user "\nError: Unknown host $router\n"; catch {close}; catch {wait}; return 1 } "Host is unreachable" { send_user "\nError: Host Unreachable: $router\n"; catch {close}; catch {wait}; return 1 } "No address associated with name" { send_user "\nError: Unknown host $router\n"; catch {close}; catch {wait}; return 1 } -re "(Host key not found |The authenticity of host .* be established).* \\(yes/no\\)\\?" { send "yes\r" send_user "\nHost $router added to the list of known hosts.\n" exp_continue } -re "HOST IDENTIFICATION HAS CHANGED.* \\(yes/no\\)\\?" { send "no\r" send_user "\nError: The host key for $router has changed. Update the SSH known_hosts file accordingly.\n" catch {close}; catch {wait}; return 1 } -re "HOST IDENTIFICATION HAS CHANGED\[^\n\r]+" { send_user "\nError: The host key for $router has changed. Update the SSH known_hosts file accordingly.\n" return 1 } -re "Offending key for .* \\(yes/no\\)\\?" { send "no\r" send_user "\nError: host key mismatch for $router. Update the SSH known_hosts file accordingly.\n" catch {close}; catch {wait}; return 1 } -re "(denied|Sorry)" { send_user "\nError: Check your passwd for $router\n" catch {close}; catch {wait}; return 1 } -re "Login (failed|incorrect)" { send_user "\nError: Check your passwd for $router\n" catch {close}; catch {wait}; return 1 } -re "% (Bad passwords|Authentication failed)" { send_user "\nError: Check your passwd for $router\n" catch {close}; catch {wait}; return 1 } "Press any key to continue" { # send_user "Pressing the ANY key\n" send "\r" exp_continue } -re "Enter Selection: " { # Catalyst 1900s have some lame menu. Enter # K to reach a command-line. send "K\r" exp_continue } -re "Last login:" { exp_continue } -re "@\[^\r\n]+ $p_prompt" { # ssh pwd prompt sleep 1 send -h -- "$userpswd\r" exp_continue } -re "$u_prompt" { send -h -- "$user\r" set uprompt_seen 1 exp_continue } -re "$p_prompt" { sleep 1 if {$uprompt_seen == 1} { send -h -- "$userpswd\r" } else { send -h -- "$passwd\r" } exp_continue } -re "$prompt" { break; } "Login invalid" { send_user "\nError: Invalid login: $router\n"; catch {close}; catch {wait}; return 1 } -re "\[^\r\n]\[\r\n]+" { exp_continue } } } set in_proc 0 return 0 } # Enable proc do_enable { enauser enapasswd } { global prompt in_proc global u_prompt e_prompt set in_proc 1 send -h "enable\r" expect { -re "$u_prompt" { send -h -- "$enauser\r"; exp_continue} -re "$e_prompt" { send -h -- "$enapasswd\r"; exp_continue} "#" { set prompt "#" } -re "(denied|Sorry|Incorrect)" { # % Access denied - from local auth and poss. others send_user "\nError: Check your Enable passwd\n"; return 1 } "% Error in authentication" { send_user "\nError: Check your Enable passwd\n" return 1 } "% Bad passwords" { send_user "\nError: Check your Enable passwd\n" return 1 } } # We set the prompt variable (above) so script files don't need # to know what it is. 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 -h "terminal length 0\r" # escape any parens in the prompt, such as "(enable)" regsub -all {[)(]} $prompt {\\&} reprompt # match cisco config mode prompts too, such as router(config-if)#, # but catalyst does not change in this fashion. regsub -all {^(.{1,11}).*([#>])$} $reprompt {\1([^#>\r\n]+)?\2(\\([^)\\r\\n]+\\))?} reprompt expect { -re $reprompt {} -re "\[\n\r]+" { exp_continue } } # this is the only way i see to get rid of more prompts in o/p..grrrrr log_user 0 set commands [split $command \;] set num_commands [llength $commands] # the pager can not be turned off on the PIX, so we have to look # for the "More" prompt. the extreme is equally obnoxious, with a # global switch in the config. # XXX I think the pager can be turned off and this is just an artifact of # clogin for {set i 0} {$i < $num_commands} { incr i} { send -h -- "[subst -nocommands [lindex $commands $i]]\r" expect { -re "\b+" { exp_continue } -re "^\[^\n\r *]*$reprompt" { send_user -- "$expect_out(buffer)" } -re "^\[^\n\r]*$reprompt." { send_user -- "$expect_out(buffer)" exp_continue } -re "^--More--\[\r\n]+" { # specific match c1900 pager send " " exp_continue } -re "\[\n\r]+" { send_user -- "$expect_out(buffer)" exp_continue } -re "\[^\r\n]*Press to cont\[^\r\n]*" { send " " # bloody ^[[2K after " " expect { -re "^\[^\r\n]*\r" {} } exp_continue } -re "^ *--More--\[^\n\r]*" { send " " exp_continue } -re "^<-+ More -+>\[^\n\r]*" { send_user -- "$expect_out(buffer)" send " " exp_continue } } } log_user 1 send -h "exit\r" expect { -re "^\[^\n\r *]*$reprompt" { # the Cisco CE and Jnx ERX # return to non-enabled mode # on exit in enabled mode. send -h "exit\r" exp_continue; } "Would you like to save them now" { # Force10 send "n\r" exp_continue } "Configuration changes have occurred.*" { # Cisco CSS send "n\r" exp_continue } "Do you wish to save your configuration changes" { send "n\r" exp_continue } -re "\[\n\r]+" { exp_continue } timeout { catch {close}; catch {wait}; 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 set exitval 0 foreach router [lrange $argv $i end] { set router [string tolower $router] send_user -- "$router\n" # device timeout set timeout [find timeout $router] if { [llength $timeout] == 0 } { set timeout $timeoutdflt } # Figure out the prompt. # autoenable is off by default. If we have it defined, it was done # on the command line. If it is not specifically set on the command # line, check the password file. if $avautoenable { set autoenable 1 set enable 0 set prompt "#\[^\[:digit:]]" } else { set ae [find autoenable $router] if { "$ae" == "1" } { set autoenable 1 set enable 0 set prompt "#\[^\[:digit:]]" } else { set autoenable 0 set enable $avenable set prompt ">" } } # look for noenable option in .cloginrc if { [find noenable $router] == "1" } { set enable 0 } # Figure out passwords if { $do_passwd || $do_enapasswd } { set pswd [find password $router] if { [llength $pswd] == 0 } { send_user -- "\nError: no password for $router in $password_file.\n" continue } if { $enable && $do_enapasswd && $autoenable == 0 && [llength $pswd] < 2 } { send_user -- "\nError: no enable password for $router in $password_file.\n" continue } set passwd [join [lindex $pswd 0] ""] set enapasswd [join [lindex $pswd 1] ""] } else { set passwd $userpasswd set enapasswd $enapasswd } # Figure out username if {[info exists username]} { # command line username set ruser $username } else { set ruser [join [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 [join [find userpassword $router] ""] if { "$userpswd" == "" } { set userpswd $passwd } } # Figure out enable username if {[info exists enausername]} { # command line enausername set enauser $enausername } else { set enauser [join [find enauser $router] ""] if { "$enauser" == "" } { set enauser $ruser } } # Figure out prompts set u_prompt [find userprompt $router] if { "$u_prompt" == "" } { set u_prompt "(Username|Login|login|user name):" } else { set u_prompt [join [lindex $u_prompt 0] ""] } set p_prompt [find passprompt $router] if { "$p_prompt" == "" } { set p_prompt "(\[Pp]assword|passwd):" } else { set p_prompt [join [lindex $p_prompt 0] ""] } set e_prompt [find enableprompt $router] if { "$e_prompt" == "" } { set e_prompt "\[Pp]assword:" } else { set e_prompt [join [lindex $e_prompt 0] ""] } # 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}} } # Figure out the SSH executable name set sshcmd [join [lindex [find sshcmd $router] 0] ""] if { "$sshcmd" == "" } { set sshcmd {ssh} } # Login to the router if {[login $router $ruser $userpswd $passwd $enapasswd $cmethod $cyphertype]} { incr exitval # if login failed, move on to the next device continue } if { $enable } { if {[do_enable $enauser $enapasswd]} { if { $do_command || $do_script } { incr exitval catch {close}; catch {wait}; continue } } } # we are logged in, now figure out the full prompt send "\r" expect { -re "\[\r\n]+" { exp_continue; } -re "^.+$prompt" { set junk $expect_out(0,string); regsub -all "\[\]\[]" $junk {\\&} prompt; } } if { $do_command } { if {[run_commands $prompt $command]} { incr exitval continue } } elseif { $do_script } { send -h "terminal length 0\r" expect -re $prompt {} source $sfile catch {close}; } else { label $router log_user 1 interact } # End of for each router catch {wait}; sleep 0.3 } exit $exitval rancid-2.3.8/bin/mrvrancid.in100644 015615 000000 00000040026 11711564471 0011554#! @PERLV_PATH@ ## ## $Id: mrvrancid.in 2368 2012-01-30 19:02:16Z heas $ ## ## @PACKAGE@ @VERSION@ ## Copyright (c) 1997-2008 by Terrapin Communications, Inc. ## All rights reserved. ## ## This code is derived from software contributed to and maintained by ## Terrapin Communications, Inc. by Henry Kilmer, John Heasley, Andrew Partan, ## Pete Whiting, Austin Schutz, and Andrew Fort. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions ## are met: ## 1. Redistributions of source code must retain the above copyright ## notice, this list of conditions and the following disclaimer. ## 2. Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## 3. All advertising materials mentioning features or use of this software ## must display the following acknowledgement: ## This product includes software developed by Terrapin Communications, ## Inc. and its contributors for RANCID. ## 4. Neither the name of Terrapin Communications, Inc. nor the names of its ## contributors may be used to endorse or promote products derived from ## this software without specific prior written permission. ## 5. It is requested that non-binding fixes and modifications be contributed ## back to Terrapin Communications, Inc. ## ## THIS SOFTWARE IS PROVIDED BY Terrapin Communications, INC. AND CONTRIBUTORS ## ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ## TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COMPANY OR CONTRIBUTORS ## BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ## CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ## SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ## INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ## CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ## ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ## POSSIBILITY OF SUCH DAMAGE. # # Amazingly hacked version of Hank's rancid - this one tries to # deal with MegaVision MRV. # # RANCID - Really Awesome New Cisco confIg Differ # # usage: rancid [-dV] [-l] [-f filename | hostname] # use Getopt::Std; getopts('dflV'); if ($opt_V) { print "@PACKAGE@ @VERSION@\n"; exit(0); } $log = $opt_l; $debug = $opt_d; $file = $opt_f; $host = $ARGV[0]; $ios = "IOS"; $clean_run = 0; $found_end = 0; $found_version = 0; $found_env = 0; $found_diag = 0; $timeo = 90; # clogin timeout in seconds # force a terminal type so as not to confuse the POS $ENV{'TERM'} = "vt100"; my(@commandtable, %commands, @commands);# command lists my($aclsort) = ("ipsort"); # ACL sorting mode my($filter_commstr); # SNMP community string filtering 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)) && scalar(%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 routine 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 routine 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 routine 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 routine (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 "show version" sub ShowVersion { print STDERR " In ShowVersion: $_" if ($debug); while () { tr/\015//d; if (/^$prompt/) { $found_version = 1; last}; next if (/^(\s*|\s*$cmd\s*)$/); return(1) if /(Invalid input detected|Type help or )/; return(0) if ($found_version); # Only do this routine once return(-1) if (/command authorization failed/i); /copyright/i && next; /^up/ && next; # skip voltage /\s+\d+V\s*\:\s*\d+\.?\d*/ && next; /Internal\ Temperature/i && next; /u-boot/i && ProcessHistory("COMMENTS","keysort","C1", "!ROM: $_") && next; ProcessHistory("COMMENTS","keysort","B1", "!Image: $_") && next; } ProcessHistory("COMMENTS","","","!\n"); return(0); } # This routine parses "show chassis" for the gsr # This will create arrays for hw info. sub ShowChassis { my($newfmt) = 0; # Skip if this is not a 1200n. print STDERR " In ShowChassis: $_" if ($debug); while () { tr/\015//d; last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); return(1) if /(Invalid input detected|Type help or )/; return(-1) if (/command authorization failed/i); s/\s+$//; $newfmt = 1 if (/\s+Serial Num$/); if (/Chassis +Model/ || /=======/) { ProcessHistory("COMMENTS","keysort","C1","!$_\n"); next; } # Trim the temp from the end of the slot line if ($newfmt) { s/(-?\d+)(\s+\w+)$//; my($fmt) = "%-" . length($1) . "s"; $_ = $_ . sprintf($fmt, "") . $2; } else { # the old format s/\S+$//; } ProcessHistory("COMMENTS","keysort","C1","!$_\n"); } ProcessHistory("COMMENTS","","","!\n"); return(0); } # This routine parses "show slots". sub ShowSlots { print STDERR " In ShowSlots: $_" if ($debug); while () { tr/\015//d; return if (/^\s*\^$/); last if (/online diag status/i); last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); return(-1) if (/command authorization failed/i); ProcessHistory("SLOTS","","","!$_"); next; } ProcessHistory("SLOTS","","","!\n"); return(0); } # This routine processes a "write term" sub WriteTerm { print STDERR " In WriteTerm: $_" if ($debug); my($lineauto,$comment,$linecnt) = (0,0,0); while () { tr/\015//d; last if (/^$prompt/); return(1) if /Line has invalid autocommand /; return(1) if (/(Invalid input detected|Type help or )/i); return(0) if ($found_end); # Only do this routine once return(-1) if (/command authorization failed/i); /Non-Volatile memory is in use/ && return(-1); # NvRAM is locked $linecnt++; $lineauto = 0 if (/^[^ ]/); # skip the crap if (/^(##+$|(Building|Current) configuration)/i) { while () { next if (/^Current configuration\s*:/i); next if (/^:/); next if (/^([%!].*|\s*)$/); last; } tr/\015//d; } # skip consecutive comment lines to avoid oscillating extra comment # line on some access servers. grrr. if (/^!/) { next if ($comment); ProcessHistory("","","",$_); $comment++; next; } $comment = 0; # 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 if (/^(enable )?(password|passwd)( level \d+)? / && $filter_pwds >= 1) { ProcessHistory("ENABLE","","","!$1$2$3 \n"); next; } if (/^(enable secret) / && $filter_pwds >= 2) { ProcessHistory("ENABLE","","","!$1 \n"); next; } if (/^username (\S+)(\s.*)? password (encrypted \S+|\S+)(\sclass .*$)/){ if ($filter_pwds >= 2) { ProcessHistory("USER","keysort","$1", "!username $1$2 password $4\n"); } else { ProcessHistory("USER","keysort","$1","$_"); } next; } if (/^(\s*)password / && $filter_pwds >= 1) { ProcessHistory("LINE-PASS","","","!$1password \n"); next; } # filter out any RCS/CVS tags to avoid confusing local CVS storage s/\$(Revision|Id):/ $1:/; # order access-lists /^access-list\s+(\d\d?)\s+(\S+)\s+(\S+)/ && ProcessHistory("ACL $1 $2","$aclsort","$3","$_") && next; # order extended access-lists /^access-list\s+(\d\d\d)\s+(\S+)\s+ip\s+host\s+(\S+)/ && ProcessHistory("EACL $1 $2","$aclsort","$3","$_") && next; /^access-list\s+(\d\d\d)\s+(\S+)\s+ip\s+(\d\S+)/ && ProcessHistory("EACL $1 $2","$aclsort","$3","$_") && next; /^access-list\s+(\d\d\d)\s+(\S+)\s+ip\s+any/ && ProcessHistory("EACL $1 $2","$aclsort","0.0.0.0","$_") && next; # order arp lists /^arp\s+(\d+\.\d+\.\d+\.\d+)\s+/ && ProcessHistory("ARP","$aclsort","$1","$_") && next; /^ip prefix-list\s+(\S+)\s+seq\s+(\d+)\s+(permit|deny)\s+(\d\S+)(\/.*)$/ && ProcessHistory("PACL $1 $3","$aclsort","$4","ip prefix-list $1 $3 $4$5\n") && next; # order logging statements /^logging (\d+\.\d+\.\d+\.\d+)/ && ProcessHistory("LOGGING","ipsort","$1","$_") && next; # order/prune snmp-server host statements # we only prune lines of the form # snmp-server host a.b.c.d if (/^snmp-server host (\d+\.\d+\.\d+\.\d+) /) { if ($filter_commstr) { my($ip) = $1; my($line) = "snmp-server host $ip"; my(@tokens) = split(' ', $'); my($token); while ($token = shift(@tokens)) { if ($token eq 'version') { $line .= " " . join(' ', ($token, shift(@tokens))); if ($token eq '3') { $line .= " " . join(' ', ($token, shift(@tokens))); } } elsif ($token eq 'vrf') { $line .= " " . join(' ', ($token, shift(@tokens))); } elsif ($token =~ /^(informs?|traps?|(no)?auth)$/) { $line .= " " . $token; } else { $line = "!$line " . join(' ', ("", join(' ',@tokens))); last; } } ProcessHistory("SNMPSERVERHOST","ipsort","$ip","$line\n"); } else { ProcessHistory("SNMPSERVERHOST","ipsort","$1","$_"); } next; } if (/^(snmp-server community) (\S+)/) { if ($filter_commstr) { ProcessHistory("SNMPSERVERCOMM","keysort","$_", "!$1 $'") && next; } else { ProcessHistory("SNMPSERVERCOMM","keysort","$_","$_") && next; } } # prune tacacs/radius server keys # radius-server host <1-5> IP SECRET [ [TIMEOUT [RETRY]]] if (/^((tacacs|radius)-server)\s(\d+\.\d+\.\d+\.\d+)\s(\w*)/ && $filter_pwds >= 1) { ProcessHistory("","","","!$1 $2 $'"); next; } # order ntp peers/servers if (/^ntp (server|peer) (\d+)\.(\d+)\.(\d+)\.(\d+)/) { $sortkey = sprintf("$1 %03d%03d%03d%03d",$2,$3,$4,$5); ProcessHistory("NTP","keysort",$sortkey,"$_"); next; } # catch anything that wasnt matched above. ProcessHistory("","","","$_"); } # The MRV MCC lacks a definitive "end of config" marker. If we have seen # at least 5 lines of show config output, we can be reasonably sure that # we got the config. if ($linecnt > 5) { $found_end = 1; return(0); } return(0); } # dummy function sub DoNothing {print STDOUT;} # Main @commandtable = ( {'show version' => 'ShowVersion'}, {'show chassis' => 'ShowChassis'}, {'show slots' => 'ShowSlots'}, {'show running-config' => 'WriteTerm'} ); # 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("|", map quotemeta($_), @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 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 clogin -t $timeo -c\"$cisco_cmds\" $host\n" if ($debug); print STDOUT "executing clogin -t $timeo -c\"$cisco_cmds\" $host\n" if ($log); if (defined($ENV{NOPIPE}) && $ENV{NOPIPE} =~ /^YES/i) { system "mrvlogin -t $timeo -c \"$cisco_cmds\" $host $host.raw 2>&1" || die "clogin failed for $host: $!\n"; open(INPUT, "< $host.raw") || die "clogin failed for $host: $!\n"; } else { open(INPUT,"mrvlogin -t $timeo -c \"$cisco_cmds\" $host ) { tr/\015//d; if (/^Error:/) { print STDOUT ("$host clogin error: $_"); print STDERR ("$host clogin error: $_") if ($debug); $clean_run = 0; last; } while (/#\s*($cmds_regexp)\s*$/) { $cmd = $1; 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; } $rval = &{$commands{$cmd}}; delete($commands{$cmd}); if ($rval == -1) { $clean_run = 0; last TOP; } } if (/[>#]\s?exit$/) { $clean_run = 1; last; } } print STDOUT "Done $logincmd: $_\n" if ($log); # Flush History ProcessHistory("","","",""); # Cleanup close(INPUT); close(OUTPUT); if (defined($ENV{NOPIPE}) && $ENV{NOPIPE} =~ /^YES/i) { 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); } rancid-2.3.8/bin/mtlogin.in100644 015615 000000 00000036275 11712066325 0011247#! @EXPECT_PATH@ -- ## ## $Id$ ## ## @PACKAGE@ @VERSION@ ## Copyright (c) @COPYYEARS@ by Terrapin Communications, Inc. ## All rights reserved. ## ## This code is derived from software contributed to and maintained by ## Terrapin Communications, Inc. by Henry Kilmer, John Heasley, Andrew Partan, ## Pete Whiting, Austin Schutz, and Andrew Fort. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions ## are met: ## 1. Redistributions of source code must retain the above copyright ## notice, this list of conditions and the following disclaimer. ## 2. Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## 3. All advertising materials mentioning features or use of this software ## must display the following acknowledgement: ## This product includes software developed by Terrapin Communications, ## Inc. and its contributors for RANCID. ## 4. Neither the name of Terrapin Communications, Inc. nor the names of its ## contributors may be used to endorse or promote products derived from ## this software without specific prior written permission. ## 5. It is requested that non-binding fixes and modifications be contributed ## back to Terrapin Communications, Inc. ## ## THIS SOFTWARE IS PROVIDED BY Terrapin Communications, INC. AND CONTRIBUTORS ## ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ## TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COMPANY OR CONTRIBUTORS ## BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ## CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ## SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ## INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ## CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ## ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ## POSSIBILITY OF SUCH DAMAGE. # # The login expect scripts were based on Erik Sherk's gwtn, by permission. # # mtlogin - MikroTik router login # # bootc@bootc.net wrote this (Chris Boot) # # Usage line set usage "Usage: $argv0 \[-dV\] \[-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 avenable 1 # The default is that you login non-enabled (tacacs can have you login already # enabled) set avautoenable 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 # Sometimes routers take awhile to answer (the default is 10 sec) set timeout 45 # 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) } elseif {[ info exists env(LOGNAME) ]} { set default_user $env(LOGNAME) } 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 "\nError: could not exec id: $reason\n" exit 1 } regexp {\(([^)]*)} "$reason" junk default_user } if {[ info exists env(CLOGINRC) ]} { set password_file $env(CLOGINRC) } # Process the command line for {set i 0} {$i < $argc} {incr i} { set arg [lindex $argv $i] switch -glob -- $arg { # Expect debug mode -d* { exp_internal 1 # Username } -u* - -U* { if {! [ regexp .\[uU\](.+) $arg ignore user]} { incr i set username [ lindex $argv $i ] } # VTY Password } -v* { if {! [ regexp .\[vV\](.+) $arg ignore passwd]} { incr i set passwd [ lindex $argv $i ] } set do_passwd 0 # Version string } -V* { send_user "rancid 2.3.2a9\n" exit 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 "\nError: 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 "\nError: 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 "\nError: Unknown argument! $arg\n" send_user $usage exit 1 } default { break } } } # Process routers...no routers listed is an error. if { $i == $argc } { send_user "\nError: $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 "\nError: password file ($password_file) does not exist\n" exit 1 } file stat $password_file fileinfo if { [expr ($fileinfo(mode) & 007)] != 0000 } { send_user "\nError: $password_file must not be world readable/writable\n" exit 1 } if [ catch {source $password_file} reason ] { send_user "\nError: $reason\n" exit 1 } } # Log into the router. # returns: 0 on success, 1 on failure proc login { router user userpswd passwd prompt cmethod cyphertype } { global spawn_id in_proc do_command do_script global u_prompt p_prompt sshcmd 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] { incr progs -1 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" return 1 } } elseif ![string compare $prog "ssh"] { if [ catch {spawn $sshcmd -c $cyphertype -x -l $user+ct $router} reason ] { send_user "\nError: $sshcmd failed: $reason\n" return 1 } } elseif ![string compare $prog "rsh"] { send_error "\nError: unsupported method: rsh\n" if { $progs == 0 } { return 1 } continue; } else { send_user "\nError: unknown connection method: $prog\n" return 1 } sleep 0.3 # This helps cleanup each expect clause. expect_after { timeout { send_user "\nError: TIMEOUT reached\n" catch {close}; catch {wait}; if { $in_proc} { return 1 } else { continue } } eof { send_user "\nError: EOF received\n" catch {close}; catch {wait}; if { $in_proc} { return 1 } else { continue } } } expect { "Connection refused" { catch {close}; catch {wait}; sleep 0.3 expect eof send_user "\nError: Connection Refused\n"; wait; return 1 } eof { send_user "\nError: Couldn't login\n"; wait; return 1 } "Unknown host\r\n" { expect eof send_user "\nError: Unknown host\n"; wait; return 1 } "Host is unreachable" { expect eof send_user "\nError: Host Unreachable!\n"; wait; return 1 } "No address associated with name" { expect eof send_user "\nError: Unknown host\n"; wait; return 1 } -re "(Host key not found |The authenticity of host .* be established).* \\(yes/no\\)\\?" { send "yes\r" send_user "\nHost $router added to the list of known hosts.\n" exp_continue } -re "HOST IDENTIFICATION HAS CHANGED.* \\(yes/no\\)\\?" { send "no\r" send_user "\nError: The host key for $router has changed. Update the SSH known_hosts file accordingly.\n" return 1 } -re "HOST IDENTIFICATION HAS CHANGED\[^\n\r]+" { send_user "\nError: The host key for $router has changed. Update the SSH known_hosts file accordingly.\n" return 1 } -re "Offending key for .* \\(yes/no\\)\\?" { send "no\r" send_user "\nError: host key mismatch for $router. Update the SSH known_hosts file accordingly.\n" return 1 } -re "$u_prompt" { send -- "$user+ct\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 "\nError: Check your password for $router\n"; catch {close}; catch {wait}; return 1 } -re "$prompt" { break; } denied { send_user "\nError: Check your passwd for $router\n" catch {close}; catch {wait}; 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 regsub -all "\[)(]" $prompt {\\&} reprompt 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 } } } send "quit\r" expect { -re "^WARNING: There are unsaved configuration changes." { send "y\r" exp_continue } "\n" { exp_continue } "\[^\n\r *]*Session terminated" { return 0 } timeout { catch {close}; catch {wait}; 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 set exitval 0 foreach router [lrange $argv $i end] { set router [string tolower $router] send_user "$router\n" # Figure out prompt. set prompt "] > " # 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 "\nError - no password for $router in $password_file.\n" continue } set passwd [join [lindex $pswd 0] ""] } # Figure out username if {[info exists username]} { # command line username set ruser $username } else { set ruser [join [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 [join [find userpassword $router] ""] if { "$userpswd" == "" } { set userpswd $passwd } } # Figure out prompts set u_prompt [find userprompt $router] if { "$u_prompt" == "" } { set u_prompt "Login:" } else { set u_prompt [join [lindex $u_prompt 0] ""] } set p_prompt [find passprompt $router] if { "$p_prompt" == "" } { set p_prompt "\[Pp]assword:" } else { set p_prompt [join [lindex $p_prompt 0] ""] } # 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}} } # Figure out the SSH executable name set sshcmd [join [lindex [find sshcmd $router] 0] ""] if { "$sshcmd" == "" } { set sshcmd {ssh} } # Login to the router if {[login $router $ruser $userpswd $passwd $prompt $cmethod $cyphertype]} { incr exitval continue } if { $do_command } { if {[run_commands $prompt $command]} { incr exitval continue } } elseif { $do_script } { source $sfile catch {close}; } else { label $router log_user 1 interact } # End of for each router catch {wait}; sleep 0.3 } exit $exitval rancid-2.3.8/bin/mtrancid.in100644 015615 000000 00000021451 11556042163 0011365#! @PERLV_PATH@ ## ## $Id$ ## ## @PACKAGE@ @VERSION@ ## Copyright (C) 1997-2011 by Terrapin Communications, Inc. ## All rights reserved. ## ## This software may be freely copied, modified and redistributed ## without fee for non-commerical purposes provided that this license ## remains intact and unmodified with any RANCID distribution. ## ## 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. ## ## Except where noted otherwise, rancid was written by and is maintained by ## Henry Kilmer, John Heasley, Andrew Partan, Pete Whiting, and Austin Schutz. ## # # RANCID - Really Awesome New Cisco confIg Differ # # usage: rancid [-dV] [-l] [-f filename | $host] # # Modified by Chris Boot for MikroTik. use Getopt::Std; 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 $clogin_pgm= $ENV{'RANCID_CLOGIN'} || "mtlogin"; 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)) && scalar(%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 routine 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 routine 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 routine 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 routine (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 "show version" sub SystemPackagePrintDetail { print STDERR " In SystemPackagePrintDetail: $_" if ($debug); my $buffer = ""; my %packages = (); while () { tr/\015//d; last if (/$prompt/); next if(/^Flags:/); return(1) if /(bad command name )/; s/^\s+//g; s/^\d+\s+//g; s/\s+$//g; if (/^$/) { if ($buffer =~ /name="(.+)"/) { $packages{$1} = $buffer; } $buffer = ""; } else { $buffer .= "$_ "; } } if ($buffer =~ /name="(.+)"/) { $packages{$1} = $buffer; } for my $name (sort keys %packages) { ProcessHistory("COMMENTS","keysort","A1","# " . $packages{$name} . "\n"); } return(0); } sub SystemRouterboardPrint { print STDERR " In SystemRouterboardPrint: $_" if ($debug); while () { tr/\015//d; last if (/$prompt/); next if(/^(\s*|\s*$cmd\s*)$/); return(1) if /(bad command name )/; s/^\s+//g; ProcessHistory("COMMENTS","keysort","C1","# $_"); } return(0); } sub SystemLicensePrint { print STDERR " In SystemLicensePrint: $_" if ($debug); while () { tr/\015//d; last if (/$prompt/); next if(/^(\s*|\s*$cmd\s*)$/); return(1) if /(bad command name )/; s/^\s+//g; ProcessHistory("COMMENTS","keysort","E1","# $_"); } return(0); } sub Export { print STDERR " In Export: $_" if ($debug); my $buffer = ""; while () { tr/\015//d; if (/$prompt/) { $found_end=1; $clean_run=1; return 0}; next if(/^(\s*|\s*$cmd\s*)$/); next if(/^#/); return(1) if /(bad command name )/; s/^\s+//g; # RouterOS splits long lines with backslashes - this joins them # back up if (/\\\n$/) { s/\s*\\\n$//; $buffer .= $_; if (!/=$/ && !/="[^"]+$/ ) { $buffer .= " "; } } else { $buffer .= $_; # Fix quoted strings $buffer =~ s/(\S+)="(\S+)"/$1=$2/g; ProcessHistory("","","","$buffer"); $buffer = ""; } } } # Main @commandtable=( {'system package print detail without-paging' => "SystemPackagePrintDetail"}, {'system routerboard print' => "SystemRouterboardPrint"}, {'system license print' => "SystemLicensePrint"}, {'export' => "Export"}, ); # Use array to preserve order of commands, and hash for mapping to subroutine my (%commands, @commands); foreach (@commandtable) { push @commands, (keys(%{$_}))[0]; $commands{$commands[$#commands]}= (values(%{$_}))[0]; }; $cisco_cmds=join(";",@commands); $cmds_regexp=join("|",@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 $clogin_pgm -t $timeo -c\"$cisco_cmds\" $host\n" if ($debug); print STDOUT "executing $clogin_pgm -t $timeo -c\"$cisco_cmds\" $host\n" if ($log); if (defined($ENV{NOPIPE})) { system "$clogin_pgm -t $timeo -c \"$cisco_cmds\" $host $host.raw 2>&1" || die "$clogin_pgm failed for $host: $!\n"; open(INPUT, "< $host.raw") || die "$clogin_pgm failed for $host: $!\n"; } else { open(INPUT,"$clogin_pgm -t $timeo -c \"$cisco_cmds\" $host ) { tr/\015//d; if (/[>#]\s*quit$/) { $clean_run=1; last; } if (/^Error:/) { print STDOUT ("$host $clogin_pgm error: $_"); print STDERR ("$host $clogin_pgm error: $_") if ($debug); $clean_run=0; last; } while (/\s*($cmds_regexp)\s*$/) { $cmd = $1; if (!defined($prompt)) { $prompt = "\] > "; # crude but effective 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; } $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); } rancid-2.3.8/bin/nlogin.in100644 015615 000000 00000041174 11712067106 0011054#! @EXPECT_PATH@ -- ## ## $Id: nlogin.in 2376 2012-01-31 22:42:14Z heas $ ## ## @PACKAGE@ @VERSION@ ## Copyright (c) @COPYYEARS@ by Terrapin Communications, Inc. ## All rights reserved. ## ## This code is derived from software contributed to and maintained by ## Terrapin Communications, Inc. by Henry Kilmer, John Heasley, Andrew Partan, ## Pete Whiting, Austin Schutz, and Andrew Fort. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions ## are met: ## 1. Redistributions of source code must retain the above copyright ## notice, this list of conditions and the following disclaimer. ## 2. Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## 3. All advertising materials mentioning features or use of this software ## must display the following acknowledgement: ## This product includes software developed by Terrapin Communications, ## Inc. and its contributors for RANCID. ## 4. Neither the name of Terrapin Communications, Inc. nor the names of its ## contributors may be used to endorse or promote products derived from ## this software without specific prior written permission. ## 5. It is requested that non-binding fixes and modifications be contributed ## back to Terrapin Communications, Inc. ## ## THIS SOFTWARE IS PROVIDED BY Terrapin Communications, INC. AND CONTRIBUTORS ## ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ## TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COMPANY OR CONTRIBUTORS ## BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ## CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ## SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ## INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ## CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ## ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ## POSSIBILITY OF SUCH DAMAGE. # # The expect login scripts were based on Erik Sherk's gwtn, by permission. # # Netscreen hacks implemented by Stephen Gill . # # nlogin - netscreen login # # Most options are intuitive for logging into a netscreen firewall. # # Misc notes # netscreen does not have the concept of "enable", once logged in, a # users permissions can not change. # Usage line set usage "Usage: $argv0 \[-dSV\] \[-c command\] \[-Evar=x\] \ \[-f cloginrc-file\] \[-p user-password\] \ \[-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 firewall set do_command 0 set do_script 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 set do_enapasswd 1 # Save config, if prompted set do_saveconfig 0 # Sometimes firewall take awhile to answer (the default is 10 sec) set timeoutdflt 45 # 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) } elseif {[info exists env(LOGNAME)]} { set default_user $env(LOGNAME) } 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 "\nError: could not exec id: $reason\n" exit 1 } regexp {\(([^)]*)} "$reason" junk default_user } if {[info exists env(CLOGINRC)]} { set password_file $env(CLOGINRC) } # Process the command line for {set i 0} {$i < $argc} {incr i} { set arg [lindex $argv $i] switch -glob -- $arg { # Expect debug mode -d* { exp_internal 1 # Username } -u* { if {! [regexp .\[uU\](.+) $arg ignore user] } { incr i set username [lindex $argv $i] } # VTY Password } -p* { if {! [regexp .\[pP\](.+) $arg ignore userpasswd]} { incr i set userpasswd [lindex $argv $i] } set do_passwd 0 # ssh passphrase } -r* { # ignore -r # Environment variable to pass to -s scripts } -E* { if {[regexp .\[E\](.+)=(.+) $arg ignore varname varvalue]} { set E$varname $varvalue } else { send_user "\nError: invalid format for -E in $arg\n" exit 1 } # Command to run. } -c* { if {! [regexp .\[cC\](.+) $arg ignore command]} { incr i set command [lindex $argv $i] } set do_command 1 # Expect script to run. } -s* { if {! [regexp .\[sS\](.+) $arg ignore sfile]} { incr i set sfile [lindex $argv $i] } if { ! [file readable $sfile] } { send_user "\nError: Can't read $sfile\n" exit 1 } set do_script 1 # save config on exit } -S* { set do_saveconfig 1 # cypher type } -y* { if {! [regexp .\[eE\](.+) $arg ignore cypher]} { incr i set cypher [lindex $argv $i] } # alternate cloginrc file } -f* { if {! [regexp .\[fF\](.+) $arg ignore password_file]} { incr i set password_file [lindex $argv $i] } # Timeout } -t* { incr i set timeoutdflt [lindex $argv $i] # Command file } -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 # Version string } -V* { send_user "@PACKAGE@ @VERSION@\n" exit 0 # Does tacacs automatically enable us? } -autoenable { # ignore autoenable } -* { send_user "\nError: Unknown argument! $arg\n" send_user $usage exit 1 } default { break } } } # Process firewalls...no firewalls listed is an error. if { $i == $argc } { send_user "\nError: $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 "\nError: password file ($password_file) does not exist\n" exit 1 } file stat $password_file fileinfo if { [expr ($fileinfo(mode) & 007)] != 0000 } { send_user "\nError: $password_file must not be world readable/writable\n" exit 1 } if [catch {source $password_file} reason] { send_user "\nError: $reason\n" exit 1 } } # Log into the firewall. # returns: 0 on success, 1 on failure proc login { router user userpswd passwd enapasswd cmethod cyphertype identfile } { global command spawn_id in_proc do_command do_script passphrase global prompt prompt_match u_prompt p_prompt sshcmd 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] { incr progs -1 if [string match "telnet*" $prog] { regexp {telnet(:([^[:space:]]+))*} $prog methcmd 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" return 1 } } elseif [string match "ssh*" $prog] { # ssh to the router & try to login with or without an identfile. regexp {ssh(:([^[:space:]]+))*} $prog methcmd suffix port set cmd $sshcmd if {"$port" != ""} { set cmd "$cmd -p $port" } if {"$identfile" != ""} { set cmd "$cmd -i $identfile" } set retval [catch {eval spawn [split "$cmd -c $cyphertype -x -l $user $router" { }]} reason] if { $retval } { send_user "\nError: $cmd failed: $reason\n" return 1 } } elseif ![string compare $prog "rsh"] { send_error "\nError: unsupported method: rsh\n" if { $progs == 0 } { return 1 } continue; } else { send_user "\nError: unknown connection method: $prog\n" return 1 } sleep 0.3 # This helps cleanup each expect clause. expect_after { timeout { send_user "\nError: TIMEOUT reached\n" catch {close}; catch {wait}; if { $in_proc} { return 1 } else { continue } } eof { send_user "\nError: EOF received\n" catch {close}; catch {wait}; if { $in_proc} { return 1 } else { continue } } } # Here we get a little tricky. There are several possibilities: # the firewall can ask for a username and passwd and then # talk to the TACACS server to authenticate you, or if the # TACACS server is not working, then it will use the enable # passwd. Or, the firewall might not have TACACS turned on, # then it will just send the passwd. # if telnet fails with connection refused, try ssh expect { -re "(Connection refused|Secure connection \[^\n\r]+ refused)" { catch {close}; catch {wait}; if !$progs { send_user "\nError: Connection Refused ($prog): $router\n" return 1 } } -re "(Connection closed by|Connection to \[^\n\r]+ closed)" { catch {close}; catch {wait}; if !$progs { send_user "\nError: Connection closed ($prog): $router\n" return 1 } } eof { send_user "\nError: Couldn't login: $router\n"; wait; return 1 } -nocase "unknown host\r" { send_user "\nError: Unknown host $router\n"; catch {close}; catch {wait}; return 1 } "Host is unreachable" { send_user "\nError: Host Unreachable: $router\n"; catch {close}; catch {wait}; return 1 } "No address associated with name" { send_user "\nError: Unknown host $router\n"; catch {close}; catch {wait}; return 1 } -re "(Host key not found |The authenticity of host .* be established).* \\(yes/no\\)\\?" { send "yes\r" send_user "\nHost $router added to the list of known hosts.\n" exp_continue } -re "HOST IDENTIFICATION HAS CHANGED.* \\(yes/no\\)\\?" { send "no\r" send_user "\nError: The host key for $router has changed. Update the SSH known_hosts file accordingly.\n" catch {close}; catch {wait}; return 1 } -re "HOST IDENTIFICATION HAS CHANGED\[^\n\r]+" { send_user "\nError: The host key for $router has changed. Update the SSH known_hosts file accordingly.\n" return 1 } -re "Offending key for .* \\(yes/no\\)\\?" { send "no\r" send_user "\nError: host key mismatch for $router. Update the SSH known_hosts file accordingly.\n" catch {close}; catch {wait}; return 1 } -re "(denied|Sorry)" { send_user "\nError: Check your passwd for $router\n" catch {close}; catch {wait}; return 1 } "Login failed" { send_user "\nError: Check your passwd for $router\n" catch {close}; catch {wait}; return 1 } -re "(login:)" { sleep 1; send -- "$user\r" set uprompt_seen 1 exp_continue } -re "@\[^\r\n]+\[Pp]assword:" { # ssh pwd prompt sleep 1 send -- "$userpswd\r" exp_continue } "\[Pp]assword:" { sleep 1; if {$uprompt_seen == 1} { send -- "$userpswd\r" } else { send -- "$passwd\r" } exp_continue } -- "$prompt" { break; } } } 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 "set console page 0\r" expect -re $prompt {} 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]+" { exp_continue } -re "$prompt" {} -gl "--- more ---" { send " " exp_continue } } } send "exit\r" expect { -re "$prompt" { send "exit\r" exp_continue } -re "\[\n\r]+" { exp_continue } -gl "Configuration modified, save?" { send "n\r" exp_continue } timeout { catch {close}; catch {wait}; return 0 } eof { return 0 } } set in_proc 0 } # # For each firewall... (this is main loop) # source_password_file $password_file set in_proc 0 set exitval 0 foreach router [lrange $argv $i end] { set router [string tolower $router] send_user -- "$router\n" # device timeout set timeout [find timeout $router] if { [llength $timeout] == 0 } { set timeout $timeoutdflt } set prompt {-> } # Figure out passwords if { $do_passwd || $do_enapasswd } { set pswd [find password $router] if { [llength $pswd] == 0 } { send_user -- "\nError: no password for $router in $password_file.\n" continue } set passwd [join [lindex $pswd 0] ""] set enapasswd [join [lindex $pswd 1] ""] } else { set passwd $userpasswd set enapasswd $enapasswd } # Figure out username if {[info exists username]} { # command line username set ruser $username } else { set ruser [join [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 [join [find userpassword $router] ""] if { "$userpswd" == "" } { set userpswd $passwd } } # Figure out identity file to use set identfile [join [lindex [find identity $router] 0] ""] # 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}} } # Figure out the SSH executable name set sshcmd [join [lindex [find sshcmd $router] 0] ""] if { "$sshcmd" == "" } { set sshcmd {ssh} } # Login to the router if {[login $router $ruser $userpswd $passwd $enapasswd $cmethod $cyphertype $identfile]} { incr exitval # if login failed, move on to the next device continue } # we are logged in, now figure out the full prompt send "\r" expect { -re "\[\r\n]+" { exp_continue; } -re "^(.+$prompt)" { set junk $expect_out(0,string); # if it has HA (high avail), the prompt will # be "something-(.)->" regsub -all "\[\]\)\(\[]" $junk {\\&} prompt; } } if { $do_command } { if {[run_commands $prompt $command]} { incr exitval continue } } elseif { $do_script } { send "set console page 0\r" expect -re $prompt {} source $sfile catch {close}; } else { label $router log_user 1 interact } # End of for each firewall catch {wait}; sleep 0.3 } exit $exitval rancid-2.3.8/bin/nrancid.in100644 015615 000000 00000026652 11710456730 0011213#! @PERLV_PATH@ ## ## $Id: nrancid.in 2362 2012-01-26 16:20:02Z heas $ ## ## @PACKAGE@ @VERSION@ ## Copyright (c) 1997-2008 by Terrapin Communications, Inc. ## All rights reserved. ## ## This code is derived from software contributed to and maintained by ## Terrapin Communications, Inc. by Henry Kilmer, John Heasley, Andrew Partan, ## Pete Whiting, Austin Schutz, and Andrew Fort. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions ## are met: ## 1. Redistributions of source code must retain the above copyright ## notice, this list of conditions and the following disclaimer. ## 2. Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## 3. All advertising materials mentioning features or use of this software ## must display the following acknowledgement: ## This product includes software developed by Terrapin Communications, ## Inc. and its contributors for RANCID. ## 4. Neither the name of Terrapin Communications, Inc. nor the names of its ## contributors may be used to endorse or promote products derived from ## this software without specific prior written permission. ## 5. It is requested that non-binding fixes and modifications be contributed ## back to Terrapin Communications, Inc. ## ## THIS SOFTWARE IS PROVIDED BY Terrapin Communications, INC. AND CONTRIBUTORS ## ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ## TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COMPANY OR CONTRIBUTORS ## BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ## CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ## SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ## INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ## CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ## ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ## POSSIBILITY OF SUCH DAMAGE. # # Amazingly hacked version of Hank's rancid - this one tries to # deal with Netscreen firewalls # # Original Netscreen hacks implemented by Stephen Gill [gillsr@yahoo.com] # # RANCID - Really Awesome New Cisco confIg Differ # # usage: rancid [-dV] [-l] [-f filename | hostname] # use Getopt::Std; getopts('dflV'); if ($opt_V) { print "@PACKAGE@ @VERSION@\n"; exit(0); } $log = $opt_l; $debug = $opt_d; $file = $opt_f; $host = $ARGV[0]; $found_end = 0; $timeo = 90; # nlogin timeout in seconds my(@commandtable, %commands, @commands);# command lists my($aclsort) = ("ipsort"); # ACL sorting mode my($filter_commstr); # SNMP community string filtering 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)) && scalar(%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 routine 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 routine 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 routine 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 routine (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 "get system" sub GetSystem { print STDERR " In GetSystem: $_" if ($debug); while () { tr/\015//d; next if /^\s*$/; last if(/$prompt/); # throw away the pager prompts s/^--- more ---[\s\b]*//g; /^Serial Number: (\S+), Control Number: [0-9a-f]+$/ && ProcessHistory("SYSTEM","","", "#SN: $1\n") && next; /^Product Name: (\S+)$/ && ProcessHistory("SYSTEM","","", "#Product: $1\n") && next; /^Hardware Version: (\S+), / && ProcessHistory("SYSTEM","","", "#HW: $1\n") && next; /^Software Version: (\S+), Type: (\S+)$/ && ProcessHistory("SYSTEM","","", "#Netscreen Type: $2\n#Software Version: $1\n") && next; /^Image: (\S+), / && ProcessHistory("SYSTEM","","", "#Image: $1\n") && next; /^Feature: (\S+)$/ && ProcessHistory("SYSTEM","","", "#Feature: $1\n") && next; /^File Name: (\S+), Checksum: (\S+)$/ && ProcessHistory("SYSTEM","","", "#File Name: $1, Checksum: $2\n") && next; /^, Total Memory: (\S+)$/ && ProcessHistory("SYSTEM","","", "#Memory: $1\n") && next; } ProcessHistory("SYSTEM","","","#\n"); return(0); } sub GetFile { print STDERR " In GetFile: $_" if ($debug); while () { last if(/$prompt/); } ProcessHistory("FILE","","","#\n"); return(0); } sub GetConf { print STDERR " In GetConf: $_" if ($debug); while () { tr/\015//d; next if /^\s*$/; next if /^Total Config.+$/i; last if(/$prompt/); # throw away the pager prompts s/^--- more ---[\s\b]*//g; if (/^set admin name "(\S+)"$/ && $filter_pwds >= 1) { ProcessHistory("ADMIN","","","#set admin name \n"); next; } if (/^set admin password (\S+)$/ && $filter_pwds >= 1) { ProcessHistory("ADMIN","","","#set admin password \n"); next; } if (/^set admin user (\S+) password (\S+) privilege (\S+)$/ && $filter_pwds >= 1) { ProcessHistory("ADMIN","","", "#set admin user $1 password privilege $3\n"); next; } if (/^set auth-server (\S+) radius secret / && $filter_pwds >= 1 ) { ProcessHistory("ADMIN","","", "#set auth-server $1 radius secret \n"); next; } if (/^set ike gateway (.*) username (\S+)(.*) password (\S+)(.*)$/ && $filter_pwds >= 1) { ProcessHistory("ADMIN","","", "#set ike gateway $1 username $3 password $5\n"); next; } if (/^set ike gateway (.*) preshare "(\S+)"(.*)$/ && $filter_pwds >= 1) { ProcessHistory("ADMIN","","", "#set ike gateway $1 preshare $3\n"); next; } if (/^set auth-server (.*) secret "(\S+)"(.*)$/ && $filter_pwds >= 1) { ProcessHistory("ADMIN","","", "#set auth-server $1 secret $3\n"); next; } ProcessHistory("","","","$_"); } $found_end=1; return(1); } # dummy function sub DoNothing {print STDOUT;} # Main @commandtable = ( {'get system' => 'GetSystem'}, {'get conf' => 'GetConf'} ); # 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("|", map quotemeta($_), @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 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 nlogin -t $timeo -c\"$cisco_cmds\" $host\n" if ($debug); print STDOUT "executing nlogin -t $timeo -c\"$cisco_cmds\" $host\n" if ($log); if (defined($ENV{NOPIPE}) && $ENV{NOPIPE} =~ /^YES/i) { system "nlogin -t $timeo -c \"$cisco_cmds\" $host $host.raw 2>&1" || die "nlogin failed for $host: $!\n"; open(INPUT, "< $host.raw") || die "nlogin failed for $host: $!\n"; } else { open(INPUT,"nlogin -t $timeo -c \"$cisco_cmds\" $host ) { tr/\015//d; if (/^Error:/) { print STDOUT ("$host nlogin error: $_"); print STDERR ("$host nlogin error: $_") if ($debug); last; } while (/>\s*($cmds_regexp)\s*$/) { $cmd = $1; 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"; last TOP; } $rval = &{$commands{$cmd}}; delete($commands{$cmd}); if ($rval == -1) { last TOP; } } } print STDOUT "Done $logincmd: $_\n" if ($log); # Flush History ProcessHistory("","","",""); # Cleanup close(INPUT); close(OUTPUT); if (defined($ENV{NOPIPE}) && $ENV{NOPIPE} =~ /^YES/i) { unlink("$host.raw") if (! $debug); } # check for completeness if (scalar(%commands) || !$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 (!$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); } rancid-2.3.8/bin/nslogin.in100644 015615 000000 00000046074 11712067106 0011243#! @EXPECT_PATH@ -- ## ## $Id: nslogin.in 2376 2012-01-31 22:42:14Z heas $ ## ## @PACKAGE@ @VERSION@ ## Copyright (c) @COPYYEARS@ by Terrapin Communications, Inc. ## All rights reserved. ## ## This code is derived from software contributed to and maintained by ## Terrapin Communications, Inc. by Henry Kilmer, John Heasley, Andrew Partan, ## Pete Whiting, Austin Schutz, and Andrew Fort. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions ## are met: ## 1. Redistributions of source code must retain the above copyright ## notice, this list of conditions and the following disclaimer. ## 2. Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## 3. All advertising materials mentioning features or use of this software ## must display the following acknowledgement: ## This product includes software developed by Terrapin Communications, ## Inc. and its contributors for RANCID. ## 4. Neither the name of Terrapin Communications, Inc. nor the names of its ## contributors may be used to endorse or promote products derived from ## this software without specific prior written permission. ## 5. It is requested that non-binding fixes and modifications be contributed ## back to Terrapin Communications, Inc. ## ## THIS SOFTWARE IS PROVIDED BY Terrapin Communications, INC. AND CONTRIBUTORS ## ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ## TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COMPANY OR CONTRIBUTORS ## BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ## CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ## SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ## INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ## CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ## ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ## POSSIBILITY OF SUCH DAMAGE. # # The expect login scripts were based on Erik Sherk's gwtn, by permission. # # nslogin - Netscaler login # # Hacks from Anshuman Kanwar. # # Most options are intuitive for logging into a Cisco router. # The default is to enable (thus -noenable). Some folks have # setup tacacs to have a user login at priv-lvl = 15 (enabled) # so the -autoenable flag was added for this case (don't go through # the process of enabling and the prompt will be the "#" prompt. # The default username password is the same as the vty password. # # Usage line set usage "Usage: $argv0 \[-dSV\] \[-autoenable\] \[-noenable\] \[-c command\] \ \[-Evar=x\] \[-e enable-password\] \[-f cloginrc-file\] \[-p user-password\] \ \[-s script-file\] \[-t timeout\] \[-u username\] \ \[-v vty-password\] \[-w enable-username\] \[-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 avenable 0 # The default is that you login non-enabled (tacacs can have you login already # enabled) set avautoenable 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 set do_enapasswd 1 # Save config, if prompted set do_saveconfig 0 # Sometimes routers take awhile to answer (the default is 10 sec) set timeoutdflt 45 # 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) } elseif {[ info exists env(LOGNAME) ]} { set default_user $env(LOGNAME) } 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 "\nError: could not exec id: $reason\n" exit 1 } regexp {\(([^)]*)} "$reason" junk default_user } if {[ info exists env(CLOGINRC) ]} { set password_file $env(CLOGINRC) } # Process the command line for {set i 0} {$i < $argc} {incr i} { set arg [lindex $argv $i] switch -glob -- $arg { # Expect debug mode -d* { exp_internal 1 # Username } -u* { if {! [ regexp .\[uU\](.+) $arg ignore user]} { incr i set username [ lindex $argv $i ] } # VTY Password } -p* { if {! [ regexp .\[pP\](.+) $arg ignore userpasswd]} { incr i set userpasswd [ lindex $argv $i ] } set do_passwd 0 # ssh passphrase } -r* { # ignore -r # VTY Password } -v* { if {! [ regexp .\[vV\](.+) $arg ignore passwd]} { incr i set passwd [ lindex $argv $i ] } set do_passwd 0 # Enable Username } -w* { if {! [ regexp .\[wW\](.+) $arg ignore enauser]} { incr i set enausername [ lindex $argv $i ] } # Environment variable to pass to -s scripts } -E* { if {[ regexp .\[E\](.+)=(.+) $arg ignore varname varvalue]} { set E$varname $varvalue } else { send_user "\nError: invalid format for -E in $arg\n" exit 1 } # Enable Password } -e* { if {! [ regexp .\[e\](.+) $arg ignore enapasswd]} { incr i set enapasswd [ lindex $argv $i ] } set do_enapasswd 0 # Command to run. } -c* { if {! [ regexp .\[cC\](.+) $arg ignore command]} { incr i set command [ lindex $argv $i ] } set do_command 1 # Expect script to run. } -s* { if {! [ regexp .\[sS\](.+) $arg ignore sfile]} { incr i set sfile [ lindex $argv $i ] } if { ! [ file readable $sfile ] } { send_user "\nError: Can't read $sfile\n" exit 1 } set do_script 1 # save config on exit } -S* { set do_saveconfig 1 # 'ssh -c' cypher type } -y* { if {! [ regexp .\[eE\](.+) $arg ignore cypher]} { incr i set cypher [ lindex $argv $i ] } # alternate cloginrc file } -f* { if {! [ regexp .\[fF\](.+) $arg ignore password_file]} { incr i set password_file [ lindex $argv $i ] } # Timeout } -t* { if {! [ regexp .\[tT\](.+) $arg ignore timeout]} { incr i set timeoutdflt [ lindex $argv $i ] } # Command file } -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 # Version string } -V* { send_user "@PACKAGE@ @VERSION@\n" exit 0 # Do we enable? } -noenable { set avenable 0 # Does tacacs automatically enable us? } -autoenable { set avautoenable 1 set avenable 0 } -* { send_user "\nError: Unknown argument! $arg\n" send_user $usage exit 1 } default { break } } } # Process routers...no routers listed is an error. if { $i == $argc } { send_user "\nError: $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 "\nError: password file ($password_file) does not exist\n" exit 1 } file stat $password_file fileinfo if { [expr ($fileinfo(mode) & 007)] != 0000 } { send_user "\nError: $password_file must not be world readable/writable\n" exit 1 } if [ catch {source $password_file} reason ] { send_user "\nError: $reason\n" exit 1 } } # Log into the router. # returns: 0 on success, 1 on failure proc login { router user userpswd passwd enapasswd cmethod cyphertype } { global spawn_id in_proc do_command do_script global prompt u_prompt p_prompt e_prompt sshcmd 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] { incr progs -1 if ![string compare $prog "ssh"] { regexp {ssh(:([^[:space:]]+))*} $prog methcmd suffix port set cmd $sshcmd if {"$port" != ""} { set cmd "$cmd -p $port" } set retval [ catch {eval spawn [split "$cmd -c $cyphertype -x -l $user $router" { }]} reason ] if { $retval } { send_user "\nError: $cmd failed: $reason\n" return 1 } } elseif ![string compare $prog "telnet"] { send_error "\nError: unsupported method: telnet\n" if { $progs == 0 } { return 1 } continue } elseif ![string compare $prog "rsh"] { send_error "\nError: unsupported method: rsh\n" if { $progs == 0 } { return 1 } continue } else { send_user "\nError: unknown connection method: $prog\n" return 1 } sleep 0.3 # This helps cleanup each expect clause. expect_after { timeout { send_user "\nError: TIMEOUT reached\n" catch {close}; catch {wait}; if { $in_proc} { return 1 } else { continue } } eof { send_user "\nError: EOF received\n" catch {close}; catch {wait}; if { $in_proc} { return 1 } else { continue } } } # Here we get a little tricky. There are several possibilities: # the router can ask for a username and passwd and then # talk to the TACACS server to authenticate you, or if the # TACACS server is not working, then it will use the enable # passwd. Or, the router might not have TACACS turned on, # then it will just send the passwd. # if telnet fails with connection refused, try ssh expect { -re "(Connection refused|Secure connection \[^\n\r]+ refused|Connection closed by)" { catch {close}; catch {wait}; if !$progs { send_user "\nError: Connection Refused ($prog)\n"; return 1 } } eof { send_user "\nError: Couldn't login\n"; wait; return 1 } -nocase "unknown host\r" { catch {close}; catch {wait}; send_user "\nError: Unknown host\n"; wait; return 1 } "Host is unreachable" { catch {close}; catch {wait}; send_user "\nError: Host Unreachable!\n"; wait; return 1 } "No address associated with name" { catch {close}; catch {wait}; send_user "\nError: Unknown host\n"; wait; return 1 } -re "(Host key not found |The authenticity of host .* be established).* \\(yes/no\\)\\?" { send "yes\r" send_user "\nHost $router added to the list of known hosts.\n" exp_continue } -re "HOST IDENTIFICATION HAS CHANGED.* \\(yes/no\\)\\?" { send "no\r" send_user "\nError: The host key for $router has changed. Update the SSH known_hosts file accordingly.\n" return 1 } -re "HOST IDENTIFICATION HAS CHANGED\[^\n\r]+" { send_user "\nError: The host key for $router has changed. Update the SSH known_hosts file accordingly.\n" return 1 } -re "Offending key for .* \\(yes/no\\)\\?" { send "no\r" send_user "\nError: host key mismatch for $router. Update the SSH known_hosts file accordingly.\n" return 1 } -re "(denied|Sorry)" { send_user "\nError: Check your passwd for $router\n" catch {close}; catch {wait}; return 1 } "Login failed" { send_user "\nError: Check your passwd for $router\n" return 1 } -re "% (Bad passwords|Authentication failed)" { send_user "\nError: Check your passwd for $router\n" return 1 } # newer netscaler code (NS8.0: Build 47.8) the password prompt is # "Password:" not "user@hosts's password:" -re "(@\[^\r\n]+ )?$p_prompt" { # ssh pwd prompt sleep 1 send -- "$userpswd\r" exp_continue } "$prompt" { break; } "Login invalid" { send_user "\nError: Invalid login\n"; catch {close}; catch {wait}; return 1 } } } 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 regsub -all "\[)(]" $prompt {\\&} reprompt # this is the only way i see to get rid of more prompts in o/p..grrrrr log_user 0 set commands [split $command \;] set num_commands [llength $commands] # the pager can not be turned off on the PIX, so we have to look # for the "More" prompt. the extreme is equally obnoxious, with a # global switch in the config. for {set i 0} {$i < $num_commands} { incr i} { send -- "[subst -nocommands [lindex $commands $i]]\r" expect { -re "\b+" { exp_continue } -re "^\[^\n\r *]*$reprompt" { send_user -- "$expect_out(buffer)" } -re "^\[^\n\r]*$reprompt." { send_user -- "$expect_out(buffer)" exp_continue } -re "\[\n\r]+" { send_user -- "$expect_out(buffer)" exp_continue } -re "\[^\r\n]*Press to cont\[^\r\n]*" { send " " # bloody ^[[2K after " " expect { -re "^\[^\r\n]*\r" {} } exp_continue } -re "^ --More--\[^\n\r]*" { send " " exp_continue } -re "^<-+ More -+>\[^\n\r]*" { send_user -- "$expect_out(buffer)" send " " exp_continue } } } log_user 1 send "quit\r" expect { "Do you wish to save your configuration changes" { send "n\r" exp_continue } "\n" { exp_continue } timeout { catch {close}; catch {wait}; 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 set exitval 0 foreach router [lrange $argv $i end] { set router [string tolower $router] send_user "$router\n" # device timeout set timeout [find timeout $router] if { [llength $timeout] == 0 } { set timeout $timeoutdflt } # Figure out prompt. set prompt "#" # look for noenable option in .cloginrc if { [find noenable $router] == "1" } { set enable 0 } else { set enable $avenable } # Figure out passwords if { $do_passwd } { set pswd [find password $router] if { [llength $pswd] == 0 } { send_user "\nError: no password for $router in $password_file.\n" continue } if { $enable && $autoenable == 0 && [llength $pswd] < 2 } { send_user "\nError: no enable password for $router in $password_file.\n" continue } set passwd [join [lindex $pswd 0] ""] set enapasswd [join [lindex $pswd 1] ""] } else { set passwd $userpasswd set enapasswd $enapasswd } # Figure out username if {[info exists username]} { # command line username set ruser $username } else { set ruser [join [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 [join [find userpassword $router] ""] if { "$userpswd" == "" } { set userpswd $passwd } } # Figure out enable username if {[info exists enausername]} { # command line enausername set enauser $enausername } else { set enauser [join [find enauser $router] ""] if { "$enauser" == "" } { set enauser $ruser } } # Figure out prompts set u_prompt [find userprompt $router] if { "$u_prompt" == "" } { set u_prompt "(Username|Login|login|user name):" } else { set u_prompt [join [lindex $u_prompt 0] ""] } set p_prompt [find passprompt $router] if { "$p_prompt" == "" } { set p_prompt "(\[Pp]assword|passwd):" } else { set p_prompt [join [lindex $p_prompt 0] ""] } set e_prompt [find enableprompt $router] if { "$e_prompt" == "" } { set e_prompt "\[Pp]assword:" } else { set e_prompt [join [lindex $e_prompt 0] ""] } # 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}} } # Figure out the SSH executable name set sshcmd [join [lindex [find sshcmd $router] 0] ""] if { "$sshcmd" == "" } { set sshcmd {ssh} } # Login to the router if {[login $router $ruser $userpswd $passwd $enapasswd $cmethod $cyphertype]} { incr exitval continue } # we are logged in, now figure out the full prompt send "\r" expect { -re "\[\r\n]+" { exp_continue; } -re "^.+$prompt" { set junk $expect_out(0,string); regsub -all "\[\]\[]" $junk {\\&} prompt; } } if { $do_command } { if {[run_commands $prompt $command]} { incr exitval continue } } elseif { $do_script } { # If the prompt is (enable), then we are on a switch and the # command is "set length 0"; otherwise its "term length 0". if [ regexp -- ".*> .*enable" "$prompt" ] { send "set length 0\r" send "set logging session disable\r" } else { send "term length 0\r" } expect -re $prompt {} source $sfile catch {close}; } else { label $router log_user 1 interact } # End of for each router catch {wait}; sleep 0.3 } exit $exitval rancid-2.3.8/bin/nsrancid.in100644 015615 000000 00000022771 11535733223 0011374#! @PERLV_PATH@ ## ## $Id: nsrancid.in 2279 2011-01-31 22:41:00Z heas $ ## ## @PACKAGE@ @VERSION@ ## Copyright (c) 1997-2008 by Terrapin Communications, Inc. ## All rights reserved. ## ## This code is derived from software contributed to and maintained by ## Terrapin Communications, Inc. by Henry Kilmer, John Heasley, Andrew Partan, ## Pete Whiting, Austin Schutz, and Andrew Fort. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions ## are met: ## 1. Redistributions of source code must retain the above copyright ## notice, this list of conditions and the following disclaimer. ## 2. Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## 3. All advertising materials mentioning features or use of this software ## must display the following acknowledgement: ## This product includes software developed by Terrapin Communications, ## Inc. and its contributors for RANCID. ## 4. Neither the name of Terrapin Communications, Inc. nor the names of its ## contributors may be used to endorse or promote products derived from ## this software without specific prior written permission. ## 5. It is requested that non-binding fixes and modifications be contributed ## back to Terrapin Communications, Inc. ## ## THIS SOFTWARE IS PROVIDED BY Terrapin Communications, INC. AND CONTRIBUTORS ## ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ## TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COMPANY OR CONTRIBUTORS ## BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ## CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ## SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ## INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ## CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ## ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ## POSSIBILITY OF SUCH DAMAGE. # # hacked version of Hank's rancid - this one tries to deal with Netscalers. # Hacks from Anshuman Kanwar. # # RANCID - Really Awesome New Cisco confIg Differ # # usage: rancid [-dV] [-l] [-f filename | hostname] # use Getopt::Std; 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; # nslogin timeout in seconds my(@commandtable, %commands, @commands);# command lists my($aclsort) = ("ipsort"); # ACL sorting mode my($filter_commstr); # SNMP community string filtering my($filter_pwds); # password filtering mode $prompt = "netscaler#"; # 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)) && scalar(%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 routine 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 routine 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 routine 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 routine (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 "show ns ns.conf" sub ShowConfig { print STDERR " In ShowConfig: $_" if ($debug); while () { tr/\015//d; last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); next if (/^Reading configuration information/); next if (/^Can\'t find object or class named \"\-all\"\s*$/); next if (/lock-address .*$/); next if (/^\# *uptime +\d+\s*$/); if (/community label /) { if ($filter_commstr) { $_ =~ s/community label .*$/community label /; } } return(1) if /(invalid command name)/; ProcessHistory("","","","$_"); } if (/exit$/) { $found_end = 1; $clean_run = 1; return(1); } return(0); } # This routine parses single command's that return no required info sub RunCommand { print STDERR " In RunCommand: $_" if ($debug); while () { tr/\015//d; last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); } return(0) } # dummy function sub DoNothing {print STDOUT;} # Main @commandtable = ( {'show ns ns.conf' => 'ShowConfig'}, ); # 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("|", map quotemeta($_), @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 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 nslogin -t $timeo -c\"$cisco_cmds\" $host\n" if ($debug); print STDOUT "executing nslogin -t $timeo -c\"$cisco_cmds\" $host\n" if ($log); if (defined($ENV{NOPIPE}) && $ENV{NOPIPE} =~ /^YES/i) { system "nslogin -t $timeo -c \"$cisco_cmds\" $host $host.raw 2>&1" || die "nslogin failed for $host: $!\n"; open(INPUT, "< $host.raw") || die "nslogin failed for $host: $!\n"; } else { open(INPUT,"nslogin -t $timeo -c \"$cisco_cmds\" $host ) { tr/\015//d; if (/^Error:/) { print STDOUT ("$host nslogin error: $_"); print STDERR ("$host nslogin error: $_") if ($debug); $clean_run = 0; last; } while (/$prompt\s*($cmds_regexp)\s*$/) { $cmd = $1; 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}) && $ENV{NOPIPE} =~ /^YES/i) { 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); } rancid-2.3.8/bin/nxrancid.in100644 015615 000000 00000111520 11614615310 0011362#! @PERLV_PATH@ ## ## $Id: nxrancid.in 2321 2011-07-29 20:40:40Z heas $ ## ## @PACKAGE@ @VERSION@ ## Copyright (c) 1997-2008 by Terrapin Communications, Inc. ## All rights reserved. ## ## This code is derived from software contributed to and maintained by ## Terrapin Communications, Inc. by Henry Kilmer, John Heasley, Andrew Partan, ## Pete Whiting, Austin Schutz, and Andrew Fort. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions ## are met: ## 1. Redistributions of source code must retain the above copyright ## notice, this list of conditions and the following disclaimer. ## 2. Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## 3. All advertising materials mentioning features or use of this software ## must display the following acknowledgement: ## This product includes software developed by Terrapin Communications, ## Inc. and its contributors for RANCID. ## 4. Neither the name of Terrapin Communications, Inc. nor the names of its ## contributors may be used to endorse or promote products derived from ## this software without specific prior written permission. ## 5. It is requested that non-binding fixes and modifications be contributed ## back to Terrapin Communications, Inc. ## ## THIS SOFTWARE IS PROVIDED BY Terrapin Communications, INC. AND CONTRIBUTORS ## ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ## TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COMPANY OR CONTRIBUTORS ## BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ## CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ## SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ## INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ## CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ## ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ## POSSIBILITY OF SUCH DAMAGE. # # RANCID - Really Awesome New Cisco confIg Differ # # usage: rancid [-dV] [-l] [-f filename | hostname] # use Getopt::Std; 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 my(@commandtable, %commands, @commands);# command lists my($aclsort) = ("ipsort"); # ACL sorting mode my($filter_commstr); # SNMP community string filtering 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)) && scalar(%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 routine 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 routine 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 routine 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 routine (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 "show version" sub ShowVersion { print STDERR " In ShowVersion: $_" if ($debug); while () { tr/\015//d; last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); return(1) if /Line has invalid autocommand /; return(1) if /(Invalid input detected|Type help or )/; return(-1) if (/\% Invalid command at /); return(-1) if (/\% Permission denied/); return(-1) if (/command authorization failed/i); if (/^Cisco Nexus Operating System/) { $type = "NXOS";} if (/^Software$/) { while () { tr/\015//d; last if (/^$prompt/); next if (/^\s*$cmd\s*$/); if (/^$/) { goto EndSoftware; } /\s*([^:]*:)\s*(.*)$/ && ProcessHistory("COMMENTS","keysort","C1", "!Software: $1 $2\n") && next; } } EndSoftware: if (/^Hardware$/) { while () { tr/\015//d; last if (/^$prompt/); next if (/^\s*$cmd\s*$/); if (/^$/) { goto EndHardware; } if (/^\s*(.*) CPU\s*with (\d*) kB(.*)$/) { my($tmp) = int($2 / 1024); ProcessHistory("COMMENTS","keysort","A2", "!Hardware: $1 CPU with $tmp MB$3\n"); next; } if (/^\s*(.*)\s*with (\d*) kB(.*)$/) { my($tmp) = int($2 / 1024); ProcessHistory("COMMENTS","keysort","A2", "!Hardware: $1with $tmp MB$3\n"); next; } /^\s*(.*)$/ && ProcessHistory("COMMENTS","keysort","A2", "!Hardware: $1\n") && next; } } EndHardware: if (/^\s+(bootflash|slot0):\s+(\d+) kB(.*)$/) { my($tmp) = int($2 / 1024); ProcessHistory("COMMENTS","keysort","B1", "!Memory: $1: $tmp MB$3\n"); next; } } print STDERR "TYPE = $type\n" if ($debug); ProcessHistory("COMMENTS","keysort","A1", "!Chassis type: $proc - a $type router\n"); ProcessHistory("COMMENTS","keysort","B0", "!\n"); ProcessHistory("COMMENTS","keysort","C0", "!\n"); ProcessHistory("COMMENTS","","", "!\n"); return(0); } # This routine parses "show version build-info" sub ShowVersionBuild { print STDERR " In ShowVersionBuild: $_" if ($debug); while () { tr/\015//d; last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); return(1) if /Line has invalid autocommand /; return(1) if /(Invalid input detected|Type help or )/; return(1) if (/\% Invalid command at /); return(-1) if (/\% Permission denied/); return(-1) if (/command authorization failed/i); /^Built By / && ProcessHistory("COMMENTS","","", "!Build: $_"); /^On Date / && ProcessHistory("COMMENTS","","", "!Build: $_"); /^From Tree / && ProcessHistory("COMMENTS","","", "!Build: $_"); /^Base Tag / && ProcessHistory("COMMENTS","","", "!Build: $_"); /^Release for / && ProcessHistory("COMMENTS","","", "!Build: $_"); } ProcessHistory("COMMENTS","","","!\n"); return(0); } # This routine parses "show license *" sub ShowLicense { print STDERR " In ShowLicense: $_" if ($debug); while () { tr/\015//d; last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); return(1) if /(Invalid input detected|Type help or )/; return(1) if (/\% Invalid command at /); return(-1) if (/\% Permission denied/); return(-1) if (/command authorization failed/i); /^-+$/ && next; # Skip lines of all dashes. s/ Grace .+$/ Grace/; # Drop anything after Grace. ProcessHistory("COMMENTS","","", "!LIC: $_"); } ProcessHistory("COMMENTS","","","!\n"); return(0); } # This routine parses "show system redundancy status" sub ShowRedundancy { print STDERR " In ShowRedundancy: $_" if ($debug); while () { tr/\015//d; last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); return(1) if /Line has invalid autocommand /; return(1) if /(Invalid input detected|Type help or )/; return(1) if (/\% Invalid command at /); return(-1) if (/\% Permission denied/); return(-1) if (/command authorization failed/i); s/ +$//; # Drop trailing ' ' ProcessHistory("COMMENTS","","","!Red: $_"); } ProcessHistory("COMMENTS","","","!\n"); return(0); } # This routine parses "show environment" sub ShowEnv { print STDERR " In ShowEnv: $_" if ($debug); while () { tr/\015//d; last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); return(1) if /Line has invalid autocommand /; return(1) if /(Invalid input detected|Type help or )/; return(1) if (/\% Invalid command at /); return(-1) if (/\% Permission denied/); return(-1) if (/command authorization failed/i); s/ +$//; # Drop trailing ' ' ProcessHistory("COMMENTS","","","!Env: $_"); } ProcessHistory("COMMENTS","","","!\n"); return(0); } # This routine parses "show environment temperature" sub ShowEnvTemp { print STDERR " In ShowEnvTemp: $_" if ($debug); while () { tr/\015//d; last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); return(1) if /Line has invalid autocommand /; return(1) if /(Invalid input detected|Type help or )/; return(-1) if (/\% Invalid command at /); return(-1) if (/\% Permission denied/); return(-1) if (/command authorization failed/i); # Cut out CurTemp - drop the 2nd to last field. #-------------------------------------------------------------------- #Module Sensor MajorThresh MinorThres CurTemp Status # (Celsius) (Celsius) (Celsius) #5 Outlet1 (s1) 125 125 33 Ok #5 QEng1Sn1(s10) 115 105 39 Ok s/^(.+\s)(\S+\s+)(\S+\s*)$/$1$3/; s/ +$//; # Drop trailing ' ' ProcessHistory("COMMENTS","","","!Env: $_"); } ProcessHistory("COMMENTS","","","!\n"); return(0); } # This routine parses "show environment power" sub ShowEnvPower { print STDERR " In ShowEnvPower: $_" if ($debug); while () { tr/\015//d; last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); next if (/^\s*\^\s*$/); return(1) if /Line has invalid autocommand /; return(1) if /(Invalid input detected|Type help or )/; return(1) if (/\% Invalid command at /); return(-1) if (/\% Permission denied/); return(-1) if (/command authorization failed/i); # Cut out Actual Output/Draw. #Power Actual Total #Supply Model Output Capacity Status # (Watts ) (Watts ) #------- ------------------- ----------- ----------- -------------- #1 ------------ 0 W 0 W Absent #3 749 W 5480 W Ok # Actual Power #Module Model Draw Allocated Status # (Watts ) (Watts ) #------- ------------------- ----------- ----------- -------------- #2 NURBURGRING N/A 573 W Powered-Up #fan1 N/A 720 W Powered-Up s/ Actual / /; s/ Output / /; s/ \(Watts \) / /; s/ Draw / /; s/ ----------- / /; s/ N\/A / / || s/ \d+ W / /; # Does not chop enough to line up. /actual draw/ && next; # Drop changing total power output. s/ +$//; # Drop trailing ' ' ProcessHistory("COMMENTS","","","!Env: $_"); } ProcessHistory("COMMENTS","","","!\n"); return(0); } # This routine parses "show boot" sub ShowBoot { print STDERR " In ShowBoot: $_" if ($debug); while () { tr/\015//d; last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); return(1) if /^\s*\^\s*$/; return(1) if /Line has invalid autocommand /; return(1) if /(Invalid input detected|Type help or )/; return(1) if /Ambiguous command/i; return(-1) if (/\% Invalid command at /); return(-1) if (/\% Permission denied/); return(-1) if (/command authorization failed/i); s/ variable = / = /; ProcessHistory("COMMENTS","","","!Variable: $_"); } ProcessHistory("COMMENTS","","","!\n"); return(0); } # This routine parses "dir /all ((disk|slot)N|bootflash|nvram):" sub DirSlotN { print STDERR " In DirSlotN: $_" if ($debug); my($dev) = (/\s([^\s]+):/); while () { tr/\015//d; last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); return(1) if /^\s*\^\s*$/; return(1) if /Line has invalid autocommand /; return(1) if /(Invalid input detected|Type help or )/; return(1) if (/\% Invalid command at /); return(1) if /(No such device|Error Sending Request)/i; return(1) if /\%Error: No such file or directory/; return(1) if /No space information available/; return(1) if / is either not present or not formatted/; return(-1) if /\%Error calling/; return(-1) if /(: device being squeezed|ATA_Status time out)/i; # busy return(-1) if (/\% Permission denied/); return(-1) if (/command authorization failed/i); return(1) if /(Open device \S+ failed|Error opening \S+:)/; if (/^\s*(\d+) bytes /) { my($tmp) = int($1 / (1024 * 1024)); s/$1 bytes /$tmp MB /; } ProcessHistory("COMMENTS","","","!Flash: $dev: $_"); } ProcessHistory("COMMENTS","","","!\n"); return(0); } # This routine parses "show module". sub ShowModule { print STDERR " In ShowModule: $_" if ($debug); while () { tr/\015//d; return if (/^\s*\^$/); last if (/online diag status/i); last if (/^$prompt/); next if (/^\s*$cmd\s*$/); return(1) if (/\% Invalid command at /); return(-1) if (/\% Permission denied/); return(-1) if (/command authorization failed/i); s/(.*) \*$/$1/; # Drop a trailing '*' /^\* this terminal session/ && next; s/ +$//; # Drop trailing ' ' ProcessHistory("COMMENTS","","","!Mod: $_"); } ProcessHistory("COMMENTS","","","!\n"); return(0); } # This routine parses "show inventory". sub ShowInventory { print STDERR " In ShowInventory: $_" if ($debug); while () { tr/\015//d; return if (/^\s*\^$/); last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); return(1) if /Line has invalid autocommand /; return(1) if /(Invalid input detected|Type help or )/; return(1) if (/\% Invalid command at /); return(-1) if (/\% Permission denied/); return(-1) if (/command authorization failed/i); if (/^(NAME: "[^"]*",)\s+(DESCR: "[^"]+")/) { ProcessHistory("COMMENTS","","", sprintf("!%-30s %s\n", $1, $2)); next; } # split PID/VID/SN line if (/^PID: (\S*)\s*,\s+VID: (\S*)\s*,\s+SN: (\S*)\s*$/) { my($entries) = ""; $entries .= "!PID: $1\n" if ($1); $entries .= "!VID: $2\n" if ($2); $entries .= "!SN: $3\n" if ($3); ProcessHistory("COMMENTS","","", "$entries"); next; } # split broken PID/VID/SN lines. if (/^PID: (\S*)\s*,\s+VID: (\S*)\s*$/) { my($entries) = ""; $entries .= "!PID: $1\n" if ($1); $entries .= "!VID: $2\n" if ($2); ; tr/\015//d; /^\s*,\s+SN: (\S*)\s*$/; $entries .= "!SN: $1\n" if ($1); ProcessHistory("COMMENTS","","", "$entries"); next; } ProcessHistory("COMMENTS","","","!$_"); } ProcessHistory("COMMENTS","","","!\n"); return(0); } # This routine parses "show vtp status" sub ShowVTP { print STDERR " In ShowVTP: $_" if ($debug); while () { tr/\015//d; last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); return(1) if /^\s*\^\s*$/; return(1) if /Line has invalid autocommand /; return(1) if /(Invalid input detected|Type help or )/; return(1) if (/\% Invalid command at /); return(-1) if (/\% Permission denied/); return(-1) if (/command authorization failed/i); next if (/^Configuration last modified by/); # the pager can not be disabled per-session on the PIX if (/^(<-+ More -+>)/) { my($len) = length($1); s/^$1\s{$len}//; } if (/^VTP Operating Mode\s+:\s+(Transparent|Server)/) { $DO_SHOW_VLAN = 1; } ProcessHistory("COMMENTS","","","!VTP: $_"); } ProcessHistory("COMMENTS","","","!\n"); return(0); } # This routine parses "show vlan" sub ShowVLAN { print STDERR " In ShowVLAN: $_" if ($debug); ($_ = , return(1)) if (!$DO_SHOW_VLAN); while () { tr/\015//d; last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); return(1) if /^\s*\^\s*$/; return(1) if /Line has invalid autocommand /; return(1) if /(Invalid input detected|Type help or )/; return(-1) if (/\% Invalid command at /); return(1) if /Ambiguous command/i; # newer releases (~12.1(9)) place the vlan config in the normal # configuration (write term). return(1) if ($type =~ /^(3550|4500)$/); return(-1) if (/\% Permission denied/); return(-1) if (/command authorization failed/i); # the pager can not be disabled per-session on the PIX if (/^(<-+ More -+>)/) { my($len) = length($1); s/^$1\s{$len}//; } ProcessHistory("COMMENTS","","","!VLAN: $_"); } ProcessHistory("COMMENTS","","","!\n"); return(0); } # This routine parses "show debug" sub ShowDebug { print STDERR " In ShowDebug: $_" if ($debug); my($lines) = 0; while () { tr/\015//d; last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); return(1) if /Line has invalid autocommand /; return(1) if /(Invalid input detected|Type help or )/; return(-1) if (/\% Invalid command at /); return(-1) if (/\% Permission denied/); return(-1) if (/command authorization failed/i); /^No matching debug flags set$/ && next; /^No debug flags set$/ && next; ProcessHistory("COMMENTS","","","!DEBUG: $_"); $lines++; } if ($lines) { ProcessHistory("COMMENTS","","","!\n"); } return(0); } # This routine parses "show cores" sub ShowCores { print STDERR " In ShowCores: $_" if ($debug); while () { tr/\015//d; last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); return(1) if /Line has invalid autocommand /; return(1) if /(Invalid input detected|Type help or )/; return(1) if (/\% Invalid command at /); return(-1) if (/\% Permission denied/); return(-1) if (/command authorization failed/i); ProcessHistory("COMMENTS","","","!CORES: $_"); } ProcessHistory("COMMENTS","","","!\n"); return(0); } # This routine parses "show processes log" sub ShowProcLog { print STDERR " In ShowProcLog: $_" if ($debug); while () { tr/\015//d; last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); return(1) if /Line has invalid autocommand /; return(1) if /(Invalid input detected|Type help or )/; return(-1) if (/\% Invalid command at /); return(-1) if (/\% Permission denied/); return(-1) if (/command authorization failed/i); ProcessHistory("COMMENTS","","","!PROC_LOGS: $_"); } ProcessHistory("COMMENTS","","","!\n"); return(0); } # This routine processes a "write term" sub WriteTerm { print STDERR " In WriteTerm: $_" if ($debug); my($lineauto,$comment,$linecnt) = (0,0,0); while () { tr/\015//d; last if (/^$prompt/); return(1) if /Line has invalid autocommand /; return(1) if (/(Invalid input detected|Type help or )/i); return(-1) if (/\% Invalid command at /); return(0) if ($found_end); # Only do this routine once return(-1) if (/\% Permission denied/); return(-1) if (/command authorization failed/i); # /Non-Volatile memory is in use/ && return(-1); # NvRAM is locked $linecnt++; $lineauto = 0 if (/^[^ ]/); # # skip the crap # if (/^(##+$|(Building|Current) configuration)/i) { # while () { # next if (/^Current configuration\s*:/i); # next if (/^:/); # next if (/^([%!].*|\s*)$/); # next if (/^ip add.*ipv4:/); # band-aid for 3620 12.0S # last; # } # if (defined($config_register)) { # ProcessHistory("","","","!\nconfig-register $config_register\n"); # } # tr/\015//d; # } # # some versions have other crap mixed in with the bits in the # # block above # /^! (Last configuration|NVRAM config last)/ && next; # # skip consecutive comment lines to avoid oscillating extra comment # # line on some access servers. grrr. # if (/^!/) { # next if ($comment); # ProcessHistory("","","",$_); # $comment++; # next; # } # $comment = 0; # Dog gone Cool matches to process the rest of the config /^!Command: show running-config/ && next; # kill this junk /^!Time: / && next; # kill this junk # /^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 # /^ clockrate / && next; # kill clockrate on serial interfaces # if (/^(enable )?(password|passwd)( level \d+)? / && $filter_pwds >= 1) { # ProcessHistory("ENABLE","","","!$1$2$3 \n"); # next; # } # if (/^(enable secret) / && $filter_pwds >= 2) { # ProcessHistory("ENABLE","","","!$1 \n"); # next; # } # if (/^username (\S+)(\s.*)? secret /) { # if ($filter_pwds >= 2) { # ProcessHistory("USER","keysort","$1","!username $1$2 secret \n"); # } else { # ProcessHistory("USER","keysort","$1","$_"); # } # next; # } # Sort username and delete passwords. if (/^username (\S+) password (\d) (\S+)(\s.*)$/) { if ($filter_pwds >= 2) { ProcessHistory("USER","keysort","$1","!username $1 password $4\n"); } elsif ($filter_pwds >= 1 && $2 ne "5") { ProcessHistory("USER","keysort","$1","!username $1 password $4\n"); } else { ProcessHistory("USER","keysort","$1","$_"); } next; } # Sort any other username info. /^username (\S+) .*$/ && ProcessHistory("USER","keysort","$1","$_") && next; # Sort snmp user and delete passwords. if (/^snmp-server user (\S+) (\S+) auth md5 (\S+) priv (\S+) localizedkey$/) { if ($filter_pwds >= 2) { ProcessHistory("SNMP-USER","keysort","$1","!snmp-server user $1 $2 auth md5 priv localizedkey\n"); } else { ProcessHistory("SNMP-USER","keysort","$1","$_"); } next; } # Sort any other snmp user info. /^snmp-server user (\S+) .*$/ && ProcessHistory("SNMP-USER","keysort","$1","$_") && next; # Delete bgp passwords. if (/^(\s*)password (\d) (\S+)(\s.*)?$/) { if ($filter_pwds >= 2) { ProcessHistory("","","","!$1password $4"); } elsif ($filter_pwds >= 1 && $2 ne "5") { ProcessHistory("","","","!$1password $4"); } else { ProcessHistory("","","","$_"); } next; } # # cisco AP w/ IOS # if (/^(wlccp \S+ username (\S+)(\s.*)? password) (\d \S+|\S+)/) { # if ($filter_pwds >= 1) { # ProcessHistory("USER","keysort","$2","!$1 \n"); # } else { # ProcessHistory("USER","keysort","$2","$_"); # } # next; # } # if (/^( set session-key (in|out)bound ah \d+ )/ && $filter_pwds >= 1) { # ProcessHistory("","","","!$1\n"); # next; # } # if (/^( set session-key (in|out)bound esp \d+ (authenticator|cypher) )/ && $filter_pwds >= 1) { # ProcessHistory("","","","!$1\n"); # next; # } # if (/^(\s*)password / && $filter_pwds >= 1) { # ProcessHistory("LINE-PASS","","","!$1password \n"); # next; # } # if (/^(\s*)secret / && $filter_pwds >= 2) { # ProcessHistory("LINE-PASS","","","!$1secret \n"); # next; # } # if (/^\s*neighbor (\S*) password / && $filter_pwds >= 1) { # ProcessHistory("","","","! neighbor $1 password \n"); # next; # } # if (/^(ppp .* password) 7 .*/ && $filter_pwds >= 1) { # ProcessHistory("","","","!$1 \n"); next; # } # if (/^(ip ftp password) / && $filter_pwds >= 1) { # ProcessHistory("","","","!$1 \n"); next; # } # if (/^( ip ospf authentication-key) / && $filter_pwds >= 1) { # ProcessHistory("","","","!$1 \n"); next; # } # # isis passwords appear to be completely plain-text # if (/^\s+isis password (\S+)( .*)?/ && $filter_pwds >= 1) { # ProcessHistory("","","","!isis password $2\n"); next; # } # if (/^\s+(domain-password|area-password) (\S+)( .*)?/ # && $filter_pwds >= 1) { # ProcessHistory("","","","!$1 $3\n"); next; # } # # this is reversable, despite 'md5' in the cmd # if (/^( ip ospf message-digest-key \d+ md5) / && $filter_pwds >= 1) { # ProcessHistory("","","","!$1 \n"); next; # } # # this is also reversable, despite 'md5 encrypted' in the cmd # if (/^( message-digest-key \d+ md5 (7|encrypted)) / && $filter_pwds >= 1) { # ProcessHistory("","","","!$1 \n"); next; # } # if (/^((crypto )?isakmp key) \S+ / && $filter_pwds >= 1) { # ProcessHistory("","","","!$1 $'"); next; # } # # filter HSRP passwords # if (/^(\s+standby \d+ authentication) / && $filter_pwds >= 1) { # ProcessHistory("","","","!$1 \n"); next; # } # # this appears in "measurement/sla" images # if (/^(\s+key-string \d?)/ && $filter_pwds >= 1) { # ProcessHistory("","","","!$1 \n"); next; # } # if (/^( l2tp tunnel \S+ password)/ && $filter_pwds >= 1) { # ProcessHistory("","","","!$1 \n"); next; # } # # i am told these are plain-text on the PIX # if (/^(vpdn username (\S+) password)/) { # if ($filter_pwds >= 1) { # ProcessHistory("USER","keysort","$2","!$1 \n"); # } else { # ProcessHistory("USER","keysort","$2","$_"); # } # next; # } # if (/^( cable shared-secret )/ && $filter_pwds >= 1) { # ProcessHistory("","","","!$1 \n"); # next; # } # /fair-queue individual-limit/ && next; # # sort ip explicit-paths. # if (/^ip explicit-path name (\S+)/) { # my($key) = $1; # my($expath) = $_; # while () { # tr/\015//d; # last if (/^$prompt/); # last if (/^$prompt/ || ! /^(ip explicit-path name |[ !])/); # if (/^ip explicit-path name (\S+)/) { # ProcessHistory("EXPATH","keysort","$key","$expath"); # $key = $1; # $expath = $_; # } else { # $expath .= $_; # } # } # ProcessHistory("EXPATH","keysort","$key","$expath"); # } # # sort route-maps # if (/^route-map (\S+)/) { # my($key) = $1; # my($routemap) = $_; # while () { # tr/\015//d; # last if (/^$prompt/ || ! /^(route-map |[ !])/); # if (/^route-map (\S+)/) { # ProcessHistory("ROUTEMAP","keysort","$key","$routemap"); # $key = $1; # $routemap = $_; # } else { # $routemap .= $_; # } # } # ProcessHistory("ROUTEMAP","keysort","$key","$routemap"); # } # # filter out any RCS/CVS tags to avoid confusing local CVS storage # s/\$(Revision|Id):/ $1:/; # # order access-lists # /^access-list\s+(\d\d?)\s+(\S+)\s+(\S+)/ && # ProcessHistory("ACL $1 $2","$aclsort","$3","$_") && next; # # order extended access-lists # /^access-list\s+(\d\d\d)\s+(\S+)\s+ip\s+host\s+(\S+)/ && # ProcessHistory("EACL $1 $2","$aclsort","$3","$_") && next; # /^access-list\s+(\d\d\d)\s+(\S+)\s+ip\s+(\d\S+)/ && # ProcessHistory("EACL $1 $2","$aclsort","$3","$_") && next; # /^access-list\s+(\d\d\d)\s+(\S+)\s+ip\s+any/ && # ProcessHistory("EACL $1 $2","$aclsort","0.0.0.0","$_") && next; # # order arp lists # /^arp\s+(\d+\.\d+\.\d+\.\d+)\s+/ && # ProcessHistory("ARP","$aclsort","$1","$_") && next; # /^ip prefix-list\s+(\S+)\s+seq\s+(\d+)\s+(permit|deny)\s+(\d\S+)(\/.*)$/ && # ProcessHistory("PACL $1 $3","$aclsort","$4","ip prefix-list $1 $3 $4$5\n") # && next; # # order logging statements # /^logging (\d+\.\d+\.\d+\.\d+)/ && # ProcessHistory("LOGGING","ipsort","$1","$_") && next; # order cli alias names /^cli alias name (\S+) .*$/ && ProcessHistory("CLI-ALIAS","keysort","$1","$_") && next; # order snmp-server enable trap statements /^snmp-server enable traps (.*)$/ && ProcessHistory("SNMP-TRAPS","keysort","$1","$_") && next; # # order/prune snmp-server host statements # # we only prune lines of the form # # snmp-server host a.b.c.d # if (/^snmp-server host (\d+\.\d+\.\d+\.\d+) /) { # if ($filter_commstr) { # my($ip) = $1; # my($line) = "snmp-server host $ip"; # my(@tokens) = split(' ', $'); # my($token); # while ($token = shift(@tokens)) { # if ($token eq 'version') { # $line .= " " . join(' ', ($token, shift(@tokens))); # if ($token eq '3') { # $line .= " " . join(' ', ($token, shift(@tokens))); # } # } elsif ($token eq 'vrf') { # $line .= " " . join(' ', ($token, shift(@tokens))); # } elsif ($token =~ /^(informs?|traps?|(no)?auth)$/) { # $line .= " " . $token; # } else { # $line = "!$line " . join(' ', ("", join(' ',@tokens))); # last; # } # } # ProcessHistory("SNMPSERVERHOST","ipsort","$ip","$line\n"); # } else { # ProcessHistory("SNMPSERVERHOST","ipsort","$1","$_"); # } # next; # } # if (/^(snmp-server community) (\S+)/) { # if ($filter_commstr) { # ProcessHistory("SNMPSERVERCOMM","keysort","$_","!$1 $'") && next; # } else { # ProcessHistory("SNMPSERVERCOMM","keysort","$_","$_") && next; # } # } # # prune tacacs/radius server keys # if (/^((tacacs|radius)-server\s(\w*[-\s(\s\S+])*\s?key) (\d )?\w+/ # && $filter_pwds >= 1) { # ProcessHistory("","","","!$1 $'"); next; # } # # order clns host statements # /^clns host \S+ (\S+)/ && # ProcessHistory("CLNS","keysort","$1","$_") && next; # # order alias statements # /^alias / && ProcessHistory("ALIAS","keysort","$_","$_") && next; # # delete ntp auth password - this md5 is a reversable too # if (/^(ntp authentication-key \d+ md5) / && $filter_pwds >= 1) { # ProcessHistory("","","","!$1 \n"); next; # } # # order ntp peers/servers # if (/^ntp (server|peer) (\d+)\.(\d+)\.(\d+)\.(\d+)/) { # $sortkey = sprintf("$1 %03d%03d%03d%03d",$2,$3,$4,$5); # ProcessHistory("NTP","keysort",$sortkey,"$_"); # next; # } # # order ip host statements # /^ip host (\S+) / && # ProcessHistory("IPHOST","keysort","$1","$_") && next; # # order ip nat source static statements # /^ip nat (\S+) source static (\S+)/ && # ProcessHistory("IP NAT $1","ipsort","$2","$_") && next; # # order atm map-list statements # /^\s+ip\s+(\d+\.\d+\.\d+\.\d+)\s+atm-vc/ && # ProcessHistory("ATM map-list","ipsort","$1","$_") && next; # # order ip rcmd lines # /^ip rcmd/ && ProcessHistory("RCMD","keysort","$_","$_") && next; # # # system controller # /^syscon address (\S*) (\S*)/ && # ProcessHistory("","","","!syscon address $1 \n") && # next; # if (/^syscon password (\S*)/ && $filter_pwds >= 1) { # ProcessHistory("","","","!syscon password \n"); # next; # } # catch anything that wasnt matched above. ProcessHistory("","","","$_"); # end of config. the ": " game is for the PIX if (/^(: +)?end$/) { $found_end = 1; return(0); } } # The ContentEngine lacks a definitive "end of config" marker. If we # know that it is a CE, SAN, or NXOS and we have seen at least 5 lines # of write term output, we can be reasonably sure that we got the config. if (($type == "CE" || $type == "SAN" || $type == "NXOS" ) && $linecnt > 5) { $found_end = 1; return(0); } return(0); } # This routine parses a single command that returns no required info. sub RunCommand { print STDERR " In RunCommand: $_" if ($debug); while () { tr/\015//d; last if (/^$prompt/); return(1) if /Line has invalid autocommand /; return(1) if (/(Invalid input detected|Type help or )/i); } return(0); } # dummy function sub DoNothing {print STDOUT;} ############################## # add these: # show version module X - wait until can show all # show version module X epld - wait until can show all ############################## # Main @commandtable = ( {'term no monitor-force' => 'RunCommand'}, {'show version' => 'ShowVersion'}, {'show version build-info all' => 'ShowVersionBuild'}, {'show license' => 'ShowLicense'}, {'show license usage' => 'ShowLicense'}, {'show license host-id' => 'ShowLicense'}, {'show system redundancy status' => 'ShowRedundancy'}, {'show environment clock' => 'ShowEnv'}, {'show environment fan' => 'ShowEnv'}, {'show environment fex all fan' => 'ShowEnv'}, {'show environment temperature' => 'ShowEnvTemp'}, {'show environment power' => 'ShowEnvPower'}, {'show boot' => 'ShowBoot'}, {'dir bootflash:' => 'DirSlotN'}, {'dir debug:' => 'DirSlotN'}, {'dir logflash:' => 'DirSlotN'}, {'dir slot0:' => 'DirSlotN'}, {'dir usb1:' => 'DirSlotN'}, {'dir usb2:' => 'DirSlotN'}, {'dir volatile:' => 'DirSlotN'}, {'show module' => 'ShowModule'}, {'show module xbar' => 'ShowModule'}, {'show inventory' => 'ShowInventory'}, {'show vtp status' => 'ShowVTP'}, # drop? {'show vlan' => 'ShowVLAN'}, {'show debug' => 'ShowDebug'}, {'show cores vdc-all' => 'ShowCores'}, {'show processes log vdc-all' => 'ShowProcLog'}, {'show running-config' => 'WriteTerm'}, ); # 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("|", map quotemeta($_), @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 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 clogin -t $timeo -c\"$cisco_cmds\" $host\n" if ($debug); print STDOUT "executing clogin -t $timeo -c\"$cisco_cmds\" $host\n" if ($log); if (defined($ENV{NOPIPE}) && $ENV{NOPIPE} =~ /^YES/i) { system "clogin -t $timeo -c \"$cisco_cmds\" $host $host.raw 2>&1" || die "clogin failed for $host: $!\n"; open(INPUT, "< $host.raw") || die "clogin failed for $host: $!\n"; } else { open(INPUT,"clogin -t $timeo -c \"$cisco_cmds\" $host ) { tr/\015//d; if (/[>#]\s?exit$/) { print STDERR ("$host: found exit\n") if ($debug); $clean_run = 1; last; } if (/^Error:/) { print STDOUT ("$host clogin error: $_"); print STDERR ("$host clogin error: $_") if ($debug); $clean_run = 0; last; } while (/#\s*($cmds_regexp)\s*$/) { $cmd = $1; 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; } $rval = &{$commands{$cmd}}; delete($commands{$cmd}); if ($rval == -1) { $clean_run = 0; print STDERR ("$host: $cmd failed: $rval\n") if ($debug); last TOP; } if (/[>#]\s?exit$/) { print STDERR ("$host: found exit\n") if ($debug); $clean_run = 1; last TOP; } } } print STDOUT "Done $logincmd: $_\n" if ($log); # Flush History ProcessHistory("","","",""); # Cleanup close(INPUT); close(OUTPUT); if (defined($ENV{NOPIPE}) && $ENV{NOPIPE} =~ /^YES/i) { 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); print STDERR "$host: clean: $clean_run, end: $found_end\n" if ($debug); system("/usr/bin/tail -1 $host.new"); } unlink "$host.new" if (! $debug); } rancid-2.3.8/bin/par.in100644 015615 000000 00000013643 11342156264 0010353#! @PERLV_PATH@ ## ## $Id: par.in 2096 2009-06-17 21:49:46Z heas $ ## ## @PACKAGE@ @VERSION@ ## Copyright (c) 1997-2008 by Terrapin Communications, Inc. ## All rights reserved. ## ## This code is derived from software contributed to and maintained by ## Terrapin Communications, Inc. by Henry Kilmer, John Heasley, Andrew Partan, ## Pete Whiting, Austin Schutz, and Andrew Fort. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions ## are met: ## 1. Redistributions of source code must retain the above copyright ## notice, this list of conditions and the following disclaimer. ## 2. Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## 3. All advertising materials mentioning features or use of this software ## must display the following acknowledgement: ## This product includes software developed by Terrapin Communications, ## Inc. and its contributors for RANCID. ## 4. Neither the name of Terrapin Communications, Inc. nor the names of its ## contributors may be used to endorse or promote products derived from ## this software without specific prior written permission. ## 5. It is requested that non-binding fixes and modifications be contributed ## back to Terrapin Communications, Inc. ## ## THIS SOFTWARE IS PROVIDED BY Terrapin Communications, INC. AND CONTRIBUTORS ## ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ## TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COMPANY OR CONTRIBUTORS ## BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ## CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ## SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ## INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ## CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ## ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ## POSSIBILITY OF SUCH DAMAGE. # # PAR - parallel processing of command # # par -q -n # -l logfile -c command -x -d # -q = quiet mode (don't log anything to the logfiles) # -n # = number of processes to run at once (default = 3) # -l logfile = logfile to store par logging into (.0-.n) # -c command = command to run (can also be in the list # of routers begining with a : # -x = view par logs as they run through xterms # -i = run commands through interactive xterms # -d = print debugging to stderr # -p # = pause # seconds between forks, default 0. # -f = no file or STDIN, just run a quantity of $command. # This precludes passing different args to each process. # -e = exec args split by spaces rather than use sh -c # # par takes a list of items to run a command on. If the list entry begins # with a ":" the remainder of the line is the command to run ("{}" will be # replaced with each subsequent item in the list. If the list entry begins # with a "#", the entry is ignored. If a command is defined (either with # the -c or with a : line) any entry thereafter will be applied to the # command by replacing the {} brackets. In no cammand is defined, then each # line is assumed to be a command to be run. # use Getopt::Std; getopts('p:n:l:c:fixedqV'); if ($opt_V) { print "@PACKAGE@ @VERSION@\n"; exit(0); } $procs=$opt_n; $procs=3 if(!$procs); $command=$opt_c; #$command="{}" if(!$command); $parlog=$opt_l; $parlog="par.log.".time() if(!$parlog); $debug=$opt_d; $no_file=$opt_f ? 1 : 0; $pause_time = $opt_p ? $opt_p : 0; if ($opt_q && ($opt_x || $opt_l)) { print STDERR "-q nullifies -x and -l\n"; exit(1); } $signalled=0; sub handler { $signalled++; print STDERR "Received signal - ending run ($signalled).\n"; if($signalled>1) { printf(STDERR "Ok - killing $id!\n"); kill 9, 0; exit(1); } } $SIG{'INT'} = 'handler'; $SIG{'TERM'} = 'handler'; $SIG{'QUIT'} = 'handler'; sub start { local($cmd,$logfile)=@_; unless ($id=fork) { if (!$opt_q) { local($date)=scalar localtime; open(LOG,">>$logfile"); print(LOG "!!!!!!!\n!$date: $cmd\n!!!!!!!\n"); close(LOG); exec "($cmd) >>$logfile"; } else { if($opt_e) { # Don't use sh -c. exec split(/\s+/, $cmd); } exec "($cmd)"; } exit 0; } print STDERR "Starting $cmd: process id=$id logfile=$logfile\n" if ($debug); $id; } sub finish { if(($id=wait)>0){ $logfile=$log{$id}; print STDERR "$id finished (logfile $logfile)\n" if($logfile && $debug); $logfile; } } sub watchf { local($log)=@_; unless(fork) { exec "xterm -e tail -f $log" ; exit 1; } } # this does not work, $_ doesnt end up with <> #for($i=0; ($no_file && $i<$procs) || (! $no_file && <> ) ;$i++) { for($i=0; ($no_file || ($_=<>)) ;$i++) { chop; if (/^\#/){$i--;next;} if ($opt_c == "" && /^:(.*)$/) { $command=$1;$i--;next; } if ($i<$procs) { $logfile="running.$i"; $logfile="$parlog.$i" if (!$opt_q); } else { $logfile=finish; } last if $signalled; if ($logfile) { $cmd = $command; $cmd =~ s/\{\}/$_/g; $cmd = "xterm -e $cmd" if ($opt_i); $id=start($cmd,$logfile); watchf($logfile) if($opt_x); $log{$id} = $logfile; } print STDERR "$i/$procs: $_: id=$id, log=$log{$id}\n" if ($debug); sleep($pause_time) if ($pause_time); } if($signalled && !eof) { $i--; print STDERR "Signalled - not running these:\n$_\n"; while(<>){print STDERR;} } else { print STDERR "All work assigned. Waiting for remaining processes.\n" if ($debug); } $procs=$i if ($i<$procs); while($procs) { $procs-- if(finish); } print STDERR "Complete\n" if ($debug); rancid-2.3.8/bin/prancid.in100755 015615 000000 00000044661 11535733223 0011220#! @PERLV_PATH@ ## ## $Id: prancid.in 2279 2011-01-31 22:41:00Z heas $ ## ## @PACKAGE@ @VERSION@ ## Copyright (c) 1997-2008 by Terrapin Communications, Inc. ## All rights reserved. ## ## This code is derived from software contributed to and maintained by ## Terrapin Communications, Inc. by Henry Kilmer, John Heasley, Andrew Partan, ## Pete Whiting, Austin Schutz, and Andrew Fort. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions ## are met: ## 1. Redistributions of source code must retain the above copyright ## notice, this list of conditions and the following disclaimer. ## 2. Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## 3. All advertising materials mentioning features or use of this software ## must display the following acknowledgement: ## This product includes software developed by Terrapin Communications, ## Inc. and its contributors for RANCID. ## 4. Neither the name of Terrapin Communications, Inc. nor the names of its ## contributors may be used to endorse or promote products derived from ## this software without specific prior written permission. ## 5. It is requested that non-binding fixes and modifications be contributed ## back to Terrapin Communications, Inc. ## ## THIS SOFTWARE IS PROVIDED BY Terrapin Communications, INC. AND CONTRIBUTORS ## ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ## TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COMPANY OR CONTRIBUTORS ## BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ## CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ## SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ## INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ## CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ## ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ## POSSIBILITY OF SUCH DAMAGE. # # This version of rancid tries to deal with Prockets. # # RANCID - Really Awesome New Cisco confIg Differ # # usage: rancid [-dV] [-l] [-f filename | hostname] # use Getopt::Std; 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 my(@commandtable, %commands, @commands);# command lists my($aclsort) = ("ipsort"); # ACL sorting mode my($filter_commstr); # SNMP community string filtering my($filter_pwds); # password filtering mode my($platform); # platform/cpu type # 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)) && scalar(%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 routine 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 routine 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 routine 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 routine (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 "show version" sub ShowVersion { print STDERR " In ShowVersion: $_" if ($debug); while () { tr/\015//d; last if(/^$prompt/); next if(/^(\s*|\s*$cmd\s*)$/); return(-1) if (/command authorization failed/i); if (/(lynxos|kernel) Version: .* (\S+)/i) { $platform = $2; } /Procket/ && ProcessHistory("COMMENTS","keysort","B0", "! $_") && next; /System Uptime:/ && next; /Protocol Uptime:/ && next; ProcessHistory("COMMENTS","keysort","B0", "!$_") && next; } return(0); } # This routine parses "show package" sub ShowPackage { print STDERR " In ShowPackage: $_" if ($debug); while () { tr/\015//d; last if(/^$prompt/); next if(/^(\s*|\s*$cmd\s*)$/); return(-1) if (/command authorization failed/i); ProcessHistory("COMMENTS","keysort","C0", "! $_") && next; } return(0); } # This routine parses "show hardware" sub ShowHardware { print STDERR " In ShowHardware: $_" if ($debug); while () { tr/\015//d; last if(/^$prompt/); next if(/^(\s*|\s*$cmd\s*)$/); # skip show hardware on titanium return(0) if ($platform =~ /i386/i); return(-1) if (/command authorization failed/i); return(-1) if (/cli: couldn.t communicate with/); ProcessHistory("COMMENTS","keysort","D0", "! $_") && next; } return(0); } # This routine parses "show inventory" sub ShowInventory { print STDERR " In ShowInventory: $_" if ($debug); while () { tr/\015//d; last if(/^$prompt/); next if(/^(\s*|\s*$cmd\s*)$/); return(0) if (/^\s+\^/); return(-1) if (/command authorization failed/i); /Procket/ && ProcessHistory("COMMENTS","keysort","E0", "! $_") && next; /System Uptime:/ && next; /Protocol Uptime:/ && next; ProcessHistory("COMMENTS","keysort","E0", "!$_") && next; } return(0); } # This routine processes a "write term" sub WriteTerm { print STDERR " In WriteTerm: $_" if ($debug); while () { tr/\015//d; last if(/^$prompt/); return(-1) if (/command authorization failed/i); /Non-Volatile memory is in use/ && return(-1); # NvRAM is locked # skip the crap if (/^(##+$|(Building|Current) configuration)/i) { while () { next if (/^Current configuration\s*:/i); next if (/^([%!].*|\s*)$/); last; } tr/\015//d; } # some versions have other crap mixed in with the bits in the # block above /^! Last Changed:/ && next; # 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 # /^ clockrate / && next; # kill clockrate on serial interfaces if (/^(enable secret( level \d)?) / && $filter_pwds >= 2) { ProcessHistory("ENABLE","","","!$1 \n"); next; } if (/^username (\S+)(\s.*)? password ((\d) \S+|\S+)/) { if ($filter_pwds == 2) { ProcessHistory("USER","keysort","$1","!username $1$2 password \n"); } elsif ($filter_pwds == 1 && $4 ne "5"){ ProcessHistory("USER","keysort","$1","!username $1$2 password \n"); } else { ProcessHistory("USER","keysort","$1","$_"); } next; } # prune passwords {bgp, ...} if (/^(\s*)password / && $filter_pwds >= 1) { ProcessHistory("","","","!$1password \n"); next; } # prune authentication keys {vrrp vrid N, router isis...} if (/^(\s*authentication \S+ key) / && $filter_pwds >= 1) { ProcessHistory("","","","!$1 \n"); next; } if (/^(\s*authentication-key) \d \S+( .*)/ && $filter_pwds >= 1) { ProcessHistory("","","","!$1 $2\n"); next; } # if (/^\s*neighbor (\S*) password / && $filter_pwds >= 1) { # ProcessHistory("","","","! neighbor $1 password \n"); # next; # } # if (/^(ppp .* password) 7 .*/ && $filter_pwds >= 1) { # ProcessHistory("","","","!$1 \n"); next; # } # if (/^(ip ftp password) / && $filter_pwds >= 1) { # ProcessHistory("","","","!$1 \n"); next; # } # prune ospf keys if (/^( ip ospf authentication-key) / && $filter_pwds >= 1) { ProcessHistory("","","","!$1 \n"); next; } # this is reversable, despite 'md5' in the cmd if (/^( ip ospf message-digest-key \d+ md5) / && $filter_pwds >= 1) { ProcessHistory("","","","!$1 \n"); next; } # this is reversable, despite 'md5' in the cmd if (/^(\s*message-digest-key \d+ md5) / && $filter_pwds >= 1) { ProcessHistory("","","","!$1 \n"); next; } # if (/^((crypto )?isakmp key) \S+ / && $filter_pwds >= 1) { # ProcessHistory("","","","!$1 $'"); next; # } # sort ip explicit-paths. if (/^ip explicit-path name (\S+)/) { my($key) = $1; my($expath) = $_; while () { tr/\015//d; last if (/^$prompt/); last if (/^$prompt/ || ! /^(ip explicit-path name |[ !])/); if (/^ip explicit-path name (\S+)/) { ProcessHistory("EXPATH","keysort","$key","$expath"); $key = $1; $expath = $_; } else { $expath .= $_; } } ProcessHistory("EXPATH","keysort","$key","$expath"); } # sort route-maps if (/^route-map (\S+)/) { my($key) = $1; my($routemap) = $_; while () { tr/\015//d; last if (/^$prompt/ || ! /^(route-map |[ !])/); if (/^route-map (\S+)/) { ProcessHistory("ROUTEMAP","keysort","$key","$routemap"); $key = $1; $routemap = $_; } else { $routemap .= $_; } } ProcessHistory("ROUTEMAP","keysort","$key","$routemap"); } # filter out any RCS/CVS tags to avoid confusing local CVS storage s/\$(Revision|Id):/ $1:/; # # order access-lists # /^access-list\s+(\d\d?)\s+(\S+)\s+(\S+)/ && # ProcessHistory("ACL $1 $2","$aclsort","$3","$_") && next; # # order extended access-lists # /^access-list\s+(\d\d\d)\s+(\S+)\s+ip\s+host\s+(\S+)/ && # ProcessHistory("EACL $1 $2","$aclsort","$3","$_") && next; # /^access-list\s+(\d\d\d)\s+(\S+)\s+ip\s+(\d\S+)/ && # ProcessHistory("EACL $1 $2","$aclsort","$3","$_") && next; # /^access-list\s+(\d\d\d)\s+(\S+)\s+ip\s+any/ && # ProcessHistory("EACL $1 $2","$aclsort","0.0.0.0","$_") && next; # # order arp lists # /^arp\s+(\d+\.\d+\.\d+\.\d+)\s+/ && # ProcessHistory("ARP","$aclsort","$1","$_") && next; # /^ip prefix-list\s+(\S+)\s+seq\s+(\d+)\s+(permit|deny)\s+(\d\S+)(\/.*)$/ && # ProcessHistory("PACL $1 $3","$aclsort","$4","ip prefix-list $1 $3 $4$5\n") # && next; # order logging statements /^logging (\d+\.\d+\.\d+\.\d+)/ && ProcessHistory("LOGGING","ipsort","$1","$_") && next; # order/prune snmp-server host statements # we only prune lines of the form # snmp-server host a.b.c.d if (/^snmp-server host (\d+\.\d+\.\d+\.\d+) /) { if ($filter_commstr) { my($ip) = $1; my($line) = "snmp-server host $ip"; my(@tokens) = split(' ', $'); my($token); while ($token = shift(@tokens)) { if ($token eq 'version') { $line .= " " . join(' ', ($token, shift(@tokens))); } elsif ($token =~ /^(informs?|traps?|(no)?auth)$/) { $line .= " " . $token; } else { $line = "!$line " . join(' ', ("", join(' ',@tokens))); last; } } ProcessHistory("SNMPSERVERHOST","ipsort","$ip","$line\n"); } else { ProcessHistory("SNMPSERVERHOST","ipsort","$1","$_"); } next; } if (/^(snmp-server community) (\S+)/) { if ($filter_commstr) { ProcessHistory("SNMPSERVERCOMM","keysort","$_","!$1 $'") && next; } else { ProcessHistory("SNMPSERVERCOMM","keysort","$_","$_") && next; } } # prune tacacs/radius server keys if (/^(tacacs-server|radius-server) key / && $filter_pwds >= 1) { ProcessHistory("","","","!$1 key \n"); next; } if (/^(tacacs-server host \S+( .*)? key) (\d )?\S+/ && $filter_pwds >= 1) { ProcessHistory("","","","!$1 \n"); next; } # order clns host statements # /^clns host \S+ (\S+)/ && # ProcessHistory("CLNS","keysort","$1","$_") && next; # prune vrrp password if (/^( ip vrrp authentication .* key) / && $filter_pwds >= 1) { ProcessHistory("","","","!$1 \n"); next; } # prune isis password if (/^( isis authentication-key) \d \S+/ && $filter_pwds >= 1) { ProcessHistory("","","","!$1 $'"); next; } # prune msdp password if (/^(ip msdp password \S+) / && $filter_pwds >= 1) { ProcessHistory("","","","!$1 \n"); next; } # delete ntp auth password - this md5 is a reversable too if (/^(ntp authentication-key \d+ md5) / && $filter_pwds >= 1) { ProcessHistory("","","","!$1 \n"); next; } # order ntp peers/servers if (/^ntp (server|peer) (\d+)\.(\d+)\.(\d+)\.(\d+)/) { $sortkey = sprintf("$1 %03d%03d%03d%03d",$2,$3,$4,$5); ProcessHistory("NTP","keysort",$sortkey,"$_"); next; } # # order ip host line statements # /^ip host line(\d+)/ && # ProcessHistory("IPHOST","numsort","$1","$_") && next; # # order ip nat source static statements # /^ip nat (\S+) source static (\S+)/ && # ProcessHistory("IP NAT $1","ipsort","$2","$_") && next; # # order atm map-list statements # /^\s+ip\s+(\d+\.\d+\.\d+\.\d+)\s+atm-vc/ && # ProcessHistory("ATM map-list","ipsort","$1","$_") && next; # # order ip rcmd lines # /^ip rcmd/ && ProcessHistory("RCMD","keysort","$_","$_") && next; # catch anything that wasnt matched above. ProcessHistory("","","","$_"); # end of config. if (/^end$/) { $found_end = 1; return(1); } } return(0); } # dummy function sub DoNothing {print STDOUT;} # Main @commandtable = ( {'show version all' => 'ShowVersion'}, {'show package' => 'ShowPackage'}, {'show hardware' => 'ShowHardware'}, {'show inventory' => 'ShowInventory'}, {'write term' => 'WriteTerm'} ); # 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("|", map quotemeta($_), @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 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 clogin -t $timeo -c\"$cisco_cmds\" $host\n" if ($debug); print STDOUT "executing clogin -t $timeo -c\"$cisco_cmds\" $host\n" if ($log); if (defined($ENV{NOPIPE}) && $ENV{NOPIPE} =~ /^YES/i) { system "clogin -t $timeo -c \"$cisco_cmds\" $host $host.raw 2>&1" || die "clogin failed for $host: $!\n"; open(INPUT, "< $host.raw") || die "clogin failed for $host: $!\n"; } else { open(INPUT,"clogin -t $timeo -c \"$cisco_cmds\" $host ) { tr/\015//d; if (/\#\s?exit$/) { $clean_run=1; last; } if (/^Error:/) { print STDOUT ("$host clogin error: $_"); print STDERR ("$host clogin error: $_") if ($debug); $clean_run=0; last; } while (/#\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}) && $ENV{NOPIPE} =~ /^YES/i) { 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); } rancid-2.3.8/bin/rancid-fe.in100644 015615 000000 00000007163 11556057021 0011417#! @PERLV_PATH@ ## ## $Id: rancid-fe.in 2296 2011-04-27 18:18:56Z heas $ ## ## @PACKAGE@ @VERSION@ ## Copyright (c) 1997-2008 by Terrapin Communications, Inc. ## All rights reserved. ## ## This code is derived from software contributed to and maintained by ## Terrapin Communications, Inc. by Henry Kilmer, John Heasley, Andrew Partan, ## Pete Whiting, Austin Schutz, and Andrew Fort. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions ## are met: ## 1. Redistributions of source code must retain the above copyright ## notice, this list of conditions and the following disclaimer. ## 2. Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## 3. All advertising materials mentioning features or use of this software ## must display the following acknowledgement: ## This product includes software developed by Terrapin Communications, ## Inc. and its contributors for RANCID. ## 4. Neither the name of Terrapin Communications, Inc. nor the names of its ## contributors may be used to endorse or promote products derived from ## this software without specific prior written permission. ## 5. It is requested that non-binding fixes and modifications be contributed ## back to Terrapin Communications, Inc. ## ## THIS SOFTWARE IS PROVIDED BY Terrapin Communications, INC. AND CONTRIBUTORS ## ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ## TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COMPANY OR CONTRIBUTORS ## BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ## CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ## SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ## INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ## CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ## ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ## POSSIBILITY OF SUCH DAMAGE. # # rancid-FE - front-end to rancid/jrancid/etc. for use with par. # # usage: rancid-fe : # require 5; ($router, $vendor) = split('\:', $ARGV[0]); $vendor =~ tr/[A-Z]/[a-z]/; %vendortable = ( 'agm' => 'agmrancid', 'alteon' => 'arancid', 'arista' => 'arrancid', 'avocent' => 'avorancid', 'baynet' => 'brancid', 'cat5' => 'cat5rancid', 'cisco' => 'rancid', 'cisco-nx' => 'nxrancid', 'cisco-xr' => 'xrrancid', 'css' => 'cssrancid', 'enterasys' => 'rivrancid', 'erx' => 'jerancid', 'extreme' => 'xrancid', 'ezt3' => 'erancid', 'f5' => 'f5rancid', 'force10' => 'f10rancid', 'fortigate' => 'fnrancid', 'foundry' => 'francid', 'hitachi' => 'htrancid', 'hp' => 'hrancid', 'juniper' => 'jrancid', 'mikrotik' => 'mtrancid', 'mrtd' => 'mrancid', 'mrv' => 'mrvrancid', 'netopia' => 'trancid', 'netscaler' => 'nsrancid', 'netscreen' => 'nrancid', 'procket' => 'prancid', 'redback' => 'rrancid', 'riverstone' => 'rivrancid', 'smc' => 'srancid', 'tnt' => 'tntrancid', 'zebra' => 'zrancid' ); if ($vendortable{$vendor} eq "") { printf(STDERR "unknown router manufacturer for $router: $vendor\n"); exit(-1); } else { exec($vendortable{$vendor} . " $router"); } printf(STDERR "exec failed router manufacturer $vendor: $!\n"); exit(-1); rancid-2.3.8/bin/rancid.in100644 015615 000000 00000210430 11712070521 0011012#! @PERLV_PATH@ ## ## $Id: rancid.in 2377 2012-01-31 22:55:13Z heas $ ## ## @PACKAGE@ @VERSION@ ## Copyright (c) 1997-2009 by Terrapin Communications, Inc. ## All rights reserved. ## ## This code is derived from software contributed to and maintained by ## Terrapin Communications, Inc. by Henry Kilmer, John Heasley, Andrew Partan, ## Pete Whiting, Austin Schutz, and Andrew Fort. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions ## are met: ## 1. Redistributions of source code must retain the above copyright ## notice, this list of conditions and the following disclaimer. ## 2. Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## 3. All advertising materials mentioning features or use of this software ## must display the following acknowledgement: ## This product includes software developed by Terrapin Communications, ## Inc. and its contributors for RANCID. ## 4. Neither the name of Terrapin Communications, Inc. nor the names of its ## contributors may be used to endorse or promote products derived from ## this software without specific prior written permission. ## 5. It is requested that non-binding fixes and modifications be contributed ## back to Terrapin Communications, Inc. ## ## THIS SOFTWARE IS PROVIDED BY Terrapin Communications, INC. AND CONTRIBUTORS ## ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ## TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COMPANY OR CONTRIBUTORS ## BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ## CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ## SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ## INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ## CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ## ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ## POSSIBILITY OF SUCH DAMAGE. # # RANCID - Really Awesome New Cisco confIg Differ # # usage: rancid [-dV] [-l] [-f filename | hostname] # use Getopt::Std; getopts('dflV'); if ($opt_V) { print "@PACKAGE@ @VERSION@\n"; exit(0); } $log = $opt_l; $debug = $opt_d; $file = $opt_f; $host = $ARGV[0]; $proc = ""; $ios = "IOS"; $clean_run = 0; $found_end = 0; $found_version = 0; $found_env = 0; $found_diag = 0; $timeo = 90; # clogin timeout in seconds my(@commandtable, %commands, @commands);# command lists my($aclsort) = ("ipsort"); # ACL sorting mode my($config_register); # configuration register value my($filter_commstr); # SNMP community string filtering my($filter_pwds); # password filtering mode my($supbootdisk) = 0; # skip sup-bootflash if sup-bootdisk # worked # 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)) && scalar(%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 routine 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 routine 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 routine 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 routine (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 "show version" sub ShowVersion { print STDERR " In ShowVersion: $_" if ($debug); my($slaveslot); while () { tr/\015//d; if (/^$prompt/) { $found_version = 1; last}; next if (/^(\s*|\s*$cmd\s*)$/); return(1) if (/Line has invalid autocommand /); return(1) if (/(Invalid (input|command) detected|Type help or )/i); return(0) if ($found_version); # Only do this routine once return(-1) if (/command authorization failed/i); # the pager can not be disabled per-session on the PIX if (/^(<-+ More -+>)/) { my($len) = length($1); s/^$1\s{$len}//; } if (/^Slave in slot (\d+) is running/) { $slave = " Slave:"; $slaveslot = ", slot $1"; next; } if (/cisco ios .* IOS-XE/i) { $ios = "XE"; } if (/^Application and Content Networking .*Software/) { $type = "CE"; } # treat the ACE like the Content Engines for matching endofconfig if (/^Cisco Application Control Software/) { $type = "CE"; } if (/^Cisco Storage Area Networking Operating System/) { $type = "SAN";} if (/^Cisco Nexus Operating System/) { $type = "NXOS";} /^Application and Content Networking Software Release /i && ProcessHistory("COMMENTS","keysort","F1", "!Image: $_") && next; /^Cisco Secure PIX /i && ProcessHistory("COMMENTS","keysort","F1", "!Image: $_") && next; # ASA "time-based licenses" - eg: bot-net /^This (PIX|platform) has a time-based license that will expire in\s+(\d{2,})\s+day.*$/ && ProcessHistory("COMMENTS","keysort","D1", "!This $1 has a time-based license\n") && next; # PIX 6 fail-over license, as in "This PIX has an Unrestricted (UR) # license." PIX 7 as "his platform has ..." /^This (PIX|platform) has an?\s+(.*)$/ && ProcessHistory("COMMENTS","keysort","D1", "!$_") && next; /^(Cisco )?IOS .* Software,? \(([A-Za-z0-9_-]*)\), .*Version\s+(.*)$/ && ProcessHistory("COMMENTS","keysort","F1", "!Image:$slave Software: $2, $3\n") && next; /^([A-Za-z-0-9_]*) Synced to mainline version: (.*)$/ && ProcessHistory("COMMENTS","keysort","F2", "!Image:$slave $1 Synced to mainline version: $2\n") && next; /^Compiled (.*)$/ && ProcessHistory("COMMENTS","keysort","F3", "!Image:$slave Compiled: $1\n") && next; /^ROM: (IOS \S+ )?(System )?Bootstrap.*(Version.*)$/ && ProcessHistory("COMMENTS","keysort","G1", "!ROM Bootstrap: $3\n") && next; if (/^Hardware:\s+(.*), (.* RAM), CPU (.*)$/) { ProcessHistory("COMMENTS","keysort","A1", "!Chassis type: $1 - a PIX\n"); ProcessHistory("COMMENTS","keysort","A2", "!CPU: $3\n"); ProcessHistory("COMMENTS","keysort","B1", "!Memory: $2\n"); } /^serial number:\s+(.*)$/i && ProcessHistory("COMMENTS","keysort","C1", "!Serial Number: $1\n") && next; # More PIX stuff /^Encryption hardware device\s+:\s+(.*)/ && ProcessHistory("COMMENTS","keysort","A3", "!Encryption: $1\n") && next; /^running activation key\s*:\s+(.*)/i && ProcessHistory("COMMENTS","keysort","D2", "!Key: $1\n") && next; # Flash on the PIX or FWSM (FireWall Switch Module) /^Flash(\s+\S+)+ \@ 0x\S+,\s+(\S+)/ && ProcessHistory("COMMENTS","keysort","B2", "!Memory: Flash $2\n") && next; # CatOS 3500xl stuff /^system serial number\s*:\s+(.*)$/i && ProcessHistory("COMMENTS","keysort","C1", "!Serial Number: $1\n") && next; /^Model / && ProcessHistory("COMMENTS","keysort","C2", "!$_") && next; /^Motherboard / && ProcessHistory("COMMENTS","keysort","C3", "!$_") && next; /^Power supply / && ProcessHistory("COMMENTS","keysort","C4", "!$_") && next; /^Activation Key:\s+(.*)$/ && ProcessHistory("COMMENTS","keysort","C2", "!$_") && next; /^ROM: \d+ Bootstrap .*(Version.*)$/ && ProcessHistory("COMMENTS","keysort","G2", "!ROM Image: Bootstrap $1\n!\n") && next; /^ROM: .*(Version.*)$/ && ProcessHistory("COMMENTS","keysort","G3","!ROM Image: $1\n") && next; /^BOOTFLASH: .*(Version.*)$/ && ProcessHistory("COMMENTS","keysort","G4","!BOOTFLASH: $1\n") && next; /^BOOTLDR: .*(Version.*)$/ && ProcessHistory("COMMENTS","keysort","G4","!BOOTLDR: $1\n") && next; /^System image file is "([^\"]*)", booted via (\S*)/ && # removed the booted source due to # CSCdk28131: cycling info in 'sh ver' # ProcessHistory("COMMENTS","keysort","F4","!Image: booted via $2, $1\n") && ProcessHistory("COMMENTS","keysort","F4","!Image: booted $1\n") && next; /^System image file is "([^\"]*)"$/ && ProcessHistory("COMMENTS","keysort","F5","!Image: $1\n") && next; if (/(\S+(?:\sseries)?)\s+(?:\((\S+)\)\s+processor|\(revision[^)]+\)).*\s+with (\S+k) bytes/i) { $proc = $1; my($cpu) = $2; my($mem) = $3; my($device) = "router"; # the next line ought to be the more specific cpu info, grab it. # yet, some boards/IOS vers have a processor ID line between these # two. grrr. make sure we dont grab the "software" junk that # follows these lines by looking for "CPU at " or the 2600s # "processor: " unique string. there are undoubtedly many other # incantations. for a slave, we dont get this info, its just a # blank line. $_ = ; if (/processor board id/i) { my($sn); if (/processor board id (\S+)/i) { $sn = $1; $sn =~ s/,$//; ProcessHistory("COMMENTS","keysort","D9", "!Processor ID: $sn\n"); } $_ = ; } $_ = "" if (! /(cpu at |processor: |$cpu processor,)/i); tr/\015//d; s/implementation/impl/i; if ($_ !~ /^\s*$/) { chomp; s/^/, /; } if ($proc eq "CSC") { $type = "AGS"; } elsif ($proc eq "CSC4") { $type = "AGS+"; } elsif ($proc =~ /1900/) { $type = "1900"; $device = "switch"; } elsif ($proc =~ /^(AS)?25[12][12]/) { $type = "2500"; } elsif ($proc =~ /261[01]/ || $proc =~ /262[01]/ ) { $type = "2600"; } elsif ($proc =~ /WS-C29/) { $type = "2900XL"; $device = "switch"; } elsif ($proc =~ /WS-C355/) { $type = "3550"; $device = "switch"; } elsif ($proc =~ /WS-C35/) { $type = "3500XL"; $device = "switch"; } elsif ($proc =~ /^36[0246][0-9]/) { $type = "3600"; } elsif ($proc =~ /^37/) { $type = "3700"; } elsif ($proc =~ /^38/) { $type = "3800"; } elsif ($proc =~ /WS-C45/) { $type = "4500"; $device = "switch"; } elsif ( $proc =~ /^AS5300/) { $type = "AS5300"; } elsif ( $proc =~ /^AS5350/) { $type = "AS5350"; } elsif ( $proc =~ /^AS5400/) { $type = "AS5400"; } elsif ($proc =~ /6000/) { $type = "6000"; $device = "switch"; } elsif ($proc eq "WK-C65") { $type = "6500"; } elsif ($proc eq "RP") { $type = "7000"; } elsif ($proc eq "RP1") { $type = "7000"; } elsif ($proc =~ /720[246]/) { $type = "7200"; } elsif ( $proc =~ /^73/) { $type = "7300"; } elsif ($proc eq "RSP7000") { $type = "7500"; } elsif ($proc =~ /RSP\d/) { $type = "7500"; } elsif ($proc =~ /OSR-76/) { $type = "7600"; } elsif ($proc =~ /CISCO76/) { $type = "7600"; } elsif ($proc =~ /1200[48]\/(GRP|PRP)/ || $proc =~ /1201[26]\/(GRP|PRP)/) { $type = "12000"; } elsif ($proc =~ /1201[26]-8R\/(GRP|PRP)/) { $type = "12000"; } elsif ($proc =~ /1240[48]\/(GRP|PRP)/ || $proc =~ /1241[06]\/(GRP|PRP)/) { $type = "12400"; } else { $type = $proc; } print STDERR "TYPE = $type\n" if ($debug); ProcessHistory("COMMENTS","keysort","A1", "!Chassis type:$slave $proc - a $type $device\n"); ProcessHistory("COMMENTS","keysort","B1", "!Memory:$slave main $mem\n"); if (defined($cpu)) { ProcessHistory("COMMENTS","keysort","A3", "!CPU:$slave $cpu$_$slaveslot\n"); } next; } if (/(\S+) Silicon\s*Switch Processor/) { if (!defined($C0)) { $C0 = 1; ProcessHistory("COMMENTS","keysort","C0","!\n"); } ProcessHistory("COMMENTS","keysort","C2","!SSP: $1\n"); $ssp = 1; $sspmem = $1; next; } /^(\d+[kK]) bytes of multibus/ && ProcessHistory("COMMENTS","keysort","B2", "!Memory: multibus $1\n") && next; /^(\d+[kK]) bytes of (non-volatile|NVRAM)/ && ProcessHistory("COMMENTS","keysort","B3", "!Memory: nvram $1\n") && next; /^(\d+[kK]) bytes of (flash memory|processor board System flash|ATA Comp actFlash)/ && ProcessHistory("COMMENTS","keysort","B5","!Memory: flash $1\n") && next; /^(\d+[kK]) bytes of .*flash partition/ && ProcessHistory("COMMENTS","keysort","B6", "!Memory: flash partition $1\n") && next; /^(\d+[kK]) bytes of Flash internal/ && ProcessHistory("COMMENTS","keysort","B4", "!Memory: bootflash $1\n") && next; if (/^(\d+[kK]) bytes of (Flash|ATA)?.*PCMCIA .*(slot|disk) ?(\d)/i) { ProcessHistory("COMMENTS","keysort","B7", "!Memory: pcmcia $2 $3$4 $1\n"); next; } if (/^(\d+[kK]) bytes of (slot|disk)(\d)/i) { ProcessHistory("COMMENTS","keysort","B7", "!Memory: pcmcia $2$3 $1\n"); next; } if (/^WARNING/) { if (!defined($I0)) { $I0 = 1; ProcessHistory("COMMENTS","keysort","I0","!\n"); } ProcessHistory("COMMENTS","keysort","I1","! $_"); } if (/^Configuration register is (.*)$/) { $config_register = $1; next; } if (/^Configuration register on node \S+ is (.*)$/) { $config_register = $1 if (length($config_register) < 1); next; } } return(0); } # This routine parses "show redundancy" sub ShowRedundancy { print STDERR " In ShowRedundancy: $_" if ($debug); while () { tr/\015//d; last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); return(1) if (/Line has invalid autocommand /); return(1) if (/(Invalid (input|command) detected|Type help or )/i); # the pager can not be disabled per-session on the PIX if (/^(<-+ More -+>)/) { my($len) = length($1); s/^$1\s{$len}//; } if (/^Version information for secondary in slot (\d+):/) { $slave = " Slave:"; $slaveslot = ", slot $1"; next; } /^IOS .* Software \(([A-Za-z0-9_-]*)\), .*Version\s+(.*)$/ && ProcessHistory("COMMENTS","keysort","F1", "!Image:$slave Software: $1, $2\n") && next; /^Compiled (.*)$/ && ProcessHistory("COMMENTS","keysort","F3", "!Image:$slave Compiled: $1\n") && next; } return(0); } # This routine parses "show IDprom" sub ShowIDprom { my($tmp); print STDERR " In ShowIDprom: $_" if ($debug); while () { tr/\015//d; last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); return(1) if (/Line has invalid autocommand /); return(1) if (/(Invalid (input|command) detected|Type help or )/i); # the pager can not be disabled per-session on the PIX if (/^(<-+ More -+>)/) { my($len) = length($1); s/^$1\s{$len}//; } /FRU is .(.*)\'/ && ($tmp = $1); /Product Number = .(.*)\'/ && ProcessHistory("COMMENTS","keysort","D0", "!Catalyst Chassis type: $1, $tmp\n"); /Serial Number = .([0-9A-Za-z]+)/ && ProcessHistory("COMMENTS","keysort","D1", "!Catalyst Chassis S/N: $1\n"); /Manufacturing Assembly Number = .([-0-9]+)/ && ($tmp = $1); /Manufacturing Assembly Revision = .(.*)\'/ && ($tmp .= ", rev " . $1); /Hardware Revision = ([0-9.]+)/ && ProcessHistory("COMMENTS","keysort","D2", "!Catalyst Chassis assembly: $tmp, ver $1\n"); } return(0); } # This routine parses "show install active" sub ShowInstallActive { print STDERR " In ShowInstallActive: $_" if ($debug); while () { tr/\015//d; last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); return(1) if (/^\s*\^\s*$/); return(1) if (/Line has invalid autocommand /); return(1) if (/(Invalid (input|command) detected|Type help or )/i); return(-1) if (/command authorization failed/i); # the pager can not be disabled per-session on the PIX if (/^(<-+ More -+>)/) { my($len) = length($1); s/^$1\s{$len}//; } ProcessHistory("COMMENTS","keysort","F5","!Image: $_") && next; } return(0); } # This routine parses "show env all" sub ShowEnv { # Skip if this is not a 7500, 7200, or 7000. print STDERR " In ShowEnv: $_" if ($debug); while () { tr/\015//d; if (/^$prompt/) { $found_env = 1; last}; next if (/^(\s*|\s*$cmd\s*)$/); #return(1) if ($type !~ /^7/); return(1) if (/Line has invalid autocommand /); return(1) if (/(Invalid (input|command) detected|Type help or )/i); return(0) if ($found_env); # Only do this routine once return(-1) if (/command authorization failed/i); # the pager can not be disabled per-session on the PIX if (/^(<-+ More -+>)/) { my($len) = length($1); s/^$1\s{$len}//; } if (!defined($E0)) { $E0 = 1; ProcessHistory("COMMENTS","keysort","E0","!\n"); } if (/^Arbiter type (\d), backplane type (\S+)/) { if (!defined($C0)) { $C0 = 1; ProcessHistory("COMMENTS","keysort","C0","!\n"); } ProcessHistory("COMMENTS","keysort","C1", "!Enviromental Arbiter Type: $1\n"); ProcessHistory("COMMENTS","keysort","A2", "!Chassis type: $2 backplane\n"); next; } /^Power Supply Information$/ && next; /^\s*Power Module\s+Voltage\s+Current$/ && next; /^\s*(Power [^:\n]+)$/ && ProcessHistory("COMMENTS","keysort","E1","!Power: $1\n") && next; /^\s*(Lower Power .*)/i && ProcessHistory("COMMENTS","keysort","E2","!Power: $1\n") && next; /^\s*(redundant .*)/i && ProcessHistory("COMMENTS","keysort","E2","!Power: $1\n") && next; /^\s*(RPS is .*)/i && ProcessHistory("COMMENTS","keysort","E2","!Power: $1\n") && next; } ProcessHistory("COMMENTS","","","!\n"); return(0); } # This routine parses "show rsp chassis-info" for the rsp # This will create arrays for hw info. sub ShowRSP { print STDERR " In ShowRSP: $_" if ($debug); while () { tr/\015//d; last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); return(1) if (/(Invalid (input|command) detected|Type help or )/i); return(-1) if (/command authorization failed/i); # return(1) if ($type !~ /^12[40]/); # the pager can not be disabled per-session on the PIX if (/^(<-+ More -+>)/) { my($len) = length($1); s/^$1\s{$len}//; } /^$/ && next; /^\s+Chassis model: (\S+)/ && ProcessHistory("COMMENTS","keysort","D1", "!RSP Chassis model: $1\n") && next; /^\s+Chassis S\/N: (.*)$/ && ProcessHistory("COMMENTS","keysort","D2", "!RSP Chassis S/N: $1\n") && next; } return(0); } # This routine parses "show gsr chassis-info" for the gsr # This will create arrays for hw info. sub ShowGSR { # Skip if this is not a 1200n. print STDERR " In ShowGSR: $_" if ($debug); while () { tr/\015//d; last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); return(1) if (/(Invalid (input|command) detected|Type help or )/i); return(-1) if (/command authorization failed/i); # return(1) if ($type !~ /^12[40]/); # the pager can not be disabled per-session on the PIX if (/^(<-+ More -+>)/) { my($len) = length($1); s/^$1\s{$len}//; } /^$/ && next; /^\s+Chassis: type (\S+) Fab Ver: (\S+)/ && ProcessHistory("COMMENTS","keysort","D1", "!GSR Chassis type: $1 Fab Ver: $2\n") && next; /^\s+Chassis S\/N: (.*)$/ && ProcessHistory("COMMENTS","keysort","D2", "!GSR Chassis S/N: $1\n") && next; /^\s+PCA: (\S+)\s*rev: (\S+)\s*dev: \S+\s*HW ver: (\S+)$/ && ProcessHistory("COMMENTS","keysort","D3", "!GSR Backplane PCA: $1, rev $2, ver $3\n") && next; /^\s+Backplane S\/N: (\S+)$/ && ProcessHistory("COMMENTS","keysort","D4", "!GSR Backplane S/N: $1\n") && next; } ProcessHistory("COMMENTS","","","!\n"); return(0); } # This routine parses "show boot" sub ShowBoot { # Pick up boot variables if 7000/7200/7500/12000/2900/3500; # otherwise pick up bootflash. print STDERR " In ShowBoot: $_" if ($debug); while () { tr/\015//d; last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); return(1) if (/^\s*\^\s*$/); return(1) if (/Line has invalid autocommand /); return(1) if (/(Invalid (input|command) detected|Type help or )/i); return(1) if (/Ambiguous command/i); return(1) if (/(Open device \S+ failed|Error opening \S+:)/); return(-1) if (/command authorization failed/i); # the pager can not be disabled per-session on the PIX if (/^(<-+ More -+>)/) { my($len) = length($1); s/^$1\s{$len}//; } 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: $_"); } else { ProcessHistory("COMMENTS","keysort","H1","!Variable: $_"); } } elsif (/(variable|register)/) { ProcessHistory("COMMENTS","keysort","H1","!Variable: $_"); } } ProcessHistory("COMMENTS","","","!\n"); return(0); } # This routine parses "show flash" sub ShowFlash { # skip if this is 7000, 7200, 7500, or 12000; else we end up with # redundant data from dir /all slot0: print STDERR " In ShowFlash: $_" if ($debug); while () { tr/\015//d; last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); return(1) if ($type =~ /^(12[40]|7)/); return(1) if ($ios eq "XE"); return(1) if (/^\s*\^\s*$/); return(1) if (/Line has invalid autocommand /); return(1) if (/(Invalid (input|command) detected|Type help or )/i); return(-1) if (/command authorization failed/i); # the pager can not be disabled per-session on the PIX if (/^(<-+ More -+>)/) { my($len) = length($1); s/^$1\s{$len}//; } # Filter dhcp database next if (/dhcp_[^. ]*\.txt/); /\s+(multiple-fs|nv_hdr|vlan\.dat)$/ && next; ProcessHistory("FLASH","","","!Flash: $_"); } ProcessHistory("","","","!\n"); return; } # This routine parses "dir /all ((disk|slot)N|bootflash|nvram):" sub DirSlotN { print STDERR " In DirSlotN: $_" if ($debug); my($dev) = (/\s([^\s]+):/); while () { tr/\015//d; last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); return(1) if /^\s*\^\s*$/; return(1) if (/Line has invalid autocommand /); return(1) if (/(Invalid (input|command) detected|Type help or )/i); return(1) if (/(No such device|Error Sending Request)/i); return(1) if (/\%Error: No such file or directory/); return(1) if (/No space information available/); # Corrupt flash /\%Error calling getdents / && ProcessHistory("FLASH","","","!Flash: $dev: $_") && next; return(-1) if (/\%Error calling/); return(-1) if (/(: device being squeezed|ATA_Status time out)/i); # busy return(-1) if (/\%Error opening \S+:\S+ \(Device or resource busy\)/i); return(-1) if (/command authorization failed/i); return(1) if (/(Open device \S+ failed|Error opening \S+:)/); # skip dir sup-bootflash if dir sup-bootdisk was successful, duplicates if ($cmd =~ / sup-bootdisk/) { $supbootdisk++; } elsif ($supbootdisk && $cmd =~ / sup-bootflash/) { return(0); } # filter frequently changing files from IOX bootflash if ($dev =~ /bootflash/) { next if (/temp_cont\s*$/); next if (/uptime_cont\s*$/); } # Filter dhcp database next if (/dhcp_[^. ]*\.txt/); if ($ios eq "XE" && /.*\((\d+) bytes free\)/) { my($tmp) = $1; if ($tmp >= (1024 * 1024 * 1024)) { $tmp = int($tmp / (1024 * 1024 * 1024)); s/$1 bytes free/$tmp GB free/; } else { $tmp = int($tmp / (1024 * 1024)); s/$1 bytes free/$tmp MB free/; } } if ($ios eq "XE" && /^((\s+)?\d+\s+\S+)\s+\d+.*(tracelogs$)/) { $_ = "$1" . sprintf("%43s", "") . "$3\n"; } if ($ios eq "IOS" && /^((\s+)?\d+\s+\S+)\s+\d+.*(sflog$)/) { $_ = "$1" . sprintf("%43s", "") . "$3\n"; } # the pager can not be disabled per-session on the PIX if (/^(<-+ More -+>)/) { my($len) = length($1); s/^$1\s{$len}//; } ProcessHistory("FLASH","","","!Flash: $dev: $_"); } ProcessHistory("","","","!\n"); return(0); } # This routine parses "show controllers" sub ShowContAll { # Skip if this is a 70[01]0, 7500, or 12000. print STDERR " In ShowContAll: $_" if ($debug); while () { tr/\015//d; last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); return(1) if (/(Invalid (input|command) detected|Type help or )/i); # return(1) if ($type =~ /^(12[40]|7[05])/); return(-1) if (/command authorization failed/i); # the pager can not be disabled per-session on the PIX if (/^(<-+ More -+>)/) { my($len) = length($1); s/^$1\s{$len}//; } if (/^Interface ([^ \n(]*)/) { $INT = "$1, "; next; } /^(BRI unit \d)/ && ProcessHistory("INT","","","!Interface: $1\n") && next; /^LANCE unit \d, NIM/ && ProcessHistory("INT","","","!Interface: $_") && next; /^(LANCE unit \d)/ && ProcessHistory("INT","","","!Interface: $1\n") && next; /(Media Type is \S+),/ && ProcessHistory("INT","","","!\t$1\n"); if (/(M\dT[^ :]*:) show controller:$/) { my($ctlr) = $1; $_ = ; tr/\015//d; s/ subunit \d,//; ProcessHistory("INT","","","!Interface: $ctlr $_"); } if (/^(\S+) : show controller:$/) { my($ctlr) = $1; $_ = ; tr/\015//d; s/ subunit \d,//; ProcessHistory("INT","","","!Interface: $ctlr: $_"); } /^(HD unit \d), idb/ && ProcessHistory("INT","","","!Interface: $1\n") && next; /^HD unit \d, NIM/ && ProcessHistory("INT","","","!Interface: $_") && next; /^buffer size \d+ HD unit \d, (.*)/ && ProcessHistory("INT","","","!\t$1\n") && next; /^AM79970 / && ProcessHistory("INT","","","!Interface: $_") && next; /^buffer size \d+ (Universal Serial: .*)/ && ProcessHistory("INT","","","!\t$1\n") && next; /^Hardware is (.*)/ && ProcessHistory("INT","","","!Interface: $INT$1\n") && next; /^(QUICC Serial unit \d),/ && ProcessHistory("INT","","","!$1\n") && next; /^QUICC Ethernet .*/ && ProcessHistory("INT","","","!$_") && next; /^DTE .*\.$/ && ProcessHistory("INT","","","!\t$_") && next; /^(cable type :.*),/ && ProcessHistory("INT","","","!\t$1\n") && next; /^(.* cable.*), received clockrate \d+$/ && ProcessHistory("INT","","","!\t$1\n") && next; /^.* cable.*$/ && ProcessHistory("INT","","","!\t$_") && next; } return(0); } # This routine parses "show controllers cbus" # Some of this is printed out in ShowDiagbus. sub ShowContCbus { # Skip if this is not a 7000 or 7500. print STDERR " In ShowContCbus: $_" if ($debug); while () { tr/\015//d; last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); return(1) if (/(Invalid (input|command) detected|Type help or )/i); #return(1) if ($type !~ /^7[05]0/); return(-1) if (/command authorization failed/i); # the pager can not be disabled per-session on the PIX if (/^(<-+ More -+>)/) { my($len) = length($1); s/^$1\s{$len}//; } if (/^\s*slot(\d+): ([^,]+), hw (\S+), sw (\S+), ccb/) { $slot = $1; $board{$slot} = $2; $hwver{$slot} = $3; $hwucode{$slot} = $4; } elsif (/^\s*(\S+) (\d+), hardware version (\S+), microcode version (\S+)/) { $slot = $2; $board{$slot} = $1; $hwver{$slot} = $3; $hwucode{$slot} = $4; } elsif (/(Microcode .*)/) { $ucode{$slot} = $1; } elsif (/(software loaded .*)/) { $ucode{$slot} = $1; } elsif (/(\d+) Kbytes of main memory, (\d+) Kbytes cache memory/) { $hwmemd{$slot} = $1; $hwmemc{$slot} = $2; } elsif (/byte buffers/) { chop; s/^\s*//; $hwbuf{$slot} = $_; } elsif (/Interface (\d+) - (\S+ \S+),/) { $interface = $1; ProcessHistory("HW","","", "!\n!Int $interface: in slot $slot, named $2\n"); next; } elsif (/(\d+) buffer RX queue threshold, (\d+) buffer TX queue limit, buffer size (\d+)/) { ProcessHistory("HW","","","!Int $interface: rxq $1, txq $2, bufsize $3\n"); next; } } return(0); } # This routine parses "show debug" sub ShowDebug { print STDERR " In ShowDebug: $_" if ($debug); my($lines) = 0; while () { tr/\015//d; last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); return(1) if (/Line has invalid autocommand /); return(1) if (/(Invalid (input|command) detected|Type help or )/i); return(-1) if (/command authorization failed/i); # the pager can not be disabled per-session on the PIX if (/^(<-+ More -+>)/) { my($len) = length($1); s/^$1\s{$len}//; } /^No matching debug flags set$/ && next; /^No debug flags set$/ && next; ProcessHistory("COMMENTS","keysort","J1","!DEBUG: $_"); $lines++; } if ($lines) { ProcessHistory("COMMENTS","keysort","J0","!\n"); } return(0); } # This routine parses "show diagbus" # This will create arrays for hw info. sub ShowDiagbus { # Skip if this is not a 7000, 70[01]0, or 7500. print STDERR " In ShowDiagbus: $_" if ($debug); while () { tr/\015//d; last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); #return(1) if ($type !~ /^7[05]/); return(1) if (/Line has invalid autocommand /); return(1) if (/(Invalid (input|command) detected|Type help or )/i); return(-1) if (/command authorization failed/i); # the pager can not be disabled per-session on the PIX if (/^(<-+ More -+>)/) { my($len) = length($1); s/^$1\s{$len}//; } if (/^\s*Slot (\d+):/i) { $slot = $1; next; } elsif (/^\s*Slot (\d+) \(virtual\):/i) { $slot = $1; next; } elsif (/^\s*(.*Processor.*|.*controller|.*controler|.*Chassis Interface)(, FRU\s?:.*)?, HW rev (\S+), board revision (\S+)/i) { $board = $1; $hwver = $3; $boardrev = $4; if ($board =~ /Processor/) { if ($board =~ /7000 Route\/Switch/) { $board = "RSP7000"; } elsif ($board =~ /Route\/Switch Processor (\d)/) { $board = "RSP$1"; } elsif ($board =~ /Route/) { $board = "RP"; } elsif ($board =~ /Silicon Switch/) { $board = "SSP"; } elsif ($board =~ /Switch/) { $board = "SP"; $board = "SSP $sspmem" if $ssp; } elsif ($board =~ /ATM/) { $board = "AIP"; } } elsif ($board =~ /(.*) controller/i) { $board = $1; } # hwucode{$slot} defined in ShowContCbus if (defined $hwucode{$slot}) { ProcessHistory("SLOT","","","!\n!Slot $slot/$board: hvers $hwver rev $boardrev ucode $hwucode{$slot}\n"); } else { ProcessHistory("SLOT","","","!\n!Slot $slot/$board: hvers $hwver rev $boardrev\n"); } # These are also from the ShowContCbus ProcessHistory("SLOT","","","!Slot $slot/$board: $ucode{$slot}\n") if (defined $ucode{$slot}); ProcessHistory("SLOT","","","!Slot $slot/$board: memd $hwmemd{$slot}, cache $hwmemc{$slot}\n") if ((defined $hwmemd{$slot}) && (defined $hwmemc{$slot})); ProcessHistory("SLOT","","","!Slot $slot/$board: $hwbuf{$slot}\n") if (defined $hwbuf{$slot}); next; } /Serial number: (\S+)\s*Part number: (\S+)/ && ProcessHistory("SLOT","","", "!Slot $slot/$board: part $2, serial $1\n") && next; /^\s*Controller Memory Size: (.*)$/ && ProcessHistory("SLOT","","","!Slot $slot/$board: $1\n") && next; if (/PA Bay (\d) Information/) { $pano = $1; if ("PA" =~ /$board/) { ($s,$c) = split(/\//,$board); $board = "$s/$c/PA $pano"; } else { $board =~ s/\/PA \d//; $board = "$board/PA $pano"; } next; } /\s+(.*) (IP|PA), (\d) ports?,( \S+,)? (FRU\s?: )?(\S+)/ && ProcessHistory("SLOT","","","!Slot $slot/$board: type $6, $3 ports\n") && next; /\s+(.*) (IP|PA)( \(\S+\))?, (\d) ports?/ && ProcessHistory("SLOT","","","!Slot $slot/$board: type $1$3, $4 ports\n") && next; /^\s*HW rev (\S+), Board revision (\S+)/ && ProcessHistory("SLOT","","","!Slot $slot/$board: hvers $1 rev $2\n") && next; /Serial number: (\S+)\s*Part number: (\S+)/ && ProcessHistory("SLOT","","","!Slot $slot/$board: part $2, serial $1\n") && next; } return(0); } # This routine parses "show diag" for the gsr, 7200, 3700, 3600, 2600. # This will create arrays for hw info. sub ShowDiag { print STDERR " In ShowDiag: $_" if ($debug); while () { REDUX: tr/\015//d; if (/^$prompt/) { $found_diag = 1; last}; next if (/^(\s*|\s*$cmd\s*)$/); return(1) if (/Line has invalid autocommand /); return(1) if (/(Invalid (input|command) detected|Type help or )/i); return(0) if ($found_diag); # Only do this routine once return(-1) if (/command authorization failed/i); /^$/ && next; # the pager can not be disabled per-session on the PIX if (/^(<-+ More -+>)/) { my($len) = length($1); s/^$1\s{$len}//; } s/Port Packet Over SONET/POS/; if (/^\s*SLOT\s+(\d+)\s+\((.*)\): (.*)/) { $slot = $1; ProcessHistory("SLOT","","","!\n"); ProcessHistory("SLOT","keysort","A","!Slot $slot: $3\n"); next; } if (/^\s*NODE\s+(\S+) : (.*)/) { $slot = $1; ProcessHistory("SLOT","","","!\n"); ProcessHistory("SLOT","keysort","A","!Slot $slot: $2\n"); next; } if (/^\s*PLIM\s+(\S+) : (.*)/) { $slot = $1 . " PLIM"; ProcessHistory("SLOT","","","!\n"); ProcessHistory("SLOT","keysort","A","!Slot $slot: $2\n"); next; } if (/^\s*RACK\s+(\S+) : (.*)/) { $slot = "Rack/" . $1; ProcessHistory("SLOT","","","!\n"); ProcessHistory("SLOT","keysort","A","!Slot $slot: $2\n"); next; } if (/^\s+MAIN:\s* type \S+,\s+(.*)/) { local($part) = $1; $_ = ; if (/^\s+(HW version|Design Release) (\S+)\s+S\/N (\S+)/i) { ProcessHistory("SLOT","keysort","AM","!Slot $slot/MAIN: part $part, serial $3\n"); ProcessHistory("SLOT","keysort","AM","!Slot $slot/MAIN: hvers $2\n"); } else { ProcessHistory("SLOT","keysort","AM","!Slot $slot/MAIN: part $part\n"); goto REDUX; } next; } if (/^\s+MAIN:\s* board type \S+$/) { $_ = ; tr/\015//d; if (/^\s+(.+)$/) { local($part) = $1; $_ = ; tr/\015//d; if (/^\s+dev (.*)$/) { local($dev) = $1; $_ = ; if (/^\s+S\/N (\S+)/) { ProcessHistory("SLOT","keysort","AM","!Slot $slot/MAIN: part $part, dev $dev, serial $1\n"); } else { ProcessHistory("SLOT","keysort","AM","!Slot $slot/MAIN: part $part, dev $dev\n"); goto REDUX; } } else { ProcessHistory("SLOT","keysort","AM","!Slot $slot/MAIN: part $part\n"); goto REDUX; } } else { goto REDUX; } next; } if (/^c3700\s+(io-board|mid-plane)/i) { $slot = $1; ProcessHistory("SLOT","","","!\n"); ProcessHistory("SLOT","keysort","A","!Slot $slot: part $1\n"); next; } if (/ Engine:\s+(.*)/) { ProcessHistory("SLOT","keysort","AE","!Slot $slot/Engine: $1\n"); } if (/FRU:\s+Linecard\/Module:\s+(\S+)/) { ProcessHistory("SLOT","keysort","AF","!Slot $slot/FRU: Linecard/Module: $1\n"); next; } if (/\s+Processor Memory:\s+(\S+)/) { ProcessHistory("SLOT","keysort","AF","!Slot $slot/FRU: Processor Memory: $1\n"); next; } if (/\s+Packet Memory:\s+(\S+)/) { ProcessHistory("SLOT","keysort","AF","!Slot $slot/FRU: Packet Memory: $1\n"); next; } if (/\s+Route Memory:\s+(\S+)/) { ProcessHistory("SLOT","keysort","AF","!Slot $slot/FRU: Route Memory: $1\n"); next; } if (/^\s+PCA:\s+(.*)/) { local($part) = $1; $_ = ; if (/^\s+(HW version|design release) (\S+)\s+S\/N (\S+)/i) { ProcessHistory("SLOT","keysort","C1","!Slot $slot/PCA: part $part, serial $3\n"); ProcessHistory("SLOT","keysort","C2","!Slot $slot/PCA: hvers $2\n"); } else { ProcessHistory("SLOT","keysort","C1","!Slot $slot/PCA: part $part\n"); goto REDUX; } next; } if (/^\s+MBUS: .*\)\s+(.*)/) { local($tmp) = "!Slot $slot/MBUS: part $1"; $_ = ; /^\s+HW version (\S+)\s+S\/N (\S+)/ && ProcessHistory("SLOT","keysort","MB1","$tmp, serial $2\n") && ProcessHistory("SLOT","keysort","MB2","!Slot $slot/MBUS: hvers $1\n"); next; } if (/^\s+MBUS Agent Software version (.*)/) { ProcessHistory("SLOT","keysort","MB3","!Slot $slot/MBUS: software $1\n"); next; } if (/^\s+PLD: (.*)/) { ProcessHistory("SLOT","keysort","P","!Slot $slot/PLD: $1\n"); next; } if (/^\s+MONLIB: (.*)/) { ProcessHistory("SLOT","keysort","Q","!Slot $slot/MONLIB: $1\n"); next; } if (/^\s+ROM Monitor version (.*)/) { ProcessHistory("SLOT","keysort","R","!Slot $slot/ROM Monitor: version $1\n"); next; } if (/^\s+ROMMON: Version (.*)/) { ProcessHistory("SLOT","keysort","R","!Slot $slot/ROMMON: version $1\n"); next; } if (/^\s+Fabric Downloader version used (.*)/) { ProcessHistory("SLOT","keysort","Z","!Slot $slot/Fabric Downloader: version $1\n"); next; } if (/^\s+DRAM size: (\d+)/) { local($dram) = $1 / 1048576; $_ = ; if (/^\s+FrFab SDRAM size: (\d+)/) { ProcessHistory("SLOT","keysort","MB4","!Slot $slot/MBUS: $dram Mbytes DRAM, " . $1 / 1024 . " Kbytes SDRAM\n"); } else { ProcessHistory("SLOT","keysort","MB4","!Slot $slot/MBUS: $dram Mbytes DRAM\n"); goto REDUX; } next; } # 7200, 3600, 2600, and 1700 stuff if (/^(Slot)\s+(\d+(\/\d+)?):/ || /^\s+(WIC|VIC|WIC\/VIC) Slot (\d):/ || /^(Encryption AIM) (\d):/) { if ($1 eq "WIC") { $WIC = "/$2"; } elsif ($1 eq "VIC") { $WIC = "/$2"; } elsif ($1 eq "WIC/VIC") { $WIC = "/$2"; } elsif ($1 eq "DSP") { $WIC = "/$2"; } elsif ($1 eq "Encryption AIM") { $slot = "$2"; undef($WIC); ProcessHistory("SLOT","","","!\n"); ProcessHistory("SLOT","keysort","B","!Slot $slot: type $1\n"); next; } else { $slot = $2; undef($WIC); } $_ = ; tr/\015//d; # clean up hideous 7200/etc formats to look more like 7500 output s/Fast-ethernet on C7200 I\/O card/FE-IO/; s/ with MII or RJ45/-TX/; s/Fast-ethernet /100Base/; s/[)(]//g; s/intermediate reach/IR/i; ProcessHistory("SLOT","","","!\n"); /\s+(.*) port adapter,?\s+(\d+)\s+/i && ProcessHistory("SLOT","keysort","B", "!Slot $slot: type $1, $2 ports\n") && next; # I/O controller with no interfaces /\s+(.*)\s+port adapter\s*$/i && ProcessHistory("SLOT","keysort","B", "!Slot $slot: type $1, 0 ports\n") && next; /\s+(.*)\s+daughter card(.*)$/ && ProcessHistory("SLOT","keysort","B", "!Slot $slot$WIC: type $1$2\n") && next; /\s+(FT1)$/ && ProcessHistory("SLOT","keysort","B", "!Slot $slot$WIC: type $1\n") && next; # AS5300/5400 handling /^Hardware is\s+(.*)$/i && ProcessHistory("SLOT","keysort","B","!Slot $slot: type $1\n") && next; /^DFC type is\s+(.*)$/i && ProcessHistory("SLOT","keysort","B","!Slot $slot: type $1\n") && next; # # handle WICs lacking "daughter card" in the 2nd line of their # show diag o/p if (defined($WIC)) { s/^\s+//; ProcessHistory("SLOT","keysort","B","!Slot $slot$WIC: type $_"); } next; } elsif (/^\s+(.* (DSP) Module) Slot (\d):/) { # The 1760 (at least) has yet another format...where it has two # dedicated DSP slots, and thus two slot 0s. my($TYPE) = $1; $WIC = "/$3"; ProcessHistory("SLOT","","","!\n"); ProcessHistory("SLOT","keysort","B", "!Slot $slot$WIC: type $TYPE\n"); next; } # yet another format. seen on 2600s w/ 12.1, but appears to be all # 12.1, including 7200s & 3700s. Sometimes the PCB serial appears # before the hardware revision. if (/(pcb serial number|hardware revision)\s+:\s+(\S+)$/i) { my($hw, $pn, $rev, $sn); if ($1 =~ /^pcb/i) { $sn = $2; } else { $hw = $2; } while () { tr/\015//d; # Sometimes "show diag" just ends while we are # trying to process this pcb stuff. Check for a # prompt so we can get out. if (/^$prompt/) { $found_diag=1; goto PerlSucks; } if (/0x..: / || /^$/) { # no effing idea why break does not work there goto PerlSucks; } if (/hardware revision\s+:\s+(\S+)/i) { $hw = $1; } if (/part number\s+:\s+(\S+)/i) { $pn = $1; } if (/board revision\s+:\s+(\S+)/i) { $rev = $1; } if (/pcb serial number\s+:\s+(\S+)/i) { $sn = $1; } # fru/pid bits, true Cisco evolving "standard", hopefully # "show inventory" will be "the way" soon. # if (/product \(fru\) number\s+:\s+(\S+)/i) { $fn = $1; } if (/product number\s+:\s+(\S+)/i) { $fn = $1; } if (/product\s+identifier\s+\(PID\)\s+:\s+(\S+)/i) { $fn = $1; } if (/fru\s+part\s+number\s+(\S+)/i) { $fn = $1; } } PerlSucks: # fru/pid bits ProcessHistory("SLOT","keysort","AG","!Slot $slot$WIC: fru $fn\n"); # ProcessHistory("SLOT","keysort","B","!Slot $slot$WIC: hvers $hw rev $rev\n"); ProcessHistory("SLOT","keysort","C","!Slot $slot$WIC: part $pn, serial $sn\n"); # If we saw the prompt, then we are done. last if $found_diag; } /revision\s+(\S+).*revision\s+(\S+)/ && ProcessHistory("SLOT","keysort","C","!Slot $slot$WIC: hvers $1 rev $2\n") && next; /number\s+(\S+)\s+Part number\s+(\S+)/ && ProcessHistory("SLOT","keysort","D","!Slot $slot$WIC: part $2, serial $1\n") && next; # AS5x00 bits /^\ Board Revision\s+(\S+),\s+Serial Number\s+(\S+),/ && ProcessHistory("SLOT","keysort","D", "!Slot $slot$WIC: rev $1, serial $2\n") && next; /^\ Board Hardware Version\s+(\S+),\s+Item Number\s+(\S+),/ && ProcessHistory("SLOT","keysort","D", "!Slot $slot$WIC: hvers $1, part $2\n") && next; /^Motherboard Info:/ && ProcessHistory("SLOT","keysort","D", "!Slot $slot$WIC: Motherboard\n") && next; # } ProcessHistory("SLOT","","","!\n"); return(0); } # This routine parses "show inventory". sub ShowInventory { print STDERR " In ShowInventory: $_" if ($debug); while () { tr/\015//d; return if (/^\s*\^$/); last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); return(1) if (/Line has invalid autocommand /); return(1) if (/(Invalid (input|command) detected|Type help or )/i); return(-1) if (/command authorization failed/i); # the pager can not be disabled per-session on the PIX if (/^(<-+ More -+>)/) { my($len) = length($1); s/^$1\s{$len}//; } if (/^(NAME: "[^"]*",) (DESCR: "[^"]+")/) { ProcessHistory("INVENTORY","","", sprintf("!%-30s %s\n", $1, $2)); next; } # split PID/VID/SN line if (/^PID: (\S*)\s*,\s*VID: (\S*)\s*,\s*SN: (\S*)\s*$/) { my($pid,$vid,$sn) = ($1, $2, $3); my($entries) = ""; # filter , "0x" and "N/A" lines if ($pid !~ /^(|0x|N\/A)$/) { $entries .= "!PID: $pid\n"; } if ($vid !~ /^(|0x|N\/A)$/) { $entries .= "!VID: $vid\n"; } if ($sn !~ /^(|0x|N\/A)$/) { $entries .= "!SN: $sn\n"; } ProcessHistory("INVENTORY","","", "$entries"); next; } ProcessHistory("INVENTORY","","","!$_"); } ProcessHistory("INVENTORY","","","!\n"); return(0); } # This routine parses "show module". sub ShowModule { print STDERR " In ShowModule: $_" if ($debug); my(@lines); my($slot, $pa); while () { tr/\015//d; return if (/^\s*\^$/); last if (/online diag status/i); last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); return(-1) if (/command authorization failed/i); # the pager can not be disabled per-session on the PIX if (/^(<-+ More -+>)/) { my($len) = length($1); s/^$1\s{$len}//; } # match slot/card info line if (/^ *(\d+)\s+(\d+)\s+(.*)\s+(\S+)\s+(\S+)\s*$/) { $lines[$1 * 1000] .= "!Slot $1: type $3, $2 ports\n!Slot $1: part $4, serial $5\n"; $lines[$1 * 1000] =~ s/\s+,/,/g; next; } # now match the Revs in the second paragraph of o/p and stick it in # the array with the previous bits...grumble. if (/^ *(\d+)\s+\S+\s+to\s+\S+\s+(\S+)\s+(\S*)\s+(\S+)(\s+\S+)?\s*$/) { $lines[$1 * 1000] .= "!Slot $1: hvers $2, firmware $3, sw $4\n"; $lines[$1 * 1000] =~ s/\s+,/,/g; next; } # grab the sub-modules, if any if (/^\s+(\d+)\s(.*)\s+(\S+)\s+(\S+)\s+(\S+)\s+\S+\s*$/) { my($idx); $pa = 0 if ($1 != $slot); $slot = $1; $idx = $1 * 1000 + $1 * 10 + $pa; $lines[$idx] .= "!Slot $1/$pa: type $2\n"; $lines[$idx] .= "!Slot $slot/$pa: part $3, serial $4\n"; $lines[$idx] .= "!Slot $slot/$pa: hvers $5\n"; $pa++; } } foreach $slot (@lines) { next if ($slot =~ /^\s*$/); ProcessHistory("Module","","","$slot!\n"); } return(0); } # This routine parses "show spe version". sub ShowSpeVersion { print STDERR " In ShowSpeVersion: $_" if ($debug); while () { tr/\015//d; last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); return(1) if /^\s*\^\s*$/; return(1) if (/Line has invalid autocommand /); return(1) if (/(Invalid (input|command) detected|Type help or )/i); return(-1) if (/command authorization failed/i); ProcessHistory("MODEM","","","!Modem: $_") && next; } ProcessHistory("MODEM","","","!\n"); return(0); } # This routine parses "show c7200" for the 7200 # This will create arrays for hw info. sub ShowC7200 { # Skip if this is not a 7200. print STDERR " In ShowC7200: $_" if ($debug); while () { tr/\015//d; last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); return(1) if (/(Invalid (input|command) detected|Type help or )/i); #return(1) if ($type !~ /^72/); return(-1) if (/command authorization failed/i); /^$/ && next; # the pager can not be disabled per-session on the PIX if (/^(<-+ More -+>)/) { my($len) = length($1); s/^$1\s{$len}//; } if (/^(C7200 )?Midplane EEPROM:/) { $_ = ; /revision\s+(\S+).*revision\s+(\S+)/; ProcessHistory("SLOT","","","!Slot Midplane: hvers $1 rev $2\n"); $_ = ; /number\s+(\S+)\s+Part number\s+(\S+)/; ProcessHistory("SLOT","","","!Slot Midplane: part $2, serial $1\n!\n"); next; } if (/C720\d(VXR)? CPU EEPROM:/) { my ($hvers,$rev,$part,$serial); # npe400s report their cpu eeprom info differently w/ 12.0.21S while () { /Hardware Revision\s+: (\S+)/ && ($hvers = $1) && next; /Board Revision\s+: (\S+)/ && ($rev = $1) && next; /Part Number\s+: (\S+)/ && ($part = $1) && next; /Serial Number\s+: (\S+)/ && ($serial = $1) && next; /revision\s+(\S+).*revision\s+(\S+)/ && ($hvers = $1, $rev = $2) && next; /number\s+(\S+)\s+Part number\s+(\S+)/ && ($serial = $1, $part = $2) && next; /^\s*$/ && last; } ProcessHistory("SLOT","","","!Slot CPU: hvers $hvers rev $rev\n"); ProcessHistory("SLOT","","","!Slot CPU: part $part, serial $serial\n!\n"); next; } } return(0); } # This routine parses "show capture". Intended for ASA/PIXes. sub ShowCapture { print STDERR " In ShowCapture: $_" if ($debug); my $capture_found = 0; while () { tr/\015//d; last if (/^$prompt/); return(1) if (/^(\s*|\s*$cmd\s*)$/); return(1) if /^\s*\^\s*$/; return(1) if (/Line has invalid autocommand /); return(1) if (/(Invalid (input|command) detected|Type help or )/i); return(-1) if (/command authorization failed/i); # the pager can not be disabled per-session on the PIX if (/^(<-+ More -+>)/) { my($len) = length($1); s/^$1\s{$len}//; } if (/capture (.*) type/) { my $cap_name = $1; s/\d+ bytes/ bytes/; ProcessHistory("CAPTURE","","","!Capture: $cap_name\n"); ProcessHistory("CAPTURE","","","!Capture: $_"); } else { ProcessHistory("CAPTURE","","","!Capture: $_"); } $capture_found = 1 } ProcessHistory("CAPTURE","","","!\n") if ($capture_found == 1); return(0); } # This routine parses "show vtp status" sub ShowVTP { print STDERR " In ShowVTP: $_" if ($debug); while () { tr/\015//d; last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); return(1) if /^\s*\^\s*$/; return(1) if (/Line has invalid autocommand /); return(1) if (/(Invalid (input|command) detected|Type help or )/i); #return(1) if ($type !~ /^(2900XL|3500XL|6000)$/); return(-1) if (/command authorization failed/i); next if (/^Configuration last modified by/); # the pager can not be disabled per-session on the PIX if (/^(<-+ More -+>)/) { my($len) = length($1); s/^$1\s{$len}//; } if (/^VTP Operating Mode\s+:\s+(Transparent|Server)/) { $DO_SHOW_VLAN = 1; } ProcessHistory("COMMENTS","keysort","I0","!VTP: $_"); } ProcessHistory("COMMENTS","keysort","I0","!\n"); return(0); } # This routine parses "show vlan" sub ShowVLAN { print STDERR " In ShowVLAN: $_" if ($debug); ($_ = , return(1)) if (!$DO_SHOW_VLAN); while () { tr/\015//d; last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); return(1) if /^\s*\^\s*$/; return(1) if (/Line has invalid autocommand /); return(1) if (/(Invalid (input|command) detected|Type help or )/i); return(1) if (/Ambiguous command/i); return(-1) if (/command authorization failed/i); # the pager can not be disabled per-session on the PIX if (/^(<-+ More -+>)/) { my($len) = length($1); s/^$1\s{$len}//; } ProcessHistory("COMMENTS","keysort","IO","!VLAN: $_"); } ProcessHistory("COMMENTS","keysort","IO","!\n"); return(0); } # This routine processes a "show shun". Intended for ASA/PIXes. sub ShowShun { print STDERR " In ShowShun: $_" if ($debug); my $shun_found = 0; while () { tr/\015//d; last if (/^$prompt/); return(1) if (/^(\s*|\s*$cmd\s*)$/); return(1) if /^\s*\^\s*$/; return(1) if (/Line has invalid autocommand /); return(1) if (/(Invalid (input|command) detected|Type help or )/i); return(-1) if (/command authorization failed/i); # the pager can not be disabled per-session on the PIX if (/^(<-+ More -+>)/) { my($len) = length($1); s/^$1\s{$len}//; } ProcessHistory("SHUN","","","!Shun: $_"); $shun_found = 1; } ProcessHistory("SHUN","","","!\n") if ($shun_found == 1); return(0); } # This routine processes a "write term" sub WriteTerm { print STDERR " In WriteTerm: $_" if ($debug); my($lineauto,$comment,$linecnt) = (0,0,0); while () { tr/\015//d; last if (/^$prompt/); return(1) if (!$linecnt && /^\s+\^\s*$/); next if (/^\s*$cmd\s*$/); return(1) if (/Line has invalid autocommand /); return(1) if (/(Invalid (input|command) detected|Type help or )/i); return(1) if (/\%Error: No such file or directory/); return(1) if (/(Open device \S+ failed|Error opening \S+:)/); return(0) if ($found_end); # Only do this routine once return(-1) if (/command authorization failed/i); return(-1) if (/% ?configuration buffer full/i); # the pager can not be disabled per-session on the PIX if (/^(<-+ More -+>)/) { my($len) = length($1); s/^$1\s{$len}//; } /^! no configuration change since last restart/i && next; # skip emtpy lines at the beginning if (!$linecnt && /^\s*$/) { next; } if (!$linecnt && defined($config_register)) { ProcessHistory("","","", "!\nconfig-register $config_register\n"); } /Non-Volatile memory is in use/ && return(-1); # NvRAM is locked /% Configuration buffer full, / && return(-1); # buffer is in use $linecnt++; $lineauto = 0 if (/^[^ ]/); # skip the crap if (/^(##+|(building|current) configuration)/i) { while () { next if (/^Current configuration\s*:/i); next if (/^:/); next if (/^([%!].*|\s*)$/); next if (/^ip add.*ipv4:/); # band-aid for 3620 12.0S last; } tr/\015//d; } # config timestamp on MDS/NX-OS /Time: / && next; # skip ASA 5520 configuration author line /^: written by /i && next; # some versions have other crap mixed in with the bits in the # block above /^! (Last configuration|NVRAM config last)/ && next; # and for the ASA /^: (Written by \S+ at|Saved)/ && next; # skip consecutive comment lines to avoid oscillating extra comment # line on some access servers. grrr. if (/^!\s*$/) { next if ($comment); ProcessHistory("","","",$_); $comment++; next; } $comment = 0; # 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 /^ clockrate / && next; # kill clockrate on serial interfaces if (/^(enable )?(password|passwd)( level \d+)? / && $filter_pwds >= 1) { ProcessHistory("ENABLE","","","!$1$2$3 \n"); next; } if (/^(enable secret) / && $filter_pwds >= 2) { ProcessHistory("ENABLE","","","!$1 \n"); next; } if (/^username (\S+)(\s.*)? secret /) { if ($filter_pwds >= 2) { ProcessHistory("USER","keysort","$1", "!username $1$2 secret \n"); } else { ProcessHistory("USER","keysort","$1","$_"); } next; } if (/^username (\S+)(\s.*)? password ((\d) \S+|\S+)/) { if ($filter_pwds >= 2) { ProcessHistory("USER","keysort","$1", "!username $1$2 password \n"); } elsif ($filter_pwds >= 1 && $4 ne "5"){ ProcessHistory("USER","keysort","$1", "!username $1$2 password \n"); } else { ProcessHistory("USER","keysort","$1","$_"); } next; } # cisco AP w/ IOS if (/^(wlccp \S+ username (\S+)(\s.*)? password) (\d \S+|\S+)/) { if ($filter_pwds >= 1) { ProcessHistory("USER","keysort","$2","!$1 \n"); } else { ProcessHistory("USER","keysort","$2","$_"); } next; } # filter auto "rogue ap" configuration lines /^rogue ap classify / && next; if (/^( set session-key (in|out)bound ah \d+ )/ && $filter_pwds >= 1) { ProcessHistory("","","","!$1\n"); next; } if (/^( set session-key (in|out)bound esp \d+ (authenticator|cypher) )/ && $filter_pwds >= 1) { ProcessHistory("","","","!$1\n"); next; } if (/^(\s*)password / && $filter_pwds >= 1) { ProcessHistory("LINE-PASS","","","!$1password \n"); next; } if (/^(\s*)secret / && $filter_pwds >= 2) { ProcessHistory("LINE-PASS","","","!$1secret \n"); next; } if (/^\s*neighbor (\S*) password / && $filter_pwds >= 1) { ProcessHistory("","","","! neighbor $1 password \n"); next; } if (/^(\s*ppp .* hostname) .*/ && $filter_pwds >= 1) { ProcessHistory("","","","!$1 \n"); next; } if (/^(\s*ppp .* password) \d .*/ && $filter_pwds >= 1) { ProcessHistory("","","","!$1 \n"); next; } if (/^(ip ftp password) / && $filter_pwds >= 1) { ProcessHistory("","","","!$1 \n"); next; } if (/^( ip ospf authentication-key) / && $filter_pwds >= 1) { ProcessHistory("","","","!$1 \n"); next; } # isis passwords appear to be completely plain-text if (/^\s+isis password (\S+)( .*)?/ && $filter_pwds >= 1) { ProcessHistory("","","","!isis password $2\n"); next; } if (/^\s+(domain-password|area-password) (\S+)( .*)?/ && $filter_pwds >= 1) { ProcessHistory("","","","!$1 $3\n"); next; } # this is reversable, despite 'md5' in the cmd if (/^( ip ospf message-digest-key \d+ md5) / && $filter_pwds >= 1) { ProcessHistory("","","","!$1 \n"); next; } # this is also reversable, despite 'md5 encrypted' in the cmd if (/^( message-digest-key \d+ md5 (7|encrypted)) / && $filter_pwds >= 1) { ProcessHistory("","","","!$1 \n"); next; } if (/^((crypto )?isakmp key) (\d )?\S+ / && $filter_pwds >= 1) { ProcessHistory("","","","!$1 $'"); next; } # filter HSRP passwords if (/^(\s+standby \d+ authentication) / && $filter_pwds >= 1) { ProcessHistory("","","","!$1 \n"); next; } # this appears in "measurement/sla" images if (/^(\s+key-string \d?)/ && $filter_pwds >= 1) { ProcessHistory("","","","!$1 \n"); next; } if (/^( l2tp tunnel \S+ password)/ && $filter_pwds >= 1) { ProcessHistory("","","","!$1 \n"); next; } # i am told these are plain-text on the PIX if (/^(vpdn username (\S+) password)/) { if ($filter_pwds >= 1) { ProcessHistory("USER","keysort","$2","!$1 \n"); } else { ProcessHistory("USER","keysort","$2","$_"); } next; } # ASA/PIX keys in more system:running-config if (/^( pre-shared-key | key |failover key ).*/ && $filter_pwds >= 1) { ProcessHistory("","","","!$1 $'"); next; } # ASA/PIX keys in more system:running-config if (/(\s+ldap-login-password )\S+(.*)/ && $filter_pwds >= 1) { ProcessHistory("","","","!$1 $'"); next; } # filter WPA password such as on cisco 877W ISR if (/^\s+(wpa-psk ascii|hex \d) / && $filter_pwds >= 1) { ProcessHistory("","","","!$1 \n"); next; } # if (/^( cable shared-secret )/ && $filter_pwds >= 1) { ProcessHistory("","","","!$1 \n"); next; } /fair-queue individual-limit/ && next; # sort ip explicit-paths. if (/^ip explicit-path name (\S+)/) { my($key) = $1; my($expath) = $_; while () { tr/\015//d; last if (/^$prompt/); last if (/^$prompt/ || ! /^(ip explicit-path name |[ !])/); if (/^ip explicit-path name (\S+)/) { ProcessHistory("EXPATH","keysort","$key","$expath"); $key = $1; $expath = $_; } else { $expath .= $_; } } ProcessHistory("EXPATH","keysort","$key","$expath"); } # sort route-maps if (/^route-map (\S+)/) { my($key) = $1; my($routemap) = $_; while () { tr/\015//d; last if (/^$prompt/ || ! /^(route-map |[ !])/); if (/^route-map (\S+)/) { ProcessHistory("ROUTEMAP","keysort","$key","$routemap"); $key = $1; $routemap = $_; } else { $routemap .= $_; } } ProcessHistory("ROUTEMAP","keysort","$key","$routemap"); } # filter out any RCS/CVS tags to avoid confusing local CVS storage s/\$(Revision|Id):/ $1:/; # order access-lists /^access-list\s+(\d\d?)\s+(\S+)\s+(\S+)/ && ProcessHistory("ACL $1 $2","$aclsort","$3","$_") && next; # order extended access-lists /^access-list\s+(\d\d\d)\s+(\S+)\s+ip\s+host\s+(\S+)/ && ProcessHistory("EACL $1 $2","$aclsort","$3","$_") && next; /^access-list\s+(\d\d\d)\s+(\S+)\s+ip\s+(\d\S+)/ && ProcessHistory("EACL $1 $2","$aclsort","$3","$_") && next; /^access-list\s+(\d\d\d)\s+(\S+)\s+ip\s+any/ && ProcessHistory("EACL $1 $2","$aclsort","0.0.0.0","$_") && next; # order arp lists /^arp\s+(\d+\.\d+\.\d+\.\d+)\s+/ && ProcessHistory("ARP","$aclsort","$1","$_") && next; /^ip(v6)? prefix-list\s+(\S+)\s+seq\s+(\d+)\s+(permit|deny)\s+(\S+)(\/.*)$/ && ProcessHistory("PACL $2 $4","$aclsort","$5", "ip$1 prefix-list $2 $4 $5$6\n") && next; # order logging statements /^logging (\d+\.\d+\.\d+\.\d+)/ && ProcessHistory("LOGGING","ipsort","$1","$_") && next; # order/prune snmp-server host statements # we only prune lines of the form # snmp-server host a.b.c.d if (/^snmp-server host (\d+\.\d+\.\d+\.\d+) /) { if ($filter_commstr) { my($ip) = $1; my($line) = "snmp-server host $ip"; my(@tokens) = split(' ', $'); my($token); while ($token = shift(@tokens)) { if ($token eq 'version') { $line .= " " . join(' ', ($token, shift(@tokens))); if ($token eq '3') { $line .= " " . join(' ', ($token, shift(@tokens))); } } elsif ($token eq 'vrf') { $line .= " " . join(' ', ($token, shift(@tokens))); } elsif ($token =~ /^(informs?|traps?|(no)?auth)$/) { $line .= " " . $token; } else { $line = "!$line " . join(' ', ("", join(' ',@tokens))); last; } } ProcessHistory("SNMPSERVERHOST","ipsort","$ip","$line\n"); } else { ProcessHistory("SNMPSERVERHOST","ipsort","$1","$_"); } next; } if (/^(snmp-server community) (\S+)/) { if ($filter_commstr) { ProcessHistory("SNMPSERVERCOMM","keysort","$_", "!$1 $'") && next; } else { ProcessHistory("SNMPSERVERCOMM","keysort","$_","$_") && next; } } # prune tacacs/radius server keys if (/^((tacacs|radius)-server\s(\w*[-\s(\s\S+])*\s?key) (\d )?\S+/ && $filter_pwds >= 1) { ProcessHistory("","","","!$1 $'"); next; } # order clns host statements /^clns host \S+ (\S+)/ && ProcessHistory("CLNS","keysort","$1","$_") && next; # order alias statements /^alias / && ProcessHistory("ALIAS","keysort","$_","$_") && next; # delete ntp auth password - this md5 is a reversable too if (/^(ntp authentication-key \d+ md5) / && $filter_pwds >= 1) { ProcessHistory("","","","!$1 \n"); next; } # order ntp peers/servers if (/^ntp (server|peer) (\d+)\.(\d+)\.(\d+)\.(\d+)/) { $sortkey = sprintf("$1 %03d%03d%03d%03d",$2,$3,$4,$5); ProcessHistory("NTP","keysort",$sortkey,"$_"); next; } # order ip host statements /^ip host (\S+) / && ProcessHistory("IPHOST","keysort","$1","$_") && next; # order ip nat source static statements /^ip nat (\S+) source static (\S+)/ && ProcessHistory("IP NAT $1","ipsort","$2","$_") && next; # order atm map-list statements /^\s+ip\s+(\d+\.\d+\.\d+\.\d+)\s+atm-vc/ && ProcessHistory("ATM map-list","ipsort","$1","$_") && next; # order ip rcmd lines /^ip rcmd/ && ProcessHistory("RCMD","keysort","$_","$_") && next; # system controller /^syscon address (\S*) (\S*)/ && ProcessHistory("","","","!syscon address $1 \n") && next; if (/^syscon password (\S*)/ && $filter_pwds >= 1) { ProcessHistory("","","","!syscon password \n"); next; } /^ *Cryptochecksum:/ && next; # catch anything that wasnt matched above. ProcessHistory("","","","$_"); # end of config. the ": " game is for the PIX if (/^(: +)?end$/) { $found_end = 1; return(0); } } # The ContentEngine lacks a definitive "end of config" marker. If we # know that it is a CE, SAN, or NXOS and we have seen at least 5 lines # of write term output, we can be reasonably sure that we got the config. if (($type == "CE" || $type == "SAN" || $type == "NXOS" ) && $linecnt > 5) { $found_end = 1; return(0); } return(0); } # dummy function sub DoNothing {print STDOUT;} # Main @commandtable = ( {'show version' => 'ShowVersion'}, {'show redundancy secondary' => 'ShowRedundancy'}, {'show idprom backplane', => 'ShowIDprom'}, {'show install active' => 'ShowInstallActive'}, {'show env all' => 'ShowEnv'}, {'show rsp chassis-info', => 'ShowRSP'}, {'show gsr chassis' => 'ShowGSR'}, {'show diag chassis-info' => 'ShowGSR'}, {'show boot' => 'ShowBoot'}, {'show bootvar' => 'ShowBoot'}, {'show variables boot' => 'ShowBoot'}, {'show flash' => 'ShowFlash'}, {'dir /all nvram:' => 'DirSlotN'}, {'dir /all bootflash:' => 'DirSlotN'}, {'dir /all slot0:' => 'DirSlotN'}, {'dir /all disk0:' => 'DirSlotN'}, {'dir /all slot1:' => 'DirSlotN'}, {'dir /all disk1:' => 'DirSlotN'}, {'dir /all slot2:' => 'DirSlotN'}, {'dir /all disk2:' => 'DirSlotN'}, {'dir /all harddisk:' => 'DirSlotN'}, {'dir /all harddiska:' => 'DirSlotN'}, {'dir /all harddiskb:' => 'DirSlotN'}, {'dir /all sup-bootdisk:' => 'DirSlotN'}, # 6500 sup32 {'dir /all sup-bootflash:' => 'DirSlotN'}, # cat 6500-ios {'dir /all sup-microcode:' => 'DirSlotN'}, # cat 6500-ios {'dir /all slavenvram:' => 'DirSlotN'}, {'dir /all slavebootflash:' => 'DirSlotN'}, {'dir /all slaveslot0:' => 'DirSlotN'}, {'dir /all slavedisk0:' => 'DirSlotN'}, {'dir /all slaveslot1:' => 'DirSlotN'}, {'dir /all slavedisk1:' => 'DirSlotN'}, {'dir /all slaveslot2:' => 'DirSlotN'}, {'dir /all slavedisk2:' => 'DirSlotN'}, {'dir /all slavesup-bootflash:' => 'DirSlotN'}, # cat 7609 {'dir /all sec-nvram:' => 'DirSlotN'}, {'dir /all sec-bootflash:' => 'DirSlotN'}, {'dir /all sec-slot0:' => 'DirSlotN'}, {'dir /all sec-disk0:' => 'DirSlotN'}, {'dir /all sec-slot1:' => 'DirSlotN'}, {'dir /all sec-disk1:' => 'DirSlotN'}, {'dir /all sec-slot2:' => 'DirSlotN'}, {'dir /all sec-disk2:' => 'DirSlotN'}, {'show controllers' => 'ShowContAll'}, {'show controllers cbus' => 'ShowContCbus'}, {'show diagbus' => 'ShowDiagbus'}, {'show diag' => 'ShowDiag'}, {'show capture' => 'ShowCapture'}, # ASA/PIX {'show module' => 'ShowModule'}, # cat 6500-ios {'show spe version' => 'ShowSpeVersion'}, {'show c7200' => 'ShowC7200'}, {'show inventory raw' => 'ShowInventory'}, {'show vtp status' => 'ShowVTP'}, {'show vlan' => 'ShowVLAN'}, {'show vlan-switch' => 'ShowVLAN'}, {'show debug' => 'ShowDebug'}, {'show shun' => 'ShowShun'}, # ASA/PIX {'more system:running-config' => 'WriteTerm'}, # ASA/PIX {'show running-config view full'=> 'WriteTerm'}, # workaround for # role-based CLI {'show running-config' => 'WriteTerm'}, {'write term' => 'WriteTerm'}, ); # 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("|", map quotemeta($_), @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 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 clogin -t $timeo -c\"$cisco_cmds\" $host\n" if ($debug); print STDOUT "executing clogin -t $timeo -c\"$cisco_cmds\" $host\n" if ($log); if (defined($ENV{NOPIPE}) && $ENV{NOPIPE} =~ /^YES/i) { system "clogin -t $timeo -c \"$cisco_cmds\" $host $host.raw 2>&1" || die "clogin failed for $host: $!\n"; open(INPUT, "< $host.raw") || die "clogin failed for $host: $!\n"; } else { open(INPUT,"clogin -t $timeo -c \"$cisco_cmds\" $host ) { tr/\015//d; if (/[>#]\s?exit$/) { $clean_run = 1; last; } if (/^Error:/) { print STDOUT ("$host clogin error: $_"); print STDERR ("$host clogin error: $_") if ($debug); $clean_run = 0; last; } while (/[>#]\s*($cmds_regexp)\s*$/) { $cmd = $1; 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; } $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}) && $ENV{NOPIPE} =~ /^YES/i) { 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); } rancid-2.3.8/bin/rivlogin.in100644 015615 000000 00000056602 11662541466 0011433#! @EXPECT_PATH@ -- ## ## $Id: rivlogin.in 2334 2011-11-17 21:09:37Z heas $ ## ## @PACKAGE@ @VERSION@ ## Copyright (c) @COPYYEARS@ by Terrapin Communications, Inc. ## All rights reserved. ## ## This code is derived from software contributed to and maintained by ## Terrapin Communications, Inc. by Henry Kilmer, John Heasley, Andrew Partan, ## Pete Whiting, Austin Schutz, and Andrew Fort. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions ## are met: ## 1. Redistributions of source code must retain the above copyright ## notice, this list of conditions and the following disclaimer. ## 2. Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## 3. All advertising materials mentioning features or use of this software ## must display the following acknowledgement: ## This product includes software developed by Terrapin Communications, ## Inc. and its contributors for RANCID. ## 4. Neither the name of Terrapin Communications, Inc. nor the names of its ## contributors may be used to endorse or promote products derived from ## this software without specific prior written permission. ## 5. It is requested that non-binding fixes and modifications be contributed ## back to Terrapin Communications, Inc. ## ## THIS SOFTWARE IS PROVIDED BY Terrapin Communications, INC. AND CONTRIBUTORS ## ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ## TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COMPANY OR CONTRIBUTORS ## BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ## CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ## SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ## INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ## CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ## ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ## POSSIBILITY OF SUCH DAMAGE. # # The expect login scripts were based on Erik Sherk's gwtn, by permission. # # rivlogin - Riverstone (and Enterasys SSR) login # # Based upon rscmd (see nmops.org) # rscmd - Riverstone Networks Automated login # by Mike MacFaden, Kiran Addepalli # Riverstone Networks, 2000 # # Returned to the RANCID crowd by andrew fort # Usage line set usage "Error: Usage: $argv0 \[-dV\] \[-noenable\] \ \[-f cloginrc-file\] \[-c command\] \[-Evar=x\] \[-s script-file\] \ \[-x command-file\] \[-t timeout\] \[-o output-file\] \ router \[router...\]\n" # program diagnostics set verbose 0 set success 1 set config 0 # in seconds to wait for data back from device set timeoutdflt 10 set tempfile "/tmp/rivlogin.[exec date]" # cli command prompt set my_prompt ">" set enable_prompt "\#" set default_user "" set output_file "" set conf_prompt "*\(config\)# " set logging 0 set config_mode 0 # Save config, if prompted set do_saveconfig 0 # Password file for routers to access set password_file $env(HOME)/.cloginrc # If no -c or -s specified, just automate router login ala rsh set do_command 0 set do_script 0 set log_user 0 # The default CLI mode to login to is "enable" mode set avenable 1 # 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 set do_enapasswd 1 # set send_human {.4 .4 .7 .3 5} # 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) } elseif {[ info exists env(LOGNAME) ]} { set default_user $env(LOGNAME) } 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 "\nError: could not exec id: $reason\n" exit 1 } regexp {\(([^)]*)} "$reason" junk default_user } if {[ info exists env(CLOGINRC) ]} { set password_file $env(CLOGINRC) } # Procedures Section # # 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 } } 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. # NOTES: 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 $var lappend $var $args } # 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 { } { global env password_file read_password_file if { [info exists read_password_file] } { return 1 } if { [info exists password_file] == 0 } { set password_file $env(HOME)/.cloginrc } set read_password_file 1 file stat $password_file fileinfo if { [expr ($fileinfo(mode) & 007)] != 0000 } { puts "ERROR: $password_file must not be group or world readable and writable\n" return 1 } source $password_file } # pre: var is x, router is y # post: return routerr entry from database else null string proc find { var router } { if {[ source_password_file ] == 0 } { return {} } upvar $var list if { [info exists list] } { foreach line $list { if { [string match [lindex $line 0] $router ] } { return [lrange $line 1 end] } } } return {} } # pre: login completed ok # post: terminate login session by closing tcp connection proc auto_exit { } { global telnet_id if { $verbose == 1 } { puts "DEBUG: auto_exit closing connection to pid $telnet_id\n" } close -i telnet_id } # perform login basic to a router # pre: args are valid, router is reachable via network # post: return 0 on successful login, else 1 # # NOTE: a number of globals are setup: my_prompt, telnet_id are key # and paging of cli output is disabled proc login { router user userpswd passwd enapasswd } { global login_array global telnet_id global expect_out global spawn_id global verbose global config verbose my_prompt if { $verbose == 1 } { puts "DEBUG: login router = $router" puts "DEBUG: login username = $user" puts "DEBUG: login userpasswd = $userpswd" puts "DEBUG: login passwd = $passwd" puts "DEBUG: login enapasswd = $enapasswd" } spawn -noecho telnet $router set telnet_id $spawn_id if { $telnet_id == 0 } { puts "ERROR: login: spawn telnet session failed.\n" return 1 } # wait for initial 'Press RETURN to...' response sleep 0.3 expect "*" send "\r" # If password fails 3 times then expect again set pass_attempt 0 expect { -re ".*> " { } "Password:" { incr pass_attempt send -- "$passwd\r" exp_continue } "Username: " { set pattempt 0 send -- "$user\r" expect { "Password: " { incr pattempt if {$pattempt == 1} { send -- "$userpswd\r"; } else { send -- "$enapasswd\r"; } exp_continue } -re ".*> " { exp_continue;} } } "%TELNETD-W-BADPASSWD" { puts "ERROR: bad userid or password to telnet." return 1 } "%CONS-W-AUTH_PASSWD" { exp_continue } "% Authentication failed." { puts "ERROR: bad userid or password to telnet." return 1 } "Authentication Failed:" { puts "ERROR: bad userid or password to radius/tacacs+" return 1 } "Connection closed *" { if {$pass_attempt == 3} { puts "ERROR: Maximum attempts for password reached. Check password. Exiting."; puts $expect_out(0,string); return 1 } } timeout { puts "ERROR: Timeout on login. Exiting."; return 1 } eof { puts "ERROR: device closed telnet connection during login" return 1 } } # save my_prompt for later use send "\r" expect -re ".*> " set abc "$expect_out(buffer)" set my_prompt "[lindex $abc 0]" regexp {(.*[^>])} $my_prompt my return 0; } # pre: login completed ok # post: turn off paging of commands proc disable_cli_paging { } { global my_prompt send "cli set terminal rows 0\r" expect { "$my_prompt" {return 0 } } return 1 } # pre: login returned 0, prompt at top level # post: turn off command completion return 0 # on error, return 1 proc disable_cmd_autocomplete { } { global my_prompt send "cli set command completion off\r" expect { $my_prompt { } timeout { puts "ERROR:disable_cmd_autocomplete(TIMEOUT)"; return 0; } } return 0 } # pre: login returned 0, do_enable returned 0, cli is in enable or config mode # post: issues logout cli to device, returns 0 proc logout { prompt } { global config_mode enable_prompt # in case of not being at root cmd... # verify top level prompt state, move to it if necessary if { $config_mode == 1 } { send "exit\r" expect { "Do you want*" { send "no\r" } "$enable_prompt" { } timeout { puts "ERROR: logout: timeout from config mode\n" } eof { puts "ERROR: device dropped connection\n" } } set config_mode 0 } send "logout\r" expect { "Are you sure*" { send "yes\r" return 0 } } } # pre: current mode allows transition to enable mode # post: enable mode entered, my_prompt updated, return 0 else 1 proc do_enable { enauser enapasswd userpswd } { global expect_out verbose global my_prompt enable_prompt set enable_prompt [ string trimright $my_prompt ">" ] set enable_prompt $enable_prompt\# set uses_username 0; if { $verbose == 1 } { puts "DEBUG: do_enable: my_prompt = $my_prompt ena_prompt = $enable_prompt" } send "enable\r" expect { Username: { set uses_username 1; send -- "$enauser\r"; exp_continue } Password: { if {$uses_username == 1} { send -- "$userpswd\r"; } else { send -- "$enapasswd\r"; } exp_continue } "$my_prompt" { puts "ERROR: do_enable failed to gain enable mode." return 1 } "CONS-W-AUTH_PASSWD" { send -- "$enapasswd\r"; } "$enable_prompt " { } "%SYS-W-NOPASSWD*" { } "Authentication Failed: Access Denied" { puts "ERROR: Bad user or password for enable mode." return 1 } } set my_prompt $enable_prompt return 0 } # pre: current mode allows transition to enable mode # post: enable mode entered, my_prompt updated, return 0 else 1 proc do_configure { } { global expect_out verbose config_mode global my_prompt set config_prompt [ string trimright $my_prompt "\#" ] set config_prompt $config_prompt\(config\)\# if { $verbose == 1 } { puts "DEBUG: do_config: my_prompt = $my_prompt cfg_prompt = $config_prompt" } send "configure\r" expect { "$config_prompt " { } "$my_prompt" { } eof { return 1} timeout { return 1} } set config_mode 1 set my_prompt $config_prompt return 0 } # track sent/received from device to output_file # pre: outut_file is valid filename w/write access # post: logfile open, global var logging == 1, return 0 , else 1 proc start_logfile { output_file } { global logging if { [ string length $output_file ] != 0 } { set rc [ catch { log_file -noappend $output_file } errMsg ] if { $rc != 0 } { puts "ERROR: open file $output_file for write access failed. $errMsg\n" return 1 } set logging 1 } return 0 } proc run_commands { prompt cmdstring } { global sendstring set commands [split $cmdstring \;] set num_commands [llength $cmdstring] for {set i 0} {$i < $num_commands} { incr i} { regsub -- {[ ]*([^\.]*)} [subst -nocommands [lindex $commands $i]] {\1} sendstring if {[ run_single_command $prompt $sendstring ] == 1} { puts "ERROR: command '$sendstring' not processed by device. Check previous error messages." return 1 } } return 0 } # Run commands given on the command line # pre: prompt is current system cli prompt, cmdstring is command to execute # post: return 0 on success else 1 # NOTE: output from router ends up in output_file if specified # expect internal input buffer is reset to "" after each command proc run_single_command { prompt cmdstring } { global verbose set rc 0 set seen_prompt 0 set seen_timeout 0 set need_ays 0 set delay 0 if {$verbose == 1} { puts "DEBUG: run_commands: prompt=$prompt \"$cmdstring\" " } # ays == "are you sure" - must send back yes if { [string compare $cmdstring "save startup" ] == 0 } { set need_ays 1 set delay 1 if {$verbose == 1} { puts "DEBUG: save startup cmd seen, set need_ays = 1" } } # TODO: add case for copy command to startup, also prompts for ok # TODO: if we see config command: system set name note it # if we see a save active, then update system prompts as well send "$cmdstring\r" if { $delay == 1} { sleep 1 } expect { "%CLI-E-IVCMD*" { puts "ERROR: run_commands(command rejected by device)\n" set rc 1 } "%CLI-E-FACUNKNWN*" { puts "ERROR: run_commands(command rejected by device)\n" set rc 1 } "%SYS-I-ADDFAILED*" { puts "ERROR: run_commands(command rejected by device)\n" set rc 1 } "%TFTP-E-REMOTE,*" { puts "ERROR: run_commands(command rejected by device)\n" set rc 1 } "%SYS-E-PRIMARY_NO_SUCH_IMAGE*" { puts "ERROR: run_commands(command rejected by device)\n" set rc 1 } "want to overwrite " { send "yes\r" if {$verbose == 1} { puts "DEBUG: got overwrite question, set need_ays to 0" } set need_ays 0 } "%CONFIG-E-DUPLICATE,*" { } "$prompt" { if { $seen_prompt == 0 } { set seen_prompt 1 } if {$verbose == 1} { puts "DEBUG: saw double prompt, exiting expect loop\n" } if { $need_ays == 1 } { exp_continue } } -re ".* More: m, --- Quit: q --- One line: ---" { send "q" exp_continue } timeout { if {$verbose == 1} { puts "DEBUG: timeout occured for the $seen_time time\n" } if { $seen_timeout == 0 } { set seen_timeout 1 send "\r\r" exp_continue } puts "ERROR:run_commands(TIMEOUT)" set rc 1 } eof { puts "ERROR:run_commands(connection closed by device)\n" set rc 1 } "\n" { exp_continue } } # clear input buffer of any remaining data expect "*" return $rc } # pre: RSTONE_USER env var is set # post: update global "default_user" to this string proc init_userid { } { global default_user if {[ info exists env(RSTONE_USER) ] } { set default_user $env(RSTONE_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. regexp {\(([^)]*)} [exec id] junk default_user } } proc source_script_file { filename } { global my_prompt expect -re "$my_prompt" {} source $filename } # pre: login completed ok, filename contains set of cli commands one per line # post: each command is extracted from filename and sent to device # return 0 on success, return 1 on error # NOTE: for scripts that begin with "configure", change the mode to configure # before executing the following commands proc process_script_file { filename } { global my_prompt verbose set rc 0 set ifile "" set rc [ catch { set ifile [ open $filename r] } errMsg ] if { $rc != 0 } { puts "ERROR: process_script_file: open script file $filename for read access failed. $errMsg\n" return 1 } set line_cnt 0 while { [eof $ifile] != 1 } { set bytes [ gets $ifile cmd ] incr line_cnt if { $bytes < 0 } { break } elseif { $bytes == 0 } { continue } if { $verbose == 1 } { puts "DEBUG: line:$line_cnt cmd = $cmd\n" } # skip comments in script files if { [regexp "^\#" $cmd] != 1 } { # puts "$cmd rc = [string compare $cmd "configure" ]\n" if { [string compare $cmd "configure" ] == 0 } { do_configure } else { if {[ run_commands $my_prompt $cmd ] == 1} { puts "ERROR: line $line_cnt in $filename not processed by device. Check previous error msgs." set rc 1 break } } } } close $ifile return $rc } # pre: filename is valid file # post: remove extended ascii sequences and other cruft # and prepend a header: rscmd: ip-addr : date # TODO: should watch all file commands more closely proc strip_log { filename router } { global tempfile set rc [ catch { set ifile [ open $filename r] } errMsg ] if { $rc != 0 } { puts "ERROR: strip_log: open script file $filename for read access failed. $errMsg\n" return 1 } set rc [ catch { set ofile [ open $tempfile w] } errMsg ] if { $rc != 0 } { puts "ERROR: strip_log: open temp file $tempfile for write access failed. $errMsg\n" return 1 } set nl 0 puts $ofile "rscmd: $router : [exec date]" while { [eof $ifile] != 1 } { set bytes [ gets $ifile cmd ] if { $bytes <= 0 } { break } incr nl if { $nl <= 2 } { continue } regsub -all -- "\r" $cmd "" newcmd puts $ofile $newcmd } close $ifile close $ofile set rc 0 file copy -force $tempfile $filename file delete $tempfile return $rc } # # main section # if { $verbose == 1 } { puts "\n\nrscmd: Version 1.1 started on [exec date]" puts "[exec uname -a]" puts "Expect Version: [exp_version]\n" } # send input like in a fast and consistent human style set send_human {.1 .3 1 .05 2} # initialize default_user variable init_userid # Parse Command Line for {set idx 0} {$idx < $argc} {incr idx} { set arg [lindex $argv $idx] switch -glob -- $arg { -c* - -C* { if {! [ regexp .\[cC\](.+) $arg ignore command]} { incr idx set command [ lindex $argv $idx ] } set do_command 1 # Expect debug mode } -d* { exp_internal 1 # Environment variable to pass to -s scripts } -E* { if {[ regexp .\[E\](.+)=(.+) $arg ignore varname varvalue]} { set E$varname $varvalue } else { send_user "Error: invalid format for -E in $arg\n" exit 1 } # Expect script to run } -s* { if {! [ regexp .\[sS\](.+) $arg ignore sfile]} { incr idx set sfile [ lindex $argv $idx ] } if { ! [ file exists $sfile ] } { puts "ERROR: invalid argument script file \"$sfile\" does not exist.\n" exit 1 } if { ! [ file readable $sfile ] } { puts "ERROR: invalid argument script file \"$sfile\" permissions disallow read access.\n" exit 1 } set do_script 1 # save config on exit } -S* { set do_saveconfig 1 # Version string } -V* { send_user "@PACKAGE@ @VERSION@\n" exit 0 # Command file } -x* - -X { if {! [ regexp .\[xX\](.+) $arg ignore cmd_file]} { incr idx set cmd_file [ lindex $argv $idx ] } 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 } -f* - -F* { if {! [ regexp .\[fF\](.+) $arg ignore password_file]} { incr idx set password_file [ lindex $argv $idx ] } } -o* - -O* { if {! [ regexp .\[fF\](.+) $arg ignore password_file]} { incr idx set output_file [ lindex $argv $idx ] if { $verbose == 1 } { puts "DEBUG: output file: $output_file" } } # Timeout } -t* - -T* { incr idx set timeoutdflt [ lindex $argv $idx ] # Do we enable? } -noenable { set avenable 0 } -* { send_user "Error: Unkown argument! $arg\n" send_user $usage exit 1 } default { break } } } # Verify at least one router is specified # if { $idx == $argc } { puts "\n$usage" exit 1 } # main loop set exitval 0 foreach router [lrange $argv $idx end] { set router [string tolower $router] send_user -- "$router\n" # device timeout set timeout [find timeout $router] if { [llength $timeout] == 0 } { set timeout $timeoutdflt } # Figure out passwords if {$verbose == 1} { puts "DEBUG: do_passwd = $do_passwd\n" puts "DEBUG: do_enablepasswd = $do_enapasswd\n" } # look for noenable option in .cloginrc if { [find noenable $router] == "1" } { set enable 0 } else { set enable $avenable } if { $do_passwd || $do_enapasswd } { set pswd [find password $router] if { [llength $pswd] == 0 } { puts "ERROR: - no password for $router in $password_file.\n" exit 1 } if { $do_enapasswd && [llength $pswd] < 2 } { puts "ERROR: no enable password found for $router in $password_file." exit 1 } set passwd [join [lindex $pswd 0] ""] set enapasswd [join [lindex $pswd 1] ""] } else { set passwd $userpasswd set enapasswd $enapasswd } # Figure out user to login with if necessary if {[info exists username]} { # command line username set user $username } else { set user [join [find user $router] ""] if { "$user" == "" } { set user $default_user } } # Figure out username's password if {[info exists userpasswd]} { # command line username set userpswd $userpasswd } else { set userpswd [join [find userpassword $router] ""] if { "$userpswd" == "" } { set userpswd $passwd } } # Figure out enable username if {[info exists enausername]} { # command line enausername set enauser $enausername } else { set enauser [join [find enauser $router] ""] if { "$enauser" == "" } { set enauser $user } } # Login to the router, set my_prompt to router's cmd prompt if {[login $router $user $userpswd $passwd $enapasswd ]} { incr exitval if { $verbose == 1 } { puts "DEBUG: login to $router failed\n" } exit 1 } if {$verbose == 1 } { puts "DEBUG: login completed ok\n" } if { $enable == 1 } { if { [do_enable $enauser $enapasswd $userpswd] == 1} { incr exitval if { $verbose == 1 } { puts "DEBUG: switch to enable mode on $router failed\n" } exit 1 } } # run in one of three modes if { $do_command } { disable_cmd_autocomplete disable_cli_paging if { [start_logfile $output_file] != 0 } { exit 1 } if {[ run_commands $my_prompt $command ]} { incr exitval log_file exit 1 } else { logout $my_prompt } } elseif { $do_script } { disable_cmd_autocomplete disable_cli_paging if {[ start_logfile $output_file] != 0 } { exit 1 } # if { [process_script_file $sfile] == 1}{ # puts "DEBUG: logfile $output_file closed on error\n" # logout $my_prompt # exit 1 # } source_script_file $sfile logout $my_prompt } else { label $router log_user 1 if {[ start_logfile $output_file] != 0 } { exit 1 } interact log_file } if { $verbose == 1 } { puts "DEBUG: exiting normally.\n" } if { $logging == 1} { log_file strip_log $output_file $router } # End of for each router catch {wait}; sleep 0.3 } exit $exitval rancid-2.3.8/bin/rivrancid.in100644 015615 000000 00000025376 11535733223 0011560#! @PERLV_PATH@ ## ## $Id: rivrancid.in 2279 2011-01-31 22:41:00Z heas $ ## ## @PACKAGE@ @VERSION@ ## Copyright (c) 1997-2008 by Terrapin Communications, Inc. ## All rights reserved. ## ## This code is derived from software contributed to and maintained by ## Terrapin Communications, Inc. by Henry Kilmer, John Heasley, Andrew Partan, ## Pete Whiting, Austin Schutz, and Andrew Fort. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions ## are met: ## 1. Redistributions of source code must retain the above copyright ## notice, this list of conditions and the following disclaimer. ## 2. Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## 3. All advertising materials mentioning features or use of this software ## must display the following acknowledgement: ## This product includes software developed by Terrapin Communications, ## Inc. and its contributors for RANCID. ## 4. Neither the name of Terrapin Communications, Inc. nor the names of its ## contributors may be used to endorse or promote products derived from ## this software without specific prior written permission. ## 5. It is requested that non-binding fixes and modifications be contributed ## back to Terrapin Communications, Inc. ## ## THIS SOFTWARE IS PROVIDED BY Terrapin Communications, INC. AND CONTRIBUTORS ## ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ## TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COMPANY OR CONTRIBUTORS ## BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ## CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ## SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ## INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ## CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ## ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ## POSSIBILITY OF SUCH DAMAGE. # # Amazingly hacked version of Hank's rancid - this one tries to # deal with Cabletron, Riverstone and Enterasys routers/switches # # 10/23/2002 -- Initial changes for Riverstone/Cabletron support # Jim Meehan -- jmeehan@vpizza.org # # RANCID - Really Awesome New Cisco confIg Differ # # usage: rivrancid [-dV] [-l] [-f filename | hostname] # use Getopt::Std; 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; # rivlogin timeout in seconds my(@commandtable, %commands, @commands);# command lists my($aclsort) = ("ipsort"); # ACL sorting mode my($filter_commstr); # SNMP community string filtering 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)) && scalar(%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 routine 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 routine 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 routine 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 routine (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 "system show version" sub ShowVersion { my($slot); print STDERR " In ShowVersion: $_" if ($debug); while () { tr/\015//d; next if /^\s*$/; last if(/^$prompt/); ProcessHistory("VERSION","","","!SW: $_"); } ProcessHistory("VERSION","","","!\n"); return(0); } # This routine parses "system show hardware" sub ShowHardware { print STDERR " In ShowHardware: $_" if ($debug); while () { tr/\015//d; last if (/^$prompt/); ProcessHistory("HARDWARE","","","!HW: $_"); } ProcessHistory("","","","!\n"); return(0); } # This routine parses "system show uptime" sub ShowUptime { print STDERR " In ShowUptime: $_" if ($debug); while () { tr/\015//d; last if(/^$prompt/); next if /^\s*$/; next if /System up/; ProcessHistory("UPTIME","","","!UPTIME: $_"); } ProcessHistory("","","","!\n"); return; } # This routine processes a "system show active" sub ShowActive { print STDERR " In ShowActive: $_" if ($debug); while () { tr/\015//d; # Remove leading whitespace and/or line numbers s/^\s*(\d+\D: )*//; # Riverstone/Cabletron doesn't have an "end" line, so # we need to set $clean_run here if (/^$prompt/) { $clean_run = 1; last; } next if (/Running system configuration/); # filter out any RCS/CVS tags to avoid confusing local CVS storage s/\$(Revision|Id):/ $1:/; if (/^(.*hashed-password \S+)/ && $filter_pwds == 2) { ProcessHistory("","","","! $1 \n"); next; } if (/^(snmp set community )\S+/ && $filter_commstr) { ProcessHistory("","","","! $1$'"); next; } ProcessHistory("","","","$_"); } return; } # dummy function sub DoNothing {print STDOUT;} # Main @commandtable = ( {'system show uptime' => 'ShowUptime'}, {'system show version' => 'ShowVersion'}, {'system show hardware' => 'ShowHardware'}, {'system show active-config' => 'ShowActive'} ); # 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("|", map quotemeta($_), @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 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 rivlogin -t $timeo -c\"$cisco_cmds\" $host\n" if ($debug); print STDOUT "executing rivlogin -t $timeo -c\"$cisco_cmds\" $host\n" if ($log); if (defined($ENV{NOPIPE}) && $ENV{NOPIPE} =~ /^YES/i) { system "rivlogin -t $timeo -c \"$cisco_cmds\" $host $host.raw 2>&1" || die "rivlogin failed for $host: $!\n"; open(INPUT, "< $host.raw") || die "rivlogin failed for $host: $!\n"; } else { open(INPUT,"rivlogin -t $timeo -c \"$cisco_cmds\" $host ) { tr/\015//d; last if ($clean_run); if (/^Error:/) { print STDOUT ("$host rivlogin error: $_"); print STDERR ("$host rivlogin error: $_") if ($debug); $clean_run=0; last; } $kradcount++; while (/\033(\[\?25l)/) { s/\033\[\?25l//g; #print STDERR "krad $1\n"; #print STDERR $_; #print STDERR $kradcount; next; } while (/#\s*($cmds_regexp)\s*$/) { $cmd = $1; if (!defined($prompt)) { $prompt = ($_ =~ /^([^#]+#)/)[0]; $prompt =~ s/([}{)(\\])/\\$1/g; } 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}) && $ENV{NOPIPE} =~ /^YES/i) { unlink("$host.raw") if (! $debug); } # check for completeness if (scalar(%commands) || !$clean_run) { 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) { 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); } rancid-2.3.8/bin/rrancid.in100644 015615 000000 00000032016 11535733223 0011206#! @PERLV_PATH@ ## ## $Id: rrancid.in 2279 2011-01-31 22:41:00Z heas $ ## ## @PACKAGE@ @VERSION@ ## Copyright (c) 1997-2008 by Terrapin Communications, Inc. ## All rights reserved. ## ## This code is derived from software contributed to and maintained by ## Terrapin Communications, Inc. by Henry Kilmer, John Heasley, Andrew Partan, ## Pete Whiting, Austin Schutz, and Andrew Fort. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions ## are met: ## 1. Redistributions of source code must retain the above copyright ## notice, this list of conditions and the following disclaimer. ## 2. Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## 3. All advertising materials mentioning features or use of this software ## must display the following acknowledgement: ## This product includes software developed by Terrapin Communications, ## Inc. and its contributors for RANCID. ## 4. Neither the name of Terrapin Communications, Inc. nor the names of its ## contributors may be used to endorse or promote products derived from ## this software without specific prior written permission. ## 5. It is requested that non-binding fixes and modifications be contributed ## back to Terrapin Communications, Inc. ## ## THIS SOFTWARE IS PROVIDED BY Terrapin Communications, INC. AND CONTRIBUTORS ## ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ## TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COMPANY OR CONTRIBUTORS ## BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ## CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ## SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ## INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ## CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ## ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ## POSSIBILITY OF SUCH DAMAGE. # # hacked version of Hank's rancid - this one tries to deal with redbacks. # # RANCID - Really Awesome New Cisco confIg Differ # # usage: rancid [-dV] [-l] [-f filename | hostname] # use Getopt::Std; 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 my(@commandtable, %commands, @commands);# command lists my($aclsort) = ("ipsort"); # ACL sorting mode my($filter_commstr); # SNMP community string filtering 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)) && scalar(%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 routine 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 routine 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 routine 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 routine (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 "show version" sub ShowVersion { print STDERR " In ShowVersion: $_" if ($debug); while () { tr/\015//d; last if(/^$prompt/); /(Copyright|uptime|restarted|^\s*$)/ && next; /(Up Time|Boot Time)/ && next; ProcessHistory("COMMENTS","keysort","A1","!Image: $_"); } return; } # This routine parses "dir /" sub DirFlash { print STDERR " In DirFlash: $_" if ($debug); my($dev) = (/\/(.*)$/); while () { tr/\015//d; last if(/^$prompt/); /^\s*$/ && next; /(Can\'t open|No such device)/ && return; /is not a valid path on a local file system/ && return; ProcessHistory("FLASH","keysort",$dev,"!Flash: $dev: $_"); } ProcessHistory("FLASH","keysort",$dev,"!\n"); return; } # This routine parses "show hardware" sub ShowHardware { print STDERR " In ShowHardware: $_" if ($debug); while () { tr/\015//d; last if(/^$prompt/); s/\s*$/\n/; /Can not retrieve information/ && return; /^Temperature:/ && next; /^Voltage/ && next; /^$/ && next; #ProcessHistory("","","","!Chassis: $_") && next; ProcessHistory("COMMENTS","keysort","B1","!Chassis: $_"); } ProcessHistory("COMMENTS","keysort","B1","!\n"); return; } # This routine parses "show chassis" sub ShowChassis { print STDERR " In ShowChassis: $_" if ($debug); while () { tr/\015//d; last if(/^$prompt/); last if(/^invalid input at/i); next if(/^(\s*|\s*$cmd\s*|\s+\^)$/); ProcessHistory("COMMENTS","keysort","C1","!Chassis: $_"); } ProcessHistory("COMMENTS","keysort","C1","!\n"); return; } # This routine parses "show slot table" sub ShowSlotTable { print STDERR " In ShowSlotTable: $_" if ($debug); while () { tr/\015//d; last if(/^$prompt/); /(Slot Table|^$)/ && next; /^\s+\^/ && next; /Invalid input at/ && return; s/^\s*//; ProcessHistory("COMMENTS","keysort","D1","!Slot Table: $_"); } ProcessHistory("COMMENTS","keysort","D1","!\n"); return; } # This routine processes a "write term" sub WriteTerm { print STDERR " In WriteTerm: $_" if ($debug); while () { tr/\015//d; last if(/^$prompt/); next if(/^\s*$/); # /Non-Volatile memory is in use/ && return(-1); # NvRAM is locked # Dog gone Cool matches to process the rest of the config /^! last updated: .*$/ && next; # kill last updated line /^Building configuration/ && next; # kill Building config line /^Current configuration/ && next; # kill Current config line /^! Configuration last changed by user / && next; /^ length / && next; # kill length on serial lines /^ width / && next; # kill width on serial lines # filter out any RCS/CVS tags to avoid confusing local CVS storage s/\$(Revision|Id):/ $1:/; # order access-lists /^access-list\s+(\d\d?)\s+(\S+)\s+(\S+)/ && ProcessHistory("ACL $1 $2","$aclsort","$3","$_") && next; # prune snmp community statements if (/^snmp (group|community) (\S+)/) { if ($filter_commstr) { ProcessHistory("SNMPSERVERCOMM","keysort","$_","!snmp $1 $'") && next; } else { ProcessHistory("SNMPSERVERCOMM","keysort","$_","$_") && next; } } ProcessHistory("","","","$_"); # end of config if (/^end$/) { $found_end = 1; last; } } return; } # dummy function sub DoNothing {print STDOUT;} # Main subroutine that splits up the work # All Subs return the name of the next function to use. # If the sub returns a new funtion name, that name will be used # else the main loop keeps using the current function sub FlailHelplessly { print STDERR "Flailing: $_" if ($debug); print STDOUT "Flailing: $_" if ($log); /#(show version)$/ && delete($commands{$1}) && return("ShowVersion"); /#(show hardware)$/ && delete($commands{$1}) && return("ShowHardware"); /#(show chassis)$/ && delete($commands{$1}) && return("ShowChassis"); /#(show slot table)$/ && delete($commands{$1}) && return("ShowSlotTable"); /#(show config)$/ && delete($commands{$1}) && return("WriteTerm"); return "FlailHelplessly"; } # Main @commandtable = ( {'show version' => 'ShowVersion'}, {'dir /flash' => 'DirFlash'}, {'dir /pcmcia0' => 'DirFlash'}, {'dir /pcmcia1' => 'DirFlash'}, {'show hardware' => 'ShowHardware'}, {'show chassis' => 'ShowChassis'}, {'show slot table' => 'ShowSlotTable'}, {'show config' => 'WriteTerm'} ); # 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); $redback_cmds=join(";",@commands); $cmds_regexp = join("|", map quotemeta($_), @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 ($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 clogin -t $timeo -c\"$redback_cmds\" $host\n" if ($debug); print STDOUT "executing clogin -t $timeo -c\"$redback_cmds\" $host\n" if ($log); if (defined($ENV{NOPIPE}) && $ENV{NOPIPE} =~ /^YES/i) { system "clogin -t $timeo -c \"$redback_cmds\" $host $host.raw" || die "clogin failed for $host: $!\n"; open(INPUT, "< $host.raw") || die "clogin failed for $host: $!\n"; } else { open(INPUT,"clogin -t $timeo -c \"$redback_cmds\" $host ) { tr/\015//d; if (/\#exit$/) { $clean_run=1; last; } if (/^Error:/) { print STDOUT ("$host clogin error: $_"); print STDERR ("$host clogin error: $_") if ($debug); $clean_run=0; last; } while (/#\s*($cmds_regexp)\s*$/) { $cmd = $1; if (!defined($prompt)) { $prompt = ($_ =~ /^([^#]*#)/)[0]; $prompt =~ s/([][}{)(\\])/\\$1/g; # quote the damn []'s 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; } $rval = &{$commands{$cmd}}; delete($commands{$cmd}); if ($rval == -1) { $clean_run = 0; last; } } } print STDOUT "Done $logincmd: $_\n" if ($log); # Flush History ProcessHistory("","","",""); # Cleanup close(INPUT); close(OUTPUT); if (defined($ENV{NOPIPE}) && $ENV{NOPIPE} =~ /^YES/i) { 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); } rancid-2.3.8/bin/srancid.in100755 015615 000000 00000031412 11535733223 0011211#! @PERLV_PATH@ ## ## $Id: srancid.in 2279 2011-01-31 22:41:00Z heas $ ## ## @PACKAGE@ @VERSION@ ## Copyright (c) 1997-2008 by Terrapin Communications, Inc. ## All rights reserved. ## ## This code is derived from software contributed to and maintained by ## Terrapin Communications, Inc. by Henry Kilmer, John Heasley, Andrew Partan, ## Pete Whiting, Austin Schutz, and Andrew Fort. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions ## are met: ## 1. Redistributions of source code must retain the above copyright ## notice, this list of conditions and the following disclaimer. ## 2. Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## 3. All advertising materials mentioning features or use of this software ## must display the following acknowledgement: ## This product includes software developed by Terrapin Communications, ## Inc. and its contributors for RANCID. ## 4. Neither the name of Terrapin Communications, Inc. nor the names of its ## contributors may be used to endorse or promote products derived from ## this software without specific prior written permission. ## 5. It is requested that non-binding fixes and modifications be contributed ## back to Terrapin Communications, Inc. ## ## THIS SOFTWARE IS PROVIDED BY Terrapin Communications, INC. AND CONTRIBUTORS ## ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ## TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COMPANY OR CONTRIBUTORS ## BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ## CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ## SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ## INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ## CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ## ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ## POSSIBILITY OF SUCH DAMAGE. # # Pretty huge hack to take care of Dell (aka. SMC) Switch configs; started by # d_pfleger@juniper.net # # RANCID - Really Awesome New Cisco confIg Differ # # usage: rancid [-dV] [-l] [-f filename | hostname] # use Getopt::Std; getopts('dflV'); if ($opt_V) { print "@PACKAGE@ @VERSION@\n"; exit(0); } $log = $opt_l; $debug = $opt_d; $file = $opt_f; $host = $ARGV[0]; $found_end = 0; $timeo = 90; # hlogin timeout in seconds my(@commandtable, %commands, @commands);# command lists my($aclsort) = ("ipsort"); # ACL sorting mode my($filter_commstr); # SNMP community string filtering 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)) && scalar(%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 routine 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 routine 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 routine 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 routine (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 "dir" sub Dir { print STDERR " In Dir: $_" if ($debug); while () { s/^\s+\015//g; tr/\015//d; next if /^\s*$/; last if(/$prompt/); # pager remnants like: ^H^H^H ^H^H^H content s/[\b]+\s*[\b]*//g; ProcessHistory("COMMENTS","keysort","D1","! $_"); } return(0); } sub ShowVer { print STDERR " In ShowVer: $_" if ($debug); while () { tr/\015//d; next if /^\s*$/; last if(/$prompt/); # pager remnants like: ^H^H^H ^H^H^H content s/[\b]+\s*[\b]*//g; ProcessHistory("COMMENTS","keysort","B1","! $_"); } return(0); } sub ShowSys { print STDERR " In ShowSys: $_" if ($debug); while () { s/^\s+\015//g; tr/\015//d; next if /^\s*$/; last if(/$prompt/); # pager remnants like: ^H^H^H ^H^H^H content s/[\b]+\s*[\b]*//g; # Remove Uptime / Up time/ && next; # filter temperature sensor info for Dell 6428 stacks /Temperature Sensors:/ && next; if (/Temperature \(Celsius\)/ && ProcessHistory("COMMENTS","keysort","C1","! Unit\tStatus\n")) { while () { s/^\s+\015//g; tr/\015//d; /(\d+)\s+\d+\s+(.*)$/ && ProcessHistory("COMMENTS","keysort","C1","! $1\t$2\n"); /^\s*$/ && last; } } /system description: (.*)/i && ProcessHistory("COMMENTS","keysort","A1", "!Chassis type: $1\n") && next; ProcessHistory("COMMENTS","keysort","C1","! $_"); } return(0); } sub ShowVlan { print STDERR " In ShowVlan: $_" if ($debug); while () { s/^\s+\015//g; tr/\015//d; next if /^\s*$/; last if(/$prompt/); # pager remnants like: ^H^H^H ^H^H^H content s/[\b]+\s*[\b]*//g; # Remove Uptime / Up time/ && next; ProcessHistory("COMMENTS","keysort","D1","! $_"); } return(0); } # This routine processes a "write term" (aka show running-configuration) sub WriteTerm { my($comment) = (0); print STDERR " In ShowRun: $_" if ($debug); while () { tr/\015//d; next if /^\s*$/; last if(/$prompt/); # pager remnants like: ^H^H^H ^H^H^H content s/[\b]+\s*[\b]*//g; # skip consecutive comment lines if (/^!/) { next if ($comment); ProcessHistory("","","",$_); $comment++; next; } $comment = 0; /^building running-config/ && next; /^------+/ && ProcessHistory("","","","!$_") && next; /^router configuration/i && ProcessHistory("","","","!$_") && next; /^oob host config/i && ProcessHistory("","","","!$_") && next; /^empty configuration/i && ProcessHistory("","","","!$_") && next; if (/^password (\S+) encrypted/ && $filter_pwds > 1) { ProcessHistory("","","","!password encrypted\n"); next; } if (/^password (\S+)$/ && $filter_pwds >= 1) { ProcessHistory("","","","!password \n"); next; } if (/^(enable password level \d+) (\S+) encrypted/ && $filter_pwds > 1){ ProcessHistory("","","","!$1 encrypted\n"); next; } if (/^(enable password level \d+) (\S+)$/ && $filter_pwds >= 1) { ProcessHistory("","","","!$1 $'\n"); next; } # order/prune snmp-server host statements # we only prune lines of the form # snmp-server host a.b.c.d if (/^(snmp-server host) (\d+\.\d+\.\d+\.\d+) (\S+)/) { if ($filter_commstr) { ProcessHistory("SNMPSERVERHOST","ipsort", "$2","!$1 $2 $'"); } else { ProcessHistory("SNMPSERVERHOST","ipsort","$2","$_"); } next; } if (/^(snmp-server community) (\S+)/) { if ($filter_commstr) { ProcessHistory("SNMPSERVERCOMM","keysort", "$_","!$1 $'") && next; } else { ProcessHistory("SNMPSERVERCOMM","keysort","$2","$_") && next; } } # prune tacacs/radius server keys if (/^(tacacs-server|radius-server) key \w+/ && $filter_pwds >= 1) { ProcessHistory("","","","!$1 $'"); next; } ProcessHistory("","","","$_"); } $found_end = 1; return(1); } # dummy function sub DoNothing {print STDOUT;} # Main @commandtable = ( {'show system' => 'ShowSys'}, {'show version' => 'ShowVer'}, {'dir' => 'Dir'}, {'show vlan' => 'ShowVlan'}, {'show running-config' => 'WriteTerm'} ); # 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("|", map quotemeta($_), @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 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 hlogin -t $timeo -c\"$cisco_cmds\" $host\n" if ($debug); print STDOUT "executing hlogin -t $timeo -c\"$cisco_cmds\" $host\n" if ($log); if (defined($ENV{NOPIPE}) && $ENV{NOPIPE} =~ /^YES/i) { system "hlogin -t $timeo -c \"$cisco_cmds\" $host $host.raw 2>&1" || die "hlogin failed for $host: $!\n"; open(INPUT, "< $host.raw") || die "hlogin failed for $host: $!\n"; } else { open(INPUT,"hlogin -t $timeo -c \"$cisco_cmds\" $host ) { tr/\015//d; if (/^Error:/) { print STDOUT ("$host dlogin error: $_"); print STDERR ("$host dlogin error: $_") if ($debug); last; } while (/#\s*($cmds_regexp)\s*$/) { $cmd = $1; 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"; last TOP; } $rval = &{$commands{$cmd}}; delete($commands{$cmd}); if ($rval == -1) { last TOP; } } } print STDOUT "Done $logincmd: $_\n" if ($log); # Flush History ProcessHistory("","","",""); # Cleanup close(INPUT); close(OUTPUT); if (defined($ENV{NOPIPE}) && $ENV{NOPIPE} =~ /^YES/i) { unlink("$host.raw") if (! $debug); } # check for completeness if (scalar(%commands) || !$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 (!$found_end) { print STDOUT "$found_end: found end\n"; 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); } rancid-2.3.8/bin/tlogin.in100644 015615 000000 00000060234 11712067106 0011060#! @EXPECT_PATH@ -- ## ## $Id: tlogin.in 2376 2012-01-31 22:42:14Z heas $ ## ## @PACKAGE@ @VERSION@ ## Copyright (c) @COPYYEARS@ by Terrapin Communications, Inc. ## All rights reserved. ## ## This code is derived from software contributed to and maintained by ## Terrapin Communications, Inc. by Henry Kilmer, John Heasley, Andrew Partan, ## Pete Whiting, Austin Schutz, and Andrew Fort. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions ## are met: ## 1. Redistributions of source code must retain the above copyright ## notice, this list of conditions and the following disclaimer. ## 2. Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## 3. All advertising materials mentioning features or use of this software ## must display the following acknowledgement: ## This product includes software developed by Terrapin Communications, ## Inc. and its contributors for RANCID. ## 4. Neither the name of Terrapin Communications, Inc. nor the names of its ## contributors may be used to endorse or promote products derived from ## this software without specific prior written permission. ## 5. It is requested that non-binding fixes and modifications be contributed ## back to Terrapin Communications, Inc. ## ## THIS SOFTWARE IS PROVIDED BY Terrapin Communications, INC. AND CONTRIBUTORS ## ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ## TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COMPANY OR CONTRIBUTORS ## BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ## CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ## SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ## INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ## CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ## ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ## POSSIBILITY OF SUCH DAMAGE. # # The login expect scripts were based on Erik Sherk's gwtn, by permission. # # tlogin - Netopis login # # Modified by Ed Ravin for Netopia. # Usage line set usage "Usage: $argv0 \[-dSV\] \[-autoenable\] \[-noenable\] \[-c command\] \ \[-Evar=x\] \[-e enable-password\] \[-f cloginrc-file\] \[-p user-password\] \ \[-s script-file\] \[-t timeout\] \[-u username\] \ \[-V\] \[-v vty-password\] \[-w enable-username\] \[-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 avenable 1 # The default is that you login non-enabled (tacacs can have you login already # enabled) set avautoenable 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 set do_enapasswd 1 # Sometimes routers take awhile to answer (the default is 10 sec) set timeoutdflt 45 # attempt at platform switching. set platform "" # 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) } elseif {[ info exists env(LOGNAME) ]} { set default_user $env(LOGNAME) } 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 "\nError: could not exec id: $reason\n" exit 1 } regexp {\(([^)]*)} "$reason" junk default_user } # Process the command line for {set i 0} {$i < $argc} {incr i} { set arg [lindex $argv $i] switch -glob -- $arg { } -d { exp_internal 1 # Username } -u* { if {! [ regexp .\[uU\](.+) $arg ignore user]} { incr i set username [ lindex $argv $i ] } # VTY Password } -p* { if {! [ regexp .\[pP\](.+) $arg ignore userpasswd]} { incr i set userpasswd [ lindex $argv $i ] } set do_passwd 0 # ssh passphrase } -r* { # ignore -r # VTY Password } -v* { if {! [ regexp .\[vV\](.+) $arg ignore passwd]} { incr i set passwd [ lindex $argv $i ] } set do_passwd 0 # Enable Username } -w* { if {! [ regexp .\[wW\](.+) $arg ignore enauser]} { incr i set enausername [ lindex $argv $i ] } # Environment variable to pass to -s scripts } -E* { if {[ regexp .\[E\](.+)=(.+) $arg ignore varname varvalue]} { set E$varname $varvalue } else { send_user "\nError: invalid format for -E in $arg\n" exit 1 } # Enable Password } -e* { if {! [ regexp .\[e\](.+) $arg ignore enapasswd]} { incr i set enapasswd [ lindex $argv $i ] } set do_enapasswd 0 # Command to run. } -c* { if {! [ regexp .\[cC\](.+) $arg ignore command]} { incr i set command [ lindex $argv $i ] } set do_command 1 # Expect script to run. } -s* { if {! [ regexp .\[sS\](.+) $arg ignore sfile]} { incr i set sfile [ lindex $argv $i ] } if { ! [ file readable $sfile ] } { send_user "\nError: Can't read $sfile\n" exit 1 } set do_script 1 # save config on exit } -S* { set do_saveconfig 1 # 'ssh -c' cypher type } -y* { if {! [ regexp .\[eE\](.+) $arg ignore cypher]} { incr i set cypher [ lindex $argv $i ] } # alternate cloginrc file } -f* { if {! [ regexp .\[fF\](.+) $arg ignore password_file]} { incr i set password_file [ lindex $argv $i ] } # Timeout } -t* { if {! [ regexp .\[tT\](.+) $arg ignore timeout]} { incr i set timeoutdflt [ lindex $argv $i ] } # Command file } -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 # Version string } -V* { send_user "@PACKAGE@ @VERSION@\n" exit 0 # Do we enable? } -noenable { set avenable 0 # Does tacacs automatically enable us? } -autoenable { set avautoenable 1 set avenable 0 } -* { send_user "\nError: Unknown argument! $arg\n" send_user $usage exit 1 } default { break } } } # Process routers...no routers listed is an error. if { $i == $argc } { send_user "\nError: $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 "\nError: password file ($password_file) does not exist\n" exit 1 } file stat $password_file fileinfo if { [expr ($fileinfo(mode) & 007)] != 0000 } { send_user "\nError: $password_file must not be world readable/writable\n" exit 1 } if [ catch {source $password_file} reason ] { send_user "\nError: $reason\n" exit 1 } } # Log into the router. proc login { router user userpswd passwd enapasswd cmethod cyphertype } { global spawn_id in_proc do_command do_script platform global prompt u_prompt p_prompt e_prompt sshcmd usercmd usercmd_chat global otpinuse 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 match "ssh*" $prog] { regexp {ssh(:([^[:space:]]+))*} $prog command suffix port set cmd $sshcmd if {"$port" != ""} { set cmd "$cmd -p $port" } set retval [ catch {eval spawn [split "$cmd -c $cyphertype -x -l $user $router" { }]} reason ] if { $retval } { send_user "\nError: $cmd failed: $reason\n" exit 1 } } elseif [string match "usercmd" $prog] { # user supplies connect cmd set retval [ catch {eval spawn $usercmd} reason ] if { $retval } { send_user "\nError: '$usercmd' failed: $reason\n" exit 1 } if { [llength $usercmd_chat] > 0 } { #send_user "\nExecuting usercmd_chat: $usercmd_chat\n" sleep 0.3 foreach {i j} $usercmd_chat { expect { -re $i { eval send -- "\"$j\""} timeout { send "\r"; send_user "\nTimeout in usercmd_chat waiting for -re $i: punting with CR\n"; break } } } } } elseif ![string compare $prog "rsh"] { if [ catch {spawn rsh -l $user $router} reason ] { send_user "\nError: rsh failed: $reason\n" exit 1 } } else { puts "\nError: 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 } } } # Here we get a little tricky. There are several possibilities: # the router can ask for a username and passwd and then # talk to the TACACS server to authenticate you, or if the # TACACS server is not working, then it will use the enable # passwd. Or, the router might not have TACACS turned on, # then it will just send the passwd. # if telnet fails with connection refused, try ssh expect { -re "(Connection refused|Secure connection \[^\n\r]+ refused)" { catch {close}; wait if !$progs { send_user "\nError: Connection Refused ($prog): $router\n" return 1 } } -re "(Connection closed by|Connection to \[^\n\r]+ closed)" { catch {close}; wait if !$progs { send_user "\nError: Connection closed ($prog): $router\n" return 1 } } eof { send_user "\nError: Couldn't login: $router\n"; wait; return 1 } -nocase "unknown host\r" { catch {close}; send_user "\nError: Unknown host $router\n"; wait; return 1 } "Host is unreachable" { catch {close}; send_user "\nError: Host Unreachable: $router\n"; wait; return 1 } "No address associated with name" { catch {close}; send_user "\nError: Unknown host $router\n"; wait; return 1 } -re "(Host key not found |The authenticity of host .* be established).* \\(yes/no\\)\\?" { send "yes\r" send_user "\nHost $router added to the list of known hosts.\n" exp_continue } -re "HOST IDENTIFICATION HAS CHANGED.* \\(yes/no\\)\\?" { send "no\r" send_user "\nError: The host key for $router has changed. Update the SSH known_hosts file accordingly.\n" return 1 } -re "HOST IDENTIFICATION HAS CHANGED\[^\n\r]+" { send_user "\nError: The host key for $router has changed. Update the SSH known_hosts file accordingly.\n" return 1 } -re "Offending key for .* \\(yes/no\\)\\?" { send "no\r" send_user "\nError: host key mismatch for $router. Update the SSH known_hosts file accordingly.\n" return 1 } -re "(denied|Sorry)" { send_user "\nError: Check your passwd for $router\n" catch {close}; wait; return 1 } "Login failed" { send_user "\nError: Check your passwd for $router\n" return 1 } -re "% (Bad passwords|Authentication failed)" { send_user "\nError: Check your passwd for $router\n" return 1 } "Press any key to continue." { # send_user "Pressing the ANY key\n" send "\r" exp_continue } -re "Enter Selection: " { # Catalyst 1900s have some lame menu. Enter # K to reach a command-line. send "K\r" exp_continue; } -re "Netopia.*always start from this main screen" { # send control-N to escape from the Playskool menu send -- "\x0e" set platform "netopia" set prompt "#" set autoenable 1 return 0 } -re "@\[^\r\n]+ $p_prompt" { # ssh pwd prompt sleep 1 send -- "$userpswd\r" exp_continue } -re "$u_prompt" { send -- "$user\r" set uprompt_seen 1 exp_continue } -re "(s/key|otp-\[0-9a-zA-Z]+) +\[0-9]+ +\[-0-9a-zA-Z]+\[ \r\n]" { if { !$otpinuse} { exp_continue } set challenge $expect_out(0,string) regsub {[ \r\n]$} $challenge {} challenge if [ catch {exec otphelper $router "$challenge"} userpswd ] { send_error "\nError: login: 'otphelper $router $challenge' failed.\nRun otphelper standalone to diagnose further.\n" exit 1 } exp_continue } -re "$p_prompt" { sleep 1 if {$uprompt_seen == 1} { send -- "$userpswd\r" } else { send -- "$passwd\r" } exp_continue } -re "$prompt" { break; } "Login invalid" { send_user "\nError: Invalid login: $router\n"; catch {close}; wait; return 1 } } } set in_proc 0 return 0 } # Enable proc do_enable { enauser enapasswd } { global prompt in_proc global u_prompt e_prompt global router otpinuse set in_proc 1 send "enable\r" expect { -re "(s/key|otp-\[0-9a-zA-Z]+) +\[0-9]+ +\[-0-9a-zA-Z]+\[ \r\n]" { if { !$otpinuse} { exp_continue } set challenge $expect_out(0,string) regsub {[ \r\n]$} $challenge {} challenge if [ catch {exec otphelper $router "$challenge"} enapasswd ] { send_error "\nError: enable: 'otphelper $router $challenge' failed.\nRun otphelper standalone to diagnose further.\n" exit 1 } exp_continue } -re "$u_prompt" { send -- "$enauser\r"; exp_continue} -re "$e_prompt" { send -- "$enapasswd\r"; exp_continue} "#" { set prompt "#" } "(enable)" { set prompt "> (enable) " } -re "(denied|Sorry|Incorrect)" { # % Access denied - from local auth and poss. others send_user "\nError: Check your Enable passwd\n"; return 1 } "% Error in authentication" { send_user "\nError: Check your Enable passwd\n" return 1 } "% Bad passwords" { send_user "\nError: Check your Enable passwd\n" return 1 } } # We set the prompt variable (above) so script files don't need # to know what it is. set in_proc 0 return 0 } # Run commands given on the command line. proc run_commands { prompt command } { global in_proc platform set in_proc 1 # If the prompt is (enable), then we are on a switch and the # command is "set length 0"; otherwise its "term length 0". # skip if its an extreme (since the pager can not be disabled on a # per-vty basis). if { [ string compare "extreme" "$platform" ] } { if [ regexp -- ".*> .*enable" "$prompt" ] { send "set length 0\r" # This is ugly, but reduces code duplication, allowing the # subsequent expects to handle everything as normal. set command "set logging session disable;$command" } elseif { ![ string compare "netopia" "$platform" ] } { # kludge - should instead skip re-sensing prompt if platform netopia set prompt "#" } else { send "term length 0\r" } # escape any parens in the prompt, such as "(enable)" regsub -all {[)(]} $prompt {\\&} reprompt # match cisco config mode prompts too, such as router(config-if)#, # but catalyst does not change in this fashion. regsub -all {^(.{1,14}).*([#>])$} $reprompt {\1([^#>\r\n]+)?[#>](\\([^)\\r\\n]+\\))?} reprompt expect { -re $reprompt {} -re "\[\n\r]+" { exp_continue } } } else { regsub -all "\[)(]" $prompt {\\&} reprompt } # this is the only way i see to get rid of more prompts in o/p..grrrrr log_user 0 set commands [split $command \;] set num_commands [llength $commands] # the pager can not be turned off on the PIX, so we have to look # for the "More" prompt. the extreme is equally obnoxious, with a # global switch in the config. for {set i 0} {$i < $num_commands} { incr i} { send -- "[subst -nocommands [lindex $commands $i]]\r" expect { -re "\b+" { exp_continue } -re "^\[^\n\r *]*$reprompt" { send_user -- "$expect_out(buffer)" } -re "^\[^\n\r]*$reprompt." { send_user -- "$expect_out(buffer)" exp_continue } -re "\[\n\r]+" { send_user -- "$expect_out(buffer)" exp_continue } -re "\[^\r\n]*Press to cont\[^\r\n]*" { send " " # bloody ^[[2K after " " expect { -re "^\[^\r\n]*\r" {} } exp_continue } -re "^ *--More--\[^\n\r]*" { send " " exp_continue } -re "^<-+ More -+>\[^\n\r]*" { send_user -- "$expect_out(buffer)" send " " exp_continue } } } log_user 1 if { [ string compare "extreme" "$platform" ] } { send "exit\r" } else { send "quit\r" } expect { -re "^\[^\n\r *]*$reprompt" { # the Cisco CE and Jnx ERX # return to non-enabled mode # on exit in enabled mode. send "exit\r" exp_continue; } "Do you wish to save your configuration changes" { send "n\r" exp_continue } -re "\[\n\r]+" { exp_continue } timeout { close; 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" # device timeout set timeout [find timeout $router] if { [llength $timeout] == 0 } { set timeout $timeoutdflt } # Figure out prompt. # Since autoenable is off by default, if we have it defined, it # was done on the command line. If it is not specifically set on the # command line, check the password file. if $avautoenable { set autoenable 1 set enable 0 set prompt "(#| \\(enable\\))" } else { set ae [find autoenable $router] if { "$ae" == "1" } { set autoenable 1 set enable 0 set prompt "(#| \\(enable\\))" } else { set autoenable 0 set enable $avenable set prompt ">" } } # look for noenable option in .cloginrc if { [find noenable $router] == "1" } { set enable 0 } # is OTP in use? If so, bypass password checks set otpinuse 0 if { [find otp_secret $router] != "" } { set otpinuse 1 } # Figure out passwords if { $do_passwd || $do_enapasswd } { set pswd [find password $router] if { [llength $pswd] == 0 && !$otpinuse} { send_user "\nError: no password for $router in $password_file.\n" continue } if { $enable && $do_enapasswd && $autoenable == 0 && [llength $pswd] < 2 && !$otpinuse } { send_user "\nError: no enable password for $router in $password_file.\n" continue } set passwd [join [lindex $pswd 0] ""] set enapasswd [join [lindex $pswd 1] ""] } # Figure out username if {[info exists username]} { # command line username set ruser $username } else { set ruser [join [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 [join [find userpassword $router] ""] if { "$userpswd" == "" } { set userpswd $passwd } } # Figure out enable username if {[info exists enausername]} { # command line enausername set enauser $enausername } else { set enauser [join [find enauser $router] ""] if { "$enauser" == "" } { set enauser $ruser } } # Figure out prompts set u_prompt [find userprompt $router] if { "$u_prompt" == "" } { set u_prompt "(Username|Login|login|user name|name):" } else { set u_prompt [join [lindex $u_prompt 0] ""] } set p_prompt [find passprompt $router] if { "$p_prompt" == "" } { set p_prompt "(\[Pp]assword|passwd):" } else { set p_prompt [join [lindex $p_prompt 0] ""] } set e_prompt [find enableprompt $router] if { "$e_prompt" == "" } { set e_prompt "\[Pp]assword:" } else { set e_prompt [join [lindex $e_prompt 0] ""] } # 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}} } # Figure out the SSH executable name set sshcmd [join [lindex [find sshcmd $router] 0] ""] if { "$sshcmd" == "" } { set sshcmd {ssh} } # If user provides a router-specific connection method, use it set usercmd [find usercmd $router] set usercmd_chat [find usercmd_chat $router] # Login to the router if {[login $router $ruser $userpswd $passwd $enapasswd $cmethod $cyphertype]} { continue } if { $enable } { if {[do_enable $enauser $enapasswd]} { if { $do_command || $do_script } { close; wait continue } } } # we are logged in, now figure out the full prompt send "\r" expect { -re "\[\r\n]+" { exp_continue; } -re "^(.+:)1 $prompt" { # stoopid extreme cmd-line numbers and # prompt based on state of config changes, # which may have an * at the beginning. set junk $expect_out(1,string) regsub -all "^\\\* " $expect_out(1,string) {} junk set prompt ".? ?$junk\[0-9]+ $expect_out(2,string)"; set platform "extreme" } -re "^.+$prompt" { set junk $expect_out(0,string); regsub -all "\[\]\[]" $junk {\\&} prompt; } -re "^.+> \\\(enable\\\)" { set junk $expect_out(0,string); regsub -all "\[\]\[]" $junk {\\&} prompt; } } if { $do_command } { if {[run_commands $prompt $command]} { continue } } elseif { $do_script } { # If the prompt is (enable), then we are on a switch and the # command is "set length 0"; otherwise its "term length 0". if [ regexp -- ".*> .*enable" "$prompt" ] { send "set length 0\r" send "set logging session disable\r" } elseif { ![ string compare "netopia" "$platform" ] } { # do nothing } else { send "term length 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 rancid-2.3.8/bin/tntlogin.in100644 015615 000000 00000037300 11712067106 0011420#! @EXPECT_PATH@ -- ## ## $Id: tntlogin.in 2376 2012-01-31 22:42:14Z heas $ ## ## @PACKAGE@ @VERSION@ ## Copyright (c) @COPYYEARS@ by Terrapin Communications, Inc. ## All rights reserved. ## ## This code is derived from software contributed to and maintained by ## Terrapin Communications, Inc. by Henry Kilmer, John Heasley, Andrew Partan, ## Pete Whiting, Austin Schutz, and Andrew Fort. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions ## are met: ## 1. Redistributions of source code must retain the above copyright ## notice, this list of conditions and the following disclaimer. ## 2. Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## 3. All advertising materials mentioning features or use of this software ## must display the following acknowledgement: ## This product includes software developed by Terrapin Communications, ## Inc. and its contributors for RANCID. ## 4. Neither the name of Terrapin Communications, Inc. nor the names of its ## contributors may be used to endorse or promote products derived from ## this software without specific prior written permission. ## 5. It is requested that non-binding fixes and modifications be contributed ## back to Terrapin Communications, Inc. ## ## THIS SOFTWARE IS PROVIDED BY Terrapin Communications, INC. AND CONTRIBUTORS ## ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ## TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COMPANY OR CONTRIBUTORS ## BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ## CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ## SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ## INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ## CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ## ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ## POSSIBILITY OF SUCH DAMAGE. # # The expect login scripts were based on Erik Sherk's gwtn, by permission. # # Modified by P B Matthews. # Usage line set usage "Usage: $argv0 \[-dSV\] \[-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 avenable 0 # The default is that you login non-enabled (tacacs can have you login already # enabled) set avautoenable 1 # 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 # Save config, if prompted set do_saveconfig 0 # Sometimes routers take awhile to answer (the default is 10 sec) set timeoutdflt 45 # 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) } elseif {[ info exists env(LOGNAME) ]} { set default_user $env(LOGNAME) } 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 "\nError: could not exec id: $reason\n" exit 1 } regexp {\(([^)]*)} "$reason" junk default_user } if {[ info exists env(CLOGINRC) ]} { set password_file $env(CLOGINRC) } # Process the command line for {set i 0} {$i < $argc} {incr i} { set arg [lindex $argv $i] switch -glob -- $arg { # Expect debug mode -d* { exp_internal 1 # Username } -u* { if {! [ regexp .\[uU\](.+) $arg ignore user]} { incr i set username [ lindex $argv $i ] } # VTY Password } -v* { if {! [ regexp .\[vV\](.+) $arg ignore passwd]} { incr i set passwd [ lindex $argv $i ] } set do_passwd 0 # ssh passphrase } -r* { # ignore -r # Version string } -V* { send_user "@PACKAGE@ @VERSION@\n" exit 0 # Enable Username } -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 "\nError: invalid format for -E in $arg\n" exit 1 } # Enable Password } -e* { # ignore -e # Command to run. } -c* { if {! [ regexp .\[cC\](.+) $arg ignore command]} { incr i set command [ lindex $argv $i ] } set do_command 1 # Expect script to run. } -s* { if {! [ regexp .\[sS\](.+) $arg ignore sfile]} { incr i set sfile [ lindex $argv $i ] } if { ! [ file readable $sfile ] } { send_user "\nError: Can't read $sfile\n" exit 1 } set do_script 1 # save config on exit } -S* { set do_saveconfig 1 # 'ssh -c' cypher type } -y* { if {! [ regexp .\[eE\](.+) $arg ignore cypher]} { incr i set cypher [ lindex $argv $i ] } # alternate cloginrc file } -f* { if {! [ regexp .\[fF\](.+) $arg ignore password_file]} { incr i set password_file [ lindex $argv $i ] } # Timeout } -t* { if {! [ regexp .\[tT\](.+) $arg ignore timeout]} { incr i set timeoutdflt [ lindex $argv $i ] } # Command file } -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 "\nError: Unknown argument! $arg\n" send_user $usage exit 1 } default { break } } } # Process routers...no routers listed is an error. if { $i == $argc } { send_user "\nError: $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 "\nError: password file ($password_file) does not exist\n" exit 1 } file stat $password_file fileinfo if { [expr ($fileinfo(mode) & 007)] != 0000 } { send_user "\nError: $password_file must not be world readable/writable\n" exit 1 } if [ catch {source $password_file} reason ] { send_user "\nError: $reason\n" exit 1 } } # Log into the router. # returns: 0 on success, 1 on failure proc login { router user userpswd passwd prompt cmethod cyphertype } { global spawn_id in_proc do_command do_script global u_prompt p_prompt sshcmd 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] { incr progs -1 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" return 1 } } elseif ![string compare $prog "ssh"] { regexp {ssh(:([^[:space:]]+))*} $prog methcmd suffix port set cmd $sshcmd if {"$port" != ""} { set cmd "$cmd -p $port" } set retval [ catch {eval spawn [split "$cmd -c $cyphertype -x -l $user $router" { }]} reason ] if { $retval } { send_user "\nError: $cmd failed: $reason\n" return 1 } } elseif ![string compare $prog "rsh"] { send_error "\nError: unsupported method: rsh\n" if { $progs == 0 } { return 1 } continue; } else { send_user "\nError: unknown connection method: $prog\n" return 1 } sleep 0.3 # This helps cleanup each expect clause. expect_after { timeout { send_user "\nError: TIMEOUT reached\n" catch {close}; catch {wait}; if { $in_proc} { return 1 } else { continue } } eof { send_user "\nError: EOF received\n" catch {close}; catch {wait}; if { $in_proc} { return 1 } else { continue } } } expect { "Connection refused" { catch {close}; catch {wait}; sleep 0.3 expect eof send_user "\nError: Connection Refused\n"; wait; return 1 } eof { send_user "\nError: Couldn't login\n"; wait; return 1 } "Unknown host\r\n" { expect eof send_user "\nError: Unknown host\n"; wait; return 1 } "Host is unreachable" { expect eof send_user "\nError: Host Unreachable!\n"; wait; return 1 } "No address associated with name" { expect eof send_user "\nError: Unknown host\n"; wait; return 1 } -re "(Host key not found |The authenticity of host .* be established).* \\(yes/no\\)\\?" { send "yes\r" send_user "\nHost $router added to the list of known hosts.\n" exp_continue } -re "HOST IDENTIFICATION HAS CHANGED.* \\(yes/no\\)\\?" { send "no\r" send_user "\nError: The host key for $router has changed. Update the SSH known_hosts file accordingly.\n" return 1 } -re "HOST IDENTIFICATION HAS CHANGED\[^\n\r]+" { send_user "\nError: The host key for $router has changed. Update the SSH known_hosts file accordingly.\n" return 1 } -re "Offending key for .* \\(yes/no\\)\\?" { send "no\r" send_user "\nError: host key mismatch for $router. Update the SSH known_hosts file accordingly.\n" 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 "\nError: Check your password for $router\n"; catch {close}; catch {wait}; return 1 } -re "$prompt" { break; } denied { send_user "\nError: Check your passwd for $router\n" catch {close}; catch {wait}; 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 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 } } } send "quit\r" # expect { # -re "^WARNING: the current user has insufficient rights to view password fields. A configuration saved under this circumstance should not be used to restore profiles containing passwords. Save anyway? [y/n]" # { # send "y\r" exp_continue } "\n" { exp_continue } "\[^\n\r *]*Session terminated" { return 0 } timeout { catch {close}; catch {wait}; 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 set exitval 0 foreach router [lrange $argv $i end] { set router [string tolower $router] send_user "$router\n" # device timeout set timeout [find timeout $router] if { [llength $timeout] == 0 } { set timeout $timeoutdflt } # Figure out prompt. set prompt "admin>" # TNT 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 "\nError - no password for $router in $password_file.\n" continue } set passwd [join [lindex $pswd 0] ""] } # Figure out username if {[info exists username]} { # command line username set ruser $username } else { set ruser [join [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 [join [find userpassword $router] ""] if { "$userpswd" == "" } { set userpswd $passwd } } # Figure out prompts set u_prompt [find userprompt $router] if { "$u_prompt" == "" } { set u_prompt "(User|Username|login| Login):" } else { set u_prompt [join [lindex $u_prompt 0] ""] } set p_prompt [find passprompt $router] if { "$p_prompt" == "" } { set p_prompt "\[Pp]assword:" } else { set p_prompt [join [lindex $p_prompt 0] ""] } # 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}} } # Figure out the SSH executable name set sshcmd [join [lindex [find sshcmd $router] 0] ""] if { "$sshcmd" == "" } { set sshcmd {ssh} } # Login to the router if {[login $router $ruser $userpswd $passwd $prompt $cmethod $cyphertype]} { incr exitval continue } if { $do_command } { if {[run_commands $prompt $command]} { incr exitval continue } } elseif { $do_script } { expect -re $prompt {} source $sfile send "y\r" catch {close}; } else { label $router log_user 1 interact } # End of for each router catch {wait}; sleep 0.3 } exit $exitval rancid-2.3.8/bin/tntrancid.in100644 015615 000000 00000023423 11535733223 0011554#! @PERLV_PATH@ ## ## $Id: tntrancid.in 2279 2011-01-31 22:41:00Z heas $ ## ## @PACKAGE@ @VERSION@ ## Copyright (c) 1997-2008 by Terrapin Communications, Inc. ## All rights reserved. ## ## This code is derived from software contributed to and maintained by ## Terrapin Communications, Inc. by Henry Kilmer, John Heasley, Andrew Partan, ## Pete Whiting, Austin Schutz, and Andrew Fort. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions ## are met: ## 1. Redistributions of source code must retain the above copyright ## notice, this list of conditions and the following disclaimer. ## 2. Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## 3. All advertising materials mentioning features or use of this software ## must display the following acknowledgement: ## This product includes software developed by Terrapin Communications, ## Inc. and its contributors for RANCID. ## 4. Neither the name of Terrapin Communications, Inc. nor the names of its ## contributors may be used to endorse or promote products derived from ## this software without specific prior written permission. ## 5. It is requested that non-binding fixes and modifications be contributed ## back to Terrapin Communications, Inc. ## ## THIS SOFTWARE IS PROVIDED BY Terrapin Communications, INC. AND CONTRIBUTORS ## ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ## TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COMPANY OR CONTRIBUTORS ## BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ## CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ## SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ## INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ## CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ## ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ## POSSIBILITY OF SUCH DAMAGE. # # Modified by Paul B Matthews & Richard Vander Reyden. # I'm suprised it still works.... # # RANCID - Really Awesome New Cisco confIg Differ # # usage: tntrancid [-dV] [-l] [-f filename | hostname] # use Getopt::Std; 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; # tntlogin timeout in seconds $prompt = "admin> "; $always_y = "y"; # cause its a pain. my(@commandtable, %commands, @commands);# command lists my($aclsort) = ("ipsort"); # ACL sorting mode my($filter_commstr); # SNMP community string filtering 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)) && scalar(%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 routine 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 routine 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 routine 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 routine (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 processes a "save con" sub SaveConf { print STDERR " In SaveConf: $_" if ($debug); while () { tr/\015//d; last if(/^$prompt/); # Leave software revision, but strip out saved date, # which causes rancid to think it changes each poll if (/^; saved from /) { ProcessHistory("","","","$_"); next; } /^; saved / && next; # catch anything that wasnt match above. ProcessHistory("","","","$_"); # end of config if (/; profiles saved$/) { printf STDERR " End SaveConf: $_" if ($debug); $found_end = 1; print STDOUT "$found_end = found_end within test\n"; return(1); } # XXX what is the purpose of this? $found_end = 1; #### print STDOUT "$found_end = found_end at test\n"; } $found_end = 1; return(0); } $found_end = 1; print STDOUT "$found_end = found_end at end test\n"; # dummy function sub DoNothing {print STDOUT;} # Main @commandtable = ( {'save con' => 'SaveConf'} ); # 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); $tnt_cmds=join(";",@commands); $cmds_regexp = join("|", map quotemeta($_), @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 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 tntlogin -t $timeo -c\"$tnt_cmds\" $host\n" if ($debug); print STDOUT "executing tntlogin -t $timeo -c\"$tnt_cmds\" $host\n" if ($log); if (defined($ENV{NOPIPE}) && $ENV{NOPIPE} =~ /^YES/i) { system "tntlogin -t $timeo -c \"$tnt_cmds\" $host $host.raw 2>&1" || die "tntlogin failed for $host: $!\n"; open(INPUT, "< $host.raw") || die "tntlogin failed for $host: $!\n"; } else { open(INPUT,"tntlogin -t $timeo -c \"$tnt_cmds\" $host ) { tr/\015//d; if (/^Error:/) { print STDOUT ("$host tntlogin error: $_"); print STDERR ("$host tntlogin error: $_") if ($debug); $clean_run=0; last; } while (/$prompt\s*($cmds_regexp)\s*$/) { $cmd = $1; if (!defined($prompt)) { $prompt = ($_ =~ /^([^#]+#)/)[0]; $prompt =~ s/([][}{)(\\])/\\$1/g; $prompt =~ s/:(\d+ ?)#/:\\d+ ?#/; 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; } $rval = &{$commands{$cmd}}; delete($commands{$cmd}); if ($rval == -1) { printf STDERR "rval = -1\n" if ($debug); $clean_run = 0; last TOP; } } } print STDOUT "Done $logincmd: $_\n" if ($log); # Flush History ProcessHistory("","","",""); # Cleanup $clean_run = 1; print STDOUT "$clean_run - clean\n"; close(INPUT); close(OUTPUT); if (defined($ENV{NOPIPE}) && $ENV{NOPIPE} =~ /^YES/i) { 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); } rancid-2.3.8/bin/trancid.in100644 015615 000000 00000023372 11535733223 0011215#! @PERLV_PATH@ ## ## $Id: trancid.in 2279 2011-01-31 22:41:00Z heas $ ## ## @PACKAGE@ @VERSION@ ## Copyright (c) 1997-2008 by Terrapin Communications, Inc. ## All rights reserved. ## ## This code is derived from software contributed to and maintained by ## Terrapin Communications, Inc. by Henry Kilmer, John Heasley, Andrew Partan, ## Pete Whiting, Austin Schutz, and Andrew Fort. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions ## are met: ## 1. Redistributions of source code must retain the above copyright ## notice, this list of conditions and the following disclaimer. ## 2. Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## 3. All advertising materials mentioning features or use of this software ## must display the following acknowledgement: ## This product includes software developed by Terrapin Communications, ## Inc. and its contributors for RANCID. ## 4. Neither the name of Terrapin Communications, Inc. nor the names of its ## contributors may be used to endorse or promote products derived from ## this software without specific prior written permission. ## 5. It is requested that non-binding fixes and modifications be contributed ## back to Terrapin Communications, Inc. ## ## THIS SOFTWARE IS PROVIDED BY Terrapin Communications, INC. AND CONTRIBUTORS ## ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ## TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COMPANY OR CONTRIBUTORS ## BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ## CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ## SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ## INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ## CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ## ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ## POSSIBILITY OF SUCH DAMAGE. # # RANCID - Really Awesome New Cisco confIg Differ # # usage: rancid [-dV] [-l] [-f filename | $host] # # Modified by Ed Ravin for Netopia. use Getopt::Std; 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; $found_version = 0; $found_env = 0; $found_diag = 0; $timeo = 90; # clogin timeout in seconds $clogin_pgm= $ENV{'RANCID_CLOGIN'} || "tlogin"; 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)) && scalar(%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 "show version" sub ShowVersion { print STDERR " In ShowVersion: $_" if ($debug); while () { tr/\015//d; if (/^$prompt/) { $found_version=1; last}; next if(/^(\s*|\s*$cmd\s*)$/); return(1) if /(Invalid input detected|Type help or )/; return(-1) if (/command authorization failed/i); return(0) if ($found_version); # Only do this routine once # no pagers in Netopia-land, but shouldn't hurt s/^<-+ More -+>\s*//; ### sample output: ### #show version ### cli version: 01.00d00 ### firmware version: 05.03.09f06 ### hardware version: 01.00f00 ### mib version: 01.00f00 ### html version: 01.01d07 ProcessHistory("COMMENTS","keysort","A1","# $_"); } return(0); } sub ShowConfig { print STDERR " In ShowConfig: $_" if ($debug); while () { tr/\015//d; if (/^$prompt/) { $found_end=1; $clean_run=1; return 0}; next if(/^(\s*|\s*$cmd\s*)$/); return(1) if /(Invalid input detected|Type help or )/; return(-1) if (/command authorization failed/i); # no pagers in Netopia-land, but shouldn't hurt s/^<-+ More -+>\s*//; # no post-processing needed - just file it ProcessHistory("","","","$_"); } } # dummy function sub DoNothing {print STDOUT;} # Main @commandtable=( {'show version' => "ShowVersion"}, {'show config' => "ShowConfig"}, ); # Use array to preserve order of commands, and hash for mapping to subroutine my (%commands, @commands); foreach (@commandtable) { push @commands, (keys(%{$_}))[0]; $commands{$commands[$#commands]}= (values(%{$_}))[0]; }; $cisco_cmds=join(";",@commands); $cmds_regexp = join("|", map quotemeta($_), @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 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 $clogin_pgm -t $timeo -c\"$cisco_cmds\" $host\n" if ($debug); print STDOUT "executing $clogin_pgm -t $timeo -c\"$cisco_cmds\" $host\n" if ($log); if (defined($ENV{NOPIPE}) && $ENV{NOPIPE} =~ /^YES/i) { system "$clogin_pgm -t $timeo -c \"$cisco_cmds\" $host $host.raw 2>&1" || die "$clogin_pgm failed for $host: $!\n"; open(INPUT, "< $host.raw") || die "$clogin_pgm failed for $host: $!\n"; } else { open(INPUT,"$clogin_pgm -t $timeo -c \"$cisco_cmds\" $host ) { tr/\015//d; if (/[>#]\s?exit$/) { $clean_run=1; last; } if (/^Error:/) { print STDOUT ("$host $clogin_pgm error: $_"); print STDERR ("$host $clogin_pgm error: $_") if ($debug); $clean_run=0; last; } while (/#\s*($cmds_regexp)\s*$/) { $cmd = $1; if (!defined($prompt)) { $prompt = "#"; # crude but effective $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; } $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}) && $ENV{NOPIPE} =~ /^YES/i) { 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); } rancid-2.3.8/bin/xrancid.in100644 015615 000000 00000041336 11674710516 0011225#! @PERLV_PATH@ ## ## $Id: xrancid.in 2349 2011-12-07 23:47:09Z heas $ ## ## @PACKAGE@ @VERSION@ ## Copyright (c) 1997-2008 by Terrapin Communications, Inc. ## All rights reserved. ## ## This code is derived from software contributed to and maintained by ## Terrapin Communications, Inc. by Henry Kilmer, John Heasley, Andrew Partan, ## Pete Whiting, Austin Schutz, and Andrew Fort. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions ## are met: ## 1. Redistributions of source code must retain the above copyright ## notice, this list of conditions and the following disclaimer. ## 2. Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## 3. All advertising materials mentioning features or use of this software ## must display the following acknowledgement: ## This product includes software developed by Terrapin Communications, ## Inc. and its contributors for RANCID. ## 4. Neither the name of Terrapin Communications, Inc. nor the names of its ## contributors may be used to endorse or promote products derived from ## this software without specific prior written permission. ## 5. It is requested that non-binding fixes and modifications be contributed ## back to Terrapin Communications, Inc. ## ## THIS SOFTWARE IS PROVIDED BY Terrapin Communications, INC. AND CONTRIBUTORS ## ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ## TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COMPANY OR CONTRIBUTORS ## BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ## CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ## SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ## INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ## CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ## ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ## POSSIBILITY OF SUCH DAMAGE. # # RANCID - Really Awesome New Cisco confIg Differ # # usage: rancid [-dV] [-l] [-f filename | hostname] # use Getopt::Std; 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 my(@commandtable, %commands, @commands);# command lists my($aclsort) = ("ipsort"); # ACL sorting mode my($filter_commstr); # SNMP community string filtering 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)) && scalar(%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 routine 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 routine 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 routine 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 routine (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 "show version" sub ShowVersion { print STDERR " In ShowVersion: $_" if ($debug); while () { tr/\015//d; last if(/^$prompt/); next if(/^(\s*|\s*$cmd\s*)$/); /^\S+ Serial Number:/i && ProcessHistory("COMMENTS","keysort","B0","#$_") && next; /^(\S+) Power Supply ([^:]+):\s+(.*)/i && ProcessHistory("COMMENTS","keysort","C0","#Power: $1 $2 $3\n") && next; /^image\s*:\s*(.*)\s+by\s+/i && ProcessHistory("COMMENTS","keysort","D0","#Image: $1\n") && next; /^bootrom\s+:\s+(.*)/i && ProcessHistory("COMMENTS","keysort","D1","#\n#Bootrom: $1\n") && next; #heas: need to collect this from show vers for ShowSlot where rev #s are excluded #SLOT 1 : 702005-06 0025S-00877 CPLD Rev #SLOT 2 : 702005-06 0021S-00131 CPLD Rev 02 #SLOT 3 : 702009-06 0024S-00170 CPLD Rev #SLOT 4 : 702009-06 0024S-00319 CPLD Rev } return(0); } # This routine parses "show memory" sub ShowMemory { print STDERR " In ShowMemory: $_" if ($debug); while () { tr/\015//d; last if(/^$prompt/); next if(/^(\s*|\s*$cmd\s*)$/); /^Total DRAM Size: (.*)/ && ProcessHistory("COMMENTS","keysort","B1","#\n#Memory: $1\n") } return(0); } # This routine parses "show diag" sub ShowDiag { print STDERR " In ShowDiag: $_" if ($debug); while () { tr/\015//d; last if (/^$prompt/); last if (/^Syntax error at token/); next if (/^(\s*|\s*$cmd\s*)$/); /platform\s+:\s+(.*)$/i && ProcessHistory("COMMENTS","keysort","A0","#Chassis type: $1\n") && next; /(\S+) part no\s+:\s+(.*)$/i && ProcessHistory("COMMENTS","keysort","E0","#$1 PN: $2\n") && next; /(\S+ \S+) no\s+:\s+(.*)$/i && ProcessHistory("COMMENTS","keysort","E0","#$1 PN: $2\n") && next; /(mac address)\s+:\s+(.*)$/i && ProcessHistory("COMMENTS","keysort","B0","#$1: $2\n") && next; } return(0); } # This routine parses "show slot" sub ShowSlot { print STDERR " In ShowSlot: $_" if ($debug); while () { tr/\015//d; last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); if (/^Slot\s+(\d+)\s+/i) { my($slot) = $1; my($hwtype, $conftype, $sn, $state); ProcessHistory("COMMENTS","keysort","F$slot","#\n"); while () { tr/\015//d; last if (/^$prompt/ || /^\s*$/); if (/State:\s+(.*)$/i) { $state = $1; } if (/serial number:\s+(.*)$/i) { $sn = $1; } if (/hw module type:\s+(.*)$/i) { $hwtype = $1; } if (/configured type:\s+(.*)$/i) { $conftype = $1; } } ProcessHistory("COMMENTS","keysort","F$slot","#Slot $slot: type " . "$hwtype," . " $conftype\n#Slot $slot: serial $sn\n#Slot $slot: state " . " $state\n"); return if (/^$prompt/); next; } } return(0); } # This routine parses "show switch" sub ShowSwitch { print STDERR " In ShowSwitch: $_" if ($debug); while () { tr/\015//d; last if(/^$prompt/); next if(/^(\s*|\s*$cmd\s*)$/); /^\s*$/i && next; /^(primary|secondary) configuration:/i && next; /^(boot |next reboot)/i && next; /^(auto |qos mode|sys\S*:|temperature|time)/i && next; /^system type\s*:\s*(.+)/i && ProcessHistory("COMMENTS","keysort","A0","#Chassis type: $1\n") && next; /^power supply: (.*)/i && ProcessHistory("COMMENTS","keysort","C0","#$1") && next; /^license/i && ProcessHistory("COMMENTS","keysort","D0","#Image: $_") && next; s/^software image (\S+):/Image: $1:/i && ProcessHistory("COMMENTS","keysort","D0","#$_") && next; /^\S+ software version:/i && ProcessHistory("COMMENTS","keysort","D0","#Image: $_") && next; /^(\S+ )?software/i && ProcessHistory("COMMENTS","keysort","D0","# $_"); } return(0); } # This routine processes a "write term" sub WriteTerm { my($lines) = 0; print STDERR " In WriteTerm: $_" if ($debug); my($comment) = 1; # strip extra comments, esp to preserve chassis type while () { tr/\015//d; last if(/^$prompt/); next if(/^\s*$/); return(0) if (/^syntax error at token /i); return(0) if (/^%% Invalid input detected at /i); return(0) if (/^%% Ambiguous command:/i); # the pager can not be disabled per-session on the PIX s/^<-+ More -+>\s*//; return(0) if ($found_end); s/^\s*$/#/; next if (/full detail configuration/i); # filter extra comments and lead comments in config so we can preserve # the chassis type at the top of muched o/p before the process history # key changes. if (/^#\s*$/) { if ($comment) { next; } else { $comment++; } } else { $comment = 0; } $lines++; # Dog gone Cool matches to process the rest of the config # some chassis report their chassis type in show diag...oh, but # others do not. grab it here, if available. so, nothing else # can change the keysort key until this is grabbed. sigh. /# (\S+) configuration generated/i && ProcessHistory("COMMENTS","keysort","A0","#Chassis type: $1\n") && ($comment = 0) && next; /configuration generated/i && next; /# system name/i && next; /# software version/i && next; if (/((create|configure) account \S+ \S+) / && $filter_pwds >= 2) { ProcessHistory("COMMENTS","keysort","H0","# $1 \n"); next; } if (/configure ssh2 key/ && $filter_pwds >= 1) { ProcessHistory("COMMENTS","keysort","H0","# $_# \n"); while () { if (/^(#|enable|conf|disable|unconf)/) { tr/\015//d; last; } } } # filter out any RCS/CVS tags to avoid confusing local CVS storage s/\$(Revision|Id):/ $1:/; if (/^((config|configure) bgp (neighbor|peer-group) \S+ password encrypted)/i && $filter_pwds >= 1) { ProcessHistory("COMMENTS","keysort","H0","# $1 \n"); next; } # order logging statements /^configure syslog add logging (\d+\.\d+\.\d+\.\d+)/ && ProcessHistory("LOGGING","ipsort","$1","$_") && next; # order/prune snmp-server host statements # we only prune lines of the form # configure snmp add trapreceiver a.b.c.d if (/^(configure snmp add trapreceiver )(\d+\.\d+\.\d+\.\d+) (community) \S+/) { if ($filter_commstr) { ProcessHistory("SNMPSVRHOST","ipsort","$2","# $1$2 $3 $'\n"); } else { ProcessHistory("SNMPSVRHOST","ipsort","$2","$_\n"); } next; } if (/^(configure snmp community (readonly|readwrite)( encrypted)?) (\S+)/) { if ($filter_commstr) { ProcessHistory("SNMPSVRCOMM","keysort","$_","#$1 $'"); next; } else { ProcessHistory("SNMPSVRCOMM","keysort","$_","$_") && next; } } # order/prune tacacs/radius server statements if (/^(configure radius (primary|secondary) (tacacs-server|radius-server) shared-secret encrypted)/ && $filter_pwds >= 1) { ProcessHistory("COMMENTS","keysort","H0","# $1 \n"); next; } # catch anything that wasnt match above. ProcessHistory("COMMENTS","keysort","H0","$_"); # end of config if (/^# End of configuration file/i) { printf STDERR " End WriteTerm: $_" if ($debug); $found_end = 1; return(0); } } if ($lines < 3) { printf(STDERR "ERROR: $host configuration appears to be truncated.\n"); $found_end = 0; return(-1); } $found_end = 1; return(0); } # dummy function sub DoNothing {print STDOUT;} # Main @commandtable = ( {'show version' => 'ShowVersion'}, {'show memory' => 'ShowMemory'}, {'show diag' => 'ShowDiag'}, {'show switch' => 'ShowSwitch'}, {'show slot' => 'ShowSlot'}, {'show configuration detail' => 'WriteTerm'}, {'show configuration' => 'WriteTerm'}, ); # 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("|", map quotemeta($_), @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 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 clogin -t $timeo -c \"$cisco_cmds\" $host\n" if ($debug); print STDOUT "executing clogin -t $timeo -c \"$cisco_cmds\" $host\n" if ($log); if (defined($ENV{NOPIPE}) && $ENV{NOPIPE} =~ /^YES/i) { system "clogin -t $timeo -c \"$cisco_cmds\" $host $host.raw 2>&1" || die "clogin failed for $host: $!\n"; open(INPUT, "< $host.raw") || die "clogin failed for $host: $!\n"; } else { open(INPUT,"clogin -t $timeo -c \"$cisco_cmds\" $host ) { tr/\015//d; # note: this match sucks rocks, but currently the extreme bits are # unreliable about echoing the 'exit\n' command. this match might really # be a bad idea, but instead rely upon WriteTerm's found_end? if (/$prompt\s?(quit|exit|Connection( to \S+)? closed)/ && $found_end) { $clean_run = 1; last; } if (/^Error:/) { print STDOUT ("$host clogin error: $_"); print STDERR ("$host clogin error: $_") if ($debug); $clean_run = 0; last; } while (/$prompt\s*($cmds_regexp)\s*$/) { $cmd = $1; if (!defined($prompt)) { $prompt = ($_ =~ /^([^#]+#)/)[0]; $prompt =~ s/([][}{)(\\])/\\$1/g; $prompt =~ s/[:.](\d+ ?)#/[:.]\\d+ ?#/; $prompt =~ s/\*/\\\*/; 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; } $rval = &{$commands{$cmd}}; delete($commands{$cmd}); if ($rval == -1) { printf STDERR "rval = -1\n" if ($debug); $clean_run = 0; last TOP; } } } print STDOUT "Done $logincmd: $_\n" if ($log); # Flush History ProcessHistory("","","",""); # Cleanup close(INPUT); close(OUTPUT); if (defined($ENV{NOPIPE}) && $ENV{NOPIPE} =~ /^YES/i) { 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); } rancid-2.3.8/bin/xrrancid.in100644 015615 000000 00000126757 11711603074 0011412#! @PERLV_PATH@ ## ## $Id: xrrancid.in 2369 2012-01-30 21:06:03Z heas $ ## ## @PACKAGE@ @VERSION@ ## Copyright (c) 1997-2010 by Terrapin Communications, Inc. ## All rights reserved. ## ## This code is derived from software contributed to and maintained by ## Terrapin Communications, Inc. by Henry Kilmer, John Heasley, Andrew Partan, ## Pete Whiting, Austin Schutz, and Andrew Fort. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions ## are met: ## 1. Redistributions of source code must retain the above copyright ## notice, this list of conditions and the following disclaimer. ## 2. Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## 3. All advertising materials mentioning features or use of this software ## must display the following acknowledgement: ## This product includes software developed by Terrapin Communications, ## Inc. and its contributors for RANCID. ## 4. Neither the name of Terrapin Communications, Inc. nor the names of its ## contributors may be used to endorse or promote products derived from ## this software without specific prior written permission. ## 5. It is requested that non-binding fixes and modifications be contributed ## back to Terrapin Communications, Inc. ## ## THIS SOFTWARE IS PROVIDED BY Terrapin Communications, INC. AND CONTRIBUTORS ## ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ## TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COMPANY OR CONTRIBUTORS ## BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ## CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ## SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ## INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ## CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ## ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ## POSSIBILITY OF SUCH DAMAGE. # # RANCID - Really Awesome New Cisco confIg Differ # # usage: rancid [-dV] [-l] [-f filename | hostname] # use Getopt::Std; getopts('dflV'); if ($opt_V) { print "@PACKAGE@ @VERSION@\n"; exit(0); } $log = $opt_l; $debug = $opt_d; $file = $opt_f; $host = $ARGV[0]; $proc = ""; $clean_run = 0; $found_end = 0; $found_version = 0; $found_env = 0; $found_diag = 0; $timeo = 90; # clogin timeout in seconds my(@commandtable, %commands, @commands);# command lists my($aclsort) = ("ipsort"); # ACL sorting mode my($config_register); # configuration register value my($filter_commstr); # SNMP community string filtering 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)) && scalar(%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 routine 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 routine 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 routine 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 routine (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 "admin show version" sub ShowVersion { print STDERR " In ShowVersion: $_" if ($debug); my($slaveslot); while () { tr/\015//d; if (/^$prompt/) { $found_version = 1; last}; next if (/^(\s*|\s*$cmd\s*)$/); return(1) if (/Line has invalid autocommand /); return(1) if (/(Invalid (input|command) detected|Type help or )/i); return(0) if ($found_version); # Only do this routine once return(-1) if (/command authorization failed/i); if (/^Slave in slot (\d+) is running/) { $slave = " Slave:"; $slaveslot = ", slot $1"; next; } /^(Cisco )?IOS .* Software,? \(([A-Za-z0-9_-]*)\), .*Version\s+(.*)$/ && ProcessHistory("COMMENTS","keysort","F1", "!Image:$slave Software: $2, $3\n") && next; /^([A-Za-z-0-9_]*) Synced to mainline version: (.*)$/ && ProcessHistory("COMMENTS","keysort","F2", "!Image:$slave $1 Synced to mainline version: $2\n") && next; /^Compiled (.*)$/ && ProcessHistory("COMMENTS","keysort","F3", "!Image:$slave Compiled: $1\n") && next; /^ROM: (IOS \S+ )?(System )?Bootstrap.*(Version.*)$/ && ProcessHistory("COMMENTS","keysort","G1", "!ROM Bootstrap: $3\n") && next; if (/^Hardware:\s+(.*), (.* RAM), CPU (.*)$/) { ProcessHistory("COMMENTS","keysort","A1", "!Chassis type: $1 - a PIX\n"); ProcessHistory("COMMENTS","keysort","A2", "!CPU: $3\n"); ProcessHistory("COMMENTS","keysort","B1", "!Memory: $2\n"); } /^Serial Number:\s+(.*)$/ && ProcessHistory("COMMENTS","keysort","C1", "!$_") && next; # More PIX stuff /^Encryption hardware device\s+:\s+(.*)/ && ProcessHistory("COMMENTS","keysort","A3", "!Encryption: $1\n") && next; /^running activation key\s*:\s+(.*)/i && ProcessHistory("COMMENTS","keysort","D2", "!Key: $1\n") && next; # Flash on the PIX or FWSM (FireWall Switch Module) /^Flash(\s+\S+)+ \@ 0x\S+,\s+(\S+)/ && ProcessHistory("COMMENTS","keysort","B2", "!Memory: Flash $2\n") && next; # CatOS 3500xl stuff /^System serial number(:\s+.*)$/ && ProcessHistory("COMMENTS","keysort","C1", "!Serial Number$1\n") && next; /^Model / && ProcessHistory("COMMENTS","keysort","C2", "!$_") && next; /^Motherboard / && ProcessHistory("COMMENTS","keysort","C3", "!$_") && next; /^Power supply / && ProcessHistory("COMMENTS","keysort","C4", "!$_") && next; /^Activation Key:\s+(.*)$/ && ProcessHistory("COMMENTS","keysort","C2", "!$_") && next; /^ROM: \d+ Bootstrap .*(Version.*)$/ && ProcessHistory("COMMENTS","keysort","G2", "!ROM Image: Bootstrap $1\n!\n") && next; /^ROM: .*(Version.*)$/ && ProcessHistory("COMMENTS","keysort","G3","!ROM Image: $1\n") && next; /^BOOTFLASH: .*(Version.*)$/ && ProcessHistory("COMMENTS","keysort","G4","!BOOTFLASH: $1\n") && next; /^BOOTLDR: .*(Version.*)$/ && ProcessHistory("COMMENTS","keysort","G4","!BOOTLDR: $1\n") && next; /^System image file is "([^\"]*)", booted via (\S*)/ && # removed the booted source due to # CSCdk28131: cycling info in 'sh ver' # ProcessHistory("COMMENTS","keysort","F4","!Image: booted via $2, $1\n") && ProcessHistory("COMMENTS","keysort","F4","!Image: booted $1\n") && next; /^System image file is "([^\"]*)"$/ && ProcessHistory("COMMENTS","keysort","F5","!Image: $1\n") && next; if (/(\S+(?:\sseries)?)\s+(?:\((\S+)\)\s+processor|\(revision[^)]+\)).*\s+with (\S+k) bytes/i) { $proc = $1; my($cpu) = $2; my($mem) = $3; my($device) = "router"; # the next line ought to be the more specific cpu info, grab it. # yet, some boards/IOS vers have a processor ID line between these # two. grrr. make sure we dont grab the "software" junk that # follows these lines by looking for "CPU at " or the 2600s # "processor: " unique string. there are undoubtedly many other # incantations. for a slave, we dont get this info, its just a # blank line. $_ = ; if (/processor board id/i) { my($sn); if (/processor board id (\S+)/i) { $sn = $1; $sn =~ s/,$//; ProcessHistory("COMMENTS","keysort","D9", "!Processor ID: $sn\n"); } $_ = ; } $_ = "" if (! /(cpu at |processor: |$cpu processor,)/i); tr/\015//d; s/implementation/impl/i; if ($_ !~ /^\s*$/) { chomp; s/^/, /; } if ($proc eq "CSC") { $type = "AGS"; } elsif ($proc eq "CSC4") { $type = "AGS+"; } elsif ($proc =~ /1900/) { $type = "1900"; $device = "switch"; } elsif ($proc =~ /^(AS)?25[12][12]/) { $type = "2500"; } elsif ($proc =~ /261[01]/ || $proc =~ /262[01]/ ) { $type = "2600"; } elsif ($proc =~ /WS-C29/) { $type = "2900XL"; $device = "switch"; } elsif ($proc =~ /WS-C355/) { $type = "3550"; $device = "switch"; } elsif ($proc =~ /WS-C35/) { $type = "3500XL"; $device = "switch"; } elsif ($proc =~ /^36[0246][0-9]/) { $type = "3600"; } elsif ($proc =~ /^37/) { $type = "3700"; } elsif ($proc =~ /^38/) { $type = "3800"; } elsif ($proc =~ /WS-C45/) { $type = "4500"; $device = "switch"; } elsif ( $proc =~ /^AS5300/) { $type = "AS5300"; } elsif ( $proc =~ /^AS5350/) { $type = "AS5350"; } elsif ( $proc =~ /^AS5400/) { $type = "AS5400"; } elsif ($proc =~ /6000/) { $type = "6000"; $device = "switch"; } elsif ($proc eq "WK-C65") { $type = "6500"; } elsif ($proc eq "RP") { $type = "7000"; } elsif ($proc eq "RP1") { $type = "7000"; } elsif ($proc =~ /720[246]/) { $type = "7200"; } elsif ( $proc =~ /^73/) { $type = "7300"; } elsif ($proc eq "RSP7000") { $type = "7500"; } elsif ($proc =~ /RSP\d/) { $type = "7500"; } elsif ($proc =~ /OSR-76/) { $type = "7600"; } elsif ($proc =~ /CISCO76/) { $type = "7600"; } elsif ($proc =~ /1200[48]\/(GRP|PRP)/ || $proc =~ /1201[26]\/(GRP|PRP)/) { $type = "12000"; } elsif ($proc =~ /1201[26]-8R\/(GRP|PRP)/) { $type = "12000"; } elsif ($proc =~ /1240[48]\/(GRP|PRP)/ || $proc =~ /1241[06]\/(GRP|PRP)/) { $type = "12400"; } else { $type = $proc; } print STDERR "TYPE = $type\n" if ($debug); ProcessHistory("COMMENTS","keysort","A1", "!Chassis type:$slave $proc - a $type $device\n"); ProcessHistory("COMMENTS","keysort","B1", "!Memory:$slave main $mem\n"); if (defined($cpu)) { ProcessHistory("COMMENTS","keysort","A3", "!CPU:$slave $cpu$_$slaveslot\n"); } next; } if (/(\S+) Silicon\s*Switch Processor/) { if (!defined($C0)) { $C0 = 1; ProcessHistory("COMMENTS","keysort","C0","!\n"); } ProcessHistory("COMMENTS","keysort","C2","!SSP: $1\n"); $ssp = 1; $sspmem = $1; next; } /^(\d+[kK]) bytes of multibus/ && ProcessHistory("COMMENTS","keysort","B2", "!Memory: multibus $1\n") && next; /^(\d+[kK]) bytes of (non-volatile|NVRAM)/ && ProcessHistory("COMMENTS","keysort","B3", "!Memory: nvram $1\n") && next; /^(\d+[kK]) bytes of flash memory/ && ProcessHistory("COMMENTS","keysort","B5","!Memory: flash $1\n") && next; /^(\d+[kK]) bytes of .*flash partition/ && ProcessHistory("COMMENTS","keysort","B6", "!Memory: flash partition $1\n") && next; /^(\d+[kK]) bytes of Flash internal/ && ProcessHistory("COMMENTS","keysort","B4", "!Memory: bootflash $1\n") && next; if (/^(\d+[kK]) bytes of (Flash|ATA)?.*PCMCIA .*(slot|disk) ?(\d)/i) { ProcessHistory("COMMENTS","keysort","B7", "!Memory: pcmcia $2 $3$4 $1\n"); next; } if (/^(\d+[kK]) bytes of (slot|disk)(\d)/i) { ProcessHistory("COMMENTS","keysort","B7", "!Memory: pcmcia $2$3 $1\n"); next; } if (/^WARNING/) { if (!defined($I0)) { $I0 = 1; ProcessHistory("COMMENTS","keysort","I0","!\n"); } ProcessHistory("COMMENTS","keysort","I1","! $_"); } if (/^Configuration register is (.*)$/) { $config_register = $1; next; } if (/^Configuration register on node \S+ is (.*)$/) { $config_register = $1 if (length($config_register) < 1); next; } } return(0); } # This routine parses "admin show diag". # This will create arrays for hw info. sub AdminShowDiag { print STDERR " In ShowDiag: $_" if ($debug); while () { tr/\015//d; if (/^$prompt/) { $found_diag = 1; last}; next if (/^(\s*|\s*$cmd\s*)$/); return(1) if (/Line has invalid autocommand /); return(1) if (/(Invalid (input|command) detected|Type help or )/i); return(-1) if (/command authorization failed/i); /^$/ && next; s/^NODE //; # wtf are these? next if (/(New Deviation|UDI_VID|Board State)/); # skip insertion time next if (/insertion time/i); # skip board h/w revision junk next if (/^(\s{2}board |\s{3,})/i); ProcessHistory("SLOT","","","!$_"); } ProcessHistory("SLOT","","","!\n"); return(0); } # This routine parses "admin show running". # This will create arrays for hw info. sub AdminShowRunning { print STDERR " In ShowRunning: $_" if ($debug); while () { tr/\015//d; if (/^$prompt/) { $found_diag = 1; last}; next if (/^(\s*|\s*$cmd\s*)$/); return(1) if (/Line has invalid autocommand /); return(1) if (/(Invalid (input|command) detected|Type help or )/i); return(-1) if (/command authorization failed/i); /^$/ && next; /^building configuration/i && next; if (/^(\s*secret) / && $filter_pwds >= 2) { ProcessHistory("SLOT","","","!$1 \n"); next; } /^end$/ && last; ProcessHistory("SLOT","","","!$_"); } ProcessHistory("SLOT","","","!\n"); return(0); } # This routine parses "admin show redundancy" sub ShowRedundancy { print STDERR " In ShowRedundancy: $_" if ($debug); while () { tr/\015//d; last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); return(1) if (/Line has invalid autocommand /); return(1) if (/(Invalid (input|command) detected|Type help or )/i); if (/^Version information for secondary in slot (\d+):/) { $slave = " Slave:"; $slaveslot = ", slot $1"; next; } /^IOS .* Software \(([A-Za-z0-9_-]*)\), .*Version\s+(.*)$/ && ProcessHistory("COMMENTS","keysort","F1", "!Image:$slave Software: $1, $2\n") && next; /^Compiled (.*)$/ && ProcessHistory("COMMENTS","keysort","F3", "!Image:$slave Compiled: $1\n") && next; } return(0); } # This routine parses "show install active" sub ShowInstallActive { print STDERR " In ShowInstallActive: $_" if ($debug); while () { tr/\015//d; last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); return(1) if (/^\s*\^\s*$/); return(1) if (/Line has invalid autocommand /); return(1) if (/(Invalid (input|command) detected|Type help or )/i); return(-1) if (/command authorization failed/i); ProcessHistory("COMMENTS","keysort","F5","!Image: $_") && next; } return(0); } # This routine parses "admin show env all" sub ShowEnv { # Skip if this is not a 7500, 7200, or 7000. print STDERR " In ShowEnv: $_" if ($debug); while () { tr/\015//d; if (/^$prompt/) { $found_env = 1; last}; next if (/^(\s*|\s*$cmd\s*)$/); #return(1) if ($type !~ /^7/); return(1) if (/Line has invalid autocommand /); return(1) if (/(Invalid (input|command) detected|Type help or )/i); return(0) if ($found_env); # Only do this routine once return(-1) if (/command authorization failed/i); if (!defined($E0)) { $E0 = 1; ProcessHistory("COMMENTS","keysort","E0","!\n"); } if (/^Arbiter type (\d), backplane type (\S+)/) { if (!defined($C0)) { $C0 = 1; ProcessHistory("COMMENTS","keysort","C0","!\n"); } ProcessHistory("COMMENTS","keysort","C1", "!Enviromental Arbiter Type: $1\n"); ProcessHistory("COMMENTS","keysort","A2", "!Chassis type: $2 backplane\n"); next; } /^Power Supply Information$/ && next; /^\s*Power Module\s+Voltage\s+Current$/ && next; /^\s*(Power [^:\n]+)$/ && ProcessHistory("COMMENTS","keysort","E1","!Power: $1\n") && next; /^\s*(Lower Power .*)/i && ProcessHistory("COMMENTS","keysort","E2","!Power: $1\n") && next; /^\s*(redundant .*)/i && ProcessHistory("COMMENTS","keysort","E2","!Power: $1\n") && next; /^\s*(RPS is .*)/i && ProcessHistory("COMMENTS","keysort","E2","!Power: $1\n") && next; } ProcessHistory("COMMENTS","","","!\n"); return(0); } # This routine parses "dir /all ((disk|slot)N|bootflash|nvram):" sub DirSlotN { print STDERR " In DirSlotN: $_" if ($debug); my($dev) = (/\s([^\s]+):/); while () { tr/\015//d; last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); return(1) if /^\s*\^\s*$/; return(1) if (/Line has invalid autocommand /); return(1) if (/(Invalid (input|command) detected|Type help or )/i); return(1) if (/(No such device|Error Sending Request)/i); return(1) if (/\%Error: No such file or directory/); return(1) if (/No space information available/); # Corrupt flash /\%Error calling getdents / && ProcessHistory("FLASH","","","!Flash: $dev: $_") && next; return(-1) if (/\%Error calling/); return(-1) if (/(: device being squeezed|ATA_Status time out)/i); # busy return(-1) if (/\%Error opening \S+:\S+ \(Device or resource busy\)/i); return(-1) if (/command authorization failed/i); return(1) if (/(Open device \S+ failed|Error opening \S+:)/); # filter frequently changing files from IOX bootflash if ($dev =~ /bootflash/) { next if (/temp_cont\s*$/); next if (/uptime_cont\s*$/); } # Filter dhcp database if (/dhcp_[^. ]*\.txt/) { next; } # Filter debugging file dlbg.txt & dlbg.txt-1 only on ASR9k w/ XR if ($proc =~ /ASR9K/ && /dlbg\.txt/) { next; } if (/.*\((\d+) bytes free\)/) { my($tmp) = $1; if ($tmp >= (1024 * 1024 * 1024)) { $tmp = int($tmp / (1024 * 1024 * 1024)); s/$1 bytes free/$tmp GB free/; } else { $tmp = int($tmp / (1024 * 1024)); s/$1 bytes free/$tmp MB free/; } } ProcessHistory("FLASH","","","!Flash: $dev: $_"); } ProcessHistory("","","","!\n"); return(0); } # This routine parses "admin show variables boot" sub ShowBootVar { print STDERR " In ShowBootVar: $_" if ($debug); while () { # delete non-ascii chars, except new line tr/ -~\n//cd; last if (/^$prompt/); next if (/\s*$cmd\s*$/); return(1) if (/^\s*\^\s*$/); return(1) if (/Line has invalid autocommand /); return(1) if (/(Invalid (input|command) detected|Type help or )/i); return(1) if (/Ambiguous command/i); return(1) if (/(Open device \S+ failed|Error opening \S+:)/); return(-1) if (/command authorization failed/i); # skip blank lines next if (/^\s*$/); ProcessHistory("COMMENTS", "keysort", "C30", "! $_"); } ProcessHistory("COMMENTS", "keysort", "C39", "!\n"); return(0); } # This routine parses "show controllers" sub ShowContAll { # Skip if this is a 70[01]0, 7500, or 12000. print STDERR " In ShowContAll: $_" if ($debug); while () { tr/\015//d; last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); return(1) if (/(Invalid (input|command) detected|Type help or )/i); # return(1) if ($type =~ /^(12[40]|7[05])/); return(-1) if (/command authorization failed/i); if (/^Interface ([^ \n(]*)/) { $INT = "$1, "; next; } /^(BRI unit \d)/ && ProcessHistory("INT","","","!Interface: $1\n") && next; /^LANCE unit \d, NIM/ && ProcessHistory("INT","","","!Interface: $_") && next; /^(LANCE unit \d)/ && ProcessHistory("INT","","","!Interface: $1\n") && next; /(Media Type is \S+),/ && ProcessHistory("INT","","","!\t$1\n"); if (/(M\dT[^ :]*:) show controller:$/) { my($ctlr) = $1; $_ = ; tr/\015//d; s/ subunit \d,//; ProcessHistory("INT","","","!Interface: $ctlr $_"); } if (/^(\S+) : show controller:$/) { my($ctlr) = $1; $_ = ; tr/\015//d; s/ subunit \d,//; ProcessHistory("INT","","","!Interface: $ctlr: $_"); } /^(HD unit \d), idb/ && ProcessHistory("INT","","","!Interface: $1\n") && next; /^HD unit \d, NIM/ && ProcessHistory("INT","","","!Interface: $_") && next; /^buffer size \d+ HD unit \d, (.*)/ && ProcessHistory("INT","","","!\t$1\n") && next; /^AM79970 / && ProcessHistory("INT","","","!Interface: $_") && next; /^buffer size \d+ (Universal Serial: .*)/ && ProcessHistory("INT","","","!\t$1\n") && next; /^Hardware is (.*)/ && ProcessHistory("INT","","","!Interface: $INT$1\n") && next; /^(QUICC Serial unit \d),/ && ProcessHistory("INT","","","!$1\n") && next; /^QUICC Ethernet .*/ && ProcessHistory("INT","","","!$_") && next; /^DTE .*\.$/ && ProcessHistory("INT","","","!\t$_") && next; /^(cable type :.*),/ && ProcessHistory("INT","","","!\t$1\n") && next; /^(.* cable.*), received clockrate \d+$/ && ProcessHistory("INT","","","!\t$1\n") && next; /^.* cable.*$/ && ProcessHistory("INT","","","!\t$_") && next; } return(0); } # This routine parses "show debug" sub ShowDebug { print STDERR " In ShowDebug: $_" if ($debug); my($lines) = 0; while () { tr/\015//d; last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); return(1) if (/Line has invalid autocommand /); return(1) if (/(Invalid (input|command) detected|Type help or )/i); return(-1) if (/command authorization failed/i); /^No matching debug flags set$/ && next; /^No debug flags set$/ && next; ProcessHistory("COMMENTS","keysort","J1","!DEBUG: $_"); $lines++; } if ($lines) { ProcessHistory("COMMENTS","keysort","J0","!\n"); } return(0); } # This routine parses "admin show install summary" sub ShowInstallSummary { print STDERR " In ShowInstallSummary: $_" if ($debug); while () { # delete non-ascii chars, except new line tr/ -~\n//cd; last if (/^$prompt/); next if (/\s*$cmd\s*$/); return(1) if (/^\s*\^\s*$/); return(1) if (/Line has invalid autocommand /); return(1) if (/(Invalid (input|command) detected|Type help or )/i); return(1) if (/Ambiguous command/i); return(1) if (/(Open device \S+ failed|Error opening \S+:)/); return(-1) if (/command authorization failed/i); # skip blank lines next if (/^\s*$/); ProcessHistory("COMMENTS", "keysort", "C15", "! $_"); } ProcessHistory("COMMENTS", "keysort", "C10", "!\n"); ProcessHistory("COMMENTS", "keysort", "C19", "!\n"); return(0); } # This routine parses "show inventory". sub ShowInventory { print STDERR " In ShowInventory: $_" if ($debug); while () { # delete non-ascii chars, except new line tr/ -~\n//cd; return if (/^\s*\^$/); last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); return(1) if (/Line has invalid autocommand /); return(1) if (/(Invalid (input|command) detected|Type help or )/i); return(-1) if (/command authorization failed/i); # remove spaces after quotes s/\"\s+/\"/g; if (/^(NAME: "[^"]*",) (DESCR: "[^"]+")/) { ProcessHistory("INVENTORY","","", sprintf("!%-30s %s\n", $1, $2)); next; } # split PID/VID/SN line if (/^PID: (\S*)\s*, VID: (\S*)\s*, SN: (\S*)\s*$/) { my($pid,$vid,$sn) = ($1, $2, $3); my($entries) = ""; # filter , "0x" and "N/A" lines if ($pid !~ /^(|0x|N\/A)$/) { $entries .= "!PID: $pid\n"; } if ($vid !~ /^(|0x|N\/A)$/) { $entries .= "!VID: $vid\n"; } if ($sn !~ /^(|0x|N\/A)$/) { $entries .= "!SN: $sn\n"; } ProcessHistory("INVENTORY","","", "$entries"); next; } ProcessHistory("INVENTORY","","","!$_"); } ProcessHistory("INVENTORY","","","!\n"); return(0); } # This routine parses "admin show license" sub ShowLicense { print STDERR " In ShowLicense: $_" if ($debug); while () { # delete non-ascii chars, except new line tr/ -~\n//cd; last if (/^$prompt/); next if (/\s*$cmd\s*$/); return(1) if (/^\s*\^\s*$/); return(1) if (/Line has invalid autocommand /); return(1) if (/(Invalid (input|command) detected|Type help or )/i); return(1) if (/Ambiguous command/i); return(1) if (/(Open device \S+ failed|Error opening \S+:)/); return(-1) if (/command authorization failed/i); # skip blank lines next if (/^\s*$/); ProcessHistory("COMMENTS", "keysort", "C20", "! $_"); } ProcessHistory("COMMENTS", "keysort", "C29", "!\n"); return(0); } # This routine parses "show rpl maximum" sub ShowRPL { print STDERR " In ShowRPL: $_" if ($debug); while () { tr/\015//d; last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); return(1) if /^\s*\^\s*$/; return(1) if (/Line has invalid autocommand /); return(1) if (/(Invalid (input|command) detected|Type help or )/i); return(1) if (/Ambiguous command/i); return(-1) if (/command authorization failed/i); ProcessHistory("COMMENTS","keysort","RPLMAX","! $_"); } ProcessHistory("COMMENTS","keysort","RPLMAX","!\n"); return(0); } # This routine parses "show vlan" sub ShowVLAN { print STDERR " In ShowVLAN: $_" if ($debug); ($_ = , return(1)) if (!$DO_SHOW_VLAN); while () { tr/\015//d; last if (/^$prompt/); next if (/^(\s*|\s*$cmd\s*)$/); return(1) if /^\s*\^\s*$/; return(1) if (/Line has invalid autocommand /); return(1) if (/(Invalid (input|command) detected|Type help or )/i); return(1) if (/Ambiguous command/i); return(-1) if (/command authorization failed/i); ProcessHistory("COMMENTS","keysort","IO","!VLAN: $_"); } ProcessHistory("COMMENTS","keysort","IO","!\n"); return(0); } # This routine processes a "write term" sub WriteTerm { print STDERR " In WriteTerm: $_" if ($debug); my($lineauto,$comment,$linecnt) = (0,0,0); while () { tr/\015//d; last if (/^$prompt/); return(1) if (!$linecnt && /^\s+\^\s*$/); return(1) if (/Line has invalid autocommand /); return(1) if (/(Invalid (input|command) detected|Type help or )/i); return(1) if (/\%Error: No such file or directory/); return(0) if ($found_end); # Only do this routine once return(-1) if (/command authorization failed/i); return(-1) if (/% ?configuration buffer full/i); /^! no configuration change since last restart/i && next; # skip emtpy lines at the beginning if (!$linecnt && /^\s*$/) { next; } if (!$linecnt && defined($config_register)) { ProcessHistory("","","", "!\nconfig-register $config_register\n"); } /Non-Volatile memory is in use/ && return(-1); # NvRAM is locked /% Configuration buffer full, / && return(-1); # buffer is in use $linecnt++; $lineauto = 0 if (/^[^ ]/); # skip the crap if (/^(##+|(building|current) configuration)/i) { while () { next if (/^Current configuration\s*:/i); next if (/^:/); next if (/^([%!].*|\s*)$/); next if (/^ip add.*ipv4:/); # band-aid for 3620 12.0S last; } tr/\015//d; } # some versions have other crap mixed in with the bits in the # block above /^! (Last configuration|NVRAM config last)/ && next; # and for the ASA /^: (Written by \S+ at|Saved)/ && next; # skip consecutive comment lines to avoid oscillating extra comment # line on some access servers. grrr. if (/^!\s*$/) { next if ($comment); ProcessHistory("","","",$_); $comment++; next; } $comment = 0; # 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 /^ clockrate / && next; # kill clockrate on serial interfaces if (/^(enable )?(password|passwd)( level \d+)? / && $filter_pwds >= 1) { ProcessHistory("ENABLE","","","!$1$2$3 \n"); next; } if (/^(enable secret) / && $filter_pwds >= 2) { ProcessHistory("ENABLE","","","!$1 \n"); next; } if (/^username (\S+)(\s.*)? secret /) { if ($filter_pwds >= 2) { ProcessHistory("USER","keysort","$1", "!username $1$2 secret \n"); } else { ProcessHistory("USER","keysort","$1","$_"); } next; } if (/^username (\S+)(\s.*)? password ((\d) \S+|\S+)/) { if ($filter_pwds >= 2) { ProcessHistory("USER","keysort","$1", "!username $1$2 password \n"); } elsif ($filter_pwds >= 1 && $4 ne "5"){ ProcessHistory("USER","keysort","$1", "!username $1$2 password \n"); } else { ProcessHistory("USER","keysort","$1","$_"); } next; } if (/^( set session-key (in|out)bound ah \d+ )/ && $filter_pwds >= 1) { ProcessHistory("","","","!$1\n"); next; } if (/^( set session-key (in|out)bound esp \d+ (authenticator|cypher) )/ && $filter_pwds >= 1) { ProcessHistory("","","","!$1\n"); next; } if (/^(\s*)password / && $filter_pwds >= 1) { ProcessHistory("LINE-PASS","","","!$1password \n"); next; } if (/^(\s*)secret / && $filter_pwds >= 2) { ProcessHistory("LINE-PASS","","","!$1secret \n"); next; } if (/^\s*neighbor (\S*) password / && $filter_pwds >= 1) { ProcessHistory("","","","! neighbor $1 password \n"); next; } if (/^(ppp .* password) 7 .*/ && $filter_pwds >= 1) { ProcessHistory("","","","!$1 \n"); next; } if (/^(ip ftp password) / && $filter_pwds >= 1) { ProcessHistory("","","","!$1 \n"); next; } if (/^( ip ospf authentication-key) / && $filter_pwds >= 1) { ProcessHistory("","","","!$1 \n"); next; } # isis passwords appear to be completely plain-text if (/^\s+isis password (\S+)( .*)?/ && $filter_pwds >= 1) { ProcessHistory("","","","!isis password $2\n"); next; } if (/^\s+(domain-password|area-password) (\S+)( .*)?/ && $filter_pwds >= 1) { ProcessHistory("","","","!$1 $3\n"); next; } # this is reversable, despite 'md5' in the cmd if (/^( ip ospf message-digest-key \d+ md5) / && $filter_pwds >= 1) { ProcessHistory("","","","!$1 \n"); next; } # this is also reversable, despite 'md5 encrypted' in the cmd if (/^( message-digest-key \d+ md5 (7|encrypted)) / && $filter_pwds >= 1) { ProcessHistory("","","","!$1 \n"); next; } if (/^((crypto )?isakmp key) \S+ / && $filter_pwds >= 1) { ProcessHistory("","","","!$1 $'"); next; } # filter HSRP passwords if (/^(\s+standby \d+ authentication) / && $filter_pwds >= 1) { ProcessHistory("","","","!$1 \n"); next; } # this appears in "measurement/sla" images if (/^(\s+key-string \d?)/ && $filter_pwds >= 1) { ProcessHistory("","","","!$1 \n"); next; } if (/^( l2tp tunnel \S+ password)/ && $filter_pwds >= 1) { ProcessHistory("","","","!$1 \n"); next; } # i am told these are plain-text on the PIX if (/^(vpdn username (\S+) password)/) { if ($filter_pwds >= 1) { ProcessHistory("USER","keysort","$2","!$1 \n"); } else { ProcessHistory("USER","keysort","$2","$_"); } next; } # ASA/PIX keys in more system:running-config if (/^( pre-shared-key | key |failover key ).*/ && $filter_pwds >= 1) { ProcessHistory("","","","!$1 $'"); next; } if (/(\s+ldap-login-password )\S+(.*)/ && $filter_pwds >= 1) { ProcessHistory("","","","!$1 $'"); next; } # if (/^( cable shared-secret )/ && $filter_pwds >= 1) { ProcessHistory("","","","!$1 \n"); next; } /fair-queue individual-limit/ && next; # sort ip explicit-paths. if (/^ip explicit-path name (\S+)/) { my($key) = $1; my($expath) = $_; while () { tr/\015//d; last if (/^$prompt/); last if (! /^(ip explicit-path name |[ !])/); if (/^ip explicit-path name (\S+)/) { ProcessHistory("EXPATH","keysort","$key","$expath"); $key = $1; $expath = $_; } else { $expath .= $_; } } ProcessHistory("EXPATH","keysort","$key","$expath"); } # sort route-maps if (/^route-map (\S+)/) { my($key) = $1; my($routemap) = $_; while () { tr/\015//d; last if (/^$prompt/ || ! /^(route-map |[ !])/); if (/^route-map (\S+)/) { ProcessHistory("ROUTEMAP","keysort","$key","$routemap"); $key = $1; $routemap = $_; } else { $routemap .= $_; } } ProcessHistory("ROUTEMAP","keysort","$key","$routemap"); } # filter out any RCS/CVS tags to avoid confusing local CVS storage s/\$(Revision|Id):/ $1:/; # order access-lists /^access-list\s+(\d\d?)\s+(\S+)\s+(\S+)/ && ProcessHistory("ACL $1 $2","$aclsort","$3","$_") && next; # order extended access-lists /^access-list\s+(\d\d\d)\s+(\S+)\s+ip\s+host\s+(\S+)/ && ProcessHistory("EACL $1 $2","$aclsort","$3","$_") && next; /^access-list\s+(\d\d\d)\s+(\S+)\s+ip\s+(\d\S+)/ && ProcessHistory("EACL $1 $2","$aclsort","$3","$_") && next; /^access-list\s+(\d\d\d)\s+(\S+)\s+ip\s+any/ && ProcessHistory("EACL $1 $2","$aclsort","0.0.0.0","$_") && next; # sort ipv{4,6} access-lists if (/^ipv(4|6) access-list (\S+)\s*$/) { my($nlri, $key) = ($1, $2); my($seq, $cmd); ProcessHistory("ACL $nlri $key","","","$_"); while () { tr/\015//d; last if (/^$prompt/ || /^\S/); ($seq, $cmd, $misc, $ip) = ($_ =~ /^\s+(\d+) (\w+) (.*\s)(\w+)/); if ($cmd =~ /(permit|deny)/) { ProcessHistory("ACL $nlri $key $cmd","$aclsort","$ip", " $cmd $misc$ip\n"); } else { ProcessHistory("ACL $nlri $key","",""," $cmd $misc$ip\n"); } } } # order arp lists /^arp\s+(\d+\.\d+\.\d+\.\d+)\s+/ && ProcessHistory("ARP","$aclsort","$1","$_") && next; /^ip prefix-list\s+(\S+)\s+seq\s+(\d+)\s+(permit|deny)\s+(\d\S+)(\/.*)$/ && ProcessHistory("PACL $1 $3","$aclsort","$4","ip prefix-list $1 $3 $4$5\n") && next; # order logging statements /^logging (\d+\.\d+\.\d+\.\d+)/ && ProcessHistory("LOGGING","ipsort","$1","$_") && next; # order/prune snmp-server host statements # we only prune lines of the form # snmp-server host a.b.c.d if (/^snmp-server host (\d+\.\d+\.\d+\.\d+) /) { if ($filter_commstr) { my($ip) = $1; my($line) = "snmp-server host $ip"; my(@tokens) = split(' ', $'); my($token); while ($token = shift(@tokens)) { if ($token eq 'version') { $line .= " " . join(' ', ($token, shift(@tokens))); if ($token eq '3') { $line .= " " . join(' ', ($token, shift(@tokens))); } } elsif ($token eq 'vrf') { $line .= " " . join(' ', ($token, shift(@tokens))); } elsif ($token =~ /^(informs?|traps?|(no)?auth)$/) { $line .= " " . $token; } else { $line = "!$line " . join(' ', ("", join(' ',@tokens))); last; } } ProcessHistory("SNMPSERVERHOST","ipsort","$ip","$line\n"); } else { ProcessHistory("SNMPSERVERHOST","ipsort","$1","$_"); } next; } if (/^(snmp-server community) (\S+)/) { if ($filter_commstr) { ProcessHistory("SNMPSERVERCOMM","keysort","$_", "!$1 $'") && next; } else { ProcessHistory("SNMPSERVERCOMM","keysort","$_","$_") && next; } } # prune tacacs/radius server keys if (/^((tacacs|radius)-server\s(\w*[-\s(\s\S+])*\s?key) (\d )?\w+/ && $filter_pwds >= 1) { ProcessHistory("","","","!$1 $'"); next; } # order clns host statements /^clns host \S+ (\S+)/ && ProcessHistory("CLNS","keysort","$1","$_") && next; # order alias statements /^alias / && ProcessHistory("ALIAS","keysort","$_","$_") && next; # delete ntp auth password - this md5 is a reversable too if (/^(ntp authentication-key \d+ md5) / && $filter_pwds >= 1) { ProcessHistory("","","","!$1 \n"); next; } # order ntp peers/servers if (/^ntp (server|peer) (\d+)\.(\d+)\.(\d+)\.(\d+)/) { $sortkey = sprintf("$1 %03d%03d%03d%03d",$2,$3,$4,$5); ProcessHistory("NTP","keysort",$sortkey,"$_"); next; } # order ip host statements /^ip host (\S+) / && ProcessHistory("IPHOST","keysort","$1","$_") && next; # order ip nat source static statements /^ip nat (\S+) source static (\S+)/ && ProcessHistory("IP NAT $1","ipsort","$2","$_") && next; # order atm map-list statements /^\s+ip\s+(\d+\.\d+\.\d+\.\d+)\s+atm-vc/ && ProcessHistory("ATM map-list","ipsort","$1","$_") && next; # order ip rcmd lines /^ip rcmd/ && ProcessHistory("RCMD","keysort","$_","$_") && next; # system controller /^syscon address (\S*) (\S*)/ && ProcessHistory("","","","!syscon address $1 \n") && next; if (/^syscon password (\S*)/ && $filter_pwds >= 1) { ProcessHistory("","","","!syscon password \n"); next; } /^ *Cryptochecksum:/ && next; # catch anything that wasnt matched above. ProcessHistory("","","","$_"); # end of config. if (/^end$/) { $found_end = 1; return(0); } } return(0); } # This routine processes a "write term" sub FilterAll { print STDERR " In FilterAll: $_" if ($debug); while () { tr/\015//d; last if (/^$prompt/); return(1) if (/Line has invalid autocommand /); return(1) if (/(Invalid (input|command) detected|Type help or )/i); return(1) if (/\%Error: No such file or directory/); return(-1) if (/command authorization failed/i); return(-1) if (/% ?configuration buffer full/i); } } # dummy function sub DoNothing {print STDOUT;} # Main @commandtable = ( # Disable timestamps in output {'terminal no-timestamp' => 'FilterAll' }, # XR 3.6 style {'terminal exec prompt no-timestamp' => 'FilterAll' }, # XR 3.8 style {'admin show version' => 'ShowVersion'}, # XR IMAGE commands {'admin show install summary' => 'ShowInstallSummary'}, {'admin show license' => 'ShowLicense'}, {'admin show variables boot' => 'ShowBootVar'}, {'show redundancy secondary' => 'ShowRedundancy'}, {'show install active' => 'ShowInstallActive'}, {'admin show env all' => 'ShowEnv'}, {'dir /all nvram:' => 'DirSlotN'}, {'dir /all bootflash:' => 'DirSlotN'}, {'dir /all compactflash:' => 'DirSlotN'}, {'dir /all compactflasha:' => 'DirSlotN'}, {'dir /all slot0:' => 'DirSlotN'}, {'dir /all disk0:' => 'DirSlotN'}, {'dir /all disk0a:' => 'DirSlotN'}, {'dir /all slot1:' => 'DirSlotN'}, {'dir /all disk1:' => 'DirSlotN'}, {'dir /all disk1a:' => 'DirSlotN'}, {'dir /all slot2:' => 'DirSlotN'}, {'dir /all disk2:' => 'DirSlotN'}, {'dir /all harddisk:' => 'DirSlotN'}, {'dir /all harddiska:' => 'DirSlotN'}, {'dir /all harddiskb:' => 'DirSlotN'}, {'dir /all slavenvram:' => 'DirSlotN'}, {'dir /all slavebootflash:' => 'DirSlotN'}, {'dir /all slaveslot0:' => 'DirSlotN'}, {'dir /all slavedisk0:' => 'DirSlotN'}, {'dir /all slaveslot1:' => 'DirSlotN'}, {'dir /all slavedisk1:' => 'DirSlotN'}, {'dir /all slaveslot2:' => 'DirSlotN'}, {'dir /all slavedisk2:' => 'DirSlotN'}, {'dir /all sec-nvram:' => 'DirSlotN'}, {'dir /all sec-bootflash:' => 'DirSlotN'}, {'dir /all sec-slot0:' => 'DirSlotN'}, {'dir /all sec-disk0:' => 'DirSlotN'}, {'dir /all sec-slot1:' => 'DirSlotN'}, {'dir /all sec-disk1:' => 'DirSlotN'}, {'dir /all sec-slot2:' => 'DirSlotN'}, {'dir /all sec-disk2:' => 'DirSlotN'}, {'show controllers' => 'ShowContAll'}, {'admin show running' => 'AdminShowRunning'}, {'admin show diag' => 'AdminShowDiag'}, {'admin show inventory raw' => 'ShowInventory'}, {'show vlan' => 'ShowVLAN'}, {'show debug' => 'ShowDebug'}, {'show rpl maximum' => 'ShowRPL'}, {'show running-config' => 'WriteTerm'}, ); # 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("|", map quotemeta($_), @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 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 clogin -t $timeo -c\"$cisco_cmds\" $host\n" if ($debug); print STDOUT "executing clogin -t $timeo -c\"$cisco_cmds\" $host\n" if ($log); if (defined($ENV{NOPIPE}) && $ENV{NOPIPE} =~ /^YES/i) { system "clogin -t $timeo -c \"$cisco_cmds\" $host $host.raw 2>&1" || die "clogin failed for $host: $!\n"; open(INPUT, "< $host.raw") || die "clogin failed for $host: $!\n"; } else { open(INPUT,"clogin -t $timeo -c \"$cisco_cmds\" $host ) { tr/\015//d; if (/[>#]\s?exit$/) { $clean_run = 1; last; } if (/^Error:/) { print STDOUT ("$host clogin error: $_"); print STDERR ("$host clogin error: $_") if ($debug); $clean_run = 0; last; } while (/#\s*($cmds_regexp)\s*$/) { $cmd = $1; 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; } $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}) && $ENV{NOPIPE} =~ /^YES/i) { 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); } rancid-2.3.8/bin/zrancid.in100755 015615 000000 00000033133 11535733223 0011222#! @PERLV_PATH@ ## ## $Id: zrancid.in 2279 2011-01-31 22:41:00Z heas $ ## ## @PACKAGE@ @VERSION@ ## Copyright (c) 1997-2008 by Terrapin Communications, Inc. ## All rights reserved. ## ## This code is derived from software contributed to and maintained by ## Terrapin Communications, Inc. by Henry Kilmer, John Heasley, Andrew Partan, ## Pete Whiting, Austin Schutz, and Andrew Fort. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions ## are met: ## 1. Redistributions of source code must retain the above copyright ## notice, this list of conditions and the following disclaimer. ## 2. Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## 3. All advertising materials mentioning features or use of this software ## must display the following acknowledgement: ## This product includes software developed by Terrapin Communications, ## Inc. and its contributors for RANCID. ## 4. Neither the name of Terrapin Communications, Inc. nor the names of its ## contributors may be used to endorse or promote products derived from ## this software without specific prior written permission. ## 5. It is requested that non-binding fixes and modifications be contributed ## back to Terrapin Communications, Inc. ## ## THIS SOFTWARE IS PROVIDED BY Terrapin Communications, INC. AND CONTRIBUTORS ## ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ## TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COMPANY OR CONTRIBUTORS ## BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ## CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ## SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ## INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ## CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ## ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ## POSSIBILITY OF SUCH DAMAGE. # # This version of rancid tries to deal with zebra s/w. # # RANCID - Really Awesome New Cisco confIg Differ # # usage: rancid [-dV] [-l] [-f filename | hostname] # use Getopt::Std; 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 my(@commandtable, %commands, @commands);# command lists my($aclsort) = ("ipsort"); # ACL sorting mode my($filter_commstr); # SNMP community string filtering my($filter_pwds); # password filtering mode # force a terminal type so as not to confuse Linux $ENV{'TERM'} = "vt100"; # 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)) && scalar(%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 routine 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 routine 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 routine 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 routine (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 "show version" sub ShowVersion { print STDERR " In ShowVersion: $_" if ($debug); while () { tr/\015//d; last if(/^$prompt/); next if(/^(\s*|\s*$cmd\s*)$/); return(-1) if (/command authorization failed/i); ProcessHistory("COMMENTS","keysort","B0", "!$_") && next; } return(0); } # This routine processes a "write term" sub WriteTerm { print STDERR " In WriteTerm: $_" if ($debug); while () { tr/\015//d; last if(/^$prompt/); return(-1) if (/command authorization failed/i); /Non-Volatile memory is in use/ && return(-1); # NvRAM is locked # skip the crap if (/^(##+$|(Building|Current) configuration)/i) { while () { next if (/^Current configuration\s*:/i); next if (/^([%!].*|\s*)$/); last; } tr/\015//d; } # some versions have other crap mixed in with the bits in the # block above /^! Last Changed:/ && next; # 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 # /^ clockrate / && next; # kill clockrate on serial interfaces if (/^(enable password( \d)?) / && $filter_pwds >= 1) { ProcessHistory("ENABLE","","","!$1 \n"); next; } if (/^username (\S+)(\s.*)? password ((\d) \S+|\S+)/) { if ($filter_pwds == 2) { ProcessHistory("USER","keysort","$1","!username $1$2 password \n"); } elsif ($filter_pwds == 1 && $4 ne "5"){ ProcessHistory("USER","keysort","$1","!username $1$2 password \n"); } else { ProcessHistory("USER","keysort","$1","$_"); } next; } # prune passwords {bgp, ...} if (/^\s*neighbor (\S*) password / && $filter_pwds >= 1) { ProcessHistory("","","","! neighbor $1 password \n"); next; } # sort route-maps if (/^route-map (\S+)/) { my($key) = $1; my($routemap) = $_; while () { tr/\015//d; last if (/^$prompt/ || ! /^(route-map |[ !])/); if (/^route-map (\S+)/) { ProcessHistory("ROUTEMAP","keysort","$key","$routemap"); $key = $1; $routemap = $_; } else { $routemap .= $_; } } ProcessHistory("ROUTEMAP","keysort","$key","$routemap"); } # filter out any RCS/CVS tags to avoid confusing local CVS storage s/\$(Revision|Id):/ $1:/; # order access-lists /^access-list\s+(\d\d?)\s+(\S+)\s+(\S+)/ && ProcessHistory("ACL $1 $2","$aclsort","$3","$_") && next; # order logging statements /^logging (\d+\.\d+\.\d+\.\d+)/ && ProcessHistory("LOGGING","ipsort","$1","$_") && next; # order/prune snmp-server host statements # we only prune lines of the form # snmp-server host a.b.c.d if (/^snmp-server host (\d+\.\d+\.\d+\.\d+) /) { if ($filter_commstr) { my($ip) = $1; my($line) = "snmp-server host $ip"; my(@tokens) = split(' ', $'); my($token); while ($token = shift(@tokens)) { if ($token eq 'version') { $line .= " " . join(' ', ($token, shift(@tokens))); } elsif ($token =~ /^(informs?|traps?|(no)?auth)$/) { $line .= " " . $token; } else { $line = "!$line " . join(' ', ("", join(' ',@tokens))); last; } } ProcessHistory("SNMPSERVERHOST","ipsort","$ip","$line\n"); } else { ProcessHistory("SNMPSERVERHOST","ipsort","$1","$_"); } next; } if (/^(snmp-server community) (\S+)/) { if (defined($ENV{'NOCOMMSTR'})) { ProcessHistory("SNMPSERVERCOMM","keysort","$_","!$1 $'") && next; } else { ProcessHistory("SNMPSERVERCOMM","keysort","$_","$_") && next; } } # prune tacacs/radius server keys if (/^(tacacs-server|radius-server) key / && $filter_pwds >= 1) { ProcessHistory("","","","!$1 key \n"); next; } if (/^(tacacs-server host \S+( .*)? key) (\d )?\S+/ && $filter_pwds >= 1) { ProcessHistory("","","","!$1 \n"); next; } # order clns host statements # /^clns host \S+ (\S+)/ && # ProcessHistory("CLNS","keysort","$1","$_") && next; # prune isis password if (/^( isis authentication-key) \d \S+/ && $filter_pwds >= 1) { ProcessHistory("","","","!$1 $'"); next; } # prune msdp password if (/^(ip msdp password \S+) / && $filter_pwds >= 1) { ProcessHistory("","","","!$1 \n"); next; } # # order ip host line statements # /^ip host line(\d+)/ && # ProcessHistory("IPHOST","numsort","$1","$_") && next; # catch anything that wasnt matched above. ProcessHistory("","","","$_"); # end of config. if (/^end$/) { $found_end = 1; return(1); } } return(0); } # dummy function sub DoNothing {print STDOUT;} # Main @commandtable = ( {'show version' => 'ShowVersion'}, {'write term' => 'WriteTerm'} ); # 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("|", map quotemeta($_), @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 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 clogin -t $timeo -c\"$cisco_cmds\" $host\n" if ($debug); print STDOUT "executing clogin -t $timeo -c\"$cisco_cmds\" $host\n" if ($log); if (defined($ENV{NOPIPE}) && $ENV{NOPIPE} =~ /^YES/i) { system "clogin -t $timeo -c \"$cisco_cmds\" $host $host.raw 2>&1" || die "clogin failed for $host: $!\n"; open(INPUT, "< $host.raw") || die "clogin failed for $host: $!\n"; } else { open(INPUT,"clogin -t $timeo -c \"$cisco_cmds\" $host ) { tr/\015//d; if (/\#\s?exit$/) { $clean_run=1; last; } if (/^Error:/) { print STDOUT ("$host clogin error: $_"); print STDERR ("$host clogin error: $_") if ($debug); $clean_run=0; last; } while (/#\s*($cmds_regexp)\s*$/) { $cmd = $1; if (!defined($prompt)) { $prompt = ($_ =~ /^([^#]+#)/)[0]; $prompt =~ s/([][}{)(\\])/\\$1/g; } 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}) && $ENV{NOPIPE} =~ /^YES/i) { 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); } rancid-2.3.8/bin/hpuifilter.c100644 015615 000000 00000050534 11430125130 0011542/* * $Id: hpuifilter.c 2225 2010-07-22 21:12:36Z heas $ * * Copyright (c) 1997-2008 by Terrapin Communications, Inc. * All rights reserved. * * This code is derived from software contributed to and maintained by * Terrapin Communications, Inc. by Henry Kilmer, John Heasley, Andrew Partan, * Pete Whiting, Austin Schutz, and Andrew Fort. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by Terrapin Communications, * Inc. and its contributors for RANCID. * 4. Neither the name of Terrapin Communications, Inc. nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * 5. It is requested that non-binding fixes and modifications be contributed * back to Terrapin Communications, Inc. * * THIS SOFTWARE IS PROVIDED BY Terrapin Communications, INC. AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COMPANY OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * * Modified openpty() from NetBSD: * Copyright (c) 1990, 1993, 1994 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include "config.h" #include "version.h" #if HAVE_UNISTD_H # include #endif #if HAVE_CTYPE_H # include #endif #include #include #include #include #if HAVE_PTY_H # include #endif #include #include #if HAVE_STRING_H # if !STDC_HEADERS && HAVE_MEMORY_H # include # endif # include #endif #if HAVE_STRINGS_H # include #endif #if HAVE_PTMX && HAVE_STROPTS_H # include #endif #include #include #include #include #if HAVE_UTIL_H # include #endif #define BUFSZ (LINE_MAX * 2) #define ESC 0x1b char **environ, *progname; int debug, sigrx, timeo = 5; /* default timeout */ pid_t child; int expectmore(char *buf, int len); int filter(char *, int); size_t mystrcspn(const char *, const char *); RETSIGTYPE reapchild(int); #if !HAVE_OPENPTY int openpty(int *, int *, char *, struct termios *, struct winsize *); #endif RETSIGTYPE sighdlr(int); #if !HAVE_UNSETENV int unsetenv(const char *); #endif void usage(void); void vers(void); int main(int argc, char **argv, char **ev) { extern char *optarg; extern int optind; char ch, hbuf[BUFSZ], /* hlogin buffer */ ptyname[FILENAME_MAX + 1], tbuf[BUFSZ], /* telnet/ssh buffer */ tbufstr[5] = {ESC, '\x07', '\r', '\n', '\0'}; int bytes, /* bytes read/written */ devnull, rval = EX_OK, ptym, /* master pty */ ptys; /* slave pty */ ssize_t idx, /* strcspan span */ hlen = 0, /* len of hbuf */ tlen = 0; /* len of tbuf */ struct pollfd pfds[3]; struct termios tios; environ = ev; /* get just the basename() of our exec() name and strip a .* off the end */ if ((progname = strrchr(argv[0], '/')) != NULL) progname += 1; else progname = argv[0]; if (strrchr(progname, '.') != NULL) *(strrchr(progname, '.')) = '\0'; while ((ch = getopt(argc, argv, "dhvt:")) != -1 ) switch (ch) { case 'd': debug++; break; case 't': timeo = atoi(optarg); if (timeo < 1) timeo = 1; break; case 'v': vers(); return(EX_OK); case 'h': default: usage(); return(EX_USAGE); } if (argc - optind < 2) { usage(); return(EX_USAGE); } unsetenv("DISPLAY"); for (sigrx = 3; sigrx < 10; sigrx++) close(sigrx); /* allocate pty for telnet/ssh, then fork and exec */ if (openpty(&ptym, &ptys, ptyname, NULL, NULL)) { fprintf(stderr, "%s: could not allocate pty: %s\n", progname, strerror(errno)); return(EX_TEMPFAIL); } /* make the pty raw */ if (tcgetattr(ptys, &tios)) { fprintf(stderr, "%s: tcgetattr() failed: %s\n", progname, strerror(errno)); return(EX_OSERR); } tios.c_lflag &= ~ECHO; tios.c_lflag &= ~ICANON; #ifdef VMIN tios.c_cc[VMIN] = 1; tios.c_cc[VTIME] = 0; #endif if (tcsetattr(ptys, TCSANOW, &tios)) { fprintf(stderr, "%s: tcsetattr() failed: %s\n", progname, strerror(errno)); return(EX_OSERR); } /* * if a tty, make it raw as the hp echos _everything_, including * passwords. */ if (isatty(fileno(stdin))) { if (tcgetattr(fileno(stdin), &tios)) { fprintf(stderr, "%s: tcgetattr() failed: %s\n", progname, strerror(errno)); return(EX_OSERR); } tios.c_lflag &= ~ECHO; tios.c_lflag &= ~ICANON; #ifdef VMIN tios.c_cc[VMIN] = 1; tios.c_cc[VTIME] = 0; #endif if (tcsetattr(fileno(stdin), TCSANOW, &tios)) { fprintf(stderr, "%s: tcsetattr() failed: %s\n", progname, strerror(errno)); return(EX_OSERR); } } /* zero the buffers */ memset(hbuf, 0, BUFSZ); memset(tbuf, 0, BUFSZ); /* reap our children, must be set-up *after* openpty() */ signal(SIGCHLD, reapchild); if ((child = fork()) == -1) { fprintf(stderr, "%s: fork() failed: %s\n", progname, strerror(errno)); return(EX_TEMPFAIL); } if (child == 0) { struct winsize ws; /* * Make sure our terminal length and width are something greater * than 1, for pagers on stupid boxes. */ ioctl(ptys, TIOCGWINSZ, &ws); ws.ws_row = 24; ws.ws_col = 132; ioctl(ptys, TIOCSWINSZ, &ws); signal(SIGCHLD, SIG_DFL); /* close the master pty & std* inherited from the parent */ close(ptym); if (ptys != 0) close(0); if (ptys != 1) close(1); if (ptys != 2) close(2); #ifdef TIOCSCTTY setsid(); if (ioctl(ptys, TIOCSCTTY, NULL) == -1) { snprintf(ptyname, FILENAME_MAX, "%s: could not set controlling " "tty: %s\n", progname, strerror(errno)); write(0, ptyname, strlen(ptyname)); return(EX_OSERR); } #endif /* close stdin/out/err and attach them to the pipes */ if (dup2(ptys, 0) == -1 || dup2(ptys, 1) == -1 || dup2(ptys, 2) == -1) { snprintf(ptyname, FILENAME_MAX, "%s: dup2() failed: %s\n", progname, strerror(errno)); write(0, ptyname, strlen(ptyname)); return(EX_OSERR); } if (ptys > 2) close(ptys); /* exec telnet/ssh */ execvp(argv[optind], argv + optind); snprintf(ptyname, FILENAME_MAX, "%s: execvp() failed: %s\n", progname, strerror(errno)); write(0, ptyname, strlen(ptyname)); return(EX_TEMPFAIL); /*NOTREACHED*/ } /* parent */ if (debug) fprintf(stderr, "child %d\n", (int)child); signal(SIGHUP, sighdlr); /* close the slave pty */ close(ptys); devnull = open("/dev/null", O_RDWR); /* make FDs non-blocking */ if (fcntl(ptym, F_SETFL, O_NONBLOCK) || fcntl(fileno(stdin), F_SETFL, O_NONBLOCK) || fcntl(fileno(stdout), F_SETFL, O_NONBLOCK)) { fprintf(stderr, "%s: fcntl(NONBLOCK) failed: %s\n", progname, strerror(errno)); exit(EX_OSERR); } /* loop to read on stdin and ptym */ #define POLLEXP (POLLERR | POLLHUP | POLLNVAL) pfds[0].fd = fileno(stdin); pfds[0].events = POLLIN | POLLEXP; pfds[1].fd = fileno(stdout); pfds[1].events = POLLEXP; pfds[2].fd = ptym; pfds[2].events = POLLIN | POLLEXP; /* shuffle data across the pipes until we see EOF or a read/write error */ sigrx = 0; while (1) { bytes = poll(pfds, 3, (timeo * 1000)); if (bytes == 0) { if (sigrx) break; /* timeout */ continue; } if (bytes == -1) { switch (errno) { case EAGAIN: case EINTR: break; default: rval = EX_IOERR; break; } continue; } /* * write buffers first * write hbuf (aka hlogin/stdin/pfds[0]) -> telnet (aka ptym/pfds[2]) */ if ((pfds[2].revents & POLLOUT) && hlen) { if ((bytes = write(pfds[2].fd, hbuf, hlen)) < 0 && errno != EINTR && errno != EAGAIN) { fprintf(stderr, "%s: write() failed: %s\n", progname, strerror(errno)); hlen = 0; hbuf[0] = '\0'; break; } else if (bytes > 0) { hlen -= bytes; memcpy(hbuf, hbuf + bytes, hlen + 1); if (hlen < 1) pfds[2].events &= ~POLLOUT; } } if (pfds[2].revents & POLLEXP) { hlen = 0; hbuf[0] = '\0'; break; } /* write tbuf (aka telnet/ptym/pfds[2]) -> hlogin (stdout/pfds[1]) */ if ((pfds[1].revents & POLLOUT) && tlen) { /* * if there is an escape char that didnt get filter()'d, * we need to write only up to that point and wait for * the bits that complete the escape sequence. if at least * two bytes follow it and it doesn't look like we should expect * more data, write it anyway as filter() didnt match it. */ bytes = tlen; idx = mystrcspn(tbuf, tbufstr); if (idx) { if (tbuf[idx] == ESC) { if (tlen - idx < 2 || expectmore(&tbuf[idx], tlen - idx)) { bytes = idx; } } if (tbuf[idx] == '\r' || tbuf[idx] == '\n') { bytes = ++idx; if (tbuf[idx] == '\r' || tbuf[idx] == '\n') bytes++; } } else { if (tbuf[0] == ESC) { if (tlen < 2 || expectmore(tbuf, tlen)) { bytes = 0; } } if (tbuf[0] == '\r' || tbuf[0] == '\n') { bytes = 1; if (tbuf[1] == '\r' || tbuf[1] == '\n') bytes++; } } if ((bytes = write(pfds[1].fd, tbuf, bytes)) < 0 && errno != EINTR && errno != EAGAIN) { fprintf(stderr, "%s: write() failed: %s\n", progname, strerror(errno)); /* dont bother trying to flush tbuf */ tlen = 0; tbuf[0] = '\0'; break; } else if (bytes > 0) { tlen -= bytes; memcpy(tbuf, tbuf + bytes, tlen + 1); if (tlen < 1) pfds[1].events &= ~POLLOUT; } } if (pfds[1].revents & POLLEXP) { /* dont bother trying to flush tbuf */ tlen = 0; tbuf[0] = '\0'; break; } /* read hlogin (aka stdin/pfds[0]) -> hbuf */ if (pfds[0].revents & POLLIN) { if (BUFSZ - hlen > 1) { bytes = read(pfds[0].fd, hbuf + hlen, (BUFSZ - 1) - hlen); if (bytes > 0) { hlen += bytes; hbuf[hlen] = '\0'; pfds[2].events |= POLLOUT; } else if (bytes < 0 && errno != EAGAIN && errno != EINTR) { /* read error */ break; } } } if (pfds[0].revents & POLLEXP) break; /* read telnet/ssh (aka ptym/pfds[2]) -> tbuf, then filter */ if (pfds[2].revents & POLLIN) { if (BUFSZ - tlen > 1) { bytes = read(pfds[2].fd, tbuf + tlen, (BUFSZ - 1) - tlen); if (bytes > 0) { tlen += bytes; tbuf[tlen] = '\0'; tlen = filter(tbuf, tlen); if (tlen > 0) pfds[1].events |= POLLOUT; } else if (bytes < 0 && errno != EAGAIN && errno != EINTR) { /* read error */ break; } } } if (pfds[2].revents & POLLEXP) break; } /* try to flush any remaining data from our buffers */ if (hlen) { (void)write(pfds[2].fd, hbuf, hlen); hlen = 0; } if (tlen) { (void)write(pfds[1].fd, tbuf, tlen); tlen = 0; } if ((bytes = read(pfds[2].fd, tbuf, (BUFSZ - 1))) > 0) { tbuf[bytes] = '\0'; tlen = filter(tbuf, bytes); (void)write(pfds[1].fd, tbuf, tlen); } tcdrain(pfds[1].fd); if ((hlen = read(pfds[0].fd, hbuf, (BUFSZ - 1))) > 0) { (void)write(pfds[2].fd, hbuf, hlen); } tcdrain(pfds[2].fd); if (child && ! kill(child, SIGINT)) reapchild(SIGCHLD); return(rval); } /* * return non-zero if the escape sequence beginning with buf appears to be * incomplete (and the caller should wait for more data). */ int expectmore(char *buf, int len) { int i; if (buf[1] == '[' || isdigit((int)buf[1])) { /* look for a char that ends the sequence */ for (i = 2; i < len; i++) { if (isalpha((int)buf[i])) return(0); } return(1); } if (buf[1] == '#') { /* look for terminating digit */ for (i = 2; i < len; i++) { if (isdigit((int)buf[i])) return(0); } return(1); } return(0); } /* * Remove/replace vt100/220 screen manipulation escape sequences so they do * not litter the output. */ int filter(char *buf, int len) { static regmatch_t pmatch[1]; #define N_REG 15 /* number of regexes in reg[][] */ #define N_CRs 2 /* number of CR replacements */ static regex_t preg[N_REG]; static char reg[N_REG][50] = { /* vt100/220 escape codes */ "\x1B""7\x1B\\[1;24r\x1B""8", /* ds */ "\x1B""8", /* fs */ "\x1B\\[2J", "\x1B\\[2K", /* kE */ "\x1B\\[[0-9]+;[0-9]+r", /* cs */ "\x1B\\[[0-9]+;[0-9]+H", /* cm */ "\x1B\\[\\?6l", "\x1B\\[\\?7l", /* RA */ "\x1B\\[\\?25h", /* ve */ "\x1B\\[\\?25l", /* vi */ "\x1B\\[K", /* ce */ "\x1B\\[7m", /* mr - ansi */ "\x07", /* bell */ /* replace these with CR */ "\x1B\\[0m", /* me */ "\x1B""E", }; char bufstr[3] = {ESC, '\x07', '\0'}, ebuf[256]; size_t nmatch = 1; int err, x; static int init = 0; if (len == 0 || mystrcspn(buf, bufstr) >= len) return(len); if (! init) { init++; for (x = 0; x < N_REG; x++) { memset(&preg[x], 0, sizeof(preg[x])); if ((err = regcomp(&preg[x], reg[x], REG_EXTENDED))) { regerror(err, &preg[x], ebuf, 256); fprintf(stderr, "%s: regex compile failed: %s\n", progname, ebuf); abort(); } } } for (x = 0; x < N_REG - N_CRs; x++) { if ((err = regexec(&preg[x], buf, nmatch, pmatch, 0))) { if (err != REG_NOMATCH) { regerror(err, &preg[x], ebuf, 256); fprintf(stderr, "%s: regexec failed: %s\n", progname, ebuf); abort(); } } else { if (len - pmatch[0].rm_eo <= 0) { buf[pmatch[0].rm_so] = '\0'; } else { memcpy(buf + pmatch[0].rm_so, buf + pmatch[0].rm_eo, len - pmatch[0].rm_eo + 1); } len -= pmatch[0].rm_eo - pmatch[0].rm_so; /* start over with the first regex */ x = -1; } } /* now the CR NL replacements */ for (x = N_REG - N_CRs; x < N_REG; x++) { if ((err = regexec(&preg[x], buf, nmatch, pmatch, 0))) { if (err != REG_NOMATCH) { regerror(err, &preg[x], ebuf, 256); fprintf(stderr, "%s: regexec failed: %s\n", progname, ebuf); abort(); } } else { *(buf + pmatch[0].rm_so++) = '\r'; *(buf + pmatch[0].rm_so++) = '\n'; if (len - pmatch[0].rm_eo == 0) { buf[pmatch[0].rm_so] = '\0'; } else { memcpy(buf + pmatch[0].rm_so, buf + pmatch[0].rm_eo, len - pmatch[0].rm_eo + 1); } len -= pmatch[0].rm_eo - pmatch[0].rm_so; /* start over with the first CR regex */ x = N_REG - 1 - N_CRs; } } return(len); } /* like strcspn(), but works around a bug in a particular O/S */ size_t mystrcspn(const char *s, const char *charset) { size_t len; const char *csp; for (len = 0; *s != '\0'; s++) { for (csp = charset; *csp != '\0'; csp++) if (*s == *csp) return(len); len++; } return(len); } RETSIGTYPE reapchild(int sig) { int status; pid_t pid; if (debug) fprintf(stderr, "GOT SIGNAL %d\n", sig); while ((pid = wait3(&status, WNOHANG, NULL)) > 0) { if (debug) fprintf(stderr, "reap child %d\n", (int)pid); if (pid == child) { child = 0; sigrx = 1; break; } } return; } RETSIGTYPE sighdlr(int sig) { if (debug) fprintf(stderr, "GOT SIGNAL %d\n", sig); sigrx = 1; return; } #if !HAVE_UNSETENV int unsetenv(const char *name) { char **victim, **end; int len; if (environ == NULL) return(0); len = strlen(name); victim = environ; while (*victim != NULL) { if (strncmp(name, *victim, len) == 0 && victim[0][len] == '=') break; victim++; } if (*victim == NULL) return(0); end = victim + 1; while (*end != NULL) end++; end--; *victim = *end; *end = NULL; return(0); } #endif void usage(void) { fprintf(stderr, "usage: %s [-hv] [-t timeout] []" " []\n", progname); return; } void vers(void) { fprintf(stderr, "%s: %s version %s\n", progname, package, version); return; } #if !HAVE_OPENPTY #include #define TTY_LETTERS "pqrstuvwxyzPQRST" #define TTY_OLD_SUFFIX "0123456789abcdef" #define TTY_NEW_SUFFIX "ghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" int openpty(int *amaster, int *aslave, char *name, struct termios *term, struct winsize *winp) { static char line[] = "/dev/XtyXX"; const char *cp1, *cp2, *cp, *linep; int master, slave; gid_t ttygid; mode_t mode; struct group *gr; #if HAVE_PTMX if ((master = #if HAVE_PTMX_BSD open("/dev/ptmx_bsd", O_RDWR)) #else open("/dev/ptmx", O_RDWR)) #endif != -1) { linep = ptsname(master); grantpt(master); unlockpt(master); #ifndef TIOCSCTTY setsid(); #endif if ((slave = open(linep, O_RDWR)) < 0) { slave = errno; (void) close(master); errno = slave; return(-1); } #if HAVE_PTMX_OSF { char buf[10240]; if (ioctl (slave, I_LOOK, buf) != 0) if (ioctl (slave, I_PUSH, "ldterm")) { close(slave); close(master); return(-1); } } #elif HAVE_STROPTS_H ioctl(slave, I_PUSH, "ptem"); ioctl(slave, I_PUSH, "ldterm"); ioctl(slave, I_PUSH, "ttcompat"); #endif goto gotit; } if (errno != ENOENT) return(-1); #endif if ((gr = getgrnam("tty")) != NULL) { ttygid = gr->gr_gid; mode = S_IRUSR|S_IWUSR|S_IWGRP; } else { ttygid = getgid(); mode = S_IRUSR|S_IWUSR; } for (cp1 = TTY_LETTERS; *cp1; cp1++) { line[8] = *cp1; for (cp = cp2 = TTY_OLD_SUFFIX TTY_NEW_SUFFIX; *cp2; cp2++) { line[5] = 'p'; line[9] = *cp2; if ((master = open(line, O_RDWR, 0)) == -1) { if (errno != ENOENT) continue; /* busy */ if (cp2 - cp + 1 < sizeof(TTY_OLD_SUFFIX)) return -1; /* out of ptys */ else break; /* out of ptys in this group */ } line[5] = 't'; linep = line; if (chown(line, getuid(), ttygid) == 0 && chmod(line, mode) == 0 && (slave = open(line, O_RDWR, 0)) != -1) { gotit: *amaster = master; *aslave = slave; if (name) (void)strcpy(name, linep); if (term) (void)tcsetattr(slave, TCSAFLUSH, term); if (winp) (void)ioctl(slave, TIOCSWINSZ, winp); return 0; } (void)close(master); } } errno = ENOENT; /* out of ptys */ return -1; } #endif rancid-2.3.8/bin/lg.cgi.in100644 015615 000000 00000060056 11661274022 0010731#! @PERLV_PATH@ ## ## $Id: lg.cgi.in 2334 2011-11-17 21:09:37Z heas $ ## ## @PACKAGE@ @VERSION@ ## Copyright (c) @COPYYEARS@ by Terrapin Communications, Inc. ## All rights reserved. ## ## This code is derived from software contributed to and maintained by ## Terrapin Communications, Inc. by Henry Kilmer, John Heasley, Andrew Partan, ## Pete Whiting, Austin Schutz, and Andrew Fort. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions ## are met: ## 1. Redistributions of source code must retain the above copyright ## notice, this list of conditions and the following disclaimer. ## 2. Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## 3. All advertising materials mentioning features or use of this software ## must display the following acknowledgement: ## This product includes software developed by Terrapin Communications, ## Inc. and its contributors for RANCID. ## 4. Neither the name of Terrapin Communications, Inc. nor the names of its ## contributors may be used to endorse or promote products derived from ## this software without specific prior written permission. ## 5. It is requested that non-binding fixes and modifications be contributed ## back to Terrapin Communications, Inc. ## ## THIS SOFTWARE IS PROVIDED BY Terrapin Communications, INC. AND CONTRIBUTORS ## ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ## TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COMPANY OR CONTRIBUTORS ## BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ## CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ## SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ## INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ## CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ## ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ## POSSIBILITY OF SUCH DAMAGE. # # The original original lookingglass s/w was written by Ed Kern. It was # a single script that used to be available at http://nitrous.digex.net/. # Provided by permission and modified beyond recognition. # # Looking glass # vars: query, router, args BEGIN { $me = $0; $me =~ s/.*\/(\S+)$/$1/; } use CGI qw/:standard escapeHTML/; use POSIX qw(strftime); use Sys::Syslog; use LockFile::Simple qw(lock trylock unlock); my($BASEDIR) = "@prefix@"; my($SYSCONFDIR) = "@sysconfdir@"; my($LOCALSTATEDIR) = "@localstatedir@"; my($pingcmd) = "@LG_PING_CMD@"; my($query, $max_time_diff, $cache_dir, $cloginrc, @results); my($type, $router_param, $remote_user, $arg, $router, $mfg); my($LG_CACHE_DIR, $LG_CLOGINRC, $LG_IMAGE, $LG_LOG, $LG_ROUTERDB, $LG_AS_REG); my($LG_BGP_RT, $LG_CACHE_TIME, $LG_SINGLE, $LG_STRIP); if (!defined($ENV{HOME})) { $ENV{HOME} = "."; } # note: the following functions are duplicated between lgform.cgi and lg.cgi # to avoid the need for module inclusion headaches from within a httpd context. # it is just easier to be self-contained. # SO, ANY CHANGES HERE SHOULD BE REFLECTED IN THE OTHER .cgi. # logging sub dolog { my($level, $msg) = @_; if (defined($LG_LOG) && $LG_LOG !~ /\//) { openlog($me, "pid", $LG_LOG); syslog($level, "%s", $msg); closelog; } else { local(*LOG); my($file); if (defined($LG_LOG)) { $file = $LG_LOG; } else { $file = "$cache_dir/lg.log"; } # log date, hostname, query, addr if (open(LOG, ">>$file") == 0) { # stderr, if all else fails printf(STDERR "[" . strftime("%a %b %e %H:%M:%S %Y", gmtime) . "] could not open log file $file: $!\n"); printf(STDERR $msg); } else { printf(LOG $msg); close(LOG); } } return; } # read LG configuration file sub readconf { my($conffile, $cmds); local(*CONF); if (defined($ENV{LG_CONF})) { $conffile = $ENV{LG_CONF}; } elsif (-e "lg.conf") { $conffile = "lg.conf"; } else { $conffile = "$SYSCONFDIR/lg.conf"; } if (! -f $conffile) { return; } if (open(CONF, "< $conffile")) { while () { next if (/^\s*(#|$)/); $cmds .= $_; } close(CONF); eval $cmds; } else { printf(STDERR "ERROR: couldn\'t open the configuration file: " . "$conffile: $!\n"); exit(1); } return; } # read router.db file sub readrouters { my($rtrdb); local(*RTR); if (defined($LG_ROUTERDB)) { $rtrdb = $LG_ROUTERDB; } else { $rtrdb = "$SYSCONFDIR/router.db"; } if (! -f $rtrdb) { my(@dirs, $dir); # if the router.db file does not exist, try to compile the list from # the rancid group router.db files. local(*DIR); if (! opendir(DIR, $LOCALSTATEDIR)) { dolog(LOG_ERR, "ERROR: couldn\'t read $LOCALSTATEDIR: $!\n"); } else { while ($dir = readdir(DIR)) { next if ($dir =~ /^(\.|\.\.|\.ssh|CVS|bin|etc|logs|util)$/); push(@dirs, $dir) if (-d "$LOCALSTATEDIR/$dir"); } closedir(DIR); foreach $dir (@dirs) { if (! opendir(DIR, "$LOCALSTATEDIR/$dir")) { dolog(LOG_ERR, "ERROR: couldn\'t read $LOCALSTATEDIR/$dir: $!\n"); next; } closedir(DIR); next if (! -f "$LOCALSTATEDIR/$dir/router.db"); if (open(RTR, "< $LOCALSTATEDIR/$dir/router.db")) { while () { next if (/^\s*(#|$)/); # fqdn:mfg:state @record = split('\:', $_); next if ($record[2] !~ /up/i || $record[1] !~ /(cisco|foundry|juniper)/); push(@rtrlist, join(':', ($record[0], $record[1]))); $rtrlabels{join(':', ($record[0], $record[1]))} = $record[0]; } close(RTR); } else { dolog(LOG_ERR, "ERROR: couldn\'t open the router.db " . "file: $LOCALSTATEDIR/$dir/router.db: $!\n"); } } } } else { if (open(RTR, "< $rtrdb")) { while () { next if (/^\s*(#|$)/); # fqdn:mfg:state @record = split('\:', $_); next if ($record[2] !~ /up/i || $record[1] !~ /(cisco|foundry|juniper)/); push(@rtrlist, join(':', ($record[0], $record[1]))); $rtrlabels{join(':', ($record[0], $record[1]))} = $record[0]; } close(RTR); } else { dolog(LOG_ERR, "ERROR: couldn\'t open the router.db file: " . "$rtrdb: $!\n"); exit(1); } } return; } # the remaining functions are particular to lg.cgi. # return true if $router is a member of @rtrlist sub arraymember { my($rtrlist) = shift; my($router) = shift; my($r); foreach $r (@$rtrlist) { $r = (split(':', $r))[0]; return(1) if ($r eq $router); } return(0); } # check reachability and lock file before attempting to connect to device # return non-zero on error. sub DoRsh { my ($router, $mfg, $cmd, $arg) = @_; my($ctime) = time(); my($val); my($lckobj) = LockFile::Simple->make(-delay => $lock_int, -max => $max_lock_wait, -hold => $max_lock_hold); if ($pingcmd =~ /\d$/) { `$pingcmd $router`; } else { `$pingcmd $router 56 1`; } if ($?) { print "$router is unreachable. Try again later.\n"; return(-1); } if ($LG_SINGLE) { if (! $lckobj->lock("$cache_dir/$router")) { print "$router is busy. Try again later.\n"; return(-1); } } $val = &DoCmd($router, $mfg, $cmd, $arg); if ($LG_SINGLE) { $lckobj->unlock("$cache_dir/$router"); } return($val); } # run commands on the router. return non-zero on error. sub DoCmd { my($rtr, $mfg, $cmd, $arg) = @_; local(*CMD); if ($mfg =~ /foundry/i) { open(CMD, "sh -c \"flogin -f $cloginrc -c \'$cmd $arg\' $rtr\" 2>&1 |"); } elsif ($mfg =~ /juniper/i) { open(CMD, "sh -c \"jlogin -f $cloginrc -c \'$cmd $arg\' $rtr\" 2>&1 |"); } else { open(CMD, "sh -c \"clogin -noenable -f $cloginrc -c \'$cmd $arg\' $rtr\" 2>&1 |"); } while () { tr/\015//d; if (/^error:/i) { dolog(LOG_ERR, $_); if ($LG_STRIP) { undef(@results); } push(@results, $_); print @results; return(-1); } push(@results, $_); if (/$cmd/) { ($prompt) = /^(\S*)[\#>]/; if ($LG_STRIP) { undef(@results); } else { print @results; } last; } } while () { last if /^$prompt[\#>]/; tr/\015//d; print $_; push(@results, $_); } while () {} close(CMD); return(0); } ## # Subroutine: Error # Usage: &Error("msg")); # Description: displays an error and exits. ## sub Error { my($msg) = @_; my($q) = new CGI(); print $q->header; if ($LG_STYLE) { print $query->start_html(-title => "LookingGlass Results - $router", -style => {'src' => $LG_STYLE}); } else { print $query->start_html(-title => "LookingGlass Results - $router"); } # add the company image, LG_IMAGE print $LG_IMAGE; print < Looking Glass Error:

$msg


$LG_INFO EOF print $q->end_html; exit(0); } # convert an ipv4 address mask to prefix length sub mask2len { my($mask) = shift; my($a, $b, $c, $d) = split('\.', $mask); my($p, $len); $p = ~ (($a << 24) + ($b << 16) + ($c << 8) + $d); for ($len = 32; $p > 0; $len --) { $p = $p >> 1; } return($len); } # end the page and exit. sub end_page { print < END print $query->end_html; exit(0); } # start the page and log the transaction... sub start_page { my($mfg) = @_; my($cmd); my($timestr) = strftime("%a %b %e %H:%M:%S %Y", gmtime); dolog(LOG_INFO, sprintf("%s %s %s %s\n", $ENV{REMOTE_HOST}, $ENV{REMOTE_ADDR}, $ENV{REMOTE_USER}, "- - [$timestr] $type $router $arg")); print $query->header; if ($LG_STYLE) { print $query->start_html(-title =>"LookingGlass form", -style => {'src' => $LG_STYLE}); } else { print $query->start_html(-title =>"LookingGlass from"); } $timestr = strftime("%a %b %e %H:%M:%S %Y %Z", gmtime); # add the company image, LG_IMAGE print $LG_IMAGE; if ($mfg =~ /foundry/i) { $cmd = $foundryCmd{$type}; } elsif ($mfg =~ /juniper/i) { $cmd = $juniperCmd{$type}; } else { $cmd = $ciscoCmd{$type}; } print <

Looking Glass Results - $router


Date: $timestr

Query: $cmd
HEAD if ($arg) { print "Argument(s): $arg\n"; } print "

\n"; print <

END

    return;
}


# Main()
# read the configuration file if it exists.
readconf();

# The script will now cache the results as simple files in the $cache_dir,
# named after the type of query (queries must, of course, be one word with
# no spaces).  Modify $LG_CACHE_TIME to set the lifetime for cache entries.
# for most web servers, cache_dir must be writable by uid nobody
if (defined($LG_CACHE_DIR)) {
    $cache_dir = $LG_CACHE_DIR;
} else {
    $cache_dir = "./tmp";
}

# read routers table to get @rtrlist
readrouters();

# when to display cache?  max time difference (in seconds)
if (defined($LG_CACHE_TIME)) {
    $max_time_diff = $LG_CACHE_TIME;
} else {
    $max_time_diff = "600" ;
}

# serialize queries?
if (!defined($LG_SINGLE)) {
    $LG_SINGLE = 1;
}

# max seconds to wait for a 'router' lock to free up
$max_lock_wait = 30;
$lock_int = 5;
$max_lock_hold = 300;

# clogin setup
if (defined($LG_CLOGINRC)) {
    $cloginrc = $LG_CLOGINRC;
} else {
    $cloginrc = $ENV{HOME} . "/.cloginrc";
}

$query = new CGI;

# get form data and validate
$type = ($query->param('query'))[0];
$router_param = ($query->param('router'))[0];
$remote_user = $ENV{REMOTE_USER};
$arg = ($query->param('args'))[0];
# handle multiple args
$arg =~ s/["'`]//g;			# these are BS in any arg for any query
@arg = split(' ', $arg);

# verify router, commands, arguments, etc.
($router, $mfg) = split(':', $router_param);
if (!defined($type) || !defined($router) || $router eq "") {
    &Error("You must at least choose a Query and a router.  Try buying " .
								"a clue.\n");
}

if ($arg !~ /^[-A-Za-z0-9|_\/: \.^\$]*$/) {
    &Error("Funny characters in argument; ignoring.\n");
}
if (length($arg) >= 50) {
    &Error("Argument string too long; ignoring. \n");
}

if (! arraymember(\@rtrlist, $router)) {
    my($timestr) = strftime("%a %b %e %H:%M:%S %Y", gmtime);
    dolog(LOG_WARNING, sprintf("%s %s %s %s\n",
	$ENV{REMOTE_HOST}, $ENV{REMOTE_ADDR}, $ENV{REMOTE_USER},
	"- - [$timestr] lg.cgi: attempt to access $router\n"));
    Error("access to $router not permitted");
}

# conversion of command "type" passed from lgform.cgi to the vendor's syntax.
if ($mfg =~ /cisco/i) {
    %mfgCmd = (
		# Debug Queries
		log => "show logging",
		# Interface Queries
		framerelay => "show frame-relay pvc",
		interface => "show interface",
		intbrief => "show ip interface",	# switch in {interface}
		# Routing Queries
		damp => "show ip bgp dampened-paths",
		neighbor => "show ip bgp neighbor",
		# Multicast Queries
		mbgp => "show ip mbgp",
		mbgpsum => "show ip mbgp summary",
		mneighbor => "show ip bgp neighbor",
		msdp => "show ip msdp summary",
		msdpsa => "show ip msdp sa-cache",
		msess => "show ip sdr",
		mroute => "show ip mroute",
		pim_interface => "show ip pim interface",
		pim_neighbor => "show ip pim neighbor",
		pim_rp => "show ip pim rp mapping",
		# IPv6 Queries
		#
		#acl => "show access-list",
		#aspath => "show ip as-path-access-list",
		#communitylist => "show ip community-list",
		ping => "ping",
		prefix => "show ip bgp",
		prefixlist => "show ip prefix-list",
		regex => "show ip bgp regex",
		route => "show ip route",
		routemap => "show route-map",
		rpf => "show ip rpf",
		summary => "show ip bgp summary",
		trace => "traceroute",
		v6_bgp => "show bgp ipv6",
		v6_interface => "show ipv6 interface",
		v6_summary => "show bgp ipv6 summary"
    );
} elsif ($mfg =~ /foundry/i) {
    %mfgCmd = (
		# Debug Queries
		log => "show log",
		ping => "ping",
		trace => "traceroute",
		# Interface Queries
		#framerelay => "show frame-relay pvc",	# no compatible command
		interface => "show interface",
		# Routing Queries
		damp => "show ip bgp dampened-paths",
		neighbor => "show ip bgp neighbor",
		#regex => "show ip bgp aspath-regex",
		route => "show ip route",
		summary => "show ip bgp summary",
		# Multicast Queries
		#mbgp => "show ip mbgp",
		#mbgpsum => "show bgp summary",
		#mneighbor => "show ip bgp neighbor",
		mroute => "show ip mroute",
		msdp => "show ip msdp summary",
		msdpsa => "show ip msdp sa-cache",
		msess => "show ip sdr",
		pim_interface => "show ip pim interface",
		pim_neighbor => "show ip pim neighbor",
		pim_rp => "show ip pim rp mapping",
		rpf => "show ip rpf",
		# IPv6 Queries
		# v6_bgp => "show bgp ipv6",
		# v6_interface => "show ipv6 interface",
		# v6_summary => "show bgp ipv6 summary"
		#
		#acl => "show access-list",
		#aspath => "show ip as-path-access-list",
		#communitylist => "show ip community-list",
		routemap => "show route-map",
		prefix => "show ip bgp",
		prefixlist => "show ip prefix-list"
	);
} elsif ($mfg =~ /juniper/i) {
    %mfgCmd = (
		# Debug Queries
		log => "show log messages",
		ping => "ping rapid count 5",
		trace => "traceroute",
		# Interface Queries
		framerelay => "show frame-relay pvc",
		interface => "show interface",
		#intbrief => "show ip interface",	# switch in {interface}
		# Routing Queries
		damp => "show route damping suppressed terse table inet.0",
		neighbor => "show bgp neighbor",
		regex => "show route table inet.0 aspath-regex",
		summary => "show bgp summary",
		# Multicast Queries
		mbgp => "show route table inet.2 terse",
		mbgpsum => "show bgp summary",
		mneighbor => "show bgp neighbor",
		mroute => "show multicast route extensive",
		msdp => "show msdp",
		msdpsa => "show msdp source-active",
		msess => "show multicast sessions",
		pim_interface => "show pim interface",
		pim_neighbor => "show pim neighbors",
		pim_rp => "show pim rps",
		pim_join => "show pim join",
		rpf => "show multicast rpf",
		# IPv6 Queries
		v6_bgp => "show route table inet6.0",
		v6_interface => "show interface",
		v6_summary => "show bgp summary",
		#
		#acl => "show access-list",
		#aspath => "show ip as-path-access-list",
		#communitylist => "show ip community-list",
		prefix => "show route table inet.0",
		prefixlist => "show policy",
		route => "show route table inet.0 terse",
		routemap => "show policy"
	);
}

# construct Display command from configuration
%cmdDisp=();
foreach $qtype (sort keys(%$queries)) {
    next if (! scalar(%{$queries->{$qtype}}));
    foreach $sub_type (sort keys(%{$queries->{$qtype}})) {
	$cmdDisp{$sub_type} = $queries->{$qtype}->{$sub_type};
    }
}

# make sure the command is not disabled
if (! defined($cmdDisp{$type})) {
    &Error("Unknown command type: $type\n");
}

# not all cmds/queries are implemented for all platforms
if (! defined($mfgCmd{$type})) {
    Error("$cmdDisp{$type} not implemented for $mfg or no suitable " .
						"equivalent exists.  sorry.\n");
}
$cmd = $mfgCmd{$type};

# handle each query/command type
if ($type eq "prefix" || $type eq "mbgp" || $type eq "route" ) {
    if ($arg[0] !~ /^\d+\.\d+\.\d+\.\d+$/) {
	&Error("The IP address \"$arg[0]\" is not valid and lacking an " .
				"address would over-burden our router.\n");
    } elsif (defined($arg[1]) && $arg[1] !~ /^\d+\.\d+\.\d+\.\d+$/) {
	&Error("The IP netmask \"$arg[1]\" is not valid.\n");
    }
    if ($mfg =~ /juniper/i && defined($arg[1])) {
	$arg = $arg[0] . "/" . mask2len($arg[1]);
    }
} elsif ($type eq "v6_route" ){
    # XXX: is this check of the address arg correct and pedantic?
    if ($arg[0] !~ /[0-9a-fA-F:]+$/) {
	&Error("The IPv6 address \"$arg[0]\" is not valid.\n");
    }
} elsif ($type eq "framerelay") {
    if ($mfg =~ /juniper/) {
	&Error("Juniper does not have a show frame-relay pvc command.  " .
						"Use show interface.\n");
    }
    if ($arg[0] > 15 && $arg[0] < 1024) {
	$arg = $arg[0];
    } else {
	undef($arg);
    }
} elsif ($type eq "interface" || $type eq "v6_interface") {

	# XXX: wtf is arg[1]?
#    if ($arg[1] =~ /[-\/0-9:.]+/) {
#       $arg = $arg[0] . " " . $arg[1];
#    } else {

    if ($mfg =~ /(cisco|foundry)/) {
	if ($arg[0] !~ /^b[^ ]+[0-9]/i && $arg[0] =~ /^b/i) {
	    $type = "intbrief";
	    $arg = "brief";
	} else {
	    $arg = $arg[0];
	}
    } elsif ($mfg =~ /juniper/) {
	my($optind) = 0;
	# arg 0 may be an intf name or a display option, but there can
	# only be 2 args
	$arg = "";
	while ($optind <= $#arg && $optind < 2) {
	    $arg[$optind] =~ s/brief/terse/;
	    if ($arg[$optind] =~ /^([a-z0-9]{2}\-\d+\/\d+\/\d+(:\d+)?)/i) {
		$arg .= " $1";
	    } elsif ($arg[$optind] =~ /^det/i) {
		$arg .= " detail";
	    } elsif ($arg[$optind] =~ /^ter/i) {
		$arg .= " terse";
	    } elsif ($arg[$optind] =~ /^ext/i) {
		$arg .= " extensive";
	    }
	    $optind += 1;
	}
    }
} elsif ($type eq "log") {
    if ($arg[0] =~ /^\s*\|?$/) {
	shift(@arg);
    }
    $arg[0] =~ s/^\s*\|?//;
    if ($arg[0] !~ /^\s*$/) {
	if ($mfg =~ /cisco/i) {
	    $arg = " | include " . join(' ', @arg);
	} elsif ($mfg =~ /juniper/i) {
	    $arg = " | match \\\"" . join(' ', @arg) . "\\\"";
	} else {
	    undef($arg);
	}
    } else {
	undef($arg);
    }
} elsif ($type eq "ping" || $type eq "trace") {
    if ($arg[0] !~ /^\d+\.\d+\.\d+\.\d+$/) {
	if ($arg[0] !~ /^[A-Za-z0-9._-]+$/) {
	    &Error("That argument ($arg[0]) is not valid.\n");
	}
    }
    $arg = $arg[0];
} elsif ($type eq "aspath" || $type eq "communitylist") {
    if ($arg[0] !~ /^\d+$/ || ($arg[0] < 1 && $arg[0] > 199)) {
	&Error("That argument ($arg[0]) is not valid.\n");
    }
    $arg = $arg[0];
} elsif ($type eq "acl") {
    if ($arg[0] !~ /^\d+$/ || ($arg[0] < 100 && $arg[0] > 199) ||
					($arg[0] < 1300 && $arg[0] > 2699)) {
	&Error("That argument ($arg[0]) is not valid.\n");
    }
    $arg = $arg[0];
    # don't show the jewels
    # XXX: this error msg is useless, but show acl is un-implemented.
    &Error($mfg) if ($arg == 98 || $arg == 99);
} elsif ($type eq "prefixlist" || $type eq "routemap") {
    if ($arg[0] !~ /^[0-9A-Za-z][^\s\"]*$/) {
	&Error("That argument ($arg[0]) is not valid.\n");
    }
    $arg = $arg[0];
} elsif ($type eq "regex") {
    # bgp as-path regex
    $arg = $arg[0];
    if ($#arg >= 1) {
	for ($n = 1; $n <= $#arg; $n++) { $arg .= " " . $arg[$n]; }
    }
    # remove leading/trailing whitespace
    $arg =~ s/^\s*//; $arg =~ s/\s*$//;
    if ($arg !~ /^[0-9_ ^.*+?[\])\(-]*\$?$/ || $arg =~ /^\s*$/) {
	&Error("That argument ($arg[0]) is not valid.\n");
    }
    # pathetic excuses for lookups
    if ($arg =~ /^[_.* ^]*(\*|1|701|1239|1280|1740|3561|5462|10303)+[_\$]*$/ ||
	$arg =~ /^[_.* ^]*(1|701|1239|1280|1740|3561|5462|10303)+[_ .]*[\[*.]/) {
	&Error("Get real.  Such a query has potential to over-burden our " .
		"router.\nLook that up on your own router.\n");
    }
    if ($mfg =~ /juniper/) {
	$arg =~ s/_/ /g;
	# pre-junos 4.4 does not allow anchors
	if ($arg =~ /\^\$/) {
	    $arg =~ "()";
	} else {
	    $arg =~ s/[\$^]/ /g;
	}
	$arg = "\\\"$arg\\\"";
    }
    # escape any ()s
    $arg =~ s/([\(\)])/\\$1/g;
} elsif ($type eq "neighbor") {
    if ($arg[0] !~ /^\d+\.\d+\.\d+\.\d+$/) {
	if ($arg[0] !~ /([A-Za-z0-9-]*.)*[A-Za-z0-9-]*.(com|edu|net|org)/) {
	    &Error("That argument ($arg[0]) is not valid.\n");
	}
    }
    $arg = $arg[0];
    if (defined($arg[1]) && $arg[1] =~ /^(a|ro|f|re)/) {
	if ($mfg =~ /juniper/) {
	    if ($arg[1] =~ /^a/) {
		if (defined($LG_BGP_RT)) {
		    $cmd = "show route table inet.0 all advertising-protocol ".
			"bgp";
		}
	    } elsif ($arg[1] =~ /^f/) {
		if (defined($LG_BGP_RT)) {
		    $cmd = "show route damping table inet.0 all ".
			"receive-protocol bgp";
		}
	    } elsif ($arg[1] =~ /^r/) {
		if (defined($LG_BGP_RT)) {
		    $cmd = "show route table inet.0 all receive-protocol bgp";
		}
	    }
	} else {
	    if ($arg[1] =~ /^a/) {
		if (defined($LG_BGP_RT)) { $arg .= " advertised-routes"; }
	    } elsif ($arg[1] =~ /^f/) {
		$arg .= " flap-statistics";
	    } elsif ($arg[1] =~ /^ro/) {
		if (defined($LG_BGP_RT)) { $arg .= " routes"; }
	    } elsif ($arg[1] =~ /^re/) {
		if (defined($LG_BGP_RT)) { $arg .= " received-routes"; }
	    }
	}
    }
} elsif ($type eq "mneighbor") {
    if ($arg[0] !~ /^\d+\.\d+\.\d+\.\d+$/) {
	if ($arg[0] !~ /([A-Za-z0-9-]*.)*[A-Za-z0-9-]*.(com|edu|net|org)/) {
	    &Error("That argument ($arg[0]) is not valid.\n");
	}
    }
    $arg = $arg[0];
    if (defined($arg[1]) && $arg[1] =~ /^(a|ro|f|re)/) {
	if ($mfg =~ /juniper/) {
	    if ($arg[1] =~ /^a/) {
		$cmd .= " advertised-routes";
	    } elsif ($arg[1] =~ /^f/) {
		$cmd .= " flap-statistics";
	    } elsif ($arg[1] =~ /^ro/) {
		$cmd .= " routes";
	    } elsif ($arg[1] =~ /^re/) {
		$cmd .= " received-routes";
	    }
	} else {
	    if ($arg[1] =~ /^a/) {
		$arg .= " advertised-routes";
	    } elsif ($arg[1] =~ /^f/) {
		$arg .= " flap-statistics";
	    } elsif ($arg[1] =~ /^ro/) {
		$arg .= " routes";
	    } elsif ($arg[1] =~ /^re/) {
		$arg .= " received-routes";
	    }
	}
    }
} elsif ($type eq "damp" || $type eq "summary" || $type eq "mbgpsum") {
    undef($arg);
}

# make stdout unbuffered, so result page streams.
$| = 1;
start_page();

# cache the following
if ($type eq "summary" || $type eq "mbgpsu" || $type eq "damp"
							|| $type eq "log") {
    if (!$arg) {
	# cache requests with no addr/argument
	local(*CACHE);

	my($file) = "$cache_dir/$type" ;
	$file =~ s/\s+/_/g;
	$file .= "_$router";

	if (-e $file) {
	    # see if cache exists
	    @stat = stat($file);
	    $ftime = $stat[9];
	    $dtime = time() - $stat[9];

	    # see if we are within cache time
	    if ($dtime <= $max_time_diff) {
		if (open(CACHE, "<$file") == 0) {
		    dolog(LOG_ERR, "couldnt open cache file $file: $!\n");
		} else {
		    print "From cache (number of seconds old (max " .
			"$max_time_diff)): $dtime\n\n";
		    while () { print $_; }
		    close(CACHE);
		    &end_page();
		}
	    }
	}

	# else, execute command and save to a new cache file
	if (! &DoRsh($router, $mfg, $cmd, $arg)) {
	    if (open(CACHE, ">$file") == 0) {
		dolog(LOG_ERR, "couldnt create cache file $file: $!\n");
		exit(1);
	    } else {
		printf(CACHE "@results");
		close(CACHE);
	    }
	}
    } else {
	&DoRsh($router, $mfg, $cmd, $arg);
    }
    &end_page();
} else {
    &DoRsh($router, $mfg, $cmd, $arg);
    &end_page();
}

exit(0);
rancid-2.3.8/bin/lgform.cgi.in100644 015615 000000 00000017175 11661274022 0011621#! @PERLV_PATH@
##
## $Id: lgform.cgi.in 2334 2011-11-17 21:09:37Z heas $
##
## @PACKAGE@ @VERSION@
## Copyright (c) @COPYYEARS@ by Terrapin Communications, Inc.
## All rights reserved.
##
## This code is derived from software contributed to and maintained by
## Terrapin Communications, Inc. by Henry Kilmer, John Heasley, Andrew Partan,
## Pete Whiting, Austin Schutz, and Andrew Fort.
##
## Redistribution and use in source and binary forms, with or without
## modification, are permitted provided that the following conditions
## are met:
## 1. Redistributions of source code must retain the above copyright
##    notice, this list of conditions and the following disclaimer.
## 2. Redistributions in binary form must reproduce the above copyright
##    notice, this list of conditions and the following disclaimer in the
##    documentation and/or other materials provided with the distribution.
## 3. All advertising materials mentioning features or use of this software
##    must display the following acknowledgement:
##        This product includes software developed by Terrapin Communications,
##        Inc. and its contributors for RANCID.
## 4. Neither the name of Terrapin Communications, Inc. nor the names of its
##    contributors may be used to endorse or promote products derived from
##    this software without specific prior written permission.
## 5. It is requested that non-binding fixes and modifications be contributed
##    back to Terrapin Communications, Inc.
##
## THIS SOFTWARE IS PROVIDED BY Terrapin Communications, INC. AND CONTRIBUTORS
## ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
## TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
## PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COMPANY OR CONTRIBUTORS
## BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
## CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
## SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
## INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
## CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
## ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
## POSSIBILITY OF SUCH DAMAGE.
# 
# The original original lookingglass s/w was written by Ed Kern.  It was
# a single script that used to be available at http://nitrous.digex.net/.
# Provided by permission and modified beyond recognition.
#
# lgform.cgi - Looking glass front-end
# produces html form for calling lg.cgi

BEGIN {
    $me = $0;
    $me =~ s/.*\/(\S+)$/$1/;
}

use CGI qw/:standard/;
use POSIX qw(strftime);
use Sys::Syslog;

my(@rtrlist, %rtrlabels);
my($BASEDIR) = "@prefix@";
my($SYSCONFDIR) = "@sysconfdir@";
my($LOCALSTATEDIR) = "@localstatedir@";

# note: the following functions are duplicated between lgform.cgi and lg.cgi
# to avoid the need for module inclusion headaches from within a httpd context.
# it is just easier to be self-contained.
# SO, ANY CHANGES HERE SHOULD BE REFLECTED IN THE OTHER .cgi.

# logging
sub dolog
{
    my($level, $msg) = @_;

    if (defined($LG_LOG) && $LG_LOG !~ /\//) {
	openlog($me, "pid", $LG_LOG);
	syslog($level, "%s", $msg);
	closelog;
    } else {
	local(*LOG);
	my($file);
	if (defined($LG_LOG)) {
	    $file = $LG_LOG;
	} else {
	    $file = "$cache_dir/lg.log";
	}
	#  log date, hostname, query, addr
	if (open(LOG, ">>$file") == 0) {
	    # stderr, if all else fails
	    printf(STDERR "[" . strftime("%a %b %e %H:%M:%S %Y", gmtime) .
			"] could not open log file $file: $!\n");
	    printf(STDERR $msg);
	} else {
	    printf(LOG $msg);
	    close(LOG);
	}
    }
    return;
}

# read LG configuration file
sub readconf
{
    my($conffile, $cmds);
    local(*CONF);
    if (defined($ENV{LG_CONF})) {
	$conffile = $ENV{LG_CONF};
    } elsif (-e "lg.conf") {
	$conffile = "lg.conf";
    } else {
	$conffile = "$SYSCONFDIR/lg.conf";
    }

    if (! -f $conffile) {
	return;
    }

    if (open(CONF, "< $conffile")) {
	while () {
	    next if (/^\s*(#|$)/);
	    $cmds .= $_;
	}
	close(CONF);
	eval $cmds;
    } else {
	printf(STDERR "ERROR: couldn\'t open the configuration file: " .
							"$conffile: $!\n");
	exit(1);
    }

    return;
}

# read router.db file
sub readrouters
{
    my($rtrdb);
    local(*RTR);

    if (defined($LG_ROUTERDB)) {
	$rtrdb = $LG_ROUTERDB;
    } else {
	$rtrdb = "$SYSCONFDIR/router.db";
    }

    if (! -f $rtrdb) {
	my(@dirs, $dir);
	# if the router.db file does not exist, try to compile the list from
	# the rancid group router.db files.
	local(*DIR);
	if (! opendir(DIR, $LOCALSTATEDIR)) {
	    dolog(LOG_ERR, "ERROR: couldn\'t read $LOCALSTATEDIR: $!\n");
	} else {
	    while ($dir = readdir(DIR)) {
		next if ($dir =~ /^(\.|\.\.|\.ssh|CVS|bin|etc|logs|util)$/);
		push(@dirs, $dir) if (-d "$LOCALSTATEDIR/$dir");
	    }
	    closedir(DIR);

	    foreach $dir (@dirs) {
		if (! opendir(DIR, "$LOCALSTATEDIR/$dir")) {
		    dolog(LOG_ERR,
			"ERROR: couldn\'t read $LOCALSTATEDIR/$dir: $!\n");
		    next;
		}
		closedir(DIR);
		next if (! -f "$LOCALSTATEDIR/$dir/router.db");
		if (open(RTR, "< $LOCALSTATEDIR/$dir/router.db")) {
		    while () {
			next if (/^\s*(#|$)/);
			# fqdn:mfg:state
			@record = split('\:', $_);
			next if ($record[2] !~ /up/i || $record[1] !~ /(cisco|foundry|juniper)/);
			push(@rtrlist, join(':', ($record[0], $record[1])));
			$rtrlabels{join(':', ($record[0], $record[1]))} = $record[0];
		    }
		    close(RTR);
		} else {
		    dolog(LOG_ERR, "ERROR: couldn\'t open the router.db " .
				"file: $LOCALSTATEDIR/$dir/router.db: $!\n");
		}
	    }
	}
    } else {
	if (open(RTR, "< $rtrdb")) {
	    while () {
		next if (/^\s*(#|$)/);
		# fqdn:mfg:state
		@record = split('\:', $_);
		next if ($record[2] !~ /up/i || $record[1] !~ /(cisco|foundry|juniper)/);
		push(@rtrlist, join(':', ($record[0], $record[1])));
		$rtrlabels{join(':', ($record[0], $record[1]))} = $record[0];
	    }
	    close(RTR);
	} else {
	    dolog(LOG_ERR, "ERROR: couldn\'t open the router.db file: " .
								"$rtrdb: $!\n");
	    exit(1);
	}
    }

    return;
}

# Main()
# read the configuration file if it exists.
readconf();

$query = new CGI;

print $query->header;
if ($LG_STYLE) {
    print $query->start_html(-title =>"LookingGlass form",
						-style => {'src' => $LG_STYLE});
} else {
    print $query->start_html(-title =>"LookingGlass form");
}

# add the company image, LG_IMAGE
print $LG_IMAGE;

print <
Looking Glass


HEAD # start table, etc here print $query->startform( -action => 'lg.cgi', -method => 'POST'); print < DOTABLE # available query types here print <
Query: Router:
TABLEHEAD foreach $sub_type (sort keys(%$queries)) { next if (! scalar(%{$queries->{$sub_type}})); print $query->radio_group (-name => 'query', -values => $queries->{$sub_type}, -default => '-', -linebreak => 'true'); print "\n" . $query->hr . "\n"; } print <Argument(s):

QTYPES # read routers table and create the scrolling list readrouters(); print $query->scrolling_list(-name => 'router', -values => \@rtrlist, -size => 20, -labels => \%rtrlabels); # end print <

TABLEEND print $query->submit(-name => 'submit', -value =>'Submit'); print $query->reset; print $query->endform; print <
Looking Glass notes

$LG_INFO TAIL print $query->end_html; exit(0); rancid-2.3.8/bin/rancid-cvs.in100644 015615 000000 00000011105 11665257036 0011620#! /bin/sh ## ## $Id: rancid-cvs.in 2340 2011-11-29 22:30:30Z heas $ ## ## @PACKAGE@ @VERSION@ ## Copyright (c) @COPYYEARS@ by Terrapin Communications, Inc. ## All rights reserved. ## ## This code is derived from software contributed to and maintained by ## Terrapin Communications, Inc. by Henry Kilmer, John Heasley, Andrew Partan, ## Pete Whiting, Austin Schutz, and Andrew Fort. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions ## are met: ## 1. Redistributions of source code must retain the above copyright ## notice, this list of conditions and the following disclaimer. ## 2. Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## 3. All advertising materials mentioning features or use of this software ## must display the following acknowledgement: ## This product includes software developed by Terrapin Communications, ## Inc. and its contributors for RANCID. ## 4. Neither the name of Terrapin Communications, Inc. nor the names of its ## contributors may be used to endorse or promote products derived from ## this software without specific prior written permission. ## 5. It is requested that non-binding fixes and modifications be contributed ## back to Terrapin Communications, Inc. ## ## THIS SOFTWARE IS PROVIDED BY Terrapin Communications, INC. AND CONTRIBUTORS ## ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ## TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COMPANY OR CONTRIBUTORS ## BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ## CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ## SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ## INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ## CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ## ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ## POSSIBILITY OF SUCH DAMAGE. # # Create all of the misc files & dirs needed for each group and import them # into CVS or Subversion. # # rancid-cvs # # Read in the environment ENVFILE="@sysconfdir@/rancid.conf" # print a usage message to stderr pr_usage() { echo "usage: $0 [-V] [group [group ...]]" >&2; } # command-line options # -V print version string if [ $# -ge 1 ] ; then while [ 1 ] ; do case $1 in -V) echo "@PACKAGE@ @VERSION@" exit 0 ;; -*) echo "unknown option: $1" >&2 pr_usage exit 1 ;; *) break; ;; esac done fi . $ENVFILE # Base dir if [ ! -d $BASEDIR ]; then mkdir -p $BASEDIR || (echo "Could not create local state directory: $BASEDIR"; exit 1) fi cd $BASEDIR # RCS system RCSSYS=${RCSSYS:=cvs}; if [ $RCSSYS != "cvs" -a $RCSSYS != "svn" ] ; then echo "$RCSSYS is not a valid value for RCSSYS." exit 1 fi # Top level CVS stuff if [ $RCSSYS = cvs ]; then if [ ! -d $CVSROOT ]; then cvs -d $CVSROOT init fi else if echo "$CVSROOT" | grep -q "://"; then # do nothing because CVSROOT is some sort of a URL # also assume the repository has already been provisioned : else if ! svn ls "file://$CVSROOT" >/dev/null 2>&1; then svnadmin create $CVSROOT @SVN_FSTYPE@ fi CVSROOT="file://$CVSROOT" fi fi # Log dir if [ ! -d logs ]; then mkdir logs fi # Which groups to do if [ $# -ge 1 ] ; then LIST_OF_GROUPS="$*"; export LIST_OF_GROUPS elif [ "$LIST_OF_GROUPS" = "" ] ; then echo "LIST_OF_GROUPS is empty in $ENVFILE" exit 1 fi for GROUP in `echo $LIST_OF_GROUPS` ; do DIR=$BASEDIR/$GROUP # Directory for the group and the configs if [ ! -d $DIR ]; then mkdir -p $DIR cd $DIR if [ $RCSSYS = cvs ]; then cvs import -m "$GROUP" $GROUP new rancid cd $BASEDIR cvs checkout $GROUP else svn import -m "$GROUP" . $CVSROOT/$GROUP cd $BASEDIR svn checkout $CVSROOT/$GROUP $GROUP cd $DIR svn update fi fi cd $DIR if [ ! -d configs ]; then mkdir configs $RCSSYS add configs $RCSSYS commit -m 'new' configs fi # main files if [ ! -f routers.all ]; then touch routers.all fi if [ ! -f routers.down ]; then touch routers.down fi if [ ! -f routers.up ]; then touch routers.up fi if [ ! -f router.db ]; then touch router.db $RCSSYS add router.db $RCSSYS commit -m 'new' router.db fi done rancid-2.3.8/bin/rancid-run.in100644 015615 000000 00000011423 11661274022 0011622#! /bin/sh ## ## $Id: rancid-run.in 2334 2011-11-17 21:09:37Z heas $ ## ## @PACKAGE@ @VERSION@ ## Copyright (c) @COPYYEARS@ by Terrapin Communications, Inc. ## All rights reserved. ## ## This code is derived from software contributed to and maintained by ## Terrapin Communications, Inc. by Henry Kilmer, John Heasley, Andrew Partan, ## Pete Whiting, Austin Schutz, and Andrew Fort. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions ## are met: ## 1. Redistributions of source code must retain the above copyright ## notice, this list of conditions and the following disclaimer. ## 2. Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## 3. All advertising materials mentioning features or use of this software ## must display the following acknowledgement: ## This product includes software developed by Terrapin Communications, ## Inc. and its contributors for RANCID. ## 4. Neither the name of Terrapin Communications, Inc. nor the names of its ## contributors may be used to endorse or promote products derived from ## this software without specific prior written permission. ## 5. It is requested that non-binding fixes and modifications be contributed ## back to Terrapin Communications, Inc. ## ## THIS SOFTWARE IS PROVIDED BY Terrapin Communications, INC. AND CONTRIBUTORS ## ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ## TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COMPANY OR CONTRIBUTORS ## BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ## CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ## SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ## INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ## CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ## ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ## POSSIBILITY OF SUCH DAMAGE. # # Run rancid for each of the rancid groups defined by $LIST_OF_GROUPS in # @sysconfdir@/rancid.conf or those specified on the command-line. # # Default ENVFILE, overrideable with -f flag. ENVFILE="@sysconfdir@/rancid.conf" TMPDIR=${TMPDIR:=/tmp}; export TMPDIR # control_rancid argv CR_ARGV=""; export CR_ARGV # print a usage message to stderr pr_usage() { echo "usage: $0 [-V] [-f config_file] [-r device_name] [-m mail rcpt] [group [group ...]]" >&2; } # command-line options # -V # -f # -m # -r if [ $# -ge 1 ] ; then while [ 1 ] ; do case $1 in -V) echo "@PACKAGE@ @VERSION@" exit 0 ;; -f) shift # next arg is the alternate config file name ENVFILE="$1" if [ -z $ENVFILE ]; then pr_usage exit 1 fi shift ;; -m) shift # next arg is the mailto name CR_ARGV="$CR_ARGV -m $1"; export CR_ARGV shift ;; -r) shift # next arg is the device name CR_ARGV="$CR_ARGV -r $1"; export CR_ARGV shift ;; --) shift; break; ;; -h) pr_usage exit ;; -*) echo "unknown option: $1" >&2 pr_usage exit 1 ;; *) break; ;; esac done fi . $ENVFILE if [ $# -ge 1 ] ; then LIST_OF_GROUPS="$*"; export LIST_OF_GROUPS elif [ "$LIST_OF_GROUPS" = "" ] ; then echo "LIST_OF_GROUPS is empty in $ENVFILE" exit 1 fi if [ ! -d $LOGDIR ] ; then mkdir $LOGDIR || (echo "Could not create log directory: $LOGDIR"; exit 1) fi for GROUP in $LIST_OF_GROUPS do LOCKFILE=$TMPDIR/.$GROUP.run.lock ( echo starting: `date` echo if [ -f $LOCKFILE ] then echo hourly config diffs failed: $LOCKFILE exists ls -l $LOCKFILE # Send email if the lock file is old. if [ "X$LOCKTIME" = "X" ] ; then LOCKTIME=4 fi @PERLV@ -e "\$t = (stat(\"$LOCKFILE\"))[9]; print \"OLD\\n\" if (time() - \$t >= $LOCKTIME*60*60);" > $TMPDIR/.$GROUP.old if [ -s $TMPDIR/.$GROUP.old ] then ( echo "To: @ADMINMAILPLUS@${GROUP}${MAILDOMAIN}" echo "Subject: rancid hung - $GROUP" echo "Precedence: bulk" echo "" cat <$LOGDIR/$GROUP.`date +%Y%m%d.%H%M%S` 2>&1 done rancid-2.3.8/man/Makefile.am100644 015615 000000 00000010714 11556057121 0011273## Process this file with automake to produce Makefile.in ## A Makefile.in is supplied, in case you do not have automake. ## $Id: Makefile.am 2294 2011-04-26 18:11:32Z heas $ ## ## Copyright (c) 1997-2007 by Terrapin Communications, Inc. ## All rights reserved. ## ## This code is derived from software contributed to and maintained by ## Terrapin Communications, Inc. by Henry Kilmer, John Heasley, Andrew Partan, ## Pete Whiting, Austin Schutz, and Andrew Fort. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions ## are met: ## 1. Redistributions of source code must retain the above copyright ## notice, this list of conditions and the following disclaimer. ## 2. Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## 3. All advertising materials mentioning features or use of this software ## must display the following acknowledgement: ## This product includes software developed by Terrapin Communications, ## Inc. and its contributors for RANCID. ## 4. Neither the name of Terrapin Communications, Inc. nor the names of its ## contributors may be used to endorse or promote products derived from ## this software without specific prior written permission. ## 5. It is requested that non-binding fixes and modifications be contributed ## back to Terrapin Communications, Inc. ## ## THIS SOFTWARE IS PROVIDED BY Terrapin Communications, INC. AND CONTRIBUTORS ## ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ## TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COMPANY OR CONTRIBUTORS ## BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ## CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ## SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ## INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ## CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ## ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ## POSSIBILITY OF SUCH DAMAGE. # # The expect login scripts were based on Erik Sherk's gwtn, by permission. # # The original looking glass software was written by Ed Kern, provided by # permission and modified beyond recognition. AUTOMAKE_OPTIONS=foreign no-dependencies @SET_MAKE@ man_gen_MANS = lg.conf.5 rancid.conf.5 lg_intro.1 man_nogen_MANS = agmrancid.1 alogin.1 arancid.1 arrancid.1 avologin.1 \ avorancid.1 blogin.1 brancid.1 cat5rancid.1 clogin.1 \ cloginrc.5 control_rancid.1 cssrancid.1 elogin.1 erancid.1 \ f5rancid.1 f10rancid.1 flogin.1 fnlogin.1 fnrancid.1 francid.1 \ hlogin.1 hrancid.1 htlogin.1 htrancid.1 jerancid.1 jlogin.1 \ jrancid.1 mrancid.1 mrvlogin.1 mrvrancid.1 mtlogin.1 \ mtrancid.1 nlogin.1 nrancid.1 nslogin.1 nsrancid.1 nxrancid.1 \ par.1 prancid.1 rancid-cvs.1 rancid-run.1 rancid.1 \ rancid_intro.1 rivlogin.1 rivrancid.1 router.db.5 rrancid.1 \ srancid.1 tlogin.1 tntlogin.1 tntrancid.1 trancid.1 xrancid.1 \ xrrancid.1 zrancid.1 man_MANS = $(man_nogen_MANS) $(man_gen_MANS) EXTRA_DIST = $(man_nogen_MANS) $(man_gen_MANS:%=%.in) CLEANFILES = $(man_gen_MANS) # auto_edit does the autoconf variable substitution. This allows the # substitution to have the full expansion of the variables, e.g.: $sysconfdir # will be /prefix/etc instead of ${prefix}/etc. # # This is a bit of a PITA, but is the method recommended by the autoconf # documentation. auto_edit = sed \ -e 's,@prefix\@,$(prefix),g' \ -e 's,@bindir\@,$(bindir),g' \ -e 's,@localstatedir\@,$(localstatedir),g' \ -e 's,@sysconfdir\@,$(sysconfdir),g' \ -e 's,@pkgdatadir\@,$(pkgdatadir),g' \ -e 's,@ADMINMAILPLUS\@,$(ADMINMAILPLUS),g' \ -e 's,@MAILPLUS\@,$(MAILPLUS),g' lg.conf.5: Makefile $(srcdir)/lg.conf.5.in rm -f lg.conf.5 lg.conf.5.tmp; \ $(auto_edit) $(srcdir)/lg.conf.5.in >lg.conf.5.tmp; \ mv lg.conf.5.tmp lg.conf.5 lg_intro.1: Makefile $(srcdir)/lg_intro.1.in rm -f lg_intro.1 lg_intro.1.tmp; \ $(auto_edit) $(srcdir)/lg_intro.1.in >lg_intro.1.tmp; \ mv lg_intro.1.tmp lg_intro.1 rancid.conf.5: Makefile $(srcdir)/rancid.conf.5.in rm -f rancid.conf.5 rancid.conf.5.tmp; \ $(auto_edit) $(srcdir)/rancid.conf.5.in >rancid.conf.5.tmp; \ mv rancid.conf.5.tmp rancid.conf.5 rancid-2.3.8/man/Makefile.in100644 015615 000000 00000040422 11661274063 0011306# Makefile.in generated by automake 1.11.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, # Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # # The expect login scripts were based on Erik Sherk's gwtn, by permission. # # The original looking glass software was written by Ed Kern, provided by # permission and modified beyond recognition. VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : subdir = man DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_HEADER = $(top_builddir)/include/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = depcomp = am__depfiles_maybe = SOURCES = DIST_SOURCES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' man1dir = $(mandir)/man1 am__installdirs = "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(man5dir)" man5dir = $(mandir)/man5 NROFF = nroff MANS = $(man_MANS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ADMINMAILPLUS = @ADMINMAILPLUS@ AMTAR = @AMTAR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ COMM = @COMM@ COPYYEARS = @COPYYEARS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CVS = @CVS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DIFF = @DIFF@ DIFF_CMD = @DIFF_CMD@ DIRNAME = @DIRNAME@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ENV_PATH = @ENV_PATH@ EXEEXT = @EXEEXT@ EXPECT_PATH = @EXPECT_PATH@ FIND = @FIND@ GREP = @GREP@ ID = @ID@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LG_PING_CMD = @LG_PING_CMD@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAILPLUS = @MAILPLUS@ MAKE = @MAKE@ MAKEINFO = @MAKEINFO@ MKDIR = @MKDIR@ MKDIR_P = @MKDIR_P@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERLV = @PERLV@ PERLV_PATH = @PERLV_PATH@ PING_PATH = @PING_PATH@ RCSSYS = @RCSSYS@ RSH = @RSH@ SENDMAIL = @SENDMAIL@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SORT = @SORT@ SSH = @SSH@ STRIP = @STRIP@ SVN = @SVN@ SVN_FSTYPE = @SVN_FSTYPE@ TAR = @TAR@ TELNET = @TELNET@ TOUCH = @TOUCH@ U = @U@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build_alias = @build_alias@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host_alias = @host_alias@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ AUTOMAKE_OPTIONS = foreign no-dependencies man_gen_MANS = lg.conf.5 rancid.conf.5 lg_intro.1 man_nogen_MANS = agmrancid.1 alogin.1 arancid.1 arrancid.1 avologin.1 \ avorancid.1 blogin.1 brancid.1 cat5rancid.1 clogin.1 \ cloginrc.5 control_rancid.1 cssrancid.1 elogin.1 erancid.1 \ f5rancid.1 f10rancid.1 flogin.1 fnlogin.1 fnrancid.1 francid.1 \ hlogin.1 hrancid.1 htlogin.1 htrancid.1 jerancid.1 jlogin.1 \ jrancid.1 mrancid.1 mrvlogin.1 mrvrancid.1 mtlogin.1 \ mtrancid.1 nlogin.1 nrancid.1 nslogin.1 nsrancid.1 nxrancid.1 \ par.1 prancid.1 rancid-cvs.1 rancid-run.1 rancid.1 \ rancid_intro.1 rivlogin.1 rivrancid.1 router.db.5 rrancid.1 \ srancid.1 tlogin.1 tntlogin.1 tntrancid.1 trancid.1 xrancid.1 \ xrrancid.1 zrancid.1 man_MANS = $(man_nogen_MANS) $(man_gen_MANS) EXTRA_DIST = $(man_nogen_MANS) $(man_gen_MANS:%=%.in) CLEANFILES = $(man_gen_MANS) # auto_edit does the autoconf variable substitution. This allows the # substitution to have the full expansion of the variables, e.g.: $sysconfdir # will be /prefix/etc instead of ${prefix}/etc. # # This is a bit of a PITA, but is the method recommended by the autoconf # documentation. auto_edit = sed \ -e 's,@prefix\@,$(prefix),g' \ -e 's,@bindir\@,$(bindir),g' \ -e 's,@localstatedir\@,$(localstatedir),g' \ -e 's,@sysconfdir\@,$(sysconfdir),g' \ -e 's,@pkgdatadir\@,$(pkgdatadir),g' \ -e 's,@ADMINMAILPLUS\@,$(ADMINMAILPLUS),g' \ -e 's,@MAILPLUS\@,$(MAILPLUS),g' all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign man/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign man/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-man1: $(man_MANS) @$(NORMAL_INSTALL) test -z "$(man1dir)" || $(MKDIR_P) "$(DESTDIR)$(man1dir)" @list=''; test -n "$(man1dir)" || exit 0; \ { for i in $$list; do echo "$$i"; done; \ l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ sed -n '/\.1[a-z]*$$/p'; \ } | while read p; do \ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; echo "$$p"; \ done | \ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ sed 'N;N;s,\n, ,g' | { \ list=; while read file base inst; do \ if test "$$base" = "$$inst"; then list="$$list $$file"; else \ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \ fi; \ done; \ for i in $$list; do echo "$$i"; done | $(am__base_list) | \ while read files; do \ test -z "$$files" || { \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \ done; } uninstall-man1: @$(NORMAL_UNINSTALL) @list=''; test -n "$(man1dir)" || exit 0; \ files=`{ for i in $$list; do echo "$$i"; done; \ l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ sed -n '/\.1[a-z]*$$/p'; \ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ test -z "$$files" || { \ echo " ( cd '$(DESTDIR)$(man1dir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(man1dir)" && rm -f $$files; } install-man5: $(man_MANS) @$(NORMAL_INSTALL) test -z "$(man5dir)" || $(MKDIR_P) "$(DESTDIR)$(man5dir)" @list=''; test -n "$(man5dir)" || exit 0; \ { for i in $$list; do echo "$$i"; done; \ l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ sed -n '/\.5[a-z]*$$/p'; \ } | while read p; do \ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; echo "$$p"; \ done | \ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^5][0-9a-z]*$$,5,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ sed 'N;N;s,\n, ,g' | { \ list=; while read file base inst; do \ if test "$$base" = "$$inst"; then list="$$list $$file"; else \ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man5dir)/$$inst'"; \ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man5dir)/$$inst" || exit $$?; \ fi; \ done; \ for i in $$list; do echo "$$i"; done | $(am__base_list) | \ while read files; do \ test -z "$$files" || { \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man5dir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(man5dir)" || exit $$?; }; \ done; } uninstall-man5: @$(NORMAL_UNINSTALL) @list=''; test -n "$(man5dir)" || exit 0; \ files=`{ for i in $$list; do echo "$$i"; done; \ l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ sed -n '/\.5[a-z]*$$/p'; \ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^5][0-9a-z]*$$,5,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ test -z "$$files" || { \ echo " ( cd '$(DESTDIR)$(man5dir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(man5dir)" && rm -f $$files; } tags: TAGS TAGS: ctags: CTAGS CTAGS: distdir: $(DISTFILES) @list='$(MANS)'; if test -n "$$list"; then \ list=`for p in $$list; do \ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ if test -f "$$d$$p"; then echo "$$d$$p"; else :; fi; done`; \ if test -n "$$list" && \ grep 'ab help2man is required to generate this page' $$list >/dev/null; then \ echo "error: found man pages containing the \`missing help2man' replacement text:" >&2; \ grep -l 'ab help2man is required to generate this page' $$list | sed 's/^/ /' >&2; \ echo " to fix them, install help2man, remove and regenerate the man pages;" >&2; \ echo " typically \`make maintainer-clean' will remove them" >&2; \ exit 1; \ else :; fi; \ else :; fi @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(MANS) installdirs: for dir in "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(man5dir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-man install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-man1 install-man5 install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-man uninstall-man: uninstall-man1 uninstall-man5 .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic distclean \ distclean-generic distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-man1 install-man5 install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic pdf \ pdf-am ps ps-am uninstall uninstall-am uninstall-man \ uninstall-man1 uninstall-man5 @SET_MAKE@ lg.conf.5: Makefile $(srcdir)/lg.conf.5.in rm -f lg.conf.5 lg.conf.5.tmp; \ $(auto_edit) $(srcdir)/lg.conf.5.in >lg.conf.5.tmp; \ mv lg.conf.5.tmp lg.conf.5 lg_intro.1: Makefile $(srcdir)/lg_intro.1.in rm -f lg_intro.1 lg_intro.1.tmp; \ $(auto_edit) $(srcdir)/lg_intro.1.in >lg_intro.1.tmp; \ mv lg_intro.1.tmp lg_intro.1 rancid.conf.5: Makefile $(srcdir)/rancid.conf.5.in rm -f rancid.conf.5 rancid.conf.5.tmp; \ $(auto_edit) $(srcdir)/rancid.conf.5.in >rancid.conf.5.tmp; \ mv rancid.conf.5.tmp rancid.conf.5 # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: rancid-2.3.8/man/agmrancid.1100644 015615 000000 00000000022 11342156264 0011236.so man1/rancid.1 rancid-2.3.8/man/alogin.1100644 015615 000000 00000000022 11342156264 0010562.so man1/clogin.1 rancid-2.3.8/man/arancid.1100644 015615 000000 00000000022 11342156264 0010712.so man1/rancid.1 rancid-2.3.8/man/arrancid.1100644 015615 000000 00000000022 11342156264 0011074.so man1/rancid.1 rancid-2.3.8/man/avologin.1100644 015615 000000 00000000022 11342156264 0011127.so man1/clogin.1 rancid-2.3.8/man/avorancid.1100644 015615 000000 00000000022 11342156264 0011257.so man1/rancid.1 rancid-2.3.8/man/blogin.1100644 015615 000000 00000000022 11342156264 0010563.so man1/clogin.1 rancid-2.3.8/man/brancid.1100644 015615 000000 00000000022 11342156264 0010713.so man1/rancid.1 rancid-2.3.8/man/cat5rancid.1100644 015615 000000 00000000022 11342156264 0011326.so man1/rancid.1 rancid-2.3.8/man/clogin.1100644 015615 000000 00000015574 11556057121 0010605.\" .hys 50 .TH "clogin" "1" "26 April 2011" .SH NAME clogin \- Cisco login script .SH SYNOPSIS .B clogin [\fB\-autoenable\fP] [\fB\-noenable\fP] [\fB\-dSV\fR] [\c .BI \-c\ command] [\c .BI \-E\ var=x] [\c .BI \-e\ enable-password] [\c .BI \-f\ cloginrc-file] [\c .BI \-p\ user-password] [\c .BI \-s\ script-file] [\c .BI \-t\ timeout] [\c .BI \-u\ username] [\c .BI \-v\ vty-password] [\c .BI \-w\ enable-username] [\c .BI \-x\ command-file] [\c .BI \-y\ ssh_cypher_type] router [router...] .SH DESCRIPTION .B clogin is an .BR expect (1) script to automate the process of logging into a Cisco router, catalyst switch, Extreme switch, Juniper ERX/E-series, Procket Networks, or Redback router. There are complementary scripts for Alteon, Avocent (Cyclades), Bay Networks (nortel), ADC-kentrox EZ-T3 mux, Foundry, HP Procurve switches and Cisco AGMs, Hitachi routers, Juniper Networks, MRV optical switch, Mikrotik routers, Netscreen firewalls, Netscaler, Riverstone, Netopia, and Lucent TNT, named .B alogin, .B avologin, .B blogin, .B elogin, .B flogin, .B fnlogin, .B hlogin, .B htlogin, .B jlogin, .B mrvlogin, .B mtlogin, .B nlogin, .B nslogin, .B rivlogin, .B tlogin, and .B tntlogin, respectively. .PP .B clogin reads the .IR .cloginrc file for its configuration, then connects and logs into each of the routers specified on the command line in the order listed. Command-line options exist to override some of the directives found in the .IR .cloginrc configuration file. .PP The command-line options are as follows: .TP .B \-S Save the configuration on exit, if the device prompts at logout time. This only has affect when used with -s. .TP .B \-V Prints package name and version strings. .\" .TP .B \-c Command to be run on each router list on the command-line. Multiple commands maybe listed by separating them with semi-colons (;). The argument should be quoted to avoid shell expansion. .\" .TP .B \-d Enable expect debugging. .\" .TP .B \-E Specifies a variable to pass through to scripts (\-s). For example, the command-line option \-Efoo=bar will produce a global variable by the name Efoo with the initial value "bar". .\" .TP .B \-e Specify a password to be supplied when gaining enable privileges on the router(s). Also see the password directive of the .IR .cloginrc file. .\" .TP .B \-f Specifies an alternate configuration file. The default is .IR "$HOME/.cloginrc" . .\" .TP .B \-p Specifies a password associated with the user specified by the .B \-u option, user directive of the .IR .cloginrc file, or the Unix username of the user. .\" .TP .B \-s The filename of an .BR expect (1) script which will be sourced after the login is successful and is expected to return control to .B clogin, with the connection to the router intact, when it is done. Note that .B clogin disables .IR log_user of .BR expect (1) when .B \-s is used. Example script(s) can be found in share/rancid/*.exp. .\" .TP .B \-t Alters the timeout interval; the period that .B clogin waits for an individual command to return a prompt or the login process to produce a prompt or failure. The argument is in seconds. .\" .TP .B \-u Specifies the username used when prompted. The command-line option overrides any user directive found in .IR .cloginrc . The default is the current Unix username. .\" .TP .B \-v Specifies a vty password, that which is prompted for upon connection to the router. This overrides the vty password of the .IR .cloginrc file's password directive. .\" .TP .B \-w Specifies the username used if prompted when gaining enable privileges. The command-line option overrides any user or enauser directives found in .IR .cloginrc . The default is the current Unix username. .\" .TP .B \-x Similar to the .B \-c option; .B \-x specifies a file with commands to run on each of the routers. The commands must not expect additional input, such as 'copy rcp startup-config' does. For example: .PP .in +1i .nf show version show logging .fi .in -1i .\" .TP .B \-y Specifies the encryption algorithm for use with the .BR ssh (1) \-c option. The default encryption type is often not supported. See the .BR ssh (1) man page for details. The default is 3des. .El .\" .SH RETURNS If the login script fails for any of the devices on the command-line, the exit value of the script will be non-zero and the value will be the number of failures. .\" .SH ENVIRONMENT .B clogin recognizes the following environment variables. .PP .TP .B CISCO_USER Overrides the user directive found in the .IR .cloginrc file, but may be overridden by the .B \-u option. .\" .TP .B CLOGIN .B clogin will not change the banner on your xterm window if this includes the character 'x'. .\" .TP .B CLOGINRC Specifies an alternative location for the .IR .cloginrc file, like the \fB\-f\fP option. .\" .TP .B HOME Normally set by .BR login (1) to the user's home directory, HOME is used by .B clogin to locate the .IR .cloginrc configuration file. .El .SH FILES .ta \w'xHOME/xcloginrc 'u \fI$HOME/.cloginrc\fR Configuration file. .SH "SEE ALSO" .BR cloginrc (5), .BR expect (1) .\" .SH CAVEATS .B clogin expects CatOS devices to have a prompt which includes a '>', such as "router> (enable)". It uses this to determine, for example, whether the command to disable the pager is "set length 0" or "term length 0". .PP The HP Procurve switches that are Foundry OEMs use flogin, not hlogin. .PP The Extreme is supported by .B clogin, but it has no concept of an "enabled" privilege level. You must set autoenable for these devices in your .IR .cloginrc . .PP The -S option is a recent addition, it may not be supported in all of the login scripts or for every target device. .\" .SH BUGS Do not use greater than (>) or pound sign (#) in device banners. These are the normal terminating characters of device prompts and the login scripts need to locate the initial prompt. Afterward, the full prompt is collected and makes a more precise match so that the scripts know when the device is ready for the next command. .PP All these login scripts for separate devices should be rolled into one. This goal is exceedingly difficult. .PP The HP Procurve switch, Motorola BSR, and Cisco AGM CLIs rely heavily upon terminal escape codes for cursor/screen manipulation and assumes a vt100 terminal type. They do not provide a way to set a different terminal type or adjust this behavior. The resulting escape codes make automating interaction with these devices very difficult or impossible. Thus bin/hpuifilter, which must be found in the user's PATH, is used by hlogin to filter these escape sequences. While this works for rancid's collection, there are side effects for interactive logins via hlogin; most of which are formatting annoyances that may be remedied by typing CTRL-R to reprint the current line. .PP WARNING: repeated ssh login failures to HP Procurves cause the switch's management interface to lock-up (this includes snmp, ping) and sometimes it will crash. This is with the latest firmware; 5.33 at the time of this writing. rancid-2.3.8/man/cloginrc.5100644 015615 000000 00000022275 11342156264 0011133.\" .\" $Id: cloginrc.5 2139 2010-02-10 19:29:27Z heas $ .\" .hys 50 .TH "cloginrc" "5" "9 February 2009" .SH NAME \.cloginrc \- clogin configuration file .SH DESCRIPTION .B .cloginrc contains configuration information for .BR alogin (1), .BR blogin (1), .BR clogin (1), .BR elogin (1), .BR flogin (1), .BR hlogin (1), .BR htlogin (1), .BR jlogin (1), .BR nlogin (1), .BR nslogin (1), .BR rivlogin (1), and .BR tntlogin (1), such as usernames, passwords, ssh encryption type, etc., and is read at run-time. .PP Each line contains either white-space (blank line), a comment which begins with the comment character '#' and may be preceded by white-space, or one of the directives listed below. .PP Each line containing a directive is of the form: .PP .in +1i .nf add {} [{} ...] .sp or .sp include {} .fi .in -1i .PP Note: the braces ({}) surrounding the values is significant when the values include TCL meta-characters. Best common practice is to always enclose the values in braces. If a value includes a (left or right) brace or space character, it must be backslash-escaped, as in: .PP .in +1i .nf add user {foo\\}bar} add user {foo\\ bar} .fi .in -1i .PP As .B .cloginrc is searched for a directive matching a hostname, it is always the first matching instance of a directive, one whose hostname glob expression matches the hostname, which is used. For example; looking up the "password" directive for hostname foo in a .B .cloginrc file containing .sp .in +1i .nf add password * {bar} {table} add password foo {bar} {table} .fi .in -1i .sp would return the first line, even though the second is an exact match. .PP .B .cloginrc is expected to exist in the user's home directory and must not be readable, writable, or executable by "others". .B .cloginrc should be mode 0600, or 0640 if it is to be shared with other users who are members of the same unix group. See .BR chgrp (1) and .BR chmod (1) for more information on ownership and file modes. .SH DIRECTIVES The accepted directives are (alphabetically): .PP .\" .TP .B add autoenable {[01]} When using locally defined usernames or AAA, it is possible to have a login which is automatically enabled. This is, that user has enable privileges without the need to execute the enable command. The router's prompt is different for enabled mode, ending with a # rather than a >. .sp Example: add autoenable * {1} .sp Default: 0 .sp zero, meaning that the user is not automatically enabled and .IR clogin should execute the enable command to gain enable privileges, unless negated by the noenable directive or \-noenable command\-line option. .sp Also see the .B noenable directive. .\" .TP .B add cyphertype {} cyphertype defines which encryption algorithm is used with ssh. A device may not support the type ssh uses by default. See .BR ssh (1)'s\c \-c option for details. .sp Default: {3des} .\" .TP .B add enableprompt {""} When using AAA with a Cisco router or switch, it is possible to redefine the prompt the device presents to the user for the enable password. enableprompt may be used to adjust the prompt that .IR clogin should look for when trying to login. Note that enableprompt can be a Tcl style regular expression. .sp Example: add enableprompt rc*.example.net {"\\[Ee]nter\\ the\\ enable\\ password:"} .sp Default: "\\[Pp]assword:" .\" .TP .B add enauser {} This is only needed if a device prompts for a username when gaining enable privileges and where this username is different from that defined by or the default of the user directive. .\" .TP .B add identity {} May be used to specify an alternate identity file for use with ssh(1). See ssh's \-i option for details. .sp Default: your default identity file. see ssh(1). .\" .TP .B add method {ssh} [{...}] Defines, in order, the connection methods to use for a device from the set {ssh, telnet, rsh}. Method telnet may have a suffix, indicating an alternate TCP port, of the form ":port". .sp Note: Different versions of telnet treat the specification of a port differently. In particular, BSD derived telnets do not do option negotiation when a port is given. Some devices, Extreme switches for example, have undesirable telnet default options such as linemode. In the BSD case, to enable option negotiation when specifying a port the method should be "{telnet:-23}" or you should add "mode character" to .telnetrc. See .BR telnet (1) for more information on telnet command-line syntax, telnet options, and .telnetrc. .sp Example: add method * {ssh} {telnet:-3000} {rsh} .sp Which would cause .IR clogin to first attempt an ssh connection to the device and if that were to fail with connection refused, a telnet connection to port 3000 would be tried, and then a rsh connection. .sp Note that not all platforms support all of these connection methods. .sp Default: {telnet} {ssh} .\" .TP .B add noenable {1} .IR clogin will not try to gain enable privileges when noenable is matched for a device. This is equivalent to .IR "clogin" 's -noenable command-line option. .sp Note that this directive is meaningless for .BR jlogin (1), .BR nlogin (1) and .BR clogin (1) [for Extreme] which do not have the concept of "enabled" and/or no way to elevate privleges once logged in; a user either has the necessary privleges or doesn't. .\" .TP .B add passphrase {""} Specify the SSH passphrase. Note that this may be particular to an .B identity directive. The passphrase will default to the .B password for the given router. .sp Example: add passphrase rc*.example.net {the\\ bird\\ goes\\ tweet} .\" .TP .B add passprompt {""} When using AAA with a Cisco router or switch, it is possible to redefine the prompt the device presents to the user for the password. passprompt may be used to adjust the prompt that .IR clogin should look for when trying to login. Note that passprompt can be a Tcl style regular expression. .sp Example: add passprompt rc*.example.net {"\\[Ee]nter\\ the\\ password:"} .sp Default: "(\\[Pp]assword|passwd):" .\" .TP .B add password {} [{}] Specifies a vty password, that which is prompted for upon the connection to the router. The last argument is the enable password and need not be specified if the device also has a matching noenable or autoenable directive or the corresponding command-line options are used. .\" .TP .B add sshcmd {} is the name of the ssh executable. OpenSSH uses a command-line option to specify the protocol version, but other implementations use a separate binary such as "ssh1". .B sshcmd allows this to be adjusted as necessary for the local environment. .sp Default: ssh .\" .TP .B add timeout {} Time in seconds that the login script will wait for input from the device before timeout. .sp Default: device dependent .\" .\" .TP .\" .B add rc {} .\" rc is used to specifies a command that will be run by .\" .IR clogin .\" immediately after logging into the device. Multiple commands may be .\" specified by separating them with semi-colons (;). The command must .\" not be one which expects additional input from the user, such as 'copy .\" rcp startup-config' on a Cisco. .\" .sp .\" Example: add rc *.domain.net {terminal monitor;show version} .\" .TP .B add user {} Specifies a username .IR clogin should use if or when prompted for one. .sp Default: $USER (or $LOGNAME), i.e.: your Unix username. .\" .TP .B add userpassword {} Specifies a password to be associated with a user, if different from that defined with the password directive. .\" .TP .B add userprompt {""} When using AAA with a Cisco router or switch, it is possible to redefine the prompt the device presents to the user for the username. userprompt may be used to adjust the prompt that .IR clogin should look for when trying to login. Note that userprompt can be a Tcl style regular expression. .sp Example: add userprompt rc*.example.net {"\\[Ee]nter\\ your\\ username:"} .sp Default: "(Username|login|user name):" .\" .TP .B include {} is the pathname of an additional .B .cloginrc file to include at that point. It is evaluated immediately. That is important with regard to the order of matching hostnames for a given directive, as mentioned above. This is useful if you have your own .B .cloginrc plus an additional .B .cloginrc file that is shared among a group of folks. .sp If is not a full pathname, $HOME/ will be prepended. .sp Example: include {.cloginrc.group} .El .SH FILES .br .nf .\" set tabstop to longest possible filename, plus a wee bit .ta \w'xHOME/xcloginrc 'u \fI$HOME/.cloginrc\fR Configuration file described here. .\" \fIshare/rancid/cloginrc.sample\fR A sample \fB.cloginrc\fR. .\" .SH ERRORS .B .cloginrc is interpreted directly by Tcl, so its syntax follows that of Tcl. Errors may produce quite unexpected results. .SH "SEE ALSO" .BR clogin (1), .BR glob (3), .BR tclsh (1) rancid-2.3.8/man/control_rancid.1100644 015615 000000 00000002501 11342156264 0012315.\" .hys 50 .TH "control_rancid" "1" "5 October 2006" .SH NAME control_rancid \- run rancid for devices of a group .SH SYNOPSIS .B control_rancid [\fB\-V\fR] [\c .BI \-m\ \c mail_rcpt]\ \c [\c .BI \-r\ \c device_name]\ \c group .SH DESCRIPTION .B control_rancid is a .IR sh (1) script to parse a group's .BR router.db (5), run rancid for each of the devices, possibly re-run rancid for devices that failed collection, e-mail diffs, and e-mail error reports. .\" .PP .\" The command-line options are as follows: .TP .B \-V Prints package name and version strings. .TP .B \-m mail_rcpt Specify the recipient of diff mail, which is normally rancid-. The argument may be a single address, multiple comma separated addresses, or .B \-m may be specified multiple times. .\" .TP .B \-r device_name Specify the name, as it appears in the router.db, of a particular device to collect and generate diffs for. The device must be marked "up". .sp The .B \-r option alters the subject line of the diff mail. It will begin with / rather than just the group name alone. .\" .PP .B control_rancid is normally (and best) run via .BR rancid-run (1) which provides a locking mechanism on a group basis and saves output in a log file for each group. .\" .SH "SEE ALSO" .BR rancid-run (1), .BR rancid.conf (5), .BR router.db (5) rancid-2.3.8/man/cssrancid.1100644 015615 000000 00000000022 11342156264 0011262.so man1/rancid.1 rancid-2.3.8/man/elogin.1100644 015615 000000 00000000022 11342156264 0010566.so man1/clogin.1 rancid-2.3.8/man/erancid.1100644 015615 000000 00000000022 11342156264 0010716.so man1/rancid.1 rancid-2.3.8/man/f5rancid.1100644 015615 000000 00000000022 11342156264 0011004.so man1/rancid.1 rancid-2.3.8/man/f10rancid.1100644 015615 000000 00000000022 11342156264 0011060.so man1/rancid.1 rancid-2.3.8/man/flogin.1100644 015615 000000 00000000022 11342156264 0010567.so man1/clogin.1 rancid-2.3.8/man/fnlogin.1100644 015615 000000 00000000022 11454676276 0010763.so man1/clogin.1 rancid-2.3.8/man/fnrancid.1100644 015615 000000 00000000022 11342156264 0011075.so man1/rancid.1 rancid-2.3.8/man/francid.1100644 015615 000000 00000000022 11342156264 0010717.so man1/rancid.1 rancid-2.3.8/man/par.1100644 015615 000000 00000004260 11342156264 0010103.\" .hys 50 .TH "par" "1" "18 December 2007" .SH NAME par \- parallel command processing .SH SYNOPSIS .B par [\fB\-dfiqx\fP] [\c .BI \-c\ command] [\c .BI \-l\ logfile] [\c .BI \-n\c #] file [file...] .SH DESCRIPTION .B par takes a list of files to run a command on. The first line of each file begins with a colon (:) or a pound-sign (#). If a colon, the remainder of the line is a command to run for each of the subsequent lines. If a pound-sign, then each subsequent line is a (self-contained) command, unless the .B \-c option was specified, in which case it operates as if the argument to .B \-c had followed a colon on the first line. .PP In each of the cases where the lines of the file following the first are not commands (i.e.: colon or -c), instances of open-close braces ({}) in the command will be replaced by these values. .PP For example, a inputfile whose contents is: .sp : echo {} .br a .br b .br c .sp run with .B par like so: .sp %par -q inputfile .sp will produce the following output (order will vary): .sp b .br a .br c .PP The command-line options are as follows: .PP .TP .B \-c Command to be run on each of the arguments following the command-line options, where the first line of the input file(s) begins with a pound-sign (#). .\" .TP .B \-d Print debugging information on standard error (stderr). .\" .TP .B \-f No file or STDIN, just run a quantity of the command specified with -c. .\" .TP .B \-i Run commands interactively through (multiple) .BR xterm (1) processes. .\" .TP .B \-l Prefix of logfile name, as in prefix.N where N is the .B par process number ([0..]). .sp Default: par.log.


    Just a few straight forward notes on our implementation of Ed Kern's looking glass (which was http://nitrous.digex.net).

  • Some items are not implemented for the junipers/foundrys yet (so, as i get to it) or no equivalent command exists.
  • If there is something which you feel is missing, feel free to ask and/or send comments to rancid@shrubbery.net. No guarantees.
  • Only one query per router allowed at any given time. This is to avoid resource deprivation on the looking glass host or the router. The looking glass will attempt to serialize queries.
  • The looking glass will ping a router prior to querying it to avoid trying to query routers which are down or otherwise inaccessible.
  • Login failures can be intermittent or permanent, either due to the router being inaccessible from the looking glass machine, or authorization failure(s). Contact your local network engineering folks to resolve login failures.
  • Queries followed by <something> require an argument(s) in the text window below the query list. Some queries take optional arguments denoted by [something]. Multiple arguments should be separated by a space.
  • Note that output from certain queries is cached by the server and may be slightly out of date. These queries will be noted as such in the output. This is limited to queries which could produce lots of output, such as 'sh ip bgp dampened-paths'.
  • Note that some queries have potential to produce great load on the router and produce lots of output, such as 'sh ip bgp' or 'sh ip bgp reg '^3561'. The looking glass attempts to deny such commands.

Some useful hints:

  • Show interfaces can take arguments other than an interface name, assuming the router is running an O/S version with the capability. For example; a cisco can take 'descriptions' or 'brief' and 'terse' for the juniper.
  • Show ip bgp neighbor can take additional arguments (if configured to allow it), such as 'advertised routes', 'flap-statistics', 'received-routes', and 'routes'. The argument will be converted for the platform.
rancid-2.3.8/share/getipacctg100644 015615 000000 00000012072 11342156264 0011623#! /bin/sh ## ## $Id: getipacctg 2096 2009-06-17 21:49:46Z heas $ ## ## Copyright (c) 1997-2007 by Terrapin Communications, Inc. ## All rights reserved. ## ## This code is derived from software contributed to and maintained by ## Terrapin Communications, Inc. by Henry Kilmer, John Heasley, Andrew Partan, ## Pete Whiting, Austin Schutz, and Andrew Fort. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions ## are met: ## 1. Redistributions of source code must retain the above copyright ## notice, this list of conditions and the following disclaimer. ## 2. Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## 3. All advertising materials mentioning features or use of this software ## must display the following acknowledgement: ## This product includes software developed by Terrapin Communications, ## Inc. and its contributors for RANCID. ## 4. Neither the name of Terrapin Communications, Inc. nor the names of its ## contributors may be used to endorse or promote products derived from ## this software without specific prior written permission. ## 5. It is requested that non-binding fixes and modifications be contributed ## back to Terrapin Communications, Inc. ## ## THIS SOFTWARE IS PROVIDED BY Terrapin Communications, INC. AND CONTRIBUTORS ## ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ## TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COMPANY OR CONTRIBUTORS ## BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ## CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ## SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ## INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ## CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ## ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ## POSSIBILITY OF SUCH DAMAGE. # # The expect login scripts were based on Erik Sherk's gwtn, by permission. # # The original looking glass software was written by Ed Kern, provided by # permission and modified beyond recognition. # # getipacctg uses clogin to login to a cisco router, collect the o/p of # show ip accounting, and sort by the greatest number of bytes. If a # second argument is supplied, it is a number indicating the top N producers. # a third (3 to N) argument(s) specify a prefix(es) to match/select src/dst # IPs, while others will be filtered. # # usage: getipacctg [] \ # [ [...]] # example: # getipacctg router 25 192.168.0.0/24 # will display the top 25 for src or dst ip's within prefix # 192.168.0.0/24 # # Contributed to rancid by Steve Neighorn of SCN Reasearch. TMP="/tmp/ipacct.$$.prefixes" TMP2="/tmp/ipacct.$$.sorted" TMP3="/tmp/ipacct.$$.pl" if [ $# -eq 0 ] ; then echo "usage: getipacctg router_name [] [ [...]]" >&2 exit 1; fi trap 'rm -fr /tmp/ipacct.$$ $TMP $TMP2 $TMP3;' 1 2 15 clogin -c 'show ip accounting' $1 > /tmp/ipacct.$$ if [ $? -ne 0 ] ; then echo "clogin failed." >&2 exit 1 fi # rest of the command-line options exec 6>$TMP HEAD="cat" shift while [ $# -ne 0 ] ; do echo $1 | grep '/' > /dev/null if [ $? -eq 1 ] ; then HEAD="head -$1" else echo $1 1>&6 fi shift done 6>&- egrep '[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+ +[0-9]+\.[0-9]+\.' /tmp/ipacct.$$ | \ sed -e 's/^ *//' -e 's/ */ /g' -e 's/.$//' | \ awk '{print $4":"$0;}' | sort -nr | \ sed -e 's/^[^:]*://' > $TMP2 if [ -s $TMP ] ; then cat > $TMP3 <) { chomp; s/\s*//g; /(.*)\/(.*)\$/; my(\$ip) = \$1; my(\$mask) = \$2; \$ip = ip_to_int(\$ip); \$mask = (~0) << (32 - \$mask); \$ip = \$ip & (\$mask); \$prefs[\$nprefs++] = \$ip; \$prefs[\$nprefs++] = \$mask; } close(PREFS); open(DATA, "< \$ARGV[1]") || die "could not open \$ARGV[1]\n"; while () { chomp; @A = split(/ /); \$A[0] = ip_to_int(\$A[0]); \$A[1] = ip_to_int(\$A[1]); for (\$f = 0; \$f < \$nprefs; \$f += 2) { if ((\$A[0] & \$prefs[\$f + 1]) == \$prefs[\$f] || (\$A[1] & \$prefs[\$f + 1]) == \$prefs[\$f]) { print "\$_\n"; break; } } } PERL perl $TMP3 $TMP $TMP2 | $HEAD else $HEAD $TMP2 fi rm -fr /tmp/ipacct.$$ $TMP $TMP2 $TMP3 trap ';' 1 2 15 exit 0 rancid-2.3.8/share/Makefile.am100644 015615 000000 00000007366 11567537670 0011651## Process this file with automake to produce Makefile.in ## A Makefile.in is supplied, in case you do not have automake. ## $Id: Makefile.am 2301 2011-05-26 20:55:24Z heas $ ## ## Copyright (c) 1997-2008 by Terrapin Communications, Inc. ## All rights reserved. ## ## This code is derived from software contributed to and maintained by ## Terrapin Communications, Inc. by Henry Kilmer, John Heasley, Andrew Partan, ## Pete Whiting, Austin Schutz, and Andrew Fort. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions ## are met: ## 1. Redistributions of source code must retain the above copyright ## notice, this list of conditions and the following disclaimer. ## 2. Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## 3. All advertising materials mentioning features or use of this software ## must display the following acknowledgement: ## This product includes software developed by Terrapin Communications, ## Inc. and its contributors for RANCID. ## 4. Neither the name of Terrapin Communications, Inc. nor the names of its ## contributors may be used to endorse or promote products derived from ## this software without specific prior written permission. ## 5. It is requested that non-binding fixes and modifications be contributed ## back to Terrapin Communications, Inc. ## ## THIS SOFTWARE IS PROVIDED BY Terrapin Communications, INC. AND CONTRIBUTORS ## ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ## TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COMPANY OR CONTRIBUTORS ## BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ## CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ## SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ## INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ## CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ## ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ## POSSIBILITY OF SUCH DAMAGE. # # The expect login scripts were based on Erik Sherk's gwtn, by permission. # # The original looking glass software was written by Ed Kern, provided by # permission and modified beyond recognition. #AUTOMAKE_OPTIONS=foreign no-dependencies AUTOMAKE_OPTIONS=foreign pkgdata_SCRIPTS= rancid-cvspurge rtrfilter downreport dist_pkgdata_SCRIPTS=getipacctg dist_pkgdata_DATA=README.misc cisco-load.exp cisco-reload.exp \ index.html lgnotes.html EXTRA_DIST = rancid-cvspurge.in rancid.spec rtrfilter.in downreport.in CLEANFILES= rancid-cvspurge downreport all: # auto_edit does the autoconf variable substitution. This allows the # substitution to have the full expansion of the variables, e.g.: $sysconfdir # will be /prefix/etc instead of ${prefix}/etc. # # This is a bit of a PITA, but is the method recommended by the autoconf # documentation. auto_edit = sed \ -e 's,@prefix\@,$(prefix),g' \ -e 's,@localstatedir\@,$(localstatedir),g' \ -e 's,@sysconfdir\@,$(sysconfdir),g' \ -e 's,@pkgdatadir\@,$(pkgdatadir),g' downreport: Makefile $(srcdir)/downreport.in rm -f downreport downreport.tmp; \ $(auto_edit) $(srcdir)/downreport.in >downreport.tmp; \ chmod +x downreport.tmp; \ mv downreport.tmp downreport rancid-cvspurge: Makefile $(srcdir)/rancid-cvspurge.in rm -f rancid-cvspurge rancid-cvspurge.tmp; \ $(auto_edit) $(srcdir)/rancid-cvspurge.in >rancid-cvspurge.tmp; \ chmod +x rancid-cvspurge.tmp; \ mv rancid-cvspurge.tmp rancid-cvspurge rancid-2.3.8/share/Makefile.in100644 015615 000000 00000037735 11661274064 0011653# Makefile.in generated by automake 1.11.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, # Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # # The expect login scripts were based on Erik Sherk's gwtn, by permission. # # The original looking glass software was written by Ed Kern, provided by # permission and modified beyond recognition. VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : subdir = share DIST_COMMON = $(dist_pkgdata_DATA) $(dist_pkgdata_SCRIPTS) \ $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ $(srcdir)/rtrfilter.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_HEADER = $(top_builddir)/include/config.h CONFIG_CLEAN_FILES = rtrfilter CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__installdirs = "$(DESTDIR)$(pkgdatadir)" "$(DESTDIR)$(pkgdatadir)" \ "$(DESTDIR)$(pkgdatadir)" SCRIPTS = $(dist_pkgdata_SCRIPTS) $(pkgdata_SCRIPTS) SOURCES = DIST_SOURCES = DATA = $(dist_pkgdata_DATA) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ADMINMAILPLUS = @ADMINMAILPLUS@ AMTAR = @AMTAR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ COMM = @COMM@ COPYYEARS = @COPYYEARS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CVS = @CVS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DIFF = @DIFF@ DIFF_CMD = @DIFF_CMD@ DIRNAME = @DIRNAME@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ENV_PATH = @ENV_PATH@ EXEEXT = @EXEEXT@ EXPECT_PATH = @EXPECT_PATH@ FIND = @FIND@ GREP = @GREP@ ID = @ID@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LG_PING_CMD = @LG_PING_CMD@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAILPLUS = @MAILPLUS@ MAKE = @MAKE@ MAKEINFO = @MAKEINFO@ MKDIR = @MKDIR@ MKDIR_P = @MKDIR_P@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERLV = @PERLV@ PERLV_PATH = @PERLV_PATH@ PING_PATH = @PING_PATH@ RCSSYS = @RCSSYS@ RSH = @RSH@ SENDMAIL = @SENDMAIL@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SORT = @SORT@ SSH = @SSH@ STRIP = @STRIP@ SVN = @SVN@ SVN_FSTYPE = @SVN_FSTYPE@ TAR = @TAR@ TELNET = @TELNET@ TOUCH = @TOUCH@ U = @U@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build_alias = @build_alias@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host_alias = @host_alias@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ #AUTOMAKE_OPTIONS=foreign no-dependencies AUTOMAKE_OPTIONS = foreign pkgdata_SCRIPTS = rancid-cvspurge rtrfilter downreport dist_pkgdata_SCRIPTS = getipacctg dist_pkgdata_DATA = README.misc cisco-load.exp cisco-reload.exp \ index.html lgnotes.html EXTRA_DIST = rancid-cvspurge.in rancid.spec rtrfilter.in downreport.in CLEANFILES = rancid-cvspurge downreport # auto_edit does the autoconf variable substitution. This allows the # substitution to have the full expansion of the variables, e.g.: $sysconfdir # will be /prefix/etc instead of ${prefix}/etc. # # This is a bit of a PITA, but is the method recommended by the autoconf # documentation. auto_edit = sed \ -e 's,@prefix\@,$(prefix),g' \ -e 's,@localstatedir\@,$(localstatedir),g' \ -e 's,@sysconfdir\@,$(sysconfdir),g' \ -e 's,@pkgdatadir\@,$(pkgdatadir),g' all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign share/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign share/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): rtrfilter: $(top_builddir)/config.status $(srcdir)/rtrfilter.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ install-dist_pkgdataSCRIPTS: $(dist_pkgdata_SCRIPTS) @$(NORMAL_INSTALL) test -z "$(pkgdatadir)" || $(MKDIR_P) "$(DESTDIR)$(pkgdatadir)" @list='$(dist_pkgdata_SCRIPTS)'; test -n "$(pkgdatadir)" || list=; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ if test -f "$$d$$p"; then echo "$$d$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n' \ -e 'h;s|.*|.|' \ -e 'p;x;s,.*/,,;$(transform)' | sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1; } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) { files[d] = files[d] " " $$1; \ if (++n[d] == $(am__install_max)) { \ print "f", d, files[d]; n[d] = 0; files[d] = "" } } \ else { print "f", d "/" $$4, $$1 } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_SCRIPT) $$files '$(DESTDIR)$(pkgdatadir)$$dir'"; \ $(INSTALL_SCRIPT) $$files "$(DESTDIR)$(pkgdatadir)$$dir" || exit $$?; \ } \ ; done uninstall-dist_pkgdataSCRIPTS: @$(NORMAL_UNINSTALL) @list='$(dist_pkgdata_SCRIPTS)'; test -n "$(pkgdatadir)" || exit 0; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 's,.*/,,;$(transform)'`; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(pkgdatadir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(pkgdatadir)" && rm -f $$files install-pkgdataSCRIPTS: $(pkgdata_SCRIPTS) @$(NORMAL_INSTALL) test -z "$(pkgdatadir)" || $(MKDIR_P) "$(DESTDIR)$(pkgdatadir)" @list='$(pkgdata_SCRIPTS)'; test -n "$(pkgdatadir)" || list=; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ if test -f "$$d$$p"; then echo "$$d$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n' \ -e 'h;s|.*|.|' \ -e 'p;x;s,.*/,,;$(transform)' | sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1; } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) { files[d] = files[d] " " $$1; \ if (++n[d] == $(am__install_max)) { \ print "f", d, files[d]; n[d] = 0; files[d] = "" } } \ else { print "f", d "/" $$4, $$1 } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_SCRIPT) $$files '$(DESTDIR)$(pkgdatadir)$$dir'"; \ $(INSTALL_SCRIPT) $$files "$(DESTDIR)$(pkgdatadir)$$dir" || exit $$?; \ } \ ; done uninstall-pkgdataSCRIPTS: @$(NORMAL_UNINSTALL) @list='$(pkgdata_SCRIPTS)'; test -n "$(pkgdatadir)" || exit 0; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 's,.*/,,;$(transform)'`; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(pkgdatadir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(pkgdatadir)" && rm -f $$files install-dist_pkgdataDATA: $(dist_pkgdata_DATA) @$(NORMAL_INSTALL) test -z "$(pkgdatadir)" || $(MKDIR_P) "$(DESTDIR)$(pkgdatadir)" @list='$(dist_pkgdata_DATA)'; test -n "$(pkgdatadir)" || list=; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgdatadir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgdatadir)" || exit $$?; \ done uninstall-dist_pkgdataDATA: @$(NORMAL_UNINSTALL) @list='$(dist_pkgdata_DATA)'; test -n "$(pkgdatadir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ test -n "$$files" || exit 0; \ echo " ( cd '$(DESTDIR)$(pkgdatadir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(pkgdatadir)" && rm -f $$files tags: TAGS TAGS: ctags: CTAGS CTAGS: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(SCRIPTS) $(DATA) installdirs: for dir in "$(DESTDIR)$(pkgdatadir)" "$(DESTDIR)$(pkgdatadir)" "$(DESTDIR)$(pkgdatadir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dist_pkgdataDATA install-dist_pkgdataSCRIPTS \ install-pkgdataSCRIPTS install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-dist_pkgdataDATA uninstall-dist_pkgdataSCRIPTS \ uninstall-pkgdataSCRIPTS .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic distclean \ distclean-generic distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am \ install-dist_pkgdataDATA install-dist_pkgdataSCRIPTS \ install-dvi install-dvi-am install-exec install-exec-am \ install-html install-html-am install-info install-info-am \ install-man install-pdf install-pdf-am install-pkgdataSCRIPTS \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic pdf \ pdf-am ps ps-am uninstall uninstall-am \ uninstall-dist_pkgdataDATA uninstall-dist_pkgdataSCRIPTS \ uninstall-pkgdataSCRIPTS all: downreport: Makefile $(srcdir)/downreport.in rm -f downreport downreport.tmp; \ $(auto_edit) $(srcdir)/downreport.in >downreport.tmp; \ chmod +x downreport.tmp; \ mv downreport.tmp downreport rancid-cvspurge: Makefile $(srcdir)/rancid-cvspurge.in rm -f rancid-cvspurge rancid-cvspurge.tmp; \ $(auto_edit) $(srcdir)/rancid-cvspurge.in >rancid-cvspurge.tmp; \ chmod +x rancid-cvspurge.tmp; \ mv rancid-cvspurge.tmp rancid-cvspurge # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: rancid-2.3.8/share/rtrfilter.in100644 015615 000000 00000013351 11342156264 0012134#! @PERLV_PATH@ ## ## $Id: rtrfilter.in 2096 2009-06-17 21:49:46Z heas $ ## ## Copyright (c) 1997-2007 by Terrapin Communications, Inc. ## All rights reserved. ## ## This code is derived from software contributed to and maintained by ## Terrapin Communications, Inc. by Henry Kilmer, John Heasley, Andrew Partan, ## Pete Whiting, Austin Schutz, and Andrew Fort. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions ## are met: ## 1. Redistributions of source code must retain the above copyright ## notice, this list of conditions and the following disclaimer. ## 2. Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## 3. All advertising materials mentioning features or use of this software ## must display the following acknowledgement: ## This product includes software developed by Terrapin Communications, ## Inc. and its contributors for RANCID. ## 4. Neither the name of Terrapin Communications, Inc. nor the names of its ## contributors may be used to endorse or promote products derived from ## this software without specific prior written permission. ## 5. It is requested that non-binding fixes and modifications be contributed ## back to Terrapin Communications, Inc. ## ## THIS SOFTWARE IS PROVIDED BY Terrapin Communications, INC. AND CONTRIBUTORS ## ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ## TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COMPANY OR CONTRIBUTORS ## BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ## CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ## SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ## INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ## CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ## ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ## POSSIBILITY OF SUCH DAMAGE. # # The expect login scripts were based on Erik Sherk's gwtn, by permission. # # The original looking glass software was written by Ed Kern, provided by # permission and modified beyond recognition. # # rtrtfilter - "| rtrfilter -x -i -f \ # -u -s " # expects to read an email message on stdin containing a diff from # rancid and emails a filtered copy to with the subject of the # original msg or the contents of -s . the perl regex(es) specified # via -x or -i (exclusive and inclusive, respectively) are applied to the # router names (i.e.: files) from the "Index:" of the diff o/p. alternatively, # the regex's may be specified in -f in the form: # # comment # x # # comment # i # do not include /'s in the regex's. # e.g.: # #i inc1 # i a0[12]\. # i a0[34]\. # # comment # x router\.db # x ^r0[0-9] # #i foo # # exclusion takes precedence and defaults to nothing. inclusion defaults to # everything. # # this program requires the Mail::Mailer module which can be found on CPAN. ## BEGIN { $me = $0; $me =~ s/.*\/(\S+)$/$1/; } require 'newgetopt.pl'; use Mail::Mailer; # process command line options $newgetopt'ignorecase=0; $newgetopt'autoabbrev=1; $result = &NGetOpt('h','x=s@','i=s@','f=s','s=s'); &usage($result) if (defined($opt_h) || $result == 0); if ($#ARGV < 0) { usage; } my($rcpts) = join(',', @ARGV); # if specified, read the regex file and append to @opt_i / @opt_x if (defined($opt_f)) { open(FILE, "< $opt_f") || die "Cant open the regex file $opt_f: $!"; while () { next if (! /^(i|x)\s+(.*$)/); #/(i|x)\s+(.*)$/; if ($1 eq "i" ) { push(@opt_i, $2); } else { push(@opt_x, $2); } } close(FILE); } # read the header, grok the subject line my($subject, $from); while () { last if (/^$/); if (s/^from: //i) { chomp; $from = $_; } if (s/^subject: //i) { chomp; $subject = $_; } } if (defined($opt_s)) { $subject = $opt_s;} if (defined($opt_u)) { $from = $opt_u;} # filter the remainder of the mail. save mail in memory to avoid empty msgs my(@mail); my($skip) = 1; while () { # look for /^Index: ", the filtering key if (/^Index: (.*)$/) { # strip the directory before passing to filter() my($line) = ($1 =~ /.*\/([^\/\s]*)$/); $skip = filter($line); } next if ($skip); push(@mail, $_); } # send mail, if any if ($#mail < 0) { exit; } $mailer = new Mail::Mailer 'sendmail', ('-t'); $headers{From} = $from; $headers{"Reply-To"} = $from; $headers{"Errors-To"} = $from; $headers{Subject} = $subject; $headers{To} = $rcpts; $headers{Precedence} = "bulk"; $mailer->open(\%headers); print $mailer @mail; $mailer->close; exit; # filter $line inclusive/exclusive (0 / 1) sub filter { my($line) = shift; # exclusion if (defined(@opt_x)) { foreach $regex (@opt_x) { if ($line =~ /$regex/) { return(1); } } } # inclusion / default inclusion if (! @opt_i) { return(0); } foreach $regex (@opt_i) { if ($line =~ /$regex/) { return(0); } } # inclusion regex specified, but fall through return(1); } sub usage { print STDERR <] [-x ] [-f ] [-u ] [-s ] [ ...] -h prints this message -f file containing perl regex matching router names (mind the cwd()) -i perl regex matching router names (inclusive) -u From: address -s mail subject -x perl regex matching router names (exclusive) USAGE exit $_; } rancid-2.3.8/share/rancid-cvspurge.in100755 015615 000000 00000006244 11571232354 0013220#! /bin/sh ## ## $Id: downreport.in 2096 2009-06-17 21:49:46Z heas $ ## ## Copyright (c) 1997-2007 by Terrapin Communications, Inc. ## All rights reserved. ## ## This code is derived from software contributed to and maintained by ## Terrapin Communications, Inc. by Henry Kilmer, John Heasley, Andrew Partan, ## Pete Whiting, Austin Schutz, and Andrew Fort. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions ## are met: ## 1. Redistributions of source code must retain the above copyright ## notice, this list of conditions and the following disclaimer. ## 2. Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## 3. All advertising materials mentioning features or use of this software ## must display the following acknowledgement: ## This product includes software developed by Terrapin Communications, ## Inc. and its contributors for RANCID. ## 4. Neither the name of Terrapin Communications, Inc. nor the names of its ## contributors may be used to endorse or promote products derived from ## this software without specific prior written permission. ## 5. It is requested that non-binding fixes and modifications be contributed ## back to Terrapin Communications, Inc. ## ## THIS SOFTWARE IS PROVIDED BY Terrapin Communications, INC. AND CONTRIBUTORS ## ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ## TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COMPANY OR CONTRIBUTORS ## BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ## CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ## SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ## INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ## CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ## ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ## POSSIBILITY OF SUCH DAMAGE. # # The expect login scripts were based on Erik Sherk's gwtn, by permission. # # The original looking glass software was written by Ed Kern, provided by # permission and modified beyond recognition. # # Purges old versions of configurations from the CVS repostiory. # # From Matthew J. Grossman # ENVFILE="@sysconfdir@/rancid.conf" . $ENVFILE if [ $RCSSYS != "cvs" ] ; then echo "$0 is for CVS only. RCSSYS is not set to CVS in rancid.conf." >&2 exit 1 fi if [ $# -ge 1 ] ; then LIST_OF_GROUPS="$*" elif [ "$LIST_OF_GROUPS" = "" ] ; then echo "LIST_OF_GROUPS is empty in $ENVFILE" >&2 exit 1 fi for GROUP in $LIST_OF_GROUPS; do cd $BASEDIR/$GROUP/configs > /dev/null 2>&1 if [ $? -ne 0 ] ; then echo "$BASEDIR/$GROUP/configs not found" >&2 continue; fi for ENTRY in `grep ^/ CVS/Entries | cut -d/ -f2,3` do ROUTER=`echo $ENTRY | cut -d/ -f1` VERSION=`echo $ENTRY | cut -d/ -f2` cvs admin -o ::$VERSION $ROUTER done done rancid-2.3.8/share/rancid.spec100644 015615 000000 00000010436 11567537670 0011721Name: rancid Version: 2.3.7 Release: 1%{?dist} Summary: Really Awesome New Cisco confIg Differ Group: Applications/System License: non-free URL: http://www.shrubbery.net/rancid/ Source: %{name}-%{version}.tar.gz BuildRoot: %{_tmppath}/%{name}-%{version}-root Requires: cvs BuildRequires: expect >= 5.40 %package lg Summary: RANCID Looking Glass CGI scripts Group: Applications/System %description Rancid is a "Really Awesome New Cisco confIg Differ" developed to maintain CVS controlled copies of router configs. Rancid is not limited to Cisco devices. It currently supports Cisco routers, Juniper routers, Catalyst switches, Foundry switches, Redback NASs, ADC EZT3 muxes, MRTd (and thus likely IRRd), Alteon switches, and HP procurve switches and a host of others. %description lg RANCID also includes looking glass software. It is based on Ed Kern's looking glass which was once used for http://nitrous.digex.net/, for the old-school folks who remember it. Our version has added functions, supports cisco, juniper, and foundry and uses the login scripts that come with rancid; so it can use telnet or ssh to connect to your devices(s). %prep %setup -q %build %configure --localstatedir=%{_localstatedir}/rancid make %install rm -rf $RPM_BUILD_ROOT #Fix the missing statedir install -m 755 -d $RPM_BUILD_ROOT/%{_localstatedir}/rancid make install DESTDIR=$RPM_BUILD_ROOT # Get rid of unwanted /usr/share/rancid install rm -rf $RPM_BUILD_ROOT/%{_datadir}/rancid # Move lg CGI scripts to CGI directory install -m 755 -d $RPM_BUILD_ROOT/var/www/cgi-bin mv $RPM_BUILD_ROOT/%{_bindir}/*.cgi $RPM_BUILD_ROOT/var/www/cgi-bin # Workaround for the stupid rpmbuild to NOT search for dependencies in the # documentation. We need to do it here as %doc ignores %attr. find share -type f -print | xargs chmod a-x # Install the sample .cloginrc file cp cloginrc.sample $RPM_BUILD_ROOT/%{_localstatedir}/rancid/.cloginrc %pre if [ $1 -eq 1 ]; then egrep -q '^rancid:' /etc/passwd || useradd -M -r -d %{_localstatedir}/rancid -c "RANCID User" rancid fi %postun if [ $1 -eq 0 ]; then # It's a matter of taste if we should remove the user on uninstall or not userdel rancid fi %clean rm -rf $RPM_BUILD_ROOT %files %defattr(-,root,root,0755) %doc BUGS CHANGES COPYING FAQ README UPGRADING Todo %doc share/cisco-load.exp share/cisco-reload.exp %doc share/rancid-cvspurge share/downreport share/getipacctg share/rtrfilter %config(noreplace) /etc/rancid.conf %{_bindir}/* %{_mandir}/man1/[a-k]* %{_mandir}/man1/[m-z]* %{_mandir}/man5/[a-k]* %{_mandir}/man5/[m-z]* %dir %attr(770,rancid,rancid) %{_localstatedir}/rancid %config(noreplace) %attr(640,rancid,rancid) %{_localstatedir}/rancid/.cloginrc %files lg %defattr(-,root,root,0755) %config(noreplace) /etc/lg.conf %{_mandir}/man1/lg_intro* %{_mandir}/man5/lg.conf* /var/www/cgi-bin/* %doc README.lg %changelog * Fri Feb 11 2011 Florian Koch 2.3.6 - Modified Version to be 2.3.6 - Fix missing 'expect' as BuildRequire (was only Require) - Fix creation of missing statedir before make install - Fix some typos - Replace mkdir with install - Make rpmlint clean (add %%defattr() to lg files section) * Mon Jul 19 2010 Lance Vermilion 2.3.4 - Modified Version to be 2.3.4 and Release to be 1%%{?dist} instead of 2%%{?dist} * Fri Feb 15 2008 Steve Snodgrass 2.3.2a8-1 - Install .cloginrc as a configuration file - Don't try to create the rancid user if it already exists * Wed Feb 13 2008 Steve Snodgrass 2.3.2a8-1 - Create subpackage for looking glass CGI scripts - Include configuration files in RPM - Many other tweaks * Wed Nov 16 2005 Michael Stefaniuc 2.3.1-3 - Use /var/rancid as localstatedir - Create the rancid user on install and remove it on uninstall - Use %%doc correctly * Wed Nov 02 2005 Michael Stefaniuc 2.3.1-2 - Original spec file by Dan Pfleger. - Add a changelog. - Make the formating of the spec file adhere to the Fedora Extras Packaging guidelines. - New %%description based on the README and the website. - Add cvs Requires. - Changed Group - Use macros in the files section. Simplify it. - Do not install the looking glass cgi's. Those make rpm pull in more perl module dependencies. rancid-2.3.8/share/downreport.in100644 015615 000000 00000007224 11342156264 0012324#! /bin/sh ## ## $Id: downreport.in 2096 2009-06-17 21:49:46Z heas $ ## ## Copyright (c) 1997-2007 by Terrapin Communications, Inc. ## All rights reserved. ## ## This code is derived from software contributed to and maintained by ## Terrapin Communications, Inc. by Henry Kilmer, John Heasley, Andrew Partan, ## Pete Whiting, Austin Schutz, and Andrew Fort. ## ## Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions ## are met: ## 1. Redistributions of source code must retain the above copyright ## notice, this list of conditions and the following disclaimer. ## 2. Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in the ## documentation and/or other materials provided with the distribution. ## 3. All advertising materials mentioning features or use of this software ## must display the following acknowledgement: ## This product includes software developed by Terrapin Communications, ## Inc. and its contributors for RANCID. ## 4. Neither the name of Terrapin Communications, Inc. nor the names of its ## contributors may be used to endorse or promote products derived from ## this software without specific prior written permission. ## 5. It is requested that non-binding fixes and modifications be contributed ## back to Terrapin Communications, Inc. ## ## THIS SOFTWARE IS PROVIDED BY Terrapin Communications, INC. AND CONTRIBUTORS ## ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ## TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COMPANY OR CONTRIBUTORS ## BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ## CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ## SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ## INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ## CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ## ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ## POSSIBILITY OF SUCH DAMAGE. # # The expect login scripts were based on Erik Sherk's gwtn, by permission. # # The original looking glass software was written by Ed Kern, provided by # permission and modified beyond recognition. # # Reports the list of routers not listed as 'up'. # Put this in your crontab to run once a day: # 0 0 * * * @pkgdatadir@/downreport # It can optionally # take a space list of groups on the command line # It will use the list of groups defined in rancid.conf otherwise. ENVFILE="@sysconfdir@/rancid.conf" . $ENVFILE if [ $# -ge 1 ] ; then LIST_OF_GROUPS="$*" elif [ "$LIST_OF_GROUPS" = "" ] ; then echo "LIST_OF_GROUPS is empty in $ENVFILE" exit 1 fi # mail variables set | grep MAILHEADERS= > /dev/null 2>&1 if [ $? -ne 0 ] ; then MAILHEADERS="Precedence: bulk\n"; export MAILHEADERS fi for GROUP in $LIST_OF_GROUPS; do ( echo "To: @MAILPLUS@admin-$GROUP" echo "Subject: Down router report - $GROUP" echo "$MAILHEADERS" | awk '{gsub(/\\n/,"\n");print;}' echo "" DIR=$BASEDIR/$GROUP if [ -s $DIR/routers.down ]; then ( cat << EOM The following $GROUP routers are listed as other than up. Routers listed as "up" in rancid's router.db are polled several times daily. This is a list of routers that are not "up" and therefore not polled. EOM cat $DIR/routers.down; ) else ( cat << EOM No routers are down/ticketed for router group $GROUP (yay). EOM ) fi ) | sendmail -t done