#!/bin/bash
set -a

# Default values, in case /etc/autobench.conf doesn't exist
HOME=${HOME:-/root}
AUTODIR=${AUTODIR:-/autobench}
NONTESTLOGDIR=${NONTESTLOGDIR:-$AUTODIR/logs/}
LOGFILE=${LOGFILE:-$NONTESTLOGDIR/logfile}
TMPDIR=${TMPDIR:-$AUTODIR/var/tmp/$$}
LOGDIR=${LOGDIR:-$NONTESTLOGDIR}
DATS_CONFIG_DEDICATED=${DATS_CONFIG_DEDICATED:-yes}
AUTO_CONFIG_BOOTABLE=${AUTO_CONFIG_BOOTABLE:-yes}
DATS_CONFIG_LOAN=${DATS_CONFIG_LOAN:-yes}

if ! [ -d "$TMPDIR" ]; then
	mkdir -p "$TMPDIR"; 
fi

# Setup the path...
export PATH=$AUTODIR/scripts/user:$AUTODIR/scripts:$AUTODIR/scripts/benchmarks:$AUTODIR/scripts/profilers:$PATH:/usr/local/sbin:/usr/sbin:/sbin

# How do we time things?
if [ -e /usr/bin/time ]; then
	TIME_CMD="/usr/bin/time"
else
	TIMEFORMAT="%2Uuser %2Ssystem %Relapsed %P%%CPU"
	TIME_CMD="time"
fi

# Who am I?
if [ -z "$MYIP" ]; then
	WORLD_IFACE=`/sbin/route -n | tr -s " " | cut -f2,8 -d" " | grep [0-9] | grep -v "0.0.0.0" | cut -f2 -d" " | head -n1 `
	if [ -z "$WORLD_IFACE" ]; then
		WORLD_IFACE="eth0"
	fi
	export MYIP=`/sbin/ifconfig $WORLD_IFACE | grep "inet addr" | tr -s " " | cut -f3 -d" " | cut -f2 -d:`
fi
		

GSA_ID="noquota noqu0ta"
GSA_ID="anonymous nopass"
ANON_ID="anonymous nopass"
function check_status() {

let rc=$?
STAMP=`date +%x-%T`
if [ $rc != 0 ]
then	
	echo $STAMP $1 "Failed rc = $rc" | tee -a $LOGFILE
	exit 86
else 
	echo $STAMP $1 "Succeeded"| tee -a $LOGFILE
fi
}

function log() {
STAMP=`date +%x-%T`
	echo $STAMP $1 | tee -a $LOGFILE
}

function scrub_string(){
local tmp=
	tmp=${1//(/{}
	tmp=${tmp//)/\}}
	tmp=${tmp// /_}
	echo "$tmp"
}

function get_file_as () {
	# args:
	# get_file_as dest url
	#	 url is either an http, or ftp url, or a location on the filesystem
	if [ $# -lt 2 ]; then
		echo "You must specify two arguments to get_file_as"
		exit 1
	fi
	if [ -e "$1" ]; then
		log "get_file_as():" target $1 already exists, removing
		rm $1
	fi;
	case $2 in
		*gz) OUTFILE=$1.gz ;;
		*bz2) OUTFILE=$1.bz2 ;;
		*) OUTFILE=$1 ;;
	esac
    case $2 in
             http://*|https://*|ftp://*)
                     wget --progress=bar -O $OUTFILE -q $2
                     check_status "Getting file: $2"
                     ;;
             *)
                     cp $2 $1
                     # just because this does start with http or ftp does not mean
                     # it is a local file, if not found local try remote.
                     if [ $? != "0" ]; then
                             log "Copy of local file: $2 failed, trying remote"
                             wget --progress=bar -O $OUTFILE -q $2
                             check_status "Getting file: $2"
                     else
                             log "Copy file $2 Succeeded"
                     fi
                     ;;
    esac

	case $2 in
		*gz) gunzip $OUTFILE ;;
		*bz2) bunzip2 $OUTFILE ;;
	esac
}

#Args:
# $1 = src file
# $2 = dst file
function apply_config () {
	if [ -e "$2" ]; then
		# find all of the CONFIG symbols mentioned in $1
		cat $1 | grep ^CONFIG_ 				\
			| sed -e "s/^[# ]*\([^ =]*\).*$/\1=/" 	\
		> $1.opts
		# and pull them out of $2
		grep -v -F -f $1.opts $2 > $2.new 
		# then readd $1's versions to $2
		cat $1 >> $2.new && \
		rm $2 2> /dev/null && \
		mv $2.new $2
		
		rm $1.opts
	else
		cp $1 $2
	fi
}

function get_with_cache(){
	local FILE=$1;
	local BASEFILE=`basename $FILE`;
	
	if [ ! -e "$LOCAL_CACHE/$BASEFILE" ]; then
		# Try the server-cache
		mkdir -p $LOCAL_CACHE
		pushd	$LOCAL_CACHE > /dev/null
		wget -q $SERVER_CACHE/$BASEFILE
		if [ $? -ne 0 ]; then
			echo kernel source locations:
			for SOURCE in $SOURCES; do
				log "getting stock $VER kernel from $SOURCE"
				wget --progress=bar $SOURCE/$FILE \
					&& break;
			done
			check_status "Get kernel"
		fi
		popd > /dev/null
	fi
}


# Figure out what type of filesystem a directory/file is on
function fs_type() {
	local WORK_DIR=$1
	local LOG_FILE=$2
	local FS_TYPE ROOT_TYPE

	WORK_DIR=`echo $WORK_DIR | sed -e "s:/$::"` # Remove trailing /'s
	FS_TYPE=`mount | grep $WORK_DIR | cut -f5 -d" "`

	if [ ${WORK_DIR:0:1} == '/' ]; then  #must be absolute path
		if [ -z "$FS_TYPE" ]; then
			if [ -d $WORK_DIR ]; then
				log "WARNING: $WORK_DIR is not an isolated partition"
			fi
	
			# Figure out which FS the given directory is on...
			ROOT_TYPE=`mount | grep "/ " | cut -f5 -d" "`
			while [ -n "$WORK_DIR" ]; do
				FS_TYPE=`mount | grep "$WORK_DIR " | cut -f5 -d" "`
				if [ -n "$FS_TYPE" ]; then
					break	# We found it...
				fi
				FS_TYPE=$ROOT_TYPE
				WORK_DIR=`echo $WORK_DIR | sed -e "s:/[^/]*$::"` # Strip another
			done
		fi
	else 
		log "WARNING: $WORKDIR is not an absolute path, can not determine fs type"
		FS_TYPE=UNKNOWN
	fi

	echo Filesystem type for $1 is $FS_TYPE
	echo $FS_TYPE > $LOG_FILE
}


# $1=host $2=ftp_cmd				
# Used by get_datfile()
function quick_ftp(){
echo -e "user $GSA_ID\n $2" | ftp -n $1
}

# $1=host $2=remote_path_file $3=local_path_file			 
function ftp_get(){
echo -e "user $ANON_ID\n bin\n get $2 $3" | ftp -n $1
}

# $1=host $2=remote_path_file			 
function ftp_del(){
echo -e "user $ANON_ID\n del $2" | ftp -n $1
}	

# $1=host $2=local_path_file $3=remote_path_file
function ftp_put(){
echo -e "user $GSA_ID\n bin\n put $2 $3" | ftp -n $1
}

# $1=host $2=local_path_file $3=remote_path
# used by results
function ftp_mput(){
echo -e "user $GSA_ID\n prompt \n bin\n cd $3 \n mput $2 " | ftp -n $1
}

# used
# $1=host $2=remote_path
# used by results
function ftp_mkdir(){
echo -e "user $GSA_ID\n mkdir $2 \n chmod 2777 $2" | ftp -n $1
}

# $1=host $2=remote_path $3=subdir1 [$4=subdir2 ...]
# used by mkresultdirs
function ftp_mkdir_recurse(){
if [ $# -lt 3 ]; then return 1; fi
cmd="user $GSA_ID"	
parentdir=$2
for subdir in ${@:3}; do
				cmd="$cmd \n cd $parentdir \n mkdir $subdir \n chmod 2777 $subdir"
				parentdir=$subdir
done
echo -e "$cmd" | ftp -n $1
}

# Used by results
function hostpath() {
echo ${1%%/*}
}

# Used by lockmeter & readprofile
function find_system_map() {
	local ARG
	for ARG in `cat /proc/cmdline`; do
		if [ `echo $ARG | tr -t A-Z a-z | cut -f1 -d=` = "sysmap" ]; then
			SYSTEM_MAP=`echo $ARG | cut -f2 -d=`
			if [ -e "$SYSTEM_MAP" ]; then
				return 0
			elif [ -e "/boot/$SYSTEM_MAP" ]; then
				SYSTEM_MAP="/boot/$SYSTEM_MAP"
				return 0
			fi
		fi
	done
	# this is an autobench kernel, and the system.map is in a known place
	if grep -q "autobench_args:" /proc/cmdline ; then
		SYSTEM_MAP=/boot/System.map-autobench
		return 0;
	fi
	if [ -e  "/boot/System.map-`uname -r`" ] ; then
		SYSTEM_MAP=/boot/System.map-`uname -r`
		return 0;
	fi
	return 1
}

# used by do_profile() (deprecated)
function get_map_name() {
echo "WARNING: this function is deprecated"
cmdline=`cat /proc/cmdline`
for name in $cmdline
do
	echo $name | grep '^sysmap=' > /dev/null
	if [ $? == 0 ]
	then
		X=`expr "$name" : '.*\(=.*\)'`	
		SYSTEM_MAP=${X:1}
		if [ -e $SYSTEM_MAP ]; then
			export SYSTEM_MAP 
		else
			if [ -e "/boot/$SYSTEM_MAP" ]; then
				SYSTEM_MAP="/boot/$SYSTEM_MAP"
				export SYSTEM_MAP
			fi
		fi
		return 1
	fi
done
return 0
}

# Used by do_profile() & start_profile() (both deprecated)
function do_profile() {
echo "WARNING: this function is deprecated"
cmdline=`cat /proc/cmdline`
export DO_PROFILE=0
for name in $cmdline
do
	echo $name | grep '^profile=2' > /dev/null
	if [ $? == 0 ]
	then
		export DO_PROFILE=1
		get_map_name
		return 
	fi
done
return 0
}


# not used - Deprecated 
function start_profile() {
echo "WARNING: this function is deprecated"
#if [ -e $AUTODIR/scripts/oprofile ]; then
#				pushd $AUTODIR/sources/oprofile/utils
#	popd
#else 
				do_profile
				if [ $? == 1 ]
				then
		if [ -e "$SYSTEM_MAP" ]; then
			cp "$SYSTEM_MAP" $LOGDIR/analysis/System.map.$RUN_NUMBER
		else
			if [ -e "/boot/$SYSTEM_MAP" ]; then
				cp "/boot/$SYSTEM_MAP" $LOGDIR/analysis/System.map.$RUN_NUMBER
			fi
		fi
					$AUTODIR/sources/readprofile/readprofile -r
				fi
				}
#fi

# $1 = raw file name (optional)
# $2 = txt file name (optional)
# not used - Deprecated 
function stop_profile() {
	echo "WARNING: this function is deprecated"
	do_profile
	if [ $? == 1 ]; then
		rawname=$1
		if [ -z $1 ]; then
			rawname=$LOGDIR/analysis/profile.raw.$RUN_NUMBERme
		fi
		txtname=$2
		if [ -z $2 ]; then
			txtname=$LOGDIR/analysis/profile.txt.$RUN_NUMBER
		fi
		cp /proc/profile $rawname
		echo 'this is deprecated, see "functions"' > $txtname
		$AUTODIR/sources/readprofile/readprofile -n -m "$SYSTEM_MAP" -p $rawname | sort -nr >> $txtname
		gzip $rawname
	fi
}

# $1 = bin file name
# $2 = interval (in seconds)
# $3 = intervals
# used by start_sar() (Deprecated)
function invoke_sar_collection () {
echo "WARNING: this function is deprecated"
		pushd $AUTODIR/sources/sysstat > /dev/null
		./sar -o $1 $2 $3 &
		popd > /dev/null
}

#function to start sar, should be called from a 'run' script only. 
# Don't forget to call stop_sar after.
# not used - Deprecated 
function start_sar () {
echo "WARNING: this function is deprecated"
interval=5
numintervals=100000
if [ -e $AUTODIR/scripts/sarinterval ]; then
		read interval < $AUTODIR/scripts/sarinterval
fi
#start sar
if [ $interval != 0 ]; then 
		invoke_sar_collection "$LOGDIR/analysis/sar.bin.$RUN_NUMBER" $interval $numintervals
fi
}

# $1 = bin file name
# $2 = txt file name
# used by stop_sar() (Deprecated)
function invoke_sar_formatting () {
echo "WARNING: this function is deprecated"
		pushd $AUTODIR/sources/sysstat > /dev/null
		./sar -A -f $1 > $2
		popd > /dev/null
}

# not used - Deprecated 
function stop_sar() {
echo "WARNING: this function is deprecated"
#kill off sar, this will kill sar and sadc subprocess
killall sar sadc; 
#postprocess sar info. if it was collected.
if [ -e $LOGDIR/analysis/sar.bin.$RUN_NUMBER ]; then
		invoke_sar_formatting "$LOGDIR/analysis/sar.bin.$RUN_NUMBER" "$LOGDIR/analysis/sar.text.$RUN_NUMBER"
fi
}

#function to start collecting schedstat , called from a run only. 
# not used - Deprecated 
function start_schedstat () {
echo "WARNING: this function is deprecated"
if [ -e $AUTODIR/scripts/schedstatinterval ]
then
	read interval < $AUTODIR/scripts/schedstatinterval
else
	interval=30
fi
#start schedstat
if [ $interval != 0 ]
then 
	schedstat $interval &
fi
}

# not used - Deprecated 
function stop_schedstat() {
echo "WARNING: this function is deprecated"
#kill off schedstat
killall schedstat
}

#function to start lockmeter, should be called from a 'run' script only. 
# Don't forget to call stop_lockmeter after.
# not used - Deprecated 
function start_lockmeter () {
echo "WARNING: this function is deprecated"
if [ -f /proc/lockmeter ]; then
	lockstat on
fi
}

# not used - Deprecated 
function stop_lockmeter() {
echo "WARNING: this function is deprecated"
if [ -f /proc/lockmeter ]; then
	lockstat off
	lockstat -m $SYSTEM.MAP print > $LOGDIR/analysis/lockstat.$RUN_NUMBER
fi
}

# used by expand_line()
function expand_parm() {
ep_parm=$1
while read ep_alias ep_subst
do
				ep_begparm="^"
				echo $ep_alias | grep '^\$' > /dev/null
	if [ $? == 0 ]; then
								ep_begparm=
				fi
	echo $ep_parm | grep "$ep_begparm$ep_alias" > /dev/null
	if [ $? == 0 ]; then
								ep_parm=${ep_parm/$ep_alias/$ep_subst}
								if [ -n "$ep_begparm" ]; then
						#echo $ep_parm
			printf "%s" "$ep_parm"
						return
								fi
	fi
done<$AUTODIR/scripts/autobench.cfg
#echo $ep_parm
printf "%s" "$ep_parm"
}

# used by autorun
# New values used to just be added to the end of the .cfg file.	But with that,
# if you have two variables, say $blah=b & $blah_word=bw, $blah_word would get 
# changed to "b_word" instead of "bw".	This add_parm makes sure that longer
# parms are listed first, so they have a chance of being substituted first.
function add_parm() {
	new_parm=$1
	shift
	new_value="$*"
	new_len=`echo $new_parm | wc -c`

	while read parm rest; do
		cur_len=`echo $parm | wc -c`
	if [ "$new_parm" == "$parm" ]; then
			echo "$new_parm $new_value" >> $AUTODIR/scripts/autobench.cfgnew
			new_len=-1
			continue
		elif [ $new_len -gt $cur_len ]; then
			echo "$new_parm $new_value" >> $AUTODIR/scripts/autobench.cfgnew
			new_len=-1
		fi
		echo "$parm $rest" >> $AUTODIR/scripts/autobench.cfgnew
	done < $AUTODIR/scripts/autobench.cfg

	if [ $new_len -gt -1 ]; then
		# We did not insert the new parm.	Either all the existing ones are bigger
		# or there are no existing ones.	Insert it at the end.
		echo "$new_parm $new_value" >> $AUTODIR/scripts/autobench.cfgnew
	fi

	if [ -e $AUTODIR/scripts/autobench.cfgnew ]; then
	mv $AUTODIR/scripts/autobench.cfgnew $AUTODIR/scripts/autobench.cfg
	fi
}


# used by expand_command()
function expand_line() {
el_line=
for el_parm in $@
do
				modparm=`expand_parm $el_parm 2> /dev/null`
				el_line="$el_line $modparm"
done
echo $el_line
}


# used by autorun, contest, specjbb
function expand_command() {
cmdstr2=
local cmdstr=$1
while [ "$cmdstr" != "$cmdstr2" ]; do
	cmdstr2=$cmdstr
	cmdstr=`expand_line $cmdstr2`
done
echo $cmdstr
}

#Used by autorun to export ENV vars
function export_cfg() {
    if [ -e $AUTODIR/scripts/autobench.cfg ]; then
        while read ep_alias ep_subst; do
            eval export ${ep_alias:1}=\'$(expand_parm $ep_alias)\'
        done<$AUTODIR/scripts/autobench.cfg
    fi
}

#
# Exmaples:
# get_kernel dest stock 2.5.59
# get_kernel dest cvs user@host.com/var/cvs linux-2.5 [-r REV | -D DATE ]
# get_kernel dest bk http://linux.bkbits.net/linux-2.5 [-rREV]
# get_kernel dest url http://system.com/kernel.tgz
# get_kernel dest url ftp://system.com/kernel.tgz
# get_kernel dest file /full/path/on/the/local/machine/kernel.tgz
# get_kernel dest dir /full/path/to/a/kernel/directory/linux/
#
# Where dest is the directory you'd like the kernel unpacked in
# 
function get_kernel(){

	local DESTDIR=$1
	case $2 in
	
	stock)
		local LOCAL_CACHE="$AUTODIR/var/cache/kernels"
		if [ -r "$AUTODIR/var/server-repository" ]; then
			. $AUTODIR/var/server-repository
			local SERVER_CACHE="$SERVER_REPO/var/cache/kernels"
		fi
		local SOURCES="";
		# KERNEL_ORG_MIRROR comes from autobench.conf
		SOURCES="$SOURCES $KERNEL_ORG_MIRROR"
		SOURCES="$SOURCES ftp://kernel.org/pub/linux/kernel"
		
		local VER=$3
		#local MAJOR=`echo $VER | cut -f1 -d.`
		#local MINOR=`echo $VER | cut -f2 -d.`
		#local SUB=`echo $VER | cut -f3 -d.`
		#if [ "''`echo $SUB | cut -f3 -d-`" != "" ]; then
		#	SUB=`echo $SUB | cut -f1-2 -d-`
		#fi
		getcommand kernelexpand
 		local KERN_FILE=`kernelexpand -r $VER | cut -f1 -d' '`
		echo "Base kernel is: $KERN_FILE"
		local KERN_BASE=`basename $KERN_FILE`
		local PATCH_FILE=`kernelexpand -p -r $VER`
		get_with_cache $KERN_FILE
		KERN_FILE="$LOCAL_CACHE/$KERN_BASE"

		if [ "$PATCH_FILE" != "" ]; then
			get_with_cache $PATCH_FILE
			PATCH_FILE="$LOCAL_CACHE/`basename $PATCH_FILE`"
		fi
		;;
		
	cvs)
		CVS_URL=$3
		mkdir -p $DESTDIR
		pushd $DESTDIR > /dev/null
		echo fetching kernel source from cvs
		echo only displaying Makefile updates...
		# -q evidently doesn't do much for checkouts
		# grepping for Makefile is a lot less output tan the
		# whole tree
		# -z9 turns compression on, which is a real win for code
		cvs -z9 -q -d $CVS_URL checkout ${@:5} $4 | grep Makefile
		check_status "Get kernel from $3 $4 ${@:5}"
		mv $4/* $DESTDIR/
		rmdir $4
		popd > /dev/null
		;;
		
	bk)
		bk clone $3 ${@:4} $DESTDIR
		check_status "Get kernel from $3 ${@:4}"
		pushd $DESTDIR 2> /dev/null
		bk -r get
		popd 2> /dev/null
		;;
	
	url)
		pushd $TMPDIR > /dev/null
		log "getting kernel from $3"
		wget --progress=bar "$3"
		check_status "Get kernel from $3"
		popd > /dev/null
		local KERN_FILE="$TMPDIR/`basename $3`"
		local REMOVE_KERN_FILE="yes"
		;;
	
	file)
		local KERN_FILE="$3"
		;;
	
	dir)
		cp -r $3 $DESTDIR
		;;
	
	*)
		echo unknown argument: $2
	
	false
	check_status "Second arg must be one of: stock, cvs, bk, url, file, or dir"
	;;
	esac

	if [ -n "$KERN_FILE" ]; then
		# unpack the kernel
		case $KERN_FILE in
	
		*.tgz|*.gz)
			echo 'gzipped kernel image'
			local zipflag="z"
			;;
		
		*.bz2)
			echo 'bzipped kernel image'
			local zipflag="j"
			;;

		*.rpm)
			echo 'rpm kernel image'
			local zipflag="r"
			;;
			
		*)
			false
			check_status "Unknown kernel format! ($KERN_FILE) Aborting !!"
			exit 1
			;;
		esac
		
		pushd $TMPDIR > /dev/null
		# handle kernel source rpms
		if [ "$zipflag" == "r" ]; then
			local KERNDIR=$(rpm -qlp $KERN_FILE | grep "/usr/src/linux-" | head -n1 | cut -d / -f4)
			rm -rf $KERNDIR
            rpm -i $KERN_FILE --prefix=/autobench/var/tmp --nodeps --force
		else
			local KERNDIR=`tar -t${zipflag}f $KERN_FILE | head -n1`
			rm -rf $KERNDIR
			tar -x${zipflag}f $KERN_FILE
		fi
		check_status "Unpacking kernel."

		# Apply branch patch if necessary
		if [ "$PATCH_FILE" != "" ]; then
			pushd $KERNDIR > /dev/null
			
			case $PATCH_FILE in
			*bz2)
				bzip2 -cd $PATCH_FILE | patch -p1 -l -f > /dev/null
				;;
			*gz)
				gzip -cd $PATCH_FILE | patch -p1 -l -f > /dev/null
				;;
			*)
				patch -f -p1 -l -i $PATCH_FILE > /dev/null
				;;
			esac
			check_status "Applying maintainer patch."
			
			popd > /dev/null
		fi
		
		rm -rf $DESTDIR
		mv $KERNDIR $DESTDIR
		popd > /dev/null
		if [ -n "$REMOVE_KERN_FILE" ]; then
			rm -rf $KERN_FILE
		fi
	fi
}

# used by autorun

function get_datfile() {
    localqueue="$AUTODIR/var/localqueue"
    mkdir -p $localqueue
    rm -f $localqueue/processing* 2> /dev/null
    datfile=`ls -1 $localqueue | grep -v "\.$" | head -n 1`
    if [ "$datfile" ]
    then
      cp $localqueue/$datfile autobench.dat
      if [ -e autobench.dat ]; then
        mv $localqueue/$datfile $localqueue/processing:$datfile
        return 0
      fi
    fi

	ftp_host="ausgsa.austin.ibm.com"
	ftp_path="/projects/l/ltcperformance/tools/autobench/workqueues/$1"
	quick_ftp $ftp_host "prompt\n mdel $ftp_path/processing*" &> /dev/null
	r=`quick_ftp ausgsa.austin.ibm.com "ls $ftp_path"`
	r=${r##*"not understood."}
	r=${r##*"not understood"}
	datfile=`echo $r | awk '{print $9}'`

	if [ "$datfile" ]; then
		wget "ftp://$ftp_host/$ftp_path/$datfile" -O autobench.dat
		if [ -s autobench.dat ]; then
			quick_ftp $ftp_host "cd $ftp_path \n rename $datfile processing:$datfile"
			cp autobench.dat $AUTODIR/logs
			return 0
		fi
	fi

	return 1
}

function scriptmode_setup () {
local cmdstr=$1
    if [ "${cmdstr:0:10}" == "scriptmode" ]; then
        scriptmode=$((${scriptmode:=0}^1))
        if [ $scriptmode -eq 1 ]; then
            if [ "${cmdstr#*[^ ] [^ ]}" != "$cmdstr" ]; then
                scriptname=${cmdstr##* }
                if [ -e $scriptname ]; then
                    rm $scriptname
                fi
                touch $scriptname
                chmod 775 $scriptname
                tmpfiles="$tmpfiles $scriptname"
            fi
        fi
        log "processing command: $cmdstr"
        return 1
    fi
    if [ ${scriptmode:=0} -eq 1 ]; then
        echo $cmdstr >> $scriptname
        log "--> $cmdstr"
        return 1
    fi
    return 0
}

