Annotation of src/etc/postinstall, Revision 1.40
1.1 lukem 1: #!/bin/sh
2: #
1.40 ! lukem 3: # $NetBSD: postinstall,v 1.39 2002/11/22 15:51:42 thorpej Exp $
1.1 lukem 4: #
5: # Copyright (c) 2002 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: # 3. All advertising materials mentioning features or use of this software
20: # must display the following acknowledgement:
21: # This product includes software developed by the NetBSD
22: # Foundation, Inc. and its contributors.
23: # 4. Neither the name of The NetBSD Foundation nor the names of its
24: # contributors may be used to endorse or promote products derived
25: # from this software without specific prior written permission.
26: #
27: # THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
28: # ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
29: # TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
30: # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
31: # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32: # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33: # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34: # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35: # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36: # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37: # POSSIBILITY OF SUCH DAMAGE.
38: #
39: # postinstall
40: # check for or fix configuration changes that occur
41: # over time as NetBSD evolves.
42: #
43:
44: #
45: # checks to add:
1.16 lukem 46: # - sysctl(8) renames
1.1 lukem 47: # - de* -> tlp* migration (/etc/ifconfig.de*, $ifconfig_de*,
48: # dhclient.conf, ...) ?
49: # - support quiet/verbose mode ?
50: #
51:
52: #
53: # helper functions
54: #
55:
56: err()
57: {
58: exitval=$1
59: shift
1.32 christos 60: echo 1>&2 "${PROGNAME}: $@"
1.1 lukem 61: exit ${exitval}
62: }
63:
64: warn()
65: {
1.32 christos 66: echo 1>&2 "${PROGNAME}: $@"
1.1 lukem 67: }
68:
69: msg()
70: {
1.32 christos 71: echo " $@"
1.1 lukem 72: }
73:
74: # additem item description
75: # add item to list of supported items to check/fix
76: #
77: additem()
78: {
79: [ $# -eq 2 ] || err 2 "USAGE: additem item description"
80: items="${items}${items:+ }$1"
81: eval desc_$1=\"$2\"
82: }
83:
1.16 lukem 84: # checkdir op dir mode
85: # ensure dir exists, and if not, create it with the appropriate mode.
86: # returns 0 if ok, 1 otherwise.
87: #
88: check_dir()
89: {
90: [ $# -eq 3 ] || err 2 "USAGE: check_dir op dir mode"
91: _cdop=$1
92: _cddir=$2
93: _cdmode=$3
94: [ -d "${_cddir}" ] && return 0
95: if [ "${_cdop}" = "check" ]; then
96: msg "${_cddir} is not a directory"
97: return 1
98: elif ! mkdir -m "${_cdmode}" "${_cddir}" ; then
99: msg "Can't create missing ${_cddir}"
100: return 1
101: else
102: msg "Missing ${_cddir} created"
103: fi
104: return 0
105: }
106:
107: # check_ids op type file id [...]
108: # check if file of type "users" or "groups" contains the relevant ids
109: # returns 0 if ok, 1 otherwise.
110: #
111: check_ids()
112: {
113: [ $# -ge 4 ] || err 2 "USAGE: checks_ids op type file id [...]"
114: _op=$1
115: _type=$2
116: _file=$3
117: shift 3
1.32 christos 118: _ids="$@"
1.16 lukem 119:
120: if [ ! -f "${_file}" ]; then
121: msg "${_file} doesn't exist; can't check for missing ${_type}"
122: return 1
123: fi
124: if [ ! -r "${_file}" ]; then
125: msg "${_file} is not readable; can't check for missing ${_type}"
126: return 1
127: fi
1.24 lukem 128: _notfixed=""
129: if [ "${_op}" = "fix" ]; then
130: _notfixed=${NOT_FIXED}
131: fi
1.16 lukem 132: _missing=$(awk -F: '
133: BEGIN {
134: for (x = 1; x < ARGC; x++)
135: idlist[ARGV[x]]++
136: ARGC=1
137: }
138: {
139: found[$1]++
140: }
141: END {
142: for (id in idlist) {
143: if (! (id in found))
144: print id
145: }
146: }
147: ' ${_ids} < ${_file}) || return 1
148: if [ -n "${_missing}" ]; then
1.24 lukem 149: msg "Missing ${_type}${_notfixed}:" $(echo ${_missing})
1.16 lukem 150: return 1
151: fi
152: return 0
153: }
154:
155: # compare_dir op src dest mode file [file ...]
1.1 lukem 156: # perform op ("check" or "fix") on files in src/ against dest/
1.16 lukem 157: # returns 0 if ok, 1 otherwise.
1.1 lukem 158: #
1.16 lukem 159: compare_dir()
1.1 lukem 160: {
1.16 lukem 161: [ $# -ge 5 ] || err 2 "USAGE: compare_dir op src dest mode file [...]"
1.1 lukem 162: _op=$1
163: _src=$2
164: _dest=$3
1.5 lukem 165: _mode=$4
166: shift 4
1.32 christos 167: _files="$@"
1.1 lukem 168:
1.18 lukem 169: if [ ! -d "${_src}" ]; then
170: msg "${_src} is not a directory; skipping check"
171: return 1
172: fi
1.16 lukem 173: check_dir ${_op} ${_dest} 755 || return 1
1.1 lukem 174:
1.5 lukem 175: _cmpdir_rv=0
1.1 lukem 176: for f in ${_files}; do
177: fs=${_src}/${f}
178: fd=${_dest}/${f}
1.24 lukem 179: _error=""
1.1 lukem 180: if [ ! -f "${fd}" ]; then
1.24 lukem 181: _error="${fd} does not exist"
1.1 lukem 182: elif ! cmp -s ${fs} ${fd} ; then
1.31 lukem 183: _error="${fs} != ${fd}"
1.1 lukem 184: else
185: continue
186: fi
187: if [ "${_op}" = "check" ]; then
1.24 lukem 188: msg ${_error}
1.5 lukem 189: _cmpdir_rv=1
1.8 lukem 190: elif ! cp -f ${fs} ${fd}; then
1.1 lukem 191: msg "Can't copy ${fs} to ${fd}"
1.5 lukem 192: _cmpdir_rv=1
193: elif ! chmod ${_mode} ${fd}; then
194: msg "Can't change mode of ${fd} to ${_mode}"
195: _cmpdir_rv=1
1.1 lukem 196: else
197: msg "Copied ${fs} to ${fd}"
198: fi
199: done
1.16 lukem 200: return ${_cmpdir_rv}
1.5 lukem 201: }
202:
1.6 lukem 203: # move_file op src dest --
204: # check (op == "check") or move (op != "check") from src to dest.
205: # returns 0 if ok, 1 otherwise.
206: #
207: move_file()
208: {
209: [ $# -eq 3 ] || err 2 "USAGE: move_file op src dest"
210: _fm_op=$1
211: _fm_src=$2
212: _fm_dest=$3
213:
214: if [ -f "${_fm_src}" -a ! -f "${_fm_dest}" ]; then
215: if [ "${_fm_op}" = "check" ]; then
216: msg "Move ${_fm_src} to ${_fm_dest}"
217: return 1
218: fi
219: if ! mv ${_fm_src} ${_fm_dest}; then
220: msg "Can't move ${_fm_src} to ${_fm_dest}"
221: return 1
222: fi
223: msg "Moved ${_fm_src} to ${_fm_dest}"
224: fi
225: return 0
226: }
227:
1.24 lukem 228: # rcconf_is_set op name var --
1.16 lukem 229: # load the rcconf for name, and check if obsolete rc.conf(5) variable
230: # var is defined or not.
231: # returns 0 if defined (even to ""), otherwise 1.
232: #
233: rcconf_is_set()
234: {
1.24 lukem 235: [ $# -eq 3 ] || err 2 "USAGE: rcconf_is_set op name var"
236: _rcis_op=$1
237: _rcis_name=$2
238: _rcis_var=$3
239: _rcis_notfixed=""
240: if [ "${_rcis_op}" = "fix" ]; then
241: _rcis_notfixed=${NOT_FIXED}
242: fi
1.16 lukem 243: (
244: for f in \
245: ${DEST_DIR}/etc/rc.conf \
1.24 lukem 246: ${DEST_DIR}/etc/rc.conf.d/${_rcis_name}; do
1.16 lukem 247: [ -f "${f}" ] && . "${f}";
248: done
1.24 lukem 249: if eval "[ -n \"\${${_rcis_var}}\" \
250: -o \"\${${_rcis_var}-UNSET}\" != \"UNSET\" ]"; then
251: msg \
252: "Obsolete rc.conf(5) variable '\$${_rcis_var}' found.${_rcis_notfixed}"
1.16 lukem 253: exit 0
254: else
255: exit 1
256: fi
257: )
258: }
259:
1.5 lukem 260:
1.1 lukem 261: #
262: # items
263: # -----
264: #
265:
266: #
267: # defaults
268: #
1.30 lukem 269: additem defaults "/etc/defaults/ being up to date"
1.1 lukem 270: do_defaults()
271: {
272: [ -n "$1" ] || err 2 "USAGE: do_defaults fix|check"
273:
1.16 lukem 274: compare_dir $1 ${SRC_DIR}/etc/defaults ${DEST_DIR}/etc/defaults 444 \
1.1 lukem 275: daily.conf monthly.conf rc.conf security.conf weekly.conf
276: }
277:
278: #
279: # mtree
280: #
1.30 lukem 281: additem mtree "/etc/mtree/ being up to date"
1.1 lukem 282: do_mtree()
283: {
284: [ -n "$1" ] || err 2 "USAGE: do_mtree fix|check"
285:
1.16 lukem 286: compare_dir $1 ${SRC_DIR}/etc/mtree ${DEST_DIR}/etc/mtree 444 \
1.1 lukem 287: NetBSD.dist special
288: }
289:
290: #
1.16 lukem 291: # gid
292: #
293: additem gid "required GIDs"
294: do_gid()
295: {
296: [ -n "$1" ] || err 2 "USAGE: do_gid fix|check"
297:
298: check_ids $1 groups "${DEST_DIR}/etc/group" \
1.19 thorpej 299: named ntpd sshd smmsp
1.16 lukem 300: }
301:
302: #
303: # uid
304: #
305: additem uid "required UIDs"
306: do_uid()
307: {
308: [ -n "$1" ] || err 2 "USAGE: do_uid fix|check"
309:
310: check_ids $1 users "${DEST_DIR}/etc/master.passwd" \
1.19 thorpej 311: named ntpd sshd smmsp
1.16 lukem 312: }
313:
314:
315: #
1.10 lukem 316: # periodic
317: #
318: additem periodic "/etc/{daily,weekly,monthly,security} being up to date"
319: do_periodic()
320: {
321: [ -n "$1" ] || err 2 "USAGE: do_periodic fix|check"
322:
1.16 lukem 323: compare_dir $1 ${SRC_DIR}/etc ${DEST_DIR}/etc 644 \
1.10 lukem 324: daily weekly monthly security
325: }
326:
327: #
1.1 lukem 328: # rc
329: #
330: additem rc "/etc/rc* and /etc/rc.d/ being up to date"
331: do_rc()
332: {
333: [ -n "$1" ] || err 2 "USAGE: do_rc fix|check"
334: op=$1
1.10 lukem 335: failed=0
1.1 lukem 336:
1.16 lukem 337: compare_dir ${op} ${SRC_DIR}/etc ${DEST_DIR}/etc 644 \
1.1 lukem 338: rc rc.subr rc.shutdown
1.10 lukem 339: failed=$(( ${failed} + $? ))
1.1 lukem 340:
1.16 lukem 341: compare_dir ${op} ${SRC_DIR}/etc/rc.d ${DEST_DIR}/etc/rc.d 555 \
1.1 lukem 342: DAEMON LOGIN NETWORKING SERVERS accounting altqd amd \
1.33 elric 343: apmd bootparams bootconf.sh ccd cgd cleartmp cron \
1.1 lukem 344: dhclient dhcpd dhcrelay dmesg downinterfaces fsck \
345: ifwatchd inetd ipfilter ipfs ipmon ipnat ipsec isdnd \
346: kdc ldconfig lkm1 lkm2 lkm3 local lpd mopd motd \
347: mountall mountcritlocal mountcritremote mountd moused \
1.25 yamt 348: mrouted mixerctl named ndbootd network newsyslog nfsd \
1.1 lukem 349: nfslocking ntpd ntpdate poffd postfix ppp pwcheck \
1.27 abs 350: quota racoon rpcbind raidframe raidframeparity rarpd rbootd \
351: root route6d routed rtadvd rtsold rwho savecore \
1.1 lukem 352: screenblank sendmail securelevel sshd swap1 swap2 \
1.26 lukem 353: sysdb sysctl syslogd timed ttys virecover \
354: wdogctl wscons wsmoused \
1.25 yamt 355: xdm xfs ypbind yppasswdd ypserv
1.10 lukem 356: failed=$(( ${failed} + $? ))
1.1 lukem 357:
1.8 lukem 358: # check for obsolete rc.d files
1.34 enami 359: for f in NETWORK fsck.sh kerberos nfsiod servers systemfs \
360: daemon gated login portmap sunndd xntpd; do
1.10 lukem 361: fd=${DEST_DIR}/etc/rc.d/${f}
1.1 lukem 362: [ ! -e "${fd}" ] && continue
363: if [ "${op}" = "check" ]; then
1.8 lukem 364: msg "Remove obsolete ${fd}"
1.10 lukem 365: failed=1
1.1 lukem 366: elif ! rm ${fd}; then
1.8 lukem 367: msg "Can't remove obsolete ${fd}"
1.10 lukem 368: failed=1
1.1 lukem 369: else
1.8 lukem 370: msg "Removed obsolete ${fd}"
371: fi
372: done
373:
374: # check for obsolete rc.conf(5) variables
375: set -- amd amd_master \
376: mountcritlocal critical_filesystems_beforenet \
377: mountcritremote critical_filesystems \
378: network ip6forwarding \
379: sysctl defcorename \
380: sysctl nfsiod_flags
381: while [ $# -gt 1 ]; do
1.24 lukem 382: if rcconf_is_set ${op} $1 $2; then
1.10 lukem 383: failed=1
1.1 lukem 384: fi
1.8 lukem 385: shift 2
1.1 lukem 386: done
387:
1.10 lukem 388: return ${failed}
1.1 lukem 389: }
390:
391: #
392: # ssh
393: #
1.16 lukem 394: additem ssh "ssh configuration update"
1.1 lukem 395: do_ssh()
396: {
397: [ -n "$1" ] || err 2 "USAGE: do_ssh fix|check"
398: op=$1
399:
400: failed=0
1.10 lukem 401: _etcssh=${DEST_DIR}/etc/ssh
1.16 lukem 402: if ! check_dir ${op} ${_etcssh} 755; then
403: failed=1
1.1 lukem 404: fi
405:
1.5 lukem 406: if [ ${failed} -eq 0 ]; then
1.1 lukem 407: for f in \
408: ssh_known_hosts ssh_known_hosts2 \
409: ssh_host_dsa_key ssh_host_dsa_key.pub \
410: ssh_host_rsa_key ssh_host_rsa_key.pub \
411: ssh_host_key ssh_host_key.pub \
412: ; do
1.10 lukem 413: if ! move_file ${op} \
414: ${DEST_DIR}/etc/${f} ${_etcssh}/${f} ;
1.6 lukem 415: then
416: failed=1
417: fi
418: done
419: for f in sshd.conf ssh.conf ; do
1.7 lukem 420: # /etc/ssh/ssh{,d}.conf -> ssh{,d}_config
421: #
1.6 lukem 422: if ! move_file ${op} \
1.7 lukem 423: ${_etcssh}/${f} ${_etcssh}/${f%.conf}_config ;
1.6 lukem 424: then
425: failed=1
426: fi
1.7 lukem 427: # /etc/ssh{,d}.conf -> /etc/ssh/ssh{,d}_config
428: #
1.6 lukem 429: if ! move_file ${op} \
1.10 lukem 430: ${DEST_DIR}/etc/${f} ${_etcssh}/${f%.conf}_config ;
1.6 lukem 431: then
432: failed=1
1.1 lukem 433: fi
434: done
435: fi
436:
1.10 lukem 437: sshdconf=""
438: for f in \
439: ${_etcssh}/sshd_config \
440: ${_etcssh}/sshd.conf \
441: ${DEST_DIR}/etc/sshd.conf ; do
442: if [ -f "${f}" ]; then
443: sshdconf=${f}
444: break;
445: fi
446: done
1.1 lukem 447: if [ -n "${sshdconf}" ]; then
448: awk '
449: $1 ~ /^[Hh][Oo][Ss][Tt][Kk][Ee][Yy]$/ &&
450: $2 ~ /^\/etc\/+ssh_host(_[dr]sa)?_key$/ {
451: sub(/\/etc\/+/, "/etc/ssh/");
452: }
453: { print }
454: ' < ${sshdconf} > ${SCRATCHDIR}/sshd_config
455: if ! cmp -s ${sshdconf} ${SCRATCHDIR}/sshd_config; then
456: diff ${sshdconf} ${SCRATCHDIR}/sshd_config > \
457: ${SCRATCHDIR}/sshd_config.diffs
458: if [ "${op}" = "check" ]; then
459: msg "${sshdconf} needs the following changes:"
460: failed=1
461: elif ! cp -f ${SCRATCHDIR}/sshd_config ${sshdconf}; then
462: msg "${sshdconf} changes not applied:"
463: failed=1
464: else
465: msg "${sshdconf} changes applied:"
466: fi
467: while read _line; do
1.5 lukem 468: msg " ${_line}"
1.1 lukem 469: done < ${SCRATCHDIR}/sshd_config.diffs
1.36 lukem 470: fi
471: fi
472:
473: dirsrc=${SRC_DIR}/crypto/dist/ssh
474: diretc=${SRC_DIR}/etc
475: modulidir=
476: if [ -f "${dirsrc}"/moduli ]; then
477: modulidir=$dirsrc
478: elif [ -f "${diretc}"/moduli ]; then
479: modulidir=$diretc
480: msg "Checking for moduli from ${modulidir} instead of ${dirsrc}"
481: else
482: msg "Can't find source directory for etc/moduli"
483: failed=1
484: fi
485: if [ -n "${modulidir}" ]; then
486: if ! compare_dir ${op} ${modulidir} \
487: ${DEST_DIR}/etc 444 moduli; then
488: failed=1
1.1 lukem 489: fi
490: fi
491:
1.16 lukem 492: if ! check_dir "${op}" "${DEST_DIR}/var/chroot/sshd" 755 ; then
1.14 itojun 493: failed=1
494: fi
495:
1.24 lukem 496: if rcconf_is_set ${op} sshd sshd_conf_dir ; then
1.5 lukem 497: failed=1
498: fi
499:
1.1 lukem 500: return ${failed}
501: }
502:
1.9 lukem 503: #
504: # wscons
505: #
506: additem wscons "wscons configuration file update"
507: do_wscons()
508: {
1.11 itojun 509: [ -n "$1" ] || err 2 "USAGE: do_wscons fix|check"
1.9 lukem 510: op=$1
511:
1.10 lukem 512: [ -f ${DEST_DIR}/etc/wscons.conf ] || return 0
1.9 lukem 513:
514: failed=0
1.24 lukem 515: notfixed=""
516: if [ "${op}" = "fix" ]; then
517: notfixed=${NOT_FIXED}
518: fi
1.9 lukem 519: while read _type _arg1 _rest; do
1.16 lukem 520: if [ "${_type}" = "mux" -a "${_arg1}" = "1" ]; then
1.9 lukem 521: msg \
1.24 lukem 522: "Obsolete wscons.conf(5) entry \""${_type} ${_arg1}"\" found.${notfixed}"
1.9 lukem 523: failed=1
524: fi
1.10 lukem 525: done < ${DEST_DIR}/etc/wscons.conf
1.9 lukem 526:
527: return ${failed}
528: }
1.1 lukem 529:
1.20 itojun 530: #
531: # makedev
532: #
533: additem makedev "/dev/MAKEDEV being up to date"
534: do_makedev()
535: {
536: [ -n "$1" ] || err 2 "USAGE: do_makedev fix|check"
537:
538: compare_dir $1 ${SRC_DIR}/etc/etc.${MACHINE} \
1.21 lukem 539: ${DEST_DIR}/dev 555 MAKEDEV || return 1
1.28 itojun 540: }
541:
542: #
543: # postfix
544: #
1.30 lukem 545: additem postfix "/etc/postfix/ being up to date"
1.28 itojun 546: do_postfix()
547: {
548: [ -n "$1" ] || err 2 "USAGE: do_postfix fix|check"
549: op=$1
550: failed=0
551:
1.31 lukem 552: dirsrc=${SRC_DIR}/gnu/dist/postfix/conf
553: dirshare=${DEST_DIR}/usr/share/examples/postfix
554: if [ -d "${dirsrc}" ]; then
555: pfdir=$dirsrc
556: elif [ -d "${dirshare}" ]; then
557: pfdir=$dirshare
558: msg "Checking from ${pfdir} instead of ${dirsrc}"
559: else
560: msg "Can't find source directory"
561: return 1
562: fi
563:
564: compare_dir ${op} ${pfdir} ${DEST_DIR}/etc/postfix 555 postfix-script
1.29 lukem 565: failed=$(( ${failed} + $? ))
1.31 lukem 566: compare_dir ${op} ${pfdir} \
567: ${DEST_DIR}/etc/postfix 444 post-install postfix-files
1.28 itojun 568: failed=$(( ${failed} + $? ))
1.37 lukem 569:
570: return ${failed}
571: }
572:
573: #
574: # obsolete
575: #
1.40 ! lukem 576: additem obsolete "obsolete file sets"
1.37 lukem 577: do_obsolete()
578: {
579: [ -n "$1" ] || err 2 "USAGE: do_obsolete fix|check"
580: op=$1
581:
582: setdir=${SRC_DIR}/distrib/sets
583: makeobs=${setdir}/makeobsolete
584: if [ ! -x "${makeobs}" ]; then
585: warn "Can't find program \"${makeobs}\""
586: return 1
587: fi
588:
1.38 itojun 589: ( cd ${setdir} && ./makeobsolete -s . -t ${SCRATCHDIR} )
1.37 lukem 590: failed=0
591:
592: for obssrcfile in ${SCRATCHDIR}/*_obsolete; do
593: while read ofile; do
594: ofile=${DEST_DIR}${ofile#.}
595: cmd="rm"
596: ftype="file"
597: if [ -h "${ofile}" ]; then
598: ftype="link"
599: elif [ -d "${ofile}" ]; then
600: ftype="directory"
601: cmd="rmdir"
602: elif [ ! -e "${ofile}" ]; then
603: continue
604: fi
605: if [ "${op}" = "check" ]; then
606: msg "Remove obsolete ${ftype} ${ofile}"
607: failed=1
608: elif ! eval ${cmd} ${ofile}; then
609: msg "Can't remove obsolete ${ftype} ${ofile}"
610: failed=1
611: else
612: msg "Removed obsolete ${ftype} ${ofile}"
613: fi
614: done < ${obssrcfile}
615: done
1.28 itojun 616:
617: return ${failed}
1.20 itojun 618: }
619:
1.1 lukem 620:
621: #
622: # end of items
623: # ------------
624: #
625:
626:
627: usage()
628: {
629: cat 1>&2 << _USAGE_
630: Usage: ${PROGNAME} [-s srcdir] [-d destdir] operation [item [...]]
631: Perform post-installation checks and/or fixes on a system's
632: configuration files. If no items are provided, all checks
633: or fixes are applied.
634:
635: Options:
1.21 lukem 636: -s srcdir Source directory to compare from. [${SRC_DIR:-/}]
637: -d destdir Destination directory to check. [${DEST_DIR:-/}]
1.1 lukem 638:
639: Operation may be one of:
1.2 lukem 640: help display this help
1.1 lukem 641: list list available items
642: check perform post-installation checks on items
643: fix apply fixes that 'check' determines need to be applied
644: usage display this usage
645: _USAGE_
646: exit 1
647: }
648:
649:
650: list()
651: {
652: echo "Supported items:"
653: echo " Item Description"
654: echo " ---- -----------"
655: for i in ${items}; do
1.5 lukem 656: eval desc="\${desc_${i}}"
1.1 lukem 657: printf " %-12s %s\n" "${i}" "${desc}"
658: done
659: }
660:
661:
662: main()
663: {
664: while getopts s:d: ch; do
665: case ${ch} in
666: s)
1.10 lukem 667: SRC_DIR=${OPTARG} ;;
1.1 lukem 668: d)
1.10 lukem 669: DEST_DIR=${OPTARG} ;;
1.1 lukem 670: *)
671: usage ;;
672: esac
673: done
674: shift $((${OPTIND} - 1))
675: [ $# -gt 0 ] || usage
676:
1.21 lukem 677: [ -d "${SRC_DIR}" ] || err 1 "${SRC_DIR} is not a directory"
678: [ -d "${DEST_DIR}" ] || err 1 "${DEST_DIR} is not a directory"
679:
680: # If directories are /, clear them, so various messages
681: # don't have leading "//". However, this requires
682: # the use of ${foo:-/} to display the variables.
683: #
684: [ "${SRC_DIR}" = "/" ] && SRC_DIR=""
685: [ "${DEST_DIR}" = "/" ] && DEST_DIR=""
1.1 lukem 686:
687: op=$1
688: shift
689:
690: case "${op}" in
691:
1.2 lukem 692: usage|help)
693: usage
694: ;;
695:
696: list)
1.21 lukem 697: echo "Source directory: ${SRC_DIR:-/}"
698: echo "Target directory: ${DEST_DIR:-/}"
1.2 lukem 699: list
1.1 lukem 700: ;;
701:
702: check|fix)
1.32 christos 703: todo="$@"
1.1 lukem 704: : ${todo:=${items}}
705:
706: # ensure that all supplied items are valid
707: #
708: for i in ${todo}; do
1.5 lukem 709: eval desc=\"\${desc_${i}}\"
1.1 lukem 710: [ -n "${desc}" ] || err 1 "Unsupported ${op} '"${i}"'"
711: done
712:
713: # perform each check/fix
714: #
1.21 lukem 715: echo "Source directory: ${SRC_DIR:-/}"
716: echo "Target directory: ${DEST_DIR:-/}"
1.1 lukem 717: items_passed=
718: items_failed=
719: for i in ${todo}; do
720: echo "${i} ${op}:"
721: ( eval do_${i} ${op} )
722: if [ $? -eq 0 ]; then
723: items_passed="${items_passed} ${i}"
724: else
725: items_failed="${items_failed} ${i}"
726: fi
727: done
728:
1.6 lukem 729: if [ "${op}" = "check" ]; then
730: plural="checks"
731: else
1.5 lukem 732: plural="fixes"
1.1 lukem 733: fi
734:
1.5 lukem 735: echo "${PROGNAME} ${plural} passed:${items_passed}"
736: echo "${PROGNAME} ${plural} failed:${items_failed}"
1.1 lukem 737:
738: ;;
739:
740: *)
741: warn "Unknown operation '"${op}"'"
742: usage
743: ;;
744:
745: esac
746: }
747:
1.4 bjh21 748: mkdtemp ()
749: {
750: # Make sure we don't loop forever if mkdir will always fail.
1.8 lukem 751: [ -d /tmp ] || err 1 /tmp is not a directory
1.4 bjh21 752: [ -w /tmp ] || err 1 /tmp is not writeable
753:
754: _base=/tmp/_postinstall.$$
755: _serial=0
756:
757: while true; do
758: _dir=${_base}.${_serial}
759: mkdir -m 0700 ${_dir} && break
760: _serial=$((${_serial} + 1))
761: done
762: echo ${_dir}
763: }
1.1 lukem 764:
765: # defaults
766: #
767: PROGNAME=${0##*/}
1.10 lukem 768: SRC_DIR="/usr/src"
769: DEST_DIR="/"
1.24 lukem 770: : ${MACHINE:=$( uname -m )} # assume native build if $MACHINE is not set
771: NOT_FIXED=" [NOT FIXED]"
772:
1.5 lukem 773: SCRATCHDIR=$( mkdtemp ) || err 1 "Can't create scratch directory"
774: trap "/bin/rm -rf ${SCRATCHDIR} ; exit 0" 0 1 2 3 15 # EXIT HUP INT QUIT TERM
1.24 lukem 775:
1.3 lukem 776: umask 022
1.1 lukem 777:
1.32 christos 778: main "$@"
1.1 lukem 779: exit 0
CVSweb <webmaster@jp.NetBSD.org>