Subject: v16i034: Larry Wall's Configure generator, etc., Part01/07 Newsgroups: comp.sources.unix Sender: sources Approved: rsalz@uunet.UU.NET Submitted-by: lwall@jpl-devvax.jpl.nasa.gov (Larry Wall) Posting-number: Volume 16, Issue 34 Archive-name: dist2/part01 #! /bin/sh # Make a new directory for the dist sources, cd to it, and run kits 1 # thru 7 through sh. When all 7 kits have been run, read README. echo "This is dist 2.0 kit 1 (of 7). If kit 1 is complete, the line" echo '"'"End of kit 1 (of 7)"'" will echo at the end.' echo "" export PATH || (echo "You didn't use sh, you clunch." ; kill $$) mkdir kit mcon mcon/U pat 2>/dev/null echo Extracting mcon/README sed >mcon/README <<'!STUFFY!FUNK!' -e 's/X//' XHow to create a Configuration script: X X 1) Consult the Glossary and write your shell scripts and C programs X in terms of the symbols that metaconfig knows how to define. If X your Glossary is out of date you can rebuild it by saying make gloss. X X 2) Copy any .U files that you want to modify to your private U directory X in the current directory. Any .U files in your private U directory X will be used in preference to the standard one. One way to force X inclusion of any unit is to copy the End.U file to your .U directory X and add the name of the unit you want as a dependency on the end X of the ?MAKE: line. Certain units can ONLY be forced in this way, X namely those of the form Warn_*.U and Chk_*.U. You can also customize X certain default Configure variables by copying Myinit.U to your X package's private U directory and setting the variables in that. X For example, you can specify what types of void support your program X needs--see $defvoidused in voidflags.U. X X 3) If you have run metaconfig before in this directory, it created a X Wanted file. If you want to reuse this file, use the -w switch with X metaconfig, and it will skip the scan of your programs for symbols. X This is useful when you are developing a new unit file for metaconfig, X and the programs in question haven't really changed. If you HAVE X changed the symbols you refer to, do not use the -w switch, and X a new Wanted file will be created. Note that you can force inclusion X of a unit by adding its name to the Wanted file, but if you delete X the Wanted file you'll lose that info. X X 4) Say "metaconfig". This should eventually produce Configure. X XHow to add a new unit: X X 1) Copy a similar unit to a new .U file. The name you choose should X be the name of a variable generated by the unit. It should be 12 X or less characters to prevent filename chopping. Actually, it X should probably be 10 or less so that those who want to use RCS X can have a .U,v on the end without chopping. Metaconfig uses X the case of the first letter to determine if any variable is X actually produced by this unit, so don't Capitalize your unit X name if it is supposed to produce a shell variable variable. X X 2) Edit the new .U file to do what you want. The first ?MAKE: line X indicates the dependencies; list before the final colon all the X variables defined, and after the final colon all the variables (or X other units) on which this unit depends. It is very important that X these lists be accurate. IMPORTANT: The first symbol after ?MAKE: X *must* be the name of the file without the .U. X X 3) To the extent possible, parameterize your unit based on shell X variable defined on ?INIT: lines. This will move the variable X definitions up to the Init.U unit, where they can be overridden X by definitions in Myinit.U, which is included after Init.U. X X 4) Add the definition of any C symbols desired as ?H: lines. A line X beginning with ?H:?%1: in the .U file will be added to the eventual X config.h file if and only if metaconfig decides that the first symbol X on the ?MAKE: line is needed. The %1 stands for that first symbol, X which happens to be the name of the file too (without .U). Always put X a comment on each ?H: line in case one of the variable substitutions X earlier on the line starts a comment without finishing it. Any shell X variable starting with d_ may do this, so beware. X X 5) Add glossary definitions as ?S: lines for shell variables and ?C: X lines for C preprocessor variables. Entries are sorted by lines X that match /[a-zA-Z_]:/ (after the ?[CS]:), so start any continuation X lines with tabs (after the ?[CS]:). See a current unit for examples. X It is VERY important to start each entry with a left justified symbol X name, and end each entry with with a ?C:. or ?S:. line. The algorithm X that translates C preprocessor symbol entries for the Glossary into X comments for config.h depends on this. X X 6) Make sure the order of all your ? lines is right. The correct order is: X X ?RCS: and ?X: lines -- basically just comments X ?MAKE: lines -- metaconfig dependencies X ?C: and ?S: lines -- Glossary definitions X ?H: lines -- config.h definitions X X ?INIT: lines can go anywhere. X X 7) Rerun metaconfig. X X 8) Send unit to lwall@jpl-devvax.jpl.nasa.gov (Larry Wall) for inclusion X in the master copy, if you think it's of general interest. X XHow to add a new program to be located: X X 1) Edit Loc.U, and add the name of the program both to the ?MAKE: line X (between the two colons) and to either loclist or trylist (depending X on whether the program is mandatory or not). X X 2) Rerun metaconfig. X X 8) Send unit to lwall@jpl-devvax.jpl.nasa.gov (Larry Wall) for inclusion X in the master copy, if you think it's of general interest. X XNotes for writing .U files: X X Always use "rm -f" because there are systems where rm is interactive by X default. Files which need to be removed at the end of Configure X should be added to the rmlist variable. (rmlist="$rmlist tmpfile") X X Always use echo " " (with a space) because of Eunice systems. X X Use only programs that came with V7, so that you know everyone has X them. X X Use $contains when you want to grep conditionally, since not all X greps return a reasonable status. X X Use "if test" rather than "if [...]" since not every sh knows the X latter construct. X X Use the myread script for inputs so that they can do shell escapes X and default evaluation. The general form is X X case "$grimble" in X '') dflt=452;; X *) dflt="$grimble";; X esac X rp="How many grimbles do you have? [$dflt]" X echo $n "$rp $c" X . myread X grimble="$ans" X X Always try to determine whether a feature is present in the most X specific way--don't say "if bsd" when you can grep libc. There X are many hybrid systems out there, and each feature should stand X or fall by itself. X X When in doubt, set a default and ask. Don't assume anything. X X If you think the user is wrong, allow for the fact that he may be right. X For instance, he could be running Configure on a different system than X he is going to use the final product on. X XMetaconfig reserves the following names in your directory, and if you use such Xa name it may get clobbered or have other unforeseen effects: X X .MT/* X Configure X Wanted X UU/* X XAdditionally, Configure may clobber these names in the directory it is run in: X X UU/* X config.sh X config.h !STUFFY!FUNK! echo Extracting README sed >README <<'!STUFFY!FUNK!' -e 's/X//' X Dist Kit, Version 2.0 X X Copyright (c) 1988, Larry Wall X XYou may copy the dist kit in whole or in part as long as you don't try to Xmake money off it, or pretend that you wrote it. X-------------------------------------------------------------------------- X XPlease read all the directions below before you proceed any further, and Xthen follow them carefully. Failure to do so may void your warranty. :-) X XAfter you have unpacked your kit, you should have all the files listed Xin MANIFEST. Be sure to put everything in a place that is visible to Xeveryone who will be using this package, since there are files in various Xsubdirectories that are referenced. Somewhere in /usr/lib might be Xappropriate. X XInstallation X X1) Run Configure. This will figure out various things about your system. X Some things Configure will figure out for itself, other things it will X ask you about. It will then proceed to make config.h, config.sh, and X Makefile. X X You might possibly have to trim # comments from the front of Configure X if your sh doesn't handle them, but all other # comments will be taken X care of. X X3) make X X This will attempt to make various things. X X4) make install X X This will put several executables into a public directory. It will X also try to put the man pages in a reasonable place. X X5) Read the manual entries before running. X X6) IMPORTANT! Help save the world! Communicate any problems and X suggested patches to me, lwall@jpl-devvax.jpl.nasa.gov (Larry Wall), X so we can keep the world in sync. If you have a problem, there's X someone else out there who either has had or will have the same problem. X X If possible, send in patches such that the patch program will apply them. X Context diffs are the best, then normal diffs. Don't send ed scripts-- X I've probably changed my copy since the version you have. X X Watch for dist patches in comp.sources.bugs. If you are just now bringing X up dist and aren't sure how many patches there are, write to me and I'll X send any you don't have. In fact, I have an automatic patch sender--if X you read a current patch it will tell you how to get any old ones. X X------------------------------------------------------------------------ X XThe dist package consists of three parts: X X 1) The Configure generator (metaconfig) and its supporting files. X 2) The distribution kit maker (makedist) and its supporting files. X 3) The patch distribution system (pat*) and its supporting files. X XEach of these can be used separately from the others. Before you can use Xany of them, however, the directory containing your package (not this Xpackage) must be initialized by putting a .package file into it. This Xcan be done by running packinit in that directory. X X XNotes: X X If you are running on a system with <= 14 char filenames, don't X distribute any files with filenames longer than 11 chars (with the X exception of patchlevel.h), so that there will be room for a X 2-digit extension indicating patch number in your bugs direcory. X This includes .SH files, so any shell script built by a .SH file X should be 8 or less characters. On systems with flexfilenames you X don't have to worry about it. !STUFFY!FUNK! echo Extracting pat/README sed >pat/README <<'!STUFFY!FUNK!' -e 's/X//' XThis directory contains an automatic patch generator. You must have RCS Xto use this. You must also have run packinit in the top level directory Xof your package to create a .package file. X XWhen you've modified a file in your package, the pat program is used to Xcontrol the whole process. The other programs can be called by hand, but Xusually needn't be. Run pat from the top level directory of your package. X XThere is also program called mailagent that will read your incoming mail and Xmail patches to people automatically. You'll have to customize mailpatch Xfor yourself. X XThe pat, patcil, patdiff, and patbase programs take a list of filenames as Xarguments. Alternately, a -a means all files listed in MANIFEST.new. X XPatcil will create an RCS directory if necessary. However, it may not check in Xthings which require special initializaton properly. For example, if you Xwant to check in a shell script, you'd better make your RCS directory yourself Xand then say X X rcs -i -c'# ' blurfl.xsh X Xbefore running pat or patcil. Otherwise the RCS log may not be commented Xproperly. X XPatdiff will create a bugs directory in your top level directory, and will want Xto find a patchlevel.h file in that same directory. Everything is done from Xthat top level directory--don't put any patchlevel.h or bugs directories in Xyour subdirectories. Each subdirectory has its own RCS directory though. X XPatpost, patsend and patftp may be used to post to Usenet, mail to someone, Xor copy patches to your ftp directory. They take a destination and a list Xof patches to process. !STUFFY!FUNK! echo Extracting kit/README sed >kit/README <<'!STUFFY!FUNK!' -e 's/X//' XThis directory contains a rudimentary kit maker. Depending on where you Xare going to send your kits you might prefer to use Rich $alz's kit maker Xinstead--it makes more robust kits but assumes more about the target Xsystem. X XYou run makedist in the top level directory of your package and it uses Xthe MANIFEST.new file to generate shar scripts of about 50000 bytes each. X XMakedist takes no arguments (except a -v for verbose). Just make sure XMANIFEST.new contains everything you want, including any Configure, Xconfig.h.SH, or patchlevel.h files. A prototype patchlevel.h may be Xfound in ../pat/patchlevel.h !STUFFY!FUNK! echo Extracting Configure sed >Configure <<'!STUFFY!FUNK!' -e 's/X//' X#! /bin/sh X# X# If these # comments don't work, trim them. Don't worry about any other X# shell scripts, Configure will trim # comments from them for you. X# X# (If you are trying to port this package to a machine without sh, I would X# suggest you cut out the prototypical config.h from the end of Configure X# and edit it to reflect your system. Some packages may include samples X# of config.h for certain machines, so you might look for one of those.) X# X# $Header: Configure,v 2.0 88/06/28 23:11:40 lwall Locked $ X# X# Yes, you may rip this off to use in other distribution packages. X# (Note: this Configure script was generated automatically. Rather than X# working with this copy of Configure, you may wish to get metaconfig.) X X: sanity checks XPATH='.:/bin:/usr/bin:/usr/local/bin:/usr/ucb:/usr/local:/usr/lbin:/etc:/usr/new:/usr/new/bin:/usr/nbin' Xexport PATH || (echo "OOPS, this isn't sh. Desperation time. I will feed myself to sh."; sh $0; kill $$) X Xif test ! -t 0; then X echo "Say 'sh Configure', not 'sh /dev/null 2>&1 && \ X echo "(I see you are using the Korn shell. Some ksh's blow up on Configure," && \ X echo "especially on exotic machines. If yours does, try the Bourne shell instead.)" X Xif test ! -d ../UU; then X if test ! -d UU; then X mkdir UU X fi X cd UU Xfi X Xcase "$1" in X-d) shift; fastread='yes';; Xesac X Xd_eunice='' Xeunicefix='' Xdefine='' Xloclist='' Xexpr='' Xsed='' Xecho='' Xcat='' Xrm='' Xmv='' Xcp='' Xtail='' Xtr='' Xmkdir='' Xsort='' Xuniq='' Xgrep='' Xtrylist='' Xtest='' Xinews='' Xegrep='' Xmore='' Xpg='' XMcc='' Xvi='' Xmailx='' Xmail='' Xcpp='' XLog='' XHeader='' Xbin='' Xcontains='' Xdefeditor='' Xhostname='' Xphostname='' Xmydomain='' Xlibc='' Xmansrc='' Xmanext='' Xn='' Xc='' Xnametype='' Xd_passnames='' Xd_berknames='' Xd_usgnames='' Xpasscat='' Xorgname='' Xpackage='' Xspitshell='' Xshsharp='' Xsharpbang='' Xstartsh='' XCONFIG='' X: set package name Xpackage=dist X Xecho " " Xecho "Beginning of configuration questions for $package kit." X: Eunice requires " " instead of "", can you believe it Xecho " " X Xdefine='define' Xundef='undef' Xlibpth='/usr/lib /usr/local/lib /lib' Xsmallmach='pdp11 i8086 z8000 i80286 iAPX286' Xrmlist='kit[1-9]isdone kit[1-9][0-9]isdone' Xtrap 'echo " "; rm -f $rmlist; exit 1' 1 2 3 X X: We must find out about Eunice early Xeunicefix=':' Xif test -f /etc/unixtovms; then X eunicefix=/etc/unixtovms Xfi Xif test -f /etc/unixtovms.exe; then X eunicefix=/etc/unixtovms.exe Xfi X Xattrlist="mc68000 sun gcos unix ibm gimpel interdata tss os mert pyr" Xattrlist="$attrlist vax pdp11 i8086 z8000 u3b2 u3b5 u3b20 u3b200" Xattrlist="$attrlist ns32000 ns16000 iAPX286 mc300 mc500 mc700 sparc" Xattrlist="$attrlist nsc32000 sinix xenix venix posix ansi M_XENIX" Xattrlist="$attrlist $mc68k __STDC__" Xpth="/usr/ucb /bin /usr/bin /usr/local /usr/local/bin /usr/lbin /etc /usr/lib /lib" Xd_newshome="../../NeWS" Xdefvoidused=7 X X: some greps do not return status, grrr. Xecho "grimblepritz" >grimble Xif grep blurfldyick grimble >/dev/null 2>&1 ; then X contains=contains Xelif grep grimblepritz grimble >/dev/null 2>&1 ; then X contains=grep Xelse X contains=contains Xfi Xrm -f grimble X: the following should work in any shell Xcase "$contains" in Xcontains*) X echo " " X echo "AGH! Grep doesn't return a status. Attempting remedial action." X cat >contains <<'EOSS' Xgrep "$1" "$2" >.greptmp && cat .greptmp && test -s .greptmp XEOSS Xchmod +x contains Xesac X X: first determine how to suppress newline on echo command Xecho "Checking echo to see how to suppress newlines..." X(echo "hi there\c" ; echo " ") >.echotmp Xif $contains c .echotmp >/dev/null 2>&1 ; then X echo "...using -n." X n='-n' X c='' Xelse X cat <<'EOM' X...using \c XEOM X n='' X c='\c' Xfi Xecho $n "Type carriage return to continue. Your cursor should be here-->$c" Xread ans Xrm -f .echotmp X X: now set up to do reads with possible shell escape and default assignment Xcat <myread Xcase "\$fastread" in Xyes) ans=''; echo " " ;; X*) ans='!';; Xesac Xwhile expr "X\$ans" : "X!" >/dev/null; do X read ans X case "\$ans" in X !) X sh X echo " " X echo $n "\$rp $c" X ;; X !*) X set \`expr "X\$ans" : "X!\(.*\)\$"\` X sh -c "\$*" X echo " " X echo $n "\$rp $c" X ;; X esac Xdone Xrp='Your answer:' Xcase "\$ans" in X'') ans="\$dflt";; Xesac XEOSC X X: general instructions Xcat <loc X$startsh Xcase \$# in X0) exit 1;; Xesac Xthing=\$1 Xshift Xdflt=\$1 Xshift Xfor dir in \$*; do X case "\$thing" in X .) X if test -d \$dir/\$thing; then X echo \$dir X exit 0 X fi X ;; X *) X if test -f \$dir/\$thing; then X echo \$dir/\$thing X exit 0 X elif test -f \$dir/\$thing.exe; then X : on Eunice apparently X echo \$dir/\$thing X exit 0 X fi X ;; X esac Xdone Xecho \$dflt Xexit 1 XEOSC Xchmod +x loc X$eunicefix loc Xloclist=" Xexpr Xsed Xecho Xcat Xrm Xgrep X" Xtrylist=" Xtest Xinews Xvi X" Xfor file in $loclist; do X xxx=`loc $file $file $pth` X eval $file=$xxx X eval _$file=$xxx X case "$xxx" in X /*) X echo $file is in $xxx. X ;; X *) X echo "I don't know where $file is. I hope it's in everyone's PATH." X ;; X esac Xdone Xecho " " Xecho "Don't worry if any of the following aren't found..." Xans=offhand Xfor file in $trylist; do X xxx=`loc $file $file $pth` X eval $file=$xxx X eval _$file=$xxx X case "$xxx" in X /*) X echo $file is in $xxx. X ;; X *) X echo "I don't see $file out there, $ans." X ans=either X ;; X esac Xdone Xcase "$egrep" in Xegrep) X echo "Substituting grep for egrep." X egrep=$grep X ;; Xesac Xcase "$test" in Xtest) X echo "Hopefully test is built into your sh." X ;; X/bin/test) X echo " " X dflt=n X rp="Is your "'"'"test"'"'" built into sh? [$dflt] (OK to guess)" X echo $n "$rp $c" X . myread X case "$ans" in X y*) test=test ;; X esac X ;; X*) X test=test X ;; Xesac Xcase "$echo" in Xecho) X echo "Hopefully echo is built into your sh." X ;; X/bin/echo) X echo " " X echo "Checking compatibility between /bin/echo and builtin echo (if any)..." X $echo $n "hi there$c" >foo1 X echo $n "hi there$c" >foo2 X if cmp foo1 foo2 >/dev/null 2>&1; then X echo "They are compatible. In fact, they may be identical." X else X case "$n" in X '-n') n='' c='\c' ans='\c' ;; X *) n='-n' c='' ans='-n' ;; X esac X cat </dev/null | sed -n -e 's/^.* T _//p' -e 's/^.* T //p' > libc.list Xif $contains '^printf$' libc.list >/dev/null 2>&1; then X echo "done" Xelse X nm $libc 2>/dev/null | sed -n -e 's/^.* D _//p' -e 's/^.* D //p' > libc.list X if $contains '^printf$' libc.list >/dev/null 2>&1; then X echo "done" X else X echo " " X echo "nm didn't seem to work right." X echo "Trying ar instead..." X rmlist="$rmlist libc.tmp" X if ar t $libc > libc.tmp; then X sed -e 's/\.o$//' < libc.tmp > libc.list X echo "Ok." X else X echo "ar didn't seem to work right." X echo "Maybe this is a Cray...trying bld instead..." X if bld t $libc | sed -e 's/.*\///' -e 's/\.o:.*$//' > libc.list; then X echo "Ok." X else X echo "That didn't work either. Giving up." X exit 1 X fi X fi X fi Xfi Xrmlist="$rmlist libc.list" X X: make some quick guesses about what we are up against Xecho " " X$echo $n "Hmm... $c" Xif $contains SIGTSTP /usr/include/signal.h >/dev/null 2>&1 ; then X echo "Looks kind of like a BSD system, but we'll see..." X echo exit 0 >bsd X echo exit 1 >usg X echo exit 1 >v7 Xelif $contains '^fcntl$' libc.list >/dev/null 2>&1 ; then X echo "Looks kind of like a USG system, but we'll see..." X echo exit 1 >bsd X echo exit 0 >usg X echo exit 1 >v7 Xelse X echo "Looks kind of like a version 7 system, but we'll see..." X echo exit 1 >bsd X echo exit 1 >usg X echo exit 0 >v7 Xfi Xif $contains '^vmssystem$' libc.list >/dev/null 2>&1 ; then X cat <<'EOI' XThere is, however, a strange, musty smell in the air that reminds me of Xsomething...hmm...yes...I've got it...there's a VMS nearby, or I'm a Blit. XEOI X echo "exit 0" >eunice X eunicefix=unixtovms X d_eunice="$define" X: it so happens the Eunice I know will not run shell scripts in Unix format Xelse X echo " " X echo "Congratulations. You aren't running Eunice." X eunicefix=':' X d_eunice="$undef" X echo "exit 1" >eunice Xfi Xif test -f /xenix; then X echo "Actually, this looks more like a XENIX system..." X echo "exit 0" >xenix Xelse X echo " " X echo "It's not Xenix..." X echo "exit 1" >xenix Xfi Xchmod +x xenix X$eunicefix xenix Xif test -f /venix; then X echo "Actually, this looks more like a VENIX system..." X echo "exit 0" >venix Xelse X echo " " X if xenix; then X : null X else X echo "Nor is it Venix..." X fi X echo "exit 1" >venix Xfi Xchmod +x bsd usg v7 eunice venix X$eunicefix bsd usg v7 eunice venix Xrmlist="$rmlist bsd usg v7 eunice venix xenix" X X: see if sh knows # comments Xecho " " Xecho "Checking your sh to see if it knows about # comments..." Xif sh -c '#' >/dev/null 2>&1 ; then X echo "Your sh handles # comments correctly." X shsharp=true X spitshell=cat X echo " " X echo "Okay, let's see if #! works on this system..." X echo "#!/bin/echo hi" > try X $eunicefix try X chmod +x try X try > today X if $contains hi today >/dev/null 2>&1; then X echo "It does." X sharpbang='#!' X else X echo "#! /bin/echo hi" > try X $eunicefix try X chmod +x try X try > today X if test -s today; then X echo "It does." X sharpbang='#! ' X else X echo "It doesn't." X sharpbang=': use ' X fi X fi Xelse X echo "Your sh doesn't grok # comments--I will strip them later on." X shsharp=false X echo "exec grep -v '^#'" >spitshell X chmod +x spitshell X $eunicefix spitshell X spitshell=`pwd`/spitshell X echo "I presume that if # doesn't work, #! won't work either!" X sharpbang=': use ' Xfi X X: figure out how to guarantee sh startup Xecho " " Xecho "Checking out how to guarantee sh startup..." Xstartsh=$sharpbang'/bin/sh' Xecho "Let's see if '$startsh' works..." Xcat >try <filexp <&2 X exit 1 X fi X case "\$1" in X */*) X echo \$dir/\`$expr x\$1 : '..[^/]*/\(.*\)'\` X ;; X *) X echo \$dir X ;; X esac X fi X ;; X*) X echo \$1 X ;; Xesac XEOSS Xchmod +x filexp X$eunicefix filexp X X: determine where public executables go Xcase "$bin" in X'') X dflt=`loc . /bin /usr/local/bin /usr/lbin /usr/local /usr/bin` X ;; X*) dflt="$bin" X ;; Xesac Xcont=true Xwhile $test "$cont" ; do X echo " " X rp="Where do you want to put the public executables? [$dflt]" X $echo $n "$rp $c" X . myread X bin="$ans" X bin=`filexp $bin` X if test -d $bin; then X cont='' X else X dflt=n X rp="Directory $bin doesn't exist. Use that name anyway? [$dflt]" X $echo $n "$rp $c" X . myread X dflt='' X case "$ans" in X y*) cont='';; X esac X fi Xdone X X: determine default editor Xcase "$defeditor" in X'') X case "$_vi" in X */*) dflt="$_vi";; X *) dflt=/usr/ucb/vi;; X esac X ;; X*) dflt="$defeditor" X ;; Xesac Xcont=true Xwhile $test "$cont" ; do X echo " " X rp="What is the default editor on your system? [$dflt]" X $echo $n "$rp $c" X . myread X defeditor="$ans" X if test -f $ans; then X cont='' X else X dflt=n X rp="File $ans doesn't exist. Use that name anyway? [$dflt]" X $echo $n "$rp $c" X . myread X dflt='' X case "$ans" in X y*) cont='';; X esac X fi Xdone X X: now get the host name Xecho " " Xecho "Figuring out host name..." Xecho 'Maybe "hostname" will work...' Xif ans=`sh -c hostname 2>&1` ; then X hostname=$ans X phostname=hostname Xelse X echo 'Oh, dear. Maybe "/etc/systemid" is the key...' X if ans=`cat /etc/systemid 2>&1` ; then X hostname=$ans X phostname='cat /etc/systemid' X if xenix; then X echo "Whadyaknow. Xenix always was a bit strange..." X else X echo "What is a non-Xenix system doing with /etc/systemid?" X fi X else X echo 'No, maybe "uuname -l" will work...' X if ans=`sh -c 'uuname -l' 2>&1` ; then X hostname=$ans X phostname='uuname -l' X else X echo 'Strange. Maybe "uname -n" will work...' X if ans=`sh -c 'uname -n' 2>&1` ; then X hostname=$ans X phostname='uname -n' X else X echo 'Oh well, maybe I can mine it out of whoami.h...' X if ans=`sh -c $contains' sysname /usr/include/whoami.h' 2>&1` ; then X hostname=`echo "$ans" | $sed 's/^.*"\(.*\)"/\1/'` X phostname="sed -n -e '"'/sysname/s/^.*\"\\(.*\\)\"/\1/{'"' -e p -e q -e '}' config.sh X$startsh X# config.sh X# This file was produced by running the Configure script. X Xd_eunice='$d_eunice' Xeunicefix='$eunicefix' Xdefine='$define' Xloclist='$loclist' Xexpr='$expr' Xsed='$sed' Xecho='$echo' Xcat='$cat' Xrm='$rm' Xmv='$mv' Xcp='$cp' Xtail='$tail' Xtr='$tr' Xmkdir='$mkdir' Xsort='$sort' Xuniq='$uniq' Xgrep='$grep' Xtrylist='$trylist' Xtest='$test' Xinews='$inews' Xegrep='$egrep' Xmore='$more' Xpg='$pg' XMcc='$Mcc' Xvi='$vi' Xmailx='$mailx' Xmail='$mail' Xcpp='$cpp' XLog='$Log' XHeader='$Header' Xbin='$bin' Xcontains='$contains' Xdefeditor='$defeditor' Xhostname='$hostname' Xphostname='$phostname' Xmydomain='$mydomain' Xlibc='$libc' Xmansrc='$mansrc' Xmanext='$manext' Xn='$n' Xc='$c' Xnametype='$nametype' Xd_passnames='$d_passnames' Xd_berknames='$d_berknames' Xd_usgnames='$d_usgnames' Xpasscat='$passcat' Xorgname='$orgname' Xpackage='$package' Xspitshell='$spitshell' Xshsharp='$shsharp' Xsharpbang='$sharpbang' Xstartsh='$startsh' XCONFIG=true XEOT X XCONFIG=true X Xecho " " Xdflt='' Xfastread='' Xecho "If you didn't make any mistakes, then just type a carriage return here." Xrp="If you need to edit config.sh, do it as a shell escape here:" X$echo $n "$rp $c" X. UU/myread Xcase "$ans" in X'') ;; X*) : in case they cannot read X eval $ans;; Xesac X. ./config.sh X Xecho " " Xecho "Doing variable substitutions on .SH files..." Xset x `awk '{print $1}' /dev/null 2>&1; then X dflt=n X $cat < makedepend.out &" XIt can take a while, so you might not want to run it right now. X XEOM X rp="Run make depend now? [$dflt]" X $echo $n "$rp $c" X . UU/myread X case "$ans" in X y*) make depend X echo "Now you must run a make." X ;; X *) echo "You must run 'make depend' then 'make'." X ;; X esac Xelif test -f Makefile; then X echo " " X echo "Now you must run a make." Xelse X echo "Done." Xfi X X$rm -f kit*isdone X: the following is currently useless Xcd UU && $rm -f $rmlist X: since this removes it all anyway Xcd .. && $rm -rf UU X: end of Configure !STUFFY!FUNK! echo Extracting mcon/metaconfig.SH sed >mcon/metaconfig.SH <<'!STUFFY!FUNK!' -e 's/X//' Xcase $CONFIG in X'') X if test ! -f config.sh; then X ln ../config.sh . || \ X ln ../../config.sh . || \ X ln ../../../config.sh . || \ X (echo "Can't find config.sh."; exit 1) X echo "Using config.sh from above..." X fi X . ./config.sh X ;; Xesac X: This forces SH files to create target in same directory as SH file. X: This is so that make depend always knows where to find SH derivatives. Xcase "$0" in X*/*) cd `expr X$0 : 'X\(.*\)/'` ;; Xesac Xecho "Extracting metaconfig (with variable substitutions)" Xcat >metaconfig <>metaconfig <<'!NO!SUBS!' X$ENV{'MC'} = $MC; Xchop($WD=`pwd`); X$ENV{'WD'} = $WD; X Xdo 'getopt.pl'; Xdo Getopt(""); X X++$opt_v if $opt_V; X Xunlink 'Wanted' unless $opt_w; X X$NEWMANI = 'MANIFEST.new'; X$MANI = 'MANIFEST'; X Xdo readpackage(); X X$ENV{'package'} = $package; X X`mkdir .MT 2>&1` unless -d '.MT'; X Xprint "Locating units...\n" if $opt_v; Xif (-d 'U') { X chdir 'U'; X foreach $file (<*.U>) { X push(@myUlist,"$WD/U/$file"); X $myUseen{$file} = 1; X } X chdir '..'; X} X Xchdir "$MC/U" || die "Can't find $MC/U.\n"; Xforeach $file (<*.U>) { X if ($myUseen{$file}) { X print " Your private U/$file overrides the public one.\n" if $opt_v; X } X else { X push(@ARGV,$file); X } X} Xpush(@ARGV,@myUlist); X Xif ($opt_V) { X print "\t"; X $, = "\n\t"; X print @ARGV; X $, = ''; X print "\n"; X} X Xprint "Extracting dependency lists from units...\n" if $opt_v; X$dependencies = ' ' x 10000; # pre-extend X$dependencies = ''; Xopen(INIT,">$WD/.MT/.Init.U") || die "Can't create $WD/.MT/.Init.U\n"; Xopen(CONF_H,">$WD/.MT/.Config_h.U") || die "Can't create $WD/.MT/.Config_h.U\n"; Xline: while (<>) { X if (/^\?MAKE:[\w ]*:/) { X s|^\?MAKE:\s*||; X $dependencies .= $_; X chop; X s/:.*//; X @ary = split(' '); X $hold = join(' ',@ary); X $unit = $ary[0]; X foreach $sym (@ary) { X if ($sym =~ /^([a-z]|Mcc|Log|Header)/) { X $shmaster{"\$$sym"} = '#'; X push(@Master,"?$unit:$sym=''\n"); X } X } X next line; X } X if (/^\?C:/) { X s|^\?C:([A-Za-z_])|?H:?%1:/* $1|; X s|^\?C:\.\s*$|?H:?%1: */\n|; X s|^\?C:(.*)|?H:?%1: *$1|; X } X s/%\*/$hold/; X s/%1/$unit/; X $dependencies .= $_ if s|^\?MAKE:||; X print INIT if s|^\?INIT:||; X print CONF_H if s|^\?H:||; X} Xprint $dependencies if $opt_V; Xprint CONF_H "!GROK!THIS!\n"; Xclose DEP; Xclose INIT; Xclose CONF_H; Xclose MASTER; X Xchdir $WD; X Xunless (-f 'Wanted') { X print "Building a Wanted file...\n" if $opt_v; X open(WANTED,"| sort | uniq >Wanted") || die "Can't create Wanted.\n"; X unless (-f $NEWMANI) { X do manifake(); X die "No $NEWMANI--can't build a Wanted file.\n" unless -f $NEWMANI; X } X X print " Extracting filenames (*.[chy] and *.SH) from $NEWMANI...\n" X if $opt_v; X open(NEWMANI,$NEWMANI) || die "Can't open $NEWMANI"; X while () { X ($file) = split(' '); X next if $file eq 'config.h.SH'; X push(@SHlist,$file) if $file =~ /\.SH$/; X push(@clist,$file) if $file =~ /\.[chy]$/; X } X X print " Extracting symbols from Config_h.U...\n" if $opt_v; X if (-f 'U/Config_h.U') { X @ARGV = ('U/Config_h.U', '.MT/.Config_h.U'); X } X else { X @ARGV = ("$MC/U/Config_h.U", '.MT/.Config_h.U'); X } X while (<>) { X next unless /^\?\w*:#.*\$/; X s|^[^#]*#||; X if (s|^\$(\w+)\s*(\w+).*\$(\w+).*$|$2 $1\n$2 $3|) { X $cmaster{$2} = '#'; X $cwanted{$2} = "$1\n$3"; X } X elsif (s|^\$(\w+)\s*(\w+).*$|$2 $1|) { X $cmaster{$2} = '#'; X $cwanted{$2} = $1; X } X elsif (s|^define\s*(\w+).*\$(\w+).*$|$1 $2|) { X $cmaster{$1} = '#'; X $cwanted{$1} = $2; X } X } X X # Now we are a little clever, and build a loop to eval so that we don't X # have to recompile our patterns on every file. We also use "study" since X # we are searching the same string for many different things. Hauls! X X unless ($#clist < 0) { X print " Scanning .c and .h files for symbols...\n" if $opt_v; X $search = "while (<>) {study;\n"; # init loop over ARGV X foreach $key (keys(cmaster)) { X $search .= "\$cmaster{'$key'}++ if /\\b$key\\b/;\n"; X } X $search .= "}\n"; # terminate loop X @ARGV = @clist; X $/ = "\001"; # swallow each file whole (delete if memory is limited) X eval $search; X $/ = "\n"; X while (($key,$value) = each(cmaster)) { X if ($value ne '#') { X print WANTED $cwanted{$key}, "\n"; X } X } X } X X print " Scanning .SH files for symbols...\n" if $opt_v; X close WANTED; X open(WANTED,"| sort | uniq >>Wanted") || die "Can't create Wanted.\n"; X $search = "while (<>) {study;\n"; X foreach $key (keys(shmaster)) { X $search .= "\$shmaster{'$key'}++ if /\\$key\\b/;\n"; X } X $search .= "}\n"; X @ARGV = @SHlist; X $/ = "\001"; # (delete if memory is limited) X eval $search; X $/ = "\n"; X# while (<>) { X# @ary = split(/[^\w\$]+/); X# for (@ary) { X# $shmaster{$_}++ if $shmaster{$_}; # assuming most don't match X# } X# } X while (($key,$value) = each(shmaster)) { X if ($value ne '#') { X $key =~ s/^\$//; X print WANTED $key, "\n"; X } X } X} Xclose WANTED; X Xdie "No desirable symbols found--aborting.\n" unless -s 'Wanted'; X Xprint "Building private make file...\n" if $opt_v; X$/ = "\001"; # change record separtor to nonexistent char Xopen(WANTED,"Wanted") || die "Can't reopen Wanted.\n"; X$_ = ; # slurp whole file; X$/ = "\n"; Xy/\n/ /; Xopen(MAKEFILE,">.MT/.Makefile") || die "Can't create .MT/.Makefile.\n"; Xprint MAKEFILE "W = $_\n"; Xprint MAKEFILE $dependencies; Xclose MAKEFILE; X Xprint "Determining the correct order for the units...\n" if $opt_v; Xchdir '.MT' || die "Can't chdir to .MT"; Xopen(MAKE, "make -n -f .Makefile|") || die "Can't run make"; Xwhile () { X print "\t$_" if $opt_V; X if (/^pick/) { X ($pick,$cmd,$symbol,$unit) = split(' '); X $symwanted{$symbol}++; X unless ($unitseen{$unit}++) { X push(@cmdwanted,"$cmd $unit"); X $symwanted{$unit}++; X } X } X else { X chop; X system; X } X} Xclose MAKE; X Xprint "Creating Configure...\n" if $opt_v; Xopen(CONFIGURE,">$WD/Configure") || die "Can't create Configure.\n"; Xopen(CONF_H,">$WD/config.h.SH") || die "Can't create config.h.SH.\n"; Xfor (@cmdwanted) { X ($cmd,$unit) = split; X $dir = ($myUseen{$unit} ? $WD : $MC); X $unit .= '.U'; X if (m|/|) { X $file = $unit; # they must know what they're doing X } X elsif ($myUseen{$unit}) { X $file = "$WD/U/$unit"; # they MIGHT know what they're doing X } X else { X $file = "$MC/U/$unit"; # normal case X } X die "Can't open $file" unless open(UNIT,$file); X print "\t$cmd $file\n" if $opt_V; X if ($cmd eq 'add') { X while () { X print CONFIGURE unless /^\?/; X } X } X elsif ($cmd eq 'weed') { X while () { X if (/^\?(\w+):/) { X s/^\?\w+:// if $symwanted{$1}; X } X print CONFIGURE unless /^\?/; X } X } X elsif ($cmd eq 'add.package') { X while () { X s/PACKAGENAME/$package/g; X print CONFIGURE unless /^\?/; X } X } X elsif ($cmd eq 'add.Null') { X for (@Master) { X if (/^\?(\w+):/) { X s/^\?\w+:// if $symwanted{$1}; X } X print CONFIGURE unless /^\?/; X } X while () { X print CONFIGURE unless /^\?/; X } X print CONFIGURE "CONFIG=''\n"; X } X elsif ($cmd eq 'add.Config_sh') { X while () { X print CONFIGURE unless /^\?/; X } X for (@Master) { X if (/^\?(\w+):/) { X s/^\?\w+:// if $symwanted{$1}; X } X s/^(\w+)=''/$1='\$$1'/; X print CONFIGURE unless /^\?/; X } X print CONFIGURE "CONFIG=true\nEOT\n\n"; X } X elsif ($cmd eq 'c_h_weed') { X while () { X if (/^\?(\w+):/) { X s/^\?\w+:// if $symwanted{$1}; X } X print CONF_H unless /^\?/; X } X } X else { X die "Unrecognized command from .Makefile: $cmd\n"; X } X close UNIT; X} Xclose CONFIGURE; Xclose CONF_H; X Xchdir $WD || die "Can't cd back to $WD\n"; X`chmod +x Configure`; X Xif (-f 'config.h.SH') { X open(NEWMANI,$NEWMANI); X $/ = "\001"; X $_ = ; X $/ = "\n"; X close NEWMANI; X unless (/config\.h\.SH/) { X print "Adding config.h.SH to your $NEWMANI file...\n" if $opt_v; X `echo "config.h.SH Produces config.h." >>$NEWMANI`; X } X} Xif ($opt_V) { X print "Leaving subdirectory .MT unremoved so you can peruse it.\n"; X} Xelse { X `rm -rf .MT 2>&1`; X} Xprint "Done.\n" if $opt_v; X Xsub readpackage { X if (! -f '.package') { X if (-f '../.package' || -f '../../.package') { X die "Run in top level directory only.\n"; X } X else { X die "No .package file! Run packinit.\n"; X } X } X open(package,'.package'); X while () { X next if /^:/; X next if /^#/; X if (($var,$val) = /^\s*(\w+)=(.*)/) { X $val = "\"$val\"" unless $val =~ /^['"]/; X eval "\$$var = $val;"; X } X } X close package; X} X Xsub manifake { X # make MANIFEST and MANIFEST.new say the same thing X if (! -f $NEWMANI) { X if (-f $MANI) { X open(IN,$MANI) || die "Can't open $MANI"; X open(OUT,">$NEWMANI") || die "Can't create $NEWMANI"; X while () { X next if 1 .. /---/; X s/(\s+)[0-9]*\s*/$1/; X } X close IN; close OUT; X } X else { Xdie "You need to make a MANIFEST.new file, with names and descriptions.\n"; X } X } X} X!NO!SUBS! Xchmod +x metaconfig X$eunicefix metaconfig !STUFFY!FUNK! echo Extracting mcon/U/mailfile.U sed >mcon/U/mailfile.U <<'!STUFFY!FUNK!' -e 's/X//' X?RCS:$Header: mailfile.U,v 2.0 88/06/28 23:17:09 lwall Locked $ X?RCS: $Log: mailfile.U,v $ X?RCS: Revision 2.0 88/06/28 23:17:09 lwall X?RCS: Baseline. X?RCS: X?MAKE:mailfile: test echo n c Myread Loc Filexp Oldconfig X?MAKE: -pick add $@ %* X?S:mailfile: X?S: This variable contains the eventual value of the MAILFILE symbol, X?S: which contains an interpretable name of the mail spool file for the X?S: current user. X?S:. X?C:MAILFILE: X?C: This symbol contains the interpretable name of the mail spool file X?C: for the current user. The program must be prepared to substitute X?C: the HOME directory for %~, and the login id for %L. X?C:. X?H:?%1:#define MAILFILE "$mailfile" /**/ X?H:?%1: X: determine where mail is spooled Xcase "$mailfile" in X'') X dflt=`loc . XXX /usr/spool/mail /usr/mail` X case "$dflt" in X XXX) dflt='%~/mailbox';; X *) dflt="$dflt/%L";; X esac X ;; X*) dflt="$mailfile" X ;; Xesac Xcat <<'EOM' X XIn the following question, you may use %~ to represent the user's home Xdirectory, and %L to represent a users name. X XEOM Xrp="Where is yet-to-be-read mail spooled? [$dflt]" X$echo $n "$rp $c" X. myread Xmailfile=`filexp "$ans"` X !STUFFY!FUNK! echo "" echo "End of kit 1 (of 7)" cat /dev/null >kit1isdone run='' config='' for iskit in 1 2 3 4 5 6 7; do if test -f kit${iskit}isdone; then run="$run $iskit" else todo="$todo $iskit" fi done case $todo in '') echo "You have run all your kits. Please read README and then type Configure." chmod 755 Configure ;; *) echo "You have run$run." echo "You still need to run$todo." ;; esac : Someone might mail this, so... exit