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