1#!/bin/sh - 2# 3# $OpenBSD: sysmerge.sh,v 1.39 2009/04/28 08:25:27 ajacoutot Exp $ 4# 5# This script is based on the FreeBSD mergemaster script, written by 6# Douglas Barton <DougB@FreeBSD.org> 7# 8# Some ideas came from the NetBSD etcupdate script, written by 9# Martti Kuparinen <martti@NetBSD.org> 10# 11# Copyright (c) 1998-2003 Douglas Barton <DougB@FreeBSD.org> 12# Copyright (c) 2008, 2009 Antoine Jacoutot <ajacoutot@openbsd.org> 13# 14# Permission to use, copy, modify, and distribute this software for any 15# purpose with or without fee is hereby granted, provided that the above 16# copyright notice and this permission notice appear in all copies. 17# 18# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 19# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 20# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 21# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 22# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 23# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 24# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 25# 26 27umask 0022 28 29WRKDIR=`mktemp -d -p /var/tmp sysmerge.XXXXX` || exit 1 30SWIDTH=`stty size | awk '{w=$2} END {if (w==0) {w=80} print w}'` 31MERGE_CMD="${MERGE_CMD:=sdiff -as -w ${SWIDTH} -o}" 32REPORT="${REPORT:=${WRKDIR}/sysmerge.log}" 33 34EDITOR="${EDITOR:=/usr/bin/vi}" 35PAGER="${PAGER:=/usr/bin/more}" 36 37# clean leftovers created by make in src 38clean_src() { 39 if [ "${SRCDIR}" ]; then 40 cd ${SRCDIR}/gnu/usr.sbin/sendmail/cf/cf && make cleandir > /dev/null 41 fi 42} 43 44# remove newly created work directory and exit with status 1 45error_rm_wrkdir() { 46 rmdir ${WRKDIR} 2> /dev/null 47 exit 1 48} 49 50usage() { 51 echo "usage: ${0##*/} [-ab] [-S etcXX.tgz] [-s src | etcXX.tgz] [-X xetcXX.tgz] [-x xetcXX.tgz]" >&2 52} 53 54trap "clean_src; rm -rf ${WRKDIR}; exit 1" 1 2 3 13 15 55 56if [ "`id -u`" -ne 0 ]; then 57 echo " *** Error: need root privileges to run this script" 58 usage 59 error_rm_wrkdir 60fi 61 62if [ -z "${FETCH_CMD}" ]; then 63 if [ -z "${FTP_KEEPALIVE}" ]; then 64 FTP_KEEPALIVE=0 65 fi 66 FETCH_CMD="/usr/bin/ftp -V -m -k ${FTP_KEEPALIVE}" 67fi 68 69 70do_pre() { 71 if [ -z "${SRCDIR}" -a -z "${TGZ}" -a -z "${XTGZ}" ]; then 72 if [ -f "/usr/src/etc/Makefile" ]; then 73 SRCDIR=/usr/src 74 else 75 echo " *** Error: please specify a valid path to src or (x)etcXX.tgz" 76 error_rm_wrkdir 77 fi 78 fi 79 80 if [ "${OTGZ}" ]; then 81 TGZV=`echo ${TGZ} | sed -e 's,^.*/,,' -e 's,etc,,' -e 's,.tgz,,'` 82 OTGZV=`echo ${OTGZ} | sed -e 's,^.*/,,' -e 's,etc,,' -e 's,.tgz,,'` 83 if [ -z "${TGZ}" ]; then 84 echo " *** Error: please specify a valid path to the new etcXX.tgz" 85 error_rm_wrkdir 86 elif cmp -s ${OTGZ} ${TGZ}; then 87 echo " *** Error: old and new etcXX.tgz are identical" 88 error_rm_wrkdir 89 elif [ "${OTGZV}" -gt "${TGZV}" ]; then 90 echo " *** Error: old etc${OTGZV}.tgz version is higher than new etc${TGZV}.tgz" 91 error_rm_wrkdir 92 fi 93 fi 94 95 if [ "${OXTGZ}" ]; then 96 XTGZV=`echo ${XTGZ} | sed -e 's,^.*/,,' -e 's,etc,,' -e 's,.tgz,,'` 97 OXTGZV=`echo ${OXTGZ} | sed -e 's,^.*/,,' -e 's,etc,,' -e 's,.tgz,,'` 98 if [ -z "${XTGZ}" ]; then 99 echo " *** Error: please specify a valid path to the new xetcXX.tgz" 100 error_rm_wrkdir 101 elif cmp -s ${OXTGZ} ${XTGZ}; then 102 echo " *** Error: old and new xetcXX.tgz are identical" 103 error_rm_wrkdir 104 elif [ "${OXTGZV}" -gt "${XTGZV}" ]; then 105 echo " *** Error: old xetc${OXTGZV}.tgz version is higher than new xetc${XTGZV}.tgz" 106 error_rm_wrkdir 107 fi 108 fi 109 110 TEMPROOT="${WRKDIR}/temproot" 111 BKPDIR="${WRKDIR}/backups" 112 113 if [ -z "${BATCHMODE}" -a -z "${AUTOMODE}" ]; then 114 echo "\n===> Running ${0##*/} with the following settings:\n" 115 if [ "${TGZURL}" ]; then 116 echo " etc source: ${TGZURL}" 117 echo " (fetched in ${TGZ})" 118 elif [ "${TGZ}" ]; then 119 echo " etc source: ${TGZ}" 120 elif [ "${SRCDIR}" ]; then 121 echo " etc source: ${SRCDIR}" 122 fi 123 if [ "${OTGZURL}" ]; then 124 echo " old etc source: ${OTGZURL}" 125 echo " (fetched in ${OTGZ})" 126 else 127 [ "${OTGZ}" ] && echo " old etc source: ${OTGZ}" 128 fi 129 if [ "${OTGZ}" -o "${OXTGZ}" ]; then echo ""; fi 130 if [ "${XTGZURL}" ]; then 131 echo " xetc source: ${XTGZURL}" 132 echo " (fetched in ${XTGZ})" 133 else 134 [ "${XTGZ}" ] && echo " xetc source: ${XTGZ}" 135 fi 136 if [ "${OXTGZURL}" ]; then 137 echo " old xetc source: ${OXTGZURL}" 138 echo " (fetched in ${OXTGZ})" 139 else 140 [ "${OXTGZ}" ] && echo " old xetc source: ${OXTGZ}" 141 fi 142 echo "" 143 echo " base work directory: ${WRKDIR}" 144 echo " temp root directory: ${TEMPROOT}" 145 echo " backup directory: ${BKPDIR}" 146 echo "" 147 echo -n "Continue? (y|[n]) " 148 read ANSWER 149 case "${ANSWER}" in 150 y|Y) 151 echo "" 152 ;; 153 *) 154 error_rm_wrkdir 155 ;; 156 esac 157 fi 158} 159 160 161do_populate() { 162 echo "===> Creating and populating temporary root under" 163 echo " ${TEMPROOT}" 164 mkdir -p ${TEMPROOT} 165 if [ "${SRCDIR}" ]; then 166 cd ${SRCDIR}/etc 167 make DESTDIR=${TEMPROOT} distribution-etc-root-var > /dev/null 2>&1 168 fi 169 170 if [ "${TGZ}" -o "${XTGZ}" ]; then 171 for i in ${TGZ} ${XTGZ}; do 172 tar -xzphf ${i} -C ${TEMPROOT}; 173 done 174 fi 175 176 if [ "${OTGZ}" -o "${OXTGZ}" ]; then 177 OTEMPROOT="${WRKDIR}/.otemproot" 178 mkdir -p ${OTEMPROOT} 179 for i in ${OTGZ} ${OXTGZ}; do 180 tar -xzphf ${i} -C ${OTEMPROOT}; 181 tar -tzf ${i} >> ${WRKDIR}/olist; 182 done 183 for i in ${TGZ} ${XTGZ}; do 184 tar -tzf ${i} >> ${WRKDIR}/nlist; 185 done 186 OBSOLETE_FILES=`diff -C 0 ${WRKDIR}/olist ${WRKDIR}/nlist | grep -E '^- .' | sed -e 's,^- .,,g'` 187 rm -f ${WRKDIR}/olist ${WRKDIR}/nlist 188 fi 189 190 # files we don't want/need to deal with 191 IGNORE_FILES="/etc/*.db /etc/mail/*.db /etc/passwd /etc/motd /etc/myname /var/mail/root" 192 CF_FILES="/etc/mail/localhost.cf /etc/mail/sendmail.cf /etc/mail/submit.cf" 193 for cf in ${CF_FILES}; do 194 CF_DIFF=`diff -q -I "##### " ${TEMPROOT}/${cf} ${DESTDIR}/${cf} 2> /dev/null` 195 if [ -z "${CF_DIFF}" ]; then 196 IGNORE_FILES="${IGNORE_FILES} ${cf}" 197 fi 198 done 199 if [ -r /etc/sysmerge.ignore ]; then 200 while read i; do \ 201 IGNORE_FILES="${IGNORE_FILES} $(echo ${i} | sed -e 's,\.\.,,g' -e 's,#.*,,g')" 202 done < /etc/sysmerge.ignore 203 fi 204 for i in ${IGNORE_FILES}; do 205 rm -rf ${TEMPROOT}/${i}; 206 done 207} 208 209 210do_install_and_rm() { 211 if [ -f "${5}/${4##*/}" ]; then 212 mkdir -p ${BKPDIR}/${4%/*} 213 cp ${5}/${4##*/} ${BKPDIR}/${4%/*} 214 fi 215 216 if ! install -m "${1}" -o "${2}" -g "${3}" "${4}" "${5}" 2> /dev/null; then 217 rm -f ${BKPDIR}/${4%/*}/${4##*/} 218 return 1 219 fi 220 rm -f "${4}" 221} 222 223 224mm_install() { 225 local INSTDIR 226 INSTDIR=${1#.} 227 INSTDIR=${INSTDIR%/*} 228 229 if [ -z "${INSTDIR}" ]; then INSTDIR=/; fi 230 231 DIR_MODE=`stat -f "%OMp%OLp" "${TEMPROOT}/${INSTDIR}"` 232 eval `stat -f "FILE_MODE=%OMp%OLp FILE_OWN=%Su FILE_GRP=%Sg" ${1}` 233 234 if [ "${DESTDIR}${INSTDIR}" -a ! -d "${DESTDIR}${INSTDIR}" ]; then 235 install -d -o root -g wheel -m "${DIR_MODE}" "${DESTDIR}${INSTDIR}" 236 fi 237 238 do_install_and_rm "${FILE_MODE}" "${FILE_OWN}" "${FILE_GRP}" "${1}" "${DESTDIR}${INSTDIR}" || return 239 240 case "${1#.}" in 241 /dev/MAKEDEV) 242 echo -n "===> A new ${DESTDIR%/}/dev/MAKEDEV script was installed, " 243 echo "running MAKEDEV" 244 (cd ${DESTDIR}/dev && /bin/sh MAKEDEV all) 245 ;; 246 /etc/login.conf) 247 if [ -f ${DESTDIR}/etc/login.conf.db ]; then 248 echo -n "===> A new ${DESTDIR%/}/etc/login.conf file was installed, " 249 echo "running cap_mkdb" 250 cap_mkdb ${DESTDIR}/etc/login.conf 251 fi 252 ;; 253 /etc/mail/access|/etc/mail/genericstable|/etc/mail/mailertable|/etc/mail/virtusertable) 254 DBFILE=`echo ${1} | sed -e 's,.*/,,'` 255 echo -n "===> A new ${DESTDIR%/}/${1#.} file was installed, " 256 echo "running makemap" 257 /usr/libexec/sendmail/makemap hash ${DESTDIR}/${1#.} < ${DESTDIR}/${1#.} 258 ;; 259 /etc/mail/aliases) 260 echo -n "===> A new ${DESTDIR%/}/etc/mail/aliases file was installed, " 261 echo "running newaliases" 262 if [ "${DESTDIR}" ]; then 263 chroot ${DESTDIR} newaliases || export NEED_NEWALIASES=1 264 else 265 newaliases 266 fi 267 ;; 268 /etc/master.passwd) 269 echo -n "===> A new ${DESTDIR%/}/etc/master.passwd file was installed, " 270 echo "running pwd_mkdb" 271 pwd_mkdb -d ${DESTDIR}/etc -p ${DESTDIR}/etc/master.passwd 272 ;; 273 esac 274} 275 276 277merge_loop() { 278 if [ "`expr "${MERGE_CMD}" : ^sdiff.*`" -gt 0 ]; then 279 echo "===> Type h at the sdiff prompt (%) to get usage help\n" 280 fi 281 MERGE_AGAIN=1 282 while [ "${MERGE_AGAIN}" ]; do 283 cp -p "${COMPFILE}" "${COMPFILE}.merged" 284 ${MERGE_CMD} "${COMPFILE}.merged" \ 285 "${DESTDIR}${COMPFILE#.}" "${COMPFILE}" 286 INSTALL_MERGED=v 287 while [ "${INSTALL_MERGED}" = "v" ]; do 288 echo "" 289 echo " Use 'e' to edit the merged file" 290 echo " Use 'i' to install the merged file" 291 echo " Use 'n' to view a diff between the merged and new files" 292 echo " Use 'o' to view a diff between the old and merged files" 293 echo " Use 'r' to re-do the merge" 294 echo " Use 'v' to view the merged file" 295 echo " Use 'x' to delete the merged file and go back to previous menu" 296 echo " Default is to leave the temporary file to deal with by hand" 297 echo "" 298 echo -n "===> How should I deal with the merged file? [Leave it for later] " 299 read INSTALL_MERGED 300 case "${INSTALL_MERGED}" in 301 [eE]) 302 echo "editing merged file...\n" 303 if [ -z "${VISUAL}" ]; then 304 EDIT="${EDITOR}" 305 else 306 EDIT="${VISUAL}" 307 fi 308 if which ${EDIT} > /dev/null 2>&1; then 309 ${EDIT} ${COMPFILE}.merged 310 else 311 echo " *** Error: ${EDIT} can not be found or is not executable" 312 fi 313 INSTALL_MERGED=v 314 ;; 315 [iI]) 316 mv "${COMPFILE}.merged" "${COMPFILE}" 317 echo "" 318 if mm_install "${COMPFILE}"; then 319 echo "===> Merged version of ${COMPFILE} installed successfully" 320 else 321 echo " *** Warning: problem installing ${COMPFILE}, it will remain to merge by hand" 322 fi 323 unset MERGE_AGAIN 324 ;; 325 [nN]) 326 ( 327 echo "comparison between merged and new files:\n" 328 diff -u ${COMPFILE}.merged ${COMPFILE} 329 ) | ${PAGER} 330 INSTALL_MERGED=v 331 ;; 332 [oO]) 333 ( 334 echo "comparison between old and merged files:\n" 335 diff -u ${DESTDIR}${COMPFILE#.} ${COMPFILE}.merged 336 ) | ${PAGER} 337 INSTALL_MERGED=v 338 ;; 339 [rR]) 340 rm "${COMPFILE}.merged" 341 ;; 342 [vV]) 343 ${PAGER} "${COMPFILE}.merged" 344 ;; 345 [xX]) 346 rm "${COMPFILE}.merged" 347 return 1 348 ;; 349 '') 350 echo "===> ${COMPFILE} will remain for your consideration" 351 unset MERGE_AGAIN 352 ;; 353 *) 354 echo "invalid choice: ${INSTALL_MERGED}" 355 INSTALL_MERGED=v 356 ;; 357 esac 358 done 359 done 360} 361 362 363diff_loop() { 364 if [ "${BATCHMODE}" ]; then 365 HANDLE_COMPFILE=todo 366 else 367 HANDLE_COMPFILE=v 368 fi 369 370 unset NO_INSTALLED 371 unset CAN_INSTALL 372 373 while [ "${HANDLE_COMPFILE}" = "v" -o "${HANDLE_COMPFILE}" = "todo" ]; do 374 if [ "${HANDLE_COMPFILE}" = "v" ]; then 375 echo "\n========================================================================\n" 376 fi 377 if [ -f "${DESTDIR}${COMPFILE#.}" -a -f "${COMPFILE}" ]; then 378 # automatically install files which differ only by CVS Id 379 if [ "${AUTOMODE}" ]; then 380 if diff -q -I'[$]OpenBSD:.*$' "${DESTDIR}${COMPFILE#.}" "${COMPFILE}" > /dev/null 2>&1; then 381 if mm_install "${COMPFILE}"; then 382 echo "===> ${COMPFILE} installed successfully" 383 AUTO_INSTALLED_FILES="${AUTO_INSTALLED_FILES}${DESTDIR}${COMPFILE#.}\n" 384 else 385 echo " *** Warning: problem installing ${COMPFILE}, it will remain to merge by hand" 386 fi 387 return 388 fi 389 fi 390 if [ "${OTGZ}" -o "${OXTGZ}" ]; then 391 # if current != new and current = old, auto-install new 392 if diff -q "${DESTDIR}${COMPFILE#.}" "${OTEMPROOT}${COMPFILE#.}" > /dev/null 2>&1; then 393 echo "===> ${COMPFILE} has not been modified since previous release/snapshot," 394 echo " automatically installing new version" 395 if mm_install "${COMPFILE}"; then 396 echo "===> ${COMPFILE} installed successfully" 397 AUTO_INSTALLED_FILES="${AUTO_INSTALLED_FILES}${DESTDIR}${COMPFILE#.}\n" 398 else 399 echo " *** Warning: problem installing ${COMPFILE}, it will remain to merge by hand" 400 fi 401 return 402 fi 403 fi 404 if [ "${HANDLE_COMPFILE}" = "v" ]; then 405 ( 406 echo "===> Displaying differences between ${COMPFILE} and installed version:" 407 echo "" 408 diff -u "${DESTDIR}${COMPFILE#.}" "${COMPFILE}" 409 ) | ${PAGER} 410 echo "" 411 fi 412 else 413 echo "===> ${COMPFILE} was not found on the target system" 414 if [ -z "${AUTOMODE}" ]; then 415 echo "" 416 NO_INSTALLED=1 417 else 418 if mm_install "${COMPFILE}"; then 419 echo "===> ${COMPFILE} installed successfully" 420 AUTO_INSTALLED_FILES="${AUTO_INSTALLED_FILES}${DESTDIR}${COMPFILE#.}\n" 421 else 422 echo " *** Warning: problem installing ${COMPFILE}, it will remain to merge by hand" 423 fi 424 return 425 fi 426 fi 427 428 if [ -z "${BATCHMODE}" ]; then 429 echo " Use 'd' to delete the temporary ${COMPFILE}" 430 if [ "${COMPFILE}" != "./etc/master.passwd" -a "${COMPFILE}" != "./etc/group" -a "${COMPFILE}" != "./etc/hosts" ]; then 431 CAN_INSTALL=1 432 echo " Use 'i' to install the temporary ${COMPFILE}" 433 fi 434 if [ -z "${NO_INSTALLED}" -a -z "${IS_BINFILE}" ]; then 435 echo " Use 'm' to merge the temporary and installed versions" 436 echo " Use 'v' to view the diff results again" 437 fi 438 echo "" 439 echo " Default is to leave the temporary file to deal with by hand" 440 echo "" 441 echo -n "How should I deal with this? [Leave it for later] " 442 read HANDLE_COMPFILE 443 else 444 unset HANDLE_COMPFILE 445 fi 446 447 case "${HANDLE_COMPFILE}" in 448 [dD]) 449 rm "${COMPFILE}" 450 echo "\n===> Deleting ${COMPFILE}" 451 ;; 452 [iI]) 453 if [ -n "${CAN_INSTALL}" ]; then 454 echo "" 455 if mm_install "${COMPFILE}"; then 456 echo "===> ${COMPFILE} installed successfully" 457 else 458 echo " *** Warning: problem installing ${COMPFILE}, it will remain to merge by hand" 459 fi 460 else 461 echo "invalid choice: ${HANDLE_COMPFILE}\n" 462 HANDLE_COMPFILE="todo" 463 fi 464 465 ;; 466 [mM]) 467 if [ -z "${NO_INSTALLED}" -a -z "${IS_BINFILE}" ]; then 468 merge_loop || HANDLE_COMPFILE="todo" 469 else 470 echo "invalid choice: ${HANDLE_COMPFILE}\n" 471 HANDLE_COMPFILE="todo" 472 fi 473 ;; 474 [vV]) 475 if [ -z "${NO_INSTALLED}" -a -z "${IS_BINFILE}" ]; then 476 HANDLE_COMPFILE="v" 477 else 478 echo "invalid choice: ${HANDLE_COMPFILE}\n" 479 HANDLE_COMPFILE="todo" 480 fi 481 ;; 482 '') 483 echo "\n===> ${COMPFILE} will remain for your consideration" 484 ;; 485 *) 486 echo "invalid choice: ${HANDLE_COMPFILE}\n" 487 HANDLE_COMPFILE="todo" 488 continue 489 ;; 490 esac 491 done 492} 493 494 495do_compare() { 496 echo "===> Starting comparison" 497 498 cd ${TEMPROOT} || error_rm_wrkdir 499 500 # use -size +0 to avoid comparing empty log files and device nodes 501 for COMPFILE in `find . -type f -size +0`; do 502 if [ ! -e "${DESTDIR}${COMPFILE#.}" ]; then 503 diff_loop 504 continue 505 fi 506 507 # compare CVS $Id's first so if the file hasn't been modified, 508 # it will be deleted from temproot and ignored from comparison. 509 # several files are generated from scripts so CVS ID is not a 510 # reliable way of detecting changes; leave for a full diff. 511 if [ "${AUTOMODE}" -a "${COMPFILE}" != "./etc/fbtab" \ 512 -a "${COMPFILE}" != "./etc/login.conf" \ 513 -a "${COMPFILE}" != "./etc/sysctl.conf" \ 514 -a "${COMPFILE}" != "./etc/ttys" ]; then 515 CVSID1=`grep "[$]OpenBSD:" ${DESTDIR}${COMPFILE#.} 2> /dev/null` 516 CVSID2=`grep "[$]OpenBSD:" ${COMPFILE} 2> /dev/null` || CVSID2=none 517 if [ "${CVSID2}" = "${CVSID1}" ]; then rm "${COMPFILE}"; fi 518 fi 519 520 if [ -f "${COMPFILE}" ]; then 521 # make sure files are different; if not, delete the one in temproot 522 if diff -q "${DESTDIR}${COMPFILE#.}" "${COMPFILE}" > /dev/null 2>&1; then 523 rm "${COMPFILE}" 524 # delete file in temproot if it has not changed since last release 525 elif [ "${OTGZ}" -o "${OXTGZ}" ] && diff -q "${COMPFILE}" "${OTEMPROOT}${COMPFILE#.}" > /dev/null 2>&1; then 526 rm "${COMPFILE}" 527 # xetcXX.tgz contains binary files; set IS_BINFILE to disable sdiff 528 elif diff -q "${DESTDIR}${COMPFILE#.}" "${COMPFILE}" | grep "Binary" > /dev/null 2>&1; then 529 IS_BINFILE=1 530 diff_loop 531 else 532 unset IS_BINFILE 533 diff_loop 534 fi 535 fi 536 done 537 538 echo "\n===> Comparison complete" 539} 540 541 542do_post() { 543 clean_src 544 rm -rf ${OTEMPROOT} 545 546 echo "===> Making sure your directory hierarchy has correct perms, running mtree" 547 mtree -qdef ${DESTDIR}/etc/mtree/4.4BSD.dist -p ${DESTDIR:=/} -U > /dev/null 548 549 if [ "${NEED_NEWALIASES}" ]; then 550 echo "===> A new ${DESTDIR}/etc/mail/aliases file was installed." >> ${REPORT} 551 echo "However ${DESTDIR}/usr/bin/newaliases could not be run," >> ${REPORT} 552 echo "you will need to rebuild your aliases database manually.\n" >> ${REPORT} 553 unset NEED_NEWALIASES 554 fi 555 556 FILES_IN_TEMPROOT=`find ${TEMPROOT} -type f ! -name \*.merged -size +0 2> /dev/null` 557 FILES_IN_BKPDIR=`find ${BKPDIR} -type f -size +0 2> /dev/null` 558 if [ "${AUTO_INSTALLED_FILES}" ]; then 559 echo "===> Automatically installed file(s)" >> ${REPORT} 560 echo "${AUTO_INSTALLED_FILES}" >> ${REPORT} 561 fi 562 if [ "${FILES_IN_BKPDIR}" ]; then 563 echo "===> Backup of replaced file(s) can be found under" >> ${REPORT} 564 echo "${BKPDIR}\n" >> ${REPORT} 565 fi 566 if [ "${OBSOLETE_FILES}" ]; then 567 echo "===> File(s) removed from previous set (maybe obsolete)" >> ${REPORT} 568 echo "${OBSOLETE_FILES}" >> ${REPORT} 569 fi 570 if [ "${FILES_IN_TEMPROOT}" ]; then 571 echo "===> File(s) remaining for you to merge by hand" >> ${REPORT} 572 echo "${FILES_IN_TEMPROOT}" >> ${REPORT} 573 fi 574 575 if [ -e "${REPORT}" ]; then 576 if [ "${OBSOLETE_FILES}" -o "${FILES_IN_TEMPROOT}" ]; then 577 echo "===> Manual intervention may be needed, see ${REPORT}" 578 else 579 echo "===> Output log available at ${REPORT}" 580 fi 581 echo "===> When done, ${WRKDIR} and its subdirectories should be removed" 582 else 583 echo "===> Removing ${WRKDIR}" 584 rm -rf "${WRKDIR}" 585 fi 586} 587 588 589while getopts abs:x:S:X: arg; do 590 case ${arg} in 591 a) 592 AUTOMODE=1 593 ;; 594 b) 595 BATCHMODE=1 596 ;; 597 s) 598 if [ -f "${OPTARG}/etc/Makefile" ]; then 599 SRCDIR=${OPTARG} 600 elif [ -f "${OPTARG}" ] && echo -n ${OPTARG} | \ 601 awk -F/ '{print $NF}' | \ 602 grep '^etc[0-9][0-9]\.tgz$' > /dev/null 2>&1 ; then 603 TGZ=${OPTARG} 604 elif echo ${OPTARG} | \ 605 grep -qE '^(http|ftp)://.*/etc[0-9][0-9]\.tgz$'; then 606 TGZ=${WRKDIR}/etc.tgz 607 TGZURL=${OPTARG} 608 if ! ${FETCH_CMD} -o ${TGZ} ${TGZURL}; then 609 echo " *** Error: could not retrieve ${TGZURL}" 610 error_rm_wrkdir 611 fi 612 else 613 echo " *** Error: ${OPTARG} is not a path to src nor etcXX.tgz" 614 error_rm_wrkdir 615 fi 616 ;; 617 x) 618 if [ -f "${OPTARG}" ] && echo -n ${OPTARG} | \ 619 awk -F/ '{print $NF}' | \ 620 grep '^xetc[0-9][0-9]\.tgz$' > /dev/null 2>&1 ; then 621 XTGZ=${OPTARG} 622 elif echo ${OPTARG} | \ 623 grep -qE '^(http|ftp)://.*/xetc[0-9][0-9]\.tgz$'; then 624 XTGZ=${WRKDIR}/xetc.tgz 625 XTGZURL=${OPTARG} 626 if ! ${FETCH_CMD} -o ${XTGZ} ${XTGZURL}; then 627 echo " *** Error: could not retrieve ${XTGZURL}" 628 error_rm_wrkdir 629 fi 630 else 631 echo " *** Error: ${OPTARG} is not a path to xetcXX.tgz" 632 error_rm_wrkdir 633 fi 634 ;; 635 S) 636 if [ -f "${OPTARG}" ] && echo -n ${OPTARG} | \ 637 awk -F/ '{print $NF}' | \ 638 grep '^etc[0-9][0-9]\.tgz$' > /dev/null 2>&1 ; then 639 OTGZ=${OPTARG} 640 elif echo ${OPTARG} | \ 641 grep -qE '^(http|ftp)://.*/etc[0-9][0-9]\.tgz$'; then 642 OTGZ=${WRKDIR}/etc.tgz 643 OTGZURL=${OPTARG} 644 if ! ${FETCH_CMD} -o ${OTGZ} ${OTGZURL}; then 645 echo " *** Error: could not retrieve ${OTGZURL}" 646 error_rm_wrkdir 647 fi 648 else 649 echo " *** Error: ${OPTARG} is not a path to etcXX.tgz" 650 error_rm_wrkdir 651 fi 652 ;; 653 X) 654 if [ -f "${OPTARG}" ] && echo -n ${OPTARG} | \ 655 awk -F/ '{print $NF}' | \ 656 grep '^xetc[0-9][0-9]\.tgz$' > /dev/null 2>&1 ; then 657 OXTGZ=${OPTARG} 658 elif echo ${OPTARG} | \ 659 grep -qE '^(http|ftp)://.*/xetc[0-9][0-9]\.tgz$'; then 660 OXTGZ=${WRKDIR}/xetc.tgz 661 OXTGZURL=${OPTARG} 662 if ! ${FETCH_CMD} -o ${OXTGZ} ${OXTGZURL}; then 663 echo " *** Error: could not retrieve ${OXTGZURL}" 664 error_rm_wrkdir 665 fi 666 else 667 echo " *** Error: ${OPTARG} is not a path to xetcXX.tgz" 668 error_rm_wrkdir 669 fi 670 ;; 671 *) 672 usage 673 error_rm_wrkdir 674 ;; 675 esac 676done 677 678 679do_pre 680do_populate 681do_compare 682do_post 683