Page MenuHomeFreeBSD

D39188.diff
No OneTemporary

D39188.diff

Index: MOVED
===================================================================
--- MOVED
+++ MOVED
@@ -17821,3 +17821,4 @@
science/dcl||2023-03-20|Has expired: Broken since 2021
graphics/gimp-gmic-plugin||2023-03-21|Has expired: Broken since 2021
science/InsightToolkit521|science/InsightToolkit|2023-03-21|Retire InsightToolkit521: it was there only to support graphics/elastix
+sysutils/etcupdate||2023-03-21|Part of the base system since FreeBSD 10.0
Index: sysutils/Makefile
===================================================================
--- sysutils/Makefile
+++ sysutils/Makefile
@@ -356,7 +356,6 @@
SUBDIR += equinix-metal-cli
SUBDIR += etc_os-release
SUBDIR += etcmerge
- SUBDIR += etcupdate
SUBDIR += ethname
SUBDIR += evhz
SUBDIR += evisum
Index: sysutils/etcupdate/Makefile
===================================================================
--- sysutils/etcupdate/Makefile
+++ /dev/null
@@ -1,23 +0,0 @@
-PORTNAME= etcupdate
-PORTVERSION= 1.1
-CATEGORIES= sysutils
-MASTER_SITES= # none
-DISTFILES= # none
-
-MAINTAINER= jhb@FreeBSD.org
-COMMENT= Manage updates to /etc automatically
-
-LICENSE= BSD2CLAUSE
-
-NO_BUILD= yes
-NO_WRKSUBDIR= yes
-
-SRC= ${.CURDIR}/src
-
-PLIST_FILES= sbin/etcupdate man/man8/etcupdate.8.gz
-
-do-install:
- ${INSTALL_SCRIPT} ${SRC}/${PORTNAME}.sh ${STAGEDIR}${PREFIX}/sbin/${PORTNAME}
- ${INSTALL_MAN} ${SRC}/${PORTNAME}.8 ${STAGEDIR}${PREFIX}/man/man8
-
-.include <bsd.port.mk>
Index: sysutils/etcupdate/pkg-descr
===================================================================
--- sysutils/etcupdate/pkg-descr
+++ /dev/null
@@ -1,11 +0,0 @@
-The etcupdate utility is a tool for managing updates to files that are
-not updated as part of `make installworld' such as files in /etc. It
-manages updates by doing a three-way merge of changes made to these files
-against the local versions. It is also designed to minimize the amount
-of user intervention with the goal of simplifying upgrades for clusters
-of machines.
-
-The primary difference from mergemaster is that etcupdate requires less
-manual work. The primary difference from etcmerge is that etcupdate
-updates files in-place similar to mergemaster rather than building a
-separate /etc tree.
Index: sysutils/etcupdate/src/etcupdate.8
===================================================================
--- sysutils/etcupdate/src/etcupdate.8
+++ /dev/null
@@ -1,834 +0,0 @@
-.\" Copyright (c) 2010-2013 Advanced Computing Technologies LLC
-.\" Written by: John H. Baldwin <jhb@FreeBSD.org>
-.\" All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.Dd December 9, 2013
-.Dt ETCUPDATE 8
-.Os
-.Sh NAME
-.Nm etcupdate
-.Nd "manage updates to system files not updated by installworld"
-.Sh SYNOPSIS
-.Nm
-.Op Fl npBF
-.Op Fl d Ar workdir
-.Op Fl r | Fl s Ar source | Fl t Ar tarball
-.Op Fl A Ar patterns
-.Op Fl D Ar destdir
-.Op Fl I Ar patterns
-.Op Fl L Ar logfile
-.Op Fl M Ar options
-.Nm
-.Cm build
-.Op Fl B
-.Op Fl d Ar workdir
-.Op Fl s Ar source
-.Op Fl L Ar logfile
-.Op Fl M Ar options
-.Ar tarball
-.Nm
-.Cm diff
-.Op Fl d Ar workdir
-.Op Fl D Ar destdir
-.Op Fl I Ar patterns
-.Op Fl L Ar logfile
-.Nm
-.Cm extract
-.Op Fl B
-.Op Fl d Ar workdir
-.Op Fl s Ar source | Fl t Ar tarball
-.Op Fl L Ar logfile
-.Op Fl M Ar options
-.Nm
-.Cm resolve
-.Op Fl p
-.Op Fl d Ar workdir
-.Op Fl D Ar destdir
-.Op Fl L Ar logfile
-.Nm
-.Cm status
-.Op Fl d Ar workdir
-.Op Fl D Ar destdir
-.Sh DESCRIPTION
-The
-.Nm
-utility is a tool for managing updates to files that are not updated as
-part of
-.Sq make installworld
-such as files in
-.Pa /etc .
-It manages updates by doing a three-way merge of changes made to these
-files against the local versions.
-It is also designed to minimize the amount of user intervention with
-the goal of simplifying upgrades for clusters of machines.
-.Pp
-To perform a three-way merge,
-.Nm
-keeps copies of the current and previous versions of files that it manages.
-These copies are stored in two trees known as the
-.Dq current
-and
-.Dq previous
-trees.
-During a merge,
-.Nm
-compares the
-.Dq current
-and
-.Dq previous
-copies of each file to determine which changes need to be merged into the
-local version of each file.
-If a file can be updated without generating a conflict,
-.Nm
-will update the file automatically.
-If the local changes to a file conflict with the changes made to a file in
-the source tree,
-then a merge conflict is generated.
-The conflict must be resolved after the merge has finished.
-The
-.Nm
-utility will not perform a new merge until all conflicts from an earlier
-merge are resolved.
-.Sh MODES
-The
-.Nm
-utility supports several modes of operation.
-The mode is specified via an optional command argument.
-If present, the command must be the first argument on the command line.
-If a command is not specified, the default mode is used.
-.Ss Default Mode
-The default mode merges changes from the source tree to the destination
-directory.
-First,
-it updates the
-.Dq current
-and
-.Dq previous
-trees.
-Next,
-it compares the two trees merging changes into the destination directory.
-Finally,
-it displays warnings for any conditions it could not handle automatically.
-.Pp
-If the
-.Fl r
-option is not specified,
-then the first step taken is to update the
-.Dq current
-and
-.Dq previous
-trees.
-If a
-.Dq current
-tree already exists,
-then that tree is saved as the
-.Dq previous
-tree.
-An older
-.Dq previous
-tree is removed if it exists.
-By default the new
-.Dq current
-tree is built from a source tree.
-However,
-if a tarball is specified via the
-.Fl t
-option,
-then the tree is extracted from that tarball instead.
-.Pp
-Next,
-.Nm
-compares the files in the
-.Dq current
-and
-.Dq previous
-trees.
-If a file was removed from the
-.Dq current
-tree,
-then it will be removed from the destination directory only if it
-does not have any local modifications.
-If a file was added to the
-.Dq current
-tree,
-then it will be copied to the destination directory only if it
-would not clobber an existing file.
-If a file is changed in the
-.Dq current
-tree,
-then
-.Nm
-will attempt to merge the changes into the version of the file in the
-destination directory.
-If the merge encounters conflicts,
-then a version of the file with conflict markers will be saved for
-future resolution.
-If the merge does not encounter conflicts,
-then the merged version of the file will be saved in the destination
-directory.
-If
-.Nm
-is not able to safely merge in changes to a file other than a merge conflict,
-it will generate a warning.
-.Pp
-For each file that is updated a line will be output with a leading character
-to indicate the action taken.
-The possible actions follow:
-.Pp
-.Bl -tag -width "A" -compact -offset indent
-.It A
-Added
-.It C
-Conflict
-.It D
-Deleted
-.It M
-Merged
-.It U
-Updated
-.El
-.Pp
-Finally,
-if any warnings were encountered they are displayed after the merge has
-completed.
-.Pp
-Note that for certain files
-.Nm
-will perform post-install actions any time that the file is updated.
-Specifically,
-.Xr pwd_mkdb 8
-is invoked if
-.Pa /etc/master.passwd
-is changed,
-.Xr cap_mkdb 1
-is invoked to update
-.Pa /etc/login.conf.db
-if
-.Pa /etc/login.conf
-is changed,
-.Xr newaliases 1
-is invoked if
-.Pa /etc/mail/aliases
-is changed,
-and
-.Pa /etc/rc.d/motd
-is invoked if
-.Pa /etc/motd
-is changed.
-One exception is that if
-.Pa /etc/mail/aliases
-is changed and the destination directory is not the default,
-then a warning will be issued instead.
-This is due to a limitation of the
-.Xr newaliases 1
-command.
-Similarly,
-if
-.Pa /etc/motd
-is changed and the destination directory is not the default,
-then
-.Pa /etc/rc.d/motd
-will not be executed due to a limitation of that script.
-In this case no warning is issued as the result of
-.Pa /etc/rc.d/motd
-is merely cosmetic and will be corrected on the next reboot.
-.Ss Build Mode
-The
-.Cm build
-mode is used to build a tarball that contains a snapshot of a
-.Dq current
-tree.
-This tarball can be used by the default and extract modes.
-Using a tarball can allow
-.Nm
-to perform a merge without requiring a source tree that matches the
-currently installed world.
-The
-.Fa tarball
-argument specifies the name of the file to create.
-The file will be a
-.Xr tar 5
-file compressed with
-.Xr bzip2 1 .
-.Ss Diff Mode
-The
-.Cm diff
-mode compares the versions of files in the destination directory to the
-.Dq current
-tree and generates a unified format diff of the changes.
-This can be used to determine which files have been locally modified and how.
-Note that
-.Nm
-does not manage files that are not maintained in the source tree such as
-.Pa /etc/fstab
-and
-.Pa /etc/rc.conf .
-.Ss Extract Mode
-The
-.Cm extract
-mode generates a new
-.Dq current
-tree.
-Unlike the default mode,
-it does not save any existing
-.Dq current
-tree and does not modify any existing
-.Dq previous
-tree.
-The new
-.Dq current
-tree can either be built from a source tree or extracted from a tarball.
-.Ss Resolve Mode
-The
-.Cm resolve
-mode is used to resolve any conflicts encountered during a merge.
-In this mode,
-.Nm
-iterates over any existing conflicts prompting the user for actions to take
-on each conflicted file.
-For each file, the following actions are available:
-.Pp
-.Bl -tag -width "(tf) theirs-full" -compact
-.It (p) postpone
-Ignore this conflict for now.
-.It (df) diff-full
-Show all changes made to the merged file as a unified diff.
-.It (e) edit
-Change the merged file in an editor.
-.It (r) resolved
-Install the merged version of the file into the destination directory.
-.It (mf) mine-full
-Use the version of the file in the destination directory and ignore any
-changes made to the file in the
-.Dq current
-tree.
-.It (tf) theirs-full
-Use the version of the file from the
-.Dq current
-tree and discard any local changes made to the file.
-.It (h) help
-Display the list of commands.
-.El
-.Ss Status Mode
-The
-.Cm status
-mode shows a summary of the results of the most recent merge.
-First it lists any files for which there are unresolved conflicts.
-Next it lists any warnings generated during the last merge.
-If the last merge did not generate any conflicts or warnings,
-then nothing will be output.
-.Sh OPTIONS
-The following options are available.
-Note that most options do not apply to all modes.
-.Bl -tag -width ".Fl A Ar patterns"
-.It Fl A Ar patterns
-Always install the new version of any files that match any of the patterns
-listed in
-.Ar patterns .
-Each pattern is evaluated as an
-.Xr sh 1
-shell pattern.
-This option may be specified multiple times to specify multiple patterns.
-Multiple space-separated patterns may also be specified in a single
-option.
-Note that ignored files specified via the
-.Ev IGNORE_FILES
-variable or the
-.Fl I
-option will not be installed.
-.It Fl B
-Do not build generated files in a private object tree.
-Instead,
-reuse the generated files from a previously built object tree that matches
-the source tree.
-This can be useful to avoid gratuitous conflicts in
-.Xr sendmail 8
-configuration
-files when bootstrapping.
-It can also be useful for building a tarball that matches a specific
-world build.
-.It Fl D Ar destdir
-Specify an alternate destination directory as the target of a merge.
-This is analogous to the
-.Dv DESTDIR
-variable used with
-.Sq make installworld .
-The default destination directory is an empty string which results in
-merges updating
-.Pa /etc
-on the local machine.
-.It Fl d Ar workdir
-Specify an alternate directory to use as the work directory.
-The work directory is used to store the
-.Dq current
-and
-.Dq previous
-trees as well as unresolved conflicts.
-The default work directory is
-.Pa <destdir>/var/db/etcupdate .
-.It Fl F
-Ignore changes in the FreeBSD ID string when comparing files in the
-destination directory to files in either of the
-.Dq current
-or
-.Dq previous
-trees.
-In
-.Cm diff
-mode,
-this reduces noise due to FreeBSD ID string changes in the output.
-During an update this can simplify handling for harmless conflicts caused
-by FreeBSD ID string changes.
-.Pp
-Specifically,
-if a file in the destination directory is identical to the same file in the
-.Dq previous
-tree modulo the FreeBSD ID string,
-then the file is treated as if it was unmodified and the
-.Dq current
-version of the file will be installed.
-Similarly,
-if a file in the destination directory is identical to the same file in the
-.Dq current
-tree modulo the FreeBSD ID string,
-then the
-.Dq current
-version of the file will be installed to update the ID string.
-If the
-.Dq previous
-and
-.Dq current
-versions of the file are identical,
-then
-.Nm
-will not change the file in the destination directory.
-.Pp
-Due to limitations in the
-.Xr diff 1
-command,
-this option may not have an effect if there are other changes in a file that
-are close to the FreeBSD ID string.
-.It Fl I Ar patterns
-Ignore any files that match any of the patterns listed in
-.Ar patterns .
-No warnings or other messages will be generated for those files during a
-merge.
-Each pattern is evaluated as an
-.Xr sh 1
-shell pattern.
-This option may be specified multiple times to specify multiple patterns.
-Multiple space-separated patterns may also be specified in a single
-option.
-.It Fl L Ar logfile
-Specify an alternate path for the log file.
-The
-.Nm
-utility logs each command that it invokes along with the standard output
-and standard error to this file.
-By default the log file is stored in a file named
-.Pa log
-in the work directory.
-.It Fl M Ar options
-Pass
-.Ar options
-as additional parameters to
-.Xr make 1
-when building a
-.Dq current
-tree.
-This can be used for to set the
-.Dv TARGET
-or
-.Dv TARGET_ARCH
-variables for a cross-build.
-.It Fl n
-Enable
-.Dq dry-run
-mode.
-Do not merge any changes to the destination directory.
-Instead,
-report what actions would be taken during a merge.
-Note that the existing
-.Dq current
-and
-.Dq previous
-trees will not be changed.
-If the
-.Fl r
-option is not specified,
-then a temporary
-.Dq current
-tree will be extracted to perform the comparison.
-.It Fl p
-Enable
-.Dq pre-world
-mode.
-Only merge changes to files that are necessary to successfully run
-.Sq make installworld
-or
-.Sq make installkernel .
-When this flag is enabled,
-the existing
-.Dq current
-and
-.Dq previous
-trees are left alone.
-Instead,
-a temporary tree is populated with the necessary files.
-This temporary tree is compared against the
-.Dq current
-tree.
-This allows a normal update to be run after
-.Sq make installworld
-has completed.
-Any conflicts generated during a
-.Dq pre-world
-update should be resolved by a
-.Dq pre-world
-.Cm resolve .
-.It Fl r
-Do not update the
-.Dq current
-and
-.Dq previous
-trees during a merge.
-This can be used to
-.Dq re-run
-a previous merge operation.
-.It Fl s Ar source
-Specify an alternate source tree to use when building or extracting a
-.Dq current
-tree.
-The default source tree is
-.Pa /usr/src .
-.It Fl t Ar tarball
-Extract a new
-.Dq current
-tree from a tarball previously generated by the
-.Cm build
-command rather than building the tree from a source tree.
-.El
-.Sh CONFIG FILE
-The
-.Nm
-utility can also be configured by setting variables in an optional
-configuration file named
-.Pa /etc/etcupdate.conf .
-Note that command line options override settings in the configuration file.
-The configuration file is executed by
-.Xr sh 1 ,
-so it uses that syntax to set configuration variables.
-The following variables can be set:
-.Bl -tag -width ".Ev ALWAYS_INSTALL"
-.It Ev ALWAYS_INSTALL
-Always install files that match any of the patterns listed in this variable
-similar to the
-.Fl A
-option.
-.It Ev DESTDIR
-Specify an alternate destination directory similar to the
-.Fl D
-option.
-.It Ev EDITOR
-Specify a program to edit merge conflicts.
-.It Ev FREEBSD_ID
-Ignore changes in the FreeBSD ID string similar to the
-.Fl F
-option.
-This is enabled by setting the variable to a non-empty value.
-.It Ev IGNORE_FILES
-Ignore files that match any of the patterns listed in this variable
-similar to the
-.Fl I
-option.
-.It Ev LOGFILE
-Specify an alternate path for the log file similar to the
-.Fl L
-option.
-.It Ev MAKE_OPTIONS
-Pass additional options to
-.Xr make 1
-when building a
-.Dq current
-tree similar to the
-.Fl M
-option.
-.It Ev SRCDIR
-Specify an alternate source tree similar to the
-.Fl s
-option.
-.It Ev WORKDIR
-Specify an alternate work directory similar to the
-.Fl d
-option.
-.El
-.Sh ENVIRONMENT
-The
-.Nm
-utility uses the program identified in the
-.Ev EDITOR
-environment variable to edit merge conflicts.
-If
-.Ev EDITOR
-is not set,
-.Xr vi 1
-is used as the default editor.
-.Sh FILES
-.Bl -tag -width ".Pa /var/db/etcupdate/log" -compact
-.It Pa /etc/etcupdate.conf
-Optional config file.
-.It Pa /var/db/etcupdate
-Default work directory used to store trees and other data.
-.It Pa /var/db/etcupdate/log
-Default log file.
-.El
-.Sh EXIT STATUS
-.Ex -std
-.Sh EXAMPLES
-If the source tree matches the currently installed world,
-then the following can be used to bootstrap
-.Nm
-so that it can be used for future upgrades:
-.Pp
-.Dl "etcupdate extract"
-.Pp
-To merge changes after an upgrade via the buildworld and installworld process:
-.Pp
-.Dl "etcupdate"
-.Pp
-To resolve any conflicts generated during a merge:
-.Pp
-.Dl "etcupdate resolve"
-.Sh DIAGNOSTICS
-The following warning messages may be generated during a merge.
-Note that several of these warnings cover obscure cases that should occur
-rarely if at all in practice.
-For example,
-if a file changes from a file to a directory in the
-.Dq current
-tree
-and the file was modified in the destination directory,
-then a warning will be triggered.
-In general,
-when a warning references a pathname,
-the corresponding file in the destination directory is not changed by a
-merge operation.
-.Bl -diag
-.It "Directory mismatch: <path> (<type>)"
-An attempt was made to create a directory at
-.Pa path
-but an existing file of type
-.Dq type
-already exists for that path name.
-.It "Modified link changed: <file> (<old> became <new>)"
-The target of a symbolic link named
-.Pa file
-was changed from
-.Dq old
-to
-.Dq new
-in the
-.Dq current
-tree.
-The symbolic link has been modified to point to a target that is neither
-.Dq old
-nor
-.Dq new
-in the destination directory.
-.It "Modified mismatch: <file> (<new> vs <dest>)"
-A file named
-.Pa file
-of type
-.Dq new
-was modified in the
-.Dq current
-tree,
-but the file exists as a different type
-.Dq dest
-in the destination directory.
-.It "Modified <type> changed: <file> (<old> became <new>)"
-A file named
-.Pa file
-changed type from
-.Dq old
-in the
-.Dq previous
-tree to type
-.Dq new
-in the
-.Dq current
-tree.
-The file in the destination directory of type
-.Dq type
-has been modified,
-so it could not be merged automatically.
-.It "Modified <type> remains: <file>"
-The file of type
-.Dq type
-named
-.Pa file
-has been removed from the
-.Dq current
-tree,
-but it has been locally modified.
-The modified version of the file remains in the destination directory.
-.It "Needs update: /etc/localtime (required manual update via tzsetup(1))"
-The
-.Fa /var/db/zoneinfo
-file does not exist,
-so
-.Nm
-was not able to refresh
-.Fa /etc/localtime
-from its source file in
-.Fa /usr/share/zoneinfo .
-Running
-.Xr tzsetup 1
-will both refresh
-.Fa /etc/localtime
-and generate
-.Fa /var/db/zoneinfo
-permitting future updates to refresh
-.Fa /etc/localtime
-automatically.
-.It "Needs update: /etc/mail/aliases.db (required manual update via newaliases(1))"
-The file
-.Pa /etc/mail/aliases
-was updated during a merge with a non-empty destination directory.
-Due to a limitation of the
-.Xr newaliases 1
-command,
-.Nm
-was not able to automatically update the corresponding aliases database.
-.It "New file mismatch: <file> (<new> vs <dest>)"
-A new file named
-.Pa file
-of type
-.Dq new
-has been added to the
-.Dq current
-tree.
-A file of that name already exists in the destination directory,
-but it is of a different type
-.Dq dest .
-.It "New link conflict: <file> (<new> vs <dest>)"
-A symbolic link named
-.Pa file
-has been added to the
-.Dq current
-tree that links to
-.Dq new .
-A symbolic link of the same name already exists in the destination
-directory,
-but it links to a different target
-.Dq dest .
-.It "Non-empty directory remains: <file>"
-The directory
-.Pa file
-was removed from the
-.Dq current
-tree,
-but it contains additional files in the destination directory.
-These additional files as well as the directory remain.
-.It "Remove mismatch: <file> (<old> became <new>)"
-A file named
-.Pa file
-changed from type
-.Dq old
-in the
-.Dq previous
-tree to type
-.Dq new
-in the
-.Dq current
-tree,
-but it has been removed in the destination directory.
-.It "Removed file changed: <file>"
-A file named
-.Pa file
-was modified in the
-.Dq current
-tree,
-but it has been removed in the destination directory.
-.It "Removed link changed: <file> (<old> became <new>)"
-The target of a symbolic link named
-.Pa file
-was changed from
-.Dq old
-to
-.Dq new
-in the
-.Dq current
-tree,
-but it has been removed in the destination directory.
-.El
-.Sh SEE ALSO
-.Xr cap_mkdb 1 ,
-.Xr diff 1 ,
-.Xr make 1 ,
-.Xr newaliases 1 ,
-.Xr sh 1 ,
-.Xr pwd_mkdb 8
-.Sh HISTORY
-The
-.Nm
-utility first appeared in
-.Fx 10.0 .
-.Sh AUTHORS
-The
-.Nm
-utility was written by
-.An John Baldwin Aq jhb@FreeBSD.org .
-.Sh BUGS
-Rerunning a merge does not automatically delete conflicts left over from a
-previous merge.
-Any conflicts must be resolved before the merge can be rerun.
-It it is not clear if this is a feature or a bug.
-.Pp
-There is no way to easily automate conflict resolution for specific files.
-For example, one can imagine a syntax along the lines of
-.Pp
-.Dl "etcupdate resolve tf /some/file"
-.Pp
-to resolve a specific conflict in an automated fashion.
-.Pp
-It might be nice to have something like a
-.Sq revert
-command to replace a locally modified version of a file with the stock
-version of the file.
-For example:
-.Pp
-.Dl "etcupdate revert /etc/mail/freebsd.cf"
-.Pp
-Bootstrapping
-.Nm
-often results in gratuitous diffs in
-.Pa /etc/mail/*.cf
-that cause conflicts in the first merge.
-If an object tree that matches the source tree is present when bootstrapping,
-then passing the
-.Fl B
-flag to the
-.Cm extract
-command can work around this.
Index: sysutils/etcupdate/src/etcupdate.sh
===================================================================
--- sysutils/etcupdate/src/etcupdate.sh
+++ /dev/null
@@ -1,1792 +0,0 @@
-#!/bin/sh
-#
-# Copyright (c) 2010-2013 Advanced Computing Technologies LLC
-# Written by: John H. Baldwin <jhb@FreeBSD.org>
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions
-# are met:
-# 1. Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-# 2. Redistributions in binary form must reproduce the above copyright
-# notice, this list of conditions and the following disclaimer in the
-# documentation and/or other materials provided with the distribution.
-#
-# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
-# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-# SUCH DAMAGE.
-
-# This is a tool to manage updating files that are not updated as part
-# of 'make installworld' such as files in /etc. Unlike other tools,
-# this one is specifically tailored to assisting with mass upgrades.
-# To that end it does not require user intervention while running.
-#
-# Theory of operation:
-#
-# The most reliable way to update changes to files that have local
-# modifications is to perform a three-way merge between the original
-# unmodified file, the new version of the file, and the modified file.
-# This requires having all three versions of the file available when
-# performing an update.
-#
-# To that end, etcupdate uses a strategy where the current unmodified
-# tree is kept in WORKDIR/current and the previous unmodified tree is
-# kept in WORKDIR/old. When performing a merge, a new tree is built
-# if needed and then the changes are merged into DESTDIR. Any files
-# with unresolved conflicts after the merge are left in a tree rooted
-# at WORKDIR/conflicts.
-#
-# To provide extra flexibility, etcupdate can also build tarballs of
-# root trees that can later be used. It can also use a tarball as the
-# source of a new tree instead of building it from /usr/src.
-
-# Global settings. These can be adjusted by config files and in some
-# cases by command line options.
-
-# TODO:
-# - automatable conflict resolution
-# - a 'revert' command to make a file "stock"
-
-usage()
-{
- cat <<EOF
-usage: etcupdate [-npBF] [-d workdir] [-r | -s source | -t tarball]
- [-A patterns] [-D destdir] [-I patterns] [-L logfile]
- [-M options]
- etcupdate build [-B] [-d workdir] [-s source] [-L logfile] [-M options]
- <tarball>
- etcupdate diff [-d workdir] [-D destdir] [-I patterns] [-L logfile]
- etcupdate extract [-B] [-d workdir] [-s source | -t tarball] [-L logfile]
- [-M options]
- etcupdate resolve [-p] [-d workdir] [-D destdir] [-L logfile]
- etcupdate status [-d workdir] [-D destdir]
-EOF
- exit 1
-}
-
-# Used to write a message prepended with '>>>' to the logfile.
-log()
-{
- echo ">>>" "$@" >&3
-}
-
-# Used for assertion conditions that should never happen.
-panic()
-{
- echo "PANIC:" "$@"
- exit 10
-}
-
-# Used to write a warning message. These are saved to the WARNINGS
-# file with " " prepended.
-warn()
-{
- echo -n " " >> $WARNINGS
- echo "$@" >> $WARNINGS
-}
-
-# Output a horizontal rule using the passed-in character. Matches the
-# length used for Index lines in CVS and SVN diffs.
-#
-# $1 - character
-rule()
-{
- jot -b "$1" -s "" 67
-}
-
-# Output a text description of a specified file's type.
-#
-# $1 - file pathname.
-file_type()
-{
- stat -f "%HT" $1 | tr "[:upper:]" "[:lower:]"
-}
-
-# Returns true (0) if a file exists
-#
-# $1 - file pathname.
-exists()
-{
- [ -e $1 -o -L $1 ]
-}
-
-# Returns true (0) if a file should be ignored, false otherwise.
-#
-# $1 - file pathname
-ignore()
-{
- local pattern -
-
- set -o noglob
- for pattern in $IGNORE_FILES; do
- set +o noglob
- case $1 in
- $pattern)
- return 0
- ;;
- esac
- set -o noglob
- done
-
- # Ignore /.cshrc and /.profile if they are hardlinked to the
- # same file in /root. This ensures we only compare those
- # files once in that case.
- case $1 in
- /.cshrc|/.profile)
- if [ ${DESTDIR}$1 -ef ${DESTDIR}/root$1 ]; then
- return 0
- fi
- ;;
- *)
- ;;
- esac
-
- return 1
-}
-
-# Returns true (0) if the new version of a file should always be
-# installed rather than attempting to do a merge.
-#
-# $1 - file pathname
-always_install()
-{
- local pattern -
-
- set -o noglob
- for pattern in $ALWAYS_INSTALL; do
- set +o noglob
- case $1 in
- $pattern)
- return 0
- ;;
- esac
- set -o noglob
- done
-
- return 1
-}
-
-# Build a new tree
-#
-# $1 - directory to store new tree in
-build_tree()
-{
- local destdir dir file make
-
- make="make $MAKE_OPTIONS"
-
- log "Building tree at $1 with $make"
- mkdir -p $1/usr/obj >&3 2>&1
- destdir=`realpath $1`
-
- if [ -n "$preworld" ]; then
- # Build a limited tree that only contains files that are
- # crucial to installworld.
- for file in $PREWORLD_FILES; do
- dir=`dirname /$file`
- mkdir -p $1/$dir >&3 2>&1 || return 1
- cp -p $SRCDIR/$file $1/$file || return 1
- done
- elif ! [ -n "$nobuild" ]; then
- (cd $SRCDIR; $make DESTDIR=$destdir distrib-dirs &&
- MAKEOBJDIRPREFIX=$destdir/usr/obj $make _obj SUBDIR_OVERRIDE=etc &&
- MAKEOBJDIRPREFIX=$destdir/usr/obj $make everything SUBDIR_OVERRIDE=etc &&
- MAKEOBJDIRPREFIX=$destdir/usr/obj $make DESTDIR=$destdir distribution) \
- >&3 2>&1 || return 1
- else
- (cd $SRCDIR; $make DESTDIR=$destdir distrib-dirs &&
- $make DESTDIR=$destdir distribution) >&3 2>&1 || return 1
- fi
- chflags -R noschg $1 >&3 2>&1 || return 1
- rm -rf $1/usr/obj >&3 2>&1 || return 1
-
- # Purge auto-generated files. Only the source files need to
- # be updated after which these files are regenerated.
- rm -f $1/etc/*.db $1/etc/passwd >&3 2>&1 || return 1
-
- # Remove empty files. These just clutter the output of 'diff'.
- find $1 -type f -size 0 -delete >&3 2>&1 || return 1
-
- # Trim empty directories.
- find -d $1 -type d -empty -delete >&3 2>&1 || return 1
- return 0
-}
-
-# Generate a new NEWTREE tree. If tarball is set, then the tree is
-# extracted from the tarball. Otherwise the tree is built from a
-# source tree.
-extract_tree()
-{
- local files
-
- # If we have a tarball, extract that into the new directory.
- if [ -n "$tarball" ]; then
- files=
- if [ -n "$preworld" ]; then
- files="$PREWORLD_FILES"
- fi
- if ! (mkdir -p $NEWTREE && tar xf $tarball -C $NEWTREE $files) \
- >&3 2>&1; then
- echo "Failed to extract new tree."
- remove_tree $NEWTREE
- exit 1
- fi
- else
- if ! build_tree $NEWTREE; then
- echo "Failed to build new tree."
- remove_tree $NEWTREE
- exit 1
- fi
- fi
-}
-
-# Forcefully remove a tree. Returns true (0) if the operation succeeds.
-#
-# $1 - path to tree
-remove_tree()
-{
-
- rm -rf $1 >&3 2>&1
- if [ -e $1 ]; then
- chflags -R noschg $1 >&3 2>&1
- rm -rf $1 >&3 2>&1
- fi
- [ ! -e $1 ]
-}
-
-# Return values for compare()
-COMPARE_EQUAL=0
-COMPARE_ONLYFIRST=1
-COMPARE_ONLYSECOND=2
-COMPARE_DIFFTYPE=3
-COMPARE_DIFFLINKS=4
-COMPARE_DIFFFILES=5
-
-# Compare two files/directories/symlinks. Note that this does not
-# recurse into subdirectories. Instead, if two nodes are both
-# directories, they are assumed to be equivalent.
-#
-# Returns true (0) if the nodes are identical. If only one of the two
-# nodes are present, return one of the COMPARE_ONLY* constants. If
-# the nodes are different, return one of the COMPARE_DIFF* constants
-# to indicate the type of difference.
-#
-# $1 - first node
-# $2 - second node
-compare()
-{
- local first second
-
- # If the first node doesn't exist, then check for the second
- # node. Note that -e will fail for a symbolic link that
- # points to a missing target.
- if ! exists $1; then
- if exists $2; then
- return $COMPARE_ONLYSECOND
- else
- return $COMPARE_EQUAL
- fi
- elif ! exists $2; then
- return $COMPARE_ONLYFIRST
- fi
-
- # If the two nodes are different file types fail.
- first=`stat -f "%Hp" $1`
- second=`stat -f "%Hp" $2`
- if [ "$first" != "$second" ]; then
- return $COMPARE_DIFFTYPE
- fi
-
- # If both are symlinks, compare the link values.
- if [ -L $1 ]; then
- first=`readlink $1`
- second=`readlink $2`
- if [ "$first" = "$second" ]; then
- return $COMPARE_EQUAL
- else
- return $COMPARE_DIFFLINKS
- fi
- fi
-
- # If both are files, compare the file contents.
- if [ -f $1 ]; then
- if cmp -s $1 $2; then
- return $COMPARE_EQUAL
- else
- return $COMPARE_DIFFFILES
- fi
- fi
-
- # As long as the two nodes are the same type of file, consider
- # them equivalent.
- return $COMPARE_EQUAL
-}
-
-# Returns true (0) if the only difference between two regular files is a
-# change in the FreeBSD ID string.
-#
-# $1 - path of first file
-# $2 - path of second file
-fbsdid_only()
-{
-
- diff -qI '\$FreeBSD.*\$' $1 $2 >/dev/null 2>&1
-}
-
-# This is a wrapper around compare that will return COMPARE_EQUAL if
-# the only difference between two regular files is a change in the
-# FreeBSD ID string. It only makes this adjustment if the -F flag has
-# been specified.
-#
-# $1 - first node
-# $2 - second node
-compare_fbsdid()
-{
- local cmp
-
- compare $1 $2
- cmp=$?
-
- if [ -n "$FREEBSD_ID" -a "$cmp" -eq $COMPARE_DIFFFILES ] && \
- fbsdid_only $1 $2; then
- return $COMPARE_EQUAL
- fi
-
- return $cmp
-}
-
-# Returns true (0) if a directory is empty.
-#
-# $1 - pathname of the directory to check
-empty_dir()
-{
- local contents
-
- contents=`ls -A $1`
- [ -z "$contents" ]
-}
-
-# Returns true (0) if one directories contents are a subset of the
-# other. This will recurse to handle subdirectories and compares
-# individual files in the trees. Its purpose is to quiet spurious
-# directory warnings for dryrun invocations.
-#
-# $1 - first directory (sub)
-# $2 - second directory (super)
-dir_subset()
-{
- local contents file
-
- if ! [ -d $1 -a -d $2 ]; then
- return 1
- fi
-
- # Ignore files that are present in the second directory but not
- # in the first.
- contents=`ls -A $1`
- for file in $contents; do
- if ! compare $1/$file $2/$file; then
- return 1
- fi
-
- if [ -d $1/$file ]; then
- if ! dir_subset $1/$file $2/$file; then
- return 1
- fi
- fi
- done
- return 0
-}
-
-# Returns true (0) if a directory in the destination tree is empty.
-# If this is a dryrun, then this returns true as long as the contents
-# of the directory are a subset of the contents in the old tree
-# (meaning that the directory would be empty in a non-dryrun when this
-# was invoked) to quiet spurious warnings.
-#
-# $1 - pathname of the directory to check relative to DESTDIR.
-empty_destdir()
-{
-
- if [ -n "$dryrun" ]; then
- dir_subset $DESTDIR/$1 $OLDTREE/$1
- return
- fi
-
- empty_dir $DESTDIR/$1
-}
-
-# Output a diff of two directory entries with the same relative name
-# in different trees. Note that as with compare(), this does not
-# recurse into subdirectories. If the nodes are identical, nothing is
-# output.
-#
-# $1 - first tree
-# $2 - second tree
-# $3 - node name
-# $4 - label for first tree
-# $5 - label for second tree
-diffnode()
-{
- local first second file old new diffargs
-
- if [ -n "$FREEBSD_ID" ]; then
- diffargs="-I \\\$FreeBSD.*\\\$"
- else
- diffargs=""
- fi
-
- compare_fbsdid $1/$3 $2/$3
- case $? in
- $COMPARE_EQUAL)
- ;;
- $COMPARE_ONLYFIRST)
- echo
- echo "Removed: $3"
- echo
- ;;
- $COMPARE_ONLYSECOND)
- echo
- echo "Added: $3"
- echo
- ;;
- $COMPARE_DIFFTYPE)
- first=`file_type $1/$3`
- second=`file_type $2/$3`
- echo
- echo "Node changed from a $first to a $second: $3"
- echo
- ;;
- $COMPARE_DIFFLINKS)
- first=`readlink $1/$file`
- second=`readlink $2/$file`
- echo
- echo "Link changed: $file"
- rule "="
- echo "-$first"
- echo "+$second"
- echo
- ;;
- $COMPARE_DIFFFILES)
- echo "Index: $3"
- rule "="
- diff -u $diffargs -L "$3 ($4)" $1/$3 -L "$3 ($5)" $2/$3
- ;;
- esac
-}
-
-# Run one-off commands after an update has completed. These commands
-# are not tied to a specific file, so they cannot be handled by
-# post_install_file().
-post_update()
-{
- local args
-
- # None of these commands should be run for a pre-world update.
- if [ -n "$preworld" ]; then
- return
- fi
-
- # If /etc/localtime exists and is not a symlink and /var/db/zoneinfo
- # exists, run tzsetup -r to refresh /etc/localtime.
- if [ -f ${DESTDIR}/etc/localtime -a \
- ! -L ${DESTDIR}/etc/localtime ]; then
- if [ -f ${DESTDIR}/var/db/zoneinfo ]; then
- if [ -n "${DESTDIR}" ]; then
- args="-C ${DESTDIR}"
- else
- args=""
- fi
- log "tzsetup -r ${args}"
- if [ -z "$dryrun" ]; then
- tzsetup -r ${args} >&3 2>&1
- fi
- else
- warn "Needs update: /etc/localtime (required" \
- "manual update via tzsetup(1))"
- fi
- fi
-}
-
-# Create missing parent directories of a node in a target tree
-# preserving the owner, group, and permissions from a specified
-# template tree.
-#
-# $1 - template tree
-# $2 - target tree
-# $3 - pathname of the node (relative to both trees)
-install_dirs()
-{
- local args dir
-
- dir=`dirname $3`
-
- # Nothing to do if the parent directory exists. This also
- # catches the degenerate cases when the path is just a simple
- # filename.
- if [ -d ${2}$dir ]; then
- return 0
- fi
-
- # If non-directory file exists with the desired directory
- # name, then fail.
- if exists ${2}$dir; then
- # If this is a dryrun and we are installing the
- # directory in the DESTDIR and the file in the DESTDIR
- # matches the file in the old tree, then fake success
- # to quiet spurious warnings.
- if [ -n "$dryrun" -a "$2" = "$DESTDIR" ]; then
- if compare $OLDTREE/$dir $DESTDIR/$dir; then
- return 0
- fi
- fi
-
- args=`file_type ${2}$dir`
- warn "Directory mismatch: ${2}$dir ($args)"
- return 1
- fi
-
- # Ensure the parent directory of the directory is present
- # first.
- if ! install_dirs $1 "$2" $dir; then
- return 1
- fi
-
- # Format attributes from template directory as install(1)
- # arguments.
- args=`stat -f "-o %Su -g %Sg -m %0Mp%0Lp" $1/$dir`
-
- log "install -d $args ${2}$dir"
- if [ -z "$dryrun" ]; then
- install -d $args ${2}$dir >&3 2>&1
- fi
- return 0
-}
-
-# Perform post-install fixups for a file. This largely consists of
-# regenerating any files that depend on the newly installed file.
-#
-# $1 - pathname of the updated file (relative to DESTDIR)
-post_install_file()
-{
- case $1 in
- /etc/mail/aliases)
- # Grr, newaliases only works for an empty DESTDIR.
- if [ -z "$DESTDIR" ]; then
- log "newaliases"
- if [ -z "$dryrun" ]; then
- newaliases >&3 2>&1
- fi
- else
- NEWALIAS_WARN=yes
- fi
- ;;
- /etc/login.conf)
- log "cap_mkdb ${DESTDIR}$1"
- if [ -z "$dryrun" ]; then
- cap_mkdb ${DESTDIR}$1 >&3 2>&1
- fi
- ;;
- /etc/master.passwd)
- log "pwd_mkdb -p -d $DESTDIR/etc ${DESTDIR}$1"
- if [ -z "$dryrun" ]; then
- pwd_mkdb -p -d $DESTDIR/etc ${DESTDIR}$1 \
- >&3 2>&1
- fi
- ;;
- /etc/motd)
- # /etc/rc.d/motd hardcodes the /etc/motd path.
- # Don't warn about non-empty DESTDIR's since this
- # change is only cosmetic anyway.
- if [ -z "$DESTDIR" ]; then
- log "sh /etc/rc.d/motd start"
- if [ -z "$dryrun" ]; then
- sh /etc/rc.d/motd start >&3 2>&1
- fi
- fi
- ;;
- /etc/services)
- log "services_mkdb -q -o $DESTDIR/var/db/services.db" \
- "${DESTDIR}$1"
- if [ -z "$dryrun" ]; then
- services_mkdb -q -o $DESTDIR/var/db/services.db \
- ${DESTDIR}$1 >&3 2>&1
- fi
- ;;
- esac
-}
-
-# Install the "new" version of a file. Returns true if it succeeds
-# and false otherwise.
-#
-# $1 - pathname of the file to install (relative to DESTDIR)
-install_new()
-{
-
- if ! install_dirs $NEWTREE "$DESTDIR" $1; then
- return 1
- fi
- log "cp -Rp ${NEWTREE}$1 ${DESTDIR}$1"
- if [ -z "$dryrun" ]; then
- cp -Rp ${NEWTREE}$1 ${DESTDIR}$1 >&3 2>&1
- fi
- post_install_file $1
- return 0
-}
-
-# Install the "resolved" version of a file. Returns true if it succeeds
-# and false otherwise.
-#
-# $1 - pathname of the file to install (relative to DESTDIR)
-install_resolved()
-{
-
- # This should always be present since the file is already
- # there (it caused a conflict). However, it doesn't hurt to
- # just be safe.
- if ! install_dirs $NEWTREE "$DESTDIR" $1; then
- return 1
- fi
-
- log "cp -Rp ${CONFLICTS}$1 ${DESTDIR}$1"
- cp -Rp ${CONFLICTS}$1 ${DESTDIR}$1 >&3 2>&1
- post_install_file $1
- return 0
-}
-
-# Generate a conflict file when a "new" file conflicts with an
-# existing file in DESTDIR.
-#
-# $1 - pathname of the file that conflicts (relative to DESTDIR)
-new_conflict()
-{
-
- if [ -n "$dryrun" ]; then
- return
- fi
-
- install_dirs $NEWTREE $CONFLICTS $1
- diff --changed-group-format='<<<<<<< (local)
-%<=======
-%>>>>>>>> (stock)
-' $DESTDIR/$1 $NEWTREE/$1 > $CONFLICTS/$1
-}
-
-# Remove the "old" version of a file.
-#
-# $1 - pathname of the old file to remove (relative to DESTDIR)
-remove_old()
-{
- log "rm -f ${DESTDIR}$1"
- if [ -z "$dryrun" ]; then
- rm -f ${DESTDIR}$1 >&3 2>&1
- fi
- echo " D $1"
-}
-
-# Update a file that has no local modifications.
-#
-# $1 - pathname of the file to update (relative to DESTDIR)
-update_unmodified()
-{
- local new old
-
- # If the old file is a directory, then remove it with rmdir
- # (this should only happen if the file has changed its type
- # from a directory to a non-directory). If the directory
- # isn't empty, then fail. This will be reported as a warning
- # later.
- if [ -d $DESTDIR/$1 ]; then
- if empty_destdir $1; then
- log "rmdir ${DESTDIR}$1"
- if [ -z "$dryrun" ]; then
- rmdir ${DESTDIR}$1 >&3 2>&1
- fi
- else
- return 1
- fi
-
- # If both the old and new files are regular files, leave the
- # existing file. This avoids breaking hard links for /.cshrc
- # and /.profile. Otherwise, explicitly remove the old file.
- elif ! [ -f ${DESTDIR}$1 -a -f ${NEWTREE}$1 ]; then
- log "rm -f ${DESTDIR}$1"
- if [ -z "$dryrun" ]; then
- rm -f ${DESTDIR}$1 >&3 2>&1
- fi
- fi
-
- # If the new file is a directory, note that the old file has
- # been removed, but don't do anything else for now. The
- # directory will be installed if needed when new files within
- # that directory are installed.
- if [ -d $NEWTREE/$1 ]; then
- if empty_dir $NEWTREE/$1; then
- echo " D $file"
- else
- echo " U $file"
- fi
- elif install_new $1; then
- echo " U $file"
- fi
- return 0
-}
-
-# Update the FreeBSD ID string in a locally modified file to match the
-# FreeBSD ID string from the "new" version of the file.
-#
-# $1 - pathname of the file to update (relative to DESTDIR)
-update_freebsdid()
-{
- local new dest file
-
- # If the FreeBSD ID string is removed from the local file,
- # there is nothing to do. In this case, treat the file as
- # updated. Otherwise, if either file has more than one
- # FreeBSD ID string, just punt and let the user handle the
- # conflict manually.
- new=`grep -c '\$FreeBSD.*\$' ${NEWTREE}$1`
- dest=`grep -c '\$FreeBSD.*\$' ${DESTDIR}$1`
- if [ "$dest" -eq 0 ]; then
- return 0
- fi
- if [ "$dest" -ne 1 -o "$dest" -ne 1 ]; then
- return 1
- fi
-
- # If the FreeBSD ID string in the new file matches the FreeBSD ID
- # string in the local file, there is nothing to do.
- new=`grep '\$FreeBSD.*\$' ${NEWTREE}$1`
- dest=`grep '\$FreeBSD.*\$' ${DESTDIR}$1`
- if [ "$new" = "$dest" ]; then
- return 0
- fi
-
- # Build the new file in three passes. First, copy all the
- # lines preceding the FreeBSD ID string from the local version
- # of the file. Second, append the FreeBSD ID string line from
- # the new version. Finally, append all the lines after the
- # FreeBSD ID string from the local version of the file.
- file=`mktemp $WORKDIR/etcupdate-XXXXXXX`
- awk '/\$FreeBSD.*\$/ { exit } { print }' ${DESTDIR}$1 >> $file
- awk '/\$FreeBSD.*\$/ { print }' ${NEWTREE}$1 >> $file
- awk '/\$FreeBSD.*\$/ { ok = 1; next } { if (ok) print }' \
- ${DESTDIR}$1 >> $file
-
- # As an extra sanity check, fail the attempt if the updated
- # version of the file has any differences aside from the
- # FreeBSD ID string.
- if ! fbsdid_only ${DESTDIR}$1 $file; then
- rm -f $file
- return 1
- fi
-
- log "cp $file ${DESTDIR}$1"
- if [ -z "$dryrun" ]; then
- cp $file ${DESTDIR}$1 >&3 2>&1
- fi
- rm -f $file
- post_install_file $1
- echo " M $1"
- return 0
-}
-
-# Attempt to update a file that has local modifications. This routine
-# only handles regular files. If the 3-way merge succeeds without
-# conflicts, the updated file is installed. If the merge fails, the
-# merged version with conflict markers is left in the CONFLICTS tree.
-#
-# $1 - pathname of the file to merge (relative to DESTDIR)
-merge_file()
-{
- local res
-
- # Try the merge to see if there is a conflict.
- merge -q -p ${DESTDIR}$1 ${OLDTREE}$1 ${NEWTREE}$1 >/dev/null 2>&3
- res=$?
- case $res in
- 0)
- # No conflicts, so just redo the merge to the
- # real file.
- log "merge ${DESTDIR}$1 ${OLDTREE}$1 ${NEWTREE}$1"
- if [ -z "$dryrun" ]; then
- merge ${DESTDIR}$1 ${OLDTREE}$1 ${NEWTREE}$1
- fi
- post_install_file $1
- echo " M $1"
- ;;
- 1)
- # Conflicts, save a version with conflict markers in
- # the conflicts directory.
- if [ -z "$dryrun" ]; then
- install_dirs $NEWTREE $CONFLICTS $1
- log "cp -Rp ${DESTDIR}$1 ${CONFLICTS}$1"
- cp -Rp ${DESTDIR}$1 ${CONFLICTS}$1 >&3 2>&1
- merge -A -q -L "yours" -L "original" -L "new" \
- ${CONFLICTS}$1 ${OLDTREE}$1 ${NEWTREE}$1
- fi
- echo " C $1"
- ;;
- *)
- panic "merge failed with status $res"
- ;;
- esac
-}
-
-# Returns true if a file contains conflict markers from a merge conflict.
-#
-# $1 - pathname of the file to resolve (relative to DESTDIR)
-has_conflicts()
-{
-
- egrep -q '^(<{7}|\|{7}|={7}|>{7}) ' $CONFLICTS/$1
-}
-
-# Attempt to resolve a conflict. The user is prompted to choose an
-# action for each conflict. If the user edits the file, they are
-# prompted again for an action. The process is very similar to
-# resolving conflicts after an update or merge with Perforce or
-# Subversion. The prompts are modelled on a subset of the available
-# commands for resolving conflicts with Subversion.
-#
-# $1 - pathname of the file to resolve (relative to DESTDIR)
-resolve_conflict()
-{
- local command junk
-
- echo "Resolving conflict in '$1':"
- edit=
- while true; do
- # Only display the resolved command if the file
- # doesn't contain any conflicts.
- echo -n "Select: (p) postpone, (df) diff-full, (e) edit,"
- if ! has_conflicts $1; then
- echo -n " (r) resolved,"
- fi
- echo
- echo -n " (h) help for more options: "
- read command
- case $command in
- df)
- diff -u ${DESTDIR}$1 ${CONFLICTS}$1
- ;;
- e)
- $EDITOR ${CONFLICTS}$1
- ;;
- h)
- cat <<EOF
- (p) postpone - ignore this conflict for now
- (df) diff-full - show all changes made to merged file
- (e) edit - change merged file in an editor
- (r) resolved - accept merged version of file
- (mf) mine-full - accept local version of entire file (ignore new changes)
- (tf) theirs-full - accept new version of entire file (lose local changes)
- (h) help - show this list
-EOF
- ;;
- mf)
- # For mine-full, just delete the
- # merged file and leave the local
- # version of the file as-is.
- rm ${CONFLICTS}$1
- return
- ;;
- p)
- return
- ;;
- r)
- # If the merged file has conflict
- # markers, require confirmation.
- if has_conflicts $1; then
- echo "File '$1' still has conflicts," \
- "are you sure? (y/n) "
- read junk
- if [ "$junk" != "y" ]; then
- continue
- fi
- fi
-
- if ! install_resolved $1; then
- panic "Unable to install merged" \
- "version of $1"
- fi
- rm ${CONFLICTS}$1
- return
- ;;
- tf)
- # For theirs-full, install the new
- # version of the file over top of the
- # existing file.
- if ! install_new $1; then
- panic "Unable to install new" \
- "version of $1"
- fi
- rm ${CONFLICTS}$1
- return
- ;;
- *)
- echo "Invalid command."
- ;;
- esac
- done
-}
-
-# Handle a file that has been removed from the new tree. If the file
-# does not exist in DESTDIR, then there is nothing to do. If the file
-# exists in DESTDIR and is identical to the old version, remove it
-# from DESTDIR. Otherwise, whine about the conflict but leave the
-# file in DESTDIR. To handle directories, this uses two passes. The
-# first pass handles all non-directory files. The second pass handles
-# just directories and removes them if they are empty.
-#
-# If -F is specified, and the only difference in the file in DESTDIR
-# is a change in the FreeBSD ID string, then remove the file.
-#
-# $1 - pathname of the file (relative to DESTDIR)
-handle_removed_file()
-{
- local dest file
-
- file=$1
- if ignore $file; then
- log "IGNORE: removed file $file"
- return
- fi
-
- compare_fbsdid $DESTDIR/$file $OLDTREE/$file
- case $? in
- $COMPARE_EQUAL)
- if ! [ -d $DESTDIR/$file ]; then
- remove_old $file
- fi
- ;;
- $COMPARE_ONLYFIRST)
- panic "Removed file now missing"
- ;;
- $COMPARE_ONLYSECOND)
- # Already removed, nothing to do.
- ;;
- $COMPARE_DIFFTYPE|$COMPARE_DIFFLINKS|$COMPARE_DIFFFILES)
- dest=`file_type $DESTDIR/$file`
- warn "Modified $dest remains: $file"
- ;;
- esac
-}
-
-# Handle a directory that has been removed from the new tree. Only
-# remove the directory if it is empty.
-#
-# $1 - pathname of the directory (relative to DESTDIR)
-handle_removed_directory()
-{
- local dir
-
- dir=$1
- if ignore $dir; then
- log "IGNORE: removed dir $dir"
- return
- fi
-
- if [ -d $DESTDIR/$dir -a -d $OLDTREE/$dir ]; then
- if empty_destdir $dir; then
- log "rmdir ${DESTDIR}$dir"
- if [ -z "$dryrun" ]; then
- rmdir ${DESTDIR}$dir >/dev/null 2>&1
- fi
- echo " D $dir"
- else
- warn "Non-empty directory remains: $dir"
- fi
- fi
-}
-
-# Handle a file that exists in both the old and new trees. If the
-# file has not changed in the old and new trees, there is nothing to
-# do. If the file in the destination directory matches the new file,
-# there is nothing to do. If the file in the destination directory
-# matches the old file, then the new file should be installed.
-# Everything else becomes some sort of conflict with more detailed
-# handling.
-#
-# $1 - pathname of the file (relative to DESTDIR)
-handle_modified_file()
-{
- local cmp dest file new newdestcmp old
-
- file=$1
- if ignore $file; then
- log "IGNORE: modified file $file"
- return
- fi
-
- compare $OLDTREE/$file $NEWTREE/$file
- cmp=$?
- if [ $cmp -eq $COMPARE_EQUAL ]; then
- return
- fi
-
- if [ $cmp -eq $COMPARE_ONLYFIRST -o $cmp -eq $COMPARE_ONLYSECOND ]; then
- panic "Changed file now missing"
- fi
-
- compare $NEWTREE/$file $DESTDIR/$file
- newdestcmp=$?
- if [ $newdestcmp -eq $COMPARE_EQUAL ]; then
- return
- fi
-
- # If the only change in the new file versus the destination
- # file is a change in the FreeBSD ID string and -F is
- # specified, just install the new file.
- if [ -n "$FREEBSD_ID" -a $newdestcmp -eq $COMPARE_DIFFFILES ] && \
- fbsdid_only $NEWTREE/$file $DESTDIR/$file; then
- if update_unmodified $file; then
- return
- else
- panic "Updating FreeBSD ID string failed"
- fi
- fi
-
- # If the local file is the same as the old file, install the
- # new file. If -F is specified and the only local change is
- # in the FreeBSD ID string, then install the new file as well.
- if compare_fbsdid $OLDTREE/$file $DESTDIR/$file; then
- if update_unmodified $file; then
- return
- fi
- fi
-
- # If the file was removed from the dest tree, just whine.
- if [ $newdestcmp -eq $COMPARE_ONLYFIRST ]; then
- # If the removed file matches an ALWAYS_INSTALL glob,
- # then just install the new version of the file.
- if always_install $file; then
- log "ALWAYS: adding $file"
- if ! [ -d $NEWTREE/$file ]; then
- if install_new $file; then
- echo " A $file"
- fi
- fi
- return
- fi
-
- # If the only change in the new file versus the old
- # file is a change in the FreeBSD ID string and -F is
- # specified, don't warn.
- if [ -n "$FREEBSD_ID" -a $cmp -eq $COMPARE_DIFFFILES ] && \
- fbsdid_only $OLDTREE/$file $NEWTREE/$file; then
- return
- fi
-
- case $cmp in
- $COMPARE_DIFFTYPE)
- old=`file_type $OLDTREE/$file`
- new=`file_type $NEWTREE/$file`
- warn "Remove mismatch: $file ($old became $new)"
- ;;
- $COMPARE_DIFFLINKS)
- old=`readlink $OLDTREE/$file`
- new=`readlink $NEWTREE/$file`
- warn \
- "Removed link changed: $file (\"$old\" became \"$new\")"
- ;;
- $COMPARE_DIFFFILES)
- warn "Removed file changed: $file"
- ;;
- esac
- return
- fi
-
- # Treat the file as unmodified and force install of the new
- # file if it matches an ALWAYS_INSTALL glob. If the update
- # attempt fails, then fall through to the normal case so a
- # warning is generated.
- if always_install $file; then
- log "ALWAYS: updating $file"
- if update_unmodified $file; then
- return
- fi
- fi
-
- # If the only change in the new file versus the old file is a
- # change in the FreeBSD ID string and -F is specified, just
- # update the FreeBSD ID string in the local file.
- if [ -n "$FREEBSD_ID" -a $cmp -eq $COMPARE_DIFFFILES ] && \
- fbsdid_only $OLDTREE/$file $NEWTREE/$file; then
- if update_freebsdid $file; then
- continue
- fi
- fi
-
- # If the file changed types between the old and new trees but
- # the files in the new and dest tree are both of the same
- # type, treat it like an added file just comparing the new and
- # dest files.
- if [ $cmp -eq $COMPARE_DIFFTYPE ]; then
- case $newdestcmp in
- $COMPARE_DIFFLINKS)
- new=`readlink $NEWTREE/$file`
- dest=`readlink $DESTDIR/$file`
- warn \
- "New link conflict: $file (\"$new\" vs \"$dest\")"
- return
- ;;
- $COMPARE_DIFFFILES)
- new_conflict $file
- echo " C $file"
- return
- ;;
- esac
- else
- # If the file has not changed types between the old
- # and new trees, but it is a different type in
- # DESTDIR, then just warn.
- if [ $newdestcmp -eq $COMPARE_DIFFTYPE ]; then
- new=`file_type $NEWTREE/$file`
- dest=`file_type $DESTDIR/$file`
- warn "Modified mismatch: $file ($new vs $dest)"
- return
- fi
- fi
-
- case $cmp in
- $COMPARE_DIFFTYPE)
- old=`file_type $OLDTREE/$file`
- new=`file_type $NEWTREE/$file`
- dest=`file_type $DESTDIR/$file`
- warn "Modified $dest changed: $file ($old became $new)"
- ;;
- $COMPARE_DIFFLINKS)
- old=`readlink $OLDTREE/$file`
- new=`readlink $NEWTREE/$file`
- warn \
- "Modified link changed: $file (\"$old\" became \"$new\")"
- ;;
- $COMPARE_DIFFFILES)
- merge_file $file
- ;;
- esac
-}
-
-# Handle a file that has been added in the new tree. If the file does
-# not exist in DESTDIR, simply copy the file into DESTDIR. If the
-# file exists in the DESTDIR and is identical to the new version, do
-# nothing. Otherwise, generate a diff of the two versions of the file
-# and mark it as a conflict.
-#
-# $1 - pathname of the file (relative to DESTDIR)
-handle_added_file()
-{
- local cmp dest file new
-
- file=$1
- if ignore $file; then
- log "IGNORE: added file $file"
- return
- fi
-
- compare $DESTDIR/$file $NEWTREE/$file
- cmp=$?
- case $cmp in
- $COMPARE_EQUAL)
- return
- ;;
- $COMPARE_ONLYFIRST)
- panic "Added file now missing"
- ;;
- $COMPARE_ONLYSECOND)
- # Ignore new directories. They will be
- # created as needed when non-directory nodes
- # are installed.
- if ! [ -d $NEWTREE/$file ]; then
- if install_new $file; then
- echo " A $file"
- fi
- fi
- return
- ;;
- esac
-
-
- # Treat the file as unmodified and force install of the new
- # file if it matches an ALWAYS_INSTALL glob. If the update
- # attempt fails, then fall through to the normal case so a
- # warning is generated.
- if always_install $file; then
- log "ALWAYS: updating $file"
- if update_unmodified $file; then
- return
- fi
- fi
-
- case $cmp in
- $COMPARE_DIFFTYPE)
- new=`file_type $NEWTREE/$file`
- dest=`file_type $DESTDIR/$file`
- warn "New file mismatch: $file ($new vs $dest)"
- ;;
- $COMPARE_DIFFLINKS)
- new=`readlink $NEWTREE/$file`
- dest=`readlink $DESTDIR/$file`
- warn "New link conflict: $file (\"$new\" vs \"$dest\")"
- ;;
- $COMPARE_DIFFFILES)
- # If the only change in the new file versus
- # the destination file is a change in the
- # FreeBSD ID string and -F is specified, just
- # install the new file.
- if [ -n "$FREEBSD_ID" ] && \
- fbsdid_only $NEWTREE/$file $DESTDIR/$file; then
- if update_unmodified $file; then
- return
- else
- panic \
- "Updating FreeBSD ID string failed"
- fi
- fi
-
- new_conflict $file
- echo " C $file"
- ;;
- esac
-}
-
-# Main routines for each command
-
-# Build a new tree and save it in a tarball.
-build_cmd()
-{
- local dir
-
- if [ $# -ne 1 ]; then
- echo "Missing required tarball."
- echo
- usage
- fi
-
- log "build command: $1"
-
- # Create a temporary directory to hold the tree
- dir=`mktemp -d $WORKDIR/etcupdate-XXXXXXX`
- if [ $? -ne 0 ]; then
- echo "Unable to create temporary directory."
- exit 1
- fi
- if ! build_tree $dir; then
- echo "Failed to build tree."
- remove_tree $dir
- exit 1
- fi
- if ! tar cfj $1 -C $dir . >&3 2>&1; then
- echo "Failed to create tarball."
- remove_tree $dir
- exit 1
- fi
- remove_tree $dir
-}
-
-# Output a diff comparing the tree at DESTDIR to the current
-# unmodified tree. Note that this diff does not include files that
-# are present in DESTDIR but not in the unmodified tree.
-diff_cmd()
-{
- local file
-
- if [ $# -ne 0 ]; then
- usage
- fi
-
- # Requires an unmodified tree to diff against.
- if ! [ -d $NEWTREE ]; then
- echo "Reference tree to diff against unavailable."
- exit 1
- fi
-
- # Unfortunately, diff alone does not quite provide the right
- # level of options that we want, so improvise.
- for file in `(cd $NEWTREE; find .) | sed -e 's/^\.//'`; do
- if ignore $file; then
- continue
- fi
-
- diffnode $NEWTREE "$DESTDIR" $file "stock" "local"
- done
-}
-
-# Just extract a new tree into NEWTREE either by building a tree or
-# extracting a tarball. This can be used to bootstrap updates by
-# initializing the current "stock" tree to match the currently
-# installed system.
-#
-# Unlike 'update', this command does not rotate or preserve an
-# existing NEWTREE, it just replaces any existing tree.
-extract_cmd()
-{
-
- if [ $# -ne 0 ]; then
- usage
- fi
-
- log "extract command: tarball=$tarball"
-
- if [ -d $NEWTREE ]; then
- if ! remove_tree $NEWTREE; then
- echo "Unable to remove current tree."
- exit 1
- fi
- fi
-
- extract_tree
-}
-
-# Resolve conflicts left from an earlier merge.
-resolve_cmd()
-{
- local conflicts
-
- if [ $# -ne 0 ]; then
- usage
- fi
-
- if ! [ -d $CONFLICTS ]; then
- return
- fi
-
- if ! [ -d $NEWTREE ]; then
- echo "The current tree is not present to resolve conflicts."
- exit 1
- fi
-
- conflicts=`(cd $CONFLICTS; find . ! -type d) | sed -e 's/^\.//'`
- for file in $conflicts; do
- resolve_conflict $file
- done
-
- if [ -n "$NEWALIAS_WARN" ]; then
- warn "Needs update: /etc/mail/aliases.db" \
- "(requires manual update via newaliases(1))"
- echo
- echo "Warnings:"
- echo " Needs update: /etc/mail/aliases.db" \
- "(requires manual update via newaliases(1))"
- fi
-}
-
-# Report a summary of the previous merge. Specifically, list any
-# remaining conflicts followed by any warnings from the previous
-# update.
-status_cmd()
-{
-
- if [ $# -ne 0 ]; then
- usage
- fi
-
- if [ -d $CONFLICTS ]; then
- (cd $CONFLICTS; find . ! -type d) | sed -e 's/^\./ C /'
- fi
- if [ -s $WARNINGS ]; then
- echo "Warnings:"
- cat $WARNINGS
- fi
-}
-
-# Perform an actual merge. The new tree can either already exist (if
-# rerunning a merge), be extracted from a tarball, or generated from a
-# source tree.
-update_cmd()
-{
- local dir
-
- if [ $# -ne 0 ]; then
- usage
- fi
-
- log "update command: rerun=$rerun tarball=$tarball preworld=$preworld"
-
- if [ `id -u` -ne 0 ]; then
- echo "Must be root to update a tree."
- exit 1
- fi
-
- # Enforce a sane umask
- umask 022
-
- # XXX: Should existing conflicts be ignored and removed during
- # a rerun?
-
- # Trim the conflicts tree. Whine if there is anything left.
- if [ -e $CONFLICTS ]; then
- find -d $CONFLICTS -type d -empty -delete >&3 2>&1
- rmdir $CONFLICTS >&3 2>&1
- fi
- if [ -d $CONFLICTS ]; then
- echo "Conflicts remain from previous update, aborting."
- exit 1
- fi
-
- if [ -z "$rerun" ]; then
- # For a dryrun that is not a rerun, do not rotate the existing
- # stock tree. Instead, extract a tree to a temporary directory
- # and use that for the comparison.
- if [ -n "$dryrun" ]; then
- dir=`mktemp -d $WORKDIR/etcupdate-XXXXXXX`
- if [ $? -ne 0 ]; then
- echo "Unable to create temporary directory."
- exit 1
- fi
-
- # A pre-world dryrun has already set OLDTREE to
- # point to the current stock tree.
- if [ -z "$preworld" ]; then
- OLDTREE=$NEWTREE
- fi
- NEWTREE=$dir
-
- # For a pre-world update, blow away any pre-existing
- # NEWTREE.
- elif [ -n "$preworld" ]; then
- if ! remove_tree $NEWTREE; then
- echo "Unable to remove pre-world tree."
- exit 1
- fi
-
- # Rotate the existing stock tree to the old tree.
- elif [ -d $NEWTREE ]; then
- # First, delete the previous old tree if it exists.
- if ! remove_tree $OLDTREE; then
- echo "Unable to remove old tree."
- exit 1
- fi
-
- # Move the current stock tree.
- if ! mv $NEWTREE $OLDTREE >&3 2>&1; then
- echo "Unable to rename current stock tree."
- exit 1
- fi
- fi
-
- if ! [ -d $OLDTREE ]; then
- cat <<EOF
-No previous tree to compare against, a sane comparison is not possible.
-EOF
- log "No previous tree to compare against."
- if [ -n "$dir" ]; then
- rmdir $dir
- fi
- exit 1
- fi
-
- # Populate the new tree.
- extract_tree
- fi
-
- # Build lists of nodes in the old and new trees.
- (cd $OLDTREE; find .) | sed -e 's/^\.//' | sort > $WORKDIR/old.files
- (cd $NEWTREE; find .) | sed -e 's/^\.//' | sort > $WORKDIR/new.files
-
- # Split the files up into three groups using comm.
- comm -23 $WORKDIR/old.files $WORKDIR/new.files > $WORKDIR/removed.files
- comm -13 $WORKDIR/old.files $WORKDIR/new.files > $WORKDIR/added.files
- comm -12 $WORKDIR/old.files $WORKDIR/new.files > $WORKDIR/both.files
-
- # Initialize conflicts and warnings handling.
- rm -f $WARNINGS
- mkdir -p $CONFLICTS
-
- # Ignore removed files for the pre-world case. A pre-world
- # update uses a stripped-down tree.
- if [ -n "$preworld" ]; then
- > $WORKDIR/removed.files
- fi
-
- # The order for the following sections is important. In the
- # odd case that a directory is converted into a file, the
- # existing subfiles need to be removed if possible before the
- # file is converted. Similarly, in the case that a file is
- # converted into a directory, the file needs to be converted
- # into a directory if possible before the new files are added.
-
- # First, handle removed files.
- for file in `cat $WORKDIR/removed.files`; do
- handle_removed_file $file
- done
-
- # For the directory pass, reverse sort the list to effect a
- # depth-first traversal. This is needed to ensure that if a
- # directory with subdirectories is removed, the entire
- # directory is removed if there are no local modifications.
- for file in `sort -r $WORKDIR/removed.files`; do
- handle_removed_directory $file
- done
-
- # Second, handle files that exist in both the old and new
- # trees.
- for file in `cat $WORKDIR/both.files`; do
- handle_modified_file $file
- done
-
- # Finally, handle newly added files.
- for file in `cat $WORKDIR/added.files`; do
- handle_added_file $file
- done
-
- if [ -n "$NEWALIAS_WARN" ]; then
- warn "Needs update: /etc/mail/aliases.db" \
- "(requires manual update via newaliases(1))"
- fi
-
- # Run any special one-off commands after an update has completed.
- post_update
-
- if [ -s $WARNINGS ]; then
- echo "Warnings:"
- cat $WARNINGS
- fi
-
- if [ -n "$dir" ]; then
- if [ -z "$dryrun" -o -n "$rerun" ]; then
- panic "Should not have a temporary directory"
- fi
-
- remove_tree $dir
- fi
-}
-
-# Determine which command we are executing. A command may be
-# specified as the first word. If one is not specified then 'update'
-# is assumed as the default command.
-command="update"
-if [ $# -gt 0 ]; then
- case "$1" in
- build|diff|extract|status|resolve)
- command="$1"
- shift
- ;;
- -*)
- # If first arg is an option, assume the
- # default command.
- ;;
- *)
- usage
- ;;
- esac
-fi
-
-# Set default variable values.
-
-# The path to the source tree used to build trees.
-SRCDIR=/usr/src
-
-# The destination directory where the modified files live.
-DESTDIR=
-
-# Ignore changes in the FreeBSD ID string.
-FREEBSD_ID=
-
-# Files that should always have the new version of the file installed.
-ALWAYS_INSTALL=
-
-# Files to ignore and never update during a merge.
-IGNORE_FILES=
-
-# Flags to pass to 'make' when building a tree.
-MAKE_OPTIONS=
-
-# Include a config file if it exists. Note that command line options
-# override any settings in the config file. More details are in the
-# manual, but in general the following variables can be set:
-# - ALWAYS_INSTALL
-# - DESTDIR
-# - EDITOR
-# - FREEBSD_ID
-# - IGNORE_FILES
-# - LOGFILE
-# - MAKE_OPTIONS
-# - SRCDIR
-# - WORKDIR
-if [ -r /etc/etcupdate.conf ]; then
- . /etc/etcupdate.conf
-fi
-
-# Parse command line options
-tarball=
-rerun=
-always=
-dryrun=
-ignore=
-nobuild=
-preworld=
-while getopts "d:nprs:t:A:BD:FI:L:M:" option; do
- case "$option" in
- d)
- WORKDIR=$OPTARG
- ;;
- n)
- dryrun=YES
- ;;
- p)
- preworld=YES
- ;;
- r)
- rerun=YES
- ;;
- s)
- SRCDIR=$OPTARG
- ;;
- t)
- tarball=$OPTARG
- ;;
- A)
- # To allow this option to be specified
- # multiple times, accumulate command-line
- # specified patterns in an 'always' variable
- # and use that to overwrite ALWAYS_INSTALL
- # after parsing all options. Need to be
- # careful here with globbing expansion.
- set -o noglob
- always="$always $OPTARG"
- set +o noglob
- ;;
- B)
- nobuild=YES
- ;;
- D)
- DESTDIR=$OPTARG
- ;;
- F)
- FREEBSD_ID=YES
- ;;
- I)
- # To allow this option to be specified
- # multiple times, accumulate command-line
- # specified patterns in an 'ignore' variable
- # and use that to overwrite IGNORE_FILES after
- # parsing all options. Need to be careful
- # here with globbing expansion.
- set -o noglob
- ignore="$ignore $OPTARG"
- set +o noglob
- ;;
- L)
- LOGFILE=$OPTARG
- ;;
- M)
- MAKE_OPTIONS="$OPTARG"
- ;;
- *)
- echo
- usage
- ;;
- esac
-done
-shift $((OPTIND - 1))
-
-# Allow -A command line options to override ALWAYS_INSTALL set from
-# the config file.
-set -o noglob
-if [ -n "$always" ]; then
- ALWAYS_INSTALL="$always"
-fi
-
-# Allow -I command line options to override IGNORE_FILES set from the
-# config file.
-if [ -n "$ignore" ]; then
- IGNORE_FILES="$ignore"
-fi
-set +o noglob
-
-# Where the "old" and "new" trees are stored.
-WORKDIR=${WORKDIR:-$DESTDIR/var/db/etcupdate}
-
-# Log file for verbose output from program that are run. The log file
-# is opened on fd '3'.
-LOGFILE=${LOGFILE:-$WORKDIR/log}
-
-# The path of the "old" tree
-OLDTREE=$WORKDIR/old
-
-# The path of the "new" tree
-NEWTREE=$WORKDIR/current
-
-# The path of the "conflicts" tree where files with merge conflicts are saved.
-CONFLICTS=$WORKDIR/conflicts
-
-# The path of the "warnings" file that accumulates warning notes from an update.
-WARNINGS=$WORKDIR/warnings
-
-# Use $EDITOR for resolving conflicts. If it is not set, default to vi.
-EDITOR=${EDITOR:-/usr/bin/vi}
-
-# Files that need to be updated before installworld.
-PREWORLD_FILES="etc/master.passwd etc/group"
-
-# Handle command-specific argument processing such as complaining
-# about unsupported options. Since the configuration file is always
-# included, do not complain about extra command line arguments that
-# may have been set via the config file rather than the command line.
-case $command in
- update)
- if [ -n "$rerun" -a -n "$tarball" ]; then
- echo "Only one of -r or -t can be specified."
- echo
- usage
- fi
- if [ -n "$rerun" -a -n "$preworld" ]; then
- echo "Only one of -p or -r can be specified."
- echo
- usage
- fi
- ;;
- build|diff|status)
- if [ -n "$dryrun" -o -n "$rerun" -o -n "$tarball" -o \
- -n "$preworld" ]; then
- usage
- fi
- ;;
- resolve)
- if [ -n "$dryrun" -o -n "$rerun" -o -n "$tarball" ]; then
- usage
- fi
- ;;
- extract)
- if [ -n "$dryrun" -o -n "$rerun" -o -n "$preworld" ]; then
- usage
- fi
- ;;
-esac
-
-# Pre-world mode uses a different set of trees. It leaves the current
-# tree as-is so it is still present for a full etcupdate run after the
-# world install is complete. Instead, it installs a few critical files
-# into a separate tree.
-if [ -n "$preworld" ]; then
- OLDTREE=$NEWTREE
- NEWTREE=$WORKDIR/preworld
-fi
-
-# Open the log file. Don't truncate it if doing a minor operation so
-# that a minor operation doesn't lose log info from a major operation.
-if ! mkdir -p $WORKDIR 2>/dev/null; then
- echo "Failed to create work directory $WORKDIR"
-fi
-
-case $command in
- diff|resolve|status)
- exec 3>>$LOGFILE
- ;;
- *)
- exec 3>$LOGFILE
- ;;
-esac
-
-${command}_cmd "$@"

File Metadata

Mime Type
text/plain
Expires
Sat, Aug 22, 10:24 AM (13 h, 53 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
37071142
Default Alt Text
D39188.diff (68 KB)

Event Timeline