Home | History | Annotate | Line # | Download | only in postinstall
postinstall.in revision 1.66
      1   1.1  christos #!/bin/sh
      2   1.1  christos #
      3  1.66       uwe # $NetBSD: postinstall.in,v 1.66 2024/10/10 22:14:34 uwe Exp $
      4   1.1  christos #
      5  1.43     lukem # Copyright (c) 2002-2022 The NetBSD Foundation, Inc.
      6   1.1  christos # All rights reserved.
      7   1.1  christos #
      8   1.1  christos # This code is derived from software contributed to The NetBSD Foundation
      9   1.1  christos # by Luke Mewburn.
     10   1.1  christos #
     11   1.1  christos # Redistribution and use in source and binary forms, with or without
     12   1.1  christos # modification, are permitted provided that the following conditions
     13   1.1  christos # are met:
     14   1.1  christos # 1. Redistributions of source code must retain the above copyright
     15   1.1  christos #    notice, this list of conditions and the following disclaimer.
     16   1.1  christos # 2. Redistributions in binary form must reproduce the above copyright
     17   1.1  christos #    notice, this list of conditions and the following disclaimer in the
     18   1.1  christos #    documentation and/or other materials provided with the distribution.
     19   1.1  christos #
     20   1.1  christos # THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     21   1.1  christos # ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     22   1.1  christos # TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     23   1.1  christos # PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     24   1.1  christos # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     25   1.1  christos # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     26   1.1  christos # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     27   1.1  christos # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     28   1.1  christos # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     29   1.1  christos # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     30   1.1  christos # POSSIBILITY OF SUCH DAMAGE.
     31   1.1  christos #
     32   1.1  christos # postinstall
     33   1.1  christos #	Check for or fix configuration changes that occur
     34   1.1  christos #	over time as NetBSD evolves.
     35   1.1  christos #
     36   1.1  christos 
     37   1.1  christos #
     38  1.36     lukem # NOTE: Be sure to use ${DEST_DIR} prefix before all real file operations.
     39   1.1  christos #
     40   1.1  christos 
     41   1.1  christos #
     42   1.1  christos # checks to add:
     43   1.1  christos #	- sysctl(8) renames (net.inet6.ip6.bindv6only -> net.inet6.ip6.v6only)
     44   1.1  christos #	- de* -> tlp* migration (/etc/ifconfig.de*, $ifconfig_de*, ...) ?
     45   1.1  christos #	- support quiet/verbose mode ?
     46   1.1  christos #	- differentiate between failures caused by missing source
     47   1.1  christos #	  and real failures
     48   1.1  christos #	- install moduli into usr/share/examples/ssh and use from there?
     49   1.1  christos #	- differentiate between "needs fix" versus "can't fix" issues
     50   1.1  christos #
     51   1.1  christos 
     52   1.1  christos # This script is executed as part of a cross build.  Allow the build
     53   1.1  christos # environment to override the locations of some tools.
     54   1.1  christos : ${AWK:=awk}
     55   1.1  christos : ${DB:=db}
     56   1.1  christos : ${GREP:=grep}
     57   1.1  christos : ${HOST_SH:=sh}
     58   1.1  christos : ${MAKE:=make}
     59   1.1  christos : ${PWD_MKDB:=/usr/sbin/pwd_mkdb}
     60   1.1  christos : ${SED:=sed}
     61   1.1  christos : ${SORT:=sort}
     62   1.1  christos : ${STAT:=stat}
     63  1.59  christos : ${RM:=rm}
     64   1.1  christos 
     65   1.1  christos #
     66   1.1  christos #	helper functions
     67   1.1  christos #
     68   1.1  christos 
     69   1.1  christos err()
     70   1.1  christos {
     71  1.59  christos 	local exitval=$1
     72   1.1  christos 	shift
     73   1.1  christos 	echo 1>&2 "${PROGNAME}: $*"
     74   1.1  christos 	if [ -n "${SCRATCHDIR}" ]; then
     75  1.59  christos 	    ${RM} -rf "${SCRATCHDIR}"
     76   1.1  christos 	fi
     77   1.1  christos 	exit ${exitval}
     78   1.1  christos }
     79   1.1  christos 
     80   1.1  christos warn()
     81   1.1  christos {
     82   1.1  christos 	echo 1>&2 "${PROGNAME}: $*"
     83   1.1  christos }
     84   1.1  christos 
     85   1.1  christos msg()
     86   1.1  christos {
     87   1.1  christos 	echo "	$*"
     88   1.1  christos }
     89   1.1  christos 
     90   1.1  christos mkdtemp()
     91   1.1  christos {
     92   1.1  christos 	# Make sure we don't loop forever if mkdir will always fail.
     93   1.1  christos 	[ -d /tmp ] || err 2 /tmp is not a directory
     94   1.1  christos 	[ -w /tmp ] || err 2 /tmp is not writable
     95   1.1  christos 
     96  1.59  christos 	local base="/tmp/_postinstall.$$"
     97  1.59  christos 	local serial=0
     98  1.60  christos 	local dir
     99   1.1  christos 
    100   1.1  christos 	while true; do
    101  1.60  christos 		dir="${base}.${serial}"
    102  1.59  christos 		mkdir -m 0700 "${dir}" && break
    103  1.61    rillig 		serial=$((${serial} + 1))
    104   1.1  christos 	done
    105  1.59  christos 	echo "${dir}"
    106   1.1  christos }
    107   1.1  christos 
    108   1.1  christos # Quote args to make them safe in the shell.
    109   1.1  christos # Usage: quotedlist="$(shell_quote args...)"
    110   1.1  christos #
    111   1.1  christos # After building up a quoted list, use it by evaling it inside
    112   1.1  christos # double quotes, like this:
    113   1.1  christos #    eval "set -- $quotedlist"
    114   1.1  christos # or like this:
    115   1.1  christos #    eval "\$command $quotedlist \$filename"
    116   1.1  christos #
    117   1.1  christos shell_quote()
    118   1.1  christos {(
    119   1.1  christos 	local result=''
    120   1.1  christos 	local arg qarg
    121   1.1  christos 	LC_COLLATE=C ; export LC_COLLATE # so [a-zA-Z0-9] works in ASCII
    122   1.1  christos 	for arg in "$@" ; do
    123   1.1  christos 		case "${arg}" in
    124   1.1  christos 		'')
    125   1.1  christos 			qarg="''"
    126   1.1  christos 			;;
    127   1.1  christos 		*[!-./a-zA-Z0-9]*)
    128   1.1  christos 			# Convert each embedded ' to '\'',
    129   1.1  christos 			# then insert ' at the beginning of the first line,
    130   1.1  christos 			# and append ' at the end of the last line.
    131   1.1  christos 			# Finally, elide unnecessary '' pairs at the
    132   1.1  christos 			# beginning and end of the result and as part of
    133   1.1  christos 			# '\'''\'' sequences that result from multiple
    134   1.1  christos 			# adjacent quotes in he input.
    135   1.1  christos 			qarg="$(printf "%s\n" "$arg" | \
    136  1.59  christos 			    ${SED} -e "s/'/'\\\\''/g" \
    137   1.1  christos 				-e "1s/^/'/" -e "\$s/\$/'/" \
    138   1.1  christos 				-e "1s/^''//" -e "\$s/''\$//" \
    139   1.1  christos 				-e "s/'''/'/g"
    140   1.1  christos 				)"
    141   1.1  christos 			;;
    142   1.1  christos 		*)
    143   1.1  christos 			# Arg is not the empty string, and does not contain
    144   1.1  christos 			# any unsafe characters.  Leave it unchanged for
    145   1.1  christos 			# readability.
    146   1.1  christos 			qarg="${arg}"
    147   1.1  christos 			;;
    148   1.1  christos 		esac
    149   1.1  christos 		result="${result}${result:+ }${qarg}"
    150   1.1  christos 	done
    151   1.1  christos 	printf "%s\n" "$result"
    152   1.1  christos )}
    153   1.1  christos 
    154   1.1  christos # Convert arg $1 to a basic regular expression (as in sed)
    155   1.1  christos # that will match the arg.  This works by inserting backslashes
    156   1.1  christos # before characters that are special in basic regular expressions.
    157   1.1  christos # It also inserts backslashes before the extra characters specified
    158   1.1  christos # in $2 (which defaults to "/,").
    159   1.1  christos # XXX: Does not handle embedded newlines.
    160   1.1  christos # Usage: regex="$(bre_quote "${string}")"
    161   1.1  christos bre_quote()
    162   1.1  christos {
    163   1.1  christos 	local arg="$1"
    164   1.1  christos 	local extra="${2-/,}"
    165   1.1  christos 	printf "%s\n" "${arg}" | ${SED} -e 's/[][^$.*\\'"${extra}"']/\\&/g'
    166   1.1  christos }
    167   1.1  christos 
    168   1.1  christos # unprefix dir
    169   1.1  christos #	Remove any dir prefix from a list of paths on stdin,
    170   1.1  christos #	and write the result to stdout.  Useful for converting
    171   1.1  christos #	from ${DEST_DIR}/path to /path.
    172   1.1  christos #
    173   1.1  christos unprefix()
    174   1.1  christos {
    175   1.1  christos 	[ $# -eq 1 ] || err 3 "USAGE: unprefix dir"
    176   1.1  christos 	local prefix="${1%/}"
    177   1.1  christos 	prefix="$(bre_quote "${prefix}")"
    178   1.1  christos 
    179   1.1  christos 	${SED} -e "s,^${prefix}/,/,"
    180   1.1  christos }
    181   1.1  christos 
    182   1.1  christos # additem item description
    183   1.1  christos #	Add item to list of supported items to check/fix,
    184   1.1  christos #	which are checked/fixed by default if no item is requested by user.
    185   1.1  christos #
    186   1.1  christos additem()
    187   1.1  christos {
    188   1.1  christos 	[ $# -eq 2 ] || err 3 "USAGE: additem item description"
    189   1.1  christos 	defaultitems="${defaultitems}${defaultitems:+ }$1"
    190   1.1  christos 	eval desc_$1=\"\$2\"
    191   1.1  christos }
    192   1.1  christos 
    193   1.1  christos # adddisableditem item description
    194   1.1  christos #	Add item to list of supported items to check/fix,
    195   1.1  christos #	but execute the item only if the user asks for it explicitly.
    196   1.1  christos #
    197   1.1  christos adddisableditem()
    198   1.1  christos {
    199   1.1  christos 	[ $# -eq 2 ] || err 3 "USAGE: adddisableditem item description"
    200   1.1  christos 	otheritems="${otheritems}${otheritems:+ }$1"
    201   1.1  christos 	eval desc_$1=\"\$2\"
    202   1.1  christos }
    203   1.1  christos 
    204   1.1  christos # checkdir op dir mode
    205   1.1  christos #	Ensure dir exists, and if not, create it with the appropriate mode.
    206   1.1  christos #	Returns 0 if ok, 1 otherwise.
    207   1.1  christos #
    208   1.1  christos check_dir()
    209   1.1  christos {
    210   1.1  christos 	[ $# -eq 3 ] || err 3 "USAGE: check_dir op dir mode"
    211  1.59  christos 	local op="$1"
    212  1.59  christos 	local dir="$2"
    213  1.59  christos 	local mode="$3"
    214  1.59  christos 	[ -d "${dir}" ] && return 0
    215  1.59  christos 	if [ "${op}" = "check" ]; then
    216  1.59  christos 		msg "${dir} is not a directory"
    217   1.1  christos 		return 1
    218  1.59  christos 	elif ! mkdir -m "${mode}" "${dir}" ; then
    219  1.59  christos 		msg "Can't create missing ${dir}"
    220   1.1  christos 		return 1
    221   1.1  christos 	else
    222  1.59  christos 		msg "Missing ${dir} created"
    223   1.1  christos 	fi
    224   1.1  christos 	return 0
    225   1.1  christos }
    226   1.1  christos 
    227  1.44     lukem # check_ids op type file srcfile start id ...
    228   1.1  christos #	Check if file of type "users" or "groups" contains the relevant IDs.
    229   1.1  christos #	Use srcfile as a reference for the expected contents.
    230   1.1  christos #	The specified "id" names should be given in numerical order,
    231   1.1  christos #	with the first name corresponding to numerical value "start",
    232   1.1  christos #	and with the special name "SKIP" being used to mark gaps in the
    233   1.1  christos #	sequence.
    234   1.1  christos #	Returns 0 if ok, 1 otherwise.
    235   1.1  christos #
    236   1.1  christos check_ids()
    237   1.1  christos {
    238  1.62    rillig 	[ $# -ge 6 ] || err 3 "USAGE: checks_ids op type file srcfile start id ..."
    239  1.59  christos 	local op="$1"
    240  1.59  christos 	local type="$2"
    241  1.59  christos 	local file="$3"
    242  1.59  christos 	local srcfile="$4"
    243  1.59  christos 	local start="$5"
    244   1.1  christos 	shift 5
    245  1.59  christos 	#local ids="$@"
    246   1.1  christos 
    247  1.59  christos 	if [ ! -f "${file}" ]; then
    248  1.59  christos 		msg "${file} doesn't exist; can't check for missing ${type}"
    249   1.1  christos 		return 1
    250   1.1  christos 	fi
    251  1.59  christos 	if [ ! -r "${file}" ]; then
    252  1.59  christos 		msg "${file} is not readable; can't check for missing ${type}"
    253   1.1  christos 		return 1
    254   1.1  christos 	fi
    255  1.59  christos 	local notfixed=""
    256  1.59  christos 	if [ "${op}" = "fix" ]; then
    257  1.59  christos 		notfixed="${NOT_FIXED}"
    258   1.1  christos 	fi
    259  1.59  christos 	local missing="$(${AWK} -v start=$start -F: '
    260   1.1  christos 		BEGIN {
    261   1.1  christos 			for (x = 1; x < ARGC; x++) {
    262   1.1  christos 				if (ARGV[x] == "SKIP")
    263   1.1  christos 					continue;
    264   1.1  christos 				idlist[ARGV[x]]++;
    265   1.1  christos 				value[ARGV[x]] = start + x - 1;
    266   1.1  christos 			}
    267   1.1  christos 			ARGC=1
    268   1.1  christos 		}
    269   1.1  christos 		{
    270   1.1  christos 			found[$1]++
    271   1.1  christos 			number[$1] = $3
    272   1.1  christos 		}
    273   1.1  christos 		END {
    274   1.1  christos 			for (id in idlist) {
    275   1.1  christos 				if (!(id in found))
    276   1.1  christos 					printf("%s (missing)\n", id)
    277   1.1  christos 				else if (number[id] != value[id])
    278   1.1  christos 					printf("%s (%d != %d)\n", id,
    279   1.1  christos 					    number[id], value[id])
    280   1.1  christos 				start++;
    281   1.1  christos 			}
    282   1.1  christos 		}
    283  1.59  christos 	' "$@" < "${file}")"	|| return 1
    284  1.59  christos 	if [ -n "${missing}" ]; then
    285  1.59  christos 		msg "Error ${type}${notfixed}:" $(echo ${missing})
    286   1.1  christos 		msg "Use the following as a template:"
    287  1.59  christos 		set -- ${missing}
    288   1.1  christos 		while [ $# -gt 0 ]
    289   1.1  christos 		do
    290  1.59  christos 			${GREP} -E "^${1}:" ${srcfile}
    291   1.1  christos 			shift 2
    292  1.31    simonb 		done | sort -t: -k3n
    293   1.1  christos 		msg "and adjust if necessary."
    294   1.1  christos 		return 1
    295   1.1  christos 	fi
    296   1.1  christos 	return 0
    297   1.1  christos }
    298   1.1  christos 
    299  1.59  christos # populate_dir op onlynew src dst mode file ...
    300  1.59  christos #	Perform op ("check" or "fix") on files in src/ against dst/
    301   1.1  christos #	If op = "check" display missing or changed files, optionally with diffs.
    302   1.1  christos #	If op != "check" copies any missing or changed files.
    303   1.1  christos #	If onlynew evaluates to true, changed files are ignored.
    304   1.1  christos #	Returns 0 if ok, 1 otherwise.
    305   1.1  christos #
    306   1.1  christos populate_dir()
    307   1.1  christos {
    308  1.59  christos 	[ $# -ge 5 ] || err 3 "USAGE: populate_dir op onlynew src dst mode file ..."
    309  1.59  christos 	local op="$1"
    310  1.59  christos 	local onlynew="$2"
    311  1.59  christos 	local src="$3"
    312  1.59  christos 	local dst="$4"
    313  1.59  christos 	local mode="$5"
    314   1.1  christos 	shift 5
    315  1.59  christos 	#local files="$@"
    316   1.1  christos 
    317  1.59  christos 	if [ ! -d "${src}" ]; then
    318  1.59  christos 		msg "${src} is not a directory; skipping check"
    319   1.1  christos 		return 1
    320   1.1  christos 	fi
    321  1.59  christos 	check_dir "${op}" "${dst}" 755 || return 1
    322   1.1  christos 
    323  1.59  christos 	local cmpdir_rv=0
    324  1.60  christos 	local f fs fd error
    325   1.1  christos 	for f in "$@"; do
    326  1.60  christos 		fs="${src}/${f}"
    327  1.60  christos 		fd="${dst}/${f}"
    328  1.60  christos 		error=""
    329   1.1  christos 		if [ ! -f "${fd}" ]; then
    330  1.59  christos 			error="${fd} does not exist"
    331   1.1  christos 		elif ! cmp -s "${fs}" "${fd}" ; then
    332  1.59  christos 			if $onlynew; then	# leave existing ${fd} alone
    333   1.1  christos 				continue;
    334   1.1  christos 			fi
    335  1.59  christos 			error="${fs} != ${fd}"
    336   1.1  christos 		else
    337   1.1  christos 			continue
    338   1.1  christos 		fi
    339  1.59  christos 		if [ "${op}" = "check" ]; then
    340  1.59  christos 			msg "${error}"
    341   1.1  christos 			if [ -n "${DIFF_STYLE}" -a -f "${fd}" ]; then
    342   1.1  christos 				diff -${DIFF_STYLE} ${DIFF_OPT} "${fd}" "${fs}"
    343   1.1  christos 			fi
    344  1.59  christos 			cmpdir_rv=1
    345  1.59  christos 		elif ! ${RM} -f "${fd}" ||
    346   1.1  christos 		     ! cp -f "${fs}" "${fd}"; then
    347   1.1  christos 			msg "Can't copy ${fs} to ${fd}"
    348  1.59  christos 			cmpdir_rv=1
    349  1.59  christos 		elif ! chmod "${mode}" "${fd}"; then
    350  1.59  christos 			msg "Can't change mode of ${fd} to ${mode}"
    351  1.59  christos 			cmpdir_rv=1
    352   1.1  christos 		else
    353   1.1  christos 			msg "Copied ${fs} to ${fd}"
    354   1.1  christos 		fi
    355   1.1  christos 	done
    356  1.59  christos 	return ${cmpdir_rv}
    357   1.1  christos }
    358   1.1  christos 
    359  1.59  christos # compare_dir op src dst mode file ...
    360  1.59  christos #	Perform op ("check" or "fix") on files in src/ against dst/
    361   1.1  christos #	If op = "check" display missing or changed files, optionally with diffs.
    362   1.1  christos #	If op != "check" copies any missing or changed files.
    363   1.1  christos #	Returns 0 if ok, 1 otherwise.
    364   1.1  christos #
    365   1.1  christos compare_dir()
    366   1.1  christos {
    367  1.59  christos 	[ $# -ge 4 ] || err 3 "USAGE: compare_dir op src dst mode file ..."
    368  1.59  christos 	local op="$1"
    369  1.59  christos 	local src="$2"
    370  1.59  christos 	local dst="$3"
    371  1.59  christos 	local mode="$4"
    372   1.1  christos 	shift 4
    373  1.59  christos 	#local files="$@"
    374   1.1  christos 
    375  1.59  christos 	populate_dir "$op" false "$src" "$dst" "$mode" "$@"
    376   1.1  christos }
    377   1.1  christos 
    378  1.59  christos # move_file op src dst --
    379  1.59  christos #	Check (op == "check") or move (op != "check") from src to dst.
    380   1.1  christos #	Returns 0 if ok, 1 otherwise.
    381   1.1  christos #
    382   1.1  christos move_file()
    383   1.1  christos {
    384  1.59  christos 	[ $# -eq 3 ] || err 3 "USAGE: move_file op src dst"
    385  1.59  christos 	local op="$1"
    386  1.59  christos 	local src="$2"
    387  1.59  christos 	local dst="$3"
    388  1.59  christos 
    389  1.59  christos 	if [ -f "${src}" -a ! -f "${dst}" ]; then
    390  1.59  christos 		if [ "${op}" = "check" ]; then
    391  1.59  christos 			msg "Move ${src} to ${dst}"
    392   1.1  christos 			return 1
    393   1.1  christos 		fi
    394  1.59  christos 		if ! mv "${src}" "${dst}"; then
    395  1.59  christos 			msg "Can't move ${src} to ${dst}"
    396   1.1  christos 			return 1
    397   1.1  christos 		fi
    398  1.59  christos 		msg "Moved ${src} to ${dst}"
    399   1.1  christos 	fi
    400   1.1  christos 	return 0
    401   1.1  christos }
    402   1.1  christos 
    403   1.1  christos # rcconf_is_set op name var [verbose] --
    404   1.1  christos #	Load the rcconf for name, and check if obsolete rc.conf(5) variable
    405   1.1  christos #	var is defined or not.
    406   1.1  christos #	Returns 0 if defined (even to ""), otherwise 1.
    407   1.1  christos #	If verbose != "", print an obsolete warning if the var is defined.
    408   1.1  christos #
    409   1.1  christos rcconf_is_set()
    410   1.1  christos {
    411   1.1  christos 	[ $# -ge 3 ] || err 3 "USAGE: rcconf_is_set op name var [verbose]"
    412  1.59  christos 	local op="$1"
    413  1.59  christos 	local name="$2"
    414  1.59  christos 	local var="$3"
    415  1.59  christos 	local verbose="$4"
    416  1.59  christos 	local notfixed=""
    417  1.59  christos 	if [ "${op}" = "fix" ]; then
    418  1.59  christos 		notfixed="${NOT_FIXED}"
    419   1.1  christos 	fi
    420   1.1  christos 	(
    421   1.1  christos 		for f in \
    422   1.1  christos 		    "${DEST_DIR}/etc/rc.conf" \
    423  1.59  christos 		    "${DEST_DIR}/etc/rc.conf.d/${name}"; do
    424   1.1  christos 			[ -f "${f}" ] && . "${f}"
    425   1.1  christos 		done
    426  1.59  christos 		eval echo -n \"\${${var}}\" 1>&3
    427  1.60  christos 		if eval "[ -n \"\${${var}+SET}\" ]"; then
    428  1.59  christos 			if [ -n "${verbose}" ]; then
    429   1.1  christos 				msg \
    430  1.59  christos     "Obsolete rc.conf(5) variable '\$${var}' found.${notfixed}"
    431   1.1  christos 			fi
    432   1.1  christos 			exit 0
    433   1.1  christos 		else
    434   1.1  christos 			exit 1
    435   1.1  christos 		fi
    436   1.1  christos 	)
    437   1.1  christos }
    438   1.1  christos 
    439   1.1  christos # rcvar_is_enabled var
    440   1.1  christos #	Check if rcvar is enabled
    441   1.1  christos #
    442   1.1  christos rcvar_is_enabled()
    443   1.1  christos {
    444   1.1  christos 	[ $# -eq 1 ] || err 3 "USAGE: rcvar_is_enabled var"
    445  1.59  christos 	local var="$1"
    446   1.1  christos 	(
    447   1.1  christos 		[ -f "${DEST_DIR}/etc/rc.conf" ] && . "${DEST_DIR}/etc/rc.conf"
    448  1.59  christos 		eval val=\"\${${var}}\"
    449  1.59  christos 		case $val in
    450   1.1  christos 		#	"yes", "true", "on", or "1"
    451   1.1  christos 		[Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1)
    452   1.1  christos 			exit 0
    453   1.1  christos 			;;
    454   1.1  christos 
    455   1.1  christos 		*)
    456   1.1  christos 			exit 1
    457   1.1  christos 			;;
    458   1.1  christos 		esac
    459   1.1  christos 	)
    460   1.1  christos }
    461   1.1  christos 
    462  1.44     lukem # find_file_in_dirlist() file message dir1 ... --
    463   1.1  christos #	Find which directory file is in, and sets ${dir} to match.
    464   1.1  christos #	Returns 0 if matched, otherwise 1 (and sets ${dir} to "").
    465   1.1  christos #
    466   1.1  christos #	Generally, check the directory for the "checking from source" case,
    467   1.1  christos #	and then the directory for the "checking from extracted etc.tgz" case.
    468   1.1  christos #
    469   1.1  christos find_file_in_dirlist()
    470   1.1  christos {
    471  1.44     lukem 	[ $# -ge 3 ] || err 3 "USAGE: find_file_in_dirlist file msg dir1 ..."
    472   1.1  christos 
    473  1.59  christos 	local file="$1" ; shift
    474  1.59  christos 	local msg="$1" ; shift
    475  1.59  christos 	local dir1st=	# first dir in list
    476  1.59  christos 	# returns dir
    477   1.1  christos 	for dir in "$@"; do
    478  1.59  christos 		: ${dir1st:="${dir}"}
    479  1.59  christos 		if [ -f "${dir}/${file}" ]; then
    480  1.59  christos 			if [ "${dir1st}" != "${dir}" ]; then
    481   1.1  christos 				msg \
    482  1.59  christos     "(Checking for ${msg} from ${dir} instead of ${dir1st})"
    483   1.1  christos 			fi
    484   1.1  christos 			return 0
    485   1.1  christos 		fi
    486   1.1  christos 	done
    487  1.59  christos 	msg "Can't find source directory for ${msg}"
    488   1.1  christos 	return 1
    489   1.1  christos }
    490   1.1  christos 
    491   1.1  christos # file_exists_exact path
    492   1.1  christos #	Returns true if a file exists in the ${DEST_DIR} whose name
    493   1.1  christos #	is exactly ${path}, interpreted in a case-sensitive way
    494   1.1  christos #	even if the underlying file system is case-insensitive.
    495   1.1  christos #
    496   1.1  christos #	The path must begin with '/' or './', and is interpreted as
    497   1.1  christos #	being relative to ${DEST_DIR}.
    498   1.1  christos #
    499   1.1  christos file_exists_exact()
    500   1.1  christos {
    501   1.1  christos 	[ -n "$1" ] || err 3 "USAGE: file_exists_exact path"
    502  1.59  christos 	local path="${1#.}"
    503  1.59  christos 	[ -h "${DEST_DIR}${path}" ] || \
    504  1.59  christos 		[ -e "${DEST_DIR}${path}" ] || return 1
    505  1.59  christos 	while [ "${path}" != "/" -a "${path}" != "." ] ; do
    506  1.59  christos 		local dirname="$(dirname "${path}" 2>/dev/null)"
    507  1.59  christos 		local basename="$(basename "${path}" 2>/dev/null)"
    508  1.59  christos 		ls -fa "${DEST_DIR}${dirname}" 2> /dev/null \
    509  1.59  christos 			| ${GREP} -q -F -x "${basename}" \
    510   1.1  christos 			|| return 1
    511  1.59  christos 		path="${dirname}"
    512   1.1  christos 	done
    513   1.1  christos 	return 0
    514   1.1  christos }
    515   1.1  christos 
    516   1.1  christos # obsolete_paths op
    517   1.1  christos #	Obsolete the list of paths provided on stdin.
    518   1.1  christos #	Each path should start with '/' or './', and
    519   1.1  christos #	will be interpreted relative to ${DEST_DIR}.
    520   1.1  christos #
    521   1.1  christos obsolete_paths()
    522   1.1  christos {
    523  1.36     lukem 	[ -n "$1" ] || err 3 "USAGE: obsolete_paths fix|check"
    524  1.59  christos 	local op="$1"
    525  1.59  christos 	local failed=0
    526  1.59  christos 	local ofile cmd ftype
    527   1.1  christos 
    528   1.1  christos 	while read ofile; do
    529   1.1  christos 		if ! ${file_exists_exact} "${ofile}"; then
    530   1.1  christos 			continue
    531   1.1  christos 		fi
    532   1.1  christos 		ofile="${DEST_DIR}${ofile#.}"
    533  1.59  christos 		cmd="${RM}"
    534   1.1  christos 		ftype="file"
    535   1.1  christos 		if [ -h "${ofile}" ]; then
    536   1.1  christos 			ftype="link"
    537   1.1  christos 		elif [ -d "${ofile}" ]; then
    538   1.1  christos 			ftype="directory"
    539   1.1  christos 			cmd="rmdir"
    540   1.1  christos 		elif [ ! -e "${ofile}" ]; then
    541   1.1  christos 			continue
    542   1.1  christos 		fi
    543   1.1  christos 		if [ "${op}" = "check" ]; then
    544   1.1  christos 			msg "Remove obsolete ${ftype} ${ofile}"
    545   1.1  christos 			failed=1
    546   1.1  christos 		elif ! eval "${cmd} \"\${ofile}\""; then
    547   1.1  christos 			msg "Can't remove obsolete ${ftype} ${ofile}"
    548   1.1  christos 			failed=1
    549   1.1  christos 		else
    550   1.1  christos 			msg "Removed obsolete ${ftype} ${ofile}"
    551   1.1  christos 		fi
    552   1.1  christos 	done
    553   1.1  christos 	return ${failed}
    554   1.1  christos }
    555   1.1  christos 
    556   1.1  christos # obsolete_libs dir
    557   1.1  christos #	Display the minor/teeny shared libraries in dir that are considered
    558   1.1  christos #	to be obsolete.
    559   1.1  christos #
    560   1.1  christos #	The implementation supports removing obsolete major libraries
    561   1.1  christos #	if the awk variable AllLibs is set, although there is no way to
    562   1.1  christos #	enable that in the enclosing shell function as this time.
    563   1.1  christos #
    564   1.1  christos obsolete_libs()
    565   1.1  christos {
    566   1.1  christos 	[ $# -eq 1 ] || err 3 "USAGE: obsolete_libs dir"
    567  1.59  christos 	local dir="$1"
    568   1.1  christos 
    569   1.1  christos 	_obsolete_libs "${dir}"
    570   1.1  christos 	_obsolete_libs "/usr/libdata/debug/${dir}"
    571   1.1  christos }
    572   1.1  christos 
    573   1.5  christos exclude()
    574   1.5  christos {
    575   1.5  christos 	local dollar
    576   1.5  christos 	case "$1" in
    577   1.5  christos 	-t)
    578   1.5  christos 		dollar='$'
    579   1.5  christos 		shift
    580   1.5  christos 		;;
    581   1.5  christos 	*)
    582   1.5  christos 		dollar=
    583   1.5  christos 		;;
    584   1.5  christos 	esac
    585   1.5  christos 	if [ -z "$*" ]; then
    586   1.5  christos 		cat
    587   1.5  christos 	else
    588   1.5  christos 		eval ${GREP} -v -E "'(^$(echo $* | \
    589   1.5  christos 		    ${SED} -e s/\\./\\\\./g -e 's/ /'${dollar}'|^/'g)${dollar})'"
    590   1.5  christos 	fi
    591   1.5  christos }
    592   1.5  christos 
    593   1.5  christos #
    594  1.66       uwe # Find all the symlink targets of shared libraries and exclude them
    595  1.66       uwe # from consideration for removal.
    596  1.66       uwe #
    597  1.66       uwe # This protects "new old" libs after downgrading a system.  Say, you
    598  1.66       uwe # had a more recent system that comes with libfoo.so.1.2 and then
    599  1.66       uwe # downgraded to an older version that had libfoo.so.1.1.  You still
    600  1.66       uwe # have 1.2 that "wins" the competition for the "libfoo.so.1" stem and
    601  1.66       uwe # thus 1.1 is considered obsolete by the awk script in _obsolete_libs
    602  1.66       uwe # below.  But your libfoo.so.1 now points to 1.1 so deleting 1.1 will
    603  1.66       uwe # render your system broken.  exclude_libs is fed the output of
    604  1.66       uwe # potentially obsolete libs and absolves those (libfoo.so.1.1) that
    605  1.66       uwe # are a target of a symlink (libfoo.so.1 -> libfoo.so.1.1)
    606   1.5  christos #
    607  1.37     lukem exclude_libs()
    608  1.37     lukem {
    609  1.66       uwe 	local targets="$(find lib*.so.* -prune -type l -exec readlink '{}' + 2> /dev/null \
    610   1.5  christos 	    | ${SED} -e 's@.*/@@' | ${SORT} -u)"
    611  1.66       uwe 	${GREP} -F -v -x "$targets"
    612   1.5  christos }
    613   1.5  christos 
    614   1.1  christos _obsolete_libs()
    615   1.1  christos {
    616  1.59  christos 	local dir="$1"
    617   1.1  christos 
    618   1.1  christos 	(
    619   1.1  christos 
    620  1.64       uwe 	[ -e "${DEST_DIR}/${dir}" ] || return 0
    621  1.64       uwe 	cd "${DEST_DIR}/${dir}" || err 2 "can't cd to ${DEST_DIR}/${dir}"
    622  1.64       uwe 
    623  1.64       uwe 	# TODO: make this selectable with a command line option?
    624  1.64       uwe 	local maybe_purge_major
    625  1.64       uwe 	#maybe_purge_major='-v PurgeOldMajor=1'
    626   1.1  christos 
    627  1.64       uwe 	printf '%s\n' lib*.so.* | ${AWK} ${maybe_purge_major} '
    628   1.1  christos #{
    629   1.1  christos 
    630  1.64       uwe BEGIN {
    631  1.64       uwe 	BASE_REGEX  = "^lib.*\\.so\\."
    632  1.64       uwe 	MAJOR_REGEX = (BASE_REGEX "[0-9]+\\.")
    633   1.1  christos 
    634  1.64       uwe 	# in the usual case different major versions of the same
    635  1.64       uwe 	# library are considered different stems and do not compete
    636  1.64       uwe 	# with each other, we keep one of each, but you may request to
    637  1.64       uwe 	# purge old majors, in which case all versions compete for the
    638  1.64       uwe 	# single basename stem
    639  1.64       uwe 	if (PurgeOldMajor)
    640  1.64       uwe 		keepone = BASE_REGEX
    641  1.64       uwe 	else
    642  1.64       uwe 		keepone = MAJOR_REGEX
    643  1.64       uwe }
    644  1.64       uwe 
    645  1.64       uwe # major version symlink
    646  1.64       uwe PurgeOldMajor && /^lib.*\.so\.[0-9]+$/ {
    647  1.64       uwe 	checklib(major, $0, BASE_REGEX)
    648  1.64       uwe }
    649  1.64       uwe 
    650  1.64       uwe # specific minor version of a library
    651  1.64       uwe /^lib.*\.so\.[0-9]+\.[0-9]+(\.[0-9]+)?(\.debug)?$/ {
    652  1.64       uwe 	checklib(minor, $0, keepone)
    653  1.64       uwe }
    654  1.64       uwe 
    655  1.64       uwe function checklib(latest, libname, stem_regex) {
    656  1.64       uwe 	if (! match(libname, stem_regex))
    657   1.1  christos 		return
    658  1.64       uwe 	stem = substr(libname, RSTART, RLENGTH)
    659  1.64       uwe 	vers = substr(libname, RLENGTH + 1)
    660  1.64       uwe 
    661  1.64       uwe 	# first time we see this stem? just record the version
    662  1.64       uwe 	if (! (stem in latest)) {
    663  1.64       uwe 		latest[stem] = vers
    664   1.1  christos 		return
    665   1.1  christos 	}
    666  1.64       uwe 
    667  1.64       uwe 	# split version suffixes into the list of numeric components
    668  1.64       uwe 	oversc = split(latest[stem], overs, ".")
    669  1.64       uwe 	nversc = split(vers,         nvers, ".")
    670  1.64       uwe 	maxc = (oversc > nversc) ? oversc : nversc
    671  1.64       uwe 
    672  1.64       uwe 	# is the new version "later" than the one we have seen?
    673  1.64       uwe 	for (i = 1; i <= maxc; ++i) {
    674  1.64       uwe 		cmp = (overs[i]+0) - (nvers[i]+0)
    675  1.64       uwe 
    676  1.64       uwe 		if (cmp < 0) {
    677  1.64       uwe 			# the one we have seen is older, so report it
    678  1.64       uwe 			# as obsolete and update the latest seen
    679  1.64       uwe 			# version to this new one
    680  1.64       uwe 			print stem latest[stem]
    681  1.64       uwe 			latest[stem] = vers
    682   1.1  christos 			return
    683  1.64       uwe 		}
    684  1.64       uwe 		else if (cmp > 0) {
    685  1.64       uwe 			# the one we have just read is older than the
    686  1.64       uwe 			# one we have seen previously, so report this
    687  1.64       uwe 			# "new" one as obsolete
    688  1.64       uwe 			print libname
    689   1.1  christos 			return
    690   1.1  christos 		}
    691   1.1  christos 	}
    692   1.1  christos }
    693   1.1  christos 
    694  1.66       uwe 	# the ouput is further filtered by exclude_libs that protects
    695  1.64       uwe 	# libraries that have symlinks pointing to them, which one
    696  1.64       uwe 	# encounters when downgrading
    697  1.64       uwe #}'	\
    698  1.64       uwe 	| exclude_libs \
    699  1.64       uwe 	| ${SED} "s|^|${dir}/|"
    700   1.1  christos 
    701   1.1  christos 	)
    702   1.1  christos }
    703   1.1  christos 
    704   1.1  christos # obsolete_stand dir
    705   1.1  christos #	Prints the names of all obsolete files and subdirs below the
    706   1.1  christos #	provided dir.  dir should be something like /stand/${MACHINE}.
    707   1.1  christos #	The input dir and all output paths are interpreted
    708   1.1  christos #	relative to ${DEST_DIR}.
    709   1.1  christos #
    710   1.1  christos #	Assumes that the numerically largest subdir is current, and all
    711   1.1  christos #	others are obsolete.
    712   1.1  christos #
    713   1.1  christos obsolete_stand()
    714   1.1  christos {
    715   1.1  christos 	[ $# -eq 1 ] || err 3 "USAGE: obsolete_stand dir"
    716   1.1  christos 	local dir="$1"
    717   1.1  christos 	local subdir
    718   1.1  christos 
    719   1.1  christos 	if ! [ -d "${DEST_DIR}${dir}" ]; then
    720   1.1  christos 		msg "${DEST_DIR}${dir} doesn't exist; can't check for obsolete files"
    721   1.1  christos 		return 1
    722   1.1  christos 	fi
    723   1.1  christos 
    724   1.1  christos 	( cd "${DEST_DIR}${dir}" && ls -1d [0-9]*[0-9]/. ) \
    725   1.1  christos 	| ${GREP} -v '[^0-9./]' \
    726   1.1  christos 	| sort -t. -r -n -k1,1 -k2,2 -k3,3 \
    727   1.1  christos 	| tail -n +2 \
    728   1.1  christos 	| while read subdir ; do
    729   1.1  christos 		subdir="${subdir%/.}"
    730   1.1  christos 		find "${DEST_DIR}${dir}/${subdir}" -depth -print
    731   1.1  christos 	done \
    732   1.1  christos 	| unprefix "${DEST_DIR}"
    733   1.1  christos }
    734   1.1  christos 
    735   1.1  christos # modify_file op srcfile scratchfile awkprog
    736   1.1  christos #	Apply awkprog to srcfile sending output to scratchfile, and
    737   1.1  christos #	if appropriate replace srcfile with scratchfile.
    738   1.1  christos #
    739   1.1  christos modify_file()
    740   1.1  christos {
    741   1.1  christos 	[ $# -eq 4 ] || err 3 "USAGE: modify_file op file scratch awkprog"
    742   1.1  christos 
    743  1.59  christos 	local op="$1"
    744  1.59  christos 	local file="$2"
    745  1.59  christos 	local scratch="$3"
    746  1.59  christos 	local prog="$4"
    747  1.59  christos 	local failed=0
    748  1.59  christos 	local line
    749  1.59  christos 
    750  1.59  christos 	${AWK} "${prog}" < "${file}" > "${scratch}"
    751  1.59  christos 	if ! cmp -s "${file}" "${scratch}"; then
    752  1.59  christos 		diff "${file}" "${scratch}" > "${scratch}.diffs"
    753  1.59  christos 		if [ "${op}" = "check" ]; then
    754  1.59  christos 			msg "${file} needs the following changes:"
    755  1.59  christos 			mffailed=1
    756  1.59  christos 		elif ! ${RM} -f "${file}" ||
    757  1.59  christos 		     ! cp -f "${scratch}" "${file}"; then
    758  1.59  christos 			msg "${file} changes not applied:"
    759  1.59  christos 			mffailed=1
    760   1.1  christos 		else
    761  1.59  christos 			msg "${file} changes applied:"
    762   1.1  christos 		fi
    763  1.59  christos 		while read line; do
    764  1.59  christos 			msg "	${line}"
    765  1.59  christos 		done < "${scratch}.diffs"
    766   1.1  christos 	fi
    767  1.59  christos 	return ${failed}
    768   1.1  christos }
    769   1.1  christos 
    770   1.1  christos 
    771   1.1  christos # contents_owner op directory user group
    772   1.1  christos #	Make sure directory and contents are owned (and group-owned)
    773   1.1  christos #	as specified.
    774   1.1  christos #
    775   1.1  christos contents_owner()
    776   1.1  christos {
    777   1.1  christos 	[ $# -eq 4 ] || err 3 "USAGE: contents_owner op dir user group"
    778   1.1  christos 
    779  1.59  christos 	local op="$1"
    780  1.59  christos 	local dir="$2"
    781  1.59  christos 	local user="$3"
    782  1.59  christos 	local grp="$4"
    783  1.59  christos 	local files error
    784  1.59  christos 
    785  1.59  christos 	if [ "${op}" = "check" ]; then
    786  1.59  christos 		files=$(find "${dir}" \( \( ! -user "${user}" \) -o \
    787  1.59  christos 		                \( ! -group "${grp}" \) \) )
    788  1.59  christos 		error=$?
    789  1.59  christos 		if [ ! -z "$files" ] || [ $error != 0 ]; then
    790  1.59  christos 			msg "${dir} and contents not all owned by" \
    791  1.59  christos 			    "${user}:${grp}"
    792   1.1  christos 			return 1
    793   1.1  christos 		else
    794   1.1  christos 			return 0
    795   1.1  christos 		fi
    796  1.59  christos 	elif [ "${op}" = "fix" ]; then
    797  1.59  christos 		find "${dir}" \( \( ! -user "${user}" \) -o \
    798  1.59  christos 		\( ! -group "${grp}" \) \) \
    799  1.59  christos 		-exec chown "${user}:${grp}" -- {} \;
    800   1.1  christos 	fi
    801   1.1  christos }
    802   1.1  christos 
    803  1.44     lukem # get_makevar var ...
    804   1.1  christos #	Retrieve the value of a user-settable system make variable
    805   1.1  christos get_makevar()
    806   1.1  christos {
    807  1.59  christos 	local var value
    808   1.1  christos 	$SOURCEMODE || err 3 "get_makevar must be used in source mode"
    809  1.44     lukem 	[ $# -eq 0 ] && err 3 "USAGE: get_makevar var ..."
    810   1.1  christos 
    811  1.59  christos 	for var in "$@"; do
    812  1.59  christos 		value="$(echo '.include <bsd.own.mk>' | \
    813  1.59  christos 		    ${MAKE} -f - -V "\${${var}}")"
    814   1.1  christos 
    815  1.59  christos 		eval ${var}=\"\${value}\"
    816   1.1  christos 	done
    817   1.1  christos }
    818   1.1  christos 
    819   1.1  christos # detect_x11
    820   1.1  christos #	Detect if X11 components should be analysed and set values of
    821   1.1  christos #	relevant variables.
    822   1.1  christos detect_x11()
    823   1.1  christos {
    824   1.1  christos 	if $SOURCEMODE; then
    825   1.1  christos 		get_makevar MKX11 X11ROOTDIR X11SRCDIR
    826   1.1  christos 	else
    827   1.1  christos 		if [ -f "${SRC_DIR}/etc/mtree/set.xetc" ]; then
    828   1.1  christos 			MKX11=yes
    829   1.1  christos 			X11ROOTDIR=/this/value/isnt/used/yet
    830   1.1  christos 		else
    831   1.1  christos 			MKX11=no
    832   1.1  christos 			X11ROOTDIR=
    833   1.1  christos 		fi
    834   1.1  christos 		X11SRCDIR=/nonexistent/xsrc
    835   1.1  christos 	fi
    836   1.1  christos }
    837   1.1  christos 
    838   1.1  christos #
    839   1.1  christos #	find out where MAKEDEV lives, set MAKEDEV_DIR appropriately
    840   1.1  christos #
    841   1.1  christos find_makedev()
    842   1.1  christos {
    843   1.1  christos 	if [ -e "${DEST_DIR}/dev/MAKEDEV" ]; then
    844   1.1  christos 		MAKEDEV_DIR="${DEST_DIR}/dev"
    845   1.1  christos 	elif [ -e "${DEST_DIR}/etc/MAKEDEV" ]; then
    846   1.1  christos 		MAKEDEV_DIR="${DEST_DIR}/etc"
    847   1.1  christos 	else
    848   1.1  christos 		MAKEDEV_DIR="${DEST_DIR}/dev"
    849   1.1  christos 	fi
    850   1.1  christos }
    851   1.1  christos 
    852   1.1  christos 
    853   1.1  christos #
    854   1.1  christos #	items
    855   1.1  christos #	-----
    856   1.1  christos #
    857  1.37     lukem # NOTE: Keep these items sorted, except for obsolete* which are listed last.
    858  1.37     lukem #
    859   1.1  christos 
    860   1.1  christos #
    861  1.37     lukem #	atf
    862   1.1  christos #
    863   1.1  christos 
    864  1.37     lukem handle_atf_user()
    865  1.37     lukem {
    866  1.37     lukem 	local op="$1"
    867  1.59  christos 	local conf="$2"
    868  1.59  christos 	local option="unprivileged-user"
    869  1.59  christos 	local old="_atf"
    870  1.59  christos 	local new="_tests"
    871  1.37     lukem 	local failed=0
    872  1.37     lukem 
    873  1.59  christos 	local c=$(readlink -f "${conf}")
    874  1.59  christos 	if ${GREP} -q "[^#]*${option}[ \t]*=.*${old}" "${c}"
    875  1.37     lukem 	then
    876  1.59  christos 		if [ "${op}" = "fix" ]; then
    877  1.59  christos 			${SED} -e "/[^#]*${option}[\ t]*=/s/${old}/${new}/" \
    878  1.59  christos 			    "${c}" >"${c}.new"
    879  1.37     lukem 			failed=$(( ${failed} + $? ))
    880  1.59  christos 			mv "${c}.new" "${c}"
    881  1.37     lukem 			failed=$(( ${failed} + $? ))
    882  1.59  christos 			msg "Set ${option}=${new} in ${c}"
    883  1.37     lukem 		else
    884  1.59  christos 			msg "${option}=${old} in ${c} should be " \
    885  1.59  christos 			    "${option}=${new}"
    886  1.37     lukem 			failed=1
    887  1.37     lukem 		fi
    888  1.37     lukem 	fi
    889  1.37     lukem 
    890  1.37     lukem 	return ${failed}
    891  1.37     lukem }
    892  1.37     lukem 
    893  1.37     lukem additem atf "install missing atf configuration files and validate them"
    894  1.37     lukem do_atf()
    895   1.1  christos {
    896  1.37     lukem 	[ -n "$1" ] || err 3 "USAGE: do_atf fix|check"
    897  1.59  christos 	local conf="${DEST_DIR}/etc/atf/common.conf"
    898  1.59  christos 	local atfdir="${DEST_DIR}/etc/atf"
    899  1.59  christos 	local op="$1"
    900  1.59  christos 	local failed=0
    901   1.1  christos 
    902  1.37     lukem 	# Ensure atf configuration files are in place.
    903  1.37     lukem 	if find_file_in_dirlist NetBSD.conf "NetBSD.conf" \
    904  1.37     lukem 	    "${SRC_DIR}/external/bsd/atf/etc/atf" \
    905  1.37     lukem 	    "${SRC_DIR}/etc/atf"; then
    906  1.59  christos 		    # ${dir} is set by find_file_in_dirlist()
    907  1.59  christos 		    populate_dir "${op}" true "${dir}" "${atfdir}" 644 \
    908  1.37     lukem 		    NetBSD.conf common.conf || failed=1
    909  1.37     lukem 	else
    910  1.37     lukem 		failed=1
    911  1.37     lukem 	fi
    912  1.37     lukem 	if find_file_in_dirlist atf-run.hooks "atf-run.hooks" \
    913  1.37     lukem 	    "${SRC_DIR}/external/bsd/atf/dist/tools/sample" \
    914  1.37     lukem 	    "${SRC_DIR}/etc/atf"; then
    915  1.59  christos 		# ${dir} is set by find_file_in_dirlist()
    916  1.59  christos 		populate_dir "${op}" true "${dir}" "${atfdir}" 644 \
    917  1.37     lukem 		    atf-run.hooks || failed=1
    918  1.37     lukem 	else
    919  1.37     lukem 		failed=1
    920  1.37     lukem 	fi
    921  1.37     lukem 
    922  1.37     lukem 	# Validate the _atf to _tests user/group renaming.
    923  1.59  christos 	if [ -f "${conf}" ]; then
    924  1.59  christos 		handle_atf_user "${op}" "${conf}" || failed=1
    925  1.37     lukem 	else
    926  1.37     lukem 		failed=1
    927  1.37     lukem 	fi
    928  1.37     lukem 
    929  1.37     lukem 	return ${failed}
    930  1.37     lukem }
    931  1.37     lukem 
    932   1.1  christos 
    933  1.37     lukem #
    934  1.37     lukem #	autofsconfig
    935  1.37     lukem #
    936   1.1  christos 
    937  1.37     lukem additem autofsconfig "automounter configuration files"
    938  1.37     lukem do_autofsconfig()
    939  1.37     lukem {
    940  1.37     lukem 	[ -n "$1" ] || err 3 "USAGE: do_autofsconfig fix|check"
    941  1.37     lukem 	local autofs_files="
    942  1.37     lukem include_ldap
    943  1.37     lukem include_nis
    944  1.37     lukem special_hosts
    945  1.37     lukem special_media
    946  1.37     lukem special_noauto
    947  1.37     lukem special_null
    948  1.37     lukem "
    949  1.59  christos 	local op="$1"
    950  1.59  christos 	local failed=0
    951  1.59  christos 
    952  1.37     lukem 	if [ "$op" = "fix" ]; then
    953  1.37     lukem 		mkdir -p "${DEST_DIR}/etc/autofs"
    954   1.1  christos 	fi
    955  1.37     lukem 	failed=$(( ${failed} + $? ))
    956  1.39   mlelstv 	populate_dir "$op" true "${SRC_DIR}/etc" \
    957  1.37     lukem 	    "${DEST_DIR}/etc" \
    958  1.37     lukem 	    644 \
    959  1.37     lukem 	    auto_master
    960  1.37     lukem 	failed=$(( ${failed} + $? ))
    961  1.39   mlelstv 	populate_dir "$op" true "${SRC_DIR}/etc/autofs" \
    962  1.37     lukem 	    "${DEST_DIR}/etc/autofs" \
    963  1.37     lukem 	    644 \
    964  1.37     lukem 	    ${autofs_files}
    965   1.1  christos 	return ${failed}
    966   1.1  christos }
    967   1.1  christos 
    968  1.37     lukem 
    969  1.37     lukem #
    970  1.37     lukem #	blocklist
    971  1.37     lukem #
    972  1.37     lukem 
    973  1.37     lukem fixblock()
    974  1.37     lukem {
    975  1.29       rin 	local op="$1"
    976  1.29       rin 	local target="${DEST_DIR}$2"
    977  1.29       rin 
    978  1.29       rin 	if [ ! -f "${target}" ]; then
    979  1.29       rin 		continue
    980  1.29       rin 	fi
    981  1.29       rin 
    982  1.29       rin 	if ${GREP} '[bB]lack' "${target}" > /dev/null; then
    983  1.29       rin 		if [ "$1" = "check" ]; then
    984  1.29       rin 			msg "Fix old configuration file(s)."
    985  1.29       rin 			return 1
    986  1.29       rin 		else
    987  1.29       rin 			local p=$(${STAT} -f %Lp "${target}")
    988  1.29       rin 			chmod u+w "${target}" || return 1
    989  1.32  christos 			if [ "$2" = "/etc/npf.conf" ]; then
    990  1.33  christos 				${SED} -i -e 's/"blacklistd"/"blocklistd"/g' "${target}"
    991  1.32  christos 			else
    992  1.32  christos 				${SED} -i -e 's/\([bB]\)lacklist/\1locklist/g' "${target}"
    993  1.32  christos 			fi
    994  1.29       rin 			chmod "${p}" "${target}"
    995  1.24  christos 		fi
    996  1.29       rin 	fi
    997  1.24  christos }
    998  1.24  christos 
    999  1.24  christos additem blocklist "rename old files to blocklist"
   1000  1.24  christos do_blocklist()
   1001  1.24  christos {
   1002  1.36     lukem 	[ -n "$1" ] || err 3 "USAGE: do_blocklist fix|check"
   1003  1.29       rin 	local op="$1"
   1004  1.60  christos 	local i old
   1005  1.30  riastrad 
   1006  1.24  christos 	# if we are actually using blocklistd
   1007  1.29       rin 	for i in /var/db/blacklist.db /etc/blacklistd.conf; do
   1008  1.60  christos 		old="${DEST_DIR}${i}"
   1009  1.29       rin 		if [ ! -f "${old}" ]; then
   1010  1.29       rin 			continue
   1011  1.29       rin 		elif [ "$1" = "check" ]; then
   1012  1.29       rin 			msg "Rename old file(s)."
   1013  1.29       rin 			return 1
   1014  1.29       rin 		fi
   1015  1.29       rin 		local new=$(echo "${old}" | ${SED} s/black/block/)
   1016  1.29       rin 		mv "${old}" "${new}" || return 1
   1017  1.29       rin 	done
   1018  1.24  christos 
   1019  1.29       rin 	for i in /etc/rc.conf /etc/npf.conf /etc/blocklistd.conf \
   1020  1.29       rin 	    /etc/defaults/rc.conf; do
   1021  1.29       rin 		fixblock "${op}" "${i}" || return 1
   1022  1.29       rin 	done
   1023  1.24  christos }
   1024  1.24  christos 
   1025  1.37     lukem 
   1026  1.37     lukem #
   1027  1.37     lukem #	bluetooth
   1028  1.37     lukem #
   1029  1.37     lukem 
   1030  1.37     lukem additem bluetooth "Bluetooth configuration is up to date"
   1031  1.37     lukem do_bluetooth()
   1032  1.37     lukem {
   1033  1.37     lukem 	[ -n "$1" ] || err 3 "USAGE: do_bluetooth fix|check"
   1034  1.59  christos 	local op="$1"
   1035  1.59  christos 	local failed=0
   1036  1.37     lukem 
   1037  1.37     lukem 	populate_dir "${op}" true \
   1038  1.37     lukem 		"${SRC_DIR}/etc/bluetooth" "${DEST_DIR}/etc/bluetooth" 644 \
   1039  1.37     lukem 		hosts protocols btattach.conf btdevctl.conf
   1040  1.37     lukem 	failed=$(( ${failed} + $? ))
   1041  1.37     lukem 
   1042  1.37     lukem 	move_file "${op}" "${DEST_DIR}/var/db/btdev.xml" \
   1043  1.37     lukem 			"${DEST_DIR}/var/db/btdevctl.plist"
   1044  1.37     lukem 	failed=$(( ${failed} + $? ))
   1045  1.37     lukem 
   1046  1.59  christos 	local notfixed=""
   1047  1.37     lukem 	if [ "${op}" = "fix" ]; then
   1048  1.37     lukem 		notfixed="${NOT_FIXED}"
   1049  1.37     lukem 	fi
   1050  1.37     lukem 	for _v in btattach btconfig btdevctl; do
   1051  1.37     lukem 		if rcvar_is_enabled "${_v}"; then
   1052  1.37     lukem 			msg \
   1053  1.37     lukem     "${_v} is obsolete in rc.conf(5)${notfixed}: use bluetooth=YES"
   1054  1.37     lukem 			failed=$(( ${failed} + 1 ))
   1055  1.37     lukem 		fi
   1056  1.37     lukem 	done
   1057  1.37     lukem 
   1058  1.37     lukem 	return ${failed}
   1059  1.37     lukem }
   1060  1.37     lukem 
   1061  1.37     lukem 
   1062  1.37     lukem #
   1063  1.37     lukem #	catpages
   1064  1.37     lukem #
   1065  1.37     lukem 
   1066  1.37     lukem obsolete_catpages()
   1067  1.37     lukem {
   1068  1.59  christos 	local op="$1"
   1069  1.59  christos 	local basedir="$2"
   1070  1.59  christos 	local section="$3"
   1071  1.59  christos 	local mandir="${basedir}/man${section}"
   1072  1.59  christos 	local catdir="${basedir}/cat${section}"
   1073  1.37     lukem 	test -d "$mandir" || return 0
   1074  1.37     lukem 	test -d "$catdir" || return 0
   1075  1.37     lukem 	(cd "$mandir" && find . -type f) | {
   1076  1.59  christos 	local failed=0
   1077  1.37     lukem 	while read manpage; do
   1078  1.37     lukem 		manpage="${manpage#./}"
   1079  1.37     lukem 		case "$manpage" in
   1080  1.37     lukem 		*.Z)
   1081  1.37     lukem 			catname="$catdir/${manpage%.*.Z}.0"
   1082  1.37     lukem 			;;
   1083  1.37     lukem 		*.gz)
   1084  1.37     lukem 			catname="$catdir/${manpage%.*.gz}.0"
   1085  1.37     lukem 			;;
   1086  1.37     lukem 		*)
   1087  1.37     lukem 			catname="$catdir/${manpage%.*}.0"
   1088  1.37     lukem 			;;
   1089  1.37     lukem 		esac
   1090  1.37     lukem 		test -e "$catname" -a "$catname" -ot "$mandir/$manpage" || continue
   1091  1.59  christos 		if [ "${op}" = "fix" ]; then
   1092  1.59  christos 			${RM} "$catname"
   1093  1.37     lukem 			failed=$(( ${failed} + $? ))
   1094  1.37     lukem 			msg "Removed obsolete cat page $catname"
   1095  1.37     lukem 		else
   1096  1.37     lukem 			msg "Obsolete cat page $catname"
   1097  1.37     lukem 			failed=1
   1098  1.37     lukem 		fi
   1099  1.37     lukem 	done
   1100  1.37     lukem 	exit $failed
   1101  1.37     lukem 	}
   1102  1.37     lukem }
   1103  1.37     lukem 
   1104  1.37     lukem additem catpages "remove outdated cat pages"
   1105  1.37     lukem do_catpages()
   1106  1.37     lukem {
   1107  1.59  christos 	local op="$1"
   1108  1.59  christos 	local failed=0
   1109  1.60  christos 	local manbase sec
   1110  1.37     lukem 	for manbase in /usr/share/man /usr/X11R6/man /usr/X11R7/man; do
   1111  1.37     lukem 		for sec in 1 2 3 4 5 6 7 8 9; do
   1112  1.37     lukem 			obsolete_catpages "$1" "${DEST_DIR}${manbase}" "${sec}"
   1113  1.37     lukem 			failed=$(( ${failed} + $? ))
   1114  1.59  christos 			if [ "${op}" = "fix" ]; then
   1115  1.37     lukem 				rmdir "${DEST_DIR}${manbase}/cat${sec}"/* \
   1116  1.37     lukem 					2>/dev/null
   1117  1.37     lukem 				rmdir "${DEST_DIR}${manbase}/cat${sec}" \
   1118  1.37     lukem 					2>/dev/null
   1119  1.37     lukem 			fi
   1120  1.37     lukem 		done
   1121  1.37     lukem 	done
   1122  1.37     lukem 	return $failed
   1123  1.37     lukem }
   1124  1.37     lukem 
   1125  1.37     lukem 
   1126   1.1  christos #
   1127   1.1  christos #	ddbonpanic
   1128   1.1  christos #
   1129  1.37     lukem 
   1130   1.1  christos additem ddbonpanic "verify ddb.onpanic is configured in sysctl.conf"
   1131   1.1  christos do_ddbonpanic()
   1132   1.1  christos {
   1133  1.36     lukem 	[ -n "$1" ] || err 3 "USAGE: do_ddbonpanic fix|check"
   1134   1.1  christos 
   1135   1.1  christos 	if ${GREP} -E '^#*[[:space:]]*ddb\.onpanic[[:space:]]*\??=[[:space:]]*[[:digit:]]+' \
   1136   1.1  christos 		"${DEST_DIR}/etc/sysctl.conf" >/dev/null 2>&1
   1137   1.1  christos 	then
   1138   1.1  christos 		result=0
   1139   1.1  christos 	else
   1140   1.1  christos 		if [ "$1" = check ]; then
   1141   1.1  christos 			msg \
   1142   1.1  christos     "The ddb.onpanic behaviour is not explicitly specified in /etc/sysctl.conf"
   1143   1.1  christos 			result=1
   1144   1.1  christos 		else
   1145   1.1  christos 			echo >> "${DEST_DIR}/etc/sysctl.conf"
   1146   1.1  christos 			${SED} < "${SRC_DIR}/etc/sysctl.conf" \
   1147   1.1  christos 			   -e '/^ddb\.onpanic/q' | \
   1148   1.1  christos 			       ${SED} -e '1,/^$/d' >> \
   1149   1.1  christos 			    "${DEST_DIR}/etc/sysctl.conf"
   1150   1.1  christos 			result=$?
   1151   1.1  christos 		fi
   1152   1.1  christos 	fi
   1153   1.1  christos 	return ${result}
   1154   1.1  christos }
   1155   1.1  christos 
   1156  1.37     lukem 
   1157   1.1  christos #
   1158   1.1  christos #	defaults
   1159   1.1  christos #
   1160  1.37     lukem 
   1161   1.1  christos additem defaults "/etc/defaults/ being up to date"
   1162   1.1  christos do_defaults()
   1163   1.1  christos {
   1164  1.36     lukem 	[ -n "$1" ] || err 3 "USAGE: do_defaults fix|check"
   1165   1.1  christos 	local op="$1"
   1166   1.1  christos 	local failed=0
   1167   1.1  christos 	local etcsets=$(getetcsets)
   1168   1.1  christos 
   1169   1.1  christos 	local rc_exclude_scripts=""
   1170   1.1  christos 	if $SOURCEMODE; then
   1171   1.1  christos 		# For most architectures rc.conf(5) should be the same as the
   1172   1.1  christos 		# one obtained from a source directory, except for the ones
   1173   1.1  christos 		# that have an append file for it.
   1174   1.1  christos 		local rc_conf_app="${SRC_DIR}/etc/etc.${MACHINE}/rc.conf.append"
   1175   1.1  christos 		if [ -f "${rc_conf_app}" ]; then
   1176   1.1  christos 			rc_exclude_scripts="rc.conf"
   1177   1.1  christos 
   1178   1.1  christos 			# Generate and compare the correct rc.conf(5) file
   1179   1.1  christos 			mkdir "${SCRATCHDIR}/defaults"
   1180   1.1  christos 
   1181   1.1  christos 			cat "${SRC_DIR}/etc/defaults/rc.conf" "${rc_conf_app}" \
   1182   1.1  christos 			    > "${SCRATCHDIR}/defaults/rc.conf"
   1183   1.1  christos 
   1184   1.1  christos 			compare_dir "${op}" "${SCRATCHDIR}/defaults" \
   1185   1.1  christos 			    "${DEST_DIR}/etc/defaults" \
   1186   1.1  christos 			    444 \
   1187   1.1  christos 			    "rc.conf"
   1188   1.1  christos 			failed=$(( ${failed} + $? ))
   1189   1.1  christos 		fi
   1190   1.1  christos 	fi
   1191   1.1  christos 
   1192   1.1  christos 	find_file_in_dirlist pf.boot.conf "pf.boot.conf" \
   1193   1.1  christos 	    "${SRC_DIR}/usr.sbin/pf/etc/defaults" "${SRC_DIR}/etc/defaults" \
   1194   1.1  christos 	    || return 1
   1195   1.1  christos 	# ${dir} is set by find_file_in_dirlist()
   1196   1.1  christos 	compare_dir "$op" "${dir}" "${DEST_DIR}/etc/defaults" 444 pf.boot.conf
   1197   1.1  christos 	failed=$(( ${failed} + $? ))
   1198   1.1  christos 
   1199   1.1  christos 	rc_exclude_scripts="${rc_exclude_scripts} pf.boot.conf"
   1200   1.1  christos 
   1201   1.1  christos 	local rc_default_conf_files="$(select_set_files /etc/defaults/ \
   1202   1.1  christos 	    "/etc/defaults/\([^[:space:]]*\.conf\)" ${etcsets} | \
   1203   1.1  christos 	    exclude ${rc_exclude_scripts})"
   1204   1.1  christos 	compare_dir "$op" "${SRC_DIR}/etc/defaults" "${DEST_DIR}/etc/defaults" \
   1205   1.1  christos 		444 \
   1206   1.1  christos 		${rc_default_conf_files}
   1207   1.1  christos 	failed=$(( ${failed} + $? ))
   1208   1.1  christos 
   1209   1.1  christos 
   1210   1.1  christos 	return ${failed}
   1211   1.1  christos }
   1212   1.1  christos 
   1213  1.37     lukem 
   1214   1.1  christos #
   1215   1.1  christos #	dhcpcd
   1216   1.1  christos #
   1217  1.37     lukem 
   1218   1.1  christos additem dhcpcd "dhcpcd configuration is up to date"
   1219   1.1  christos do_dhcpcd()
   1220   1.1  christos {
   1221   1.1  christos 	[ -n "$1" ] || err 3 "USAGE: do_dhcpcd fix|check"
   1222  1.59  christos 	local op="$1"
   1223  1.59  christos 	local failed=0
   1224   1.1  christos 
   1225   1.1  christos 	find_file_in_dirlist dhcpcd.conf "dhcpcd.conf" \
   1226   1.1  christos 	    "${SRC_DIR}/external/bsd/dhcpcd/dist/src" \
   1227   1.1  christos 	    "${SRC_DIR}/etc" || return 1
   1228   1.1  christos 			# ${dir} is set by find_file_in_dirlist()
   1229   1.1  christos 	populate_dir "$op" true "${dir}" "${DEST_DIR}/etc" 644 dhcpcd.conf
   1230   1.1  christos 	failed=$(( ${failed} + $? ))
   1231   1.1  christos 
   1232  1.22       roy 	check_dir "${op}" "${DEST_DIR}/var/db/dhcpcd" 755
   1233   1.1  christos 	failed=$(( ${failed} + $? ))
   1234   1.1  christos 
   1235   1.1  christos 	move_file "${op}" \
   1236   1.1  christos 		"${DEST_DIR}/etc/dhcpcd.duid" \
   1237  1.22       roy 		"${DEST_DIR}/var/db/dhcpcd/duid"
   1238   1.1  christos 	failed=$(( ${failed} + $? ))
   1239   1.1  christos 
   1240   1.1  christos 	move_file "${op}" \
   1241   1.1  christos 		"${DEST_DIR}/etc/dhcpcd.secret" \
   1242  1.22       roy 		"${DEST_DIR}/var/db/dhcpcd/secret"
   1243   1.1  christos 	failed=$(( ${failed} + $? ))
   1244   1.1  christos 
   1245   1.1  christos 	move_file "${op}" \
   1246   1.1  christos 		"${DEST_DIR}/var/db/dhcpcd-rdm.monotonic" \
   1247  1.22       roy 		"${DEST_DIR}/var/db/dhcpcd/rdm_monotonic"
   1248   1.1  christos 	failed=$(( ${failed} + $? ))
   1249   1.1  christos 
   1250   1.1  christos 	for lease in "${DEST_DIR}/var/db/dhcpcd-"*.lease*; do
   1251   1.1  christos 		[ -f "${lease}" ] || continue
   1252   1.1  christos 		new_lease=$(basename "${lease}" | ${SED} -e 's/dhcpcd-//')
   1253  1.22       roy 		new_lease="${DEST_DIR}/var/db/dhcpcd/${new_lease}"
   1254   1.1  christos 		move_file "${op}" "${lease}" "${new_lease}"
   1255   1.1  christos 		failed=$(( ${failed} + $? ))
   1256   1.1  christos 	done
   1257   1.1  christos 
   1258  1.22       roy 	chroot_dir="${DEST_DIR}/var/chroot/dhcpcd"
   1259  1.16       roy 	move_file "${op}" \
   1260  1.22       roy 		"${chroot_dir}/var/db/dhcpcd/duid" \
   1261  1.22       roy 		"${DEST_DIR}/var/db/dhcpcd/duid"
   1262  1.16       roy 	failed=$(( ${failed} + $? ))
   1263  1.16       roy 
   1264  1.16       roy 	move_file "${op}" \
   1265  1.22       roy 		"${chroot_dir}/var/db/dhcpcd/secret" \
   1266  1.22       roy 		"${DEST_DIR}/var/db/dhcpcd/secret"
   1267  1.16       roy 	failed=$(( ${failed} + $? ))
   1268  1.16       roy 
   1269  1.16       roy 	move_file "${op}" \
   1270  1.22       roy 		"${chroot_dir}/var/db/dhcpcd/rdm_monotonic" \
   1271  1.22       roy 		"${DEST_DIR}/var/db/dhcpcd/rdm_monotonic"
   1272  1.16       roy 	failed=$(( ${failed} + $? ))
   1273  1.16       roy 
   1274  1.22       roy 	for lease in "${chroot_dir}/var/db/dhcpcd/"*.lease*; do
   1275  1.16       roy 		[ -f "${lease}" ] || continue
   1276  1.22       roy 		new_lease="${DEST_DIR}/var/db/dhcpcd/$(basename ${lease})"
   1277  1.16       roy 		move_file "${op}" "${lease}" "${new_lease}"
   1278  1.16       roy 		failed=$(( ${failed} + $? ))
   1279  1.16       roy 	done
   1280  1.16       roy 
   1281  1.22       roy 	# Ensure chroot is now empty
   1282  1.22       roy 	for dir in \
   1283  1.23       roy 		$(find ${chroot_dir} ! -type d) \
   1284  1.22       roy 		$(find ${chroot_dir} -type d -mindepth 1 | sort -r)
   1285  1.22       roy 	do
   1286  1.22       roy 		echo "/var/chroot/dhcpcd${dir##${chroot_dir}}"
   1287  1.22       roy 	done | obsolete_paths "${op}"
   1288  1.22       roy 	failed=$(( ${failed} + $? ))
   1289  1.22       roy 
   1290  1.22       roy 	contents_owner "${op}" "${DEST_DIR}/var/db/dhcpcd" root wheel
   1291  1.16       roy 	failed=$(( ${failed} + $? ))
   1292  1.16       roy 
   1293   1.1  christos 	return ${failed}
   1294   1.1  christos }
   1295   1.1  christos 
   1296  1.37     lukem 
   1297   1.1  christos #
   1298   1.1  christos #	dhcpcdrundir
   1299   1.1  christos #
   1300  1.37     lukem 
   1301  1.41    andvar additem dhcpcdrundir "accidentally created /@RUNDIR@ does not exist"
   1302   1.1  christos do_dhcpcdrundir()
   1303   1.1  christos {
   1304   1.1  christos 	[ -n "$1" ] || err 3 "USAGE: do_dhcpcdrundir fix|check"
   1305  1.59  christos 	local op="$1"
   1306  1.59  christos 	local failed=0
   1307   1.1  christos 
   1308   1.1  christos 	if [ -d "${DEST_DIR}/@RUNDIR@" ]; then
   1309   1.1  christos 		if [ "${op}" = "check" ]; then
   1310  1.40    andvar 			msg "Remove erroneously created /@RUNDIR@"
   1311   1.1  christos 			failed=1
   1312  1.59  christos 		elif ! ${RM} -r "${DEST_DIR}/@RUNDIR@"; then
   1313   1.1  christos 			msg "Failed to remove ${DEST_DIR}/@RUNDIR@"
   1314   1.1  christos 			failed=1
   1315   1.1  christos 		else
   1316  1.40    andvar 			msg "Removed erroneously created ${DEST_DIR}/@RUNDIR@"
   1317   1.1  christos 		fi
   1318   1.1  christos 	fi
   1319   1.1  christos 	return ${failed}
   1320   1.1  christos }
   1321   1.1  christos 
   1322  1.37     lukem 
   1323   1.1  christos #
   1324   1.1  christos #	envsys
   1325   1.1  christos #
   1326  1.37     lukem 
   1327   1.1  christos additem envsys "envsys configuration is up to date"
   1328   1.1  christos do_envsys()
   1329   1.1  christos {
   1330   1.1  christos 	[ -n "$1" ] || err 3 "USAGE: do_envsys fix|check"
   1331   1.3  christos 	local op="$1"
   1332   1.3  christos 	local failed=0
   1333   1.3  christos 	local etcsets=$(getetcsets)
   1334   1.1  christos 
   1335   1.1  christos 	populate_dir "$op" true "${SRC_DIR}/etc" "${DEST_DIR}/etc" 644 \
   1336   1.1  christos 		envsys.conf
   1337   1.1  christos 	failed=$(( ${failed} + $? ))
   1338   1.1  christos 
   1339   1.3  christos 	local powerd_scripts="$(select_set_files /etc/powerd/scripts/ \
   1340   1.3  christos 	    "/etc/powerd/scripts/\([^[:space:]/]*\)" ${etcsets})"
   1341   1.3  christos 
   1342   1.1  christos 	populate_dir "$op" true "${SRC_DIR}/etc/powerd/scripts" \
   1343   1.3  christos 		"${DEST_DIR}/etc/powerd/scripts" \
   1344   1.3  christos 		555 \
   1345   1.3  christos 		${powerd_scripts}
   1346   1.1  christos 	failed=$(( ${failed} + $? ))
   1347   1.1  christos 
   1348   1.1  christos 	return ${failed}
   1349   1.1  christos }
   1350   1.1  christos 
   1351  1.37     lukem 
   1352   1.1  christos #
   1353  1.37     lukem #	fontconfig
   1354  1.13  christos #
   1355  1.37     lukem 
   1356  1.37     lukem additem fontconfig "X11 font configuration is up to date"
   1357  1.37     lukem do_fontconfig()
   1358  1.13  christos {
   1359  1.37     lukem 	[ -n "$1" ] || err 3 "USAGE: do_fontconfig fix|check"
   1360  1.59  christos 	local op="$1"
   1361  1.59  christos 	local failed=0
   1362  1.37     lukem 
   1363  1.37     lukem 	# First, check for updates we can handle.
   1364  1.37     lukem 	if ! $SOURCEMODE; then
   1365  1.37     lukem 		FONTCONFIG_DIR="${SRC_DIR}/etc/fonts/conf.avail"
   1366  1.37     lukem 	else
   1367  1.37     lukem 		FONTCONFIG_DIR="${XSRC_DIR}/external/mit/fontconfig/dist/conf.d"
   1368  1.37     lukem 	fi
   1369  1.37     lukem 
   1370  1.37     lukem 	if [ ! -d "${FONTCONFIG_DIR}" ]; then
   1371  1.37     lukem 		msg "${FONTCONFIG_DIR} is not a directory; skipping check"
   1372  1.37     lukem 		return 0
   1373  1.13  christos 	fi
   1374  1.37     lukem 	local regular_fonts="
   1375  1.37     lukem 10-autohint.conf
   1376   1.4  christos 10-scale-bitmap-fonts.conf
   1377   1.4  christos 10-sub-pixel-bgr.conf
   1378  1.52       mrg 10-sub-pixel-none.conf
   1379   1.4  christos 10-sub-pixel-rgb.conf
   1380   1.4  christos 10-sub-pixel-vbgr.conf
   1381   1.4  christos 10-sub-pixel-vrgb.conf
   1382   1.4  christos 10-unhinted.conf
   1383   1.4  christos 11-lcdfilter-default.conf
   1384   1.4  christos 11-lcdfilter-legacy.conf
   1385   1.4  christos 11-lcdfilter-light.conf
   1386   1.4  christos 20-unhint-small-vera.conf
   1387   1.4  christos 25-unhint-nonlatin.conf
   1388   1.4  christos 30-metric-aliases.conf
   1389   1.4  christos 40-nonlatin.conf
   1390   1.4  christos 45-generic.conf
   1391   1.4  christos 45-latin.conf
   1392   1.4  christos 49-sansserif.conf
   1393   1.4  christos 50-user.conf
   1394   1.4  christos 51-local.conf
   1395   1.4  christos 60-generic.conf
   1396   1.4  christos 60-latin.conf
   1397   1.4  christos 65-fonts-persian.conf
   1398   1.4  christos 65-khmer.conf
   1399   1.4  christos 65-nonlatin.conf
   1400   1.4  christos 69-unifont.conf
   1401   1.4  christos 70-no-bitmaps.conf
   1402   1.4  christos 70-yes-bitmaps.conf
   1403   1.4  christos 80-delicious.conf
   1404   1.4  christos 90-synthetic.conf
   1405   1.4  christos "
   1406   1.4  christos 	populate_dir "$op" false "${FONTCONFIG_DIR}" \
   1407   1.4  christos 	    "${DEST_DIR}/etc/fonts/conf.avail" \
   1408   1.4  christos 	    444 \
   1409   1.4  christos 	    ${regular_fonts}
   1410   1.1  christos 	failed=$(( ${failed} + $? ))
   1411   1.1  christos 
   1412   1.1  christos 	if ! $SOURCEMODE; then
   1413   1.1  christos 		FONTS_DIR="${SRC_DIR}/etc/fonts"
   1414   1.1  christos 	else
   1415   1.1  christos 		FONTS_DIR="${SRC_DIR}/external/mit/xorg/lib/fontconfig/etc"
   1416   1.1  christos 	fi
   1417   1.1  christos 
   1418   1.1  christos 	populate_dir "$op" false "${FONTS_DIR}" "${DEST_DIR}/etc/fonts" 444 \
   1419   1.1  christos 		fonts.conf
   1420   1.1  christos 	failed=$(( ${failed} + $? ))
   1421   1.1  christos 
   1422   1.1  christos 	# We can't modify conf.d easily; someone might have removed a file.
   1423   1.1  christos 
   1424   1.1  christos 	# Look for old files that need to be deleted.
   1425  1.59  christos 	local obsolete_fonts="
   1426   1.4  christos 10-autohint.conf
   1427   1.4  christos 10-no-sub-pixel.conf
   1428   1.4  christos 10-sub-pixel-bgr.conf
   1429   1.4  christos 10-sub-pixel-rgb.conf
   1430   1.4  christos 10-sub-pixel-vbgr.conf
   1431   1.4  christos 10-sub-pixel-vrgb.conf
   1432   1.4  christos 10-unhinted.conf
   1433   1.4  christos 25-unhint-nonlatin.conf
   1434   1.4  christos 65-khmer.conf
   1435   1.4  christos 70-no-bitmaps.conf
   1436   1.4  christos 70-yes-bitmaps.conf
   1437   1.4  christos "
   1438  1.59  christos 	local failed_fonts=""
   1439   1.4  christos 	for i in ${obsolete_fonts}; do
   1440   1.4  christos 	    if [ -f "${DEST_DIR}/etc/fonts/conf.d/$i" ]; then
   1441   1.4  christos 		    conf_d_failed=1
   1442   1.4  christos 		    failed_fonts="$failed_fonts $i"
   1443   1.4  christos 	    fi
   1444   1.4  christos 	done
   1445   1.1  christos 
   1446   1.4  christos 	if [ -n "$failed_fonts" ]; then
   1447   1.1  christos 		msg \
   1448   1.4  christos     "Broken fontconfig configuration found; please delete these files:"
   1449   1.4  christos 		msg "[$failed_fonts]"
   1450   1.4  christos 		failed=$(( ${failed} + 1 ))
   1451   1.1  christos 	fi
   1452   1.1  christos 
   1453   1.1  christos 	return ${failed}
   1454   1.1  christos }
   1455   1.1  christos 
   1456  1.37     lukem 
   1457   1.1  christos #
   1458   1.1  christos #	gid
   1459   1.1  christos #
   1460  1.37     lukem 
   1461   1.1  christos additem gid "required groups in /etc/group"
   1462   1.1  christos do_gid()
   1463   1.1  christos {
   1464  1.36     lukem 	[ -n "$1" ] || err 3 "USAGE: do_gid fix|check"
   1465   1.1  christos 
   1466   1.1  christos 	check_ids "$1" groups "${DEST_DIR}/etc/group" \
   1467   1.1  christos 	    "${SRC_DIR}/etc/group" 14 \
   1468   1.1  christos 	    named ntpd sshd SKIP _pflogd _rwhod staff _proxy _timedc \
   1469   1.1  christos 	    _sdpd _httpd _mdnsd _tests _tcpdump _tss _gpio _rtadvd SKIP \
   1470  1.17       roy 	    _unbound _nsd nvmm _dhcpcd
   1471   1.1  christos }
   1472   1.1  christos 
   1473  1.37     lukem 
   1474   1.1  christos #
   1475   1.1  christos #	gpio
   1476   1.1  christos #
   1477  1.37     lukem 
   1478   1.1  christos additem gpio "gpio configuration is up to date"
   1479   1.1  christos do_gpio()
   1480   1.1  christos {
   1481   1.1  christos 	[ -n "$1" ] || err 3 "USAGE: do_gpio fix|check"
   1482  1.59  christos 	local op="$1"
   1483  1.59  christos 	local failed=0
   1484   1.1  christos 
   1485   1.1  christos 	populate_dir "$op" true "${SRC_DIR}/etc" "${DEST_DIR}/etc" 644 \
   1486   1.1  christos 		gpio.conf
   1487   1.1  christos 	failed=$(( ${failed} + $? ))
   1488   1.1  christos 
   1489   1.1  christos 	return ${failed}
   1490   1.1  christos }
   1491   1.1  christos 
   1492  1.37     lukem 
   1493   1.1  christos #
   1494   1.1  christos #	hosts
   1495   1.1  christos #
   1496  1.37     lukem 
   1497   1.1  christos additem hosts "/etc/hosts being up to date"
   1498   1.1  christos do_hosts()
   1499   1.1  christos {
   1500  1.36     lukem 	[ -n "$1" ] || err 3 "USAGE: do_hosts fix|check"
   1501   1.1  christos 
   1502   1.1  christos 	modify_file "$1" "${DEST_DIR}/etc/hosts" "${SCRATCHDIR}/hosts" '
   1503   1.1  christos 		/^(127\.0\.0\.1|::1)[ 	]+[^\.]*$/ {
   1504   1.1  christos 			print $0, "localhost."
   1505   1.1  christos 			next
   1506   1.1  christos 		}
   1507   1.1  christos 		{ print }
   1508   1.1  christos 	'
   1509   1.1  christos 	return $?
   1510   1.1  christos }
   1511   1.1  christos 
   1512  1.37     lukem 
   1513   1.1  christos #
   1514   1.1  christos #	iscsi
   1515   1.1  christos #
   1516  1.37     lukem 
   1517   1.1  christos additem iscsi "/etc/iscsi is populated"
   1518   1.1  christos do_iscsi()
   1519   1.1  christos {
   1520  1.36     lukem 	[ -n "$1" ] || err 3 "USAGE: do_iscsi fix|check"
   1521   1.1  christos 
   1522   1.1  christos 	populate_dir "${op}" true \
   1523   1.1  christos 	    "${SRC_DIR}/etc/iscsi" "${DEST_DIR}/etc/iscsi" 600 auths
   1524   1.1  christos 	populate_dir "${op}" true \
   1525   1.1  christos 	    "${SRC_DIR}/etc/iscsi" "${DEST_DIR}/etc/iscsi" 644 targets
   1526   1.1  christos 	return $?
   1527   1.1  christos }
   1528   1.1  christos 
   1529  1.37     lukem 
   1530  1.37     lukem #
   1531  1.37     lukem #	mailerconf
   1532  1.37     lukem #
   1533  1.37     lukem 
   1534  1.37     lukem adddisableditem mailerconf "update /etc/mailer.conf after sendmail removal"
   1535  1.37     lukem do_mailerconf()
   1536  1.37     lukem {
   1537  1.37     lukem 	[ -n "$1" ] || err 3 "USAGE: do_mailterconf fix|check"
   1538  1.59  christos 	local op="$1"
   1539  1.37     lukem 
   1540  1.59  christos 	local failed=0
   1541  1.37     lukem 	mta_path="$(${AWK} '/^sendmail[ \t]/{print$2}' \
   1542  1.37     lukem 		"${DEST_DIR}/etc/mailer.conf")"
   1543  1.37     lukem 	old_sendmail_path="/usr/libexec/sendmail/sendmail"
   1544  1.37     lukem 	if [ "${mta_path}" = "${old_sendmail_path}" ]; then
   1545  1.37     lukem 	    if [ "$op" = check ]; then
   1546  1.37     lukem 		msg "mailer.conf points to obsolete ${old_sendmail_path}"
   1547  1.37     lukem 		failed=1;
   1548  1.37     lukem 	    else
   1549  1.37     lukem 		populate_dir "${op}" false \
   1550  1.37     lukem 		"${SRC_DIR}/etc" "${DEST_DIR}/etc" 644 mailer.conf
   1551  1.37     lukem 		failed=$?
   1552  1.37     lukem 	    fi
   1553  1.37     lukem 	fi
   1554  1.37     lukem 
   1555  1.37     lukem 	return ${failed}
   1556  1.37     lukem }
   1557  1.37     lukem 
   1558  1.37     lukem 
   1559   1.1  christos #
   1560   1.1  christos #	makedev
   1561   1.1  christos #
   1562  1.37     lukem 
   1563   1.1  christos additem makedev "/dev/MAKEDEV being up to date"
   1564   1.1  christos do_makedev()
   1565   1.1  christos {
   1566  1.36     lukem 	[ -n "$1" ] || err 3 "USAGE: do_makedev fix|check"
   1567  1.59  christos 	local failed=0
   1568   1.1  christos 
   1569   1.1  christos 	if [ -f "${SRC_DIR}/etc/MAKEDEV.tmpl" ]; then
   1570   1.1  christos 			# generate MAKEDEV from source if source is available
   1571   1.1  christos 		env MACHINE="${MACHINE}" \
   1572   1.1  christos 		    MACHINE_ARCH="${MACHINE_ARCH}" \
   1573   1.1  christos 		    NETBSDSRCDIR="${SRC_DIR}" \
   1574   1.1  christos 		    ${AWK} -f "${SRC_DIR}/etc/MAKEDEV.awk" \
   1575   1.1  christos 		    "${SRC_DIR}/etc/MAKEDEV.tmpl" > "${SCRATCHDIR}/MAKEDEV"
   1576   1.1  christos 	fi
   1577   1.1  christos 
   1578   1.1  christos 	find_file_in_dirlist MAKEDEV "MAKEDEV" \
   1579   1.1  christos 	    "${SCRATCHDIR}" "${SRC_DIR}/dev" \
   1580   1.1  christos 	    || return 1
   1581   1.1  christos 			# ${dir} is set by find_file_in_dirlist()
   1582   1.1  christos 	find_makedev
   1583   1.1  christos 	compare_dir "$1" "${dir}" "${MAKEDEV_DIR}" 555 MAKEDEV
   1584   1.1  christos 	failed=$(( ${failed} + $? ))
   1585   1.1  christos 
   1586   1.1  christos 	find_file_in_dirlist MAKEDEV.local "MAKEDEV.local" \
   1587   1.1  christos 	    "${SRC_DIR}/etc" "${SRC_DIR}/dev" \
   1588   1.1  christos 	    || return 1
   1589   1.1  christos 			# ${dir} is set by find_file_in_dirlist()
   1590   1.1  christos 	compare_dir "$1" "${dir}" "${DEST_DIR}/dev" 555 MAKEDEV.local
   1591   1.1  christos 	failed=$(( ${failed} + $? ))
   1592   1.1  christos 
   1593   1.1  christos 	return ${failed}
   1594   1.1  christos }
   1595   1.1  christos 
   1596  1.37     lukem 
   1597  1.37     lukem #
   1598  1.37     lukem #	man.conf
   1599  1.37     lukem #
   1600  1.37     lukem 
   1601  1.37     lukem additem manconf "check for a mandoc usage in /etc/man.conf"
   1602  1.37     lukem do_manconf()
   1603  1.37     lukem {
   1604  1.37     lukem 	[ -n "$1" ] || err 3 "USAGE: do_manconf fix|check"
   1605  1.59  christos 	local op="$1"
   1606  1.59  christos 	local failed=0
   1607  1.37     lukem 
   1608  1.37     lukem 	[ -f "${DEST_DIR}/etc/man.conf" ] || return 0
   1609  1.37     lukem 	if ${GREP} -w "mandoc" "${DEST_DIR}/etc/man.conf" >/dev/null 2>&1;
   1610  1.37     lukem 	then
   1611  1.37     lukem 		failed=0;
   1612  1.37     lukem 	else
   1613  1.37     lukem 		failed=1
   1614  1.37     lukem 		notfixed=""
   1615  1.37     lukem 		if [ "${op}" = "fix" ]; then
   1616  1.37     lukem 			notfixed="${NOT_FIXED}"
   1617  1.37     lukem 		fi
   1618  1.37     lukem 		msg "The file /etc/man.conf has not been adapted to mandoc usage; you"
   1619  1.37     lukem 		msg "probably want to copy a new version over. ${notfixed}"
   1620  1.37     lukem 	fi
   1621  1.37     lukem 
   1622  1.37     lukem 	return ${failed}
   1623  1.37     lukem }
   1624  1.37     lukem 
   1625  1.37     lukem 
   1626   1.1  christos #
   1627   1.1  christos #	motd
   1628   1.1  christos #
   1629  1.37     lukem 
   1630   1.1  christos additem motd "contents of motd"
   1631   1.1  christos do_motd()
   1632   1.1  christos {
   1633  1.36     lukem 	[ -n "$1" ] || err 3 "USAGE: do_motd fix|check"
   1634   1.1  christos 
   1635   1.1  christos 	if ${GREP} -i 'http://www.NetBSD.org/Misc/send-pr.html' \
   1636   1.1  christos 		"${DEST_DIR}/etc/motd" >/dev/null 2>&1 \
   1637  1.15  nakayama 	    || ${GREP} -i 'https*://www.NetBSD.org/support/send-pr.html' \
   1638   1.1  christos 		"${DEST_DIR}/etc/motd" >/dev/null 2>&1
   1639   1.1  christos 	then
   1640   1.1  christos 		tmp1="$(mktemp /tmp/postinstall.motd.XXXXXXXX)"
   1641   1.1  christos 		tmp2="$(mktemp /tmp/postinstall.motd.XXXXXXXX)"
   1642   1.1  christos 		${SED} '1,2d' <"${SRC_DIR}/etc/motd" >"${tmp1}"
   1643   1.1  christos 		${SED} '1,2d' <"${DEST_DIR}/etc/motd" >"${tmp2}"
   1644   1.1  christos 
   1645   1.1  christos 		if [ "$1" = check ]; then
   1646   1.1  christos 			cmp -s "${tmp1}" "${tmp2}"
   1647   1.1  christos 			result=$?
   1648   1.1  christos 			if [ "${result}" -ne 0 ]; then
   1649   1.1  christos 				msg \
   1650   1.1  christos     "Bug reporting messages do not seem to match the installed release"
   1651   1.1  christos 			fi
   1652   1.1  christos 		else
   1653   1.1  christos 			head -n 2 "${DEST_DIR}/etc/motd" >"${tmp1}"
   1654   1.1  christos 			${SED} '1,2d' <"${SRC_DIR}/etc/motd" >>"${tmp1}"
   1655   1.1  christos 			cp "${tmp1}" "${DEST_DIR}/etc/motd"
   1656   1.1  christos 			result=0
   1657   1.1  christos 		fi
   1658   1.1  christos 
   1659  1.59  christos 		${RM} -f "${tmp1}" "${tmp2}"
   1660   1.1  christos 	else
   1661   1.1  christos 		result=0
   1662   1.1  christos 	fi
   1663   1.1  christos 
   1664   1.1  christos 	return ${result}
   1665   1.1  christos }
   1666   1.1  christos 
   1667  1.37     lukem 
   1668   1.1  christos #
   1669   1.1  christos #	mtree
   1670   1.1  christos #
   1671  1.37     lukem 
   1672   1.1  christos additem mtree "/etc/mtree/ being up to date"
   1673   1.1  christos do_mtree()
   1674   1.1  christos {
   1675  1.36     lukem 	[ -n "$1" ] || err 3 "USAGE: do_mtree fix|check"
   1676  1.59  christos 	local failed=0
   1677   1.1  christos 
   1678   1.1  christos 	compare_dir "$1" "${SRC_DIR}/etc/mtree" "${DEST_DIR}/etc/mtree" 444 special
   1679   1.1  christos 	failed=$(( ${failed} + $? ))
   1680   1.1  christos 
   1681   1.1  christos 	if ! $SOURCEMODE; then
   1682   1.1  christos 		MTREE_DIR="${SRC_DIR}/etc/mtree"
   1683   1.1  christos 	else
   1684  1.59  christos 		${RM} -rf "${SCRATCHDIR}/obj"
   1685   1.1  christos 		mkdir "${SCRATCHDIR}/obj"
   1686   1.1  christos 		${MAKE} -s -C "${SRC_DIR}/etc/mtree" TOOL_AWK="${AWK}" \
   1687   1.1  christos 		    MAKEOBJDIR="${SCRATCHDIR}/obj" emit_dist_file > \
   1688   1.1  christos 		    "${SCRATCHDIR}/NetBSD.dist"
   1689   1.1  christos 		MTREE_DIR="${SCRATCHDIR}"
   1690  1.59  christos 		${RM} -rf "${SCRATCHDIR}/obj"
   1691   1.1  christos 	fi
   1692   1.1  christos 	compare_dir "$1" "${MTREE_DIR}" "${DEST_DIR}/etc/mtree" 444 NetBSD.dist
   1693   1.1  christos 	failed=$(( ${failed} + $? ))
   1694   1.1  christos 
   1695   1.1  christos 	return ${failed}
   1696   1.1  christos }
   1697   1.1  christos 
   1698  1.37     lukem 
   1699   1.1  christos #
   1700   1.1  christos #	named
   1701   1.1  christos #
   1702  1.59  christos handle_named_conf()
   1703  1.59  christos {
   1704  1.59  christos 	local op="$1"
   1705  1.59  christos 	local option="dnssec-enable"
   1706  1.59  christos 	local failed=0
   1707  1.59  christos 	local conf
   1708  1.59  christos 
   1709  1.59  christos 	shift
   1710  1.59  christos 
   1711  1.59  christos 	for conf; do
   1712  1.59  christos 		local c=$(readlink -f "${conf}")
   1713  1.59  christos 		if ! ${GREP} -qs "${option}" "${c}"
   1714  1.59  christos 		then
   1715  1.59  christos 			continue
   1716  1.59  christos 		fi
   1717  1.59  christos 
   1718  1.59  christos 		if [ "${op}" = "fix" ]; then
   1719  1.59  christos 			${SED} -e "/${option}/d" "${c}" > "${c}.new"
   1720  1.59  christos 			failed=$(( ${failed} + $? ))
   1721  1.59  christos 			mv "${c}.new" "${c}"
   1722  1.59  christos 			failed=$(( ${failed} + $? ))
   1723  1.59  christos 			msg "Removed obsolete '${option}' in ${c}"
   1724  1.59  christos 		else
   1725  1.59  christos 			msg "'${option}' option in ${c} should be removed"
   1726  1.59  christos 			failed=$(( ${failed} + 1 ))
   1727  1.59  christos 		fi
   1728  1.59  christos 	done
   1729  1.59  christos 
   1730  1.59  christos 	return ${failed}
   1731  1.59  christos }
   1732  1.37     lukem 
   1733   1.1  christos additem named "named configuration update"
   1734   1.1  christos do_named()
   1735   1.1  christos {
   1736  1.59  christos 	local oldconf="${DEST_DIR}/etc/namedb/named.conf"
   1737  1.59  christos 	local conf="${DEST_DIR}/etc/named.conf"
   1738  1.36     lukem 	[ -n "$1" ] || err 3 "USAGE: do_named fix|check"
   1739  1.59  christos 	local op="$1"
   1740   1.1  christos 
   1741  1.59  christos 	move_file "${op}" "${oldconf}" "${conf}"
   1742  1.59  christos 	handle_named_conf "${op}" "${oldconf}" "${conf}"
   1743   1.1  christos 
   1744   1.1  christos 	compare_dir "${op}" "${SRC_DIR}/etc/namedb" "${DEST_DIR}/etc/namedb" \
   1745   1.1  christos 		644 \
   1746   1.1  christos 		root.cache
   1747  1.63  christos 
   1748  1.63  christos 	local od="${DEST_DIR}/usr/libexec/named"
   1749  1.63  christos 	if [ -d "$od" ]; then
   1750  1.63  christos 		rm -fr "$od"
   1751  1.63  christos 		msg "Removed obsolete '${od}'"
   1752  1.63  christos 	fi
   1753   1.1  christos }
   1754   1.1  christos 
   1755  1.37     lukem 
   1756   1.1  christos #
   1757  1.55  riastrad #	opensslcertsconf
   1758  1.53  riastrad #
   1759  1.53  riastrad 
   1760  1.55  riastrad additem opensslcertsconf "ensure TLS trust anchor configuration exists"
   1761  1.55  riastrad do_opensslcertsconf()
   1762  1.53  riastrad {
   1763  1.56  riastrad 	local certsdir certsconf defaultconf manualmsg
   1764  1.55  riastrad 
   1765  1.55  riastrad 	[ -n "$1" ] || err 3 "USAGE: do_opensslcertsconf fix|check"
   1766  1.55  riastrad 
   1767  1.55  riastrad 	certsdir="${DEST_DIR}/etc/openssl/certs"
   1768  1.55  riastrad 	certsconf="${DEST_DIR}/etc/openssl/certs.conf"
   1769  1.55  riastrad 	defaultconf="${DEST_DIR}/usr/share/examples/certctl/certs.conf"
   1770  1.53  riastrad 
   1771  1.53  riastrad 	case $1 in
   1772  1.55  riastrad 	check)	if [ ! -r "$certsconf" ]; then
   1773  1.55  riastrad 			msg "/etc/openssl/certs.conf missing; see certctl(8)"
   1774  1.55  riastrad 			return 1
   1775  1.55  riastrad 		fi
   1776  1.55  riastrad 		;;
   1777  1.55  riastrad 	fix)	# If /etc/openssl/certs.conf is already there, nothing
   1778  1.55  riastrad 		# to do.
   1779  1.55  riastrad 		if [ -r "$certsconf" ]; then
   1780  1.55  riastrad 			return 0
   1781  1.55  riastrad 		fi
   1782  1.55  riastrad 
   1783  1.55  riastrad 		# If /etc/openssl/certs is a symlink, or exists but is
   1784  1.55  riastrad 		# not a directory, or is a directory but is nonempty,
   1785  1.55  riastrad 		# then either it's managed by someone else or something
   1786  1.55  riastrad 		# fishy is afoot.  So set it manual in that case.
   1787  1.55  riastrad 		# Otherwise, install the default config file.
   1788  1.55  riastrad 		if [ -h "$certsdir" ] ||
   1789  1.55  riastrad 		    [ -e "$certsdir" -a ! -d "$certsdir" ] ||
   1790  1.55  riastrad 		    ([ -d "$certsdir" ] &&
   1791  1.55  riastrad 			find -f "$certsdir" -- \
   1792  1.55  riastrad 			    -maxdepth 0 -type d -empty -exit 1)
   1793  1.55  riastrad 		then
   1794  1.55  riastrad 			msg "/etc/openssl/certs appears manually configured"
   1795  1.56  riastrad 			manualmsg="[existing /etc/openssl/certs configuration"
   1796  1.56  riastrad 			manualmsg="$manualmsg detected by postinstall(8)]"
   1797  1.56  riastrad                         # Change the commented-out `#manual' line to
   1798  1.56  riastrad                         # uncommented `manual', or print an error
   1799  1.56  riastrad                         # message if there is no `#manual' line and put
   1800  1.56  riastrad                         # `manual' at the end.
   1801  1.56  riastrad                         awk -v defaultconf="$defaultconf" \
   1802  1.56  riastrad 			    -v manualmsg="$manualmsg" '
   1803  1.56  riastrad 				BEGIN {
   1804  1.56  riastrad 					manual = 0
   1805  1.56  riastrad 				}
   1806  1.56  riastrad 				/^#manual/ && !manual {
   1807  1.56  riastrad 					manual = 1
   1808  1.56  riastrad 					sub(/^#/, "")
   1809  1.56  riastrad 					print
   1810  1.56  riastrad 					print "#", manualmsg
   1811  1.56  riastrad 					next
   1812  1.56  riastrad 				}
   1813  1.56  riastrad 				{
   1814  1.56  riastrad 					print
   1815  1.56  riastrad 				}
   1816  1.56  riastrad 				END {
   1817  1.56  riastrad 					if (!manual) {
   1818  1.56  riastrad 						printf "warning: %s %s?\n", \
   1819  1.56  riastrad 						    "corrupt", defaultconf \
   1820  1.56  riastrad 						    >"/dev/stderr"
   1821  1.56  riastrad 						print "manual"
   1822  1.56  riastrad 						print "#", manualmsg
   1823  1.56  riastrad 					}
   1824  1.56  riastrad 				}
   1825  1.56  riastrad 			' <$defaultconf >${certsconf}.tmp
   1826  1.55  riastrad 		else
   1827  1.55  riastrad 			msg "installing default /etc/openssl/certs.conf"
   1828  1.56  riastrad 			cat <$defaultconf >${certsconf}.tmp
   1829  1.55  riastrad 		fi && mv -f -- "${certsconf}.tmp" "$certsconf"
   1830  1.55  riastrad 		;;
   1831  1.55  riastrad 	*)	err 3 "USAGE: do_opensslcerts fix|check"
   1832  1.55  riastrad 		;;
   1833  1.55  riastrad 	esac
   1834  1.55  riastrad }
   1835  1.55  riastrad 
   1836  1.55  riastrad 
   1837  1.55  riastrad #
   1838  1.55  riastrad #	opensslcertsrehash
   1839  1.55  riastrad #
   1840  1.55  riastrad 
   1841  1.55  riastrad additem opensslcertsrehash "make /etc/openssl/certs cache of TLS trust anchors"
   1842  1.55  riastrad do_opensslcertsrehash()
   1843  1.55  riastrad {
   1844  1.55  riastrad 	local mtreekeys scratchdir
   1845  1.55  riastrad 
   1846  1.55  riastrad 	[ -n "$1" ] || err 3 "USAGE: do_opensslcertsrehash fix|check"
   1847  1.55  riastrad 
   1848  1.55  riastrad 	if [ ! -r "${DEST_DIR}/etc/openssl/certs.conf" ]; then
   1849  1.55  riastrad 		msg "/etc/openssl/certs.conf missing; see certctl(8)"
   1850  1.55  riastrad 		return 1
   1851  1.55  riastrad 	fi
   1852  1.55  riastrad 
   1853  1.55  riastrad 	case $1 in
   1854  1.55  riastrad 	check)	# Create a scratch rehash for comparison.
   1855  1.55  riastrad 		mtreekeys="type,link"
   1856  1.55  riastrad 		scratchdir="${SCRATCHDIR}/opensslcerts"
   1857  1.57  riastrad 		/usr/sbin/certctl -c "$scratchdir" rehash || return $?
   1858  1.55  riastrad 
   1859  1.55  riastrad 		# This will create ${scratchdir}/.certctl unless the
   1860  1.55  riastrad 		# configuration is manual.  If the configuration is
   1861  1.55  riastrad 		# manual, stop here; nothing to do.  certctl(8) will
   1862  1.55  riastrad 		# have already printed a message about that.
   1863  1.55  riastrad 		#
   1864  1.55  riastrad 		# XXX Grody to rely on the internal structure used by
   1865  1.55  riastrad 		# certctl(8), but less bad than having two versions of
   1866  1.55  riastrad 		# the config parsing logic.
   1867  1.55  riastrad 		if [ ! -f "${scratchdir}/.certctl" ]; then
   1868  1.55  riastrad 			return 0
   1869  1.55  riastrad 		fi
   1870  1.55  riastrad 
   1871  1.55  riastrad 		# Do a dry run of rehashing into the real
   1872  1.55  riastrad 		# /etc/openssl/certs.  This curious extra step ensures
   1873  1.55  riastrad 		# that we report a failure if /etc/openssl/certs
   1874  1.55  riastrad 		# appears to be managed manually, but `manual' was not
   1875  1.55  riastrad 		# specified in /etc/openssl/certs.conf.
   1876  1.57  riastrad 		/usr/sbin/certctl -n rehash || return $?
   1877  1.55  riastrad 
   1878  1.55  riastrad 		# Compare the trees with mtree(8).  Inconveniently,
   1879  1.55  riastrad 		# mtree returns status zero even if there are missing
   1880  1.55  riastrad 		# or extra files.  So instead of examining the return
   1881  1.55  riastrad 		# status, test for any output.  Empty output means
   1882  1.55  riastrad 		# everything matches; otherwise the mismatch, missing,
   1883  1.55  riastrad 		# or extra files are output.
   1884  1.55  riastrad 		mtree -p "$scratchdir" -c -k "$mtreekeys" \
   1885  1.55  riastrad 		| mtree -p "${DEST_DIR}/etc/openssl/certs" 2>&1 \
   1886  1.55  riastrad 		| {
   1887  1.55  riastrad 			while read -r line; do
   1888  1.55  riastrad 				# mismatch, missing, or extra
   1889  1.55  riastrad 				msg "/etc/openssl/certs needs rehash"
   1890  1.55  riastrad 				exit 1
   1891  1.55  riastrad 			done
   1892  1.55  riastrad 			exit 0
   1893  1.55  riastrad 		}
   1894  1.53  riastrad 		;;
   1895  1.53  riastrad 	fix)	# This runs openssl(1), which is not available as a
   1896  1.53  riastrad 		# build-time tool.  So for now, restrict it to running
   1897  1.53  riastrad 		# on the installed system.
   1898  1.53  riastrad 		case $DEST_DIR in
   1899  1.53  riastrad 		''|/)	;;
   1900  1.55  riastrad 		*)	msg "opensslcertsrehash limited to DEST_DIR=/"
   1901  1.53  riastrad 			return 1
   1902  1.53  riastrad 			;;
   1903  1.53  riastrad 		esac
   1904  1.57  riastrad 		/usr/sbin/certctl rehash
   1905  1.53  riastrad 		;;
   1906  1.53  riastrad 	*)	err 3 "USAGE: do_opensslcerts fix|check"
   1907  1.53  riastrad 		;;
   1908  1.53  riastrad 	esac
   1909  1.53  riastrad }
   1910  1.53  riastrad 
   1911  1.53  riastrad 
   1912  1.53  riastrad #
   1913   1.1  christos #	pam
   1914   1.1  christos #
   1915  1.37     lukem 
   1916   1.1  christos additem pam "/etc/pam.d is populated"
   1917   1.1  christos do_pam()
   1918   1.1  christos {
   1919  1.36     lukem 	[ -n "$1" ] || err 3 "USAGE: do_pam fix|check"
   1920  1.59  christos 	local op="$1"
   1921  1.59  christos 	local failed=0
   1922   1.1  christos 
   1923   1.1  christos 	populate_dir "${op}" true "${SRC_DIR}/etc/pam.d" \
   1924   1.1  christos 		"${DEST_DIR}/etc/pam.d" 644 \
   1925   1.1  christos 		README cron display_manager ftpd gdm imap kde login other \
   1926   1.1  christos 		passwd pop3 ppp racoon rexecd rsh sshd su system telnetd \
   1927   1.1  christos 		xdm xserver
   1928   1.1  christos 
   1929   1.1  christos 	failed=$(( ${failed} + $? ))
   1930   1.1  christos 
   1931   1.1  christos 	return ${failed}
   1932   1.1  christos }
   1933   1.1  christos 
   1934  1.37     lukem 
   1935   1.1  christos #
   1936   1.1  christos #	periodic
   1937   1.1  christos #
   1938  1.37     lukem 
   1939   1.1  christos additem periodic "/etc/{daily,weekly,monthly,security} being up to date"
   1940   1.1  christos do_periodic()
   1941   1.1  christos {
   1942  1.36     lukem 	[ -n "$1" ] || err 3 "USAGE: do_periodic fix|check"
   1943   1.1  christos 
   1944   1.1  christos 	compare_dir "$1" "${SRC_DIR}/etc" "${DEST_DIR}/etc" 644 \
   1945   1.1  christos 		daily weekly monthly security
   1946   1.1  christos }
   1947   1.1  christos 
   1948  1.37     lukem 
   1949   1.1  christos #
   1950   1.1  christos #	pf
   1951   1.1  christos #
   1952  1.37     lukem 
   1953   1.1  christos additem pf "pf configuration being up to date"
   1954   1.1  christos do_pf()
   1955   1.1  christos {
   1956  1.36     lukem 	[ -n "$1" ] || err 3 "USAGE: do_pf fix|check"
   1957  1.59  christos 	local op="$1"
   1958  1.59  christos 	local failed=0
   1959   1.1  christos 
   1960   1.1  christos 	find_file_in_dirlist pf.os "pf.os" \
   1961   1.1  christos 	    "${SRC_DIR}/dist/pf/etc" "${SRC_DIR}/etc" \
   1962   1.1  christos 	    || return 1
   1963   1.1  christos 			# ${dir} is set by find_file_in_dirlist()
   1964   1.1  christos 	populate_dir "${op}" true \
   1965   1.1  christos 	    "${dir}" "${DEST_DIR}/etc" 644 \
   1966   1.1  christos 	    pf.conf
   1967   1.1  christos 	failed=$(( ${failed} + $? ))
   1968   1.1  christos 
   1969   1.1  christos 	compare_dir "${op}" "${dir}" "${DEST_DIR}/etc" 444 pf.os
   1970   1.1  christos 	failed=$(( ${failed} + $? ))
   1971   1.1  christos 
   1972   1.1  christos 	return ${failed}
   1973   1.1  christos }
   1974   1.1  christos 
   1975  1.37     lukem 
   1976  1.37     lukem #
   1977  1.37     lukem #	ptyfsoldnodes
   1978  1.37     lukem #
   1979  1.37     lukem 
   1980  1.37     lukem additem ptyfsoldnodes "remove legacy device nodes when using ptyfs"
   1981  1.37     lukem do_ptyfsoldnodes()
   1982  1.37     lukem {
   1983  1.37     lukem 	[ -n "$1" ] || err 3 "USAGE: do_ptyfsoldnodes fix|check"
   1984  1.59  christos 	local op="$1"
   1985  1.37     lukem 
   1986  1.37     lukem 	# Check whether ptyfs is in use
   1987  1.59  christos 	local failed=0;
   1988  1.37     lukem 	if ! ${GREP} -E "^ptyfs" "${DEST_DIR}/etc/fstab" > /dev/null; then
   1989  1.37     lukem 		msg "ptyfs is not in use"
   1990  1.37     lukem 		return 0
   1991  1.37     lukem 	fi
   1992  1.37     lukem 
   1993  1.37     lukem 	if [ ! -e "${DEST_DIR}/dev/pts" ]; then
   1994  1.37     lukem 		msg "ptyfs is not properly configured: missing /dev/pts"
   1995  1.37     lukem 		return 1
   1996  1.37     lukem 	fi
   1997  1.37     lukem 
   1998  1.37     lukem 	# Find the device major numbers for the pty master and slave
   1999  1.37     lukem 	# devices, by parsing the output from "MAKEDEV -s pty0".
   2000  1.37     lukem 	#
   2001  1.37     lukem 	# Output from MAKEDEV looks like this:
   2002  1.37     lukem 	# ./ttyp0 type=char device=netbsd,5,0 mode=666 gid=0 uid=0
   2003  1.37     lukem 	# ./ptyp0 type=char device=netbsd,6,0 mode=666 gid=0 uid=0
   2004  1.37     lukem 	#
   2005  1.37     lukem 	# Output from awk, used in the eval statement, looks like this:
   2006  1.37     lukem 	# maj_ptym=6; maj_ptys=5;
   2007  1.37     lukem 	#
   2008  1.59  christos 	local maj_ptym maj_ptys
   2009  1.37     lukem 	find_makedev
   2010  1.37     lukem 	eval "$(
   2011  1.37     lukem 	    ${HOST_SH} "${MAKEDEV_DIR}/MAKEDEV" -s pty0 2>/dev/null \
   2012  1.37     lukem 	    | ${AWK} '\
   2013  1.37     lukem 	    BEGIN { before_re = ".*device=[a-zA-Z]*,"; after_re = ",.*"; }
   2014  1.37     lukem 	    /ptyp0/ { maj_ptym = gensub(before_re, "", 1, $0);
   2015  1.37     lukem 		      maj_ptym = gensub(after_re, "", 1, maj_ptym); }
   2016  1.37     lukem 	    /ttyp0/ { maj_ptys = gensub(before_re, "", 1, $0);
   2017  1.37     lukem 		      maj_ptys = gensub(after_re, "", 1, maj_ptys); }
   2018  1.37     lukem 	    END { print "maj_ptym=" maj_ptym "; maj_ptys=" maj_ptys ";"; }
   2019  1.37     lukem 	    '
   2020  1.37     lukem 	    )"
   2021  1.37     lukem 	#msg "Major numbers are maj_ptym=${maj_ptym} maj_ptys=${maj_ptys}"
   2022  1.37     lukem 	if [ -z "$maj_ptym" ] || [ -z "$maj_ptys" ]; then
   2023  1.37     lukem 		msg "Cannot find device major numbers for pty master and slave"
   2024  1.37     lukem 		return 1
   2025  1.37     lukem 	fi
   2026  1.37     lukem 
   2027  1.37     lukem 	# look for /dev/[pt]ty[p-zP-T][0-9a-zA-Z], and check that they
   2028  1.37     lukem 	# have the expected device major numbers.  ttyv* is typically not a
   2029  1.37     lukem 	# pty device, but we check it anyway.
   2030  1.37     lukem 	#
   2031  1.37     lukem 	# The "for d1" loop is intended to avoid overflowing ARG_MAX;
   2032  1.37     lukem 	# otherwise we could have used a single glob pattern.
   2033  1.37     lukem 	#
   2034  1.37     lukem 	# If there are no files that match a particular pattern,
   2035  1.37     lukem 	# then stat prints something like:
   2036  1.37     lukem 	#    stat: /dev/[pt]tyx?: lstat: No such file or directory
   2037  1.37     lukem 	# and we ignore it.  XXX: We also ignore other error messages.
   2038  1.37     lukem 	#
   2039  1.59  christos 	local d1 major node
   2040  1.59  christos 	local tmp="$(mktemp /tmp/postinstall.ptyfs.XXXXXXXX)"
   2041  1.59  christos 
   2042  1.37     lukem 	for d1 in p q r s t u v w x y z P Q R S T; do
   2043  1.37     lukem 		${STAT} -f "%Hr %N" "${DEST_DIR}/dev/"[pt]ty${d1}? 2>&1
   2044  1.37     lukem 	done \
   2045  1.37     lukem 	| while read -r major node ; do
   2046  1.37     lukem 		case "$major" in
   2047  1.37     lukem 		${maj_ptym}|${maj_ptys}) echo "$node" ;;
   2048  1.37     lukem 		esac
   2049  1.59  christos 	done > "${tmp}"
   2050  1.37     lukem 
   2051  1.59  christos 	local desc="legacy device node"
   2052  1.37     lukem 	while read node; do
   2053  1.59  christos 		if [ "${op}" = "check" ]; then
   2054  1.59  christos 			msg "Remove ${desc} ${node}"
   2055  1.37     lukem 			failed=1
   2056  1.37     lukem 		else # "fix"
   2057  1.59  christos 			if ${RM} "${node}"; then
   2058  1.59  christos 				msg "Removed ${desc} ${node}"
   2059  1.37     lukem 			else
   2060  1.59  christos 				warn "Failed to remove ${desc} ${node}"
   2061  1.37     lukem 				failed=1
   2062  1.37     lukem 			fi
   2063  1.37     lukem 		fi
   2064  1.59  christos 	done < "${tmp}"
   2065  1.59  christos 	${RM} "${tmp}"
   2066  1.37     lukem 
   2067  1.37     lukem 	return ${failed}
   2068  1.37     lukem }
   2069  1.37     lukem 
   2070  1.37     lukem 
   2071   1.1  christos #
   2072   1.1  christos #	pwd_mkdb
   2073   1.1  christos #
   2074  1.37     lukem 
   2075   1.1  christos additem pwd_mkdb "passwd database version"
   2076   1.1  christos do_pwd_mkdb()
   2077   1.1  christos {
   2078  1.36     lukem 	[ -n "$1" ] || err 3 "USAGE: do_pwd_mkdb fix|check"
   2079  1.59  christos 	local op="$1"
   2080  1.59  christos 	local failed=0
   2081   1.1  christos 
   2082   1.1  christos 	# XXX Ideally, we should figure out the endianness of the
   2083   1.1  christos 	# target machine, and add "-E B"/"-E L" to the db(1) flags,
   2084   1.1  christos 	# and "-B"/"-L" to the pwd_mkdb(8) flags if the target is not
   2085   1.1  christos 	# the same as the host machine.  It probably doesn't matter,
   2086   1.1  christos 	# because we don't expect "postinstall fix pwd_mkdb" to be
   2087   1.1  christos 	# invoked during a cross build.
   2088   1.1  christos 
   2089   1.1  christos 	set -- $(${DB} -q -Sb -Ub -To -N hash "${DEST_DIR}/etc/pwd.db" \
   2090   1.1  christos 		'VERSION\0')
   2091   1.1  christos 	case "$2" in
   2092   1.1  christos 	'\001\000\000\000') return 0 ;; # version 1, little-endian
   2093   1.1  christos 	'\000\000\000\001') return 0 ;; # version 1, big-endian
   2094   1.1  christos 	esac
   2095   1.1  christos 
   2096   1.1  christos 	if [ "${op}" = "check" ]; then
   2097   1.1  christos 		msg "Update format of passwd database"
   2098   1.1  christos 		failed=1
   2099   1.1  christos 	elif ! ${PWD_MKDB} -V 1 -d "${DEST_DIR:-/}" \
   2100   1.1  christos 			"${DEST_DIR}/etc/master.passwd";
   2101   1.1  christos 	then
   2102   1.1  christos 		msg "Can't update format of passwd database"
   2103   1.1  christos 		failed=1
   2104   1.1  christos 	else
   2105   1.1  christos 		msg "Updated format of passwd database"
   2106   1.1  christos 	fi
   2107   1.1  christos 
   2108   1.1  christos 	return ${failed}
   2109   1.1  christos }
   2110   1.1  christos 
   2111  1.37     lukem 
   2112   1.1  christos #
   2113   1.1  christos #	rc
   2114   1.1  christos #
   2115   1.1  christos 
   2116  1.12   tsutsui # There is no info in src/distrib or /etc/mtree which rc* files
   2117  1.12   tsutsui # can be overwritten unconditionally on upgrade. See PR/54741.
   2118  1.12   tsutsui rc_644_files="
   2119  1.12   tsutsui rc
   2120  1.12   tsutsui rc.subr
   2121  1.12   tsutsui rc.shutdown
   2122  1.12   tsutsui "
   2123  1.12   tsutsui 
   2124   1.1  christos rc_obsolete_vars="
   2125   1.1  christos amd amd_master
   2126   1.1  christos btcontrol btcontrol_devices
   2127   1.1  christos critical_filesystems critical_filesystems_beforenet
   2128   1.1  christos mountcritlocal mountcritremote
   2129   1.1  christos network ip6forwarding
   2130   1.1  christos network nfsiod_flags
   2131   1.1  christos sdpd sdpd_control
   2132   1.1  christos sdpd sdpd_groupname
   2133   1.1  christos sdpd sdpd_username
   2134   1.1  christos sysctl defcorename
   2135   1.1  christos "
   2136   1.1  christos 
   2137   1.1  christos update_rc()
   2138   1.1  christos {
   2139   1.1  christos 	local op=$1
   2140   1.1  christos 	local dir=$2
   2141   1.1  christos 	local name=$3
   2142   1.1  christos 	local bindir=$4
   2143   1.1  christos 	local rcdir=$5
   2144   1.1  christos 
   2145   1.1  christos 	if [ ! -x "${DEST_DIR}/${bindir}/${name}" ]; then
   2146   1.1  christos 		return 0
   2147   1.1  christos 	fi
   2148   1.1  christos 
   2149   1.1  christos 	if ! find_file_in_dirlist "${name}" "${name}" \
   2150   1.1  christos 	    "${rcdir}" "${SRC_DIR}/etc/rc.d"; then
   2151   1.1  christos 		return 1
   2152   1.1  christos 	fi
   2153   1.1  christos 	populate_dir "${op}" false "${dir}" "${DEST_DIR}/etc/rc.d" 555 "${name}"
   2154   1.1  christos 	return $?
   2155   1.1  christos }
   2156   1.1  christos 
   2157   1.1  christos # select non-obsolete files in a sets file
   2158   1.1  christos # $1: directory pattern
   2159   1.1  christos # $2: file pattern
   2160   1.1  christos # $3: filename
   2161   1.1  christos select_set_files()
   2162   1.1  christos {
   2163   1.1  christos 	local qdir="$(echo $1 | ${SED} -e s@/@\\\\/@g -e s/\\./\\\\./g)"
   2164   1.1  christos 	${SED} -n -e /obsolete/d \
   2165   1.1  christos 	    -e "/^\.${qdir}/s@^.$2[[:space:]].*@\1@p" $3
   2166   1.1  christos }
   2167   1.1  christos 
   2168   1.4  christos # select obsolete files in a sets file
   2169   1.4  christos # $1: directory pattern
   2170   1.4  christos # $2: file pattern
   2171  1.10  christos # $3: setname
   2172   1.4  christos select_obsolete_files()
   2173   1.4  christos {
   2174  1.10  christos 	if $SOURCEMODE; then
   2175  1.10  christos 		${SED} -n -e "/obsolete/s@\.$1$2[[:space:]].*@\1@p" \
   2176  1.35     lukem 		    "${SRC_DIR}/distrib/sets/lists/$3/mi"
   2177  1.11  christos 		return
   2178  1.11  christos 	fi
   2179  1.11  christos 
   2180  1.11  christos 	# On upgrade builds we don't extract the "etc" set so we
   2181  1.11  christos 	# try to use the source set instead. See PR/54730 for
   2182  1.11  christos 	# ways to better handle this.
   2183  1.11  christos 
   2184  1.11  christos 	local obsolete_dir
   2185  1.11  christos 
   2186  1.11  christos 	if [ $3 = "etc" ] ;then
   2187  1.35     lukem 		obsolete_dir="${SRC_DIR}/var/db/obsolete"
   2188  1.10  christos 	else
   2189  1.35     lukem 		obsolete_dir="${DEST_DIR}/var/db/obsolete"
   2190  1.10  christos 	fi
   2191  1.11  christos 	${SED} -n -e "s@\.$1$2\$@\1@p" "${obsolete_dir}/$3"
   2192   1.4  christos }
   2193   1.4  christos 
   2194   1.1  christos getetcsets()
   2195   1.1  christos {
   2196   1.1  christos 	if $SOURCEMODE; then
   2197   1.1  christos 		echo "${SRC_DIR}/distrib/sets/lists/etc/mi"
   2198   1.1  christos 	else
   2199   1.1  christos 		echo "${SRC_DIR}/etc/mtree/set.etc"
   2200   1.1  christos 	fi
   2201   1.1  christos }
   2202   1.1  christos 
   2203   1.1  christos additem rc "/etc/rc* and /etc/rc.d/ being up to date"
   2204   1.1  christos do_rc()
   2205   1.1  christos {
   2206  1.36     lukem 	[ -n "$1" ] || err 3 "USAGE: do_rc fix|check"
   2207   1.1  christos 	local op="$1"
   2208   1.1  christos 	local failed=0
   2209   1.1  christos 	local generated_scripts=""
   2210   1.1  christos 	local etcsets=$(getetcsets)
   2211   1.1  christos 	if [ "${MKX11}" != "no" ]; then
   2212   1.1  christos 		generated_scripts="${generated_scripts} xdm xfs"
   2213   1.1  christos 	fi
   2214   1.1  christos 
   2215   1.1  christos 	# Directories of external programs that have rc files (in bsd)
   2216  1.26  christos 	local rc_external_files="blocklist nsd unbound"
   2217   1.1  christos 
   2218   1.1  christos 	# rc* files in /etc/
   2219  1.12   tsutsui 	# XXX: at least rc.conf and rc.local shouldn't be updated. PR/54741
   2220  1.12   tsutsui 	#local rc_644_files="$(select_set_files /etc/rc \
   2221  1.12   tsutsui 	#    "/etc/\(rc[^[:space:]/]*\)" ${etcsets})"
   2222   1.1  christos 
   2223   1.1  christos 	# no-obsolete rc files in /etc/rc.d
   2224   1.1  christos 	local rc_555_files="$(select_set_files /etc/rc.d/ \
   2225   1.1  christos 	    "/etc/rc\.d/\([^[:space:]]*\)" ${etcsets} | \
   2226   1.1  christos 	    exclude ${rc_external_files})"
   2227   1.1  christos 
   2228   1.1  christos 	# obsolete rc file in /etc/rc.d
   2229   1.4  christos 	local rc_obsolete_files="$(select_obsolete_files /etc/rc.d/ \
   2230  1.10  christos 	    "\([^[:space:]]*\)" etc)"
   2231   1.1  christos 
   2232   1.1  christos 	compare_dir "${op}" "${SRC_DIR}/etc" "${DEST_DIR}/etc" 644 \
   2233   1.1  christos 		${rc_644_files}
   2234   1.1  christos 	failed=$(( ${failed} + $? ))
   2235   1.1  christos 
   2236   1.1  christos 	local extra_scripts
   2237   1.1  christos 	if ! $SOURCEMODE; then
   2238   1.1  christos 		extra_scripts="${generated_scripts}"
   2239   1.1  christos 	else
   2240   1.1  christos 		extra_scripts=""
   2241   1.1  christos 	fi
   2242   1.1  christos 
   2243   1.1  christos 	compare_dir "${op}" "${SRC_DIR}/etc/rc.d" "${DEST_DIR}/etc/rc.d" 555 \
   2244   1.1  christos 		${rc_555_files} \
   2245   1.1  christos 		${extra_scripts}
   2246   1.1  christos 	failed=$(( ${failed} + $? ))
   2247   1.1  christos 
   2248  1.60  christos 	local i rc_file
   2249   1.1  christos 	for i in ${rc_external_files}; do
   2250   1.1  christos 	    case $i in
   2251   1.1  christos 	    *d) rc_file=${i};;
   2252   1.1  christos 	    *)	rc_file=${i}d;;
   2253   1.1  christos 	    esac
   2254  1.28  riastrad 
   2255   1.1  christos 	    update_rc "${op}" "${dir}" ${rc_file} /sbin \
   2256   1.1  christos 		"${SRC_DIR}/external/bsd/$i/etc/rc.d"
   2257   1.1  christos 	    failed=$(( ${failed} + $? ))
   2258   1.1  christos 	done
   2259   1.1  christos 
   2260   1.1  christos 	if $SOURCEMODE && [ -n "${generated_scripts}" ]; then
   2261   1.1  christos 		# generate scripts
   2262   1.1  christos 		mkdir "${SCRATCHDIR}/rc"
   2263   1.1  christos 		for f in ${generated_scripts}; do
   2264   1.1  christos 			${SED} -e "s,@X11ROOTDIR@,${X11ROOTDIR},g" \
   2265   1.1  christos 			    < "${SRC_DIR}/etc/rc.d/${f}.in" \
   2266   1.1  christos 			    > "${SCRATCHDIR}/rc/${f}"
   2267   1.1  christos 		done
   2268   1.1  christos 		compare_dir "${op}" "${SCRATCHDIR}/rc" \
   2269   1.1  christos 		    "${DEST_DIR}/etc/rc.d" 555 \
   2270   1.1  christos 		    ${generated_scripts}
   2271   1.1  christos 		failed=$(( ${failed} + $? ))
   2272   1.1  christos 	fi
   2273   1.1  christos 
   2274   1.1  christos 		# check for obsolete rc.d files
   2275   1.1  christos 	for f in ${rc_obsolete_files}; do
   2276   1.1  christos 		local fd="/etc/rc.d/${f}"
   2277   1.1  christos 		[ -e "${DEST_DIR}${fd}" ] && echo "${fd}"
   2278   1.1  christos 	done | obsolete_paths "${op}"
   2279   1.1  christos 	failed=$(( ${failed} + $? ))
   2280   1.1  christos 
   2281   1.1  christos 		# check for obsolete rc.conf(5) variables
   2282   1.1  christos 	set -- ${rc_obsolete_vars}
   2283   1.1  christos 	while [ $# -gt 1 ]; do
   2284   1.1  christos 		if rcconf_is_set "${op}" "$1" "$2" 1; then
   2285   1.1  christos 			failed=1
   2286   1.1  christos 		fi
   2287   1.1  christos 		shift 2
   2288   1.1  christos 	done
   2289   1.1  christos 
   2290   1.1  christos 	return ${failed}
   2291   1.1  christos }
   2292   1.1  christos 
   2293  1.37     lukem 
   2294   1.1  christos #
   2295   1.1  christos #	sendmail
   2296   1.1  christos #
   2297  1.37     lukem 
   2298   1.1  christos adddisableditem sendmail "remove obsolete sendmail configuration files and scripts"
   2299   1.1  christos do_sendmail()
   2300   1.1  christos {
   2301  1.36     lukem 	[ -n "$1" ] || err 3 "USAGE: do_sendmail fix|check"
   2302   1.1  christos 	op="$1"
   2303   1.1  christos 	failed=0
   2304   1.1  christos 
   2305   1.1  christos 	# Don't complain if the "sendmail" package is installed because the
   2306   1.1  christos 	# files might still be in use.
   2307   1.1  christos 	if /usr/sbin/pkg_info -qe sendmail >/dev/null 2>&1; then
   2308   1.1  christos 		return 0
   2309   1.1  christos 	fi
   2310   1.1  christos 
   2311   1.1  christos 	for f in /etc/mail/helpfile /etc/mail/local-host-names \
   2312   1.1  christos 	    /etc/mail/sendmail.cf /etc/mail/submit.cf /etc/rc.d/sendmail \
   2313   1.1  christos 	    /etc/rc.d/smmsp /usr/share/misc/sendmail.hf \
   2314   1.1  christos 	    $( ( find "${DEST_DIR}/usr/share/sendmail" -type f ; \
   2315   1.1  christos 	         find "${DEST_DIR}/usr/share/sendmail" -type d \
   2316   1.1  christos 	       ) | unprefix "${DEST_DIR}" ) \
   2317   1.1  christos 	    /var/log/sendmail.st \
   2318   1.1  christos 	    /var/spool/clientmqueue \
   2319   1.1  christos 	    /var/spool/mqueue
   2320   1.1  christos 	do
   2321   1.1  christos 		[ -e "${DEST_DIR}${f}" ] && echo "${f}"
   2322   1.1  christos 	done | obsolete_paths "${op}"
   2323   1.1  christos 	failed=$(( ${failed} + $? ))
   2324   1.1  christos 
   2325   1.1  christos 	return ${failed}
   2326   1.1  christos }
   2327   1.1  christos 
   2328   1.1  christos 
   2329   1.1  christos #
   2330   1.1  christos #	ssh
   2331   1.1  christos #
   2332  1.37     lukem 
   2333   1.1  christos additem ssh "ssh configuration update"
   2334   1.1  christos do_ssh()
   2335   1.1  christos {
   2336  1.36     lukem 	[ -n "$1" ] || err 3 "USAGE: do_ssh fix|check"
   2337  1.59  christos 	local op="$1"
   2338   1.1  christos 
   2339  1.59  christos 	local failed=0
   2340  1.59  christos 	local etcssh="${DEST_DIR}/etc/ssh"
   2341  1.59  christos 	if ! check_dir "${op}" "${etcssh}" 755; then
   2342   1.1  christos 		failed=1
   2343   1.1  christos 	fi
   2344   1.1  christos 
   2345   1.1  christos 	if [ ${failed} -eq 0 ]; then
   2346   1.1  christos 		for f in \
   2347   1.1  christos 			    ssh_known_hosts ssh_known_hosts2 \
   2348   1.1  christos 			    ssh_host_dsa_key ssh_host_dsa_key.pub \
   2349   1.1  christos 			    ssh_host_rsa_key ssh_host_rsa_key.pub \
   2350   1.1  christos 			    ssh_host_key ssh_host_key.pub \
   2351   1.1  christos 		    ; do
   2352   1.1  christos 			if ! move_file "${op}" \
   2353  1.59  christos 			    "${DEST_DIR}/etc/${f}" "${etcssh}/${f}" ; then
   2354   1.1  christos 				failed=1
   2355   1.1  christos 			fi
   2356   1.1  christos 		done
   2357   1.1  christos 		for f in sshd.conf ssh.conf ; do
   2358   1.1  christos 				# /etc/ssh/ssh{,d}.conf -> ssh{,d}_config
   2359   1.1  christos 				#
   2360   1.1  christos 			if ! move_file "${op}" \
   2361  1.59  christos 			    "${etcssh}/${f}" "${etcssh}/${f%.conf}_config" ;
   2362   1.1  christos 			then
   2363   1.1  christos 				failed=1
   2364   1.1  christos 			fi
   2365   1.1  christos 				# /etc/ssh{,d}.conf -> /etc/ssh/ssh{,d}_config
   2366   1.1  christos 				#
   2367   1.1  christos 			if ! move_file "${op}" \
   2368   1.1  christos 			    "${DEST_DIR}/etc/${f}" \
   2369  1.59  christos 			    "${etcssh}/${f%.conf}_config" ;
   2370   1.1  christos 			then
   2371   1.1  christos 				failed=1
   2372   1.1  christos 			fi
   2373   1.1  christos 		done
   2374   1.1  christos 	fi
   2375   1.1  christos 
   2376  1.59  christos 	local sshdconf=""
   2377  1.59  christos 	local f
   2378   1.1  christos 	for f in \
   2379  1.59  christos 	    "${etcssh}/sshd_config" \
   2380  1.59  christos 	    "${etcssh}/sshd.conf" \
   2381   1.1  christos 	    "${DEST_DIR}/etc/sshd.conf" ; do
   2382   1.1  christos 		if [ -f "${f}" ]; then
   2383   1.1  christos 			sshdconf="${f}"
   2384   1.1  christos 			break
   2385   1.1  christos 		fi
   2386   1.1  christos 	done
   2387   1.1  christos 	if [ -n "${sshdconf}" ]; then
   2388   1.1  christos 		modify_file "${op}" "${sshdconf}" "${SCRATCHDIR}/sshdconf" '
   2389   1.1  christos 			/^[^#$]/ {
   2390   1.1  christos 				kw = tolower($1)
   2391   1.1  christos 				if (kw == "hostkey" &&
   2392   1.1  christos 				    $2 ~ /^\/etc\/+ssh_host(_[dr]sa)?_key$/ ) {
   2393   1.1  christos 					sub(/\/etc\/+/, "/etc/ssh/")
   2394   1.1  christos 				}
   2395   1.1  christos 				if (kw == "rhostsauthentication" ||
   2396   1.1  christos 				    kw == "verifyreversemapping" ||
   2397   1.1  christos 				    kw == "reversemappingcheck") {
   2398   1.1  christos 					sub(/^/, "# DEPRECATED:\t")
   2399   1.1  christos 				}
   2400   1.1  christos 			}
   2401   1.1  christos 			{ print }
   2402   1.1  christos 		'
   2403   1.1  christos 		failed=$(( ${failed} + $? ))
   2404   1.1  christos 	fi
   2405   1.1  christos 
   2406   1.1  christos 	if ! find_file_in_dirlist moduli "moduli" \
   2407   1.1  christos 	    "${SRC_DIR}/crypto/external/bsd/openssh/dist" "${SRC_DIR}/etc" ; then
   2408   1.1  christos 		failed=1
   2409   1.1  christos 			# ${dir} is set by find_file_in_dirlist()
   2410   1.1  christos 	elif ! compare_dir "${op}" "${dir}" "${DEST_DIR}/etc" 444 moduli; then
   2411   1.1  christos 		failed=1
   2412   1.1  christos 	fi
   2413   1.1  christos 
   2414   1.1  christos 	if ! check_dir "${op}" "${DEST_DIR}/var/chroot/sshd" 755 ; then
   2415   1.1  christos 		failed=1
   2416   1.1  christos 	fi
   2417   1.1  christos 
   2418   1.1  christos 	if rcconf_is_set "${op}" sshd sshd_conf_dir 1; then
   2419   1.1  christos 		failed=1
   2420   1.1  christos 	fi
   2421   1.1  christos 
   2422   1.1  christos 	return ${failed}
   2423   1.1  christos }
   2424   1.1  christos 
   2425  1.37     lukem 
   2426   1.1  christos #
   2427  1.37     lukem #	tcpdumpchroot
   2428   1.1  christos #
   2429  1.37     lukem 
   2430  1.37     lukem additem tcpdumpchroot "remove /var/chroot/tcpdump/etc/protocols"
   2431  1.37     lukem do_tcpdumpchroot()
   2432   1.1  christos {
   2433  1.37     lukem 	[ -n "$1" ] || err 3 "USAGE: do_tcpdumpchroot fix|check"
   2434  1.59  christos 	local op="$1"
   2435  1.37     lukem 
   2436  1.59  christos 	local failed=0;
   2437  1.37     lukem 	if [ -r "${DEST_DIR}/var/chroot/tcpdump/etc/protocols" ]; then
   2438  1.59  christos 		if [ "${op}" = "fix" ]; then
   2439  1.59  christos 			${RM} "${DEST_DIR}/var/chroot/tcpdump/etc/protocols"
   2440  1.37     lukem 			failed=$(( ${failed} + $? ))
   2441  1.37     lukem 			rmdir "${DEST_DIR}/var/chroot/tcpdump/etc"
   2442  1.37     lukem 			failed=$(( ${failed} + $? ))
   2443  1.37     lukem 		else
   2444  1.37     lukem 			failed=1
   2445  1.37     lukem 		fi
   2446  1.37     lukem 	fi
   2447  1.37     lukem 	return ${failed}
   2448  1.37     lukem }
   2449  1.37     lukem 
   2450  1.37     lukem 
   2451  1.37     lukem #
   2452  1.37     lukem #	uid
   2453  1.37     lukem #
   2454  1.37     lukem 
   2455  1.37     lukem additem uid "required users in /etc/master.passwd"
   2456  1.37     lukem do_uid()
   2457  1.37     lukem {
   2458  1.37     lukem 	[ -n "$1" ] || err 3 "USAGE: do_uid fix|check"
   2459  1.37     lukem 
   2460  1.37     lukem 	check_ids "$1" users "${DEST_DIR}/etc/master.passwd" \
   2461  1.37     lukem 	    "${SRC_DIR}/etc/master.passwd" 12 \
   2462  1.37     lukem 	    postfix SKIP named ntpd sshd SKIP _pflogd _rwhod SKIP _proxy \
   2463  1.37     lukem 	    _timedc _sdpd _httpd _mdnsd _tests _tcpdump _tss SKIP _rtadvd \
   2464  1.37     lukem 	    SKIP _unbound _nsd SKIP _dhcpcd
   2465  1.37     lukem }
   2466  1.37     lukem 
   2467  1.37     lukem 
   2468  1.37     lukem #
   2469  1.37     lukem #	varrwho
   2470  1.37     lukem #
   2471  1.37     lukem 
   2472  1.37     lukem additem varrwho "required ownership of files in /var/rwho"
   2473  1.37     lukem do_varrwho()
   2474  1.37     lukem {
   2475  1.37     lukem 	[ -n "$1" ] || err 3 "USAGE: do_varrwho fix|check"
   2476  1.37     lukem 
   2477  1.37     lukem 	contents_owner "$1" "${DEST_DIR}/var/rwho" _rwhod _rwhod
   2478  1.37     lukem }
   2479  1.37     lukem 
   2480  1.37     lukem 
   2481  1.37     lukem #
   2482  1.37     lukem #	varshm
   2483  1.37     lukem #
   2484  1.37     lukem 
   2485  1.37     lukem additem varshm "check for a tmpfs mounted on /var/shm"
   2486  1.37     lukem do_varshm()
   2487  1.37     lukem {
   2488  1.37     lukem 	[ -n "$1" ] || err 3 "USAGE: do_varshm fix|check"
   2489  1.37     lukem 	op="$1"
   2490  1.37     lukem 	failed=0
   2491  1.37     lukem 
   2492  1.37     lukem 	[ -f "${DEST_DIR}/etc/fstab" ] || return 0
   2493  1.37     lukem 	if ${GREP} -E "^var_shm_symlink" "${DEST_DIR}/etc/rc.conf" >/dev/null 2>&1;
   2494  1.37     lukem 	then
   2495  1.37     lukem 		failed=0;
   2496  1.37     lukem 	elif ${GREP} -w "/var/shm" "${DEST_DIR}/etc/fstab" >/dev/null 2>&1;
   2497  1.37     lukem 	then
   2498  1.37     lukem 		failed=0;
   2499  1.37     lukem 	else
   2500  1.37     lukem 		if [ "${op}" = "check" ]; then
   2501  1.37     lukem 			failed=1
   2502  1.37     lukem 			msg "No /var/shm mount found in ${DEST_DIR}/etc/fstab"
   2503  1.37     lukem 		elif [ "${op}" = "fix" ]; then
   2504  1.37     lukem 			printf '\ntmpfs\t/var/shm\ttmpfs\trw,-m1777,-sram%%25\n' \
   2505  1.37     lukem 				>> "${DEST_DIR}/etc/fstab"
   2506  1.37     lukem 			msg "Added tmpfs with 25% ram limit as /var/shm"
   2507  1.37     lukem 
   2508  1.37     lukem 		fi
   2509  1.37     lukem 	fi
   2510  1.37     lukem 
   2511  1.37     lukem 	return ${failed}
   2512  1.37     lukem }
   2513  1.37     lukem 
   2514  1.37     lukem 
   2515  1.37     lukem #
   2516  1.37     lukem #	wscons
   2517  1.37     lukem #
   2518  1.37     lukem 
   2519  1.37     lukem additem wscons "wscons configuration file update"
   2520  1.37     lukem do_wscons()
   2521  1.37     lukem {
   2522  1.37     lukem 	[ -n "$1" ] || err 3 "USAGE: do_wscons fix|check"
   2523  1.37     lukem 	op="$1"
   2524   1.1  christos 
   2525   1.1  christos 	[ -f "${DEST_DIR}/etc/wscons.conf" ] || return 0
   2526   1.1  christos 
   2527   1.1  christos 	failed=0
   2528   1.1  christos 	notfixed=""
   2529   1.1  christos 	if [ "${op}" = "fix" ]; then
   2530   1.1  christos 		notfixed="${NOT_FIXED}"
   2531   1.1  christos 	fi
   2532   1.1  christos 	while read _type _arg1 _rest; do
   2533   1.1  christos 		if [ "${_type}" = "mux" -a "${_arg1}" = "1" ]; then
   2534   1.1  christos 			msg \
   2535   1.1  christos     "Obsolete wscons.conf(5) entry \""${_type} ${_arg1}"\" found.${notfixed}"
   2536   1.1  christos 			failed=1
   2537   1.1  christos 		fi
   2538   1.1  christos 	done < "${DEST_DIR}/etc/wscons.conf"
   2539   1.1  christos 
   2540   1.1  christos 	return ${failed}
   2541   1.1  christos }
   2542   1.1  christos 
   2543  1.37     lukem 
   2544   1.1  christos #
   2545  1.37     lukem #	x11
   2546   1.1  christos #
   2547  1.37     lukem 
   2548   1.1  christos additem x11 "x11 configuration update"
   2549   1.1  christos do_x11()
   2550   1.1  christos {
   2551  1.36     lukem 	[ -n "$1" ] || err 3 "USAGE: do_x11 fix|check"
   2552  1.59  christos 	local p="$1"
   2553   1.1  christos 
   2554  1.59  christos 	local failed=0
   2555  1.59  christos 	local etcx11="${DEST_DIR}/etc/X11"
   2556  1.59  christos 	local libx11=""
   2557  1.59  christos 	if [ ! -d "${etcx11}" ]; then
   2558  1.59  christos 		msg "${etcx11} is not a directory; skipping check"
   2559   1.1  christos 		return 0
   2560   1.1  christos 	fi
   2561   1.1  christos 	if [ -d "${DEST_DIR}/usr/X11R6/." ]
   2562   1.1  christos 	then
   2563  1.59  christos 		libx11="${DEST_DIR}/usr/X11R6/lib/X11"
   2564  1.59  christos 		if [ ! -d "${libx11}" ]; then
   2565  1.59  christos 			msg "${libx11} is not a directory; skipping check"
   2566   1.1  christos 			return 0
   2567   1.1  christos 		fi
   2568   1.1  christos 	fi
   2569   1.1  christos 
   2570  1.59  christos 	local notfixed=""
   2571   1.1  christos 	if [ "${op}" = "fix" ]; then
   2572  1.59  christos 		notfixed="${NOT_FIXED}"
   2573   1.1  christos 	fi
   2574   1.1  christos 
   2575  1.60  christos 	local d
   2576  1.42     lukem 	# check if /usr/X11R6/lib/X11 needs to migrate to /etc/X11
   2577  1.59  christos 	if [ -n "${libx11}" ]; then
   2578  1.42     lukem 		for d in \
   2579  1.59  christos 		    fs lbxproxy proxymngr rstart twm xdm xinit xserver xsm \
   2580  1.42     lukem 		    ; do
   2581  1.59  christos 			sd="${libx11}/${d}"
   2582  1.42     lukem 			ld="/etc/X11/${d}"
   2583  1.42     lukem 			td="${DEST_DIR}${ld}"
   2584  1.42     lukem 			if [ -h "${sd}" ]; then
   2585  1.42     lukem 				continue
   2586  1.42     lukem 			elif [ -d "${sd}" ]; then
   2587  1.42     lukem 				tdfiles="$(find "${td}" \! -type d)"
   2588  1.42     lukem 				if [ -n "${tdfiles}" ]; then
   2589  1.42     lukem 					msg "${sd} exists yet ${td} already" \
   2590  1.59  christos 					    "contains files${notfixed}"
   2591  1.42     lukem 				else
   2592  1.59  christos 					msg "Migrate ${sd} to ${td}${notfixed}"
   2593  1.42     lukem 				fi
   2594  1.42     lukem 				failed=1
   2595  1.42     lukem 			elif [ -e "${sd}" ]; then
   2596  1.59  christos 				msg "Unexpected file ${sd}${notfixed}"
   2597  1.42     lukem 				continue
   2598   1.1  christos 			else
   2599  1.42     lukem 				continue
   2600   1.1  christos 			fi
   2601  1.42     lukem 		done
   2602  1.42     lukem 	fi
   2603   1.1  christos 
   2604   1.1  christos 	# check if xdm resources have been updated
   2605  1.59  christos 	if [ -r ${etcx11}/xdm/Xresources ] && \
   2606  1.59  christos 	    ! ${GREP} -q 'inpColor:' ${etcx11}/xdm/Xresources; then
   2607  1.59  christos 		msg "Update ${etcx11}/xdm/Xresources${notfixed}"
   2608   1.1  christos 		failed=1
   2609   1.1  christos 	fi
   2610   1.1  christos 
   2611   1.1  christos 	return ${failed}
   2612   1.1  christos }
   2613   1.1  christos 
   2614  1.37     lukem 
   2615   1.1  christos #
   2616   1.1  christos #	xkb
   2617   1.1  christos #
   2618   1.1  christos # /usr/X11R7/lib/X11/xkb/symbols/pc used to be a directory, but changed
   2619   1.1  christos # to a file on 2009-06-12.  Fixing this requires removing the directory
   2620   1.1  christos # (which we can do) and re-extracting the xbase set (which we can't do),
   2621   1.1  christos # or at least adding that one file (which we may be able to do if X11SRCDIR
   2622   1.1  christos # is available).
   2623   1.1  christos #
   2624  1.37     lukem 
   2625   1.1  christos additem xkb "clean up for xkbdata to xkeyboard-config upgrade"
   2626   1.1  christos do_xkb()
   2627   1.1  christos {
   2628  1.36     lukem 	[ -n "$1" ] || err 3 "USAGE: do_xkb fix|check"
   2629  1.59  christos 	local op="$1"
   2630  1.59  christos 	local failed=0
   2631   1.1  christos 
   2632  1.59  christos 	local pcpath="/usr/X11R7/lib/X11/xkb/symbols/pc"
   2633  1.59  christos 	local pcsrcdir="${X11SRCDIR}/external/mit/xkeyboard-config/dist/symbols"
   2634   1.1  christos 
   2635  1.59  christos 	local filemsg="\
   2636   1.1  christos ${pcpath} was a directory, should be a file.
   2637   1.1  christos     To fix, extract the xbase set again."
   2638   1.1  christos 
   2639  1.59  christos 	local notfixed=""
   2640   1.1  christos 	if [ "${op}" = "fix" ]; then
   2641  1.59  christos 		notfixed="${NOT_FIXED}"
   2642   1.1  christos 	fi
   2643   1.1  christos 
   2644   1.1  christos 	if [ ! -d "${DEST_DIR}${pcpath}" ]; then
   2645   1.1  christos 		return 0
   2646   1.1  christos 	fi
   2647   1.1  christos 
   2648   1.1  christos 	# Delete obsolete files in the directory, and the directory
   2649   1.1  christos 	# itself.  If the directory contains unexpected extra files
   2650   1.1  christos 	# then it will not be deleted.
   2651   1.1  christos 	( [ -f "${DEST_DIR}"/var/db/obsolete/xbase ] \
   2652   1.1  christos 	    &&  ${SORT} -ru "${DEST_DIR}"/var/db/obsolete/xbase \
   2653   1.1  christos 	    | ${GREP} -E "^\\.?${pcpath}/" ;
   2654   1.1  christos 	    echo "${pcpath}" ) \
   2655   1.1  christos 	| obsolete_paths "${op}"
   2656   1.1  christos 	failed=$(( ${failed} + $? ))
   2657   1.1  christos 
   2658   1.1  christos 	# If the directory was removed above, then try to replace it with
   2659   1.1  christos 	# a file.
   2660   1.1  christos 	if [ -d "${DEST_DIR}${pcpath}" ]; then
   2661  1.59  christos 		msg "${filemsg}${notfixed}"
   2662   1.1  christos 		failed=$(( ${failed} + 1 ))
   2663   1.1  christos 	else
   2664   1.1  christos 		if ! find_file_in_dirlist pc "${pcpath}" \
   2665   1.1  christos 			"${pcsrcdir}" "${SRC_DIR}${pcpath%/*}"
   2666   1.1  christos 		then
   2667  1.59  christos 			msg "${filemsg}${notfixed}"
   2668   1.1  christos 			failed=$(( ${failed} + 1 ))
   2669   1.1  christos 		else
   2670   1.1  christos 			# ${dir} is set by find_file_in_dirlist()
   2671   1.1  christos 			populate_dir "${op}" true \
   2672   1.1  christos 				"${dir}" "${DEST_DIR}${pcpath%/*}" 444 \
   2673   1.1  christos 				pc
   2674   1.1  christos 			failed=$(( ${failed} + $? ))
   2675   1.1  christos 		fi
   2676   1.1  christos 	fi
   2677   1.1  christos 
   2678   1.1  christos 	return $failed
   2679   1.1  christos }
   2680   1.1  christos 
   2681   1.1  christos 
   2682   1.1  christos #
   2683  1.37     lukem #	obsolete_stand
   2684  1.37     lukem #	obsolete_stand_debug
   2685   1.1  christos #
   2686   1.1  christos 
   2687  1.21  christos obsolete_stand_internal()
   2688   1.1  christos {
   2689  1.21  christos 	local prefix="$1"
   2690  1.21  christos 	shift
   2691  1.36     lukem 	[ -n "$1" ] || err 3 "USAGE: do_obsolete_stand fix|check"
   2692  1.21  christos 	local op="$1"
   2693  1.21  christos 	local failed=0
   2694  1.59  christos 	local dir
   2695   1.1  christos 
   2696   1.1  christos 	for dir in \
   2697  1.21  christos 	    ${prefix}/stand/${MACHINE} \
   2698  1.21  christos 	    ${prefix}/stand/${MACHINE}-4xx \
   2699  1.21  christos 	    ${prefix}/stand/${MACHINE}-booke \
   2700  1.21  christos 	    ${prefix}/stand/${MACHINE}-xen \
   2701  1.21  christos 	    ${prefix}/stand/${MACHINE}pae-xen
   2702   1.1  christos 	do
   2703  1.34     lukem 		[ -d "${DEST_DIR}${dir}" ] && obsolete_stand "${dir}"
   2704   1.1  christos 	done | obsolete_paths "${op}"
   2705   1.1  christos 	failed=$(( ${failed} + $? ))
   2706   1.1  christos 
   2707   1.1  christos 	return ${failed}
   2708   1.1  christos }
   2709   1.1  christos 
   2710  1.21  christos adddisableditem obsolete_stand "remove obsolete files from /stand"
   2711  1.21  christos do_obsolete_stand()
   2712  1.21  christos {
   2713  1.21  christos 	obsolete_stand_internal "" "$@"
   2714  1.21  christos 	return $?
   2715  1.21  christos }
   2716  1.21  christos 
   2717  1.21  christos adddisableditem obsolete_stand_debug "remove obsolete files from /usr/libdata/debug/stand"
   2718  1.21  christos do_obsolete_stand_debug()
   2719  1.21  christos {
   2720  1.21  christos 	obsolete_stand_internal "/usr/libdata/debug" "$@"
   2721  1.21  christos 	return $?
   2722  1.21  christos }
   2723  1.21  christos 
   2724  1.37     lukem 
   2725  1.37     lukem #
   2726  1.37     lukem #	obsolete
   2727  1.37     lukem #
   2728  1.37     lukem # NOTE: This item is last to allow other items to move obsolete files.
   2729  1.37     lukem #
   2730  1.37     lukem 
   2731  1.37     lukem listarchsubdirs()
   2732  1.37     lukem {
   2733   1.1  christos 	if ! $SOURCEMODE; then
   2734   1.1  christos 		echo "@ARCHSUBDIRS@"
   2735   1.2  christos 	else
   2736   1.2  christos 		${SED} -n -e '/ARCHDIR_SUBDIR/s/[[:space:]]//gp' \
   2737  1.35     lukem 		    "${SRC_DIR}/compat/archdirs.mk"
   2738   1.1  christos 	fi
   2739   1.2  christos }
   2740   1.2  christos 
   2741  1.37     lukem getarchsubdirs()
   2742  1.37     lukem {
   2743   1.1  christos 	local m
   2744  1.59  christos 	local i
   2745  1.59  christos 
   2746   1.1  christos 	case ${MACHINE_ARCH} in
   2747   1.1  christos 	*arm*|*aarch64*)	m=arm;;
   2748   1.1  christos 	x86_64)			m=amd64;;
   2749   1.1  christos 	*)			m=${MACHINE_ARCH};;
   2750   1.1  christos 	esac
   2751   1.1  christos 
   2752   1.2  christos 	for i in $(listarchsubdirs); do
   2753   1.2  christos 		echo $i
   2754   1.2  christos 	done | ${SORT} -u | ${SED} -n -e "/=${m}/s@.*=${m}/\(.*\)@\1@p"
   2755   1.1  christos }
   2756   1.1  christos 
   2757  1.37     lukem getcompatlibdirs()
   2758  1.37     lukem {
   2759  1.59  christos 	local i
   2760  1.59  christos 
   2761   1.1  christos 	for i in $(getarchsubdirs); do
   2762   1.7  nakayama 		if [ -d "${DEST_DIR}/usr/lib/$i" ]; then
   2763   1.1  christos 			echo /usr/lib/$i
   2764   1.1  christos 		fi
   2765   1.1  christos 	done
   2766   1.1  christos }
   2767   1.1  christos 
   2768   1.1  christos additem obsolete "remove obsolete file sets and minor libraries"
   2769   1.1  christos do_obsolete()
   2770   1.1  christos {
   2771  1.36     lukem 	[ -n "$1" ] || err 3 "USAGE: do_obsolete fix|check"
   2772  1.59  christos 	local op="$1"
   2773  1.59  christos 	local failed=0
   2774  1.59  christos 	local i
   2775   1.1  christos 
   2776   1.1  christos 	${SORT} -ru "${DEST_DIR}"/var/db/obsolete/* | obsolete_paths "${op}"
   2777   1.1  christos 	failed=$(( ${failed} + $? ))
   2778   1.1  christos 
   2779   1.1  christos 	(
   2780   1.1  christos 		obsolete_libs /lib
   2781   1.1  christos 		obsolete_libs /usr/lib
   2782   1.1  christos 		obsolete_libs /usr/lib/i18n
   2783   1.1  christos 		obsolete_libs /usr/X11R6/lib
   2784   1.1  christos 		obsolete_libs /usr/X11R7/lib
   2785   1.1  christos 		for i in $(getcompatlibdirs); do
   2786   1.1  christos 			obsolete_libs $i
   2787   1.1  christos 		done
   2788   1.1  christos 	) | obsolete_paths "${op}"
   2789   1.1  christos 	failed=$(( ${failed} + $? ))
   2790   1.1  christos 
   2791   1.1  christos 	return ${failed}
   2792   1.1  christos }
   2793   1.1  christos 
   2794  1.37     lukem 
   2795   1.1  christos #
   2796   1.1  christos #	end of items
   2797   1.1  christos #	------------
   2798   1.1  christos #
   2799   1.1  christos 
   2800   1.1  christos 
   2801  1.43     lukem help()
   2802   1.1  christos {
   2803  1.43     lukem 	cat << _USAGE_
   2804  1.50     lukem Usage: ${PROGNAME} [-a ARCH] [-d DEST_DIR] [-m MACHINE] [-s SRC_ARG] [-x XSRC_DIR] OPERATION ...
   2805  1.47     lukem        ${PROGNAME} -?
   2806  1.47     lukem 
   2807   1.1  christos 	Perform post-installation checks and/or fixes on a system's
   2808   1.1  christos 	configuration files.
   2809   1.1  christos 	If no items are provided, a default set of checks or fixes is applied.
   2810   1.1  christos 
   2811   1.1  christos 	Options:
   2812  1.48     lukem 	-?		Display this help, and exit.
   2813  1.49     lukem 	-a ARCH		Set \$MACHINE_ARCH to ARCH.	[${MACHINE_ARCH}]
   2814  1.46     lukem 	-d DEST_DIR	Destination directory to check. [${DEST_DIR:-/}]
   2815  1.49     lukem 	-m MACHINE	Set \$MACHINE to MACHINE.	[${MACHINE}]
   2816  1.50     lukem 	-s SRC_ARG	Location of the source files.  This may be any of
   2817  1.46     lukem 			the following:
   2818  1.50     lukem 			-s SRC_DIR	A directory that contains a NetBSD
   2819  1.50     lukem 					source tree.
   2820  1.50     lukem 			-s TGZ_DIR	A directory in which one or both of
   2821  1.50     lukem 					"etc.tgz" and "xetc.tgz" have been
   2822  1.50     lukem 					extracted.
   2823  1.50     lukem 			-s TGZ_FILE	A distribution set file such as
   2824  1.50     lukem 					"etc.tgz" or "xetc.tgz".
   2825  1.50     lukem 					May be specified multipled times.
   2826   1.1  christos 							[${SRC_DIR:-/usr/src}]
   2827  1.46     lukem 	-x XSRC_DIR	Location of the X11 source files.  This must be
   2828   1.1  christos 			a directory that contains a NetBSD xsrc tree.
   2829   1.1  christos 							[${XSRC_DIR:-/usr/src/../xsrc}]
   2830  1.46     lukem 
   2831  1.46     lukem 	Supported values for OPERATION:
   2832  1.48     lukem 	help		Display this help, and exit.
   2833  1.46     lukem 	list		List available items.
   2834  1.46     lukem 	check ITEM ...	Perform post-installation checks on ITEMs.
   2835  1.47     lukem 	diff [-bcenpuw] ITEM ...
   2836  1.46     lukem 			Similar to 'check' but also output difference of files,
   2837  1.47     lukem 			using diff with the provided options.
   2838  1.46     lukem 	fix ITEM ...	Apply fixes that 'check' determines need to be applied.
   2839  1.48     lukem 	usage		Display this help, and exit.
   2840   1.1  christos _USAGE_
   2841  1.43     lukem }
   2842  1.43     lukem 
   2843  1.43     lukem usage()
   2844  1.43     lukem {
   2845  1.43     lukem 	help 1>&2
   2846   1.1  christos 	exit 2
   2847   1.1  christos }
   2848   1.1  christos 
   2849   1.1  christos 
   2850   1.1  christos list()
   2851   1.1  christos {
   2852  1.59  christos 	local i
   2853   1.1  christos 	echo "Default set of items (to apply if no items are provided by user):"
   2854  1.38     lukem 	echo " Item                 Description"
   2855  1.38     lukem 	echo " ----                 -----------"
   2856   1.1  christos 	for i in ${defaultitems}; do
   2857   1.1  christos 		eval desc=\"\${desc_${i}}\"
   2858  1.38     lukem 		printf " %-20s %s\n" "${i}" "${desc}"
   2859   1.1  christos 	done
   2860   1.1  christos 	echo "Items disabled by default (must be requested explicitly):"
   2861  1.38     lukem 	echo " Item                 Description"
   2862  1.38     lukem 	echo " ----                 -----------"
   2863   1.1  christos 	for i in ${otheritems}; do
   2864   1.1  christos 		eval desc=\"\${desc_${i}}\"
   2865  1.38     lukem 		printf " %-20s %s\n" "${i}" "${desc}"
   2866   1.1  christos 	done
   2867   1.1  christos }
   2868   1.1  christos 
   2869   1.1  christos 
   2870   1.1  christos main()
   2871   1.1  christos {
   2872  1.44     lukem 	DIRMODE=false		# true if "-s" specified a directory
   2873  1.45     lukem 	ITEMS=			# items to check|diff|fix. [${defaultitems}]
   2874  1.44     lukem 	N_SRC_ARGS=0		# number of "-s" args in SRC_ARGLIST
   2875  1.44     lukem 	SOURCEMODE=false	# true if "-s" specified a source directory
   2876   1.1  christos 	SRC_ARGLIST=		# quoted list of one or more "-s" args
   2877   1.1  christos 	SRC_DIR="${SRC_ARG}"	# set default value for early usage()
   2878  1.44     lukem 	TGZLIST=		# quoted list list of tgz files
   2879  1.44     lukem 	TGZMODE=false		# true if "-s" specifies a tgz file
   2880   1.1  christos 	XSRC_DIR="${SRC_ARG}/../xsrc"
   2881  1.44     lukem 	XSRC_DIR_FIX=
   2882   1.1  christos 
   2883   1.1  christos 	case "$(uname -s)" in
   2884   1.1  christos 	Darwin)
   2885   1.1  christos 		# case sensitive match for case insensitive fs
   2886   1.1  christos 		file_exists_exact=file_exists_exact
   2887   1.1  christos 		;;
   2888   1.1  christos 	*)
   2889   1.1  christos 		file_exists_exact=:
   2890   1.1  christos 		;;
   2891   1.1  christos 	esac
   2892   1.1  christos 
   2893  1.45     lukem 		# Validate options.
   2894  1.45     lukem 		#
   2895  1.47     lukem 	while getopts :a:d:m:s:x: ch; do
   2896   1.1  christos 		case "${ch}" in
   2897  1.46     lukem 		a)
   2898  1.46     lukem 			MACHINE_ARCH="${OPTARG}"
   2899  1.46     lukem 			;;
   2900  1.46     lukem 		d)
   2901  1.46     lukem 			DEST_DIR="${OPTARG}"
   2902  1.46     lukem 			;;
   2903  1.46     lukem 		m)
   2904  1.46     lukem 			MACHINE="${OPTARG}"
   2905  1.46     lukem 			;;
   2906   1.1  christos 		s)
   2907   1.1  christos 			qarg="$(shell_quote "${OPTARG}")"
   2908   1.1  christos 			N_SRC_ARGS=$(( $N_SRC_ARGS + 1 ))
   2909   1.1  christos 			SRC_ARGLIST="${SRC_ARGLIST}${SRC_ARGLIST:+ }-s ${qarg}"
   2910   1.1  christos 			if [ -f "${OPTARG}" ]; then
   2911   1.1  christos 				# arg refers to a *.tgz file.
   2912   1.1  christos 				# This may happen twice, for both
   2913   1.1  christos 				# etc.tgz and xetc.tgz, so we build up a
   2914   1.1  christos 				# quoted list in TGZLIST.
   2915   1.1  christos 				TGZMODE=true
   2916   1.1  christos 				TGZLIST="${TGZLIST}${TGZLIST:+ }${qarg}"
   2917   1.1  christos 				# Note that, when TGZMODE is true,
   2918   1.1  christos 				# SRC_ARG is used only for printing
   2919   1.1  christos 				# human-readable messages.
   2920   1.1  christos 				SRC_ARG="${TGZLIST}"
   2921   1.1  christos 			elif [ -d "${OPTARG}" ]; then
   2922   1.1  christos 				# arg refers to a directory.
   2923   1.1  christos 				# It might be a source directory, or a
   2924   1.1  christos 				# directory where the sets have already
   2925   1.1  christos 				# been extracted.
   2926   1.1  christos 				DIRMODE=true
   2927   1.1  christos 				SRC_ARG="${OPTARG}"
   2928   1.1  christos 				if [ -f "${OPTARG}/etc/Makefile" ]; then
   2929   1.1  christos 					SOURCEMODE=true
   2930   1.1  christos 				fi
   2931   1.1  christos 			else
   2932   1.1  christos 				err 2 "Invalid argument for -s option"
   2933   1.1  christos 			fi
   2934   1.1  christos 			;;
   2935   1.1  christos 		x)
   2936   1.1  christos 			if [ -d "${OPTARG}" ]; then
   2937   1.1  christos 				# arg refers to a directory.
   2938   1.1  christos 				XSRC_DIR="${OPTARG}"
   2939   1.1  christos 				XSRC_DIR_FIX="-x ${OPTARG} "
   2940   1.1  christos 			else
   2941   1.1  christos 				err 2 "Not a directory for -x option"
   2942   1.1  christos 			fi
   2943   1.1  christos 			;;
   2944  1.47     lukem 		"?")
   2945  1.47     lukem 			if [ "${OPTARG}" = "?" ]; then
   2946  1.47     lukem 				help
   2947  1.47     lukem 				return	# no further processing or validation
   2948  1.47     lukem 			fi
   2949  1.47     lukem 			warn "Unknown option -${OPTARG}"
   2950  1.47     lukem 			usage
   2951  1.47     lukem 			;;
   2952  1.47     lukem 
   2953  1.47     lukem 		:)
   2954  1.47     lukem 			warn "Missing argument for option -${OPTARG}"
   2955  1.47     lukem 			usage
   2956  1.47     lukem 			;;
   2957  1.47     lukem 
   2958   1.1  christos 		*)
   2959  1.47     lukem 			err 3 "Unimplemented option -${ch}"
   2960   1.1  christos 			;;
   2961   1.1  christos 		esac
   2962   1.1  christos 	done
   2963   1.1  christos 	shift $((${OPTIND} - 1))
   2964  1.43     lukem 	if [ $# -eq 0 ] ; then
   2965  1.43     lukem 		warn "Missing operation"
   2966  1.43     lukem 		usage
   2967  1.43     lukem 	fi
   2968  1.45     lukem 	op="$1"
   2969  1.45     lukem 	shift
   2970   1.1  christos 
   2971   1.1  christos 	if [ "$N_SRC_ARGS" -gt 1 ] && $DIRMODE; then
   2972   1.1  christos 		err 2 "Multiple -s args are allowed only with tgz files"
   2973   1.1  christos 	fi
   2974   1.1  christos 	if [ "$N_SRC_ARGS" -eq 0 ]; then
   2975   1.1  christos 		# The default SRC_ARG was set elsewhere
   2976   1.1  christos 		DIRMODE=true
   2977   1.1  christos 		SOURCEMODE=true
   2978   1.1  christos 		SRC_ARGLIST="-s $(shell_quote "${SRC_ARG}")"
   2979   1.1  christos 	fi
   2980   1.1  christos 
   2981  1.45     lukem 		# Validate 'diff' first, as it becomes 'check'
   2982  1.45     lukem 		#
   2983  1.45     lukem 	case "${op}" in
   2984  1.45     lukem 
   2985  1.45     lukem 	diff)
   2986  1.45     lukem 		op=check
   2987  1.45     lukem 		DIFF_STYLE=n			# default style is RCS
   2988  1.45     lukem 		OPTIND=1
   2989  1.47     lukem 		while getopts :bcenpuw ch; do
   2990  1.45     lukem 			case "${ch}" in
   2991  1.45     lukem 			c|e|n|u)
   2992  1.45     lukem 				if [ "${DIFF_STYLE}" != "n" -a \
   2993  1.45     lukem 				    "${DIFF_STYLE}" != "${ch}" ]; then
   2994  1.47     lukem 					warn "diff: conflicting output style: -${ch}"
   2995  1.47     lukem 					usage
   2996  1.45     lukem 				fi
   2997  1.45     lukem 				DIFF_STYLE="${ch}"
   2998  1.45     lukem 				;;
   2999  1.45     lukem 			b|p|w)
   3000  1.45     lukem 				DIFF_OPT="${DIFF_OPT} -${ch}"
   3001  1.45     lukem 				;;
   3002  1.47     lukem 			"?")
   3003  1.47     lukem 				# NOTE: not supporting diff -?
   3004  1.47     lukem 				warn "diff: Unknown option -${OPTARG}"
   3005  1.47     lukem 				usage
   3006  1.47     lukem 				;;
   3007  1.47     lukem 			:)
   3008  1.47     lukem 				warn "diff: Missing argument for option -${OPTARG}"
   3009  1.47     lukem 				usage
   3010  1.47     lukem 				;;
   3011  1.45     lukem 			*)
   3012  1.47     lukem 				err 3 "diff: Unimplemented option -${ch}"
   3013  1.45     lukem 				;;
   3014  1.45     lukem 			esac
   3015  1.45     lukem 		done
   3016  1.45     lukem 		shift $((${OPTIND} - 1))
   3017  1.45     lukem 		;;
   3018  1.45     lukem 
   3019  1.45     lukem 	esac
   3020  1.45     lukem 
   3021  1.45     lukem 		# Validate operation and items.
   3022  1.45     lukem 		#
   3023  1.45     lukem 	case "${op}" in
   3024  1.45     lukem 
   3025  1.45     lukem 	check|fix)
   3026  1.45     lukem 		ITEMS="$*"
   3027  1.45     lukem 		: ${ITEMS:="${defaultitems}"}
   3028  1.45     lukem 
   3029  1.45     lukem 		# ensure that all supplied items are valid
   3030  1.45     lukem 		#
   3031  1.45     lukem 		for i in ${ITEMS}; do
   3032  1.45     lukem 			eval desc=\"\${desc_${i}}\"
   3033  1.45     lukem 			[ -n "${desc}" ] || err 2 "Unsupported ${op} '"${i}"'"
   3034  1.45     lukem 		done
   3035  1.45     lukem 		;;
   3036  1.45     lukem 
   3037  1.45     lukem 	help|usage)
   3038  1.45     lukem 		help
   3039  1.45     lukem 		return	# no further processing or validation
   3040  1.45     lukem 		;;
   3041  1.45     lukem 
   3042  1.45     lukem 	list)
   3043  1.45     lukem 		# processed below
   3044  1.45     lukem 		;;
   3045  1.45     lukem 
   3046  1.45     lukem 	*)
   3047  1.45     lukem 		warn "Unknown operation '"${op}"'"
   3048  1.45     lukem 		usage
   3049  1.45     lukem 		;;
   3050  1.45     lukem 
   3051  1.45     lukem 	esac
   3052  1.45     lukem 
   3053   1.1  christos 	#
   3054   1.1  christos 	# If '-s' arg or args specified tgz files, extract them
   3055   1.1  christos 	# to a scratch directory.
   3056   1.1  christos 	#
   3057   1.1  christos 	if $TGZMODE; then
   3058   1.1  christos 		ETCTGZDIR="${SCRATCHDIR}/etc.tgz"
   3059   1.1  christos 		echo "Note: Creating temporary directory ${ETCTGZDIR}"
   3060   1.1  christos 		if ! mkdir "${ETCTGZDIR}"; then
   3061   1.1  christos 			err 2 "Can't create ${ETCTGZDIR}"
   3062   1.1  christos 		fi
   3063   1.1  christos 		( # subshell to localise changes to "$@"
   3064   1.1  christos 			eval "set -- ${TGZLIST}"
   3065   1.1  christos 			for tgz in "$@"; do
   3066   1.1  christos 				echo "Note: Extracting files from ${tgz}"
   3067   1.1  christos 				cat "${tgz}" | (
   3068   1.1  christos 					cd "${ETCTGZDIR}" &&
   3069   1.1  christos 					tar -zxf -
   3070   1.1  christos 				) || err 2 "Can't extract ${tgz}"
   3071   1.1  christos 			done
   3072   1.1  christos 		)
   3073   1.1  christos 		SRC_DIR="${ETCTGZDIR}"
   3074   1.1  christos 	else
   3075   1.1  christos 		SRC_DIR="${SRC_ARG}"
   3076   1.1  christos 	fi
   3077   1.1  christos 
   3078   1.1  christos 	[ -d "${SRC_DIR}" ]	|| err 2 "${SRC_DIR} is not a directory"
   3079   1.1  christos 	[ -d "${DEST_DIR}" ]	|| err 2 "${DEST_DIR} is not a directory"
   3080   1.1  christos 	[ -n "${MACHINE}" ]	|| err 2 "\${MACHINE} is not defined"
   3081   1.1  christos 	[ -n "${MACHINE_ARCH}" ] || err 2 "\${MACHINE_ARCH} is not defined"
   3082   1.1  christos 	if ! $SOURCEMODE && ! [ -f "${SRC_DIR}/etc/mtree/set.etc" ]; then
   3083   1.1  christos 		err 2 "Files from the etc.tgz set are missing"
   3084   1.1  christos 	fi
   3085   1.1  christos 
   3086   1.1  christos 		# If directories are /, clear them, so various messages
   3087   1.1  christos 		# don't have leading "//".   However, this requires
   3088   1.1  christos 		# the use of ${foo:-/} to display the variables.
   3089   1.1  christos 		#
   3090   1.1  christos 	[ "${SRC_DIR}" = "/" ]	&& SRC_DIR=""
   3091   1.1  christos 	[ "${DEST_DIR}" = "/" ]	&& DEST_DIR=""
   3092   1.1  christos 
   3093   1.1  christos 	detect_x11
   3094   1.1  christos 
   3095  1.45     lukem 		# Perform operation.
   3096  1.45     lukem 		#
   3097   1.1  christos 	case "${op}" in
   3098   1.1  christos 
   3099   1.1  christos 	check|fix)
   3100  1.45     lukem 		[ -n "${ITEMS}" ] || err 2 "${op}: missing items"
   3101   1.1  christos 
   3102   1.1  christos 		echo "Source directory: ${SRC_DIR:-/}"
   3103   1.1  christos 		if $TGZMODE; then
   3104   1.1  christos 			echo " (extracted from: ${SRC_ARG})"
   3105   1.1  christos 		fi
   3106   1.1  christos 		echo "Target directory: ${DEST_DIR:-/}"
   3107   1.1  christos 		items_passed=
   3108   1.1  christos 		items_failed=
   3109  1.45     lukem 		for i in ${ITEMS}; do
   3110   1.1  christos 			echo "${i} ${op}:"
   3111   1.1  christos 			( eval do_${i} ${op} )
   3112   1.1  christos 			if [ $? -eq 0 ]; then
   3113   1.1  christos 				items_passed="${items_passed} ${i}"
   3114   1.1  christos 			else
   3115   1.1  christos 				items_failed="${items_failed} ${i}"
   3116   1.1  christos 			fi
   3117   1.1  christos 		done
   3118   1.1  christos 
   3119   1.1  christos 		if [ "${op}" = "check" ]; then
   3120   1.1  christos 			plural="checks"
   3121   1.1  christos 		else
   3122   1.1  christos 			plural="fixes"
   3123   1.1  christos 		fi
   3124   1.1  christos 
   3125   1.1  christos 		echo "${PROGNAME} ${plural} passed:${items_passed}"
   3126   1.1  christos 		echo "${PROGNAME} ${plural} failed:${items_failed}"
   3127   1.1  christos 		if [ -n "${items_failed}" ]; then
   3128   1.1  christos 		    exitstatus=1;
   3129   1.1  christos 		    if [ "${op}" = "check" ]; then
   3130   1.1  christos 			[ "$MACHINE" = "$(uname -m)" ] && m= || m=" -m $MACHINE"
   3131   1.1  christos 			cat <<_Fix_me_
   3132   1.1  christos To fix, run:
   3133   1.1  christos     ${HOST_SH} ${0} ${SRC_ARGLIST} ${XSRC_DIR_FIX}-d ${DEST_DIR:-/}$m fix${items_failed}
   3134   1.1  christos Note that this may overwrite local changes.
   3135   1.1  christos _Fix_me_
   3136   1.1  christos 		    fi
   3137   1.1  christos 		fi
   3138  1.45     lukem 		;;
   3139   1.1  christos 
   3140  1.45     lukem 	list)
   3141  1.45     lukem 		echo "Source directory: ${SRC_DIR:-/}"
   3142  1.45     lukem 		echo "Target directory: ${DEST_DIR:-/}"
   3143  1.45     lukem 		if $TGZMODE; then
   3144  1.45     lukem 			echo " (extracted from: ${SRC_ARG})"
   3145  1.45     lukem 		fi
   3146  1.45     lukem 		list
   3147   1.1  christos 		;;
   3148   1.1  christos 
   3149   1.1  christos 	*)
   3150  1.45     lukem 			# diff, help, usage handled during operation validation
   3151  1.45     lukem 		err 3 "Unimplemented operation '"${op}"'"
   3152   1.1  christos 		;;
   3153   1.1  christos 
   3154   1.1  christos 	esac
   3155   1.1  christos }
   3156   1.1  christos 
   3157   1.2  christos if [ -n "$POSTINSTALL_FUNCTION" ]; then
   3158   1.2  christos 	eval "$POSTINSTALL_FUNCTION"
   3159   1.2  christos 	exit 0
   3160   1.2  christos fi
   3161   1.2  christos 
   3162   1.1  christos # defaults
   3163   1.1  christos #
   3164   1.1  christos PROGNAME="${0##*/}"
   3165   1.1  christos SRC_ARG="/usr/src"
   3166   1.1  christos DEST_DIR="/"
   3167   1.1  christos : ${MACHINE:="$( uname -m )"}	# assume native build if $MACHINE is not set
   3168   1.1  christos : ${MACHINE_ARCH:="$( uname -p )"}# assume native build if not set
   3169   1.1  christos 
   3170   1.1  christos DIFF_STYLE=
   3171  1.45     lukem DIFF_OPT=
   3172   1.1  christos NOT_FIXED=" (FIX MANUALLY)"
   3173   1.1  christos SCRATCHDIR="$( mkdtemp )" || err 2 "Can't create scratch directory"
   3174  1.59  christos trap "${RM} -rf \"\${SCRATCHDIR}\" ; exit 0" 1 2 3 15	# HUP INT QUIT TERM
   3175   1.1  christos 
   3176   1.1  christos umask 022
   3177   1.1  christos exec 3>/dev/null
   3178   1.1  christos exec 4>/dev/null
   3179   1.1  christos exitstatus=0
   3180   1.1  christos 
   3181   1.1  christos main "$@"
   3182  1.59  christos ${RM} -rf "${SCRATCHDIR}"
   3183   1.1  christos exit $exitstatus
   3184