rc revision 98189
1#!/bin/sh
2#
3# Copyright (c) 2000  The FreeBSD Project
4# All rights reserved.
5#
6# Redistribution and use in source and binary forms, with or without
7# modification, are permitted provided that the following conditions
8# are met:
9# 1. Redistributions of source code must retain the above copyright
10#    notice, this list of conditions and the following disclaimer.
11# 2. Redistributions in binary form must reproduce the above copyright
12#    notice, this list of conditions and the following disclaimer in the
13#    documentation and/or other materials provided with the distribution.
14#
15# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25# SUCH DAMAGE.
26#
27#	@(#)rc	5.27 (Berkeley) 6/5/91
28# $FreeBSD: head/etc/rc 98189 2002-06-13 22:30:02Z gordon $
29#
30
31# System startup script run by init on autoboot
32# or after single-user.
33# Output and error are redirected to console by init,
34# and the console is the controlling terminal.
35
36# Note that almost all of the user-configurable behavior is no longer in
37# this file, but rather in /etc/defaults/rc.conf.  Please check that file
38# first before contemplating any changes here.  If you do need to change
39# this file for some reason, we would like to know about it.
40
41stty status '^T'
42
43# Set shell to ignore SIGINT (2), but not children;
44# shell catches SIGQUIT (3) and returns to single user after fsck.
45#
46trap : 2
47trap : 3	# shouldn't be needed
48
49HOME=/
50PATH=/sbin:/bin:/usr/sbin:/usr/bin
51export HOME PATH
52
53# If there is a global system configuration file, suck it in.
54# XXX - The only purpose of duplicating it here is to catch rc_ng="YES"
55#
56if [ -r /etc/defaults/rc.conf ]; then
57        . /etc/defaults/rc.conf
58        source_rc_confs
59elif [ -r /etc/rc.conf ]; then
60        . /etc/rc.conf
61fi
62
63# Diskless setups have to depend on a different mechanism since
64# their config files haven't been retargeted yet.
65#
66[ -e /.rcng_yes ] && rc_ng="YES"
67
68case ${rc_ng} in
69[Yy][Ee][Ss])
70	. /etc/rc.subr
71
72	# Load system configuration files. The 'XXX' is there because
73	# the function requires an argument that we don't need to use.
74	#
75	load_rc_config 'XXX'
76
77	if [ "$1" = autoboot ]; then
78        	autoboot=yes
79		_boot="faststart"
80        	rc_fast=yes        # run_rc_command(): do fast booting
81		export autoboot
82		export rc_fast
83	else
84		autoboot=no
85		_boot="start"
86	fi
87
88	os=`eval ${CMD_OSTYPE}`
89	files=`rcorder -k ${os} -s nostart /etc/rc.d/*`
90
91	for _rc_elem in ${files}; do
92        	run_rc_script ${_rc_elem} ${_boot}
93	done
94
95	echo ''
96	date
97	exit 0
98	;;
99*)
100	# fall-through to the old rc scripts
101	;;
102esac
103
104bootmode=$1
105
106# BOOTP diskless boot.  We have to run the rc file early in order to
107# retarget various config files.
108#
109if [ -r /etc/rc.diskless1 ]; then
110	dlv=`/sbin/sysctl -n vfs.nfs.diskless_valid 2> /dev/null`
111	if [ ${dlv:=0} != 0 ]; then
112		. /etc/rc.diskless1
113	fi
114fi
115
116# If there is a global system configuration file, suck it in.
117#
118if [ -r /etc/defaults/rc.conf ]; then
119	. /etc/defaults/rc.conf
120	source_rc_confs
121elif [ -r /etc/rc.conf ]; then
122	. /etc/rc.conf
123fi
124
125feed_dev_random() {
126	if [ -f "${1}" -a -r "${1}" -a -s "${1}" ]; then
127#		echo "Using ${1} as an entropy file"
128		cat "${1}" | dd of=/dev/random bs=8k 2>/dev/null
129	fi
130}
131
132chkdepend() {
133	svc=$1
134	svc_var=$2
135	dep=$3
136	dep_var=$4
137
138	eval svc_val=\${$svc_var}
139	eval dep_val=\${$dep_var}
140
141	case ${svc_val} in
142	[Yy][Ee][Ss])
143		case ${dep_val} in
144		[Yy][Ee][Ss])
145		    ;;
146		*)
147		    eval ${dep_var}="YES"
148		    echo "DEPENDENCY NOTE: ${dep} will be enabled" \
149			 "to support ${svc}"
150		    ;;
151		esac
152		;;
153	esac
154}
155
156chkdepend amd amd_enable        portmap portmap_enable
157chkdepend amd amd_enable        NFS nfs_client_enable
158chkdepend NFS nfs_server_enable portmap portmap_enable
159chkdepend NIS nis_server_enable portmap portmap_enable
160chkdepend NIS nis_client_enable portmap portmap_enable
161
162# Enable dumpdev early so that a crash during the boot process can be caught.
163#
164case ${dumpdev} in
165[Nn][Oo] | '')
166	dumpdev='NO'
167	;;
168*)
169	/sbin/dumpon -v ${dumpdev}
170	;;
171esac
172
173# Enable harvesting of entropy via devices.  The sooner this happens the
174# better so that we can take advantage of the boot process.
175#
176echo -n 'Entropy harvesting:'
177
178case ${harvest_interrupt} in
179[Nn][Oo])
180	;;
181*)
182	if [ -w /dev/random ]; then
183		/sbin/sysctl kern.random.sys.harvest.interrupt=1 >/dev/null
184		echo -n ' interrupts'
185	fi
186	;;
187esac
188
189case ${harvest_ethernet} in
190[Nn][Oo])
191	;;
192*)
193	if [ -w /dev/random ]; then
194		/sbin/sysctl kern.random.sys.harvest.ethernet=1 >/dev/null
195		echo -n ' ethernet'
196	fi
197	;;
198esac
199
200case ${harvest_p_to_p} in
201[Nn][Oo])
202	;;
203*)
204	if [ -w /dev/random ]; then
205	/sbin/sysctl kern.random.sys.harvest.point_to_point=1 >/dev/null
206		echo -n ' point_to_point'
207	fi
208	;;
209esac
210
211echo '.'
212
213# First pass at reseeding /dev/random.
214#
215case ${entropy_file} in
216[Nn][Oo] | '')
217	;;
218*)
219	if [ -w /dev/random ]; then
220		feed_dev_random "${entropy_file}"
221	fi
222	;;
223esac
224
225# XXX temporary until we can get the entropy
226# harvesting rate up
227# Entropy below is not great,
228# but better than nothing.
229( ps -fauxww; sysctl -a; date; df -ib; dmesg; ps -fauxww; ) \
230    | dd of=/dev/random bs=8k 2>/dev/null
231cat /bin/ls | dd of=/dev/random bs=8k 2>/dev/null
232
233# Configure ccd devices.
234#
235if [ -r /etc/ccd.conf ]; then
236	ccdconfig -C
237fi
238
239case ${start_vinum} in
240[Yy][Ee][Ss])
241	vinum start
242	;;
243esac
244
245swapon -a
246
247# Last chance to do things before potentially waiting for
248# operator to do fsck related tasks
249if [ -r /etc/rc.early ]; then
250	. /etc/rc.early
251fi
252
253case ${bootmode} in
254autoboot)
255	echo 'Automatic boot in progress...'
256	case ${background_fsck} in
257	[Yy][Ee][Ss])
258		fsck -F -p
259		;;
260	*)
261		fsck -p
262		;;
263	esac
264	case $? in
265	0)
266		;;
267	2)
268		exit 1
269		;;
270	4)
271		reboot
272		echo 'Reboot failed... help!'
273		exit 1
274		;;
275	8)
276		case ${fsck_y_enable} in
277		[Yy][Ee][Ss])
278			echo 'File system preen failed, trying fsck -y . . .'
279			fsck -y
280			case $? in
281			0)
282				;;
283			*)
284			echo 'Automatic filesystem check failed . . . help!'
285				exit 1
286				;;
287			esac
288			;;
289		*)
290			echo 'Automatic filesystem check failed . . . help!'
291			exit 1
292			;;
293		esac
294		;;
295	12)
296		echo 'Reboot interrupted'
297		exit 1
298		;;
299	130)
300		# interrupt before catcher installed
301		exit 1
302		;;
303	*)
304		echo 'Unknown error in reboot'
305		exit 1
306		;;
307	esac
308	;;
309*)
310	echo 'Skipping disk checks ...'
311	;;
312esac
313
314set -T
315trap "echo 'Reboot interrupted'; exit 1" 3
316
317# root normally must be read/write, but if this is a BOOTP NFS
318# diskless boot it does not have to be.
319#
320case ${root_rw_mount} in
321[Nn][Oo] | '')
322	;;
323*)
324	if ! mount -u -o rw / ; then
325		echo 'Mounting root filesystem rw failed, startup aborted'
326		exit 1
327	fi
328	;;
329esac
330
331umount -a >/dev/null 2>&1
332
333# Set up the list of network filesystem types for which mounting should be
334# delayed until after network initialization.
335networkfs_types='nfs:NFS smbfs:SMB portalfs:PORTAL'
336case ${extra_netfs_types} in
337[Nn][Oo])
338	;;
339*)
340	networkfs_types="${networkfs_types} ${extra_netfs_types}"
341	;;
342esac
343
344# Mount everything except nfs filesystems.
345mount_excludes='no'
346for i in ${networkfs_types}; do
347	fstype=${i%:*}
348	mount_excludes="${mount_excludes}${fstype},"
349done
350mount_excludes=${mount_excludes%,}
351mount -a -t ${mount_excludes}
352
353case $? in
3540)
355	;;
356*)
357	echo 'Mounting /etc/fstab filesystems failed, startup aborted'
358	exit 1
359	;;
360esac
361
362# Run custom disk mounting function here
363#
364if [ -n "${diskless_mount}" -a -r "${diskless_mount}" ]; then
365		sh ${diskless_mount}
366fi
367
368# If we booted a special kernel remove the record so we will boot
369# the default kernel next time
370rm -f /boot/nextboot.conf
371
372# Reseed /dev/random with previously stored entropy.
373case ${entropy_dir} in
374[Nn][Oo])
375	;;
376*)
377	entropy_dir=${entropy_dir:-/var/db/entropy}
378	if [ -d "${entropy_dir}" ]; then
379		if [ -w /dev/random ]; then
380			for seedfile in ${entropy_dir}/*; do
381				feed_dev_random "${seedfile}"
382			done
383		fi
384	fi
385	;;
386esac
387
388case ${entropy_file} in
389[Nn][Oo] | '')
390	;;
391*)
392	if [ -w /dev/random ]; then
393		feed_dev_random "${entropy_file}"
394	fi
395	;;
396esac
397
398adjkerntz -i
399
400purgedir() {
401	local dir file
402
403	if [ $# -eq 0 ]; then
404		purgedir .
405	else
406		for dir
407		do
408		(
409			cd "$dir" && for file in .* *
410			do
411				[ ."$file" = .. -o ."$file" = ... ] && continue
412				if [ -d "$file" -a ! -L "$file" ]
413				then
414					purgedir "$file"
415				else
416					rm -f -- "$file"
417				fi
418			done
419		)
420		done
421	fi
422}
423
424clean_var() {
425	if [ -d /var/run -a ! -f /var/run/clean_var ]; then
426		purgedir /var/run
427		# Keep a copy of the boot messages around
428		dmesg >/var/run/dmesg.boot
429		# And an initial utmp file
430		(cd /var/run && cp /dev/null utmp && chmod 644 utmp;)
431		>/var/run/clean_var
432	fi
433	if [ -d /var/spool/lock -a ! -f /var/spool/lock/clean_var ]; then
434		purgedir /var/spool/lock
435		>/var/spool/lock/clean_var
436	fi
437	rm -rf /var/spool/uucp/.Temp/*
438}
439
440# network_pass1() *may* end up writing stuff to /var - we don't want to
441# remove it immediately afterwards - *nor* do we want to fail to clean
442# an NFS-mounted /var.
443rm -f /var/run/clean_var /var/spool/lock/clean_var
444clean_var
445
446# Add additional swapfile, if configured.
447#
448case ${swapfile} in
449[Nn][Oo] | '')
450	;;
451*)
452	if [ -w "${swapfile}" -a -c /dev/mdctl ]; then
453		echo "Adding ${swapfile} as additional swap"
454		mdev=`mdconfig -a -t vnode -f ${swapfile}` && swapon /dev/${mdev}
455	fi
456	;;
457esac
458
459# Early pass to set the variables we can
460#
461if [ -r /etc/rc.sysctl ]; then
462	sh /etc/rc.sysctl first
463fi
464
465# Configure serial devices
466#
467if [ -r /etc/rc.serial ]; then
468	. /etc/rc.serial
469fi
470
471# Start up PC-card configuration
472#
473if [ -r /etc/rc.pccard ]; then
474	. /etc/rc.pccard
475fi
476
477# Start up the initial network configuration.
478#
479if [ -r /etc/rc.network ]; then
480	. /etc/rc.network	# We only need to do this once.
481	network_pass1
482fi
483
484case ${ipv6_enable} in
485[Yy][Ee][Ss])
486	if [ -r /etc/rc.network6 ]; then
487		. /etc/rc.network6	# We only need to do this once also.
488		network6_pass1
489	fi
490	;;
491esac
492
493# Mount NFS filesystems if present in /etc/fstab
494#
495# XXX When the vfsload() issues with nfsclient support and related sysctls
496# have been resolved, this block can be removed, and the condition that
497# skips nfs in the following block (for "other network filesystems") can
498# be removed.
499case "`mount -d -a -t nfs 2> /dev/null`" in
500*mount_nfs*)
501	# Handle absent nfs client support
502	nfsclient_in_kernel=0
503	if sysctl vfs.nfs >/dev/null 2>&1; then
504		nfsclient_in_kernel=1
505	else
506		kldload nfsclient && nfsclient_in_kernel=1
507	fi
508
509	case ${nfsclient_in_kernel} in
510	1)
511		echo -n 'Mounting NFS filesystem:'
512		mount -a -t nfs
513		echo '.'
514		;;
515	*)
516		echo 'Warning: nfs mount requested, but no nfs client in kernel'
517		;;
518	esac
519	;;
520esac
521
522# Mount other network filesystems if present in /etc/fstab
523for i in ${networkfs_types}; do
524	fstype=${i%:*}
525	fsdecr=${i#*:}
526
527	if [ "${fstype}" = "nfs" ]; then
528		continue
529	fi
530	case "`mount -d -a -t ${fstype}`" in
531	*mount_${fstype}*)
532	       echo -n "Mounting ${fsdecr} filesystems:"
533	       mount -a -t ${fstype}
534	       echo '.'
535	       ;;
536	esac
537done
538
539# Whack the pty perms back into shape.
540#
541if ls /dev/tty[pqrsPQRS]* > /dev/null 2>&1; then
542	chflags 0 /dev/tty[pqrsPQRS]*
543	chmod 666 /dev/tty[pqrsPQRS]*
544	chown root:wheel /dev/tty[pqrsPQRS]*
545fi
546
547# Clean up left-over files
548#
549clean_var			# If it hasn't already been done
550rm /var/run/clean_var /var/spool/lock/clean_var
551
552# Clearing /tmp at boot-time seems to have a long tradition.  It doesn't
553# help in any way for long-living systems, and it might accidentally
554# clobber files you would rather like to have preserved after a crash
555# (if not using mfs /tmp anyway).
556#
557# See also the example of another cleanup policy in /etc/periodic/daily.
558#
559case ${clear_tmp_enable} in
560[Yy][Ee][Ss])
561	echo -n 'Clearing /tmp:'
562	# prune quickly with one rm, then use find to clean up /tmp/[lq]*
563	# (not needed with mfs /tmp, but doesn't hurt there...)
564	(cd /tmp && rm -rf [a-km-pr-zA-Z]* &&
565		find -d . ! -name . ! -name lost+found ! -name quota.user \
566		! -name quota.group -exec rm -rf -- {} \;)
567	echo '.'
568	;;
569esac
570
571# Remove X lock files, since they will prevent you from restarting X11
572# after a system crash.
573#
574rm -f /tmp/.X*-lock
575rm -fr /tmp/.X11-unix
576mkdir -m 1777 /tmp/.X11-unix
577
578# Snapshot any kernel -c changes back to disk here <someday>.
579# This has changed with ELF and /kernel.config.
580
581# Load LOMAC(4) security if wanted.
582case ${lomac_enable} in
583[Yy][Ee][Ss])
584	kldload lomac >/dev/null 2>&1
585	;;
586esac
587
588echo -n 'Additional daemons:'
589
590# Start system logging and name service.  Named needs to start before syslogd
591# if you don't have a /etc/resolv.conf.
592#
593case ${syslogd_enable} in
594[Yy][Ee][Ss])
595	# Transitional symlink (for the next couple of years :) until all
596	# binaries have had a chance to move towards /var/run/log.
597	if [ ! -L /dev/log ]; then
598		# might complain for r/o root f/s
599		ln -sf /var/run/log /dev/log
600	fi
601
602	rm -f /var/run/log
603	echo -n ' syslogd';
604	${syslogd_program:-/usr/sbin/syslogd} ${syslogd_flags}
605	;;
606esac
607
608echo '.'
609
610# Build device name databases if we are not using DEVFS
611#
612if sysctl vfs.devfs.generation > /dev/null 2>&1 ; then
613	rm -f /var/run/dev.db
614else
615	dev_mkdb
616fi
617
618# $dumpdir should be a directory or a symbolic link
619# to the crash directory if core dumps are to be saved.
620#
621if [ "${dumpdev}" != 'NO' ]; then
622	case ${dumpdir} in
623	'')
624		dumpdir='/var/crash'
625		;;
626	[Nn][Oo])
627		dumpdir='NO'
628		;;
629	esac
630
631	if [ "${dumpdir}" != 'NO' ]; then
632		echo -n 'Checking for core dump: '
633		/sbin/savecore ${savecore_flags} "${dumpdir}"
634	fi
635fi
636
637if [ -n "${network_pass1_done}" ]; then
638	network_pass2
639fi
640
641# Enable/Check the quotas (must be after ypbind if using NIS)
642#
643case ${enable_quotas} in
644[Yy][Ee][Ss])
645	case ${check_quotas} in
646	[Yy][Ee][Ss])
647		echo -n 'Checking quotas:'
648		quotacheck -a
649		echo ' done.'
650		;;
651	esac
652
653	echo -n 'Enabling quotas:'
654	quotaon -a
655	echo ' done.'
656	;;
657esac
658
659if [ -n "${network_pass2_done}" ]; then
660	network_pass3
661fi
662
663# Check the password temp/lock file
664#
665if [ -e /etc/ptmp ]; then
666	logger -s -p auth.err \
667	"password file may be incorrect -- /etc/ptmp exists"
668fi
669
670case ${accounting_enable} in
671[Yy][Ee][Ss])
672	if [ -d /var/account ]; then
673		echo 'Turning on accounting:'
674		if [ ! -e /var/account/acct ]; then
675			touch /var/account/acct
676		fi
677		accton /var/account/acct
678	fi
679	;;
680esac
681
682# Make shared lib searching a little faster.  Leave /usr/lib first if you
683# add your own entries or you may come to grief.
684#
685ldconfig="/sbin/ldconfig"
686case ${ldconfig_insecure} in
687[Yy][Ee][Ss])
688	ldconfig="${ldconfig} -i"
689	;;
690esac
691if [ -x /sbin/ldconfig ]; then
692	case `/usr/bin/objformat` in
693	elf)
694		_LDC=/usr/lib
695		for i in ${ldconfig_paths}; do
696			if [ -d "${i}" ]; then
697				_LDC="${_LDC} ${i}"
698			fi
699		done
700		echo 'ELF ldconfig path:' ${_LDC}
701		${ldconfig} -elf ${_LDC}
702		;;
703	esac
704
705	# Legacy aout support for i386 only
706	case `sysctl -n hw.machine_arch` in
707	i386)
708		# Default the a.out ldconfig path.
709		: ${ldconfig_paths_aout=${ldconfig_paths}}
710		_LDC=/usr/lib/aout
711		for i in ${ldconfig_paths_aout}; do
712			if [ -d "${i}" ]; then
713				_LDC="${_LDC} ${i}"
714			fi
715		done
716		echo 'a.out ldconfig path:' ${_LDC}
717		${ldconfig} -aout ${_LDC}
718		;;
719	esac
720fi
721
722# Now start up miscellaneous daemons that don't belong anywhere else
723#
724echo -n 'Starting standard daemons:'
725case ${inetd_enable} in
726[Nn][Oo])
727	;;
728*)
729	echo -n ' inetd'; ${inetd_program:-/usr/sbin/inetd} ${inetd_flags}
730	;;
731esac
732
733case ${cron_enable} in
734[Nn][Oo])
735	;;
736*)
737	echo -n ' cron';	${cron_program:-/usr/sbin/cron} ${cron_flags}
738	;;
739esac
740
741case ${lpd_enable} in
742[Yy][Ee][Ss])
743	echo -n ' printer';	${lpd_program:-/usr/sbin/lpd} ${lpd_flags}
744	;;
745esac
746
747case ${sshd_enable} in
748[Yy][Ee][Ss])
749	if [ -x ${sshd_program:-/usr/sbin/sshd} ]; then
750		echo -n ' sshd';
751		${sshd_program:-/usr/sbin/sshd} ${sshd_flags}
752	fi
753	;;
754esac
755
756case ${usbd_enable} in
757[Yy][Ee][Ss])
758	echo -n ' usbd';	/usr/sbin/usbd ${usbd_flags}
759	;;
760esac
761
762case ${mta_start_script} in
763/*)
764	if [ -r ${mta_start_script} ]; then
765		sh ${mta_start_script}
766	fi
767	;;
768esac
769
770echo '.'
771
772# Recover vi editor files.
773find /var/tmp/vi.recover ! -type f -a ! -type d -delete
774vibackup=`echo /var/tmp/vi.recover/vi.*`
775if [ "${vibackup}" != '/var/tmp/vi.recover/vi.*' ]; then
776	echo -n 'Recovering vi editor sessions:'
777	for i in /var/tmp/vi.recover/vi.*; do
778		# Only test files that are readable.
779		if [ ! -r "${i}" ]; then
780			continue
781		fi
782
783		# Unmodified nvi editor backup files either have the
784		# execute bit set or are zero length.  Delete them.
785		if [ -x "${i}" -o ! -s "${i}" ]; then
786			rm -f "${i}"
787		fi
788	done
789
790	# It is possible to get incomplete recovery files, if the editor
791	# crashes at the right time.
792	virecovery=`echo /var/tmp/vi.recover/recover.*`
793	if [ "${virecovery}" != "/var/tmp/vi.recover/recover.*" ]; then
794		for i in /var/tmp/vi.recover/recover.*; do
795			# Only test files that are readable.
796			if [ ! -r "${i}" ]; then
797				continue
798			fi
799
800			# Delete any recovery files that are zero length,
801			# corrupted, or that have no corresponding backup file.
802			# Else send mail to the user.
803			recfile=`awk '/^X-vi-recover-path:/{print $2}' < "${i}"`
804			if [ -n "${recfile}" -a -s "${recfile}" ]; then
805				sendmail -t < "${i}"
806			else
807				rm -f "${i}"
808			fi
809		done
810	fi
811	echo '.'
812fi
813
814# Make a bounds file for msgs(1) if there isn't one already
815#
816if [ -d /var/msgs -a ! -f /var/msgs/bounds -a ! -L /var/msgs/bounds ]; then
817	echo 0 > /var/msgs/bounds
818fi
819
820case ${update_motd} in
821[Nn][Oo] | '')
822	;;
823*)
824	if T=`mktemp /tmp/_motd.XXXXXX`; then
825		uname -v | sed -e 's,^\([^#]*\) #\(.* [1-2][0-9][0-9][0-9]\).*/\([^\]*\) $,\1 (\3) #\2,' > ${T}
826		awk '{if (NR == 1) {if ($1 == "FreeBSD") {next} else {print "\n"$0}} else {print}}' < /etc/motd >> ${T}
827		cmp -s ${T} /etc/motd || {
828			cp ${T} /etc/motd
829			chmod 644 /etc/motd
830		}
831		rm -f ${T}
832	fi
833	;;
834esac
835
836# Run rc.devfs if readable to customize devfs
837#
838if [ -r /etc/rc.devfs ]; then
839	sh /etc/rc.devfs
840fi
841
842# Configure implementation specific stuff
843#
844arch=`uname -p`
845if [ -r /etc/rc.${arch} ]; then
846	. /etc/rc.${arch}
847fi
848
849# Configure the system console
850#
851if [ -r /etc/rc.syscons ]; then
852	. /etc/rc.syscons
853fi
854
855echo -n 'Additional ABI support:'
856
857# Load the SysV IPC API if requested.
858case ${sysvipc_enable} in
859[Yy][Ee][Ss])
860	echo -n ' sysvipc'
861	kldload sysvmsg >/dev/null 2>&1
862	kldload sysvsem >/dev/null 2>&1
863	kldload sysvshm >/dev/null 2>&1
864	;;
865esac
866
867# Start the Linux binary compatibility if requested.
868#
869case ${linux_enable} in
870[Yy][Ee][Ss])
871	echo -n ' linux'
872	if ! kldstat -v | grep -E 'linux(aout|elf)' > /dev/null; then
873		kldload linux > /dev/null 2>&1
874	fi
875	if [ -x /compat/linux/sbin/ldconfig ]; then
876		/compat/linux/sbin/ldconfig
877	fi
878	;;
879esac
880
881# Start the SysVR4 binary emulation if requested.
882#
883case ${svr4_enable} in
884[Yy][Ee][Ss])
885	echo -n ' svr4';	kldload svr4 > /dev/null 2>&1
886	;;
887esac
888
889echo '.'
890
891# Do traditional (but rather obsolete) rc.local file if it exists.  If you
892# use this file and want to make it programmatic, source /etc/defaults/rc.conf
893# in /etc/rc.local and add your custom variables to /etc/rc.conf, as
894# shown below.  Please do not put local extensions into /etc/rc itself.
895# Use /etc/rc.local
896#
897# ---- rc.local ----
898#	if [ -r /etc/defaults/rc.conf ]; then
899#		. /etc/defaults/rc.conf
900#		source_rc_confs
901#	elif [ -r /etc/rc.conf ]; then
902#		. /etc/rc.conf
903#	fi
904#
905#	... additional startup conditionals ...
906# ---- rc.local ----
907#
908if [ -r /etc/rc.local ]; then
909	echo -n 'Starting local daemons:'
910	sh /etc/rc.local
911	echo '.'
912fi
913
914# For each valid dir in $local_startup, search for init scripts matching *.sh
915#
916case ${local_startup} in
917[Nn][Oo] | '')
918	;;
919*)
920	echo -n 'Local package initialization:'
921	slist=""
922	if [ -z "${script_name_sep}" ]; then
923		script_name_sep=" "
924	fi
925	for dir in ${local_startup}; do
926		if [ -d "${dir}" ]; then
927			for script in ${dir}/*.sh; do
928				slist="${slist}${script_name_sep}${script}"
929			done
930		fi
931	done
932	script_save_sep="$IFS"
933	IFS="${script_name_sep}"
934	for script in ${slist}; do
935		if [ -x "${script}" ]; then
936			(set -T
937			trap 'exit 1' 2
938			${script} start)
939		elif [ -f "${script}" -o -L "${script}" ]; then
940			echo -n " (skipping ${script##*/}, not executable)"
941		fi
942	done
943	IFS="${script_save_sep}"
944	echo '.'
945	;;
946esac
947
948if [ -n "${network_pass3_done}" ]; then
949	network_pass4
950fi
951
952# Late pass to set variables we missed the first time
953#
954if [ -r /etc/rc.sysctl ]; then
955	sh /etc/rc.sysctl last
956fi
957
958# Raise kernel security level.  This should be done only after `fsck' has
959# repaired local filesystems if you want the securelevel to be greater than 1.
960#
961case ${kern_securelevel_enable} in
962[Yy][Ee][Ss])
963	if [ "${kern_securelevel}" -ge 0 ]; then
964		echo 'Raising kernel security level: '
965		sysctl kern.securelevel=${kern_securelevel}
966	fi
967	;;
968esac
969
970# Start background fsck checks if necessary
971case ${background_fsck} in
972[Yy][Ee][Ss])
973	echo 'Starting background filesystem checks'
974	nice -4 fsck -B -p 2>&1 | logger -p daemon.notice &
975	;;
976esac
977
978echo ''
979
980date
981
982exit 0
983
984