Lines Matching +full:current +full:- +full:rotate

3 # SPDX-License-Identifier: BSD-2-Clause
5 # Copyright (c) 2010-2013 Hudson River Trading LLC
39 # modifications is to perform a three-way merge between the original
44 # To that end, etcupdate uses a strategy where the current unmodified
45 # tree is kept in WORKDIR/current and the previous unmodified tree is
59 # - automatable conflict resolution
64 usage: etcupdate [-npBFN] [-d workdir] [-r | -s source | -t tarball]
65 [-A patterns] [-D destdir] [-I patterns] [-L logfile]
66 [-M options] [-m make]
67 etcupdate build [-BN] [-d workdir] [-s source] [-L logfile] [-M options]
68 [-m make] <tarball>
69 etcupdate diff [-d workdir] [-D destdir] [-I patterns] [-L logfile]
70 etcupdate extract [-BN] [-d workdir] [-s source | -t tarball]
71 [-D destdir] [-L logfile] [-M options] [-m make]
72 etcupdate resolve [-p] [-d workdir] [-D destdir] [-L logfile]
73 etcupdate revert [-d workdir] [-D destdir] [-L logfile] file ...
74 etcupdate status [-d workdir] [-D destdir]
96 echo -n " " >> $WARNINGS
100 # Output a horizontal rule using the passed-in character. Matches the
103 # $1 - character
106 jot -b "$1" -s "" 67
111 # $1 - file pathname.
114 stat -f "%HT" $1 | tr "[:upper:]" "[:lower:]"
119 # $1 - file pathname.
122 [ -e $1 -o -L $1 ]
127 # $1 - file pathname
130 local pattern -
132 set -o noglob
140 set -o noglob
148 if [ ${DESTDIR}$1 -ef ${DESTDIR}/root$1 ]; then
162 # $1 - file pathname
165 local pattern -
167 set -o noglob
175 set -o noglob
183 # $1 - directory to store new tree in
188 make="$MAKE_CMD $MAKE_OPTIONS -DNO_FILEMON"
190 if [ -n "$noroot" ]; then
191 make="$make -DNO_ROOT"
192 metatmp=`mktemp $WORKDIR/etcupdate-XXXXXXX`
194 trap "rm -f $metatmp; trap '' EXIT; return 1" INT
195 trap "rm -f $metatmp" EXIT
205 mkdir -p $1/usr/obj
208 if [ -n "$preworld" ]; then
213 mkdir -p $1/etc || return 1
214 cp -p $SRCDIR/$file $1/etc/$name || return 1
219 if ! [ -n "$nobuild" ]; then
221 if [ -n "$($make -V.ALLTARGETS:Mbuildetc)" ]; then
228 if [ -n "$($make -V.ALLTARGETS:Minstalletc)" ]; then
231 $make DESTDIR=$destdir distrib-dirs || exit 1
236 chflags -R noschg $1 || return 1
237 rm -rf $1/usr/obj || return 1
239 # Purge auto-generated files. Only the source files need to
243 rm -f $autogenfiles) || return 1
246 (cd $1 && find . -type f -size 0 -delete -print >> $metatmp) || \
250 (cd $1 && find . -depth -type d -empty -delete -print >> $metatmp) || \
253 if [ -n "$noroot" ]; then
280 # $1 - directory to store new tree in
286 if [ -n "$tarball" ]; then
288 if [ -n "$preworld" ]; then
291 if ! (mkdir -p $1 && tar xf $tarball -C $1 $files) \
308 # $1 - path to tree
312 rm -rf $1 >&3 2>&1
313 if [ -e $1 ]; then
314 chflags -R noschg $1 >&3 2>&1
315 rm -rf $1 >&3 2>&1
317 [ ! -e $1 ]
337 # $1 - first node
338 # $2 - second node
344 # node. Note that -e will fail for a symbolic link that
357 first=`stat -f "%Hp" $1`
358 second=`stat -f "%Hp" $2`
364 if [ -L $1 ]; then
375 if [ -f $1 ]; then
376 if cmp -s $1 $2; then
391 # $1 - path of first file
392 # $2 - path of second file
396 diff -qI '\$FreeBSD.*\$' $1 $2 >/dev/null 2>&1
401 # FreeBSD ID string. It only makes this adjustment if the -F flag has
404 # $1 - first node
405 # $2 - second node
413 if [ -n "$FREEBSD_ID" -a "$cmp" -eq $COMPARE_DIFFFILES ] && \
423 # $1 - pathname of the directory to check
428 contents=`ls -A $1`
429 [ -z "$contents" ]
437 # $1 - first directory (sub)
438 # $2 - second directory (super)
443 if ! [ -d $1 -a -d $2 ]; then
449 contents=`ls -A $1`
455 if [ -d $1/$file ]; then
467 # (meaning that the directory would be empty in a non-dryrun when this
470 # $1 - pathname of the directory to check relative to DESTDIR.
474 if [ -n "$dryrun" ]; then
487 # $1 - first tree
488 # $2 - second tree
489 # $3 - node name
490 # $4 - label for first tree
491 # $5 - label for second tree
496 if [ -n "$FREEBSD_ID" ]; then
497 diffargs="-I \\\$FreeBSD.*\\\$"
529 echo "-$first"
536 diff -u $diffargs -L "$3 ($4)" $1/$3 -L "$3 ($5)" $2/$3
541 # Run one-off commands after an update has completed. These commands
548 # None of these commands should be run for a pre-world update.
549 if [ -n "$preworld" ]; then
554 # exists, run tzsetup -r to refresh /etc/localtime.
555 if [ -f ${DESTDIR}/etc/localtime -a \
556 ! -L ${DESTDIR}/etc/localtime ]; then
557 if [ -f ${DESTDIR}/var/db/zoneinfo ]; then
558 if [ -n "${DESTDIR}" ]; then
559 args="-C ${DESTDIR}"
563 log "tzsetup -r ${args}"
564 if [ -z "$dryrun" ]; then
565 tzsetup -r ${args} >&3 2>&1
578 # $1 - template tree
579 # $2 - target tree
580 # $3 - pathname of the node (relative to both trees)
590 if [ -d ${2}$dir ]; then
594 # If non-directory file exists with the desired directory
601 if [ -n "$dryrun" -a "$2" = "$DESTDIR" ]; then
620 args=`stat -f "-o %Su -g %Sg -m %0Mp%0Lp" $1/$dir`
622 log "install -d $args ${2}$dir"
623 if [ -z "$dryrun" ]; then
624 install -d $args ${2}$dir >&3 2>&1
629 # Perform post-install fixups for a file. This largely consists of
632 # $1 - pathname of the updated file (relative to DESTDIR)
638 if [ -z "$DESTDIR" ]; then
640 if [ -z "$dryrun" ]; then
649 if [ -z "$dryrun" ]; then
655 if [ -z "$dryrun" ]; then
660 log "pwd_mkdb -p -d $DESTDIR/etc ${DESTDIR}$1"
661 if [ -z "$dryrun" ]; then
662 pwd_mkdb -p -d $DESTDIR/etc ${DESTDIR}$1 \
668 # Don't warn about non-empty DESTDIR's since this
670 if [ -z "$DESTDIR" ]; then
672 if [ -z "$dryrun" ]; then
678 log "services_mkdb -q -o $DESTDIR/var/db/services.db" \
680 if [ -z "$dryrun" ]; then
681 services_mkdb -q -o $DESTDIR/var/db/services.db \
691 # $1 - pathname of the file to install (relative to DESTDIR)
698 log "cp -Rp ${NEWTREE}$1 ${DESTDIR}$1"
699 if [ -z "$dryrun" ]; then
700 cp -Rp ${NEWTREE}$1 ${DESTDIR}$1 >&3 2>&1
709 # $1 - pathname of the file to install (relative to DESTDIR)
730 # $1 - pathname of the file that conflicts (relative to DESTDIR)
734 if [ -n "$dryrun" ]; then
739 diff --changed-group-format='<<<<<<< (local)
747 # $1 - pathname of the old file to remove (relative to DESTDIR)
750 log "rm -f ${DESTDIR}$1"
751 if [ -z "$dryrun" ]; then
752 rm -f ${DESTDIR}$1 >&3 2>&1
759 # $1 - pathname of the file to update (relative to DESTDIR)
766 # from a directory to a non-directory). If the directory
769 if [ -d $DESTDIR/$1 ]; then
772 if [ -z "$dryrun" ]; then
782 elif ! [ -f ${DESTDIR}$1 -a -f ${NEWTREE}$1 ]; then
783 log "rm -f ${DESTDIR}$1"
784 if [ -z "$dryrun" ]; then
785 rm -f ${DESTDIR}$1 >&3 2>&1
793 if [ -d $NEWTREE/$1 ]; then
808 # $1 - pathname of the file to update (relative to DESTDIR)
818 new=`grep -c '\$FreeBSD.*\$' ${NEWTREE}$1`
819 dest=`grep -c '\$FreeBSD.*\$' ${DESTDIR}$1`
820 if [ "$dest" -eq 0 ]; then
823 if [ "$dest" -ne 1 -o "$dest" -ne 1 ]; then
840 file=`mktemp $WORKDIR/etcupdate-XXXXXXX`
850 rm -f $file
855 if [ -z "$dryrun" ]; then
858 rm -f $file
865 # only handles regular files. If the 3-way merge succeeds without
869 # $1 - pathname of the file to merge (relative to DESTDIR)
875 diff3 -E -m ${DESTDIR}$1 ${OLDTREE}$1 ${NEWTREE}$1 > /dev/null 2>&3
881 log "diff3 -E -m ${DESTDIR}$1 ${OLDTREE}$1 ${NEWTREE}$1"
882 if [ -z "$dryrun" ]; then
883 temp=$(mktemp -t etcupdate)
884 diff3 -E -m ${DESTDIR}$1 ${OLDTREE}$1 ${NEWTREE}$1 > ${temp}
887 rm -f ${temp}
895 if [ -z "$dryrun" ]; then
897 log "diff3 -m ${DESTDIR}$1 ${CONFLICTS}$1"
898 diff3 -m -L "yours" -L "original" -L "new" \
912 # $1 - pathname of the file to resolve (relative to DESTDIR)
916 egrep -q '^(<{7}|\|{7}|={7}|>{7}) ' $CONFLICTS/$1
926 # $1 - pathname of the file to resolve (relative to DESTDIR)
936 echo -n "Select: (p) postpone, (df) diff-full, (e) edit,"
938 echo -n " (r) resolved,"
941 echo -n " (h) help for more options: "
945 diff -u ${DESTDIR}$1 ${CONFLICTS}$1
952 (p) postpone - ignore this conflict for now
953 (df) diff-full - show all changes made to merged file
954 (e) edit - change merged file in an editor
955 (r) resolved - accept merged version of file
956 (mf) mine-full - accept local version of entire file (ignore new changes)
957 (tf) theirs-full - accept new version of entire file (lose local changes)
958 (h) help - show this list
962 # For mine-full, just delete the
964 # version of the file as-is.
991 # For theirs-full, install the new
1013 # first pass handles all non-directory files. The second pass handles
1016 # If -F is specified, and the only difference in the file in DESTDIR
1019 # $1 - pathname of the file (relative to DESTDIR)
1033 if ! [ -d $DESTDIR/$file ]; then
1053 # $1 - pathname of the directory (relative to DESTDIR)
1064 if [ -d $DESTDIR/$dir -a -d $OLDTREE/$dir ]; then
1067 if [ -z "$dryrun" ]; then
1072 warn "Non-empty directory remains: $dir"
1085 # $1 - pathname of the file (relative to DESTDIR)
1098 if [ $cmp -eq $COMPARE_EQUAL ]; then
1102 if [ $cmp -eq $COMPARE_ONLYFIRST -o $cmp -eq $COMPARE_ONLYSECOND ]; then
1108 if [ $newdestcmp -eq $COMPARE_EQUAL ]; then
1113 # file is a change in the FreeBSD ID string and -F is
1115 if [ -n "$FREEBSD_ID" -a $newdestcmp -eq $COMPARE_DIFFFILES ] && \
1125 # new file. If -F is specified and the only local change is
1134 if [ $newdestcmp -eq $COMPARE_ONLYFIRST ]; then
1139 if ! [ -d $NEWTREE/$file ]; then
1148 # file is a change in the FreeBSD ID string and -F is
1150 if [ -n "$FREEBSD_ID" -a $cmp -eq $COMPARE_DIFFFILES ] && \
1186 # change in the FreeBSD ID string and -F is specified, just
1188 if [ -n "$FREEBSD_ID" -a $cmp -eq $COMPARE_DIFFFILES ] && \
1199 if [ $cmp -eq $COMPARE_DIFFTYPE ]; then
1218 if [ $newdestcmp -eq $COMPARE_DIFFTYPE ]; then
1251 # $1 - pathname of the file (relative to DESTDIR)
1273 # created as needed when non-directory nodes
1275 if ! [ -d $NEWTREE/$file ]; then
1310 # FreeBSD ID string and -F is specified, just
1312 if [ -n "$FREEBSD_ID" ] && \
1335 if [ $# -ne 1 ]; then
1344 dir=`mktemp -d $WORKDIR/etcupdate-XXXXXXX`
1345 if [ $? -ne 0 ]; then
1354 if [ -n "$noroot" ]; then
1359 if ! tar cfj $1 -C $dir $tartree >&3 2>&1; then
1367 # Output a diff comparing the tree at DESTDIR to the current
1374 if [ $# -ne 0 ]; then
1379 if ! [ -d $NEWTREE ]; then
1386 for file in `(cd $NEWTREE; find .) | sed -e 's/^\.//'`; do
1397 # initializing the current "stock" tree to match the currently
1400 # Unlike 'update', this command does not rotate or preserve an
1405 if [ $# -ne 0 ]; then
1412 dir=`mktemp -d $WORKDIR/etcupdate-XXXXXXX`
1413 if [ $? -ne 0 ]; then
1420 if [ -d $NEWTREE ]; then
1422 echo "Unable to remove current tree."
1429 echo "Unable to rename temp tree to current tree."
1440 if [ $# -ne 0 ]; then
1444 if ! [ -d $CONFLICTS ]; then
1448 if ! [ -d $NEWTREE ]; then
1449 echo "The current tree is not present to resolve conflicts."
1453 conflicts=`(cd $CONFLICTS; find . ! -type d) | sed -e 's/^\.//'`
1458 if [ -n "$NEWALIAS_WARN" ]; then
1474 if [ $# -eq 0 ]; then
1481 if ! [ -e $NEWTREE/$file ]; then
1482 echo "File $file does not exist in the current tree."
1485 if [ -d $NEWTREE/$file ]; then
1492 if [ $cmp -eq $COMPARE_EQUAL ]; then
1499 if [ -e $CONFLICTS/$file ]; then
1515 if [ $# -ne 0 ]; then
1519 if [ -d $CONFLICTS ]; then
1520 (cd $CONFLICTS; find . ! -type d) | sed -e 's/^\./ C /'
1522 if [ -s $WARNINGS ]; then
1535 if [ $# -ne 0 ]; then
1541 if [ `id -u` -ne 0 ]; then
1553 if [ -e $CONFLICTS ]; then
1554 find -d $CONFLICTS -type d -empty -delete >&3 2>&1
1557 if [ -d $CONFLICTS ]; then
1565 if [ -z "$rerun" ]; then
1570 dir=`mktemp -d $WORKDIR/etcupdate-XXXXXXX`
1571 if [ $? -ne 0 ]; then
1581 # current stock tree.
1582 if [ -z "$preworld" ]; then
1588 if ! [ -d $OLDTREE ]; then
1593 if [ -n "$dir" ]; then
1594 if [ -n "$rerun" ]; then
1603 (cd $OLDTREE; find .) | sed -e 's/^\.//' | sort > $WORKDIR/old.files
1604 (cd $NEWTREE; find .) | sed -e 's/^\.//' | sort > $WORKDIR/new.files
1607 comm -23 $WORKDIR/old.files $WORKDIR/new.files > $WORKDIR/removed.files
1608 comm -13 $WORKDIR/old.files $WORKDIR/new.files > $WORKDIR/added.files
1609 comm -12 $WORKDIR/old.files $WORKDIR/new.files > $WORKDIR/both.files
1612 rm -f $WARNINGS
1613 mkdir -p $CONFLICTS
1618 # Ignore removed files for the pre-world case. A pre-world
1619 # update uses a stripped-down tree.
1620 if [ -n "$preworld" ]; then
1637 # depth-first traversal. This is needed to ensure that if a
1640 for file in `sort -r $WORKDIR/removed.files`; do
1655 if [ -n "$NEWALIAS_WARN" ]; then
1660 # Run any special one-off commands after an update has completed.
1663 if [ -s $WARNINGS ]; then
1670 if [ -n "$dryrun" ]; then
1671 if [ -n "$dir" ]; then
1672 if [ -n "$rerun" ]; then
1680 # Finally, rotate any needed trees.
1682 if [ -n "$rerun" ]; then
1685 if [ -z "$dir" ]; then
1689 # Rotate the old tree if needed
1691 if [ -n "$preworld" ]; then
1706 # Rotate the new tree. Remove a previous pre-world
1708 if [ -d $new ]; then
1709 if [ -z "$preworld" ]; then
1713 echo "Unable to remove previous pre-world tree."
1719 echo "Unable to rename current tree."
1729 if [ $# -gt 0 ]; then
1735 -*)
1771 # - ALWAYS_INSTALL
1772 # - DESTDIR
1773 # - EDITOR
1774 # - FREEBSD_ID
1775 # - IGNORE_FILES
1776 # - LOGFILE
1777 # - MAKE_CMD
1778 # - MAKE_OPTIONS
1779 # - SRCDIR
1780 # - WORKDIR
1781 if [ -r /etc/etcupdate.conf ]; then
1819 # multiple times, accumulate command-line
1824 set -o noglob
1839 # multiple times, accumulate command-line
1844 set -o noglob
1863 shift $((OPTIND - 1))
1865 # Allow -A command line options to override ALWAYS_INSTALL set from
1867 set -o noglob
1868 if [ -n "$always" ]; then
1872 # Allow -I command line options to override IGNORE_FILES set from the
1874 if [ -n "$ignore" ]; then
1880 WORKDIR=${WORKDIR:-$DESTDIR/var/db/etcupdate}
1884 LOGFILE=${LOGFILE:-$WORKDIR/log}
1890 NEWTREE=$WORKDIR/current
1899 EDITOR=${EDITOR:-/usr/bin/vi}
1904 # Handle command-specific argument processing such as complaining
1910 if [ -n "$rerun" -a -n "$tarball" ]; then
1911 echo "Only one of -r or -t can be specified."
1915 if [ -n "$rerun" -a -n "$preworld" ]; then
1916 echo "Only one of -p or -r can be specified."
1922 if [ -n "$dryrun" -o -n "$rerun" -o -n "$tarball" -o \
1923 -n "$preworld" ]; then
1928 if [ -n "$dryrun" -o -n "$rerun" -o -n "$tarball" ]; then
1933 if [ -n "$dryrun" -o -n "$rerun" -o -n "$preworld" ]; then
1939 # Pre-world mode uses a different set of trees. It leaves the current
1940 # tree as-is so it is still present for a full etcupdate run after the
1943 if [ -n "$preworld" ]; then
1950 if ! mkdir -p $WORKDIR 2>/dev/null; then