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