420 lines
8.9 KiB
Bash
Executable File
420 lines
8.9 KiB
Bash
Executable File
#!/bin/sh
|
|
|
|
# "$Revision: 1.19 $"
|
|
|
|
|
|
USAGE="$0: [-vt] [-b board] [-p prefix] [-m master] [-u muser] [-c cmd]"
|
|
|
|
FIXER="Marty Castilla at ext 1479 or pager 694-8973"
|
|
|
|
PREFIX='8:0:69'
|
|
MASTER=bonnie.engr.sgi.com
|
|
MUSER=fddimac
|
|
MCMD="allocmac2"
|
|
DBM="fddimacs"
|
|
RCDS=/tmp/gotmacs
|
|
|
|
BINDIR=/usr/bin
|
|
SETMADDR=$BINDIR/setmaddr
|
|
EPFIRM=/usr/etc/epfirm
|
|
GETMAC=$BINDIR/getmac
|
|
|
|
ARGS="$*"
|
|
|
|
# get a yes or no answer
|
|
getyes() {
|
|
while true; do
|
|
echo "$1 \c"
|
|
if read yesno; then
|
|
case "$yesno" in
|
|
[yY]*)
|
|
return 0
|
|
;;
|
|
[nN]*)
|
|
return 1
|
|
;;
|
|
esac
|
|
else
|
|
echo
|
|
exit 1
|
|
fi
|
|
echo '\tPlease answer "yes" or "no".'
|
|
done
|
|
}
|
|
|
|
|
|
# get a string of minimum size
|
|
getname() {
|
|
while true; do
|
|
echo "$2 \c"
|
|
if read ans; then
|
|
anslen=`echo "$ans" | wc -c`
|
|
if test $3 -le $anslen -a \( $4 -eq 0 -o $4 -ge $anslen \); then
|
|
eval "$1='$ans'"
|
|
return 0
|
|
fi
|
|
else
|
|
echo
|
|
exit 1
|
|
fi
|
|
echo "\t$5"
|
|
done
|
|
}
|
|
|
|
# get a serial number
|
|
# $1=variable to set, $2=mesage, $3=min significant digits, $4=max digits
|
|
# $5=error message
|
|
getnum() {
|
|
while true; do
|
|
echo "$2 \c"
|
|
if read ans; then
|
|
ans=`echo "$ans" | tr '[a-z]' '[A-Z]'`
|
|
# anslen=totlen length
|
|
anslen=`echo "$ans" | wc -c`
|
|
# ansblen=number of non-alphanumerics
|
|
ansblen=`echo "$ans" | tr -d '[A-Z][0-9]' | wc -c`
|
|
# ansdlen=number of digits
|
|
ansdlen=`echo "$ans" | tr -d '[A-Z]' | wc -c`
|
|
# require minimuml length, not too many characters, no extra
|
|
# strange characters (including LF from echo),
|
|
# and at least one digit
|
|
if test $3 -le $anslen -a $4 -ge $anslen \
|
|
-a $ansblen = 1 -a $ansdlen -gt 1; then
|
|
eval "$1='$ans'"
|
|
return 0
|
|
fi
|
|
else
|
|
echo
|
|
exit 1
|
|
fi
|
|
echo "\t$5"
|
|
done
|
|
}
|
|
|
|
|
|
# get MAC addresses from board
|
|
getomacs() {
|
|
if test "$TYP" = ep; then
|
|
ans=`$EPFIRM -vv $BD \
|
|
| sed -n -e 's/^ep[0-9]\{1,\}: *\([0-9a-fA-F:]\{11,\}\).*$/\1/p'`
|
|
if test -z "$ans"; then
|
|
echo "please contact $FIXER.\n"
|
|
exit 1
|
|
fi
|
|
set $ans
|
|
OMAC=$1
|
|
OMAC1=$2
|
|
OMAC2=$3
|
|
OMAC3=$4
|
|
OMAC4=$5
|
|
OMAC5=$6
|
|
OMAC6=$7
|
|
OMAC7=$8
|
|
else
|
|
OMAC=`$SETMADDR $BD`
|
|
if test -n "$BD1"; then
|
|
OMAC1=`$SETMADDR $BD1`
|
|
fi
|
|
fi
|
|
}
|
|
|
|
|
|
|
|
while getopts "vtb:p:m:u:cf" c; do
|
|
case $c in
|
|
v) if test -n "$verbose"; then
|
|
verbose="$verbose"v
|
|
else
|
|
verbose=-v
|
|
fi
|
|
if test x"$verbose" = "x-vv"; then
|
|
set -x
|
|
fi
|
|
;;
|
|
t) TMODE=1;;
|
|
b) BD="$OPTARG";;
|
|
p) PREFIX="$OPTARG";;
|
|
m) MASTER="$OPTARG";;
|
|
u) MUSER="$OPTARG";;
|
|
c) MCMD="$OPTARG";;
|
|
f) REPAIR="yes";;
|
|
\?) echo $USAGE; exit 1;;
|
|
esac
|
|
done
|
|
shift `expr $OPTIND - 1`
|
|
if test "$#" != 0; then
|
|
echo $USAGE
|
|
exit 1
|
|
fi
|
|
|
|
# we must be root
|
|
set `id`
|
|
if test "$1" != "uid=0(root)" ; then
|
|
echo "You must be running as root. Use the su command."
|
|
exit 1
|
|
fi
|
|
|
|
trap 'echo "\ninterrupted--No harm done.\n"; exit 1' 1 2 15
|
|
|
|
|
|
# get a new copy of the script daily, unless in test mode
|
|
if test -z "$TMODE" -a \
|
|
-z "`find $GETMAC -mtime -1 -print 2> /dev/null`"; then
|
|
rm -f /tmp/getmac
|
|
rcp guest@$MASTER:~$MUSER/bin/getmac /tmp
|
|
if test ! -s /tmp/getmac; then
|
|
echo "failed to rcp a new copy of getmac from $MASTER"
|
|
exit 1
|
|
fi
|
|
if cmp -s $GETMAC /tmp/getmac; then
|
|
touch $GETMAC $SETMADDR
|
|
else
|
|
mv /tmp/getmac $GETMAC
|
|
echo "installing a new copy of getmac from $MASTER"
|
|
exec $GETMAC $ARGS
|
|
fi
|
|
fi
|
|
|
|
#get newer version of setmaddr
|
|
if test -x $SETMADDR; then
|
|
rm -f `find $SETMADDR ! -newer $GETMAC -print`
|
|
fi
|
|
if test ! -x $SETMADDR; then
|
|
echo "copying setmaddr from $MASTER"
|
|
rm -f $SETMADDR
|
|
if test `uname -r` = '5.3'; then
|
|
rcp guest@$MASTER:~$MUSER/bin/setmaddr.coff $SETMADDR
|
|
else
|
|
rcp guest@$MASTER:~$MUSER/bin/setmaddr $SETMADDR
|
|
fi
|
|
fi
|
|
|
|
if test ! -x $BINDIR/test.fddi; then
|
|
echo "copying test.fddi from $MASTER"
|
|
rm -f $BINDIR/test.fddi
|
|
rcp guest@$MASTER:~$MUSER/bin/test.fddi $BINDIR
|
|
fi
|
|
|
|
# default the board if not specified
|
|
if test -z "$BD"; then
|
|
if `/usr/etc/ifconfig xpi0 > /dev/null 2>&1`; then
|
|
BD=xpi0
|
|
elif `/usr/etc/ifconfig ep0 > /dev/null 2>&1`; then
|
|
BD=ep0
|
|
else
|
|
BD=ipg0
|
|
fi
|
|
fi
|
|
|
|
case "$BD" in
|
|
ipg[0-3])
|
|
TYP=ipg
|
|
MINSN=5
|
|
NBD=1
|
|
;;
|
|
|
|
xpi*)
|
|
TYP=xpi
|
|
MINSN=1
|
|
if test 1 -lt `hinv -c processor | sed -n -e '1s/ .*//p'`; then
|
|
#deal with both units on the board, making the first
|
|
#one the even unit
|
|
BD="xpi`expr $BD : 'xpi\(.\)' / 2 '*' 2`"
|
|
BD1="xpi`expr $BD : 'xpi\(.\)' / 2 '*' 2 + 1`"
|
|
NBD=2
|
|
else
|
|
NBD=1
|
|
fi
|
|
;;
|
|
|
|
ep*)
|
|
TYP=ep
|
|
MINSN=1
|
|
NBD=8
|
|
#start with the first unit on a board
|
|
BD="ep`expr $BD : 'ep\(.\)' / 10 '*' 10`"
|
|
BD1="ep`expr $BD : 'ep\(.\)' / 10 '*' 10 + 1`"
|
|
BD2="ep`expr $BD : 'ep\(.\)' / 10 '*' 10 + 2`"
|
|
BD3="ep`expr $BD : 'ep\(.\)' / 10 '*' 10 + 3`"
|
|
BD4="ep`expr $BD : 'ep\(.\)' / 10 '*' 10 + 4`"
|
|
BD5="ep`expr $BD : 'ep\(.\)' / 10 '*' 10 + 5`"
|
|
BD6="ep`expr $BD : 'ep\(.\)' / 10 '*' 10 + 6`"
|
|
BD7="ep`expr $BD : 'ep\(.\)' / 10 '*' 10 + 7`"
|
|
;;
|
|
|
|
*)
|
|
echo "$BD" is an unknown board
|
|
exit 1
|
|
;;
|
|
esac
|
|
|
|
|
|
|
|
# get the current MAC addresses
|
|
getomacs
|
|
if test -n "$verbose"; then
|
|
if test -n "$BD1"; then
|
|
SPACE="Old addresses"
|
|
BDNUM=0
|
|
for nm in $OMAC $OMAC1 $OMAC2 $OMAC3 $OMAC4 $OMAC5 $OMAC6 $OMAC7; do
|
|
if test "$BDNUM" = 3; then
|
|
SPACE=",\n "
|
|
BDNUM=0
|
|
fi
|
|
echo "$SPACE $nm\c"
|
|
SPACE=","
|
|
BDNUM=`expr ${BDNUM:-0} + 1`
|
|
done
|
|
echo
|
|
else
|
|
echo "Old address $OMAC"
|
|
fi
|
|
fi
|
|
|
|
BNUMS=`echo " $OMAC $OMAC1 $OMAC2 $OMAC3 $OMAC4 $OMAC5 $OMAC6 $OMAC7" \
|
|
| sed -e "s/ $PREFIX"'[0-9a-fA-F:]*/G/g' -e 's/GG*/G/'`
|
|
if test "$BNUMS" = G; then
|
|
echo "The board already has a valid MAC address."
|
|
if getyes "Do you want to continue?"; then :
|
|
else
|
|
echo "\nOk, no changes made.\n"
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
if test "$REPAIR" != "yes"; then
|
|
getname UNAME "Who are you?" 3 0 "Please supply a more interesting name"
|
|
fi
|
|
|
|
getnum SNUM "What is the $BD board serial number?" $MINSN 10 \
|
|
"That does not seem like a serial number."
|
|
|
|
# set RCD# to old address from the database
|
|
rsh guest@$MASTER -n egrep -i "'^[^# ]*=$TYP *$SNUM(-[0-9])? '" \
|
|
~$MUSER/$DBM >$RCDS
|
|
if test -s $RCDS; then
|
|
eval `sed -e 's/^\([^# ]*\)='"$TYP *$SNUM"'-*\([0-9]*\).*/RCD\2=\1/' \
|
|
-e 's/^RCD0=/RCD=/' $RCDS`
|
|
fi
|
|
|
|
# only repair returned boards
|
|
if test "$REPAIR" = yes; then
|
|
if test -s $RCDS; then
|
|
echo "\nThere is no record of a $TYP board with serial number $SNUM."
|
|
echo "Nothing changed."
|
|
exit 1
|
|
fi
|
|
|
|
elif test -s $RCDS; then
|
|
echo "\nA board with serial $SNUM already has the following record(s) in the database:"
|
|
cat $RCDS
|
|
echo "\nIf this board is not the same as the other board with serial number $SNUM,"
|
|
echo "please contact $FIXER.\n"
|
|
|
|
if getyes "Is this the same board and it only needs repairing"?; then
|
|
REPAIR=yes
|
|
elif getyes "Do you really want to allocate a new MAC address?"; then :
|
|
RCD=
|
|
else
|
|
echo "\nOk. It must be the same board. Rewrite its address.\n"
|
|
REPAIR=yes
|
|
fi
|
|
fi
|
|
|
|
|
|
echo
|
|
if test "$REPAIR" != yes; then
|
|
if getyes "Are you $UNAME and are you setting the $BD board with serial number $SNUM?";
|
|
then :
|
|
else
|
|
echo "\nOk. No harm done.\n"
|
|
exit 1
|
|
fi
|
|
|
|
#disable interrupts when we are committed
|
|
trap "" 1 2 15
|
|
|
|
rsh $MUSER@$MASTER -n $MCMD -t $TYP -d $DBM -c $NBD \
|
|
-u "$UNAME" -s $SNUM >$RCDS 2>&1
|
|
if test `egrep -v -c "^[^# ]*=$TYP *$SNUM(-[0-9])? " $RCDS` != 0; then
|
|
echo "\nThe address allocator on $MASTER failed saying\n"
|
|
cat $RCDS
|
|
echo "\nCall $FIXER."
|
|
exit 1
|
|
fi
|
|
eval `sed -e 's/^\([^# ]*\)='"$TYP *$SNUM"'-*\([0-9]*\).*/RCD\2=\1/' \
|
|
-e 's/^RCD0=/RCD=/' $RCDS`
|
|
fi
|
|
|
|
if test $NBD != `echo $RCD $RCD1 $RCD2 $RCD3 $RCD4 $RCD5 $RCD6 $RCD7 | wc -w`\
|
|
-o $NBD != `wc -l <$RCDS`; then
|
|
echo "\nThere are insufficient records for serial number $SNUM:"
|
|
cat $RCDS
|
|
echo "\nNothing changed."
|
|
echo "Call $FIXER."
|
|
exit 1
|
|
fi
|
|
|
|
echo
|
|
|
|
# disable interrupts when we are committed
|
|
trap "" 1 2 15
|
|
|
|
|
|
# program the board
|
|
if test "$TYP" = ep; then
|
|
if test ! -x $EPFIRM; then
|
|
echo "epfirm must be installed."
|
|
echo "Call $FIXER."
|
|
exit 1
|
|
fi
|
|
$EPFIRM -v $verbose -w "$RCD,$RCD1,$RCD2,$RCD3,$RCD4,$RCD5,$RCD6,$RCD7" $BD
|
|
else
|
|
#keep SMTD from turning the board back on
|
|
killall smtd
|
|
$SETMADDR $verbose -w "$RCD" $BD
|
|
if test $? != 0; then
|
|
echo "\nThe board refused to accept the address."
|
|
echo "Call $FIXER."
|
|
exit 1
|
|
fi
|
|
if test -n "$BD1"; then
|
|
$SETMADDR $verbose -w "$RCD1" $BD1
|
|
if test $? != 0; then
|
|
echo "\nThe board refused to accept the second address."
|
|
echo "Call $FIXER."
|
|
exit 1
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
|
|
#try to ensure that everyone knows about the new address
|
|
trap "" 1 2 15
|
|
if test -z "$TMODE"; then
|
|
killall smtd smtstat fddivis
|
|
/etc/init.d/network stop
|
|
/etc/init.d/network start
|
|
fi
|
|
|
|
|
|
getomacs
|
|
if test -z "$BD1"; then
|
|
echo "\nThe board now has address $OMAC.\n"
|
|
else
|
|
SPACE="\nThe board now has addresses"
|
|
BDNUM=1
|
|
for nm in $OMAC $OMAC1 $OMAC2 $OMAC3 $OMAC4 $OMAC5 $OMAC6 $OMAC7; do
|
|
if test "$BDNUM" = 3; then
|
|
SPACE=",\n "
|
|
BDNUM=0
|
|
fi
|
|
echo "$SPACE $nm\c"
|
|
SPACE=","
|
|
BDNUM=`expr ${BDNUM:-0} + 1`
|
|
done
|
|
echo "\n"
|
|
fi
|
|
|
|
exit 0
|