xref: /titanic_51/usr/src/tools/scripts/nightly.sh (revision 84cf253f8f6b41850d9fd9d5c853b30ce633bb40)
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#
24# Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
25# Copyright 2008, 2010, Richard Lowe
26#
27# Based on the nightly script from the integration folks,
28# Mostly modified and owned by mike_s.
29# Changes also by kjc, dmk.
30#
31# BRINGOVER_WS may be specified in the env file.
32# The default is the old behavior of CLONE_WS
33#
34# -i on the command line, means fast options, so when it's on the
35# command line (only), lint and check builds are skipped no matter what
36# the setting of their individual flags are in NIGHTLY_OPTIONS.
37#
38# LINTDIRS can be set in the env file, format is a list of:
39#
40#	/dirname-to-run-lint-on flag
41#
42#	Where flag is:	y - enable lint noise diff output
43#			n - disable lint noise diff output
44#
45#	For example: LINTDIRS="$SRC/uts n $SRC/stand y $SRC/psm y"
46#
47# OPTHOME and TEAMWARE may be set in the environment to override /opt
48# and /opt/teamware defaults.
49#
50
51#
52# The CDPATH variable causes ksh's `cd' builtin to emit messages to stdout
53# under certain circumstances, which can really screw things up; unset it.
54#
55unset CDPATH
56
57# Get the absolute path of the nightly script that the user invoked.  This
58# may be a relative path, and we need to do this before changing directory.
59nightly_path=`whence $0`
60nightly_ls="`ls -l $nightly_path`"
61
62#
63# Keep track of where we found nightly so we can invoke the matching
64# which_scm script.  If that doesn't work, don't go guessing, just rely
65# on the $PATH settings, which will generally give us either /opt/onbld
66# or the user's workspace.
67#
68WHICH_SCM=$(dirname $nightly_path)/which_scm
69if [[ ! -x $WHICH_SCM ]]; then
70	WHICH_SCM=which_scm
71fi
72
73#
74# Function to do a DEBUG and non-DEBUG build. Needed because we might
75# need to do another for the source build, and since we only deliver DEBUG or
76# non-DEBUG packages.
77#
78# usage: normal_build
79#
80function normal_build {
81
82	typeset orig_p_FLAG="$p_FLAG"
83	typeset crypto_signer="$CODESIGN_USER"
84
85	suffix=""
86
87	# non-DEBUG build begins
88
89	if [ "$F_FLAG" = "n" ]; then
90		set_non_debug_build_flags
91		CODESIGN_USER="$crypto_signer" \
92		    build "non-DEBUG" "$suffix-nd" "-nd" "$MULTI_PROTO"
93		if [ "$build_ok" = "y" -a "$X_FLAG" = "y" -a \
94		    "$p_FLAG" = "y" ]; then
95			copy_ihv_pkgs non-DEBUG -nd
96		fi
97	else
98		echo "\n==== No non-DEBUG $open_only build ====\n" >> "$LOGFILE"
99	fi
100
101	# non-DEBUG build ends
102
103	# DEBUG build begins
104
105	if [ "$D_FLAG" = "y" ]; then
106		set_debug_build_flags
107		CODESIGN_USER="$crypto_signer" \
108		    build "DEBUG" "$suffix" "" "$MULTI_PROTO"
109		if [ "$build_ok" = "y" -a "$X_FLAG" = "y" -a \
110		    "$p_FLAG" = "y" ]; then
111			copy_ihv_pkgs DEBUG ""
112		fi
113	else
114		echo "\n==== No DEBUG $open_only build ====\n" >> "$LOGFILE"
115	fi
116
117	# DEBUG build ends
118
119	p_FLAG="$orig_p_FLAG"
120}
121
122#
123# usage: run_hook HOOKNAME ARGS...
124#
125# If variable "$HOOKNAME" is defined, insert a section header into
126# our logs and then run the command with ARGS
127#
128function run_hook {
129	HOOKNAME=$1
130    	eval HOOKCMD=\$$HOOKNAME
131	shift
132
133	if [ -n "$HOOKCMD" ]; then
134	    	(
135			echo "\n==== Running $HOOKNAME command: $HOOKCMD ====\n"
136		    	( $HOOKCMD "$@" 2>&1 )
137			if [ "$?" -ne 0 ]; then
138			    	# Let exit status propagate up
139			    	touch $TMPDIR/abort
140			fi
141		) | tee -a $mail_msg_file >> $LOGFILE
142
143		if [ -f $TMPDIR/abort ]; then
144			build_ok=n
145			echo "\nAborting at request of $HOOKNAME" |
146				tee -a $mail_msg_file >> $LOGFILE
147			exit 1
148		fi
149	fi
150}
151
152#
153# usage: filelist DESTDIR PATTERN
154#
155function filelist {
156	DEST=$1
157	PATTERN=$2
158	cd ${DEST}
159
160	OBJFILES=${ORIG_SRC}/xmod/obj_files
161	if [ ! -f ${OBJFILES} ]; then
162		return;
163	fi
164	for i in `grep -v '^#' ${OBJFILES} | \
165	    grep ${PATTERN} | cut -d: -f2 | tr -d ' \t'`
166	do
167		# wildcard expansion
168		for j in $i
169		do
170			if [ -f "$j" ]; then
171				echo $j
172			fi
173			if [ -d "$j" ]; then
174				echo $j
175			fi
176		done
177	done | sort | uniq
178}
179
180# function to save off binaries after a full build for later
181# restoration
182function save_binaries {
183	# save off list of binaries
184	echo "\n==== Saving binaries from build at `date` ====\n" | \
185	    tee -a $mail_msg_file >> $LOGFILE
186	rm -f ${BINARCHIVE}
187	cd ${CODEMGR_WS}
188	filelist ${CODEMGR_WS} '^preserve:' >> $LOGFILE
189	filelist ${CODEMGR_WS} '^preserve:' | \
190	    cpio -ocB 2>/dev/null | compress \
191	    > ${BINARCHIVE}
192}
193
194# delete files
195# usage: hybridize_files DESTDIR MAKE_TARGET
196function hybridize_files {
197	DEST=$1
198	MAKETARG=$2
199
200	echo "\n==== Hybridizing files at `date` ====\n" | \
201	    tee -a $mail_msg_file >> $LOGFILE
202	for i in `filelist ${DEST} '^delete:'`
203	do
204		echo "removing ${i}." | tee -a $mail_msg_file >> $LOGFILE
205		rm -rf "${i}"
206	done
207	for i in `filelist ${DEST} '^hybridize:' `
208	do
209		echo "hybridizing ${i}." | tee -a $mail_msg_file >> $LOGFILE
210		rm -f ${i}+
211		sed -e "/^# HYBRID DELETE START/,/^# HYBRID DELETE END/d" \
212		    < ${i} > ${i}+
213		mv ${i}+ ${i}
214	done
215}
216
217# restore binaries into the proper source tree.
218# usage: restore_binaries DESTDIR MAKE_TARGET
219function restore_binaries {
220	DEST=$1
221	MAKETARG=$2
222
223	echo "\n==== Restoring binaries to ${MAKETARG} at `date` ====\n" | \
224	    tee -a $mail_msg_file >> $LOGFILE
225	cd ${DEST}
226	zcat ${BINARCHIVE} | \
227	    cpio -idmucvB 2>/dev/null | tee -a $mail_msg_file >> ${LOGFILE}
228}
229
230# rename files we save binaries of
231# usage: rename_files DESTDIR MAKE_TARGET
232function rename_files {
233	DEST=$1
234	MAKETARG=$2
235	echo "\n==== Renaming source files in ${MAKETARG} at `date` ====\n" | \
236	    tee -a $mail_msg_file >> $LOGFILE
237	for i in `filelist ${DEST} '^rename:'`
238	do
239		echo ${i} | tee -a $mail_msg_file >> ${LOGFILE}
240		rm -f ${i}.export
241		mv ${i} ${i}.export
242	done
243}
244
245#
246# Copy some or all of the source tree.
247#
248# Returns 0 for success, non-zero for failure.
249#
250# usage: copy_source CODEMGR_WS DESTDIR LABEL SRCROOT
251#
252function copy_source {
253	WS=$1
254	DEST=$2
255	label=$3
256	srcroot=$4
257
258	printf "\n==== Creating %s source from %s (%s) ====\n\n" \
259	    "$DEST" "$WS" "$label" | tee -a $mail_msg_file >> $LOGFILE
260
261	printf "cleaning out %s\n" "$DEST." >> $LOGFILE
262	rm -rf "$DEST" >> $LOGFILE 2>&1
263
264	printf "creating %s\n" "$DEST." >> $LOGFILE
265	mkdir -p "$DEST" 2>> $LOGFILE
266
267	if (( $? != 0 )) ; then
268		printf "failed to create %s\n" "$DEST" |
269		    tee -a $mail_msg_file >> $LOGFILE
270		build_ok=n
271		return 1
272	fi
273	cd "$WS"
274
275	printf "populating %s\n" "$DEST." >> $LOGFILE
276
277	case "$SCM_TYPE" in
278	teamware)
279		find $srcroot -name 's\.*' -a -type f -print | \
280		    sed -e 's,SCCS\/s.,,' | \
281		    grep -v '/\.del-*' | \
282		    cpio -pd $DEST >>$LOGFILE 2>&1
283		if (( $? != 0 )) ; then
284		    printf "cpio failed for %s\n" "$DEST" |
285			tee -a $mail_msg_file >> $LOGFILE
286		    build_ok=n
287		    return 1
288		fi
289		;;
290	mercurial)
291		copy_source_mercurial $DEST $srcroot
292		if (( $? != 0 )) ; then
293		    build_ok=n
294		    return 1
295		fi
296		;;
297	*)
298		build_ok=n
299		echo "Tree copy is not supported for workspace type" \
300		    "$SCM_TYPE" | tee -a $mail_msg_file >> $LOGFILE
301		return 1
302		;;
303	esac
304
305	return 0
306}
307
308#
309# Mercurial-specific copy code for copy_source().  Handles the
310# combined open and closed trees.
311#
312# Returns 0 for success, non-zero for failure.
313#
314# usage: copy_source_mercurial destdir srcroot
315#
316function copy_source_mercurial {
317	typeset dest=$1
318	typeset srcroot=$2
319	typeset open_top closed_top
320
321	case $srcroot in
322	usr)
323		open_top=usr
324		if [[ "$CLOSED_IS_PRESENT" = yes ]]; then
325			closed_top=usr/closed
326		fi
327		;;
328	usr/closed*)
329		if [[ "$CLOSED_IS_PRESENT" = no ]]; then
330			printf "can't copy %s: closed tree not present.\n" \
331			    "$srcroot" | tee -a $mail_msg_file >> $LOGFILE
332			return 1
333		fi
334		closed_top="$srcroot"
335		;;
336	*)
337		open_top="$srcroot"
338		;;
339	esac
340
341	if [[ -n "$open_top" ]]; then
342		hg locate -I "$open_top" | cpio -pd "$dest" >>$LOGFILE 2>&1
343		if (( $? != 0 )) ; then
344		    printf "cpio failed for %s\n" "$dest" |
345			tee -a $mail_msg_file >> $LOGFILE
346		    return 1
347		fi
348	fi
349
350	if [[ -n "$closed_top" ]]; then
351		mkdir -p "$dest/usr/closed" || return 1
352		if [[ "$closed_top" = usr/closed ]]; then
353			(cd usr/closed; hg locate |
354			    cpio -pd "$dest/usr/closed") >>$LOGFILE 2>&1
355			if (( $? != 0 )) ; then
356			    printf "cpio failed for %s/usr/closed\n" \
357				"$dest" | tee -a $mail_msg_file >> $LOGFILE
358			    return 1
359			fi
360		else
361			# copy subtree of usr/closed
362			closed_top=${closed_top#usr/closed/}
363			(cd usr/closed; hg locate -I "$closed_top" |
364			    cpio -pd "$dest/usr/closed") >>$LOGFILE 2>&1
365			if (( $? != 0 )) ; then
366			    printf "cpio failed for %s/usr/closed/%s\n" \
367				"$dest" "$closed_top" |
368				tee -a $mail_msg_file >> $LOGFILE
369			    return 1
370			fi
371		fi
372	fi
373
374	return 0
375}
376
377#
378# function to create (but not build) the export/crypt source tree.
379# usage: set_up_source_build CODEMGR_WS DESTDIR MAKE_TARGET
380# Sets SRC to the modified source tree, for use by the caller when it
381# builds the tree.
382#
383function set_up_source_build {
384	WS=$1
385	DEST=$2
386	MAKETARG=$3
387
388	copy_source $WS $DEST $MAKETARG usr
389	if (( $? != 0 )); then
390	    echo "\nCould not copy source tree for source build." |
391		tee -a $mail_msg_file >> $LOGFILE
392	    build_ok=n
393	    return
394	fi
395
396	SRC=${DEST}/usr/src
397
398	cd $SRC
399	rm -f ${MAKETARG}.out
400	echo "making ${MAKETARG} in ${SRC}." >> $LOGFILE
401	/bin/time $MAKE -e ${MAKETARG} 2>&1 | \
402	    tee -a $SRC/${MAKETARG}.out >> $LOGFILE
403	echo "\n==== ${MAKETARG} build errors ====\n" >> $mail_msg_file
404	egrep ":" $SRC/${MAKETARG}.out | \
405		egrep -e "(^${MAKE}:|[ 	]error[: 	\n])" | \
406		egrep -v "Ignoring unknown host" | \
407		egrep -v "warning" >> $mail_msg_file
408
409	echo "clearing state files." >> $LOGFILE
410	find . -name '.make*' -exec rm -f {} \;
411
412	cd ${DEST}
413	if [ "${MAKETARG}" = "CRYPT_SRC" ]; then
414		rm -f ${CODEMGR_WS}/crypt_files.cpio.Z
415		echo "\n==== xmod/cry_files that don't exist ====\n" | \
416		    tee -a $mail_msg_file >> $LOGFILE
417		CRYPT_FILES=${WS}/usr/src/xmod/cry_files
418		for i in `cat ${CRYPT_FILES}`
419		do
420			# make sure the files exist
421			if [ -f "$i" ]; then
422				continue
423			fi
424			if [ -d "$i" ]; then
425				continue
426			fi
427			echo "$i" | tee -a $mail_msg_file >> $LOGFILE
428		done
429		find `cat ${CRYPT_FILES}` -print 2>/dev/null | \
430		    cpio -ocB 2>/dev/null | \
431		    compress > ${CODEMGR_WS}/crypt_files.cpio.Z
432	fi
433
434	if [ "${MAKETARG}" = "EXPORT_SRC" ]; then
435		# rename first, since we might restore a file
436		# of the same name (mapfiles)
437		rename_files ${EXPORT_SRC} EXPORT_SRC
438		if [ "$SH_FLAG" = "y" ]; then
439			hybridize_files ${EXPORT_SRC} EXPORT_SRC
440		fi
441	fi
442
443	# save the cleartext
444	echo "\n==== Creating ${MAKETARG}.cpio.Z ====\n" | \
445	    tee -a $mail_msg_file >> $LOGFILE
446	cd ${DEST}
447	rm -f ${MAKETARG}.cpio.Z
448	find usr -depth -print | \
449	    grep -v usr/src/${MAKETARG}.out | \
450	    cpio -ocB 2>/dev/null | \
451	    compress > ${CODEMGR_WS}/${MAKETARG}.cpio.Z
452	if [ "${MAKETARG}" = "EXPORT_SRC" ]; then
453		restore_binaries ${EXPORT_SRC} EXPORT_SRC
454	fi
455
456	if [ "${MAKETARG}" = "CRYPT_SRC" ]; then
457		restore_binaries ${CRYPT_SRC} CRYPT_SRC
458	fi
459
460}
461
462# Return library search directive as function of given root.
463function myldlibs {
464	echo "-L$1/lib -L$1/usr/lib"
465}
466
467# Return header search directive as function of given root.
468function myheaders {
469	echo "-I$1/usr/include"
470}
471
472#
473# Function to do the build, including package generation.
474# usage: build LABEL SUFFIX ND MULTIPROTO
475# - LABEL is used to tag build output.
476# - SUFFIX is used to distinguish files (e.g., DEBUG vs non-DEBUG,
477#   open-only vs full tree).
478# - ND is "-nd" (non-DEBUG builds) or "" (DEBUG builds).
479# - If MULTIPROTO is "yes", it means to name the proto area according to
480#   SUFFIX.  Otherwise ("no"), (re)use the standard proto area.
481#
482function build {
483	LABEL=$1
484	SUFFIX=$2
485	ND=$3
486	MULTIPROTO=$4
487	INSTALLOG=install${SUFFIX}-${MACH}
488	NOISE=noise${SUFFIX}-${MACH}
489	PKGARCHIVE=${PKGARCHIVE_ORIG}${SUFFIX}
490
491	ORIGROOT=$ROOT
492	[ $MULTIPROTO = no ] || export ROOT=$ROOT$SUFFIX
493
494	if [[ "$O_FLAG" = y ]]; then
495		echo "\nSetting CLOSEDROOT= ${ROOT}-closed\n" >> $LOGFILE
496		export CLOSEDROOT=${ROOT}-closed
497	fi
498
499	export ENVLDLIBS1=`myldlibs $ROOT`
500	export ENVCPPFLAGS1=`myheaders $ROOT`
501
502	this_build_ok=y
503	#
504	#	Build OS-Networking source
505	#
506	echo "\n==== Building OS-Net source at `date` ($LABEL) ====\n" \
507		>> $LOGFILE
508
509	rm -f $SRC/${INSTALLOG}.out
510	cd $SRC
511	/bin/time $MAKE -e install 2>&1 | \
512	    tee -a $SRC/${INSTALLOG}.out >> $LOGFILE
513
514	if [[ "$SCM_TYPE" = teamware ]]; then
515		echo "\n==== SCCS Noise ($LABEL) ====\n" >> $mail_msg_file
516		egrep 'sccs(check:| *get)' $SRC/${INSTALLOG}.out >> \
517			$mail_msg_file
518	fi
519
520	echo "\n==== Build errors ($LABEL) ====\n" >> $mail_msg_file
521	egrep ":" $SRC/${INSTALLOG}.out |
522		egrep -e "(^${MAKE}:|[ 	]error[: 	\n])" | \
523		egrep -v "Ignoring unknown host" | \
524		egrep -v "cc .* -o error " | \
525		egrep -v "warning" >> $mail_msg_file
526	if [ "$?" = "0" ]; then
527		build_ok=n
528		this_build_ok=n
529	fi
530	grep "bootblock image is .* bytes too big" $SRC/${INSTALLOG}.out \
531		>> $mail_msg_file
532	if [ "$?" = "0" ]; then
533		build_ok=n
534		this_build_ok=n
535	fi
536
537	if [ "$W_FLAG" = "n" ]; then
538		echo "\n==== Build warnings ($LABEL) ====\n" >>$mail_msg_file
539		egrep -i warning: $SRC/${INSTALLOG}.out \
540			| egrep -v '^tic:' \
541			| egrep -v "symbol (\`|')timezone' has differing types:" \
542		        | egrep -v "parameter <PSTAMP> set to" \
543			| egrep -v "Ignoring unknown host" \
544			| egrep -v "redefining segment flags attribute for" \
545			>> $mail_msg_file
546	fi
547
548	echo "\n==== Ended OS-Net source build at `date` ($LABEL) ====\n" \
549		>> $LOGFILE
550
551	echo "\n==== Elapsed build time ($LABEL) ====\n" >>$mail_msg_file
552	tail -3  $SRC/${INSTALLOG}.out >>$mail_msg_file
553
554	if [ "$i_FLAG" = "n" -a "$W_FLAG" = "n" ]; then
555		rm -f $SRC/${NOISE}.ref
556		if [ -f $SRC/${NOISE}.out ]; then
557			mv $SRC/${NOISE}.out $SRC/${NOISE}.ref
558		fi
559		grep : $SRC/${INSTALLOG}.out \
560			| egrep -v '^/' \
561			| egrep -v '^(Start|Finish|real|user|sys|./bld_awk)' \
562			| egrep -v '^tic:' \
563			| egrep -v '^mcs' \
564			| egrep -v '^LD_LIBRARY_PATH=' \
565			| egrep -v 'ar: creating' \
566			| egrep -v 'ar: writing' \
567			| egrep -v 'conflicts:' \
568			| egrep -v ':saved created' \
569			| egrep -v '^stty.*c:' \
570			| egrep -v '^mfgname.c:' \
571			| egrep -v '^uname-i.c:' \
572			| egrep -v '^volumes.c:' \
573			| egrep -v '^lint library construction:' \
574			| egrep -v 'tsort: INFORM:' \
575			| egrep -v 'stripalign:' \
576			| egrep -v 'chars, width' \
577			| egrep -v "symbol (\`|')timezone' has differing types:" \
578			| egrep -v 'PSTAMP' \
579			| egrep -v '|%WHOANDWHERE%|' \
580			| egrep -v '^Manifying' \
581			| egrep -v 'Ignoring unknown host' \
582			| egrep -v 'Processing method:' \
583			| egrep -v '^Writing' \
584			| egrep -v 'spellin1:' \
585			| egrep -v '^adding:' \
586			| egrep -v "^echo 'msgid" \
587			| egrep -v '^echo ' \
588			| egrep -v '\.c:$' \
589			| egrep -v '^Adding file:' \
590			| egrep -v 'CLASSPATH=' \
591			| egrep -v '\/var\/mail\/:saved' \
592			| egrep -v -- '-DUTS_VERSION=' \
593			| egrep -v '^Running Mkbootstrap' \
594			| egrep -v '^Applet length read:' \
595			| egrep -v 'bytes written:' \
596			| egrep -v '^File:SolarisAuthApplet.bin' \
597			| egrep -v -i 'jibversion' \
598			| egrep -v '^Output size:' \
599			| egrep -v '^Solo size statistics:' \
600			| egrep -v '^Using ROM API Version' \
601			| egrep -v '^Zero Signature length:' \
602			| egrep -v '^Note \(probably harmless\):' \
603			| egrep -v '::' \
604			| egrep -v -- '-xcache' \
605			| egrep -v '^\+' \
606			| egrep -v '^cc1: note: -fwritable-strings' \
607			| egrep -v 'svccfg-native -s svc:/' \
608			| sort | uniq >$SRC/${NOISE}.out
609		if [ ! -f $SRC/${NOISE}.ref ]; then
610			cp $SRC/${NOISE}.out $SRC/${NOISE}.ref
611		fi
612		echo "\n==== Build noise differences ($LABEL) ====\n" \
613			>>$mail_msg_file
614		diff $SRC/${NOISE}.ref $SRC/${NOISE}.out >>$mail_msg_file
615	fi
616
617	#
618	#	Re-sign selected binaries using signing server
619	#	(gatekeeper builds only)
620	#
621	if [ -n "$CODESIGN_USER" -a "$this_build_ok" = "y" ]; then
622		echo "\n==== Signing proto area at `date` ====\n" >> $LOGFILE
623		signing_file="${TMPDIR}/signing"
624		rm -f ${signing_file}
625		export CODESIGN_USER
626		signproto $SRC/tools/codesign/creds 2>&1 | \
627			tee -a ${signing_file} >> $LOGFILE
628		echo "\n==== Finished signing proto area at `date` ====\n" \
629		    >> $LOGFILE
630		echo "\n==== Crypto module signing errors ($LABEL) ====\n" \
631		    >> $mail_msg_file
632		egrep 'WARNING|ERROR' ${signing_file} >> $mail_msg_file
633		if (( $? == 0 )) ; then
634			build_ok=n
635			this_build_ok=n
636		fi
637	fi
638
639	#
640	#	Building Packages
641	#
642	if [ "$p_FLAG" = "y" -a "$this_build_ok" = "y" ]; then
643		if [ -d $SRC/pkg -o -d $SRC/pkgdefs ]; then
644			echo "\n==== Creating $LABEL packages at `date` ====\n" \
645				>> $LOGFILE
646			echo "Clearing out $PKGARCHIVE ..." >> $LOGFILE
647			rm -rf $PKGARCHIVE >> "$LOGFILE" 2>&1
648			mkdir -p $PKGARCHIVE >> "$LOGFILE" 2>&1
649
650			for d in pkg pkgdefs; do
651				if [ ! -f "$SRC/$d/Makefile" ]; then
652					continue
653				fi
654				rm -f $SRC/$d/${INSTALLOG}.out
655				cd $SRC/$d
656				/bin/time $MAKE -e install 2>&1 | \
657					tee -a $SRC/$d/${INSTALLOG}.out >> $LOGFILE
658			done
659
660			echo "\n==== package build errors ($LABEL) ====\n" \
661				>> $mail_msg_file
662
663			for d in pkg pkgdefs; do
664				if [ ! -f "$SRC/$d/Makefile" ]; then
665					continue
666				fi
667
668				egrep "${MAKE}|ERROR|WARNING" $SRC/$d/${INSTALLOG}.out | \
669					grep ':' | \
670					grep -v PSTAMP | \
671					egrep -v "Ignoring unknown host" \
672					>> $mail_msg_file
673			done
674		else
675			#
676			# Handle it gracefully if -p was set but there are
677			# neither pkg nor pkgdefs directories.
678			#
679			echo "\n==== No $LABEL packages to build ====\n" \
680				>> $LOGFILE
681		fi
682	else
683		echo "\n==== Not creating $LABEL packages ====\n" >> $LOGFILE
684	fi
685
686	ROOT=$ORIGROOT
687}
688
689# Usage: dolint /dir y|n
690# Arg. 2 is a flag to turn on/off the lint diff output
691function dolint {
692	if [ ! -d "$1" ]; then
693		echo "dolint error: $1 is not a directory"
694		exit 1
695	fi
696
697	if [ "$2" != "y" -a "$2" != "n" ]; then
698		echo "dolint internal error: $2 should be 'y' or 'n'"
699		exit 1
700	fi
701
702	lintdir=$1
703	dodiff=$2
704	base=`basename $lintdir`
705	LINTOUT=$lintdir/lint-${MACH}.out
706	LINTNOISE=$lintdir/lint-noise-${MACH}
707	export ENVLDLIBS1=`myldlibs $ROOT`
708	export ENVCPPFLAGS1=`myheaders $ROOT`
709
710	set_debug_build_flags
711
712	#
713	#	'$MAKE lint' in $lintdir
714	#
715	echo "\n==== Begin '$MAKE lint' of $base at `date` ====\n" >> $LOGFILE
716
717	# remove old lint.out
718	rm -f $lintdir/lint.out $lintdir/lint-noise.out
719	if [ -f $lintdir/lint-noise.ref ]; then
720		mv $lintdir/lint-noise.ref ${LINTNOISE}.ref
721	fi
722
723	rm -f $LINTOUT
724	cd $lintdir
725	#
726	# Remove all .ln files to ensure a full reference file
727	#
728	rm -f Nothing_to_remove \
729	    `find . \( -name SCCS -o -name .hg -o -name .svn \) \
730	    	-prune -o -type f -name '*.ln' -print `
731
732	/bin/time $MAKE -ek lint 2>&1 | \
733	    tee -a $LINTOUT >> $LOGFILE
734	echo "\n==== '$MAKE lint' of $base ERRORS ====\n" >> $mail_msg_file
735	grep "$MAKE:" $LINTOUT |
736		egrep -v "Ignoring unknown host" \
737		>> $mail_msg_file
738
739	echo "\n==== Ended '$MAKE lint' of $base at `date` ====\n" >> $LOGFILE
740
741	echo "\n==== Elapsed time of '$MAKE lint' of $base ====\n" \
742		>>$mail_msg_file
743	tail -3  $LINTOUT >>$mail_msg_file
744
745	rm -f ${LINTNOISE}.ref
746	if [ -f ${LINTNOISE}.out ]; then
747		mv ${LINTNOISE}.out ${LINTNOISE}.ref
748	fi
749        grep : $LINTOUT | \
750		egrep -v '^(real|user|sys)' |
751		egrep -v '(library construction)' | \
752		egrep -v ': global crosschecks' | \
753		egrep -v 'Ignoring unknown host' | \
754		egrep -v '\.c:$' | \
755		sort | uniq > ${LINTNOISE}.out
756	if [ ! -f ${LINTNOISE}.ref ]; then
757		cp ${LINTNOISE}.out ${LINTNOISE}.ref
758	fi
759	if [ "$dodiff" != "n" ]; then
760		echo "\n==== lint warnings $base ====\n" \
761			>>$mail_msg_file
762		# should be none, though there are a few that were filtered out
763		# above
764		egrep -i '(warning|lint):' ${LINTNOISE}.out \
765			| sort | uniq >> $mail_msg_file
766		echo "\n==== lint noise differences $base ====\n" \
767			>> $mail_msg_file
768		diff ${LINTNOISE}.ref ${LINTNOISE}.out \
769			>> $mail_msg_file
770	fi
771}
772
773# Install proto area from IHV build
774
775function copy_ihv_proto {
776
777	echo "\n==== Installing IHV proto area ====\n" \
778		>> $LOGFILE
779	if [ -d "$IA32_IHV_ROOT" ]; then
780		if [ ! -d "$ROOT" ]; then
781			echo "mkdir -p $ROOT" >> $LOGFILE
782			mkdir -p $ROOT
783		fi
784		echo "copying $IA32_IHV_ROOT to $ROOT\n" >> $LOGFILE
785		cd $IA32_IHV_ROOT
786		tar cf - . | (cd $ROOT; umask 0; tar xpf - ) 2>&1 >> $LOGFILE
787	else
788		echo "$IA32_IHV_ROOT: not found" >> $LOGFILE
789	fi
790
791	if [ "$MULTI_PROTO" = yes ]; then
792		if [ ! -d "$ROOT-nd" ]; then
793			echo "mkdir -p $ROOT-nd" >> $LOGFILE
794			mkdir -p $ROOT-nd
795		fi
796		# If there's a non-DEBUG version of the IHV proto area,
797		# copy it, but copy something if there's not.
798		if [ -d "$IA32_IHV_ROOT-nd" ]; then
799			echo "copying $IA32_IHV_ROOT-nd to $ROOT-nd\n" >> $LOGFILE
800			cd $IA32_IHV_ROOT-nd
801		elif [ -d "$IA32_IHV_ROOT" ]; then
802			echo "copying $IA32_IHV_ROOT to $ROOT-nd\n" >> $LOGFILE
803			cd $IA32_IHV_ROOT
804		else
805			echo "$IA32_IHV_ROOT{-nd,}: not found" >> $LOGFILE
806			return
807		fi
808		tar cf - . | (cd $ROOT-nd; umask 0; tar xpf - ) 2>&1 >> $LOGFILE
809	fi
810}
811
812# Install IHV packages in PKGARCHIVE
813# usage: copy_ihv_pkgs LABEL SUFFIX
814function copy_ihv_pkgs {
815	LABEL=$1
816	SUFFIX=$2
817	# always use non-DEBUG IHV packages
818	IA32_IHV_PKGS=${IA32_IHV_PKGS_ORIG}-nd
819	PKGARCHIVE=${PKGARCHIVE_ORIG}${SUFFIX}
820
821	echo "\n==== Installing IHV packages from $IA32_IHV_PKGS ($LABEL) ====\n" \
822		>> $LOGFILE
823	if [ -d "$IA32_IHV_PKGS" ]; then
824		cd $IA32_IHV_PKGS
825		tar cf - * | \
826		   (cd $PKGARCHIVE; umask 0; tar xpf - ) 2>&1 >> $LOGFILE
827	else
828		echo "$IA32_IHV_PKGS: not found" >> $LOGFILE
829	fi
830
831	echo "\n==== Installing IHV packages from $IA32_IHV_BINARY_PKGS ($LABEL) ====\n" \
832		>> $LOGFILE
833	if [ -d "$IA32_IHV_BINARY_PKGS" ]; then
834		cd $IA32_IHV_BINARY_PKGS
835		tar cf - * | \
836		    (cd $PKGARCHIVE; umask 0; tar xpf - ) 2>&1 >> $LOGFILE
837	else
838		echo "$IA32_IHV_BINARY_PKGS: not found" >> $LOGFILE
839	fi
840}
841
842#
843# Build and install the onbld tools.
844#
845# usage: build_tools DESTROOT
846#
847# returns non-zero status if the build was successful.
848#
849function build_tools {
850	DESTROOT=$1
851
852	INSTALLOG=install-${MACH}
853
854	echo "\n==== Building tools at `date` ====\n" \
855		>> $LOGFILE
856
857	rm -f ${TOOLS}/${INSTALLOG}.out
858	cd ${TOOLS}
859	/bin/time $MAKE TOOLS_PROTO=${DESTROOT} -e install 2>&1 | \
860	    tee -a ${TOOLS}/${INSTALLOG}.out >> $LOGFILE
861
862	echo "\n==== Tools build errors ====\n" >> $mail_msg_file
863
864	egrep ":" ${TOOLS}/${INSTALLOG}.out |
865		egrep -e "(${MAKE}:|[ 	]error[: 	\n])" | \
866		egrep -v "Ignoring unknown host" | \
867		egrep -v warning >> $mail_msg_file
868	return $?
869}
870
871#
872# Set up to use locally installed tools.
873#
874# usage: use_tools TOOLSROOT
875#
876function use_tools {
877	TOOLSROOT=$1
878
879	#
880	# If we're not building ON workspace, then the TOOLSROOT
881	# settings here are clearly ignored by the workspace
882	# makefiles, prepending nonexistent directories to PATH is
883	# harmless, and we clearly do not wish to override
884	# ONBLD_TOOLS.
885	#
886	# If we're building an ON workspace, then the prepended PATH
887	# elements should supercede the preexisting ONBLD_TOOLS paths,
888	# and we want to override ONBLD_TOOLS to catch the tools that
889	# don't have specific path env vars here.
890	#
891	# So the only conditional behavior is overriding ONBLD_TOOLS,
892	# and we check for "an ON workspace" by looking for
893	# ${TOOLSROOT}/opt/onbld.
894	#
895
896	STABS=${TOOLSROOT}/opt/onbld/bin/${MACH}/stabs
897	export STABS
898	CTFSTABS=${TOOLSROOT}/opt/onbld/bin/${MACH}/ctfstabs
899	export CTFSTABS
900	GENOFFSETS=${TOOLSROOT}/opt/onbld/bin/genoffsets
901	export GENOFFSETS
902
903	CTFCONVERT=${TOOLSROOT}/opt/onbld/bin/${MACH}/ctfconvert
904	export CTFCONVERT
905	CTFMERGE=${TOOLSROOT}/opt/onbld/bin/${MACH}/ctfmerge
906	export CTFMERGE
907
908	CTFCVTPTBL=${TOOLSROOT}/opt/onbld/bin/ctfcvtptbl
909	export CTFCVTPTBL
910	CTFFINDMOD=${TOOLSROOT}/opt/onbld/bin/ctffindmod
911	export CTFFINDMOD
912
913	if [ "$VERIFY_ELFSIGN" = "y" ]; then
914		ELFSIGN=${TOOLSROOT}/opt/onbld/bin/elfsigncmp
915	else
916		ELFSIGN=${TOOLSROOT}/opt/onbld/bin/${MACH}/elfsign
917	fi
918	export ELFSIGN
919
920	PATH="${TOOLSROOT}/opt/onbld/bin/${MACH}:${PATH}"
921	PATH="${TOOLSROOT}/opt/onbld/bin:${PATH}"
922	export PATH
923
924	if [ -d "${TOOLSROOT}/opt/onbld" ]; then
925		ONBLD_TOOLS=${TOOLSROOT}/opt/onbld
926		export ONBLD_TOOLS
927	fi
928
929	echo "\n==== New environment settings. ====\n" >> $LOGFILE
930	echo "STABS=${STABS}" >> $LOGFILE
931	echo "CTFSTABS=${CTFSTABS}" >> $LOGFILE
932	echo "CTFCONVERT=${CTFCONVERT}" >> $LOGFILE
933	echo "CTFMERGE=${CTFMERGE}" >> $LOGFILE
934	echo "CTFCVTPTBL=${CTFCVTPTBL}" >> $LOGFILE
935	echo "CTFFINDMOD=${CTFFINDMOD}" >> $LOGFILE
936	echo "ELFSIGN=${ELFSIGN}" >> $LOGFILE
937	echo "PATH=${PATH}" >> $LOGFILE
938	echo "ONBLD_TOOLS=${ONBLD_TOOLS}" >> $LOGFILE
939}
940
941function staffer {
942	if [ $ISUSER -ne 0 ]; then
943		"$@"
944	else
945		arg="\"$1\""
946		shift
947		for i
948		do
949			arg="$arg \"$i\""
950		done
951		eval su $STAFFER -c \'$arg\'
952	fi
953}
954
955#
956# Verify that the closed tree is present if it needs to be.
957# Sets CLOSED_IS_PRESENT for future use.
958#
959function check_closed_tree {
960	if [ -z "$CLOSED_IS_PRESENT" ]; then
961		if [ -d $CODEMGR_WS/usr/closed ]; then
962			CLOSED_IS_PRESENT="yes"
963		else
964			CLOSED_IS_PRESENT="no"
965		fi
966		export CLOSED_IS_PRESENT
967	fi
968	if [[ "$CLOSED_IS_PRESENT" = no && ! -d "$ON_CLOSED_BINS" ]]; then
969		#
970		# If it's an old (pre-split) tree or an empty
971		# workspace, don't complain.
972		#
973		if grep -s CLOSED_BUILD $SRC/Makefile.master > /dev/null; then
974			echo "If the closed sources are not present," \
975			    "ON_CLOSED_BINS"
976			echo "must point to the closed binaries tree."
977			build_ok=n
978			exit 1
979		fi
980	fi
981}
982
983function obsolete_build {
984    	echo "WARNING: Obsolete $1 build requested; request will be ignored"
985}
986
987#
988# wrapper over wsdiff.
989# usage: do_wsdiff LABEL OLDPROTO NEWPROTO
990#
991function do_wsdiff {
992	label=$1
993	oldproto=$2
994	newproto=$3
995
996	wsdiff="wsdiff"
997	[ "$t_FLAG" = y ] && wsdiff="wsdiff -t"
998
999	echo "\n==== Getting object changes since last build at `date`" \
1000	    "($label) ====\n" | tee -a $LOGFILE >> $mail_msg_file
1001	$wsdiff -s -r ${TMPDIR}/wsdiff.results $oldproto $newproto 2>&1 | \
1002		    tee -a $LOGFILE >> $mail_msg_file
1003	echo "\n==== Object changes determined at `date` ($label) ====\n" | \
1004	    tee -a $LOGFILE >> $mail_msg_file
1005}
1006
1007#
1008# Functions for setting build flags (DEBUG/non-DEBUG).  Keep them
1009# together.
1010#
1011
1012function set_non_debug_build_flags {
1013	export INTERNAL_RELEASE_BUILD ; INTERNAL_RELEASE_BUILD=
1014	export RELEASE_BUILD ; RELEASE_BUILD=
1015	unset EXTRA_OPTIONS
1016	unset EXTRA_CFLAGS
1017}
1018
1019function set_debug_build_flags {
1020	export INTERNAL_RELEASE_BUILD ; INTERNAL_RELEASE_BUILD=
1021	unset RELEASE_BUILD
1022	unset EXTRA_OPTIONS
1023	unset EXTRA_CFLAGS
1024}
1025
1026
1027MACH=`uname -p`
1028
1029if [ "$OPTHOME" = "" ]; then
1030	OPTHOME=/opt
1031	export OPTHOME
1032fi
1033if [ "$TEAMWARE" = "" ]; then
1034	TEAMWARE=$OPTHOME/teamware
1035	export TEAMWARE
1036fi
1037
1038USAGE='Usage: nightly [-in] [+t] [-V VERS ] [ -S E|D|H|O ] <env_file>
1039
1040Where:
1041	-i	Fast incremental options (no clobber, lint, check)
1042	-n      Do not do a bringover
1043	+t	Use the build tools in $ONBLD_TOOLS/bin
1044	-V VERS set the build version string to VERS
1045	-S	Build a variant of the source product
1046		E - build exportable source
1047		D - build domestic source (exportable + crypt)
1048		H - build hybrid source (binaries + deleted source)
1049		O - build (only) open source
1050
1051	<env_file>  file in Bourne shell syntax that sets and exports
1052	variables that configure the operation of this script and many of
1053	the scripts this one calls. If <env_file> does not exist,
1054	it will be looked for in $OPTHOME/onbld/env.
1055
1056non-DEBUG is the default build type. Build options can be set in the
1057NIGHTLY_OPTIONS variable in the <env_file> as follows:
1058
1059	-A	check for ABI differences in .so files
1060	-C	check for cstyle/hdrchk errors
1061	-D	do a build with DEBUG on
1062	-F	do _not_ do a non-DEBUG build
1063	-G	gate keeper default group of options (-au)
1064	-I	integration engineer default group of options (-ampu)
1065	-M	do not run pmodes (safe file permission checker)
1066	-N	do not run protocmp
1067	-O	generate OpenSolaris deliverables
1068	-R	default group of options for building a release (-mp)
1069	-U	update proto area in the parent
1070	-V VERS set the build version string to VERS
1071	-X	copy x86 IHV proto area
1072	-f	find unreferenced files
1073	-i	do an incremental build (no "make clobber")
1074	-l	do "make lint" in $LINTDIRS (default: $SRC y)
1075	-m	send mail to $MAILTO at end of build
1076	-n      do not do a bringover
1077	-o	build using root privileges to set OWNER/GROUP (old style)
1078	-p	create packages
1079	-r	check ELF runtime attributes in the proto area
1080	-t	build and use the tools in $SRC/tools (default setting)
1081	+t	Use the build tools in $ONBLD_TOOLS/bin
1082	-u	update proto_list_$MACH and friends in the parent workspace;
1083		when used with -f, also build an unrefmaster.out in the parent
1084	-w	report on differences between previous and current proto areas
1085	-z	compress cpio archives with gzip
1086	-W	Do not report warnings (freeware gate ONLY)
1087	-S	Build a variant of the source product
1088		E - build exportable source
1089		D - build domestic source (exportable + crypt)
1090		H - build hybrid source (binaries + deleted source)
1091		O - build (only) open source
1092'
1093#
1094#	-x	less public handling of xmod source for the source product
1095#
1096#	A log file will be generated under the name $LOGFILE
1097#	for partially completed build and log.`date '+%F'`
1098#	in the same directory for fully completed builds.
1099#
1100
1101# default values for low-level FLAGS; G I R are group FLAGS
1102A_FLAG=n
1103C_FLAG=n
1104D_FLAG=n
1105F_FLAG=n
1106f_FLAG=n
1107i_FLAG=n; i_CMD_LINE_FLAG=n
1108l_FLAG=n
1109M_FLAG=n
1110m_FLAG=n
1111N_FLAG=n
1112n_FLAG=n
1113O_FLAG=n
1114o_FLAG=n
1115P_FLAG=n
1116p_FLAG=n
1117r_FLAG=n
1118T_FLAG=n
1119t_FLAG=y
1120U_FLAG=n
1121u_FLAG=n
1122V_FLAG=n
1123W_FLAG=n
1124w_FLAG=n
1125X_FLAG=n
1126SD_FLAG=n
1127SE_FLAG=n
1128SH_FLAG=n
1129SO_FLAG=n
1130#
1131XMOD_OPT=
1132#
1133build_ok=y
1134
1135function is_source_build {
1136	[ "$SE_FLAG" = "y" -o "$SD_FLAG" = "y" -o \
1137	    "$SH_FLAG" = "y" -o "$SO_FLAG" = "y" ]
1138	return $?
1139}
1140
1141#
1142# examine arguments
1143#
1144
1145#
1146# single function for setting -S flag and doing error checking.
1147# usage: set_S_flag <type>
1148# where <type> is the source build type ("E", "D", ...).
1149#
1150function set_S_flag {
1151	if is_source_build; then
1152		echo "Can only build one source variant at a time."
1153		exit 1
1154	fi
1155	if [ "$1" = "E" ]; then
1156		SE_FLAG=y
1157	elif [ "$1" = "D" ]; then
1158		SD_FLAG=y
1159	elif [ "$1" = "H" ]; then
1160		SH_FLAG=y
1161	elif [ "$1" = "O" ]; then
1162		SO_FLAG=y
1163	else
1164		echo "$USAGE"
1165		exit 1
1166	fi
1167}
1168
1169OPTIND=1
1170while getopts +inS:tV: FLAG
1171do
1172	case $FLAG in
1173	  i )	i_FLAG=y; i_CMD_LINE_FLAG=y
1174		;;
1175	  n )	n_FLAG=y
1176		;;
1177	  S )
1178		set_S_flag $OPTARG
1179		;;
1180	 +t )	t_FLAG=n
1181		;;
1182	  V )	V_FLAG=y
1183		V_ARG="$OPTARG"
1184		;;
1185	 \? )	echo "$USAGE"
1186		exit 1
1187		;;
1188	esac
1189done
1190
1191# correct argument count after options
1192shift `expr $OPTIND - 1`
1193
1194# test that the path to the environment-setting file was given
1195if [ $# -ne 1 ]; then
1196	echo "$USAGE"
1197	exit 1
1198fi
1199
1200# check if user is running nightly as root
1201# ISUSER is set non-zero if an ordinary user runs nightly, or is zero
1202# when root invokes nightly.
1203/usr/bin/id | grep '^uid=0(' >/dev/null 2>&1
1204ISUSER=$?;	export ISUSER
1205
1206#
1207# force locale to C
1208LC_COLLATE=C;	export LC_COLLATE
1209LC_CTYPE=C;	export LC_CTYPE
1210LC_MESSAGES=C;	export LC_MESSAGES
1211LC_MONETARY=C;	export LC_MONETARY
1212LC_NUMERIC=C;	export LC_NUMERIC
1213LC_TIME=C;	export LC_TIME
1214
1215# clear environment variables we know to be bad for the build
1216unset LD_OPTIONS
1217unset LD_AUDIT		LD_AUDIT_32		LD_AUDIT_64
1218unset LD_BIND_NOW	LD_BIND_NOW_32		LD_BIND_NOW_64
1219unset LD_BREADTH	LD_BREADTH_32		LD_BREADTH_64
1220unset LD_CONFIG		LD_CONFIG_32		LD_CONFIG_64
1221unset LD_DEBUG		LD_DEBUG_32		LD_DEBUG_64
1222unset LD_DEMANGLE	LD_DEMANGLE_32		LD_DEMANGLE_64
1223unset LD_FLAGS		LD_FLAGS_32		LD_FLAGS_64
1224unset LD_LIBRARY_PATH	LD_LIBRARY_PATH_32	LD_LIBRARY_PATH_64
1225unset LD_LOADFLTR	LD_LOADFLTR_32		LD_LOADFLTR_64
1226unset LD_NOAUDIT	LD_NOAUDIT_32		LD_NOAUDIT_64
1227unset LD_NOAUXFLTR	LD_NOAUXFLTR_32		LD_NOAUXFLTR_64
1228unset LD_NOCONFIG	LD_NOCONFIG_32		LD_NOCONFIG_64
1229unset LD_NODIRCONFIG	LD_NODIRCONFIG_32	LD_NODIRCONFIG_64
1230unset LD_NODIRECT	LD_NODIRECT_32		LD_NODIRECT_64
1231unset LD_NOLAZYLOAD	LD_NOLAZYLOAD_32	LD_NOLAZYLOAD_64
1232unset LD_NOOBJALTER	LD_NOOBJALTER_32	LD_NOOBJALTER_64
1233unset LD_NOVERSION	LD_NOVERSION_32		LD_NOVERSION_64
1234unset LD_ORIGIN		LD_ORIGIN_32		LD_ORIGIN_64
1235unset LD_PRELOAD	LD_PRELOAD_32		LD_PRELOAD_64
1236unset LD_PROFILE	LD_PROFILE_32		LD_PROFILE_64
1237
1238unset CONFIG
1239unset GROUP
1240unset OWNER
1241unset REMOTE
1242unset ENV
1243unset ARCH
1244unset CLASSPATH
1245unset NAME
1246
1247#
1248# To get ONBLD_TOOLS from the environment, it must come from the env file.
1249# If it comes interactively, it is generally TOOLS_PROTO, which will be
1250# clobbered before the compiler version checks, which will therefore fail.
1251#
1252unset ONBLD_TOOLS
1253
1254#
1255#	Setup environmental variables
1256#
1257if [ -f /etc/nightly.conf ]; then
1258	. /etc/nightly.conf
1259fi
1260
1261if [ -f $1 ]; then
1262	if [[ $1 = */* ]]; then
1263		. $1
1264	else
1265		. ./$1
1266	fi
1267else
1268	if [ -f $OPTHOME/onbld/env/$1 ]; then
1269		. $OPTHOME/onbld/env/$1
1270	else
1271		echo "Cannot find env file as either $1 or $OPTHOME/onbld/env/$1"
1272		exit 1
1273	fi
1274fi
1275
1276# contents of stdenv.sh inserted after next line:
1277# STDENV_START
1278# STDENV_END
1279
1280#
1281# place ourselves in a new task, respecting BUILD_PROJECT if set.
1282#
1283if [ -z "$BUILD_PROJECT" ]; then
1284	/usr/bin/newtask -c $$
1285else
1286	/usr/bin/newtask -c $$ -p $BUILD_PROJECT
1287fi
1288
1289ps -o taskid= -p $$ | read build_taskid
1290ps -o project= -p $$ | read build_project
1291
1292#
1293# See if NIGHTLY_OPTIONS is set
1294#
1295if [ "$NIGHTLY_OPTIONS" = "" ]; then
1296	NIGHTLY_OPTIONS="-aBm"
1297fi
1298
1299#
1300# If BRINGOVER_WS was not specified, let it default to CLONE_WS
1301#
1302if [ "$BRINGOVER_WS" = "" ]; then
1303	BRINGOVER_WS=$CLONE_WS
1304fi
1305
1306#
1307# If CLOSED_BRINGOVER_WS was not specified, let it default to CLOSED_CLONE_WS
1308#
1309if [ "$CLOSED_BRINGOVER_WS" = "" ]; then
1310	CLOSED_BRINGOVER_WS=$CLOSED_CLONE_WS
1311fi
1312
1313#
1314# If BRINGOVER_FILES was not specified, default to usr
1315#
1316if [ "$BRINGOVER_FILES" = "" ]; then
1317	BRINGOVER_FILES="usr"
1318fi
1319
1320#
1321# If the closed sources are not present, the closed binaries must be
1322# present for the build to succeed.  If there's no pointer to the
1323# closed binaries, flag that now, rather than forcing the user to wait
1324# a couple hours (or more) to find out.
1325#
1326orig_closed_is_present="$CLOSED_IS_PRESENT"
1327check_closed_tree
1328
1329#
1330# Note: changes to the option letters here should also be applied to the
1331#	bldenv script.  `d' is listed for backward compatibility.
1332#
1333NIGHTLY_OPTIONS=-${NIGHTLY_OPTIONS#-}
1334OPTIND=1
1335while getopts +ABCDdFfGIilMmNnOoPpRrS:TtUuWwXxz FLAG $NIGHTLY_OPTIONS
1336do
1337	case $FLAG in
1338	  A )	A_FLAG=y
1339		#
1340		# If ELF_DATA_BASELINE_DIR is not defined, and we are on SWAN
1341		# (based on CLOSED_IS_PRESENT), then refuse to run. The value
1342		# of ELF version checking is greatly enhanced by including
1343		# the baseline gate comparison.
1344		if [ "$CLOSED_IS_PRESENT" = 'yes' -a \
1345		     "$ELF_DATA_BASELINE_DIR" = '' ]; then
1346			echo "ELF_DATA_BASELINE_DIR must be set if the A" \
1347			    "flag is present in\nNIGHTLY_OPTIONS and closed" \
1348			    "sources are present. Update environment file."
1349			exit 1;
1350		fi
1351		;;
1352	  B )	D_FLAG=y
1353		;; # old version of D
1354	  C )	C_FLAG=y
1355		;;
1356	  D )	D_FLAG=y
1357		;;
1358	  F )	F_FLAG=y
1359		;;
1360	  f )	f_FLAG=y
1361		;;
1362	  G )   u_FLAG=y
1363		;;
1364	  I )	m_FLAG=y
1365		p_FLAG=y
1366		u_FLAG=y
1367		;;
1368	  i )	i_FLAG=y
1369		;;
1370	  l )	l_FLAG=y
1371		;;
1372	  M )	M_FLAG=y
1373		;;
1374	  m )	m_FLAG=y
1375		;;
1376	  N )	N_FLAG=y
1377		;;
1378	  n )	n_FLAG=y
1379		;;
1380	  O )	O_FLAG=y
1381		;;
1382	  o )	o_FLAG=y
1383		;;
1384	  P )	P_FLAG=y
1385		;; # obsolete
1386	  p )	p_FLAG=y
1387		;;
1388	  R )	m_FLAG=y
1389		p_FLAG=y
1390		;;
1391	  r )	r_FLAG=y
1392		;;
1393	  S )
1394		set_S_flag $OPTARG
1395		;;
1396	  T )	T_FLAG=y
1397		;; # obsolete
1398	 +t )	t_FLAG=n
1399		;;
1400	  U )   if [ -z "${PARENT_ROOT}" ]; then
1401			echo "PARENT_ROOT must be set if the U flag is" \
1402			    "present in NIGHTLY_OPTIONS."
1403			exit 1
1404		fi
1405		NIGHTLY_PARENT_ROOT=$PARENT_ROOT
1406		if [ -n "${PARENT_TOOLS_ROOT}" ]; then
1407			NIGHTLY_PARENT_TOOLS_ROOT=$PARENT_TOOLS_ROOT
1408		fi
1409		U_FLAG=y
1410		;;
1411	  u )	u_FLAG=y
1412		;;
1413	  W )	W_FLAG=y
1414		;;
1415
1416	  w )	w_FLAG=y
1417		;;
1418	  X )	# now that we no longer need realmode builds, just
1419		# copy IHV packages.  only meaningful on x86.
1420		if [ "$MACH" = "i386" ]; then
1421			X_FLAG=y
1422		fi
1423		;;
1424	  x )	XMOD_OPT="-x"
1425		;;
1426	 \? )	echo "$USAGE"
1427		exit 1
1428		;;
1429	esac
1430done
1431
1432if [ $ISUSER -ne 0 ]; then
1433	if [ "$o_FLAG" = "y" ]; then
1434		echo "Old-style build requires root permission."
1435		exit 1
1436	fi
1437
1438	# Set default value for STAFFER, if needed.
1439	if [ -z "$STAFFER" -o "$STAFFER" = "nobody" ]; then
1440		STAFFER=`/usr/xpg4/bin/id -un`
1441		export STAFFER
1442	fi
1443fi
1444
1445if [ -z "$MAILTO" -o "$MAILTO" = "nobody" ]; then
1446	MAILTO=$STAFFER
1447	export MAILTO
1448fi
1449
1450PATH="$OPTHOME/onbld/bin:$OPTHOME/onbld/bin/${MACH}:/usr/ccs/bin"
1451PATH="$PATH:$OPTHOME/SUNWspro/bin:$TEAMWARE/bin:/usr/bin:/usr/sbin:/usr/ucb"
1452PATH="$PATH:/usr/openwin/bin:/usr/sfw/bin:/opt/sfw/bin:."
1453export PATH
1454
1455# roots of source trees, both relative to $SRC and absolute.
1456relsrcdirs="."
1457if [[ -d $CODEMGR_WS/usr/closed && "$CLOSED_IS_PRESENT" != no ]]; then
1458	relsrcdirs="$relsrcdirs ../closed"
1459fi
1460abssrcdirs=""
1461for d in $relsrcdirs; do
1462	abssrcdirs="$abssrcdirs $SRC/$d"
1463done
1464
1465unset CH
1466if [ "$o_FLAG" = "y" ]; then
1467# root invoked old-style build -- make sure it works as it always has
1468# by exporting 'CH'.  The current Makefile.master doesn't use this, but
1469# the old ones still do.
1470	PROTOCMPTERSE="protocmp.terse"
1471	CH=
1472	export CH
1473else
1474	PROTOCMPTERSE="protocmp.terse -gu"
1475fi
1476POUND_SIGN="#"
1477# have we set RELEASE_DATE in our env file?
1478if [ -z "$RELEASE_DATE" ]; then
1479	RELEASE_DATE=$(LC_ALL=C date +"%B %Y")
1480fi
1481BUILD_DATE=$(LC_ALL=C date +%Y-%b-%d)
1482BASEWSDIR=$(basename $CODEMGR_WS)
1483DEV_CM="\"@(#)SunOS Internal Development: $LOGNAME $BUILD_DATE [$BASEWSDIR]\""
1484
1485# we export POUND_SIGN, RELEASE_DATE and DEV_CM to speed up the build process
1486# by avoiding repeated shell invocations to evaluate Makefile.master definitions.
1487# we export o_FLAG and X_FLAG for use by makebfu, and by usr/src/pkg/Makefile
1488export o_FLAG X_FLAG POUND_SIGN RELEASE_DATE DEV_CM
1489
1490maketype="distributed"
1491MAKE=dmake
1492# get the dmake version string alone
1493DMAKE_VERSION=$( $MAKE -v )
1494DMAKE_VERSION=${DMAKE_VERSION#*: }
1495# focus in on just the dotted version number alone
1496DMAKE_MAJOR=$( echo $DMAKE_VERSION | \
1497	sed -e 's/.*\<\([^.]*\.[^   ]*\).*$/\1/' )
1498# extract the second (or final) integer
1499DMAKE_MINOR=${DMAKE_MAJOR#*.}
1500DMAKE_MINOR=${DMAKE_MINOR%%.*}
1501# extract the first integer
1502DMAKE_MAJOR=${DMAKE_MAJOR%%.*}
1503CHECK_DMAKE=${CHECK_DMAKE:-y}
1504# x86 was built on the 12th, sparc on the 13th.
1505if [ "$CHECK_DMAKE" = "y" -a \
1506     "$DMAKE_VERSION" != "Sun Distributed Make 7.3 2003/03/12" -a \
1507     "$DMAKE_VERSION" != "Sun Distributed Make 7.3 2003/03/13" -a \( \
1508     "$DMAKE_MAJOR" -lt 7 -o \
1509     "$DMAKE_MAJOR" -eq 7 -a "$DMAKE_MINOR" -lt 4 \) ]; then
1510	if [ -z "$DMAKE_VERSION" ]; then
1511		echo "$MAKE is missing."
1512		exit 1
1513	fi
1514	echo `whence $MAKE`" version is:"
1515	echo "  ${DMAKE_VERSION}"
1516	cat <<EOF
1517
1518This version may not be safe for use.  Either set TEAMWARE to a better
1519path or (if you really want to use this version of dmake anyway), add
1520the following to your environment to disable this check:
1521
1522  CHECK_DMAKE=n
1523EOF
1524	exit 1
1525fi
1526export PATH
1527export MAKE
1528
1529if [[ "$O_FLAG" = y ]]; then
1530	export TONICBUILD=""
1531else
1532	export TONICBUILD="#"
1533fi
1534
1535if [ "${SUNWSPRO}" != "" ]; then
1536	PATH="${SUNWSPRO}/bin:$PATH"
1537	export PATH
1538fi
1539
1540hostname=$(uname -n)
1541if [[ $DMAKE_MAX_JOBS != +([0-9]) || $DMAKE_MAX_JOBS -eq 0 ]]
1542then
1543	maxjobs=
1544	if [[ -f $HOME/.make.machines ]]
1545	then
1546		# Note: there is a hard tab and space character in the []s
1547		# below.
1548		egrep -i "^[ 	]*$hostname[ 	\.]" \
1549			$HOME/.make.machines | read host jobs
1550		maxjobs=${jobs##*=}
1551	fi
1552
1553	if [[ $maxjobs != +([0-9]) || $maxjobs -eq 0 ]]
1554	then
1555		# default
1556		maxjobs=4
1557	fi
1558
1559	export DMAKE_MAX_JOBS=$maxjobs
1560fi
1561
1562DMAKE_MODE=parallel;
1563export DMAKE_MODE
1564
1565if [ -z "${ROOT}" ]; then
1566	echo "ROOT must be set."
1567	exit 1
1568fi
1569
1570#
1571# if -V flag was given, reset VERSION to V_ARG
1572#
1573if [ "$V_FLAG" = "y" ]; then
1574	VERSION=$V_ARG
1575fi
1576
1577#
1578# Check for IHV root for copying ihv proto area
1579#
1580if [ "$X_FLAG" = "y" ]; then
1581        if [ "$IA32_IHV_ROOT" = "" ]; then
1582		echo "IA32_IHV_ROOT: must be set for copying ihv proto"
1583		args_ok=n
1584        fi
1585        if [ ! -d "$IA32_IHV_ROOT" ]; then
1586                echo "$IA32_IHV_ROOT: not found"
1587                args_ok=n
1588        fi
1589        if [ "$IA32_IHV_WS" = "" ]; then
1590		echo "IA32_IHV_WS: must be set for copying ihv proto"
1591		args_ok=n
1592        fi
1593        if [ ! -d "$IA32_IHV_WS" ]; then
1594                echo "$IA32_IHV_WS: not found"
1595                args_ok=n
1596        fi
1597fi
1598
1599# Append source version
1600if [ "$SE_FLAG" = "y" ]; then
1601	VERSION="${VERSION}:EXPORT"
1602fi
1603
1604if [ "$SD_FLAG" = "y" ]; then
1605	VERSION="${VERSION}:DOMESTIC"
1606fi
1607
1608if [ "$SH_FLAG" = "y" ]; then
1609	VERSION="${VERSION}:MODIFIED_SOURCE_PRODUCT"
1610fi
1611
1612if [ "$SO_FLAG" = "y" ]; then
1613	VERSION="${VERSION}:OPEN_ONLY"
1614fi
1615
1616TMPDIR="/tmp/nightly.tmpdir.$$"
1617export TMPDIR
1618rm -rf ${TMPDIR}
1619mkdir -p $TMPDIR || exit 1
1620chmod 777 $TMPDIR
1621
1622#
1623# Keep elfsign's use of pkcs11_softtoken from looking in the user home
1624# directory, which doesn't always work.   Needed until all build machines
1625# have the fix for 6271754
1626#
1627SOFTTOKEN_DIR=$TMPDIR
1628export SOFTTOKEN_DIR
1629
1630#
1631# Tools should only be built non-DEBUG.  Keep track of the tools proto
1632# area path relative to $TOOLS, because the latter changes in an
1633# export build.
1634#
1635# TOOLS_PROTO is included below for builds other than usr/src/tools
1636# that look for this location.  For usr/src/tools, this will be
1637# overridden on the $MAKE command line in build_tools().
1638#
1639TOOLS=${SRC}/tools
1640TOOLS_PROTO_REL=proto/root_${MACH}-nd
1641TOOLS_PROTO=${TOOLS}/${TOOLS_PROTO_REL};	export TOOLS_PROTO
1642
1643unset   CFLAGS LD_LIBRARY_PATH LDFLAGS
1644
1645# create directories that are automatically removed if the nightly script
1646# fails to start correctly
1647function newdir {
1648	dir=$1
1649	toadd=
1650	while [ ! -d $dir ]; do
1651		toadd="$dir $toadd"
1652		dir=`dirname $dir`
1653	done
1654	torm=
1655	newlist=
1656	for dir in $toadd; do
1657		if staffer mkdir $dir; then
1658			newlist="$ISUSER $dir $newlist"
1659			torm="$dir $torm"
1660		else
1661			[ -z "$torm" ] || staffer rmdir $torm
1662			return 1
1663		fi
1664	done
1665	newdirlist="$newlist $newdirlist"
1666	return 0
1667}
1668newdirlist=
1669
1670[ -d $CODEMGR_WS ] || newdir $CODEMGR_WS || exit 1
1671
1672# since this script assumes the build is from full source, it nullifies
1673# variables likely to have been set by a "ws" script; nullification
1674# confines the search space for headers and libraries to the proto area
1675# built from this immediate source.
1676ENVLDLIBS1=
1677ENVLDLIBS2=
1678ENVLDLIBS3=
1679ENVCPPFLAGS1=
1680ENVCPPFLAGS2=
1681ENVCPPFLAGS3=
1682ENVCPPFLAGS4=
1683PARENT_ROOT=
1684
1685export ENVLDLIBS3 ENVCPPFLAGS1 ENVCPPFLAGS2 ENVCPPFLAGS3 ENVCPPFLAGS4 \
1686	PARENT_ROOT
1687
1688PKGARCHIVE_ORIG=$PKGARCHIVE
1689IA32_IHV_PKGS_ORIG=$IA32_IHV_PKGS
1690
1691#
1692# Juggle the logs and optionally send mail on completion.
1693#
1694
1695function logshuffle {
1696    	LLOG="$ATLOG/log.`date '+%F.%H:%M'`"
1697	if [ -f $LLOG -o -d $LLOG ]; then
1698	    	LLOG=$LLOG.$$
1699	fi
1700	mkdir $LLOG
1701	export LLOG
1702
1703	if [ "$build_ok" = "y" ]; then
1704		mv $ATLOG/proto_list_${MACH} $LLOG
1705
1706		if [ -f $ATLOG/proto_list_tools_${MACH} ]; then
1707			mv $ATLOG/proto_list_tools_${MACH} $LLOG
1708	        fi
1709
1710		if [ -f $TMPDIR/wsdiff.results ]; then
1711		    	mv $TMPDIR/wsdiff.results $LLOG
1712		fi
1713
1714		if [ -f $TMPDIR/wsdiff-nd.results ]; then
1715			mv $TMPDIR/wsdiff-nd.results $LLOG
1716		fi
1717	fi
1718
1719	#
1720	# Now that we're about to send mail, it's time to check the noise
1721	# file.  In the event that an error occurs beyond this point, it will
1722	# be recorded in the nightly.log file, but nowhere else.  This would
1723	# include only errors that cause the copying of the noise log to fail
1724	# or the mail itself not to be sent.
1725	#
1726
1727	exec >>$LOGFILE 2>&1
1728	if [ -s $build_noise_file ]; then
1729	    	echo "\n==== Nightly build noise ====\n" |
1730		    tee -a $LOGFILE >>$mail_msg_file
1731		cat $build_noise_file >>$LOGFILE
1732		cat $build_noise_file >>$mail_msg_file
1733		echo | tee -a $LOGFILE >>$mail_msg_file
1734	fi
1735	rm -f $build_noise_file
1736
1737	case "$build_ok" in
1738		y)
1739			state=Completed
1740			;;
1741		i)
1742			state=Interrupted
1743			;;
1744		*)
1745	    		state=Failed
1746			;;
1747	esac
1748	NIGHTLY_STATUS=$state
1749	export NIGHTLY_STATUS
1750
1751	run_hook POST_NIGHTLY $state
1752	run_hook SYS_POST_NIGHTLY $state
1753
1754	cat $build_time_file $build_environ_file $mail_msg_file \
1755	    > ${LLOG}/mail_msg
1756	if [ "$m_FLAG" = "y" ]; then
1757	    	cat ${LLOG}/mail_msg | /usr/bin/mailx -s \
1758	"Nightly ${MACH} Build of `basename ${CODEMGR_WS}` ${state}." \
1759			${MAILTO}
1760	fi
1761
1762	if [ "$u_FLAG" = "y" -a "$build_ok" = "y" ]; then
1763	    	staffer cp ${LLOG}/mail_msg $PARENT_WS/usr/src/mail_msg-${MACH}
1764		staffer cp $LOGFILE $PARENT_WS/usr/src/nightly-${MACH}.log
1765	fi
1766
1767	mv $LOGFILE $LLOG
1768}
1769
1770#
1771#	Remove the locks and temporary files on any exit
1772#
1773function cleanup {
1774    	logshuffle
1775
1776	[ -z "$lockfile" ] || staffer rm -f $lockfile
1777	[ -z "$atloglockfile" ] || rm -f $atloglockfile
1778	[ -z "$ulockfile" ] || staffer rm -f $ulockfile
1779	[ -z "$Ulockfile" ] || rm -f $Ulockfile
1780
1781	set -- $newdirlist
1782	while [ $# -gt 0 ]; do
1783		ISUSER=$1 staffer rmdir $2
1784		shift; shift
1785	done
1786	rm -rf $TMPDIR
1787}
1788
1789function cleanup_signal {
1790    	build_ok=i
1791	# this will trigger cleanup(), above.
1792	exit 1
1793}
1794
1795trap cleanup 0
1796trap cleanup_signal 1 2 3 15
1797
1798#
1799# Generic lock file processing -- make sure that the lock file doesn't
1800# exist.  If it does, it should name the build host and PID.  If it
1801# doesn't, then make sure we can create it.  Clean up locks that are
1802# known to be stale (assumes host name is unique among build systems
1803# for the workspace).
1804#
1805function create_lock {
1806	lockf=$1
1807	lockvar=$2
1808
1809	ldir=`dirname $lockf`
1810	[ -d $ldir ] || newdir $ldir || exit 1
1811	eval $lockvar=$lockf
1812
1813	while ! staffer ln -s $hostname.$STAFFER.$$ $lockf 2> /dev/null; do
1814		basews=`basename $CODEMGR_WS`
1815		ls -l $lockf | nawk '{print $NF}' | IFS=. read host user pid
1816		if [ "$host" != "$hostname" ]; then
1817			echo "$MACH build of $basews apparently" \
1818			    "already started by $user on $host as $pid."
1819			exit 1
1820		elif kill -s 0 $pid 2>/dev/null; then
1821			echo "$MACH build of $basews already started" \
1822			    "by $user as $pid."
1823			exit 1
1824		else
1825			# stale lock; clear it out and try again
1826			rm -f $lockf
1827		fi
1828	done
1829}
1830
1831#
1832# Return the list of interesting proto areas, depending on the current
1833# options.
1834#
1835function allprotos {
1836	typeset roots="$ROOT"
1837
1838	if [[ "$F_FLAG" = n && "$MULTI_PROTO" = yes ]]; then
1839		roots="$roots $ROOT-nd"
1840	fi
1841
1842	if [[ $O_FLAG = y ]]; then
1843		roots="$roots $ROOT-closed"
1844		[ $MULTI_PROTO = yes ] && roots="$roots $ROOT-nd-closed"
1845	fi
1846
1847	echo $roots
1848}
1849
1850# Ensure no other instance of this script is running on this host.
1851# LOCKNAME can be set in <env_file>, and is by default, but is not
1852# required due to the use of $ATLOG below.
1853if [ -n "$LOCKNAME" ]; then
1854	create_lock /tmp/$LOCKNAME "lockfile"
1855fi
1856#
1857# Create from one, two, or three other locks:
1858#	$ATLOG/nightly.lock
1859#		- protects against multiple builds in same workspace
1860#	$PARENT_WS/usr/src/nightly.$MACH.lock
1861#		- protects against multiple 'u' copy-backs
1862#	$NIGHTLY_PARENT_ROOT/nightly.lock
1863#		- protects against multiple 'U' copy-backs
1864#
1865# Overriding ISUSER to 1 causes the lock to be created as root if the
1866# script is run as root.  The default is to create it as $STAFFER.
1867ISUSER=1 create_lock $ATLOG/nightly.lock "atloglockfile"
1868if [ "$u_FLAG" = "y" ]; then
1869	create_lock $PARENT_WS/usr/src/nightly.$MACH.lock "ulockfile"
1870fi
1871if [ "$U_FLAG" = "y" ]; then
1872	# NIGHTLY_PARENT_ROOT is written as root if script invoked as root.
1873	ISUSER=1 create_lock $NIGHTLY_PARENT_ROOT/nightly.lock "Ulockfile"
1874fi
1875
1876# Locks have been taken, so we're doing a build and we're committed to
1877# the directories we may have created so far.
1878newdirlist=
1879
1880#
1881# Create mail_msg_file
1882#
1883mail_msg_file="${TMPDIR}/mail_msg"
1884touch $mail_msg_file
1885build_time_file="${TMPDIR}/build_time"
1886build_environ_file="${TMPDIR}/build_environ"
1887touch $build_environ_file
1888#
1889#	Move old LOGFILE aside
1890#	ATLOG directory already made by 'create_lock' above
1891#
1892if [ -f $LOGFILE ]; then
1893	mv -f $LOGFILE ${LOGFILE}-
1894fi
1895#
1896#	Build OsNet source
1897#
1898START_DATE=`date`
1899SECONDS=0
1900echo "\n==== Nightly $maketype build started:   $START_DATE ====" \
1901    | tee -a $LOGFILE > $build_time_file
1902
1903echo "\nBuild project:  $build_project\nBuild taskid:   $build_taskid" | \
1904    tee -a $mail_msg_file >> $LOGFILE
1905
1906# make sure we log only to the nightly build file
1907build_noise_file="${TMPDIR}/build_noise"
1908exec </dev/null >$build_noise_file 2>&1
1909
1910run_hook SYS_PRE_NIGHTLY
1911run_hook PRE_NIGHTLY
1912
1913echo "\n==== list of environment variables ====\n" >> $LOGFILE
1914env >> $LOGFILE
1915
1916echo "\n==== Nightly argument issues ====\n" | tee -a $mail_msg_file >> $LOGFILE
1917
1918if [ "$P_FLAG" = "y" ]; then
1919	obsolete_build GPROF | tee -a $mail_msg_file >> $LOGFILE
1920fi
1921
1922if [ "$T_FLAG" = "y" ]; then
1923	obsolete_build TRACE | tee -a $mail_msg_file >> $LOGFILE
1924fi
1925
1926if is_source_build; then
1927	if [ "$i_FLAG" = "y" -o "$i_CMD_LINE_FLAG" = "y" ]; then
1928		echo "WARNING: the -S flags do not support incremental" \
1929		    "builds; forcing clobber\n" | tee -a $mail_msg_file >> $LOGFILE
1930		i_FLAG=n
1931		i_CMD_LINE_FLAG=n
1932	fi
1933	if [ "$N_FLAG" = "n" ]; then
1934		echo "WARNING: the -S flags do not support protocmp;" \
1935		    "protocmp disabled\n" | \
1936		    tee -a $mail_msg_file >> $LOGFILE
1937		N_FLAG=y
1938	fi
1939	if [ "$l_FLAG" = "y" ]; then
1940		echo "WARNING: the -S flags do not support lint;" \
1941		    "lint disabled\n" | tee -a $mail_msg_file >> $LOGFILE
1942		l_FLAG=n
1943	fi
1944	if [ "$C_FLAG" = "y" ]; then
1945		echo "WARNING: the -S flags do not support cstyle;" \
1946		    "cstyle check disabled\n" | tee -a $mail_msg_file >> $LOGFILE
1947		C_FLAG=n
1948	fi
1949else
1950	if [ "$N_FLAG" = "y" ]; then
1951		if [ "$p_FLAG" = "y" ]; then
1952			cat <<EOF | tee -a $mail_msg_file >> $LOGFILE
1953WARNING: the p option (create packages) is set, but so is the N option (do
1954         not run protocmp); this is dangerous; you should unset the N option
1955EOF
1956		else
1957			cat <<EOF | tee -a $mail_msg_file >> $LOGFILE
1958Warning: the N option (do not run protocmp) is set; it probably shouldn't be
1959EOF
1960		fi
1961		echo "" | tee -a $mail_msg_file >> $LOGFILE
1962	fi
1963fi
1964
1965if [ "$D_FLAG" = "n" -a "$l_FLAG" = "y" ]; then
1966	#
1967	# In the past we just complained but went ahead with the lint
1968	# pass, even though the proto area was built non-DEBUG.  It's
1969	# unlikely that non-DEBUG headers will make a difference, but
1970	# rather than assuming it's a safe combination, force the user
1971	# to specify a DEBUG build.
1972	#
1973	echo "WARNING: DEBUG build not requested; disabling lint.\n" \
1974	    | tee -a $mail_msg_file >> $LOGFILE
1975	l_FLAG=n
1976fi
1977
1978if [ "$f_FLAG" = "y" ]; then
1979	if [ "$i_FLAG" = "y" ]; then
1980		echo "WARNING: the -f flag cannot be used during incremental" \
1981		    "builds; ignoring -f\n" | tee -a $mail_msg_file >> $LOGFILE
1982		f_FLAG=n
1983	fi
1984	if [ "${l_FLAG}${p_FLAG}" != "yy" ]; then
1985		echo "WARNING: the -f flag requires -l, and -p;" \
1986		    "ignoring -f\n" | tee -a $mail_msg_file >> $LOGFILE
1987		f_FLAG=n
1988	fi
1989fi
1990
1991if [ "$w_FLAG" = "y" -a ! -d $ROOT ]; then
1992	echo "WARNING: -w specified, but $ROOT does not exist;" \
1993	    "ignoring -w\n" | tee -a $mail_msg_file >> $LOGFILE
1994	w_FLAG=n
1995fi
1996
1997if [ "$t_FLAG" = "n" ]; then
1998	#
1999	# We're not doing a tools build, so make sure elfsign(1) is
2000	# new enough to safely sign non-crypto binaries.  We test
2001	# debugging output from elfsign to detect the old version.
2002	#
2003	newelfsigntest=`SUNW_CRYPTO_DEBUG=stderr /usr/bin/elfsign verify \
2004	    -e /usr/lib/security/pkcs11_softtoken.so.1 2>&1 \
2005	    | egrep algorithmOID`
2006	if [ -z "$newelfsigntest" ]; then
2007		echo "WARNING: /usr/bin/elfsign out of date;" \
2008		    "will only sign crypto modules\n" | \
2009		    tee -a $mail_msg_file >> $LOGFILE
2010		export ELFSIGN_OBJECT=true
2011	elif [ "$VERIFY_ELFSIGN" = "y" ]; then
2012		echo "WARNING: VERIFY_ELFSIGN=y requires" \
2013		    "the -t flag; ignoring VERIFY_ELFSIGN\n" | \
2014		    tee -a $mail_msg_file >> $LOGFILE
2015	fi
2016fi
2017
2018[ "$O_FLAG" = y ] && MULTI_PROTO=yes
2019
2020case $MULTI_PROTO in
2021yes|no)	;;
2022*)
2023	echo "WARNING: MULTI_PROTO is \"$MULTI_PROTO\"; " \
2024	    "should be \"yes\" or \"no\"." | tee -a $mail_msg_file >> $LOGFILE
2025	echo "Setting MULTI_PROTO to \"no\".\n" | \
2026	    tee -a $mail_msg_file >> $LOGFILE
2027	export MULTI_PROTO=no
2028	;;
2029esac
2030
2031echo "\n==== Build version ====\n" | tee -a $mail_msg_file >> $LOGFILE
2032echo $VERSION | tee -a $mail_msg_file >> $LOGFILE
2033
2034# Save the current proto area if we're comparing against the last build
2035if [ "$w_FLAG" = "y" -a -d "$ROOT" ]; then
2036    if [ -d "$ROOT.prev" ]; then
2037	rm -rf $ROOT.prev
2038    fi
2039    mv $ROOT $ROOT.prev
2040fi
2041
2042# Same for non-DEBUG proto area
2043if [ "$w_FLAG" = "y" -a "$MULTI_PROTO" = yes -a -d "$ROOT-nd" ]; then
2044	if [ -d "$ROOT-nd.prev" ]; then
2045		rm -rf $ROOT-nd.prev
2046	fi
2047	mv $ROOT-nd $ROOT-nd.prev
2048fi
2049
2050#
2051# Echo the SCM type of the parent workspace, this can't just be which_scm
2052# as that does not know how to identify various network repositories.
2053#
2054function parent_wstype {
2055	typeset scm_type junk
2056
2057	CODEMGR_WS="$BRINGOVER_WS" "$WHICH_SCM" 2>/dev/null \
2058	    | read scm_type junk
2059	if [[ -z "$scm_type" || "$scm_type" == unknown ]]; then
2060		# Probe BRINGOVER_WS to determine its type
2061		if [[ $BRINGOVER_WS == svn*://* ]]; then
2062			scm_type="subversion"
2063		elif [[ $BRINGOVER_WS == file://* ]] &&
2064		    egrep -s "This is a Subversion repository" \
2065		    ${BRINGOVER_WS#file://}/README.txt 2> /dev/null; then
2066			scm_type="subversion"
2067		elif [[ $BRINGOVER_WS == ssh://* ]]; then
2068			scm_type="mercurial"
2069		elif [[ $BRINGOVER_WS == http://* ]] && \
2070		    wget -q -O- --save-headers "$BRINGOVER_WS/?cmd=heads" | \
2071		    egrep -s "application/mercurial" 2> /dev/null; then
2072			scm_type="mercurial"
2073		elif svn info $BRINGOVER_WS > /dev/null 2>&1; then
2074			scm_type="subversion"
2075		else
2076			scm_type="none"
2077		fi
2078	fi
2079
2080	# fold both unsupported and unrecognized results into "none"
2081	case "$scm_type" in
2082	none|subversion|teamware|mercurial)
2083		;;
2084	*)	scm_type=none
2085		;;
2086	esac
2087
2088	echo $scm_type
2089}
2090
2091# Echo the SCM types of $CODEMGR_WS and $BRINGOVER_WS
2092function child_wstype {
2093	typeset scm_type junk
2094
2095	# Probe CODEMGR_WS to determine its type
2096	if [[ -d $CODEMGR_WS ]]; then
2097		$WHICH_SCM | read scm_type junk || exit 1
2098	fi
2099
2100	case "$scm_type" in
2101	none|subversion|teamware|mercurial)
2102		;;
2103	*)	scm_type=none
2104		;;
2105	esac
2106
2107	echo $scm_type
2108}
2109
2110export SCM_TYPE=$(child_wstype)
2111
2112#
2113#	Decide whether to clobber
2114#
2115if [ "$i_FLAG" = "n" -a -d "$SRC" ]; then
2116	echo "\n==== Make clobber at `date` ====\n" >> $LOGFILE
2117
2118	cd $SRC
2119	# remove old clobber file
2120	rm -f $SRC/clobber.out
2121	rm -f $SRC/clobber-${MACH}.out
2122
2123	# Remove all .make.state* files, just in case we are restarting
2124	# the build after having interrupted a previous 'make clobber'.
2125	find . \( -name SCCS -o -name .hg -o -name .svn \
2126		-o -name 'interfaces.*' \) -prune \
2127		-o -name '.make.*' -print | xargs rm -f
2128
2129	$MAKE -ek clobber 2>&1 | tee -a $SRC/clobber-${MACH}.out >> $LOGFILE
2130	echo "\n==== Make clobber ERRORS ====\n" >> $mail_msg_file
2131	grep "$MAKE:" $SRC/clobber-${MACH}.out |
2132		egrep -v "Ignoring unknown host" \
2133		>> $mail_msg_file
2134
2135	if [[ "$t_FLAG" = "y" || "$O_FLAG" = "y" ]]; then
2136		echo "\n==== Make tools clobber at `date` ====\n" >> $LOGFILE
2137		cd ${TOOLS}
2138		rm -f ${TOOLS}/clobber-${MACH}.out
2139		$MAKE TOOLS_PROTO=$TOOLS_PROTO -ek clobber 2>&1 | \
2140			tee -a ${TOOLS}/clobber-${MACH}.out >> $LOGFILE
2141		echo "\n==== Make tools clobber ERRORS ====\n" \
2142			>> $mail_msg_file
2143		grep "$MAKE:" ${TOOLS}/clobber-${MACH}.out \
2144			>> $mail_msg_file
2145		rm -rf ${TOOLS_PROTO}
2146		mkdir -p ${TOOLS_PROTO}
2147	fi
2148
2149	typeset roots=$(allprotos)
2150	echo "\n\nClearing $roots" >> "$LOGFILE"
2151	rm -rf $roots
2152
2153	# Get back to a clean workspace as much as possible to catch
2154	# problems that only occur on fresh workspaces.
2155	# Remove all .make.state* files, libraries, and .o's that may
2156	# have been omitted from clobber.  A couple of libraries are
2157	# under source code control, so leave them alone.
2158	# We should probably blow away temporary directories too.
2159	cd $SRC
2160	find $relsrcdirs \( -name SCCS -o -name .hg -o -name .svn \
2161	    -o -name 'interfaces.*' \) -prune -o \
2162	    \( -name '.make.*' -o -name 'lib*.a' -o -name 'lib*.so*' -o \
2163	       -name '*.o' \) -print | \
2164	    grep -v 'tools/ctf/dwarf/.*/libdwarf' | xargs rm -f
2165else
2166	echo "\n==== No clobber at `date` ====\n" >> $LOGFILE
2167fi
2168
2169type bringover_teamware > /dev/null 2>&1 || function bringover_teamware {
2170	# sleep on the parent workspace's lock
2171	while egrep -s write $BRINGOVER_WS/Codemgr_wsdata/locks
2172	do
2173		sleep 120
2174	done
2175
2176	if [[ -z $BRINGOVER ]]; then
2177		BRINGOVER=$TEAMWARE/bin/bringover
2178	fi
2179
2180	staffer $BRINGOVER -c "nightly update" -p $BRINGOVER_WS \
2181	    -w $CODEMGR_WS $BRINGOVER_FILES < /dev/null 2>&1 ||
2182		touch $TMPDIR/bringover_failed
2183
2184        staffer bringovercheck $CODEMGR_WS >$TMPDIR/bringovercheck.out 2>&1
2185	if [ -s $TMPDIR/bringovercheck.out ]; then
2186		echo "\n==== POST-BRINGOVER CLEANUP NOISE ====\n"
2187		cat $TMPDIR/bringovercheck.out
2188	fi
2189}
2190
2191type bringover_mercurial > /dev/null 2>&1 || function bringover_mercurial {
2192	typeset -x PATH=$PATH
2193
2194	# If the repository doesn't exist yet, then we want to populate it.
2195	if [[ ! -d $CODEMGR_WS/.hg ]]; then
2196		staffer hg init $CODEMGR_WS
2197		staffer echo "[paths]" > $CODEMGR_WS/.hg/hgrc
2198		staffer echo "default=$BRINGOVER_WS" >> $CODEMGR_WS/.hg/hgrc
2199		touch $TMPDIR/new_repository
2200	fi
2201
2202	#
2203	# If the user set CLOSED_BRINGOVER_WS and didn't set CLOSED_IS_PRESENT
2204	# to "no," then we'll want to initialise the closed repository
2205	#
2206	# We use $orig_closed_is_present instead of $CLOSED_IS_PRESENT,
2207	# because for newly-created source trees, the latter will be "no"
2208	# until after the bringover completes.
2209	#
2210	if [[ "$orig_closed_is_present" != "no" && \
2211	    -n "$CLOSED_BRINGOVER_WS" && \
2212	    ! -d $CODEMGR_WS/usr/closed/.hg ]]; then
2213		staffer mkdir -p $CODEMGR_WS/usr/closed
2214		staffer hg init $CODEMGR_WS/usr/closed
2215		staffer echo "[paths]" > $CODEMGR_WS/usr/closed/.hg/hgrc
2216		staffer echo "default=$CLOSED_BRINGOVER_WS" >> $CODEMGR_WS/usr/closed/.hg/hgrc
2217		touch $TMPDIR/new_closed
2218		export CLOSED_IS_PRESENT=yes
2219	fi
2220
2221	typeset -x HGMERGE="/bin/false"
2222
2223	#
2224	# If the user has changes, regardless of whether those changes are
2225	# committed, and regardless of whether those changes conflict, then
2226	# we'll attempt to merge them either implicitly (uncommitted) or
2227	# explicitly (committed).
2228	#
2229	# These are the messages we'll use to help clarify mercurial output
2230	# in those cases.
2231	#
2232	typeset mergefailmsg="\
2233***\n\
2234*** nightly was unable to automatically merge your changes.  You should\n\
2235*** redo the full merge manually, following the steps outlined by mercurial\n\
2236*** above, then restart nightly.\n\
2237***\n"
2238	typeset mergepassmsg="\
2239***\n\
2240*** nightly successfully merged your changes.  This means that your working\n\
2241*** directory has been updated, but those changes are not yet committed.\n\
2242*** After nightly completes, you should validate the results of the merge,\n\
2243*** then use hg commit manually.\n\
2244***\n"
2245
2246	#
2247	# For each repository in turn:
2248	#
2249	# 1. Do the pull.  If this fails, dump the output and bail out.
2250	#
2251	# 2. If the pull resulted in an extra head, do an explicit merge.
2252	#    If this fails, dump the output and bail out.
2253	#
2254	# Because we can't rely on Mercurial to exit with a failure code
2255	# when a merge fails (Mercurial issue #186), we must grep the
2256	# output of pull/merge to check for attempted and/or failed merges.
2257	#
2258	# 3. If a merge failed, set the message and fail the bringover.
2259	#
2260	# 4. Otherwise, if a merge succeeded, set the message
2261	#
2262	# 5. Dump the output, and any message from step 3 or 4.
2263	#
2264
2265	typeset HG_SOURCE=$BRINGOVER_WS
2266	if [ ! -f $TMPDIR/new_repository ]; then
2267		HG_SOURCE=$TMPDIR/open_bundle.hg
2268		staffer hg --cwd $CODEMGR_WS incoming --bundle $HG_SOURCE \
2269		    -v $BRINGOVER_WS > $TMPDIR/incoming_open.out
2270
2271		#
2272		# If there are no incoming changesets, then incoming will
2273		# fail, and there will be no bundle file.  Reset the source,
2274		# to allow the remaining logic to complete with no false
2275		# negatives.  (Unlike incoming, pull will return success
2276		# for the no-change case.)
2277		#
2278		if (( $? != 0 )); then
2279			HG_SOURCE=$BRINGOVER_WS
2280		fi
2281	fi
2282
2283	staffer hg --cwd $CODEMGR_WS pull -u $HG_SOURCE \
2284	    > $TMPDIR/pull_open.out 2>&1
2285	if (( $? != 0 )); then
2286		printf "%s: pull failed as follows:\n\n" "$CODEMGR_WS"
2287		cat $TMPDIR/pull_open.out
2288		if grep "^merging.*failed" $TMPDIR/pull_open.out > /dev/null 2>&1; then
2289			printf "$mergefailmsg"
2290		fi
2291		touch $TMPDIR/bringover_failed
2292		return
2293	fi
2294
2295	if grep "not updating" $TMPDIR/pull_open.out > /dev/null 2>&1; then
2296		staffer hg --cwd $CODEMGR_WS merge \
2297		    >> $TMPDIR/pull_open.out 2>&1
2298		if (( $? != 0 )); then
2299			printf "%s: merge failed as follows:\n\n" \
2300			    "$CODEMGR_WS"
2301			cat $TMPDIR/pull_open.out
2302			if grep "^merging.*failed" $TMPDIR/pull_open.out \
2303			    > /dev/null 2>&1; then
2304				printf "$mergefailmsg"
2305			fi
2306			touch $TMPDIR/bringover_failed
2307			return
2308		fi
2309	fi
2310
2311	printf "updated %s with the following results:\n" "$CODEMGR_WS"
2312	cat $TMPDIR/pull_open.out
2313	if grep "^merging" $TMPDIR/pull_open.out >/dev/null 2>&1; then
2314		printf "$mergepassmsg"
2315	fi
2316	printf "\n"
2317
2318	#
2319	# We only want to update usr/closed if it exists, and we haven't been
2320	# told not to via $CLOSED_IS_PRESENT, and we actually know where to
2321	# pull from ($CLOSED_BRINGOVER_WS).
2322	#
2323	if [[ $CLOSED_IS_PRESENT = yes && \
2324	    -d $CODEMGR_WS/usr/closed/.hg && \
2325	    -n $CLOSED_BRINGOVER_WS ]]; then
2326
2327		HG_SOURCE=$CLOSED_BRINGOVER_WS
2328		if [ ! -f $TMPDIR/new_closed ]; then
2329			HG_SOURCE=$TMPDIR/closed_bundle.hg
2330			staffer hg --cwd $CODEMGR_WS/usr/closed incoming \
2331			    --bundle $HG_SOURCE -v $CLOSED_BRINGOVER_WS \
2332			    > $TMPDIR/incoming_closed.out
2333
2334			#
2335			# If there are no incoming changesets, then incoming will
2336			# fail, and there will be no bundle file.  Reset the source,
2337			# to allow the remaining logic to complete with no false
2338			# negatives.  (Unlike incoming, pull will return success
2339			# for the no-change case.)
2340			#
2341			if (( $? != 0 )); then
2342				HG_SOURCE=$CLOSED_BRINGOVER_WS
2343			fi
2344		fi
2345
2346		staffer hg --cwd $CODEMGR_WS/usr/closed pull -u \
2347			$HG_SOURCE > $TMPDIR/pull_closed.out 2>&1
2348		if (( $? != 0 )); then
2349			printf "closed pull failed as follows:\n\n"
2350			cat $TMPDIR/pull_closed.out
2351			if grep "^merging.*failed" $TMPDIR/pull_closed.out \
2352			    > /dev/null 2>&1; then
2353				printf "$mergefailmsg"
2354			fi
2355			touch $TMPDIR/bringover_failed
2356			return
2357		fi
2358
2359		if grep "not updating" $TMPDIR/pull_closed.out > /dev/null 2>&1; then
2360			staffer hg --cwd $CODEMGR_WS/usr/closed merge \
2361			    >> $TMPDIR/pull_closed.out 2>&1
2362			if (( $? != 0 )); then
2363				printf "closed merge failed as follows:\n\n"
2364				cat $TMPDIR/pull_closed.out
2365				if grep "^merging.*failed" $TMPDIR/pull_closed.out > /dev/null 2>&1; then
2366					printf "$mergefailmsg"
2367				fi
2368				touch $TMPDIR/bringover_failed
2369				return
2370			fi
2371		fi
2372
2373		printf "updated %s with the following results:\n" \
2374		    "$CODEMGR_WS/usr/closed"
2375		cat $TMPDIR/pull_closed.out
2376		if grep "^merging" $TMPDIR/pull_closed.out > /dev/null 2>&1; then
2377			printf "$mergepassmsg"
2378		fi
2379	fi
2380
2381	#
2382	# Per-changeset output is neither useful nor manageable for a
2383	# newly-created repository.
2384	#
2385	if [ -f $TMPDIR/new_repository ]; then
2386		return
2387	fi
2388
2389	printf "\nadded the following changesets to open repository:\n"
2390	cat $TMPDIR/incoming_open.out
2391
2392	#
2393	# The closed repository could have been newly created, even though
2394	# the open one previously existed...
2395	#
2396	if [ -f $TMPDIR/new_closed ]; then
2397		return
2398	fi
2399
2400	if [ -f $TMPDIR/incoming_closed.out ]; then
2401		printf "\nadded the following changesets to closed repository:\n"
2402		cat $TMPDIR/incoming_closed.out
2403	fi
2404}
2405
2406type bringover_subversion > /dev/null 2>&1 || function bringover_subversion {
2407	typeset -x PATH=$PATH
2408
2409	if [[ ! -d $CODEMGR_WS/.svn ]]; then
2410		staffer svn checkout $BRINGOVER_WS $CODEMGR_WS ||
2411			touch $TMPDIR/bringover_failed
2412	else
2413		typeset root
2414		root=$(staffer svn info $CODEMGR_WS |
2415			nawk '/^Repository Root:/ {print $NF}')
2416		if [[ $root != $BRINGOVER_WS ]]; then
2417			# We fail here because there's no way to update
2418			# from a named repo.
2419			cat <<-EOF
2420			\$BRINGOVER_WS doesn't match repository root:
2421			  \$BRINGOVER_WS:  $BRINGOVER_WS
2422			  Repository root: $root
2423			EOF
2424			touch $TMPDIR/bringover_failed
2425		else
2426			# If a conflict happens, svn still exits 0.
2427			staffer svn update $CODEMGR_WS | tee $TMPDIR/pull.out ||
2428				touch $TMPDIR/bringover_failed
2429			if grep "^C" $TMPDIR/pull.out > /dev/null 2>&1; then
2430				touch $TMPDIR/bringover_failed
2431			fi
2432		fi
2433	fi
2434}
2435
2436type bringover_none > /dev/null 2>&1 || function bringover_none {
2437	echo "Couldn't figure out what kind of SCM to use for $BRINGOVER_WS."
2438	touch $TMPDIR/bringover_failed
2439}
2440
2441#
2442#	Decide whether to bringover to the codemgr workspace
2443#
2444if [ "$n_FLAG" = "n" ]; then
2445	PARENT_SCM_TYPE=$(parent_wstype)
2446
2447	if [[ $SCM_TYPE != none && $SCM_TYPE != $PARENT_SCM_TYPE ]]; then
2448		echo "cannot bringover from $PARENT_SCM_TYPE to $SCM_TYPE, " \
2449		    "quitting at `date`." | tee -a $mail_msg_file >> $LOGFILE
2450		exit 1
2451	fi
2452
2453	run_hook PRE_BRINGOVER
2454
2455	echo "\n==== bringover to $CODEMGR_WS at `date` ====\n" >> $LOGFILE
2456	echo "\n==== BRINGOVER LOG ====\n" >> $mail_msg_file
2457
2458	eval "bringover_${PARENT_SCM_TYPE}" 2>&1 |
2459		tee -a $mail_msg_file >> $LOGFILE
2460
2461	if [ -f $TMPDIR/bringover_failed ]; then
2462		rm -f $TMPDIR/bringover_failed
2463		build_ok=n
2464		echo "trouble with bringover, quitting at `date`." |
2465			tee -a $mail_msg_file >> $LOGFILE
2466		exit 1
2467	fi
2468
2469	#
2470	# It's possible that we used the bringover above to create
2471	# $CODEMGR_WS.  If so, then SCM_TYPE was previously "none,"
2472	# but should now be the same as $BRINGOVER_WS.
2473	#
2474	[[ $SCM_TYPE = none ]] && SCM_TYPE=$PARENT_SCM_TYPE
2475
2476	run_hook POST_BRINGOVER
2477
2478	#
2479	# Possible transition from pre-split workspace to split
2480	# workspace.  See if the bringover changed anything.
2481	#
2482	CLOSED_IS_PRESENT="$orig_closed_is_present"
2483	check_closed_tree
2484
2485else
2486	echo "\n==== No bringover to $CODEMGR_WS ====\n" >> $LOGFILE
2487fi
2488
2489if [[ "$O_FLAG" = y && "$CLOSED_IS_PRESENT" != "yes" ]]; then
2490	build_ok=n
2491	echo "OpenSolaris binary deliverables need usr/closed." \
2492	    | tee -a "$mail_msg_file" >> $LOGFILE
2493	exit 1
2494fi
2495
2496echo "\n==== Build environment ====\n" | tee -a $build_environ_file >> $LOGFILE
2497
2498# System
2499whence uname | tee -a $build_environ_file >> $LOGFILE
2500uname -a 2>&1 | tee -a $build_environ_file >> $LOGFILE
2501echo | tee -a $build_environ_file >> $LOGFILE
2502
2503# nightly
2504echo "$0 $@" | tee -a $build_environ_file >> $LOGFILE
2505if [[ $nightly_path = "/opt/onbld/bin/nightly" ]]; then
2506	# We assume that if you have /opt/onbld/bin/nightly, then
2507	# you have some form of the onbld package installed. If this
2508	# is not true then your nightly is almost definitely out of
2509	# date and should not be used.
2510	/usr/bin/pkg info \*onbld\* | \
2511	    egrep "Name:|Publisher:|Version:|Packaging:|FMRI:"
2512else
2513	echo "$nightly_ls"
2514fi | tee -a $build_environ_file >> $LOGFILE
2515echo | tee -a $build_environ_file >> $LOGFILE
2516
2517# make
2518whence $MAKE | tee -a $build_environ_file >> $LOGFILE
2519$MAKE -v | tee -a $build_environ_file >> $LOGFILE
2520echo "number of concurrent jobs = $DMAKE_MAX_JOBS" |
2521    tee -a $build_environ_file >> $LOGFILE
2522
2523#
2524# Report the compiler versions.
2525#
2526
2527if [[ ! -f $SRC/Makefile ]]; then
2528	build_ok=n
2529	echo "\nUnable to find \"Makefile\" in $SRC." | \
2530	    tee -a $build_environ_file >> $LOGFILE
2531	exit 1
2532fi
2533
2534( cd $SRC
2535  for target in cc-version cc64-version java-version; do
2536	echo
2537	#
2538	# Put statefile somewhere we know we can write to rather than trip
2539	# over a read-only $srcroot.
2540	#
2541	rm -f $TMPDIR/make-state
2542	export SRC
2543	if $MAKE -K $TMPDIR/make-state -e $target 2>/dev/null; then
2544		continue
2545	fi
2546	touch $TMPDIR/nocompiler
2547  done
2548  echo
2549) | tee -a $build_environ_file >> $LOGFILE
2550
2551if [ -f $TMPDIR/nocompiler ]; then
2552	rm -f $TMPDIR/nocompiler
2553	build_ok=n
2554	echo "Aborting due to missing compiler." |
2555		tee -a $build_environ_file >> $LOGFILE
2556	exit 1
2557fi
2558
2559# as
2560whence as | tee -a $build_environ_file >> $LOGFILE
2561as -V 2>&1 | head -1 | tee -a $build_environ_file >> $LOGFILE
2562echo | tee -a $build_environ_file >> $LOGFILE
2563
2564# Check that we're running a capable link-editor
2565whence ld | tee -a $build_environ_file >> $LOGFILE
2566LDVER=`ld -V 2>&1`
2567echo $LDVER | tee -a $build_environ_file >> $LOGFILE
2568LDVER=`echo $LDVER | sed -e "s/.*-1\.//" -e "s/:.*//"`
2569if [ `expr $LDVER \< 422` -eq 1 ]; then
2570	echo "The link-editor needs to be at version 422 or higher to build" | \
2571	    tee -a $build_environ_file >> $LOGFILE
2572	echo "the latest stuff.  Hope your build works." | \
2573	    tee -a $build_environ_file >> $LOGFILE
2574fi
2575
2576#
2577# Build and use the workspace's tools if requested
2578#
2579if [[ "$t_FLAG" = "y" || "$O_FLAG" = y ]]; then
2580	set_non_debug_build_flags
2581
2582	build_tools ${TOOLS_PROTO}
2583	if [[ $? != 0  && "$t_FLAG" = y ]]; then
2584		use_tools $TOOLS_PROTO
2585	fi
2586fi
2587
2588#
2589# copy ihv proto area in addition to the build itself
2590#
2591if [ "$X_FLAG" = "y" ]; then
2592	copy_ihv_proto
2593fi
2594
2595if [ "$i_FLAG" = "y" -a "$SH_FLAG" = "y" ]; then
2596	echo "\n==== NOT Building base OS-Net source ====\n" | \
2597	    tee -a $LOGFILE >> $mail_msg_file
2598else
2599	# timestamp the start of the normal build; the findunref tool uses it.
2600	touch $SRC/.build.tstamp
2601
2602	normal_build
2603fi
2604
2605#
2606# Generate the THIRDPARTYLICENSE files if needed.  This is done after
2607# the build, so that dynamically-created license files are there.
2608# It's done before findunref to help identify license files that need
2609# to be added to tools/opensolaris/license-list.
2610#
2611if [ "$O_FLAG" = y -a "$build_ok" = y ]; then
2612	echo "\n==== Generating THIRDPARTYLICENSE files ====\n" |
2613	    tee -a "$mail_msg_file" >> "$LOGFILE"
2614
2615	if [ -d $ROOT/licenses/usr ]; then
2616		( cd $ROOT/licenses ; \
2617		    mktpl $SRC/pkg/license-list ) >> "$LOGFILE" 2>&1
2618		if (( $? != 0 )) ; then
2619			echo "Couldn't create THIRDPARTYLICENSE files" |
2620			    tee -a "$mail_msg_file" >> "$LOGFILE"
2621		fi
2622	else
2623		echo "No licenses found under $ROOT/licenses" |
2624		    tee -a "$mail_msg_file" >> "$LOGFILE"
2625	fi
2626fi
2627
2628ORIG_SRC=$SRC
2629BINARCHIVE=${CODEMGR_WS}/bin-${MACH}.cpio.Z
2630
2631if [ "$SE_FLAG" = "y" -o "$SD_FLAG" = "y" -o "$SH_FLAG" = "y" ]; then
2632	save_binaries
2633fi
2634
2635
2636# EXPORT_SRC comes after CRYPT_SRC since a domestic build will need
2637# $SRC pointing to the export_source usr/src.
2638
2639if [ "$SE_FLAG" = "y" -o "$SD_FLAG" = "y" -o "$SH_FLAG" = "y" ]; then
2640	if [ "$SD_FLAG" = "y" -a $build_ok = y ]; then
2641	    set_up_source_build ${CODEMGR_WS} ${CRYPT_SRC} CRYPT_SRC
2642	fi
2643
2644	if [ $build_ok = y ]; then
2645	    set_up_source_build ${CODEMGR_WS} ${EXPORT_SRC} EXPORT_SRC
2646	fi
2647fi
2648
2649if [ "$SD_FLAG" = "y" -a $build_ok = y ]; then
2650	# drop the crypt files in place.
2651	cd ${EXPORT_SRC}
2652	echo "\nextracting crypt_files.cpio.Z onto export_source.\n" \
2653	    >> ${LOGFILE}
2654	zcat ${CODEMGR_WS}/crypt_files.cpio.Z | \
2655	    cpio -idmucvB 2>/dev/null >> ${LOGFILE}
2656	if [ "$?" = "0" ]; then
2657		echo "\n==== DOMESTIC extraction succeeded ====\n" \
2658		    >> $mail_msg_file
2659	else
2660		echo "\n==== DOMESTIC extraction failed ====\n" \
2661		    >> $mail_msg_file
2662	fi
2663
2664fi
2665
2666if [ "$SO_FLAG" = "y" -a "$build_ok" = y ]; then
2667	#
2668	# Copy the open sources into their own tree, set up the closed
2669	# binaries, and set up the environment.  The build looks for
2670	# the closed binaries in a location that depends on whether
2671	# it's a DEBUG build, so we might need to make two copies.
2672	#
2673	# If copy_source fails, it will have already generated an
2674	# error message and set build_ok=n, so we don't need to worry
2675	# about that here.
2676	#
2677	copy_source $CODEMGR_WS $OPEN_SRCDIR OPEN_SOURCE usr/src
2678fi
2679
2680if [ "$SO_FLAG" = "y" -a "$build_ok" = y ]; then
2681
2682	echo "\n==== Generating skeleton closed binaries for" \
2683	    "open-only build ====\n" | \
2684	    tee -a $LOGFILE >> $mail_msg_file
2685
2686	rm -rf $CODEMGR_WS/closed.skel
2687	if [ "$D_FLAG" = y ]; then
2688		mkclosed $MACH $ROOT $CODEMGR_WS/closed.skel/root_$MACH \
2689		    >>$LOGFILE 2>&1
2690		if (( $? != 0 )) ; then
2691			echo "Couldn't create skeleton DEBUG closed binaries." |
2692			    tee -a $mail_msg_file >> $LOGFILE
2693		fi
2694	fi
2695	if [ "$F_FLAG" = n ]; then
2696		root=$ROOT
2697		[ "$MULTI_PROTO" = yes ] && root=$ROOT-nd
2698		mkclosed $MACH $root $CODEMGR_WS/closed.skel/root_$MACH-nd \
2699		    >>$LOGFILE 2>&1
2700		if (( $? != 0 )) ; then
2701			echo "Couldn't create skeleton non-DEBUG closed binaries." |
2702			    tee -a $mail_msg_file >> $LOGFILE
2703		fi
2704	fi
2705
2706	SRC=$OPEN_SRCDIR/usr/src
2707	# Try not to clobber any user-provided closed binaries.
2708	export ON_CLOSED_BINS=$CODEMGR_WS/closed.skel
2709	export CLOSED_IS_PRESENT=no
2710fi
2711
2712if is_source_build && [ $build_ok = y ] ; then
2713	# remove proto area(s) here, since we don't clobber
2714	rm -rf `allprotos`
2715	if [ "$t_FLAG" = "y" ]; then
2716		set_non_debug_build_flags
2717		ORIG_TOOLS=$TOOLS
2718		#
2719		# SRC was set earlier to point to the source build
2720		# source tree (e.g., $EXPORT_SRC).
2721		#
2722		TOOLS=${SRC}/tools
2723		TOOLS_PROTO=${TOOLS}/${TOOLS_PROTO_REL}; export TOOLS_PROTO
2724		build_tools ${TOOLS_PROTO}
2725		if [[ $? != 0 ]]; then
2726			use_tools ${TOOLS_PROTO}
2727		fi
2728	fi
2729
2730	export EXPORT_RELEASE_BUILD ; EXPORT_RELEASE_BUILD=#
2731	normal_build
2732fi
2733
2734if [[ "$SO_FLAG" = "y" && "$build_ok" = "y" ]]; then
2735	rm -rf $ON_CLOSED_BINS
2736fi
2737
2738#
2739# There are several checks that need to look at the proto area, but
2740# they only need to look at one, and they don't care whether it's
2741# DEBUG or non-DEBUG.
2742#
2743if [[ "$MULTI_PROTO" = yes && "$D_FLAG" = n ]]; then
2744	checkroot=$ROOT-nd
2745else
2746	checkroot=$ROOT
2747fi
2748
2749if [ "$build_ok" = "y" ]; then
2750	echo "\n==== Creating protolist system file at `date` ====" \
2751		>> $LOGFILE
2752	protolist $checkroot > $ATLOG/proto_list_${MACH}
2753	echo "==== protolist system file created at `date` ====\n" \
2754		>> $LOGFILE
2755
2756	if [ "$N_FLAG" != "y" ]; then
2757
2758		E1=
2759		f1=
2760		if [ -d "$SRC/pkgdefs" ]; then
2761			f1="$SRC/pkgdefs/etc/exception_list_$MACH"
2762			if [ "$X_FLAG" = "y" ]; then
2763				f1="$f1 $IA32_IHV_WS/usr/src/pkgdefs/etc/exception_list_$MACH"
2764			fi
2765		fi
2766
2767		for f in $f1; do
2768			if [ -f "$f" ]; then
2769				E1="$E1 -e $f"
2770			fi
2771		done
2772
2773		E2=
2774		f2=
2775		if [ -d "$SRC/pkg" ]; then
2776			f2="$f2 exceptions/packaging"
2777			if [ "$CLOSED_IS_PRESENT" = "no" ]; then
2778				f2="$f2 exceptions/packaging.open"
2779			else
2780				f2="$f2 exceptions/packaging.closed"
2781			fi
2782		fi
2783
2784		for f in $f2; do
2785			if [ -f "$f" ]; then
2786				E2="$E2 -e $f"
2787			fi
2788		done
2789
2790		if [ -f "$REF_PROTO_LIST" ]; then
2791			#
2792			# For builds that copy the IHV proto area (-X), add the
2793			# IHV proto list to the reference list if the reference
2794			# was built without -X.
2795			#
2796			# For builds that don't copy the IHV proto area, add the
2797			# IHV proto list to the build's proto list if the
2798			# reference was built with -X.
2799			#
2800			# Use the presence of the first file entry of the cached
2801			# IHV proto list in the reference list to determine
2802			# whether it was built with -X or not.
2803			#
2804			IHV_REF_PROTO_LIST=$SRC/pkg/proto_list_ihv_$MACH
2805			grepfor=$(nawk '$1 == "f" { print $2; exit }' \
2806				$IHV_REF_PROTO_LIST 2> /dev/null)
2807			if [ $? = 0 -a -n "$grepfor" ]; then
2808				if [ "$X_FLAG" = "y" ]; then
2809					grep -w "$grepfor" \
2810						$REF_PROTO_LIST > /dev/null
2811					if [ ! "$?" = "0" ]; then
2812						REF_IHV_PROTO="-d $IHV_REF_PROTO_LIST"
2813					fi
2814				else
2815					grep -w "$grepfor" \
2816						$REF_PROTO_LIST > /dev/null
2817					if [ "$?" = "0" ]; then
2818						IHV_PROTO_LIST="$IHV_REF_PROTO_LIST"
2819					fi
2820				fi
2821			fi
2822		fi
2823	fi
2824
2825	if [ "$N_FLAG" != "y" -a -f $SRC/pkgdefs/Makefile ]; then
2826		echo "\n==== Impact on SVr4 packages ====\n" >> $mail_msg_file
2827		#
2828		# Compare the build's proto list with current package
2829		# definitions to audit the quality of package
2830		# definitions and makefile install targets. Use the
2831		# current exception list.
2832		#
2833		PKGDEFS_LIST=""
2834		for d in $abssrcdirs; do
2835			if [ -d $d/pkgdefs ]; then
2836				PKGDEFS_LIST="$PKGDEFS_LIST -d $d/pkgdefs"
2837			fi
2838		done
2839		if [ "$X_FLAG" = "y" -a \
2840		    -d $IA32_IHV_WS/usr/src/pkgdefs ]; then
2841			PKGDEFS_LIST="$PKGDEFS_LIST -d $IA32_IHV_WS/usr/src/pkgdefs"
2842		fi
2843		$PROTOCMPTERSE \
2844		    "Files missing from the proto area:" \
2845		    "Files missing from packages:" \
2846		    "Inconsistencies between pkgdefs and proto area:" \
2847		    ${E1} \
2848		    ${PKGDEFS_LIST} \
2849		    $ATLOG/proto_list_${MACH} \
2850		    >> $mail_msg_file
2851	fi
2852
2853	if [ "$N_FLAG" != "y" -a -d $SRC/pkg ]; then
2854		echo "\n==== Validating manifests against proto area ====\n" \
2855		    >> $mail_msg_file
2856		( cd $SRC/pkg ; $MAKE -e protocmp ROOT="$checkroot" ) \
2857		    >> $mail_msg_file
2858
2859	fi
2860
2861	if [ "$N_FLAG" != "y" -a -f "$REF_PROTO_LIST" ]; then
2862		echo "\n==== Impact on proto area ====\n" >> $mail_msg_file
2863		if [ -n "$E2" ]; then
2864			ELIST=$E2
2865		else
2866			ELIST=$E1
2867		fi
2868		$PROTOCMPTERSE \
2869			"Files in yesterday's proto area, but not today's:" \
2870			"Files in today's proto area, but not yesterday's:" \
2871			"Files that changed between yesterday and today:" \
2872			${ELIST} \
2873			-d $REF_PROTO_LIST \
2874			$REF_IHV_PROTO \
2875			$ATLOG/proto_list_${MACH} \
2876			$IHV_PROTO_LIST \
2877			>> $mail_msg_file
2878	fi
2879fi
2880
2881if [ "$u_FLAG" = "y"  -a "$build_ok" = "y" ]; then
2882	staffer cp $ATLOG/proto_list_${MACH} \
2883		$PARENT_WS/usr/src/proto_list_${MACH}
2884fi
2885
2886# Update parent proto area if necessary. This is done now
2887# so that the proto area has either DEBUG or non-DEBUG kernels.
2888# Note that this clears out the lock file, so we can dispense with
2889# the variable now.
2890if [ "$U_FLAG" = "y" -a "$build_ok" = "y" ]; then
2891	echo "\n==== Copying proto area to $NIGHTLY_PARENT_ROOT ====\n" | \
2892	    tee -a $LOGFILE >> $mail_msg_file
2893	rm -rf $NIGHTLY_PARENT_ROOT/*
2894	unset Ulockfile
2895	mkdir -p $NIGHTLY_PARENT_ROOT
2896	if [[ "$MULTI_PROTO" = no || "$D_FLAG" = y ]]; then
2897		( cd $ROOT; tar cf - . |
2898		    ( cd $NIGHTLY_PARENT_ROOT;  umask 0; tar xpf - ) ) 2>&1 |
2899		    tee -a $mail_msg_file >> $LOGFILE
2900	fi
2901	if [[ "$MULTI_PROTO" = yes && "$F_FLAG" = n ]]; then
2902		rm -rf $NIGHTLY_PARENT_ROOT-nd/*
2903		mkdir -p $NIGHTLY_PARENT_ROOT-nd
2904		cd $ROOT-nd
2905		( tar cf - . |
2906		    ( cd $NIGHTLY_PARENT_ROOT-nd; umask 0; tar xpf - ) ) 2>&1 |
2907		    tee -a $mail_msg_file >> $LOGFILE
2908	fi
2909	if [ -n "${NIGHTLY_PARENT_TOOLS_ROOT}" ]; then
2910		echo "\n==== Copying tools proto area to $NIGHTLY_PARENT_TOOLS_ROOT ====\n" | \
2911		    tee -a $LOGFILE >> $mail_msg_file
2912		rm -rf $NIGHTLY_PARENT_TOOLS_ROOT/*
2913		mkdir -p $NIGHTLY_PARENT_TOOLS_ROOT
2914		if [[ "$MULTI_PROTO" = no || "$D_FLAG" = y ]]; then
2915			( cd $TOOLS_PROTO; tar cf - . |
2916			    ( cd $NIGHTLY_PARENT_TOOLS_ROOT;
2917			    umask 0; tar xpf - ) ) 2>&1 |
2918			    tee -a $mail_msg_file >> $LOGFILE
2919		fi
2920	fi
2921fi
2922
2923#
2924# ELF verification: ABI (-A) and runtime (-r) checks
2925#
2926if [[ ($build_ok = y) && ( ($A_FLAG = y) || ($r_FLAG = y) ) ]]; then
2927	# Directory ELF-data.$MACH holds the files produced by these tests.
2928	elf_ddir=$SRC/ELF-data.$MACH
2929
2930	# If there is a previous ELF-data backup directory, remove it. Then,
2931	# rotate current ELF-data directory into its place and create a new
2932	# empty directory
2933	rm -rf $elf_ddir.ref
2934	if [[ -d $elf_ddir ]]; then
2935		mv $elf_ddir $elf_ddir.ref
2936	fi
2937	mkdir -p $elf_ddir
2938
2939	# Call find_elf to produce a list of the ELF objects in the proto area.
2940	# This list is passed to check_rtime and interface_check, preventing
2941	# them from separately calling find_elf to do the same work twice.
2942	find_elf -fr $checkroot > $elf_ddir/object_list
2943
2944	if [[ $A_FLAG = y ]]; then
2945	       	echo "\n==== Check versioning and ABI information ====\n"  | \
2946		    tee -a $LOGFILE >> $mail_msg_file
2947
2948		# Produce interface description for the proto. Report errors.
2949		interface_check -o -w $elf_ddir -f object_list \
2950			-i interface -E interface.err
2951		if [[ -s $elf_ddir/interface.err ]]; then
2952			tee -a $LOGFILE < $elf_ddir/interface.err \
2953				>> $mail_msg_file
2954		fi
2955
2956		# If ELF_DATA_BASELINE_DIR is defined, compare the new interface
2957		# description file to that from the baseline gate. Issue a
2958		# warning if the baseline is not present, and keep going.
2959		if [[ "$ELF_DATA_BASELINE_DIR" != '' ]]; then
2960			base_ifile="$ELF_DATA_BASELINE_DIR/interface"
2961
2962		       	echo "\n==== Compare versioning and ABI information" \
2963			    "to baseline ====\n"  | \
2964			    tee -a $LOGFILE >> $mail_msg_file
2965		       	echo "Baseline:  $base_ifile\n" >> $LOGFILE
2966
2967			if [[ -f $base_ifile ]]; then
2968				interface_cmp -d -o $base_ifile \
2969				    $elf_ddir/interface > $elf_ddir/interface.cmp
2970				if [[ -s $elf_ddir/interface.cmp ]]; then
2971					echo | tee -a $LOGFILE >> $mail_msg_file
2972					tee -a $LOGFILE < \
2973					    $elf_ddir/interface.cmp \
2974					    >> $mail_msg_file
2975				fi
2976			else
2977			       	echo "baseline not available. comparison" \
2978                                    "skipped" | \
2979				    tee -a $LOGFILE >> $mail_msg_file
2980			fi
2981
2982		fi
2983	fi
2984
2985	if [[ $r_FLAG = y ]]; then
2986		echo "\n==== Check ELF runtime attributes ====\n" | \
2987		    tee -a $LOGFILE >> $mail_msg_file
2988
2989		# If we're doing a DEBUG build the proto area will be left
2990		# with debuggable objects, thus don't assert -s.
2991		if [[ $D_FLAG = y ]]; then
2992			rtime_sflag=""
2993		else
2994			rtime_sflag="-s"
2995		fi
2996		check_rtime -i -m -v $rtime_sflag -o -w $elf_ddir \
2997			-D object_list  -f object_list -E runtime.err \
2998			-I runtime.attr.raw
2999
3000		# check_rtime -I output needs to be sorted in order to
3001		# compare it to that from previous builds.
3002		sort $elf_ddir/runtime.attr.raw > $elf_ddir/runtime.attr
3003		rm $elf_ddir/runtime.attr.raw
3004
3005		# Report errors
3006		if [[ -s $elf_ddir/runtime.err ]]; then
3007			tee -a $LOGFILE < $elf_ddir/runtime.err \
3008				>> $mail_msg_file
3009		fi
3010
3011		# If there is an ELF-data directory from a previous build,
3012		# then diff the attr files. These files contain information
3013		# about dependencies, versioning, and runpaths. There is some
3014		# overlap with the ABI checking done above, but this also
3015		# flushes out non-ABI interface differences along with the
3016		# other information.
3017		echo "\n==== Diff ELF runtime attributes" \
3018		    "(since last build) ====\n" | \
3019		    tee -a $LOGFILE >> $mail_msg_file >> $mail_msg_file
3020
3021		if [[ -f $elf_ddir.ref/runtime.attr ]]; then
3022			diff $elf_ddir.ref/runtime.attr \
3023				$elf_ddir/runtime.attr \
3024				>> $mail_msg_file
3025		fi
3026	fi
3027
3028	# If -u set, copy contents of ELF-data.$MACH to the parent workspace.
3029	if [[ "$u_FLAG" = "y" ]]; then
3030		p_elf_ddir=$PARENT_WS/usr/src/ELF-data.$MACH
3031
3032		# If parent lacks the ELF-data.$MACH directory, create it
3033		if [[ ! -d $p_elf_ddir ]]; then
3034			staffer mkdir -p $p_elf_ddir
3035		fi
3036
3037		# These files are used asynchronously by other builds for ABI
3038		# verification, as above for the -A option. As such, we require
3039		# the file replacement to be atomic. Copy the data to a temp
3040		# file in the same filesystem and then rename into place.
3041		(
3042			cd $elf_ddir
3043			for elf_dfile in *; do
3044				staffer cp $elf_dfile \
3045				    ${p_elf_ddir}/${elf_dfile}.new
3046				staffer mv -f ${p_elf_ddir}/${elf_dfile}.new \
3047				    ${p_elf_ddir}/${elf_dfile}
3048			done
3049		)
3050	fi
3051fi
3052
3053# DEBUG lint of kernel begins
3054
3055if [ "$i_CMD_LINE_FLAG" = "n" -a "$l_FLAG" = "y" ]; then
3056	if [ "$LINTDIRS" = "" ]; then
3057		# LINTDIRS="$SRC/uts y $SRC/stand y $SRC/psm y"
3058		LINTDIRS="$SRC y"
3059	fi
3060	set $LINTDIRS
3061	while [ $# -gt 0 ]; do
3062		dolint $1 $2; shift; shift
3063	done
3064else
3065	echo "\n==== No '$MAKE lint' ====\n" >> $LOGFILE
3066fi
3067
3068# "make check" begins
3069
3070if [ "$i_CMD_LINE_FLAG" = "n" -a "$C_FLAG" = "y" ]; then
3071	# remove old check.out
3072	rm -f $SRC/check.out
3073
3074	rm -f $SRC/check-${MACH}.out
3075	cd $SRC
3076	$MAKE -ek check 2>&1 | tee -a $SRC/check-${MACH}.out >> $LOGFILE
3077	echo "\n==== cstyle/hdrchk errors ====\n" >> $mail_msg_file
3078
3079	grep ":" $SRC/check-${MACH}.out |
3080		egrep -v "Ignoring unknown host" | \
3081		sort | uniq >> $mail_msg_file
3082else
3083	echo "\n==== No '$MAKE check' ====\n" >> $LOGFILE
3084fi
3085
3086echo "\n==== Find core files ====\n" | \
3087    tee -a $LOGFILE >> $mail_msg_file
3088
3089find $abssrcdirs -name core -a -type f -exec file {} \; | \
3090	tee -a $LOGFILE >> $mail_msg_file
3091
3092if [ "$f_FLAG" = "y" -a "$build_ok" = "y" ]; then
3093	echo "\n==== Diff unreferenced files (since last build) ====\n" \
3094	    | tee -a $LOGFILE >>$mail_msg_file
3095	rm -f $SRC/unref-${MACH}.ref
3096	if [ -f $SRC/unref-${MACH}.out ]; then
3097		mv $SRC/unref-${MACH}.out $SRC/unref-${MACH}.ref
3098	fi
3099
3100	findunref -S $SCM_TYPE -t $SRC/.build.tstamp -s usr $CODEMGR_WS \
3101	    ${TOOLS}/findunref/exception_list 2>> $mail_msg_file | \
3102	    sort > $SRC/unref-${MACH}.out
3103
3104	if [ ! -f $SRC/unref-${MACH}.ref ]; then
3105		cp $SRC/unref-${MACH}.out $SRC/unref-${MACH}.ref
3106	fi
3107
3108	diff $SRC/unref-${MACH}.ref $SRC/unref-${MACH}.out >>$mail_msg_file
3109fi
3110
3111#
3112# Generate the OpenSolaris deliverables if requested.  Some of these
3113# steps need to come after findunref and are commented below.
3114#
3115
3116# If we are doing an OpenSolaris _source_ build (-S O) then we do
3117# not have usr/closed available to us to generate closedbins from,
3118# so skip this part.
3119if [ "$SO_FLAG" = n -a "$O_FLAG" = y -a "$build_ok" = y ]; then
3120	echo "\n==== Generating OpenSolaris tarballs ====\n" | \
3121	    tee -a $mail_msg_file >> $LOGFILE
3122
3123	cd $CODEMGR_WS
3124
3125	#
3126	# This step grovels through the package manifests, so it
3127	# must come after findunref.
3128	#
3129	# We assume no DEBUG vs non-DEBUG package content variation
3130	# here; if that changes, then the "make all" in $SRC/pkg will
3131	# need to be moved into the conditionals and repeated for each
3132	# different build.
3133	#
3134	echo "Generating closed binaries tarball(s)..." >> $LOGFILE
3135	closed_basename=on-closed-bins
3136	if [ "$D_FLAG" = y ]; then
3137		bindrop "$closed_basename" >>"$LOGFILE" 2>&1
3138		if (( $? != 0 )) ; then
3139			echo "Couldn't create DEBUG closed binaries." |
3140			    tee -a $mail_msg_file >> $LOGFILE
3141			build_ok=n
3142		fi
3143	fi
3144	if [ "$F_FLAG" = n ]; then
3145		bindrop -n "$closed_basename-nd" >>"$LOGFILE" 2>&1
3146		if (( $? != 0 )) ; then
3147			echo "Couldn't create non-DEBUG closed binaries." |
3148			    tee -a $mail_msg_file >> $LOGFILE
3149			build_ok=n
3150		fi
3151	fi
3152
3153	echo "Generating README.opensolaris..." >> $LOGFILE
3154	cat $SRC/tools/opensolaris/README.opensolaris.tmpl | \
3155	    mkreadme_osol $CODEMGR_WS/README.opensolaris >> $LOGFILE 2>&1
3156	if (( $? != 0 )) ; then
3157		echo "Couldn't create README.opensolaris." |
3158		    tee -a $mail_msg_file >> $LOGFILE
3159		build_ok=n
3160	fi
3161fi
3162
3163# Verify that the usual lists of files, such as exception lists,
3164# contain only valid references to files.  If the build has failed,
3165# then don't check the proto area.
3166CHECK_PATHS=${CHECK_PATHS:-y}
3167if [ "$CHECK_PATHS" = y -a "$N_FLAG" != y ]; then
3168	echo "\n==== Check lists of files ====\n" | tee -a $LOGFILE \
3169		>>$mail_msg_file
3170	arg=-b
3171	[ "$build_ok" = y ] && arg=
3172	checkpaths $arg $checkroot 2>&1 | tee -a $LOGFILE >>$mail_msg_file
3173fi
3174
3175if [ "$M_FLAG" != "y" -a "$build_ok" = y ]; then
3176	echo "\n==== Impact on file permissions ====\n" \
3177		>> $mail_msg_file
3178
3179	abspkgdefs=
3180	abspkg=
3181	for d in $abssrcdirs; do
3182		if [ -d "$d/pkgdefs" ]; then
3183			abspkgdefs="$abspkgdefs $d"
3184		fi
3185		if [ -d "$d/pkg" ]; then
3186			abspkg="$abspkg $d"
3187		fi
3188	done
3189
3190	if [ -n "$abspkgdefs" ]; then
3191		pmodes -qvdP \
3192		    `find $abspkgdefs -name pkginfo.tmpl -print -o \
3193		    -name .del\* -prune | sed -e 's:/pkginfo.tmpl$::' | \
3194		    sort -u` >> $mail_msg_file
3195	fi
3196
3197	if [ -n "$abspkg" ]; then
3198		for d in "$abspkg"; do
3199			( cd $d/pkg ; $MAKE -e pmodes ) >> $mail_msg_file
3200		done
3201	fi
3202fi
3203
3204if [ "$w_FLAG" = "y" -a "$build_ok" = "y" ]; then
3205	if [[ "$MULTI_PROTO" = no || "$D_FLAG" = y ]]; then
3206		do_wsdiff DEBUG $ROOT.prev $ROOT
3207	fi
3208
3209	if [[ "$MULTI_PROTO" = yes && "$F_FLAG" = n ]]; then
3210		do_wsdiff non-DEBUG $ROOT-nd.prev $ROOT-nd
3211	fi
3212fi
3213
3214END_DATE=`date`
3215echo "==== Nightly $maketype build completed: $END_DATE ====" | \
3216    tee -a $LOGFILE >> $build_time_file
3217
3218typeset -i10 hours
3219typeset -Z2 minutes
3220typeset -Z2 seconds
3221
3222elapsed_time=$SECONDS
3223((hours = elapsed_time / 3600 ))
3224((minutes = elapsed_time / 60  % 60))
3225((seconds = elapsed_time % 60))
3226
3227echo "\n==== Total build time ====" | \
3228    tee -a $LOGFILE >> $build_time_file
3229echo "\nreal    ${hours}:${minutes}:${seconds}" | \
3230    tee -a $LOGFILE >> $build_time_file
3231
3232if [ "$u_FLAG" = "y" -a "$f_FLAG" = "y" -a "$build_ok" = "y" ]; then
3233	staffer cp ${SRC}/unref-${MACH}.out $PARENT_WS/usr/src/
3234
3235	#
3236	# Produce a master list of unreferenced files -- ideally, we'd
3237	# generate the master just once after all of the nightlies
3238	# have finished, but there's no simple way to know when that
3239	# will be.  Instead, we assume that we're the last nightly to
3240	# finish and merge all of the unref-${MACH}.out files in
3241	# $PARENT_WS/usr/src/.  If we are in fact the final ${MACH} to
3242	# finish, then this file will be the authoritative master
3243	# list.  Otherwise, another ${MACH}'s nightly will eventually
3244	# overwrite ours with its own master, but in the meantime our
3245	# temporary "master" will be no worse than any older master
3246	# which was already on the parent.
3247	#
3248
3249	set -- $PARENT_WS/usr/src/unref-*.out
3250	cp "$1" ${TMPDIR}/unref.merge
3251	shift
3252
3253	for unreffile; do
3254		comm -12 ${TMPDIR}/unref.merge "$unreffile" > ${TMPDIR}/unref.$$
3255		mv ${TMPDIR}/unref.$$ ${TMPDIR}/unref.merge
3256	done
3257
3258	staffer cp ${TMPDIR}/unref.merge $PARENT_WS/usr/src/unrefmaster.out
3259fi
3260
3261#
3262# All done save for the sweeping up.
3263# (whichever exit we hit here will trigger the "cleanup" trap which
3264# optionally sends mail on completion).
3265#
3266if [ "$build_ok" = "y" ]; then
3267	exit 0
3268fi
3269exit 1
3270