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$ 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 echo " Use 'l' to set PAGER to 'less' for this run" 42552400Sbillf echo " Use 'm' to use plain old 'more' as your PAGER for this run" 42652400Sbillf echo '' 427244461Seadler echo " or you may type an absolute path to PAGER for this run" 428244461Seadler 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]) 439244454Seadler PAGER=less 44052400Sbillf ;; 44160420Sbsd [mM]|'') 44252400Sbillf PAGER=more 44352400Sbillf ;; 444244461Seadler /*) 445244461Seadler PAGER="$FIXPAGER" 446244461Seadler ;; 44758910Salfred *) 44858910Salfred echo '' 44958910Salfred echo "invalid choice: ${FIXPAGER}" 45052400Sbillf esac 45152400Sbillf echo '' 45258910Salfred done 453186695Sdougb} 454186695Sdougb if [ -n "${PAGER}" ]; then 455186695Sdougb check_pager 456186695Sdougb fi 45752400Sbillf ;; 45852400Sbillfesac 45952400Sbillf 46052400Sbillf# If user has a pager defined, or got assigned one above, use it. 46152400Sbillf# If not, use more. 46252400Sbillf# 46352400SbillfPAGER=${PAGER:-more} 46452400Sbillf 46552400Sbillfif [ -n "${VERBOSE}" -a ! "${PAGER}" = "more" ]; then 46652400Sbillf echo " *** You have ${PAGER} defined as your pager so we will use that" 46752400Sbillf echo '' 46852400Sbillf sleep 3 46952400Sbillffi 47052400Sbillf 47152400Sbillf# Assign the diff flag once so we will not have to keep testing it 47252400Sbillf# 47352400SbillfDIFF_FLAG=${DIFF_FLAG:--u} 47452400Sbillf 47552400Sbillf# Assign the source directory 47652400Sbillf# 477186678SdougbSOURCEDIR=${SOURCEDIR:-/usr/src} 478186678Sdougbif [ ! -f ${SOURCEDIR}/Makefile.inc1 -a \ 479186678Sdougb -f ${SOURCEDIR}/../Makefile.inc1 ]; then 480186678Sdougb echo " *** The source directory you specified (${SOURCEDIR})" 481186678Sdougb echo " will be reset to ${SOURCEDIR}/.." 482186678Sdougb echo '' 483186678Sdougb sleep 3 484186678Sdougb SOURCEDIR=${SOURCEDIR}/.. 485186678Sdougbfi 486250583SeadlerSOURCEDIR=$(realpath "$SOURCEDIR") 48752400Sbillf 488186678Sdougb# Setup make to use system files from SOURCEDIR 489186695SdougbMM_MAKE="make ${ARCHSTRING} -m ${SOURCEDIR}/share/mk" 490186678Sdougb 491158149Sgordon# Check DESTDIR against the mergemaster mtree database to see what 492158149Sgordon# files the user changed from the reference files. 493158149Sgordon# 494200416Sdougbif [ -n "${AUTO_UPGRADE}" -a -s "${MTREEFILE}" ]; then 495192230Sdougb CHANGED=: 496200416Sdougb for file in `mtree -eqL -f ${MTREEFILE} -p ${DESTDIR}/ \ 497158149Sgordon 2>/dev/null | awk '($2 == "changed") {print $1}'`; do 498158149Sgordon if [ -f "${DESTDIR}/$file" ]; then 499192230Sdougb CHANGED="${CHANGED}${DESTDIR}/${file}:" 500158149Sgordon fi 501158149Sgordon done 502192230Sdougb [ "$CHANGED" = ':' ] && unset CHANGED 503158149Sgordonfi 504158149Sgordon 50596045Sdougb# Check the width of the user's terminal 50696045Sdougb# 50796045Sdougbif [ -t 0 ]; then 508110377Sdougb w=`tput columns` 50996045Sdougb case "${w}" in 51096045Sdougb 0|'') ;; # No-op, since the input is not valid 51196045Sdougb *) 51296045Sdougb case "${SCREEN_WIDTH}" in 51396045Sdougb '') SCREEN_WIDTH="${w}" ;; 51496045Sdougb "${w}") ;; # No-op, since they are the same 51596045Sdougb *) 51696045Sdougb echo -n "*** You entered ${SCREEN_WIDTH} as your screen width, but stty " 51796045Sdougb echo "thinks it is ${w}." 51896045Sdougb echo '' 51996045Sdougb echo -n "What would you like to use? [${w}] " 52096045Sdougb read SCREEN_WIDTH 52197380Sdougb case "${SCREEN_WIDTH}" in 52297380Sdougb '') SCREEN_WIDTH="${w}" ;; 52397380Sdougb esac 52496045Sdougb ;; 52596045Sdougb esac 52696045Sdougb esac 52796045Sdougbfi 52896045Sdougb 529241337Sdougb# Define what $Id tag to look for to aid portability. 53073651Sdougb# 531241337SdougbID_TAG=FreeBSD 53273651Sdougb 53399152Sdougbdelete_temproot () { 534101362Sdougb rm -rf "${TEMPROOT}" 2>/dev/null 535101362Sdougb chflags -R 0 "${TEMPROOT}" 2>/dev/null 536201765Sdougb rm -rf "${TEMPROOT}" || { echo "*** Unable to delete ${TEMPROOT}"; exit 1; } 53799152Sdougb} 53899152Sdougb 53952400Sbillfcase "${RERUN}" in 54052400Sbillf'') 54152400Sbillf # Set up the loop to test for the existence of the 54252400Sbillf # temp root directory. 54352400Sbillf # 54452400Sbillf TEST_TEMP_ROOT=yes 54552400Sbillf while [ "${TEST_TEMP_ROOT}" = "yes" ]; do 54652400Sbillf if [ -d "${TEMPROOT}" ]; then 54752400Sbillf echo "*** The directory specified for the temporary root environment," 54867859Sdougb echo " ${TEMPROOT}, exists. This can be a security risk if untrusted" 54952400Sbillf echo " users have access to the system." 55052400Sbillf echo '' 55152400Sbillf case "${AUTO_RUN}" in 55252400Sbillf '') 55352400Sbillf echo " Use 'd' to delete the old ${TEMPROOT} and continue" 55452400Sbillf echo " Use 't' to select a new temporary root directory" 55552400Sbillf echo " Use 'e' to exit mergemaster" 55652400Sbillf echo '' 55752400Sbillf echo " Default is to use ${TEMPROOT} as is" 55852400Sbillf echo '' 55967859Sdougb echo -n "How should I deal with this? [Use the existing ${TEMPROOT}] " 56067859Sdougb read DELORNOT 56167859Sdougb 56267859Sdougb case "${DELORNOT}" in 56367859Sdougb [dD]) 56467859Sdougb echo '' 56567859Sdougb echo " *** Deleting the old ${TEMPROOT}" 56667859Sdougb echo '' 567201765Sdougb delete_temproot 56867859Sdougb unset TEST_TEMP_ROOT 56952400Sbillf ;; 57067859Sdougb [tT]) 57167859Sdougb echo " *** Enter new directory name for temporary root environment" 57267859Sdougb read TEMPROOT 57367859Sdougb ;; 57467859Sdougb [eE]) 57567859Sdougb exit 0 57667859Sdougb ;; 57767859Sdougb '') 57867859Sdougb echo '' 57967859Sdougb echo " *** Leaving ${TEMPROOT} intact" 58067859Sdougb echo '' 58167859Sdougb unset TEST_TEMP_ROOT 58267859Sdougb ;; 58367859Sdougb *) 58467859Sdougb echo '' 58567859Sdougb echo "invalid choice: ${DELORNOT}" 58667859Sdougb echo '' 58767859Sdougb ;; 58867859Sdougb esac 58967859Sdougb ;; 59052400Sbillf *) 59177323Sdougb # If this is an auto-run, try a hopefully safe alternative then 59277323Sdougb # re-test anyway. 59352400Sbillf TEMPROOT=/var/tmp/temproot.`date +%m%d.%H.%M.%S` 59452400Sbillf ;; 59552400Sbillf esac 59652400Sbillf else 59752400Sbillf unset TEST_TEMP_ROOT 59852400Sbillf fi 59952400Sbillf done 60052400Sbillf 60152400Sbillf echo "*** Creating the temporary root environment in ${TEMPROOT}" 60252400Sbillf 60352400Sbillf if mkdir -p "${TEMPROOT}"; then 60452400Sbillf echo " *** ${TEMPROOT} ready for use" 60552400Sbillf fi 60652400Sbillf 60752400Sbillf if [ ! -d "${TEMPROOT}" ]; then 60852400Sbillf echo '' 60952400Sbillf echo " *** FATAL ERROR: Cannot create ${TEMPROOT}" 61052400Sbillf echo '' 61152400Sbillf exit 1 61252400Sbillf fi 61352400Sbillf 61452400Sbillf echo " *** Creating and populating directory structure in ${TEMPROOT}" 61552400Sbillf echo '' 61652400Sbillf 61752400Sbillf case "${VERBOSE}" in 61852400Sbillf '') ;; 61952400Sbillf *) 62097960Sdougb press_to_continue 62152400Sbillf ;; 62252400Sbillf esac 62352400Sbillf 62491193Sdougb case "${PRE_WORLD}" in 62591193Sdougb '') 62691193Sdougb { cd ${SOURCEDIR} && 62791193Sdougb case "${DESTDIR}" in 62891193Sdougb '') ;; 62991193Sdougb *) 630208088Sdougb ${MM_MAKE} DESTDIR=${DESTDIR} distrib-dirs >/dev/null 63191193Sdougb ;; 63291193Sdougb esac 633208088Sdougb ${MM_MAKE} DESTDIR=${TEMPROOT} distrib-dirs >/dev/null && 634250118Sbrooks ${MM_MAKE} _obj SUBDIR_OVERRIDE=etc >/dev/null && 635250118Sbrooks ${MM_MAKE} everything SUBDIR_OVERRIDE=etc >/dev/null && 636250118Sbrooks ${MM_MAKE} DESTDIR=${TEMPROOT} distribution >/dev/null;} || 63791193Sdougb { echo ''; 63891193Sdougb echo " *** FATAL ERROR: Cannot 'cd' to ${SOURCEDIR} and install files to"; 63991193Sdougb echo " the temproot environment"; 64091193Sdougb echo ''; 64191193Sdougb exit 1;} 64291193Sdougb ;; 64391193Sdougb *) 64491193Sdougb # Only set up files that are crucial to {build|install}world 64591193Sdougb { mkdir -p ${TEMPROOT}/etc && 646186678Sdougb cp -p ${SOURCEDIR}/etc/master.passwd ${TEMPROOT}/etc && 647224726Sdougb install -p -o root -g wheel -m 0644 ${SOURCEDIR}/etc/group ${TEMPROOT}/etc;} || 64891193Sdougb { echo ''; 64991193Sdougb echo ' *** FATAL ERROR: Cannot copy files to the temproot environment'; 65091193Sdougb echo ''; 65191193Sdougb exit 1;} 65291193Sdougb ;; 65391193Sdougb esac 65452400Sbillf 65577323Sdougb # Doing the inventory and removing files that we don't want to compare only 65677323Sdougb # makes sense if we are not doing a rerun, since we have no way of knowing 65777323Sdougb # what happened to the files during previous incarnations. 65867949Sdougb case "${VERBOSE}" in 65967949Sdougb '') ;; 66067949Sdougb *) 66167949Sdougb echo '' 66267949Sdougb echo ' *** The following files exist only in the installed version of' 66367949Sdougb echo " ${DESTDIR}/etc. In the vast majority of cases these files" 66467949Sdougb echo ' are necessary parts of the system and should not be deleted.' 66567949Sdougb echo ' However because these files are not updated by this process you' 66667949Sdougb echo ' might want to verify their status before rebooting your system.' 66767949Sdougb echo '' 66897960Sdougb press_to_continue 669101348Sdougb diff -qr ${DESTDIR}/etc ${TEMPROOT}/etc | grep "^Only in ${DESTDIR}/etc" | ${PAGER} 67067949Sdougb echo '' 67197960Sdougb press_to_continue 67267949Sdougb ;; 67367949Sdougb esac 67467949Sdougb 67552534Sbillf case "${IGNORE_MOTD}" in 676202340Sdougb '') ;; 677202339Sdougb *) 678186678Sdougb echo '' 679186678Sdougb echo "*** You have the IGNORE_MOTD option set in your mergemaster rc file." 680186678Sdougb echo " This option is deprecated in favor of the IGNORE_FILES option." 681186678Sdougb echo " Please update your rc file accordingly." 682186678Sdougb echo '' 683202339Sdougb exit 1 68452534Sbillf ;; 68552534Sbillf esac 68652534Sbillf 687186678Sdougb # Avoid comparing the following user specified files 688186678Sdougb for file in ${IGNORE_FILES}; do 689186688Sdougb test -e ${TEMPROOT}/${file} && unlink ${TEMPROOT}/${file} 690186678Sdougb done 69152400Sbillf 692201291Sdougb # We really don't want to have to deal with files like login.conf.db, pwd.db, 693201291Sdougb # or spwd.db. Instead, we want to compare the text versions, and run *_mkdb. 694201291Sdougb # Prompt the user to do so below, as needed. 695201291Sdougb # 696201291Sdougb rm -f ${TEMPROOT}/etc/*.db ${TEMPROOT}/etc/passwd 69777478Sdougb 698201291Sdougb # We only need to compare things like freebsd.cf once 699201291Sdougb find ${TEMPROOT}/usr/obj -type f -delete 2>/dev/null 70094196Sdougb 701201291Sdougb # Delete stuff we do not need to keep the mtree database small, 702201291Sdougb # and to make the actual comparison faster. 703201291Sdougb find ${TEMPROOT}/usr -type l -delete 2>/dev/null 704201291Sdougb find ${TEMPROOT} -type f -size 0 -delete 2>/dev/null 705201291Sdougb find -d ${TEMPROOT} -type d -empty -delete 2>/dev/null 706158149Sgordon 707201291Sdougb # Build the mtree database in a temporary location. 708201291Sdougb case "${PRE_WORLD}" in 709201323Sdougb '') MTREENEW=`mktemp -t mergemaster.mtree` 710255476Sdelphij mtree -nci -p ${TEMPROOT} -k size,md5digest > ${MTREENEW} 2>/dev/null 711201291Sdougb ;; 712201291Sdougb *) # We don't want to mess with the mtree database on a pre-world run or 713201291Sdougb # when re-scanning a previously-built tree. 714201291Sdougb ;; 715201291Sdougb esac 716201291Sdougb ;; # End of the "RERUN" test 717158149Sgordonesac 718158149Sgordon 71952400Sbillf# Get ready to start comparing files 72052400Sbillf 72198084Sdougb# Check umask if not specified on the command line, 72298084Sdougb# and we are not doing an autorun 72352400Sbillf# 72498084Sdougbif [ -z "${NEW_UMASK}" -a -z "${AUTO_RUN}" ]; then 72598084Sdougb USER_UMASK=`umask` 72652400Sbillf case "${USER_UMASK}" in 72777335Sdougb 0022|022) ;; 72852400Sbillf *) 72952400Sbillf echo '' 73098084Sdougb echo " *** Your umask is currently set to ${USER_UMASK}. By default, this script" 73198084Sdougb echo " installs all files with the same user, group and modes that" 732186678Sdougb echo " they are created with by ${SOURCEDIR}/etc/Makefile, compared to" 73398084Sdougb echo " a umask of 022. This umask allows world read permission when" 73498084Sdougb echo " the file's default permissions have it." 73552400Sbillf echo '' 73698084Sdougb echo " No world permissions can sometimes cause problems. A umask of" 73798084Sdougb echo " 022 will restore the default behavior, but is not mandatory." 73898084Sdougb echo " /etc/master.passwd is a special case. Its file permissions" 73998084Sdougb echo " will be 600 (rw-------) if installed." 74097960Sdougb echo '' 74198084Sdougb echo -n "What umask should I use? [${USER_UMASK}] " 74298084Sdougb read NEW_UMASK 74398084Sdougb 74498084Sdougb NEW_UMASK="${NEW_UMASK:-$USER_UMASK}" 74552400Sbillf ;; 74652400Sbillf esac 74752400Sbillf echo '' 74898084Sdougbfi 74952400Sbillf 75098084SdougbCONFIRMED_UMASK=${NEW_UMASK:-0022} 75198084Sdougb 75252400Sbillf# 753114501Sdougb# Warn users who still have old rc files 754114501Sdougb# 755179315Sbzfor file in atm devfs diskless1 diskless2 network network6 pccard \ 756114523Sdougb serial syscons sysctl alpha amd64 i386 ia64 sparc64; do 757114501Sdougb if [ -f "${DESTDIR}/etc/rc.${file}" ]; then 758114501Sdougb OLD_RC_PRESENT=1 759114501Sdougb break 760114501Sdougb fi 761114501Sdougbdone 762114501Sdougb 763114501Sdougbcase "${OLD_RC_PRESENT}" in 764114501Sdougb1) 76552400Sbillf echo '' 766114501Sdougb echo " *** There are elements of the old rc system in ${DESTDIR}/etc/." 76767949Sdougb echo '' 768114501Sdougb echo ' While these scripts will not hurt anything, they are not' 769114501Sdougb echo ' functional on an up to date system, and can be removed.' 77067949Sdougb echo '' 771114501Sdougb 77252400Sbillf case "${AUTO_RUN}" in 77352400Sbillf '') 774114501Sdougb echo -n 'Move these files to /var/tmp/mergemaster/old_rc? [yes] ' 775114501Sdougb read MOVE_OLD_RC 77667859Sdougb 777114501Sdougb case "${MOVE_OLD_RC}" in 778114501Sdougb [nN]*) ;; 77952400Sbillf *) 780114501Sdougb mkdir -p /var/tmp/mergemaster/old_rc 781179315Sbz for file in atm devfs diskless1 diskless2 network network6 pccard \ 782114523Sdougb serial syscons sysctl alpha amd64 i386 ia64 sparc64; do 783114501Sdougb if [ -f "${DESTDIR}/etc/rc.${file}" ]; then 784114501Sdougb mv ${DESTDIR}/etc/rc.${file} /var/tmp/mergemaster/old_rc/ 785114501Sdougb fi 786114501Sdougb done 787114501Sdougb echo ' The files have been moved' 788114501Sdougb press_to_continue 78952400Sbillf ;; 79052400Sbillf esac 79152400Sbillf ;; 79252400Sbillf *) ;; 79352400Sbillf esac 794114501Sdougbesac 79552400Sbillf 79698084Sdougb# Use the umask/mode information to install the files 79752400Sbillf# Create directories as needed 79852400Sbillf# 799186678Sdougbinstall_error () { 800186678Sdougb echo "*** FATAL ERROR: Unable to install ${1} to ${2}" 801186678Sdougb echo '' 802186678Sdougb exit 1 803186678Sdougb} 804186678Sdougb 80578490Sdougbdo_install_and_rm () { 806114501Sdougb case "${PRESERVE_FILES}" in 807114501Sdougb [Yy][Ee][Ss]) 808114501Sdougb if [ -f "${3}/${2##*/}" ]; then 809114565Sdougb mkdir -p ${PRESERVE_FILES_DIR}/${2%/*} 810114565Sdougb cp ${3}/${2##*/} ${PRESERVE_FILES_DIR}/${2%/*} 811114501Sdougb fi 812114501Sdougb ;; 813114501Sdougb esac 814114501Sdougb 815186678Sdougb if [ ! -d "${3}/${2##*/}" ]; then 816186678Sdougb if install -m ${1} ${2} ${3}; then 817186678Sdougb unlink ${2} 818186678Sdougb else 819186678Sdougb install_error ${2} ${3} 820186678Sdougb fi 821186678Sdougb else 822186678Sdougb install_error ${2} ${3} 823186678Sdougb fi 82478490Sdougb} 82578490Sdougb 82698084Sdougb# 4095 = "obase=10;ibase=8;07777" | bc 82798084Sdougbfind_mode () { 82898084Sdougb local OCTAL 82998084Sdougb OCTAL=$(( ~$(echo "obase=10; ibase=8; ${CONFIRMED_UMASK}" | bc) & 4095 & 830124053Sdougb $(echo "obase=10; ibase=8; $(stat -f "%OMp%OLp" ${1})" | bc) )) 83198084Sdougb printf "%04o\n" ${OCTAL} 83298084Sdougb} 83398084Sdougb 83452400Sbillfmm_install () { 83552400Sbillf local INSTALL_DIR 83652400Sbillf INSTALL_DIR=${1#.} 83752400Sbillf INSTALL_DIR=${INSTALL_DIR%/*} 83867949Sdougb 83952400Sbillf case "${INSTALL_DIR}" in 84052400Sbillf '') 84152400Sbillf INSTALL_DIR=/ 84252400Sbillf ;; 84352400Sbillf esac 84452400Sbillf 84567949Sdougb if [ -n "${DESTDIR}${INSTALL_DIR}" -a ! -d "${DESTDIR}${INSTALL_DIR}" ]; then 84698084Sdougb DIR_MODE=`find_mode "${TEMPROOT}/${INSTALL_DIR}"` 847200425Sdougb install -d -o root -g wheel -m "${DIR_MODE}" "${DESTDIR}${INSTALL_DIR}" || 848200425Sdougb install_error $1 ${DESTDIR}${INSTALL_DIR} 84952400Sbillf fi 85052400Sbillf 85198084Sdougb FILE_MODE=`find_mode "${1}"` 85252400Sbillf 85352400Sbillf if [ ! -x "${1}" ]; then 85452400Sbillf case "${1#.}" in 85564625Sgshapiro /etc/mail/aliases) 85652400Sbillf NEED_NEWALIASES=yes 85752400Sbillf ;; 85852400Sbillf /etc/login.conf) 85952400Sbillf NEED_CAP_MKDB=yes 86052400Sbillf ;; 861207612Snork /etc/services) 862207612Snork NEED_SERVICES_MKDB=yes 863207612Snork ;; 86452400Sbillf /etc/master.passwd) 86578490Sdougb do_install_and_rm 600 "${1}" "${DESTDIR}${INSTALL_DIR}" 86652400Sbillf NEED_PWD_MKDB=yes 86752400Sbillf DONT_INSTALL=yes 86852400Sbillf ;; 86952400Sbillf /.cshrc | /.profile) 870200708Sdougb local st_nlink 871200708Sdougb 872200708Sdougb # install will unlink the file before it installs the new one, 873200708Sdougb # so we have to restore/create the link afterwards. 874200708Sdougb # 875200708Sdougb st_nlink=0 # In case the file does not yet exist 876200708Sdougb eval $(stat -s ${DESTDIR}${COMPFILE#.} 2>/dev/null) 877200708Sdougb 878200708Sdougb do_install_and_rm "${FILE_MODE}" "${1}" "${DESTDIR}${INSTALL_DIR}" 879200708Sdougb 880200708Sdougb if [ -n "${AUTO_INSTALL}" -a $st_nlink -gt 1 ]; then 881200708Sdougb HANDLE_LINK=l 882200708Sdougb else 883200701Sdougb case "${LINK_EXPLAINED}" in 884200701Sdougb '') 885200701Sdougb echo " *** Historically BSD derived systems have had a" 886200701Sdougb echo " hard link from /.cshrc and /.profile to" 887200701Sdougb echo " their namesakes in /root. Please indicate" 888200701Sdougb echo " your preference below for bringing your" 889200701Sdougb echo " installed files up to date." 890200701Sdougb echo '' 891200701Sdougb LINK_EXPLAINED=yes 892200701Sdougb ;; 893200701Sdougb esac 894200701Sdougb 895200701Sdougb echo " Use 'd' to delete the temporary ${COMPFILE}" 896200708Sdougb echo " Use 'l' to delete the existing ${DESTDIR}/root/${COMPFILE##*/} and create the link" 89752400Sbillf echo '' 898200701Sdougb echo " Default is to leave the temporary file to deal with by hand" 899200701Sdougb echo '' 900200701Sdougb echo -n " How should I handle ${COMPFILE}? [Leave it to install later] " 901200701Sdougb read HANDLE_LINK 902200708Sdougb fi 90352400Sbillf 90452400Sbillf case "${HANDLE_LINK}" in 90552400Sbillf [dD]*) 90652400Sbillf rm "${COMPFILE}" 90752400Sbillf echo '' 90852400Sbillf echo " *** Deleting ${COMPFILE}" 90952400Sbillf ;; 91052400Sbillf [lL]*) 91152400Sbillf echo '' 912200708Sdougb unlink ${DESTDIR}/root/${COMPFILE##*/} 913200708Sdougb if ln ${DESTDIR}${COMPFILE#.} ${DESTDIR}/root/${COMPFILE##*/}; then 91467949Sdougb echo " *** Link from ${DESTDIR}${COMPFILE#.} to ${DESTDIR}/root/${COMPFILE##*/} installed successfully" 91552400Sbillf else 916200708Sdougb echo " *** Error linking ${DESTDIR}${COMPFILE#.} to ${DESTDIR}/root/${COMPFILE##*/}" 917200708Sdougb echo " *** ${COMPFILE} will remain for your consideration" 91852400Sbillf fi 91952400Sbillf ;; 92052400Sbillf *) 92152400Sbillf echo " *** ${COMPFILE} will remain for your consideration" 92252400Sbillf ;; 92352400Sbillf esac 924200708Sdougb return 92552400Sbillf ;; 92652400Sbillf esac 92752400Sbillf 92852400Sbillf case "${DONT_INSTALL}" in 92952400Sbillf '') 93078490Sdougb do_install_and_rm "${FILE_MODE}" "${1}" "${DESTDIR}${INSTALL_DIR}" 93152400Sbillf ;; 93252400Sbillf *) 93352400Sbillf unset DONT_INSTALL 93452400Sbillf ;; 93552400Sbillf esac 93678490Sdougb else # File matched -x 93778490Sdougb do_install_and_rm "${FILE_MODE}" "${1}" "${DESTDIR}${INSTALL_DIR}" 93852400Sbillf fi 93952400Sbillf return $? 94052400Sbillf} 94152400Sbillf 942174841Sdougbif [ ! -d "${TEMPROOT}" ]; then 943174841Sdougb echo "*** FATAL ERROR: The temproot directory (${TEMPROOT})" 944174841Sdougb echo ' has disappeared!' 945174841Sdougb echo '' 946174841Sdougb exit 1 947174841Sdougbfi 948174841Sdougb 94967949Sdougbecho '' 95067949Sdougbecho "*** Beginning comparison" 95167949Sdougbecho '' 95252400Sbillf 953124136Sdougb# Pre-world does not populate /etc/rc.d. 954124053Sdougb# It is very possible that a previous run would have deleted files in 955124053Sdougb# ${TEMPROOT}/etc/rc.d, thus creating a lot of false positives. 956124136Sdougbif [ -z "${PRE_WORLD}" -a -z "${RERUN}" ]; then 957124053Sdougb echo " *** Checking ${DESTDIR}/etc/rc.d for stale files" 958124053Sdougb echo '' 959124053Sdougb cd "${DESTDIR}/etc/rc.d" && 960124053Sdougb for file in *; do 961124053Sdougb if [ ! -e "${TEMPROOT}/etc/rc.d/${file}" ]; then 962124053Sdougb STALE_RC_FILES="${STALE_RC_FILES} ${file}" 963124053Sdougb fi 964124053Sdougb done 965124053Sdougb case "${STALE_RC_FILES}" in 966126718Sdougb ''|' *') 967124053Sdougb echo ' *** No stale files found' 968124053Sdougb ;; 969124053Sdougb *) 970124053Sdougb echo " *** The following files exist in ${DESTDIR}/etc/rc.d but not in" 971124053Sdougb echo " ${TEMPROOT}/etc/rc.d/:" 972124053Sdougb echo '' 973124053Sdougb echo "${STALE_RC_FILES}" 974124053Sdougb echo '' 975124053Sdougb echo ' The presence of stale files in this directory can cause the' 976124053Sdougb echo ' dreaded unpredictable results, and therefore it is highly' 977124053Sdougb echo ' recommended that you delete them.' 978124053Sdougb case "${AUTO_RUN}" in 979124053Sdougb '') 980124053Sdougb echo '' 981153604Sdougb echo -n ' *** Delete them now? [n] ' 982124053Sdougb read DELETE_STALE_RC_FILES 983124053Sdougb case "${DELETE_STALE_RC_FILES}" in 984153604Sdougb [yY]) 985124053Sdougb echo ' *** Deleting ... ' 986124053Sdougb rm ${STALE_RC_FILES} 987124053Sdougb echo ' done.' 988124053Sdougb ;; 989153604Sdougb *) 990153604Sdougb echo ' *** Files will not be deleted' 991153604Sdougb ;; 992124053Sdougb esac 993124053Sdougb sleep 2 994124053Sdougb ;; 995201291Sdougb *) 996201291Sdougb if [ -n "${DELETE_STALE_RC_FILES}" ]; then 997201291Sdougb echo ' *** Deleting ... ' 998201291Sdougb rm ${STALE_RC_FILES} 999201291Sdougb echo ' done.' 1000201291Sdougb fi 1001124053Sdougb esac 1002124053Sdougb ;; 1003124053Sdougb esac 1004124053Sdougb echo '' 1005124136Sdougbfi 1006124053Sdougb 100767949Sdougbcd "${TEMPROOT}" 100867949Sdougb 100967949Sdougbif [ -r "${MM_PRE_COMPARE_SCRIPT}" ]; then 101067949Sdougb . "${MM_PRE_COMPARE_SCRIPT}" 101167949Sdougbfi 101267949Sdougb 1013200425Sdougb# Things that were files/directories/links in one version can sometimes 1014200425Sdougb# change to something else in a newer version. So we need to explicitly 1015200425Sdougb# test for this, and warn the user if what we find does not match. 1016200425Sdougb# 1017200700Sdougbfor COMPFILE in `find . | sort` ; do 1018200425Sdougb if [ -e "${DESTDIR}${COMPFILE#.}" ]; then 1019200425Sdougb INSTALLED_TYPE=`stat -f '%HT' ${DESTDIR}${COMPFILE#.}` 1020200425Sdougb else 1021200425Sdougb continue 1022200425Sdougb fi 1023200425Sdougb TEMPROOT_TYPE=`stat -f '%HT' $COMPFILE` 1024200425Sdougb 1025200425Sdougb if [ ! "$TEMPROOT_TYPE" = "$INSTALLED_TYPE" ]; then 1026200425Sdougb [ "$COMPFILE" = '.' ] && continue 1027200425Sdougb TEMPROOT_TYPE=`echo $TEMPROOT_TYPE | tr [:upper:] [:lower:]` 1028200425Sdougb INSTALLED_TYPE=`echo $INSTALLED_TYPE | tr [:upper:] [:lower:]` 1029200425Sdougb 1030200425Sdougb echo "*** The installed file ${DESTDIR}${COMPFILE#.} has the type \"$INSTALLED_TYPE\"" 1031200425Sdougb echo " but the new version has the type \"$TEMPROOT_TYPE\"" 1032200425Sdougb echo '' 1033200425Sdougb echo " How would you like to handle this?" 1034200425Sdougb echo '' 1035200425Sdougb echo " Use 'r' to remove ${DESTDIR}${COMPFILE#.}" 1036200425Sdougb case "$TEMPROOT_TYPE" in 1037200425Sdougb 'symbolic link') 1038200425Sdougb TARGET=`readlink $COMPFILE` 1039200425Sdougb echo " and create a link to $TARGET in its place" ;; 1040200425Sdougb *) echo " You will be able to install it as a \"$TEMPROOT_TYPE\"" ;; 1041200425Sdougb esac 1042200425Sdougb echo '' 1043200425Sdougb echo " Use 'i' to ignore this" 1044200425Sdougb echo '' 1045200425Sdougb echo -n " How to proceed? [i] " 1046200425Sdougb read ANSWER 1047200425Sdougb case "$ANSWER" in 1048200425Sdougb [rR]) case "${PRESERVE_FILES}" in 1049200425Sdougb [Yy][Ee][Ss]) 1050200425Sdougb mv ${DESTDIR}${COMPFILE#.} ${PRESERVE_FILES_DIR}/ || exit 1 ;; 1051200425Sdougb *) rm -rf ${DESTDIR}${COMPFILE#.} ;; 1052200425Sdougb esac 1053200425Sdougb case "$TEMPROOT_TYPE" in 1054200425Sdougb 'symbolic link') ln -sf $TARGET ${DESTDIR}${COMPFILE#.} ;; 1055200425Sdougb esac ;; 1056200425Sdougb *) echo '' 1057200425Sdougb echo "*** See the man page about adding ${COMPFILE#.} to the list of IGNORE_FILES" 1058200425Sdougb press_to_continue ;; 1059200425Sdougb esac 1060200425Sdougb echo '' 1061200425Sdougb fi 1062200425Sdougbdone 1063200425Sdougb 1064200700Sdougbfor COMPFILE in `find . -type f | sort`; do 106567949Sdougb 106667949Sdougb # First, check to see if the file exists in DESTDIR. If not, the 106767949Sdougb # diff_loop function knows how to handle it. 106867949Sdougb # 106967949Sdougb if [ ! -e "${DESTDIR}${COMPFILE#.}" ]; then 107077325Sdougb case "${AUTO_RUN}" in 107177325Sdougb '') 107277325Sdougb diff_loop 107377325Sdougb ;; 107477325Sdougb *) 107577325Sdougb case "${AUTO_INSTALL}" in 107677325Sdougb '') 107777325Sdougb # If this is an auto run, make it official 107877325Sdougb echo " *** ${COMPFILE} will remain for your consideration" 107977325Sdougb ;; 108077325Sdougb *) 108177325Sdougb diff_loop 108277325Sdougb ;; 108377325Sdougb esac 108477325Sdougb ;; 108577325Sdougb esac # Auto run test 108667949Sdougb continue 108767949Sdougb fi 108867949Sdougb 108952400Sbillf case "${STRICT}" in 109052400Sbillf '' | [Nn][Oo]) 1091241337Sdougb # Compare $Id's first so if the file hasn't been modified 109252400Sbillf # local changes will be ignored. 109352400Sbillf # If the files have the same $Id, delete the one in temproot so the 109452400Sbillf # user will have less to wade through if files are left to merge by hand. 109552400Sbillf # 1096241337Sdougb ID1=`grep "[$]${ID_TAG}:" ${DESTDIR}${COMPFILE#.} 2>/dev/null` 1097241337Sdougb ID2=`grep "[$]${ID_TAG}:" ${COMPFILE} 2>/dev/null` || ID2=none 109852400Sbillf 1099241337Sdougb case "${ID2}" in 1100241337Sdougb "${ID1}") 1101241337Sdougb echo " *** Temp ${COMPFILE} and installed have the same Id, deleting" 110267949Sdougb rm "${COMPFILE}" 110367949Sdougb ;; 110467949Sdougb esac 110552400Sbillf ;; 110652400Sbillf esac 110752400Sbillf 110852400Sbillf # If the file is still here either because the $Ids are different, the 110952400Sbillf # file doesn't have an $Id, or we're using STRICT mode; look at the diff. 111052400Sbillf # 111152400Sbillf if [ -f "${COMPFILE}" ]; then 111252400Sbillf 111352400Sbillf # Do an absolute diff first to see if the files are actually different. 111452400Sbillf # If they're not different, delete the one in temproot. 111552400Sbillf # 1116110377Sdougb if diff -q ${DIFF_OPTIONS} "${DESTDIR}${COMPFILE#.}" "${COMPFILE}" > \ 1117110377Sdougb /dev/null 2>&1; then 111852400Sbillf echo " *** Temp ${COMPFILE} and installed are the same, deleting" 111952400Sbillf rm "${COMPFILE}" 112052400Sbillf else 112177323Sdougb # Ok, the files are different, so show the user where they differ. 112277323Sdougb # Use user's choice of diff methods; and user's pager if they have one. 112377323Sdougb # Use more if not. 112467859Sdougb # Use unified diffs by default. Context diffs give me a headache. :) 112552400Sbillf # 1126189992Sdougb # If the user chose the -F option, test for that before proceeding 1127189992Sdougb # 1128189992Sdougb if [ -n "$FREEBSD_ID" ]; then 1129201291Sdougb if diff -q -I'[$]FreeBSD.*[$]' "${DESTDIR}${COMPFILE#.}" "${COMPFILE}" > \ 1130189992Sdougb /dev/null 2>&1; then 1131189992Sdougb if mm_install "${COMPFILE}"; then 1132189992Sdougb echo "*** Updated revision control Id for ${DESTDIR}${COMPFILE#.}" 1133189992Sdougb else 1134189992Sdougb echo "*** Problem installing ${COMPFILE}, it will remain to merge by hand later" 1135189992Sdougb fi 1136189992Sdougb continue 1137189992Sdougb fi 1138189992Sdougb fi 113952400Sbillf case "${AUTO_RUN}" in 114052400Sbillf '') 114158910Salfred # prompt user to install/delete/merge changes 114258910Salfred diff_loop 114352400Sbillf ;; 114452400Sbillf *) 114552400Sbillf # If this is an auto run, make it official 114652400Sbillf echo " *** ${COMPFILE} will remain for your consideration" 114752400Sbillf ;; 114852400Sbillf esac # Auto run test 114952400Sbillf fi # Yes, the files are different 115052400Sbillf fi # Yes, the file still remains to be checked 1151189763Sdougbdone # This is for the for way up there at the beginning of the comparison 115252400Sbillf 115352534Sbillfecho '' 115452400Sbillfecho "*** Comparison complete" 1155158149Sgordon 1156192230Sdougbif [ -s "${MTREENEW}" ]; then 1157158149Sgordon echo "*** Saving mtree database for future upgrades" 1158200416Sdougb test -e "${MTREEFILE}" && unlink ${MTREEFILE} 1159200416Sdougb mv ${MTREENEW} ${MTREEFILE} 1160158149Sgordonfi 1161158149Sgordon 116252400Sbillfecho '' 116352400Sbillf 116452400SbillfTEST_FOR_FILES=`find ${TEMPROOT} -type f -size +0 2>/dev/null` 116552400Sbillfif [ -n "${TEST_FOR_FILES}" ]; then 116652400Sbillf echo "*** Files that remain for you to merge by hand:" 1167200700Sdougb find "${TEMPROOT}" -type f -size +0 | sort 116877335Sdougb echo '' 116952400Sbillf 1170201765Sdougb case "${AUTO_RUN}" in 1171201765Sdougb '') 1172201765Sdougb echo -n "Do you wish to delete what is left of ${TEMPROOT}? [no] " 1173201765Sdougb read DEL_TEMPROOT 1174201765Sdougb case "${DEL_TEMPROOT}" in 1175201765Sdougb [yY]*) 1176201765Sdougb delete_temproot 1177201765Sdougb ;; 1178201765Sdougb *) 1179201765Sdougb echo " *** ${TEMPROOT} will remain" 1180201765Sdougb ;; 1181201765Sdougb esac 118252400Sbillf ;; 1183201765Sdougb *) ;; 118452400Sbillf esac 1185201765Sdougbelse 1186201765Sdougb echo "*** ${TEMPROOT} is empty, deleting" 1187201765Sdougb delete_temproot 1188201765Sdougbfi 118952400Sbillf 119068153Sdougbcase "${AUTO_INSTALLED_FILES}" in 119168153Sdougb'') ;; 119268153Sdougb*) 119373651Sdougb case "${AUTO_RUN}" in 119473651Sdougb '') 119573651Sdougb ( 119673651Sdougb echo '' 119777323Sdougb echo '*** You chose the automatic install option for files that did not' 119877323Sdougb echo ' exist on your system. The following were installed for you:' 119973651Sdougb echo "${AUTO_INSTALLED_FILES}" 120073651Sdougb ) | ${PAGER} 120173651Sdougb ;; 120273651Sdougb *) 120368153Sdougb 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:' 120668153Sdougb echo "${AUTO_INSTALLED_FILES}" 120773651Sdougb ;; 120873651Sdougb esac 120968153Sdougb ;; 121068153Sdougbesac 121168153Sdougb 1212158149Sgordoncase "${AUTO_UPGRADED_FILES}" in 1213158149Sgordon'') ;; 1214158149Sgordon*) 1215158149Sgordon case "${AUTO_RUN}" in 1216158149Sgordon '') 1217158149Sgordon ( 1218158149Sgordon echo '' 1219158149Sgordon echo '*** You chose the automatic upgrade option for files that you did' 1220158149Sgordon echo ' not alter on your system. The following were upgraded for you:' 1221158149Sgordon echo "${AUTO_UPGRADED_FILES}" 1222158149Sgordon ) | ${PAGER} 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 ;; 1230158149Sgordon esac 1231158149Sgordon ;; 1232158149Sgordonesac 1233158149Sgordon 123473651Sdougbrun_it_now () { 1235227145Sdougb [ -n "$AUTO_RUN" ] && return 123673651Sdougb 1237227145Sdougb local answer 1238227145Sdougb 1239227145Sdougb echo '' 1240227145Sdougb while : ; do 1241227145Sdougb if [ "$RUN_UPDATES" = always ]; then 1242227145Sdougb answer=y 1243227145Sdougb elif [ "$RUN_UPDATES" = never ]; then 1244227145Sdougb answer=n 1245227145Sdougb else 1246227145Sdougb echo -n ' Would you like to run it now? y or n [n] ' 1247227145Sdougb read answer 1248227145Sdougb fi 1249227145Sdougb 1250227145Sdougb case "$answer" in 125173651Sdougb y) 125277335Sdougb echo " Running ${1}" 125377335Sdougb echo '' 125473651Sdougb eval "${1}" 1255227145Sdougb return 125673651Sdougb ;; 125777335Sdougb ''|n) 1258227145Sdougb if [ ! "$RUN_UPDATES" = never ]; then 1259227145Sdougb echo '' 1260227145Sdougb echo " *** Cancelled" 1261227145Sdougb echo '' 1262227145Sdougb fi 126377335Sdougb echo " Make sure to run ${1} yourself" 1264227145Sdougb return 126577335Sdougb ;; 126673651Sdougb *) 126777335Sdougb echo '' 1268227145Sdougb echo " *** Sorry, I do not understand your answer (${answer})" 126977335Sdougb echo '' 127073651Sdougb esac 1271227145Sdougb done 127273651Sdougb} 127373651Sdougb 127452400Sbillfcase "${NEED_NEWALIASES}" in 127552400Sbillf'') ;; 127652400Sbillf*) 127752400Sbillf echo '' 127877335Sdougb if [ -n "${DESTDIR}" ]; then 127977335Sdougb echo "*** You installed a new aliases file into ${DESTDIR}/etc/mail, but" 128077335Sdougb echo " the newaliases command is limited to the directories configured" 128177335Sdougb echo " in sendmail.cf. Make sure to create your aliases database by" 128277335Sdougb echo " hand when your sendmail configuration is done." 128377335Sdougb else 128477335Sdougb echo "*** You installed a new aliases file, so make sure that you run" 128577335Sdougb echo " '/usr/bin/newaliases' to rebuild your aliases database" 128677335Sdougb run_it_now '/usr/bin/newaliases' 128777335Sdougb fi 128852400Sbillf ;; 128952400Sbillfesac 129052400Sbillf 129152400Sbillfcase "${NEED_CAP_MKDB}" in 129252400Sbillf'') ;; 129352400Sbillf*) 129452400Sbillf echo '' 129552400Sbillf echo "*** You installed a login.conf file, so make sure that you run" 129677335Sdougb echo " '/usr/bin/cap_mkdb ${DESTDIR}/etc/login.conf'" 129777335Sdougb echo " to rebuild your login.conf database" 129877335Sdougb run_it_now "/usr/bin/cap_mkdb ${DESTDIR}/etc/login.conf" 129952400Sbillf ;; 130052400Sbillfesac 130152400Sbillf 1302207612Snorkcase "${NEED_SERVICES_MKDB}" in 1303207612Snork'') ;; 1304207612Snork*) 1305207612Snork echo '' 1306207612Snork echo "*** You installed a services file, so make sure that you run" 1307207612Snork echo " '/usr/sbin/services_mkdb -q -o ${DESTDIR}/var/db/services.db ${DESTDIR}/etc/services'" 1308207612Snork echo " to rebuild your services database" 1309207612Snork run_it_now "/usr/sbin/services_mkdb -q -o ${DESTDIR}/var/db/services.db ${DESTDIR}/etc/services" 1310207612Snork ;; 1311207612Snorkesac 1312207612Snork 131352400Sbillfcase "${NEED_PWD_MKDB}" in 131452400Sbillf'') ;; 131552400Sbillf*) 131652400Sbillf echo '' 131752400Sbillf echo "*** You installed a new master.passwd file, so make sure that you run" 131877335Sdougb if [ -n "${DESTDIR}" ]; then 131977335Sdougb echo " '/usr/sbin/pwd_mkdb -d ${DESTDIR}/etc -p ${DESTDIR}/etc/master.passwd'" 132077335Sdougb echo " to rebuild your password files" 132177335Sdougb run_it_now "/usr/sbin/pwd_mkdb -d ${DESTDIR}/etc -p ${DESTDIR}/etc/master.passwd" 132277335Sdougb else 132377335Sdougb echo " '/usr/sbin/pwd_mkdb -p /etc/master.passwd'" 132477335Sdougb echo " to rebuild your password files" 132577335Sdougb run_it_now '/usr/sbin/pwd_mkdb -p /etc/master.passwd' 132677335Sdougb fi 132752400Sbillf ;; 132852400Sbillfesac 132952400Sbillf 1330265383Speterif [ -e "${DESTDIR}/etc/localtime" -a ! -L "${DESTDIR}/etc/localtime" -a -z "${PRE_WORLD}" ]; then # Ignore if TZ == UTC 1331227145Sdougb echo '' 1332228169Sdougb [ -n "${DESTDIR}" ] && tzs_args="-C ${DESTDIR}" 1333227145Sdougb if [ -f "${DESTDIR}/var/db/zoneinfo" ]; then 1334227145Sdougb echo "*** Reinstalling `cat ${DESTDIR}/var/db/zoneinfo` as ${DESTDIR}/etc/localtime" 1335227145Sdougb tzsetup $tzs_args -r 1336227145Sdougb else 1337227145Sdougb echo "*** There is no ${DESTDIR}/var/db/zoneinfo file to update ${DESTDIR}/etc/localtime." 1338227145Sdougb echo ' You should run tzsetup' 1339228169Sdougb run_it_now "tzsetup $tzs_args" 1340227145Sdougb fi 1341227145Sdougbfi 1342227145Sdougb 134352400Sbillfecho '' 134452400Sbillf 134567949Sdougbif [ -r "${MM_EXIT_SCRIPT}" ]; then 134667949Sdougb . "${MM_EXIT_SCRIPT}" 134767949Sdougbfi 134867949Sdougb 134991193Sdougbcase "${COMP_CONFS}" in 135091193Sdougb'') ;; 135191193Sdougb*) 135291193Sdougb . ${DESTDIR}/etc/defaults/rc.conf 135391193Sdougb 135491193Sdougb (echo '' 135591193Sdougb echo "*** Comparing conf files: ${rc_conf_files}" 135691193Sdougb 135791193Sdougb for CONF_FILE in ${rc_conf_files}; do 135891193Sdougb if [ -r "${DESTDIR}${CONF_FILE}" ]; then 135991193Sdougb echo '' 136091193Sdougb echo "*** From ${DESTDIR}${CONF_FILE}" 136191193Sdougb echo "*** From ${DESTDIR}/etc/defaults/rc.conf" 136291193Sdougb 136391193Sdougb for RC_CONF_VAR in `grep -i ^[a-z] ${DESTDIR}${CONF_FILE} | 136491193Sdougb cut -d '=' -f 1`; do 136591193Sdougb echo '' 136691223Sdougb grep -w ^${RC_CONF_VAR} ${DESTDIR}${CONF_FILE} 136791223Sdougb grep -w ^${RC_CONF_VAR} ${DESTDIR}/etc/defaults/rc.conf || 136891193Sdougb echo ' * No default variable with this name' 136991193Sdougb done 137091193Sdougb fi 137191193Sdougb done) | ${PAGER} 137291193Sdougb echo '' 137391193Sdougb ;; 137491193Sdougbesac 137591193Sdougb 1376200425Sdougbif [ -n "${PRESERVE_FILES}" ]; then 1377200425Sdougb find -d $PRESERVE_FILES_DIR -type d -empty -delete 2>/dev/null 1378200425Sdougb rmdir $PRESERVE_FILES_DIR 2>/dev/null 1379200425Sdougbfi 1380200425Sdougb 138152400Sbillfexit 0 1382241337Sdougb 1383241337Sdougb#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1384241337Sdougb 1385241337Sdougb# Copyright (c) 1998-2012 Douglas Barton 1386241337Sdougb# All rights reserved. 1387241337Sdougb# 1388241337Sdougb# Redistribution and use in source and binary forms, with or without 1389241337Sdougb# modification, are permitted provided that the following conditions 1390241337Sdougb# are met: 1391241337Sdougb# 1. Redistributions of source code must retain the above copyright 1392241337Sdougb# notice, this list of conditions and the following disclaimer. 1393241337Sdougb# 2. Redistributions in binary form must reproduce the above copyright 1394241337Sdougb# notice, this list of conditions and the following disclaimer in the 1395241337Sdougb# documentation and/or other materials provided with the distribution. 1396241337Sdougb# 1397241337Sdougb# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1398241337Sdougb# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1399241337Sdougb# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1400241337Sdougb# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1401241337Sdougb# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1402241337Sdougb# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 1403241337Sdougb# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 1404241337Sdougb# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 1405241337Sdougb# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 1406241337Sdougb# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 1407241337Sdougb# SUCH DAMAGE. 1408