#!/bin/sh
#
# ident "@(#)utrepair.sh	1.16 04/10/21 SMI"
#
# Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
# Use is subject to license terms.
#
#
# Delete/add/replace a stanza bracketed by '# Start SUNWut' and '# End SUNWut'
#
# Usage: utrepair -{r|a} [-d dir] [-R dir] files...
# Options:
#	-r Remove Sun Ray configuration from files
#	-a Add/Replace Sun Ray configuration in files
#	-d dir Directory containing prototype files
#		(default /opt/SUNWut/lib/prototype)
#	-R dir Alternative root directory, ie the directory that is the
#		root of the filesystem that contains the target files
#

usage() {
	printf "Usage: $1 -{r|a} [-d dir] [-R dir] files...\n" 1>&2
	printf "Options:\n" 1>&2
	printf "\t-r Remove Sun Ray configuration from files\n" 1>&2
	printf "\t-a Add/Replace Sun Ray configuration in files\n" 1>&2
	printf "\t-d dir Directory containing prototype files\n" 1>&2
	printf "\t\t(default %s)\n" "`cd ${defval}; /bin/pwd`" 1>&2
	printf "\t-R dir Root of filesystem containing target files\n" 1>&2
}

#
# delblk <filename> <start block delimiter> <end block delimiter>
#
# Echo all text in <filename> except for that between <start block delimiter> and
# <end block delimiter>, inclusive.
#
delblk() {
	awk -f - $1 <<-ENDAWKBLK
		BEGIN { DOPRINT = 1; STATUS = 0 }

		/^$2$/ {
		    if ( DOPRINT == 0 )
			STATUS = 2
		    else
			DOPRINT = 0
		}

		{ if ( DOPRINT == 1 ) { print } }

		/^$3$/ {
		    if ( DOPRINT == 1 )
			STATUS = 2
		    else
			DOPRINT = 1
		}

		END {
		    if ( DOPRINT == 0 )
			exit 2
		    else
			exit STATUS
		}
	ENDAWKBLK
	if [ $? != 0 ]; then
	    printf "Error: '$1' is poorly constructed\n" 1>&2
	    return 2
	fi
	return 0
}

#
# addblk <filename> <start block delimiter> <end block delimiter>
#
# Echo text in <filename> within bracketed delimiters and with a warning comment
#
addblk() {
    if [ ! -r $1 ]; then
	printf "Error: prototype '$1' not readable\n" 1>&2
	return 2
    fi
    echo "$2"
    echo "# WARNING: Do not edit anything in this block ending with 'End SUNWut'"
    cat $1
    echo "$3"
}

#
# checks to see if the file specified in $1 is empty.
# Returns 0 if true, else 1.
isEmpty() {
    grep -v '^[ 	]*$' $1 > /dev/null 2>&1 && return 1
    return 0
}


processfile() {
    makebackup=true
    file=$1
    cleanup_list="$cleanup_list $file.$$"
    if [ ! -w $file ]; then
	if [ ! -f $file ]; then
	    printf "Warning: file '$file' does not exist.  Creating it\n" 1>&2
	    makebackup=false
	    touch $file
	    chmod 644 $file
	    chown root $file
	    chgrp sys $file
	else
	    printf "Error: file '$file' is not writable\n" 1>&2
	    return 2
	fi
    fi
    
    # Strip old SUNWut block, if any
    delblk $1 "$2" "$3" > $file.$$
    if [ $? != 0 ]; then
	return 2
    fi

    if isEmpty $file.$$; then
	# no need to backup the result file if it is empty after deleting the sunray
	# block
	makebackup=false
    fi

    if [ $aflag ]; then
	# Add new SUNWut block
	addblk $dval/`basename $1`.SUNWut.prototype "$2" "$3" >> $file.$$

	if [ $? != 0 ]; then
	    return 2
	fi
    fi
    if $makebackup ; then
	cp $file $file.bak
    fi
    if isEmpty $file.$$; then
	# remove the file if the final merged file is empty
	rm -rf $file
    else
	# cp the final merged file to preserve owner/mode
    	cp -f $file.$$ $file
    fi
}

cleanup() {
    rm -f $cleanup_list
}

# main
cleanup_list=
START="# Start SUNWut"
END="# End SUNWut"
aflag=
rflag=
defval=/etc/opt/SUNWut/basedir/lib/prototype
dval=$defval
altroot=""
while getopts ard:R: opt
do
  case $opt in
  a) aflag=1;;
  r) rflag=1;;
  d) dval="$OPTARG";;
  R) altroot="$OPTARG"/;;
  ?) usage $0
     exit 1;;
  esac
done
shift `expr $OPTIND - 1`

if [ -z "${aflag}${rflag}" ]; then
    printf "Error: either -a or -r must be specified\n" 1>&2
    usage $0
    exit 1
fi

if [ "${aflag}${rflag}" = "11" ]; then
    printf "Error: only one of -a or -r may be specified\n" 1>&2
    usage $0
    exit 1
fi

status=0

umask 022

trap cleanup 0

for file in "$@"
do
  processfile "$altroot$file" "$START" "$END"

  if [ $? != 0 ]; then
    status=2
  fi
done

exit $status
