Deleted Added
sdiff udiff text old ( 67859 ) new ( 67949 )
full compact
1#!/bin/sh
2
3# mergemaster
4
5# Compare files created by /usr/src/etc/Makefile (or the directory
6# the user specifies) with the currently installed copies.
7
8# Copyright 1998-2000 Douglas Barton
9# Doug@gorean.org
10
11# $FreeBSD: head/usr.sbin/mergemaster/mergemaster.sh 67949 2000-10-30 10:33:51Z dougb $
12
13PATH=/bin:/usr/bin:/usr/sbin:/sbin
14
15display_usage () {
16 VERSION_NUMBER=`grep "[$]FreeBSD:" $0 | cut -d ' ' -f 4`
17 echo "mergemaster version ${VERSION_NUMBER}"
18 echo 'Usage: mergemaster [-scrvahi] [-m /path]'
19 echo ' [-t /path] [-d] [-u N] [-w N] [-D /path]'
20 echo "Options:"
21 echo " -s Strict comparison (diff every pair of files)"
22 echo " -c Use context diff instead of unified diff"
23 echo " -r Re-run on a previously cleaned directory (skip temproot creation)"
24 echo " -v Be more verbose about the process, include additional checks"
25 echo " -a Leave all files that differ to merge by hand"
26 echo " -h Display more complete help"
27 echo ' -i Automatically install files that do not exist in destination directory'
28 echo " -m /path/directory Specify location of source to do the make in"
29 echo " -t /path/directory Specify temp root directory"
30 echo " -d Add date and time to directory name (e.g., /var/tmp/temproot.`date +%m%d.%H.%M`)"
31 echo " -u N Specify a numeric umask"
32 echo " -w N Specify a screen width in columns to sdiff"
33 echo ' -D /path/directory Specify the destination directory to install files to'
34 echo ''
35}
36
37display_help () {
38 echo "* To specify a directory other than /var/tmp/temproot for the"
39 echo " temporary root environment, use -t /path/to/temp/root"
40 echo "* The -w option takes a number as an argument for the column width"
41 echo " of the screen. The default is 80."
42 echo '* The -a option causes mergemaster to run without prompting.'
43}
44
45# Loop allowing the user to use sdiff to merge files and display the merged
46# file.
47merge_loop () {
48 case "${VERBOSE}" in
49 '') ;;
50 *)
51 echo " *** Type h at the sdiff prompt (%) to get usage help"
52 ;;
53 esac
54 echo ''
55 MERGE_AGAIN=yes
56 while [ "${MERGE_AGAIN}" = "yes" ]; do
57 # Prime file.merged so we don't blat the owner/group id's
58 cp -p "${COMPFILE}" "${COMPFILE}.merged"
59 sdiff -o "${COMPFILE}.merged" --text --suppress-common-lines \
60 --width=${SCREEN_WIDTH:-80} "${DESTDIR}${COMPFILE#.}" "${COMPFILE}"
61 INSTALL_MERGED=V
62 while [ "${INSTALL_MERGED}" = "v" -o "${INSTALL_MERGED}" = "V" ]; do
63 echo ''
64 echo " Use 'i' to install merged file"
65 echo " Use 'r' to re-do the merge"
66 echo " Use 'v' to view the merged file"
67 echo " Default is to leave the temporary file to deal with by hand"
68 echo ''

--- 32 unchanged lines hidden (view full) ---

101
102# Loop showing user differences between files, allow merge, skip or install
103# options
104diff_loop () {
105
106 HANDLE_COMPFILE=v
107
108 while [ "${HANDLE_COMPFILE}" = "v" -o "${HANDLE_COMPFILE}" = "V" -o "${HANDLE_COMPFILE}" = "NOT V" ]; do
109 if [ -f "${DESTDIR}${COMPFILE#.}" -a -f "${COMPFILE}" ]; then
110 if [ "${HANDLE_COMPFILE}" = "v" -o "${HANDLE_COMPFILE}" = "V" ]; then
111 (
112 echo ''
113 echo " *** Displaying differences between ${COMPFILE} and installed version:"
114 echo ''
115 diff "${DIFF_FLAG}" "${DESTDIR}${COMPFILE#.}" "${COMPFILE}"
116 ) | ${PAGER}
117 echo ''
118 fi
119 else
120 echo ''
121 echo " *** There is no installed version of ${COMPFILE}"
122 case "${AUTO_INSTALL}" in
123 [Yy][Ee][Ss])
124 echo ''
125 if mm_install "${COMPFILE}"; then
126 echo " *** ${COMPFILE} installed successfully"
127 # Make the list print one file per line
128 AUTO_INSTALLED_FILES="${AUTO_INSTALLED_FILES} ${DESTDIR}${COMPFILE#.}
129"
130 else
131 echo " *** Problem installing ${COMPFILE}, it will remain to merge by hand"
132 fi
133 return
134 ;;
135 *)
136 NO_INSTALLED=yes
137 ;;
138 esac
139 fi
140
141 echo " Use 'd' to delete the temporary ${COMPFILE}"
142 echo " Use 'i' to install the temporary ${COMPFILE}"
143 case "${NO_INSTALLED}" in
144 '')
145 echo " Use 'm' to merge the old and new versions"
146 echo " Use 'v' to view to differences between the old and new versions again"

--- 44 unchanged lines hidden (view full) ---

191 # invalid choice, show menu again.
192 echo "invalid choice: ${HANDLE_COMPFILE}"
193 echo ''
194 HANDLE_COMPFILE="NOT V"
195 continue
196 ;;
197 esac # End of "How to handle files that are different"
198 done
199 unset NO_INSTALLED
200 echo ''
201 case "${VERBOSE}" in
202 '') ;;
203 *)
204 sleep 3
205 ;;
206 esac
207}
208
209# Set the default path for the temporary root environment
210#
211TEMPROOT='/var/tmp/temproot'
212
213# Read .mergemasterrc before command line so CLI can override
214#
215if [ -r "$HOME/.mergemasterrc" ]; then
216 . "$HOME/.mergemasterrc"
217fi
218
219# Check the command line options
220#
221while getopts ":ascrvhim:t:du:w:D:" COMMAND_LINE_ARGUMENT ; do
222 case "${COMMAND_LINE_ARGUMENT}" in
223 s)
224 STRICT=yes
225 ;;
226 c)
227 DIFF_FLAG='-c'
228 ;;
229 r)

--- 8 unchanged lines hidden (view full) ---

238 AUTO_RUN=yes
239 unset VERBOSE
240 ;;
241 h)
242 display_usage
243 display_help
244 exit 0
245 ;;
246 i)
247 AUTO_INSTALL=yes
248 ;;
249 m)
250 SOURCEDIR=${OPTARG}
251 ;;
252 t)
253 TEMPROOT=${OPTARG}
254 ;;
255 d)
256 TEMPROOT=${TEMPROOT}.`date +%m%d.%H.%M`
257 ;;
258 u)
259 NEW_UMASK=${OPTARG}
260 ;;
261 w)
262 SCREEN_WIDTH=${OPTARG}
263 ;;
264 D)
265 DESTDIR=${OPTARG}
266 ;;
267 *)
268 display_usage
269 exit 1
270 ;;
271 esac
272done
273
274echo ''

--- 148 unchanged lines hidden (view full) ---

423 *)
424 echo " *** Press [Enter] or [Return] key to continue"
425 read ANY_KEY
426 unset ANY_KEY
427 ;;
428 esac
429
430 { cd ${SOURCEDIR} &&
431 make DESTDIR=${DESTDIR} distrib-dirs &&
432 make DESTDIR=${TEMPROOT} distrib-dirs &&
433 make DESTDIR=${TEMPROOT} -DNO_MAKEDEV distribution;} ||
434 { echo '';
435 echo " *** FATAL ERROR: Cannot 'cd' to ${SOURCEDIR} and install files to the";
436 echo " temproot environment";
437 echo '';
438 exit 1;}
439
440 # Doing the inventory and removing files that we don't want to compare only makes
441 # sense if we are not doing a rerun, since we have no way of knowing what happened
442 # to the files during previous incarnations.
443 case "${VERBOSE}" in
444 '') ;;
445 *)
446 echo ''
447 echo ' *** The following files exist only in the installed version of'
448 echo " ${DESTDIR}/etc. In the vast majority of cases these files"
449 echo ' are necessary parts of the system and should not be deleted.'
450 echo ' However because these files are not updated by this process you'
451 echo ' might want to verify their status before rebooting your system.'
452 echo ''
453 echo ' *** Press [Enter] or [Return] key to continue'
454 read ANY_KEY
455 unset ANY_KEY
456 diff -qr ${DESTDIR}/etc ${TEMPROOT}/etc | grep "^Only in /etc" | ${PAGER}
457 echo ''
458 echo ' *** Press [Enter] or [Return] key to continue'
459 read ANY_KEY
460 unset ANY_KEY
461 ;;
462 esac
463
464 # We really don't want to have to deal with these files, since
465 # master.passwd is the real file that should be compared, then
466 # the user should run pwd_mkdb if necessary.
467 #
468 rm ${TEMPROOT}/etc/spwd.db ${TEMPROOT}/etc/passwd ${TEMPROOT}/etc/pwd.db
469
470 # Avoid comparing the motd if the user specifies it in .mergemasterrc
471 case "${IGNORE_MOTD}" in
472 '') ;;
473 *) rm ${TEMPROOT}/etc/motd
474 ;;

--- 4 unchanged lines hidden (view full) ---

479 rm ${TEMPROOT}/dev/MAKEDEV ${TEMPROOT}/dev/MAKEDEV.local
480 fi
481
482 ;; # End of the "RERUN" test
483esac
484
485# Get ready to start comparing files
486
487# Check umask if not specified on the command line,
488# and we are not doing an autorun
489#
490if [ -z "${NEW_UMASK}" -a -z "${AUTO_RUN}" ]; then
491 USER_UMASK=`umask`
492 case "${USER_UMASK}" in
493 0022) ;;
494 *)

--- 14 unchanged lines hidden (view full) ---

509 NEW_UMASK="${NEW_UMASK:-$USER_UMASK}"
510 ;;
511 esac
512 echo ''
513fi
514
515CONFIRMED_UMASK=${NEW_UMASK:-0022}
516
517# Warn users who still have ${DESTDIR}/etc/sysconfig
518#
519if [ -e "${DESTDIR}/etc/sysconfig" ]; then
520 echo ''
521 echo " *** There is a sysconfig file on this system in ${DESTDIR}/etc/."
522 echo ''
523 echo ' Starting with FreeBSD version 2.2.2 those settings moved from'
524 echo ' /etc/sysconfig to /etc/rc.conf. If you are upgrading an older'
525 echo ' system make sure that you transfer your settings by hand from'
526 echo ' sysconfig to rc.conf and install the rc.conf file. If you'
527 echo ' have already made this transition, you should consider'
528 echo ' renaming or deleting the sysconfig file.'
529 echo ''
530 case "${AUTO_RUN}" in
531 '')
532 echo -n "Continue with the merge process? [yes] "
533 read CONT_OR_NOT
534
535 case "${CONT_OR_NOT}" in
536 [nN]*)
537 exit 0
538 ;;
539 *)
540 echo " *** Continuing"
541 echo ''
542 ;;
543 esac
544 ;;
545 *) ;;
546 esac
547fi
548
549# Use the umask/mode information to install the files
550# Create directories as needed
551#
552mm_install () {
553 local INSTALL_DIR
554 INSTALL_DIR=${1#.}
555 INSTALL_DIR=${INSTALL_DIR%/*}
556
557 case "${INSTALL_DIR}" in
558 '')
559 INSTALL_DIR=/
560 ;;
561 esac
562
563 if [ -n "${DESTDIR}${INSTALL_DIR}" -a ! -d "${DESTDIR}${INSTALL_DIR}" ]; then
564 DIR_MODE=`perl -e 'printf "%04o\n", (((stat("$ARGV[0]"))[2] & 07777) &~ oct("$ARGV[1]"))' "${TEMPROOT}/${INSTALL_DIR}" "${CONFIRMED_UMASK}"`
565 install -d -o root -g wheel -m "${DIR_MODE}" "${DESTDIR}${INSTALL_DIR}"
566 fi
567
568 FILE_MODE=`perl -e 'printf "%04o\n", (((stat("$ARGV[0]"))[2] & 07777) &~ oct("$ARGV[1]"))' "${1}" "${CONFIRMED_UMASK}"`
569
570 if [ ! -x "${1}" ]; then
571 case "${1#.}" in
572 /etc/mail/aliases)
573 NEED_NEWALIASES=yes
574 ;;
575 /etc/login.conf)
576 NEED_CAP_MKDB=yes
577 ;;
578 /etc/master.passwd)
579 install -m 600 "${1}" "${DESTDIR}${INSTALL_DIR}"
580 NEED_PWD_MKDB=yes
581 DONT_INSTALL=yes
582 ;;
583 /.cshrc | /.profile)
584 case "${LINK_EXPLAINED}" in
585 '')
586 echo " *** Historically BSD derived systems have had a"
587 echo " hard link from /.cshrc and /.profile to"
588 echo " their namesakes in /root. Please indicate"
589 echo " your preference below for bringing your"
590 echo " installed files up to date."
591 echo ''
592 LINK_EXPLAINED=yes
593 ;;
594 esac
595
596 echo " Use 'd' to delete the temporary ${COMPFILE}"
597 echo " Use 'l' to delete the existing ${DESTDIR}${COMPFILE#.} and create the link"
598 echo ''
599 echo " Default is to leave the temporary file to deal with by hand"
600 echo ''
601 echo -n " How should I handle ${COMPFILE}? [Leave it to install later] "
602 read HANDLE_LINK
603
604 case "${HANDLE_LINK}" in
605 [dD]*)
606 rm "${COMPFILE}"
607 echo ''
608 echo " *** Deleting ${COMPFILE}"
609 ;;
610 [lL]*)
611 echo ''
612 rm -f "${DESTDIR}${COMPFILE#.}"
613 if ln "${DESTDIR}/root/${COMPFILE##*/}" "${DESTDIR}${COMPFILE#.}"; then
614 echo " *** Link from ${DESTDIR}${COMPFILE#.} to ${DESTDIR}/root/${COMPFILE##*/} installed successfully"
615 rm "${COMPFILE}"
616 else
617 echo " *** Error linking ${DESTDIR}${COMPFILE#.} to ${DESTDIR}/root/${COMPFILE##*/}, ${COMPFILE} will remain to install by hand"
618 fi
619 ;;
620 *)
621 echo " *** ${COMPFILE} will remain for your consideration"
622 ;;
623 esac
624 DONT_INSTALL=yes
625 ;;
626 esac
627
628 case "${DONT_INSTALL}" in
629 '')
630 install -m "${FILE_MODE}" "${1}" "${DESTDIR}${INSTALL_DIR}"
631 ;;
632 *)
633 unset DONT_INSTALL
634 ;;
635 esac
636 else
637 case "${1#.}" in
638 /dev/MAKEDEV)
639 NEED_MAKEDEV=yes
640 ;;
641 esac
642 install -m "${FILE_MODE}" "${1}" "${DESTDIR}${INSTALL_DIR}"
643 fi
644 return $?
645}
646
647echo ''
648echo "*** Beginning comparison"
649echo ''
650
651cd "${TEMPROOT}"
652
653if [ -r "${MM_PRE_COMPARE_SCRIPT}" ]; then
654 . "${MM_PRE_COMPARE_SCRIPT}"
655fi
656
657# Using -size +0 avoids uselessly checking the empty log files created
658# by ${SOURCEDIR}/Makefile and the device entries in ./dev, but does
659# check the scripts in ./dev, as we'd like (assuming no devfs of course).
660#
661for COMPFILE in `find . -type f -size +0`; do
662
663 # First, check to see if the file exists in DESTDIR. If not, the
664 # diff_loop function knows how to handle it.
665 #
666 if [ ! -e "${DESTDIR}${COMPFILE#.}" ]; then
667 diff_loop
668 continue
669 fi
670
671 case "${STRICT}" in
672 '' | [Nn][Oo])
673 # Compare CVS $Id's first so if the file hasn't been modified
674 # local changes will be ignored.
675 # If the files have the same $Id, delete the one in temproot so the
676 # user will have less to wade through if files are left to merge by hand.
677 #
678 # Reduce complexity and improve portability by using ident
679 #
680 CVSID1=`ident ${DESTDIR}${COMPFILE#.} 2>&1`
681 CVSID1="${CVSID1#${DESTDIR}}"
682 CVSID2=`ident ${COMPFILE} 2>&1`
683
684 case "${CVSID2}" in
685 *'no id keywords'*)
686 ;;
687 ."${CVSID1}")
688 echo " *** Temp ${COMPFILE} and installed have the same CVS Id, deleting"
689 rm "${COMPFILE}"
690 ;;
691 esac
692 ;;
693 esac
694
695 # If the file is still here either because the $Ids are different, the
696 # file doesn't have an $Id, or we're using STRICT mode; look at the diff.
697 #
698 if [ -f "${COMPFILE}" ]; then
699
700 # Do an absolute diff first to see if the files are actually different.
701 # If they're not different, delete the one in temproot.
702 #
703 if diff -q "${DESTDIR}${COMPFILE#.}" "${COMPFILE}" > /dev/null 2>&1; then
704 echo " *** Temp ${COMPFILE} and installed are the same, deleting"
705 rm "${COMPFILE}"
706 else
707 # Ok, the files are different, so show the user where they differ. Use user's
708 # choice of diff methods; and user's pager if they have one. Use more if not.
709 # Use unified diffs by default. Context diffs give me a headache. :)
710 #
711 case "${AUTO_RUN}" in

--- 73 unchanged lines hidden (view full) ---

785'') ;;
786*)
787 echo ''
788 echo "*** You installed a new master.passwd file, so make sure that you run"
789 echo " 'pwd_mkdb -p /etc/master.passwd' to rebuild your password files"
790 ;;
791esac
792
793case "${AUTO_INSTALLED_FILES}" in
794'') ;;
795*)
796 (
797 echo ''
798 echo '*** You chose the automatic install option for files that did not exist'
799 echo ' on your system. The following files were installed for you:'
800 echo "${AUTO_INSTALLED_FILES}"
801 ) | ${PAGER}
802 ;;
803esac
804
805echo ''
806
807if [ -r "${MM_EXIT_SCRIPT}" ]; then
808 . "${MM_EXIT_SCRIPT}"
809fi
810
811exit 0
812