1#!/bin/ksh - 2# 3# $OpenBSD: sysmerge.sh,v 1.82 2011/09/01 07:52:46 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 fi 205 export NEED_REBOOT=1 206 ;; 207 /etc/mail/access|/etc/mail/genericstable|/etc/mail/mailertable|/etc/mail/virtusertable) 208 echo " (running makemap(8))" 209 DBFILE=`echo ${1} | sed -e 's,.*/,,'` 210 /usr/libexec/sendmail/makemap hash ${DESTDIR}/${1#.} < ${DESTDIR}/${1#.} 211 ;; 212 /etc/mail/aliases) 213 echo " (running newaliases(8))" 214 if [ "${DESTDIR}" ]; then 215 chroot ${DESTDIR} newaliases >/dev/null || export NEED_NEWALIASES=1 216 else 217 newaliases >/dev/null 218 fi 219 ;; 220 /etc/master.passwd) 221 echo " (running pwd_mkdb(8))" 222 pwd_mkdb -d ${DESTDIR}/etc -p ${DESTDIR}/etc/master.passwd 223 ;; 224 *) 225 echo "" 226 ;; 227 esac 228} 229 230mm_install_link() { 231 _LINKT=`readlink ${COMPFILE}` 232 _LINKF=`dirname ${DESTDIR}${COMPFILE#.}` 233 234 DIR_MODE=`stat -f "%OMp%OLp" "${TEMPROOT}/${_LINKF}"` 235 [ ! -d "${_LINKF}" ] && \ 236 install -d -o root -g wheel -m "${DIR_MODE}" "${_LINKF}" 237 238 rm -f ${COMPFILE} 239 (cd ${_LINKF} && ln -sf ${_LINKT} .) 240 return 241} 242 243merge_loop() { 244 if [ "`expr "${MERGE_CMD}" : ^sdiff.*`" -gt 0 ]; then 245 echo "===> Type h at the sdiff prompt (%) to get usage help\n" 246 fi 247 MERGE_AGAIN=1 248 while [ "${MERGE_AGAIN}" ]; do 249 cp -p "${COMPFILE}" "${COMPFILE}.merged" 250 ${MERGE_CMD} "${COMPFILE}.merged" \ 251 "${DESTDIR}${COMPFILE#.}" "${COMPFILE}" 252 INSTALL_MERGED=v 253 while [ "${INSTALL_MERGED}" = "v" ]; do 254 echo "" 255 echo " Use 'e' to edit the merged file" 256 echo " Use 'i' to install the merged file" 257 echo " Use 'n' to view a diff between the merged and new files" 258 echo " Use 'o' to view a diff between the old and merged files" 259 echo " Use 'r' to re-do the merge" 260 echo " Use 'v' to view the merged file" 261 echo " Use 'x' to delete the merged file and go back to previous menu" 262 echo " Default is to leave the temporary file to deal with by hand" 263 echo "" 264 echo -n "===> How should I deal with the merged file? [Leave it for later] " 265 read INSTALL_MERGED 266 case "${INSTALL_MERGED}" in 267 [eE]) 268 echo "editing merged file...\n" 269 if [ -z "${VISUAL}" ]; then 270 EDIT="${EDITOR:=/usr/bin/vi}" 271 else 272 EDIT="${VISUAL}" 273 fi 274 ${EDIT} ${COMPFILE}.merged 275 INSTALL_MERGED=v 276 ;; 277 [iI]) 278 mv "${COMPFILE}.merged" "${COMPFILE}" 279 echo -n "\n===> Merging ${COMPFILE#.}" 280 if ! mm_install "${COMPFILE}"; then 281 echo "\t*** WARNING: problem merging ${COMPFILE#.}" 282 fi 283 unset MERGE_AGAIN 284 ;; 285 [nN]) 286 ( 287 echo "comparison between merged and new files:\n" 288 diff -u ${COMPFILE}.merged ${COMPFILE} 289 ) | ${PAGER} 290 INSTALL_MERGED=v 291 ;; 292 [oO]) 293 ( 294 echo "comparison between old and merged files:\n" 295 diff -u ${DESTDIR}${COMPFILE#.} ${COMPFILE}.merged 296 ) | ${PAGER} 297 INSTALL_MERGED=v 298 ;; 299 [rR]) 300 rm "${COMPFILE}.merged" 301 ;; 302 [vV]) 303 ${PAGER} "${COMPFILE}.merged" 304 ;; 305 [xX]) 306 rm "${COMPFILE}.merged" 307 return 1 308 ;; 309 '') 310 echo "===> ${COMPFILE} will remain for your consideration" 311 unset MERGE_AGAIN 312 ;; 313 *) 314 echo "invalid choice: ${INSTALL_MERGED}" 315 INSTALL_MERGED=v 316 ;; 317 esac 318 done 319 done 320} 321 322diff_loop() { 323 if [ "${BATCHMODE}" ]; then 324 HANDLE_COMPFILE=todo 325 else 326 HANDLE_COMPFILE=v 327 fi 328 329 unset NO_INSTALLED 330 unset CAN_INSTALL 331 unset FORCE_UPG 332 333 while [ "${HANDLE_COMPFILE}" = "v" -o "${HANDLE_COMPFILE}" = "todo" ]; do 334 if [ -f "${DESTDIR}${COMPFILE#.}" -a -f "${COMPFILE}" -a -z "${IS_LINK}" ]; then 335 if [ -z "${DIFFMODE}" ]; then 336 # automatically install files if current != new and current = old 337 for i in "${AUTO_UPG[@]}"; do 338 if [ "${i}" = "${COMPFILE}" ]; then 339 FORCE_UPG=1 340 fi 341 done 342 # automatically install files which differ only by CVS Id or that are binaries 343 if [ -z "`diff -q -I'[$]OpenBSD:.*$' "${DESTDIR}${COMPFILE#.}" "${COMPFILE}"`" -o -n "${FORCE_UPG}" -o -n "${IS_BINFILE}" ]; then 344 echo -n "===> Updating ${COMPFILE#.}" 345 if mm_install "${COMPFILE}"; then 346 AUTO_INSTALLED_FILES="${AUTO_INSTALLED_FILES}${DESTDIR}${COMPFILE#.}\n" 347 else 348 echo "\t*** WARNING: problem updating ${COMPFILE#.}" 349 fi 350 return 351 fi 352 # automatically install missing users 353 if [ "${COMPFILE}" = "./etc/master.passwd" ]; then 354 local _merge_pwd 355 while read l; do 356 _u=`echo ${l} | awk -F ':' '{ print $1 }'` 357 if [ "${_u}" != "root" ]; then 358 if [ -z "`grep -E "^${_u}:" ${DESTDIR}${COMPFILE#.}`" ]; then 359 echo "===> Adding the ${_u} user" 360 if [ "${DESTDIR}" ]; then 361 chroot ${DESTDIR} chpass -la "${l}" 362 else 363 chpass -la "${l}" 364 fi 365 if [ $? -eq 0 ]; then 366 set -A NEWUSR -- ${NEWUSR[@]} ${_u} 367 else 368 _merge_pwd=1 369 fi 370 fi 371 fi 372 done < ${COMPFILE} 373 if [ -z ${_merge_pwd} ]; then 374 rm "${TEMPROOT}${COMPFILE#.}" 375 return 376 fi 377 fi 378 # automatically install missing groups 379 if [ "${COMPFILE}" = "./etc/group" ]; then 380 local _merge_grp 381 while read l; do 382 _g=`echo ${l} | awk -F ':' '{ print $1 }'` 383 _gid=`echo ${l} | awk -F ':' '{ print $3 }'` 384 if [ -z "`grep -E "^${_g}:" ${DESTDIR}${COMPFILE#.}`" ]; then 385 echo "===> Adding the ${_g} group" 386 if [ "${DESTDIR}" ]; then 387 chroot ${DESTDIR} groupadd -g "${_gid}" "${_g}" 388 else 389 groupadd -g "${_gid}" "${_g}" 390 fi 391 if [ $? -eq 0 ]; then 392 set -A NEWGRP -- ${NEWGRP[@]} ${_g} 393 else 394 _merge_grp=1 395 fi 396 fi 397 done < ${COMPFILE} 398 if [ -z ${_merge_grp} ]; then 399 rm "${TEMPROOT}${COMPFILE#.}" 400 return 401 fi 402 fi 403 fi 404 if [ "${HANDLE_COMPFILE}" = "v" ]; then 405 ( 406 echo "\n========================================================================\n" 407 echo "===> Displaying differences between ${COMPFILE} and installed version:" 408 echo "" 409 diff -u "${DESTDIR}${COMPFILE#.}" "${COMPFILE}" 410 ) | ${PAGER} 411 echo "" 412 fi 413 else 414 # file does not exist on the target system 415 if [ "${IS_LINK}" ]; then 416 if [ -n "${DIFFMODE}" ]; then 417 echo "" 418 NO_INSTALLED=1 419 else 420 if mm_install_link; then 421 echo "===> ${COMPFILE#.} link created successfully" 422 AUTO_INSTALLED_FILES="${AUTO_INSTALLED_FILES}${DESTDIR}${COMPFILE#.}\n" 423 else 424 echo "\t*** WARNING: problem creating ${COMPFILE#.} link" 425 fi 426 return 427 fi 428 fi 429 if [ -n "${DIFFMODE}" ]; then 430 echo "" 431 NO_INSTALLED=1 432 else 433 echo -n "===> Installing ${COMPFILE#.}" 434 if mm_install "${COMPFILE}"; then 435 AUTO_INSTALLED_FILES="${AUTO_INSTALLED_FILES}${DESTDIR}${COMPFILE#.}\n" 436 else 437 echo "\t*** WARNING: problem installing ${COMPFILE#.}" 438 fi 439 return 440 fi 441 fi 442 443 if [ -z "${BATCHMODE}" ]; then 444 echo " Use 'd' to delete the temporary ${COMPFILE}" 445 if [ "${COMPFILE}" != "./etc/master.passwd" -a "${COMPFILE}" != "./etc/group" -a "${COMPFILE}" != "./etc/hosts" ]; then 446 CAN_INSTALL=1 447 echo " Use 'i' to install the temporary ${COMPFILE}" 448 fi 449 if [ -z "${NO_INSTALLED}" -a -z "${IS_BINFILE}" -a -z "${IS_LINK}" ]; then 450 echo " Use 'm' to merge the temporary and installed versions" 451 echo " Use 'v' to view the diff results again" 452 fi 453 echo "" 454 echo " Default is to leave the temporary file to deal with by hand" 455 echo "" 456 echo -n "How should I deal with this? [Leave it for later] " 457 read HANDLE_COMPFILE 458 else 459 unset HANDLE_COMPFILE 460 fi 461 462 case "${HANDLE_COMPFILE}" in 463 [dD]) 464 rm "${COMPFILE}" 465 echo "\n===> Deleting ${COMPFILE}" 466 ;; 467 [iI]) 468 if [ -n "${CAN_INSTALL}" ]; then 469 echo "" 470 if [ -n "${IS_LINK}" ]; then 471 if mm_install_link; then 472 echo "===> ${COMPFILE#.} link created successfully" 473 AUTO_INSTALLED_FILES="${AUTO_INSTALLED_FILES}${DESTDIR}${COMPFILE#.}\n" 474 else 475 echo "\t*** WARNING: problem creating ${COMPFILE#.} link" 476 fi 477 else 478 echo -n "===> Updating ${COMPFILE#.}" 479 if ! mm_install "${COMPFILE}"; then 480 echo "\t*** WARNING: problem updating ${COMPFILE#.}" 481 fi 482 fi 483 else 484 echo "invalid choice: ${HANDLE_COMPFILE}\n" 485 HANDLE_COMPFILE="todo" 486 fi 487 488 ;; 489 [mM]) 490 if [ -z "${NO_INSTALLED}" -a -z "${IS_BINFILE}" -a -z "${IS_LINK}" ]; then 491 merge_loop || HANDLE_COMPFILE="todo" 492 else 493 echo "invalid choice: ${HANDLE_COMPFILE}\n" 494 HANDLE_COMPFILE="todo" 495 fi 496 ;; 497 [vV]) 498 if [ -z "${NO_INSTALLED}" -a -z "${IS_BINFILE}" -a -z "${IS_LINK}" ]; then 499 HANDLE_COMPFILE="v" 500 else 501 echo "invalid choice: ${HANDLE_COMPFILE}\n" 502 HANDLE_COMPFILE="todo" 503 fi 504 ;; 505 '') 506 echo "\n===> ${COMPFILE} will remain for your consideration" 507 ;; 508 *) 509 echo "invalid choice: ${HANDLE_COMPFILE}\n" 510 HANDLE_COMPFILE="todo" 511 continue 512 ;; 513 esac 514 done 515} 516 517do_compare() { 518 echo "===> Starting comparison" 519 520 cd ${TEMPROOT} || error_rm_wrkdir 521 522 # use -size +0 to avoid comparing empty log files and device nodes; 523 # however, we want to keep the symlinks; group and master.passwd 524 # need to be handled first in case mm_install needs a new user/group 525 local _c1="./etc/group ./etc/master.passwd" 526 local _c2=`find . -type f -size +0 -or -type l | grep -vE '(./etc/group|./etc/master.passwd)'` 527 for COMPFILE in ${_c1} ${_c2}; do 528 unset IS_BINFILE 529 unset IS_LINK 530 # links need to be treated in a different way 531 if [ -h "${COMPFILE}" ]; then 532 IS_LINK=1 533 fi 534 if [ ! -e "${DESTDIR}${COMPFILE#.}" ]; then 535 diff_loop 536 continue 537 fi 538 539 # compare CVS $Id's first so if the file hasn't been modified, 540 # it will be deleted from temproot and ignored from comparison. 541 # several files are generated from scripts so CVS ID is not a 542 # reliable way of detecting changes; leave for a full diff. 543 if [ -z "${DIFFMODE}" -a "${COMPFILE}" != "./etc/fbtab" \ 544 -a "${COMPFILE}" != "./etc/login.conf" \ 545 -a "${COMPFILE}" != "./etc/sysctl.conf" \ 546 -a "${COMPFILE}" != "./etc/ttys" -a -z "${IS_LINK}" ]; then 547 CVSID1=`grep "[$]OpenBSD:" ${DESTDIR}${COMPFILE#.} 2>/dev/null` 548 CVSID2=`grep "[$]OpenBSD:" ${COMPFILE} 2>/dev/null` || CVSID2=none 549 if [ "${CVSID2}" = "${CVSID1}" ]; then rm "${COMPFILE}"; fi 550 fi 551 552 if [ -f "${COMPFILE}" -a -z "${IS_LINK}" ]; then 553 # make sure files are different; if not, delete the one in temproot 554 if diff -q "${DESTDIR}${COMPFILE#.}" "${COMPFILE}" >/dev/null 2>&1; then 555 rm "${COMPFILE}" 556 # xetcXX.tgz contains binary files; set IS_BINFILE to disable sdiff 557 elif diff -q "${DESTDIR}${COMPFILE#.}" "${COMPFILE}" | grep "Binary" >/dev/null 2>&1; then 558 IS_BINFILE=1 559 diff_loop 560 else 561 diff_loop 562 fi 563 fi 564 done 565 566 echo "===> Comparison complete" 567} 568 569do_post() { 570 echo "===> Checking directory hierarchy permissions (running mtree(8))" 571 mtree -qdef ${DESTDIR}/etc/mtree/4.4BSD.dist -p ${DESTDIR:=/} -U >/dev/null 572 if [ -n "${XTGZ}" ]; then 573 mtree -qdef ${DESTDIR}/etc/mtree/BSD.x11.dist -p ${DESTDIR:=/} -U >/dev/null 574 fi 575 576 if [ "${NEED_NEWALIASES}" ]; then 577 echo "===> A new ${DESTDIR}/etc/mail/aliases file was installed." >> ${REPORT} 578 echo "However ${DESTDIR}/usr/bin/newaliases could not be run," >> ${REPORT} 579 echo "you will need to rebuild your aliases database manually.\n" >> ${REPORT} 580 unset NEED_NEWALIASES 581 fi 582 583 FILES_IN_TEMPROOT=`find ${TEMPROOT} -type f ! -name \*.merged -size +0 2>/dev/null` 584 FILES_IN_BKPDIR=`find ${BKPDIR} -type f -size +0 2>/dev/null` 585 if [ "${AUTO_INSTALLED_FILES}" ]; then 586 echo "===> Automatically installed file(s)" >> ${REPORT} 587 echo "${AUTO_INSTALLED_FILES}" >> ${REPORT} 588 fi 589 if [ "${FILES_IN_BKPDIR}" ]; then 590 echo "===> Backup of replaced file(s) can be found under" >> ${REPORT} 591 echo "${BKPDIR}\n" >> ${REPORT} 592 fi 593 if [ "${NEWUSR}" -o "${NEWGRP}" ]; then 594 echo "===> The following user(s)/group(s) have been added" >> ${REPORT} 595 if [ "${NEWUSR}" ]; then 596 echo -n "user(s): ${NEWUSR[@]}\n" >> ${REPORT} 597 fi 598 if [ "${NEWGRP}" ]; then 599 echo -n "group(s): ${NEWGRP[@]}\n" >> ${REPORT} 600 fi 601 echo "" >> ${REPORT} 602 fi 603 if [ "${FILES_IN_TEMPROOT}" ]; then 604 echo "===> File(s) remaining for you to merge by hand" >> ${REPORT} 605 echo "${FILES_IN_TEMPROOT}" >> ${REPORT} 606 fi 607 608 if [ -e "${REPORT}" ]; then 609 echo "===> Output log available at ${REPORT}" 610 else 611 echo "===> Removing ${WRKDIR}" 612 rm -rf "${WRKDIR}" 613 fi 614 615 if [ "${FILES_IN_TEMPROOT}" ]; then 616 echo "\t*** WARNING: some files are still left for comparison" 617 fi 618 619 if [ "${NEED_NEWALIASES}" ]; then 620 echo "\t*** WARNING: newaliases(8) failed to run properly" 621 fi 622 623 if [ "${NEED_REBOOT}" ]; then 624 echo "\t*** WARNING: some new/updated file(s) may require a reboot" 625 fi 626 627 unset FILES_IN_TEMPROOT NEED_NEWALIASES NEED_REBOOT 628 629 clean_src 630 rm -f ${DESTDIR}/${DBDIR}/.*.bak 631} 632 633while getopts bds:x: arg; do 634 case ${arg} in 635 b) 636 BATCHMODE=1 637 ;; 638 d) 639 DIFFMODE=1 640 ;; 641 s) 642 if [ -d "${OPTARG}" ]; then 643 SRCDIR=${OPTARG} 644 elif echo ${OPTARG} | \ 645 grep -qE '^(file|ftp|http|https)://.*/etc[0-9][0-9]\.tgz$'; then 646 TGZ=${WRKDIR}/etc.tgz 647 TGZURL=${OPTARG} 648 if ! ${FETCH_CMD} -o ${TGZ} ${TGZURL}; then 649 echo "\t*** ERROR: could not retrieve ${TGZURL}" 650 error_rm_wrkdir 651 fi 652 else 653 TGZ=${OPTARG} 654 fi 655 ;; 656 x) 657 if echo ${OPTARG} | \ 658 grep -qE '^(file|ftp|http|https)://.*/xetc[0-9][0-9]\.tgz$'; then 659 XTGZ=${WRKDIR}/xetc.tgz 660 XTGZURL=${OPTARG} 661 if ! ${FETCH_CMD} -o ${XTGZ} ${XTGZURL}; then 662 echo "\t*** ERROR: could not retrieve ${XTGZURL}" 663 error_rm_wrkdir 664 fi 665 else 666 XTGZ=${OPTARG} 667 fi 668 ;; 669 *) 670 usage 671 error_rm_wrkdir 672 ;; 673 esac 674done 675 676shift $(( OPTIND -1 )) 677if [ $# -ne 0 ]; then 678 usage 679 error_rm_wrkdir 680fi 681 682if [ -z "${SRCDIR}" -a -z "${TGZ}" -a -z "${XTGZ}" ]; then 683 if [ -f "/usr/src/etc/Makefile" ]; then 684 SRCDIR=/usr/src 685 else 686 echo "\t*** ERROR: please specify a valid path to src or (x)etcXX.tgz" 687 usage 688 error_rm_wrkdir 689 fi 690fi 691 692if [ -n "${SRCDIR}" -a ! -f "${SRCDIR}/etc/Makefile" ]; then 693 echo "\t*** ERROR: ${SRCDIR} is not a valid path to src" 694 error_rm_wrkdir 695fi 696 697if [ -n "${TGZ}" ] && ! tar tzf ${TGZ} ./var/db/sysmerge/etcsum >/dev/null 2>&1; then 698 echo "\t*** ERROR: ${TGZ} is not a valid etcXX.tgz set" 699 error_rm_wrkdir 700fi 701 702if [ -n "${XTGZ}" ] && ! tar tzf ${XTGZ} ./var/db/sysmerge/xetcsum >/dev/null 2>&1; then 703 echo "\t*** ERROR: ${XTGZ} is not a valid xetcXX.tgz set" 704 error_rm_wrkdir 705fi 706 707TEMPROOT="${WRKDIR}/temproot" 708BKPDIR="${WRKDIR}/backups" 709 710do_populate 711do_compare 712do_post 713