xref: /titanic_50/usr/src/tools/scripts/nightly.sh (revision 84f7a9b9dca4f23b5f50edef0e59d7eb44301114)
1#!/bin/ksh -p
2#
3# CDDL HEADER START
4#
5# The contents of this file are subject to the terms of the
6# Common Development and Distribution License (the "License").
7# You may not use this file except in compliance with the License.
8#
9# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10# or http://www.opensolaris.org/os/licensing.
11# See the License for the specific language governing permissions
12# and limitations under the License.
13#
14# When distributing Covered Code, include this CDDL HEADER in each
15# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16# If applicable, add the following below this CDDL HEADER, with the
17# fields enclosed by brackets "[]" replaced with your own identifying
18# information: Portions Copyright [yyyy] [name of copyright owner]
19#
20# CDDL HEADER END
21#
22#
23# Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
24# Use is subject to license terms.
25#
26# ident	"%Z%%M%	%I%	%E% SMI"
27#
28# Based on the nightly script from the integration folks,
29# Mostly modified and owned by mike_s.
30# Changes also by kjc, dmk.
31#
32# BRINGOVER_WS may be specified in the env file.
33# The default is the old behavior of CLONE_WS
34#
35# -i on the command line, means fast options, so when it's on the
36# command line (only), lint and check builds are skipped no matter what
37# the setting of their individual flags are in NIGHTLY_OPTIONS.
38#
39# LINTDIRS can be set in the env file, format is a list of:
40#
41#	/dirname-to-run-lint-on flag
42#
43#	Where flag is:	y - enable lint noise diff output
44#			n - disable lint noise diff output
45#
46#	For example: LINTDIRS="$SRC/uts n $SRC/stand y $SRC/psm y"
47#
48# -A flag in NIGHTLY_OPTIONS checks ABI diffs in .so files
49# This option requires a couple of scripts.
50#
51# OPTHOME and TEAMWARE may be set in the environment to override /opt
52# and /opt/teamware defaults.
53#
54
55#
56# The CDPATH variable causes ksh's `cd' builtin to emit messages to stdout
57# under certain circumstances, which can really screw things up; unset it.
58#
59unset CDPATH
60
61# function to do a DEBUG and non-DEBUG build. Needed because we might
62# need to do another for the source build, and since we only deliver DEBUG or
63# non-DEBUG packages.
64
65normal_build() {
66
67	# timestamp the start of a nightly build; the findunref tool uses it.
68	touch $SRC/.build.tstamp
69
70	# non-DEBUG build begins
71
72	if [ "$F_FLAG" = "n" ]; then
73		export INTERNAL_RELEASE_BUILD ; INTERNAL_RELEASE_BUILD=
74		export RELEASE_BUILD ; RELEASE_BUILD=
75		unset EXTRA_OPTIONS
76		unset EXTRA_CFLAGS
77
78		build non-DEBUG -nd
79
80		if [ "$build_ok" = "y" -a "$X_FLAG" = "y" -a "$p_FLAG" = "y" ]; then
81			copy_ihv_pkgs non-DEBUG -nd
82		fi
83	else
84		echo "\n==== No non-DEBUG build ====\n" >> $LOGFILE
85	fi
86
87	# non-DEBUG build ends
88
89	# DEBUG build begins
90
91	if [ "$D_FLAG" = "y" ]; then
92
93		export INTERNAL_RELEASE_BUILD ; INTERNAL_RELEASE_BUILD=
94		unset RELEASE_BUILD
95		unset EXTRA_OPTIONS
96		unset EXTRA_CFLAGS
97
98		build DEBUG ""
99
100		if [ "$build_ok" = "y" -a "$X_FLAG" = "y" -a "$p_FLAG" = "y" ]; then
101			copy_ihv_pkgs DEBUG ""
102		fi
103
104	else
105		echo "\n==== No DEBUG build ====\n" >> $LOGFILE
106	fi
107
108	# DEBUG build ends
109}
110
111#
112# usage: filelist DESTDIR PATTERN
113#
114filelist() {
115	DEST=$1
116	PATTERN=$2
117	cd ${DEST}
118
119	OBJFILES=${ORIG_SRC}/xmod/obj_files
120	if [ ! -f ${OBJFILES} ]; then
121		return;
122	fi
123	for i in `grep -v '^#' ${OBJFILES} | \
124	    grep ${PATTERN} | cut -d: -f2 | tr -d ' \t'`
125	do
126		# wildcard expansion
127		for j in $i
128		do
129			if [ -f "$j" ]; then
130				echo $j
131			fi
132			if [ -d "$j" ]; then
133				echo $j
134			fi
135		done
136	done | sort | uniq
137}
138
139# function to save off binaries after a full build for later
140# restoration
141save_binaries() {
142	# save off list of binaries
143	echo "\n==== Saving binaries from build at `date` ====\n" | \
144	    tee -a $mail_msg_file >> $LOGFILE
145	rm -f ${BINARCHIVE}
146	cd ${CODEMGR_WS}
147	filelist ${CODEMGR_WS} '^preserve:' >> $LOGFILE
148	filelist ${CODEMGR_WS} '^preserve:' | \
149	    cpio -ocB 2>/dev/null | compress \
150	    > ${BINARCHIVE}
151}
152
153# delete files
154# usage: hybridize_files DESTDIR MAKE_TARGET
155hybridize_files() {
156	DEST=$1
157	MAKETARG=$2
158
159	echo "\n==== Hybridizing files at `date` ====\n" | \
160	    tee -a $mail_msg_file >> $LOGFILE
161	for i in `filelist ${DEST} '^delete:'`
162	do
163		echo "removing ${i}." | tee -a $mail_msg_file >> $LOGFILE
164		rm -rf "${i}"
165	done
166	for i in `filelist ${DEST} '^hybridize:' `
167	do
168		echo "hybridizing ${i}." | tee -a $mail_msg_file >> $LOGFILE
169		rm -f ${i}+
170		sed -e "/^# HYBRID DELETE START/,/^# HYBRID DELETE END/d" \
171		    < ${i} > ${i}+
172		mv ${i}+ ${i}
173	done
174}
175
176# restore binaries into the proper source tree.
177# usage: restore_binaries DESTDIR MAKE_TARGET
178restore_binaries() {
179	DEST=$1
180	MAKETARG=$2
181
182	echo "\n==== Restoring binaries to ${MAKETARG} at `date` ====\n" | \
183	    tee -a $mail_msg_file >> $LOGFILE
184	cd ${DEST}
185	zcat ${BINARCHIVE} | \
186	    cpio -idmucvB 2>/dev/null | tee -a $mail_msg_file >> ${LOGFILE}
187}
188
189# rename files we save binaries of
190# usage: rename_files DESTDIR MAKE_TARGET
191rename_files() {
192	DEST=$1
193	MAKETARG=$2
194	echo "\n==== Renaming source files in ${MAKETARG} at `date` ====\n" | \
195	    tee -a $mail_msg_file >> $LOGFILE
196	for i in `filelist ${DEST} '^rename:'`
197	do
198		echo ${i} | tee -a $mail_msg_file >> ${LOGFILE}
199		rm -f ${i}.export
200		mv ${i} ${i}.export
201	done
202}
203
204#
205# Copy some or all of the source tree.
206# usage: copy_source CODEMGR_WS DESTDIR LABEL SRCROOT
207#
208copy_source() {
209	WS=$1
210	DEST=$2
211	label=$3
212	srcroot=$4
213
214	echo "\n==== Creating ${DEST} source from ${WS} ($label) ====\n" | \
215	    tee -a $mail_msg_file >> $LOGFILE
216
217	echo "cleaning out ${DEST}." >> $LOGFILE
218	rm -rf "${DEST}" >> $LOGFILE 2>&1
219
220	mkdir -p ${DEST}
221	cd ${WS}
222
223	echo "creating ${DEST}." >> $LOGFILE
224	find $srcroot -name 's\.*' -a -type f -print | \
225	    sed -e 's,SCCS\/s.,,' | \
226	    grep -v '/\.del-*' | \
227	    cpio -pd ${DEST} >>$LOGFILE 2>&1
228}
229
230#
231# function to create (but not build) the export/crypt source tree.
232# usage: set_up_source_build CODEMGR_WS DESTDIR MAKE_TARGET
233# Sets SRC to the modified source tree, for use by the caller when it
234# builds the tree.
235#
236set_up_source_build() {
237	WS=$1
238	DEST=$2
239	MAKETARG=$3
240
241	copy_source $WS $DEST $MAKETARG usr
242	SRC=${DEST}/usr/src
243
244	cd $SRC
245	rm -f ${MAKETARG}.out
246	echo "making ${MAKETARG} in ${SRC}." >> $LOGFILE
247	/bin/time $MAKE -e ${MAKETARG} 2>&1 | \
248	    tee -a $SRC/${MAKETARG}.out >> $LOGFILE
249	echo "\n==== ${MAKETARG} build errors ====\n" >> $mail_msg_file
250	egrep ":" $SRC/${MAKETARG}.out | \
251		egrep -e "(^${MAKE}:|[ 	]error[: 	\n])" | \
252		egrep -v "Ignoring unknown host" | \
253		egrep -v "warning" >> $mail_msg_file
254
255	echo "clearing state files." >> $LOGFILE
256	find . -name '.make*' -exec rm -f {} \;
257
258	cd ${DEST}
259	if [ "${MAKETARG}" = "CRYPT_SRC" ]; then
260		rm -f ${CODEMGR_WS}/crypt_files.cpio.Z
261		echo "\n==== xmod/cry_files that don't exist ====\n" | \
262		    tee -a $mail_msg_file >> $LOGFILE
263		CRYPT_FILES=${WS}/usr/src/xmod/cry_files
264		for i in `cat ${CRYPT_FILES}`
265		do
266			# make sure the files exist
267			if [ -f "$i" ]; then
268				continue
269			fi
270			if [ -d "$i" ]; then
271				continue
272			fi
273			echo "$i" | tee -a $mail_msg_file >> $LOGFILE
274		done
275		find `cat ${CRYPT_FILES}` -print 2>/dev/null | \
276		    cpio -ocB 2>/dev/null | \
277		    compress > ${CODEMGR_WS}/crypt_files.cpio.Z
278	fi
279
280	if [ "${MAKETARG}" = "EXPORT_SRC" ]; then
281		# rename first, since we might restore a file
282		# of the same name (mapfiles)
283		rename_files ${EXPORT_SRC} EXPORT_SRC
284		if [ "$SH_FLAG" = "y" ]; then
285			hybridize_files ${EXPORT_SRC} EXPORT_SRC
286		fi
287	fi
288
289	# save the cleartext
290	echo "\n==== Creating ${MAKETARG}.cpio.Z ====\n" | \
291	    tee -a $mail_msg_file >> $LOGFILE
292	cd ${DEST}
293	rm -f ${MAKETARG}.cpio.Z
294	find usr -depth -print | \
295	    grep -v usr/src/${MAKETARG}.out | \
296	    cpio -ocB 2>/dev/null | \
297	    compress > ${CODEMGR_WS}/${MAKETARG}.cpio.Z
298	if [ "${MAKETARG}" = "EXPORT_SRC" ]; then
299		restore_binaries ${EXPORT_SRC} EXPORT_SRC
300	fi
301
302	if [ "${MAKETARG}" = "CRYPT_SRC" ]; then
303		restore_binaries ${CRYPT_SRC} CRYPT_SRC
304	fi
305
306}
307
308# function to do the build.
309# usage: build LABEL SUFFIX
310
311build() {
312	LABEL=$1
313	SUFFIX=$2
314	INSTALLOG=install${SUFFIX}-${MACH}
315	NOISE=noise${SUFFIX}-${MACH}
316	CPIODIR=${CPIODIR_ORIG}${SUFFIX}
317	PKGARCHIVE=${PKGARCHIVE_ORIG}${SUFFIX}
318	if [ "$SPARC_RM_PKGARCHIVE_ORIG" ]; then
319		SPARC_RM_PKGARCHIVE=${SPARC_RM_PKGARCHIVE_ORIG}${SUFFIX}
320	fi
321
322	this_build_ok=y
323	#
324	#	Build OS-Networking source
325	#
326	echo "\n==== Building OS-Net source at `date` ($LABEL) ====\n" \
327		>> $LOGFILE
328
329	rm -f $SRC/${INSTALLOG}.out
330	cd $SRC
331	/bin/time $MAKE -e install 2>&1 | \
332	    tee -a $SRC/${INSTALLOG}.out >> $LOGFILE
333
334	echo "\n==== SCCS Noise ($LABEL) ====\n" >> $mail_msg_file
335
336	egrep 'sccs(check|  get)' $SRC/${INSTALLOG}.out >> $mail_msg_file
337
338	echo "\n==== Build errors ($LABEL) ====\n" >> $mail_msg_file
339	egrep ":" $SRC/${INSTALLOG}.out |
340		egrep -e "(^${MAKE}:|[ 	]error[: 	\n])" | \
341		egrep -v "Ignoring unknown host" | \
342		egrep -v "cc .* -o error " | \
343		egrep -v "warning" >> $mail_msg_file
344	if [ "$?" = "0" ]; then
345		build_ok=n
346		this_build_ok=n
347	fi
348	grep "bootblock image is .* bytes too big" $SRC/${INSTALLOG}.out \
349		>> $mail_msg_file
350	if [ "$?" = "0" ]; then
351		build_ok=n
352		this_build_ok=n
353	fi
354
355	if [ "$W_FLAG" = "n" ]; then
356		echo "\n==== Build warnings ($LABEL) ====\n" >>$mail_msg_file
357		egrep -i warning: $SRC/${INSTALLOG}.out \
358			| egrep -v '^tic:' \
359			| egrep -v "symbol \`timezone' has differing types:" \
360		        | egrep -v "parameter <PSTAMP> set to" \
361			| egrep -v "Ignoring unknown host" \
362			| egrep -v "redefining segment flags attribute for" \
363			>> $mail_msg_file
364	fi
365
366	echo "\n==== Ended OS-Net source build at `date` ($LABEL) ====\n" \
367		>> $LOGFILE
368
369	echo "\n==== Elapsed build time ($LABEL) ====\n" >>$mail_msg_file
370	tail -3  $SRC/${INSTALLOG}.out >>$mail_msg_file
371
372	if [ "$i_FLAG" = "n" -a "$W_FLAG" = "n" ]; then
373		rm -f $SRC/${NOISE}.ref
374		if [ -f $SRC/${NOISE}.out ]; then
375			mv $SRC/${NOISE}.out $SRC/${NOISE}.ref
376		fi
377		grep : $SRC/${INSTALLOG}.out \
378			| egrep -v '^/' \
379			| egrep -v '^(Start|Finish|real|user|sys|./bld_awk)' \
380			| egrep -v '^tic:' \
381			| egrep -v '^mcs' \
382			| egrep -v '^LD_LIBRARY_PATH=' \
383			| egrep -v 'ar: creating' \
384			| egrep -v 'ar: writing' \
385			| egrep -v 'conflicts:' \
386			| egrep -v ':saved created' \
387			| egrep -v '^stty.*c:' \
388			| egrep -v '^mfgname.c:' \
389			| egrep -v '^uname-i.c:' \
390			| egrep -v '^volumes.c:' \
391			| egrep -v '^lint library construction:' \
392			| egrep -v 'tsort: INFORM:' \
393			| egrep -v 'stripalign:' \
394			| egrep -v 'chars, width' \
395			| egrep -v "symbol \`timezone' has differing types:" \
396			| egrep -v 'PSTAMP' \
397			| egrep -v '|%WHOANDWHERE%|' \
398			| egrep -v '^Manifying' \
399			| egrep -v 'Ignoring unknown host' \
400			| egrep -v 'Processing method:' \
401			| egrep -v '^Writing' \
402			| egrep -v 'spellin1:' \
403			| egrep -v '^adding:' \
404			| egrep -v "^echo 'msgid" \
405			| egrep -v '^echo ' \
406			| egrep -v '\.c:$' \
407			| egrep -v '^Adding file:' \
408			| egrep -v 'CLASSPATH=' \
409			| egrep -v '\/var\/mail\/:saved' \
410			| egrep -v -- '-DUTS_VERSION=' \
411			| egrep -v '^Running Mkbootstrap' \
412			| egrep -v '^Applet length read:' \
413			| egrep -v 'bytes written:' \
414			| egrep -v '^File:SolarisAuthApplet.bin' \
415			| egrep -v -i 'jibversion' \
416			| egrep -v '^Output size:' \
417			| egrep -v '^Solo size statistics:' \
418			| egrep -v '^Using ROM API Version' \
419			| egrep -v '^Zero Signature length:' \
420			| egrep -v '^Note \(probably harmless\):' \
421			| egrep -v '::' \
422			| egrep -v -- '-xcache' \
423			| egrep -v '^\+' \
424			| egrep -v '^cc1: note: -fwritable-strings' \
425			| egrep -v 'svccfg-native -s svc:/' \
426			| sort | uniq >$SRC/${NOISE}.out
427		if [ ! -f $SRC/${NOISE}.ref ]; then
428			cp $SRC/${NOISE}.out $SRC/${NOISE}.ref
429		fi
430		echo "\n==== Build noise differences ($LABEL) ====\n" \
431			>>$mail_msg_file
432		diff $SRC/${NOISE}.ref $SRC/${NOISE}.out >>$mail_msg_file
433	fi
434
435	#
436	#	Re-sign selected binaries using signing server
437	#	(gatekeeper builds only)
438	#
439	if [ -n "$CODESIGN_USER" ]; then
440		echo "\n==== Signing proto area at `date` ====\n" >> $LOGFILE
441		signing_file="${TMPDIR}/signing"
442		rm -f ${signing_file}
443		export CODESIGN_USER
444		signproto $SRC/tools/codesign/creds 2>&1 | \
445			tee -a ${signing_file} >> $LOGFILE
446		echo "\n==== Finished signing proto area at `date` ====\n" \
447		    >> $LOGFILE
448		echo "\n==== Crypto module signing errors ($LABEL) ====\n" \
449		    >> $mail_msg_file
450		egrep 'WARNING|ERROR' ${signing_file} >> $mail_msg_file
451	fi
452
453	#
454	#	Create cpio archives for preintegration testing (PIT)
455	#
456	if [ "$a_FLAG" = "y" -a "$this_build_ok" = "y" ]; then
457		echo "\n==== Creating $LABEL cpio archives at `date` ====\n" \
458			>> $LOGFILE
459		makebfu_file="${TMPDIR}/makebfu"
460		rm -f ${makebfu_file}
461		makebfu 2>&1 | \
462			tee -a ${makebfu_file} >> $LOGFILE
463		echo "\n==== cpio archives build errors ($LABEL) ====\n" \
464			>> $mail_msg_file
465		grep -v "^Creating .* archive:" ${makebfu_file} | \
466			grep -v "^Making" | \
467			grep -v "^$" | \
468			sort | uniq >> $mail_msg_file
469		rm -f ${makebfu_file}
470		# hack for test folks
471		if [ -z "`echo $PARENT_WS|egrep '^\/ws\/'`" ]; then
472			X=/net/`uname -n`${CPIODIR}
473		else
474			X=${CPIODIR}
475		fi
476		echo "Archive_directory: ${X}" >${TMPDIR}/f
477		cp ${TMPDIR}/f ${CPIODIR}/../../.${MACH}_wgtrun
478		rm -f ${TMPDIR}/f
479
480	else
481		echo "\n==== Not creating $LABEL cpio archives ====\n" \
482			>> $LOGFILE
483	fi
484
485	#
486	#	Building Packages
487	#
488	if [ "$p_FLAG" = "y" -a "$this_build_ok" = "y" ]; then
489		echo "\n==== Creating $LABEL packages at `date` ====\n" \
490			>> $LOGFILE
491		rm -f $SRC/pkgdefs/${INSTALLOG}.out
492		echo "Clearing out $PKGARCHIVE ..." >> $LOGFILE
493		rm -rf $PKGARCHIVE
494		mkdir -p $PKGARCHIVE
495
496		#
497		# Optional build of sparc realmode on i386
498		#
499		if [ "$MACH" = "i386" ] && [ "${SPARC_RM_PKGARCHIVE}" ]; then
500			echo "Clearing out ${SPARC_RM_PKGARCHIVE} ..." \
501				>> $LOGFILE
502			rm -rf ${SPARC_RM_PKGARCHIVE}
503			mkdir -p ${SPARC_RM_PKGARCHIVE}
504		fi
505
506		cd $SRC/pkgdefs
507		$MAKE -e install 2>&1 | \
508			tee -a $SRC/pkgdefs/${INSTALLOG}.out >> $LOGFILE
509		echo "\n==== Package build errors ($LABEL) ====\n" \
510			>> $mail_msg_file
511		egrep "${MAKE}|ERROR|WARNING" $SRC/pkgdefs/${INSTALLOG}.out | \
512			grep ':' | \
513			grep -v PSTAMP | \
514			egrep -v "Ignoring unknown host" \
515			>> $mail_msg_file
516	else
517		echo "\n==== Not creating $LABEL packages ====\n" >> $LOGFILE
518	fi
519}
520
521# Usage: dolint /dir y|n
522# Arg. 2 is a flag to turn on/off the lint diff output
523dolint() {
524	if [ ! -d "$1" ]; then
525		echo "dolint error: $1 is not a directory"
526		exit 1
527	fi
528
529	if [ "$2" != "y" -a "$2" != "n" ]; then
530		echo "dolint internal error: $2 should be 'y' or 'n'"
531		exit 1
532	fi
533
534	lintdir=$1
535	dodiff=$2
536	base=`basename $lintdir`
537	LINTOUT=$lintdir/lint-${MACH}.out
538	LINTNOISE=$lintdir/lint-noise-${MACH}
539
540	export INTERNAL_RELEASE_BUILD ; INTERNAL_RELEASE_BUILD=
541	unset RELEASE_BUILD
542	unset EXTRA_OPTIONS
543	unset EXTRA_CFLAGS
544
545	#
546	#	'$MAKE lint' in $lintdir
547	#
548	echo "\n==== Begin '$MAKE lint' of $base at `date` ====\n" >> $LOGFILE
549
550	# remove old lint.out
551	rm -f $lintdir/lint.out $lintdir/lint-noise.out
552	if [ -f $lintdir/lint-noise.ref ]; then
553		mv $lintdir/lint-noise.ref ${LINTNOISE}.ref
554	fi
555
556	rm -f $LINTOUT
557	cd $lintdir
558	#
559	# Remove all .ln files to ensure a full reference file
560	#
561	rm -f Nothing_to_remove \
562	    `find . -name SCCS -prune -o -type f -name '*.ln' -print `
563
564	/bin/time $MAKE -ek lint 2>&1 | \
565	    tee -a $LINTOUT >> $LOGFILE
566	echo "\n==== '$MAKE lint' of $base ERRORS ====\n" >> $mail_msg_file
567	grep "$MAKE:" $LINTOUT |
568		egrep -v "Ignoring unknown host" \
569		>> $mail_msg_file
570
571	echo "\n==== Ended '$MAKE lint' of $base at `date` ====\n" >> $LOGFILE
572
573	echo "\n==== Elapsed time of '$MAKE lint' of $base ====\n" \
574		>>$mail_msg_file
575	tail -3  $LINTOUT >>$mail_msg_file
576
577	rm -f ${LINTNOISE}.ref
578	if [ -f ${LINTNOISE}.out ]; then
579		mv ${LINTNOISE}.out ${LINTNOISE}.ref
580	fi
581        grep : $LINTOUT | \
582		egrep -v '^(real|user|sys)' |
583		egrep -v '(library construction)' | \
584		egrep -v ': global crosschecks' | \
585		egrep -v 'Ignoring unknown host' | \
586		egrep -v '\.c:$' | \
587		sort | uniq > ${LINTNOISE}.out
588	if [ ! -f ${LINTNOISE}.ref ]; then
589		cp ${LINTNOISE}.out ${LINTNOISE}.ref
590	fi
591	if [ "$dodiff" != "n" ]; then
592		echo "\n==== lint warnings $base ====\n" \
593			>>$mail_msg_file
594		# should be none, though there are a few that were filtered out
595		# above
596		egrep -i '(warning|lint):' ${LINTNOISE}.out \
597			| sort | uniq >> $mail_msg_file
598		echo "\n==== lint noise differences $base ====\n" \
599			>> $mail_msg_file
600		diff ${LINTNOISE}.ref ${LINTNOISE}.out \
601			>> $mail_msg_file
602	fi
603}
604
605# Install proto area from IHV build
606
607copy_ihv_proto() {
608
609	echo "\n==== Installing IHV proto area ====\n" \
610		>> $LOGFILE
611	if [ -d "$IA32_IHV_ROOT" ]; then
612		if [ ! -d "$ROOT" ]; then
613			echo "mkdir -p $ROOT" >> $LOGFILE
614			mkdir -p $ROOT
615		fi
616		echo "copying $IA32_IHV_ROOT to $ROOT\n" >> $LOGFILE
617		cd $IA32_IHV_ROOT
618		tar -cf - . | (cd $ROOT; umask 0; tar xpf - ) 2>&1 >> $LOGFILE
619	else
620		echo "$IA32_IHV_ROOT: not found" >> $LOGFILE
621	fi
622}
623
624# Install IHV packages in PKGARCHIVE
625# usage: copy_ihv_pkgs LABEL SUFFIX
626copy_ihv_pkgs() {
627	LABEL=$1
628	SUFFIX=$2
629	# always use non-DEBUG IHV packages
630	IA32_IHV_PKGS=${IA32_IHV_PKGS_ORIG}-nd
631	PKGARCHIVE=${PKGARCHIVE_ORIG}${SUFFIX}
632
633	echo "\n==== Installing IHV packages from $IA32_IHV_PKGS ($LABEL) ====\n" \
634		>> $LOGFILE
635	if [ -d "$IA32_IHV_PKGS" ]; then
636		cd $IA32_IHV_PKGS
637		tar -cf - * | \
638		   (cd $PKGARCHIVE; umask 0; tar xpf - ) 2>&1 >> $LOGFILE
639	else
640		echo "$IA32_IHV_PKGS: not found" >> $LOGFILE
641	fi
642
643	echo "\n==== Installing IHV packages from $IA32_IHV_BINARY_PKGS ($LABEL) ====\n" \
644		>> $LOGFILE
645	if [ -d "$IA32_IHV_BINARY_PKGS" ]; then
646		cd $IA32_IHV_BINARY_PKGS
647		tar -cf - * | \
648		    (cd $PKGARCHIVE; umask 0; tar xpf - ) 2>&1 >> $LOGFILE
649	else
650		echo "$IA32_IHV_BINARY_PKGS: not found" >> $LOGFILE
651	fi
652}
653
654# usage: build_tools DESTROOT
655build_tools() {
656	DESTROOT=$1
657
658	INSTALLOG=install-${MACH}
659
660	echo "\n==== Building tools at `date` ====\n" \
661		>> $LOGFILE
662
663	rm -f ${TOOLS}/${INSTALLOG}.out
664	cd ${TOOLS}
665	/bin/time $MAKE ROOT=${DESTROOT} -e install 2>&1 | \
666	    tee -a ${TOOLS}/${INSTALLOG}.out >> $LOGFILE
667
668	echo "\n==== Tools build errors ====\n" >> $mail_msg_file
669
670	egrep ":" ${TOOLS}/${INSTALLOG}.out |
671		egrep -e "(${MAKE}:|[ 	]error[: 	\n])" | \
672		egrep -v "Ignoring unknown host" | \
673		egrep -v warning >> $mail_msg_file
674	if [ "$?" != "0" ]; then
675		STABS=${DESTROOT}/opt/onbld/bin/${MACH}/stabs
676		export STABS
677		CTFSTABS=${DESTROOT}/opt/onbld/bin/${MACH}/ctfstabs
678		export CTFSTABS
679		GENOFFSETS=${DESTROOT}/opt/onbld/bin/genoffsets
680		export GENOFFSETS
681
682		CTFCONVERT=${DESTROOT}/opt/onbld/bin/${MACH}/ctfconvert
683		export CTFCONVERT
684		CTFMERGE=${DESTROOT}/opt/onbld/bin/${MACH}/ctfmerge
685		export CTFMERGE
686
687		CTFCVTPTBL=${DESTROOT}/opt/onbld/bin/ctfcvtptbl
688		export CTFCVTPTBL
689		CTFFINDMOD=${DESTROOT}/opt/onbld/bin/ctffindmod
690		export CTFFINDMOD
691
692		if [ "$VERIFY_ELFSIGN" = "y" ]; then
693			ELFSIGN=${DESTROOT}/opt/onbld/bin/elfsigncmp
694		else
695			ELFSIGN=${DESTROOT}/opt/onbld/bin/${MACH}/elfsign
696		fi
697		export ELFSIGN
698
699		PATH="${DESTROOT}/opt/onbld/bin/${MACH}:${PATH}"
700		PATH="${DESTROOT}/opt/onbld/bin:${PATH}"
701		export PATH
702
703		echo "\n==== New environment settings. ====\n" >> $LOGFILE
704		echo "STABS=${STABS}" >> $LOGFILE
705		echo "CTFSTABS=${CTFSTABS}" >> $LOGFILE
706		echo "CTFCONVERT=${CTFCONVERT}" >> $LOGFILE
707		echo "CTFMERGE=${CTFMERGE}" >> $LOGFILE
708		echo "CTFCVTPTBL=${CTFCVTPTBL}" >> $LOGFILE
709		echo "CTFFINDMOD=${CTFFINDMOD}" >> $LOGFILE
710		echo "ELFSIGN=${ELFSIGN}" >> $LOGFILE
711		echo "PATH=${PATH}" >> $LOGFILE
712	fi
713}
714
715staffer() {
716	if [ $ISUSER -ne 0 ]; then
717		"$@"
718	else
719		arg="\"$1\""
720		shift
721		for i
722		do
723			arg="$arg \"$i\""
724		done
725		eval su $STAFFER -c \'$arg\'
726	fi
727}
728
729#
730# Verify that the closed tree is present if it needs to be.
731# Sets CLOSED_IS_PRESENT for future use.
732#
733check_closed_tree() {
734	if [ -z "$CLOSED_IS_PRESENT" ]; then
735		if [ -d $SRC/../closed ]; then
736			CLOSED_IS_PRESENT="yes"
737		else
738			CLOSED_IS_PRESENT="no"
739		fi
740		export CLOSED_IS_PRESENT
741	fi
742	if [[ "$CLOSED_IS_PRESENT" = no && ! -d "$ON_CLOSED_BINS" ]]; then
743		#
744		# If it's an old (pre-split) tree or an empty
745		# workspace, don't complain.
746		#
747		if grep -s CLOSED_BUILD $SRC/Makefile.master > /dev/null; then
748			echo "If the closed sources are not present," \
749			    "ON_CLOSED_BINS"
750			echo "must point to the closed binaries tree."
751			exit 1
752		fi
753	fi
754}
755
756obsolete_build() {
757    	echo "WARNING: Obsolete $1 build requested; request will be ignored"
758}
759
760
761MACH=`uname -p`
762
763if [ "$OPTHOME" = "" ]; then
764	OPTHOME=/opt
765	export OPTHOME
766fi
767if [ "$TEAMWARE" = "" ]; then
768	TEAMWARE=$OPTHOME/teamware
769	export TEAMWARE
770fi
771
772USAGE='Usage: nightly [-in] [-V VERS ] [ -S E|D|H|O ] <env_file>
773
774Where:
775	-i	Fast incremental options (no clobber, lint, check)
776	-n      Do not do a bringover
777	-V VERS set the build version string to VERS
778	-S	Build a variant of the source product
779		E - build exportable source
780		D - build domestic source (exportable + crypt)
781		H - build hybrid source (binaries + deleted source)
782		O - build (only) open source
783
784	<env_file>  file in Bourne shell syntax that sets and exports
785	variables that configure the operation of this script and many of
786	the scripts this one calls. If <env_file> does not exist,
787	it will be looked for in $OPTHOME/onbld/env.
788
789non-DEBUG is the default build type. Build options can be set in the
790NIGHTLY_OPTIONS variable in the <env_file> as follows:
791
792	-A	check for ABI differences in .so files
793	-C	check for cstyle/hdrchk errors
794	-D	do a build with DEBUG on
795	-F	do _not_ do a non-DEBUG build
796	-G	gate keeper default group of options (-au)
797	-I	integration engineer default group of options (-ampu)
798	-M	do not run pmodes (safe file permission checker)
799	-N	do not run protocmp
800	-R	default group of options for building a release (-mp)
801	-U	update proto area in the parent
802	-V VERS set the build version string to VERS
803	-X	copy x86 IHV proto area
804	-a	create cpio archives
805	-f	find unreferenced files
806	-i	do an incremental build (no "make clobber")
807	-l	do "make lint" in $LINTDIRS (default: $SRC y)
808	-m	send mail to $MAILTO at end of build
809	-n      do not do a bringover
810	-o	build using root privileges to set OWNER/GROUP (old style)
811	-p	create packages
812	-r	check ELF runtime attributes in the proto area
813	-t	build and use the tools in $SRC/tools
814	-u	update proto_list_$MACH and friends in the parent workspace;
815		when used with -f, also build an unrefmaster.out in the parent
816	-w	report on differences between previous and current proto areas
817	-z	compress cpio archives with gzip
818	-W	Do not report warnings (freeware gate ONLY)
819	-S	Build a variant of the source product
820		E - build exportable source
821		D - build domestic source (exportable + crypt)
822		H - build hybrid source (binaries + deleted source)
823		O - build (only) open source
824'
825#
826#	-x	less public handling of xmod source for the source product
827#
828#	A log file will be generated under the name $LOGFILE
829#	for partially completed build and log.`date '+%F'`
830#	in the same directory for fully completed builds.
831#
832
833# default values for low-level FLAGS; G I R are group FLAGS
834A_FLAG=n
835a_FLAG=n
836C_FLAG=n
837D_FLAG=n
838F_FLAG=n
839f_FLAG=n
840i_FLAG=n; i_CMD_LINE_FLAG=n
841l_FLAG=n
842M_FLAG=n
843m_FLAG=n
844N_FLAG=n
845n_FLAG=n
846o_FLAG=n
847P_FLAG=n
848p_FLAG=n
849r_FLAG=n
850T_FLAG=n
851t_FLAG=n
852U_FLAG=n
853u_FLAG=n
854V_FLAG=n
855W_FLAG=n
856w_FLAG=n
857X_FLAG=n
858z_FLAG=n
859SD_FLAG=n
860SE_FLAG=n
861SH_FLAG=n
862SO_FLAG=n
863#
864XMOD_OPT=
865#
866build_ok=y
867
868is_source_build() {
869	[ "$SE_FLAG" = "y" -o "$SD_FLAG" = "y" -o \
870	    "$SH_FLAG" = "y" -o "$SO_FLAG" = "y" ]
871	return $?
872}
873
874#
875# examine arguments
876#
877
878#
879# single function for setting -S flag and doing error checking.
880# usage: set_S_flag <type>
881# where <type> is the source build type ("E", "D", ...).
882#
883set_S_flag() {
884	if is_source_build; then
885		echo "Can only build one source variant at a time."
886		exit 1
887	fi
888	if [ "$1" = "E" ]; then
889		SE_FLAG=y
890	elif [ "$1" = "D" ]; then
891		SD_FLAG=y
892	elif [ "$1" = "H" ]; then
893		SH_FLAG=y
894	elif [ "$1" = "O" ]; then
895		SO_FLAG=y
896	else
897		echo "$USAGE"
898		exit 1
899	fi
900}
901
902OPTIND=1
903while getopts inS:tV: FLAG
904do
905	case $FLAG in
906	  i )	i_FLAG=y; i_CMD_LINE_FLAG=y
907		;;
908	  n )	n_FLAG=y
909		;;
910	  S )
911		set_S_flag $OPTARG
912		;;
913	  t )	t_FLAG=y
914		;;
915	  V )	V_FLAG=y
916		V_ARG="$OPTARG"
917		;;
918	 \? )	echo "$USAGE"
919		exit 1
920		;;
921	esac
922done
923
924# correct argument count after options
925shift `expr $OPTIND - 1`
926
927# test that the path to the environment-setting file was given
928if [ $# -ne 1 ]; then
929	echo "$USAGE"
930	exit 1
931fi
932
933# check if user is running nightly as root
934# ISUSER is set non-zero if an ordinary user runs nightly, or is zero
935# when root invokes nightly.
936/usr/bin/id | grep '^uid=0(' >/dev/null 2>&1
937ISUSER=$?;	export ISUSER
938
939#
940# force locale to C
941LC_COLLATE=C;	export LC_COLLATE
942LC_CTYPE=C;	export LC_CTYPE
943LC_MESSAGES=C;	export LC_MESSAGES
944LC_MONETARY=C;	export LC_MONETARY
945LC_NUMERIC=C;	export LC_NUMERIC
946LC_TIME=C;	export LC_TIME
947
948# clear environment variables we know to be bad for the build
949unset LD_OPTIONS
950unset LD_AUDIT		LD_AUDIT_32		LD_AUDIT_64
951unset LD_BIND_NOW	LD_BIND_NOW_32		LD_BIND_NOW_64
952unset LD_BREADTH	LD_BREADTH_32		LD_BREADTH_64
953unset LD_CONFIG		LD_CONFIG_32		LD_CONFIG_64
954unset LD_DEBUG		LD_DEBUG_32		LD_DEBUG_64
955unset LD_DEMANGLE	LD_DEMANGLE_32		LD_DEMANGLE_64
956unset LD_FLAGS		LD_FLAGS_32		LD_FLAGS_64
957unset LD_LIBRARY_PATH	LD_LIBRARY_PATH_32	LD_LIBRARY_PATH_64
958unset LD_LOADFLTR	LD_LOADFLTR_32		LD_LOADFLTR_64
959unset LD_NOAUDIT	LD_NOAUDIT_32		LD_NOAUDIT_64
960unset LD_NOAUXFLTR	LD_NOAUXFLTR_32		LD_NOAUXFLTR_64
961unset LD_NOCONFIG	LD_NOCONFIG_32		LD_NOCONFIG_64
962unset LD_NODIRCONFIG	LD_NODIRCONFIG_32	LD_NODIRCONFIG_64
963unset LD_NODIRECT	LD_NODIRECT_32		LD_NODIRECT_64
964unset LD_NOLAZYLOAD	LD_NOLAZYLOAD_32	LD_NOLAZYLOAD_64
965unset LD_NOOBJALTER	LD_NOOBJALTER_32	LD_NOOBJALTER_64
966unset LD_NOVERSION	LD_NOVERSION_32		LD_NOVERSION_64
967unset LD_ORIGIN		LD_ORIGIN_32		LD_ORIGIN_64
968unset LD_PRELOAD	LD_PRELOAD_32		LD_PRELOAD_64
969unset LD_PROFILE	LD_PROFILE_32		LD_PROFILE_64
970
971unset CONFIG
972unset GROUP
973unset OWNER
974unset REMOTE
975unset ENV
976unset ARCH
977unset CLASSPATH
978unset NAME
979
980#
981#	Setup environmental variables
982#
983if [ -f $1 ]; then
984	if [[ $1 = */* ]]; then
985		. $1
986	else
987		. ./$1
988	fi
989else
990	if [ -f $OPTHOME/onbld/env/$1 ]; then
991		. $OPTHOME/onbld/env/$1
992	else
993		echo "Cannot find env file as either $1 or $OPTHOME/onbld/env/$1"
994		exit 1
995	fi
996fi
997
998# contents of stdenv.sh inserted after next line:
999# STDENV_START
1000# STDENV_END
1001
1002#
1003# place ourselves in a new task, respecting BUILD_PROJECT if set.
1004#
1005if [ -z "$BUILD_PROJECT" ]; then
1006	/usr/bin/newtask -c $$
1007else
1008	/usr/bin/newtask -c $$ -p $BUILD_PROJECT
1009fi
1010
1011ps -o taskid= -p $$ | read build_taskid
1012ps -o project= -p $$ | read build_project
1013
1014#
1015# See if NIGHTLY_OPTIONS is set
1016#
1017if [ "$NIGHTLY_OPTIONS" = "" ]; then
1018	NIGHTLY_OPTIONS="-aBm"
1019fi
1020
1021#
1022# If BRINGOVER_WS was not specified, let it default to CLONE_WS
1023#
1024if [ "$BRINGOVER_WS" = "" ]; then
1025	BRINGOVER_WS=$CLONE_WS
1026fi
1027
1028#
1029# If BRINGOVER_FILES was not specified, default to usr
1030#
1031if [ "$BRINGOVER_FILES" = "" ]; then
1032	BRINGOVER_FILES="usr"
1033fi
1034
1035#
1036# If the closed sources are not present, the closed binaries must be
1037# present for the build to succeed.  If there's no pointer to the
1038# closed binaries, flag that now, rather than forcing the user to wait
1039# a couple hours (or more) to find out.
1040#
1041orig_closed_is_present="$CLOSED_IS_PRESENT"
1042check_closed_tree
1043
1044#
1045# Note: changes to the option letters here should also be applied to the
1046#	bldenv script.  `d' is listed for backward compatibility.
1047#
1048NIGHTLY_OPTIONS=-${NIGHTLY_OPTIONS#-}
1049OPTIND=1
1050while getopts AaBCDdFfGIilMmNnoPpRrS:TtUuWwXxz FLAG $NIGHTLY_OPTIONS
1051do
1052	case $FLAG in
1053	  A )	A_FLAG=y
1054		;;
1055	  a )	a_FLAG=y
1056		;;
1057	  B )	D_FLAG=y
1058		;; # old version of D
1059	  C )	C_FLAG=y
1060		;;
1061	  D )	D_FLAG=y
1062		;;
1063	  F )	F_FLAG=y
1064		;;
1065	  f )	f_FLAG=y
1066		;;
1067	  G )	a_FLAG=y
1068		u_FLAG=y
1069		;;
1070	  I )	a_FLAG=y
1071		m_FLAG=y
1072		p_FLAG=y
1073		u_FLAG=y
1074		;;
1075	  i )	i_FLAG=y
1076		;;
1077	  l )	l_FLAG=y
1078		;;
1079	  M )	M_FLAG=y
1080		;;
1081	  m )	m_FLAG=y
1082		;;
1083	  N )	N_FLAG=y
1084		;;
1085	  n )	n_FLAG=y
1086		;;
1087	  o )	o_FLAG=y
1088		;;
1089	  P )	P_FLAG=y
1090		;; # obsolete
1091	  p )	p_FLAG=y
1092		;;
1093	  R )	m_FLAG=y
1094		p_FLAG=y
1095		;;
1096	  r )	r_FLAG=y
1097		;;
1098	  S )
1099		set_S_flag $OPTARG
1100		;;
1101	  T )	T_FLAG=y
1102		;; # obsolete
1103	  t )	t_FLAG=y
1104		;;
1105	  U )
1106		if [ -z "${PARENT_ROOT}" ]; then
1107			echo "PARENT_ROOT must be set if the U flag is" \
1108			    "present in NIGHTLY_OPTIONS."
1109			exit 1
1110		fi
1111		U_FLAG=y
1112		NIGHTLY_PARENT_ROOT=$PARENT_ROOT
1113		;;
1114	  u )	u_FLAG=y
1115		;;
1116	  W )	W_FLAG=y
1117		;;
1118
1119	  w )	w_FLAG=y
1120		;;
1121	  X )	# now that we no longer need realmode builds, just
1122		# copy IHV packages.  only meaningful on x86.
1123		if [ "$MACH" = "i386" ]; then
1124			X_FLAG=y
1125		fi
1126		;;
1127	  x )	XMOD_OPT="-x"
1128		;;
1129	  z )	z_FLAG=y
1130		;;
1131	 \? )	echo "$USAGE"
1132		exit 1
1133		;;
1134	esac
1135done
1136
1137if [ $ISUSER -ne 0 ]; then
1138	if [ "$o_FLAG" = "y" ]; then
1139		echo "Old-style build requires root permission."
1140		exit 1
1141	fi
1142
1143	# Set default value for STAFFER, if needed.
1144	if [ -z "$STAFFER" -o "$STAFFER" = "nobody" ]; then
1145		STAFFER=`/usr/xpg4/bin/id -un`
1146		export STAFFER
1147	fi
1148fi
1149
1150if [ -z "$MAILTO" -o "$MAILTO" = "nobody" ]; then
1151	MAILTO=$STAFFER
1152	export MAILTO
1153fi
1154
1155PATH="$OPTHOME/onbld/bin:$OPTHOME/onbld/bin/${MACH}:/usr/ccs/bin"
1156PATH="$PATH:$OPTHOME/SUNWspro/bin:$TEAMWARE/bin:/usr/bin:/usr/sbin:/usr/ucb"
1157PATH="$PATH:/usr/openwin/bin:/usr/sfw/bin:/opt/sfw/bin:."
1158export PATH
1159
1160# roots of source trees, both relative to $SRC and absolute.
1161relsrcdirs="."
1162if [[ -d $SRC/../closed && "$CLOSED_IS_PRESENT" != no ]]; then
1163	relsrcdirs="$relsrcdirs ../closed"
1164fi
1165abssrcdirs=""
1166for d in $relsrcdirs; do
1167	abssrcdirs="$abssrcdirs $SRC/$d"
1168done
1169
1170unset CH
1171if [ "$o_FLAG" = "y" ]; then
1172# root invoked old-style build -- make sure it works as it always has
1173# by exporting 'CH'.  The current Makefile.master doesn't use this, but
1174# the old ones still do.
1175	PROTOCMPTERSE="protocmp.terse"
1176	CH=
1177	export CH
1178else
1179	PROTOCMPTERSE="protocmp.terse -gu"
1180fi
1181POUND_SIGN="#"
1182
1183# we export POUND_SIGN to speed up the build process -- prevents evaluation of
1184# the Makefile.master definitions.
1185export o_FLAG X_FLAG POUND_SIGN
1186
1187maketype="distributed"
1188MAKE=dmake
1189# get the dmake version string alone
1190DMAKE_VERSION=$( $MAKE -v )
1191DMAKE_VERSION=${DMAKE_VERSION#*: }
1192# focus in on just the dotted version number alone
1193DMAKE_MAJOR=$( echo $DMAKE_VERSION | \
1194	sed -e 's/.*\<\([^.]*\.[^   ]*\).*$/\1/' )
1195# extract the second (or final) integer
1196DMAKE_MINOR=${DMAKE_MAJOR#*.}
1197DMAKE_MINOR=${DMAKE_MINOR%%.*}
1198# extract the first integer
1199DMAKE_MAJOR=${DMAKE_MAJOR%%.*}
1200CHECK_DMAKE=${CHECK_DMAKE:-y}
1201# x86 was built on the 12th, sparc on the 13th.
1202if [ "$CHECK_DMAKE" = "y" -a \
1203     "$DMAKE_VERSION" != "Sun Distributed Make 7.3 2003/03/12" -a \
1204     "$DMAKE_VERSION" != "Sun Distributed Make 7.3 2003/03/13" -a \( \
1205     "$DMAKE_MAJOR" -lt 7 -o \
1206     "$DMAKE_MAJOR" -eq 7 -a "$DMAKE_MINOR" -lt 4 \) ]; then
1207	if [ -z "$DMAKE_VERSION" ]; then
1208		echo "$MAKE is missing."
1209		exit 1
1210	fi
1211	echo `whence $MAKE`" version is:"
1212	echo "  ${DMAKE_VERSION}"
1213	cat <<EOF
1214
1215This version may not be safe for use.  Either set TEAMWARE to a better
1216path or (if you really want to use this version of dmake anyway), add
1217the following to your environment to disable this check:
1218
1219  CHECK_DMAKE=n
1220EOF
1221	exit 1
1222fi
1223export PATH
1224export MAKE
1225
1226if [ "${SUNWSPRO}" != "" ]; then
1227	PATH="${SUNWSPRO}/bin:$PATH"
1228	export PATH
1229fi
1230
1231hostname=`uname -n`
1232if [ ! -f $HOME/.make.machines ]; then
1233	DMAKE_MAX_JOBS=4
1234else
1235	DMAKE_MAX_JOBS="`grep $hostname $HOME/.make.machines | \
1236	    tail -1 | awk -F= '{print $ 2;}'`"
1237	if [ "$DMAKE_MAX_JOBS" = "" ]; then
1238		DMAKE_MAX_JOBS=4
1239	fi
1240fi
1241DMAKE_MODE=parallel;
1242export DMAKE_MODE
1243export DMAKE_MAX_JOBS
1244
1245if [ -z "${ROOT}" ]; then
1246	echo "ROOT must be set."
1247	exit 1
1248fi
1249
1250#
1251# if -V flag was given, reset VERSION to V_ARG
1252#
1253if [ "$V_FLAG" = "y" ]; then
1254	VERSION=$V_ARG
1255fi
1256
1257#
1258# Check for IHV root for copying ihv proto area
1259#
1260if [ "$X_FLAG" = "y" ]; then
1261        if [ "$IA32_IHV_ROOT" = "" ]; then
1262		echo "IA32_IHV_ROOT: must be set for copying ihv proto"
1263		args_ok=n
1264        fi
1265        if [ ! -d "$IA32_IHV_ROOT" ]; then
1266                echo "$IA32_IHV_ROOT: not found"
1267                args_ok=n
1268        fi
1269        if [ "$IA32_IHV_WS" = "" ]; then
1270		echo "IA32_IHV_WS: must be set for copying ihv proto"
1271		args_ok=n
1272        fi
1273        if [ ! -d "$IA32_IHV_WS" ]; then
1274                echo "$IA32_IHV_WS: not found"
1275                args_ok=n
1276        fi
1277fi
1278
1279# Append source version
1280if [ "$SE_FLAG" = "y" ]; then
1281	VERSION="${VERSION}:EXPORT"
1282fi
1283
1284if [ "$SD_FLAG" = "y" ]; then
1285	VERSION="${VERSION}:DOMESTIC"
1286fi
1287
1288if [ "$SH_FLAG" = "y" ]; then
1289	VERSION="${VERSION}:MODIFIED_SOURCE_PRODUCT"
1290fi
1291
1292if [ "$SO_FLAG" = "y" ]; then
1293	VERSION="${VERSION}:OPEN_ONLY"
1294fi
1295
1296TMPDIR="/tmp/nightly.tmpdir.$$"
1297export TMPDIR
1298rm -rf ${TMPDIR}
1299mkdir -p $TMPDIR || exit 1
1300
1301#
1302# Keep elfsign's use of pkcs11_softtoken from looking in the user home
1303# directory, which doesn't always work.   Needed until all build machines
1304# have the fix for 6271754
1305#
1306SOFTTOKEN_DIR=$TMPDIR
1307export SOFTTOKEN_DIR
1308
1309TOOLS=${SRC}/tools
1310TOOLS_PROTO=${TOOLS}/proto
1311
1312unset   CFLAGS LD_LIBRARY_PATH LDFLAGS
1313
1314# create directories that are automatically removed if the nightly script
1315# fails to start correctly
1316newdir() {
1317	dir=$1
1318	toadd=
1319	while [ ! -d $dir ]; do
1320		toadd="$dir $toadd"
1321		dir=`dirname $dir`
1322	done
1323	torm=
1324	newlist=
1325	for dir in $toadd; do
1326		if staffer mkdir $dir; then
1327			newlist="$ISUSER $dir $newlist"
1328			torm="$dir $torm"
1329		else
1330			[ -z "$torm" ] || staffer rmdir $torm
1331			return 1
1332		fi
1333	done
1334	newdirlist="$newlist $newdirlist"
1335	return 0
1336}
1337newdirlist=
1338
1339[ -d $CODEMGR_WS ] || newdir $CODEMGR_WS || exit 1
1340
1341# since this script assumes the build is from full source, it nullifies
1342# variables likely to have been set by a "ws" script; nullification
1343# confines the search space for headers and libraries to the proto area
1344# built from this immediate source.
1345ENVLDLIBS1=
1346ENVLDLIBS2=
1347ENVLDLIBS3=
1348ENVCPPFLAGS1=
1349ENVCPPFLAGS2=
1350ENVCPPFLAGS3=
1351ENVCPPFLAGS4=
1352PARENT_ROOT=
1353
1354export ENVLDLIBS3 ENVCPPFLAGS1 ENVCPPFLAGS2 ENVCPPFLAGS3 ENVCPPFLAGS4 \
1355	PARENT_ROOT
1356
1357ENVLDLIBS1="-L$ROOT/lib -L$ROOT/usr/lib"
1358ENVCPPFLAGS1="-I$ROOT/usr/include"
1359
1360export ENVLDLIBS1 ENVLDLIBS2
1361
1362CPIODIR_ORIG=$CPIODIR
1363PKGARCHIVE_ORIG=$PKGARCHIVE
1364IA32_IHV_PKGS_ORIG=$IA32_IHV_PKGS
1365if [ "$SPARC_RM_PKGARCHIVE" ]; then
1366	SPARC_RM_PKGARCHIVE_ORIG=$SPARC_RM_PKGARCHIVE
1367fi
1368
1369#
1370# Juggle the logs and optionally send mail on completion.
1371#
1372
1373logshuffle() {
1374    	LLOG="$ATLOG/log.`date '+%F'`"
1375	rm -rf $ATLOG/log.??`date '+%d'`
1376	rm -rf $ATLOG/log.????-??-`date '+%d'`
1377	if [ -f $LLOG -o -d $LLOG ]; then
1378	    	LLOG=$LLOG.$$
1379	fi
1380	mkdir $LLOG
1381	export LLOG
1382
1383	if [ "$build_ok" = "y" ]; then
1384		mv $ATLOG/proto_list_${MACH} $LLOG
1385
1386		if [ -f $TMPDIR/wsdiff.results ]; then
1387		    mv $TMPDIR/wsdiff.results $LLOG
1388		fi
1389	fi
1390
1391	#
1392	# Now that we're about to send mail, it's time to check the noise
1393	# file.  In the event that an error occurs beyond this point, it will
1394	# be recorded in the nightly.log file, but nowhere else.  This would
1395	# include only errors that cause the copying of the noise log to fail
1396	# or the mail itself not to be sent.
1397	#
1398
1399	exec >>$LOGFILE 2>&1
1400	if [ -s $build_noise_file ]; then
1401	    	echo "\n==== Nightly build noise ====\n" |
1402		    tee -a $LOGFILE >>$mail_msg_file
1403		cat $build_noise_file >>$LOGFILE
1404		cat $build_noise_file >>$mail_msg_file
1405		echo | tee -a $LOGFILE >>$mail_msg_file
1406	fi
1407	rm -f $build_noise_file
1408
1409	case "$build_ok" in
1410		y)
1411			state=Completed
1412			;;
1413		i)
1414			state=Interrupted
1415			;;
1416		*)
1417	    		state=Failed
1418			;;
1419	esac
1420	NIGHTLY_STATUS=$state
1421	export NIGHTLY_STATUS
1422
1423	if [ -n "$POST_NIGHTLY" ]; then
1424		echo "\n==== Running POST_NIGHTLY command:" \
1425		    "$POST_NIGHTLY ====\n" | tee -a $mail_msg_file >> $LOGFILE
1426		$POST_NIGHTLY $state 2>&1 | tee -a $mail_msg_file >> $LOGFILE
1427	fi
1428
1429	cat $build_time_file $mail_msg_file > ${LLOG}/mail_msg
1430	if [ "$m_FLAG" = "y" ]; then
1431	    	cat $build_time_file $mail_msg_file |
1432		    /usr/bin/mailx -s \
1433	"Nightly ${MACH} Build of `basename ${CODEMGR_WS}` ${state}." \
1434			${MAILTO}
1435	fi
1436
1437	if [ "$u_FLAG" = "y" -a "$build_ok" = "y" ]; then
1438	    	staffer cp ${LLOG}/mail_msg $PARENT_WS/usr/src/mail_msg-${MACH}
1439		staffer cp $LOGFILE $PARENT_WS/usr/src/nightly-${MACH}.log
1440	fi
1441
1442	mv $LOGFILE $LLOG
1443}
1444
1445#
1446#	Remove the locks and temporary files on any exit
1447#
1448cleanup() {
1449    	logshuffle
1450
1451	[ -z "$lockfile" ] || staffer rm -f $lockfile
1452	[ -z "$atloglockfile" ] || rm -f $atloglockfile
1453	[ -z "$ulockfile" ] || staffer rm -f $ulockfile
1454	[ -z "$Ulockfile" ] || rm -f $Ulockfile
1455
1456	set -- $newdirlist
1457	while [ $# -gt 0 ]; do
1458		ISUSER=$1 staffer rmdir $2
1459		shift; shift
1460	done
1461	rm -rf $TMPDIR
1462}
1463
1464cleanup_signal() {
1465    	build_ok=i
1466	# this will trigger cleanup(), above.
1467	exit 1
1468}
1469
1470trap cleanup 0
1471trap cleanup_signal 1 2 3 15
1472
1473#
1474# Generic lock file processing -- make sure that the lock file doesn't
1475# exist.  If it does, it should name the build host and PID.  If it
1476# doesn't, then make sure we can create it.  Clean up locks that are
1477# known to be stale (assumes host name is unique among build systems
1478# for the workspace).
1479create_lock() {
1480	lockf=$1
1481	lockvar=$2
1482	if [ -f $lockf ]; then
1483		basews=`basename $CODEMGR_WS`
1484		if read host user pid < $lockf; then
1485			if [ "$host" != "$hostname" ]; then
1486				echo "$MACH build of $basews apparently" \
1487				    "already started by $user on $host as $pid."
1488			elif kill -s 0 $pid 2>/dev/null; then
1489				echo "$MACH build of $basews already started" \
1490				    "by $user as $pid."
1491			else
1492				# stale lock; clear it out and continue
1493				rm -f $lockf
1494			fi
1495		else
1496			echo "$MACH build of $basews already running."
1497		fi
1498	fi
1499	if [ -f $lockf ]; then
1500		echo "Lock file is $lockf."
1501		exit 1
1502	fi
1503	ldir=`dirname $lockf`
1504	[ -d $ldir ] || newdir $ldir || exit 1
1505	eval $lockvar=$lockf
1506	staffer sh -c "echo $hostname $STAFFER $$ > $lockf" || exit 1
1507}
1508
1509# Ensure no other instance of this script is running on this host.
1510# LOCKNAME can be set in <env_file>, and is by default, but is not
1511# required due to the use of $ATLOG below.
1512if [ -n "$LOCKNAME" ]; then
1513	create_lock /tmp/$LOCKNAME "lockfile"
1514fi
1515#
1516# Create from one, two, or three other locks:
1517#	$ATLOG/nightly.lock
1518#		- protects against multiple builds in same workspace
1519#	$PARENT_WS/usr/src/nightly.$MACH.lock
1520#		- protects against multiple 'u' copy-backs
1521#	$NIGHTLY_PARENT_ROOT/nightly.lock
1522#		- protects against multiple 'U' copy-backs
1523#
1524# Overriding ISUSER to 1 causes the lock to be created as root if the
1525# script is run as root.  The default is to create it as $STAFFER.
1526ISUSER=1 create_lock $ATLOG/nightly.lock "atloglockfile"
1527if [ "$u_FLAG" = "y" ]; then
1528	create_lock $PARENT_WS/usr/src/nightly.$MACH.lock "ulockfile"
1529fi
1530if [ "$U_FLAG" = "y" ]; then
1531	# NIGHTLY_PARENT_ROOT is written as root if script invoked as root.
1532	ISUSER=1 create_lock $NIGHTLY_PARENT_ROOT/nightly.lock "Ulockfile"
1533fi
1534
1535# Locks have been taken, so we're doing a build and we're committed to
1536# the directories we may have created so far.
1537newdirlist=
1538
1539#
1540# Create mail_msg_file
1541#
1542mail_msg_file="${TMPDIR}/mail_msg"
1543touch $mail_msg_file
1544build_time_file="${TMPDIR}/build_time"
1545#
1546#	Move old LOGFILE aside
1547#	ATLOG directory already made by 'create_lock' above
1548#
1549if [ -f $LOGFILE ]; then
1550	mv -f $LOGFILE ${LOGFILE}-
1551fi
1552#
1553#	Build OsNet source
1554#
1555START_DATE=`date`
1556SECONDS=0
1557echo "\n==== Nightly $maketype build started:   $START_DATE ====" \
1558    | tee -a $LOGFILE > $build_time_file
1559
1560# make sure we log only to the nightly build file
1561build_noise_file="${TMPDIR}/build_noise"
1562exec </dev/null >$build_noise_file 2>&1
1563
1564echo "\n==== list of environment variables ====\n" >> $LOGFILE
1565env >> $LOGFILE
1566
1567echo "\n==== Nightly argument issues ====\n" | tee -a $mail_msg_file >> $LOGFILE
1568
1569if [ "$P_FLAG" = "y" ]; then
1570	obsolete_build GPROF | tee -a $mail_msg_file >> $LOGFILE
1571fi
1572
1573if [ "$T_FLAG" = "y" ]; then
1574	obsolete_build TRACE | tee -a $mail_msg_file >> $LOGFILE
1575fi
1576
1577if is_source_build; then
1578	if [ "$i_FLAG" = "y" -o "$i_CMD_LINE_FLAG" = "y" ]; then
1579		echo "WARNING: the -S flags do not support incremental" \
1580		    "builds; forcing clobber\n" | tee -a $mail_msg_file >> $LOGFILE
1581		i_FLAG=n
1582		i_CMD_LINE_FLAG=n
1583	fi
1584	if [ "$N_FLAG" = "n" ]; then
1585		echo "WARNING: the -S flags do not support protocmp;" \
1586		    "protocmp disabled\n" | \
1587		    tee -a $mail_msg_file >> $LOGFILE
1588		N_FLAG=y
1589	fi
1590	if [ "$l_FLAG" = "y" ]; then
1591		echo "WARNING: the -S flags do not support lint;" \
1592		    "lint disabled\n" | tee -a $mail_msg_file >> $LOGFILE
1593		l_FLAG=n
1594	fi
1595	if [ "$C_FLAG" = "y" ]; then
1596		echo "WARNING: the -S flags do not support cstyle;" \
1597		    "cstyle check disabled\n" | tee -a $mail_msg_file >> $LOGFILE
1598		C_FLAG=n
1599	fi
1600else
1601	if [ "$N_FLAG" = "y" ]; then
1602		if [ "$p_FLAG" = "y" ]; then
1603			cat <<EOF | tee -a $mail_msg_file >> $LOGFILE
1604WARNING: the p option (create packages) is set, but so is the N option (do
1605         not run protocmp); this is dangerous; you should unset the N option
1606EOF
1607		else
1608			cat <<EOF | tee -a $mail_msg_file >> $LOGFILE
1609Warning: the N option (do not run protocmp) is set; it probably shouldn't be
1610EOF
1611		fi
1612		echo "" | tee -a $mail_msg_file >> $LOGFILE
1613	fi
1614fi
1615
1616if [ "$a_FLAG" = "y" -a "$D_FLAG" = "n" -a "$F_FLAG" = "y" ]; then
1617	echo "WARNING: Neither DEBUG nor non-DEBUG build requested, but the" \
1618	    "'a' option was set." | tee -a $mail_msg_file >> $LOGFILE
1619fi
1620
1621if [ "$D_FLAG" = "n" -a "$l_FLAG" = "y" ]; then
1622	echo "WARNING: DEBUG build not requested, but lint will be with" \
1623	    "DEBUG enabled.\n" \
1624	    | tee -a $mail_msg_file >> $LOGFILE
1625fi
1626
1627if [ "$f_FLAG" = "y" ]; then
1628	if [ "$i_FLAG" = "y" ]; then
1629		echo "WARNING: the -f flag cannot be used during incremental" \
1630		    "builds; ignoring -f\n" | tee -a $mail_msg_file >> $LOGFILE
1631		f_FLAG=n
1632	fi
1633	if [ "$p_FLAG" != "y" -o "$l_FLAG" != "y" ]; then
1634		echo "WARNING: the -f flag requires -l and -p; ignoring -f\n" | \
1635		    tee -a $mail_msg_file >> $LOGFILE
1636		f_FLAG=n
1637	fi
1638fi
1639
1640if [ "$w_FLAG" = "y" -a ! -d $ROOT ]; then
1641	echo "WARNING: -w specified, but no pre-existing proto area found;" \
1642	    "ignoring -w\n" | tee -a $mail_msg_file >> $LOGFILE
1643	w_FLAG=n
1644fi
1645
1646if [ "$t_FLAG" = "n" ]; then
1647	#
1648	# We're not doing a tools build, so make sure elfsign(1) is
1649	# new enough to safely sign non-crypto binaries.  We test
1650	# debugging output from elfsign to detect the old version.
1651	#
1652	newelfsigntest=`SUNW_CRYPTO_DEBUG=stderr /usr/bin/elfsign verify \
1653	    -e /usr/lib/security/pkcs11_softtoken.so.1 2>&1 \
1654	    | egrep algorithmOID`
1655	if [ -z "$newelfsigntest" ]; then
1656		echo "WARNING: /usr/bin/elfsign out of date;" \
1657		    "will only sign crypto modules\n" | \
1658		    tee -a $mail_msg_file >> $LOGFILE
1659		export ELFSIGN_OBJECT=true
1660	elif [ "$VERIFY_ELFSIGN" = "y" ]; then
1661		echo "WARNING: VERIFY_ELFSIGN=y requires" \
1662		    "the -t flag; ignoring VERIFY_ELFSIGN\n" | \
1663		    tee -a $mail_msg_file >> $LOGFILE
1664	fi
1665fi
1666
1667echo "==== Build environment ====\n" | tee -a $mail_msg_file >> $LOGFILE
1668
1669# System
1670whence uname | tee -a $mail_msg_file >> $LOGFILE
1671uname -a 2>&1 | tee -a $mail_msg_file >> $LOGFILE
1672echo | tee -a $mail_msg_file >> $LOGFILE
1673
1674# nightly (will fail in year 2100 due to SCCS flaw)
1675echo "$0 $@" | tee -a $mail_msg_file >> $LOGFILE
1676echo "%M% version %I% 20%E%\n" | tee -a $mail_msg_file >> $LOGFILE
1677
1678# make
1679whence $MAKE | tee -a $mail_msg_file >> $LOGFILE
1680$MAKE -v | tee -a $mail_msg_file >> $LOGFILE
1681echo "number of concurrent jobs = $DMAKE_MAX_JOBS" |
1682    tee -a $mail_msg_file >> $LOGFILE
1683
1684#
1685# Report the compiler versions.
1686#
1687if [ -f $SRC/Makefile ]; then
1688	srcroot=$SRC
1689elif [ -f $BRINGOVER_WS/usr/src/Makefile ]; then
1690	srcroot=$BRINGOVER_WS/usr/src
1691else
1692	echo "\nUnable to find \"Makefile\" in $BRINGOVER_WS/usr/src or $SRC." |
1693	    tee -a $mail_msg_file >> $LOGFILE
1694	exit 1
1695fi
1696
1697( cd $srcroot
1698  for target in cc-version cc64-version java-version; do
1699	echo
1700	#
1701	# Put statefile somewhere we know we can write to rather than trip
1702	# over a read-only $srcroot.
1703	#
1704	rm -f $TMPDIR/make-state
1705	export SRC=$srcroot
1706	if $MAKE -K $TMPDIR/make-state -e $target 2>/dev/null; then
1707		continue
1708	fi
1709	touch $TMPDIR/nocompiler
1710  done
1711  echo
1712) | tee -a $mail_msg_file >> $LOGFILE
1713
1714if [ -f $TMPDIR/nocompiler ]; then
1715	rm -f $TMPDIR/nocompiler
1716	build_ok=n
1717	echo "Aborting due to missing compiler." |
1718		tee -a $mail_msg_file >> $LOGFILE
1719	exit 1
1720fi
1721
1722# as
1723whence as | tee -a $mail_msg_file >> $LOGFILE
1724as -V 2>&1 | head -1 | tee -a $mail_msg_file >> $LOGFILE
1725echo | tee -a $mail_msg_file >> $LOGFILE
1726
1727# Check that we're running a capable link-editor
1728whence ld | tee -a $mail_msg_file >> $LOGFILE
1729LDVER=`ld -V 2>&1`
1730echo $LDVER | tee -a $mail_msg_file >> $LOGFILE
1731LDVER=`echo $LDVER | sed -e "s/.*-1\.//" -e "s/:.*//"`
1732if [ `expr $LDVER \< 422` -eq 1 ]; then
1733	echo "The link-editor needs to be at version 422 or higher to build" | \
1734	    tee -a $mail_msg_file >> $LOGFILE
1735	echo "the latest stuff, hope your build works." | \
1736	    tee -a $mail_msg_file >> $LOGFILE
1737fi
1738
1739echo "\nBuild project:  $build_project\nBuild taskid:   $build_taskid" | \
1740    tee -a $mail_msg_file >> $LOGFILE
1741
1742echo "\n==== Build version ====\n" | tee -a $mail_msg_file >> $LOGFILE
1743echo $VERSION | tee -a $mail_msg_file >> $LOGFILE
1744
1745# Save the current proto area if we're comparing against the last build
1746if [ "$w_FLAG" = "y" -a -d "$ROOT" ]; then
1747    if [ -d "$ROOT.prev" ]; then
1748	rm -rf $ROOT.prev
1749    fi
1750    mv $ROOT $ROOT.prev
1751fi
1752
1753#
1754#	Decide whether to clobber
1755#
1756if [ "$i_FLAG" = "n" -a -d "$SRC" ]; then
1757	echo "\n==== Make clobber at `date` ====\n" >> $LOGFILE
1758
1759	cd $SRC
1760	# remove old clobber file
1761	rm -f $SRC/clobber.out
1762	rm -f $SRC/clobber-${MACH}.out
1763
1764	# Remove all .make.state* files, just in case we are restarting
1765	# the build after having interrupted a previous 'make clobber'.
1766	find . \( -name SCCS -o -name 'interfaces.*' \) -prune \
1767	    -o -name '.make.*' -print | xargs rm -f
1768
1769	$MAKE -ek clobber 2>&1 | tee -a $SRC/clobber-${MACH}.out >> $LOGFILE
1770	echo "\n==== Make clobber ERRORS ====\n" >> $mail_msg_file
1771	grep "$MAKE:" $SRC/clobber-${MACH}.out |
1772		egrep -v "Ignoring unknown host" \
1773		>> $mail_msg_file
1774
1775	if [ "$t_FLAG" = "y" ]; then
1776		echo "\n==== Make tools clobber at `date` ====\n" >> $LOGFILE
1777		cd ${TOOLS}
1778		rm -f ${TOOLS}/clobber-${MACH}.out
1779		$MAKE -ek clobber 2>&1 | \
1780			tee -a ${TOOLS}/clobber-${MACH}.out >> $LOGFILE
1781		echo "\n==== Make tools clobber ERRORS ====\n" \
1782			>> $mail_msg_file
1783		grep "$MAKE:" ${TOOLS}/clobber-${MACH}.out \
1784			>> $mail_msg_file
1785		rm -rf ${TOOLS_PROTO}
1786		mkdir -p ${TOOLS_PROTO}
1787	fi
1788
1789	rm -rf $ROOT
1790
1791	# Get back to a clean workspace as much as possible to catch
1792	# problems that only occur on fresh workspaces.
1793	# Remove all .make.state* files, libraries, and .o's that may
1794	# have been omitted from clobber.  A couple of libraries are
1795	# under SCCS, so leave them alone.
1796	# We should probably blow away temporary directories too.
1797	cd $SRC
1798	find $relsrcdirs \( -name SCCS -o -name 'interfaces.*' \) -prune -o \
1799	    \( -name '.make.*' -o -name 'lib*.a' -o -name 'lib*.so*' -o \
1800	       -name '*.o' \) -print | \
1801	    grep -v 'tools/ctf/dwarf/.*/libdwarf' | xargs rm -f
1802else
1803	echo "\n==== No clobber at `date` ====\n" >> $LOGFILE
1804fi
1805
1806#
1807#	Decide whether to bringover to the codemgr workspace
1808#
1809if [ "$n_FLAG" = "n" ]; then
1810	echo "\n==== bringover to $CODEMGR_WS at `date` ====\n" >> $LOGFILE
1811	# sleep on the parent workspace's lock
1812	while egrep -s write $BRINGOVER_WS/Codemgr_wsdata/locks
1813	do
1814		sleep 120
1815	done
1816
1817	echo "\n==== BRINGOVER LOG ====\n" >> $mail_msg_file
1818
1819	(staffer $TEAMWARE/bin/bringover -c "nightly update" -p $BRINGOVER_WS \
1820	    -w $CODEMGR_WS $BRINGOVER_FILES < /dev/null 2>&1 ||
1821		touch $TMPDIR/bringover_failed
1822
1823         staffer bringovercheck $CODEMGR_WS >$TMPDIR/bringovercheck.out 2>&1
1824
1825	 if [ -s $TMPDIR/bringovercheck.out ]; then
1826		echo "\n==== POST-BRINGOVER CLEANUP NOISE ====\n"
1827		cat $TMPDIR/bringovercheck.out
1828	 fi
1829
1830	) | tee -a  $mail_msg_file >> $LOGFILE
1831
1832	if [ -f $TMPDIR/bringover_failed ]; then
1833		rm -f $TMPDIR/bringover_failed
1834		build_ok=n
1835		echo "trouble with bringover, quitting at `date`." |
1836			tee -a $mail_msg_file >> $LOGFILE
1837		exit 1
1838	fi
1839
1840	#
1841	# Possible transition from pre-split workspace to split
1842	# workspace.  See if the bringover changed anything.
1843	#
1844	CLOSED_IS_PRESENT="$orig_closed_is_present"
1845	check_closed_tree
1846else
1847	echo "\n==== No bringover to $CODEMGR_WS ====\n" >> $LOGFILE
1848fi
1849
1850#
1851# Build tools if requested
1852#
1853if [ "$t_FLAG" = "y" ]; then
1854	export INTERNAL_RELEASE_BUILD ; INTERNAL_RELEASE_BUILD=
1855	export RELEASE_BUILD ; RELEASE_BUILD=
1856	unset EXTRA_OPTIONS
1857	unset EXTRA_CFLAGS
1858
1859	export ONBLD_TOOLS=${ONBLD_TOOLS:=${TOOLS_PROTO}/opt/onbld}
1860	build_tools ${TOOLS_PROTO}
1861fi
1862
1863#
1864# copy ihv proto area in addition to the build itself
1865#
1866if [ "$X_FLAG" = "y" ]; then
1867	copy_ihv_proto
1868fi
1869
1870if [ "$i_FLAG" = "y" -a "$SH_FLAG" = "y" ]; then
1871	echo "\n==== NOT Building base OS-Net source ====\n" | \
1872	    tee -a $LOGFILE >> $mail_msg_file
1873else
1874	normal_build
1875fi
1876
1877ORIG_SRC=$SRC
1878BINARCHIVE=${CODEMGR_WS}/bin-${MACH}.cpio.Z
1879
1880#
1881# For the "open" build, we don't mung any source files, so skip this
1882# step.
1883#
1884if [ "$SE_FLAG" = "y" -o "$SD_FLAG" = "y" -o "$SH_FLAG" = "y" ]; then
1885	save_binaries
1886
1887	echo "\n==== Retrieving SCCS files at `date` ====\n" >> $LOGFILE
1888	SCCSHELPER=${TMPDIR}/sccs-helper
1889	rm -f ${SCCSHELPER}
1890cat >${SCCSHELPER} <<EOF
1891#!/bin/ksh
1892cd \$1
1893cd ..
1894sccs get SCCS >/dev/null 2>&1
1895EOF
1896	cd $SRC
1897	chmod +x ${SCCSHELPER}
1898	find $relsrcdirs -name SCCS | xargs -L 1 ${SCCSHELPER}
1899	rm -f ${SCCSHELPER}
1900fi
1901
1902if [ "$SD_FLAG" = "y" ]; then
1903	set_up_source_build ${CODEMGR_WS} ${CRYPT_SRC} CRYPT_SRC
1904fi
1905
1906# EXPORT_SRC comes after CRYPT_SRC since a domestic build will need
1907# $SRC pointing to the export_source usr/src.
1908if [ "$SE_FLAG" = "y" -o "$SD_FLAG" = "y" -o "$SH_FLAG" = "y" ]; then
1909	set_up_source_build ${CODEMGR_WS} ${EXPORT_SRC} EXPORT_SRC
1910fi
1911
1912if [ "$SD_FLAG" = "y" ]; then
1913	# drop the crypt files in place.
1914	cd ${EXPORT_SRC}
1915	echo "\nextracting crypt_files.cpio.Z onto export_source.\n" \
1916	    >> ${LOGFILE}
1917	zcat ${CODEMGR_WS}/crypt_files.cpio.Z | \
1918	    cpio -idmucvB 2>/dev/null >> ${LOGFILE}
1919	if [ "$?" = "0" ]; then
1920		echo "\n==== DOMESTIC extraction succeeded ====\n" \
1921		    >> $mail_msg_file
1922	else
1923		echo "\n==== DOMESTIC extraction failed ====\n" \
1924		    >> $mail_msg_file
1925	fi
1926
1927fi
1928
1929if [ "$SO_FLAG" = "y" ]; then
1930	#
1931	# Copy the open sources into their own tree, set up the closed
1932	# binaries, and set up the environment.
1933	#
1934	copy_source $CODEMGR_WS $OPEN_SRCDIR OPEN_SOURCE usr/src
1935	SRC=$OPEN_SRCDIR/usr/src
1936
1937	# Try not to clobber any user-provided closed binaries.
1938	export ON_CLOSED_BINS=$CODEMGR_WS/closed$$
1939	echo "\n==== Copying skeleton closed binaries to $ON_CLOSED_BINS ====\n" | \
1940	    tee -a $mail_msg_file >> $LOGFILE
1941	mkclosed $MACH $CODEMGR_WS/proto $ON_CLOSED_BINS >>$LOGFILE 2>&1
1942	if [ $? -ne 0 ]; then
1943		build_ok=n
1944		echo "Aborting (couldn't create closed binaries)." |
1945			tee -a $mail_msg_file >> $LOGFILE
1946	fi
1947	CLOSED_IS_PRESENT=no
1948fi
1949
1950if is_source_build && [ $build_ok = y ] ; then
1951	# remove proto area here, since we don't clobber
1952	rm -rf "$ROOT"
1953	if [ "$t_FLAG" = "y" ]; then
1954		export INTERNAL_RELEASE_BUILD ; INTERNAL_RELEASE_BUILD=
1955		export RELEASE_BUILD ; RELEASE_BUILD=
1956		unset EXTRA_OPTIONS
1957		unset EXTRA_CFLAGS
1958		ORIG_TOOLS=$TOOLS
1959		#
1960		# SRC was set earlier to point to the source build
1961		# source tree (e.g., $EXPORT_SRC).
1962		#
1963		TOOLS=${SRC}/tools
1964		build_tools ${SRC}/tools/proto
1965		TOOLS=$ORIG_TOOLS
1966	fi
1967
1968	export EXPORT_RELEASE_BUILD ; EXPORT_RELEASE_BUILD=#
1969	normal_build
1970fi
1971
1972if [[ "$SO_FLAG" = "y" && "$build_ok" = "y" ]]; then
1973	rm -rf $ON_CLOSED_BINS
1974fi
1975
1976if [ "$build_ok" = "y" ]; then
1977	echo "\n==== Creating protolist system file at `date` ====" \
1978		>> $LOGFILE
1979	protolist $ROOT > $ATLOG/proto_list_${MACH}
1980	echo "==== protolist system file created at `date` ====\n" \
1981		>> $LOGFILE
1982
1983	if [ "$N_FLAG" != "y" ]; then
1984		echo "\n==== Impact on packages ====\n" >> $mail_msg_file
1985
1986		# If there is a reference proto list, compare the build's proto
1987		# list with the reference to see changes in proto areas.
1988		# Use the current exception list.
1989		exc=etc/exception_list_$MACH
1990		if [ -f $SRC/pkgdefs/$exc ]; then
1991			ELIST="-e $SRC/pkgdefs/$exc"
1992		fi
1993		if [ "$X_FLAG" = "y" -a -f $IA32_IHV_WS/usr/src/pkgdefs/$exc ]; then
1994			ELIST="$ELIST -e $IA32_IHV_WS/usr/src/pkgdefs/$exc"
1995		fi
1996
1997		if [ -f "$REF_PROTO_LIST" ]; then
1998			# For builds that copy the IHV proto area (-X), add the
1999			# IHV proto list to the reference list if the reference
2000			# was built without -X.
2001			#
2002			# For builds that don't copy the IHV proto area, add the
2003			# IHV proto list to the build's proto list if the
2004			# reference was built with -X.
2005			#
2006			# Use the presence of the first file entry of the cached
2007			# IHV proto list in the reference list to determine
2008			# whether it was build with -X or not.
2009			IHV_REF_PROTO_LIST=$SRC/pkgdefs/etc/proto_list_ihv_$MACH
2010			grepfor=$(nawk '$1 == "f" { print $2; exit }' \
2011				$IHV_REF_PROTO_LIST 2> /dev/null)
2012			if [ $? = 0 -a -n "$grepfor" ]; then
2013				if [ "$X_FLAG" = "y" ]; then
2014					grep -w "$grepfor" \
2015						$REF_PROTO_LIST > /dev/null
2016					if [ ! "$?" = "0" ]; then
2017						REF_IHV_PROTO="-d $IHV_REF_PROTO_LIST"
2018					fi
2019				else
2020					grep -w "$grepfor" \
2021						$REF_PROTO_LIST > /dev/null
2022					if [ "$?" = "0" ]; then
2023						IHV_PROTO_LIST="$IHV_REF_PROTO_LIST"
2024					fi
2025				fi
2026			fi
2027
2028			$PROTOCMPTERSE \
2029			  "Files in yesterday's proto area, but not today's:" \
2030			  "Files in today's proto area, but not yesterday's:" \
2031			  "Files that changed between yesterday and today:" \
2032			  ${ELIST} \
2033			  -d $REF_PROTO_LIST \
2034			  $REF_IHV_PROTO \
2035			  $ATLOG/proto_list_${MACH} \
2036			  $IHV_PROTO_LIST \
2037				>> $mail_msg_file
2038		fi
2039		# Compare the build's proto list with current package
2040		# definitions to audit the quality of package definitions
2041		# and makefile install targets. Use the current exception list.
2042		PKGDEFS_LIST=""
2043		for d in $abssrcdirs; do
2044			if [ -d $d/pkgdefs ]; then
2045				PKGDEFS_LIST="$PKGDEFS_LIST -d $d/pkgdefs"
2046			fi
2047		done
2048		if [ "$X_FLAG" = "y" -a -d $IA32_IHV_WS/usr/src/pkgdefs ]; then
2049			PKGDEFS_LIST="$PKGDEFS_LIST -d $IA32_IHV_WS/usr/src/pkgdefs"
2050		fi
2051
2052		$PROTOCMPTERSE \
2053		    "Files missing from the proto area:" \
2054		    "Files missing from packages:" \
2055		    "Inconsistencies between pkgdefs and proto area:" \
2056		    ${ELIST} \
2057		    ${PKGDEFS_LIST} \
2058		    $ATLOG/proto_list_${MACH} \
2059		    >> $mail_msg_file
2060	fi
2061fi
2062
2063if [ "$u_FLAG" = "y"  -a "$build_ok" = "y" ]; then
2064	staffer cp $ATLOG/proto_list_${MACH} \
2065		$PARENT_WS/usr/src/proto_list_${MACH}
2066fi
2067
2068# Update parent proto area if necessary. This is done now
2069# so that the proto area has either DEBUG or non-DEBUG kernels.
2070# Note that this clears out the lock file, so we can dispense with
2071# the variable now.
2072if [ "$U_FLAG" = "y" -a "$build_ok" = "y" ]; then
2073	echo "\n==== Copying proto area to $NIGHTLY_PARENT_ROOT ====\n" | \
2074	    tee -a $LOGFILE >> $mail_msg_file
2075	# The rm -rf command below produces predictable errors if
2076	# nightly is invoked from the parent's $ROOT/opt/onbld/bin,
2077	# and that directory is accessed via NFS.  This is because
2078	# deleted-but-still-open files don't actually disappear as
2079	# expected, but rather turn into .nfsXXXX junk files, leaving
2080	# the directory non-empty.  Since this is a not-unusual usage
2081	# pattern, and we still want to catch other errors here, we
2082	# take the unusal step of moving aside 'nightly' from that
2083	# directory (if we're using it).
2084	mypath=${0##*/root_$MACH/}
2085	if [ "$mypath" = $0 ]; then
2086		mypath=opt/onbld/bin/${0##*/}
2087	fi
2088	if [ $0 -ef $PARENT_WS/proto/root_$MACH/$mypath ]; then
2089		mv -f $0 $PARENT_WS/proto/root_$MACH
2090	fi
2091	rm -rf $PARENT_WS/proto/root_$MACH/*
2092	unset Ulockfile
2093	mkdir -p $NIGHTLY_PARENT_ROOT
2094	cd $ROOT
2095	( tar cf - . | ( cd $NIGHTLY_PARENT_ROOT;  umask 0; tar xpf - ) ) 2>&1 |
2096		tee -a $mail_msg_file >> $LOGFILE
2097fi
2098
2099#
2100# do shared library interface verification
2101#
2102
2103if [ "$A_FLAG" = "y" -a "$build_ok" = "y" ]; then
2104	echo "\n==== Check versioning and ABI information ====\n"  | \
2105	    tee -a $LOGFILE >> $mail_msg_file
2106
2107	rm -rf $SRC/interfaces.ref
2108	if [ -d $SRC/interfaces.out ]; then
2109		mv $SRC/interfaces.out $SRC/interfaces.ref
2110	fi
2111	rm -rf $SRC/interfaces.out
2112	mkdir -p $SRC/interfaces.out
2113
2114	intf_check -V -m -o -b $SRC/tools/abi/etc \
2115		-d $SRC/interfaces.out $ROOT 2>&1 | sort \
2116		> $SRC/interfaces.out/log
2117
2118	# report any ERROR found in log file
2119	fgrep 'ERROR' $SRC/interfaces.out/log | sed 's/^ERROR: //' | \
2120		tee -a $LOGFILE >> $mail_msg_file
2121
2122	if [ ! -d $SRC/interfaces.ref ] ; then
2123		mkdir -p $SRC/interfaces.ref
2124		if [ -d  $SRC/interfaces.out ]; then
2125			cp -r $SRC/interfaces.out/* $SRC/interfaces.ref
2126		fi
2127	fi
2128
2129	echo "\n==== Diff versioning warnings (since last build) ====\n" | \
2130	    tee -a $LOGFILE >> $mail_msg_file
2131
2132	out_vers=`grep ^VERSION $SRC/interfaces.out/log`;
2133	ref_vers=`grep ^VERSION $SRC/interfaces.ref/log`;
2134
2135	# Report any differences in WARNING messages between last
2136	# and current build.
2137	if [ "$out_vers" = "$ref_vers" ]; then
2138		diff $SRC/interfaces.ref/log $SRC/interfaces.out/log | \
2139		    fgrep 'WARNING' | sed 's/WARNING: //' | \
2140		    tee -a $LOGFILE >> $mail_msg_file
2141	fi
2142fi
2143
2144if [ "$r_FLAG" = "y" -a "$build_ok" = "y" ]; then
2145	echo "\n==== Check ELF runtime attributes ====\n" | \
2146	    tee -a $LOGFILE >> $mail_msg_file
2147
2148	LDDUSAGE="^ldd: does not support -e"
2149	LDDWRONG="wrong class"
2150	CRLERROR="^crle:"
2151	CRLECONF="^crle: configuration file:"
2152
2153	rm -f $SRC/runtime.ref
2154	if [ -f $SRC/runtime.out ]; then
2155		egrep -v "$LDDUSAGE|$LDDWRONG|$CRLERROR|$CRLECONF" \
2156			$SRC/runtime.out > $SRC/runtime.ref
2157	fi
2158
2159	# If we're doing a debug build the proto area will be left with
2160	# debuggable objects, thus don't assert -s.
2161	if [ "$D_FLAG" = "y" ]; then
2162		rtime_sflag=""
2163	else
2164		rtime_sflag="-s"
2165	fi
2166	check_rtime -d $ROOT -i -m -o $rtime_sflag $ROOT 2>&1 | \
2167	    egrep -v ": unreferenced object=$ROOT/.*/lib(w|intl|thread|pthread).so" | \
2168	    egrep -v ": unused object=$ROOT/.*/lib(w|intl|thread|pthread).so" | \
2169	    sort >$SRC/runtime.out
2170
2171	# Determine any processing errors that will affect the final output
2172	# and display these first.
2173	grep -l "$LDDUSAGE" $SRC/runtime.out > /dev/null
2174	if [ $? -eq 0 ]; then
2175	    echo "WARNING: ldd(1) does not support -e.  The version of ldd(1)" | \
2176		tee -a $LOGFILE >> $mail_msg_file
2177	    echo "on your system is old - 4390308 (s81_30) is required.\n" | \
2178		tee -a $LOGFILE >> $mail_msg_file
2179	fi
2180	grep -l "$LDDWRONG" $SRC/runtime.out > /dev/null
2181	if [ $? -eq 0 ]; then
2182	    echo "WARNING: wrong class message detected.  ldd(1) was unable" | \
2183		tee -a $LOGFILE >> $mail_msg_file
2184	    echo "to execute an object, thus it could not be checked fully." | \
2185		tee -a $LOGFILE >> $mail_msg_file
2186	    echo "Perhaps a 64-bit object was encountered on a 32-bit system," | \
2187		tee -a $LOGFILE >> $mail_msg_file
2188	    echo "or an i386 object was encountered on a sparc system?\n" | \
2189		tee -a $LOGFILE >> $mail_msg_file
2190	fi
2191	grep -l "$CRLECONF" $SRC/runtime.out > /dev/null
2192	if [ $? -eq 0 ]; then
2193	    echo "WARNING: creation of an alternative dependency cache failed." | \
2194		tee -a $LOGFILE >> $mail_msg_file
2195	    echo "Dependencies will bind to the base system libraries.\n" | \
2196		tee -a $LOGFILE >> $mail_msg_file
2197	    grep "$CRLECONF" $SRC/runtime.out | \
2198		tee -a $LOGFILE >> $mail_msg_file
2199	    grep "$CRLERROR" $SRC/runtime.out | grep -v "$CRLECONF" | \
2200		tee -a $LOGFILE >> $mail_msg_file
2201	    echo "\n" | tee -a $LOGFILE >> $mail_msg_file
2202	fi
2203
2204	egrep '<dependency no longer necessary>' $SRC/runtime.out | \
2205	    tee -a $LOGFILE >> $mail_msg_file
2206
2207	# NEEDED= and RPATH= are informational; report anything else that we
2208	# haven't already.
2209	egrep -v "NEEDED=|RPATH=|$LDDUSAGE|$LDDWRONG|$CRLERROR|$CRLECONF" \
2210	    $SRC/runtime.out | tee -a $LOGFILE >> $mail_msg_file
2211
2212	# probably should compare against a 'known ok runpaths' list
2213	if [ ! -f $SRC/runtime.ref ]; then
2214		egrep -v "$LDDUSAGE|$LDDWRONG|$CRLERROR|$CRLECONF" \
2215			$SRC/runtime.out >  $SRC/runtime.ref
2216	fi
2217
2218	echo "\n==== Diff ELF runtime attributes (since last build) ====\n" \
2219	    >> $mail_msg_file
2220
2221	egrep -v "$LDDUSAGE|$LDDWRONG|$CRLERROR|$CRLECONF" $SRC/runtime.out | \
2222	    diff $SRC/runtime.ref - >> $mail_msg_file
2223fi
2224
2225# DEBUG lint of kernel begins
2226
2227if [ "$i_CMD_LINE_FLAG" = "n" -a "$l_FLAG" = "y" ]; then
2228	if [ "$LINTDIRS" = "" ]; then
2229		# LINTDIRS="$SRC/uts y $SRC/stand y $SRC/psm y"
2230		LINTDIRS="$SRC y"
2231	fi
2232	set $LINTDIRS
2233	while [ $# -gt 0 ]; do
2234		dolint $1 $2; shift; shift
2235	done
2236else
2237	echo "\n==== No '$MAKE lint' ====\n" >> $LOGFILE
2238fi
2239
2240# "make check" begins
2241
2242if [ "$i_CMD_LINE_FLAG" = "n" -a "$C_FLAG" = "y" ]; then
2243	# remove old check.out
2244	rm -f $SRC/check.out
2245
2246	rm -f $SRC/check-${MACH}.out
2247	cd $SRC
2248	$MAKE -ek check 2>&1 | tee -a $SRC/check-${MACH}.out >> $LOGFILE
2249	echo "\n==== cstyle/hdrchk errors ====\n" >> $mail_msg_file
2250
2251	grep ":" $SRC/check-${MACH}.out |
2252		egrep -v "Ignoring unknown host" | \
2253		sort | uniq >> $mail_msg_file
2254else
2255	echo "\n==== No '$MAKE check' ====\n" >> $LOGFILE
2256fi
2257
2258echo "\n==== Find core files ====\n" | \
2259    tee -a $LOGFILE >> $mail_msg_file
2260
2261find $abssrcdirs -name core -a -type f -exec file {} \; | \
2262	tee -a $LOGFILE >> $mail_msg_file
2263
2264if [ "$f_FLAG" = "y" -a "$build_ok" = "y" ]; then
2265	echo "\n==== Diff unreferenced files (since last build) ====\n" \
2266	    | tee -a $LOGFILE >>$mail_msg_file
2267	rm -f $SRC/unref-${MACH}.ref
2268	if [ -f $SRC/unref-${MACH}.out ]; then
2269		mv $SRC/unref-${MACH}.out $SRC/unref-${MACH}.ref
2270	fi
2271
2272	findunref -t $SRC/.build.tstamp $SRC/.. \
2273	    ${TOOLS}/findunref/exception_list \
2274	    2>> $mail_msg_file | sort | \
2275	    sed -e s=^./src/=./= -e s=^./closed/=../closed/= \
2276	    > $SRC/unref-${MACH}.out
2277
2278	if [ ! -f $SRC/unref-${MACH}.ref ]; then
2279		cp $SRC/unref-${MACH}.out $SRC/unref-${MACH}.ref
2280	fi
2281
2282	diff $SRC/unref-${MACH}.ref $SRC/unref-${MACH}.out >>$mail_msg_file
2283fi
2284
2285# Verify that the usual lists of files, such as exception lists,
2286# contain only valid references to files.  If the build has failed,
2287# then don't check the proto area.
2288CHECK_PATHS=${CHECK_PATHS:-y}
2289if [ "$CHECK_PATHS" = y -a "$N_FLAG" != y ]; then
2290	echo "\n==== Check lists of files ====\n" | tee -a $LOGFILE \
2291		>>$mail_msg_file
2292	arg=-b
2293	[ "$build_ok" = y ] && arg=
2294	checkpaths $arg $ROOT 2>&1 | tee -a $LOGFILE >>$mail_msg_file
2295fi
2296
2297if [ "$M_FLAG" != "y" -a "$build_ok" = y ]; then
2298	echo "\n==== Impact on file permissions ====\n" \
2299		>> $mail_msg_file
2300	#
2301	# Get pkginfo files from usr/src/pkgdefs
2302	#
2303	pmodes -qvdP \
2304	`for d in $abssrcdirs; do
2305		if [ -d "$d/pkgdefs" ]
2306		then
2307			find $d/pkgdefs -name pkginfo.tmpl -print -o -name .del\* -prune
2308		fi
2309	 done | sed -e 's:/pkginfo.tmpl$::' | sort -u ` >> $mail_msg_file
2310fi
2311
2312if [ "$w_FLAG" = "y" -a "$build_ok" = "y" ]; then
2313	echo "\n==== Objects that differ since last build ====\n" | \
2314	    tee -a $LOGFILE >> $mail_msg_file
2315
2316	if [ "$t_FLAG" = "y" ]; then
2317	    wsdiff -t -r ${TMPDIR}/wsdiff.results $ROOT.prev $ROOT | \
2318		tee -a $LOGFILE >> $mail_msg_file
2319	else
2320	    wsdiff -r ${TMPDIR}/wsdiff.results $ROOT.prev $ROOT  | \
2321		tee -a $LOGFILE >> $mail_msg_file
2322	fi
2323fi
2324
2325END_DATE=`date`
2326echo "==== Nightly $maketype build completed: $END_DATE ====" | \
2327    tee -a $LOGFILE >> $build_time_file
2328
2329typeset -Z2 minutes
2330typeset -Z2 seconds
2331
2332elapsed_time=$SECONDS
2333((hours = elapsed_time / 3600 ))
2334((minutes = elapsed_time / 60  % 60))
2335((seconds = elapsed_time % 60))
2336
2337echo "\n==== Total build time ====" | \
2338    tee -a $LOGFILE >> $build_time_file
2339echo "\nreal    ${hours}:${minutes}:${seconds}" | \
2340    tee -a $LOGFILE >> $build_time_file
2341
2342if [ "$u_FLAG" = "y" -a "$f_FLAG" = "y" -a "$build_ok" = "y" ]; then
2343	staffer cp ${SRC}/unref-${MACH}.out $PARENT_WS/usr/src/
2344
2345	#
2346	# Produce a master list of unreferenced files -- ideally, we'd
2347	# generate the master just once after all of the nightlies
2348	# have finished, but there's no simple way to know when that
2349	# will be.  Instead, we assume that we're the last nightly to
2350	# finish and merge all of the unref-${MACH}.out files in
2351	# $PARENT_WS/usr/src/.  If we are in fact the final ${MACH} to
2352	# finish, then this file will be the authoritative master
2353	# list.  Otherwise, another ${MACH}'s nightly will eventually
2354	# overwrite ours with its own master, but in the meantime our
2355	# temporary "master" will be no worse than any older master
2356	# which was already on the parent.
2357	#
2358
2359	set -- $PARENT_WS/usr/src/unref-*.out
2360	cp "$1" ${TMPDIR}/unref.merge
2361	shift
2362
2363	for unreffile; do
2364		comm -12 ${TMPDIR}/unref.merge "$unreffile" > ${TMPDIR}/unref.$$
2365		mv ${TMPDIR}/unref.$$ ${TMPDIR}/unref.merge
2366	done
2367
2368	staffer cp ${TMPDIR}/unref.merge $PARENT_WS/usr/src/unrefmaster.out
2369fi
2370
2371#
2372# All done save for the sweeping up.
2373# (whichever exit we hit here will trigger the "cleanup" trap which
2374# optionally sends mail on completion).
2375#
2376if [ "$build_ok" = "y" ]; then
2377	exit 0
2378fi
2379exit 1
2380