#!/bin/ksh
# IBM_PROLOG_BEGIN_TAG 
# This is an automatically generated prolog. 
#  
# bos720 src/bos/usr/lib/nim/methods/chcosi.sh 1.8.1.2 
#  
# Licensed Materials - Property of IBM 
#  
# COPYRIGHT International Business Machines Corp. 2006,2011 
# All Rights Reserved 
#  
# US Government Users Restricted Rights - Use, duplication or 
# disclosure restricted by GSA ADP Schedule Contract with IBM Corp. 
#  
# IBM_PROLOG_END_TAG 
# @(#)85    1.8.1.2  src/bos/usr/lib/nim/methods/chcosi.sh, cmdnim, bos720  7/15/11  05:06:49
#
#   COMPONENT_NAME: CMDNIM
#
#   FUNCTIONS: ./usr/lib/nim/methods/chcosi.sh
#
#   ORIGINS: 27
#

NIMPATH=/usr/lpp/bos.sysmgt/nim
NIM_METHODS="${NIMPATH}/methods"
export NIMPATH NIM_METHODS
. ${NIM_METHODS}/c_sh_lib
. ${NIM_METHODS}/libcosi

# --------------------------- module globals
argtype=""
commitsw=""
devicetype=""
operation=""
ARGUMENT=""

# --------------------------------------------------------------------------- #
# NAME:         usage
#
# FUNCTION:     Print usage message
#
# PARAMETERS:   None.
#
# RETURNS:      0 - successful function execution
# --------------------------------------------------------------------------- #
function usage {

	/usr/bin/dspmsg -s ${MSG_SET} cmdnim.cat ${MSG_CHCOSI_INSTALL_USAGE} \
		'To install software:\n\
%1$s -i -s Source [-f Fileset | -b installp_bundle | -F Fixes | -B fix_bundle] [-c] [-R] [-v] COSI\n' \
		"${PROGNAME}"
	/usr/bin/dspmsg -s ${MSG_SET} cmdnim.cat ${MSG_CHCOSI_UPDATE_USAGE} \
		'To update software:\n\
%1$s -u -s Source [-f Fileset | -b installp_bundle | -F Fixes | -B fix_bundle] [-c] [-R] [-v] COSI\n' \
		"${PROGNAME}"
	/usr/bin/dspmsg -s ${MSG_SET} cmdnim.cat ${MSG_CHCOSI_REJECT_USAGE} \
		'To reject software:\n\
%1$s -j {-f Fileset | -b installp_bundle | -F Fixes | -B fix_bundle} [-R] [-v] COSI\n' \
		"${PROGNAME}"
	/usr/bin/dspmsg -s ${MSG_SET} cmdnim.cat ${MSG_CHCOSI_REMOVE_USAGE} \
		'To remove software:\n\
%1$s -r {-f Fileset | -b installp_bundle | -F Fixes | -B fix_bundle} [-R] [-v] COSI\n' \
		"${PROGNAME}"
	/usr/bin/dspmsg -s ${MSG_SET} cmdnim.cat ${MSG_CHCOSI_COMMIT_USAGE} \
		'To commit software:\n\
%1$s -c {-f Fileset | -b installp_bundle | -F Fixes | -B fix_bundle} [-R] [-v] COSI\n' \
		"${PROGNAME}"

	return 0
}

# --------------------------------------------------------------------------- #
# NAME:         ck_attr
#
# FUNCTION:     Check for valid attribute.
#
# PARAMETERS:   None.
#
# RETURNS:      0 - valid attribute
#               1 - invalid attribute
# --------------------------------------------------------------------------- #
function ck_attr {

	# Check the following global flag:
	# ARGUMENT
	# source
	# location

	ck_user || return 1

	if [[ -z $ARGUMENT ]] ||
	   [[ $(echo $ARGUMENT | wc -w) -gt 1 ]] ||
	   [[ -n $reject && -n $remove ]] ||
	   [[ -n $update && -n $install ]] ||
	   [[ -n $fix_bundle && -n $installp_bundle ]] ||
	   [[ -n $commit && (-n $reject || -n $remove) ]] ||
	   [[ -n $source && (-n $reject || -n $remove) ]] || 
	   [[ -z $source && (-n $update || -n $install) ]] ||
	   [[ -z $install && -z $update && -z $reject && -z $remove && -z $commit ]] ||
	   [[ -n $fixes && -n $installp_bundle ]] || [[ -n $fixes && -n $fix_bundle ]] ||
	   [[ -z $filesets && -z $fixes && -z $installp_bundle && -z $fix_bundle && (-n $reject || -n $remove) ]] ||
	   [[ -n $filesets && -n $fixes ]] || [[ -n $filesets && -n $installp_bundle ]] || [[ -n $filesets && -n $fix_bundle ]]; then
		usage
		return 1
	fi

	if [[ $(obj_exist "master" $ARGUMENT; echo $?) -ne 0 ]]; then
		/usr/bin/dspmsg -s ${MSG_SET} cmdnim.cat ${MSG_CMD_NOT_EXIST} \
                        '%1$s: \"%2$s\" does not exist.\n' "${PROGNAME}" "${ARGUMENT}"
		return 1
	fi

	if [[ -n $source ]]; then
                devicetype=`get_devicetype $source`
		if [[ $? -ne 0 ]]; then
			/usr/bin/dspmsg -s ${ERR_SET} cmdnim.cat ${ERR_SOURCE} \
				'0042-055 %s: \"%s\" is not a valid \"source\" for\n\tthis operation' \
				${PROGNAME} "${source}"
			echo
			return 1
		fi

                if [[ $devicetype = "cdrom" ]]; then
			source=`ck_source $source` || return 1
		fi
	fi

	# Check if fileset exists in the source before creating performing operation on COSI
	if [[ -n $filesets ]]; then
	        if [[ $devicetype = "dir" ]] || [[ $devicetype = "mnt" ]]; then
			source_location=$source
	        elif [[ $devicetype = "cdrom" ]]; then
        	        nim_mount $source
                	source_location=$access_pnt
			nim_unmount $source
		elif [[ $devicetype = "nim" ]]; then
			source_location=`get_attr_value "master" $source "location"`
        	fi

		filesets=`echo $filesets | /usr/bin/awk 'BEGIN { FS=" "; OFS="\n" } { print $0 }'`
		filesets_count=`echo $filesets | /usr/bin/wc -w | /usr/bin/awk '{print $1}'`
		filesets_tr=`echo $filesets | /usr/bin/tr ' ' '\n'`
                filesets_exist=`/usr/sbin/geninstall -Ld $source_location | /usr/bin/cut -d: -f2 | /usr/bin/grep -e "$filesets_tr" | /usr/bin/uniq`
		list_count=`echo "$filesets_exist" | /usr/bin/wc -l | /usr/bin/awk '{print $1}'`
		filesets_not_exist=`echo "$filesets_tr" | /usr/bin/grep -v -e "$filesets_exist"`

		if [[ $list_count -ne $filesets_count ]]; then
			for temp_file in $filesets_not_exist
			do
				/usr/bin/dspmsg -s ${MSG_SET} cmdnim.cat ${MSG_CMD_NOT_EXIST} \
					'%1$s: \"%2$s\" does not exist.\n' "${PROGNAME}" "$temp_file"
			done

			return 1;
		fi
	fi

        return 0
}

# --------------------------------------------------------------------------- #
# NAME:         change_cosi
#
# FUNCTION:     Perform maintenance on a common image.
#
# PARAMETERS:   None.
#
# RETURNS:      0 - successful
#               1 - unsuccessful
# --------------------------------------------------------------------------- #
function change_cosi {

	typeset -i count=0
	typeset -i rc=0
	typeset -i NAME_CHANGE=0

	if [[ $(get_attr_value "master" $ARGUMENT "alloc_count") -gt 0 ]]; then
		count=$(/usr/sbin/lsnim -t spot | /usr/bin/grep "${ARGUMENT}_X" | /usr/bin/sort | \
			/usr/bin/tail -1 | /usr/bin/awk '{print $1}' | /usr/bin/awk 'BEGIN { FS="_X" } {print $2}')
		((count=$count + 1))
		name=${ARGUMENT}_X${count}
		/usr/sbin/cpcosi -c $ARGUMENT $name 
		if [[ $? -ne 0 ]]; then
			/usr/bin/dspmsg -s ${ERR_SET} cmdnim.cat ${ERR_CANT_DEFINE_OBJ} \
				'%1$s: Unable to define %2$s object.\n' "${PROGNAME}" $name
			return 1
		fi
		NAME_CHANGE=1
	else
		name=$ARGUMENT
	fi

        # Determine the source.
        # cdrom  - Mount the cdrom, create a temporary lpp_source to create the common image.
        #          Once completed, unmount the cdrom and remove the lpp_source.
        #
        # dir    - Create the lpp_source from the directory to create the common image.
        #          Once completed, remove the lpp_source.
        #
        # mnt    - Create the lpp_source using the mounted location as a source to create the common image.
        #          Once completed, remove the lpp_source and remove the content from the lpp_source location.
        #
        # nim    - Create the common image from the NIM lpp_source object.
        #
        # remote - Mount the remote location, and create the lpp_source from the mounted location.
        #          Once completed, remove the lpp_source and remove the content from the lpp_source location.

	server=`get_attr_value "master" $ARGUMENT "server"`
	location=`get_attr_value "master" $ARGUMENT "location"`
	location=`/usr/bin/df -m $location | /usr/bin/awk '(NR==2) {print $7}'`

        if [[ $devicetype = "dir" ]]; then
                define_res "lpp_source" "${name}_$$_lpp" $server "$location/${name}_$$_lpp" $source     || return 1
		lpp_source="${name}_$$_lpp"
        elif [[ $devicetype = "mnt" ]]; then
                define_res "lpp_source" "${name}_$$_lpp" $server "$location/${name}_$$_lpp" $source "true" || return 1
		lpp_source="${name}_$$_lpp"
        elif [[ $devicetype = "cdrom" ]]; then
                define_res "lpp_source" "${name}_$$_lpp" $server "$location/${name}_$$_lpp" $source     || return 1
		lpp_source="${name}_$$_lpp"
        elif [[ $devicetype = "remote" ]]; then
                nim_mount $source
                define_res "lpp_source" "${name}_$$_lpp" $server "$location/${name}_$$_lpp" $access_pnt || return 1
		lpp_source="${name}_$$_lpp"
        elif [[ $devicetype = "nim" ]]; then
                # Use the source since it is a already a nim object
		lpp_source=$source
        fi

	# The installp_bundle is not a NIM object.
	# We will define it as a NIM object for the operation and remove it afterward.
        if [[ -n $installp_bundle ]] && [[ $(obj_exist "master" $installp_bundle; echo $?) -ne 0 ]]; then
		if [[ -s $installp_bundle ]]; then
                        cp_file $installp_bundle "${location}/${name}_$$_installp_bundle" || return 1
                        define_res "installp_bundle" "${name}_$$_installp_bundle" $server "$location/${name}_$$_installp_bundle" || return 1
                        installp_bundle="${name}_$$_installp_bundle"
                	DEFINE_INSTALLP_BUNDLE=yes
		else 
			/usr/bin/dspmsg -s ${MSG_SET} cmdnim.cat ${MSG_CMD_NOT_EXIST} \
				'%1$s: \"%2$s\" does not exist.\n' "${PROGNAME}" "${installp_bundle}"
			exit 1;
		fi
        fi

	# The fix_bundle is not a NIM object.
	# We will define it as a NIM object for the operation and remove it afterward.
        if [[ -n $fix_bundle ]] && [[ $(obj_exist "master" $fix_bundle; echo $?) -ne 0 ]]; then
		if [[ -s $fix_bundle ]]; then
                        cp_file $fix_bundle "${location}/${name}_$$_fix_bundle" || return 1
                        define_res "fix_bundle" "${name}_$$_fix_bundle" $server "$location/${name}_$$_fix_bundle" || return 1
                        fix_bundle="${name}_$$_fix_bundle"
                        DEFINE_FIX_BUNDLE=yes
		else
			/usr/bin/dspmsg -s ${MSG_SET} cmdnim.cat ${MSG_CMD_NOT_EXIST} \
				'%1$s: \"%2$s\" does not exist.\n' "${PROGNAME}" "${fix_bundle}"
			exit 1;
                fi
        fi

	if [[ -n $install ]]; then
		/usr/sbin/nim -o cust ${filesets:+-a filesets="$filesets"} ${fixes:+-a fixes="$fixes"} \
			${installp_bundle:+-a installp_bundle=$installp_bundle} ${fix_bundle:+-a fix_bundle=$fix_bundle} \
			-a installp_flags=a${requisite:+g}${commit:+c}X -a lpp_source=$lpp_source $name

		
	elif [[ -n $update ]]; then
		/usr/sbin/nim -o cust ${filesets:+-a filesets="$filesets"} ${fixes:+-a fixes="$fixes"} \
			${installp_bundle:+-a installp_bundle=$installp_bundle} ${fix_bundle:+-a fix_bundle=$fix_bundle} \
			-a installp_flags=a${requisite:+g}${commit:+c}X -a lpp_source=$lpp_source $name
	elif [[ -n $reject ]]; then
		[[ -n $fixes ]] && filesets=`get_apar_fileset $fixes`
		[[ -n $fix_bundle ]] && filesets=`get_fixbundle_fileset $fix_bundle`
		/usr/sbin/nim -o maint ${filesets:+-a filesets="$filesets"} \
			${installp_bundle:+-a installp_bundle=$installp_bundle} -a installp_flags=\"-r${requisite:+g}\" $name
	elif [[ -n $remove ]]; then
		[[ -n $fixes ]] && filesets=`get_apar_fileset $fixes`
		[[ -n $fix_bundle ]] && filesets=`get_fixbundle_fileset $fix_bundle`
		/usr/sbin/nim -o maint ${filesets:+-a filesets="$filesets"} \
			${installp_bundle:+-a installp_bundle=$installp_bundle} -a installp_flags=\"-u${requisite:+g}\" $name
	elif [[ -n $commit && -z $install && -z $update ]]; then
		[[ -n $fixes ]] && filesets=`get_apar_fileset $fixes`
		[[ -n $fix_bundle ]] && filesets=`get_fixbundle_fileset $fix_bundle`
		/usr/sbin/nim -o maint ${filesets:+-a filesets="$filesets"} \
			${installp_bundle:+-a installp_bundle=$installp_bundle} -a installp_flags=\"-c${requisite:+g}\" $name
	fi
	rc=$?

        if [[ $devicetype = "dir" ]]; then
                rm_nim_obj "${name}_$$_lpp"
		rm_file "$location/${name}_$$_lpp"
        elif [[ $devicetype = "mnt" ]]; then
                rm_nim_obj "${name}_$$_lpp"
                rm_file "$location/${name}_$$_lpp"
        elif [[ $devicetype = "cdrom" ]]; then
                rm_nim_obj "${name}_$$_lpp"
        elif [[ $devicetype = "remote" ]]; then
                nim_unmount $source
                rm_nim_obj "${name}_$$_lpp"
                rm_file "$location/${name}_$$_lpp"
        fi

	if [[ $DEFINE_INSTALLP_BUNDLE = "yes" ]]; then
		rm_nim_obj "${name}_$$_installp_bundle"
                rm_file "$location/${name}_$$_installp_bundle"
	fi
	
	if [[ $DEFINE_FIX_BUNDLE = "yes" ]]; then
		rm_nim_obj "${name}_$$_fix_bundle"
                rm_file "$location/${name}_$$_fix_bundle"
        fi      

        if [[ $rc -ne 0 ]] && [[ $NAME_CHANGE -eq 1 ]]; then
                rm_nim_obj "${name}"
        fi

	return $rc
}

# --------------------------------------------------------------------------- #
# NAME:         undo
#
# FUNCTION:     Undo files and object that were created.
#
# PARAMETERS:   None.
#
# RETURNS:      0 - file removed successfully
#               1 - unable to remove file
# --------------------------------------------------------------------------- #
function undo {

	if [[ $(obj_exist "master" "${name}_$$_lpp"; echo $?) -eq 0 ]]; then
		rm_nim_obj "${name}_$$_lpp"
	fi

	if [[ -s "$location/${name}_$$_lpp" ]]; then
		rm_file "$location/${name}_$$_lpp"
	fi

        if [[ $DEFINE_INSTALLP_BUNDLE = "yes" ]]; then
                rm_nim_obj "${name}_$$_installp_bundle"
                rm_file "$location/${name}_$$_installp_bundle"
        fi

        if [[ $DEFINE_FIX_BUNDLE = "yes" ]]; then
                rm_nim_obj "${name}_$$_fix_bundle"
                rm_file "$location/${name}_$$_fix_bundle"
        fi     

	err_signal

	return 1
}

# ---------------------------------- chcosi --------------------------------- #
#
# NAME: chcosi
#
# FUNCTION:	 /usr/sbin/chcosi command 
#
# NOTES:
#
# RETURNS: (int)
#	0	= SUCCESS
#	1	= FAILURE
#
# --------------------------------------------------------------------------- #
#
trap cleanup 0
trap 'undo' 2 11 15

# NIM initialization
nim_init

# set parameters from command line
while getopts :B:F:Rcb:f:ijrs:uv x
do
	case ${x} in
		B)	# Specify the fix bundle to process against the common image.
			fix_bundle=${OPTARG}
			;;

		F)	# Specify fixes to process against the common image.
			fixes=${OPTARG}
			;;

		R)	# Specify operation apply on requisites
			requisite=true
			;;

		c)	# Specify to commit
			commit=true
			;;

		b)	# Specify the installp bundle to process against the common image.
			installp_bundle=${OPTARG}
			;;

		f)	# Specify filesets to process against the common image.
			filesets=${OPTARG}
			;;

		i)	# Specify to install
			install=true
			;;

		j)	# Specify to reject
			reject=true
			;;

		r)	# Specify to remove
			remove=true
			;;

		s)	# Specify the source for creating the common image.
			source=${OPTARG}
			;;

		u)	# Specify to update
			update=true
			;;

		v)	# verbose mode (for debugging)
			set -x
			for i in $(typeset +f)
			do
				typeset -ft $i
			done
			;;

		\?)	# unknown option
			usage
			exit 1
			;;
	esac
done

shift $((OPTIND - 1))

ARGUMENT=$*
ck_nim_env  || exit 1
ck_attr	    || exit 1

change_cosi
rc=$?

exit $rc

# end of script