[Taclug-General] Improved: Make a bootable SuSE DVD

Russell Evans taclug-general@taclug.org
Mon May 19 22:45:00 2003


This is a multi-part message in MIME format...

------------=_1053409472-8957-0
Content-Type: text/plain; charset="iso-8859-1"
Content-Disposition: inline
Content-Transfer-Encoding: 7bit

I didn't unset the arrays holding the directory listing. This meant any
directory smaller than the proceding one didn't over write all the previous
entries. I didn't like the way the ping times were  captured, this seems
better. 

Thank you
Russell



#!/bin/sh

#
# Make a bottable DVD ISO from a FTP version of SuSE Linux
#

# Change according to your needs 
VER=8.2
DIR="/srv/ftp/pub/suse/i386/$VER"
ISODIR="/srv/ftp/pub/cdlibrary/iso"
ISO="SuSE-${VER}-ftp.iso"
TMPDIR="/tmp"
MD5SUM_ER_FILE="md5sumerror"
LS_FILE="ls_for_dir"

# Programs and paths
WGETBIN=/usr/bin/wget
PINGBIN=/bin/ping
GREPBIN=/usr/bin/grep
RMBIN=/bin/rm
TOUCHBIN=/usr/bin/touch
FINDBIN=/usr/bin/find
PSBIN=/bin/ps
PWDBIN=/bin/pwd 
MD5SUMBIN=/usr/bin/md5sum
MKISOFSBIN=/usr/local/bin/mkisofs
CUTBIN=/usr/bin/cut
SLEEPBIN=/bin/sleep
DOS2UNIXBIN=/usr/bin/dos2unix
LSBIN=/bin/ls
WCBIN=/usr/bin/wc


# You shouldn't need to change anything below this
SOURCE="$DIR/suse/src"
OPTS="-r -J -l -D -L -V  -P  -p  -abstract  -biblio -copyright"
BOOTDIR="boot/loader"
BOOT="isolinux.bin"
CAT="boot.cat"
BOPTS="-no-emul-boot -boot-load-size 4 -boot-info-table"
GRAFT="-graft-points /=$DIR"

declare -i PING
declare -i LOWPING 
declare -a LS_FILE_ARRAY
declare -a LS_LEN_ARRAY

#### FUNCTIONS ####

# Choose Mirror  
PING_MIRRORS () {
	echo "Looking for closest mirror"
	LIST="ftp-linux.cc.gatech.edu mirror.mcs.anl.gov ftp.gwdg.de
chuck.ucs.indiana.edu distro.ibiblio.org mirrors.usc.edu"
	let LOWPING=0
	for HOST in $LIST ; do
		PING=`eval $PINGBIN -q -c 10 $HOST | $GREPBIN rtt | $CUTBIN -d
"/" -f 5 | $CUTBIN -d"." -f 1`
		echo "$HOST is $PING ms away"
		if [ "$PING" -lt  "$LOWPING" ] && [ "$PING" != "0" ] && [
"$LOWPING" != "0" ] ; then
			LOWPING=$PING
			PINGTEST=$HOST
		elif [ "$PING" != "0" ] && [ "$LOWPING" = "0" ] ; then
			LOWPING=$PING
			PINGTEST=$HOST
		fi
	done

	case $PINGTEST in
		mirrors.usc.edu)
				MIRROR="mirrors.usc.edu"
			       
MIRRORPATH="pub/linux/distributions/suse/i386/$VER"
				;;
		distro.ibiblio.org)
				MIRROR="distro.ibiblio.org"
			       
MIRRORPATH="pub/Linux/distributions/suse/suse/i386/$VER"
				;;
		ftp-linux.cc.gatech.edu)
				MIRROR="ftp-linux.cc.gatech.edu"
				MIRRORPATH="pub/suse/suse/i386/$VER"
				;;
		mirror.mcs.anl.gov)
				MIRROR="mirror.mcs.anl.gov"
				MIRRORPATH="pub/suse/i386/$VER"
				;;
		ftp.gwdg.de)
				MIRROR="ftp.gwdg.de"
			       
MIRRORPATH="pub/linux/suse/ftp.suse.com/suse/i386/$VER"
				;;
		chuck.ucs.indiana.edu)
				MIRROR="chuck.ucs.indiana.edu"
				MIRRORPATH="linux/suse/suse/i386/$VER"
				;;
	esac

	# Don't get source rpms as they won't fit on the DVD anyway
	EXCLUDESRC="$MIRRORPATH/suse/src"

	# Cut the directories in MIRRORPATH for the ftp mirror of MIRROR
	DIRCUT=`echo ${MIRRORPATH//[A-Za-z0-9\_\.\:\\\,\-]} | $WCBIN -c`
	echo ""
}

# Test to see if the SuSE version is available
TEST_DIR () {
	echo "Testing for $VER on $MIRROR"
	eval $WGETBIN -q  -O - ftp://$MIRROR/$MIRRORPATH/ >/dev/null
	NEWTEST=$?
}

# Exit if the SuSE version wanted isn't available
MIRROR () {
	if [ "$NEWTEST" = 0 ] ; then
		echo "OK" 
		echo ""
		echo "Mirroring $MIRROR"
		eval $WGETBIN -cmq -nH --passive -X /$EXCLUDESRC -P $DIR
--cut-dirs=${DIRCUT// } ftp://${MIRROR}/${MIRRORPATH} &
		PID=$! 
		while true ; do
			RUNNING=`eval $PSBIN h -o pid  -p $PID`
			if [ "${RUNNING}" ] ; then
				echo -en "#"
				eval $SLEEPBIN 5
			else
				echo "#"
				echo "Download complete"
				echo ""
				break
			fi
		done
	else
		echo "$VER isn't avialable"
		exit 1
	fi
}

#Verify file sizes
CHECK () {
	for DOTLIST in `eval $FINDBIN $DIR -name "\.listing"` ; do
		eval $DOS2UNIXBIN -q $DOTLIST	
		eval $LSBIN -l ${DOTLIST%.*} | $GREPBIN -v total >
$TMPDIR/$LS_FILE
		cd ${DOTLIST%.*}
		NAME=${DOTLIST%.*}
		PATH=${NAME//$DIR}
		unset LS_FILE_ARRAY
		unset LS_LEN_ARRAY
		let x=0
		while read x1 x2 x3 x4 LEN x5 x6 x7 FILE ; do 
			if [ ! -d "$FILE" ] ; then 
				LS_FILE_ARRAY["$x"]="$FILE"
				LS_LEN_ARRAY["$x"]="$LEN"
				let x++
			fi	
		done < $TMPDIR/$LS_FILE
		COUNT=${#LS_FILE_ARRAY[@]}
		if [ $COUNT -gt 0 ] ; then
			echo ""
			echo "Looking at file sizes in ${DOTLIST%.*} -- $COUNT
files"
		fi
		while read x1 x2 x3 x4 LEN x5 x6 x7 FILE ; do 
			if [ ! -d "$FILE" ] ; then 
				if [ -e "$FILE" ] ; then
					let z=0
					while [ $z -lt "$COUNT" ] ; do
						if [ "${FILE}" =
"${LS_FILE_ARRAY["$z"]}" ] ; then
							echo -en "#" 
							if [ "${LEN}" !=
"${LS_LEN_ARRAY["$z"]}" ] ; then
								echo "#"
								echo "Getting
$FILE again"
								eval $RMBIN
$FILE
								while true ; do 
									eval
$WGETBIN -q ftp://$MIRROR/$MIRRORPATH/$PATH/$FILE &
								       
WGETTEST=$?
									PID=$! 
									while
true ; do
									       
RUNNING=`eval $PSBIN h -o pid  -p $PID`
									       
if [ "${RUNNING}" ] ; then
									       
	echo -en "#"
									       
	eval $SLEEPBIN 5
									       
else
									       
	echo "#"
									       
	echo ""
									       
	break
									       
fi
									done
									if [
"$WGETTEST" = 0 ] ; then
									       
echo "Continuing file check"
									       
break
									fi
								done
							fi
						fi
						let z++ 
					done
				else
					echo ""
					echo "Getting $FILE again"
					while true ; do 
						eval $WGETBIN -q
ftp://$MIRROR/$MIRRORPATH/$PATH/$FILE &
						WGETTEST=$?
						PID=$! 
						while true ; do
							RUNNING=`eval $PSBIN h
-o pid	-p $PID`
							if [ "${RUNNING}" ] ;
then
								echo -en "#"
								eval $SLEEPBIN
5
							else
								echo "#"
								echo ""
								break
							fi
						done
						if [ "$WGETTEST" = 0 ] ; then
							echo "Continuing file
check"
							echo ""
							break
						fi
					done
				fi				
			fi		
		done < $DOTLIST 
		#eval $RMBIN $DOTLIST
		cd -	
	done
}

# Check MD5SUMS for rpms
TEST_MD5SUMS () {
	if [ -e $TMPDIR/$MD5SUM_ER_FILE ] ; then
		eval $RMBIN $TMPDIR/$MD5SUM_ER_FILE
		eval $TOUCHBIN $TMPDIR/$MD5SUM_ER_FILE
	fi
	cd $DIR
	echo ""
	for MD in `eval $FINDBIN $DIR -name MD5SUMS` ; do
		cd ${MD%/*}
		echo "Checking sums in ${MD%/*}"
		echo ${MD%/*} >> $TMPDIR/$MD5SUM_ER_FILE
		eval $MD5SUMBIN -c $MD 2>/dev/null | $GREPBIN FAILED  >>
$TMPDIR/$MD5SUM_ER_FILE &
		PID=$! 
		while true ; do
			RUNNING=`eval $PSBIN h -o pid  -p $PID`
			if [ "${RUNNING}" ] ; then
				echo -en "#"
				eval $SLEEPBIN 5
			else
				echo "#"
				echo ""
				break
			fi
		done
	done
	cd -
}

# Fix md5sum errors
FIX () {
	CURRENT_DIR=`eval $PWDBIN`
	while read NAME STAT ; do
		if [ -d ${NAME} ] ; then
			cd $NAME
			PATH=${NAME//$DIR}
		elif [ "$STAT" = "FAILED" ] ; then 
			echo ""
			echo "Getting ${NAME//:} again"  
			eval $RMBIN ${NAME//:}
			while true ; do
				eval $WGETBIN -q
ftp://$MIRROR/$MIRRORPATH/$PATH/${NAME//:} &
				WGETTEST=$?
				PID=$! 
				while true ; do
					RUNNING=`eval $PSBIN h -o pid  -p $PID`
					if [ "${RUNNING}" ] ; then
						echo -en "#"
						eval $SLEEPBIN 5
					else
						echo "#"
						echo ""
						break
					fi
				done
				if [ "$WGETTEST" = 0 ] ; then
					break
				fi
			done
		fi
	done < $TMPDIR/$MD5SUM_ER_FILE
	cd $CURRENT_DIR
}

# Make the DVD iso or exit if it already exist
ISO () {
	if [ ! -e  ${ISODIR}/${ISO} ] ; then
		eval $MKISOFSBIN $OPTS	\
		-x $SOURCE		\
		-o ${ISODIR}/${ISO}	\
		-b ${BOOTDIR}/${BOOT}	\
		-c ${BOOTDIR}/${CAT}	\
		$BOPTS			\
		$GRAFT
	else
		echo  ${ISODIR}/${ISO} exists
	fi
}


#### MAIN ####

clear
PING_MIRRORS
TEST_DIR
MIRROR
CHECK
echo ""
eval $RMBIN $TMPDIR/$LS_FILE
while true ; do 
	TEST_MD5SUMS
	MD5SUMTEST=`$GREPBIN "FAILED" $TMPDIR/$MD5SUM_ER_FILE`
	if [ ${#MD5SUMTEST} -gt 0 ] ; then
		echo "There were problems with the md5sums. Some files will be
downloaded again."
		FIX
		echo ""
		echo "Testing md5sums again"
		echo ""
	else
		eval $RMBIN $TMPDIR/$MD5SUM_ER_FILE
		break
	fi	
done			
ISO
exit 0



------------=_1053409472-8957-0
Content-Type: application/x-unknown; name="mksuse"
Content-Disposition: inline; filename="mksuse"
Content-Transfer-Encoding: base64

IyEvYmluL3NoCgojCiMKIwoKIyBDaGFuZ2UgYWNjb3JkaW5nIHRvIHlvdXIg
bmVlZHMgClZFUj04LjIKRElSPSIvc3J2L2Z0cC9wdWIvc3VzZS9pMzg2LyRW
RVIiCklTT0RJUj0iL3Nydi9mdHAvcHViL2NkbGlicmFyeS9pc28iCklTTz0i
U3VTRS0ke1ZFUn0tZnRwLmlzbyIKVE1QRElSPSIvdG1wIgpNRDVTVU1fRVJf
RklMRT0ibWQ1c3VtZXJyb3IiCkxTX0ZJTEU9ImxzX2Zvcl9kaXIiCgojIFBy
b2dyYW1zIGFuZCBwYXRocwpXR0VUQklOPS91c3IvYmluL3dnZXQKUElOR0JJ
Tj0vYmluL3BpbmcKR1JFUEJJTj0vdXNyL2Jpbi9ncmVwClJNQklOPS9iaW4v
cm0KVE9VQ0hCSU49L3Vzci9iaW4vdG91Y2gKRklOREJJTj0vdXNyL2Jpbi9m
aW5kClBTQklOPS9iaW4vcHMKUFdEQklOPS9iaW4vcHdkIApNRDVTVU1CSU49
L3Vzci9iaW4vbWQ1c3VtCk1LSVNPRlNCSU49L3Vzci9sb2NhbC9iaW4vbWtp
c29mcwpDVVRCSU49L3Vzci9iaW4vY3V0ClNMRUVQQklOPS9iaW4vc2xlZXAK
RE9TMlVOSVhCSU49L3Vzci9iaW4vZG9zMnVuaXgKTFNCSU49L2Jpbi9scwpX
Q0JJTj0vdXNyL2Jpbi93YwoKCiMgWW91IHNob3VsZG4ndCBuZWVkIHRvIGNo
YW5nZSBhbnl0aGluZyBiZWxvdyB0aGlzClNPVVJDRT0iJERJUi9zdXNlL3Ny
YyIKT1BUUz0iLXIgLUogLWwgLUQgLUwgLVYgIC1QICAtcCAgLWFic3RyYWN0
ICAtYmlibGlvIC1jb3B5cmlnaHQiCkJPT1RESVI9ImJvb3QvbG9hZGVyIgpC
T09UPSJpc29saW51eC5iaW4iCkNBVD0iYm9vdC5jYXQiCkJPUFRTPSItbm8t
ZW11bC1ib290IC1ib290LWxvYWQtc2l6ZSA0IC1ib290LWluZm8tdGFibGUi
CkdSQUZUPSItZ3JhZnQtcG9pbnRzIC89JERJUiIKCmRlY2xhcmUgLWkgUElO
RwpkZWNsYXJlIC1pIExPV1BJTkcgCmRlY2xhcmUgLWEgTFNfRklMRV9BUlJB
WQpkZWNsYXJlIC1hIExTX0xFTl9BUlJBWQoKIyMjIyBGVU5DVElPTlMgIyMj
IwoKIyBDaG9vc2UgTWlycm9yICAKUElOR19NSVJST1JTICgpIHsKCWVjaG8g
Ikxvb2tpbmcgZm9yIGNsb3Nlc3QgbWlycm9yIgoJTElTVD0iZnRwLWxpbnV4
LmNjLmdhdGVjaC5lZHUgbWlycm9yLm1jcy5hbmwuZ292IGZ0cC5nd2RnLmRl
IGNodWNrLnVjcy5pbmRpYW5hLmVkdSBkaXN0cm8uaWJpYmxpby5vcmcgbWly
cm9ycy51c2MuZWR1IgoJbGV0IExPV1BJTkc9MAoJZm9yIEhPU1QgaW4gJExJ
U1QgOyBkbwoJCVBJTkc9YGV2YWwgJFBJTkdCSU4gLXEgLWMgMTAgJEhPU1Qg
fCAkR1JFUEJJTiBydHQgfCAkQ1VUQklOIC1kICIvIiAtZiA1IHwgJENVVEJJ
TiAtZCIuIiAtZiAxYAoJCWVjaG8gIiRIT1NUIGlzICRQSU5HIG1zIGF3YXki
CgkJaWYgWyAiJFBJTkciIC1sdCAgIiRMT1dQSU5HIiBdICYmIFsgIiRQSU5H
IiAhPSAiMCIgXSAmJiBbICIkTE9XUElORyIgIT0gIjAiIF0gOyB0aGVuCgkJ
CUxPV1BJTkc9JFBJTkcKCQkJUElOR1RFU1Q9JEhPU1QKCQllbGlmIFsgIiRQ
SU5HIiAhPSAiMCIgXSAmJiBbICIkTE9XUElORyIgPSAiMCIgXSA7IHRoZW4K
CQkJTE9XUElORz0kUElORwoJCQlQSU5HVEVTVD0kSE9TVAoJCWZpCglkb25l
CgoJY2FzZSAkUElOR1RFU1QgaW4KCQltaXJyb3JzLnVzYy5lZHUpCgkJCQlN
SVJST1I9Im1pcnJvcnMudXNjLmVkdSIKCQkJCU1JUlJPUlBBVEg9InB1Yi9s
aW51eC9kaXN0cmlidXRpb25zL3N1c2UvaTM4Ni8kVkVSIgoJCQkJOzsKCQlk
aXN0cm8uaWJpYmxpby5vcmcpCgkJCQlNSVJST1I9ImRpc3Ryby5pYmlibGlv
Lm9yZyIKCQkJCU1JUlJPUlBBVEg9InB1Yi9MaW51eC9kaXN0cmlidXRpb25z
L3N1c2Uvc3VzZS9pMzg2LyRWRVIiCgkJCQk7OwoJCWZ0cC1saW51eC5jYy5n
YXRlY2guZWR1KQoJCQkJTUlSUk9SPSJmdHAtbGludXguY2MuZ2F0ZWNoLmVk
dSIKCQkJCU1JUlJPUlBBVEg9InB1Yi9zdXNlL3N1c2UvaTM4Ni8kVkVSIgoJ
CQkJOzsKCQltaXJyb3IubWNzLmFubC5nb3YpCgkJCQlNSVJST1I9Im1pcnJv
ci5tY3MuYW5sLmdvdiIKCQkJCU1JUlJPUlBBVEg9InB1Yi9zdXNlL2kzODYv
JFZFUiIKCQkJCTs7CgkJZnRwLmd3ZGcuZGUpCgkJCQlNSVJST1I9ImZ0cC5n
d2RnLmRlIgoJCQkJTUlSUk9SUEFUSD0icHViL2xpbnV4L3N1c2UvZnRwLnN1
c2UuY29tL3N1c2UvaTM4Ni8kVkVSIgoJCQkJOzsKCQljaHVjay51Y3MuaW5k
aWFuYS5lZHUpCgkJCQlNSVJST1I9ImNodWNrLnVjcy5pbmRpYW5hLmVkdSIK
CQkJCU1JUlJPUlBBVEg9ImxpbnV4L3N1c2Uvc3VzZS9pMzg2LyRWRVIiCgkJ
CQk7OwoJZXNhYwoKCSMgRG9uJ3QgZ2V0IHNvdXJjZSBycG1zIGFzIHRoZXkg
d29uJ3QgZml0IG9uIHRoZSBEVkQgYW55d2F5CglFWENMVURFU1JDPSIkTUlS
Uk9SUEFUSC9zdXNlL3NyYyIKCgkjIEN1dCB0aGUgZGlyZWN0b3JpZXMgaW4g
TUlSUk9SUEFUSCBmb3IgdGhlIGZ0cCBtaXJyb3Igb2YgTUlSUk9SCglESVJD
VVQ9YGVjaG8gJHtNSVJST1JQQVRILy9bQS1aYS16MC05XF9cLlw6XFxcLFwt
XX0gfCAkV0NCSU4gLWNgCgllY2hvICIiCn0KCiMgVGVzdCB0byBzZWUgaWYg
dGhlIFN1U0UgdmVyc2lvbiBpcyBhdmFpbGFibGUKVEVTVF9ESVIgKCkgewoJ
ZWNobyAiVGVzdGluZyBmb3IgJFZFUiBvbiAkTUlSUk9SIgoJZXZhbCAkV0dF
VEJJTiAtcSAgLU8gLSBmdHA6Ly8kTUlSUk9SLyRNSVJST1JQQVRILyA+L2Rl
di9udWxsCglORVdURVNUPSQ/Cn0KCiMgRXhpdCBpZiB0aGUgU3VTRSB2ZXJz
aW9uIHdhbnRlZCBpc24ndCBhdmFpbGFibGUKTUlSUk9SICgpIHsKCWlmIFsg
IiRORVdURVNUIiA9IDAgXSA7IHRoZW4KCQllY2hvICJPSyIgCgkJZWNobyAi
IgoJCWVjaG8gIk1pcnJvcmluZyAkTUlSUk9SIgoJCWV2YWwgJFdHRVRCSU4g
LWNtcSAtbkggLS1wYXNzaXZlIC1YIC8kRVhDTFVERVNSQyAtUCAkRElSIC0t
Y3V0LWRpcnM9JHtESVJDVVQvLyB9IGZ0cDovLyR7TUlSUk9SfS8ke01JUlJP
UlBBVEh9ICYKCQlQSUQ9JCEgCiAgICAgICAgCXdoaWxlIHRydWUgOyBkbwog
ICAgICAgICAgICAgICAgCVJVTk5JTkc9YGV2YWwgJFBTQklOIGggLW8gcGlk
ICAtcCAkUElEYAogICAgICAgICAgICAgICAgCWlmIFsgIiR7UlVOTklOR30i
IF0gOyB0aGVuCiAgICAgICAgICAgICAgICAgICAgICAgIAllY2hvIC1lbiAi
IyIKICAgICAgICAgICAgICAgICAgICAgICAgCWV2YWwgJFNMRUVQQklOIDUK
ICAgICAgICAgICAgICAgIAllbHNlCgkJCQllY2hvICIjIgoJCQkJZWNobyAi
RG93bmxvYWQgY29tcGxldGUiCgkJCQllY2hvICIiCgkJCQlicmVhawoJCQlm
aQogICAgICAgIAlkb25lCgllbHNlCgkJZWNobyAiJFZFUiBpc24ndCBhdmlh
bGFibGUiCgkJZXhpdCAxCglmaQp9CgojVmVyaWZ5IGZpbGUgc2l6ZXMKQ0hF
Q0sgKCkgewoJZm9yIERPVExJU1QgaW4gYGV2YWwgJEZJTkRCSU4gJERJUiAt
bmFtZSAiXC5saXN0aW5nImAgOyBkbwoJCWV2YWwgJERPUzJVTklYQklOIC1x
ICRET1RMSVNUCQoJCWV2YWwgJExTQklOIC1sICR7RE9UTElTVCUuKn0gfCAk
R1JFUEJJTiAtdiB0b3RhbCA+ICRUTVBESVIvJExTX0ZJTEUKCQljZCAke0RP
VExJU1QlLip9CgkJTkFNRT0ke0RPVExJU1QlLip9CgkJUEFUSD0ke05BTUUv
LyRESVJ9CgkJdW5zZXQgTFNfRklMRV9BUlJBWQoJCXVuc2V0IExTX0xFTl9B
UlJBWQoJCWxldCB4PTAKCQl3aGlsZSByZWFkIHgxIHgyIHgzIHg0IExFTiB4
NSB4NiB4NyBGSUxFIDsgZG8gCgkJCWlmIFsgISAtZCAiJEZJTEUiIF0gOyB0
aGVuIAoJCQkJTFNfRklMRV9BUlJBWVsiJHgiXT0iJEZJTEUiCgkJCQlMU19M
RU5fQVJSQVlbIiR4Il09IiRMRU4iCgkJCQlsZXQgeCsrCgkJCWZpCQoJCWRv
bmUgPCAkVE1QRElSLyRMU19GSUxFCgkJQ09VTlQ9JHsjTFNfRklMRV9BUlJB
WVtAXX0KCQlpZiBbICRDT1VOVCAtZ3QgMCBdIDsgdGhlbgoJCQllY2hvICIi
CgkJCWVjaG8gIkxvb2tpbmcgYXQgZmlsZSBzaXplcyBpbiAke0RPVExJU1Ql
Lip9IC0tICRDT1VOVCBmaWxlcyIKCQlmaQoJCXdoaWxlIHJlYWQgeDEgeDIg
eDMgeDQgTEVOIHg1IHg2IHg3IEZJTEUgOyBkbyAKCQkJaWYgWyAhIC1kICIk
RklMRSIgXSA7IHRoZW4gCgkJCQlpZiBbIC1lICIkRklMRSIgXSA7IHRoZW4K
CQkJCQlsZXQgej0wCgkJCQkJd2hpbGUgWyAkeiAtbHQgIiRDT1VOVCIgXSA7
IGRvCgkJCQkJCWlmIFsgIiR7RklMRX0iID0gIiR7TFNfRklMRV9BUlJBWVsi
JHoiXX0iIF0gOyB0aGVuCgkJCQkJCQllY2hvIC1lbiAiIyIgCgkJCQkJCQlp
ZiBbICIke0xFTn0iICE9ICIke0xTX0xFTl9BUlJBWVsiJHoiXX0iIF0gOyB0
aGVuCgkJCQkJCQkJZWNobyAiIyIKCQkJCQkJCQllY2hvICJHZXR0aW5nICRG
SUxFIGFnYWluIgoJCQkJCQkJCWV2YWwgJFJNQklOICRGSUxFCgkJCQkJCQkJ
d2hpbGUgdHJ1ZSA7IGRvCQoJCQkJCQkJCQlldmFsICRXR0VUQklOIC1xIGZ0
cDovLyRNSVJST1IvJE1JUlJPUlBBVEgvJFBBVEgvJEZJTEUgJgoJCQkJCQkJ
CQlXR0VUVEVTVD0kPwoJCQkJCQkJCQlQSUQ9JCEgCiAgICAgICAgCQkJCQkJ
CQl3aGlsZSB0cnVlIDsgZG8KICAgICAgICAgICAgICAgIAkJCQkJCQkJUlVO
TklORz1gZXZhbCAkUFNCSU4gaCAtbyBwaWQgIC1wICRQSURgCiAgICAgICAg
ICAgICAgICAJCQkJCQkJCWlmIFsgIiR7UlVOTklOR30iIF0gOyB0aGVuCiAg
ICAgICAgICAgICAgICAgICAgICAgIAkJCQkJCQkJZWNobyAtZW4gIiMiCiAg
ICAgICAgICAgICAgICAgICAgICAgIAkJCQkJCQkJZXZhbCAkU0xFRVBCSU4g
NQogICAgICAgICAgICAgICAgCQkJCQkJCQllbHNlCiAgICAgICAgICAgICAg
ICAgICAgICAgIAkJCQkJCQkJZWNobyAiIyIKCQkJCQkJCQkJCQllY2hvICIi
CiAgICAgICAgICAgICAgICAgICAgICAgIAkJCQkJCQkJYnJlYWsKICAgICAg
ICAgICAgICAgIAkJCQkJCQkJZmkKICAgICAgICAJCQkJCQkJCWRvbmUKCQkJ
CQkJCQkJaWYgWyAiJFdHRVRURVNUIiA9IDAgXSA7IHRoZW4KCQkJCQkJCQkJ
CWVjaG8gIkNvbnRpbnVpbmcgZmlsZSBjaGVjayIKCQkJCQkJCQkJCWJyZWFr
CgkJCQkJCQkJCWZpCgkJCQkJCQkJZG9uZQoJCQkJCQkJZmkKCQkJCQkJZmkK
CQkJCQkJbGV0IHorKwkKCQkJCQlkb25lCgkJCQllbHNlCgkJCQkJZWNobyAi
IgoJCQkJCWVjaG8gIkdldHRpbmcgJEZJTEUgYWdhaW4iCgkJCQkJd2hpbGUg
dHJ1ZSA7IGRvCQoJCQkJCQlldmFsICRXR0VUQklOIC1xIGZ0cDovLyRNSVJS
T1IvJE1JUlJPUlBBVEgvJFBBVEgvJEZJTEUgJgoJCQkJCQlXR0VUVEVTVD0k
PwoJCQkJCQlQSUQ9JCEgCiAgICAgICAgCQkJCQl3aGlsZSB0cnVlIDsgZG8K
ICAgICAgICAgICAgICAgIAkJCQkJUlVOTklORz1gZXZhbCAkUFNCSU4gaCAt
byBwaWQgIC1wICRQSURgCiAgICAgICAgICAgICAgICAJCQkJCWlmIFsgIiR7
UlVOTklOR30iIF0gOyB0aGVuCiAgICAgICAgICAgICAgICAgICAgICAgIAkJ
CQkJZWNobyAtZW4gIiMiCiAgICAgICAgICAgICAgICAgICAgICAgIAkJCQkJ
ZXZhbCAkU0xFRVBCSU4gNQogICAgICAgICAgICAgICAgCQkJCQllbHNlCiAg
ICAgICAgICAgICAgICAgICAgICAgIAkJCQkJZWNobyAiIyIKCQkJCQkJCQll
Y2hvICIiCiAgICAgICAgICAgICAgICAgICAgICAgIAkJCQkJYnJlYWsKICAg
ICAgICAgICAgICAgIAkJCQkJZmkKICAgICAgICAJCQkJCWRvbmUKCQkJCQkJ
aWYgWyAiJFdHRVRURVNUIiA9IDAgXSA7IHRoZW4KCQkJCQkJCWVjaG8gIkNv
bnRpbnVpbmcgZmlsZSBjaGVjayIKCQkJCQkJCWVjaG8gIiIKCQkJCQkJCWJy
ZWFrCgkJCQkJCWZpCgkJCQkJZG9uZQoJCQkJZmkJCQkJCgkJCWZpCQkKCQlk
b25lIDwgJERPVExJU1QJCgkJI2V2YWwgJFJNQklOICRET1RMSVNUCgkJY2Qg
LQkKCWRvbmUKfQoKIyBDaGVjayBNRDVTVU1TIGZvciBycG1zClRFU1RfTUQ1
U1VNUyAoKSB7CglpZiBbIC1lICRUTVBESVIvJE1ENVNVTV9FUl9GSUxFIF0g
OyB0aGVuCgkJZXZhbCAkUk1CSU4gJFRNUERJUi8kTUQ1U1VNX0VSX0ZJTEUK
CQlldmFsICRUT1VDSEJJTiAkVE1QRElSLyRNRDVTVU1fRVJfRklMRQoJZmkK
CWNkICRESVIKCWVjaG8gIiIKCWZvciBNRCBpbiBgZXZhbCAkRklOREJJTiAk
RElSIC1uYW1lIE1ENVNVTVNgIDsgZG8KCQljZCAke01EJS8qfQoJCWVjaG8g
IkNoZWNraW5nIHN1bXMgaW4gJHtNRCUvKn0iCgkJZWNobyAke01EJS8qfSA+
PiAkVE1QRElSLyRNRDVTVU1fRVJfRklMRQoJCWV2YWwgJE1ENVNVTUJJTiAt
YyAkTUQgMj4vZGV2L251bGwgfCAkR1JFUEJJTiBGQUlMRUQgID4+ICRUTVBE
SVIvJE1ENVNVTV9FUl9GSUxFICYKCQlQSUQ9JCEgCiAgICAgICAgCXdoaWxl
IHRydWUgOyBkbwogICAgICAgICAgICAgICAgCVJVTk5JTkc9YGV2YWwgJFBT
QklOIGggLW8gcGlkICAtcCAkUElEYAogICAgICAgICAgICAgICAgCWlmIFsg
IiR7UlVOTklOR30iIF0gOyB0aGVuCiAgICAgICAgICAgICAgICAgICAgICAg
IAllY2hvIC1lbiAiIyIKICAgICAgICAgICAgICAgICAgICAgICAgCWV2YWwg
JFNMRUVQQklOIDUKICAgICAgICAgICAgICAgIAllbHNlCiAgICAgICAgICAg
ICAgICAgICAgICAgIAllY2hvICIjIgoJCQkJZWNobyAiIgogICAgICAgICAg
ICAgICAgICAgICAgICAJYnJlYWsKICAgICAgICAgICAgICAgIAlmaQogICAg
ICAgIAlkb25lCglkb25lCgljZCAtCn0KCiMgRml4IG1kNXN1bSBlcnJvcnMK
RklYICgpIHsKCUNVUlJFTlRfRElSPWBldmFsICRQV0RCSU5gCgl3aGlsZSBy
ZWFkIE5BTUUgU1RBVCA7IGRvCgkJaWYgWyAtZCAke05BTUV9IF0gOyB0aGVu
CgkJCWNkICROQU1FCgkJCVBBVEg9JHtOQU1FLy8kRElSfQoJCWVsaWYgWyAi
JFNUQVQiID0gIkZBSUxFRCIgXSA7IHRoZW4gCgkJCWVjaG8gIiIKCQkJZWNo
byAiR2V0dGluZyAke05BTUUvLzp9IGFnYWluIiAgCgkJCWV2YWwgJFJNQklO
ICR7TkFNRS8vOn0KCQkJd2hpbGUgdHJ1ZSA7IGRvCgkJCSAJZXZhbCAkV0dF
VEJJTiAtcSBmdHA6Ly8kTUlSUk9SLyRNSVJST1JQQVRILyRQQVRILyR7TkFN
RS8vOn0gJgoJCQkJV0dFVFRFU1Q9JD8KCQkJCVBJRD0kISAKICAgICAgICAJ
CQl3aGlsZSB0cnVlIDsgZG8KICAgICAgICAgICAgICAgIAkJCVJVTk5JTkc9
YGV2YWwgJFBTQklOIGggLW8gcGlkICAtcCAkUElEYAogICAgICAgICAgICAg
ICAgCQkJaWYgWyAiJHtSVU5OSU5HfSIgXSA7IHRoZW4KICAgICAgICAgICAg
ICAgICAgICAgICAgCQkJZWNobyAtZW4gIiMiCiAgICAgICAgICAgICAgICAg
ICAgICAgIAkJCWV2YWwgJFNMRUVQQklOIDUKICAgICAgICAgICAgICAgIAkJ
CWVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgCQkJZWNobyAiIyIKCQkJ
CQkJZWNobyAiIgogICAgICAgICAgICAgICAgICAgICAgICAJCQlicmVhawog
ICAgICAgICAgICAgICAgCQkJZmkKICAgICAgICAJCQlkb25lCgkJCQlpZiBb
ICIkV0dFVFRFU1QiID0gMCBdIDsgdGhlbgoJCQkJCWJyZWFrCgkJCQlmaQoJ
CQlkb25lCgkJZmkKCWRvbmUgPCAkVE1QRElSLyRNRDVTVU1fRVJfRklMRQoJ
Y2QgJENVUlJFTlRfRElSCn0KCiMgTWFrZSB0aGUgRFZEIGlzbyBvciBleGl0
IGlmIGl0IGFscmVhZHkgZXhpc3QKSVNPICgpIHsKCWlmIFsgISAtZSAgJHtJ
U09ESVJ9LyR7SVNPfSBdIDsgdGhlbgoJCWV2YWwgJE1LSVNPRlNCSU4gJE9Q
VFMgCVwKCQkteCAkU09VUkNFCQlcCgkJLW8gJHtJU09ESVJ9LyR7SVNPfSAg
IAlcCgkJLWIgJHtCT09URElSfS8ke0JPT1R9CVwKCQktYyAke0JPT1RESVJ9
LyR7Q0FUfQlcCgkJJEJPUFRTICAgICAgICAJCVwKCQkkR1JBRlQKCWVsc2UK
CQllY2hvICAke0lTT0RJUn0vJHtJU099IGV4aXN0cwoJZmkKfQoKCiMjIyMg
TUFJTiAjIyMjCgpjbGVhcgpQSU5HX01JUlJPUlMKVEVTVF9ESVIKTUlSUk9S
CkNIRUNLCmVjaG8gIiIKZXZhbCAkUk1CSU4gJFRNUERJUi8kTFNfRklMRQp3
aGlsZSB0cnVlIDsgZG8gCglURVNUX01ENVNVTVMKCU1ENVNVTVRFU1Q9YCRH
UkVQQklOICJGQUlMRUQiICRUTVBESVIvJE1ENVNVTV9FUl9GSUxFYAoJaWYg
WyAkeyNNRDVTVU1URVNUfSAtZ3QgMCBdIDsgdGhlbgoJCWVjaG8gIlRoZXJl
IHdlcmUgcHJvYmxlbXMgd2l0aCB0aGUgbWQ1c3Vtcy4gU29tZSBmaWxlcyB3
aWxsIGJlIGRvd25sb2FkZWQgYWdhaW4uIgoJCUZJWAoJCWVjaG8gIiIKCQll
Y2hvICJUZXN0aW5nIG1kNXN1bXMgYWdhaW4iCgkJZWNobyAiIgoJZWxzZQoJ
CWV2YWwgJFJNQklOICRUTVBESVIvJE1ENVNVTV9FUl9GSUxFCgkJYnJlYWsK
CWZpCQpkb25lCQkJCklTTwpleGl0IDAK

------------=_1053409472-8957-0--