#! /bin/sh ######################################################################## # # /u/sonmi/bin/header - /u/svbld/bin/init/nss/header # # variables, utilities and shellfunctions global to NSS QA # needs to work on all Unix platforms # # included from (don't expect this to be up to date) # -------------------------------------------------- # qa_stat # mksymlinks # nssqa # # parameters # ---------- # nssversion (supported: 30b, 31, 332, tip 32) # builddate (default - today) # # options # ------- # -y answer all questions with y - use at your own risk... ignores warnings # -s silent (only usefull with -y) # -h, -? - you guessed right - displays this text # -d debug # -f - write the (error)output to filename # -fcronfile produces the resultfiles in the same locations # as would have been produced with -cron # -m - send filename to mailinglist (csl) only useful # with -f # -ml - send link to filename to mailinglist (csl) # only useful with -f # -cron equivalient to -y -s -d -f $RESULTDIR/$HOST. # -t run on a tinderbox build that means: local, from the startlocation # -l run on a local build mozroot # -ln copy a networkbuild to a local directory mozroot, # used for networkindipendend QA # -lt try to copy a networkbuild to a local directory, if not possible # run on the network # used for networkindipendend QA # # special strings # --------------- # FIXME ... known problems, search for this string # NOTE .... unexpected behavior # # moduls (not yet) # ---------------- # --# INIT # --# USERCOM # --# UTILS # # FIXME - split in init / usercom / utils # ######################################################################## #------------------------------# INIT #------------------------------ # below the option flags get initialized if [ -z "$QASCRIPT_DIR" ] then QASCRIPT_DIR=`dirname $0` if [ "$QASCRIPT_DIR" = '.' ] then QASCRIPT_DIR=`pwd` fi fi export QASCRIPT_DIR O_HWACC=OFF if [ -z "$O_ALWAYS_YES" ] ; then O_ALWAYS_YES=OFF # turned on by -y answer all questions with y fi if [ -z "$O_INIT" ] # header is global, some including scripts may not then # want the init to run, the others don't need to bother O_INIT=ON fi if [ -z "$O_PARAM" ] # header is global, some including scripts may not then # require parameters, the others don't need to bother O_PARAM=ON fi if [ -z "$O_OPTIONS" ] # header is global, some including scripts may not then # permit options, they don't need to bother O_OPTIONS=OFF fi O_SILENT=OFF # turned on by -s silent (only usefull with -y) if [ -z "$O_DEBUG" ] ; then O_DEBUG=OFF # turned on by -d - calls to Debug produce output when ON fi O_FILE=OFF # turned on by -f echo all output to a file $FILENAME O_CRON=OFF # turned on by -cron cron use only O_CRONFILE=OFF # turned on by -cron cron and -fcron O_LOCAL=OFF # turned on by -l* run on a local build in $LOCAL_MOZROOT O_LN=OFF # turned on by -ln and -lt, test a networkbuild locally O_MAIL=OFF # turned on by -m - sends email O_MAIL_LINK=OFF # turned on by -ml - sends email O_TBX=OFF # turned on by -t run on a tinderbox build # that means: local, from the startlocation if [ -z "$DOMSUF" ] then DOMSUF=red.iplanet.com DS_WAS_SET=FALSE else DS_WAS_SET=TRUE fi TMPFILES="" WAIT_FOR=600 # if waiting for an event sleep n seconds before rechecking # recomended value 10 minutes 600 WAIT_TIMES=30 # recheck n times before giving up - recomended 30 - total of 5h if [ -z "$QAYEAR" ] # may I introduce - the y2k+1 bug? QA for last year then # might not work QAYEAR=`date +%Y` fi if [ -z "$TMP" ] then if [ -z "$TEMP" ] then TMP="/tmp" else TMP=$TEMP fi fi if [ ! -w "$TMP" ] then echo "Can't write to tmp directory $TMP - exiting" echo "Can't write to tmp directory $TMP - exiting" >&2 exit 1 fi KILLPIDS="$TMP/killpids.$$" export KILLERPIDS TMPFILES="$TMPFILES $KILLPIDS" KILL_SELFSERV=OFF # if sourcing script sets this to on cleanup will also # kill the running selfserv processes # Set the masterbuilds if [ -z "$UX_MASTERBUILD" ] then UX_MASTERBUILD=booboo_Solaris8 #if [ ! -d $UX_MASTERBUILD ] ; then #UX_MASTERBUILD=booboo_Solaris8_forte6 #fi UX_MB_WAS_SET=FALSE else UX_MB_WAS_SET=TRUE fi if [ -z "$NT_MASTERBUILD" ] then NT_MASTERBUILD=blowfish_NT4.0_Win95 NT_MB_WAS_SET=FALSE # in this case later functions can override if # they find a different build that looks like NT else NT_MB_WAS_SET=TRUE fi if [ -z "$MASTERBUILD" ] then MASTERBUILD=$UX_MASTERBUILD fi # Set the default build if [ -z "$BUILDNUMBER" ] then BUILDNUMBER=1 fi export BUILDNUMBER O_LDIR=OFF #local QA dir for NT, temporary if [ -z "$WIN_WAIT_FOREVER" ] # header is global, some including scripts then # want the init to wait forever for directories to # appear (windows only) if OFF exit, if ON wait forever WIN_WAIT_FOREVER=OFF fi # NOTE: following variables have to change # from release to release if [ -z "$BC_MASTER" ] # master directory for backwardscompatibility testing then RH="NO" grep 7.1 /etc/redhat-release > /dev/null 2>/dev/null && RH="YES" grep 7.2 /etc/redhat-release > /dev/null 2>/dev/null && RH="YES" if [ "$RH" = "YES" ] then # NSS-3-3-1RTM BC_UX_MASTER=nss331/builds/20010928.2.331-RTM/booboo_Solaris8 BC_NT_MASTER=nss331/builds/20010928.2.331-RTM/blowfish_NT4.0_Win95 else # NSS-3-2-2RTM BC_UX_MASTER=nss322/builds/20010820.1/y2sun2_Solaris8 BC_NT_MASTER=nss322/builds/20010820.1/blowfish_NT4.0_Win95 fi BC_MASTER=$BC_UX_MASTER BC_MASTER_WAS_SET=FALSE else BC_MASTER_WAS_SET=TRUE fi BC_RELEASE=3.2 export BC_RELEASE EARLY_EXIT=TRUE #before the report file has been created, causes Exit to #create it UX_D0=/share/builds/mccrel3/nss ################################### glob_init ########################## # global shell function, main initialisation function ######################################################################## glob_init() { if [ $O_PARAM = "ON" ] ; then eval_opts $* # parse parameters and options - set flags fi # if running from cron HOST needs to be known early, init_host # so the output file name can be constructed. Debug "Setting up environment...( $QASCRIPT_DIR/set_environment) " . $QASCRIPT_DIR/set_environment #finds out if we are running on Windows Debug "OPerating system: $os_name $os_full" umask 0 init_dirs init_files init_vars } ################################### init_vars ########################### # global shell function, sets the environment variables, part of init ######################################################################## init_vars() { if [ -z "$LOGNAME" ] then if [ $O_WIN = "ON" ] then LOGNAME=$USERNAME else LOGNAME=$USER fi if [ -z "$LOGNAME" ] then LOGNAME=$UNAME if [ -z "$LOGNAME" ] then LOGNAME=`basename $HOME` fi fi fi if [ -z "$LOGNAME" ] then Exit "Can't determine current user" fi case $HOST in iws-perf) O_HWACC=ON HWACC_LIST="rainbow ncipher" #MODUTIL="-add rainbow -libfile /usr/lib/libcryptoki22.so" export HWACC_LIST ;; *) O_HWACC=OFF ;; esac export O_HWACC } ######################################################################## # functions below deal with setting up the directories and PATHs for # all different flavors of OS (Unix, Linux, NT MKS, NT Cygnus) and QA # (Standard, local tinderbox) ######################################################################## ########################## find_nt_masterbuild ######################### # global shell function, sets the nt masterbuild directories, part of init ######################################################################## find_nt_masterbuild() { NT_MASTERDIR=${DAILY_BUILD}/${NT_MASTERBUILD} if [ "${NT_MB_WAS_SET}" = "FALSE" -a ! -d $NT_MASTERDIR ] ; then if [ -d ${DAILY_BUILD}/*NT4* ] ; then NT_MASTERBUILD=` cd ${DAILY_BUILD}; ls -d *NT4* ` Debug "NT_MASTERBUILD $NT_MASTERBUILD" NT_MASTERDIR=${DAILY_BUILD}/${NT_MASTERBUILD} fi fi Debug "NT_MASTERDIR $NT_MASTERDIR" } ################################### set_daily_build_dirs ########################### # global shell function, sets directories ######################################################################## set_daily_build_dirs() { if [ "$O_LOCAL" = "ON" -a "$O_LN" = "OFF" ] ; then DAILY_BUILD=${LOCAL_MOZROOT} # on local builds NSS_VER_DIR and DAILY_BUILD are # set to the LOCAL_MOZROOT, since it is not sure # if ../.. (DAILY_BUILD) even exists LOCALDIST=${LOCAL_MOZROOT}/dist elif [ "$O_TBX" = "ON" ] ; then DAILY_BUILD="$TBX_DAILY_BUILD" LOCALDIST=${UXDIST} else DAILY_BUILD=${NSS_VER_DIR}/builds/${QAYEAR}${BUILDDATE}.${BUILDNUMBER} LOCALDIST=${DAILY_BUILD}/${MASTERBUILD}/mozilla/dist fi } map_os64() { IS_64="" case `uname -s` in SunOS) MAPPED_OS=Solaris*8 IS_64=`(isainfo -v | grep 64)>/dev/null 2>/dev/null && echo 64 bit` if [ "$O_TBX" = "OFF" ] ; then set_osdir if [ -n "$IS_64" ] then #Wait for the 64 bit build to finish... Debug Testing build for $MAPPED_OS in $OSDIR Wait ${OSDIR}/SVbuild.InProgress.1 0 fi fi ;; AIX) IS_64=`lslpp -l | grep "bos.64bit"> /dev/null && echo 64 bit` ;; HP-UX) IS_64=`getconf KERNEL_BITS | grep 64 >/dev/null && echo 64 bit` ;; esac Debug "Mapped OS to $MAPPED_OS" } ################################### copy_to_local ######################## # global shell function, copies the necessary directories from the # daily build aerea to the local disk ######################################################################## copy_to_local() { Debug "Copy network directories to local directories" C2L_ERROR=0 if [ ! -d ${LOCAL_MOZROOT}/dist ] ; then mkdir -p ${LOCAL_MOZROOT}/dist || C2L_ERROR=1 fi if [ ! -d ${LOCAL_MOZROOT}/security/nss ] ; then mkdir -p ${LOCAL_MOZROOT}/security/nss || C2L_ERROR=2 fi if [ $C2L_ERROR != 0 ] ; then Exit "copy_to_local: Can t make necesssary directories ($C2L_ERROR ) " fi if [ ! -d ${LOCAL_MOZROOT}/security/nss/tests ] ; then cp -r ${TESTSCRIPTDIR} ${LOCAL_MOZROOT}/security/nss || C2L_ERROR=1 fi if [ ! -d ${LOCAL_MOZROOT}/security/coreconf ] ; then cp -r ${MOZILLA_ROOT}/security/coreconf ${LOCAL_MOZROOT}/security || C2L_ERROR=2 fi NO_DIRS=0; if [ "$O_WIN" = "ON" ] ; then OS_TARGET=WINNT;export OS_TARGET fi unset BUILD_OPT;export BUILD_OPT; unset USE_64;export USE_64; #FIXME only tested on 64 bit Solaris and only got 32 bit builds while [ $NO_DIRS -lt 4 ] ; do # first time thru: Debug 32 bit NT set_objdir Debug "Copying ${OBJDIR}..." if [ ! -d ${LOCAL_MOZROOT}/dist/${OBJDIR} ] ; then cp -r ${LOCALDIST}/${OBJDIR} ${LOCAL_MOZROOT}/dist || C2L_ERROR=3 fi NO_DIRS=`expr $NO_DIRS + 1` if [ $NO_DIRS = 1 ] ; then # 2nd time: OPT 32 bit NT BUILD_OPT=1; export BUILD_OPT; elif [ $NO_DIRS = 2 ] ; then # 3rd time: OPT, either 64 bit or Win95 or force exit if [ "$O_WIN" = "ON" ] ; then OS_TARGET=WIN95;export OS_TARGET else map_os64 if [ -z "$IS_64" ] ; then #32 bit platform NO_DIRS=4 else USE_64=1; export USE_64 fi fi elif [ $NO_DIRS = 3 ] ; then # 4th time: Debug either 64 bit or Win95 unset BUILD_OPT;export BUILD_OPT; fi done if [ $C2L_ERROR != 0 ] ; then Exit "copy_to_local: Can t copy necesssary directories ($C2L_ERROR ) " fi unset TESTSCRIPTDIR unset TESTDIR unset RESULTDIR O_LN=OFF #from here on pretend it is regular -l local QA FIXME, might cause #problems with the backwardcompatibility tests Debug "Successfully copied network directories to local directories" } ################################### local_dirs ########################### # global shell function, sets the directories for local QA ######################################################################## local_dirs() { Debug "Set directories for local QA" #if [ "$O_WIN" = "ON" ] ; then #win_set_tmp #fi NSS_VER_DIR=${LOCAL_MOZROOT} # on local builds NSS_VER_DIR and DAILY_BUILD are # set to the LOCAL_MOZROOT, since it is not sure # if ../../../.. (NSS_VER_DIR) even exists if [ -z "${RESULTDIR}" ] ; then # needs to be local as well Debug "Setting RESULTDIR for local QA" RESULTDIR="${LOCAL_MOZROOT}/tests_results/security/${HOST}-`date +%Y%m%d-%H.%M`" fi set_daily_build_dirs UX_MASTERDIR=`dirname ${LOCAL_MOZROOT}` NT_MASTERDIR=$UX_MASTERDIR MOZILLA_ROOT=${LOCAL_MOZROOT} UXDIST=${MOZILLA_ROOT}/dist NTDIST=${UXDIST} if [ -z "${TESTDIR}" ] ; then Debug "Setting TESTDIR for local QA" TESTDIR=${RESULTDIR} fi if [ -n "$TESTDIR" ] ; then if [ ! -d $TESTDIR ] ; then Debug "Making TESTDIR for local QA" mkdir -p $TESTDIR fi fi export TESTDIR Debug "RESULTDIR $RESULTDIR TESTDIR $TESTDIR" TESTSCRIPTDIR=${LOCAL_MOZROOT}/security/nss/tests COMMON=${TESTSCRIPTDIR}/common set_objdir debug_dirs export_dirs } ################################### tbx_dirs ########################### # global shell function, sets the directories for tinderbox QA ######################################################################## tbx_dirs() { Debug "Set directories for tinderbox" if [ "$O_WIN" = "ON" ] ; then win_set_d1 # we need the NSS_VER_DIR later else NSS_VER_DIR="$UX_D0"/nss$NSSVER fi if [ -z "${RESULTDIR}" ] ; then # needs to be different for tinderbox Debug "Setting RESULTDIR for tinderbox" TBX_NOBITS="" echo $QASCRIPT_DIR | grep 64 >/dev/null && TBX_NOBITS=64 TRD="${HOST}${TBX_NOBITS}-`date +%Y%m%d-%H.%M`" RESULTDIR="${NSS_VER_DIR}/tinderbox/tests_results/security/${TRD}" if [ ${DOMSUF} = "mcom.com" -o ${DOMSUF} = "netscape.com" -o ${DOMSUF} = "nscp.aoltw.net" ] ; then URL="sbs-rel.nscp.aoltw.net" else URL="cindercone.red.iplanet.com" fi if [ "$O_WIN" = "ON" ] ; then RESULTDIRURL="QA" else RESULTDIRURL="QA" fi Debug "RESULTDIRURL TinderboxPrint:$RESULTDIRURL" fi TBX_DAILY_BUILD=`cd ../../../../..;pwd` NSS_VER_DIR="${TBX_DAILY_BUILD}/../.." TBX_LOGFILE_DIR=`ls ${NSS_VER_DIR}/logs/tinderbox | sed -e 's/ .*//g'` if [ -z "$TBX_LOGFILE_DIR" ] ; then TBX_LOGFILE_DIR=`ls ${NSS_VER_DIR}/logs/tbx | sed -e 's/ .*//g'` TBX_LOGFILE_DIR="${NSS_VER_DIR}/logs/tbx/${TBX_LOGFILE_DIR}" else TBX_LOGFILE_DIR="${NSS_VER_DIR}/logs/tinderbox/${TBX_LOGFILE_DIR}" fi Debug "Set TBX_LOGFILE_DIR ${TBX_LOGFILE_DIR}" set_daily_build_dirs UX_MASTERDIR=`cd ../../../..;pwd` NT_MASTERDIR=$UX_MASTERDIR MOZILLA_ROOT=$UX_MASTERDIR/mozilla UXDIST=${MOZILLA_ROOT}/dist NTDIST=${UXDIST} if [ -z "${TESTDIR}" ] ; then Debug "Setting TESTDIR for tinderbox" TESTDIR=${RESULTDIR} fi if [ -n "$TESTDIR" ] ; then if [ ! -d $TESTDIR ] ; then Debug "Making TESTDIR for tinderbox" mkdir -p $TESTDIR fi fi Debug "Making QAstatus file" echo "QA running" >${TESTDIR}/QAstatus export TESTDIR Debug "RESULTDIR $RESULTDIR TESTDIR $TESTDIR" TESTSCRIPTDIR=`pwd` COMMON=${TESTSCRIPTDIR}/common set_objdir debug_dirs export_dirs } ################################### init_mcom ########################### # global shell function, sets domain specific variables for AOL's # domains according to Bishakha's instructions ######################################################################## init_mcom() { Debug "Running in mcom or netscape domain - changing directories..." if [ "${UX_MB_WAS_SET}" = "FALSE" ] ; then #in case it was set # before script was called use these values UX_MASTERBUILD=spd04_Solaris8 fi if [ "${NT_MB_WAS_SET}" = "FALSE" ] ; then NT_MASTERBUILD=spd06_NT4 fi MASTERBUILD=$UX_MASTERBUILD if [ "${BC_MASTER_WAS_SET}" = "FALSE" ] ; then BC_UX_MASTER=nss322/builds/20010820.1/y2sun2_Solaris8 BC_NT_MASTER=nss322/builds/20010820.1/blowfish_NT4.0_Win95 BC_MASTER=$BC_UX_MASTER fi UX_D0=/share/builds/sbsrel2/nss URL="sbs-rel.nscp.aoltw.net" } ################################### init_dirs ########################### # global shell function, sets the directories for standard QA # calls special functions for tinderbox, windows or local QA, part of init ######################################################################## init_dirs() { if [ ${DOMSUF} = "mcom.com" -o ${DOMSUF} = "netscape.com" -o ${DOMSUF} = "nscp.aoltw.net" ] ; then init_mcom fi if [ $O_WIN = "ON" ] ; then win_set_tmp write_to_tmpfile MASTERBUILD=$NT_MASTERBUILD BC_MASTER=$BC_NT_MASTER fi if [ "$O_LOCAL" = "ON" -a $O_LN = "OFF" ] ; then # if it is a LN we need to know # all the directories off the network first to copy them local_dirs # O_LOCAL alone assumes that all the directories are already there return elif [ "$O_TBX" = "ON" ] ; then tbx_dirs return elif [ "$O_WIN" = "ON" ] ; then win_set_d1 else NSS_VER_DIR="$UX_D0"/nss$NSSVER fi #set -x set_daily_build_dirs if [ -z "${BCDIST}" ] ; then #BCDIST=/share/builds/mccrel3/nss/${BC_MASTER}/mozilla/dist BCDIST=${NSS_VER_DIR}/../${BC_MASTER}/mozilla/dist if [ ! -d $BCDIST -a `basename $0` != jssqa ] ; then ask "Backward compatibility directory $BCDIST does not exist, continue" "y" "n" || Exit fi fi UX_MASTERDIR=${DAILY_BUILD}/${UX_MASTERBUILD} find_nt_masterbuild if [ "$O_WIN" = "ON" ] then MOZILLA_ROOT=${NT_MASTERDIR}/mozilla else MOZILLA_ROOT=${UX_MASTERDIR}/mozilla fi UXDIST=${UX_MASTERDIR}/mozilla/dist NTDIST=${NT_MASTERDIR}/mozilla/dist if [ -z "${RESULTDIR}" ] ; then RESULTDIR=${UX_MASTERDIR}/mozilla/tests_results/security fi if [ -n "$PRODUCT_TO_TEST" -a "$PRODUCT_TO_TEST" = "JSS" ] ; then if [ "$O_WIN" = "ON" ] ; then JSS_NSS_SRC_DIR=$JSS_NSS_NT_SRC_DIR fi TESTSCRIPTDIR=${NSS_VER_DIR}/../${JSS_NSS_SRC_DIR}/mozilla/security/nss/tests else TESTSCRIPTDIR=${MOZILLA_ROOT}/security/nss/tests fi if [ ! -d $TESTSCRIPTDIR -a `basename $0` != jssqa ] ; then if [ "$O_WIN" = "ON" -a "$WIN_WAIT_FOREVER" = "ON" ] then WaitForever $TESTSCRIPTDIR/all.sh 1 else Exit "Test directory $TESTSCRIPTDIR does not exist" fi fi COMMON=${TESTSCRIPTDIR}/common if [ "$O_LOCAL" = "ON" -a $O_LN = "ON" ] ; then # if it is a LN we need to know # all the directories off the network first to copy them copy_to_local local_dirs fi #set +x set_objdir debug_dirs export_dirs } debug_dirs() { Debug "NTDIST $NTDIST" Debug "UXDIST $UXDIST" Debug "TESTSCRIPTDIR $TESTSCRIPTDIR" Debug "RESULTDIR $RESULTDIR" Debug "TMP $TMP" Debug "LOCALDIST_BIN $LOCALDIST_BIN" Debug "COMMON $COMMON" Debug "MOZILLA_ROOT $MOZILLA_ROOT" Debug "BCDIST $BCDIST" } export_dirs() { export NSS_VER_DIR DAILY_BUILD NTDIST UXDIST RESULTDIR TESTSCRIPTDIR BCDIST export UX_MASTERDIR NT_MASTERDIR COMMON MOZILLA_ROOT } set_osdir() { OSDIR=${DAILY_BUILD}/*${MAPPED_OS}* } ################################### init_files ########################### # global shell function, sets filenames, initializes files, part of init ######################################################################## init_files() { if [ $O_CRONFILE = "ON" ] then Debug "attempting to create resultfiles" if [ "$O_TBX" = "ON" ] ; then NEWFILENAME=${TBX_LOGFILE_DIR}/qa.log if [ ! -w ${TBX_LOGFILE_DIR} ] ; then Exit "can't touch $NEWFILENAME" fi else NEWFILENAME=$RESULTDIR/$HOST.`basename $0` fi if [ ! -d $RESULTDIR ] then mkdir -p $RESULTDIR || Exit "Error: can't make $RESULTDIR" fi if [ ! -w $RESULTDIR ] ; then Exit "can't touch $NEWFILENAME" fi Debug "About to touch $NEWFILENAME " touch $NEWFILENAME || Exit "Error: can't touch $NEWFILENAME" if [ "$O_TBX" = "ON" ] ; then echo "QA results in $RESULTDIR" >>$NEWFILENAME || Exit "Error: can't write to $NEWFILENAME" fi Debug "About to cat $FILENAME >>$NEWFILENAME " cat $FILENAME >>$NEWFILENAME || Exit "Error: can't append $FILENAME to $NEWFILENAME" TMPFILES="$TMPFILES $FILENAME" FILENAME=$NEWFILENAME Debug "Writing output to $FILENAME" fi } ################################### write_to_tmpfile ########################## # global shell function, for NT and cron operation, first a tmpfile # needs to be created ######################################################################## write_to_tmpfile() { O_CRONFILE=ON O_FILE=ON FILENAME=${TMP}/nsstmp.$$ # for now write to the temporary file # since we don't know the hostname yet # will be inserted to the real file later TMPFILES="$TMPFILES nsstmp.$$" touch $FILENAME || Exit "Error: can't touch $FILENAME" Debug "Writing output to $FILENAME" } ############################# turn_on_cronoptions ###################### # global shell function, turns on options needed for cron and tinderbox ######################################################################## turn_on_cronoptions() { O_CRON=ON O_SILENT=ON O_DEBUG=ON # FIXME take out! O_ALWAYS_YES=ON write_to_tmpfile } ########################## test_mozroot ########################## # global shell function, determines if the variable LOCAL_MOZROOT is set, # and is usable as mozilla root diretory for a local QA ################################################################### test_mozroot() { PWD=`pwd` Debug "LOCAL_MOZROOT = $LOCAL_MOZROOT" case "$LOCAL_MOZROOT" in [0-9-]*|tip) glob_usage "Error: -"$1" requires a directoryname to follow (start with a letter) " ;; \.\.) LOCAL_MOZROOT=`dirname $PWD` ;; \.) LOCAL_MOZROOT=$PWD ;; \.\/*) LOCAL_MOZROOT=`echo $LOCAL_MOZROOT | sed -e "s/^\.//"` LOCAL_MOZROOT="${PWD}${LOCAL_MOZROOT}" ;; \.\.\/*) LOCAL_MOZROOT="${PWD}/${LOCAL_MOZROOT}" ;; \/*|[a-zA-Z]:\/*) ;; ?*) LOCAL_MOZROOT="${PWD}/${LOCAL_MOZROOT}" ;; *) glob_usage "Error: -"$1" requires a directoryname to follow" ;; esac Debug "Reformated MOZROOT to $LOCAL_MOZROOT" if [ "$1" = "ln" ] ; then LOCAL_MOZROOT_PARENT=`dirname $LOCAL_MOZROOT` if [ ! -d $LOCAL_MOZROOT_PARENT -o ! -w $LOCAL_MOZROOT_PARENT -o \ ! -x $LOCAL_MOZROOT_PARENT ] ; then Exit "Error: Can't create $LOCAL_MOZROOT (permissions)" fi if [ ! -d "$LOCAL_MOZROOT" ] ; then mkdir $LOCAL_MOZROOT || Exit "Error: Can't create mozroot $LOCAL_MOZROOT (mkdir failed)" else ask "mozroot $LOCAL_MOZROOT exists - continue (y will remove dir) ?" \ "y" "n" || Exit rm -rf $LOCAL_MOZROOT/dist $LOCAL_MOZROOT/security $LOCAL_MOZROOT/tests_results || Exit "Error: Can't clean mozroot $LOCAL_MOZROOT" fi fi if [ ! -d "$LOCAL_MOZROOT" ] ; then glob_usage "Error: mozilla root $LOCAL_MOZROOT not a valid directory" fi } ################################### eval_opts ########################## # global shell function, evapuates options and parameters, sets flags # variables and defaults ######################################################################## eval_opts() { while [ -n "$1" ] do case $1 in -cron) turn_on_cronoptions ;; -T*|-t*) O_TBX=ON turn_on_cronoptions O_SILENT=OFF #FIXME debug only ;; -S*|-s*) O_SILENT=ON ;; -Y*|-y) Debug "Option -y dedectet" O_ALWAYS_YES=ON ;; -d*|-D) O_DEBUG=ON #set -x ;; -ml|-ML) O_MAIL_LINK=ON shift MAILINGLIST=$1 if [ -z "$MAILINGLIST" ] then glob_usage "Error: -m requires a mailinglist to follow, for example sonmi,wtc,nelsonb " fi Debug "Sending link to result to $MAILINGLIST" ;; -m|-M) O_MAIL=ON shift MAILINGLIST=$1 if [ -z "$MAILINGLIST" ] then glob_usage "Error: -m requires a mailinglist to follow, for example sonmi,wtc,nelsonb " fi Debug "Sending result to $MAILINGLIST" ;; -fcron*|-F[Cc][Rr][Oo][Nn]*) write_to_tmpfile ;; -f|-F) O_FILE=ON shift FILENAME=$1 if [ -z "$FILENAME" ] then glob_usage "Error: -f requires a filename to follow" fi #rm -f $FILENAME 2>/dev/null touch $FILENAME || Exit "Error: can't touch $FILENAME" #NOTE we append rather that creating Debug "Writing output to $FILENAME" ;; -h|-help|"-?") glob_usage ;; -ln) if [ `basename $0` != nssqa ] ; then glob_usage "Error: Can't handle option $1" fi O_LOCAL=ON O_LN=ON shift LOCAL_MOZROOT=$1 test_mozroot ln ;; -lt) if [ `basename $0` != nssqa ] ; then glob_usage "Error: Can't handle option $1" fi O_LN=ON O_LOCAL=ON ;; -l) if [ `basename $0` != nssqa ] ; then glob_usage "Error: Can't handle option $1" fi O_LOCAL=ON shift LOCAL_MOZROOT=$1 test_mozroot l ;; -p) shift PORT=$1 export PORT ;; -*) glob_usage "Error: Can't handle option $1" ;; tip|3.|3..) NSSVER=$1 if [ -z "$NSSVER" ] ; then glob_usage "Error: illegal parameter" fi ;; [01][0-9][0123][0-9]) BUILDDATE=$1 if [ -z "$BUILDDATE" ] ; then glob_usage "Error: illegal parameter" fi ;; ?*) glob_usage "Error: Can't handle parameter $1" ;; esac shift done if [ -z "$PORT" -a "$O_TBX" = "ON" ] ; then PORT=8444 export PORT if [ -z "$NSSVER" ] ; then NSSVER="tip" Debug "NSS Version: Parameters missing - defaulting to tip!" fi elif [ -z "$NSSVER" ] ; then NSSVER="tip" Debug "NSS Version: Parameters missing - defaulting to tip!" fi if [ -z "$BUILDDATE" ] ; then BUILDDATE=`date +%m%d` Debug "Builddate: Parameters missing - defaulting to today!" fi Debug "Builddate $BUILDDATE NssVersion $NSSVER" export BUILDDATE NSSVER export O_CRON O_SILENT O_DEBUG O_ALWAYS_YES O_TBX } win_set_tmp() { TMP=`echo "$TMP" | sed -e 's/ /\/t/g' -e 's//\/b/' -e 's/\\\/\//g'` Debug "TMP reformated to $TMP" } ######################### win_set_d1 ################################ # global shell function, interactively finds the directories in case # windows can't get to the default ######################################################################## win_set_d1() { Debug "set Windows Directories..." #win_set_tmp if [ "$O_CYGNUS" = ON ] then NSS_VER_DIR=/cygdrive/w/nss/nss$NSSVER else NSS_VER_DIR=w:/nss/nss$NSSVER fi if [ ! -w $NSS_VER_DIR ] then Echo "Windows special... can't write in $NSS_VER_DIR" if [ "$O_CYGNUS" = ON ] then NSS_VER_DIR=/cygdrive/u/nss/nss$NSSVER else NSS_VER_DIR="u:/nss/nss$NSSVER" fi else Debug "NSS_VER_DIR set to $NSS_VER_DIR" return fi while [ ! -w $NSS_VER_DIR ] do if [ "$O_CRONFILE" = "ON" ] then Exit "cant write in $NSS_VER_DIR" fi Warning "cant write in $NSS_VER_DIR" Echo "input start directory (u:/nss, d:/src/nss, f:/shared/nss) " read D if [ -n "$D" ] then NSS_VER_DIR=$D/nss$NSSVER fi done Debug "NSS_VER_DIR set to $NSS_VER_DIR" } ########################### init_host ################################## # global shell function, sets required variables HOST and DOMSUF, and asks # the user if it has been set right ######################################################################## set_host() { init_host } init_host() { if [ `basename $0` != nssqa ] ; then return fi init_host_done=0 if [ $DS_WAS_SET = FALSE ] #give chance to overwrite, espec. for NT then Debug "Domainname was not set..." DOMSUF=`domainname 2>/dev/null` if [ -z "$DOMSUF" ] then Debug "domainname command did not work ..." DOMSUF=`echo $HOST | grep '\.' | sed -e "s/[^\.]*\.//"` if [ -z "$DOMSUF" ] then Debug "Domainname not part of the hostname" DOMSUF=`cat /etc/defaultdomain 2>/dev/null` if [ -z "$DOMSUF" ] then Debug "Domainname needs to be hardcoded to red.iplanet.com" DOMSUF="red.iplanet.com" fi fi fi fi case $HOST in *\.*) Debug "HOSTNAME $HOST contains Dot" HOST=`echo $HOST | sed -e "s/\..*//"` ;; esac if [ -z "$HOST" ] then HOST=`uname -n` case $HOST in *\.*) Debug "HOSTNAME $HOST contains Dot" HOST=`echo $HOST | sed -e "s/\..*//"` ;; esac fi if [ $O_DEBUG = "ON" ] then while [ $init_host_done -eq 0 ] do Echo ask "DOMSUF=$DOMSUF, HOST=$HOST - OK", "y" "n" && init_host_done=1 if [ $init_host_done -eq 0 ] then Echo "input DOMSUF: " read D if [ -n "$D" ] then DOMSUF=$D fi Echo "input HOST: " read H if [ -n "$H" ] then HOST=$H fi fi done fi export HOST DOMSUF Debug "HOST: $HOST, DOMSUF: $DOMSUF" } #-----------------------------# UTILS #---------------------------------- ########################### qa_stat_get_sysinfo ######################## # local shell function, tries to determine the QA operating system ######################################################################## qa_stat_get_sysinfo() { case $1 in ?*) REM_SYS=$1 GET_SYSINFO="rsh $1" ;; *) REM_SYS="" GET_SYSINFO="" ;; esac QA_SYS=`$GET_SYSINFO uname -sr` echo $QA_SYS | grep Linux >/dev/null && QA_RHVER=`$GET_SYSINFO cat /etc/redhat-release` if [ -n "$QA_RHVER" ] then QA_OS=`echo $REM_SYS $QA_RHVER | sed -e "s/Red Hat /RH /" \ -e "s/ release//"` else case $QA_SYS in *SunOS*5.[89]*) ISAINFO=`$GET_SYSINFO isainfo -v` IS_64=`echo $ISAINFO | grep 64 >/dev/null && \ echo 64 bit` IS_I386=`echo $ISAINFO | grep i386 >/dev/null && \ echo i86pc` if [ -n "$IS_I386" ] ; then IS_64="$IS_I386"; fi; if [ -z "$IS_64" ] ; then IS_64="32 bit"; fi; ;; *HP*) IS_64=`$GET_SYSINFO getconf KERNEL_BITS | grep 64 >/dev/null && echo 64 bit` if [ -z "$IS_64" ] ; then IS_64="32 bit"; fi; ;; *AIX*) IS_64=`$GET_SYSINFO lslpp -l | grep "bos.64bit"> /dev/null && echo 64 bit` if [ -z "$IS_64" ] ; then IS_64="32 bit"; fi; ;; esac QA_OS=`echo "$REM_SYS $QA_SYS $IS_64"` fi if [ "$O_SILENT" != ON ] ; then echo $QA_OS fi QA_OS_STRING=`echo $QA_OS | sed -e "s/^[_ ]//" -e "s/ /_/g"` } ################################### set_objdir ######################### # global shell function, sets the object directories and DIST ######################################################################## set_objdir() { Debug "set object dir" OBJDIR=`cd ${TESTSCRIPTDIR}/common; gmake objdir_name` OS_ARCH=`cd ${TESTSCRIPTDIR}/common; gmake os_arch` #at this point $MASTERBUILD needs to be either NT or unix set_daily_build_dirs LOCALDIST_BIN=${LOCALDIST}/${OBJDIR}/bin DIST=$LOCALDIST if [ -z "${TEST_LEVEL}" ] ; then TEST_LEVEL=0 fi bc ${TEST_LEVEL} #set the path for the backward compatibility test PATH_CONTAINS_BIN="TRUE" export PATH_CONTAINS_BIN export OBJDIR OS_ARCH LOCALDIST LOCALDIST_BIN DIST PATH } ########################### bc ######################################### # global shell function , sets paths for the backward compatibility test ######################################################################## bc() { if [ -n "$PRODUCT_TO_TEST" -a "$PRODUCT_TO_TEST" = "JSS" ] ; then TESTDIR=${RESULTDIR} BC_ACTION="" DON_T_SET_PATHS="FALSE" #let init.sh override - FIXME - check if necessary return fi DON_T_SET_PATHS="TRUE" case $1 in 0) #unset TESTDIR TESTDIR=${RESULTDIR} if [ "$O_WIN" = "ON" -a "$O_CYGNUS" != ON ] ; then PATH="$TESTSCRIPTDIR;$LOCALDIST_BIN;$BASEPATH" else PATH=$TESTSCRIPTDIR:$LOCALDIST_BIN:$BASEPATH fi BC_ACTION="" DON_T_SET_PATHS="FALSE" #let init.sh override - FIXME - check if necessary ;; *) if [ "$O_LOCAL" = "ON" ] ; then Exit "FIXME Can't run backwardcompatibility tests locally yet" fi TESTSCRIPTDIR=${BCDIST}/../security/nss/tests COMMON=${TESTSCRIPTDIR}/common TESTDIR=${RESULTDIR}/bct BC_ACTION="backward compatibility of binaries in $BC_MASTER to new libs" BCDIST_BIN=${BCDIST}/${OBJDIR}/bin LD_LIBRARY_PATH=${LOCALDIST}/${OBJDIR}/lib if [ "$O_WIN" = "ON" ] ; then if [ "$O_CYGNUS" = ON ] ; then PATH=$TESTSCRIPTDIR:$BCDIST_BIN:$BASEPATH:$LD_LIBRARY_PATH else PATH="$TESTSCRIPTDIR;$BCDIST_BIN;$BASEPATH;$LD_LIBRARY_PATH" fi else PATH=$TESTSCRIPTDIR:$BCDIST_BIN:$BASEPATH fi Debug "1st stage of backward compatibility test" ;; esac if [ -n "$TESTDIR" ] ; then if [ ! -d $TESTDIR ] ; then mkdir -p $TESTDIR fi export TESTDIR fi SHLIB_PATH=${LD_LIBRARY_PATH} LIBPATH=${LD_LIBRARY_PATH} Debug "PATH $PATH" Debug "LD_LIBRARY_PATH $LD_LIBRARY_PATH" export PATH LD_LIBRARY_PATH SHLIB_PATH LIBPATH export DON_T_SET_PATHS BC_ACTION export TESTSCRIPTDIR COMMON } ########################### Ps ######################################### # global shell function , attempts a platform specific ps ######################################################################## Ps() { #AIX, ps -ef, solaris /usr/5bin/ps -ef, win ps -ef but no user id #linux ps -ef, HP if [ $os_name = "SunOS" ] then /usr/5bin/ps -ef else ps -ef fi } ########################### kill_by_name ################################ # global shell function , kills the process whose name is given as # parameter ######################################################################## kill_by_name() { for PID in `Ps | grep "$1" | grep -v grep | \ sed -e "s/^ *//g" -e "s/^[^ ]* //" -e "s/^ *//g" -e "s/ .*//g"` do if [ $O_WIN = "ON" -a $O_CYGNUS = "ON" ] then ask "Do you want to kill Process $PID (`Ps | grep $PID | \ grep -v grep | awk '{ print $1, $2, $6, $7, $8, $9 }' | \ sed -e "s/[0-9]:[0-6][0-9]//g" | grep $PID `)" \ "y" "n" && { kill $PID sleep 1 kill -9 $PID 2>/dev/null } else ask "Do you want to kill Process $PID (`Ps | grep $PID | \ grep -v grep | awk '{ print $1, $2, $8, $9, $10, $11 }' | \ sed -e "s/[0-9]:[0-6][0-9]//g" | grep $PID `)" \ "y" "n" && { kill $PID sleep 1 kill -9 $PID 2>/dev/null } fi done } ############################### early_exit ################################### # global shell function , attempts a little more usefull user notification # of a complete failure ######################################################################## early_exit() { if [ -z "$DOCDIR" ] then DOCDIR=`dirname $0`/../doc fi if [ -f $DOCDIR/QAerror.html ] then Debug "Found QA errorheader" rm ${FILENAME}.err 2>/dev/null cp $DOCDIR/QAerror.html ${FILENAME}.err echo "$1" >>${FILENAME}.err echo '' >>${FILENAME}.err if [ -n "$FILENAME" -a -f "$FILENAME" ] then cat $FILENAME | sed -e "s/^/
/" >>${FILENAME}.err fi echo '' >>${FILENAME}.err cat ${FILENAME}.err | $RMAIL $MAILINGLIST rm ${FILENAME}.err 2>/dev/null #echo "cat ${FILENAME}.err | $RMAIL $MAILINGLIST " fi } ############################### Exit ################################### # global shell function , central exiting point # cleanup: temporary files, kill the remaining selfservers if sourcing # script sets KILL_SELFSERV ######################################################################## Exit() { Echo $1 if [ "$O_CRON" = "OFF" ] then echo $1 >&2 fi if [ -f "${KILLPIDS}" ] then Debug "Attempting to kill background processes...`cat ${KILLPIDS}`" kill `cat "${KILLPIDS}"` sleep 1 kill -9 `cat "${KILLPIDS}"` fi if [ -n "${TMPFILES}" ] then Debug "rm -f ${TMPFILES}" rm -f $TMPFILES 2>/dev/null fi O_ALWAYS_YES=ON # set to non-interactive - don't ask anymore questions here if [ $KILL_SELFSERV = "ON" ] then kill_by_name selfserv fi if [ $O_MAIL_LINK = "ON" -a $O_FILE = "ON" ] then if [ $EARLY_EXIT = TRUE ] #before the report file has been created then early_exit "$1" else head -3 $FILENAME >$ML_FILE echo "Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit " >>$ML_FILE echo $HREF_TMP_HTML_FILE >>$ML_FILE cat $ML_FILE | $RMAIL $MAILINGLIST fi #FIXME - early exit etc elif [ $O_MAIL = "ON" -a $O_FILE = "ON" ] then if [ $EARLY_EXIT = TRUE ] #before the report file has been created then early_exit "$1" elif [ -n "$FILENAME" -a -f "$FILENAME" ] then cat $FILENAME | $RMAIL $MAILINGLIST fi #rm $FILENAME 2>/dev/null elif [ $O_MAIL = "ON" -a $EARLY_EXIT = TRUE ] then early_exit "$1" rm $FILENAME 2>/dev/null fi #chmod a+rw ${RESULTDIR} ${RESULTDIR}/* ${RESULTDIR}/*/* & if [ -n "$O_TBX" -a "$O_TBX" = "ON" ] ; then rm ${TESTDIR}/QAstatus if [ "$1" = "killed... cleaning up..." ] ; then echo "QA killed" >${TESTDIR}/QAstatus elif [ "$TBX_EXIT" = 0 ] ; then echo "QA passed" >${TESTDIR}/QAstatus else echo "QA failed" >${TESTDIR}/QAstatus fi exit $TBX_EXIT else exit fi } trap "rm -f ${TMPFILES} 2>/dev/null; Exit 'killed... cleaning up...'" 2 3 15 ################################ Wait ################################## # global shell function to wait for an event to happen, 1st parameter # filename to watch, 2nd parameter 0 - wait for it to disappear, 1 wait # for it to be created. # uses the variables WAIT_FOR and WAIT_TIMES # WAIT_FOR: if waiting for an event sleep n seconds before rechecking # recomended value 10 minutes 600 # WAIT_TIMES: recheck n times before giving up to prevent endless loop # recomended 30 - total of 5h ######################################################################## Wait() { i=0 Debug "Waiting for $1" while [ $i -lt $WAIT_TIMES ] do i=`expr $i + 1` if [ -f "$1" -a $2 -eq 1 ] # if file exists and is supposed to then return fi if [ ! -f "$1" -a $2 -eq 0 ] # not exists and not supposed to exist then return fi Debug "Waiting for $1, loop #$i, about to sleep $WAIT_FOR seconds zzzz..." sleep $WAIT_FOR done TOTAL=`expr $WAIT_TIMES \* $WAIT_FOR / 60` Exit "I HAVE WAITED LONG ENOUGH FOR $1 NOW, I'M GONE! (THAT WAS A TOTAL OF $TOTAL MINUTES) I have better things to do... " } ################################ WaitForever ################################## # global shell function to wait for an event to happen, 1st parameter # filename to watch, 2nd parameter 0 - wait for it to disappear, 1 wait # for it to be created. # because we daon't have any relyable cron on NT... ######################################################################## WaitForever() { i=0 Debug "Waiting for $1" TOTAL=0 while [ 1 ] do i=`expr $i + 1` if [ -f "$1" -a $2 -eq 1 ] # if file exists and is supposed to then return fi if [ ! -f "$1" -a $2 -eq 0 ] # not exists and not supposed to exist then return fi Debug "Waiting for $1, loop #$i, about to sleep $WAIT_FOR seconds Total $TOTAL" sleep $WAIT_FOR TOTAL=`expr $i \* $WAIT_FOR / 60` if [ -n "$MAX_FOREVER" ] # we are cheating. Forever can be very short... then if [ "$TOTAL" -gt "$MAX_FOREVER" ] then Exit "I HAVE WAITED LONG ENOUGH FOR $1 NOW, I'M GONE! (THAT WAS A TOTAL OF $TOTAL MINUTES) I have better things to do... " fi fi done } ################################### is_running ######################### # global shell function , implements primitive locking mechanism # filename is passed as a parameter, if filename.* exists we assume calling # script is running already and exit, otherwise filename.processid is # created ######################################################################## is_running() { Debug "Testing if $0 is already running... file ${1} - ${1}.$$" if [ -f ${1}.* ] then Exit "$0 seems to be running already ($1 exists) - Exiting" fi TMPFILES="$TMPFILES ${1}.$$" echo "running $0 on `date` PID $$" >${1}.$$ Debug "wrote \"running $0 on `date` PID $$\" to ${1}.$$" } #---------------------------# USERCOM #--------------------------------- ############################## Echo ##################################### # global shell function , depending on the options the output gets written # to a file, or is being discarded # FIXME \n and \c are mistreates by differnet shells, and linux has /bin/echo # instead of /usr/bin/echo ######################################################################## Echo () { if [ $O_SILENT = OFF ] then echo "$*" #/usr/bin/echo "$*" fi if [ $O_FILE = ON ] then echo "$*" >>$FILENAME fi } ################################### ask ################################ # global shell function, Asks the a question, and gives the returns 0 # on the 1st choice, 1 on the 2nd choice # # PARAMETERS: # $1 question text # $2 1st choice # $3 2nd choice # # MODIFIERS: # -y O_ALWAYS_YES will assume a first choice always (not neccessaryly "y") # # RETURN: # 0 - User picked 1st choice # 1 - User picked 2nd choice # # EXAMPLE # ask "Would you like to continue" "y" "n" || Exit # will produce the string "Would you like to continue (y/n) ?", # read input from keyboard (or assume a yes with option -y) # - on a yes it will return 0, on a no it will return 1, the # shell interprets it as error and the || Exit will be executed # # NOTE: NEVER use "n" as the second parameter - it will mess up -y # don't ask "Continue" "n" "y" || Exit # it will Exit on a "y" # ######################################################################## Ask() { ask $* } ask() { if [ $O_ALWAYS_YES = ON ] then Echo "$1 ($2/$3) ?" Echo "YES!" return 0 fi A="" while [ 1 ] do Echo "$1 ($2/$3) ?" read A if [ -n "$A" ] then if [ $A = $2 ] then return 0 elif [ $A = $3 ] then return 1 fi fi done return 0 } ################################### Warning ############################ # global shell function, Asks the user a "... continue? (y/n)" question, # and exits when the user answers with no # NOTE -y will answer the warnings always with yes ######################################################################## Warning () { ask "WARNING: $0: \n $* continue " "y" "n" || Exit } ################################### Debug ############################ # global shell function, when option -d Debugging output is written ######################################################################## Debug() { if [ $O_DEBUG = ON ] then Echo "DEBUG: (`date +%H:%M`) $0: $*" fi } ################################### line ############################### # global shell function, supposed to make output more readable... ######################################################################## line() { Echo #Echo "=======================================================================" #Echo } ################################### opt_usage ########################## # global shell function, tells user about available options ######################################################################## opt_usage() { if [ $O_OPTIONS = "ON" ] then Echo line Echo Echo " -y answer all questions with y - use at your own risk..." Echo " -s silent (only usefull with -y)" Echo " -h, -? - you guessed right - displays this text" Echo " -d debug" Echo " -f - write the (error)output to filename" Echo " -fcronfile produces the resultfiles in the same locations" Echo " as would have been produced with -cron" Echo " -m - send filename to mailinglist (csl " Echo " example sonmi,nelsonb,wtc) only useful with -f" Echo " -ml - send link to filename to mailinglist " Echo " (csl example sonmi,nelsonb,wtc) only useful with -f" Echo " -cron equivalient to -y -s -d -f \$RESULTDIR/\$HOST.nssqa" Echo " -t run on a tinderbox build (included -cron)" if [ `basename $0` = nssqa ] ; then Echo " -l run on a local build" Echo " -ln copy a networkbuild to a local directory " Echo " mozroot, used for networkindipendend QA " Echo " -lt try to copy a networkbuild to a local directory, if" Echo " not possible run on the network Echo " used for networkindipendend QA fi # # special strings fi } ################################### glob_usage ######################### # global shell function, how to use the calling script (parameters, options) ######################################################################## glob_usage() { line Echo $1 Echo if [ $O_OPTIONS = "ON" ] then Echo "usage $0 [options] nssversion builddate" else Echo "usage $0 nssversion builddate" fi Echo " for example: $0 30b 0926" Echo " $0 31 1002" opt_usage Echo Exit "$1" } tell() { if [ $O_SILENT = OFF ] then line pwd ls -CF line fi if [ $O_FILE = ON ] then line pwd >>$FILENAME ls -CF >>$FILENAME line fi } if [ $O_INIT = "ON" ] then glob_init $* fi EARLY_EXIT=FALSE