mergemaster.sh revision 225736
162053Smarkm#!/bin/sh
2256381Smarkm
3254147Sobrien# mergemaster
462053Smarkm
562053Smarkm# Compare files created by /usr/src/etc/Makefile (or the directory
662053Smarkm# the user specifies) with the currently installed copies.
762053Smarkm
862053Smarkm# Copyright 1998-2011 Douglas Barton
962053Smarkm# dougb@FreeBSD.org
1062053Smarkm
1162053Smarkm# $FreeBSD: stable/9/usr.sbin/mergemaster/mergemaster.sh 224726 2011-08-09 07:42:19Z dougb $
1262053Smarkm
1362053SmarkmPATH=/bin:/usr/bin:/usr/sbin
1462053Smarkm
1562053Smarkmdisplay_usage () {
1662053Smarkm  VERSION_NUMBER=`grep "[$]FreeBSD:" $0 | cut -d ' ' -f 4`
1762053Smarkm  echo "mergemaster version ${VERSION_NUMBER}"
1862053Smarkm  echo 'Usage: mergemaster [-scrvhpCP] [-a|[-iFU]]'
1962053Smarkm  echo '    [-m /path] [-t /path] [-d] [-u N] [-w N] [-A arch] [-D /path]'
2062053Smarkm  echo "Options:"
2162053Smarkm  echo "  -s  Strict comparison (diff every pair of files)"
2262053Smarkm  echo "  -c  Use context diff instead of unified diff"
2362053Smarkm  echo "  -r  Re-run on a previously cleaned directory (skip temproot creation)"
2462053Smarkm  echo "  -v  Be more verbose about the process, include additional checks"
2562053Smarkm  echo "  -a  Leave all files that differ to merge by hand"
2662053Smarkm  echo "  -h  Display more complete help"
2762053Smarkm  echo '  -i  Automatically install files that do not exist in destination directory'
2862053Smarkm  echo '  -p  Pre-buildworld mode, only compares crucial files'
29119418Sobrien  echo '  -F  Install files that differ only by revision control Id ($FreeBSD)'
30119418Sobrien  echo '  -C  Compare local rc.conf variables to the defaults'
31119418Sobrien  echo '  -P  Preserve files that are overwritten'
3262053Smarkm  echo "  -U  Attempt to auto upgrade files that have not been user modified"
3362053Smarkm  echo '      ***DANGEROUS***'
3476166Smarkm  echo ''
3562053Smarkm  echo "  -m /path/directory  Specify location of source to do the make in"
3676166Smarkm  echo "  -t /path/directory  Specify temp root directory"
3774771Smarkm  echo "  -d  Add date and time to directory name (e.g., /var/tmp/temproot.`date +%m%d.%H.%M`)"
3862053Smarkm  echo "  -u N  Specify a numeric umask"
3974072Smarkm  echo "  -w N  Specify a screen width in columns to sdiff"
4076166Smarkm  echo "  -A architecture  Alternative architecture name to pass to make"
4162053Smarkm  echo '  -D /path/directory  Specify the destination directory to install files to'
42129876Sphk  echo ''
4376166Smarkm}
4467112Smarkm
45164033Srwatsondisplay_help () {
4683366Sjulian  echo "* To specify a directory other than /var/tmp/temproot for the"
47256381Smarkm  echo "  temporary root environment, use -t /path/to/temp/root"
4870834Swollman  echo "* The -w option takes a number as an argument for the column width"
4976166Smarkm  echo "  of the screen.  The default is 80."
5076166Smarkm  echo '* The -a option causes mergemaster to run without prompting.'
5174072Smarkm}
5262053Smarkm
5374072Smarkm# Loop allowing the user to use sdiff to merge files and display the merged
5462053Smarkm# file.
55256381Smarkmmerge_loop () {
56256381Smarkm  case "${VERBOSE}" in
57255362Smarkm  '') ;;
58256381Smarkm  *)
59256381Smarkm      echo "   *** Type h at the sdiff prompt (%) to get usage help"
6062053Smarkm      ;;
61122871Smarkm  esac
6262053Smarkm  echo ''
63128059Smarkm  MERGE_AGAIN=yes
64128059Smarkm  while [ "${MERGE_AGAIN}" = "yes" ]; do
65128059Smarkm    # Prime file.merged so we don't blat the owner/group id's
66128059Smarkm    cp -p "${COMPFILE}" "${COMPFILE}.merged"
67122871Smarkm    sdiff -o "${COMPFILE}.merged" --text --suppress-common-lines \
6862053Smarkm      --width=${SCREEN_WIDTH:-80} "${DESTDIR}${COMPFILE#.}" "${COMPFILE}"
69128059Smarkm    INSTALL_MERGED=V
70128059Smarkm    while [ "${INSTALL_MERGED}" = "v" -o "${INSTALL_MERGED}" = "V" ]; do
71128059Smarkm      echo ''
72128059Smarkm      echo "  Use 'i' to install merged file"
73128059Smarkm      echo "  Use 'r' to re-do the merge"
74128059Smarkm      echo "  Use 'v' to view the merged file"
7562053Smarkm      echo "  Default is to leave the temporary file to deal with by hand"
7662053Smarkm      echo ''
7762053Smarkm      echo -n "    *** How should I deal with the merged file? [Leave it for later] "
78130585Sphk      read INSTALL_MERGED
7962053Smarkm
8091600Smarkm      case "${INSTALL_MERGED}" in
8162053Smarkm      [iI])
82130585Sphk        mv "${COMPFILE}.merged" "${COMPFILE}"
8362053Smarkm        echo ''
84128059Smarkm        if mm_install "${COMPFILE}"; then
85128367Smarkm          echo "     *** Merged version of ${COMPFILE} installed successfully"
8662053Smarkm        else
87128059Smarkm          echo "     *** Problem installing ${COMPFILE}, it will remain to merge by hand later"
88254147Sobrien        fi
89254147Sobrien        unset MERGE_AGAIN
90128059Smarkm        ;;
91128059Smarkm      [rR])
92128059Smarkm        rm "${COMPFILE}.merged"
93128367Smarkm        ;;
94256381Smarkm      [vV])
95128367Smarkm        ${PAGER} "${COMPFILE}.merged"
96128059Smarkm        ;;
97128059Smarkm      '')
98254147Sobrien        echo "   *** ${COMPFILE} will remain for your consideration"
99128059Smarkm        unset MERGE_AGAIN
100128059Smarkm        ;;
101256381Smarkm      *)
102256381Smarkm        echo "invalid choice: ${INSTALL_MERGED}"
103256381Smarkm        INSTALL_MERGED=V
104128367Smarkm        ;;
105256381Smarkm      esac
106128367Smarkm    done
10767286Speter  done
108128151Smarkm}
109128059Smarkm
11062053Smarkm# Loop showing user differences between files, allow merge, skip or install
11162053Smarkm# options
11291600Smarkmdiff_loop () {
11362053Smarkm
114130585Sphk  HANDLE_COMPFILE=v
11562053Smarkm
11662053Smarkm  while [ "${HANDLE_COMPFILE}" = "v" -o "${HANDLE_COMPFILE}" = "V" -o \
117256381Smarkm    "${HANDLE_COMPFILE}" = "NOT V" ]; do
118256381Smarkm    if [ -f "${DESTDIR}${COMPFILE#.}" -a -f "${COMPFILE}" ]; then
119256381Smarkm      if [ -n "${AUTO_UPGRADE}" -a -n "${CHANGED}" ]; then
120256381Smarkm        case "${CHANGED}" in
121256381Smarkm        *:${DESTDIR}${COMPFILE#.}:*) ;;		# File has been modified
122256381Smarkm        *)
123256381Smarkm          echo ''
124128367Smarkm          echo "  *** ${COMPFILE} has not been user modified."
125256381Smarkm          echo ''
12662053Smarkm
12762053Smarkm          if mm_install "${COMPFILE}"; then
12891600Smarkm            echo "   *** ${COMPFILE} upgraded successfully"
12962053Smarkm            echo ''
130130585Sphk            # Make the list print one file per line
13191600Smarkm            AUTO_UPGRADED_FILES="${AUTO_UPGRADED_FILES}      ${DESTDIR}${COMPFILE#.}
13265686Smarkm"
133128059Smarkm          else
134128059Smarkm            echo "   *** Problem upgrading ${COMPFILE}, it will remain to merge by hand"
13574771Smarkm          fi
136128059Smarkm          return
13774771Smarkm          ;;
13874771Smarkm        esac
139128059Smarkm      fi
14074771Smarkm      if [ "${HANDLE_COMPFILE}" = "v" -o "${HANDLE_COMPFILE}" = "V" ]; then
141128059Smarkm	echo ''
14274771Smarkm	echo '   ======================================================================   '
143128059Smarkm	echo ''
14465686Smarkm        (
14565686Smarkm          echo "  *** Displaying differences between ${COMPFILE} and installed version:"
14691600Smarkm          echo ''
14765686Smarkm          diff ${DIFF_FLAG} ${DIFF_OPTIONS} "${DESTDIR}${COMPFILE#.}" "${COMPFILE}"
148130585Sphk        ) | ${PAGER}
14967112Smarkm        echo ''
150128059Smarkm      fi
15167112Smarkm    else
15267112Smarkm      echo ''
153254147Sobrien      echo "  *** There is no installed version of ${COMPFILE}"
15467112Smarkm      echo ''
15567112Smarkm      case "${AUTO_INSTALL}" in
156256381Smarkm      [Yy][Ee][Ss])
15767112Smarkm        echo ''
158128059Smarkm        if mm_install "${COMPFILE}"; then
15967112Smarkm          echo "   *** ${COMPFILE} installed successfully"
16067112Smarkm          echo ''
161254147Sobrien          # Make the list print one file per line
162254147Sobrien          AUTO_INSTALLED_FILES="${AUTO_INSTALLED_FILES}      ${DESTDIR}${COMPFILE#.}
163254147Sobrien"
164256381Smarkm        else
165256381Smarkm          echo "   *** Problem installing ${COMPFILE}, it will remain to merge by hand"
166254147Sobrien        fi
167254147Sobrien        return
168254147Sobrien        ;;
169254147Sobrien      *)
170254147Sobrien        NO_INSTALLED=yes
171254147Sobrien        ;;
172254147Sobrien      esac
173254147Sobrien    fi
174254147Sobrien
175254147Sobrien    echo "  Use 'd' to delete the temporary ${COMPFILE}"
176254147Sobrien    echo "  Use 'i' to install the temporary ${COMPFILE}"
177254147Sobrien    case "${NO_INSTALLED}" in
178256381Smarkm    '')
179256381Smarkm      echo "  Use 'm' to merge the temporary and installed versions"
180254147Sobrien      echo "  Use 'v' to view the diff results again"
181254147Sobrien      ;;
182256381Smarkm    esac
183254147Sobrien    echo ''
184254147Sobrien    echo "  Default is to leave the temporary file to deal with by hand"
185254147Sobrien    echo ''
186254147Sobrien    echo -n "How should I deal with this? [Leave it for later] "
187254147Sobrien    read HANDLE_COMPFILE
18891600Smarkm
18967112Smarkm    case "${HANDLE_COMPFILE}" in
19091600Smarkm    [dD])
19162053Smarkm      rm "${COMPFILE}"
192256381Smarkm      echo ''
193128059Smarkm      echo "   *** Deleting ${COMPFILE}"
19465686Smarkm      ;;
195128059Smarkm    [iI])
19662053Smarkm      echo ''
197255362Smarkm      if mm_install "${COMPFILE}"; then
19871037Smarkm        echo "   *** ${COMPFILE} installed successfully"
199254147Sobrien      else
200256381Smarkm        echo "   *** Problem installing ${COMPFILE}, it will remain to merge by hand"
201256381Smarkm      fi
202254147Sobrien      ;;
203254147Sobrien    [mM])
204256381Smarkm      case "${NO_INSTALLED}" in
205254147Sobrien      '')
20671037Smarkm        # interact with user to merge files
207128059Smarkm        merge_loop
20874072Smarkm        ;;
20962053Smarkm      *)
210254147Sobrien        echo ''
211254147Sobrien        echo "   *** There is no installed version of ${COMPFILE}"
212254147Sobrien        echo ''
213254147Sobrien        HANDLE_COMPFILE="NOT V"
214254147Sobrien        ;;
215256381Smarkm      esac # End of "No installed version of file but user selected merge" test
216254147Sobrien      ;;
217254147Sobrien    [vV])
21874072Smarkm      continue
219128059Smarkm      ;;
220122871Smarkm    '')
22162053Smarkm      echo ''
222128059Smarkm      echo "   *** ${COMPFILE} will remain for your consideration"
22362053Smarkm      ;;
224132199Sphk    *)
225132199Sphk      # invalid choice, show menu again.
226132199Sphk      echo "invalid choice: ${HANDLE_COMPFILE}"
227132199Sphk      echo ''
22862053Smarkm      HANDLE_COMPFILE="NOT V"
229128059Smarkm      continue
23062053Smarkm      ;;
23162053Smarkm    esac  # End of "How to handle files that are different"
23262053Smarkm  done
233133036Smarkm  unset NO_INSTALLED
234  echo ''
235  case "${VERBOSE}" in
236  '') ;;
237  *)
238    sleep 3
239    ;;
240  esac
241}
242
243press_to_continue () {
244  local DISCARD
245  echo -n ' *** Press the [Enter] or [Return] key to continue '
246  read DISCARD
247}
248
249# Set the default path for the temporary root environment
250#
251TEMPROOT='/var/tmp/temproot'
252
253# Read /etc/mergemaster.rc first so the one in $HOME can override
254#
255if [ -r /etc/mergemaster.rc ]; then
256  . /etc/mergemaster.rc
257fi
258
259# Read .mergemasterrc before command line so CLI can override
260#
261if [ -r "$HOME/.mergemasterrc" ]; then
262  . "$HOME/.mergemasterrc"
263fi
264
265# Check the command line options
266#
267while getopts ":ascrvhipCPm:t:du:w:D:A:FU" COMMAND_LINE_ARGUMENT ; do
268  case "${COMMAND_LINE_ARGUMENT}" in
269  A)
270    ARCHSTRING='TARGET_ARCH='${OPTARG}
271    ;;
272  F)
273    FREEBSD_ID=yes
274    ;;
275  U)
276    AUTO_UPGRADE=yes
277    ;;
278  s)
279    STRICT=yes
280    unset DIFF_OPTIONS
281    ;;
282  c)
283    DIFF_FLAG='-c'
284    ;;
285  r)
286    RERUN=yes
287    ;;
288  v)
289    case "${AUTO_RUN}" in
290    '') VERBOSE=yes ;;
291    esac
292    ;;
293  a)
294    AUTO_RUN=yes
295    unset VERBOSE
296    ;;
297  h)
298    display_usage
299    display_help
300    exit 0
301    ;;
302  i)
303    AUTO_INSTALL=yes
304    ;;
305  C)
306    COMP_CONFS=yes
307    ;;
308  P)
309    PRESERVE_FILES=yes
310    ;;
311  p)
312    PRE_WORLD=yes
313    unset COMP_CONFS
314    unset AUTO_RUN
315    ;;
316  m)
317    SOURCEDIR=${OPTARG}
318    ;;
319  t)
320    TEMPROOT=${OPTARG}
321    ;;
322  d)
323    TEMPROOT=${TEMPROOT}.`date +%m%d.%H.%M`
324    ;;
325  u)
326    NEW_UMASK=${OPTARG}
327    ;;
328  w)
329    SCREEN_WIDTH=${OPTARG}
330    ;;
331  D)
332    DESTDIR=${OPTARG}
333    ;;
334  *)
335    display_usage
336    exit 1
337    ;;
338  esac
339done
340
341if [ -n "$AUTO_RUN" ]; then
342  if [ -n "$FREEBSD_ID" -o -n "$AUTO_UPGRADE" -o -n "$AUTO_INSTALL" ]; then
343    echo ''
344    echo "*** You have included the -a option along with one or more options"
345    echo '    that indicate that you wish mergemaster to actually make updates'
346    echo '    (-F, -U, or -i), however these options are not compatible.'
347    echo '    Please read mergemaster(8) for more information.'
348    echo ''
349    exit 1
350  fi
351fi
352
353# Assign the location of the mtree database
354#
355MTREEDB=${MTREEDB:-${DESTDIR}/var/db}
356MTREEFILE="${MTREEDB}/mergemaster.mtree"
357
358# Don't force the user to set this in the mergemaster rc file
359if [ -n "${PRESERVE_FILES}" -a -z "${PRESERVE_FILES_DIR}" ]; then
360  PRESERVE_FILES_DIR=/var/tmp/mergemaster/preserved-files-`date +%y%m%d-%H%M%S`
361  mkdir -p ${PRESERVE_FILES_DIR}
362fi
363
364# Check for the mtree database in DESTDIR
365case "${AUTO_UPGRADE}" in
366'') ;;	# If the option is not set no need to run the test or warn the user
367*)
368  if [ ! -s "${MTREEFILE}" ]; then
369    echo ''
370    echo "*** Unable to find mtree database (${MTREEFILE})."
371    echo "    Skipping auto-upgrade on this run."
372    echo "    It will be created for the next run when this one is complete."
373    echo ''
374    case "${AUTO_RUN}" in
375    '')
376      press_to_continue
377      ;;
378    esac
379    unset AUTO_UPGRADE
380  fi
381  ;;
382esac
383
384if [ -e "${DESTDIR}/etc/fstab" ]; then
385  if grep -q nodev ${DESTDIR}/etc/fstab; then
386    echo ''
387    echo "*** You have the deprecated 'nodev' option in ${DESTDIR}/etc/fstab."
388    echo "    This can prevent the filesystem from being mounted on reboot."
389    echo "    Please update your fstab before continuing."
390    echo "    See fstab(5) for more information."
391    echo ''
392    exit 1
393  fi
394fi
395
396echo ''
397
398# If the user has a pager defined, make sure we can run it
399#
400case "${DONT_CHECK_PAGER}" in
401'')
402check_pager () {
403  while ! type "${PAGER%% *}" >/dev/null; do
404    echo " *** Your PAGER environment variable specifies '${PAGER}', but"
405    echo "     due to the limited PATH that I use for security reasons,"
406    echo "     I cannot execute it.  So, what would you like to do?"
407    echo ''
408    echo "  Use 'e' to exit mergemaster and fix your PAGER variable"
409    if [ -x /usr/bin/less -o -x /usr/local/bin/less ]; then
410    echo "  Use 'l' to set PAGER to 'less' for this run"
411    fi
412    echo "  Use 'm' to use plain old 'more' as your PAGER for this run"
413    echo ''
414    echo "  Default is to use plain old 'more' "
415    echo ''
416    echo -n "What should I do? [Use 'more'] "
417    read FIXPAGER
418
419    case "${FIXPAGER}" in
420    [eE])
421       exit 0
422       ;;
423    [lL])
424       if [ -x /usr/bin/less ]; then
425         PAGER=/usr/bin/less
426       elif [ -x /usr/local/bin/less ]; then
427         PAGER=/usr/local/bin/less
428       else
429         echo ''
430         echo " *** Fatal Error:"
431         echo "     You asked to use 'less' as your pager, but I can't"
432         echo "     find it in /usr/bin or /usr/local/bin"
433         exit 1
434       fi
435       ;;
436    [mM]|'')
437       PAGER=more
438       ;;
439    *)
440       echo ''
441       echo "invalid choice: ${FIXPAGER}"
442    esac
443    echo ''
444  done
445}
446  if [ -n "${PAGER}" ]; then
447    check_pager
448  fi
449  ;;
450esac
451
452# If user has a pager defined, or got assigned one above, use it.
453# If not, use more.
454#
455PAGER=${PAGER:-more}
456
457if [ -n "${VERBOSE}" -a ! "${PAGER}" = "more" ]; then
458  echo " *** You have ${PAGER} defined as your pager so we will use that"
459  echo ''
460  sleep 3
461fi
462
463# Assign the diff flag once so we will not have to keep testing it
464#
465DIFF_FLAG=${DIFF_FLAG:--u}
466
467# Assign the source directory
468#
469SOURCEDIR=${SOURCEDIR:-/usr/src}
470if [ ! -f ${SOURCEDIR}/Makefile.inc1 -a \
471   -f ${SOURCEDIR}/../Makefile.inc1 ]; then
472  echo " *** The source directory you specified (${SOURCEDIR})"
473  echo "     will be reset to ${SOURCEDIR}/.."
474  echo ''
475  sleep 3
476  SOURCEDIR=${SOURCEDIR}/..
477fi
478
479# Setup make to use system files from SOURCEDIR
480MM_MAKE="make ${ARCHSTRING} -m ${SOURCEDIR}/share/mk"
481
482# Check DESTDIR against the mergemaster mtree database to see what
483# files the user changed from the reference files.
484#
485if [ -n "${AUTO_UPGRADE}" -a -s "${MTREEFILE}" ]; then
486	CHANGED=:
487	for file in `mtree -eqL -f ${MTREEFILE} -p ${DESTDIR}/ \
488		2>/dev/null | awk '($2 == "changed") {print $1}'`; do
489		if [ -f "${DESTDIR}/$file" ]; then
490			CHANGED="${CHANGED}${DESTDIR}/${file}:"
491		fi
492	done
493	[ "$CHANGED" = ':' ] && unset CHANGED
494fi
495
496# Check the width of the user's terminal
497#
498if [ -t 0 ]; then
499  w=`tput columns`
500  case "${w}" in
501  0|'') ;; # No-op, since the input is not valid
502  *)
503    case "${SCREEN_WIDTH}" in
504    '') SCREEN_WIDTH="${w}" ;;
505    "${w}") ;; # No-op, since they are the same
506    *)
507      echo -n "*** You entered ${SCREEN_WIDTH} as your screen width, but stty "
508      echo "thinks it is ${w}."
509      echo ''
510      echo -n "What would you like to use? [${w}] "
511      read SCREEN_WIDTH
512      case "${SCREEN_WIDTH}" in
513      '') SCREEN_WIDTH="${w}" ;;
514      esac
515      ;;
516    esac
517  esac
518fi
519
520# Define what CVS $Id tag to look for to aid portability.
521#
522CVS_ID_TAG=FreeBSD
523
524delete_temproot () {
525  rm -rf "${TEMPROOT}" 2>/dev/null
526  chflags -R 0 "${TEMPROOT}" 2>/dev/null
527  rm -rf "${TEMPROOT}" || { echo "*** Unable to delete ${TEMPROOT}";  exit 1; }
528}
529
530case "${RERUN}" in
531'')
532  # Set up the loop to test for the existence of the
533  # temp root directory.
534  #
535  TEST_TEMP_ROOT=yes
536  while [ "${TEST_TEMP_ROOT}" = "yes" ]; do
537    if [ -d "${TEMPROOT}" ]; then
538      echo "*** The directory specified for the temporary root environment,"
539      echo "    ${TEMPROOT}, exists.  This can be a security risk if untrusted"
540      echo "    users have access to the system."
541      echo ''
542      case "${AUTO_RUN}" in
543      '')
544        echo "  Use 'd' to delete the old ${TEMPROOT} and continue"
545        echo "  Use 't' to select a new temporary root directory"
546        echo "  Use 'e' to exit mergemaster"
547        echo ''
548        echo "  Default is to use ${TEMPROOT} as is"
549        echo ''
550        echo -n "How should I deal with this? [Use the existing ${TEMPROOT}] "
551        read DELORNOT
552
553        case "${DELORNOT}" in
554        [dD])
555          echo ''
556          echo "   *** Deleting the old ${TEMPROOT}"
557          echo ''
558          delete_temproot
559          unset TEST_TEMP_ROOT
560          ;;
561        [tT])
562          echo "   *** Enter new directory name for temporary root environment"
563          read TEMPROOT
564          ;;
565        [eE])
566          exit 0
567          ;;
568        '')
569          echo ''
570          echo "   *** Leaving ${TEMPROOT} intact"
571          echo ''
572          unset TEST_TEMP_ROOT
573          ;;
574        *)
575          echo ''
576          echo "invalid choice: ${DELORNOT}"
577          echo ''
578          ;;
579        esac
580        ;;
581      *)
582        # If this is an auto-run, try a hopefully safe alternative then
583        # re-test anyway.
584        TEMPROOT=/var/tmp/temproot.`date +%m%d.%H.%M.%S`
585        ;;
586      esac
587    else
588      unset TEST_TEMP_ROOT
589    fi
590  done
591
592  echo "*** Creating the temporary root environment in ${TEMPROOT}"
593
594  if mkdir -p "${TEMPROOT}"; then
595    echo " *** ${TEMPROOT} ready for use"
596  fi
597
598  if [ ! -d "${TEMPROOT}" ]; then
599    echo ''
600    echo "  *** FATAL ERROR: Cannot create ${TEMPROOT}"
601    echo ''
602    exit 1
603  fi
604
605  echo " *** Creating and populating directory structure in ${TEMPROOT}"
606  echo ''
607
608  case "${VERBOSE}" in
609  '') ;;
610  *)
611    press_to_continue
612    ;;
613  esac
614
615  case "${PRE_WORLD}" in
616  '')
617    { cd ${SOURCEDIR} &&
618      case "${DESTDIR}" in
619      '') ;;
620      *)
621        ${MM_MAKE} DESTDIR=${DESTDIR} distrib-dirs >/dev/null
622        ;;
623      esac
624      od=${TEMPROOT}/usr/obj
625      ${MM_MAKE} DESTDIR=${TEMPROOT} distrib-dirs >/dev/null &&
626      MAKEOBJDIRPREFIX=$od ${MM_MAKE} _obj SUBDIR_OVERRIDE=etc >/dev/null &&
627      MAKEOBJDIRPREFIX=$od ${MM_MAKE} everything SUBDIR_OVERRIDE=etc >/dev/null &&
628      MAKEOBJDIRPREFIX=$od ${MM_MAKE} DESTDIR=${TEMPROOT} distribution >/dev/null;} ||
629    { echo '';
630     echo "  *** FATAL ERROR: Cannot 'cd' to ${SOURCEDIR} and install files to";
631      echo "      the temproot environment";
632      echo '';
633      exit 1;}
634    ;;
635  *)
636    # Only set up files that are crucial to {build|install}world
637    { mkdir -p ${TEMPROOT}/etc &&
638      cp -p ${SOURCEDIR}/etc/master.passwd ${TEMPROOT}/etc &&
639      install -p -o root -g wheel -m 0644 ${SOURCEDIR}/etc/group ${TEMPROOT}/etc;} ||
640    { echo '';
641      echo '  *** FATAL ERROR: Cannot copy files to the temproot environment';
642      echo '';
643      exit 1;}
644    ;;
645  esac
646
647  # Doing the inventory and removing files that we don't want to compare only
648  # makes sense if we are not doing a rerun, since we have no way of knowing
649  # what happened to the files during previous incarnations.
650  case "${VERBOSE}" in
651  '') ;;
652  *)
653    echo ''
654    echo ' *** The following files exist only in the installed version of'
655    echo "     ${DESTDIR}/etc.  In the vast majority of cases these files"
656    echo '     are necessary parts of the system and should not be deleted.'
657    echo '     However because these files are not updated by this process you'
658    echo '     might want to verify their status before rebooting your system.'
659    echo ''
660    press_to_continue
661    diff -qr ${DESTDIR}/etc ${TEMPROOT}/etc | grep "^Only in ${DESTDIR}/etc" | ${PAGER}
662    echo ''
663    press_to_continue
664    ;;
665  esac
666
667  case "${IGNORE_MOTD}" in
668  '') ;;
669  *)
670     echo ''
671     echo "*** You have the IGNORE_MOTD option set in your mergemaster rc file."
672     echo "    This option is deprecated in favor of the IGNORE_FILES option."
673     echo "    Please update your rc file accordingly."
674     echo ''
675     exit 1
676     ;;
677  esac
678
679  # Avoid comparing the following user specified files
680  for file in ${IGNORE_FILES}; do
681    test -e ${TEMPROOT}/${file} && unlink ${TEMPROOT}/${file}
682  done
683
684  # We really don't want to have to deal with files like login.conf.db, pwd.db,
685  # or spwd.db.  Instead, we want to compare the text versions, and run *_mkdb.
686  # Prompt the user to do so below, as needed.
687  #
688  rm -f ${TEMPROOT}/etc/*.db ${TEMPROOT}/etc/passwd
689
690  # We only need to compare things like freebsd.cf once
691  find ${TEMPROOT}/usr/obj -type f -delete 2>/dev/null
692
693  # Delete stuff we do not need to keep the mtree database small,
694  # and to make the actual comparison faster.
695  find ${TEMPROOT}/usr -type l -delete 2>/dev/null
696  find ${TEMPROOT} -type f -size 0 -delete 2>/dev/null
697  find -d ${TEMPROOT} -type d -empty -delete 2>/dev/null
698
699  # Build the mtree database in a temporary location.
700  case "${PRE_WORLD}" in
701  '') MTREENEW=`mktemp -t mergemaster.mtree`
702      mtree -ci -p ${TEMPROOT} -k size,md5digest > ${MTREENEW} 2>/dev/null
703      ;;
704  *) # We don't want to mess with the mtree database on a pre-world run or
705     # when re-scanning a previously-built tree.
706     ;;
707  esac
708  ;; # End of the "RERUN" test
709esac
710
711# Get ready to start comparing files
712
713# Check umask if not specified on the command line,
714# and we are not doing an autorun
715#
716if [ -z "${NEW_UMASK}" -a -z "${AUTO_RUN}" ]; then
717  USER_UMASK=`umask`
718  case "${USER_UMASK}" in
719  0022|022) ;;
720  *)
721    echo ''
722    echo " *** Your umask is currently set to ${USER_UMASK}.  By default, this script"
723    echo "     installs all files with the same user, group and modes that"
724    echo "     they are created with by ${SOURCEDIR}/etc/Makefile, compared to"
725    echo "     a umask of 022.  This umask allows world read permission when"
726    echo "     the file's default permissions have it."
727    echo ''
728    echo "     No world permissions can sometimes cause problems.  A umask of"
729    echo "     022 will restore the default behavior, but is not mandatory."
730    echo "     /etc/master.passwd is a special case.  Its file permissions"
731    echo "     will be 600 (rw-------) if installed."
732    echo ''
733    echo -n "What umask should I use? [${USER_UMASK}] "
734    read NEW_UMASK
735
736    NEW_UMASK="${NEW_UMASK:-$USER_UMASK}"
737    ;;
738  esac
739  echo ''
740fi
741
742CONFIRMED_UMASK=${NEW_UMASK:-0022}
743
744#
745# Warn users who still have old rc files
746#
747for file in atm devfs diskless1 diskless2 network network6 pccard \
748  serial syscons sysctl alpha amd64 i386 ia64 sparc64; do
749  if [ -f "${DESTDIR}/etc/rc.${file}" ]; then
750    OLD_RC_PRESENT=1
751    break
752  fi
753done
754
755case "${OLD_RC_PRESENT}" in
7561)
757  echo ''
758  echo " *** There are elements of the old rc system in ${DESTDIR}/etc/."
759  echo ''
760  echo '     While these scripts will not hurt anything, they are not'
761  echo '     functional on an up to date system, and can be removed.'
762  echo ''
763
764  case "${AUTO_RUN}" in
765  '')
766    echo -n 'Move these files to /var/tmp/mergemaster/old_rc? [yes] '
767    read MOVE_OLD_RC
768
769    case "${MOVE_OLD_RC}" in
770    [nN]*) ;;
771    *)
772      mkdir -p /var/tmp/mergemaster/old_rc
773        for file in atm devfs diskless1 diskless2 network network6 pccard \
774          serial syscons sysctl alpha amd64 i386 ia64 sparc64; do
775          if [ -f "${DESTDIR}/etc/rc.${file}" ]; then
776            mv ${DESTDIR}/etc/rc.${file} /var/tmp/mergemaster/old_rc/
777          fi
778        done
779      echo '  The files have been moved'
780      press_to_continue
781      ;;
782    esac
783    ;;
784  *) ;;
785  esac
786esac
787
788# Use the umask/mode information to install the files
789# Create directories as needed
790#
791install_error () {
792  echo "*** FATAL ERROR: Unable to install ${1} to ${2}"
793  echo ''
794  exit 1
795}
796
797do_install_and_rm () {
798  case "${PRESERVE_FILES}" in
799  [Yy][Ee][Ss])
800    if [ -f "${3}/${2##*/}" ]; then
801      mkdir -p ${PRESERVE_FILES_DIR}/${2%/*}
802      cp ${3}/${2##*/} ${PRESERVE_FILES_DIR}/${2%/*}
803    fi
804    ;;
805  esac
806
807  if [ ! -d "${3}/${2##*/}" ]; then
808    if install -m ${1} ${2} ${3}; then
809      unlink ${2}
810    else
811      install_error ${2} ${3}
812    fi
813  else
814    install_error ${2} ${3}
815  fi
816}
817
818# 4095 = "obase=10;ibase=8;07777" | bc
819find_mode () {
820  local OCTAL
821  OCTAL=$(( ~$(echo "obase=10; ibase=8; ${CONFIRMED_UMASK}" | bc) & 4095 &
822    $(echo "obase=10; ibase=8; $(stat -f "%OMp%OLp" ${1})" | bc) ))
823  printf "%04o\n" ${OCTAL}
824}
825
826mm_install () {
827  local INSTALL_DIR
828  INSTALL_DIR=${1#.}
829  INSTALL_DIR=${INSTALL_DIR%/*}
830
831  case "${INSTALL_DIR}" in
832  '')
833    INSTALL_DIR=/
834    ;;
835  esac
836
837  if [ -n "${DESTDIR}${INSTALL_DIR}" -a ! -d "${DESTDIR}${INSTALL_DIR}" ]; then
838    DIR_MODE=`find_mode "${TEMPROOT}/${INSTALL_DIR}"`
839    install -d -o root -g wheel -m "${DIR_MODE}" "${DESTDIR}${INSTALL_DIR}" ||
840      install_error $1 ${DESTDIR}${INSTALL_DIR}
841  fi
842
843  FILE_MODE=`find_mode "${1}"`
844
845  if [ ! -x "${1}" ]; then
846    case "${1#.}" in
847    /etc/mail/aliases)
848      NEED_NEWALIASES=yes
849      ;;
850    /etc/login.conf)
851      NEED_CAP_MKDB=yes
852      ;;
853    /etc/services)
854      NEED_SERVICES_MKDB=yes
855      ;;
856    /etc/master.passwd)
857      do_install_and_rm 600 "${1}" "${DESTDIR}${INSTALL_DIR}"
858      NEED_PWD_MKDB=yes
859      DONT_INSTALL=yes
860      ;;
861    /.cshrc | /.profile)
862      local st_nlink
863
864      # install will unlink the file before it installs the new one,
865      # so we have to restore/create the link afterwards.
866      #
867      st_nlink=0		# In case the file does not yet exist
868      eval $(stat -s ${DESTDIR}${COMPFILE#.} 2>/dev/null)
869
870      do_install_and_rm "${FILE_MODE}" "${1}" "${DESTDIR}${INSTALL_DIR}"
871
872      if [ -n "${AUTO_INSTALL}" -a $st_nlink -gt 1 ]; then
873        HANDLE_LINK=l
874      else
875        case "${LINK_EXPLAINED}" in
876        '')
877          echo "   *** Historically BSD derived systems have had a"
878          echo "       hard link from /.cshrc and /.profile to"
879          echo "       their namesakes in /root.  Please indicate"
880          echo "       your preference below for bringing your"
881          echo "       installed files up to date."
882          echo ''
883          LINK_EXPLAINED=yes
884          ;;
885        esac
886
887        echo "   Use 'd' to delete the temporary ${COMPFILE}"
888        echo "   Use 'l' to delete the existing ${DESTDIR}/root/${COMPFILE##*/} and create the link"
889        echo ''
890        echo "   Default is to leave the temporary file to deal with by hand"
891        echo ''
892        echo -n "  How should I handle ${COMPFILE}? [Leave it to install later] "
893        read HANDLE_LINK
894      fi
895
896      case "${HANDLE_LINK}" in
897      [dD]*)
898        rm "${COMPFILE}"
899        echo ''
900        echo "   *** Deleting ${COMPFILE}"
901        ;;
902      [lL]*)
903        echo ''
904        unlink ${DESTDIR}/root/${COMPFILE##*/}
905        if ln ${DESTDIR}${COMPFILE#.} ${DESTDIR}/root/${COMPFILE##*/}; then
906          echo "   *** Link from ${DESTDIR}${COMPFILE#.} to ${DESTDIR}/root/${COMPFILE##*/} installed successfully"
907        else
908          echo "   *** Error linking ${DESTDIR}${COMPFILE#.} to ${DESTDIR}/root/${COMPFILE##*/}"
909          echo "   *** ${COMPFILE} will remain for your consideration"
910        fi
911        ;;
912      *)
913        echo "   *** ${COMPFILE} will remain for your consideration"
914        ;;
915      esac
916      return
917      ;;
918    esac
919
920    case "${DONT_INSTALL}" in
921    '')
922      do_install_and_rm "${FILE_MODE}" "${1}" "${DESTDIR}${INSTALL_DIR}"
923      ;;
924    *)
925      unset DONT_INSTALL
926      ;;
927    esac
928  else	# File matched -x
929    do_install_and_rm "${FILE_MODE}" "${1}" "${DESTDIR}${INSTALL_DIR}"
930  fi
931  return $?
932}
933
934if [ ! -d "${TEMPROOT}" ]; then
935	echo "*** FATAL ERROR: The temproot directory (${TEMPROOT})"
936	echo '                 has disappeared!'
937	echo ''
938	exit 1
939fi
940
941echo ''
942echo "*** Beginning comparison"
943echo ''
944
945# Pre-world does not populate /etc/rc.d.
946# It is very possible that a previous run would have deleted files in
947# ${TEMPROOT}/etc/rc.d, thus creating a lot of false positives.
948if [ -z "${PRE_WORLD}" -a -z "${RERUN}" ]; then
949  echo "   *** Checking ${DESTDIR}/etc/rc.d for stale files"
950  echo ''
951  cd "${DESTDIR}/etc/rc.d" &&
952  for file in *; do
953    if [ ! -e "${TEMPROOT}/etc/rc.d/${file}" ]; then
954      STALE_RC_FILES="${STALE_RC_FILES} ${file}"
955    fi
956  done
957  case "${STALE_RC_FILES}" in
958  ''|' *')
959    echo '   *** No stale files found'
960    ;;
961  *)
962    echo "   *** The following files exist in ${DESTDIR}/etc/rc.d but not in"
963    echo "       ${TEMPROOT}/etc/rc.d/:"
964    echo ''
965    echo "${STALE_RC_FILES}"
966    echo ''
967    echo '       The presence of stale files in this directory can cause the'
968    echo '       dreaded unpredictable results, and therefore it is highly'
969    echo '       recommended that you delete them.'
970    case "${AUTO_RUN}" in
971    '')
972      echo ''
973      echo -n '   *** Delete them now? [n] '
974      read DELETE_STALE_RC_FILES
975      case "${DELETE_STALE_RC_FILES}" in
976      [yY])
977        echo '      *** Deleting ... '
978        rm ${STALE_RC_FILES}
979        echo '                       done.'
980        ;;
981      *)
982        echo '      *** Files will not be deleted'
983        ;;
984      esac
985      sleep 2
986      ;;
987    *)
988      if [ -n "${DELETE_STALE_RC_FILES}" ]; then
989        echo '      *** Deleting ... '
990        rm ${STALE_RC_FILES}
991        echo '                       done.'
992      fi
993    esac
994    ;;
995  esac
996  echo ''
997fi
998
999cd "${TEMPROOT}"
1000
1001if [ -r "${MM_PRE_COMPARE_SCRIPT}" ]; then
1002  . "${MM_PRE_COMPARE_SCRIPT}"
1003fi
1004
1005# Things that were files/directories/links in one version can sometimes
1006# change to something else in a newer version.  So we need to explicitly
1007# test for this, and warn the user if what we find does not match.
1008#
1009for COMPFILE in `find . | sort` ; do
1010  if [ -e "${DESTDIR}${COMPFILE#.}" ]; then
1011    INSTALLED_TYPE=`stat -f '%HT' ${DESTDIR}${COMPFILE#.}`
1012  else
1013    continue
1014  fi
1015  TEMPROOT_TYPE=`stat -f '%HT' $COMPFILE`
1016
1017  if [ ! "$TEMPROOT_TYPE" = "$INSTALLED_TYPE" ]; then
1018    [ "$COMPFILE" = '.' ] && continue
1019    TEMPROOT_TYPE=`echo $TEMPROOT_TYPE | tr [:upper:] [:lower:]`
1020    INSTALLED_TYPE=`echo $INSTALLED_TYPE | tr [:upper:] [:lower:]`
1021
1022    echo "*** The installed file ${DESTDIR}${COMPFILE#.} has the type \"$INSTALLED_TYPE\""
1023    echo "    but the new version has the type \"$TEMPROOT_TYPE\""
1024    echo ''
1025    echo "    How would you like to handle this?"
1026    echo ''
1027    echo "    Use 'r' to remove ${DESTDIR}${COMPFILE#.}"
1028    case "$TEMPROOT_TYPE" in
1029    'symbolic link')
1030	TARGET=`readlink $COMPFILE`
1031	echo "    and create a link to $TARGET in its place" ;;
1032    *)	echo "    You will be able to install it as a \"$TEMPROOT_TYPE\"" ;;
1033    esac
1034    echo ''
1035    echo "    Use 'i' to ignore this"
1036    echo ''
1037    echo -n "    How to proceed? [i] "
1038    read ANSWER
1039    case "$ANSWER" in
1040    [rR])	case "${PRESERVE_FILES}" in
1041		[Yy][Ee][Ss])
1042		mv ${DESTDIR}${COMPFILE#.} ${PRESERVE_FILES_DIR}/ || exit 1 ;;
1043		*) rm -rf ${DESTDIR}${COMPFILE#.} ;;
1044		esac
1045		case "$TEMPROOT_TYPE" in
1046		'symbolic link') ln -sf $TARGET ${DESTDIR}${COMPFILE#.} ;;
1047		esac ;;
1048    *)	echo ''
1049        echo "*** See the man page about adding ${COMPFILE#.} to the list of IGNORE_FILES"
1050        press_to_continue ;;
1051    esac
1052    echo ''
1053  fi
1054done
1055
1056for COMPFILE in `find . -type f | sort`; do
1057
1058  # First, check to see if the file exists in DESTDIR.  If not, the
1059  # diff_loop function knows how to handle it.
1060  #
1061  if [ ! -e "${DESTDIR}${COMPFILE#.}" ]; then
1062    case "${AUTO_RUN}" in
1063      '')
1064        diff_loop
1065        ;;
1066      *)
1067        case "${AUTO_INSTALL}" in
1068        '')
1069          # If this is an auto run, make it official
1070          echo "   *** ${COMPFILE} will remain for your consideration"
1071          ;;
1072        *)
1073          diff_loop
1074          ;;
1075        esac
1076        ;;
1077    esac # Auto run test
1078    continue
1079  fi
1080
1081  case "${STRICT}" in
1082  '' | [Nn][Oo])
1083    # Compare CVS $Id's first so if the file hasn't been modified
1084    # local changes will be ignored.
1085    # If the files have the same $Id, delete the one in temproot so the
1086    # user will have less to wade through if files are left to merge by hand.
1087    #
1088    CVSID1=`grep "[$]${CVS_ID_TAG}:" ${DESTDIR}${COMPFILE#.} 2>/dev/null`
1089    CVSID2=`grep "[$]${CVS_ID_TAG}:" ${COMPFILE} 2>/dev/null` || CVSID2=none
1090
1091    case "${CVSID2}" in
1092    "${CVSID1}")
1093      echo " *** Temp ${COMPFILE} and installed have the same CVS Id, deleting"
1094      rm "${COMPFILE}"
1095      ;;
1096    esac
1097    ;;
1098  esac
1099
1100  # If the file is still here either because the $Ids are different, the
1101  # file doesn't have an $Id, or we're using STRICT mode; look at the diff.
1102  #
1103  if [ -f "${COMPFILE}" ]; then
1104
1105    # Do an absolute diff first to see if the files are actually different.
1106    # If they're not different, delete the one in temproot.
1107    #
1108    if diff -q ${DIFF_OPTIONS} "${DESTDIR}${COMPFILE#.}" "${COMPFILE}" > \
1109      /dev/null 2>&1; then
1110      echo " *** Temp ${COMPFILE} and installed are the same, deleting"
1111      rm "${COMPFILE}"
1112    else
1113      # Ok, the files are different, so show the user where they differ.
1114      # Use user's choice of diff methods; and user's pager if they have one.
1115      # Use more if not.
1116      # Use unified diffs by default.  Context diffs give me a headache. :)
1117      #
1118      # If the user chose the -F option, test for that before proceeding
1119      #
1120      if [ -n "$FREEBSD_ID" ]; then
1121        if diff -q -I'[$]FreeBSD.*[$]' "${DESTDIR}${COMPFILE#.}" "${COMPFILE}" > \
1122            /dev/null 2>&1; then
1123          if mm_install "${COMPFILE}"; then
1124            echo "*** Updated revision control Id for ${DESTDIR}${COMPFILE#.}"
1125          else
1126            echo "*** Problem installing ${COMPFILE}, it will remain to merge by hand later"
1127          fi
1128          continue
1129        fi
1130      fi
1131      case "${AUTO_RUN}" in
1132      '')
1133        # prompt user to install/delete/merge changes
1134        diff_loop
1135        ;;
1136      *)
1137        # If this is an auto run, make it official
1138        echo "   *** ${COMPFILE} will remain for your consideration"
1139        ;;
1140      esac # Auto run test
1141    fi # Yes, the files are different
1142  fi # Yes, the file still remains to be checked
1143done # This is for the for way up there at the beginning of the comparison
1144
1145echo ''
1146echo "*** Comparison complete"
1147
1148if [ -s "${MTREENEW}" ]; then
1149  echo "*** Saving mtree database for future upgrades"
1150  test -e "${MTREEFILE}" && unlink ${MTREEFILE}
1151  mv ${MTREENEW} ${MTREEFILE}
1152fi
1153
1154echo ''
1155
1156TEST_FOR_FILES=`find ${TEMPROOT} -type f -size +0 2>/dev/null`
1157if [ -n "${TEST_FOR_FILES}" ]; then
1158  echo "*** Files that remain for you to merge by hand:"
1159  find "${TEMPROOT}" -type f -size +0 | sort
1160  echo ''
1161
1162  case "${AUTO_RUN}" in
1163  '')
1164    echo -n "Do you wish to delete what is left of ${TEMPROOT}? [no] "
1165    read DEL_TEMPROOT
1166    case "${DEL_TEMPROOT}" in
1167    [yY]*)
1168      delete_temproot
1169      ;;
1170    *)
1171      echo " *** ${TEMPROOT} will remain"
1172      ;;
1173    esac
1174    ;;
1175  *) ;;
1176  esac
1177else
1178  echo "*** ${TEMPROOT} is empty, deleting"
1179  delete_temproot
1180fi
1181
1182case "${AUTO_INSTALLED_FILES}" in
1183'') ;;
1184*)
1185  case "${AUTO_RUN}" in
1186  '')
1187    (
1188      echo ''
1189      echo '*** You chose the automatic install option for files that did not'
1190      echo '    exist on your system.  The following were installed for you:'
1191      echo "${AUTO_INSTALLED_FILES}"
1192    ) | ${PAGER}
1193    ;;
1194  *)
1195    echo ''
1196    echo '*** You chose the automatic install option for files that did not'
1197    echo '    exist on your system.  The following were installed for you:'
1198    echo "${AUTO_INSTALLED_FILES}"
1199    ;;
1200  esac
1201  ;;
1202esac
1203
1204case "${AUTO_UPGRADED_FILES}" in
1205'') ;;
1206*)
1207  case "${AUTO_RUN}" in
1208  '')
1209    (
1210      echo ''
1211      echo '*** You chose the automatic upgrade option for files that you did'
1212      echo '    not alter on your system.  The following were upgraded for you:'
1213      echo "${AUTO_UPGRADED_FILES}"
1214    ) | ${PAGER}
1215    ;;
1216  *)
1217    echo ''
1218    echo '*** You chose the automatic upgrade option for files that you did'
1219    echo '    not alter on your system.  The following were upgraded for you:'
1220    echo "${AUTO_UPGRADED_FILES}"
1221    ;;
1222  esac
1223  ;;
1224esac
1225
1226run_it_now () {
1227  case "${AUTO_RUN}" in
1228  '')
1229    unset YES_OR_NO
1230    echo ''
1231    echo -n '    Would you like to run it now? y or n [n] '
1232    read YES_OR_NO
1233
1234    case "${YES_OR_NO}" in
1235    y)
1236      echo "    Running ${1}"
1237      echo ''
1238      eval "${1}"
1239      ;;
1240    ''|n)
1241      echo ''
1242      echo "       *** Cancelled"
1243      echo ''
1244      echo "    Make sure to run ${1} yourself"
1245      ;;
1246    *)
1247      echo ''
1248      echo "       *** Sorry, I do not understand your answer (${YES_OR_NO})"
1249      echo ''
1250      echo "    Make sure to run ${1} yourself"
1251    esac
1252    ;;
1253  *) ;;
1254  esac
1255}
1256
1257case "${NEED_NEWALIASES}" in
1258'') ;;
1259*)
1260  echo ''
1261  if [ -n "${DESTDIR}" ]; then
1262    echo "*** You installed a new aliases file into ${DESTDIR}/etc/mail, but"
1263    echo "    the newaliases command is limited to the directories configured"
1264    echo "    in sendmail.cf.  Make sure to create your aliases database by"
1265    echo "    hand when your sendmail configuration is done."
1266  else
1267    echo "*** You installed a new aliases file, so make sure that you run"
1268    echo "    '/usr/bin/newaliases' to rebuild your aliases database"
1269    run_it_now '/usr/bin/newaliases'
1270  fi
1271  ;;
1272esac
1273
1274case "${NEED_CAP_MKDB}" in
1275'') ;;
1276*)
1277  echo ''
1278  echo "*** You installed a login.conf file, so make sure that you run"
1279  echo "    '/usr/bin/cap_mkdb ${DESTDIR}/etc/login.conf'"
1280  echo "     to rebuild your login.conf database"
1281  run_it_now "/usr/bin/cap_mkdb ${DESTDIR}/etc/login.conf"
1282  ;;
1283esac
1284
1285case "${NEED_SERVICES_MKDB}" in
1286'') ;;
1287*)
1288  echo ''
1289  echo "*** You installed a services file, so make sure that you run"
1290  echo "    '/usr/sbin/services_mkdb -q -o ${DESTDIR}/var/db/services.db ${DESTDIR}/etc/services'"
1291  echo "     to rebuild your services database"
1292  run_it_now "/usr/sbin/services_mkdb -q -o ${DESTDIR}/var/db/services.db ${DESTDIR}/etc/services"
1293  ;;
1294esac
1295
1296case "${NEED_PWD_MKDB}" in
1297'') ;;
1298*)
1299  echo ''
1300  echo "*** You installed a new master.passwd file, so make sure that you run"
1301  if [ -n "${DESTDIR}" ]; then
1302    echo "    '/usr/sbin/pwd_mkdb -d ${DESTDIR}/etc -p ${DESTDIR}/etc/master.passwd'"
1303    echo "    to rebuild your password files"
1304    run_it_now "/usr/sbin/pwd_mkdb -d ${DESTDIR}/etc -p ${DESTDIR}/etc/master.passwd"
1305  else
1306    echo "    '/usr/sbin/pwd_mkdb -p /etc/master.passwd'"
1307    echo "     to rebuild your password files"
1308    run_it_now '/usr/sbin/pwd_mkdb -p /etc/master.passwd'
1309  fi
1310  ;;
1311esac
1312
1313echo ''
1314
1315if [ -r "${MM_EXIT_SCRIPT}" ]; then
1316  . "${MM_EXIT_SCRIPT}"
1317fi
1318
1319case "${COMP_CONFS}" in
1320'') ;;
1321*)
1322  . ${DESTDIR}/etc/defaults/rc.conf
1323
1324  (echo ''
1325  echo "*** Comparing conf files: ${rc_conf_files}"
1326
1327  for CONF_FILE in ${rc_conf_files}; do
1328    if [ -r "${DESTDIR}${CONF_FILE}" ]; then
1329      echo ''
1330      echo "*** From ${DESTDIR}${CONF_FILE}"
1331      echo "*** From ${DESTDIR}/etc/defaults/rc.conf"
1332
1333      for RC_CONF_VAR in `grep -i ^[a-z] ${DESTDIR}${CONF_FILE} |
1334        cut -d '=' -f 1`; do
1335        echo ''
1336        grep -w ^${RC_CONF_VAR} ${DESTDIR}${CONF_FILE}
1337        grep -w ^${RC_CONF_VAR} ${DESTDIR}/etc/defaults/rc.conf ||
1338          echo ' * No default variable with this name'
1339      done
1340    fi
1341  done) | ${PAGER}
1342  echo ''
1343  ;;
1344esac
1345
1346case "${PRE_WORLD}" in
1347'') ;;
1348*)
1349  MAKE_CONF="${SOURCEDIR}/share/examples/etc/make.conf"
1350
1351  (echo ''
1352  echo '*** Comparing make variables'
1353  echo ''
1354  echo "*** From ${DESTDIR}/etc/make.conf"
1355  echo "*** From ${MAKE_CONF}"
1356
1357  for MAKE_VAR in `grep -i ^[a-z] ${DESTDIR}/etc/make.conf | cut -d '=' -f 1`; do
1358    echo ''
1359    grep -w ^${MAKE_VAR} ${DESTDIR}/etc/make.conf
1360    grep -w ^#${MAKE_VAR} ${MAKE_CONF} ||
1361      echo ' * No example variable with this name'
1362  done) | ${PAGER}
1363  ;;
1364esac
1365
1366if [ -n "${PRESERVE_FILES}" ]; then
1367  find -d $PRESERVE_FILES_DIR -type d -empty -delete 2>/dev/null
1368  rmdir $PRESERVE_FILES_DIR 2>/dev/null
1369fi
1370
1371exit 0
1372