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