[comp.sources.misc] v02i040: linksrc - ease source maintenance over heterogenous NFS

joe@hanauma.STANFORD.EDU (Joe Dellinger) (02/03/88)

Comp.sources.misc: Volume 2, Issue 40
Submitted-By: "Joe Dellinger" <joe@hanauma.STANFORD.EDU>
Archive-Name: linksrc

#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
#	README
#	binary.c
#	corr
#	linksrc
# This archive created: Wed Jan 27 23:44:03 1988
export PATH; PATH=/bin:$PATH
if test -f 'README'
then
	echo shar: will not over-write existing file "'README'"
else
sed 's/^J //' << \SHAR_EOF > 'README'
J Linksrc:
J 
J 	This is our solution to the problem of many UNIX machines NFS'd together,
J sharing the same source code but with incompatible object and executable files.
J The simplest solution is simply to maintain a copy of the source on one of each
J type of machine. This is a bad idea as it invites such problems as divergent
J source, loss of bug fixes, archaic copies of files surviving to cause trouble,
J etc, etc.
J 
J 	Another solution would be to have a "smart" version of Make, one that
J knows about different kinds of machines, keeps track of .o and .a files for
J different kinds of machines, etc, etc. This would be nice, but would involve
J first GETTING such a magical smart "make" and then trying to get it to work
J with what you've already got with the least bother. Ug.
J 
J 	My solution is inelegant, but simple. One central machine will maintain
J the "master copy" of the "official device-independent source". For each kind
J of machine that you need to separately compile the source on, there will be
J one machine that contains the "shadow copy" of the "official device-independent
J source". Now, we would be back to the problem of having multiple copies of
J the source again, but there's a simple trick. Mount the "master copy" on
J each machine via NFS. Have all the device-independent source files in the
J "shadow copy" be mere symbolic links to the "master copy". The device
J dependent files are not linked.
J 
J 	For example, you can have a directory like this:
J 
J On the "master machine", a C-1:
J cd /usr/src/graphics/vplot/util
J ls -l
J total 65
J -rw-rw-r--  1 rick          409 Nov  8 23:06 Makefile
J -rw-rw-r--  1 rick          200 Nov  8 23:06 README
J -rw-rw-r--  1 rick        11419 Jan 27 00:06 plas.c
J -rw-rw-r--  1 rick        24727 Jan 20 23:16 plas.o
J -rw-rw-r--  1 rick        10150 Jan 27 00:06 pldb.c
J -rw-rw-r--  1 rick        14873 Jan 20 23:17 pldb.o
J -rwxrwxr-x  1 rick          564 Nov  8 23:06 tube.example
J 
J The "shadow" version of the same directory on another machine, a Sun 3:
J cd /usr/src/sepsrc/vplot/util
J ls -l
J total 106
J -rw-rw-r--  1 joe           442 Jan 20  1988 Makefile
J lrwxrwxrwx  1 root           36 Jan 27  1988 README -> /husr/src/graphics/vplot/util/README
J -rwxrwxr-x  1 root        40960 Jan 20  1988 plas
J lrwxrwxrwx  1 root           36 Jan 27  1988 plas.c -> /husr/src/graphics/vplot/util/plas.c
J -rw-rw-r--  1 root        11941 Jan 20  1988 plas.o
J -rwxrwxr-x  1 root        40960 Jan 20  1988 pldb
J lrwxrwxrwx  1 root           36 Jan 27  1988 pldb.c -> /husr/src/graphics/vplot/util/pldb.c
J -rw-rw-r--  1 root         8275 Jan 20  1988 pldb.o
J lrwxrwxrwx  1 root           42 Jan 27  1988 tube.example -> /husr/src/graphics/vplot/util/tube.example
J 
J 
J 	We thus have 2 copies of the source on 2 different machines.
J "Make" will work on both without conflict, and the machine independent
J files (here the .c's, the README, and tube.example) are guaranteed to not
J diverge. Note that Make looks at the last-modified date of the linked-to file,
J not the link itself. This trick also makes it much easier to avoid redundancy
J when doing source backups.
J 
J ########################################################################
J 
J Now that I've explained the reasoning, here's the program:
J 
J Linksrc is the csh I created to make it easier to set this all up.
J Do
J linksrc master_directory shadow_directory
J 
J It will work through all subdirectories of the master_directory,
J either linking or copying appropriate files to the corresponding
J position in the shadow_directory. 
J Here are the rules:
J If there is already a file in the shadow source directory, or a link
J that points to something that exists, that file will be left alone.
J If the master copy of the file is a
J .o file, .a file, a "special" file, or a non-ASCII file (unless ending in .v),
J nothing will be done.
J If the master copy of the file matches
J the patterns "[mM]ake*", "install*", "param*.h", "site*.h",
J "machdep*", or "mach_dep*", the file will be copied instead of linked.
J Otherwise the shadow copy of the file will be a symbolic link to the
J master copy.
J 
J Whenever a new directory needs to be created, you will be asked whether
J you want it created. If you do not let it create it, then all shadow source
J directories under it will be automatically skipped.
J 
J The file "corr" (you might want to change the name of it, and make it a
J hard path name) should contain a set of "sed" substitutions for changing
J master directory names to shadow directory names. Make sure to list longer
J substitution strings first! I provide a copy of a "corr" file for our
J machine.
J 
J The program "binary" is used to tell whether a file is binary or not.
J I would have used the "file" command, but have discovered that "file"
J commands can say silly things about files on other machines. You will
J need to compile and install the "binary" program.
J 
J You may want to periodically update the links to catch master files that
J have changed names, been newly created, or disappeared. You can do this from
J crontab once a day or so, like thus:
J yes no | linksrc ....
J The "yes" command will always answer "no" when linksrc asks whether it
J should create a new directory.
J 
J #######################################################
J 
J Anyway, hope other people find this trick useful.
J You'll probably want to modify the innards of linksrc a bit to adapt
J it to your local situations. I distribute this strictly as-is. If you
J can't figure out how it works, or you do something stupid to yourself
J with it, tough!
J 
J - Joe Dellinger
J joe@hanauma.stanford.edu
J decvax!hanauma!joe
SHAR_EOF
if test 5479 -ne "`wc -c < 'README'`"
then
	echo shar: error transmitting "'README'" '(should have been 5479 characters)'
fi
fi # end of overwriting check
if test -f 'binary.c'
then
	echo shar: will not over-write existing file "'binary.c'"
else
sed 's/^J //' << \SHAR_EOF > 'binary.c'
J /*
J  * See if a file is Ascii or not.
J  *
J  * Keyword: binary file status
J  */
J 
J #include <stdio.h>
J main()
J {
J int ii, jj, kk;
J 
J kk = 0;
J 
J for (ii=0; ii < 100; ii++)
J {
J if ( (jj = getchar()) == EOF )
J 	{
J 	break;
J 	}
J 
J if (jj == 0 || jj > '~')
J 	{
J 	kk = 1;
J 	break;
J 	}
J }
J 
J printf("%d\n",kk);
J }
SHAR_EOF
if test 277 -ne "`wc -c < 'binary.c'`"
then
	echo shar: error transmitting "'binary.c'" '(should have been 277 characters)'
fi
fi # end of overwriting check
if test -f 'corr'
then
	echo shar: will not over-write existing file "'corr'"
else
sed 's/^J //' << \SHAR_EOF > 'corr'
J s+/husr/src/graphics/vplot/filters/otherpens/+/usr/src/sepsrc/vplot/filters/+
J s+/husr/src/graphics/+/usr/src/sepsrc/+
SHAR_EOF
if test 118 -ne "`wc -c < 'corr'`"
then
	echo shar: error transmitting "'corr'" '(should have been 118 characters)'
fi
fi # end of overwriting check
if test -f 'linksrc'
then
	echo shar: will not over-write existing file "'linksrc'"
else
sed 's/^J //' << \SHAR_EOF > 'linksrc'
J #!/bin/csh -f
J #
J # Author - Joe Dellinger
J # Stanford Exploration Project
J # Dept of Geophysics, Stanford University
J # January 27, 1988
J #
J 
J if ( $#argv != 2 ) then
J 	echo "Usage: linksrc remote_dir local_dir"
J 	exit
J endif
J 
J foreach direct (`find $1 -type d -print`)
J set there = "$direct/"
J set here = `echo $there | sed -f corr`
J set heredir = `echo $here | sed -e 's+/$++'`
J if (-e $heredir) then
J  if (! -w $heredir || ! -d $heredir) then
J   echo "Can't write in $heredir, so skipping it."
J   continue
J  endif
J  echo "Doing directory $heredir"
J else
J  set hereabove = `echo $here | sed -e 's+[^/]*/$++'`
J  set hereabovedir = `echo $hereabove | sed -e 's+/$++'`
J  if (-w $hereabovedir && -d $hereabovedir) then
J   again:
J   echo "Directory $heredir does not exist."
J   echo "Should I create it?"
J   set answer =  $<
J   if ($answer =~ y* ) then
J    echo "OK, I'll create it."
J    mkdir $heredir
J   else if ($answer =~ n* ) then
J    echo "OK, I'll skip it."
J    continue
J   else
J    echo "Answer yes or no, you idiot\!"
J    goto again
J   endif
J   
J  else
J  echo "Can't write in $hereabovedir,"
J  echo "  so I'm forced to skip $heredir"
J  continue
J  endif
J endif
J 
J foreach file (`cd $there; echo *`)
J if ( ! -e $here$file && -f $there$file \
J 	&& $file !~ *.o && $file !~ *.a \
J 	&& ("0" == `binary < $there$file` || $file =~ *.v ) ) then
J 
J if ( $file !~ Make* && $file !~ make* \
J 	&& $file !~ install* && $file !~ param*.h && $file !~ site*.h \
J 	&& $file !~ machdep* && $file !~ mach_dep* ) then
J 
J rm -f $here$file
J ln -s $there$file $here$file
J echo linked $file
J 
J else
J 
J rm -f $here$file
J cp -p $there$file $here$file
J echo copied $file
J 
J endif
J 
J endif
J end
J end
SHAR_EOF
if test 1608 -ne "`wc -c < 'linksrc'`"
then
	echo shar: error transmitting "'linksrc'" '(should have been 1608 characters)'
fi
chmod +x 'linksrc'
fi # end of overwriting check
#	End of shell archive
exit 0