#!/sbin/sh
#
# (c)Copyright 1997 Hewlett-Packard Co.,  All Rights Reserved.
# $Header: /ignite/cold_fusion/src/server_admin/make_medialif 10.12 1998/02/06 17:11:05 hmgr Exp $
# $Revision: 10.12 $
#

PATH=/usr/bin:/usr/contrib/bin:/opt/ignite/bin:/opt/ignite/lbin
unset LANG

#
# Function to print out usage statement to stderr.
# 
# Optional argument is a string to be printed first to stderr.
#

usage()
{
    [[ $# -eq 1 ]] && print -u2 -- $command: $1
    print -u2 "Usage: $command -f <config> [[ -f <config> ]...] | -c \"<cfg_file_clause>\""
    print -u2 "                     [-r <release>] [-l <LIF_file>] [-s <script_file> ...] [-S]"
    print -u2 "                     [-C \"<cfg_file_clause>\"] [-o 32|64] [-v] [-d <tmpdir>]"
    exit 1
}

#
# Function to print out fatal error message to stderr.
#
# Optional argument is string to be printed first to stderr.
#

fatal()
{
    [[ $# -eq 1 ]] && print -u2 -- $command: error - $1
    rm -f $scripts_tmp $isl_tmp $uxinstlf_tmp $config_tmp
    exit 2
}

#
# Main section of make_medialif
#

#
# Set constants
#

DEFAULT_LIF_FILE=/var/opt/ignite/local/uxinstlf.recovery
REQUIRED_FILES="/opt/ignite/boot/boot_lif
		/opt/ignite/data/INSTCMDS"
REQUIRED_32BIT_FILES="/opt/ignite/boot/INSTALL
		      /opt/ignite/boot/INSTALLFS"
REQUIRED_64BIT_FILES="/opt/ignite/boot/VINSTALL
		      /opt/ignite/boot/VINSTALLFS"
SCRIPT_DIRS="/opt/ignite/data/scripts
             /var/opt/ignite/scripts"
UXINSTLF_TMP=uxinstlf.tmp
CONFIG_TMP=config.tmp
SCRIPTS_TMP=scripts.tmp
ISL_TMP=isl.tmp
TMP_DIR=/var/tmp
VCLASS_MODEL_STRING="9000/800/V*"

#
# Set variables
#

command=$(basename $0)
lif_file=$DEFAULT_LIF_FILE
release=$(uname -r)
tmp_dir=$TMP_DIR
bitness=32

fflag=0
rflag=0
sflag=0
vflag=0
cflag=0
lflag=0
Sflag=0
Cflag=0
oflag=0
dflag=0

num_config_files=0

typeset script_files[1]=/opt/ignite/data/scripts/os_arch_post_l 
typeset script_files[2]=/opt/ignite/data/scripts/os_arch_post_c
num_script_files=2

# Check arguments using getopts

while getopts :l:c:f:r:s:vC:So:d: option
do
    case $option in
	f)
	    if [[ ! -r $OPTARG || ! -f $OPTARG ]]
	    then
		usage "$OPTARG not found, not readable or not regular file"
	    fi
	    (( num_config_files += 1 ))
	    config_files[$num_config_files]=$OPTARG
	    fflag=1;;
	c)
	    if [[ $cflag -eq 1 ]]
	    then
		usage "-c option allowed only once"
	    fi
	    cfg_clause="$OPTARG"
	    cflag=1;;
	l)
	    if [[ $lflag -eq 1 ]]
	    then
		usage "-l option allowed only once"
	    fi
	    lif_file=$OPTARG
	    lflag=1;;
	r)
	    if [[ $rflag -eq 1 ]]
	    then
		usage "-r option allowed only once"
	    fi
	    release=$OPTARG
	    rflag=1;;
	C)
	    if [[ $Cflag -eq 1 ]]
	    then
		usage "-C option allowed only once"
	    fi
	    Cfg_clause="$OPTARG"
	    Cflag=1;;
	s)
	    if [[ ${OPTARG} = ${OPTARG#/} ]]
	    then
		usage "$OPTARG must have absolute path name"
	    fi
	    if [[ ! -r $OPTARG || ! -f $OPTARG ]]
	    then
		usage "$OPTARG not found, not readable or not regular file"
	    fi
	    index=1
	    while [[ $index -lt $num_script_files ]]
	    do
		if [[ $OPTARG = script_files[$index] ]]
		then
		    continue 2
		fi
		(( index += 1 ))
	    done
	    (( num_script_files += 1 ))
	    script_files[$num_script_files]=$OPTARG;;
	v)
	    vflag=1;;
	S)
	    Sflag=1;;
	o)
	    if [[ $oflag -eq 1 ]]
	    then
		usage "-o option allowed only once"
	    fi
	    case $OPTARG in
		32) bitness=32;;
		64) bitness=64;;
		*) usage "-o argument $OPTARG invalid, must be either 32 or 64";;
	    esac
	    oflag=1;;
	d)
	    if [[ $dflag -eq 1 ]]
	    then
		usage "-d option allowed only once"
	    fi
	    if [[ ! -d $OPTARG ]]
	    then
		usage "$OPTARG not a directory"
	    fi
	    temp_slash=$OPTARG
	    while [[ $temp_slash = +(*//*) ]]
	    do
		 hold=$(echo $temp_slash | sed -e s?//?/?g )
		 temp_slash=$hold
	    done
	    if [[ $temp_slash != "/" ]]
	    then
	        tmp_dir_base=$(basename $temp_slash)
		if [[ $tmp_dir_base = "/" ]]
		then
	            tmp_dir_base=
		fi
	        tmp_dir_dir=$(dirname $temp_slash)
		if [[ $tmp_dir_dir = "/" ]]
		then
	            tmp_dir_dir=
		fi
	        tmp_dir=${tmp_dir_dir}/${tmp_dir_base}
		if [[ $tmp_dir = "/" ]]
		then
	            tmp_dir=
		fi
	    else
	        tmp_dir=
	    fi
	    dflag=1;;
	\?)
	    usage "unknown option -$OPTARG";;
	:)
	    usage "missing argument for -$OPTARG option";;
    esac
done

# Use -d option to determine where temporary files should go

uxinstlf_tmp=${tmp_dir}/$UXINSTLF_TMP.$$
config_tmp=${tmp_dir}/$CONFIG_TMP.$$
scripts_tmp=${tmp_dir}/$SCRIPTS_TMP.$$
isl_tmp=${tmp_dir}/$ISL_TMP.$$

# Make sure either -f or -c was used

if [[ $fflag -eq 0 && $cflag -eq 0 ]]
then
    fatal "must specify either -f or -c"
fi

# Make sure only -f or -c was used

if [[ $fflag -eq 1 && $cflag -eq 1 ]]
then
    fatal "must specify only -f or only -c"
fi

# Check that release is of the form B.[0-9][0-9].[0-9][0-9]

if [[ $release != +(B\.[0-9][0-9]\.[0-9][0-9]) ]]
then
    fatal "release $release is not of the form B.[0-9][0-9].[0-9][0-9]"
fi

# Check for presence of SYSCMDS file (based on $release)

syscmds_file=/opt/ignite/data/Rel_$release/SYSCMDS
if [[ ! -r $syscmds_file || ! -f $syscmds_file ]]
then
    fatal "$syscmds_file does not exist, is not a regular file or is not readable"
fi

# If -c was used, get list of config files from manage_index
# First check to be sure config clause exists

if [[ $cflag -eq 1 ]]
then
    manage_index -l -c "$cfg_clause" >/dev/null 2>&1
    if [[ $? -eq 1 ]]
    then
        fatal "config clause \"$cfg_clause\" not found"
    fi

    # Now get all the config file associated with that config clause

    manage_index -w -c "$cfg_clause" |
    while read config_file
    do
        if [[ ! -r $config_file || ! -f $config_file ]]
        then
	    fatal "$config_file not found, not readable or not regular file"
        fi
        (( num_config_files += 1 ))
        config_files[$num_config_files]=$config_file
    done

    if [[ $num_config_files -eq 0 ]]
    then
	fatal "manage_index failed to return config files for $cfg_clause configuration"
    fi
fi

# Determine bitness if -o option not used

if [[ $oflag -eq 0 ]]
then
    if [[ $(model) = +($VCLASS_MODEL_STRING) ]]
    then
	bitness=64
    fi
fi

# Check that all other required files are present before proceeding

if [[ $bitness = 32 ]]
then
    ALL_REQUIRED_FILES="$REQUIRED_FILES $REQUIRED_32BIT_FILES"
else
    ALL_REQUIRED_FILES="$REQUIRED_FILES $REQUIRED_64BIT_FILES"
fi

for file in $ALL_REQUIRED_FILES
do
    if [[ ! -r $file || ! -f $file ]]
    then
        fatal "$file does not exist, is not a regular file or is not readable"
    fi
done

if [[ $Cflag -eq 0 ]]
then
    if [[ $cflag -eq 1 ]]
    then
        Cfg_clause=$cfg_clause
    else
        Cfg_clause="HP-UX $release Default"
    fi
fi

# Process -S option if given.  Add in script files.

if [[ $Sflag -eq 1 ]]
then
    for dir in $SCRIPT_DIRS
    do
	for file in $dir/*
	do
	    if [[ ! -r $file || ! -f $file ]]
	    then
		fatal "$file not found, not readable or not regular file"
	    fi
	    index=1
	    while [[ $index -lt $num_script_files ]]
	    do
		if [[ $file = script_files[$index] ]]
		then
		    continue 2
		fi
		(( index += 1 ))
	    done
	    (( num_script_files += 1 ))
	    script_files[$num_script_files]=$file
	done
    done
fi

# Put leading . on all script file names in preparation for tar

script_files_list=$( index=1
                     while [[ $index -le $num_script_files ]]
                     do
                         echo .${script_files[$index]}
	                 (( index += 1 ))
                     done )

cur_dir=$(pwd)
cd /
tar -cfb - 20 $script_files_list | 
  gzip -9 -c > $scripts_tmp || fatal "gzip failure on scripts, probable insufficient disk space in $tmp_dir"
cd $cur_dir

# Determine ipl_options

lifcp -r /opt/ignite/boot/boot_lif:ISL $isl_tmp
if [[ $? -ne 0 ]]
then
    fatal "lifcp -r /opt/ignite/boot/boot_lif:ISL failed, probable insufficient disk space in $tmp_dir"
fi
ipl_options="$(iplopt $isl_tmp)"

# Create lif volume using ipl_options

lifinit $ipl_options -v45000000 -d16 -nISL10 -K2 -s4096 $uxinstlf_tmp ||
  fatal "lifinit failed"
chmod u+w $uxinstlf_tmp

# Copy the ISL file

lifcp -K2 /opt/ignite/boot/boot_lif:ISL ${uxinstlf_tmp}:ISL ||
  fatal "lifcp ISL failed, probable insufficient disk space in $tmp_dir"

# Create the AUTO file

echo "hpux (;0):INSTALL" | \
  lifcp -K2 -r -T -12289 - ${uxinstlf_tmp}:AUTO || fatal "lifcp AUTO failed, probable insufficient disk space in $tmp_dir"

# Create the INDEX file

cat << EOF | lifcp -K2 -r - ${uxinstlf_tmp}:INDEX || fatal "lifcp INDEX failed, probable insufficient disk space in $tmp_dir"
cfg "$Cfg_clause" {
    description "This selection supplies the default system configuration given to make_medialif for the $release release."
    "CONFIG"
}
EOF

# Create and copy the CONFIG file

rm -f $config_tmp
index=1
while [[ $index -le $num_config_files ]]
do
    cat ${config_files[$index]} >> $config_tmp
    (( index += 1 ))
done
lifcp -K2 -r $config_tmp ${uxinstlf_tmp}:CONFIG || fatal "lifcp CONFIG failed, probable insufficient disk space in $tmp_dir"

# Copy the HPUX file

lifcp -K2 /opt/ignite/boot/boot_lif:HPUX ${uxinstlf_tmp}:HPUX  || fatal "lifcp HPUX failed, probable insufficient disk space in $tmp_dir"

# Copy the INSTALL and INSTALLFS files

if [[ $bitness = 32 ]]
then
    lifcp -r -T-12290 -K2 /opt/ignite/boot/INSTALL \
              ${uxinstlf_tmp}:INSTALL || fatal "lifcp INSTALL failed, probable insufficient disk space in $tmp_dir"
    lifcp -r -T-12290 -K2 /opt/ignite/boot/INSTALLFS \
              ${uxinstlf_tmp}:INSTALLFS || fatal "lifcp INSTALLFS failed, probable insufficient disk space in $tmp_dir"
else
    lifcp -r -T-12290 -K2 /opt/ignite/boot/VINSTALL \
              ${uxinstlf_tmp}:VINSTALL || fatal "lifcp VINSTALL failed, probable insufficient disk space in $tmp_dir"
    lifcp -r -T-12290 -K2 /opt/ignite/boot/VINSTALLFS \
              ${uxinstlf_tmp}:VINSTALLFS || fatal "lifcp VINSTALLFS failed, probable insufficient disk space in $tmp_dir"
fi

# Copy the INSTCMDS file

lifcp -r -K2 /opt/ignite/data/INSTCMDS \
	  ${uxinstlf_tmp}:INSTCMDS || fatal "lifcp INSTCMDS failed, probable insufficient disk space in $tmp_dir"

# Copy the SYSCMDS file

lifcp -r -K2 $syscmds_file \
	  ${uxinstlf_tmp}:SYSCMDS || fatal "lifcp SYSCMDS failed, probable insufficient disk space in $tmp_dir"

# Copy the SCRIPTS file

lifcp -r -K2 $scripts_tmp \
	  ${uxinstlf_tmp}:SCRIPTS || fatal "lifcp SCRIPTS failed, probable insufficient disk space in $tmp_dir"

mv $uxinstlf_tmp $lif_file
if [[ vflag -eq 1 ]]
then
    echo "Result of make_medialif located in: $lif_file"
    echo "Release is: $release"
    echo "Configuration is: \"$Cfg_clause\"\n"
    lifls -l $lif_file
fi
rm -f $scripts_tmp $isl_tmp $config_tmp

exit 0
