mergemaster.sh revision 77335
11573Srgrimes#!/bin/sh
21573Srgrimes
31573Srgrimes# mergemaster
41573Srgrimes
51573Srgrimes# Compare files created by /usr/src/etc/Makefile (or the directory
61573Srgrimes# the user specifies) with the currently installed copies.
71573Srgrimes
81573Srgrimes# Copyright 1998-2001 Douglas Barton
91573Srgrimes# DougB@FreeBSD.org
101573Srgrimes
111573Srgrimes# $FreeBSD: head/usr.sbin/mergemaster/mergemaster.sh 77335 2001-05-28 13:17:20Z dougb $
121573Srgrimes
131573SrgrimesPATH=/bin:/usr/bin:/usr/sbin
141573Srgrimes
151573Srgrimesdisplay_usage () {
161573Srgrimes  VERSION_NUMBER=`grep "[$]FreeBSD:" $0 | cut -d ' ' -f 4`
171573Srgrimes  echo "mergemaster version ${VERSION_NUMBER}"
181573Srgrimes  echo 'Usage: mergemaster [-scrvahi] [-m /path]'
191573Srgrimes  echo '         [-t /path] [-d] [-u N] [-w N] [-D /path]'
201573Srgrimes  echo "Options:"
211573Srgrimes  echo "  -s  Strict comparison (diff every pair of files)"
221573Srgrimes  echo "  -c  Use context diff instead of unified diff"
231573Srgrimes  echo "  -r  Re-run on a previously cleaned directory (skip temproot creation)"
241573Srgrimes  echo "  -v  Be more verbose about the process, include additional checks"
251573Srgrimes  echo "  -a  Leave all files that differ to merge by hand"
261573Srgrimes  echo "  -h  Display more complete help"
271573Srgrimes  echo '  -i  Automatically install files that do not exist in destination directory'
281573Srgrimes  echo "  -m /path/directory  Specify location of source to do the make in"
291573Srgrimes  echo "  -t /path/directory  Specify temp root directory"
301573Srgrimes  echo "  -d  Add date and time to directory name (e.g., /var/tmp/temproot.`date +%m%d.%H.%M`)"
311573Srgrimes  echo "  -u N  Specify a numeric umask"
321573Srgrimes  echo "  -w N  Specify a screen width in columns to sdiff"
3350476Speter  echo '  -D /path/directory  Specify the destination directory to install files to'
341573Srgrimes  echo ''
35108775Stjr}
361573Srgrimes
371573Srgrimesdisplay_help () {
381573Srgrimes  echo "* To specify a directory other than /var/tmp/temproot for the"
391573Srgrimes  echo "  temporary root environment, use -t /path/to/temp/root"
401573Srgrimes  echo "* The -w option takes a number as an argument for the column width"
411573Srgrimes  echo "  of the screen.  The default is 80."
421573Srgrimes  echo '* The -a option causes mergemaster to run without prompting.'
431573Srgrimes}
441573Srgrimes
451573Srgrimes# Loop allowing the user to use sdiff to merge files and display the merged
4659460Sphantom# file.
4759460Sphantommerge_loop () {
481573Srgrimes  case "${VERBOSE}" in
4984306Sru  '') ;;
501573Srgrimes  *)
51104989Smike      echo "   *** Type h at the sdiff prompt (%) to get usage help"
521573Srgrimes      ;;
53104989Smike  esac
541573Srgrimes  echo ''
55104989Smike  MERGE_AGAIN=yes
5684306Sru  while [ "${MERGE_AGAIN}" = "yes" ]; do
571573Srgrimes    # Prime file.merged so we don't blat the owner/group id's
58104989Smike    cp -p "${COMPFILE}" "${COMPFILE}.merged"
591573Srgrimes    sdiff -o "${COMPFILE}.merged" --text --suppress-common-lines \
60104989Smike      --width=${SCREEN_WIDTH:-80} "${DESTDIR}${COMPFILE#.}" "${COMPFILE}"
611573Srgrimes    INSTALL_MERGED=V
62104989Smike    while [ "${INSTALL_MERGED}" = "v" -o "${INSTALL_MERGED}" = "V" ]; do
631573Srgrimes      echo ''
641573Srgrimes      echo "  Use 'i' to install merged file"
651573Srgrimes      echo "  Use 'r' to re-do the merge"
661573Srgrimes      echo "  Use 'v' to view the merged file"
671573Srgrimes      echo "  Default is to leave the temporary file to deal with by hand"
681573Srgrimes      echo ''
691573Srgrimes      echo -n "    *** How should I deal with the merged file? [Leave it for later] "
701573Srgrimes      read INSTALL_MERGED
711573Srgrimes
721573Srgrimes      case "${INSTALL_MERGED}" in
731573Srgrimes      [iI])
741573Srgrimes        mv "${COMPFILE}.merged" "${COMPFILE}"
751573Srgrimes        echo ''
761573Srgrimes        if mm_install "${COMPFILE}"; then
771573Srgrimes          echo "     *** Merged version of ${COMPFILE} installed successfully"
781573Srgrimes        else
79107619Sru          echo "     *** Problem installing ${COMPFILE}, it will remain to merge by hand later"
801573Srgrimes        fi
811573Srgrimes        unset MERGE_AGAIN
821573Srgrimes        ;;
831573Srgrimes      [rR])
841573Srgrimes        rm "${COMPFILE}.merged"
851573Srgrimes        ;;
861573Srgrimes      [vV])
871573Srgrimes        ${PAGER} "${COMPFILE}.merged"
881573Srgrimes        ;;
891573Srgrimes      '')
901573Srgrimes        echo "   *** ${COMPFILE} will remain for your consideration"
911573Srgrimes        unset MERGE_AGAIN
921573Srgrimes        ;;
931573Srgrimes      *)
941573Srgrimes        echo "invalid choice: ${INSTALL_MERGED}"
951573Srgrimes        INSTALL_MERGED=V
961573Srgrimes        ;;
971573Srgrimes      esac
981573Srgrimes    done
991573Srgrimes  done
1001573Srgrimes}
1011573Srgrimes
1021573Srgrimes# Loop showing user differences between files, allow merge, skip or install
1031573Srgrimes# options
1041573Srgrimesdiff_loop () {
1051573Srgrimes
1061573Srgrimes  HANDLE_COMPFILE=v
1071573Srgrimes
1081573Srgrimes  while [ "${HANDLE_COMPFILE}" = "v" -o "${HANDLE_COMPFILE}" = "V" -o \
1091573Srgrimes    "${HANDLE_COMPFILE}" = "NOT V" ]; do
1101573Srgrimes    if [ -f "${DESTDIR}${COMPFILE#.}" -a -f "${COMPFILE}" ]; then
1111573Srgrimes      if [ "${HANDLE_COMPFILE}" = "v" -o "${HANDLE_COMPFILE}" = "V" ]; then
11291995Sdd        (
11391995Sdd          echo ''
11491995Sdd          echo "  *** Displaying differences between ${COMPFILE} and installed version:"
1151573Srgrimes          echo ''
1161573Srgrimes          diff "${DIFF_FLAG}" "${DESTDIR}${COMPFILE#.}" "${COMPFILE}"
1171573Srgrimes        ) | ${PAGER}
1181573Srgrimes        echo ''
1191573Srgrimes      fi
1201573Srgrimes    else
1211573Srgrimes      echo ''
1221573Srgrimes      echo "  *** There is no installed version of ${COMPFILE}"
1231573Srgrimes      case "${AUTO_INSTALL}" in
1241573Srgrimes      [Yy][Ee][Ss])
1251573Srgrimes        echo ''
1261573Srgrimes        if mm_install "${COMPFILE}"; then
1271573Srgrimes          echo "   *** ${COMPFILE} installed successfully"
1281573Srgrimes          echo ''
1291573Srgrimes          # Make the list print one file per line
1301573Srgrimes          AUTO_INSTALLED_FILES="${AUTO_INSTALLED_FILES}      ${DESTDIR}${COMPFILE#.}
1311573Srgrimes"
1321573Srgrimes        else
1331573Srgrimes          echo "   *** Problem installing ${COMPFILE}, it will remain to merge by hand"
1341573Srgrimes        fi
1351573Srgrimes        return
1361573Srgrimes        ;;
1371573Srgrimes      *)
13895137Sfenner        NO_INSTALLED=yes
1391573Srgrimes        ;;
1401573Srgrimes      esac
1411573Srgrimes    fi
1421573Srgrimes
14395137Sfenner    echo "  Use 'd' to delete the temporary ${COMPFILE}"
14495137Sfenner    echo "  Use 'i' to install the temporary ${COMPFILE}"
14595137Sfenner    case "${NO_INSTALLED}" in
14695137Sfenner    '')
14795137Sfenner      echo "  Use 'm' to merge the temporary and installed versions"
14895137Sfenner      echo "  Use 'v' to view the diff results again"
14997570Sru      ;;
15095137Sfenner    esac
15197570Sru    echo ''
1521573Srgrimes    echo "  Default is to leave the temporary file to deal with by hand"
1531573Srgrimes    echo ''
1541573Srgrimes    echo -n "How should I deal with this? [Leave it for later] "
1551573Srgrimes    read HANDLE_COMPFILE
1561573Srgrimes
1571573Srgrimes    case "${HANDLE_COMPFILE}" in
15897570Sru    [dD])
1591573Srgrimes      rm "${COMPFILE}"
16097570Sru      echo ''
16195137Sfenner      echo "   *** Deleting ${COMPFILE}"
16295137Sfenner      ;;
1631573Srgrimes    [iI])
1641573Srgrimes      echo ''
1651573Srgrimes      if mm_install "${COMPFILE}"; then
1661573Srgrimes        echo "   *** ${COMPFILE} installed successfully"
16797570Sru      else
1681573Srgrimes        echo "   *** Problem installing ${COMPFILE}, it will remain to merge by hand"
16997570Sru      fi
17095137Sfenner      ;;
171116968Sdas    [mM])
172116968Sdas      case "${NO_INSTALLED}" in
173116968Sdas      '')
1741573Srgrimes        # interact with user to merge files
17597570Sru        merge_loop
1761573Srgrimes        ;;
17797570Sru      *)
17895137Sfenner        echo ''
179103854Stjr        echo "   *** There is no installed version of ${COMPFILE}"
180103854Stjr        echo ''
18195137Sfenner        HANDLE_COMPFILE="NOT V"
182103854Stjr        ;;
18395137Sfenner      esac # End of "No installed version of file but user selected merge" test
18497570Sru      ;;
18595137Sfenner    [vV])
18697570Sru      continue
18795137Sfenner      ;;
18895137Sfenner    '')
18995137Sfenner      echo ''
19095137Sfenner      echo "   *** ${COMPFILE} will remain for your consideration"
19195137Sfenner      ;;
19295137Sfenner    *)
19397570Sru      # invalid choice, show menu again.
19495137Sfenner      echo "invalid choice: ${HANDLE_COMPFILE}"
19597570Sru      echo ''
1961573Srgrimes      HANDLE_COMPFILE="NOT V"
19795137Sfenner      continue
198116968Sdas      ;;
19995137Sfenner    esac  # End of "How to handle files that are different"
20095137Sfenner  done
2011573Srgrimes  unset NO_INSTALLED
20297570Sru  echo ''
20395137Sfenner  case "${VERBOSE}" in
20495137Sfenner  '') ;;
20595137Sfenner  *)
20695137Sfenner    sleep 3
20795137Sfenner    ;;
20895137Sfenner  esac
20997570Sru}
21095137Sfenner
21197570Sru# Set the default path for the temporary root environment
21295137Sfenner#
21395137SfennerTEMPROOT='/var/tmp/temproot'
21495137Sfenner
21595137Sfenner# Read /etc/mergemaster.rc first so the one in $HOME can override
21695137Sfenner#
21795137Sfennerif [ -r /etc/mergemaster.rc ]; then
21897570Sru  . /etc/mergemaster.rc
21995137Sfennerfi
22097570Sru
22195137Sfenner# Read .mergemasterrc before command line so CLI can override
22295137Sfenner#
22395137Sfennerif [ -r "$HOME/.mergemasterrc" ]; then
22495137Sfenner  . "$HOME/.mergemasterrc"
22595137Sfennerfi
22695137Sfenner
22797570Sru# Check the command line options
22895137Sfenner#
22997570Sruwhile getopts ":ascrvhim:t:du:w:D:" COMMAND_LINE_ARGUMENT ; do
23027151Sjkh  case "${COMMAND_LINE_ARGUMENT}" in
23195137Sfenner  s)
23295137Sfenner    STRICT=yes
23327151Sjkh    ;;
23427151Sjkh  c)
23527151Sjkh    DIFF_FLAG='-c'
23627151Sjkh    ;;
23797570Sru  r)
23827151Sjkh    RERUN=yes
23997570Sru    ;;
2401573Srgrimes  v)
2411573Srgrimes    case "${AUTO_RUN}" in
2421573Srgrimes    '') VERBOSE=yes ;;
2431573Srgrimes    esac
2441573Srgrimes    ;;
2451573Srgrimes  a)
2461573Srgrimes    AUTO_RUN=yes
2471573Srgrimes    unset VERBOSE
2481573Srgrimes    ;;
24997570Sru  h)
25097570Sru    display_usage
25197570Sru    display_help
252103854Stjr    exit 0
2531573Srgrimes    ;;
254103854Stjr  i)
255103854Stjr    AUTO_INSTALL=yes
256103854Stjr    ;;
257103854Stjr  m)
258103854Stjr    SOURCEDIR=${OPTARG}
259103854Stjr    ;;
260103854Stjr  t)
2611573Srgrimes    TEMPROOT=${OPTARG}
2621573Srgrimes    ;;
2631573Srgrimes  d)
2641573Srgrimes    TEMPROOT=${TEMPROOT}.`date +%m%d.%H.%M`
2651573Srgrimes    ;;
2661573Srgrimes  u)
2671573Srgrimes    NEW_UMASK=${OPTARG}
26897570Sru    ;;
26997570Sru  w)
27097570Sru    SCREEN_WIDTH=${OPTARG}
27197570Sru    ;;
27297570Sru  D)
27397570Sru    DESTDIR=${OPTARG}
27497570Sru    ;;
27597570Sru  *)
2761573Srgrimes    display_usage
2771573Srgrimes    exit 1
2781573Srgrimes    ;;
2791573Srgrimes  esac
28097570Srudone
2811573Srgrimes
2821573Srgrimesecho ''
2831573Srgrimes
28497570Sru# If the user has a pager defined, make sure we can run it
2851573Srgrimes#
2861573Srgrimescase "${DONT_CHECK_PAGER}" in
2871573Srgrimes'')
2881573Srgrimes  while ! type "${PAGER%% *}" >/dev/null && [ -n "${PAGER}" ]; do
2891573Srgrimes    echo " *** Your PAGER environment variable specifies '${PAGER}', but"
2901573Srgrimes    echo "     due to the limited PATH that I use for security reasons,"
2911573Srgrimes    echo "     I cannot execute it.  So, what would you like to do?"
2921573Srgrimes    echo ''
2931573Srgrimes    echo "  Use 'e' to exit mergemaster and fix your PAGER variable"
2941573Srgrimes    if [ -x /usr/bin/less -o -x /usr/local/bin/less ]; then
2951573Srgrimes    echo "  Use 'l' to set PAGER to 'less' for this run"
2961573Srgrimes    fi
29797570Sru    echo "  Use 'm' to use plain old 'more' as your PAGER for this run"
2981573Srgrimes    echo ''
2991573Srgrimes    echo "  Default is to use plain old 'more' "
3001573Srgrimes    echo ''
30197570Sru    echo -n "What should I do? [Use 'more'] "
30295137Sfenner    read FIXPAGER
3031573Srgrimes
3041573Srgrimes    case "${FIXPAGER}" in
30597570Sru    [eE])
306116968Sdas       exit 0
307116968Sdas       ;;
308116968Sdas    [lL])
309116968Sdas       if [ -x /usr/bin/less ]; then
310116968Sdas         PAGER=/usr/bin/less
311116968Sdas       elif [ -x /usr/local/bin/less ]; then
312116968Sdas         PAGER=/usr/local/bin/less
313116968Sdas       else
314116968Sdas         echo ''
315116968Sdas         echo " *** Fatal Error:"
3161573Srgrimes         echo "     You asked to use 'less' as your pager, but I can't"
3171573Srgrimes         echo "     find it in /usr/bin or /usr/local/bin"
3181573Srgrimes         exit 1
31997570Sru       fi
3201573Srgrimes       ;;
3211573Srgrimes    [mM]|'')
3221573Srgrimes       PAGER=more
3231573Srgrimes       ;;
3241573Srgrimes    *)
3251573Srgrimes       echo ''
326103854Stjr       echo "invalid choice: ${FIXPAGER}"
327103854Stjr    esac
328103854Stjr    echo ''
329103854Stjr  done
330103854Stjr  ;;
331103854Stjresac
332103854Stjr
33395137Sfenner# If user has a pager defined, or got assigned one above, use it.
33495137Sfenner# If not, use more.
33595137Sfenner#
3361573SrgrimesPAGER=${PAGER:-more}
3371573Srgrimes
3381573Srgrimesif [ -n "${VERBOSE}" -a ! "${PAGER}" = "more" ]; then
3391573Srgrimes  echo " *** You have ${PAGER} defined as your pager so we will use that"
3401573Srgrimes  echo ''
3411573Srgrimes  sleep 3
34297570Srufi
3431573Srgrimes
3441573Srgrimes# Assign the diff flag once so we will not have to keep testing it
3451573Srgrimes#
3461573SrgrimesDIFF_FLAG=${DIFF_FLAG:--u}
3471573Srgrimes
3481573Srgrimes# Assign the source directory
349103854Stjr#
350103854StjrSOURCEDIR=${SOURCEDIR:-/usr/src/etc}
351103854Stjr
352103854Stjr# Define what CVS $Id tag to look for to aid portability.
353103854Stjr#
354103854StjrCVS_ID_TAG=FreeBSD
355103854Stjr
35695137Sfennercase "${RERUN}" in
35795137Sfenner'')
35895137Sfenner  # Set up the loop to test for the existence of the
3591573Srgrimes  # temp root directory.
3601573Srgrimes  #
3611573Srgrimes  TEST_TEMP_ROOT=yes
3621573Srgrimes  while [ "${TEST_TEMP_ROOT}" = "yes" ]; do
36397570Sru    if [ -d "${TEMPROOT}" ]; then
3641573Srgrimes      echo "*** The directory specified for the temporary root environment,"
3651573Srgrimes      echo "    ${TEMPROOT}, exists.  This can be a security risk if untrusted"
3661573Srgrimes      echo "    users have access to the system."
3671573Srgrimes      echo ''
3681573Srgrimes      case "${AUTO_RUN}" in
3691573Srgrimes      '')
3701573Srgrimes        echo "  Use 'd' to delete the old ${TEMPROOT} and continue"
3711573Srgrimes        echo "  Use 't' to select a new temporary root directory"
3721573Srgrimes        echo "  Use 'e' to exit mergemaster"
373235363Sjoel        echo ''
3741573Srgrimes        echo "  Default is to use ${TEMPROOT} as is"
3751573Srgrimes        echo ''
376235363Sjoel        echo -n "How should I deal with this? [Use the existing ${TEMPROOT}] "
3771573Srgrimes        read DELORNOT
3781573Srgrimes
3791573Srgrimes        case "${DELORNOT}" in
3801573Srgrimes        [dD])
3811573Srgrimes          echo ''
3821573Srgrimes          echo "   *** Deleting the old ${TEMPROOT}"
3831573Srgrimes          echo ''
3841573Srgrimes          rm -rf "${TEMPROOT}"
3851573Srgrimes          unset TEST_TEMP_ROOT
3861573Srgrimes          ;;
3871573Srgrimes        [tT])
3881573Srgrimes          echo "   *** Enter new directory name for temporary root environment"
3891573Srgrimes          read TEMPROOT
3901573Srgrimes          ;;
3911573Srgrimes        [eE])
3921573Srgrimes          exit 0
3931573Srgrimes          ;;
3941573Srgrimes        '')
3951573Srgrimes          echo ''
39697570Sru          echo "   *** Leaving ${TEMPROOT} intact"
39797570Sru          echo ''
3981573Srgrimes          unset TEST_TEMP_ROOT
3991573Srgrimes          ;;
4001573Srgrimes        *)
401103854Stjr          echo ''
402103854Stjr          echo "invalid choice: ${DELORNOT}"
403103854Stjr          echo ''
404103854Stjr          ;;
405103854Stjr        esac
406103854Stjr        ;;
407103854Stjr      *)
4081573Srgrimes        # If this is an auto-run, try a hopefully safe alternative then
4091573Srgrimes        # re-test anyway.
4101573Srgrimes        TEMPROOT=/var/tmp/temproot.`date +%m%d.%H.%M.%S`
4111573Srgrimes        ;;
4121573Srgrimes      esac
4131573Srgrimes    else
41497570Sru      unset TEST_TEMP_ROOT
4151573Srgrimes    fi
4161573Srgrimes  done
4171573Srgrimes
4181573Srgrimes  echo "*** Creating the temporary root environment in ${TEMPROOT}"
4191573Srgrimes
42097570Sru  if mkdir -p "${TEMPROOT}"; then
4211573Srgrimes    echo " *** ${TEMPROOT} ready for use"
4221573Srgrimes  fi
4231573Srgrimes
4241573Srgrimes  if [ ! -d "${TEMPROOT}" ]; then
4251573Srgrimes    echo ''
4261573Srgrimes    echo "  *** FATAL ERROR: Cannot create ${TEMPROOT}"
4271573Srgrimes    echo ''
42872290Sache    exit 1
42972313Sru  fi
43072313Sru
43172290Sache  echo " *** Creating and populating directory structure in ${TEMPROOT}"
43297570Sru  echo ''
43397570Sru
43497570Sru  case "${VERBOSE}" in
4351573Srgrimes  '') ;;
4361573Srgrimes  *)
4371573Srgrimes    echo " *** Press [Enter] or [Return] key to continue"
4381573Srgrimes    read ANY_KEY
4391573Srgrimes    unset ANY_KEY
4401573Srgrimes    ;;
4411573Srgrimes  esac
4421573Srgrimes
4431573Srgrimes  { cd ${SOURCEDIR} &&
4441573Srgrimes    case "${DESTDIR}" in
4451573Srgrimes    '') ;;
4461573Srgrimes    *)
4471573Srgrimes      make DESTDIR=${DESTDIR} distrib-dirs
4481573Srgrimes      ;;
4491573Srgrimes    esac
4501573Srgrimes    make DESTDIR=${TEMPROOT} distrib-dirs &&
4511573Srgrimes    make DESTDIR=${TEMPROOT} -DNO_MAKEDEV_RUN distribution;} ||
4521573Srgrimes  { echo '';
4531573Srgrimes    echo "  *** FATAL ERROR: Cannot 'cd' to ${SOURCEDIR} and install files to";
45457686Ssheldonh    echo "      the temproot environment";
45557686Ssheldonh    echo '';
4561573Srgrimes    exit 1;}
4571573Srgrimes
4581573Srgrimes  # Doing the inventory and removing files that we don't want to compare only
45921907Swosch  # makes sense if we are not doing a rerun, since we have no way of knowing
460103891Stjr  # what happened to the files during previous incarnations.
46121907Swosch  case "${VERBOSE}" in
46221907Swosch  '') ;;
4631573Srgrimes  *)
464103891Stjr    echo ''
465103891Stjr    echo ' *** The following files exist only in the installed version of'
4661573Srgrimes    echo "     ${DESTDIR}/etc.  In the vast majority of cases these files"
4671573Srgrimes    echo '     are necessary parts of the system and should not be deleted.'
4681573Srgrimes    echo '     However because these files are not updated by this process you'
4691573Srgrimes    echo '     might want to verify their status before rebooting your system.'
470108120Stjr    echo ''
471108120Stjr    echo ' *** Press [Enter] or [Return] key to continue'
472108120Stjr    read ANY_KEY
4731573Srgrimes    unset ANY_KEY
474108120Stjr    diff -qr ${DESTDIR}/etc ${TEMPROOT}/etc | grep "^Only in /etc" | ${PAGER}
4751573Srgrimes    echo ''
47695137Sfenner    echo ' *** Press [Enter] or [Return] key to continue'
4771573Srgrimes    read ANY_KEY
47895137Sfenner    unset ANY_KEY
47995137Sfenner    ;;
48095137Sfenner  esac
48195137Sfenner
4821573Srgrimes  # We really don't want to have to deal with these files, since
48395137Sfenner  # master.passwd is the real file that should be compared, then
48495137Sfenner  # the user should run pwd_mkdb if necessary.
48595137Sfenner  #
48697570Sru  rm ${TEMPROOT}/etc/spwd.db ${TEMPROOT}/etc/passwd ${TEMPROOT}/etc/pwd.db
48797570Sru
48895137Sfenner  # Avoid comparing the motd if the user specifies it in .mergemasterrc
48995137Sfenner  case "${IGNORE_MOTD}" in
49095137Sfenner  '') ;;
49195137Sfenner  *) rm ${TEMPROOT}/etc/motd
49295137Sfenner     ;;
49397570Sru  esac
49497570Sru
4951573Srgrimes  # Avoid trying to update MAKEDEV if /dev is on a devfs
4961573Srgrimes  if /sbin/sysctl vfs.devfs.generation > /dev/null 2>&1 ; then
4971573Srgrimes    rm ${TEMPROOT}/dev/MAKEDEV ${TEMPROOT}/dev/MAKEDEV.local
4981573Srgrimes  fi
4991573Srgrimes
5001573Srgrimes  ;; # End of the "RERUN" test
5011573Srgrimesesac
5021573Srgrimes
5031573Srgrimes# Get ready to start comparing files
50495137Sfenner
50595137Sfenner# Check umask if not specified on the command line,
50695137Sfenner# and we are not doing an autorun
50795137Sfenner#
50895137Sfennerif [ -z "${NEW_UMASK}" -a -z "${AUTO_RUN}" ]; then
50995137Sfenner  USER_UMASK=`umask`
510108775Stjr  case "${USER_UMASK}" in
511108775Stjr  0022|022) ;;
512108775Stjr  *)
513108775Stjr    echo ''
514    echo " *** Your umask is currently set to ${USER_UMASK}.  By default, this script"
515    echo "     installs all files with the same user, group and modes that"
516    echo "     they are created with by ${SOURCEDIR}/Makefile, compared to"
517    echo "     a umask of 022.  This umask allows world read permission when"
518    echo "     the file's default permissions have it."
519    echo "     No world permissions can sometimes cause problems.  A umask of"
520    echo "     022 will restore the default behavior, but is not mandatory."
521    echo "     /etc/master.passwd is a special case.  Its file permissions"
522    echo "     will be 600 (rw-------) if installed."
523    echo ''
524    echo -n "What umask should I use? [${USER_UMASK}] "
525    read NEW_UMASK
526
527    NEW_UMASK="${NEW_UMASK:-$USER_UMASK}"
528    ;;
529  esac
530  echo ''
531fi
532
533CONFIRMED_UMASK=${NEW_UMASK:-0022}
534
535# Warn users who still have ${DESTDIR}/etc/sysconfig
536#
537if [ -e "${DESTDIR}/etc/sysconfig" ]; then
538  echo ''
539  echo " *** There is a sysconfig file on this system in ${DESTDIR}/etc/."
540  echo ''
541  echo '     Starting with FreeBSD version 2.2.2 those settings moved from'
542  echo '     /etc/sysconfig to /etc/rc.conf.  If you are upgrading an older'
543  echo '     system make sure that you transfer your settings by hand from'
544  echo '     sysconfig to rc.conf and install the rc.conf file.  If you'
545  echo '     have already made this transition, you should consider'
546  echo '     renaming or deleting the sysconfig file.'
547  echo ''
548  case "${AUTO_RUN}" in
549  '')
550    echo -n "Continue with the merge process? [yes] "
551    read CONT_OR_NOT
552
553    case "${CONT_OR_NOT}" in
554    [nN]*)
555      exit 0
556      ;;
557    *)
558      echo "   *** Continuing"
559      echo ''
560      ;;
561    esac
562    ;;
563  *) ;;
564  esac
565fi
566
567# Use the umask/mode information to install the files
568# Create directories as needed
569#
570mm_install () {
571  local INSTALL_DIR
572  INSTALL_DIR=${1#.}
573  INSTALL_DIR=${INSTALL_DIR%/*}
574
575  case "${INSTALL_DIR}" in
576  '')
577    INSTALL_DIR=/
578    ;;
579  esac
580
581  if [ -n "${DESTDIR}${INSTALL_DIR}" -a ! -d "${DESTDIR}${INSTALL_DIR}" ]; then
582    DIR_MODE=`perl -e 'printf "%04o\n", (((stat("$ARGV[0]"))[2] & 07777) &~ \
583      oct("$ARGV[1]"))' "${TEMPROOT}/${INSTALL_DIR}" "${CONFIRMED_UMASK}"`
584    install -d -o root -g wheel -m "${DIR_MODE}" "${DESTDIR}${INSTALL_DIR}"
585  fi
586
587  FILE_MODE=`perl -e 'printf "%04o\n", (((stat("$ARGV[0]"))[2] & 07777) &~ \
588      oct("$ARGV[1]"))' "${1}" "${CONFIRMED_UMASK}"`
589
590  if [ ! -x "${1}" ]; then
591    case "${1#.}" in
592    /etc/mail/aliases)
593      NEED_NEWALIASES=yes
594      ;;
595    /etc/login.conf)
596      NEED_CAP_MKDB=yes
597      ;;
598    /etc/master.passwd)
599      install -m 600 "${1}" "${DESTDIR}${INSTALL_DIR}"
600      NEED_PWD_MKDB=yes
601      DONT_INSTALL=yes
602      ;;
603    /.cshrc | /.profile)
604    case "${AUTO_INSTALL}" in
605    '')
606      case "${LINK_EXPLAINED}" in
607      '')
608        echo "   *** Historically BSD derived systems have had a"
609        echo "       hard link from /.cshrc and /.profile to"
610        echo "       their namesakes in /root.  Please indicate"
611        echo "       your preference below for bringing your"
612        echo "       installed files up to date."
613        echo ''
614        LINK_EXPLAINED=yes
615        ;;
616      esac
617
618      echo "   Use 'd' to delete the temporary ${COMPFILE}"
619      echo "   Use 'l' to delete the existing ${DESTDIR}${COMPFILE#.} and create the link"
620      echo ''
621      echo "   Default is to leave the temporary file to deal with by hand"
622      echo ''
623      echo -n "  How should I handle ${COMPFILE}? [Leave it to install later] "
624      read HANDLE_LINK
625      ;;
626    *)  # Part of AUTO_INSTALL
627      HANDLE_LINK=l
628      ;;
629    esac
630
631      case "${HANDLE_LINK}" in
632      [dD]*)
633        rm "${COMPFILE}"
634        echo ''
635        echo "   *** Deleting ${COMPFILE}"
636        ;;
637      [lL]*)
638        echo ''
639        rm -f "${DESTDIR}${COMPFILE#.}"
640        if ln "${DESTDIR}/root/${COMPFILE##*/}" "${DESTDIR}${COMPFILE#.}"; then
641          echo "   *** Link from ${DESTDIR}${COMPFILE#.} to ${DESTDIR}/root/${COMPFILE##*/} installed successfully"
642          rm "${COMPFILE}"
643        else
644          echo "   *** Error linking ${DESTDIR}${COMPFILE#.} to ${DESTDIR}/root/${COMPFILE##*/}, ${COMPFILE} will remain to install by hand"
645        fi
646        ;;
647      *)
648        echo "   *** ${COMPFILE} will remain for your consideration"
649        ;;
650      esac
651      DONT_INSTALL=yes
652      ;;
653    esac
654
655    case "${DONT_INSTALL}" in
656    '')
657      install -m "${FILE_MODE}" "${1}" "${DESTDIR}${INSTALL_DIR}"
658      ;;
659    *)
660      unset DONT_INSTALL
661      ;;
662    esac
663  else
664    case "${1#.}" in
665    /dev/MAKEDEV)
666      NEED_MAKEDEV=yes
667      ;;
668    esac
669    install -m "${FILE_MODE}" "${1}" "${DESTDIR}${INSTALL_DIR}"
670  fi
671  return $?
672}
673
674echo ''
675echo "*** Beginning comparison"
676echo ''
677
678cd "${TEMPROOT}"
679
680if [ -r "${MM_PRE_COMPARE_SCRIPT}" ]; then
681  . "${MM_PRE_COMPARE_SCRIPT}"
682fi
683
684# Using -size +0 avoids uselessly checking the empty log files created
685# by ${SOURCEDIR}/Makefile and the device entries in ./dev, but does
686# check the scripts in ./dev, as we'd like (assuming no devfs of course).
687#
688for COMPFILE in `find . -type f -size +0`; do
689
690  # First, check to see if the file exists in DESTDIR.  If not, the
691  # diff_loop function knows how to handle it.
692  #
693  if [ ! -e "${DESTDIR}${COMPFILE#.}" ]; then
694    case "${AUTO_RUN}" in
695      '')
696        diff_loop
697        ;;
698      *)
699        case "${AUTO_INSTALL}" in
700        '')
701          # If this is an auto run, make it official
702          echo "   *** ${COMPFILE} will remain for your consideration"
703          ;;
704        *)
705          diff_loop
706          ;;
707        esac
708        ;;
709    esac # Auto run test
710    continue
711  fi
712
713  case "${STRICT}" in
714  '' | [Nn][Oo])
715    # Compare CVS $Id's first so if the file hasn't been modified
716    # local changes will be ignored.
717    # If the files have the same $Id, delete the one in temproot so the
718    # user will have less to wade through if files are left to merge by hand.
719    #
720    CVSID1=`grep "[$]${CVS_ID_TAG}:" ${DESTDIR}${COMPFILE#.} 2>/dev/null`
721    CVSID2=`grep "[$]${CVS_ID_TAG}:" ${COMPFILE} 2>/dev/null`
722
723    case "${CVSID2}" in
724    "${CVSID1}")
725      echo " *** Temp ${COMPFILE} and installed have the same CVS Id, deleting"
726      rm "${COMPFILE}"
727      ;;
728    esac
729    ;;
730  esac
731
732  # If the file is still here either because the $Ids are different, the
733  # file doesn't have an $Id, or we're using STRICT mode; look at the diff.
734  #
735  if [ -f "${COMPFILE}" ]; then
736
737    # Do an absolute diff first to see if the files are actually different.
738    # If they're not different, delete the one in temproot.
739    #
740    if diff -q "${DESTDIR}${COMPFILE#.}" "${COMPFILE}" > /dev/null 2>&1; then
741      echo " *** Temp ${COMPFILE} and installed are the same, deleting"
742      rm "${COMPFILE}"
743    else
744      # Ok, the files are different, so show the user where they differ.
745      # Use user's choice of diff methods; and user's pager if they have one.
746      # Use more if not.
747      # Use unified diffs by default.  Context diffs give me a headache. :)
748      #
749      case "${AUTO_RUN}" in
750      '')
751        # prompt user to install/delete/merge changes
752        diff_loop
753        ;;
754      *)
755        # If this is an auto run, make it official
756        echo "   *** ${COMPFILE} will remain for your consideration"
757        ;;
758      esac # Auto run test
759    fi # Yes, the files are different
760  fi # Yes, the file still remains to be checked
761done # This is for the do way up there at the beginning of the comparison
762
763echo ''
764echo "*** Comparison complete"
765echo ''
766
767TEST_FOR_FILES=`find ${TEMPROOT} -type f -size +0 2>/dev/null`
768if [ -n "${TEST_FOR_FILES}" ]; then
769  echo "*** Files that remain for you to merge by hand:"
770  find "${TEMPROOT}" -type f -size +0
771  echo ''
772fi
773
774case "${AUTO_RUN}" in
775'')
776  echo -n "Do you wish to delete what is left of ${TEMPROOT}? [no] "
777  read DEL_TEMPROOT
778
779  case "${DEL_TEMPROOT}" in
780  [yY]*)
781    if rm -rf "${TEMPROOT}"; then
782      echo " *** ${TEMPROOT} has been deleted"
783    else
784      echo " *** Unable to delete ${TEMPROOT}"
785    fi
786    ;;
787  *)
788    echo " *** ${TEMPROOT} will remain"
789    ;;
790  esac
791  ;;
792*) ;;
793esac
794
795case "${AUTO_INSTALLED_FILES}" in
796'') ;;
797*)
798  case "${AUTO_RUN}" in
799  '')
800    (
801      echo ''
802      echo '*** You chose the automatic install option for files that did not'
803      echo '    exist on your system.  The following were installed for you:'
804      echo "${AUTO_INSTALLED_FILES}"
805    ) | ${PAGER}
806    ;;
807  *)
808    echo ''
809    echo '*** You chose the automatic install option for files that did not'
810    echo '    exist on your system.  The following were installed for you:'
811    echo "${AUTO_INSTALLED_FILES}"
812    ;;
813  esac
814  ;;
815esac
816
817run_it_now () {
818  case "${AUTO_RUN}" in
819  '')
820    unset YES_OR_NO
821    echo ''
822    echo -n '    Would you like to run it now? y or n [n] '
823    read YES_OR_NO
824
825    case "${YES_OR_NO}" in
826    y)
827      echo "    Running ${1}"
828      echo ''
829      eval "${1}"
830      ;;
831    ''|n)
832      echo ''
833      echo "       *** Cancelled"
834      echo ''
835      echo "    Make sure to run ${1} yourself"
836      ;;
837    *)
838      echo ''
839      echo "       *** Sorry, I do not understand your answer (${YES_OR_NO})"
840      echo ''
841      echo "    Make sure to run ${1} yourself"
842    esac
843    ;;
844  *) ;;
845  esac
846}
847
848case "${NEED_MAKEDEV}" in
849'') ;;
850*)
851  echo ''
852  echo "*** You installed a new ${DESTDIR}/dev/MAKEDEV script, so make sure that you run"
853  echo "    'cd ${DESTDIR}/dev && /bin/sh MAKEDEV all' to rebuild your devices"
854  run_it_now "cd ${DESTDIR}/dev && /bin/sh MAKEDEV all"
855  ;;
856esac
857
858case "${NEED_NEWALIASES}" in
859'') ;;
860*)
861  echo ''
862  if [ -n "${DESTDIR}" ]; then
863    echo "*** You installed a new aliases file into ${DESTDIR}/etc/mail, but"
864    echo "    the newaliases command is limited to the directories configured"
865    echo "    in sendmail.cf.  Make sure to create your aliases database by"
866    echo "    hand when your sendmail configuration is done."
867  else
868    echo "*** You installed a new aliases file, so make sure that you run"
869    echo "    '/usr/bin/newaliases' to rebuild your aliases database"
870    run_it_now '/usr/bin/newaliases'
871  fi
872  ;;
873esac
874
875case "${NEED_CAP_MKDB}" in
876'') ;;
877*)
878  echo ''
879  echo "*** You installed a login.conf file, so make sure that you run"
880  echo "    '/usr/bin/cap_mkdb ${DESTDIR}/etc/login.conf'"
881  echo "     to rebuild your login.conf database"
882  run_it_now "/usr/bin/cap_mkdb ${DESTDIR}/etc/login.conf"
883  ;;
884esac
885
886case "${NEED_PWD_MKDB}" in
887'') ;;
888*)
889  echo ''
890  echo "*** You installed a new master.passwd file, so make sure that you run"
891  if [ -n "${DESTDIR}" ]; then
892    echo "    '/usr/sbin/pwd_mkdb -d ${DESTDIR}/etc -p ${DESTDIR}/etc/master.passwd'"
893    echo "    to rebuild your password files"
894    run_it_now "/usr/sbin/pwd_mkdb -d ${DESTDIR}/etc -p ${DESTDIR}/etc/master.passwd"
895  else
896    echo "    '/usr/sbin/pwd_mkdb -p /etc/master.passwd'"
897    echo "     to rebuild your password files"
898    run_it_now '/usr/sbin/pwd_mkdb -p /etc/master.passwd'
899  fi
900  ;;
901esac
902
903echo ''
904
905if [ -r "${MM_EXIT_SCRIPT}" ]; then
906  . "${MM_EXIT_SCRIPT}"
907fi
908
909exit 0
910
911