mergemaster.sh revision 96045
159769Sgrog#!/bin/sh 259769Sgrog 324424Swosch# mergemaster 424424Swosch 524424Swosch# Compare files created by /usr/src/etc/Makefile (or the directory 624424Swosch# the user specifies) with the currently installed copies. 724424Swosch 824424Swosch# Copyright 1998-2002 Douglas Barton 924424Swosch# DougB@FreeBSD.org 1024424Swosch 1124424Swosch# $FreeBSD: head/usr.sbin/mergemaster/mergemaster.sh 96045 2002-05-04 22:45:12Z dougb $ 1224424Swosch 1324424SwoschPATH=/bin:/usr/bin:/usr/sbin 1424424Swosch 1542704Swoschdisplay_usage () { 1642704Swosch VERSION_NUMBER=`grep "[$]FreeBSD:" $0 | cut -d ' ' -f 4` 1742704Swosch echo "mergemaster version ${VERSION_NUMBER}" 1824424Swosch echo 'Usage: mergemaster [-scrvahipC] [-m /path]' 1942704Swosch echo ' [-t /path] [-d] [-u N] [-w N] [-D /path]' 2042704Swosch echo "Options:" 2142704Swosch echo " -s Strict comparison (diff every pair of files)" 2242704Swosch echo " -c Use context diff instead of unified diff" 2342704Swosch echo " -r Re-run on a previously cleaned directory (skip temproot creation)" 2442704Swosch echo " -v Be more verbose about the process, include additional checks" 2542704Swosch echo " -a Leave all files that differ to merge by hand" 2642704Swosch echo " -h Display more complete help" 2742704Swosch echo ' -i Automatically install files that do not exist in destination directory' 2842704Swosch echo ' -p Pre-buildworld mode, only compares crucial files' 2942704Swosch echo ' -C Compare local rc.conf variables to the defaults' 3059769Sgrog echo " -m /path/directory Specify location of source to do the make in" 3159769Sgrog echo " -t /path/directory Specify temp root directory" 3259769Sgrog echo " -d Add date and time to directory name (e.g., /var/tmp/temproot.`date +%m%d.%H.%M`)" 3359769Sgrog echo " -u N Specify a numeric umask" 3459769Sgrog echo " -w N Specify a screen width in columns to sdiff" 3559769Sgrog echo ' -D /path/directory Specify the destination directory to install files to' 3659769Sgrog echo '' 3759769Sgrog} 3859769Sgrog 3924424Swoschdisplay_help () { 4042704Swosch echo "* To specify a directory other than /var/tmp/temproot for the" 4124424Swosch echo " temporary root environment, use -t /path/to/temp/root" 4242704Swosch echo "* The -w option takes a number as an argument for the column width" 4324424Swosch echo " of the screen. The default is 80." 4442704Swosch echo '* The -a option causes mergemaster to run without prompting.' 4524424Swosch} 4624424Swosch 4724424Swosch# Loop allowing the user to use sdiff to merge files and display the merged 4842704Swosch# file. 4925031Swoschmerge_loop () { 5059156Swosch case "${VERBOSE}" in 5125031Swosch '') ;; 5225031Swosch *) 5324424Swosch echo " *** Type h at the sdiff prompt (%) to get usage help" 5424424Swosch ;; 5524424Swosch esac 5624424Swosch echo '' 5771231Sitojun MERGE_AGAIN=yes 5824424Swosch while [ "${MERGE_AGAIN}" = "yes" ]; do 5971231Sitojun # Prime file.merged so we don't blat the owner/group id's 6025031Swosch cp -p "${COMPFILE}" "${COMPFILE}.merged" 6171231Sitojun sdiff -o "${COMPFILE}.merged" --text --suppress-common-lines \ 6224424Swosch --width=${SCREEN_WIDTH:-80} "${DESTDIR}${COMPFILE#.}" "${COMPFILE}" 6325031Swosch INSTALL_MERGED=V 6425031Swosch while [ "${INSTALL_MERGED}" = "v" -o "${INSTALL_MERGED}" = "V" ]; do 6571231Sitojun echo '' 6625031Swosch echo " Use 'i' to install merged file" 6771231Sitojun echo " Use 'r' to re-do the merge" 6870110Swosch echo " Use 'v' to view the merged file" 6970110Swosch echo " Default is to leave the temporary file to deal with by hand" 7070110Swosch echo '' 7170110Swosch echo -n " *** How should I deal with the merged file? [Leave it for later] " 7270110Swosch read INSTALL_MERGED 7370110Swosch 7470110Swosch case "${INSTALL_MERGED}" in 7570110Swosch [iI]) 7670110Swosch mv "${COMPFILE}.merged" "${COMPFILE}" 7770110Swosch echo '' 7870110Swosch if mm_install "${COMPFILE}"; then 7980675Sasmodai echo " *** Merged version of ${COMPFILE} installed successfully" 8080675Sasmodai else 8180675Sasmodai echo " *** Problem installing ${COMPFILE}, it will remain to merge by hand later" 8280675Sasmodai fi 8380675Sasmodai unset MERGE_AGAIN 8480675Sasmodai ;; 8580675Sasmodai [rR]) 8680675Sasmodai rm "${COMPFILE}.merged" 8780675Sasmodai ;; 8880675Sasmodai [vV]) 8980675Sasmodai ${PAGER} "${COMPFILE}.merged" 9080675Sasmodai ;; 9180675Sasmodai '') 9280675Sasmodai echo " *** ${COMPFILE} will remain for your consideration" 9380675Sasmodai unset MERGE_AGAIN 9480675Sasmodai ;; 9580675Sasmodai *) 9680675Sasmodai echo "invalid choice: ${INSTALL_MERGED}" 9780675Sasmodai INSTALL_MERGED=V 9880675Sasmodai ;; 9980675Sasmodai esac 10080675Sasmodai done 10180675Sasmodai done 10280675Sasmodai} 10380675Sasmodai 10480675Sasmodai# Loop showing user differences between files, allow merge, skip or install 10580675Sasmodai# options 10680675Sasmodaidiff_loop () { 10780675Sasmodai 10880675Sasmodai HANDLE_COMPFILE=v 10980675Sasmodai 11080675Sasmodai while [ "${HANDLE_COMPFILE}" = "v" -o "${HANDLE_COMPFILE}" = "V" -o \ 11180675Sasmodai "${HANDLE_COMPFILE}" = "NOT V" ]; do 11280675Sasmodai if [ -f "${DESTDIR}${COMPFILE#.}" -a -f "${COMPFILE}" ]; then 11380675Sasmodai if [ "${HANDLE_COMPFILE}" = "v" -o "${HANDLE_COMPFILE}" = "V" ]; then 11480675Sasmodai echo '' 11580675Sasmodai echo ' ====================================================================== ' 11680675Sasmodai echo '' 11780675Sasmodai ( 11880675Sasmodai echo '' 11980675Sasmodai echo " *** Displaying differences between ${COMPFILE} and installed version:" 12080675Sasmodai echo '' 12180675Sasmodai diff "${DIFF_FLAG}" "${DESTDIR}${COMPFILE#.}" "${COMPFILE}" 12280675Sasmodai ) | ${PAGER} 12380675Sasmodai echo '' 12480675Sasmodai fi 12580675Sasmodai else 12680675Sasmodai echo '' 12780675Sasmodai echo " *** There is no installed version of ${COMPFILE}" 12880675Sasmodai echo '' 12980675Sasmodai case "${AUTO_INSTALL}" in 13080675Sasmodai [Yy][Ee][Ss]) 13180675Sasmodai echo '' 13280675Sasmodai if mm_install "${COMPFILE}"; then 13380675Sasmodai echo " *** ${COMPFILE} installed successfully" 13480675Sasmodai echo '' 13580675Sasmodai # Make the list print one file per line 13680675Sasmodai AUTO_INSTALLED_FILES="${AUTO_INSTALLED_FILES} ${DESTDIR}${COMPFILE#.} 13780675Sasmodai" 138101401Swosch else 13980675Sasmodai echo " *** Problem installing ${COMPFILE}, it will remain to merge by hand" 140147593Shrs fi 14187200Swosch return 142147593Shrs ;; 14380675Sasmodai *) 144104772Smaxim NO_INSTALLED=yes 145104772Smaxim ;; 146104772Smaxim esac 147104772Smaxim fi 148104781Sjhb 149104781Sjhb echo " Use 'd' to delete the temporary ${COMPFILE}" 150104781Sjhb echo " Use 'i' to install the temporary ${COMPFILE}" 151104781Sjhb case "${NO_INSTALLED}" in 152104781Sjhb '') 153104781Sjhb echo " Use 'm' to merge the temporary and installed versions" 154119217Smurray echo " Use 'v' to view the diff results again" 155147593Shrs ;; 156147593Shrs esac 157119217Smurray echo '' 158119217Smurray echo " Default is to leave the temporary file to deal with by hand" 159119217Smurray echo '' 160119217Smurray echo -n "How should I deal with this? [Leave it for later] " 161132652Sosa read HANDLE_COMPFILE 162132652Sosa 163132652Sosa case "${HANDLE_COMPFILE}" in 164132652Sosa [dD]) 165132652Sosa rm "${COMPFILE}" 166132652Sosa echo '' 167132652Sosa echo " *** Deleting ${COMPFILE}" 168132652Sosa ;; 169132652Sosa [iI]) 170132652Sosa echo '' 171140831Smaxim if mm_install "${COMPFILE}"; then 172140831Smaxim echo " *** ${COMPFILE} installed successfully" 173132652Sosa else 174132652Sosa echo " *** Problem installing ${COMPFILE}, it will remain to merge by hand" 175132652Sosa fi 176132652Sosa ;; 177137120Smaxim [mM]) 178132652Sosa case "${NO_INSTALLED}" in 179132652Sosa '') 180132652Sosa # interact with user to merge files 181132652Sosa merge_loop 182132652Sosa ;; 183132652Sosa *) 184132652Sosa echo '' 185136878Sscottl echo " *** There is no installed version of ${COMPFILE}" 186137120Smaxim echo '' 187146071Smaxim HANDLE_COMPFILE="NOT V" 188147593Shrs ;; 189147593Shrs esac # End of "No installed version of file but user selected merge" test 190147593Shrs ;; 191147593Shrs [vV]) 192147593Shrs continue 193151926Smaxim ;; 194146071Smaxim '') 195137120Smaxim echo '' 196132652Sosa echo " *** ${COMPFILE} will remain for your consideration" 197132652Sosa ;; 19824424Swosch *) 19924424Swosch # invalid choice, show menu again. 20024424Swosch echo "invalid choice: ${HANDLE_COMPFILE}" 20124424Swosch echo '' 20269277Sasmodai HANDLE_COMPFILE="NOT V" 20369277Sasmodai continue 20424424Swosch ;; 20525031Swosch esac # End of "How to handle files that are different" 20625031Swosch done 20725031Swosch unset NO_INSTALLED 20880675Sasmodai echo '' 209104782Sjhb case "${VERBOSE}" in 210144864Smaxim '') ;; 21125031Swosch *) 212104782Sjhb sleep 3 213104782Sjhb ;; 214104782Sjhb esac 215104797Sjhb} 216104797Sjhb 21725031Swosch# Set the default path for the temporary root environment 21825031Swosch# 21925031SwoschTEMPROOT='/var/tmp/temproot' 22045349Swosch 22145349Swosch# Read /etc/mergemaster.rc first so the one in $HOME can override 222104782Sjhb# 223104782Sjhbif [ -r /etc/mergemaster.rc ]; then 224104782Sjhb . /etc/mergemaster.rc 225104782Sjhbfi 22642704Swosch 22725031Swosch# Read .mergemasterrc before command line so CLI can override 22824424Swosch# 22959769Sgrogif [ -r "$HOME/.mergemasterrc" ]; then 23025031Swosch . "$HOME/.mergemasterrc" 23125031Swoschfi 23225031Swosch 23325031Swosch# Check the command line options 23459769Sgrog# 23525031Swoschwhile getopts ":ascrvhipCm:t:du:w:D:" COMMAND_LINE_ARGUMENT ; do 23625031Swosch case "${COMMAND_LINE_ARGUMENT}" in 23725031Swosch s) 23825031Swosch STRICT=yes 23924424Swosch ;; 24025031Swosch c) 24125031Swosch DIFF_FLAG='-c' 24225031Swosch ;; 24325031Swosch r) 24425031Swosch RERUN=yes 24559769Sgrog ;; 24659769Sgrog v) 24742704Swosch case "${AUTO_RUN}" in 24842704Swosch '') VERBOSE=yes ;; 24942704Swosch esac 25070110Swosch ;; 25142704Swosch a) 25242704Swosch AUTO_RUN=yes 25325031Swosch unset VERBOSE 25425031Swosch ;; 25524424Swosch h) 25625031Swosch display_usage 25725031Swosch display_help 25825031Swosch exit 0 25925031Swosch ;; 26025031Swosch i) 26125031Swosch AUTO_INSTALL=yes 26225031Swosch ;; 26325031Swosch C) 26425031Swosch COMP_CONFS=yes 26524424Swosch ;; 26625031Swosch p) 26725031Swosch PRE_WORLD=yes 26825031Swosch unset COMP_CONFS 26925031Swosch unset AUTO_RUN 27025031Swosch ;; 27125031Swosch m) 27225031Swosch SOURCEDIR=${OPTARG} 27325031Swosch ;; 27459156Swosch t) 27525031Swosch TEMPROOT=${OPTARG} 27625031Swosch ;; 27725031Swosch d) 27825031Swosch TEMPROOT=${TEMPROOT}.`date +%m%d.%H.%M` 27925031Swosch ;; 28025031Swosch u) 28189981Sjoe NEW_UMASK=${OPTARG} 28225031Swosch ;; 28325031Swosch w) 28425031Swosch SCREEN_WIDTH=${OPTARG} 28524424Swosch ;; 28625031Swosch D) 28725031Swosch DESTDIR=${OPTARG} 28889981Sjoe ;; 28925031Swosch *) 29089981Sjoe display_usage 29189981Sjoe exit 1 29225031Swosch ;; 29389981Sjoe esac 29489981Sjoedone 29589981Sjoe 29670110Swoschecho '' 29771231Sitojun 29870110Swosch# If the user has a pager defined, make sure we can run it 29925031Swosch# 30071231Sitojuncase "${DONT_CHECK_PAGER}" in 30171231Sitojun'') 30269278Sasmodai while ! type "${PAGER%% *}" >/dev/null && [ -n "${PAGER}" ]; do 30325031Swosch echo " *** Your PAGER environment variable specifies '${PAGER}', but" 30471231Sitojun echo " due to the limited PATH that I use for security reasons," 30570110Swosch echo " I cannot execute it. So, what would you like to do?" 30671231Sitojun echo '' 30770110Swosch echo " Use 'e' to exit mergemaster and fix your PAGER variable" 30870110Swosch if [ -x /usr/bin/less -o -x /usr/local/bin/less ]; then 30971231Sitojun echo " Use 'l' to set PAGER to 'less' for this run" 31070110Swosch fi 31157000Swosch echo " Use 'm' to use plain old 'more' as your PAGER for this run" 31225031Swosch echo '' 31345349Swosch echo " Default is to use plain old 'more' " 31478270Snik echo '' 31571231Sitojun echo -n "What should I do? [Use 'more'] " 31625031Swosch read FIXPAGER 317147051Smaxim 318147051Smaxim case "${FIXPAGER}" in 319147051Smaxim [eE]) 320147051Smaxim exit 0 32157000Swosch ;; 32238440Sjkh [lL]) 323147055Smaxim if [ -x /usr/bin/less ]; then 32470110Swosch PAGER=/usr/bin/less 32569278Sasmodai elif [ -x /usr/local/bin/less ]; then 32670110Swosch PAGER=/usr/local/bin/less 32725031Swosch else 32825031Swosch echo '' 32969278Sasmodai echo " *** Fatal Error:" 33045349Swosch echo " You asked to use 'less' as your pager, but I can't" 33170110Swosch echo " find it in /usr/bin or /usr/local/bin" 33269278Sasmodai exit 1 33345349Swosch fi 33445349Swosch ;; 33569278Sasmodai [mM]|'') 33669278Sasmodai PAGER=more 33780675Sasmodai ;; 33869278Sasmodai *) 33970110Swosch echo '' 34069278Sasmodai echo "invalid choice: ${FIXPAGER}" 34169278Sasmodai esac 34269278Sasmodai echo '' 34357000Swosch done 34445349Swosch ;; 34569277Sasmodaiesac 34645349Swosch 34766542Sitojun# If user has a pager defined, or got assigned one above, use it. 34869277Sasmodai# If not, use more. 34957000Swosch# 35070110SwoschPAGER=${PAGER:-more} 35145349Swosch 35257000Swoschif [ -n "${VERBOSE}" -a ! "${PAGER}" = "more" ]; then 35369277Sasmodai echo " *** You have ${PAGER} defined as your pager so we will use that" 35470110Swosch echo '' 35570110Swosch sleep 3 35642589Swoschfi 35770110Swosch 35870110Swosch# Assign the diff flag once so we will not have to keep testing it 35946321Swosch# 36045349SwoschDIFF_FLAG=${DIFF_FLAG:--u} 36145349Swosch 36257000Swosch# Assign the source directory 36346318Swosch# 36470110SwoschSOURCEDIR=${SOURCEDIR:-/usr/src/etc} 36556406Swosch 36655389Sbillf# Check the width of the user's terminal 36755389Sbillf# 36857000Swoschif [ -t 0 ]; then 36955389Sbillf w=$(stty -a | sed -ne 's/.* \([0-9][0-9]*\) columns.*/\1/p') 37055389Sbillf case "${w}" in 37155389Sbillf 0|'') ;; # No-op, since the input is not valid 37270110Swosch *) 37358448Swosch case "${SCREEN_WIDTH}" in 37458448Swosch '') SCREEN_WIDTH="${w}" ;; 37565412Swosch "${w}") ;; # No-op, since they are the same 37664612Salex *) 37764612Salex echo -n "*** You entered ${SCREEN_WIDTH} as your screen width, but stty " 37865411Swosch echo "thinks it is ${w}." 37965974Swosch echo '' 38069277Sasmodai echo -n "What would you like to use? [${w}] " 38169277Sasmodai read SCREEN_WIDTH 38270119Swosch ;; 38369277Sasmodai esac 38470111Swosch esac 38580675Sasmodaifi 38675833Swosch 38778867Sitojun# Define what CVS $Id tag to look for to aid portability. 38879603Sitojun# 38984087SwoschCVS_ID_TAG=FreeBSD 39083686Sobrien 391104797Sjhbcase "${RERUN}" in 39287201Swosch'') 39392013Swosch # Set up the loop to test for the existence of the 394104772Smaxim # temp root directory. 395101331Swosch # 396101331Swosch TEST_TEMP_ROOT=yes 397104797Sjhb while [ "${TEST_TEMP_ROOT}" = "yes" ]; do 398104781Sjhb if [ -d "${TEMPROOT}" ]; then 399104781Sjhb echo "*** The directory specified for the temporary root environment," 400104781Sjhb echo " ${TEMPROOT}, exists. This can be a security risk if untrusted" 401104659Smurray echo " users have access to the system." 402106406Smaxim echo '' 403111949Swosch case "${AUTO_RUN}" in 404111949Swosch '') 405111949Swosch echo " Use 'd' to delete the old ${TEMPROOT} and continue" 406113054Smurray echo " Use 't' to select a new temporary root directory" 407114211Swosch echo " Use 'e' to exit mergemaster" 408114572Swosch echo '' 409119217Smurray echo " Default is to use ${TEMPROOT} as is" 410119217Smurray echo '' 411121648Smurray echo -n "How should I deal with this? [Use the existing ${TEMPROOT}] " 412121648Smurray read DELORNOT 413126724Swosch 414121787Swosch case "${DELORNOT}" in 415124462Smaxim [dD]) 416126235Swosch echo '' 417128863Smaxim echo " *** Deleting the old ${TEMPROOT}" 418128863Smaxim echo '' 419129793Shrs rm -rf "${TEMPROOT}" 420144864Smaxim unset TEST_TEMP_ROOT 421137120Smaxim ;; 422137326Shrs [tT]) 423138844Smaxim echo " *** Enter new directory name for temporary root environment" 424140831Smaxim read TEMPROOT 425144864Smaxim ;; 426147593Shrs [eE]) 427146091Smaxim exit 0 428146071Smaxim ;; 429146433Smaxim '') 430151926Smaxim echo '' 43124424Swosch echo " *** Leaving ${TEMPROOT} intact" 43224424Swosch echo '' 43324424Swosch unset TEST_TEMP_ROOT 43424424Swosch ;; 43524424Swosch *) 43624424Swosch echo '' 43724424Swosch echo "invalid choice: ${DELORNOT}" 43824424Swosch echo '' 43924424Swosch ;; 44024424Swosch esac 44124424Swosch ;; 44224424Swosch *) 44324424Swosch # If this is an auto-run, try a hopefully safe alternative then 44424424Swosch # re-test anyway. 44524424Swosch TEMPROOT=/var/tmp/temproot.`date +%m%d.%H.%M.%S` 446134378Sosa ;; 447134378Sosa esac 448134378Sosa else 449134378Sosa unset TEST_TEMP_ROOT 45025031Swosch fi 45125031Swosch done 45224424Swosch 45324424Swosch echo "*** Creating the temporary root environment in ${TEMPROOT}" 45424424Swosch 45524424Swosch if mkdir -p "${TEMPROOT}"; then 45659769Sgrog echo " *** ${TEMPROOT} ready for use" 457147051Smaxim fi 45824424Swosch 45925031Swosch if [ ! -d "${TEMPROOT}" ]; then 46025031Swosch echo '' 46125031Swosch echo " *** FATAL ERROR: Cannot create ${TEMPROOT}" 46225031Swosch echo '' 46359769Sgrog exit 1 46425031Swosch fi 46531658Swosch 46679514Sitojun echo " *** Creating and populating directory structure in ${TEMPROOT}" 46731658Swosch echo '' 46859769Sgrog 46979514Sitojun case "${VERBOSE}" in 47059769Sgrog '') ;; 47165415Swosch *) 472104786Sjhb echo " *** Press [Enter] or [Return] key to continue" 47365415Swosch read ANY_KEY 47475834Swosch unset ANY_KEY 47579514Sitojun ;; 47675834Swosch esac 47775834Swosch 47875834Swosch case "${PRE_WORLD}" in 47925031Swosch '') 48025031Swosch { cd ${SOURCEDIR} && 48125031Swosch case "${DESTDIR}" in 48259769Sgrog '') ;; 48325031Swosch *) 48425031Swosch make DESTDIR=${DESTDIR} distrib-dirs 48531658Swosch ;; 48625031Swosch esac 48724424Swosch make DESTDIR=${TEMPROOT} distrib-dirs && 488126235Swosch make MAKEOBJDIRPREFIX=${TEMPROOT}/usr/obj obj && 489121787Swosch make MAKEOBJDIRPREFIX=${TEMPROOT}/usr/obj DESTDIR=${TEMPROOT} \ 49042589Swosch -DNO_MAKEDEV_RUN distribution;} || 49150970Speter { echo ''; 492 echo " *** FATAL ERROR: Cannot 'cd' to ${SOURCEDIR} and install files to"; 493 echo " the temproot environment"; 494 echo ''; 495 exit 1;} 496 ;; 497 *) 498 # Only set up files that are crucial to {build|install}world 499 { mkdir -p ${TEMPROOT}/etc && 500 cp -p ${SOURCEDIR}/master.passwd ${TEMPROOT}/etc && 501 cp -p ${SOURCEDIR}/group ${TEMPROOT}/etc;} || 502 { echo ''; 503 echo ' *** FATAL ERROR: Cannot copy files to the temproot environment'; 504 echo ''; 505 exit 1;} 506 ;; 507 esac 508 509 # Doing the inventory and removing files that we don't want to compare only 510 # makes sense if we are not doing a rerun, since we have no way of knowing 511 # what happened to the files during previous incarnations. 512 case "${VERBOSE}" in 513 '') ;; 514 *) 515 echo '' 516 echo ' *** The following files exist only in the installed version of' 517 echo " ${DESTDIR}/etc. In the vast majority of cases these files" 518 echo ' are necessary parts of the system and should not be deleted.' 519 echo ' However because these files are not updated by this process you' 520 echo ' might want to verify their status before rebooting your system.' 521 echo '' 522 echo ' *** Press [Enter] or [Return] key to continue' 523 read ANY_KEY 524 unset ANY_KEY 525 diff -qr ${DESTDIR}/etc ${TEMPROOT}/etc | grep "^Only in /etc" | ${PAGER} 526 echo '' 527 echo ' *** Press [Enter] or [Return] key to continue' 528 read ANY_KEY 529 unset ANY_KEY 530 ;; 531 esac 532 533 # Avoid comparing the motd if the user specifies it in .mergemasterrc 534 case "${IGNORE_MOTD}" in 535 '') ;; 536 *) rm -f ${TEMPROOT}/etc/motd 537 ;; 538 esac 539 540 # Avoid trying to update MAKEDEV if /dev is on a devfs 541 if /sbin/sysctl vfs.devfs.generation > /dev/null 2>&1 ; then 542 rm -f ${TEMPROOT}/dev/MAKEDEV ${TEMPROOT}/dev/MAKEDEV.local 543 fi 544 545 ;; # End of the "RERUN" test 546esac 547 548# We really don't want to have to deal with these files, since 549# master.passwd is the real file that should be compared, then 550# the user should run pwd_mkdb if necessary. 551# 552rm -f ${TEMPROOT}/etc/spwd.db ${TEMPROOT}/etc/passwd ${TEMPROOT}/etc/pwd.db 553 554# We only need to compare things like freebsd.cf once 555find ${TEMPROOT}/usr/obj -type f -delete 2>/dev/null 556 557# Get ready to start comparing files 558 559# Check umask if not specified on the command line, 560# and we are not doing an autorun 561# 562if [ -z "${NEW_UMASK}" -a -z "${AUTO_RUN}" ]; then 563 USER_UMASK=`umask` 564 case "${USER_UMASK}" in 565 0022|022) ;; 566 *) 567 echo '' 568 echo " *** Your umask is currently set to ${USER_UMASK}. By default, this script" 569 echo " installs all files with the same user, group and modes that" 570 echo " they are created with by ${SOURCEDIR}/Makefile, compared to" 571 echo " a umask of 022. This umask allows world read permission when" 572 echo " the file's default permissions have it." 573 echo " No world permissions can sometimes cause problems. A umask of" 574 echo " 022 will restore the default behavior, but is not mandatory." 575 echo " /etc/master.passwd is a special case. Its file permissions" 576 echo " will be 600 (rw-------) if installed." 577 echo '' 578 echo -n "What umask should I use? [${USER_UMASK}] " 579 read NEW_UMASK 580 581 NEW_UMASK="${NEW_UMASK:-$USER_UMASK}" 582 ;; 583 esac 584 echo '' 585fi 586 587CONFIRMED_UMASK=${NEW_UMASK:-0022} 588 589# Warn users who still have ${DESTDIR}/etc/sysconfig 590# 591if [ -e "${DESTDIR}/etc/sysconfig" ]; then 592 echo '' 593 echo " *** There is a sysconfig file on this system in ${DESTDIR}/etc/." 594 echo '' 595 echo ' Starting with FreeBSD version 2.2.2 those settings moved from' 596 echo ' /etc/sysconfig to /etc/rc.conf. If you are upgrading an older' 597 echo ' system make sure that you transfer your settings by hand from' 598 echo ' sysconfig to rc.conf and install the rc.conf file. If you' 599 echo ' have already made this transition, you should consider' 600 echo ' renaming or deleting the sysconfig file.' 601 echo '' 602 case "${AUTO_RUN}" in 603 '') 604 echo -n "Continue with the merge process? [yes] " 605 read CONT_OR_NOT 606 607 case "${CONT_OR_NOT}" in 608 [nN]*) 609 exit 0 610 ;; 611 *) 612 echo " *** Continuing" 613 echo '' 614 ;; 615 esac 616 ;; 617 *) ;; 618 esac 619fi 620 621# Use the umask/mode information to install the files 622# Create directories as needed 623# 624do_install_and_rm () { 625 install -m "${1}" "${2}" "${3}" && 626 rm -f "${2}" 627} 628 629mm_install () { 630 local INSTALL_DIR 631 INSTALL_DIR=${1#.} 632 INSTALL_DIR=${INSTALL_DIR%/*} 633 634 case "${INSTALL_DIR}" in 635 '') 636 INSTALL_DIR=/ 637 ;; 638 esac 639 640 if [ -n "${DESTDIR}${INSTALL_DIR}" -a ! -d "${DESTDIR}${INSTALL_DIR}" ]; then 641 DIR_MODE=`perl -e 'printf "%04o\n", (((stat("$ARGV[0]"))[2] & 07777) &~ \ 642 oct("$ARGV[1]"))' "${TEMPROOT}/${INSTALL_DIR}" "${CONFIRMED_UMASK}"` 643 install -d -o root -g wheel -m "${DIR_MODE}" "${DESTDIR}${INSTALL_DIR}" 644 fi 645 646 FILE_MODE=`perl -e 'printf "%04o\n", (((stat("$ARGV[0]"))[2] & 07777) &~ \ 647 oct("$ARGV[1]"))' "${1}" "${CONFIRMED_UMASK}"` 648 649 if [ ! -x "${1}" ]; then 650 case "${1#.}" in 651 /etc/mail/aliases) 652 NEED_NEWALIASES=yes 653 ;; 654 /etc/login.conf) 655 NEED_CAP_MKDB=yes 656 ;; 657 /etc/master.passwd) 658 do_install_and_rm 600 "${1}" "${DESTDIR}${INSTALL_DIR}" 659 NEED_PWD_MKDB=yes 660 DONT_INSTALL=yes 661 ;; 662 /.cshrc | /.profile) 663 case "${AUTO_INSTALL}" in 664 '') 665 case "${LINK_EXPLAINED}" in 666 '') 667 echo " *** Historically BSD derived systems have had a" 668 echo " hard link from /.cshrc and /.profile to" 669 echo " their namesakes in /root. Please indicate" 670 echo " your preference below for bringing your" 671 echo " installed files up to date." 672 echo '' 673 LINK_EXPLAINED=yes 674 ;; 675 esac 676 677 echo " Use 'd' to delete the temporary ${COMPFILE}" 678 echo " Use 'l' to delete the existing ${DESTDIR}${COMPFILE#.} and create the link" 679 echo '' 680 echo " Default is to leave the temporary file to deal with by hand" 681 echo '' 682 echo -n " How should I handle ${COMPFILE}? [Leave it to install later] " 683 read HANDLE_LINK 684 ;; 685 *) # Part of AUTO_INSTALL 686 HANDLE_LINK=l 687 ;; 688 esac 689 690 case "${HANDLE_LINK}" in 691 [dD]*) 692 rm "${COMPFILE}" 693 echo '' 694 echo " *** Deleting ${COMPFILE}" 695 ;; 696 [lL]*) 697 echo '' 698 rm -f "${DESTDIR}${COMPFILE#.}" 699 if ln "${DESTDIR}/root/${COMPFILE##*/}" "${DESTDIR}${COMPFILE#.}"; then 700 echo " *** Link from ${DESTDIR}${COMPFILE#.} to ${DESTDIR}/root/${COMPFILE##*/} installed successfully" 701 rm "${COMPFILE}" 702 else 703 echo " *** Error linking ${DESTDIR}${COMPFILE#.} to ${DESTDIR}/root/${COMPFILE##*/}, ${COMPFILE} will remain to install by hand" 704 fi 705 ;; 706 *) 707 echo " *** ${COMPFILE} will remain for your consideration" 708 ;; 709 esac 710 DONT_INSTALL=yes 711 ;; 712 esac 713 714 case "${DONT_INSTALL}" in 715 '') 716 do_install_and_rm "${FILE_MODE}" "${1}" "${DESTDIR}${INSTALL_DIR}" 717 ;; 718 *) 719 unset DONT_INSTALL 720 ;; 721 esac 722 else # File matched -x 723 case "${1#.}" in 724 /dev/MAKEDEV) 725 NEED_MAKEDEV=yes 726 ;; 727 esac 728 do_install_and_rm "${FILE_MODE}" "${1}" "${DESTDIR}${INSTALL_DIR}" 729 fi 730 return $? 731} 732 733echo '' 734echo "*** Beginning comparison" 735echo '' 736 737cd "${TEMPROOT}" 738 739if [ -r "${MM_PRE_COMPARE_SCRIPT}" ]; then 740 . "${MM_PRE_COMPARE_SCRIPT}" 741fi 742 743# Using -size +0 avoids uselessly checking the empty log files created 744# by ${SOURCEDIR}/Makefile and the device entries in ./dev, but does 745# check the scripts in ./dev, as we'd like (assuming no devfs of course). 746# 747for COMPFILE in `find . -type f -size +0`; do 748 749 # First, check to see if the file exists in DESTDIR. If not, the 750 # diff_loop function knows how to handle it. 751 # 752 if [ ! -e "${DESTDIR}${COMPFILE#.}" ]; then 753 case "${AUTO_RUN}" in 754 '') 755 diff_loop 756 ;; 757 *) 758 case "${AUTO_INSTALL}" in 759 '') 760 # If this is an auto run, make it official 761 echo " *** ${COMPFILE} will remain for your consideration" 762 ;; 763 *) 764 diff_loop 765 ;; 766 esac 767 ;; 768 esac # Auto run test 769 continue 770 fi 771 772 case "${STRICT}" in 773 '' | [Nn][Oo]) 774 # Compare CVS $Id's first so if the file hasn't been modified 775 # local changes will be ignored. 776 # If the files have the same $Id, delete the one in temproot so the 777 # user will have less to wade through if files are left to merge by hand. 778 # 779 CVSID1=`grep "[$]${CVS_ID_TAG}:" ${DESTDIR}${COMPFILE#.} 2>/dev/null` 780 CVSID2=`grep "[$]${CVS_ID_TAG}:" ${COMPFILE} 2>/dev/null` || CVSID2=none 781 782 case "${CVSID2}" in 783 "${CVSID1}") 784 echo " *** Temp ${COMPFILE} and installed have the same CVS Id, deleting" 785 rm "${COMPFILE}" 786 ;; 787 esac 788 ;; 789 esac 790 791 # If the file is still here either because the $Ids are different, the 792 # file doesn't have an $Id, or we're using STRICT mode; look at the diff. 793 # 794 if [ -f "${COMPFILE}" ]; then 795 796 # Do an absolute diff first to see if the files are actually different. 797 # If they're not different, delete the one in temproot. 798 # 799 if diff -q "${DESTDIR}${COMPFILE#.}" "${COMPFILE}" > /dev/null 2>&1; then 800 echo " *** Temp ${COMPFILE} and installed are the same, deleting" 801 rm "${COMPFILE}" 802 else 803 # Ok, the files are different, so show the user where they differ. 804 # Use user's choice of diff methods; and user's pager if they have one. 805 # Use more if not. 806 # Use unified diffs by default. Context diffs give me a headache. :) 807 # 808 case "${AUTO_RUN}" in 809 '') 810 # prompt user to install/delete/merge changes 811 diff_loop 812 ;; 813 *) 814 # If this is an auto run, make it official 815 echo " *** ${COMPFILE} will remain for your consideration" 816 ;; 817 esac # Auto run test 818 fi # Yes, the files are different 819 fi # Yes, the file still remains to be checked 820done # This is for the do way up there at the beginning of the comparison 821 822echo '' 823echo "*** Comparison complete" 824echo '' 825 826TEST_FOR_FILES=`find ${TEMPROOT} -type f -size +0 2>/dev/null` 827if [ -n "${TEST_FOR_FILES}" ]; then 828 echo "*** Files that remain for you to merge by hand:" 829 find "${TEMPROOT}" -type f -size +0 830 echo '' 831fi 832 833case "${AUTO_RUN}" in 834'') 835 echo -n "Do you wish to delete what is left of ${TEMPROOT}? [no] " 836 read DEL_TEMPROOT 837 838 case "${DEL_TEMPROOT}" in 839 [yY]*) 840 if rm -rf "${TEMPROOT}"; then 841 echo " *** ${TEMPROOT} has been deleted" 842 else 843 echo " *** Unable to delete ${TEMPROOT}" 844 fi 845 ;; 846 *) 847 echo " *** ${TEMPROOT} will remain" 848 ;; 849 esac 850 ;; 851*) ;; 852esac 853 854case "${AUTO_INSTALLED_FILES}" in 855'') ;; 856*) 857 case "${AUTO_RUN}" in 858 '') 859 ( 860 echo '' 861 echo '*** You chose the automatic install option for files that did not' 862 echo ' exist on your system. The following were installed for you:' 863 echo "${AUTO_INSTALLED_FILES}" 864 ) | ${PAGER} 865 ;; 866 *) 867 echo '' 868 echo '*** You chose the automatic install option for files that did not' 869 echo ' exist on your system. The following were installed for you:' 870 echo "${AUTO_INSTALLED_FILES}" 871 ;; 872 esac 873 ;; 874esac 875 876run_it_now () { 877 case "${AUTO_RUN}" in 878 '') 879 unset YES_OR_NO 880 echo '' 881 echo -n ' Would you like to run it now? y or n [n] ' 882 read YES_OR_NO 883 884 case "${YES_OR_NO}" in 885 y) 886 echo " Running ${1}" 887 echo '' 888 eval "${1}" 889 ;; 890 ''|n) 891 echo '' 892 echo " *** Cancelled" 893 echo '' 894 echo " Make sure to run ${1} yourself" 895 ;; 896 *) 897 echo '' 898 echo " *** Sorry, I do not understand your answer (${YES_OR_NO})" 899 echo '' 900 echo " Make sure to run ${1} yourself" 901 esac 902 ;; 903 *) ;; 904 esac 905} 906 907case "${NEED_MAKEDEV}" in 908'') ;; 909*) 910 echo '' 911 echo "*** You installed a new ${DESTDIR}/dev/MAKEDEV script, so make sure that you run" 912 echo " 'cd ${DESTDIR}/dev && /bin/sh MAKEDEV all' to rebuild your devices" 913 run_it_now "cd ${DESTDIR}/dev && /bin/sh MAKEDEV all" 914 ;; 915esac 916 917case "${NEED_NEWALIASES}" in 918'') ;; 919*) 920 echo '' 921 if [ -n "${DESTDIR}" ]; then 922 echo "*** You installed a new aliases file into ${DESTDIR}/etc/mail, but" 923 echo " the newaliases command is limited to the directories configured" 924 echo " in sendmail.cf. Make sure to create your aliases database by" 925 echo " hand when your sendmail configuration is done." 926 else 927 echo "*** You installed a new aliases file, so make sure that you run" 928 echo " '/usr/bin/newaliases' to rebuild your aliases database" 929 run_it_now '/usr/bin/newaliases' 930 fi 931 ;; 932esac 933 934case "${NEED_CAP_MKDB}" in 935'') ;; 936*) 937 echo '' 938 echo "*** You installed a login.conf file, so make sure that you run" 939 echo " '/usr/bin/cap_mkdb ${DESTDIR}/etc/login.conf'" 940 echo " to rebuild your login.conf database" 941 run_it_now "/usr/bin/cap_mkdb ${DESTDIR}/etc/login.conf" 942 ;; 943esac 944 945case "${NEED_PWD_MKDB}" in 946'') ;; 947*) 948 echo '' 949 echo "*** You installed a new master.passwd file, so make sure that you run" 950 if [ -n "${DESTDIR}" ]; then 951 echo " '/usr/sbin/pwd_mkdb -d ${DESTDIR}/etc -p ${DESTDIR}/etc/master.passwd'" 952 echo " to rebuild your password files" 953 run_it_now "/usr/sbin/pwd_mkdb -d ${DESTDIR}/etc -p ${DESTDIR}/etc/master.passwd" 954 else 955 echo " '/usr/sbin/pwd_mkdb -p /etc/master.passwd'" 956 echo " to rebuild your password files" 957 run_it_now '/usr/sbin/pwd_mkdb -p /etc/master.passwd' 958 fi 959 ;; 960esac 961 962echo '' 963 964if [ -r "${MM_EXIT_SCRIPT}" ]; then 965 . "${MM_EXIT_SCRIPT}" 966fi 967 968case "${COMP_CONFS}" in 969'') ;; 970*) 971 . ${DESTDIR}/etc/defaults/rc.conf 972 973 (echo '' 974 echo "*** Comparing conf files: ${rc_conf_files}" 975 976 for CONF_FILE in ${rc_conf_files}; do 977 if [ -r "${DESTDIR}${CONF_FILE}" ]; then 978 echo '' 979 echo "*** From ${DESTDIR}${CONF_FILE}" 980 echo "*** From ${DESTDIR}/etc/defaults/rc.conf" 981 982 for RC_CONF_VAR in `grep -i ^[a-z] ${DESTDIR}${CONF_FILE} | 983 cut -d '=' -f 1`; do 984 echo '' 985 grep -w ^${RC_CONF_VAR} ${DESTDIR}${CONF_FILE} 986 grep -w ^${RC_CONF_VAR} ${DESTDIR}/etc/defaults/rc.conf || 987 echo ' * No default variable with this name' 988 done 989 fi 990 done) | ${PAGER} 991 echo '' 992 ;; 993esac 994 995case "${PRE_WORLD}" in 996'') ;; 997*) 998 MAKE_CONF="${SOURCEDIR%etc}share/examples/etc/make.conf" 999 1000 (echo '' 1001 echo '*** Comparing make variables' 1002 echo '' 1003 echo "*** From ${DESTDIR}/etc/make.conf" 1004 echo "*** From ${MAKE_CONF}" 1005 1006 for MAKE_VAR in `grep -i ^[a-z] /etc/make.conf | cut -d '=' -f 1`; do 1007 echo '' 1008 grep -w ^${MAKE_VAR} ${DESTDIR}/etc/make.conf 1009 grep -w ^#${MAKE_VAR} ${MAKE_CONF} || 1010 echo ' * No example variable with this name' 1011 done) | ${PAGER} 1012 ;; 1013esac 1014 1015exit 0 1016 1017