diff options
author | billf <billf@FreeBSD.org> | 1999-10-20 07:22:52 +0000 |
---|---|---|
committer | billf <billf@FreeBSD.org> | 1999-10-20 07:22:52 +0000 |
commit | 0df9ba5e6f4611db14037b14b20d287cecb6d76c (patch) | |
tree | 5735d954a833950d5931d306b9167580bd6b3917 | |
download | FreeBSD-src-0df9ba5e6f4611db14037b14b20d287cecb6d76c.zip FreeBSD-src-0df9ba5e6f4611db14037b14b20d287cecb6d76c.tar.gz |
Import mergemaster into the tree, a product of freebsdcon.
Submitted by: Doug Barton <doug@gorean.org>
-rwxr-xr-x | usr.sbin/mergemaster/mergemaster | 678 | ||||
-rw-r--r-- | usr.sbin/mergemaster/mergemaster.8 | 278 | ||||
-rwxr-xr-x | usr.sbin/mergemaster/mergemaster.sh | 678 |
3 files changed, 1634 insertions, 0 deletions
diff --git a/usr.sbin/mergemaster/mergemaster b/usr.sbin/mergemaster/mergemaster new file mode 100755 index 0000000..beb65b2 --- /dev/null +++ b/usr.sbin/mergemaster/mergemaster @@ -0,0 +1,678 @@ +#!/bin/sh + +# mergemaster + +# Compare files created by /usr/src/etc/Makefile (or the directory +# the user specifies) with the currently installed copies. + +# Copyright 1998, 1999 Douglas Barton +# Doug@gorean.org + +# $Revision: 1.36 $ +# $Date: 1999/09/10 20:56:33 $ + +PATH=/bin:/usr/bin:/usr/sbin + +display_usage () { + VERSION_NUMBER=`grep "[$]Revision:" $0 | cut -d ' ' -f 3` + echo "mergemaster version ${VERSION_NUMBER}" + echo "Usage: mergemaster [-scrvah] [-m /path] [-t /path] [-d] [-u N] [-w N]" + echo "Options:" + echo " -s Strict comparison (diff every pair of files)" + echo " -c Use context diff instead of unified diff" + echo " -r Re-run on a previously cleaned directory (skip temproot creation)" + echo " -v Be more verbose about the process, include additional checks" + echo " -a Leave all files that differ to merge by hand" + echo " -h Display more complete help" + echo " -m /path/directory Specify location of source to do the make in" + echo " -t /path/directory Specify temp root directory" + echo " -d Add date and time to directory name (e.g., /var/tmp/temproot.`date +%m%d.%H.%M`)" + echo " -u N Specify a numeric umask" + echo " -w N Specify a screen width in columns to sdiff" + echo '' +} + +display_help () { + echo "* To create a temporary root environment, compare CVS revision \$Ids" + echo " for files that have them, and compare diffs for files that do not," + echo " or have different ones, just type, mergemaster" + echo "* To specify a directory other than /var/tmp/temproot for the" + echo " temporary root environment, use -t /path/to/temp/root" + echo "* The -w option takes a number as an argument for the column width" + echo " of the screen. The default is 80." + echo "* The -a option causes mergemaster to run without prompting" +} + +# Set the default path for the temporary root environment +# +TEMPROOT='/var/tmp/temproot' + +# Read .mergemasterrc before command line so CLI can override +# +if [ -f "$HOME/.mergemasterrc" ]; then + . "$HOME/.mergemasterrc" +fi + +# Check the command line options +# +while getopts ":ascrvhm:t:du:w:" COMMAND_LINE_ARGUMENT ; do + case "${COMMAND_LINE_ARGUMENT}" in + s) + STRICT=yes + ;; + c) + DIFF_FLAG='-c' + ;; + r) + RERUN=yes + ;; + v) + case "${AUTO_RUN}" in + '') VERBOSE=yes ;; + esac + ;; + a) + AUTO_RUN=yes + unset VERBOSE + ;; + h) + display_usage + display_help + exit 0 + ;; + m) + SOURCEDIR=${OPTARG} + ;; + t) + TEMPROOT=${OPTARG} + ;; + d) + TEMPROOT=${TEMPROOT}.`date +%m%d.%H.%M` + ;; + u) + NEW_UMASK=${OPTARG} + ;; + w) + SCREEN_WIDTH=${OPTARG} + ;; + *) + display_usage + exit 1 + ;; + esac +done + +echo '' + +# If the user has a pager defined, make sure we can run it +# +case "${DONT_CHECK_PAGER}" in +'') + if [ -n "${PAGER}" -a ! -x "${PAGER}" ]; then + echo " *** Your PAGER environment variable specifies '${PAGER}', but" + echo " I cannot execute it. In general it is good practice to" + echo " specify the full path for environment variables like" + echo " PAGER and EDITOR. Meanwhile, what would you like to do?" + echo '' + echo " Use 'e' to exit mergemaster and fix your PAGER variable" + if [ -x /usr/local/bin/less ]; then + echo " Use 'l' to set PAGER to /usr/local/bin/less for this run" + fi + echo " Use 'm' to use plain old 'more' as your PAGER for this run" + echo '' + echo " Default is to use plain old 'more' " + echo '' + read -p "What should I do? [Use 'more'] " FIXPAGER + case "${FIXPAGER}" in + [eE]*) + exit 0 + ;; + [lL]*) + PAGER=/usr/local/bin/less + ;; + *) + PAGER=more + ;; + esac + echo '' + fi + ;; +esac + +# If user has a pager defined, or got assigned one above, use it. +# If not, use more. +# +PAGER=${PAGER:-more} + +if [ -n "${VERBOSE}" -a ! "${PAGER}" = "more" ]; then + echo " *** You have ${PAGER} defined as your pager so we will use that" + echo '' + sleep 3 +fi + +# Assign the diff flag once so we will not have to keep testing it +# +DIFF_FLAG=${DIFF_FLAG:--u} + +# Assign the source directory +# +SOURCEDIR=${SOURCEDIR:-/usr/src/etc} + +case "${RERUN}" in +'') + # Set up the loop to test for the existence of the + # temp root directory. + # + TEST_TEMP_ROOT=yes + while [ "${TEST_TEMP_ROOT}" = "yes" ]; do + if [ -d "${TEMPROOT}" ]; then + echo "*** The directory specified for the temporary root environment," + echo " ${TEMPROOT}, exists. This can be a security risk if untrusted" + echo " users have access to the system." + echo '' + case "${AUTO_RUN}" in + '') + echo " Use 'd' to delete the old ${TEMPROOT} and continue" + echo " Use 't' to select a new temporary root directory" + echo " Use 'e' to exit mergemaster" + echo '' + echo " Default is to use ${TEMPROOT} as is" + echo '' + read -p "How should I deal with this? [Use the existing ${TEMPROOT}] " DELORNOT + case "${DELORNOT}" in + [dD]*) + echo '' + echo " *** Deleting the old ${TEMPROOT}" + echo '' + rm -rf "${TEMPROOT}" + unset TEST_TEMP_ROOT + ;; + [tT]*) + echo " *** Enter new directory name for temporary root environment" + read TEMPROOT + ;; + [eE]*) + exit 0 + ;; + *) + echo '' + echo " *** Leaving ${TEMPROOT} intact" + echo '' + unset TEST_TEMP_ROOT + ;; + esac + ;; + *) + # If this is an auto-run, try a hopefully safe alternative then re-test anyway + TEMPROOT=/var/tmp/temproot.`date +%m%d.%H.%M.%S` + ;; + esac + else + unset TEST_TEMP_ROOT + fi + done + + echo "*** Creating the temporary root environment in ${TEMPROOT}" + + if mkdir -p "${TEMPROOT}"; then + echo " *** ${TEMPROOT} ready for use" + fi + + if [ ! -d "${TEMPROOT}" ]; then + echo '' + echo " *** FATAL ERROR: Cannot create ${TEMPROOT}" + echo '' + exit 1 + fi + + echo " *** Creating and populating directory structure in ${TEMPROOT}" + echo '' + + case "${VERBOSE}" in + '') ;; + *) + echo " *** Press [Enter] or [Return] key to continue" + read ANY_KEY + unset ANY_KEY + ;; + esac + + { cd ${SOURCEDIR} && + make DESTDIR=${TEMPROOT} distrib-dirs && + make DESTDIR=${TEMPROOT} distribution;} || + { echo ''; + echo " *** FATAL ERROR: Cannot 'cd' to ${SOURCEDIR} and install files to the"; + echo " temproot environment"; + echo ''; + exit 1;} + + # We really don't want to have to deal with these files, since + # master.passwd is the real file that should be compared, then + # the user should run pwd_mkdb if necessary. + # Only do this if we are not rerun'ing, since if we are the + # files will not be there. + # + rm ${TEMPROOT}/etc/spwd.db ${TEMPROOT}/etc/passwd ${TEMPROOT}/etc/pwd.db + + ;; # End of the "RERUN" test +esac + +# Get ready to start comparing files + +case "${VERBOSE}" in +'') ;; +*) + echo '' + echo " *** The following files exist only in the installed version" + echo " of /etc. In the far majority of cases these files are" + echo " necessary parts of the system and should not be deleted," + echo " however because these files are not updated by this process" + echo " you might want to verify their status before rebooting your system." + echo '' + echo " *** Press [Enter] or [Return] key to continue" + read ANY_KEY + unset ANY_KEY + diff -qr /etc ${TEMPROOT}/etc | grep "^Only in /etc" | ${PAGER} + echo '' + echo " *** Press [Enter] or [Return] key to continue" + read ANY_KEY + unset ANY_KEY + ;; +esac + +# Check umask if not specified on the command line, +# and we are not doing an autorun +# +if [ -z "${NEW_UMASK}" -a -z "${AUTO_RUN}" ]; then + USER_UMASK=`umask` + case "${USER_UMASK}" in + 0022) ;; + *) + echo '' + echo " *** Your umask is currently set to ${USER_UMASK}. By default, this script" + echo " installs all files with the same user, group and modes that" + echo " they are created with by ${SOURCEDIR}/Makefile, compared to" + echo " a umask of 022. This umask allows world read permission when" + echo " the file's default permissions have it." + echo " No world permissions can sometimes cause problems. A umask of" + echo " 022 will restore the default behavior, but is not mandatory." + echo " /etc/master.passwd is a special case. Its file permissions" + echo " will be 600 (rw-------) if installed." + echo '' + read -p "What umask should I use? [${USER_UMASK}] " NEW_UMASK + NEW_UMASK="${NEW_UMASK:-$USER_UMASK}" + ;; + esac + echo '' +fi + +CONFIRMED_UMASK=${NEW_UMASK:-0022} + +# Warn users who have an /etc/sysconfig file +# +if [ -f /etc/sysconfig ]; then + echo " *** There is an /etc/sysconfig file on this system. Starting with" + echo " FreeBSD version 2.2.2 those settings have moved from /etc/sysconfig" + echo " to /etc/rc.conf. If you are upgrading an older system make sure" + echo " that you transfer your settings by hand from sysconfig to rc.conf and" + echo " install the rc.conf file. If you have already made this transition," + echo " you should consider renaming or deleting the /etc/sysconfig file." + echo '' + case "${AUTO_RUN}" in + '') + read -p "Continue with the merge process? [yes] " CONT_OR_NOT + case "${CONT_OR_NOT}" in + [nN]*) + exit 0 + ;; + *) + echo " *** Continuing" + echo '' + ;; + esac + ;; + *) ;; + esac +fi + +echo '' +echo "*** Beginning comparison" +echo '' + +cd "${TEMPROOT}" + +# Use the umask/mode information to install the files +# Create directories as needed +# +mm_install () { + local INSTALL_DIR + INSTALL_DIR=${1#.} + INSTALL_DIR=${INSTALL_DIR%/*} + case "${INSTALL_DIR}" in + '') + INSTALL_DIR=/ + ;; + esac + + if [ -n "${INSTALL_DIR}" -a ! -d "${INSTALL_DIR}" ]; then + DIR_MODE=`perl -e 'printf "%04o\n", (((stat("$ARGV[0]"))[2] & 07777) &~ oct("$ARGV[1]"))' "${TEMPROOT}/${INSTALL_DIR}" "${CONFIRMED_UMASK}"` + install -d -o root -g wheel -m "${DIR_MODE}" "${INSTALL_DIR}" + fi + + FILE_MODE=`perl -e 'printf "%04o\n", (((stat("$ARGV[0]"))[2] & 07777) &~ oct("$ARGV[1]"))' "${1}" "${CONFIRMED_UMASK}"` + + if [ ! -x "${1}" ]; then + case "${1#.}" in + /dev/MAKEDEV) + NEED_MAKEDEV=yes + ;; + /etc/aliases) + NEED_NEWALIASES=yes + ;; + /etc/login.conf) + NEED_CAP_MKDB=yes + ;; + /etc/master.passwd) + install -m 600 "${1}" "${INSTALL_DIR}" + NEED_PWD_MKDB=yes + DONT_INSTALL=yes + ;; + /.cshrc | /.profile) + case "${LINK_EXPLAINED}" in + '') + echo " *** Historically FreeBSD has had a hard link from" + echo " /.cshrc and /.profile to their namesakes in" + echo " /root. Please indicate your preference below" + echo " for bringing your installed files up to date." + echo '' + LINK_EXPLAINED=yes + ;; + esac + + echo " Use 'd' to delete the temporary ${COMPFILE}" + echo " Use 'l' to delete the existing ${COMPFILE#.} and create the link" + echo '' + echo " Default is to leave the temporary file to deal with by hand" + echo '' + read -p " How should I handle ${COMPFILE}? [Leave it to install later] " HANDLE_LINK + case "${HANDLE_LINK}" in + [dD]*) + rm "${COMPFILE}" + echo '' + echo " *** Deleting ${COMPFILE}" + ;; + [lL]*) + echo '' + if [ -e "${COMPFILE#.}" ]; then + rm "${COMPFILE#.}" + fi + if ln "/root/${COMPFILE##*/}" "${COMPFILE#.}"; then + echo " *** Link from ${COMPFILE#.} to /root/${COMPFILE##*/} installed successfully" + rm "${COMPFILE}" + else + echo " *** Error linking ${COMPFILE#.} to /root/${COMPFILE##*/}, ${COMPFILE} will remain to install by hand" + fi + ;; + *) + echo " *** ${COMPFILE} will remain for your consideration" + ;; + esac + DONT_INSTALL=yes + ;; + esac + + case "${DONT_INSTALL}" in + '') + install -m "${FILE_MODE}" "${1}" "${INSTALL_DIR}" + ;; + *) + unset DONT_INSTALL + ;; + esac + + else + install -m "${FILE_MODE}" "${1}" "${INSTALL_DIR}" + fi + return $? +} + +compare_ids () { + case "${1}" in + "${2}") + echo " *** Temp ${COMPFILE} and installed have the same ${IDTAG}, deleting" + rm "${COMPFILE}" + ;; + esac +} + +# Using -size +0 avoids uselessly checking the empty log files created +# by ${SOURCEDIR}/Makefile and the device entries in ./dev, but does +# check the scripts in ./dev, as we'd like. +# +for COMPFILE in `find . -type f -size +0`; do + case "${STRICT}" in + '' | [Nn][Oo]) + # Compare CVS $Id's first so if the file hasn't been modified + # local changes will be ignored. + # If the files have the same $Id, delete the one in temproot so the + # user will have less to wade through if files are left to merge by hand. + # Take the $Id -> $FreeBSD tag change into account + # + FREEBSDID1=`grep "[$]FreeBSD:" ${COMPFILE#.} 2>/dev/null` + FREEBSDID2=`grep "[$]FreeBSD:" ${COMPFILE} 2>/dev/null` + + if [ -n "${FREEBSDID1}" -a -n "${FREEBSDID2}" ]; then + IDTAG='$FreeBSD' + compare_ids "${FREEBSDID1}" "${FREEBSDID2}" + else + CVSID1=`grep "[$]Id:" ${COMPFILE#.} 2>/dev/null` + CVSID2=`grep "[$]Id:" ${COMPFILE} 2>/dev/null` + + if [ -n "${CVSID1}" -a -n "${CVSID2}" ]; then + IDTAG='$Id' + compare_ids "${CVSID1}" "${CVSID2}" + fi + fi + ;; + esac + + # If the file is still here either because the $Ids are different, the + # file doesn't have an $Id, or we're using STRICT mode; look at the diff. + # + if [ -f "${COMPFILE}" ]; then + + # Do an absolute diff first to see if the files are actually different. + # If they're not different, delete the one in temproot. + # + if diff -q "${COMPFILE#.}" "${COMPFILE}" > /dev/null 2>&1; then + echo " *** Temp ${COMPFILE} and installed are the same, deleting" + rm "${COMPFILE}" + else + # Ok, the files are different, so show the user where they differ. Use user's + # choice of diff methods; and user's pager if they have one. Use more if not. + # Use unified diffs by default. Context diffs give me a headache. :) + # + case "${AUTO_RUN}" in + '') + echo '' + if [ -f "${COMPFILE#.}" -a -f "${COMPFILE}" ]; then + echo " *** Displaying differences between ${COMPFILE} and installed version" + echo '' + diff "${DIFF_FLAG}" "${COMPFILE#.}" "${COMPFILE}" | ${PAGER} + echo '' + else + echo " *** There is no installed version of ${COMPFILE}" + NO_INSTALLED=yes + fi + echo " Use 'd' to delete the temporary ${COMPFILE}" + echo " Use 'i' to install the temporary ${COMPFILE}" + case "${NO_INSTALLED}" in + '') + echo " Use 'm' to merge the old and new versions" + ;; + esac + echo '' + echo " Default is to leave the temporary file to deal with by hand" + echo '' + read -p "How should I deal with this? [Leave it for later] " HANDLE_COMPFILE + case "${HANDLE_COMPFILE}" in + [dD]*) + rm "${COMPFILE}" + echo '' + echo " *** Deleting ${COMPFILE}" + ;; + [iI]*) + echo '' + if mm_install "${COMPFILE}"; then + echo " *** ${COMPFILE} installed successfully" + else + echo " *** Problem installing ${COMPFILE}, it will remain to merge by hand" + fi + ;; + [mM]*) + case "${NO_INSTALLED}" in + '') + case "${VERBOSE}" in + '') ;; + *) + echo " *** Type h at the sdiff prompt (%) to get usage help" + ;; + esac + echo '' + MERGE_AGAIN=yes + while [ "${MERGE_AGAIN}" = "yes" ]; do + # Prime file.merged so we don't blat the owner/group id's + cp -p "${COMPFILE}" "${COMPFILE}.merged" + sdiff -o "${COMPFILE}.merged" --text --suppress-common-lines \ + --width=${SCREEN_WIDTH:-80} "${COMPFILE#.}" "${COMPFILE}" + + echo '' + echo " Use 'i' to install merged file" + echo " Use 'r' to re-do the merge" + echo " Default is to leave the temporary file to deal with by hand" + echo '' + read -p " *** How should I deal with the merged file? [Leave it for later] " INSTALL_MERGED + + case "${INSTALL_MERGED}" in + [iI]*) + mv "${COMPFILE}.merged" "${COMPFILE}" + echo '' + if mm_install "${COMPFILE}"; then + echo " *** Merged version of ${COMPFILE} installed successfully" + else + echo " *** Problem installing ${COMPFILE}, it will remain to merge by hand later" + fi + unset MERGE_AGAIN + ;; + [rR]*) + rm "${COMPFILE}.merged" + ;; + *) + echo " *** ${COMPFILE} will remain for your consideration" + unset MERGE_AGAIN + ;; + esac + done + ;; + *) + echo '' + echo " *** There is no installed version of ${COMPFILE}" + echo " to merge so it will remain to install by hand later" + echo '' + echo " *** Press [Enter] or [Return] key to continue" + read ANY_KEY + unset ANY_KEY + ;; + esac # End of "No installed version of file but user selected merge" test + ;; + *) + echo '' + echo " *** ${COMPFILE} will remain for your consideration" + ;; + esac # End of "How to handle files that are different" + unset NO_INSTALLED + echo '' + case "${VERBOSE}" in + '') ;; + *) + sleep 3 + ;; + esac + ;; + *) + # If this is an auto run, make it official + echo " *** ${COMPFILE} will remain for your consideration" + ;; + esac # Auto run test + fi # Yes, the files are different + fi # Yes, the file still remains to be checked +done # This is for the do way up there at the beginning of the comparison + +echo "*** Comparison complete" +echo '' + +TEST_FOR_FILES=`find ${TEMPROOT} -type f -size +0 2>/dev/null` +if [ -n "${TEST_FOR_FILES}" ]; then + echo "*** Files that remain for you to merge by hand:" + find "${TEMPROOT}" -type f -size +0 +fi + +case "${AUTO_RUN}" in +'') + echo '' + read -p "Do you wish to delete what is left of ${TEMPROOT}? [no] " DEL_TEMPROOT + case "${DEL_TEMPROOT}" in + [yY]*) + if rm -rf "${TEMPROOT}"; then + echo " *** ${TEMPROOT} has been deleted" + else + echo " *** Unable to delete ${TEMPROOT}" + fi + ;; + *) + echo " *** ${TEMPROOT} will remain" + ;; + esac + ;; +*) ;; +esac + +case "${NEED_MAKEDEV}" in +'') ;; +*) + echo '' + echo "*** You installed a new /dev/MAKEDEV script, so make sure that you run" + echo " 'cd /dev && /bin/sh MAKEDEV all' to rebuild your devices" + ;; +esac + +case "${NEED_NEWALIASES}" in +'') ;; +*) + echo '' + echo "*** You installed a new aliases file, so make sure that you run" + echo " 'newaliases' to rebuild your aliases database" + ;; +esac + +case "${NEED_CAP_MKDB}" in +'') ;; +*) + echo '' + echo "*** You installed a login.conf file, so make sure that you run" + echo " 'cap_mkdb /etc/login.conf' to rebuild your login.conf database" + ;; +esac + +case "${NEED_PWD_MKDB}" in +'') ;; +*) + echo '' + echo "*** You installed a new master.passwd file, so make sure that you run" + echo " 'pwd_mkdb -p /etc/master.passwd' to rebuild your password files" + ;; +esac + +echo '' + +exit 0 diff --git a/usr.sbin/mergemaster/mergemaster.8 b/usr.sbin/mergemaster/mergemaster.8 new file mode 100644 index 0000000..2c58e17 --- /dev/null +++ b/usr.sbin/mergemaster/mergemaster.8 @@ -0,0 +1,278 @@ +.\" Copyright (c) 1998, 1999 Douglas Barton +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Date: 1999/09/10 20:34:22 $ +.\" $Revision: 1.15 $ +.\" +.Dd September 10, 1999 +.Dt MERGEMASTER 8 +.Os FreeBSD +.Sh NAME +.Nm mergemaster +.Nd Merge configuration files, et al during an upgrade +.Sh SYNOPSIS +.Nm +.Op Fl scrvah +.Op Fl m Ar /path/to/sources +.Op Fl t Ar /path/to/temp/root +.Op Fl d +.Op Fl u Ar N +.Op Fl w Ar N +.Sh DESCRIPTION +.Nm +is a Bourne shell script which is designed to aid you +in updating the various configuration and other files +associated with FreeBSD. +It is +.Sy HIGHLY +recommended that you back up your +.Pa /etc +directory before beginning this process. +.Pp +The script uses +.Pa /usr/src/etc/Makefile +to build a temporary root environment from +.Pa / +down, populating that environment with the various +files. You can specify a different source directory +with the +.Op Fl m +command line option. +It then compares each file in that environment +to its installed counterpart. When the script finds a +change in the new file, or there is no installed +version of the new file it gives you four options to +deal with it. You can install the new file as is, +delete the new file, merge the old and new +files (as appropriate) using +.Xr sdiff 1 +or leave the file in the temporary root environment to +merge by hand later. +.Pp +By default it creates the temporary root in +.Pa /var/tmp/temproot +and compares the +.Xr cvs 1 +version $Id/$FreeBSD strings for files that have them, deleting +the temporary file if the strings match. If there is +no $Id string, or if the strings are different it +compares the files themselves. You can +also specify that the script ignore the $Id strings and +compare every file. +.Pp +.Nm +checks your umask and issues a warning for anything +other than 022. While it is not mandatory to grant +world read permissions for most configuration files, you +may run into problems without them. If you choose a +umask other than 022 and experience trouble later this +could be the cause. +.Pa /etc/master.passwd +is treated as a special case. If you choose to install +this file or a merged version of it the file permissions +are always 600 (rw-------) for security reasons. After +installing an updated version of this file you should +probably run +.Xr pwd_mkdb 8 +with the -p option to rebuild your password databases +and recreate +.Pa /etc/passwd . +.Pp +The script uses the owner and group id's +that the files are created with by +.Pa /usr/src/etc/Makefile , +and file permissions as specified by the umask. +Unified diffs are used by default to display any +differences unless you choose context diffs. +.Pp +The options are as follows: +.Bl -tag -width Fl +.It Fl s +Perform a strict comparison, diff'ing every pair of files. +.It Fl c +Use context diffs instead of unified diffs. +.It Fl r +Re-run +.Nm +on a previously cleaned directory, skipping the creation of +the temporary root environment. This option is compatible +with all other options. +.It Fl v +Be more verbose about the process. You should probably use +this option the first time you run +.Nm mergemaster . +This option also gives you a list of files that exist +only in the installed version of +.Pa /etc . +.It Fl a +Run automatically. This option will leave all the files that +differ from the installed versions in the temporary directory +to be dealt with by hand. If the +.Pa temproot +directory exists, it creates a new one in a previously +non-existent directory. This option unsets the verbose flag, +but is compatible with all other options. Setting -a makes +-w superfluous. +.It Fl h +Display usage and help information. +.It Fl m Ar /path/to/sources +Specify the path to the directory where you want to do the +.Xr make 1 . +(In other words, where your sources are, but -s was already +taken.) +.It Fl t Ar /path/to/temp/root +Create the temporary root environment in +.Pa /path/to/temp/root +instead of the default +.Pa /var/tmp/temproot . +.It Fl d +Add the date and time to the name of the temporary +root directory. If -t is specified, this option must +follow it if you want the date added too. +.It Fl u Ar N +Specify a numeric umask. The default is 022. +.It Fl w Ar N +Supply an alternate screen width to the +.Xr sdiff 1 +command in numbers of columns. The default is 80. +.El +.Sh ENVIRONMENT +The +.Nm +script uses the +.Ev PAGER +environment variable if set. Otherwise it uses +.Xr more 1 . +If +.Ev PAGER +specifies a program outside +its +limited +.Ev PATH +without specifying the full path, +.Nm +prompts you with options on how to proceed. +.Sh EXAMPLES +Typically all you will need to do is type +.Nm +at the prompt and the script will do all the work for you. +.Pp +To use context diff's and have +.Nm +explain more things as it goes along, use: +.Pp +.Dl # mergemaster -cv +.Pp +To specify that +.Nm +put the temporary root environment in +.Pa /usr/tmp/root , +use: +.Pp +.Dl # mergemaster -t /usr/tmp/root +.Pp +To specify a 110 column screen with a strict +comparison, use: +.Pp +.Dl # mergemaster -sw 110 +.Sh FILES +.Bl -tag -width $HOME/.mergemasterrc -compact +.Pa $HOME/.mergemasterrc +.Pp +.Nm +will . (source) this file if it exists. Command line options +will override rc file options. Here is an example +with all values commented out: +.Pp +.Bd -literal +# These are options for mergemaster, with their default values listed +# The following options have command line overrides +# +# Directory to install the temporary root environment into +#TEMPROOT='/var/tmp/temproot' +# +# Strict comparison bypasses the CVS $Id tests and compares every file +#STRICT=no +# +# Flag(s) to use for diff displayed when files differ +#DIFF_FLAG='-u' +# +# Verbose mode includes more details and additional checks +#VERBOSE= +# +# Sourcedir is the directory to do the 'make' in (where the new files are) +#SOURCEDIR=/usr/src/etc +# +# The umask for mergemaster to compare the default file's modes to +#NEW_UMASK=022 +# +# The following options have no command line overrides +# For those who just cannot stand including the full path to PAGER +#DONT_CHECK_PAGER= +# If you set 'yes' above, make sure to include the PATH to your pager +#PATH=/bin:/usr/bin:/usr/sbin +.Ed +.Sh SEE ALSO +.Xr cvs 1 , +.Xr diff 1 , +.Xr make 1 , +.Xr more 1 , +.Xr sdiff 1 , +.Xr pwd_mkdb 8 +.Pp +.Pa /usr/src/etc/Makefile +.Pp +http://www.freebsd.org/tutorials/, +.Pa Upgrading FreeBSD from source (using make world) , +by Nik Clayton +.Sh DIAGNOSTICS +Exit status is 0 on successful completion, or if the user bails out +manually at some point during execution. +.Pp +Exit status is 1 if it fails for one of the following reasons: +.Pp +Invalid command line option +.Pp +Failure to create the temporary root environment +.Pp +Failure to populate the temporary root +.Pp +.Sh HISTORY +The +.Nm +script was first publicly available on one of my +web pages in a much simpler form under the name +.Pa comproot +on 13 March 1998. The idea for creating the +temporary root environment comes from Nik Clayton's +make world tutorial which is referenced above. +.Pp +.Sh AUTHOR +This manual page and the script itself were written by +.An Douglas Barton Aq Doug@gorean.org . +.Sh BUGS +There are no known bugs. Please report any problems, +comments or suggestions to the author. Several of the +improvements to this program have come from user +suggestions. Thank you. diff --git a/usr.sbin/mergemaster/mergemaster.sh b/usr.sbin/mergemaster/mergemaster.sh new file mode 100755 index 0000000..beb65b2 --- /dev/null +++ b/usr.sbin/mergemaster/mergemaster.sh @@ -0,0 +1,678 @@ +#!/bin/sh + +# mergemaster + +# Compare files created by /usr/src/etc/Makefile (or the directory +# the user specifies) with the currently installed copies. + +# Copyright 1998, 1999 Douglas Barton +# Doug@gorean.org + +# $Revision: 1.36 $ +# $Date: 1999/09/10 20:56:33 $ + +PATH=/bin:/usr/bin:/usr/sbin + +display_usage () { + VERSION_NUMBER=`grep "[$]Revision:" $0 | cut -d ' ' -f 3` + echo "mergemaster version ${VERSION_NUMBER}" + echo "Usage: mergemaster [-scrvah] [-m /path] [-t /path] [-d] [-u N] [-w N]" + echo "Options:" + echo " -s Strict comparison (diff every pair of files)" + echo " -c Use context diff instead of unified diff" + echo " -r Re-run on a previously cleaned directory (skip temproot creation)" + echo " -v Be more verbose about the process, include additional checks" + echo " -a Leave all files that differ to merge by hand" + echo " -h Display more complete help" + echo " -m /path/directory Specify location of source to do the make in" + echo " -t /path/directory Specify temp root directory" + echo " -d Add date and time to directory name (e.g., /var/tmp/temproot.`date +%m%d.%H.%M`)" + echo " -u N Specify a numeric umask" + echo " -w N Specify a screen width in columns to sdiff" + echo '' +} + +display_help () { + echo "* To create a temporary root environment, compare CVS revision \$Ids" + echo " for files that have them, and compare diffs for files that do not," + echo " or have different ones, just type, mergemaster" + echo "* To specify a directory other than /var/tmp/temproot for the" + echo " temporary root environment, use -t /path/to/temp/root" + echo "* The -w option takes a number as an argument for the column width" + echo " of the screen. The default is 80." + echo "* The -a option causes mergemaster to run without prompting" +} + +# Set the default path for the temporary root environment +# +TEMPROOT='/var/tmp/temproot' + +# Read .mergemasterrc before command line so CLI can override +# +if [ -f "$HOME/.mergemasterrc" ]; then + . "$HOME/.mergemasterrc" +fi + +# Check the command line options +# +while getopts ":ascrvhm:t:du:w:" COMMAND_LINE_ARGUMENT ; do + case "${COMMAND_LINE_ARGUMENT}" in + s) + STRICT=yes + ;; + c) + DIFF_FLAG='-c' + ;; + r) + RERUN=yes + ;; + v) + case "${AUTO_RUN}" in + '') VERBOSE=yes ;; + esac + ;; + a) + AUTO_RUN=yes + unset VERBOSE + ;; + h) + display_usage + display_help + exit 0 + ;; + m) + SOURCEDIR=${OPTARG} + ;; + t) + TEMPROOT=${OPTARG} + ;; + d) + TEMPROOT=${TEMPROOT}.`date +%m%d.%H.%M` + ;; + u) + NEW_UMASK=${OPTARG} + ;; + w) + SCREEN_WIDTH=${OPTARG} + ;; + *) + display_usage + exit 1 + ;; + esac +done + +echo '' + +# If the user has a pager defined, make sure we can run it +# +case "${DONT_CHECK_PAGER}" in +'') + if [ -n "${PAGER}" -a ! -x "${PAGER}" ]; then + echo " *** Your PAGER environment variable specifies '${PAGER}', but" + echo " I cannot execute it. In general it is good practice to" + echo " specify the full path for environment variables like" + echo " PAGER and EDITOR. Meanwhile, what would you like to do?" + echo '' + echo " Use 'e' to exit mergemaster and fix your PAGER variable" + if [ -x /usr/local/bin/less ]; then + echo " Use 'l' to set PAGER to /usr/local/bin/less for this run" + fi + echo " Use 'm' to use plain old 'more' as your PAGER for this run" + echo '' + echo " Default is to use plain old 'more' " + echo '' + read -p "What should I do? [Use 'more'] " FIXPAGER + case "${FIXPAGER}" in + [eE]*) + exit 0 + ;; + [lL]*) + PAGER=/usr/local/bin/less + ;; + *) + PAGER=more + ;; + esac + echo '' + fi + ;; +esac + +# If user has a pager defined, or got assigned one above, use it. +# If not, use more. +# +PAGER=${PAGER:-more} + +if [ -n "${VERBOSE}" -a ! "${PAGER}" = "more" ]; then + echo " *** You have ${PAGER} defined as your pager so we will use that" + echo '' + sleep 3 +fi + +# Assign the diff flag once so we will not have to keep testing it +# +DIFF_FLAG=${DIFF_FLAG:--u} + +# Assign the source directory +# +SOURCEDIR=${SOURCEDIR:-/usr/src/etc} + +case "${RERUN}" in +'') + # Set up the loop to test for the existence of the + # temp root directory. + # + TEST_TEMP_ROOT=yes + while [ "${TEST_TEMP_ROOT}" = "yes" ]; do + if [ -d "${TEMPROOT}" ]; then + echo "*** The directory specified for the temporary root environment," + echo " ${TEMPROOT}, exists. This can be a security risk if untrusted" + echo " users have access to the system." + echo '' + case "${AUTO_RUN}" in + '') + echo " Use 'd' to delete the old ${TEMPROOT} and continue" + echo " Use 't' to select a new temporary root directory" + echo " Use 'e' to exit mergemaster" + echo '' + echo " Default is to use ${TEMPROOT} as is" + echo '' + read -p "How should I deal with this? [Use the existing ${TEMPROOT}] " DELORNOT + case "${DELORNOT}" in + [dD]*) + echo '' + echo " *** Deleting the old ${TEMPROOT}" + echo '' + rm -rf "${TEMPROOT}" + unset TEST_TEMP_ROOT + ;; + [tT]*) + echo " *** Enter new directory name for temporary root environment" + read TEMPROOT + ;; + [eE]*) + exit 0 + ;; + *) + echo '' + echo " *** Leaving ${TEMPROOT} intact" + echo '' + unset TEST_TEMP_ROOT + ;; + esac + ;; + *) + # If this is an auto-run, try a hopefully safe alternative then re-test anyway + TEMPROOT=/var/tmp/temproot.`date +%m%d.%H.%M.%S` + ;; + esac + else + unset TEST_TEMP_ROOT + fi + done + + echo "*** Creating the temporary root environment in ${TEMPROOT}" + + if mkdir -p "${TEMPROOT}"; then + echo " *** ${TEMPROOT} ready for use" + fi + + if [ ! -d "${TEMPROOT}" ]; then + echo '' + echo " *** FATAL ERROR: Cannot create ${TEMPROOT}" + echo '' + exit 1 + fi + + echo " *** Creating and populating directory structure in ${TEMPROOT}" + echo '' + + case "${VERBOSE}" in + '') ;; + *) + echo " *** Press [Enter] or [Return] key to continue" + read ANY_KEY + unset ANY_KEY + ;; + esac + + { cd ${SOURCEDIR} && + make DESTDIR=${TEMPROOT} distrib-dirs && + make DESTDIR=${TEMPROOT} distribution;} || + { echo ''; + echo " *** FATAL ERROR: Cannot 'cd' to ${SOURCEDIR} and install files to the"; + echo " temproot environment"; + echo ''; + exit 1;} + + # We really don't want to have to deal with these files, since + # master.passwd is the real file that should be compared, then + # the user should run pwd_mkdb if necessary. + # Only do this if we are not rerun'ing, since if we are the + # files will not be there. + # + rm ${TEMPROOT}/etc/spwd.db ${TEMPROOT}/etc/passwd ${TEMPROOT}/etc/pwd.db + + ;; # End of the "RERUN" test +esac + +# Get ready to start comparing files + +case "${VERBOSE}" in +'') ;; +*) + echo '' + echo " *** The following files exist only in the installed version" + echo " of /etc. In the far majority of cases these files are" + echo " necessary parts of the system and should not be deleted," + echo " however because these files are not updated by this process" + echo " you might want to verify their status before rebooting your system." + echo '' + echo " *** Press [Enter] or [Return] key to continue" + read ANY_KEY + unset ANY_KEY + diff -qr /etc ${TEMPROOT}/etc | grep "^Only in /etc" | ${PAGER} + echo '' + echo " *** Press [Enter] or [Return] key to continue" + read ANY_KEY + unset ANY_KEY + ;; +esac + +# Check umask if not specified on the command line, +# and we are not doing an autorun +# +if [ -z "${NEW_UMASK}" -a -z "${AUTO_RUN}" ]; then + USER_UMASK=`umask` + case "${USER_UMASK}" in + 0022) ;; + *) + echo '' + echo " *** Your umask is currently set to ${USER_UMASK}. By default, this script" + echo " installs all files with the same user, group and modes that" + echo " they are created with by ${SOURCEDIR}/Makefile, compared to" + echo " a umask of 022. This umask allows world read permission when" + echo " the file's default permissions have it." + echo " No world permissions can sometimes cause problems. A umask of" + echo " 022 will restore the default behavior, but is not mandatory." + echo " /etc/master.passwd is a special case. Its file permissions" + echo " will be 600 (rw-------) if installed." + echo '' + read -p "What umask should I use? [${USER_UMASK}] " NEW_UMASK + NEW_UMASK="${NEW_UMASK:-$USER_UMASK}" + ;; + esac + echo '' +fi + +CONFIRMED_UMASK=${NEW_UMASK:-0022} + +# Warn users who have an /etc/sysconfig file +# +if [ -f /etc/sysconfig ]; then + echo " *** There is an /etc/sysconfig file on this system. Starting with" + echo " FreeBSD version 2.2.2 those settings have moved from /etc/sysconfig" + echo " to /etc/rc.conf. If you are upgrading an older system make sure" + echo " that you transfer your settings by hand from sysconfig to rc.conf and" + echo " install the rc.conf file. If you have already made this transition," + echo " you should consider renaming or deleting the /etc/sysconfig file." + echo '' + case "${AUTO_RUN}" in + '') + read -p "Continue with the merge process? [yes] " CONT_OR_NOT + case "${CONT_OR_NOT}" in + [nN]*) + exit 0 + ;; + *) + echo " *** Continuing" + echo '' + ;; + esac + ;; + *) ;; + esac +fi + +echo '' +echo "*** Beginning comparison" +echo '' + +cd "${TEMPROOT}" + +# Use the umask/mode information to install the files +# Create directories as needed +# +mm_install () { + local INSTALL_DIR + INSTALL_DIR=${1#.} + INSTALL_DIR=${INSTALL_DIR%/*} + case "${INSTALL_DIR}" in + '') + INSTALL_DIR=/ + ;; + esac + + if [ -n "${INSTALL_DIR}" -a ! -d "${INSTALL_DIR}" ]; then + DIR_MODE=`perl -e 'printf "%04o\n", (((stat("$ARGV[0]"))[2] & 07777) &~ oct("$ARGV[1]"))' "${TEMPROOT}/${INSTALL_DIR}" "${CONFIRMED_UMASK}"` + install -d -o root -g wheel -m "${DIR_MODE}" "${INSTALL_DIR}" + fi + + FILE_MODE=`perl -e 'printf "%04o\n", (((stat("$ARGV[0]"))[2] & 07777) &~ oct("$ARGV[1]"))' "${1}" "${CONFIRMED_UMASK}"` + + if [ ! -x "${1}" ]; then + case "${1#.}" in + /dev/MAKEDEV) + NEED_MAKEDEV=yes + ;; + /etc/aliases) + NEED_NEWALIASES=yes + ;; + /etc/login.conf) + NEED_CAP_MKDB=yes + ;; + /etc/master.passwd) + install -m 600 "${1}" "${INSTALL_DIR}" + NEED_PWD_MKDB=yes + DONT_INSTALL=yes + ;; + /.cshrc | /.profile) + case "${LINK_EXPLAINED}" in + '') + echo " *** Historically FreeBSD has had a hard link from" + echo " /.cshrc and /.profile to their namesakes in" + echo " /root. Please indicate your preference below" + echo " for bringing your installed files up to date." + echo '' + LINK_EXPLAINED=yes + ;; + esac + + echo " Use 'd' to delete the temporary ${COMPFILE}" + echo " Use 'l' to delete the existing ${COMPFILE#.} and create the link" + echo '' + echo " Default is to leave the temporary file to deal with by hand" + echo '' + read -p " How should I handle ${COMPFILE}? [Leave it to install later] " HANDLE_LINK + case "${HANDLE_LINK}" in + [dD]*) + rm "${COMPFILE}" + echo '' + echo " *** Deleting ${COMPFILE}" + ;; + [lL]*) + echo '' + if [ -e "${COMPFILE#.}" ]; then + rm "${COMPFILE#.}" + fi + if ln "/root/${COMPFILE##*/}" "${COMPFILE#.}"; then + echo " *** Link from ${COMPFILE#.} to /root/${COMPFILE##*/} installed successfully" + rm "${COMPFILE}" + else + echo " *** Error linking ${COMPFILE#.} to /root/${COMPFILE##*/}, ${COMPFILE} will remain to install by hand" + fi + ;; + *) + echo " *** ${COMPFILE} will remain for your consideration" + ;; + esac + DONT_INSTALL=yes + ;; + esac + + case "${DONT_INSTALL}" in + '') + install -m "${FILE_MODE}" "${1}" "${INSTALL_DIR}" + ;; + *) + unset DONT_INSTALL + ;; + esac + + else + install -m "${FILE_MODE}" "${1}" "${INSTALL_DIR}" + fi + return $? +} + +compare_ids () { + case "${1}" in + "${2}") + echo " *** Temp ${COMPFILE} and installed have the same ${IDTAG}, deleting" + rm "${COMPFILE}" + ;; + esac +} + +# Using -size +0 avoids uselessly checking the empty log files created +# by ${SOURCEDIR}/Makefile and the device entries in ./dev, but does +# check the scripts in ./dev, as we'd like. +# +for COMPFILE in `find . -type f -size +0`; do + case "${STRICT}" in + '' | [Nn][Oo]) + # Compare CVS $Id's first so if the file hasn't been modified + # local changes will be ignored. + # If the files have the same $Id, delete the one in temproot so the + # user will have less to wade through if files are left to merge by hand. + # Take the $Id -> $FreeBSD tag change into account + # + FREEBSDID1=`grep "[$]FreeBSD:" ${COMPFILE#.} 2>/dev/null` + FREEBSDID2=`grep "[$]FreeBSD:" ${COMPFILE} 2>/dev/null` + + if [ -n "${FREEBSDID1}" -a -n "${FREEBSDID2}" ]; then + IDTAG='$FreeBSD' + compare_ids "${FREEBSDID1}" "${FREEBSDID2}" + else + CVSID1=`grep "[$]Id:" ${COMPFILE#.} 2>/dev/null` + CVSID2=`grep "[$]Id:" ${COMPFILE} 2>/dev/null` + + if [ -n "${CVSID1}" -a -n "${CVSID2}" ]; then + IDTAG='$Id' + compare_ids "${CVSID1}" "${CVSID2}" + fi + fi + ;; + esac + + # If the file is still here either because the $Ids are different, the + # file doesn't have an $Id, or we're using STRICT mode; look at the diff. + # + if [ -f "${COMPFILE}" ]; then + + # Do an absolute diff first to see if the files are actually different. + # If they're not different, delete the one in temproot. + # + if diff -q "${COMPFILE#.}" "${COMPFILE}" > /dev/null 2>&1; then + echo " *** Temp ${COMPFILE} and installed are the same, deleting" + rm "${COMPFILE}" + else + # Ok, the files are different, so show the user where they differ. Use user's + # choice of diff methods; and user's pager if they have one. Use more if not. + # Use unified diffs by default. Context diffs give me a headache. :) + # + case "${AUTO_RUN}" in + '') + echo '' + if [ -f "${COMPFILE#.}" -a -f "${COMPFILE}" ]; then + echo " *** Displaying differences between ${COMPFILE} and installed version" + echo '' + diff "${DIFF_FLAG}" "${COMPFILE#.}" "${COMPFILE}" | ${PAGER} + echo '' + else + echo " *** There is no installed version of ${COMPFILE}" + NO_INSTALLED=yes + fi + echo " Use 'd' to delete the temporary ${COMPFILE}" + echo " Use 'i' to install the temporary ${COMPFILE}" + case "${NO_INSTALLED}" in + '') + echo " Use 'm' to merge the old and new versions" + ;; + esac + echo '' + echo " Default is to leave the temporary file to deal with by hand" + echo '' + read -p "How should I deal with this? [Leave it for later] " HANDLE_COMPFILE + case "${HANDLE_COMPFILE}" in + [dD]*) + rm "${COMPFILE}" + echo '' + echo " *** Deleting ${COMPFILE}" + ;; + [iI]*) + echo '' + if mm_install "${COMPFILE}"; then + echo " *** ${COMPFILE} installed successfully" + else + echo " *** Problem installing ${COMPFILE}, it will remain to merge by hand" + fi + ;; + [mM]*) + case "${NO_INSTALLED}" in + '') + case "${VERBOSE}" in + '') ;; + *) + echo " *** Type h at the sdiff prompt (%) to get usage help" + ;; + esac + echo '' + MERGE_AGAIN=yes + while [ "${MERGE_AGAIN}" = "yes" ]; do + # Prime file.merged so we don't blat the owner/group id's + cp -p "${COMPFILE}" "${COMPFILE}.merged" + sdiff -o "${COMPFILE}.merged" --text --suppress-common-lines \ + --width=${SCREEN_WIDTH:-80} "${COMPFILE#.}" "${COMPFILE}" + + echo '' + echo " Use 'i' to install merged file" + echo " Use 'r' to re-do the merge" + echo " Default is to leave the temporary file to deal with by hand" + echo '' + read -p " *** How should I deal with the merged file? [Leave it for later] " INSTALL_MERGED + + case "${INSTALL_MERGED}" in + [iI]*) + mv "${COMPFILE}.merged" "${COMPFILE}" + echo '' + if mm_install "${COMPFILE}"; then + echo " *** Merged version of ${COMPFILE} installed successfully" + else + echo " *** Problem installing ${COMPFILE}, it will remain to merge by hand later" + fi + unset MERGE_AGAIN + ;; + [rR]*) + rm "${COMPFILE}.merged" + ;; + *) + echo " *** ${COMPFILE} will remain for your consideration" + unset MERGE_AGAIN + ;; + esac + done + ;; + *) + echo '' + echo " *** There is no installed version of ${COMPFILE}" + echo " to merge so it will remain to install by hand later" + echo '' + echo " *** Press [Enter] or [Return] key to continue" + read ANY_KEY + unset ANY_KEY + ;; + esac # End of "No installed version of file but user selected merge" test + ;; + *) + echo '' + echo " *** ${COMPFILE} will remain for your consideration" + ;; + esac # End of "How to handle files that are different" + unset NO_INSTALLED + echo '' + case "${VERBOSE}" in + '') ;; + *) + sleep 3 + ;; + esac + ;; + *) + # If this is an auto run, make it official + echo " *** ${COMPFILE} will remain for your consideration" + ;; + esac # Auto run test + fi # Yes, the files are different + fi # Yes, the file still remains to be checked +done # This is for the do way up there at the beginning of the comparison + +echo "*** Comparison complete" +echo '' + +TEST_FOR_FILES=`find ${TEMPROOT} -type f -size +0 2>/dev/null` +if [ -n "${TEST_FOR_FILES}" ]; then + echo "*** Files that remain for you to merge by hand:" + find "${TEMPROOT}" -type f -size +0 +fi + +case "${AUTO_RUN}" in +'') + echo '' + read -p "Do you wish to delete what is left of ${TEMPROOT}? [no] " DEL_TEMPROOT + case "${DEL_TEMPROOT}" in + [yY]*) + if rm -rf "${TEMPROOT}"; then + echo " *** ${TEMPROOT} has been deleted" + else + echo " *** Unable to delete ${TEMPROOT}" + fi + ;; + *) + echo " *** ${TEMPROOT} will remain" + ;; + esac + ;; +*) ;; +esac + +case "${NEED_MAKEDEV}" in +'') ;; +*) + echo '' + echo "*** You installed a new /dev/MAKEDEV script, so make sure that you run" + echo " 'cd /dev && /bin/sh MAKEDEV all' to rebuild your devices" + ;; +esac + +case "${NEED_NEWALIASES}" in +'') ;; +*) + echo '' + echo "*** You installed a new aliases file, so make sure that you run" + echo " 'newaliases' to rebuild your aliases database" + ;; +esac + +case "${NEED_CAP_MKDB}" in +'') ;; +*) + echo '' + echo "*** You installed a login.conf file, so make sure that you run" + echo " 'cap_mkdb /etc/login.conf' to rebuild your login.conf database" + ;; +esac + +case "${NEED_PWD_MKDB}" in +'') ;; +*) + echo '' + echo "*** You installed a new master.passwd file, so make sure that you run" + echo " 'pwd_mkdb -p /etc/master.passwd' to rebuild your password files" + ;; +esac + +echo '' + +exit 0 |