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