mergemaster.sh revision 64467
152400Sbillf#!/bin/sh
252400Sbillf
352400Sbillf# mergemaster
452400Sbillf
552400Sbillf# Compare files created by /usr/src/etc/Makefile (or the directory
652400Sbillf# the user specifies) with the currently installed copies.
752400Sbillf
852400Sbillf# Copyright 1998, 1999 Douglas Barton
952400Sbillf# Doug@gorean.org
1052400Sbillf
1152495Sbillf# $FreeBSD: head/usr.sbin/mergemaster/mergemaster.sh 64467 2000-08-09 20:36:15Z brian $
1252400Sbillf
1352400SbillfPATH=/bin:/usr/bin:/usr/sbin
1452400Sbillf
1552400Sbillfdisplay_usage () {
1652533Sbillf  VERSION_NUMBER=`grep "[$]FreeBSD:" $0 | cut -d ' ' -f 4`
1752400Sbillf  echo "mergemaster version ${VERSION_NUMBER}"
1852400Sbillf  echo "Usage: mergemaster [-scrvah] [-m /path] [-t /path] [-d] [-u N] [-w N]"
1952400Sbillf  echo "Options:"
2052400Sbillf  echo "  -s  Strict comparison (diff every pair of files)"
2152400Sbillf  echo "  -c  Use context diff instead of unified diff"
2252400Sbillf  echo "  -r  Re-run on a previously cleaned directory (skip temproot creation)"
2352400Sbillf  echo "  -v  Be more verbose about the process, include additional checks"
2452400Sbillf  echo "  -a  Leave all files that differ to merge by hand"
2552400Sbillf  echo "  -h  Display more complete help"
2652400Sbillf  echo "  -m /path/directory  Specify location of source to do the make in"
2752400Sbillf  echo "  -t /path/directory  Specify temp root directory"
2852400Sbillf  echo "  -d  Add date and time to directory name (e.g., /var/tmp/temproot.`date +%m%d.%H.%M`)"
2952400Sbillf  echo "  -u N  Specify a numeric umask"
3052400Sbillf  echo "  -w N  Specify a screen width in columns to sdiff"
3152400Sbillf  echo ''
3252400Sbillf}
3352400Sbillf
3452400Sbillfdisplay_help () {
3552400Sbillf  echo "* To create a temporary root environment, compare CVS revision \$Ids"
3652400Sbillf  echo "  for files that have them, and compare diffs for files that do not,"
3752400Sbillf  echo "  or have different ones, just type, mergemaster"
3852400Sbillf  echo "* To specify a directory other than /var/tmp/temproot for the"
3952400Sbillf  echo "  temporary root environment, use -t /path/to/temp/root"
4052400Sbillf  echo "* The -w option takes a number as an argument for the column width"
4152400Sbillf  echo "  of the screen. The default is 80."
4252400Sbillf  echo "* The -a option causes mergemaster to run without prompting"
4352400Sbillf}
4452400Sbillf
4558910Salfred
4658910Salfred# Loop allowing the user to use sdiff to merge files and display the merged
4758910Salfred# file.
4858910Salfredmerge_loop () {
4958910Salfred	case "${VERBOSE}" in
5058910Salfred   	'') ;;
5158910Salfred	*)
5258910Salfred        echo "   *** Type h at the sdiff prompt (%) to get usage help"
5358910Salfred		;;
5458910Salfred	esac
5558910Salfred	echo ''
5658910Salfred	MERGE_AGAIN=yes
5758910Salfred	while [ "${MERGE_AGAIN}" = "yes" ]; do
5858910Salfred		# Prime file.merged so we don't blat the owner/group id's
5958910Salfred		cp -p "${COMPFILE}" "${COMPFILE}.merged"
6058910Salfred		sdiff -o "${COMPFILE}.merged" --text --suppress-common-lines \
6158910Salfred			--width=${SCREEN_WIDTH:-80} "${COMPFILE#.}" "${COMPFILE}"
6258910Salfred		INSTALL_MERGED=V
6358910Salfred		while [ "${INSTALL_MERGED}" = "v" -o "${INSTALL_MERGED}" = "V" ]; do
6458910Salfred			echo ''
6558910Salfred			echo "  Use 'i' to install merged file"
6658910Salfred			echo "  Use 'r' to re-do the merge"
6758910Salfred			echo "  Use 'v' to view the merged file"
6858910Salfred			echo "  Default is to leave the temporary file to deal with by hand"
6958910Salfred			echo ''
7058910Salfred			read -p "    *** How should I deal with the merged file? [Leave it for later] " INSTALL_MERGED
7158910Salfred
7258910Salfred			case "${INSTALL_MERGED}" in
7358910Salfred			[iI])
7458910Salfred				mv "${COMPFILE}.merged" "${COMPFILE}"
7558910Salfred				echo ''
7658910Salfred				if mm_install "${COMPFILE}"; then
7758910Salfred					echo "     *** Merged version of ${COMPFILE} installed successfully"
7858910Salfred				else 
7958910Salfred					echo "     *** Problem installing ${COMPFILE}, it will remain to merge by hand later"
8058910Salfred				fi 
8158910Salfred				unset MERGE_AGAIN
8258910Salfred				;;
8358910Salfred			[rR])
8458910Salfred				rm "${COMPFILE}.merged"
8558910Salfred				;; 
8658910Salfred			[vV])
8758910Salfred				${PAGER} "${COMPFILE}.merged"
8858910Salfred				;;
8958910Salfred			'')
9058910Salfred				echo "   *** ${COMPFILE} will remain for your consideration"
9158910Salfred				unset MERGE_AGAIN
9258910Salfred				;;
9358910Salfred			*)
9458910Salfred				echo "invalid choice: ${INSTALL_MERGED}"
9558910Salfred				INSTALL_MERGED=V
9658910Salfred				;;
9758910Salfred			esac
9858910Salfred		done
9958910Salfred	done
10058910Salfred}
10158910Salfred
10258910Salfred# Loop showing user differences between files, allow merge, skip or install
10358910Salfred# options
10458910Salfreddiff_loop () {
10558910Salfred
10658910Salfred	HANDLE_COMPFILE=v
10758910Salfred
10858910Salfred	while [ "${HANDLE_COMPFILE}" = "v" -o "${HANDLE_COMPFILE}" = "V" -o "${HANDLE_COMPFILE}" = "NOT V" ]; do
10958910Salfred		if [ -f "${COMPFILE#.}" -a -f "${COMPFILE}" ]; then
11058910Salfred			if [ "${HANDLE_COMPFILE}" = "v" -o "${HANDLE_COMPFILE}" = "V" ]; then
11158910Salfred				(
11258910Salfred					echo "  *** Displaying differences between ${COMPFILE} and installed version:"
11358910Salfred					echo ''
11458910Salfred				diff "${DIFF_FLAG}" "${COMPFILE#.}" "${COMPFILE}"
11558910Salfred				) | ${PAGER}
11658910Salfred				echo ''
11758910Salfred			fi
11858910Salfred		else
11958910Salfred			echo "  *** There is no installed version of ${COMPFILE}"
12058910Salfred			NO_INSTALLED=yes
12158910Salfred		fi
12258910Salfred	
12358910Salfred		echo "  Use 'd' to delete the temporary ${COMPFILE}"
12458910Salfred		echo "  Use 'i' to install the temporary ${COMPFILE}"
12558910Salfred		case "${NO_INSTALLED}" in
12658910Salfred		'')
12758910Salfred			echo "  Use 'm' to merge the old and new versions"
12858910Salfred			echo "  Use 'v' to view to differences between the old and new versions again"
12958910Salfred			;;
13058910Salfred		esac
13158910Salfred		echo ''
13258910Salfred		echo "  Default is to leave the temporary file to deal with by hand"
13358910Salfred		echo ''
13458910Salfred		read -p "How should I deal with this? [Leave it for later] " HANDLE_COMPFILE
13558910Salfred		case "${HANDLE_COMPFILE}" in
13658910Salfred		[dD])
13758910Salfred			rm "${COMPFILE}"
13858910Salfred			echo ''
13958910Salfred			echo "   *** Deleting ${COMPFILE}"
14058910Salfred			;;
14158910Salfred		[iI])
14258910Salfred			echo ''
14358910Salfred			if mm_install "${COMPFILE}"; then
14458910Salfred				echo "   *** ${COMPFILE} installed successfully"
14558910Salfred			else
14658910Salfred				echo "   *** Problem installing ${COMPFILE}, it will remain to merge by hand"
14758910Salfred			fi
14858910Salfred			;;
14958910Salfred		[mM])
15058910Salfred			case "${NO_INSTALLED}" in
15158910Salfred			'')
15258910Salfred				# interact with user to merge files
15358910Salfred				merge_loop
15458910Salfred				;;
15558910Salfred			*)
15658910Salfred				echo ''
15758910Salfred				echo "   *** There is no installed version of ${COMPFILE}"
15858910Salfred				echo ''
15958910Salfred				HANDLE_COMPFILE="NOT V"
16058910Salfred				;;
16158910Salfred			esac # End of "No installed version of file but user selected merge" test
16258910Salfred			;;
16358910Salfred		[vV])
16458910Salfred			continue
16558910Salfred			;;
16658910Salfred		'')
16758910Salfred			echo ''
16858910Salfred			echo "   *** ${COMPFILE} will remain for your consideration"
16958910Salfred			;;
17058910Salfred		*)
17158910Salfred			# invalid choice, show menu again.
17258910Salfred			echo "invalid choice: ${HANDLE_COMPFILE}"
17358910Salfred			echo ''
17458910Salfred			HANDLE_COMPFILE="NOT V"
17558910Salfred			continue
17658910Salfred			;;
17758910Salfred		esac  # End of "How to handle files that are different"
17858910Salfred	done	
17958910Salfred	echo ''
18058910Salfred	unset NO_INSTALLED
18158910Salfred	echo ''
18258910Salfred	case "${VERBOSE}" in
18358910Salfred	'') ;;
18458910Salfred	*)
18558910Salfred		sleep 3
18658910Salfred		;;
18758910Salfred	esac
18858910Salfred}
18958910Salfred
19052400Sbillf# Set the default path for the temporary root environment
19152400Sbillf#
19252400SbillfTEMPROOT='/var/tmp/temproot'
19352400Sbillf
19452400Sbillf# Read .mergemasterrc before command line so CLI can override
19552400Sbillf#
19652400Sbillfif [ -f "$HOME/.mergemasterrc" ]; then
19752400Sbillf  . "$HOME/.mergemasterrc"
19852400Sbillffi
19952400Sbillf
20052400Sbillf# Check the command line options
20152400Sbillf#
20252400Sbillfwhile getopts ":ascrvhm:t:du:w:" COMMAND_LINE_ARGUMENT ; do
20352400Sbillf  case "${COMMAND_LINE_ARGUMENT}" in
20452400Sbillf  s)
20552400Sbillf    STRICT=yes
20652400Sbillf    ;;
20752400Sbillf  c)
20852400Sbillf    DIFF_FLAG='-c'
20952400Sbillf    ;;
21052400Sbillf  r)
21152400Sbillf    RERUN=yes
21252400Sbillf    ;;
21352400Sbillf  v)
21452400Sbillf    case "${AUTO_RUN}" in
21552400Sbillf    '') VERBOSE=yes ;;
21652400Sbillf    esac
21752400Sbillf    ;;
21852400Sbillf  a)
21952400Sbillf    AUTO_RUN=yes
22052400Sbillf    unset VERBOSE
22152400Sbillf    ;;
22252400Sbillf  h)
22352400Sbillf    display_usage
22452400Sbillf    display_help
22552400Sbillf    exit 0
22652400Sbillf    ;;
22752400Sbillf  m)
22852400Sbillf    SOURCEDIR=${OPTARG}
22952400Sbillf    ;;
23052400Sbillf  t)
23152400Sbillf    TEMPROOT=${OPTARG}
23252400Sbillf    ;;
23352400Sbillf  d)
23452400Sbillf    TEMPROOT=${TEMPROOT}.`date +%m%d.%H.%M`
23552400Sbillf    ;;
23652400Sbillf  u)
23752400Sbillf    NEW_UMASK=${OPTARG}
23852400Sbillf    ;;
23952400Sbillf  w)
24052400Sbillf    SCREEN_WIDTH=${OPTARG}
24152400Sbillf    ;;
24252400Sbillf  *)
24352400Sbillf    display_usage
24452400Sbillf    exit 1
24552400Sbillf    ;;
24652400Sbillf  esac
24752400Sbillfdone
24852400Sbillf
24952400Sbillfecho ''
25052400Sbillf
25152400Sbillf# If the user has a pager defined, make sure we can run it
25252400Sbillf#
25352400Sbillfcase "${DONT_CHECK_PAGER}" in
25452400Sbillf'')
25564467Sbrian  while ! type "${PAGER%% *}" >/dev/null && [ -n "${PAGER}" ]; do
25652400Sbillf    echo " *** Your PAGER environment variable specifies '${PAGER}', but"
25764467Sbrian    echo "     due to the limited PATH that I use for security reasons,"
25864467Sbrian    echo "     I cannot execute it. So, what would you like to do?"
25952400Sbillf    echo ''
26052400Sbillf    echo "  Use 'e' to exit mergemaster and fix your PAGER variable"
26164467Sbrian    if [ -x /usr/bin/less -o -x /usr/local/bin/less ]; then
26264467Sbrian    echo "  Use 'l' to set PAGER to 'less' for this run"
26352400Sbillf    fi
26452400Sbillf    echo "  Use 'm' to use plain old 'more' as your PAGER for this run"
26552400Sbillf    echo ''
26652400Sbillf    echo "  Default is to use plain old 'more' "
26752400Sbillf    echo ''
26852400Sbillf    read -p "What should I do? [Use 'more'] " FIXPAGER
26952400Sbillf    case "${FIXPAGER}" in
27058910Salfred    [eE])
27152400Sbillf       exit 0
27252400Sbillf       ;;
27358910Salfred    [lL])
27464467Sbrian       if [ -x /usr/bin/less ]; then
27564467Sbrian         PAGER=/usr/bin/less
27664467Sbrian       elif [ -x /usr/local/bin/less ]; then
27758910Salfred         PAGER=/usr/local/bin/less
27864467Sbrian       else
27964467Sbrian         echo ''
28064467Sbrian         echo " *** Fatal Error:"
28164467Sbrian         echo "     You asked to use 'less' as your pager, but I can't"
28264467Sbrian         echo "     find it in /usr/bin or /usr/local/bin"
28364467Sbrian         exit 1
28458910Salfred       fi
28552400Sbillf       ;;
28660420Sbsd    [mM]|'')
28752400Sbillf       PAGER=more
28852400Sbillf       ;;
28958910Salfred    *)
29058910Salfred       echo ''
29158910Salfred       echo "invalid choice: ${FIXPAGER}"
29252400Sbillf    esac
29352400Sbillf    echo ''
29458910Salfred  done
29552400Sbillf  ;;
29652400Sbillfesac
29752400Sbillf
29852400Sbillf# If user has a pager defined, or got assigned one above, use it.
29952400Sbillf# If not, use more.
30052400Sbillf#
30152400SbillfPAGER=${PAGER:-more}
30252400Sbillf
30352400Sbillfif [ -n "${VERBOSE}" -a ! "${PAGER}" = "more" ]; then
30452400Sbillf  echo " *** You have ${PAGER} defined as your pager so we will use that"
30552400Sbillf  echo ''
30652400Sbillf  sleep 3
30752400Sbillffi
30852400Sbillf
30952400Sbillf# Assign the diff flag once so we will not have to keep testing it
31052400Sbillf#
31152400SbillfDIFF_FLAG=${DIFF_FLAG:--u}
31252400Sbillf
31352400Sbillf# Assign the source directory
31452400Sbillf#
31552400SbillfSOURCEDIR=${SOURCEDIR:-/usr/src/etc}
31652400Sbillf
31752400Sbillfcase "${RERUN}" in
31852400Sbillf'')
31952400Sbillf  # Set up the loop to test for the existence of the
32052400Sbillf  # temp root directory.
32152400Sbillf  #
32252400Sbillf  TEST_TEMP_ROOT=yes
32352400Sbillf  while [ "${TEST_TEMP_ROOT}" = "yes" ]; do
32452400Sbillf    if [ -d "${TEMPROOT}" ]; then
32552400Sbillf      echo "*** The directory specified for the temporary root environment,"
32652400Sbillf      echo "    ${TEMPROOT}, exists. This can be a security risk if untrusted"
32752400Sbillf      echo "    users have access to the system."
32852400Sbillf      echo ''
32952400Sbillf      case "${AUTO_RUN}" in
33052400Sbillf      '')
33152400Sbillf        echo "  Use 'd' to delete the old ${TEMPROOT} and continue"
33252400Sbillf        echo "  Use 't' to select a new temporary root directory"
33352400Sbillf        echo "  Use 'e' to exit mergemaster"
33452400Sbillf        echo ''
33552400Sbillf        echo "  Default is to use ${TEMPROOT} as is"
33652400Sbillf        echo ''
33752400Sbillf        read -p "How should I deal with this? [Use the existing ${TEMPROOT}] " DELORNOT
33852400Sbillf          case "${DELORNOT}" in
33958910Salfred          [dD])
34052400Sbillf            echo ''
34152400Sbillf            echo "   *** Deleting the old ${TEMPROOT}"
34252400Sbillf            echo ''
34352400Sbillf            rm -rf "${TEMPROOT}"
34452400Sbillf            unset TEST_TEMP_ROOT
34552400Sbillf            ;;
34658910Salfred          [tT])
34752400Sbillf            echo "   *** Enter new directory name for temporary root environment"
34852400Sbillf            read TEMPROOT
34952400Sbillf            ;;
35058910Salfred          [eE])
35152400Sbillf            exit 0
35252400Sbillf            ;;
35358910Salfred          '')
35452400Sbillf            echo ''
35552400Sbillf            echo "   *** Leaving ${TEMPROOT} intact"
35652400Sbillf            echo ''
35752400Sbillf            unset TEST_TEMP_ROOT
35852400Sbillf            ;;
35958910Salfred          *)
36058910Salfred            echo ''
36158910Salfred            echo "invalid choice: ${DELORNOT}"
36258910Salfred            echo ''
36358910Salfred            ;;
36452400Sbillf          esac
36552400Sbillf          ;;
36652400Sbillf      *)
36752400Sbillf        # If this is an auto-run, try a hopefully safe alternative then re-test anyway
36852400Sbillf        TEMPROOT=/var/tmp/temproot.`date +%m%d.%H.%M.%S`
36952400Sbillf        ;;
37052400Sbillf      esac
37152400Sbillf    else
37252400Sbillf      unset TEST_TEMP_ROOT
37352400Sbillf    fi
37452400Sbillf  done
37552400Sbillf
37652400Sbillf  echo "*** Creating the temporary root environment in ${TEMPROOT}"
37752400Sbillf
37852400Sbillf  if mkdir -p "${TEMPROOT}"; then
37952400Sbillf    echo " *** ${TEMPROOT} ready for use"
38052400Sbillf  fi
38152400Sbillf
38252400Sbillf  if [ ! -d "${TEMPROOT}" ]; then
38352400Sbillf    echo ''
38452400Sbillf    echo "  *** FATAL ERROR: Cannot create ${TEMPROOT}"
38552400Sbillf    echo ''
38652400Sbillf    exit 1
38752400Sbillf  fi
38852400Sbillf
38952400Sbillf  echo " *** Creating and populating directory structure in ${TEMPROOT}"
39052400Sbillf  echo ''
39152400Sbillf
39252400Sbillf  case "${VERBOSE}" in
39352400Sbillf  '') ;;
39452400Sbillf  *)
39552400Sbillf    echo " *** Press [Enter] or [Return] key to continue"
39652400Sbillf    read ANY_KEY
39752400Sbillf    unset ANY_KEY
39852400Sbillf    ;;
39952400Sbillf  esac
40052400Sbillf
40152400Sbillf  { cd ${SOURCEDIR} &&
40252400Sbillf    make DESTDIR=${TEMPROOT} distrib-dirs &&
40357173Sbillf    make DESTDIR=${TEMPROOT} -DNO_MAKEDEV distribution;} ||
40452400Sbillf  { echo '';
40552400Sbillf    echo "  *** FATAL ERROR: Cannot 'cd' to ${SOURCEDIR} and install files to the";
40652400Sbillf    echo "      temproot environment";
40752400Sbillf    echo '';
40852400Sbillf    exit 1;}
40952400Sbillf
41052400Sbillf  # We really don't want to have to deal with these files, since
41152400Sbillf  # master.passwd is the real file that should be compared, then
41252400Sbillf  # the user should run pwd_mkdb if necessary.
41352400Sbillf  # Only do this if we are not rerun'ing, since if we are the
41452400Sbillf  # files will not be there.
41552400Sbillf  #
41652400Sbillf  rm ${TEMPROOT}/etc/spwd.db ${TEMPROOT}/etc/passwd ${TEMPROOT}/etc/pwd.db
41752400Sbillf
41852534Sbillf  # Avoid comparing the motd if the user specifies it in .mergemasterrc
41952534Sbillf  case "${IGNORE_MOTD}" in
42052534Sbillf  '') ;;
42152534Sbillf  *) rm ${TEMPROOT}/etc/motd
42252534Sbillf     ;;
42352534Sbillf  esac
42452534Sbillf
42552400Sbillf  ;; # End of the "RERUN" test
42652400Sbillfesac
42752400Sbillf
42852400Sbillf# Get ready to start comparing files
42952400Sbillf
43052400Sbillfcase "${VERBOSE}" in
43152400Sbillf'') ;;
43252400Sbillf*)
43352400Sbillf  echo ''
43452400Sbillf  echo " *** The following files exist only in the installed version"
43552400Sbillf  echo "     of /etc. In the far majority of cases these files are"
43652400Sbillf  echo "     necessary parts of the system and should not be deleted,"
43752400Sbillf  echo "     however because these files are not updated by this process"
43852400Sbillf  echo "     you might want to verify their status before rebooting your system."
43952400Sbillf  echo ''
44052400Sbillf  echo " *** Press [Enter] or [Return] key to continue"
44152400Sbillf  read ANY_KEY
44252400Sbillf  unset ANY_KEY
44352400Sbillf  diff -qr /etc ${TEMPROOT}/etc | grep "^Only in /etc" | ${PAGER}
44452400Sbillf  echo ''
44552400Sbillf  echo " *** Press [Enter] or [Return] key to continue"
44652400Sbillf  read ANY_KEY
44752400Sbillf  unset ANY_KEY
44852400Sbillf  ;;
44952400Sbillfesac
45052400Sbillf
45152400Sbillf# Check umask if not specified on the command line,
45252400Sbillf# and we are not doing an autorun
45352400Sbillf#
45452400Sbillfif [ -z "${NEW_UMASK}" -a -z "${AUTO_RUN}" ]; then
45552400Sbillf  USER_UMASK=`umask`
45652400Sbillf  case "${USER_UMASK}" in
45752400Sbillf  0022) ;;
45852400Sbillf  *)
45952400Sbillf    echo ''
46052400Sbillf    echo " *** Your umask is currently set to ${USER_UMASK}. By default, this script"
46152400Sbillf    echo "     installs all files with the same user, group and modes that"
46252400Sbillf    echo "     they are created with by ${SOURCEDIR}/Makefile, compared to"
46352400Sbillf    echo "     a umask of 022. This umask allows world read permission when"
46452400Sbillf    echo "     the file's default permissions have it."
46552400Sbillf    echo "     No world permissions can sometimes cause problems. A umask of"
46652400Sbillf    echo "     022 will restore the default behavior, but is not mandatory."
46752400Sbillf    echo "     /etc/master.passwd is a special case. Its file permissions"
46852400Sbillf    echo "     will be 600 (rw-------) if installed."
46952400Sbillf    echo ''
47052400Sbillf    read -p "What umask should I use? [${USER_UMASK}] " NEW_UMASK
47152400Sbillf    NEW_UMASK="${NEW_UMASK:-$USER_UMASK}"
47252400Sbillf    ;;
47352400Sbillf  esac
47452400Sbillf  echo ''
47552400Sbillffi
47652400Sbillf
47752400SbillfCONFIRMED_UMASK=${NEW_UMASK:-0022}
47852400Sbillf
47952400Sbillf# Warn users who have an /etc/sysconfig file
48052400Sbillf#
48152400Sbillfif [ -f /etc/sysconfig ]; then
48252400Sbillf  echo " *** There is an /etc/sysconfig file on this system. Starting with"
48352400Sbillf  echo "     FreeBSD version 2.2.2 those settings have moved from /etc/sysconfig"
48452400Sbillf  echo "     to /etc/rc.conf. If you are upgrading an older system make sure"
48552400Sbillf  echo "     that you transfer your settings by hand from sysconfig to rc.conf and"
48652400Sbillf  echo "     install the rc.conf file. If you have already made this transition,"
48752400Sbillf  echo "     you should consider renaming or deleting the /etc/sysconfig file."
48852400Sbillf  echo ''
48952400Sbillf  case "${AUTO_RUN}" in
49052400Sbillf  '')
49152400Sbillf    read -p "Continue with the merge process? [yes] " CONT_OR_NOT
49252400Sbillf    case "${CONT_OR_NOT}" in
49352400Sbillf    [nN]*)
49452400Sbillf      exit 0
49552400Sbillf      ;;
49652400Sbillf    *)
49752400Sbillf      echo "   *** Continuing"
49852400Sbillf      echo ''
49952400Sbillf      ;;
50052400Sbillf    esac
50152400Sbillf    ;;
50252400Sbillf  *) ;;
50352400Sbillf  esac
50452400Sbillffi
50552400Sbillf
50652400Sbillfecho ''
50752400Sbillfecho "*** Beginning comparison"
50852400Sbillfecho ''
50952400Sbillf
51052400Sbillfcd "${TEMPROOT}"
51152400Sbillf
51252400Sbillf# Use the umask/mode information to install the files
51352400Sbillf# Create directories as needed
51452400Sbillf#
51552400Sbillfmm_install () {
51652400Sbillf  local INSTALL_DIR
51752400Sbillf  INSTALL_DIR=${1#.}
51852400Sbillf  INSTALL_DIR=${INSTALL_DIR%/*}
51952400Sbillf  case "${INSTALL_DIR}" in
52052400Sbillf  '')
52152400Sbillf    INSTALL_DIR=/
52252400Sbillf    ;;
52352400Sbillf  esac
52452400Sbillf
52552400Sbillf  if [ -n "${INSTALL_DIR}" -a ! -d "${INSTALL_DIR}" ]; then
52652400Sbillf    DIR_MODE=`perl -e 'printf "%04o\n", (((stat("$ARGV[0]"))[2] & 07777) &~ oct("$ARGV[1]"))' "${TEMPROOT}/${INSTALL_DIR}" "${CONFIRMED_UMASK}"`
52752400Sbillf    install -d -o root -g wheel -m "${DIR_MODE}" "${INSTALL_DIR}"
52852400Sbillf  fi
52952400Sbillf
53052400Sbillf  FILE_MODE=`perl -e 'printf "%04o\n", (((stat("$ARGV[0]"))[2] & 07777) &~ oct("$ARGV[1]"))' "${1}" "${CONFIRMED_UMASK}"`
53152400Sbillf
53252400Sbillf  if [ ! -x "${1}" ]; then
53352400Sbillf    case "${1#.}" in
53452400Sbillf    /dev/MAKEDEV)
53552400Sbillf      NEED_MAKEDEV=yes
53652400Sbillf      ;;
53752400Sbillf    /etc/aliases)
53852400Sbillf      NEED_NEWALIASES=yes
53952400Sbillf      ;;
54052400Sbillf    /etc/login.conf)
54152400Sbillf      NEED_CAP_MKDB=yes
54252400Sbillf      ;;
54352400Sbillf    /etc/master.passwd)
54452400Sbillf      install -m 600 "${1}" "${INSTALL_DIR}"
54552400Sbillf      NEED_PWD_MKDB=yes
54652400Sbillf      DONT_INSTALL=yes
54752400Sbillf      ;;
54852400Sbillf    /.cshrc | /.profile)
54952400Sbillf      case "${LINK_EXPLAINED}" in
55052400Sbillf      '')
55152400Sbillf        echo "   *** Historically FreeBSD has had a hard link from"
55252400Sbillf        echo "       /.cshrc and /.profile to their namesakes in"
55352400Sbillf        echo "       /root. Please indicate your preference below"
55452400Sbillf        echo "       for bringing your installed files up to date."
55552400Sbillf        echo ''
55652400Sbillf        LINK_EXPLAINED=yes
55752400Sbillf        ;;
55852400Sbillf      esac
55952400Sbillf
56052400Sbillf      echo "   Use 'd' to delete the temporary ${COMPFILE}"
56152400Sbillf      echo "   Use 'l' to delete the existing ${COMPFILE#.} and create the link"
56252400Sbillf      echo ''
56352400Sbillf      echo "   Default is to leave the temporary file to deal with by hand"
56452400Sbillf      echo ''
56552400Sbillf      read -p "  How should I handle ${COMPFILE}? [Leave it to install later] " HANDLE_LINK
56652400Sbillf      case "${HANDLE_LINK}" in
56752400Sbillf      [dD]*)
56852400Sbillf        rm "${COMPFILE}"
56952400Sbillf        echo ''
57052400Sbillf        echo "   *** Deleting ${COMPFILE}"
57152400Sbillf        ;;
57252400Sbillf      [lL]*)
57352400Sbillf        echo ''
57452400Sbillf        if [ -e "${COMPFILE#.}" ]; then
57552400Sbillf          rm "${COMPFILE#.}"
57652400Sbillf        fi
57752400Sbillf        if ln "/root/${COMPFILE##*/}" "${COMPFILE#.}"; then
57852400Sbillf          echo "   *** Link from ${COMPFILE#.} to /root/${COMPFILE##*/} installed successfully"
57952400Sbillf          rm "${COMPFILE}"
58052400Sbillf        else
58152400Sbillf          echo "   *** Error linking ${COMPFILE#.} to /root/${COMPFILE##*/}, ${COMPFILE} will remain to install by hand"
58252400Sbillf        fi
58352400Sbillf        ;;
58452400Sbillf      *)
58552400Sbillf        echo "   *** ${COMPFILE} will remain for your consideration"
58652400Sbillf        ;;
58752400Sbillf      esac
58852400Sbillf      DONT_INSTALL=yes
58952400Sbillf      ;;
59052400Sbillf    esac
59152400Sbillf
59252400Sbillf    case "${DONT_INSTALL}" in
59352400Sbillf    '')
59452400Sbillf      install -m "${FILE_MODE}" "${1}" "${INSTALL_DIR}"
59552400Sbillf      ;;
59652400Sbillf    *)
59752400Sbillf      unset DONT_INSTALL
59852400Sbillf      ;;
59952400Sbillf    esac
60052400Sbillf
60152400Sbillf  else
60252400Sbillf    install -m "${FILE_MODE}" "${1}" "${INSTALL_DIR}"
60352400Sbillf  fi
60452400Sbillf  return $?
60552400Sbillf}
60652400Sbillf
60752400Sbillfcompare_ids () {
60852400Sbillf  case "${1}" in
60952400Sbillf "${2}")
61052400Sbillf    echo " *** Temp ${COMPFILE} and installed have the same ${IDTAG}, deleting"
61152400Sbillf    rm "${COMPFILE}"
61252400Sbillf    ;;
61352400Sbillf  esac
61452400Sbillf}
61552400Sbillf
61652400Sbillf# Using -size +0 avoids uselessly checking the empty log files created
61752400Sbillf# by ${SOURCEDIR}/Makefile and the device entries in ./dev, but does
61852400Sbillf# check the scripts in ./dev, as we'd like.
61952400Sbillf#
62052400Sbillffor COMPFILE in `find . -type f -size +0`; do
62152400Sbillf  case "${STRICT}" in
62252400Sbillf  '' | [Nn][Oo])
62352400Sbillf    # Compare CVS $Id's first so if the file hasn't been modified
62452400Sbillf    # local changes will be ignored.
62552400Sbillf    # If the files have the same $Id, delete the one in temproot so the
62652400Sbillf    # user will have less to wade through if files are left to merge by hand.
62752400Sbillf    # Take the $Id -> $FreeBSD tag change into account
62852400Sbillf    #
62952400Sbillf    FREEBSDID1=`grep "[$]FreeBSD:" ${COMPFILE#.} 2>/dev/null`
63052400Sbillf    FREEBSDID2=`grep "[$]FreeBSD:" ${COMPFILE} 2>/dev/null`
63152400Sbillf
63252400Sbillf    if [ -n "${FREEBSDID1}" -a -n "${FREEBSDID2}" ]; then
63352400Sbillf      IDTAG='$FreeBSD'
63452400Sbillf      compare_ids "${FREEBSDID1}" "${FREEBSDID2}"
63552400Sbillf    else
63652400Sbillf      CVSID1=`grep "[$]Id:" ${COMPFILE#.} 2>/dev/null`
63752400Sbillf      CVSID2=`grep "[$]Id:" ${COMPFILE} 2>/dev/null`
63852400Sbillf
63952400Sbillf      if [ -n "${CVSID1}" -a -n "${CVSID2}" ]; then
64052400Sbillf        IDTAG='$Id'
64152400Sbillf        compare_ids "${CVSID1}" "${CVSID2}"
64252400Sbillf      fi
64352400Sbillf    fi
64452400Sbillf    ;;
64552400Sbillf  esac
64652400Sbillf
64752400Sbillf  # If the file is still here either because the $Ids are different, the
64852400Sbillf  # file doesn't have an $Id, or we're using STRICT mode; look at the diff.
64952400Sbillf  #
65052400Sbillf  if [ -f "${COMPFILE}" ]; then
65152400Sbillf
65252400Sbillf    # Do an absolute diff first to see if the files are actually different.
65352400Sbillf    # If they're not different, delete the one in temproot.
65452400Sbillf    #
65552400Sbillf    if diff -q "${COMPFILE#.}" "${COMPFILE}" > /dev/null 2>&1; then
65652400Sbillf      echo " *** Temp ${COMPFILE} and installed are the same, deleting"
65752400Sbillf      rm "${COMPFILE}"
65852400Sbillf    else
65952400Sbillf      # Ok, the files are different, so show the user where they differ. Use user's
66052400Sbillf      # choice of diff methods; and user's pager if they have one. Use more if not.
66152400Sbillf      # Use unified diffs by default. Context diffs give me a headache. :)
66252400Sbillf      #
66352400Sbillf      case "${AUTO_RUN}" in
66452400Sbillf      '')
66558910Salfred        # prompt user to install/delete/merge changes
66658910Salfred        diff_loop
66752400Sbillf        ;;
66852400Sbillf      *)
66952400Sbillf        # If this is an auto run, make it official
67052400Sbillf        echo "   *** ${COMPFILE} will remain for your consideration"
67152400Sbillf        ;;
67252400Sbillf      esac # Auto run test
67352400Sbillf    fi # Yes, the files are different
67452400Sbillf  fi # Yes, the file still remains to be checked
67552400Sbillfdone # This is for the do way up there at the beginning of the comparison
67652400Sbillf
67752534Sbillfecho ''
67852400Sbillfecho "*** Comparison complete"
67952400Sbillfecho ''
68052400Sbillf
68152400SbillfTEST_FOR_FILES=`find ${TEMPROOT} -type f -size +0 2>/dev/null`
68252400Sbillfif [ -n "${TEST_FOR_FILES}" ]; then
68352400Sbillf  echo "*** Files that remain for you to merge by hand:"
68452400Sbillf  find "${TEMPROOT}" -type f -size +0
68552400Sbillffi
68652400Sbillf
68752400Sbillfcase "${AUTO_RUN}" in
68852400Sbillf'')
68952400Sbillf  echo ''
69052400Sbillf  read -p "Do you wish to delete what is left of ${TEMPROOT}? [no] " DEL_TEMPROOT
69152400Sbillf  case "${DEL_TEMPROOT}" in
69252400Sbillf  [yY]*)
69352400Sbillf    if rm -rf "${TEMPROOT}"; then
69452400Sbillf      echo " *** ${TEMPROOT} has been deleted"
69552400Sbillf    else
69652400Sbillf      echo " *** Unable to delete ${TEMPROOT}"
69752400Sbillf    fi
69852400Sbillf    ;;
69952400Sbillf  *)
70052400Sbillf    echo " *** ${TEMPROOT} will remain"
70152400Sbillf    ;;
70252400Sbillf  esac
70352400Sbillf  ;;
70452400Sbillf*) ;;
70552400Sbillfesac
70652400Sbillf
70752400Sbillfcase "${NEED_MAKEDEV}" in
70852400Sbillf'') ;;
70952400Sbillf*)
71052400Sbillf  echo ''
71152400Sbillf  echo "*** You installed a new /dev/MAKEDEV script, so make sure that you run"
71252400Sbillf  echo "    'cd /dev && /bin/sh MAKEDEV all' to rebuild your devices"
71352400Sbillf  ;;
71452400Sbillfesac
71552400Sbillf
71652400Sbillfcase "${NEED_NEWALIASES}" in
71752400Sbillf'') ;;
71852400Sbillf*)
71952400Sbillf  echo ''
72052400Sbillf  echo "*** You installed a new aliases file, so make sure that you run"
72152400Sbillf  echo "    'newaliases' to rebuild your aliases database"
72252400Sbillf  ;;
72352400Sbillfesac
72452400Sbillf
72552400Sbillfcase "${NEED_CAP_MKDB}" in
72652400Sbillf'') ;;
72752400Sbillf*)
72852400Sbillf  echo ''
72952400Sbillf  echo "*** You installed a login.conf file, so make sure that you run"
73052400Sbillf  echo "    'cap_mkdb /etc/login.conf' to rebuild your login.conf database"
73152400Sbillf  ;;
73252400Sbillfesac
73352400Sbillf
73452400Sbillfcase "${NEED_PWD_MKDB}" in
73552400Sbillf'') ;;
73652400Sbillf*)
73752400Sbillf  echo ''
73852400Sbillf  echo "*** You installed a new master.passwd file, so make sure that you run"
73952400Sbillf  echo "    'pwd_mkdb -p /etc/master.passwd' to rebuild your password files"
74052400Sbillf  ;;
74152400Sbillfesac
74252400Sbillf
74352400Sbillfecho ''
74452400Sbillf
74552400Sbillfexit 0
746