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