#!/bin/ksh
#
#--------------------------------------------------------------------------
# $Header: mci,v 1.3.114.1 95/10/02 18:15:08 kcs Exp $
# $Source: /nfs/hpindgr/dcia1/KCS.cm/rcs/nfs_davis_800/bin/RCS/mci,v $
#--------------------------------------------------------------------------
#
# Filename:  mci [-b branch_name -b brach_name...] file1 <file2...>
#
# Syntax:    See syntax_display below
#
# Called by: User
#
# Reads:     $HOME/.mcsrc
#
# Description:
#	mci is a "multiple" kci tool.  This tools will perform a
#	checkin to a group of files on a group of branches.
#       For example:
#	   mci -b branch1 -b branch2 foo.1 and foo.2
#       will checkin foo.1 and foo2 to branch and branch2, IFF the
#	files are identical on all branches specified.
#
# 	Branches can either be passed in on the command line with the 
#	-b option, or they can be read out of the $HOME/.mcsrc file.
#	A -b option on the command line will override the .mcsrc file.
#
#	An array, B_ARRAY, is used to store the branch names. Indexing
#	starts at 0.
#
# Exit Conditions:
# ----------------
#    0  - The script completed successfully
#    1  - An error occurred
#
###########################################################################
# 	FUNCTIONS START HERE
###########################################################################

#---------------------------------------------------------------------------
# Function: log_template
# Purpose:
#   This function echos the template into a temporary file.  The user will
#   fill in the template using the $EDITOR and then the temporary file
#   will be passed to kci to be used for the log message during the actual
#   checkin.
#---------------------------------------------------------------------------
function log_template
{
  
  echo "Filename: $each " > $LOGMSG
  echo "BRANCH: ${B_ARRAY[*]}" >> $LOGMSG
  echo "DTS/SR #: " >> $LOGMSG
  echo "Patch Name: " >> $LOGMSG
  echo "FileList:"  >> $LOGMSG
  echo "" >> $LOGMSG
  echo "Enter_Log_message_here" >> $LOGMSG
  echo "" >> $LOGMSG
  echo "Name/Ext:" >> $LOGMSG

  $EDITOR $LOGMSG
}

#---------------------------------------------------------------------------
# Function: ci_if_ok
# Purpose:
#   This function displays the log message that was entered and then asks
#   the user if it is correct.  If the user is not satisified with the log
#   message, they may re-edit the message in which case they are put back
#   into the editor.  Once the user is happy with the log message, the 
#   file is checked in.  If the user is not happy with the log message and
#   they don't wish to re-edit it, they will just abort that check-in and
#   move on to the next file if there is one.
#---------------------------------------------------------------------------
function ci_if_ok
{
  success="n"
  while [ "$success" != "y" -a "$success" != "Y" ]
  do
    echo
    echo
    echo "HERE IS YOUR LOG MESSAGE"
    echo "================================================================="
    cat $LOGMSG
    echo "================================================================="
    echo
    echo "Is this log message correct? (y or n; q to quit) \c" > /dev/tty
    read ans < /dev/tty
    #
    case "$ans" in
    "y"|"Y") 
	# The user is happy, check it in
	LOG_ENTERED="Y"

        i=0 		#initialize the counter
	#Now check the file in on each branch
        while [ $i -lt ${BRANCH_NUM} ]
        do
	  if [ "$NFS" = "TRUE" ]; then
	    if [ "${B_ARRAY[$i]}" = "${RMT_BRANCH}" ]; then
	      # This is nfs's checkin script.  It will automatically
	      # check out a copy, so don't do it explicity.
	      #NOTE: ADD -f option to checkin.
	      #FIND VALUE OF RMT_BRANCH, verify it's in the branch
	      #list!!  Test.
	      checkin -f $LOGMSG $each
            else
	      kci -o -r${B_ARRAY[$i]} -m"`cat $LOGMSG`" $each
	      kco -r${B_ARRAY[$i]} $each > /dev/null 2>&1
	    fi
	  else
	    kci -o -r${B_ARRAY[$i]} -m"`cat $LOGMSG`" $each
	    #Keep checking out copies of the file until we get to the last
	    #branch.  We do a kco instead of a kci -u because we were having
	    #trouble with kcs writing to a directory with the permissions of
	    #755.  During a kci -u the file is "owned" by kcs, not the current
	    #user.
	    if [ $i -lt ${BRANCH_NUM}-1 ]; then
	       kco -r${B_ARRAY[$i]} $each > /dev/null 2>&1
            fi
	  fi
	  i=i+1
        done
	echo "The file $each was checked into the branches: ${B_ARRAY[*]}"
	echo

	FILE_NUM=FILE_NUM+1
	success="y"
	;;
    "n"|"N") 
        # If the user is not happy with the log message, give them
        # another opportunity to change it.
        echo "Re-edit the log message again? (y or n; n or q will quit) \c" > /dev/tty
        read ans < /dev/tty
	case "$ans" in
	   "y"|"Y") $EDITOR $LOGMSG
		    success="n"
		    ;;
           "n"|"N") success="y"
		    exiting_script
		    exit 0
		    ;;
		 *) exiting_script
		    exit 0
		    ;;
        esac
	;;
    *)  
	# Another character was entered, so exit the program
	exiting_script
	exit 0
	;;
    esac
    done
}

#
#---------------------------------------------------------------------------
# Function: syntax_display
# Purpose:
# 	This function displays the proper syntax and exits the script
#---------------------------------------------------------------------------
function syntax_display
{
    echo "syntax: mci [-b branch -b branch] ... file1 <file2> <file3> ..."
    echo "        Must give at least one branch name and filename."
    echo "        Branches can either be passed with the -b option"
    echo "        or specified in ${HOME}/.mcsrc"
    echo "        (If -b is used, the .mcsrc file is NOT read)"
}

#
#---------------------------------------------------------------------------
# Function: exiting_script
# Purpose:
# 	This function removes temp log files before exiting the script
#---------------------------------------------------------------------------
function exiting_script
{
   rm -f $LOGMSG $LOGTMP $DIFF_FILE $ERR_FILE > /dev/null 2>&1 
}
    
#########################################################################
#	GLOBAL VARIABLES                                                #
#########################################################################
USER=`id -un`
LOGMSG=/tmp/cpe.msg.$USER$$
LOGTMP=/tmp/cpe.tmp.$USER$$
DIFF_FILE=/tmp/diff.$USER$$
ERR_FILE=/tmp/err.$USER$$
EDITOR=${EDITOR:-/usr/bin/vi}
LOG_ENTERED="N"
integer FILE_NUM=1
integer BRANCH_NUM=0
integer i		#A counter used to march through the branch array

#########################################################################
#	                MAIN                                            #
#########################################################################

# Set up a trap to remove temporary files if exited abnormally
trap 'rm -f $LOGMSG $LOGTMP $ERR_FILE $DIFF_FILE' 1 2 3 15

#########################################################################
# Go sort out the parameters.
#########################################################################
while [ "$#" -gt 0 ]
do
  case ${1} in
    -b | -B)
      shift
      B_ARRAY[$BRANCH_NUM]="${1}"
      BRANCH_NUM=BRANCH_NUM+1
      ;;

    -b* | -B*)
      B_ARRAY[$BRANCH_NUM]=`expr ${1} : "-[bB]\(.*\)"`
      BRANCH_NUM=BRANCH_NUM+1
      ;;

    -*)
      echo "******** ${1} is an Illegal option ***********"
      echo
      syntax_display
      exit 1
      ;;

     *)
      # All other parameters are filenames, so just read'em in.
      TOTAL_FILES="$#"
      FILE_LIST="$*"
      break
      ;;
  esac
  shift
done

# IFF no branch names have been passed in as parameters, attempt to
# read them out of the file .mcsrc 
if [ ${BRANCH_NUM} -eq 0 ]; then
  #Source the mcsrc file to read in the branch names.  The .mcsrc
  #file contains the line BRANCHES=" " which lists out what multiple
  #branches files should be checked in on.
  if [ -f ${HOME}/.mcsrc ]; then
     . ${HOME}/.mcsrc
  fi

  #Set up an array of branch names and determine how many elements we have.
  set -A B_ARRAY `echo ${BRANCHES}`
  BRANCH_NUM=${#B_ARRAY[*]}

  #Since we read the branches out of the configuration files, ask
  #to make sure they are OK.
    if [ "${BRANCH_NUM}" -ne 0 ]; then
      echo "The following branches will be used: ${BRANCHES}"
      echo "Is this OK? (y or n) \c" > /dev/tty
      read ans < /dev/tty
      if [ "$ans" != "y" -a "$ans" != "Y" ]; then
         exit 1
    fi
  fi
fi

#Check to make sure they have listed at least one branch and one file
if [ "${BRANCH_NUM}" -eq 0 -o "${FILE_LIST}" = "" ]; then
    syntax_display
    exit 1
fi

#Get the branch name in the RMTBRANCH file for NFS purposes.
#For nfs, if $RMT_BRANCH = "The current branch being checked into"
#then use checkin instead of kci to clean up the links in the 
#checkout directory.  
RMT_BRANCH=`cat RMTBRANCH | cut -d / -f1`

#Remove the error file to begin with just to make sure we are collecting
#errors only from this run.
rm -f $ERR_FILE  > /dev/null 2>&1

#########################################################################
#Loop through all the files on all the branches and make sure the file
#is checked out in the current directory, locked on every branch, and 
#identcal for each branch. We will save up a file of errors and print
#them out if there are any.  If there are NO errors, then we launch 
#into the checkin portion of the script.
#########################################################################
for each in $FILE_LIST
do
  #Remove the diff file for this round, start fresh
  rm -f $DIFF_FILE

  # For each file do some error checking to make sure there is 
  # a copy of the file and that it is locked by the user attempting
  # to check it in.
  if [ ! -f $each ]; then
    echo "    The file $each doesn't exist in the current directory" >> $ERR_FILE
  fi

  i=0  #initialize the counter

  #Loop through each branch in the branch array and make sure the file is 
  #locked and that all files on all branches are identical.
  while [ $i -lt ${BRANCH_NUM} ]
  do
    RLOG_FILE=`klog -h -r${B_ARRAY[$i]} $each 2>/dev/null | grep locks: ` 

    #Check to make sure the klog didn't exit with an error.
    if [ $? != 0 ]; then
      echo "A kcs error occurred, please check the RMTBRANCH file and your"
      echo "KCS environment variables, bailing out!"
      exit 1
    fi

    LOCK=`echo $RLOG_FILE | grep " $USER:"`
   
    #Check to make sure the file was really locked ahead of time.
    if [ "$LOCK" = "" ]; then
      echo "    The file $each on branch ${B_ARRAY[$i]} is not locked by you" >> $ERR_FILE
    fi

    # Check to make sure the TOB files are all the same if we are checking
    # into multiple branches. Don't do this diff until i is 2 or greater.
    if [ "${i}" -gt 0 ]; then
      kcsdiff -r${B_ARRAY[0]} -r${B_ARRAY[$i]} -z $each >> $DIFF_FILE 2> /dev/null
      #if the file exists and it's not empty we found some differences
      if [ -s $DIFF_FILE ]; then
        echo "    The $each files on the branches ${B_ARRAY[0]} and ${B_ARRAY[$i]} are NOT identical" >> $ERR_FILE
      fi
    fi
    #Increment the branch number
    i=i+1
  done #looping through branches
done #looping through all the files

# Check to see if we encountered errors.  If so print them out and exit.
if [ -s "$ERR_FILE" ]; then
   echo "NO FILES WERE CHECKED IN !!!"
   echo "The following errors were found:"
   cat $ERR_FILE
   exiting_script
   exit 1
fi

#########################################################################
# We passed all of the checks, now check in each file in each branch
#########################################################################
for each in $FILE_LIST
do
  # If a log file has already been entered, ask if they'd like to just
  # reuse the previous log, or create a brand new one.
  if [ "$LOG_ENTERED" = "Y" ]; then
      echo "Reuse previous log message for $each (y or n)? \c" > /dev/tty
      read ans < /dev/tty
      if [ "$ans" = "y" -o "$ans" = "Y" ]
      then
	  # Remove Filename: file from the logmsg file.  It's the 
	  # previous filename, so we don't want it anymore, and replace
	  # it with the new filename.
	  sed '/Filename:/d' $LOGMSG > $LOGTMP
	  echo "Filename: $each" > $LOGMSG
	  cat $LOGTMP >> $LOGMSG
	  rm -f $LOGTMP
      else
	  # Create a new log message
	  log_template
      fi
  else 
    # A log file has not been previously entered, so create one
    log_template
  fi
      
  # Call the function ci_if_ok to check if the log message is acceptable 
  # to the user and then check it in
  ci_if_ok
done

# exit the script, call function to clean up the log files and then exit
exiting_script
exit 0

