#!/bin/sh # # $NetBSD: etcupdate,v 1.60 2016/01/03 08:44:59 martin Exp $ # # Copyright (c) 2001-2008 The NetBSD Foundation, Inc. # All rights reserved. # # This code is derived from software contributed to The NetBSD Foundation # by Martti Kuparinen. # # 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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 script helps you to update the configuration files in /etc # after an operating system upgrade. Instead of running "make distribution" # in /usr/src/etc (and losing your current configuration) you can easily # see the modifications and either install the new version or merge the # changes in to your current configuration files. # # This script was written by Martti Kuparinen and # improved by several other NetBSD users. # # The idea for this script (including code fragments, variable names etc.) # came from the FreeBSD mergemaster (by Douglas Barton). # PATH="/sbin:/usr/sbin:/bin:/usr/bin:${PATH}" # Default settings PROG="${0##*/}" DESTDIR="" # must not have a trailing slash DESTDIR_BRE="" # basic regex to match ${DESTDIR} TEMPROOT="${TEMPROOT:=/tmp/temproot}" PAGER="${PAGER:=/usr/bin/more}" SWIDTH="$(stty size | awk '{w=$2}END{if(w==0){w=80}print w}')" WIDTH="${WIDTH:="${SWIDTH}"}" DIFF_COMMAND="diff -u" VERBOSE=false CONTINUE=false SOURCEMODE=false # true for "-s source_dir" SRCDIR= # directory for SOURCEMODE BINARYMODE=false # true for both BINARYDIRMODE and BINARYTGZMODE BINARYDIRMODE=false # true for "-s extracted_dir" BINARYDIR= # directory name for BINARYDIRMODE BINARYTGZMODE=false # true for "-s etc.tgz" TGZLIST= # quoted list list of files for BINARYTGZMODE SRC_ARGLIST= # quoted list of "-s" args N_SRC_ARGS=0 # number of "-s" args AUTOMATIC=false LOCALSKIP=false MACHINE="${MACHINE:="$(uname -m)"}" export MACHINE MACHINE_ARCH="${MACHINE_ARCH:="$(uname -p)"}" export MACHINE_ARCH # Settings for post-installation procedures NEED_ANYTHING=false NEED_MAKEDEV=false NEED_MTREE=false NEED_NEWALIASES=false NEED_PWD_MKDB=false NEED_SERVICES_MKDB=false usage() { cat << EOF >&2 Usage: ${PROG} [options] Options: -p pager Which pager to use (default: /usr/bin/more) -s {srcdir|tgzfile|tempdir} (default: /usr/src) Location of the source files. This may be any of the following: * A directory that contains a NetBSD source tree; * A distribution set file such as "etc.tgz" or "xetc.tgz". Pass multiple -s options to specify multiple such files; * A temporary directory in which one or both of "etc.tgz" and "xetc.tgz" have been extracted. -t temproot Where to store temporary files (default: /tmp/temproot) -d destdir Destination directory to check. (default: /) -w width Screen width (default: 80) -a Automatically update unmodified files -l Automatically skip files with strictly local changes (this option has no effect on files lacking RCS Ids) -h This help text -v Be more verbose EOF exit 1 } verbose() { # $* = message to display if in verbose mode ${VERBOSE} && echo "${@}" } yesno() { # $* = message to display echo -n "${@}? (y/[n]) " read ANSWER case "${ANSWER}" in y|Y) return 0 ;; *) return 1 ;; esac } # Quote args to make them safe in the shell. # Usage: quotedlist="$(shell_quote args...)" # # After building up a quoted list, use it by evaling it inside # double quotes, like this: # eval "set -- $quotedlist" # or like this: # eval "\$command $quotedlist \$filename" # shell_quote() {( local result='' local arg qarg LC_COLLATE=C ; export LC_COLLATE # so [a-zA-Z0-9] works in ASCII for arg in "$@" ; do case "${arg}" in '') qarg="''" ;; *[!-./a-zA-Z0-9]*) # Convert each embedded ' to '\'', # then insert ' at the beginning of the first line, # and append ' at the end of the last line. # Finally, elide unnecessary '' pairs at the # beginning and end of the result and as part of # '\'''\'' sequences that result from multiple # adjacent quotes in he input. qarg="$(printf "%s\n" "$arg" | \ ${SED:-sed} -e "s/'/'\\\\''/g" \ -e "1s/^/'/" -e "\$s/\$/'/" \ -e "1s/^''//" -e "\$s/''\$//" \ -e "s/'''/'/g" )" ;; *) # Arg is not the empty string, and does not contain # any unsafe characters. Leave it unchanged for # readability. qarg="${arg}" ;; esac result="${result}${result:+ }${qarg}" done printf "%s\n" "$result" )} # Convert arg $1 to a basic regular expression (as in sed) # that will match the arg. This works by inserting backslashes # before characters that are special in basic regular expressions. # It also inserts backslashes before the extra characters specified # in $2 (which defaults to "/,"). # XXX: Does not handle embedded newlines. # Usage: regex="$(bre_quote "${string}")" bre_quote() { local arg="$1" local extra="${2-/,}" printf "%s\n" "${arg}" | sed -e 's/[][^$.*\\'"${extra}"']/\\&/g' } install_dir() { # $1 = target directory (relative to ${DESTDIR}) NEED_ANYTHING=true if yesno "Create ${DESTDIR}${1}"; then verbose "Creating ${DESTDIR}${1}" mkdir -p "${DESTDIR}${1}" || exit 1 NEED_MTREE=true fi } install_file() { # $1 = target file (relative to ${DESTDIR}) NEED_ANYTHING=true # Install the new file verbose "Installing ${DESTDIR}${1}" cp -p "${TEMPROOT}${1}" "${DESTDIR}${1}" && rm -f "${TEMPROOT}${1}" # Check if this was a special file case "${1}" in /dev/MAKEDEV) NEED_MAKEDEV=true ;; /dev/MAKEDEV.local) NEED_MAKEDEV=true ;; /etc/mail/aliases) NEED_NEWALIASES=true ;; /etc/master.passwd) NEED_PWD_MKDB=true ;; /etc/services) NEED_SERVICES_MKDB=true ;; esac } install_checksum() { # $1 = target file (relative to ${DESTDIR}) ${AUTOMATIC} || return NEED_ANYTHING=true D="$(dirname "${1}")" mkdir -p "${DESTDIR}/var/etcupdate/${D}" verbose "Saving MD5 checksum for ${DESTDIR}${1} to" \ "${DESTDIR}/var/etcupdate/${1}" # The sed part of the following pipeline changes things like # "MD5 (/path/to/dest/dir/etc/filename) = abc123" to # "MD5 (/etc/filename) = abc123". md5 "${DESTDIR}${1}" | sed -e "s,(${DESTDIR_BRE},(," \ > "${DESTDIR}/var/etcupdate/${1}" } # Initialise the DIFF_EXTRA_OPTIONS variable. init_diff_extra_options() { # # Start with a few options that are always available. # DIFF_EXTRA_OPTIONS=\ " su Show differences in unified format (\"diff -u\") sc Show differences in context format (\"diff -c\") ss Show differences side by side (\"sdiff -w${WIDTH}\")" # # wdiff is not part of the base system, but the # user might have installed it from pkgsrc. It is # useful to show differences on a word by word basis # instead of line by line. If it is executable # then offer to use it in the menu. # if (wdiff /dev/null /dev/null) >/dev/null 2>&1 ; then DIFF_EXTRA_OPTIONS="${DIFF_EXTRA_OPTIONS} sw Show differences word by word (\"wdiff -n -l\")" fi # # End with an option to use a user-specified diff-like command. # DIFF_EXTRA_OPTIONS="${DIFF_EXTRA_OPTIONS} scommand Show differences using the specified diff-like command" } diff_and_merge_file() { # $1 = target file (relative to ${DESTDIR}) if cmp -s "${TEMPROOT}${1}" "${DESTDIR}${1}"; then verbose "===> ${1} (ok)" rm -f "${TEMPROOT}${1}" install_checksum "${1}" return fi if ${AUTOMATIC} && [ -f "${DESTDIR}/var/etcupdate/${1}" ]; then SUM1="$(md5 "${1}")" SUM2="$(cat "${DESTDIR}/var/etcupdate/${1}")" if [ "${SUM1}" = "${SUM2}" ]; then install_file "${1}" install_checksum "${1}" return fi fi if ${LOCALSKIP}; then ID1="$(ident -q "${TEMPROOT}${1}" | sed -n 2p)" ID1="${ID1:-0}" ID2="$(ident -q "${DESTDIR}${1}" | sed -n 2p)" ID2="${ID2:-1}" if [ "${ID1}" = "${ID2}" ]; then verbose "===> ${1} (ok:RCS)" rm -f "${TEMPROOT}${1}" return fi fi clear if [ ! -f "${DESTDIR}${1}" ]; then verbose "===> ${DESTDIR}${1} (missing)" DOES_EXIST=false else verbose "===> ${DESTDIR}${1} (modified)" verbose "" DOES_EXIST=true diff -u "${DESTDIR}${1}" "${TEMPROOT}${1}" | ${PAGER} fi STAY_HERE=true ALREADY_MERGED=false # Determine name for the backup file (/foo/._etcupdate.bar) D="$(dirname "${TEMPROOT}${1}")" F="$(basename "${TEMPROOT}${1}")" B="${D}/.etcupdate.${F}" F="${D}/${F}" while ${STAY_HERE}; do # Ask the user if (s)he wants to install the new # version or perform a more complicated manual work. echo "" echo -n "File: ${DESTDIR}${1}" if [ ! -f "${DESTDIR}${1}" ]; then echo -n " (missing)" else echo -n " (modified)" fi echo "" echo "" echo "Please select one of the following operations:" echo "" if ! ${DOES_EXIST}; then cat << EOF d Don't install the missing file i Install the missing file v Show the missing file EOF elif ! ${ALREADY_MERGED}; then cat << EOF d Don't install the new file (keep your old file) i Install the new file (overwrites your local modifications!) m Merge the currently installed and new files s Show the differences between the currently installed and new files ${DIFF_EXTRA_OPTIONS} v Show the new file EOF else cat << EOF d Don't install the merged file (keep your old file) i Install the merged file (overwrites your old file) m Merge again (your old file against the result from the previous merge) s Show the differences between the currently installed and new merged files ${DIFF_EXTRA_OPTIONS} u Undo merge (start again with the original version of the new file) v Show the merged file EOF fi echo -n "What do you want to do? [Leave it for later] " read ANSWER case "${ANSWER}" in [dD]) verbose "Removing ${TEMPROOT}${1}" rm -f "${TEMPROOT}${1}" STAY_HERE=false ;; [iI]) install_file "${1}" if ! ${ALREADY_MERGED}; then install_checksum "${1}" fi STAY_HERE=false ;; [mM]) ${DOES_EXIST} || continue [ ! -f "${B}" ] && cp "${F}" "${B}" cp "${TEMPROOT}${1}" "${TEMPROOT}${1}.merged" sdiff -o "${TEMPROOT}${1}.merged" \ --width=${WIDTH} \ --suppress-common-lines --text \ "${DESTDIR}${1}" "${TEMPROOT}${1}" mv -f "${TEMPROOT}${1}.merged" "${TEMPROOT}${1}" ALREADY_MERGED=true ;; [sS]*) ${DOES_EXIST} || continue case "${ANSWER}" in [sS]) : no change ;; [sS]u) DIFF_COMMAND="diff -u" ;; [sS]c) DIFF_COMMAND="diff -c" ;; [sS]s) DIFF_COMMAND="sdiff -w${WIDTH}" ;; [sS]w) DIFF_COMMAND="wdiff -n -l" ;; [sS]*) DIFF_COMMAND="${ANSWER#?}" ;; esac ${DIFF_COMMAND} "${DESTDIR}${1}" "${TEMPROOT}${1}" \ | ${PAGER} ;; [uU]) if [ -f "${B}" ]; then echo "*** Restoring ${F}" mv -f "${B}" "${F}" fi ALREADY_MERGED=false ;; [vV]) ${PAGER} "${TEMPROOT}${1}" ;; "") STAY_HERE=false ;; *) echo "*** Invalid selection!" ;; esac done rm -f "$B" } # Set the environment for make. set_makeenv() { # # INSTALL_DONE=1 prevents installation of unwanted # files (things that are not part of the etc set). # BUILD=1 allows building of files that are wanted. # MAKE_ENV=" \ NETBSDSRCDIR=$(shell_quote "${SRCDIR}") \ DESTDIR=$(shell_quote "${TEMPROOT}") \ MAKE=make \ MTREE=mtree \ TOOL_MTREE=mtree \ INSTALL_DONE=1 \ BUILD=1 \ USETOOLS=never" } # # main() # # Read global configuration GLOBALRC="/etc/${PROG}.conf" [ -r ${GLOBALRC} ] && . ${GLOBALRC} # Read user configuration USERRC="${HOME}/.{PROG}rc" [ -r ${USERRC} ] && . ${USERRC} # Read command line arguments while getopts ad:hlp:s:t:vw: i do case "${i}" in a) AUTOMATIC=true ;; d) DESTDIR="${OPTARG}" ;; h) usage ;; l) LOCALSKIP=true ;; p) PAGER="${OPTARG}" ;; s) # Three cases: # -s tgzfile (may be repeated) # -s srcdir (may not be repeated) # -s extracted_dir (may not be repeated) arg="${OPTARG}" qarg="$(shell_quote "${OPTARG}")" N_SRC_ARGS=$(( N_SRC_ARGS + 1 )) SRC_ARGLIST="${SRC_ARGLIST}${SRC_ARGLIST:+ }-s ${qarg}" if [ -f "${arg}" ]; then # arg refers to a *.tgz file. # This may happen twice, for both etc.tgz and # xetc.tgz, so we build up a list in TGZLIST. BINARYMODE=true BINARYTGZMODE=true TGZLIST="${TGZLIST}${TGZLIST:+ }${qarg}" elif [ -d "${arg}" ] && [ -f "${arg}/etc/Makefile" ]; then # arg refers to a source directory SOURCEMODE=true SRCDIR="${arg}" elif [ -d "${arg}" ] && [ -d "${arg}/etc" ] \ && ! [ -f "${arg}/etc/Makefile" ] then # arg refers to a directory where the # sets have already been extracted BINARYMODE=true BINARYDIRMODE=true BINARYDIR="${arg}" else echo "*** Nonexistent or invalid file or directory" \ "for -s ${arg}" usage fi ;; t) TEMPROOT="${OPTARG}" ;; v) VERBOSE=true ;; w) WIDTH="${OPTARG}" ;; *) # getopts should already have printed an error message usage break ;; esac done # Last minute sanity checks if [ "$(id -u)" -ne 0 ]; then echo "*** ERROR: You MUST be root" exit 1 fi DESTDIR="${DESTDIR%/}" # remove trailing slash, if any. result might be "". DESTDIR_BRE="$(bre_quote "${DESTDIR}")" if [ "${N_SRC_ARGS}" -gt 1 ] && ( ${SOURCEMODE} || ${BINARYDIRMODE} ); then echo "*** ERROR: Multiple -s args are allowed only with tgz files" usage fi case "${TEMPROOT}" in /*) : OK ;; *) new="${PWD:-$(pwd)}/${TEMPROOT}" echo "*** NOTE: Using TEMPROOT \"${new}\" instead of \"${TEMPROOT}\"" TEMPROOT="${new}" ;; esac if ${BINARYDIRMODE}; then SRCDIR="${TEMPROOT}" fi if ${BINARYTGZMODE}; then SRCDIR="${TEMPROOT}" fi if [ "${N_SRC_ARGS}" -eq 0 ]; then # default if no "-s" option was specified SOURCEMODE=true SRCDIR="/usr/src" SRC_ARGLIST="-s $(shell_quote "${SRCDIR}")" fi if [ -z "${SRCDIR}" -o -z "${TEMPROOT}" ]; then echo "*** ERROR: One of the following variables is undefined" echo "" echo "SRCDIR=\"${SRCDIR}\"" echo "TEMPROOT=\"${TEMPROOT}\"" echo "" exit 1 fi if [ -r "${TEMPROOT}" ]; then echo "" echo "*** WARNING: ${TEMPROOT} already exists" echo "" if yesno "Continue previously aborted update"; then CONTINUE=true elif yesno "Remove the old ${TEMPROOT}"; then echo "*** Removing ${TEMPROOT}" rm -rf "${TEMPROOT}" fi fi if ! ${CONTINUE}; then # Create the temporary root directory echo "*** Creating ${TEMPROOT}" mkdir -p "${TEMPROOT}" if [ ! -d "${TEMPROOT}" ]; then echo "*** ERROR: Unable to create ${TEMPROOT}" exit 1 fi # Are we using the sources or binaries? if ${BINARYTGZMODE}; then # Populate ${TEMPROOT} from ${TGZLIST} eval "set -- ${TGZLIST}" for tgz in "$@"; do if [ ! -f "${tgz}" ]; then echo "*** ERROR: Unable to find ${tgz}" exit 1 fi echo "*** Populating ${TEMPROOT} from ${tgz}" tar -zxpf "${tgz}" -C "${TEMPROOT}" [ $? -ne 0 ] && exit 1 done elif ${BINARYDIRMODE}; then # Populate ${TEMPROOT} from ${SRCDIR} by copying. # Copy only the files that belong to the etc and xetc sets. echo "*** Populating ${TEMPROOT} from ${BINARYDIR} (copying)" for setname in etc xetc; do mtreefile="${BINARYDIR}/etc/mtree/set.${setname}" if ${VERBOSE}; then vflag="-v"; else vflag=""; fi if [ -f "${mtreefile}" ]; then echo "*** Copying files belonging to" \ "${setname} set" (cd "${BINARYDIR}" \ && pax -rwdM ${vflag} "${TEMPROOT%/}/." ) <"${mtreefile}" [ $? -ne 0 ] && exit 1 else echo "*** Not copying files belonging to" \ "${setname} set: ${mtreefile} not found" fi done elif ${SOURCEMODE}; then # Populate ${TEMPROOT} from ${SRCDIR} by running make if [ ! -f "${SRCDIR}/etc/Makefile" ]; then echo "*** ERROR: Unable to find ${SRCDIR}/etc/Makefile" exit 1 fi set_makeenv echo "*** Populating ${TEMPROOT} from ${SRCDIR} (make distribution)" cd ${SRCDIR}/etc if ! ${VERBOSE}; then eval "${MAKE_ENV} make distribution > /dev/null" else eval "${MAKE_ENV} make distribution" fi [ $? -ne 0 ] && exit 1 fi if ! [ -f "${TEMPROOT}/etc/mtree/set.etc" ]; then echo "*** ERROR: Files from the etc.tgz set are missing" exit 1 fi if [ ! -f "${TEMPROOT}/dev/MAKEDEV" ]; then echo "" echo "*** WARNING: ${TEMPROOT}/dev/MAKEDEV not found" echo "Make sure you update /dev/MAKEDEV later and run" echo "(cd /dev && ./MAKEDEV all) to rebuild the device nodes" echo "" fi # Ignore the following files during comparision rm -f "${TEMPROOT}"/etc/passwd rm -f "${TEMPROOT}"/etc/pwd.db rm -f "${TEMPROOT}"/etc/spwd.db find "${TEMPROOT}" -type f -size 0 -exec rm {} \; # Ignore files we're told to ignore if [ ! -z "${IGNOREFILES}" ]; then echo "*** Ignoring files: ${IGNOREFILES}" for file in ${IGNOREFILES}; do rm -f "${TEMPROOT}"${file} done fi # Are there any new directories? echo "*** Checking for new directories" exec 3<&0 find "${TEMPROOT}" -type d | \ while read i; do D="${i#"${TEMPROOT}"}" [ "x${i}" = "x${TEMPROOT}" ] && continue [ ! -d "${D}" ] && install_dir "${D}" <&3 done fi # Start the comparision echo "*** Checking for added/modified files" init_diff_extra_options exec 3<&0 find "${TEMPROOT}" -type f -a ! -name \*.etcupdate.\* | \ while read i; do D="${i#"${TEMPROOT}"}" diff_and_merge_file "${D}" <&3 done # Do we have files which were not processed? REMAINING="$(find "${TEMPROOT}" -type f -a ! -name \*.etcupdate.\*)" if [ ! -z "${REMAINING}" ]; then echo "" echo "*** The following files need your attention:" echo "" echo "${REMAINING}" | sed -e 's/^/ /' echo "" elif ! ${NEED_ANYTHING}; then echo "" echo "*** No changes were needed" echo "" fi if yesno "Remove ${TEMPROOT}"; then echo "*** Removing ${TEMPROOT}" rm -rf "${TEMPROOT}" else echo "*** Keeping ${TEMPROOT}" fi # Clean up after "make distribution" if ${SOURCEMODE}; then echo "*** Cleaning up in ${SRCDIR}/etc" set_makeenv cd ${SRCDIR}/etc if ! ${VERBOSE}; then eval "${MAKE_ENV} make clean > /dev/null" else eval "${MAKE_ENV} make clean" fi fi # Do some post-installation tasks if ${NEED_PWD_MKDB}; then pwd_mkdb_cmd="$(shell_quote \ pwd_mkdb ${DESTDIR:+-d "${DESTDIR}"} \ -p "${DESTDIR}/etc/master.passwd")" if yesno "Do you want to rebuild the password databases from the" \ "new ${DESTDIR}/etc/master.passwd" then verbose "Running pwd_mkdb" eval "${pwd_mkdb_cmd}" else echo "" echo "*** You MUST rebuild the password databases to make" \ "the changes visible" echo "*** This is done by running \"${pwd_mkdb_cmd}\" as root" echo "" fi fi if ! ${NEED_SERVICES_MKDB}; then if test -e "${DESTDIR}/var/db/services.db" \ -a ! -e "${DESTDIR}/var/db/services.cdb" then NEED_SERVICES_MKDB=true fi fi if ${NEED_SERVICES_MKDB}; then services_mkdb_cmd="$(shell_quote services_mkdb -V cdb \ -o "${DESTDIR}/var/db/services.cdb" \ "${DESTDIR}/etc/services")" if yesno "Do you want to rebuild the services databases from the" \ "new ${DESTDIR}/etc/services" then verbose "Running services_mkdb" eval "${services_mkdb_cmd}" else echo "" echo "*** You SHOULD rebuild the services databases to make" \ "the changes visible" echo "*** This is done by running \"${services_mkdb_cmd}\"" \ "as root" echo "" fi fi if ${NEED_MTREE}; then if yesno "You have created new directories. Run mtree to set" \ "permissions" then (cd "${DESTDIR:-/}" && \ mtree -Udef "${DESTDIR}/etc/mtree/NetBSD.dist") fi fi if ${NEED_MAKEDEV}; then makedev_cmd="($(shell_quote cd "${DESTDIR}/dev") && ./MAKEDEV all)" if yesno "Do you want to rebuild the device nodes in ${DESTDIR}/dev" then verbose "Running MAKEDEV in /dev" eval "${makedev_cmd}" else echo "" echo "*** You SHOULD rebuild the device nodes in" \ "${DESTDIR}/dev" echo "*** This is done by running \"${makedev_cmd}\" as root." echo "" fi fi if ${NEED_NEWALIASES}; then newaliases_cmd="newaliases" # XXX newaliases doesn't work with DESTDIR. # We could check whether the system configuration is # sufficiently standard, and then run postalias(1) with the # right args to make it work, but changes to /etc/mail/aliases # are so rare that it doesn't seem worth the effort of checking # that the system's mail configuration is standard. if [ -z "${DESTDIR}" ] && \ yesno "Do you want to rebuild the mail alias database" then verbose "Running newaliases" eval "${newaliases_cmd}" else echo "" echo "*** You MUST rebuild the mail alias database to make" \ "the changes visible" echo "*** This is done by running \"${newaliases_cmd}\" as root" if [ -n "${DESTDIR}" ]; then postalias_cmd="$(shell_quote \ postalias "hash:${DESTDIR}/etc/mail/aliases")" echo "*** but it won't work with DESTDIR=${DESTDIR}." echo "*** If you use postfix(1) with the default" \ "configuration, then you can try" echo "*** running \"${postalias_cmd}\" as root." fi echo "" fi fi if [ -x "${DESTDIR}/usr/sbin/postinstall" ]; then postinstall_cmd="$(shell_quote "${DESTDIR}/usr/sbin/postinstall" \ ${DESTDIR:+-d "${DESTDIR}"}) ${SRC_ARGLIST} check" echo "*** Running ${DESTDIR}/usr/sbin/postinstall" eval "${postinstall_cmd}" fi echo "*** All done"