mergemaster.sh revision 241337
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 8241337Sdougb# Copyright (c) 1998-2012 Douglas Barton, All rights reserved 9241337Sdougb# Please see detailed copyright below 1052400Sbillf 1152495Sbillf# $FreeBSD: stable/9/usr.sbin/mergemaster/mergemaster.sh 241337 2012-10-08 05:50:58Z dougb $ 1252400Sbillf 1368507SdougbPATH=/bin:/usr/bin:/usr/sbin 1452400Sbillf 1552400Sbillfdisplay_usage () { 1652533Sbillf VERSION_NUMBER=`grep "[$]FreeBSD:" $0 | cut -d ' ' -f 4` 1752400Sbillf echo "mergemaster version ${VERSION_NUMBER}" 18227145Sdougb echo 'Usage: mergemaster [-scrvhpCP] [-a|[-iFU]] [--run-updates=always|never]' 19189763Sdougb echo ' [-m /path] [-t /path] [-d] [-u N] [-w N] [-A arch] [-D /path]' 2052400Sbillf echo "Options:" 2152400Sbillf echo " -s Strict comparison (diff every pair of files)" 2252400Sbillf echo " -c Use context diff instead of unified diff" 2352400Sbillf echo " -r Re-run on a previously cleaned directory (skip temproot creation)" 2452400Sbillf echo " -v Be more verbose about the process, include additional checks" 2552400Sbillf echo " -a Leave all files that differ to merge by hand" 2652400Sbillf echo " -h Display more complete help" 2767949Sdougb echo ' -i Automatically install files that do not exist in destination directory' 2891193Sdougb echo ' -p Pre-buildworld mode, only compares crucial files' 29190320Sdougb echo ' -F Install files that differ only by revision control Id ($FreeBSD)' 3091193Sdougb echo ' -C Compare local rc.conf variables to the defaults' 31114501Sdougb echo ' -P Preserve files that are overwritten' 32189763Sdougb echo " -U Attempt to auto upgrade files that have not been user modified" 33224726Sdougb echo ' ***DANGEROUS***' 34227145Sdougb echo ' --run-updates= Specify always or never to run newalises, pwd_mkdb, etc.' 35189763Sdougb echo '' 3652400Sbillf echo " -m /path/directory Specify location of source to do the make in" 3752400Sbillf echo " -t /path/directory Specify temp root directory" 3852400Sbillf echo " -d Add date and time to directory name (e.g., /var/tmp/temproot.`date +%m%d.%H.%M`)" 3952400Sbillf echo " -u N Specify a numeric umask" 4052400Sbillf echo " -w N Specify a screen width in columns to sdiff" 41155309Srwatson echo " -A architecture Alternative architecture name to pass to make" 4267949Sdougb echo ' -D /path/directory Specify the destination directory to install files to' 4352400Sbillf echo '' 4452400Sbillf} 4552400Sbillf 4652400Sbillfdisplay_help () { 4752400Sbillf echo "* To specify a directory other than /var/tmp/temproot for the" 4852400Sbillf echo " temporary root environment, use -t /path/to/temp/root" 4952400Sbillf echo "* The -w option takes a number as an argument for the column width" 5067859Sdougb echo " of the screen. The default is 80." 5167949Sdougb echo '* The -a option causes mergemaster to run without prompting.' 5252400Sbillf} 5352400Sbillf 5458910Salfred# Loop allowing the user to use sdiff to merge files and display the merged 5558910Salfred# file. 5658910Salfredmerge_loop () { 5767850Sdougb case "${VERBOSE}" in 5867850Sdougb '') ;; 5967850Sdougb *) 6067850Sdougb echo " *** Type h at the sdiff prompt (%) to get usage help" 6167850Sdougb ;; 6267850Sdougb esac 6367850Sdougb echo '' 6467850Sdougb MERGE_AGAIN=yes 6567850Sdougb while [ "${MERGE_AGAIN}" = "yes" ]; do 6667850Sdougb # Prime file.merged so we don't blat the owner/group id's 6767850Sdougb cp -p "${COMPFILE}" "${COMPFILE}.merged" 6867850Sdougb sdiff -o "${COMPFILE}.merged" --text --suppress-common-lines \ 6967949Sdougb --width=${SCREEN_WIDTH:-80} "${DESTDIR}${COMPFILE#.}" "${COMPFILE}" 7067850Sdougb INSTALL_MERGED=V 7167850Sdougb while [ "${INSTALL_MERGED}" = "v" -o "${INSTALL_MERGED}" = "V" ]; do 7267850Sdougb echo '' 7367850Sdougb echo " Use 'i' to install merged file" 7467850Sdougb echo " Use 'r' to re-do the merge" 7567850Sdougb echo " Use 'v' to view the merged file" 7667850Sdougb echo " Default is to leave the temporary file to deal with by hand" 7767850Sdougb echo '' 7867859Sdougb echo -n " *** How should I deal with the merged file? [Leave it for later] " 7967859Sdougb read INSTALL_MERGED 8058910Salfred 8167850Sdougb case "${INSTALL_MERGED}" in 8267850Sdougb [iI]) 8367850Sdougb mv "${COMPFILE}.merged" "${COMPFILE}" 8467850Sdougb echo '' 8567850Sdougb if mm_install "${COMPFILE}"; then 8667850Sdougb echo " *** Merged version of ${COMPFILE} installed successfully" 8767859Sdougb else 8867850Sdougb echo " *** Problem installing ${COMPFILE}, it will remain to merge by hand later" 8967859Sdougb fi 9067850Sdougb unset MERGE_AGAIN 9167850Sdougb ;; 9267850Sdougb [rR]) 9367850Sdougb rm "${COMPFILE}.merged" 9467859Sdougb ;; 9567850Sdougb [vV]) 9667850Sdougb ${PAGER} "${COMPFILE}.merged" 9767850Sdougb ;; 9867850Sdougb '') 9967850Sdougb echo " *** ${COMPFILE} will remain for your consideration" 10067850Sdougb unset MERGE_AGAIN 10167850Sdougb ;; 10267850Sdougb *) 10367850Sdougb echo "invalid choice: ${INSTALL_MERGED}" 10467850Sdougb INSTALL_MERGED=V 10567850Sdougb ;; 10667850Sdougb esac 10767850Sdougb done 10867850Sdougb done 10958910Salfred} 11058910Salfred 11158910Salfred# Loop showing user differences between files, allow merge, skip or install 11258910Salfred# options 11358910Salfreddiff_loop () { 11458910Salfred 11567850Sdougb HANDLE_COMPFILE=v 11658910Salfred 11777323Sdougb while [ "${HANDLE_COMPFILE}" = "v" -o "${HANDLE_COMPFILE}" = "V" -o \ 11877323Sdougb "${HANDLE_COMPFILE}" = "NOT V" ]; do 11967949Sdougb if [ -f "${DESTDIR}${COMPFILE#.}" -a -f "${COMPFILE}" ]; then 120192230Sdougb if [ -n "${AUTO_UPGRADE}" -a -n "${CHANGED}" ]; then 121192230Sdougb case "${CHANGED}" in 122192230Sdougb *:${DESTDIR}${COMPFILE#.}:*) ;; # File has been modified 123192230Sdougb *) 124158149Sgordon echo '' 125158149Sgordon echo " *** ${COMPFILE} has not been user modified." 126158149Sgordon echo '' 127158149Sgordon 128158149Sgordon if mm_install "${COMPFILE}"; then 129158149Sgordon echo " *** ${COMPFILE} upgraded successfully" 130158149Sgordon echo '' 131158149Sgordon # Make the list print one file per line 132158149Sgordon AUTO_UPGRADED_FILES="${AUTO_UPGRADED_FILES} ${DESTDIR}${COMPFILE#.} 133158149Sgordon" 134158149Sgordon else 135192230Sdougb echo " *** Problem upgrading ${COMPFILE}, it will remain to merge by hand" 136158149Sgordon fi 137158149Sgordon return 138192230Sdougb ;; 139192230Sdougb esac 140158149Sgordon fi 14167850Sdougb if [ "${HANDLE_COMPFILE}" = "v" -o "${HANDLE_COMPFILE}" = "V" ]; then 14290564Sdougb echo '' 143109993Sdillon echo ' ====================================================================== ' 144109993Sdillon echo '' 145109993Sdillon ( 146109993Sdillon echo " *** Displaying differences between ${COMPFILE} and installed version:" 147109993Sdillon echo '' 148110377Sdougb diff ${DIFF_FLAG} ${DIFF_OPTIONS} "${DESTDIR}${COMPFILE#.}" "${COMPFILE}" 149109993Sdillon ) | ${PAGER} 150109993Sdillon echo '' 15167850Sdougb fi 15267850Sdougb else 153109993Sdillon echo '' 15467850Sdougb echo " *** There is no installed version of ${COMPFILE}" 15591193Sdougb echo '' 15667949Sdougb case "${AUTO_INSTALL}" in 15767949Sdougb [Yy][Ee][Ss]) 15867949Sdougb echo '' 15967949Sdougb if mm_install "${COMPFILE}"; then 16067949Sdougb echo " *** ${COMPFILE} installed successfully" 16168507Sdougb echo '' 16267949Sdougb # Make the list print one file per line 16367949Sdougb AUTO_INSTALLED_FILES="${AUTO_INSTALLED_FILES} ${DESTDIR}${COMPFILE#.} 16467949Sdougb" 16567949Sdougb else 16667949Sdougb echo " *** Problem installing ${COMPFILE}, it will remain to merge by hand" 16767949Sdougb fi 16867949Sdougb return 16967949Sdougb ;; 17067949Sdougb *) 17167949Sdougb NO_INSTALLED=yes 17267949Sdougb ;; 17367949Sdougb esac 17467850Sdougb fi 17567859Sdougb 17667850Sdougb echo " Use 'd' to delete the temporary ${COMPFILE}" 17767850Sdougb echo " Use 'i' to install the temporary ${COMPFILE}" 17867850Sdougb case "${NO_INSTALLED}" in 17967850Sdougb '') 18077326Sdougb echo " Use 'm' to merge the temporary and installed versions" 181109993Sdillon echo " Use 'v' to view the diff results again" 18267850Sdougb ;; 18367850Sdougb esac 18467850Sdougb echo '' 18567850Sdougb echo " Default is to leave the temporary file to deal with by hand" 18667850Sdougb echo '' 18767859Sdougb echo -n "How should I deal with this? [Leave it for later] " 18867859Sdougb read HANDLE_COMPFILE 18967859Sdougb 19067850Sdougb case "${HANDLE_COMPFILE}" in 19167850Sdougb [dD]) 19267850Sdougb rm "${COMPFILE}" 19367850Sdougb echo '' 19467850Sdougb echo " *** Deleting ${COMPFILE}" 19567850Sdougb ;; 19667850Sdougb [iI]) 19767850Sdougb echo '' 19867850Sdougb if mm_install "${COMPFILE}"; then 19967850Sdougb echo " *** ${COMPFILE} installed successfully" 20067850Sdougb else 20167850Sdougb echo " *** Problem installing ${COMPFILE}, it will remain to merge by hand" 20267850Sdougb fi 20367850Sdougb ;; 20467850Sdougb [mM]) 20567850Sdougb case "${NO_INSTALLED}" in 20667850Sdougb '') 20767850Sdougb # interact with user to merge files 20867850Sdougb merge_loop 20967850Sdougb ;; 21067850Sdougb *) 21167850Sdougb echo '' 21267850Sdougb echo " *** There is no installed version of ${COMPFILE}" 21367850Sdougb echo '' 21467850Sdougb HANDLE_COMPFILE="NOT V" 21567850Sdougb ;; 21667850Sdougb esac # End of "No installed version of file but user selected merge" test 21767850Sdougb ;; 21867850Sdougb [vV]) 21967850Sdougb continue 22067850Sdougb ;; 22167850Sdougb '') 22267850Sdougb echo '' 22367850Sdougb echo " *** ${COMPFILE} will remain for your consideration" 22467850Sdougb ;; 22567850Sdougb *) 22667850Sdougb # invalid choice, show menu again. 22767850Sdougb echo "invalid choice: ${HANDLE_COMPFILE}" 22867850Sdougb echo '' 22967850Sdougb HANDLE_COMPFILE="NOT V" 23067850Sdougb continue 23167850Sdougb ;; 23267850Sdougb esac # End of "How to handle files that are different" 23367859Sdougb done 23467850Sdougb unset NO_INSTALLED 23567850Sdougb echo '' 23667850Sdougb case "${VERBOSE}" in 23767850Sdougb '') ;; 23867850Sdougb *) 23967850Sdougb sleep 3 24067850Sdougb ;; 24167850Sdougb esac 24258910Salfred} 24358910Salfred 24497960Sdougbpress_to_continue () { 24597960Sdougb local DISCARD 24697960Sdougb echo -n ' *** Press the [Enter] or [Return] key to continue ' 24797960Sdougb read DISCARD 24897960Sdougb} 24997960Sdougb 25052400Sbillf# Set the default path for the temporary root environment 25152400Sbillf# 25252400SbillfTEMPROOT='/var/tmp/temproot' 25352400Sbillf 25473651Sdougb# Read /etc/mergemaster.rc first so the one in $HOME can override 25573651Sdougb# 25673651Sdougbif [ -r /etc/mergemaster.rc ]; then 25773651Sdougb . /etc/mergemaster.rc 25873651Sdougbfi 25973651Sdougb 26052400Sbillf# Read .mergemasterrc before command line so CLI can override 26152400Sbillf# 26267949Sdougbif [ -r "$HOME/.mergemasterrc" ]; then 26352400Sbillf . "$HOME/.mergemasterrc" 26452400Sbillffi 26552400Sbillf 266227145Sdougbfor var in "$@" ; do 267227145Sdougb case "$var" in 268227145Sdougb --run-updates*) 269227145Sdougb RUN_UPDATES=`echo ${var#--run-updates=} | tr [:upper:] [:lower:]` 270227145Sdougb ;; 271227145Sdougb *) 272227145Sdougb newopts="$newopts $var" 273227145Sdougb ;; 274227145Sdougb esac 275227145Sdougbdone 276227145Sdougb 277227145Sdougbset -- $newopts 278227145Sdougbunset var newopts 279227145Sdougb 28052400Sbillf# Check the command line options 28152400Sbillf# 282189992Sdougbwhile getopts ":ascrvhipCPm:t:du:w:D:A:FU" COMMAND_LINE_ARGUMENT ; do 28352400Sbillf case "${COMMAND_LINE_ARGUMENT}" in 284155309Srwatson A) 285186678Sdougb ARCHSTRING='TARGET_ARCH='${OPTARG} 286155309Srwatson ;; 287189992Sdougb F) 288189992Sdougb FREEBSD_ID=yes 289189992Sdougb ;; 290158149Sgordon U) 291158149Sgordon AUTO_UPGRADE=yes 292158149Sgordon ;; 29352400Sbillf s) 29452400Sbillf STRICT=yes 295110377Sdougb unset DIFF_OPTIONS 29652400Sbillf ;; 29752400Sbillf c) 29852400Sbillf DIFF_FLAG='-c' 29952400Sbillf ;; 30052400Sbillf r) 30152400Sbillf RERUN=yes 30252400Sbillf ;; 30352400Sbillf v) 30452400Sbillf case "${AUTO_RUN}" in 30552400Sbillf '') VERBOSE=yes ;; 30652400Sbillf esac 30752400Sbillf ;; 30852400Sbillf a) 30952400Sbillf AUTO_RUN=yes 31052400Sbillf unset VERBOSE 31152400Sbillf ;; 31252400Sbillf h) 31352400Sbillf display_usage 31452400Sbillf display_help 31552400Sbillf exit 0 31652400Sbillf ;; 31767949Sdougb i) 31867949Sdougb AUTO_INSTALL=yes 31967949Sdougb ;; 32096045Sdougb C) 32196045Sdougb COMP_CONFS=yes 32296045Sdougb ;; 323114501Sdougb P) 324114501Sdougb PRESERVE_FILES=yes 325114501Sdougb ;; 32691193Sdougb p) 32791193Sdougb PRE_WORLD=yes 32896045Sdougb unset COMP_CONFS 32996045Sdougb unset AUTO_RUN 33091193Sdougb ;; 33152400Sbillf m) 33252400Sbillf SOURCEDIR=${OPTARG} 33352400Sbillf ;; 33452400Sbillf t) 33552400Sbillf TEMPROOT=${OPTARG} 33652400Sbillf ;; 33752400Sbillf d) 33852400Sbillf TEMPROOT=${TEMPROOT}.`date +%m%d.%H.%M` 33952400Sbillf ;; 34052400Sbillf u) 34152400Sbillf NEW_UMASK=${OPTARG} 34252400Sbillf ;; 34352400Sbillf w) 34452400Sbillf SCREEN_WIDTH=${OPTARG} 34552400Sbillf ;; 34667949Sdougb D) 34767949Sdougb DESTDIR=${OPTARG} 34867949Sdougb ;; 34952400Sbillf *) 35052400Sbillf display_usage 35152400Sbillf exit 1 35252400Sbillf ;; 35352400Sbillf esac 35452400Sbillfdone 35552400Sbillf 356205145Sdougbif [ -n "$AUTO_RUN" ]; then 357205145Sdougb if [ -n "$FREEBSD_ID" -o -n "$AUTO_UPGRADE" -o -n "$AUTO_INSTALL" ]; then 358205145Sdougb echo '' 359205145Sdougb echo "*** You have included the -a option along with one or more options" 360205145Sdougb echo ' that indicate that you wish mergemaster to actually make updates' 361205145Sdougb echo ' (-F, -U, or -i), however these options are not compatible.' 362205145Sdougb echo ' Please read mergemaster(8) for more information.' 363205145Sdougb echo '' 364205145Sdougb exit 1 365205145Sdougb fi 366205145Sdougbfi 367205145Sdougb 368202817Sdougb# Assign the location of the mtree database 369202817Sdougb# 370202817SdougbMTREEDB=${MTREEDB:-${DESTDIR}/var/db} 371202817SdougbMTREEFILE="${MTREEDB}/mergemaster.mtree" 372202817Sdougb 373114501Sdougb# Don't force the user to set this in the mergemaster rc file 374114501Sdougbif [ -n "${PRESERVE_FILES}" -a -z "${PRESERVE_FILES_DIR}" ]; then 375114501Sdougb PRESERVE_FILES_DIR=/var/tmp/mergemaster/preserved-files-`date +%y%m%d-%H%M%S` 376200425Sdougb mkdir -p ${PRESERVE_FILES_DIR} 377114501Sdougbfi 378114501Sdougb 379186678Sdougb# Check for the mtree database in DESTDIR 380186678Sdougbcase "${AUTO_UPGRADE}" in 381186678Sdougb'') ;; # If the option is not set no need to run the test or warn the user 382186678Sdougb*) 383200416Sdougb if [ ! -s "${MTREEFILE}" ]; then 384186678Sdougb echo '' 385200416Sdougb echo "*** Unable to find mtree database (${MTREEFILE})." 386200416Sdougb echo " Skipping auto-upgrade on this run." 387193853Sdougb echo " It will be created for the next run when this one is complete." 388186678Sdougb echo '' 389201291Sdougb case "${AUTO_RUN}" in 390201291Sdougb '') 391201291Sdougb press_to_continue 392201291Sdougb ;; 393201291Sdougb esac 394186678Sdougb unset AUTO_UPGRADE 395186678Sdougb fi 396186678Sdougb ;; 397186678Sdougbesac 398186678Sdougb 399186689Sdougbif [ -e "${DESTDIR}/etc/fstab" ]; then 400186689Sdougb if grep -q nodev ${DESTDIR}/etc/fstab; then 401186689Sdougb echo '' 402186689Sdougb echo "*** You have the deprecated 'nodev' option in ${DESTDIR}/etc/fstab." 403186689Sdougb echo " This can prevent the filesystem from being mounted on reboot." 404186689Sdougb echo " Please update your fstab before continuing." 405186689Sdougb echo " See fstab(5) for more information." 406186689Sdougb echo '' 407186689Sdougb exit 1 408186689Sdougb fi 409158149Sgordonfi 410158149Sgordon 41152400Sbillfecho '' 41252400Sbillf 41352400Sbillf# If the user has a pager defined, make sure we can run it 41452400Sbillf# 41552400Sbillfcase "${DONT_CHECK_PAGER}" in 41652400Sbillf'') 417186695Sdougbcheck_pager () { 418186695Sdougb while ! type "${PAGER%% *}" >/dev/null; do 41952400Sbillf echo " *** Your PAGER environment variable specifies '${PAGER}', but" 42064467Sbrian echo " due to the limited PATH that I use for security reasons," 42167859Sdougb echo " I cannot execute it. So, what would you like to do?" 42252400Sbillf echo '' 42352400Sbillf echo " Use 'e' to exit mergemaster and fix your PAGER variable" 42464467Sbrian if [ -x /usr/bin/less -o -x /usr/local/bin/less ]; then 42564467Sbrian echo " Use 'l' to set PAGER to 'less' for this run" 42652400Sbillf fi 42752400Sbillf echo " Use 'm' to use plain old 'more' as your PAGER for this run" 42852400Sbillf echo '' 42952400Sbillf echo " Default is to use plain old 'more' " 43052400Sbillf echo '' 43167859Sdougb echo -n "What should I do? [Use 'more'] " 43267859Sdougb read FIXPAGER 43367859Sdougb 43452400Sbillf case "${FIXPAGER}" in 43558910Salfred [eE]) 43652400Sbillf exit 0 43752400Sbillf ;; 43858910Salfred [lL]) 43964467Sbrian if [ -x /usr/bin/less ]; then 44064467Sbrian PAGER=/usr/bin/less 44164467Sbrian elif [ -x /usr/local/bin/less ]; then 44258910Salfred PAGER=/usr/local/bin/less 44364467Sbrian else 44464467Sbrian echo '' 44564467Sbrian echo " *** Fatal Error:" 44664467Sbrian echo " You asked to use 'less' as your pager, but I can't" 44764467Sbrian echo " find it in /usr/bin or /usr/local/bin" 44864467Sbrian exit 1 44958910Salfred fi 45052400Sbillf ;; 45160420Sbsd [mM]|'') 45252400Sbillf PAGER=more 45352400Sbillf ;; 45458910Salfred *) 45558910Salfred echo '' 45658910Salfred echo "invalid choice: ${FIXPAGER}" 45752400Sbillf esac 45852400Sbillf echo '' 45958910Salfred done 460186695Sdougb} 461186695Sdougb if [ -n "${PAGER}" ]; then 462186695Sdougb check_pager 463186695Sdougb fi 46452400Sbillf ;; 46552400Sbillfesac 46652400Sbillf 46752400Sbillf# If user has a pager defined, or got assigned one above, use it. 46852400Sbillf# If not, use more. 46952400Sbillf# 47052400SbillfPAGER=${PAGER:-more} 47152400Sbillf 47252400Sbillfif [ -n "${VERBOSE}" -a ! "${PAGER}" = "more" ]; then 47352400Sbillf echo " *** You have ${PAGER} defined as your pager so we will use that" 47452400Sbillf echo '' 47552400Sbillf sleep 3 47652400Sbillffi 47752400Sbillf 47852400Sbillf# Assign the diff flag once so we will not have to keep testing it 47952400Sbillf# 48052400SbillfDIFF_FLAG=${DIFF_FLAG:--u} 48152400Sbillf 48252400Sbillf# Assign the source directory 48352400Sbillf# 484186678SdougbSOURCEDIR=${SOURCEDIR:-/usr/src} 485186678Sdougbif [ ! -f ${SOURCEDIR}/Makefile.inc1 -a \ 486186678Sdougb -f ${SOURCEDIR}/../Makefile.inc1 ]; then 487186678Sdougb echo " *** The source directory you specified (${SOURCEDIR})" 488186678Sdougb echo " will be reset to ${SOURCEDIR}/.." 489186678Sdougb echo '' 490186678Sdougb sleep 3 491186678Sdougb SOURCEDIR=${SOURCEDIR}/.. 492186678Sdougbfi 49352400Sbillf 494186678Sdougb# Setup make to use system files from SOURCEDIR 495186695SdougbMM_MAKE="make ${ARCHSTRING} -m ${SOURCEDIR}/share/mk" 496186678Sdougb 497158149Sgordon# Check DESTDIR against the mergemaster mtree database to see what 498158149Sgordon# files the user changed from the reference files. 499158149Sgordon# 500200416Sdougbif [ -n "${AUTO_UPGRADE}" -a -s "${MTREEFILE}" ]; then 501192230Sdougb CHANGED=: 502200416Sdougb for file in `mtree -eqL -f ${MTREEFILE} -p ${DESTDIR}/ \ 503158149Sgordon 2>/dev/null | awk '($2 == "changed") {print $1}'`; do 504158149Sgordon if [ -f "${DESTDIR}/$file" ]; then 505192230Sdougb CHANGED="${CHANGED}${DESTDIR}/${file}:" 506158149Sgordon fi 507158149Sgordon done 508192230Sdougb [ "$CHANGED" = ':' ] && unset CHANGED 509158149Sgordonfi 510158149Sgordon 51196045Sdougb# Check the width of the user's terminal 51296045Sdougb# 51396045Sdougbif [ -t 0 ]; then 514110377Sdougb w=`tput columns` 51596045Sdougb case "${w}" in 51696045Sdougb 0|'') ;; # No-op, since the input is not valid 51796045Sdougb *) 51896045Sdougb case "${SCREEN_WIDTH}" in 51996045Sdougb '') SCREEN_WIDTH="${w}" ;; 52096045Sdougb "${w}") ;; # No-op, since they are the same 52196045Sdougb *) 52296045Sdougb echo -n "*** You entered ${SCREEN_WIDTH} as your screen width, but stty " 52396045Sdougb echo "thinks it is ${w}." 52496045Sdougb echo '' 52596045Sdougb echo -n "What would you like to use? [${w}] " 52696045Sdougb read SCREEN_WIDTH 52797380Sdougb case "${SCREEN_WIDTH}" in 52897380Sdougb '') SCREEN_WIDTH="${w}" ;; 52997380Sdougb esac 53096045Sdougb ;; 53196045Sdougb esac 53296045Sdougb esac 53396045Sdougbfi 53496045Sdougb 535241337Sdougb# Define what $Id tag to look for to aid portability. 53673651Sdougb# 537241337SdougbID_TAG=FreeBSD 53873651Sdougb 53999152Sdougbdelete_temproot () { 540101362Sdougb rm -rf "${TEMPROOT}" 2>/dev/null 541101362Sdougb chflags -R 0 "${TEMPROOT}" 2>/dev/null 542201765Sdougb rm -rf "${TEMPROOT}" || { echo "*** Unable to delete ${TEMPROOT}"; exit 1; } 54399152Sdougb} 54499152Sdougb 54552400Sbillfcase "${RERUN}" in 54652400Sbillf'') 54752400Sbillf # Set up the loop to test for the existence of the 54852400Sbillf # temp root directory. 54952400Sbillf # 55052400Sbillf TEST_TEMP_ROOT=yes 55152400Sbillf while [ "${TEST_TEMP_ROOT}" = "yes" ]; do 55252400Sbillf if [ -d "${TEMPROOT}" ]; then 55352400Sbillf echo "*** The directory specified for the temporary root environment," 55467859Sdougb echo " ${TEMPROOT}, exists. This can be a security risk if untrusted" 55552400Sbillf echo " users have access to the system." 55652400Sbillf echo '' 55752400Sbillf case "${AUTO_RUN}" in 55852400Sbillf '') 55952400Sbillf echo " Use 'd' to delete the old ${TEMPROOT} and continue" 56052400Sbillf echo " Use 't' to select a new temporary root directory" 56152400Sbillf echo " Use 'e' to exit mergemaster" 56252400Sbillf echo '' 56352400Sbillf echo " Default is to use ${TEMPROOT} as is" 56452400Sbillf echo '' 56567859Sdougb echo -n "How should I deal with this? [Use the existing ${TEMPROOT}] " 56667859Sdougb read DELORNOT 56767859Sdougb 56867859Sdougb case "${DELORNOT}" in 56967859Sdougb [dD]) 57067859Sdougb echo '' 57167859Sdougb echo " *** Deleting the old ${TEMPROOT}" 57267859Sdougb echo '' 573201765Sdougb delete_temproot 57467859Sdougb unset TEST_TEMP_ROOT 57552400Sbillf ;; 57667859Sdougb [tT]) 57767859Sdougb echo " *** Enter new directory name for temporary root environment" 57867859Sdougb read TEMPROOT 57967859Sdougb ;; 58067859Sdougb [eE]) 58167859Sdougb exit 0 58267859Sdougb ;; 58367859Sdougb '') 58467859Sdougb echo '' 58567859Sdougb echo " *** Leaving ${TEMPROOT} intact" 58667859Sdougb echo '' 58767859Sdougb unset TEST_TEMP_ROOT 58867859Sdougb ;; 58967859Sdougb *) 59067859Sdougb echo '' 59167859Sdougb echo "invalid choice: ${DELORNOT}" 59267859Sdougb echo '' 59367859Sdougb ;; 59467859Sdougb esac 59567859Sdougb ;; 59652400Sbillf *) 59777323Sdougb # If this is an auto-run, try a hopefully safe alternative then 59877323Sdougb # re-test anyway. 59952400Sbillf TEMPROOT=/var/tmp/temproot.`date +%m%d.%H.%M.%S` 60052400Sbillf ;; 60152400Sbillf esac 60252400Sbillf else 60352400Sbillf unset TEST_TEMP_ROOT 60452400Sbillf fi 60552400Sbillf done 60652400Sbillf 60752400Sbillf echo "*** Creating the temporary root environment in ${TEMPROOT}" 60852400Sbillf 60952400Sbillf if mkdir -p "${TEMPROOT}"; then 61052400Sbillf echo " *** ${TEMPROOT} ready for use" 61152400Sbillf fi 61252400Sbillf 61352400Sbillf if [ ! -d "${TEMPROOT}" ]; then 61452400Sbillf echo '' 61552400Sbillf echo " *** FATAL ERROR: Cannot create ${TEMPROOT}" 61652400Sbillf echo '' 61752400Sbillf exit 1 61852400Sbillf fi 61952400Sbillf 62052400Sbillf echo " *** Creating and populating directory structure in ${TEMPROOT}" 62152400Sbillf echo '' 62252400Sbillf 62352400Sbillf case "${VERBOSE}" in 62452400Sbillf '') ;; 62552400Sbillf *) 62697960Sdougb press_to_continue 62752400Sbillf ;; 62852400Sbillf esac 62952400Sbillf 63091193Sdougb case "${PRE_WORLD}" in 63191193Sdougb '') 63291193Sdougb { cd ${SOURCEDIR} && 63391193Sdougb case "${DESTDIR}" in 63491193Sdougb '') ;; 63591193Sdougb *) 636208088Sdougb ${MM_MAKE} DESTDIR=${DESTDIR} distrib-dirs >/dev/null 63791193Sdougb ;; 63891193Sdougb esac 639186749Sdougb od=${TEMPROOT}/usr/obj 640208088Sdougb ${MM_MAKE} DESTDIR=${TEMPROOT} distrib-dirs >/dev/null && 641208088Sdougb MAKEOBJDIRPREFIX=$od ${MM_MAKE} _obj SUBDIR_OVERRIDE=etc >/dev/null && 642208088Sdougb MAKEOBJDIRPREFIX=$od ${MM_MAKE} everything SUBDIR_OVERRIDE=etc >/dev/null && 643208088Sdougb MAKEOBJDIRPREFIX=$od ${MM_MAKE} DESTDIR=${TEMPROOT} distribution >/dev/null;} || 64491193Sdougb { echo ''; 64591193Sdougb echo " *** FATAL ERROR: Cannot 'cd' to ${SOURCEDIR} and install files to"; 64691193Sdougb echo " the temproot environment"; 64791193Sdougb echo ''; 64891193Sdougb exit 1;} 64991193Sdougb ;; 65091193Sdougb *) 65191193Sdougb # Only set up files that are crucial to {build|install}world 65291193Sdougb { mkdir -p ${TEMPROOT}/etc && 653186678Sdougb cp -p ${SOURCEDIR}/etc/master.passwd ${TEMPROOT}/etc && 654224726Sdougb install -p -o root -g wheel -m 0644 ${SOURCEDIR}/etc/group ${TEMPROOT}/etc;} || 65591193Sdougb { echo ''; 65691193Sdougb echo ' *** FATAL ERROR: Cannot copy files to the temproot environment'; 65791193Sdougb echo ''; 65891193Sdougb exit 1;} 65991193Sdougb ;; 66091193Sdougb esac 66152400Sbillf 66277323Sdougb # Doing the inventory and removing files that we don't want to compare only 66377323Sdougb # makes sense if we are not doing a rerun, since we have no way of knowing 66477323Sdougb # what happened to the files during previous incarnations. 66567949Sdougb case "${VERBOSE}" in 66667949Sdougb '') ;; 66767949Sdougb *) 66867949Sdougb echo '' 66967949Sdougb echo ' *** The following files exist only in the installed version of' 67067949Sdougb echo " ${DESTDIR}/etc. In the vast majority of cases these files" 67167949Sdougb echo ' are necessary parts of the system and should not be deleted.' 67267949Sdougb echo ' However because these files are not updated by this process you' 67367949Sdougb echo ' might want to verify their status before rebooting your system.' 67467949Sdougb echo '' 67597960Sdougb press_to_continue 676101348Sdougb diff -qr ${DESTDIR}/etc ${TEMPROOT}/etc | grep "^Only in ${DESTDIR}/etc" | ${PAGER} 67767949Sdougb echo '' 67897960Sdougb press_to_continue 67967949Sdougb ;; 68067949Sdougb esac 68167949Sdougb 68252534Sbillf case "${IGNORE_MOTD}" in 683202340Sdougb '') ;; 684202339Sdougb *) 685186678Sdougb echo '' 686186678Sdougb echo "*** You have the IGNORE_MOTD option set in your mergemaster rc file." 687186678Sdougb echo " This option is deprecated in favor of the IGNORE_FILES option." 688186678Sdougb echo " Please update your rc file accordingly." 689186678Sdougb echo '' 690202339Sdougb exit 1 69152534Sbillf ;; 69252534Sbillf esac 69352534Sbillf 694186678Sdougb # Avoid comparing the following user specified files 695186678Sdougb for file in ${IGNORE_FILES}; do 696186688Sdougb test -e ${TEMPROOT}/${file} && unlink ${TEMPROOT}/${file} 697186678Sdougb done 69852400Sbillf 699201291Sdougb # We really don't want to have to deal with files like login.conf.db, pwd.db, 700201291Sdougb # or spwd.db. Instead, we want to compare the text versions, and run *_mkdb. 701201291Sdougb # Prompt the user to do so below, as needed. 702201291Sdougb # 703201291Sdougb rm -f ${TEMPROOT}/etc/*.db ${TEMPROOT}/etc/passwd 70477478Sdougb 705201291Sdougb # We only need to compare things like freebsd.cf once 706201291Sdougb find ${TEMPROOT}/usr/obj -type f -delete 2>/dev/null 70794196Sdougb 708201291Sdougb # Delete stuff we do not need to keep the mtree database small, 709201291Sdougb # and to make the actual comparison faster. 710201291Sdougb find ${TEMPROOT}/usr -type l -delete 2>/dev/null 711201291Sdougb find ${TEMPROOT} -type f -size 0 -delete 2>/dev/null 712201291Sdougb find -d ${TEMPROOT} -type d -empty -delete 2>/dev/null 713158149Sgordon 714201291Sdougb # Build the mtree database in a temporary location. 715201291Sdougb case "${PRE_WORLD}" in 716201323Sdougb '') MTREENEW=`mktemp -t mergemaster.mtree` 717201323Sdougb mtree -ci -p ${TEMPROOT} -k size,md5digest > ${MTREENEW} 2>/dev/null 718201291Sdougb ;; 719201291Sdougb *) # We don't want to mess with the mtree database on a pre-world run or 720201291Sdougb # when re-scanning a previously-built tree. 721201291Sdougb ;; 722201291Sdougb esac 723201291Sdougb ;; # End of the "RERUN" test 724158149Sgordonesac 725158149Sgordon 72652400Sbillf# Get ready to start comparing files 72752400Sbillf 72898084Sdougb# Check umask if not specified on the command line, 72998084Sdougb# and we are not doing an autorun 73052400Sbillf# 73198084Sdougbif [ -z "${NEW_UMASK}" -a -z "${AUTO_RUN}" ]; then 73298084Sdougb USER_UMASK=`umask` 73352400Sbillf case "${USER_UMASK}" in 73477335Sdougb 0022|022) ;; 73552400Sbillf *) 73652400Sbillf echo '' 73798084Sdougb echo " *** Your umask is currently set to ${USER_UMASK}. By default, this script" 73898084Sdougb echo " installs all files with the same user, group and modes that" 739186678Sdougb echo " they are created with by ${SOURCEDIR}/etc/Makefile, compared to" 74098084Sdougb echo " a umask of 022. This umask allows world read permission when" 74198084Sdougb echo " the file's default permissions have it." 74252400Sbillf echo '' 74398084Sdougb echo " No world permissions can sometimes cause problems. A umask of" 74498084Sdougb echo " 022 will restore the default behavior, but is not mandatory." 74598084Sdougb echo " /etc/master.passwd is a special case. Its file permissions" 74698084Sdougb echo " will be 600 (rw-------) if installed." 74797960Sdougb echo '' 74898084Sdougb echo -n "What umask should I use? [${USER_UMASK}] " 74998084Sdougb read NEW_UMASK 75098084Sdougb 75198084Sdougb NEW_UMASK="${NEW_UMASK:-$USER_UMASK}" 75252400Sbillf ;; 75352400Sbillf esac 75452400Sbillf echo '' 75598084Sdougbfi 75652400Sbillf 75798084SdougbCONFIRMED_UMASK=${NEW_UMASK:-0022} 75898084Sdougb 75952400Sbillf# 760114501Sdougb# Warn users who still have old rc files 761114501Sdougb# 762179315Sbzfor file in atm devfs diskless1 diskless2 network network6 pccard \ 763114523Sdougb serial syscons sysctl alpha amd64 i386 ia64 sparc64; do 764114501Sdougb if [ -f "${DESTDIR}/etc/rc.${file}" ]; then 765114501Sdougb OLD_RC_PRESENT=1 766114501Sdougb break 767114501Sdougb fi 768114501Sdougbdone 769114501Sdougb 770114501Sdougbcase "${OLD_RC_PRESENT}" in 771114501Sdougb1) 77252400Sbillf echo '' 773114501Sdougb echo " *** There are elements of the old rc system in ${DESTDIR}/etc/." 77467949Sdougb echo '' 775114501Sdougb echo ' While these scripts will not hurt anything, they are not' 776114501Sdougb echo ' functional on an up to date system, and can be removed.' 77767949Sdougb echo '' 778114501Sdougb 77952400Sbillf case "${AUTO_RUN}" in 78052400Sbillf '') 781114501Sdougb echo -n 'Move these files to /var/tmp/mergemaster/old_rc? [yes] ' 782114501Sdougb read MOVE_OLD_RC 78367859Sdougb 784114501Sdougb case "${MOVE_OLD_RC}" in 785114501Sdougb [nN]*) ;; 78652400Sbillf *) 787114501Sdougb mkdir -p /var/tmp/mergemaster/old_rc 788179315Sbz for file in atm devfs diskless1 diskless2 network network6 pccard \ 789114523Sdougb serial syscons sysctl alpha amd64 i386 ia64 sparc64; do 790114501Sdougb if [ -f "${DESTDIR}/etc/rc.${file}" ]; then 791114501Sdougb mv ${DESTDIR}/etc/rc.${file} /var/tmp/mergemaster/old_rc/ 792114501Sdougb fi 793114501Sdougb done 794114501Sdougb echo ' The files have been moved' 795114501Sdougb press_to_continue 79652400Sbillf ;; 79752400Sbillf esac 79852400Sbillf ;; 79952400Sbillf *) ;; 80052400Sbillf esac 801114501Sdougbesac 80252400Sbillf 80398084Sdougb# Use the umask/mode information to install the files 80452400Sbillf# Create directories as needed 80552400Sbillf# 806186678Sdougbinstall_error () { 807186678Sdougb echo "*** FATAL ERROR: Unable to install ${1} to ${2}" 808186678Sdougb echo '' 809186678Sdougb exit 1 810186678Sdougb} 811186678Sdougb 81278490Sdougbdo_install_and_rm () { 813114501Sdougb case "${PRESERVE_FILES}" in 814114501Sdougb [Yy][Ee][Ss]) 815114501Sdougb if [ -f "${3}/${2##*/}" ]; then 816114565Sdougb mkdir -p ${PRESERVE_FILES_DIR}/${2%/*} 817114565Sdougb cp ${3}/${2##*/} ${PRESERVE_FILES_DIR}/${2%/*} 818114501Sdougb fi 819114501Sdougb ;; 820114501Sdougb esac 821114501Sdougb 822186678Sdougb if [ ! -d "${3}/${2##*/}" ]; then 823186678Sdougb if install -m ${1} ${2} ${3}; then 824186678Sdougb unlink ${2} 825186678Sdougb else 826186678Sdougb install_error ${2} ${3} 827186678Sdougb fi 828186678Sdougb else 829186678Sdougb install_error ${2} ${3} 830186678Sdougb fi 83178490Sdougb} 83278490Sdougb 83398084Sdougb# 4095 = "obase=10;ibase=8;07777" | bc 83498084Sdougbfind_mode () { 83598084Sdougb local OCTAL 83698084Sdougb OCTAL=$(( ~$(echo "obase=10; ibase=8; ${CONFIRMED_UMASK}" | bc) & 4095 & 837124053Sdougb $(echo "obase=10; ibase=8; $(stat -f "%OMp%OLp" ${1})" | bc) )) 83898084Sdougb printf "%04o\n" ${OCTAL} 83998084Sdougb} 84098084Sdougb 84152400Sbillfmm_install () { 84252400Sbillf local INSTALL_DIR 84352400Sbillf INSTALL_DIR=${1#.} 84452400Sbillf INSTALL_DIR=${INSTALL_DIR%/*} 84567949Sdougb 84652400Sbillf case "${INSTALL_DIR}" in 84752400Sbillf '') 84852400Sbillf INSTALL_DIR=/ 84952400Sbillf ;; 85052400Sbillf esac 85152400Sbillf 85267949Sdougb if [ -n "${DESTDIR}${INSTALL_DIR}" -a ! -d "${DESTDIR}${INSTALL_DIR}" ]; then 85398084Sdougb DIR_MODE=`find_mode "${TEMPROOT}/${INSTALL_DIR}"` 854200425Sdougb install -d -o root -g wheel -m "${DIR_MODE}" "${DESTDIR}${INSTALL_DIR}" || 855200425Sdougb install_error $1 ${DESTDIR}${INSTALL_DIR} 85652400Sbillf fi 85752400Sbillf 85898084Sdougb FILE_MODE=`find_mode "${1}"` 85952400Sbillf 86052400Sbillf if [ ! -x "${1}" ]; then 86152400Sbillf case "${1#.}" in 86264625Sgshapiro /etc/mail/aliases) 86352400Sbillf NEED_NEWALIASES=yes 86452400Sbillf ;; 86552400Sbillf /etc/login.conf) 86652400Sbillf NEED_CAP_MKDB=yes 86752400Sbillf ;; 868207612Snork /etc/services) 869207612Snork NEED_SERVICES_MKDB=yes 870207612Snork ;; 87152400Sbillf /etc/master.passwd) 87278490Sdougb do_install_and_rm 600 "${1}" "${DESTDIR}${INSTALL_DIR}" 87352400Sbillf NEED_PWD_MKDB=yes 87452400Sbillf DONT_INSTALL=yes 87552400Sbillf ;; 87652400Sbillf /.cshrc | /.profile) 877200708Sdougb local st_nlink 878200708Sdougb 879200708Sdougb # install will unlink the file before it installs the new one, 880200708Sdougb # so we have to restore/create the link afterwards. 881200708Sdougb # 882200708Sdougb st_nlink=0 # In case the file does not yet exist 883200708Sdougb eval $(stat -s ${DESTDIR}${COMPFILE#.} 2>/dev/null) 884200708Sdougb 885200708Sdougb do_install_and_rm "${FILE_MODE}" "${1}" "${DESTDIR}${INSTALL_DIR}" 886200708Sdougb 887200708Sdougb if [ -n "${AUTO_INSTALL}" -a $st_nlink -gt 1 ]; then 888200708Sdougb HANDLE_LINK=l 889200708Sdougb else 890200701Sdougb case "${LINK_EXPLAINED}" in 891200701Sdougb '') 892200701Sdougb echo " *** Historically BSD derived systems have had a" 893200701Sdougb echo " hard link from /.cshrc and /.profile to" 894200701Sdougb echo " their namesakes in /root. Please indicate" 895200701Sdougb echo " your preference below for bringing your" 896200701Sdougb echo " installed files up to date." 897200701Sdougb echo '' 898200701Sdougb LINK_EXPLAINED=yes 899200701Sdougb ;; 900200701Sdougb esac 901200701Sdougb 902200701Sdougb echo " Use 'd' to delete the temporary ${COMPFILE}" 903200708Sdougb echo " Use 'l' to delete the existing ${DESTDIR}/root/${COMPFILE##*/} and create the link" 90452400Sbillf echo '' 905200701Sdougb echo " Default is to leave the temporary file to deal with by hand" 906200701Sdougb echo '' 907200701Sdougb echo -n " How should I handle ${COMPFILE}? [Leave it to install later] " 908200701Sdougb read HANDLE_LINK 909200708Sdougb fi 91052400Sbillf 91152400Sbillf case "${HANDLE_LINK}" in 91252400Sbillf [dD]*) 91352400Sbillf rm "${COMPFILE}" 91452400Sbillf echo '' 91552400Sbillf echo " *** Deleting ${COMPFILE}" 91652400Sbillf ;; 91752400Sbillf [lL]*) 91852400Sbillf echo '' 919200708Sdougb unlink ${DESTDIR}/root/${COMPFILE##*/} 920200708Sdougb if ln ${DESTDIR}${COMPFILE#.} ${DESTDIR}/root/${COMPFILE##*/}; then 92167949Sdougb echo " *** Link from ${DESTDIR}${COMPFILE#.} to ${DESTDIR}/root/${COMPFILE##*/} installed successfully" 92252400Sbillf else 923200708Sdougb echo " *** Error linking ${DESTDIR}${COMPFILE#.} to ${DESTDIR}/root/${COMPFILE##*/}" 924200708Sdougb echo " *** ${COMPFILE} will remain for your consideration" 92552400Sbillf fi 92652400Sbillf ;; 92752400Sbillf *) 92852400Sbillf echo " *** ${COMPFILE} will remain for your consideration" 92952400Sbillf ;; 93052400Sbillf esac 931200708Sdougb return 93252400Sbillf ;; 93352400Sbillf esac 93452400Sbillf 93552400Sbillf case "${DONT_INSTALL}" in 93652400Sbillf '') 93778490Sdougb do_install_and_rm "${FILE_MODE}" "${1}" "${DESTDIR}${INSTALL_DIR}" 93852400Sbillf ;; 93952400Sbillf *) 94052400Sbillf unset DONT_INSTALL 94152400Sbillf ;; 94252400Sbillf esac 94378490Sdougb else # File matched -x 94478490Sdougb do_install_and_rm "${FILE_MODE}" "${1}" "${DESTDIR}${INSTALL_DIR}" 94552400Sbillf fi 94652400Sbillf return $? 94752400Sbillf} 94852400Sbillf 949174841Sdougbif [ ! -d "${TEMPROOT}" ]; then 950174841Sdougb echo "*** FATAL ERROR: The temproot directory (${TEMPROOT})" 951174841Sdougb echo ' has disappeared!' 952174841Sdougb echo '' 953174841Sdougb exit 1 954174841Sdougbfi 955174841Sdougb 95667949Sdougbecho '' 95767949Sdougbecho "*** Beginning comparison" 95867949Sdougbecho '' 95952400Sbillf 960124136Sdougb# Pre-world does not populate /etc/rc.d. 961124053Sdougb# It is very possible that a previous run would have deleted files in 962124053Sdougb# ${TEMPROOT}/etc/rc.d, thus creating a lot of false positives. 963124136Sdougbif [ -z "${PRE_WORLD}" -a -z "${RERUN}" ]; then 964124053Sdougb echo " *** Checking ${DESTDIR}/etc/rc.d for stale files" 965124053Sdougb echo '' 966124053Sdougb cd "${DESTDIR}/etc/rc.d" && 967124053Sdougb for file in *; do 968124053Sdougb if [ ! -e "${TEMPROOT}/etc/rc.d/${file}" ]; then 969124053Sdougb STALE_RC_FILES="${STALE_RC_FILES} ${file}" 970124053Sdougb fi 971124053Sdougb done 972124053Sdougb case "${STALE_RC_FILES}" in 973126718Sdougb ''|' *') 974124053Sdougb echo ' *** No stale files found' 975124053Sdougb ;; 976124053Sdougb *) 977124053Sdougb echo " *** The following files exist in ${DESTDIR}/etc/rc.d but not in" 978124053Sdougb echo " ${TEMPROOT}/etc/rc.d/:" 979124053Sdougb echo '' 980124053Sdougb echo "${STALE_RC_FILES}" 981124053Sdougb echo '' 982124053Sdougb echo ' The presence of stale files in this directory can cause the' 983124053Sdougb echo ' dreaded unpredictable results, and therefore it is highly' 984124053Sdougb echo ' recommended that you delete them.' 985124053Sdougb case "${AUTO_RUN}" in 986124053Sdougb '') 987124053Sdougb echo '' 988153604Sdougb echo -n ' *** Delete them now? [n] ' 989124053Sdougb read DELETE_STALE_RC_FILES 990124053Sdougb case "${DELETE_STALE_RC_FILES}" in 991153604Sdougb [yY]) 992124053Sdougb echo ' *** Deleting ... ' 993124053Sdougb rm ${STALE_RC_FILES} 994124053Sdougb echo ' done.' 995124053Sdougb ;; 996153604Sdougb *) 997153604Sdougb echo ' *** Files will not be deleted' 998153604Sdougb ;; 999124053Sdougb esac 1000124053Sdougb sleep 2 1001124053Sdougb ;; 1002201291Sdougb *) 1003201291Sdougb if [ -n "${DELETE_STALE_RC_FILES}" ]; then 1004201291Sdougb echo ' *** Deleting ... ' 1005201291Sdougb rm ${STALE_RC_FILES} 1006201291Sdougb echo ' done.' 1007201291Sdougb fi 1008124053Sdougb esac 1009124053Sdougb ;; 1010124053Sdougb esac 1011124053Sdougb echo '' 1012124136Sdougbfi 1013124053Sdougb 101467949Sdougbcd "${TEMPROOT}" 101567949Sdougb 101667949Sdougbif [ -r "${MM_PRE_COMPARE_SCRIPT}" ]; then 101767949Sdougb . "${MM_PRE_COMPARE_SCRIPT}" 101867949Sdougbfi 101967949Sdougb 1020200425Sdougb# Things that were files/directories/links in one version can sometimes 1021200425Sdougb# change to something else in a newer version. So we need to explicitly 1022200425Sdougb# test for this, and warn the user if what we find does not match. 1023200425Sdougb# 1024200700Sdougbfor COMPFILE in `find . | sort` ; do 1025200425Sdougb if [ -e "${DESTDIR}${COMPFILE#.}" ]; then 1026200425Sdougb INSTALLED_TYPE=`stat -f '%HT' ${DESTDIR}${COMPFILE#.}` 1027200425Sdougb else 1028200425Sdougb continue 1029200425Sdougb fi 1030200425Sdougb TEMPROOT_TYPE=`stat -f '%HT' $COMPFILE` 1031200425Sdougb 1032200425Sdougb if [ ! "$TEMPROOT_TYPE" = "$INSTALLED_TYPE" ]; then 1033200425Sdougb [ "$COMPFILE" = '.' ] && continue 1034200425Sdougb TEMPROOT_TYPE=`echo $TEMPROOT_TYPE | tr [:upper:] [:lower:]` 1035200425Sdougb INSTALLED_TYPE=`echo $INSTALLED_TYPE | tr [:upper:] [:lower:]` 1036200425Sdougb 1037200425Sdougb echo "*** The installed file ${DESTDIR}${COMPFILE#.} has the type \"$INSTALLED_TYPE\"" 1038200425Sdougb echo " but the new version has the type \"$TEMPROOT_TYPE\"" 1039200425Sdougb echo '' 1040200425Sdougb echo " How would you like to handle this?" 1041200425Sdougb echo '' 1042200425Sdougb echo " Use 'r' to remove ${DESTDIR}${COMPFILE#.}" 1043200425Sdougb case "$TEMPROOT_TYPE" in 1044200425Sdougb 'symbolic link') 1045200425Sdougb TARGET=`readlink $COMPFILE` 1046200425Sdougb echo " and create a link to $TARGET in its place" ;; 1047200425Sdougb *) echo " You will be able to install it as a \"$TEMPROOT_TYPE\"" ;; 1048200425Sdougb esac 1049200425Sdougb echo '' 1050200425Sdougb echo " Use 'i' to ignore this" 1051200425Sdougb echo '' 1052200425Sdougb echo -n " How to proceed? [i] " 1053200425Sdougb read ANSWER 1054200425Sdougb case "$ANSWER" in 1055200425Sdougb [rR]) case "${PRESERVE_FILES}" in 1056200425Sdougb [Yy][Ee][Ss]) 1057200425Sdougb mv ${DESTDIR}${COMPFILE#.} ${PRESERVE_FILES_DIR}/ || exit 1 ;; 1058200425Sdougb *) rm -rf ${DESTDIR}${COMPFILE#.} ;; 1059200425Sdougb esac 1060200425Sdougb case "$TEMPROOT_TYPE" in 1061200425Sdougb 'symbolic link') ln -sf $TARGET ${DESTDIR}${COMPFILE#.} ;; 1062200425Sdougb esac ;; 1063200425Sdougb *) echo '' 1064200425Sdougb echo "*** See the man page about adding ${COMPFILE#.} to the list of IGNORE_FILES" 1065200425Sdougb press_to_continue ;; 1066200425Sdougb esac 1067200425Sdougb echo '' 1068200425Sdougb fi 1069200425Sdougbdone 1070200425Sdougb 1071200700Sdougbfor COMPFILE in `find . -type f | sort`; do 107267949Sdougb 107367949Sdougb # First, check to see if the file exists in DESTDIR. If not, the 107467949Sdougb # diff_loop function knows how to handle it. 107567949Sdougb # 107667949Sdougb if [ ! -e "${DESTDIR}${COMPFILE#.}" ]; then 107777325Sdougb case "${AUTO_RUN}" in 107877325Sdougb '') 107977325Sdougb diff_loop 108077325Sdougb ;; 108177325Sdougb *) 108277325Sdougb case "${AUTO_INSTALL}" in 108377325Sdougb '') 108477325Sdougb # If this is an auto run, make it official 108577325Sdougb echo " *** ${COMPFILE} will remain for your consideration" 108677325Sdougb ;; 108777325Sdougb *) 108877325Sdougb diff_loop 108977325Sdougb ;; 109077325Sdougb esac 109177325Sdougb ;; 109277325Sdougb esac # Auto run test 109367949Sdougb continue 109467949Sdougb fi 109567949Sdougb 109652400Sbillf case "${STRICT}" in 109752400Sbillf '' | [Nn][Oo]) 1098241337Sdougb # Compare $Id's first so if the file hasn't been modified 109952400Sbillf # local changes will be ignored. 110052400Sbillf # If the files have the same $Id, delete the one in temproot so the 110152400Sbillf # user will have less to wade through if files are left to merge by hand. 110252400Sbillf # 1103241337Sdougb ID1=`grep "[$]${ID_TAG}:" ${DESTDIR}${COMPFILE#.} 2>/dev/null` 1104241337Sdougb ID2=`grep "[$]${ID_TAG}:" ${COMPFILE} 2>/dev/null` || ID2=none 110552400Sbillf 1106241337Sdougb case "${ID2}" in 1107241337Sdougb "${ID1}") 1108241337Sdougb echo " *** Temp ${COMPFILE} and installed have the same Id, deleting" 110967949Sdougb rm "${COMPFILE}" 111067949Sdougb ;; 111167949Sdougb esac 111252400Sbillf ;; 111352400Sbillf esac 111452400Sbillf 111552400Sbillf # If the file is still here either because the $Ids are different, the 111652400Sbillf # file doesn't have an $Id, or we're using STRICT mode; look at the diff. 111752400Sbillf # 111852400Sbillf if [ -f "${COMPFILE}" ]; then 111952400Sbillf 112052400Sbillf # Do an absolute diff first to see if the files are actually different. 112152400Sbillf # If they're not different, delete the one in temproot. 112252400Sbillf # 1123110377Sdougb if diff -q ${DIFF_OPTIONS} "${DESTDIR}${COMPFILE#.}" "${COMPFILE}" > \ 1124110377Sdougb /dev/null 2>&1; then 112552400Sbillf echo " *** Temp ${COMPFILE} and installed are the same, deleting" 112652400Sbillf rm "${COMPFILE}" 112752400Sbillf else 112877323Sdougb # Ok, the files are different, so show the user where they differ. 112977323Sdougb # Use user's choice of diff methods; and user's pager if they have one. 113077323Sdougb # Use more if not. 113167859Sdougb # Use unified diffs by default. Context diffs give me a headache. :) 113252400Sbillf # 1133189992Sdougb # If the user chose the -F option, test for that before proceeding 1134189992Sdougb # 1135189992Sdougb if [ -n "$FREEBSD_ID" ]; then 1136201291Sdougb if diff -q -I'[$]FreeBSD.*[$]' "${DESTDIR}${COMPFILE#.}" "${COMPFILE}" > \ 1137189992Sdougb /dev/null 2>&1; then 1138189992Sdougb if mm_install "${COMPFILE}"; then 1139189992Sdougb echo "*** Updated revision control Id for ${DESTDIR}${COMPFILE#.}" 1140189992Sdougb else 1141189992Sdougb echo "*** Problem installing ${COMPFILE}, it will remain to merge by hand later" 1142189992Sdougb fi 1143189992Sdougb continue 1144189992Sdougb fi 1145189992Sdougb fi 114652400Sbillf case "${AUTO_RUN}" in 114752400Sbillf '') 114858910Salfred # prompt user to install/delete/merge changes 114958910Salfred diff_loop 115052400Sbillf ;; 115152400Sbillf *) 115252400Sbillf # If this is an auto run, make it official 115352400Sbillf echo " *** ${COMPFILE} will remain for your consideration" 115452400Sbillf ;; 115552400Sbillf esac # Auto run test 115652400Sbillf fi # Yes, the files are different 115752400Sbillf fi # Yes, the file still remains to be checked 1158189763Sdougbdone # This is for the for way up there at the beginning of the comparison 115952400Sbillf 116052534Sbillfecho '' 116152400Sbillfecho "*** Comparison complete" 1162158149Sgordon 1163192230Sdougbif [ -s "${MTREENEW}" ]; then 1164158149Sgordon echo "*** Saving mtree database for future upgrades" 1165200416Sdougb test -e "${MTREEFILE}" && unlink ${MTREEFILE} 1166200416Sdougb mv ${MTREENEW} ${MTREEFILE} 1167158149Sgordonfi 1168158149Sgordon 116952400Sbillfecho '' 117052400Sbillf 117152400SbillfTEST_FOR_FILES=`find ${TEMPROOT} -type f -size +0 2>/dev/null` 117252400Sbillfif [ -n "${TEST_FOR_FILES}" ]; then 117352400Sbillf echo "*** Files that remain for you to merge by hand:" 1174200700Sdougb find "${TEMPROOT}" -type f -size +0 | sort 117577335Sdougb echo '' 117652400Sbillf 1177201765Sdougb case "${AUTO_RUN}" in 1178201765Sdougb '') 1179201765Sdougb echo -n "Do you wish to delete what is left of ${TEMPROOT}? [no] " 1180201765Sdougb read DEL_TEMPROOT 1181201765Sdougb case "${DEL_TEMPROOT}" in 1182201765Sdougb [yY]*) 1183201765Sdougb delete_temproot 1184201765Sdougb ;; 1185201765Sdougb *) 1186201765Sdougb echo " *** ${TEMPROOT} will remain" 1187201765Sdougb ;; 1188201765Sdougb esac 118952400Sbillf ;; 1190201765Sdougb *) ;; 119152400Sbillf esac 1192201765Sdougbelse 1193201765Sdougb echo "*** ${TEMPROOT} is empty, deleting" 1194201765Sdougb delete_temproot 1195201765Sdougbfi 119652400Sbillf 119768153Sdougbcase "${AUTO_INSTALLED_FILES}" in 119868153Sdougb'') ;; 119968153Sdougb*) 120073651Sdougb case "${AUTO_RUN}" in 120173651Sdougb '') 120273651Sdougb ( 120373651Sdougb echo '' 120477323Sdougb echo '*** You chose the automatic install option for files that did not' 120577323Sdougb echo ' exist on your system. The following were installed for you:' 120673651Sdougb echo "${AUTO_INSTALLED_FILES}" 120773651Sdougb ) | ${PAGER} 120873651Sdougb ;; 120973651Sdougb *) 121068153Sdougb echo '' 121177323Sdougb echo '*** You chose the automatic install option for files that did not' 121277323Sdougb echo ' exist on your system. The following were installed for you:' 121368153Sdougb echo "${AUTO_INSTALLED_FILES}" 121473651Sdougb ;; 121573651Sdougb esac 121668153Sdougb ;; 121768153Sdougbesac 121868153Sdougb 1219158149Sgordoncase "${AUTO_UPGRADED_FILES}" in 1220158149Sgordon'') ;; 1221158149Sgordon*) 1222158149Sgordon case "${AUTO_RUN}" in 1223158149Sgordon '') 1224158149Sgordon ( 1225158149Sgordon echo '' 1226158149Sgordon echo '*** You chose the automatic upgrade option for files that you did' 1227158149Sgordon echo ' not alter on your system. The following were upgraded for you:' 1228158149Sgordon echo "${AUTO_UPGRADED_FILES}" 1229158149Sgordon ) | ${PAGER} 1230158149Sgordon ;; 1231158149Sgordon *) 1232158149Sgordon echo '' 1233158149Sgordon echo '*** You chose the automatic upgrade option for files that you did' 1234158149Sgordon echo ' not alter on your system. The following were upgraded for you:' 1235158149Sgordon echo "${AUTO_UPGRADED_FILES}" 1236158149Sgordon ;; 1237158149Sgordon esac 1238158149Sgordon ;; 1239158149Sgordonesac 1240158149Sgordon 124173651Sdougbrun_it_now () { 1242227145Sdougb [ -n "$AUTO_RUN" ] && return 124373651Sdougb 1244227145Sdougb local answer 1245227145Sdougb 1246227145Sdougb echo '' 1247227145Sdougb while : ; do 1248227145Sdougb if [ "$RUN_UPDATES" = always ]; then 1249227145Sdougb answer=y 1250227145Sdougb elif [ "$RUN_UPDATES" = never ]; then 1251227145Sdougb answer=n 1252227145Sdougb else 1253227145Sdougb echo -n ' Would you like to run it now? y or n [n] ' 1254227145Sdougb read answer 1255227145Sdougb fi 1256227145Sdougb 1257227145Sdougb case "$answer" in 125873651Sdougb y) 125977335Sdougb echo " Running ${1}" 126077335Sdougb echo '' 126173651Sdougb eval "${1}" 1262227145Sdougb return 126373651Sdougb ;; 126477335Sdougb ''|n) 1265227145Sdougb if [ ! "$RUN_UPDATES" = never ]; then 1266227145Sdougb echo '' 1267227145Sdougb echo " *** Cancelled" 1268227145Sdougb echo '' 1269227145Sdougb fi 127077335Sdougb echo " Make sure to run ${1} yourself" 1271227145Sdougb return 127277335Sdougb ;; 127373651Sdougb *) 127477335Sdougb echo '' 1275227145Sdougb echo " *** Sorry, I do not understand your answer (${answer})" 127677335Sdougb echo '' 127773651Sdougb esac 1278227145Sdougb done 127973651Sdougb} 128073651Sdougb 128152400Sbillfcase "${NEED_NEWALIASES}" in 128252400Sbillf'') ;; 128352400Sbillf*) 128452400Sbillf echo '' 128577335Sdougb if [ -n "${DESTDIR}" ]; then 128677335Sdougb echo "*** You installed a new aliases file into ${DESTDIR}/etc/mail, but" 128777335Sdougb echo " the newaliases command is limited to the directories configured" 128877335Sdougb echo " in sendmail.cf. Make sure to create your aliases database by" 128977335Sdougb echo " hand when your sendmail configuration is done." 129077335Sdougb else 129177335Sdougb echo "*** You installed a new aliases file, so make sure that you run" 129277335Sdougb echo " '/usr/bin/newaliases' to rebuild your aliases database" 129377335Sdougb run_it_now '/usr/bin/newaliases' 129477335Sdougb fi 129552400Sbillf ;; 129652400Sbillfesac 129752400Sbillf 129852400Sbillfcase "${NEED_CAP_MKDB}" in 129952400Sbillf'') ;; 130052400Sbillf*) 130152400Sbillf echo '' 130252400Sbillf echo "*** You installed a login.conf file, so make sure that you run" 130377335Sdougb echo " '/usr/bin/cap_mkdb ${DESTDIR}/etc/login.conf'" 130477335Sdougb echo " to rebuild your login.conf database" 130577335Sdougb run_it_now "/usr/bin/cap_mkdb ${DESTDIR}/etc/login.conf" 130652400Sbillf ;; 130752400Sbillfesac 130852400Sbillf 1309207612Snorkcase "${NEED_SERVICES_MKDB}" in 1310207612Snork'') ;; 1311207612Snork*) 1312207612Snork echo '' 1313207612Snork echo "*** You installed a services file, so make sure that you run" 1314207612Snork echo " '/usr/sbin/services_mkdb -q -o ${DESTDIR}/var/db/services.db ${DESTDIR}/etc/services'" 1315207612Snork echo " to rebuild your services database" 1316207612Snork run_it_now "/usr/sbin/services_mkdb -q -o ${DESTDIR}/var/db/services.db ${DESTDIR}/etc/services" 1317207612Snork ;; 1318207612Snorkesac 1319207612Snork 132052400Sbillfcase "${NEED_PWD_MKDB}" in 132152400Sbillf'') ;; 132252400Sbillf*) 132352400Sbillf echo '' 132452400Sbillf echo "*** You installed a new master.passwd file, so make sure that you run" 132577335Sdougb if [ -n "${DESTDIR}" ]; then 132677335Sdougb echo " '/usr/sbin/pwd_mkdb -d ${DESTDIR}/etc -p ${DESTDIR}/etc/master.passwd'" 132777335Sdougb echo " to rebuild your password files" 132877335Sdougb run_it_now "/usr/sbin/pwd_mkdb -d ${DESTDIR}/etc -p ${DESTDIR}/etc/master.passwd" 132977335Sdougb else 133077335Sdougb echo " '/usr/sbin/pwd_mkdb -p /etc/master.passwd'" 133177335Sdougb echo " to rebuild your password files" 133277335Sdougb run_it_now '/usr/sbin/pwd_mkdb -p /etc/master.passwd' 133377335Sdougb fi 133452400Sbillf ;; 133552400Sbillfesac 133652400Sbillf 1337241337Sdougbif [ -e "${DESTDIR}/etc/localtime" -a -z "${PRE_WORLD}" ]; then # Ignore if TZ == UTC 1338227145Sdougb echo '' 1339228169Sdougb [ -n "${DESTDIR}" ] && tzs_args="-C ${DESTDIR}" 1340227145Sdougb if [ -f "${DESTDIR}/var/db/zoneinfo" ]; then 1341227145Sdougb echo "*** Reinstalling `cat ${DESTDIR}/var/db/zoneinfo` as ${DESTDIR}/etc/localtime" 1342227145Sdougb tzsetup $tzs_args -r 1343227145Sdougb else 1344227145Sdougb echo "*** There is no ${DESTDIR}/var/db/zoneinfo file to update ${DESTDIR}/etc/localtime." 1345227145Sdougb echo ' You should run tzsetup' 1346228169Sdougb run_it_now "tzsetup $tzs_args" 1347227145Sdougb fi 1348227145Sdougbfi 1349227145Sdougb 135052400Sbillfecho '' 135152400Sbillf 135267949Sdougbif [ -r "${MM_EXIT_SCRIPT}" ]; then 135367949Sdougb . "${MM_EXIT_SCRIPT}" 135467949Sdougbfi 135567949Sdougb 135691193Sdougbcase "${COMP_CONFS}" in 135791193Sdougb'') ;; 135891193Sdougb*) 135991193Sdougb . ${DESTDIR}/etc/defaults/rc.conf 136091193Sdougb 136191193Sdougb (echo '' 136291193Sdougb echo "*** Comparing conf files: ${rc_conf_files}" 136391193Sdougb 136491193Sdougb for CONF_FILE in ${rc_conf_files}; do 136591193Sdougb if [ -r "${DESTDIR}${CONF_FILE}" ]; then 136691193Sdougb echo '' 136791193Sdougb echo "*** From ${DESTDIR}${CONF_FILE}" 136891193Sdougb echo "*** From ${DESTDIR}/etc/defaults/rc.conf" 136991193Sdougb 137091193Sdougb for RC_CONF_VAR in `grep -i ^[a-z] ${DESTDIR}${CONF_FILE} | 137191193Sdougb cut -d '=' -f 1`; do 137291193Sdougb echo '' 137391223Sdougb grep -w ^${RC_CONF_VAR} ${DESTDIR}${CONF_FILE} 137491223Sdougb grep -w ^${RC_CONF_VAR} ${DESTDIR}/etc/defaults/rc.conf || 137591193Sdougb echo ' * No default variable with this name' 137691193Sdougb done 137791193Sdougb fi 137891193Sdougb done) | ${PAGER} 137991193Sdougb echo '' 138091193Sdougb ;; 138191193Sdougbesac 138291193Sdougb 1383200425Sdougbif [ -n "${PRESERVE_FILES}" ]; then 1384200425Sdougb find -d $PRESERVE_FILES_DIR -type d -empty -delete 2>/dev/null 1385200425Sdougb rmdir $PRESERVE_FILES_DIR 2>/dev/null 1386200425Sdougbfi 1387200425Sdougb 138852400Sbillfexit 0 1389241337Sdougb 1390241337Sdougb#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1391241337Sdougb 1392241337Sdougb# Copyright (c) 1998-2012 Douglas Barton 1393241337Sdougb# All rights reserved. 1394241337Sdougb# 1395241337Sdougb# Redistribution and use in source and binary forms, with or without 1396241337Sdougb# modification, are permitted provided that the following conditions 1397241337Sdougb# are met: 1398241337Sdougb# 1. Redistributions of source code must retain the above copyright 1399241337Sdougb# notice, this list of conditions and the following disclaimer. 1400241337Sdougb# 2. Redistributions in binary form must reproduce the above copyright 1401241337Sdougb# notice, this list of conditions and the following disclaimer in the 1402241337Sdougb# documentation and/or other materials provided with the distribution. 1403241337Sdougb# 1404241337Sdougb# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1405241337Sdougb# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1406241337Sdougb# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1407241337Sdougb# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1408241337Sdougb# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1409241337Sdougb# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 1410241337Sdougb# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 1411241337Sdougb# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 1412241337Sdougb# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 1413241337Sdougb# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 1414241337Sdougb# SUCH DAMAGE. 1415