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