#!/bin/ksh -p # exp_tools: explorer API for data gathering modules # $Id: //depot/dev/proactive/explorer3/lib/exp_tools#29 $ EXP_TOOLS_VERSION='$Revision: #29 $' export EXP_TOOLS_VERSION if [ -n "${DO_VERSION}" ] then LIB=`basename $0` echo "${LIB} version: ${EXP_TOOLS_VERSION}" exit fi # Source common functions . ${EXP_LIB}/exp_common # # touch a file # First arg is the file to create # touch_file () { if [ "$#" -lt 1 ] then # logfile ERROR "Wrong number of args to touch_file: $*" TEXT=`gettext "Wrong number of args to touch_file: %s"` TEXT=`printf "${TEXT}" "$*"` logfile ERROR "${TEXT}" return 1 fi FILE=${EXP_TARGET}/$1 DIR=`dirname ${FILE}` # Make sure the directory exists [ ! -d "${DIR}" ] && { mkdir -p ${DIR}; } touch ${FILE} >/dev/null 2>&1 } # # echo to a file # First arg is the file to echo to # Optional second arg is the message to print # echo_file () { ( if [ "$#" -lt 1 ] then # logfile ERROR "Wrong number of args to echo_file: $*" TEXT=`gettext "Wrong number of args to echo_file: %s"` TEXT=`printf "${TEXT}" "$*"` logfile ERROR return 1 fi FILE=${EXP_TARGET}/$1 DIR=`dirname ${FILE}` shift # Check for writeability of file if [ ! -w "${FILE}" ] then # Make sure the directory exists [ ! -d "${DIR}" ] && { mkdir -p ${DIR}; } # Create the file touch ${FILE} >/dev/null 2>&1 fi { if [ "$#" -gt 0 ] then echo "$*" else cat fi } >>${FILE} 2>&1 ) } # # create a symlink in EXP_TARGET # First arg is the basedir # Second arg is the source # Third arg is the link # symlink () { if [ "$#" -lt 3 ] then # logfile ERROR "Wrong number of args to symlink: $*" TEXT=`gettext "Wrong number of args to symlink: %s"` TEXT=`printf "${TEXT}" "$*"` logfile ERROR "${TEXT}" return 1 fi cd ${EXP_TARGET}/$1 ln -s $2 $3 logfile "link: $3 -> $2 in $1" } # # get a file # First arg is file to copy # Optional second arg is directory to store it in # get_file () { FTP="" if [ "$#" -lt 1 ] then # logfile ERROR "Wrong number of args to get_file: $*" TEXT=`gettext "Wrong number of args to get_file: %s"` TEXT=`printf "${TEXT}" "$*"` logfile ERROR "${TEXT}" return 1 fi FILES=$1 # Get file via ftp? echo "$2" | egrep -s -e "^ftp:" if [ "$?" -eq 0 ] then HOST=`echo $2 | nawk -F: '{print $2}'` PASS=`echo $2 | nawk -F: '{print $3}'` CDIR=`echo $2 | nawk -F: '{print $4}'` FTP=notempty shift fi # Where does the file go if [ -n "$2" ] then DIR=${EXP_TARGET}/$2 else DIR=${EXP_TARGET}/extra fi # ftp get if [ -n "${FTP}" ] then # Add to .netrc to allow auto ftp of files if [ -f "/.netrc" ] then cp /.netrc /.netrc.${EXP_PID} echo "machine ${HOST} login root password ${PASS}" >>/.netrc else touch /.netrc chmod 600 /.netrc echo "machine ${HOST} login root password ${PASS}" >>/.netrc fi # Make sure destination DIR exists [ ! -d "${DIR}" ] && { mkdir -p ${DIR}; } cd ${DIR} # Ftp off certain files EXP_TMPFILE="${EXP_TMPDIR}/ftp.${EXP_PID}" ftp ${HOST} >${EXP_TMPFILE} 2>&1 </ { print $NF }'` # Absolute path, copy it if echo $LINK | egrep -s -e "^\/" then # Copy file cp -p "${FILE}" "${DIR}" logfile "file: ${FILE}" continue fi # Relative path DEST=`basename $FILE` LDIR=`dirname $LINK` LDIR=`echo $LDIR | sed -e "s~^~${DIR}/~"` NEW=`echo $LINK | sed -e "s~^~${CDIR}/~"` # Make sure the directory exists [ ! -d "${LDIR}" ] && { mkdir -p ${LDIR}; } # Copy file linked to, then cd and link cp -p "${NEW}" "${LDIR}" (cd ${DIR} ; ln -s ${LINK} ${DEST}) logfile "file: ${NEW}" logfile "file: ${FILE} linked to ${LINK}" else # Copy file cp -p "${FILE}" "${DIR}" logfile "file: ${FILE}" fi done return 0 } # # get a directory's contents # First arg may be recursive, otherwise it is source dir # Optional second arg is directory to store files in get_dir () { if [ "$#" -lt 1 ] then # logfile ERROR "Wrong number of args to get_dir: $*" TEXT=`gettext "Wrong number of args to get_dir: %s"` TEXT=`printf "${TEXT}" "$*"` logfile ERROR "${TEXT}" return 1 fi RECURSE=0 # Check for recursive if [ "$1" = "recursive" ] then RECURSE=1 shift fi logfile "dir: $1" # Check for empty directories FILES=`ls -l $1/* 2>/dev/null | wc -l` if [ "${FILES}" -eq 0 ] then if [ -n "$2" ] then DIR="${EXP_TARGET}/$2" else DIR="${EXP_TARGET}/extra/`basename $1`" fi # Make the dir even if it's empty [ ! -d "${DIR}" ] && { mkdir -p ${DIR}; } fi # Walk directory for FILE in $1/* do if [ -d "${FILE}" -a "${RECURSE}" -eq 1 ] then # Preserve some directory info if [ -n "$2" ] then DIR="$2/`basename ${FILE}`" else DIR="extra/`basename $1`/`basename ${FILE}`" fi get_dir recursive "${FILE}" "${DIR}" else # Preserve some directory info if [ -n "$2" ] then TAR="$2" else TAR="extra/`basename $1`" fi get_file "${FILE}" "${TAR}" fi done } # # Get command output # First arg is command to run # Optional second arg is the 3.x filename or destination dir # get_cmd () { # Save current LC_ALL and run commands in 'C' locale LC_SAVE=${LC_ALL} export LC_ALL=C if [ "$#" -lt 1 ] then export LC_ALL=${LC_SAVE} # logfile ERROR "Wrong number of args to get_cmd: $*" TEXT=`gettext "Wrong number of args to get_cmd: %s"` TEXT=`printf "${TEXT}" "$*"` logfile ERROR "${TEXT}" return 1 fi COMMAND=$1 # Clean up what is printed echo "${COMMAND}" | egrep -s -e " " if [ "$?" -eq 0 ] then CMD=`echo "${COMMAND}" | nawk '{ print $1 }'` ARG=`echo "${COMMAND}" | sed -e "s~${CMD} ~~"` CDIR=`dirname ${CMD}` TMP=`echo "${CMD}" | sed -e "s~${CDIR}/~~"` BIN="$TMP $ARG" else CMD="${COMMAND}" CDIR=`dirname ${CMD}` BIN=`echo "${CMD}" | sed -e "s~${CDIR}/~~"` fi # ignore option to set SERR=/dev/null IGNORE="" if [ -n "$2" ] then if [ "$2" = "ignore" ] then IGNORE=notempty shift fi fi # get command via telnet TELNET="" echo "$2" | egrep -s -e "^telnet:" if [ "$?" -eq 0 ] then TELNET=notempty IGNORE=notempty TYPE=`echo $2 | nawk -F: '{ print $2 }'` HOST=`echo $2 | nawk -F: '{ print $3 }'` PASS=`echo $2 | nawk -F: '{ print $4 }'` TIME=`echo $2 | nawk -F: '{ print $5 }'` CDIR="/bin" if [ "${TYPE}" = "t3" ] then LOGIN=root LOGOUT=exit PORT=23 elif [ "${TYPE}" = "sc" ] then LOGIN= LOGOUT=disc PORT=5000 elif [ "${TYPE}" = "brocade" ] then LOGIN=`echo $2 | nawk -F: '{ print $6 }'` LOGOUT=exit PORT=23 else export LC_ALL=${LC_SAVE} # logfile ERROR "Unknown telnet type for get_cmd: $*" TEXT=`gettext "Unknown telnet type for get_cmd: %s"` TEXT=`printf "${TEXT}" "$*"` logfile ERROR "${TEXT}" return 1 fi shift export LC_ALL=${LC_SAVE} logfile "cmd: ${BIN} (on ${HOST})" export LC_ALL=C else export LC_ALL=${LC_SAVE} logfile "cmd: ${BIN}" export LC_ALL=C fi # Run command as a different user? USER="" if [ -n "$2" ] then if echo "$2" | egrep -s -e "user=" then USER=`echo $2 | nawk -F= '{ print $2 }'` shift fi fi # Do we have a destination dir or explorer3 name if [ -n "$2" ] then echo "$2" | egrep -s -e "/$" if [ "$?" -eq 0 ] then # Destination dir FILE=`echo "${BIN}" | sed -e 's~/~@~g' -e 's~ ~_~g' -e "s~${CDIR}/~~g"` DIR=`echo "$2" | sed -e "s~/$~~"` # Construct SOUT/SERR SOUT="${EXP_TARGET}/${DIR}/${FILE}.out" SERR="${EXP_TARGET}/${DIR}/${FILE}.err" else # explorer 3 name echo "$2" | egrep -s -e "!$" # Use exact name? (name!) if [ "$?" -eq 0 ] then # strip ! FILE=`echo $2 | sed -e "s/!$//"` # Construct SOUT/SERR SOUT="${EXP_TARGET}/${FILE}" SERR="${EXP_TARGET}/${FILE}.err" else # Construct SOUT/SERR SOUT="${EXP_TARGET}/$2.out" SERR="${EXP_TARGET}/$2.err" fi fi else # Filename based removing full path to command # and translated '/'='@' and ' '='_' FILE=`echo "${BIN}" | sed -e 's~/~@~g' -e 's~ ~_~g' -e "s~${CDIR}/~~g"` # Construct SOUT/SERR SOUT="${EXP_TARGET}/extra/${FILE}.out" SERR="${EXP_TARGET}/extra/${FILE}.err" fi # Use /dev/null if IGNORE set if [ -n "${IGNORE}" ] then SERR="/dev/null" fi # Make sure the directory exists DIR=`dirname ${SOUT}` [ ! -d "${DIR}" ] && { mkdir -p ${DIR}; } # Get command via telnet if [ -n "${TELNET}" ] then if [ "${EXP_HOME}" = "/" ] then IN_FILE="${EXP_LIB}/cmd.txt" else IN_FILE="${EXP_HOME}/etc/cmd.txt" fi CMD_FILE="${EXP_TMPDIR}/cmd.${EXP_PID}" if [ -n "${LOGIN}" ] then sed -e "s~HOST~${HOST}~" \ -e "s~PORT~${PORT}~" \ -e "s~LOGIN~${LOGIN}~" \ -e "s~LOGOUT~${LOGOUT}~" \ -e "s~PASS~${PASS}~" \ -e "s~TIME~${TIME}~" \ -e "s~TYPE~${TYPE}~" \ -e "s~FILE~${SOUT}~" \ -e "s~CMD~${COMMAND}~" ${IN_FILE} > ${CMD_FILE} else sed -e "s~HOST~${HOST}~" \ -e "s~PORT~${PORT}~" \ -e "/LOGIN/d" \ -e "/sleep 3/d" \ -e "s~LOGOUT~${LOGOUT}~" \ -e "s~PASS~${PASS}~" \ -e "s~TIME~${TIME}~" \ -e "s~TYPE~${TYPE}~" \ -e "s~FILE~${SOUT}~" \ -e "s~CMD~${COMMAND}~" ${IN_FILE} > ${CMD_FILE} fi # Make cmd file executeable chmod 700 ${CMD_FILE} # Execute command via telnet ${CMD_FILE} | telnet >>${SOUT} 2>>${SERR} rc=$? # Clean up rm -f ${CMD_FILE} export LC_ALL=${LC_SAVE} if [ "${rc}" -eq 0 ] then if egrep -s -e "ogin incorrect" ${SOUT} then rc=1 fi fi return ${rc} fi # Force use of full path name on executable if [ ! -f "${CMD}" ] then export LC_ALL=${LC_SAVE} # logfile WARNING "${CMD} not found" TEXT=`gettext "%s not found"` TEXT=`printf "${TEXT}" "${CMD}"` logfile WARNING "${TEXT}" return 1 fi # Make sure it's executeable if [ ! -x "${CMD}" ] then export LC_ALL=${LC_SAVE} # logfile WARNING "Unable to execute ${CMD}" TEXT=`gettext "Unable to execute %s"` TEXT=`printf "${TEXT}" "${CMD}"` logfile WARNING "${TEXT}" return 1 fi # Execute command if [ -z "${USER}" ] then ksh -p -c "${COMMAND}" >>${SOUT} 2>>${SERR} rc=$? else su ${USER} -c "${COMMAND}" >>${SOUT} 2>>${SERR} rc=$? fi export LC_ALL=${LC_SAVE} logfile "cmd: exit status: $rc" return $rc } # # which_gate foo bar # return non-zero if neither foo nor bar is in the ${EXP_WHICH} directive # order of arguments is important. which_gate foo bar returns zero on # "foo,!bar" but one on "!foo,bar". # which_gate () { for i in $* do test `expr "${EXP_WHICH}" : ".*!\<$i\>.*"` -ne 0 && return 1 test `expr "${EXP_WHICH}" : ".*\<$i\>.*"` -ne 0 && return 0 done return 1 } # # returns non-zero if all of the components of the ${EXP_WHICH} variable # are negative (start with a ! character). # which_negative_check () { for i in `echo ${EXP_WHICH} | sed -e 's/,/ /g'` do expr "$i" : "^!" >/dev/null || return 0 done return 1 } # # used by scripts to determine if they are executed (-w) # which_gate_exit () { which_gate $* if [ "$?" -eq 0 ] then TEXT=`gettext "RUNNING"` logfile NOTNOISE "${TEXT}" else TEXT=`gettext "SKIPPING"` logfile "${TEXT}" exit 0 fi }