Date: Sun, 14 Jul 2002 01:15:58 +0200 (CEST) From: Cyrille Lefevre <cyrille.lefevre@laposte.net> To: FreeBSD-gnats-submit@FreeBSD.org Cc: Doug Barton <DougB@FreeBSD.org> Subject: bin/40538: mergemaster fixes and enhancements Message-ID: <200207132315.g6DNFwtc055327@gits.gits.dyndns.org>
next in thread | raw e-mail | index | archive | help
>Number: 40538 >Category: bin >Synopsis: mergemaster fixes and enhancements >Confidential: no >Severity: critical >Priority: high >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Sat Jul 13 16:20:01 PDT 2002 >Closed-Date: >Last-Modified: >Originator: Cyrille Lefevre >Release: FreeBSD 4.6-STABLE i386 >Organization: ACME >Environment: System: FreeBSD gits 4.6-STABLE FreeBSD 4.6-STABLE #16: Sat Jul 6 19:06:54 CEST 2002 root@gits:/disk2/freebsd/stable/src/sys/compile/CUSTOM i386 >Description: the major fix concern the `cd ${TEMPROOT}' (at line 752) w/o check which may move every files under ${PWD} to ${DESTDIR} when used in conjunction w/ -riv w/o an existing ${TEMPROOT}. other fixes are : * locally used variables are now initialized to avoid conflicts w/ existsing shell exported variable. * ${} -> "${}" tidy up some things : * $XXX -> ${XXX} * `...` -> $(...) * [ ... = "constant" ] -> [ ... = constant ] * almost long `echo' lines have been wrapped. the enhancements are : * MM_EXIT_SCRIPT has been moved before the ${TEMPROOT} deletion so it is now possible to set AUTO_RUN=yes in it to automagically delete ${TEMPROOT} and to automagically rebuild ${NEED_...} databases when used in conjunction w/ -riv. * -p and -C output changed a lot to look more like to a diff output. also, now compare commented variables. to make them (or the one undocummented) invisible, prefix them w/ a space. * -C can now handle included make.conf files through MAKE_CONF_FILES which is defaulted to /etc/make.conf. the man has been updated as well. >How-To-Repeat: mkdir /var/tmp/mm cd /var/tmp/mm mkdir nothing touch nothing/important rm -rf /var/tmp/temproot chflags -R 0 /var/tmp/temproot rm -rf /var/tmp/temproot mergemaster -riv ls -ltr / | tail -1 >Fix: Index: mergemaster.8 =================================================================== RCS file: /home/ncvs/src/usr.sbin/mergemaster/mergemaster.8,v retrieving revision 1.5.2.10 diff -u -r1.5.2.10 mergemaster.8 --- mergemaster.8 28 May 2002 07:30:20 -0000 1.5.2.10 +++ mergemaster.8 13 Jul 2002 21:21:32 -0000 @@ -292,13 +292,13 @@ # The following options have command line overrides # # Directory to install the temporary root environment into -#TEMPROOT='/var/tmp/temproot' +#TEMPROOT=/var/tmp/temproot # # Strict comparison bypasses the CVS $Id tests and compares every file #STRICT=no # # Flag(s) to use for diff displayed when files differ -#DIFF_FLAG='-u' +#DIFF_FLAG=-u # # Verbose mode includes more details and additional checks #VERBOSE= @@ -310,7 +310,7 @@ #COMP_CONFS=yes # # Sourcedir is the directory to do the 'make' in (where the new files are) -#SOURCEDIR='/usr/src/etc' +#SOURCEDIR=/usr/src/etc # # The umask for mergemaster to compare the default file's modes to #NEW_UMASK=022 @@ -327,6 +327,9 @@ # # Don't compare the old and new motd files #IGNORE_MOTD=yes +# +# List of makefiles to check for variables in pre-world (-p) +# MAKE_CONF_FILES=/etc/make.conf # # Specify the path to scripts to run before the comparison starts, # and/or after the script has finished its work Index: mergemaster.sh =================================================================== RCS file: /home/ncvs/src/usr.sbin/mergemaster/mergemaster.sh,v retrieving revision 1.6.2.14 diff -u -r1.6.2.14 mergemaster.sh --- mergemaster.sh 30 Jun 2002 19:01:35 -0000 1.6.2.14 +++ mergemaster.sh 13 Jul 2002 22:49:38 -0000 @@ -13,7 +13,7 @@ PATH=/bin:/usr/bin:/usr/sbin display_usage () { - VERSION_NUMBER=`grep "[$]FreeBSD:" $0 | cut -d ' ' -f 4` + VERSION_NUMBER=$(grep "[$]FreeBSD:" "$0" | cut -d ' ' -f 4) echo "mergemaster version ${VERSION_NUMBER}" echo 'Usage: mergemaster [-scrvahipC] [-m /path]' echo ' [-t /path] [-d] [-u N] [-w N] [-D /path]' @@ -29,7 +29,7 @@ echo ' -C Compare local rc.conf variables to the defaults' echo " -m /path/directory Specify location of source to do the make in" echo " -t /path/directory Specify temp root directory" - echo " -d Add date and time to directory name (e.g., /var/tmp/temproot.`date +%m%d.%H.%M`)" + echo " -d Add date and time to directory name (e.g., /var/tmp/temproot.$(date +%m%d.%H.%M))" echo " -u N Specify a numeric umask" echo " -w N Specify a screen width in columns to sdiff" echo ' -D /path/directory Specify the destination directory to install files to' @@ -55,20 +55,21 @@ esac echo '' MERGE_AGAIN=yes - while [ "${MERGE_AGAIN}" = "yes" ]; do + while [ "${MERGE_AGAIN}" = yes ]; do # Prime file.merged so we don't blat the owner/group id's cp -p "${COMPFILE}" "${COMPFILE}.merged" sdiff -o "${COMPFILE}.merged" --text --suppress-common-lines \ --width=${SCREEN_WIDTH:-80} "${DESTDIR}${COMPFILE#.}" "${COMPFILE}" INSTALL_MERGED=V - while [ "${INSTALL_MERGED}" = "v" -o "${INSTALL_MERGED}" = "V" ]; do + while [ "${INSTALL_MERGED}" = v -o "${INSTALL_MERGED}" = V ]; do echo '' echo " Use 'i' to install merged file" echo " Use 'r' to re-do the merge" echo " Use 'v' to view the merged file" echo " Default is to leave the temporary file to deal with by hand" echo '' - echo -n " *** How should I deal with the merged file? [Leave it for later] " + echo -n " *** How should I deal with the merged file?" \ + "[Leave it for later] " read INSTALL_MERGED case "${INSTALL_MERGED}" in @@ -78,7 +79,8 @@ if mm_install "${COMPFILE}"; then echo " *** Merged version of ${COMPFILE} installed successfully" else - echo " *** Problem installing ${COMPFILE}, it will remain to merge by hand later" + echo " *** Problem installing ${COMPFILE}," \ + "it will remain to merge by hand later" fi unset MERGE_AGAIN ;; @@ -107,16 +109,17 @@ HANDLE_COMPFILE=v - while [ "${HANDLE_COMPFILE}" = "v" -o "${HANDLE_COMPFILE}" = "V" -o \ + while [ "${HANDLE_COMPFILE}" = v -o "${HANDLE_COMPFILE}" = V -o \ "${HANDLE_COMPFILE}" = "NOT V" ]; do if [ -f "${DESTDIR}${COMPFILE#.}" -a -f "${COMPFILE}" ]; then - if [ "${HANDLE_COMPFILE}" = "v" -o "${HANDLE_COMPFILE}" = "V" ]; then + if [ "${HANDLE_COMPFILE}" = v -o "${HANDLE_COMPFILE}" = V ]; then echo '' echo ' ====================================================================== ' echo '' ( echo '' - echo " *** Displaying differences between ${COMPFILE} and installed version:" + echo " *** Displaying differences between ${COMPFILE}" \ + "and installed version:" echo '' diff "${DIFF_FLAG}" "${DESTDIR}${COMPFILE#.}" "${COMPFILE}" ) | ${PAGER} @@ -136,7 +139,8 @@ AUTO_INSTALLED_FILES="${AUTO_INSTALLED_FILES} ${DESTDIR}${COMPFILE#.} " else - echo " *** Problem installing ${COMPFILE}, it will remain to merge by hand" + echo " *** Problem installing ${COMPFILE}," \ + "it will remain to merge by hand" fi return ;; @@ -171,7 +175,8 @@ if mm_install "${COMPFILE}"; then echo " *** ${COMPFILE} installed successfully" else - echo " *** Problem installing ${COMPFILE}, it will remain to merge by hand" + echo " *** Problem installing ${COMPFILE}," \ + "it will remain to merge by hand" fi ;; [mM]) @@ -220,11 +225,14 @@ read DISCARD } -# Set the default path for the temporary root environment +# Initialize locally used variables # -TEMPROOT='/var/tmp/temproot' +STRICT= DIFF_FLAG= RERUN= VERBOSE= AUTO_RUN= AUTO_INSTALL= +COMP_CONFS= PRE_WORLD= SOURCEDIR= TEMPROOT= NEW_UMASK= +SCREEN_WIDTH= DESTDIR= DONT_CHECK_PAGER= IGNORE_MOTD= +MM_PRE_COMPARE_SCRIPT= MM_EXIT_SCRIPT= MAKE_CONF_FILES= -# Read /etc/mergemaster.rc first so the one in $HOME can override +# Read /etc/mergemaster.rc first so the one in ${HOME} can override # if [ -r /etc/mergemaster.rc ]; then . /etc/mergemaster.rc @@ -232,8 +240,8 @@ # Read .mergemasterrc before command line so CLI can override # -if [ -r "$HOME/.mergemasterrc" ]; then - . "$HOME/.mergemasterrc" +if [ -r "${HOME}/.mergemasterrc" ]; then + . "${HOME}/.mergemasterrc" fi # Check the command line options @@ -281,7 +289,7 @@ TEMPROOT=${OPTARG} ;; d) - TEMPROOT=${TEMPROOT}.`date +%m%d.%H.%M` + TEMPROOT=${TEMPROOT}.$(date +%m%d.%H.%M) ;; u) NEW_UMASK=${OPTARG} @@ -355,7 +363,7 @@ # PAGER=${PAGER:-more} -if [ -n "${VERBOSE}" -a ! "${PAGER}" = "more" ]; then +if [ -n "${VERBOSE}" -a ! "${PAGER}" = more ]; then echo " *** You have ${PAGER} defined as your pager so we will use that" echo '' sleep 3 @@ -369,6 +377,14 @@ # SOURCEDIR=${SOURCEDIR:-/usr/src/etc} +# Assign the temporary root environment +# +TEMPROOT=${TEMPROOT:-/var/tmp/temproot} + +# Assign the default list of make configuration files +# +MAKE_CONF_FILES=${MAKE_CONF_FILES:=/etc/make.conf} + # Check the width of the user's terminal # if [ -t 0 ]; then @@ -398,7 +414,7 @@ CVS_ID_TAG=FreeBSD delete_temproot () { - rm -rf "${TEMPROOT}" + rm -rf "${TEMPROOT}" 2> /dev/null chflags -R 0 "${TEMPROOT}" rm -rf "${TEMPROOT}" } @@ -409,7 +425,7 @@ # temp root directory. # TEST_TEMP_ROOT=yes - while [ "${TEST_TEMP_ROOT}" = "yes" ]; do + while [ "${TEST_TEMP_ROOT}" = yes ]; do if [ -d "${TEMPROOT}" ]; then echo "*** The directory specified for the temporary root environment," echo " ${TEMPROOT}, exists. This can be a security risk if untrusted" @@ -457,7 +473,7 @@ *) # If this is an auto-run, try a hopefully safe alternative then # re-test anyway. - TEMPROOT=/var/tmp/temproot.`date +%m%d.%H.%M.%S` + TEMPROOT=/var/tmp/temproot.$(date +%m%d.%H.%M.%S) ;; esac else @@ -490,16 +506,16 @@ case "${PRE_WORLD}" in '') - { cd ${SOURCEDIR} && + { cd "${SOURCEDIR}" && case "${DESTDIR}" in '') ;; *) - make DESTDIR=${DESTDIR} distrib-dirs + make DESTDIR="${DESTDIR}" distrib-dirs ;; esac - make DESTDIR=${TEMPROOT} distrib-dirs && - make MAKEOBJDIRPREFIX=${TEMPROOT}/usr/obj obj && - make MAKEOBJDIRPREFIX=${TEMPROOT}/usr/obj DESTDIR=${TEMPROOT} \ + make DESTDIR="${TEMPROOT}" distrib-dirs && + make MAKEOBJDIRPREFIX="${TEMPROOT}/usr/obj" obj && + make MAKEOBJDIRPREFIX="${TEMPROOT}/usr/obj" DESTDIR="${TEMPROOT}" \ -DNO_MAKEDEV_RUN distribution;} || { echo ''; echo " *** FATAL ERROR: Cannot 'cd' to ${SOURCEDIR} and install files to"; @@ -509,9 +525,9 @@ ;; *) # Only set up files that are crucial to {build|install}world - { mkdir -p ${TEMPROOT}/etc && - cp -p ${SOURCEDIR}/master.passwd ${TEMPROOT}/etc && - cp -p ${SOURCEDIR}/group ${TEMPROOT}/etc;} || + { mkdir -p "${TEMPROOT}/etc" && + cp -p "${SOURCEDIR}/master.passwd" "${TEMPROOT}/etc" && + cp -p "${SOURCEDIR}/group" "${TEMPROOT}/etc";} || { echo ''; echo ' *** FATAL ERROR: Cannot copy files to the temproot environment'; echo ''; @@ -533,7 +549,8 @@ echo ' might want to verify their status before rebooting your system.' echo '' press_to_continue - diff -qr ${DESTDIR}/etc ${TEMPROOT}/etc | grep "^Only in /etc" | ${PAGER} + diff -qr "${DESTDIR}/etc" "${TEMPROOT}/etc" | + grep "^Only in ${DESTDIR}/etc" | ${PAGER} echo '' press_to_continue ;; @@ -542,7 +559,7 @@ # Avoid comparing the motd if the user specifies it in .mergemasterrc case "${IGNORE_MOTD}" in '') ;; - *) rm -f ${TEMPROOT}/etc/motd + *) rm -f "${TEMPROOT}/etc/motd" ;; esac @@ -553,10 +570,10 @@ # master.passwd is the real file that should be compared, then # the user should run pwd_mkdb if necessary. # -rm -f ${TEMPROOT}/etc/spwd.db ${TEMPROOT}/etc/passwd ${TEMPROOT}/etc/pwd.db +rm -f "${TEMPROOT}/etc/spwd.db" "${TEMPROOT}/etc/passwd" "${TEMPROOT}/etc/pwd.db" # We only need to compare things like freebsd.cf once -find ${TEMPROOT}/usr/obj -type f -delete 2>/dev/null +find "${TEMPROOT}/usr/obj" -type f -delete 2>/dev/null # Get ready to start comparing files @@ -564,12 +581,13 @@ # and we are not doing an autorun # if [ -z "${NEW_UMASK}" -a -z "${AUTO_RUN}" ]; then - USER_UMASK=`umask` + USER_UMASK=$(umask) case "${USER_UMASK}" in 0022|022) ;; *) echo '' - echo " *** Your umask is currently set to ${USER_UMASK}. By default, this script" + echo " *** Your umask is currently set to ${USER_UMASK}." \ + "By default, this script" echo " installs all files with the same user, group and modes that" echo " they are created with by ${SOURCEDIR}/Makefile, compared to" echo " a umask of 022. This umask allows world read permission when" @@ -583,7 +601,7 @@ echo -n "What umask should I use? [${USER_UMASK}] " read NEW_UMASK - NEW_UMASK="${NEW_UMASK:-$USER_UMASK}" + NEW_UMASK="${NEW_UMASK:-${USER_UMASK}}" ;; esac echo '' @@ -643,13 +661,13 @@ esac if [ -n "${DESTDIR}${INSTALL_DIR}" -a ! -d "${DESTDIR}${INSTALL_DIR}" ]; then - DIR_MODE=`perl -e 'printf "%04o\n", (((stat("$ARGV[0]"))[2] & 07777) &~ \ - oct("$ARGV[1]"))' "${TEMPROOT}/${INSTALL_DIR}" "${CONFIRMED_UMASK}"` + DIR_MODE=$(perl -e 'printf "%04o\n", (((stat("$ARGV[0]"))[2] & 07777) &~ \ + oct("$ARGV[1]"))' "${TEMPROOT}/${INSTALL_DIR}" "${CONFIRMED_UMASK}") install -d -o root -g wheel -m "${DIR_MODE}" "${DESTDIR}${INSTALL_DIR}" fi - FILE_MODE=`perl -e 'printf "%04o\n", (((stat("$ARGV[0]"))[2] & 07777) &~ \ - oct("$ARGV[1]"))' "${1}" "${CONFIRMED_UMASK}"` + FILE_MODE=$(perl -e 'printf "%04o\n", (((stat("$ARGV[0]"))[2] & 07777) &~ \ + oct("$ARGV[1]"))' "${1}" "${CONFIRMED_UMASK}") if [ ! -x "${1}" ]; then case "${1#.}" in @@ -680,7 +698,8 @@ esac echo " Use 'd' to delete the temporary ${COMPFILE}" - echo " Use 'l' to delete the existing ${DESTDIR}${COMPFILE#.} and create the link" + echo " Use 'l' to delete the existing ${DESTDIR}${COMPFILE#.}" \ + "and create the link" echo '' echo " Default is to leave the temporary file to deal with by hand" echo '' @@ -702,10 +721,13 @@ echo '' rm -f "${DESTDIR}${COMPFILE#.}" if ln "${DESTDIR}/root/${COMPFILE##*/}" "${DESTDIR}${COMPFILE#.}"; then - echo " *** Link from ${DESTDIR}${COMPFILE#.} to ${DESTDIR}/root/${COMPFILE##*/} installed successfully" + echo " *** Link from ${DESTDIR}${COMPFILE#.}" \ + "to ${DESTDIR}/root/${COMPFILE##*/} installed successfully" rm "${COMPFILE}" else - echo " *** Error linking ${DESTDIR}${COMPFILE#.} to ${DESTDIR}/root/${COMPFILE##*/}, ${COMPFILE} will remain to install by hand" + echo " *** Error linking ${DESTDIR}${COMPFILE#.}" \ + "to ${DESTDIR}/root/${COMPFILE##*/}, ${COMPFILE}" \ + "will remain to install by hand" fi ;; *) @@ -739,7 +761,7 @@ echo "*** Beginning comparison" echo '' -cd "${TEMPROOT}" +cd "${TEMPROOT}" || exit if [ -r "${MM_PRE_COMPARE_SCRIPT}" ]; then . "${MM_PRE_COMPARE_SCRIPT}" @@ -749,7 +771,7 @@ # by ${SOURCEDIR}/Makefile and the device entries in ./dev, but does # check the scripts in ./dev, as we'd like (assuming no devfs of course). # -for COMPFILE in `find . -type f -size +0`; do +for COMPFILE in $(find . -type f -size +0); do # First, check to see if the file exists in DESTDIR. If not, the # diff_loop function knows how to handle it. @@ -781,8 +803,8 @@ # If the files have the same $Id, delete the one in temproot so the # user will have less to wade through if files are left to merge by hand. # - CVSID1=`grep "[$]${CVS_ID_TAG}:" ${DESTDIR}${COMPFILE#.} 2>/dev/null` - CVSID2=`grep "[$]${CVS_ID_TAG}:" ${COMPFILE} 2>/dev/null` || CVSID2=none + CVSID1=$(grep "[$]${CVS_ID_TAG}:" "${DESTDIR}${COMPFILE#.}" 2>/dev/null) + CVSID2=$(grep "[$]${CVS_ID_TAG}:" "${COMPFILE}" 2>/dev/null) || CVSID2=none case "${CVSID2}" in "${CVSID1}") @@ -828,13 +850,17 @@ echo "*** Comparison complete" echo '' -TEST_FOR_FILES=`find ${TEMPROOT} -type f -size +0 2>/dev/null` +TEST_FOR_FILES=$(find "${TEMPROOT}" -type f -size +0 2>/dev/null) if [ -n "${TEST_FOR_FILES}" ]; then echo "*** Files that remain for you to merge by hand:" find "${TEMPROOT}" -type f -size +0 echo '' fi +if [ -r "${MM_EXIT_SCRIPT}" ]; then + . "${MM_EXIT_SCRIPT}" +fi + case "${AUTO_RUN}" in '') echo -n "Do you wish to delete what is left of ${TEMPROOT}? [no] " @@ -913,7 +939,8 @@ '') ;; *) echo '' - echo "*** You installed a new ${DESTDIR}/dev/MAKEDEV script, so make sure that you run" + echo "*** You installed a new ${DESTDIR}/dev/MAKEDEV script," \ + "so make sure that you run" echo " 'cd ${DESTDIR}/dev && /bin/sh MAKEDEV all' to rebuild your devices" run_it_now "cd ${DESTDIR}/dev && /bin/sh MAKEDEV all" ;; @@ -966,14 +993,11 @@ echo '' -if [ -r "${MM_EXIT_SCRIPT}" ]; then - . "${MM_EXIT_SCRIPT}" -fi - case "${COMP_CONFS}" in '') ;; *) - . ${DESTDIR}/etc/defaults/rc.conf + RC_CONF="${DESTDIR}/etc/defaults/rc.conf" + . "${DESTDIR}${RC_CONF}" (echo '' echo "*** Comparing conf files: ${rc_conf_files}" @@ -981,15 +1005,16 @@ for CONF_FILE in ${rc_conf_files}; do if [ -r "${DESTDIR}${CONF_FILE}" ]; then echo '' + echo "*** From ${DESTDIR}${RC_CONF}" echo "*** From ${DESTDIR}${CONF_FILE}" - echo "*** From ${DESTDIR}/etc/defaults/rc.conf" - for RC_CONF_VAR in `grep -i ^[a-z] ${DESTDIR}${CONF_FILE} | - cut -d '=' -f 1`; do + for RC_CONF_VAR in $(awk -F = '/^#?[A-Za-z]/{sub("^#","");print $1}' \ + "${DESTDIR}${CONF_FILE}"); do echo '' - grep -w ^${RC_CONF_VAR} ${DESTDIR}${CONF_FILE} - grep -w ^${RC_CONF_VAR} ${DESTDIR}/etc/defaults/rc.conf || - echo ' * No default variable with this name' + egrep -w "^#?${RC_CONF_VAR}" "${DESTDIR}${RC_CONF}" | sed 's/^/< /' + egrep -qw "^#?${RC_CONF_VAR}" "${DESTDIR}${RC_CONF}" || + echo '* No default variable with this name' + egrep -w "^#?${RC_CONF_VAR}" "${DESTDIR}${CONF_FILE}" | sed 's/^/> /' done fi done) | ${PAGER} @@ -1003,16 +1028,23 @@ MAKE_CONF="${SOURCEDIR}/defaults/make.conf" (echo '' - echo '*** Comparing make variables' - echo '' - echo "*** From ${DESTDIR}/etc/make.conf" - echo "*** From ${MAKE_CONF}" + echo "*** Comparing make files: ${MAKE_CONF_FILES}" - for MAKE_VAR in `grep -i ^[a-z] /etc/make.conf | cut -d '=' -f 1`; do - echo '' - grep -w ^${MAKE_VAR} ${DESTDIR}/etc/make.conf - grep -w ^#${MAKE_VAR} ${MAKE_CONF} || - echo ' * No example variable with this name' + for MAKE_FILE in ${MAKE_CONF_FILES}; do + if [ -r "${DESTDIR}${MAKE_FILE}" ]; then + echo '' + echo "*** From ${MAKE_CONF}" + echo "*** From ${DESTDIR}${MAKE_FILE}" + + for MAKE_VAR in $(awk -F '[?+=]' '/^#?[A-Za-z]/{sub("^#","");print $1}' \ + "${DESTDIR}${MAKE_FILE}"); do + echo '' + egrep -w "^#?${MAKE_VAR}" "${MAKE_CONF}" | sed 's/^/< /' + egrep -qw "^#?${MAKE_VAR}" "${MAKE_CONF}" || + echo '* No example variable with this name' + egrep -w "^#?${MAKE_VAR}" "${DESTDIR}${MAKE_FILE}" | sed 's/^/> /' + done + fi done) | ${PAGER} ;; esac >Release-Note: >Audit-Trail: >Unformatted: To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-bugs" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200207132315.g6DNFwtc055327>