mergemaster.sh revision 155309
1#!/bin/sh 2 3# mergemaster 4 5# Compare files created by /usr/src/etc/Makefile (or the directory 6# the user specifies) with the currently installed copies. 7 8# Copyright 1998-2004 Douglas Barton 9# DougB@FreeBSD.org 10 11# $FreeBSD: head/usr.sbin/mergemaster/mergemaster.sh 155309 2006-02-04 18:24:06Z rwatson $ 12 13PATH=/bin:/usr/bin:/usr/sbin 14 15display_usage () { 16 VERSION_NUMBER=`grep "[$]FreeBSD:" $0 | cut -d ' ' -f 4` 17 echo "mergemaster version ${VERSION_NUMBER}" 18 echo 'Usage: mergemaster [-scrvahipCP] [-m /path]' 19 echo ' [-t /path] [-d] [-u N] [-w N] [-D /path]' 20 echo "Options:" 21 echo " -s Strict comparison (diff every pair of files)" 22 echo " -c Use context diff instead of unified diff" 23 echo " -r Re-run on a previously cleaned directory (skip temproot creation)" 24 echo " -v Be more verbose about the process, include additional checks" 25 echo " -a Leave all files that differ to merge by hand" 26 echo " -h Display more complete help" 27 echo ' -i Automatically install files that do not exist in destination directory' 28 echo ' -p Pre-buildworld mode, only compares crucial files' 29 echo ' -C Compare local rc.conf variables to the defaults' 30 echo ' -P Preserve files that are overwritten' 31 echo " -m /path/directory Specify location of source to do the make in" 32 echo " -t /path/directory Specify temp root directory" 33 echo " -d Add date and time to directory name (e.g., /var/tmp/temproot.`date +%m%d.%H.%M`)" 34 echo " -u N Specify a numeric umask" 35 echo " -w N Specify a screen width in columns to sdiff" 36 echo " -A architecture Alternative architecture name to pass to make" 37 echo ' -D /path/directory Specify the destination directory to install files to' 38 echo '' 39} 40 41display_help () { 42 echo "* To specify a directory other than /var/tmp/temproot for the" 43 echo " temporary root environment, use -t /path/to/temp/root" 44 echo "* The -w option takes a number as an argument for the column width" 45 echo " of the screen. The default is 80." 46 echo '* The -a option causes mergemaster to run without prompting.' 47} 48 49# Loop allowing the user to use sdiff to merge files and display the merged 50# file. 51merge_loop () { 52 case "${VERBOSE}" in 53 '') ;; 54 *) 55 echo " *** Type h at the sdiff prompt (%) to get usage help" 56 ;; 57 esac 58 echo '' 59 MERGE_AGAIN=yes 60 while [ "${MERGE_AGAIN}" = "yes" ]; do 61 # Prime file.merged so we don't blat the owner/group id's 62 cp -p "${COMPFILE}" "${COMPFILE}.merged" 63 sdiff -o "${COMPFILE}.merged" --text --suppress-common-lines \ 64 --width=${SCREEN_WIDTH:-80} "${DESTDIR}${COMPFILE#.}" "${COMPFILE}" 65 INSTALL_MERGED=V 66 while [ "${INSTALL_MERGED}" = "v" -o "${INSTALL_MERGED}" = "V" ]; do 67 echo '' 68 echo " Use 'i' to install merged file" 69 echo " Use 'r' to re-do the merge" 70 echo " Use 'v' to view the merged file" 71 echo " Default is to leave the temporary file to deal with by hand" 72 echo '' 73 echo -n " *** How should I deal with the merged file? [Leave it for later] " 74 read INSTALL_MERGED 75 76 case "${INSTALL_MERGED}" in 77 [iI]) 78 mv "${COMPFILE}.merged" "${COMPFILE}" 79 echo '' 80 if mm_install "${COMPFILE}"; then 81 echo " *** Merged version of ${COMPFILE} installed successfully" 82 else 83 echo " *** Problem installing ${COMPFILE}, it will remain to merge by hand later" 84 fi 85 unset MERGE_AGAIN 86 ;; 87 [rR]) 88 rm "${COMPFILE}.merged" 89 ;; 90 [vV]) 91 ${PAGER} "${COMPFILE}.merged" 92 ;; 93 '') 94 echo " *** ${COMPFILE} will remain for your consideration" 95 unset MERGE_AGAIN 96 ;; 97 *) 98 echo "invalid choice: ${INSTALL_MERGED}" 99 INSTALL_MERGED=V 100 ;; 101 esac 102 done 103 done 104} 105 106# Loop showing user differences between files, allow merge, skip or install 107# options 108diff_loop () { 109 110 HANDLE_COMPFILE=v 111 112 while [ "${HANDLE_COMPFILE}" = "v" -o "${HANDLE_COMPFILE}" = "V" -o \ 113 "${HANDLE_COMPFILE}" = "NOT V" ]; do 114 if [ -f "${DESTDIR}${COMPFILE#.}" -a -f "${COMPFILE}" ]; then 115 if [ "${HANDLE_COMPFILE}" = "v" -o "${HANDLE_COMPFILE}" = "V" ]; then 116 echo '' 117 echo ' ====================================================================== ' 118 echo '' 119 ( 120 echo " *** Displaying differences between ${COMPFILE} and installed version:" 121 echo '' 122 diff ${DIFF_FLAG} ${DIFF_OPTIONS} "${DESTDIR}${COMPFILE#.}" "${COMPFILE}" 123 ) | ${PAGER} 124 echo '' 125 fi 126 else 127 echo '' 128 echo " *** There is no installed version of ${COMPFILE}" 129 echo '' 130 case "${AUTO_INSTALL}" in 131 [Yy][Ee][Ss]) 132 echo '' 133 if mm_install "${COMPFILE}"; then 134 echo " *** ${COMPFILE} installed successfully" 135 echo '' 136 # Make the list print one file per line 137 AUTO_INSTALLED_FILES="${AUTO_INSTALLED_FILES} ${DESTDIR}${COMPFILE#.} 138" 139 else 140 echo " *** Problem installing ${COMPFILE}, it will remain to merge by hand" 141 fi 142 return 143 ;; 144 *) 145 NO_INSTALLED=yes 146 ;; 147 esac 148 fi 149 150 echo " Use 'd' to delete the temporary ${COMPFILE}" 151 echo " Use 'i' to install the temporary ${COMPFILE}" 152 case "${NO_INSTALLED}" in 153 '') 154 echo " Use 'm' to merge the temporary and installed versions" 155 echo " Use 'v' to view the diff results again" 156 ;; 157 esac 158 echo '' 159 echo " Default is to leave the temporary file to deal with by hand" 160 echo '' 161 echo -n "How should I deal with this? [Leave it for later] " 162 read HANDLE_COMPFILE 163 164 case "${HANDLE_COMPFILE}" in 165 [dD]) 166 rm "${COMPFILE}" 167 echo '' 168 echo " *** Deleting ${COMPFILE}" 169 ;; 170 [iI]) 171 echo '' 172 if mm_install "${COMPFILE}"; then 173 echo " *** ${COMPFILE} installed successfully" 174 else 175 echo " *** Problem installing ${COMPFILE}, it will remain to merge by hand" 176 fi 177 ;; 178 [mM]) 179 case "${NO_INSTALLED}" in 180 '') 181 # interact with user to merge files 182 merge_loop 183 ;; 184 *) 185 echo '' 186 echo " *** There is no installed version of ${COMPFILE}" 187 echo '' 188 HANDLE_COMPFILE="NOT V" 189 ;; 190 esac # End of "No installed version of file but user selected merge" test 191 ;; 192 [vV]) 193 continue 194 ;; 195 '') 196 echo '' 197 echo " *** ${COMPFILE} will remain for your consideration" 198 ;; 199 *) 200 # invalid choice, show menu again. 201 echo "invalid choice: ${HANDLE_COMPFILE}" 202 echo '' 203 HANDLE_COMPFILE="NOT V" 204 continue 205 ;; 206 esac # End of "How to handle files that are different" 207 done 208 unset NO_INSTALLED 209 echo '' 210 case "${VERBOSE}" in 211 '') ;; 212 *) 213 sleep 3 214 ;; 215 esac 216} 217 218press_to_continue () { 219 local DISCARD 220 echo -n ' *** Press the [Enter] or [Return] key to continue ' 221 read DISCARD 222} 223 224# Set the default path for the temporary root environment 225# 226TEMPROOT='/var/tmp/temproot' 227 228# Read /etc/mergemaster.rc first so the one in $HOME can override 229# 230if [ -r /etc/mergemaster.rc ]; then 231 . /etc/mergemaster.rc 232fi 233 234# Read .mergemasterrc before command line so CLI can override 235# 236if [ -r "$HOME/.mergemasterrc" ]; then 237 . "$HOME/.mergemasterrc" 238fi 239 240# Check the command line options 241# 242while getopts ":ascrvhipCPm:t:du:w:D:A:" COMMAND_LINE_ARGUMENT ; do 243 case "${COMMAND_LINE_ARGUMENT}" in 244 A) 245 ARCHSTRING='MACHINE_ARCH='${OPTARG} 246 ;; 247 s) 248 STRICT=yes 249 unset DIFF_OPTIONS 250 ;; 251 c) 252 DIFF_FLAG='-c' 253 ;; 254 r) 255 RERUN=yes 256 ;; 257 v) 258 case "${AUTO_RUN}" in 259 '') VERBOSE=yes ;; 260 esac 261 ;; 262 a) 263 AUTO_RUN=yes 264 unset VERBOSE 265 ;; 266 h) 267 display_usage 268 display_help 269 exit 0 270 ;; 271 i) 272 AUTO_INSTALL=yes 273 ;; 274 C) 275 COMP_CONFS=yes 276 ;; 277 P) 278 PRESERVE_FILES=yes 279 ;; 280 p) 281 PRE_WORLD=yes 282 unset COMP_CONFS 283 unset AUTO_RUN 284 ;; 285 m) 286 SOURCEDIR=${OPTARG} 287 ;; 288 t) 289 TEMPROOT=${OPTARG} 290 ;; 291 d) 292 TEMPROOT=${TEMPROOT}.`date +%m%d.%H.%M` 293 ;; 294 u) 295 NEW_UMASK=${OPTARG} 296 ;; 297 w) 298 SCREEN_WIDTH=${OPTARG} 299 ;; 300 D) 301 DESTDIR=${OPTARG} 302 ;; 303 *) 304 display_usage 305 exit 1 306 ;; 307 esac 308done 309 310# Don't force the user to set this in the mergemaster rc file 311if [ -n "${PRESERVE_FILES}" -a -z "${PRESERVE_FILES_DIR}" ]; then 312 PRESERVE_FILES_DIR=/var/tmp/mergemaster/preserved-files-`date +%y%m%d-%H%M%S` 313fi 314 315echo '' 316 317# If the user has a pager defined, make sure we can run it 318# 319case "${DONT_CHECK_PAGER}" in 320'') 321 while ! type "${PAGER%% *}" >/dev/null && [ -n "${PAGER}" ]; do 322 echo " *** Your PAGER environment variable specifies '${PAGER}', but" 323 echo " due to the limited PATH that I use for security reasons," 324 echo " I cannot execute it. So, what would you like to do?" 325 echo '' 326 echo " Use 'e' to exit mergemaster and fix your PAGER variable" 327 if [ -x /usr/bin/less -o -x /usr/local/bin/less ]; then 328 echo " Use 'l' to set PAGER to 'less' for this run" 329 fi 330 echo " Use 'm' to use plain old 'more' as your PAGER for this run" 331 echo '' 332 echo " Default is to use plain old 'more' " 333 echo '' 334 echo -n "What should I do? [Use 'more'] " 335 read FIXPAGER 336 337 case "${FIXPAGER}" in 338 [eE]) 339 exit 0 340 ;; 341 [lL]) 342 if [ -x /usr/bin/less ]; then 343 PAGER=/usr/bin/less 344 elif [ -x /usr/local/bin/less ]; then 345 PAGER=/usr/local/bin/less 346 else 347 echo '' 348 echo " *** Fatal Error:" 349 echo " You asked to use 'less' as your pager, but I can't" 350 echo " find it in /usr/bin or /usr/local/bin" 351 exit 1 352 fi 353 ;; 354 [mM]|'') 355 PAGER=more 356 ;; 357 *) 358 echo '' 359 echo "invalid choice: ${FIXPAGER}" 360 esac 361 echo '' 362 done 363 ;; 364esac 365 366# If user has a pager defined, or got assigned one above, use it. 367# If not, use more. 368# 369PAGER=${PAGER:-more} 370 371if [ -n "${VERBOSE}" -a ! "${PAGER}" = "more" ]; then 372 echo " *** You have ${PAGER} defined as your pager so we will use that" 373 echo '' 374 sleep 3 375fi 376 377# Assign the diff flag once so we will not have to keep testing it 378# 379DIFF_FLAG=${DIFF_FLAG:--u} 380 381# Assign the source directory 382# 383SOURCEDIR=${SOURCEDIR:-/usr/src/etc} 384 385# Check the width of the user's terminal 386# 387if [ -t 0 ]; then 388 w=`tput columns` 389 case "${w}" in 390 0|'') ;; # No-op, since the input is not valid 391 *) 392 case "${SCREEN_WIDTH}" in 393 '') SCREEN_WIDTH="${w}" ;; 394 "${w}") ;; # No-op, since they are the same 395 *) 396 echo -n "*** You entered ${SCREEN_WIDTH} as your screen width, but stty " 397 echo "thinks it is ${w}." 398 echo '' 399 echo -n "What would you like to use? [${w}] " 400 read SCREEN_WIDTH 401 case "${SCREEN_WIDTH}" in 402 '') SCREEN_WIDTH="${w}" ;; 403 esac 404 ;; 405 esac 406 esac 407fi 408 409# Define what CVS $Id tag to look for to aid portability. 410# 411CVS_ID_TAG=FreeBSD 412 413delete_temproot () { 414 rm -rf "${TEMPROOT}" 2>/dev/null 415 chflags -R 0 "${TEMPROOT}" 2>/dev/null 416 rm -rf "${TEMPROOT}" || exit 1 417} 418 419case "${RERUN}" in 420'') 421 # Set up the loop to test for the existence of the 422 # temp root directory. 423 # 424 TEST_TEMP_ROOT=yes 425 while [ "${TEST_TEMP_ROOT}" = "yes" ]; do 426 if [ -d "${TEMPROOT}" ]; then 427 echo "*** The directory specified for the temporary root environment," 428 echo " ${TEMPROOT}, exists. This can be a security risk if untrusted" 429 echo " users have access to the system." 430 echo '' 431 case "${AUTO_RUN}" in 432 '') 433 echo " Use 'd' to delete the old ${TEMPROOT} and continue" 434 echo " Use 't' to select a new temporary root directory" 435 echo " Use 'e' to exit mergemaster" 436 echo '' 437 echo " Default is to use ${TEMPROOT} as is" 438 echo '' 439 echo -n "How should I deal with this? [Use the existing ${TEMPROOT}] " 440 read DELORNOT 441 442 case "${DELORNOT}" in 443 [dD]) 444 echo '' 445 echo " *** Deleting the old ${TEMPROOT}" 446 echo '' 447 delete_temproot || exit 1 448 unset TEST_TEMP_ROOT 449 ;; 450 [tT]) 451 echo " *** Enter new directory name for temporary root environment" 452 read TEMPROOT 453 ;; 454 [eE]) 455 exit 0 456 ;; 457 '') 458 echo '' 459 echo " *** Leaving ${TEMPROOT} intact" 460 echo '' 461 unset TEST_TEMP_ROOT 462 ;; 463 *) 464 echo '' 465 echo "invalid choice: ${DELORNOT}" 466 echo '' 467 ;; 468 esac 469 ;; 470 *) 471 # If this is an auto-run, try a hopefully safe alternative then 472 # re-test anyway. 473 TEMPROOT=/var/tmp/temproot.`date +%m%d.%H.%M.%S` 474 ;; 475 esac 476 else 477 unset TEST_TEMP_ROOT 478 fi 479 done 480 481 echo "*** Creating the temporary root environment in ${TEMPROOT}" 482 483 if mkdir -p "${TEMPROOT}"; then 484 echo " *** ${TEMPROOT} ready for use" 485 fi 486 487 if [ ! -d "${TEMPROOT}" ]; then 488 echo '' 489 echo " *** FATAL ERROR: Cannot create ${TEMPROOT}" 490 echo '' 491 exit 1 492 fi 493 494 echo " *** Creating and populating directory structure in ${TEMPROOT}" 495 echo '' 496 497 case "${VERBOSE}" in 498 '') ;; 499 *) 500 press_to_continue 501 ;; 502 esac 503 504 case "${PRE_WORLD}" in 505 '') 506 { cd ${SOURCEDIR} && 507 case "${DESTDIR}" in 508 '') ;; 509 *) 510 make DESTDIR=${DESTDIR} ${ARCHSTRING} distrib-dirs 511 ;; 512 esac 513 make DESTDIR=${TEMPROOT} ${ARCHSTRING} distrib-dirs && 514 MAKEOBJDIRPREFIX=${TEMPROOT}/usr/obj make ${ARCHSTRING} obj && 515 MAKEOBJDIRPREFIX=${TEMPROOT}/usr/obj make ${ARCHSTRING} all && 516 MAKEOBJDIRPREFIX=${TEMPROOT}/usr/obj make ${ARCHSTRING} \ 517 DESTDIR=${TEMPROOT} distribution;} || 518 { echo ''; 519 echo " *** FATAL ERROR: Cannot 'cd' to ${SOURCEDIR} and install files to"; 520 echo " the temproot environment"; 521 echo ''; 522 exit 1;} 523 ;; 524 *) 525 # Only set up files that are crucial to {build|install}world 526 { mkdir -p ${TEMPROOT}/etc && 527 cp -p ${SOURCEDIR}/master.passwd ${TEMPROOT}/etc && 528 cp -p ${SOURCEDIR}/group ${TEMPROOT}/etc;} || 529 { echo ''; 530 echo ' *** FATAL ERROR: Cannot copy files to the temproot environment'; 531 echo ''; 532 exit 1;} 533 ;; 534 esac 535 536 # Doing the inventory and removing files that we don't want to compare only 537 # makes sense if we are not doing a rerun, since we have no way of knowing 538 # what happened to the files during previous incarnations. 539 case "${VERBOSE}" in 540 '') ;; 541 *) 542 echo '' 543 echo ' *** The following files exist only in the installed version of' 544 echo " ${DESTDIR}/etc. In the vast majority of cases these files" 545 echo ' are necessary parts of the system and should not be deleted.' 546 echo ' However because these files are not updated by this process you' 547 echo ' might want to verify their status before rebooting your system.' 548 echo '' 549 press_to_continue 550 diff -qr ${DESTDIR}/etc ${TEMPROOT}/etc | grep "^Only in ${DESTDIR}/etc" | ${PAGER} 551 echo '' 552 press_to_continue 553 ;; 554 esac 555 556 # Avoid comparing the motd if the user specifies it in .mergemasterrc 557 case "${IGNORE_MOTD}" in 558 '') ;; 559 *) rm -f ${TEMPROOT}/etc/motd 560 ;; 561 esac 562 563 # Avoid trying to update MAKEDEV if /dev is on a devfs 564 if /sbin/sysctl vfs.devfs.generation > /dev/null 2>&1 ; then 565 rm -f ${TEMPROOT}/dev/MAKEDEV ${TEMPROOT}/dev/MAKEDEV.local 566 fi 567 568 ;; # End of the "RERUN" test 569esac 570 571# We really don't want to have to deal with files like login.conf.db, pwd.db, 572# or spwd.db. Instead, we want to compare the text versions, and run *_mkdb. 573# Prompt the user to do so below, as needed. 574# 575rm -f ${TEMPROOT}/etc/*.db ${TEMPROOT}/etc/passwd 576 577# We only need to compare things like freebsd.cf once 578find ${TEMPROOT}/usr/obj -type f -delete 2>/dev/null 579 580# Get ready to start comparing files 581 582# Check umask if not specified on the command line, 583# and we are not doing an autorun 584# 585if [ -z "${NEW_UMASK}" -a -z "${AUTO_RUN}" ]; then 586 USER_UMASK=`umask` 587 case "${USER_UMASK}" in 588 0022|022) ;; 589 *) 590 echo '' 591 echo " *** Your umask is currently set to ${USER_UMASK}. By default, this script" 592 echo " installs all files with the same user, group and modes that" 593 echo " they are created with by ${SOURCEDIR}/Makefile, compared to" 594 echo " a umask of 022. This umask allows world read permission when" 595 echo " the file's default permissions have it." 596 echo '' 597 echo " No world permissions can sometimes cause problems. A umask of" 598 echo " 022 will restore the default behavior, but is not mandatory." 599 echo " /etc/master.passwd is a special case. Its file permissions" 600 echo " will be 600 (rw-------) if installed." 601 echo '' 602 echo -n "What umask should I use? [${USER_UMASK}] " 603 read NEW_UMASK 604 605 NEW_UMASK="${NEW_UMASK:-$USER_UMASK}" 606 ;; 607 esac 608 echo '' 609fi 610 611CONFIRMED_UMASK=${NEW_UMASK:-0022} 612 613# 614# Warn users who still have old rc files 615# 616for file in atm devfs diskless1 diskless2 isdn network network6 pccard \ 617 serial syscons sysctl alpha amd64 i386 ia64 sparc64; do 618 if [ -f "${DESTDIR}/etc/rc.${file}" ]; then 619 OLD_RC_PRESENT=1 620 break 621 fi 622done 623 624case "${OLD_RC_PRESENT}" in 6251) 626 echo '' 627 echo " *** There are elements of the old rc system in ${DESTDIR}/etc/." 628 echo '' 629 echo ' While these scripts will not hurt anything, they are not' 630 echo ' functional on an up to date system, and can be removed.' 631 echo '' 632 633 case "${AUTO_RUN}" in 634 '') 635 echo -n 'Move these files to /var/tmp/mergemaster/old_rc? [yes] ' 636 read MOVE_OLD_RC 637 638 case "${MOVE_OLD_RC}" in 639 [nN]*) ;; 640 *) 641 mkdir -p /var/tmp/mergemaster/old_rc 642 for file in atm devfs diskless1 diskless2 isdn network network6 pccard \ 643 serial syscons sysctl alpha amd64 i386 ia64 sparc64; do 644 if [ -f "${DESTDIR}/etc/rc.${file}" ]; then 645 mv ${DESTDIR}/etc/rc.${file} /var/tmp/mergemaster/old_rc/ 646 fi 647 done 648 echo ' The files have been moved' 649 press_to_continue 650 ;; 651 esac 652 ;; 653 *) ;; 654 esac 655esac 656 657# Use the umask/mode information to install the files 658# Create directories as needed 659# 660do_install_and_rm () { 661 case "${PRESERVE_FILES}" in 662 [Yy][Ee][Ss]) 663 if [ -f "${3}/${2##*/}" ]; then 664 mkdir -p ${PRESERVE_FILES_DIR}/${2%/*} 665 cp ${3}/${2##*/} ${PRESERVE_FILES_DIR}/${2%/*} 666 fi 667 ;; 668 esac 669 670 install -m "${1}" "${2}" "${3}" && 671 rm -f "${2}" 672} 673 674# 4095 = "obase=10;ibase=8;07777" | bc 675find_mode () { 676 local OCTAL 677 OCTAL=$(( ~$(echo "obase=10; ibase=8; ${CONFIRMED_UMASK}" | bc) & 4095 & 678 $(echo "obase=10; ibase=8; $(stat -f "%OMp%OLp" ${1})" | bc) )) 679 printf "%04o\n" ${OCTAL} 680} 681 682mm_install () { 683 local INSTALL_DIR 684 INSTALL_DIR=${1#.} 685 INSTALL_DIR=${INSTALL_DIR%/*} 686 687 case "${INSTALL_DIR}" in 688 '') 689 INSTALL_DIR=/ 690 ;; 691 esac 692 693 if [ -n "${DESTDIR}${INSTALL_DIR}" -a ! -d "${DESTDIR}${INSTALL_DIR}" ]; then 694 DIR_MODE=`find_mode "${TEMPROOT}/${INSTALL_DIR}"` 695 install -d -o root -g wheel -m "${DIR_MODE}" "${DESTDIR}${INSTALL_DIR}" 696 fi 697 698 FILE_MODE=`find_mode "${1}"` 699 700 if [ ! -x "${1}" ]; then 701 case "${1#.}" in 702 /etc/mail/aliases) 703 NEED_NEWALIASES=yes 704 ;; 705 /etc/login.conf) 706 NEED_CAP_MKDB=yes 707 ;; 708 /etc/master.passwd) 709 do_install_and_rm 600 "${1}" "${DESTDIR}${INSTALL_DIR}" 710 NEED_PWD_MKDB=yes 711 DONT_INSTALL=yes 712 ;; 713 /.cshrc | /.profile) 714 case "${AUTO_INSTALL}" in 715 '') 716 case "${LINK_EXPLAINED}" in 717 '') 718 echo " *** Historically BSD derived systems have had a" 719 echo " hard link from /.cshrc and /.profile to" 720 echo " their namesakes in /root. Please indicate" 721 echo " your preference below for bringing your" 722 echo " installed files up to date." 723 echo '' 724 LINK_EXPLAINED=yes 725 ;; 726 esac 727 728 echo " Use 'd' to delete the temporary ${COMPFILE}" 729 echo " Use 'l' to delete the existing ${DESTDIR}${COMPFILE#.} and create the link" 730 echo '' 731 echo " Default is to leave the temporary file to deal with by hand" 732 echo '' 733 echo -n " How should I handle ${COMPFILE}? [Leave it to install later] " 734 read HANDLE_LINK 735 ;; 736 *) # Part of AUTO_INSTALL 737 HANDLE_LINK=l 738 ;; 739 esac 740 741 case "${HANDLE_LINK}" in 742 [dD]*) 743 rm "${COMPFILE}" 744 echo '' 745 echo " *** Deleting ${COMPFILE}" 746 ;; 747 [lL]*) 748 echo '' 749 rm -f "${DESTDIR}${COMPFILE#.}" 750 if ln "${DESTDIR}/root/${COMPFILE##*/}" "${DESTDIR}${COMPFILE#.}"; then 751 echo " *** Link from ${DESTDIR}${COMPFILE#.} to ${DESTDIR}/root/${COMPFILE##*/} installed successfully" 752 rm "${COMPFILE}" 753 else 754 echo " *** Error linking ${DESTDIR}${COMPFILE#.} to ${DESTDIR}/root/${COMPFILE##*/}, ${COMPFILE} will remain to install by hand" 755 fi 756 ;; 757 *) 758 echo " *** ${COMPFILE} will remain for your consideration" 759 ;; 760 esac 761 DONT_INSTALL=yes 762 ;; 763 esac 764 765 case "${DONT_INSTALL}" in 766 '') 767 do_install_and_rm "${FILE_MODE}" "${1}" "${DESTDIR}${INSTALL_DIR}" 768 ;; 769 *) 770 unset DONT_INSTALL 771 ;; 772 esac 773 else # File matched -x 774 case "${1#.}" in 775 /dev/MAKEDEV) 776 NEED_MAKEDEV=yes 777 ;; 778 esac 779 do_install_and_rm "${FILE_MODE}" "${1}" "${DESTDIR}${INSTALL_DIR}" 780 fi 781 return $? 782} 783 784echo '' 785echo "*** Beginning comparison" 786echo '' 787 788# Pre-world does not populate /etc/rc.d. 789# It is very possible that a previous run would have deleted files in 790# ${TEMPROOT}/etc/rc.d, thus creating a lot of false positives. 791if [ -z "${PRE_WORLD}" -a -z "${RERUN}" ]; then 792 echo " *** Checking ${DESTDIR}/etc/rc.d for stale files" 793 echo '' 794 cd "${DESTDIR}/etc/rc.d" && 795 for file in *; do 796 if [ ! -e "${TEMPROOT}/etc/rc.d/${file}" ]; then 797 STALE_RC_FILES="${STALE_RC_FILES} ${file}" 798 fi 799 done 800 case "${STALE_RC_FILES}" in 801 ''|' *') 802 echo ' *** No stale files found' 803 ;; 804 *) 805 echo " *** The following files exist in ${DESTDIR}/etc/rc.d but not in" 806 echo " ${TEMPROOT}/etc/rc.d/:" 807 echo '' 808 echo "${STALE_RC_FILES}" 809 echo '' 810 echo ' The presence of stale files in this directory can cause the' 811 echo ' dreaded unpredictable results, and therefore it is highly' 812 echo ' recommended that you delete them.' 813 case "${AUTO_RUN}" in 814 '') 815 echo '' 816 echo -n ' *** Delete them now? [n] ' 817 read DELETE_STALE_RC_FILES 818 case "${DELETE_STALE_RC_FILES}" in 819 [yY]) 820 echo ' *** Deleting ... ' 821 rm ${STALE_RC_FILES} 822 echo ' done.' 823 ;; 824 *) 825 echo ' *** Files will not be deleted' 826 ;; 827 esac 828 sleep 2 829 ;; 830 esac 831 ;; 832 esac 833 echo '' 834fi 835 836cd "${TEMPROOT}" 837 838if [ -r "${MM_PRE_COMPARE_SCRIPT}" ]; then 839 . "${MM_PRE_COMPARE_SCRIPT}" 840fi 841 842# Using -size +0 avoids uselessly checking the empty log files created 843# by ${SOURCEDIR}/Makefile and the device entries in ./dev, but does 844# check the scripts in ./dev, as we'd like (assuming no devfs of course). 845# 846for COMPFILE in `find . -type f -size +0`; do 847 848 # First, check to see if the file exists in DESTDIR. If not, the 849 # diff_loop function knows how to handle it. 850 # 851 if [ ! -e "${DESTDIR}${COMPFILE#.}" ]; then 852 case "${AUTO_RUN}" in 853 '') 854 diff_loop 855 ;; 856 *) 857 case "${AUTO_INSTALL}" in 858 '') 859 # If this is an auto run, make it official 860 echo " *** ${COMPFILE} will remain for your consideration" 861 ;; 862 *) 863 diff_loop 864 ;; 865 esac 866 ;; 867 esac # Auto run test 868 continue 869 fi 870 871 case "${STRICT}" in 872 '' | [Nn][Oo]) 873 # Compare CVS $Id's first so if the file hasn't been modified 874 # local changes will be ignored. 875 # If the files have the same $Id, delete the one in temproot so the 876 # user will have less to wade through if files are left to merge by hand. 877 # 878 CVSID1=`grep "[$]${CVS_ID_TAG}:" ${DESTDIR}${COMPFILE#.} 2>/dev/null` 879 CVSID2=`grep "[$]${CVS_ID_TAG}:" ${COMPFILE} 2>/dev/null` || CVSID2=none 880 881 case "${CVSID2}" in 882 "${CVSID1}") 883 echo " *** Temp ${COMPFILE} and installed have the same CVS Id, deleting" 884 rm "${COMPFILE}" 885 ;; 886 esac 887 ;; 888 esac 889 890 # If the file is still here either because the $Ids are different, the 891 # file doesn't have an $Id, or we're using STRICT mode; look at the diff. 892 # 893 if [ -f "${COMPFILE}" ]; then 894 895 # Do an absolute diff first to see if the files are actually different. 896 # If they're not different, delete the one in temproot. 897 # 898 if diff -q ${DIFF_OPTIONS} "${DESTDIR}${COMPFILE#.}" "${COMPFILE}" > \ 899 /dev/null 2>&1; then 900 echo " *** Temp ${COMPFILE} and installed are the same, deleting" 901 rm "${COMPFILE}" 902 else 903 # Ok, the files are different, so show the user where they differ. 904 # Use user's choice of diff methods; and user's pager if they have one. 905 # Use more if not. 906 # Use unified diffs by default. Context diffs give me a headache. :) 907 # 908 case "${AUTO_RUN}" in 909 '') 910 # prompt user to install/delete/merge changes 911 diff_loop 912 ;; 913 *) 914 # If this is an auto run, make it official 915 echo " *** ${COMPFILE} will remain for your consideration" 916 ;; 917 esac # Auto run test 918 fi # Yes, the files are different 919 fi # Yes, the file still remains to be checked 920done # This is for the do way up there at the beginning of the comparison 921 922echo '' 923echo "*** Comparison complete" 924echo '' 925 926TEST_FOR_FILES=`find ${TEMPROOT} -type f -size +0 2>/dev/null` 927if [ -n "${TEST_FOR_FILES}" ]; then 928 echo "*** Files that remain for you to merge by hand:" 929 find "${TEMPROOT}" -type f -size +0 930 echo '' 931fi 932 933case "${AUTO_RUN}" in 934'') 935 echo -n "Do you wish to delete what is left of ${TEMPROOT}? [no] " 936 read DEL_TEMPROOT 937 938 case "${DEL_TEMPROOT}" in 939 [yY]*) 940 if delete_temproot; then 941 echo " *** ${TEMPROOT} has been deleted" 942 else 943 echo " *** Unable to delete ${TEMPROOT}" 944 fi 945 ;; 946 *) 947 echo " *** ${TEMPROOT} will remain" 948 ;; 949 esac 950 ;; 951*) ;; 952esac 953 954case "${AUTO_INSTALLED_FILES}" in 955'') ;; 956*) 957 case "${AUTO_RUN}" in 958 '') 959 ( 960 echo '' 961 echo '*** You chose the automatic install option for files that did not' 962 echo ' exist on your system. The following were installed for you:' 963 echo "${AUTO_INSTALLED_FILES}" 964 ) | ${PAGER} 965 ;; 966 *) 967 echo '' 968 echo '*** You chose the automatic install option for files that did not' 969 echo ' exist on your system. The following were installed for you:' 970 echo "${AUTO_INSTALLED_FILES}" 971 ;; 972 esac 973 ;; 974esac 975 976run_it_now () { 977 case "${AUTO_RUN}" in 978 '') 979 unset YES_OR_NO 980 echo '' 981 echo -n ' Would you like to run it now? y or n [n] ' 982 read YES_OR_NO 983 984 case "${YES_OR_NO}" in 985 y) 986 echo " Running ${1}" 987 echo '' 988 eval "${1}" 989 ;; 990 ''|n) 991 echo '' 992 echo " *** Cancelled" 993 echo '' 994 echo " Make sure to run ${1} yourself" 995 ;; 996 *) 997 echo '' 998 echo " *** Sorry, I do not understand your answer (${YES_OR_NO})" 999 echo '' 1000 echo " Make sure to run ${1} yourself" 1001 esac 1002 ;; 1003 *) ;; 1004 esac 1005} 1006 1007case "${NEED_MAKEDEV}" in 1008'') ;; 1009*) 1010 echo '' 1011 echo "*** You installed a new ${DESTDIR}/dev/MAKEDEV script, so make sure that you run" 1012 echo " 'cd ${DESTDIR}/dev && /bin/sh MAKEDEV all' to rebuild your devices" 1013 run_it_now "cd ${DESTDIR}/dev && /bin/sh MAKEDEV all" 1014 ;; 1015esac 1016 1017case "${NEED_NEWALIASES}" in 1018'') ;; 1019*) 1020 echo '' 1021 if [ -n "${DESTDIR}" ]; then 1022 echo "*** You installed a new aliases file into ${DESTDIR}/etc/mail, but" 1023 echo " the newaliases command is limited to the directories configured" 1024 echo " in sendmail.cf. Make sure to create your aliases database by" 1025 echo " hand when your sendmail configuration is done." 1026 else 1027 echo "*** You installed a new aliases file, so make sure that you run" 1028 echo " '/usr/bin/newaliases' to rebuild your aliases database" 1029 run_it_now '/usr/bin/newaliases' 1030 fi 1031 ;; 1032esac 1033 1034case "${NEED_CAP_MKDB}" in 1035'') ;; 1036*) 1037 echo '' 1038 echo "*** You installed a login.conf file, so make sure that you run" 1039 echo " '/usr/bin/cap_mkdb ${DESTDIR}/etc/login.conf'" 1040 echo " to rebuild your login.conf database" 1041 run_it_now "/usr/bin/cap_mkdb ${DESTDIR}/etc/login.conf" 1042 ;; 1043esac 1044 1045case "${NEED_PWD_MKDB}" in 1046'') ;; 1047*) 1048 echo '' 1049 echo "*** You installed a new master.passwd file, so make sure that you run" 1050 if [ -n "${DESTDIR}" ]; then 1051 echo " '/usr/sbin/pwd_mkdb -d ${DESTDIR}/etc -p ${DESTDIR}/etc/master.passwd'" 1052 echo " to rebuild your password files" 1053 run_it_now "/usr/sbin/pwd_mkdb -d ${DESTDIR}/etc -p ${DESTDIR}/etc/master.passwd" 1054 else 1055 echo " '/usr/sbin/pwd_mkdb -p /etc/master.passwd'" 1056 echo " to rebuild your password files" 1057 run_it_now '/usr/sbin/pwd_mkdb -p /etc/master.passwd' 1058 fi 1059 ;; 1060esac 1061 1062echo '' 1063 1064if [ -r "${MM_EXIT_SCRIPT}" ]; then 1065 . "${MM_EXIT_SCRIPT}" 1066fi 1067 1068case "${COMP_CONFS}" in 1069'') ;; 1070*) 1071 . ${DESTDIR}/etc/defaults/rc.conf 1072 1073 (echo '' 1074 echo "*** Comparing conf files: ${rc_conf_files}" 1075 1076 for CONF_FILE in ${rc_conf_files}; do 1077 if [ -r "${DESTDIR}${CONF_FILE}" ]; then 1078 echo '' 1079 echo "*** From ${DESTDIR}${CONF_FILE}" 1080 echo "*** From ${DESTDIR}/etc/defaults/rc.conf" 1081 1082 for RC_CONF_VAR in `grep -i ^[a-z] ${DESTDIR}${CONF_FILE} | 1083 cut -d '=' -f 1`; do 1084 echo '' 1085 grep -w ^${RC_CONF_VAR} ${DESTDIR}${CONF_FILE} 1086 grep -w ^${RC_CONF_VAR} ${DESTDIR}/etc/defaults/rc.conf || 1087 echo ' * No default variable with this name' 1088 done 1089 fi 1090 done) | ${PAGER} 1091 echo '' 1092 ;; 1093esac 1094 1095case "${PRE_WORLD}" in 1096'') ;; 1097*) 1098 MAKE_CONF="${SOURCEDIR%etc}share/examples/etc/make.conf" 1099 1100 (echo '' 1101 echo '*** Comparing make variables' 1102 echo '' 1103 echo "*** From ${DESTDIR}/etc/make.conf" 1104 echo "*** From ${MAKE_CONF}" 1105 1106 for MAKE_VAR in `grep -i ^[a-z] ${DESTDIR}/etc/make.conf | cut -d '=' -f 1`; do 1107 echo '' 1108 grep -w ^${MAKE_VAR} ${DESTDIR}/etc/make.conf 1109 grep -w ^#${MAKE_VAR} ${MAKE_CONF} || 1110 echo ' * No example variable with this name' 1111 done) | ${PAGER} 1112 ;; 1113esac 1114 1115exit 0 1116 1117