mergemaster.sh revision 101362
1251881Speter#!/bin/sh 2251881Speter 3251881Speter# mergemaster 4251881Speter 5251881Speter# Compare files created by /usr/src/etc/Makefile (or the directory 6251881Speter# the user specifies) with the currently installed copies. 7251881Speter 8251881Speter# Copyright 1998-2002 Douglas Barton 9251881Speter# DougB@FreeBSD.org 10251881Speter 11251881Speter# $FreeBSD: head/usr.sbin/mergemaster/mergemaster.sh 101362 2002-08-05 08:47:52Z dougb $ 12251881Speter 13251881SpeterPATH=/bin:/usr/bin:/usr/sbin 14251881Speter 15251881Speterdisplay_usage () { 16251881Speter VERSION_NUMBER=`grep "[$]FreeBSD:" $0 | cut -d ' ' -f 4` 17251881Speter echo "mergemaster version ${VERSION_NUMBER}" 18251881Speter echo 'Usage: mergemaster [-scrvahipC] [-m /path]' 19251881Speter echo ' [-t /path] [-d] [-u N] [-w N] [-D /path]' 20251881Speter echo "Options:" 21251881Speter echo " -s Strict comparison (diff every pair of files)" 22251881Speter echo " -c Use context diff instead of unified diff" 23251881Speter echo " -r Re-run on a previously cleaned directory (skip temproot creation)" 24251881Speter echo " -v Be more verbose about the process, include additional checks" 25251881Speter echo " -a Leave all files that differ to merge by hand" 26251881Speter echo " -h Display more complete help" 27251881Speter echo ' -i Automatically install files that do not exist in destination directory' 28251881Speter echo ' -p Pre-buildworld mode, only compares crucial files' 29289180Speter echo ' -C Compare local rc.conf variables to the defaults' 30251881Speter echo " -m /path/directory Specify location of source to do the make in" 31251881Speter echo " -t /path/directory Specify temp root directory" 32251881Speter echo " -d Add date and time to directory name (e.g., /var/tmp/temproot.`date +%m%d.%H.%M`)" 33251881Speter echo " -u N Specify a numeric umask" 34251881Speter echo " -w N Specify a screen width in columns to sdiff" 35251881Speter echo ' -D /path/directory Specify the destination directory to install files to' 36251881Speter echo '' 37251881Speter} 38251881Speter 39251881Speterdisplay_help () { 40251881Speter echo "* To specify a directory other than /var/tmp/temproot for the" 41251881Speter echo " temporary root environment, use -t /path/to/temp/root" 42251881Speter echo "* The -w option takes a number as an argument for the column width" 43251881Speter echo " of the screen. The default is 80." 44251881Speter echo '* The -a option causes mergemaster to run without prompting.' 45251881Speter} 46251881Speter 47251881Speter# Loop allowing the user to use sdiff to merge files and display the merged 48251881Speter# file. 49251881Spetermerge_loop () { 50251881Speter case "${VERBOSE}" in 51251881Speter '') ;; 52251881Speter *) 53251881Speter echo " *** Type h at the sdiff prompt (%) to get usage help" 54251881Speter ;; 55251881Speter esac 56251881Speter echo '' 57289180Speter MERGE_AGAIN=yes 58251881Speter while [ "${MERGE_AGAIN}" = "yes" ]; do 59289180Speter # Prime file.merged so we don't blat the owner/group id's 60251881Speter cp -p "${COMPFILE}" "${COMPFILE}.merged" 61251881Speter sdiff -o "${COMPFILE}.merged" --text --suppress-common-lines \ 62251881Speter --width=${SCREEN_WIDTH:-80} "${DESTDIR}${COMPFILE#.}" "${COMPFILE}" 63251881Speter INSTALL_MERGED=V 64251881Speter while [ "${INSTALL_MERGED}" = "v" -o "${INSTALL_MERGED}" = "V" ]; do 65251881Speter echo '' 66251881Speter echo " Use 'i' to install merged file" 67251881Speter echo " Use 'r' to re-do the merge" 68251881Speter echo " Use 'v' to view the merged file" 69251881Speter echo " Default is to leave the temporary file to deal with by hand" 70251881Speter echo '' 71251881Speter echo -n " *** How should I deal with the merged file? [Leave it for later] " 72251881Speter read INSTALL_MERGED 73251881Speter 74251881Speter case "${INSTALL_MERGED}" in 75251881Speter [iI]) 76251881Speter mv "${COMPFILE}.merged" "${COMPFILE}" 77251881Speter echo '' 78251881Speter if mm_install "${COMPFILE}"; then 79251881Speter echo " *** Merged version of ${COMPFILE} installed successfully" 80251881Speter else 81251881Speter echo " *** Problem installing ${COMPFILE}, it will remain to merge by hand later" 82251881Speter fi 83251881Speter unset MERGE_AGAIN 84251881Speter ;; 85251881Speter [rR]) 86251881Speter rm "${COMPFILE}.merged" 87251881Speter ;; 88251881Speter [vV]) 89251881Speter ${PAGER} "${COMPFILE}.merged" 90251881Speter ;; 91251881Speter '') 92251881Speter echo " *** ${COMPFILE} will remain for your consideration" 93251881Speter unset MERGE_AGAIN 94251881Speter ;; 95251881Speter *) 96251881Speter echo "invalid choice: ${INSTALL_MERGED}" 97251881Speter INSTALL_MERGED=V 98251881Speter ;; 99251881Speter esac 100251881Speter done 101251881Speter done 102251881Speter} 103251881Speter 104251881Speter# Loop showing user differences between files, allow merge, skip or install 105251881Speter# options 106251881Speterdiff_loop () { 107251881Speter 108251881Speter HANDLE_COMPFILE=v 109251881Speter 110251881Speter while [ "${HANDLE_COMPFILE}" = "v" -o "${HANDLE_COMPFILE}" = "V" -o \ 111251881Speter "${HANDLE_COMPFILE}" = "NOT V" ]; do 112251881Speter if [ -f "${DESTDIR}${COMPFILE#.}" -a -f "${COMPFILE}" ]; then 113251881Speter if [ "${HANDLE_COMPFILE}" = "v" -o "${HANDLE_COMPFILE}" = "V" ]; then 114251881Speter echo '' 115251881Speter echo ' ====================================================================== ' 116251881Speter echo '' 117251881Speter ( 118251881Speter echo '' 119251881Speter echo " *** Displaying differences between ${COMPFILE} and installed version:" 120251881Speter echo '' 121289180Speter diff "${DIFF_FLAG}" "${DESTDIR}${COMPFILE#.}" "${COMPFILE}" 122289180Speter ) | ${PAGER} 123289180Speter echo '' 124289180Speter fi 125251881Speter else 126251881Speter echo '' 127251881Speter echo " *** There is no installed version of ${COMPFILE}" 128251881Speter echo '' 129251881Speter case "${AUTO_INSTALL}" in 130251881Speter [Yy][Ee][Ss]) 131251881Speter echo '' 132251881Speter if mm_install "${COMPFILE}"; then 133251881Speter echo " *** ${COMPFILE} installed successfully" 134251881Speter echo '' 135251881Speter # Make the list print one file per line 136251881Speter AUTO_INSTALLED_FILES="${AUTO_INSTALLED_FILES} ${DESTDIR}${COMPFILE#.} 137251881Speter" 138251881Speter else 139251881Speter echo " *** Problem installing ${COMPFILE}, it will remain to merge by hand" 140251881Speter fi 141251881Speter return 142251881Speter ;; 143251881Speter *) 144251881Speter NO_INSTALLED=yes 145251881Speter ;; 146251881Speter esac 147251881Speter fi 148251881Speter 149251881Speter echo " Use 'd' to delete the temporary ${COMPFILE}" 150251881Speter echo " Use 'i' to install the temporary ${COMPFILE}" 151251881Speter case "${NO_INSTALLED}" in 152251881Speter '') 153251881Speter echo " Use 'm' to merge the temporary and installed versions" 154289180Speter echo " Use 'v' to view the diff results again" 155251881Speter ;; 156251881Speter esac 157251881Speter echo '' 158251881Speter echo " Default is to leave the temporary file to deal with by hand" 159251881Speter echo '' 160251881Speter echo -n "How should I deal with this? [Leave it for later] " 161251881Speter read HANDLE_COMPFILE 162251881Speter 163251881Speter case "${HANDLE_COMPFILE}" in 164251881Speter [dD]) 165251881Speter rm "${COMPFILE}" 166251881Speter echo '' 167251881Speter echo " *** Deleting ${COMPFILE}" 168251881Speter ;; 169251881Speter [iI]) 170251881Speter echo '' 171251881Speter if mm_install "${COMPFILE}"; then 172251881Speter echo " *** ${COMPFILE} installed successfully" 173251881Speter else 174251881Speter echo " *** Problem installing ${COMPFILE}, it will remain to merge by hand" 175251881Speter fi 176251881Speter ;; 177251881Speter [mM]) 178251881Speter case "${NO_INSTALLED}" in 179251881Speter '') 180251881Speter # interact with user to merge files 181251881Speter merge_loop 182251881Speter ;; 183251881Speter *) 184251881Speter echo '' 185251881Speter echo " *** There is no installed version of ${COMPFILE}" 186251881Speter echo '' 187251881Speter HANDLE_COMPFILE="NOT V" 188251881Speter ;; 189251881Speter esac # End of "No installed version of file but user selected merge" test 190251881Speter ;; 191251881Speter [vV]) 192251881Speter continue 193251881Speter ;; 194251881Speter '') 195251881Speter echo '' 196251881Speter echo " *** ${COMPFILE} will remain for your consideration" 197251881Speter ;; 198251881Speter *) 199251881Speter # invalid choice, show menu again. 200251881Speter echo "invalid choice: ${HANDLE_COMPFILE}" 201251881Speter echo '' 202251881Speter HANDLE_COMPFILE="NOT V" 203251881Speter continue 204251881Speter ;; 205251881Speter esac # End of "How to handle files that are different" 206251881Speter done 207251881Speter unset NO_INSTALLED 208251881Speter echo '' 209251881Speter case "${VERBOSE}" in 210251881Speter '') ;; 211251881Speter *) 212251881Speter sleep 3 213251881Speter ;; 214251881Speter esac 215251881Speter} 216251881Speter 217251881Speterpress_to_continue () { 218251881Speter local DISCARD 219251881Speter echo -n ' *** Press the [Enter] or [Return] key to continue ' 220251881Speter read DISCARD 221251881Speter} 222251881Speter 223251881Speter# Set the default path for the temporary root environment 224251881Speter# 225251881SpeterTEMPROOT='/var/tmp/temproot' 226251881Speter 227251881Speter# Read /etc/mergemaster.rc first so the one in $HOME can override 228251881Speter# 229251881Speterif [ -r /etc/mergemaster.rc ]; then 230251881Speter . /etc/mergemaster.rc 231251881Speterfi 232251881Speter 233251881Speter# Read .mergemasterrc before command line so CLI can override 234251881Speter# 235251881Speterif [ -r "$HOME/.mergemasterrc" ]; then 236251881Speter . "$HOME/.mergemasterrc" 237251881Speterfi 238251881Speter 239251881Speter# Check the command line options 240251881Speter# 241251881Speterwhile getopts ":ascrvhipCm:t:du:w:D:" COMMAND_LINE_ARGUMENT ; do 242251881Speter case "${COMMAND_LINE_ARGUMENT}" in 243289180Speter s) 244289180Speter STRICT=yes 245289180Speter ;; 246251881Speter c) 247251881Speter DIFF_FLAG='-c' 248251881Speter ;; 249251881Speter r) 250251881Speter RERUN=yes 251251881Speter ;; 252251881Speter v) 253251881Speter case "${AUTO_RUN}" in 254251881Speter '') VERBOSE=yes ;; 255251881Speter esac 256251881Speter ;; 257251881Speter a) 258251881Speter AUTO_RUN=yes 259251881Speter unset VERBOSE 260251881Speter ;; 261251881Speter h) 262251881Speter display_usage 263251881Speter display_help 264251881Speter exit 0 265251881Speter ;; 266251881Speter i) 267251881Speter AUTO_INSTALL=yes 268251881Speter ;; 269251881Speter C) 270251881Speter COMP_CONFS=yes 271251881Speter ;; 272251881Speter p) 273251881Speter PRE_WORLD=yes 274251881Speter unset COMP_CONFS 275251881Speter unset AUTO_RUN 276251881Speter ;; 277251881Speter m) 278251881Speter SOURCEDIR=${OPTARG} 279251881Speter ;; 280251881Speter t) 281251881Speter TEMPROOT=${OPTARG} 282251881Speter ;; 283251881Speter d) 284251881Speter TEMPROOT=${TEMPROOT}.`date +%m%d.%H.%M` 285251881Speter ;; 286251881Speter u) 287251881Speter NEW_UMASK=${OPTARG} 288251881Speter ;; 289251881Speter w) 290251881Speter SCREEN_WIDTH=${OPTARG} 291251881Speter ;; 292251881Speter D) 293251881Speter DESTDIR=${OPTARG} 294251881Speter ;; 295251881Speter *) 296251881Speter display_usage 297251881Speter exit 1 298251881Speter ;; 299251881Speter esac 300251881Speterdone 301251881Speter 302251881Speterecho '' 303251881Speter 304289180Speter# If the user has a pager defined, make sure we can run it 305289180Speter# 306289180Spetercase "${DONT_CHECK_PAGER}" in 307251881Speter'') 308251881Speter while ! type "${PAGER%% *}" >/dev/null && [ -n "${PAGER}" ]; do 309251881Speter echo " *** Your PAGER environment variable specifies '${PAGER}', but" 310251881Speter echo " due to the limited PATH that I use for security reasons," 311251881Speter echo " I cannot execute it. So, what would you like to do?" 312251881Speter echo '' 313251881Speter echo " Use 'e' to exit mergemaster and fix your PAGER variable" 314251881Speter if [ -x /usr/bin/less -o -x /usr/local/bin/less ]; then 315251881Speter echo " Use 'l' to set PAGER to 'less' for this run" 316251881Speter fi 317251881Speter echo " Use 'm' to use plain old 'more' as your PAGER for this run" 318251881Speter echo '' 319251881Speter echo " Default is to use plain old 'more' " 320251881Speter echo '' 321251881Speter echo -n "What should I do? [Use 'more'] " 322251881Speter read FIXPAGER 323251881Speter 324251881Speter case "${FIXPAGER}" in 325251881Speter [eE]) 326251881Speter exit 0 327251881Speter ;; 328251881Speter [lL]) 329251881Speter if [ -x /usr/bin/less ]; then 330251881Speter PAGER=/usr/bin/less 331251881Speter elif [ -x /usr/local/bin/less ]; then 332251881Speter PAGER=/usr/local/bin/less 333251881Speter else 334251881Speter echo '' 335251881Speter echo " *** Fatal Error:" 336251881Speter echo " You asked to use 'less' as your pager, but I can't" 337251881Speter echo " find it in /usr/bin or /usr/local/bin" 338251881Speter exit 1 339251881Speter fi 340251881Speter ;; 341251881Speter [mM]|'') 342251881Speter PAGER=more 343251881Speter ;; 344251881Speter *) 345251881Speter echo '' 346251881Speter echo "invalid choice: ${FIXPAGER}" 347251881Speter esac 348251881Speter echo '' 349251881Speter done 350251881Speter ;; 351251881Speteresac 352251881Speter 353251881Speter# If user has a pager defined, or got assigned one above, use it. 354251881Speter# If not, use more. 355251881Speter# 356251881SpeterPAGER=${PAGER:-more} 357251881Speter 358251881Speterif [ -n "${VERBOSE}" -a ! "${PAGER}" = "more" ]; then 359251881Speter echo " *** You have ${PAGER} defined as your pager so we will use that" 360251881Speter echo '' 361251881Speter sleep 3 362251881Speterfi 363251881Speter 364251881Speter# Assign the diff flag once so we will not have to keep testing it 365251881Speter# 366251881SpeterDIFF_FLAG=${DIFF_FLAG:--u} 367251881Speter 368251881Speter# Assign the source directory 369251881Speter# 370251881SpeterSOURCEDIR=${SOURCEDIR:-/usr/src/etc} 371251881Speter 372251881Speter# Check the width of the user's terminal 373251881Speter# 374251881Speterif [ -t 0 ]; then 375251881Speter w=$(stty -a | sed -ne 's/.* \([0-9][0-9]*\) columns.*/\1/p') 376251881Speter case "${w}" in 377251881Speter 0|'') ;; # No-op, since the input is not valid 378251881Speter *) 379251881Speter case "${SCREEN_WIDTH}" in 380251881Speter '') SCREEN_WIDTH="${w}" ;; 381251881Speter "${w}") ;; # No-op, since they are the same 382251881Speter *) 383251881Speter echo -n "*** You entered ${SCREEN_WIDTH} as your screen width, but stty " 384251881Speter echo "thinks it is ${w}." 385251881Speter echo '' 386251881Speter echo -n "What would you like to use? [${w}] " 387251881Speter read SCREEN_WIDTH 388251881Speter case "${SCREEN_WIDTH}" in 389251881Speter '') SCREEN_WIDTH="${w}" ;; 390251881Speter esac 391251881Speter ;; 392251881Speter esac 393251881Speter esac 394251881Speterfi 395251881Speter 396251881Speter# Define what CVS $Id tag to look for to aid portability. 397251881Speter# 398251881SpeterCVS_ID_TAG=FreeBSD 399251881Speter 400289180Speterdelete_temproot () { 401289180Speter rm -rf "${TEMPROOT}" 2>/dev/null 402289180Speter chflags -R 0 "${TEMPROOT}" 2>/dev/null 403289180Speter rm -rf "${TEMPROOT}" || exit 1 404251881Speter} 405251881Speter 406251881Spetercase "${RERUN}" in 407251881Speter'') 408251881Speter # Set up the loop to test for the existence of the 409251881Speter # temp root directory. 410251881Speter # 411251881Speter TEST_TEMP_ROOT=yes 412251881Speter while [ "${TEST_TEMP_ROOT}" = "yes" ]; do 413251881Speter if [ -d "${TEMPROOT}" ]; then 414251881Speter echo "*** The directory specified for the temporary root environment," 415251881Speter echo " ${TEMPROOT}, exists. This can be a security risk if untrusted" 416251881Speter echo " users have access to the system." 417251881Speter echo '' 418251881Speter case "${AUTO_RUN}" in 419251881Speter '') 420251881Speter echo " Use 'd' to delete the old ${TEMPROOT} and continue" 421251881Speter echo " Use 't' to select a new temporary root directory" 422251881Speter echo " Use 'e' to exit mergemaster" 423251881Speter echo '' 424251881Speter echo " Default is to use ${TEMPROOT} as is" 425251881Speter echo '' 426251881Speter echo -n "How should I deal with this? [Use the existing ${TEMPROOT}] " 427289180Speter read DELORNOT 428289180Speter 429289180Speter case "${DELORNOT}" in 430289180Speter [dD]) 431289180Speter echo '' 432289180Speter echo " *** Deleting the old ${TEMPROOT}" 433289180Speter echo '' 434289180Speter delete_temproot || exit 1 435251881Speter unset TEST_TEMP_ROOT 436289180Speter ;; 437289180Speter [tT]) 438289180Speter echo " *** Enter new directory name for temporary root environment" 439251881Speter read TEMPROOT 440251881Speter ;; 441251881Speter [eE]) 442251881Speter exit 0 443251881Speter ;; 444251881Speter '') 445251881Speter echo '' 446251881Speter echo " *** Leaving ${TEMPROOT} intact" 447251881Speter echo '' 448251881Speter unset TEST_TEMP_ROOT 449251881Speter ;; 450251881Speter *) 451251881Speter echo '' 452251881Speter echo "invalid choice: ${DELORNOT}" 453251881Speter echo '' 454251881Speter ;; 455251881Speter esac 456251881Speter ;; 457251881Speter *) 458251881Speter # If this is an auto-run, try a hopefully safe alternative then 459251881Speter # re-test anyway. 460251881Speter TEMPROOT=/var/tmp/temproot.`date +%m%d.%H.%M.%S` 461251881Speter ;; 462251881Speter esac 463251881Speter else 464251881Speter unset TEST_TEMP_ROOT 465251881Speter fi 466251881Speter done 467251881Speter 468251881Speter echo "*** Creating the temporary root environment in ${TEMPROOT}" 469251881Speter 470251881Speter if mkdir -p "${TEMPROOT}"; then 471251881Speter echo " *** ${TEMPROOT} ready for use" 472251881Speter fi 473251881Speter 474251881Speter if [ ! -d "${TEMPROOT}" ]; then 475251881Speter echo '' 476251881Speter echo " *** FATAL ERROR: Cannot create ${TEMPROOT}" 477251881Speter echo '' 478251881Speter exit 1 479251881Speter fi 480251881Speter 481251881Speter echo " *** Creating and populating directory structure in ${TEMPROOT}" 482362181Sdim echo '' 483251881Speter 484251881Speter case "${VERBOSE}" in 485251881Speter '') ;; 486251881Speter *) 487251881Speter press_to_continue 488251881Speter ;; 489251881Speter esac 490362181Sdim 491251881Speter case "${PRE_WORLD}" in 492251881Speter '') 493251881Speter { cd ${SOURCEDIR} && 494251881Speter case "${DESTDIR}" in 495251881Speter '') ;; 496251881Speter *) 497251881Speter make DESTDIR=${DESTDIR} distrib-dirs 498251881Speter ;; 499251881Speter esac 500251881Speter make DESTDIR=${TEMPROOT} distrib-dirs && 501251881Speter make MAKEOBJDIRPREFIX=${TEMPROOT}/usr/obj obj && 502251881Speter make MAKEOBJDIRPREFIX=${TEMPROOT}/usr/obj DESTDIR=${TEMPROOT} \ 503251881Speter -DNO_MAKEDEV_RUN distribution;} || 504251881Speter { echo ''; 505251881Speter echo " *** FATAL ERROR: Cannot 'cd' to ${SOURCEDIR} and install files to"; 506362181Sdim echo " the temproot environment"; 507362181Sdim echo ''; 508362181Sdim exit 1;} 509362181Sdim ;; 510362181Sdim *) 511251881Speter # Only set up files that are crucial to {build|install}world 512362181Sdim { mkdir -p ${TEMPROOT}/etc && 513362181Sdim cp -p ${SOURCEDIR}/master.passwd ${TEMPROOT}/etc && 514362181Sdim cp -p ${SOURCEDIR}/group ${TEMPROOT}/etc;} || 515362181Sdim { echo ''; 516362181Sdim echo ' *** FATAL ERROR: Cannot copy files to the temproot environment'; 517362181Sdim echo ''; 518362181Sdim exit 1;} 519362181Sdim ;; 520362181Sdim esac 521362181Sdim 522362181Sdim # Doing the inventory and removing files that we don't want to compare only 523362181Sdim # makes sense if we are not doing a rerun, since we have no way of knowing 524362181Sdim # what happened to the files during previous incarnations. 525362181Sdim case "${VERBOSE}" in 526362181Sdim '') ;; 527362181Sdim *) 528251881Speter echo '' 529251881Speter echo ' *** The following files exist only in the installed version of' 530251881Speter echo " ${DESTDIR}/etc. In the vast majority of cases these files" 531251881Speter echo ' are necessary parts of the system and should not be deleted.' 532251881Speter echo ' However because these files are not updated by this process you' 533251881Speter echo ' might want to verify their status before rebooting your system.' 534251881Speter echo '' 535251881Speter press_to_continue 536251881Speter diff -qr ${DESTDIR}/etc ${TEMPROOT}/etc | grep "^Only in ${DESTDIR}/etc" | ${PAGER} 537251881Speter echo '' 538251881Speter press_to_continue 539251881Speter ;; 540251881Speter esac 541251881Speter 542251881Speter # Avoid comparing the motd if the user specifies it in .mergemasterrc 543251881Speter case "${IGNORE_MOTD}" in 544251881Speter '') ;; 545251881Speter *) rm -f ${TEMPROOT}/etc/motd 546251881Speter ;; 547251881Speter esac 548251881Speter 549251881Speter # Avoid trying to update MAKEDEV if /dev is on a devfs 550251881Speter if /sbin/sysctl vfs.devfs.generation > /dev/null 2>&1 ; then 551251881Speter rm -f ${TEMPROOT}/dev/MAKEDEV ${TEMPROOT}/dev/MAKEDEV.local 552251881Speter fi 553251881Speter 554251881Speter ;; # End of the "RERUN" test 555251881Speteresac 556251881Speter 557251881Speter# We really don't want to have to deal with these files, since 558251881Speter# master.passwd is the real file that should be compared, then 559251881Speter# the user should run pwd_mkdb if necessary. 560251881Speter# 561251881Speterrm -f ${TEMPROOT}/etc/spwd.db ${TEMPROOT}/etc/passwd ${TEMPROOT}/etc/pwd.db 562251881Speter 563251881Speter# We only need to compare things like freebsd.cf once 564251881Speterfind ${TEMPROOT}/usr/obj -type f -delete 2>/dev/null 565251881Speter 566251881Speter# Get ready to start comparing files 567251881Speter 568251881Speter# Check umask if not specified on the command line, 569251881Speter# and we are not doing an autorun 570251881Speter# 571251881Speterif [ -z "${NEW_UMASK}" -a -z "${AUTO_RUN}" ]; then 572251881Speter USER_UMASK=`umask` 573251881Speter case "${USER_UMASK}" in 574251881Speter 0022|022) ;; 575251881Speter *) 576251881Speter echo '' 577251881Speter echo " *** Your umask is currently set to ${USER_UMASK}. By default, this script" 578251881Speter echo " installs all files with the same user, group and modes that" 579251881Speter echo " they are created with by ${SOURCEDIR}/Makefile, compared to" 580251881Speter echo " a umask of 022. This umask allows world read permission when" 581251881Speter echo " the file's default permissions have it." 582251881Speter echo '' 583251881Speter echo " No world permissions can sometimes cause problems. A umask of" 584251881Speter echo " 022 will restore the default behavior, but is not mandatory." 585251881Speter echo " /etc/master.passwd is a special case. Its file permissions" 586251881Speter echo " will be 600 (rw-------) if installed." 587251881Speter echo '' 588251881Speter echo -n "What umask should I use? [${USER_UMASK}] " 589251881Speter read NEW_UMASK 590251881Speter 591251881Speter NEW_UMASK="${NEW_UMASK:-$USER_UMASK}" 592251881Speter ;; 593251881Speter esac 594251881Speter echo '' 595251881Speterfi 596251881Speter 597251881SpeterCONFIRMED_UMASK=${NEW_UMASK:-0022} 598251881Speter 599251881Speter# Warn users who still have ${DESTDIR}/etc/sysconfig 600251881Speter# 601251881Speterif [ -e "${DESTDIR}/etc/sysconfig" ]; then 602251881Speter echo '' 603251881Speter echo " *** There is a sysconfig file on this system in ${DESTDIR}/etc/." 604251881Speter echo '' 605251881Speter echo ' Starting with FreeBSD version 2.2.2 those settings moved from' 606251881Speter echo ' /etc/sysconfig to /etc/rc.conf. If you are upgrading an older' 607251881Speter echo ' system make sure that you transfer your settings by hand from' 608251881Speter echo ' sysconfig to rc.conf and install the rc.conf file. If you' 609251881Speter echo ' have already made this transition, you should consider' 610251881Speter echo ' renaming or deleting the sysconfig file.' 611251881Speter echo '' 612251881Speter case "${AUTO_RUN}" in 613251881Speter '') 614251881Speter echo -n "Continue with the merge process? [yes] " 615251881Speter read CONT_OR_NOT 616251881Speter 617251881Speter case "${CONT_OR_NOT}" in 618289180Speter [nN]*) 619289180Speter exit 0 620289180Speter ;; 621289180Speter *) 622251881Speter echo " *** Continuing" 623251881Speter echo '' 624251881Speter ;; 625251881Speter esac 626251881Speter ;; 627251881Speter *) ;; 628251881Speter esac 629251881Speterfi 630251881Speter 631251881Speter# Use the umask/mode information to install the files 632251881Speter# Create directories as needed 633251881Speter# 634251881Speterdo_install_and_rm () { 635251881Speter install -m "${1}" "${2}" "${3}" && 636251881Speter rm -f "${2}" 637251881Speter} 638289180Speter 639289180Speter# 4095 = "obase=10;ibase=8;07777" | bc 640289180Speterfind_mode () { 641289180Speter local OCTAL 642289180Speter OCTAL=$(( ~$(echo "obase=10; ibase=8; ${CONFIRMED_UMASK}" | bc) & 4095 & 643289180Speter $(echo "obase=10; ibase=8; $(stat -f "%OMp%OLp" ${1})" | bc) )) 644289180Speter printf "%04o\n" ${OCTAL} 645251881Speter} 646289180Speter 647289180Spetermm_install () { 648289180Speter local INSTALL_DIR 649289180Speter INSTALL_DIR=${1#.} 650289180Speter INSTALL_DIR=${INSTALL_DIR%/*} 651289180Speter 652289180Speter case "${INSTALL_DIR}" in 653289180Speter '') 654251881Speter INSTALL_DIR=/ 655251881Speter ;; 656251881Speter esac 657251881Speter 658251881Speter if [ -n "${DESTDIR}${INSTALL_DIR}" -a ! -d "${DESTDIR}${INSTALL_DIR}" ]; then 659251881Speter DIR_MODE=`find_mode "${TEMPROOT}/${INSTALL_DIR}"` 660251881Speter install -d -o root -g wheel -m "${DIR_MODE}" "${DESTDIR}${INSTALL_DIR}" 661251881Speter fi 662251881Speter 663251881Speter FILE_MODE=`find_mode "${1}"` 664251881Speter 665251881Speter if [ ! -x "${1}" ]; then 666251881Speter case "${1#.}" in 667251881Speter /etc/mail/aliases) 668251881Speter NEED_NEWALIASES=yes 669251881Speter ;; 670251881Speter /etc/login.conf) 671251881Speter NEED_CAP_MKDB=yes 672251881Speter ;; 673251881Speter /etc/master.passwd) 674289180Speter do_install_and_rm 600 "${1}" "${DESTDIR}${INSTALL_DIR}" 675289180Speter NEED_PWD_MKDB=yes 676289180Speter DONT_INSTALL=yes 677289180Speter ;; 678289180Speter /.cshrc | /.profile) 679251881Speter case "${AUTO_INSTALL}" in 680289180Speter '') 681251881Speter case "${LINK_EXPLAINED}" in 682289180Speter '') 683289180Speter echo " *** Historically BSD derived systems have had a" 684251881Speter echo " hard link from /.cshrc and /.profile to" 685289180Speter echo " their namesakes in /root. Please indicate" 686289180Speter echo " your preference below for bringing your" 687289180Speter echo " installed files up to date." 688289180Speter echo '' 689289180Speter LINK_EXPLAINED=yes 690251881Speter ;; 691251881Speter esac 692251881Speter 693251881Speter echo " Use 'd' to delete the temporary ${COMPFILE}" 694251881Speter echo " Use 'l' to delete the existing ${DESTDIR}${COMPFILE#.} and create the link" 695251881Speter echo '' 696251881Speter echo " Default is to leave the temporary file to deal with by hand" 697251881Speter echo '' 698251881Speter echo -n " How should I handle ${COMPFILE}? [Leave it to install later] " 699298845Sdim read HANDLE_LINK 700251881Speter ;; 701251881Speter *) # Part of AUTO_INSTALL 702251881Speter HANDLE_LINK=l 703251881Speter ;; 704251881Speter esac 705251881Speter 706251881Speter case "${HANDLE_LINK}" in 707251881Speter [dD]*) 708251881Speter rm "${COMPFILE}" 709251881Speter echo '' 710251881Speter echo " *** Deleting ${COMPFILE}" 711251881Speter ;; 712251881Speter [lL]*) 713289180Speter echo '' 714289180Speter rm -f "${DESTDIR}${COMPFILE#.}" 715289180Speter if ln "${DESTDIR}/root/${COMPFILE##*/}" "${DESTDIR}${COMPFILE#.}"; then 716251881Speter echo " *** Link from ${DESTDIR}${COMPFILE#.} to ${DESTDIR}/root/${COMPFILE##*/} installed successfully" 717289180Speter rm "${COMPFILE}" 718289180Speter else 719251881Speter echo " *** Error linking ${DESTDIR}${COMPFILE#.} to ${DESTDIR}/root/${COMPFILE##*/}, ${COMPFILE} will remain to install by hand" 720251881Speter fi 721289180Speter ;; 722289180Speter *) 723289180Speter echo " *** ${COMPFILE} will remain for your consideration" 724251881Speter ;; 725289180Speter esac 726289180Speter DONT_INSTALL=yes 727298845Sdim ;; 728289180Speter esac 729251881Speter 730289180Speter case "${DONT_INSTALL}" in 731289180Speter '') 732289180Speter do_install_and_rm "${FILE_MODE}" "${1}" "${DESTDIR}${INSTALL_DIR}" 733289180Speter ;; 734251881Speter *) 735289180Speter unset DONT_INSTALL 736289180Speter ;; 737289180Speter esac 738289180Speter else # File matched -x 739289180Speter case "${1#.}" in 740289180Speter /dev/MAKEDEV) 741289180Speter NEED_MAKEDEV=yes 742251881Speter ;; 743251881Speter esac 744251881Speter do_install_and_rm "${FILE_MODE}" "${1}" "${DESTDIR}${INSTALL_DIR}" 745362181Sdim fi 746362181Sdim return $? 747362181Sdim} 748362181Sdim 749362181Sdimecho '' 750362181Sdimecho "*** Beginning comparison" 751362181Sdimecho '' 752362181Sdim 753362181Sdimcd "${TEMPROOT}" 754362181Sdim 755362181Sdimif [ -r "${MM_PRE_COMPARE_SCRIPT}" ]; then 756362181Sdim . "${MM_PRE_COMPARE_SCRIPT}" 757362181Sdimfi 758362181Sdim 759362181Sdim# Using -size +0 avoids uselessly checking the empty log files created 760362181Sdim# by ${SOURCEDIR}/Makefile and the device entries in ./dev, but does 761362181Sdim# check the scripts in ./dev, as we'd like (assuming no devfs of course). 762362181Sdim# 763362181Sdimfor COMPFILE in `find . -type f -size +0`; do 764362181Sdim 765362181Sdim # First, check to see if the file exists in DESTDIR. If not, the 766362181Sdim # diff_loop function knows how to handle it. 767362181Sdim # 768362181Sdim if [ ! -e "${DESTDIR}${COMPFILE#.}" ]; then 769362181Sdim case "${AUTO_RUN}" in 770362181Sdim '') 771362181Sdim diff_loop 772362181Sdim ;; 773362181Sdim *) 774362181Sdim case "${AUTO_INSTALL}" in 775362181Sdim '') 776362181Sdim # If this is an auto run, make it official 777362181Sdim echo " *** ${COMPFILE} will remain for your consideration" 778362181Sdim ;; 779362181Sdim *) 780362181Sdim diff_loop 781362181Sdim ;; 782362181Sdim esac 783362181Sdim ;; 784362181Sdim esac # Auto run test 785362181Sdim continue 786362181Sdim fi 787362181Sdim 788362181Sdim case "${STRICT}" in 789362181Sdim '' | [Nn][Oo]) 790362181Sdim # Compare CVS $Id's first so if the file hasn't been modified 791362181Sdim # local changes will be ignored. 792362181Sdim # If the files have the same $Id, delete the one in temproot so the 793362181Sdim # user will have less to wade through if files are left to merge by hand. 794362181Sdim # 795362181Sdim CVSID1=`grep "[$]${CVS_ID_TAG}:" ${DESTDIR}${COMPFILE#.} 2>/dev/null` 796362181Sdim CVSID2=`grep "[$]${CVS_ID_TAG}:" ${COMPFILE} 2>/dev/null` || CVSID2=none 797362181Sdim 798362181Sdim case "${CVSID2}" in 799362181Sdim "${CVSID1}") 800362181Sdim echo " *** Temp ${COMPFILE} and installed have the same CVS Id, deleting" 801362181Sdim rm "${COMPFILE}" 802362181Sdim ;; 803362181Sdim esac 804362181Sdim ;; 805362181Sdim esac 806362181Sdim 807362181Sdim # If the file is still here either because the $Ids are different, the 808362181Sdim # file doesn't have an $Id, or we're using STRICT mode; look at the diff. 809362181Sdim # 810251881Speter if [ -f "${COMPFILE}" ]; then 811251881Speter 812251881Speter # Do an absolute diff first to see if the files are actually different. 813251881Speter # If they're not different, delete the one in temproot. 814251881Speter # 815251881Speter if diff -q "${DESTDIR}${COMPFILE#.}" "${COMPFILE}" > /dev/null 2>&1; then 816251881Speter echo " *** Temp ${COMPFILE} and installed are the same, deleting" 817251881Speter rm "${COMPFILE}" 818251881Speter else 819251881Speter # Ok, the files are different, so show the user where they differ. 820251881Speter # Use user's choice of diff methods; and user's pager if they have one. 821251881Speter # Use more if not. 822251881Speter # Use unified diffs by default. Context diffs give me a headache. :) 823251881Speter # 824251881Speter case "${AUTO_RUN}" in 825251881Speter '') 826251881Speter # prompt user to install/delete/merge changes 827251881Speter diff_loop 828251881Speter ;; 829251881Speter *) 830251881Speter # If this is an auto run, make it official 831251881Speter echo " *** ${COMPFILE} will remain for your consideration" 832251881Speter ;; 833251881Speter esac # Auto run test 834251881Speter fi # Yes, the files are different 835251881Speter fi # Yes, the file still remains to be checked 836251881Speterdone # This is for the do way up there at the beginning of the comparison 837251881Speter 838362181Sdimecho '' 839362181Sdimecho "*** Comparison complete" 840362181Sdimecho '' 841362181Sdim 842362181SdimTEST_FOR_FILES=`find ${TEMPROOT} -type f -size +0 2>/dev/null` 843362181Sdimif [ -n "${TEST_FOR_FILES}" ]; then 844251881Speter echo "*** Files that remain for you to merge by hand:" 845362181Sdim find "${TEMPROOT}" -type f -size +0 846362181Sdim echo '' 847362181Sdimfi 848362181Sdim 849362181Sdimcase "${AUTO_RUN}" in 850251881Speter'') 851251881Speter echo -n "Do you wish to delete what is left of ${TEMPROOT}? [no] " 852251881Speter read DEL_TEMPROOT 853251881Speter 854251881Speter case "${DEL_TEMPROOT}" in 855251881Speter [yY]*) 856251881Speter if delete_temproot; then 857251881Speter echo " *** ${TEMPROOT} has been deleted" 858251881Speter else 859251881Speter echo " *** Unable to delete ${TEMPROOT}" 860251881Speter fi 861251881Speter ;; 862251881Speter *) 863251881Speter echo " *** ${TEMPROOT} will remain" 864251881Speter ;; 865251881Speter esac 866251881Speter ;; 867251881Speter*) ;; 868251881Speteresac 869251881Speter 870251881Spetercase "${AUTO_INSTALLED_FILES}" in 871251881Speter'') ;; 872251881Speter*) 873251881Speter case "${AUTO_RUN}" in 874251881Speter '') 875251881Speter ( 876251881Speter echo '' 877251881Speter echo '*** You chose the automatic install option for files that did not' 878251881Speter echo ' exist on your system. The following were installed for you:' 879251881Speter echo "${AUTO_INSTALLED_FILES}" 880251881Speter ) | ${PAGER} 881251881Speter ;; 882251881Speter *) 883251881Speter echo '' 884251881Speter echo '*** You chose the automatic install option for files that did not' 885251881Speter echo ' exist on your system. The following were installed for you:' 886251881Speter echo "${AUTO_INSTALLED_FILES}" 887251881Speter ;; 888251881Speter esac 889251881Speter ;; 890251881Speteresac 891251881Speter 892251881Speterrun_it_now () { 893251881Speter case "${AUTO_RUN}" in 894251881Speter '') 895251881Speter unset YES_OR_NO 896251881Speter echo '' 897251881Speter echo -n ' Would you like to run it now? y or n [n] ' 898251881Speter read YES_OR_NO 899251881Speter 900251881Speter case "${YES_OR_NO}" in 901251881Speter y) 902251881Speter echo " Running ${1}" 903251881Speter echo '' 904251881Speter eval "${1}" 905251881Speter ;; 906251881Speter ''|n) 907251881Speter echo '' 908251881Speter echo " *** Cancelled" 909251881Speter echo '' 910251881Speter echo " Make sure to run ${1} yourself" 911251881Speter ;; 912251881Speter *) 913251881Speter echo '' 914251881Speter echo " *** Sorry, I do not understand your answer (${YES_OR_NO})" 915251881Speter echo '' 916251881Speter echo " Make sure to run ${1} yourself" 917251881Speter esac 918251881Speter ;; 919251881Speter *) ;; 920251881Speter esac 921251881Speter} 922251881Speter 923251881Spetercase "${NEED_MAKEDEV}" in 924251881Speter'') ;; 925251881Speter*) 926251881Speter echo '' 927251881Speter echo "*** You installed a new ${DESTDIR}/dev/MAKEDEV script, so make sure that you run" 928251881Speter echo " 'cd ${DESTDIR}/dev && /bin/sh MAKEDEV all' to rebuild your devices" 929251881Speter run_it_now "cd ${DESTDIR}/dev && /bin/sh MAKEDEV all" 930251881Speter ;; 931251881Speteresac 932251881Speter 933251881Spetercase "${NEED_NEWALIASES}" in 934251881Speter'') ;; 935251881Speter*) 936251881Speter echo '' 937251881Speter if [ -n "${DESTDIR}" ]; then 938251881Speter echo "*** You installed a new aliases file into ${DESTDIR}/etc/mail, but" 939251881Speter echo " the newaliases command is limited to the directories configured" 940251881Speter echo " in sendmail.cf. Make sure to create your aliases database by" 941251881Speter echo " hand when your sendmail configuration is done." 942251881Speter else 943251881Speter echo "*** You installed a new aliases file, so make sure that you run" 944251881Speter echo " '/usr/bin/newaliases' to rebuild your aliases database" 945251881Speter run_it_now '/usr/bin/newaliases' 946251881Speter fi 947251881Speter ;; 948251881Speteresac 949251881Speter 950251881Spetercase "${NEED_CAP_MKDB}" in 951251881Speter'') ;; 952251881Speter*) 953251881Speter echo '' 954251881Speter echo "*** You installed a login.conf file, so make sure that you run" 955251881Speter echo " '/usr/bin/cap_mkdb ${DESTDIR}/etc/login.conf'" 956251881Speter echo " to rebuild your login.conf database" 957251881Speter run_it_now "/usr/bin/cap_mkdb ${DESTDIR}/etc/login.conf" 958251881Speter ;; 959251881Speteresac 960251881Speter 961251881Spetercase "${NEED_PWD_MKDB}" in 962289180Speter'') ;; 963251881Speter*) 964251881Speter echo '' 965251881Speter echo "*** You installed a new master.passwd file, so make sure that you run" 966251881Speter if [ -n "${DESTDIR}" ]; then 967251881Speter echo " '/usr/sbin/pwd_mkdb -d ${DESTDIR}/etc -p ${DESTDIR}/etc/master.passwd'" 968251881Speter echo " to rebuild your password files" 969251881Speter run_it_now "/usr/sbin/pwd_mkdb -d ${DESTDIR}/etc -p ${DESTDIR}/etc/master.passwd" 970251881Speter else 971251881Speter echo " '/usr/sbin/pwd_mkdb -p /etc/master.passwd'" 972251881Speter echo " to rebuild your password files" 973251881Speter run_it_now '/usr/sbin/pwd_mkdb -p /etc/master.passwd' 974251881Speter fi 975251881Speter ;; 976251881Speteresac 977251881Speter 978251881Speterecho '' 979251881Speter 980251881Speterif [ -r "${MM_EXIT_SCRIPT}" ]; then 981251881Speter . "${MM_EXIT_SCRIPT}" 982251881Speterfi 983251881Speter 984251881Spetercase "${COMP_CONFS}" in 985251881Speter'') ;; 986251881Speter*) 987251881Speter . ${DESTDIR}/etc/defaults/rc.conf 988251881Speter 989251881Speter (echo '' 990251881Speter echo "*** Comparing conf files: ${rc_conf_files}" 991251881Speter 992289180Speter for CONF_FILE in ${rc_conf_files}; do 993289180Speter if [ -r "${DESTDIR}${CONF_FILE}" ]; then 994251881Speter echo '' 995251881Speter echo "*** From ${DESTDIR}${CONF_FILE}" 996251881Speter echo "*** From ${DESTDIR}/etc/defaults/rc.conf" 997251881Speter 998251881Speter for RC_CONF_VAR in `grep -i ^[a-z] ${DESTDIR}${CONF_FILE} | 999251881Speter cut -d '=' -f 1`; do 1000251881Speter echo '' 1001251881Speter grep -w ^${RC_CONF_VAR} ${DESTDIR}${CONF_FILE} 1002251881Speter grep -w ^${RC_CONF_VAR} ${DESTDIR}/etc/defaults/rc.conf || 1003251881Speter echo ' * No default variable with this name' 1004251881Speter done 1005251881Speter fi 1006251881Speter done) | ${PAGER} 1007251881Speter echo '' 1008251881Speter ;; 1009251881Speteresac 1010251881Speter 1011251881Spetercase "${PRE_WORLD}" in 1012251881Speter'') ;; 1013251881Speter*) 1014251881Speter MAKE_CONF="${SOURCEDIR%etc}share/examples/etc/make.conf" 1015251881Speter 1016251881Speter (echo '' 1017251881Speter echo '*** Comparing make variables' 1018251881Speter echo '' 1019251881Speter echo "*** From ${DESTDIR}/etc/make.conf" 1020251881Speter echo "*** From ${MAKE_CONF}" 1021251881Speter 1022251881Speter for MAKE_VAR in `grep -i ^[a-z] ${DESTDIR}/etc/make.conf | cut -d '=' -f 1`; do 1023251881Speter echo '' 1024362181Sdim grep -w ^${MAKE_VAR} ${DESTDIR}/etc/make.conf 1025362181Sdim grep -w ^#${MAKE_VAR} ${MAKE_CONF} || 1026362181Sdim echo ' * No example variable with this name' 1027362181Sdim done) | ${PAGER} 1028251881Speter ;; 1029251881Speteresac 1030251881Speter 1031251881Speterexit 0 1032251881Speter 1033251881Speter