#! /bin/sh
#
# This is a self-applying patch in a shell script.
# It has this form because some of the files are generated,
# and thus no history is available for them;
# they need to be deleted before the patch is applied.
#
# Change directory to the appropriate place
# before applying running this shell script.
#
# Don't forget the -p0 option if you apply this patch manually.
#
# ------------------------------------------------------------

#
# Before you apply this patch manually,
# please delete the following files:
#
rm -f README ALPHA BUILDING CHANGES MANIFEST Makefile

#
# Now patch the files...
#	(Don't forget the -p0 option.)
#
patch -p0 << 'fubar'
Index: common/patchlevel.h
Prereq: "1.3.D035"
***************
*** 1 ****
! #define PATCHLEVEL "1.3.D035"
--- 1 ----
! #define PATCHLEVEL "1.4.D038"
Index: README
***************
*** 0 ****
--- 1,396 ----
+ 
+ 
+ 
+ readme(aegis)					    readme(aegis)
+ 
+ 
+ NAME
+ 	aegis -	project	change supervisor
+ 	Copyright (C) 1990, 1991, 1992,	1993 Peter Miller.
+ 	All rights reserved.
+ 
+ 	The aegis program is distributed under the terms of the
+ 	GNU General Public License.  See the LICENSE section,
+ 	below, for more	details.
+ 
+ 	aegis (ee.j.iz)	n., a protection, a defence.
+ 
+ DESCRIPTION
+ 	The aegis program is a CASE tool with a	difference.  In
+ 	the spirit of the UNIX Operating System, the aegis
+ 	program	is a small component designed to work with other
+ 	programs.
+ 
+ 	Many CASE systems attempt to provide everything, from
+ 	bubble charts to source	control	to compilers.  Users are
+ 	trapped	with the components supplied by	the CASE system,
+ 	and if you don't like one of the components (it	may be
+ 	too limited, for instance), then that is just tough.
+ 
+ 	In contrast, UNIX provides many	components of a	CASE
+ 	system - compilers, editors, dependency	manitenance tools
+ 	(such as make),	source control tools (such as RCS).  You
+ 	may substitute the tool	of your	choice if you don't like
+ 	the ones supplied with the system - gcc, jove, cake, to
+ 	name just a few.  The aegis program adds to this list
+ 	with software configuration management,	and true to UNIX
+ 	philosophy, the	aegis program does not dictate the choice
+ 	of any of the other tools (although it may stretch them
+ 	to their limits).
+ 
+ 	Enough hype, what is it	that the aegis program does?
+ 	Just what is software configuration management?	 This
+ 	question is sufficiently broad as to require a book in
+ 	answer.	 In essence, the aegis program is a project
+ 	change supervisor.  It provides	a framework within which
+ 	a team of developers may work on many changes to a
+ 	program	independently, and the aegis program coordinates
+ 	integrating these changes back into the	master source of
+ 	the program, with as little disruption as possible.
+ 	Resolution of contention for source files, a major
+ 	headache for any project with more than	one developer, is
+ 	one of the aegis program's major functions.
+ 
+ 	It should be noted that	the aegis program is a
+ 	developer's tool, in the same sense as make or RCS are
+ 	developer's tools.  It is not a	manager's tool - it does
+ 	not provide progress tracking or manage	work allocation.
+ 
+ 
+ 
+ 
+ 
+ 
+ 								1
+ 
+ 
+ 
+ 
+ 
+ readme(aegis)					    readme(aegis)
+ 
+ 
+ BENEFITS
+ 	So why should you use the aegis	program?
+ 
+ 	The aegis program uses a particular model of the
+ 	development of software	projects.  This	model has a
+ 	master source (or baseline) of a project, and a	team of
+ 	developers creating changes to be made to this baseline.
+ 	When a change is complete, it is integrated with the
+ 	baseline, to become the	new baseline.  Each change must
+ 	be atomic and self-contained, no change	is allowed to
+ 	cause the baseline to cease to work.  "Working"	is
+ 	defined	as passing it's	own tests.  The	tests are
+ 	considered part	of the baseline.  The aegis program
+ 	provides support for the developer so that an entire copy
+ 	of the baseline	need not be taken to change a few files,
+ 	only those files which are to be changed need to be
+ 	copied.
+ 
+ 	In order to ensure that	changes	are unable to cause the
+ 	baseline to cease to work, aegis mandates that changes be
+ 	accompanied by at least	one test, and that all such tests
+ 	be known to complete sucessfully.  These steadily
+ 	accumulated tests form an ever increasing regression test
+ 	suite for all later changes.  There is also a mandatory
+ 	review stage for each change to	the baseline.  While
+ 	these requirements may be relaxed per-change or	even per-
+ 	project, doing so potentially compromises the "working"
+ 	definition of the baseline.
+ 
+ 	The win	in using the aegis program is that there are O(n)
+ 	interactions between developers	and the	baseline.
+ 	Contrast this with a master source which is being edited
+ 	directly by the	developers - there are O(n!)
+ 	interactions between developers	- this makes adding "just
+ 	one more" developer a potential	disaster.
+ 
+ 	Another	win is that the	project	baseline always	works.
+ 	Always having a	working	baseline means that a version is
+ 	always available for demonstrations, or	those "pre-
+ 	release	snapshots" we are always forced	to provide.
+ 
+ 	The above advantages are all very well - for management
+ 	types.	Why should Joe Average Programmer use the aegis
+ 	program?  Recall that RCS provides file	locking, but only
+ 	for one	file at	a time.	 The aegis program provides the
+ 	file locking, atomically, for the set of files in the
+ 	change.	 Recall	also that RCS locks the	file the instant
+ 	you start editing it.  This makes popular files	a project
+ 	bottleneck.  The aegis program allows concurrent editing,
+ 	and a resolution mechanism just	before the change must be
+ 	integrated, meaning fewer delays for J.A.Programmer.
+ 
+ 
+ 
+ 
+ 
+ 
+ 								2
+ 
+ 
+ 
+ 
+ 
+ readme(aegis)					    readme(aegis)
+ 
+ 
+ ALPHA NOTICE
+ 	Please note that this is Alpha software.  It probably has
+ 	bugs, it is known to have unimplemented	features.  This
+ 	version	is not intended	to be the final	product.  For
+ 	more information, see the ALPHA	file included in this
+ 	release.
+ 
+ 	The reasons the	author thinks this software is alpha
+ 	include: * it has not clocked enought CPU time,	* it has
+ 	not been built on enough systems, * it has not been
+ 	tested on enough systems, * the	User Guide is not
+ 	finished.  However, feedback to	date has been very
+ 	favourable.
+ 
+ 	This will probably be the last Alpha release.  The next
+ 	release	will be	2.0, and will be a Beta	release.  The
+ 	problems reported to date are configuration and	build
+ 	problems; there	are few	reports	of it failing to function
+ 	correctly in other cases.
+ 
+ ARCHIVE	SITE
+ 	The latest version of aegis is available by anonymous ftp
+ 	from:
+ 	    Host:   ftp.cse.nau.edu (134.114.64.70)
+ 	    Dir:    /pub/Aegis
+ 	    File:   aegis.1.4.tar.Z	# the complete source
+ 	    File:   aegis.1.4.patch.Z	# patch	to take	1.3 to 1.4
+ 	    File:   aegis.1.4.ps.Z	# PostScript of	the User Guide
+ 
+ 	To use anonymous ftp, give "anonymous" as the user name
+ 	(omit the quotes) and your email address as the	password.
+ 
+ 	My grateful thanks to Paul Balyoz <pab@ftp.cse.nau.edu>
+ 	for his	generosity in providing	this archive space.
+ 
+ 	This directory also contains a few other pieces	of
+ 	software written by me.	 Some are referred to in the
+ 	aegis documentation.  Please have a look if you	are
+ 	interested.
+ 
+ 	For those of you without ftp, I	recommend the use of an
+ 	ftp-by-email server.  Here is a	list of	a few (there are
+ 	many more):
+ 		mail-server@pit-manager.mit.edu
+ 		ftpmail@decwrl.dec.com
+ 		ftpmail@cs.uow.edu.au
+ 
+ 	In general, you	can get	a help message about how to use
+ 	each system by sending email with a subject of "help" and
+ 	a message body containing just the word	"help".
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 								3
+ 
+ 
+ 
+ 
+ 
+ readme(aegis)					    readme(aegis)
+ 
+ 
+ MAILING	LIST
+ 	A mailing list has been	created	so that	users of aegis
+ 	may exchange ideas about how to	use the	aegis program.
+ 	Discussion may include,	but is not limited to: bugs,
+ 	enhancements, and applications.	 The list is not
+ 	moderated.
+ 
+ 	The address of the mailing list	is
+ 		aegis-users@bmr.gov.au
+ 
+ 	To subscribe to	this mailing list, send	an email message
+ 	to majordomo@bmr.gov.au	with a message body containing
+ 	the single line
+ 		subscribe aegis-users
+ 	Please note that bmr.gov.au is an Internet site, so if
+ 	you have an address which is not readily derived from
+ 	your mail headers (majordomo is	only a Perl program,
+ 	after all) you will need to use	a message of the form:
+ 		subscribe aegis-users address
+ 	where address is an email address which	makes sense from
+ 	an Internet site.
+ 
+ 	The software which handles this	mailing	list CANNOT send
+ 	you a copy of the aegis	program.  Please use ftp or ftp-
+ 	by-email, instead.
+ 
+ COMPARISON WITH	CVS
+ 	One of the most	common questions about aegis is	"How does
+ 	it compare with	CVS?"
+ 
+ 	The CVS	program	aims to	provide	a repository, RCS for
+ 	sets of	files.	The aegis program aims to provide a
+ 	baseline, a repository,	consistency of the baseline, and
+ 	validation of changes being made to the	baseline.
+ 
+ 	A simplistic way of thinking of	this is	"CVS is	over
+ 	RCS", but "aegis is over RCS and make".	 Actually CVS
+ 	requires RCS, whereas aegis may	be configured to use
+ 	almost any history tool; similarly for the dependency
+ 	maintenance tool, aegis	may be configured to use almost
+ 	any sufficiently capable tool (unfortunately traditional
+ 	make isn't sufficiently	capable, but the name is well
+ 	known and evokes the appropriate functional image).
+ 
+ 	The most significant point of departure	is around the
+ 	"cvs checkin" fucntionality.  In CVS, this is
+ 	unconditional; a developer can add a poorly though-out
+ 	code change, or	even indulge in	a little vandalism, with
+ 	nothing	to prevent it.	In contrast, the aegis program
+ 	breaks this step into several pieces: the change must be
+ 	be known to build, the change must have	tests and those
+ 	tests be known to have run and passed, the change must
+ 	then be	reviewed (double check), and then built	and
+ 	tested again (tripple check).
+ 
+ 
+ 
+ 								4
+ 
+ 
+ 
+ 
+ 
+ readme(aegis)					    readme(aegis)
+ 
+ 
+ 	For a more detailed discussion,	see appendix C of the
+ 	User Guide.
+ 
+ NEW IN THIS RELEASE
+ 	A number of features have been added to	aegis with this
+ 	release.  A few	of them	are detailed here:
+ 
+ 	* Support has been added for systems without the seteuid
+ 	system call, or	those with crippled implementations.
+ 
+ 	* Most of the unimplemented command variants have been
+ 	finished.  These include New Change Undo, Develop Begin
+ 	Undo and ReMove	PRoject.  Most notable of the exceptions
+ 	is -ANticipate option for the -CoPy_file and -DIFFerence
+ 	command.
+ 
+ 	* The User Guide has been added	to, making it a	little
+ 	more complete.	It still needs more work, sigh.
+ 
+ 	* The code to handle automounters has been made	more
+ 	robust.
+ 
+ 	* The command substitutions have been vastly improved,
+ 	and are	now documented.
+ 
+ 	Plus the usual crop of bug fixes and tinkering.	 For
+ 	excruciating detail, and also acknowlegements of those
+ 	who generously sent me feedback, please	see the	CHANGES
+ 	file included in this distribution.
+ 
+ BUILDING
+ 	Instructions on	how to build and test the aegis	program
+ 	are to be found	in the BUILDING	file included in this
+ 	distribution.
+ 
+ LICENSE
+ 	The aegis program is free software; you	can redistribute
+ 	it and/or modify it under the terms of the GNU General
+ 	Public License as published by the Free	Software
+ 	Foundation; either version 2 of	the License, or	(at your
+ 	option)	any later version.
+ 
+ 	The aegis program is distributed in the	hope that it will
+ 	be useful, but WITHOUT ANY WARRANTY; without even the
+ 	implied	warranty of MERCHANTABILITY or FITNESS FOR A
+ 	PARTICULAR PURPOSE.  See the GNU General Public	License
+ 	for more details.
+ 
+ 	You should have	received a copy	of the GNU General Public
+ 	License	along with this	program; if not, write to the
+ 	Free Software Foundation, Inc.,	675 Mass Ave, Cambridge,
+ 	MA 02139, USA.
+ 
+ 	It should be in	the LICENSE file included in this
+ 
+ 
+ 
+ 								5
+ 
+ 
+ 
+ 
+ 
+ readme(aegis)					    readme(aegis)
+ 
+ 
+ 	distribution.
+ 
+ AUTHOR
+ 	Peter Miller   UUCP	  uunet!munnari!bmr.gov.au!pmiller
+ 	/\/\*	       Internet	  pmiller@bmr.gov.au
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 								6
+ 
+ 
Index: ALPHA
***************
*** 0 ****
--- 1,264 ----
+ 
+ 
+ 
+ alpha(aegis)					     alpha(aegis)
+ 
+ 
+ NAME
+ 	aegis -	project	change supervisor
+ 	Copyright (C) 1990, 1991, 1992,	1993 Peter Miller.
+ 	All rights reserved.
+ 
+ 	The aegis program is distributed under the terms of the
+ 	GNU General Public License.  See the LICENSE section,
+ 	below, for more	details.
+ 
+ 	aegis (ee.j.iz)	n., a protection, a defence.
+ 
+ ALPHA SOFTWARE
+ 	This is	an alpha version of the	aegis program.	This
+ 	means that it is not the final product,	or even	a Beta
+ 	version.  It probably has bugs,	and it has known
+ 	limitations.  This version is intended for testing only,
+ 	and should be used with	caution	in a "live" environment.
+ 	That said, the harder you use it, the more useful the
+ 	testing.  If you are still interested, the author would
+ 	like to	know the following:
+ 
+ 	1. The type of UNIX
+ 		The author will	need to	know the type of UNIX you
+ 		are using, and sometimes what version, or if it
+ 		is not UNIX but	something else.	 The output of
+ 		"uname -rs" is usually sufficent (but not all
+ 		systems	have it).
+ 
+ 	2. The Version Number
+ 		In any information you send, please include the
+ 		version	number reported	in the
+ 		common/patchlevel.h file, or `aegis -vers` if you
+ 		can get	it to compile.
+ 
+ 	3. The Archive Site
+ 		When and where you obtained this version of
+ 		aegis.	If you tell me nothing else, tell me this
+ 		(and, hopefully, why you did nothing else).
+ 
+ 	4. Unpacking
+ 		Did you	have problems unpacking	aegis?	This
+ 		probably isn't a problem with the .tar.Z
+ 		distribution, but you could have obtained a shar
+ 		format copy.
+ 
+ 	5. Building
+ 		Did you	have problems building aegis?  This could
+ 		have been the instructions included, it	could
+ 		have been the Makefile,	it could have been
+ 		problems configuring it, or anything else.
+ 
+ 	6. Testing, Non-Set-Uid
+ 		Did you	have problems with the tests?  Yes, the
+ 		aegis program comes with tests!	 You could have
+ 
+ 
+ 
+ 								1
+ 
+ 
+ 
+ 
+ 
+ alpha(aegis)					     alpha(aegis)
+ 
+ 
+ 		had problems running them, or some of them could
+ 		have failed.  If some tests fail but not others,
+ 		please let me know which ones failed.
+ 
+ 	7. Testing, Set-Uid-Root
+ 		Did you	have problems with the tests when aegis
+ 		was set-uid-root?  You could have had problems
+ 		running	them, or some of them could have failed.
+ 		If some	tests fail but not others, please let me
+ 		know which ones	failed,	and include the	fact that
+ 		aegis was set-uid-root at the time.
+ 
+ 	8. Installation
+ 		Did you	have problems installing aegis?	 This
+ 		could have been	the instructions, or anything
+ 		else.
+ 
+ 	At this	point it would probably	be a very good idea to
+ 	print out the manual entries and read them carefully.
+ 	You will also want to print a copy of the User Guide; if
+ 	you don't gave groff, there should be a	PostScript copy
+ 	at the archive site.  It is a known flaw that the User
+ 	Guide is incomplete, it	is something the author	is
+ 	working	on "at this moment".  (See the PRINTED MANUALS
+ 	section	of the BUILDING	file for more details.)
+ 
+ 	9. The Example Project
+ 		After reading the User Guide, it is often useful
+ 		to manually run	through	the example in chapter 3.
+ 		You will need to do more than one change,
+ 		hopefully several; the first change is not
+ 		representative of the system.  Did you manually
+ 		do the example?	 Did you find flaws in the User
+ 		Guide or manual	entries?
+ 
+ 	10. Using Aegis
+ 		Did you	have problems using aegis?  This is a
+ 		whole can of worms.  If	possible, include a shell
+ 		script similar to the tests which accompany
+ 		aegis, which reproduces	the bug.  Exit code 1 on
+ 		failure	(bug), exit code 0 on success (for when
+ 		bug is fixed).
+ 
+ 	11. The	Source Code
+ 		Did you	read the code?	Did you	write some code?
+ 		If you read the	code and found problems, fixed
+ 		them, or extended aegis, these contributions are
+ 		most welcome.  I reserve the right to modify or
+ 		reject such contributions.
+ 
+ 	The above list is inclusive, not exclusive.  Any and all
+ 	feedback is greatly appreciated, as is the effort and
+ 	interest required to produce it.
+ 
+ 
+ 
+ 
+ 								2
+ 
+ 
+ 
+ 
+ 
+ alpha(aegis)					     alpha(aegis)
+ 
+ 
+ SOME HISTORY
+ 	The idea for aegis did not come	full-blown into	my head
+ 	in the shower, as some of my programs do, but rather from
+ 	working	for a software shop which used a simplistic form
+ 	of something similar.  That system was held together by
+ 	chewing-gum and	string,	it was written in a disgusting
+ 	variant	of Basic, and by golly the damn	thing worked
+ 	(mostly).  The aegis program is	nothing	like it, owes
+ 	none of	its code to that system, and is	far more
+ 	versatile.
+ 
+ 	Since that company decided to close down our section, we
+ 	all moved on simultaneously (all 60 of us), sometimes
+ 	working	together, and sometimes	not, but always	keeping
+ 	in touch.  With	suggestions and	conversations with some
+ 	of them	early in 1990, the manual entries for aegis took
+ 	shape, and formed most of the design document for aegis.
+ 	The rest of the	design document	will eventually	appear in
+ 	the "model" section of the user	manual.
+ 
+ 	Since getting the first	glimmerings of a functional aegis
+ 	late in	1990 it	is increasingly	obvious	that I never want
+ 	to be without it ever again.  All of my	sources	that I
+ 	modify are instantly placed under aegis, as is anything	I
+ 	distribute.  All code I	write for myself, and all new
+ 	code I write for my employer, goes under aegis.	 Why?
+ 	Because	it has fewer bugs!
+ 
+ 	Example: one of	the sources I carry with me from job to
+ 	job is "cook", my dependency maintenance tool.	Cook had
+ 	existed	for 3 years before aegis appeared on the scene,
+ 	and I used it daily.  When I placed cook under aegis, I
+ 	found 6	bugs!  Since then I have found even more.  Not
+ 	only are there now fewer bugs, but they	never come back,
+ 	because	the regession test suite always	grows.
+ 
+ LICENSE
+ 	The aegis program is free software; you	can redistribute
+ 	it and/or modify it under the terms of the GNU General
+ 	Public License as published by the Free	Software
+ 	Foundation; either version 2 of	the License, or	(at your
+ 	option)	any later version.
+ 
+ 	The aegis program is distributed in the	hope that it will
+ 	be useful, but WITHOUT ANY WARRANTY; without even the
+ 	implied	warranty of MERCHANTABILITY or FITNESS FOR A
+ 	PARTICULAR PURPOSE.  See the GNU General Public	License
+ 	for more details.
+ 
+ 	You should have	received a copy	of the GNU General Public
+ 	License	along with this	program; if not, write to the
+ 	Free Software Foundation, Inc.,	675 Mass Ave, Cambridge,
+ 	MA 02139, USA.
+ 
+ 
+ 
+ 
+ 								3
+ 
+ 
+ 
+ 
+ 
+ alpha(aegis)					     alpha(aegis)
+ 
+ 
+ 	It should be in	the LICENSE file included in this
+ 	distribution.
+ 
+ AUTHOR
+ 	Peter Miller   UUCP	  uunet!munnari!bmr.gov.au!pmiller
+ 	/\/\*	       Internet	  pmiller@bmr.gov.au
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 								4
+ 
+ 
Index: BUILDING
***************
*** 0 ****
--- 1,594 ----
+ 
+ 
+ 
+ build(aegis)					     build(aegis)
+ 
+ 
+ NAME
+ 	aegis -	project	change supervisor
+ 	Copyright (C) 1990, 1991, 1992,	1993 Peter Miller.
+ 	All rights reserved.
+ 
+ 	The aegis program is distributed under the terms of the
+ 	GNU General Public License.  See the LICENSE section,
+ 	below, for more	details.
+ 
+ 	aegis (ee.j.iz)	n., a protection, a defence.
+ 
+ SPACE REQUIREMENTS
+ 	You will need up to 10MB to unpack and build the aegis
+ 	program.  (This	is the worst case seen so far, most
+ 	systems	have binaries about 60%	as big as this,	6MB is
+ 	more typical.)	Your mileage may vary.
+ 
+ SITE CONFIGURATION
+ 	The file common/conf.h needs to	be created to match your
+ 	site.  Select an appropriate file from the conf
+ 	directory.  The	files in this directory	are named for the
+ 	various	systems	encountered to date by the author.  The
+ 	file most closely resembling your system should	be copied
+ 	into the common/conf.h file.  You can copy it or use a
+ 	symbolic link; copying is recommended because you may
+ 	need to	edit.
+ 
+ 	The common/conf.h file is extensively commented.  Read
+ 	the comments and change	what you need to.  Please read
+ 	this file carefully.
+ 
+ 	Another	file which may require editing is the Makefile
+ 	file.  The first few lines contain comments describing
+ 	what may require changing.  In general these changes will
+ 	relate to the name of your favorite C compiler,	and where
+ 	it keeps its include files.
+ 
+ 	The top	of the Makefile	file is	arranged as macro
+ 	definitions, with alternatives for each	known system in
+ 	comments.  Search for your system's name, editing the
+ 	macro definition as required.
+ 
+ KNOWN SYSTEMS
+ 	This distribution of aegis is known to build on	the
+ 	following systems:
+ 
+ 	SunOS 4.1
+ 		The native cc(1) and also gcc(1) are known to
+ 		work for Sun4s.	 The appropriate configuration is
+ 		contained in the conf/SunOS-4.1	file.  Sun seem
+ 		to be having chronic problems with locking; you
+ 		may need to get	the very latest	set of locking
+ 		patches	and apply them.
+ 
+ 
+ 
+ 
+ 								1
+ 
+ 
+ 
+ 
+ 
+ build(aegis)					     build(aegis)
+ 
+ 
+ 	ConvexOS 10.0
+ 		The native cc(1) works just fine.  The
+ 		appropriate configuration is contained in the
+ 		conf/ConvexOS-10 file.	Note that there	is no
+ 		"bin" user on ConvexOS,	so the owner of	aegis '
+ 		library	files is "daemon"; you will need to map
+ 		user and group "bin" to	"daemon" in the
+ 		instructions below.
+ 
+ 	DG/UX 5.4.1
+ 		The native cc(1) works just fine.  The
+ 		appropriate configuration is contained in the
+ 		conf/dgux-5.4.1	file.
+ 
+ 	ULTRIX 4.2
+ 		It has the seteuid and setegid calls, but the
+ 		shell has no functions!	 Complain to your vendor.
+ 		You will need to change	the SHELL macro
+ 		definition in the Makefile file	to use sh5(1)
+ 		instead.  The appropriate configuration	is
+ 		contained in the conf/ULTRIX-4.2 file.
+ 
+ 	Pyramid	SMP DC/OSx 1.0-92b023
+ 		This system is pretty horrendous.  Read	the file
+ 		BUILDpyr included in this distribution for
+ 		instruction how	to configure aegis, then follow
+ 		the rest of the	instructions in	this file.  The
+ 		appropriate configuration is contained in the
+ 		conf/dcosx file.
+ 
+ 	HP-UX A.08.07
+ 		The author has been advised that the aegis
+ 		program	works on this system.  Could another
+ 		person confirm this, please.  The appropriate
+ 		configuration is contained in the conf/hpux-8.07
+ 		file.
+ 
+ 	SCO 2.4
+ 		The author has been advised that the aegis
+ 		program	works on this system.  Could another
+ 		person confirm this, please.  The appropriate
+ 		configuration is contained in the conf/SCO-2.4
+ 		file.
+ 
+ 	If the instructions for	any of the above systems do not
+ 	work, after you	have double-checked everything,	the
+ 	author would like to know.
+ 
+ UNKNOWN	SYSTEMS
+ 	Please let the author know of any other	systems	you get
+ 	aegis working on, and the modifications	necessary.
+ 	Please include the differences to the Makefile file, and
+ 	the whole common/conf.h	file you used.	Included any
+ 	other files you	edited or added.  Include the output of
+ 
+ 
+ 
+ 								2
+ 
+ 
+ 
+ 
+ 
+ build(aegis)					     build(aegis)
+ 
+ 
+ 	the "uname -rs"	command, if your flavour of UNIX has such
+ 	a command.
+ 
+ 	While the aegis	program	was developed using gcc, this is
+ 	not the	default	in the Makefile	file.  The code	uses ANSI
+ 	C features without compromising	the ability to be
+ 	compiled on older C compilers.	Functions mandated by the
+ 	ANSI C standard	are used, because many systems provided
+ 	them, one way or another.  Please let the author know of
+ 	any others you think should be added to	the common/ansi.c
+ 	file.
+ 
+ 	You may	need to	use some ANSI C	header files which the
+ 	aegis code uses, but which some	systems	(as yet) fail to
+ 	provide.  You will find	lines at the top of the	Makefile
+ 	file similar to
+ 		H = -I/usr/include -Ih
+ 	Change this to suit your system	and your compiler.  The
+ 	"h" directory must be searched last as it is intended to
+ 	suplement your system, not replace it.
+ 
+ 	You will need to check the include files in the	"h"
+ 	directory to see that they are suitable	for your system.
+ 	You may	want to	delete any that	your system already has.
+ 
+ BUILDING AEGIS
+ 	All you	should need to do is use the
+ 		% make
+ 		...lots	of output...
+ 		%
+ 	command	and wait.  When	this finishes you should see a
+ 	directory called bin containing	two files: aegis and
+ 	fmtgen.	 The fmtgen file is a program used in
+ 	constructing aegis and is not for general consumption.
+ 
+ OTHER USEFUL SOFTWARE
+ 	Before describing how to test aegis, you may need to grab
+ 	some other free	software, because the tests require it in
+ 	some cases, and	because	it is generally	useful in others.
+ 
+ 	cook
+ 		This is	a dependency maintenance tool (DMT).  An
+ 		example	of a well-known	DTM is make(1),	however
+ 		this old failthfull is not sufficiently	capable
+ 		to meet	the demands placed on it by the	aegis
+ 		program, but cook certainly is.	 The cook package
+ 		is written by the same author as aegis.	 The cook
+ 		package	is necessary for test 11 to pass.  It is
+ 		also used in the documentation.	 The cook program
+ 		may be found at	the same archive site as the
+ 		aegis program, and in the same directory.  The
+ 		cook program is	available under	the terms of the
+ 		GNU General Public License.
+ 
+ 
+ 
+ 
+ 								3
+ 
+ 
+ 
+ 
+ 
+ build(aegis)					     build(aegis)
+ 
+ 
+ 	RCS
+ 		This is	a source control package, and is
+ 		available from any of the GNU archives.	 The
+ 		tests use RCS as the history mechanism,	so it is
+ 		necessary to have RCS for most of the tests to
+ 		pass.
+ 
+ 	GNU diff
+ 		If the diff(1) utility supplied	by your	flavor of
+ 		unix does not have the -c option, you will need
+ 		GNU diff to make patch files, if you want to
+ 		publish	software for FTP or on USENET.	Context
+ 		differences are	also helpful for reviewing
+ 		changes.
+ 
+ 	groff
+ 		This GNU software replaces the documentation
+ 		tools which (sometimes)	come with UNIX.	 They
+ 		produce	superior error messages, and support a
+ 		wider range of functionality and fonts.	 The
+ 		aegis User Guide was prepared with groff.
+ 
+ 	bison
+ 		This GNU software is a replacement for yacc(1).
+ 		Some systems have very sick yaccs, and this may
+ 		be necessary if	your system include files
+ 		disagree strongly with your system's yacc.  The
+ 		Makefile has bison setup in comments.
+ 
+ 	fhist
+ 		This software, available under the terms of the
+ 		GNU General Public License, is a set of	file
+ 		history	and comparison utilities.  It was
+ 		originally written by David I. Bell, and is based
+ 		on the minimal difference algorithm by Eugene W.
+ 		Myers.	This copy is enhanced and maintained by
+ 		the same author	as aegis, and may be found at the
+ 		same archive site, in the same directory.
+ 
+ TESTING	AEGIS
+ 	The aegis program comes	with a test suite.  To run this
+ 	test suite, use	the command
+ 		% make sure
+ 		...lots	of output...
+ 		Passed All Tests
+ 		%
+ 
+ 	The tests take a minute	or two each, with a few	very
+ 	fast, and a couple very	slow, but it varies greatly
+ 	depending on your CPU.
+ 
+ 	The tests assume that the RCS commands "ci", "co", "rlog"
+ 	and "rcs" are somewhere	in the command search PATH.
+ 
+ 
+ 
+ 
+ 								4
+ 
+ 
+ 
+ 
+ 
+ build(aegis)					     build(aegis)
+ 
+ 
+ 	The test/00/t0011a.sh file assumes the cook(1) command by
+ 	the author is somewhere	in the command search path.  This
+ 	test reproduces	the example used in Chapter 3 of the User
+ 	Guide.
+ 
+ 	If you are using Sun's tmpfs file system as your /tmp
+ 	directory, the tests will fail.	 This is because the
+ 	tmpfs file system does not support file	locking.  Set the
+ 	AEGIS_TMP environment variable to somewhere else before
+ 	running	the tests.  Something like
+ 		% setenv AEGIS_TMP /usr/tmp
+ 		%
+ 	is usually sufficient if you are using C shell,	or
+ 		$ AEGIS_TMP=/usr/tmp
+ 		$ export AEGIS_TMP
+ 		$
+ 	if you are using Bourne	shell.	Remember, this must be
+ 	done before running the	tests.
+ 
+ 	If the tests fail due to errors	complaining of "user too
+ 	privileged" you	will need to adjust the	AEGIS_MIN_UID
+ 	define in the common/conf.h file.  Similarly for "group
+ 	too privileged", although this is rarer.  This error
+ 	message	will also occur	if you run the tests as	root: the
+ 	tests must be run as a mortal each time.
+ 
+ TESTING	SET-UID-ROOT
+ 	If the aegis program is	not set-uid-root then it runs in
+ 	"test" mode which gives	you some confidence that aegis is
+ 	working	before being tested again when it is set-uid-
+ 	root.  Two pass	testing	like this means	that you need not
+ 	trust your system to a set-uid-root program which is not
+ 	known to work.
+ 
+ 	You will need to do a little of	the install, to	create
+ 	the directory which will contain aegis'	lock file.
+ 		# mkdir	/usr/local/lib/aegis
+ 		# chmod	755 /usr/local/lib/aegis
+ 		# chown	bin /usr/local/lib/aegis
+ 		# chgrp	bin /usr/local/lib/aegis
+ 		#
+ 	You will need to change	aegis to be set-uid-root.  This
+ 	may be done with the following commands:
+ 		# chown	root bin/aegis
+ 		# chmod	u+s bin/aegis
+ 		#
+ 	Once aegis is set-uid-root, it is tested again,	in the
+ 	same manner as before.
+ 		% make sure
+ 		...lots	of output...
+ 		Passed All Tests
+ 		%
+ 
+ 	You should test	aegis as a mortal in both passes, rather
+ 
+ 
+ 
+ 								5
+ 
+ 
+ 
+ 
+ 
+ build(aegis)					     build(aegis)
+ 
+ 
+ 	than as	root, to be sure the set-uid-root functionality
+ 	is working correctly.
+ 
+ INSTALLING AEGIS
+ 	Put the	aegis program somewhere	where users will
+ 	automatically pick it up, such as in the /usr/local/bin
+ 	directory.  Use	the command
+ 		# cp bin/aegis /usr/local/bin
+ 		#
+ 	Don't forget to	make sure that the copy	is set-uid-root,
+ 	some versions of cp do not transfer the	set-uid	bit of
+ 	the mode.
+ 
+ 	The manuals can	be installed using the commands
+ 		# sh man1/install.sh /usr/local/man/man1
+ 		# sh man5/install.sh /usr/local/man/man5
+ 		#
+ 	but this is very site specific.	 You can select	a
+ 	different path by changing the last argument.
+ 
+ 	By default, aegis is configured	to use
+ 	/usr/local/lib/aegis as	the place it stores the	table
+ 	containing the mapping from project name to project
+ 	directory, and indexes into this table.	 The aegis
+ 	program	also has example .cshrc	and .profile files, and
+ 	generic	notification scripts.  These can be copied to
+ 	this library as	follows:
+ 		# mkdir	/usr/local/lib/aegis
+ 		# chmod	755 /usr/local/lib/aegis
+ 		# chown	bin /usr/local/lib/aegis
+ 		# chgrp	bin /usr/local/lib/aegis
+ 		# cp lib/* /usr/local/lib/aegis
+ 		# chmod	a+r /usr/local/lib/aegis/*
+ 		# chmod	a+x /usr/local/lib/aegis/*.sh
+ 		#
+ 	This is	only an	example, and you may want to place this
+ 	somewhere else.	 Control of the	placement of this
+ 	directory may be found in the first few	lines of the
+ 	Makefile file.
+ 
+ 	All of the above install can be	done automatically, using
+ 	the "make install" command as root.  Control of	the
+ 	directories used may be	found in the first few lines of
+ 	the Makefile file.
+ 
+ USER CONFIGURATION
+ 	The aegis command is assumed to	be in a	generally
+ 	accessable place, otherwise users will need to add the
+ 	relevant directory to their PATH.  Users should	add
+ 		source /usr/local/lib/aegis/cshrc
+ 	to the end of their .cshrc file	for the	recommended
+ 	aliases.  There	is a profile for users of the Bourne
+ 	shell (it assumes you have a version of	the Bourne shell
+ 	which has functions).
+ 
+ 
+ 
+ 								6
+ 
+ 
+ 
+ 
+ 
+ build(aegis)					     build(aegis)
+ 
+ 
+ 	The /usr/local/lib/aegis/state file contains pointers to
+ 	"system" projects.  Users may add their	own project
+ 	pointers (to their own projects) by putting a search path
+ 	into the AEGIS environment variable.  The system part is
+ 	always automatically appended by aegis.	 The default,
+ 	already	set by the /usr/local/lib/aegis/cshrc file, is
+ 	$HOME/lib/aegis.  Do not create	this directory,	aegis is
+ 	finickey and wants to do this itself.
+ 
+ 	Where projects reside is completely flexible, be they
+ 	system projects	or user	projects.  They	are not	kept
+ 	under the /usr/local/lib/aegis directory, this directory
+ 	only contains pointers.
+ 
+ PRINTED	MANUALS
+ 	This distribution contains the sources to all of the
+ 	documentation for aegis.  The author used the GNU groff
+ 	package	and a postscript printer to prepare the
+ 	documentation.	If you do not have this	software, you
+ 	will need to substitute	commands appropriate to	your
+ 	site.
+ 
+ 	To print copies	of the README, BUILDING	and ALPHA files,
+ 	the following commands may be used
+ 		% groff	-t -man	aux/*.man | lpr
+ 		%
+ 	This will produce about	12 pages.  The "-t" flag means
+ 	preprocess with	tbl(1).
+ 
+ 	To print copies	of the manual entries, the following
+ 	commands may be	used
+ 		% cd man1
+ 		% groff	-s -t -man *.1 | lpr
+ 		% cd ../man5
+ 		% groff	-s -t -man *.5 | lpr
+ 		% cd ..
+ 		%
+ 	This will produce about	60 pages.  The "-s" flag means
+ 	preprocess with	soelim(1), and the "-t"	flag means
+ 	preprocess with	tbl(1).
+ 
+ 	To print a copy	of the User Guide, the following commands
+ 	may be used
+ 		% cd doc
+ 		% groff	-s -t -p -ms aegis.ms |	lpr
+ 		% cd ..
+ 		%
+ 	This will produce about	90 pages.  The "-s" flag means
+ 	preprocess with	soelim(1), the "-t" flag means preprocess
+ 	with tbl(1), and the "-p" flag means preprocess	with
+ 	pic(1).	 Alternatively,	you could get a	PostScript copy
+ 	of the User Guide from the archive site.
+ 
+ 	Please note the	the User Guide is still	in the process of
+ 
+ 
+ 
+ 								7
+ 
+ 
+ 
+ 
+ 
+ build(aegis)					     build(aegis)
+ 
+ 
+ 	being written.	Some sections of the User Guide	are
+ 	incomplete.  Feedback on the form and content of this
+ 	document would be most welcome.
+ 
+ GETTING	HELP
+ 	This is	alpha software,	so things will probably	go wrong.
+ 	Thank you for your patience.
+ 
+ 	If you need assistance with the	aegis program, please do
+ 	not hesitate to	contact	the author at
+ 		Peter Miller <pmiller@bmr.gov.au>
+ 	Any and	all feedback is	welcome.
+ 
+ 	When reporting problems, please	include	the version
+ 	number given by	the
+ 		% aegis	-version
+ 		aegis version a.b.cccc
+ 		...
+ 		%
+ 	command.
+ 
+ 	In the common/main.h file, the is a define of DEBUG in
+ 	comments.  If the comments are removed,	extensive
+ 	debugging is turned on.	 This causes some performance
+ 	loss, but performs much	run-time checking and adds the
+ 	-TRace command line option.
+ 
+ 	When the -TRace	command	line option is followed	by one or
+ 	more file names, it turns on execution traces in those
+ 	source files.  It is usually best to place this	on the
+ 	end of the command line	so that	names of the files to be
+ 	traced are not confused	with other file	names or strings
+ 	on the command line.
+ 
+ LICENSE
+ 	The aegis program is free software; you	can redistribute
+ 	it and/or modify it under the terms of the GNU General
+ 	Public License as published by the Free	Software
+ 	Foundation; either version 2 of	the License, or	(at your
+ 	option)	any later version.
+ 
+ 	The aegis program is distributed in the	hope that it will
+ 	be useful, but WITHOUT ANY WARRANTY; without even the
+ 	implied	warranty of MERCHANTABILITY or FITNESS FOR A
+ 	PARTICULAR PURPOSE.  See the GNU General Public	License
+ 	for more details.
+ 
+ 	It should be in	the LICENSE file included in this
+ 	distribution.
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 								8
+ 
+ 
+ 
+ 
+ 
+ build(aegis)					     build(aegis)
+ 
+ 
+ AUTHOR
+ 	Peter Miller   UUCP	  uunet!munnari!bmr.gov.au!pmiller
+ 	/\/\*	       Internet	  pmiller@bmr.gov.au
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 								9
+ 
+ 
Index: CHANGES
***************
*** 0 ****
--- 1,2934 ----
+ 
+ 
+ 
+ Project "aegis.1.4"						  Page 1
+ List of Changes					Tue Mar 30 23:57:23 1993
+ 
+ Change	State		Description
+ ------- -------		-------------
+    1	completed	New release derived from aegis.1.3.
+    2	completed	create the aermpr command
+    3	completed	aenrls dumped core for non-owner but worked for
+ 			owner
+    4	completed	implement the aencu functionality
+    5	completed	implement the aedbu functionality
+    6	completed	note that ULTRIX was tried
+    7	completed	add a build lock, to protect builds from
+ 			integrate pass
+    8	completed	clear build time and diff time fields of config
+ 			copied into a change
+    9	completed	add the AEGIS_PROJECT and AEGIS_CHANGE
+ 			environment variables
+   10	completed	improve handling of outomounter directories
+   11	completed	document CVS vs Aegis
+   12	completed	complete the chapter 3 example in the User Guide
+   13	completed	inprove failure messages from tests
+   14	completed	make automounter handling more robust
+   15	completed	unix permissions for projects
+   16	completed	improve command substitutions
+   17	completed	change configuration to use new substitutions
+   18	completed	improve copyright notices
+   19	completed	add substitutions to file templates
+   20	completed	add support for the GNU long option style
+   21	completed	stop using _t suffix on type names
+   22	completed	and config details for AIX
+   23	completed	add support for systems without seteuid
+   24	completed	allow nomination of temp test dir
+   25	completed	rationalize lib entries
+   26	completed	fix problems with ULTRIX
+   27	completed	fix a bug in the no-seteuid flavour
+   28	completed	more documentation
+   29	completed	pyramid port
+   30	completed	improve pyramid port
+   31	completed	there was a permissions bug in aeibu
+   32	completed	fix problems found in final testing
+   33	completed	fix bugs in aecp and  column output
+   34	completed	note hpux as a known port
+   35	completed	New_Project does not check uid
+   36	being_		fix minor problem with generated Makefile
+ 	integrated
+ 
+ 
+ 
+ Project "aegis.1.4", Change 1					  Page 1
+ Change Details					Tue Mar 30 23:57:27 1993
+ 
+ NAME
+ 	Project "aegis.1.4", Delta 1, Change 1.
+ 
+ SUMMARY
+ 	New release derived from aegis.1.3.
+ 
+ DESCRIPTION
+ 	New release derived from aegis.1.3.
+ 
+ 	This change is exempt from testing.  This change is exempt from
+ 	testing against the baseline.
+ 
+ CAUSE
+ 	This change was caused by internal_enhancement.
+ 
+ FILES
+ 	Type	Action	Edit	File Name
+ 	------- ------- ------- -----------
+ 	source	create	1	COPYING
+ 	source	create	1	aegis/administ.c
+ 	source	create	1	aegis/administ.h
+ 	source	create	1	aegis/arglex2.h
+ 	source	create	1	aegis/build.c
+ 	source	create	1	aegis/build.h
+ 	source	create	1	aegis/cattr.def
+ 	source	create	1	aegis/cattr_ed.c
+ 	source	create	1	aegis/cattr_ed.h
+ 	source	create	1	aegis/change.c
+ 	source	create	1	aegis/change.h
+ 	source	create	1	aegis/chdir.c
+ 	source	create	1	aegis/chdir.h
+ 	source	create	1	aegis/col.c
+ 	source	create	1	aegis/col.h
+ 	source	create	1	aegis/commit.c
+ 	source	create	1	aegis/commit.h
+ 	source	create	1	aegis/common.def
+ 	source	create	1	aegis/copyfile.c
+ 	source	create	1	aegis/copyfile.h
+ 	source	create	1	aegis/cstate.def
+ 	source	create	1	aegis/develop1.c
+ 	source	create	1	aegis/develop1.h
+ 	source	create	1	aegis/develop2.c
+ 	source	create	1	aegis/develop2.h
+ 	source	create	1	aegis/diff.c
+ 	source	create	1	aegis/diff.h
+ 	source	create	1	aegis/dir.c
+ 	source	create	1	aegis/dir.h
+ 	source	create	1	aegis/file.c
+ 	source	create	1	aegis/file.h
+ 	source	create	1	aegis/gonzo.c
+ 	source	create	1	aegis/gonzo.h
+ 	source	create	1	aegis/gram.h
+ 	source	create	1	aegis/gram.y
+ 	source	create	1	aegis/gstate.def
+ 	source	create	1	aegis/help.c
+ 	source	create	1	aegis/help.h
+ 	source	create	1	aegis/integra1.c
+ 
+ 
+ 
+ Project "aegis.1.4", Change 1					  Page 2
+ Change Details					Tue Mar 30 23:57:27 1993
+ 
+ 	Type	Action	Edit	File Name
+ 	------- ------- ------- -----------
+ 	source	create	1	aegis/integra1.h
+ 	source	create	1	aegis/integra2.c
+ 	source	create	1	aegis/integra2.h
+ 	source	create	1	aegis/io.c
+ 	source	create	1	aegis/io.h
+ 	source	create	1	aegis/lex.c
+ 	source	create	1	aegis/lex.h
+ 	source	create	1	aegis/list.c
+ 	source	create	1	aegis/list.h
+ 	source	create	1	aegis/lock.c
+ 	source	create	1	aegis/lock.h
+ 	source	create	1	aegis/log.c
+ 	source	create	1	aegis/log.h
+ 	source	create	1	aegis/main.c
+ 	source	create	1	aegis/new_chan.c
+ 	source	create	1	aegis/new_chan.h
+ 	source	create	1	aegis/new_file.c
+ 	source	create	1	aegis/new_file.h
+ 	source	create	1	aegis/new_proj.c
+ 	source	create	1	aegis/new_proj.h
+ 	source	create	1	aegis/new_rele.c
+ 	source	create	1	aegis/new_rele.h
+ 	source	create	1	aegis/new_test.c
+ 	source	create	1	aegis/new_test.h
+ 	source	create	1	aegis/os.c
+ 	source	create	1	aegis/os.h
+ 	source	create	1	aegis/pager.c
+ 	source	create	1	aegis/pager.h
+ 	source	create	1	aegis/parse.c
+ 	source	create	1	aegis/parse.h
+ 	source	create	1	aegis/pattr.def
+ 	source	create	1	aegis/pattr_ed.c
+ 	source	create	1	aegis/pattr_ed.h
+ 	source	create	1	aegis/pconf.def
+ 	source	create	1	aegis/project.c
+ 	source	create	1	aegis/project.h
+ 	source	create	1	aegis/pstate.def
+ 	source	create	1	aegis/rem_file.c
+ 	source	create	1	aegis/rem_file.h
+ 	source	create	1	aegis/review.c
+ 	source	create	1	aegis/review.h
+ 	source	create	1	aegis/reviewer.c
+ 	source	create	1	aegis/reviewer.h
+ 	source	create	1	aegis/sub.c
+ 	source	create	1	aegis/sub.h
+ 	source	create	1	aegis/test.c
+ 	source	create	1	aegis/test.h
+ 	source	create	1	aegis/type.c
+ 	source	create	1	aegis/type.h
+ 	source	create	1	aegis/uconf.def
+ 	source	create	1	aegis/undo.c
+ 	source	create	1	aegis/undo.h
+ 	source	create	1	aegis/user.c
+ 	source	create	1	aegis/user.h
+ 	source	create	1	aegis/ustate.def
+ 
+ 
+ 
+ Project "aegis.1.4", Change 1					  Page 3
+ Change Details					Tue Mar 30 23:57:27 1993
+ 
+ 	Type	Action	Edit	File Name
+ 	------- ------- ------- -----------
+ 	source	create	1	aegis/version.c
+ 	source	create	1	aegis/version.h
+ 	source	create	1	aux/ALPHA.man
+ 	source	create	1	aux/BUILDING.man
+ 	source	create	1	aux/CHANGES.sh
+ 	source	create	1	aux/Howto.cook
+ 	source	create	1	aux/MANIFEST.sh
+ 	source	create	1	aux/Makefile.awk
+ 	source	create	1	aux/Makefile.sh
+ 	source	create	1	aux/README.man
+ 	source	create	1	aux/patches.sh
+ 	source	create	1	common/ansi.c
+ 	source	create	1	common/arglex.c
+ 	source	create	1	common/arglex.h
+ 	source	create	1	common/error.c
+ 	source	create	1	common/error.h
+ 	source	create	1	common/indent.c
+ 	source	create	1	common/indent.h
+ 	source	create	1	common/main.h
+ 	source	create	1	common/mem.c
+ 	source	create	1	common/mem.h
+ 	source	create	1	common/option.c
+ 	source	create	1	common/option.h
+ 	source	create	1	common/s-v-arg.h
+ 	source	create	1	common/str.c
+ 	source	create	1	common/str.h
+ 	source	create	1	common/trace.c
+ 	source	create	1	common/trace.h
+ 	source	create	1	common/word.c
+ 	source	create	1	common/word.h
+ 	source	create	1	conf/ConvexOS-10
+ 	source	create	1	conf/SunOS-4.1.1
+ 	source	create	1	conf/SunOS-4.1.2
+ 	source	create	1	conf/SunOS-4.1.3
+ 	source	create	1	conf/SysV-4.0
+ 	source	create	1	conf/dgux-5.4.1
+ 	source	create	1	config
+ 	source	create	1	doc/aegis.ms
+ 	source	create	1	doc/c1.0.so
+ 	source	create	1	doc/c1.1.so
+ 	source	create	1	doc/c1.2.so
+ 	source	create	1	doc/c1.3.so
+ 	source	create	1	doc/c1.4.so
+ 	source	create	1	doc/c2.0.so
+ 	source	create	1	doc/c2.1.so
+ 	source	create	1	doc/c2.2.so
+ 	source	create	1	doc/c2.3.so
+ 	source	create	1	doc/c2.4.so
+ 	source	create	1	doc/c3.0.so
+ 	source	create	1	doc/c3.1.so
+ 	source	create	1	doc/c3.2.so
+ 	source	create	1	doc/c3.3.so
+ 	source	create	1	doc/c4.0.so
+ 	source	create	1	doc/c4.1.so
+ 	source	create	1	doc/c4.2.so
+ 
+ 
+ 
+ Project "aegis.1.4", Change 1					  Page 4
+ Change Details					Tue Mar 30 23:57:27 1993
+ 
+ 	Type	Action	Edit	File Name
+ 	------- ------- ------- -----------
+ 	source	create	1	doc/c4.3.so
+ 	source	create	1	doc/c5.0.so
+ 	source	create	1	doc/c6.0.so
+ 	source	create	1	doc/c7.0.so
+ 	source	create	1	doc/c7.1.so
+ 	source	create	1	doc/c7.2.so
+ 	source	create	1	doc/c7.4.so
+ 	source	create	1	doc/c7.5.so
+ 	source	create	1	doc/cA.0.so
+ 	source	create	1	doc/cB.0.so
+ 	source	create	1	dot.cshrc
+ 	source	create	1	dot.profile
+ 	source	create	1	fmtgen/id.c
+ 	source	create	1	fmtgen/id.h
+ 	source	create	1	fmtgen/lex.c
+ 	source	create	1	fmtgen/lex.h
+ 	source	create	1	fmtgen/main.c
+ 	source	create	1	fmtgen/parse.h
+ 	source	create	1	fmtgen/parse.y
+ 	source	create	1	fmtgen/type.c
+ 	source	create	1	fmtgen/type.h
+ 	source	create	1	fmtgen/type_enum.c
+ 	source	create	1	fmtgen/type_integ.c
+ 	source	create	1	fmtgen/type_list.c
+ 	source	create	1	fmtgen/type_ref.c
+ 	source	create	1	fmtgen/type_strin.c
+ 	source	create	1	fmtgen/type_struc.c
+ 	source	create	1	h/stdarg.h-min
+ 	source	create	1	h/stddef.h
+ 	source	create	1	h/stdlib.h
+ 	source	create	1	man1/aeb.1
+ 	source	create	1	man1/aeca.1
+ 	source	create	1	man1/aecd.1
+ 	source	create	1	man1/aecp.1
+ 	source	create	1	man1/aecpu.1
+ 	source	create	1	man1/aed.1
+ 	source	create	1	man1/aedb.1
+ 	source	create	1	man1/aedbu.1
+ 	source	create	1	man1/aede.1
+ 	source	create	1	man1/aedeu.1
+ 	source	create	1	man1/aegis.1
+ 	source	create	1	man1/aeib.1
+ 	source	create	1	man1/aeibu.1
+ 	source	create	1	man1/aeif.1
+ 	source	create	1	man1/aeip.1
+ 	source	create	1	man1/ael.1
+ 	source	create	1	man1/aena.1
+ 	source	create	1	man1/aenc.1
+ 	source	create	1	man1/aencu.1
+ 	source	create	1	man1/aend.1
+ 	source	create	1	man1/aenf.1
+ 	source	create	1	man1/aenfu.1
+ 	source	create	1	man1/aeni.1
+ 	source	create	1	man1/aenpr.1
+ 	source	create	1	man1/aenrls.1
+ 
+ 
+ 
+ Project "aegis.1.4", Change 1					  Page 5
+ Change Details					Tue Mar 30 23:57:27 1993
+ 
+ 	Type	Action	Edit	File Name
+ 	------- ------- ------- -----------
+ 	source	create	1	man1/aenrv.1
+ 	source	create	1	man1/aent.1
+ 	source	create	1	man1/aentu.1
+ 	source	create	1	man1/aepa.1
+ 	source	create	1	man1/aera.1
+ 	source	create	1	man1/aerd.1
+ 	source	create	1	man1/aerf.1
+ 	source	create	1	man1/aeri.1
+ 	source	create	1	man1/aerm.1
+ 	source	create	1	man1/aermu.1
+ 	source	create	1	man1/aerp.1
+ 	source	create	1	man1/aerpr.1
+ 	source	create	1	man1/aerpu.1
+ 	source	create	1	man1/aerrv.1
+ 	source	create	1	man1/aet.1
+ 	source	create	1	man1/aev.1
+ 	source	create	1	man1/install.sh
+ 	source	create	1	man1/o__rules.so
+ 	source	create	1	man1/o_anticip.so
+ 	source	create	1	man1/o_auto.so
+ 	source	create	1	man1/o_baselin.so
+ 	source	create	1	man1/o_change.so
+ 	source	create	1	man1/o_devdir.so
+ 	source	create	1	man1/o_dir.so
+ 	source	create	1	man1/o_help.so
+ 	source	create	1	man1/o_indep.so
+ 	source	create	1	man1/o_keep.so
+ 	source	create	1	man1/o_lib.so
+ 	source	create	1	man1/o_list.so
+ 	source	create	1	man1/o_major.so
+ 	source	create	1	man1/o_manual.so
+ 	source	create	1	man1/o_min.so
+ 	source	create	1	man1/o_minor.so
+ 	source	create	1	man1/o_nolog.so
+ 	source	create	1	man1/o_overw.so
+ 	source	create	1	man1/o_page.so
+ 	source	create	1	man1/o_project.so
+ 	source	create	1	man1/o_terse.so
+ 	source	create	1	man1/o_verbose.so
+ 	source	create	1	man1/z_cr.so
+ 	source	create	1	man1/z_exit.so
+ 	source	create	1	man1/z_intuit.so
+ 	source	create	1	man1/z_name.so
+ 	source	create	1	man5/aecattr.5
+ 	source	create	1	man5/aecstate.5
+ 	source	create	1	man5/aedir.5
+ 	source	create	1	man5/aegis.5
+ 	source	create	1	man5/aegstate.5
+ 	source	create	1	man5/aepattr.5
+ 	source	create	1	man5/aepconf.5
+ 	source	create	1	man5/aepstate.5
+ 	source	create	1	man5/aeuconf.5
+ 	source	create	1	man5/aeustate.5
+ 	source	create	1	man5/install.sh
+ 	source	create	1	man5/z_cr.so
+ 
+ 
+ 
+ Project "aegis.1.4", Change 1					  Page 6
+ Change Details					Tue Mar 30 23:57:27 1993
+ 
+ 	Type	Action	Edit	File Name
+ 	------- ------- ------- -----------
+ 	source	create	1	man5/z_name.so
+ 	source	create	1	notify/de.sh
+ 	source	create	1	notify/deu.sh
+ 	source	create	1	notify/if.sh
+ 	source	create	1	notify/ip.sh
+ 	source	create	1	notify/rf.sh
+ 	source	create	1	notify/rp.sh
+ 	source	create	1	notify/rpu.sh
+ 	test	create	1	test/00/t0001a.sh
+ 	test	create	1	test/00/t0002a.sh
+ 	test	create	1	test/00/t0003a.sh
+ 	test	create	1	test/00/t0004a.sh
+ 	test	create	1	test/00/t0005a.sh
+ 	test	create	1	test/00/t0006a.sh
+ 	test	create	1	test/00/t0007a.sh
+ 	test	create	1	test/00/t0008a.sh
+ 	test	create	1	test/00/t0009a.sh
+ 	test	create	1	test/00/t0010a.sh
+ 	test	create	1	test/00/t0011a.sh
+ 
+ HISTORY
+ 	What		When		Who	Comment
+ 	------		------		-----	---------
+ 	new_change	Thu Jan	 7	pmiller
+ 			16:12:43 1993	1
+ 	develop_begin	Thu Jan	 7	pmiller
+ 			16:12:43 1993	1
+ 	develop_end	Thu Jan	 7	pmiller
+ 			16:12:43 1993	1
+ 	review_pass	Thu Jan	 7	pmiller
+ 			16:12:43 1993	1
+ 	integrate_begin Thu Jan	 7	pmiller
+ 			16:12:43 1993	1
+ 	integrate_pass	Thu Jan	 7	pmiller
+ 			16:21:54 1993	1
+ 
+ 
+ 
+ Project "aegis.1.4", Change 2					  Page 1
+ Change Details					Tue Mar 30 23:57:28 1993
+ 
+ NAME
+ 	Project "aegis.1.4", Delta 2, Change 2.
+ 
+ SUMMARY
+ 	create the aermpr command
+ 
+ DESCRIPTION
+ 	create the aermpr command
+ 
+ CAUSE
+ 	This change was caused by internal_enhancement.
+ 
+ FILES
+ 	Type	Action	Edit	File Name
+ 	------- ------- ------- -----------
+ 	source	modify	2	aegis/gonzo.c
+ 	source	modify	2	aegis/gonzo.h
+ 	source	modify	2	aegis/integra2.c
+ 	source	modify	2	aegis/main.c
+ 	source	create	1	aegis/rem_proj.c
+ 	source	create	1	aegis/rem_proj.h
+ 	source	modify	2	man1/aegis.1
+ 	source	create	1	man1/aermpr.1
+ 	source	remove	1	man1/aerpr.1
+ 	source	modify	2	man1/o_keep.so
+ 	test	create	1	test/00/t0012a.sh
+ 
+ HISTORY
+ 	What		When		Who	Comment
+ 	------		------		-----	---------
+ 	new_change	Thu Jan	 7	pmiller
+ 			21:34:50 1993
+ 	develop_begin	Thu Jan	 7	pmiller Elapsed time: 1.084
+ 			21:35:17 1993		days.
+ 	develop_end	Fri Jan	 8	pmiller
+ 			22:12:52 1993
+ 	review_pass	Fri Jan	 8	pmiller
+ 			22:13:05 1993
+ 	integrate_begin Fri Jan	 8	pmiller Elapsed time: 0.060
+ 			22:13:57 1993		days.
+ 	integrate_pass	Fri Jan	 8	pmiller
+ 			22:40:53 1993
+ 
+ 
+ 
+ Project "aegis.1.4", Change 3					  Page 1
+ Change Details					Tue Mar 30 23:57:28 1993
+ 
+ NAME
+ 	Project "aegis.1.4", Delta 3, Change 3.
+ 
+ SUMMARY
+ 	aenrls dumped core for non-owner but worked for owner
+ 
+ DESCRIPTION
+ 	The aenrls command dumped core for non-owner but worked for
+ 	owner, because group field of the new project was being
+ 	referenced before it was initialized.  It worked for the owner
+ 	because that user has been seen earlier, and so the project's
+ 	group was never queried.
+ 
+ 	This change is exempt from testing.  This change is exempt from
+ 	testing against the baseline.
+ 
+ CAUSE
+ 	This change was caused by internal_bug.
+ 
+ FILES
+ 	Type	Action	Edit	File Name
+ 	------- ------- ------- -----------
+ 	source	modify	2	aegis/new_rele.c
+ 	source	modify	2	dot.cshrc
+ 	source	modify	2	dot.profile
+ 
+ HISTORY
+ 	What		When		Who	Comment
+ 	------		------		-----	---------
+ 	new_change	Fri Jan	 8	pmiller
+ 			22:42:58 1993
+ 	develop_begin	Fri Jan	 8	pmiller Elapsed time: 0.812
+ 			22:43:12 1993		days.
+ 	develop_end	Sat Jan	 9	pmiller
+ 			21:18:24 1993
+ 	develop_end_	Sat Jan	 9	pmiller Elapsed time: 0.054
+ 	undo		21:19:10 1993		days.
+ 	develop_end	Sat Jan	 9	pmiller
+ 			21:43:31 1993
+ 	review_pass	Sat Jan	 9	pmiller
+ 			21:43:40 1993
+ 	integrate_begin Sat Jan	 9	pmiller Elapsed time: 0.050
+ 			21:44:28 1993		days.
+ 	integrate_pass	Sat Jan	 9	pmiller
+ 			22:06:50 1993
+ 
+ 
+ 
+ Project "aegis.1.4", Change 4					  Page 1
+ Change Details					Tue Mar 30 23:57:29 1993
+ 
+ NAME
+ 	Project "aegis.1.4", Delta 4, Change 4.
+ 
+ SUMMARY
+ 	implement the aencu functionality
+ 
+ DESCRIPTION
+ 	Implement the -New_Change_Undo functionality
+ 
+ CAUSE
+ 	This change was caused by internal_enhancement.
+ 
+ FILES
+ 	Type	Action	Edit	File Name
+ 	------- ------- ------- -----------
+ 	source	modify	2	aegis/new_chan.c
+ 	source	modify	2	aegis/project.c
+ 	source	modify	2	aegis/project.h
+ 	test	create	1	test/00/t0013a.sh
+ 
+ HISTORY
+ 	What		When		Who	Comment
+ 	------		------		-----	---------
+ 	new_change	Sat Jan	 9	pmiller
+ 			22:08:25 1993
+ 	develop_begin	Sat Jan	 9	pmiller Elapsed time: 1.065
+ 			22:08:49 1993		days.
+ 	develop_end	Sun Jan 10	pmiller
+ 			22:38:12 1993
+ 	review_pass	Sun Jan 10	pmiller
+ 			22:38:55 1993
+ 	integrate_begin Sun Jan 10	pmiller Elapsed time: 0.052
+ 			22:39:54 1993		days.
+ 	integrate_pass	Sun Jan 10	pmiller
+ 			23:03:27 1993
+ 
+ 
+ 
+ Project "aegis.1.4", Change 5					  Page 1
+ Change Details					Tue Mar 30 23:57:30 1993
+ 
+ NAME
+ 	Project "aegis.1.4", Delta 5, Change 5.
+ 
+ SUMMARY
+ 	implement the aedbu functionality
+ 
+ DESCRIPTION
+ 	implement the aedbu functionality
+ 
+ CAUSE
+ 	This change was caused by internal_enhancement.
+ 
+ FILES
+ 	Type	Action	Edit	File Name
+ 	------- ------- ------- -----------
+ 	source	modify	2	aegis/develop2.c
+ 	test	create	1	test/00/t0014a.sh
+ 
+ HISTORY
+ 	What		When		Who	Comment
+ 	------		------		-----	---------
+ 	new_change	Sun Jan 10	pmiller
+ 			23:04:57 1993
+ 	develop_begin	Sun Jan 10	pmiller Elapsed time: 0.000
+ 			23:05:04 1993		days.
+ 	develop_end	Mon Jan 11	pmiller
+ 			11:13:41 1993
+ 	review_pass	Mon Jan 11	pmiller
+ 			11:13:51 1993
+ 	integrate_begin Mon Jan 11	pmiller Elapsed time: 0.126
+ 			11:14:36 1993		days.
+ 	integrate_pass	Mon Jan 11	pmiller
+ 			12:11:06 1993
+ 
+ 
+ 
+ Project "aegis.1.4", Change 6					  Page 1
+ Change Details					Tue Mar 30 23:57:30 1993
+ 
+ NAME
+ 	Project "aegis.1.4", Delta 6, Change 6.
+ 
+ SUMMARY
+ 	note that ULTRIX was tried
+ 
+ DESCRIPTION
+ 	A build of aegis as tried on ULTRIX 4.2.	 It failed,
+ 	because the ULTRIX Bourne shell does not have functions.
+ 	Complain to your vendor.
+ 
+ 	This change is exempt from testing.  This change is exempt from
+ 	testing against the baseline.
+ 
+ CAUSE
+ 	This change was caused by internal_enhancement.
+ 
+ FILES
+ 	Type	Action	Edit	File Name
+ 	------- ------- ------- -----------
+ 	source	modify	2	aux/BUILDING.man
+ 	source	modify	2	aux/README.man
+ 	source	create	1	conf/ULTRIX-4.2
+ 
+ HISTORY
+ 	What		When		Who	Comment
+ 	------		------		-----	---------
+ 	new_change	Mon Jan 11	pmiller
+ 			12:12:07 1993
+ 	develop_begin	Mon Jan 11	pmiller Elapsed time: 0.025
+ 			12:12:18 1993		days.
+ 	develop_end	Mon Jan 11	pmiller
+ 			12:23:22 1993
+ 	review_pass	Mon Jan 11	pmiller
+ 			12:23:49 1993
+ 	integrate_begin Mon Jan 11	pmiller Elapsed time: 0.059
+ 			12:24:43 1993		days.
+ 	integrate_pass	Mon Jan 11	pmiller
+ 			12:51:09 1993
+ 
+ 
+ 
+ Project "aegis.1.4", Change 7					  Page 1
+ Change Details					Tue Mar 30 23:57:31 1993
+ 
+ NAME
+ 	Project "aegis.1.4", Delta 7, Change 7.
+ 
+ SUMMARY
+ 	add a build lock, to protect builds from integrate pass
+ 
+ DESCRIPTION
+ 	It is possible that if an integrate pass were to happen buring
+ 	a development build, then the build could fail, because it was
+ 	started with one baseline with includes and objects, and
+ 	completed with a different baseline with includes and objects,
+ 	albeit with the same name.
+ 
+ 	To prevent this, a build lock is taken by builds (non
+ 	exclusive) and by integrate pass (exclusive) to prevent this
+ 	from happenning.
+ 
+ 	My thanks to Neil Justusson <njustusson@wampyr.cc.uow.edu.au>
+ 	for reporting this problem.
+ 
+ 	This change is exempt from testing.  This change is exempt from
+ 	testing against the baseline.
+ 
+ CAUSE
+ 	This change was caused by external_bug.
+ 
+ FILES
+ 	Type	Action	Edit	File Name
+ 	------- ------- ------- -----------
+ 	source	modify	2	aegis/build.c
+ 	source	modify	3	aegis/integra2.c
+ 	source	modify	2	aegis/lock.c
+ 	source	modify	2	aegis/lock.h
+ 	source	modify	3	aegis/new_rele.c
+ 	source	modify	3	aegis/project.c
+ 	source	modify	3	aegis/project.h
+ 
+ HISTORY
+ 	What		When		Who	Comment
+ 	------		------		-----	---------
+ 	new_change	Mon Jan 11	pmiller
+ 			12:58:27 1993
+ 	develop_begin	Mon Jan 11	pmiller Elapsed time: 0.207
+ 			12:58:36 1993		days.
+ 	develop_end	Mon Jan 11	pmiller
+ 			14:31:50 1993
+ 	develop_end_	Mon Jan 11	pmiller
+ 	undo		14:33:31 1993
+ 	develop_end	Mon Jan 11	pmiller
+ 			14:41:05 1993
+ 	review_pass	Mon Jan 11	pmiller
+ 			14:51:01 1993
+ 	integrate_begin Mon Jan 11	pmiller Elapsed time: 0.892
+ 			14:51:54 1993		days.
+ 	integrate_pass	Mon Jan 11	pmiller
+ 			21:33:16 1993
+ 
+ 
+ 
+ Project "aegis.1.4", Change 8					  Page 1
+ Change Details					Tue Mar 30 23:57:32 1993
+ 
+ NAME
+ 	Project "aegis.1.4", Delta 8, Change 8.
+ 
+ SUMMARY
+ 	clear build time and diff time fields of config copied into a
+ 	change
+ 
+ DESCRIPTION
+ 	It was possible to deceive aegis about the success or otherwise
+ 	of builds and diferences, by manipulating the config file.  By
+ 	invalidating builds and differences when the config file is
+ 	added to or removed from a change, this ability goes away.
+ 
+ 	Update the manual entries to describe the build lock.
+ 
+ 	This change is exempt from testing.  This change is exempt from
+ 	testing against the baseline.
+ 
+ CAUSE
+ 	This change was caused by internal_bug.
+ 
+ FILES
+ 	Type	Action	Edit	File Name
+ 	------- ------- ------- -----------
+ 	source	modify	3	aegis/build.c
+ 	source	modify	2	aegis/copyfile.c
+ 	source	modify	4	aegis/integra2.c
+ 	source	modify	2	man1/aeb.1
+ 	source	modify	2	man1/aecp.1
+ 	source	modify	2	man1/aecpu.1
+ 	source	modify	2	man1/aeip.1
+ 	source	create	1	man1/o_bld_lk.so
+ 
+ HISTORY
+ 	What		When		Who	Comment
+ 	------		------		-----	---------
+ 	new_change	Mon Jan 11	pmiller
+ 			21:37:50 1993
+ 	develop_begin	Mon Jan 11	pmiller Elapsed time: 0.138
+ 			21:38:06 1993		days.
+ 	develop_end	Mon Jan 11	pmiller
+ 			22:40:25 1993
+ 	review_pass	Mon Jan 11	pmiller
+ 			22:40:36 1993
+ 	integrate_begin Mon Jan 11	pmiller Elapsed time: 0.056
+ 			22:41:28 1993		days.
+ 	integrate_pass	Mon Jan 11	pmiller
+ 			23:06:27 1993
+ 
+ 
+ 
+ Project "aegis.1.4", Change 9					  Page 1
+ Change Details					Tue Mar 30 23:57:33 1993
+ 
+ NAME
+ 	Project "aegis.1.4", Delta 9, Change 9.
+ 
+ SUMMARY
+ 	add the AEGIS_PROJECT and AEGIS_CHANGE environment variables
+ 
+ DESCRIPTION
+ 	1. Experience has shown that these envionment variables are
+ 	essential to allow aegis to be used by more than one project.
+ 	Users frequently work on one project while waiting for a build
+ 	on another.
+ 	2. allow administrators to delete projects, not just owners
+ 	(since administrators may initiate -NewRelease)
+ 
+ 	This change is exempt from testing.  This change is exempt from
+ 	testing against the baseline.
+ 
+ CAUSE
+ 	This change was caused by internal_enhancement.
+ 
+ FILES
+ 	Type	Action	Edit	File Name
+ 	------- ------- ------- -----------
+ 	source	modify	2	aegis/administ.c
+ 	source	modify	4	aegis/build.c
+ 	source	modify	2	aegis/cattr_ed.c
+ 	source	modify	2	aegis/chdir.c
+ 	source	modify	3	aegis/copyfile.c
+ 	source	modify	2	aegis/develop1.c
+ 	source	modify	3	aegis/develop2.c
+ 	source	modify	2	aegis/diff.c
+ 	source	modify	2	aegis/integra1.c
+ 	source	modify	5	aegis/integra2.c
+ 	source	modify	2	aegis/list.c
+ 	source	modify	3	aegis/new_chan.c
+ 	source	modify	2	aegis/new_file.c
+ 	source	modify	2	aegis/new_test.c
+ 	source	modify	2	aegis/pattr_ed.c
+ 	source	modify	2	aegis/rem_file.c
+ 	source	modify	2	aegis/rem_proj.c
+ 	source	modify	2	aegis/review.c
+ 	source	modify	2	aegis/reviewer.c
+ 	source	modify	2	aegis/test.c
+ 	source	modify	2	aegis/uconf.def
+ 	source	modify	2	aegis/user.c
+ 	source	modify	2	man1/aermpr.1
+ 	source	modify	2	man1/o_change.so
+ 	source	modify	2	man1/o_project.so
+ 	source	modify	2	man5/aeuconf.5
+ 
+ HISTORY
+ 	What		When		Who	Comment
+ 	------		------		-----	---------
+ 	new_change	Mon Jan 11	pmiller
+ 			23:07:58 1993
+ 	develop_begin	Mon Jan 11	pmiller Elapsed time: 0.080
+ 			23:08:11 1993		days.
+ 
+ 
+ 
+ Project "aegis.1.4", Change 9					  Page 2
+ Change Details					Tue Mar 30 23:57:33 1993
+ 
+ 	What		When		Who	Comment
+ 	------		------		-----	---------
+ 	develop_end	Tue Jan 12	pmiller
+ 			16:14:21 1993
+ 	review_pass	Tue Jan 12	pmiller
+ 			16:14:33 1993
+ 	integrate_begin Tue Jan 12	pmiller Elapsed time: 0.067
+ 			16:15:24 1993		days.
+ 	integrate_pass	Tue Jan 12	pmiller
+ 			16:45:26 1993
+ 
+ 
+ 
+ Project "aegis.1.4", Change 10					  Page 1
+ Change Details					Tue Mar 30 23:57:34 1993
+ 
+ NAME
+ 	Project "aegis.1.4", Delta 11, Change 10.
+ 
+ SUMMARY
+ 	improve handling of outomounter directories
+ 
+ DESCRIPTION
+ 	The simplistic method used for coping with the automounter
+ 	proved ineffective, because it assumed (among other things)
+ 	that the mounts would be direct mounts.	 A more robust method,
+ 	invokving searching the /etc/mtab file for mount information,
+ 	has been implemented.
+ 
+ 	My thanks to Malcolm C. Strickland <chuck-
+ 	strickland@orl.mmc.com> for reporting this problem.  (And
+ 	probably numerous others in the coming days.)
+ 
+ 	There are some systems out there which use a getmnt() system
+ 	call, rather than have a /etc/mtab file.  I don't have access
+ 	to one, so this case is not handled by this change.  Volunteers?
+ 
+ 	This change is exempt from testing.  This change is exempt from
+ 	testing against the baseline.
+ 
+ CAUSE
+ 	This change was caused by external_bug.
+ 
+ FILES
+ 	Type	Action	Edit	File Name
+ 	------- ------- ------- -----------
+ 	source	create	1	aegis/automount.c
+ 	source	create	1	aegis/automount.h
+ 	source	modify	3	aegis/gonzo.c
+ 	source	modify	2	aegis/os.c
+ 	source	modify	2	aux/Howto.cook
+ 	source	modify	3	aux/README.man
+ 	source	modify	2	conf/ConvexOS-10
+ 	source	modify	2	conf/SunOS-4.1.1
+ 	source	modify	2	conf/SunOS-4.1.2
+ 	source	modify	2	conf/SunOS-4.1.3
+ 	source	modify	2	conf/SysV-4.0
+ 	source	modify	2	conf/ULTRIX-4.2
+ 	source	modify	2	conf/dgux-5.4.1
+ 
+ HISTORY
+ 	What		When		Who	Comment
+ 	------		------		-----	---------
+ 	new_change	Fri Jan 22	pmiller
+ 			10:07:13 1993
+ 	develop_begin	Fri Jan 22	pmiller Elapsed time: 0.621
+ 			10:07:19 1993		days.
+ 	develop_end	Fri Jan 22	pmiller
+ 			14:46:56 1993
+ 	review_pass	Fri Jan 22	pmiller
+ 			14:47:07 1993
+ 	integrate_begin Fri Jan 22	pmiller
+ 			14:47:58 1993
+ 
+ 
+ 
+ Project "aegis.1.4", Change 10					  Page 2
+ Change Details					Tue Mar 30 23:57:34 1993
+ 
+ 	What		When		Who	Comment
+ 	------		------		-----	---------
+ 	integrate_fail	Fri Jan 22	pmiller awk bew its brains out
+ 			14:55:21 1993		in creating Makefile.
+ 						Replace it with gawk.
+ 						Elapsed time: 0.059
+ 						days.
+ 	develop_end	Fri Jan 22	pmiller
+ 			15:21:52 1993
+ 	review_pass	Fri Jan 22	pmiller
+ 			15:25:59 1993
+ 	integrate_begin Fri Jan 22	pmiller Elapsed time: 0.127
+ 			15:26:53 1993		days.
+ 	integrate_pass	Fri Jan 22	pmiller
+ 			16:23:51 1993
+ 
+ 
+ 
+ Project "aegis.1.4", Change 11					  Page 1
+ Change Details					Tue Mar 30 23:57:35 1993
+ 
+ NAME
+ 	Project "aegis.1.4", Delta 12, Change 11.
+ 
+ SUMMARY
+ 	document CVS vs Aegis
+ 
+ DESCRIPTION
+ 	add a comparison of CVS to the documentation and to the README
+ 	file.
+ 
+ 	The people who asked for this information are too numerous to
+ 	remember.  Thank you all for prompting me for this information.
+ 
+ 	This change is exempt from testing.  This change is exempt from
+ 	testing against the baseline.
+ 
+ CAUSE
+ 	This change was caused by internal_enhancement.
+ 
+ FILES
+ 	Type	Action	Edit	File Name
+ 	------- ------- ------- -----------
+ 	source	modify	3	aux/Howto.cook
+ 	source	modify	4	aux/README.man
+ 	source	modify	2	doc/aegis.ms
+ 	source	modify	2	doc/c7.4.so
+ 	source	create	1	doc/cC.0.so
+ 
+ HISTORY
+ 	What		When		Who	Comment
+ 	------		------		-----	---------
+ 	new_change	Sun Jan 24	pmiller
+ 			09:21:25 1993
+ 	develop_begin	Sun Jan 24	pmiller Elapsed time: 0.000
+ 			09:22:21 1993		days.
+ 	develop_end	Sun Jan 24	pmiller
+ 			23:30:22 1993
+ 	review_pass	Sun Jan 24	pmiller
+ 			23:30:30 1993
+ 	integrate_begin Sun Jan 24	pmiller Elapsed time: 0.000
+ 			23:31:31 1993		days.
+ 	integrate_pass	Mon Jan 25	pmiller
+ 			09:31:26 1993
+ 
+ 
+ 
+ Project "aegis.1.4", Change 12					  Page 1
+ Change Details					Tue Mar 30 23:57:35 1993
+ 
+ NAME
+ 	Project "aegis.1.4", Delta 29, Change 12.
+ 
+ SUMMARY
+ 	complete the chapter 3 example in the User Guide
+ 
+ DESCRIPTION
+ 	complete the chapter 3 example in the User Guide
+ 
+ 	This change is exempt from testing against the baseline.
+ 
+ CAUSE
+ 	This change was caused by internal_enhancement.
+ 
+ FILES
+ 	Type	Action	Edit	File Name
+ 	------- ------- ------- -----------
+ 	source	modify	9	aegis/diff.c
+ 	source	modify	3	aegis/help.c
+ 	source	modify	8	aux/Howto.cook
+ 	source	modify	4	aux/MANIFEST.sh
+ 	source	modify	11	aux/README.man
+ 	source	modify	8	config
+ 	source	modify	4	doc/aegis.ms
+ 	source	modify	3	doc/c1.0.so
+ 	source	modify	3	doc/c2.0.so
+ 	source	modify	3	doc/c2.1.so
+ 	source	modify	3	doc/c2.2.so
+ 	source	modify	3	doc/c2.3.so
+ 	source	modify	3	doc/c2.4.so
+ 	source	create	1	doc/c2.5.so
+ 	source	modify	4	man1/z_cr.so
+ 	source	modify	4	man5/z_cr.so
+ 	test	modify	6	test/00/t0011a.sh
+ 
+ HISTORY
+ 	What		When		Who	Comment
+ 	------		------		-----	---------
+ 	new_change	Mon Jan 25	pmiller
+ 			09:34:05 1993
+ 	develop_begin	Mon Jan 25	pmiller Elapsed time: 29.559
+ 			09:34:13 1993		days.
+ 	develop_end	Mon Mar	 8	pmiller
+ 			21:45:42 1993
+ 	review_pass	Mon Mar	 8	pmiller
+ 			21:45:52 1993
+ 	integrate_begin Mon Mar	 8	pmiller Elapsed time: 0.063
+ 			21:47:08 1993		days.
+ 	integrate_pass	Mon Mar	 8	pmiller
+ 			22:15:24 1993
+ 
+ 
+ 
+ Project "aegis.1.4", Change 13					  Page 1
+ Change Details					Tue Mar 30 23:57:36 1993
+ 
+ NAME
+ 	Project "aegis.1.4", Delta 15, Change 13.
+ 
+ SUMMARY
+ 	inprove failure messages from tests
+ 
+ DESCRIPTION
+ 	Tests need to say what failed when they fail.
+ 
+ 	My thanks to J. Cazander, Philips Electronic Design & Tools,
+ 	The Netherlands, for this suggestion.
+ 
+ 	This change is exempt from testing against the baseline.
+ 
+ CAUSE
+ 	This change was caused by external_enhancement.
+ 
+ FILES
+ 	Type	Action	Edit	File Name
+ 	------- ------- ------- -----------
+ 	source	modify	3	config
+ 	test	modify	2	test/00/t0001a.sh
+ 	test	modify	2	test/00/t0002a.sh
+ 	test	modify	2	test/00/t0003a.sh
+ 	test	modify	2	test/00/t0004a.sh
+ 	test	modify	2	test/00/t0005a.sh
+ 	test	modify	2	test/00/t0006a.sh
+ 	test	modify	2	test/00/t0007a.sh
+ 	test	modify	2	test/00/t0008a.sh
+ 	test	modify	2	test/00/t0009a.sh
+ 	test	modify	2	test/00/t0010a.sh
+ 	test	modify	2	test/00/t0011a.sh
+ 	test	modify	2	test/00/t0012a.sh
+ 	test	modify	2	test/00/t0013a.sh
+ 	test	modify	2	test/00/t0014a.sh
+ 
+ HISTORY
+ 	What		When		Who	Comment
+ 	------		------		-----	---------
+ 	new_change	Sat Jan 30	pmiller Elapsed time: 1.135
+ 			23:04:42 1993		days.
+ 	develop_begin	Tue Feb	 2	pmiller Elapsed time: 0.721
+ 			16:35:34 1993		days.
+ 	develop_end	Tue Feb	 2	pmiller
+ 			22:00:03 1993
+ 	review_pass	Tue Feb	 2	pmiller
+ 			22:00:16 1993
+ 	integrate_begin Tue Feb	 2	pmiller Elapsed time: 0.095
+ 			22:01:11 1993		days.
+ 	integrate_pass	Tue Feb	 2	pmiller
+ 			22:43:54 1993
+ 
+ 
+ 
+ Project "aegis.1.4", Change 14					  Page 1
+ Change Details					Tue Mar 30 23:57:37 1993
+ 
+ NAME
+ 	Project "aegis.1.4", Delta 13, Change 14.
+ 
+ SUMMARY
+ 	make automounter handling more robust
+ 
+ DESCRIPTION
+ 	The automounter mangles pathnames.  What the user thinks a file
+ 	is called and what the system insists that it is called can
+ 	differ radically.  Change aegis to compare the system's idea of
+ 	pathnames, not the user's idead of pathnames.
+ 	* make sure the manuals for the -dir options mention the risks
+ 	of using `pwd`.
+ 	* make sure defaults go through use home directory (not am
+ 	mangled) or user defined default (hopefully not am mangled).
+ 
+ 	This change is exempt from testing.  This change is exempt from
+ 	testing against the baseline.
+ 
+ CAUSE
+ 	This change was caused by internal_enhancement.
+ 
+ FILES
+ 	Type	Action	Edit	File Name
+ 	------- ------- ------- -----------
+ 	source	remove	1	aegis/automount.c
+ 	source	remove	1	aegis/automount.h
+ 	source	modify	2	aegis/change.c
+ 	source	modify	2	aegis/change.h
+ 	source	modify	3	aegis/chdir.c
+ 	source	modify	4	aegis/copyfile.c
+ 	source	modify	4	aegis/develop2.c
+ 	source	modify	6	aegis/integra2.c
+ 	source	modify	3	aegis/new_file.c
+ 	source	modify	2	aegis/new_proj.c
+ 	source	modify	4	aegis/new_rele.c
+ 	source	modify	3	aegis/new_test.c
+ 	source	modify	3	aegis/os.c
+ 	source	modify	4	aegis/project.c
+ 	source	modify	3	aegis/rem_file.c
+ 	source	modify	3	aegis/user.c
+ 	source	modify	2	man1/aedb.1
+ 	source	modify	2	man1/aenpr.1
+ 	source	modify	2	man1/aenrls.1
+ 	source	modify	2	man1/o_dir.so
+ 
+ HISTORY
+ 	What		When		Who	Comment
+ 	------		------		-----	---------
+ 	new_change	Sat Jan 30	pmiller
+ 			23:08:59 1993
+ 	develop_begin	Sat Jan 30	pmiller Elapsed time: 0.000
+ 			23:09:08 1993		days.
+ 	develop_end	Mon Feb	 1	pmiller
+ 			13:38:33 1993
+ 	review_pass	Mon Feb	 1	pmiller
+ 			13:38:43 1993
+ 
+ 
+ 
+ Project "aegis.1.4", Change 14					  Page 2
+ Change Details					Tue Mar 30 23:57:37 1993
+ 
+ 	What		When		Who	Comment
+ 	------		------		-----	---------
+ 	integrate_begin Mon Feb	 1	pmiller Elapsed time: 0.165
+ 			13:39:17 1993		days.
+ 	integrate_pass	Mon Feb	 1	pmiller
+ 			14:53:44 1993
+ 
+ 
+ 
+ Project "aegis.1.4", Change 15					  Page 1
+ Change Details					Tue Mar 30 23:57:38 1993
+ 
+ NAME
+ 	Project "aegis.1.4", Delta 14, Change 15.
+ 
+ SUMMARY
+ 	unix permissions for projects
+ 
+ DESCRIPTION
+ 	1. Make the 'ael p' listing cope with Permission denied errors
+ 	2. add the 'users_changes' listing to tell what a user is
+ 	currently working on
+ 	3. fix adcd to not resolve the symbolic links.
+ 
+ 	This change is exempt from testing.  This change is exempt from
+ 	testing against the baseline.
+ 
+ CAUSE
+ 	This change was caused by internal_bug.
+ 
+ FILES
+ 	Type	Action	Edit	File Name
+ 	------- ------- ------- -----------
+ 	source	modify	5	aegis/build.c
+ 	source	modify	3	aegis/change.c
+ 	source	modify	3	aegis/change.h
+ 	source	modify	4	aegis/chdir.c
+ 	source	modify	5	aegis/copyfile.c
+ 	source	modify	5	aegis/develop2.c
+ 	source	modify	3	aegis/diff.c
+ 	source	modify	4	aegis/gonzo.c
+ 	source	modify	7	aegis/integra2.c
+ 	source	modify	3	aegis/list.c
+ 	source	modify	2	aegis/list.h
+ 	source	modify	4	aegis/new_file.c
+ 	source	modify	3	aegis/new_proj.c
+ 	source	modify	5	aegis/new_rele.c
+ 	source	modify	4	aegis/new_test.c
+ 	source	modify	4	aegis/os.c
+ 	source	modify	2	aegis/os.h
+ 	source	modify	5	aegis/project.c
+ 	source	modify	4	aegis/project.h
+ 	source	modify	4	aegis/rem_file.c
+ 	source	modify	3	aegis/review.c
+ 	source	modify	2	aegis/sub.c
+ 	source	modify	3	aegis/test.c
+ 	source	modify	4	aegis/user.c
+ 	source	modify	2	aegis/user.h
+ 	source	modify	5	aux/README.man
+ 	source	modify	2	config
+ 	source	modify	2	man1/ael.1
+ 
+ HISTORY
+ 	What		When		Who	Comment
+ 	------		------		-----	---------
+ 	new_change	Mon Feb	 1	pmiller Elapsed time: 0.505
+ 			11:08:03 1993		days.
+ 	develop_begin	Mon Feb	 1	pmiller Elapsed time: 0.941
+ 			14:55:27 1993		days.
+ 
+ 
+ 
+ Project "aegis.1.4", Change 15					  Page 2
+ Change Details					Tue Mar 30 23:57:38 1993
+ 
+ 	What		When		Who	Comment
+ 	------		------		-----	---------
+ 	develop_end	Tue Feb	 2	pmiller
+ 			14:29:05 1993
+ 	review_pass	Tue Feb	 2	pmiller
+ 			14:29:12 1993
+ 	integrate_begin Tue Feb	 2	pmiller Elapsed time: 0.255
+ 			14:30:07 1993		days.
+ 	integrate_pass	Tue Feb	 2	pmiller
+ 			16:24:56 1993
+ 
+ 
+ 
+ Project "aegis.1.4", Change 16					  Page 1
+ Change Details					Tue Mar 30 23:57:39 1993
+ 
+ NAME
+ 	Project "aegis.1.4", Delta 16, Change 16.
+ 
+ SUMMARY
+ 	improve command substitutions
+ 
+ DESCRIPTION
+ 	1. Make the command substitutions be symbolic, as in
+ 	'${input}', rather than cryptic, as in '%1'.
+ 	2. Provide backwards compatibility for a few revs
+ 	3. change the manual entries with the %n form.
+ 	4. change the document to the new form
+ 	5. change the tests to use the new form
+ 
+ 	This change is exempt from testing against the baseline.
+ 
+ CAUSE
+ 	This change was caused by internal_enhancement.
+ 
+ FILES
+ 	Type	Action	Edit	File Name
+ 	------- ------- ------- -----------
+ 	source	modify	6	aegis/build.c
+ 	source	modify	2	aegis/cattr.def
+ 	source	modify	4	aegis/change.c
+ 	source	modify	4	aegis/diff.c
+ 	source	modify	8	aegis/integra2.c
+ 	source	modify	4	aegis/list.c
+ 	source	modify	6	aegis/new_rele.c
+ 	source	modify	2	aegis/pattr.def
+ 	source	modify	2	aegis/pconf.def
+ 	source	modify	3	aegis/sub.c
+ 	source	modify	2	aegis/sub.h
+ 	source	modify	2	aegis/version.c
+ 	source	modify	6	aux/README.man
+ 	source	modify	2	common/arglex.c
+ 	source	modify	2	common/arglex.h
+ 	source	modify	2	doc/c3.0.so
+ 	source	modify	2	doc/c3.1.so
+ 	source	modify	2	doc/c3.2.so
+ 	source	modify	2	doc/c3.3.so
+ 	source	modify	2	doc/c4.2.so
+ 	source	modify	3	doc/c7.4.so
+ 	source	modify	2	man1/z_cr.so
+ 	source	modify	2	man5/aecattr.5
+ 	source	create	1	man5/aecattr.so
+ 	source	modify	2	man5/aecstate.5
+ 	source	modify	2	man5/aepattr.5
+ 	source	create	1	man5/aepattr.so
+ 	source	modify	2	man5/aepconf.5
+ 	source	modify	2	man5/aepstate.5
+ 	source	create	1	man5/aesub.5
+ 	source	modify	2	man5/z_cr.so
+ 	test	modify	3	test/00/t0002a.sh
+ 	test	modify	3	test/00/t0004a.sh
+ 	test	modify	3	test/00/t0005a.sh
+ 	test	modify	3	test/00/t0006a.sh
+ 
+ 
+ 
+ Project "aegis.1.4", Change 16					  Page 2
+ Change Details					Tue Mar 30 23:57:39 1993
+ 
+ 	Type	Action	Edit	File Name
+ 	------- ------- ------- -----------
+ 	test	modify	3	test/00/t0007a.sh
+ 	test	modify	3	test/00/t0008a.sh
+ 	test	modify	3	test/00/t0009a.sh
+ 	test	modify	3	test/00/t0010a.sh
+ 	test	modify	3	test/00/t0011a.sh
+ 
+ HISTORY
+ 	What		When		Who	Comment
+ 	------		------		-----	---------
+ 	new_change	Mon Feb	 1	pmiller Elapsed time: 0.248
+ 			11:10:06 1993		days.
+ 	develop_begin	Tue Feb	 2	pmiller Elapsed time: 9.031
+ 			22:01:38 1993		days.
+ 	develop_end	Mon Feb 15	pmiller
+ 			22:15:31 1993
+ 	review_pass	Mon Feb 15	pmiller
+ 			22:16:34 1993
+ 	integrate_begin Mon Feb 15	pmiller Elapsed time: 0.000
+ 			22:17:57 1993		days.
+ 	integrate_pass	Tue Feb 16	pmiller
+ 			09:04:13 1993
+ 
+ 
+ 
+ Project "aegis.1.4", Change 17					  Page 1
+ Change Details					Tue Mar 30 23:57:39 1993
+ 
+ NAME
+ 	Project "aegis.1.4", Delta 18, Change 17.
+ 
+ SUMMARY
+ 	change configuration to use new substitutions
+ 
+ DESCRIPTION
+ 	1. change configuration to use new substitutions
+ 	2. fix bug where -New_Release fails to copy some of the
+ 	attributes.
+ 	3. rationalize some of the command executing functions
+ 
+ 	This change is exempt from testing.  This change is exempt from
+ 	testing against the baseline.
+ 
+ CAUSE
+ 	This change was caused by internal_enhancement.
+ 
+ FILES
+ 	Type	Action	Edit	File Name
+ 	------- ------- ------- -----------
+ 	source	modify	5	aegis/change.c
+ 	source	modify	4	aegis/change.h
+ 	source	modify	5	aegis/diff.c
+ 	source	modify	9	aegis/integra2.c
+ 	source	modify	7	aegis/new_rele.c
+ 	source	modify	3	aegis/pattr.def
+ 	source	modify	4	aegis/sub.c
+ 	source	modify	4	aux/Howto.cook
+ 	source	modify	7	aux/README.man
+ 	source	modify	2	aux/patches.sh
+ 	source	modify	4	config
+ 
+ HISTORY
+ 	What		When		Who	Comment
+ 	------		------		-----	---------
+ 	new_change	Tue Feb 16	pmiller
+ 			09:12:15 1993
+ 	develop_begin	Tue Feb 16	pmiller Elapsed time: 1.800
+ 			09:12:24 1993		days.
+ 	develop_end	Wed Feb 17	pmiller
+ 			15:12:32 1993
+ 	review_pass	Wed Feb 17	pmiller
+ 			15:12:50 1993
+ 	integrate_begin Wed Feb 17	pmiller Elapsed time: 0.075
+ 			15:13:38 1993		days.
+ 	integrate_fail	Wed Feb 17	pmiller problems creating th
+ 			15:47:26 1993		epatch
+ 						Elapsed time: 0.997
+ 						days.
+ 	develop_end	Wed Feb 17	pmiller
+ 			23:16:09 1993
+ 	review_pass	Wed Feb 17	pmiller
+ 			23:16:22 1993
+ 	integrate_begin Wed Feb 17	pmiller Elapsed time: 0.147
+ 			23:17:18 1993		days.
+ 	integrate_pass	Thu Feb 18	pmiller
+ 
+ 
+ 
+ Project "aegis.1.4", Change 17					  Page 2
+ Change Details					Tue Mar 30 23:57:39 1993
+ 
+ 	What		When		Who	Comment
+ 	------		------		-----	---------
+ 			16:53:32 1993
+ 
+ 
+ 
+ Project "aegis.1.4", Change 18					  Page 1
+ Change Details					Tue Mar 30 23:57:40 1993
+ 
+ NAME
+ 	Project "aegis.1.4", Delta 19, Change 18.
+ 
+ SUMMARY
+ 	improve copyright notices
+ 
+ DESCRIPTION
+ 	Change copyright notices to be legally binding
+ 
+ 	My thanks to Len <gnu@prep.ai.mit.edu> and Richard Stallman
+ 	<rms@gnu.ai.mit.edu> for for their advice in this matter.
+ 
+ 	This change is exempt from testing against the baseline.
+ 
+ CAUSE
+ 	This change was caused by external_bug.
+ 
+ FILES
+ 	Type	Action	Edit	File Name
+ 	------- ------- ------- -----------
+ 	source	remove	1	COPYING
+ 	source	create	1	LICENSE
+ 	source	modify	3	aegis/administ.c
+ 	source	modify	2	aegis/administ.h
+ 	source	modify	2	aegis/arglex2.h
+ 	source	modify	7	aegis/build.c
+ 	source	modify	2	aegis/build.h
+ 	source	modify	3	aegis/cattr.def
+ 	source	modify	3	aegis/cattr_ed.c
+ 	source	modify	2	aegis/cattr_ed.h
+ 	source	modify	6	aegis/change.c
+ 	source	modify	5	aegis/change.h
+ 	source	modify	5	aegis/chdir.c
+ 	source	modify	2	aegis/chdir.h
+ 	source	modify	2	aegis/col.c
+ 	source	modify	2	aegis/col.h
+ 	source	modify	2	aegis/commit.c
+ 	source	modify	2	aegis/commit.h
+ 	source	modify	2	aegis/common.def
+ 	source	modify	6	aegis/copyfile.c
+ 	source	modify	2	aegis/copyfile.h
+ 	source	modify	2	aegis/cstate.def
+ 	source	modify	3	aegis/develop1.c
+ 	source	modify	2	aegis/develop1.h
+ 	source	modify	6	aegis/develop2.c
+ 	source	modify	2	aegis/develop2.h
+ 	source	modify	6	aegis/diff.c
+ 	source	modify	2	aegis/diff.h
+ 	source	modify	2	aegis/dir.c
+ 	source	modify	2	aegis/dir.h
+ 	source	modify	2	aegis/file.c
+ 	source	modify	2	aegis/file.h
+ 	source	modify	5	aegis/gonzo.c
+ 	source	modify	3	aegis/gonzo.h
+ 	source	modify	2	aegis/gram.h
+ 	source	modify	2	aegis/gram.y
+ 	source	modify	2	aegis/gstate.def
+ 
+ 
+ 
+ Project "aegis.1.4", Change 18					  Page 2
+ Change Details					Tue Mar 30 23:57:40 1993
+ 
+ 	Type	Action	Edit	File Name
+ 	------- ------- ------- -----------
+ 	source	modify	2	aegis/help.c
+ 	source	modify	2	aegis/help.h
+ 	source	modify	3	aegis/integra1.c
+ 	source	modify	2	aegis/integra1.h
+ 	source	modify	10	aegis/integra2.c
+ 	source	modify	2	aegis/integra2.h
+ 	source	modify	2	aegis/io.c
+ 	source	modify	2	aegis/io.h
+ 	source	modify	2	aegis/lex.c
+ 	source	modify	2	aegis/lex.h
+ 	source	modify	5	aegis/list.c
+ 	source	modify	3	aegis/list.h
+ 	source	modify	3	aegis/lock.c
+ 	source	modify	3	aegis/lock.h
+ 	source	modify	2	aegis/log.c
+ 	source	modify	2	aegis/log.h
+ 	source	modify	3	aegis/main.c
+ 	source	modify	4	aegis/new_chan.c
+ 	source	modify	2	aegis/new_chan.h
+ 	source	modify	5	aegis/new_file.c
+ 	source	modify	2	aegis/new_file.h
+ 	source	modify	4	aegis/new_proj.c
+ 	source	modify	2	aegis/new_proj.h
+ 	source	modify	8	aegis/new_rele.c
+ 	source	modify	2	aegis/new_rele.h
+ 	source	modify	5	aegis/new_test.c
+ 	source	modify	2	aegis/new_test.h
+ 	source	modify	5	aegis/os.c
+ 	source	modify	3	aegis/os.h
+ 	source	modify	2	aegis/pager.c
+ 	source	modify	2	aegis/pager.h
+ 	source	modify	2	aegis/parse.c
+ 	source	modify	2	aegis/parse.h
+ 	source	modify	4	aegis/pattr.def
+ 	source	modify	3	aegis/pattr_ed.c
+ 	source	modify	2	aegis/pattr_ed.h
+ 	source	modify	3	aegis/pconf.def
+ 	source	modify	6	aegis/project.c
+ 	source	modify	5	aegis/project.h
+ 	source	modify	2	aegis/pstate.def
+ 	source	modify	5	aegis/rem_file.c
+ 	source	modify	2	aegis/rem_file.h
+ 	source	modify	3	aegis/rem_proj.c
+ 	source	modify	2	aegis/rem_proj.h
+ 	source	modify	4	aegis/review.c
+ 	source	modify	2	aegis/review.h
+ 	source	modify	3	aegis/reviewer.c
+ 	source	modify	2	aegis/reviewer.h
+ 	source	modify	5	aegis/sub.c
+ 	source	modify	3	aegis/sub.h
+ 	source	modify	4	aegis/test.c
+ 	source	modify	2	aegis/test.h
+ 	source	modify	2	aegis/type.c
+ 	source	modify	2	aegis/type.h
+ 	source	modify	3	aegis/uconf.def
+ 
+ 
+ 
+ Project "aegis.1.4", Change 18					  Page 3
+ Change Details					Tue Mar 30 23:57:40 1993
+ 
+ 	Type	Action	Edit	File Name
+ 	------- ------- ------- -----------
+ 	source	modify	2	aegis/undo.c
+ 	source	modify	2	aegis/undo.h
+ 	source	modify	5	aegis/user.c
+ 	source	modify	3	aegis/user.h
+ 	source	modify	2	aegis/ustate.def
+ 	source	modify	3	aegis/version.c
+ 	source	modify	2	aegis/version.h
+ 	source	modify	2	aux/ALPHA.man
+ 	source	modify	3	aux/BUILDING.man
+ 	source	modify	2	aux/CHANGES.sh
+ 	source	modify	5	aux/Howto.cook
+ 	source	modify	2	aux/MANIFEST.sh
+ 	source	modify	2	aux/Makefile.awk
+ 	source	modify	2	aux/Makefile.sh
+ 	source	modify	8	aux/README.man
+ 	source	modify	3	aux/patches.sh
+ 	source	modify	2	common/ansi.c
+ 	source	modify	3	common/arglex.c
+ 	source	modify	3	common/arglex.h
+ 	source	modify	2	common/error.c
+ 	source	modify	2	common/error.h
+ 	source	modify	2	common/indent.c
+ 	source	modify	2	common/indent.h
+ 	source	modify	2	common/main.h
+ 	source	modify	2	common/mem.c
+ 	source	modify	2	common/mem.h
+ 	source	modify	2	common/option.c
+ 	source	modify	2	common/option.h
+ 	source	modify	2	common/s-v-arg.h
+ 	source	modify	2	common/str.c
+ 	source	modify	2	common/str.h
+ 	source	modify	2	common/trace.c
+ 	source	modify	2	common/trace.h
+ 	source	modify	2	common/word.c
+ 	source	modify	2	common/word.h
+ 	source	modify	3	conf/ConvexOS-10
+ 	source	modify	3	conf/SunOS-4.1.1
+ 	source	modify	3	conf/SunOS-4.1.2
+ 	source	modify	3	conf/SunOS-4.1.3
+ 	source	modify	3	conf/SysV-4.0
+ 	source	modify	3	conf/ULTRIX-4.2
+ 	source	modify	3	conf/dgux-5.4.1
+ 	source	modify	5	config
+ 	source	modify	3	doc/aegis.ms
+ 	source	modify	2	doc/c1.0.so
+ 	source	modify	2	doc/c1.1.so
+ 	source	modify	2	doc/c1.2.so
+ 	source	modify	2	doc/c1.3.so
+ 	source	modify	2	doc/c1.4.so
+ 	source	modify	2	doc/c2.0.so
+ 	source	modify	2	doc/c2.1.so
+ 	source	modify	2	doc/c2.2.so
+ 	source	modify	2	doc/c2.3.so
+ 	source	modify	2	doc/c2.4.so
+ 	source	modify	3	doc/c3.0.so
+ 
+ 
+ 
+ Project "aegis.1.4", Change 18					  Page 4
+ Change Details					Tue Mar 30 23:57:40 1993
+ 
+ 	Type	Action	Edit	File Name
+ 	------- ------- ------- -----------
+ 	source	modify	3	doc/c3.1.so
+ 	source	modify	3	doc/c3.2.so
+ 	source	modify	3	doc/c3.3.so
+ 	source	modify	2	doc/c4.0.so
+ 	source	modify	2	doc/c4.1.so
+ 	source	modify	3	doc/c4.2.so
+ 	source	modify	2	doc/c4.3.so
+ 	source	modify	2	doc/c5.0.so
+ 	source	modify	2	doc/c6.0.so
+ 	source	modify	2	doc/c7.0.so
+ 	source	modify	2	doc/c7.1.so
+ 	source	modify	2	doc/c7.2.so
+ 	source	modify	4	doc/c7.4.so
+ 	source	modify	2	doc/c7.5.so
+ 	source	modify	2	doc/cA.0.so
+ 	source	modify	2	doc/cB.0.so
+ 	source	modify	2	doc/cC.0.so
+ 	source	modify	3	dot.cshrc
+ 	source	modify	3	dot.profile
+ 	source	modify	2	fmtgen/id.c
+ 	source	modify	2	fmtgen/id.h
+ 	source	modify	2	fmtgen/lex.c
+ 	source	modify	2	fmtgen/lex.h
+ 	source	modify	2	fmtgen/main.c
+ 	source	modify	2	fmtgen/parse.h
+ 	source	modify	2	fmtgen/parse.y
+ 	source	modify	2	fmtgen/type.c
+ 	source	modify	2	fmtgen/type.h
+ 	source	modify	2	fmtgen/type_enum.c
+ 	source	modify	2	fmtgen/type_integ.c
+ 	source	modify	2	fmtgen/type_list.c
+ 	source	modify	2	fmtgen/type_ref.c
+ 	source	modify	2	fmtgen/type_strin.c
+ 	source	modify	2	fmtgen/type_struc.c
+ 	source	modify	2	h/stdarg.h-min
+ 	source	modify	2	h/stddef.h
+ 	source	modify	2	h/stdlib.h
+ 	source	modify	3	man1/aeb.1
+ 	source	modify	2	man1/aeca.1
+ 	source	modify	2	man1/aecd.1
+ 	source	modify	3	man1/aecp.1
+ 	source	modify	3	man1/aecpu.1
+ 	source	modify	2	man1/aed.1
+ 	source	modify	3	man1/aedb.1
+ 	source	modify	2	man1/aedbu.1
+ 	source	modify	2	man1/aede.1
+ 	source	modify	2	man1/aedeu.1
+ 	source	modify	3	man1/aegis.1
+ 	source	modify	2	man1/aeib.1
+ 	source	modify	2	man1/aeibu.1
+ 	source	modify	2	man1/aeif.1
+ 	source	modify	3	man1/aeip.1
+ 	source	modify	3	man1/ael.1
+ 	source	modify	2	man1/aena.1
+ 	source	modify	2	man1/aenc.1
+ 
+ 
+ 
+ Project "aegis.1.4", Change 18					  Page 5
+ Change Details					Tue Mar 30 23:57:40 1993
+ 
+ 	Type	Action	Edit	File Name
+ 	------- ------- ------- -----------
+ 	source	modify	2	man1/aencu.1
+ 	source	modify	2	man1/aend.1
+ 	source	modify	2	man1/aenf.1
+ 	source	modify	2	man1/aenfu.1
+ 	source	modify	2	man1/aeni.1
+ 	source	modify	3	man1/aenpr.1
+ 	source	modify	3	man1/aenrls.1
+ 	source	modify	2	man1/aenrv.1
+ 	source	modify	2	man1/aent.1
+ 	source	modify	2	man1/aentu.1
+ 	source	modify	2	man1/aepa.1
+ 	source	modify	2	man1/aera.1
+ 	source	modify	2	man1/aerd.1
+ 	source	modify	2	man1/aerf.1
+ 	source	modify	2	man1/aeri.1
+ 	source	modify	2	man1/aerm.1
+ 	source	modify	3	man1/aermpr.1
+ 	source	modify	2	man1/aermu.1
+ 	source	modify	2	man1/aerp.1
+ 	source	modify	2	man1/aerpu.1
+ 	source	modify	2	man1/aerrv.1
+ 	source	modify	2	man1/aet.1
+ 	source	modify	2	man1/aev.1
+ 	source	modify	2	man1/install.sh
+ 	source	modify	2	man1/o__rules.so
+ 	source	modify	2	man1/o_anticip.so
+ 	source	modify	2	man1/o_auto.so
+ 	source	modify	2	man1/o_baselin.so
+ 	source	modify	2	man1/o_bld_lk.so
+ 	source	modify	3	man1/o_change.so
+ 	source	modify	2	man1/o_devdir.so
+ 	source	modify	3	man1/o_dir.so
+ 	source	modify	2	man1/o_help.so
+ 	source	modify	2	man1/o_indep.so
+ 	source	modify	3	man1/o_keep.so
+ 	source	modify	2	man1/o_lib.so
+ 	source	modify	2	man1/o_list.so
+ 	source	modify	2	man1/o_major.so
+ 	source	modify	2	man1/o_manual.so
+ 	source	modify	2	man1/o_min.so
+ 	source	modify	2	man1/o_minor.so
+ 	source	modify	2	man1/o_nolog.so
+ 	source	modify	2	man1/o_overw.so
+ 	source	modify	2	man1/o_page.so
+ 	source	modify	3	man1/o_project.so
+ 	source	modify	2	man1/o_terse.so
+ 	source	modify	2	man1/o_verbose.so
+ 	source	modify	3	man1/z_cr.so
+ 	source	modify	2	man1/z_exit.so
+ 	source	modify	2	man1/z_intuit.so
+ 	source	modify	2	man1/z_name.so
+ 	source	modify	3	man5/aecattr.5
+ 	source	modify	2	man5/aecattr.so
+ 	source	modify	3	man5/aecstate.5
+ 	source	modify	2	man5/aedir.5
+ 
+ 
+ 
+ Project "aegis.1.4", Change 18					  Page 6
+ Change Details					Tue Mar 30 23:57:40 1993
+ 
+ 	Type	Action	Edit	File Name
+ 	------- ------- ------- -----------
+ 	source	modify	2	man5/aegis.5
+ 	source	modify	2	man5/aegstate.5
+ 	source	modify	3	man5/aepattr.5
+ 	source	modify	2	man5/aepattr.so
+ 	source	modify	3	man5/aepconf.5
+ 	source	modify	3	man5/aepstate.5
+ 	source	modify	2	man5/aesub.5
+ 	source	modify	3	man5/aeuconf.5
+ 	source	modify	2	man5/aeustate.5
+ 	source	modify	2	man5/install.sh
+ 	source	modify	3	man5/z_cr.so
+ 	source	modify	2	man5/z_name.so
+ 	source	modify	2	notify/de.sh
+ 	source	modify	2	notify/deu.sh
+ 	source	modify	2	notify/if.sh
+ 	source	modify	2	notify/ip.sh
+ 	source	modify	2	notify/rf.sh
+ 	source	modify	2	notify/rp.sh
+ 	source	modify	2	notify/rpu.sh
+ 	test	modify	3	test/00/t0001a.sh
+ 	test	modify	4	test/00/t0002a.sh
+ 	test	modify	3	test/00/t0003a.sh
+ 	test	modify	4	test/00/t0004a.sh
+ 	test	modify	4	test/00/t0005a.sh
+ 	test	modify	4	test/00/t0006a.sh
+ 	test	modify	4	test/00/t0007a.sh
+ 	test	modify	4	test/00/t0008a.sh
+ 	test	modify	4	test/00/t0009a.sh
+ 	test	modify	4	test/00/t0010a.sh
+ 	test	modify	4	test/00/t0011a.sh
+ 	test	modify	3	test/00/t0012a.sh
+ 	test	modify	3	test/00/t0013a.sh
+ 	test	modify	3	test/00/t0014a.sh
+ 
+ HISTORY
+ 	What		When		Who	Comment
+ 	------		------		-----	---------
+ 	new_change	Wed Feb 17	pmiller Elapsed time: 0.857
+ 			23:21:55 1993		days.
+ 	develop_begin	Thu Feb 18	pmiller Elapsed time: 0.978
+ 			22:17:39 1993		days.
+ 	develop_end	Fri Feb 19	pmiller
+ 			22:07:52 1993
+ 	develop_end_	Fri Feb 19	pmiller Elapsed time: 0.157
+ 	undo		22:10:52 1993		days.
+ 	develop_end	Fri Feb 19	pmiller
+ 			23:21:41 1993
+ 	review_pass	Fri Feb 19	pmiller
+ 			23:21:53 1993
+ 	integrate_begin Fri Feb 19	pmiller Elapsed time: 0.682
+ 			23:23:27 1993		days.
+ 	integrate_pass	Sun Feb 21	pmiller
+ 			21:00:21 1993
+ 
+ 
+ 
+ Project "aegis.1.4", Change 19					  Page 1
+ Change Details					Tue Mar 30 23:57:41 1993
+ 
+ NAME
+ 	Project "aegis.1.4", Delta 21, Change 19.
+ 
+ SUMMARY
+ 	add substitutions to file templates
+ 
+ DESCRIPTION
+ 	Use substitutions to fill in more of file templates.  Things
+ 	like the file name and the date are now available.
+ 
+ 	This change is exempt from testing.  This change is exempt from
+ 	testing against the baseline.
+ 
+ CAUSE
+ 	This change was caused by external_bug.
+ 
+ FILES
+ 	Type	Action	Edit	File Name
+ 	------- ------- ------- -----------
+ 	source	modify	7	aegis/change.c
+ 	source	modify	7	aegis/new_file.c
+ 	source	modify	7	aegis/new_test.c
+ 	source	modify	6	aegis/sub.c
+ 	source	modify	3	aux/ALPHA.man
+ 	source	modify	3	common/ansi.c
+ 	source	modify	4	conf/ConvexOS-10
+ 	source	modify	4	conf/SunOS-4.1.1
+ 	source	modify	4	conf/SunOS-4.1.2
+ 	source	modify	4	conf/SunOS-4.1.3
+ 	source	modify	4	conf/SysV-4.0
+ 	source	modify	4	conf/ULTRIX-4.2
+ 	source	modify	4	conf/dgux-5.4.1
+ 	source	modify	6	config
+ 	source	modify	4	man5/aepconf.5
+ 	source	modify	3	man5/aesub.5
+ 
+ HISTORY
+ 	What		When		Who	Comment
+ 	------		------		-----	---------
+ 	new_change	Wed Feb 17	pmiller Elapsed time: 1.783
+ 			23:23:19 1993		days.
+ 	develop_begin	Mon Feb 22	pmiller Elapsed time: 0.547
+ 			14:15:28 1993		days.
+ 	develop_end	Tue Feb 23	pmiller
+ 			10:51:32 1993
+ 	review_pass	Tue Feb 23	pmiller
+ 			10:53:04 1993
+ 	integrate_begin Tue Feb 23	pmiller Elapsed time: 0.244
+ 			10:54:20 1993		days.
+ 	integrate_pass	Tue Feb 23	pmiller
+ 			12:44:13 1993
+ 
+ 
+ 
+ Project "aegis.1.4", Change 20					  Page 1
+ Change Details					Tue Mar 30 23:57:42 1993
+ 
+ NAME
+ 	Project "aegis.1.4", Delta 20, Change 20.
+ 
+ SUMMARY
+ 	add support for the GNU long option style
+ 
+ DESCRIPTION
+ 	The GNU people use --name for options which are more than one
+ 	letter long.  All of aegis' options are more than one letter
+ 	long, so this is kind-of unnecessray.	      Also map '--
+ 	foo=bar' into '-foo' 'bar' for another form of compatibility.
+ 
+ 	My thanks to Richard Stallman <rms@gnu.ai.mit.edu> for this
+ 	suggestion.
+ 
+ 	This change is exempt from testing against the baseline.
+ 
+ CAUSE
+ 	This change was caused by external_enhancement.
+ 
+ FILES
+ 	Type	Action	Edit	File Name
+ 	------- ------- ------- -----------
+ 	source	modify	4	aegis/administ.c
+ 	source	modify	8	aegis/build.c
+ 	source	modify	4	aegis/cattr_ed.c
+ 	source	modify	7	aegis/copyfile.c
+ 	source	modify	4	aegis/develop1.c
+ 	source	modify	7	aegis/develop2.c
+ 	source	modify	7	aegis/diff.c
+ 	source	modify	4	aegis/integra1.c
+ 	source	modify	11	aegis/integra2.c
+ 	source	modify	6	aegis/list.c
+ 	source	modify	4	aegis/main.c
+ 	source	modify	5	aegis/new_chan.c
+ 	source	modify	6	aegis/new_file.c
+ 	source	modify	5	aegis/new_proj.c
+ 	source	modify	9	aegis/new_rele.c
+ 	source	modify	6	aegis/new_test.c
+ 	source	modify	4	aegis/pattr_ed.c
+ 	source	modify	6	aegis/rem_file.c
+ 	source	modify	4	aegis/rem_proj.c
+ 	source	modify	5	aegis/review.c
+ 	source	modify	4	aegis/reviewer.c
+ 	source	modify	5	aegis/test.c
+ 	source	modify	4	aegis/version.c
+ 	source	modify	4	aux/BUILDING.man
+ 	source	modify	6	aux/Howto.cook
+ 	source	modify	3	aux/MANIFEST.sh
+ 	source	modify	4	aux/patches.sh
+ 	source	modify	4	common/arglex.c
+ 	source	modify	3	fmtgen/main.c
+ 	source	modify	3	man1/o__rules.so
+ 	test	modify	5	test/00/t0002a.sh
+ 
+ 
+ 
+ Project "aegis.1.4", Change 20					  Page 2
+ Change Details					Tue Mar 30 23:57:42 1993
+ 
+ HISTORY
+ 	What		When		Who	Comment
+ 	------		------		-----	---------
+ 	new_change	Sun Feb 21	pmiller
+ 			21:11:57 1993
+ 	develop_begin	Sun Feb 21	pmiller Elapsed time: 0.000
+ 			21:12:02 1993		days.
+ 	develop_end	Mon Feb 22	pmiller
+ 			13:32:22 1993
+ 	review_pass	Mon Feb 22	pmiller
+ 			13:32:33 1993
+ 	integrate_begin Mon Feb 22	pmiller Elapsed time: 0.083
+ 			13:33:35 1993		days.
+ 	integrate_pass	Mon Feb 22	pmiller
+ 			14:10:57 1993
+ 
+ 
+ 
+ Project "aegis.1.4", Change 21					  Page 1
+ Change Details					Tue Mar 30 23:57:43 1993
+ 
+ NAME
+ 	Project "aegis.1.4", Delta 22, Change 21.
+ 
+ SUMMARY
+ 	stop using _t suffix on type names
+ 
+ DESCRIPTION
+ 	The ANSI C and POSIX standards reserve the _t suffix on
+ 	identifiers, to indicate system specified types.
+ 
+ 	This change is exempt from testing.  This change is exempt from
+ 	testing against the baseline.
+ 
+ CAUSE
+ 	This change was caused by internal_bug.
+ 
+ FILES
+ 	Type	Action	Edit	File Name
+ 	------- ------- ------- -----------
+ 	source	modify	5	aegis/administ.c
+ 	source	modify	9	aegis/build.c
+ 	source	modify	5	aegis/cattr_ed.c
+ 	source	modify	8	aegis/change.c
+ 	source	modify	6	aegis/change.h
+ 	source	modify	6	aegis/chdir.c
+ 	source	modify	3	aegis/col.c
+ 	source	modify	3	aegis/commit.c
+ 	source	modify	3	aegis/commit.h
+ 	source	modify	8	aegis/copyfile.c
+ 	source	modify	5	aegis/develop1.c
+ 	source	modify	8	aegis/develop2.c
+ 	source	modify	8	aegis/diff.c
+ 	source	modify	3	aegis/dir.c
+ 	source	modify	3	aegis/dir.h
+ 	source	modify	3	aegis/file.c
+ 	source	modify	3	aegis/file.h
+ 	source	modify	6	aegis/gonzo.c
+ 	source	modify	4	aegis/gonzo.h
+ 	source	modify	3	aegis/gram.y
+ 	source	modify	5	aegis/integra1.c
+ 	source	modify	12	aegis/integra2.c
+ 	source	modify	3	aegis/io.c
+ 	source	modify	3	aegis/io.h
+ 	source	modify	7	aegis/list.c
+ 	source	modify	4	aegis/list.h
+ 	source	modify	4	aegis/lock.c
+ 	source	modify	4	aegis/lock.h
+ 	source	modify	3	aegis/log.c
+ 	source	modify	3	aegis/log.h
+ 	source	modify	5	aegis/main.c
+ 	source	modify	6	aegis/new_chan.c
+ 	source	modify	8	aegis/new_file.c
+ 	source	modify	6	aegis/new_proj.c
+ 	source	modify	10	aegis/new_rele.c
+ 	source	modify	8	aegis/new_test.c
+ 	source	modify	6	aegis/os.c
+ 	source	modify	4	aegis/os.h
+ 
+ 
+ 
+ Project "aegis.1.4", Change 21					  Page 2
+ Change Details					Tue Mar 30 23:57:43 1993
+ 
+ 	Type	Action	Edit	File Name
+ 	------- ------- ------- -----------
+ 	source	modify	3	aegis/parse.c
+ 	source	modify	3	aegis/parse.h
+ 	source	modify	5	aegis/pattr_ed.c
+ 	source	modify	7	aegis/project.c
+ 	source	modify	6	aegis/project.h
+ 	source	modify	7	aegis/rem_file.c
+ 	source	modify	5	aegis/rem_proj.c
+ 	source	modify	6	aegis/review.c
+ 	source	modify	5	aegis/reviewer.c
+ 	source	modify	7	aegis/sub.c
+ 	source	modify	4	aegis/sub.h
+ 	source	modify	6	aegis/test.c
+ 	source	modify	3	aegis/type.c
+ 	source	modify	3	aegis/type.h
+ 	source	modify	3	aegis/undo.c
+ 	source	modify	3	aegis/undo.h
+ 	source	modify	6	aegis/user.c
+ 	source	modify	4	aegis/user.h
+ 	source	modify	5	aegis/version.c
+ 	source	modify	5	common/arglex.c
+ 	source	modify	4	common/arglex.h
+ 	source	modify	3	common/error.c
+ 	source	modify	3	common/error.h
+ 	source	modify	3	common/str.c
+ 	source	modify	3	common/str.h
+ 	source	modify	3	common/trace.c
+ 	source	modify	3	common/word.c
+ 	source	modify	3	common/word.h
+ 	source	modify	3	fmtgen/id.c
+ 	source	modify	3	fmtgen/id.h
+ 	source	modify	3	fmtgen/lex.c
+ 	source	modify	3	fmtgen/lex.h
+ 	source	modify	4	fmtgen/main.c
+ 	source	modify	3	fmtgen/parse.y
+ 	source	modify	3	fmtgen/type.c
+ 	source	modify	3	fmtgen/type.h
+ 	source	modify	3	fmtgen/type_enum.c
+ 	source	modify	3	fmtgen/type_integ.c
+ 	source	modify	3	fmtgen/type_list.c
+ 	source	modify	3	fmtgen/type_ref.c
+ 	source	modify	3	fmtgen/type_strin.c
+ 	source	modify	3	fmtgen/type_struc.c
+ 
+ HISTORY
+ 	What		When		Who	Comment
+ 	------		------		-----	---------
+ 	new_change	Tue Feb 23	pmiller
+ 			10:51:17 1993
+ 	develop_begin	Tue Feb 23	pmiller Elapsed time: 0.000
+ 			10:55:03 1993		days.
+ 	develop_end	Tue Feb 23	pmiller
+ 			21:52:17 1993
+ 	review_pass	Tue Feb 23	pmiller
+ 			21:52:27 1993
+ 	integrate_begin Tue Feb 23	pmiller Elapsed time: 0.163
+ 
+ 
+ 
+ Project "aegis.1.4", Change 21					  Page 3
+ Change Details					Tue Mar 30 23:57:43 1993
+ 
+ 	What		When		Who	Comment
+ 	------		------		-----	---------
+ 			21:53:45 1993		days.
+ 	integrate_pass	Tue Feb 23	pmiller
+ 			23:06:59 1993
+ 
+ 
+ 
+ Project "aegis.1.4", Change 22					  Page 1
+ Change Details					Tue Mar 30 23:57:44 1993
+ 
+ NAME
+ 	Project "aegis.1.4", Delta 23, Change 22.
+ 
+ SUMMARY
+ 	and config details for AIX
+ 
+ DESCRIPTION
+ 	1. Add configuration details for AIX-3.2.
+ 	2. The support for AIX is very limited at this stage, because
+ 	it has the brain-dead POSIX seteuid sematics, so the set-uid-
+ 	root mode does not work
+ 
+ 	My thanks to John M. Sellens <jmsellen@watdragon.uwaterloo.ca>
+ 	and Andy Lowry <lowry@watson.ibm.com> for providing this
+ 	information.
+ 
+ 	This change is exempt from testing.  This change is exempt from
+ 	testing against the baseline.
+ 
+ CAUSE
+ 	This change was caused by external_enhancement.
+ 
+ FILES
+ 	Type	Action	Edit	File Name
+ 	------- ------- ------- -----------
+ 	source	modify	4	aegis/col.c
+ 	source	modify	7	aegis/user.c
+ 	source	modify	5	aux/BUILDING.man
+ 	source	modify	3	aux/Makefile.sh
+ 	source	modify	3	common/option.c
+ 	source	create	1	conf/AIX-3.2
+ 	source	modify	5	conf/ConvexOS-10
+ 	source	modify	5	conf/SunOS-4.1.1
+ 	source	modify	5	conf/SunOS-4.1.2
+ 	source	modify	5	conf/SunOS-4.1.3
+ 	source	modify	5	conf/SysV-4.0
+ 	source	modify	5	conf/ULTRIX-4.2
+ 	source	modify	5	conf/dgux-5.4.1
+ 
+ HISTORY
+ 	What		When		Who	Comment
+ 	------		------		-----	---------
+ 	new_change	Tue Feb 23	pmiller Elapsed time: 0.101
+ 			22:15:46 1993		days.
+ 	develop_begin	Tue Feb 23	pmiller Elapsed time: 0.000
+ 			23:01:03 1993		days.
+ 	develop_end	Wed Feb 24	pmiller
+ 			12:28:50 1993
+ 	review_pass	Wed Feb 24	pmiller
+ 			12:38:44 1993
+ 	integrate_begin Wed Feb 24	pmiller Elapsed time: 0.126
+ 			12:40:08 1993		days.
+ 	integrate_pass	Wed Feb 24	pmiller
+ 			13:36:57 1993
+ 
+ 
+ 
+ Project "aegis.1.4", Change 23					  Page 1
+ Change Details					Tue Mar 30 23:57:45 1993
+ 
+ NAME
+ 	Project "aegis.1.4", Delta 24, Change 23.
+ 
+ SUMMARY
+ 	add support for systems without seteuid
+ 
+ DESCRIPTION
+ 	While many modern UNIXes have seteuid, there are numerous older
+ 	flavours without it.  And there are some which have it, but
+ 	with unusable semantics.  This change adds conditional
+ 	functionality to use forks and setuid if an functional seteuid
+ 	is not available.
+ 
+ 	My thanks to Andy Lowry <lowry@watson.ibm.com> for
+ 	encouragement and discussion while designing and implemnting
+ 	this change.  This change was a very welcome one, if my inbox
+ 	is any indication.
+ 
+ 	This change is exempt from testing.  This change is exempt from
+ 	testing against the baseline.
+ 
+ CAUSE
+ 	This change was caused by external_enhancement.
+ 
+ FILES
+ 	Type	Action	Edit	File Name
+ 	------- ------- ------- -----------
+ 	source	modify	10	aegis/build.c
+ 	source	modify	9	aegis/change.c
+ 	source	modify	7	aegis/chdir.c
+ 	source	modify	5	aegis/col.c
+ 	source	modify	9	aegis/copyfile.c
+ 	source	modify	9	aegis/develop2.c
+ 	source	modify	4	aegis/file.c
+ 	source	create	1	aegis/glue.c
+ 	source	create	1	aegis/glue.h
+ 	source	create	1	aegis/indent.c
+ 	source	create	1	aegis/indent.h
+ 	source	modify	13	aegis/integra2.c
+ 	source	modify	3	aegis/lex.c
+ 	source	modify	5	aegis/lock.c
+ 	source	modify	4	aegis/log.c
+ 	source	modify	9	aegis/new_file.c
+ 	source	modify	9	aegis/new_test.c
+ 	source	modify	7	aegis/os.c
+ 	source	modify	5	aegis/os.h
+ 	source	modify	3	aegis/pager.c
+ 	source	modify	4	aux/ALPHA.man
+ 	source	modify	6	aux/BUILDING.man
+ 	source	modify	9	aux/README.man
+ 	source	modify	4	common/error.c
+ 	source	modify	4	common/error.h
+ 	source	remove	2	common/indent.c
+ 	source	remove	2	common/indent.h
+ 	source	modify	4	common/trace.c
+ 	source	modify	3	common/trace.h
+ 	source	modify	2	conf/AIX-3.2
+ 
+ 
+ 
+ Project "aegis.1.4", Change 23					  Page 2
+ Change Details					Tue Mar 30 23:57:45 1993
+ 
+ 	Type	Action	Edit	File Name
+ 	------- ------- ------- -----------
+ 	source	modify	6	conf/ConvexOS-10
+ 	source	modify	6	conf/SunOS-4.1.1
+ 	source	modify	6	conf/SunOS-4.1.2
+ 	source	modify	6	conf/SunOS-4.1.3
+ 	source	modify	6	conf/SysV-4.0
+ 	source	modify	6	conf/ULTRIX-4.2
+ 	source	modify	6	conf/dgux-5.4.1
+ 	source	create	1	fmtgen/indent.c
+ 	source	create	1	fmtgen/indent.h
+ 
+ HISTORY
+ 	What		When		Who	Comment
+ 	------		------		-----	---------
+ 	new_change	Wed Feb 24	pmiller
+ 			12:41:43 1993
+ 	develop_begin	Wed Feb 24	pmiller Elapsed time: 5.502
+ 			12:42:02 1993		days.
+ 	develop_end	Wed Mar	 3	pmiller
+ 			16:27:46 1993
+ 	review_pass	Wed Mar	 3	pmiller
+ 			16:27:55 1993
+ 	integrate_begin Wed Mar	 3	pmiller Elapsed time: 0.818
+ 			16:29:26 1993		days.
+ 	integrate_pass	Wed Mar	 3	pmiller
+ 			22:37:31 1993
+ 
+ 
+ 
+ Project "aegis.1.4", Change 24					  Page 1
+ Change Details					Tue Mar 30 23:57:46 1993
+ 
+ NAME
+ 	Project "aegis.1.4", Delta 25, Change 24.
+ 
+ SUMMARY
+ 	allow nomination of temp test dir
+ 
+ DESCRIPTION
+ 	Some people have found aegis difficult to test because they are
+ 	using the tmpfs as their /tmp, but this does not provide
+ 	locking, and so the tests fail.
+ 
+ 	This is solved by changing the tests to use the AEGIS_TMP
+ 	environment variable, if set.
+ 
+ 	A curious SunOS bug is also avoided.  SunOS seems to be
+ 	forgetting to release some locks when processes are killed,
+ 	notabley shared locks.	This prevented integrate pass from
+ 	completing, in some cases.
+ 
+ 	This change is exempt from testing against the baseline.
+ 
+ CAUSE
+ 	This change was caused by external_enhancement.
+ 
+ FILES
+ 	Type	Action	Edit	File Name
+ 	------- ------- ------- -----------
+ 	source	modify	7	aegis/gonzo.c
+ 	source	modify	6	aegis/lock.c
+ 	source	modify	5	aux/ALPHA.man
+ 	source	modify	7	aux/BUILDING.man
+ 	source	modify	7	aux/Howto.cook
+ 	source	modify	10	aux/README.man
+ 	source	modify	7	config
+ 	source	create	1	h/unistd.h
+ 	test	modify	4	test/00/t0001a.sh
+ 	test	modify	6	test/00/t0002a.sh
+ 	test	modify	4	test/00/t0003a.sh
+ 	test	modify	5	test/00/t0004a.sh
+ 	test	modify	5	test/00/t0005a.sh
+ 	test	modify	5	test/00/t0006a.sh
+ 	test	modify	5	test/00/t0007a.sh
+ 	test	modify	5	test/00/t0008a.sh
+ 	test	modify	5	test/00/t0009a.sh
+ 	test	modify	5	test/00/t0010a.sh
+ 	test	modify	5	test/00/t0011a.sh
+ 	test	modify	4	test/00/t0012a.sh
+ 	test	modify	4	test/00/t0013a.sh
+ 	test	modify	4	test/00/t0014a.sh
+ 
+ HISTORY
+ 	What		When		Who	Comment
+ 	------		------		-----	---------
+ 	new_change	Wed Mar	 3	pmiller
+ 			22:44:06 1993
+ 	develop_begin	Wed Mar	 3	pmiller Elapsed time: 0.000
+ 			22:44:28 1993		days.
+ 
+ 
+ 
+ Project "aegis.1.4", Change 24					  Page 2
+ Change Details					Tue Mar 30 23:57:46 1993
+ 
+ 	What		When		Who	Comment
+ 	------		------		-----	---------
+ 	develop_end	Thu Mar	 4	pmiller
+ 			13:20:55 1993
+ 	review_pass	Thu Mar	 4	pmiller
+ 			13:25:06 1993
+ 	integrate_begin Thu Mar	 4	pmiller Elapsed time: 0.284
+ 			13:26:04 1993		days.
+ 	integrate_pass	Thu Mar	 4	pmiller
+ 			15:33:48 1993
+ 
+ 
+ 
+ Project "aegis.1.4", Change 25					  Page 1
+ Change Details					Tue Mar 30 23:57:46 1993
+ 
+ NAME
+ 	Project "aegis.1.4", Delta 26, Change 25.
+ 
+ SUMMARY
+ 	rationalize lib entries
+ 
+ DESCRIPTION
+ 	Place all of the items to be installed into the system lib
+ 	directory in a single source directory
+ 
+ 	Also fixed a nasty catch-22 in the error handling.  Was caused
+ 	by the recent locking bug fix.
+ 
+ 	This change is exempt from testing.  This change is exempt from
+ 	testing against the baseline.
+ 
+ CAUSE
+ 	This change was caused by internal_enhancement.
+ 
+ FILES
+ 	Type	Action	Edit	File Name
+ 	------- ------- ------- -----------
+ 	source	modify	2	aegis/glue.c
+ 	source	modify	7	aegis/lock.c
+ 	source	modify	10	aegis/new_file.c
+ 	source	modify	10	aegis/new_test.c
+ 	source	modify	8	aux/BUILDING.man
+ 	source	modify	5	common/error.c
+ 	source	modify	3	doc/c6.0.so
+ 	source	remove	3	dot.cshrc
+ 	source	remove	3	dot.profile
+ 	source	create	1	lib/cshrc
+ 	source	create	1	lib/de.inews.sh
+ 	source	create	1	lib/de.sh
+ 	source	create	1	lib/deu.inews.sh
+ 	source	create	1	lib/deu.sh
+ 	source	create	1	lib/if.inews.sh
+ 	source	create	1	lib/if.sh
+ 	source	create	1	lib/ip.inews.sh
+ 	source	create	1	lib/ip.sh
+ 	source	create	1	lib/profile
+ 	source	create	1	lib/rf.inews.sh
+ 	source	create	1	lib/rf.sh
+ 	source	create	1	lib/rp.inews.sh
+ 	source	create	1	lib/rp.sh
+ 	source	create	1	lib/rpu.inews.sh
+ 	source	create	1	lib/rpu.sh
+ 	source	remove	2	notify/de.sh
+ 	source	remove	2	notify/deu.sh
+ 	source	remove	2	notify/if.sh
+ 	source	remove	2	notify/ip.sh
+ 	source	remove	2	notify/rf.sh
+ 	source	remove	2	notify/rp.sh
+ 	source	remove	2	notify/rpu.sh
+ 
+ 
+ 
+ Project "aegis.1.4", Change 25					  Page 2
+ Change Details					Tue Mar 30 23:57:46 1993
+ 
+ HISTORY
+ 	What		When		Who	Comment
+ 	------		------		-----	---------
+ 	new_change	Thu Mar	 4	pmiller
+ 			15:37:40 1993
+ 	develop_begin	Thu Mar	 4	pmiller Elapsed time: 0.742
+ 			15:37:50 1993		days.
+ 	develop_end	Fri Mar	 5	pmiller
+ 			13:41:47 1993
+ 	review_pass	Fri Mar	 5	pmiller
+ 			13:42:11 1993
+ 	integrate_begin Fri Mar	 5	pmiller Elapsed time: 0.277
+ 			13:42:50 1993		days.
+ 	integrate_pass	Fri Mar	 5	pmiller
+ 			15:47:34 1993
+ 
+ 
+ 
+ Project "aegis.1.4", Change 26					  Page 1
+ Change Details					Tue Mar 30 23:57:47 1993
+ 
+ NAME
+ 	Project "aegis.1.4", Delta 27, Change 26.
+ 
+ SUMMARY
+ 	fix problems with ULTRIX
+ 
+ DESCRIPTION
+ 	Ultrix needs to use the /bin/sh5 shell, rather than the /bin/sh
+ 	shell.	Make the necessary changes to modify the shell as
+ 	required.
+ 
+ 	This change is exempt from testing.  This change is exempt from
+ 	testing against the baseline.
+ 
+ CAUSE
+ 	This change was caused by external_bug.
+ 
+ FILES
+ 	Type	Action	Edit	File Name
+ 	------- ------- ------- -----------
+ 	source	modify	8	aegis/os.c
+ 	source	modify	6	aegis/os.h
+ 	source	modify	7	aegis/test.c
+ 	source	modify	8	aegis/user.c
+ 	source	modify	9	aux/BUILDING.man
+ 	source	modify	3	conf/AIX-3.2
+ 	source	modify	7	conf/ConvexOS-10
+ 	source	modify	7	conf/SunOS-4.1.1
+ 	source	modify	7	conf/SunOS-4.1.2
+ 	source	modify	7	conf/SunOS-4.1.3
+ 	source	modify	7	conf/SysV-4.0
+ 	source	modify	7	conf/ULTRIX-4.2
+ 	source	modify	7	conf/dgux-5.4.1
+ 	source	modify	3	man1/aet.1
+ 
+ HISTORY
+ 	What		When		Who	Comment
+ 	------		------		-----	---------
+ 	new_change	Fri Mar	 5	pmiller
+ 			16:16:31 1993
+ 	develop_begin	Fri Mar	 5	pmiller Elapsed time: 0.079
+ 			16:16:39 1993		days.
+ 	develop_end	Fri Mar	 5	pmiller
+ 			16:52:06 1993
+ 	review_pass	Fri Mar	 5	pmiller
+ 			16:52:17 1993
+ 	integrate_begin Fri Mar	 5	pmiller Elapsed time: 1.666
+ 			16:53:17 1993		days.
+ 	integrate_pass	Sat Mar	 6	pmiller
+ 			21:52:50 1993
+ 
+ 
+ 
+ Project "aegis.1.4", Change 27					  Page 1
+ Change Details					Tue Mar 30 23:57:48 1993
+ 
+ NAME
+ 	Project "aegis.1.4", Delta 28, Change 27.
+ 
+ SUMMARY
+ 	fix a bug in the no-seteuid flavour
+ 
+ DESCRIPTION
+ 	the pager code needs to remember what it is talking to.
+ 
+ 	My thanks to Andy Lowry <lowry@watson.ibm.com> for raising this
+ 	problem.
+ 
+ 	This change is exempt from testing.  This change is exempt from
+ 	testing against the baseline.
+ 
+ CAUSE
+ 	This change was caused by external_bug.
+ 
+ FILES
+ 	Type	Action	Edit	File Name
+ 	------- ------- ------- -----------
+ 	source	modify	6	aegis/col.c
+ 	source	modify	3	aegis/glue.c
+ 	source	modify	9	aegis/user.c
+ 
+ HISTORY
+ 	What		When		Who	Comment
+ 	------		------		-----	---------
+ 	new_change	Sat Mar	 6	pmiller
+ 			21:55:48 1993
+ 	develop_begin	Sat Mar	 6	pmiller Elapsed time: 1.065
+ 			21:55:56 1993		days.
+ 	develop_end	Sun Mar	 7	pmiller
+ 			21:25:14 1993
+ 	review_pass	Sun Mar	 7	pmiller
+ 			21:25:51 1993
+ 	integrate_begin Sun Mar	 7	pmiller Elapsed time: 0.053
+ 			21:27:01 1993		days.
+ 	integrate_pass	Sun Mar	 7	pmiller
+ 			21:50:46 1993
+ 
+ 
+ 
+ Project "aegis.1.4", Change 28					  Page 1
+ Change Details					Tue Mar 30 23:57:48 1993
+ 
+ NAME
+ 	Project "aegis.1.4", Delta 30, Change 28.
+ 
+ SUMMARY
+ 	more documentation
+ 
+ DESCRIPTION
+ 	1. polish the integrator section of chapter 3.
+ 	2. add a chapter about the difference tools.
+ 
+ 	This change is exempt from testing.  This change is exempt from
+ 	testing against the baseline.
+ 
+ CAUSE
+ 	This change was caused by internal_enhancement.
+ 
+ FILES
+ 	Type	Action	Edit	File Name
+ 	------- ------- ------- -----------
+ 	source	modify	10	aux/BUILDING.man
+ 	source	modify	5	doc/aegis.ms
+ 	source	modify	3	doc/c1.4.so
+ 	source	modify	4	doc/c2.3.so
+ 	source	modify	3	doc/c5.0.so
+ 	source	modify	3	doc/c7.1.so
+ 	source	create	1	doc/c8.0.so
+ 	source	create	1	doc/c8.1.so
+ 	source	create	1	doc/c8.2.so
+ 	source	create	1	doc/c8.3.so
+ 	source	modify	3	doc/cB.0.so
+ 
+ HISTORY
+ 	What		When		Who	Comment
+ 	------		------		-----	---------
+ 	new_change	Mon Mar	 8	pmiller
+ 			22:23:59 1993
+ 	develop_begin	Mon Mar	 8	pmiller Elapsed time: 0.000
+ 			22:24:07 1993		days.
+ 	develop_end	Tue Mar	 9	pmiller
+ 			14:37:27 1993
+ 	review_pass	Tue Mar	 9	pmiller
+ 			14:38:00 1993
+ 	integrate_begin Tue Mar	 9	pmiller Elapsed time: 0.909
+ 			14:39:02 1993		days.
+ 	integrate_pass	Tue Mar	 9	pmiller
+ 			21:27:59 1993
+ 
+ 
+ 
+ Project "aegis.1.4", Change 29					  Page 1
+ Change Details					Tue Mar 30 23:57:49 1993
+ 
+ NAME
+ 	Project "aegis.1.4", Delta 31, Change 29.
+ 
+ SUMMARY
+ 	pyramid port
+ 
+ DESCRIPTION
+ 	A number of things needed to be done to make aegis work on the
+ 	pyramid.
+ 	1. read the BUILD.PY file for what needs to be done.  Changed
+ 	BUILDING to reference it.
+ 	2. fix a number of minor things in the code to make it compile.
+ 
+ 	This change is exempt from testing against the baseline.
+ 
+ CAUSE
+ 	This change was caused by internal_enhancement.
+ 
+ FILES
+ 	Type	Action	Edit	File Name
+ 	------- ------- ------- -----------
+ 	source	modify	4	aegis/dir.c
+ 	source	modify	4	aegis/glue.c
+ 	source	modify	2	aegis/glue.h
+ 	source	modify	8	aegis/lock.c
+ 	source	modify	11	aegis/new_rele.c
+ 	source	modify	8	aegis/sub.c
+ 	source	modify	10	aegis/user.c
+ 	source	create	1	aux/BUILD.PY.man
+ 	source	modify	11	aux/BUILDING.man
+ 	source	modify	9	aux/Howto.cook
+ 	source	modify	4	aux/Makefile.sh
+ 	source	modify	6	common/error.c
+ 	source	modify	4	conf/AIX-3.2
+ 	source	modify	8	conf/ConvexOS-10
+ 	source	modify	8	conf/SunOS-4.1.1
+ 	source	modify	8	conf/SunOS-4.1.2
+ 	source	modify	8	conf/SunOS-4.1.3
+ 	source	modify	8	conf/SysV-4.0
+ 	source	modify	8	conf/ULTRIX-4.2
+ 	source	create	1	conf/apollo
+ 	source	create	1	conf/dcosx
+ 	source	modify	8	conf/dgux-5.4.1
+ 	source	modify	4	fmtgen/type_list.c
+ 	source	modify	4	fmtgen/type_struc.c
+ 	source	create	1	h/dirent.h
+ 	source	create	1	h/utime.h
+ 	test	modify	6	test/00/t0007a.sh
+ 	test	modify	5	test/00/t0012a.sh
+ 	test	modify	5	test/00/t0013a.sh
+ 	test	modify	5	test/00/t0014a.sh
+ 
+ HISTORY
+ 	What		When		Who	Comment
+ 	------		------		-----	---------
+ 	new_change	Wed Mar 10	pmiller
+ 			12:25:51 1993
+ 
+ 
+ 
+ Project "aegis.1.4", Change 29					  Page 2
+ Change Details					Tue Mar 30 23:57:49 1993
+ 
+ 	What		When		Who	Comment
+ 	------		------		-----	---------
+ 	develop_begin	Wed Mar 10	pmiller Elapsed time: 0.183
+ 			12:26:02 1993		days.
+ 	develop_end	Thu Mar 11	pmiller
+ 			22:48:29 1993
+ 	review_pass	Thu Mar 11	pmiller
+ 			22:49:17 1993
+ 	integrate_begin Thu Mar 11	pmiller Elapsed time: 0.111
+ 			22:52:09 1993		days.
+ 	integrate_pass	Thu Mar 11	pmiller
+ 			23:41:59 1993
+ 
+ 
+ 
+ Project "aegis.1.4", Change 30					  Page 1
+ Change Details					Tue Mar 30 23:57:50 1993
+ 
+ NAME
+ 	Project "aegis.1.4", Delta 32, Change 30.
+ 
+ SUMMARY
+ 	improve pyramid port
+ 
+ DESCRIPTION
+ 	improve pyramid port
+ 
+ 	This change is exempt from testing against the baseline.
+ 
+ CAUSE
+ 	This change was caused by internal_bug.
+ 
+ FILES
+ 	Type	Action	Edit	File Name
+ 	------- ------- ------- -----------
+ 	source	modify	6	aegis/cattr_ed.c
+ 	source	modify	10	aegis/change.c
+ 	source	modify	8	aegis/gonzo.c
+ 	source	modify	6	aegis/pattr_ed.c
+ 	source	modify	8	aegis/project.c
+ 	source	modify	11	aegis/user.c
+ 	source	remove	1	aux/BUILD.PY.man
+ 	source	modify	12	aux/BUILDING.man
+ 	source	create	1	aux/BUILDpyr.man
+ 	source	modify	10	aux/Howto.cook
+ 	source	modify	5	aux/Makefile.sh
+ 	source	modify	2	conf/dcosx
+ 	source	modify	4	doc/c2.1.so
+ 	source	modify	4	fmtgen/parse.y
+ 	source	modify	5	fmtgen/type_struc.c
+ 	test	modify	7	test/00/t0007a.sh
+ 
+ HISTORY
+ 	What		When		Who	Comment
+ 	------		------		-----	---------
+ 	new_change	Sat Mar 13	pmiller
+ 			22:54:35 1993
+ 	develop_begin	Sat Mar 13	pmiller Elapsed time: 2.795
+ 			22:54:41 1993		days.
+ 	develop_end	Wed Mar 17	pmiller
+ 			21:22:26 1993
+ 	review_pass	Wed Mar 17	pmiller
+ 			21:22:36 1993
+ 	integrate_begin Wed Mar 17	pmiller Elapsed time: 1.129
+ 			21:23:33 1993		days.
+ 	integrate_pass	Thu Mar 18	pmiller
+ 			22:21:35 1993
+ 
+ 
+ 
+ Project "aegis.1.4", Change 31					  Page 1
+ Change Details					Tue Mar 30 23:57:51 1993
+ 
+ NAME
+ 	Project "aegis.1.4", Delta 33, Change 31.
+ 
+ SUMMARY
+ 	there was a permissions bug in aeibu
+ 
+ DESCRIPTION
+ 	there was a permissions bug in aeibu
+ 
+ CAUSE
+ 	This change was caused by internal_bug.
+ 
+ FILES
+ 	Type	Action	Edit	File Name
+ 	------- ------- ------- -----------
+ 	source	modify	14	aegis/integra2.c
+ 	source	modify	6	aux/ALPHA.man
+ 	source	modify	13	aux/BUILDING.man
+ 	source	modify	12	aux/README.man
+ 	source	modify	9	config
+ 	test	create	1	test/00/t0015a.sh
+ 
+ HISTORY
+ 	What		When		Who	Comment
+ 	------		------		-----	---------
+ 	new_change	Thu Mar 18	pmiller
+ 			22:25:31 1993
+ 	develop_begin	Thu Mar 18	pmiller Elapsed time: 1.077
+ 			22:25:39 1993		days.
+ 	develop_end	Fri Mar 19	pmiller
+ 			23:00:23 1993
+ 	review_pass	Fri Mar 19	pmiller
+ 			23:00:34 1993
+ 	integrate_begin Fri Mar 19	pmiller Elapsed time: 0.094
+ 			23:02:14 1993		days.
+ 	integrate_pass	Fri Mar 19	pmiller
+ 			23:44:22 1993
+ 
+ 
+ 
+ Project "aegis.1.4", Change 32					  Page 1
+ Change Details					Tue Mar 30 23:57:51 1993
+ 
+ NAME
+ 	Project "aegis.1.4", Delta 34, Change 32.
+ 
+ SUMMARY
+ 	fix problems found in final testing
+ 
+ DESCRIPTION
+ 	fix problems found in final testing
+ 
+ 	This change is exempt from testing.  This change is exempt from
+ 	testing against the baseline.
+ 
+ CAUSE
+ 	This change was caused by internal_bug.
+ 
+ FILES
+ 	Type	Action	Edit	File Name
+ 	------- ------- ------- -----------
+ 	source	modify	5	aegis/glue.c
+ 	source	modify	9	aegis/gonzo.c
+ 	source	modify	14	aux/BUILDING.man
+ 	source	modify	6	aux/Makefile.sh
+ 	source	modify	9	conf/ConvexOS-10
+ 
+ HISTORY
+ 	What		When		Who	Comment
+ 	------		------		-----	---------
+ 	new_change	Sat Mar 20	pmiller
+ 			09:20:45 1993
+ 	develop_begin	Sat Mar 20	pmiller Elapsed time: 0.869
+ 			09:20:51 1993		days.
+ 	develop_end	Sun Mar 21	pmiller
+ 			08:22:03 1993
+ 	review_pass	Sun Mar 21	pmiller
+ 			08:22:15 1993
+ 	integrate_begin Sun Mar 21	pmiller Elapsed time: 0.063
+ 			08:23:27 1993		days.
+ 	integrate_pass	Sun Mar 21	pmiller
+ 			08:51:41 1993
+ 
+ 
+ 
+ Project "aegis.1.4", Change 33					  Page 1
+ Change Details					Tue Mar 30 23:57:52 1993
+ 
+ NAME
+ 	Project "aegis.1.4", Delta 35, Change 33.
+ 
+ SUMMARY
+ 	fix bugs in aecp and  column output
+ 
+ DESCRIPTION
+ 	1. aecp -delta N failed to remember the correct edit number in
+ 	the change, thus not performing a merge
+ 	2. column headings came out in the wrong place when columns
+ 	wrapped over page boundaries.
+ 
+ 	This change is exempt from testing.  This change is exempt from
+ 	testing against the baseline.
+ 
+ CAUSE
+ 	This change was caused by internal_bug.
+ 
+ FILES
+ 	Type	Action	Edit	File Name
+ 	------- ------- ------- -----------
+ 	source	modify	7	aegis/col.c
+ 	source	modify	10	aegis/copyfile.c
+ 
+ HISTORY
+ 	What		When		Who	Comment
+ 	------		------		-----	---------
+ 	new_change	Sun Mar 21	pmiller
+ 			08:52:55 1993
+ 	develop_begin	Sun Mar 21	pmiller Elapsed time: 1.483
+ 			08:53:02 1993		days.
+ 	develop_end	Mon Mar 22	pmiller
+ 			12:30:10 1993
+ 	review_pass	Mon Mar 22	pmiller
+ 			12:31:10 1993
+ 	integrate_begin Mon Mar 22	pmiller Elapsed time: 0.321
+ 			12:32:17 1993		days.
+ 	integrate_pass	Mon Mar 22	pmiller
+ 			14:56:51 1993
+ 
+ 
+ 
+ Project "aegis.1.4", Change 34					  Page 1
+ Change Details					Tue Mar 30 23:57:53 1993
+ 
+ NAME
+ 	Project "aegis.1.4", Delta 36, Change 34.
+ 
+ SUMMARY
+ 	note hpux as a known port
+ 
+ DESCRIPTION
+ 	1. A user managed to get aegis compiled and tested under HP/UX,
+ 	but was unable to verify set-uid-root functionality.  My thanks
+ 	to Chris Adeniyi-Jones <a909947@tiuk.ti.com> for providing this
+ 	information.
+ 	2. Mention the mailing list in the README file.
+ 	3. correct the author's sig
+ 	4. add an install target to te Makefile as requires by c.s.unix
+ 	stds.
+ 
+ 	This change is exempt from testing.  This change is exempt from
+ 	testing against the baseline.
+ 
+ CAUSE
+ 	This change was caused by internal_enhancement.
+ 
+ FILES
+ 	Type	Action	Edit	File Name
+ 	------- ------- ------- -----------
+ 	source	modify	4	aegis/help.c
+ 	source	modify	7	aux/ALPHA.man
+ 	source	modify	15	aux/BUILDING.man
+ 	source	modify	2	aux/BUILDpyr.man
+ 	source	modify	7	aux/Makefile.sh
+ 	source	modify	13	aux/README.man
+ 	source	modify	4	common/ansi.c
+ 	source	create	1	conf/hpux-8.07
+ 	source	modify	5	fmtgen/main.c
+ 	source	modify	5	man1/z_cr.so
+ 	source	modify	5	man5/z_cr.so
+ 
+ HISTORY
+ 	What		When		Who	Comment
+ 	------		------		-----	---------
+ 	new_change	Sun Mar 28	pmiller
+ 			21:25:11 1993
+ 	develop_begin	Sun Mar 28	pmiller Elapsed time: 0.000
+ 			21:26:08 1993		days.
+ 	develop_end	Mon Mar 29	pmiller
+ 			13:23:41 1993
+ 	review_pass	Mon Mar 29	pmiller
+ 			13:23:52 1993
+ 	integrate_begin Mon Mar 29	pmiller Elapsed time: 0.156
+ 			13:25:02 1993		days.
+ 	integrate_pass	Mon Mar 29	pmiller
+ 			14:35:15 1993
+ 
+ 
+ 
+ Project "aegis.1.4", Change 35					  Page 1
+ Change Details					Tue Mar 30 23:57:54 1993
+ 
+ NAME
+ 	Project "aegis.1.4", Delta 37, Change 35.
+ 
+ SUMMARY
+ 	New_Project does not check uid
+ 
+ DESCRIPTION
+ 	1. The uid limits were not checked when a project was created.
+ 	Users were creating projects as root, and then getting
+ 	"permission denied" errors from the NFS semantics.  My thanks
+ 	to John Thorp <jathorp@gchq.demon.co.uk> for raising this
+ 	problem.
+ 
+ 	2. Add the SCO config.	My thanks to David Robison
+ 	<david@hccwmv2> for the config info.
+ 
+ 	This change is exempt from testing.  This change is exempt from
+ 	testing against the baseline.
+ 
+ CAUSE
+ 	This change was caused by internal_enhancement.
+ 
+ FILES
+ 	Type	Action	Edit	File Name
+ 	------- ------- ------- -----------
+ 	source	modify	7	aegis/new_proj.c
+ 	source	modify	16	aux/BUILDING.man
+ 	source	modify	8	aux/Makefile.sh
+ 	source	create	1	conf/SCO-2.4
+ 
+ HISTORY
+ 	What		When		Who	Comment
+ 	------		------		-----	---------
+ 	new_change	Mon Mar 29	pmiller
+ 			15:25:20 1993
+ 	develop_begin	Mon Mar 29	pmiller Elapsed time: 0.128
+ 			15:25:26 1993		days.
+ 	develop_end	Mon Mar 29	pmiller
+ 			16:23:10 1993
+ 	review_pass	Mon Mar 29	pmiller
+ 			16:24:05 1993
+ 	integrate_begin Mon Mar 29	pmiller Elapsed time: 1.840
+ 			16:25:31 1993		days.
+ 	integrate_pass	Tue Mar 30	pmiller
+ 			22:43:22 1993
+ 
+ 
+ 
+ Project "aegis.1.4", Change 36					  Page 1
+ Change Details					Tue Mar 30 23:57:55 1993
+ 
+ NAME
+ 	Project "aegis.1.4", Delta 38, Change 36.
+ 
+ SUMMARY
+ 	fix minor problem with generated Makefile
+ 
+ DESCRIPTION
+ 	fix minor problem with generated Makefile
+ 
+ 	This change is exempt from testing.  This change is exempt from
+ 	testing against the baseline.
+ 
+ CAUSE
+ 	This change was caused by internal_enhancement.
+ 
+ STATE
+ 	This change is in 'being_integrated' state.
+ 
+ FILES
+ 	Type	Action	Edit	File Name
+ 	------- ------- ------- -----------
+ 	source	modify	8	aux/Makefile.sh
+ 	source	modify	4	doc/c2.1.so
+ 	source	modify	3	doc/c2.2.so
+ 	source	modify	4	doc/c2.3.so
+ 
+ HISTORY
+ 	What		When		Who	Comment
+ 	------		------		-----	---------
+ 	new_change	Tue Mar 30	pmiller
+ 			22:50:44 1993
+ 	develop_begin	Tue Mar 30	pmiller Elapsed time: 0.137
+ 			22:50:50 1993		days.
+ 	develop_end	Tue Mar 30	pmiller
+ 			23:52:28 1993
+ 	review_pass	Tue Mar 30	pmiller
+ 			23:52:38 1993
+ 	integrate_begin Tue Mar 30	pmiller
+ 			23:53:48 1993
Index: MANIFEST
***************
*** 0 ****
--- 1,326 ----
+ 
+ 
+ README	Blurb about aegis
+ ALPHA	Warning that aegis is only ALPHA software
+ BUILDING	Instructions how to build, test and install aegis
+ BUILDpyr	
+ CHANGES	Change history of this release of aegis
+ LICENSE	GNU General Public License
+ MANIFEST	This file
+ Makefile	Instructions to make(1) how to build and test aegis
+ aegis/administ.c	 functions to add and remove administrators
+ aegis/administ.h	 interface definition for aegis/administ.c
+ aegis/arglex2.h	 definitions of command line tokens
+ aegis/build.c	 functions to perform development and integration builds
+ aegis/build.h	 interface definition for aegis/build.c
+ aegis/cattr.def	 change state file contents definition
+ aegis/cattr_ed.c	 functions to list and modify change attributes
+ aegis/cattr_ed.h	 interface definition for aegis/cattr_ed.c
+ aegis/change.c	 functions to manipulate change state data
+ aegis/change.h	 interface definition for aegis/change.c
+ aegis/chdir.c	 functions to change directory or determine paths
+ aegis/chdir.h	 interface definition for aegis/chdir.c
+ aegis/col.c	 functions for columnized output
+ aegis/col.h	 interface definition for aegis/col.c
+ aegis/commit.c	 functions to store and enact file manipulations for commit
+ aegis/commit.h	 interface definition for aegis/commit.c
+ aegis/common.def	 enumerations common to many aegis file contents
+ aegis/copyfile.c	 copy files into a change, and undo
+ aegis/copyfile.h	 interface definition for aegis/copyfile.c
+ aegis/cstate.def	 change state file contents definition
+ aegis/develop1.c	 functions to add and remove developers
+ aegis/develop1.h	 interface definition for aegis/develop1.c
+ aegis/develop2.c	 functions to enter and leave 'being_developed' state
+ aegis/develop2.h	 interface definition for aegis/develop2.c
+ aegis/diff.c	 difference a change
+ aegis/diff.h	 interface definition for aegis/diff.c
+ aegis/dir.c	 functions to walk directory trees
+ aegis/dir.h	 interface definition for aegis/dir.c
+ aegis/file.c	 functions for pushing files around
+ aegis/file.h	 interface definition for aegis/file.c
+ aegis/glue.c	 functions to perform systems calls in subprocesses
+ aegis/glue.h	 interface definition for aegis/glue.c
+ aegis/gonzo.c	 functions for manipulating global state data
+ aegis/gonzo.h	 interface definition for aegis/gonzo.c
+ aegis/gram.h	 interface definition for aegis/gram.y
+ aegis/gram.y	 grammar and functions to parse aegis' data files
+ aegis/gstate.def	 global state file contents definition
+ aegis/help.c	 functions to provide consistent treatment of -Help options
+ aegis/help.h	 interface definition for aegis/help.c
+ aegis/indent.c	 functions to automatically indent output
+ aegis/indent.h	 interface definition for aegis/indent.c
+ aegis/integra1.c	 functions to add and remove integrators
+ aegis/integra1.h	 interface definition for aegis/integra1.c
+ aegis/integra2.c	 functions for state transitions to and from being_integrated state
+ aegis/integra2.h	 interface definition for aegis/integra2.c
+ aegis/io.c	 functions to parse and write fundamental data types
+ aegis/io.h	 interface definition for aegis/io.c
+ aegis/lex.c	 functions to perform lexical analysis on aegis' data files
+ aegis/lex.h	 interface definition for aegis/lex.c
+ aegis/list.c	 list interesting things about changes and projects
+ aegis/list.h	 interface definition for aegis/list.c
+ aegis/lock.c	 functions to lock aegis' data
+ aegis/lock.h	 interface definition for aegis/lock.c
+ aegis/log.c	 functions to open and close log files
+ aegis/log.h	 interface definition for aegis/log.c
+ aegis/main.c	 the operating system start-up point
+ aegis/new_chan.c	 functions to create and destroy changes
+ aegis/new_chan.h	 interface definition for aegis/new_chan.c
+ aegis/new_file.c	 functions to add or remove a new file to a change
+ aegis/new_file.h	 interface definition for aegis/new_file.c
+ aegis/new_proj.c	 functions to create and destroy projects
+ aegis/new_proj.h	 interface definition for aegis/new_proj.c
+ aegis/new_rele.c	 functions to create a new project out of an old one
+ aegis/new_rele.h	 interface definition for aegis/new_rele.c
+ aegis/new_test.c	 functions to add and remove new tests to a change
+ aegis/new_test.h	 interface definition for aegis/new_test.c
+ aegis/os.c	 wrappers around operating system functions
+ aegis/os.h	 interface definition for aegis/os.c
+ aegis/pager.c	 functions to pipe output through paginator
+ aegis/pager.h	 interface definition for aegis/pager.c
+ aegis/parse.c	 functions to parse aegis' data files
+ aegis/parse.h	 interface definition for aegis/parse.c
+ aegis/pattr.def	 project attributes file contents definition
+ aegis/pattr_ed.c	 functions to list and modify project attributes
+ aegis/pattr_ed.h	 interface definition for aegis/patter_ed.c
+ aegis/pconf.def	 project config file contents definition
+ aegis/project.c	 functions to manipulate project state data
+ aegis/project.h	 interface definition for aegis/project.h
+ aegis/pstate.def	 project state file contents definition
+ aegis/rem_file.c	 functions to add and remove files to be deleted to a change
+ aegis/rem_file.h	 interface definition for aegis/rem_file.c
+ aegis/rem_proj.c	 functions to remove projects
+ aegis/rem_proj.h	 interface definition for aegis/rem_proj.c
+ aegis/review.c	 review a change, pass or fail or undo
+ aegis/review.h	 interface definition for aegis/review.c
+ aegis/reviewer.c	 functions to add and remove reviewers
+ aegis/reviewer.h	 interface definition for aegis/reviewer.c
+ aegis/sub.c	 functions to perform command substitutions
+ aegis/sub.h	 interface definition for aegis/sub.c
+ aegis/test.c	 test a change
+ aegis/test.h	 interface definition for aegis/test.c
+ aegis/type.c	 functions to manipulate types in aegis' data files
+ aegis/type.h	 interface definition for aegis/type.c
+ aegis/uconf.def	 user config file contents definition
+ aegis/undo.c	 functions to store and enact file operations on transation abort
+ aegis/undo.h	 interface definition for aegis/undo.c
+ aegis/user.c	 functions to manage information about users
+ aegis/user.h	 interface definition for aegis/user.c
+ aegis/ustate.def	 user state file contents definition
+ aegis/version.c	 give version information
+ aegis/version.h	 interface definition for aegis/version.c
+ aux/ALPHA.man	 source for ALPHA file
+ aux/BUILDING.man	 source for BUILDING file
+ aux/BUILDpyr.man	 source of the BUILDpyr file
+ aux/CHANGES.sh	 shell script to create the CHANGES file
+ aux/Howto.cook	 instructions to cook(1), how to build project
+ aux/MANIFEST.sh	 shell script to generate the MANIFEST file
+ aux/Makefile.awk	 helper file for generating the Makefile file
+ aux/Makefile.sh	 shell script to generate the Mafile file
+ aux/README.man	 source for the README file
+ aux/patches.sh	 shell script to generate the patch file
+ common/ansi.c	 missing ANSI C library functions
+ common/arglex.c	 lexical analysis of command line arguments
+ common/arglex.h	 interface definition for common/arglex.c
+ common/error.c	 functions to report errors
+ common/error.h	 interface definition for common/error.c
+ common/main.h	 common definitions, including DEBUG define
+ common/mem.c	 functions to manipulate dynamic memory
+ common/mem.h	 interface definition for common/mem.c
+ common/option.c	 functions to manipulate command line options
+ common/option.h	 interface definition for common/option.c
+ common/patchlevel.h	The patch level of this distribution.
+ common/s-v-arg.h	 insulation from varargs.h versus stdarg.h incompatibilities
+ common/str.c	 string manipulation functions
+ common/str.h	 interface definition for common/str.c
+ common/trace.c	 functions for execution trace
+ common/trace.h	 interface definition for common/trace.c
+ common/word.c	 functions to manipulate lists of strings
+ common/word.h	 interface definition for common/word.c
+ conf/AIX-3.2	 aegis configuration for AIX 3.2 system
+ conf/ConvexOS-10	 aegis configuration for ConvexOS 10
+ conf/SCO-2.4	 aegis configuration for SCO 2.4
+ conf/SunOS-4.1.1	 aegis configuration for SunOS 4.1.1
+ conf/SunOS-4.1.2	 aegis configuration for SunOS 4.1.2
+ conf/SunOS-4.1.3	 aegis configuration for SunOS 4.1.3
+ conf/SysV-4.0	 aegis configuration for generic SVR4 system
+ conf/ULTRIX-4.2	 aegis configuration for ULTRIX version 4.2
+ conf/apollo	 aegis configuration for apollo domain
+ conf/dcosx	 aegis configuration for Pyramid SMP DC/OSx
+ conf/dgux-5.4.1	 aegis configuration for dgux 5.4.1
+ conf/hpux-8.07	 aegis configuration for generic SVR4 system
+ config	 instructions to aegis, per-project configuration
+ doc/aegis.ms	 User Guide
+ doc/c1.0.so	 User Guide, Introduction
+ doc/c1.1.so	 User Guide, Introduction, What does aegis do?
+ doc/c1.2.so	 User Guide, Introduction, Why use aegis?
+ doc/c1.3.so	 User Guide, How Aegis Works, When (not) to use Aegis
+ doc/c1.4.so	 User Guide, Introduction, How to use this manual
+ doc/c2.0.so	 User Guide, The Change Development Cycle
+ doc/c2.1.so	 User Guide, The Change Development Cycle, The Developer
+ doc/c2.2.so	 User Guide, The Change Development Cycle, The Reviewer
+ doc/c2.3.so	 User Guide, The Change Development Cycle, The Integrator
+ doc/c2.4.so	 User Guide, The Change Development Cycle, The Administrator
+ doc/c2.5.so	 User Guide, The Change Development Cycle, What to do Next
+ doc/c3.0.so	 User Guide, The History Tool"
+ doc/c3.1.so	 User Guide, The History Tool, Using SCCS
+ doc/c3.2.so	 User Guide, The History Tool, Using RCS
+ doc/c3.3.so	 User Guide, The History Tool, Using fhist
+ doc/c4.0.so	 User Guide, The Dependency Maintenance Tool
+ doc/c4.1.so	 User Guide, The Dependency Maintenance Tool, Requirements
+ doc/c4.2.so	 User Guide, The Dependency Maintenance Tool, Cook
+ doc/c4.3.so	 User Guiide, The Depenency Maintenance Tool, Other Packages
+ doc/c5.0.so	 User Guide, The Project Attributes
+ doc/c6.0.so	 User Guide, Tips and Traps
+ doc/c7.0.so	 User Guide, How Aegis Works
+ doc/c7.1.so	 User Guide, How Aegis Works, The Model
+ doc/c7.2.so	 User Guide, How Aegis Works, Philosophy
+ doc/c7.4.so	 User Guide, How Aegis Works, Further Work
+ doc/c7.5.so	 User Guide, How Aegis Works, Security
+ doc/c8.0.so	 User Guide, The Difference Tools
+ doc/c8.1.so	 User Guide, The Difference Tools, Interfacing
+ doc/c8.2.so	 User Guide, The Difference Tools, Using diff and diff3
+ doc/c8.3.so	 User Guide, The Difference Tools, Using fhist
+ doc/cA.0.so	 User Guide, Appendix A: New Project Quick Reference
+ doc/cB.0.so	 User Guide, Appendix B: Glossary
+ doc/cC.0.so	 User Guide, Appendix C, Product Comparisons
+ doc/version.so	The patch level of this distribution.
+ fmtgen/id.c	 symbol table manipulation
+ fmtgen/id.h	 interface definition for fmtgen/id.c
+ fmtgen/indent.c	 functions to automatically indent output
+ fmtgen/indent.h	 interface definition for fmtgen/indent.c
+ fmtgen/lex.c	 lexical analyzer
+ fmtgen/lex.h	 interface definition for fmtgen/lex.c
+ fmtgen/main.c	 operating system start-up point
+ fmtgen/parse.h	 interface definition for fmtgen/parse.y
+ fmtgen/parse.y	 grammar and functions to parse aegis file contents definitions
+ fmtgen/type.c	 functions to manipulate data types
+ fmtgen/type.h	 interface definition for fmtgen/type.c
+ fmtgen/type_enum.c	 enumerated types functions gereation
+ fmtgen/type_integ.c	 functions to manipulate integer type
+ fmtgen/type_list.c	 list types function generation
+ fmtgen/type_ref.c	 functions to manipulate reference types
+ fmtgen/type_strin.c	 functions to manipluate string type
+ fmtgen/type_struc.c	 struct types function generation
+ h/dirent.h	 minimal replacement for dirent.h
+ h/stdarg.h-min	 minimal stdarg.h substitute
+ h/stddef.h	 minimal stddef.h substitute
+ h/stdlib.h	 minimal stdlib.h substitute
+ h/unistd.h	 minimal substitute for unistd.h
+ h/utime.h	 minimal replacement for utime.h
+ lib/cshrc	 csh user config for aegis
+ lib/de.inews.sh	 command used to notify by usenet that a change is ready for review
+ lib/de.sh	 command used to notify by email that a change is ready for review
+ lib/deu.inews.sh	 command used to notify by usenet that a change has been withdrawn from review
+ lib/deu.sh	 command used to notify by email that a change has been withdrawn from review
+ lib/if.inews.sh	 command used to notify by usenet that a change failed integration
+ lib/if.sh	 command used to notify by email that a change failed integration
+ lib/ip.inews.sh	 command used to notify by usenet that a change has passed integration
+ lib/ip.sh	 command used to notify by email that a change has passed integration
+ lib/profile	 Bourne shell user config for aegis
+ lib/rf.inews.sh	 command used to notify by usenet that a change failed review
+ lib/rf.sh	 command used to notify by email that a change failed review
+ lib/rp.inews.sh	 command used to notify by usenet that a change has passed review
+ lib/rp.sh	 command used to notify by email that a change has passed review
+ lib/rpu.inews.sh	 command used to notify by usenet that a change review passed is rescinded
+ lib/rpu.sh	 command used to notify by email that a change review passed is rescinded
+ man1/aeb.1	 manual entry for 'aegis -Build' command
+ man1/aeca.1	 manual entry for 'aegis -Change_Attributes' command
+ man1/aecd.1	 manual entry for 'aegis -Change_Directory' command
+ man1/aecp.1	 manual entry for aegis -CoPy_file
+ man1/aecpu.1	 manual entry for 'aegis -CoPy_file_Undo' command
+ man1/aed.1	 manual entry for 'aegis -DIFFerence' command
+ man1/aedb.1	 manual entry for 'aegis -Develop_Begin' command
+ man1/aedbu.1	 manual entry for 'aegis -Develop_Begin_Undo' command
+ man1/aede.1	 manual entry for 'aegis -Develop_End' command
+ man1/aedeu.1	 manual entry for 'aegis -Develop_End_Undo' command
+ man1/aegis.1	 manual entry for aegis
+ man1/aeib.1	 manual entry for 'aegis -Integrate_Begin' command
+ man1/aeibu.1	 manual entry for 'aegis -Integrate_Begin_Undo' command
+ man1/aeif.1	 manual entry for 'aegis -Integrate_Fail' command
+ man1/aeip.1	 manual entry for 'aegis -Integrate_Pass' command
+ man1/ael.1	 manual entry for 'aegis -List' command
+ man1/aena.1	 manual entry for 'aegis -New_Administrator' command
+ man1/aenc.1	 manual entry for 'aegis -New_Change' command
+ man1/aencu.1	 manual entry for 'aegis -New_Change_Undo' command
+ man1/aend.1	 manual entry for 'aegis -New_Developer' command
+ man1/aenf.1	 manual entry for 'aegis -New_File' command
+ man1/aenfu.1	 manual entry for 'aegis -New_Fule_Undo' command
+ man1/aeni.1	 manual entry for 'aegis -New_Integrator' command
+ man1/aenpr.1	 manual entry for 'aegis -New_PRoject' command
+ man1/aenrls.1	 manual entry for 'aegis -New_ReLeaSe' command
+ man1/aenrv.1	 manual entry for 'aegis -New_ReViewer' command
+ man1/aent.1	 manual entry for 'aegis -New_Test' command
+ man1/aentu.1	 manual entry for 'aegis -New_Test_Undo' command
+ man1/aepa.1	 manual entry for 'aegis -Project_Attributes' command
+ man1/aera.1	 manual entry for 'aegis -Remove_Administrator' command
+ man1/aerd.1	 manual entry for 'aegis -Remove_Developer' command
+ man1/aerf.1	 manual entry for 'aegis -Review_FAIL' command
+ man1/aeri.1	 manual entry for the 'aegis -Remove_Integrator' command
+ man1/aerm.1	 manual entry for the 'aegis -ReMove_file' command
+ man1/aermpr.1	 manual entry for the 'aegis -ReMove_PRoject' command
+ man1/aermu.1	 manual entry for the 'aegis -ReMove_file_Undo' command
+ man1/aerp.1	 manual entry for the 'aegis -Review_PASS' command
+ man1/aerpu.1	 manual entry for the 'aegis -Review_Pass_Undo' command
+ man1/aerrv.1	 manual entry for the 'aegis -Remove ReViewer' command
+ man1/aet.1	 manual entry for the 'aegis -Test' command
+ man1/aev.1	 manual entry for the 'aegis -VERSion' command
+ man1/install.sh	 shell script to install section 1 manual pages
+ man1/o__rules.so	 description of option up/down case convention
+ man1/o_anticip.so	 description of -ANticipate command line option
+ man1/o_auto.so	 description of -AUTOmatic command line option
+ man1/o_baselin.so	 description of -BaseLine command line option
+ man1/o_bld_lk.so	 manual section describing the build lock
+ man1/o_change.so	 description of -Change command line option
+ man1/o_devdir.so	 description of -Development_Directory command line option
+ man1/o_dir.so	 description of -DIRectory command line option
+ man1/o_help.so	 description of -Help command line option
+ man1/o_indep.so	 description of -INDependent command line option
+ man1/o_keep.so	 description of -Keep command line option
+ man1/o_lib.so	 description of -LIBrary command line option
+ man1/o_list.so	 description of -List command line option
+ man1/o_major.so	 description of -MAJor command line option
+ man1/o_manual.so	 description of -MINor command line option
+ man1/o_min.so	 description of -MINImum command line option
+ man1/o_minor.so	 description of -MINOr command line option
+ man1/o_nolog.so	 description of -Not_Logging command line option
+ man1/o_overw.so	 description of -OverWriting command line option
+ man1/o_page.so	 description of -Page_Length and -Page_Width command line options
+ man1/o_project.so	 description of -Project command line option
+ man1/o_terse.so	 description of -TERse command line option
+ man1/o_verbose.so	 description of -Verbose command line option
+ man1/z_cr.so	 copyright and author parts of section 1 manual entries
+ man1/z_exit.so	 exit status part of section 1 manual entries
+ man1/z_intuit.so	 description of how file names are interpreted on command line
+ man1/z_name.so	 common setup for section 1 manual entries
+ man5/aecattr.5	 description of aegis change attribute file format
+ man5/aecattr.so	 description of aegis change attribute file format
+ man5/aecstate.5	 description of aegis change state file format
+ man5/aedir.5	 description of aegis project directory structure
+ man5/aegis.5	 description of aegis file format general structure
+ man5/aegstate.5	 description of aegis global state file format
+ man5/aepattr.5	 description of aegis project attribute file format
+ man5/aepattr.so	 description of aegis project attribute file format
+ man5/aepconf.5	 description of aegis project config file format
+ man5/aepstate.5	 description of aegis project state file format
+ man5/aesub.5	 manual page describing command substitutions
+ man5/aeuconf.5	 description of aegis user config file format
+ man5/aeustate.5	 description of aegis user state file format
+ man5/install.sh	 shell script to install section 5 manual entries
+ man5/z_cr.so	 copyright and author parts of section 5 manual entries
+ man5/z_name.so	 common setup for section 5 manual entries
+ test/00/t0001a.sh	 test -Help for each function
+ test/00/t0002a.sh	 Test core functionality.
+ test/00/t0003a.sh	 Test 'aegis -VERSion'
+ test/00/t0004a.sh	 Test the 'aegis -DIFFerence' command.
+ test/00/t0005a.sh	 Test the 'aegis -DevEnd' command.
+ test/00/t0006a.sh	 Test 'aegis -DIFFerence' when the edit number is out-of-date.
+ test/00/t0007a.sh	 test for correct behaviour around symbolic links
+ test/00/t0008a.sh	 Test command substitutions
+ test/00/t0009a.sh	 Test -New_ReLeaSe functionality.
+ test/00/t0010a.sh	 Test -Review_Pass_Undo functionality.
+ test/00/t0011a.sh	 Test documentation example.
+ test/00/t0012a.sh	 Test the aermpr functionality
+ test/00/t0013a.sh	 Test the -New_Change_Undo functionality
+ test/00/t0014a.sh	 Test the -Develop_Begin_Undo functionality
+ test/00/t0015a.sh	 Test the -Integrate_Begin_Undo functionality
Index: Makefile
***************
*** 0 ****
--- 1,921 ----
+ #
+ # You may need to change this for your system.
+ # The ``h'' directory supplements your system, not replacing it.
+ # The first variation is for gcc when it isn't the native complier,
+ # the second variation is for systems with missing ANSI C include files,
+ # the third variation is for conforming ANSI C implementations.
+ #
+ # H = -I/usr/local/lib/gcc-include -I/usr/include -Ih
+ # H = -I/usr/include -Ih
+ H =
+ # H =				# SunOS
+ # H =				# ConvexOS
+ # H =				# dgux
+ # H =				# dcosx
+ # H =				# ULTRIX
+ # H =				# hpux
+ # H =				# SCO
+ 
+ #
+ # the name of the compiler to use
+ #
+ CC = cc
+ # CC = gcc
+ # CC = cc			# SunOS
+ # CC = cc			# ConvexOS
+ # CC = cc			# dgux
+ # CC = /usr/ucb/cc		# dcosx
+ # CC = cc			# ULTRIX
+ # CC = cc			# hpux
+ # CC = rcc			# SCO
+ 
+ #
+ # The compiler flags to use, except for include path.
+ #
+ CFLAGS = -O
+ # CFLAGS = -g
+ # CFLAGS = -O			# SunOS
+ # CFLAGS = -O			# ConvexOS
+ # CFLAGS = -O			# dgux
+ # CFLAGS = -O -Wall -ansi	# gcc
+ # CFLAGS = -O -Xt -U__STDC__	# dcosx
+ # CFLAGS = -O			# ULTRIX
+ # CFLAGS = -O			# hpux
+ # CFLAGS = -O			# SCO
+ 
+ #
+ # which yacc to use
+ #
+ YACC = yacc
+ # YACC = byacc			# Berkeley
+ # YACC = bison -y		# GNU
+ 
+ #
+ # where to put the library directory
+ #	(not used in testing mode)
+ #
+ LIB = /usr/local/lib/aegis
+ 
+ #
+ # where to put the executables
+ #
+ BIN = /usr/local/bin
+ 
+ #
+ # where to put the manual entries
+ #
+ MAN = /usr/local/man
+ 
+ #
+ # extra libraries required for your system
+ #
+ LIBRARIES =
+ # LIBRARIES = -lbsd
+ # LIBRARIES =			# SunOS
+ # LIBRARIES =			# ConvexOS
+ # LIBRARIES =			# dgux
+ # LIBRARIES = -lucb		# dcosx
+ # LIBRARIES =			# ULTRIX
+ # LIBRARIES =			# hpux
+ # LIBRARIES = -lsocket		# SCO
+ 
+ #
+ # shell to use to run the tests
+ #	make sure there are no spaces after the definition,
+ #	many flavours of make(1) can't cope with them.
+ #
+ SHELL = /bin/sh
+ # SHELL = /bin/sh		# SunOS
+ # SHELL = /bin/sh		# ConvexOS
+ # SHELL = /bin/sh		# dgux
+ # SHELL = /bin/sh		# dcosx
+ # SHELL = /bin/sh5		# ULTRIX
+ # SHELL = /bin/ksh		# apollo
+ # SHELL = /bin/sh		# hpux
+ # SHELL = /bin/sh		# SCO
+ 
+ # You should not need to alter anything below this point.
+ #------------------------------------------------------------
+ 
+ all: bin/aegis
+ 
+ 
+ aegis/administ.o: aegis/administ.c aegis/arglex2.h common/arglex.h \
+ 		common/main.h aegis/administ.h aegis/commit.h \
+ 		common/str.h common/s-v-arg.h common/conf.h \
+ 		common/error.h aegis/help.h aegis/list.h aegis/lock.h \
+ 		common/option.h aegis/os.h aegis/project.h \
+ 		aegis/pstate.h aegis/type.h aegis/parse.h aegis/pattr.h \
+ 		common/trace.h aegis/user.h aegis/ustate.h \
+ 		aegis/uconf.h common/word.h 
+ 	$(CC) $(CFLAGS)  -Iaegis -Icommon $(H) -c aegis/administ.c
+ 	mv administ.o aegis/administ.o
+ 
+ aegis/build.o: aegis/build.c aegis/arglex2.h common/arglex.h \
+ 		common/main.h aegis/build.h aegis/col.h aegis/commit.h \
+ 		common/str.h common/s-v-arg.h common/conf.h \
+ 		aegis/change.h aegis/cstate.h aegis/type.h \
+ 		aegis/parse.h aegis/pconf.h common/error.h aegis/help.h \
+ 		aegis/list.h aegis/lock.h aegis/log.h common/option.h \
+ 		aegis/os.h aegis/project.h aegis/pstate.h aegis/pattr.h \
+ 		aegis/sub.h common/trace.h aegis/user.h aegis/ustate.h \
+ 		aegis/uconf.h 
+ 	$(CC) $(CFLAGS)  -Iaegis -Icommon $(H) -c aegis/build.c
+ 	mv build.o aegis/build.o
+ 
+ aegis/cattr.c aegis/cattr.h: aegis/cattr.def bin/fmtgen aegis/common.def
+ 	bin/fmtgen -Iaegis aegis/cattr.def aegis/cattr.c aegis/cattr.h
+ 
+ aegis/cattr.o: aegis/cattr.c aegis/cattr.h common/main.h aegis/type.h \
+ 		common/str.h common/s-v-arg.h common/conf.h \
+ 		aegis/parse.h common/error.h aegis/indent.h aegis/io.h \
+ 		common/mem.h aegis/os.h common/trace.h 
+ 	$(CC) $(CFLAGS) -Iaegis -Icommon $(H) -c aegis/cattr.c
+ 	mv cattr.o aegis/cattr.o
+ 
+ aegis/cattr_ed.o: aegis/cattr_ed.c aegis/arglex2.h common/arglex.h \
+ 		common/main.h aegis/cattr.h aegis/type.h common/str.h \
+ 		common/s-v-arg.h common/conf.h aegis/parse.h \
+ 		aegis/cattr_ed.h aegis/commit.h aegis/change.h \
+ 		aegis/cstate.h aegis/pconf.h common/error.h \
+ 		aegis/help.h aegis/lock.h aegis/project.h \
+ 		aegis/pstate.h aegis/pattr.h common/option.h aegis/os.h \
+ 		common/trace.h aegis/user.h aegis/ustate.h \
+ 		aegis/uconf.h 
+ 	$(CC) $(CFLAGS)  -Iaegis -Icommon $(H) -c aegis/cattr_ed.c
+ 	mv cattr_ed.o aegis/cattr_ed.o
+ 
+ aegis/change.o: aegis/change.c aegis/change.h common/main.h \
+ 		aegis/cstate.h aegis/type.h common/str.h \
+ 		common/s-v-arg.h common/conf.h aegis/parse.h \
+ 		aegis/pconf.h aegis/commit.h common/error.h \
+ 		aegis/lock.h common/mem.h common/option.h aegis/os.h \
+ 		aegis/project.h aegis/pstate.h aegis/pattr.h \
+ 		aegis/sub.h common/trace.h aegis/undo.h aegis/user.h \
+ 		aegis/ustate.h aegis/uconf.h common/word.h 
+ 	$(CC) $(CFLAGS)  -Iaegis -Icommon $(H) -c aegis/change.c
+ 	mv change.o aegis/change.o
+ 
+ aegis/chdir.o: aegis/chdir.c aegis/arglex2.h common/arglex.h \
+ 		common/main.h aegis/chdir.h aegis/change.h \
+ 		aegis/cstate.h aegis/type.h common/str.h \
+ 		common/s-v-arg.h common/conf.h aegis/parse.h \
+ 		aegis/pconf.h common/error.h aegis/help.h aegis/list.h \
+ 		common/option.h aegis/os.h aegis/project.h \
+ 		aegis/pstate.h aegis/pattr.h common/trace.h \
+ 		aegis/user.h aegis/ustate.h aegis/uconf.h 
+ 	$(CC) $(CFLAGS)  -Iaegis -Icommon $(H) -c aegis/chdir.c
+ 	mv chdir.o aegis/chdir.o
+ 
+ aegis/col.o: aegis/col.c aegis/col.h common/main.h common/error.h \
+ 		aegis/glue.h common/conf.h common/mem.h common/option.h \
+ 		aegis/os.h common/str.h common/s-v-arg.h aegis/pager.h \
+ 		common/trace.h 
+ 	$(CC) $(CFLAGS)  -Iaegis -Icommon $(H) -c aegis/col.c
+ 	mv col.o aegis/col.o
+ 
+ aegis/commit.o: aegis/commit.c aegis/commit.h common/str.h \
+ 		common/s-v-arg.h common/conf.h common/main.h \
+ 		aegis/dir.h common/mem.h aegis/os.h common/trace.h \
+ 		aegis/undo.h 
+ 	$(CC) $(CFLAGS)  -Iaegis -Icommon $(H) -c aegis/commit.c
+ 	mv commit.o aegis/commit.o
+ 
+ aegis/common.c aegis/common.h: aegis/common.def bin/fmtgen
+ 	bin/fmtgen -Iaegis aegis/common.def aegis/common.c aegis/common.h
+ 
+ aegis/common.o: aegis/common.c aegis/common.h common/main.h \
+ 		aegis/type.h common/str.h common/s-v-arg.h \
+ 		common/conf.h aegis/parse.h common/error.h \
+ 		aegis/indent.h aegis/io.h common/mem.h aegis/os.h \
+ 		common/trace.h 
+ 	$(CC) $(CFLAGS) -Iaegis -Icommon $(H) -c aegis/common.c
+ 	mv common.o aegis/common.o
+ 
+ aegis/copyfile.o: aegis/copyfile.c aegis/arglex2.h common/arglex.h \
+ 		common/main.h aegis/commit.h common/str.h \
+ 		common/s-v-arg.h common/conf.h aegis/copyfile.h \
+ 		aegis/change.h aegis/cstate.h aegis/type.h \
+ 		aegis/parse.h aegis/pconf.h common/error.h aegis/file.h \
+ 		aegis/help.h aegis/list.h aegis/lock.h aegis/log.h \
+ 		common/option.h aegis/os.h aegis/project.h \
+ 		aegis/pstate.h aegis/pattr.h common/trace.h \
+ 		aegis/undo.h aegis/user.h aegis/ustate.h aegis/uconf.h \
+ 		common/word.h 
+ 	$(CC) $(CFLAGS)  -Iaegis -Icommon $(H) -c aegis/copyfile.c
+ 	mv copyfile.o aegis/copyfile.o
+ 
+ aegis/cstate.c aegis/cstate.h: aegis/cstate.def bin/fmtgen \
+ 		aegis/cattr.def aegis/common.def 
+ 	bin/fmtgen -Iaegis aegis/cstate.def aegis/cstate.c aegis/cstate.h
+ 
+ aegis/cstate.o: aegis/cstate.c aegis/cstate.h common/main.h \
+ 		aegis/type.h common/str.h common/s-v-arg.h \
+ 		common/conf.h aegis/parse.h common/error.h \
+ 		aegis/indent.h aegis/io.h common/mem.h aegis/os.h \
+ 		common/trace.h 
+ 	$(CC) $(CFLAGS) -Iaegis -Icommon $(H) -c aegis/cstate.c
+ 	mv cstate.o aegis/cstate.o
+ 
+ aegis/develop1.o: aegis/develop1.c aegis/arglex2.h common/arglex.h \
+ 		common/main.h aegis/commit.h common/str.h \
+ 		common/s-v-arg.h common/conf.h aegis/develop1.h \
+ 		common/error.h aegis/help.h aegis/lock.h aegis/list.h \
+ 		common/option.h aegis/os.h aegis/project.h \
+ 		aegis/pstate.h aegis/type.h aegis/parse.h aegis/pattr.h \
+ 		common/trace.h aegis/user.h aegis/ustate.h \
+ 		aegis/uconf.h common/word.h 
+ 	$(CC) $(CFLAGS)  -Iaegis -Icommon $(H) -c aegis/develop1.c
+ 	mv develop1.o aegis/develop1.o
+ 
+ aegis/develop2.o: aegis/develop2.c aegis/arglex2.h common/arglex.h \
+ 		common/main.h aegis/change.h aegis/cstate.h \
+ 		aegis/type.h common/str.h common/s-v-arg.h \
+ 		common/conf.h aegis/parse.h aegis/pconf.h aegis/col.h \
+ 		aegis/commit.h aegis/common.h aegis/develop2.h \
+ 		aegis/dir.h common/error.h aegis/help.h aegis/list.h \
+ 		aegis/lock.h common/option.h aegis/os.h aegis/project.h \
+ 		aegis/pstate.h aegis/pattr.h aegis/sub.h common/trace.h \
+ 		aegis/undo.h aegis/user.h aegis/ustate.h aegis/uconf.h 
+ 	$(CC) $(CFLAGS)  -Iaegis -Icommon $(H) -c aegis/develop2.c
+ 	mv develop2.o aegis/develop2.o
+ 
+ aegis/diff.o: aegis/diff.c aegis/arglex2.h common/arglex.h \
+ 		common/main.h aegis/change.h aegis/cstate.h \
+ 		aegis/type.h common/str.h common/s-v-arg.h \
+ 		common/conf.h aegis/parse.h aegis/pconf.h aegis/col.h \
+ 		aegis/commit.h aegis/diff.h common/error.h aegis/help.h \
+ 		aegis/list.h aegis/lock.h aegis/log.h common/option.h \
+ 		aegis/os.h aegis/project.h aegis/pstate.h aegis/pattr.h \
+ 		aegis/sub.h common/trace.h aegis/undo.h aegis/user.h \
+ 		aegis/ustate.h aegis/uconf.h common/word.h 
+ 	$(CC) $(CFLAGS)  -Iaegis -Icommon $(H) -c aegis/diff.c
+ 	mv diff.o aegis/diff.o
+ 
+ aegis/dir.o: aegis/dir.c aegis/dir.h common/main.h common/str.h \
+ 		common/s-v-arg.h common/conf.h common/error.h \
+ 		aegis/glue.h common/trace.h common/word.h 
+ 	$(CC) $(CFLAGS)  -Iaegis -Icommon $(H) -c aegis/dir.c
+ 	mv dir.o aegis/dir.o
+ 
+ aegis/file.o: aegis/file.c aegis/file.h common/main.h common/str.h \
+ 		common/s-v-arg.h common/conf.h common/error.h \
+ 		aegis/glue.h common/mem.h aegis/os.h common/trace.h 
+ 	$(CC) $(CFLAGS)  -Iaegis -Icommon $(H) -c aegis/file.c
+ 	mv file.o aegis/file.o
+ 
+ aegis/glue.o: aegis/glue.c common/error.h common/main.h aegis/glue.h \
+ 		common/conf.h common/mem.h aegis/os.h common/str.h \
+ 		common/s-v-arg.h common/trace.h aegis/undo.h 
+ 	$(CC) $(CFLAGS)  -Iaegis -Icommon $(H) -c aegis/glue.c
+ 	mv glue.o aegis/glue.o
+ 
+ aegis/gonzo.o: aegis/gonzo.c aegis/commit.h common/str.h \
+ 		common/s-v-arg.h common/conf.h common/main.h \
+ 		common/error.h aegis/gonzo.h aegis/gstate.h \
+ 		aegis/type.h aegis/parse.h aegis/lock.h common/mem.h \
+ 		common/option.h aegis/os.h aegis/project.h \
+ 		aegis/pstate.h aegis/pattr.h common/trace.h \
+ 		aegis/undo.h aegis/user.h aegis/ustate.h aegis/uconf.h \
+ 		common/word.h 
+ 	$(CC) $(CFLAGS) -D'LIB="$(LIB)"' -Iaegis -Icommon $(H) -c aegis/gonzo.c
+ 	mv gonzo.o aegis/gonzo.o
+ 
+ aegis/gram.gen.c aegis/gram.gen.h: aegis/gram.y
+ 	$(YACC) -d aegis/gram.y
+ 	sed "s/[yY][yY]/gram_/g" < y.tab.c > aegis/gram.gen.c
+ 	rm y.tab.c
+ 	sed "s/[yY][yY]/gram_/g" < y.tab.h > aegis/gram.gen.h
+ 	rm y.tab.h
+ 
+ aegis/gram.gen.o: aegis/gram.gen.c aegis/gram.h common/main.h \
+ 		aegis/lex.h common/mem.h aegis/parse.h common/str.h \
+ 		common/s-v-arg.h common/conf.h aegis/type.h 
+ 	$(CC) $(CFLAGS) -Iaegis -Icommon $(H) -c aegis/gram.gen.c
+ 	mv gram.gen.o aegis/gram.gen.o
+ 
+ aegis/gstate.c aegis/gstate.h: aegis/gstate.def bin/fmtgen
+ 	bin/fmtgen -Iaegis aegis/gstate.def aegis/gstate.c aegis/gstate.h
+ 
+ aegis/gstate.o: aegis/gstate.c aegis/gstate.h common/main.h \
+ 		aegis/type.h common/str.h common/s-v-arg.h \
+ 		common/conf.h aegis/parse.h common/error.h \
+ 		aegis/indent.h aegis/io.h common/mem.h aegis/os.h \
+ 		common/trace.h 
+ 	$(CC) $(CFLAGS) -Iaegis -Icommon $(H) -c aegis/gstate.c
+ 	mv gstate.o aegis/gstate.o
+ 
+ aegis/help.o: aegis/help.c aegis/arglex2.h common/arglex.h \
+ 		common/main.h common/error.h aegis/gonzo.h \
+ 		aegis/gstate.h aegis/type.h common/str.h \
+ 		common/s-v-arg.h common/conf.h aegis/parse.h \
+ 		aegis/help.h common/option.h aegis/pager.h \
+ 		common/patchlevel.h common/trace.h aegis/undo.h 
+ 	$(CC) $(CFLAGS)  -Iaegis -Icommon $(H) -c aegis/help.c
+ 	mv help.o aegis/help.o
+ 
+ aegis/indent.o: aegis/indent.c common/error.h common/main.h \
+ 		aegis/glue.h common/conf.h aegis/indent.h \
+ 		common/s-v-arg.h common/trace.h 
+ 	$(CC) $(CFLAGS)  -Iaegis -Icommon $(H) -c aegis/indent.c
+ 	mv indent.o aegis/indent.o
+ 
+ aegis/integra1.o: aegis/integra1.c aegis/arglex2.h common/arglex.h \
+ 		common/main.h aegis/commit.h common/str.h \
+ 		common/s-v-arg.h common/conf.h common/error.h \
+ 		aegis/help.h aegis/integra1.h aegis/list.h aegis/lock.h \
+ 		common/option.h aegis/os.h aegis/project.h \
+ 		aegis/pstate.h aegis/type.h aegis/parse.h aegis/pattr.h \
+ 		common/trace.h aegis/user.h aegis/ustate.h \
+ 		aegis/uconf.h common/word.h 
+ 	$(CC) $(CFLAGS)  -Iaegis -Icommon $(H) -c aegis/integra1.c
+ 	mv integra1.o aegis/integra1.o
+ 
+ aegis/integra2.o: aegis/integra2.c aegis/arglex2.h common/arglex.h \
+ 		common/main.h aegis/commit.h common/str.h \
+ 		common/s-v-arg.h common/conf.h aegis/change.h \
+ 		aegis/cstate.h aegis/type.h aegis/parse.h aegis/pconf.h \
+ 		aegis/dir.h common/error.h aegis/file.h aegis/help.h \
+ 		aegis/integra2.h aegis/list.h aegis/lock.h aegis/log.h \
+ 		common/option.h aegis/os.h aegis/project.h \
+ 		aegis/pstate.h aegis/pattr.h aegis/sub.h common/trace.h \
+ 		aegis/undo.h aegis/user.h aegis/ustate.h aegis/uconf.h 
+ 	$(CC) $(CFLAGS)  -Iaegis -Icommon $(H) -c aegis/integra2.c
+ 	mv integra2.o aegis/integra2.o
+ 
+ aegis/io.o: aegis/io.c aegis/indent.h common/main.h common/str.h \
+ 		common/s-v-arg.h common/conf.h aegis/io.h aegis/type.h 
+ 	$(CC) $(CFLAGS)  -Iaegis -Icommon $(H) -c aegis/io.c
+ 	mv io.o aegis/io.o
+ 
+ aegis/lex.o: aegis/lex.c common/error.h common/main.h aegis/glue.h \
+ 		common/conf.h aegis/lex.h common/s-v-arg.h common/str.h \
+ 		aegis/gram.gen.h 
+ 	$(CC) $(CFLAGS)  -Iaegis -Icommon $(H) -c aegis/lex.c
+ 	mv lex.o aegis/lex.o
+ 
+ aegis/list.o: aegis/list.c aegis/arglex2.h common/arglex.h \
+ 		common/main.h aegis/col.h aegis/change.h aegis/cstate.h \
+ 		aegis/type.h common/str.h common/s-v-arg.h \
+ 		common/conf.h aegis/parse.h aegis/pconf.h \
+ 		common/error.h aegis/gonzo.h aegis/gstate.h \
+ 		aegis/help.h aegis/list.h common/option.h aegis/os.h \
+ 		aegis/project.h aegis/pstate.h aegis/pattr.h \
+ 		common/trace.h aegis/user.h aegis/ustate.h \
+ 		aegis/uconf.h common/word.h 
+ 	$(CC) $(CFLAGS)  -Iaegis -Icommon $(H) -c aegis/list.c
+ 	mv list.o aegis/list.o
+ 
+ aegis/lock.o: aegis/lock.c common/error.h common/main.h aegis/glue.h \
+ 		common/conf.h aegis/gonzo.h aegis/gstate.h aegis/type.h \
+ 		common/str.h common/s-v-arg.h aegis/parse.h \
+ 		aegis/lock.h common/mem.h aegis/os.h common/trace.h 
+ 	$(CC) $(CFLAGS)  -Iaegis -Icommon $(H) -c aegis/lock.c
+ 	mv lock.o aegis/lock.o
+ 
+ aegis/log.o: aegis/log.c common/error.h common/main.h aegis/log.h \
+ 		aegis/os.h common/str.h common/s-v-arg.h common/conf.h \
+ 		common/trace.h aegis/undo.h aegis/user.h aegis/ustate.h \
+ 		aegis/type.h aegis/parse.h aegis/uconf.h 
+ 	$(CC) $(CFLAGS)  -Iaegis -Icommon $(H) -c aegis/log.c
+ 	mv log.o aegis/log.o
+ 
+ aegis/main.o: aegis/main.c aegis/administ.h common/main.h \
+ 		aegis/arglex2.h common/arglex.h aegis/build.h \
+ 		aegis/cattr_ed.h aegis/chdir.h aegis/copyfile.h \
+ 		aegis/develop1.h aegis/develop2.h aegis/diff.h \
+ 		common/error.h aegis/help.h aegis/integra1.h \
+ 		aegis/integra2.h aegis/list.h aegis/log.h \
+ 		aegis/new_chan.h aegis/new_file.h aegis/new_proj.h \
+ 		aegis/new_rele.h aegis/new_test.h common/option.h \
+ 		aegis/os.h common/str.h common/s-v-arg.h common/conf.h \
+ 		aegis/pattr_ed.h aegis/rem_file.h aegis/rem_proj.h \
+ 		aegis/review.h aegis/reviewer.h aegis/test.h \
+ 		common/trace.h aegis/undo.h aegis/version.h 
+ 	$(CC) $(CFLAGS)  -Iaegis -Icommon $(H) -c aegis/main.c
+ 	mv main.o aegis/main.o
+ 
+ aegis/new_chan.o: aegis/new_chan.c aegis/arglex2.h common/arglex.h \
+ 		common/main.h aegis/cattr.h aegis/type.h common/str.h \
+ 		common/s-v-arg.h common/conf.h aegis/parse.h \
+ 		aegis/change.h aegis/cstate.h aegis/pconf.h aegis/col.h \
+ 		aegis/commit.h aegis/common.h common/error.h \
+ 		aegis/help.h aegis/list.h aegis/lock.h aegis/new_chan.h \
+ 		common/option.h aegis/os.h aegis/project.h \
+ 		aegis/pstate.h aegis/pattr.h common/trace.h \
+ 		aegis/user.h aegis/ustate.h aegis/uconf.h 
+ 	$(CC) $(CFLAGS)  -Iaegis -Icommon $(H) -c aegis/new_chan.c
+ 	mv new_chan.o aegis/new_chan.o
+ 
+ aegis/new_file.o: aegis/new_file.c aegis/arglex2.h common/arglex.h \
+ 		common/main.h aegis/change.h aegis/cstate.h \
+ 		aegis/type.h common/str.h common/s-v-arg.h \
+ 		common/conf.h aegis/parse.h aegis/pconf.h aegis/col.h \
+ 		aegis/commit.h common/error.h aegis/glue.h aegis/help.h \
+ 		aegis/list.h aegis/lock.h aegis/log.h aegis/new_file.h \
+ 		common/option.h aegis/os.h aegis/project.h \
+ 		aegis/pstate.h aegis/pattr.h common/trace.h \
+ 		aegis/user.h aegis/ustate.h aegis/uconf.h common/word.h 
+ 	$(CC) $(CFLAGS)  -Iaegis -Icommon $(H) -c aegis/new_file.c
+ 	mv new_file.o aegis/new_file.o
+ 
+ aegis/new_proj.o: aegis/new_proj.c aegis/arglex2.h common/arglex.h \
+ 		common/main.h aegis/commit.h common/str.h \
+ 		common/s-v-arg.h common/conf.h common/error.h \
+ 		aegis/gonzo.h aegis/gstate.h aegis/type.h aegis/parse.h \
+ 		aegis/help.h aegis/list.h aegis/lock.h aegis/new_proj.h \
+ 		common/option.h aegis/os.h aegis/project.h \
+ 		aegis/pstate.h aegis/pattr.h common/trace.h \
+ 		aegis/undo.h aegis/user.h aegis/ustate.h aegis/uconf.h 
+ 	$(CC) $(CFLAGS)  -Iaegis -Icommon $(H) -c aegis/new_proj.c
+ 	mv new_proj.o aegis/new_proj.o
+ 
+ aegis/new_rele.o: aegis/new_rele.c aegis/arglex2.h common/arglex.h \
+ 		common/main.h aegis/change.h aegis/cstate.h \
+ 		aegis/type.h common/str.h common/s-v-arg.h \
+ 		common/conf.h aegis/parse.h aegis/pconf.h \
+ 		aegis/commit.h aegis/dir.h common/error.h aegis/file.h \
+ 		aegis/gonzo.h aegis/gstate.h aegis/help.h aegis/list.h \
+ 		aegis/lock.h aegis/log.h common/mem.h aegis/new_rele.h \
+ 		common/option.h aegis/os.h aegis/project.h \
+ 		aegis/pstate.h aegis/pattr.h aegis/sub.h common/trace.h \
+ 		aegis/undo.h aegis/user.h aegis/ustate.h aegis/uconf.h 
+ 	$(CC) $(CFLAGS)  -Iaegis -Icommon $(H) -c aegis/new_rele.c
+ 	mv new_rele.o aegis/new_rele.o
+ 
+ aegis/new_test.o: aegis/new_test.c aegis/arglex2.h common/arglex.h \
+ 		common/main.h aegis/change.h aegis/cstate.h \
+ 		aegis/type.h common/str.h common/s-v-arg.h \
+ 		common/conf.h aegis/parse.h aegis/pconf.h aegis/col.h \
+ 		aegis/commit.h common/error.h aegis/glue.h aegis/help.h \
+ 		aegis/list.h aegis/lock.h aegis/new_test.h \
+ 		common/option.h aegis/os.h aegis/project.h \
+ 		aegis/pstate.h aegis/pattr.h common/trace.h \
+ 		aegis/user.h aegis/ustate.h aegis/uconf.h common/word.h 
+ 	$(CC) $(CFLAGS)  -Iaegis -Icommon $(H) -c aegis/new_test.c
+ 	mv new_test.o aegis/new_test.o
+ 
+ aegis/os.o: aegis/os.c common/conf.h aegis/dir.h common/main.h \
+ 		common/str.h common/s-v-arg.h common/error.h \
+ 		aegis/file.h aegis/glue.h common/mem.h common/option.h \
+ 		aegis/os.h common/trace.h aegis/undo.h common/word.h 
+ 	$(CC) $(CFLAGS)  -Iaegis -Icommon $(H) -c aegis/os.c
+ 	mv os.o aegis/os.o
+ 
+ aegis/pager.o: aegis/pager.c common/error.h common/main.h aegis/os.h \
+ 		common/str.h common/s-v-arg.h common/conf.h \
+ 		aegis/pager.h common/trace.h aegis/undo.h 
+ 	$(CC) $(CFLAGS)  -Iaegis -Icommon $(H) -c aegis/pager.c
+ 	mv pager.o aegis/pager.o
+ 
+ aegis/parse.o: aegis/parse.c common/error.h common/main.h aegis/gram.h \
+ 		aegis/lex.h common/mem.h aegis/parse.h common/str.h \
+ 		common/s-v-arg.h common/conf.h aegis/type.h \
+ 		common/trace.h 
+ 	$(CC) $(CFLAGS)  -Iaegis -Icommon $(H) -c aegis/parse.c
+ 	mv parse.o aegis/parse.o
+ 
+ aegis/pattr.c aegis/pattr.h: aegis/pattr.def bin/fmtgen aegis/common.def
+ 	bin/fmtgen -Iaegis aegis/pattr.def aegis/pattr.c aegis/pattr.h
+ 
+ aegis/pattr.o: aegis/pattr.c aegis/pattr.h common/main.h aegis/type.h \
+ 		common/str.h common/s-v-arg.h common/conf.h \
+ 		aegis/parse.h common/error.h aegis/indent.h aegis/io.h \
+ 		common/mem.h aegis/os.h common/trace.h 
+ 	$(CC) $(CFLAGS) -Iaegis -Icommon $(H) -c aegis/pattr.c
+ 	mv pattr.o aegis/pattr.o
+ 
+ aegis/pattr_ed.o: aegis/pattr_ed.c aegis/arglex2.h common/arglex.h \
+ 		common/main.h aegis/commit.h common/str.h \
+ 		common/s-v-arg.h common/conf.h common/error.h \
+ 		aegis/help.h aegis/lock.h common/option.h aegis/os.h \
+ 		aegis/pattr.h aegis/type.h aegis/parse.h \
+ 		aegis/pattr_ed.h aegis/project.h aegis/pstate.h \
+ 		common/trace.h aegis/user.h aegis/ustate.h \
+ 		aegis/uconf.h 
+ 	$(CC) $(CFLAGS)  -Iaegis -Icommon $(H) -c aegis/pattr_ed.c
+ 	mv pattr_ed.o aegis/pattr_ed.o
+ 
+ aegis/pconf.c aegis/pconf.h: aegis/pconf.def bin/fmtgen aegis/common.def
+ 	bin/fmtgen -Iaegis aegis/pconf.def aegis/pconf.c aegis/pconf.h
+ 
+ aegis/pconf.o: aegis/pconf.c aegis/pconf.h common/main.h aegis/type.h \
+ 		common/str.h common/s-v-arg.h common/conf.h \
+ 		aegis/parse.h common/error.h aegis/indent.h aegis/io.h \
+ 		common/mem.h aegis/os.h common/trace.h 
+ 	$(CC) $(CFLAGS) -Iaegis -Icommon $(H) -c aegis/pconf.c
+ 	mv pconf.o aegis/pconf.o
+ 
+ aegis/project.o: aegis/project.c aegis/change.h common/main.h \
+ 		aegis/cstate.h aegis/type.h common/str.h \
+ 		common/s-v-arg.h common/conf.h aegis/parse.h \
+ 		aegis/pconf.h aegis/commit.h common/error.h \
+ 		aegis/gonzo.h aegis/gstate.h aegis/lock.h common/mem.h \
+ 		common/option.h aegis/os.h aegis/project.h \
+ 		aegis/pstate.h aegis/pattr.h common/trace.h \
+ 		aegis/user.h aegis/ustate.h aegis/uconf.h aegis/undo.h 
+ 	$(CC) $(CFLAGS)  -Iaegis -Icommon $(H) -c aegis/project.c
+ 	mv project.o aegis/project.o
+ 
+ aegis/pstate.c aegis/pstate.h: aegis/pstate.def bin/fmtgen \
+ 		aegis/pattr.def aegis/common.def 
+ 	bin/fmtgen -Iaegis aegis/pstate.def aegis/pstate.c aegis/pstate.h
+ 
+ aegis/pstate.o: aegis/pstate.c aegis/pstate.h common/main.h \
+ 		aegis/type.h common/str.h common/s-v-arg.h \
+ 		common/conf.h aegis/parse.h common/error.h \
+ 		aegis/indent.h aegis/io.h common/mem.h aegis/os.h \
+ 		common/trace.h 
+ 	$(CC) $(CFLAGS) -Iaegis -Icommon $(H) -c aegis/pstate.c
+ 	mv pstate.o aegis/pstate.o
+ 
+ aegis/rem_file.o: aegis/rem_file.c aegis/arglex2.h common/arglex.h \
+ 		common/main.h aegis/change.h aegis/cstate.h \
+ 		aegis/type.h common/str.h common/s-v-arg.h \
+ 		common/conf.h aegis/parse.h aegis/pconf.h \
+ 		aegis/commit.h common/error.h aegis/help.h aegis/list.h \
+ 		aegis/lock.h aegis/log.h common/option.h aegis/os.h \
+ 		aegis/project.h aegis/pstate.h aegis/pattr.h \
+ 		aegis/rem_file.h common/trace.h aegis/user.h \
+ 		aegis/ustate.h aegis/uconf.h common/word.h 
+ 	$(CC) $(CFLAGS)  -Iaegis -Icommon $(H) -c aegis/rem_file.c
+ 	mv rem_file.o aegis/rem_file.o
+ 
+ aegis/rem_proj.o: aegis/rem_proj.c aegis/arglex2.h common/arglex.h \
+ 		common/main.h aegis/change.h aegis/cstate.h \
+ 		aegis/type.h common/str.h common/s-v-arg.h \
+ 		common/conf.h aegis/parse.h aegis/pconf.h \
+ 		aegis/commit.h common/error.h aegis/gonzo.h \
+ 		aegis/gstate.h aegis/help.h aegis/list.h aegis/lock.h \
+ 		common/option.h aegis/project.h aegis/pstate.h \
+ 		aegis/pattr.h aegis/rem_proj.h common/trace.h \
+ 		aegis/user.h aegis/ustate.h aegis/uconf.h 
+ 	$(CC) $(CFLAGS)  -Iaegis -Icommon $(H) -c aegis/rem_proj.c
+ 	mv rem_proj.o aegis/rem_proj.o
+ 
+ aegis/review.o: aegis/review.c aegis/arglex2.h common/arglex.h \
+ 		common/main.h aegis/change.h aegis/cstate.h \
+ 		aegis/type.h common/str.h common/s-v-arg.h \
+ 		common/conf.h aegis/parse.h aegis/pconf.h \
+ 		aegis/commit.h aegis/dir.h common/error.h aegis/file.h \
+ 		aegis/help.h aegis/list.h aegis/lock.h common/mem.h \
+ 		common/option.h aegis/os.h aegis/project.h \
+ 		aegis/pstate.h aegis/pattr.h aegis/review.h aegis/sub.h \
+ 		common/trace.h aegis/undo.h aegis/user.h aegis/ustate.h \
+ 		aegis/uconf.h 
+ 	$(CC) $(CFLAGS)  -Iaegis -Icommon $(H) -c aegis/review.c
+ 	mv review.o aegis/review.o
+ 
+ aegis/reviewer.o: aegis/reviewer.c aegis/arglex2.h common/arglex.h \
+ 		common/main.h aegis/commit.h common/str.h \
+ 		common/s-v-arg.h common/conf.h common/error.h \
+ 		aegis/help.h aegis/list.h aegis/lock.h common/option.h \
+ 		aegis/os.h aegis/project.h aegis/pstate.h aegis/type.h \
+ 		aegis/parse.h aegis/pattr.h aegis/reviewer.h \
+ 		common/trace.h aegis/user.h aegis/ustate.h \
+ 		aegis/uconf.h common/word.h 
+ 	$(CC) $(CFLAGS)  -Iaegis -Icommon $(H) -c aegis/reviewer.c
+ 	mv reviewer.o aegis/reviewer.o
+ 
+ aegis/sub.o: aegis/sub.c common/arglex.h common/main.h aegis/change.h \
+ 		aegis/cstate.h aegis/type.h common/str.h \
+ 		common/s-v-arg.h common/conf.h aegis/parse.h \
+ 		aegis/pconf.h common/error.h common/mem.h \
+ 		common/option.h aegis/os.h aegis/project.h \
+ 		aegis/pstate.h aegis/pattr.h aegis/sub.h common/trace.h \
+ 		common/word.h 
+ 	$(CC) $(CFLAGS)  -Iaegis -Icommon $(H) -c aegis/sub.c
+ 	mv sub.o aegis/sub.o
+ 
+ aegis/test.o: aegis/test.c aegis/arglex2.h common/arglex.h \
+ 		common/main.h aegis/change.h aegis/cstate.h \
+ 		aegis/type.h common/str.h common/s-v-arg.h \
+ 		common/conf.h aegis/parse.h aegis/pconf.h \
+ 		aegis/commit.h common/error.h aegis/help.h aegis/list.h \
+ 		aegis/lock.h aegis/log.h common/option.h aegis/os.h \
+ 		aegis/project.h aegis/pstate.h aegis/pattr.h \
+ 		aegis/test.h common/trace.h aegis/user.h aegis/ustate.h \
+ 		aegis/uconf.h common/word.h 
+ 	$(CC) $(CFLAGS)  -Iaegis -Icommon $(H) -c aegis/test.c
+ 	mv test.o aegis/test.o
+ 
+ aegis/type.o: aegis/type.c aegis/type.h common/main.h common/str.h \
+ 		common/s-v-arg.h common/conf.h 
+ 	$(CC) $(CFLAGS)  -Iaegis -Icommon $(H) -c aegis/type.c
+ 	mv type.o aegis/type.o
+ 
+ aegis/uconf.c aegis/uconf.h: aegis/uconf.def bin/fmtgen
+ 	bin/fmtgen -Iaegis aegis/uconf.def aegis/uconf.c aegis/uconf.h
+ 
+ aegis/uconf.o: aegis/uconf.c aegis/uconf.h common/main.h aegis/type.h \
+ 		common/str.h common/s-v-arg.h common/conf.h \
+ 		aegis/parse.h common/error.h aegis/indent.h aegis/io.h \
+ 		common/mem.h aegis/os.h common/trace.h 
+ 	$(CC) $(CFLAGS) -Iaegis -Icommon $(H) -c aegis/uconf.c
+ 	mv uconf.o aegis/uconf.o
+ 
+ aegis/undo.o: aegis/undo.c common/error.h common/main.h common/mem.h \
+ 		common/option.h aegis/os.h common/str.h \
+ 		common/s-v-arg.h common/conf.h common/trace.h \
+ 		aegis/undo.h 
+ 	$(CC) $(CFLAGS)  -Iaegis -Icommon $(H) -c aegis/undo.c
+ 	mv undo.o aegis/undo.o
+ 
+ aegis/user.o: aegis/user.c aegis/commit.h common/str.h common/s-v-arg.h \
+ 		common/conf.h common/main.h common/error.h \
+ 		aegis/gonzo.h aegis/gstate.h aegis/type.h aegis/parse.h \
+ 		aegis/lock.h common/mem.h common/option.h aegis/os.h \
+ 		aegis/project.h aegis/pstate.h aegis/pattr.h \
+ 		common/trace.h aegis/user.h aegis/ustate.h \
+ 		aegis/uconf.h aegis/undo.h common/word.h 
+ 	$(CC) $(CFLAGS)  -Iaegis -Icommon $(H) -c aegis/user.c
+ 	mv user.o aegis/user.o
+ 
+ aegis/ustate.c aegis/ustate.h: aegis/ustate.def bin/fmtgen
+ 	bin/fmtgen -Iaegis aegis/ustate.def aegis/ustate.c aegis/ustate.h
+ 
+ aegis/ustate.o: aegis/ustate.c aegis/ustate.h common/main.h \
+ 		aegis/type.h common/str.h common/s-v-arg.h \
+ 		common/conf.h aegis/parse.h common/error.h \
+ 		aegis/indent.h aegis/io.h common/mem.h aegis/os.h \
+ 		common/trace.h 
+ 	$(CC) $(CFLAGS) -Iaegis -Icommon $(H) -c aegis/ustate.c
+ 	mv ustate.o aegis/ustate.o
+ 
+ aegis/version.o: aegis/version.c aegis/arglex2.h common/arglex.h \
+ 		common/main.h common/error.h aegis/help.h \
+ 		common/option.h common/str.h common/s-v-arg.h \
+ 		common/conf.h common/trace.h aegis/version.h 
+ 	$(CC) $(CFLAGS)  -Iaegis -Icommon $(H) -c aegis/version.c
+ 	mv version.o aegis/version.o
+ 
+ common/ansi.o: common/ansi.c common/main.h common/conf.h
+ 	$(CC) $(CFLAGS) -Icommon $(H) -c common/ansi.c
+ 	mv ansi.o common/ansi.o
+ 
+ common/arglex.o: common/arglex.c common/arglex.h common/main.h \
+ 		common/error.h common/option.h common/str.h \
+ 		common/s-v-arg.h common/conf.h common/trace.h 
+ 	$(CC) $(CFLAGS) -Icommon $(H) -c common/arglex.c
+ 	mv arglex.o common/arglex.o
+ 
+ common/error.o: common/error.c common/arglex.h common/main.h \
+ 		common/error.h common/option.h common/s-v-arg.h \
+ 		common/conf.h 
+ 	$(CC) $(CFLAGS) -Icommon $(H) -c common/error.c
+ 	mv error.o common/error.o
+ 
+ common/mem.o: common/mem.c common/main.h common/mem.h common/error.h
+ 	$(CC) $(CFLAGS) -Icommon $(H) -c common/mem.c
+ 	mv mem.o common/mem.o
+ 
+ common/option.o: common/option.c common/error.h common/main.h \
+ 		common/option.h common/trace.h 
+ 	$(CC) $(CFLAGS) -Icommon $(H) -c common/option.c
+ 	mv option.o common/option.o
+ 
+ common/str.o: common/str.c common/error.h common/main.h common/mem.h \
+ 		common/s-v-arg.h common/conf.h common/str.h 
+ 	$(CC) $(CFLAGS) -Icommon $(H) -c common/str.c
+ 	mv str.o common/str.o
+ 
+ common/trace.o: common/trace.c common/error.h common/main.h \
+ 		common/mem.h common/option.h common/s-v-arg.h \
+ 		common/conf.h common/str.h common/trace.h 
+ 	$(CC) $(CFLAGS) -Icommon $(H) -c common/trace.c
+ 	mv trace.o common/trace.o
+ 
+ common/word.o: common/word.c common/main.h common/word.h common/str.h \
+ 		common/s-v-arg.h common/conf.h common/error.h \
+ 		common/mem.h 
+ 	$(CC) $(CFLAGS) -Icommon $(H) -c common/word.c
+ 	mv word.o common/word.o
+ 
+ fmtgen/id.o: fmtgen/id.c common/main.h fmtgen/id.h common/str.h \
+ 		common/s-v-arg.h common/conf.h common/word.h \
+ 		common/mem.h common/error.h 
+ 	$(CC) $(CFLAGS) -Ifmtgen -Icommon $(H) -c fmtgen/id.c
+ 	mv id.o fmtgen/id.o
+ 
+ fmtgen/indent.o: fmtgen/indent.c common/error.h common/main.h \
+ 		fmtgen/indent.h common/s-v-arg.h common/conf.h \
+ 		common/trace.h 
+ 	$(CC) $(CFLAGS) -Ifmtgen -Icommon $(H) -c fmtgen/indent.c
+ 	mv indent.o fmtgen/indent.o
+ 
+ fmtgen/lex.o: fmtgen/lex.c common/error.h common/main.h fmtgen/id.h \
+ 		common/str.h common/s-v-arg.h common/conf.h \
+ 		common/word.h fmtgen/lex.h common/mem.h fmtgen/type.h \
+ 		fmtgen/parse.gen.h 
+ 	$(CC) $(CFLAGS) -Ifmtgen -Icommon $(H) -c fmtgen/lex.c
+ 	mv lex.o fmtgen/lex.o
+ 
+ fmtgen/main.o: fmtgen/main.c common/arglex.h common/main.h \
+ 		common/error.h fmtgen/id.h common/str.h \
+ 		common/s-v-arg.h common/conf.h common/word.h \
+ 		fmtgen/lex.h common/option.h fmtgen/parse.h \
+ 		common/trace.h 
+ 	$(CC) $(CFLAGS) -Ifmtgen -Icommon $(H) -c fmtgen/main.c
+ 	mv main.o fmtgen/main.o
+ 
+ fmtgen/parse.gen.c fmtgen/parse.gen.h: fmtgen/parse.y
+ 	$(YACC) -d fmtgen/parse.y
+ 	sed "s/[yY][yY]/parse_/g" < y.tab.c > fmtgen/parse.gen.c
+ 	rm y.tab.c
+ 	sed "s/[yY][yY]/parse_/g" < y.tab.h > fmtgen/parse.gen.h
+ 	rm y.tab.h
+ 
+ fmtgen/parse.gen.o: fmtgen/parse.gen.c common/error.h common/main.h \
+ 		fmtgen/id.h common/str.h common/s-v-arg.h common/conf.h \
+ 		common/word.h fmtgen/indent.h fmtgen/lex.h common/mem.h \
+ 		fmtgen/parse.h common/trace.h fmtgen/type.h 
+ 	$(CC) $(CFLAGS) -Ifmtgen -Icommon $(H) -c fmtgen/parse.gen.c
+ 	mv parse.gen.o fmtgen/parse.gen.o
+ 
+ fmtgen/type.o: fmtgen/type.c fmtgen/type.h common/main.h fmtgen/lex.h \
+ 		common/str.h common/s-v-arg.h common/conf.h 
+ 	$(CC) $(CFLAGS) -Ifmtgen -Icommon $(H) -c fmtgen/type.c
+ 	mv type.o fmtgen/type.o
+ 
+ fmtgen/type_enum.o: fmtgen/type_enum.c fmtgen/type.h common/main.h \
+ 		fmtgen/lex.h common/str.h common/s-v-arg.h \
+ 		common/conf.h fmtgen/indent.h fmtgen/id.h common/word.h \
+ 		common/mem.h 
+ 	$(CC) $(CFLAGS) -Ifmtgen -Icommon $(H) -c fmtgen/type_enum.c
+ 	mv type_enum.o fmtgen/type_enum.o
+ 
+ fmtgen/type_integ.o: fmtgen/type_integ.c fmtgen/type.h common/main.h \
+ 		fmtgen/lex.h common/str.h common/s-v-arg.h \
+ 		common/conf.h fmtgen/indent.h common/mem.h 
+ 	$(CC) $(CFLAGS) -Ifmtgen -Icommon $(H) -c fmtgen/type_integ.c
+ 	mv type_integ.o fmtgen/type_integ.o
+ 
+ fmtgen/type_list.o: fmtgen/type_list.c fmtgen/type.h common/main.h \
+ 		fmtgen/lex.h common/str.h common/s-v-arg.h \
+ 		common/conf.h fmtgen/indent.h common/mem.h fmtgen/id.h \
+ 		common/word.h 
+ 	$(CC) $(CFLAGS) -Ifmtgen -Icommon $(H) -c fmtgen/type_list.c
+ 	mv type_list.o fmtgen/type_list.o
+ 
+ fmtgen/type_ref.o: fmtgen/type_ref.c fmtgen/type.h common/main.h \
+ 		fmtgen/lex.h common/str.h common/s-v-arg.h \
+ 		common/conf.h fmtgen/indent.h common/mem.h fmtgen/id.h \
+ 		common/word.h common/error.h 
+ 	$(CC) $(CFLAGS) -Ifmtgen -Icommon $(H) -c fmtgen/type_ref.c
+ 	mv type_ref.o fmtgen/type_ref.o
+ 
+ fmtgen/type_strin.o: fmtgen/type_strin.c fmtgen/type.h common/main.h \
+ 		fmtgen/lex.h common/str.h common/s-v-arg.h \
+ 		common/conf.h fmtgen/indent.h common/mem.h 
+ 	$(CC) $(CFLAGS) -Ifmtgen -Icommon $(H) -c fmtgen/type_strin.c
+ 	mv type_strin.o fmtgen/type_strin.o
+ 
+ fmtgen/type_struc.o: fmtgen/type_struc.c fmtgen/type.h common/main.h \
+ 		fmtgen/lex.h common/str.h common/s-v-arg.h \
+ 		common/conf.h fmtgen/indent.h common/mem.h fmtgen/id.h \
+ 		common/word.h common/error.h 
+ 	$(CC) $(CFLAGS) -Ifmtgen -Icommon $(H) -c fmtgen/type_struc.c
+ 	mv type_struc.o fmtgen/type_struc.o
+ 
+ t0001a: all test/00/t0001a.sh
+ 	$(SHELL) test/00/t0001a.sh
+ 
+ t0002a: all test/00/t0002a.sh
+ 	$(SHELL) test/00/t0002a.sh
+ 
+ t0003a: all test/00/t0003a.sh
+ 	$(SHELL) test/00/t0003a.sh
+ 
+ t0004a: all test/00/t0004a.sh
+ 	$(SHELL) test/00/t0004a.sh
+ 
+ t0005a: all test/00/t0005a.sh
+ 	$(SHELL) test/00/t0005a.sh
+ 
+ t0006a: all test/00/t0006a.sh
+ 	$(SHELL) test/00/t0006a.sh
+ 
+ t0007a: all test/00/t0007a.sh
+ 	$(SHELL) test/00/t0007a.sh
+ 
+ t0008a: all test/00/t0008a.sh
+ 	$(SHELL) test/00/t0008a.sh
+ 
+ t0009a: all test/00/t0009a.sh
+ 	$(SHELL) test/00/t0009a.sh
+ 
+ t0010a: all test/00/t0010a.sh
+ 	$(SHELL) test/00/t0010a.sh
+ 
+ t0011a: all test/00/t0011a.sh
+ 	$(SHELL) test/00/t0011a.sh
+ 
+ t0012a: all test/00/t0012a.sh
+ 	$(SHELL) test/00/t0012a.sh
+ 
+ t0013a: all test/00/t0013a.sh
+ 	$(SHELL) test/00/t0013a.sh
+ 
+ t0014a: all test/00/t0014a.sh
+ 	$(SHELL) test/00/t0014a.sh
+ 
+ t0015a: all test/00/t0015a.sh
+ 	$(SHELL) test/00/t0015a.sh
+ 
+ clean:
+ 	rm -f core bin/fmtgen aegis/administ.o aegis/build.o \
+ 		aegis/cattr.c aegis/cattr.h aegis/cattr.o \
+ 		aegis/cattr_ed.o aegis/change.o aegis/chdir.o \
+ 		aegis/col.o aegis/commit.o aegis/common.c \
+ 		aegis/common.h aegis/common.o aegis/copyfile.o \
+ 		aegis/cstate.c aegis/cstate.h aegis/cstate.o \
+ 		aegis/develop1.o aegis/develop2.o aegis/diff.o \
+ 		aegis/dir.o aegis/file.o aegis/glue.o aegis/gonzo.o \
+ 		aegis/gram.gen.c aegis/gram.gen.h aegis/gram.gen.o \
+ 		aegis/gstate.c aegis/gstate.h aegis/gstate.o \
+ 		aegis/help.o aegis/indent.o aegis/integra1.o \
+ 		aegis/integra2.o aegis/io.o aegis/lex.o aegis/list.o \
+ 		aegis/lock.o aegis/log.o aegis/main.o aegis/new_chan.o \
+ 		aegis/new_file.o aegis/new_proj.o aegis/new_rele.o \
+ 		aegis/new_test.o aegis/os.o aegis/pager.o aegis/parse.o \
+ 		aegis/pattr.c aegis/pattr.h aegis/pattr.o \
+ 		aegis/pattr_ed.o aegis/pconf.c aegis/pconf.h \
+ 		aegis/pconf.o aegis/project.o aegis/pstate.c \
+ 		aegis/pstate.h aegis/pstate.o aegis/rem_file.o \
+ 		aegis/rem_proj.o aegis/review.o aegis/reviewer.o \
+ 		aegis/sub.o aegis/test.o aegis/type.o aegis/uconf.c \
+ 		aegis/uconf.h aegis/uconf.o aegis/undo.o aegis/user.o \
+ 		aegis/ustate.c aegis/ustate.h aegis/ustate.o \
+ 		aegis/version.o common/ansi.o common/arglex.o \
+ 		common/error.o common/mem.o common/option.o \
+ 		common/str.o common/trace.o common/word.o fmtgen/id.o \
+ 		fmtgen/indent.o fmtgen/lex.o fmtgen/main.o \
+ 		fmtgen/parse.gen.c fmtgen/parse.gen.h \
+ 		fmtgen/parse.gen.o fmtgen/type.o fmtgen/type_enum.o \
+ 		fmtgen/type_integ.o fmtgen/type_list.o \
+ 		fmtgen/type_ref.o fmtgen/type_strin.o \
+ 		fmtgen/type_struc.o 
+ 
+ realclean: clean
+ 	rm -f bin/aegis
+ 
+ clobber: realclean
+ 	rm -f common/conf.h
+ 
+ common/conf.h:
+ 	echo "#include <../conf/`uname -s`-`uname -r`>" > common/conf.h
+ 
+ FmtgenFiles = common/ansi.o common/arglex.o common/error.o common/mem.o \
+ 		common/option.o common/str.o common/trace.o \
+ 		common/word.o fmtgen/id.o fmtgen/indent.o fmtgen/lex.o \
+ 		fmtgen/main.o fmtgen/parse.gen.o fmtgen/type.o \
+ 		fmtgen/type_enum.o fmtgen/type_integ.o \
+ 		fmtgen/type_list.o fmtgen/type_ref.o \
+ 		fmtgen/type_strin.o fmtgen/type_struc.o 
+ 
+ bin/fmtgen: $(FmtgenFiles)
+ 	if test ! -d bin; then mkdir bin; fi; exit 0
+ 	$(CC) -o bin/fmtgen $(FmtgenFiles) $(LIBRARIES)
+ 
+ AegisFiles = aegis/administ.o aegis/build.o aegis/cattr.o \
+ 		aegis/cattr_ed.o aegis/change.o aegis/chdir.o \
+ 		aegis/col.o aegis/commit.o aegis/common.o \
+ 		aegis/copyfile.o aegis/cstate.o aegis/develop1.o \
+ 		aegis/develop2.o aegis/diff.o aegis/dir.o aegis/file.o \
+ 		aegis/glue.o aegis/gonzo.o aegis/gram.gen.o \
+ 		aegis/gstate.o aegis/help.o aegis/indent.o \
+ 		aegis/integra1.o aegis/integra2.o aegis/io.o \
+ 		aegis/lex.o aegis/list.o aegis/lock.o aegis/log.o \
+ 		aegis/main.o aegis/new_chan.o aegis/new_file.o \
+ 		aegis/new_proj.o aegis/new_rele.o aegis/new_test.o \
+ 		aegis/os.o aegis/pager.o aegis/parse.o aegis/pattr.o \
+ 		aegis/pattr_ed.o aegis/pconf.o aegis/project.o \
+ 		aegis/pstate.o aegis/rem_file.o aegis/rem_proj.o \
+ 		aegis/review.o aegis/reviewer.o aegis/sub.o \
+ 		aegis/test.o aegis/type.o aegis/uconf.o aegis/undo.o \
+ 		aegis/user.o aegis/ustate.o aegis/version.o \
+ 		common/ansi.o common/arglex.o common/error.o \
+ 		common/mem.o common/option.o common/str.o \
+ 		common/trace.o common/word.o 
+ 
+ bin/aegis: $(AegisFiles)
+ 	if test ! -d bin; then mkdir bin; fi; exit 0
+ 	$(CC) -o bin/aegis $(AegisFiles) $(LIBRARIES)
+ 
+ sure: t0001a t0002a t0003a t0004a t0005a t0006a t0007a t0008a t0009a \
+ 		t0010a t0011a t0012a t0013a t0014a t0015a 
+ 	@echo Passed All Tests
+ 
+ install: all
+ 	cp bin/aegis $(BIN)
+ 	chown root $(BIN)/aegis
+ 	chmod a+x,u+s $(BIN)/aegis
+ 	-mkdir $(LIB)
+ 	chmod 0755 $(LIB)
+ 	cp lib/* $(LIB)
+ 	chmod a+r $(LIB)/*
+ 	chmod a+x $(LIB)/*.sh
+ 	chown bin $(LIB)
+ 	chgrp bin $(LIB)
+ 	$(SHELL) man1/install.sh $(MAN)/man1
+ 	$(SHELL) man5/install.sh $(MAN)/man5
Index: LICENSE
***************
*** 0 ****
--- 1,339 ----
+ 		    GNU GENERAL PUBLIC LICENSE
+ 		       Version 2, June 1991
+ 
+  Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+                           675 Mass Ave, Cambridge, MA 02139, USA
+  Everyone is permitted to copy and distribute verbatim copies
+  of this license document, but changing it is not allowed.
+ 
+ 			    Preamble
+ 
+   The licenses for most software are designed to take away your
+ freedom to share and change it.  By contrast, the GNU General Public
+ License is intended to guarantee your freedom to share and change free
+ software--to make sure the software is free for all its users.  This
+ General Public License applies to most of the Free Software
+ Foundation's software and to any other program whose authors commit to
+ using it.  (Some other Free Software Foundation software is covered by
+ the GNU Library General Public License instead.)  You can apply it to
+ your programs, too.
+ 
+   When we speak of free software, we are referring to freedom, not
+ price.  Our General Public Licenses are designed to make sure that you
+ have the freedom to distribute copies of free software (and charge for
+ this service if you wish), that you receive source code or can get it
+ if you want it, that you can change the software or use pieces of it
+ in new free programs; and that you know you can do these things.
+ 
+   To protect your rights, we need to make restrictions that forbid
+ anyone to deny you these rights or to ask you to surrender the rights.
+ These restrictions translate to certain responsibilities for you if you
+ distribute copies of the software, or if you modify it.
+ 
+   For example, if you distribute copies of such a program, whether
+ gratis or for a fee, you must give the recipients all the rights that
+ you have.  You must make sure that they, too, receive or can get the
+ source code.  And you must show them these terms so they know their
+ rights.
+ 
+   We protect your rights with two steps: (1) copyright the software, and
+ (2) offer you this license which gives you legal permission to copy,
+ distribute and/or modify the software.
+ 
+   Also, for each author's protection and ours, we want to make certain
+ that everyone understands that there is no warranty for this free
+ software.  If the software is modified by someone else and passed on, we
+ want its recipients to know that what they have is not the original, so
+ that any problems introduced by others will not reflect on the original
+ authors' reputations.
+ 
+   Finally, any free program is threatened constantly by software
+ patents.  We wish to avoid the danger that redistributors of a free
+ program will individually obtain patent licenses, in effect making the
+ program proprietary.  To prevent this, we have made it clear that any
+ patent must be licensed for everyone's free use or not licensed at all.
+ 
+   The precise terms and conditions for copying, distribution and
+ modification follow.
+ 
+ 		    GNU GENERAL PUBLIC LICENSE
+    TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+ 
+   0. This License applies to any program or other work which contains
+ a notice placed by the copyright holder saying it may be distributed
+ under the terms of this General Public License.  The "Program", below,
+ refers to any such program or work, and a "work based on the Program"
+ means either the Program or any derivative work under copyright law:
+ that is to say, a work containing the Program or a portion of it,
+ either verbatim or with modifications and/or translated into another
+ language.  (Hereinafter, translation is included without limitation in
+ the term "modification".)  Each licensee is addressed as "you".
+ 
+ Activities other than copying, distribution and modification are not
+ covered by this License; they are outside its scope.  The act of
+ running the Program is not restricted, and the output from the Program
+ is covered only if its contents constitute a work based on the
+ Program (independent of having been made by running the Program).
+ Whether that is true depends on what the Program does.
+ 
+   1. You may copy and distribute verbatim copies of the Program's
+ source code as you receive it, in any medium, provided that you
+ conspicuously and appropriately publish on each copy an appropriate
+ copyright notice and disclaimer of warranty; keep intact all the
+ notices that refer to this License and to the absence of any warranty;
+ and give any other recipients of the Program a copy of this License
+ along with the Program.
+ 
+ You may charge a fee for the physical act of transferring a copy, and
+ you may at your option offer warranty protection in exchange for a fee.
+ 
+   2. You may modify your copy or copies of the Program or any portion
+ of it, thus forming a work based on the Program, and copy and
+ distribute such modifications or work under the terms of Section 1
+ above, provided that you also meet all of these conditions:
+ 
+     a) You must cause the modified files to carry prominent notices
+     stating that you changed the files and the date of any change.
+ 
+     b) You must cause any work that you distribute or publish, that in
+     whole or in part contains or is derived from the Program or any
+     part thereof, to be licensed as a whole at no charge to all third
+     parties under the terms of this License.
+ 
+     c) If the modified program normally reads commands interactively
+     when run, you must cause it, when started running for such
+     interactive use in the most ordinary way, to print or display an
+     announcement including an appropriate copyright notice and a
+     notice that there is no warranty (or else, saying that you provide
+     a warranty) and that users may redistribute the program under
+     these conditions, and telling the user how to view a copy of this
+     License.  (Exception: if the Program itself is interactive but
+     does not normally print such an announcement, your work based on
+     the Program is not required to print an announcement.)
+ 
+ These requirements apply to the modified work as a whole.  If
+ identifiable sections of that work are not derived from the Program,
+ and can be reasonably considered independent and separate works in
+ themselves, then this License, and its terms, do not apply to those
+ sections when you distribute them as separate works.  But when you
+ distribute the same sections as part of a whole which is a work based
+ on the Program, the distribution of the whole must be on the terms of
+ this License, whose permissions for other licensees extend to the
+ entire whole, and thus to each and every part regardless of who wrote it.
+ 
+ Thus, it is not the intent of this section to claim rights or contest
+ your rights to work written entirely by you; rather, the intent is to
+ exercise the right to control the distribution of derivative or
+ collective works based on the Program.
+ 
+ In addition, mere aggregation of another work not based on the Program
+ with the Program (or with a work based on the Program) on a volume of
+ a storage or distribution medium does not bring the other work under
+ the scope of this License.
+ 
+   3. You may copy and distribute the Program (or a work based on it,
+ under Section 2) in object code or executable form under the terms of
+ Sections 1 and 2 above provided that you also do one of the following:
+ 
+     a) Accompany it with the complete corresponding machine-readable
+     source code, which must be distributed under the terms of Sections
+     1 and 2 above on a medium customarily used for software interchange; or,
+ 
+     b) Accompany it with a written offer, valid for at least three
+     years, to give any third party, for a charge no more than your
+     cost of physically performing source distribution, a complete
+     machine-readable copy of the corresponding source code, to be
+     distributed under the terms of Sections 1 and 2 above on a medium
+     customarily used for software interchange; or,
+ 
+     c) Accompany it with the information you received as to the offer
+     to distribute corresponding source code.  (This alternative is
+     allowed only for noncommercial distribution and only if you
+     received the program in object code or executable form with such
+     an offer, in accord with Subsection b above.)
+ 
+ The source code for a work means the preferred form of the work for
+ making modifications to it.  For an executable work, complete source
+ code means all the source code for all modules it contains, plus any
+ associated interface definition files, plus the scripts used to
+ control compilation and installation of the executable.  However, as a
+ special exception, the source code distributed need not include
+ anything that is normally distributed (in either source or binary
+ form) with the major components (compiler, kernel, and so on) of the
+ operating system on which the executable runs, unless that component
+ itself accompanies the executable.
+ 
+ If distribution of executable or object code is made by offering
+ access to copy from a designated place, then offering equivalent
+ access to copy the source code from the same place counts as
+ distribution of the source code, even though third parties are not
+ compelled to copy the source along with the object code.
+ 
+   4. You may not copy, modify, sublicense, or distribute the Program
+ except as expressly provided under this License.  Any attempt
+ otherwise to copy, modify, sublicense or distribute the Program is
+ void, and will automatically terminate your rights under this License.
+ However, parties who have received copies, or rights, from you under
+ this License will not have their licenses terminated so long as such
+ parties remain in full compliance.
+ 
+   5. You are not required to accept this License, since you have not
+ signed it.  However, nothing else grants you permission to modify or
+ distribute the Program or its derivative works.  These actions are
+ prohibited by law if you do not accept this License.  Therefore, by
+ modifying or distributing the Program (or any work based on the
+ Program), you indicate your acceptance of this License to do so, and
+ all its terms and conditions for copying, distributing or modifying
+ the Program or works based on it.
+ 
+   6. Each time you redistribute the Program (or any work based on the
+ Program), the recipient automatically receives a license from the
+ original licensor to copy, distribute or modify the Program subject to
+ these terms and conditions.  You may not impose any further
+ restrictions on the recipients' exercise of the rights granted herein.
+ You are not responsible for enforcing compliance by third parties to
+ this License.
+ 
+   7. If, as a consequence of a court judgment or allegation of patent
+ infringement or for any other reason (not limited to patent issues),
+ conditions are imposed on you (whether by court order, agreement or
+ otherwise) that contradict the conditions of this License, they do not
+ excuse you from the conditions of this License.  If you cannot
+ distribute so as to satisfy simultaneously your obligations under this
+ License and any other pertinent obligations, then as a consequence you
+ may not distribute the Program at all.  For example, if a patent
+ license would not permit royalty-free redistribution of the Program by
+ all those who receive copies directly or indirectly through you, then
+ the only way you could satisfy both it and this License would be to
+ refrain entirely from distribution of the Program.
+ 
+ If any portion of this section is held invalid or unenforceable under
+ any particular circumstance, the balance of the section is intended to
+ apply and the section as a whole is intended to apply in other
+ circumstances.
+ 
+ It is not the purpose of this section to induce you to infringe any
+ patents or other property right claims or to contest validity of any
+ such claims; this section has the sole purpose of protecting the
+ integrity of the free software distribution system, which is
+ implemented by public license practices.  Many people have made
+ generous contributions to the wide range of software distributed
+ through that system in reliance on consistent application of that
+ system; it is up to the author/donor to decide if he or she is willing
+ to distribute software through any other system and a licensee cannot
+ impose that choice.
+ 
+ This section is intended to make thoroughly clear what is believed to
+ be a consequence of the rest of this License.
+ 
+   8. If the distribution and/or use of the Program is restricted in
+ certain countries either by patents or by copyrighted interfaces, the
+ original copyright holder who places the Program under this License
+ may add an explicit geographical distribution limitation excluding
+ those countries, so that distribution is permitted only in or among
+ countries not thus excluded.  In such case, this License incorporates
+ the limitation as if written in the body of this License.
+ 
+   9. The Free Software Foundation may publish revised and/or new versions
+ of the General Public License from time to time.  Such new versions will
+ be similar in spirit to the present version, but may differ in detail to
+ address new problems or concerns.
+ 
+ Each version is given a distinguishing version number.  If the Program
+ specifies a version number of this License which applies to it and "any
+ later version", you have the option of following the terms and conditions
+ either of that version or of any later version published by the Free
+ Software Foundation.  If the Program does not specify a version number of
+ this License, you may choose any version ever published by the Free Software
+ Foundation.
+ 
+   10. If you wish to incorporate parts of the Program into other free
+ programs whose distribution conditions are different, write to the author
+ to ask for permission.  For software which is copyrighted by the Free
+ Software Foundation, write to the Free Software Foundation; we sometimes
+ make exceptions for this.  Our decision will be guided by the two goals
+ of preserving the free status of all derivatives of our free software and
+ of promoting the sharing and reuse of software generally.
+ 
+ 			    NO WARRANTY
+ 
+   11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+ FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+ OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+ PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+ OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+ TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+ PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+ REPAIR OR CORRECTION.
+ 
+   12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+ WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+ REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+ INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+ OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+ TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+ YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+ PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGES.
+ 
+ 		     END OF TERMS AND CONDITIONS
+ 
+ 	Appendix: How to Apply These Terms to Your New Programs
+ 
+   If you develop a new program, and you want it to be of the greatest
+ possible use to the public, the best way to achieve this is to make it
+ free software which everyone can redistribute and change under these terms.
+ 
+   To do so, attach the following notices to the program.  It is safest
+ to attach them to the start of each source file to most effectively
+ convey the exclusion of warranty; and each file should have at least
+ the "copyright" line and a pointer to where the full notice is found.
+ 
+     <one line to give the program's name and a brief idea of what it does.>
+     Copyright (C) 19yy  <name of author>
+ 
+     This program is free software; you can redistribute it and/or modify
+     it under the terms of the GNU General Public License as published by
+     the Free Software Foundation; either version 2 of the License, or
+     (at your option) any later version.
+ 
+     This program is distributed in the hope that it will be useful,
+     but WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+     GNU General Public License for more details.
+ 
+     You should have received a copy of the GNU General Public License
+     along with this program; if not, write to the Free Software
+     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ 
+ Also add information on how to contact you by electronic and paper mail.
+ 
+ If the program is interactive, make it output a short notice like this
+ when it starts in an interactive mode:
+ 
+     Gnomovision version 69, Copyright (C) 19yy name of author
+     Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+     This is free software, and you are welcome to redistribute it
+     under certain conditions; type `show c' for details.
+ 
+ The hypothetical commands `show w' and `show c' should show the appropriate
+ parts of the General Public License.  Of course, the commands you use may
+ be called something other than `show w' and `show c'; they could even be
+ mouse-clicks or menu items--whatever suits your program.
+ 
+ You should also get your employer (if you work as a programmer) or your
+ school, if any, to sign a "copyright disclaimer" for the program, if
+ necessary.  Here is a sample; alter the names:
+ 
+   Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+   `Gnomovision' (which makes passes at compilers) written by James Hacker.
+ 
+   <signature of Ty Coon>, 1 April 1989
+   Ty Coon, President of Vice
+ 
+ This General Public License does not permit incorporating your program into
+ proprietary programs.  If your program is a subroutine library, you may
+ consider it more useful to permit linking proprietary applications with the
+ library.  If this is what you want to do, use the GNU Library General
+ Public License instead of this License.
Index: aegis/administ.c
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 87,100 ****
  "",
  "	-Project <name>",
  "		This option may be used to select the project of",
! "		interest.  When no -Project option is specified, if",
! "		the user is only working on changes within a single",
! "		project, the project name defaults to that project;",
! "		if the user is currently working on changes to more",
! "		than one project, or is not working on changes to",
! "		any project, the user's $HOME/.%src file is",
! "		examined for a default project field (see aeuconf(5)",
! "		for more information).",
  "",
  "	-TERse",
  "		This option may be used to cause listings to",
--- 87,100 ----
  "",
  "	-Project <name>",
  "		This option may be used to select the project of",
! "		interest.  When no -Project option is specified, the",
! "		AEGIS_PROJECT environment variable is consulted.  If",
! "		that does not exist, the user's $HOME/.aegisrc file",
! "		is examined for a default project field (see",
! "		aeuconf(5) for more information).  If that does not",
! "		exist, when the user is only working on changes",
! "		within a single project, the project name defaults",
! "		to that project.  Otherwise, it is an error.",
  "",
  "	-TERse",
  "		This option may be used to cause listings to",
***************
*** 108,118 ****
  "		option this option causes column headings to be",
  "		added.",
  "",
! "	All options are case insensitive.  Options may be",
! "	abbreviated; the abbreviation is the upper case letters.",
  "	Options and other command line arguments may be mixed",
! "	arbitrarily on the command line.",
  "",
  "RECOMMENDED ALIAS",
  "	The recommended alias for this command is",
  "	csh%%	alias aena '%s -na \\!* -v'",
--- 108,136 ----
  "		option this option causes column headings to be",
  "		added.",
  "",
! "	All options may be abbreviated; the abbreviation is",
! "	documented as the upper case letters, all lower case",
! "	letters and underscores (_) are optional.  You must use",
! "	consecutive sequences of optional letters.",
! "",
! "	All options are case insensitive, you may type them in",
! "	upper case or lower case or a combination of both, case",
! "	is not important.",
! "",
! "	For example: the arguments \"-project, \"-PROJ\" and \"-p\"",
! "	are all interpreted to mean the -Project option.  The",
! "	argument \"-prj\" will not be understood, because",
! "	consecutive optional characters were not supplied.",
! "",
  "	Options and other command line arguments may be mixed",
! "	arbitrarily on the command line, after the function",
! "	selectors.",
  "",
+ "	The GNU long option names are understood.  Since all",
+ "	option names for aegis are long, this means ignoring the",
+ "	extra leading '-'.  The \"--option=value\" convention is",
+ "	also understood.",
+ "",
  "RECOMMENDED ALIAS",
  "	The recommended alias for this command is",
  "	csh%%	alias aena '%s -na \\!* -v'",
***************
*** 145,151 ****
  static void
  administrator_list()
  {
! 	string_t	*project_name;
  
  	trace(("administrator_list()\n{\n"/*}*/));
  	arglex();
--- 163,169 ----
  static void
  administrator_list()
  {
! 	string_ty	*project_name;
  
  	trace(("administrator_list()\n{\n"/*}*/));
  	arglex();
***************
*** 181,192 ****
  new_administrator_main()
  {
  	wlist		wl;
! 	string_t	*s1;
  	pstate		pstate_data;
  	int		j;
! 	string_t	*project_name;
! 	project_t	*pp;
! 	user_t		*up;
  
  	trace(("new_administrator_main()\n{\n"/*}*/));
  	wl_zero(&wl);
--- 199,210 ----
  new_administrator_main()
  {
  	wlist		wl;
! 	string_ty	*s1;
  	pstate		pstate_data;
  	int		j;
! 	string_ty	*project_name;
! 	project_ty	*pp;
! 	user_ty		*up;
  
  	trace(("new_administrator_main()\n{\n"/*}*/));
  	wl_zero(&wl);
***************
*** 259,265 ****
  	 */
  	for (j = 0; j < wl.wl_nwords; ++j)
  	{
! 		user_t		*candidate;
  
  		/*
  		 * make sure the user isn't already there
--- 277,283 ----
  	 */
  	for (j = 0; j < wl.wl_nwords; ++j)
  	{
! 		user_ty		*candidate;
  
  		/*
  		 * make sure the user isn't already there
***************
*** 413,423 ****
  "		option this option causes column headings to be",
  "		added.",
  "",
! "	All options are case insensitive.  Options may be",
! "	abbreviated; the abbreviation is the upper case letters.",
  "	Options and other command line arguments may be mixed",
! "	arbitrarily on the command line.",
  "",
  "RECOMMENDED ALIAS",
  "	The recommended alias for this command is",
  "	csh%%	alias aera '%s -ra \\!* -v'",
--- 431,459 ----
  "		option this option causes column headings to be",
  "		added.",
  "",
! "	All options may be abbreviated; the abbreviation is",
! "	documented as the upper case letters, all lower case",
! "	letters and underscores (_) are optional.  You must use",
! "	consecutive sequences of optional letters.",
! "",
! "	All options are case insensitive, you may type them in",
! "	upper case or lower case or a combination of both, case",
! "	is not important.",
! "",
! "	For example: the arguments \"-project, \"-PROJ\" and \"-p\"",
! "	are all interpreted to mean the -Project option.  The",
! "	argument \"-prj\" will not be understood, because",
! "	consecutive optional characters were not supplied.",
! "",
  "	Options and other command line arguments may be mixed",
! "	arbitrarily on the command line, after the function",
! "	selectors.",
  "",
+ "	The GNU long option names are understood.  Since all",
+ "	option names for aegis are long, this means ignoring the",
+ "	extra leading '-'.  The \"--option=value\" convention is",
+ "	also understood.",
+ "",
  "RECOMMENDED ALIAS",
  "	The recommended alias for this command is",
  "	csh%%	alias aera '%s -ra \\!* -v'",
***************
*** 452,463 ****
  remove_administrator_main()
  {
  	wlist		wl;
! 	string_t	*s1;
  	pstate		pstate_data;
  	int		j;
! 	string_t	*project_name;
! 	project_t	*pp;
! 	user_t		*up;
  
  	trace(("remove_administrator_main()\n{\n"/*}*/));
  	wl_zero(&wl);
--- 488,499 ----
  remove_administrator_main()
  {
  	wlist		wl;
! 	string_ty	*s1;
  	pstate		pstate_data;
  	int		j;
! 	string_ty	*project_name;
! 	project_ty	*pp;
! 	user_ty		*up;
  
  	trace(("remove_administrator_main()\n{\n"/*}*/));
  	wl_zero(&wl);
***************
*** 530,536 ****
  	 */
  	for (j = 0; j < wl.wl_nwords; ++j)
  	{
! 		user_t	*candidate;
  
  		candidate = user_symbolic(pp, wl.wl_word[j]);
  		if (!project_administrator_query(pp, user_name(candidate)))
--- 566,572 ----
  	 */
  	for (j = 0; j < wl.wl_nwords; ++j)
  	{
! 		user_ty	*candidate;
  
  		candidate = user_symbolic(pp, wl.wl_word[j]);
  		if (!project_administrator_query(pp, user_name(candidate)))
Index: aegis/administ.h
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
Index: aegis/arglex2.h
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
Index: aegis/build.c
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 118,131 ****
  "	the project account for instance, in order to do an",
  "	integration.",
  "",
  "OPTIONS",
  "	The following options are understood:",
  "",
  "	-Change <number>",
  "		This option may be used to specify a particular",
! "		change within a project.  If the user is only",
! "		working on one change within a project, that is",
! "		the default change number.",
  "",
  "	-Help",
  "		This option may be used to obtain more",
--- 118,144 ----
  "	the project account for instance, in order to do an",
  "	integration.",
  "",
+ "	While there is a build in progress for any change in a",
+ "	project, an integrate pass for the project will wait until",
+ "	all the builds are completed before starting.  This is to",
+ "	ensure that the baseline is consistent for the entire build.",
+ "	Similarly, while an integrate pass is in progress for a",
+ "	project, any builds will wait until it is completed before",
+ "	starting.",
+ "",
  "OPTIONS",
  "	The following options are understood:",
  "",
  "	-Change <number>",
  "		This option may be used to specify a particular",
! "		change within a project.  When no -Change option is",
! "		specified, the AEGIS_CHANGE environment variable is",
! "		consulted.  If that does not exist, the user's",
! "		$HOME/.aegisrc file is examined for a default change",
! "		field (see aeuconf(5) for more information).  If",
! "		that does not exist, when the user is only working",
! "		on one change within a project, that is the default",
! "		change number.  Otherwise, it is an error.",
  "",
  "	-Help",
  "		This option may be used to obtain more",
***************
*** 138,151 ****
  "",
  "	-Project <name>",
  "		This option may be used to select the project of",
! "		interest.  When no -Project option is specified, if",
! "		the user is only working on changes within a single",
! "		project, the project name defaults to that project;",
! "		if the user is currently working on changes to more",
! "		than one project, or is not working on changes to",
! "		any project, the user's $HOME/.%src file is",
! "		examined for a default project field (see aeuconf(5)",
! "		for more information).",
  "",
  "	-TERse",
  "		This option may be used to cause listings to",
--- 151,164 ----
  "",
  "	-Project <name>",
  "		This option may be used to select the project of",
! "		interest.  When no -Project option is specified, the",
! "		AEGIS_PROJECT environment variable is consulted.  If",
! "		that does not exist, the user's $HOME/.aegisrc file",
! "		is examined for a default project field (see",
! "		aeuconf(5) for more information).  If that does not",
! "		exist, when the user is only working on changes",
! "		within a single project, the project name defaults",
! "		to that project.  Otherwise, it is an error.",
  "",
  "	-TERse",
  "		This option may be used to cause listings to",
***************
*** 160,169 ****
  "		added.",
  "",
  "	All options are case insensitive.  Options may be",
! "	abbreviated; the abbreviation is the upper case letters.",
  "	Options and other command line arguments may be mixed",
! "	arbitrarily on the command line.",
  "",
  "RECOMMENDED ALIAS",
  "	The recommended alias for this command is",
  "	csh%%	alias aeb '%s -b \\!* -v'",
--- 173,200 ----
  "		added.",
  "",
  "	All options are case insensitive.  Options may be",
! "	All options may be abbreviated; the abbreviation is",
! "	documented as the upper case letters, all lower case",
! "	letters and underscores (_) are optional.  You must use",
! "	consecutive sequences of optional letters.",
! "",
! "	All options are case insensitive, you may type them in",
! "	upper case or lower case or a combination of both, case",
! "	is not important.",
! "",
! "	For example: the arguments \"-project, \"-PROJ\" and \"-p\"",
! "	are all interpreted to mean the -Project option.  The",
! "	argument \"-prj\" will not be understood, because",
! "	consecutive optional characters were not supplied.",
! "",
  "	Options and other command line arguments may be mixed",
! "	arbitrarily on the command line, after the function",
! "	selectors.",
  "",
+ "	The GNU long option names are understood.  Since all",
+ "	option names for aegis are long, this means ignoring the",
+ "	extra leading '-'.  The \"--option=value\" convention is",
+ "	also understood.",
  "RECOMMENDED ALIAS",
  "	The recommended alias for this command is",
  "	csh%%	alias aeb '%s -b \\!* -v'",
***************
*** 208,214 ****
  static void
  build_list()
  {
! 	string_t	*project_name;
  
  	trace(("build_list()\n{\n"/*}*/));
  	arglex();
--- 239,245 ----
  static void
  build_list()
  {
! 	string_ty	*project_name;
  
  	trace(("build_list()\n{\n"/*}*/));
  	arglex();
***************
*** 264,279 ****
  static void
  build_main()
  {
! 	string_t	*the_command;
  	cstate		cstate_data;
  	pstate		pstate_data;
  	pconf		pconf_data;
! 	string_t	*project_name;
! 	project_t	*pp;
  	long		change_number;
! 	change_t	*cp;
  	int		nolog;
! 	user_t		*up;
  
  	trace(("build_main()\n{\n"/*}*/));
  	nolog = 0;
--- 295,310 ----
  static void
  build_main()
  {
! 	string_ty	*the_command;
  	cstate		cstate_data;
  	pstate		pstate_data;
  	pconf		pconf_data;
! 	string_ty	*project_name;
! 	project_ty	*pp;
  	long		change_number;
! 	change_ty	*cp;
  	int		nolog;
! 	user_ty		*up;
  
  	trace(("build_main()\n{\n"/*}*/));
  	nolog = 0;
***************
*** 347,352 ****
--- 378,384 ----
  	 * Block if necessary.
  	 */
  	change_cstate_lock_prepare(cp);
+ 	project_build_read_lock_prepare(pp);
  	lock_take();
  	cstate_data = change_cstate_get(cp);
  	pstate_data = project_pstate_get(pp);
***************
*** 413,421 ****
  	trace(("work out the build command\n"));
  	if (cstate_data->state == cstate_state_being_integrated)
  	{
- 		char		stamp[40];
- 		char		cnum[20];
- 
  		/*
  		 * %1 = project name
  		 * %2 = change number
--- 445,450 ----
***************
*** 424,455 ****
  		 *	'b' is the minor version number,
  		 *	and 'nnn' is the build number.
  		 */
! 		sprintf
! 		(
! 			stamp,
! 			"%ld.%ld.D%3.3ld",
! 			pstate_data->version_major,
! 			pstate_data->version_minor,
! 			cstate_data->delta_number
! 		);
! 		sprintf(cnum, "%ld", change_number);
  		the_command = pconf_data->build_command;
! 		the_command =
! 			substitute
! 			(
! 				cp,
! 				the_command->str_text,
! 				project_name_get(pp)->str_text,
! 				cnum,
! 				stamp,
! 				(char *)0
! 			);
  	}
  	else
  	{
- 		char		stamp[40];
- 		char		cnum[20];
- 
  		/*
  		 * %1 = project name
  		 * %2 = change number
--- 453,466 ----
  		 *	'b' is the minor version number,
  		 *	and 'nnn' is the build number.
  		 */
! 		sub_var_set("1", "${project}");
! 		sub_var_set("2", "${change}");
! 		sub_var_set("3", "${version}");
  		the_command = pconf_data->build_command;
! 		the_command = substitute(cp, the_command);
  	}
  	else
  	{
  		/*
  		 * %1 = project name
  		 * %2 = change number
***************
*** 459,485 ****
  		 *	and 'nnn' is the change number.
  		 * %4 = the absolute path of the project baseline directory.
  		 */
! 		sprintf
! 		(
! 			stamp,
! 			"%ld.%ld.C%3.3ld",
! 			pstate_data->version_major,
! 			pstate_data->version_minor,
! 			change_number
! 		);
! 		sprintf(cnum, "%ld", change_number);
! 		the_command =
! 			substitute
! 			(
! 				cp,
! 				pconf_data->development_build_command->str_text,
! 				project_name_get(pp)->str_text,
! 				cnum,
! 				stamp,
! 				project_baseline_path_get(pp)->str_text,
! 				(char *)0
! 			);
! 
  	}
  
  	/*
--- 470,481 ----
  		 *	and 'nnn' is the change number.
  		 * %4 = the absolute path of the project baseline directory.
  		 */
! 		sub_var_set("1", "${project}");
! 		sub_var_set("2", "${change}");
! 		sub_var_set("3", "${version}");
! 		sub_var_set("4", "${baseline}");
! 		the_command = pconf_data->development_build_command;
! 		the_command = substitute(cp, the_command);
  	}
  
  	/*
***************
*** 497,507 ****
  	trace(("do the build\n"));
  	if (cstate_data->state == cstate_state_being_integrated)
  	{
! 		string_t	*id;
  
  		if (!nolog)
  		{
! 			user_t		*pup;
  
  			pup = project_user(pp);
  			log_open(change_logfile_get(cp), pup);
--- 493,503 ----
  	trace(("do the build\n"));
  	if (cstate_data->state == cstate_state_being_integrated)
  	{
! 		string_ty	*id;
  
  		if (!nolog)
  		{
! 			user_ty		*pup;
  
  			pup = project_user(pp);
  			log_open(change_logfile_get(cp), pup);
***************
*** 508,531 ****
  			user_free(pup);
  		}
  		change_verbose(cp, "integration build started");
! 		id = change_integration_directory_get(cp);
  		project_become(pp);
  		os_execute(the_command, OS_EXEC_FLAG_NO_INPUT, id);
! 		os_become_undo();
  		change_verbose(cp, "integration build complete");
  	}
  	else
  	{
! 		string_t	*dd;
  
  		if (!nolog)
  			log_open(change_logfile_get(cp), up);
  		change_verbose(cp, "development build started");
  		change_run_project_file_command(cp);
! 		dd = change_development_directory_get(cp);
  		user_become(up);
  		os_execute(the_command, OS_EXEC_FLAG_NO_INPUT, dd);
! 		os_become_undo();
  		change_verbose(cp, "development build complete");
  	}
  
--- 504,527 ----
  			user_free(pup);
  		}
  		change_verbose(cp, "integration build started");
! 		id = change_integration_directory_get(cp, 0);
  		project_become(pp);
  		os_execute(the_command, OS_EXEC_FLAG_NO_INPUT, id);
! 		project_become_undo();
  		change_verbose(cp, "integration build complete");
  	}
  	else
  	{
! 		string_ty	*dd;
  
  		if (!nolog)
  			log_open(change_logfile_get(cp), up);
  		change_verbose(cp, "development build started");
  		change_run_project_file_command(cp);
! 		dd = change_development_directory_get(cp, 0);
  		user_become(up);
  		os_execute(the_command, OS_EXEC_FLAG_NO_INPUT, dd);
! 		user_become_undo();
  		change_verbose(cp, "development build complete");
  	}
  
Index: aegis/build.h
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
Index: aegis/cattr.def
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 20,27 ****
   * MANIFEST: change state file contents definition
   *
   * if you change this file, don't forget to change
!  *	man5/aecattr.5
!  *	man5/aecstate.5
   */
  
  #include <common.def>
--- 20,26 ----
   * MANIFEST: change state file contents definition
   *
   * if you change this file, don't forget to change
!  *	man5/aecattr.so
   */
  
  #include <common.def>
Index: aegis/cattr_ed.c
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 82,90 ****
  "",
  "	-Change <number>",
  "		This option may be used to specify a particular",
! "		change within a project.  If the user is only",
! "		working on one change within a project, that is",
! "		the default change number.",
  "",
  "	-Help",
  "		This option may be used to obtain more",
--- 82,95 ----
  "",
  "	-Change <number>",
  "		This option may be used to specify a particular",
! "		change within a project.  When no -Change option is",
! "		specified, the AEGIS_CHANGE environment variable is",
! "		consulted.  If that does not exist, the user's",
! "		$HOME/.aegisrc file is examined for a default change",
! "		field (see aeuconf(5) for more information).  If",
! "		that does not exist, when the user is only working",
! "		on one change within a project, that is the default",
! "		change number.  Otherwise, it is an error.",
  "",
  "	-Help",
  "		This option may be used to obtain more",
***************
*** 97,110 ****
  "",
  "	-Project <name>",
  "		This option may be used to select the project of",
! "		interest.  When no -Project option is specified, if",
! "		the user is only working on changes within a single",
! "		project, the project name defaults to that project;",
! "		if the user is currently working on changes to more",
! "		than one project, or is not working on changes to",
! "		any project, the user's $HOME/.%src file is",
! "		examined for a default project field (see aeuconf(5)",
! "		for more information).",
  "",
  "	-TERse",
  "		This option may be used to cause listings to",
--- 102,115 ----
  "",
  "	-Project <name>",
  "		This option may be used to select the project of",
! "		interest.  When no -Project option is specified, the",
! "		AEGIS_PROJECT environment variable is consulted.  If",
! "		that does not exist, the user's $HOME/.aegisrc file",
! "		is examined for a default project field (see",
! "		aeuconf(5) for more information).  If that does not",
! "		exist, when the user is only working on changes",
! "		within a single project, the project name defaults",
! "		to that project.  Otherwise, it is an error.",
  "",
  "	-TERse",
  "		This option may be used to cause listings to",
***************
*** 118,128 ****
  "		option this option causes column headings to be",
  "		added.",
  "",
! "	All options are case insensitive.  Options may be",
! "	abbreviated; the abbreviation is the upper case letters.",
  "	Options and other command line arguments may be mixed",
! "	arbitrarily on the command line.",
  "",
  "RECOMMENDED ALIAS",
  "	The recommended alias for this command is",
  "	csh%%	alias aeca '%s -ca \\!* -v'",
--- 123,151 ----
  "		option this option causes column headings to be",
  "		added.",
  "",
! "	All options may be abbreviated; the abbreviation is",
! "	documented as the upper case letters, all lower case",
! "	letters and underscores (_) are optional.  You must use",
! "	consecutive sequences of optional letters.",
! "",
! "	All options are case insensitive, you may type them in",
! "	upper case or lower case or a combination of both, case",
! "	is not important.",
! "",
! "	For example: the arguments \"-project, \"-PROJ\" and \"-p\"",
! "	are all interpreted to mean the -Project option.  The",
! "	argument \"-prj\" will not be understood, because",
! "	consecutive optional characters were not supplied.",
! "",
  "	Options and other command line arguments may be mixed",
! "	arbitrarily on the command line, after the function",
! "	selectors.",
  "",
+ "	The GNU long option names are understood.  Since all",
+ "	option names for aegis are long, this means ignoring the",
+ "	extra leading '-'.  The \"--option=value\" convention is",
+ "	also understood.",
+ "",
  "RECOMMENDED ALIAS",
  "	The recommended alias for this command is",
  "	csh%%	alias aeca '%s -ca \\!* -v'",
***************
*** 153,165 ****
  static void
  change_attributes_list()
  {
! 	string_t	*project_name;
! 	project_t	*pp;
  	cattr		cattr_data;
  	cstate		cstate_data;
  	long		change_number;
! 	change_t	*cp;
! 	user_t		*up;
  
  	trace(("change_attributes_list()\n{\n"/*}*/));
  	arglex();
--- 176,188 ----
  static void
  change_attributes_list()
  {
! 	string_ty	*project_name;
! 	project_ty	*pp;
  	cattr		cattr_data;
  	cstate		cstate_data;
  	long		change_number;
! 	change_ty	*cp;
! 	user_ty		*up;
  
  	trace(("change_attributes_list()\n{\n"/*}*/));
  	arglex();
***************
*** 223,229 ****
  	 * build the cattr data
  	 */
  	cstate_data = change_cstate_get(cp);
! 	cattr_data = cattr_type.alloc();
  	if (cstate_data->description)
  		cattr_data->description = str_copy(cstate_data->description);
  	if (cstate_data->brief_description)
--- 246,252 ----
  	 * build the cattr data
  	 */
  	cstate_data = change_cstate_get(cp);
! 	cattr_data = (cattr)cattr_type.alloc();
  	if (cstate_data->description)
  		cattr_data->description = str_copy(cstate_data->description);
  	if (cstate_data->brief_description)
***************
*** 250,262 ****
  static void
  change_attributes_main()
  {
! 	string_t	*project_name;
! 	project_t	*pp;
  	cattr		cattr_data = 0;
  	cstate		cstate_data;
  	long		change_number;
! 	change_t	*cp;
! 	user_t		*up;
  
  	trace(("change_attributes_main()\n{\n"/*}*/));
  	project_name = 0;
--- 273,285 ----
  static void
  change_attributes_main()
  {
! 	string_ty	*project_name;
! 	project_ty	*pp;
  	cattr		cattr_data = 0;
  	cstate		cstate_data;
  	long		change_number;
! 	change_ty	*cp;
! 	user_ty		*up;
  
  	trace(("change_attributes_main()\n{\n"/*}*/));
  	project_name = 0;
Index: aegis/cattr_ed.h
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
Index: aegis/change.c
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 41,56 ****
  #include <word.h>
  
  
! change_t *
  change_alloc(pp, number)
! 	project_t	*pp;
  	long		number;
  {
! 	change_t	*cp;
  
  	trace(("change_alloc(pp = %08lX, number = %ld)\n{\n"/*}*/, pp, number));
  	assert(number >= 1);
! 	cp = (change_t *)mem_alloc_clear(sizeof(change_t));
  	cp->reference_count = 1;
  	cp->pp = project_copy(pp);
  	cp->number = number;
--- 41,56 ----
  #include <word.h>
  
  
! change_ty *
  change_alloc(pp, number)
! 	project_ty	*pp;
  	long		number;
  {
! 	change_ty	*cp;
  
  	trace(("change_alloc(pp = %08lX, number = %ld)\n{\n"/*}*/, pp, number));
  	assert(number >= 1);
! 	cp = (change_ty *)mem_alloc_clear(sizeof(change_ty));
  	cp->reference_count = 1;
  	cp->pp = project_copy(pp);
  	cp->number = number;
***************
*** 63,69 ****
  
  void
  change_free(cp)
! 	change_t	*cp;
  {
  	trace(("change_free(cp = %08lX)\n{\n"/*}*/, cp));
  	assert(cp->reference_count >= 1);
--- 63,69 ----
  
  void
  change_free(cp)
! 	change_ty	*cp;
  {
  	trace(("change_free(cp = %08lX)\n{\n"/*}*/, cp));
  	assert(cp->reference_count >= 1);
***************
*** 92,100 ****
  }
  
  
! change_t *
  change_copy(cp)
! 	change_t	*cp;
  {
  	trace(("change_copy(cp = %08lX)\n{\n"/*}*/, cp));
  	assert(cp->reference_count >= 1);
--- 92,100 ----
  }
  
  
! change_ty *
  change_copy(cp)
! 	change_ty	*cp;
  {
  	trace(("change_copy(cp = %08lX)\n{\n"/*}*/, cp));
  	assert(cp->reference_count >= 1);
***************
*** 105,130 ****
  }
  
  
! static void improve _((change_t *));
  
  static void
  improve(cp)
! 	change_t	*cp;
  {
  	trace(("improve(cp = %08lX)\n{\n"/*}*/, cp));
  	if (!cp->cstate_data->history)
! 		cp->cstate_data->history = cstate_history_list_type.alloc();
  	if (!cp->cstate_data->src)
! 		cp->cstate_data->src = cstate_src_list_type.alloc();
  	trace((/*{*/"}\n"));
  }
  
  
! static void lock_sync _((change_t *));
  
  static void
  lock_sync(cp)
! 	change_t	*cp;
  {
  	long		n;
  
--- 105,134 ----
  }
  
  
! static void improve _((change_ty *));
  
  static void
  improve(cp)
! 	change_ty	*cp;
  {
  	trace(("improve(cp = %08lX)\n{\n"/*}*/, cp));
  	if (!cp->cstate_data->history)
! 		cp->cstate_data->history =
! 			(cstate_history_list)
! 			cstate_history_list_type.alloc();
  	if (!cp->cstate_data->src)
! 		cp->cstate_data->src =
! 			(cstate_src_list)
! 			cstate_src_list_type.alloc();
  	trace((/*{*/"}\n"));
  }
  
  
! static void lock_sync _((change_ty *));
  
  static void
  lock_sync(cp)
! 	change_ty	*cp;
  {
  	long		n;
  
***************
*** 148,154 ****
  
  cstate
  change_cstate_get(cp)
! 	change_t	*cp;
  {
  	trace(("change_cstate_get(cp = %08lX)\n{\n"/*}*/, cp));
  	lock_sync(cp);
--- 152,158 ----
  
  cstate
  change_cstate_get(cp)
! 	change_ty	*cp;
  {
  	trace(("change_cstate_get(cp = %08lX)\n{\n"/*}*/, cp));
  	lock_sync(cp);
***************
*** 267,278 ****
  
  void
  change_bind_new(cp)
! 	change_t	*cp;
  {
  	trace(("change_bind_new(cp = %08lX)\n{\n"/*}*/, cp));
  	assert(!cp->cstate_data);
  	cp->is_a_new_file = 1;
! 	cp->cstate_data = cstate_type.alloc();
  	improve(cp);
  	trace((/*{*/"}\n"));
  }
--- 271,282 ----
  
  void
  change_bind_new(cp)
! 	change_ty	*cp;
  {
  	trace(("change_bind_new(cp = %08lX)\n{\n"/*}*/, cp));
  	assert(!cp->cstate_data);
  	cp->is_a_new_file = 1;
! 	cp->cstate_data = (cstate)cstate_type.alloc();
  	improve(cp);
  	trace((/*{*/"}\n"));
  }
***************
*** 296,305 ****
  
  void
  change_cstate_write(cp)
! 	change_t	*cp;
  {
! 	string_t	*filename_new;
! 	string_t	*filename_old;
  	pstate		pstate_data;
  	static int	count;
  
--- 300,309 ----
  
  void
  change_cstate_write(cp)
! 	change_ty	*cp;
  {
! 	string_ty	*filename_new;
! 	string_ty	*filename_old;
  	pstate		pstate_data;
  	static int	count;
  
***************
*** 338,345 ****
  	change_become(cp);
  	if (cp->is_a_new_file)
  	{
! 		string_t	*s1;
! 		string_t	*s2;
  
  		s1 = project_home_path_get(cp->pp);
  		s2 = os_below_dir(s1, cp->filename);
--- 342,349 ----
  	change_become(cp);
  	if (cp->is_a_new_file)
  	{
! 		string_ty	*s1;
! 		string_ty	*s2;
  
  		s1 = project_home_path_get(cp->pp);
  		s2 = os_below_dir(s1, cp->filename);
***************
*** 372,379 ****
  
  cstate_src
  change_src_find(cp, file_name)
! 	change_t	*cp;
! 	string_t	*file_name;
  {
  	cstate		cstate_data;
  	int		j;
--- 376,383 ----
  
  cstate_src
  change_src_find(cp, file_name)
! 	change_ty	*cp;
! 	string_ty	*file_name;
  {
  	cstate		cstate_data;
  	int		j;
***************
*** 402,409 ****
  
  void
  change_src_remove(cp, file_name)
! 	change_t	*cp;
! 	string_t	*file_name;
  {
  	cstate		cstate_data;
  	int		j;
--- 406,413 ----
  
  void
  change_src_remove(cp, file_name)
! 	change_ty	*cp;
! 	string_ty	*file_name;
  {
  	cstate		cstate_data;
  	int		j;
***************
*** 428,439 ****
  
  cstate_src
  change_src_new(cp)
! 	change_t	*cp;
  {
  	cstate		cstate_data;
  	cstate_src	src_data;
  	cstate_src	*src_data_p;
! 	type_t		*type_p;
  
  	trace(("change_src_new(cp = %08lX)\n{\n"/*}*/, cp));
  	cstate_data = change_cstate_get(cp);
--- 432,443 ----
  
  cstate_src
  change_src_new(cp)
! 	change_ty	*cp;
  {
  	cstate		cstate_data;
  	cstate_src	src_data;
  	cstate_src	*src_data_p;
! 	type_ty		*type_p;
  
  	trace(("change_src_new(cp = %08lX)\n{\n"/*}*/, cp));
  	cstate_data = change_cstate_get(cp);
***************
*** 444,450 ****
  		&type_p,
  		(void **)&src_data_p
  	);
! 	src_data = cstate_src_type.alloc();
  	*src_data_p = src_data;
  	trace(("return %08lX;\n", src_data));
  	trace((/*{*/"}\n"));
--- 448,454 ----
  		&type_p,
  		(void **)&src_data_p
  	);
! 	src_data = (cstate_src)cstate_src_type.alloc();
  	*src_data_p = src_data;
  	trace(("return %08lX;\n", src_data));
  	trace((/*{*/"}\n"));
***************
*** 454,466 ****
  
  cstate_history
  change_history_new(cp, up)
! 	change_t	*cp;
! 	user_t		*up;
  {
  	cstate		cstate_data;
  	cstate_history	history_data;
  	cstate_history	*history_data_p;
! 	type_t		*type_p;
  
  	trace(("change_history_new(cp = %08lX)\n{\n"/*}*/, cp));
  	cstate_data = change_cstate_get(cp);
--- 458,470 ----
  
  cstate_history
  change_history_new(cp, up)
! 	change_ty	*cp;
! 	user_ty		*up;
  {
  	cstate		cstate_data;
  	cstate_history	history_data;
  	cstate_history	*history_data_p;
! 	type_ty		*type_p;
  
  	trace(("change_history_new(cp = %08lX)\n{\n"/*}*/, cp));
  	cstate_data = change_cstate_get(cp);
***************
*** 471,477 ****
  		&type_p,
  		(void **)&history_data_p
  	);
! 	history_data = cstate_history_type.alloc();
  	*history_data_p = history_data;
  	time(&history_data->when);
  	history_data->who = str_copy(user_name(up));
--- 475,481 ----
  		&type_p,
  		(void **)&history_data_p
  	);
! 	history_data = (cstate_history)cstate_history_type.alloc();
  	*history_data_p = history_data;
  	time(&history_data->when);
  	history_data->who = str_copy(user_name(up));
***************
*** 481,489 ****
  }
  
  
! string_t *
  change_developer_name(cp)
! 	change_t	*cp;
  {
  	cstate		cstate_data;
  	cstate_history	history_data;
--- 485,493 ----
  }
  
  
! string_ty *
  change_developer_name(cp)
! 	change_ty	*cp;
  {
  	cstate		cstate_data;
  	cstate_history	history_data;
***************
*** 510,525 ****
  		}
  		break;
  	}
! 	assert(history_data);
! 	trace_string(history_data->who->str_text);
  	trace((/*{*/"}\n"));
! 	return history_data->who;
  }
  
  
! string_t *
  change_reviewer_name(cp)
! 	change_t	*cp;
  {
  	cstate		cstate_data;
  	cstate_history	history_data;
--- 514,529 ----
  		}
  		break;
  	}
! 	trace(("return \"%s\";\n",
! 		history_data ? history_data->who->str_text : ""));
  	trace((/*{*/"}\n"));
! 	return (history_data ? history_data->who : 0);
  }
  
  
! string_ty *
  change_reviewer_name(cp)
! 	change_ty	*cp;
  {
  	cstate		cstate_data;
  	cstate_history	history_data;
***************
*** 545,560 ****
  		}
  		break;
  	}
! 	assert(history_data);
! 	trace_string(history_data->who->str_text);
  	trace((/*{*/"}\n"));
! 	return history_data->who;
  }
  
  
! string_t *
  change_integrator_name(cp)
! 	change_t	*cp;
  {
  	cstate		cstate_data;
  	cstate_history	history_data;
--- 549,564 ----
  		}
  		break;
  	}
! 	trace(("return \"%s\";\n",
! 		history_data ? history_data->who->str_text : ""));
  	trace((/*{*/"}\n"));
! 	return (history_data ? history_data->who : 0);
  }
  
  
! string_ty *
  change_integrator_name(cp)
! 	change_ty	*cp;
  {
  	cstate		cstate_data;
  	cstate_history	history_data;
***************
*** 581,596 ****
  		}
  		break;
  	}
! 	assert(history_data);
! 	trace_string(history_data->who->str_text);
  	trace((/*{*/"}\n"));
! 	return history_data->who;
  }
  
  
  void
  change_bind_existing(cp)
! 	change_t	*cp;
  {
  	pstate		pstate_data;
  	int		j;
--- 585,600 ----
  		}
  		break;
  	}
! 	trace(("return \"%s\";\n",
! 		history_data ? history_data->who->str_text : ""));
  	trace((/*{*/"}\n"));
! 	return (history_data ? history_data->who : 0);
  }
  
  
  void
  change_bind_existing(cp)
! 	change_ty	*cp;
  {
  	pstate		pstate_data;
  	int		j;
***************
*** 615,631 ****
  
  void
  change_development_directory_set(cp, s)
! 	change_t	*cp;
! 	string_t	*s;
  {
  	cstate		cstate_data;
  
  	trace(("change_development_directory_set(cp = %08lX, s = \"%s\")\n{\n"/*}*/, cp, s->str_text));
  	if (cp->development_directory)
  		fatal("duplicate -DIRectory option");
  	assert(s->str_text[0] == '/');
  	change_become(cp);
! 	cp->development_directory = os_pathname(s);
  	change_become_undo();
  	cstate_data = change_cstate_get(cp);
  	if (!cstate_data->development_directory)
--- 619,642 ----
  
  void
  change_development_directory_set(cp, s)
! 	change_ty	*cp;
! 	string_ty	*s;
  {
  	cstate		cstate_data;
  
+ 	/*
+ 	 * To cope with automounters, directories are stored as given,
+ 	 * or are derived from the home directory in the passwd file.
+ 	 * Within aegis, pathnames have their symbolic links resolved,
+ 	 * and any comparison of paths is done on this "system idea"
+ 	 * of the pathname.
+ 	 */
  	trace(("change_development_directory_set(cp = %08lX, s = \"%s\")\n{\n"/*}*/, cp, s->str_text));
  	if (cp->development_directory)
  		fatal("duplicate -DIRectory option");
  	assert(s->str_text[0] == '/');
  	change_become(cp);
! 	cp->development_directory = os_pathname(s, 1);
  	change_become_undo();
  	cstate_data = change_cstate_get(cp);
  	if (!cstate_data->development_directory)
***************
*** 634,710 ****
  }
  
  
! string_t *
! change_development_directory_get(cp)
! 	change_t	*cp;
  {
  	trace(("change_development_directory_get(cp = %08lX)\n{\n"/*}*/, cp));
! 	if (!cp->development_directory)
  	{
- 		cstate		cstate_data;
- 
  		cstate_data = change_cstate_get(cp);
! 		if (!cstate_data->development_directory)
! 			fatal("no development directory");
! 		change_become(cp);
! 		cp->development_directory =
! 			os_pathname(cstate_data->development_directory);
! 		change_become_undo();
  	}
! 	trace_string(cp->development_directory->str_text);
  	trace((/*{*/"}\n"));
! 	return cp->development_directory;
  }
  
  
  void
  change_integration_directory_set(cp, s)
! 	change_t	*cp;
! 	string_t	*s;
  {
  	cstate		cstate_data;
  
  	trace(("change_integration_directory_set(cp = %08lX, s = \"%s\")\n{\n"/*}*/, cp, s->str_text));
  	if (cp->integration_directory)
  		fatal("duplicate -DIRectory option");
  	change_become(cp);
! 	cp->integration_directory = os_pathname(s);
  	change_become_undo();
  	cstate_data = change_cstate_get(cp);
  	if (!cstate_data->integration_directory)
! 		cp->cstate_data->integration_directory = str_copy(s);
  	trace((/*{*/"}\n"));
  }
  
  
! string_t *
! change_integration_directory_get(cp)
! 	change_t	*cp;
  {
  	trace(("change_integration_directory_get(cp = %08lX)\n{\n"/*}*/, cp));
! 	if (!cp->integration_directory)
  	{
- 		cstate		cstate_data;
- 
  		cstate_data = change_cstate_get(cp);
! 		if (!cstate_data->integration_directory)
! 			fatal("no integration directory");
! 		change_become(cp);
! 		cp->integration_directory =
! 			os_pathname(cstate_data->integration_directory);
! 		change_become_undo();
  	}
! 	trace_string(cp->integration_directory->str_text);
  	trace((/*{*/"}\n"));
! 	return cp->integration_directory;
  }
  
  
! string_t *
  change_logfile_get(cp)
! 	change_t	*cp;
  {
! 	string_t	*s1;
  	cstate		cstate_data;
  
  	trace(("change_logfile_get(cp = %08lX)\n{\n"/*}*/, cp));
--- 645,786 ----
  }
  
  
! string_ty *
! change_development_directory_get(cp, resolve)
! 	change_ty	*cp;
! 	int		resolve;
  {
+ 	string_ty	*result;
+ 	cstate		cstate_data;
+ 
+ 	/*
+ 	 * To cope with automounters, directories are stored as given,
+ 	 * or are derived from the home directory in the passwd file.
+ 	 * Within aegis, pathnames have their symbolic links resolved,
+ 	 * and any comparison of paths is done on this "system idea"
+ 	 * of the pathname.
+ 	 */
  	trace(("change_development_directory_get(cp = %08lX)\n{\n"/*}*/, cp));
! 	if (!resolve)
  	{
  		cstate_data = change_cstate_get(cp);
! 		result = cstate_data->development_directory;
  	}
! 	else
! 	{
! 		if (!cp->development_directory)
! 		{
! 			cstate_data = change_cstate_get(cp);
! 			if (!cstate_data->development_directory)
! 			{
! 				change_fatal
! 				(
! 					cp,
! 	    "this change is in the %s state, there is no development directory",
! 					cstate_state_ename(cstate_data->state)
! 				);
! 			}
! 			change_become(cp);
! 			cp->development_directory =
! 				os_pathname
! 				(
! 					cstate_data->development_directory,
! 					1
! 				);
! 			change_become_undo();
! 		}
! 		result = cp->development_directory;
! 	}
! 	trace_string(result->str_text);
  	trace((/*{*/"}\n"));
! 	return result;
  }
  
  
  void
  change_integration_directory_set(cp, s)
! 	change_ty	*cp;
! 	string_ty	*s;
  {
  	cstate		cstate_data;
  
+ 	/*
+ 	 * To cope with automounters, directories are stored as given,
+ 	 * or are derived from the home directory in the passwd file.
+ 	 * Within aegis, pathnames have their symbolic links resolved,
+ 	 * and any comparison of paths is done on this "system idea"
+ 	 * of the pathname.
+ 	 */
  	trace(("change_integration_directory_set(cp = %08lX, s = \"%s\")\n{\n"/*}*/, cp, s->str_text));
  	if (cp->integration_directory)
  		fatal("duplicate -DIRectory option");
  	change_become(cp);
! 	cp->integration_directory = os_pathname(s, 1);
  	change_become_undo();
  	cstate_data = change_cstate_get(cp);
  	if (!cstate_data->integration_directory)
! 		cstate_data->integration_directory = str_copy(s);
  	trace((/*{*/"}\n"));
  }
  
  
! string_ty *
! change_integration_directory_get(cp, resolve)
! 	change_ty	*cp;
! 	int		resolve;
  {
+ 	string_ty	*result;
+ 	cstate		cstate_data;
+ 
+ 	/*
+ 	 * To cope with automounters, directories are stored as given,
+ 	 * or are derived from the home directory in the passwd file.
+ 	 * Within aegis, pathnames have their symbolic links resolved,
+ 	 * and any comparison of paths is done on this "system idea"
+ 	 * of the pathname.
+ 	 */
  	trace(("change_integration_directory_get(cp = %08lX)\n{\n"/*}*/, cp));
! 	if (!resolve)
  	{
  		cstate_data = change_cstate_get(cp);
! 		result = cstate_data->integration_directory;
  	}
! 	else
! 	{
! 		if (!cp->integration_directory)
! 		{
! 			cstate_data = change_cstate_get(cp);
! 			if (!cstate_data->integration_directory)
! 			{
! 				change_fatal
! 				(
! 					cp,
! 	    "this change is in the %s state, there is no integration directory",
! 					cstate_state_ename(cstate_data->state)
! 				);
! 			}
! 			change_become(cp);
! 			cp->integration_directory =
! 				os_pathname
! 				(
! 					cstate_data->integration_directory,
! 					1
! 				);
! 			change_become_undo();
! 		}
! 		result = cp->integration_directory;
! 	}
! 	trace_string(result->str_text);
  	trace((/*{*/"}\n"));
! 	return result;
  }
  
  
! string_ty *
  change_logfile_get(cp)
! 	change_ty	*cp;
  {
! 	string_ty	*s1;
  	cstate		cstate_data;
  
  	trace(("change_logfile_get(cp = %08lX)\n{\n"/*}*/, cp));
***************
*** 717,727 ****
  			change_fatal(cp, "no log file");
  	
  		case cstate_state_being_integrated:
! 			s1 = change_integration_directory_get(cp);
  			break;
  	
  		case cstate_state_being_developed:
! 			s1 = change_development_directory_get(cp);
  			break;
  		}
  	
--- 793,803 ----
  			change_fatal(cp, "no log file");
  	
  		case cstate_state_being_integrated:
! 			s1 = change_integration_directory_get(cp, 0);
  			break;
  	
  		case cstate_state_being_developed:
! 			s1 = change_development_directory_get(cp, 0);
  			break;
  		}
  	
***************
*** 736,742 ****
  
  void
  change_cstate_lock_prepare(cp)
! 	change_t	*cp;
  {
  	trace(("change_cstate_lock_prepare(cp = %08lX)\n{\n"/*}*/, cp));
  	lock_prepare_cstate(project_name_get(cp->pp), cp->number);
--- 812,818 ----
  
  void
  change_cstate_lock_prepare(cp)
! 	change_ty	*cp;
  {
  	trace(("change_cstate_lock_prepare(cp = %08lX)\n{\n"/*}*/, cp));
  	lock_prepare_cstate(project_name_get(cp->pp), cp->number);
***************
*** 746,757 ****
  
  void
  change_error(cp, s sva_last)
! 	change_t	*cp;
  	char		*s;
  	sva_last_decl
  {
  	va_list		ap;
! 	string_t	*msg;
  
  	sva_init(ap, s);
  	msg = str_vformat(s, ap);
--- 822,833 ----
  
  void
  change_error(cp, s sva_last)
! 	change_ty	*cp;
  	char		*s;
  	sva_last_decl
  {
  	va_list		ap;
! 	string_ty	*msg;
  
  	sva_init(ap, s);
  	msg = str_vformat(s, ap);
***************
*** 762,773 ****
  
  void
  change_fatal(cp, s sva_last)
! 	change_t	*cp;
  	char		*s;
  	sva_last_decl
  {
  	va_list		ap;
! 	string_t	*msg;
  
  	sva_init(ap, s);
  	msg = str_vformat(s, ap);
--- 838,849 ----
  
  void
  change_fatal(cp, s sva_last)
! 	change_ty	*cp;
  	char		*s;
  	sva_last_decl
  {
  	va_list		ap;
! 	string_ty	*msg;
  
  	sva_init(ap, s);
  	msg = str_vformat(s, ap);
***************
*** 778,789 ****
  
  void
  change_verbose(cp, s sva_last)
! 	change_t	*cp;
  	char		*s;
  	sva_last_decl
  {
  	va_list		ap;
! 	string_t	*msg;
  
  	sva_init(ap, s);
  	msg = str_vformat(s, ap);
--- 854,865 ----
  
  void
  change_verbose(cp, s sva_last)
! 	change_ty	*cp;
  	char		*s;
  	sva_last_decl
  {
  	va_list		ap;
! 	string_ty	*msg;
  
  	sva_init(ap, s);
  	msg = str_vformat(s, ap);
***************
*** 792,805 ****
  }
  
  
! string_t *
  change_pconf_path_get(cp)
! 	change_t	*cp;
  {
  	cstate		cstate_data;
  	pstate_src	p_src_data;
  	cstate_src	c_src_data;
! 	static string_t	*file_name;
  
  	trace(("change_pconf_path_get(cp = %08lX)\n{\n"/*}*/, cp));
  	if (cp->pconf_path)
--- 868,881 ----
  }
  
  
! string_ty *
  change_pconf_path_get(cp)
! 	change_ty	*cp;
  {
  	cstate		cstate_data;
  	pstate_src	p_src_data;
  	cstate_src	c_src_data;
! 	static string_ty	*file_name;
  
  	trace(("change_pconf_path_get(cp = %08lX)\n{\n"/*}*/, cp));
  	if (cp->pconf_path)
***************
*** 815,821 ****
  			str_format
  			(
  				"%S/%S",
! 				change_integration_directory_get(cp),
  				file_name
  			);
  		goto ret;
--- 891,897 ----
  			str_format
  			(
  				"%S/%S",
! 				change_integration_directory_get(cp, 1),
  				file_name
  			);
  		goto ret;
***************
*** 840,846 ****
  			str_format
  			(
  				"%S/%S",
! 				change_development_directory_get(cp),
  				file_name
  			);
  		goto ret;
--- 916,922 ----
  			str_format
  			(
  				"%S/%S",
! 				change_development_directory_get(cp, 1),
  				file_name
  			);
  		goto ret;
***************
*** 852,858 ****
  			str_format
  			(
  				"%S/%S",
! 				project_baseline_path_get(cp->pp),
  				file_name
  			);
  		goto ret;
--- 928,934 ----
  			str_format
  			(
  				"%S/%S",
! 				project_baseline_path_get(cp->pp, 1),
  				file_name
  			);
  		goto ret;
***************
*** 867,884 ****
  
  pconf
  change_pconf_get(cp)
! 	change_t	*cp;
  {
  	trace(("change_pconf_get(cp = %08lX)\n{\n"/*}*/, cp));
  	lock_sync(cp);
  	if (!cp->pconf_data)
  	{
! 		string_t	*filename;
  
  		filename = change_pconf_path_get(cp);
  		change_become(cp);
  		if (!os_exists(filename))
! 			cp->pconf_data = pconf_type.alloc();
  		else
  		{
  			cp->pconf_data = pconf_read_file(filename->str_text);
--- 943,960 ----
  
  pconf
  change_pconf_get(cp)
! 	change_ty	*cp;
  {
  	trace(("change_pconf_get(cp = %08lX)\n{\n"/*}*/, cp));
  	lock_sync(cp);
  	if (!cp->pconf_data)
  	{
! 		string_ty	*filename;
  
  		filename = change_pconf_path_get(cp);
  		change_become(cp);
  		if (!os_exists(filename))
! 			cp->pconf_data = (pconf)pconf_type.alloc();
  		else
  		{
  			cp->pconf_data = pconf_read_file(filename->str_text);
***************
*** 959,975 ****
  
  void
  change_run_change_file_command(cp, wlp, up)
! 	change_t	*cp;
  	wlist		*wlp;
! 	user_t		*up;
  {
  	pconf		pconf_data;
! 	string_t	*the_command;
! 	char		num[20];
! 	char		cnum[40];
! 	string_t	*the_files;
  	pstate		pstate_data;
! 	string_t	*dd;
  
  	trace(("change_run_change_file_command(cp = %08lX)\n{\n"/*}*/, cp));
  	pconf_data = change_pconf_get(cp);
--- 1035,1049 ----
  
  void
  change_run_change_file_command(cp, wlp, up)
! 	change_ty	*cp;
  	wlist		*wlp;
! 	user_ty		*up;
  {
  	pconf		pconf_data;
! 	string_ty	*the_command;
! 	string_ty	*the_files;
  	pstate		pstate_data;
! 	string_ty	*dd;
  
  	trace(("change_run_change_file_command(cp = %08lX)\n{\n"/*}*/, cp));
  	pconf_data = change_pconf_get(cp);
***************
*** 977,1006 ****
  		goto ret;
  	pstate_data = project_pstate_get(cp->pp);
  
- 	sprintf(num, "%ld", cp->number);
- 	sprintf
- 	(
- 		cnum,
- 		"%ld.%ld.C%3.3ld",
- 		pstate_data->version_major,
- 		pstate_data->version_minor,
- 		cp->number
- 	);
  	the_files = wl2str(wlp, 0, 32767);
! 	the_command =
! 		substitute
! 		(
! 			cp,
! 			pconf_data->change_file_command->str_text,
! 			project_name_get(cp->pp)->str_text,
! 			num,
! 			cnum,
! 			project_baseline_path_get(cp->pp)->str_text,
! 			the_files->str_text,
! 			(char *)0
! 		);
  	str_free(the_files);
! 	dd = change_development_directory_get(cp);
  	user_become(up);
  	os_execute(the_command, OS_EXEC_FLAG_NO_INPUT, dd);
  	user_become_undo();
--- 1051,1067 ----
  		goto ret;
  	pstate_data = project_pstate_get(cp->pp);
  
  	the_files = wl2str(wlp, 0, 32767);
! 	sub_var_set("File_List", "%S", the_files);
  	str_free(the_files);
! 	sub_var_set("1", "${project}");
! 	sub_var_set("2", "${change}");
! 	sub_var_set("3", "${version}");
! 	sub_var_set("4", "${baseline}");
! 	sub_var_set("5", "${file_list}");
! 	the_command = pconf_data->change_file_command;
! 	the_command = substitute(cp, the_command);
! 	dd = change_development_directory_get(cp, 0);
  	user_become(up);
  	os_execute(the_command, OS_EXEC_FLAG_NO_INPUT, dd);
  	user_become_undo();
***************
*** 1012,1026 ****
  
  void
  change_run_project_file_command(cp)
! 	change_t	*cp;
  {
  	cstate		cstate_data;
  	pconf		pconf_data;
! 	string_t	*the_command;
! 	char		num[20];
! 	char		cnum[40];
! 	pstate		pstate_data;
! 	string_t	*dd;
  
  	/*
  	 * make sure are sync'ed with project
--- 1073,1084 ----
  
  void
  change_run_project_file_command(cp)
! 	change_ty	*cp;
  {
  	cstate		cstate_data;
  	pconf		pconf_data;
! 	string_ty	*the_command;
! 	string_ty	*dd;
  
  	/*
  	 * make sure are sync'ed with project
***************
*** 1045,1088 ****
  		goto done;
  
  	/*
! 	 * %1 = project name
! 	 * %2 = change number
! 	 * %3 = identifying string, in the form "a.b.Cnnn"
! 	 *	where 'a' is the major version number,
! 	 *	'b' is the minor version number,
! 	 *	and 'nnn' is the change number.
! 	 * %4 = the absolute path of the project baseline directory.
  	 */
! 	pstate_data = project_pstate_get(cp->pp);
! 	sprintf
! 	(
! 		cnum,
! 		"%ld.%ld.C%3.3ld",
! 		pstate_data->version_major,
! 		pstate_data->version_minor,
! 		cp->number
! 	);
! 	sprintf(num, "%ld", cp->number);
  
  	/*
- 	 * construct the command string
- 	 */
- 	the_command =
- 		substitute
- 		(
- 			cp,
- 			pconf_data->project_file_command->str_text,
- 			project_name_get(cp->pp)->str_text,
- 			num,
- 			cnum,
- 			project_baseline_path_get(cp->pp)->str_text,
- 			(char *)0
- 		);
- 
- 	/*
  	 * execute the command
  	 */
! 	dd = change_development_directory_get(cp);
  	change_become(cp);
  	os_execute(the_command, OS_EXEC_FLAG_NO_INPUT, dd);
  	change_become_undo();
--- 1103,1121 ----
  		goto done;
  
  	/*
! 	 * All of the substitutions described in aesub(5) are available.
  	 */
! 	sub_var_set("1", "${project}");
! 	sub_var_set("2", "${change}");
! 	sub_var_set("3", "${version}");
! 	sub_var_set("4", "${baseline}");
! 	the_command = pconf_data->project_file_command;
! 	the_command = substitute(cp, the_command);
  
  	/*
  	 * execute the command
  	 */
! 	dd = change_development_directory_get(cp, 0);
  	change_become(cp);
  	os_execute(the_command, OS_EXEC_FLAG_NO_INPUT, dd);
  	change_become_undo();
***************
*** 1314,1325 ****
  }
  
  
! string_t *
  change_file_template(cp, name)
! 	change_t	*cp;
! 	string_t	*name;
  {
! 	string_t	*result;
  	size_t		j, k;
  	pconf		pconf_data;
  
--- 1347,1358 ----
  }
  
  
! string_ty *
  change_file_template(cp, name)
! 	change_ty	*cp;
! 	string_ty	*name;
  {
! 	string_ty	*result;
  	size_t		j, k;
  	pconf		pconf_data;
  
***************
*** 1338,1344 ****
  		for (k = 0; k < ftp->pattern->length; ++k)
  		{
  			int		m;
! 			string_t	*s;
  
  			s = ftp->pattern->list[k];
  			m = gmatch(s->str_text, name->str_text);
--- 1371,1377 ----
  		for (k = 0; k < ftp->pattern->length; ++k)
  		{
  			int		m;
! 			string_ty	*s;
  
  			s = ftp->pattern->list[k];
  			m = gmatch(s->str_text, name->str_text);
***************
*** 1356,1362 ****
  		}
  		if (k < ftp->pattern->length)
  		{
! 			result = ftp->body;
  			break;
  		}
  	}
--- 1389,1395 ----
  		}
  		if (k < ftp->pattern->length)
  		{
! 			result = str_copy(ftp->body);
  			break;
  		}
  	}
***************
*** 1365,1370 ****
--- 1398,1412 ----
  	 * here for all exits
  	 */
  	done:
+ 	if (result)
+ 	{
+ 		string_ty	*s;
+ 
+ 		sub_var_set("File_Name", "%S", name);
+ 		s = substitute(cp, result);
+ 		str_free(result);
+ 		result = s;
+ 	}
  	trace((/*{*/"}\n"));
  	return result;
  }
***************
*** 1372,1378 ****
  
  void
  change_become(cp)
! 	change_t	*cp;
  {
  	trace(("change_become(cp = %08lX)\n{\n"/*}*/, cp));
  	project_become(cp->pp);
--- 1414,1420 ----
  
  void
  change_become(cp)
! 	change_ty	*cp;
  {
  	trace(("change_become(cp = %08lX)\n{\n"/*}*/, cp));
  	project_become(cp->pp);
***************
*** 1391,1397 ****
  
  int
  change_umask(cp)
! 	change_t	*cp;
  {
  	return project_umask(cp->pp);
  }
--- 1433,1439 ----
  
  int
  change_umask(cp)
! 	change_ty	*cp;
  {
  	return project_umask(cp->pp);
  }
***************
*** 1399,1410 ****
  
  void
  change_run_develop_end_notify_command(cp)
! 	change_t	*cp;
  {
  	pstate		pstate_data;
! 	string_t	*the_command;
! 	char		num[20];
! 	string_t	*dd;
  
  	/*
  	 * make sure there is one
--- 1441,1451 ----
  
  void
  change_run_develop_end_notify_command(cp)
! 	change_ty	*cp;
  {
  	pstate		pstate_data;
! 	string_ty	*the_command;
! 	string_ty	*dd;
  
  	/*
  	 * make sure there is one
***************
*** 1420,1445 ****
  	 * it happens after the data is written and the locks are released,
  	 * so we don't much care if the command fails!
  	 *
! 	 *	%1 = project name
! 	 *	%2 = change number
! 	 *	%3 = developer
  	 */
! 	sprintf(num, "%ld", cp->number);
! 	the_command =
! 		substitute
! 		(
! 			cp,
! 			pstate_data->develop_end_notify_command->str_text,
! 			project_name_get(cp->pp)->str_text,
! 			num,
! 			change_developer_name(cp)->str_text,
! 			(char *)0
! 		);
  
  	/*
  	 * execute the command
  	 */
! 	dd = change_development_directory_get(cp);
  	change_become(cp);
  	os_execute(the_command, OS_EXEC_FLAG_NO_INPUT + OS_EXEC_FLAG_ERROK, dd);
  	change_become_undo();
--- 1461,1478 ----
  	 * it happens after the data is written and the locks are released,
  	 * so we don't much care if the command fails!
  	 *
! 	 * All of the substitutions described in aesub(5) are available.
  	 */
! 	sub_var_set("1", "${project}");
! 	sub_var_set("2", "${change}");
! 	sub_var_set("3", "${developer}");
! 	the_command = pstate_data->develop_end_notify_command;
! 	the_command = substitute(cp, the_command);
  
  	/*
  	 * execute the command
  	 */
! 	dd = change_development_directory_get(cp, 0);
  	change_become(cp);
  	os_execute(the_command, OS_EXEC_FLAG_NO_INPUT + OS_EXEC_FLAG_ERROK, dd);
  	change_become_undo();
***************
*** 1455,1466 ****
  
  void
  change_run_develop_end_undo_notify_command(cp)
! 	change_t	*cp;
  {
  	pstate		pstate_data;
! 	string_t	*the_command;
! 	char		num[20];
! 	string_t	*dd;
  
  	/*
  	 * make sure there is one
--- 1488,1498 ----
  
  void
  change_run_develop_end_undo_notify_command(cp)
! 	change_ty	*cp;
  {
  	pstate		pstate_data;
! 	string_ty	*the_command;
! 	string_ty	*dd;
  
  	/*
  	 * make sure there is one
***************
*** 1476,1501 ****
  	 * it happens after the data is written and the locks are released,
  	 * so we don't much care if the command fails!
  	 *
! 	 *	%1 = project name
! 	 *	%2 = change number
! 	 *	%3 = developer
  	 */
! 	sprintf(num, "%ld", cp->number);
! 	the_command =
! 		substitute
! 		(
! 			cp,
! 			pstate_data->develop_end_undo_notify_command->str_text,
! 			project_name_get(cp->pp)->str_text,
! 			num,
! 			change_developer_name(cp)->str_text,
! 			(char *)0
! 		);
  
  	/*
  	 * execute the command
  	 */
! 	dd = change_development_directory_get(cp);
  	change_become(cp);
  	os_execute(the_command, OS_EXEC_FLAG_NO_INPUT + OS_EXEC_FLAG_ERROK, dd);
  	change_become_undo();
--- 1508,1525 ----
  	 * it happens after the data is written and the locks are released,
  	 * so we don't much care if the command fails!
  	 *
! 	 * All of the substitutions described in aesub(5) are available.
  	 */
! 	sub_var_set("1", "${project}");
! 	sub_var_set("2", "${change}");
! 	sub_var_set("3", "${developer}");
! 	the_command = pstate_data->develop_end_undo_notify_command;
! 	the_command = substitute(cp, the_command);
  
  	/*
  	 * execute the command
  	 */
! 	dd = change_development_directory_get(cp, 0);
  	change_become(cp);
  	os_execute(the_command, OS_EXEC_FLAG_NO_INPUT + OS_EXEC_FLAG_ERROK, dd);
  	change_become_undo();
***************
*** 1511,1522 ****
  
  void
  change_run_integrate_fail_notify_command(cp)
! 	change_t	*cp;
  {
  	pstate		pstate_data;
! 	string_t	*the_command;
! 	char		num[20];
! 	string_t	*dd;
  
  	/*
  	 * make sure there is one
--- 1535,1545 ----
  
  void
  change_run_integrate_fail_notify_command(cp)
! 	change_ty	*cp;
  {
  	pstate		pstate_data;
! 	string_ty	*the_command;
! 	string_ty	*dd;
  
  	/*
  	 * make sure there is one
***************
*** 1535,1564 ****
  	 * In doing it after the locks are released,
  	 * the lists will be accurate (e.g. list of files in change).
  	 *
! 	 *	%1 = project name
! 	 *	%2 = change number
! 	 *	%3 = developer
! 	 *	%4 = reviewer
! 	 *	%5 = integrator
  	 */
! 	sprintf(num, "%ld", cp->number);
! 	the_command =
! 		substitute
! 		(
! 			cp,
! 			pstate_data->integrate_fail_notify_command->str_text,
! 			project_name_get(cp->pp)->str_text,
! 			num,
! 			change_developer_name(cp)->str_text,
! 			change_reviewer_name(cp)->str_text,
! 			change_integrator_name(cp)->str_text,
! 			(char *)0
! 		);
  
  	/*
  	 * execute the command
  	 */
! 	dd = change_development_directory_get(cp);
  	change_become(cp);
  	os_execute(the_command, OS_EXEC_FLAG_NO_INPUT + OS_EXEC_FLAG_ERROK, dd);
  	change_become_undo();
--- 1558,1577 ----
  	 * In doing it after the locks are released,
  	 * the lists will be accurate (e.g. list of files in change).
  	 *
! 	 * All of the substitutions described in aesub(5) are available.
  	 */
! 	sub_var_set("1", "${project}");
! 	sub_var_set("2", "${change}");
! 	sub_var_set("3", "${developer}");
! 	sub_var_set("4", "${reviewer}");
! 	sub_var_set("5", "${integrator}");
! 	the_command = pstate_data->integrate_fail_notify_command;
! 	the_command = substitute(cp, the_command);
  
  	/*
  	 * execute the command
  	 */
! 	dd = change_development_directory_get(cp, 0);
  	change_become(cp);
  	os_execute(the_command, OS_EXEC_FLAG_NO_INPUT + OS_EXEC_FLAG_ERROK, dd);
  	change_become_undo();
***************
*** 1574,1585 ****
  
  void
  change_run_integrate_pass_notify_command(cp)
! 	change_t	*cp;
  {
  	pstate		pstate_data;
! 	string_t	*the_command;
! 	char		num[20];
! 	string_t	*bl;
  
  	/*
  	 * make sure there is one
--- 1587,1597 ----
  
  void
  change_run_integrate_pass_notify_command(cp)
! 	change_ty	*cp;
  {
  	pstate		pstate_data;
! 	string_ty	*the_command;
! 	string_ty	*bl;
  
  	/*
  	 * make sure there is one
***************
*** 1598,1627 ****
  	 * In doing it after the locks are released,
  	 * the lists will be accurate (e.g. list of files in change).
  	 *
! 	 *	%1 = project name
! 	 *	%2 = change number
! 	 *	%3 = developer
! 	 *	%4 = reviewer
! 	 *	%5 = integrator
  	 */
! 	sprintf(num, "%ld", cp->number);
! 	the_command =
! 		substitute
! 		(
! 			cp,
! 			pstate_data->integrate_pass_notify_command->str_text,
! 			project_name_get(cp->pp)->str_text,
! 			num,
! 			change_developer_name(cp)->str_text,
! 			change_reviewer_name(cp)->str_text,
! 			change_integrator_name(cp)->str_text,
! 			(char *)0
! 		);
  
  	/*
  	 * execute the command
  	 */
! 	bl = project_baseline_path_get(cp->pp);
  	project_become(cp->pp);
  	os_execute(the_command, OS_EXEC_FLAG_NO_INPUT + OS_EXEC_FLAG_ERROK, bl);
  	project_become_undo();
--- 1610,1629 ----
  	 * In doing it after the locks are released,
  	 * the lists will be accurate (e.g. list of files in change).
  	 *
! 	 * All of the substitutions described in aesub(5) are available.
  	 */
! 	sub_var_set("1", "${project}");
! 	sub_var_set("2", "${change}");
! 	sub_var_set("3", "${developer}");
! 	sub_var_set("4", "${reviewer}");
! 	sub_var_set("5", "${integrator}");
! 	the_command = pstate_data->integrate_pass_notify_command;
! 	the_command = substitute(cp, the_command);
  
  	/*
  	 * execute the command
  	 */
! 	bl = project_baseline_path_get(cp->pp, 0);
  	project_become(cp->pp);
  	os_execute(the_command, OS_EXEC_FLAG_NO_INPUT + OS_EXEC_FLAG_ERROK, bl);
  	project_become_undo();
***************
*** 1637,1648 ****
  
  void
  change_run_review_pass_notify_command(cp)
! 	change_t	*cp;
  {
  	pstate		pstate_data;
! 	string_t	*the_command;
! 	char		num[20];
! 	string_t	*dd;
  
  	/*
  	 * make sure there is one
--- 1639,1649 ----
  
  void
  change_run_review_pass_notify_command(cp)
! 	change_ty	*cp;
  {
  	pstate		pstate_data;
! 	string_ty	*the_command;
! 	string_ty	*dd;
  
  	/*
  	 * make sure there is one
***************
*** 1658,1685 ****
  	 * it happens after the data is written and the locks are released,
  	 * so we don't much care if the command fails!
  	 *
! 	 *	%1 = project name
! 	 *	%2 = change number
! 	 *	%3 = developer
! 	 *	%4 = reviewer
  	 */
! 	sprintf(num, "%ld", cp->number);
! 	the_command =
! 		substitute
! 		(
! 			cp,
! 			pstate_data->review_pass_notify_command->str_text,
! 			project_name_get(cp->pp)->str_text,
! 			num,
! 			change_developer_name(cp)->str_text,
! 			change_reviewer_name(cp)->str_text,
! 			(char *)0
! 		);
  
  	/*
  	 * execute the command
  	 */
! 	dd = change_development_directory_get(cp);
  	change_become(cp);
  	os_execute(the_command, OS_EXEC_FLAG_NO_INPUT + OS_EXEC_FLAG_ERROK, dd);
  	str_free(the_command);
--- 1659,1677 ----
  	 * it happens after the data is written and the locks are released,
  	 * so we don't much care if the command fails!
  	 *
! 	 * All of the substitutions described in aesub(5) are available.
  	 */
! 	sub_var_set("1", "${project}");
! 	sub_var_set("2", "${change}");
! 	sub_var_set("3", "${developer}");
! 	sub_var_set("4", "${reviewer}");
! 	the_command = pstate_data->review_pass_notify_command;
! 	the_command = substitute(cp, the_command);
  
  	/*
  	 * execute the command
  	 */
! 	dd = change_development_directory_get(cp, 0);
  	change_become(cp);
  	os_execute(the_command, OS_EXEC_FLAG_NO_INPUT + OS_EXEC_FLAG_ERROK, dd);
  	str_free(the_command);
***************
*** 1695,1707 ****
  
  void
  change_run_review_pass_undo_notify_command(cp)
! 	change_t	*cp;
  {
  	pstate		pstate_data;
! 	string_t	*the_command;
! 	char		num[20];
! 	string_t	*dd;
! 	string_t	*notify;
  
  	/*
  	 * make sure there is one
--- 1687,1698 ----
  
  void
  change_run_review_pass_undo_notify_command(cp)
! 	change_ty	*cp;
  {
  	pstate		pstate_data;
! 	string_ty	*the_command;
! 	string_ty	*dd;
! 	string_ty	*notify;
  
  	/*
  	 * make sure there is one
***************
*** 1720,1747 ****
  	 * it happens after the data is written and the locks are released,
  	 * so we don't much care if the command fails!
  	 *
! 	 *	%1 = project name
! 	 *	%2 = change number
! 	 *	%3 = developer
! 	 *	%4 = reviewer
  	 */
! 	sprintf(num, "%ld", cp->number);
! 	the_command =
! 		substitute
! 		(
! 			cp,
! 			notify->str_text,
! 			project_name_get(cp->pp)->str_text,
! 			num,
! 			change_developer_name(cp)->str_text,
! 			change_reviewer_name(cp)->str_text,
! 			(char *)0
! 		);
  
  	/*
  	 * execute the command
  	 */
! 	dd = change_development_directory_get(cp);
  	change_become(cp);
  	os_execute(the_command, OS_EXEC_FLAG_NO_INPUT + OS_EXEC_FLAG_ERROK, dd);
  	str_free(the_command);
--- 1711,1728 ----
  	 * it happens after the data is written and the locks are released,
  	 * so we don't much care if the command fails!
  	 *
! 	 * All of the substitutions described in aesub(5) are available.
  	 */
! 	sub_var_set("1", "${project}");
! 	sub_var_set("2", "${change}");
! 	sub_var_set("3", "${developer}");
! 	sub_var_set("4", "${reviewer}");
! 	the_command = substitute(cp, notify);
  
  	/*
  	 * execute the command
  	 */
! 	dd = change_development_directory_get(cp, 0);
  	change_become(cp);
  	os_execute(the_command, OS_EXEC_FLAG_NO_INPUT + OS_EXEC_FLAG_ERROK, dd);
  	str_free(the_command);
***************
*** 1757,1768 ****
  
  void
  change_run_review_fail_notify_command(cp)
! 	change_t	*cp;
  {
  	pstate		pstate_data;
! 	string_t	*the_command;
! 	char		num[20];
! 	string_t	*dd;
  
  	/*
  	 * make sure there is one
--- 1738,1748 ----
  
  void
  change_run_review_fail_notify_command(cp)
! 	change_ty	*cp;
  {
  	pstate		pstate_data;
! 	string_ty	*the_command;
! 	string_ty	*dd;
  
  	/*
  	 * make sure there is one
***************
*** 1781,1808 ****
  	 * In doing it after the locks are released,
  	 * the lists will be accurate (e.g. list of files in change).
  	 *
! 	 *	%1 = project name
! 	 *	%2 = change number
! 	 *	%3 = developer
! 	 *	%4 = reviewer
  	 */
! 	sprintf(num, "%ld", cp->number);
! 	the_command =
! 		substitute
! 		(
! 			cp,
! 			pstate_data->review_fail_notify_command->str_text,
! 			project_name_get(cp->pp)->str_text,
! 			num,
! 			change_developer_name(cp)->str_text,
! 			change_reviewer_name(cp)->str_text,
! 			(char *)0
! 		);
  
  	/*
  	 * execute the command
  	 */
! 	dd = change_development_directory_get(cp);
  	change_become(cp);
  	os_execute(the_command, OS_EXEC_FLAG_NO_INPUT + OS_EXEC_FLAG_ERROK, dd);
  	str_free(the_command);
--- 1761,1779 ----
  	 * In doing it after the locks are released,
  	 * the lists will be accurate (e.g. list of files in change).
  	 *
! 	 * All of the substitutions described in aesub(5) are available.
  	 */
! 	sub_var_set("1", "${project}");
! 	sub_var_set("2", "${change}");
! 	sub_var_set("3", "${developer}");
! 	sub_var_set("4", "${reviewer}");
! 	the_command = pstate_data->review_fail_notify_command;
! 	the_command = substitute(cp, the_command);
  
  	/*
  	 * execute the command
  	 */
! 	dd = change_development_directory_get(cp, 0);
  	change_become(cp);
  	os_execute(the_command, OS_EXEC_FLAG_NO_INPUT + OS_EXEC_FLAG_ERROK, dd);
  	str_free(the_command);
***************
*** 1818,1833 ****
  
  void
  change_run_history_get_command(cp, file_name, edit_number, output_file, up)
! 	change_t	*cp;
! 	string_t	*file_name;
! 	string_t	*edit_number;
! 	string_t	*output_file;
! 	user_t		*up;
  {
! 	string_t	*hist;
! 	string_t	*dir;
  	cstate		cstate_data;
! 	string_t	*the_command;
  	pconf		pconf_data;
  
  	/*
--- 1789,1803 ----
  
  void
  change_run_history_get_command(cp, file_name, edit_number, output_file, up)
! 	change_ty	*cp;
! 	string_ty	*file_name;
! 	string_ty	*edit_number;
! 	string_ty	*output_file;
! 	user_ty		*up;
  {
! 	string_ty	*dir;
  	cstate		cstate_data;
! 	string_ty	*the_command;
  	pconf		pconf_data;
  
  	/*
***************
*** 1834,1857 ****
  	 * If the edit numbers differ, extract the
  	 * appropriate edit from the baseline (use the
  	 * history-get-command) into a file in /tmp
! 	 * %1 = history file
! 	 * %2 = edit number
! 	 * %3 = output file
  	 */
  	trace(("change_run_history_get_command(cp = %08lX)\n{\n"/*}*/, cp));
! 	hist = str_format("%S/%S", project_history_path_get(cp->pp), file_name);
  	pconf_data = change_pconf_get(cp);
! 	the_command =
! 		substitute
! 		(
! 			cp,
! 			pconf_data->history_get_command->str_text,
! 			hist->str_text,
! 			edit_number->str_text,
! 			output_file->str_text,
! 			(char *)0
! 		);
! 	str_free(hist);
  
  	/*
  	 * run the command as the current user
--- 1804,1838 ----
  	 * If the edit numbers differ, extract the
  	 * appropriate edit from the baseline (use the
  	 * history-get-command) into a file in /tmp
! 	 *
! 	 * All of the substitutions described in aesub(5) are available;
! 	 * in addition
! 	 *
! 	 * ${History}
! 	 *	history file
! 	 *
! 	 * ${Edit}
! 	 *	edit number
! 	 *
! 	 * ${Output}
! 	 *	output file
  	 */
  	trace(("change_run_history_get_command(cp = %08lX)\n{\n"/*}*/, cp));
! 	sub_var_set
! 	(
! 		"History",
! 		"%S/%S",
! 		project_history_path_get(cp->pp),
! 		file_name
! 	);
! 	sub_var_set("Edit", "%S", edit_number);
! 	sub_var_set("Output", "%S", output_file);
! 	sub_var_set("1", "${history}");
! 	sub_var_set("2", "${edit}");
! 	sub_var_set("3", "${output}");
  	pconf_data = change_pconf_get(cp);
! 	the_command = pconf_data->history_get_command;
! 	the_command = substitute(cp, the_command);
  
  	/*
  	 * run the command as the current user
***************
*** 1859,1870 ****
  	 */
  	cstate_data = change_cstate_get(cp);
  	if (cstate_data->state == cstate_state_being_integrated)
! 		dir = change_integration_directory_get(cp);
  	else
! 		dir = change_development_directory_get(cp);
  	user_become(up);
  	os_execute(the_command, OS_EXEC_FLAG_NO_INPUT, dir);
! 	os_become_undo();
  	str_free(the_command);
  	trace((/*{*/"}\n"));
  }
--- 1840,2141 ----
  	 */
  	cstate_data = change_cstate_get(cp);
  	if (cstate_data->state == cstate_state_being_integrated)
! 		dir = change_integration_directory_get(cp, 0);
  	else
! 		dir = change_development_directory_get(cp, 0);
  	user_become(up);
  	os_execute(the_command, OS_EXEC_FLAG_NO_INPUT, dir);
! 	user_become_undo();
! 	str_free(the_command);
! 	trace((/*{*/"}\n"));
! }
! 
! 
! void
! change_development_directory_clear(cp)
! 	change_ty	*cp;
! {
! 	cstate		cstate_data;
! 
! 	cstate_data = change_cstate_get(cp);
! 	assert(cstate_data->development_directory);
! 	if (cstate_data->development_directory)
! 	{
! 		str_free(cstate_data->development_directory);
! 		cstate_data->development_directory = 0;
! 	}
! }
! 
! 
! void
! change_integration_directory_clear(cp)
! 	change_ty	*cp;
! {
! 	cstate		cstate_data;
! 
! 	cstate_data = change_cstate_get(cp);
! 	assert(cstate_data->integration_directory);
! 	if (cstate_data->integration_directory)
! 	{
! 		str_free(cstate_data->integration_directory);
! 		cstate_data->integration_directory = 0;
! 	}
! }
! 
! 
! void
! change_run_history_create_command(cp, filename)
! 	change_ty	*cp;
! 	string_ty	*filename;
! {
! 	string_ty	*hp;
! 	string_ty	*id;
! 	pconf		pconf_data;
! 	string_ty	*the_command;
! 
! 	/*
! 	 * create a new history
! 	 * All of the substitutions described in aesub(5) are avaliable.
! 	 * In addition:
! 	 *
! 	 * ${Input}
! 	 *	absolute path of source file
! 	 *
! 	 * ${History}
! 	 *	absolute path of history file
! 	 */
! 	trace(("change_run_history_create_command(cp = %08lX, \
! filename = \"%s\")\n{\n"/*}*/, (long)cp, filename->str_text));
! 	pconf_data = change_pconf_get(cp);
! 	hp = project_history_path_get(cp->pp);
! 	id = change_integration_directory_get(cp, 0);
! 	sub_var_set("Input", "%S/%S", id, filename);
! 	sub_var_set("History", "%S/%S", hp, filename);
! 	sub_var_set("1", "${input}");
! 	sub_var_set("2", "${history}");
! 	the_command = pconf_data->history_create_command;
! 	the_command = substitute(cp, the_command);
! 	project_become(cp->pp);
! 	os_mkdir_between(hp, filename, 02755);
! 	os_execute(the_command, OS_EXEC_FLAG_NO_INPUT, id);
! 	project_become_undo();
! 	str_free(the_command);
! 	trace((/*{*/"}\n"));
! }
! 
! 
! void
! change_run_history_put_command(cp, filename)
! 	change_ty	*cp;
! 	string_ty	*filename;
! {
! 	string_ty	*hp;
! 	string_ty	*id;
! 	pconf		pconf_data;
! 	string_ty	*the_command;
! 
! 	/*
! 	 * Update and existing history.
! 	 * All of the substitutions described in aesub(5) are avaliable.
! 	 * In addition:
! 	 *
! 	 * ${Input}
! 	 *	absolute path of source file
! 	 *
! 	 * ${History}
! 	 *	absolute path of history file
! 	 */
! 	trace(("change_run_history_put_command(cp = %08lX, \
! filename = \"%s\")\n{\n"/*}*/, (long)cp, filename->str_text));
! 	pconf_data = change_pconf_get(cp);
! 	hp = project_history_path_get(cp->pp);
! 	id = change_integration_directory_get(cp, 0);
! 	sub_var_set("Input", "%S/%S", id, filename);
! 	sub_var_set("History", "%S/%S", hp, filename);
! 	sub_var_set("1", "${input}");
! 	sub_var_set("2", "${history}");
! 	the_command = pconf_data->history_put_command;
! 	the_command = substitute(cp, the_command);
! 	project_become(cp->pp);
! 	os_execute(the_command, OS_EXEC_FLAG_NO_INPUT, id);
! 	project_become_undo();
! 	str_free(the_command);
! 	trace((/*{*/"}\n"));
! }
! 
! 
! string_ty *
! change_run_history_query_command(cp, filename)
! 	change_ty	*cp;
! 	string_ty	*filename;
! {
! 	string_ty	*hp;
! 	string_ty	*bl;
! 	pconf		pconf_data;
! 	string_ty	*the_command;
! 	string_ty	*result;
! 
! 	/*
! 	 * Ask the history file what its edit number is.
! 	 * We use this method because the string
! 	 * returned is essentially random,
! 	 * between different history programs.
! 	 * All of the substitutions described in aesub(5) are available.
! 	 * In addition
! 	 *
! 	 * ${History}
! 	 *	absolute path of history file
! 	 */
! 	trace(("change_run_history_query_command(cp = %08lX, \
! filename = \"%s\")\n{\n"/*}*/, (long)cp, filename->str_text));
! 	pconf_data = change_pconf_get(cp);
! 	hp = project_history_path_get(cp->pp);
! 	bl = project_baseline_path_get(cp->pp, 0);
! 	sub_var_set("History", "%S/%S", hp, filename);
! 	sub_var_set("1", "${history}");
! 	the_command = pconf_data->history_query_command;
! 	the_command = substitute(cp, the_command);
! 	project_become(cp->pp);
! 	result =
! 		os_execute_slurp
! 		(
! 			the_command,
! 			OS_EXEC_FLAG_NO_INPUT,
! 			bl
! 		);
! 	project_become_undo();
! 	str_free(the_command);
! 	if (!result->str_length)
! 	{
! 		fatal
! 		(
! 	  "the history_query_command returned the empty string, this is invalid"
! 		);
! 	}
! 	trace(("return \"%s\";\n", result->str_text));
! 	trace((/*{*/"}\n"));
! 	return result;
! }
! 
! 
! void
! change_run_diff_command(cp, up, original, input, output)
! 	change_ty	*cp;
! 	user_ty		*up;
! 	string_ty	*original;
! 	string_ty	*input;
! 	string_ty	*output;
! {
! 	pconf		pconf_data;
! 	string_ty	*dd;
! 	string_ty	*the_command;
! 
! 	/*
! 	 * Run the diff_command.
! 	 * All of the substitutions described in aesub(5) are available.
! 	 * In addition
! 	 *
! 	 * ${Original}
! 	 *	absolute path of original file copied from the baseline
! 	 *	usually, but not always
! 	 *
! 	 * ${Input}
! 	 *	absolute path of current file in the development directory
! 	 *	usually, but not always
! 	 *
! 	 * ${Output}
! 	 *	absolute path of file in which to write the difference listing
! 	 *	usually in the development diretcory
! 	 */
! 	trace
! 	((
! 		"change_run_diff_command(cp = %08lX, up = %08lX, \
! original = \"%s\", input = \"%s\", output = \"%s\")\n{\n"/*}*/,
! 		(long)cp,
! 		(long)up,
! 		original->str_text,
! 		input->str_text,
! 		output->str_text
! 	));
! 	pconf_data = change_pconf_get(cp);
! 	dd = change_development_directory_get(cp, 0);
! 	sub_var_set("ORiginal", "%S", original);
! 	sub_var_set("Input", "%S", input);
! 	sub_var_set("Output", "%S", output);
! 	sub_var_set("1", "${original}");
! 	sub_var_set("2", "${input}");
! 	sub_var_set("3", "${output}");
! 	the_command = pconf_data->diff_command;
! 	the_command = substitute(cp, the_command);
! 	trace_string(the_command->str_text);
! 	user_become(up);
! 	os_execute(the_command, OS_EXEC_FLAG_NO_INPUT, dd);
! 	user_become_undo();
! 	str_free(the_command);
! 	trace((/*{*/"}\n"));
! }
! 
! 
! void
! change_run_diff3_command(cp, up, original, most_recent, input, output)
! 	change_ty	*cp;
! 	user_ty		*up;
! 	string_ty	*original;
! 	string_ty	*most_recent;
! 	string_ty	*input;
! 	string_ty	*output;
! {
! 	pconf		pconf_data;
! 	string_ty	*the_command;
! 	string_ty	*dd;
! 
! 	/*
! 	 * Run the diff3_command.
! 	 * All of the substitutions described in aesub(5) are available.
! 	 * In addition
! 	 *
! 	 * ${Original}
! 	 *	absolute path of original file copied from the baseline
! 	 *	usually somewhere in /tmp
! 	 *
! 	 * ${Most_Recent}
! 	 *	absolute path of original file currently in the baseline
! 	 *	usually, but not always
! 	 *
! 	 * ${Input}
! 	 *	absolute path of current file in the development directory
! 	 *	usually, but not always
! 	 *
! 	 * ${Output}
! 	 *	absolute path of file in which to write the difference listing
! 	 *	usually in the development diretcory
! 	 */
! 	trace
! 	((
! 		"change_run_diff3_command(cp = %08lX, up = %08lX, original = \
! \"%s\", most_recent = \"%s\", input = \"%s\", output = \"%s\")\n{\n"/*}*/,
! 		(long)cp,
! 		(long)up,
! 		original->str_text,
! 		most_recent->str_text,
! 		input->str_text,
! 		output->str_text
! 	));
! 	pconf_data = change_pconf_get(cp);
! 	dd = change_development_directory_get(cp, 0);
! 	sub_var_set("ORiginal", "%S", original);
! 	sub_var_set("Most_Recent", "%S", most_recent);
! 	sub_var_set("Input", "%S", input);
! 	sub_var_set("Output", "%S", output);
! 	sub_var_set("1", "${original}");
! 	sub_var_set("2", "${most_recent}");
! 	sub_var_set("3", "${input}");
! 	sub_var_set("4", "${output}");
! 	the_command = pconf_data->diff3_command;
! 	the_command = substitute(cp, the_command);
! 	user_become(up);
! 	os_execute(the_command, OS_EXEC_FLAG_NO_INPUT, dd);
! 	user_become_undo();
  	str_free(the_command);
  	trace((/*{*/"}\n"));
  }
Index: aegis/change.h
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 28,48 ****
  #include <pconf.h>
  
  struct wlist;
! struct user_t;
  
! typedef struct change_t change_t;
! struct change_t
  {
  	long		reference_count;
! 	struct project_t *pp;
  	long		number;
  	int		is_a_new_file;
! 	string_t	*filename;
  	cstate		cstate_data;
! 	string_t	*development_directory;
! 	string_t	*integration_directory;
! 	string_t	*logfile;
! 	string_t	*pconf_path;
  	pconf		pconf_data;
  	long		lock_magic;
  	/*
--- 28,48 ----
  #include <pconf.h>
  
  struct wlist;
! struct user_ty;
  
! typedef struct change_ty change_ty;
! struct change_ty
  {
  	long		reference_count;
! 	struct project_ty *pp;
  	long		number;
  	int		is_a_new_file;
! 	string_ty	*filename;
  	cstate		cstate_data;
! 	string_ty	*development_directory;
! 	string_ty	*integration_directory;
! 	string_ty	*logfile;
! 	string_ty	*pconf_path;
  	pconf		pconf_data;
  	long		lock_magic;
  	/*
***************
*** 51,96 ****
  	 */
  };
  
! change_t *change_alloc _((struct project_t *, long));
! void change_free _((change_t *));
! change_t *change_copy _((change_t *));
! void change_bind_existing _((change_t *));
! void change_bind_new _((change_t *));
! cstate change_cstate_get _((change_t *));
! void change_cstate_write _((change_t *));
! cstate_src change_src_find _((change_t *, string_t *));
! void change_src_remove _((change_t *, string_t *));
! cstate_src change_src_new _((change_t *));
! cstate_history change_history_new _((change_t *, struct user_t *));
! string_t *change_developer_name _((change_t *));
! string_t *change_reviewer_name _((change_t *));
! string_t *change_integrator_name _((change_t *));
! void change_development_directory_set _((change_t *, string_t *));
! void change_integration_directory_set _((change_t *, string_t *));
! string_t *change_development_directory_get _((change_t *));
! string_t *change_integration_directory_get _((change_t *));
! string_t *change_logfile_get _((change_t *));
! void change_cstate_lock_prepare _((change_t *));
! void change_error _((change_t *, char *, ...));
! void change_fatal _((change_t *, char *, ...));
! void change_verbose _((change_t *, char *, ...));
! string_t *change_pconf_path_get _((change_t *));
! pconf change_pconf_get _((change_t *));
! void change_run_change_file_command _((change_t *, struct wlist *,
! 	struct user_t *));
! void change_run_project_file_command _((change_t *));
! void change_run_develop_end_notify_command _((change_t *));
! void change_run_develop_end_undo_notify_command _((change_t *));
! void change_run_review_pass_notify_command _((change_t *));
! void change_run_review_pass_undo_notify_command _((change_t *));
! void change_run_review_fail_notify_command _((change_t *));
! void change_run_integrate_pass_notify_command _((change_t *));
! void change_run_integrate_fail_notify_command _((change_t *));
! void change_run_history_get_command _((change_t *cp, string_t *file_name,
! 	string_t *edit_number, string_t *output_file, struct user_t *up));
! string_t *change_file_template _((change_t *, string_t *));
! void change_become _((change_t *));
  void change_become_undo _((void));
! int change_umask _((change_t *));
  
  #endif /* CHANGE_H */
--- 51,107 ----
  	 */
  };
  
! change_ty *change_alloc _((struct project_ty *, long));
! void change_free _((change_ty *));
! change_ty *change_copy _((change_ty *));
! void change_bind_existing _((change_ty *));
! void change_bind_new _((change_ty *));
! cstate change_cstate_get _((change_ty *));
! void change_cstate_write _((change_ty *));
! cstate_src change_src_find _((change_ty *, string_ty *));
! void change_src_remove _((change_ty *, string_ty *));
! cstate_src change_src_new _((change_ty *));
! cstate_history change_history_new _((change_ty *, struct user_ty *));
! string_ty *change_developer_name _((change_ty *));
! string_ty *change_reviewer_name _((change_ty *));
! string_ty *change_integrator_name _((change_ty *));
! void change_development_directory_set _((change_ty *, string_ty *));
! void change_integration_directory_set _((change_ty *, string_ty *));
! string_ty *change_development_directory_get _((change_ty *, int));
! string_ty *change_integration_directory_get _((change_ty *, int));
! string_ty *change_logfile_get _((change_ty *));
! void change_cstate_lock_prepare _((change_ty *));
! void change_error _((change_ty *, char *, ...));
! void change_fatal _((change_ty *, char *, ...));
! void change_verbose _((change_ty *, char *, ...));
! string_ty *change_pconf_path_get _((change_ty *));
! pconf change_pconf_get _((change_ty *));
! void change_run_change_file_command _((change_ty *, struct wlist *,
! 	struct user_ty *));
! void change_run_project_file_command _((change_ty *));
! void change_run_develop_end_notify_command _((change_ty *));
! void change_run_develop_end_undo_notify_command _((change_ty *));
! void change_run_review_pass_notify_command _((change_ty *));
! void change_run_review_pass_undo_notify_command _((change_ty *));
! void change_run_review_fail_notify_command _((change_ty *));
! void change_run_integrate_pass_notify_command _((change_ty *));
! void change_run_integrate_fail_notify_command _((change_ty *));
! void change_run_history_get_command _((change_ty *cp, string_ty *file_name,
! 	string_ty *edit_number, string_ty *output_file, struct user_ty *up));
! void change_run_history_create_command _((change_ty *cp, string_ty *file_name));
! void change_run_history_put_command _((change_ty *cp, string_ty *file_name));
! string_ty *change_run_history_query_command _((change_ty *cp,
! 	string_ty *file_name));
! void change_run_diff_command _((change_ty *cp, struct user_ty *up,
! 	string_ty *original, string_ty *input, string_ty *output));
! void change_run_diff3_command _((change_ty *cp, struct user_ty *up,
! 	string_ty *original, string_ty *most_recent, string_ty *input,
! 	string_ty *output));
! string_ty *change_file_template _((change_ty *, string_ty *));
! void change_become _((change_ty *));
  void change_become_undo _((void));
! int change_umask _((change_ty *));
! void change_development_directory_clear _((change_ty *));
! void change_integration_directory_clear _((change_ty *));
  
  #endif /* CHANGE_H */
Index: aegis/chdir.c
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 84,92 ****
  "",
  "	-Change <number>",
  "		This option may be used to specify a particular",
! "		change within a project.  If the user is only",
! "		working on one change within a project, that is",
! "		the default change number.",
  "",
  "	-Development_Directory",
  "		This option is ised to specify that the",
--- 84,97 ----
  "",
  "	-Change <number>",
  "		This option may be used to specify a particular",
! "		change within a project.  When no -Change option is",
! "		specified, the AEGIS_CHANGE environment variable is",
! "		consulted.  If that does not exist, the user's",
! "		$HOME/.aegisrc file is examined for a default change",
! "		field (see aeuconf(5) for more information).  If",
! "		that does not exist, when the user is only working",
! "		on one change within a project, that is the default",
! "		change number.  Otherwise, it is an error.",
  "",
  "	-Development_Directory",
  "		This option is ised to specify that the",
***************
*** 106,119 ****
  "",
  "	-Project <name>",
  "		This option may be used to select the project of",
! "		interest.  When no -Project option is specified, if",
! "		the user is only working on changes within a single",
! "		project, the project name defaults to that project;",
! "		if the user is currently working on changes to more",
! "		than one project, or is not working on changes to",
! "		any project, the user's $HOME/.%src file is",
! "		examined for a default project field (see aeuconf(5)",
! "		for more information).",
  "",
  "	-TERse",
  "		This option may be used to cause listings to",
--- 111,124 ----
  "",
  "	-Project <name>",
  "		This option may be used to select the project of",
! "		interest.  When no -Project option is specified, the",
! "		AEGIS_PROJECT environment variable is consulted.  If",
! "		that does not exist, the user's $HOME/.aegisrc file",
! "		is examined for a default project field (see",
! "		aeuconf(5) for more information).  If that does not",
! "		exist, when the user is only working on changes",
! "		within a single project, the project name defaults",
! "		to that project.  Otherwise, it is an error.",
  "",
  "	-TERse",
  "		This option may be used to cause listings to",
***************
*** 162,168 ****
  static void
  change_directory_list()
  {
! 	string_t	*project_name;
  
  	trace(("change_directory_list()\n{\n"/*}*/));
  	arglex();
--- 167,173 ----
  static void
  change_directory_list()
  {
! 	string_ty	*project_name;
  
  	trace(("change_directory_list()\n{\n"/*}*/));
  	arglex();
***************
*** 212,224 ****
  	char		*subdir = 0;
  	int		devdir = 0;
  	cstate		cstate_data;
! 	string_t	*d;
  	int		baseline = 0;
! 	string_t	*project_name;
! 	project_t	*pp;
  	long		change_number;
! 	change_t	*cp;
! 	user_t		*up;
  
  	trace(("change_directory_main()\n{\n"/*}*/));
  	project_name = 0;
--- 217,229 ----
  	char		*subdir = 0;
  	int		devdir = 0;
  	cstate		cstate_data;
! 	string_ty	*d;
  	int		baseline = 0;
! 	string_ty	*project_name;
! 	project_ty	*pp;
  	long		change_number;
! 	change_ty	*cp;
! 	user_ty		*up;
  
  	trace(("change_directory_main()\n{\n"/*}*/));
  	project_name = 0;
***************
*** 305,312 ****
  	if (baseline)
  	{
  		if (change_number)
! 			fatal("the -BaseLine and -Change options are mutually exclusive");
! 		d = project_baseline_path_get(pp);
  		cp = 0;
  	}
  	else
--- 310,322 ----
  	if (baseline)
  	{
  		if (change_number)
! 		{
! 			fatal
! 			(
! 		      "the -BaseLine and -Change options are mutually exclusive"
! 			);
! 		}
! 		d = project_baseline_path_get(pp, 0);
  		cp = 0;
  	}
  	else
***************
*** 328,334 ****
  		case cstate_state_being_integrated:
  			if (!devdir)
  			{
! 				d = cstate_data->integration_directory;
  				break;
  			}
  			/* fall through... */
--- 338,344 ----
  		case cstate_state_being_integrated:
  			if (!devdir)
  			{
! 				d = change_integration_directory_get(cp, 0);
  				break;
  			}
  			/* fall through... */
***************
*** 336,342 ****
  		case cstate_state_awaiting_integration:
  		case cstate_state_being_reviewed:
  		case cstate_state_being_developed:
! 			d = cstate_data->development_directory;
  			break;
  		}
  	}
--- 346,352 ----
  		case cstate_state_awaiting_integration:
  		case cstate_state_being_reviewed:
  		case cstate_state_being_developed:
! 			d = change_development_directory_get(cp, 0);
  			break;
  		}
  	}
***************
*** 347,358 ****
  	 */
  	if (subdir)
  	{
! 		string_t *tmp;
  
  		tmp = str_format("%S/%s", d, subdir);
  		user_become(up);
! 		d = os_pathname(tmp);
! 		os_become_undo();
  		str_free(tmp);
  	}
  
--- 357,368 ----
  	 */
  	if (subdir)
  	{
! 		string_ty *tmp;
  
  		tmp = str_format("%S/%s", d, subdir);
  		user_become(up);
! 		d = os_pathname(tmp, 0);
! 		user_become_undo();
  		str_free(tmp);
  	}
  
Index: aegis/chdir.h
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
Index: aegis/col.c
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 27,32 ****
--- 27,33 ----
  
  #include <col.h>
  #include <error.h>
+ #include <glue.h>
  #include <mem.h>
  #include <option.h>
  #include <os.h>
***************
*** 38,45 ****
  #define PRINTER_THRESHOLD 33
  
  
! typedef struct col_t col_t;
! struct col_t
  {
  	int	icol;
  	int	ocol;
--- 39,46 ----
  #define PRINTER_THRESHOLD 33
  
  
! typedef struct col_ty col_ty;
! struct col_ty
  {
  	int	icol;
  	int	ocol;
***************
*** 55,61 ****
  };
  
  static	size_t	ncols;
! static	col_t	**col;
  static	char	*filename;
  static	FILE	*fp;
  static	char	pager[] = "PAGER";
--- 56,62 ----
  };
  
  static	size_t	ncols;
! static	col_ty	**col;
  static	char	*filename;
  static	FILE	*fp;
  static	char	pager[] = "PAGER";
***************
*** 104,110 ****
  	{
  		filename = mem_copy_string(s);
  		os_become_orig();
! 		fp = fopen(filename, "w");
  		if (!fp)
  			nfatal("open(\"%s\")", filename);
  		os_become_undo();
--- 105,111 ----
  	{
  		filename = mem_copy_string(s);
  		os_become_orig();
! 		fp = glue_fopen(filename, "w");
  		if (!fp)
  			nfatal("open(\"%s\")", filename);
  		os_become_undo();
***************
*** 176,182 ****
  col_close()
  {
  	int	j;
! 	col_t	*cp;
  
  	/*
  	 * free the memory consumed by the columns
--- 177,183 ----
  col_close()
  {
  	int	j;
! 	col_ty	*cp;
  
  	/*
  	 * free the memory consumed by the columns
***************
*** 211,218 ****
  	/*
  	 * write the last of the output
  	 */
! 	if (fflush(fp))
! 		col_error();
  
  	/*
  	 * close the output
--- 212,227 ----
  	/*
  	 * write the last of the output
  	 */
! 	if (filename != pager)
! 	{
! 		if (glue_fflush(fp))
! 			col_error();
! 	}
! 	else
! 	{
! 		if (fflush(fp))
! 			col_error();
! 	}
  
  	/*
  	 * close the output
***************
*** 219,225 ****
  	 */
  	if (filename != pager)
  	{
! 		if (fclose(fp))
  			nfatal("close(\"%s\")", filename);
  		mem_free(filename);
  	}
--- 228,234 ----
  	 */
  	if (filename != pager)
  	{
! 		if (glue_fclose(fp))
  			nfatal("close(\"%s\")", filename);
  		mem_free(filename);
  	}
***************
*** 256,262 ****
  	int	min;
  	int	max;
  {
! 	col_t	*cp;
  
  	trace(("col_create(min = %d, max = %d)\n{\n"/*}*/, min, max));
  	if (!max)
--- 265,271 ----
  	int	min;
  	int	max;
  {
! 	col_ty	*cp;
  
  	trace(("col_create(min = %d, max = %d)\n{\n"/*}*/, min, max));
  	if (!max)
***************
*** 263,273 ****
  	{
  		max = page_width;
  		if (max <= min)
! 			max = min + 1;
  	}
  	assert(min < max);
! 	cp = (col_t *)mem_alloc(sizeof(col_t));
! 	*(col_t **)enlarge(&ncols, (char **)&col, sizeof(col_t *)) = cp;
  	cp->min = min;
  	cp->max = max;
  	cp->text_length_max = 0;
--- 272,289 ----
  	{
  		max = page_width;
  		if (max <= min)
! 			max = min + 8;
  	}
+ 
+ 	/*
+ 	 * try to get sensable behaviour out of narrow windows
+ 	 */
+ 	if (max > page_width)
+ 		page_width = max;
+ 
  	assert(min < max);
! 	cp = (col_ty *)mem_alloc(sizeof(col_ty));
! 	*(col_ty **)enlarge(&ncols, (char **)&col, sizeof(col_ty *)) = cp;
  	cp->min = min;
  	cp->max = max;
  	cp->text_length_max = 0;
***************
*** 277,282 ****
--- 293,299 ----
  	cp->ocol = 0;
  	cp->heading = 0;
  	cp->heading_required = 0;
+ 	cp->top_of_page_diverted = 0;
  	trace(("return %d;\n", ncols - 1));
  	trace((/*{*/"}\n"));
  	return (ncols - 1);
***************
*** 288,294 ****
   *	col_save_char
   *
   * SYNOPSIS
!  *	void col_save_char(col_t *cp, int c);
   *
   * DESCRIPTION
   *	The col_save_char function is used to
--- 305,311 ----
   *	col_save_char
   *
   * SYNOPSIS
!  *	void col_save_char(col_ty *cp, int c);
   *
   * DESCRIPTION
   *	The col_save_char function is used to
***************
*** 299,309 ****
   *	c	- the character to append
   */
  
! static void col_save_char _((col_t *, int));
  
  static void
  col_save_char(cp, c)
! 	col_t	*cp;
  	int	c;
  {
  	if (cp->text_length >= cp->text_length_max)
--- 316,326 ----
   *	c	- the character to append
   */
  
! static void col_save_char _((col_ty *, int));
  
  static void
  col_save_char(cp, c)
! 	col_ty	*cp;
  	int	c;
  {
  	if (cp->text_length >= cp->text_length_max)
***************
*** 332,338 ****
   *	col_putchar
   *
   * SYNOPSIS
!  *	void col_putchar(col_t *cp, int c);
   *
   * DESCRIPTION
   *	The col_putchar function is used to
--- 349,355 ----
   *	col_putchar
   *
   * SYNOPSIS
!  *	void col_putchar(col_ty *cp, int c);
   *
   * DESCRIPTION
   *	The col_putchar function is used to
***************
*** 347,357 ****
   *	c	- the character to append
   */
  
! static void col_putchar _((col_t *, int));
  
  static void
  col_putchar(cp, c)
! 	col_t	*cp;
  	int	c;
  {
  	switch (c)
--- 364,374 ----
   *	c	- the character to append
   */
  
! static void col_putchar _((col_ty *, int));
  
  static void
  col_putchar(cp, c)
! 	col_ty	*cp;
  	int	c;
  {
  	switch (c)
***************
*** 419,425 ****
  	int		cid;
  	char		*s;
  {
! 	col_t		*cp;
  
  	trace(("col_puts(cid = %d, s = %08lX)\n{\n"/*}*/, cid, s));
  	assert(cid >= 0 && cid < ncols);
--- 436,442 ----
  	int		cid;
  	char		*s;
  {
! 	col_ty		*cp;
  
  	trace(("col_puts(cid = %d, s = %08lX)\n{\n"/*}*/, cid, s));
  	assert(cid >= 0 && cid < ncols);
***************
*** 491,497 ****
  top_of_page_mark()
  {
  	int	j;
! 	col_t	*cp;
  
  	top_of_page = 1;
  	for (j = 0; j < ncols; ++j)
--- 508,514 ----
  top_of_page_mark()
  {
  	int	j;
! 	col_ty	*cp;
  
  	top_of_page = 1;
  	for (j = 0; j < ncols; ++j)
***************
*** 544,552 ****
  	switch (c)
  	{
  	case '\n':
! 		putc('\n', fp);
  #ifdef DEBUG
! 		fflush(fp);
  #endif
  		in_col = 0;
  		out_col = 0;
--- 561,575 ----
  	switch (c)
  	{
  	case '\n':
! 		if (filename != pager)
! 			glue_fputc('\n', fp);
! 		else
! 			putc('\n', fp);
  #ifdef DEBUG
! 		if (filename != pager)
! 			glue_fflush(fp);
! 		else
! 			fflush(fp);
  #endif
  		in_col = 0;
  		out_col = 0;
***************
*** 566,586 ****
  	default:
  		while (((out_col + 8) & -8) <= in_col && out_col + 1 < in_col)
  		{
! 			putc('\t', fp);
  			out_col = (out_col + 8) & -8;
  		}
  		while (out_col < in_col)
  		{
! 			putc(' ', fp);
  			++out_col;
  		}
! 		putc(c, fp);
  		in_col++;
  		out_col++;
  		break;
  	}
! 	if (ferror(fp))
! 		col_error();
  }
  
  
--- 589,626 ----
  	default:
  		while (((out_col + 8) & -8) <= in_col && out_col + 1 < in_col)
  		{
! 			if (filename != pager)
! 				glue_fputc('\t', fp);
! 			else
! 				putc('\t', fp);
  			out_col = (out_col + 8) & -8;
  		}
  		while (out_col < in_col)
  		{
! 			if (filename != pager)
! 				glue_fputc(' ', fp);
! 			else
! 				putc(' ', fp);
  			++out_col;
  		}
! 		if (filename != pager)
! 			glue_fputc(c, fp);
! 		else
! 			putc(c, fp);
  		in_col++;
  		out_col++;
  		break;
  	}
! 	if (filename != pager)
! 	{
! 		if (glue_ferror(fp))
! 			col_error();
! 	}
! 	else
! 	{
! 		if (ferror(fp))
! 			col_error();
! 	}
  }
  
  
***************
*** 637,643 ****
  {
  	int	more;
  	int	j;
! 	col_t	*cp;
  
  	trace(("col_eoln_sub()\n{\n"/*}*/));
  	for (;;)
--- 677,683 ----
  {
  	int	more;
  	int	j;
! 	col_ty	*cp;
  
  	trace(("col_eoln_sub()\n{\n"/*}*/));
  	for (;;)
***************
*** 744,750 ****
  {
  	int	heading_required;
  	int	j;
! 	col_t	*cp;
  	char	tmp1[50];
  	char	*tmp2;
  	int	frac;
--- 784,790 ----
  {
  	int	heading_required;
  	int	j;
! 	col_ty	*cp;
  	char	tmp1[50];
  	char	*tmp2;
  	int	frac;
***************
*** 806,811 ****
--- 846,869 ----
  	col_emit_char('\n');
  
  	/*
+ 	 * in weird cases where the terminal is too narrow,
+ 	 * the headings can try to span pages.
+ 	 * If we are already top-of-page diverted, don't do it again.
+ 	 */
+ 	heading_required = 0;
+ 	for (j = 0; j < ncols; ++j)
+ 	{
+ 		if (col[j]->top_of_page_diverted)
+ 			heading_required--;
+ 	}
+ 	if (heading_required < 0)
+ 	{
+ 		for (j = 0; j < ncols; ++j)
+ 			col[j]->heading_required = 0;
+ 		return;
+ 	}
+ 
+ 	/*
  	 * divert for headings
  	 */
  	heading_required = 0;
***************
*** 812,817 ****
--- 870,876 ----
  	for (j = 0; j < ncols; ++j)
  	{
  		cp = col[j];
+ 		assert(!cp->top_of_page_diverted);
  		cp->top_of_page_diverted = cp->current;
  		if (cp->heading && cp->heading_required)
  		{
***************
*** 836,841 ****
--- 895,902 ----
  	{
  		cp = col[j];
  		cp->current = cp->top_of_page_diverted;
+ 		cp->heading_required = 0;
+ 		cp->top_of_page_diverted = 0;
  	}
  }
  
***************
*** 859,865 ****
  col_eoln()
  {
  	int	j;
! 	col_t	*cp;
  	int	heading_required;
  
  	/*
--- 920,926 ----
  col_eoln()
  {
  	int	j;
! 	col_ty	*cp;
  	int	heading_required;
  
  	/*
***************
*** 942,948 ****
  col_bol(cid)
  	int	cid;
  {
! 	col_t	*cp;
  
  	trace(("col_bol(cid = %d)\n{\n"/*}*/, cid));
  	assert(cid >= 0 && cid < ncols);
--- 1003,1009 ----
  col_bol(cid)
  	int	cid;
  {
! 	col_ty	*cp;
  
  	trace(("col_bol(cid = %d)\n{\n"/*}*/, cid));
  	assert(cid >= 0 && cid < ncols);
***************
*** 974,980 ****
  	int	cid;
  	char	*s;
  {
! 	col_t	*cp;
  
  	trace(("col_heading(cid = %d, s = %08lX)\n{\n"/*}*/, cid, s));
  	assert(cid >= 0 && cid < ncols);
--- 1035,1041 ----
  	int	cid;
  	char	*s;
  {
! 	col_ty	*cp;
  
  	trace(("col_heading(cid = %d, s = %08lX)\n{\n"/*}*/, cid, s));
  	assert(cid >= 0 && cid < ncols);
Index: aegis/col.h
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
Index: aegis/commit.c
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 44,50 ****
   * set at the time the commit call was issued.
   */
  
! enum what_t
  {
  	what_rename,
  	what_unlink_errok,
--- 44,50 ----
   * set at the time the commit call was issued.
   */
  
! enum what_ty
  {
  	what_rename,
  	what_unlink_errok,
***************
*** 51,73 ****
  	what_rmdir_errok,
  	what_rmdir_tree_errok
  };
! typedef enum what_t what_t;
  
! typedef struct action_t action_t;
! struct action_t
  {
! 	what_t		what;
! 	string_t	*path1;
! 	string_t	*path2;
! 	action_t	*next;
  	int		uid;
  	int		gid;
  	int		umask;
  };
  
! static	action_t	*head1;
! static	action_t	*tail1;
! static	action_t	*head2;
  
  
  /*
--- 51,73 ----
  	what_rmdir_errok,
  	what_rmdir_tree_errok
  };
! typedef enum what_ty what_ty;
  
! typedef struct action_ty action_ty;
! struct action_ty
  {
! 	what_ty		what;
! 	string_ty	*path1;
! 	string_ty	*path2;
! 	action_ty	*next;
  	int		uid;
  	int		gid;
  	int		umask;
  };
  
! static	action_ty	*head1;
! static	action_ty	*tail1;
! static	action_ty	*head2;
  
  
  /*
***************
*** 75,81 ****
   *	link1
   *
   * SYNOPSIS
!  *	void link1(what_t action, string_t *path1, string_t *path2);
   *
   * DESCRIPTION
   *	The link1 function is used to
--- 75,81 ----
   *	link1
   *
   * SYNOPSIS
!  *	void link1(what_ty action, string_ty *path1, string_ty *path2);
   *
   * DESCRIPTION
   *	The link1 function is used to
***************
*** 87,104 ****
   *	path2	- optional argument (NULL if not used)
   */
  
! static void link1 _((what_t, string_t *, string_t *));
  
  static void
  link1(what, path1, path2)
! 	what_t		what;
! 	string_t	*path1;
! 	string_t	*path2;
  {
! 	action_t	*new;
  
  	trace(("commit::link1(what = %d, path1 = %08lX, path2 = %08lX)\n{\n"/*}*/, what, path1, path2));
! 	new = (action_t *)mem_alloc(sizeof(action_t));
  	new->what = what;
  	os_become_query(&new->uid, &new->gid, &new->umask);
  	new->path1 = str_copy(path1);
--- 87,104 ----
   *	path2	- optional argument (NULL if not used)
   */
  
! static void link1 _((what_ty, string_ty *, string_ty *));
  
  static void
  link1(what, path1, path2)
! 	what_ty		what;
! 	string_ty	*path1;
! 	string_ty	*path2;
  {
! 	action_ty	*new;
  
  	trace(("commit::link1(what = %d, path1 = %08lX, path2 = %08lX)\n{\n"/*}*/, what, path1, path2));
! 	new = (action_ty *)mem_alloc(sizeof(action_ty));
  	new->what = what;
  	os_become_query(&new->uid, &new->gid, &new->umask);
  	new->path1 = str_copy(path1);
***************
*** 123,129 ****
   *	link2
   *
   * SYNOPSIS
!  *	void link2(what_t action, string_t *path1, string_t *path2);
   *
   * DESCRIPTION
   *	The link2 function is used to
--- 123,129 ----
   *	link2
   *
   * SYNOPSIS
!  *	void link2(what_ty action, string_ty *path1, string_ty *path2);
   *
   * DESCRIPTION
   *	The link2 function is used to
***************
*** 135,152 ****
   *	path2	- optional argument (NULL if not used)
   */
  
! static void link2 _((what_t, string_t *, string_t *));
  
  static void
  link2(what, path1, path2)
! 	what_t		what;
! 	string_t	*path1;
! 	string_t	*path2;
  {
! 	action_t	*new;
  
  	trace(("commit::link2(what = %d, path1 = %08lX, path2 = %08lX)\n{\n"/*}*/, what, path1, path2));
! 	new = (action_t *)mem_alloc(sizeof(action_t));
  	new->what = what;
  	os_become_query(&new->uid, &new->gid, &new->umask);
  	new->path1 = str_copy(path1);
--- 135,152 ----
   *	path2	- optional argument (NULL if not used)
   */
  
! static void link2 _((what_ty, string_ty *, string_ty *));
  
  static void
  link2(what, path1, path2)
! 	what_ty		what;
! 	string_ty	*path1;
! 	string_ty	*path2;
  {
! 	action_ty	*new;
  
  	trace(("commit::link2(what = %d, path1 = %08lX, path2 = %08lX)\n{\n"/*}*/, what, path1, path2));
! 	new = (action_ty *)mem_alloc(sizeof(action_ty));
  	new->what = what;
  	os_become_query(&new->uid, &new->gid, &new->umask);
  	new->path1 = str_copy(path1);
***************
*** 178,185 ****
  
  void
  commit_rename(from, to)
! 	string_t	*from;
! 	string_t	*to;
  {
  	trace(("commit_rename(from = %08lX, to = %08lX)\n{\n"/*}*/, from, to));
  	trace_string(from->str_text);
--- 178,185 ----
  
  void
  commit_rename(from, to)
! 	string_ty	*from;
! 	string_ty	*to;
  {
  	trace(("commit_rename(from = %08lX, to = %08lX)\n{\n"/*}*/, from, to));
  	trace_string(from->str_text);
***************
*** 207,217 ****
  
  void
  commit_unlink_errok(path)
! 	string_t	*path;
  {
  	trace(("commit_unlink_errok(path = %08lX)\n{\n"/*}*/, path));
  	trace_string(path->str_text);
! 	link2(what_unlink_errok, path, (string_t *)0);
  	trace((/*{*/"}\n"));
  }
  
--- 207,217 ----
  
  void
  commit_unlink_errok(path)
! 	string_ty	*path;
  {
  	trace(("commit_unlink_errok(path = %08lX)\n{\n"/*}*/, path));
  	trace_string(path->str_text);
! 	link2(what_unlink_errok, path, (string_ty *)0);
  	trace((/*{*/"}\n"));
  }
  
***************
*** 221,227 ****
   *	commit_rmdir_errok
   *
   * SYNOPSIS
!  *	void commit_rmdir_errok(string_t *path);
   *
   * DESCRIPTION
   *	The commit_rmdir_errok function is used to
--- 221,227 ----
   *	commit_rmdir_errok
   *
   * SYNOPSIS
!  *	void commit_rmdir_errok(string_ty *path);
   *
   * DESCRIPTION
   *	The commit_rmdir_errok function is used to
***************
*** 235,245 ****
  
  void
  commit_rmdir_errok(path)
! 	string_t	*path;
  {
  	trace(("commit_rmdir_errok(path = %08lX)\n{\n"/*}*/, path));
  	trace_string(path->str_text);
! 	link2(what_rmdir_errok, path, (string_t *)0);
  	trace((/*{*/"}\n"));
  }
  
--- 235,245 ----
  
  void
  commit_rmdir_errok(path)
! 	string_ty	*path;
  {
  	trace(("commit_rmdir_errok(path = %08lX)\n{\n"/*}*/, path));
  	trace_string(path->str_text);
! 	link2(what_rmdir_errok, path, (string_ty *)0);
  	trace((/*{*/"}\n"));
  }
  
***************
*** 249,255 ****
   *	commit_rmdir_tree_errok
   *
   * SYNOPSIS
!  *	void commit_rmdir_tree_errok(string_t *path);
   *
   * DESCRIPTION
   *	The commit_rmdir_tree_errok function is used to
--- 249,255 ----
   *	commit_rmdir_tree_errok
   *
   * SYNOPSIS
!  *	void commit_rmdir_tree_errok(string_ty *path);
   *
   * DESCRIPTION
   *	The commit_rmdir_tree_errok function is used to
***************
*** 263,273 ****
  
  void
  commit_rmdir_tree_errok(path)
! 	string_t	*path;
  {
  	trace(("commit_rmdir_tree_errok(path = %08lX)\n{\n"/*}*/, path));
  	trace_string(path->str_text);
! 	link2(what_rmdir_tree_errok, path, (string_t *)0);
  	trace((/*{*/"}\n"));
  }
  
--- 263,273 ----
  
  void
  commit_rmdir_tree_errok(path)
! 	string_ty	*path;
  {
  	trace(("commit_rmdir_tree_errok(path = %08lX)\n{\n"/*}*/, path));
  	trace_string(path->str_text);
! 	link2(what_rmdir_tree_errok, path, (string_ty *)0);
  	trace((/*{*/"}\n"));
  }
  
***************
*** 277,284 ****
   *	rmdir_tree_callback
   *
   * SYNOPSIS
!  *	void rmdir_tree_callback(void * arg, dir_walk_message_t message,
!  *		string_t *path, struct stat *st);
   *
   * DESCRIPTION
   *	The rmdir_tree_callback function is used to
--- 277,284 ----
   *	rmdir_tree_callback
   *
   * SYNOPSIS
!  *	void rmdir_tree_callback(void * arg, dir_walk_message_ty message,
!  *		string_ty *path, struct stat *st);
   *
   * DESCRIPTION
   *	The rmdir_tree_callback function is used to
***************
*** 300,313 ****
   *	st	- pointer to stat structure describing file system entity
   */
  
! static void rmdir_tree_callback _((void *, dir_walk_message_t, string_t *path,
! 	struct stat *));
  
  static void
  rmdir_tree_callback(arg, message, path, stat)
  	void		*arg;
! 	dir_walk_message_t message;
! 	string_t	*path;
  	struct stat	*stat;
  {
  	trace(("rmdir_tree_callback(message = %d, path = %08lX, \
--- 300,313 ----
   *	st	- pointer to stat structure describing file system entity
   */
  
! static void rmdir_tree_callback _((void *, dir_walk_message_ty,
! 	string_ty *path, struct stat *));
  
  static void
  rmdir_tree_callback(arg, message, path, stat)
  	void		*arg;
! 	dir_walk_message_ty message;
! 	string_ty	*path;
  	struct stat	*stat;
  {
  	trace(("rmdir_tree_callback(message = %d, path = %08lX, \
***************
*** 357,363 ****
  	trace(("commit()\n{\n"/*}*/));
  	while (head1 || head2)
  	{
! 		action_t	*action;
  
  		/*
  		 * Take the first item off the list.
--- 357,363 ----
  	trace(("commit()\n{\n"/*}*/));
  	while (head1 || head2)
  	{
! 		action_ty	*action;
  
  		/*
  		 * Take the first item off the list.
Index: aegis/commit.h
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 25,34 ****
  
  #include <str.h>
  
! void commit_rename _((string_t *from, string_t *to));
! void commit_unlink_errok _((string_t *path));
! void commit_rmdir_errok _((string_t *path));
! void commit_rmdir_tree_errok _((string_t *path));
  void commit _((void));
  
  #endif /* COMMIT_H */
--- 25,34 ----
  
  #include <str.h>
  
! void commit_rename _((string_ty *from, string_ty *to));
! void commit_unlink_errok _((string_ty *path));
! void commit_rmdir_errok _((string_ty *path));
! void commit_rmdir_tree_errok _((string_ty *path));
  void commit _((void));
  
  #endif /* COMMIT_H */
Index: aegis/common.def
***************
*** 1,12 ****
  /*	
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *	
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *	
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*	
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *	
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *	
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
Index: aegis/copyfile.c
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 104,109 ****
--- 104,114 ----
  "	development directory, and added to the list of files in",
  "	the change.",
  "",
+ "	This command will cancel any build or test registrations,",
+ "	because adding another file logically invalidates them.  If",
+ "	the config file was added, any diff registration will also",
+ "	be cancelled.",
+ "",
  "OPTIONS",
  "	The following options are understood:",
  "",
***************
*** 117,125 ****
  "",
  "	-Change <number>",
  "		This option may be used to specify a particular",
! "		change within a project.  If the user is only",
! "		working on one change within a project, that is",
! "		the default change number.",
  "",
  "	-Delta <number>",
  "		This optioon may be used to specify a particular",
--- 122,135 ----
  "",
  "	-Change <number>",
  "		This option may be used to specify a particular",
! "		change within a project.  When no -Change option is",
! "		specified, the AEGIS_CHANGE environment variable is",
! "		consulted.  If that does not exist, the user's",
! "		$HOME/.aegisrc file is examined for a default change",
! "		field (see aeuconf(5) for more information).  If",
! "		that does not exist, when the user is only working",
! "		on one change within a project, that is the default",
! "		change number.  Otherwise, it is an error.",
  "",
  "	-Delta <number>",
  "		This optioon may be used to specify a particular",
***************
*** 150,163 ****
  "",
  "	-Project <name>",
  "		This option may be used to select the project of",
! "		interest.  When no -Project option is specified, if",
! "		the user is only working on changes within a single",
! "		project, the project name defaults to that project;",
! "		if the user is currently working on changes to more",
! "		than one project, or is not working on changes to",
! "		any project, the user's $HOME/.%src file is",
! "		examined for a default project field (see aeuconf(5)",
! "		for more information).",
  "",
  "	-TERse",
  "		This option may be used to cause listings to",
--- 160,173 ----
  "",
  "	-Project <name>",
  "		This option may be used to select the project of",
! "		interest.  When no -Project option is specified, the",
! "		AEGIS_PROJECT environment variable is consulted.  If",
! "		that does not exist, the user's $HOME/.aegisrc file",
! "		is examined for a default project field (see",
! "		aeuconf(5) for more information).  If that does not",
! "		exist, when the user is only working on changes",
! "		within a single project, the project name defaults",
! "		to that project.  Otherwise, it is an error.",
  "",
  "	-TERse",
  "		This option may be used to cause listings to",
***************
*** 171,181 ****
  "		option this option causes column headings to be",
  "		added.",
  "",
! "	All options are case insensitive.  Options may be",
! "	abbreviated; the abbreviation is the upper case letters.",
  "	Options and other command line arguments may be mixed",
! "	arbitrarily on the command line.",
  "",
  "RECOMMENDED ALIAS",
  "	The recommended alias for this command is",
  "	csh%%	alias aecp '%s -cp \\!* -v'",
--- 181,209 ----
  "		option this option causes column headings to be",
  "		added.",
  "",
! "	All options may be abbreviated; the abbreviation is",
! "	documented as the upper case letters, all lower case",
! "	letters and underscores (_) are optional.  You must use",
! "	consecutive sequences of optional letters.",
! "",
! "	All options are case insensitive, you may type them in",
! "	upper case or lower case or a combination of both, case",
! "	is not important.",
! "",
! "	For example: the arguments \"-project, \"-PROJ\" and \"-p\"",
! "	are all interpreted to mean the -Project option.  The",
! "	argument \"-prj\" will not be understood, because",
! "	consecutive optional characters were not supplied.",
! "",
  "	Options and other command line arguments may be mixed",
! "	arbitrarily on the command line, after the function",
! "	selectors.",
  "",
+ "	The GNU long option names are understood.  Since all",
+ "	option names for aegis are long, this means ignoring the",
+ "	extra leading '-'.  The \"--option=value\" convention is",
+ "	also understood.",
+ "",
  "RECOMMENDED ALIAS",
  "	The recommended alias for this command is",
  "	csh%%	alias aecp '%s -cp \\!* -v'",
***************
*** 210,216 ****
  static void
  copy_file_list()
  {
! 	string_t	*project_name;
  	long		change_number;
  
  	trace(("copy_file_list()\n{\n"/*}*/));
--- 238,244 ----
  static void
  copy_file_list()
  {
! 	string_ty	*project_name;
  	long		change_number;
  
  	trace(("copy_file_list()\n{\n"/*}*/));
***************
*** 260,283 ****
  static void
  copy_file_main()
  {
! 	string_t	*dd;
! 	string_t	*bl;
  	wlist		wl;
! 	string_t	*s1;
! 	string_t	*s2;
  	int		stomp;
  	cstate		cstate_data;
  	pstate		pstate_data;
  	int		j;
  	pconf		pconf_data;
! 	string_t	*project_name;
! 	project_t	*pp;
  	long		change_number;
! 	change_t	*cp;
  	int		nolog;
! 	user_t		*up;
  	char		*output;
  	long		delta_number;
  
  	trace(("copy_file_main()\n{\n"/*}*/));
  	wl_zero(&wl);
--- 288,315 ----
  static void
  copy_file_main()
  {
! 	string_ty	*id;
! 	string_ty	*dd;
! 	string_ty	*bl;
  	wlist		wl;
! 	string_ty	*s1;
! 	string_ty	*s2;
  	int		stomp;
  	cstate		cstate_data;
  	pstate		pstate_data;
  	int		j;
  	pconf		pconf_data;
! 	string_ty	*project_name;
! 	project_ty	*pp;
  	long		change_number;
! 	change_ty	*cp;
  	int		nolog;
! 	user_ty		*up;
  	char		*output;
  	long		delta_number;
+ 	string_ty	*delta_number_implies_edit_number = 0;
+ 	int		config_seen;
+ 	string_ty	*config_name;
  
  	trace(("copy_file_main()\n{\n"/*}*/));
  	wl_zero(&wl);
***************
*** 311,317 ****
  		case arglex_token_string:
  			s1 = str_from_c(arglex_value.alv_string);
  			os_become_orig();
! 			s2 = os_pathname(s1);
  			os_become_undo();
  			str_free(s1);
  			if (wl_member(&wl, s2))
--- 343,349 ----
  		case arglex_token_string:
  			s1 = str_from_c(arglex_value.alv_string);
  			os_become_orig();
! 			s2 = os_pathname(s1, 1);
  			os_become_undo();
  			str_free(s1);
  			if (wl_member(&wl, s2))
***************
*** 489,496 ****
  			/*
  			 * the delta given was the current baseline,
  			 * don't bother with history
  			 */
! 			delta_number = 0;
  			break;
  		}
  	}
--- 521,532 ----
  			/*
  			 * the delta given was the current baseline,
  			 * don't bother with history
+ 			 *
+ 			 * Except when integrating,
+ 			 * in which case the integration copy may differ.
  			 */
! 			if (cstate_data->state != cstate_state_being_integrated)
! 				delta_number = 0;
  			break;
  		}
  	}
***************
*** 501,521 ****
  	 * 2. if the file is inside the development directory, ok
  	 * 3. if the file is inside the baseline, ok
  	 * 4. if neither, error
  	 */
  	for (j = 0; j < wl.wl_nwords; ++j)
  	{
  		s1 = wl.wl_word[j];
  		assert(s1->str_text[0] == '/');
! 		s2 = os_below_dir(change_development_directory_get(cp), s1);
  		if (!s2)
! 			s2 = os_below_dir(project_baseline_path_get(pp), s1);
! 		if (!s2 && cstate_data->state == cstate_state_being_integrated)
! 			s2 = os_below_dir(change_integration_directory_get(cp), s1);
  		if (!s2)
  			change_fatal(cp, "path \"%S\" unrelated", s1);
  		str_free(s1);
  		wl.wl_word[j] = s2;
  	}
  
  	/*
  	 * ensure that each file
--- 537,574 ----
  	 * 2. if the file is inside the development directory, ok
  	 * 3. if the file is inside the baseline, ok
  	 * 4. if neither, error
+ 	 *
+ 	 * To cope with automounters, directories are stored as given,
+ 	 * or are derived from the home directory in the passwd file.
+ 	 * Within aegis, pathnames have their symbolic links resolved,
+ 	 * and any comparison of paths is done on this "system idea"
+ 	 * of the pathname.
  	 */
+ 	config_seen = 0;
+ 	config_name = str_from_c("config");
+ 	dd = change_development_directory_get(cp, 1);
+ 	if (cstate_data->state == cstate_state_being_integrated)
+ 		id = change_integration_directory_get(cp, 1);
+ 	else
+ 		id = 0;
+ 	bl = project_baseline_path_get(pp, 1);
  	for (j = 0; j < wl.wl_nwords; ++j)
  	{
  		s1 = wl.wl_word[j];
  		assert(s1->str_text[0] == '/');
! 		s2 = os_below_dir(dd, s1);
  		if (!s2)
! 			s2 = os_below_dir(bl, s1);
! 		if (!s2 && id)
! 			s2 = os_below_dir(id, s1);
  		if (!s2)
  			change_fatal(cp, "path \"%S\" unrelated", s1);
  		str_free(s1);
  		wl.wl_word[j] = s2;
+ 		if (str_equal(s2, config_name))
+ 			config_seen++;
  	}
+ 	str_free(config_name);
  
  	/*
  	 * ensure that each file
***************
*** 561,581 ****
  	 * Copy each file into the development directory.
  	 * Create any necessary directories along the way.
  	 */
- 	dd = change_development_directory_get(cp);
- 	if (cstate_data->state == cstate_state_being_integrated)
- 		bl = change_integration_directory_get(cp);
- 	else
- 		bl = project_baseline_path_get(pp);
  	for (j = 0; j < wl.wl_nwords; ++j)
  	{
! 		string_t	*from;
! 		string_t	*to;
  
  		s1 = wl.wl_word[j];
  		if (delta_number)
  		{
- 			string_t *edit_number;
- 
  			/*
  			 * find the edit number,
  			 * given fie file name and delta number
--- 614,627 ----
  	 * Copy each file into the development directory.
  	 * Create any necessary directories along the way.
  	 */
  	for (j = 0; j < wl.wl_nwords; ++j)
  	{
! 		string_ty	*from;
! 		string_ty	*to;
  
  		s1 = wl.wl_word[j];
  		if (delta_number)
  		{
  			/*
  			 * find the edit number,
  			 * given fie file name and delta number
***************
*** 583,591 ****
  			 * NULL returned means that the file
  			 * does not exist at the given delta.
  			 */
! 			edit_number =
  				project_delta_to_edit(pp, delta_number, s1);
! 			if (edit_number)
  			{
  				/*
  				 * make a temporary file
--- 629,637 ----
  			 * NULL returned means that the file
  			 * does not exist at the given delta.
  			 */
! 			delta_number_implies_edit_number =
  				project_delta_to_edit(pp, delta_number, s1);
! 			if (delta_number_implies_edit_number)
  			{
  				/*
  				 * make a temporary file
***************
*** 608,614 ****
  				(
  					cp,
  					s1,
! 					edit_number,
  					from,
  					up
  				);
--- 654,660 ----
  				(
  					cp,
  					s1,
! 					delta_number_implies_edit_number,
  					from,
  					up
  				);
***************
*** 635,645 ****
  			/*
  			 * clean up afterwards
  			 */
! 			if (edit_number)
! 			{
! 				str_free(edit_number);
  				os_unlink_errok(from);
- 			}
  			user_become_undo();
  			str_free(from);
  			str_free(to);
--- 681,688 ----
  			/*
  			 * clean up afterwards
  			 */
! 			if (delta_number_implies_edit_number)
  				os_unlink_errok(from);
  			user_become_undo();
  			str_free(from);
  			str_free(to);
***************
*** 646,652 ****
  		}
  		else
  		{
! 			from = str_format("%S/%S", bl, s1);
  			if (output)
  				to = str_from_c(output);
  			else
--- 689,698 ----
  		}
  		else
  		{
! 			if (id)
! 				from = str_format("%S/%S", id, s1);
! 			else
! 				from = str_format("%S/%S", bl, s1);
  			if (output)
  				to = str_from_c(output);
  			else
***************
*** 707,713 ****
  			else
  				str_free(c_src_data->edit_number);
  			assert(p_src_data->edit_number);
! 			c_src_data->edit_number = str_copy(p_src_data->edit_number);
  		}
  
  		/*
--- 753,766 ----
  			else
  				str_free(c_src_data->edit_number);
  			assert(p_src_data->edit_number);
! 			if (delta_number_implies_edit_number)
! 				c_src_data->edit_number =
! 					delta_number_implies_edit_number;
! 			else
! 				c_src_data->edit_number =
! 					str_copy(p_src_data->edit_number);
! 			if (config_seen)
! 				c_src_data->diff_time = 0;
  		}
  
  		/*
***************
*** 828,841 ****
  "	confuse tools such as make(1) by leaving these files in",
  "	place.",
  "",
  "OPTIONS",
  "	The following options are understood:",
  "",
  "	-Change <number>",
  "		This option may be used to specify a particular",
! "		change within a project.  If the user is only",
! "		working on one change within a project, that is",
! "		the default change number.",
  "",
  "	-Help",
  "		This option may be used to obtain more",
--- 881,904 ----
  "	confuse tools such as make(1) by leaving these files in",
  "	place.",
  "",
+ "	This command will cancel any build or test registrations,",
+ "	because deleting a file logically invalidates them.  If the",
+ "	config file was deleted, any diff registration will also be",
+ "	cancelled.",
+ "",
  "OPTIONS",
  "	The following options are understood:",
  "",
  "	-Change <number>",
  "		This option may be used to specify a particular",
! "		change within a project.  When no -Change option is",
! "		specified, the AEGIS_CHANGE environment variable is",
! "		consulted.  If that does not exist, the user's",
! "		$HOME/.aegisrc file is examined for a default change",
! "		field (see aeuconf(5) for more information).  If",
! "		that does not exist, when the user is only working",
! "		on one change within a project, that is the default",
! "		change number.  Otherwise, it is an error.",
  "",
  "	-Help",
  "		This option may be used to obtain more",
***************
*** 848,861 ****
  "",
  "	-Project <name>",
  "		This option may be used to select the project of",
! "		interest.  When no -Project option is specified, if",
! "		the user is only working on changes within a single",
! "		project, the project name defaults to that project;",
! "		if the user is currently working on changes to more",
! "		than one project, or is not working on changes to",
! "		any project, the user's $HOME/.%src file is",
! "		examined for a default project field (see aeuconf(5)",
! "		for more information).",
  "",
  "	-TERse",
  "		This option may be used to cause listings to",
--- 911,924 ----
  "",
  "	-Project <name>",
  "		This option may be used to select the project of",
! "		interest.  When no -Project option is specified, the",
! "		AEGIS_PROJECT environment variable is consulted.  If",
! "		that does not exist, the user's $HOME/.aegisrc file",
! "		is examined for a default project field (see",
! "		aeuconf(5) for more information).  If that does not",
! "		exist, when the user is only working on changes",
! "		within a single project, the project name defaults",
! "		to that project.  Otherwise, it is an error.",
  "",
  "	-TERse",
  "		This option may be used to cause listings to",
***************
*** 869,879 ****
  "		option this option causes column headings to be",
  "		added.",
  "",
! "	All options are case insensitive.  Options may be",
! "	abbreviated; the abbreviation is the upper case letters.",
  "	Options and other command line arguments may be mixed",
! "	arbitrarily on the command line.",
  "",
  "RECOMMENDED ALIAS",
  "	The recommended alias for this command is",
  "	csh%%	alias aecpu '%s -cpu \\!* -v'",
--- 932,960 ----
  "		option this option causes column headings to be",
  "		added.",
  "",
! "	All options may be abbreviated; the abbreviation is",
! "	documented as the upper case letters, all lower case",
! "	letters and underscores (_) are optional.  You must use",
! "	consecutive sequences of optional letters.",
! "",
! "	All options are case insensitive, you may type them in",
! "	upper case or lower case or a combination of both, case",
! "	is not important.",
! "",
! "	For example: the arguments \"-project, \"-PROJ\" and \"-p\"",
! "	are all interpreted to mean the -Project option.  The",
! "	argument \"-prj\" will not be understood, because",
! "	consecutive optional characters were not supplied.",
! "",
  "	Options and other command line arguments may be mixed",
! "	arbitrarily on the command line, after the function",
! "	selectors.",
  "",
+ "	The GNU long option names are understood.  Since all",
+ "	option names for aegis are long, this means ignoring the",
+ "	extra leading '-'.  The \"--option=value\" convention is",
+ "	also understood.",
+ "",
  "RECOMMENDED ALIAS",
  "	The recommended alias for this command is",
  "	csh%%	alias aecpu '%s -cpu \\!* -v'",
***************
*** 906,912 ****
  static void
  copy_file_undo_list()
  {
! 	string_t	*project_name;
  	long		change_number;
  
  	trace(("copy_file_undo_list()\n{\n"/*}*/));
--- 987,993 ----
  static void
  copy_file_undo_list()
  {
! 	string_ty	*project_name;
  	long		change_number;
  
  	trace(("copy_file_undo_list()\n{\n"/*}*/));
***************
*** 960,975 ****
  	cstate		cstate_data;
  	pstate		pstate_data;
  	int		j;
! 	string_t	*s1;
! 	string_t	*s2;
  	int		keep;
  	pconf		pconf_data;
! 	string_t	*project_name;
! 	project_t	*pp;
  	long		change_number;
! 	change_t	*cp;
  	int		nolog;
! 	user_t		*up;
  
  	trace(("copy_file_undo_main()\n{\n"/*}*/));
  	wl_zero(&wl);
--- 1041,1058 ----
  	cstate		cstate_data;
  	pstate		pstate_data;
  	int		j;
! 	string_ty	*s1;
! 	string_ty	*s2;
  	int		keep;
  	pconf		pconf_data;
! 	string_ty	*project_name;
! 	project_ty	*pp;
  	long		change_number;
! 	change_ty	*cp;
  	int		nolog;
! 	user_ty		*up;
! 	int		config_seen;
! 	string_ty	*config_name;
  
  	trace(("copy_file_undo_main()\n{\n"/*}*/));
  	wl_zero(&wl);
***************
*** 988,994 ****
  		case arglex_token_string:
  			s1 = str_from_c(arglex_value.alv_string);
  			os_become_orig();
! 			s2 = os_pathname(s1);
  			os_become_undo();
  			str_free(s1);
  			if (wl_member(&wl, s2))
--- 1071,1077 ----
  		case arglex_token_string:
  			s1 = str_from_c(arglex_value.alv_string);
  			os_become_orig();
! 			s2 = os_pathname(s1, 1);
  			os_become_undo();
  			str_free(s1);
  			if (wl_member(&wl, s2))
***************
*** 1092,1109 ****
  	 * 3.	if the file is inside the baseline, ok
  	 * 4.	if neither, error
  	 */
  	for (j = 0; j < wl.wl_nwords; ++j)
  	{
  		s1 = wl.wl_word[j];
  		assert(s1->str_text[0] == '/');
! 		s2 = os_below_dir(cstate_data->development_directory, s1);
  		if (!s2)
! 			s2 = os_below_dir(project_baseline_path_get(pp), s1);
  		if (!s2)
  			change_fatal(cp, "path \"%S\" unrelated", s1);
  		str_free(s1);
  		wl.wl_word[j] = s2;
  	}
  
  	/*
  	 * ensure that each file
--- 1175,1197 ----
  	 * 3.	if the file is inside the baseline, ok
  	 * 4.	if neither, error
  	 */
+ 	config_seen = 0;
+ 	config_name = str_from_c("config");
  	for (j = 0; j < wl.wl_nwords; ++j)
  	{
  		s1 = wl.wl_word[j];
  		assert(s1->str_text[0] == '/');
! 		s2 = os_below_dir(change_development_directory_get(cp, 1), s1);
  		if (!s2)
! 			s2 = os_below_dir(project_baseline_path_get(pp, 1), s1);
  		if (!s2)
  			change_fatal(cp, "path \"%S\" unrelated", s1);
  		str_free(s1);
  		wl.wl_word[j] = s2;
+ 		if (str_equal(s2, config_name))
+ 			config_seen++;
  	}
+ 	str_free(config_name);
  
  	/*
  	 * ensure that each file
***************
*** 1120,1125 ****
--- 1208,1215 ----
  			change_fatal(cp, "file \"%S\" not in change", s1);
  		if (src_data->action != file_action_modify)
  			change_fatal(cp, "file \"%S\" is not -CoPy_file", s1);
+ 		if (config_seen)
+ 			src_data->diff_time = 0;
  	}
  
  	/*
***************
*** 1129,1137 ****
  	 */
  	if (!keep)
  	{
! 		string_t	*dd;
  
! 		dd = change_development_directory_get(cp);
  		user_become(up);
  		for (j = 0; j < wl.wl_nwords; ++j)
  		{
--- 1219,1227 ----
  	 */
  	if (!keep)
  	{
! 		string_ty	*dd;
  
! 		dd = change_development_directory_get(cp, 1);
  		user_become(up);
  		for (j = 0; j < wl.wl_nwords; ++j)
  		{
***************
*** 1146,1152 ****
  				commit_unlink_errok(s2);
  			str_free(s2);
  		}
! 		os_become_undo();
  	}
  
  	/*
--- 1236,1242 ----
  				commit_unlink_errok(s2);
  			str_free(s2);
  		}
! 		user_become_undo();
  	}
  
  	/*
Index: aegis/copyfile.h
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
Index: aegis/cstate.def
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
Index: aegis/develop1.c
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 86,99 ****
  "",
  "	-Project <name>",
  "		This option may be used to select the project of",
! "		interest.  When no -Project option is specified, if",
! "		the user is only working on changes within a single",
! "		project, the project name defaults to that project;",
! "		if the user is currently working on changes to more",
! "		than one project, or is not working on changes to",
! "		any project, the user's $HOME/.%src file is",
! "		examined for a default project field (see aeuconf(5)",
! "		for more information).",
  "",
  "	-TERse",
  "		This option may be used to cause listings to",
--- 86,99 ----
  "",
  "	-Project <name>",
  "		This option may be used to select the project of",
! "		interest.  When no -Project option is specified, the",
! "		AEGIS_PROJECT environment variable is consulted.  If",
! "		that does not exist, the user's $HOME/.aegisrc file",
! "		is examined for a default project field (see",
! "		aeuconf(5) for more information).  If that does not",
! "		exist, when the user is only working on changes",
! "		within a single project, the project name defaults",
! "		to that project.  Otherwise, it is an error.",
  "",
  "	-TERse",
  "		This option may be used to cause listings to",
***************
*** 107,117 ****
  "		option this option causes column headings to be",
  "		added.",
  "",
! "	All options are case insensitive.  Options may be",
! "	abbreviated; the abbreviation is the upper case letters.",
  "	Options and other command line arguments may be mixed",
! "	arbitrarily on the command line.",
  "",
  "RECOMMENDED ALIAS",
  "	The recommended alias for this command is",
  "	csh%%	alias aend '%s -nd \\!* -v'",
--- 107,135 ----
  "		option this option causes column headings to be",
  "		added.",
  "",
! "	All options may be abbreviated; the abbreviation is",
! "	documented as the upper case letters, all lower case",
! "	letters and underscores (_) are optional.  You must use",
! "	consecutive sequences of optional letters.",
! "",
! "	All options are case insensitive, you may type them in",
! "	upper case or lower case or a combination of both, case",
! "	is not important.",
! "",
! "	For example: the arguments \"-project, \"-PROJ\" and \"-p\"",
! "	are all interpreted to mean the -Project option.  The",
! "	argument \"-prj\" will not be understood, because",
! "	consecutive optional characters were not supplied.",
! "",
  "	Options and other command line arguments may be mixed",
! "	arbitrarily on the command line, after the function",
! "	selectors.",
  "",
+ "	The GNU long option names are understood.  Since all",
+ "	option names for aegis are long, this means ignoring the",
+ "	extra leading '-'.  The \"--option=value\" convention is",
+ "	also understood.",
+ "",
  "RECOMMENDED ALIAS",
  "	The recommended alias for this command is",
  "	csh%%	alias aend '%s -nd \\!* -v'",
***************
*** 143,149 ****
  developer_list(usage)
  	void		(*usage)_((void));
  {
! 	string_t	*project_name;
  
  	trace(("developer_list()\n{\n"/*}*/));
  	arglex();
--- 161,167 ----
  developer_list(usage)
  	void		(*usage)_((void));
  {
! 	string_ty	*project_name;
  
  	trace(("developer_list()\n{\n"/*}*/));
  	arglex();
***************
*** 177,188 ****
  new_developer_main()
  {
  	wlist		wl;
! 	string_t	*s1;
  	pstate		pstate_data;
  	int		j;
! 	string_t	*project_name;
! 	project_t	*pp;
! 	user_t		*up;
  
  	trace(("new_developer_main()\n{\n"/*}*/));
  	wl_zero(&wl);
--- 195,206 ----
  new_developer_main()
  {
  	wlist		wl;
! 	string_ty	*s1;
  	pstate		pstate_data;
  	int		j;
! 	string_ty	*project_name;
! 	project_ty	*pp;
! 	user_ty		*up;
  
  	trace(("new_developer_main()\n{\n"/*}*/));
  	wl_zero(&wl);
***************
*** 255,261 ****
  	 */
  	for (j = 0; j < wl.wl_nwords; ++j)
  	{
! 		user_t		*candidate;
  
  		/*
  		 * make sure the user isn't already there
--- 273,279 ----
  	 */
  	for (j = 0; j < wl.wl_nwords; ++j)
  	{
! 		user_ty		*candidate;
  
  		/*
  		 * make sure the user isn't already there
***************
*** 388,401 ****
  "",
  "	-Project <name>",
  "		This option may be used to select the project of",
! "		interest.  When no -Project option is specified, if",
! "		the user is only working on changes within a single",
! "		project, the project name defaults to that project;",
! "		if the user is currently working on changes to more",
! "		than one project, or is not working on changes to",
! "		any project, the user's $HOME/.%src file is",
! "		examined for a default project field (see aeuconf(5)",
! "		for more information).",
  "",
  "	-TERse",
  "		This option may be used to cause listings to",
--- 406,419 ----
  "",
  "	-Project <name>",
  "		This option may be used to select the project of",
! "		interest.  When no -Project option is specified, the",
! "		AEGIS_PROJECT environment variable is consulted.  If",
! "		that does not exist, the user's $HOME/.aegisrc file",
! "		is examined for a default project field (see",
! "		aeuconf(5) for more information).  If that does not",
! "		exist, when the user is only working on changes",
! "		within a single project, the project name defaults",
! "		to that project.  Otherwise, it is an error.",
  "",
  "	-TERse",
  "		This option may be used to cause listings to",
***************
*** 409,419 ****
  "		option this option causes column headings to be",
  "		added.",
  "",
! "	All options are case insensitive.  Options may be",
! "	abbreviated; the abbreviation is the upper case letters.",
  "	Options and other command line arguments may be mixed",
! "	arbitrarily on the command line.",
  "",
  "RECOMMENDED ALIAS",
  "	The recommended alias for this command is",
  "	csh%%	alias aerd '%s -rd \\!* -v'",
--- 427,455 ----
  "		option this option causes column headings to be",
  "		added.",
  "",
! "	All options may be abbreviated; the abbreviation is",
! "	documented as the upper case letters, all lower case",
! "	letters and underscores (_) are optional.  You must use",
! "	consecutive sequences of optional letters.",
! "",
! "	All options are case insensitive, you may type them in",
! "	upper case or lower case or a combination of both, case",
! "	is not important.",
! "",
! "	For example: the arguments \"-project, \"-PROJ\" and \"-p\"",
! "	are all interpreted to mean the -Project option.  The",
! "	argument \"-prj\" will not be understood, because",
! "	consecutive optional characters were not supplied.",
! "",
  "	Options and other command line arguments may be mixed",
! "	arbitrarily on the command line, after the function",
! "	selectors.",
  "",
+ "	The GNU long option names are understood.  Since all",
+ "	option names for aegis are long, this means ignoring the",
+ "	extra leading '-'.  The \"--option=value\" convention is",
+ "	also understood.",
+ "",
  "RECOMMENDED ALIAS",
  "	The recommended alias for this command is",
  "	csh%%	alias aerd '%s -rd \\!* -v'",
***************
*** 445,456 ****
  remove_developer_main()
  {
  	wlist		wl;
! 	string_t	*s1;
  	pstate		pstate_data;
  	int		j;
! 	string_t	*project_name;
! 	project_t	*pp;
! 	user_t		*up;
  
  	trace(("remove_developer_main()\n{\n"/*}*/));
  	wl_zero(&wl);
--- 481,492 ----
  remove_developer_main()
  {
  	wlist		wl;
! 	string_ty	*s1;
  	pstate		pstate_data;
  	int		j;
! 	string_ty	*project_name;
! 	project_ty	*pp;
! 	user_ty		*up;
  
  	trace(("remove_developer_main()\n{\n"/*}*/));
  	wl_zero(&wl);
***************
*** 523,529 ****
  	 */
  	for (j = 0; j < wl.wl_nwords; ++j)
  	{
! 		user_t	*candidate;
  
  		candidate = user_symbolic(pp, wl.wl_word[j]);
  		if (!project_developer_query(pp, user_name(candidate)))
--- 559,565 ----
  	 */
  	for (j = 0; j < wl.wl_nwords; ++j)
  	{
! 		user_ty	*candidate;
  
  		candidate = user_symbolic(pp, wl.wl_word[j]);
  		if (!project_developer_query(pp, user_name(candidate)))
Index: aegis/develop1.h
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
Index: aegis/develop2.c
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 83,98 ****
  "",
  "	The development directory for the change will be created",
  "	automatically; below the directory specified in the",
! "	default_development_directory of aeuconf(5), or if not set",
! "	below the directory specified in the",
! "	default_development_directory of aepattr(5), or if not set",
! "	below the current user's home directory.  It is rare to need",
! "	to know the exact pathname of the development directory, as",
! "	the aecd(1) command can take you there at any time.",
  "",
  "	Successful execution of this command will move the",
! "	specified change from the 'awaiting_development' state to",
! "	the 'being_developed' state.",
  "",
  "OPTIONS",
  "	The following options are understood:",
--- 83,99 ----
  "",
  "	The development directory for the change will be created",
  "	automatically; below the directory specified in the",
! "	default_development_directory field of aeuconf(5), or if",
! "	not set below the directory specified in the default_-",
! "	development_directory field of aepattr(5), or if not set",
! "	below the current user's home directory.  It is rare to",
! "	need to know the exact pathname of the development",
! "	directory, as the aecd(1) command can take you there at",
! "	any time.",
  "",
  "	Successful execution of this command will move the",
! "	specified change from the awaiting development state to",
! "	the being developed state.",
  "",
  "OPTIONS",
  "	The following options are understood:",
***************
*** 99,117 ****
  "",
  "	-Change <number>",
  "		This option may be used to specify a particular",
! "		change within a project.  If the user is only",
! "		working on one change within a project, that is",
! "		the default change number.",
  "",
  "	-DIRectory <path>",
! "		This option may be used to specify which",
! "		directory is to be used.  It is an error if the",
! "		current user does not have appropriate",
! "		permissions to create the directory path given.",
  "",
  "	-Help",
! "		This option may be used to obtain more",
! "		information about how to use the %s program.",
  "",
  "	-List",
  "		This option may be used to obtain a list of",
--- 100,129 ----
  "",
  "	-Change <number>",
  "		This option may be used to specify a particular",
! "		change within a project.  When no -Change option",
! "		is specified, the AEGIS_CHANGE environment",
! "		variable is consulted.  If that does not exist,",
! "		the user's $HOME/.%src file is examined for a",
! "		default change field (see aeuconf(5) for more",
! "		information).  If that does not exist, when the",
! "		user is only working on one change within a",
! "		project, that is the default change number.",
! "		Otherwise, it is an error.",
  "",
  "	-DIRectory <path>",
! "		This option may be used to specify which directory",
! "		is to be used.  It is an error if the current user",
! "		does not have appropriate permissions to create",
! "		the directory path given.  This must be an",
! "		absolute path.",
  "",
+ "		Caution: If you are using an automounter do not",
+ "		use `pwd` to make an absolute path, it usually",
+ "		gives the wrong answer.",
+ "",
  "	-Help",
! "		This option may be used to obtain more information",
! "		about how to use the %s program.",
  "",
  "	-List",
  "		This option may be used to obtain a list of",
***************
*** 120,133 ****
  "",
  "	-Project <name>",
  "		This option may be used to select the project of",
! "		interest.  When no -Project option is specified, if",
! "		the user is only working on changes within a single",
! "		project, the project name defaults to that project;",
! "		if the user is currently working on changes to more",
! "		than one project, or is not working on changes to",
! "		any project, the user's $HOME/.%src file is",
! "		examined for a default project field (see aeuconf(5)",
! "		for more information).",
  "",
  "	-TERse",
  "		This option may be used to cause listings to",
--- 132,146 ----
  "",
  "	-Project <name>",
  "		This option may be used to select the project of",
! "		interest.  When no -Project option is specified,",
! "		the AEGIS_PROJECT environment variable is",
! "		consulted.  If that does not exist, the user's",
! "		$HOME/.%src file is examined for a default",
! "		project field (see aeuconf(5) for more",
! "		information).  If that does not exist, when the",
! "		user is only working on changes within a single",
! "		project, the project name defaults to that",
! "		project.  Otherwise, it is an error.",
  "",
  "	-TERse",
  "		This option may be used to cause listings to",
***************
*** 137,151 ****
  "	-Verbose",
  "		This option may be used to cause %s to produce",
  "		more output.  By default %s only produces",
! "		output on errors.  When used with the -List",
! "		option this option causes column headings to be",
! "		added.",
  "",
! "	All options are case insensitive.  Options may be",
! "	abbreviated; the abbreviation is the upper case letters.",
  "	Options and other command line arguments may be mixed",
! "	arbitrarily on the command line.",
  "",
  "RECOMMENDED ALIAS",
  "	The recommended alias for this command is",
  "	csh%%	alias aedb '%s -db \\!* -v'",
--- 150,181 ----
  "	-Verbose",
  "		This option may be used to cause %s to produce",
  "		more output.  By default %s only produces",
! "		output on errors.  When used with the -List option",
! "		this option causes column headings to be added.",
  "",
! "	All options may be abbreviated; the abbreviation is",
! "	documented as the upper case letters, all lower case",
! "	letters and underscores (_) are optional.  You must use",
! "	consecutive sequences of optional letters.",
! "",
! "	All options are case insensitive, you may type them in",
! "	upper case or lower case or a combination of both, case",
! "	is not important.",
! "",
! "	For example: the arguments \"-project, \"-PROJ\" and \"-p\"",
! "	are all interpreted to mean the -Project option.  The",
! "	argument \"-prj\" will not be understood, because",
! "	consecutive optional characters were not supplied.",
! "",
  "	Options and other command line arguments may be mixed",
! "	arbitrarily on the command line, after the function",
! "	selectors.",
  "",
+ "	The GNU long option names are understood.  Since all",
+ "	option names for aegis are long, this means ignoring the",
+ "	extra leading '-'.  The \"--option=value\" convention is",
+ "	also understood.",
+ "",
  "RECOMMENDED ALIAS",
  "	The recommended alias for this command is",
  "	csh%%	alias aedb '%s -db \\!* -v'",
***************
*** 153,166 ****
  "",
  "ERRORS",
  "	It is an error if the change does not exist.",
! "	It is an error if the change is not in the",
! "	'awaiting_development' state.",
  "	It is an error if the current user is not a developer of",
  "	the specified project.",
  "",
  "EXIT STATUS",
  "	The %s command will exit with a status of 1 on any",
! "	error.	The %s command will only exit with a status of",
  "	0 if there are no errors.",
  "",
  "COPYRIGHT",
--- 183,196 ----
  "",
  "ERRORS",
  "	It is an error if the change does not exist.",
! "	It is an error if the change is not in the awaiting",
! "	development state.",
  "	It is an error if the current user is not a developer of",
  "	the specified project.",
  "",
  "EXIT STATUS",
  "	The %s command will exit with a status of 1 on any",
! "	error.  The %s command will only exit with a status of",
  "	0 if there are no errors.",
  "",
  "COPYRIGHT",
***************
*** 179,185 ****
  static void
  develop_begin_list()
  {
! 	string_t	*project_name;
  
  	trace(("develop_begin_list()\n{\n"/*}*/));
  	project_name = 0;
--- 209,215 ----
  static void
  develop_begin_list()
  {
! 	string_ty	*project_name;
  
  	trace(("develop_begin_list()\n{\n"/*}*/));
  	project_name = 0;
***************
*** 224,236 ****
  	cstate		cstate_data;
  	pstate		pstate_data;
  	cstate_history	history_data;
! 	string_t	*devdir;
! 	string_t	*s2;
! 	string_t	*project_name;
! 	project_t	*pp;
  	long		change_number;
! 	change_t	*cp;
! 	user_t		*up;
  
  	trace(("develop_begin_main()\n{\n"/*}*/));
  	project_name = 0;
--- 254,266 ----
  	cstate		cstate_data;
  	pstate		pstate_data;
  	cstate_history	history_data;
! 	string_ty	*devdir;
! 	string_ty	*s2;
! 	string_ty	*project_name;
! 	project_ty	*pp;
  	long		change_number;
! 	change_ty	*cp;
! 	user_ty		*up;
  
  	trace(("develop_begin_main()\n{\n"/*}*/));
  	project_name = 0;
***************
*** 262,272 ****
  				develop_begin_usage();
  			if (devdir)
  				fatal("duplicate -DIRectory option");
! 			s2 = str_from_c(arglex_value.alv_string);
! 			os_become_orig();
! 			devdir = os_pathname(s2);
! 			os_become_undo();
! 			str_free(s2);
  			break;
  
  		case arglex_token_project:
--- 292,305 ----
  				develop_begin_usage();
  			if (devdir)
  				fatal("duplicate -DIRectory option");
! 			/*
! 			 * To cope with automounters, directories are stored as
! 			 * given, or are derived from the home directory in the
! 			 * passwd file.  Within aegis, pathnames have their
! 			 * symbolic links resolved, and any comparison of paths
! 			 * is done on this "system idea" of the pathname.
! 			 */
! 			devdir = str_from_c(arglex_value.alv_string);
  			break;
  
  		case arglex_token_project:
***************
*** 371,377 ****
  			);
  		str_free(s2);
  	}
- 	assert(!cstate_data->development_directory);
  	change_development_directory_set(cp, devdir);
  
  	/*
--- 404,409 ----
***************
*** 380,386 ****
  	user_become(up);
  	os_mkdir(devdir, 02755);
  	undo_rmdir_errok(devdir);
! 	os_become_undo();
  	change_verbose(cp, "development directory \"%S\"", devdir);
  
  	/*
--- 412,418 ----
  	user_become(up);
  	os_mkdir(devdir, 02755);
  	undo_rmdir_errok(devdir);
! 	user_become_undo();
  	change_verbose(cp, "development directory \"%S\"", devdir);
  
  	/*
***************
*** 477,485 ****
  "",
  "	-Change <number>",
  "		This option may be used to specify a particular",
! "		change within a project.  If the user is only",
! "		working on one change within a project, that is",
! "		the default change number.",
  "",
  "	-Help",
  "		This option may be used to obtain more",
--- 509,522 ----
  "",
  "	-Change <number>",
  "		This option may be used to specify a particular",
! "		change within a project.  When no -Change option is",
! "		specified, the AEGIS_CHANGE environment variable is",
! "		consulted.  If that does not exist, the user's",
! "		$HOME/.aegisrc file is examined for a default change",
! "		field (see aeuconf(5) for more information).  If",
! "		that does not exist, when the user is only working",
! "		on one change within a project, that is the default",
! "		change number.  Otherwise, it is an error.",
  "",
  "	-Help",
  "		This option may be used to obtain more",
***************
*** 496,509 ****
  "",
  "	-Project <name>",
  "		This option may be used to select the project of",
! "		interest.  When no -Project option is specified, if",
! "		the user is only working on changes within a single",
! "		project, the project name defaults to that project;",
! "		if the user is currently working on changes to more",
! "		than one project, or is not working on changes to",
! "		any project, the user's $HOME/.%src file is",
! "		examined for a default project field (see aeuconf(5)",
! "		for more information).",
  "",
  "	-TERse",
  "		This option may be used to cause listings to",
--- 533,546 ----
  "",
  "	-Project <name>",
  "		This option may be used to select the project of",
! "		interest.  When no -Project option is specified, the",
! "		AEGIS_PROJECT environment variable is consulted.  If",
! "		that does not exist, the user's $HOME/.aegisrc file",
! "		is examined for a default project field (see",
! "		aeuconf(5) for more information).  If that does not",
! "		exist, when the user is only working on changes",
! "		within a single project, the project name defaults",
! "		to that project.  Otherwise, it is an error.",
  "",
  "	-TERse",
  "		This option may be used to cause listings to",
***************
*** 517,527 ****
  "		option this option causes column headings to be",
  "		added.",
  "",
! "	All options are case insensitive.  Options may be",
! "	abbreviated; the abbreviation is the upper case letters.",
  "	Options and other command line arguments may be mixed",
! "	arbitrarily on the command line.",
  "",
  "RECOMMENDED ALIAS",
  "	The recommended alias for this command is",
  "	csh%%	alias aedbu '%s -dbu \\!* -v'",
--- 554,582 ----
  "		option this option causes column headings to be",
  "		added.",
  "",
! "	All options may be abbreviated; the abbreviation is",
! "	documented as the upper case letters, all lower case",
! "	letters and underscores (_) are optional.  You must use",
! "	consecutive sequences of optional letters.",
! "",
! "	All options are case insensitive, you may type them in",
! "	upper case or lower case or a combination of both, case",
! "	is not important.",
! "",
! "	For example: the arguments \"-project, \"-PROJ\" and \"-p\"",
! "	are all interpreted to mean the -Project option.  The",
! "	argument \"-prj\" will not be understood, because",
! "	consecutive optional characters were not supplied.",
! "",
  "	Options and other command line arguments may be mixed",
! "	arbitrarily on the command line, after the function",
! "	selectors.",
  "",
+ "	The GNU long option names are understood.  Since all",
+ "	option names for aegis are long, this means ignoring the",
+ "	extra leading '-'.  The \"--option=value\" convention is",
+ "	also understood.",
+ "",
  "RECOMMENDED ALIAS",
  "	The recommended alias for this command is",
  "	csh%%	alias aedbu '%s -dbu \\!* -v'",
***************
*** 554,560 ****
  static void
  develop_begin_undo_list()
  {
! 	string_t	*project_name;
  
  	trace(("develop_begin_undo_list()\n{\n"/*}*/));
  	project_name = 0;
--- 609,615 ----
  static void
  develop_begin_undo_list()
  {
! 	string_ty	*project_name;
  
  	trace(("develop_begin_undo_list()\n{\n"/*}*/));
  	project_name = 0;
***************
*** 596,603 ****
  static void
  develop_begin_undo_main()
  {
  	trace(("develop_begin_undo_main()\n{\n"/*}*/));
! 	fatal("develop_begin_undo not implememted");
  	trace((/*{*/"}\n"));
  }
  
--- 651,830 ----
  static void
  develop_begin_undo_main()
  {
+ 	string_ty	*project_name;
+ 	long		change_number;
+ 	int		keep;
+ 	project_ty	*pp;
+ 	user_ty		*up;
+ 	change_ty	*cp;
+ 	pstate		pstate_data;
+ 	cstate		cstate_data;
+ 	cstate_history	history_data;
+ 
  	trace(("develop_begin_undo_main()\n{\n"/*}*/));
! 	project_name = 0;
! 	change_number = 0;
! 	keep = 0;
! 	while (arglex_token != arglex_token_eoln)
! 	{
! 		switch (arglex_token)
! 		{
! 		default:
! 			generic_argument(develop_begin_undo_usage);
! 			continue;
! 
! 		case arglex_token_keep:
! 			if (keep)
! 			{
! 				fatal
! 				(
! 					"duplicate %s option",
! 					arglex_value.alv_string
! 				);
! 			}
! 			keep++;
! 			break;
! 
! 		case arglex_token_change:
! 			if (arglex() != arglex_token_number)
! 				develop_begin_undo_usage();
! 			/* fall through... */
! 
! 		case arglex_token_number:
! 			if (change_number)
! 				fatal("duplicate -Change option");
! 			change_number = arglex_value.alv_number;
! 			if (change_number < 1)
! 				fatal("change %ld out of range", change_number);
! 			break;
! 
! 		case arglex_token_project:
! 			if (arglex() != arglex_token_string)
! 				develop_begin_undo_usage();
! 			/* fall through... */
! 		
! 		case arglex_token_string:
! 			if (project_name)
! 				fatal("duplicate -Project option");
! 			project_name = str_from_c(arglex_value.alv_string);
! 			break;
! 		}
! 		arglex();
! 	}
! 
! 	/*
! 	 * locate project data
! 	 */
! 	if (!project_name)
! 		project_name = user_default_project();
! 	pp = project_alloc(project_name);
! 	str_free(project_name);
! 	project_bind_existing(pp);
! 
! 	/*
! 	 * locate user data
! 	 */
! 	up = user_executing(pp);
! 
! 	/*
! 	 * locate change data
! 	 */
! 	if (!change_number)
! 		change_number = user_default_change(up);
! 	cp = change_alloc(pp, change_number);
! 	change_bind_existing(cp);
! 
! 	/*
! 	 * Take an advisory write lock on the appropriate row of the change
! 	 * table.  Take an advisory write lock on the appropriate row of the
! 	 * user table.  Block until can get both simultaneously.
! 	 */
! 	project_pstate_lock_prepare(pp);
! 	change_cstate_lock_prepare(cp);
! 	user_ustate_lock_prepare(up);
! 	lock_take();
! 	cstate_data = change_cstate_get(cp);
! 	pstate_data = project_pstate_get(pp);
! 
! 	/*
! 	 * It is an error if the change is not in the being developed state.
! 	 * It is an error if the change is not assigned to the current user.
! 	 */
! 	if (cstate_data->state != cstate_state_being_developed)
! 		change_fatal(cp, "not in 'being_developed' state");
! 	if (!str_equal(change_developer_name(cp), user_name(up)))
! 	{
! 		change_fatal
! 		(
! 			cp,
! 			"user \"%S\" is not the developer",
! 			user_name(up)
! 		);
! 	}
! 
! 	/*
! 	 * add to history for state change
! 	 */
! 	history_data = change_history_new(cp, up);
! 	history_data->what = cstate_history_what_develop_begin_undo;
! 
! 	/*
! 	 * Send the change to the awaiting-development state.
! 	 * Clear the build-time field.
! 	 * Clear the test-time field.
! 	 * Clear the test-baseline-time field.
! 	 * Clear the src field.
! 	 */
! 	cstate_data->state = cstate_state_awaiting_development;
! 	cstate_data->build_time = 0;
! 	cstate_data->test_time = 0;
! 	cstate_data->test_baseline_time = 0;
! 	while (cstate_data->src->length)
! 		change_src_remove(cp, cstate_data->src->list[0]->file_name);
! 
! 	/*
! 	 * Remove the change from the list of assigned changes in the user
! 	 * change table (in the user row).
! 	 */
! 	user_own_remove(up, project_name_get(pp), change_number);
! 
! 	/*
! 	 * remove the development directory
! 	 */
! 	if (!keep)
! 	{
! 		string_ty	*dd;
! 
! 		change_verbose(cp, "remove development directory");
! 		dd = change_development_directory_get(cp, 1);
! 		change_become(cp);
! 		commit_rmdir_tree_errok(dd);
! 		change_become_undo();
! 	}
! 
! 	/*
! 	 * clear development directory field
! 	 */
! 	change_development_directory_clear(cp);
! 
! 	/*
! 	 * Write the change table row.
! 	 * Write the user table row.
! 	 * Release advisory locks.
! 	 */
! 	change_cstate_write(cp);
! 	project_pstate_write(pp);
! 	user_ustate_write(up);
! 	commit();
! 	lock_release();
! 
! 	/*
! 	 * verbose success message
! 	 */
! 	change_verbose(cp, "no longer being developed");
! 	change_free(cp);
! 	project_free(pp);
! 	user_free(up);
  	trace((/*{*/"}\n"));
  }
  
***************
*** 676,684 ****
  "",
  "	-Change <number>",
  "		This option may be used to specify a particular",
! "		change within a project.  If the user is only",
! "		working on one change within a project, that is",
! "		the default change number.",
  "",
  "	-Help",
  "		This option may be used to obtain more",
--- 903,916 ----
  "",
  "	-Change <number>",
  "		This option may be used to specify a particular",
! "		change within a project.  When no -Change option is",
! "		specified, the AEGIS_CHANGE environment variable is",
! "		consulted.  If that does not exist, the user's",
! "		$HOME/.aegisrc file is examined for a default change",
! "		field (see aeuconf(5) for more information).  If",
! "		that does not exist, when the user is only working",
! "		on one change within a project, that is the default",
! "		change number.  Otherwise, it is an error.",
  "",
  "	-Help",
  "		This option may be used to obtain more",
***************
*** 691,704 ****
  "",
  "	-Project <name>",
  "		This option may be used to select the project of",
! "		interest.  When no -Project option is specified, if",
! "		the user is only working on changes within a single",
! "		project, the project name defaults to that project;",
! "		if the user is currently working on changes to more",
! "		than one project, or is not working on changes to",
! "		any project, the user's $HOME/.%src file is",
! "		examined for a default project field (see aeuconf(5)",
! "		for more information).",
  "",
  "	-TERse",
  "		This option may be used to cause listings to",
--- 923,936 ----
  "",
  "	-Project <name>",
  "		This option may be used to select the project of",
! "		interest.  When no -Project option is specified, the",
! "		AEGIS_PROJECT environment variable is consulted.  If",
! "		that does not exist, the user's $HOME/.aegisrc file",
! "		is examined for a default project field (see",
! "		aeuconf(5) for more information).  If that does not",
! "		exist, when the user is only working on changes",
! "		within a single project, the project name defaults",
! "		to that project.  Otherwise, it is an error.",
  "",
  "	-TERse",
  "		This option may be used to cause listings to",
***************
*** 712,722 ****
  "		option this option causes column headings to be",
  "		added.",
  "",
! "	All options are case insensitive.  Options may be",
! "	abbreviated; the abbreviation is the upper case letters.",
  "	Options and other command line arguments may be mixed",
! "	arbitrarily on the command line.",
  "",
  "RECOMMENDED ALIAS",
  "	The recommended alias for this command is",
  "	csh%%	alias aede '%s -de \\!* -v'",
--- 944,972 ----
  "		option this option causes column headings to be",
  "		added.",
  "",
! "	All options may be abbreviated; the abbreviation is",
! "	documented as the upper case letters, all lower case",
! "	letters and underscores (_) are optional.  You must use",
! "	consecutive sequences of optional letters.",
! "",
! "	All options are case insensitive, you may type them in",
! "	upper case or lower case or a combination of both, case",
! "	is not important.",
! "",
! "	For example: the arguments \"-project, \"-PROJ\" and \"-p\"",
! "	are all interpreted to mean the -Project option.  The",
! "	argument \"-prj\" will not be understood, because",
! "	consecutive optional characters were not supplied.",
! "",
  "	Options and other command line arguments may be mixed",
! "	arbitrarily on the command line, after the function",
! "	selectors.",
  "",
+ "	The GNU long option names are understood.  Since all",
+ "	option names for aegis are long, this means ignoring the",
+ "	extra leading '-'.  The \"--option=value\" convention is",
+ "	also understood.",
+ "",
  "RECOMMENDED ALIAS",
  "	The recommended alias for this command is",
  "	csh%%	alias aede '%s -de \\!* -v'",
***************
*** 758,764 ****
  static void
  develop_end_list()
  {
! 	string_t	*project_name;
  
  	trace(("develop_end_list()\n{\n"/*}*/));
  	project_name = 0;
--- 1008,1014 ----
  static void
  develop_end_list()
  {
! 	string_ty	*project_name;
  
  	trace(("develop_end_list()\n{\n"/*}*/));
  	project_name = 0;
***************
*** 795,812 ****
  }
  
  
! static void repair_diff_time _((change_t *, string_t *));
  
  static void
  repair_diff_time(cp, path)
! 	change_t	*cp;
! 	string_t	*path;
  {
! 	string_t	*s;
  	cstate_src	src_data;
! 	string_t	*s2;
  
! 	s = os_below_dir(change_development_directory_get(cp), path);
  	src_data = change_src_find(cp, s);
  	if (src_data)
  		src_data->diff_time = os_mtime(path);
--- 1045,1062 ----
  }
  
  
! static void repair_diff_time _((change_ty *, string_ty *));
  
  static void
  repair_diff_time(cp, path)
! 	change_ty	*cp;
! 	string_ty	*path;
  {
! 	string_ty	*s;
  	cstate_src	src_data;
! 	string_ty	*s2;
  
! 	s = os_below_dir(change_development_directory_get(cp, 1), path);
  	src_data = change_src_find(cp, s);
  	if (src_data)
  		src_data->diff_time = os_mtime(path);
***************
*** 830,850 ****
  }
  
  
! static void de_func _((void *, dir_walk_message_t, string_t *, struct stat *));
  
  static void
  de_func(arg, message, path, st)
  	void		*arg;
! 	dir_walk_message_t message;
! 	string_t	*path;
  	struct stat	*st;
  {
! 	change_t	*cp;
  	int		uid;
  
  	trace(("de_func(message = %d, path = \"%s\", st = %08lX)\n{\n"/*}*/,
  		message, path->str_text, st));
! 	cp = (change_t *)arg;
  	switch (message)
  	{
  	case dir_walk_file:
--- 1080,1100 ----
  }
  
  
! static void de_func _((void *, dir_walk_message_ty, string_ty *, struct stat *));
  
  static void
  de_func(arg, message, path, st)
  	void		*arg;
! 	dir_walk_message_ty message;
! 	string_ty	*path;
  	struct stat	*st;
  {
! 	change_ty	*cp;
  	int		uid;
  
  	trace(("de_func(message = %d, path = \"%s\", st = %08lX)\n{\n"/*}*/,
  		message, path->str_text, st));
! 	cp = (change_ty *)arg;
  	switch (message)
  	{
  	case dir_walk_file:
***************
*** 872,887 ****
  static void
  develop_end_main()
  {
! 	string_t	*dd;
  	cstate		cstate_data;
  	pstate		pstate_data;
  	int		j;
  	cstate_history	history_data;
! 	string_t	*project_name;
! 	project_t	*pp;
  	long		change_number;
! 	change_t	*cp;
! 	user_t		*up;
  	int		build_whine;
  	int		test_whine;
  	int		test_bl_whine;
--- 1122,1137 ----
  static void
  develop_end_main()
  {
! 	string_ty	*dd;
  	cstate		cstate_data;
  	pstate		pstate_data;
  	int		j;
  	cstate_history	history_data;
! 	string_ty	*project_name;
! 	project_ty	*pp;
  	long		change_number;
! 	change_ty	*cp;
! 	user_ty		*up;
  	int		build_whine;
  	int		test_whine;
  	int		test_bl_whine;
***************
*** 994,1007 ****
  	 * It is an error if any files in the change file table have been
  	 * modified since the last diff.
  	 */
! 	dd = change_development_directory_get(cp);
  	user_become(up);
  	for (j = 0; j < cstate_data->src->length; ++j)
  	{
  		cstate_src	c_src_data;
  		pstate_src	p_src_data;
! 		string_t	*path;
! 		string_t	*path_d;
  		long		when;
  		long		when_d;
  
--- 1244,1257 ----
  	 * It is an error if any files in the change file table have been
  	 * modified since the last diff.
  	 */
! 	dd = change_development_directory_get(cp, 1);
  	user_become(up);
  	for (j = 0; j < cstate_data->src->length; ++j)
  	{
  		cstate_src	c_src_data;
  		pstate_src	p_src_data;
! 		string_ty	*path;
! 		string_ty	*path_d;
  		long		when;
  		long		when_d;
  
***************
*** 1184,1190 ****
  	 * to be read-only, and record the new ctime.
  	 */
  	dir_walk(dd, de_func, cp);
! 	os_become_undo();
  
  	/*
  	 * add to history for state change
--- 1434,1440 ----
  	 * to be read-only, and record the new ctime.
  	 */
  	dir_walk(dd, de_func, cp);
! 	user_become_undo();
  
  	/*
  	 * add to history for state change
***************
*** 1304,1312 ****
  "",
  "	-Change <number>",
  "		This option may be used to specify a particular",
! "		change within a project.  If the user is only",
! "		working on one change within a project, that is",
! "		the default change number.",
  "",
  "	-Help",
  "		This option may be used to obtain more",
--- 1554,1567 ----
  "",
  "	-Change <number>",
  "		This option may be used to specify a particular",
! "		change within a project.  When no -Change option is",
! "		specified, the AEGIS_CHANGE environment variable is",
! "		consulted.  If that does not exist, the user's",
! "		$HOME/.aegisrc file is examined for a default change",
! "		field (see aeuconf(5) for more information).  If",
! "		that does not exist, when the user is only working",
! "		on one change within a project, that is the default",
! "		change number.  Otherwise, it is an error.",
  "",
  "	-Help",
  "		This option may be used to obtain more",
***************
*** 1319,1332 ****
  "",
  "	-Project <name>",
  "		This option may be used to select the project of",
! "		interest.  When no -Project option is specified, if",
! "		the user is only working on changes within a single",
! "		project, the project name defaults to that project;",
! "		if the user is currently working on changes to more",
! "		than one project, or is not working on changes to",
! "		any project, the user's $HOME/.%src file is",
! "		examined for a default project field (see aeuconf(5)",
! "		for more information).",
  "",
  "	-TERse",
  "		This option may be used to cause listings to",
--- 1574,1587 ----
  "",
  "	-Project <name>",
  "		This option may be used to select the project of",
! "		interest.  When no -Project option is specified, the",
! "		AEGIS_PROJECT environment variable is consulted.  If",
! "		that does not exist, the user's $HOME/.aegisrc file",
! "		is examined for a default project field (see",
! "		aeuconf(5) for more information).  If that does not",
! "		exist, when the user is only working on changes",
! "		within a single project, the project name defaults",
! "		to that project.  Otherwise, it is an error.",
  "",
  "	-TERse",
  "		This option may be used to cause listings to",
***************
*** 1377,1383 ****
  static void
  develop_end_undo_list()
  {
! 	string_t	*project_name;
  
  	trace(("develop_end_undo_list()\n{\n"/*}*/));
  	project_name = 0;
--- 1632,1638 ----
  static void
  develop_end_undo_list()
  {
! 	string_ty	*project_name;
  
  	trace(("develop_end_undo_list()\n{\n"/*}*/));
  	project_name = 0;
***************
*** 1416,1436 ****
  }
  
  
! static void deu_func _((void *, dir_walk_message_t, string_t *, struct stat *));
  
  static void
  deu_func(arg, message, path, st)
  	void		*arg;
! 	dir_walk_message_t message;
! 	string_t	*path;
  	struct stat	*st;
  {
! 	change_t	*cp;
  	int		uid;
  
  	trace(("deu_func(message = %d, path = \"%s\", st = %08lX)\n{\n"/*}*/,
  		message, path->str_text, st));
! 	cp = (change_t *)arg;
  	switch (message)
  	{
  	case dir_walk_dir_before:
--- 1671,1691 ----
  }
  
  
! static void deu_func _((void *, dir_walk_message_ty, string_ty *, struct stat *));
  
  static void
  deu_func(arg, message, path, st)
  	void		*arg;
! 	dir_walk_message_ty message;
! 	string_ty	*path;
  	struct stat	*st;
  {
! 	change_ty	*cp;
  	int		uid;
  
  	trace(("deu_func(message = %d, path = \"%s\", st = %08lX)\n{\n"/*}*/,
  		message, path->str_text, st));
! 	cp = (change_ty *)arg;
  	switch (message)
  	{
  	case dir_walk_dir_before:
***************
*** 1462,1473 ****
  	pstate		pstate_data;
  	cstate_history	history_data;
  	int		j;
! 	string_t	*project_name;
! 	project_t	*pp;
  	long		change_number;
! 	change_t	*cp;
! 	user_t		*up;
! 	string_t	*dd;
  
  	trace(("develop_end_undo_main()\n{\n"/*}*/));
  	project_name = 0;
--- 1717,1728 ----
  	pstate		pstate_data;
  	cstate_history	history_data;
  	int		j;
! 	string_ty	*project_name;
! 	project_ty	*pp;
  	long		change_number;
! 	change_ty	*cp;
! 	user_ty		*up;
! 	string_ty	*dd;
  
  	trace(("develop_end_undo_main()\n{\n"/*}*/));
  	project_name = 0;
***************
*** 1605,1614 ****
  	/*
  	 * change the ownership back to the user
  	 */
! 	dd = change_development_directory_get(cp);
  	user_become(up);
  	dir_walk(dd, deu_func, cp);
! 	os_become_undo();
  
  	/*
  	 * write out the data and release the locks
--- 1860,1869 ----
  	/*
  	 * change the ownership back to the user
  	 */
! 	dd = change_development_directory_get(cp, 1);
  	user_become(up);
  	dir_walk(dd, deu_func, cp);
! 	user_become_undo();
  
  	/*
  	 * write out the data and release the locks
Index: aegis/develop2.h
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
Index: aegis/diff.c
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 113,121 ****
  "",
  "	-Change <number>",
  "		This option may be used to specify a particular",
! "		change within a project.  If the user is only",
! "		working on one change within a project, that is",
! "		the default change number.",
  "",
  "	-Help",
  "		This option may be used to obtain more",
--- 113,126 ----
  "",
  "	-Change <number>",
  "		This option may be used to specify a particular",
! "		change within a project.  When no -Change option is",
! "		specified, the AEGIS_CHANGE environment variable is",
! "		consulted.  If that does not exist, the user's",
! "		$HOME/.aegisrc file is examined for a default change",
! "		field (see aeuconf(5) for more information).  If",
! "		that does not exist, when the user is only working",
! "		on one change within a project, that is the default",
! "		change number.  Otherwise, it is an error.",
  "",
  "	-Help",
  "		This option may be used to obtain more",
***************
*** 128,141 ****
  "",
  "	-Project <name>",
  "		This option may be used to select the project of",
! "		interest.  When no -Project option is specified, if",
! "		the user is only working on changes within a single",
! "		project, the project name defaults to that project;",
! "		if the user is currently working on changes to more",
! "		than one project, or is not working on changes to",
! "		any project, the user's $HOME/.%src file is",
! "		examined for a default project field (see aeuconf(5)",
! "		for more information).",
  "",
  "	-TERse",
  "		This option may be used to cause listings to",
--- 133,146 ----
  "",
  "	-Project <name>",
  "		This option may be used to select the project of",
! "		interest.  When no -Project option is specified, the",
! "		AEGIS_PROJECT environment variable is consulted.  If",
! "		that does not exist, the user's $HOME/.aegisrc file",
! "		is examined for a default project field (see",
! "		aeuconf(5) for more information).  If that does not",
! "		exist, when the user is only working on changes",
! "		within a single project, the project name defaults",
! "		to that project.  Otherwise, it is an error.",
  "",
  "	-TERse",
  "		This option may be used to cause listings to",
***************
*** 149,159 ****
  "		option this option causes column headings to be",
  "		added.",
  "",
! "	All options are case insensitive.  Options may be",
! "	abbreviated; the abbreviation is the upper case letters.",
  "	Options and other command line arguments may be mixed",
! "	arbitrarily on the command line.",
  "",
  "RECOMMENDED ALIAS",
  "	The recommended alias for this command is",
  "	csh%%	alias aed '%s -diff \\!* -v'",
--- 154,182 ----
  "		option this option causes column headings to be",
  "		added.",
  "",
! "	All options may be abbreviated; the abbreviation is",
! "	documented as the upper case letters, all lower case",
! "	letters and underscores (_) are optional.  You must use",
! "	consecutive sequences of optional letters.",
! "",
! "	All options are case insensitive, you may type them in",
! "	upper case or lower case or a combination of both, case",
! "	is not important.",
! "",
! "	For example: the arguments \"-project, \"-PROJ\" and \"-p\"",
! "	are all interpreted to mean the -Project option.  The",
! "	argument \"-prj\" will not be understood, because",
! "	consecutive optional characters were not supplied.",
! "",
  "	Options and other command line arguments may be mixed",
! "	arbitrarily on the command line, after the function",
! "	selectors.",
  "",
+ "	The GNU long option names are understood.  Since all",
+ "	option names for aegis are long, this means ignoring the",
+ "	extra leading '-'.  The \"--option=value\" convention is",
+ "	also understood.",
+ "",
  "RECOMMENDED ALIAS",
  "	The recommended alias for this command is",
  "	csh%%	alias aed '%s -diff \\!* -v'",
***************
*** 183,189 ****
  static void
  difference_list()
  {
! 	string_t	*project_name;
  	long		change_number;
  
  	trace(("difference_list()\n{\n"/*}*/));
--- 206,212 ----
  static void
  difference_list()
  {
! 	string_ty	*project_name;
  	long		change_number;
  
  	trace(("difference_list()\n{\n"/*}*/));
***************
*** 234,255 ****
  static void
  difference_main()
  {
! 	string_t	*dd;
! 	string_t	*bl;
  	wlist		wl;
! 	string_t	*s1 = 0;
! 	string_t	*s2;
  	wlist		need_new_build;
  	pstate		pstate_data;
  	pconf		pconf_data;
  	cstate		cstate_data;
  	size_t		j;
! 	string_t	*project_name;
! 	project_t	*pp;
  	long		change_number;
! 	change_t	*cp;
  	int		nolog;
! 	user_t		*up;
  
  	trace(("difference_main()\n{\n"/*}*/));
  	wl_zero(&wl);
--- 257,278 ----
  static void
  difference_main()
  {
! 	string_ty	*dd;
! 	string_ty	*bl;
  	wlist		wl;
! 	string_ty	*s1 = 0;
! 	string_ty	*s2;
  	wlist		need_new_build;
  	pstate		pstate_data;
  	pconf		pconf_data;
  	cstate		cstate_data;
  	size_t		j;
! 	string_ty	*project_name;
! 	project_ty	*pp;
  	long		change_number;
! 	change_ty	*cp;
  	int		nolog;
! 	user_ty		*up;
  
  	trace(("difference_main()\n{\n"/*}*/));
  	wl_zero(&wl);
***************
*** 268,274 ****
  		case arglex_token_string:
  			s1 = str_from_c(arglex_value.alv_string);
  			os_become_orig();
! 			s2 = os_pathname(s1);
  			os_become_undo();
  			if (wl_member(&wl, s2))
  			{
--- 291,297 ----
  		case arglex_token_string:
  			s1 = str_from_c(arglex_value.alv_string);
  			os_become_orig();
! 			s2 = os_pathname(s1, 1);
  			os_become_undo();
  			if (wl_member(&wl, s2))
  			{
***************
*** 389,397 ****
  		{
  			s1 = wl.wl_word[j];
  			assert(s1->str_text[0] == '/');
! 			s2 = os_below_dir(change_development_directory_get(cp), s1);
  			if (!s2)
! 				s2 = os_below_dir(project_baseline_path_get(pp), s1);
  			if (!s2)
  				change_fatal(cp, "path \"%S\" unrelated", s1);
  			str_free(s1);
--- 412,420 ----
  		{
  			s1 = wl.wl_word[j];
  			assert(s1->str_text[0] == '/');
! 			s2 = os_below_dir(change_development_directory_get(cp, 1), s1);
  			if (!s2)
! 				s2 = os_below_dir(project_baseline_path_get(pp, 1), s1);
  			if (!s2)
  				change_fatal(cp, "path \"%S\" unrelated", s1);
  			str_free(s1);
***************
*** 422,437 ****
  	if (!nolog)
  		log_open(change_logfile_get(cp), up);
  	pconf_data = change_pconf_get(cp);
! 	dd = change_development_directory_get(cp);
! 	bl = project_baseline_path_get(pp);
  	for (j = 0; j < wl.wl_nwords; ++j)
  	{
  		cstate_src	src1_data;
  		pstate_src	src2_data;
! 		string_t	*outname;
! 		string_t	*curfile;
! 		string_t	*the_command = 0;
! 		string_t	*orig1 = 0;
  		int		ignore;
  
  		s1 = wl.wl_word[j];
--- 445,460 ----
  	if (!nolog)
  		log_open(change_logfile_get(cp), up);
  	pconf_data = change_pconf_get(cp);
! 	dd = change_development_directory_get(cp, 1);
! 	bl = project_baseline_path_get(pp, 1);
  	for (j = 0; j < wl.wl_nwords; ++j)
  	{
  		cstate_src	src1_data;
  		pstate_src	src2_data;
! 		string_ty	*original;
! 		string_ty	*input;
! 		string_ty	*curfile;
! 		string_ty	*outname;
  		int		ignore;
  
  		s1 = wl.wl_word[j];
***************
*** 481,519 ****
  				&&
  					src1_data->diff_file_time == os_mtime(outname)
  				);
! 			os_become_undo();
  			if (ignore)
  				break;
  
  			/*
! 			 * if the file is a new file,
! 			 * use the diff-command
! 			 * %1 set to /dev/null,
! 			 * %2 set to development copy file,
! 			 * %3 set to development copy file with a ",D" suffix.
  			 */
! 			the_command =
! 				substitute
! 				(
! 					cp,
! 					pconf_data->diff_command->str_text,
! 					"/dev/null",
! 					curfile->str_text,
! 					outname->str_text,
! 					(char *)0
! 				);
! 			trace_string(the_command->str_text);
! 			user_become(up);
! 			os_execute
  			(
! 				the_command,
! 				OS_EXEC_FLAG_NO_INPUT,
! 				dd
  			);
! 			str_free(the_command);
  			src1_data->diff_time = os_mtime(curfile);
  			src1_data->diff_file_time = os_mtime(outname);
! 			os_become_undo();
  			break;
  
  		case file_action_remove:
--- 504,531 ----
  				&&
  					src1_data->diff_file_time == os_mtime(outname)
  				);
! 			user_become_undo();
  			if (ignore)
  				break;
  
  			/*
! 			 * difference the file
! 			 * from nothing
  			 */
! 			original = str_from_c("/dev/null");
! 			change_run_diff_command
  			(
! 				cp,
! 				up,
! 				original,
! 				curfile,
! 				outname
  			);
! 			str_free(original);
! 			user_become(up);
  			src1_data->diff_time = os_mtime(curfile);
  			src1_data->diff_file_time = os_mtime(outname);
! 			user_become_undo();
  			break;
  
  		case file_action_remove:
***************
*** 543,549 ****
  				&&
  					src1_data->diff_file_time == os_mtime(outname)
  				);
! 			os_become_undo();
  			if (ignore)
  				break;
  
--- 555,561 ----
  				&&
  					src1_data->diff_file_time == os_mtime(outname)
  				);
! 			user_become_undo();
  			if (ignore)
  				break;
  
***************
*** 553,585 ****
  			 */
  			user_become(up);
  			os_mkdir_between(dd, s1, 02755);
! 			os_become_undo();
  
  			/*
! 			 * if the file is being deleted,
! 			 * use the diff-command
! 			 * %1 set to baseline file,
! 			 * %2 set to /dev/null,
! 			 * %3 set to development copy file with a ",D" suffix.
  			 */
! 			orig1 = str_format("%S/%S", bl, s1);
! 			the_command =
! 				substitute
! 				(
! 					cp,
! 					pconf_data->diff_command->str_text,
! 					orig1->str_text,
! 					"/dev/null",
! 					outname->str_text,
! 					(char *)0
! 				);
! 			str_free(orig1);
  			user_become(up);
- 			os_execute(the_command, OS_EXEC_FLAG_NO_INPUT, dd);
- 			str_free(the_command);
  			src1_data->diff_time = 0;
  			src1_data->diff_file_time = os_mtime(outname);
! 			os_become_undo();
  			break;
  
  		case file_action_modify:
--- 565,592 ----
  			 */
  			user_become(up);
  			os_mkdir_between(dd, s1, 02755);
! 			user_become_undo();
  
  			/*
! 			 * difference the file
! 			 * to nothing
  			 */
! 			original = str_format("%S/%S", bl, s1);
! 			input = str_from_c("/dev/null");
! 			change_run_diff_command
! 			(
! 				cp,
! 				up,
! 				original,
! 				input,
! 				outname
! 			);
! 			str_free(original);
! 			str_free(input);
  			user_become(up);
  			src1_data->diff_time = 0;
  			src1_data->diff_file_time = os_mtime(outname);
! 			user_become_undo();
  			break;
  
  		case file_action_modify:
***************
*** 617,623 ****
  					&&
  						src1_data->diff_file_time == os_mtime(outname)
  					);
! 				os_become_undo();
  				if (ignore)
  					break;
  
--- 624,630 ----
  					&&
  						src1_data->diff_file_time == os_mtime(outname)
  					);
! 				user_become_undo();
  				if (ignore)
  					break;
  
***************
*** 625,663 ****
  				 * If the edit number of the file in the change
  				 * files table matches the edit number in the
  				 * baseline files table,
! 				 * use the diff-command field from the product
! 				 * table
! 				 * %1 set to baseline file,
! 				 * %2 set to development copy file,
! 				 * %3 set to development copy file with a ",D"
  				 */
! 				orig1 = str_format("%S/%S", bl, s1);
! 				the_command =
! 					substitute
! 					(
! 						cp,
! 					     pconf_data->diff_command->str_text,
! 						orig1->str_text,
! 						curfile->str_text,
! 						outname->str_text,
! 						(char *)0
! 					);
  				user_become(up);
- 				os_execute(the_command, OS_EXEC_FLAG_NO_INPUT, dd);
- 				str_free(the_command);
  				src1_data->diff_time = os_mtime(curfile);
  				src1_data->diff_file_time = os_mtime(outname);
! 				os_become_undo();
! 				str_free(orig1);
  			}
  			else
  			{
! 				string_t	*orig2;
  
  				/*
  				 * name for temp file
  				 */
! 				orig1 =
  					str_format
  					(
  						"/tmp/%s.%d",
--- 632,662 ----
  				 * If the edit number of the file in the change
  				 * files table matches the edit number in the
  				 * baseline files table,
! 				 * use the diff-command
  				 */
! 				original = str_format("%S/%S", bl, s1);
! 				change_run_diff_command
! 				(
! 					cp,
! 					up,
! 					original,
! 					curfile,
! 					outname
! 				);
! 				str_free(original);
  				user_become(up);
  				src1_data->diff_time = os_mtime(curfile);
  				src1_data->diff_file_time = os_mtime(outname);
! 				user_become_undo();
  			}
  			else
  			{
! 				string_ty	*most_recent;
  
  				/*
  				 * name for temp file
  				 */
! 				original =
  					str_format
  					(
  						"/tmp/%s.%d",
***************
*** 665,671 ****
  						getpid()
  					);
  				user_become(up);
! 				undo_unlink_errok(orig1);
  				user_become_undo();
  
  				/*
--- 664,670 ----
  						getpid()
  					);
  				user_become(up);
! 				undo_unlink_errok(original);
  				user_become_undo();
  
  				/*
***************
*** 676,718 ****
  					cp,
  					s1,
  					src1_data->edit_number,
! 					orig1,
  					up
  				);
  
  				/*
! 				 * and then use the diff3-command from the
! 				 * product table
! 				 * %1 set to the temporary file,
! 				 * %2 set to baseline file,
! 				 * %3 set to development copy file,
! 				 * %4 set to development copy file with a ",D"
  				 */
! 				orig2 = str_format("%S/%S", bl, s1);
! 				the_command =
! 					substitute
! 					(
! 						cp,
! 					    pconf_data->diff3_command->str_text,
! 						orig1->str_text,
! 						orig2->str_text,
! 						curfile->str_text,
! 						outname->str_text,
! 						(char *)0
! 					);
! 				user_become(up);
! 				os_execute(the_command, OS_EXEC_FLAG_NO_INPUT, dd);
! 				str_free(the_command);
  
  				/*
  				 * Remember to remove the temporary file when
  				 * finished.
  				 */
! 				os_unlink(orig1);
! 				os_become_undo();
  
  				/*
! 				 * Set the edit number in the change file row
  				 * to the latest baseline edit number.
  				 */
  				str_free(src1_data->edit_number);
--- 675,710 ----
  					cp,
  					s1,
  					src1_data->edit_number,
! 					original,
  					up
  				);
  
  				/*
! 				 * use the diff3-command
  				 */
! 				most_recent = str_format("%S/%S", bl, s1);
! 				change_run_diff3_command
! 				(
! 					cp,
! 					up,
! 					original,
! 					most_recent,
! 					curfile,
! 					outname
! 				);
! 				str_free(most_recent);
  
  				/*
  				 * Remember to remove the temporary file when
  				 * finished.
  				 */
! 				user_become(up);
! 				os_unlink(original);
! 				user_become_undo();
! 				str_free(original);
  
  				/*
! 				 * Set the edit number in the change
  				 * to the latest baseline edit number.
  				 */
  				str_free(src1_data->edit_number);
***************
*** 721,732 ****
  
  				/*
  				 * Invalidate the build-time field.
  				 * (because need new build)
  				 */
  				wl_append(&need_new_build, src1_data->file_name);
  				cstate_data->build_time = 0;
- 				str_free(orig1);
- 				str_free(orig2);
  				src1_data->diff_time = 0;
  				src1_data->diff_file_time = 0;
  			}
--- 713,723 ----
  
  				/*
  				 * Invalidate the build-time field.
+ 				 * Invalidate the diff-time fields.
  				 * (because need new build)
  				 */
  				wl_append(&need_new_build, src1_data->file_name);
  				cstate_data->build_time = 0;
  				src1_data->diff_time = 0;
  				src1_data->diff_file_time = 0;
  			}
***************
*** 759,765 ****
  			change_error
  			(
  				cp,
! 			"file \"%S\" was out-of-date, see \"%S,D\" for details",
  				need_new_build.wl_word[j],
  				need_new_build.wl_word[j]
  			);
--- 750,756 ----
  			change_error
  			(
  				cp,
! 			"file \"%S\" was out of date, see \"%S,D\" for details",
  				need_new_build.wl_word[j],
  				need_new_build.wl_word[j]
  			);
Index: aegis/diff.h
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
Index: aegis/dir.c
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 22,32 ****
  
  #include <sys/types.h>
  #include <sys/stat.h>
- #include <dirent.h>
- #include <unistd.h>
  
  #include <dir.h>
  #include <error.h>
  #include <trace.h>
  #include <word.h>
  
--- 22,31 ----
  
  #include <sys/types.h>
  #include <sys/stat.h>
  
  #include <dir.h>
  #include <error.h>
+ #include <glue.h>
  #include <trace.h>
  #include <word.h>
  
***************
*** 33,56 ****
  
  void
  dir_walk(path, callback, arg)
! 	string_t	*path;
! 	dir_walk_callback_t callback;
  	void		*arg;
  {
  	wlist		wl;
  	struct stat	st;
- 	DIR		*dp;
- 	struct dirent	*de;
  	int		j;
! 	string_t	*s;
  
! 	trace(("dir_walk(path = %08lX, callback = %08lX, arg = %08lX)\n{\n"/*}*/, path, callback, arg));
  	trace_string(path->str_text);
  #ifdef S_IFLNK
! 	if (lstat(path->str_text, &st))
  		nfatal("lstat(\"%s\")", path->str_text);
  #else
! 	if (stat(path->str_text, &st))
  		nfatal("stat(\"%s\")", path->str_text);
  #endif
  	switch (st.st_mode & S_IFMT)
--- 32,57 ----
  
  void
  dir_walk(path, callback, arg)
! 	string_ty	*path;
! 	dir_walk_callback_ty callback;
  	void		*arg;
  {
  	wlist		wl;
  	struct stat	st;
  	int		j;
! 	string_ty	*s;
! 	char		*cp;
! 	char		*data;
! 	long		data_len;
  
! 	trace(("dir_walk(path = %08lX, callback = %08lX, \
! arg = %08lX)\n{\n"/*}*/, path, callback, arg));
  	trace_string(path->str_text);
  #ifdef S_IFLNK
! 	if (glue_lstat(path->str_text, &st))
  		nfatal("lstat(\"%s\")", path->str_text);
  #else
! 	if (glue_stat(path->str_text, &st))
  		nfatal("stat(\"%s\")", path->str_text);
  #endif
  	switch (st.st_mode & S_IFMT)
***************
*** 58,91 ****
  	case S_IFDIR:
  		callback(arg, dir_walk_dir_before, path, &st);
  		wl_zero(&wl);
! 		dp = opendir(path->str_text);
! 		if (!dp)
! 			nfatal("opendir(\"%s\")", path->str_text);
! 		for (;;)
  		{
! 			de = readdir(dp);
! 			if (!de)
! 				break;
! 			if
! 			(
! 				de->d_name[0] == '.'
! 			&&
! 				(
! 					!de->d_name[1]
! 				||
! 					(
! 						de->d_name[1] == '.'
! 					&&
! 						!de->d_name[2]
! 					)
! 				)
! 			)
! 				continue;
! 			s = str_from_c(de->d_name);
  			wl_append(&wl, s);
  			str_free(s);
  		}
- 		closedir(dp);
  		for (j = 0; j < wl.wl_nwords; ++j)
  		{
  			s = str_format("%S/%S", path, wl.wl_word[j]);
--- 59,74 ----
  	case S_IFDIR:
  		callback(arg, dir_walk_dir_before, path, &st);
  		wl_zero(&wl);
! 		if (glue_read_whole_dir(path->str_text, &data, &data_len))
! 			nfatal("read \"%s\" directory", path->str_text);
! 		cp = data;
! 		while (cp < data + data_len)
  		{
! 			s = str_from_c(cp);
! 			cp += s->str_length + 1;
  			wl_append(&wl, s);
  			str_free(s);
  		}
  		for (j = 0; j < wl.wl_nwords; ++j)
  		{
  			s = str_format("%S/%S", path, wl.wl_word[j]);
Index: aegis/dir.h
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 26,32 ****
  #include <main.h>
  #include <str.h>
  
! enum dir_walk_message_t
  {
  	dir_walk_dir_before,
  	dir_walk_dir_after,
--- 26,32 ----
  #include <main.h>
  #include <str.h>
  
! enum dir_walk_message_ty
  {
  	dir_walk_dir_before,
  	dir_walk_dir_after,
***************
*** 34,45 ****
  	dir_walk_special,
  	dir_walk_symlink
  };
! typedef enum dir_walk_message_t dir_walk_message_t;
  
  struct stat;
  
! typedef void (*dir_walk_callback_t)_((void *arg, dir_walk_message_t, string_t *, struct stat *));
  
! void dir_walk _((string_t *, dir_walk_callback_t, void *arg));
  
  #endif /* DIR_H */
--- 34,46 ----
  	dir_walk_special,
  	dir_walk_symlink
  };
! typedef enum dir_walk_message_ty dir_walk_message_ty;
  
  struct stat;
  
! typedef void (*dir_walk_callback_ty)_((void *arg, dir_walk_message_ty,
! 	string_ty *, struct stat *));
  
! void dir_walk _((string_ty *, dir_walk_callback_ty, void *arg));
  
  #endif /* DIR_H */
Index: aegis/file.c
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 26,31 ****
--- 26,32 ----
  
  #include <file.h>
  #include <error.h>
+ #include <glue.h>
  #include <mem.h>
  #include <os.h>
  #include <trace.h>
***************
*** 36,42 ****
   *	copy_whole_file
   *
   * SYNOPSIS
!  *	void copy_whole_file(string_t *from, string_t *to, int cmt);
   *
   * DESCRIPTION
   *	The copy_whole_file function is used to
--- 37,43 ----
   *	copy_whole_file
   *
   * SYNOPSIS
!  *	void copy_whole_file(string_ty *from, string_ty *to, int cmt);
   *
   * DESCRIPTION
   *	The copy_whole_file function is used to
***************
*** 57,103 ****
  
  void
  copy_whole_file(from, to, cmt)
! 	string_t	*from;
! 	string_t	*to;
  	int		cmt;
  {
- 	FILE		*fp1;
- 	FILE		*fp2;
- 	int		c;
- 
  	trace(("copy_whole_file(from = %08lX, to = %08lX)\n{\n"/*}*/, from, to));
  	os_become_must_be_active();
  	trace_string(from->str_text);
  	trace_string(to->str_text);
- 	fp1 = fopen(from->str_text, "rb");
- 	if (!fp1)
- 		nfatal("fopen(\"%s\", \"rb\")", from->str_text);
  	if (to->str_length)
  	{
! 		fp2 = fopen(to->str_text, "wb");
! 		if (!fp2)
! 			nfatal("fopen(\"%s\", \"wb\")", to->str_text);
  	}
  	else
- 		fp2 = stdout;
- 	while ((c = fgetc(fp1)) != EOF)
  	{
! 		fputc(c, fp2);
! 		if (ferror(fp2))
! 		{
! 			if (fp2 == stdout)
! 				nfatal("standard output");
! 			nfatal("write(\"%s\")", to->str_text);
! 		}
  	}
- 	if (ferror(fp1))
- 		nfatal("read(\"%s\")", from->str_text);
- 	if (fclose(fp1))
- 		nfatal("close(\"%s\")", from->str_text);
- 	if (fflush(fp2))
- 		nfatal("write(\"%s\")", to->str_text);
- 	if (fp2 != stdout && fclose(fp2))
- 		nfatal("close(\"%s\")", to->str_text);
  
  	/*
  	 * copy last-time-modified of the file
--- 58,88 ----
  
  void
  copy_whole_file(from, to, cmt)
! 	string_ty	*from;
! 	string_ty	*to;
  	int		cmt;
  {
  	trace(("copy_whole_file(from = %08lX, to = %08lX)\n{\n"/*}*/, from, to));
  	os_become_must_be_active();
  	trace_string(from->str_text);
  	trace_string(to->str_text);
  	if (to->str_length)
  	{
! 		if (glue_copyfile(from->str_text, to->str_text))
! 		{
! 			nfatal
! 			(
! 				"cp \"%s\" \"%s\"",
! 				from->str_text,
! 				to->str_text
! 			);
! 		}
  	}
  	else
  	{
! 		if (glue_catfile(from->str_text))
! 			nfatal("cat \"%s\"", from->str_text);
  	}
  
  	/*
  	 * copy last-time-modified of the file
***************
*** 118,124 ****
   *	read_whole_file
   *
   * SYNOPSIS
!  *	string_t *read_whole_file(char *path);
   *
   * DESCRIPTION
   *	The read_whole_file function is used to
--- 103,109 ----
   *	read_whole_file
   *
   * SYNOPSIS
!  *	string_ty *read_whole_file(char *path);
   *
   * DESCRIPTION
   *	The read_whole_file function is used to
***************
*** 135,141 ****
   *	Assumes the user has already been set.
   */
  
! string_t *
  read_whole_file(fn)
  	char		*fn;
  {
--- 120,126 ----
   *	Assumes the user has already been set.
   */
  
! string_ty *
  read_whole_file(fn)
  	char		*fn;
  {
***************
*** 142,148 ****
  	size_t		length_max;
  	size_t		length;
  	char		*text;
! 	string_t	*s;
  	int		c;
  	FILE		*fp;
  
--- 127,133 ----
  	size_t		length_max;
  	size_t		length;
  	char		*text;
! 	string_ty	*s;
  	int		c;
  	FILE		*fp;
  
***************
*** 150,159 ****
  	length_max = 1000;
  	length = 0;
  	text = mem_alloc(length_max);
! 	fp = fopen(fn, "r");
  	if (!fp)
  		nfatal("open(\"%s\")", fn);
! 	while ((c = fgetc(fp)) != EOF)
  	{
  		if (length >= length_max)
  		{
--- 135,144 ----
  	length_max = 1000;
  	length = 0;
  	text = mem_alloc(length_max);
! 	fp = glue_fopen(fn, "r");
  	if (!fp)
  		nfatal("open(\"%s\")", fn);
! 	while ((c = glue_fgetc(fp)) != EOF)
  	{
  		if (length >= length_max)
  		{
***************
*** 162,172 ****
  		}
  		text[length++] = c;
  	}
! 	if (ferror(fp))
  		nfatal("read(\"%s\")", fn);
  	while (length > 0 && isspace(text[length - 1]))
  		--length;
! 	fclose(fp);
  	s = str_n_from_c(text, length);
  	mem_free(text);
  	return s;
--- 147,157 ----
  		}
  		text[length++] = c;
  	}
! 	if (glue_ferror(fp))
  		nfatal("read(\"%s\")", fn);
  	while (length > 0 && isspace(text[length - 1]))
  		--length;
! 	glue_fclose(fp);
  	s = str_n_from_c(text, length);
  	mem_free(text);
  	return s;
Index: aegis/file.h
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 26,32 ****
  #include <main.h>
  #include <str.h>
  
! void copy_whole_file _((string_t *from, string_t *to, int cmt));
! string_t *read_whole_file _((char *));
  
  #endif /* FILE_H */
--- 26,32 ----
  #include <main.h>
  #include <str.h>
  
! void copy_whole_file _((string_ty *from, string_ty *to, int cmt));
! string_ty *read_whole_file _((char *));
  
  #endif /* FILE_H */
Index: aegis/glue.c
***************
*** 0 ****
--- 1,2260 ----
+ /*
+  *	aegis - project change supervisor
+  *	Copyright (C) 1993 Peter Miller.
+  *	All rights reserved.
+  *
+  *	This program is free software; you can redistribute it and/or modify
+  *	it under the terms of the GNU General Public License as published by
+  *	the Free Software Foundation; either version 2 of the License, or
+  *	(at your option) any later version.
+  *
+  *	This program is distributed in the hope that it will be useful,
+  *	but WITHOUT ANY WARRANTY; without even the implied warranty of
+  *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  *	GNU General Public License for more details.
+  *
+  *	You should have received a copy of the GNU General Public License
+  *	along with this program; if not, write to the Free Software
+  *	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+  *
+  * MANIFEST: functions to perform systems calls in subprocesses
+  *
+  * Most of the functions in this file are only used when
+  * the CONF_NO_seteuid  symbol is defined in common/conf.h.
+  *
+  * The various system calls wgich must be perfomed as a specific user
+  * are given to a "proxy" process to perform, where this proxy process
+  * has the appropriate real (and effective) user id and group id.
+  * These processes terminate when they see end-of-file on their command
+  * streams, which only happens when the parent process exits.
+  *
+  * The overhead of communicating with the proxy process will
+  * naturally result in a performance hit for systems without
+  * a seteuid system call.
+  *
+  * Note that some systems, notably AIX, have a seteuid system call
+  * which is broken.  These systems will also need to use this glue.
+  */
+ 
+ #include <sys/types.h>
+ #include <dirent.h>
+ #include <errno.h>
+ #include <fcntl.h>
+ #include <signal.h>
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <unistd.h>
+ #include <utime.h>
+ 
+ #include <error.h>
+ #include <glue.h>
+ #include <mem.h>
+ #include <os.h>
+ #include <trace.h>
+ #include <undo.h>
+ 
+ #ifdef CONF_NO_seteuid
+ 
+ #define GUARD1 0x416E6479
+ #define GUARD2 0x4C777279
+ 
+ enum
+ {
+ 	command_access,
+ 	command_catfile,
+ 	command_chmod,
+ 	command_chown,
+ 	command_close,
+ 	command_copyfile,
+ 	command_creat,
+ 	command_fcntl,
+ 	command_getcwd,
+ 	command_link,
+ 	command_lstat,
+ 	command_mkdir,
+ 	command_open,
+ 	command_read,
+ 	command_readlink,
+ 	command_read_whole_dir,
+ 	command_rename,
+ 	command_rmdir,
+ 	command_stat,
+ 	command_unlink,
+ 	command_utime,
+ 	command_write,
+ };
+ 
+ 
+ typedef struct proxy_ty proxy_ty;
+ struct proxy_ty
+ {
+ 	int		hash;
+ 	int		uid;
+ 	int		gid;
+ 	int		umask;
+ 	int		pid;
+ 	FILE		*command;
+ 	FILE		*reply;
+ 	proxy_ty	*next;
+ 
+ };
+ 
+ #define proxy_hash(u, g, m) (((u) * 16 + (g) * 4 + (m)) & 0x7FFF)
+ 
+ /*
+  * This table will be sparsely filled.
+  * The maximum number of entries expected is 4.
+  * The size MUST be prime.
+  */
+ static proxy_ty	*proxy_table[17];
+ 
+ 
+ #ifdef DEBUG
+ 
+ static char *command_name _((int));
+ 
+ static char *
+ command_name(n)
+ 	int		n;
+ {
+ 	static char	buf[12];
+ 
+ 	switch (n)
+ 	{
+ 	case EOF:		return "quit";
+ 	case command_access:	return "access";
+ 	case command_catfile:	return "catfile";
+ 	case command_chmod:	return "chmod";
+ 	case command_chown:	return "chown";
+ 	case command_close:	return "close";
+ 	case command_copyfile:	return "copyfile";
+ 	case command_creat:	return "creat";
+ 	case command_fcntl:	return "fcntl";
+ 	case command_getcwd:	return "getcwd";
+ 	case command_link:	return "link";
+ 	case command_lstat:	return "lstat";
+ 	case command_mkdir:	return "mkdir";
+ 	case command_open:	return "open";
+ 	case command_read:	return "read";
+ 	case command_readlink:	return "readlink";
+ 	case command_read_whole_dir: return "read_whole_dir";
+ 	case command_rename:	return "rename";
+ 	case command_rmdir:	return "rmdir";
+ 	case command_stat:	return "stat";
+ 	case command_unlink:	return "unlink";
+ 	case command_utime:	return "utime";
+ 	case command_write:	return "write";
+ 	}
+ 	sprintf(buf, "%d", n);
+ 	return buf;
+ }
+ 
+ #endif
+ 
+ 
+ static void put_int _((FILE *, int));
+ 
+ static void
+ put_int(fp, n)
+ 	FILE		*fp;
+ 	int		n;
+ {
+ 	int		j;
+ 	unsigned char	*ptr;
+ 
+ 	trace(("put_int(%d)\n{\n"/*}*/, n));
+ 	ptr = (unsigned char *)&n; 
+ 	for (j = 0; j < sizeof(int); ++j)
+ 		putc(ptr[j], fp);
+ 	if (ferror(fp))
+ 		nfatal("writing pipe");
+ 	trace((/*{*/"}\n"));
+ }
+ 
+ 
+ static int get_int _((FILE *));
+ 
+ static int
+ get_int(fp)
+ 	FILE		*fp;
+ {
+ 	int		result;
+ 	int		j;
+ 	unsigned char	*ptr;
+ 
+ 	trace(("get_int()\n{\n"/*}*/));
+ 	ptr = (unsigned char *)&result;
+ 	for (j = 0; j < sizeof(int); ++j)
+ 	{
+ 		int	c;
+ 
+ 		c = getc(fp);
+ 		if (c == EOF)
+ 		{
+ 			if (ferror(fp))
+ 				nfatal("reading pipe");
+ 			fatal("reading pipe: proxy protocol error (%d)", getpid());
+ 		}
+ 		ptr[j] = c;
+ 	}
+ 	trace(("return %d;\n", result));
+ 	trace((/*{*/"}\n"));
+ 	return result;
+ }
+ 
+ 
+ static void put_long _((FILE *, long));
+ 
+ static void
+ put_long(fp, n)
+ 	FILE		*fp;
+ 	long		n;
+ {
+ 	int		j;
+ 	unsigned char	*ptr;
+ 
+ 	trace(("put_long(%ld)\n{\n"/*}*/, n));
+ 	ptr = (unsigned char *)&n; 
+ 	for (j = 0; j < sizeof(long); ++j)
+ 		putc(ptr[j], fp);
+ 	if (ferror(fp))
+ 		nfatal("writing pipe");
+ 	trace((/*{*/"}\n"));
+ }
+ 
+ 
+ static long get_long _((FILE *));
+ 
+ static long
+ get_long(fp)
+ 	FILE		*fp;
+ {
+ 	long		result;
+ 	int		j;
+ 	unsigned char	*ptr;
+ 
+ 	trace(("get_long()\n{\n"/*}*/));
+ 	ptr = (unsigned char *)&result;
+ 	for (j = 0; j < sizeof(long); ++j)
+ 	{
+ 		int	c;
+ 
+ 		c = getc(fp);
+ 		if (c == EOF)
+ 		{
+ 			if (ferror(fp))
+ 				nfatal("reading pipe");
+ 			fatal("reading pipe: proxy protocol error (%d)", getpid());
+ 		}
+ 		ptr[j] = c;
+ 	}
+ 	trace(("return %ld;\n", result));
+ 	trace((/*{*/"}\n"));
+ 	return result;
+ }
+ 
+ 
+ static void put_binary _((FILE *, void *, size_t));
+ 
+ static void
+ put_binary(fp, ptr, len)
+ 	FILE		*fp;
+ 	void		*ptr;
+ 	size_t		len;
+ {
+ 	trace(("put_binary(%ld)\n{\n"/*}*/, len));
+ 	fwrite(ptr, 1, len, fp);
+ 	if (ferror(fp))
+ 		nfatal("writing pipe");
+ 	trace((/*{*/"}\n"));
+ }
+ 
+ 
+ static void get_binary _((FILE *, void *, size_t));
+ 
+ static void
+ get_binary(fp, ptr, len)
+ 	FILE		*fp;
+ 	void		*ptr;
+ 	size_t		len;
+ {
+ 	long		n;
+ 
+ 	trace(("get_binary(%ld)\n{\n"/*}*/, len));
+ 	n = fread(ptr, 1, len, fp);
+ 	if (n != len)
+ 	{
+ 		if (ferror(fp))
+ 			nfatal("reading pipe");
+ 		fatal("reading pipe: proxy protocol error (%d)", getpid());
+ 	}
+ 	trace((/*{*/"}\n"));
+ }
+ 
+ 
+ static void put_string _((FILE *, char *));
+ 
+ static void
+ put_string(fp, s)
+ 	FILE		*fp;
+ 	char		*s;
+ {
+ 	trace(("put_string(\"%s\")\n{\n"/*}*/, s));
+ 	for (;;)
+ 	{
+ 		putc(*s, fp);
+ 		if (ferror(fp))
+ 			nfatal("writing pipe");
+ 		if (!*s)
+ 			break;
+ 		++s;
+ 	}
+ 	trace((/*{*/"}\n"));
+ }
+ 
+ 
+ static void *get_string _((FILE *));
+ 
+ static void *
+ get_string(fp)
+ 	FILE		*fp;
+ {
+ 	static char	*result;
+ 	static size_t	result_max;
+ 	size_t		pos;
+ 
+ 	trace(("get_string()\n{\n"/*}*/));
+ 	if (!result)
+ 	{
+ 		result_max = (1L << 10 ) - 32;
+ 		result = mem_alloc(result_max);
+ 	}
+ 
+ 	pos = 0;
+ 	for (;;)
+ 	{
+ 		int	c;
+ 
+ 		c = getc(fp);
+ 		if (c == EOF)
+ 		{
+ 			if (ferror(fp))
+ 				nfatal("reading pipe");
+ 			fatal("reading pipe: proxy protocol error (%d)", getpid());
+ 		}
+ 		if (pos >= result_max)
+ 		{
+ 			result_max += (1L << 10);
+ 			mem_change_size(&result, result_max);
+ 		}
+ 		result[pos] = c;
+ 		if (!c)
+ 			break;
+ 		++pos;
+ 	}
+ 	trace(("return \"%s\";\n", result));
+ 	trace((/*{*/"}\n"));
+ 	return result;
+ }
+ 
+ 
+ static void proxy _((int rd, int wr));
+ 
+ static void
+ proxy(rd_fd, wr_fd)
+ 	int		rd_fd;
+ 	int		wr_fd;
+ {
+ 	FILE		*command;
+ 	FILE		*reply;
+ 	char		*path;
+ 	char		*path1;
+ 	int		mode;
+ 	struct stat	st;
+ 	struct utimbuf	utb;
+ 	int		uid;
+ 	int		gid;
+ 	char		*buf;
+ 	int		max;
+ 	int		perm;
+ 	int		result;
+ 	int		fd;
+ 	long		nbytes;
+ 	long		nbytes2;
+ 	struct flock	flock;
+ 
+ 	trace(("proxy(%d, %d)\n{\n"/*}*/, rd_fd, wr_fd));
+ 	errno = 0;
+ 	command = fdopen(rd_fd, "r");
+ 	if (!command)
+ 	{
+ 		if (!errno)
+ 			errno = ENOMEM;
+ 		exit(errno);
+ 	}
+ 
+ 	errno = 0;
+ 	reply = fdopen(wr_fd, "w");
+ 	if (!reply)
+ 	{
+ 		if (!errno)
+ 			errno = ENOMEM;
+ 		exit(errno);
+ 	}
+ 
+ 	for (;;)
+ 	{
+ 		int	c;
+ 
+ 		c = getc(command);
+ 		trace(("command: %s\n", command_name(c)));
+ 		trace(("uid = %d;\n", getuid()));
+ 		trace(("gid = %d;\n", getgid()));
+ 		switch (c)
+ 		{
+ 		case EOF:
+ 			if (ferror(command))
+ 				exit(errno);
+ 			exit(0);
+ 
+ 		default:
+ 			fatal("proxy: unknown %d command (bug)", c);
+ 
+ 		case command_access:
+ 			path = get_string(command);
+ 			mode = get_int(command);
+ 			if (access(path, mode))
+ 				result = errno;
+ 			else
+ 				result = 0;
+ 			put_int(reply, result);
+ 			break;
+ 
+ 		case command_catfile:
+ 			path = get_string(command);
+ 			if (catfile(path))
+ 				result = errno;
+ 			else
+ 				result = 0;
+ 			put_int(reply, result);
+ 			break;
+ 
+ 		case command_chmod:
+ 			path = get_string(command);
+ 			mode = get_int(command);
+ 			if (chmod(path, mode))
+ 				result = errno;
+ 			else
+ 				result = 0;
+ 			put_int(reply, result);
+ 			break;
+ 
+ 		case command_chown:
+ 			path = get_string(command);
+ 			uid = get_int(command);
+ 			gid = get_int(command);
+ 			if (chown(path, uid, gid))
+ 				result = errno;
+ 			else
+ 				result = 0;
+ 			put_int(reply, result);
+ 			break;
+ 
+ 		case command_close:
+ 			fd = get_int(command);
+ 			if (close(fd))
+ 				result = errno;
+ 			else
+ 				result = 0;
+ 			put_int(reply, result);
+ 			break;
+ 
+ 		case command_copyfile:
+ 			path = get_string(command);
+ 			path1 = mem_copy_string(path);
+ 			path = get_string(command);
+ 			result = copyfile(path1, path);
+ 			if (result)
+ 				result = errno;
+ 			mem_free(path1);
+ 			put_int(reply, result);
+ 			break;
+ 
+ 		case command_creat:
+ 			path = get_string(command);
+ 			mode = get_int(command);
+ 			result = creat(path, mode);
+ 			put_int(reply, result);
+ 			if (result < 0)
+ 				put_int(reply, errno);
+ 			break;
+ 
+ 		case command_getcwd:
+ 			max = get_int(command);
+ 			path = mem_alloc(max);
+ 			if (!getcwd(path, max))
+ 				put_int(reply, errno);
+ 			else
+ 			{
+ 				put_int(reply, 0);
+ 				put_string(reply, path);
+ 			}
+ 			mem_free(path);
+ 			break;
+ 
+ 		case command_fcntl:
+ 			fd = get_int(command);
+ 			mode = get_int(command);
+ 			get_binary(command, &flock, sizeof(flock));
+ 			result = fcntl(fd, mode, &flock);
+ 			if (result)
+ 				result = errno;
+ 			put_int(reply, result);
+ 			put_binary(reply, &flock, sizeof(flock));
+ 			break;
+ 
+ 		case command_lstat:
+ 			path = get_string(command);
+ #ifdef S_IFLNK
+ 			result = lstat(path, &st);
+ #else
+ 			result = stat(path, &st);
+ #endif
+ 			if (result)
+ 				put_int(reply, errno);
+ 			else
+ 			{
+ 				put_int(reply, 0);
+ 				put_binary(reply, &st, sizeof(st));
+ 			}
+ 			break;
+ 
+ 
+ 		case command_link:
+ 			path = get_string(command);
+ 			path1 = mem_copy_string(path);
+ 			path = get_string(command);
+ 			result = link(path1, path);
+ 			if (result)
+ 				result = errno;
+ 			mem_free(path1);
+ 			put_int(reply, result);
+ 			break;
+ 
+ 		case command_mkdir:
+ 			path = get_string(command);
+ 			mode = get_int(command);
+ 			if (mkdir(path, mode))
+ 				result = errno;
+ 			else
+ 				result = 0;
+ 			put_int(reply, result);
+ 			break;
+ 
+ 		case command_open:
+ 			path = get_string(command);
+ 			mode = get_int(command);
+ 			perm = get_int(command);
+ 			result = open(path, mode, perm);
+ 			put_int(reply, result);
+ 			if (result < 0)
+ 				put_int(reply, errno);
+ 			break;
+ 
+ 		case command_rename:
+ 			path = get_string(command);
+ 			path1 = mem_copy_string(path);
+ 			path = get_string(command);
+ 			result = rename(path1, path);
+ 			if (result)
+ 				result = errno;
+ 			mem_free(path1);
+ 			put_int(reply, result);
+ 			break;
+ 
+ 		case command_read:
+ 			fd = get_int(command);
+ 			nbytes = get_long(command);
+ 			buf = mem_alloc(nbytes);
+ 			nbytes2 = read(fd, buf, nbytes);
+ 			put_long(reply, nbytes2);
+ 			if (nbytes2 > 0)
+ 				put_binary(reply, buf, nbytes2);
+ 			else if (nbytes2 < 0)
+ 				put_int(reply, errno);
+ 			mem_free(buf);
+ 			break;
+ 
+ 		case command_readlink:
+ 			path = get_string(command);
+ 			max = get_int(command);
+ 			path1 = mem_alloc(max + 1);
+ 			result = readlink(path, path1, max);
+ 			put_int(reply, result);
+ 			if (result < 0)
+ 				put_int(reply, errno);
+ 			else
+ 				put_binary(reply, path1, result);
+ 			mem_free(path1);
+ 			break;
+ 
+ 		case command_read_whole_dir:
+ 			path = get_string(command);
+ 			result = read_whole_dir(path, &buf, &nbytes);
+ 			if (result < 0)
+ 				put_int(reply, errno);
+ 			else
+ 			{
+ 				put_int(reply, 0);
+ 				put_long(reply, nbytes);
+ 				put_binary(reply, buf, nbytes);
+ 			}
+ 			break;
+ 
+ 		case command_rmdir:
+ 			path = get_string(command);
+ 			if (rmdir(path))
+ 				result = errno;
+ 			else
+ 				result = 0;
+ 			put_int(reply, result);
+ 			break;
+ 
+ 		case command_stat:
+ 			path = get_string(command);
+ 			result = stat(path, &st);
+ 			if (result)
+ 				put_int(reply, errno);
+ 			else
+ 			{
+ 				put_int(reply, 0);
+ 				put_binary(reply, &st, sizeof(st));
+ 			}
+ 			break;
+ 
+ 		case command_unlink:
+ 			path = get_string(command);
+ 			result = unlink(path);
+ 			if (result)
+ 				result = errno;
+ 			put_int(reply, result);
+ 			break;
+ 
+ 		case command_utime:
+ 			path = get_string(command);
+ 			get_binary(command, &utb, sizeof(utb));
+ 			result = utime(path, &utb);
+ 			if (result)
+ 				result = errno;
+ 			put_int(reply, result);
+ 			break;
+ 
+ 		case command_write:
+ 			fd = get_int(command);
+ 			nbytes = get_long(command);
+ 			buf = mem_alloc(nbytes);
+ 			get_binary(command, buf, nbytes);
+ 			nbytes2 = write(fd, buf, nbytes);
+ 			put_long(reply, nbytes2);
+ 			if (nbytes2 < 0)
+ 				put_int(reply, errno);
+ 			mem_free(buf);
+ 			break;
+ 		}
+ 		fflush(reply);
+ 		if (ferror(reply))
+ 			exit(errno);
+ 	}
+ 	trace((/*{*/"}\n"));
+ }
+ 
+ 
+ static void get_pipe _((int *, int *));
+ 
+ static void
+ get_pipe(rd, wr)
+ 	int	*rd;
+ 	int	*wr;
+ {
+ 	int	fd[2];
+ 
+ 	trace(("get_pipe()\n{\n"/*}*/));
+ 	if (pipe(fd))
+ 		nfatal("pipe");
+ 	*rd = fd[0];
+ 	*wr = fd[1];
+ 	trace(("read %d\n", fd[0]));
+ 	trace(("write %d\n", fd[1]));
+ 	trace((/*{*/"}\n"));
+ }
+ 
+ 
+ static  void proxy_close _((void));
+ 
+ static void
+ proxy_close()
+ {
+ 	proxy_ty	*p;
+ 	int		j;
+ 
+ 	trace(("proxy_close()\n{\n"/*}*/));
+ 	trace(("pid = %d;\n", getpid()));
+ 	for (j = 0; j < SIZEOF(proxy_table); ++j)
+ 	{
+ 		for (;;)
+ 		{
+ 			p = proxy_table[j];
+ 			if (!p)
+ 				break;
+ 			trace(("p->pid %d; uid %d; gid %d\n", p->pid, p->uid, p->gid));
+ 			proxy_table[j] = p->next;
+ 			fclose(p->command);
+ 			fclose(p->reply);
+ 			mem_free((char *)p);
+ 		}
+ 	}
+ 	trace((/*{*/"}\n"));
+ }
+ 
+ 
+ static void proxy_spawn _((proxy_ty *));
+ 
+ static void
+ proxy_spawn(pp)
+ 	proxy_ty	*pp;
+ {
+ 	int		command_read_fd;
+ 	int		command_write_fd;
+ 	int		reply_read_fd;
+ 	int		reply_write_fd;
+ 	int		pid;
+ 	static int	quitregd;
+ 
+ 	trace(("proxy_spawn()\n{\n"/*}*/));
+ 	if (!quitregd)
+ 	{
+ 		quitregd = 1;
+ 		signal(SIGPIPE, SIG_IGN);
+ 		trace(("master pid %d;\n", getpid()));
+ 	}
+ 
+ 	get_pipe(&command_read_fd, &command_write_fd);
+ 	get_pipe(&reply_read_fd, &reply_write_fd);
+ 	switch (pid = fork())
+ 	{
+ 	case -1:
+ 		nfatal("fork");
+ 
+ 	case 0:
+ 		/*
+ 		 * close the ends of the pipes the proxy will not be using
+ 		 */
+ 		close(command_write_fd);
+ 		close(reply_read_fd);
+ 		error_set_id_func((error_id_ty)0);
+ 
+ 		/*
+ 		 * the proxy now assumes the appropriate ID
+ 		 */
+ 		if (setgid(pp->gid))
+ 			exit(errno);
+ 		if (setuid(pp->uid))
+ 			exit(errno);
+ 		umask(pp->umask);
+ 
+ 		/*
+ 		 * close all of the master ends of all the other proxys
+ 		 * otherwise they will keep each other alive
+ 		 * after the master dies
+ 		 */
+ 		trace_indent_reset();
+ 		proxy_close();
+ 
+ 		/*
+ 		 * normally the proxys are silent,
+ 		 * returning all errors to the master.
+ 		 * Should one of the error functions be called,
+ 		 * make sure the proxy does not perform the undo.
+ 		 */
+ 		undo_cancel();
+ 
+ 		/*
+ 		 * do whatever is asked
+ 		 */
+ 		proxy(command_read_fd, reply_write_fd);
+ 		exit(0);
+ 
+ 	default:
+ 		/*
+ 		 * close the ends of the pipes the master will not be using
+ 		 */
+ 		close(command_read_fd);
+ 		close(reply_write_fd);
+ 
+ 		/*
+ 		 * remember who the child is
+ 		 * (even though we don't have a use for it at the moment)
+ 		 */
+ 		pp->pid = pid;
+ 		trace(("child pid %d\n", getpid()));
+ 
+ 		/*
+ 		 * open a buffered stream for commands
+ 		 */
+ 		errno = 0;
+ 		pp->command = fdopen(command_write_fd, "w");
+ 		if (!pp->command)
+ 		{
+ 			if (!errno)
+ 				errno = ENOMEM;
+ 			nfatal("fdopen");
+ 		}
+ 
+ 		/*
+ 		 * open a buffered stream for replies
+ 		 */
+ 		errno = 0;
+ 		pp->reply = fdopen(reply_read_fd, "r");
+ 		if (!pp->reply)
+ 		{
+ 			if (!errno)
+ 				errno = ENOMEM;
+ 			nfatal("fdopen");
+ 		}
+ 		break;
+ 	}
+ 	trace((/*{*/"}\n"));
+ }
+ 
+ 
+ static proxy_ty *proxy_find _((void));
+ 
+ static proxy_ty *
+ proxy_find()
+ {
+ 	int		uid;
+ 	int		gid;
+ 	int		um;
+ 	int		hash;
+ 	int		pix;
+ 	proxy_ty	*pp;
+ 
+ 	/*
+ 	 * search for an existing proxy
+ 	 */
+ 	trace(("proxy_find()\n{\n"/*}*/));
+ 	os_become_must_be_active();
+ 	os_become_query(&uid, &gid, &um);
+ 	hash = proxy_hash(uid, gid, um);
+ 	pix = hash % SIZEOF(proxy_table);
+ 	for (pp = proxy_table[pix]; pp; pp = pp->next)
+ 	{
+ 		if (pp->hash != hash)
+ 			continue;
+ 		if (pp->uid != uid || pp->gid != gid || pp->umask != um)
+ 			continue;
+ 		goto done;
+ 	}
+ 
+ 	/*
+ 	 * no such proxy, so create a new one
+ 	 */
+ 	trace(("uid = %d; gid = %d; umask = 0%o;\n", uid, gid, um));
+ 	pp = (proxy_ty *)mem_alloc(sizeof(proxy_ty));
+ 	pp->hash = hash;
+ 	pp->uid = uid;
+ 	pp->gid = gid;
+ 	pp->umask = um;
+ 	pp->pid = -1;
+ 	pp->command = 0;
+ 	pp->reply = 0;
+ 	pp->next = 0;
+ 	proxy_spawn(pp);
+ 
+ 	/*
+ 	 * glue into the table AFTER the spawn,
+ 	 * so the child doesn't close the wrong things.
+ 	 */
+ 	pp->next = proxy_table[pix];
+ 	proxy_table[pix] = pp;
+ 
+ 	/*
+ 	 * here for all exits
+ 	 */
+ 	done:
+ 	trace(("return %08lX;\n", (long)pp));
+ 	trace((/*{*/"}\n"));
+ 	return pp;
+ }
+ 
+ 
+ static void end_of_command _((proxy_ty *));
+ 
+ static void
+ end_of_command(pp)
+ 	proxy_ty	*pp;
+ {
+ 	trace(("end_of_command()\n{\n"/*}*/));
+ 	if (fflush(pp->command))
+ 		nfatal("write pipe");
+ 	trace((/*{*/"}\n"));
+ }
+ 
+ 
+ int
+ glue_stat(path, st)
+ 	char		*path;
+ 	struct stat	*st;
+ {
+ 	proxy_ty	*pp;
+ 	int		result;
+ 
+ 	trace(("glue_stat()\n{\n"/*}*/));
+ 	pp = proxy_find();
+ 	putc(command_stat, pp->command);
+ 	put_string(pp->command, path);
+ 	end_of_command(pp);
+ 	result = get_int(pp->reply);
+ 	if (result)
+ 	{
+ 		errno = result;
+ 		result = -1;
+ 	}
+ 	else
+ 		get_binary(pp->reply, st, sizeof(*st));
+ 	trace(("return %d; /* errno = %d */\n", result, errno));
+ 	trace((/*{*/"}\n"));
+ 	return result;
+ }
+ 
+ 
+ int
+ glue_lstat(path, st)
+ 	char		*path;
+ 	struct stat	*st;
+ {
+ 	proxy_ty	*pp;
+ 	int		result;
+ 
+ 	trace(("glue_lstat()\n{\n"/*}*/));
+ 	pp = proxy_find();
+ 	putc(command_lstat, pp->command);
+ 	put_string(pp->command, path);
+ 	end_of_command(pp);
+ 	result = get_int(pp->reply);
+ 	if (result)
+ 	{
+ 		errno = result;
+ 		result = -1;
+ 	}
+ 	else
+ 		get_binary(pp->reply, st, sizeof(*st));
+ 	trace(("return %d; /* errno = %d */\n", result, errno));
+ 	trace((/*{*/"}\n"));
+ 	return result;
+ }
+ 
+ 
+ int
+ glue_mkdir(path, mode)
+ 	char		*path;
+ 	int		mode;
+ {
+ 	proxy_ty	*pp;
+ 	int		result;
+ 
+ 	trace(("glue_mkdir()\n{\n"/*}*/));
+ 	pp = proxy_find();
+ 	putc(command_mkdir, pp->command);
+ 	put_string(pp->command, path);
+ 	put_int(pp->command, mode);
+ 	end_of_command(pp);
+ 	result = get_int(pp->reply);
+ 	if (result)
+ 	{
+ 		errno = result;
+ 		result = -1;
+ 	}
+ 	trace(("return %d; /* errno = %d */\n", result, errno));
+ 	trace((/*{*/"}\n"));
+ 	return result;
+ }
+ 
+ 
+ int
+ glue_chown(path, uid, gid)
+ 	char		*path;
+ 	int		uid;
+ 	int		gid;
+ {
+ 	proxy_ty	*pp;
+ 	int		result;
+ 
+ 	trace(("glue_chown()\n{\n"/*}*/));
+ 	pp = proxy_find();
+ 	putc(command_chown, pp->command);
+ 	put_string(pp->command, path);
+ 	put_int(pp->command, uid);
+ 	put_int(pp->command, gid);
+ 	end_of_command(pp);
+ 	result = get_int(pp->reply);
+ 	if (result)
+ 	{
+ 		errno = result;
+ 		result = -1;
+ 	}
+ 	trace(("return %d; /* errno = %d */\n", result, errno));
+ 	trace((/*{*/"}\n"));
+ 	return result;
+ }
+ 
+ 
+ int
+ glue_catfile(path)
+ 	char		*path;
+ {
+ 	proxy_ty	*pp;
+ 	int		result;
+ 
+ 	trace(("glue_catfile()\n{\n"/*}*/));
+ 	pp = proxy_find();
+ 	putc(command_catfile, pp->command);
+ 	put_string(pp->command, path);
+ 	end_of_command(pp);
+ 	result = get_int(pp->reply);
+ 	if (result)
+ 	{
+ 		errno = result;
+ 		result = -1;
+ 	}
+ 	trace(("return %d; /* errno = %d */\n", result, errno));
+ 	trace((/*{*/"}\n"));
+ 	return result;
+ }
+ 
+ 
+ int
+ glue_chmod(path, mode)
+ 	char		*path;
+ 	int		mode;
+ {
+ 	proxy_ty	*pp;
+ 	int		result;
+ 
+ 	trace(("glue_chmod()\n{\n"/*}*/));
+ 	pp = proxy_find();
+ 	putc(command_chmod, pp->command);
+ 	put_string(pp->command, path);
+ 	put_int(pp->command, mode);
+ 	end_of_command(pp);
+ 	result = get_int(pp->reply);
+ 	if (result)
+ 	{
+ 		errno = result;
+ 		result = -1;
+ 	}
+ 	trace(("return %d; /* errno = %d */\n", result, errno));
+ 	trace((/*{*/"}\n"));
+ 	return result;
+ }
+ 
+ 
+ int
+ glue_rmdir(path)
+ 	char		*path;
+ {
+ 	proxy_ty	*pp;
+ 	int		result;
+ 
+ 	trace(("glue_rmdir()\n{\n"/*}*/));
+ 	pp = proxy_find();
+ 	putc(command_rmdir, pp->command);
+ 	put_string(pp->command, path);
+ 	end_of_command(pp);
+ 	result = get_int(pp->reply);
+ 	if (result)
+ 	{
+ 		errno = result;
+ 		result = -1;
+ 	}
+ 	trace(("return %d; /* errno = %d */\n", result, errno));
+ 	trace((/*{*/"}\n"));
+ 	return result;
+ }
+ 
+ 
+ int
+ glue_rename(p1, p2)
+ 	char		*p1;
+ 	char		*p2;
+ {
+ 	proxy_ty	*pp;
+ 	int		result;
+ 
+ 	trace(("glue_rename()\n{\n"/*}*/));
+ 	pp = proxy_find();
+ 	putc(command_rename, pp->command);
+ 	put_string(pp->command, p1);
+ 	put_string(pp->command, p2);
+ 	end_of_command(pp);
+ 	result = get_int(pp->reply);
+ 	if (result)
+ 	{
+ 		errno = result;
+ 		result = -1;
+ 	}
+ 	trace(("return %d; /* errno = %d */\n", result, errno));
+ 	trace((/*{*/"}\n"));
+ 	return result;
+ }
+ 
+ 
+ int
+ glue_unlink(path)
+ 	char		*path;
+ {
+ 	proxy_ty	*pp;
+ 	int		result;
+ 
+ 	trace(("glue_unlink()\n{\n"/*}*/));
+ 	pp = proxy_find();
+ 	putc(command_unlink, pp->command);
+ 	put_string(pp->command, path);
+ 	end_of_command(pp);
+ 	result = get_int(pp->reply);
+ 	if (result)
+ 	{
+ 		errno = result;
+ 		result = -1;
+ 	}
+ 	trace(("return %d; /* errno = %d */\n", result, errno));
+ 	trace((/*{*/"}\n"));
+ 	return result;
+ }
+ 
+ 
+ int
+ glue_link(p1, p2)
+ 	char		*p1;
+ 	char		*p2;
+ {
+ 	proxy_ty	*pp;
+ 	int		result;
+ 
+ 	trace(("glue_link()\n{\n"/*}*/));
+ 	pp = proxy_find();
+ 	putc(command_link, pp->command);
+ 	put_string(pp->command, p1);
+ 	put_string(pp->command, p2);
+ 	end_of_command(pp);
+ 	result = get_int(pp->reply);
+ 	if (result)
+ 	{
+ 		errno = result;
+ 		result = -1;
+ 	}
+ 	trace(("return %d; /* errno = %d */\n", result, errno));
+ 	trace((/*{*/"}\n"));
+ 	return result;
+ }
+ 
+ 
+ int
+ glue_access(path, mode)
+ 	char		*path;
+ 	int		mode;
+ {
+ 	proxy_ty	*pp;
+ 	int		result;
+ 
+ 	trace(("glue_access()\n{\n"/*}*/));
+ 	pp = proxy_find();
+ 	putc(command_access, pp->command);
+ 	put_string(pp->command, path);
+ 	put_int(pp->command, mode);
+ 	end_of_command(pp);
+ 	result = get_int(pp->reply);
+ 	if (result)
+ 	{
+ 		errno = result;
+ 		result = -1;
+ 	}
+ 	trace(("return %d; /* errno = %d */\n", result, errno));
+ 	trace((/*{*/"}\n"));
+ 	return result;
+ }
+ 
+ 
+ char *
+ glue_getcwd(buf, max)
+ 	char		*buf;
+ 	int		max;
+ {
+ 	proxy_ty	*pp;
+ 	char		*s;
+ 	int		result;
+ 
+ 	/*
+ 	 * don't bother with the case where buf
+ 	 * is the NULL pointer, aegis never uses it.
+ 	 */
+ 	trace(("glue_getcwd()\n{\n"/*}*/));
+ 	assert(buf);
+ 	pp = proxy_find();
+ 	putc(command_getcwd, pp->command);
+ 	put_int(pp->command, max);
+ 	end_of_command(pp);
+ 	result = get_int(pp->reply);
+ 	if (result)
+ 	{
+ 		s = 0;
+ 		trace(("return NULL; /* errno = %d */\n", result));
+ 		errno = result;
+ 	}
+ 	else
+ 	{
+ 		s = get_string(pp->reply);
+ 		strcpy(buf, s);
+ 		s = buf;
+ 		trace(("return \"%s\";\n", s));
+ 	}
+ 	trace((/*{*/"}\n"));
+ 	return s;
+ }
+ 
+ 
+ int
+ glue_readlink(path, buf, max)
+ 	char		*path;
+ 	char		*buf;
+ 	int		max;
+ {
+ 	proxy_ty	*pp;
+ 	int		result;
+ 
+ 	trace(("glue_readlink()\n{\n"/*}*/));
+ 	pp = proxy_find();
+ 	putc(command_readlink, pp->command);
+ 	put_string(pp->command, path);
+ 	put_int(pp->command, max);
+ 	end_of_command(pp);
+ 	result = get_int(pp->reply);
+ 	if (result < 0)
+ 	{
+ 		errno = get_int(pp->reply);
+ 		result = -1;
+ 	}
+ 	else
+ 	{
+ 		get_binary(pp->reply, buf, result);
+ 		trace(("buf = \"%.*s\";\n", result, buf));
+ 	}
+ 	trace(("return %d; /* errno = %d */\n", result, errno));
+ 	trace((/*{*/"}\n"));
+ 	return result;
+ }
+ 
+ 
+ int
+ glue_utime(path, values)
+ 	char		*path;
+ 	struct utimbuf	*values;
+ {
+ 	proxy_ty	*pp;
+ 	int		result;
+ 
+ 	trace(("glue_utime()\n{\n"/*}*/));
+ 	pp = proxy_find();
+ 	putc(command_utime, pp->command);
+ 	put_string(pp->command, path);
+ 	put_binary(pp->command, values, sizeof(*values));
+ 	end_of_command(pp);
+ 	result = get_int(pp->reply);
+ 	if (result)
+ 	{
+ 		errno = result;
+ 		result = -1;
+ 	}
+ 	trace(("return %d; /* errno = %d */\n", result, errno));
+ 	trace((/*{*/"}\n"));
+ 	return result;
+ }
+ 
+ 
+ int
+ glue_copyfile(p1, p2)
+ 	char		*p1;
+ 	char		*p2;
+ {
+ 	proxy_ty	*pp;
+ 	int		result;
+ 
+ 	trace(("glue_copyfile()\n{\n"/*}*/));
+ 	pp = proxy_find();
+ 	putc(command_copyfile, pp->command);
+ 	put_string(pp->command, p1);
+ 	put_string(pp->command, p2);
+ 	end_of_command(pp);
+ 	result = get_int(pp->reply);
+ 	if (result)
+ 	{
+ 		errno = result;
+ 		result = -1;
+ 	}
+ 	trace(("return %d; /* errno = %d */\n", result, errno));
+ 	trace((/*{*/"}\n"));
+ 	return result;
+ }
+ 
+ 
+ typedef struct glue_file_ty glue_file_ty;
+ struct glue_file_ty
+ {
+ 	long		guard1;
+ 	char		*path;
+ 	int		fmode;
+ 	char		*buffer_end;
+ 	char		*buffer_pos;
+ 	int		fd;
+ 	int		errno;
+ 	int		pushback;
+ 	proxy_ty	*pp;
+ 	char		buffer[1 << 11]; /* fits within knl pipe buf */
+ 	long		guard2;
+ };
+ 
+ 
+ FILE *
+ glue_fopen(path, mode)
+ 	char		*path;
+ 	char		*mode;
+ {
+ 	glue_file_ty	*gfp;
+ 	proxy_ty	*pp;
+ 	int		fmode;
+ 	int		fd;
+ 
+ 	trace(("glue_fopen()\n{\n"/*}*/));
+ 	if (!strcmp(mode, "r"))
+ 		fmode = O_RDONLY;
+ 	else if (!strcmp(mode, "w"))
+ 		fmode = O_WRONLY | O_CREAT | O_TRUNC;
+ 	else
+ 	{
+ 		errno = EINVAL;
+ 		gfp = 0;
+ 		goto done;
+ 	}
+ 
+ 	pp = proxy_find();
+ 	putc(command_open, pp->command);
+ 	put_string(pp->command, path);
+ 	put_int(pp->command, fmode);
+ 	put_int(pp->command, 0666);
+ 	end_of_command(pp);
+ 	fd = get_int(pp->reply);
+ 	if (fd < 0)
+ 	{
+ 		errno = get_int(pp->reply);
+ 		gfp = 0;
+ 		goto done;
+ 	}
+ 
+ 	/*
+ 	 * build our file structure
+ 	 */
+ 	gfp = (glue_file_ty *)mem_alloc(sizeof(glue_file_ty));
+ 	gfp->pp = pp;
+ 	gfp->path = mem_copy_string(path);
+ 	gfp->fmode = fmode;
+ 	gfp->fd = fd;
+ 	gfp->guard1 = GUARD1;
+ 	gfp->guard2 = GUARD2;
+ 	if (gfp->fmode == O_RDONLY)
+ 	{
+ 		gfp->buffer_end = 0;
+ 		gfp->buffer_pos = 0;
+ 	}
+ 	else
+ 	{
+ 		gfp->buffer_pos = gfp->buffer;
+ 		gfp->buffer_end = gfp->buffer + sizeof(gfp->buffer);
+ 	}
+ 	gfp->errno = 0;
+ 	gfp->pushback = EOF;
+ 
+ 	/*
+ 	 * NOTE: this is veeerrry nasty.
+ 	 * The return value is not really a valid FILE,
+ 	 * but is only useful to the glue file functions.
+ 	 */
+ 	done:
+ 	trace(("return %08lX; /* errno = %d */\n", (long)gfp, errno));
+ 	trace((/*{*/"}\n"));
+ 	return (FILE *)gfp;
+ }
+ 
+ 
+ int
+ glue_fclose(fp)
+ 	FILE		*fp;
+ {
+ 	proxy_ty	*pp;
+ 	glue_file_ty	*gfp;
+ 	int		result;
+ 	int		result2;
+ 
+ 	/*
+ 	 * Leave the standard file streams alone.
+ 	 * There is a chance these will be seen here.
+ 	 */
+ 	if (fp == stdout || fp == stdin || fp == stderr)
+ 		return fclose(fp);
+ 
+ 	/*
+ 	 * flush the buffers
+ 	 */
+ 	trace(("glue_fclose()\n{\n"/*}*/));
+ 	result = glue_fflush(fp) ? errno : 0;
+ 
+ 	/*
+ 	 * locate the appropriate proxy
+ 	 */
+ 	gfp = (glue_file_ty *)fp;
+ 	assert(gfp->guard1 == GUARD1);
+ 	assert(gfp->guard2 == GUARD2);
+ 	pp = gfp->pp;
+ 
+ 	/*
+ 	 * tell the proxy to close
+ 	 */
+ 	putc(command_close, pp->command);
+ 	put_int(pp->command, gfp->fd);
+ 	end_of_command(pp);
+ 	result2 = get_int(pp->reply);
+ 	if (!result)
+ 		result = result2;
+ 
+ 	/*
+ 	 * Fclose always closes the file,
+ 	 * even when the implicit write fails.
+ 	 * Always dispose of our data.
+ 	 */
+ 	mem_free(gfp->path);
+ 	mem_free((char *)gfp);
+ 	
+ 	/*
+ 	 * set errno and get out of here
+ 	 */
+ 	if (result)
+ 	{
+ 		errno = result;
+ 		result = -1;
+ 	}
+ 	trace(("return %d; /* errno = %d */\n", result, errno));
+ 	trace((/*{*/"}\n"));
+ 	return result;
+ }
+ 
+ 
+ int
+ glue_fgetc(fp)
+ 	FILE		*fp;
+ {
+ 	proxy_ty	*pp;
+ 	glue_file_ty	*gfp;
+ 	int		result;
+ 	long		nbytes;
+ 
+ 	/*
+ 	 * Leave the standard file streams alone.
+ 	 * There is a chance these will be seen here.
+ 	 */
+ 	if (fp == stdout || fp == stdin || fp == stderr)
+ 		return getc(fp);
+ 
+ 	/*
+ 	 * locate the appropriate proxy
+ 	 */
+ #if 0
+ 	trace(("glue_fgetc()\n{\n"/*}*/));
+ #endif
+ 	gfp = (glue_file_ty *)fp;
+ 	assert(gfp->guard1 == GUARD1);
+ 	assert(gfp->guard2 == GUARD2);
+ 	pp = gfp->pp;
+ 
+ 	/*
+ 	 * complain if we are in an error state,
+ 	 * or they asked for something stupid
+ 	 */
+ 	if (gfp->errno)
+ 	{
+ 		errno = gfp->errno;
+ 		result = EOF;
+ 		goto done;
+ 	}
+ 	if (gfp->fmode != O_RDONLY)
+ 	{
+ 		gfp->errno = EINVAL;
+ 		errno = EINVAL;
+ 		result = EOF;
+ 		goto done;
+ 	}
+ 
+ 	/*
+ 	 * use pushback if there is anything in it
+ 	 */
+ 	if (gfp->pushback != EOF)
+ 	{
+ 		result = gfp->pushback;
+ 		gfp->pushback = EOF;
+ 		goto done;
+ 	}
+ 
+ 	/*
+ 	 * use the buffer if there is anything in it
+ 	 */
+ 	if (gfp->buffer_pos && gfp->buffer_pos < gfp->buffer_end)
+ 	{
+ 		result = (unsigned char)*gfp->buffer_pos++;
+ 		goto done;
+ 	}
+ 	gfp->buffer_pos = 0;
+ 	gfp->buffer_end = 0;
+ 
+ 	/*
+ 	 * tell the proxy to read another buffer-full
+ 	 */
+ 	pp = gfp->pp;
+ 	putc(command_read, pp->command);
+ 	put_int(pp->command, gfp->fd);
+ 	put_long(pp->command, (long)sizeof(gfp->buffer));
+ 	end_of_command(pp);
+ 	nbytes = get_long(pp->reply);
+ 	if (nbytes < 0)
+ 	{
+ 		gfp->errno = get_int(pp->reply);
+ 		errno = gfp->errno;
+ 		result = EOF;
+ 		goto done;
+ 	}
+ 	if (nbytes == 0)
+ 	{
+ 		errno = 0;
+ 		result = EOF;
+ 		goto done;
+ 	}
+ 	assert(nbytes <= sizeof(gfp->buffer));
+ 	get_binary(pp->reply, gfp->buffer, nbytes);
+ 	gfp->buffer_pos = gfp->buffer;
+ 	gfp->buffer_end = gfp->buffer + nbytes;
+ 	result = (unsigned char)*gfp->buffer_pos++;
+ 
+ 	/*
+ 	 * here for all exits
+ 	 */
+ 	done:
+ #if 0
+ 	trace(("return %d; /* errno = %d */\n", result, errno));
+ 	trace((/*{*/"}\n"));
+ #endif
+ 	return result;
+ }
+ 
+ 
+ int
+ glue_ungetc(c, fp)
+ 	int		c;
+ 	FILE		*fp;
+ {
+ 	glue_file_ty	*gfp;
+ 	int		result;
+ 
+ 	/*
+ 	 * Leave the standard file streams alone.
+ 	 * There is a chance these will be seen here.
+ 	 */
+ 	if (fp == stdout || fp == stdin || fp == stderr)
+ 		return ungetc(c, fp);
+ 
+ 	/*
+ 	 * make a pointer to our data
+ 	 */
+ 	trace(("glue_ungetc()\n{\n"/*}*/));
+ 	result = EOF;
+ 	gfp = (glue_file_ty *)fp;
+ 	assert(gfp->guard1 == GUARD1);
+ 	assert(gfp->guard2 == GUARD2);
+ 
+ 	/*
+ 	 * make sure not too many
+ 	 */
+ 	if (gfp->pushback != EOF || c == EOF)
+ 	{
+ 		gfp->errno = EINVAL;
+ 		errno = EINVAL;
+ 		gfp->pushback = EOF;
+ 		goto done;
+ 	}
+ 
+ 	/*
+ 	 * stash the returned char
+ 	 */
+ 	gfp->pushback = (unsigned char)c;
+ 	result = (unsigned char)c;
+ 
+ 	/*
+ 	 * here for all exits
+ 	 */
+ 	done:
+ 	trace(("return %d; /* errno = %d */\n", result, errno));
+ 	trace((/*{*/"}\n"));
+ 	return result;
+ }
+ 
+ 
+ int
+ glue_fputc(c, fp)
+ 	int		c;
+ 	FILE		*fp;
+ {
+ 	proxy_ty	*pp;
+ 	glue_file_ty	*gfp;
+ 	int		result;
+ 
+ 	/*
+ 	 * Leave the standard file streams alone.
+ 	 * There is a chance these will be seen here.
+ 	 */
+ 	if (fp == stdout || fp == stdin || fp == stderr)
+ 		return putc(c, fp);
+ 
+ 	/*
+ 	 * locate the appropriate proxy
+ 	 */
+ #if 0
+ 	trace(("glue_fputc()\n{\n"/*}*/));
+ #endif
+ 	result = EOF;
+ 	gfp = (glue_file_ty *)fp;
+ 	assert(gfp->guard1 == GUARD1);
+ 	assert(gfp->guard2 == GUARD2);
+ 	pp = gfp->pp;
+ 
+ 	/*
+ 	 * if the stream is in an error state,
+ 	 * or we were asked to do something stupid,
+ 	 * return the error
+ 	 */
+ 	if (gfp->errno)
+ 	{
+ 		errno = gfp->errno;
+ 		goto done;
+ 	}
+ 	if (gfp->fmode == O_RDONLY)
+ 	{
+ 		gfp->errno = EINVAL;
+ 		errno = EINVAL;
+ 		goto done;
+ 	}
+ 
+ 	/*
+ 	 * if there is no room in the buffer,
+ 	 * flush it to the proxy
+ 	 */
+ 	assert(gfp->buffer_pos);
+ 	if (gfp->buffer_pos >= gfp->buffer_end)
+ 	{
+ 		long	nbytes;
+ 		long	nbytes2;
+ 
+ 		putc(command_write, pp->command);
+ 		put_int(pp->command, gfp->fd);
+ 		nbytes = gfp->buffer_pos - gfp->buffer;
+ 		put_long(pp->command, nbytes);
+ 		put_binary(pp->command, gfp->buffer, nbytes);
+ 		end_of_command(pp);
+ 		nbytes2 = get_long(pp->reply);
+ 		if (nbytes2 < 0)
+ 		{
+ 			gfp->errno = get_int(pp->reply);
+ 			errno = gfp->errno;
+ 			goto done;
+ 		}
+ 		if (nbytes2 != nbytes)
+ 		{
+ 			gfp->errno = EIO;
+ 			errno = EIO;
+ 			goto done;
+ 		}
+ 		gfp->buffer_pos = gfp->buffer;
+ 		gfp->buffer_end = gfp->buffer + sizeof(gfp->buffer);
+ 	}
+ 
+ 	/*
+ 	 * stash the character
+ 	 */
+ 	*gfp->buffer_pos++ = c;
+ 	result = (unsigned char)c;
+ 
+ 	/*
+ 	 * here for all exits
+ 	 */
+ 	done:
+ #if 0
+ 	trace(("return %d; /* errno = %d */\n", result, errno));
+ 	trace((/*{*/"}\n"));
+ #endif
+ 	return result;
+ }
+ 
+ 
+ int
+ glue_ferror(fp)
+ 	FILE		*fp;
+ {
+ 	glue_file_ty	*gfp;
+ 
+ 	/*
+ 	 * Leave the standard file streams alone.
+ 	 * There is a chance these will be seen here.
+ 	 */
+ 	if (fp == stdout || fp == stdin || fp == stderr)
+ 		return ferror(fp);
+ 
+ 	/*
+ 	 * locate the appropriate proxy
+ 	 */
+ 	gfp = (glue_file_ty *)fp;
+ 	assert(gfp->guard1 == GUARD1);
+ 	assert(gfp->guard2 == GUARD2);
+ 
+ 	/*
+ 	 * set errno depending on
+ 	 * the error for this stream.
+ 	 */
+ 	if (gfp->errno)
+ 	{
+ 		errno = gfp->errno;
+ 		gfp->errno = 0;
+ 		return 1;
+ 	}
+ 	return 0;
+ }
+ 
+ 
+ int
+ glue_fflush(fp)
+ 	FILE		*fp;
+ {
+ 	glue_file_ty	*gfp;
+ 	proxy_ty	*pp;
+ 	int		result;
+ 
+ 	/*
+ 	 * Leave the standard file streams alone.
+ 	 * There is a chance these will be seen here.
+ 	 */
+ 	if (fp == stdout || fp == stdin || fp == stderr)
+ 		return fflush(fp);
+ 
+ 	/*
+ 	 * locate the appropriate proxy
+ 	 */
+ 	trace(("glue_fflush()\n{\n"/*}*/));
+ 	result = EOF;
+ 	gfp = (glue_file_ty *)fp;
+ 	assert(gfp->guard1 == GUARD1);
+ 	assert(gfp->guard2 == GUARD2);
+ 	pp = gfp->pp;
+ 
+ 	/*
+ 	 * if the stream is in an error state,
+ 	 * don't do anything
+ 	 */
+ 	if (gfp->errno)
+ 	{
+ 		errno = gfp->errno;
+ 		goto done;
+ 	}
+ 	if (gfp->fmode == O_RDONLY)
+ 	{
+ 		gfp->errno = EINVAL;
+ 		errno = EINVAL;
+ 		goto done;
+ 	}
+ 
+ 	/*
+ 	 * if there is anything in the buffer,
+ 	 * send it to the proxy
+ 	 */
+ 	if (gfp->buffer_pos && gfp->buffer_pos > gfp->buffer)
+ 	{
+ 		long	nbytes;
+ 		long	nbytes2;
+ 
+ 		putc(command_write, pp->command);
+ 		put_int(pp->command, gfp->fd);
+ 		nbytes = gfp->buffer_pos - gfp->buffer;
+ 		put_long(pp->command, nbytes);
+ 		put_binary(pp->command, gfp->buffer, nbytes);
+ 		end_of_command(pp);
+ 		nbytes2 = get_long(pp->reply);
+ 		if (nbytes2 < 0)
+ 		{
+ 			gfp->errno = get_int(pp->reply);
+ 			errno = gfp->errno;
+ 			goto done;
+ 		}
+ 		if (nbytes2 != nbytes)
+ 		{
+ 			gfp->errno = EIO;
+ 			errno = EIO;
+ 			goto done;
+ 		}
+ 		gfp->buffer_pos = gfp->buffer;
+ 		gfp->buffer_end = gfp->buffer + sizeof(gfp->buffer);
+ 	}
+ 	result = 0;
+ 
+ 	/*
+ 	 * here for all exits
+ 	 */
+ 	done:
+ 	trace(("return %d; /* errno = %d */\n", result, errno));
+ 	trace((/*{*/"}\n"));
+ 	return result;
+ }
+ 
+ 
+ int
+ glue_open(path, mode, perm)
+ 	char		*path;
+ 	int		mode;
+ 	int		perm;
+ {
+ 	proxy_ty	*pp;
+ 	int		result;
+ 
+ 	trace(("glue_open()\n{\n"/*}*/));
+ 	pp = proxy_find();
+ 	putc(command_open, pp->command);
+ 	put_string(pp->command, path);
+ 	put_int(pp->command, mode);
+ 	put_int(pp->command, perm);
+ 	end_of_command(pp);
+ 	result = get_int(pp->reply);
+ 	if (result < 0)
+ 		errno = get_int(pp->reply);
+ 	trace(("return %d; /* errno = %d */\n", result, errno));
+ 	trace((/*{*/"}\n"));
+ 	return result;
+ }
+ 
+ 
+ int
+ glue_creat(path, mode)
+ 	char		*path;
+ 	int		mode;
+ {
+ 	proxy_ty	*pp;
+ 	int		result;
+ 
+ 	trace(("glue_creat()\n{\n"/*}*/));
+ 	pp = proxy_find();
+ 	putc(command_creat, pp->command);
+ 	put_string(pp->command, path);
+ 	put_int(pp->command, mode);
+ 	end_of_command(pp);
+ 	result = get_int(pp->reply);
+ 	if (result < 0)
+ 		errno = get_int(pp->reply);
+ 	trace(("return %d; /* errno = %d */\n", result, errno));
+ 	trace((/*{*/"}\n"));
+ 	return result;
+ }
+ 
+ 
+ int
+ glue_close(fd)
+ 	int		fd;
+ {
+ 	proxy_ty	*pp;
+ 	int		result;
+ 
+ 	trace(("glue_close()\n{\n"/*}*/));
+ 	pp = proxy_find();
+ 	putc(command_close, pp->command);
+ 	put_int(pp->command, fd);
+ 	end_of_command(pp);
+ 	result = get_int(pp->reply);
+ 	if (result)
+ 	{
+ 		errno = result;
+ 		result = -1;
+ 	}
+ 	trace(("return %d; /* errno = %d */\n", result, errno));
+ 	trace((/*{*/"}\n"));
+ 	return result;
+ }
+ 
+ 
+ int
+ glue_write(fd, buf, len)
+ 	int		fd;
+ 	char		*buf;
+ 	long		len;
+ {
+ 	proxy_ty	*pp;
+ 	int		result;
+ 
+ 	trace(("glue_write()\n{\n"/*}*/));
+ 	pp = proxy_find();
+ 	putc(command_write, pp->command);
+ 	put_int(pp->command, fd);
+ 	put_long(pp->command, len);
+ 	put_binary(pp->command, buf, len);
+ 	end_of_command(pp);
+ 	result = get_int(pp->reply);
+ 	if (result)
+ 	{
+ 		errno = result;
+ 		result = -1;
+ 	}
+ 	trace(("return %d; /* errno = %d */\n", result, errno));
+ 	trace((/*{*/"}\n"));
+ 	return result;
+ }
+ 
+ 
+ int
+ glue_fcntl(fd, cmd, data)
+ 	int		fd;
+ 	int		cmd;
+ 	struct flock	*data;
+ {
+ 	proxy_ty	*pp;
+ 	int		result;
+ 
+ 	trace(("glue_fcntl()\n{\n"/*}*/));
+ 	assert(cmd == F_SETLKW || cmd == F_SETLK || cmd == F_UNLCK);
+ 	pp = proxy_find();
+ 	putc(command_fcntl, pp->command);
+ 	put_int(pp->command, fd);
+ 	put_int(pp->command, cmd);
+ 	put_binary(pp->command, data, sizeof(*data));
+ 	end_of_command(pp);
+ 	result = get_int(pp->reply);
+ 	get_binary(pp->reply, data, sizeof(*data));
+ 	if (result)
+ 	{
+ 		errno = result;
+ 		result = -1;
+ 	}
+ 	trace(("return %d; /* errno = %d */\n", result, errno));
+ 	trace((/*{*/"}\n"));
+ 	return result;
+ }
+ 
+ 
+ int
+ glue_read_whole_dir(path, data_p, data_len_p)
+ 	char		*path;
+ 	char		**data_p;
+ 	long		*data_len_p;
+ {
+ 	static char	*data;
+ 	static long	data_max;
+ 	long		data_len;
+ 
+ 	trace(("glue_read_whole_dir(path = \"%s\")\n{\n"/*}*/, path));
+ 	pp = proxy_find();
+ 	putc(command_read_whole_dir, pp->command);
+ 	put_string(pp->command, path);
+ 	end_of_command(pp);
+ 	result = get_int(pp->reply);
+ 	if (result)
+ 	{
+ 		errno = result;
+ 		result = -1;
+ 	}
+ 	else
+ 	{
+ 		data_len = get_long(pp->reply);
+ 		if (data_len > data_max)
+ 		{
+ 			data_max = data_len;
+ 			if (!data)
+ 				data = mem_alloc(data_max);
+ 			else
+ 				mem_change_size(&data, data_max);
+ 		}
+ 		get_binary(pp->reply, data, data_len);
+ 		*data_len_p = data_len;
+ 		*data_p = data;
+ 	}
+ 	trace(("return %d; /* errno = %d */\n", result, errno));
+ 	trace((/*{*/"}\n"));
+ 	return result;
+ }
+ 
+ 
+ #endif /* CONF_NO_seteuid */
+ 
+ 
+ /*
+  * NAME
+  *	copyfile - copy a file
+  *
+  * SYNOPSIS
+  *	int copyfile(char *src, char *dst);
+  *
+  * DESCRIPTION
+  *	The copyfile function complements the link and rename functions.
+  *
+  * ARGUMENTS
+  *	src	- pathname of source file
+  *	dst	- pathname of destination file
+  *
+  * RETURNS
+  *	0	on success
+  *	-1	on error, setting errno appropriately
+  */
+ 
+ int
+ copyfile(src, dst)
+ 	char	*src;
+ 	char	*dst;
+ {
+ 	int	src_fd;
+ 	int	dst_fd;
+ 	char	*buffer;
+ 	long	max;
+ 	long	nbytes;
+ 	long	nbytes2;
+ 	int	err;
+ 	int	result;
+ 
+ 	trace(("copyfile(\"%s\", \"%s\")\n{\n"/*}*/, src, dst));
+ 	result = -1;
+ 	src_fd = open(src, O_RDONLY, 0666);
+ 	if (src_fd < 0)
+ 		goto done;
+ 	dst_fd = open(dst, O_WRONLY | O_CREAT | O_TRUNC, 0666);
+ 	if (dst_fd < 0)
+ 	{
+ 		err = errno;
+ 		close(src_fd);
+ 		errno = err;
+ 		goto done;
+ 	}
+ 
+ 	max = 1L << 13;
+ 	errno = 0;
+ 	buffer = malloc(max);
+ 	if (!buffer)
+ 	{
+ 		err = errno ? errno : ENOMEM;
+ 		close(dst_fd);
+ 		close(src_fd);
+ 		errno = err;
+ 		goto done;
+ 	}
+ 
+ 	for (;;)
+ 	{
+ 		nbytes = read(src_fd, buffer, max);
+ 		if (nbytes < 0)
+ 		{
+ 			err = errno;
+ 			close(src_fd);
+ 			close(dst_fd);
+ 			free(buffer);
+ 			errno = err;
+ 			goto done;
+ 		}
+ 		if (nbytes == 0)
+ 			break;
+ 		
+ 		nbytes2 = write(dst_fd, buffer, nbytes);
+ 		if (nbytes2 < 0)
+ 		{
+ 			err = errno;
+ 			close(src_fd);
+ 			close(dst_fd);
+ 			free(buffer);
+ 			errno = err;
+ 			goto done;
+ 		}
+ 		if (nbytes2 != nbytes)
+ 		{
+ 			close(src_fd);
+ 			close(dst_fd);
+ 			free(buffer);
+ 			errno = EIO; /* weird device, probably */
+ 			goto done;
+ 		}
+ 	}
+ 	free(buffer);
+ 	if (close(src_fd))
+ 	{
+ 		err = errno;
+ 		close(dst_fd);
+ 		errno = err;
+ 		goto done;
+ 	}
+ 	result = close(dst_fd);
+ 
+ 	/*
+ 	 * here for all exits
+ 	 */
+ 	done:
+ 	trace(("return %d; /* errno = %d */\n", result, errno));
+ 	trace((/*{*/"}\n"));
+ 	return result;
+ }
+ 
+ 
+ /*
+  * NAME
+  *	catfile - copy a file
+  *
+  * SYNOPSIS
+  *	int catfile(char *path);
+  *
+  * DESCRIPTION
+  *	The catfile function is used to print the contents of
+  *	a file on the standard output.
+  *
+  * ARGUMENTS
+  *	path	- pathname of source file
+  *
+  * RETURNS
+  *	0	on success
+  *	-1	on error, setting errno appropriately
+  */
+ 
+ int
+ catfile(path)
+ 	char	*path;
+ {
+ 	int	fd;
+ 	char	*buffer;
+ 	long	max;
+ 	long	nbytes;
+ 	long	nbytes2;
+ 	int	err;
+ 	int	result;
+ 
+ 	trace(("catfile(\"%s\")\n{\n"/*}*/, path));
+ 	result = -1;
+ 	fd = open(path, O_RDONLY, 0666);
+ 	if (fd < 0)
+ 		goto done;
+ 
+ 	max = 1L << 13;
+ 	errno = 0;
+ 	buffer = malloc(max);
+ 	if (!buffer)
+ 	{
+ 		err = errno ? errno : ENOMEM;
+ 		close(fd);
+ 		errno = err;
+ 		goto done;
+ 	}
+ 
+ 	for (;;)
+ 	{
+ 		nbytes = read(fd, buffer, max);
+ 		if (nbytes < 0)
+ 		{
+ 			err = errno;
+ 			close(fd);
+ 			free(buffer);
+ 			errno = err;
+ 			goto done;
+ 		}
+ 		if (nbytes == 0)
+ 			break;
+ 		
+ 		nbytes2 = write(fileno(stdout), buffer, nbytes);
+ 		if (nbytes2 < 0)
+ 		{
+ 			err = errno;
+ 			close(fd);
+ 			free(buffer);
+ 			errno = err;
+ 			goto done;
+ 		}
+ 		if (nbytes2 != nbytes)
+ 		{
+ 			close(fd);
+ 			free(buffer);
+ 			errno = EIO; /* weird device, probably */
+ 			goto done;
+ 		}
+ 	}
+ 	free(buffer);
+ 	result = close(fd);
+ 
+ 	/*
+ 	 * here for all exits
+ 	 */
+ 	done:
+ 	trace(("return %d; /* errno = %d */\n", result, errno));
+ 	trace((/*{*/"}\n"));
+ 	return result;
+ }
+ 
+ 
+ int
+ read_whole_dir(path, data_p, data_len_p)
+ 	char		*path;
+ 	char		**data_p;
+ 	long		*data_len_p;
+ {
+ 	DIR		*dp;
+ 	struct dirent	*de;
+ 	static char	*data;
+ 	static size_t	data_len;
+ 	static size_t	data_max;
+ 	char		*np;
+ 	size_t		len;
+ 
+ 	errno = ENOMEM;
+ 	dp = opendir(path);
+ 	if (!dp)
+ 		return -1;
+ 	errno = 0;
+ 	if (!data)
+ 	{
+ 		data_max = 1000;
+ 		data = mem_alloc(data_max);
+ 	}
+ 	data_len = 0;
+ 	for (;;)
+ 	{
+ 		de = readdir(dp);
+ 		if (!de)
+ 			break;
+ 		np = de->d_name;
+ #ifdef CONF_pyramid_broken_readdir
+ 		np -= 2;
+ #endif
+ 		if (np[0] == '.' && (!np[1] || (np[1] == '.' && !np[2])))
+ 			continue;
+ 		len = strlen(np) + 1;
+ 		if (data_len + len > data_max)
+ 		{
+ 			data_max += 1000;
+ 			mem_change_size(&data, data_max);
+ 		}
+ 		memcpy(data + data_len, np, len);
+ 		data_len += len;
+ 	}
+ 	closedir(dp);
+ 	*data_p = data;
+ 	*data_len_p = data_len;
+ 	return 0;
+ }
Index: aegis/glue.h
***************
*** 0 ****
--- 1,109 ----
+ /*
+  *	aegis - project change supervisor
+  *	Copyright (C) 1993 Peter Miller.
+  *	All rights reserved.
+  *
+  *	This program is free software; you can redistribute it and/or modify
+  *	it under the terms of the GNU General Public License as published by
+  *	the Free Software Foundation; either version 2 of the License, or
+  *	(at your option) any later version.
+  *
+  *	This program is distributed in the hope that it will be useful,
+  *	but WITHOUT ANY WARRANTY; without even the implied warranty of
+  *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  *	GNU General Public License for more details.
+  *
+  *	You should have received a copy of the GNU General Public License
+  *	along with this program; if not, write to the Free Software
+  *	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+  *
+  * MANIFEST: interface definition for aegis/glue.c
+  */
+ 
+ #ifndef AEGIS_GLUE_H
+ #define AEGIS_GLUE_H
+ 
+ #include <stdio.h>
+ 
+ #include <main.h>
+ #include <conf.h>
+ 
+ struct stat;
+ struct utimbuf;
+ struct flock;
+ 
+ int copyfile _((char *src, char *dst));
+ int catfile _((char *path));
+ int read_whole_dir _((char *path, char **data, long *datalen));
+ 
+ #ifndef CONF_NO_seteuid
+ 
+ /*
+  * seteuid works
+  */
+ #define	glue_access	access
+ #define	glue_catfile	catfile
+ #define	glue_chmod	chmod
+ #define	glue_chown	chown
+ #define	glue_close	close
+ #define	glue_creat	creat
+ #define	glue_copyfile	copyfile
+ #define	glue_fclose	fclose
+ #define	glue_fcntl	fcntl
+ #define	glue_ferror	ferror
+ #define	glue_fflush	fflush
+ #define	glue_fgetc	getc
+ #define	glue_fopen	fopen
+ #define	glue_fputc	putc
+ #define	glue_getcwd	getcwd
+ #define	glue_link	link
+ #define	glue_lstat	lstat
+ #define	glue_mkdir	mkdir
+ #define	glue_open	open
+ #define	glue_readlink	readlink
+ #define	glue_read_whole_dir	read_whole_dir
+ #define	glue_rename	rename
+ #define	glue_rmdir	rmdir
+ #define	glue_stat	stat
+ #define	glue_ungetc	ungetc
+ #define	glue_unlink	unlink
+ #define	glue_utime	utime
+ #define	glue_write	write
+ 
+ #else
+ 
+ /*
+  * no seteuid call, or doesn't work correctly
+  */
+ int glue_access _((char *path, int mode));
+ int glue_catfile _((char *path));
+ int glue_chmod _((char *path, int mode));
+ int glue_chown _((char *path, int uid, int gid));
+ int glue_close _((int fd));
+ int glue_creat _((char *path, int mode));
+ int glue_copyfile _((char *src, char *dst));
+ int glue_fclose _((FILE *));
+ int glue_fcntl _((int fd, int cmd, struct flock *));
+ int glue_ferror _((FILE *));
+ int glue_fflush _((FILE *));
+ int glue_fgetc _((FILE *));
+ FILE *glue_fopen _((char *path, char *mode));
+ int glue_fputc _((int, FILE *));
+ char *glue_getcwd _((char *buf, int max));
+ int glue_link _((char *p1, char *p2));
+ int glue_lstat _((char *path, struct stat *st));
+ int glue_mkdir _((char *path, int mode));
+ int glue_open _((char *path, int mode, int perm));
+ int glue_readlink _((char *path, char *buf, int max));
+ int glue_read_whole_dir _((char *path, char **data, long *datalen));
+ int glue_rename _((char *p1, char *p2));
+ int glue_rmdir _((char *path));
+ int glue_stat _((char *path, struct stat *st));
+ int glue_ungetc _((int, FILE *));
+ int glue_unlink _((char *path));
+ int glue_utime _((char *path, struct utimbuf *));
+ int glue_write _((int fd, char *data, long len));
+ 
+ #endif /* seteuid alternatives */
+ 
+ #endif /* AEGIS_GLUE_H */
Index: aegis/gonzo.c
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 41,51 ****
  #include <ustate.h>
  #include <word.h>
  
! typedef struct gonzo_t gonzo_t;
! struct gonzo_t
  {
! 	string_t	*dir;
! 	string_t	*gstate_filename;
  	gstate		gstate_data;
  	int		is_a_new_file;
  	int		modified;
--- 41,51 ----
  #include <ustate.h>
  #include <word.h>
  
! typedef struct gonzo_ty gonzo_ty;
! struct gonzo_ty
  {
! 	string_ty	*dir;
! 	string_ty	*gstate_filename;
  	gstate		gstate_data;
  	int		is_a_new_file;
  	int		modified;
***************
*** 54,76 ****
  };
  
  static	size_t		ngonzos;
! static	gonzo_t		**gonzo;
  static	int		done_tail;
  
  
! static user_t *gonzo_user _((void));
  
! static user_t *
  gonzo_user()
  {
! 	static	user_t	*u;
  
  	if (!u)
  	{
! 		string_t	*s;
  
  		s = str_from_c(AEGIS_USER);
! 		u = user_symbolic((project_t *)0, s);
  		u->umask = 022;
  		str_free(s);
  	}
--- 54,76 ----
  };
  
  static	size_t		ngonzos;
! static	gonzo_ty	**gonzo;
  static	int		done_tail;
  
  
! static user_ty *gonzo_user _((void));
  
! static user_ty *
  gonzo_user()
  {
! 	static user_ty	*u;
  
  	if (!u)
  	{
! 		string_ty	*s;
  
  		s = str_from_c(AEGIS_USER);
! 		u = user_symbolic((project_ty *)0, s);
  		u->umask = 022;
  		str_free(s);
  	}
***************
*** 78,90 ****
  }
  
  
! static int is_temporary _((string_t *));
  
  static int
  is_temporary(s)
! 	string_t	*s;
  {
! 	return !strncmp(s->str_text, "/tmp/", 5);
  }
  
  
--- 78,97 ----
  }
  
  
! static int is_temporary _((string_ty *));
  
  static int
  is_temporary(s)
! 	string_ty	*s;
  {
! 	return
! 	(
! 		!strncmp(s->str_text, "/tmp/", 5)
! 	||
! 		!strncmp(s->str_text, "/usr/tmp/", 9)
! 	||
! 		!strncmp(s->str_text, "/var/tmp/", 9)
! 	);
  }
  
  
***************
*** 92,100 ****
  gonzo_library_append(s)
  	char		*s;
  {
! 	gonzo_t		*gp;
! 	string_t	*tmp;
! 	string_t	*dir;
  
  	/*
  	 * resolve the pathname
--- 99,107 ----
  gonzo_library_append(s)
  	char		*s;
  {
! 	gonzo_ty	*gp;
! 	string_ty	*tmp;
! 	string_ty	*dir;
  
  	/*
  	 * resolve the pathname
***************
*** 104,110 ****
  	assert(!done_tail);
  	tmp = str_from_c(s);
  	os_become_orig();
! 	dir = os_pathname(tmp);
  	os_become_undo();
  	str_free(tmp);
  
--- 111,117 ----
  	assert(!done_tail);
  	tmp = str_from_c(s);
  	os_become_orig();
! 	dir = os_pathname(tmp, 1);
  	os_become_undo();
  	str_free(tmp);
  
***************
*** 111,130 ****
  	/*
  	 * append the new entry to the end of the list
  	 */
! 	gp = (gonzo_t *)mem_alloc_clear(sizeof(gonzo_t));
  	gp->dir = dir;
  	gp->temporary = is_temporary(dir);
  	gp->gstate_filename = str_format("%S/state", gp->dir);
! 	*(gonzo_t **)enlarge(&ngonzos, (char **)&gonzo, sizeof(gonzo_t *)) = gp;
  	trace((/*{*/"}\n"));
  }
  
  
! static void lock_sync _((gonzo_t *));
  
  static void
  lock_sync(gp)
! 	gonzo_t		*gp;
  {
  	long		n;
  
--- 118,143 ----
  	/*
  	 * append the new entry to the end of the list
  	 */
! 	gp = (gonzo_ty *)mem_alloc_clear(sizeof(gonzo_ty));
  	gp->dir = dir;
  	gp->temporary = is_temporary(dir);
  	gp->gstate_filename = str_format("%S/state", gp->dir);
! 	*(gonzo_ty **)
! 	enlarge
! 	(
! 		&ngonzos,
! 		(char **)&gonzo, sizeof(gonzo_ty *)
! 	) =
! 		gp;
  	trace((/*{*/"}\n"));
  }
  
  
! static void lock_sync _((gonzo_ty *));
  
  static void
  lock_sync(gp)
! 	gonzo_ty	*gp;
  {
  	long		n;
  
***************
*** 145,155 ****
  
  
  
! static gstate gonzo_gstate_get _((gonzo_t *));
  
  static gstate
  gonzo_gstate_get(gp)
! 	gonzo_t		*gp;
  {
  	trace(("gonzo_gstate_get(gp = %08lX)\n{\n"/*}*/, gp));
  	lock_sync(gp);
--- 158,168 ----
  
  
  
! static gstate gonzo_gstate_get _((gonzo_ty *));
  
  static gstate
  gonzo_gstate_get(gp)
! 	gonzo_ty	*gp;
  {
  	trace(("gonzo_gstate_get(gp = %08lX)\n{\n"/*}*/, gp));
  	lock_sync(gp);
***************
*** 170,178 ****
  				gstate_read_file(gp->gstate_filename->str_text);
  		}
  		else
! 			gp->gstate_data = gstate_type.alloc();
  		if (!gp->gstate_data->where)
! 			gp->gstate_data->where = gstate_where_list_type.alloc();
  		gonzo_become_undo();
  	}
  	trace(("return %08lX;\n", gp->gstate_data));
--- 183,193 ----
  				gstate_read_file(gp->gstate_filename->str_text);
  		}
  		else
! 			gp->gstate_data = (gstate)gstate_type.alloc();
  		if (!gp->gstate_data->where)
! 			gp->gstate_data->where =
! 				(gstate_where_list)
! 				gstate_where_list_type.alloc();
  		gonzo_become_undo();
  	}
  	trace(("return %08lX;\n", gp->gstate_data));
***************
*** 186,192 ****
   *	construct_library_directory
   *
   * SYNOPSIS
!  *	void construct_library_directory(gonzo_t *gp);
   *
   * DESCRIPTION
   *	The construct_library_directory function is used to
--- 201,207 ----
   *	construct_library_directory
   *
   * SYNOPSIS
!  *	void construct_library_directory(gonzo_ty *gp);
   *
   * DESCRIPTION
   *	The construct_library_directory function is used to
***************
*** 214,229 ****
   *	foreign "root" users to the "unknown" user instead.
   */
  
! static void construct_library_directory _((gonzo_t *));
  
  static void
  construct_library_directory(gp)
! 	gonzo_t		*gp;
  {
  	int		exists;
! 	string_t	*above;
! 	string_t	*above2;
! 	string_t	*root;
  	int		mode;
  	
  	/*
--- 229,244 ----
   *	foreign "root" users to the "unknown" user instead.
   */
  
! static void construct_library_directory _((gonzo_ty *));
  
  static void
  construct_library_directory(gp)
! 	gonzo_ty	*gp;
  {
  	int		exists;
! 	string_ty	*above;
! 	string_ty	*above2;
! 	string_ty	*root;
  	int		mode;
  	
  	/*
***************
*** 285,298 ****
  }
  
  
! static void gonzo_gstate_write_sub _((gonzo_t *));
  
  static void
  gonzo_gstate_write_sub(gp)
! 	gonzo_t		*gp;
  {
! 	string_t	*filename_new;
! 	string_t	*filename_old;
  	static int	count;
  
  	if (!gp->modified)
--- 300,313 ----
  }
  
  
! static void gonzo_gstate_write_sub _((gonzo_ty *));
  
  static void
  gonzo_gstate_write_sub(gp)
! 	gonzo_ty	*gp;
  {
! 	string_ty	*filename_new;
! 	string_ty	*filename_old;
  	static int	count;
  
  	if (!gp->modified)
***************
*** 335,342 ****
  static void
  do_tail()
  {
! 	string_t	*s1;
! 	string_t	*s2;
  	char		*cp;
  	wlist		path;
  	size_t		j;
--- 350,357 ----
  static void
  do_tail()
  {
! 	string_ty	*s1;
! 	string_ty	*s2;
  	char		*cp;
  	wlist		path;
  	size_t		j;
***************
*** 393,405 ****
  }
  
  
! static gonzo_t *gonzo_nth _((size_t));
  
! static gonzo_t *
  gonzo_nth(j)
  	size_t		j;
  {
! 	gonzo_t		*result;
  
  	trace(("gonzo_nth(j = %ld)\n{\n"/*}*/, j));
  	do_tail();
--- 408,420 ----
  }
  
  
! static gonzo_ty *gonzo_nth _((size_t));
  
! static gonzo_ty *
  gonzo_nth(j)
  	size_t		j;
  {
! 	gonzo_ty	*result;
  
  	trace(("gonzo_nth(j = %ld)\n{\n"/*}*/, j));
  	do_tail();
***************
*** 417,423 ****
  gonzo_gstate_write()
  {
  	size_t		j;
! 	gonzo_t		*gp;
  
  	trace(("gonzo_gstate_write()\n{\n"/*}*/));
  	for (j = 0; ; ++j)
--- 432,438 ----
  gonzo_gstate_write()
  {
  	size_t		j;
! 	gonzo_ty	*gp;
  
  	trace(("gonzo_gstate_write()\n{\n"/*}*/));
  	for (j = 0; ; ++j)
***************
*** 431,446 ****
  }
  
  
! static string_t *gonzo_project_home_path_sub _((gonzo_t *, string_t *));
  
! static string_t *
  gonzo_project_home_path_sub(gp, name)
! 	gonzo_t		*gp;
! 	string_t	*name;
  {
  	gstate		gstate_data;
  	size_t		j;
! 	string_t	*result;
  
  	/*
  	 * find the project in the gstate
--- 446,461 ----
  }
  
  
! static string_ty *gonzo_project_home_path_sub _((gonzo_ty *, string_ty *));
  
! static string_ty *
  gonzo_project_home_path_sub(gp, name)
! 	gonzo_ty	*gp;
! 	string_ty	*name;
  {
  	gstate		gstate_data;
  	size_t		j;
! 	string_ty	*result;
  
  	/*
  	 * find the project in the gstate
***************
*** 466,479 ****
  }
  
  
! string_t *
  gonzo_project_home_path_from_name(name)
! 	string_t	*name;
  {
! 	gonzo_t		*gp;
  	size_t		j;
! 	string_t	*result;
! 	string_t	*s;
  
  	/*
  	 * find the project in the gstate list
--- 481,494 ----
  }
  
  
! string_ty *
  gonzo_project_home_path_from_name(name)
! 	string_ty	*name;
  {
! 	gonzo_ty	*gp;
  	size_t		j;
! 	string_ty	*result;
! 	string_ty	*s;
  
  	/*
  	 * find the project in the gstate list
***************
*** 504,510 ****
  {
  	size_t		n;
  	size_t		j;
! 	gonzo_t		*gp;
  	gstate		gstate_data;
  
  	trace(("gonzo_project_list(result = %08lX)\n{\n"/*}*/, result));
--- 519,525 ----
  {
  	size_t		n;
  	size_t		j;
! 	gonzo_ty	*gp;
  	gstate		gstate_data;
  
  	trace(("gonzo_project_list(result = %08lX)\n{\n"/*}*/, result));
***************
*** 539,545 ****
  
  void
  gonzo_project_list_user(uname, result)
! 	string_t	*uname;
  	wlist		*result;
  {
  	size_t		n;
--- 554,560 ----
  
  void
  gonzo_project_list_user(uname, result)
! 	string_ty	*uname;
  	wlist		*result;
  {
  	size_t		n;
***************
*** 550,558 ****
  	wl_zero(result);
  	for (n = 0; ; ++n)
  	{
! 		string_t	*ustate_path;
  		ustate		ustate_data;
! 		gonzo_t		*gp;
  
  		gp = gonzo_nth(n);
  		if (!gp)
--- 565,573 ----
  	wl_zero(result);
  	for (n = 0; ; ++n)
  	{
! 		string_ty	*ustate_path;
  		ustate		ustate_data;
! 		gonzo_ty	*gp;
  
  		gp = gonzo_nth(n);
  		if (!gp)
***************
*** 573,579 ****
  		ustate_data = ustate_read_file(ustate_path->str_text);
  		gonzo_become_undo();
  		if (!ustate_data->own)
! 			ustate_data->own = ustate_own_type.alloc();
  		str_free(ustate_path);
  
  		/*
--- 588,596 ----
  		ustate_data = ustate_read_file(ustate_path->str_text);
  		gonzo_become_undo();
  		if (!ustate_data->own)
! 			ustate_data->own =
! 				(ustate_own_list)
! 				ustate_own_list_type.alloc();
  		str_free(ustate_path);
  
  		/*
***************
*** 598,609 ****
  
  void
  gonzo_project_add(pp)
! 	project_t	*pp;
  {
  	gstate_where	*addr_p;
  	gstate_where	addr;
! 	gonzo_t		*gp;
! 	type_t		*type_p;
  
  	trace(("gonzo_project_add(pp = %08lX)\n{\n"/*}*/, pp));
  	gp = gonzo_nth(0);
--- 615,626 ----
  
  void
  gonzo_project_add(pp)
! 	project_ty	*pp;
  {
  	gstate_where	*addr_p;
  	gstate_where	addr;
! 	gonzo_ty	*gp;
! 	type_ty		*type_p;
  
  	trace(("gonzo_project_add(pp = %08lX)\n{\n"/*}*/, pp));
  	gp = gonzo_nth(0);
***************
*** 613,619 ****
  		&type_p,
  		(void **)&addr_p
  	);
! 	addr = gstate_where_type.alloc();
  	*addr_p = addr;
  	trace_pointer(addr);
  	addr->project_name = str_copy(project_name_get(pp));
--- 630,636 ----
  		&type_p,
  		(void **)&addr_p
  	);
! 	addr = (gstate_where)gstate_where_type.alloc();
  	*addr_p = addr;
  	trace_pointer(addr);
  	addr->project_name = str_copy(project_name_get(pp));
***************
*** 623,629 ****
--- 640,720 ----
  }
  
  
+ static int gonzo_project_delete_sub _((gonzo_ty *, project_ty *));
+ 
+ static int 
+ gonzo_project_delete_sub(gp, pp)
+ 	gonzo_ty	*gp;
+ 	project_ty	*pp;
+ {
+ 	gstate		gstate_data;
+ 	size_t		j;
+ 	int		result;
+ 
+ 	/*
+ 	 * find the project in the gstate
+ 	 */
+ 	trace(("gonzo_project_delete_sub(gp = %08lX, pp = %08lX)\n{\n"/*}*/,
+ 		gp, pp));
+ 	gstate_data = gonzo_gstate_get(gp);
+ 	assert(gstate_data->where);
+ 	result = 0;
+ 	for (j = 0; j < gstate_data->where->length; ++j)
+ 	{
+ 		gstate_where	addr;
+ 		long		k;
+ 
+ 		addr = gstate_data->where->list[j];
+ 		if (!str_equal(addr->project_name, project_name_get(pp)))
+ 			continue;
+ 
+ 		/*
+ 		 * delete the item from the list
+ 		 */
+ 		for (k = j + 1; k < gstate_data->where->length; ++k)
+ 			gstate_data->where->list[k - 1] =
+ 				gstate_data->where->list[k];
+ 		gstate_data->where->length--;
+ 
+ 		/*
+ 		 * free the item
+ 		 */
+ 		gstate_where_type.free(addr);
+ 
+ 		/*
+ 		 * mark this gstate file as modified
+ 		 */
+ 		gp->modified = 1;
+ 		result = 1;
+ 		break;
+ 	}
+ 	trace(("return %d;\n", result));
+ 	trace((/*{*/"}\n"));
+ 	return result;
+ }
+ 
+ 
  void
+ gonzo_project_delete(pp)
+ 	project_ty	*pp;
+ {
+ 	gonzo_ty	*gp;
+ 	long		j;
+ 
+ 	trace(("gonzo_project_delete(pp = %08lX)\n{\n"/*}*/, pp));
+ 	for (j = 0; ; ++j)
+ 	{
+ 		gp = gonzo_nth(j);
+ 		if (!gp)
+ 			break;
+ 		if (gonzo_project_delete_sub(gp, pp))
+ 			break;
+ 	}
+ 	trace((/*{*/"}\n"));
+ }
+ 
+ 
+ void
  gonzo_gstate_lock_prepare_new()
  {
  	trace(("gonzo_gstate_lock_prepare_new()\n{\n"/*}*/));
***************
*** 632,642 ****
  }
  
  
! string_t *
  gonzo_lockpath_get()
  {
! 	static string_t *path;
! 	gonzo_t		*gp;
  
  	trace(("gonzo_lockpath_get()\n{\n"/*}*/));
  	if (!path)
--- 723,733 ----
  }
  
  
! string_ty *
  gonzo_lockpath_get()
  {
! 	static string_ty *path;
! 	gonzo_ty	*gp;
  
  	trace(("gonzo_lockpath_get()\n{\n"/*}*/));
  	if (!path)
***************
*** 652,663 ****
  }
  
  
! static int gonzo_ustate_path_sub _((gonzo_t *, string_t *));
  
  static int
  gonzo_ustate_path_sub(gp, project_name)
! 	gonzo_t		*gp;
! 	string_t	*project_name;
  {
  	gstate		gstate_data;
  	size_t		j;
--- 743,754 ----
  }
  
  
! static int gonzo_ustate_path_sub _((gonzo_ty *, string_ty *));
  
  static int
  gonzo_ustate_path_sub(gp, project_name)
! 	gonzo_ty	*gp;
! 	string_ty	*project_name;
  {
  	gstate		gstate_data;
  	size_t		j;
***************
*** 687,701 ****
  }
  
  
! string_t *
  gonzo_ustate_path(project_name, user_name)
! 	string_t	*project_name;
! 	string_t	*user_name;
  {
! 	gonzo_t		*gp;
  	size_t		j;
! 	string_t	*dir;
! 	string_t	*result;
  
  	/*
  	 * find the project in the gstate list
--- 778,792 ----
  }
  
  
! string_ty *
  gonzo_ustate_path(project_name, user_name)
! 	string_ty	*project_name;
! 	string_ty	*user_name;
  {
! 	gonzo_ty	*gp;
  	size_t		j;
! 	string_ty	*dir;
! 	string_ty	*result;
  
  	/*
  	 * find the project in the gstate list
Index: aegis/gonzo.h
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 27,47 ****
  #include <gstate.h>
  
  struct wlist;
! struct project_t;
  
  void gonzo_gstate_write _((void));
  
  void gonzo_library_append _((char *path));
  
! struct string_t *gonzo_project_home_path_from_name _((struct string_t *));
  void gonzo_project_list _((struct wlist *result));
! void gonzo_project_list_user _((string_t *, struct wlist *result));
! void gonzo_project_add _((struct project_t *));
  void gonzo_gstate_write _((void));
  void gonzo_gstate_lock_prepare_new _((void));
  
! string_t *gonzo_lockpath_get _((void));
! string_t *gonzo_ustate_path _((string_t *project_name, string_t *user_name));
  
  void gonzo_become _((void));
  void gonzo_become_undo _((void));
--- 27,48 ----
  #include <gstate.h>
  
  struct wlist;
! struct project_ty;
  
  void gonzo_gstate_write _((void));
  
  void gonzo_library_append _((char *path));
  
! struct string_ty *gonzo_project_home_path_from_name _((struct string_ty *));
  void gonzo_project_list _((struct wlist *result));
! void gonzo_project_list_user _((string_ty *, struct wlist *result));
! void gonzo_project_add _((struct project_ty *));
! void gonzo_project_delete _((struct project_ty *));
  void gonzo_gstate_write _((void));
  void gonzo_gstate_lock_prepare_new _((void));
  
! string_ty *gonzo_lockpath_get _((void));
! string_ty *gonzo_ustate_path _((string_ty *project_name, string_ty *user_name));
  
  void gonzo_become _((void));
  void gonzo_become_undo _((void));
Index: aegis/gram.h
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
Index: aegis/gram.y
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 37,44 ****
  
  %union
  {
! 	string_t *lv_string;
! 	long	lv_integer;
  }
  
  %type <lv_string> NAME STRING
--- 37,44 ----
  
  %union
  {
! 	string_ty	*lv_string;
! 	long		lv_integer;
  }
  
  %type <lv_string> NAME STRING
Index: aegis/gstate.def
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
Index: aegis/help.c
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 39,45 ****
  
  static char *cr[] =
  {
! 	"%s version %v, Copyright (c) 1991-1993 Peter Miller.",
  	"All rights reserved.",
  	"",
  	"The %s program comes with ABSOLUTELY NO WARRANTY;",
--- 39,46 ----
  
  static char *cr[] =
  {
! 	"%s version %v",
! 	"Copyright (C) 1990, 1991, 1992, 1993 Peter Miller.",
  	"All rights reserved.",
  	"",
  	"The %s program comes with ABSOLUTELY NO WARRANTY;",
***************
*** 51,58 ****
  
  static char *au[] =
  {
! 	"Peter Miller\tUUCP\tuunet!munnari!bmr.gov.au!pmiller",
! 	"/\\/\\*\t\tCSNET\tpmiller@bmr.gov.au",
  };
  
  
--- 52,59 ----
  
  static char *au[] =
  {
! 	"Peter Miller   UUCP     uunet!munnari!bmr.gov.au!pmiller",
! 	"/\\/\\*          Internet pmiller@bmr.gov.au",
  };
  
  
Index: aegis/help.h
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
Index: aegis/indent.c
***************
*** 0 ****
--- 1,269 ----
+ /*
+  *	aegis - project change supervisor
+  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
+  *	All rights reserved.
+  *
+  *	This program is free software; you can redistribute it and/or modify
+  *	it under the terms of the GNU General Public License as published by
+  *	the Free Software Foundation; either version 2 of the License, or
+  *	(at your option) any later version.
+  *
+  *	This program is distributed in the hope that it will be useful,
+  *	but WITHOUT ANY WARRANTY; without even the implied warranty of
+  *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  *	GNU General Public License for more details.
+  *
+  *	You should have received a copy of the GNU General Public License
+  *	along with this program; if not, write to the Free Software
+  *	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+  *
+  * MANIFEST: functions to automatically indent output
+  */
+ 
+ #include <stdio.h>
+ #include <errno.h>
+ 
+ #include <error.h>
+ #include <glue.h>
+ #include <indent.h>
+ #include <s-v-arg.h>
+ #include <trace.h>
+ 
+ 
+ #define INDENT 8
+ 
+ static	FILE	*fp;
+ static	char	*fn;
+ static int	depth;
+ static int	in_col;
+ static int	out_col;
+ static	int	continuation_line;
+ 
+ 
+ /*
+  * Function Name:
+  *	indent_more
+  *
+  * Description:
+  *	The indent_more function is used to increase the indenting
+  *	beyond the automatically calculated indent.
+  *
+  * Preconditions:
+  *	There must be a matching indent_less call.
+  *
+  * validataion:
+  *	none
+  *
+  * Passed:
+  *	nothing
+  *
+  * Returns:
+  *	nothing
+  */
+ 
+ void
+ indent_more()
+ {
+ 	++depth;
+ }
+ 
+ 
+ /*
+  * Function Name:
+  *	indent_less
+  *
+  * Description:
+  *	The indent_less function is used to decrease the indenting
+  *	to less than the automatically calculated indent.
+  *
+  * Preconditions:
+  *	There must be a matching indent_more call.
+  *
+  * validataion:
+  *	none
+  *
+  * Passed:
+  *	nothing
+  *
+  * Returns:
+  *	nothing
+  */
+ 
+ void
+ indent_less()
+ {
+ 	--depth;
+ }
+ 
+ 
+ /*
+  * Function Name:
+  *	indent_putchar
+  *
+  * Description:
+  *	The indent_putchar function is used to emity characters.
+  *	It keeps track of (){}[] pairs and indents between them.
+  *	Leading whitespace is suppressed and replaced with its own
+  *	idea of indenting.
+  *
+  * Preconditions:
+  *	none
+  *
+  * validation:
+  *	none
+  *
+  * Passed:
+  *	'c' the character to emit.
+  */
+ 
+ void
+ indent_putchar(c)
+ 	char	c;
+ {
+ 	assert(fp);
+ 	switch (c)
+ 	{
+ 	case '\n':
+ 		glue_fputc('\n', fp);
+ #ifdef DEBUG
+ 		glue_fflush(fp);
+ #endif
+ 		in_col = 0;
+ 		out_col = 0;
+ 		if (continuation_line == 1)
+ 			continuation_line = 2;
+ 		else
+ 			continuation_line = 0;
+ 		break;
+ 
+ 	case ' ':
+ 		if (out_col)
+ 			++in_col;
+ 		break;
+ 
+ 	case '\t':
+ 		if (out_col)
+ 			in_col = (in_col / INDENT + 1) * INDENT;
+ 		break;
+ 
+ 	case '\1':
+ 		if (!out_col)
+ 			break;
+ 		if (in_col >= INDENT * (depth + 2))
+ 			++in_col;
+ 		else
+ 			in_col = INDENT * (depth + 2);
+ 		break;
+ 
+ 	case /*{*/'}':
+ 	case /*(*/')':
+ 	case /*[*/']':
+ 		--depth;
+ 		/* fall through */
+ 
+ 	default:
+ 		if (!out_col && c != '#' && continuation_line != 2)
+ 			in_col += INDENT * depth;
+ 		while (((out_col + 8) & -8) <= in_col && out_col + 1 < in_col)
+ 		{
+ 			glue_fputc('\t', fp);
+ 			out_col = (out_col + 8) & -8;
+ 		}
+ 		while (out_col < in_col)
+ 		{
+ 			glue_fputc(' ', fp);
+ 			++out_col;
+ 		}
+ 		if (c == '{'/*}*/ || c == '('/*)*/ || c == '['/*]*/)
+ 			++depth;
+ 		glue_fputc(c, fp);
+ 		in_col++;
+ 		out_col = in_col;
+ 		continuation_line = (c == '\\');
+ 		break;
+ 	}
+ 	if (glue_ferror(fp))
+ 		nfatal("write \"%s\"", fn);
+ }
+ 
+ 
+ /*
+  * Function Name:
+  *	indent_printf
+  *
+  * Description:
+  *	As putchar is to indent_putchasr, printf is to indent_printf.
+  *
+  * Preconditions:
+  *	none
+  *
+  * Validation:
+  *	none
+  *
+  * Passed:
+  *	's' format string
+  *	... and optional arguments
+  *
+  * Returns:
+  *	nothing
+  */
+ 
+ /*VARARGS1*/
+ void
+ indent_printf(s sva_last)
+ 	char		*s;
+ 	sva_last_decl
+ {
+ 	va_list		ap;
+ 	char		buffer[2000];
+ 
+ 	sva_init(ap, s);
+ 	vsprintf(buffer, s, ap);
+ 	va_end(ap);
+ 	for (s = buffer; *s; ++s)
+ 		indent_putchar(*s);
+ }
+ 
+ 
+ void
+ indent_open(s)
+ 	char	*s;
+ {
+ 	trace(("indent_open(s = %08lX)\n{\n"/*}*/, s));
+ 	if (!s)
+ 	{
+ 		fp = stdout;
+ 		s = "(stdout)";
+ 	}
+ 	else
+ 	{
+ 		trace_string(s);
+ 		fp = glue_fopen(s, "w");
+ 		if (!fp)
+ 			nfatal("open \"%s\"", s);
+ 	}
+ 	trace_pointer(fp);
+ 	fn = s;
+ 	depth = 0;
+ 	in_col = 0;
+ 	out_col = 0;
+ 	continuation_line = 0;
+ 	trace((/*{*/"}\n"));
+ }
+ 
+ 
+ void
+ indent_close()
+ {
+ 	trace(("indent_close()\n{\n"/*}*/));
+ 	trace_pointer(fp);
+ 	if (out_col)
+ 		indent_putchar('\n');
+ 	if (glue_fflush(fp))
+ 		nfatal("write \"%s\"", fn);
+ 	if (fp != stdout && glue_fclose(fp))
+ 		nfatal("close \"%s\"", fn);
+ 	fp = 0;
+ 	fn = 0;
+ 	trace((/*{*/"}\n"));
+ }
Index: aegis/indent.h
***************
*** 0 ****
--- 1,35 ----
+ /*
+  *	aegis - project change supervisor
+  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
+  *	All rights reserved.
+  *
+  *	This program is free software; you can redistribute it and/or modify
+  *	it under the terms of the GNU General Public License as published by
+  *	the Free Software Foundation; either version 2 of the License, or
+  *	(at your option) any later version.
+  *
+  *	This program is distributed in the hope that it will be useful,
+  *	but WITHOUT ANY WARRANTY; without even the implied warranty of
+  *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  *	GNU General Public License for more details.
+  *
+  *	You should have received a copy of the GNU General Public License
+  *	along with this program; if not, write to the Free Software
+  *	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+  *
+  * MANIFEST: interface definition for aegis/indent.c
+  */
+ 
+ #ifndef INDENT_H
+ #define INDENT_H
+ 
+ #include <main.h>
+ 
+ void indent_close _((void));
+ void indent_less _((void));
+ void indent_more _((void));
+ void indent_open _((char *));
+ void indent_printf _((char *, ...));
+ void indent_putchar _((int));
+ 
+ #endif /* INDENT_H */
Index: aegis/integra1.c
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 86,99 ****
  "",
  "	-Project <name>",
  "		This option may be used to select the project of",
! "		interest.  When no -Project option is specified, if",
! "		the user is only working on changes within a single",
! "		project, the project name defaults to that project;",
! "		if the user is currently working on changes to more",
! "		than one project, or is not working on changes to",
! "		any project, the user's $HOME/.%src file is",
! "		examined for a default project field (see aeuconf(5)",
! "		for more information).",
  "",
  "	-TERse",
  "		This option may be used to cause listings to",
--- 86,99 ----
  "",
  "	-Project <name>",
  "		This option may be used to select the project of",
! "		interest.  When no -Project option is specified, the",
! "		AEGIS_PROJECT environment variable is consulted.  If",
! "		that does not exist, the user's $HOME/.aegisrc file",
! "		is examined for a default project field (see",
! "		aeuconf(5) for more information).  If that does not",
! "		exist, when the user is only working on changes",
! "		within a single project, the project name defaults",
! "		to that project.  Otherwise, it is an error.",
  "",
  "	-TERse",
  "		This option may be used to cause listings to",
***************
*** 107,117 ****
  "		option this option causes column headings to be",
  "		added.",
  "",
! "	All options are case insensitive.  Options may be",
! "	abbreviated; the abbreviation is the upper case letters.",
  "	Options and other command line arguments may be mixed",
! "	arbitrarily on the command line.",
  "",
  "RECOMMENDED ALIAS",
  "	The recommended alias for this command is",
  "	csh%%	alias aeni '%s -ni \\!* -v'",
--- 107,135 ----
  "		option this option causes column headings to be",
  "		added.",
  "",
! "	All options may be abbreviated; the abbreviation is",
! "	documented as the upper case letters, all lower case",
! "	letters and underscores (_) are optional.  You must use",
! "	consecutive sequences of optional letters.",
! "",
! "	All options are case insensitive, you may type them in",
! "	upper case or lower case or a combination of both, case",
! "	is not important.",
! "",
! "	For example: the arguments \"-project, \"-PROJ\" and \"-p\"",
! "	are all interpreted to mean the -Project option.  The",
! "	argument \"-prj\" will not be understood, because",
! "	consecutive optional characters were not supplied.",
! "",
  "	Options and other command line arguments may be mixed",
! "	arbitrarily on the command line, after the function",
! "	selectors.",
  "",
+ "	The GNU long option names are understood.  Since all",
+ "	option names for aegis are long, this means ignoring the",
+ "	extra leading '-'.  The \"--option=value\" convention is",
+ "	also understood.",
+ "",
  "RECOMMENDED ALIAS",
  "	The recommended alias for this command is",
  "	csh%%	alias aeni '%s -ni \\!* -v'",
***************
*** 143,149 ****
  integrator_list(usage)
  	void	(*usage)_((void));
  {
! 	string_t	*project_name;
  
  	trace(("integrator_list()\n{\n"/*}*/));
  	arglex();
--- 161,167 ----
  integrator_list(usage)
  	void	(*usage)_((void));
  {
! 	string_ty	*project_name;
  
  	trace(("integrator_list()\n{\n"/*}*/));
  	arglex();
***************
*** 179,190 ****
  new_integrator_main()
  {
  	wlist		wl;
! 	string_t	*s1;
  	pstate		pstate_data;
  	int		j;
! 	string_t	*project_name;
! 	project_t	*pp;
! 	user_t		*up;
  
  	trace(("new_integrator_main()\n{\n"/*}*/));
  	wl_zero(&wl);
--- 197,208 ----
  new_integrator_main()
  {
  	wlist		wl;
! 	string_ty	*s1;
  	pstate		pstate_data;
  	int		j;
! 	string_ty	*project_name;
! 	project_ty	*pp;
! 	user_ty		*up;
  
  	trace(("new_integrator_main()\n{\n"/*}*/));
  	wl_zero(&wl);
***************
*** 257,263 ****
  	 */
  	for (j = 0; j < wl.wl_nwords; ++j)
  	{
! 		user_t		*candidate;
  
  		/*
  		 * make sure the user isn't already there
--- 275,281 ----
  	 */
  	for (j = 0; j < wl.wl_nwords; ++j)
  	{
! 		user_ty		*candidate;
  
  		/*
  		 * make sure the user isn't already there
***************
*** 411,421 ****
  "		option this option causes column headings to be",
  "		added.",
  "",
! "	All options are case insensitive.  Options may be",
! "	abbreviated; the abbreviation is the upper case letters.",
  "	Options and other command line arguments may be mixed",
! "	arbitrarily on the command line.",
  "",
  "RECOMMENDED ALIAS",
  "	The recommended alias for this command is",
  "	csh%%	alias aeri '%s -ri \\!* -v'",
--- 429,457 ----
  "		option this option causes column headings to be",
  "		added.",
  "",
! "	All options may be abbreviated; the abbreviation is",
! "	documented as the upper case letters, all lower case",
! "	letters and underscores (_) are optional.  You must use",
! "	consecutive sequences of optional letters.",
! "",
! "	All options are case insensitive, you may type them in",
! "	upper case or lower case or a combination of both, case",
! "	is not important.",
! "",
! "	For example: the arguments \"-project, \"-PROJ\" and \"-p\"",
! "	are all interpreted to mean the -Project option.  The",
! "	argument \"-prj\" will not be understood, because",
! "	consecutive optional characters were not supplied.",
! "",
  "	Options and other command line arguments may be mixed",
! "	arbitrarily on the command line, after the function",
! "	selectors.",
  "",
+ "	The GNU long option names are understood.  Since all",
+ "	option names for aegis are long, this means ignoring the",
+ "	extra leading '-'.  The \"--option=value\" convention is",
+ "	also understood.",
+ "",
  "RECOMMENDED ALIAS",
  "	The recommended alias for this command is",
  "	csh%%	alias aeri '%s -ri \\!* -v'",
***************
*** 447,458 ****
  remove_integrator_main()
  {
  	wlist		wl;
! 	string_t	*s1;
  	pstate		pstate_data;
  	int		j;
! 	string_t	*project_name;
! 	project_t	*pp;
! 	user_t		*up;
  
  	trace(("remove_integrator_main()\n{\n"/*}*/));
  	wl_zero(&wl);
--- 483,494 ----
  remove_integrator_main()
  {
  	wlist		wl;
! 	string_ty	*s1;
  	pstate		pstate_data;
  	int		j;
! 	string_ty	*project_name;
! 	project_ty	*pp;
! 	user_ty		*up;
  
  	trace(("remove_integrator_main()\n{\n"/*}*/));
  	wl_zero(&wl);
***************
*** 525,531 ****
  	 */
  	for (j = 0; j < wl.wl_nwords; ++j)
  	{
! 		user_t		*candidate;
  
  		candidate = user_symbolic(pp, wl.wl_word[j]);
  		if (!project_integrator_query(pp, user_name(candidate)))
--- 561,567 ----
  	 */
  	for (j = 0; j < wl.wl_nwords; ++j)
  	{
! 		user_ty		*candidate;
  
  		candidate = user_symbolic(pp, wl.wl_word[j]);
  		if (!project_integrator_query(pp, user_name(candidate)))
Index: aegis/integra1.h
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
Index: aegis/integra2.c
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 110,118 ****
  "",
  "	-Change <number>",
  "		This option may be used to specify a particular",
! "		change within a project.  If the user is only",
! "		working on one change within a project, that is",
! "		the default change number.",
  "",
  "	-Help",
  "		This option may be used to obtain more",
--- 110,123 ----
  "",
  "	-Change <number>",
  "		This option may be used to specify a particular",
! "		change within a project.  When no -Change option is",
! "		specified, the AEGIS_CHANGE environment variable is",
! "		consulted.  If that does not exist, the user's",
! "		$HOME/.aegisrc file is examined for a default change",
! "		field (see aeuconf(5) for more information).  If",
! "		that does not exist, when the user is only working",
! "		on one change within a project, that is the default",
! "		change number.  Otherwise, it is an error.",
  "",
  "	-Help",
  "		This option may be used to obtain more",
***************
*** 132,145 ****
  "",
  "	-Project <name>",
  "		This option may be used to select the project of",
! "		interest.  When no -Project option is specified, if",
! "		the user is only working on changes within a single",
! "		project, the project name defaults to that project;",
! "		if the user is currently working on changes to more",
! "		than one project, or is not working on changes to",
! "		any project, the user's $HOME/.%src file is",
! "		examined for a default project field (see aeuconf(5)",
! "		for more information).",
  "",
  "	-TERse",
  "		This option may be used to cause listings to",
--- 137,150 ----
  "",
  "	-Project <name>",
  "		This option may be used to select the project of",
! "		interest.  When no -Project option is specified, the",
! "		AEGIS_PROJECT environment variable is consulted.  If",
! "		that does not exist, the user's $HOME/.aegisrc file",
! "		is examined for a default project field (see",
! "		aeuconf(5) for more information).  If that does not",
! "		exist, when the user is only working on changes",
! "		within a single project, the project name defaults",
! "		to that project.  Otherwise, it is an error.",
  "",
  "	-TERse",
  "		This option may be used to cause listings to",
***************
*** 153,163 ****
  "		option this option causes column headings to be",
  "		added.",
  "",
! "	All options are case insensitive.  Options may be",
! "	abbreviated; the abbreviation is the upper case letters.",
  "	Options and other command line arguments may be mixed",
! "	arbitrarily on the command line.",
  "",
  "RECOMMENDED ALIAS",
  "	The recommended alias for this command is",
  "	csh%%	alias aeib '%s -ib \\!* -v'",
--- 158,186 ----
  "		option this option causes column headings to be",
  "		added.",
  "",
! "	All options may be abbreviated; the abbreviation is",
! "	documented as the upper case letters, all lower case",
! "	letters and underscores (_) are optional.  You must use",
! "	consecutive sequences of optional letters.",
! "",
! "	All options are case insensitive, you may type them in",
! "	upper case or lower case or a combination of both, case",
! "	is not important.",
! "",
! "	For example: the arguments \"-project, \"-PROJ\" and \"-p\"",
! "	are all interpreted to mean the -Project option.  The",
! "	argument \"-prj\" will not be understood, because",
! "	consecutive optional characters were not supplied.",
! "",
  "	Options and other command line arguments may be mixed",
! "	arbitrarily on the command line, after the function",
! "	selectors.",
  "",
+ "	The GNU long option names are understood.  Since all",
+ "	option names for aegis are long, this means ignoring the",
+ "	extra leading '-'.  The \"--option=value\" convention is",
+ "	also understood.",
+ "",
  "RECOMMENDED ALIAS",
  "	The recommended alias for this command is",
  "	csh%%	alias aeib '%s -ib \\!* -v'",
***************
*** 198,204 ****
  static void
  integrate_begin_list()
  {
! 	string_t	*project_name;
  
  	trace(("integrate_begin_list()\n{\n"/*}*/));
  	arglex();
--- 221,227 ----
  static void
  integrate_begin_list()
  {
! 	string_ty	*project_name;
  
  	trace(("integrate_begin_list()\n{\n"/*}*/));
  	arglex();
***************
*** 232,264 ****
  }
  
  
! static void link_tree_callback_minimum _((void *, dir_walk_message_t,
! 	string_t *, struct stat *));
  
  static void
  link_tree_callback_minimum(arg, message, path, st)
  	void		*arg;
! 	dir_walk_message_t message;
! 	string_t	*path;
  	struct stat	*st;
  {
! 	string_t	*s1;
! 	string_t	*s2;
! 	change_t	*cp;
  	pstate_src	src;
  
  	trace(("link_tree_callback_minimum(message = %d, path = %08lX, \
  st = %08lX)\n{\n"/*}*/, message, path, st));
! 	cp = (change_t *)arg;
  	assert(cp);
  	trace_string(path->str_text);
! 	s1 = os_below_dir(project_baseline_path_get(cp->pp), path);
  	assert(s1);
  	trace_string(s1->str_text);
  	if (!s1->str_length)
! 		s2 = str_copy(change_integration_directory_get(cp));
  	else
! 		s2 = str_format("%S/%S", change_integration_directory_get(cp), s1);
  	trace_string(s2->str_text);
  	switch (message)
  	{
--- 255,287 ----
  }
  
  
! static void link_tree_callback_minimum _((void *, dir_walk_message_ty,
! 	string_ty *, struct stat *));
  
  static void
  link_tree_callback_minimum(arg, message, path, st)
  	void		*arg;
! 	dir_walk_message_ty message;
! 	string_ty	*path;
  	struct stat	*st;
  {
! 	string_ty	*s1;
! 	string_ty	*s2;
! 	change_ty	*cp;
  	pstate_src	src;
  
  	trace(("link_tree_callback_minimum(message = %d, path = %08lX, \
  st = %08lX)\n{\n"/*}*/, message, path, st));
! 	cp = (change_ty *)arg;
  	assert(cp);
  	trace_string(path->str_text);
! 	s1 = os_below_dir(project_baseline_path_get(cp->pp, 1), path);
  	assert(s1);
  	trace_string(s1->str_text);
  	if (!s1->str_length)
! 		s2 = str_copy(change_integration_directory_get(cp, 1));
  	else
! 		s2 = str_format("%S/%S", change_integration_directory_get(cp, 1), s1);
  	trace_string(s2->str_text);
  	switch (message)
  	{
***************
*** 301,307 ****
  		 */
  		os_mkdir_between
  		(
! 			change_integration_directory_get(cp),
  			s1,
  			02755
  		);
--- 324,330 ----
  		 */
  		os_mkdir_between
  		(
! 			change_integration_directory_get(cp, 1),
  			s1,
  			02755
  		);
***************
*** 340,372 ****
  }
  
  
! static void link_tree_callback _((void *, dir_walk_message_t, string_t *,
  	struct stat *));
  
  static void
  link_tree_callback(arg, message, path, st)
  	void		*arg;
! 	dir_walk_message_t message;
! 	string_t	*path;
  	struct stat	*st;
  {
! 	string_t	*s1;
! 	string_t	*s2;
! 	change_t	*cp;
  	pstate_src	src;
  
  	trace(("link_tree_callback(message = %d, path = %08lX, \
  st = %08lX)\n{\n"/*}*/, message, path, st));
! 	cp = (change_t *)arg;
  	assert(cp);
  	trace_string(path->str_text);
! 	s1 = os_below_dir(project_baseline_path_get(cp->pp), path);
  	assert(s1);
  	trace_string(s1->str_text);
  	if (!s1->str_length)
! 		s2 = str_copy(change_integration_directory_get(cp));
  	else
! 		s2 = str_format("%S/%S", change_integration_directory_get(cp), s1);
  	trace_string(s2->str_text);
  	switch (message)
  	{
--- 363,395 ----
  }
  
  
! static void link_tree_callback _((void *, dir_walk_message_ty, string_ty *,
  	struct stat *));
  
  static void
  link_tree_callback(arg, message, path, st)
  	void		*arg;
! 	dir_walk_message_ty message;
! 	string_ty	*path;
  	struct stat	*st;
  {
! 	string_ty	*s1;
! 	string_ty	*s2;
! 	change_ty	*cp;
  	pstate_src	src;
  
  	trace(("link_tree_callback(message = %d, path = %08lX, \
  st = %08lX)\n{\n"/*}*/, message, path, st));
! 	cp = (change_ty *)arg;
  	assert(cp);
  	trace_string(path->str_text);
! 	s1 = os_below_dir(project_baseline_path_get(cp->pp, 1), path);
  	assert(s1);
  	trace_string(s1->str_text);
  	if (!s1->str_length)
! 		s2 = str_copy(change_integration_directory_get(cp, 1));
  	else
! 		s2 = str_format("%S/%S", change_integration_directory_get(cp, 1), s1);
  	trace_string(s2->str_text);
  	switch (message)
  	{
***************
*** 425,456 ****
  }
  
  
! static void copy_tree_callback_minimum _((void *, dir_walk_message_t,
! 	string_t *, struct stat *));
  
  static void
  copy_tree_callback_minimum(arg, message, path, st)
  	void		*arg;
! 	dir_walk_message_t message;
! 	string_t	*path;
  	struct stat	*st;
  {
! 	string_t	*s1;
! 	string_t	*s2;
! 	change_t	*cp;
  	pstate_src	src;
  	int		uid;
  
  	trace(("copy_tree_callback(message = %d, path = %08lX, \
  st = %08lX)\n{\n"/*}*/, message, path, st));
! 	cp = (change_t *)arg;
  	assert(cp);
  	trace_string(path->str_text);
! 	s1 = os_below_dir(project_baseline_path_get(cp->pp), path);
  	assert(s1);
  	trace_string(s1->str_text);
  	if (!s1->str_length)
! 		s2 = str_copy(change_integration_directory_get(cp));
  	else
  	{
  		s2 =
--- 448,479 ----
  }
  
  
! static void copy_tree_callback_minimum _((void *, dir_walk_message_ty,
! 	string_ty *, struct stat *));
  
  static void
  copy_tree_callback_minimum(arg, message, path, st)
  	void		*arg;
! 	dir_walk_message_ty message;
! 	string_ty	*path;
  	struct stat	*st;
  {
! 	string_ty	*s1;
! 	string_ty	*s2;
! 	change_ty	*cp;
  	pstate_src	src;
  	int		uid;
  
  	trace(("copy_tree_callback(message = %d, path = %08lX, \
  st = %08lX)\n{\n"/*}*/, message, path, st));
! 	cp = (change_ty *)arg;
  	assert(cp);
  	trace_string(path->str_text);
! 	s1 = os_below_dir(project_baseline_path_get(cp->pp, 1), path);
  	assert(s1);
  	trace_string(s1->str_text);
  	if (!s1->str_length)
! 		s2 = str_copy(change_integration_directory_get(cp, 1));
  	else
  	{
  		s2 =
***************
*** 457,463 ****
  			str_format
  			(
  				"%S/%S",
! 				change_integration_directory_get(cp),
  				s1
  			);
  	}
--- 480,486 ----
  			str_format
  			(
  				"%S/%S",
! 				change_integration_directory_get(cp, 1),
  				s1
  			);
  	}
***************
*** 511,517 ****
  		 */
  		os_mkdir_between
  		(
! 			change_integration_directory_get(cp),
  			s1,
  			02755
  		);
--- 534,540 ----
  		 */
  		os_mkdir_between
  		(
! 			change_integration_directory_get(cp, 1),
  			s1,
  			02755
  		);
***************
*** 550,580 ****
  }
  
  
! static void copy_tree_callback _((void *, dir_walk_message_t, string_t *,
  	struct stat *));
  
  static void
  copy_tree_callback(arg, message, path, st)
  	void		*arg;
! 	dir_walk_message_t message;
! 	string_t	*path;
  	struct stat	*st;
  {
! 	string_t	*s1;
! 	string_t	*s2;
! 	change_t	*cp;
  	pstate_src	src;
  	int		uid;
  
  	trace(("copy_tree_callback(message = %d, path = %08lX, st = %08lX)\n{\n"/*}*/, message, path, st));
! 	cp = (change_t *)arg;
  	assert(cp);
  	trace_string(path->str_text);
! 	s1 = os_below_dir(project_baseline_path_get(cp->pp), path);
  	assert(s1);
  	trace_string(s1->str_text);
  	if (!s1->str_length)
! 		s2 = str_copy(change_integration_directory_get(cp));
  	else
  	{
  		s2 =
--- 573,603 ----
  }
  
  
! static void copy_tree_callback _((void *, dir_walk_message_ty, string_ty *,
  	struct stat *));
  
  static void
  copy_tree_callback(arg, message, path, st)
  	void		*arg;
! 	dir_walk_message_ty message;
! 	string_ty	*path;
  	struct stat	*st;
  {
! 	string_ty	*s1;
! 	string_ty	*s2;
! 	change_ty	*cp;
  	pstate_src	src;
  	int		uid;
  
  	trace(("copy_tree_callback(message = %d, path = %08lX, st = %08lX)\n{\n"/*}*/, message, path, st));
! 	cp = (change_ty *)arg;
  	assert(cp);
  	trace_string(path->str_text);
! 	s1 = os_below_dir(project_baseline_path_get(cp->pp, 1), path);
  	assert(s1);
  	trace_string(s1->str_text);
  	if (!s1->str_length)
! 		s2 = str_copy(change_integration_directory_get(cp, 1));
  	else
  	{
  		s2 =
***************
*** 581,587 ****
  			str_format
  			(
  				"%S/%S",
! 				change_integration_directory_get(cp),
  				s1
  			);
  	}
--- 604,610 ----
  			str_format
  			(
  				"%S/%S",
! 				change_integration_directory_get(cp, 1),
  				s1
  			);
  	}
***************
*** 653,661 ****
  static void
  integrate_begin_main()
  {
! 	string_t	*bl;
! 	string_t	*dd;
! 	string_t	*id;
  	pconf		pconf_data;
  	pstate		pstate_data;
  	cstate		cstate_data;
--- 676,684 ----
  static void
  integrate_begin_main()
  {
! 	string_ty	*bl;
! 	string_ty	*dd;
! 	string_ty	*id;
  	pconf		pconf_data;
  	pstate		pstate_data;
  	cstate		cstate_data;
***************
*** 662,674 ****
  	int		j;
  	cstate_history	history_data;
  	int		minimum;
! 	string_t	*project_name;
! 	project_t	*pp;
  	long		change_number;
! 	change_t	*cp;
  	int		nolog;
! 	user_t		*up;
  	int		errs;
  
  	trace(("integrate_begin_main()\n{\n"/*}*/));
  	minimum = 0;
--- 685,698 ----
  	int		j;
  	cstate_history	history_data;
  	int		minimum;
! 	string_ty	*project_name;
! 	project_ty	*pp;
  	long		change_number;
! 	change_ty	*cp;
  	int		nolog;
! 	user_ty		*up;
  	int		errs;
+ 	string_ty	*s;
  
  	trace(("integrate_begin_main()\n{\n"/*}*/));
  	minimum = 0;
***************
*** 798,804 ****
  	/*
  	 * Create the integration directory.
  	 */
! 	cstate_data->integration_directory =
  		str_format
  		(
  			"%S/delta.%3.3ld",
--- 822,828 ----
  	/*
  	 * Create the integration directory.
  	 */
! 	s =
  		str_format
  		(
  			"%S/delta.%3.3ld",
***************
*** 805,815 ****
  			project_home_path_get(pp),
  			cstate_data->delta_number
  		);
! 	change_integration_directory_set
! 	(
! 		cp,
! 		cstate_data->integration_directory
! 	);
  
  	/*
  	 * There will be many files in the baseline in addition
--- 829,836 ----
  			project_home_path_get(pp),
  			cstate_data->delta_number
  		);
! 	change_integration_directory_set(cp, s);
! 	str_free(s);
  
  	/*
  	 * There will be many files in the baseline in addition
***************
*** 840,855 ****
  	 * (b) the changed file must exist and not have been modified
  	 * (c) the difference file must exist and not have been modified
  	 */
! 	dd = change_development_directory_get(cp);
! 	id = change_integration_directory_get(cp);
! 	bl = project_baseline_path_get(pp);
  	project_become(pp);
  	errs = 0;
  	for (j = 0; j < cstate_data->src->length; ++j)
  	{
  		cstate_src	src_data;
! 		string_t	*s1;
! 		string_t	*s2;
  
  		src_data = cstate_data->src->list[j];
  		s1 = str_format("%S/%S", dd, src_data->file_name);
--- 861,876 ----
  	 * (b) the changed file must exist and not have been modified
  	 * (c) the difference file must exist and not have been modified
  	 */
! 	dd = change_development_directory_get(cp, 1);
! 	id = change_integration_directory_get(cp, 1);
! 	bl = project_baseline_path_get(pp, 1);
  	project_become(pp);
  	errs = 0;
  	for (j = 0; j < cstate_data->src->length; ++j)
  	{
  		cstate_src	src_data;
! 		string_ty	*s1;
! 		string_ty	*s2;
  
  		src_data = cstate_data->src->list[j];
  		s1 = str_format("%S/%S", dd, src_data->file_name);
***************
*** 933,940 ****
  	for (j = 0; j < cstate_data->src->length; ++j)
  	{
  		cstate_src	src_data;
! 		string_t	*s1;
! 		string_t	*s2;
  
  		src_data = cstate_data->src->list[j];
  		s1 = str_format("%S/%S", dd, src_data->file_name);
--- 954,961 ----
  	for (j = 0; j < cstate_data->src->length; ++j)
  	{
  		cstate_src	src_data;
! 		string_ty	*s1;
! 		string_ty	*s2;
  
  		src_data = cstate_data->src->list[j];
  		s1 = str_format("%S/%S", dd, src_data->file_name);
***************
*** 965,971 ****
  			break;
  		}
  	}
! 	os_become_undo();
  
  	/*
  	 * add the change to the user's list
--- 986,992 ----
  			break;
  		}
  	}
! 	project_become_undo();
  
  	/*
  	 * add the change to the user's list
***************
*** 990,1025 ****
  	 */
  	if (pconf_data->integrate_begin_command)
  	{
! 		string_t	*the_command;
! 		char		num[20];
! 		char		bnum[40];
  
  		if (!nolog)
  			log_open(change_logfile_get(cp), up);
! 		sprintf(num, "%ld", change_number);
! 		sprintf
! 		(
! 			bnum,
! 			"%ld.%ld.D%3.3ld",
! 			pstate_data->version_major,
! 			pstate_data->version_minor,
! 			cstate_data->delta_number
! 		);
! 		the_command =
! 			substitute
! 			(
! 				cp,
! 				pconf_data->integrate_begin_command->str_text,
! 				project_name_get(pp)->str_text,
! 				num,
! 				bnum,
! 				(char *)0
! 			);
  		os_execute
  		(
  			the_command,
  			OS_EXEC_FLAG_NO_INPUT + OS_EXEC_FLAG_ERROK,
! 			change_integration_directory_get(cp)
  		);
  		str_free(the_command);
  	}
--- 1011,1030 ----
  	 */
  	if (pconf_data->integrate_begin_command)
  	{
! 		string_ty	*the_command;
  
  		if (!nolog)
  			log_open(change_logfile_get(cp), up);
! 		sub_var_set("1", "${project}");
! 		sub_var_set("2", "${change}");
! 		sub_var_set("3", "${version}");
! 		the_command = pconf_data->integrate_begin_command;
! 		the_command = substitute(cp, the_command);
  		os_execute
  		(
  			the_command,
  			OS_EXEC_FLAG_NO_INPUT + OS_EXEC_FLAG_ERROK,
! 			change_integration_directory_get(cp, 1)
  		);
  		str_free(the_command);
  	}
***************
*** 1103,1111 ****
  "",
  "	-Change <number>",
  "		This option may be used to specify a particular",
! "		change within a project.  If the user is only",
! "		working on one change within a project, that is",
! "		the default change number.",
  "",
  "	-Help",
  "		This option may be used to obtain more",
--- 1108,1121 ----
  "",
  "	-Change <number>",
  "		This option may be used to specify a particular",
! "		change within a project.  When no -Change option is",
! "		specified, the AEGIS_CHANGE environment variable is",
! "		consulted.  If that does not exist, the user's",
! "		$HOME/.aegisrc file is examined for a default change",
! "		field (see aeuconf(5) for more information).  If",
! "		that does not exist, when the user is only working",
! "		on one change within a project, that is the default",
! "		change number.  Otherwise, it is an error.",
  "",
  "	-Help",
  "		This option may be used to obtain more",
***************
*** 1122,1135 ****
  "",
  "	-Project <name>",
  "		This option may be used to select the project of",
! "		interest.  When no -Project option is specified, if",
! "		the user is only working on changes within a single",
! "		project, the project name defaults to that project;",
! "		if the user is currently working on changes to more",
! "		than one project, or is not working on changes to",
! "		any project, the user's $HOME/.%src file is",
! "		examined for a default project field (see aeuconf(5)",
! "		for more information).",
  "",
  "	-TERse",
  "		This option may be used to cause listings to",
--- 1132,1145 ----
  "",
  "	-Project <name>",
  "		This option may be used to select the project of",
! "		interest.  When no -Project option is specified, the",
! "		AEGIS_PROJECT environment variable is consulted.  If",
! "		that does not exist, the user's $HOME/.aegisrc file",
! "		is examined for a default project field (see",
! "		aeuconf(5) for more information).  If that does not",
! "		exist, when the user is only working on changes",
! "		within a single project, the project name defaults",
! "		to that project.  Otherwise, it is an error.",
  "",
  "	-TERse",
  "		This option may be used to cause listings to",
***************
*** 1143,1153 ****
  "		option this option causes column headings to be",
  "		added.",
  "",
! "	All options are case insensitive.  Options may be",
! "	abbreviated; the abbreviation is the upper case letters.",
  "	Options and other command line arguments may be mixed",
! "	arbitrarily on the command line.",
  "",
  "RECOMMENDED ALIAS",
  "	The recommended alias for this command is",
  "	csh%%	alias aeibu '%s -ibu \\!* -v'",
--- 1153,1181 ----
  "		option this option causes column headings to be",
  "		added.",
  "",
! "	All options may be abbreviated; the abbreviation is",
! "	documented as the upper case letters, all lower case",
! "	letters and underscores (_) are optional.  You must use",
! "	consecutive sequences of optional letters.",
! "",
! "	All options are case insensitive, you may type them in",
! "	upper case or lower case or a combination of both, case",
! "	is not important.",
! "",
! "	For example: the arguments \"-project, \"-PROJ\" and \"-p\"",
! "	are all interpreted to mean the -Project option.  The",
! "	argument \"-prj\" will not be understood, because",
! "	consecutive optional characters were not supplied.",
! "",
  "	Options and other command line arguments may be mixed",
! "	arbitrarily on the command line, after the function",
! "	selectors.",
  "",
+ "	The GNU long option names are understood.  Since all",
+ "	option names for aegis are long, this means ignoring the",
+ "	extra leading '-'.  The \"--option=value\" convention is",
+ "	also understood.",
+ "",
  "RECOMMENDED ALIAS",
  "	The recommended alias for this command is",
  "	csh%%	alias aeibu '%s -ibu \\!* -v'",
***************
*** 1181,1187 ****
  integrating_list(usage)
  	void		(*usage)_((void));
  {
! 	string_t	*project_name;
  
  	trace(("integrating_list()\n{\n"/*}*/));
  	arglex();
--- 1209,1215 ----
  integrating_list(usage)
  	void		(*usage)_((void));
  {
! 	string_ty	*project_name;
  
  	trace(("integrating_list()\n{\n"/*}*/));
  	arglex();
***************
*** 1223,1234 ****
  	cstate		cstate_data;
  	pstate		pstate_data;
  	cstate_history	history_data;
! 	string_t	*dir;
! 	string_t	*project_name;
! 	project_t	*pp;
  	long		change_number;
! 	change_t	*cp;
! 	user_t		*up;
  
  	trace(("integrate_begin_main()\n{\n"/*}*/));
  	project_name = 0;
--- 1251,1262 ----
  	cstate		cstate_data;
  	pstate		pstate_data;
  	cstate_history	history_data;
! 	string_ty	*dir;
! 	string_ty	*project_name;
! 	project_ty	*pp;
  	long		change_number;
! 	change_ty	*cp;
! 	user_ty		*up;
  
  	trace(("integrate_begin_main()\n{\n"/*}*/));
  	project_name = 0;
***************
*** 1332,1339 ****
  	 * Note that the project has no current integration
  	 */
  	pstate_data->currently_integrating_change = 0;
! 	dir = cstate_data->integration_directory;
! 	cstate_data->integration_directory = 0;
  	cstate_data->build_time = 0;
  	cstate_data->delta_number = 0;
  
--- 1360,1367 ----
  	 * Note that the project has no current integration
  	 */
  	pstate_data->currently_integrating_change = 0;
! 	dir = str_copy(change_integration_directory_get(cp, 1));
! 	change_integration_directory_clear(cp);
  	cstate_data->build_time = 0;
  	cstate_data->delta_number = 0;
  
***************
*** 1341,1348 ****
--- 1369,1378 ----
  	 * Complain if they are in the integration directory,
  	 * because the rmdir at the end can't then run to completion.
  	 */
+ 	os_become_orig();
  	if (os_below_dir(dir, os_curdir()))
  		change_fatal(cp, "please leave the integration directory");
+ 	os_become_undo();
  
  	/*
  	 * write out the data and release the locks
***************
*** 1352,1358 ****
  	project_pstate_write(pp);
  	user_become(up);
  	commit_rmdir_tree_errok(dir);
! 	os_become_undo();
  	str_free(dir);
  	commit();
  	lock_release();
--- 1382,1388 ----
  	project_pstate_write(pp);
  	user_become(up);
  	commit_rmdir_tree_errok(dir);
! 	user_become_undo();
  	str_free(dir);
  	commit();
  	lock_release();
***************
*** 1439,1447 ****
  "",
  "	-Change <number>",
  "		This option may be used to specify a particular",
! "		change within a project.  If the user is only",
! "		working on one change within a project, that is",
! "		the default change number.",
  "",
  "	-Help",
  "		This option may be used to obtain more",
--- 1469,1482 ----
  "",
  "	-Change <number>",
  "		This option may be used to specify a particular",
! "		change within a project.  When no -Change option is",
! "		specified, the AEGIS_CHANGE environment variable is",
! "		consulted.  If that does not exist, the user's",
! "		$HOME/.aegisrc file is examined for a default change",
! "		field (see aeuconf(5) for more information).  If",
! "		that does not exist, when the user is only working",
! "		on one change within a project, that is the default",
! "		change number.  Otherwise, it is an error.",
  "",
  "	-Help",
  "		This option may be used to obtain more",
***************
*** 1458,1471 ****
  "",
  "	-Project <name>",
  "		This option may be used to select the project of",
! "		interest.  When no -Project option is specified, if",
! "		the user is only working on changes within a single",
! "		project, the project name defaults to that project;",
! "		if the user is currently working on changes to more",
! "		than one project, or is not working on changes to",
! "		any project, the user's $HOME/.%src file is",
! "		examined for a default project field (see aeuconf(5)",
! "		for more information).",
  "",
  "	-TERse",
  "		This option may be used to cause listings to",
--- 1493,1506 ----
  "",
  "	-Project <name>",
  "		This option may be used to select the project of",
! "		interest.  When no -Project option is specified, the",
! "		AEGIS_PROJECT environment variable is consulted.  If",
! "		that does not exist, the user's $HOME/.aegisrc file",
! "		is examined for a default project field (see",
! "		aeuconf(5) for more information).  If that does not",
! "		exist, when the user is only working on changes",
! "		within a single project, the project name defaults",
! "		to that project.  Otherwise, it is an error.",
  "",
  "	-TERse",
  "		This option may be used to cause listings to",
***************
*** 1479,1489 ****
  "		option this option causes column headings to be",
  "		added.",
  "",
! "	All options are case insensitive.  Options may be",
! "	abbreviated; the abbreviation is the upper case letters.",
  "	Options and other command line arguments may be mixed",
! "	arbitrarily on the command line.",
  "",
  "RECOMMENDED ALIAS",
  "	The recommended alias for this command is",
  "	csh%%	alias aeif '%s -if \\!* -v'",
--- 1514,1542 ----
  "		option this option causes column headings to be",
  "		added.",
  "",
! "	All options may be abbreviated; the abbreviation is",
! "	documented as the upper case letters, all lower case",
! "	letters and underscores (_) are optional.  You must use",
! "	consecutive sequences of optional letters.",
! "",
! "	All options are case insensitive, you may type them in",
! "	upper case or lower case or a combination of both, case",
! "	is not important.",
! "",
! "	For example: the arguments \"-project, \"-PROJ\" and \"-p\"",
! "	are all interpreted to mean the -Project option.  The",
! "	argument \"-prj\" will not be understood, because",
! "	consecutive optional characters were not supplied.",
! "",
  "	Options and other command line arguments may be mixed",
! "	arbitrarily on the command line, after the function",
! "	selectors.",
  "",
+ "	The GNU long option names are understood.  Since all",
+ "	option names for aegis are long, this means ignoring the",
+ "	extra leading '-'.  The \"--option=value\" convention is",
+ "	also understood.",
+ "",
  "RECOMMENDED ALIAS",
  "	The recommended alias for this command is",
  "	csh%%	alias aeif '%s -if \\!* -v'",
***************
*** 1511,1528 ****
  }
  
  
! static void repair_diff_time _((change_t *, string_t *));
  
  static void
  repair_diff_time(cp, path)
! 	change_t	*cp;
! 	string_t	*path;
  {
! 	string_t	*s;
  	cstate_src	src_data;
! 	string_t	*s2;
  
! 	s = os_below_dir(change_development_directory_get(cp), path);
  	src_data = change_src_find(cp, s);
  	if (src_data)
  		src_data->diff_time = os_mtime(path);
--- 1564,1581 ----
  }
  
  
! static void repair_diff_time _((change_ty *, string_ty *));
  
  static void
  repair_diff_time(cp, path)
! 	change_ty	*cp;
! 	string_ty	*path;
  {
! 	string_ty	*s;
  	cstate_src	src_data;
! 	string_ty	*s2;
  
! 	s = os_below_dir(change_development_directory_get(cp, 1), path);
  	src_data = change_src_find(cp, s);
  	if (src_data)
  		src_data->diff_time = os_mtime(path);
***************
*** 1546,1566 ****
  }
  
  
! static void if_func _((void *, dir_walk_message_t, string_t *, struct stat *));
  
  static void
  if_func(arg, message, path, st)
  	void		*arg;
! 	dir_walk_message_t message;
! 	string_t	*path;
  	struct stat	*st;
  {
! 	change_t	*cp;
  	int		uid;
  
  	trace(("if_func(message = %d, path = \"%s\", st = %08lX)\n{\n"/*}*/,
  		message, path->str_text, st));
! 	cp = (change_t *)arg;
  	switch (message)
  	{
  	case dir_walk_dir_before:
--- 1599,1619 ----
  }
  
  
! static void if_func _((void *, dir_walk_message_ty, string_ty *, struct stat *));
  
  static void
  if_func(arg, message, path, st)
  	void		*arg;
! 	dir_walk_message_ty message;
! 	string_ty	*path;
  	struct stat	*st;
  {
! 	change_ty	*cp;
  	int		uid;
  
  	trace(("if_func(message = %d, path = \"%s\", st = %08lX)\n{\n"/*}*/,
  		message, path->str_text, st));
! 	cp = (change_ty *)arg;
  	switch (message)
  	{
  	case dir_walk_dir_before:
***************
*** 1592,1612 ****
  static void
  integrate_fail_main()
  {
! 	string_t	*dd;
  	cstate		cstate_data;
  	pstate		pstate_data;
  	cstate_history	history_data;
! 	string_t	*comment = 0;
! 	string_t	*rev_name;
! 	string_t	*int_name;
! 	string_t	*dir;
  	int		j;
! 	string_t	*project_name;
! 	project_t	*pp;
  	long		change_number;
! 	change_t	*cp;
! 	user_t		*up;
! 	user_t		*devup;
  
  	trace(("integrate_fail_main()\n{\n"/*}*/));
  	project_name = 0;
--- 1645,1665 ----
  static void
  integrate_fail_main()
  {
! 	string_ty	*dd;
  	cstate		cstate_data;
  	pstate		pstate_data;
  	cstate_history	history_data;
! 	string_ty	*comment = 0;
! 	string_ty	*rev_name;
! 	string_ty	*int_name;
! 	string_ty	*dir;
  	int		j;
! 	string_ty	*project_name;
! 	project_ty	*pp;
  	long		change_number;
! 	change_ty	*cp;
! 	user_ty		*up;
! 	user_ty		*devup;
  
  	trace(("integrate_fail_main()\n{\n"/*}*/));
  	project_name = 0;
***************
*** 1713,1720 ****
  	rev_name = change_reviewer_name(cp);
  	int_name = change_integrator_name(cp);
  	cstate_data->delta_number = 0;
! 	dir = cstate_data->integration_directory;
! 	cstate_data->integration_directory = 0;
  	cstate_data->state = cstate_state_being_developed;
  
  	/*
--- 1766,1773 ----
  	rev_name = change_reviewer_name(cp);
  	int_name = change_integrator_name(cp);
  	cstate_data->delta_number = 0;
! 	dir = str_copy(change_integration_directory_get(cp, 1));
! 	change_integration_directory_clear(cp);
  	cstate_data->state = cstate_state_being_developed;
  
  	/*
***************
*** 1743,1752 ****
  	 * make the change files writable again
  	 */
  	change_verbose(cp, "make the development directory writable again");
! 	dd = change_development_directory_get(cp);
  	user_become(devup);
  	dir_walk(dd, if_func, cp);
! 	os_become_undo();
  
  	/*
  	 * go through the files in the change and unlock them
--- 1796,1805 ----
  	 * make the change files writable again
  	 */
  	change_verbose(cp, "make the development directory writable again");
! 	dd = change_development_directory_get(cp, 1);
  	user_become(devup);
  	dir_walk(dd, if_func, cp);
! 	user_become_undo();
  
  	/*
  	 * go through the files in the change and unlock them
***************
*** 1780,1786 ****
  	change_verbose(cp, "remove the integration directory");
  	project_become(pp);
  	commit_rmdir_tree_errok(dir);
! 	os_become_undo();
  
  	/*
  	 * write out the data and release the locks
--- 1833,1839 ----
  	change_verbose(cp, "remove the integration directory");
  	project_become(pp);
  	commit_rmdir_tree_errok(dir);
! 	project_become_undo();
  
  	/*
  	 * write out the data and release the locks
***************
*** 1872,1885 ****
  "	directory is deleted.  The change is no longer assigned",
  "	to the current user.",
  "",
  "OPTIONS",
  "	The following options are understood:",
  "",
  "	-Change <number>",
  "		This option may be used to specify a particular",
! "		change within a project.  If the user is only",
! "		working on one change within a project, that is",
! "		the default change number.",
  "",
  "	-Help",
  "		This option may be used to obtain more",
--- 1925,1951 ----
  "	directory is deleted.  The change is no longer assigned",
  "	to the current user.",
  "",
+ "	While there is a build in progress for any change in a",
+ "	project, an integrate pass for the project will wait until",
+ "	all the builds are completed before starting.  This is to",
+ "	ensure that the baseline is consistent for the entire build.",
+ "	Similarly, while an integrate pass is in progress for a",
+ "	project, any builds will wait until it is completed before",
+ "	starting.",
+ "",
  "OPTIONS",
  "	The following options are understood:",
  "",
  "	-Change <number>",
  "		This option may be used to specify a particular",
! "		change within a project.  When no -Change option is",
! "		specified, the AEGIS_CHANGE environment variable is",
! "		consulted.  If that does not exist, the user's",
! "		$HOME/.aegisrc file is examined for a default change",
! "		field (see aeuconf(5) for more information).  If",
! "		that does not exist, when the user is only working",
! "		on one change within a project, that is the default",
! "		change number.  Otherwise, it is an error.",
  "",
  "	-Help",
  "		This option may be used to obtain more",
***************
*** 1892,1905 ****
  "",
  "	-Project <name>",
  "		This option may be used to select the project of",
! "		interest.  When no -Project option is specified, if",
! "		the user is only working on changes within a single",
! "		project, the project name defaults to that project;",
! "		if the user is currently working on changes to more",
! "		than one project, or is not working on changes to",
! "		any project, the user's $HOME/.%src file is",
! "		examined for a default project field (see aeuconf(5)",
! "		for more information).",
  "",
  "	-TERse",
  "		This option may be used to cause listings to",
--- 1958,1971 ----
  "",
  "	-Project <name>",
  "		This option may be used to select the project of",
! "		interest.  When no -Project option is specified, the",
! "		AEGIS_PROJECT environment variable is consulted.  If",
! "		that does not exist, the user's $HOME/.aegisrc file",
! "		is examined for a default project field (see",
! "		aeuconf(5) for more information).  If that does not",
! "		exist, when the user is only working on changes",
! "		within a single project, the project name defaults",
! "		to that project.  Otherwise, it is an error.",
  "",
  "	-TERse",
  "		This option may be used to cause listings to",
***************
*** 1913,1923 ****
  "		option this option causes column headings to be",
  "		added.",
  "",
! "	All options are case insensitive.  Options may be",
! "	abbreviated; the abbreviation is the upper case letters.",
  "	Options and other command line arguments may be mixed",
! "	arbitrarily on the command line.",
  "",
  "RECOMMENDED ALIAS",
  "	The recommended alias for this command is",
  "	csh%%	alias aeip '%s -ip \\!* -v'",
--- 1979,2007 ----
  "		option this option causes column headings to be",
  "		added.",
  "",
! "	All options may be abbreviated; the abbreviation is",
! "	documented as the upper case letters, all lower case",
! "	letters and underscores (_) are optional.  You must use",
! "	consecutive sequences of optional letters.",
! "",
! "	All options are case insensitive, you may type them in",
! "	upper case or lower case or a combination of both, case",
! "	is not important.",
! "",
! "	For example: the arguments \"-project, \"-PROJ\" and \"-p\"",
! "	are all interpreted to mean the -Project option.  The",
! "	argument \"-prj\" will not be understood, because",
! "	consecutive optional characters were not supplied.",
! "",
  "	Options and other command line arguments may be mixed",
! "	arbitrarily on the command line, after the function",
! "	selectors.",
  "",
+ "	The GNU long option names are understood.  Since all",
+ "	option names for aegis are long, this means ignoring the",
+ "	extra leading '-'.  The \"--option=value\" convention is",
+ "	also understood.",
+ "",
  "RECOMMENDED ALIAS",
  "	The recommended alias for this command is",
  "	csh%%	alias aeip '%s -ip \\!* -v'",
***************
*** 1956,1984 ****
  static void
  integrate_pass_main()
  {
! 	string_t	*hp;
! 	string_t	*id;
! 	string_t	*cwd;
  	pstate		pstate_data;
  	cstate		cstate_data;
! 	string_t	*old_baseline;
! 	string_t	*new_baseline;
! 	string_t	*dev_dir;
! 	string_t	*int_name;
! 	string_t	*rev_name;
! 	string_t	*dev_name;
  	cstate_history	history_data;
  	pstate_history	phistory_data;
  	int		j;
  	int		ncmds;
  	pconf		pconf_data;
! 	string_t	*project_name;
! 	project_t	*pp;
  	long		change_number;
! 	change_t	*cp;
  	int		nolog;
! 	user_t		*up;
! 	user_t		*devup;
  
  	trace(("integrate_pass_main()\n{\n"/*}*/));
  	project_name = 0;
--- 2040,2068 ----
  static void
  integrate_pass_main()
  {
! 	string_ty	*hp;
! 	string_ty	*id;
! 	string_ty	*cwd;
  	pstate		pstate_data;
  	cstate		cstate_data;
! 	string_ty	*old_baseline;
! 	string_ty	*new_baseline;
! 	string_ty	*dev_dir;
! 	string_ty	*int_name;
! 	string_ty	*rev_name;
! 	string_ty	*dev_name;
  	cstate_history	history_data;
  	pstate_history	phistory_data;
  	int		j;
  	int		ncmds;
  	pconf		pconf_data;
! 	string_ty	*project_name;
! 	project_ty	*pp;
  	long		change_number;
! 	change_ty	*cp;
  	int		nolog;
! 	user_ty		*up;
! 	user_ty		*devup;
  
  	trace(("integrate_pass_main()\n{\n"/*}*/));
  	project_name = 0;
***************
*** 2055,2060 ****
--- 2139,2145 ----
  	project_pstate_lock_prepare(pp);
  	change_cstate_lock_prepare(cp);
  	user_ustate_lock_prepare(up);
+ 	project_build_write_lock_prepare(pp);
  	lock_take();
  	cstate_data = change_cstate_get(cp);
  	pstate_data = project_pstate_get(pp);
***************
*** 2066,2077 ****
  	os_become_orig();
  	cwd = os_curdir();
  	os_become_undo();
! 	if (os_below_dir(change_development_directory_get(cp), cwd))
  		change_fatal(cp, "please leave development directory");
! 	id = change_integration_directory_get(cp);
  	if (os_below_dir(id, cwd))
  		change_fatal(cp, "please leave integration directory");
! 	if (os_below_dir(project_baseline_path_get(pp), cwd))
  		project_fatal(pp, "please leave baseline directory");
  
  	/*
--- 2151,2162 ----
  	os_become_orig();
  	cwd = os_curdir();
  	os_become_undo();
! 	if (os_below_dir(change_development_directory_get(cp, 1), cwd))
  		change_fatal(cp, "please leave development directory");
! 	id = change_integration_directory_get(cp, 1);
  	if (os_below_dir(id, cwd))
  		change_fatal(cp, "please leave integration directory");
! 	if (os_below_dir(project_baseline_path_get(pp, 1), cwd))
  		project_fatal(pp, "please leave baseline directory");
  
  	/*
***************
*** 2153,2159 ****
  	 */
  	if (!nolog)
  	{
! 		user_t	*pup;
  
  		pup = project_user(pp);
  		log_open(change_logfile_get(cp), pup);
--- 2238,2244 ----
  	 */
  	if (!nolog)
  	{
! 		user_ty	*pup;
  
  		pup = project_user(pp);
  		log_open(change_logfile_get(cp), pup);
***************
*** 2166,2174 ****
  	{
  		cstate_src	c_src_data;
  		pstate_src	p_src_data;
! 		string_t	*the_command;
! 		string_t	*src_file;
! 		string_t	*dst_file;
  
  		c_src_data = cstate_data->src->list[j];
  		c_src_data->diff_time = 0;
--- 2251,2258 ----
  	{
  		cstate_src	c_src_data;
  		pstate_src	p_src_data;
! 		string_ty	*src_file;
! 		string_ty	*dst_file;
  
  		c_src_data = cstate_data->src->list[j];
  		c_src_data->diff_time = 0;
***************
*** 2182,2187 ****
--- 2266,2282 ----
  		{
  		case file_action_create:
  			/*
+ 			 * because history is never thrown away,
+ 			 * we could be reusing an existing history file
+ 			 */
+ 			if (p_src_data->edit_number)
+ 			{
+ 				assert(p_src_data->deleted_by);
+ 				p_src_data->deleted_by = 0;
+ 				goto reusing_an_old_file;
+ 			}
+ 
+ 			/*
  			 * it exists, now
  			 */
  			trace(("create\n"));
***************
*** 2188,2252 ****
  			p_src_data->about_to_be_created_by = 0;
  
  			/*
! 			 * prepare for the history commands
  			 */
! 			project_become(pp);
! 			os_mkdir_between(hp, c_src_data->file_name, 02755);
! 			os_become_undo();
! 			src_file =
! 				str_format("%S/%S", id, c_src_data->file_name);
! 			dst_file =
! 				str_format("%S/%S", hp, c_src_data->file_name);
! 
! 			/*
! 			 * create a new history
! 			 *	%1 = source file
! 			 *	%2 = history file
! 			 */
! 			the_command = pconf_data->history_create_command;
! 			the_command =
! 				substitute
  				(
  					cp,
! 					the_command->str_text,
! 					src_file->str_text,
! 					dst_file->str_text,
! 					(char *)0
  				);
- 			project_become(pp);
- 			os_execute(the_command, OS_EXEC_FLAG_NO_INPUT, id);
- 			os_become_undo();
- 
- 			/*
- 			 * ask the history file what its edit number is
- 			 *	%1 = history file
- 			 * we use this method because the string
- 			 * returned is essentially random,
- 			 * between different history programs.
- 			 */
- 			the_command = pconf_data->history_query_command;
- 			the_command =
- 				substitute
- 				(
- 					cp,
- 					the_command->str_text,
- 					dst_file->str_text,
- 					(char *)0
- 				);
- 			project_become(pp);
- 			p_src_data->edit_number =
- 				os_execute_slurp
- 				(
- 					the_command,
- 					OS_EXEC_FLAG_NO_INPUT,
- 					id
- 				);
- 			os_become_undo();
  			c_src_data->edit_number =
  				str_copy(p_src_data->edit_number);
  			break;
  
  		case file_action_modify:
  			trace(("modify\n"));
  			assert(str_equal(p_src_data->edit_number,
  				c_src_data->edit_number));
--- 2283,2307 ----
  			p_src_data->about_to_be_created_by = 0;
  
  			/*
! 			 * create the history
  			 */
! 			change_run_history_create_command
! 			(
! 				cp,
! 				c_src_data->file_name
! 			);
! 			p_src_data->edit_number =
! 				change_run_history_query_command
  				(
  					cp,
! 					c_src_data->file_name
  				);
  			c_src_data->edit_number =
  				str_copy(p_src_data->edit_number);
  			break;
  
  		case file_action_modify:
+ 			reusing_an_old_file:
  			trace(("modify\n"));
  			assert(str_equal(p_src_data->edit_number,
  				c_src_data->edit_number));
***************
*** 2261,2309 ****
  
  			/*
  			 * update the history
- 			 *	%1 = source file
- 			 *	%2 = history file
  			 */
! 			the_command = pconf_data->history_put_command;
! 			the_command =
! 				substitute
  				(
  					cp,
! 					the_command->str_text,
! 					src_file->str_text,
! 					dst_file->str_text,
! 					(char *)0
  				);
- 			project_become(pp);
- 			os_execute(the_command, OS_EXEC_FLAG_NO_INPUT, id);
- 			os_become_undo();
- 
- 			/*
- 			 * ask the history file what its edit number is
- 			 *	%1 = history file
- 			 * we use this method because the string
- 			 * returned is essentially random,
- 			 * between different history programs.
- 			 */
- 			the_command = pconf_data->history_query_command;
- 			the_command =
- 				substitute
- 				(
- 					cp,
- 					the_command->str_text,
- 					dst_file->str_text,
- 					(char *)0
- 				);
- 			str_free(p_src_data->edit_number);
- 			project_become(pp);
- 			p_src_data->edit_number =
- 				os_execute_slurp
- 				(
- 					the_command,
- 					OS_EXEC_FLAG_NO_INPUT,
- 					id
- 				);
- 			os_become_undo();
  			c_src_data->edit_number =
  				str_copy(p_src_data->edit_number);
  			break;
--- 2316,2333 ----
  
  			/*
  			 * update the history
  			 */
! 			change_run_history_put_command
! 			(
! 				cp,
! 				c_src_data->file_name
! 			);
! 			p_src_data->edit_number =
! 				change_run_history_query_command
  				(
  					cp,
! 					c_src_data->file_name
  				);
  			c_src_data->edit_number =
  				str_copy(p_src_data->edit_number);
  			break;
***************
*** 2323,2340 ****
  
  	/*
  	 * Advance the change to the 'completed' state.
! 	 * Clear the build-done field.
! 	 * Clear the test-done field.
! 	 * Clear the test-baseline-done field.
  	 */
  	cstate_data->state = cstate_state_completed;
  	cstate_data->build_time = 0;
  	cstate_data->test_time = 0;
  	cstate_data->test_baseline_time = 0;
! 	dev_dir = cstate_data->development_directory;
! 	cstate_data->development_directory = 0;
! 	new_baseline = cstate_data->integration_directory;
! 	cstate_data->integration_directory = 0;
  	int_name = change_integrator_name(cp);
  	rev_name = change_reviewer_name(cp);
  	dev_name = change_developer_name(cp);
--- 2347,2364 ----
  
  	/*
  	 * Advance the change to the 'completed' state.
! 	 * Clear the build-time field.
! 	 * Clear the test-time field.
! 	 * Clear the test-baseline-time field.
  	 */
  	cstate_data->state = cstate_state_completed;
  	cstate_data->build_time = 0;
  	cstate_data->test_time = 0;
  	cstate_data->test_baseline_time = 0;
! 	dev_dir = str_copy(change_development_directory_get(cp, 1));
! 	change_development_directory_clear(cp);
! 	new_baseline = str_copy(change_integration_directory_get(cp, 1));
! 	change_integration_directory_clear(cp);
  	int_name = change_integrator_name(cp);
  	rev_name = change_reviewer_name(cp);
  	dev_name = change_developer_name(cp);
***************
*** 2347,2370 ****
  		str_format
  		(
  			"%S.D%3.3ld",
! 			project_baseline_path_get(pp),
  			cstate_data->delta_number - 1
  		);
! 	new_baseline = change_integration_directory_get(cp);
  	project_become(pp);
! 	commit_rename(project_baseline_path_get(pp), old_baseline);
! 	commit_rename(new_baseline, project_baseline_path_get(pp));
  	commit_rmdir_tree_errok(old_baseline);
! 	os_become_undo();
  	str_free(old_baseline);
  
  	/*
  	 * throw away the development directory
  	 */
  	devup = user_symbolic(pp, dev_name);
  	user_become(devup);
  	commit_rmdir_tree_errok(dev_dir);
! 	os_become_undo();
  	str_free(dev_dir);
  	user_free(devup);
  
--- 2371,2395 ----
  		str_format
  		(
  			"%S.D%3.3ld",
! 			project_baseline_path_get(pp, 1),
  			cstate_data->delta_number - 1
  		);
! 	new_baseline = change_integration_directory_get(cp, 1);
  	project_become(pp);
! 	commit_rename(project_baseline_path_get(pp, 1), old_baseline);
! 	commit_rename(new_baseline, project_baseline_path_get(pp, 1));
  	commit_rmdir_tree_errok(old_baseline);
! 	project_become_undo();
  	str_free(old_baseline);
  
  	/*
  	 * throw away the development directory
  	 */
+ 	change_verbose(cp, "discard old directories");
  	devup = user_symbolic(pp, dev_name);
  	user_become(devup);
  	commit_rmdir_tree_errok(dev_dir);
! 	user_become_undo();
  	str_free(dev_dir);
  	user_free(devup);
  
Index: aegis/integra2.h
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
Index: aegis/io.c
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 28,34 ****
  #include <io.h>
  
  
! type_t	integer_type =
  {
  	type_class_integer,
  	"integer",
--- 28,34 ----
  #include <io.h>
  
  
! type_ty	integer_type =
  {
  	type_class_integer,
  	"integer",
***************
*** 38,44 ****
  };
  
  
! type_t string_type =
  {
  	type_class_string,
  	"string",
--- 38,44 ----
  };
  
  
! type_ty string_type =
  {
  	type_class_string,
  	"string",
***************
*** 92,98 ****
  void
  string_write(name, this)
  	char		*name;
! 	string_t	*this;
  {
  	char		*s;
  	int		count;
--- 92,98 ----
  void
  string_write(name, this)
  	char		*name;
! 	string_ty	*this;
  {
  	char		*s;
  	int		count;
Index: aegis/io.h
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 26,35 ****
  #include <main.h>
  #include <type.h>
  
! extern type_t integer_type;
! extern type_t string_type;
  
! void string_write _((char *, string_t *));
  void integer_write _((char *, long));
  
  #endif /* IO_H */
--- 26,35 ----
  #include <main.h>
  #include <type.h>
  
! extern type_ty integer_type;
! extern type_ty string_type;
  
! void string_write _((char *, string_ty *));
  void integer_write _((char *, long));
  
  #endif /* IO_H */
Index: aegis/lex.c
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 25,30 ****
--- 25,31 ----
  #include <errno.h>
  
  #include <error.h>
+ #include <glue.h>
  #include <lex.h>
  #include <s-v-arg.h>
  #include <str.h>
***************
*** 42,50 ****
  
  void
  lex_open(s)
!     char            *s;
  {
! 	fp = fopen(s, "r");
  	if (!fp)
  		nfatal("open \"%s\"", s);
  	file_name = s;
--- 43,51 ----
  
  void
  lex_open(s)
! 	char		*s;
  {
! 	fp = glue_fopen(s, "r");
  	if (!fp)
  		nfatal("open \"%s\"", s);
  	file_name = s;
***************
*** 56,62 ****
  void
  lex_close()
  {
! 	fclose(fp);
  	fp = 0;
  	if (error_count)
  		fatal("%s: incorrect format", file_name);
--- 57,63 ----
  void
  lex_close()
  {
! 	glue_fclose(fp);
  	fp = 0;
  	if (error_count)
  		fatal("%s: incorrect format", file_name);
***************
*** 71,81 ****
  {
  	int		c;
  
! 	c = fgetc(fp);
  	switch (c)
  	{
  	case EOF:
! 		if (ferror(fp))
  		{
  			nerror("%s", file_name);
  			++error_count;
--- 72,82 ----
  {
  	int		c;
  
! 	c = glue_fgetc(fp);
  	switch (c)
  	{
  	case EOF:
! 		if (glue_ferror(fp))
  		{
  			nerror("%s", file_name);
  			++error_count;
***************
*** 115,121 ****
  		/* fall through... */
  
  	default:
! 		ungetc(c, fp);
  		break;
  	}
  }
--- 116,122 ----
  		/* fall through... */
  
  	default:
! 		glue_ungetc(c, fp);
  		break;
  	}
  }
Index: aegis/lex.h
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
Index: aegis/list.c
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 40,55 ****
  #include <word.h>
  
  
! typedef struct table_t table_t;
! struct table_t
  {
  	char	*name;
  	char	*description;
! 	void	(*func)_((string_t *, long));
  };
  
  
! static	table_t	table[] =
  {
  	{
  		"Administrators",
--- 40,55 ----
  #include <word.h>
  
  
! typedef struct table_ty table_ty;
! struct table_ty
  {
  	char	*name;
  	char	*description;
! 	void	(*func)_((string_ty *, long));
  };
  
  
! static	table_ty	table[] =
  {
  	{
  		"Administrators",
***************
*** 112,117 ****
--- 112,123 ----
  		list_reviewers,
  	},
  	{
+ 		"Users_Changes",
+ 		"List of changes owned by the current user",
+ 		list_user_changes,
+ 
+ 	},
+ 	{
  		"Version",
  		"List version of a project or change",
  		list_version,
***************
*** 145,151 ****
  "	%s -List - list (possibly) interesting things",
  "",
  "SYNOPSIS",
! "	%s -List [ <option>... ] <listname>",
  "	%s -List -List [ <option>... ]",
  "	%s -List -Help",
  "",
--- 151,157 ----
  "	%s -List - list (possibly) interesting things",
  "",
  "SYNOPSIS",
! "	%s -List [ <option>... ] <list-name>",
  "	%s -List -List [ <option>... ]",
  "	%s -List -Help",
  "",
***************
*** 158,164 ****
  "		List the administrators of a project.",
  "",
  "	Change_Details",
! "		List all information about a change in large layout form",
  "",
  "	Change_Files",
  "		List all files in a change.",
--- 164,171 ----
  "		List the administrators of a project.",
  "",
  "	Change_Details",
! "		List full information about a change in large",
! "		format.",
  "",
  "	Change_Files",
  "		List all files in a change.",
***************
*** 190,195 ****
--- 197,208 ----
  "	Reviewers",
  "		List the reviewers of a project.",
  "",
+ "	Users_Changes",
+ "		List of changes owned by the current user.",
+ "",
+ "	Version",
+ "		List version of a project or change.",
+ "",
  "	Most of these lists are available from other %s",
  "	functions.  Many %s functions provide more specific",
  "	lists.",
***************
*** 199,207 ****
  "",
  "	-Change <number>",
  "		This option may be used to specify a particular",
! "		change within a project.  If the user is only",
! "		working on one change within a project, that is",
! "		the default change number.",
  "",
  "	-Help",
  "		This option may be used to obtain more",
--- 212,226 ----
  "",
  "	-Change <number>",
  "		This option may be used to specify a particular",
! "		change within a project.  When no -Change option",
! "		is specified, the AEGIS_CHANGE environment",
! "		variable is consulted.  If that does not exist,",
! "		the user's $HOME/.%src file is examined for a",
! "		default change field (see aeuconf(5) for more",
! "		information).  If that does not exist, when the",
! "		user is only working on one change within a",
! "		project, that is the default change number.",
! "		Otherwise, it is an error.",
  "",
  "	-Help",
  "		This option may be used to obtain more",
***************
*** 214,227 ****
  "",
  "	-Project <name>",
  "		This option may be used to select the project of",
! "		interest.  When no -Project option is specified, if",
! "		the user is only working on changes within a single",
! "		project, the project name defaults to that project;",
! "		if the user is currently working on changes to more",
! "		than one project, or is not working on changes to",
! "		any project, the user's $HOME/.%src file is",
! "		examined for a default project field (see aeuconf(5)",
! "		for more information).",
  "",
  "	-TERse",
  "		This option may be used to cause listings to",
--- 233,247 ----
  "",
  "	-Project <name>",
  "		This option may be used to select the project of",
! "		interest.  When no -Project option is specified,",
! "		the AEGIS_PROJECT environment variable is",
! "		consulted.  If that does not exist, the user's",
! "		$HOME/.%src file is examined for a default",
! "		project field (see aeuconf(5) for more",
! "		information).  If that does not exist, when the",
! "		user is only working on changes within a single",
! "		project, the project name defaults to that",
! "		project.  Otherwise, it is an error.",
  "",
  "	-TERse",
  "		This option may be used to cause listings to",
***************
*** 237,257 ****
  "",
  "	-Page_Length <number>",
  "		This option may be used to set the page length of",
! "		listings.  The default, in order of preference, is",
! "		obtained from the system, from the LINES environment",
! "		variable, or set to 24 lines.",
  "",
  "	-Page_Width <number>",
  "		This option may be used to set the page width of",
! "		listings and error messages.  The default, in order",
! "		of preference, is obtained from the system, from the",
! "		COLS environment variable, or set to 79 characters.",
  "",
! "	All options are case insensitive.  Options may be",
! "	abbreviated; the abbreviation is the upper case letters.",
  "	Options and other command line arguments may be mixed",
! "	arbitrarily on the command line.",
  "",
  "RECOMMENDED ALIAS",
  "	The recommended alias for this command is",
  "	csh%%	alias ael '%s -l \\!* -v'",
--- 257,296 ----
  "",
  "	-Page_Length <number>",
  "		This option may be used to set the page length of",
! "		listings.  The default, in order of preference,",
! "		is obtained from the system, from the LINES",
! "		environment variable, or set to 24 lines.",
  "",
  "	-Page_Width <number>",
  "		This option may be used to set the page width of",
! "		listings and error messages.  The default, in",
! "		order of preference, is obtained from the system,",
! "		from the COLS environment variable, or set to 79",
! "		characters.",
  "",
! "	All options may be abbreviated; the abbreviation is",
! "	documented as the upper case letters, all lower case",
! "	letters and underscores (_) are optional.  You must use",
! "	consecutive sequences of optional letters.",
! "",
! "	All options are case insensitive, you may type them in",
! "	upper case or lower case or a combination of both, case",
! "	is not important.",
! "",
! "	For example: the arguments \"-project, \"-PROJ\" and \"-p\"",
! "	are all interpreted to mean the -Project option.  The",
! "	argument \"-prj\" will not be understood, because",
! "	consecutive optional characters were not supplied.",
! "",
  "	Options and other command line arguments may be mixed",
! "	arbitrarily on the command line, after the function",
! "	selectors.",
  "",
+ "	The GNU long option names are understood.  Since all",
+ "	option names for aegis are long, this means ignoring the",
+ "	extra leading '-'.  The \"--option=value\" convention is",
+ "	also understood.",
+ "",
  "RECOMMENDED ALIAS",
  "	The recommended alias for this command is",
  "	csh%%	alias ael '%s -l \\!* -v'",
***************
*** 262,268 ****
  "",
  "EXIT STATUS",
  "	The %s command will exit with a status of 1 on any",
! "	error.	The %s command will only exit with a status of",
  "	0 if there are no errors.",
  "",
  "COPYRIGHT",
--- 301,307 ----
  "",
  "EXIT STATUS",
  "	The %s command will exit with a status of 1 on any",
! "	error.  The %s command will only exit with a status of",
  "	0 if there are no errors.",
  "",
  "COPYRIGHT",
***************
*** 296,308 ****
  list_main()
  {
  	char		*listname;
! 	table_t		*tp;
  	int		j;
! 	table_t		*hit[SIZEOF(table)];
  	int		nhit;
! 	string_t	*s1;
! 	string_t	*s2;
! 	string_t	*project_name;
  	long		change_number;
  
  	trace(("list_main()\n{\n"/*}*/));
--- 335,347 ----
  list_main()
  {
  	char		*listname;
! 	table_ty		*tp;
  	int		j;
! 	table_ty		*hit[SIZEOF(table)];
  	int		nhit;
! 	string_ty	*s1;
! 	string_ty	*s2;
! 	string_ty	*project_name;
  	long		change_number;
  
  	trace(("list_main()\n{\n"/*}*/));
***************
*** 352,358 ****
  	nhit = 0;
  	for (tp = table; tp < ENDOF(table); ++tp)
  	{
! 		if (argcmp(tp->name, listname))
  			hit[nhit++] = tp;
  	}
  	switch (nhit)
--- 391,397 ----
  	nhit = 0;
  	for (tp = table; tp < ENDOF(table); ++tp)
  	{
! 		if (arglex_compare(tp->name, listname))
  			hit[nhit++] = tp;
  	}
  	switch (nhit)
***************
*** 409,419 ****
  	const void	*va;
  	const void	*vb;
  {
! 	string_t	*a;
! 	string_t	*b;
  
! 	a = *(string_t **)va;
! 	b = *(string_t **)vb;
  	return strcmp(a->str_text, b->str_text);
  }
  
--- 448,458 ----
  	const void	*va;
  	const void	*vb;
  {
! 	string_ty	*a;
! 	string_ty	*b;
  
! 	a = *(string_ty **)va;
! 	b = *(string_ty **)vb;
  	return strcmp(a->str_text, b->str_text);
  }
  
***************
*** 421,427 ****
  
  void
  list_projects(project_name, change_number)
! 	string_t	*project_name;
  	long		change_number;
  {
  	wlist		name;
--- 460,466 ----
  
  void
  list_projects(project_name, change_number)
! 	string_ty	*project_name;
  	long		change_number;
  {
  	wlist		name;
***************
*** 462,478 ****
  		col_heading(desc_col, "Description\n-------------");
  		for (j = 0; j < name.wl_nwords; ++j)
  		{
! 			project_t	*pp;
  
  			pp = project_alloc(name.wl_word[j]);
  			project_bind_existing(pp);
  			col_puts(name_col, project_name_get(pp)->str_text);
  			col_puts(dir_col, project_home_path_get(pp)->str_text);
! 			col_puts
! 			(
! 				desc_col,
! 				project_pstate_get(pp)->description->str_text
! 			);
  			project_free(pp);
  			col_eoln();
  		}
--- 501,527 ----
  		col_heading(desc_col, "Description\n-------------");
  		for (j = 0; j < name.wl_nwords; ++j)
  		{
! 			project_ty	*pp;
! 			int		err;
  
  			pp = project_alloc(name.wl_word[j]);
  			project_bind_existing(pp);
  			col_puts(name_col, project_name_get(pp)->str_text);
  			col_puts(dir_col, project_home_path_get(pp)->str_text);
! 			os_become_orig();
! 			err = os_readable(project_pstate_path_get(pp));
! 			os_become_undo();
! 			if (err)
! 				col_puts(desc_col, strerror(err));
! 			else
! 			{
! 				col_puts
! 				(
! 					desc_col,
! 					project_pstate_get(pp)->description->
! 						str_text
! 				);
! 			}
  			project_free(pp);
  			col_eoln();
  		}
***************
*** 484,496 ****
  
  void
  list_project_files(project_name, change_number)
! 	string_t	*project_name;
  	long		change_number;
  {
  	pstate		pstate_data;
! 	project_t	*pp;
! 	change_t	*cp;
! 	user_t		*up;
  
  	/*
  	 * locate project data
--- 533,545 ----
  
  void
  list_project_files(project_name, change_number)
! 	string_ty	*project_name;
  	long		change_number;
  {
  	pstate		pstate_data;
! 	project_ty	*pp;
! 	change_ty	*cp;
! 	user_ty		*up;
  
  	/*
  	 * locate project data
***************
*** 531,537 ****
  
  		if (!option_get_terse())
  		{
! 			string_t	*line1;
  
  			col_open((char *)0);
  			if (change_number)
--- 580,586 ----
  
  		if (!option_get_terse())
  		{
! 			string_ty	*line1;
  
  			col_open((char *)0);
  			if (change_number)
***************
*** 640,650 ****
  
  void
  list_administrators(project_name, change_number)
! 	string_t	*project_name;
  	long		change_number;
  {
  	pstate		pstate_data;
! 	project_t	*pp;
  
  	trace(("list_administrators()\n{\n"/*}*/));
  	if (change_number)
--- 689,699 ----
  
  void
  list_administrators(project_name, change_number)
! 	string_ty	*project_name;
  	long		change_number;
  {
  	pstate		pstate_data;
! 	project_ty	*pp;
  
  	trace(("list_administrators()\n{\n"/*}*/));
  	if (change_number)
***************
*** 681,687 ****
  		int		login_col;
  		int		name_col;
  		int		j;
! 		string_t	*line1;
  
  		col_open((char *)0);
  		line1 = str_format("Project \"%S\"", project_name);
--- 730,736 ----
  		int		login_col;
  		int		name_col;
  		int		j;
! 		string_ty	*line1;
  
  		col_open((char *)0);
  		line1 = str_format("Project \"%S\"", project_name);
***************
*** 694,700 ****
  		col_heading(name_col, "Full Name\n-----------");
  		for (j = 0; j < pstate_data->administrator->length; ++j)
  		{
! 			string_t	*logname;
  
  			logname = pstate_data->administrator->list[j];
  			col_puts(login_col, logname->str_text);
--- 743,749 ----
  		col_heading(name_col, "Full Name\n-----------");
  		for (j = 0; j < pstate_data->administrator->length; ++j)
  		{
! 			string_ty	*logname;
  
  			logname = pstate_data->administrator->list[j];
  			col_puts(login_col, logname->str_text);
***************
*** 712,724 ****
  
  void
  list_change_files(project_name, change_number)
! 	string_t	*project_name;
  	long		change_number;
  {
  	cstate		cstate_data;
! 	project_t	*pp;
! 	change_t	*cp;
! 	user_t		*up;
  
  	/*
  	 * locate project data
--- 761,773 ----
  
  void
  list_change_files(project_name, change_number)
! 	string_ty	*project_name;
  	long		change_number;
  {
  	cstate		cstate_data;
! 	project_ty	*pp;
! 	change_ty	*cp;
! 	user_ty		*up;
  
  	/*
  	 * locate project data
***************
*** 757,763 ****
  
  		if (!option_get_terse())
  		{
! 			string_t	*line1;
  
  			col_open((char *)0);
  			line1 = str_format("Project \"%S\"  Change %ld", project_name, change_number);
--- 806,812 ----
  
  		if (!option_get_terse())
  		{
! 			string_ty	*line1;
  
  			col_open((char *)0);
  			line1 = str_format("Project \"%S\"  Change %ld", project_name, change_number);
***************
*** 949,961 ****
  
  void
  list_change_history(project_name, change_number)
! 	string_t	*project_name;
  	long		change_number;
  {
  	cstate		cstate_data;
! 	project_t	*pp;
! 	change_t	*cp;
! 	user_t		*up;
  
  	/*
  	 * locate project data
--- 998,1010 ----
  
  void
  list_change_history(project_name, change_number)
! 	string_ty	*project_name;
  	long		change_number;
  {
  	cstate		cstate_data;
! 	project_ty	*pp;
! 	change_ty	*cp;
! 	user_ty		*up;
  
  	/*
  	 * locate project data
***************
*** 991,997 ****
  		int		who_col;
  		int		why_col;
  		int		j;
! 		string_t	*line1;
  
  		col_open((char *)0);
  		line1 = str_format("Project \"%S\"  Change %ld", project_name, change_number);
--- 1040,1046 ----
  		int		who_col;
  		int		why_col;
  		int		j;
! 		string_ty	*line1;
  
  		col_open((char *)0);
  		line1 = str_format("Project \"%S\"  Change %ld", project_name, change_number);
***************
*** 1056,1062 ****
  
  void
  list_changes_in_state_mask(project_name, state_mask)
! 	string_t	*project_name;
  	int		state_mask;
  {
  	pstate		pstate_data;
--- 1105,1111 ----
  
  void
  list_changes_in_state_mask(project_name, state_mask)
! 	string_ty	*project_name;
  	int		state_mask;
  {
  	pstate		pstate_data;
***************
*** 1065,1071 ****
  	int		description_col = 0;
  	int		state_col = 0;
  	int		j;
! 	project_t	*pp;
  
  	/*
  	 * locate project data
--- 1114,1120 ----
  	int		description_col = 0;
  	int		state_col = 0;
  	int		j;
! 	project_ty	*pp;
  
  	/*
  	 * locate project data
***************
*** 1085,1091 ****
  	{
  		cstate		cstate_data;
  		long		change_number;
! 		change_t	*cp;
  
  		change_number = pstate_data->change->list[j];
  		if (option_get_terse())
--- 1134,1140 ----
  	{
  		cstate		cstate_data;
  		long		change_number;
! 		change_ty	*cp;
  
  		change_number = pstate_data->change->list[j];
  		if (option_get_terse())
***************
*** 1100,1106 ****
  		{
  			if (!n)
  			{
! 				string_t	*line1;
  
  				col_open((char *)0);
  				line1 = str_format("Project \"%S\"", project_name);
--- 1149,1155 ----
  		{
  			if (!n)
  			{
! 				string_ty	*line1;
  
  				col_open((char *)0);
  				line1 = str_format("Project \"%S\"", project_name);
***************
*** 1142,1148 ****
  
  void
  list_changes(project_name, change_number)
! 	string_t	*project_name;
  	long		change_number;
  {
  	trace(("list_changes()\n{\n"/*}*/));
--- 1191,1197 ----
  
  void
  list_changes(project_name, change_number)
! 	string_ty	*project_name;
  	long		change_number;
  {
  	trace(("list_changes()\n{\n"/*}*/));
***************
*** 1155,1166 ****
  
  void
  list_list_list(project_name, change_number)
! 	string_t	*project_name;
  	long		change_number;
  {
  	int		name_col;
  	int		desc_col;
! 	table_t		*tp;
  
  	trace(("list_list_list()\n{\n"/*}*/));
  	if (project_name)
--- 1204,1215 ----
  
  void
  list_list_list(project_name, change_number)
! 	string_ty	*project_name;
  	long		change_number;
  {
  	int		name_col;
  	int		desc_col;
! 	table_ty		*tp;
  
  	trace(("list_list_list()\n{\n"/*}*/));
  	if (project_name)
***************
*** 1186,1196 ****
  
  void
  list_developers(project_name, change_number)
! 	string_t	*project_name;
  	long		change_number;
  {
  	pstate		pstate_data;
! 	project_t	*pp;
  
  	trace(("list_developers()\n{\n"/*}*/));
  	if (change_number)
--- 1235,1245 ----
  
  void
  list_developers(project_name, change_number)
! 	string_ty	*project_name;
  	long		change_number;
  {
  	pstate		pstate_data;
! 	project_ty	*pp;
  
  	trace(("list_developers()\n{\n"/*}*/));
  	if (change_number)
***************
*** 1227,1233 ****
  		int		login_col;
  		int		name_col;
  		int		j;
! 		string_t	*line1;
  
  		col_open((char *)0);
  		line1 = str_format("Project \"%S\"", project_name);
--- 1276,1282 ----
  		int		login_col;
  		int		name_col;
  		int		j;
! 		string_ty	*line1;
  
  		col_open((char *)0);
  		line1 = str_format("Project \"%S\"", project_name);
***************
*** 1240,1246 ****
  		col_heading(name_col, "Full Name\n-----------");
  		for (j = 0; j < pstate_data->developer->length; ++j)
  		{
! 			string_t	*logname;
  
  			logname = pstate_data->developer->list[j];
  			col_puts(login_col, logname->str_text);
--- 1289,1295 ----
  		col_heading(name_col, "Full Name\n-----------");
  		for (j = 0; j < pstate_data->developer->length; ++j)
  		{
! 			string_ty	*logname;
  
  			logname = pstate_data->developer->list[j];
  			col_puts(login_col, logname->str_text);
***************
*** 1258,1268 ****
  
  void
  list_integrators(project_name, change_number)
! 	string_t	*project_name;
  	long		change_number;
  {
  	pstate		pstate_data;
! 	project_t	*pp;
  
  	trace(("list_integrators()\n{\n"/*}*/));
  	if (change_number)
--- 1307,1317 ----
  
  void
  list_integrators(project_name, change_number)
! 	string_ty	*project_name;
  	long		change_number;
  {
  	pstate		pstate_data;
! 	project_ty	*pp;
  
  	trace(("list_integrators()\n{\n"/*}*/));
  	if (change_number)
***************
*** 1299,1305 ****
  		int		login_col;
  		int		name_col;
  		int		j;
! 		string_t	*line1;
  
  		col_open((char *)0);
  		line1 = str_format("Project \"%S\"", project_name);
--- 1348,1354 ----
  		int		login_col;
  		int		name_col;
  		int		j;
! 		string_ty	*line1;
  
  		col_open((char *)0);
  		line1 = str_format("Project \"%S\"", project_name);
***************
*** 1312,1318 ****
  		col_heading(name_col, "Full Name\n-----------");
  		for (j = 0; j < pstate_data->integrator->length; ++j)
  		{
! 			string_t	*logname;
  
  			logname = pstate_data->integrator->list[j];
  			col_puts(login_col, logname->str_text);
--- 1361,1367 ----
  		col_heading(name_col, "Full Name\n-----------");
  		for (j = 0; j < pstate_data->integrator->length; ++j)
  		{
! 			string_ty	*logname;
  
  			logname = pstate_data->integrator->list[j];
  			col_puts(login_col, logname->str_text);
***************
*** 1330,1340 ****
  
  void
  list_reviewers(project_name, change_number)
! 	string_t	*project_name;
  	long		change_number;
  {
  	pstate		pstate_data;
! 	project_t	*pp;
  
  	trace(("list_reviewers()\n{\n"/*}*/));
  	if (change_number)
--- 1379,1389 ----
  
  void
  list_reviewers(project_name, change_number)
! 	string_ty	*project_name;
  	long		change_number;
  {
  	pstate		pstate_data;
! 	project_ty	*pp;
  
  	trace(("list_reviewers()\n{\n"/*}*/));
  	if (change_number)
***************
*** 1371,1377 ****
  		int		login_col;
  		int		name_col;
  		int		j;
! 		string_t	*line1;
  
  		col_open((char *)0);
  		line1 = str_format("Project \"%S\"", project_name);
--- 1420,1426 ----
  		int		login_col;
  		int		name_col;
  		int		j;
! 		string_ty	*line1;
  
  		col_open((char *)0);
  		line1 = str_format("Project \"%S\"", project_name);
***************
*** 1384,1390 ****
  		col_heading(name_col, "Full Name\n-----------");
  		for (j = 0; j < pstate_data->reviewer->length; ++j)
  		{
! 			string_t	*logname;
  
  			logname = pstate_data->reviewer->list[j];
  			col_puts(login_col, logname->str_text);
--- 1433,1439 ----
  		col_heading(name_col, "Full Name\n-----------");
  		for (j = 0; j < pstate_data->reviewer->length; ++j)
  		{
! 			string_ty	*logname;
  
  			logname = pstate_data->reviewer->list[j];
  			col_puts(login_col, logname->str_text);
***************
*** 1402,1408 ****
  
  void
  list_project_history(project_name, change_number)
! 	string_t	*project_name;
  	long		change_number;
  {
  	pstate		pstate_data;
--- 1451,1457 ----
  
  void
  list_project_history(project_name, change_number)
! 	string_ty	*project_name;
  	long		change_number;
  {
  	pstate		pstate_data;
***************
*** 1412,1418 ****
  	int		change_col = 0;
  	int		description_col = 0;
  	int		j;
! 	project_t	*pp;
  
  	trace(("list_project_history()\n{\n"/*}*/));
  	if (change_number)
--- 1461,1467 ----
  	int		change_col = 0;
  	int		description_col = 0;
  	int		j;
! 	project_ty	*pp;
  
  	trace(("list_project_history()\n{\n"/*}*/));
  	if (change_number)
***************
*** 1436,1442 ****
  		cstate		cstate_data;
  		pstate_history	history_data;
  		time_t		t;
! 		change_t	*cp;
  
  		history_data = pstate_data->history->list[j];
  		if (option_get_terse())
--- 1485,1491 ----
  		cstate		cstate_data;
  		pstate_history	history_data;
  		time_t		t;
! 		change_ty	*cp;
  
  		history_data = pstate_data->history->list[j];
  		if (option_get_terse())
***************
*** 1449,1455 ****
  		cstate_data = change_cstate_get(cp);
  		if (!n)
  		{
! 			string_t	*line1;
  
  			col_open((char *)0);
  			line1 = str_format("Project \"%S\"", project_name);
--- 1498,1504 ----
  		cstate_data = change_cstate_get(cp);
  		if (!n)
  		{
! 			string_ty	*line1;
  
  			col_open((char *)0);
  			line1 = str_format("Project \"%S\"", project_name);
***************
*** 1490,1503 ****
  
  void
  list_version(project_name, change_number)
! 	string_t	*project_name;
  	long		change_number;
  {
  	pstate		pstate_data;
! 	project_t	*pp;
  	cstate		cstate_data;
! 	change_t	*cp;
! 	user_t		*up;
  
  	/*
  	 * locate project data
--- 1539,1552 ----
  
  void
  list_version(project_name, change_number)
! 	string_ty	*project_name;
  	long		change_number;
  {
  	pstate		pstate_data;
! 	project_ty	*pp;
  	cstate		cstate_data;
! 	change_ty	*cp;
! 	user_ty		*up;
  
  	/*
  	 * locate project data
***************
*** 1581,1597 ****
  
  void
  list_change_details(project_name, change_number)
! 	string_t	*project_name;
  	long		change_number;
  {
  	int		j;
  	int		head_col;
  	int		body_col;
! 	project_t	*pp;
! 	change_t	*cp;
  	cstate		cstate_data;
! 	user_t		*up;
! 	string_t	*line1;
  
  	/*
  	 * locate project data
--- 1630,1646 ----
  
  void
  list_change_details(project_name, change_number)
! 	string_ty	*project_name;
  	long		change_number;
  {
  	int		j;
  	int		head_col;
  	int		body_col;
! 	project_ty	*pp;
! 	change_ty	*cp;
  	cstate		cstate_data;
! 	user_ty		*up;
! 	string_ty	*line1;
  
  	/*
  	 * locate project data
***************
*** 1902,1906 ****
--- 1951,2110 ----
  	change_free(cp);
  	project_free(pp);
  	user_free(up);
+ 	trace((/*{*/"}\n"));
+ }
+ 
+ 
+ void
+ list_user_changes(project_name, change_number)
+ 	string_ty	*project_name;
+ 	long		change_number;
+ {
+ 	user_ty		*up;
+ 	int		project_col;
+ 	int		change_col;
+ 	int		state_col;
+ 	int		description_col;
+ 	string_ty	*s;
+ 	wlist		name;
+ 	long		j;
+ 
+ 	trace(("list_user_changes()\n{\n"/*}*/));
+ 	if (project_name)
+ 		fatal("inappropriate -Project option");
+ 	if (change_number)
+ 		fatal("inappropriate -Change option");
+ 
+ 
+ 	/*
+ 	 * get the list of projects
+ 	 */
+ 	gonzo_project_list(&name);
+ 	if (!name.wl_nwords)
+ 	{
+ 		verbose("there are no projects");
+ 		goto done;
+ 	}
+ 
+ 	/*
+ 	 * sort the list so the listing is pretty
+ 	 */
+ 	qsort
+ 	(
+ 		name.wl_word,
+ 		name.wl_nwords,
+ 		sizeof(name.wl_word[0]),
+ 		name_cmp
+ 	);
+ 
+ 	/*
+ 	 * open listing
+ 	 */
+ 	col_open((char *)0);
+ 	up = user_executing((project_ty *)0);
+ 	s = str_format("Owned by %S <%S>", up->full_name, user_name(up));
+ 	user_free(up);
+ 	col_title("List of Changes", s->str_text);
+ 	str_free(s);
+ 
+ 	/*
+ 	 * create the columns
+ 	 */
+ 	project_col = col_create(0, 10);
+ 	change_col = col_create(11, 17);
+ 	state_col = col_create(18, 28);
+ 	description_col = col_create(29, 0);
+ 	col_heading(project_col, "Project\n----------");
+ 	col_heading(change_col, "Change\n------");
+ 	col_heading(state_col, "State\n----------");
+ 	col_heading(description_col, "Description\n-------------");
+ 
+ 	/*
+ 	 * for each project, see if the current user
+ 	 * is working on any of them.
+ 	 */
+ 	for (j = 0; j < name.wl_nwords; ++j)
+ 	{
+ 		project_ty	*pp;
+ 		int		err;
+ 		long		n;
+ 
+ 		/*
+ 		 * locate the project,
+ 		 * and make sure we are allowed to look at it
+ 		 */
+ 		pp = project_alloc(name.wl_word[j]);
+ 		project_bind_existing(pp);
+ 		os_become_orig();
+ 		err = os_readable(project_pstate_path_get(pp));
+ 		os_become_undo();
+ 		if (err)
+ 		{
+ 			project_free(pp);
+ 			continue;
+ 		}
+ 
+ 		/*
+ 		 * bind a user to that project
+ 		 */
+ 		up = user_executing(pp);
+ 
+ 		/*
+ 		 * for each change within this project the user
+ 		 * is working on emit a line of information
+ 		 */
+ 		for (n = 0; ; ++n)
+ 		{
+ 			change_ty	*cp;
+ 			cstate		cstate_data;
+ 
+ 			if (!user_own_nth(up, n, &change_number))
+ 				break;
+ 			
+ 			/*
+ 			 * locate change data
+ 			 */
+ 			cp = change_alloc(pp, change_number);
+ 			change_bind_existing(cp);
+ 	
+ 			/*
+ 			 * emit the info
+ 			 */
+ 			col_puts(project_col, project_name_get(pp)->str_text);
+ 			col_printf(change_col, "%4ld", change_number);
+ 			cstate_data = change_cstate_get(cp);
+ 			col_puts
+ 			(
+ 				state_col,
+ 				cstate_state_ename(cstate_data->state)
+ 			);
+ 			if (cstate_data->brief_description)
+ 			{
+ 				col_puts
+ 				(
+ 					description_col,
+ 					cstate_data->brief_description->str_text
+ 				);
+ 			}
+ 			col_eoln();
+ 	
+ 			/*
+ 			 * release change and project
+ 			 */
+ 			change_free(cp);
+ 		}
+ 
+ 		/*
+ 		 * free user and project
+ 		 */
+ 		user_free(up);
+ 		project_free(pp);
+ 	}
+ 
+ 	/*
+ 	 * clean up and go home
+ 	 */
+ 	col_close();
+ 	done:
  	trace((/*{*/"}\n"));
  }
Index: aegis/list.h
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 25,47 ****
  
  #include <main.h>
  
! struct string_t;
  
  void list _((void));
  
! void list_administrators _((struct string_t *, long));
! void list_change_details _((struct string_t *, long));
! void list_change_files _((struct string_t *, long));
! void list_change_history _((struct string_t *, long));
! void list_changes_in_state_mask _((struct string_t *, int state_mask));
! void list_changes _((struct string_t *, long));
! void list_developers _((struct string_t *, long));
! void list_integrators _((struct string_t *, long));
! void list_list_list _((struct string_t *, long));
! void list_project_files _((struct string_t *, long));
! void list_project_history _((struct string_t *, long));
! void list_projects _((struct string_t *, long));
! void list_reviewers _((struct string_t *, long));
! void list_version _((struct string_t *, long));
  
  #endif /* LIST_H */
--- 25,48 ----
  
  #include <main.h>
  
! struct string_ty;
  
  void list _((void));
  
! void list_administrators _((struct string_ty *, long));
! void list_change_details _((struct string_ty *, long));
! void list_change_files _((struct string_ty *, long));
! void list_change_history _((struct string_ty *, long));
! void list_changes_in_state_mask _((struct string_ty *, int state_mask));
! void list_changes _((struct string_ty *, long));
! void list_developers _((struct string_ty *, long));
! void list_integrators _((struct string_ty *, long));
! void list_list_list _((struct string_ty *, long));
! void list_project_files _((struct string_ty *, long));
! void list_project_history _((struct string_ty *, long));
! void list_projects _((struct string_ty *, long));
! void list_reviewers _((struct string_ty *, long));
! void list_user_changes _((struct string_ty *, long));
! void list_version _((struct string_ty *, long));
  
  #endif /* LIST_H */
Index: aegis/lock.c
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 27,38 ****
  #include <string.h>
  
  #include <error.h>
  #include <lock.h>
  #include <mem.h>
! #include <gonzo.h>
  #include <trace.h>
  
  
  enum lock_ty
  {
  	lock_master,
--- 27,47 ----
  #include <string.h>
  
  #include <error.h>
+ #include <glue.h>
+ #include <gonzo.h>
  #include <lock.h>
  #include <mem.h>
! #include <os.h>
  #include <trace.h>
  
  
+ /*
+  * how many bits of the hash to use in the mux
+  */
+ #define BITS 16
+ #define BITS_SIZE (1L << BITS)
+ #define BITS_MASK (BITS_SIZE - 1)
+ 
  enum lock_ty
  {
  	lock_master,
***************
*** 41,56 ****
  };
  typedef enum lock_ty lock_ty;
  
! enum lock_mux_t
  {
  	lock_mux_ustate,
  	lock_mux_pstate,
  	lock_mux_cstate,
  	lock_mux_MAX
  };
! typedef enum lock_mux_t lock_mux_t;
  
  
  static	size_t		nplaces;
  static	struct flock	*place;
  static	int		fd = -1;
--- 50,67 ----
  };
  typedef enum lock_ty lock_ty;
  
! enum lock_mux_ty
  {
  	lock_mux_ustate,
  	lock_mux_pstate,
  	lock_mux_cstate,
+ 	lock_mux_build,
  	lock_mux_MAX
  };
! typedef enum lock_mux_ty lock_mux_ty;
  
  
+ static	string_ty	*path;
  static	size_t		nplaces;
  static	struct flock	*place;
  static	int		fd = -1;
***************
*** 86,104 ****
  }
  
  
! static void lock_prepare _((long, long));
  
  static void
! lock_prepare(start, length)
  	long		start;
  	long		length;
  {
  	struct flock	p;
  
! 	trace(("lock_prepare(start = %ld, length = %ld)\n{\n"/*}*/, start, length));
  	assert(start > lock_master);
  	assert(length > 0);
! 	flock_construct(&p, F_WRLCK, start, length);
  	*(struct flock *)
  	enlarge(&nplaces, (char **)&place, sizeof(struct flock)) =
  		p;
--- 97,117 ----
  }
  
  
! static void lock_prepare _((long, long, int));
  
  static void
! lock_prepare(start, length, exclusive)
  	long		start;
  	long		length;
+ 	int		exclusive;
  {
  	struct flock	p;
  
! 	trace(("lock_prepare(start = %ld, length = %ld, excl = %d)\n{\n"/*}*/,
! 		start, length, exclusive));
  	assert(start > lock_master);
  	assert(length > 0);
! 	flock_construct(&p, (exclusive ? F_WRLCK : F_RDLCK), start, length);
  	*(struct flock *)
  	enlarge(&nplaces, (char **)&place, sizeof(struct flock)) =
  		p;
***************
*** 110,141 ****
  lock_prepare_gstate()
  {
  	trace(("lock_prepare_gstate()\n{\n"/*}*/));
! 	lock_prepare((long)lock_gstate, 1L);
  	trace((/*{*/"}\n"));
  }
  
  
! static void lock_prepare_mux _((lock_mux_t, long));
  
  static void
! lock_prepare_mux(lock_mux, n)
! 	lock_mux_t	lock_mux;
  	long		n;
  {
! 	trace(("lock_prepare_mux(lock_mux = %d, n = %ld)\n{\n"/*}*/, lock_mux, n));
! 	lock_prepare(((lock_mux + 1L) << 16) + (n & 0xFFFF), 1L);
  	trace((/*{*/"}\n"));
  }
  
  
! static void lock_prepare_mux_all _((lock_mux_t));
  
  static void
! lock_prepare_mux_all(lock_mux)
! 	lock_mux_t	lock_mux;
  {
  	trace(("lock_prepare_mux_all(lock_mux = %d)\n{\n"/*}*/, lock_mux));
! 	lock_prepare(((lock_mux + 1L) << 16), 0x10000L);
  	trace((/*{*/"}\n"));
  }
  
--- 123,162 ----
  lock_prepare_gstate()
  {
  	trace(("lock_prepare_gstate()\n{\n"/*}*/));
! 	lock_prepare((long)lock_gstate, 1L, 1);
  	trace((/*{*/"}\n"));
  }
  
  
! static void lock_prepare_mux _((lock_mux_ty, long, int));
  
  static void
! lock_prepare_mux(lock_mux, n, exclusive)
! 	lock_mux_ty	lock_mux;
  	long		n;
+ 	int		exclusive;
  {
! 	trace(("lock_prepare_mux(lock_mux = %d, n = %ld, excl = %d)\n{\n"/*}*/,
! 		lock_mux, n, exclusive));
! 	lock_prepare
! 	(
! 		((lock_mux + 1L) << BITS) + (n & BITS_MASK),
! 		1L,
! 		exclusive
! 	);
  	trace((/*{*/"}\n"));
  }
  
  
! static void lock_prepare_mux_all _((lock_mux_ty, int));
  
  static void
! lock_prepare_mux_all(lock_mux, exclusive)
! 	lock_mux_ty	lock_mux;
! 	int		exclusive;
  {
  	trace(("lock_prepare_mux_all(lock_mux = %d)\n{\n"/*}*/, lock_mux));
! 	lock_prepare(((lock_mux + 1L) << BITS), BITS_SIZE, exclusive);
  	trace((/*{*/"}\n"));
  }
  
***************
*** 142,161 ****
  
  void
  lock_prepare_pstate(s)
! 	string_t	*s;
  {
  	trace(("lock_prepare_pstate(s = \"%s\")\n{\n"/*}*/, s->str_text));
! 	lock_prepare_mux(lock_mux_pstate, (long)s->str_hash);
  	trace((/*{*/"}\n"));
  }
  
  
  void
  lock_prepare_ustate(uid)
  	int		uid;
  {
  	trace(("lock_prepare_ustate()\n{\n"/*}*/));
! 	lock_prepare_mux(lock_mux_ustate, (long)uid);
  	trace((/*{*/"}\n"));
  }
  
--- 163,202 ----
  
  void
  lock_prepare_pstate(s)
! 	string_ty	*s;
  {
  	trace(("lock_prepare_pstate(s = \"%s\")\n{\n"/*}*/, s->str_text));
! 	lock_prepare_mux(lock_mux_pstate, (long)s->str_hash, 1);
  	trace((/*{*/"}\n"));
  }
  
  
  void
+ lock_prepare_build_read(s)
+ 	string_ty	*s;
+ {
+ 	trace(("lock_prepare_pstate(s = \"%s\")\n{\n"/*}*/, s->str_text));
+ 	lock_prepare_mux(lock_mux_build, (long)s->str_hash, 0);
+ 	trace((/*{*/"}\n"));
+ }
+ 
+ 
+ void
+ lock_prepare_build_write(s)
+ 	string_ty	*s;
+ {
+ 	trace(("lock_prepare_pstate(s = \"%s\")\n{\n"/*}*/, s->str_text));
+ 	lock_prepare_mux(lock_mux_build, (long)s->str_hash, 1);
+ 	trace((/*{*/"}\n"));
+ }
+ 
+ 
+ void
  lock_prepare_ustate(uid)
  	int		uid;
  {
  	trace(("lock_prepare_ustate()\n{\n"/*}*/));
! 	lock_prepare_mux(lock_mux_ustate, (long)uid, 1);
  	trace((/*{*/"}\n"));
  }
  
***************
*** 164,170 ****
  lock_prepare_ustate_all()
  {
  	trace(("lock_prepare_ustate_all()\n{\n"/*}*/));
! 	lock_prepare_mux_all(lock_mux_ustate);
  	trace((/*{*/"}\n"));
  }
  
--- 205,211 ----
  lock_prepare_ustate_all()
  {
  	trace(("lock_prepare_ustate_all()\n{\n"/*}*/));
! 	lock_prepare_mux_all(lock_mux_ustate, 1);
  	trace((/*{*/"}\n"));
  }
  
***************
*** 171,184 ****
  
  void
  lock_prepare_cstate(project_name, change_number)
! 	string_t	*project_name;
  	long		change_number;
  {
! 	trace(("lock_prepare_cstate(project_name = \"%s\", change_number = %ld)\n{\n"/*}*/, project_name->str_text, change_number));
  	lock_prepare_mux
  	(
  		lock_mux_cstate,
! 		change_number + project_name->str_hash
  	);
  	trace((/*{*/"}\n"));
  }
--- 212,227 ----
  
  void
  lock_prepare_cstate(project_name, change_number)
! 	string_ty	*project_name;
  	long		change_number;
  {
! 	trace(("lock_prepare_cstate(project_name = \"%s\", change_number = \
! %ld)\n{\n"/*}*/, project_name->str_text, change_number));
  	lock_prepare_mux
  	(
  		lock_mux_cstate,
! 		change_number + project_name->str_hash,
! 		1
  	);
  	trace((/*{*/"}\n"));
  }
***************
*** 248,260 ****
  }
  
  
  void
  lock_take()
  {
- 	string_t	*path;
  	int		flags;
  	struct flock	p;
  	int		j, k;
  
  	/*
  	 * get the file descriptor of the lock file
--- 291,350 ----
  }
  
  
+ static char *lock_description _((struct flock *));
+ 
+ static char *
+ lock_description(p)
+ 	struct flock	*p;
+ {
+ 	switch (p->l_start)
+ 	{
+ 	case lock_master:
+ 		return "master";
+ 
+ 	case lock_gstate:
+ 		return "global state";
+ 	}
+ 	switch ((p->l_start >> BITS) - 1)
+ 	{
+ 	case lock_mux_ustate:
+ 		return "user";
+ 
+ 	case lock_mux_cstate:
+ 		return "change";
+ 
+ 	case lock_mux_pstate:
+ 		return "project";
+ 
+ 	case lock_mux_build:
+ 		return "build";
+ 	}
+ 	return "unknown";
+ }
+ 
+ 
+ static void quitter _((int));
+ 
+ static void
+ quitter(n)
+ 	int	n;
+ {
+ 	if (fd >= 0)
+ 	{
+ 		while (os_become_active())
+ 			os_become_undo();
+ 		lock_release();
+ 	}
+ }
+ 
+ 
  void
  lock_take()
  {
  	int		flags;
  	struct flock	p;
  	int		j, k;
+ 	static int 	quitregd;
  
  	/*
  	 * get the file descriptor of the lock file
***************
*** 265,296 ****
  	trace(("lock_take()\n{\n"/*}*/));
  	assert(fd < 0);
  	assert(nplaces);
! 	path = gonzo_lockpath_get();
  	gonzo_become();
! 	fd = open(path->str_text, O_RDWR | O_CREAT | O_TRUNC, 0600);
  	if (fd < 0)
  		nfatal("open(\"%s\")", path->str_text);
- 	gonzo_become_undo();
  	trace_int(fd);
  
  	/*
  	 * make sure the file is closed when a child exec's
  	 */
  	if (fcntl(fd, F_GETFD, &flags))
  		nfatal("fcntl(\"%s\", F_GETFD)", path->str_text);
  	flags |= 1;
  	if (fcntl(fd, F_SETFD, flags))
  		nfatal("fcntl(\"%s\", F_SETFD, %d)", path->str_text, flags);
  
  	/*
! 	 * block fo the master lock.
! 	 * take the locks we really want.
! 	 * if we got them, release master and return.
  	 * release the locks we could get and then the master.
! 	 * block on the lock we could not get.
! 	 * release that lock and styart again.
  	 *
! 	 * unfortunately, this scheme isn't fair
  	 * (i.e. no guarantee of success in finite time)
  	 * it would be nice if I could atomically lock (and block)
  	 * an entire vector of locks.  (vfcntl like berkeley's vwrite?)
--- 355,395 ----
  	trace(("lock_take()\n{\n"/*}*/));
  	assert(fd < 0);
  	assert(nplaces);
! 	if (!quitregd)
! 	{
! 		quitregd = 1;
! 		quit_register(quitter);
! 	}
! 	if (!path)
! 		path = gonzo_lockpath_get();
  	gonzo_become();
! 	fd = glue_open(path->str_text, O_RDWR | O_CREAT | O_TRUNC, 0600);
  	if (fd < 0)
  		nfatal("open(\"%s\")", path->str_text);
  	trace_int(fd);
  
  	/*
  	 * make sure the file is closed when a child exec's
  	 */
+ #ifndef CONF_NO_seteuid
  	if (fcntl(fd, F_GETFD, &flags))
  		nfatal("fcntl(\"%s\", F_GETFD)", path->str_text);
  	flags |= 1;
  	if (fcntl(fd, F_SETFD, flags))
  		nfatal("fcntl(\"%s\", F_SETFD, %d)", path->str_text, flags);
+ 	trace(("mark\n"));
+ #endif
  
  	/*
! 	 * Block for the master lock.
! 	 * Take the locks we really want.
! 	 * If we got them, release master and return.
! 	 * If did not get all of the locks,
  	 * release the locks we could get and then the master.
! 	 * Block on the lock we could not get,
! 	 * release that lock and start again.
  	 *
! 	 * Unfortunately, this scheme isn't fair
  	 * (i.e. no guarantee of success in finite time)
  	 * it would be nice if I could atomically lock (and block)
  	 * an entire vector of locks.  (vfcntl like berkeley's vwrite?)
***************
*** 302,309 ****
  		 * (block if necessary,
  		 * it should never be held for long)
  		 */
  		flock_construct(&p, F_WRLCK, (long)lock_master, 1L);
! 		if (fcntl(fd, F_SETLKW, &p))
  		{
  			nfatal
  			(
--- 401,409 ----
  		 * (block if necessary,
  		 * it should never be held for long)
  		 */
+ 		trace(("mark\n"));
  		flock_construct(&p, F_WRLCK, (long)lock_master, 1L);
! 		if (glue_fcntl(fd, F_SETLKW, &p))
  		{
  			nfatal
  			(
***************
*** 318,325 ****
  		 */
  		for (j = 0; j < nplaces; ++j)
  		{
  			p = place[j];
! 			if (fcntl(fd, F_SETLK, &p))
  			{
  				if (errno != EACCES && errno != EAGAIN)
  				{
--- 418,426 ----
  		 */
  		for (j = 0; j < nplaces; ++j)
  		{
+ 			trace(("mark\n"));
  			p = place[j];
! 			if (glue_fcntl(fd, F_SETLK, &p))
  			{
  				if (errno != EACCES && errno != EAGAIN)
  				{
***************
*** 339,346 ****
  		 */
  		if (j >= nplaces)
  		{
  			flock_construct(&p, F_UNLCK, (long)lock_master, 1L);
! 			if (fcntl(fd, F_SETLKW, &p))
  			{
  				nfatal
  				(
--- 440,448 ----
  		 */
  		if (j >= nplaces)
  		{
+ 			trace(("mark\n"));
  			flock_construct(&p, F_UNLCK, (long)lock_master, 1L);
! 			if (glue_fcntl(fd, F_SETLKW, &p))
  			{
  				nfatal
  				(
***************
*** 358,370 ****
  		 */
  		for (k = 0; k < j; ++k)
  		{
  			p = place[k];
! 			p.l_type =  F_UNLCK;
! 			if (fcntl(fd, F_SETLK, &p))
  			{
  				nfatal
  				(
! 					"fcntl(\"%s\", F_SETLK, %s)",
  					path->str_text,
  					flock_string(&p)
  				);
--- 460,473 ----
  		 */
  		for (k = 0; k < j; ++k)
  		{
+ 			trace(("mark\n"));
  			p = place[k];
! 			p.l_type = F_UNLCK;
! 			if (glue_fcntl(fd, F_SETLKW, &p))
  			{
  				nfatal
  				(
! 					"fcntl(\"%s\", F_SETLKW, %s)",
  					path->str_text,
  					flock_string(&p)
  				);
***************
*** 375,381 ****
  		 * release the master lock
  		 */
  		flock_construct(&p, F_UNLCK, (long)lock_master, 1L);
! 		if (fcntl(fd, F_SETLKW, &p))
  		{
  			nfatal
  			(
--- 478,484 ----
  		 * release the master lock
  		 */
  		flock_construct(&p, F_UNLCK, (long)lock_master, 1L);
! 		if (glue_fcntl(fd, F_SETLKW, &p))
  		{
  			nfatal
  			(
***************
*** 384,395 ****
  				flock_string(&p)
  			);
  		}
  
  		/*
! 		 * block on the lock that stopped us before
  		 */
  		p = place[j];
! 		if (fcntl(fd, F_SETLKW, &p))
  		{
  			nfatal
  			(
--- 487,504 ----
  				flock_string(&p)
  			);
  		}
+ 		trace(("mark\n"));
  
  		/*
! 		 * verbose message about why we are blocking
  		 */
  		p = place[j];
! 		verbose("waiting for %s lock", lock_description(&p));
! 
! 		/*
! 		 * block on the lock that stopped us before
! 		 */
! 		if (glue_fcntl(fd, F_SETLKW, &p))
  		{
  			nfatal
  			(
***************
*** 405,411 ****
  		 */
  		p = place[j];
  		p.l_type = F_UNLCK;
! 		if (fcntl(fd, F_SETLKW, &p))
  		{
  			nfatal
  			(
--- 514,520 ----
  		 */
  		p = place[j];
  		p.l_type = F_UNLCK;
! 		if (glue_fcntl(fd, F_SETLKW, &p))
  		{
  			nfatal
  			(
***************
*** 414,420 ****
--- 523,531 ----
  				flock_string(&p)
  			);
  		}
+ 		trace(("mark\n"));
  	}
+ 	gonzo_become_undo();
  	magic++;
  	trace((/*{*/"}\n"));
  }
***************
*** 423,436 ****
  void
  lock_release()
  {
  	trace(("lock_release()\n{\n"/*}*/));
  	trace_int(fd);
  	assert(fd >= 0);
- 	close(fd);
- 	fd = -1;
  	assert(nplaces);
- 	nplaces = 0;
  	assert(place);
  	mem_free((char *)place);
  	place = 0;
  	trace((/*{*/"}\n"));
--- 534,585 ----
  void
  lock_release()
  {
+ 	struct flock	p;
+ 	int		j;
+ 	int		fildes;
+ 
+ 	/*
+ 	 * set the file descriptor to -1
+ 	 * so that we will not be invoked again should
+ 	 * a fatal error happen here.
+ 	 */
  	trace(("lock_release()\n{\n"/*}*/));
  	trace_int(fd);
  	assert(fd >= 0);
  	assert(nplaces);
  	assert(place);
+ 	assert(path);
+ 	gonzo_become();
+ 	fildes = fd;
+ 	fd = -1;
+ 
+ 	/*
+ 	 * Release each of the locks.
+ 	 * This should be unnecessary, because we then close the file,
+ 	 * but SunOS hangs onto some of them, even after the process dies.
+ 	 */
+ 	for (j = 0; j < nplaces; ++j)
+ 	{
+ 		p = place[j];
+ 		p.l_type = F_UNLCK;
+ 		if (glue_fcntl(fildes, F_SETLKW, &p))
+ 		{
+ 			nfatal
+ 			(
+ 				"fcntl(\"%s\", F_SETLKW, %s)",
+ 				path->str_text,
+ 				flock_string(&p)
+ 			);
+ 		}
+ 	}
+ 
+ 	/*
+ 	 * close the file
+ 	 * (this *should* have been enough)
+ 	 */
+ 	glue_close(fildes);
+ 	gonzo_become_undo();
+ 	nplaces = 0;
  	mem_free((char *)place);
  	place = 0;
  	trace((/*{*/"}\n"));
Index: aegis/lock.h
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 25,39 ****
  
  #include <main.h>
  
! struct string_t;
  
  void lock_prepare_gstate _((void));
! void lock_prepare_pstate _((struct string_t *project_name));
  void lock_prepare_ustate _((int uid));
  void lock_prepare_ustate_all _((void));
! void lock_prepare_cstate _((struct string_t *project_name, long change_number));
  void lock_take _((void));
  void lock_release _((void));
  long lock_magic _((void));
  
  #endif /* LOCK_H */
--- 25,41 ----
  
  #include <main.h>
  
! struct string_ty;
  
  void lock_prepare_gstate _((void));
! void lock_prepare_pstate _((struct string_ty *project_name));
  void lock_prepare_ustate _((int uid));
  void lock_prepare_ustate_all _((void));
! void lock_prepare_cstate _((struct string_ty *project_name, long change_number));
  void lock_take _((void));
  void lock_release _((void));
  long lock_magic _((void));
+ void lock_prepare_build_read _((struct string_ty *project_name));
+ void lock_prepare_build_write _((struct string_ty *project_name));
  
  #endif /* LOCK_H */
Index: aegis/log.c
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 42,48 ****
   *	log_open - start logging
   *
   *  SYNOPSIS
!  *	void log_open(string_t *logfile, user_t *up);
   *
   *  DESCRIPTION
   *	The log_open function is used to start sending stdout
--- 42,48 ----
   *	log_open - start logging
   *
   *  SYNOPSIS
!  *	void log_open(string_ty *logfile, user_ty *up);
   *
   *  DESCRIPTION
   *	The log_open function is used to start sending stdout
***************
*** 52,59 ****
  
  void
  log_open(log, up)
! 	string_t	*log;
! 	user_t		*up;
  {
  	static int	already_done;
  	int		fd[2];
--- 52,59 ----
  
  void
  log_open(log, up)
! 	string_ty	*log;
! 	user_ty		*up;
  {
  	static int	already_done;
  	int		fd[2];
***************
*** 173,189 ****
  {
  	if (pid > 0)
  	{
  		fclose(stdout);
  		fclose(stderr);
! 		for (;;)
! 		{
! 			int	who;
! 			int	status;
! 
! 			who = wait(&status);
! 			if (who < 0 || who == pid)
! 				break;
! 		}
  		pid = 0;
  	}
  }
--- 173,183 ----
  {
  	if (pid > 0)
  	{
+ 		int	status;
+ 
  		fclose(stdout);
  		fclose(stderr);
! 		os_waitpid(pid, &status);
  		pid = 0;
  	}
  }
Index: aegis/log.h
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 25,34 ****
  
  #include <main.h>
  
! struct string_t;
! struct user_t;
  
! void log_open _((struct string_t *, struct user_t *));
  void log_close _((void));
  void log_quitter _((int));
  
--- 25,34 ----
  
  #include <main.h>
  
! struct string_ty;
! struct user_ty;
  
! void log_open _((struct string_ty *, struct user_ty *));
  void log_close _((void));
  void log_quitter _((int));
  
Index: aegis/main.c
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 49,54 ****
--- 49,55 ----
  #include <os.h>
  #include <pattr_ed.h>
  #include <rem_file.h>
+ #include <rem_proj.h>
  #include <review.h>
  #include <reviewer.h>
  #include <str.h>
***************
*** 57,129 ****
  #include <undo.h>
  #include <version.h>
  
! static arglex_table_t argtab[] =
  {
! 	{ "-ANticipate",	arglex_token_anticipate,	},
! 	{ "-AUTOmatic",		arglex_token_automatic,		},
! 	{ "-BaseLine",		arglex_token_baseline,		},
! 	{ "-Build",		arglex_token_build,		},
! 	{ "-Change",		arglex_token_change,		},
! 	{ "-Change_Attributes",	arglex_token_change_attributes,	},
! 	{ "-Change_Directory",	arglex_token_change_directory,	},
! 	{ "-CoPy_file",		arglex_token_copy_file,		},
! 	{ "-CoPy_file_Undo",	arglex_token_copy_file_undo,	},
! 	{ "-DIFference",	arglex_token_difference,	},
! 	{ "-DIRectory",		arglex_token_directory,		},
! 	{ "-DELta",		arglex_token_delta,		},
! 	{ "-Develop_Begin",	arglex_token_develop_begin,	},
! 	{ "-Develop_Begin_Undo", arglex_token_develop_begin_undo, },
! 	{ "-Develop_End",	arglex_token_develop_end,	},
! 	{ "-Develop_End_Undo",	arglex_token_develop_end_undo,	},
! 	{ "-Development_Directory", arglex_token_development_directory, },
! 	{ "-Force",		arglex_token_force,		},
! 	{ "-INDependent",	arglex_token_independent,	},
! 	{ "-Integrate_Begin",	arglex_token_integrate_begin,	},
! 	{ "-Integrate_Begin_Undo", arglex_token_integrate_begin_undo, },
! 	{ "-Integrate_FAIL",	arglex_token_integrate_fail,	},
! 	{ "-Integrate_PASS",	arglex_token_integrate_pass,	},
! 	{ "-Keep",		arglex_token_keep,		},
! 	{ "-LIBrary",		arglex_token_library,		},
! 	{ "-LOg",               arglex_token_log,		},
! 	{ "-List",		arglex_token_list,		},
! 	{ "-MAJor",		arglex_token_major,		},
! 	{ "-MANual",		arglex_token_manual,		},
! 	{ "-MINImum",		arglex_token_minimum,		},
! 	{ "-MINOr",		arglex_token_minor,		},
! 	{ "-New_Administrator",	arglex_token_new_administrator,	},
! 	{ "-New_Change",	arglex_token_new_change,	},
! 	{ "-New_Change_Undo",	arglex_token_new_change_undo,	},
! 	{ "-New_Developer",	arglex_token_new_developer,	},
! 	{ "-New_File",		arglex_token_new_file,		},
! 	{ "-New_File_Undo",	arglex_token_new_file_undo,	},
! 	{ "-New_Integrator",	arglex_token_new_integrator,	},
! 	{ "-New_Project",	arglex_token_new_project,	},
! 	{ "-New_ReLeaSe",	arglex_token_new_release,	},
! 	{ "-New_ReViewer",	arglex_token_new_reviewer,	},
! 	{ "-New_Test",		arglex_token_new_test,		},
! 	{ "-New_Test_Undo",	arglex_token_new_test_undo,	},
! 	{ "-Not_Logging",	arglex_token_nolog,		},
! 	{ "-Output",		arglex_token_output,		},
! 	{ "-OverWriting",	arglex_token_overwriting,	},
! 	{ "-Page_Length",	arglex_token_page_length,	},
! 	{ "-Page_Width",	arglex_token_page_width,	},
! 	{ "-Project",		arglex_token_project,		},
! 	{ "-Project_Attributes", arglex_token_project_attributes, },
! 	{ "-REGression",	arglex_token_regression,	},
! 	{ "-ReMove_file",	arglex_token_remove_file,	},
! 	{ "-ReMove_file_Undo",	arglex_token_remove_file_undo,	},
! 	{ "-Remove_Administrator", arglex_token_remove_administrator, },
! 	{ "-Remove_Developer",	arglex_token_remove_developer,	},
! 	{ "-Remove_Integrator",	arglex_token_remove_integrator,	},
! 	{ "-Remove_PRoject",	arglex_token_remove_project,	},
! 	{ "-Remove_ReViewer",	arglex_token_remove_reviewer,	},
! 	{ "-Review_FAIL",	arglex_token_review_fail,	},
! 	{ "-Review_PASS",	arglex_token_review_pass,	},
! 	{ "-Review_Pass_Undo",	arglex_token_review_pass_undo,	},
! 	{ "-TERse",		arglex_token_terse,		},
! 	{ "-Test",		arglex_token_test,		},
! 	{ "-Verbose",		arglex_token_verbose,		},
! 	{ 0, 0, } /* end marker */
  };
  
  
--- 58,324 ----
  #include <undo.h>
  #include <version.h>
  
! static arglex_table_ty argtab[] =
  {
! 	{
! 		"-ANticipate",
! 		(arglex_token_ty)arglex_token_anticipate,
! 	},
! 	{
! 		"-AUTOmatic",
! 		(arglex_token_ty)arglex_token_automatic,
! 	},
! 	{
! 		"-BaseLine",
! 		(arglex_token_ty)arglex_token_baseline,
! 	},
! 	{
! 		"-Build",
! 		(arglex_token_ty)arglex_token_build,
! 	},
! 	{
! 		"-Change",
! 		(arglex_token_ty)arglex_token_change,
! 	},
! 	{
! 		"-Change_Attributes",
! 		(arglex_token_ty)arglex_token_change_attributes,
! 	},
! 	{
! 		"-Change_Directory",
! 		(arglex_token_ty)arglex_token_change_directory,
! 	},
! 	{
! 		"-CoPy_file",
! 		(arglex_token_ty)arglex_token_copy_file,
! 	},
! 	{
! 		"-CoPy_file_Undo",
! 		(arglex_token_ty)arglex_token_copy_file_undo,
! 	},
! 	{
! 		"-DIFference",
! 		(arglex_token_ty)arglex_token_difference,
! 	},
! 	{
! 		"-DIRectory",
! 		(arglex_token_ty)arglex_token_directory,
! 	},
! 	{
! 		"-DELta",
! 		(arglex_token_ty)arglex_token_delta,
! 	},
! 	{
! 		"-Develop_Begin",
! 		(arglex_token_ty)arglex_token_develop_begin,
! 	},
! 	{
! 		"-Develop_Begin_Undo",
! 		(arglex_token_ty)arglex_token_develop_begin_undo,
! 	},
! 	{
! 		"-Develop_End",
! 		(arglex_token_ty)arglex_token_develop_end,
! 	},
! 	{
! 		"-Develop_End_Undo",
! 		(arglex_token_ty)arglex_token_develop_end_undo,
! 	},
! 	{
! 		"-Development_Directory",
! 		(arglex_token_ty)arglex_token_development_directory,
! 	},
! 	{
! 		"-Force",
! 		(arglex_token_ty)arglex_token_force,
! 	},
! 	{
! 		"-INDependent",
! 		(arglex_token_ty)arglex_token_independent,
! 	},
! 	{
! 		"-Integrate_Begin",
! 		(arglex_token_ty)arglex_token_integrate_begin,
! 	},
! 	{
! 		"-Integrate_Begin_Undo",
! 		(arglex_token_ty)arglex_token_integrate_begin_undo,
! 	},
! 	{
! 		"-Integrate_FAIL",
! 		(arglex_token_ty)arglex_token_integrate_fail,
! 	},
! 	{
! 		"-Integrate_PASS",
! 		(arglex_token_ty)arglex_token_integrate_pass,
! 	},
! 	{
! 		"-Keep",
! 		(arglex_token_ty)arglex_token_keep,
! 	},
! 	{
! 		"-LIBrary",
! 		(arglex_token_ty)arglex_token_library,
! 	},
! 	{
! 		"-LOg",
! 		(arglex_token_ty)arglex_token_log,
! 	},
! 	{
! 		"-List",
! 		(arglex_token_ty)arglex_token_list,
! 	},
! 	{
! 		"-MAJor",
! 		(arglex_token_ty)arglex_token_major,
! 	},
! 	{
! 		"-MANual",
! 		(arglex_token_ty)arglex_token_manual,
! 	},
! 	{
! 		"-MINImum",
! 		(arglex_token_ty)arglex_token_minimum,
! 	},
! 	{
! 		"-MINOr",
! 		(arglex_token_ty)arglex_token_minor,
! 	},
! 	{
! 		"-New_Administrator",
! 		(arglex_token_ty)arglex_token_new_administrator,
! 	},
! 	{
! 		"-New_Change",
! 		(arglex_token_ty)arglex_token_new_change,
! 	},
! 	{
! 		"-New_Change_Undo",
! 		(arglex_token_ty)arglex_token_new_change_undo,
! 	},
! 	{
! 		"-New_Developer",
! 		(arglex_token_ty)arglex_token_new_developer,
! 	},
! 	{
! 		"-New_File",
! 		(arglex_token_ty)arglex_token_new_file,
! 	},
! 	{
! 		"-New_File_Undo",
! 		(arglex_token_ty)arglex_token_new_file_undo,
! 	},
! 	{
! 		"-New_Integrator",
! 		(arglex_token_ty)arglex_token_new_integrator,
! 	},
! 	{
! 		"-New_Project",
! 		(arglex_token_ty)arglex_token_new_project,
! 	},
! 	{
! 		"-New_ReLeaSe",
! 		(arglex_token_ty)arglex_token_new_release,
! 	},
! 	{
! 		"-New_ReViewer",
! 		(arglex_token_ty)arglex_token_new_reviewer,
! 	},
! 	{
! 		"-New_Test",
! 		(arglex_token_ty)arglex_token_new_test,
! 	},
! 	{
! 		"-New_Test_Undo",
! 		(arglex_token_ty)arglex_token_new_test_undo,
! 	},
! 	{
! 		"-Not_Logging",
! 		(arglex_token_ty)arglex_token_nolog,
! 	},
! 	{
! 		"-Output",
! 		(arglex_token_ty)arglex_token_output,
! 	},
! 	{
! 		"-OverWriting",
! 		(arglex_token_ty)arglex_token_overwriting,
! 	},
! 	{
! 		"-Page_Length",
! 		(arglex_token_ty)arglex_token_page_length,
! 	},
! 	{
! 		"-Page_Width",
! 		(arglex_token_ty)arglex_token_page_width,
! 	},
! 	{
! 		"-Project",
! 		(arglex_token_ty)arglex_token_project,
! 	},
! 	{
! 		"-Project_Attributes",
! 		(arglex_token_ty)arglex_token_project_attributes,
! 	},
! 	{
! 		"-REGression",
! 		(arglex_token_ty)arglex_token_regression,
! 	},
! 	{
! 		"-ReMove_file",
! 		(arglex_token_ty)arglex_token_remove_file,
! 	},
! 	{
! 		"-ReMove_file_Undo",
! 		(arglex_token_ty)arglex_token_remove_file_undo,
! 	},
! 	{
! 		"-Remove_Administrator",
! 		(arglex_token_ty)arglex_token_remove_administrator,
! 	},
! 	{
! 		"-Remove_Developer",
! 		(arglex_token_ty)arglex_token_remove_developer,
! 	},
! 	{
! 		"-Remove_Integrator",
! 		(arglex_token_ty)arglex_token_remove_integrator,
! 	},
! 	{
! 		"-ReMove_PRoject",
! 		(arglex_token_ty)arglex_token_remove_project,
! 	},
! 	{
! 		"-Remove_ReViewer",
! 		(arglex_token_ty)arglex_token_remove_reviewer,
! 	},
! 	{
! 		"-Review_FAIL",
! 		(arglex_token_ty)arglex_token_review_fail,
! 	},
! 	{
! 		"-Review_PASS",
! 		(arglex_token_ty)arglex_token_review_pass,
! 	},
! 	{
! 		"-Review_Pass_Undo",
! 		(arglex_token_ty)arglex_token_review_pass_undo,
! 	},
! 	{
! 		"-TERse",
! 		(arglex_token_ty)arglex_token_terse,
! 	},
! 	{
! 		"-Test",
! 		(arglex_token_ty)arglex_token_test,
! 	},
! 	{
! 		"-Verbose",
! 		(arglex_token_ty)arglex_token_verbose,
! 	},
! 
! 	/* end marker */
! 	{ 0, (arglex_token_ty)0, },
  };
  
  
***************
*** 329,337 ****
  "		remove integrators from a project.  See aeri(1)",
  "		for more information.",
  "",
! "	-Remove_PRoject",
! "		The %s -Remove_PRoject command is used to",
! "		remove a project.  See aerpr(1) for more information.",
  "",
  "	-Remove_ReViewer",
  "		The %s -Remove_ReViewer command is used to",
--- 524,532 ----
  "		remove integrators from a project.  See aeri(1)",
  "		for more information.",
  "",
! "	-ReMove_PRoject",
! "		The %s -ReMove_PRoject command is used to",
! "		remove a project.  See aermpr(1) for more information.",
  "",
  "	-Remove_ReViewer",
  "		The %s -Remove_ReViewer command is used to",
***************
*** 364,373 ****
  "		copyright and version details.	See aev(1) for",
  "		more information.",
  "",
! "	All function are case insensitive.  Functions may be",
! "	abbreviated; the abbreviation is the upper case letters.",
! "	Functions must appear as the first command line argument.",
  "",
  "OPTIONS",
  "	The following options are available to all functions.  These",
  "	options may appear anywhere on the command line following",
--- 559,587 ----
  "		copyright and version details.	See aev(1) for",
  "		more information.",
  "",
! "	All options may be abbreviated; the abbreviation is",
! "	documented as the upper case letters, all lower case",
! "	letters and underscores (_) are optional.  You must use",
! "	consecutive sequences of optional letters.",
  "",
+ "	All options are case insensitive, you may type them in",
+ "	upper case or lower case or a combination of both, case",
+ "	is not important.",
+ "",
+ "	For example: the arguments \"-project, \"-PROJ\" and \"-p\"",
+ "	are all interpreted to mean the -Project option.  The",
+ "	argument \"-prj\" will not be understood, because",
+ "	consecutive optional characters were not supplied.",
+ "",
+ "	Options and other command line arguments may be mixed",
+ "	arbitrarily on the command line, after the function",
+ "	selectors.",
+ "",
+ "	The GNU long option names are understood.  Since all",
+ "	option names for aegis are long, this means ignoring the",
+ "	extra leading '-'.  The \"--option=value\" convention is",
+ "	also understood.",
+ "",
  "OPTIONS",
  "	The following options are available to all functions.  These",
  "	options may appear anywhere on the command line following",
***************
*** 398,408 ****
  "		specified, either on the command line or in the",
  "		AEGIS environment variable, must be absolute.",
  "",
! "	All options are case insensitive.  Options may be",
! "	abbreviated; the abbreviation is the upper case letters.",
  "	Options and other command line arguments may be mixed",
! "	arbitrarily on the command line.",
  "",
  "EXIT STATUS",
  "	The %s command will exit with a status of 1 on any",
  "	error.	The %s command will only exit with a status of",
--- 612,640 ----
  "		specified, either on the command line or in the",
  "		AEGIS environment variable, must be absolute.",
  "",
! "	All options may be abbreviated; the abbreviation is",
! "	documented as the upper case letters, all lower case",
! "	letters and underscores (_) are optional.  You must use",
! "	consecutive sequences of optional letters.",
! "",
! "	All options are case insensitive, you may type them in",
! "	upper case or lower case or a combination of both, case",
! "	is not important.",
! "",
! "	For example: the arguments \"-project, \"-PROJ\" and \"-p\"",
! "	are all interpreted to mean the -Project option.  The",
! "	argument \"-prj\" will not be understood, because",
! "	consecutive optional characters were not supplied.",
! "",
  "	Options and other command line arguments may be mixed",
! "	arbitrarily on the command line, after the function",
! "	selectors.",
  "",
+ "	The GNU long option names are understood.  Since all",
+ "	option names for aegis are long, this means ignoring the",
+ "	extra leading '-'.  The \"--option=value\" convention is",
+ "	also understood.",
+ "",
  "EXIT STATUS",
  "	The %s command will exit with a status of 1 on any",
  "	error.	The %s command will only exit with a status of",
***************
*** 472,477 ****
--- 704,710 ----
  	case arglex_token_remove_developer: remove_developer(); break;
  	case arglex_token_remove_file: remove_file(); break;
  	case arglex_token_remove_file_undo: remove_file_undo(); break;
+ 	case arglex_token_remove_project: remove_project(); break;
  	case arglex_token_remove_integrator: remove_integrator(); break;
  	case arglex_token_remove_reviewer: remove_reviewer(); break;
  	case arglex_token_review_fail: review_fail(); break;
Index: aegis/new_chan.c
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 97,110 ****
  "",
  "	-Project <name>",
  "		This option may be used to select the project of",
! "		interest.  When no -Project option is specified, if",
! "		the user is only working on changes within a single",
! "		project, the project name defaults to that project;",
! "		if the user is currently working on changes to more",
! "		than one project, or is not working on changes to",
! "		any project, the user's $HOME/.%src file is",
! "		examined for a default project field (see aeuconf(5)",
! "		for more information).",
  "",
  "	-TERse",
  "		This option may be used to cause listings to",
--- 97,110 ----
  "",
  "	-Project <name>",
  "		This option may be used to select the project of",
! "		interest.  When no -Project option is specified, the",
! "		AEGIS_PROJECT environment variable is consulted.  If",
! "		that does not exist, the user's $HOME/.aegisrc file",
! "		is examined for a default project field (see",
! "		aeuconf(5) for more information).  If that does not",
! "		exist, when the user is only working on changes",
! "		within a single project, the project name defaults",
! "		to that project.  Otherwise, it is an error.",
  "",
  "	-TERse",
  "		This option may be used to cause listings to",
***************
*** 118,128 ****
  "		option this option causes column headings to be",
  "		added.",
  "",
! "	All options are case insensitive.  Options may be",
! "	abbreviated; the abbreviation is the upper case letters.",
  "	Options and other command line arguments may be mixed",
! "	arbitrarily on the command line.",
  "",
  "RECOMMENDED ALIAS",
  "	The recommended alias for this command is",
  "	csh%%	alias aenc '%s -nc \\!* -v'",
--- 118,146 ----
  "		option this option causes column headings to be",
  "		added.",
  "",
! "	All options may be abbreviated; the abbreviation is",
! "	documented as the upper case letters, all lower case",
! "	letters and underscores (_) are optional.  You must use",
! "	consecutive sequences of optional letters.",
! "",
! "	All options are case insensitive, you may type them in",
! "	upper case or lower case or a combination of both, case",
! "	is not important.",
! "",
! "	For example: the arguments \"-project, \"-PROJ\" and \"-p\"",
! "	are all interpreted to mean the -Project option.  The",
! "	argument \"-prj\" will not be understood, because",
! "	consecutive optional characters were not supplied.",
! "",
  "	Options and other command line arguments may be mixed",
! "	arbitrarily on the command line, after the function",
! "	selectors.",
  "",
+ "	The GNU long option names are understood.  Since all",
+ "	option names for aegis are long, this means ignoring the",
+ "	extra leading '-'.  The \"--option=value\" convention is",
+ "	also understood.",
+ "",
  "RECOMMENDED ALIAS",
  "	The recommended alias for this command is",
  "	csh%%	alias aenc '%s -nc \\!* -v'",
***************
*** 155,161 ****
  static void
  new_change_list()
  {
! 	string_t	*project_name;
  
  	trace(("new_chane_list()\n{\n"/*}*/));
  	project_name = 0;
--- 173,179 ----
  static void
  new_change_list()
  {
! 	string_ty	*project_name;
  
  	trace(("new_chane_list()\n{\n"/*}*/));
  	project_name = 0;
***************
*** 194,204 ****
  	cstate		cstate_data;
  	cstate_history	history_data;
  	cattr		cattr_data;
! 	string_t	*project_name;
! 	project_t	*pp;
  	long		change_number;
! 	change_t	*cp;
! 	user_t		*up;
  
  	trace(("new_change_main()\n{\n"/*}*/));
  	cattr_data = 0;
--- 212,222 ----
  	cstate		cstate_data;
  	cstate_history	history_data;
  	cattr		cattr_data;
! 	string_ty	*project_name;
! 	project_ty	*pp;
  	long		change_number;
! 	change_ty	*cp;
! 	user_ty		*up;
  
  	trace(("new_change_main()\n{\n"/*}*/));
  	cattr_data = 0;
***************
*** 449,457 ****
  "",
  "	-Change <number>",
  "		This option may be used to specify a particular",
! "		change within a project.  If the user is only",
! "		working on one change within a project, that is",
! "		the default change number.",
  "",
  "	-Help",
  "		This option may be used to obtain more",
--- 467,480 ----
  "",
  "	-Change <number>",
  "		This option may be used to specify a particular",
! "		change within a project.  When no -Change option is",
! "		specified, the AEGIS_CHANGE environment variable is",
! "		consulted.  If that does not exist, the user's",
! "		$HOME/.aegisrc file is examined for a default change",
! "		field (see aeuconf(5) for more information).  If",
! "		that does not exist, when the user is only working",
! "		on one change within a project, that is the default",
! "		change number.  Otherwise, it is an error.",
  "",
  "	-Help",
  "		This option may be used to obtain more",
***************
*** 464,477 ****
  "",
  "	-Project <name>",
  "		This option may be used to select the project of",
! "		interest.  When no -Project option is specified, if",
! "		the user is only working on changes within a single",
! "		project, the project name defaults to that project;",
! "		if the user is currently working on changes to more",
! "		than one project, or is not working on changes to",
! "		any project, the user's $HOME/.%src file is",
! "		examined for a default project field (see aeuconf(5)",
! "		for more information).",
  "",
  "	-TERse",
  "		This option may be used to cause listings to",
--- 487,500 ----
  "",
  "	-Project <name>",
  "		This option may be used to select the project of",
! "		interest.  When no -Project option is specified, the",
! "		AEGIS_PROJECT environment variable is consulted.  If",
! "		that does not exist, the user's $HOME/.aegisrc file",
! "		is examined for a default project field (see",
! "		aeuconf(5) for more information).  If that does not",
! "		exist, when the user is only working on changes",
! "		within a single project, the project name defaults",
! "		to that project.  Otherwise, it is an error.",
  "",
  "	-TERse",
  "		This option may be used to cause listings to",
***************
*** 485,495 ****
  "		option this option causes column headings to be",
  "		added.",
  "",
! "	All options are case insensitive.  Options may be",
! "	abbreviated; the abbreviation is the upper case letters.",
  "	Options and other command line arguments may be mixed",
! "	arbitrarily on the command line.",
  "",
  "RECOMMENDED ALIAS",
  "	The recommended alias for this command is",
  "	csh%%	alias aencu '%s -ncu \\!* -v'",
--- 508,536 ----
  "		option this option causes column headings to be",
  "		added.",
  "",
! "	All options may be abbreviated; the abbreviation is",
! "	documented as the upper case letters, all lower case",
! "	letters and underscores (_) are optional.  You must use",
! "	consecutive sequences of optional letters.",
! "",
! "	All options are case insensitive, you may type them in",
! "	upper case or lower case or a combination of both, case",
! "	is not important.",
! "",
! "	For example: the arguments \"-project, \"-PROJ\" and \"-p\"",
! "	are all interpreted to mean the -Project option.  The",
! "	argument \"-prj\" will not be understood, because",
! "	consecutive optional characters were not supplied.",
! "",
  "	Options and other command line arguments may be mixed",
! "	arbitrarily on the command line, after the function",
! "	selectors.",
  "",
+ "	The GNU long option names are understood.  Since all",
+ "	option names for aegis are long, this means ignoring the",
+ "	extra leading '-'.  The \"--option=value\" convention is",
+ "	also understood.",
+ "",
  "RECOMMENDED ALIAS",
  "	The recommended alias for this command is",
  "	csh%%	alias aencu '%s -ncu \\!* -v'",
***************
*** 522,528 ****
  static void
  new_change_undo_list()
  {
! 	string_t	*project_name;
  
  	trace(("new_change_list()\n{\n"/*}*/));
  	arglex();
--- 563,569 ----
  static void
  new_change_undo_list()
  {
! 	string_ty	*project_name;
  
  	trace(("new_change_list()\n{\n"/*}*/));
  	arglex();
***************
*** 561,568 ****
  static void
  new_change_undo_main()
  {
  	trace(("new_change_undo_main()\n{\n"/*}*/));
! 	fatal("-ncu not implemented");
  	trace((/*{*/"}\n"));
  }
  
--- 602,735 ----
  static void
  new_change_undo_main()
  {
+ 	string_ty	*project_name;
+ 	long		change_number;
+ 	project_ty	*pp;
+ 	user_ty		*up;
+ 	change_ty	*cp;
+ 	cstate		cstate_data;
+ 	pstate		pstate_data;
+ 
  	trace(("new_change_undo_main()\n{\n"/*}*/));
! 	project_name = 0;
! 	change_number = 0;
! 	while (arglex_token != arglex_token_eoln)
! 	{
! 		switch (arglex_token)
! 		{
! 		default:
! 			generic_argument(new_change_undo_usage);
! 			continue;
! 
! 		case arglex_token_change:
! 			if (arglex() != arglex_token_number)
! 				new_change_undo_usage();
! 			/* fall through... */
! 
! 		case arglex_token_number:
! 			if (change_number)
! 				fatal("duplicate -Change option");
! 			change_number = arglex_value.alv_number;
! 			if (change_number < 1)
! 				fatal("change %ld out of range", change_number);
! 			break;
! 
! 		case arglex_token_project:
! 			if (arglex() != arglex_token_string)
! 				new_change_undo_usage();
! 			/* fall through... */
! 		
! 		case arglex_token_string:
! 			if (project_name)
! 				fatal("duplicate -Project option");
! 			project_name = str_from_c(arglex_value.alv_string);
! 			break;
! 		}
! 		arglex();
! 	}
! 
! 	/*
! 	 * locate project data
! 	 */
! 	if (!project_name)
! 		project_name = user_default_project();
! 	pp = project_alloc(project_name);
! 	str_free(project_name);
! 	project_bind_existing(pp);
! 
! 	/*
! 	 * locate user data
! 	 */
! 	up = user_executing(pp);
! 
! 	/*
! 	 * locate change data
! 	 *
! 	 * The change number must be given on the command line,
! 	 * even if there is only one appropriate change.
! 	 * The is the "least surprizes" principle at work,
! 	 * even though we could sometimes work this out for ourself.
! 	 */
! 	if (!change_number)
! 		change_number = user_default_change(up);
! 	cp = change_alloc(pp, change_number);
! 	change_bind_existing(cp);
! 
! 	/*
! 	 * Take an advisory write lock on the project state
! 	 * and the change state.
! 	 */
! 	project_pstate_lock_prepare(pp);
! 	change_cstate_lock_prepare(cp);
! 	lock_take();
! 	cstate_data = change_cstate_get(cp);
! 	pstate_data = project_pstate_get(pp);
! 
! 	/*
! 	 * Extract the appropriate row of the change table.
! 	 * It is an error if the change is not in the
! 	 * awaiting_development state.
! 	 */
! 	if (cstate_data->state != cstate_state_awaiting_development)
! 		change_fatal(cp, "not in 'awaiting_development' state");
! 	if (!project_administrator_query(pp, user_name(up)))
! 	{
! 		project_fatal
! 		(
! 			pp,
! 			"user \"%S\" is not an administrator",
! 			user_name(up)
! 		);
! 	}
! 
! 	/*
! 	 * tell the project to forget this change
! 	 */
! 	project_change_delete(pp, change_number);
! 
! 	/*
! 	 * delete the change state file
! 	 */
! 	project_become(pp);
! 	commit_unlink_errok(cp->filename);
! 	project_become_undo();
! 
! 	/*
! 	 * Update change table row (and change history table).
! 	 * Update user table row.
! 	 * Release advisory write locks.
! 	 */
! 	project_pstate_write(pp);
! 	commit();
! 	lock_release();
! 
! 	/*
! 	 * verbose success message
! 	 */
! 	change_verbose(cp, "removed");
! 	change_free(cp);
! 	project_free(pp);
! 	user_free(up);
  	trace((/*{*/"}\n"));
  }
  
Index: aegis/new_chan.h
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
Index: aegis/new_file.c
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 22,27 ****
--- 22,28 ----
  
  #include <stdio.h>
  #include <stdlib.h>
+ #include <unistd.h>
  
  #include <arglex2.h>
  #include <change.h>
***************
*** 28,33 ****
--- 29,35 ----
  #include <col.h>
  #include <commit.h>
  #include <error.h>
+ #include <glue.h>
  #include <help.h>
  #include <list.h>
  #include <lock.h>
***************
*** 102,110 ****
  "",
  "	-Change <number>",
  "		This option may be used to specify a particular",
! "		change within a project.  If the user is only",
! "		working on one change within a project, that is",
! "		the default change number.",
  "",
  "	-Help",
  "		This option may be used to obtain more",
--- 104,117 ----
  "",
  "	-Change <number>",
  "		This option may be used to specify a particular",
! "		change within a project.  When no -Change option is",
! "		specified, the AEGIS_CHANGE environment variable is",
! "		consulted.  If that does not exist, the user's",
! "		$HOME/.aegisrc file is examined for a default change",
! "		field (see aeuconf(5) for more information).  If",
! "		that does not exist, when the user is only working",
! "		on one change within a project, that is the default",
! "		change number.  Otherwise, it is an error.",
  "",
  "	-Help",
  "		This option may be used to obtain more",
***************
*** 117,130 ****
  "",
  "	-Project <name>",
  "		This option may be used to select the project of",
! "		interest.  When no -Project option is specified, if",
! "		the user is only working on changes within a single",
! "		project, the project name defaults to that project;",
! "		if the user is currently working on changes to more",
! "		than one project, or is not working on changes to",
! "		any project, the user's $HOME/.%src file is",
! "		examined for a default project field (see aeuconf(5)",
! "		for more information).",
  "",
  "	-TERse",
  "		This option may be used to cause listings to",
--- 124,137 ----
  "",
  "	-Project <name>",
  "		This option may be used to select the project of",
! "		interest.  When no -Project option is specified, the",
! "		AEGIS_PROJECT environment variable is consulted.  If",
! "		that does not exist, the user's $HOME/.aegisrc file",
! "		is examined for a default project field (see",
! "		aeuconf(5) for more information).  If that does not",
! "		exist, when the user is only working on changes",
! "		within a single project, the project name defaults",
! "		to that project.  Otherwise, it is an error.",
  "",
  "	-TERse",
  "		This option may be used to cause listings to",
***************
*** 138,148 ****
  "		option this option causes column headings to be",
  "		added.",
  "",
! "	All options are case insensitive.  Options may be",
! "	abbreviated; the abbreviation is the upper case letters.",
  "	Options and other command line arguments may be mixed",
! "	arbitrarily on the command line.",
  "",
  "RECOMMENDED ALIAS",
  "	The recommended alias for this command is",
  "	csh%%	alias aenf '%s -nf \\!* -v'",
--- 145,173 ----
  "		option this option causes column headings to be",
  "		added.",
  "",
! "	All options may be abbreviated; the abbreviation is",
! "	documented as the upper case letters, all lower case",
! "	letters and underscores (_) are optional.  You must use",
! "	consecutive sequences of optional letters.",
! "",
! "	All options are case insensitive, you may type them in",
! "	upper case or lower case or a combination of both, case",
! "	is not important.",
! "",
! "	For example: the arguments \"-project, \"-PROJ\" and \"-p\"",
! "	are all interpreted to mean the -Project option.  The",
! "	argument \"-prj\" will not be understood, because",
! "	consecutive optional characters were not supplied.",
! "",
  "	Options and other command line arguments may be mixed",
! "	arbitrarily on the command line, after the function",
! "	selectors.",
  "",
+ "	The GNU long option names are understood.  Since all",
+ "	option names for aegis are long, this means ignoring the",
+ "	extra leading '-'.  The \"--option=value\" convention is",
+ "	also understood.",
+ "",
  "RECOMMENDED ALIAS",
  "	The recommended alias for this command is",
  "	csh%%	alias aenf '%s -nf \\!* -v'",
***************
*** 178,184 ****
  static void
  new_file_list()
  {
! 	string_t	*project_name;
  	long		change_number;
  
  	trace(("new_file_list()\n{\n"/*}*/));
--- 203,209 ----
  static void
  new_file_list()
  {
! 	string_ty	*project_name;
  	long		change_number;
  
  	trace(("new_file_list()\n{\n"/*}*/));
***************
*** 228,247 ****
  static void
  new_file_main()
  {
! 	string_t	*dd;
  	wlist		wl;
  	cstate		cstate_data;
  	pstate		pstate_data;
  	int		j;
! 	string_t	*s1;
! 	string_t	*s2;
  	pconf		pconf_data;
! 	string_t	*project_name;
! 	project_t	*pp;
  	long		change_number;
! 	change_t	*cp;
  	int		nolog;
! 	user_t		*up;
  
  	trace(("new_file_main()\n{\n"/*}*/));
  	project_name = 0;
--- 253,273 ----
  static void
  new_file_main()
  {
! 	string_ty	*bl;
! 	string_ty	*dd;
  	wlist		wl;
  	cstate		cstate_data;
  	pstate		pstate_data;
  	int		j;
! 	string_ty	*s1;
! 	string_ty	*s2;
  	pconf		pconf_data;
! 	string_ty	*project_name;
! 	project_ty	*pp;
  	long		change_number;
! 	change_ty	*cp;
  	int		nolog;
! 	user_ty		*up;
  
  	trace(("new_file_main()\n{\n"/*}*/));
  	project_name = 0;
***************
*** 259,265 ****
  		case arglex_token_string:
  			s1 = str_from_c(arglex_value.alv_string);
  			os_become_orig();
! 			s2 = os_pathname(s1);
  			str_free(s1);
  			if (wl_member(&wl, s2))
  				fatal("file \"%s\" named more than once", arglex_value.alv_string);
--- 285,291 ----
  		case arglex_token_string:
  			s1 = str_from_c(arglex_value.alv_string);
  			os_become_orig();
! 			s2 = os_pathname(s1, 1);
  			str_free(s1);
  			if (wl_member(&wl, s2))
  				fatal("file \"%s\" named more than once", arglex_value.alv_string);
***************
*** 365,377 ****
  	 * 3.	if the file is inside the baseline, ok
  	 * 4.	if neither, error
  	 */
  	for (j = 0; j < wl.wl_nwords; ++j)
  	{
  		s1 = wl.wl_word[j];
  		assert(s1->str_text[0] == '/');
! 		s2 = os_below_dir(cstate_data->development_directory, s1);
  		if (!s2)
! 			s2 = os_below_dir(project_baseline_path_get(pp), s1);
  		if (!s2)
  			change_fatal(cp, "path \"%S\" unrelated", s1);
  		str_free(s1);
--- 391,405 ----
  	 * 3.	if the file is inside the baseline, ok
  	 * 4.	if neither, error
  	 */
+ 	dd = change_development_directory_get(cp, 1);
+ 	bl = project_baseline_path_get(pp, 1);
  	for (j = 0; j < wl.wl_nwords; ++j)
  	{
  		s1 = wl.wl_word[j];
  		assert(s1->str_text[0] == '/');
! 		s2 = os_below_dir(dd, s1);
  		if (!s2)
! 			s2 = os_below_dir(bl, s1);
  		if (!s2)
  			change_fatal(cp, "path \"%S\" unrelated", s1);
  		str_free(s1);
***************
*** 407,413 ****
  	 * if it does not already exist.
  	 * Create any necessary directories along the way.
  	 */
- 	dd = change_development_directory_get(cp);
  	user_become(up);
  	for (j = 0; j < wl.wl_nwords; ++j)
  	{
--- 435,440 ----
***************
*** 416,446 ****
  		s2 = str_format("%S/%S", dd, s1);
  		if (!os_exists(s2))
  		{
! 			FILE		*fp;
! 			string_t	*template;
  
! 			os_become_undo();
  			template = change_file_template(cp, s1);
  			user_become(up);
! 			fp = fopen(s2->str_text, "w");
! 			if (!fp)
  				nfatal("create(\"%s\")", s2->str_text);
  			if (template)
  			{
! 				fwrite
  				(
  					template->str_text,
! 					template->str_length,
! 					1,
! 					fp
  				);
  			}
! 			fclose(fp);
  			os_chmod(s2, 0644 & ~change_umask(cp));
  		}
  		str_free(s2);
  	}
! 	os_become_undo();
  
  	/*
  	 * Add each file to the change file,
--- 443,473 ----
  		s2 = str_format("%S/%S", dd, s1);
  		if (!os_exists(s2))
  		{
! 			int		fd;
! 			string_ty	*template;
  
! 			user_become_undo();
  			template = change_file_template(cp, s1);
  			user_become(up);
! 			fd = glue_creat(s2->str_text, 0666);
! 			if (fd < 0)
  				nfatal("create(\"%s\")", s2->str_text);
  			if (template)
  			{
! 				glue_write
  				(
+ 					fd,
  					template->str_text,
! 					template->str_length
  				);
+ 				str_free(template);
  			}
! 			glue_close(fd);
  			os_chmod(s2, 0644 & ~change_umask(cp));
  		}
  		str_free(s2);
  	}
! 	user_become_undo();
  
  	/*
  	 * Add each file to the change file,
***************
*** 570,578 ****
  "",
  "	-Change <number>",
  "		This option may be used to specify a particular",
! "		change within a project.  If the user is only",
! "		working on one change within a project, that is",
! "		the default change number.",
  "",
  "	-Help",
  "		This option may be used to obtain more",
--- 597,610 ----
  "",
  "	-Change <number>",
  "		This option may be used to specify a particular",
! "		change within a project.  When no -Change option is",
! "		specified, the AEGIS_CHANGE environment variable is",
! "		consulted.  If that does not exist, the user's",
! "		$HOME/.aegisrc file is examined for a default change",
! "		field (see aeuconf(5) for more information).  If",
! "		that does not exist, when the user is only working",
! "		on one change within a project, that is the default",
! "		change number.  Otherwise, it is an error.",
  "",
  "	-Help",
  "		This option may be used to obtain more",
***************
*** 589,602 ****
  "",
  "	-Project <name>",
  "		This option may be used to select the project of",
! "		interest.  When no -Project option is specified, if",
! "		the user is only working on changes within a single",
! "		project, the project name defaults to that project;",
! "		if the user is currently working on changes to more",
! "		than one project, or is not working on changes to",
! "		any project, the user's $HOME/.%src file is",
! "		examined for a default project field (see aeuconf(5)",
! "		for more information).",
  "",
  "	-TERse",
  "		This option may be used to cause listings to",
--- 621,634 ----
  "",
  "	-Project <name>",
  "		This option may be used to select the project of",
! "		interest.  When no -Project option is specified, the",
! "		AEGIS_PROJECT environment variable is consulted.  If",
! "		that does not exist, the user's $HOME/.aegisrc file",
! "		is examined for a default project field (see",
! "		aeuconf(5) for more information).  If that does not",
! "		exist, when the user is only working on changes",
! "		within a single project, the project name defaults",
! "		to that project.  Otherwise, it is an error.",
  "",
  "	-TERse",
  "		This option may be used to cause listings to",
***************
*** 610,620 ****
  "		option this option causes column headings to be",
  "		added.",
  "",
! "	All options are case insensitive.  Options may be",
! "	abbreviated; the abbreviation is the upper case letters.",
  "	Options and other command line arguments may be mixed",
! "	arbitrarily on the command line.",
  "",
  "RECOMMENDED ALIAS",
  "	The recommended alias for this command is",
  "	csh%%	alias aenfu '%s -nfu \\!$ -v'",
--- 642,670 ----
  "		option this option causes column headings to be",
  "		added.",
  "",
! "	All options may be abbreviated; the abbreviation is",
! "	documented as the upper case letters, all lower case",
! "	letters and underscores (_) are optional.  You must use",
! "	consecutive sequences of optional letters.",
! "",
! "	All options are case insensitive, you may type them in",
! "	upper case or lower case or a combination of both, case",
! "	is not important.",
! "",
! "	For example: the arguments \"-project, \"-PROJ\" and \"-p\"",
! "	are all interpreted to mean the -Project option.  The",
! "	argument \"-prj\" will not be understood, because",
! "	consecutive optional characters were not supplied.",
! "",
  "	Options and other command line arguments may be mixed",
! "	arbitrarily on the command line, after the function",
! "	selectors.",
  "",
+ "	The GNU long option names are understood.  Since all",
+ "	option names for aegis are long, this means ignoring the",
+ "	extra leading '-'.  The \"--option=value\" convention is",
+ "	also understood.",
+ "",
  "RECOMMENDED ALIAS",
  "	The recommended alias for this command is",
  "	csh%%	alias aenfu '%s -nfu \\!$ -v'",
***************
*** 650,656 ****
  static void
  new_file_undo_list()
  {
! 	string_t	*project_name;
  	long		change_number;
  
  	trace(("new_file_undo_list()\n{\n"/*}*/));
--- 700,706 ----
  static void
  new_file_undo_list()
  {
! 	string_ty	*project_name;
  	long		change_number;
  
  	trace(("new_file_undo_list()\n{\n"/*}*/));
***************
*** 704,721 ****
  	cstate		cstate_data;
  	pstate		pstate_data;
  	int		j;
! 	string_t	*s1;
! 	string_t	*s2;
  	int		keep;
  	pconf		pconf_data;
! 	string_t	*project_name;
! 	project_t	*pp;
  	long		change_number;
! 	change_t	*cp;
  	int		nolog;
! 	user_t		*up;
! 	string_t	*dd;
! 	string_t	*bl;
  
  	trace(("new_file_undo_main()\n{\n"/*}*/));
  	project_name = 0;
--- 754,771 ----
  	cstate		cstate_data;
  	pstate		pstate_data;
  	int		j;
! 	string_ty	*s1;
! 	string_ty	*s2;
  	int		keep;
  	pconf		pconf_data;
! 	string_ty	*project_name;
! 	project_ty	*pp;
  	long		change_number;
! 	change_ty	*cp;
  	int		nolog;
! 	user_ty		*up;
! 	string_ty	*dd;
! 	string_ty	*bl;
  
  	trace(("new_file_undo_main()\n{\n"/*}*/));
  	project_name = 0;
***************
*** 734,740 ****
  		case arglex_token_string:
  			s1 = str_from_c(arglex_value.alv_string);
  			os_become_orig();
! 			s2 = os_pathname(s1);
  			os_become_undo();
  			str_free(s1);
  			if (wl_member(&wl, s2))
--- 784,790 ----
  		case arglex_token_string:
  			s1 = str_from_c(arglex_value.alv_string);
  			os_become_orig();
! 			s2 = os_pathname(s1, 1);
  			os_become_undo();
  			str_free(s1);
  			if (wl_member(&wl, s2))
***************
*** 838,845 ****
  	 * 3.	if the file is inside the baseline, ok
  	 * 4.	if neither, error
  	 */
! 	dd = change_development_directory_get(cp);
! 	bl = project_baseline_path_get(pp);
  	for (j = 0; j < wl.wl_nwords; ++j)
  	{
  		s1 = wl.wl_word[j];
--- 888,895 ----
  	 * 3.	if the file is inside the baseline, ok
  	 * 4.	if neither, error
  	 */
! 	dd = change_development_directory_get(cp, 1);
! 	bl = project_baseline_path_get(pp, 1);
  	for (j = 0; j < wl.wl_nwords; ++j)
  	{
  		s1 = wl.wl_word[j];
Index: aegis/new_file.h
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
Index: aegis/new_proj.c
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 66,72 ****
  "	%s -New_PRoject - create a new project",
  "",
  "SYNOPSIS",
! "	%s -New_PRoject project-name [ <option>... ]",
  "	%s -New_PRoject -List [ <option>... ]",
  "	%s -New_PRoject -Help",
  "",
--- 66,72 ----
  "	%s -New_PRoject - create a new project",
  "",
  "SYNOPSIS",
! "	%s -New_PRoject <project-name> [ <option>... ]",
  "	%s -New_PRoject -List [ <option>... ]",
  "	%s -New_PRoject -Help",
  "",
***************
*** 78,105 ****
  "	and history and state and change data are kept, will be",
  "	created at this time.  If the -DIRectory option is not",
  "	given, the project directory will be created in the",
! "	current user's home directory, with the same name as the",
  "	project.",
  "",
  "	The project is created with the current user and group as",
  "	the owning user and group.  The current user is an",
! "	administrator for the project.	The project has no",
  "	developers, reviewers, integrators or other",
  "	administrators.",
  "",
  "OPTIONS",
  "	The following options are understood:",
  "",
  "	-DIRectory <path>",
! "		This option may be used to specify which",
! "		directory is to be used.  It is an error if the",
! "		current user does not have appropriate",
! "		permissions to create the directory path given.",
  "",
  "	-Help",
! "		This option may be used to obtain more",
! "		information about how to use the %s program.",
  "",
  "	-List",
  "		This option may be used to obtain a list of",
  "		suitable subjects for this command.  The list may",
--- 78,132 ----
  "	and history and state and change data are kept, will be",
  "	created at this time.  If the -DIRectory option is not",
  "	given, the project directory will be created in the",
! "	directory specified by the default_project_directory field",
! "	of aeuconf(5), or if not set in current user's home",
! "	directory; in either case with the same name as the",
  "	project.",
  "",
  "	The project is created with the current user and group as",
  "	the owning user and group.  The current user is an",
! "	administrator for the project.  The project has no",
  "	developers, reviewers, integrators or other",
  "	administrators.",
  "",
+ "	The project pointer will be added to the first element of",
+ "	the search path, or /usr/local/lib/%s if no path is",
+ "	set.  If this is inappropriate, use the -LIBrary option",
+ "	to explicitly set the desired location.  See the -LIBrary",
+ "	option for more information.",
+ "",
  "OPTIONS",
  "	The following options are understood:",
  "",
  "	-DIRectory <path>",
! "		This option may be used to specify which directory",
! "		is to be used.  It is an error if the current user",
! "		does not have appropriate permissions to create",
! "		the directory path given.  This must be an",
! "		absolute path.",
  "",
+ "		Caution: If you are using an automounter do not",
+ "		use `pwd` to make an absolute path, it usually",
+ "		gives the wrong answer.",
+ "",
  "	-Help",
! "		This option may be used to obtain more information",
! "		about how to use the %s program.",
  "",
+ "	-LIBrary <abspath>",
+ "		This option may be used to specify a directory to",
+ "		be searched for global state files and user state",
+ "		files.  (See aegstate(5) and aeustate(5) for more",
+ "		information.)  Several library options may be",
+ "		present on the command line, and are search in the",
+ "		order given.  Appended to this explicit search",
+ "		path are the directories specified by the AEGIS",
+ "		enviroment variable (colon separated), and",
+ "		finally, /usr/local/lib/%s is always searched.",
+ "		All paths specified, either on the command line or",
+ "		in the AEGIS environment variable, must be",
+ "		absolute.",
+ "",
  "	-List",
  "		This option may be used to obtain a list of",
  "		suitable subjects for this command.  The list may",
***************
*** 113,127 ****
  "	-Verbose",
  "		This option may be used to cause %s to produce",
  "		more output.  By default %s only produces",
! "		output on errors.  When used with the -List",
! "		option this option causes column headings to be",
! "		added.",
  "",
! "	All options are case insensitive.  Options may be",
! "	abbreviated; the abbreviation is the upper case letters.",
  "	Options and other command line arguments may be mixed",
! "	arbitrarily on the command line.",
  "",
  "RECOMMENDED ALIAS",
  "	The recommended alias for this command is",
  "	csh%%	alias aenpr '%s -npr \\!* -v'",
--- 140,171 ----
  "	-Verbose",
  "		This option may be used to cause %s to produce",
  "		more output.  By default %s only produces",
! "		output on errors.  When used with the -List option",
! "		this option causes column headings to be added.",
  "",
! "	All options may be abbreviated; the abbreviation is",
! "	documented as the upper case letters, all lower case",
! "	letters and underscores (_) are optional.  You must use",
! "	consecutive sequences of optional letters.",
! "",
! "	All options are case insensitive, you may type them in",
! "	upper case or lower case or a combination of both, case",
! "	is not important.",
! "",
! "	For example: the arguments \"-project, \"-PROJ\" and \"-p\"",
! "	are all interpreted to mean the -Project option.  The",
! "	argument \"-prj\" will not be understood, because",
! "	consecutive optional characters were not supplied.",
! "",
  "	Options and other command line arguments may be mixed",
! "	arbitrarily on the command line, after the function",
! "	selectors.",
  "",
+ "	The GNU long option names are understood.  Since all",
+ "	option names for aegis are long, this means ignoring the",
+ "	extra leading '-'.  The \"--option=value\" convention is",
+ "	also understood.",
+ "",
  "RECOMMENDED ALIAS",
  "	The recommended alias for this command is",
  "	csh%%	alias aenpr '%s -npr \\!* -v'",
***************
*** 130,142 ****
  "ERRORS",
  "	It is an error if the project name already exists.",
  "	It is an error if the project directory already exists.",
! "	It is an error if the currrent user does not have",
! "	suffient permissions to create the directory specified",
! "	with the -DIRectory option.",
  "",
  "EXIT STATUS",
  "	The %s command will exit with a status of 1 on any",
! "	error.	The %s command will only exit with a status of",
  "	0 if there are no errors.",
  "",
  "COPYRIGHT",
--- 174,186 ----
  "ERRORS",
  "	It is an error if the project name already exists.",
  "	It is an error if the project directory already exists.",
! "	It is an error if the currrent user does not have suffient",
! "	permissions to create the directory specified with the",
! "	-DIRectory option.",
  "",
  "EXIT STATUS",
  "	The %s command will exit with a status of 1 on any",
! "	error.  The %s command will only exit with a status of",
  "	0 if there are no errors.",
  "",
  "COPYRIGHT",
***************
*** 168,178 ****
  new_project_main()
  {
  	pstate		pstate_data;
! 	string_t	*home;
! 	string_t	*s1;
! 	string_t	*project_name;
! 	project_t	*pp;
! 	user_t		*up;
  
  	trace(("new_project_main()\n{\n"/*}*/));
  	project_name = 0;
--- 212,225 ----
  new_project_main()
  {
  	pstate		pstate_data;
! 	string_ty	*home;
! 	string_ty	*s1;
! 	string_ty	*project_name;
! 	project_ty	*pp;
! 	user_ty		*up;
! 	string_ty	*bl;
! 	string_ty	*hp;
! 	string_ty	*ip;
  
  	trace(("new_project_main()\n{\n"/*}*/));
  	project_name = 0;
***************
*** 204,214 ****
  				);
  			if (home)
  				fatal("duplicate -DIRectory option");
! 			s1 = str_from_c(arglex_value.alv_string);
! 			os_become_orig();
! 			home = os_pathname(s1);
! 			os_become_undo();
! 			str_free(s1);
  			break;
  		}
  		arglex();
--- 251,264 ----
  				);
  			if (home)
  				fatal("duplicate -DIRectory option");
! 			/*
! 			 * To cope with automounters, directories are stored as
! 			 * given, or are derived from the home directory in the
! 			 * passwd file.  Within aegis, pathnames have their
! 			 * symbolic links resolved, and any comparison of paths
! 			 * is done on this "system idea" of the pathname.
! 			 */
! 			home = str_from_c(arglex_value.alv_string);
  			break;
  		}
  		arglex();
***************
*** 225,233 ****
  	/*
  	 * locate user data
  	 */
! 	up = user_executing((project_t *)0);
  
  	/*
  	 * it is an error if the name is already in use
  	 */
  	pp = project_alloc(project_name);
--- 275,303 ----
  	/*
  	 * locate user data
  	 */
! 	up = user_executing((project_ty *)0);
  
  	/*
+ 	 * make sure not too privileged
+ 	 */
+ 	if (!user_uid_check(up->name))
+ 	{
+ 		fatal
+ 		(
+ 			"user \"%s\" is too privileged",
+ 			up->name->str_text
+ 		);
+ 	}
+ 	if (!user_gid_check(up->group))
+ 	{
+ 		fatal
+ 		(
+ 			"group \"%s\" is too privileged",
+ 			up->group->str_text
+ 		);
+ 	}
+ 
+ 	/*
  	 * it is an error if the name is already in use
  	 */
  	pp = project_alloc(project_name);
***************
*** 269,283 ****
  	 * It is an error if the directories can't be created.
  	 */
  	s1 = project_home_path_get(pp);
  	project_become(pp);
  	os_mkdir(s1, 02755);
  	undo_rmdir_errok(s1);
! 	os_mkdir(project_baseline_path_get(pp), 02755);
! 	undo_rmdir_errok(project_baseline_path_get(pp));
! 	os_mkdir(project_history_path_get(pp), 02755);
! 	undo_rmdir_errok(project_history_path_get(pp));
! 	os_mkdir(project_info_path_get(pp), 02755);
! 	undo_rmdir_errok(project_info_path_get(pp));
  	project_become_undo();
  
  	/*
--- 339,356 ----
  	 * It is an error if the directories can't be created.
  	 */
  	s1 = project_home_path_get(pp);
+ 	bl = project_baseline_path_get(pp, 0);
+ 	hp = project_history_path_get(pp);
+ 	ip = project_info_path_get(pp);
  	project_become(pp);
  	os_mkdir(s1, 02755);
  	undo_rmdir_errok(s1);
! 	os_mkdir(bl, 02755);
! 	undo_rmdir_errok(bl);
! 	os_mkdir(hp, 02755);
! 	undo_rmdir_errok(hp);
! 	os_mkdir(ip, 02755);
! 	undo_rmdir_errok(ip);
  	project_become_undo();
  
  	/*
Index: aegis/new_proj.h
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
Index: aegis/new_rele.c
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 74,120 ****
  	static char *text[] =
  	{
  "NAME",
! "	%s -New_ReLeaSe - create a new release",
  "",
  "SYNOPSIS",
! "	%s -New_ReLeaSe [ <option>... ]",
  "	%s -New_ReLeaSe -List [ <option>... ]",
  "	%s -New_ReLeaSe -Help",
  "",
  "DESCRIPTION",
  "	The %s -New_ReLeaSe command is used to create a new",
! "	release of an existing project.  The new release will",
! "	become a new project in its own right.",
  "",
  "	The project directory, under which the project baseline",
  "	and history and state and change data are kept, will be",
  "	created at this time.  If the -DIRectory option is not",
  "	given, the project directory will be created in the",
! "	current user's home directory, with the same name as the",
! "	project.",
  "",
! "	The new project is created with the same owner, group,",
! "	administrators, developers, reviewers and intergrators as",
! "	the existing project.",
  "",
  "OPTIONS",
  "	The following options are understood:",
  "",
  "	-DIRectory <path>",
! "		This option may be used to specify which",
! "		directory is to be used.  It is an error if the",
! "		current user does not have appropriate",
! "		permissions to create the directory path given.",
  "",
  "	-Help",
! "		This option may be used to obtain more",
! "		information about how to use the %s program.",
  "",
  "	-List",
  "		This option may be used to obtain a list of",
  "		suitable subjects for this command.  The list may",
  "		be more general than expected.",
  "",
  "	-TERse",
  "		This option may be used to cause listings to",
  "		produce the bare minimum of information.  It is",
--- 74,188 ----
  	static char *text[] =
  	{
  "NAME",
! "	%s -New_ReLeaSe - create a new project from an existing",
! "	project.",
  "",
  "SYNOPSIS",
! "	%s -New_ReLeaSe <project-name> [ <new-project-name> ][ <option>... ]",
  "	%s -New_ReLeaSe -List [ <option>... ]",
  "	%s -New_ReLeaSe -Help",
  "",
  "DESCRIPTION",
  "	The %s -New_ReLeaSe command is used to create a new",
! "	project from an existing project.",
  "",
+ "	If no new-project-name is specified, it will be derived",
+ "	from the project given as follows: any minor version dot",
+ "	suffix will be removed from the name, then any major",
+ "	version dot suffix will be removed from the name.  A major",
+ "	version dot suffix will be appended, and then a minor",
+ "	version dot suffix will be appended.  As an example,",
+ "	\"foo.1.0\" would become \"foo.1.1\" assuming the default",
+ "	minor version incriment, and \"foo\" would become \"foo.1.1\"",
+ "	assiming the same minor version incriment.",
+ "",
+ "	The entire project baseline will be copied.  The project",
+ "	state will be as if change 1 had already been integrated,",
+ "	naming every file (in the old project) as a new file.  The",
+ "	history files will reflect this.  No build will be",
+ "	necessary; it is assumed that the old baseline was built",
+ "	sucessfully.  Change numbers will commence at 2, as will",
+ "	build numbers.  Test numbers will commence where the old",
+ "	project left off (because all the earlier test numbers",
+ "	were used by the old project).",
+ "",
+ "	The default is for the minor version number to be",
+ "	incrimented.  If the major version number is incrimented",
+ "	or set, the minor version number will be set to zero if it",
+ "	is not explicitly given.",
+ "",
+ "	The pointer to the new project will be added to the first",
+ "	element of the search path, or /usr/local/lib/%s if",
+ "	none is set.  If this is inappropriate, use the",
+ "	-LIBrary option to explicitly set the desired location.",
+ "	See the -LIBrary option for more information.",
+ "",
  "	The project directory, under which the project baseline",
  "	and history and state and change data are kept, will be",
  "	created at this time.  If the -DIRectory option is not",
  "	given, the project directory will be created in the",
! "	directory specified by the default_project_directory field",
! "	of the project user's aeuconf(5), or if not set in project",
! "	user's home directory; in either case with the same name",
! "	as the project.",
  "",
! "	All staff will be copied from the old project to the new",
! "	project without change, as will all of the project",
! "	attributes.",
  "",
  "OPTIONS",
  "	The following options are understood:",
  "",
  "	-DIRectory <path>",
! "		This option may be used to specify which directory",
! "		is to be used.  It is an error if the current user",
! "		does not have appropriate permissions to create",
! "		the directory path given.  This must be an",
! "		absolute path.",
  "",
+ "		Caution: If you are using an automounter do not",
+ "		use `pwd` to make an absolute path, it usually",
+ "		gives the wrong answer.",
+ "",
  "	-Help",
! "		This option may be used to obtain more information",
! "		about how to use the %s program.",
  "",
+ "	-LIBrary <abspath>",
+ "		This option may be used to specify a directory to",
+ "		be searched for global state files and user state",
+ "		files.  (See aegstate(5) and aeustate(5) for more",
+ "		information.)  Several library options may be",
+ "		present on the command line, and are search in the",
+ "		order given.  Appended to this explicit search",
+ "		path are the directories specified by the AEGIS",
+ "		enviroment variable (colon separated), and",
+ "		finally, /usr/local/lib/%s is always searched.",
+ "		All paths specified, either on the command line or",
+ "		in the AEGIS environment variable, must be",
+ "		absolute.",
+ "",
  "	-List",
  "		This option may be used to obtain a list of",
  "		suitable subjects for this command.  The list may",
  "		be more general than expected.",
  "",
+ "	-MAJor [ <number> ]",
+ "		Specify that the major version number is to be",
+ "		incrimented, or set to the given number if",
+ "		specified.",
+ "",
+ "	-MINOr [ <number> ]",
+ "		Specify that the minor version number is to be",
+ "		incrimented, or set to the given number if",
+ "		specified.",
+ "",
+ "	-Not_Logging",
+ "		This option may be used to disable the automatic",
+ "		logging of output and errors to a file.  This is",
+ "		often useful when several %s commands are",
+ "		combined in a shell script.",
+ "",
  "	-TERse",
  "		This option may be used to cause listings to",
  "		produce the bare minimum of information.  It is",
***************
*** 123,152 ****
  "	-Verbose",
  "		This option may be used to cause %s to produce",
  "		more output.  By default %s only produces",
! "		output on errors.  When used with the -List",
! "		option this option causes column headings to be",
! "		added.",
  "",
! "	All options are case insensitive.  Options may be",
! "	abbreviated; the abbreviation is the upper case letters.",
  "	Options and other command line arguments may be mixed",
! "	arbitrarily on the command line.",
  "",
  "RECOMMENDED ALIAS",
  "	The recommended alias for this command is",
! "	csh%%	alias aenpr '%s -npr \\!* -v'",
! "	sh$	aenpr(){%s -npr $* -v}",
  "",
  "ERRORS",
! "	It is an error if the project name already exists.",
! "	It is an error if the project directory already exists.",
! "	It is an error if the current user does not have",
! "	sufficient permissions to create the directory specified",
! "	with the -DIRectory option.",
  "",
  "EXIT STATUS",
  "	The %s command will exit with a status of 1 on any",
! "	error.	The %s command will only exit with a status of",
  "	0 if there are no errors.",
  "",
  "COPYRIGHT",
--- 191,242 ----
  "	-Verbose",
  "		This option may be used to cause %s to produce",
  "		more output.  By default %s only produces",
! "		output on errors.  When used with the -List option",
! "		this option causes column headings to be added.",
  "",
! "	All options may be abbreviated; the abbreviation is",
! "	documented as the upper case letters, all lower case",
! "	letters and underscores (_) are optional.  You must use",
! "	consecutive sequences of optional letters.",
! "",
! "	All options are case insensitive, you may type them in",
! "	upper case or lower case or a combination of both, case",
! "	is not important.",
! "",
! "	For example: the arguments \"-project, \"-PROJ\" and \"-p\"",
! "	are all interpreted to mean the -Project option.  The",
! "	argument \"-prj\" will not be understood, because",
! "	consecutive optional characters were not supplied.",
! "",
  "	Options and other command line arguments may be mixed",
! "	arbitrarily on the command line, after the function",
! "	selectors.",
  "",
+ "	The GNU long option names are understood.  Since all",
+ "	option names for aegis are long, this means ignoring the",
+ "	extra leading '-'.  The \"--option=value\" convention is",
+ "	also understood.",
+ "",
  "RECOMMENDED ALIAS",
  "	The recommended alias for this command is",
! "	csh%%	alias aenrls '%s -nrls \\!* -v'",
! "	sh$	aenrls(){%s -nrls $* -v}",
  "",
  "ERRORS",
! "	It is an error if the old project named does not exist.",
  "",
+ "	It is an error if the old project named has not yet had",
+ "	any changes integrated.",
+ "",
+ "	It is an error if the old project named has any changes",
+ "	not in the completed state.",
+ "",
+ "	It is an error if the current user is not an administrator",
+ "	of the old project.",
+ "",
  "EXIT STATUS",
  "	The %s command will exit with a status of 1 on any",
! "	error.  The %s command will only exit with a status of",
  "	0 if there are no errors.",
  "",
  "COPYRIGHT",
***************
*** 196,206 ****
  }
  
  
! static string_t *build_new_name _((string_t *, long, long, long, long));
  
! static string_t *
  build_new_name(s, major_old, minor_old, major_new, minor_new)
! 	string_t	*s;
  	long		major_old;
  	long		minor_old;
  	long		major_new;
--- 286,296 ----
  }
  
  
! static string_ty *build_new_name _((string_ty *, long, long, long, long));
  
! static string_ty *
  build_new_name(s, major_old, minor_old, major_new, minor_new)
! 	string_ty	*s;
  	long		major_old;
  	long		minor_old;
  	long		major_new;
***************
*** 218,247 ****
  }
  
  
! typedef struct copy_tree_arg_t copy_tree_arg_t;
! struct copy_tree_arg_t
  {
! 	string_t	*from;
! 	string_t	*to;
  };
  
  
! static void copy_tree_callback _((void *, dir_walk_message_t, string_t *,
  	struct stat *));
  
  static void
  copy_tree_callback(arg, message, path, st)
  	void		*arg;
! 	dir_walk_message_t message;
! 	string_t	*path;
  	struct stat	*st;
  {
! 	string_t	*s1;
! 	string_t	*s2;
! 	copy_tree_arg_t	*info;
  
  	trace(("copy_tree_callback(arg = %08lX, message = %d, path = %08lX, st = %08lX)\n{\n"/*}*/, arg, message, path, st));
! 	info = arg;
  	trace_string(path->str_text);
  	s1 = os_below_dir(info->from, path);
  	assert(s1);
--- 308,337 ----
  }
  
  
! typedef struct copy_tree_arg_ty copy_tree_arg_ty;
! struct copy_tree_arg_ty
  {
! 	string_ty	*from;
! 	string_ty	*to;
  };
  
  
! static void copy_tree_callback _((void *, dir_walk_message_ty, string_ty *,
  	struct stat *));
  
  static void
  copy_tree_callback(arg, message, path, st)
  	void		*arg;
! 	dir_walk_message_ty message;
! 	string_ty	*path;
  	struct stat	*st;
  {
! 	string_ty	*s1;
! 	string_ty	*s2;
! 	copy_tree_arg_ty	*info;
  
  	trace(("copy_tree_callback(arg = %08lX, message = %d, path = %08lX, st = %08lX)\n{\n"/*}*/, arg, message, path, st));
! 	info = (copy_tree_arg_ty *)arg;
  	trace_string(path->str_text);
  	s1 = os_below_dir(info->from, path);
  	assert(s1);
***************
*** 286,312 ****
  static void
  new_release_main()
  {
! 	string_t	*bl;
! 	string_t	*hp;
  	long		major_new;
  	long		minor_new;
  	int		j;
  	pstate		pstate_data[2];
! 	string_t	*home;
! 	string_t	*s1;
! 	string_t	*s2;
! 	string_t	*project_name[2];
  	int		project_name_count;
! 	project_t	*pp[2];
! 	change_t	*cp;
  	cstate_history	chp;
  	pstate_history	php;
  	cstate		cstate_data;
! 	copy_tree_arg_t	info;
  	pconf		pconf_data;
  	int		nolog;
! 	user_t		*up;
! 	user_t		*pup;
  
  	trace(("new_release_main()\n{\n"/*}*/));
  	nolog = 0;
--- 376,403 ----
  static void
  new_release_main()
  {
! 	string_ty	*ip;
! 	string_ty	*bl;
! 	string_ty	*hp;
  	long		major_new;
  	long		minor_new;
  	int		j;
  	pstate		pstate_data[2];
! 	string_ty	*home;
! 	string_ty	*s1;
! 	string_ty	*s2;
! 	string_ty	*project_name[2];
  	int		project_name_count;
! 	project_ty	*pp[2];
! 	change_ty	*cp;
  	cstate_history	chp;
  	pstate_history	php;
  	cstate		cstate_data;
! 	copy_tree_arg_ty	info;
  	pconf		pconf_data;
  	int		nolog;
! 	user_ty		*up;
! 	user_ty		*pup;
  
  	trace(("new_release_main()\n{\n"/*}*/));
  	nolog = 0;
***************
*** 344,350 ****
  			}
  			s1 = str_from_c(arglex_value.alv_string);
  			os_become_orig();
! 			home = os_pathname(s1);
  			os_become_undo();
  			str_free(s1);
  			break;
--- 435,441 ----
  			}
  			s1 = str_from_c(arglex_value.alv_string);
  			os_become_orig();
! 			home = os_pathname(s1, 1);
  			os_become_undo();
  			str_free(s1);
  			break;
***************
*** 507,518 ****
  	 */
  	pp[1] = project_alloc(project_name[1]);
  	project_bind_new(pp[1]);
! 	pup = user_symbolic(pp[1], project_owner(pp[0]));
  
  	/*
  	 * read in the table
  	 */
  	project_pstate_lock_prepare(pp[1]);
  	gonzo_gstate_lock_prepare_new();
  	lock_take();
  	pstate_data[0] = project_pstate_get(pp[0]);
--- 598,610 ----
  	 */
  	pp[1] = project_alloc(project_name[1]);
  	project_bind_new(pp[1]);
! 	pup = project_user(pp[0]);
  
  	/*
  	 * read in the table
  	 */
  	project_pstate_lock_prepare(pp[1]);
+ 	project_build_read_lock_prepare(pp[0]);
  	gonzo_gstate_lock_prepare_new();
  	lock_take();
  	pstate_data[0] = project_pstate_get(pp[0]);
***************
*** 532,537 ****
--- 624,631 ----
  	pstate_data[1]->group_name = str_copy(project_group(pp[0]));
  	pstate_data[1]->version_previous = project_version_get(pp[0]);
  	pstate_data[1]->umask = pstate_data[0]->umask;
+ 	pstate_data[1]->default_test_exemption =
+ 		pstate_data[0]->default_test_exemption;
  	/* administrators */
  	for (j = 0; j < pstate_data[0]->administrator->length; ++j)
  	{
***************
*** 577,582 ****
--- 671,701 ----
  	pstate_data[1]->developers_may_create_changes =
  		pstate_data[0]->developers_may_create_changes;
  
+ 	if (pstate_data[0]->develop_end_notify_command)
+ 		pstate_data[1]->develop_end_notify_command =
+ 			str_copy(pstate_data[0]->develop_end_notify_command);
+ 	if (pstate_data[0]->develop_end_undo_notify_command)
+ 		pstate_data[1]->develop_end_undo_notify_command =
+ 			str_copy(pstate_data[0]->develop_end_undo_notify_command);
+ 	if (pstate_data[0]->review_pass_notify_command)
+ 		pstate_data[1]->review_pass_notify_command =
+ 			str_copy(pstate_data[0]->review_pass_notify_command);
+ 	if (pstate_data[0]->review_pass_undo_notify_command)
+ 		pstate_data[1]->review_pass_undo_notify_command =
+ 			str_copy(pstate_data[0]->review_pass_undo_notify_command);
+ 	if (pstate_data[0]->review_fail_notify_command)
+ 		pstate_data[1]->review_fail_notify_command =
+ 			str_copy(pstate_data[0]->review_fail_notify_command);
+ 	if (pstate_data[0]->integrate_pass_notify_command)
+ 		pstate_data[1]->integrate_pass_notify_command =
+ 			str_copy(pstate_data[0]->integrate_pass_notify_command);
+ 	if (pstate_data[0]->integrate_fail_notify_command)
+ 		pstate_data[1]->integrate_fail_notify_command =
+ 			str_copy(pstate_data[0]->integrate_fail_notify_command);
+ 	if (pstate_data[0]->default_development_directory)
+ 		pstate_data[1]->default_development_directory =
+ 			str_copy(pstate_data[0]->default_development_directory);
+ 
  	/*
  	 * if no project directory was specified
  	 * create the directory in their home directory.
***************
*** 595,604 ****
  	/*
  	 * create the diectory and subdirectories.
  	 * It is an error if the directories can't be created.
  	 */
  	s1 = project_home_path_get(pp[1]);
! 	bl = project_baseline_path_get(pp[1]);
  	hp = project_history_path_get(pp[1]);
  	project_become(pp[1]);
  	os_mkdir(s1, 02755);
  	undo_rmdir_errok(s1);
--- 714,727 ----
  	/*
  	 * create the diectory and subdirectories.
  	 * It is an error if the directories can't be created.
+ 	 *
+ 	 * Don't use the project_baseline_path_get function,
+ 	 * because it resolves any symlinks.
  	 */
  	s1 = project_home_path_get(pp[1]);
! 	bl = project_baseline_path_get(pp[1], 0);
  	hp = project_history_path_get(pp[1]);
+ 	ip = project_info_path_get(pp[1]);
  	project_become(pp[1]);
  	os_mkdir(s1, 02755);
  	undo_rmdir_errok(s1);
***************
*** 606,613 ****
  	undo_rmdir_errok(bl);
  	os_mkdir(hp, 02755);
  	undo_rmdir_errok(hp);
! 	os_mkdir(project_info_path_get(pp[1]), 02755);
! 	undo_rmdir_errok(project_info_path_get(pp[1]));
  	os_become_undo();
  
  	/*
--- 729,736 ----
  	undo_rmdir_errok(bl);
  	os_mkdir(hp, 02755);
  	undo_rmdir_errok(hp);
! 	os_mkdir(ip, 02755);
! 	undo_rmdir_errok(ip);
  	os_become_undo();
  
  	/*
***************
*** 672,678 ****
  	/*
  	 * copy files from old baseline to new baseline
  	 */
! 	info.from = project_baseline_path_get(pp[0]);
  	info.to = bl;
  	project_verbose(pp[1], "copy baseline");
  	project_become(pp[1]);
--- 795,801 ----
  	/*
  	 * copy files from old baseline to new baseline
  	 */
! 	info.from = project_baseline_path_get(pp[0], 1);
  	info.to = bl;
  	project_verbose(pp[1], "copy baseline");
  	project_become(pp[1]);
***************
*** 684,690 ****
  	 */
  	if (!nolog)
  	{
! 		user_t	*pup;
  
  		s1 = str_format("%S/%s.log", bl, option_get_progname());
  		pup = project_user(pp[1]);
--- 807,813 ----
  	 */
  	if (!nolog)
  	{
! 		user_ty	*pup;
  
  		s1 = str_format("%S/%s.log", bl, option_get_progname());
  		pup = project_user(pp[1]);
***************
*** 697,705 ****
  	{
  		cstate_src	c_src_data;
  		pstate_src	p_src_data;
- 		string_t	*the_command;
- 		string_t	*src_file;
- 		string_t	*dst_file;
  
  		c_src_data = cstate_data->src->list[j];
  		p_src_data = project_src_find(pp[1], c_src_data->file_name);
--- 820,825 ----
***************
*** 706,763 ****
  		assert(p_src_data);
  
  		/*
! 		 * prepare for the history commands
  		 */
! 		project_become(pp[1]);
! 		os_mkdir_between(hp, c_src_data->file_name, 02755);
! 		os_become_undo();
! 		src_file = str_format("%S/%S", bl, c_src_data->file_name);
! 		dst_file = str_format("%S/%S", hp, c_src_data->file_name);
! 
! 		/*
! 		 * create a new history
! 		 *	%1 = source file
! 		 *	%2 = history file
! 		 */
! 		the_command = pconf_data->history_create_command;
! 		the_command =
! 			substitute
  			(
  				cp,
! 				the_command->str_text,
! 				src_file->str_text,
! 				dst_file->str_text,
! 				(char *)0
  			);
- 		project_become(pp[1]);
- 		os_execute(the_command, OS_EXEC_FLAG_NO_INPUT, bl);
- 		os_become_undo();
- 
- 		/*
- 		 * ask the history file what its edit number is
- 		 *	%1 = history file
- 		 * we use this method because the string
- 		 * returned is essentially random,
- 		 * between different history programs.
- 		 */
- 		the_command = pconf_data->history_query_command;
- 		the_command =
- 			substitute
- 			(
- 				cp,
- 				the_command->str_text,
- 				dst_file->str_text,
- 				(char *)0
- 			);
- 		project_become(pp[1]);
- 		p_src_data->edit_number =
- 			os_execute_slurp
- 			(
- 				the_command,
- 				OS_EXEC_FLAG_NO_INPUT,
- 				bl
- 			);
- 		os_become_undo();
  		c_src_data->edit_number = str_copy(p_src_data->edit_number);
  	}
  
--- 826,840 ----
  		assert(p_src_data);
  
  		/*
! 		 * create a new history file
  		 */
! 		change_run_history_create_command(cp, c_src_data->file_name);
! 		p_src_data->edit_number =
! 			change_run_history_query_command
  			(
  				cp,
! 				c_src_data->file_name
  			);
  		c_src_data->edit_number = str_copy(p_src_data->edit_number);
  	}
  
Index: aegis/new_rele.h
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
Index: aegis/new_test.c
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 22,27 ****
--- 22,28 ----
  
  #include <stdio.h>
  #include <stdlib.h>
+ #include <unistd.h>
  
  #include <arglex2.h>
  #include <change.h>
***************
*** 28,33 ****
--- 29,35 ----
  #include <col.h>
  #include <commit.h>
  #include <error.h>
+ #include <glue.h>
  #include <help.h>
  #include <list.h>
  #include <lock.h>
***************
*** 97,105 ****
  "",
  "	-Change <number>",
  "		This option may be used to specify a particular",
! "		change within a project.  If the user is only",
! "		working on one change within a project, that is",
! "		the default change number.",
  "",
  "	-Help",
  "		This option may be used to obtain more",
--- 99,112 ----
  "",
  "	-Change <number>",
  "		This option may be used to specify a particular",
! "		change within a project.  When no -Change option is",
! "		specified, the AEGIS_CHANGE environment variable is",
! "		consulted.  If that does not exist, the user's",
! "		$HOME/.aegisrc file is examined for a default change",
! "		field (see aeuconf(5) for more information).  If",
! "		that does not exist, when the user is only working",
! "		on one change within a project, that is the default",
! "		change number.  Otherwise, it is an error.",
  "",
  "	-Help",
  "		This option may be used to obtain more",
***************
*** 119,132 ****
  "",
  "	-Project <name>",
  "		This option may be used to select the project of",
! "		interest.  When no -Project option is specified, if",
! "		the user is only working on changes within a single",
! "		project, the project name defaults to that project;",
! "		if the user is currently working on changes to more",
! "		than one project, or is not working on changes to",
! "		any project, the user's $HOME/.%src file is",
! "		examined for a default project field (see aeuconf(5)",
! "		for more information).",
  "",
  "	-TERse",
  "		This option may be used to cause listings to",
--- 126,139 ----
  "",
  "	-Project <name>",
  "		This option may be used to select the project of",
! "		interest.  When no -Project option is specified, the",
! "		AEGIS_PROJECT environment variable is consulted.  If",
! "		that does not exist, the user's $HOME/.aegisrc file",
! "		is examined for a default project field (see",
! "		aeuconf(5) for more information).  If that does not",
! "		exist, when the user is only working on changes",
! "		within a single project, the project name defaults",
! "		to that project.  Otherwise, it is an error.",
  "",
  "	-TERse",
  "		This option may be used to cause listings to",
***************
*** 140,150 ****
  "		option this option causes column headings to be",
  "		added.",
  "",
! "	All options are case insensitive.  Options may be",
! "	abbreviated; the abbreviation is the upper case letters.",
  "	Options and other command line arguments may be mixed",
! "	arbitrarily on the command line.",
  "",
  "RECOMMENDED ALIAS",
  "	The recommended alias for this command is",
  "	csh%%	alias aent '%s -nt \\!* -v'",
--- 147,175 ----
  "		option this option causes column headings to be",
  "		added.",
  "",
! "	All options may be abbreviated; the abbreviation is",
! "	documented as the upper case letters, all lower case",
! "	letters and underscores (_) are optional.  You must use",
! "	consecutive sequences of optional letters.",
! "",
! "	All options are case insensitive, you may type them in",
! "	upper case or lower case or a combination of both, case",
! "	is not important.",
! "",
! "	For example: the arguments \"-project, \"-PROJ\" and \"-p\"",
! "	are all interpreted to mean the -Project option.  The",
! "	argument \"-prj\" will not be understood, because",
! "	consecutive optional characters were not supplied.",
! "",
  "	Options and other command line arguments may be mixed",
! "	arbitrarily on the command line, after the function",
! "	selectors.",
  "",
+ "	The GNU long option names are understood.  Since all",
+ "	option names for aegis are long, this means ignoring the",
+ "	extra leading '-'.  The \"--option=value\" convention is",
+ "	also understood.",
+ "",
  "RECOMMENDED ALIAS",
  "	The recommended alias for this command is",
  "	csh%%	alias aent '%s -nt \\!* -v'",
***************
*** 177,183 ****
  static void
  new_test_list()
  {
! 	string_t	*project_name;
  	long		change_number;
  
  	trace(("new_test_list()\n{\n"/*}*/));
--- 202,208 ----
  static void
  new_test_list()
  {
! 	string_ty	*project_name;
  	long		change_number;
  
  	trace(("new_test_list()\n{\n"/*}*/));
***************
*** 229,245 ****
  {
  	cstate		cstate_data;
  	pstate		pstate_data;
! 	string_t	*s1;
! 	string_t	*s2;
! 	string_t	*dd;
  	cstate_src	src_data;
  	int		manual_flag;
  	int		automatic_flag;
! 	string_t	*project_name;
! 	project_t	*pp;
  	long		change_number;
! 	change_t	*cp;
! 	user_t		*up;
  
  	trace(("new_test_main()\n{\n"/*}*/));
  	manual_flag = 0;
--- 254,270 ----
  {
  	cstate		cstate_data;
  	pstate		pstate_data;
! 	string_ty	*s1;
! 	string_ty	*s2;
! 	string_ty	*dd;
  	cstate_src	src_data;
  	int		manual_flag;
  	int		automatic_flag;
! 	string_ty	*project_name;
! 	project_ty	*pp;
  	long		change_number;
! 	change_ty	*cp;
! 	user_ty		*up;
  
  	trace(("new_test_main()\n{\n"/*}*/));
  	manual_flag = 0;
***************
*** 349,355 ****
  	 * Create each file in the development directory.
  	 * Create any necessary directories along the way.
  	 */
! 	dd = change_development_directory_get(cp);
  	change_pconf_get(cp);
  	s1 =
  		str_format
--- 374,380 ----
  	 * Create each file in the development directory.
  	 * Create any necessary directories along the way.
  	 */
! 	dd = change_development_directory_get(cp, 1);
  	change_pconf_get(cp);
  	s1 =
  		str_format
***************
*** 365,390 ****
  	s2 = str_format("%S/%S", dd, s1);
  	if (!os_exists(s2))
  	{
! 		FILE		*fp;
! 		string_t	*template;
  
  		os_become_undo();
  		template = change_file_template(cp, s1);
  		user_become(up);
! 		fp = fopen(s2->str_text, "w");
! 		if (!fp)
  			nfatal("create(\"%s\")", s2->str_text);
  		if (template)
  		{
! 			fwrite
  			(
  				template->str_text,
! 				template->str_length,
! 				1,
! 				fp
  			);
  		}
! 		fclose(fp);
  		os_chmod(s2, 0644 & ~change_umask(cp));
  	}
  	str_free(s2);
--- 390,415 ----
  	s2 = str_format("%S/%S", dd, s1);
  	if (!os_exists(s2))
  	{
! 		int		fd;
! 		string_ty	*template;
  
  		os_become_undo();
  		template = change_file_template(cp, s1);
  		user_become(up);
! 		fd = glue_creat(s2->str_text, 0666);
! 		if (fd < 0)
  			nfatal("create(\"%s\")", s2->str_text);
  		if (template)
  		{
! 			glue_write
  			(
+ 				fd,
  				template->str_text,
! 				template->str_length
  			);
+ 			str_free(template);
  		}
! 		glue_close(fd);
  		os_chmod(s2, 0644 & ~change_umask(cp));
  	}
  	str_free(s2);
***************
*** 501,509 ****
  "",
  "	-Change <number>",
  "		This option may be used to specify a particular",
! "		change within a project.  If the user is only",
! "		working on one change within a project, that is",
! "		the default change number.",
  "",
  "	-Help",
  "		This option may be used to obtain more",
--- 526,539 ----
  "",
  "	-Change <number>",
  "		This option may be used to specify a particular",
! "		change within a project.  When no -Change option is",
! "		specified, the AEGIS_CHANGE environment variable is",
! "		consulted.  If that does not exist, the user's",
! "		$HOME/.aegisrc file is examined for a default change",
! "		field (see aeuconf(5) for more information).  If",
! "		that does not exist, when the user is only working",
! "		on one change within a project, that is the default",
! "		change number.  Otherwise, it is an error.",
  "",
  "	-Help",
  "		This option may be used to obtain more",
***************
*** 520,533 ****
  "",
  "	-Project <name>",
  "		This option may be used to select the project of",
! "		interest.  When no -Project option is specified, if",
! "		the user is only working on changes within a single",
! "		project, the project name defaults to that project;",
! "		if the user is currently working on changes to more",
! "		than one project, or is not working on changes to",
! "		any project, the user's $HOME/.%src file is",
! "		examined for a default project field (see aeuconf(5)",
! "		for more information).",
  "",
  "	-TERse",
  "		This option may be used to cause listings to",
--- 550,563 ----
  "",
  "	-Project <name>",
  "		This option may be used to select the project of",
! "		interest.  When no -Project option is specified, the",
! "		AEGIS_PROJECT environment variable is consulted.  If",
! "		that does not exist, the user's $HOME/.aegisrc file",
! "		is examined for a default project field (see",
! "		aeuconf(5) for more information).  If that does not",
! "		exist, when the user is only working on changes",
! "		within a single project, the project name defaults",
! "		to that project.  Otherwise, it is an error.",
  "",
  "	-TERse",
  "		This option may be used to cause listings to",
***************
*** 541,551 ****
  "		option this option causes column headings to be",
  "		added.",
  "",
! "	All options are case insensitive.  Options may be",
! "	abbreviated; the abbreviation is the upper case letters.",
  "	Options and other command line arguments may be mixed",
! "	arbitrarily on the command line.",
  "",
  "RECOMMENDED ALIAS",
  "	The recommended alias for this command is",
  "	csh%%	alias aentu '%s -ntu \\!$ -v'",
--- 571,599 ----
  "		option this option causes column headings to be",
  "		added.",
  "",
! "	All options may be abbreviated; the abbreviation is",
! "	documented as the upper case letters, all lower case",
! "	letters and underscores (_) are optional.  You must use",
! "	consecutive sequences of optional letters.",
! "",
! "	All options are case insensitive, you may type them in",
! "	upper case or lower case or a combination of both, case",
! "	is not important.",
! "",
! "	For example: the arguments \"-project, \"-PROJ\" and \"-p\"",
! "	are all interpreted to mean the -Project option.  The",
! "	argument \"-prj\" will not be understood, because",
! "	consecutive optional characters were not supplied.",
! "",
  "	Options and other command line arguments may be mixed",
! "	arbitrarily on the command line, after the function",
! "	selectors.",
  "",
+ "	The GNU long option names are understood.  Since all",
+ "	option names for aegis are long, this means ignoring the",
+ "	extra leading '-'.  The \"--option=value\" convention is",
+ "	also understood.",
+ "",
  "RECOMMENDED ALIAS",
  "	The recommended alias for this command is",
  "	csh%%	alias aentu '%s -ntu \\!$ -v'",
***************
*** 581,587 ****
  static void
  new_test_undo_list()
  {
! 	string_t	*project_name;
  	long		change_number;
  
  	trace(("new_test_undo_list()\n{\n"/*}*/));
--- 629,635 ----
  static void
  new_test_undo_list()
  {
! 	string_ty	*project_name;
  	long		change_number;
  
  	trace(("new_test_undo_list()\n{\n"/*}*/));
***************
*** 635,648 ****
  	cstate		cstate_data;
  	pstate		pstate_data;
  	int		j;
! 	string_t	*s1;
! 	string_t	*s2;
  	int		keep;
! 	string_t	*project_name;
! 	project_t	*pp;
  	long		change_number;
! 	change_t	*cp;
! 	user_t		*up;
  
  	trace(("new_test_undo_main()\n{\n"/*}*/));
  	project_name = 0;
--- 683,698 ----
  	cstate		cstate_data;
  	pstate		pstate_data;
  	int		j;
! 	string_ty	*s1;
! 	string_ty	*s2;
  	int		keep;
! 	string_ty	*project_name;
! 	project_ty	*pp;
  	long		change_number;
! 	change_ty	*cp;
! 	user_ty		*up;
! 	string_ty	*dd;
! 	string_ty	*bl;
  
  	trace(("new_test_undo_main()\n{\n"/*}*/));
  	project_name = 0;
***************
*** 660,666 ****
  		case arglex_token_string:
  			s1 = str_from_c(arglex_value.alv_string);
  			os_become_orig();
! 			s2 = os_pathname(s1);
  			os_become_undo();
  			str_free(s1);
  			if (wl_member(&wl, s2))
--- 710,716 ----
  		case arglex_token_string:
  			s1 = str_from_c(arglex_value.alv_string);
  			os_become_orig();
! 			s2 = os_pathname(s1, 1);
  			os_become_undo();
  			str_free(s1);
  			if (wl_member(&wl, s2))
***************
*** 754,766 ****
  	 * 3.	if the file is inside the baseline, ok
  	 * 4.	if neither, error
  	 */
  	for (j = 0; j < wl.wl_nwords; ++j)
  	{
  		s1 = wl.wl_word[j];
  		assert(s1->str_text[0] == '/');
! 		s2 = os_below_dir(cstate_data->development_directory, s1);
  		if (!s2)
! 			s2 = os_below_dir(project_baseline_path_get(pp), s1);
  		if (!s2)
  			change_fatal(cp, "path \"%S\" unrelated", s1);
  		str_free(s1);
--- 804,818 ----
  	 * 3.	if the file is inside the baseline, ok
  	 * 4.	if neither, error
  	 */
+ 	dd = change_development_directory_get(cp, 1);
+ 	bl = project_baseline_path_get(pp, 1);
  	for (j = 0; j < wl.wl_nwords; ++j)
  	{
  		s1 = wl.wl_word[j];
  		assert(s1->str_text[0] == '/');
! 		s2 = os_below_dir(dd, s1);
  		if (!s2)
! 			s2 = os_below_dir(bl, s1);
  		if (!s2)
  			change_fatal(cp, "path \"%S\" unrelated", s1);
  		str_free(s1);
***************
*** 801,809 ****
  	 */
  	if (!keep)
  	{
- 		string_t	*dd;
- 
- 		dd = change_development_directory_get(cp);
  		user_become(up);
  		for (j = 0; j < wl.wl_nwords; ++j)
  		{
--- 853,858 ----
Index: aegis/new_test.h
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
Index: aegis/os.c
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 34,39 ****
--- 34,40 ----
  #include <dir.h>
  #include <error.h>
  #include <file.h>
+ #include <glue.h>
  #include <mem.h>
  #include <option.h>
  #include <os.h>
***************
*** 43,70 ****
  
  #define MAX_CMD_RPT 36
  
- /*
-  * where the automounter puts things
-  *
-  * The code which deals with the auto-mounter makes a few big assumptions:
-  * 1. it assumes the file systems appear to be in the same place on
-  *	every system (rather confusing for users if they don't),
-  * 2. it assumes that the auto-mounter mount directory is in the default
-  *	place on every system (you have to change the code to change the dir),
-  * 3. it assumes that the auto-mounter preserves the name under the mount tree,
-  *	and thus by taking it off, will derive the "real" name.
-  */
- static char tmp_mnt[] = "/tmp_mnt/";
  
  
  int
  os_exists(path)
! 	string_t	*path;
  {
  	struct stat	st;
  
  	os_become_must_be_active();
! 	if (stat(path->str_text, &st))
  	{
  		if (errno != ENOENT)
  			nfatal("stat(\"%s\")", path->str_text);
--- 44,129 ----
  
  #define MAX_CMD_RPT 36
  
  
+ static int interrupted;
  
+ 
+ static void interrupt _((int));
+ 
+ static void
+ interrupt(n)
+ 	int	n;
+ {
+ 	interrupted++;
+ 	signal(n, interrupt);
+ }
+ 
+ 
  int
+ os_waitpid_status(child, cmd)
+ 	int		child;
+ 	char		*cmd;
+ {
+ 	int		result;
+ 	void		(*hold)_((int));
+ 	int		a, b, c;
+ 	int		status;
+ 
+ 	trace(("os_waitpid_status(child = %d, cmd = \"%s\")\n{\n"/*}*/, child, cmd));
+ 	interrupted = 0;
+ 	hold = signal(SIGINT, SIG_IGN);
+ 	if (hold != SIG_IGN)
+ 		signal(SIGINT, interrupt);
+ 	result = 0;
+ 	if (os_waitpid(child, &status))
+ 		nfatal("wait");
+ 	a = (status >> 8) & 0xFF;
+ 	b = (status >> 7) & 1;
+ 	c = status & 0x7F;
+ 	switch (c)
+ 	{
+ 	case 0x7F:
+ 		/*
+ 		 * process was stopped,
+ 		 * since we didn't do it, treat it as an error
+ 		 */
+ 		fatal("command \"%s\" stopped", cmd);
+ 
+ 	case 0:
+ 		/* normal termination */
+ 		result = a;
+ 		break;
+ 
+ 	default:
+ 		/*
+ 		 * process dies from unhandled condition
+ 		 */
+ 		fatal
+ 		(
+ 			"command \"%s\" terminated by %s%s",
+ 			cmd,
+ 			signal_name(c),
+ 			(b ? " (core dumped)" : "")
+ 		);
+ 	}
+ 	if (hold != SIG_IGN)
+ 		signal(SIGINT, hold);
+ 	if (interrupted)
+ 		fatal("interrupted");
+ 	trace(("return %d;\n", result));
+ 	trace((/*{*/"}\n"));
+ 	return result;
+ }
+ 
+ 
+ int
  os_exists(path)
! 	string_ty	*path;
  {
  	struct stat	st;
  
  	os_become_must_be_active();
! 	if (glue_stat(path->str_text, &st))
  	{
  		if (errno != ENOENT)
  			nfatal("stat(\"%s\")", path->str_text);
***************
*** 76,82 ****
  
  void
  os_mkdir(path, mode)
! 	string_t	*path;
  	int		mode;
  {
  	int		uid;
--- 135,141 ----
  
  void
  os_mkdir(path, mode)
! 	string_ty	*path;
  	int		mode;
  {
  	int		uid;
***************
*** 86,92 ****
  	trace(("os_mkdir(path = \"%s\", mode = 0%o)\n{\n"/*}*/,
  		path->str_text, mode));
  	os_become_must_be_active();
! 	if (mkdir(path->str_text, mode))
  		nfatal("mkdir(\"%s\", 0%o)", path->str_text, mode);
  
  	/*
--- 145,151 ----
  	trace(("os_mkdir(path = \"%s\", mode = 0%o)\n{\n"/*}*/,
  		path->str_text, mode));
  	os_become_must_be_active();
! 	if (glue_mkdir(path->str_text, mode))
  		nfatal("mkdir(\"%s\", 0%o)", path->str_text, mode);
  
  	/*
***************
*** 95,101 ****
  	 * the one intended (egid).
  	 */
  	os_become_query(&uid, &gid, &um);
! 	if (chown(path->str_text, -1, gid))
  		nfatal("chgrp(\"%s\", %d)", path->str_text, gid);
  
  	/*
--- 154,160 ----
  	 * the one intended (egid).
  	 */
  	os_become_query(&uid, &gid, &um);
! 	if (glue_chown(path->str_text, -1, gid))
  		nfatal("chgrp(\"%s\", %d)", path->str_text, gid);
  
  	/*
***************
*** 104,110 ****
  	 * so set it explicitly.
  	 */
  	mode &= ~um;
! 	if (chmod(path->str_text, mode))
  		nfatal("chmod(\"%s\", 0%0)", path->str_text, mode);
  	trace((/*{*/"}\n"));
  }
--- 163,169 ----
  	 * so set it explicitly.
  	 */
  	mode &= ~um;
! 	if (glue_chmod(path->str_text, mode))
  		nfatal("chmod(\"%s\", 0%0)", path->str_text, mode);
  	trace((/*{*/"}\n"));
  }
***************
*** 112,122 ****
  
  void
  os_rmdir(path)
! 	string_t	*path;
  {
  	trace(("os_rmdir(path = \"%s\")\n{\n"/*}*/, path->str_text));
  	os_become_must_be_active();
! 	if (rmdir(path->str_text))
  		nfatal("rmdir(\"%s\")", path->str_text);
  	trace((/*{*/"}\n"));
  }
--- 171,181 ----
  
  void
  os_rmdir(path)
! 	string_ty	*path;
  {
  	trace(("os_rmdir(path = \"%s\")\n{\n"/*}*/, path->str_text));
  	os_become_must_be_active();
! 	if (glue_rmdir(path->str_text))
  		nfatal("rmdir(\"%s\")", path->str_text);
  	trace((/*{*/"}\n"));
  }
***************
*** 124,134 ****
  
  void
  os_rmdir_errok(path)
! 	string_t	*path;
  {
  	trace(("os_rmdir_errok(path = \"%s\")\n{\n"/*}*/, path->str_text));
  	os_become_must_be_active();
! 	if (rmdir(path->str_text))
  		nerror("warning: rmdir(\"%s\")", path->str_text);
  	trace((/*{*/"}\n"));
  }
--- 183,193 ----
  
  void
  os_rmdir_errok(path)
! 	string_ty	*path;
  {
  	trace(("os_rmdir_errok(path = \"%s\")\n{\n"/*}*/, path->str_text));
  	os_become_must_be_active();
! 	if (glue_rmdir(path->str_text))
  		nerror("warning: rmdir(\"%s\")", path->str_text);
  	trace((/*{*/"}\n"));
  }
***************
*** 136,148 ****
  
  void
  os_mkdir_between(top, extn, mode)
! 	string_t	*top;
! 	string_t	*extn;
  	int		mode;
  {
  	char		*cp;
! 	string_t	*s1;
! 	string_t	*s2;
  
  	trace(("os_mkdir_between(top = %08lX, extn = %08lX, \
  mode = 0%o)\n{\n"/*}*/, top, extn, mode));
--- 195,207 ----
  
  void
  os_mkdir_between(top, extn, mode)
! 	string_ty	*top;
! 	string_ty	*extn;
  	int		mode;
  {
  	char		*cp;
! 	string_ty	*s1;
! 	string_ty	*s2;
  
  	trace(("os_mkdir_between(top = %08lX, extn = %08lX, \
  mode = 0%o)\n{\n"/*}*/, top, extn, mode));
***************
*** 169,184 ****
  	trace((/*{*/"}\n"));
  }
  
  void
  os_rename(a, b)
! 	string_t	*a;
! 	string_t	*b;
  {
  	trace(("os_rename(a = %08lX, b = %08lX)\n{\n"/*}*/, a, b));
  	os_become_must_be_active();
  	trace_string(a->str_text);
  	trace_string(b->str_text);
! 	if (rename(a->str_text, b->str_text))
  		nfatal("rename(\"%s\", \"%s\")", a->str_text, b->str_text);
  	trace((/*{*/"}\n"));
  }
--- 228,244 ----
  	trace((/*{*/"}\n"));
  }
  
+ 
  void
  os_rename(a, b)
! 	string_ty	*a;
! 	string_ty	*b;
  {
  	trace(("os_rename(a = %08lX, b = %08lX)\n{\n"/*}*/, a, b));
  	os_become_must_be_active();
  	trace_string(a->str_text);
  	trace_string(b->str_text);
! 	if (glue_rename(a->str_text, b->str_text))
  		nfatal("rename(\"%s\", \"%s\")", a->str_text, b->str_text);
  	trace((/*{*/"}\n"));
  }
***************
*** 185,191 ****
  
  void
  os_unlink(path)
! 	string_t	*path;
  {
  	struct stat	st;
  
--- 245,251 ----
  
  void
  os_unlink(path)
! 	string_ty	*path;
  {
  	struct stat	st;
  
***************
*** 198,212 ****
  	 * because we are set-uid-root, and root can unlink directories!
  	 */
  #ifdef S_IFLNK
! 	if (lstat(path->str_text, &st))
  		nfatal("lstat(\"%s\")", path->str_text);
  #else
! 	if (stat(path->str_text, &st))
  		nfatal("stat(\"%s\")", path->str_text);
  #endif
  	if ((st.st_mode & S_IFMT) == S_IFDIR)
  		fatal("unlink(\"%s\"): is a directory", path->str_text);
! 	if (unlink(path->str_text))
  		nfatal("unlink(\"%s\")", path->str_text);
  	trace((/*{*/"}\n"));
  }
--- 258,272 ----
  	 * because we are set-uid-root, and root can unlink directories!
  	 */
  #ifdef S_IFLNK
! 	if (glue_lstat(path->str_text, &st))
  		nfatal("lstat(\"%s\")", path->str_text);
  #else
! 	if (glue_stat(path->str_text, &st))
  		nfatal("stat(\"%s\")", path->str_text);
  #endif
  	if ((st.st_mode & S_IFMT) == S_IFDIR)
  		fatal("unlink(\"%s\"): is a directory", path->str_text);
! 	if (glue_unlink(path->str_text))
  		nfatal("unlink(\"%s\")", path->str_text);
  	trace((/*{*/"}\n"));
  }
***************
*** 213,219 ****
  
  void
  os_unlink_errok(path)
! 	string_t	*path;
  {
  	struct stat	st;
  
--- 273,279 ----
  
  void
  os_unlink_errok(path)
! 	string_ty	*path;
  {
  	struct stat	st;
  
***************
*** 226,232 ****
  	 * because we are set-uid-root, and root can unlink directories!
  	 */
  #ifdef S_IFLNK
! 	if (lstat(path->str_text, &st))
  	{
  		if (errno != ENOENT)
  			nfatal("lstat(\"%s\")", path->str_text);
--- 286,292 ----
  	 * because we are set-uid-root, and root can unlink directories!
  	 */
  #ifdef S_IFLNK
! 	if (glue_lstat(path->str_text, &st))
  	{
  		if (errno != ENOENT)
  			nfatal("lstat(\"%s\")", path->str_text);
***************
*** 234,240 ****
  		goto done;
  	}
  #else
! 	if (stat(path->str_text, &st))
  	{
  		if (errno != ENOENT)
  			nfatal("stat(\"%s\")", path->str_text);
--- 294,300 ----
  		goto done;
  	}
  #else
! 	if (glue_stat(path->str_text, &st))
  	{
  		if (errno != ENOENT)
  			nfatal("stat(\"%s\")", path->str_text);
***************
*** 251,257 ****
  		);
  		goto done;
  	}
! 	if (unlink(path->str_text))
  		nerror("warning: unlink(\"%s\")", path->str_text);
  
  	/*
--- 311,317 ----
  		);
  		goto done;
  	}
! 	if (glue_unlink(path->str_text))
  		nerror("warning: unlink(\"%s\")", path->str_text);
  
  	/*
***************
*** 264,276 ****
  
  /*
   * NAME
!  *	os_curdir - full current directory path
   *
   * SYNOPSIS
!  *	string_t *os_curdir(void);
   *
   * DESCRIPTION
!  *	Os_curdir is used to determine the full pathname
   *	of the current directory.
   *
   * RETURNS
--- 324,336 ----
  
  /*
   * NAME
!  *	os_curdir_sub - get current directory
   *
   * SYNOPSIS
!  *	string_ty *os_curdir_sub(void);
   *
   * DESCRIPTION
!  *	The os_curdir_sub function is used to determine the system's idea
   *	of the current directory.
   *
   * RETURNS
***************
*** 278,290 ****
   *	A null pointer is returned on error.
   *
   * CAVEAT
!  *	Use str_free() when you are done with the value returned.
   */
  
! string_t *
! os_curdir()
  {
! 	static string_t	*s;
  
  	os_become_must_be_active();
  	if (!s)
--- 338,352 ----
   *	A null pointer is returned on error.
   *
   * CAVEAT
!  *	DO NOT use str_free() on the value returned.
   */
  
! static string_ty *os_curdir_sub _((void));
! 
! static string_ty *
! os_curdir_sub()
  {
! 	static string_ty	*s;
  
  	os_become_must_be_active();
  	if (!s)
***************
*** 291,320 ****
  	{
  		char	buffer[2000];
  
! 		if (!getcwd(buffer, sizeof(buffer)))
  			nfatal("getcwd");
  		assert(buffer[0] == '/');
! 		assert(tmp_mnt[sizeof(tmp_mnt) - 1] == 0);
! 		if (!memcmp(buffer, tmp_mnt, sizeof(tmp_mnt) - 1))
! 			s = str_from_c(buffer + sizeof(tmp_mnt) - 2);
! 		else
! 			s = str_from_c(buffer);
  	}
! 	return str_copy(s);
  }
  
  
  /*
   * NAME
   *	os_pathname - determine full file name
   *
   * SYNOPSIS
!  *	string_t *os_pathname(string_t *path);
   *
   * DESCRIPTION
   *	Os_pathname is used to determine the full path name
   *	of a partial path given.
   *
   * RETURNS
   *	pointer to dynamically allocated string.
   *
--- 353,419 ----
  	{
  		char	buffer[2000];
  
! 		if (!glue_getcwd(buffer, sizeof(buffer)))
  			nfatal("getcwd");
  		assert(buffer[0] == '/');
! 		s = str_from_c(buffer);
  	}
! 	return s;
  }
  
  
  /*
   * NAME
+  *	os_curdir - full current directory path
+  *
+  * SYNOPSIS
+  *	string_ty *os_curdir(void);
+  *
+  * DESCRIPTION
+  *	Os_curdir is used to determine the pathname
+  *	of the current directory.  Automounter vaguaries will be elided.
+  *
+  * RETURNS
+  *	A pointer to a string in dynamic memory is returned.
+  *	A null pointer is returned on error.
+  *
+  * CAVEAT
+  *	Use str_free() when you are done with the value returned.
+  */
+ 
+ string_ty *
+ os_curdir()
+ {
+ 	static string_ty	*result;
+ 
+ 	os_become_must_be_active();
+ 	if (!result)
+ 	{
+ 		string_ty	*dot;
+ 		
+ 		dot = str_from_c(".");
+ 		result = os_pathname(dot, 1);
+ 		str_free(dot);
+ 	}
+ 	return str_copy(result);
+ }
+ 
+ 
+ /*
+  * NAME
   *	os_pathname - determine full file name
   *
   * SYNOPSIS
!  *	string_ty *os_pathname(string_ty *path, int resolve);
   *
   * DESCRIPTION
   *	Os_pathname is used to determine the full path name
   *	of a partial path given.
   *
+  * ARGUMENTS
+  *	path	- path to canonicalize
+  *	resolve	- non-zero if should resolve symlinks, 0 if not
+  *
   * RETURNS
   *	pointer to dynamically allocated string.
   *
***************
*** 322,330 ****
   *	Use str_free() when you are done with the value returned.
   */
  
! string_t *
! os_pathname(path)
! 	string_t	*path;
  {
  	static char	*tmp;
  	static size_t	tmplen;
--- 421,430 ----
   *	Use str_free() when you are done with the value returned.
   */
  
! string_ty *
! os_pathname(path, resolve)
! 	string_ty	*path;
! 	int		resolve;
  {
  	static char	*tmp;
  	static size_t	tmplen;
***************
*** 333,342 ****
  	int		c;
  	int		found;
  #ifdef S_IFLNK
- 	char		link[2000];
- 	int		nbytes;
  	wlist		loop;
- 	string_t	*s;
  #endif
  
  	/*
--- 433,439 ----
***************
*** 343,359 ****
  	 * Change relative pathnames to absolute
  	 */
  	trace(("os_pathname(path = %08lX)\n{\n"/*}*/, path));
! 	os_become_must_be_active();
  	trace_string(path->str_text);
  	if (path->str_text[0] != '/')
! 	{
! 		string_t	*cwd;
! 
! 		cwd = os_curdir();
! 		assert(cwd);
! 		path = str_format("%S/%S", cwd, path);
! 		str_free(cwd);
! 	}
  	else
  		path = str_copy(path);
  	if (!tmp)
--- 440,450 ----
  	 * Change relative pathnames to absolute
  	 */
  	trace(("os_pathname(path = %08lX)\n{\n"/*}*/, path));
! 	if (resolve)
! 		os_become_must_be_active();
  	trace_string(path->str_text);
  	if (path->str_text[0] != '/')
! 		path = str_format("%S/%S", os_curdir_sub(), path);
  	else
  		path = str_copy(path);
  	if (!tmp)
***************
*** 447,518 ****
  		 * see if the path so far is a symbolic link
  		 */
  #ifdef S_IFLNK
! 		s = str_n_from_c(tmp, opos);
! 		if (wl_member(&loop, s))
  		{
! 			fatal
! 			(
! 				"symbolic link loop \"%s\" detected",
! 				s->str_text
! 			);
! 		}
! 		nbytes = readlink(s->str_text, link, sizeof(link) - 1);
! 		if (nbytes < 0)
! 		{
! 			/*
! 			 * probably not a symbolic link
! 			 */
! 			if (errno != EINVAL && errno != ENOENT)
! 				nfatal("readlink(\"%s\")", s->str_text);
! 			not_a_sym_link:
! 			str_free(s);
! 		}
! 		else
! 		{
! 			string_t	*newpath;
  
! 			if (nbytes == 0)
  			{
  				fatal
  				(
! 					"readlink(\"%s\") returned \"\"",
  					s->str_text
  				);
  			}
! 			link[nbytes] = 0;
! 
! 			/*
! 			 * check for auto-mounter symlinks
! 			 * and leave them alone,
! 			 * they change for every auto-mount.
! 			 */
! 			if (!memcmp(link, tmp_mnt, sizeof(tmp_mnt) - 1))
! 				goto not_a_sym_link;
! 
! 			wl_append(&loop, s);
! 			str_free(s);
! 			if (link[0] == '/')
! 				tmp[1] = 0;
  			else
  			{
! 				while (tmp[opos - 1] != '/')
! 					opos--;
! 				tmp[opos] = 0;
  			}
- 			newpath =
- 				str_format
- 				(
- 					"%s/%s/%s",
- 					tmp,
- 					link,
- 					path->str_text + ipos
- 				);
- 			str_free(path);
- 			path = newpath;
- 			ipos = 0;
- 			opos = 0;
- 			found = 0;
- 			continue;
  		}
  #endif
  	
--- 538,607 ----
  		 * see if the path so far is a symbolic link
  		 */
  #ifdef S_IFLNK
! 		if (resolve)
  		{
! 			char		link[2000];
! 			int		nbytes;
! 			string_ty	*s;
  
! 			s = str_n_from_c(tmp, opos);
! 			if (wl_member(&loop, s))
  			{
  				fatal
  				(
! 					"symbolic link loop \"%s\" detected",
  					s->str_text
  				);
  			}
! 			nbytes = glue_readlink(s->str_text, link, sizeof(link) - 1);
! 			if (nbytes < 0)
! 			{
! 				/*
! 				 * probably not a symbolic link
! 				 */
! 				if (errno != EINVAL && errno != ENOENT)
! 					nfatal("readlink(\"%s\")", s->str_text);
! 				str_free(s);
! 			}
  			else
  			{
! 				string_ty	*newpath;
! 	
! 				if (nbytes == 0)
! 				{
! 					fatal
! 					(
! 					       "readlink(\"%s\") returned \"\"",
! 						s->str_text
! 					);
! 				}
! 				link[nbytes] = 0;
! 	
! 				wl_append(&loop, s);
! 				str_free(s);
! 				if (link[0] == '/')
! 					tmp[1] = 0;
! 				else
! 				{
! 					while (tmp[opos - 1] != '/')
! 						opos--;
! 					tmp[opos] = 0;
! 				}
! 				newpath =
! 					str_format
! 					(
! 						"%s/%s/%s",
! 						tmp,
! 						link,
! 						path->str_text + ipos
! 					);
! 				str_free(path);
! 				path = newpath;
! 				ipos = 0;
! 				opos = 0;
! 				found = 0;
! 				continue;
  			}
  		}
  #endif
  	
***************
*** 548,554 ****
   *	os_entryname - take path apart
   *
   * SYNOPSIS
!  *	string_t *os_entryname(string_t *path);
   *
   * DESCRIPTION
   *	Os_entryname is used to extract the entry part
--- 637,643 ----
   *	os_entryname - take path apart
   *
   * SYNOPSIS
!  *	string_ty *os_entryname(string_ty *path);
   *
   * DESCRIPTION
   *	Os_entryname is used to extract the entry part
***************
*** 561,576 ****
   *	Use str_free() when you are done with the return value.
   */
  
! string_t *
  os_entryname(path)
! 	string_t	*path;
  {
! 	string_t	*s;
  	char		*cp;
  
  	trace(("os_entryname(path = %08lX)\n{\n"/*}*/, path));
  	trace_string(path->str_text);
! 	s = os_pathname(path);
  	cp = strrchr(s->str_text, '/');
  	if (cp && s->str_length > 1)
  		path = str_from_c(cp + 1);
--- 650,665 ----
   *	Use str_free() when you are done with the return value.
   */
  
! string_ty *
  os_entryname(path)
! 	string_ty	*path;
  {
! 	string_ty	*s;
  	char		*cp;
  
  	trace(("os_entryname(path = %08lX)\n{\n"/*}*/, path));
  	trace_string(path->str_text);
! 	s = os_pathname(path, 1);
  	cp = strrchr(s->str_text, '/');
  	if (cp && s->str_length > 1)
  		path = str_from_c(cp + 1);
***************
*** 588,594 ****
   *	os_dirname - take path apart
   *
   * SYNOPSIS
!  *	string_t *os_dirname(string_t *path);
   *
   * DESCRIPTION
   *	Os_dirname is used to extract the directory part
--- 677,683 ----
   *	os_dirname - take path apart
   *
   * SYNOPSIS
!  *	string_ty *os_dirname(string_ty *path);
   *
   * DESCRIPTION
   *	Os_dirname is used to extract the directory part
***************
*** 601,616 ****
   *	Use str_free() when you are done with the value returned.
   */
  
! string_t *
  os_dirname(path)
! 	string_t	*path;
  {
! 	string_t	*s;
  	char		*cp;
  
  	trace(("os_dirname(path = %08lX)\n{\n"/*}*/, path));
  	trace_string(path->str_text);
! 	s = os_pathname(path);
  	cp = strrchr(s->str_text, '/');
  	assert(cp);
  	if (cp > s->str_text)
--- 690,705 ----
   *	Use str_free() when you are done with the value returned.
   */
  
! string_ty *
  os_dirname(path)
! 	string_ty	*path;
  {
! 	string_ty	*s;
  	char		*cp;
  
  	trace(("os_dirname(path = %08lX)\n{\n"/*}*/, path));
  	trace_string(path->str_text);
! 	s = os_pathname(path, 1);
  	cp = strrchr(s->str_text, '/');
  	assert(cp);
  	if (cp > s->str_text)
***************
*** 626,635 ****
  }
  
  
! string_t *
  os_below_dir(higher, lower)
! 	string_t	*higher;
! 	string_t	*lower;
  {
  	char		*s1;
  	char		*s2;
--- 715,724 ----
  }
  
  
! string_ty *
  os_below_dir(higher, lower)
! 	string_ty	*higher;
! 	string_ty	*lower;
  {
  	char		*s1;
  	char		*s2;
***************
*** 650,656 ****
  
  void
  os_chdir(path)
! 	string_t	*path;
  {
  	os_become_must_not_be_active();
  	if (chdir(path->str_text))
--- 739,745 ----
  
  void
  os_chdir(path)
! 	string_ty	*path;
  {
  	os_become_must_not_be_active();
  	if (chdir(path->str_text))
***************
*** 680,688 ****
  
  void
  os_execute(cmd, flags, dir)
! 	string_t	*cmd;
  	int		flags;
! 	string_t	*dir;
  {
  	int		result;
  
--- 769,777 ----
  
  void
  os_execute(cmd, flags, dir)
! 	string_ty	*cmd;
  	int		flags;
! 	string_ty	*dir;
  {
  	int		result;
  
***************
*** 690,696 ****
  	result = os_execute_retcode(cmd, flags, dir);
  	if (result)
  	{
! 		string_t	*s;
  
  		if (cmd->str_length > MAX_CMD_RPT)
  			s = str_format("%.*S...", MAX_CMD_RPT - 3, cmd);
--- 779,785 ----
  	result = os_execute_retcode(cmd, flags, dir);
  	if (result)
  	{
! 		string_ty	*s;
  
  		if (cmd->str_length > MAX_CMD_RPT)
  			s = str_format("%.*S...", MAX_CMD_RPT - 3, cmd);
***************
*** 703,727 ****
  }
  
  
- static int interrupted;
- 
- 
- static void interrupt _((int));
- 
- static void
- interrupt(n)
- 	int	n;
- {
- 	interrupted++;
- 	signal(n, interrupt);
- }
- 
- 
  int
  os_execute_retcode(cmd, flags, dir)
! 	string_t	*cmd;
  	int		flags;
! 	string_t	*dir;
  {
  	int		uid;
  	int		gid;
--- 792,802 ----
  }
  
  
  int
  os_execute_retcode(cmd, flags, dir)
! 	string_ty	*cmd;
  	int		flags;
! 	string_ty	*dir;
  {
  	int		uid;
  	int		gid;
***************
*** 730,736 ****
  	int		result = 0;
  	static char	dev_null[] = "/dev/null";
  	void		(*hold)_((int));
! 	string_t	*cmd2;
  
  	trace(("os_execute_retcode()\n{\n"/*}*/));
  	os_become_must_be_active();
--- 805,812 ----
  	int		result = 0;
  	static char	dev_null[] = "/dev/null";
  	void		(*hold)_((int));
! 	string_ty	*cmd2;
! 	char		*shell;
  
  	trace(("os_execute_retcode()\n{\n"/*}*/));
  	os_become_must_be_active();
***************
*** 756,812 ****
  		hold = signal(SIGINT, SIG_IGN);
  		if (hold != SIG_IGN)
  			signal(SIGINT, interrupt);
! 		for (;;)
! 		{
! 			int	a, b, c;
! 			int	status;
! 			int	pid;
! 
! 			pid = wait(&status);
! 			if (pid < 0)
! 			{
! 				if (errno != EINTR)
! 					nfatal("wait");
! 				continue;
! 			}
! 			if (pid != child)
! 				continue;
! 
! 			a = (status >> 8) & 0xFF;
! 			b = (status >> 7) & 1;
! 			c = status & 0x7F;
! 			switch (c)
! 			{
! 			case 0x7F:
! 				/*
! 				 * process was stopped,
! 				 * since we didn't do it, treat it as an error
! 				 */
! 				fatal("command \"%s\" stopped", cmd2->str_text);
! 		
! 			case 0:
! 				/* normal termination */
! 				result = a;
! 				break;
! 		
! 			default:
! 				/*
! 				 * process dies from unhandled condition
! 				 */
! 				fatal
! 				(
! 					"command \"%s\" terminated by %s%s",
! 					cmd2->str_text,
! 					signal_name(c),
! 					(b ? " (core dumped)" : "")
! 				);
! 			}
! 			break;
! 		}
! 		if (hold != SIG_IGN)
! 			signal(SIGINT, hold);
! 		if (interrupted)
! 			fatal("interrupted");
  		break;
  
  	case 0:
--- 832,838 ----
  		hold = signal(SIGINT, SIG_IGN);
  		if (hold != SIG_IGN)
  			signal(SIGINT, interrupt);
! 		result = os_waitpid_status(child, cmd2->str_text);
  		break;
  
  	case 0:
***************
*** 821,827 ****
  		umask(um);
  
  		/*
! 		 * change directory to the top of the development directory.
  		 */
  		os_chdir(dir);
  
--- 847,853 ----
  		umask(um);
  
  		/*
! 		 * change directory to the appropriate directory.
  		 */
  		os_chdir(dir);
  
***************
*** 845,852 ****
  		/*
  		 * invoke the command through sh(1)
  		 */
! 		execl("/bin/sh", "sh", "-ec", cmd->str_text, (char *)0);
! 		nfatal("exec(\"/bin/sh\")");
  	}
  	if (result && (flags & OS_EXEC_FLAG_ERROK))
  	{
--- 871,879 ----
  		/*
  		 * invoke the command through sh(1)
  		 */
! 		shell = os_shell();
! 		execl(shell, shell, "-ec", cmd->str_text, (char *)0);
! 		nfatal("exec(\"%s\")", shell);
  	}
  	if (result && (flags & OS_EXEC_FLAG_ERROK))
  	{
***************
*** 867,873 ****
  
  time_t
  os_mtime(path)
! 	string_t	*path;
  {
  	struct stat	statbuf;
  	time_t		result;
--- 894,900 ----
  
  time_t
  os_mtime(path)
! 	string_ty	*path;
  {
  	struct stat	statbuf;
  	time_t		result;
***************
*** 876,882 ****
  	os_become_must_be_active();
  	trace_string(path->str_text);
  
! 	if (stat(path->str_text, &statbuf))
  		nfatal("stat(\"%s\")", path->str_text);
  
  	/*
--- 903,909 ----
  	os_become_must_be_active();
  	trace_string(path->str_text);
  
! 	if (glue_stat(path->str_text, &statbuf))
  		nfatal("stat(\"%s\")", path->str_text);
  
  	/*
***************
*** 896,902 ****
  
  void
  os_mtime_set(path, when)
! 	string_t	*path;
  	time_t		when;
  {
  	struct utimbuf	utb;
--- 923,929 ----
  
  void
  os_mtime_set(path, when)
! 	string_ty	*path;
  	time_t		when;
  {
  	struct utimbuf	utb;
***************
*** 907,913 ****
  	trace(("when = %s", ctime(&when)));
  	utb.actime = when;
  	utb.modtime = when;
! 	if (utime(path->str_text, &utb))
  		nfatal("utime(\"%s\")", path->str_text);
  	trace((/*{*/"}\n"));
  }
--- 934,940 ----
  	trace(("when = %s", ctime(&when)));
  	utb.actime = when;
  	utb.modtime = when;
! 	if (glue_utime(path->str_text, &utb))
  		nfatal("utime(\"%s\")", path->str_text);
  	trace((/*{*/"}\n"));
  }
***************
*** 915,921 ****
  
  void
  os_chown_check(path, mode, uid, gid)
! 	string_t	*path;
  	int		mode;
  	int		uid;
  	int		gid;
--- 942,948 ----
  
  void
  os_chown_check(path, mode, uid, gid)
! 	string_ty	*path;
  	int		mode;
  	int		uid;
  	int		gid;
***************
*** 926,932 ****
  	trace(("os_chown_check(path = \"%s\")\n{\n"/*}*/, path->str_text));
  	os_become_must_be_active();
  	nerrs = 0;
! 	if (stat(path->str_text, &st))
  		nfatal("stat(\"%s\")", path->str_text);
  	if (os_testing_mode())
  	{
--- 953,959 ----
  	trace(("os_chown_check(path = \"%s\")\n{\n"/*}*/, path->str_text));
  	os_become_must_be_active();
  	nerrs = 0;
! 	if (glue_stat(path->str_text, &st))
  		nfatal("stat(\"%s\")", path->str_text);
  	if (os_testing_mode())
  	{
***************
*** 997,1003 ****
  
  void
  os_chmod(path, mode)
! 	string_t	*path;
  	int		mode;
  {
  	trace(("os_chmod(path = \"%s\", mode = 0%o)\n{\n"/*}*/,
--- 1024,1030 ----
  
  void
  os_chmod(path, mode)
! 	string_ty	*path;
  	int		mode;
  {
  	trace(("os_chmod(path = \"%s\", mode = 0%o)\n{\n"/*}*/,
***************
*** 1004,1010 ****
  		path->str_text, mode));
  	mode &= 07777;
  	os_become_must_be_active();
! 	if (chmod(path->str_text, mode))
  		nfatal("chmod(\"%s\", 0%o)", path->str_text, mode);
  	trace((/*{*/"}\n"));
  }
--- 1031,1037 ----
  		path->str_text, mode));
  	mode &= 07777;
  	os_become_must_be_active();
! 	if (glue_chmod(path->str_text, mode))
  		nfatal("chmod(\"%s\", 0%o)", path->str_text, mode);
  	trace((/*{*/"}\n"));
  }
***************
*** 1012,1018 ****
  
  int
  os_chmod_query(path)
! 	string_t	*path;
  {
  	int		mode;
  	struct stat	st;
--- 1039,1045 ----
  
  int
  os_chmod_query(path)
! 	string_ty	*path;
  {
  	int		mode;
  	struct stat	st;
***************
*** 1019,1025 ****
  
  	trace(("os_chmod_query(path = \"%s\")\n{\n"/*}*/, path->str_text));
  	os_become_must_be_active();
! 	if (stat(path->str_text, &st))
  		nfatal("stat(\"%s\")", path->str_text);
  	mode = st.st_mode & 07777;
  	trace(("return %05o;\n", mode));
--- 1046,1052 ----
  
  	trace(("os_chmod_query(path = \"%s\")\n{\n"/*}*/, path->str_text));
  	os_become_must_be_active();
! 	if (glue_stat(path->str_text, &st))
  		nfatal("stat(\"%s\")", path->str_text);
  	mode = st.st_mode & 07777;
  	trace(("return %05o;\n", mode));
***************
*** 1030,1036 ****
  
  void
  os_chmod_errok(path, mode)
! 	string_t	*path;
  	int		mode;
  {
  	trace(("os_chmod_errok(path = \"%s\", mode = 0%o)\n{\n"/*}*/,
--- 1057,1063 ----
  
  void
  os_chmod_errok(path, mode)
! 	string_ty	*path;
  	int		mode;
  {
  	trace(("os_chmod_errok(path = \"%s\", mode = 0%o)\n{\n"/*}*/,
***************
*** 1037,1043 ****
  		path->str_text, mode));
  	os_become_must_be_active();
  	mode &= 07777;
! 	if (chmod(path->str_text, mode))
  		nerror("warning: chmod(\"%s\", 0%o)", path->str_text, mode);
  	trace((/*{*/"}\n"));
  }
--- 1064,1070 ----
  		path->str_text, mode));
  	os_become_must_be_active();
  	mode &= 07777;
! 	if (glue_chmod(path->str_text, mode))
  		nerror("warning: chmod(\"%s\", 0%o)", path->str_text, mode);
  	trace((/*{*/"}\n"));
  }
***************
*** 1045,1071 ****
  
  void
  os_link(from, to)
! 	string_t	*from;
! 	string_t	*to;
  {
  	trace(("os_link(from = %08lX, to = %08lX)\n{\n"/*}*/, from, to));
  	os_become_must_be_active();
  	trace_string(from->str_text);
  	trace_string(to->str_text);
! 	if (link(from->str_text, to->str_text))
  		nfatal("link(\"%s\", \"%s\")", from->str_text, to->str_text);
  	trace((/*{*/"}\n"));
  }
  
  
! string_t *
  os_execute_slurp(cmd, flags, dir)
! 	string_t	*cmd;
  	int		flags;
! 	string_t	*dir;
  {
! 	string_t	*s1;
! 	string_t	*s2;
  
  	trace(("os_execute_slurp()\n{\n"/*}*/));
  	s1 = str_format("/tmp/%s.%d", option_get_progname(), getpid());
--- 1072,1098 ----
  
  void
  os_link(from, to)
! 	string_ty	*from;
! 	string_ty	*to;
  {
  	trace(("os_link(from = %08lX, to = %08lX)\n{\n"/*}*/, from, to));
  	os_become_must_be_active();
  	trace_string(from->str_text);
  	trace_string(to->str_text);
! 	if (glue_link(from->str_text, to->str_text))
  		nfatal("link(\"%s\", \"%s\")", from->str_text, to->str_text);
  	trace((/*{*/"}\n"));
  }
  
  
! string_ty *
  os_execute_slurp(cmd, flags, dir)
! 	string_ty	*cmd;
  	int		flags;
! 	string_ty	*dir;
  {
! 	string_ty	*s1;
! 	string_ty	*s2;
  
  	trace(("os_execute_slurp()\n{\n"/*}*/));
  	s1 = str_format("/tmp/%s.%d", option_get_progname(), getpid());
***************
*** 1093,1102 ****
--- 1120,1142 ----
  static	int	become_active_umask;
  
  
+ static void whoami _((int *, int *));
+ 
+ static void
+ whoami(uid, gid)
+ 	int	*uid;
+ 	int	*gid;
+ {
+ 	*uid = become_active_uid;
+ 	*gid = become_active_gid;
+ }
+ 
+ 
  void
  os_become_init()
  {
  	assert(!become_inited);
+ 	error_set_id_func(whoami);
  	become_active_umask = DEFAULT_UMASK;
  	become_orig_umask = umask(DEFAULT_UMASK);
  	become_orig_uid = getuid();
***************
*** 1148,1161 ****
  	become_active = 1;
  	if (os_testing_mode())
  		return;
  	if (setegid(gid))
  		nfatal("setegid(%d)", gid);
- 	become_active_uid = uid;
  	if (seteuid(uid))
  		nfatal("seteuid(%d)", uid);
- 	become_active_gid = gid;
  	umask(um);
! 	become_active_umask = um;
  }
  
  
--- 1188,1203 ----
  	become_active = 1;
  	if (os_testing_mode())
  		return;
+ 	become_active_uid = uid;
+ 	become_active_gid = gid;
+ 	become_active_umask = um;
+ #ifndef CONF_NO_seteuid
  	if (setegid(gid))
  		nfatal("setegid(%d)", gid);
  	if (seteuid(uid))
  		nfatal("seteuid(%d)", uid);
  	umask(um);
! #endif
  }
  
  
***************
*** 1167,1177 ****
  	become_active = 0;
  	if (become_testing)
  		return;
  	if (seteuid(0))
  		nfatal("seteuid(0)");
- 	become_active_uid = 0;
  	if (setegid(0))
  		nfatal("setegid(0)");
  	become_active_gid = 0;
  }
  
--- 1209,1221 ----
  	become_active = 0;
  	if (become_testing)
  		return;
+ #ifndef CONF_NO_seteuid
  	if (seteuid(0))
  		nfatal("seteuid(0)");
  	if (setegid(0))
  		nfatal("setegid(0)");
+ #endif
+ 	become_active_uid = 0;
  	become_active_gid = 0;
  }
  
***************
*** 1316,1319 ****
--- 1360,1476 ----
  	 * probably forground
  	 */
  	return 0;
+ }
+ 
+ 
+ int
+ os_readable(path)
+ 	string_ty	*path;
+ {
+ 	os_become_must_be_active();
+ 	if (glue_access(path->str_text, R_OK))
+ 		return errno;
+ 	return 0;
+ }
+ 
+ 
+ int
+ os_waitpid(child, status_p)
+ 	int		child;
+ 	int		*status_p;
+ {
+ 	typedef struct ret_ty ret_ty;
+ 	struct ret_ty
+ 	{
+ 		int	pid;
+ 		int	status;
+ 	};
+ 
+ 	static long	nret;
+ 	static long	nret_max;
+ 	static ret_ty	*ret;
+ 	int		pid;
+ 	int		status;
+ 	int		j;
+ 	int		result;
+ 
+ 	/*
+ 	 * see if we already have it
+ 	 */
+ 	trace(("os_waitpid(child = %d)\n{\n"/*}*/, child));
+ 	assert(child > 0);
+ 	result = 0;
+ 	for (j = 0; j < nret; ++j)
+ 	{
+ 		if (ret[j].pid != child)
+ 			continue;
+ 		*status_p = ret[j].status;
+ 		ret[j] = ret[--nret];
+ 		goto done;
+ 	}
+ 
+ 	/*
+ 	 * new one, go hunting
+ 	 */
+ 	for (;;)
+ 	{
+ 		/*
+ 		 * block until a child terminates,
+ 		 * or there are no more children
+ 		 */
+ 		pid = wait(&status);
+ 		if (pid == -1)
+ 		{
+ 			if (errno == EINTR)
+ 				continue;
+ 			result = -1;
+ 			break;
+ 		}
+ 
+ 		/*
+ 		 * stop if this is the child
+ 		 * we are looking for
+ 		 */
+ 		if (pid == child)
+ 		{
+ 			*status_p = status;
+ 			break;
+ 		}
+ 
+ 		/*
+ 		 * remember and keep going
+ 		 */
+ 		if (nret >= nret_max)
+ 		{
+ 			long	nbytes;
+ 
+ 			nret_max += 11;
+ 			nbytes = nret_max * sizeof(ret_ty);
+ 			if (!ret)
+ 				ret = (ret_ty *)mem_alloc(nbytes);
+ 			else
+ 				mem_change_size((char **)&ret, nbytes);
+ 		}
+ 		ret[nret].pid = pid;
+ 		ret[nret].status = status;
+ 		++nret;
+ 	}
+ 
+ 	/*
+ 	 * here for all exits
+ 	 */
+ 	done:
+ 	trace(("return %d;\n", result));
+ 	trace((/*{*/"}\n"));
+ 	return result;
+ }
+ 
+ 
+ char *
+ os_shell()
+ {
+ 	static char shell[] = CONF_SHELL;
+ 
+ 	assert(shell[0] == '/');
+ 	return shell;
  }
Index: aegis/os.h
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 32,63 ****
  #define OS_EXEC_FLAG_INPUT 1
  #define OS_EXEC_FLAG_ERROK 2
  
! int os_exists _((string_t *));
! void os_mkdir _((string_t *path, int mode));
! void os_rmdir _((string_t *));
! void os_rmdir_errok _((string_t *));
! void os_mkdir_between _((string_t *root, string_t *rel, int mode));
! void os_rename _((string_t *, string_t *));
! void os_unlink _((string_t *));
! void os_unlink_errok _((string_t *));
! string_t *os_curdir _((void));
! string_t *os_pathname _((string_t *));
! string_t *os_dirname _((string_t *));
! string_t *os_entryname _((string_t *));
! string_t *os_below_dir _((string_t *, string_t *));
! void os_chdir _((string_t *));
  void os_setuid _((int));
  void os_setgid _((int));
! void os_execute _((string_t *cmd, int flags, string_t *dir));
! int os_execute_retcode _((string_t *cmd, int flags, string_t *dir));
! string_t *os_execute_slurp _((string_t *cmd, int flags, string_t *dir));
! time_t os_mtime _((string_t *));
! void os_mtime_set _((string_t *, time_t));
! void os_chown_check _((string_t *path, int mode, int uid, int gid));
! void os_chmod _((string_t *, int));
! void os_chmod_errok _((string_t *, int));
! int os_chmod_query _((string_t *));
! void os_link _((string_t *from, string_t *to));
  int os_testing_mode _((void));
  void os_become_init _((void));
  void os_become _((int uid, int gid, int umask));
--- 32,63 ----
  #define OS_EXEC_FLAG_INPUT 1
  #define OS_EXEC_FLAG_ERROK 2
  
! int os_exists _((string_ty *));
! void os_mkdir _((string_ty *path, int mode));
! void os_rmdir _((string_ty *));
! void os_rmdir_errok _((string_ty *));
! void os_mkdir_between _((string_ty *root, string_ty *rel, int mode));
! void os_rename _((string_ty *, string_ty *));
! void os_unlink _((string_ty *));
! void os_unlink_errok _((string_ty *));
! string_ty *os_curdir _((void));
! string_ty *os_pathname _((string_ty *, int));
! string_ty *os_dirname _((string_ty *));
! string_ty *os_entryname _((string_ty *));
! string_ty *os_below_dir _((string_ty *, string_ty *));
! void os_chdir _((string_ty *));
  void os_setuid _((int));
  void os_setgid _((int));
! void os_execute _((string_ty *cmd, int flags, string_ty *dir));
! int os_execute_retcode _((string_ty *cmd, int flags, string_ty *dir));
! string_ty *os_execute_slurp _((string_ty *cmd, int flags, string_ty *dir));
! time_t os_mtime _((string_ty *));
! void os_mtime_set _((string_ty *, time_t));
! void os_chown_check _((string_ty *path, int mode, int uid, int gid));
! void os_chmod _((string_ty *, int));
! void os_chmod_errok _((string_ty *, int));
! int os_chmod_query _((string_ty *));
! void os_link _((string_ty *from, string_ty *to));
  int os_testing_mode _((void));
  void os_become_init _((void));
  void os_become _((int uid, int gid, int umask));
***************
*** 75,79 ****
--- 75,84 ----
  void os_become_must_not_be_active_gizzards _((char *, int));
  
  int os_background _((void));
+ int os_readable _((string_ty *));
+ int os_waitpid _((int child, int *status));
+ int os_waitpid_status _((int child, char *cmd));
+ 
+ char *os_shell _((void));
  
  #endif /* OS_H */
Index: aegis/pager.c
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 96,112 ****
  pipe_close(fp)
  	FILE	*fp;
  {
! 	fclose(fp);
  
! 	for (;;)
! 	{
! 		int	who;
! 		int	status;
! 
! 		who = wait(&status);
! 		if (who < 0 || who == pid)
! 			break;
! 	}
  }
  
  
--- 96,106 ----
  pipe_close(fp)
  	FILE	*fp;
  {
! 	int	status;
  
! 	fclose(fp);
! 	os_waitpid(pid, &status);
! 	pid = 0;
  }
  
  
Index: aegis/pager.h
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
Index: aegis/parse.c
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 27,39 ****
  #include <parse.h>
  #include <trace.h>
  
! static sem_t *sem_root;
  
  
  void *
  parse(filename, type)
  	char	*filename;
! 	type_t	*type;
  {
  	void	*addr;
  
--- 27,39 ----
  #include <parse.h>
  #include <trace.h>
  
! static sem_ty *sem_root;
  
  
  void *
  parse(filename, type)
  	char	*filename;
! 	type_ty	*type;
  {
  	void	*addr;
  
***************
*** 57,70 ****
  
  void
  sem_push(type, addr)
! 	type_t		*type;
  	void		*addr;
  {
! 	sem_t		*sp;
  
  	trace(("sem_push(type = %08lX, addr = %08lX)\n{\n"/*}*/, type, addr));
  	trace(("type->class == %s;\n", type ? type_class_name(type) : "void"));
! 	sp = (sem_t *)mem_alloc_clear(sizeof(sem_t));
  	sp->type = type;
  	sp->addr = addr;
  	sp->next = sem_root;
--- 57,70 ----
  
  void
  sem_push(type, addr)
! 	type_ty		*type;
  	void		*addr;
  {
! 	sem_ty		*sp;
  
  	trace(("sem_push(type = %08lX, addr = %08lX)\n{\n"/*}*/, type, addr));
  	trace(("type->class == %s;\n", type ? type_class_name(type) : "void"));
! 	sp = (sem_ty *)mem_alloc_clear(sizeof(sem_ty));
  	sp->type = type;
  	sp->addr = addr;
  	sp->next = sem_root;
***************
*** 86,92 ****
  void
  sem_pop()
  {
! 	sem_t *x;
  
  	trace(("sem_pop()\n{\n"/*}*/));
  	x = sem_root;
--- 86,92 ----
  void
  sem_pop()
  {
! 	sem_ty *x;
  
  	trace(("sem_pop()\n{\n"/*}*/));
  	x = sem_root;
***************
*** 124,130 ****
  
  void
  sem_string(s)
! 	string_t *s;
  {
  	trace(("sem_string(s = %08lX)\n{\n"/*}*/, s));
  	trace_string(s->str_text);
--- 124,130 ----
  
  void
  sem_string(s)
! 	string_ty *s;
  {
  	trace(("sem_string(s = %08lX)\n{\n"/*}*/, s));
  	trace_string(s->str_text);
***************
*** 146,152 ****
  			sem_root->addr,
  			*(void **)sem_root->addr
  		));
! 		*(string_t **)sem_root->addr = s;
  	}
  	
  	/*
--- 146,152 ----
  			sem_root->addr,
  			*(void **)sem_root->addr
  		));
! 		*(string_ty **)sem_root->addr = s;
  	}
  	
  	/*
***************
*** 159,165 ****
  
  void
  sem_enum(s)
! 	string_t *s;
  {
  	trace(("sem_enum(s = %08lX)\n{\n"/*}*/, s));
  	trace_string(s->str_text);
--- 159,165 ----
  
  void
  sem_enum(s)
! 	string_ty *s;
  {
  	trace(("sem_enum(s = %08lX)\n{\n"/*}*/, s));
  	trace_string(s->str_text);
***************
*** 213,219 ****
  	}
  	else
  	{
! 		type_t	*type;
  		void	*addr;
  
  		sem_root->type->list_parse
--- 213,219 ----
  	}
  	else
  	{
! 		type_ty	*type;
  		void	*addr;
  
  		sem_root->type->list_parse
***************
*** 235,241 ****
  
  void
  sem_field(name)
! 	string_t	*name;
  {
  	trace(("sem_field(name = %08lX)\n{\n"/*}*/, name));
  	trace_string(name->str_text);
--- 235,241 ----
  
  void
  sem_field(name)
! 	string_ty	*name;
  {
  	trace(("sem_field(name = %08lX)\n{\n"/*}*/, name));
  	trace_string(name->str_text);
***************
*** 257,263 ****
  	}
  	else
  	{
! 		type_t		*type;
  		void		*addr;
  		unsigned long	mask;
  
--- 257,263 ----
  	}
  	else
  	{
! 		type_ty		*type;
  		void		*addr;
  		unsigned long	mask;
  
Index: aegis/parse.h
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 27,48 ****
  #include <str.h>
  #include <type.h>
  
! typedef struct sem_t sem_t;
! struct sem_t
  {
! 	type_t	*type;
! 	sem_t	*next;
  	void	*addr;
  };
  
! void sem_push _((type_t *, void *));
  void sem_pop _((void));
  void sem_integer _((long));
! void sem_string _((string_t *));
! void sem_enum _((string_t *));
  void sem_list _((void));
! void sem_field _((string_t *));
  
! void *parse _((char *, type_t *));
  
  #endif /* PARSE_H */
--- 27,48 ----
  #include <str.h>
  #include <type.h>
  
! typedef struct sem_ty sem_ty;
! struct sem_ty
  {
! 	type_ty	*type;
! 	sem_ty	*next;
  	void	*addr;
  };
  
! void sem_push _((type_ty *, void *));
  void sem_pop _((void));
  void sem_integer _((long));
! void sem_string _((string_ty *));
! void sem_enum _((string_ty *));
  void sem_list _((void));
! void sem_field _((string_ty *));
  
! void *parse _((char *, type_ty *));
  
  #endif /* PARSE_H */
Index: aegis/pattr.def
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 20,28 ****
   * MANIFEST: project attributes file contents definition
   *
   * if you change this file, don't forget to change
!  *	man5/aepattr.5
!  *	man5/aepstate.5
   *	aegis/pattr_ed.c
   */
  
  #include <common.def>
--- 20,28 ----
   * MANIFEST: project attributes file contents definition
   *
   * if you change this file, don't forget to change
!  *	man5/aepattr.so
   *	aegis/pattr_ed.c
+  *	aegis/new_rele.c
   */
  
  #include <common.def>
***************
*** 78,86 ****
  
  /*
   * notify that a change requires reviewing
!  *	%1 = project name
!  *	%2 = change number
!  *	%3 = developer
   * this field is optional
   *
   * This command could also be used to notify other management systems,
--- 78,84 ----
  
  /*
   * notify that a change requires reviewing
!  * All of the substitutions described in aesub(5) are available.
   * this field is optional
   *
   * This command could also be used to notify other management systems,
***************
*** 91,99 ****
  /*
   * notify that a change has been withdrawn from review
   * for further development
!  *	%1 = project name
!  *	%2 = change number
!  *	%3 = developer
   * this field is optional
   *
   * This command could also be used to notify other management systems,
--- 89,95 ----
  /*
   * notify that a change has been withdrawn from review
   * for further development
!  * All of the substitutions described in aesub(5) are available.
   * this field is optional
   *
   * This command could also be used to notify other management systems,
***************
*** 103,112 ****
  
  /*
   * notify that the review has passed
!  *	%1 = project name
!  *	%2 = change number
!  *	%3 = developer
!  *	%4 = reviewer
   * this field is optional
   *
   * This command could also be used to notify other management systems,
--- 99,105 ----
  
  /*
   * notify that the review has passed
!  * All of the substitutions described in aesub(5) are available.
   * this field is optional
   *
   * This command could also be used to notify other management systems,
***************
*** 116,125 ****
  
  /*
   * notify that a review pass has has been rescinded
!  *	%1 = project name
!  *	%2 = change number
!  *	%3 = developer
!  *	%4 = reviewer
   * this field is optional.
   * Defaults to the develop_end_notify_command field.
   *
--- 109,115 ----
  
  /*
   * notify that a review pass has has been rescinded
!  * All of the substitutions described in aesub(5) are available.
   * this field is optional.
   * Defaults to the develop_end_notify_command field.
   *
***************
*** 130,139 ****
  
  /*
   * notify that the review has failed
!  *	%1 = project name
!  *	%2 = change number
!  *	%3 = developer
!  *	%4 = reviewer
   * this field is optional
   *
   * This command could also be used to notify other management systems,
--- 120,126 ----
  
  /*
   * notify that the review has failed
!  * All of the substitutions described in aesub(5) are available.
   * this field is optional
   *
   * This command could also be used to notify other management systems,
***************
*** 143,153 ****
  
  /*
   * notify that the integration has passed
!  *	%1 = project name
!  *	%2 = change number
!  *	%3 = developer
!  *	%4 = reviewer
!  *	%5 = integrator
   * this field is optional
   *
   * This command could also be used to notify other management systems,
--- 130,136 ----
  
  /*
   * notify that the integration has passed
!  * All of the substitutions described in aesub(5) are available.
   * this field is optional
   *
   * This command could also be used to notify other management systems,
***************
*** 157,167 ****
  
  /*
   * notify that the integration has failed
!  *	%1 = project name
!  *	%2 = change number
!  *	%3 = developer
!  *	%4 = reviewer
!  *	%5 = integrator
   * this field is optional
   *
   * This command could also be used to notify other management systems,
--- 140,146 ----
  
  /*
   * notify that the integration has failed
!  * All of the substitutions described in aesub(5) are available.
   * this field is optional
   *
   * This command could also be used to notify other management systems,
Index: aegis/pattr_ed.c
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 91,104 ****
  "",
  "	-Project <name>",
  "		This option may be used to select the project of",
! "		interest.  When no -Project option is specified, if",
! "		the user is only working on changes within a single",
! "		project, the project name defaults to that project;",
! "		if the user is currently working on changes to more",
! "		than one project, or is not working on changes to",
! "		any project, the user's $HOME/.%src file is",
! "		examined for a default project field (see aeuconf(5)",
! "		for more information).",
  "",
  "	-TERse",
  "		This option may be used to cause listings to",
--- 91,104 ----
  "",
  "	-Project <name>",
  "		This option may be used to select the project of",
! "		interest.  When no -Project option is specified, the",
! "		AEGIS_PROJECT environment variable is consulted.  If",
! "		that does not exist, the user's $HOME/.aegisrc file",
! "		is examined for a default project field (see",
! "		aeuconf(5) for more information).  If that does not",
! "		exist, when the user is only working on changes",
! "		within a single project, the project name defaults",
! "		to that project.  Otherwise, it is an error.",
  "",
  "	-TERse",
  "		This option may be used to cause listings to",
***************
*** 112,122 ****
  "		option this option causes column headings to be",
  "		added.",
  "",
! "	All options are case insensitive.  Options may be",
! "	abbreviated; the abbreviation is the upper case letters.",
  "	Options and other command line arguments may be mixed",
! "	arbitrarily on the command line.",
  "",
  "RECOMMENDED ALIAS",
  "	The recommended alias for this command is",
  "	csh%%	alias aepa '%s -pa \\!* -v'",
--- 112,140 ----
  "		option this option causes column headings to be",
  "		added.",
  "",
! "	All options may be abbreviated; the abbreviation is",
! "	documented as the upper case letters, all lower case",
! "	letters and underscores (_) are optional.  You must use",
! "	consecutive sequences of optional letters.",
! "",
! "	All options are case insensitive, you may type them in",
! "	upper case or lower case or a combination of both, case",
! "	is not important.",
! "",
! "	For example: the arguments \"-project, \"-PROJ\" and \"-p\"",
! "	are all interpreted to mean the -Project option.  The",
! "	argument \"-prj\" will not be understood, because",
! "	consecutive optional characters were not supplied.",
! "",
  "	Options and other command line arguments may be mixed",
! "	arbitrarily on the command line, after the function",
! "	selectors.",
  "",
+ "	The GNU long option names are understood.  Since all",
+ "	option names for aegis are long, this means ignoring the",
+ "	extra leading '-'.  The \"--option=value\" convention is",
+ "	also understood.",
+ "",
  "RECOMMENDED ALIAS",
  "	The recommended alias for this command is",
  "	csh%%	alias aepa '%s -pa \\!* -v'",
***************
*** 149,156 ****
  {
  	pattr		pattr_data;
  	pstate		pstate_data;
! 	string_t	*project_name;
! 	project_t	*pp;
  
  	trace(("project_attributes_list()\n{\n"/*}*/));
  	project_name = 0;
--- 167,174 ----
  {
  	pattr		pattr_data;
  	pstate		pstate_data;
! 	string_ty	*project_name;
! 	project_ty	*pp;
  
  	trace(("project_attributes_list()\n{\n"/*}*/));
  	project_name = 0;
***************
*** 187,193 ****
  	project_bind_existing(pp);
  
  	pstate_data = project_pstate_get(pp);
! 	pattr_data = pattr_type.alloc();
  	if (pstate_data->description)
  		pattr_data->description = str_copy(pstate_data->description);
  	if (pstate_data->owner_name)
--- 205,211 ----
  	project_bind_existing(pp);
  
  	pstate_data = project_pstate_get(pp);
! 	pattr_data = (pattr)pattr_type.alloc();
  	if (pstate_data->description)
  		pattr_data->description = str_copy(pstate_data->description);
  	if (pstate_data->owner_name)
***************
*** 244,252 ****
  {
  	pattr		pattr_data = 0;
  	pstate		pstate_data;
! 	string_t	*project_name;
! 	project_t	*pp;
! 	string_t	*s;
  
  	trace(("project_attributes_main()\n{\n"/*}*/));
  	project_name = 0;
--- 262,270 ----
  {
  	pattr		pattr_data = 0;
  	pstate		pstate_data;
! 	string_ty	*project_name;
! 	project_ty	*pp;
! 	string_ty	*s;
  
  	trace(("project_attributes_main()\n{\n"/*}*/));
  	project_name = 0;
Index: aegis/pattr_ed.h
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
Index: aegis/pconf.def
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 35,44 ****
   *	(actually, how to do an integration build)
   * mandatory
   *
!  * %1 = project name
!  * %2 = change number
!  * %3 = identifying string, in the form "Dnnn"
!  *	where 'nnn' is the build number.
   */
  build_command = string;
  
--- 35,41 ----
   *	(actually, how to do an integration build)
   * mandatory
   *
!  * All of the substitutions described in aesub(5) are available.
   */
  build_command = string;
  
***************
*** 46,56 ****
   * how to do a development build
   * defaults to above
   *
!  * %1 = project name
!  * %2 = change number
!  * %3 = identifying string, in the form "Cnnn"
!  *	where 'nnn' is the change number.
!  * %4 = the absolute path of the project baseline directory.
   */
  development_build_command = string;
  
--- 43,49 ----
   * how to do a development build
   * defaults to above
   *
!  * All of the substitutions described in aesub(5) are available.
   */
  development_build_command = string;
  
***************
*** 57,68 ****
  /*
   * Executed whenever the files in the change, change.
   *
!  * %1 = project name
!  * %2 = change number
!  * %3 = identifying string, in the form "Cnnn"
!  *	where 'nnn' is the change number.
!  * %4 = the absolute path of the project baseline directory.
!  * %5 = space separated list of files named
   */
  change_file_command = string;
  
--- 50,60 ----
  /*
   * Executed whenever the files in the change, change.
   *
!  * All of the substitutions described in aesub(5) are available.
!  * In addition:
!  *
!  * ${File_List}
!  *	 space separated list of files named
   */
  change_file_command = string;
  
***************
*** 72,82 ****
   *	(b)	after some other change has been integrated into the baseline
   *		since the last build.
   *
!  * %1 = project name
!  * %2 = change number
!  * %3 = identifying string, in the form "Cnnn"
!  *	where 'nnn' is the change number.
!  * %4 = the absolute path of the project baseline directory.
   */
  project_file_command = string;
  
--- 64,70 ----
   *	(b)	after some other change has been integrated into the baseline
   *		since the last build.
   *
!  * All of the substitutions described in aesub(5) are available.
   */
  project_file_command = string;
  
***************
*** 83,92 ****
  /*
   * Executed at integrate begin
   *
!  * %1 = project name
!  * %2 = change number
!  * %3 = identifying string, in the form "Dnnn"
!  *	where 'nnn' is the build number.
   */
  integrate_begin_command = string;
  
--- 71,77 ----
  /*
   * Executed at integrate begin
   *
!  * All of the substitutions described in aesub(5) are available.
   */
  integrate_begin_command = string;
  
***************
*** 106,156 ****
  
  /*
   * create a new history
-  *	%1 = source file
-  *	%2 = history file
   * always executed as the project owner
   */
  history_create_command = string;
  
  /*
   * get a file from history
-  *	%1 = history file
-  *	%2 = edit number
-  *	%3 = destination file
   * may be executed by developers
   */
  history_get_command = string;
  
  /*
   * add a new change to the history
-  *	%1 = source file
-  *	%2 = history file
   * always executed as the project owner
   */
  history_put_command = string;
  
  /*
   * query the topmost edit of a history file
-  *	%1 = history file
   * Result to be printed on stdout.
   * may be executed by developers
   */
  history_query_command = string;
  
  /*
   * difference of 2 files
!  *	%1 = earlier file
!  *	%2 = later file	
!  *	%3 = output file
   */
  diff_command = string;
  
  /*
   * difference of 3 files
!  *	%1 = earliest file
!  *	%2 = one competing edit
!  *	%3 = another competing edit
!  *	%4 = output file
   */
  diff3_command = string;
  
--- 91,183 ----
  
  /*
   * create a new history
   * always executed as the project owner
+  * All of the substitutions described in aesub(5) are available.
+  * In addition:
+  *
+  * ${Input}
+  *	absolute path of the source file
+  *
+  * ${History}
+  *	absolute path of the history file
   */
  history_create_command = string;
  
  /*
   * get a file from history
   * may be executed by developers
+  * All of the substitutions described in aesub(5) are available.
+  * In addition:
+  *
+  * ${History}
+  *	absolute path of the history file
+  *
+  * ${Edit}
+  *	edit number to be extracted (artibrary string)
+  *
+  * ${Output}
+  *	Absolute path of output file.
   */
  history_get_command = string;
  
  /*
   * add a new change to the history
   * always executed as the project owner
+  * All of the substitutions described in aesub(5) are available.
+  * In addition:
+  *
+  * ${Input}
+  *	absolute path of the source file
+  *
+  * ${History}
+  *	absolute path of the history file
   */
  history_put_command = string;
  
  /*
   * query the topmost edit of a history file
   * Result to be printed on stdout.
   * may be executed by developers
+  * All of the substitutions described in aesub(5) are available.
+  * In addition:
+  *
+  * ${History}
+  *	absolute path of the history file
   */
  history_query_command = string;
  
  /*
   * difference of 2 files
!  * All of the substitutions described in aesub(5) are available.
!  * In addition:
!  *
!  * ${ORiginal}
!  *	absolute path of file in baseline (usually)
!  *
!  * ${Input}
!  *	absolute path of file in development directory (usually)
!  *
!  * ${Output}
!  *	Absolute path of output file
   */
  diff_command = string;
  
  /*
   * difference of 3 files
!  * All of the substitutions described in aesub(5) are available.
!  * In addition:
!  *
!  * ${ORiginal}
!  *	Absolute path of common ancestor
!  *
!  * ${Most_Recent}
!  *	Absolute path of competing edit, usually in the baseline.
!  *
!  * ${Input}
!  *	absolute path of file in development directory (usually)
!  *
!  * ${Output}
!  *	absolute path of output file
   */
  diff3_command = string;
  
Index: aegis/project.c
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 48,69 ****
  {
  	trace(("improve(pstate_data = %08lX)\n{\n"/*}*/, pstate_data));
  	if (!pstate_data->administrator)
! 		pstate_data->administrator = pstate_administrator_list_type.alloc();
  	if (!pstate_data->developer)
! 		pstate_data->developer = pstate_developer_list_type.alloc();
  	if (!pstate_data->reviewer)
! 		pstate_data->reviewer = pstate_reviewer_list_type.alloc();
  	if (!pstate_data->integrator)
! 		pstate_data->integrator = pstate_integrator_list_type.alloc();
  	if (!pstate_data->change)
! 		pstate_data->change = pstate_change_list_type.alloc();
  	if (!pstate_data->src)
! 		pstate_data->src = pstate_src_list_type.alloc();
  	if (!pstate_data->history)
! 		pstate_data->history = pstate_history_list_type.alloc();
! 	if (pstate_data->version_major < 1)
  		pstate_data->version_major = 1;
! 	if (pstate_data->version_minor < 0)
  		pstate_data->version_minor = 0;
  	/*
  	 * owner: always read, always write, always search/exec.
--- 48,83 ----
  {
  	trace(("improve(pstate_data = %08lX)\n{\n"/*}*/, pstate_data));
  	if (!pstate_data->administrator)
! 		pstate_data->administrator =
! 			(pstate_administrator_list)
! 			pstate_administrator_list_type.alloc();
  	if (!pstate_data->developer)
! 		pstate_data->developer =
! 			(pstate_developer_list)
! 			pstate_developer_list_type.alloc();
  	if (!pstate_data->reviewer)
! 		pstate_data->reviewer =
! 			(pstate_reviewer_list)
! 			pstate_reviewer_list_type.alloc();
  	if (!pstate_data->integrator)
! 		pstate_data->integrator =
! 			(pstate_integrator_list)
! 			pstate_integrator_list_type.alloc();
  	if (!pstate_data->change)
! 		pstate_data->change =
! 			(pstate_change_list)
! 			pstate_change_list_type.alloc();
  	if (!pstate_data->src)
! 		pstate_data->src =
! 			(pstate_src_list)
! 			pstate_src_list_type.alloc();
  	if (!pstate_data->history)
! 		pstate_data->history =
! 			(pstate_history_list)
! 			pstate_history_list_type.alloc();
! 	if (!(pstate_data->mask & pstate_version_major_mask))
  		pstate_data->version_major = 1;
! 	if (!(pstate_data->mask & pstate_version_minor_mask))
  		pstate_data->version_minor = 0;
  	/*
  	 * owner: always read, always write, always search/exec.
***************
*** 81,94 ****
  }
  
  
! project_t *
  project_alloc(s)
! 	string_t	*s;
  {
! 	project_t	*pp;
  
  	trace(("project_alloc(s = \"%s\")\n{\n"/*}*/, s->str_text));
! 	pp = (project_t *)mem_alloc_clear(sizeof(project_t));
  	pp->reference_count = 1;
  	pp->name = str_copy(s);
  	trace(("return %08lX;\n", pp));
--- 95,108 ----
  }
  
  
! project_ty *
  project_alloc(s)
! 	string_ty	*s;
  {
! 	project_ty	*pp;
  
  	trace(("project_alloc(s = \"%s\")\n{\n"/*}*/, s->str_text));
! 	pp = (project_ty *)mem_alloc_clear(sizeof(project_ty));
  	pp->reference_count = 1;
  	pp->name = str_copy(s);
  	trace(("return %08lX;\n", pp));
***************
*** 97,105 ****
  }
  
  
! project_t *
  project_copy(pp)
! 	project_t	*pp;
  {
  	trace(("project_copy(pp = %08lX)\n{\n"/*}*/, pp));
  	assert(pp->reference_count >= 1);
--- 111,119 ----
  }
  
  
! project_ty *
  project_copy(pp)
! 	project_ty	*pp;
  {
  	trace(("project_copy(pp = %08lX)\n{\n"/*}*/, pp));
  	assert(pp->reference_count >= 1);
***************
*** 112,118 ****
  
  void
  project_free(pp)
! 	project_t	*pp;
  {
  	trace(("project_free(pp = %08lX)\n{\n"/*}*/, pp));
  	assert(pp->reference_count >= 1);
--- 126,132 ----
  
  void
  project_free(pp)
! 	project_ty	*pp;
  {
  	trace(("project_free(pp = %08lX)\n{\n"/*}*/, pp));
  	assert(pp->reference_count >= 1);
***************
*** 122,127 ****
--- 136,143 ----
  		str_free(pp->name);
  		if (pp->home_path)
  			str_free(pp->home_path);
+ 		if (pp->baseline_path_unresolved)
+ 			str_free(pp->baseline_path_unresolved);
  		if (pp->baseline_path)
  			str_free(pp->baseline_path);
  		if (pp->history_path)
***************
*** 140,150 ****
  }
  
  
! static void lock_sync _((project_t *));
  
  static void
  lock_sync(pp)
! 	project_t	*pp;
  {
  	long		n;
  
--- 156,166 ----
  }
  
  
! static void lock_sync _((project_ty *));
  
  static void
  lock_sync(pp)
! 	project_ty	*pp;
  {
  	long		n;
  
***************
*** 164,170 ****
  
  pstate
  project_pstate_get(pp)
! 	project_t	*pp;
  {
  	int		j, k;
  
--- 180,186 ----
  
  pstate
  project_pstate_get(pp)
! 	project_ty	*pp;
  {
  	int		j, k;
  
***************
*** 172,178 ****
  	lock_sync(pp);
  	if (!pp->pstate_data)
  	{
! 		string_t	*path;
  
  		path = project_pstate_path_get(pp);
  		pp->is_a_new_file = 0;
--- 188,194 ----
  	lock_sync(pp);
  	if (!pp->pstate_data)
  	{
! 		string_ty	*path;
  
  		path = project_pstate_path_get(pp);
  		pp->is_a_new_file = 0;
***************
*** 268,276 ****
  
  void
  project_pstate_lock_prepare(pp)
! 	project_t	*pp;
  {
! 	trace(("project_lock_prepare(pp = %08lX)\n{\n"/*}*/, pp));
  	lock_prepare_pstate(pp->name);
  	trace((/*{*/"}\n"));
  }
--- 284,292 ----
  
  void
  project_pstate_lock_prepare(pp)
! 	project_ty	*pp;
  {
! 	trace(("project_pstate_lock_prepare(pp = %08lX)\n{\n"/*}*/, pp));
  	lock_prepare_pstate(pp->name);
  	trace((/*{*/"}\n"));
  }
***************
*** 277,286 ****
  
  
  void
  project_bind_existing(pp)
! 	project_t	*pp;
  {
! 	string_t	*s;
  
  	/*
  	 * make sure project exists
--- 293,322 ----
  
  
  void
+ project_build_read_lock_prepare(pp)
+ 	project_ty	*pp;
+ {
+ 	trace(("project_build_read_lock_prepare(pp = %08lX)\n{\n"/*}*/, pp));
+ 	lock_prepare_build_read(pp->name);
+ 	trace((/*{*/"}\n"));
+ }
+ 
+ 
+ void
+ project_build_write_lock_prepare(pp)
+ 	project_ty	*pp;
+ {
+ 	trace(("project_build_write_lock_prepare(pp = %08lX)\n{\n"/*}*/, pp));
+ 	lock_prepare_build_write(pp->name);
+ 	trace((/*{*/"}\n"));
+ }
+ 
+ 
+ void
  project_bind_existing(pp)
! 	project_ty	*pp;
  {
! 	string_ty	*s;
  
  	/*
  	 * make sure project exists
***************
*** 290,298 ****
  	s = gonzo_project_home_path_from_name(pp->name);
  	if (!s)
  		fatal("project \"%s\" unknown", pp->name->str_text);
! 	project_become(pp);
! 	pp->home_path = os_pathname(s);
! 	project_become_undo();
  	trace((/*{*/"}\n"));
  }
  
--- 326,339 ----
  	s = gonzo_project_home_path_from_name(pp->name);
  	if (!s)
  		fatal("project \"%s\" unknown", pp->name->str_text);
! 	/*
! 	 * To cope with automounters, directories are stored as given,
! 	 * or are derived from the home directory in the passwd file.
! 	 * Within aegis, pathnames have their symbolic links resolved,
! 	 * and any comparison of paths is done on this "system idea"
! 	 * of the pathname.
! 	 */
! 	pp->home_path = str_copy(s);
  	trace((/*{*/"}\n"));
  }
  
***************
*** 299,305 ****
  
  void
  project_bind_new(pp)
! 	project_t	*pp;
  {
  	/*
  	 * make sure name is appropriate length
--- 340,346 ----
  
  void
  project_bind_new(pp)
! 	project_ty	*pp;
  {
  	/*
  	 * make sure name is appropriate length
***************
*** 327,333 ****
  	assert(!pp->pstate_data);
  	assert(!pp->pstate_path);
  	pp->is_a_new_file = 1;
! 	pp->pstate_data = pstate_type.alloc();
  	pp->pstate_data->next_change_number = 1;
  	pp->pstate_data->next_delta_number = 1;
  	pp->pstate_data->next_test_number = 1;
--- 368,374 ----
  	assert(!pp->pstate_data);
  	assert(!pp->pstate_path);
  	pp->is_a_new_file = 1;
! 	pp->pstate_data = (pstate)pstate_type.alloc();
  	pp->pstate_data->next_change_number = 1;
  	pp->pstate_data->next_delta_number = 1;
  	pp->pstate_data->next_test_number = 1;
***************
*** 355,365 ****
  
  void
  project_pstate_write(pp)
! 	project_t	*pp;
  {
! 	string_t	*filename;
! 	string_t	*filename_new;
! 	string_t	*filename_old;
  	static int	count;
  
  	trace(("project_pstate_write(pp)\n{\n"/*}*/, pp));
--- 396,406 ----
  
  void
  project_pstate_write(pp)
! 	project_ty	*pp;
  {
! 	string_ty	*filename;
! 	string_ty	*filename_new;
! 	string_ty	*filename_old;
  	static int	count;
  
  	trace(("project_pstate_write(pp)\n{\n"/*}*/, pp));
***************
*** 415,428 ****
  }
  
  
! string_t *
  project_home_path_get(pp)
! 	project_t	*pp;
  {
  	trace(("project_home_path_get(pp = %08lX)\n{\n"/*}*/, pp));
  	if (!pp->home_path)
  	{
! 		string_t	*s;
  
  		/*
  		 * it is an error if the project name is not known
--- 456,469 ----
  }
  
  
! string_ty *
  project_home_path_get(pp)
! 	project_ty	*pp;
  {
  	trace(("project_home_path_get(pp = %08lX)\n{\n"/*}*/, pp));
  	if (!pp->home_path)
  	{
! 		string_ty	*s;
  
  		/*
  		 * it is an error if the project name is not known
***************
*** 430,439 ****
  		s = gonzo_project_home_path_from_name(pp->name);
  		if (!s)
  			fatal("project \"%s\" unknown", pp->name->str_text);
! 		/* can't become project, may not who it is, yet */
! 		os_become_orig();
! 		pp->home_path = os_pathname(s);
! 		os_become_undo();
  	}
  	trace(("return \"%s\";\n", pp->home_path->str_text));
  	trace((/*{*/"}\n"));
--- 471,484 ----
  		s = gonzo_project_home_path_from_name(pp->name);
  		if (!s)
  			fatal("project \"%s\" unknown", pp->name->str_text);
! 		/*
! 		 * To cope with automounters, directories are stored as given,
! 		 * or are derived from the home directory in the passwd file.
! 		 * Within aegis, pathnames have their symbolic links resolved,
! 		 * and any comparison of paths is done on this "system idea"
! 		 * of the pathname.
! 		 */
! 		pp->home_path = str_copy(s);
  	}
  	trace(("return \"%s\";\n", pp->home_path->str_text));
  	trace((/*{*/"}\n"));
***************
*** 443,464 ****
  
  void
  project_home_path_set(pp, s)
! 	project_t	*pp;
! 	string_t	*s;
  {
  	trace(("project_home_path_set(pp = %08lX, s = \"%s\")\n{\n"/*}*/, pp, s->str_text));
  	if (pp->home_path)
  		fatal("duplicate -DIRectory option");
! 	os_become_orig();
! 	pp->home_path = os_pathname(s);
! 	os_become_undo();
  	trace((/*{*/"}\n"));
  }
  
  
! string_t *
  project_info_path_get(pp)
! 	project_t	*pp;
  {
  	trace(("project_info_path_get(pp = %08lX)\n{\n"/*}*/, pp));
  	if (!pp->info_path)
--- 488,514 ----
  
  void
  project_home_path_set(pp, s)
! 	project_ty	*pp;
! 	string_ty	*s;
  {
+ 	/*
+ 	 * To cope with automounters, directories are stored as given,
+ 	 * or are derived from the home directory in the passwd file.
+ 	 * Within aegis, pathnames have their symbolic links resolved,
+ 	 * and any comparison of paths is done on this "system idea"
+ 	 * of the pathname.
+ 	 */
  	trace(("project_home_path_set(pp = %08lX, s = \"%s\")\n{\n"/*}*/, pp, s->str_text));
  	if (pp->home_path)
  		fatal("duplicate -DIRectory option");
! 	pp->home_path = str_copy(s);
  	trace((/*{*/"}\n"));
  }
  
  
! string_ty *
  project_info_path_get(pp)
! 	project_ty	*pp;
  {
  	trace(("project_info_path_get(pp = %08lX)\n{\n"/*}*/, pp));
  	if (!pp->info_path)
***************
*** 472,480 ****
  }
  
  
! string_t *
  project_changes_path_get(pp)
! 	project_t	*pp;
  {
  	trace(("project_changes_path_get(pp = %08lX)\n{\n"/*}*/, pp));
  	if (!pp->changes_path)
--- 522,530 ----
  }
  
  
! string_ty *
  project_changes_path_get(pp)
! 	project_ty	*pp;
  {
  	trace(("project_changes_path_get(pp = %08lX)\n{\n"/*}*/, pp));
  	if (!pp->changes_path)
***************
*** 488,499 ****
  }
  
  
! string_t *
  project_change_path_get(pp, n)
! 	project_t	*pp;
  	long		n;
  {
! 	string_t	*s;
  
  	trace(("project_change_path_get(pp = %08lX, n = %ld)\n{\n"/*}*/, pp, n));
  	s = str_format("%S/%d/%3.3d", project_changes_path_get(pp), n / 100, n);
--- 538,549 ----
  }
  
  
! string_ty *
  project_change_path_get(pp, n)
! 	project_ty	*pp;
  	long		n;
  {
! 	string_ty	*s;
  
  	trace(("project_change_path_get(pp = %08lX, n = %ld)\n{\n"/*}*/, pp, n));
  	s = str_format("%S/%d/%3.3d", project_changes_path_get(pp), n / 100, n);
***************
*** 503,511 ****
  }
  
  
! string_t *
  project_pstate_path_get(pp)
! 	project_t	*pp;
  {
  	trace(("project_pstate_path_get(pp = %08lX)\n{\n"/*}*/, pp));
  	if (!pp->pstate_path)
--- 553,561 ----
  }
  
  
! string_ty *
  project_pstate_path_get(pp)
! 	project_ty	*pp;
  {
  	trace(("project_pstate_path_get(pp = %08lX)\n{\n"/*}*/, pp));
  	if (!pp->pstate_path)
***************
*** 519,543 ****
  }
  
  
! string_t *
! project_baseline_path_get(pp)
! 	project_t	*pp;
  {
  	trace(("project_baseline_path_get(pp = %08lX)\n{\n"/*}*/, pp));
! 	if (!pp->baseline_path)
  	{
! 		pp->baseline_path =
  			str_format("%S/baseline", project_home_path_get(pp));
  	}
! 	trace(("return \"%s\";\n", pp->baseline_path->str_text));
  	trace((/*{*/"}\n"));
! 	return pp->baseline_path;
  }
  
  
! string_t *
  project_history_path_get(pp)
! 	project_t	*pp;
  {
  	trace(("project_history_path_get(pp = %08lX)\n{\n"/*}*/, pp));
  	if (!pp->history_path)
--- 569,616 ----
  }
  
  
! string_ty *
! project_baseline_path_get(pp, resolve)
! 	project_ty	*pp;
! 	int		resolve;
  {
+ 	string_ty	*result;
+ 
+ 	/*
+ 	 * To cope with automounters, directories are stored as given,
+ 	 * or are derived from the home directory in the passwd file.
+ 	 * Within aegis, pathnames have their symbolic links resolved,
+ 	 * and any comparison of paths is done on this "system idea"
+ 	 * of the pathname.
+ 	 */
  	trace(("project_baseline_path_get(pp = %08lX)\n{\n"/*}*/, pp));
! 	if (!pp->baseline_path_unresolved)
  	{
! 		pp->baseline_path_unresolved =
  			str_format("%S/baseline", project_home_path_get(pp));
  	}
! 	if (!resolve)
! 		result = pp->baseline_path_unresolved;
! 	else
! 	{
! 		if (!pp->baseline_path)
! 		{
! 			project_become(pp);
! 			pp->baseline_path =
! 				os_pathname(pp->baseline_path_unresolved, 1);
! 			project_become_undo();
! 		}
! 		result = pp->baseline_path;
! 	}
! 	trace(("return \"%s\";\n", result->str_text));
  	trace((/*{*/"}\n"));
! 	return result;
  }
  
  
! string_ty *
  project_history_path_get(pp)
! 	project_ty	*pp;
  {
  	trace(("project_history_path_get(pp = %08lX)\n{\n"/*}*/, pp));
  	if (!pp->history_path)
***************
*** 551,561 ****
  }
  
  
! string_t *
  project_name_get(pp)
! 	project_t	*pp;
  {
! 	trace(("project_name_get(pp)\n{\n"/*}*/, pp));
  	trace(("return \"%s\";\n", pp->name->str_text));
  	trace((/*{*/"}\n"));
  	return pp->name;
--- 624,634 ----
  }
  
  
! string_ty *
  project_name_get(pp)
! 	project_ty	*pp;
  {
! 	trace(("project_name_get(pp = %08lX)\n{\n"/*}*/, pp));
  	trace(("return \"%s\";\n", pp->name->str_text));
  	trace((/*{*/"}\n"));
  	return pp->name;
***************
*** 564,571 ****
  
  pstate_src
  project_src_find(pp, file_name)
! 	project_t	*pp;
! 	string_t	*file_name;
  {
  	pstate		pstate_data;
  	int		j;
--- 637,644 ----
  
  pstate_src
  project_src_find(pp, file_name)
! 	project_ty	*pp;
! 	string_ty	*file_name;
  {
  	pstate		pstate_data;
  	int		j;
***************
*** 590,608 ****
  
  pstate_src
  project_src_new(pp, file_name)
! 	project_t	*pp;
! 	string_t	*file_name;
  {
  	pstate		pstate_data;
  	pstate_src	src_data;
  	pstate_src	*addr;
! 	type_t		*type_p;
  
  	trace(("project_src_new(pp = %08lX, file_name = \"%s\")\n{\n"/*}*/, pp, file_name->str_text));
  	pstate_data = project_pstate_get(pp);
  	assert(pstate_data->src);
  	pstate_src_list_type.list_parse(pstate_data->src, &type_p, (void **)&addr);
! 	src_data = pstate_src_type.alloc();
  	*addr = src_data;
  	src_data->file_name = str_copy(file_name);
  	trace(("return %08lX;\n", src_data));
--- 663,681 ----
  
  pstate_src
  project_src_new(pp, file_name)
! 	project_ty	*pp;
! 	string_ty	*file_name;
  {
  	pstate		pstate_data;
  	pstate_src	src_data;
  	pstate_src	*addr;
! 	type_ty		*type_p;
  
  	trace(("project_src_new(pp = %08lX, file_name = \"%s\")\n{\n"/*}*/, pp, file_name->str_text));
  	pstate_data = project_pstate_get(pp);
  	assert(pstate_data->src);
  	pstate_src_list_type.list_parse(pstate_data->src, &type_p, (void **)&addr);
! 	src_data = (pstate_src)pstate_src_type.alloc();
  	*addr = src_data;
  	src_data->file_name = str_copy(file_name);
  	trace(("return %08lX;\n", src_data));
***************
*** 613,620 ****
  
  void
  project_src_remove(pp, file_name)
! 	project_t	*pp;
! 	string_t	*file_name;
  {
  	pstate		pstate_data;
  	pstate_src	src_data;
--- 686,693 ----
  
  void
  project_src_remove(pp, file_name)
! 	project_ty	*pp;
! 	string_ty	*file_name;
  {
  	pstate		pstate_data;
  	pstate_src	src_data;
***************
*** 641,648 ****
  
  int
  project_administrator_query(pp, user)
! 	project_t	*pp;
! 	string_t	*user;
  {
  	pstate		pstate_data;
  	int		j;
--- 714,721 ----
  
  int
  project_administrator_query(pp, user)
! 	project_ty	*pp;
! 	string_ty	*user;
  {
  	pstate		pstate_data;
  	int		j;
***************
*** 660,671 ****
  
  void
  project_administrator_add(pp, name)
! 	project_t	*pp;
! 	string_t	*name;
  {
  	pstate		pstate_data;
! 	type_t		*type_p;
! 	string_t	**who_p;
  
  	trace(("project_administrator_add(pp = %08lX, name = \"%s\")\n{\n"/*}*/, pp, name->str_text));
  	pstate_data = project_pstate_get(pp);
--- 733,744 ----
  
  void
  project_administrator_add(pp, name)
! 	project_ty	*pp;
! 	string_ty	*name;
  {
  	pstate		pstate_data;
! 	type_ty		*type_p;
! 	string_ty	**who_p;
  
  	trace(("project_administrator_add(pp = %08lX, name = \"%s\")\n{\n"/*}*/, pp, name->str_text));
  	pstate_data = project_pstate_get(pp);
***************
*** 682,689 ****
  
  void
  project_administrator_delete(pp, name)
! 	project_t	*pp;
! 	string_t	*name;
  {
  	size_t		k;
  	pstate		pstate_data;
--- 755,762 ----
  
  void
  project_administrator_delete(pp, name)
! 	project_ty	*pp;
! 	string_ty	*name;
  {
  	size_t		k;
  	pstate		pstate_data;
***************
*** 707,714 ****
  
  int
  project_developer_query(pp, user)
! 	project_t	*pp;
! 	string_t	*user;
  {
  	pstate		pstate_data;
  	size_t		j;
--- 780,787 ----
  
  int
  project_developer_query(pp, user)
! 	project_ty	*pp;
! 	string_ty	*user;
  {
  	pstate		pstate_data;
  	size_t		j;
***************
*** 726,737 ****
  
  void
  project_developer_add(pp, name)
! 	project_t	*pp;
! 	string_t	*name;
  {
  	pstate		pstate_data;
! 	type_t		*type_p;
! 	string_t	**who_p;
  
  	pstate_data = project_pstate_get(pp);
  	pstate_developer_list_type.list_parse
--- 799,810 ----
  
  void
  project_developer_add(pp, name)
! 	project_ty	*pp;
! 	string_ty	*name;
  {
  	pstate		pstate_data;
! 	type_ty		*type_p;
! 	string_ty	**who_p;
  
  	pstate_data = project_pstate_get(pp);
  	pstate_developer_list_type.list_parse
***************
*** 746,753 ****
  
  void
  project_developer_delete(pp, name)
! 	project_t	*pp;
! 	string_t	*name;
  {
  	size_t		k;
  	pstate		pstate_data;
--- 819,826 ----
  
  void
  project_developer_delete(pp, name)
! 	project_ty	*pp;
! 	string_ty	*name;
  {
  	size_t		k;
  	pstate		pstate_data;
***************
*** 771,778 ****
  
  int
  project_integrator_query(pp, user)
! 	project_t	*pp;
! 	string_t	*user;
  {
  	pstate		pstate_data;
  	size_t		j;
--- 844,851 ----
  
  int
  project_integrator_query(pp, user)
! 	project_ty	*pp;
! 	string_ty	*user;
  {
  	pstate		pstate_data;
  	size_t		j;
***************
*** 790,801 ****
  
  void
  project_integrator_add(pp, name)
! 	project_t	*pp;
! 	string_t	*name;
  {
  	pstate		pstate_data;
! 	type_t		*type_p;
! 	string_t	**who_p;
  
  	pstate_data = project_pstate_get(pp);
  	pstate_integrator_list_type.list_parse
--- 863,874 ----
  
  void
  project_integrator_add(pp, name)
! 	project_ty	*pp;
! 	string_ty	*name;
  {
  	pstate		pstate_data;
! 	type_ty		*type_p;
! 	string_ty	**who_p;
  
  	pstate_data = project_pstate_get(pp);
  	pstate_integrator_list_type.list_parse
***************
*** 810,817 ****
  
  void
  project_integrator_delete(pp, name)
! 	project_t	*pp;
! 	string_t	*name;
  {
  	size_t		k;
  	pstate		pstate_data;
--- 883,890 ----
  
  void
  project_integrator_delete(pp, name)
! 	project_ty	*pp;
! 	string_ty	*name;
  {
  	size_t		k;
  	pstate		pstate_data;
***************
*** 835,842 ****
  
  int
  project_reviewer_query(pp, user)
! 	project_t	*pp;
! 	string_t	*user;
  {
  	pstate		pstate_data;
  	size_t		j;
--- 908,915 ----
  
  int
  project_reviewer_query(pp, user)
! 	project_ty	*pp;
! 	string_ty	*user;
  {
  	pstate		pstate_data;
  	size_t		j;
***************
*** 854,865 ****
  
  void
  project_reviewer_add(pp, name)
! 	project_t	*pp;
! 	string_t	*name;
  {
  	pstate		pstate_data;
! 	type_t		*type_p;
! 	string_t	**who_p;
  
  	pstate_data = project_pstate_get(pp);
  	pstate_reviewer_list_type.list_parse
--- 927,938 ----
  
  void
  project_reviewer_add(pp, name)
! 	project_ty	*pp;
! 	string_ty	*name;
  {
  	pstate		pstate_data;
! 	type_ty		*type_p;
! 	string_ty	**who_p;
  
  	pstate_data = project_pstate_get(pp);
  	pstate_reviewer_list_type.list_parse
***************
*** 874,881 ****
  
  void
  project_reviewer_delete(pp, name)
! 	project_t	*pp;
! 	string_t	*name;
  {
  	size_t		k;
  	pstate		pstate_data;
--- 947,954 ----
  
  void
  project_reviewer_delete(pp, name)
! 	project_ty	*pp;
! 	string_ty	*name;
  {
  	size_t		k;
  	pstate		pstate_data;
***************
*** 899,910 ****
  
  pstate_history
  project_history_new(pp)
! 	project_t	*pp;
  {
  	pstate		pstate_data;
  	pstate_history	history_data;
  	pstate_history	*history_data_p;
! 	type_t		*type_p;
  
  	trace(("project_history_new()\n{\n"/*}*/));
  	pstate_data = project_pstate_get(pp);
--- 972,983 ----
  
  pstate_history
  project_history_new(pp)
! 	project_ty	*pp;
  {
  	pstate		pstate_data;
  	pstate_history	history_data;
  	pstate_history	*history_data_p;
! 	type_ty		*type_p;
  
  	trace(("project_history_new()\n{\n"/*}*/));
  	pstate_data = project_pstate_get(pp);
***************
*** 915,921 ****
  		&type_p,
  		(void **)&history_data_p
  	);
! 	history_data = pstate_history_type.alloc();
  	*history_data_p = history_data;
  	trace(("return %08lX;\n", history_data));
  	trace((/*{*/"}\n"));
--- 988,994 ----
  		&type_p,
  		(void **)&history_data_p
  	);
! 	history_data = (pstate_history)pstate_history_type.alloc();
  	*history_data_p = history_data;
  	trace(("return %08lX;\n", history_data));
  	trace((/*{*/"}\n"));
***************
*** 925,931 ****
  
  long
  project_last_change_integrated(pp)
! 	project_t	*pp;
  {
  	pstate		pstate_data;
  	pstate_history	history_data;
--- 998,1004 ----
  
  long
  project_last_change_integrated(pp)
! 	project_ty	*pp;
  {
  	pstate		pstate_data;
  	pstate_history	history_data;
***************
*** 941,952 ****
  
  void
  project_error(pp, s sva_last)
! 	project_t	*pp;
  	char		*s;
  	sva_last_decl
  {
  	va_list		ap;
! 	string_t	*msg;
  
  	sva_init(ap, s);
  	msg = str_vformat(s, ap);
--- 1014,1025 ----
  
  void
  project_error(pp, s sva_last)
! 	project_ty	*pp;
  	char		*s;
  	sva_last_decl
  {
  	va_list		ap;
! 	string_ty	*msg;
  
  	sva_init(ap, s);
  	msg = str_vformat(s, ap);
***************
*** 963,974 ****
  
  void
  project_fatal(pp, s sva_last)
! 	project_t	*pp;
  	char		*s;
  	sva_last_decl
  {
  	va_list		ap;
! 	string_t	*msg;
  
  	sva_init(ap, s);
  	msg = str_vformat(s, ap);
--- 1036,1047 ----
  
  void
  project_fatal(pp, s sva_last)
! 	project_ty	*pp;
  	char		*s;
  	sva_last_decl
  {
  	va_list		ap;
! 	string_ty	*msg;
  
  	sva_init(ap, s);
  	msg = str_vformat(s, ap);
***************
*** 984,995 ****
  
  void
  project_verbose(pp, s sva_last)
! 	project_t	*pp;
  	char		*s;
  	sva_last_decl
  {
  	va_list		ap;
! 	string_t	*msg;
  
  	sva_init(ap, s);
  	msg = str_vformat(s, ap);
--- 1057,1068 ----
  
  void
  project_verbose(pp, s sva_last)
! 	project_ty	*pp;
  	char		*s;
  	sva_last_decl
  {
  	va_list		ap;
! 	string_ty	*msg;
  
  	sva_init(ap, s);
  	msg = str_vformat(s, ap);
***************
*** 1006,1017 ****
  
  void
  project_change_append(pp, cn)
! 	project_t	*pp;
  	long		cn;
  {
  	pstate		pstate_data;
  	long		*change_p;
! 	type_t		*type_p;
  
  	pstate_data = project_pstate_get(pp);
  	assert(pstate_data->change);
--- 1079,1090 ----
  
  void
  project_change_append(pp, cn)
! 	project_ty	*pp;
  	long		cn;
  {
  	pstate		pstate_data;
  	long		*change_p;
! 	type_ty		*type_p;
  
  	pstate_data = project_pstate_get(pp);
  	assert(pstate_data->change);
***************
*** 1025,1035 ****
  }
  
  
! string_t *
  project_version_get(pp)
! 	project_t	*pp;
  {
! 	string_t	*s;
  	pstate		pstate_data;
  	pstate_history	history_data;
  
--- 1098,1131 ----
  }
  
  
! void
! project_change_delete(pp, cn)
! 	project_ty	*pp;
! 	long		cn;
! {
! 	pstate		pstate_data;
! 	long		j, k;
! 
! 	pstate_data = project_pstate_get(pp);
! 	assert(pstate_data->change);
! 	for (j = 0; j < pstate_data->change->length; ++j)
! 	{
! 		if (pstate_data->change->list[j] != cn)
! 			continue;
! 		for (k = j + 1; k < pstate_data->change->length; ++k)
! 			pstate_data->change->list[k - 1] =
! 				pstate_data->change->list[k];
! 		pstate_data->change->length--;
! 		break;
! 	}
! }
! 
! 
! string_ty *
  project_version_get(pp)
! 	project_ty	*pp;
  {
! 	string_ty	*s;
  	pstate		pstate_data;
  	pstate_history	history_data;
  
***************
*** 1053,1098 ****
  }
  
  
! string_t *
  project_owner(pp)
! 	project_t	*pp;
  {
  	return project_pstate_get(pp)->owner_name;
  }
  
  
! string_t *
  project_group(pp)
! 	project_t	*pp;
  {
  	return project_pstate_get(pp)->group_name;
  }
  
  
! string_t *
  project_default_development_directory(pp)
! 	project_t	*pp;
  {
  	pstate		pstate_data;
- 	string_t	*s;
  
  	pstate_data = project_pstate_get(pp);
! 	s = pstate_data->default_development_directory;
! 	if (s)
! 	{
! 		project_become(pp);
! 		s = os_pathname(s);
! 		project_become_undo();
! 	}
! 	return s;
  }
  
  
! user_t *
  project_user(pp)
! 	project_t	*pp;
  {
! 	user_t		*up;
  
  	trace(("project_user(pp = %08lX)\n{\n"/*}*/, pp));
  	up = user_symbolic(pp, project_owner(pp));
--- 1149,1193 ----
  }
  
  
! string_ty *
  project_owner(pp)
! 	project_ty	*pp;
  {
  	return project_pstate_get(pp)->owner_name;
  }
  
  
! string_ty *
  project_group(pp)
! 	project_ty	*pp;
  {
  	return project_pstate_get(pp)->group_name;
  }
  
  
! string_ty *
  project_default_development_directory(pp)
! 	project_ty	*pp;
  {
  	pstate		pstate_data;
  
+ 	/*
+ 	 * To cope with automounters, directories are stored as given,
+ 	 * or are derived from the home directory in the passwd file.
+ 	 * Within aegis, pathnames have their symbolic links resolved,
+ 	 * and any comparison of paths is done on this "system idea"
+ 	 * of the pathname.
+ 	 */
  	pstate_data = project_pstate_get(pp);
! 	return pstate_data->default_development_directory;
  }
  
  
! user_ty *
  project_user(pp)
! 	project_ty	*pp;
  {
! 	user_ty		*up;
  
  	trace(("project_user(pp = %08lX)\n{\n"/*}*/, pp));
  	up = user_symbolic(pp, project_owner(pp));
***************
*** 1104,1112 ****
  
  void
  project_become(pp)
! 	project_t	*pp;
  {
! 	user_t		*up;
  
  	trace(("project_become(pp = %08lX)\n{\n"/*}*/, pp));
  	up = project_user(pp);
--- 1199,1207 ----
  
  void
  project_become(pp)
! 	project_ty	*pp;
  {
! 	user_ty		*up;
  
  	trace(("project_become(pp = %08lX)\n{\n"/*}*/, pp));
  	up = project_user(pp);
***************
*** 1127,1133 ****
  
  int
  project_umask(pp)
! 	project_t	*pp;
  {
  	return project_pstate_get(pp)->umask;
  }
--- 1222,1228 ----
  
  int
  project_umask(pp)
! 	project_ty	*pp;
  {
  	return project_pstate_get(pp)->umask;
  }
***************
*** 1135,1141 ****
  
  int
  project_delta_exists(pp, delta_number)
! 	project_t	*pp;
  	long		delta_number;
  {
  	int		result;
--- 1230,1236 ----
  
  int
  project_delta_exists(pp, delta_number)
! 	project_ty	*pp;
  	long		delta_number;
  {
  	int		result;
***************
*** 1177,1184 ****
   *	project_delta_to_edit
   *
   * SYNOPSIS
!  *	string_t *project_delta_to_edit(project_t *pp, long delta_number,
!  *		string_t *file_name);
   *
   * DESCRIPTION
   *	The project_delta_to_edit function is used to map a delta number
--- 1272,1279 ----
   *	project_delta_to_edit
   *
   * SYNOPSIS
!  *	string_ty *project_delta_to_edit(project_ty *pp, long delta_number,
!  *		string_ty *file_name);
   *
   * DESCRIPTION
   *	The project_delta_to_edit function is used to map a delta number
***************
*** 1192,1198 ****
   *	file_name	- name of file
   *
   * RETURNS
!  *	string_t *;	string containing edit number,
   *			NULL if file does not exist at this delta.
   *
   * CAVEAT
--- 1287,1293 ----
   *	file_name	- name of file
   *
   * RETURNS
!  *	string_ty *;	string containing edit number,
   *			NULL if file does not exist at this delta.
   *
   * CAVEAT
***************
*** 1200,1216 ****
   *	when not futher required.
   */
  
! string_t *
  project_delta_to_edit(pp, delta_number, file_name)
! 	project_t	*pp;
  	long		delta_number;
! 	string_t	*file_name;
  {
! 	string_t	*edit_number;
  	pstate		pstate_data;
  	pstate_history	history_data;
  	long		j;
! 	change_t	*cp;
  	cstate_src	src_data;
  
  	trace(("project_delta_exists(pp = %08lX, delta_number = %ld)\n{\n"/*}*/, pp, delta_number));
--- 1295,1311 ----
   *	when not futher required.
   */
  
! string_ty *
  project_delta_to_edit(pp, delta_number, file_name)
! 	project_ty	*pp;
  	long		delta_number;
! 	string_ty	*file_name;
  {
! 	string_ty	*edit_number;
  	pstate		pstate_data;
  	pstate_history	history_data;
  	long		j;
! 	change_ty	*cp;
  	cstate_src	src_data;
  
  	trace(("project_delta_exists(pp = %08lX, delta_number = %ld)\n{\n"/*}*/, pp, delta_number));
Index: aegis/project.h
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 26,42 ****
  #include <pstate.h>
  #include <pattr.h>
  
! typedef struct project_t project_t;
! struct project_t
  {
  	long		reference_count;
! 	string_t	*name;
! 	string_t	*home_path;
! 	string_t	*baseline_path;
! 	string_t	*history_path;
! 	string_t	*info_path;
! 	string_t	*pstate_path;
! 	string_t	*changes_path;
  	pstate		pstate_data;
  	int		is_a_new_file;
  	long		lock_magic;
--- 26,43 ----
  #include <pstate.h>
  #include <pattr.h>
  
! typedef struct project_ty project_ty;
! struct project_ty
  {
  	long		reference_count;
! 	string_ty	*name;
! 	string_ty	*home_path;
! 	string_ty	*baseline_path_unresolved;
! 	string_ty	*baseline_path;
! 	string_ty	*history_path;
! 	string_ty	*info_path;
! 	string_ty	*pstate_path;
! 	string_ty	*changes_path;
  	pstate		pstate_data;
  	int		is_a_new_file;
  	long		lock_magic;
***************
*** 46,100 ****
  	 */
  };
  
! project_t *project_alloc _((string_t *name));
! void project_bind_existing _((project_t *));
! void project_bind_new _((project_t *));
! void project_free _((project_t *));
! string_t *project_name_get _((project_t *));
! project_t *project_copy _((project_t *));
! string_t *project_home_path_get _((project_t *));
! void project_home_path_set _((project_t *, string_t *));
! string_t *project_baseline_path_get _((project_t *));
! string_t *project_history_path_get _((project_t *));
! string_t *project_info_path_get _((project_t *));
! string_t *project_changes_path_get _((project_t *));
! string_t *project_change_path_get _((project_t *, long));
! string_t *project_pstate_path_get _((project_t *));
! pstate project_pstate_get _((project_t *));
! void project_pstate_write _((project_t *));
! void project_pstate_lock_prepare _((project_t *));
! pattr project_pattr_get _((project_t *));
! void project_pattr_set _((project_t *, pattr));
! pstate_src project_src_find _((project_t *, string_t *));
! pstate_src project_src_new _((project_t *, string_t *));
! void project_src_remove _((project_t *, string_t *));
! int project_administrator_query _((project_t *, string_t *));
! void project_administrator_add _((project_t *, string_t *));
! void project_administrator_delete _((project_t *, string_t *));
! int project_integrator_query _((project_t *, string_t *));
! void project_integrator_add _((project_t *, string_t *));
! void project_integrator_delete _((project_t *, string_t *));
! int project_reviewer_query _((project_t *, string_t *));
! void project_reviewer_add _((project_t *, string_t *));
! void project_reviewer_delete _((project_t *, string_t *));
! int project_developer_query _((project_t *, string_t *));
! void project_developer_add _((project_t *, string_t *));
! void project_developer_delete _((project_t *, string_t *));
! pstate_history project_history_new _((project_t *));
! long project_last_change_integrated _((project_t *));
! void project_error _((project_t *, char *, ...));
! void project_fatal _((project_t *, char *, ...));
! void project_verbose _((project_t *, char *, ...));
! void project_change_append _((project_t *, long));
! string_t *project_version_get _((project_t *));
! string_t *project_owner _((project_t *));
! string_t *project_group _((project_t *));
! string_t *project_default_development_directory _((project_t *));
! struct user_t *project_user _((project_t *));
! void project_become _((project_t *));
  void project_become_undo _((void));
! int project_umask _((project_t *));
! int project_delta_exists _((project_t *pp, long dn));
! string_t *project_delta_to_edit _((project_t *pp, long delta, string_t *fn));
  
  #endif /* PROJECT_H */
--- 47,104 ----
  	 */
  };
  
! project_ty *project_alloc _((string_ty *name));
! void project_bind_existing _((project_ty *));
! void project_bind_new _((project_ty *));
! void project_free _((project_ty *));
! string_ty *project_name_get _((project_ty *));
! project_ty *project_copy _((project_ty *));
! string_ty *project_home_path_get _((project_ty *));
! void project_home_path_set _((project_ty *, string_ty *));
! string_ty *project_baseline_path_get _((project_ty *, int));
! string_ty *project_history_path_get _((project_ty *));
! string_ty *project_info_path_get _((project_ty *));
! string_ty *project_changes_path_get _((project_ty *));
! string_ty *project_change_path_get _((project_ty *, long));
! string_ty *project_pstate_path_get _((project_ty *));
! pstate project_pstate_get _((project_ty *));
! void project_pstate_write _((project_ty *));
! void project_pstate_lock_prepare _((project_ty *));
! void project_build_read_lock_prepare _((project_ty *));
! void project_build_write_lock_prepare _((project_ty *));
! pattr project_pattr_get _((project_ty *));
! void project_pattr_set _((project_ty *, pattr));
! pstate_src project_src_find _((project_ty *, string_ty *));
! pstate_src project_src_new _((project_ty *, string_ty *));
! void project_src_remove _((project_ty *, string_ty *));
! int project_administrator_query _((project_ty *, string_ty *));
! void project_administrator_add _((project_ty *, string_ty *));
! void project_administrator_delete _((project_ty *, string_ty *));
! int project_integrator_query _((project_ty *, string_ty *));
! void project_integrator_add _((project_ty *, string_ty *));
! void project_integrator_delete _((project_ty *, string_ty *));
! int project_reviewer_query _((project_ty *, string_ty *));
! void project_reviewer_add _((project_ty *, string_ty *));
! void project_reviewer_delete _((project_ty *, string_ty *));
! int project_developer_query _((project_ty *, string_ty *));
! void project_developer_add _((project_ty *, string_ty *));
! void project_developer_delete _((project_ty *, string_ty *));
! pstate_history project_history_new _((project_ty *));
! long project_last_change_integrated _((project_ty *));
! void project_error _((project_ty *, char *, ...));
! void project_fatal _((project_ty *, char *, ...));
! void project_verbose _((project_ty *, char *, ...));
! void project_change_append _((project_ty *, long));
! void project_change_delete _((project_ty *, long));
! string_ty *project_version_get _((project_ty *));
! string_ty *project_owner _((project_ty *));
! string_ty *project_group _((project_ty *));
! string_ty *project_default_development_directory _((project_ty *));
! struct user_ty *project_user _((project_ty *));
! void project_become _((project_ty *));
  void project_become_undo _((void));
! int project_umask _((project_ty *));
! int project_delta_exists _((project_ty *pp, long dn));
! string_ty *project_delta_to_edit _((project_ty *pp, long delta, string_ty *fn));
  
  #endif /* PROJECT_H */
Index: aegis/pstate.def
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
Index: aegis/rem_file.c
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 120,128 ****
  "",
  "	-Change <number>",
  "		This option may be used to specify a particular",
! "		change within a project.  If the user is only",
! "		working on one change within a project, that is",
! "		the default change number.",
  "",
  "	-Help",
  "		This option may be used to obtain more",
--- 120,133 ----
  "",
  "	-Change <number>",
  "		This option may be used to specify a particular",
! "		change within a project.  When no -Change option is",
! "		specified, the AEGIS_CHANGE environment variable is",
! "		consulted.  If that does not exist, the user's",
! "		$HOME/.aegisrc file is examined for a default change",
! "		field (see aeuconf(5) for more information).  If",
! "		that does not exist, when the user is only working",
! "		on one change within a project, that is the default",
! "		change number.  Otherwise, it is an error.",
  "",
  "	-Help",
  "		This option may be used to obtain more",
***************
*** 135,148 ****
  "",
  "	-Project <name>",
  "		This option may be used to select the project of",
! "		interest.  When no -Project option is specified, if",
! "		the user is only working on changes within a single",
! "		project, the project name defaults to that project;",
! "		if the user is currently working on changes to more",
! "		than one project, or is not working on changes to",
! "		any project, the user's $HOME/.%src file is",
! "		examined for a default project field (see aeuconf(5)",
! "		for more information).",
  "",
  "	-TERse",
  "		This option may be used to cause listings to",
--- 140,153 ----
  "",
  "	-Project <name>",
  "		This option may be used to select the project of",
! "		interest.  When no -Project option is specified, the",
! "		AEGIS_PROJECT environment variable is consulted.  If",
! "		that does not exist, the user's $HOME/.aegisrc file",
! "		is examined for a default project field (see",
! "		aeuconf(5) for more information).  If that does not",
! "		exist, when the user is only working on changes",
! "		within a single project, the project name defaults",
! "		to that project.  Otherwise, it is an error.",
  "",
  "	-TERse",
  "		This option may be used to cause listings to",
***************
*** 156,166 ****
  "		option this option causes column headings to be",
  "		added.",
  "",
! "	All options are case insensitive.  Options may be",
! "	abbreviated; the abbreviation is the upper case letters.",
  "	Options and other command line arguments may be mixed",
! "	arbitrarily on the command line.",
  "",
  "RECOMMENDED ALIAS",
  "	The recommended alias for this command is",
  "	csh%%	alias aerm '%s -rm \\!* -v'",
--- 161,189 ----
  "		option this option causes column headings to be",
  "		added.",
  "",
! "	All options may be abbreviated; the abbreviation is",
! "	documented as the upper case letters, all lower case",
! "	letters and underscores (_) are optional.  You must use",
! "	consecutive sequences of optional letters.",
! "",
! "	All options are case insensitive, you may type them in",
! "	upper case or lower case or a combination of both, case",
! "	is not important.",
! "",
! "	For example: the arguments \"-project, \"-PROJ\" and \"-p\"",
! "	are all interpreted to mean the -Project option.  The",
! "	argument \"-prj\" will not be understood, because",
! "	consecutive optional characters were not supplied.",
! "",
  "	Options and other command line arguments may be mixed",
! "	arbitrarily on the command line, after the function",
! "	selectors.",
  "",
+ "	The GNU long option names are understood.  Since all",
+ "	option names for aegis are long, this means ignoring the",
+ "	extra leading '-'.  The \"--option=value\" convention is",
+ "	also understood.",
+ "",
  "RECOMMENDED ALIAS",
  "	The recommended alias for this command is",
  "	csh%%	alias aerm '%s -rm \\!* -v'",
***************
*** 209,215 ****
  static void
  remove_file_list()
  {
! 	string_t	*project_name;
  	long		change_number;
  
  	trace(("remove_file_list()\n{\n"/*}*/));
--- 232,238 ----
  static void
  remove_file_list()
  {
! 	string_ty	*project_name;
  	long		change_number;
  
  	trace(("remove_file_list()\n{\n"/*}*/));
***************
*** 276,283 ****
  remove_file_main()
  {
  	wlist		wl;
! 	string_t	*s1;
! 	string_t	*s2;
  	cstate		cstate_data;
  	cstate_src	c_src_data;
  	pstate_src	p_src_data;
--- 299,306 ----
  remove_file_main()
  {
  	wlist		wl;
! 	string_ty	*s1;
! 	string_ty	*s2;
  	cstate		cstate_data;
  	cstate_src	c_src_data;
  	pstate_src	p_src_data;
***************
*** 284,295 ****
  	int		j;
  	pconf		pconf_data;
  	pstate		pstate_data;
! 	string_t	*project_name;
! 	project_t	*pp;
  	long		change_number;
! 	change_t	*cp;
  	int		nolog;
! 	user_t		*up;
  
  	trace(("remove_file_main()\n{\n"/*}*/));
  	project_name = 0;
--- 307,320 ----
  	int		j;
  	pconf		pconf_data;
  	pstate		pstate_data;
! 	string_ty	*project_name;
! 	project_ty	*pp;
  	long		change_number;
! 	change_ty	*cp;
  	int		nolog;
! 	user_ty		*up;
! 	string_ty	*dd;
! 	string_ty	*bl;
  
  	trace(("remove_file_main()\n{\n"/*}*/));
  	project_name = 0;
***************
*** 307,313 ****
  		case arglex_token_string:
  			s1 = str_from_c(arglex_value.alv_string);
  			os_become_orig();
! 			s2 = os_pathname(s1);
  			os_become_undo();
  			if (wl_member(&wl, s2))
  				fatal("file \"%s\" named more than once", arglex_value.alv_string);
--- 332,338 ----
  		case arglex_token_string:
  			s1 = str_from_c(arglex_value.alv_string);
  			os_become_orig();
! 			s2 = os_pathname(s1, 1);
  			os_become_undo();
  			if (wl_member(&wl, s2))
  				fatal("file \"%s\" named more than once", arglex_value.alv_string);
***************
*** 402,414 ****
  	 * 3.	if the file is inside the baseline, ok
  	 * 4.	if neither, error
  	 */
  	for (j = 0; j < wl.wl_nwords; ++j)
  	{
  		s1 = wl.wl_word[j];
  		assert(s1->str_text[0] == '/');
! 		s2 = os_below_dir(cstate_data->development_directory, s1);
  		if (!s2)
! 			s2 = os_below_dir(project_baseline_path_get(pp), s1);
  		if (!s2)
  			change_fatal(cp, "path \"%S\" unrelated", s1);
  		str_free(s1);
--- 427,441 ----
  	 * 3.	if the file is inside the baseline, ok
  	 * 4.	if neither, error
  	 */
+ 	dd = change_development_directory_get(cp, 1);
+ 	bl = project_baseline_path_get(pp, 1);
  	for (j = 0; j < wl.wl_nwords; ++j)
  	{
  		s1 = wl.wl_word[j];
  		assert(s1->str_text[0] == '/');
! 		s2 = os_below_dir(dd, s1);
  		if (!s2)
! 			s2 = os_below_dir(bl, s1);
  		if (!s2)
  			change_fatal(cp, "path \"%S\" unrelated", s1);
  		str_free(s1);
***************
*** 586,594 ****
  "",
  "	-Change <number>",
  "		This option may be used to specify a particular",
! "		change within a project.  If the user is only",
! "		working on one change within a project, that is",
! "		the default change number.",
  "",
  "	-Help",
  "		This option may be used to obtain more",
--- 613,626 ----
  "",
  "	-Change <number>",
  "		This option may be used to specify a particular",
! "		change within a project.  When no -Change option is",
! "		specified, the AEGIS_CHANGE environment variable is",
! "		consulted.  If that does not exist, the user's",
! "		$HOME/.aegisrc file is examined for a default change",
! "		field (see aeuconf(5) for more information).  If",
! "		that does not exist, when the user is only working",
! "		on one change within a project, that is the default",
! "		change number.  Otherwise, it is an error.",
  "",
  "	-Help",
  "		This option may be used to obtain more",
***************
*** 601,614 ****
  "",
  "	-Project <name>",
  "		This option may be used to select the project of",
! "		interest.  When no -Project option is specified, if",
! "		the user is only working on changes within a single",
! "		project, the project name defaults to that project;",
! "		if the user is currently working on changes to more",
! "		than one project, or is not working on changes to",
! "		any project, the user's $HOME/.%src file is",
! "		examined for a default project field (see aeuconf(5)",
! "		for more information).",
  "",
  "	-TERse",
  "		This option may be used to cause listings to",
--- 633,646 ----
  "",
  "	-Project <name>",
  "		This option may be used to select the project of",
! "		interest.  When no -Project option is specified, the",
! "		AEGIS_PROJECT environment variable is consulted.  If",
! "		that does not exist, the user's $HOME/.aegisrc file",
! "		is examined for a default project field (see",
! "		aeuconf(5) for more information).  If that does not",
! "		exist, when the user is only working on changes",
! "		within a single project, the project name defaults",
! "		to that project.  Otherwise, it is an error.",
  "",
  "	-TERse",
  "		This option may be used to cause listings to",
***************
*** 622,632 ****
  "		option this option causes column headings to be",
  "		added.",
  "",
! "	All options are case insensitive.  Options may be",
! "	abbreviated; the abbreviation is the upper case letters.",
  "	Options and other command line arguments may be mixed",
! "	arbitrarily on the command line.",
  "",
  "RECOMMENDED ALIAS",
  "	The recommended alias for this command is",
  "	csh%%	alias aermu '%s -rmu \\!* -v'",
--- 654,682 ----
  "		option this option causes column headings to be",
  "		added.",
  "",
! "	All options may be abbreviated; the abbreviation is",
! "	documented as the upper case letters, all lower case",
! "	letters and underscores (_) are optional.  You must use",
! "	consecutive sequences of optional letters.",
! "",
! "	All options are case insensitive, you may type them in",
! "	upper case or lower case or a combination of both, case",
! "	is not important.",
! "",
! "	For example: the arguments \"-project, \"-PROJ\" and \"-p\"",
! "	are all interpreted to mean the -Project option.  The",
! "	argument \"-prj\" will not be understood, because",
! "	consecutive optional characters were not supplied.",
! "",
  "	Options and other command line arguments may be mixed",
! "	arbitrarily on the command line, after the function",
! "	selectors.",
  "",
+ "	The GNU long option names are understood.  Since all",
+ "	option names for aegis are long, this means ignoring the",
+ "	extra leading '-'.  The \"--option=value\" convention is",
+ "	also understood.",
+ "",
  "RECOMMENDED ALIAS",
  "	The recommended alias for this command is",
  "	csh%%	alias aermu '%s -rmu \\!* -v'",
***************
*** 675,681 ****
  static void
  remove_file_undo_list()
  {
! 	string_t	*project_name;
  	long		change_number;
  
  	trace(("remove_file_undo_list()\n{\n"/*}*/));
--- 725,731 ----
  static void
  remove_file_undo_list()
  {
! 	string_ty	*project_name;
  	long		change_number;
  
  	trace(("remove_file_undo_list()\n{\n"/*}*/));
***************
*** 740,758 ****
  remove_file_undo_main()
  {
  	wlist		wl;
! 	string_t	*s1;
! 	string_t	*s2;
  	int		j;
  	cstate		cstate_data;
  	pconf		pconf_data;
  	pstate		pstate_data;
! 	string_t	*project_name;
! 	project_t	*pp;
  	long		change_number;
! 	change_t	*cp;
  	int		nolog;
! 	user_t		*up;
! 	string_t	*dd;
  
  	trace(("remove_file_undo_main()\n{\n"/*}*/));
  	project_name = 0;
--- 790,809 ----
  remove_file_undo_main()
  {
  	wlist		wl;
! 	string_ty	*s1;
! 	string_ty	*s2;
  	int		j;
  	cstate		cstate_data;
  	pconf		pconf_data;
  	pstate		pstate_data;
! 	string_ty	*project_name;
! 	project_ty	*pp;
  	long		change_number;
! 	change_ty	*cp;
  	int		nolog;
! 	user_ty		*up;
! 	string_ty	*dd;
! 	string_ty	*bl;
  
  	trace(("remove_file_undo_main()\n{\n"/*}*/));
  	project_name = 0;
***************
*** 770,776 ****
  		case arglex_token_string:
  			s1 = str_from_c(arglex_value.alv_string);
  			os_become_orig();
! 			s2 = os_pathname(s1);
  			os_become_undo();
  			if (wl_member(&wl, s2))
  				fatal("file \"%s\" named more than once", arglex_value.alv_string);
--- 821,827 ----
  		case arglex_token_string:
  			s1 = str_from_c(arglex_value.alv_string);
  			os_become_orig();
! 			s2 = os_pathname(s1, 1);
  			os_become_undo();
  			if (wl_member(&wl, s2))
  				fatal("file \"%s\" named more than once", arglex_value.alv_string);
***************
*** 865,877 ****
  	 * 3.	if the file is inside the baseline, ok
  	 * 4.	if neither, error
  	 */
  	for (j = 0; j < wl.wl_nwords; ++j)
  	{
  		s1 = wl.wl_word[j];
  		assert(s1->str_text[0] == '/');
! 		s2 = os_below_dir(cstate_data->development_directory, s1);
  		if (!s2)
! 			s2 = os_below_dir(project_baseline_path_get(pp), s1);
  		if (!s2)
  			change_fatal(cp, "path \"%S\" unrelated", s1);
  		str_free(s1);
--- 916,930 ----
  	 * 3.	if the file is inside the baseline, ok
  	 * 4.	if neither, error
  	 */
+ 	dd = change_development_directory_get(cp, 1);
+ 	bl = project_baseline_path_get(pp, 1);
  	for (j = 0; j < wl.wl_nwords; ++j)
  	{
  		s1 = wl.wl_word[j];
  		assert(s1->str_text[0] == '/');
! 		s2 = os_below_dir(dd, s1);
  		if (!s2)
! 			s2 = os_below_dir(bl, s1);
  		if (!s2)
  			change_fatal(cp, "path \"%S\" unrelated", s1);
  		str_free(s1);
***************
*** 898,904 ****
  	 * Remove the difference files,
  	 * if they exist.
  	 */
- 	dd = change_development_directory_get(cp);
  	user_become(up);
  	for (j = 0; j < wl.wl_nwords; ++j)
  	{
--- 951,956 ----
Index: aegis/rem_file.h
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
Index: aegis/rem_proj.c
***************
*** 0 ****
--- 1,369 ----
+ /*
+  *	aegis - project change supervisor
+  *	Copyright (C) 1993 Peter Miller.
+  *	All rights reserved.
+  *
+  *	This program is free software; you can redistribute it and/or modify
+  *	it under the terms of the GNU General Public License as published by
+  *	the Free Software Foundation; either version 2 of the License, or
+  *	(at your option) any later version.
+  *
+  *	This program is distributed in the hope that it will be useful,
+  *	but WITHOUT ANY WARRANTY; without even the implied warranty of
+  *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  *	GNU General Public License for more details.
+  *
+  *	You should have received a copy of the GNU General Public License
+  *	along with this program; if not, write to the Free Software
+  *	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+  *
+  * MANIFEST: functions to remove projects
+  */
+ 
+ #include <stdio.h>
+ 
+ #include <arglex2.h>
+ #include <change.h>
+ #include <commit.h>
+ #include <error.h>
+ #include <gonzo.h>
+ #include <help.h>
+ #include <list.h>
+ #include <lock.h>
+ #include <option.h>
+ #include <project.h>
+ #include <rem_proj.h>
+ #include <str.h>
+ #include <trace.h>
+ #include <user.h>
+ 
+ 
+ static void remove_project_usage _((void));
+ 
+ static void
+ remove_project_usage()
+ {
+ 	char	*progname;
+ 
+ 	progname = option_get_progname();
+ 	fprintf
+ 	(
+ 		stderr,
+ 		"usage: %s -ReMove_PRoject [ <option>... ]\n",
+ 		progname
+ 	);
+ 	fprintf
+ 	(
+ 		stderr,
+ 		"       %s -ReMove_PRoject -List [ <option>... ]\n",
+ 		progname
+ 	);
+ 	fprintf(stderr, "       %s -ReMove_PRoject -Help\n", progname);
+ 	quit(1);
+ }
+ 
+ 
+ static void remove_project_help _((void));
+ 
+ static void
+ remove_project_help()
+ {
+ 	static char *text[] =
+ 	{
+ "NAME",
+ "	%s -ReMove_PRoject - remove project",
+ "",
+ "SYNOPSIS",
+ "	%s -ReMove_Project <project-name> [ <option>...  ]",
+ "	%s -ReMove_Project -List [ <option>...  ]",
+ "	%s -ReMove_Project -Help",
+ "",
+ "DESCRIPTION",
+ "	The %s -ReMove_PRoject command is used to remove a",
+ "	project, either entirely, or just from %s' supervision.",
+ "",
+ "OPTIONS",
+ "	The following options are understood:",
+ "",
+ "	-Keep",
+ "		This option may be used to retain files and/or",
+ "		directories usually deleted by the command.",
+ "",
+ "	-LIBrary <abspath>",
+ "		This option may be used to specify a directory to be",
+ "		searched for global state files and user state",
+ "		files.  (See aegstate(5) and aeustate(5) for more",
+ "		information.) Several library options may be present",
+ "		on the command line, and are search in the order",
+ "		given.  Appended to this explicit search path are",
+ "		the directories specified by the AEGIS enviroment",
+ "		variable (colon separated), and finally,",
+ "		/usr/local/lib/%s is always searched.  All paths",
+ "		specified, either on the command line or in the",
+ "		AEGIS environment variable, must be absolute.",
+ "",
+ "	-List",
+ "		This option may be used to obtain a list of suitable",
+ "		subjects for this command.  The list may be more",
+ "		general than expected.",
+ "",
+ "	-Help",
+ "		This option may be used to obtain more information",
+ "		about how to use the %s program.",
+ "",
+ "	-Project <name>",
+ "		This option may be used to select the project of",
+ "		interest.  When no -Project option is specified, the",
+ "		AEGIS_PROJECT environment variable is consulted.  If",
+ "		that does not exist, the user's $HOME/.aegisrc file",
+ "		is examined for a default project field (see",
+ "		aeuconf(5) for more information).  If that does not",
+ "		exist, when the user is only working on changes",
+ "		within a single project, the project name defaults",
+ "		to that project.  Otherwise, it is an error.",
+ "",
+ "	-TERse",
+ "		This option may be used to cause listings to produce",
+ "		the bare minimum of information.  It is usually",
+ "		useful for shell scripts.",
+ "",
+ "	-Verbose",
+ "		This option may be used to cause %s to produce",
+ "		more output.  By default %s only produces output",
+ "		on errors.  When used with the -List option this",
+ "		option causes column headings to be added.",
+ "",
+ "	All options may be abbreviated; the abbreviation is",
+ "	documented as the upper case letters, all lower case",
+ "	letters and underscores (_) are optional.  You must use",
+ "	consecutive sequences of optional letters.",
+ "",
+ "	All options are case insensitive, you may type them in",
+ "	upper case or lower case or a combination of both, case",
+ "	is not important.",
+ "",
+ "	For example: the arguments \"-project, \"-PROJ\" and \"-p\"",
+ "	are all interpreted to mean the -Project option.  The",
+ "	argument \"-prj\" will not be understood, because",
+ "	consecutive optional characters were not supplied.",
+ "",
+ "	Options and other command line arguments may be mixed",
+ "	arbitrarily on the command line, after the function",
+ "	selectors.",
+ "",
+ "	The GNU long option names are understood.  Since all",
+ "	option names for aegis are long, this means ignoring the",
+ "	extra leading '-'.  The \"--option=value\" convention is",
+ "	also understood.",
+ "",
+ "RECOMMENDED ALIAS",
+ "	The recommended alias for this command is",
+ "	csh%%	alias aermpr '%s -rmpr \\!* -v'",
+ "	sh$	aermpr(){%s -rmpr $* -v}",
+ "",
+ "ERRORS",
+ "	It is an error if the project has any changes between the",
+ "	being developed and being integrated states, inclusive.",
+ "	It is an error if the current user is not an administrator.",
+ "",
+ "EXIT STATUS",
+ "	The %s command will exit with a status of 1 on any error.",
+ "	The %s command will only exit with a status of 0 if there",
+ "	are no errors.",
+ "",
+ "COPYRIGHT",
+ "	%C",
+ "",
+ "AUTHOR",
+ "	%A",
+ 	};
+ 
+ 	help(text, SIZEOF(text), remove_project_usage);
+ }
+ 
+ 
+ static void remove_project_list _((void));
+ 
+ static void
+ remove_project_list()
+ {
+ 	arglex();
+ 	while (arglex_token != arglex_token_eoln)
+ 		generic_argument(remove_project_usage);
+ 	list_projects(0, 0);
+ }
+ 
+ 
+ static void remove_project_main _((void));
+ 
+ static void
+ remove_project_main()
+ {
+ 	long		nerr;
+ 	int		j;
+ 	pstate		pstate_data;
+ 	string_ty	*project_name;
+ 	project_ty	*pp;
+ 	change_ty	*cp;
+ 	cstate		cstate_data;
+ 	user_ty		*up;
+ 	int		keep;
+ 
+ 	trace(("remove_project_main()\n{\n"/*}*/));
+ 	keep = 0;
+ 	project_name = 0;
+ 	while (arglex_token != arglex_token_eoln)
+ 	{
+ 		switch (arglex_token)
+ 		{
+ 		default:
+ 			generic_argument(remove_project_usage);
+ 			continue;
+ 
+ 		case arglex_token_keep:
+ 			if (keep)
+ 			{
+ 				error
+ 				(
+ 					"duplicate \"%s\" option",
+ 					arglex_value.alv_string
+ 				);
+ 				remove_project_usage();
+ 			}
+ 			keep = 1;
+ 			break;
+ 
+ 		case arglex_token_project:
+ 			if (arglex() != arglex_token_string)
+ 				remove_project_usage();
+ 			/* fall through... */
+ 
+ 		case arglex_token_string:
+ 			if (project_name)
+ 				fatal("duplicate -Project option");
+ 			project_name = str_from_c(arglex_value.alv_string);
+ 			break;
+ 		}
+ 		arglex();
+ 	}
+ 
+ 	/*
+ 	 * locate project data
+ 	 */
+ 	if (!project_name)
+ 		fatal("project must be named explicitly");
+ 	pp = project_alloc(project_name);
+ 	str_free(project_name);
+ 	project_bind_existing(pp);
+ 
+ 	/*
+ 	 * locate user data
+ 	 */
+ 	up = user_executing(pp);
+ 
+ 	/*
+ 	 * lock the project
+ 	 */
+ 	project_pstate_lock_prepare(pp);
+ 	gonzo_gstate_lock_prepare_new();
+ 	lock_take();
+ 	pstate_data = project_pstate_get(pp);
+ 
+ 	/*
+ 	 * it is an error if any of the changes are active
+ 	 */
+ 	nerr = 0;
+ 	for (j = 0; j < pstate_data->change->length; ++j)
+ 	{
+ 		long	change_number;
+ 
+ 		change_number = pstate_data->change->list[j];
+ 		cp = change_alloc(pp, change_number);
+ 		change_bind_existing(cp);
+ 		cstate_data = change_cstate_get(cp);
+ 		if
+ 		(
+ 			cstate_data->state >= cstate_state_being_developed
+ 		&& 
+ 			cstate_data->state <= cstate_state_being_integrated
+ 		)
+ 		{
+ 			change_error(cp, "still active");
+ 			++nerr;
+ 		}
+ 		change_free(cp);
+ 	}
+ 
+ 	/*
+ 	 * it is an error if the current user is not an administrator
+ 	 */
+ 	if (!project_administrator_query(pp, user_name(up)))
+ 	{
+ 		project_error
+ 		(
+ 			pp,
+ 			"user \"%S\" is not an administrator",
+ 			user_name(up)
+ 		);
+ 		nerr++;
+ 	}
+ 	if (nerr)
+ 		quit(1);
+ 
+ 	/*
+ 	 * remove the project directory
+ 	 */
+ 	if (!keep)
+ 	{
+ 		project_verbose(pp, "remove project directory");
+ 		project_become(pp);
+ 		commit_rmdir_tree_errok(project_home_path_get(pp));
+ 		project_become_undo();
+ 	}
+ 
+ 	/*
+ 	 * tell gonzo to forget about this project
+ 	 */
+ 	gonzo_project_delete(pp);
+ 	gonzo_gstate_write();
+ 
+ 	/*
+ 	 * release the locks
+ 	 */
+ 	commit();
+ 	lock_release();
+ 
+ 	/*
+ 	 * verbose success message
+ 	 */
+ 	project_verbose(pp, "removed");
+ 
+ 	/*
+ 	 * clean up and go home
+ 	 */
+ 	project_free(pp);
+ 	user_free(up);
+ 	trace((/*{*/"}\n"));
+ }
+ 
+ 
+ void
+ remove_project()
+ {
+ 	trace(("remove_project()\n{\n"/*}*/));
+ 	switch (arglex())
+ 	{
+ 	default:
+ 		remove_project_main();
+ 		break;
+ 
+ 	case arglex_token_help:
+ 		remove_project_help();
+ 		break;
+ 
+ 	case arglex_token_list:
+ 		remove_project_list();
+ 		break;
+ 	}
+ 	trace((/*{*/"}\n"));
+ }
Index: aegis/rem_proj.h
***************
*** 0 ****
--- 1,30 ----
+ /*
+  *	aegis - project change supervisor
+  *	Copyright (C) 1993 Peter Miller.
+  *	All rights reserved.
+  *
+  *	This program is free software; you can redistribute it and/or modify
+  *	it under the terms of the GNU General Public License as published by
+  *	the Free Software Foundation; either version 2 of the License, or
+  *	(at your option) any later version.
+  *
+  *	This program is distributed in the hope that it will be useful,
+  *	but WITHOUT ANY WARRANTY; without even the implied warranty of
+  *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  *	GNU General Public License for more details.
+  *
+  *	You should have received a copy of the GNU General Public License
+  *	along with this program; if not, write to the Free Software
+  *	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+  *
+  * MANIFEST: interface definition for aegis/rem_proj.c
+  */
+ 
+ #ifndef REM_PROJ_H
+ #define REM_PROJ_H
+ 
+ #include <main.h>
+ 
+ void remove_project _((void));
+ 
+ #endif /* REM_PROJ_H */
Index: aegis/review.c
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 87,95 ****
  "",
  "	-Change <number>",
  "		This option may be used to specify a particular",
! "		change within a project.  If the user is only",
! "		working on one change within a project, that is",
! "		the default change number.",
  "",
  "	-Help",
  "		This option may be used to obtain more",
--- 87,100 ----
  "",
  "	-Change <number>",
  "		This option may be used to specify a particular",
! "		change within a project.  When no -Change option is",
! "		specified, the AEGIS_CHANGE environment variable is",
! "		consulted.  If that does not exist, the user's",
! "		$HOME/.aegisrc file is examined for a default change",
! "		field (see aeuconf(5) for more information).  If",
! "		that does not exist, when the user is only working",
! "		on one change within a project, that is the default",
! "		change number.  Otherwise, it is an error.",
  "",
  "	-Help",
  "		This option may be used to obtain more",
***************
*** 102,115 ****
  "",
  "	-Project <name>",
  "		This option may be used to select the project of",
! "		interest.  When no -Project option is specified, if",
! "		the user is only working on changes within a single",
! "		project, the project name defaults to that project;",
! "		if the user is currently working on changes to more",
! "		than one project, or is not working on changes to",
! "		any project, the user's $HOME/.%src file is",
! "		examined for a default project field (see aeuconf(5)",
! "		for more information).",
  "",
  "	-TERse",
  "		This option may be used to cause listings to",
--- 107,120 ----
  "",
  "	-Project <name>",
  "		This option may be used to select the project of",
! "		interest.  When no -Project option is specified, the",
! "		AEGIS_PROJECT environment variable is consulted.  If",
! "		that does not exist, the user's $HOME/.aegisrc file",
! "		is examined for a default project field (see",
! "		aeuconf(5) for more information).  If that does not",
! "		exist, when the user is only working on changes",
! "		within a single project, the project name defaults",
! "		to that project.  Otherwise, it is an error.",
  "",
  "	-TERse",
  "		This option may be used to cause listings to",
***************
*** 123,133 ****
  "		option this option causes column headings to be",
  "		added.",
  "",
! "	All options are case insensitive.  Options may be",
! "	abbreviated; the abbreviation is the upper case letters.",
  "	Options and other command line arguments may be mixed",
! "	arbitrarily on the command line.",
  "",
  "RECOMMENDED ALIAS",
  "	The recommended alias for this command is",
  "	csh%%	alias aerp '%s -rp \\!* -v'",
--- 128,156 ----
  "		option this option causes column headings to be",
  "		added.",
  "",
! "	All options may be abbreviated; the abbreviation is",
! "	documented as the upper case letters, all lower case",
! "	letters and underscores (_) are optional.  You must use",
! "	consecutive sequences of optional letters.",
! "",
! "	All options are case insensitive, you may type them in",
! "	upper case or lower case or a combination of both, case",
! "	is not important.",
! "",
! "	For example: the arguments \"-project, \"-PROJ\" and \"-p\"",
! "	are all interpreted to mean the -Project option.  The",
! "	argument \"-prj\" will not be understood, because",
! "	consecutive optional characters were not supplied.",
! "",
  "	Options and other command line arguments may be mixed",
! "	arbitrarily on the command line, after the function",
! "	selectors.",
  "",
+ "	The GNU long option names are understood.  Since all",
+ "	option names for aegis are long, this means ignoring the",
+ "	extra leading '-'.  The \"--option=value\" convention is",
+ "	also understood.",
+ "",
  "RECOMMENDED ALIAS",
  "	The recommended alias for this command is",
  "	csh%%	alias aerp '%s -rp \\!* -v'",
***************
*** 164,170 ****
  review_list(usage)
  	void		(*usage)_((void));
  {
! 	string_t	*project_name;
  
  	trace(("review_list()\n{\n"/*}*/));
  	project_name = 0;
--- 187,193 ----
  review_list(usage)
  	void		(*usage)_((void));
  {
! 	string_ty	*project_name;
  
  	trace(("review_list()\n{\n"/*}*/));
  	project_name = 0;
***************
*** 209,219 ****
  	cstate		cstate_data;
  	pstate		pstate_data;
  	cstate_history	history_data;
! 	string_t	*project_name;
! 	project_t	*pp;
  	long		change_number;
! 	change_t	*cp;
! 	user_t		*up;
  
  	trace(("review_pass_main()\n{\n"/*}*/));
  	project_name = 0;
--- 232,242 ----
  	cstate		cstate_data;
  	pstate		pstate_data;
  	cstate_history	history_data;
! 	string_ty	*project_name;
! 	project_ty	*pp;
  	long		change_number;
! 	change_ty	*cp;
! 	user_ty		*up;
  
  	trace(("review_pass_main()\n{\n"/*}*/));
  	project_name = 0;
***************
*** 400,409 ****
  "	The following options are understood:",
  "",
  "	-Change <number>",
! "		 This option may be used to specify a particular",
! "		 change within a project.  If the user is only",
! "		 working on one change within a project, that is the",
! "		 default change number.",
  "",
  "	-Help",
  "		 This option may be used to obtain more information",
--- 423,437 ----
  "	The following options are understood:",
  "",
  "	-Change <number>",
! "		This option may be used to specify a particular",
! "		change within a project.  When no -Change option is",
! "		specified, the AEGIS_CHANGE environment variable is",
! "		consulted.  If that does not exist, the user's",
! "		$HOME/.aegisrc file is examined for a default change",
! "		field (see aeuconf(5) for more information).  If",
! "		that does not exist, when the user is only working",
! "		on one change within a project, that is the default",
! "		change number.  Otherwise, it is an error.",
  "",
  "	-Help",
  "		 This option may be used to obtain more information",
***************
*** 416,429 ****
  "",
  "	-Project <name>",
  "		This option may be used to select the project of",
! "		interest.  When no -Project option is specified, if",
! "		the user is only working on changes within a single",
! "		project, the project name defaults to that project;",
! "		if the user is currently working on changes to more",
! "		than one project, or is not working on changes to",
! "		any project, the user's $HOME/.%src file is",
! "		examined for a default project field (see aeuconf(5)",
! "		for more information).",
  "",
  "	-TERse",
  "		 This option may be used to cause listings to produce",
--- 444,457 ----
  "",
  "	-Project <name>",
  "		This option may be used to select the project of",
! "		interest.  When no -Project option is specified, the",
! "		AEGIS_PROJECT environment variable is consulted.  If",
! "		that does not exist, the user's $HOME/.aegisrc file",
! "		is examined for a default project field (see",
! "		aeuconf(5) for more information).  If that does not",
! "		exist, when the user is only working on changes",
! "		within a single project, the project name defaults",
! "		to that project.  Otherwise, it is an error.",
  "",
  "	-TERse",
  "		 This option may be used to cause listings to produce",
***************
*** 436,446 ****
  "		 on errors.  When used with the -List option this",
  "		 option causes column headings to be added.",
  "",
! "	All options are case insensitive.  Options may be",
! "	abbreviated; the abbreviation is the upper case letters.",
  "	Options and other command line arguments may be mixed",
! "	arbitrarily on the command line.",
  "",
  "RECOMMENDED ALIAS",
  "	The recommended alias for this command is",
  "	csh%%	alias aerpu '%s -rp \\!* -v'",
--- 464,492 ----
  "		 on errors.  When used with the -List option this",
  "		 option causes column headings to be added.",
  "",
! "	All options may be abbreviated; the abbreviation is",
! "	documented as the upper case letters, all lower case",
! "	letters and underscores (_) are optional.  You must use",
! "	consecutive sequences of optional letters.",
! "",
! "	All options are case insensitive, you may type them in",
! "	upper case or lower case or a combination of both, case",
! "	is not important.",
! "",
! "	For example: the arguments \"-project, \"-PROJ\" and \"-p\"",
! "	are all interpreted to mean the -Project option.  The",
! "	argument \"-prj\" will not be understood, because",
! "	consecutive optional characters were not supplied.",
! "",
  "	Options and other command line arguments may be mixed",
! "	arbitrarily on the command line, after the function",
! "	selectors.",
  "",
+ "	The GNU long option names are understood.  Since all",
+ "	option names for aegis are long, this means ignoring the",
+ "	extra leading '-'.  The \"--option=value\" convention is",
+ "	also understood.",
+ "",
  "RECOMMENDED ALIAS",
  "	The recommended alias for this command is",
  "	csh%%	alias aerpu '%s -rp \\!* -v'",
***************
*** 481,487 ****
  review_pass_undo_list(usage)
  	void		(*usage)_((void));
  {
! 	string_t	*project_name;
  
  	trace(("review_list()\n{\n"/*}*/));
  	project_name = 0;
--- 527,533 ----
  review_pass_undo_list(usage)
  	void		(*usage)_((void));
  {
! 	string_ty	*project_name;
  
  	trace(("review_list()\n{\n"/*}*/));
  	project_name = 0;
***************
*** 526,536 ****
  	cstate		cstate_data;
  	pstate		pstate_data;
  	cstate_history	history_data;
! 	string_t	*project_name;
! 	project_t	*pp;
  	long		change_number;
! 	change_t	*cp;
! 	user_t		*up;
  
  	trace(("review_pass_undo_main()\n{\n"/*}*/));
  	project_name = 0;
--- 572,582 ----
  	cstate		cstate_data;
  	pstate		pstate_data;
  	cstate_history	history_data;
! 	string_ty	*project_name;
! 	project_ty	*pp;
  	long		change_number;
! 	change_ty	*cp;
! 	user_ty		*up;
  
  	trace(("review_pass_undo_main()\n{\n"/*}*/));
  	project_name = 0;
***************
*** 723,731 ****
  "",
  "	-Change <number>",
  "		This option may be used to specify a particular",
! "		change within a project.  If the user is only",
! "		working on one change within a project, that is",
! "		the default change number.",
  "",
  "	-Help",
  "		This option may be used to obtain more",
--- 769,782 ----
  "",
  "	-Change <number>",
  "		This option may be used to specify a particular",
! "		change within a project.  When no -Change option is",
! "		specified, the AEGIS_CHANGE environment variable is",
! "		consulted.  If that does not exist, the user's",
! "		$HOME/.aegisrc file is examined for a default change",
! "		field (see aeuconf(5) for more information).  If",
! "		that does not exist, when the user is only working",
! "		on one change within a project, that is the default",
! "		change number.  Otherwise, it is an error.",
  "",
  "	-Help",
  "		This option may be used to obtain more",
***************
*** 738,751 ****
  "",
  "	-Project <name>",
  "		This option may be used to select the project of",
! "		interest.  When no -Project option is specified, if",
! "		the user is only working on changes within a single",
! "		project, the project name defaults to that project;",
! "		if the user is currently working on changes to more",
! "		than one project, or is not working on changes to",
! "		any project, the user's $HOME/.%src file is",
! "		examined for a default project field (see aeuconf(5)",
! "		for more information).",
  "",
  "	-TERse",
  "		This option may be used to cause listings to",
--- 789,802 ----
  "",
  "	-Project <name>",
  "		This option may be used to select the project of",
! "		interest.  When no -Project option is specified, the",
! "		AEGIS_PROJECT environment variable is consulted.  If",
! "		that does not exist, the user's $HOME/.aegisrc file",
! "		is examined for a default project field (see",
! "		aeuconf(5) for more information).  If that does not",
! "		exist, when the user is only working on changes",
! "		within a single project, the project name defaults",
! "		to that project.  Otherwise, it is an error.",
  "",
  "	-TERse",
  "		This option may be used to cause listings to",
***************
*** 759,769 ****
  "		option this option causes column headings to be",
  "		added.",
  "",
! "	All options are case insensitive.  Options may be",
! "	abbreviated; the abbreviation is the upper case letters.",
  "	Options and other command line arguments may be mixed",
! "	arbitrarily on the command line.",
  "",
  "RECOMMENDED ALIAS",
  "	The recommended alias for this command is",
  "	csh%%	alias aerf '%s -rf \\!* -v'",
--- 810,838 ----
  "		option this option causes column headings to be",
  "		added.",
  "",
! "	All options may be abbreviated; the abbreviation is",
! "	documented as the upper case letters, all lower case",
! "	letters and underscores (_) are optional.  You must use",
! "	consecutive sequences of optional letters.",
! "",
! "	All options are case insensitive, you may type them in",
! "	upper case or lower case or a combination of both, case",
! "	is not important.",
! "",
! "	For example: the arguments \"-project, \"-PROJ\" and \"-p\"",
! "	are all interpreted to mean the -Project option.  The",
! "	argument \"-prj\" will not be understood, because",
! "	consecutive optional characters were not supplied.",
! "",
  "	Options and other command line arguments may be mixed",
! "	arbitrarily on the command line, after the function",
! "	selectors.",
  "",
+ "	The GNU long option names are understood.  Since all",
+ "	option names for aegis are long, this means ignoring the",
+ "	extra leading '-'.  The \"--option=value\" convention is",
+ "	also understood.",
+ "",
  "RECOMMENDED ALIAS",
  "	The recommended alias for this command is",
  "	csh%%	alias aerf '%s -rf \\!* -v'",
***************
*** 794,811 ****
  }
  
  
! static void repair_diff_time _((change_t *, string_t *));
  
  static void
  repair_diff_time(cp, path)
! 	change_t	*cp;
! 	string_t	*path;
  {
! 	string_t	*s;
  	cstate_src	src_data;
! 	string_t	*s2;
  
! 	s = os_below_dir(change_development_directory_get(cp), path);
  	src_data = change_src_find(cp, s);
  	if (src_data)
  		src_data->diff_time = os_mtime(path);
--- 863,880 ----
  }
  
  
! static void repair_diff_time _((change_ty *, string_ty *));
  
  static void
  repair_diff_time(cp, path)
! 	change_ty	*cp;
! 	string_ty	*path;
  {
! 	string_ty	*s;
  	cstate_src	src_data;
! 	string_ty	*s2;
  
! 	s = os_below_dir(change_development_directory_get(cp, 1), path);
  	src_data = change_src_find(cp, s);
  	if (src_data)
  		src_data->diff_time = os_mtime(path);
***************
*** 829,849 ****
  }
  
  
! static void rf_func _((void *, dir_walk_message_t, string_t *, struct stat *));
  
  static void
  rf_func(arg, message, path, st)
  	void		*arg;
! 	dir_walk_message_t message;
! 	string_t	*path;
  	struct stat	*st;
  {
! 	change_t	*cp;
  	int		uid;
  
  	trace(("rf_func(message = %d, path = %08lX, st = %08lX)\n{\n"/*}*/,
  		message, path, st));
! 	cp = (change_t *)arg;
  	trace_string(path->str_text);
  	switch (message)
  	{
--- 898,918 ----
  }
  
  
! static void rf_func _((void *, dir_walk_message_ty, string_ty *, struct stat *));
  
  static void
  rf_func(arg, message, path, st)
  	void		*arg;
! 	dir_walk_message_ty message;
! 	string_ty	*path;
  	struct stat	*st;
  {
! 	change_ty	*cp;
  	int		uid;
  
  	trace(("rf_func(message = %d, path = %08lX, st = %08lX)\n{\n"/*}*/,
  		message, path, st));
! 	cp = (change_ty *)arg;
  	trace_string(path->str_text);
  	switch (message)
  	{
***************
*** 872,889 ****
  static void
  review_fail_main()
  {
! 	string_t	*dd;
  	cstate		cstate_data;
  	pstate		pstate_data;
  	cstate_history	history_data;
! 	string_t	*comment = 0;
  	int		j;
! 	string_t	*project_name;
! 	project_t	*pp;
  	long		change_number;
! 	change_t	*cp;
! 	user_t		*up;
! 	user_t		*devup;
  
  	trace(("review_fail_main()\n{\n"/*}*/));
  	project_name = 0;
--- 941,958 ----
  static void
  review_fail_main()
  {
! 	string_ty	*dd;
  	cstate		cstate_data;
  	pstate		pstate_data;
  	cstate_history	history_data;
! 	string_ty	*comment = 0;
  	int		j;
! 	string_ty	*project_name;
! 	project_ty	*pp;
  	long		change_number;
! 	change_ty	*cp;
! 	user_ty		*up;
! 	user_ty		*devup;
  
  	trace(("review_fail_main()\n{\n"/*}*/));
  	project_name = 0;
***************
*** 1007,1013 ****
  	 * Restore write permission to the change files
  	 * and repair the diff time fields.
  	 */
! 	dd = change_development_directory_get(cp);
  	user_become(devup);
  	dir_walk(dd, rf_func, cp);
  	os_become_undo();
--- 1076,1082 ----
  	 * Restore write permission to the change files
  	 * and repair the diff time fields.
  	 */
! 	dd = change_development_directory_get(cp, 1);
  	user_become(devup);
  	dir_walk(dd, rf_func, cp);
  	os_become_undo();
Index: aegis/review.h
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
Index: aegis/reviewer.c
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 86,99 ****
  "",
  "	-Project <name>",
  "		This option may be used to select the project of",
! "		interest.  When no -Project option is specified, if",
! "		the user is only working on changes within a single",
! "		project, the project name defaults to that project;",
! "		if the user is currently working on changes to more",
! "		than one project, or is not working on changes to",
! "		any project, the user's $HOME/.%src file is",
! "		examined for a default project field (see aeuconf(5)",
! "		for more information).",
  "",
  "	-TERse",
  "		This option may be used to cause listings to produce",
--- 86,99 ----
  "",
  "	-Project <name>",
  "		This option may be used to select the project of",
! "		interest.  When no -Project option is specified, the",
! "		AEGIS_PROJECT environment variable is consulted.  If",
! "		that does not exist, the user's $HOME/.aegisrc file",
! "		is examined for a default project field (see",
! "		aeuconf(5) for more information).  If that does not",
! "		exist, when the user is only working on changes",
! "		within a single project, the project name defaults",
! "		to that project.  Otherwise, it is an error.",
  "",
  "	-TERse",
  "		This option may be used to cause listings to produce",
***************
*** 105,115 ****
  "		more output.  By default %s only produces output",
  "		on errors.  When used with the -List option this",
  "		option causes column headings to be added.",
- "		",
- "	All options are case insensitive.  Options may be abbreviated;",
- "	the abbreviation is the upper case letters.  Options and other",
- "	command line arguments may be mixed arbitrarily on the command line.",
  "",
  "RECOMMENDED ALIAS",
  "	The recommended alias for this command is",
  "	csh%%	alias aenrv '%s -nrv \\!* -v'",
--- 105,134 ----
  "		more output.  By default %s only produces output",
  "		on errors.  When used with the -List option this",
  "		option causes column headings to be added.",
  "",
+ "	All options may be abbreviated; the abbreviation is",
+ "	documented as the upper case letters, all lower case",
+ "	letters and underscores (_) are optional.  You must use",
+ "	consecutive sequences of optional letters.",
+ "",
+ "	All options are case insensitive, you may type them in",
+ "	upper case or lower case or a combination of both, case",
+ "	is not important.",
+ "",
+ "	For example: the arguments \"-project, \"-PROJ\" and \"-p\"",
+ "	are all interpreted to mean the -Project option.  The",
+ "	argument \"-prj\" will not be understood, because",
+ "	consecutive optional characters were not supplied.",
+ "",
+ "	Options and other command line arguments may be mixed",
+ "	arbitrarily on the command line, after the function",
+ "	selectors.",
+ "",
+ "	The GNU long option names are understood.  Since all",
+ "	option names for aegis are long, this means ignoring the",
+ "	extra leading '-'.  The \"--option=value\" convention is",
+ "	also understood.",
+ "",
  "RECOMMENDED ALIAS",
  "	The recommended alias for this command is",
  "	csh%%	alias aenrv '%s -nrv \\!* -v'",
***************
*** 141,147 ****
  reviewer_list(usage)
  	void	(*usage)_((void));
  {
! 	string_t	*project_name;
  
  	trace(("reviewer_list()\n{\n"/*}*/));
  	project_name = 0;
--- 160,166 ----
  reviewer_list(usage)
  	void	(*usage)_((void));
  {
! 	string_ty	*project_name;
  
  	trace(("reviewer_list()\n{\n"/*}*/));
  	project_name = 0;
***************
*** 177,188 ****
  new_reviewer_main()
  {
  	wlist		wl;
! 	string_t	*s1;
  	pstate		pstate_data;
  	int		j;
! 	string_t	*project_name;
! 	project_t	*pp;
! 	user_t		*up;
  
  	trace(("new_reviewer_main()\n{\n"/*}*/));
  	project_name = 0;
--- 196,207 ----
  new_reviewer_main()
  {
  	wlist		wl;
! 	string_ty	*s1;
  	pstate		pstate_data;
  	int		j;
! 	string_ty	*project_name;
! 	project_ty	*pp;
! 	user_ty		*up;
  
  	trace(("new_reviewer_main()\n{\n"/*}*/));
  	project_name = 0;
***************
*** 255,261 ****
  	 */
  	for (j = 0; j < wl.wl_nwords; ++j)
  	{
! 		user_t		*candidate;
  
  		/*
  		 * make sure the user isn't already there
--- 274,280 ----
  	 */
  	for (j = 0; j < wl.wl_nwords; ++j)
  	{
! 		user_ty		*candidate;
  
  		/*
  		 * make sure the user isn't already there
***************
*** 387,400 ****
  "",
  "	-Project <name>",
  "		This option may be used to select the project of",
! "		interest.  When no -Project option is specified, if",
! "		the user is only working on changes within a single",
! "		project, the project name defaults to that project;",
! "		if the user is currently working on changes to more",
! "		than one project, or is not working on changes to",
! "		any project, the user's $HOME/.%src file is",
! "		examined for a default project field (see aeuconf(5)",
! "		for more information).",
  "",
  "	-TERse",
  "		This option may be used to cause listings to produce",
--- 406,419 ----
  "",
  "	-Project <name>",
  "		This option may be used to select the project of",
! "		interest.  When no -Project option is specified, the",
! "		AEGIS_PROJECT environment variable is consulted.  If",
! "		that does not exist, the user's $HOME/.aegisrc file",
! "		is examined for a default project field (see",
! "		aeuconf(5) for more information).  If that does not",
! "		exist, when the user is only working on changes",
! "		within a single project, the project name defaults",
! "		to that project.  Otherwise, it is an error.",
  "",
  "	-TERse",
  "		This option may be used to cause listings to produce",
***************
*** 406,416 ****
  "		more output.  By default %s only produces output",
  "		on errors.  When used with the -List option this",
  "		option causes column headings to be added.",
- "		",
- "	All options are case insensitive.  Options may be abbreviated; the",
- "	abbreviation is the upper case letters.  Options and other command",
- "	line arguments may be mixed arbitrarily on the command line.",
  "",
  "RECOMMENDED ALIAS",
  "	The recommended alias for this command is",
  "	csh%%	alias aerrv '%s -rrv \\!* -v'",
--- 425,454 ----
  "		more output.  By default %s only produces output",
  "		on errors.  When used with the -List option this",
  "		option causes column headings to be added.",
  "",
+ "	All options may be abbreviated; the abbreviation is",
+ "	documented as the upper case letters, all lower case",
+ "	letters and underscores (_) are optional.  You must use",
+ "	consecutive sequences of optional letters.",
+ "",
+ "	All options are case insensitive, you may type them in",
+ "	upper case or lower case or a combination of both, case",
+ "	is not important.",
+ "",
+ "	For example: the arguments \"-project, \"-PROJ\" and \"-p\"",
+ "	are all interpreted to mean the -Project option.  The",
+ "	argument \"-prj\" will not be understood, because",
+ "	consecutive optional characters were not supplied.",
+ "",
+ "	Options and other command line arguments may be mixed",
+ "	arbitrarily on the command line, after the function",
+ "	selectors.",
+ "",
+ "	The GNU long option names are understood.  Since all",
+ "	option names for aegis are long, this means ignoring the",
+ "	extra leading '-'.  The \"--option=value\" convention is",
+ "	also understood.",
+ "",
  "RECOMMENDED ALIAS",
  "	The recommended alias for this command is",
  "	csh%%	alias aerrv '%s -rrv \\!* -v'",
***************
*** 442,453 ****
  remove_reviewer_main()
  {
  	wlist		wl;
! 	string_t	*s1;
  	pstate		pstate_data;
  	int		j;
! 	string_t	*project_name;
! 	project_t	*pp;
! 	user_t		*up;
  
  	trace(("remove_reviewer_main()\n{\n"/*}*/));
  	project_name = 0;
--- 480,491 ----
  remove_reviewer_main()
  {
  	wlist		wl;
! 	string_ty	*s1;
  	pstate		pstate_data;
  	int		j;
! 	string_ty	*project_name;
! 	project_ty	*pp;
! 	user_ty		*up;
  
  	trace(("remove_reviewer_main()\n{\n"/*}*/));
  	project_name = 0;
***************
*** 520,526 ****
  	 */
  	for (j = 0; j < wl.wl_nwords; ++j)
  	{
! 		user_t	*candidate;
  
  		candidate = user_symbolic(pp, wl.wl_word[j]);
  		if (!project_reviewer_query(pp, user_name(candidate)))
--- 558,564 ----
  	 */
  	for (j = 0; j < wl.wl_nwords; ++j)
  	{
! 		user_ty	*candidate;
  
  		candidate = user_symbolic(pp, wl.wl_word[j]);
  		if (!project_reviewer_query(pp, user_name(candidate)))
Index: aegis/reviewer.h
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
Index: aegis/sub.c
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 20,243 ****
   * MANIFEST: functions to perform command substitutions
   */
  
  #include <change.h>
  #include <error.h>
  #include <option.h>
  #include <os.h>
  #include <project.h>
- #include <s-v-arg.h>
  #include <sub.h>
  #include <trace.h>
  
  
! string_t *
! substitute(cp, fmt sva_last)
! 	change_t	*cp;
! 	char		*fmt;
! 	sva_last_decl
  {
! 	va_list		ap;
! 	char		*arg[9];
! 	int		nargs;
! 	char		*out;
! 	char		*in;
! 	char		buffer[2000];
! 	int		c;
! 	char		*bp;
  
! 	trace(("substitute(cp = %08lX, fmt = %08lX)\n{\n"/*}*/, cp, fmt));
! 	trace_string(fmt);
! 	assert(cp);
  
! 	/*
! 	 * collect the arguments
! 	 */
! 	sva_init(ap, fmt);
! 	for (nargs = 0; nargs < 9; ++nargs)
  	{
! 		arg[nargs] = va_arg(ap, char *);
! 		if (!arg[nargs])
  			break;
! 		trace_string(arg[nargs]);
  	}
! 	va_end(ap);
! 	trace_int(nargs);
  
! 	out = buffer;
! 	in = fmt;
! 	while (*in)
  	{
! 		int		path;
! 		int		file;
! 		string_t	*s;
! 		string_t	*s2;
  
! 		/*
! 		 * get the next character
! 		 */
! 		c = *in++;
! 		if (c != '%')
  		{
! 			*out++ = c;
! 			continue;
  		}
  
  		/*
! 		 * started a % sequence
  		 */
! 		c = *in++;
! 		path = 0;
! 		file = 0;
  
  		/*
! 		 * look for modifiers
! 		 *	F	basename part
! 		 *	P	directory part
  		 */
! 		if (c == '%')
  		{
! 			*out++ = c;
! 			continue;
  		}
! 		while (c == 'P')
  		{
! 			path++;
! 			c = *in++;
  		}
! 		if (c == 'F')
  		{
! 			file = 1;
! 			c = *in++;
  		}
  
  		/*
! 		 * get the argument number
! 		 * or the special %(name) construct
  		 */
! 		switch (c)
  		{
! 		default:
! 			fatal("bad command \"%s\" format (%%%c)", fmt, c);
  
! 		case '1': case '2': case '3': case '4':
! 		case '5': case '6': case '7': case '8': case '9': 
! 			/*
! 			 * get the Nth argument
! 			 */
! 			if (c - '1' >= nargs)
  			{
! 				fatal
  				(
! 		       "bad command \"%s\" substitution, argument %%%c unknown",
! 					fmt,
! 					c
  				);
  			}
! 			s = str_from_c(arg[c - '1']);
  			break;
  
! 		case '('/*)*/:
  			/*
! 			 * find change/project path
  			 */
! 			bp = in;
! 			while (*in && *in != /*(*/')')
! 				++in;
! 			if (!*in)
  			{
! 				fatal
! 				(
! 		  "bad command \"%s\" substitution, file %%(name) unterminated",
! 					fmt
! 				);
  			}
- 			s = str_n_from_c(bp, in - bp);
- 			++in;
  
  			/*
! 			 * Make sure the named file exists
! 			 * either in the change or in the project.
  			 */
! 			if (!change_src_find(cp, s))
  			{
! 				if (project_src_find(cp->pp, s))
! 				{
! 					cstate		cstate_data;
! 	
! 					/*
! 					 * if the project is is the 'being
! 					 * developed' state, need to qualify
! 					 * the file name with the baseline
! 					 * directory name.
! 					 *
! 					 * If the change is in the 'being
! 					 * integrated' state, don't do
! 					 * anything, as files in the
! 					 * project AND files in the change
! 					 * are below the current directory.
! 					 */
! 					cstate_data = change_cstate_get(cp);
! 					if
! 					(
! 						cstate_data->state
! 					<
! 						cstate_state_being_integrated
! 					)
! 					{
! 						s2 =
! 							str_format
! 							(
! 								"%S/%S",
! 					      project_baseline_path_get(cp->pp),
! 								s
! 							);
! 						str_free(s);
! 						s = s2;
! 					}
! 				}
! 				else
! 				{
! 					fatal
! 					(
! 		     "bad command \"%s\" substitution, file \"%%(%s)\" unknown",
! 						fmt,
! 						s->str_text
! 					);
! 				}
  			}
  			break;
  		}
  
  		/*
! 		 * perform modifiers
  		 */
! 		while (path--)
  		{
! 			change_become(cp);
! 			s2 = os_dirname(s);
! 			os_become_undo();
! 			str_free(s);
! 			s = s2;
  		}
- 		if (file)
- 		{
- 			change_become(cp);
- 			s2 = os_entryname(s);
- 			os_become_undo();
- 			str_free(s);
- 			s = s2;
- 		}
  
  		/*
! 		 * copy the string to the output
  		 */
! 		bp = s->str_text;
! 		while (*bp)
! 			*out++ = *bp++;
! 		str_free(s);
  	}
! 	*out = 0;
! 	trace_string(buffer);
  	trace((/*{*/"}\n"));
! 	return str_from_c(buffer);
  }
--- 20,2189 ----
   * MANIFEST: functions to perform command substitutions
   */
  
+ #include <ctype.h>
+ 
+ #include <arglex.h>
  #include <change.h>
  #include <error.h>
+ #include <mem.h>
  #include <option.h>
  #include <os.h>
  #include <project.h>
  #include <sub.h>
  #include <trace.h>
+ #include <word.h>
  
+ typedef string_ty *(*fp)_((wlist *));
  
! typedef struct table_ty table_ty;
! struct table_ty
  {
! 	char		*name;
! 	fp		func;
! 	string_ty	*value;
! };
  
! typedef struct diversion_ty diversion_ty;
! struct diversion_ty
! {
! 	long		pos;
! 	string_ty	*text;
! 	diversion_ty	*prev;
! };
  
! 
! static	diversion_ty	*diversion;
! static	char		*collect_buf;
! static	size_t		collect_size;
! static	size_t		collect_pos;
! static	table_ty	*sub_var_list;
! static	size_t		sub_var_size;
! static	size_t		sub_var_pos;
! static	change_ty	*cp;
! static	project_ty	*pp;
! static	char		*suberr;
! 
! 
! /*
!  * NAME
!  *	sub_administrator_list - the administrator_list substitution
!  *
!  * SYNOPSIS
!  *	string_ty *sub_administrator_list(wlist *arg);
!  *
!  * DESCRIPTION
!  *	The sub_administrator_list function implements the administrator_list
!  * 	substitution.  The administrator_list substitution is replaced by
!  *	a space separated list of project administrators.
!  *
!  * ARGUMENTS
!  *	arg	- list of arguments, including the function name as [0]
!  *
!  * RETURNS
!  *	a pointer to a string in dynamic memory;
!  *	or NULL on error, setting suberr appropriately.
!  */
! 
! static string_ty *sub_administrator_list _((wlist *));
! 
! static string_ty *
! sub_administrator_list(arg)
! 	wlist		*arg;
! {
! 	string_ty	*result;
! 	pstate		pstate_data;
! 	long		j;
! 
! 	trace(("sub_administrator_list()\n{\n"/*}*/));
! 	if (arg->wl_nwords != 1)
  	{
! 		suberr = "requires zero arguments";
! 		result = 0;
! 	}
! 	else
! 	{
! 		/*
! 		 * build a string containing all of the project administrators
! 		 */
! 		assert(pp);
! 		pstate_data = project_pstate_get(pp);
! 		assert(pstate_data->administrator);
! 		switch (pstate_data->administrator->length)
! 		{
! 		case 0:
! 			result = str_from_c("");
  			break;
! 	
! 		case 1:
! 			result = str_copy(pstate_data->administrator->list[0]);
! 			break;
! 	
! 		default:
! 			assert(pstate_data->administrator->length >= 2);
! 			result = str_copy(pstate_data->administrator->list[0]);
! 			for (j = 1; j < pstate_data->administrator->length; ++j)
! 			{
! 				string_ty	*s;
! 	
! 				s =
! 					str_format
! 					(
! 						"%S %S",
! 						result,
! 						pstate_data->administrator->
! 							list[j]
! 					);
! 				str_free(result);
! 				result = s;
! 			}
! 			break;
! 		}
  	}
! 	trace(("return \"%s\";\n", result ? result->str_text : suberr));
! 	trace((/*{*/"}\n"));
! 	return result;
! }
  
! 
! /*
!  * NAME
!  *	sub_baseline - the baseline substitution
!  *
!  * SYNOPSIS
!  *	string_ty *sub_baseline(wlist *arg);
!  *
!  * DESCRIPTION
!  *	The sub_baseline function implements the baseline substitution.
!  *	The baseline substitution is used to insert the absolute path
!  *	of the baseline.
!  *
!  * ARGUMENTS
!  *	arg	- list of arguments, including the function name as [0]
!  *
!  * RETURNS
!  *	a pointer to a string in dynamic memory;
!  *	or NULL on error, setting suberr appropriately.
!  */
! 
! static string_ty *sub_baseline _((wlist *));
! 
! static string_ty *
! sub_baseline(arg)
! 	wlist		*arg;
! {
! 	string_ty	*result;
! 
! 	trace(("sub_baseline()\n{\n"/*}*/));
! 	if (arg->wl_nwords != 1)
  	{
! 		suberr = "requires zero arguments";
! 		result = 0;
! 	}
! 	else
! 		result = str_copy(project_baseline_path_get(pp, 0));
! 	trace(("return \"%s\";\n", result ? result->str_text : suberr));
! 	trace((/*{*/"}\n"));
! 	return result;
! }
  
! 
! /*
!  * NAME
!  *	sub_basename - the basename substitution
!  *
!  * SYNOPSIS
!  *	string_ty *sub_basename(wlist *arg);
!  *
!  * DESCRIPTION
!  *	The sub_basename function implements the basename substitution.
!  *	The basename substitution is replaced by the basename of
!  *	the argument path, similar to the basename(1) command.
!  *
!  * ARGUMENTS
!  *	arg	- list of arguments, including the function name as [0]
!  *
!  * RETURNS
!  *	a pointer to a string in dynamic memory;
!  *	or NULL on error, setting suberr appropriately.
!  */
! 
! static string_ty *sub_basename _((wlist *));
! 
! static string_ty *
! sub_basename(arg)
! 	wlist		*arg;
! {
! 	string_ty	*result;
! 	string_ty	*suffix;
! 	string_ty	*s;
! 	long		len;
! 
! 	trace(("sub_basename()\n{\n"/*}*/));
! 	switch (arg->wl_nwords)
! 	{
! 	default:
! 		suberr = "requires one or two arguments";
! 		result = 0;
! 		break;
! 	
! 	case 2:
! 		change_become(cp);
! 		result = os_entryname(arg->wl_word[1]);
! 		change_become_undo();
! 		break;
! 	
! 	case 3:
! 		change_become(cp);
! 		s = os_entryname(arg->wl_word[1]);
! 		change_become_undo();
! 		suffix = arg->wl_word[2];
! 		len = s->str_length - suffix->str_length;
! 		if
! 		(
! 			len > 0
! 		&&
! 			!memcmp
! 			(
! 				s->str_text + len,
! 				suffix->str_text,
! 				suffix->str_length
! 			)
! 		)
  		{
! 			result = str_n_from_c(s->str_text, len);
! 			str_free(s);
  		}
+ 		else
+ 			result = s;
+ 		break;
+ 	}
+ 	trace(("return \"%s\";\n", result ? result->str_text : suberr));
+ 	trace((/*{*/"}\n"));
+ 	return result;
+ }
  
+ 
+ /*
+  * NAME
+  *	sub_change - the change substitution
+  *
+  * SYNOPSIS
+  *	string_ty *sub_change(wlist *arg);
+  *
+  * DESCRIPTION
+  *	The sub_change function implements the change substitution.
+  *	The change substitution is replaced by the change number.
+  *
+  * ARGUMENTS
+  *	arg	- list of arguments, including the function name as [0]
+  *
+  * RETURNS
+  *	a pointer to a string in dynamic memory;
+  *	or NULL on error, setting suberr appropriately.
+  */
+ 
+ static string_ty *sub_change _((wlist *));
+ 
+ static string_ty *
+ sub_change(arg)
+ 	wlist		*arg;
+ {
+ 	string_ty	*result;
+ 
+ 	trace(("sub_change()\n{\n"/*}*/));
+ 	if (arg->wl_nwords != 1)
+ 	{
+ 		suberr = "requires zero arguments";
+ 		result = 0;
+ 	}
+ 	else
+ 		result = str_format("%ld", cp->number);
+ 	trace(("return \"%s\";\n", result ? result->str_text : suberr));
+ 	trace((/*{*/"}\n"));
+ 	return result;
+ }
+ 
+ 
+ /*
+  * NAME
+  *	sub_date - the date substitution
+  *
+  * SYNOPSIS
+  *	string_ty *sub_date(wlist *arg);
+  *
+  * DESCRIPTION
+  *	The sub_date function implements the date substitution.
+  *	The date substitution is replaced by the current date.
+  *	The optional arguments may construct format string,
+  *	similar to the date(1) command.
+  *
+  * ARGUMENTS
+  *	arg	- list of arguments, including the function name as [0]
+  *
+  * RETURNS
+  *	a pointer to a string in dynamic memory;
+  *	or NULL on error, setting suberr appropriately.
+  */
+ 
+ static string_ty *sub_date _((wlist *));
+ 
+ static string_ty *
+ sub_date(arg)
+ 	wlist		*arg;
+ {
+ 	string_ty	*result;
+ 	time_t		now;
+ 
+ 	trace(("sub_date()\n{\n"/*}*/));
+ 	assert(cp);
+ 	time(&now);
+ 	if (arg->wl_nwords < 2)
+ 	{
+ 		char	*cp;
+ 
+ 		cp = ctime(&now);
+ 		result = str_n_from_c(cp, 24);
+ 	}
+ 	else
+ 	{
+ 		struct tm	*tm;
+ 		char		buf[1000];
+ 		size_t		nbytes;
+ 		string_ty	*fmt;
+ 		extern size_t strftime _((char *, size_t, char *, struct tm *));
+ 
+ 		fmt = wl2str(arg, 1, 32767);
+ 		tm = localtime(&now);
+ 		nbytes = strftime(buf, sizeof(buf) - 1, fmt->str_text, tm);
+ 		if (!nbytes && fmt->str_length)
+ 		{
+ 			suberr = "strftime output too large";
+ 			result = 0;
+ 		}
+ 		else
+ 			result = str_n_from_c(buf, nbytes);
+ 		str_free(fmt);
+ 	}
+ 	trace(("return \"%s\";\n", result ? result->str_text : suberr));
+ 	trace((/*{*/"}\n"));
+ 	return result;
+ }
+ 
+ 
+ /*
+  * NAME
+  *	sub_delta - the delta substitution
+  *
+  * SYNOPSIS
+  *	string_ty *sub_delta(wlist *arg);
+  *
+  * DESCRIPTION
+  *	The sub_delta function implements the delta substitution.
+  *	The delta substitution is replaced by the delta number of the project.
+  *
+  * ARGUMENTS
+  *	arg	- list of arguments, including the function name as [0]
+  *
+  * RETURNS
+  *	a pointer to a string in dynamic memory;
+  *	or NULL on error, setting suberr appropriately.
+  */
+ 
+ static string_ty *sub_delta _((wlist *));
+ 
+ static string_ty *
+ sub_delta(arg)
+ 	wlist		*arg;
+ {
+ 	string_ty	*result;
+ 	cstate		cstate_data;
+ 
+ 	trace(("sub_delta()\n{\n"/*}*/));
+ 	assert(cp);
+ 	cstate_data = change_cstate_get(cp);
+ 	if (arg->wl_nwords != 1)
+ 	{
+ 		suberr = "requires zero arguments";
+ 		result = 0;
+ 	}
+ 	else if (cstate_data->state != cstate_state_being_integrated)
+ 	{
+ 		suberr = "not meaningful in current state";
+ 		result = 0;
+ 	}
+ 	else
+ 		result = str_format("%ld", cstate_data->delta_number);
+ 	trace(("return \"%s\";\n", result ? result->str_text : suberr));
+ 	trace((/*{*/"}\n"));
+ 	return result;
+ }
+ 
+ 
+ /*
+  * NAME
+  *	sub_developer - the developer substitution
+  *
+  * SYNOPSIS
+  *	string_ty *sub_developer(wlist *arg);
+  *
+  * DESCRIPTION
+  *	The sub_developer function implements the developer substitution.
+  *	The developer substitution is replaced by the name of the developer
+  *	of the project.
+  *
+  * ARGUMENTS
+  *	arg	- list of arguments, including the function name as [0]
+  *
+  * RETURNS
+  *	a pointer to a string in dynamic memory;
+  *	or NULL on error, setting suberr appropriately.
+  */
+ 
+ static string_ty *sub_developer _((wlist *arg));
+ 
+ static string_ty *
+ sub_developer(arg)
+ 	wlist		*arg;
+ {
+ 	string_ty	*result;
+ 	string_ty	*s;
+ 
+ 	trace(("sub_developer()\n{\n"/*}*/));
+ 	assert(cp);
+ 	if (arg->wl_nwords != 1)
+ 	{
+ 		suberr = "requires zero arguments";
+ 		result = 0;
+ 	}
+ 	else
+ 	{
+ 		s = change_developer_name(cp);
+ 		if (!s)
+ 		{
+ 			suberr = "not meaningful in current state";
+ 			result = 0;
+ 		}
+ 		else
+ 			result = str_copy(s);
+ 	}
+ 	trace(("return \"%s\";\n", result ? result->str_text : suberr));
+ 	trace((/*{*/"}\n"));
+ 	return result;
+ }
+ 
+ 
+ /*
+  * NAME
+  *	sub_developer_list - the developer_list substitution
+  *
+  * SYNOPSIS
+  *	string_ty *sub_developer_list(wlist *arg);
+  *
+  * DESCRIPTION
+  *	The sub_developer_list function implements the developer_list substitution.
+  *	The developer_list substitution is replaced by a space separated list
+  *	of the project's developers.
+  *
+  * ARGUMENTS
+  *	arg	- list of arguments, including the function name as [0]
+  *
+  * RETURNS
+  *	a pointer to a string in dynamic memory;
+  *	or NULL on error, setting suberr appropriately.
+  */
+ 
+ static string_ty *sub_developer_list _((wlist *));
+ 
+ static string_ty *
+ sub_developer_list(arg)
+ 	wlist		*arg;
+ {
+ 	string_ty	*result;
+ 	pstate		pstate_data;
+ 	long		j;
+ 
+ 	trace(("sub_developer_list()\n{\n"/*}*/));
+ 	if (arg->wl_nwords != 1)
+ 	{
+ 		suberr = "requires zero arguments";
+ 		result = 0;
+ 	}
+ 	else
+ 	{
  		/*
! 		 * build a string containing all of the project developers
  		 */
! 		assert(pp);
! 		pstate_data = project_pstate_get(pp);
! 		assert(pstate_data->developer);
! 		switch (pstate_data->developer->length)
! 		{
! 		case 0:
! 			result = str_from_c("");
! 			break;
! 	
! 		case 1:
! 			result = str_copy(pstate_data->developer->list[0]);
! 			break;
! 	
! 		default:
! 			assert(pstate_data->developer->length >= 2);
! 			result = str_copy(pstate_data->developer->list[0]);
! 			for (j = 1; j < pstate_data->developer->length; ++j)
! 			{
! 				string_ty	*s;
! 	
! 				s =
! 					str_format
! 					(
! 						"%S %S",
! 						result,
! 						pstate_data->developer->list[j]
! 					);
! 				str_free(result);
! 				result = s;
! 			}
! 			break;
! 		}
! 	}
! 	trace(("return \"%s\";\n", result ? result->str_text : suberr));
! 	trace((/*{*/"}\n"));
! 	return result;
! }
  
+ 
+ /*
+  * NAME
+  *	sub_development_directory - the development_directory substitution
+  *
+  * SYNOPSIS
+  *	string_ty *sub_development_directory(wlist *arg);
+  *
+  * DESCRIPTION
+  *	The sub_development_directory function implements the development_directory substitution.
+  *	The development_directory substitution is used to insert the absolute path
+  *	of the development_directory.
+  *
+  * ARGUMENTS
+  *	arg	- list of arguments, including the function name as [0]
+  *
+  * RETURNS
+  *	a pointer to a string in dynamic memory;
+  *	or NULL on error, setting suberr appropriately.
+  */
+ 
+ static string_ty *sub_development_directory _((wlist *));
+ 
+ static string_ty *
+ sub_development_directory(arg)
+ 	wlist		*arg;
+ {
+ 	string_ty	*result;
+ 	cstate		cstate_data;
+ 
+ 	trace(("sub_development_directory()\n{\n"/*}*/));
+ 	assert(cp);
+ 	cstate_data = change_cstate_get(cp);
+ 	if (arg->wl_nwords != 1)
+ 	{
+ 		suberr = "requires zero arguments";
+ 		result = 0;
+ 	}
+ 	else if
+ 	(
+ 		cstate_data->state < cstate_state_being_developed
+ 	||
+ 		cstate_data->state > cstate_state_being_integrated
+ 	)
+ 	{
+ 		suberr = "not meaningful in current state";
+ 		result = 0;
+ 	}
+ 	else
+ 		result = str_copy(change_development_directory_get(cp, 0));
+ 	trace(("return \"%s\";\n", result ? result->str_text : suberr));
+ 	trace((/*{*/"}\n"));
+ 	return result;
+ }
+ 
+ 
+ /*
+  * NAME
+  *	sub_dirname - the dirname substitution
+  *
+  * SYNOPSIS
+  *	string_ty *sub_dirname(wlist *arg);
+  *
+  * DESCRIPTION
+  *	The sub_dirname function implements the dirname substitution.
+  *	The dirname substitution is replaced by the dirname of
+  *	the argument path, similar to the dirname(1) command.
+  *
+  * ARGUMENTS
+  *	arg	- list of arguments, including the function name as [0]
+  *
+  * RETURNS
+  *	a pointer to a string in dynamic memory;
+  *	or NULL on error, setting suberr appropriately.
+  */
+ 
+ static string_ty *sub_dirname _((wlist *));
+ 
+ static string_ty *
+ sub_dirname(arg)
+ 	wlist		*arg;
+ {
+ 	string_ty	*result;
+ 
+ 	trace(("sub_dirname()\n{\n"/*}*/));
+ 	if (arg->wl_nwords != 2)
+ 	{
+ 		suberr = "requires one argument";
+ 		result = 0;
+ 	}
+ 	else
+ 	{
+ 		change_become(cp);
+ 		result = os_dirname(arg->wl_word[1]);
+ 		change_become_undo();
+ 	}
+ 	trace(("return \"%s\";\n", result ? result->str_text : suberr));
+ 	trace((/*{*/"}\n"));
+ 	return result;
+ }
+ 
+ 
+ /*
+  * NAME
+  *	sub_downcase - the downcase substitution
+  *
+  * SYNOPSIS
+  *	string_ty *sub_downcase(wlist *arg);
+  *
+  * DESCRIPTION
+  *	The sub_downcase function implements the downcase substitution.
+  *	The downcase substitution is replaced by the single argument
+  *	mapped to lower case.
+  *
+  *	Requires exactly one argument.
+  *
+  * ARGUMENTS
+  *	arg	- list of arguments, including the function name as [0]
+  *
+  * RETURNS
+  *	a pointer to a string in dynamic memory;
+  *	or NULL on error, setting suberr appropriately.
+  */
+ 
+ static string_ty *sub_downcase _((wlist *arg));
+ 
+ static string_ty *
+ sub_downcase(arg)
+ 	wlist		*arg;
+ {
+ 	string_ty	*result;
+ 
+ 	trace(("sub_downcase()\n{\n"/*}*/));
+ 	if (arg->wl_nwords != 2)
+ 	{
+ 		suberr = "requires one argument";
+ 		result = 0;
+ 	}
+ 	else
+ 		result = str_downcase(arg->wl_word[1]);
+ 	trace(("return \"%s\";\n", result ? result->str_text : suberr));
+ 	trace((/*{*/"}\n"));
+ 	return result;
+ }
+ 
+ 
+ /*
+  * NAME
+  *	sub_identifier - the identifier substitution
+  *
+  * SYNOPSIS
+  *	string_ty *sub_identifier(wlist *arg);
+  *
+  * DESCRIPTION
+  *	The sub_identifier function implements the identifier substitution.
+  *	The identifier substitution is replaced by the single argument
+  *	mapped to a C identifier.  All characters which are not legal in
+  *	a C identifier are replaced by an underscore.
+  *
+  *	Requires exactly one argument.
+  *
+  * ARGUMENTS
+  *	arg	- list of arguments, including the function name as [0]
+  *
+  * RETURNS
+  *	a pointer to a string in dynamic memory;
+  *	or NULL on error, setting suberr appropriately.
+  */
+ 
+ static string_ty *sub_identifier _((wlist *arg));
+ 
+ static string_ty *
+ sub_identifier(arg)
+ 	wlist		*arg;
+ {
+ 	string_ty	*result;
+ 
+ 	trace(("sub_identifier()\n{\n"/*}*/));
+ 	if (arg->wl_nwords != 2)
+ 	{
+ 		suberr = "requires one argument";
+ 		result = 0;
+ 	}
+ 	else if (arg->wl_word[1]->str_length == 0)
+ 		result = str_from_c("_");
+ 	else
+ 	{
+ 		string_ty	*s;
+ 		size_t		len;
+ 		char		*tmp;
+ 		char		*cp1;
+ 		char		*cp2;
+ 
+ 		s = arg->wl_word[1];
+ 		len = s->str_length;
+ 		tmp = mem_alloc(len);
+ 		for
+ 		(
+ 			cp1 = s->str_text, cp2 = tmp;
+ 			cp1 < s->str_text + len;
+ 			++cp1, ++cp2
+ 		)
+ 		{
+ 			if (isalnum(*cp1))
+ 				*cp2 = *cp1;
+ 			else
+ 				*cp2 = '_';
+ 		}
+ 		if (isdigit(tmp[0]))
+ 			tmp[0] = '_';
+ 		result = str_n_from_c(tmp, len);
+ 		mem_free(tmp);
+ 	}
+ 	trace(("return \"%s\";\n", result ? result->str_text : suberr));
+ 	trace((/*{*/"}\n"));
+ 	return result;
+ }
+ 
+ 
+ /*
+  * NAME
+  *	sub_integration_directory - the integration_directory substitution
+  *
+  * SYNOPSIS
+  *	string_ty *sub_integration_directory(wlist *arg);
+  *
+  * DESCRIPTION
+  *	The sub_integration_directory function implements the integration_directory substitution.
+  *	The integration_directory substitution is used to insert the absolute path
+  *	of the integration_directory.
+  *
+  * ARGUMENTS
+  *	arg	- list of arguments, including the function name as [0]
+  *
+  * RETURNS
+  *	a pointer to a string in dynamic memory;
+  *	or NULL on error, setting suberr appropriately.
+  */
+ 
+ static string_ty *sub_integration_directory _((wlist *));
+ 
+ static string_ty *
+ sub_integration_directory(arg)
+ 	wlist		*arg;
+ {
+ 	string_ty	*result;
+ 	cstate		cstate_data;
+ 
+ 	trace(("sub_integration_directory()\n{\n"/*}*/));
+ 	assert(cp);
+ 	cstate_data = change_cstate_get(cp);
+ 	if (arg->wl_nwords != 1)
+ 	{
+ 		suberr = "requires zero arguments";
+ 		result = 0;
+ 	}
+ 	else if (cstate_data->state != cstate_state_being_integrated)
+ 	{
+ 		suberr = "not meaningful in current state";
+ 		result = 0;
+ 	}
+ 	else
+ 		result = str_copy(change_integration_directory_get(cp, 0));
+ 	trace(("return \"%s\";\n", result ? result->str_text : suberr));
+ 	trace((/*{*/"}\n"));
+ 	return result;
+ }
+ 
+ 
+ /*
+  * NAME
+  *	sub_integrator - the integrator substitution
+  *
+  * SYNOPSIS
+  *	string_ty *sub_integrator(wlist *arg);
+  *
+  * DESCRIPTION
+  *	The sub_integrator function implements the integrator substitution.
+  *	The integrator substitution is replaced by the name of the integrator
+  *	of the project.
+  *
+  * ARGUMENTS
+  *	arg	- list of arguments, including the function name as [0]
+  *
+  * RETURNS
+  *	a pointer to a string in dynamic memory;
+  *	or NULL on error, setting suberr appropriately.
+  */
+ 
+ static string_ty *sub_integrator _((wlist *arg));
+ 
+ static string_ty *
+ sub_integrator(arg)
+ 	wlist		*arg;
+ {
+ 	string_ty	*result;
+ 	string_ty	*s;
+ 
+ 	trace(("sub_integrator()\n{\n"/*}*/));
+ 	assert(cp);
+ 	if (arg->wl_nwords != 1)
+ 	{
+ 		suberr = "requires zero arguments";
+ 		result = 0;
+ 	}
+ 	else
+ 	{
+ 		s = change_integrator_name(cp);
+ 		if (!s)
+ 		{
+ 			suberr = "not meaningful in current state";
+ 			result = 0;
+ 		}
+ 		else
+ 			result = str_copy(s);
+ 	}
+ 	trace(("return \"%s\";\n", result ? result->str_text : suberr));
+ 	trace((/*{*/"}\n"));
+ 	return result;
+ }
+ 
+ 
+ /*
+  * NAME
+  *	sub_integrator_list - the integrator_list substitution
+  *
+  * SYNOPSIS
+  *	string_ty *sub_integrator_list(wlist *arg);
+  *
+  * DESCRIPTION
+  *	The sub_integrator_list function implements the integrator_list substitution.
+  *	The integrator_list substitution is replaced by a space separated list
+  *	of the project's integrators.
+  *
+  * ARGUMENTS
+  *	arg	- list of arguments, including the function name as [0]
+  *
+  * RETURNS
+  *	a pointer to a string in dynamic memory;
+  *	or NULL on error, setting suberr appropriately.
+  */
+ 
+ static string_ty *sub_integrator_list _((wlist *));
+ 
+ static string_ty *
+ sub_integrator_list(arg)
+ 	wlist		*arg;
+ {
+ 	string_ty	*result;
+ 	pstate		pstate_data;
+ 	long		j;
+ 
+ 	trace(("sub_integrator_list()\n{\n"/*}*/));
+ 	if (arg->wl_nwords != 1)
+ 	{
+ 		suberr = "requires zero arguments";
+ 		result = 0;
+ 	}
+ 	else
+ 	{
  		/*
! 		 * build a string containing all of the project integrators
  		 */
! 		assert(pp);
! 		pstate_data = project_pstate_get(pp);
! 		assert(pstate_data->integrator);
! 		switch (pstate_data->integrator->length)
  		{
! 		case 0:
! 			result = str_from_c("");
! 			break;
! 	
! 		case 1:
! 			result = str_copy(pstate_data->integrator->list[0]);
! 			break;
! 	
! 		default:
! 			assert(pstate_data->integrator->length >= 2);
! 			result = str_copy(pstate_data->integrator->list[0]);
! 			for (j = 1; j < pstate_data->integrator->length; ++j)
! 			{
! 				string_ty	*s;
! 	
! 				s =
! 					str_format
! 					(
! 						"%S %S",
! 						result,
! 						pstate_data->integrator->list[j]
! 					);
! 				str_free(result);
! 				result = s;
! 			}
! 			break;
  		}
! 	}
! 	trace(("return \"%s\";\n", result ? result->str_text : suberr));
! 	trace((/*{*/"}\n"));
! 	return result;
! }
! 
! 
! /*
!  * NAME
!  *	sub_project - the project substitution
!  *
!  * SYNOPSIS
!  *	string_ty *sub_project(wlist *arg);
!  *
!  * DESCRIPTION
!  *	The sub_project function implements the project substitution.
!  *	The project substitution is replaced by the project name.
!  *
!  * ARGUMENTS
!  *	arg	- list of arguments, including the function name as [0]
!  *
!  * RETURNS
!  *	a pointer to a string in dynamic memory;
!  *	or NULL on error, setting suberr appropriately.
!  */
! 
! static string_ty *sub_project _((wlist *));
! 
! static string_ty *
! sub_project(arg)
! 	wlist		*arg;
! {
! 	string_ty	*result;
! 
! 	trace(("sub_project()\n{\n"/*}*/));
! 	if (arg->wl_nwords != 1)
! 	{
! 		suberr = "requires zero arguments";
! 		result = 0;
! 	}
! 	else
! 		result = str_copy(project_name_get(pp));
! 	trace(("return \"%s\";\n", result ? result->str_text : suberr));
! 	trace((/*{*/"}\n"));
! 	return result;
! }
! 
! 
! /*
!  * NAME
!  *	sub_reviewer - the reviewer substitution
!  *
!  * SYNOPSIS
!  *	string_ty *sub_reviewer(wlist *arg);
!  *
!  * DESCRIPTION
!  *	The sub_reviewer function implements the reviewer substitution.
!  *	The reviewer substitution is replaced by the name of the reviewer
!  *	of the project.
!  *
!  * ARGUMENTS
!  *	arg	- list of arguments, including the function name as [0]
!  *
!  * RETURNS
!  *	a pointer to a string in dynamic memory;
!  *	or NULL on error, setting suberr appropriately.
!  */
! 
! static string_ty *sub_reviewer _((wlist *arg));
! 
! static string_ty *
! sub_reviewer(arg)
! 	wlist		*arg;
! {
! 	string_ty	*result;
! 	string_ty	*s;
! 
! 	trace(("sub_reviewer()\n{\n"/*}*/));
! 	assert(cp);
! 	if (arg->wl_nwords != 1)
! 	{
! 		suberr = "requires zero arguments";
! 		result = 0;
! 	}
! 	else
! 	{
! 		s = change_reviewer_name(cp);
! 		if (!s)
  		{
! 			suberr = "not meaningful in current state";
! 			result = 0;
  		}
! 		else
! 			result = str_copy(s);
! 	}
! 	trace(("return \"%s\";\n", result ? result->str_text : suberr));
! 	trace((/*{*/"}\n"));
! 	return result;
! }
! 
! 
! /*
!  * NAME
!  *	sub_reviewer_list - the reviewer_list substitution
!  *
!  * SYNOPSIS
!  *	string_ty *sub_reviewer_list(wlist *arg);
!  *
!  * DESCRIPTION
!  *	The sub_reviewer_list function implements the reviewer_list substitution.
!  *	The reviewer_list substitution is replaced by a space separated list
!  *	of the project's reviewers.
!  *
!  * ARGUMENTS
!  *	arg	- list of arguments, including the function name as [0]
!  *
!  * RETURNS
!  *	a pointer to a string in dynamic memory;
!  *	or NULL on error, setting suberr appropriately.
!  */
! 
! static string_ty *sub_reviewer_list _((wlist *));
! 
! static string_ty *
! sub_reviewer_list(arg)
! 	wlist		*arg;
! {
! 	string_ty	*result;
! 	pstate		pstate_data;
! 	long		j;
! 
! 	trace(("sub_reviewer_list()\n{\n"/*}*/));
! 	if (arg->wl_nwords != 1)
! 	{
! 		suberr = "requires zero arguments";
! 		result = 0;
! 	}
! 	else
! 	{
! 		/*
! 		 * build a string containing all of the project reviewers
! 		 */
! 		assert(pp);
! 		pstate_data = project_pstate_get(pp);
! 		assert(pstate_data->reviewer);
! 		switch (pstate_data->reviewer->length)
  		{
! 		case 0:
! 			result = str_from_c("");
! 			break;
! 	
! 		case 1:
! 			result = str_copy(pstate_data->reviewer->list[0]);
! 			break;
! 	
! 		default:
! 			assert(pstate_data->reviewer->length >= 2);
! 			result = str_copy(pstate_data->reviewer->list[0]);
! 			for (j = 1; j < pstate_data->reviewer->length; ++j)
! 			{
! 				string_ty	*s;
! 	
! 				s =
! 					str_format
! 					(
! 						"%S %S",
! 						result,
! 						pstate_data->reviewer->list[j]
! 					);
! 				str_free(result);
! 				result = s;
! 			}
! 			break;
  		}
+ 	}
+ 	trace(("return \"%s\";\n", result ? result->str_text : suberr));
+ 	trace((/*{*/"}\n"));
+ 	return result;
+ }
  
+ 
+ /*
+  * NAME
+  *	sub_source - the source substitution
+  *
+  * SYNOPSIS
+  *	string_ty *sub_source(wlist *arg);
+  *
+  * DESCRIPTION
+  *	The sub_source function implements the source substitution.
+  *	The source substitution is replaced by the path of the source file,
+  *	depending on wether it is in the baseline or the change.
+  *	If the file named in the argument is in the change,
+  *	the name will be left unchanged,
+  *	but if the file is in the baseline, an absolute path will resiult.
+  *	If the change is being integrated, it will always be left untouched.
+  *
+  *	Requires exactly one argument.
+  *
+  * ARGUMENTS
+  *	arg	- list of arguments, including the function name as [0]
+  *
+  * RETURNS
+  *	a pointer to a string in dynamic memory;
+  *	or NULL on error, setting suberr appropriately.
+  */
+ 
+ static string_ty *sub_source _((wlist *arg));
+ 
+ static string_ty *
+ sub_source(arg)
+ 	wlist		*arg;
+ {
+ 	string_ty	*result;
+ 	cstate		cstate_data;
+ 
+ 	trace(("sub_source()\n{\n"/*}*/));
+ 	cstate_data = change_cstate_get(cp);
+ 	if (arg->wl_nwords != 2)
+ 	{
+ 		suberr = "requires one argument";
+ 		result = 0;
+ 	}
+ 	else if (cstate_data->state == cstate_state_awaiting_development)
+ 	{
+ 		suberr = "not meaningful in current state";
+ 		result = 0;
+ 	}
+ 	else
+ 	{
  		/*
! 		 * Make sure the named file exists
! 		 * either in the change or in the project.
  		 */
! 		if (!change_src_find(cp, arg->wl_word[1]))
! 		{
! 			if (project_src_find(cp->pp, arg->wl_word[1]))
! 			{
! 				/*
! 				 * if the project is is the 'being
! 				 * developed' state, need to qualify
! 				 * the file name with the baseline
! 				 * directory name.
! 				 *
! 				 * If the change is in the 'being
! 				 * integrated' state, don't do
! 				 * anything, as files in the
! 				 * project AND files in the change
! 				 * are below the current directory.
! 				 */
! 				if
! 				(
! 					cstate_data->state
! 				<
! 					cstate_state_being_integrated
! 				)
! 				{
! 					result =
! 						str_format
! 						(
! 							"%S/%S",
! 					project_baseline_path_get(cp->pp, 0),
! 							arg->wl_word[1]
! 						);
! 				}
! 				else
! 					result = str_copy(arg->wl_word[1]);
! 			}
! 			else
! 			{
! 				suberr = "source file unknown";
! 				result = 0;
! 			}
! 		}
! 		else
! 			result = str_copy(arg->wl_word[1]);
! 	}
! 	trace(("return \"%s\";\n", result ? result->str_text : suberr));
! 	trace((/*{*/"}\n"));
! 	return result;
! }
! 
! 
! /*
!  * NAME
!  *	sub_upcase - the upcase substitution
!  *
!  * SYNOPSIS
!  *	string_ty *sub_upcase(wlist *arg);
!  *
!  * DESCRIPTION
!  *	The sub_upcase function implements the upcase substitution.
!  *	The upcase substitution is replaced by the single argument
!  *	mapped to upper case.
!  *
!  *	Requires exactly one argument.
!  *
!  * ARGUMENTS
!  *	arg	- list of arguments, including the function name as [0]
!  *
!  * RETURNS
!  *	a pointer to a string in dynamic memory;
!  *	or NULL on error, setting suberr appropriately.
!  */
! 
! static string_ty *sub_upcase _((wlist *arg));
! 
! static string_ty *
! sub_upcase(arg)
! 	wlist		*arg;
! {
! 	string_ty	*result;
! 
! 	trace(("sub_upcase()\n{\n"/*}*/));
! 	if (arg->wl_nwords != 2)
! 	{
! 		suberr = "requires one argument";
! 		result = 0;
! 	}
! 	else
! 		result = str_upcase(arg->wl_word[1]);
! 	trace(("return \"%s\";\n", result ? result->str_text : suberr));
! 	trace((/*{*/"}\n"));
! 	return result;
! }
! 
! 
! /*
!  * NAME
!  *	sub_version - the version substitution
!  *
!  * SYNOPSIS
!  *	string_ty *sub_version(wlist *arg);
!  *
!  * DESCRIPTION
!  *	The sub_version function implements the version substitution.
!  *	The version substitution is replaced by the version of the chnage.
!  *
!  *	If the change is not in the being_integrated or completed states,
!  *	the version will be major.minor.Cnumber, where
!  *	"major" is the project major version number,
!  *	"minor" is the project minor version number, and
!  *	"change" is a 3 digit change number, possibly zero padded.
!  *
!  *	If the change is in the being_integrated or completed state,
!  *	the version will be major.minor.Cdelta, where
!  *	"delta" is a 3 digit delta number, possibly zero padded.
!  *
!  * ARGUMENTS
!  *	arg	- list of arguments, including the function name as [0]
!  *
!  * RETURNS
!  *	a pointer to a string in dynamic memory;
!  *	or NULL on error, setting suberr appropriately.
!  */
! 
! static string_ty *sub_version _((wlist *arg));
! 
! static string_ty *
! sub_version(arg)
! 	wlist		*arg;
! {
! 	string_ty	*result;
! 	pstate		pstate_data;
! 	cstate		cstate_data;
! 
! 	trace(("sub_version()\n{\n"/*}*/));
! 	assert(cp);
! 	if (arg->wl_nwords != 1)
! 	{
! 		suberr = "requires zero arguments";
! 		result = 0;
! 	}
! 	else
! 	{
! 		pstate_data = project_pstate_get(pp);
! 		cstate_data = change_cstate_get(cp);
! 		if (cstate_data->state < cstate_state_being_integrated)
  		{
! 			result =
! 				str_format
! 				(
! 					"%ld.%ld.C%3.3ld",
! 					pstate_data->version_major,
! 					pstate_data->version_minor,
! 					cp->number
! 				);
! 		}
! 		else
! 		{
! 			result =
! 				str_format
! 				(
! 					"%ld.%ld.D%3.3ld",
! 					pstate_data->version_major,
! 					pstate_data->version_minor,
! 					cstate_data->delta_number
! 				);
! 		}
! 	}
! 	trace(("return \"%s\";\n", result ? result->str_text : suberr));
! 	trace((/*{*/"}\n"));
! 	return result;
! }
  
! 
! static table_ty	table[] =
! {
! 	{ "Administrator_List",		sub_administrator_list,		},
! 	{ "BaseLine",			sub_baseline,			},
! 	{ "Basename",			sub_basename,			},
! 	{ "Change",			sub_change,			},
! 	{ "DAte",			sub_date,			},
! 	{ "DELta",			sub_delta,			},
! 	{ "DEVeloper",			sub_developer,			},
! 	{ "DEVeloper_List",		sub_developer_list,		},
! 	{ "Development_Directory",	sub_development_directory,	},
! 	{ "Dirname",			sub_dirname,			},
! 	{ "DownCase",			sub_downcase,			},
! 	/* Edit								*/
! 	/* File_Name							*/
! 	/* History							*/
! 	/* Input							*/
! 	{ "IDentifier",			sub_identifier,			},
! 	{ "INTegration_Directory",	sub_integration_directory,	},
! 	{ "INTegrator",			sub_integrator,			},
! 	{ "INTegrator_List",		sub_integrator_list,		},
! 	/* Most_Recent							*/
! 	/* Output							*/
! 	/* ORiginal							*/
! 	{ "Project",			sub_project,			},
! 	{ "Reviewer",			sub_reviewer,			},
! 	{ "Reviewer_List",		sub_reviewer_list,		},
! 	{ "Source",			sub_source,			},
! 	{ "UpCase",			sub_upcase,			},
! 	{ "Version",			sub_version,			},
! };
! 
! 
! /*
!  * NAME
!  *	sub_diversion
!  *
!  * SYNOPSIS
!  *	void sub_diversion(string_ty *s);
!  *
!  * DESCRIPTION
!  *	The sub_diversion function is used to divert input
!  *	to a string, until that string is exhausted.
!  *	When the string is exhausted, input will resume
!  *	from the previous string.
!  *
!  * ARGUMENTS
!  *	s - string to take as input
!  */
! 
! static void sub_diversion _((string_ty *));
! 
! static void
! sub_diversion(s)
! 	string_ty	*s;
! {
! 	diversion_ty	*dp;
! 
! 	trace(("sub_diversion(\"%s\")\n{\n"/*}*/, s->str_text));
! 	dp = (diversion_ty *)mem_alloc(sizeof(diversion_ty));
! 	dp->text = str_copy(s);
! 	dp->pos = 0;
! 	dp->prev = diversion;
! 	diversion = dp;
! 	trace((/*{*/"}\n"));
! }
! 
! 
! /*
!  * NAME
!  *	sub_diversion_close
!  *
!  * SYNOPSIS
!  *	void sub_diversion_close(void);
!  *
!  * DESCRIPTION
!  *	The sub_diversion_close function is used to
!  *	release a diversion when it has been exhausted.
!  */
! 
! static void sub_diversion_close _((void));
! 
! static void
! sub_diversion_close()
! {
! 	diversion_ty	*dp;
! 
! 	trace(("sub_diversion_close()\n{\n"/*}*/));
! 	assert(diversion);
! 	dp = diversion;
! 	diversion = dp->prev;
! 	assert(dp->pos == dp->text->str_length);
! 	str_free(dp->text);
! 	mem_free((char *)dp);
! 	trace((/*{*/"}\n"));
! }
! 
! 
! /*
!  * NAME
!  *	execute
!  *
!  * SYNOPSIS
!  *	void execute(wlist *args);
!  *
!  * DESCRIPTION
!  *	The execute function is used to perform the substitution
!  *	described by the argument list.
!  *
!  * ARGUMENTS
!  *	args - the name and arguments of the substitution
!  */
! 
! static void execute _((wlist *));
! 
! static void
! execute(arg)
! 	wlist		*arg;
! {
! 	char		*cmd;
! 	string_ty	*s;
! 	table_ty	*hit[20];
! 	int		nhits;
! 	table_ty	*tp;
! 	long		j;
! 
! 	trace(("execute()\n{\n"/*}*/));
! 	if (arg->wl_nwords == 0)
! 		fatal("empty ${} substitution");
! 	
! 	/*
! 	 * scan the variables
! 	 */
! 	nhits = 0;
! 	cmd = arg->wl_word[0]->str_text;
! 	for (j = 0; j < sub_var_pos; ++j)
! 	{
! 		tp = &sub_var_list[j];
! 		if (arglex_compare(tp->name, cmd))
! 		{
! 			if (nhits < SIZEOF(hit))
! 				hit[nhits++] = tp;
! 		}
! 	}
! 
! 	/*
! 	 * scan the functions
! 	 */
! 	for (tp = table; tp < ENDOF(table); ++tp)
! 	{
! 		if (arglex_compare(tp->name, cmd))
! 		{
! 			if (nhits < SIZEOF(hit))
! 				hit[nhits++] = tp;
! 		}
! 	}
! 
! 	/*
! 	 * figure what to do
! 	 */
! 	switch (nhits)
! 	{
! 	case 0:
! 		suberr = "unknown substitution name";
! 		s = 0;
! 		break;
! 
! 	case 1:
! 		tp = hit[0];
! 		if (tp->value)
! 		{
! 			s = str_copy(tp->value);
! 			if (isdigit(tp->name[0]))
  			{
! 				error
  				(
!        "warning: the %%%s substitution has been replaced by %s in this context",
! 					tp->name,
! 					s->str_text
  				);
  			}
! 			trace(("%s -> %s\n", tp->name, s->str_text));
! 		}
! 		else
! 		{
! 			str_free(arg->wl_word[0]);
! 			arg->wl_word[0] = str_from_c(tp->name);
! 			s = tp->func(arg);
! 		}
! 		break;
! 
! 	default:
! 		suberr = "ambiguous substitution name";
! 		s = 0;
! 		break;
! 	}
! 
! 	/*
! 	 * deal with the result
! 	 */
! 	if (s)
! 	{
! 		sub_diversion(s);
! 		str_free(s);
! 	}
! 	else
! 	{
! 		string_ty	*s2;
! 
! 		s2 = wl2str(arg, 0, 32767);
! 		fatal
! 		(
! 			"substitution ${%s} failed: %s",
! 			s2->str_text,
! 			suberr
! 		);
! 		str_free(s2);
! 	}
! 	trace((/*{*/"}\n"));
! }
! 
! 
! /*
!  * NAME
!  *	sub_getc_meta
!  *
!  * SYNOPSIS
!  *	void sub_getc_meta(void);
!  *
!  * DESCRIPTION
!  *	The sub_getc_meta function is used to get a character from
!  *	the current input string.  When the current string is exhaused,
!  *	the previous string is resumed.
!  *
!  * RETURNS
!  *	int - the chacater, or NUL to indicate end of input
!  */
! 
! static int sub_getc_meta _((void));
! 
! static int
! sub_getc_meta()
! {
! 	int		result;
! 	diversion_ty	*dp;
! 
! 	trace(("sub_getc_meta()\n{\n"/*}*/));
! 	dp = diversion;
! 	if (!dp)
! 		result = 0;
! 	else if (dp->pos >= dp->text->str_length)
! 		result = 0;
! 	else
! 		result = dp->text->str_text[dp->pos++];
! 	trace(("return '%c';\n", result ? result : 0x80));
! 	trace((/*{*/"}\n"));
! 	return result;
! }
! 
! 
! /*
!  * NAME
!  *	sub_getc_meta_undo
!  *
!  * SYNOPSIS
!  *	void sub_getc_meta_undo(int c);
!  *
!  * DESCRIPTION
!  *	The sub_getc_meta_undo function is used to give back
!  *	a character output by sub_getc_meta.
!  *
!  * ARGUMENTS
!  *	c - character being given back
!  *
!  * CAVEAT
!  *	Only push back what was read.
!  */
! 
! static void sub_getc_meta_undo _((int));
! 
! static void
! sub_getc_meta_undo(c)
! 	int		c;
! {
! 	diversion_ty	*dp;
! 
! 	trace(("sub_getc_meta_undo('%c')\n{\n"/*}*/, c ? c : 0x80));
! 	dp = diversion;
! 	assert(dp);
! 	if (!c)
! 	{
! 		assert(dp->pos == dp->text->str_length);
! 	}
! 	else
! 	{
! 		assert(dp->pos >= 1);
! 		dp->pos--;
! 		assert(c == dp->text->str_text[dp->pos]);
! 	}
! 	trace((/*{*/"}\n"));
! }
! 
! 
! /*
!  * NAME
!  *	collect
!  *
!  * SYNOPSIS
!  *	void collect(int c);
!  *
!  * DESCRIPTION
!  *	The collect function is used to accumulate a string
!  *	one character at a time.  No size limit.
!  *
!  * ARGUMENTS
!  *	c - the character being collected
!  */
! 
! static void collect _((int));
! 
! static void
! collect(c)
! 	int	c;
! {
! 	if (collect_pos >= collect_size)
! 	{
! 		collect_size += (1L << 10);
! 		if (!collect_buf)
! 			collect_buf = mem_alloc(collect_size);
! 		else
! 			mem_change_size(&collect_buf, collect_size);
! 	}
! 	collect_buf[collect_pos++] = c;
! }
! 
! 
! /*
!  * NAME
!  *	collect_end
!  *
!  * SYNOPSIS
!  *	string_ty *collect_end(void);
!  *
!  * DESCRIPTION
!  *	The collect_end function is used to fetch the string
!  *	accumulated with the collect function.
!  *	The bufferer for the collect function is cleared.
!  *
!  * RETURNS
!  *	string_ty *; pointer to the string in dynamic memory.
!  */
! 
! static string_ty *collect_end _((void));
! 
! static string_ty *
! collect_end()
! {
! 	string_ty	*result;
! 
! 	result = str_n_from_c(collect_buf, collect_pos);
! 	collect_pos = 0;
! 	return result;
! }
! 
! 
! /*
!  * NAME
!  *	percent
!  *
!  * SYNOPSIS
!  *	int percent(void);
!  *
!  * DESCRIPTION
!  *	The percent function is used to perform percent (%) substitutions.
!  *	On entry, the % is expected to have been consumed.
!  *
!  *	The substitution is usually achieved as a side-effect,
!  *	by using the sub_diversion function.
!  *
!  * RETURNS
!  *	int	a character to deliver as output,
!  *		or NUL if none.
!  */
! 
! static int percent _((void));
! 
! static int
! percent()
! {
! 	int		c;
! 	int		result;
! 	int		c2;
! 	string_ty	*s;
! 	static int	warned;
! 	string_ty	*s2;
! 
! 	trace(("percent()\n{\n"/*}*/));
! 	result = 0;
! 	c = sub_getc_meta();
! 	switch (c)
! 	{
! 	case 'P':
! 		c2 = sub_getc_meta();
! 		if (!isdigit(c2))
! 		{
! 			sub_getc_meta_undo(c2);
! 			sub_getc_meta_undo(c);
! 			result = '%';
  			break;
+ 		}
+ 		s = str_format("${dirname ${%c}}", c2);
+ 		sub_diversion(s);
+ 		str_free(s);
+ 		break;
  
! 	case 'F':
! 		c2 = sub_getc_meta();
! 		if (!isdigit(c2))
! 		{
! 			sub_getc_meta_undo(c2);
! 			sub_getc_meta_undo(c);
! 			result = '%';
! 			break;
! 		}
! 		s = str_format("${basename ${%c}}", c2);
! 		sub_diversion(s);
! 		str_free(s);
! 		break;
! 
! 	case '0': case '1': case '2': case '3': case '4':
! 	case '5': case '6': case '7': case '8': case '9':
! 		s = str_format("${%c}", c);
! 		sub_diversion(s);
! 		str_free(s);
! 		break;
! 
! 	case '('/*)*/:
! 		for (;;)
! 		{
! 			c = sub_getc_meta();
! 			if (!c)
! 				fatal("unterminated %%() substitution");
! 			if (c == /*(*/')')
! 				break;
! 			collect(c);
! 		}
! 		s2 = collect_end();
! 		s = str_format("${source %S}", s2);
! 		str_free(s2);
! 		sub_diversion(s);
! 		str_free(s);
! 		break;
! 
! 	default:
! 		sub_getc_meta_undo(c);
! 		result = '%';
! 		break;
! 	}
! 	if (!result && !warned)
! 	{
! 		error
! 		(
! "warning: the percent (%%) substitutions are obsolescent, \
! please use the equilavent dollar ($) substitution"
! 		);
! 		warned = 1;
! 	}
! 	trace(("return '%c'\n", result ? result : 0x80));
! 	trace((/*{*/"}\n"));
! 	return result;
! }
! 
! 
! /*
!  * NAME
!  *	dollar
!  *
!  * SYNOPSIS
!  *	void dollar(void);
!  *
!  * DESCRIPTION
!  *	The dollar function is used to perform dollar ($) substitutions.
!  *	On entry, the $ is expected to have been consumed.
!  *
!  *	The substitution is usually achieved as a side-effect,
!  *	by using the sub_diversion function.
!  *
!  * RETURNS
!  *	int	a character to deliver as output,
!  *		or NUL if none.
!  */
! 
! static int sub_getc _((void)); /* forward */
! 
! static int dollar _((void));
! 
! static int
! dollar()
! {
! 	wlist		arg;
! 	int		result;
! 	int		c;
! 	string_ty	*s;
! 
! 	trace(("dollar()\n{\n"/*}*/));
! 	wl_zero(&arg);
! 	result = 0;
! 	c = sub_getc_meta();
! 	switch (c)
! 	{
! 	case '0': case '1': case '2': case '3': case '4':
! 	case '5': case '6': case '7': case '8': case '9': 
! 		for (;;)
! 		{
! 			collect(c);
! 			c = sub_getc_meta();
! 			if (!isdigit(c))
! 			{
! 				sub_getc_meta_undo(c);
! 				break;
! 			}
! 		}
! 		s = collect_end();
! 		wl_append(&arg, s);
! 		str_free(s);
! 		execute(&arg);
! 		wl_free(&arg);
! 		break;
! 
! 	case 'a': case 'b': case 'c': case 'd': case 'e':
! 	case 'f': case 'g': case 'h': case 'i': case 'j':
! 	case 'k': case 'l': case 'm': case 'n': case 'o':
! 	case 'p': case 'q': case 'r': case 's': case 't':
! 	case 'u': case 'v': case 'w': case 'x': case 'y': case 'z': 
! 	case 'A': case 'B': case 'C': case 'D': case 'E':
! 	case 'F': case 'G': case 'H': case 'I': case 'J':
! 	case 'K': case 'L': case 'M': case 'N': case 'O':
! 	case 'P': case 'Q': case 'R': case 'S': case 'T':
! 	case 'U': case 'V': case 'W': case 'X': case 'Y': case 'Z': 
! 		for (;;)
! 		{
! 			collect(c);
! 			c = sub_getc_meta();
! 			if (!isalnum(c) && c != '_' && c != '-')
! 			{
! 				sub_getc_meta_undo(c);
! 				break;
! 			}
! 		}
! 		s = collect_end();
! 		wl_append(&arg, s);
! 		str_free(s);
! 		execute(&arg);
! 		wl_free(&arg);
! 		break;
! 
! 	case '{'/*}*/:
! 		c = sub_getc();
! 		for (;;)
! 		{
  			/*
! 			 * look for terminator
  			 */
! 			if (c == /*{*/'}')
! 				break;
! 
! 			/*
! 			 * watch out for unterminated substitutions
! 			 */
! 			if (!c)
  			{
! 				fatal("unterminated ${} substitution");
! 				break;
  			}
  
  			/*
! 			 * skip white space separating the arguments
  			 */
! 			if (isspace(c))
  			{
! 				c = sub_getc();
! 				continue;
  			}
+ 
+ 			/*
+ 			 * collect the argument
+ 			 *	any run of non-white-space characters
+ 			 */
+ 			for (;;)
+ 			{
+ 				collect(c);
+ 				c = sub_getc();
+ 				if (!c || isspace(c) || c == /*{*/'}')
+ 					break;
+ 			}
+ 			s = collect_end();
+ 			wl_append(&arg, s);
+ 			str_free(s);
+ 		}
+ 		execute(&arg);
+ 		wl_free(&arg);
+ 		break;
+ 
+ 	case '$':
+ 		result = '$';
+ 		break;
+ 
+ 	default:
+ 		sub_getc_meta_undo(c);
+ 		result = '$';
+ 		break;
+ 	}
+ 	trace(("return '%c';\n", result ? result : 0x80));
+ 	trace((/*{*/"}\n"));
+ 	return result;
+ }
+ 
+ 
+ /*
+  * NAME
+  *	sub_getc
+  *
+  * SYNOPSIS
+  *	int sub_getc(void);
+  *
+  * DESCRIPTION
+  *	The sub_getc function is used to get a character from
+  *	the substitution stream.  This is used both for the final output
+  *	and for fetching arguments to dollar ($) substitutions.
+  *
+  * RETURNS
+  *	int	a character from the stream,
+  *		or NUL to indicate end of input.
+  */
+ 
+ static int sub_getc _((void));
+ 
+ static int
+ sub_getc()
+ {
+ 	int	c;
+ 
+ 	trace(("sub_getc()\n{\n"/*}*/));
+ 	for (;;)
+ 	{
+ 		c = sub_getc_meta();
+ 		switch (c)
+ 		{
+ 		default:
  			break;
+ 
+ 		case 0:
+ 			if (!diversion)
+ 				break;
+ 			sub_diversion_close();
+ 			continue;
+ 
+ 		case '%':
+ 			c = percent();
+ 			if (!c)
+ 				continue;
+ 			break;
+ 
+ 		case '$':
+ 			c = dollar();
+ 			if (!c)
+ 				continue;
+ 			break;
  		}
+ 		break;
+ 	}
+ 	trace(("return '%c';\n", c ? c : 0x80));
+ 	trace((/*{*/"}\n"));
+ 	return c;
+ }
  
+ 
+ /*
+  * NAME
+  *	substitute
+  *
+  * SYNOPSIS
+  *	string_ty *substitute(change_ty *cp, string_ty *s);
+  *
+  * DESCRIPTION
+  *	The substitute function is used to perform substitutions on
+  *	strings.  Usually command strings, but not always.
+  *
+  *	The format of substitutions, and the commonly available
+  *	substitutions, are described in aesub(5).
+  *
+  * ARGUMENTS
+  *	cp	- the aegis change involved with the command
+  *		  This may never be NULL.
+  *	s	- the string to be substituted.
+  *
+  * RETURNS
+  *	string_ty *; pointer to string in dynamic memory
+  */
+ 
+ string_ty *
+ substitute(acp, s)
+ 	change_ty	*acp;
+ 	string_ty	*s;
+ {
+ 	static char	*buffer;
+ 	static size_t	buflen;
+ 	size_t		pos;
+ 	int		c;
+ 	string_ty	*result;
+ 
+ 	trace(("substitute(acp = %08lX, s = \"%s\")\n{\n"/*}*/,
+ 		(long)acp, s->str_text));
+ 	assert(acp);
+ 	cp = acp;
+ 	pp = acp->pp;
+ 
+ 	sub_diversion(s);
+ 	pos = 0;
+ 	if (!buffer)
+ 	{
+ 		buflen = (1L << 10);
+ 		buffer = mem_alloc(buflen);
+ 	}
+ 	for (;;)
+ 	{
  		/*
! 		 * get the next character
  		 */
! 		c = sub_getc();
! 		if (!c)
! 			break;
! 
! 		/*
! 		 * make sure there is room
! 		 */
! 		if (pos >= buflen)
  		{
! 			buflen += (1L << 10);
! 			mem_change_size(&buffer, buflen);
  		}
  
  		/*
! 		 * save the character
  		 */
! 		buffer[pos++] = c;
  	}
! 	sub_var_clear();
! 	cp = 0;
! 	pp = 0;
! 	result = str_n_from_c(buffer, pos);
! 	trace(("return \"%s\";\n", result->str_text));
  	trace((/*{*/"}\n"));
! 	return result;
! }
! 
! 
! /*
!  * NAME
!  *	sub_var_clear
!  *
!  * SYNOPSIS
!  *	void sub_var_clear(void);
!  *
!  * DESCRIPTION
!  *	The sub_var_clear function is used to clear all of
!  *	the substitution variables.  Not usually needed manually,
!  *	as this is done automatically at the end of every substitute().
!  */
! 
! void
! sub_var_clear()
! {
! 	size_t	j;
! 
! 	for (j = 0; j < sub_var_pos; ++j)
! 		str_free(sub_var_list[j].value);
! 	sub_var_pos = 0;
! }
! 
! 
! /*
!  * NAME
!  *	sub_var_set
!  *
!  * SYNOPSIS
!  *	void sub_var_set(char *name, char *fmt, ...);
!  *
!  * DESCRIPTION
!  *	The sub_var_set function is used to set the value of a
!  *	substitution variable.  These variables are command specific,
!  *	as opposed to the functions which are always present.
!  *	The user documentation does NOT make this distinction by
!  *	using the names "variable" and "function", they are always referred
!  *	to as "substitutions".
!  *
!  * ARGUMENTS
!  *	name	- the name of the variable
!  *	fmt,...	- a format string and arguments to construct the value.
!  *		  Handed to str_vformat to make a (string_ty *) out of it.
!  *
!  * CAVEAT
!  *	remains in scope until the next invokation of sub_var_clear,
!  *	or until the end of the next invokation of substitute.
!  */
! 
! void
! sub_var_set(name, fmt sva_last)
! 	char		*name;
! 	char		*fmt;
! 	sva_last_decl
! {
! 	va_list		ap;
! 	string_ty	*s;
! 	table_ty	*svp;
! 
! 	sva_init(ap, fmt);
! 	s = str_vformat(fmt, ap);
! 	va_end(ap);
! 
! 	if (sub_var_pos >= sub_var_size)
! 	{
! 		size_t	nbytes;
! 
! 		sub_var_size += 10;
! 		nbytes = sub_var_size * sizeof(table_ty);
! 		if (!sub_var_list)
! 			sub_var_list = (table_ty *)mem_alloc(nbytes);
! 		else
! 			mem_change_size((char **)&sub_var_list, nbytes);
! 	}
! 	svp = &sub_var_list[sub_var_pos++];
! 	svp->name = name;
! 	svp->value = s;
  }
Index: aegis/sub.h
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 25,32 ****
  
  #include <str.h>
  
! struct change_t;
  
! string_t *substitute _((struct change_t *, char *, ...));
  
  #endif /* SUB_H */
--- 25,34 ----
  
  #include <str.h>
  
! struct change_ty;
  
! void sub_var_clear _((void));
! void sub_var_set _((char *name, char *fmt, ...));
! string_ty *substitute _((struct change_ty *cp, string_ty *the_command));
  
  #endif /* SUB_H */
Index: aegis/test.c
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 90,96 ****
  "	if the file named is outside one of these directory",
  "	trees.",
  "",
! "	Tests are executed by /bin/sh.  The current directory",
  "	will be the top of the appropriate directory tree.  If",
  "	tests require temporary files, they should create them in",
  "	/tmp, as a test cannot expect to have write permission in",
--- 90,96 ----
  "	if the file named is outside one of these directory",
  "	trees.",
  "",
! "	Tests are executed by the Bourne shell.  The current directory",
  "	will be the top of the appropriate directory tree.  If",
  "	tests require temporary files, they should create them in",
  "	/tmp, as a test cannot expect to have write permission in",
***************
*** 109,117 ****
  "",
  "	-Change <number>",
  "		This option may be used to specify a particular",
! "		change within a project.  If the user is only",
! "		working on one change within a project, that is",
! "		the default change number.",
  "",
  "	-Development_Directory",
  "		This option is ised to specify that the",
--- 109,122 ----
  "",
  "	-Change <number>",
  "		This option may be used to specify a particular",
! "		change within a project.  When no -Change option is",
! "		specified, the AEGIS_CHANGE environment variable is",
! "		consulted.  If that does not exist, the user's",
! "		$HOME/.aegisrc file is examined for a default change",
! "		field (see aeuconf(5) for more information).  If",
! "		that does not exist, when the user is only working",
! "		on one change within a project, that is the default",
! "		change number.  Otherwise, it is an error.",
  "",
  "	-Development_Directory",
  "		This option is ised to specify that the",
***************
*** 138,151 ****
  "",
  "	-Project <name>",
  "		This option may be used to select the project of",
! "		interest.  When no -Project option is specified, if",
! "		the user is only working on changes within a single",
! "		project, the project name defaults to that project;",
! "		if the user is currently working on changes to more",
! "		than one project, or is not working on changes to",
! "		any project, the user's $HOME/.%src file is",
! "		examined for a default project field (see aeuconf(5)",
! "		for more information).",
  "",
  "	-TERse",
  "		This option may be used to cause listings to",
--- 143,156 ----
  "",
  "	-Project <name>",
  "		This option may be used to select the project of",
! "		interest.  When no -Project option is specified, the",
! "		AEGIS_PROJECT environment variable is consulted.  If",
! "		that does not exist, the user's $HOME/.aegisrc file",
! "		is examined for a default project field (see",
! "		aeuconf(5) for more information).  If that does not",
! "		exist, when the user is only working on changes",
! "		within a single project, the project name defaults",
! "		to that project.  Otherwise, it is an error.",
  "",
  "	-TERse",
  "		This option may be used to cause listings to",
***************
*** 159,169 ****
  "		option this option causes column headings to be",
  "		added.",
  "",
! "	All options are case insensitive.  Options may be",
! "	abbreviated; the abbreviation is the upper case letters.",
  "	Options and other command line arguments may be mixed",
! "	arbitrarily on the command line.",
  "",
  "RECOMMENDED ALIAS",
  "	The recommended alias for this command is",
  "	csh%%	alias aet '%s -t \\!* -v'",
--- 164,192 ----
  "		option this option causes column headings to be",
  "		added.",
  "",
! "	All options may be abbreviated; the abbreviation is",
! "	documented as the upper case letters, all lower case",
! "	letters and underscores (_) are optional.  You must use",
! "	consecutive sequences of optional letters.",
! "",
! "	All options are case insensitive, you may type them in",
! "	upper case or lower case or a combination of both, case",
! "	is not important.",
! "",
! "	For example: the arguments \"-project, \"-PROJ\" and \"-p\"",
! "	are all interpreted to mean the -Project option.  The",
! "	argument \"-prj\" will not be understood, because",
! "	consecutive optional characters were not supplied.",
! "",
  "	Options and other command line arguments may be mixed",
! "	arbitrarily on the command line, after the function",
! "	selectors.",
  "",
+ "	The GNU long option names are understood.  Since all",
+ "	option names for aegis are long, this means ignoring the",
+ "	extra leading '-'.  The \"--option=value\" convention is",
+ "	also understood.",
+ "",
  "RECOMMENDED ALIAS",
  "	The recommended alias for this command is",
  "	csh%%	alias aet '%s -t \\!* -v'",
***************
*** 196,202 ****
  static void
  test_list()
  {
! 	string_t	*project_name;
  	long		change_number;
  
  	trace(("test_list()\n{\n"/*}*/));
--- 219,225 ----
  static void
  test_list()
  {
! 	string_ty	*project_name;
  	long		change_number;
  
  	trace(("test_list()\n{\n"/*}*/));
***************
*** 246,253 ****
  static void
  test_main()
  {
! 	string_t	*bl;
! 	string_t	*top;
  	int		baseline_flag;
  	int		devdir_flag;
  	int		regression_flag;
--- 269,276 ----
  static void
  test_main()
  {
! 	string_ty	*bl;
! 	string_ty	*top;
  	int		baseline_flag;
  	int		devdir_flag;
  	int		regression_flag;
***************
*** 256,277 ****
  	wlist		wl;
  	wlist		cfile;
  	wlist		pfile;
! 	string_t	*s1;
! 	string_t	*s2;
  	pstate		pstate_data;
  	pstate_src	p_src_data;
  	cstate		cstate_data;
  	cstate_src	c_src_data;
! 	string_t	*dir;
  	int		j;
  	int		npassed;
  	int		nfailed;
! 	string_t	*project_name;
! 	project_t	*pp;
  	long		change_number;
! 	change_t	*cp;
  	int		nolog;
! 	user_t		*up;
  
  	trace(("test_main()\n{\n"/*}*/));
  	project_name = 0;
--- 279,300 ----
  	wlist		wl;
  	wlist		cfile;
  	wlist		pfile;
! 	string_ty	*s1;
! 	string_ty	*s2;
  	pstate		pstate_data;
  	pstate_src	p_src_data;
  	cstate		cstate_data;
  	cstate_src	c_src_data;
! 	string_ty	*dir;
  	int		j;
  	int		npassed;
  	int		nfailed;
! 	string_ty	*project_name;
! 	project_ty	*pp;
  	long		change_number;
! 	change_ty	*cp;
  	int		nolog;
! 	user_ty		*up;
  
  	trace(("test_main()\n{\n"/*}*/));
  	project_name = 0;
***************
*** 331,337 ****
  		case arglex_token_string:
  			s1 = str_from_c(arglex_value.alv_string);
  			os_become_orig();
! 			s2 = os_pathname(s1);
  			os_become_undo();
  			if (wl_member(&wl, s1))
  			{
--- 354,360 ----
  		case arglex_token_string:
  			s1 = str_from_c(arglex_value.alv_string);
  			os_become_orig();
! 			s2 = os_pathname(s1, 1);
  			os_become_undo();
  			if (wl_member(&wl, s1))
  			{
***************
*** 427,433 ****
  	/*
  	 * see if it is an appropriate thing to be doing
  	 */
! 	bl = project_baseline_path_get(pp);
  	switch (cstate_data->state)
  	{
  	case cstate_state_being_developed:
--- 450,456 ----
  	/*
  	 * see if it is an appropriate thing to be doing
  	 */
! 	bl = project_baseline_path_get(pp, 1);
  	switch (cstate_data->state)
  	{
  	case cstate_state_being_developed:
***************
*** 444,450 ****
  			dir = bl;
  		else
  		{
! 			dir = change_development_directory_get(cp);
  			trace_string(dir->str_text);
  		}
  		break;
--- 467,473 ----
  			dir = bl;
  		else
  		{
! 			dir = change_development_directory_get(cp, 1);
  			trace_string(dir->str_text);
  		}
  		break;
***************
*** 464,472 ****
  		else
  		{
  			if (devdir_flag)
! 				dir = change_development_directory_get(cp);
  			else
! 				dir = change_integration_directory_get(cp);
  		}
  		break;
  
--- 487,495 ----
  		else
  		{
  			if (devdir_flag)
! 				dir = change_development_directory_get(cp, 1);
  			else
! 				dir = change_integration_directory_get(cp, 1);
  		}
  		break;
  
***************
*** 497,505 ****
  		assert(s1->str_text[0] == '/');
  		s2 = os_below_dir(bl, s1);
  		if (!s2 && cstate_data->state == cstate_state_being_integrated)
! 			s2 = os_below_dir(change_integration_directory_get(cp), s1);
  		if (!s2)
! 			s2 = os_below_dir(change_development_directory_get(cp), s1);
  		if (!s2)
  			change_fatal(cp, "path \"%S\" unrelated", s1);
  		c_src_data = change_src_find(cp, s2);
--- 520,528 ----
  		assert(s1->str_text[0] == '/');
  		s2 = os_below_dir(bl, s1);
  		if (!s2 && cstate_data->state == cstate_state_being_integrated)
! 			s2 = os_below_dir(change_integration_directory_get(cp, 1), s1);
  		if (!s2)
! 			s2 = os_below_dir(change_development_directory_get(cp, 1), s1);
  		if (!s2)
  			change_fatal(cp, "path \"%S\" unrelated", s1);
  		c_src_data = change_src_find(cp, s2);
***************
*** 644,650 ****
  		 */
  		if (cstate_data->state == cstate_state_being_integrated)
  		{
! 			user_t	*pup;
  
  			pup = project_user(pp);
  			log_open(change_logfile_get(cp), pup);
--- 667,673 ----
  		 */
  		if (cstate_data->state == cstate_state_being_integrated)
  		{
! 			user_ty	*pup;
  
  			pup = project_user(pp);
  			log_open(change_logfile_get(cp), pup);
***************
*** 657,665 ****
  	nfailed = 0;
  	trace_string(dir->str_text);
  	if (cstate_data->state == cstate_state_being_integrated)
! 		top = change_integration_directory_get(cp);
  	else
! 		top = change_development_directory_get(cp);
  	for (j = 0; j < cfile.wl_nwords; ++j)
  	{
  		int		result;
--- 680,688 ----
  	nfailed = 0;
  	trace_string(dir->str_text);
  	if (cstate_data->state == cstate_state_being_integrated)
! 		top = change_integration_directory_get(cp, 1);
  	else
! 		top = change_development_directory_get(cp, 1);
  	for (j = 0; j < cfile.wl_nwords; ++j)
  	{
  		int		result;
***************
*** 668,674 ****
  		s1 = cfile.wl_word[j];
  		c_src_data = change_src_find(cp, s1);
  		assert(c_src_data);
! 		s2 = str_format("sh %S/%S", top, s1);
  		if (c_src_data->usage == file_usage_manual_test)
  			flags = OS_EXEC_FLAG_INPUT;
  		else
--- 691,697 ----
  		s1 = cfile.wl_word[j];
  		c_src_data = change_src_find(cp, s1);
  		assert(c_src_data);
! 		s2 = str_format("%s %S/%S", os_shell(), top, s1);
  		if (c_src_data->usage == file_usage_manual_test)
  			flags = OS_EXEC_FLAG_INPUT;
  		else
***************
*** 729,735 ****
  		s1 = pfile.wl_word[j];
  		p_src_data = project_src_find(pp, s1);
  		assert(p_src_data);
! 		s2 = str_format("sh %S/%S", bl, s1);
  		if (p_src_data->usage == file_usage_manual_test)
  			flags = OS_EXEC_FLAG_INPUT;
  		else
--- 752,758 ----
  		s1 = pfile.wl_word[j];
  		p_src_data = project_src_find(pp, s1);
  		assert(p_src_data);
! 		s2 = str_format("%s %S/%S", os_shell(), bl, s1);
  		if (p_src_data->usage == file_usage_manual_test)
  			flags = OS_EXEC_FLAG_INPUT;
  		else
***************
*** 789,808 ****
  static void
  test_independent()
  {
! 	string_t	*bl;
  	int		automatic_flag;
  	int		manual_flag;
  	wlist		wl;
! 	string_t	*s1;
! 	string_t	*s2;
  	pstate		pstate_data;
  	pstate_src	src_data;
  	int		j;
  	int		npassed;
  	int		nfailed;
! 	string_t	*project_name;
! 	project_t	*pp;
! 	user_t		*pup;
  
  	trace(("test_independent()\n{\n"/*}*/));
  	project_name = 0;
--- 812,831 ----
  static void
  test_independent()
  {
! 	string_ty	*bl;
  	int		automatic_flag;
  	int		manual_flag;
  	wlist		wl;
! 	string_ty	*s1;
! 	string_ty	*s2;
  	pstate		pstate_data;
  	pstate_src	src_data;
  	int		j;
  	int		npassed;
  	int		nfailed;
! 	string_ty	*project_name;
! 	project_ty	*pp;
! 	user_ty		*pup;
  
  	trace(("test_independent()\n{\n"/*}*/));
  	project_name = 0;
***************
*** 835,841 ****
  		case arglex_token_string:
  			s1 = str_from_c(arglex_value.alv_string);
  			os_become_orig();
! 			s2 = os_pathname(s1);
  			os_become_undo();
  			if (wl_member(&wl, s1))
  			{
--- 858,864 ----
  		case arglex_token_string:
  			s1 = str_from_c(arglex_value.alv_string);
  			os_become_orig();
! 			s2 = os_pathname(s1, 1);
  			os_become_undo();
  			if (wl_member(&wl, s1))
  			{
***************
*** 894,900 ****
  	/*
  	 * make sure the paths make sense
  	 */
! 	bl = project_baseline_path_get(pp);
  	for (j = 0; j < wl.wl_nwords; ++j)
  	{
  		s1 = wl.wl_word[j];
--- 917,923 ----
  	/*
  	 * make sure the paths make sense
  	 */
! 	bl = project_baseline_path_get(pp, 1);
  	for (j = 0; j < wl.wl_nwords; ++j)
  	{
  		s1 = wl.wl_word[j];
Index: aegis/test.h
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
Index: aegis/type.c
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 28,34 ****
   *	type_class_name
   *
   * SYNOPSIS
!  *	char *type_class_name(type_class_t n);
   *
   * DESCRIPTION
   *	The type_class_name function is used to
--- 28,34 ----
   *	type_class_name
   *
   * SYNOPSIS
!  *	char *type_class_name(type_class_ty n);
   *
   * DESCRIPTION
   *	The type_class_name function is used to
***************
*** 46,52 ****
  
  char *
  type_class_name(type)
! 	type_t	*type;
  {
  	switch (type->class)
  	{
--- 46,52 ----
  
  char *
  type_class_name(type)
! 	type_ty	*type;
  {
  	switch (type->class)
  	{
Index: aegis/type.h
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 28,34 ****
  #include <main.h>
  #include <str.h>
  
! enum type_class_t
  {
  	type_class_integer,
  	type_class_string,
--- 28,34 ----
  #include <main.h>
  #include <str.h>
  
! enum type_class_ty
  {
  	type_class_integer,
  	type_class_string,
***************
*** 36,57 ****
  	type_class_list,
  	type_class_struct
  };
! typedef enum type_class_t type_class_t;
  
! typedef struct type_t type_t;
! struct type_t
  {
! 	type_class_t	class;
  	char		*name;
  
  	void *(*alloc)_((void));
  	void (*free)_((void *this));
! 	int (*enum_parse)_((string_t *name, void *addr));
! 	void (*list_parse)_((void *this, type_t **type_pp, void **addr_p));
! 	int (*struct_parse)_((void *this, string_t *name, type_t **type_pp,
  		void **addr_p, unsigned long *maskp));
  };
  
! char *type_class_name _((type_t *));
  
  #endif /* TYPE_H */
--- 36,57 ----
  	type_class_list,
  	type_class_struct
  };
! typedef enum type_class_ty type_class_ty;
  
! typedef struct type_ty type_ty;
! struct type_ty
  {
! 	type_class_ty	class;
  	char		*name;
  
  	void *(*alloc)_((void));
  	void (*free)_((void *this));
! 	int (*enum_parse)_((string_ty *name, void *addr));
! 	void (*list_parse)_((void *this, type_ty **type_pp, void **addr_p));
! 	int (*struct_parse)_((void *this, string_ty *name, type_ty **type_pp,
  		void **addr_p, unsigned long *maskp));
  };
  
! char *type_class_name _((type_ty *));
  
  #endif /* TYPE_H */
Index: aegis/uconf.def
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 23,34 ****
   *
   * it is only ever read by aegis, so there is no need for locking.
   *
-  * Becase this file is not maintained by aegis,
-  * it is not possible to place a default change here.
-  *
-  * This file has higher precedence than gstate.def defaults,
-  * for the host on which it appears.
-  *
   * If you change this file, don't forget to change
   *	man5/aeuconf.5
   */
--- 23,28 ----
***************
*** 37,42 ****
--- 31,41 ----
   * The name of a project.
   */
  default_project_name = string;
+ 
+ /*
+  * the number of a change
+  */
+ default_change_number = integer;
  
  /*
   * The pathname of where to place new development directories.
Index: aegis/undo.c
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 28,34 ****
  #include <undo.h>
  
  
! enum what_t
  {
  	what_rename,
  	what_chmod,
--- 28,34 ----
  #include <undo.h>
  
  
! enum what_ty
  {
  	what_rename,
  	what_chmod,
***************
*** 36,70 ****
  	what_unlink_errok,
  	what_rmdir_errok
  };
! typedef enum what_t what_t;
  
! typedef struct action_t action_t;
! struct action_t
  {
! 	what_t		what;
! 	string_t	*path1;
! 	string_t	*path2;
  	int		arg1;
  	int		arg2;
! 	action_t	*next;
  	int		uid;
  	int		gid;
  	int		umask;
  };
  
! static	action_t	*head;
  
  
! static action_t *newlink _((what_t));
  
! static action_t *
  newlink(what)
! 	what_t		what;
  {
! 	action_t	*new;
  
  	trace(("undo::newlink(what = %d)\n{\n"/*}*/, what));
! 	new = (action_t *)mem_alloc(sizeof(action_t));
  	new->what = what;
  	new->next = head;
  	new->path1 = 0;
--- 36,70 ----
  	what_unlink_errok,
  	what_rmdir_errok
  };
! typedef enum what_ty what_ty;
  
! typedef struct action_ty action_ty;
! struct action_ty
  {
! 	what_ty		what;
! 	string_ty	*path1;
! 	string_ty	*path2;
  	int		arg1;
  	int		arg2;
! 	action_ty	*next;
  	int		uid;
  	int		gid;
  	int		umask;
  };
  
! static	action_ty	*head;
  
  
! static action_ty *newlink _((what_ty));
  
! static action_ty *
  newlink(what)
! 	what_ty		what;
  {
! 	action_ty	*new;
  
  	trace(("undo::newlink(what = %d)\n{\n"/*}*/, what));
! 	new = (action_ty *)mem_alloc(sizeof(action_ty));
  	new->what = what;
  	new->next = head;
  	new->path1 = 0;
***************
*** 81,90 ****
  
  void
  undo_rename(from, to)
! 	string_t	*from;
! 	string_t	*to;
  {
! 	action_t	*new;
  
  	trace(("undo_rename(from = %08lX, to = %08lX)\n{\n"/*}*/, from, to));
  	trace_string(from->str_text);
--- 81,90 ----
  
  void
  undo_rename(from, to)
! 	string_ty	*from;
! 	string_ty	*to;
  {
! 	action_ty	*new;
  
  	trace(("undo_rename(from = %08lX, to = %08lX)\n{\n"/*}*/, from, to));
  	trace_string(from->str_text);
***************
*** 98,107 ****
  
  void
  undo_chmod(path, mode)
! 	string_t	*path;
  	int		mode;
  {
! 	action_t	*new;
  
  	mode &= 07777;
  	trace(("undo_chmod(path = %08lX, mode = %05o)\n{\n"/*}*/, path, mode));
--- 98,107 ----
  
  void
  undo_chmod(path, mode)
! 	string_ty	*path;
  	int		mode;
  {
! 	action_ty	*new;
  
  	mode &= 07777;
  	trace(("undo_chmod(path = %08lX, mode = %05o)\n{\n"/*}*/, path, mode));
***************
*** 115,124 ****
  
  void
  undo_chmod_errok(path, mode)
! 	string_t	*path;
  	int		mode;
  {
! 	action_t	*new;
  
  	mode &= 07777;
  	trace(("undo_chmod_errok(path = %08lX, mode = %05o)\n{\n"/*}*/, path, mode));
--- 115,124 ----
  
  void
  undo_chmod_errok(path, mode)
! 	string_ty	*path;
  	int		mode;
  {
! 	action_ty	*new;
  
  	mode &= 07777;
  	trace(("undo_chmod_errok(path = %08lX, mode = %05o)\n{\n"/*}*/, path, mode));
***************
*** 132,140 ****
  
  void
  undo_unlink_errok(path)
! 	string_t	*path;
  {
! 	action_t	*new;
  
  	trace(("undo_unlink_errok(path = %08lX)\n{\n"/*}*/, path));
  	trace_string(path->str_text);
--- 132,140 ----
  
  void
  undo_unlink_errok(path)
! 	string_ty	*path;
  {
! 	action_ty	*new;
  
  	trace(("undo_unlink_errok(path = %08lX)\n{\n"/*}*/, path));
  	trace_string(path->str_text);
***************
*** 145,153 ****
  
  void
  undo_rmdir_errok(path)
! 	string_t	*path;
  {
! 	action_t	*new;
  
  	trace(("undo_rmdir_errok(path = %08lX)\n{\n"/*}*/, path));
  	trace_string(path->str_text);
--- 145,153 ----
  
  void
  undo_rmdir_errok(path)
! 	string_ty	*path;
  {
! 	action_ty	*new;
  
  	trace(("undo_rmdir_errok(path = %08lX)\n{\n"/*}*/, path));
  	trace_string(path->str_text);
***************
*** 161,167 ****
  undo()
  {
  	static int	count;
! 	action_t	*ap;
  	char		*progname;
  
  	trace(("undo()\n{\n"/*}*/));
--- 161,167 ----
  undo()
  {
  	static int	count;
! 	action_ty	*ap;
  	char		*progname;
  
  	trace(("undo()\n{\n"/*}*/));
***************
*** 302,308 ****
  void
  undo_cancel()
  {
! 	action_t	*ap;
  
  	trace(("undo_cancel()\n{\n"/*}*/));
  	while (head)
--- 302,308 ----
  void
  undo_cancel()
  {
! 	action_ty	*ap;
  
  	trace(("undo_cancel()\n{\n"/*}*/));
  	while (head)
Index: aegis/undo.h
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 25,35 ****
  
  #include <str.h>
  
! void undo_rename _((string_t *from, string_t *to));
! void undo_chmod _((string_t *path, int mode));
! void undo_chmod_errok _((string_t *path, int mode));
! void undo_unlink_errok _((string_t *path));
! void undo_rmdir_errok _((string_t *path));
  void undo _((void));
  void undo_quitter _((int));
  void undo_cancel _((void));
--- 25,35 ----
  
  #include <str.h>
  
! void undo_rename _((string_ty *from, string_ty *to));
! void undo_chmod _((string_ty *path, int mode));
! void undo_chmod_errok _((string_ty *path, int mode));
! void undo_unlink_errok _((string_ty *path));
! void undo_rmdir_errok _((string_ty *path));
  void undo _((void));
  void undo_quitter _((int));
  void undo_cancel _((void));
Index: aegis/user.c
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 20,25 ****
--- 20,27 ----
   * MANIFEST: functions to manage information about users
   */
  
+ #include <ctype.h>
+ #include <stdlib.h>
  #include <pwd.h>
  #include <grp.h>
  #include <unistd.h>
***************
*** 40,46 ****
  
  
  static	size_t	nusers;
! static	user_t	**user;
  
  
  /*
--- 42,48 ----
  
  
  static	size_t	nusers;
! static	user_ty	**user;
  
  
  /*
***************
*** 48,54 ****
   *	user_numeric
   *
   * SYNOPSIS
!  *	user_t *user_numeric(project_t *pp, int uid);
   *
   * DESCRIPTION
   *	The user_numeric function is used to
--- 50,56 ----
   *	user_numeric
   *
   * SYNOPSIS
!  *	user_ty *user_numeric(project_ty *pp, int uid);
   *
   * DESCRIPTION
   *	The user_numeric function is used to
***************
*** 68,80 ****
   *	Release the user structure with the user_free() function when done.
   */
  
! user_t *
  user_numeric(pp, uid)
! 	project_t	*pp;
  	int		uid;
  {
  	size_t		j;
! 	user_t		*up;
  	struct passwd	*pw;
  	struct group	*gr;
  
--- 70,82 ----
   *	Release the user structure with the user_free() function when done.
   */
  
! user_ty *
  user_numeric(pp, uid)
! 	project_ty	*pp;
  	int		uid;
  {
  	size_t		j;
! 	user_ty		*up;
  	struct passwd	*pw;
  	struct group	*gr;
  
***************
*** 102,108 ****
  	pw = getpwuid(uid);
  	if (!pw)
  		fatal("uid %d unknown", uid);
! 	up = (user_t *)mem_alloc_clear(sizeof(user_t));
  	up->reference_count = 1;
  	if (pp)
  		up->pp = project_copy(pp);
--- 104,110 ----
  	pw = getpwuid(uid);
  	if (!pw)
  		fatal("uid %d unknown", uid);
! 	up = (user_ty *)mem_alloc_clear(sizeof(user_ty));
  	up->reference_count = 1;
  	if (pp)
  		up->pp = project_copy(pp);
***************
*** 113,120 ****
--- 115,124 ----
  	up->home = str_from_c(pw->pw_dir);
  	if (pw->pw_gecos && pw->pw_gecos[0])
  		up->full_name = str_from_c(pw->pw_gecos);
+ #ifndef CONF_NO_pw_comment
  	else if (pw->pw_comment && pw->pw_comment[0])
  		up->full_name = str_from_c(pw->pw_comment);
+ #endif
  	else
  		up->full_name = str_from_c(pw->pw_name);
  	if (pp)
***************
*** 138,144 ****
  	/*
  	 * add it to the list
  	 */
! 	*(user_t **)enlarge(&nusers, (char **)&user, sizeof(user_t *)) = up;
  
  	/*
  	 * Find the umask.
--- 142,148 ----
  	/*
  	 * add it to the list
  	 */
! 	*(user_ty **)enlarge(&nusers, (char **)&user, sizeof(user_ty *)) = up;
  
  	/*
  	 * Find the umask.
***************
*** 165,171 ****
   *	user_symbolic
   *
   * SYNOPSIS
!  *	user_t *user_symbolic(project_t *pp, string_t *name);
   *
   * DESCRIPTION
   *	The user_symbolic function is used to
--- 169,175 ----
   *	user_symbolic
   *
   * SYNOPSIS
!  *	user_ty *user_symbolic(project_ty *pp, string_ty *name);
   *
   * DESCRIPTION
   *	The user_symbolic function is used to
***************
*** 187,199 ****
   *	Release the user structure with the user_free() function when done.
   */
  
! user_t *
  user_symbolic(pp, name)
! 	project_t	*pp;
! 	string_t	*name;
  {
  	struct passwd	*pw;
! 	user_t		*result;
  
  	trace(("user_symbolic(pp = %08lX, name = \"%s\")\n{\n"/*}*/, pp,
  		name->str_text));
--- 191,203 ----
   *	Release the user structure with the user_free() function when done.
   */
  
! user_ty *
  user_symbolic(pp, name)
! 	project_ty	*pp;
! 	string_ty	*name;
  {
  	struct passwd	*pw;
! 	user_ty		*result;
  
  	trace(("user_symbolic(pp = %08lX, name = \"%s\")\n{\n"/*}*/, pp,
  		name->str_text));
***************
*** 212,218 ****
   *	user_executing
   *
   * SYNOPSIS
!  *	user_t *user_executing(project_t *pp);
   *
   * DESCRIPTION
   *	The user_executing function is used to
--- 216,222 ----
   *	user_executing
   *
   * SYNOPSIS
!  *	user_ty *user_executing(project_ty *pp);
   *
   * DESCRIPTION
   *	The user_executing function is used to
***************
*** 229,239 ****
   *	Release the user structure with the user_free() function when done.
   */
  
! user_t *
  user_executing(pp)
! 	project_t	*pp;
  {
! 	user_t		*result;
  	int		uid;
  	int		gid;
  
--- 233,243 ----
   *	Release the user structure with the user_free() function when done.
   */
  
! user_ty *
  user_executing(pp)
! 	project_ty	*pp;
  {
! 	user_ty		*result;
  	int		uid;
  	int		gid;
  
***************
*** 251,257 ****
   *	user_free
   *
   * SYNOPSIS
!  *	void user_free(user_t *up);
   *
   * DESCRIPTION
   *	The user_free function is used to
--- 255,261 ----
   *	user_free
   *
   * SYNOPSIS
!  *	void user_free(user_ty *up);
   *
   * DESCRIPTION
   *	The user_free function is used to
***************
*** 263,269 ****
  
  void
  user_free(up)
! 	user_t		*up;
  {
  	trace(("user_free(up = %08lX)\n{\n"/*}*/, up));
  	up->reference_count--;
--- 267,273 ----
  
  void
  user_free(up)
! 	user_ty		*up;
  {
  	trace(("user_free(up = %08lX)\n{\n"/*}*/, up));
  	up->reference_count--;
***************
*** 311,317 ****
   *	user_copy
   *
   * SYNOPSIS
!  *	user_t *user_copy(user_t *up);
   *
   * DESCRIPTION
   *	The user_copy function is used to
--- 315,321 ----
   *	user_copy
   *
   * SYNOPSIS
!  *	user_ty *user_copy(user_ty *up);
   *
   * DESCRIPTION
   *	The user_copy function is used to
***************
*** 327,335 ****
   *	Release the user structure with the user_free() function when done.
   */
  
! user_t *
  user_copy(up)
! 	user_t		*up;
  {
  	trace(("user_copy(up = %08lX)\n{\n"/*}*/, up));
  	up->reference_count++;
--- 331,339 ----
   *	Release the user structure with the user_free() function when done.
   */
  
! user_ty *
  user_copy(up)
! 	user_ty		*up;
  {
  	trace(("user_copy(up = %08lX)\n{\n"/*}*/, up));
  	up->reference_count++;
***************
*** 344,350 ****
   *	user_name
   *
   * SYNOPSIS
!  *	string_t *user_name(user_t *);
   *
   * DESCRIPTION
   *	The user_name function is used to
--- 348,354 ----
   *	user_name
   *
   * SYNOPSIS
!  *	string_ty *user_name(user_ty *);
   *
   * DESCRIPTION
   *	The user_name function is used to
***************
*** 357,365 ****
   *	pointer to string containing user's login name
   */
  
! string_t *
  user_name(up)
! 	user_t		*up;
  {
  	trace(("user_name(up = %08lX)\n{\n"/*}*/, up));
  	trace(("return \"%s\";\n", up->name->str_text));
--- 361,369 ----
   *	pointer to string containing user's login name
   */
  
! string_ty *
  user_name(up)
! 	user_ty		*up;
  {
  	trace(("user_name(up = %08lX)\n{\n"/*}*/, up));
  	trace(("return \"%s\";\n", up->name->str_text));
***************
*** 373,379 ****
   *	user_id
   *
   * SYNOPSIS
!  *	int user_id(user_t *up);
   *
   * DESCRIPTION
   *	The user_id function is used to
--- 377,383 ----
   *	user_id
   *
   * SYNOPSIS
!  *	int user_id(user_ty *up);
   *
   * DESCRIPTION
   *	The user_id function is used to
***************
*** 388,394 ****
  
  int
  user_id(up)
! 	user_t		*up;
  {
  	trace(("user_id(up = %08lX)\n{\n"/*}*/, up));
  	trace(("return %d;\n", up->uid));
--- 392,398 ----
  
  int
  user_id(up)
! 	user_ty		*up;
  {
  	trace(("user_id(up = %08lX)\n{\n"/*}*/, up));
  	trace(("return %d;\n", up->uid));
***************
*** 402,408 ****
   *	user_group
   *
   * SYNOPSIS
!  *	string_t *user_group(user_t *);
   *
   * DESCRIPTION
   *	The user_group function is used to
--- 406,412 ----
   *	user_group
   *
   * SYNOPSIS
!  *	string_ty *user_group(user_ty *);
   *
   * DESCRIPTION
   *	The user_group function is used to
***************
*** 415,423 ****
   *	pointer to string naming default group
   */
  
! string_t *
  user_group(up)
! 	user_t		*up;
  {
  	trace(("user_group(up = %08lX)\n{\n"/*}*/, up));
  	trace(("return \"%s\";\n", up->group->str_text));
--- 419,427 ----
   *	pointer to string naming default group
   */
  
! string_ty *
  user_group(up)
! 	user_ty		*up;
  {
  	trace(("user_group(up = %08lX)\n{\n"/*}*/, up));
  	trace(("return \"%s\";\n", up->group->str_text));
***************
*** 431,437 ****
   *	user_gid
   *
   * SYNOPSIS
!  *	int user_gid(user_t *up);
   *
   * DESCRIPTION
   *	The user_gid function is used to
--- 435,441 ----
   *	user_gid
   *
   * SYNOPSIS
!  *	int user_gid(user_ty *up);
   *
   * DESCRIPTION
   *	The user_gid function is used to
***************
*** 446,452 ****
  
  int
  user_gid(up)
! 	user_t		*up;
  {
  	trace(("user_gid(up = %08lX)\n{\n"/*}*/, up));
  	trace(("return %d;\n", up->gid));
--- 450,456 ----
  
  int
  user_gid(up)
! 	user_ty		*up;
  {
  	trace(("user_gid(up = %08lX)\n{\n"/*}*/, up));
  	trace(("return %d;\n", up->gid));
***************
*** 460,466 ****
   *	user_umask
   *
   * SYNOPSIS
!  *	int user_umask(user_t *up);
   *
   * DESCRIPTION
   *	The user_umask function is used to
--- 464,470 ----
   *	user_umask
   *
   * SYNOPSIS
!  *	int user_umask(user_ty *up);
   *
   * DESCRIPTION
   *	The user_umask function is used to
***************
*** 475,481 ****
  
  int
  user_umask(up)
! 	user_t		*up;
  {
  	trace(("user_umask(up = %08lX)\n{\n"/*}*/, up));
  	trace(("return %05o;\n", up->umask));
--- 479,485 ----
  
  int
  user_umask(up)
! 	user_ty		*up;
  {
  	trace(("user_umask(up = %08lX)\n{\n"/*}*/, up));
  	trace(("return %05o;\n", up->umask));
***************
*** 489,495 ****
   *	lock_sync
   *
   * SYNOPSIS
!  *	void lock_sync(user_t *up);
   *
   * DESCRIPTION
   *	The lock_sync function is used to
--- 493,499 ----
   *	lock_sync
   *
   * SYNOPSIS
!  *	void lock_sync(user_ty *up);
   *
   * DESCRIPTION
   *	The lock_sync function is used to
***************
*** 500,510 ****
   *	up	- pointer to user structure
   */
  
! static void lock_sync _((user_t *));
  
  static void
  lock_sync(up)
! 	user_t		*up;
  {
  	long		n;
  
--- 504,514 ----
   *	up	- pointer to user structure
   */
  
! static void lock_sync _((user_ty *));
  
  static void
  lock_sync(up)
! 	user_ty		*up;
  {
  	long		n;
  
***************
*** 528,534 ****
   *	user_ustate_get
   *
   * SYNOPSIS
!  *	ustate user_ustate_get(user_t *up);
   *
   * DESCRIPTION
   *	The user_ustate_get function is used to
--- 532,538 ----
   *	user_ustate_get
   *
   * SYNOPSIS
!  *	ustate user_ustate_get(user_ty *up);
   *
   * DESCRIPTION
   *	The user_ustate_get function is used to
***************
*** 542,552 ****
   *	pointer to ustate structure in dynamic memory
   */
  
! static ustate user_ustate_get _((user_t *));
  
  static ustate
  user_ustate_get(up)
! 	user_t		*up;
  {
  	trace(("user_ustate_get(up = %08lX)\n{\n"/*}*/, up));
  	lock_sync(up);
--- 546,556 ----
   *	pointer to ustate structure in dynamic memory
   */
  
! static ustate user_ustate_get _((user_ty *));
  
  static ustate
  user_ustate_get(up)
! 	user_ty		*up;
  {
  	trace(("user_ustate_get(up = %08lX)\n{\n"/*}*/, up));
  	lock_sync(up);
***************
*** 563,574 ****
  		}
  		else
  		{
! 			up->ustate_data = ustate_type.alloc();
  			up->ustate_is_new = 1;
  		}
  		gonzo_become_undo();
  		if (!up->ustate_data->own)
! 			up->ustate_data->own = ustate_own_list_type.alloc();
  	}
  	trace(("return %08lX;\n", up->ustate_data));
  	trace((/*{*/"}\n"));
--- 567,580 ----
  		}
  		else
  		{
! 			up->ustate_data = (ustate)ustate_type.alloc();
  			up->ustate_is_new = 1;
  		}
  		gonzo_become_undo();
  		if (!up->ustate_data->own)
! 			up->ustate_data->own =
! 				(ustate_own_list)
! 				ustate_own_list_type.alloc();
  	}
  	trace(("return %08lX;\n", up->ustate_data));
  	trace((/*{*/"}\n"));
***************
*** 595,605 ****
   *	pointer to uconf structure in dynamic memory
   */
  
! static uconf user_uconf_get _((user_t *up));
  
  static uconf
  user_uconf_get(up)
! 	user_t		*up;
  {
  	trace(("user_uconf_get(up = %08lX)\n{\n"/*}*/, up));
  	lock_sync(up);
--- 601,611 ----
   *	pointer to uconf structure in dynamic memory
   */
  
! static uconf user_uconf_get _((user_ty *up));
  
  static uconf
  user_uconf_get(up)
! 	user_ty		*up;
  {
  	trace(("user_uconf_get(up = %08lX)\n{\n"/*}*/, up));
  	lock_sync(up);
***************
*** 615,621 ****
  				uconf_read_file(up->uconf_path->str_text);
  		}
  		else
! 			up->uconf_data = uconf_type.alloc();
  		user_become_undo();
  	}
  	trace(("return %08lX;\n", up->uconf_data));
--- 621,627 ----
  				uconf_read_file(up->uconf_path->str_text);
  		}
  		else
! 			up->uconf_data = (uconf)uconf_type.alloc();
  		user_become_undo();
  	}
  	trace(("return %08lX;\n", up->uconf_data));
***************
*** 629,635 ****
   *	user_home
   *
   * SYNOPSIS
!  *	string_t *user_home(user_t *up);
   *
   * DESCRIPTION
   *	The user_home function is used to
--- 635,641 ----
   *	user_home
   *
   * SYNOPSIS
!  *	string_ty *user_home(user_ty *up);
   *
   * DESCRIPTION
   *	The user_home function is used to
***************
*** 646,654 ****
   *	it won't be here, either.
   */
  
! string_t *
  user_home(up)
! 	user_t		*up;
  {
  	trace(("user_home(up = %08lX)\n{\n"/*}*/, up));
  	assert(up->home);
--- 652,660 ----
   *	it won't be here, either.
   */
  
! string_ty *
  user_home(up)
! 	user_ty		*up;
  {
  	trace(("user_home(up = %08lX)\n{\n"/*}*/, up));
  	assert(up->home);
***************
*** 663,669 ****
   *	user_full_name
   *
   * SYNOPSIS
!  *	char *user_full_name(string_t *login);
   *
   * DESCRIPTION
   *	The user_full_name function is used to
--- 669,675 ----
   *	user_full_name
   *
   * SYNOPSIS
!  *	char *user_full_name(string_ty *login);
   *
   * DESCRIPTION
   *	The user_full_name function is used to
***************
*** 683,689 ****
  
  char *
  user_full_name(name)
! 	string_t	*name;
  {
  	struct passwd	*pw;
  	char		*result;
--- 689,695 ----
  
  char *
  user_full_name(name)
! 	string_ty	*name;
  {
  	struct passwd	*pw;
  	char		*result;
***************
*** 694,701 ****
--- 700,709 ----
  		result = "";
  	else if (pw->pw_gecos && pw->pw_gecos[0])
  		result = pw->pw_gecos;
+ #ifndef CONF_NO_pw_comment
  	else if (pw->pw_comment && pw->pw_comment[0])
  		result = pw->pw_comment;
+ #endif
  	else
  		result = "";
  	trace(("return \"%s\";\n", result));
***************
*** 709,715 ****
   *	user_ustate_write
   *
   * SYNOPSIS
!  *	void user_ustate_write(user_t *up);
   *
   * DESCRIPTION
   *	The user_ustate_write function is used to
--- 717,723 ----
   *	user_ustate_write
   *
   * SYNOPSIS
!  *	void user_ustate_write(user_ty *up);
   *
   * DESCRIPTION
   *	The user_ustate_write function is used to
***************
*** 721,730 ****
  
  void
  user_ustate_write(up)
! 	user_t		*up;
  {
! 	string_t	*filename_new;
! 	string_t	*filename_old;
  	static int	count;
  
  	trace(("user_ustate_write(up = %08lX)\n{\n"/*}*/, up));
--- 729,738 ----
  
  void
  user_ustate_write(up)
! 	user_ty		*up;
  {
! 	string_ty	*filename_new;
! 	string_ty	*filename_old;
  	static int	count;
  
  	trace(("user_ustate_write(up = %08lX)\n{\n"/*}*/, up));
***************
*** 769,775 ****
   *	user_own_add
   *
   * SYNOPSIS
!  *	void user_own_add(user_t *up, string_t *project_name,
   *		long change_number);
   *
   * DESCRIPTION
--- 777,783 ----
   *	user_own_add
   *
   * SYNOPSIS
!  *	void user_own_add(user_ty *up, string_ty *project_name,
   *		long change_number);
   *
   * DESCRIPTION
***************
*** 787,794 ****
  
  void
  user_own_add(up, project_name, change_number)
! 	user_t		*up;
! 	string_t	*project_name;
  	long		change_number;
  {
  	ustate		ustate_data;
--- 795,802 ----
  
  void
  user_own_add(up, project_name, change_number)
! 	user_ty		*up;
! 	string_ty	*project_name;
  	long		change_number;
  {
  	ustate		ustate_data;
***************
*** 796,802 ****
  	ustate_own	own_data = 0;
  	ustate_own	*own_data_p;
  	long		*change_p;
! 	type_t		*type_p;
  
  	trace(("user_own_add()\n{\n"/*}*/));
  	ustate_data = user_ustate_get(up);
--- 804,810 ----
  	ustate_own	own_data = 0;
  	ustate_own	*own_data_p;
  	long		*change_p;
! 	type_ty		*type_p;
  
  	trace(("user_own_add()\n{\n"/*}*/));
  	ustate_data = user_ustate_get(up);
***************
*** 823,829 ****
  			&type_p,
  			(void **)&own_data_p
  		);
! 		own_data = ustate_own_type.alloc();
  		*own_data_p = own_data;
  		own_data->project_name = str_copy(project_name);
  	}
--- 831,837 ----
  			&type_p,
  			(void **)&own_data_p
  		);
! 		own_data = (ustate_own)ustate_own_type.alloc();
  		*own_data_p = own_data;
  		own_data->project_name = str_copy(project_name);
  	}
***************
*** 832,838 ****
  	 * Create a changes for the project, if necessary.
  	 */
  	if (!own_data->changes)
! 		own_data->changes = ustate_own_changes_list_type.alloc();
  
  	/*
  	 * Add another item to the changes list for the project.
--- 840,848 ----
  	 * Create a changes for the project, if necessary.
  	 */
  	if (!own_data->changes)
! 		own_data->changes =
! 			(ustate_own_changes_list)
! 			ustate_own_changes_list_type.alloc();
  
  	/*
  	 * Add another item to the changes list for the project.
***************
*** 851,860 ****
  
  /*
   * NAME
   *	user_own_remove
   *
   * SYNOPSIS
!  *	void user_own_remove(user_t *up, string_t *project_name,
   *		long change_number);
   *
   * DESCRIPTION
--- 861,940 ----
  
  /*
   * NAME
+  *	user_own_nth
+  *
+  * SYNOPSIS
+  *	int user_own_nth(user_ty *up, long n, long *change_number);
+  *
+  * DESCRIPTION
+  *	The user_own_nth function is used to fetch the n'th
+  *	change owned by a user.
+  *	The project name is derived from the user structure.
+  *
+  * ARGUMENTS
+  *	up		- pointer to user structure
+  *	n		- selector
+  *	change_number	- pointer to where to put number of the change
+  *
+  * RETURNS
+  *	1 on sucess, 0 if no such n.
+  */
+ 
+ int
+ user_own_nth(up, n, change_number)
+ 	user_ty		*up;
+ 	long		n;
+ 	long		*change_number;
+ {
+ 	ustate		ustate_data;
+ 	int		j;
+ 	int		result;
+ 
+ 	trace(("user_own_nth(up = %08lX, n = %ld)\n{\n"/*}*/, (long)up, n));
+ 	result = 0;
+ 	assert(n >= 0);
+ 	assert(up->pp);
+ 	if (n < 0 || !up->pp)
+ 		goto done;
+ 	ustate_data = user_ustate_get(up);
+ 	assert(ustate_data->own);
+ 
+ 	/*
+ 	 * find the relevant project
+ 	 *	and extract the n'th change
+ 	 */
+ 	for (j = 0; j < ustate_data->own->length; ++j)
+ 	{
+ 		ustate_own	own_data;
+ 
+ 		own_data = ustate_data->own->list[j];
+ 		if (str_equal(project_name_get(up->pp), own_data->project_name))
+ 		{
+ 			if (n < own_data->changes->length)
+ 			{
+ 				*change_number = own_data->changes->list[n];
+ 				result = 1;
+ 			}
+ 			break;
+ 		}
+ 	}
+ 
+ 	/*
+ 	 * here for all exits
+ 	 */
+ 	done:
+ 	trace(("return %d;\n", result));
+ 	trace((/*{*/"}\n"));
+ 	return result;
+ }
+ 
+ 
+ /*
+  * NAME
   *	user_own_remove
   *
   * SYNOPSIS
!  *	void user_own_remove(user_ty *up, string_ty *project_name,
   *		long change_number);
   *
   * DESCRIPTION
***************
*** 872,879 ****
  
  void
  user_own_remove(up, project_name, change_number)
! 	user_t		*up;
! 	string_t	*project_name;
  	long		change_number;
  {
  	ustate		ustate_data;
--- 952,959 ----
  
  void
  user_own_remove(up, project_name, change_number)
! 	user_ty		*up;
! 	string_ty	*project_name;
  	long		change_number;
  {
  	ustate		ustate_data;
***************
*** 900,906 ****
  	 * Create the ``changes'' list for the project, if necessary.
  	 */
  	if (!own_data->changes)
! 		own_data->changes = ustate_own_changes_list_type.alloc();
  
  	/*
  	 * Search for the change in the ``changes'' list.
--- 980,988 ----
  	 * Create the ``changes'' list for the project, if necessary.
  	 */
  	if (!own_data->changes)
! 		own_data->changes =
! 			(ustate_own_changes_list)
! 			ustate_own_changes_list_type.alloc();
  
  	/*
  	 * Search for the change in the ``changes'' list.
***************
*** 948,954 ****
   *	user_ustate_lock_prepare
   *
   * SYNOPSIS
!  *	void user_ustate_lock_prepare(user_t *up);
   *
   * DESCRIPTION
   *	The user_ustate_lock_prepare function is used to
--- 1030,1036 ----
   *	user_ustate_lock_prepare
   *
   * SYNOPSIS
!  *	void user_ustate_lock_prepare(user_ty *up);
   *
   * DESCRIPTION
   *	The user_ustate_lock_prepare function is used to
***************
*** 960,966 ****
  
  void
  user_ustate_lock_prepare(up)
! 	user_t		*up;
  {
  	trace(("user_ustate_lock_prepare(up = %08lX)\n{\n"/*}*/, up));
  	lock_prepare_ustate(up->uid);
--- 1042,1048 ----
  
  void
  user_ustate_lock_prepare(up)
! 	user_ty		*up;
  {
  	trace(("user_ustate_lock_prepare(up = %08lX)\n{\n"/*}*/, up));
  	lock_prepare_ustate(up->uid);
***************
*** 973,979 ****
   *	user_default_change
   *
   * SYNOPSIS
!  *	long user_default_change(user_t *up);
   *
   * DESCRIPTION
   *	The user_default_change function is used to
--- 1055,1061 ----
   *	user_default_change
   *
   * SYNOPSIS
!  *	long user_default_change(user_ty *up);
   *
   * DESCRIPTION
   *	The user_default_change function is used to
***************
*** 990,1023 ****
   *	it is a fatal error if there is no default change number
   */
  
  long
  user_default_change(up)
! 	user_t		*up;
  {
- 	ustate		ustate_data;
- 	int		j;
  	long		change_number;
  
  	/*
  	 * If the user is only working on one change within the given
! 	 * product, then that is the change.
  	 */
! 	trace(("user_default_change(up = %08lX)\n{\n"/*}*/, up));
! 	change_number = 0;
! 	ustate_data = user_ustate_get(up);
! 	assert(ustate_data->own);
! 	for (j = 0; j < ustate_data->own->length; ++j)
  	{
! 		ustate_own	own_data;
! 		string_t	*project_name;
  
! 		own_data = ustate_data->own->list[j];
! 		project_name = project_name_get(up->pp);
! 		if (str_equal(own_data->project_name, project_name))
  		{
! 			if (own_data->changes->length == 1)
! 				change_number = own_data->changes->list[0];
! 			break;
  		}
  	}
  
--- 1072,1169 ----
   *	it is a fatal error if there is no default change number
   */
  
+ static int is_a_change_number _((char *, long *));
+ 
+ static int
+ is_a_change_number(s, answer)
+ 	char		*s;
+ 	long		*answer;
+ {
+ 	long		n;
+ 
+ 	while (isspace(*s))
+ 		++s;
+ 	n = 0;
+ 	while (isdigit(*s))
+ 		n = n * 10 + *s++ - '0';
+ 	if (n < 1)
+ 		return 0;
+ 	while (isspace(*s))
+ 		++s;
+ 	if (*s)
+ 		return 0;
+ 	*answer = n;
+ 	return 1;
+ }
+ 
  long
  user_default_change(up)
! 	user_ty		*up;
  {
  	long		change_number;
+ 	string_ty	*s1;
+ 	string_ty	*s2;
+ 	char		*cp;
  
+ 	trace(("user_default_change(up = %08lX)\n{\n"/*}*/, up));
+ 	change_number = 0;
+ 
  	/*
+ 	 * check the AEGIS_CHANGE environment variable
+ 	 */
+ 	s1 = str_format("%s_change", option_get_progname());
+ 	s2 = str_upcase(s1);
+ 	str_free(s1);
+ 	cp = getenv(s2->str_text);
+ 	if (cp)
+ 	{
+ 		if (!is_a_change_number(cp, &change_number))
+ 		{
+ 			fatal
+ 			(
+ 		"the %s environment variable must be a positive decimal number",
+ 				s2->str_text
+ 			);
+ 		}
+ 	}
+ 	str_free(s2);
+ 
+ 	/*
+ 	 * check the $HOME/.aegisrc file
+ 	 */
+ 	if (!change_number)
+ 	{
+ 		uconf		uconf_data;
+ 
+ 		uconf_data = user_uconf_get(up);
+ 		if (uconf_data->mask & uconf_default_change_number_mask)
+ 			change_number = uconf_data->default_change_number;
+ 	}
+ 
+ 	/*
  	 * If the user is only working on one change within the given
! 	 * project, then that is the change.
  	 */
! 	if (!change_number)
  	{
! 		ustate		ustate_data;
! 		int		j;
  
! 		ustate_data = user_ustate_get(up);
! 		assert(ustate_data->own);
! 		for (j = 0; j < ustate_data->own->length; ++j)
  		{
! 			ustate_own	own_data;
! 			string_ty	*project_name;
! 	
! 			own_data = ustate_data->own->list[j];
! 			project_name = project_name_get(up->pp);
! 			if (str_equal(own_data->project_name, project_name))
! 			{
! 				if (own_data->changes->length == 1)
! 					change_number = own_data->changes->list[0];
! 				break;
! 			}
  		}
  	}
  
***************
*** 1025,1031 ****
  	 * It is an error if no change number has been given.
  	 */
  	if (!change_number)
! 		fatal("no -Change option specified");
  	trace(("return %d;\n", change_number));
  	trace((/*{*/"}\n"));
  	return change_number;
--- 1171,1177 ----
  	 * It is an error if no change number has been given.
  	 */
  	if (!change_number)
! 		project_fatal(up->pp, "no -Change option specified");
  	trace(("return %d;\n", change_number));
  	trace((/*{*/"}\n"));
  	return change_number;
***************
*** 1050,1077 ****
   *	it is a fatal error if there is no default project name
   */
  
! string_t *
  user_default_project()
  {
! 	string_t	*result;
! 	wlist		name;
! 	user_t		*up;
  
  	/*
  	 * build a temporary user
  	 */
  	trace(("user_default_project()\n{\n"/*}*/));
! 	up = user_executing((project_t *)0);
  
  	/*
! 	 * check the search path, see if we use just one
  	 */
! 	gonzo_project_list_user(up->name, &name);
! 	if (name.wl_nwords == 1)
! 		result = str_copy(name.wl_word[0]);
! 	else
! 		result = 0;
! 	wl_free(&name);
  
  	/*
  	 * From the $HOME/.aegisrc file.
--- 1196,1227 ----
   *	it is a fatal error if there is no default project name
   */
  
! string_ty *
  user_default_project()
  {
! 	string_ty	*result;
! 	user_ty		*up;
! 	string_ty	*s1;
! 	string_ty	*s2;
! 	char		*cp;
  
  	/*
  	 * build a temporary user
  	 */
  	trace(("user_default_project()\n{\n"/*}*/));
! 	up = user_executing((project_ty *)0);
! 	result = 0;
  
  	/*
! 	 * from the AEGIS_PROJECT environment variable.
  	 */
! 	s1 = str_format("%s_project", option_get_progname());
! 	s2 = str_upcase(s1);
! 	str_free(s1);
! 	cp = getenv(s2->str_text);
! 	str_free(s2);
! 	if (cp && *cp)
! 		result = str_from_c(cp);
  
  	/*
  	 * From the $HOME/.aegisrc file.
***************
*** 1086,1091 ****
--- 1236,1254 ----
  	}
  
  	/*
+ 	 * check the search path, see if we use just one
+ 	 */
+ 	if (!result)
+ 	{
+ 		wlist		name;
+ 
+ 		gonzo_project_list_user(up->name, &name);
+ 		if (name.wl_nwords == 1)
+ 			result = str_copy(name.wl_word[0]);
+ 		wl_free(&name);
+ 	}
+ 
+ 	/*
  	 * It is an error if no project name has been given.
  	 */
  	if (!result)
***************
*** 1106,1112 ****
   *	user_default_development_directory_get
   *
   * SYNOPSIS
!  *	string_t *user_default_development_directory_get(user_t *up);
   *
   * DESCRIPTION
   *	The user_default_development_directory_get function is used to
--- 1269,1275 ----
   *	user_default_development_directory_get
   *
   * SYNOPSIS
!  *	string_ty *user_default_development_directory_get(user_ty *up);
   *
   * DESCRIPTION
   *	The user_default_development_directory_get function is used to
***************
*** 1124,1162 ****
   *	the user's home directory will be returned.
   */
  
! string_t *
  user_default_development_directory(up)
! 	user_t		*up;
  {
  	uconf		uconf_data;
! 	string_t	*path;
! 	string_t	*s;
  
  	uconf_data = user_uconf_get(up);
! 	s = uconf_data->default_development_directory;
! 	if (s)
  	{
! 		user_become(up);
! 		if (s->str_text[0] == '/')
! 			path = os_pathname(s);
  		else
! 		{
! 			s = str_format("%S/%S", user_home(up), s);
! 			path = os_pathname(s);
! 			str_free(s);
! 		}
! 		user_become_undo();
  	}
  	else
  	{
  		path = project_default_development_directory(up->pp);
  		if (!path)
- 		{
  			path = user_home(up);
! 			user_become(up);
! 			path = os_pathname(path);
! 			user_become_undo();
! 		}
  	}
  	return path;
  }
--- 1287,1321 ----
   *	the user's home directory will be returned.
   */
  
! string_ty *
  user_default_development_directory(up)
! 	user_ty		*up;
  {
  	uconf		uconf_data;
! 	string_ty	*path;
  
+ 	/*
+ 	 * To cope with automounters, directories are stored as given,
+ 	 * or are derived from the home directory in the passwd file.
+ 	 * Within aegis, pathnames have their symbolic links resolved,
+ 	 * and any comparison of paths is done on this "system idea"
+ 	 * of the pathname.
+ 	 */
  	uconf_data = user_uconf_get(up);
! 	path = uconf_data->default_development_directory;
! 	if (path)
  	{
! 		if (path->str_text[0] == '/')
! 			path = str_copy(path);
  		else
! 			path = str_format("%S/%S", user_home(up), path);
  	}
  	else
  	{
  		path = project_default_development_directory(up->pp);
  		if (!path)
  			path = user_home(up);
! 		path = str_copy(path);
  	}
  	return path;
  }
***************
*** 1184,1215 ****
   *	the user's home directory will be returned.
   */
  
! string_t *
  user_default_project_directory(up)
! 	user_t		*up;
  {
  	uconf		uconf_data;
! 	string_t	*path;
! 	string_t	*s;
  
  	trace(("user_default_project_directory(up = %08lX)\n{\n"/*}*/, up));
  	uconf_data = user_uconf_get(up);
! 	user_become(up);
! 	s = uconf_data->default_project_directory;
! 	if (s)
  	{
! 		if (s->str_text[0] == '/')
! 			path = os_pathname(s);
  		else
! 		{
! 			s = str_format("%S/%S", user_home(up), s);
! 			path = os_pathname(s);
! 			str_free(s);
! 		}
  	}
  	else
! 		path = os_pathname(user_home(up));
! 	user_become_undo();
  	trace(("return \"%s\";\n", path->str_text));
  	trace((/*{*/"}\n"));
  	return path;
--- 1343,1374 ----
   *	the user's home directory will be returned.
   */
  
! string_ty *
  user_default_project_directory(up)
! 	user_ty		*up;
  {
  	uconf		uconf_data;
! 	string_ty	*path;
  
+ 	/*
+ 	 * To cope with automounters, directories are stored as given,
+ 	 * or are derived from the home directory in the passwd file.
+ 	 * Within aegis, pathnames have their symbolic links resolved,
+ 	 * and any comparison of paths is done on this "system idea"
+ 	 * of the pathname.
+ 	 */
  	trace(("user_default_project_directory(up = %08lX)\n{\n"/*}*/, up));
  	uconf_data = user_uconf_get(up);
! 	path = uconf_data->default_project_directory;
! 	if (path)
  	{
! 		if (path->str_text[0] == '/')
! 			path = str_copy(path);
  		else
! 			path = str_format("%S/%S", user_home(up), path);
  	}
  	else
! 		path = str_copy(user_home(up));
  	trace(("return \"%s\";\n", path->str_text));
  	trace((/*{*/"}\n"));
  	return path;
***************
*** 1241,1247 ****
  
  int
  user_uid_check(name)
! 	string_t	*name;
  {
  	struct passwd	*pw;
  
--- 1400,1406 ----
  
  int
  user_uid_check(name)
! 	string_ty	*name;
  {
  	struct passwd	*pw;
  
***************
*** 1248,1254 ****
  	pw = getpwnam(name->str_text);
  	if (!pw)
  		fatal("user \"%s\" unknown", name->str_text);
! 	return (pw->pw_uid >= 100);
  }
  
  
--- 1407,1413 ----
  	pw = getpwnam(name->str_text);
  	if (!pw)
  		fatal("user \"%s\" unknown", name->str_text);
! 	return (pw->pw_uid >= AEGIS_MIN_UID);
  }
  
  
***************
*** 1277,1283 ****
  
  int
  user_gid_check(name)
! 	string_t	*name;
  {
  	struct group	*gr;
  
--- 1436,1442 ----
  
  int
  user_gid_check(name)
! 	string_ty	*name;
  {
  	struct group	*gr;
  
***************
*** 1284,1290 ****
  	gr = getgrnam(name->str_text);
  	if (!gr)
  		fatal("group \"%s\" unknown", name->str_text);
! 	return (gr->gr_gid >= 10);
  }
  
  
--- 1443,1449 ----
  	gr = getgrnam(name->str_text);
  	if (!gr)
  		fatal("group \"%s\" unknown", name->str_text);
! 	return (gr->gr_gid >= AEGIS_MIN_GID);
  }
  
  
***************
*** 1293,1299 ****
   *	user_become
   *
   * SYNOPSIS
!  *	void user_become(user_t *up);
   *
   * DESCRIPTION
   *	The user_become function is used to
--- 1452,1458 ----
   *	user_become
   *
   * SYNOPSIS
!  *	void user_become(user_ty *up);
   *
   * DESCRIPTION
   *	The user_become function is used to
***************
*** 1308,1314 ****
  
  void
  user_become(up)
! 	user_t	*up;
  {
  	trace(("user_become(up = %08lX)\n{\n"/*}*/, up));
  	os_become(up->uid, up->gid, up->umask);
--- 1467,1473 ----
  
  void
  user_become(up)
! 	user_ty		*up;
  {
  	trace(("user_become(up = %08lX)\n{\n"/*}*/, up));
  	os_become(up->uid, up->gid, up->umask);
Index: aegis/user.h
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 26,48 ****
  #include <ustate.h>
  #include <uconf.h>
  
! typedef struct user_t user_t;
! struct user_t
  {
  	long		reference_count;
! 	struct project_t *pp;
! 	string_t	*name;
! 	string_t	*full_name;
! 	string_t	*home;
! 	string_t	*group;
  	int		uid;
  	int		gid;
  	int		umask;
! 	string_t	*ustate_path;
  	ustate		ustate_data;
  	int		ustate_is_new;
  	int		ustate_modified;
! 	string_t	*uconf_path;
  	uconf		uconf_data;
  	long		lock_magic;
  	/*
--- 26,48 ----
  #include <ustate.h>
  #include <uconf.h>
  
! typedef struct user_ty user_ty;
! struct user_ty
  {
  	long		reference_count;
! 	struct project_ty *pp;
! 	string_ty	*name;
! 	string_ty	*full_name;
! 	string_ty	*home;
! 	string_ty	*group;
  	int		uid;
  	int		gid;
  	int		umask;
! 	string_ty	*ustate_path;
  	ustate		ustate_data;
  	int		ustate_is_new;
  	int		ustate_modified;
! 	string_ty	*uconf_path;
  	uconf		uconf_data;
  	long		lock_magic;
  	/*
***************
*** 52,92 ****
  };
  
  
! user_t *user_numeric _((struct project_t *pp, int uid));
! user_t *user_symbolic _((struct project_t *pp, string_t *user_name));
! user_t *user_executing _((struct project_t *));
! void user_free _((user_t *));
! user_t *user_copy _((user_t *));
  
! string_t *user_name _((user_t *));
! int user_id _((user_t *));
! int user_gid _((user_t *));
! int user_umask _((user_t *));
  
! void user_ustate_lock_prepare _((user_t *));
  
! string_t *user_group _((user_t *));
  
! string_t *user_home _((user_t *));
  
! char *user_full_name _((string_t *));
  
! void user_ustate_write _((user_t *));
  
! void user_own_add _((user_t *up, struct string_t *project_name,
  	long change_number));
! 
! void user_own_remove _((user_t *, struct string_t *project_name,
  	long change_number));
  
! long user_default_change _((user_t *));
! string_t *user_default_project _((void));
! string_t *user_default_development_directory _((user_t *));
! string_t *user_default_project_directory _((user_t *));
  
! int user_uid_check _((string_t *));
! int user_gid_check _((string_t *));
! void user_become _((user_t *));
  void user_become_undo _((void));
  
  #endif /* USER_H */
--- 52,92 ----
  };
  
  
! user_ty *user_numeric _((struct project_ty *pp, int uid));
! user_ty *user_symbolic _((struct project_ty *pp, string_ty *user_name));
! user_ty *user_executing _((struct project_ty *));
! void user_free _((user_ty *));
! user_ty *user_copy _((user_ty *));
  
! string_ty *user_name _((user_ty *));
! int user_id _((user_ty *));
! int user_gid _((user_ty *));
! int user_umask _((user_ty *));
  
! void user_ustate_lock_prepare _((user_ty *));
  
! string_ty *user_group _((user_ty *));
  
! string_ty *user_home _((user_ty *));
  
! char *user_full_name _((string_ty *));
  
! void user_ustate_write _((user_ty *));
  
! void user_own_add _((user_ty *up, struct string_ty *project_name,
  	long change_number));
! int user_own_nth _((user_ty *up, long n, long *change_number));
! void user_own_remove _((user_ty *, struct string_ty *project_name,
  	long change_number));
  
! long user_default_change _((user_ty *));
! string_ty *user_default_project _((void));
! string_ty *user_default_development_directory _((user_ty *));
! string_ty *user_default_project_directory _((user_ty *));
  
! int user_uid_check _((string_ty *));
! int user_gid_check _((string_ty *));
! void user_become _((user_ty *));
  void user_become_undo _((void));
  
  #endif /* USER_H */
Index: aegis/ustate.def
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
Index: aegis/version.c
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 55,168 ****
  "		    GNU GENERAL PUBLIC LICENSE",
  "   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION",
  "",
! "  0. This License Agreement applies to any program or other work which",
! "contains a notice placed by the copyright holder saying it may be",
! "distributed under the terms of this General Public License.  The",
! "\"Program\", below, refers to any such program or work, and a \"work based",
! "on the Program\" means either the Program or any work containing the",
! "Program or a portion of it, either verbatim or with modifications.  Each",
! "licensee is addressed as \"you\".",
  "",
! "  1. You may copy and distribute verbatim copies of the %s Program's source",
! "code as you receive it, in any medium, provided that you conspicuously and",
! "appropriately publish on each copy an appropriate copyright notice and",
! "disclaimer of warranty; keep intact all the notices that refer to this",
! "General Public License and to the absence of any warranty; and give any",
! "other recipients of the %s Program a copy of this General Public License",
! "along with the %s Program.  You may charge a fee for the physical act of",
! "transferring a copy.",
  "",
! "  2. You may modify your copy or copies of the %s Program or any portion of",
! "it, and copy and distribute such modifications under the terms of Paragraph",
! "1 above, provided that you also do the following:",
  "",
! "    a) cause the modified files to carry prominent notices stating that",
! "    you changed the files and the date of any change; and",
  "",
! "    b) cause the whole of any work that you distribute or publish, that",
! "    in whole or in part contains the %s Program or any part thereof, either",
! "    with or without modifications, to be licensed at no charge to all",
! "    third parties under the terms of this General Public License (except",
! "    that you may choose to grant warranty protection to some or all",
! "    third parties, at your option).",
  "",
! "    c) If the modified program normally reads commands interactively when",
! "    run, you must cause it, when started running for such interactive use",
! "    in the simplest and most usual way, to print or display an",
! "    announcement including an appropriate copyright notice and a notice",
! "    that there is no warranty (or else, saying that you provide a",
! "    warranty) and that users may redistribute the program under these",
! "    conditions, and telling the user how to view a copy of this General",
! "    Public License.",
  "",
! "    d) You may charge a fee for the physical act of transferring a",
! "    copy, and you may at your option offer warranty protection in",
! "    exchange for a fee.",
  "",
! "Mere aggregation of another independent work with the %s Program (or its",
! "derivative) on a volume of a storage or distribution medium does not bring",
! "the other work under the scope of these terms.",
  "",
! "  3. You may copy and distribute the %s Program (or a portion or derivative of",
! "it, under Paragraph 2) in object code or executable form under the terms of",
! "Paragraphs 1 and 2 above provided that you also do one of the following:",
  "",
! "    a) accompany it with the complete corresponding machine-readable",
! "    source code, which must be distributed under the terms of",
! "    Paragraphs 1 and 2 above; or,",
  "",
! "    b) accompany it with a written offer, valid for at least three",
! "    years, to give any third party free (except for a nominal charge",
! "    for the cost of distribution) a complete machine-readable copy of the",
! "    corresponding source code, to be distributed under the terms of",
! "    Paragraphs 1 and 2 above; or,",
  "",
! "    c) accompany it with the information you received as to where the",
! "    corresponding source code may be obtained.  (This alternative is",
  "    allowed only for noncommercial distribution and only if you",
! "    received the program in object code or executable form alone.)",
  "",
! "Source code for a work means the preferred form of the work for making",
! "modifications to it.  For an executable file, complete source code means",
! "all the source code for all modules it contains; but, as a special",
! "exception, it need not include source code for modules which are standard",
! "libraries that accompany the operating system on which the executable",
! "file runs, or for standard header files or definitions files that",
! "accompany that operating system.",
  "",
! "  4. You may not copy, modify, sublicense, distribute or transfer the",
! "%s Program except as expressly provided under this General Public License.",
! "Any attempt otherwise to copy, modify, sublicense, distribute or transfer",
! "the %s Program is void, and will automatically terminate your rights to use",
! "the %s Program under this License.  However, parties who have received",
! "copies, or rights to use copies, from you under this General Public",
! "License will not have their licenses terminated so long as such parties",
! "remain in full compliance.",
  "",
! "  5. By copying, distributing or modifying the %s Program (or any work based",
! "on the %s Program) you indicate your acceptance of this license to do so,",
! "and all its terms and conditions.",
  "",
! "  6. Each time you redistribute the %s Program (or any work based on the",
! "%s Program), the recipient automatically receives a license from the original",
! "licensor to copy, distribute or modify the %s Program subject to these",
! "terms and conditions.  You may not impose any further restrictions on the",
! "recipients' exercise of the rights granted herein.",
  "",
! "  7. The Free Software Foundation may publish revised and/or new versions",
  "of the General Public License from time to time.  Such new versions will",
  "be similar in spirit to the present version, but may differ in detail to",
  "address new problems or concerns.",
  "",
! "Each version is given a distinguishing version number.  If the %s Program",
! "specifies a version number of the license which applies to it and \"any",
  "later version\", you have the option of following the terms and conditions",
  "either of that version or of any later version published by the Free",
! "Software Foundation.  If the %s Program does not specify a version number of",
! "the license, you may choose any version ever published by the Free Software",
  "Foundation.",
  "",
! "  8. If you wish to incorporate parts of the %s Program into other free",
  "programs whose distribution conditions are different, write to the author",
  "to ask for permission.  For software which is copyrighted by the Free",
  "Software Foundation, write to the Free Software Foundation; we sometimes",
--- 55,249 ----
  "		    GNU GENERAL PUBLIC LICENSE",
  "   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION",
  "",
! "  0. This License applies to any program or other work which contains",
! "a notice placed by the copyright holder saying it may be distributed",
! "under the terms of this General Public License.  The \"Program\", below,",
! "refers to any such program or work, and a \"work based on the Program\"",
! "means either the Program or any derivative work under copyright law:",
! "that is to say, a work containing the Program or a portion of it,",
! "either verbatim or with modifications and/or translated into another",
! "language.  (Hereinafter, translation is included without limitation in",
! "the term \"modification\".)  Each licensee is addressed as \"you\".",
  "",
! "Activities other than copying, distribution and modification are not",
! "covered by this License; they are outside its scope.  The act of",
! "running the Program is not restricted, and the output from the Program",
! "is covered only if its contents constitute a work based on the",
! "Program (independent of having been made by running the Program).",
! "Whether that is true depends on what the Program does.",
  "",
! "  1. You may copy and distribute verbatim copies of the Program's",
! "source code as you receive it, in any medium, provided that you",
! "conspicuously and appropriately publish on each copy an appropriate",
! "copyright notice and disclaimer of warranty; keep intact all the",
! "notices that refer to this License and to the absence of any warranty;",
! "and give any other recipients of the Program a copy of this License",
! "along with the Program.",
  "",
! "You may charge a fee for the physical act of transferring a copy, and",
! "you may at your option offer warranty protection in exchange for a fee.",
  "",
! "  2. You may modify your copy or copies of the Program or any portion",
! "of it, thus forming a work based on the Program, and copy and",
! "distribute such modifications or work under the terms of Section 1",
! "above, provided that you also meet all of these conditions:",
  "",
! "    a) You must cause the modified files to carry prominent notices",
! "    stating that you changed the files and the date of any change.",
  "",
! "    b) You must cause any work that you distribute or publish, that in",
! "    whole or in part contains or is derived from the Program or any",
! "    part thereof, to be licensed as a whole at no charge to all third",
! "    parties under the terms of this License.",
  "",
! "    c) If the modified program normally reads commands interactively",
! "    when run, you must cause it, when started running for such",
! "    interactive use in the most ordinary way, to print or display an",
! "    announcement including an appropriate copyright notice and a",
! "    notice that there is no warranty (or else, saying that you provide",
! "    a warranty) and that users may redistribute the program under",
! "    these conditions, and telling the user how to view a copy of this",
! "    License.  (Exception: if the Program itself is interactive but",
! "    does not normally print such an announcement, your work based on",
! "    the Program is not required to print an announcement.)",
  "",
! "These requirements apply to the modified work as a whole.  If",
! "identifiable sections of that work are not derived from the Program,",
! "and can be reasonably considered independent and separate works in",
! "themselves, then this License, and its terms, do not apply to those",
! "sections when you distribute them as separate works.  But when you",
! "distribute the same sections as part of a whole which is a work based",
! "on the Program, the distribution of the whole must be on the terms of",
! "this License, whose permissions for other licensees extend to the",
! "entire whole, and thus to each and every part regardless of who wrote it.",
  "",
! "Thus, it is not the intent of this section to claim rights or contest",
! "your rights to work written entirely by you; rather, the intent is to",
! "exercise the right to control the distribution of derivative or",
! "collective works based on the Program.",
  "",
! "In addition, mere aggregation of another work not based on the Program",
! "with the Program (or with a work based on the Program) on a volume of",
! "a storage or distribution medium does not bring the other work under",
! "the scope of this License.",
  "",
! "  3. You may copy and distribute the Program (or a work based on it,",
! "under Section 2) in object code or executable form under the terms of",
! "Sections 1 and 2 above provided that you also do one of the following:",
! "",
! "    a) Accompany it with the complete corresponding machine-readable",
! "    source code, which must be distributed under the terms of Sections",
! "    1 and 2 above on a medium customarily used for software interchange; or,",
! "",
! "    b) Accompany it with a written offer, valid for at least three",
! "    years, to give any third party, for a charge no more than your",
! "    cost of physically performing source distribution, a complete",
! "    machine-readable copy of the corresponding source code, to be",
! "    distributed under the terms of Sections 1 and 2 above on a medium",
! "    customarily used for software interchange; or,",
! "",
! "    c) Accompany it with the information you received as to the offer",
! "    to distribute corresponding source code.  (This alternative is",
  "    allowed only for noncommercial distribution and only if you",
! "    received the program in object code or executable form with such",
! "    an offer, in accord with Subsection b above.)",
  "",
! "The source code for a work means the preferred form of the work for",
! "making modifications to it.  For an executable work, complete source",
! "code means all the source code for all modules it contains, plus any",
! "associated interface definition files, plus the scripts used to",
! "control compilation and installation of the executable.  However, as a",
! "special exception, the source code distributed need not include",
! "anything that is normally distributed (in either source or binary",
! "form) with the major components (compiler, kernel, and so on) of the",
! "operating system on which the executable runs, unless that component",
! "itself accompanies the executable.",
  "",
! "If distribution of executable or object code is made by offering",
! "access to copy from a designated place, then offering equivalent",
! "access to copy the source code from the same place counts as",
! "distribution of the source code, even though third parties are not",
! "compelled to copy the source along with the object code.",
  "",
! "  4. You may not copy, modify, sublicense, or distribute the Program",
! "except as expressly provided under this License.  Any attempt",
! "otherwise to copy, modify, sublicense or distribute the Program is",
! "void, and will automatically terminate your rights under this License.",
! "However, parties who have received copies, or rights, from you under",
! "this License will not have their licenses terminated so long as such",
! "parties remain in full compliance.",
  "",
! "  5. You are not required to accept this License, since you have not",
! "signed it.  However, nothing else grants you permission to modify or",
! "distribute the Program or its derivative works.  These actions are",
! "prohibited by law if you do not accept this License.  Therefore, by",
! "modifying or distributing the Program (or any work based on the",
! "Program), you indicate your acceptance of this License to do so, and",
! "all its terms and conditions for copying, distributing or modifying",
! "the Program or works based on it.",
  "",
! "  6. Each time you redistribute the Program (or any work based on the",
! "Program), the recipient automatically receives a license from the",
! "original licensor to copy, distribute or modify the Program subject to",
! "these terms and conditions.  You may not impose any further",
! "restrictions on the recipients' exercise of the rights granted herein.",
! "You are not responsible for enforcing compliance by third parties to",
! "this License.",
! "",
! "  7. If, as a consequence of a court judgment or allegation of patent",
! "infringement or for any other reason (not limited to patent issues),",
! "conditions are imposed on you (whether by court order, agreement or",
! "otherwise) that contradict the conditions of this License, they do not",
! "excuse you from the conditions of this License.  If you cannot",
! "distribute so as to satisfy simultaneously your obligations under this",
! "License and any other pertinent obligations, then as a consequence you",
! "may not distribute the Program at all.  For example, if a patent",
! "license would not permit royalty-free redistribution of the Program by",
! "all those who receive copies directly or indirectly through you, then",
! "the only way you could satisfy both it and this License would be to",
! "refrain entirely from distribution of the Program.",
! "",
! "If any portion of this section is held invalid or unenforceable under",
! "any particular circumstance, the balance of the section is intended to",
! "apply and the section as a whole is intended to apply in other",
! "circumstances.",
! "",
! "It is not the purpose of this section to induce you to infringe any",
! "patents or other property right claims or to contest validity of any",
! "such claims; this section has the sole purpose of protecting the",
! "integrity of the free software distribution system, which is",
! "implemented by public license practices.  Many people have made",
! "generous contributions to the wide range of software distributed",
! "through that system in reliance on consistent application of that",
! "system; it is up to the author/donor to decide if he or she is willing",
! "to distribute software through any other system and a licensee cannot",
! "impose that choice.",
! "",
! "This section is intended to make thoroughly clear what is believed to",
! "be a consequence of the rest of this License.",
! "",
! "  8. If the distribution and/or use of the Program is restricted in",
! "certain countries either by patents or by copyrighted interfaces, the",
! "original copyright holder who places the Program under this License",
! "may add an explicit geographical distribution limitation excluding",
! "those countries, so that distribution is permitted only in or among",
! "countries not thus excluded.  In such case, this License incorporates",
! "the limitation as if written in the body of this License.",
! "",
! "  9. The Free Software Foundation may publish revised and/or new versions",
  "of the General Public License from time to time.  Such new versions will",
  "be similar in spirit to the present version, but may differ in detail to",
  "address new problems or concerns.",
  "",
! "Each version is given a distinguishing version number.  If the Program",
! "specifies a version number of this License which applies to it and \"any",
  "later version\", you have the option of following the terms and conditions",
  "either of that version or of any later version published by the Free",
! "Software Foundation.  If the Program does not specify a version number of",
! "this License, you may choose any version ever published by the Free Software",
  "Foundation.",
  "",
! "  10. If you wish to incorporate parts of the Program into other free",
  "programs whose distribution conditions are different, write to the author",
  "to ask for permission.  For software which is copyrighted by the Free",
  "Software Foundation, write to the Free Software Foundation; we sometimes",
***************
*** 181,203 ****
  {
  	static char *text[] =
  	{
! "			NO WARRANTY",
  "",
! "  9. BECAUSE THE %s PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY",
! "FOR THE %s PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN",
  "OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES",
! "PROVIDE THE %s PROGRAM \"AS IS\" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED",
  "OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF",
  "MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS",
  "TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE",
! "%s PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,",
  "REPAIR OR CORRECTION.",
  "",
! "  10. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING",
  "WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR",
! "REDISTRIBUTE THE %s PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,",
  "INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING",
! "OUT OF THE USE OR INABILITY TO USE THE %s PROGRAM (INCLUDING BUT NOT LIMITED",
  "TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY",
  "YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER",
  "PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE",
--- 262,284 ----
  {
  	static char *text[] =
  	{
! "			    NO WARRANTY",
  "",
! "  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY",
! "FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN",
  "OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES",
! "PROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED",
  "OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF",
  "MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS",
  "TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE",
! "PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,",
  "REPAIR OR CORRECTION.",
  "",
! "  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING",
  "WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR",
! "REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,",
  "INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING",
! "OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED",
  "TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY",
  "YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER",
  "PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE",
***************
*** 222,229 ****
  }
  
  
! typedef struct table_t table_t;
! struct table_t
  {
  	char	*name;
  	void	(*func)_((void));
--- 303,310 ----
  }
  
  
! typedef struct table_ty table_ty;
! struct table_ty
  {
  	char	*name;
  	void	(*func)_((void));
***************
*** 230,236 ****
  };
  
  
! static	table_t	table[] =
  {
  	{ "Copyright",		version_copyright,	},
  	{ "Redistribution",	version_redistribution,	},
--- 311,317 ----
  };
  
  
! static	table_ty	table[] =
  {
  	{ "Copyright",		version_copyright,	},
  	{ "Redistribution",	version_redistribution,	},
***************
*** 268,283 ****
  	if (name)
  	{
  		int		nhit;
! 		table_t		*tp;
! 		string_t	*s1;
! 		string_t	*s2;
! 		table_t		*hit[SIZEOF(table)];
  		int		j;
  
  		nhit = 0;
  		for (tp = table; tp < ENDOF(table); ++tp)
  		{
! 			if (argcmp(tp->name, name))
  				hit[nhit++] = tp;
  		}
  		switch (nhit)
--- 349,364 ----
  	if (name)
  	{
  		int		nhit;
! 		table_ty	*tp;
! 		string_ty	*s1;
! 		string_ty	*s2;
! 		table_ty	*hit[SIZEOF(table)];
  		int		j;
  
  		nhit = 0;
  		for (tp = table; tp < ENDOF(table); ++tp)
  		{
! 			if (arglex_compare(tp->name, name))
  				hit[nhit++] = tp;
  		}
  		switch (nhit)
***************
*** 352,361 ****
  "	-Help	This option may be used to obtain more",
  "		information about how to use the %s program.",
  "",
! "	All options are case insensitive.  Options may be",
! "	abbreviated; the abbreviation is the upper case letters.",
  "	Options and other command line arguments may be mixed",
! "	arbitrarily on the command line.",
  "",
  "RECOMMENDED ALIAS",
  "	The recommended alias for this command is",
--- 433,460 ----
  "	-Help	This option may be used to obtain more",
  "		information about how to use the %s program.",
  "",
! "	All options may be abbreviated; the abbreviation is",
! "	documented as the upper case letters, all lower case",
! "	letters and underscores (_) are optional.  You must use",
! "	consecutive sequences of optional letters.",
! "",
! "	All options are case insensitive, you may type them in",
! "	upper case or lower case or a combination of both, case",
! "	is not important.",
! "",
! "	For example: the arguments \"-project, \"-PROJ\" and \"-p\"",
! "	are all interpreted to mean the -Project option.  The",
! "	argument \"-prj\" will not be understood, because",
! "	consecutive optional characters were not supplied.",
! "",
  "	Options and other command line arguments may be mixed",
! "	arbitrarily on the command line, after the function",
! "	selectors.",
! "",
! "	The GNU long option names are understood.  Since all",
! "	option names for aegis are long, this means ignoring the",
! "	extra leading '-'.  The \"--option=value\" convention is",
! "	also understood.",
  "",
  "RECOMMENDED ALIAS",
  "	The recommended alias for this command is",
Index: aegis/version.h
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
Index: aux/ALPHA.man
***************
*** 1,12 ****
  '\" t
  .\"	aegis - project change supervisor
! .\"	Copyright (c) 1990-1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 1, or (at your option)
! .\"	any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  '\" t
  .\"	aegis - project change supervisor
! .\"	Copyright (C) 1991, 1992, 1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 2 of the License, or
! .\"	(at your option) any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 20,37 ****
  .\" MANIFEST: source for ALPHA file
  .\"
  .TH alpha aegis
! .hy 0
! .ad l
  .SH NAME
  aegis \- project change supervisor
  .br
! .if t .ds c) \(co
! .if n .ds c) (c)
! Copyright \*(c) 1990-1993 Peter Miller.
  .br
  All rights reserved.
  .PP
! The aegis program is distributed under the terms of the
  GNU General Public License.
  See the LICENSE section, below, for more details.
  .PP
--- 20,40 ----
  .\" MANIFEST: source for ALPHA file
  .\"
  .TH alpha aegis
! .if n .hy 0
! .if n .ad l
! .if n .nr IN 8n
  .SH NAME
  aegis \- project change supervisor
  .br
! .if t .ds C) \(co
! .if n .ds C) (C)
! Copyright \*(C) 1990, 1991, 1992, 1993 Peter Miller.
  .br
  All rights reserved.
  .PP
! The
! .I aegis
! program is distributed under the terms of the
  GNU General Public License.
  See the LICENSE section, below, for more details.
  .PP
***************
*** 41,47 ****
  a protection,
  a defence.
  .SH ALPHA SOFTWARE
! This is an alpha version of the aegis program.
  This means that it is not the final product,
  or even a Beta version.
  It probably has bugs,
--- 44,52 ----
  a protection,
  a defence.
  .SH ALPHA SOFTWARE
! This is an alpha version of the
! .I aegis
! program.
  This means that it is not the final product,
  or even a Beta version.
  It probably has bugs,
***************
*** 54,178 ****
  If you are still interested,
  the author would like to know the following:
  .TP
! 1. The Version Number
  .br
  In any information you send,
  please include the version number
! reported in the common/patchlevel.h file,
! or `aegis -vers` if you can get it to compile.
  .TP
! 2. The Archive Site
  .br
! When and where you obtained this version of aegis.
  If you tell me nothing else,
  tell me this (and, hopefully, why you did nothing else).
  .TP
! 3. Unpacking
  .br
! Did you have problems unpacking aegis?
  This probably isn't a problem with the .tar.Z distribution,
  but you could have obtained a shar format copy.
  .TP
! 4. Building
  .br
! Did you have problems building aegis?
  This could have been the instructions included,
  it could have been the Makefile,
  it could have been problems configuring it,
  or anything else.
  .TP
! 5. Testing
  .br
  Did you have problems with the tests?
! Yes, the aegis program comes with tests!
  You could have had problems running them,
  or some of them could have failed.
  If some tests fail but not others,
  please let me know
  .I which
  ones failed,
! and wether or not it was running set-uid-root at the time.
  .TP
! 6. Installation
  .br
! Did you have problems installing aegis?
  This could have been the instructions,
  or anything else.
  .PP
  At this point it would probably be a very good idea to print out the
  manual entries and read them carefully.
! It is a known flaw that the other documentation is horrible,
  it is something the author is working on "at this moment".
! Anyone especially good at writing documentation is invited to contribute,
! urgently!
  .TP
! 7. Using Aegis
  .br
! Did you have problems using aegis?
  This is a whole can of worms.
  If possible,
! include a shell script similar to the tests which accompany aegis,
  which reproduces the bug.
  Exit code 1 on failure (bug),
  exit code 0 on success (for when bug is fixed).
  .TP
! 8. The Source Code
  .br
  Did you read the code?
  Did you write some code?
  If you read the code and found problems,
  fixed them,
! or extended aegis,
  these contributions are most welcome.
! I reserved the right to "vet" and/or modify such contributions.
  .PP
  The above list is inclusive,
  not exclusive.
  Any and all feedback is greatly appreciated,
  as is the effort and interest required to produce it.
- .SH NOTE CHANGES
- The changes contained
- in this release make aegis.1.3 incompatible with aegis.1.2 and earlier.
- Some of the fields in the files have been altered.
- These can be fixed with a text editor,
- or simple UNIX commands.
- The changes include:
- .TP 8n
- /usr/local/lib/aegis
  .br
! This directory,
! and all its contents,
! are now owned by
! .IR bin .
! Previous versions had these owned by
! .IR root .
! This also applies to users' libraries.
! .TP 8n
! \fIproject\fP/info/state
! .br
! The
! .I next_build_number
! field has been renamed to
! .IR next_delta_number .
! The
! .I build_number
! field of the
! .I history
! list has been changed to
! .IR delta_number .
! .TP 8n
! \fIproject\fP/info/change/*/*
! .br
! The
! .I diff_time
! field no longer exists,
! it should be deleted if it is present.
! The
! .I build_number
! field has been renamed to
! .IR delta_number .
  .SH SOME HISTORY
! The idea for aegis did not come full-blown into my head in the shower,
  as some of my programs do,
  but rather from working for a software shop
  which used a simplistic form of something similar.
--- 59,193 ----
  If you are still interested,
  the author would like to know the following:
  .TP
! 1. The type of UNIX
  .br
+ The author will need to know the type of UNIX you are using,
+ and sometimes what version,
+ or if it is not UNIX but something else.
+ The output of "uname -rs" is usually sufficent (but not all systems have it).
+ .TP
+ 2. The Version Number
+ .br
  In any information you send,
  please include the version number
! reported in the
! .I common/patchlevel.h
! file,
! or \f(CW`aegis -vers`\fP if you can get it to compile.
  .TP
! 3. The Archive Site
  .br
! When and where you obtained this version of
! .IR aegis .
  If you tell me nothing else,
  tell me this (and, hopefully, why you did nothing else).
  .TP
! 4. Unpacking
  .br
! Did you have problems unpacking
! .IR aegis ?
  This probably isn't a problem with the .tar.Z distribution,
  but you could have obtained a shar format copy.
  .TP
! 5. Building
  .br
! Did you have problems building
! .IR aegis ?
  This could have been the instructions included,
  it could have been the Makefile,
  it could have been problems configuring it,
  or anything else.
  .TP
! 6. Testing, Non-Set-Uid
  .br
  Did you have problems with the tests?
! Yes, the
! .I aegis
! program comes with tests!
  You could have had problems running them,
  or some of them could have failed.
  If some tests fail but not others,
  please let me know
  .I which
+ ones failed.
+ .TP
+ 7. Testing, Set-Uid-Root
+ .br
+ Did you have problems with the tests when
+ .I aegis
+ was set-uid-root?
+ You could have had problems running them,
+ or some of them could have failed.
+ If some tests fail but not others,
+ please let me know
+ .I which
  ones failed,
! and include the fact that
! .I aegis
! was set-uid-root at the time.
  .TP
! 8. Installation
  .br
! Did you have problems installing
! .IR aegis ?
  This could have been the instructions,
  or anything else.
  .PP
  At this point it would probably be a very good idea to print out the
  manual entries and read them carefully.
! You will also want to print a copy of the User Guide;
! if you don't gave groff,
! there should be a PostScript copy at the archive site.
! It is a known flaw that the User Guide is incomplete,
  it is something the author is working on "at this moment".
! (See the
! .I "PRINTED MANUALS"
! section of the
! .I BUILDING
! file for more details.)
  .TP
! 9. The Example Project
  .br
! After reading the User Guide,
! it is often useful to manually run through the example in chapter 3.
! You will need to do more than one change, hopefully several;
! the first change is not representative of the system.
! Did you manually do the example?
! Did you find flaws in the User Guide or manual entries?
! .TP
! 10. Using Aegis
! .br
! Did you have problems using
! .IR aegis ?
  This is a whole can of worms.
  If possible,
! include a shell script similar to the tests which accompany
! .IR aegis ,
  which reproduces the bug.
  Exit code 1 on failure (bug),
  exit code 0 on success (for when bug is fixed).
  .TP
! 11. The Source Code
  .br
  Did you read the code?
  Did you write some code?
  If you read the code and found problems,
  fixed them,
! or extended
! .IR aegis ,
  these contributions are most welcome.
! I reserve the right to modify or reject such contributions.
  .PP
  The above list is inclusive,
  not exclusive.
  Any and all feedback is greatly appreciated,
  as is the effort and interest required to produce it.
  .br
! .ne 1i
  .SH SOME HISTORY
! The idea for
! .I aegis
! did not come full-blown into my head in the shower,
  as some of my programs do,
  but rather from working for a software shop
  which used a simplistic form of something similar.
***************
*** 179,185 ****
  That system was held together by chewing-gum and string,
  it was written in a disgusting variant of Basic,
  and by golly the damn thing worked (mostly).
! Aegis is nothing like it,
  owes none of its code to that system,
  and is far more versatile.
  .PP
--- 194,202 ----
  That system was held together by chewing-gum and string,
  it was written in a disgusting variant of Basic,
  and by golly the damn thing worked (mostly).
! The
! .I aegis
! program is nothing like it,
  owes none of its code to that system,
  and is far more versatile.
  .PP
***************
*** 190,228 ****
  but always keeping in touch.
  With suggestions and conversations with
  some of them early in 1990,
! the manual entries for aegis took shape,
! and formed most of the design document for aegis.
  The rest of the design document will eventually appear
! in the "rationale" section of the user manual.
  .PP
! Since getting the first glimmerings of a functional aegis late in 1990 it
  is increasingly obvious that I never want to be without it ever again.
! All of my sources that I modify are instantly placed under aegis,
  as is anything I distribute.
  All code I write for myself,
  and all new code I write for my employer,
! goes under aegis.
  Why?
  Because it has fewer bugs!
  .PP
! Example: one of the sources I truck around from job to jobs is "cook",
! my make-oid (err, dependency maintenance tool).
! Cook had existed for 3 years before aegis appeared on the scene,
  and I used it daily.
! When I placed cook under aegis,
  I found 6 bugs!
  Since then I have found even more.
! Not only are there fewer bugs,
  but they never come back,
! because the regession test suite always grows!
  .SH LICENSE
! The aegis program is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
! the Free Software Foundation; either version 1, or (at your option)
! any later version.
  .PP
! The aegis program is distributed in the hope that it will be useful,
! but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  See the GNU General Public License for more details.
  .PP
--- 207,264 ----
  but always keeping in touch.
  With suggestions and conversations with
  some of them early in 1990,
! the manual entries for
! .I aegis
! took shape,
! and formed most of the design document for
! .IR aegis .
  The rest of the design document will eventually appear
! in the "model" section of the user manual.
  .PP
! Since getting the first glimmerings of a functional
! .I aegis
! late in 1990 it
  is increasingly obvious that I never want to be without it ever again.
! All of my sources that I modify are instantly placed under
! .IR aegis ,
  as is anything I distribute.
  All code I write for myself,
  and all new code I write for my employer,
! goes under
! .IR aegis .
  Why?
  Because it has fewer bugs!
  .PP
! Example: one of the sources I carry with me from job to job is "cook",
! my dependency maintenance tool.
! Cook had existed for 3 years before
! .I aegis
! appeared on the scene,
  and I used it daily.
! When I placed cook under
! .IR aegis ,
  I found 6 bugs!
  Since then I have found even more.
! Not only are there now fewer bugs,
  but they never come back,
! because the regession test suite always grows.
! .br
! .ne 1i
  .SH LICENSE
! The
! .I aegis
! program is free software;
! you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
! the Free Software Foundation;
! either version 2 of the License,
! or (at your option) any later version.
  .PP
! The
! .I aegis
! program is distributed in the hope that it will be useful,
! but WITHOUT ANY WARRANTY;
! without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  See the GNU General Public License for more details.
  .PP
***************
*** 229,239 ****
  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
! It should be in the COPYING file.
  .SH AUTHOR
  .TS
  tab(;);
  l l l.
  Peter Miller;UUCP;uunet!munnari!bmr.gov.au!pmiller
! \f(CW/\e/\e*\fR;CSNET;pmiller@bmr.gov.au
  .TE
--- 265,280 ----
  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
! .PP
! It should be in the
! .I LICENSE
! file included in this distribution.
! .br
! .ne 1i
  .SH AUTHOR
  .TS
  tab(;);
  l l l.
  Peter Miller;UUCP;uunet!munnari!bmr.gov.au!pmiller
! \f(CW/\e/\e*\fR;Internet;pmiller@bmr.gov.au
  .TE
Index: aux/BUILDING.man
***************
*** 1,12 ****
  '\" t
  .\"	aegis - project change supervisor
! .\"	Copyright (c) 1992-1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 1, or (at your option)
! .\"	any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  '\" t
  .\"	aegis - project change supervisor
! .\"	Copyright (C) 1992, 1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 2 of the License, or
! .\"	(at your option) any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 20,37 ****
  .\" MANIFEST: source for BUILDING file
  .\"
  .TH build aegis
! .hy 0
! .ad l
  .SH NAME
  aegis \- project change supervisor
  .br
! .if t .ds c) \(co
! .if n .ds c) (c)
! Copyright \*(c) 1990-1993 Peter Miller.
  .br
  All rights reserved.
  .PP
! The aegis program is distributed under the terms of the
  GNU General Public License.
  See the LICENSE section, below, for more details.
  .PP
--- 20,40 ----
  .\" MANIFEST: source for BUILDING file
  .\"
  .TH build aegis
! .if n .hy 0
! .if n .ad l
! .if n .nr IN 8n
  .SH NAME
  aegis \- project change supervisor
  .br
! .if t .ds C) \(co
! .if n .ds C) (C)
! Copyright \*(C) 1990, 1991, 1992, 1993 Peter Miller.
  .br
  All rights reserved.
  .PP
! The
! .I aegis
! program is distributed under the terms of the
  GNU General Public License.
  See the LICENSE section, below, for more details.
  .PP
***************
*** 41,56 ****
  a protection,
  a defence.
  .SH SPACE REQUIREMENTS
! You will need about 5MB to unpack and build the
  .I aegis
  program.
  Your mileage may vary.
  .SH SITE CONFIGURATION
  The file
  .I common/conf.h
! needs to be altered to match your site.
! The file of this name in the distribution matches the author's site,
! and probably will not suit yours.
  Select an appropriate file from the
  .I conf
  directory.
--- 44,60 ----
  a protection,
  a defence.
  .SH SPACE REQUIREMENTS
! You will need up to 10MB to unpack and build the
  .I aegis
  program.
+ (This is the worst case seen so far,
+ most systems have binaries about 60% as big as this,
+ 6MB is more typical.)
  Your mileage may vary.
  .SH SITE CONFIGURATION
  The file
  .I common/conf.h
! needs to be created to match your site.
  Select an appropriate file from the
  .I conf
  directory.
***************
*** 59,64 ****
--- 63,70 ----
  The file most closely resembling your system should be copied into the
  .I common/conf.h
  file.
+ You can copy it or use a symbolic link;
+ copying is recommended because you may need to edit.
  .PP
  The
  .I common/conf.h
***************
*** 73,78 ****
--- 79,92 ----
  In general these changes will relate to the name of your favorite
  C compiler,
  and where it keeps its include files.
+ .PP
+ The top of the
+ .I Makefile
+ file is arranged as macro definitions,
+ with alternatives for each known system in comments.
+ Search for your system's name,
+ editing the macro definition as required.
+ .br
  .ne 1i
  .SH KNOWN SYSTEMS
  This distribution of
***************
*** 86,91 ****
--- 100,110 ----
  and also
  .IR gcc (1)
  are known to work for Sun4s.
+ The appropriate configuration is contained in the
+ .I conf/SunOS-4.1
+ file.
+ Sun seem to be having chronic problems with locking;
+ you may need to get the very latest set of locking patches and apply them.
  .TP 8n
  ConvexOS 10.0
  .br
***************
*** 95,105 ****
--- 114,201 ----
  The appropriate configuration is contained in the
  .I conf/ConvexOS-10
  file.
+ Note that there is no "bin" user on ConvexOS,
+ so the owner of
+ .I aegis "'"
+ library files is "daemon";
+ you will need to map user and group "bin" to "daemon"
+ in the instructions below.
+ .TP 8n
+ DG/UX 5.4.1
+ .br
+ The native
+ .IR cc (1)
+ works just fine.
+ The appropriate configuration is contained in the
+ .I conf/dgux-5.4.1
+ file.
+ .TP 8n
+ ULTRIX 4.2
+ .br
+ It has the seteuid and setegid calls,
+ but the shell has no functions!
+ Complain to your vendor.
+ You will need to change the
+ .I SHELL
+ macro definition in the
+ .I Makefile
+ file to use
+ .IR sh5 (1)
+ instead.
+ The appropriate configuration is contained in the
+ .I conf/ULTRIX-4.2
+ file.
+ .TP 8n
+ Pyramid SMP DC/OSx 1.0-92b023
+ .br
+ This system is pretty horrendous.
+ Read the file
+ .I BUILDpyr
+ included in this distribution
+ for instruction how to configure
+ .IR aegis ,
+ then follow the rest of the instructions in this file.
+ The appropriate configuration is contained in the
+ .I conf/dcosx
+ file.
+ .TP 8n
+ HP-UX A.08.07
+ .br
+ The author has been advised that the
+ .I aegis
+ program works on this system.
+ Could another person confirm this, please.
+ The appropriate configuration is contained in the
+ .I conf/hpux-8.07
+ file.
+ .TP 8n
+ SCO 2.4
+ .br
+ The author has been advised that the
+ .I aegis
+ program works on this system.
+ Could another person confirm this, please.
+ The appropriate configuration is contained in the
+ .I conf/SCO-2.4
+ file.
  .PP
+ If the instructions for any of the above systems do not work,
+ after you have double-checked everything,
+ the author would like to know.
+ .SH UNKNOWN SYSTEMS
  Please let the author know of any other systems you get
  .I aegis
  working on,
  and the modifications necessary.
+ Please include the differences to the
+ .I Makefile
+ file,
+ and the whole
+ .I common/conf.h
+ file you used.
+ Included any other files you edited or added.
+ Include the output of the "uname -rs" command,
+ if your flavour of UNIX has such a command.
  .PP
  While the
  .I aegis
***************
*** 124,132 ****
  .I Makefile
  file similar to
  .RS
  H = -I/usr/include -Ih
  .RE
! Change this to suite your system and your compiler.
  The "h" directory must be searched last as it is
  intended to suplement your system,
  not replace it.
--- 220,230 ----
  .I Makefile
  file similar to
  .RS
+ .ft CW
  H = -I/usr/include -Ih
+ .ft R
  .RE
! Change this to suit your system and your compiler.
  The "h" directory must be searched last as it is
  intended to suplement your system,
  not replace it.
***************
*** 134,165 ****
  You will need to check the include files in the "h" directory
  to see that they are suitable for your system.
  You may want to delete any that your system already has.
- .ne 1i
- .SH KNOWN BAD SYSTEMS
- This distribution of
- .I aegis
- is known NOT to build on systems which do not have the
- .I seteuid
- and
- .I setegid
- systems calls.
- Most AT&T and Berkeley derived UNIXes have these
- systems calls.
- .PP
- Systems the aegis program is known NOT to work on include:
- .TP 8n
- SCO 3.2
  .br
- No seteuid and setegid systems calls.
  .ne 1i
  .SH BUILDING AEGIS
  All you should need to do is use the
  .RS
  .nf
  % make
  \fI\&...lots of output...\fP
  %
  .fi
  .RE
  command and wait.
  When this finishes you should see a directory called
--- 232,249 ----
  You will need to check the include files in the "h" directory
  to see that they are suitable for your system.
  You may want to delete any that your system already has.
  .br
  .ne 1i
  .SH BUILDING AEGIS
  All you should need to do is use the
  .RS
+ .ft CW
  .nf
  % make
  \fI\&...lots of output...\fP
  %
  .fi
+ .ft R
  .RE
  command and wait.
  When this finishes you should see a directory called
***************
*** 173,195 ****
  file is a program used in constructing
  .I aegis
  and is not for general consumption.
! .PP
! The Makefile assumes you are building
! .I aegis
! as root,
! because
! .I aegis
! is a set-uid-root program.
! It is not a disaster if you are not root initially,
! because the tests can be performed to confirm that
! .I aegis
! is working before you set it.
! (The error code from the
! .I chown
! will be ignored.)
  .ne 1i
  .SH OTHER USEFUL SOFTWARE
! Before describing how to test aegis,
  you may need to grab some other free software,
  because the tests require it in some cases,
  and because it is generally useful in others.
--- 257,267 ----
  file is a program used in constructing
  .I aegis
  and is not for general consumption.
! .br
  .ne 1i
  .SH OTHER USEFUL SOFTWARE
! Before describing how to test
! .IR aegis ,
  you may need to grab some other free software,
  because the tests require it in some cases,
  and because it is generally useful in others.
***************
*** 213,228 ****
  .I cook
  package is necessary for test 11 to pass.
  It is also used in the documentation.
- .br
  The
  .I cook
! package is available under the terms of the GNU General Public License.
  .TP 8n
  RCS
  .br
  This is a source control package,
  and is available from any of the GNU archives.
! The tests use RCS as the history mechanism.
  .TP 8n
  GNU diff
  .br
--- 285,307 ----
  .I cook
  package is necessary for test 11 to pass.
  It is also used in the documentation.
  The
  .I cook
! program may be found at the same archive site as the
! .I aegis
! program,
! and in the same directory.
! The
! .I cook
! program is available under the terms of the GNU General Public License.
  .TP 8n
  RCS
  .br
  This is a source control package,
  and is available from any of the GNU archives.
! The tests use RCS as the history mechanism,
! so it is necessary to have RCS
! for most of the tests to pass.
  .TP 8n
  GNU diff
  .br
***************
*** 232,239 ****
  .B -c
  option,
  you will need GNU diff to make patch files,
! if you want to publish aftware for FTP or on USENET.
  Context differences are also helpful for reviewing changes.
  .SH TESTING AEGIS
  The
  .I aegis
--- 311,354 ----
  .B -c
  option,
  you will need GNU diff to make patch files,
! if you want to publish software for FTP or on USENET.
  Context differences are also helpful for reviewing changes.
+ .TP 8n
+ groff
+ .br
+ This GNU software replaces the
+ documentation tools which (sometimes)
+ come with UNIX.
+ They produce superior error messages,
+ and support a wider range of functionality and fonts.
+ The
+ .I aegis
+ User Guide was prepared with groff.
+ .TP 8n
+ bison
+ .br
+ This GNU software is a replacement for
+ .IR yacc (1).
+ Some systems have very sick yaccs,
+ and this may be necessary if your system include files
+ disagree strongly with your system's yacc.
+ The
+ .I Makefile
+ has bison setup in comments.
+ .TP 8n
+ fhist
+ .br
+ This software,
+ available under the terms of the GNU General Public License,
+ is a set of file history and comparison utilities.
+ It was originally written by David I. Bell,
+ and is based on the minimal difference algorithm by Eugene W. Myers.
+ This copy is enhanced and maintained by the same author as
+ .IR aegis ,
+ and may be found at the same archive site,
+ in the same directory.
+ .br
+ .ne 1i
  .SH TESTING AEGIS
  The
  .I aegis
***************
*** 240,245 ****
--- 355,361 ----
  program comes with a test suite.
  To run this test suite, use the command
  .RS
+ .ft CW
  .nf
  % make sure
  \fI\&...lots of output...\fP
***************
*** 246,251 ****
--- 362,368 ----
  Passed All Tests
  %
  .fi
+ .ft R
  .RE
  .PP
  The tests take a minute or two each,
***************
*** 261,289 ****
  file assumes the
  .IR cook (1)
  command by the author is somewhere in the command search path.
! This test reproduces the commands used in the user guide.
  .PP
  If the
  .I aegis
  program is not set-uid-root then it runs in "test" mode
! which allows the functionality to be tested before
  being tested again when it is set-uid-root.
  .RS
  .nf
! % su
! Password: ...
  # chown root bin/aegis
  # chmod u+s bin/aegis
! # exit
  % make sure
  \fI\&...lots of output...\fP
  Passed All Tests
  %
  .fi
  .RE
- Two pass testing like this allows you to be confidant that
- .I aegis
- is functional before trusting your system to it.
  .PP
  You should test
  .I aegis
--- 378,487 ----
  file assumes the
  .IR cook (1)
  command by the author is somewhere in the command search path.
! This test reproduces the example used in Chapter 3 of the User Guide.
  .PP
+ If you are using Sun's
+ .I tmpfs
+ file system as your
+ .I /tmp
+ directory,
+ the tests will fail.
+ This is because the
+ .I tmpfs
+ file system does not support file locking.
+ Set the
+ .I AEGIS_TMP
+ environment variable to somewhere else
+ before running the tests.
+ Something like
+ .RS
+ .ft CW
+ .nf
+ % setenv AEGIS_TMP /usr/tmp
+ %
+ .fi
+ .ft R
+ .RE
+ is usually sufficient if you are using C shell, or
+ .RS
+ .ft CW
+ .nf
+ $ AEGIS_TMP=/usr/tmp
+ $ export AEGIS_TMP
+ $
+ .fi
+ .ft R
+ .RE
+ if you are using Bourne shell.
+ Remember,
+ this must be done before running the tests.
+ .PP
+ If the tests fail due to errors complaining of "user too privileged"
+ you will need to adjust the
+ .I AEGIS_MIN_UID
+ define in the
+ .I common/conf.h
+ file.
+ Similarly for "group too privileged",
+ although this is rarer.
+ This error message will also occur if you run the tests as root:
+ the tests must be run as a mortal each time.
+ .br
+ .ne 1i
+ .SH TESTING SET-UID-ROOT
  If the
  .I aegis
  program is not set-uid-root then it runs in "test" mode
! which gives you some confidence that
! .I aegis
! is working before
  being tested again when it is set-uid-root.
+ Two pass testing like this means that you need not trust your system
+ to a set-uid-root program which is not known to work.
+ .PP
+ You will need to do a little of the install,
+ to create the directory which will contain
+ .IR aegis "'"
+ lock file.
  .RS
+ .ft CW
  .nf
! # mkdir /usr/local/lib/aegis
! # chmod 755 /usr/local/lib/aegis
! # chown bin /usr/local/lib/aegis
! # chgrp bin /usr/local/lib/aegis
! #
! .fi
! .ft R
! .RE
! You will need to change
! .I aegis
! to be set-uid-root.
! This may be done with the following commands:
! .RS
! .ft CW
! .nf
  # chown root bin/aegis
  # chmod u+s bin/aegis
! #
! .fi
! .ft R
! .RE
! Once
! .I aegis
! is set-uid-root,
! it is tested again,
! in the same manner as before.
! .RS
! .nf
! .ft CW
  % make sure
  \fI\&...lots of output...\fP
  Passed All Tests
  %
  .fi
+ .ft R
  .RE
  .PP
  You should test
  .I aegis
***************
*** 290,295 ****
--- 488,494 ----
  as a mortal in both passes,
  rather than as root,
  to be sure the set-uid-root functionality is working correctly.
+ .br
  .ne 1i
  .SH INSTALLING AEGIS
  Put the
***************
*** 300,309 ****
--- 499,510 ----
  directory.
  Use the command
  .RS
+ .ft CW
  .nf
  # cp bin/aegis /usr/local/bin
  #
  .fi
+ .ft R
  .RE
  Don't forget to make sure that the copy is set-uid-root,
  some versions of \fIcp\fP do not transfer the set-uid bit of the mode.
***************
*** 310,320 ****
  .PP
  The manuals can be installed using the commands
  .RS
  .nf
! # sh man1/install.sh \fI/usr/man/man1\fP
! # sh man5/install.sh \fI/usr/man/man5\fP
  #
  .fi
  .RE
  but this is very site specific.
  You can select a different path by changing the last argument.
--- 511,523 ----
  .PP
  The manuals can be installed using the commands
  .RS
+ .ft CW
  .nf
! # sh man1/install.sh \fI/usr/local/man/man1\fP
! # sh man5/install.sh \fI/usr/local/man/man5\fP
  #
  .fi
+ .ft R
  .RE
  but this is very site specific.
  You can select a different path by changing the last argument.
***************
*** 323,329 ****
  .I aegis
  is configured to use
  .I /usr/local/lib/aegis
! as the place it stores the table contining the mapping
  from project name to project directory,
  and indexes into this table.
  The
--- 526,532 ----
  .I aegis
  is configured to use
  .I /usr/local/lib/aegis
! as the place it stores the table containing the mapping
  from project name to project directory,
  and indexes into this table.
  The
***************
*** 336,349 ****
  and generic notification scripts.
  These can be copied to this library as follows:
  .RS
  .nf
  # mkdir /usr/local/lib/aegis
  # chown bin /usr/local/lib/aegis
  # chgrp bin /usr/local/lib/aegis
! # cp dot.cshrc dot.profile /usr/local/lib/aegis
! # cp notify/* /usr/local/lib/aegis
  #
  .fi
  .RE
  This is only an example,
  and you may want to place this somewhere else.
--- 539,556 ----
  and generic notification scripts.
  These can be copied to this library as follows:
  .RS
+ .ft CW
  .nf
  # mkdir /usr/local/lib/aegis
+ # chmod 755 /usr/local/lib/aegis
  # chown bin /usr/local/lib/aegis
  # chgrp bin /usr/local/lib/aegis
! # cp lib/* /usr/local/lib/aegis
! # chmod a+r /usr/local/lib/aegis/*
! # chmod a+x /usr/local/lib/aegis/*.sh
  #
  .fi
+ .ft R
  .RE
  This is only an example,
  and you may want to place this somewhere else.
***************
*** 352,373 ****
  .I Makefile
  file.
  .PP
! The User Guide
! may be formatted and printed using a command such as
! .RS
! .nf
! % cd doc
! % tbl aegis.ms | troff -t -ms | lpr -t
! %
! .fi
! .RE
! .LP
! This is a guess,
! your site may be different.
! .LP
! Please note the the User Guide is still in the process of being written.
! Most sections of the user guide are still incomplete.
! Feedback on the form and content of this document would be most welcome.
  .ne 1i
  .SH USER CONFIGURATION
  The
--- 559,571 ----
  .I Makefile
  file.
  .PP
! All of the above install can be done automatically,
! using the "\f(CWmake install\fP" command as root.
! Control of the directories used may be found in the first
! few lines of the
! .I Makefile
! file.
! .br
  .ne 1i
  .SH USER CONFIGURATION
  The
***************
*** 376,389 ****
  otherwise users will need to add the relevant directory to their PATH.
  Users should add
  .RS
! source /usr/local/lib/aegis/dot.cshrc
  .RE
  to the end of their
  .I .cshrc
  file for the recommended aliases.
  There is a
! .I dot.profile
! for users of the Bourne shell.
  .PP
  The
  .I /usr/local/lib/aegis/state
--- 574,590 ----
  otherwise users will need to add the relevant directory to their PATH.
  Users should add
  .RS
! .ft CW
! source /usr/local/lib/aegis/cshrc
! .ft R
  .RE
  to the end of their
  .I .cshrc
  file for the recommended aliases.
  There is a
! .I profile
! for users of the Bourne shell
! (it assumes you have a version of the Bourne shell which has functions).
  .PP
  The
  .I /usr/local/lib/aegis/state
***************
*** 392,398 ****
  by putting a search path into the
  .I AEGIS
  environment variable.
! The system part is always appended.
  .PP
  Where projects reside is completely flexible,
  be they system projects or user projects.
--- 593,609 ----
  by putting a search path into the
  .I AEGIS
  environment variable.
! The system part is always automatically appended by
! .IR aegis .
! The default,
! already set by the
! .I /usr/local/lib/\%aegis/cshrc
! file,
! is
! .IR $HOME/lib/aegis .
! Do not create this directory,
! .I aegis
! is finickey and wants to do this itself.
  .PP
  Where projects reside is completely flexible,
  be they system projects or user projects.
***************
*** 400,406 ****
--- 611,693 ----
  .I /usr/local/lib/aegis
  directory,
  this directory only contains pointers.
+ .br
  .ne 1i
+ .SH PRINTED MANUALS
+ This distribution contains the sources to
+ all of the documentation for
+ .IR aegis .
+ The author used the GNU groff package
+ and a postscript printer to prepare the documentation.
+ If you do not have this software,
+ you will need to substitute commands appropriate to your site.
+ .PP
+ To print copies of the
+ .IR README ,
+ .IR BUILDING
+ and
+ .I ALPHA
+ files,
+ the following commands may be used
+ .RS
+ .ft CW
+ .nf
+ % groff -t -man aux/*.man | lpr
+ %
+ .fi
+ .ft R
+ .RE
+ This will produce about 12 pages.
+ The "-t" flag means preprocess with
+ .IR tbl (1).
+ .PP
+ To print copies of the manual entries,
+ the following commands may be used
+ .RS
+ .ft CW
+ .nf
+ % cd man1
+ % groff -s -t -man *.1 | lpr
+ % cd ../man5
+ % groff -s -t -man *.5 | lpr
+ % cd ..
+ %
+ .fi
+ .ft R
+ .RE
+ This will produce about 60 pages.
+ The "-s" flag means preprocess with
+ .IR soelim (1),
+ and the "-t" flag means preprocess with
+ .IR tbl (1).
+ .PP
+ To print a copy of the User Guide,
+ the following commands may be used
+ .RS
+ .ft CW
+ .nf
+ % cd doc
+ % groff -s -t -p -ms aegis.ms | lpr
+ % cd ..
+ %
+ .fi
+ .ft R
+ .RE
+ This will produce about 90 pages.
+ The "-s" flag means preprocess with
+ .IR soelim (1),
+ the "-t" flag means preprocess with
+ .IR tbl (1),
+ and the "-p" flag means preprocess with
+ .IR pic (1).
+ Alternatively,
+ you could get a PostScript copy of the User Guide from the archive site.
+ .PP
+ Please note the the User Guide is still in the process of being written.
+ Some sections of the User Guide are incomplete.
+ Feedback on the form and content of this document would be most welcome.
+ .br
+ .ne 1i
  .SH GETTING HELP
  This is alpha software,
  so things will probably go wrong.
***************
*** 419,429 ****
  please include the version number
  given by the
  .RS
  .nf
  % aegis -version
! aegis version \fIa.b.cccc\fP, \fI...\fP
  %
  .fi
  .RE
  command.
  .PP
--- 706,719 ----
  please include the version number
  given by the
  .RS
+ .ft CW
  .nf
  % aegis -version
! aegis version \fIa.b.cccc\fP
! \fI\&...\fP
  %
  .fi
+ .ft R
  .RE
  command.
  .PP
***************
*** 439,459 ****
  and adds the
  .B -TRace
  command line option.
! When followed by one or more file names,
! this turns on execution traces in those files.
  .ne 1i
  .SH LICENSE
  The
  .I aegis
! package is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY;
  without even the implied warranty of MERCHANTABILITY or
  FITNESS FOR A PARTICULAR PURPOSE.
  See the GNU General Public License for more details.
  .SH AUTHOR
  .TS
  tab(;);
  l l l.
  Peter Miller;UUCP;uunet!munnari!bmr.gov.au!pmiller
! \f(CW/\e/\e*\fR;CSNET;pmiller@bmr.gov.au
  .TE
--- 729,771 ----
  and adds the
  .B -TRace
  command line option.
! .PP
! When the
! .B -TRace
! command line option is followed by one or more file names,
! it turns on execution traces in those source files.
! It is usually best to place this on the end of the command line
! so that names of the files to be traced are not confused
! with other file names or strings on the command line.
! .br
  .ne 1i
  .SH LICENSE
  The
  .I aegis
! program is free software;
! you can redistribute it and/or modify
! it under the terms of the GNU General Public License as published by
! the Free Software Foundation;
! either version 2 of the License,
! or (at your option) any later version.
! .PP
! The
! .I aegis
! program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY;
  without even the implied warranty of MERCHANTABILITY or
  FITNESS FOR A PARTICULAR PURPOSE.
  See the GNU General Public License for more details.
+ .PP
+ It should be in the
+ .I LICENSE
+ file included in this distribution.
+ .br
+ .ne 1i
  .SH AUTHOR
  .TS
  tab(;);
  l l l.
  Peter Miller;UUCP;uunet!munnari!bmr.gov.au!pmiller
! \f(CW/\e/\e*\fR;Internet;pmiller@bmr.gov.au
  .TE
Index: aux/BUILDpyr.man
***************
*** 0 ****
--- 1,120 ----
+ '\" t
+ .\"	aegis - project change supervisor
+ .\"	Copyright (C) 1993 Peter Miller.
+ .\"	All rights reserved.
+ .\"
+ .\"	This program is free software; you can redistribute it and/or modify
+ .\"	it under the terms of the GNU General Public License as published by
+ .\"	the Free Software Foundation; either version 2 of the License, or
+ .\"	(at your option) any later version.
+ .\"
+ .\"	This program is distributed in the hope that it will be useful,
+ .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
+ .\"	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ .\"	GNU General Public License for more details.
+ .\"
+ .\"	You should have received a copy of the GNU General Public License
+ .\"	along with this program; if not, write to the Free Software
+ .\"	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ .\"
+ .\" MANIFEST: source of the BUILDpyr file
+ .\"
+ .TH build-pyramid aegis
+ .if n .hy 0
+ .if n .ad l
+ .if n .nr IN 8n
+ .SH NAME
+ aegis \- project change supervisor
+ .br
+ .if t .ds C) \(co
+ .if n .ds C) (C)
+ Copyright \*(C) 1990, 1991, 1992, 1993 Peter Miller.
+ .br
+ All rights reserved.
+ .PP
+ The aegis program is distributed under the terms of the
+ GNU General Public License.
+ See the LICENSE section, below, for more details.
+ .PP
+ .B aegis
+ (ee.j.iz)
+ .I n.,
+ a protection,
+ a defence.
+ .SH PYRAMID
+ This file describes how to configure aegis to be compiled on the
+ Pyramid SMP DC/OSx 1.0-92b023 operating system.
+ .TP 4n
+ 1.
+ Copy the 
+ .I conf/dcosx
+ file to the
+ .I common/conf.h
+ file.
+ This sets most of the compile-time configuations.
+ .TP 4n
+ 2.
+ There is a bug in the \fC<sys/types.h>\fP include file.
+ Make a copy and replace the string "enum boolean" with "enum boolean_t".
+ There is only one.
+ The ANSI C and POSIX rules say that they should have used a _t suffix
+ or an underscore (_) prefix.
+ Complain to your vendor.
+ .RS
+ .ft C
+ .nf
+ % mkdir common/sys
+ % cp /usr/include/sys/types.h common/sys/stypes.h
+ % vi common/sys/types.h
+ \fI\&...edit the file...\fP
+ %
+ .fi
+ .ft R
+ .RE
+ .TP 4n
+ 3.
+ Edit the
+ .I Makefile
+ file and select the alternatives marked "dcosx".
+ The horrible CC and CFLAGS macros are because the C compiler is brain-dead.
+ You will get a
+ .I huge
+ number of warnings when you compile aegis,
+ just ignore them.
+ You may want to consider getting gcc instead.
+ .TP 4n
+ 4.
+ Once you have obtained gcc,
+ edit the Makefile and select the gcc alternatives for the CC and CFLAGS macros.
+ .br
+ .ne 1i
+ .SH LICENSE
+ The
+ .I aegis
+ program is free software;
+ you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation;
+ either version 2 of the License,
+ or (at your option) any later version.
+ .PP
+ The
+ .I aegis
+ program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY;
+ without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU General Public License for more details.
+ .PP
+ It should be in the
+ .I LICENSE
+ file included in this distribution.
+ .br
+ .ne 1i
+ .SH AUTHOR
+ .TS
+ tab(;);
+ l l l.
+ Peter Miller;UUCP;uunet!munnari!bmr.gov.au!pmiller
+ \f(CW/\e/\e*\fR;Internet;pmiller@bmr.gov.au
+ .TE
Index: aux/CHANGES.sh
***************
*** 1,13 ****
! #!/bin/sh
  #
  #	aegis - project change supervisor
! #	Copyright (c) 1992 Peter Miller.
  #	All rights reserved.
  #
  #	This program is free software; you can redistribute it and/or modify
  #	it under the terms of the GNU General Public License as published by
! #	the Free Software Foundation; either version 1, or (at your option)
! #	any later version.
  #
  #	This program is distributed in the hope that it will be useful,
  #	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,13 ----
! #! /bin/sh
  #
  #	aegis - project change supervisor
! #	Copyright (C) 1992, 1993 Peter Miller.
  #	All rights reserved.
  #
  #	This program is free software; you can redistribute it and/or modify
  #	it under the terms of the GNU General Public License as published by
! #	the Free Software Foundation; either version 2 of the License, or
! #	(at your option) any later version.
  #
  #	This program is distributed in the hope that it will be useful,
  #	but WITHOUT ANY WARRANTY; without even the implied warranty of
Index: aux/Howto.cook
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 73,79 ****
  vs_file = common/patchlevel.h;
  change_files =
  	[collect aegis -l chafil -ter -p [project] -c [change]]
! 	[vs_file]
  	;
  project_files =
  	[collect aegis -l profil -ter -p [project] -c [change]]
--- 73,79 ----
  vs_file = common/patchlevel.h;
  change_files =
  	[collect aegis -l chafil -ter -p [project] -c [change]]
! 	[vs_file] doc/version.so
  	;
  project_files =
  	[collect aegis -l profil -ter -p [project] -c [change]]
***************
*** 197,203 ****
   */
  if [defined change] then if [not [defined baseline]] then
  	all = [all] archive/Part01.Z archive/[project].tar.Z
! 		archive/[project].patch.Z;
  
  all: [all]
  {
--- 197,203 ----
   */
  if [defined change] then if [not [defined baseline]] then
  	all = [all] archive/Part01.Z archive/[project].tar.Z
! 		archive/[project].patch.Z ;
  
  all: [all]
  {
***************
*** 284,289 ****
--- 284,307 ----
  		set clearstat;
  }
  
+ #ifndef baseline
+ 
+ if [exists doc/version.so] then
+ 	rm doc/version.so
+ 		set clearstat;
+ 
+ #endif
+ 
+ if [not [exists doc/version.so]] then
+ {
+ 	if [not [exists doc]] then
+ 		mkdir doc
+ 			set clearstat;
+ 	echo \"[version]\" > doc/version.so
+ 		set clearstat;
+ 	cooktime -m 2-Jan-70 doc/version.so;
+ }
+ 
  /*
   * These recipes are only expected to be exercised in an integration build.
   * They will work sort-of-OK for a development build, but are incapable
***************
*** 296,302 ****
  		rm Makefile
  			set clearstat;
  	sh [resolve aux/Makefile.sh [source_files]]
! 		| awk -f [resolve aux/Makefile.awk] > Makefile;
  }
  
  /*
--- 314,320 ----
  		rm Makefile
  			set clearstat;
  	sh [resolve aux/Makefile.sh [source_files]]
! 		| gawk -f [resolve aux/Makefile.awk] > Makefile;
  }
  
  /*
***************
*** 316,323 ****
  	if [not [exists cat%1]] then
  		mkdir cat%1
  			set clearstat;
  	roffpp [prepost "-I" "/man%1" [search_list]] [resolve man%1/%2.%1]
! 		| tbl | nroff -man > cat%1/%2.%1; 
  }
  
  
--- 334,344 ----
  	if [not [exists cat%1]] then
  		mkdir cat%1
  			set clearstat;
+ 	if [exists [target]] then
+ 		rm [target]
+ 			set clearstat;
  	roffpp [prepost "-I" "/man%1" [search_list]] [resolve man%1/%2.%1]
! 		| groff -Tascii -P-h -t -man > cat%1/%2.%1; 
  }
  
  
***************
*** 356,362 ****
  		rm -f [target]
  			set clearstat;
  	roffpp [prepost "-I" "/aux" [search_list]] [resolve aux/%.man]
! 		| tbl | nroff -man > [target]; 
  }
  
  
--- 377,383 ----
  		rm -f [target]
  			set clearstat;
  	roffpp [prepost "-I" "/aux" [search_list]] [resolve aux/%.man]
! 		| groff -Tascii -P-hub -t -man > [target]; 
  }
  
  
***************
*** 380,386 ****
  		rm [parts]
  			set clearstat;
  	/* assumes shar.3.49 available */
! 	shar -n[project] -a -c -oarchive/Part -L50 [source_file_order];
  	compress -v archive/Part*;
  }
  
--- 401,409 ----
  		rm [parts]
  			set clearstat;
  	/* assumes shar.3.49 available */
! 	shar -n[project] -a -c -oarchive/Part -L50
! 		-s pmiller@bmr.gov.au
! 		[resolve [source_file_order]];
  	compress -v archive/Part*;
  }
  
***************
*** 392,398 ****
  	if [exists [target]] then
  		rm [target]
  			set clearstat;
! 	tar cf - [source_file_order] | compress > [target];
  }
  
  archive/[project].patch.Z: [source_file_order]
--- 415,427 ----
  	if [exists [target]] then
  		rm [target]
  			set clearstat;
! 	if [exists archive/[project].tar] then
! 		rm archive/[project].tar
! 			set clearstat;
! 	tar cf - [resolve [source_file_order]] | tardy -unu 0 -gnu 0
! 	-una Peter -gna Miller -p [project] -ms 0644 -mc 022
! 		> archive/[project].tar;
! 	compress -v archive/[project].tar;
  }
  
  archive/[project].patch.Z: [source_file_order]
***************
*** 403,409 ****
  	if [exists [target]] then
  		rm [target]
  			set clearstat;
! 	sh [resolve aux/patches.sh] [project] [change] | compress > [target];
  }
  
  CHANGES: aux/CHANGES.sh [vs_file]
--- 432,443 ----
  	if [exists [target]] then
  		rm [target]
  			set clearstat;
! 	if [exists archive/[project].patch] then
! 		rm archive/[project].patch
! 			set clearstat;
! 	sh [resolve aux/patches.sh] [project] [change]
! 		> archive/[project].patch;
! 	compress -v archive/[project].patch;
  }
  
  CHANGES: aux/CHANGES.sh [vs_file]
Index: aux/MANIFEST.sh
***************
*** 1,13 ****
! #!/bin/sh
  #
  #	aegis - project change supervisor
! #	Copyright (c) 1992 Peter Miller.
  #	All rights reserved.
  #
  #	This program is free software; you can redistribute it and/or modify
  #	it under the terms of the GNU General Public License as published by
! #	the Free Software Foundation; either version 1, or (at your option)
! #	any later version.
  #
  #	This program is distributed in the hope that it will be useful,
  #	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,13 ----
! #! /bin/sh
  #
  #	aegis - project change supervisor
! #	Copyright (C) 1992, 1993 Peter Miller.
  #	All rights reserved.
  #
  #	This program is free software; you can redistribute it and/or modify
  #	it under the terms of the GNU General Public License as published by
! #	the Free Software Foundation; either version 2 of the License, or
! #	(at your option) any later version.
  #
  #	This program is distributed in the hope that it will be useful,
  #	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 28,34 ****
  	MANIFEST)
  		info="This file"
  		;;
! 	COPYING)
  		info="GNU General Public License"
  		;;
  	README)
--- 28,34 ----
  	MANIFEST)
  		info="This file"
  		;;
! 	LICENSE)
  		info="GNU General Public License"
  		;;
  	README)
***************
*** 47,52 ****
--- 47,55 ----
  		info="Instructions to make(1) how to build and test aegis"
  		;;
  	common/patchlevel.h)
+ 		info="The patch level of this distribution."
+ 		;;
+ 	doc/version.so)
  		info="The patch level of this distribution."
  		;;
  	*)
Index: aux/Makefile.awk
***************
*** 1,12 ****
  #
  #	aegis - project change supervisor
! #	Copyright (c) 1992 Peter Miller.
  #	All rights reserved.
  #
  #	This program is free software; you can redistribute it and/or modify
  #	it under the terms of the GNU General Public License as published by
! #	the Free Software Foundation; either version 1, or (at your option)
! #	any later version.
  #
  #	This program is distributed in the hope that it will be useful,
  #	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  #
  #	aegis - project change supervisor
! #	Copyright (C) 1992, 1993 Peter Miller.
  #	All rights reserved.
  #
  #	This program is free software; you can redistribute it and/or modify
  #	it under the terms of the GNU General Public License as published by
! #	the Free Software Foundation; either version 2 of the License, or
! #	(at your option) any later version.
  #
  #	This program is distributed in the hope that it will be useful,
  #	but WITHOUT ANY WARRANTY; without even the implied warranty of
Index: aux/Makefile.sh
***************
*** 1,13 ****
  #! /bin/sh
  #
  #	aegis - project change supervisor
! #	Copyright (c) 1991-1993 Peter Miller.
  #	All rights reserved.
  #
  #	This program is free software; you can redistribute it and/or modify
  #	it under the terms of the GNU General Public License as published by
! #	the Free Software Foundation; either version 1, or (at your option)
! #	any later version.
  #
  #	This program is distributed in the hope that it will be useful,
  #	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,13 ----
  #! /bin/sh
  #
  #	aegis - project change supervisor
! #	Copyright (C) 1991, 1992, 1993 Peter Miller.
  #	All rights reserved.
  #
  #	This program is free software; you can redistribute it and/or modify
  #	it under the terms of the GNU General Public License as published by
! #	the Free Software Foundation; either version 2 of the License, or
! #	(at your option) any later version.
  #
  #	This program is distributed in the hope that it will be useful,
  #	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 34,40 ****
--- 34,46 ----
  echo  "# H = -I/usr/local/lib/gcc-include -I/usr/include -Ih"
  echo  "# H = -I/usr/include -Ih"
  echo  "H ="
+ echo  "# H =				# SunOS"
+ echo  "# H =				# ConvexOS"
  echo  "# H =				# dgux"
+ echo  "# H =				# dcosx"
+ echo  "# H =				# ULTRIX"
+ echo  "# H =				# hpux"
+ echo  "# H =				# SCO"
  echo
  echo  "#"
  echo  "# the name of the compiler to use"
***************
*** 41,47 ****
  echo  "#"
  echo  "CC = cc"
  echo  "# CC = gcc"
! echo  "# CC = gcc			# dgux"
  echo  "# CC = rcc			# SCO"
  echo
  echo  "#"
--- 47,58 ----
  echo  "#"
  echo  "CC = cc"
  echo  "# CC = gcc"
! echo  "# CC = cc			# SunOS"
! echo  "# CC = cc			# ConvexOS"
! echo  "# CC = cc			# dgux"
! echo  "# CC = /usr/ucb/cc		# dcosx"
! echo  "# CC = cc			# ULTRIX"
! echo  "# CC = cc			# hpux"
  echo  "# CC = rcc			# SCO"
  echo
  echo  "#"
***************
*** 49,56 ****
--- 60,73 ----
  echo  "#"
  echo  "CFLAGS = -O"
  echo  "# CFLAGS = -g"
+ echo  "# CFLAGS = -O			# SunOS"
+ echo  "# CFLAGS = -O			# ConvexOS"
  echo  "# CFLAGS = -O			# dgux"
  echo  "# CFLAGS = -O -Wall -ansi	# gcc"
+ echo  "# CFLAGS = -O -Xt -U__STDC__	# dcosx"
+ echo  "# CFLAGS = -O			# ULTRIX"
+ echo  "# CFLAGS = -O			# hpux"
+ echo  "# CFLAGS = -O			# SCO"
  echo
  echo  "#"
  echo  "# which yacc to use"
***************
*** 58,80 ****
  echo  "YACC = yacc"
  echo  "# YACC = byacc			# Berkeley"
  echo  "# YACC = bison -y		# GNU"
! echo ""
! echo "#"
! echo "# where to put the library directory"
! echo "#	(not used in testing mode)"
! echo "#"
! echo "LIB = -D'LIB=\"/usr/local/lib/aegis\"'"
! echo ""
! echo "#"
! echo "# extra libraries required for your system"
! echo "#"
! echo "LIBRARIES ="
! echo "# LIBRARIES = -lbsd"
! echo ""
! echo "# You should not need to alter anything below this point."
! echo "#------------------------------------------------------------"
! echo ""
! echo "all: bin/aegis"
  echo
  rm -f common/conf.h
  cp /dev/null common/conf.h
--- 75,129 ----
  echo  "YACC = yacc"
  echo  "# YACC = byacc			# Berkeley"
  echo  "# YACC = bison -y		# GNU"
! echo  ""
! echo  "#"
! echo  "# where to put the library directory"
! echo  "#	(not used in testing mode)"
! echo  "#"
! echo  "LIB = /usr/local/lib/aegis"
! echo  ""
! echo  "#"
! echo  "# where to put the executables"
! echo  "#"
! echo  "BIN = /usr/local/bin"
! echo  ""
! echo  "#"
! echo  "# where to put the manual entries"
! echo  "#"
! echo  "MAN = /usr/local/man"
! echo  ""
! echo  "#"
! echo  "# extra libraries required for your system"
! echo  "#"
! echo  "LIBRARIES ="
! echo  "# LIBRARIES = -lbsd"
! echo  "# LIBRARIES =			# SunOS"
! echo  "# LIBRARIES =			# ConvexOS"
! echo  "# LIBRARIES =			# dgux"
! echo  "# LIBRARIES = -lucb		# dcosx"
! echo  "# LIBRARIES =			# ULTRIX"
! echo  "# LIBRARIES =			# hpux"
! echo  "# LIBRARIES = -lsocket		# SCO"
! echo  ""
! echo  "#"
! echo  "# shell to use to run the tests"
! echo  "#	make sure there are no spaces after the definition,"
! echo  "#	many flavours of make(1) can't cope with them."
! echo  "#"
! echo  "SHELL = /bin/sh"
! echo  "# SHELL = /bin/sh		# SunOS"
! echo  "# SHELL = /bin/sh		# ConvexOS"
! echo  "# SHELL = /bin/sh		# dgux"
! echo  "# SHELL = /bin/sh		# dcosx"
! echo  "# SHELL = /bin/sh5		# ULTRIX"
! echo  "# SHELL = /bin/ksh		# apollo"
! echo  "# SHELL = /bin/sh		# hpux"
! echo  "# SHELL = /bin/sh		# SCO"
! echo  ""
! echo  "# You should not need to alter anything below this point."
! echo  "#------------------------------------------------------------"
! echo  ""
! echo  "all: bin/aegis"
  echo
  rm -f common/conf.h
  cp /dev/null common/conf.h
***************
*** 88,96 ****
  		echo
  		echo "fmtgen/${root}.gen.c fmtgen/${root}.gen.h: $file"
  		echo "	$(YACC) -d $file"
! 		echo "	sed "s/[yY][yY]/${root}_/g" < y.tab.c > fmtgen/${root}.gen.c"
  		echo "	rm y.tab.c"
! 		echo "	sed "s/[yY][yY]/${root}_/g" < y.tab.h > fmtgen/${root}.gen.h"
  		echo "	rm y.tab.h"
  		clean_files="$clean_files fmtgen/${root}.gen.c fmtgen/${root}.gen.h"
  		echo
--- 137,145 ----
  		echo
  		echo "fmtgen/${root}.gen.c fmtgen/${root}.gen.h: $file"
  		echo "	$(YACC) -d $file"
! 		echo "	sed \"s/[yY][yY]/${root}_/g\" < y.tab.c > fmtgen/${root}.gen.c"
  		echo "	rm y.tab.c"
! 		echo "	sed \"s/[yY][yY]/${root}_/g\" < y.tab.h > fmtgen/${root}.gen.h"
  		echo "	rm y.tab.h"
  		clean_files="$clean_files fmtgen/${root}.gen.c fmtgen/${root}.gen.h"
  		echo
***************
*** 134,142 ****
  		echo
  		echo "aegis/${root}.gen.c aegis/${root}.gen.h: $file"
  		echo "	$(YACC) -d $file"
! 		echo "	sed "s/[yY][yY]/${root}_/g" < y.tab.c > aegis/${root}.gen.c"
  		echo "	rm y.tab.c"
! 		echo "	sed "s/[yY][yY]/${root}_/g" < y.tab.h > aegis/${root}.gen.h"
  		echo "	rm y.tab.h"
  		clean_files="$clean_files aegis/${root}.gen.c aegis/${root}.gen.h"
  		echo
--- 183,191 ----
  		echo
  		echo "aegis/${root}.gen.c aegis/${root}.gen.h: $file"
  		echo "	$(YACC) -d $file"
! 		echo "	sed \"s/[yY][yY]/${root}_/g\" < y.tab.c > aegis/${root}.gen.c"
  		echo "	rm y.tab.c"
! 		echo "	sed \"s/[yY][yY]/${root}_/g\" < y.tab.h > aegis/${root}.gen.h"
  		echo "	rm y.tab.h"
  		clean_files="$clean_files aegis/${root}.gen.c aegis/${root}.gen.h"
  		echo
***************
*** 155,161 ****
  		oflg=
  		if [ $root = gonzo ]
  		then
! 			oflg='$(LIB)'
  		fi
  		echo "	$(CC) $(CFLAGS) $oflg -Iaegis -Icommon $(H) -c $file"
  		echo "	mv ${root}.o aegis/${root}.o"
--- 204,210 ----
  		oflg=
  		if [ $root = gonzo ]
  		then
! 			oflg="-D'LIB=\"$(LIB)\"'"
  		fi
  		echo "	$(CC) $(CFLAGS) $oflg -Iaegis -Icommon $(H) -c $file"
  		echo "	mv ${root}.o aegis/${root}.o"
***************
*** 179,185 ****
  		root=`basename $file .sh`
  		echo ""
  		echo "${root}: all $file"
! 		echo "	sh $file"
  		test_files="$test_files $root"
  		;;
  
--- 228,234 ----
  		root=`basename $file .sh`
  		echo ""
  		echo "${root}: all $file"
! 		echo "	$(SHELL) $file"
  		test_files="$test_files $root"
  		;;
  
***************
*** 213,219 ****
  echo "FmtgenFiles = $fmtgen_files"
  echo
  echo "bin/fmtgen: $(FmtgenFiles)"
! echo "	if [ ! -d bin ]; then mkdir bin; fi"
  echo "	$(CC) -o bin/fmtgen $(FmtgenFiles) $(LIBRARIES)"
  
  echo
--- 262,268 ----
  echo "FmtgenFiles = $fmtgen_files"
  echo
  echo "bin/fmtgen: $(FmtgenFiles)"
! echo "	if test ! -d bin; then mkdir bin; fi; exit 0"
  echo "	$(CC) -o bin/fmtgen $(FmtgenFiles) $(LIBRARIES)"
  
  echo
***************
*** 220,232 ****
  echo "AegisFiles = $aegis_files"
  echo
  echo "bin/aegis: $(AegisFiles)"
! echo "	if [ ! -d bin ]; then mkdir bin; fi"
  echo "	$(CC) -o bin/aegis $(AegisFiles) $(LIBRARIES)"
- echo "	-chown root bin/aegis && chmod u+st bin/aegis"
  
  echo
  echo "sure:" $test_files
  echo "	@echo Passed All Tests"
  
  rm common/conf.h
  exit 0
--- 269,295 ----
  echo "AegisFiles = $aegis_files"
  echo
  echo "bin/aegis: $(AegisFiles)"
! echo "	if test ! -d bin; then mkdir bin; fi; exit 0"
  echo "	$(CC) -o bin/aegis $(AegisFiles) $(LIBRARIES)"
  
  echo
  echo "sure:" $test_files
  echo "	@echo Passed All Tests"
+ 
+ echo
+ echo "install: all"
+ echo "	cp bin/aegis $(BIN)"
+ echo "	chown root $(BIN)/aegis"
+ echo "	chmod a+x,u+s $(BIN)/aegis"
+ echo "	-mkdir $(LIB)"
+ echo "	chmod 0755 $(LIB)"
+ echo "	cp lib/* $(LIB)"
+ echo "	chmod a+r $(LIB)/*"
+ echo "	chmod a+x $(LIB)/*.sh"
+ echo "	chown bin $(LIB)"
+ echo "	chgrp bin $(LIB)"
+ echo "	$(SHELL) man1/install.sh $(MAN)/man1"
+ echo "	$(SHELL) man5/install.sh $(MAN)/man5"
  
  rm common/conf.h
  exit 0
Index: aux/README.man
***************
*** 1,12 ****
  '\" t
  .\"	aegis - project change supervisor
! .\"	Copyright (c) 1990-1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 1, or (at your option)
! .\"	any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  '\" t
  .\"	aegis - project change supervisor
! .\"	Copyright (C) 1990, 1991, 1992, 1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 2 of the License, or
! .\"	(at your option) any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 20,37 ****
  .\" MANIFEST: source for the README file
  .\"
  .TH readme aegis
! .hy 0
! .ad l
  .SH NAME
  aegis \- project change supervisor
  .br
! .if t .ds c) \(co
! .if n .ds c) (c)
! Copyright \*(c) 1990-1993 Peter Miller.
  .br
  All rights reserved.
  .PP
! The aegis program is distributed under the terms of the
  GNU General Public License.
  See the LICENSE section, below, for more details.
  .PP
--- 20,40 ----
  .\" MANIFEST: source for the README file
  .\"
  .TH readme aegis
! .if n .hy 0
! .if n .ad l
! .if n .nr IN 8n
  .SH NAME
  aegis \- project change supervisor
  .br
! .if t .ds C) \(co
! .if n .ds C) (C)
! Copyright \*(C) 1990, 1991, 1992, 1993 Peter Miller.
  .br
  All rights reserved.
  .PP
! The
! .I aegis
! program is distributed under the terms of the
  GNU General Public License.
  See the LICENSE section, below, for more details.
  .PP
***************
*** 40,58 ****
  .I n.,
  a protection,
  a defence.
- .SH ALPHA NOTICE
- Please note that this is Alpha software.
- It probably has bugs,
- it is known to have unimplemented features.
- This version is not intended to be the final product.
- For more information,
- see the
- .I ALPHA
- file included in this release.
  .SH DESCRIPTION
! The aegis program is a CASE tool with a difference.
! In the spirit of the UNIX Opertaing System,
! the aegis program is a small component designed to work with other programs.
  .PP
  Many CASE systems attempt to provide everything,
  from bubble charts to source control to compilers.
--- 43,56 ----
  .I n.,
  a protection,
  a defence.
  .SH DESCRIPTION
! The
! .I aegis
! program is a CASE tool with a difference.
! In the spirit of the UNIX Operating System,
! the
! .I aegis
! program is a small component designed to work with other programs.
  .PP
  Many CASE systems attempt to provide everything,
  from bubble charts to source control to compilers.
***************
*** 61,102 ****
  for instance), then that is just tough.
  .PP
  In contrast,
! UNIX provides many components of a CASE system - compilers,
  editors,
! dependency tools (such as make),
! source control (such as SCCS).
! You may substitute the tool of your choice - gcc, jove, cake,
! rcs (to name a few) if you don't like the ones supplied with the system.
! The aegis program adds to this list with software configuration
! management (SCM),
  and true to UNIX philosophy,
! the aegis program does not
  dictate the choice of any of the other tools (although it may stretch them
  to their limits).
  .PP
! Enough hype, what is it that this Aegis program does?
  Just what is software configuration management?
  This question is sufficiently broad as to require a book in answer.
  In essence,
! the aegis program is a project change supervisor.
  It provides a
  framework within which a team of developers may work on many changes to a
  program independently,
! and the aegis program coordinates integrating these
  changes back into the master source of the program,
  with as little disruption as possible.
  Resolution of contention for source files,
  a major headache for any project with more than one developer,
! is one of the aegis program's major functions. 
  .PP
! It should be noted that the aegis program is a developer's tool,
! in the same sense as make or SCCS are developer's tools.
! It is not a manager's tool - it
! does not provide progress tracking or help with work allocation.
  .SH BENEFITS
! So why should you use the aegis program?
  .PP
! The aegis program uses a particular model of the development of software
  projects.
  This model has a master source (or baseline) of a project,
  and a team of developers creating changes to be made to this baseline.
--- 59,121 ----
  for instance), then that is just tough.
  .PP
  In contrast,
! UNIX provides many components of a CASE system \- compilers,
  editors,
! dependency manitenance tools (such as make),
! source control tools (such as RCS).
! You may substitute the tool of your choice
! if you don't like the ones supplied with the system \- gcc, jove, cake,
! to name just a few.
! The
! .I aegis
! program adds to this list with software configuration
! management,
  and true to UNIX philosophy,
! the
! .I aegis
! program does not
  dictate the choice of any of the other tools (although it may stretch them
  to their limits).
  .PP
! Enough hype, what is it that the
! .I aegis
! program does?
  Just what is software configuration management?
  This question is sufficiently broad as to require a book in answer.
  In essence,
! the
! .I aegis
! program is a project change supervisor.
  It provides a
  framework within which a team of developers may work on many changes to a
  program independently,
! and the
! .I aegis
! program coordinates integrating these
  changes back into the master source of the program,
  with as little disruption as possible.
  Resolution of contention for source files,
  a major headache for any project with more than one developer,
! is one of the
! .I aegis
! program's major functions. 
  .PP
! It should be noted that the
! .I aegis
! program is a developer's tool,
! in the same sense as make or RCS are developer's tools.
! It is not a manager's tool \- it
! does not provide progress tracking or manage work allocation.
! .br
! .ne 1i
  .SH BENEFITS
! So why should you use the
! .I aegis
! program?
  .PP
! The
! .I aegis
! program uses a particular model of the development of software
  projects.
  This model has a master source (or baseline) of a project,
  and a team of developers creating changes to be made to this baseline.
***************
*** 107,117 ****
  no change is allowed to cause the baseline to cease to work.
  "Working" is defined as passing it's own tests.
  The tests are considered part of the baseline.
! The aegis program provides support for the developer so that an entire copy of
  the baseline need not be taken to change a few files,
  only those files which are to be changed need to be copied.
  .PP
! The win in using the aegis program is that there are
  .I O(n)
  interactions between
  developers and the baseline.
--- 126,151 ----
  no change is allowed to cause the baseline to cease to work.
  "Working" is defined as passing it's own tests.
  The tests are considered part of the baseline.
! The
! .I aegis
! program provides support for the developer so that an entire copy of
  the baseline need not be taken to change a few files,
  only those files which are to be changed need to be copied.
  .PP
! In order to ensure that changes are unable to
! cause the baseline to cease to work,
! .I aegis
! mandates that changes be accompanied by at least one test,
! and that all such tests be known to complete sucessfully.
! These steadily accumulated tests form an ever increasing
! regression test suite for all later changes.
! There is also a mandatory review stage for each change to the baseline.
! While these requirements may be relaxed per-change or even per-project,
! doing so potentially compromises the "working" definition of the baseline.
! .PP
! The win in using the
! .I aegis
! program is that there are
  .I O(n)
  interactions between
  developers and the baseline.
***************
*** 127,175 ****
  or those "pre-release snapshots" we are always forced to provide.
  .PP
  The above advantages are all very well - for management types.
! Why should Joe Average Programmer use the aegis program?
! Recall that SCCS provides file locking,
  but only for one file at a time.
! The aegis program provides the file locking,
  atomically,
  for the set of files in the change.
! Recall also that SCCS locks the file the instant you start editing it.
  This makes popular files a project bottleneck.
! The aegis program allows concurrent editing,
  and a resolution mechanism just before the
  change must be integrated,
  meaning fewer delays for J.A.Programmer.
! .SH NEW IN THIS RELEASE
! A number of features have been added to aegis with this release.
! A few of them are detailed here:
  .PP
! \(bu Support for NFS and the automounter.
! The
  .I aegis
! program will now function correctly in this environment.
  .PP
! \(bu Generation of patch files.
  The
  .I aegis
! program now provides functionailty for the generation of patch files.
! An example shell script may be found in the
! .I aux/patches.sh
! file.
  .PP
! \(bu Extracting previous versions.
! It is now possible to extract an historical version of a file
! when copying a file into change,
! not just the most up-to-date version.
! This aids in reproducing and killing bugs.
  .PP
! \(bu The tests distributed with the
  .I aegis
! program now use RCS.
! Previously SCCS was used,
! but this costs money and thus not everyone had it.
! RCS is free software and more readily accessible
! and far less expensive.
  .PP
  Plus the usual crop of bug fixes and tinkering.
  For excruciating detail,
  and also acknowlegements of those who generously sent me feedback,
--- 161,400 ----
  or those "pre-release snapshots" we are always forced to provide.
  .PP
  The above advantages are all very well - for management types.
! Why should Joe Average Programmer use the
! .I aegis
! program?
! Recall that RCS provides file locking,
  but only for one file at a time.
! The
! .I aegis
! program provides the file locking,
  atomically,
  for the set of files in the change.
! Recall also that RCS locks the file the instant you start editing it.
  This makes popular files a project bottleneck.
! The
! .I aegis
! program allows concurrent editing,
  and a resolution mechanism just before the
  change must be integrated,
  meaning fewer delays for J.A.Programmer.
! .br
! .ne 1i
! .SH ALPHA NOTICE
! Please note that this is Alpha software.
! It probably has bugs,
! it is known to have unimplemented features.
! This version is not intended to be the final product.
! For more information,
! see the
! .I ALPHA
! file included in this release.
  .PP
! The reasons the author thinks this software is alpha include:
! .if n *
! .if t \(bu
! it has not clocked enought CPU time,
! .if n *
! .if t \(bu
! it has not been built on enough systems,
! .if n *
! .if t \(bu
! it has not been tested on enough systems,
! .if n *
! .if t \(bu
! the User Guide is not finished.
! However, feedback to date has been very favourable.
! .PP
! This will probably be the last Alpha release.
! The next release will be 2.0,
! and will be a Beta release.
! The problems reported to date are configuration and build problems;
! there are few reports of it failing to function correctly in other cases.
! .br
! .ne 1i
! .SH ARCHIVE SITE
! The latest version of
  .I aegis
! is available by anonymous ftp from:
! .RS
! .TS
! center,tab(;);
! l l s
! l l l.
! Host:;ftp.cse.nau.edu (134.114.64.70)
! Dir:;/pub/Aegis
! File:;aegis.1.4.tar.Z;# the complete source
! File:;aegis.1.4.patch.Z;# patch to take 1.3 to 1.4
! File:;aegis.1.4.ps.Z;# PostScript of the User Guide
! .TE
! .RE
  .PP
! To use anonymous ftp,
! give "anonymous" as the user name (omit the quotes)
! and your email address as the password.
! .PP
! My grateful thanks to Paul Balyoz <pab@ftp.cse.nau.edu>
! for his generosity in providing this archive space.
! .PP
! This directory also contains a few other pieces of software written by me.
! Some are referred to in the
! .I aegis
! documentation.
! Please have a look if you are interested.
! .PP
! For those of you without ftp,
! I recommend the use of an ftp-by-email server.
! Here is a list of a few (there are many more):
! .RS
! .nf
! mail-server@pit-manager.mit.edu
! ftpmail@decwrl.dec.com
! ftpmail@cs.uow.edu.au
! .fi
! .RE
! .PP
! In general, you can get a help message about how to use each system
! by sending email with a subject of "help"
! and a message body containing just the word "help".
! .br
! .ne 1i
! .SH MAILING LIST
! A mailing list has been created so that users of
! .I aegis
! may exchange ideas about how to use the
! .I aegis
! program.
! Discussion may include,
! but is not limited to:
! bugs, enhancements, and applications.
! The list is not moderated.
! .PP
! The address of the mailing list is
! .RS
! .ft CW
! aegis-users@bmr.gov.au
! .ft R
! .RE
! .PP
! To subscribe to this mailing list,
! send an email message to \f(CWmajordomo@bmr.gov.au\fP with
! a message body containing the single line
! .RS
! .ft CW
! subscribe aegis-users
! .ft R
! .RE
! Please note that \f(CWbmr.gov.au\fP is an Internet site,
! so if you have an address which is not readily derived from
! your mail headers (majordomo is only a Perl program, after all)
! you will need to use a message of the form:
! .RS
! .ft CW
! subscribe aegis-users \fIaddress\fP
! .ft R
! .RE
! where \fIaddress\fP is an email address which
! makes sense from an Internet site.
! .PP
! The software which handles this mailing list
! .if n CANNOT
! .if t .B cannot
! send you a copy of the
! .I aegis
! program.
! Please use ftp or ftp-by-email, instead.
! .br
! .ne 1i
! .SH COMPARISON WITH CVS
! One of the most common questions about
! .I aegis
! is "How does it compare with CVS?"
! .PP
! The CVS program aims to provide a repository,
! RCS for sets of files.
  The
  .I aegis
! program aims to provide a baseline,
! a repository,
! consistency of the baseline,
! and validation of changes being made to the baseline.
  .PP
! A simplistic way of thinking of this is "CVS is over RCS",
! but "aegis is over RCS and make".
! Actually CVS requires RCS,
! whereas
! .I aegis
! may be configured to use almost any history tool;
! similarly for the dependency maintenance tool,
! .I aegis
! may be configured to use almost any sufficiently capable
! tool (unfortunately traditional make isn't sufficiently capable,
! but the name is well known and evokes the appropriate functional image).
  .PP
! The most significant point of departure is around the "cvs checkin"
! fucntionality.
! In CVS, this is unconditional;
! a developer can add a poorly though-out code change,
! or even indulge in a little vandalism,
! with nothing to prevent it.
! In contrast,
! the
  .I aegis
! program breaks this step into several pieces:
! the change must be be known to build,
! the change must have tests and those tests be known to have run and passed,
! the change must then be reviewed (double check),
! and then built and tested again (tripple check).
  .PP
+ For a more detailed discussion,
+ see appendix C of the User Guide.
+ .br
+ .ne 1i
+ .SH NEW IN THIS RELEASE
+ A number of features have been added to
+ .I aegis
+ with this release.
+ A few of them are detailed here:
+ .PP
+ .if n *
+ .if t \(bu
+ Support has been added for systems without the
+ .I seteuid
+ system call,
+ or those with crippled implementations.
+ .PP
+ .if n *
+ .if t \(bu
+ Most of the unimplemented command variants have been finished.
+ These include
+ .IR "New Change Undo" ,
+ .IR "Develop Begin Undo"
+ and
+ .IR "ReMove PRoject" .
+ Most notable of the exceptions is
+ .I -ANticipate
+ option for the
+ .I -CoPy_file
+ and
+ .I -DIFFerence
+ command.
+ .PP
+ .if n *
+ .if t \(bu
+ The User Guide has been added to,
+ making it a little more complete.
+ It still needs more work, sigh.
+ .PP
+ .if n *
+ .if t \(bu
+ The code to handle automounters has been made more robust.
+ .PP
+ .if n *
+ .if t \(bu
+ The command substitutions have been vastly improved,
+ and are now documented.
+ .PP
  Plus the usual crop of bug fixes and tinkering.
  For excruciating detail,
  and also acknowlegements of those who generously sent me feedback,
***************
*** 176,194 ****
  please see the
  .I CHANGES
  file included in this distribution.
  .SH BUILDING
! Instructions on how to build and test the aegis program
  are to be found in the
  .I BUILDING
! file included with this release.
  .SH LICENSE
! The aegis program is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
! the Free Software Foundation; either version 1, or (at your option)
! any later version.
  .PP
! The aegis program is distributed in the hope that it will be useful,
! but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  See the GNU General Public License for more details.
  .PP
--- 401,432 ----
  please see the
  .I CHANGES
  file included in this distribution.
+ .br
+ .ne 1i
  .SH BUILDING
! Instructions on how to build and test the
! .I aegis
! program
  are to be found in the
  .I BUILDING
! file included in this distribution.
! .br
! .ne 1i
  .SH LICENSE
! The
! .I aegis
! program is free software;
! you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
! the Free Software Foundation;
! either version 2 of the License,
! or (at your option) any later version.
  .PP
! The
! .I aegis
! program is distributed in the hope that it will be useful,
! but WITHOUT ANY WARRANTY;
! without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  See the GNU General Public License for more details.
  .PP
***************
*** 195,205 ****
  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
! It should be in the COPYING file.
  .SH AUTHOR
  .TS
  tab(;);
  l l l.
  Peter Miller;UUCP;uunet!munnari!bmr.gov.au!pmiller
! \f(CW/\e/\e*\fR;CSNET;pmiller@bmr.gov.au
  .TE
--- 433,448 ----
  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
! .PP
! It should be in the
! .I LICENSE
! file included in this distribution.
! .br
! .ne 1i
  .SH AUTHOR
  .TS
  tab(;);
  l l l.
  Peter Miller;UUCP;uunet!munnari!bmr.gov.au!pmiller
! \f(CW/\e/\e*\fR;Internet;pmiller@bmr.gov.au
  .TE
Index: aux/patches.sh
***************
*** 1,13 ****
  #! /bin/sh
  #
  #	aegis - project change supervisor
! #	Copyright (c) 1992-1993 Peter Miller.
  #	All rights reserved.
  #
  #	This program is free software; you can redistribute it and/or modify
  #	it under the terms of the GNU General Public License as published by
! #	the Free Software Foundation; either version 1, or (at your option)
! #	any later version.
  #
  #	This program is distributed in the hope that it will be useful,
  #	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,13 ----
  #! /bin/sh
  #
  #	aegis - project change supervisor
! #	Copyright (C) 1992, 1993 Peter Miller.
  #	All rights reserved.
  #
  #	This program is free software; you can redistribute it and/or modify
  #	it under the terms of the GNU General Public License as published by
! #	the Free Software Foundation; either version 2 of the License, or
! #	(at your option) any later version.
  #
  #	This program is distributed in the hope that it will be useful,
  #	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 34,39 ****
--- 34,40 ----
  set -e
  tmp=/tmp/$$
  tmp2=/tmp/$$.2
+ bl=`aegis -cd -bl -p $project`
  
  #
  # These files are generated
***************
*** 55,61 ****
  echo "# ------------------------------------------------------------"
  echo
  echo "#"
! echo "# Before you apply this patch,"
  echo "# please delete the following files:"
  echo "#"
  echo "rm -f $weird"
--- 56,62 ----
  echo "# ------------------------------------------------------------"
  echo
  echo "#"
! echo "# Before you apply this patch manually,"
  echo "# please delete the following files:"
  echo "#"
  echo "rm -f $weird"
***************
*** 84,90 ****
  do
  	echo "Index: $f"
  	set +e
! 	diff -c /dev/null $f | sed '1,2d'
  	set -e
  done
  
--- 85,97 ----
  do
  	echo "Index: $f"
  	set +e
! 	if [ -f $f ]
! 	then
! 		fn=$f
! 	else
! 		fn=$bl/$f
! 	fi
! 	diff -c /dev/null $fn | sed '1,2d'
  	set -e
  done
  
***************
*** 100,106 ****
  do
  	aegis -cp $f -delta 1 -output $tmp -p $project -c $change
  	set +e
! 	if diff -c $tmp $f > $tmp2 2> /dev/null
  	then
  		set -e
  	else
--- 107,119 ----
  do
  	aegis -cp $f -delta 1 -output $tmp -p $project -c $change
  	set +e
! 	if [ -f $f ]
! 	then
! 		fn=$f
! 	else
! 		fn=$bl/$f
! 	fi
! 	if diff -c $tmp $fn > $tmp2 2> /dev/null
  	then
  		set -e
  	else
Index: common/ansi.c
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 23,28 ****
--- 23,29 ----
  #include <stddef.h>
  #include <stdio.h>
  #include <string.h>
+ #include <time.h>
  
  #include <main.h>
  #include <conf.h>
***************
*** 68,71 ****
      return sys_errlist[n];
  }
  
! #endif /* CONF_NO_STRERROR */
--- 69,519 ----
      return sys_errlist[n];
  }
  
! #endif /* CONF_NO_strerror */
! 
! 
! /*
!  *  NAME
!  *      strftime - string from time
!  *
!  *  SYNOPSIS
!  *      size_t strftime(char *s, size_t maxsize, const char *format,
!  *		const struct tm *timeptr);
!  *
!  *  DESCRIPTION
!  *      The strftime function places characters into the array pointed to
!  *	by s as controlled by the string pointed to by format.  The format
!  *	string consists of zero or more directives and ordinary characters.
!  *	A directive consists of a % character followed by a character that
!  *	determined the dirrective's behaviour.  All ordinary characters
!  *	(including the terminating null character) are copied unchanged
!  *	into the array.  No more thaqn maxsize characters are placed into
!  *	the array.  Each directive is replaced by appropriate characters as
!  *	described in the following list.  The appropriate characters are
!  *	determined by the program's locale and by the values contained in
!  *	the structure pointed to by timeptr.
!  *
!  *	%a is replaced by the locale's abbreviated weekday name
!  *	%A is replaced by the locale's full weekday name
!  *	%b is replaced by the locale's abbreviated month name
!  *	%B is replaced by the locale's full month name
!  *	%c is replaced by the locale's appropriae date and time representation
!  *	%d is replaced by the day of the month as decimal number (01-31)
!  *	%H is replaced by the hour (24-hour clock) as decimal number (00-23)
!  *	%I is replaced by the hour (12-hour clock) as decimal number (01-12)
!  *	%j is replaced by the day of te year as decimal number (001-366)
!  *	%m is replaced by the month as decomal number (01-12)
!  *	%M is replaced by the minute as decimal number (00-59)
!  *	%p is replaced by the locale's equivalent of either AM or PM
!  *	%S is replaced by the second as decimal number (00-59)
!  *	%U is replaced by the week number of they year (Sunday as the first
!  *		day of the week) as decimal number (00-52)
!  *	%w is replaced by the weekday as decimal number (0=Sunday to 6=Saturday)
!  *	%W is replaced by the week number of the year (Monday as the first
!  *		day of the week) as decimal number (00-52)
!  *	%x is replaced by the locale's appropriate date representation
!  *	%X is replaced by the locale's appropriate time representation
!  *	%y is replaced by the year without century as decimal number (00-99)
!  *	%Y is replaced by the year with century as decimal number
!  *	%Z is replaced by the time zone name, or no characters in no time
!  *		zone name is available
!  *	%% is replaced by %
!  *
!  *  RETURNS
!  *	If the total number of resulting characters including the terminating
!  *	null character is not more than maxsize, the strftime function returns
!  *	the number of characters placed into the array pointed to by s not
!  *	including the terminating null character.  Otherwise, zero is returned
!  *	and the contents of the array are indeterminate.
!  *
!  *  CAVEAT
!  *      This suffers from a serious design flaw: there is no way to
!  *	distinguish between a result which is the empty string, and a result
!  *	which is more than maxsize characters.
!  *
!  *	The behaviour for unknow directivbes is not only undefined,
!  *	it is unmentioned!  (Normally the standard specifically allows
!  *	implementation defined behaviour on weird boundary conditions.)
!  *	This implementation will echo unknown directives into the output.
!  */
! 
! #ifdef CONF_NO_strftime
! 
! #ifdef SYSV
! extern char *tzname[2];
! #endif
! 
! size_t
! strftime(buf, max, fmt, tm)
! 	char		*buf;
! 	size_t		max;
! 	char		*fmt;
! 	struct tm	*tm;
! {
! 	char		*cp;
! 	char		*end;
! 	char		output[1000];
! 	int		n;
! 	size_t		len;
! 
! 	static char *weekday[] =
! 	{
! 		"Sunday",
! 		"Monday",
! 		"Tuesday",
! 		"Wednesday",
! 		"Thrusday",
! 		"Friday",
! 		"Saturday",
! 	};
! 
! 	static char *month[] =
! 	{
! 		"January",
! 		"February",
! 		"March",
! 		"April",
! 		"May",
! 		"June",
! 		"July",
! 		"August",
! 		"September",
! 		"October",
! 		"November",
! 		"December",
! 	};
! 
! 	end = buf + max - 1;
! 	cp = buf;
! 	while (*fmt)
! 	{
! 		if (*fmt++ != '%')
! 		{
! 			if (cp >= end)
! 				return 0;
! 			*cp++ = fmt[-1];
! 			continue;
! 		}
! 		switch (*fmt++)
! 		{
! 		case 0:
! 			--fmt;
! 			output[0] = '%';
! 			output[1] = 0;
! 			break;
! 
! 		default:
! 			output[0] = '%';
! 			output[1] = fmt[-1];
! 			output[2] = 0;
! 			break;
! 
! 		case '%':
! 			output[0] = '%';
! 			output[1] = 0;
! 			break;
! 
! 		case 'a':
! 			/*
! 			 * the abbreviated weekday name
! 			 */
! 			sprintf(output, "%3.3s", weekday[tm->tm_wday]);
! 			break;
! 
! 		case 'A':
! 			/*
! 			 * the full weekday name
! 			 */
! 			strcpy(output, weekday[tm->tm_wday]);
! 			break;
! 
! 		case 'b':
! 		case 'h':
! 			/*
! 			 * the abbreviated month name
! 			 */
! 			sprintf(output, "%3.3s", month[tm->tm_mon]);
! 			break;
! 
! 		case 'B':
! 			/*
! 			 * the full month name
! 			 */
! 			strcpy(output, month[tm->tm_mon]);
! 			break;
! 
! 		case 'c':
! 			/*
! 			 * the date and time
! 			 */
! 			len = strftime(output, sizeof(output), "%b %e %X %Y", tm);
! 			if (!len)
! 				output[0] = 0;
! 			break;
! 
! 		case 'C':
! 			/*
! 			 * This looks like a Sun extra.
! 			 * Local date.
! 			 */
! 			len = strftime(output, sizeof(output), "%A, %B %e, %Y", tm);
! 			if (!len)
! 				output[0] = 0;
! 			break;
! 		
! 		case 'd':
! 			/*
! 			 * the day of the month,
! 			 * zero padded.
! 			 */
! 			sprintf(output, "%2.2d", tm->tm_mday);
! 			break;
! 		
! 		case 'D':
! 			/*
! 			 * This looks like a Sun extra.
! 			 * Local date.
! 			 */
! 			len = strftime(output, sizeof(output), "%m/%d/%y", tm);
! 			if (!len)
! 				output[0] = 0;
! 			break;
! 
! 		case 'e':
! 			/*
! 			 * This looks like a Sun extra.
! 			 * the day of the month,
! 			 * blank padded.
! 			 */
! 			sprintf(output, "%2d", tm->tm_mday);
! 			break;
! 
! 		case 'H':
! 			/*
! 			 * the hour of a 24-hour day
! 			 * zero padded
! 			 */
! 			sprintf(output, "%2.2d", tm->tm_hour);
! 			break;
! 
! 		case 'I':
! 			/*
! 			 * the hour of a 12-hour day,
! 			 * zero padded
! 			 */
! 			n = tm->tm_hour % 12;
! 			sprintf(output, "%2.2d", n ? n : 12);
! 			break;
! 
! 		case 'j':
! 			/*
! 			 * the day of the year,
! 			 * zero padded, one based
! 			 */
! 			sprintf(output, "%3.3d", tm->tm_yday + 1);
! 			break;
! 
! 		case 'k':
! 			/*
! 			 * This looks like a Sun extra.
! 			 * the hour of the 24-hour day,
! 			 * blank padded.
! 			 */
! 			sprintf(output, "%2d", tm->tm_hour);
! 			break;
! 
! 		case 'l':
! 			/*
! 			 * This looks like a Sun extra.
! 			 * the hour of the 12-hour day,
! 			 * blank padded.
! 			 */
! 			n = tm->tm_hour % 12;
! 			sprintf(output, "%2d", n ? n : 12);
! 			break;
! 
! 		case 'm':
! 			/*
! 			 * the month of the year,
! 			 * zero padded, one based.
! 			 */
! 			sprintf(output, "%2.2d", tm->tm_mon + 1);
! 			break;
! 
! 		case 'M':
! 			/*
! 			 * the minute of the hour,
! 			 * zero padded
! 			 */
! 			sprintf(output, "%2.2d", tm->tm_min);
! 			break;
! 
! 		case 'n':
! 			/*
! 			 * This looks like a Sun extra.
! 			 * like \n
! 			 */
! 			output[0] = '\n';
! 			output[1] = 0;
! 			break;
! 
! 		case 'p':
! 			/*
! 			 * meridian indicator
! 			 */
! 			if (tm->tm_hour >= 12)
! 				strcpy(output, "PM");
! 			else
! 				strcpy(output, "AM");
! 			break;
! 
! 		case 'r':
! 			/*
! 			 * this looks like a Sun extra.
! 			 * like %X, but 12-hour clock with meridian.
! 			 */
! 			len = strftime(output, sizeof(output), "%I:%M:%S %p", tm);
! 			if (!len)
! 				output[0] = 0;
! 			break;
! 
! 		case 'R':
! 			/*
! 			 * this looks like a Sun extra.
! 			 * the 24-hour time as HH:MM
! 			 */
! 			len = strftime(output, sizeof(output), "%H:%M", tm);
! 			if (!len)
! 				output[0] = 0;
! 			break;
! 
! 		case 'S':
! 			/*
! 			 * seconds of the minute
! 			 */
! 			sprintf(output, "%2.2d", tm->tm_sec);
! 			break;
! 
! 		case 't':
! 			/*
! 			 * this looks like a Sun extra.
! 			 * like \t
! 			 */
! 			output[0] = '\t';
! 			output[1] = 0;
! 			break;
! 
! 		case 'T':
! 			/*
! 			 * This looks like a Sun extra.
! 			 * the 24-hour time as HH:MM:SS
! 			 */
! 			len = strftime(output, sizeof(output), "%H:%M:%S", tm);
! 			if (!len)
! 				output[0] = 0;
! 			break;
! 
! 		case 'U':
! 			/*
! 			 * the Sunday week of the year
! 			 */
! 			n = (tm->tm_yday - tm->tm_wday + 5) / 7;
! 			sprintf(output, "%2.2d", n);
! 			break;
! 
! 		case 'w':
! 			/*
! 			 * the day of the week,
! 			 * Sunday = 0
! 			 */
! 			sprintf(output, "%d", tm->tm_wday);
! 			break;
! 
! 		case 'W':
! 			/*
! 			 * the Monday week of the year
! 			 */
! 			n = (tm->tm_yday - ((tm->tm_wday + 6) % 7) + 5) / 7;
! 			sprintf(output, "%2.2d", n);
! 			break;
! 
! 		case 'x':
! 			/*
! 			 * the date, as mmm dd yyyy
! 			 */
! 			len = strftime(output, sizeof(output), "%b %d %Y", tm);
! 			if (!len)
! 				output[0] = 0;
! 			break;
! 
! 		case 'X':
! 			/*
! 			 * the time as hh:mm:ss
! 			 */
! 			len = strftime(output, sizeof(output), "%H:%M:%S", tm);
! 			if (!len)
! 				output[0] = 0;
! 			break;
! 
! 		case 'y':
! 			/*
! 			 * the year of the century
! 			 */
! 			sprintf(output, "%2.2d", tm->tm_year % 100);
! 			break;
! 
! 		case 'Y':
! 			/*
! 			 * the year including century
! 			 */
! 			sprintf(output, "%4.4d", tm->tm_year + 1900);
! 			break;
! 
! 		case 'Z':
! 			/*
! 			 * the timezone name, if any
! 			 */
! #ifdef SYSV
! 			if (tm->tm_isdst >= 0 && tm->tm_isdst <= 1)
! 				strcpy(output, tzname[tm->tm_isdst]);
! 			else
! 				output[0] = 0;
! #else
! 			/* Berkeley derivateives have extra tm field */
! 			strcpy(output, tm->tm_zone);
! #endif
! 			break;
! 		}
! 
! 		/*
! 		 * make sure it fits in the buffer
! 		 */
! 		len = strlen(output);
! 		if (cp + len > end)
! 			return -1;
! 		memcpy(cp, output, len);
! 		cp += len;
! 	}
! 	*cp = 0;
! 	return (cp - buf);
! }
! 
! #endif /* CONF_NO_strftime */
! 
! #ifdef CONF_HAS_seuid
! 
! int
! seteuid(x)
! 	int	x;
! {
! 	return setresuid(-1, x, -1);
! }
! 
! int
! setegid(x)
! 	int	x;
! {
! 	return setresgid(-1, x, -1);
! }
! 
! #endif
Index: common/arglex.c
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 30,36 ****
  #include <str.h>
  #include <trace.h>
  
! static arglex_table_t table[] =
  {
  	{ "-",			arglex_token_stdio,		},
  	{ "-Help",		arglex_token_help,		},
--- 30,36 ----
  #include <str.h>
  #include <trace.h>
  
! static arglex_table_ty table[] =
  {
  	{ "-",			arglex_token_stdio,		},
  	{ "-Help",		arglex_token_help,		},
***************
*** 40,56 ****
  
  static	int		argc;
  static	char		**argv;
! 	arglex_value_t	arglex_value;
! 	arglex_token_t	arglex_token;
! static	arglex_table_t	*utable;
  static	char		*partial;
  
  
  void
  arglex_init(ac, av, tp)
  	int		ac;
  	char		**av;
! 	arglex_table_t	*tp;
  {
  	option_set_progname(av[0]);
  	argc = ac - 1;
--- 40,76 ----
  
  static	int		argc;
  static	char		**argv;
! 	arglex_value_ty	arglex_value;
! 	arglex_token_ty	arglex_token;
! static	arglex_table_ty	*utable;
  static	char		*partial;
  
  
+ /*
+  * NAME
+  *	arglex_init
+  *
+  * SYNOPSIS
+  *	void arglex_init(int ac, char **av, arglex_table-t *tp);
+  *
+  * DESCRIPTION
+  *	The arglex_init function is used to initialize the
+  *	command line processing.
+  *
+  * ARGUMENTS
+  *	ac	- aergument count, from main
+  *	av	- argument values, from main
+  *	tp	- pointer to table of options
+  *
+  * CAVEAT
+  *	Must be called before the arglex() function.
+  */
+ 
  void
  arglex_init(ac, av, tp)
  	int		ac;
  	char		**av;
! 	arglex_table_ty	*tp;
  {
  	option_set_progname(av[0]);
  	argc = ac - 1;
***************
*** 59,66 ****
  }
  
  
  int
! argcmp(formal, actual)
  	char	*formal;
  	char	*actual;
  {
--- 79,135 ----
  }
  
  
+ /*
+  * NAME
+  *	arglex_compare
+  *
+  * SYNOPSIS
+  *	int arglex_compare(char *formal, char *actual);
+  *
+  * DESCRIPTION
+  *	The arglex_compare function is used to compare
+  *	a command line string with a formal spec of the option,
+  *	to see if they compare equal.
+  *
+  *	The actual is case-insensitive.  Uppercase in the formal
+  *	means a mandatory character, while lower case means optional.
+  *	Any number of consecutive optional characters may be supplied
+  *	by actual, but none may be skipped, unless all are skipped to
+  *	the next non-lower-case letter.
+  *
+  *	The underscore (_) is like a lower-case minus,
+  *	it matches "", "-" and "_".
+  *
+  *	The "*" in a pattern matches everything to the end of the line,
+  *	anything after the "*" is ignored.  The rest of the line is pointed
+  *	to by the "partial" variable as a side-effect (else it will be 0).
+  *	This rather ugly feature is to support "-I./dir" type options.
+  *
+  *	A backslash in a pattern nominates an exact match required,
+  *	case must matche excatly here.
+  *	This rather ugly feature is to support "-I./dir" type options.
+  *
+  *	For example: "-project" and "-P' both match "-Project",
+  *	as does "-proJ", but "-prj" does not.
+  *
+  *	For example: "-devDir" and "-d_d' both match "-Development_Directory",
+  *	but "-dvlpmnt_drctry" does not.
+  *
+  *	For example: to match include path specifications, use a pattern
+  *	such as "-\\I*", and the partial global variable will have the
+  *	path in it on return.
+  *
+  * ARGUMENTS
+  *	formal	- the "pattern" for the option
+  *	actual	- what the user supplied
+  *
+  * RETURNS
+  *	int;	zero if no match,
+  *		non-zero if they do match.
+  */
+ 
  int
! arglex_compare(formal, actual)
  	char	*formal;
  	char	*actual;
  {
***************
*** 68,74 ****
  	char	ac;
  	int	result;
  
! 	trace(("argcmp(formal = \"%s\", actual = \"%s\")\n{\n", formal, actual));
  	for (;;)
  	{
  		trace_string(formal);
--- 137,144 ----
  	char	ac;
  	int	result;
  
! 	trace(("arglex_compare(formal = \"%s\", actual = \"%s\")\n{\n",
! 		formal, actual));
  	for (;;)
  	{
  		trace_string(formal);
***************
*** 81,87 ****
  		{
  		case 0:
  			result = !ac;
! 			goto ret;
  			
  		case '_':
  			if (ac == '-')
--- 151,157 ----
  		{
  		case 0:
  			result = !ac;
! 			goto done;
  			
  		case '_':
  			if (ac == '-')
***************
*** 97,106 ****
  			/*
  			 * optional characters
  			 */
! 			if (ac == fc && argcmp(formal, actual))
  			{
  				result = 1;
! 				goto ret;
  			}
  
  			/*
--- 167,176 ----
  			/*
  			 * optional characters
  			 */
! 			if (ac == fc && arglex_compare(formal, actual))
  			{
  				result = 1;
! 				goto done;
  			}
  
  			/*
***************
*** 127,143 ****
  			if (!ac)
  			{
  				result = 0;
! 				goto ret;
  			}
  			partial = actual - 1;
  			result = 1;
! 			goto ret;
  
  		case '\\':
  			if (actual[-1] != *formal++)
  			{
  				result = 0;
! 				goto ret;
  			}
  			break;
  
--- 197,213 ----
  			if (!ac)
  			{
  				result = 0;
! 				goto done;
  			}
  			partial = actual - 1;
  			result = 1;
! 			goto done;
  
  		case '\\':
  			if (actual[-1] != *formal++)
  			{
  				result = 0;
! 				goto done;
  			}
  			break;
  
***************
*** 157,173 ****
  			if (fc != ac)
  			{
  				result = 0;
! 				goto ret;
  			}
  			break;
  		}
  	}
! ret:
  	trace(("return %d;\n}\n", result));
  	return result;
  }
  
  
  static int is_a_number _((char *));
  
  static int
--- 227,272 ----
  			if (fc != ac)
  			{
  				result = 0;
! 				goto done;
  			}
  			break;
  		}
  	}
! 	done:
  	trace(("return %d;\n}\n", result));
  	return result;
  }
  
  
+ /*
+  * NAME
+  *	is_a_number
+  *
+  * SYNOPSIS
+  *	int is_a_number(char *s);
+  *
+  * DESCRIPTION
+  *	The is_a_number function is used to determine if the
+  *	argument is a number.
+  *
+  *	The value is placed in arglex_value.alv_number as
+  *	a side effect.
+  *
+  *	Negative and positive signs are accepted.
+  *	The C conventions for decimal, octal and hexadecimal are understood.
+  *
+  *	There may be no white space anywhere in the string,
+  *	and the string must end after the last digit.
+  *	Trailing garbage will be interpreted to mean it is not a string.
+  *
+  * ARGUMENTS
+  *	s	- string to be tested and evaluated
+  *
+  * RETURNS
+  *	int;	zero if not a number,
+  *		non-zero if is a number.
+  */
+ 
  static int is_a_number _((char *));
  
  static int
***************
*** 265,300 ****
  }
  
  
! arglex_token_t
  arglex()
  {
! 	arglex_table_t	*tp;
  	int		j;
! 	arglex_table_t	*hit[20];
  	int		nhit;
  
  	trace(("arglex()\n{\n"));
! 	if (argc <= 0)
  	{
! 		arglex_token = arglex_token_eoln;
! 		arglex_value.alv_string = "";
! 		goto ret;
  	}
! 	arglex_value.alv_string = argv[0];
! 	argc--;
! 	argv++;
  
! 	if (is_a_number(arglex_value.alv_string))
  	{
  		arglex_token = arglex_token_number;
! 		goto ret;
  	}
  
  	nhit = 0;
  	partial = 0;
  	for (tp = table; tp < ENDOF(table); tp++)
  	{
! 		if (argcmp(tp->t_name, arglex_value.alv_string))
  			hit[nhit++] = tp;
  	}
  	if (utable)
--- 364,474 ----
  }
  
  
! /*
!  * NAME
!  *	arglex
!  *
!  * SYNOPSIS
!  *	arglex_token_ty arglex(void);
!  *
!  * DESCRIPTION
!  *	The arglex function is used to perfom lexical analysis
!  *	on the command line arguments.
!  *
!  *	Unrecognised options are returned as arglex_token_option
!  *	for anything starting with a '-', or
!  *	arglex_token_string otherwise.
!  *
!  * RETURNS
!  *	The next token in the token stream.
!  *	When the end is reached, arglex_token_eoln is returned forever.
!  *
!  * CAVEAT
!  *	Must call arglex_init befor this function is called.
!  */
! 
! arglex_token_ty
  arglex()
  {
! 	arglex_table_ty	*tp;
  	int		j;
! 	arglex_table_ty	*hit[20];
  	int		nhit;
+ 	static char	*pushback;
+ 	char		*arg;
  
  	trace(("arglex()\n{\n"));
! 	if (pushback)
  	{
! 		/*
! 		 * the second half of a "-foo=bar" style argument.
! 		 */
! 		arg = pushback;
! 		pushback = 0;
  	}
! 	else
! 	{
! 		if (argc <= 0)
! 		{
! 			arglex_token = arglex_token_eoln;
! 			arg = "";
! 			goto done;
! 		}
! 		arg = argv[0];
! 		argc--;
! 		argv++;
  
! 		/*
! 		 * See if it looks like a GNU "-foo=bar" option.
! 		 * Split it at the '=' to make it something the
! 		 * rest of the code understands.
! 		 */
! 		if (arg[0] == '-' && arg[1] != '=')
! 		{
! 			char	*eqp;
! 
! 			eqp = strchr(arg, '=');
! 			if (eqp)
! 			{
! 				pushback = eqp + 1;
! 				*eqp = 0;
! 			}
! 		}
! 
! 		/*
! 		 * Turn the GNU-style leading "--"
! 		 * into "-" if necessary.
! 		 */
! 		if
! 		(
! 			arg[0] == '-'
! 		&&
! 			arg[1] == '-'
! 		&&
! 			arg[2]
! 		&&
! 			!is_a_number(arg + 1)
! 		)
! 			++arg;
! 	}
! 
! 	/*
! 	 * see if it is a number
! 	 */
! 	if (is_a_number(arg))
  	{
  		arglex_token = arglex_token_number;
! 		goto done;
  	}
  
+ 	/*
+ 	 * scan the tables to see what it matches
+ 	 */
  	nhit = 0;
  	partial = 0;
  	for (tp = table; tp < ENDOF(table); tp++)
  	{
! 		if (arglex_compare(tp->t_name, arg))
  			hit[nhit++] = tp;
  	}
  	if (utable)
***************
*** 301,327 ****
  	{
  		for (tp = utable; tp->t_name; tp++)
  		{
! 			if (argcmp(tp->t_name, arglex_value.alv_string))
  				hit[nhit++] = tp;
  		}
  	}
  	switch (nhit)
  	{
  	case 0:
  		break;
  
  	case 1:
  		arglex_token = hit[0]->t_token;
  		if (partial)
! 			arglex_value.alv_string = partial;
  		else
! 			arglex_value.alv_string = hit[0]->t_name;
! 		goto ret;
  
  	default:
  		{
! 			string_t	*s1;
! 			string_t	*s2;
  
  			s1 = str_from_c(hit[0]->t_name);
  			for (j = 1; j < nhit; ++j)
--- 475,512 ----
  	{
  		for (tp = utable; tp->t_name; tp++)
  		{
! 			if (arglex_compare(tp->t_name, arg))
  				hit[nhit++] = tp;
  		}
  	}
+ 
+ 	/*
+ 	 * deal with unknown or ambiguous options
+ 	 */
  	switch (nhit)
  	{
  	case 0:
+ 		/*
+ 		 * not found in the tables
+ 		 */
+ 		if (*arg == '-')
+ 			arglex_token = arglex_token_option;
+ 		else
+ 			arglex_token = arglex_token_string;
  		break;
  
  	case 1:
  		arglex_token = hit[0]->t_token;
  		if (partial)
! 			arg = partial;
  		else
! 			arg = hit[0]->t_name;
! 		break;
  
  	default:
  		{
! 			string_ty	*s1;
! 			string_ty	*s2;
  
  			s1 = str_from_c(hit[0]->t_name);
  			for (j = 1; j < nhit; ++j)
***************
*** 333,339 ****
  			fatal
  			(
  				"option \"%s\" abmiguous (%s)",
! 				arglex_value.alv_string,
  				s1->str_text
  			);
  		}
--- 518,524 ----
  			fatal
  			(
  				"option \"%s\" abmiguous (%s)",
! 				arg,
  				s1->str_text
  			);
  		}
***************
*** 340,356 ****
  	}
  
  	/*
- 	 * not found in the table
- 	 */
- 	if (arglex_value.alv_string[0] == '-')
- 		arglex_token = arglex_token_option;
- 	else
- 		arglex_token = arglex_token_string;
- 
- 	/*
  	 * here for all exits
  	 */
! 	ret:
  	trace(("return %d; /* %s */\n", arglex_token, arglex_value.alv_string));
  	trace((/*{*/"}\n"));
  	return arglex_token;
--- 525,534 ----
  	}
  
  	/*
  	 * here for all exits
  	 */
! 	done:
! 	arglex_value.alv_string = arg;
  	trace(("return %d; /* %s */\n", arglex_token, arglex_value.alv_string));
  	trace((/*{*/"}\n"));
  	return arglex_token;
Index: common/arglex.h
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 25,31 ****
  
  #include <main.h>
  
! enum arglex_token_t
  {
  	arglex_token_eoln = -20,
  	arglex_token_help,
--- 25,31 ----
  
  #include <main.h>
  
! enum arglex_token_ty
  {
  	arglex_token_eoln = -20,
  	arglex_token_help,
***************
*** 36,62 ****
  	arglex_token_trace,
  	arglex_token_version
  };
! typedef enum arglex_token_t arglex_token_t;
  
! typedef struct arglex_table_t arglex_table_t;
! struct arglex_table_t
  {
  	char		*t_name;
! 	arglex_token_t	t_token;
  };
  
! typedef struct arglex_value_t arglex_value_t;
! struct arglex_value_t
  {
  	char	*alv_string;
  	long	alv_number;
  };
  
! extern arglex_token_t arglex_token;
! extern arglex_value_t arglex_value;
  
! void arglex_init _((int, char **, arglex_table_t *));
! arglex_token_t arglex _((void));
! int argcmp _((char *formal, char *actual));
  
  #endif /* ARGLEX_H */
--- 36,62 ----
  	arglex_token_trace,
  	arglex_token_version
  };
! typedef enum arglex_token_ty arglex_token_ty;
  
! typedef struct arglex_table_ty arglex_table_ty;
! struct arglex_table_ty
  {
  	char		*t_name;
! 	arglex_token_ty	t_token;
  };
  
! typedef struct arglex_value_ty arglex_value_ty;
! struct arglex_value_ty
  {
  	char	*alv_string;
  	long	alv_number;
  };
  
! extern arglex_token_ty arglex_token;
! extern arglex_value_ty arglex_value;
  
! void arglex_init _((int, char **, arglex_table_ty *));
! arglex_token_ty arglex _((void));
! int arglex_compare _((char *formal, char *actual));
  
  #endif /* ARGLEX_H */
Index: common/error.c
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 40,45 ****
--- 40,71 ----
  #define HUGE_BUFFER 6000
  
  
+ static void error_get_id _((int *, int *));
+ 
+ static void
+ error_get_id(uid, gid)
+ 	int	*uid;
+ 	int	*gid;
+ {
+ 	*uid = geteuid();
+ 	*gid = getegid();
+ }
+ 
+ 
+ static	error_id_ty errid = error_get_id;
+ 
+ 
+ void
+ error_set_id_func(f)
+ 	error_id_ty	f;
+ {
+ 	if (f)
+ 		errid = f;
+ 	else
+ 		errid = error_get_id;
+ }
+ 
+ 
  /*
   * NAME
   *	wrap - wrap s string over lines
***************
*** 190,196 ****
  	struct group	*gr;
  	char		gidn[20];
  
! 	uid = geteuid();
  	pw = getpwuid(uid);
  	if (pw)
  		sprintf(uidn, "user \"%.8s\"", pw->pw_name);
--- 216,222 ----
  	struct group	*gr;
  	char		gidn[20];
  
! 	errid(&uid, &gid);
  	pw = getpwuid(uid);
  	if (pw)
  		sprintf(uidn, "user \"%.8s\"", pw->pw_name);
***************
*** 197,203 ****
  	else
  		sprintf(uidn, "uid %d", uid);
  
- 	gid = getegid();
  	gr = getgrgid(gid);
  	if (gr)
  		sprintf(gidn, "group \"%.8s\"", gr->gr_name);
--- 223,228 ----
***************
*** 567,579 ****
  }
  
  
! static	quit_t	quit_list[10];
  static	int	quit_list_len;
  
  
  void
  quit_register(func)
! 	quit_t	func;
  {
  	assert(quit_list_len < SIZEOF(quit_list));
  	assert(func);
--- 592,604 ----
  }
  
  
! static	quit_ty	quit_list[10];
  static	int	quit_list_len;
  
  
  void
  quit_register(func)
! 	quit_ty	func;
  {
  	assert(quit_list_len < SIZEOF(quit_list));
  	assert(func);
***************
*** 583,592 ****
  
  void
  quit(n)
! 	int	n;
  {
! 	int	j;
  
  	for (j = quit_list_len - 1; j >= 0; --j)
  		quit_list[j](n);
  	exit(n);
--- 608,629 ----
  
  void
  quit(n)
! 	int		n;
  {
! 	int		j;
! 	static int	quitting;
  
+ 	if (quitting > 4)
+ 	{
+ 		fprintf
+ 		(
+ 			stderr,
+ 			"%s: incorrectly handled error while quitting (bug)\n",
+ 			option_get_progname()
+ 		);
+ 		exit(1);
+ 	}
+ 	++quitting;
  	for (j = quit_list_len - 1; j >= 0; --j)
  		quit_list[j](n);
  	exit(n);
Index: common/error.h
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 32,39 ****
  void nerror _((char *, ...));
  void nfatal _((char *, ...));
  
! typedef void (*quit_t)_((int));
! void quit_register _((quit_t));
  void quit _((int));
  
  char *signal_name _((int));
--- 32,39 ----
  void nerror _((char *, ...));
  void nfatal _((char *, ...));
  
! typedef void (*quit_ty)_((int));
! void quit_register _((quit_ty));
  void quit _((int));
  
  char *signal_name _((int));
***************
*** 48,52 ****
--- 48,56 ----
  #else
  # define assert(c)
  #endif
+ 
+ typedef void (*error_id_ty)_((int *uid, int *gid));
+ 
+ void error_set_id_func _((error_id_ty));
  
  #endif /* ERROR_H */
Index: common/main.h
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
Index: common/mem.c
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
Index: common/mem.h
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
Index: common/option.c
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 30,36 ****
  #include <trace.h>
  
  
! #define MIN_PAGE_WIDTH 20
  /* #define MAX_PAGE_WIDTH in option.h */
  #define DEFAULT_PAGE_WIDTH 79 /* don't use 80, many terminals really stupid */
  #define MIN_PAGE_LENGTH 10
--- 30,36 ----
  #include <trace.h>
  
  
! #define MIN_PAGE_WIDTH 40
  /* #define MAX_PAGE_WIDTH in option.h */
  #define DEFAULT_PAGE_WIDTH 79 /* don't use 80, many terminals really stupid */
  #define MIN_PAGE_LENGTH 10
Index: common/option.h
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
Index: common/s-v-arg.h
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
Index: common/str.c
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 45,58 ****
   */
  #define MAX_WIDTH 509
  
! static string_t **hash_table;
! static hash_t hash_modulus;
! static hash_t hash_cutover;
! static hash_t hash_cutover_mask;
! static hash_t hash_cutover_split_mask;
! static hash_t hash_split;
! static hash_t hash_load;
! static int changed;
  
  #define MAX_HASH_LEN 20
  
--- 45,58 ----
   */
  #define MAX_WIDTH 509
  
! static	string_ty	**hash_table;
! static	str_hash_ty	hash_modulus;
! static	str_hash_ty	hash_cutover;
! static	str_hash_ty	hash_cutover_mask;
! static	str_hash_ty	hash_cutover_split_mask;
! static	str_hash_ty	hash_split;
! static	str_hash_ty	hash_load;
! static	int		changed;
  
  #define MAX_HASH_LEN 20
  
***************
*** 62,88 ****
   *	hash_generate - hash string to number
   *
   * SYNOPSIS
!  *	hash_t hash_generate(char *s, size_t n);
   *
   * DESCRIPTION
   *	The hash_generate function is used to make a number from a string.
   *
   * RETURNS
!  *	hash_t - the magic number
   *
   * CAVEAT
   *	Only the last MAX_HASH_LEN characters are used.
!  *	It is important that hash_t be unsigned (int or long).
   */
  
! static hash_t hash_generate _((char *, size_t));
  
! static hash_t
  hash_generate(s, n)
  	char		*s;
  	size_t		n;
  {
! 	hash_t		retval;
  
  	if (n > MAX_HASH_LEN)
  	{
--- 62,88 ----
   *	hash_generate - hash string to number
   *
   * SYNOPSIS
!  *	str_hash_ty hash_generate(char *s, size_t n);
   *
   * DESCRIPTION
   *	The hash_generate function is used to make a number from a string.
   *
   * RETURNS
!  *	str_hash_ty - the magic number
   *
   * CAVEAT
   *	Only the last MAX_HASH_LEN characters are used.
!  *	It is important that str_hash_ty be unsigned (int or long).
   */
  
! static str_hash_ty hash_generate _((char *, size_t));
  
! static str_hash_ty
  hash_generate(s, n)
  	char		*s;
  	size_t		n;
  {
! 	str_hash_ty	retval;
  
  	if (n > MAX_HASH_LEN)
  	{
***************
*** 121,127 ****
  void
  str_initialize()
  {
! 	hash_t		j;
  
  	hash_modulus = 1<<8; /* MUST be a power of 2 */
  	hash_cutover = hash_modulus;
--- 121,127 ----
  void
  str_initialize()
  {
! 	str_hash_ty	j;
  
  	hash_modulus = 1<<8; /* MUST be a power of 2 */
  	hash_cutover = hash_modulus;
***************
*** 129,135 ****
  	hash_cutover_mask = hash_cutover - 1;
  	hash_cutover_split_mask = (hash_cutover * 2) - 1;
  	hash_load = 0;
! 	hash_table = (string_t **)mem_alloc(hash_modulus * sizeof(string_t *));
  	for (j = 0; j < hash_modulus; ++j)
  		hash_table[j] = 0;
  }
--- 129,135 ----
  	hash_cutover_mask = hash_cutover - 1;
  	hash_cutover_split_mask = (hash_cutover * 2) - 1;
  	hash_load = 0;
! 	hash_table = (string_ty **)mem_alloc(hash_modulus * sizeof(string_ty *));
  	for (j = 0; j < hash_modulus; ++j)
  		hash_table[j] = 0;
  }
***************
*** 157,165 ****
  static void
  split()
  {
! 	string_t	*p;
! 	string_t	*p2;
! 	hash_t		index;
  
  	/*
  	 * get the list to be split across buckets
--- 157,165 ----
  static void
  split()
  {
! 	string_ty	*p;
! 	string_ty	*p2;
! 	str_hash_ty	index;
  
  	/*
  	 * get the list to be split across buckets
***************
*** 171,177 ****
  	 * increase the modulus by one
  	 */
  	hash_modulus++;
! 	mem_change_size((char **)&hash_table, hash_modulus * sizeof(string_t*));
  	hash_table[hash_modulus - 1] = 0;
  	hash_split = hash_modulus - hash_cutover;
  	if (hash_split >= hash_cutover)
--- 171,177 ----
  	 * increase the modulus by one
  	 */
  	hash_modulus++;
! 	mem_change_size((char **)&hash_table, hash_modulus * sizeof(string_ty*));
  	hash_table[hash_modulus - 1] = 0;
  	hash_split = hash_modulus - hash_cutover;
  	if (hash_split >= hash_cutover)
***************
*** 204,210 ****
   *	str_from_c - make string from C string
   *
   * SYNOPSIS
!  *	string_t *str_from_c(char*);
   *
   * DESCRIPTION
   *	The str_from_c function is used to make a string from a null terminated
--- 204,210 ----
   *	str_from_c - make string from C string
   *
   * SYNOPSIS
!  *	string_ty *str_from_c(char*);
   *
   * DESCRIPTION
   *	The str_from_c function is used to make a string from a null terminated
***************
*** 211,217 ****
   *	C string.
   *
   * RETURNS
!  *	string_t* - a pointer to a string in dynamic memory.  Use str_free when
   *	finished with.
   *
   * CAVEAT
--- 211,217 ----
   *	C string.
   *
   * RETURNS
!  *	string_ty* - a pointer to a string in dynamic memory.  Use str_free when
   *	finished with.
   *
   * CAVEAT
***************
*** 218,226 ****
   *	The contents of the structure pointed to MUST NOT be altered.
   */
  
! string_t *
  str_from_c(s)
! 	char	*s;
  {
  	return str_n_from_c(s, strlen(s));
  }
--- 218,226 ----
   *	The contents of the structure pointed to MUST NOT be altered.
   */
  
! string_ty *
  str_from_c(s)
! 	char		*s;
  {
  	return str_n_from_c(s, strlen(s));
  }
***************
*** 231,237 ****
   *	str_n_from_c - make string
   *
   * SYNOPSIS
!  *	string_t *str_n_from_c(char *s, size_t n);
   *
   * DESCRIPTION
   *	The str_n_from_c function is used to make a string from an array of
--- 231,237 ----
   *	str_n_from_c - make string
   *
   * SYNOPSIS
!  *	string_ty *str_n_from_c(char *s, size_t n);
   *
   * DESCRIPTION
   *	The str_n_from_c function is used to make a string from an array of
***************
*** 238,244 ****
   *	characters.  No null terminator is assumed.
   *
   * RETURNS
!  *	string_t* - a pointer to a string in dynamic memory.  Use str_free when
   *	finished with.
   *
   * CAVEAT
--- 238,244 ----
   *	characters.  No null terminator is assumed.
   *
   * RETURNS
!  *	string_ty* - a pointer to a string in dynamic memory.  Use str_free when
   *	finished with.
   *
   * CAVEAT
***************
*** 245,258 ****
   *	The contents of the structure pointed to MUST NOT be altered.
   */
  
! string_t *
  str_n_from_c(s, length)
  	char		*s;
  	size_t		length;
  {
! 	hash_t		hash;
! 	hash_t		index;
! 	string_t	*p;
  
  	hash = hash_generate(s, length);
  
--- 245,258 ----
   *	The contents of the structure pointed to MUST NOT be altered.
   */
  
! string_ty *
  str_n_from_c(s, length)
  	char		*s;
  	size_t		length;
  {
! 	str_hash_ty	hash;
! 	str_hash_ty	index;
! 	string_ty	*p;
  
  	hash = hash_generate(s, length);
  
***************
*** 276,282 ****
  		}
  	}
  
! 	p = (string_t *)mem_alloc(sizeof(string_t) + length);
  	p->str_hash = hash;
  	p->str_length = length;
  	p->str_references = 1;
--- 276,282 ----
  		}
  	}
  
! 	p = (string_ty *)mem_alloc(sizeof(string_ty) + length);
  	p->str_hash = hash;
  	p->str_length = length;
  	p->str_references = 1;
***************
*** 298,310 ****
   *	str_copy - make a copy of a string
   *
   * SYNOPSIS
!  *	string_t *str_copy(string_t *s);
   *
   * DESCRIPTION
   *	The str_copy function is used to make a copy of a string.
   *
   * RETURNS
!  *	string_t* - a pointer to a string in dynamic memory.  Use str_free when
   *	finished with.
   *
   * CAVEAT
--- 298,310 ----
   *	str_copy - make a copy of a string
   *
   * SYNOPSIS
!  *	string_ty *str_copy(string_ty *s);
   *
   * DESCRIPTION
   *	The str_copy function is used to make a copy of a string.
   *
   * RETURNS
!  *	string_ty* - a pointer to a string in dynamic memory.  Use str_free when
   *	finished with.
   *
   * CAVEAT
***************
*** 311,319 ****
   *	The contents of the structure pointed to MUST NOT be altered.
   */
  
! string_t *
  str_copy(s)
! 	string_t	*s;
  {
  	s->str_references++;
  	return s;
--- 311,319 ----
   *	The contents of the structure pointed to MUST NOT be altered.
   */
  
! string_ty *
  str_copy(s)
! 	string_ty	*s;
  {
  	s->str_references++;
  	return s;
***************
*** 325,331 ****
   *	str_free - release a string
   *
   * SYNOPSIS
!  *	void str_free(string_t *s);
   *
   * DESCRIPTION
   *	The str_free function is used to indicate that a string hash been
--- 325,331 ----
   *	str_free - release a string
   *
   * SYNOPSIS
!  *	void str_free(string_ty *s);
   *
   * DESCRIPTION
   *	The str_free function is used to indicate that a string hash been
***************
*** 340,349 ****
  
  void
  str_free(s)
! 	string_t	*s;
  {
! 	hash_t		index;
! 	string_t	**spp;
  
  	if (!s)
  		return;
--- 340,349 ----
  
  void
  str_free(s)
! 	string_ty	*s;
  {
! 	str_hash_ty	index;
! 	string_ty	**spp;
  
  	if (!s)
  		return;
***************
*** 384,390 ****
   *	str_catenate - join two strings
   *
   * SYNOPSIS
!  *	string_t *str_catenate(string_t *, string_t *);
   *
   * DESCRIPTION
   *	The str_catenate function is used to concatenate two strings to form a
--- 384,390 ----
   *	str_catenate - join two strings
   *
   * SYNOPSIS
!  *	string_ty *str_catenate(string_ty *, string_ty *);
   *
   * DESCRIPTION
   *	The str_catenate function is used to concatenate two strings to form a
***************
*** 391,397 ****
   *	new string.
   *
   * RETURNS
!  *	string_t* - a pointer to a string in dynamic memory.  Use str_free when
   *	finished with.
   *
   * CAVEAT
--- 391,397 ----
   *	new string.
   *
   * RETURNS
!  *	string_ty* - a pointer to a string in dynamic memory.  Use str_free when
   *	finished with.
   *
   * CAVEAT
***************
*** 398,411 ****
   *	The contents of the structure pointed to MUST NOT be altered.
   */
  
! string_t *
  str_catenate(s1, s2)
! 	string_t	*s1;
! 	string_t	*s2;
  {
  	static char	*tmp;
  	static size_t	tmplen;
! 	string_t	*s;
  	size_t		length;
  
  	length = s1->str_length + s2->str_length;
--- 398,411 ----
   *	The contents of the structure pointed to MUST NOT be altered.
   */
  
! string_ty *
  str_catenate(s1, s2)
! 	string_ty	*s1;
! 	string_ty	*s2;
  {
  	static char	*tmp;
  	static size_t	tmplen;
! 	string_ty	*s;
  	size_t		length;
  
  	length = s1->str_length + s2->str_length;
***************
*** 436,442 ****
   *	str_cat_three - join three strings
   *
   * SYNOPSIS
!  *	string_t *str_cat_three(string_t *, string_t *, string_t *);
   *
   * DESCRIPTION
   *	The str_cat_three function is used to concatenate three strings to form
--- 436,442 ----
   *	str_cat_three - join three strings
   *
   * SYNOPSIS
!  *	string_ty *str_cat_three(string_ty *, string_ty *, string_ty *);
   *
   * DESCRIPTION
   *	The str_cat_three function is used to concatenate three strings to form
***************
*** 443,449 ****
   *	a new string.
   *
   * RETURNS
!  *	string_t* - a pointer to a string in dynamic memory.  Use str_free when
   *	finished with.
   *
   * CAVEAT
--- 443,449 ----
   *	a new string.
   *
   * RETURNS
!  *	string_ty* - a pointer to a string in dynamic memory.  Use str_free when
   *	finished with.
   *
   * CAVEAT
***************
*** 450,464 ****
   *	The contents of the structure pointed to MUST NOT be altered.
   */
  
! string_t *
  str_cat_three(s1, s2, s3)
! 	string_t	*s1;
! 	string_t	*s2;
! 	string_t	*s3;
  {
  	static char	*tmp;
  	static size_t	tmplen;
! 	string_t	*s;
  	size_t		length;
  
  	length = s1->str_length + s2->str_length + s3->str_length;
--- 450,464 ----
   *	The contents of the structure pointed to MUST NOT be altered.
   */
  
! string_ty *
  str_cat_three(s1, s2, s3)
! 	string_ty	*s1;
! 	string_ty	*s2;
! 	string_ty	*s3;
  {
  	static char	*tmp;
  	static size_t	tmplen;
! 	string_ty	*s;
  	size_t		length;
  
  	length = s1->str_length + s2->str_length + s3->str_length;
***************
*** 495,501 ****
   *	str_equal - test equality of strings
   *
   * SYNOPSIS
!  *	int str_equal(string_t *, string_t *);
   *
   * DESCRIPTION
   *	The str_equal function is used to test if two strings are equal.
--- 495,501 ----
   *	str_equal - test equality of strings
   *
   * SYNOPSIS
!  *	int str_equal(string_ty *, string_ty *);
   *
   * DESCRIPTION
   *	The str_equal function is used to test if two strings are equal.
***************
*** 512,519 ****
  
  int
  str_equal(s1, s2)
! 	string_t	*s1;
! 	string_t	*s2;
  {
  	return (s1 == s2);
  }
--- 512,519 ----
  
  int
  str_equal(s1, s2)
! 	string_ty	*s1;
! 	string_ty	*s2;
  {
  	return (s1 == s2);
  }
***************
*** 526,532 ****
   *	str_upcase - upcase a string
   *
   * SYNOPSIS
!  *	string_t *str_upcase(string_t *);
   *
   * DESCRIPTION
   *	The str_upcase function is used to form a string which is an upper case
--- 526,532 ----
   *	str_upcase - upcase a string
   *
   * SYNOPSIS
!  *	string_ty *str_upcase(string_ty *);
   *
   * DESCRIPTION
   *	The str_upcase function is used to form a string which is an upper case
***************
*** 533,539 ****
   *	form of the supplied string.
   *
   * RETURNS
!  *	string_t* - a pointer to a string in dynamic memory.  Use str_free when
   *	finished with.
   *
   * CAVEAT
--- 533,539 ----
   *	form of the supplied string.
   *
   * RETURNS
!  *	string_ty* - a pointer to a string in dynamic memory.  Use str_free when
   *	finished with.
   *
   * CAVEAT
***************
*** 540,552 ****
   *	The contents of the structure pointed to MUST NOT be altered.
   */
  
! string_t *
  str_upcase(s)
! 	string_t	*s;
  {
  	static char	*tmp;
  	static size_t	tmplen;
! 	string_t	*retval;
  	char		*cp1;
  	char		*cp2;
  
--- 540,552 ----
   *	The contents of the structure pointed to MUST NOT be altered.
   */
  
! string_ty *
  str_upcase(s)
! 	string_ty	*s;
  {
  	static char	*tmp;
  	static size_t	tmplen;
! 	string_ty	*retval;
  	char		*cp1;
  	char		*cp2;
  
***************
*** 584,590 ****
   *	str_downcase - lowercase string
   *
   * SYNOPSIS
!  *	string_t *str_downcase(string_t *);
   *
   * DESCRIPTION
   *	The str_downcase function is used to form a string which is a lowercase
--- 584,590 ----
   *	str_downcase - lowercase string
   *
   * SYNOPSIS
!  *	string_ty *str_downcase(string_ty *);
   *
   * DESCRIPTION
   *	The str_downcase function is used to form a string which is a lowercase
***************
*** 591,597 ****
   *	form of the supplied string.
   *
   * RETURNS
!  *	string_t* - a pointer to a string in dynamic memory.  Use str_free when
   *	finished with.
   *
   * CAVEAT
--- 591,597 ----
   *	form of the supplied string.
   *
   * RETURNS
!  *	string_ty* - a pointer to a string in dynamic memory.  Use str_free when
   *	finished with.
   *
   * CAVEAT
***************
*** 598,610 ****
   *	The contents of the structure pointed to MUST NOT be altered.
   */
  
! string_t *
  str_downcase(s)
! 	string_t	*s;
  {
  	static char	*tmp;
  	static size_t	tmplen;
! 	string_t	*retval;
  	char		*cp1;
  	char		*cp2;
  
--- 598,610 ----
   *	The contents of the structure pointed to MUST NOT be altered.
   */
  
! string_ty *
  str_downcase(s)
! 	string_ty	*s;
  {
  	static char	*tmp;
  	static size_t	tmplen;
! 	string_ty	*retval;
  	char		*cp1;
  	char		*cp2;
  
***************
*** 642,648 ****
   *	str_bool - get boolean value
   *
   * SYNOPSIS
!  *	int str_bool(string_t *s);
   *
   * DESCRIPTION
   *	The str_bool function is used to determine the boolean value of the
--- 642,648 ----
   *	str_bool - get boolean value
   *
   * SYNOPSIS
!  *	int str_bool(string_ty *s);
   *
   * DESCRIPTION
   *	The str_bool function is used to determine the boolean value of the
***************
*** 656,662 ****
  
  int
  str_bool(s)
! 	string_t	*s;
  {
  	char		*cp;
  
--- 656,662 ----
  
  int
  str_bool(s)
! 	string_ty	*s;
  {
  	char		*cp;
  
***************
*** 676,682 ****
   *	str_field - extract a field from a string
   *
   * SYNOPSIS
!  *	string_t *str_field(string_t *, char separator, int field_number);
   *
   * DESCRIPTION
   *	The str_field functipon is used to erxtract a field from a string.
--- 676,682 ----
   *	str_field - extract a field from a string
   *
   * SYNOPSIS
!  *	string_ty *str_field(string_ty *, char separator, int field_number);
   *
   * DESCRIPTION
   *	The str_field functipon is used to erxtract a field from a string.
***************
*** 688,696 ****
   *	pointer return.  The null string is considered to have one empty field.
   */
  
! string_t *
  str_field(s, sep, fldnum)
! 	string_t	*s;
  	int		sep;
  	int		fldnum;
  {
--- 688,696 ----
   *	pointer return.  The null string is considered to have one empty field.
   */
  
! string_ty *
  str_field(s, sep, fldnum)
! 	string_ty	*s;
  	int		sep;
  	int		fldnum;
  {
***************
*** 716,722 ****
  void
  slow_to_fast(in, out, length)
  	char		**in;
! 	string_t	**out;
  	size_t		length;
  {
  	size_t		j;
--- 716,722 ----
  void
  slow_to_fast(in, out, length)
  	char		**in;
! 	string_ty	**out;
  	size_t		length;
  {
  	size_t		j;
***************
*** 728,740 ****
  }
  
  
! string_t *
  str_format(fmt sva_last)
  	char		*fmt;
  	sva_last_decl
  {
  	va_list		ap;
! 	string_t	*result;
  
  	sva_init(ap, fmt);
  	result = str_vformat(fmt, ap);
--- 728,740 ----
  }
  
  
! string_ty *
  str_format(fmt sva_last)
  	char		*fmt;
  	sva_last_decl
  {
  	va_list		ap;
! 	string_ty	*result;
  
  	sva_init(ap, fmt);
  	result = str_vformat(fmt, ap);
***************
*** 748,761 ****
  
  static void
  build_fake(fake, flag, width, precision, qualifier, specifier)
! 	char	*fake;
! 	int	flag;
! 	int	width;
! 	int	precision;
! 	int	qualifier;
! 	int	specifier;
  {
! 	char	*fp;
  
  	fp = fake;
  	*fp++ = '%';
--- 748,761 ----
  
  static void
  build_fake(fake, flag, width, precision, qualifier, specifier)
! 	char		*fake;
! 	int		flag;
! 	int		width;
! 	int		precision;
! 	int		qualifier;
! 	int		specifier;
  {
! 	char		*fp;
  
  	fp = fake;
  	*fp++ = '%';
***************
*** 776,782 ****
  }
  
  
! string_t *
  str_vformat(fmt, ap)
  	char		*fmt;
  	va_list		ap;
--- 776,782 ----
  }
  
  
! string_ty *
  str_vformat(fmt, ap)
  	char		*fmt;
  	va_list		ap;
***************
*** 1194,1203 ****
  
  		case 'S':
  			{
! 				string_t	*a;
  				size_t		len;
  
! 				a = va_arg(ap, string_t *);
  				len = a->str_length;
  				if (!prec_set)
  					prec = len;
--- 1194,1203 ----
  
  		case 'S':
  			{
! 				string_ty	*a;
  				size_t		len;
  
! 				a = va_arg(ap, string_ty *);
  				len = a->str_length;
  				if (!prec_set)
  					prec = len;
Index: common/str.h
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 27,39 ****
  #include <s-v-arg.h>
  #include <main.h>
  
! typedef unsigned long hash_t;
  
! typedef struct string_t string_t;
! struct string_t
  {
! 	hash_t		str_hash;
! 	string_t	*str_next;
  	long		str_references;
  	size_t		str_length;
  	char		str_text[1];
--- 27,39 ----
  #include <s-v-arg.h>
  #include <main.h>
  
! typedef unsigned long str_hash_ty;
  
! typedef struct string_ty string_ty;
! struct string_ty
  {
! 	str_hash_ty	str_hash;
! 	string_ty	*str_next;
  	long		str_references;
  	size_t		str_length;
  	char		str_text[1];
***************
*** 40,59 ****
  };
  
  void str_initialize _((void));
! string_t *str_from_c _((char *));
! string_t *str_n_from_c _((char *, size_t));
! string_t *str_copy _((string_t *));
! void str_free _((string_t *));
! string_t *str_catenate _((string_t *, string_t *));
! string_t *str_cat_three _((string_t *, string_t *, string_t *));
! int str_bool _((string_t *));
! string_t *str_upcase _((string_t *));
! string_t *str_downcase _((string_t *));
  void str_dump _((void));
! string_t *str_field _((string_t *str, int sep, int fldnum));
! void slow_to_fast _((char **, string_t **, size_t));
! string_t *str_format _((char *, ...));
! string_t *str_vformat _((char *, va_list));
  
  #define str_equal(s1, s2) ((s1) == (s2))
  
--- 40,59 ----
  };
  
  void str_initialize _((void));
! string_ty *str_from_c _((char *));
! string_ty *str_n_from_c _((char *, size_t));
! string_ty *str_copy _((string_ty *));
! void str_free _((string_ty *));
! string_ty *str_catenate _((string_ty *, string_ty *));
! string_ty *str_cat_three _((string_ty *, string_ty *, string_ty *));
! int str_bool _((string_ty *));
! string_ty *str_upcase _((string_ty *));
! string_ty *str_downcase _((string_ty *));
  void str_dump _((void));
! string_ty *str_field _((string_ty *str, int sep, int fldnum));
! void slow_to_fast _((char **, string_ty **, size_t));
! string_ty *str_format _((char *, ...));
! string_ty *str_vformat _((char *, va_list));
  
  #define str_equal(s1, s2) ((s1) == (s2))
  
Index: common/trace.c
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 34,57 ****
  
  #define INDENT 2
  
! typedef struct known_t known_t;
! struct known_t
  {
! 	string_t	*filename;
  	int		flag;
  	int		*flag_p;
! 	known_t		*next;
  };
  
! static	string_t	*file_name;
  static	int		line_number;
  static	int		page_width;
! static	known_t		*known;
  
  
! static string_t *basename _((char *));
  
! static string_t *
  basename(file)
  	char		*file;
  {
--- 34,58 ----
  
  #define INDENT 2
  
! typedef struct known_ty known_ty;
! struct known_ty
  {
! 	string_ty	*filename;
  	int		flag;
  	int		*flag_p;
! 	known_ty	*next;
  };
  
! static	string_ty	*file_name;
  static	int		line_number;
  static	int		page_width;
! static	known_ty	*known;
! static	int		depth;
  
  
! static string_ty *basename _((char *));
  
! static string_ty *
  basename(file)
  	char		*file;
  {
***************
*** 77,84 ****
  	char		*file;
  	int		*result;
  {
! 	string_t	*s;
! 	known_t		*kp;
  
  	s = basename(file);
  	for (kp = known; kp; kp = kp->next)
--- 78,85 ----
  	char		*file;
  	int		*result;
  {
! 	string_ty	*s;
! 	known_ty	*kp;
  
  	s = basename(file);
  	for (kp = known; kp; kp = kp->next)
***************
*** 91,97 ****
  	}
  	if (!kp)
  	{
! 		kp = (known_t *)mem_alloc(sizeof(known_t));
  		kp->filename = s;
  		kp->next = known;
  		kp->flag = 2; /* disabled */
--- 92,98 ----
  	}
  	if (!kp)
  	{
! 		kp = (known_ty *)mem_alloc(sizeof(known_ty));
  		kp->filename = s;
  		kp->next = known;
  		kp->flag = 2; /* disabled */
***************
*** 108,114 ****
  	char		*file;
  	int		line;
  {
! 	string_t	*s;
  
  	/*
  	 * take new name fist, because will probably be same as last
--- 109,115 ----
  	char		*file;
  	int		line;
  {
! 	string_ty	*s;
  
  	/*
  	 * take new name fist, because will probably be same as last
***************
*** 128,134 ****
  trace_putchar(c)
  	int		c;
  {
- 	static int	depth;
  	static char	buffer[MAX_PAGE_WIDTH + 2];
  	static char	*cp;
  	static int	in_col;
--- 129,134 ----
***************
*** 184,190 ****
  	case /*(*/')':
  	case /*[*/']':
  		if (depth > 0)
! 		--depth;
  		/* fall through */
  
  	default:
--- 184,190 ----
  	case /*(*/')':
  	case /*[*/']':
  		if (depth > 0)
! 			--depth;
  		/* fall through */
  
  	default:
***************
*** 242,249 ****
  trace_enable(file)
  	char		*file;
  {
! 	string_t	*s;
! 	known_t		*kp;
  
  	s = basename(file);
  	for (kp = known; kp; kp = kp->next)
--- 242,249 ----
  trace_enable(file)
  	char		*file;
  {
! 	string_ty	*s;
! 	known_ty	*kp;
  
  	s = basename(file);
  	for (kp = known; kp; kp = kp->next)
***************
*** 256,262 ****
  	}
  	if (!kp)
  	{
! 		kp = (known_t *)mem_alloc(sizeof(known_t));
  		kp->filename = s;
  		kp->flag_p = 0;
  		kp->next = known;
--- 256,262 ----
  	}
  	if (!kp)
  	{
! 		kp = (known_ty *)mem_alloc(sizeof(known_ty));
  		kp->filename = s;
  		kp->flag_p = 0;
  		kp->next = known;
***************
*** 401,407 ****
  	char		*name;
  	char		*vp;
  {
! 	char	*s;
  	long		count;
  
  	trace_printf("%s = ", name);
--- 401,407 ----
  	char		*name;
  	char		*vp;
  {
! 	char		*s;
  	long		count;
  
  	trace_printf("%s = ", name);
***************
*** 480,483 ****
--- 480,490 ----
  		}
  	}
  	trace_printf("\";\n");
+ }
+ 
+ 
+ void
+ trace_indent_reset()
+ {
+ 	depth = 0;
  }
Index: common/trace.h
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 64,69 ****
--- 64,70 ----
  void trace_where _((char *file, int line));
  void trace_printf _((char *, ...));
  void trace_enable _((char *));
+ void trace_indent_reset _((void));
  
  
  #if defined(__STDC__) || defined(__stdc__)
Index: common/word.c
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 34,73 ****
  
  
  /*
!  *  NAME
   *	wl_append - append to a word list
   *
!  *  SYNOPSIS
!  *	void wl_append(wlist *wlp, string_t *wp);
   *
!  *  DESCRIPTION
   *	Wl_append is used to append to a word list.
   *
!  *  CAVEAT
   *	The word being appended IS copied.
   */
  
  void
  wl_append(wlp, w)
!     wlist   *wlp;
!     string_t *w;
  {
!     *(string_t **)enlarge(&wlp->wl_nwords, (char **)&wlp->wl_word, sizeof(string_t *)) = str_copy(w);
  }
  
  
  /*
!  *  NAME
   *	wl_free - free a word list
   *
!  *  SYNOPSIS
   *	void wl_free(wlist *wlp);
   *
!  *  DESCRIPTION
   *	Wl_free is used to free the contents of a word list
   *	when it is finished with.
   *
!  *  CAVEAT
   *	It is assumed that the contents of the word list were all
   *	created using strdup() or similar, and grown using wl_append().
   */
--- 34,79 ----
  
  
  /*
!  * NAME
   *	wl_append - append to a word list
   *
!  * SYNOPSIS
!  *	void wl_append(wlist *wlp, string_ty *wp);
   *
!  * DESCRIPTION
   *	Wl_append is used to append to a word list.
   *
!  * CAVEAT
   *	The word being appended IS copied.
   */
  
  void
  wl_append(wlp, w)
! 	wlist		*wlp;
! 	string_ty	*w;
  {
! 	*(string_ty **)
! 	enlarge
! 	(
! 		&wlp->wl_nwords,
! 		(char **)&wlp->wl_word, sizeof(string_ty *)
! 	) =
! 		str_copy(w);
  }
  
  
  /*
!  * NAME
   *	wl_free - free a word list
   *
!  * SYNOPSIS
   *	void wl_free(wlist *wlp);
   *
!  * DESCRIPTION
   *	Wl_free is used to free the contents of a word list
   *	when it is finished with.
   *
!  * CAVEAT
   *	It is assumed that the contents of the word list were all
   *	created using strdup() or similar, and grown using wl_append().
   */
***************
*** 74,104 ****
  
  void
  wl_free(wlp)
!     wlist   *wlp;
  {
!     int	    j;
  
!     for (j = 0; j < wlp->wl_nwords; j++)
! 	str_free(wlp->wl_word[j]);
!     if (wlp->wl_nwords)
! 	free(wlp->wl_word);
!     wlp->wl_nwords = 0;
!     wlp->wl_word = 0;
  }
  
  
  /*
!  *  NAME
   *	wl_member - word list membership
   *
!  *  SYNOPSIS
!  *	int wl_member(wlist *wlp, string_t *wp);
   *
!  *  DESCRIPTION
   *	Wl_member is used to determine if the given word is
   *	contained in the given word list.
   *
!  *  RETURNS
   *	A zero if the word is not in the list,
   *	and a non-zero if it is.
   */
--- 80,110 ----
  
  void
  wl_free(wlp)
! 	wlist		*wlp;
  {
! 	int		j;
  
! 	for (j = 0; j < wlp->wl_nwords; j++)
! 		str_free(wlp->wl_word[j]);
! 	if (wlp->wl_nwords)
! 		free(wlp->wl_word);
! 	wlp->wl_nwords = 0;
! 	wlp->wl_word = 0;
  }
  
  
  /*
!  * NAME
   *	wl_member - word list membership
   *
!  * SYNOPSIS
!  *	int wl_member(wlist *wlp, string_ty *wp);
   *
!  * DESCRIPTION
   *	Wl_member is used to determine if the given word is
   *	contained in the given word list.
   *
!  * RETURNS
   *	A zero if the word is not in the list,
   *	and a non-zero if it is.
   */
***************
*** 105,136 ****
  
  int
  wl_member(wlp, w)
!     wlist   *wlp;
!     string_t *w;
  {
!     int	    j;
  
!     for (j = 0; j < wlp->wl_nwords; j++)
! 	if (str_equal(wlp->wl_word[j], w))
! 	    return 1;
!     return 0;
  }
  
  
  /*
!  *  NAME
   *	wl_copy - copy a word list
   *
!  *  SYNOPSIS
   *	void wl_copy(wlist *to, wlist *from);
   *
!  *  DESCRIPTION
   *	Wl_copy is used to copy word lists.
   *
!  *  RETURNS
   *	A copy of the 'to' word list is placed in 'from'.
   *
!  *  CAVEAT
   *	It is the responsibility of the caller to ensure that the
   *	new word list is freed when finished with, by a call to wl_free().
   */
--- 111,142 ----
  
  int
  wl_member(wlp, w)
! 	wlist		*wlp;
! 	string_ty	*w;
  {
! 	int		j;
  
! 	for (j = 0; j < wlp->wl_nwords; j++)
! 		if (str_equal(wlp->wl_word[j], w))
! 			return 1;
! 	return 0;
  }
  
  
  /*
!  * NAME
   *	wl_copy - copy a word list
   *
!  * SYNOPSIS
   *	void wl_copy(wlist *to, wlist *from);
   *
!  * DESCRIPTION
   *	Wl_copy is used to copy word lists.
   *
!  * RETURNS
   *	A copy of the 'to' word list is placed in 'from'.
   *
!  * CAVEAT
   *	It is the responsibility of the caller to ensure that the
   *	new word list is freed when finished with, by a call to wl_free().
   */
***************
*** 137,245 ****
  
  void
  wl_copy(to, from)
!     wlist   *to;
!     wlist   *from;
  {
!     int	    j;
  
!     wl_zero(to);
!     for (j = 0; j < from->wl_nwords; j++)
! 	wl_append(to, str_copy(from->wl_word[j]));
  }
  
  
  /*
!  *  NAME
   *	wl2str - form a string from a word list
   *
!  *  SYNOPSIS
!  *	string_t *wl2str(wlist *wlp, int start, int stop);
   *
!  *  DESCRIPTION
   *	Wl2str is used to form a string from a word list.
   *
!  *  RETURNS
   *	A pointer to the newly formed string in dynamic memory.
   *
!  *  CAVEAT
   *	It is the responsibility of the caller to ensure that the
   *	new string is freed when finished with, by a call to free().
   */
  
! string_t *
  wl2str(wl, start, stop)
!     wlist   *wl;
!     int	    start;
!     int     stop;
  {
!     int	    j;
!     static char *tmp;
!     static size_t tmplen;
!     size_t  length;
!     char    *pos;
!     string_t *s;
  
!     length = 0;
!     for (j = start; j <= stop && j < wl->wl_nwords; j++)
!     {
! 	s = wl->wl_word[j];
! 	if (s->str_length)
  	{
! 	    if (length)
! 	        ++length;
! 	    length += s->str_length;
  	}
-     }
  
!     if (!tmp)
!     {
! 	tmplen = length;
! 	if (tmplen < 16)
! 	    tmplen = 16;
!         tmp = mem_alloc(tmplen);
!     }
!     else
!     {
! 	if (tmplen < length)
  	{
! 	    tmplen = length;
!             mem_change_size(&tmp, tmplen);
  	}
!     }
  
!     pos = tmp;
!     for (j = start; j <= stop && j < wl->wl_nwords; j++)
!     {
! 	s = wl->wl_word[j];
! 	if (s->str_length)
  	{
! 	    if (pos != tmp)
! 	        *pos++ = ' ';
! 	    memcpy(pos, s->str_text, s->str_length);
! 	    pos += s->str_length;
  	}
-     }
  
!     s = str_n_from_c(tmp, length);
!     return s;
  }
  
  
  /*
!  *  NAME
   *	str2wl - string to word list
   *
!  *  SYNOPSIS
!  *	void str2wl(wlist *wlp, string_t *s);
   *
!  *  DESCRIPTION
   *	Str2wl is used to form a word list from a string.
   *
!  *  RETURNS
   *	The string is broken on spaces into words,
   *	using strndup() and wl_append().
   *
!  *  CAVEAT
   *	Quoting is not understood.
   */
  
--- 143,251 ----
  
  void
  wl_copy(to, from)
! 	wlist		*to;
! 	wlist		*from;
  {
! 	int		j;
  
! 	wl_zero(to);
! 	for (j = 0; j < from->wl_nwords; j++)
! 		wl_append(to, str_copy(from->wl_word[j]));
  }
  
  
  /*
!  * NAME
   *	wl2str - form a string from a word list
   *
!  * SYNOPSIS
!  *	string_ty *wl2str(wlist *wlp, int start, int stop);
   *
!  * DESCRIPTION
   *	Wl2str is used to form a string from a word list.
   *
!  * RETURNS
   *	A pointer to the newly formed string in dynamic memory.
   *
!  * CAVEAT
   *	It is the responsibility of the caller to ensure that the
   *	new string is freed when finished with, by a call to free().
   */
  
! string_ty *
  wl2str(wl, start, stop)
! 	wlist		*wl;
! 	int		start;
! 	int		stop;
  {
! 	int		j;
! 	static char	*tmp;
! 	static size_t	tmplen;
! 	size_t		length;
! 	char		*pos;
! 	string_ty	*s;
  
! 	length = 0;
! 	for (j = start; j <= stop && j < wl->wl_nwords; j++)
  	{
! 		s = wl->wl_word[j];
! 		if (s->str_length)
! 		{
! 			if (length)
! 				++length;
! 			length += s->str_length;
! 		}
  	}
  
! 	if (!tmp)
  	{
! 		tmplen = length;
! 		if (tmplen < 16)
! 			tmplen = 16;
! 		tmp = mem_alloc(tmplen);
  	}
! 	else
! 	{
! 		if (tmplen < length)
! 		{
! 			tmplen = length;
! 			mem_change_size(&tmp, tmplen);
! 		}
! 	}
  
! 	pos = tmp;
! 	for (j = start; j <= stop && j < wl->wl_nwords; j++)
  	{
! 		s = wl->wl_word[j];
! 		if (s->str_length)
! 		{
! 			if (pos != tmp)
! 				*pos++ = ' ';
! 			memcpy(pos, s->str_text, s->str_length);
! 			pos += s->str_length;
! 		}
  	}
  
! 	s = str_n_from_c(tmp, length);
! 	return s;
  }
  
  
  /*
!  * NAME
   *	str2wl - string to word list
   *
!  * SYNOPSIS
!  *	void str2wl(wlist *wlp, string_ty *s);
   *
!  * DESCRIPTION
   *	Str2wl is used to form a word list from a string.
   *
!  * RETURNS
   *	The string is broken on spaces into words,
   *	using strndup() and wl_append().
   *
!  * CAVEAT
   *	Quoting is not understood.
   */
  
***************
*** 246,252 ****
  void
  str2wl(slp, s, sep)
  	wlist		*slp;
! 	string_t	*s;
  	char		*sep;
  {
  	char		*cp;
--- 252,258 ----
  void
  str2wl(slp, s, sep)
  	wlist		*slp;
! 	string_ty	*s;
  	char		*sep;
  {
  	char		*cp;
***************
*** 257,263 ****
  	more = 0;
  	while (*cp || more)
  	{
! 		string_t	*w;
  		char		*cp1;
  		char		*cp2;
  
--- 263,269 ----
  	more = 0;
  	while (*cp || more)
  	{
! 		string_ty	*w;
  		char		*cp1;
  		char		*cp2;
  
***************
*** 299,370 ****
  
  
  /*
!  *  NAME
   *	wl_insert - a insert a word into a list
   *
!  *  SYNOPSIS
!  *	void wl_insert(wlist *wlp, string_t *wp);
   *
!  *  DESCRIPTION
   *	Wl_insert is similar to wl_append, however it does not
   *	append the word unless it is not already in the list.
   *
!  *  CAVEAT
   *	If the word is inserted it is copied.
   */
  
  void
  wl_append_unique(wlp, wp)
!     wlist   *wlp;
!     string_t *wp;
  {
!     int	    j;
  
!     for (j = 0; j < wlp->wl_nwords; j++)
! 	if (str_equal(wlp->wl_word[j], wp))
! 	    return;
!     wl_append(wlp, wp);
  }
  
  
  /*
!  *  NAME
!  *      wl_delete - remove list member
   *
!  *  SYNOPSIS
!  *      void wl_delete(wlist *wlp, string_t *wp);
   *
!  *  DESCRIPTION
!  *      The wl_delete function is used to delete a member of a word list.
   *
!  *  RETURNS
!  *      void
   */
  
  void
  wl_delete(wlp, wp)
!     wlist   *wlp;
!     string_t *wp;
  {
!     int     j;
!     int     k;
  
!     for (j = 0; j < wlp->wl_nwords; ++j)
!     {
! 	if (str_equal(wlp->wl_word[j], wp))
  	{
! 	    wlp->wl_nwords--;
! 	    for (k = j; k < wlp->wl_nwords; ++k)
! 		wlp->wl_word[k] = wlp->wl_word[k + 1];
! 	    str_free(wp);
! 	    break;
  	}
-     }
  }
  
  void
  wl_zero(wlp)
! 	wlist	*wlp;
  {
  	wlp->wl_nwords = 0;
  	wlp->wl_word = 0;
--- 305,376 ----
  
  
  /*
!  * NAME
   *	wl_insert - a insert a word into a list
   *
!  * SYNOPSIS
!  *	void wl_insert(wlist *wlp, string_ty *wp);
   *
!  * DESCRIPTION
   *	Wl_insert is similar to wl_append, however it does not
   *	append the word unless it is not already in the list.
   *
!  * CAVEAT
   *	If the word is inserted it is copied.
   */
  
  void
  wl_append_unique(wlp, wp)
! 	wlist		*wlp;
! 	string_ty	*wp;
  {
! 	int		j;
  
! 	for (j = 0; j < wlp->wl_nwords; j++)
! 		if (str_equal(wlp->wl_word[j], wp))
! 			return;
! 	wl_append(wlp, wp);
  }
  
  
  /*
!  * NAME
!  *	wl_delete - remove list member
   *
!  * SYNOPSIS
!  *	void wl_delete(wlist *wlp, string_ty *wp);
   *
!  * DESCRIPTION
!  *	The wl_delete function is used to delete a member of a word list.
   *
!  * RETURNS
!  *	void
   */
  
  void
  wl_delete(wlp, wp)
! 	wlist		*wlp;
! 	string_ty	*wp;
  {
! 	int		j;
! 	int		k;
  
! 	for (j = 0; j < wlp->wl_nwords; ++j)
  	{
! 		if (str_equal(wlp->wl_word[j], wp))
! 		{
! 			wlp->wl_nwords--;
! 			for (k = j; k < wlp->wl_nwords; ++k)
! 				wlp->wl_word[k] = wlp->wl_word[k + 1];
! 			str_free(wp);
! 			break;
! 		}
  	}
  }
  
  void
  wl_zero(wlp)
! 	wlist		*wlp;
  {
  	wlp->wl_nwords = 0;
  	wlp->wl_word = 0;
Index: common/word.h
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 29,44 ****
  struct wlist
  {
  	size_t		wl_nwords;
! 	string_t	**wl_word;
  };
  
! int wl_member _((wlist *, string_t *));
! string_t *wl2str _((wlist *, int, int));
! void str2wl _((wlist *, string_t *, char *));
! void wl_append _((wlist *, string_t *));
! void wl_append_unique _((wlist *, string_t *));
  void wl_copy _((wlist *, wlist *));
! void wl_delete _((wlist *, string_t *));
  void wl_free _((wlist *));
  void wl_zero _((wlist *));
  
--- 29,44 ----
  struct wlist
  {
  	size_t		wl_nwords;
! 	string_ty	**wl_word;
  };
  
! int wl_member _((wlist *, string_ty *));
! string_ty *wl2str _((wlist *, int, int));
! void str2wl _((wlist *, string_ty *, char *));
! void wl_append _((wlist *, string_ty *));
! void wl_append_unique _((wlist *, string_ty *));
  void wl_copy _((wlist *, wlist *));
! void wl_delete _((wlist *, string_ty *));
  void wl_free _((wlist *));
  void wl_zero _((wlist *));
  
Index: conf/AIX-3.2
***************
*** 0 ****
--- 1,142 ----
+ /*
+  *	aegis - project change supervisor
+  *	Copyright (C) 1992, 1993 Peter Miller.
+  *	All rights reserved.
+  *
+  *	This program is free software; you can redistribute it and/or modify
+  *	it under the terms of the GNU General Public License as published by
+  *	the Free Software Foundation; either version 1, or (at your option)
+  *	any later version.
+  *
+  *	This program is distributed in the hope that it will be useful,
+  *	but WITHOUT ANY WARRANTY; without even the implied warranty of
+  *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  *	GNU General Public License for more details.
+  *
+  *	You should have received a copy of the GNU General Public License
+  *	along with this program; if not, write to the Free Software
+  *	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+  *
+  * MANIFEST: aegis configuration for AIX 3.2 system
+  */
+ 
+ #ifndef CONF_H
+ #define CONF_H
+ 
+ /*
+  * Define this symbol if your system does NOT
+  * have the ANSI C strerror system call, and
+  * does not define strerror in <string.h>.
+  *
+ #define CONF_NO_strerror
+  */
+ 
+ /*
+  * Define this symbol if your system does NOT
+  * have the POSIX tcgetpgrp system call.
+  *
+ #define CONF_NO_tcgetpgrp
+  */
+ 
+ /*
+  * Define this symbol if your system does NOT
+  * have the stdarg.h include file mandated by ANSI C.
+  *
+ #ifndef __STDC__
+ #define CONF_NO_stdarg
+ #endif
+  */
+ 
+ /*
+  * Define one of these symbols to indicate which
+  * universe your UNIX is derived from.
+  * If you have a choice, define both.
+  */
+ #define BSD
+ #define SYSV
+ 
+ /*
+  * Define this symbol as an appropriate arguemnt to
+  * the getpgrp system call for your system.
+  * Ignore if your system does not have a getpgrp system call.
+  */
+ /* #define CONF_getpgrp_arg 0 */
+ #define CONF_getpgrp_arg
+ 
+ /*
+  * Suitable user for storing aegis' global files.
+  * The group will be derived from the relevant entry in /etc/passwd.
+  *
+  * Do not confuse this with the fact that aegis must be set-uid-root.
+  * Aegis MUST be set-uid-root to manipulate file ownersips, etc.
+  *
+  * This string defines the owner of aegis' global files, so that aegis
+  * may access them when they are on NFS mounted partitions (when root
+  * is mapped to "nobody").
+  */
+ #define AEGIS_USER	"bin"
+ 
+ /*
+  * This defines the file creation mask.  See umask(2) for more information.
+  * Some bits are not available, because aegis is _meant_ to be paranoid.
+  * Owner: always has read, write and search/exec.
+  * Group: always has read and search/exec, so that developers can get at the
+  *	baseline.  There is never group write, because then developers
+  *	could trash the baseline, which is counter-productive.
+  * Others: There is never others write, for the same reason as group.
+  *	Others read and search/execute is configurable.
+  *
+  * The permissions mask in binary looks like
+  *	000 010 X1X
+  * where the Xs may be configured.
+  *
+  * Alternatives for default umask are thus
+  *	027	others get nothing
+  *	026	others can execute the results if they know where they are going
+  *	022	others can see and copy and execute anything
+  *	023	don't do this (why is left as an exersize for the reader)
+  *
+  * Projects have a configurable umask, this is just the default.
+  *	See aepattr(1) for more information.
+  */
+ #define DEFAULT_UMASK 026
+ 
+ /*
+  * Define this symbol if your system does NOT have the strftime
+  * function mandated by the ANSI C standard.
+  *
+ #define CONF_NO_strftime
+  */
+ 
+ /*
+  * Define this symbol if your system does NOT
+  * have the pw_comment field in struct passwd in <pwd.h>
+  */
+ #define CONF_NO_pw_comment
+ 
+ /*
+  * Define this symbol if your system does NOT
+  * have the seteuid system call.
+  *
+  * In this case, one is present, but with crippled semantics.
+  */
+ #define CONF_NO_seteuid
+ 
+ /*
+  * Define this symbol to be the pathname of your shell.
+  * Leave it as a Bourne shell whenever possible.
+  * Some systems have different versions of the Bourne shell,
+  * with and without functions; choose the one *with* functions if so.
+  */
+ #define CONF_SHELL "/bin/sh"
+ 
+ /*
+  * These symbols define where non-system user IDs start,
+  * and where non-system group IDs start.
+  * This is mostly to ensure that accounts "root" and "bin"
+  * and "uucp" are not project owners.
+  */
+ #define AEGIS_MIN_UID 100
+ #define AEGIS_MIN_GID 10
+ 
+ #endif /* CONF_H */
Index: conf/ConvexOS-10
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 73,79 ****
   * may access them when they are on NFS mounted partitions (when root
   * is mapped to "nobody").
   */
! #define AEGIS_USER	"bin"
  
  /*
   * This defines the file creation mask.  See umask(2) for more information.
--- 73,79 ----
   * may access them when they are on NFS mounted partitions (when root
   * is mapped to "nobody").
   */
! #define AEGIS_USER	"daemon"
  
  /*
   * This defines the file creation mask.  See umask(2) for more information.
***************
*** 99,103 ****
--- 99,141 ----
   *	See aepattr(1) for more information.
   */
  #define DEFAULT_UMASK 026
+ 
+ /*
+  * Define this symbol if your system does NOT have the strftime
+  * function mandated by the ANSI C standard.
+  *
+ #define CONF_NO_strftime
+  */
+ 
+ /*
+  * Define this symbol if your system does NOT
+  * have the pw_comment field in struct passwd in <pwd.h>
+  *
+ #define CONF_NO_pw_comment
+  */
+ 
+ /*
+  * Define this symbol if your system does NOT
+  * have the seteuid system call.
+  *
+ #define CONF_NO_seteuid
+  */
+ 
+ /*
+  * Define this symbol to be the pathname of your shell.
+  * Leave it as a Bourne shell whenever possible.
+  * Some systems have different versions of the Bourne shell,
+  * with and without functions; choose the one *with* functions if so.
+  */
+ #define CONF_SHELL "/bin/sh"
+ 
+ /*
+  * These symbols define where non-system user IDs start,
+  * and where non-system group IDs start.
+  * This is mostly to ensure that accounts "root" and "bin"
+  * and "uucp" are not project owners.
+  */
+ #define AEGIS_MIN_UID 100
+ #define AEGIS_MIN_GID 10
  
  #endif /* CONF_H */
Index: conf/SCO-2.4
***************
*** 0 ****
--- 1,141 ----
+ /*
+  *	aegis - project change supervisor
+  *	Copyright (C) 1993 Peter Miller.
+  *	All rights reserved.
+  *
+  *	This program is free software; you can redistribute it and/or modify
+  *	it under the terms of the GNU General Public License as published by
+  *	the Free Software Foundation; either version 2 of the License, or
+  *	(at your option) any later version.
+  *
+  *	This program is distributed in the hope that it will be useful,
+  *	but WITHOUT ANY WARRANTY; without even the implied warranty of
+  *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  *	GNU General Public License for more details.
+  *
+  *	You should have received a copy of the GNU General Public License
+  *	along with this program; if not, write to the Free Software
+  *	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+  *
+  * MANIFEST: aegis configuration for SCO 2.4
+  */
+ 
+ #ifndef CONF_H
+ #define CONF_H
+ 
+ /*
+  * Define this symbol if your system does NOT
+  * have the ANSI C strerror system call, and
+  * does not define strerror in <string.h>.
+  *
+ #define CONF_NO_strerror
+  */
+ 
+ /*
+  * Define this symbol if your system does NOT
+  * have the POSIX tcgetpgrp system call.
+  *
+ #define CONF_NO_tcgetpgrp
+  */
+ 
+ /*
+  * Define this symbol if your system does NOT
+  * have the stdarg.h include file mandated by ANSI C.
+  */
+ #ifndef __STDC__
+ #define CONF_NO_stdarg
+ #endif
+ 
+ /*
+  * Define one of these symbols to indicate which
+  * universe your UNIX is derived from.
+  * If you have a choice, define both.
+  */
+ /* #define BSD */
+ #define SYSV
+ 
+ /*
+  * Define this symbol as an appropriate arguemnt to
+  * the getpgrp system call for your system.
+  * Ignore if your system does not have a getpgrp system call.
+  */
+ /* #define CONF_getpgrp_arg 0 */
+ #define CONF_getpgrp_arg
+ 
+ /*
+  * Suitable user for storing aegis' global files.
+  * The group will be derived from the relevant entry in /etc/passwd.
+  *
+  * Do not confuse this with the fact that aegis must be set-uid-root.
+  * Aegis MUST be set-uid-root to manipulate file ownersips, etc.
+  *
+  * This string defines the owner of aegis' global files, so that aegis
+  * may access them when they are on NFS mounted partitions (when root
+  * is mapped to "nobody").
+  */
+ #define AEGIS_USER	"bin"
+ 
+ /*
+  * This defines the file creation mask.  See umask(2) for more information.
+  * Some bits are not available, because aegis is _meant_ to be paranoid.
+  * Owner: always has read, write and search/exec.
+  * Group: always has read and search/exec, so that developers can get at the
+  *	baseline.  There is never group write, because then developers
+  *	could trash the baseline, which is counter-productive.
+  * Others: There is never others write, for the same reason as group.
+  *	Others read and search/execute is configurable.
+  *
+  * The permissions mask in binary looks like
+  *	000 010 X1X
+  * where the Xs may be configured.
+  *
+  * Alternatives for default umask are thus
+  *	027	others get nothing
+  *	026	others can execute the results if they know where they are going
+  *	022	others can see and copy and execute anything
+  *	023	don't do this (why is left as an exersize for the reader)
+  *
+  * Projects have a configurable umask, this is just the default.
+  *	See aepattr(1) for more information.
+  */
+ #define DEFAULT_UMASK 026
+ 
+ /*
+  * Define this symbol if your system does NOT have the strftime
+  * function mandated by the ANSI C standard.
+  *
+ #define CONF_NO_strftime
+  */
+ 
+ /*
+  * Define this symbol if your system does NOT
+  * have the pw_comment field in struct passwd in <pwd.h>
+  *
+ #define CONF_NO_pw_comment
+  */
+ 
+ /*
+  * Define this symbol if your system does NOT
+  * have the seteuid system call.
+  *
+ #define CONF_NO_seteuid
+  */
+ 
+ /*
+  * Define this symbol to be the pathname of your shell.
+  * Leave it as a Bourne shell whenever possible.
+  * Some systems have different versions of the Bourne shell,
+  * with and without functions; choose the one *with* functions if so.
+  */
+ #define CONF_SHELL "/bin/sh"
+ 
+ /*
+  * These symbols define where non-system user IDs start,
+  * and where non-system group IDs start.
+  * This is mostly to ensure that accounts "root" and "bin"
+  * and "uucp" are not project owners.
+  */
+ #define AEGIS_MIN_UID 100
+ #define AEGIS_MIN_GID 10
+ 
+ #endif /* CONF_H */
Index: conf/SunOS-4.1.1
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 98,102 ****
--- 98,140 ----
   *	See aepattr(1) for more information.
   */
  #define DEFAULT_UMASK 026
+ 
+ /*
+  * Define this symbol if your system does NOT have the strftime
+  * function mandated by the ANSI C standard.
+  *
+ #define CONF_NO_strftime
+  */
+ 
+ /*
+  * Define this symbol if your system does NOT
+  * have the pw_comment field in struct passwd in <pwd.h>
+  *
+ #define CONF_NO_pw_comment
+  */
+ 
+ /*
+  * Define this symbol if your system does NOT
+  * have the seteuid system call.
+  *
+ #define CONF_NO_seteuid
+  */
+ 
+ /*
+  * Define this symbol to be the pathname of your shell.
+  * Leave it as a Bourne shell whenever possible.
+  * Some systems have different versions of the Bourne shell,
+  * with and without functions; choose the one *with* functions if so.
+  */
+ #define CONF_SHELL "/bin/sh"
+ 
+ /*
+  * These symbols define where non-system user IDs start,
+  * and where non-system group IDs start.
+  * This is mostly to ensure that accounts "root" and "bin"
+  * and "uucp" are not project owners.
+  */
+ #define AEGIS_MIN_UID 100
+ #define AEGIS_MIN_GID 10
  
  #endif /* CONF_H */
Index: conf/SunOS-4.1.2
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 98,102 ****
--- 98,140 ----
   *	See aepattr(1) for more information.
   */
  #define DEFAULT_UMASK 026
+ 
+ /*
+  * Define this symbol if your system does NOT have the strftime
+  * function mandated by the ANSI C standard.
+  *
+ #define CONF_NO_strftime
+  */
+ 
+ /*
+  * Define this symbol if your system does NOT
+  * have the pw_comment field in struct passwd in <pwd.h>
+  *
+ #define CONF_NO_pw_comment
+  */
+ 
+ /*
+  * Define this symbol if your system does NOT
+  * have the seteuid system call.
+  *
+ #define CONF_NO_seteuid
+  */
+ 
+ /*
+  * Define this symbol to be the pathname of your shell.
+  * Leave it as a Bourne shell whenever possible.
+  * Some systems have different versions of the Bourne shell,
+  * with and without functions; choose the one *with* functions if so.
+  */
+ #define CONF_SHELL "/bin/sh"
+ 
+ /*
+  * These symbols define where non-system user IDs start,
+  * and where non-system group IDs start.
+  * This is mostly to ensure that accounts "root" and "bin"
+  * and "uucp" are not project owners.
+  */
+ #define AEGIS_MIN_UID 100
+ #define AEGIS_MIN_GID 10
  
  #endif /* CONF_H */
Index: conf/SunOS-4.1.3
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 98,102 ****
--- 98,140 ----
   *	See aepattr(1) for more information.
   */
  #define DEFAULT_UMASK 026
+ 
+ /*
+  * Define this symbol if your system does NOT have the strftime
+  * function mandated by the ANSI C standard.
+  *
+ #define CONF_NO_strftime
+  */
+ 
+ /*
+  * Define this symbol if your system does NOT
+  * have the pw_comment field in struct passwd in <pwd.h>
+  *
+ #define CONF_NO_pw_comment
+  */
+ 
+ /*
+  * Define this symbol if your system does NOT
+  * have the seteuid system call.
+  *
+ #define CONF_NO_seteuid
+  */
+ 
+ /*
+  * Define this symbol to be the pathname of your shell.
+  * Leave it as a Bourne shell whenever possible.
+  * Some systems have different versions of the Bourne shell,
+  * with and without functions; choose the one *with* functions if so.
+  */
+ #define CONF_SHELL "/bin/sh"
+ 
+ /*
+  * These symbols define where non-system user IDs start,
+  * and where non-system group IDs start.
+  * This is mostly to ensure that accounts "root" and "bin"
+  * and "uucp" are not project owners.
+  */
+ #define AEGIS_MIN_UID 100
+ #define AEGIS_MIN_GID 10
  
  #endif /* CONF_H */
Index: conf/SysV-4.0
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 97,101 ****
--- 97,139 ----
   *	See aepattr(1) for more information.
   */
  #define DEFAULT_UMASK 026
+ 
+ /*
+  * Define this symbol if your system does NOT have the strftime
+  * function mandated by the ANSI C standard.
+  *
+ #define CONF_NO_strftime
+  */
+ 
+ /*
+  * Define this symbol if your system does NOT
+  * have the pw_comment field in struct passwd in <pwd.h>
+  *
+ #define CONF_NO_pw_comment
+  */
+ 
+ /*
+  * Define this symbol if your system does NOT
+  * have the seteuid system call.
+  *
+ #define CONF_NO_seteuid
+  */
+ 
+ /*
+  * Define this symbol to be the pathname of your shell.
+  * Leave it as a Bourne shell whenever possible.
+  * Some systems have different versions of the Bourne shell,
+  * with and without functions; choose the one *with* functions if so.
+  */
+ #define CONF_SHELL "/bin/sh"
+ 
+ /*
+  * These symbols define where non-system user IDs start,
+  * and where non-system group IDs start.
+  * This is mostly to ensure that accounts "root" and "bin"
+  * and "uucp" are not project owners.
+  */
+ #define AEGIS_MIN_UID 100
+ #define AEGIS_MIN_GID 10
  
  #endif /* CONF_H */
Index: conf/ULTRIX-4.2
***************
*** 0 ****
--- 1,139 ----
+ /*
+  *	aegis - project change supervisor
+  *	Copyright (C) 1993 Peter Miller.
+  *	All rights reserved.
+  *
+  *	This program is free software; you can redistribute it and/or modify
+  *	it under the terms of the GNU General Public License as published by
+  *	the Free Software Foundation; either version 2 of the License, or
+  *	(at your option) any later version.
+  *
+  *	This program is distributed in the hope that it will be useful,
+  *	but WITHOUT ANY WARRANTY; without even the implied warranty of
+  *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  *	GNU General Public License for more details.
+  *
+  *	You should have received a copy of the GNU General Public License
+  *	along with this program; if not, write to the Free Software
+  *	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+  *
+  * MANIFEST: aegis configuration for ULTRIX version 4.2
+  */
+ 
+ #ifndef CONF_H
+ #define CONF_H
+ 
+ /*
+  * Define this symbol if your system does NOT
+  * have the ANSI C strerror system call, and
+  * does not define strerror in <string.h>.
+  *
+ #define CONF_NO_strerror
+  */
+ 
+ /*
+  * Define this symbol if your system does NOT
+  * have the POSIX tcgetpgrp system call.
+  *
+ #define CONF_NO_tcgetpgrp
+  */
+ 
+ /*
+  * Define this symbol if your system does NOT
+  * have the stdarg.h include file mandated by ANSI C.
+  */
+ #define CONF_NO_stdarg
+ 
+ /*
+  * Define one of these symbols to indicate which
+  * universe your UNIX is derived from.
+  * If you have a choice, define both.
+  */
+ /* #define BSD */
+ #define SYSV
+ 
+ /*
+  * Define this symbol as an appropriate arguemnt to
+  * the getpgrp system call for your system.
+  * Ignore if your system does not have a getpgrp system call.
+  */
+ /* #define CONF_getpgrp_arg 0 */
+ #define CONF_getpgrp_arg
+ 
+ /*
+  * Suitable user for storing aegis' global files.
+  * The group will be derived from the relevant entry in /etc/passwd.
+  *
+  * Do not confuse this with the fact that aegis must be set-uid-root.
+  * Aegis MUST be set-uid-root to manipulate file ownersips, etc.
+  *
+  * This string defines the owner of aegis' global files, so that aegis
+  * may access them when they are on NFS mounted partitions (when root
+  * is mapped to "nobody").
+  */
+ #define AEGIS_USER	"bin"
+ 
+ /*
+  * This defines the file creation mask.  See umask(2) for more information.
+  * Some bits are not available, because aegis is _meant_ to be paranoid.
+  * Owner: always has read, write and search/exec.
+  * Group: always has read and search/exec, so that developers can get at the
+  *	baseline.  There is never group write, because then developers
+  *	could trash the baseline, which is counter-productive.
+  * Others: There is never others write, for the same reason as group.
+  *	Others read and search/execute is configurable.
+  *
+  * The permissions mask in binary looks like
+  *	000 010 X1X
+  * where the Xs may be configured.
+  *
+  * Alternatives for default umask are thus
+  *	027	others get nothing
+  *	026	others can execute the results if they know where they are going
+  *	022	others can see and copy and execute anything
+  *	023	don't do this (why is left as an exersize for the reader)
+  *
+  * Projects have a configurable umask, this is just the default.
+  *	See aepattr(1) for more information.
+  */
+ #define DEFAULT_UMASK 026
+ 
+ /*
+  * Define this symbol if your system does NOT have the strftime
+  * function mandated by the ANSI C standard.
+  *
+ #define CONF_NO_strftime
+  */
+ 
+ /*
+  * Define this symbol if your system does NOT
+  * have the pw_comment field in struct passwd in <pwd.h>
+  *
+ #define CONF_NO_pw_comment
+  */
+ 
+ /*
+  * Define this symbol if your system does NOT
+  * have the seteuid system call.
+  *
+ #define CONF_NO_seteuid
+  */
+ 
+ /*
+  * Define this symbol to be the pathname of your shell.
+  * Leave it as a Bourne shell whenever possible.
+  * Some systems have different versions of the Bourne shell,
+  * with and without functions; choose the one *with* functions if so.
+  */
+ #define CONF_SHELL "/bin/sh5"
+ 
+ /*
+  * These symbols define where non-system user IDs start,
+  * and where non-system group IDs start.
+  * This is mostly to ensure that accounts "root" and "bin"
+  * and "uucp" are not project owners.
+  */
+ #define AEGIS_MIN_UID 100
+ #define AEGIS_MIN_GID 10
+ 
+ #endif /* CONF_H */
Index: conf/apollo
***************
*** 0 ****
--- 1,139 ----
+ /*
+  *	aegis - project change supervisor
+  *	Copyright (C) 1993 Peter Miller.
+  *	All rights reserved.
+  *
+  *	This program is free software; you can redistribute it and/or modify
+  *	it under the terms of the GNU General Public License as published by
+  *	the Free Software Foundation; either version 2 of the License, or
+  *	(at your option) any later version.
+  *
+  *	This program is distributed in the hope that it will be useful,
+  *	but WITHOUT ANY WARRANTY; without even the implied warranty of
+  *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  *	GNU General Public License for more details.
+  *
+  *	You should have received a copy of the GNU General Public License
+  *	along with this program; if not, write to the Free Software
+  *	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+  *
+  * MANIFEST: aegis configuration for apollo domain
+  *
+  * Aegis is not known to work on apollos, but then
+  * aegis isn't know not to work on apollos, either...
+  */
+ 
+ #ifndef CONF_H
+ #define CONF_H
+ 
+ /*
+  * Define this symbol if your system does NOT
+  * have the ANSI C strerror system call, and
+  * does not define strerror in <string.h>.
+  */
+ #define CONF_NO_strerror
+ 
+ /*
+  * Define this symbol if your system does NOT
+  * have the POSIX tcgetpgrp system call.
+  */
+ #define CONF_NO_tcgetpgrp
+ 
+ /*
+  * Define this symbol if your system does NOT
+  * have the stdarg.h include file mandated by ANSI C.
+  */
+ #define CONF_NO_stdarg
+ 
+ /*
+  * Define one of these symbols to indicate which
+  * universe your UNIX is derived from.
+  * If you have a choice, define both.
+  */
+ /* #define BSD */
+ #define SYSV
+ 
+ /*
+  * Define this symbol as an appropriate arguemnt to
+  * the getpgrp system call for your system.
+  * Ignore if your system does not have a getpgrp system call.
+  */
+ /* #define CONF_getpgrp_arg 0 */
+ #define CONF_getpgrp_arg
+ 
+ /*
+  * Suitable user for storing aegis' global files.
+  * The group will be derived from the relevant entry in /etc/passwd.
+  *
+  * Do not confuse this with the fact that aegis must be set-uid-root.
+  * Aegis MUST be set-uid-root to manipulate file ownersips, etc.
+  *
+  * This string defines the owner of aegis' global files, so that aegis
+  * may access them when they are on NFS mounted partitions (when root
+  * is mapped to "nobody").
+  */
+ #define AEGIS_USER	"bin"
+ 
+ /*
+  * This defines the file creation mask.  See umask(2) for more information.
+  * Some bits are not available, because aegis is _meant_ to be paranoid.
+  * Owner: always has read, write and search/exec.
+  * Group: always has read and search/exec, so that developers can get at the
+  *	baseline.  There is never group write, because then developers
+  *	could trash the baseline, which is counter-productive.
+  * Others: There is never others write, for the same reason as group.
+  *	Others read and search/execute is configurable.
+  *
+  * The permissions mask in binary looks like
+  *	000 010 X1X
+  * where the Xs may be configured.
+  *
+  * Alternatives for default umask are thus
+  *	027	others get nothing
+  *	026	others can execute the results if they know where they are going
+  *	022	others can see and copy and execute anything
+  *	023	don't do this (why is left as an exersize for the reader)
+  *
+  * Projects have a configurable umask, this is just the default.
+  *	See aepattr(1) for more information.
+  */
+ #define DEFAULT_UMASK 026
+ 
+ /*
+  * Define this symbol if your system does NOT have the strftime
+  * function mandated by the ANSI C standard.
+  */
+ #define CONF_NO_strftime
+ 
+ /*
+  * Define this symbol if your system does NOT
+  * have the pw_comment field in struct passwd in <pwd.h>
+  *
+ #define CONF_NO_pw_comment
+  */
+ 
+ /*
+  * Define this symbol if your system does NOT
+  * have the seteuid system call.
+  *
+ #define CONF_NO_seteuid
+  */
+ 
+ /*
+  * Define this symbol to be the pathname of your shell.
+  * Leave it as a Bourne shell whenever possible.
+  * Some systems have different versions of the Bourne shell,
+  * with and without functions; choose the one *with* functions if so.
+  */
+ #define CONF_SHELL "/bin/ksh"
+ 
+ /*
+  * These symbols define where non-system user IDs start,
+  * and where non-system group IDs start.
+  * This is mostly to ensure that accounts "root" and "bin"
+  * and "uucp" are not project owners.
+  */
+ #define AEGIS_MIN_UID 100
+ #define AEGIS_MIN_GID 10
+ 
+ #endif /* CONF_H */
Index: conf/dcosx
***************
*** 0 ****
--- 1,148 ----
+ /*
+  *	aegis - project change supervisor
+  *	Copyright (C) 1993 Peter Miller.
+  *	All rights reserved.
+  *
+  *	This program is free software; you can redistribute it and/or modify
+  *	it under the terms of the GNU General Public License as published by
+  *	the Free Software Foundation; either version 2 of the License, or
+  *	(at your option) any later version.
+  *
+  *	This program is distributed in the hope that it will be useful,
+  *	but WITHOUT ANY WARRANTY; without even the implied warranty of
+  *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  *	GNU General Public License for more details.
+  *
+  *	You should have received a copy of the GNU General Public License
+  *	along with this program; if not, write to the Free Software
+  *	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+  *
+  * MANIFEST: aegis configuration for Pyramid SMP DC/OSx
+  */
+ 
+ #ifndef CONF_H
+ #define CONF_H
+ 
+ /*
+  * Define this symbol if your system does NOT
+  * have the ANSI C strerror system call, and
+  * does not define strerror in <string.h>.
+  */
+ #define CONF_NO_strerror
+ 
+ /*
+  * Define this symbol if your system does NOT
+  * have the POSIX tcgetpgrp system call.
+  *
+ #define CONF_NO_tcgetpgrp
+  */
+ 
+ /*
+  * Define this symbol if your system does NOT
+  * have the stdarg.h include file mandated by ANSI C.
+  */
+ #ifndef __STDC__
+ #define CONF_NO_stdarg
+ #endif
+ 
+ /*
+  * Define one of these symbols to indicate which
+  * universe your UNIX is derived from.
+  * If you have a choice, define both.
+  */
+ /* #define BSD */
+ #define SYSV
+ 
+ /*
+  * Define this symbol as an appropriate arguemnt to
+  * the getpgrp system call for your system.
+  * Ignore if your system does not have a getpgrp system call.
+  */
+ /* #define CONF_getpgrp_arg 0 */
+ #define CONF_getpgrp_arg
+ 
+ /*
+  * Suitable user for storing aegis' global files.
+  * The group will be derived from the relevant entry in /etc/passwd.
+  *
+  * Do not confuse this with the fact that aegis must be set-uid-root.
+  * Aegis MUST be set-uid-root to manipulate file ownersips, etc.
+  *
+  * This string defines the owner of aegis' global files, so that aegis
+  * may access them when they are on NFS mounted partitions (when root
+  * is mapped to "nobody").
+  */
+ #define AEGIS_USER	"bin"
+ 
+ /*
+  * This defines the file creation mask.  See umask(2) for more information.
+  * Some bits are not available, because aegis is _meant_ to be paranoid.
+  * Owner: always has read, write and search/exec.
+  * Group: always has read and search/exec, so that developers can get at the
+  *	baseline.  There is never group write, because then developers
+  *	could trash the baseline, which is counter-productive.
+  * Others: There is never others write, for the same reason as group.
+  *	Others read and search/execute is configurable.
+  *
+  * The permissions mask in binary looks like
+  *	000 010 X1X
+  * where the Xs may be configured.
+  *
+  * Alternatives for default umask are thus
+  *	027	others get nothing
+  *	026	others can execute the results if they know where they are going
+  *	022	others can see and copy and execute anything
+  *	023	don't do this (why is left as an exersize for the reader)
+  *
+  * Projects have a configurable umask, this is just the default.
+  *	See aepattr(1) for more information.
+  */
+ #define DEFAULT_UMASK 026
+ 
+ /*
+  * Define this symbol if your system does NOT have the strftime
+  * function mandated by the ANSI C standard.
+  *
+ #define CONF_NO_strftime
+  */
+ 
+ /*
+  * Define this symbol if your system does NOT
+  * have the pw_comment field in struct passwd in <pwd.h>
+  *
+ #define CONF_NO_pw_comment
+  */
+ 
+ /*
+  * Define this symbol if your system does NOT
+  * have the seteuid system call.
+  *
+ #define CONF_NO_seteuid
+  */
+ 
+ /*
+  * Define this symbol to be the pathname of your shell.
+  * Leave it as a Bourne shell whenever possible.
+  * Some systems have different versions of the Bourne shell,
+  * with and without functions; choose the one *with* functions if so.
+  */
+ #define CONF_SHELL "/bin/sh"
+ 
+ /*
+  * These symbols define where non-system user IDs start,
+  * and where non-system group IDs start.
+  * This is mostly to ensure that accounts "root" and "bin"
+  * and "uucp" are not project owners.
+  */
+ #define AEGIS_MIN_UID 100
+ #define AEGIS_MIN_GID 10
+ 
+ /*
+  * On the pyramid the author used to test aegis,
+  * the readdir function returned a structure that 
+  * had the name starting in the wrong place.
+  * Maybe a version later than 1.0-92b023 has fixed it.
+  */
+ #define CONF_pyramid_broken_readdir
+ 
+ #endif /* CONF_H */
Index: conf/dgux-5.4.1
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 99,103 ****
--- 99,141 ----
   *	See aepattr(1) for more information.
   */
  #define DEFAULT_UMASK 026
+ 
+ /*
+  * Define this symbol if your system does NOT have the strftime
+  * function mandated by the ANSI C standard.
+  *
+ #define CONF_NO_strftime
+  */
+ 
+ /*
+  * Define this symbol if your system does NOT
+  * have the pw_comment field in struct passwd in <pwd.h>
+  *
+ #define CONF_NO_pw_comment
+  */
+ 
+ /*
+  * Define this symbol if your system does NOT
+  * have the seteuid system call.
+  *
+ #define CONF_NO_seteuid
+  */
+ 
+ /*
+  * Define this symbol to be the pathname of your shell.
+  * Leave it as a Bourne shell whenever possible.
+  * Some systems have different versions of the Bourne shell,
+  * with and without functions; choose the one *with* functions if so.
+  */
+ #define CONF_SHELL "/bin/sh"
+ 
+ /*
+  * These symbols define where non-system user IDs start,
+  * and where non-system group IDs start.
+  * This is mostly to ensure that accounts "root" and "bin"
+  * and "uucp" are not project owners.
+  */
+ #define AEGIS_MIN_UID 100
+ #define AEGIS_MIN_GID 10
  
  #endif /* CONF_H */
Index: conf/hpux-8.07
***************
*** 0 ****
--- 1,146 ----
+ /*
+  *	aegis - project change supervisor
+  *	Copyright (C) 1992, 1993 Peter Miller.
+  *	All rights reserved.
+  *
+  *	This program is free software; you can redistribute it and/or modify
+  *	it under the terms of the GNU General Public License as published by
+  *	the Free Software Foundation; either version 2 of the License, or
+  *	(at your option) any later version.
+  *
+  *	This program is distributed in the hope that it will be useful,
+  *	but WITHOUT ANY WARRANTY; without even the implied warranty of
+  *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  *	GNU General Public License for more details.
+  *
+  *	You should have received a copy of the GNU General Public License
+  *	along with this program; if not, write to the Free Software
+  *	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+  *
+  * MANIFEST: aegis configuration for generic SVR4 system
+  */
+ 
+ #ifndef CONF_H
+ #define CONF_H
+ 
+ #define HPUX
+ /*
+  * Define this symbol if your system does NOT
+  * have the ANSI C strerror system call, and
+  * does not define strerror in <string.h>.
+  */
+ #define CONF_NO_strerror
+ 
+ /*
+  * Define this symbol if your system does NOT
+  * have the POSIX tcgetpgrp system call.
+  */
+ /*#define CONF_NO_tcgetpgrp*/
+ 
+ /*
+  * Define this symbol if your system does NOT
+  * have the stdarg.h include file mandated by ANSI C.
+  */
+ #ifndef __STDC__
+ #define CONF_NO_stdarg
+ #endif
+ 
+ /*
+  * Define one of these symbols to indicate which
+  * universe your UNIX is derived from.
+  * If you have a choice, define both.
+  */
+ /* #define BSD */
+ #define SYSV
+ 
+ /*
+  * Define this symbol as an appropriate arguemnt to
+  * the getpgrp system call for your system.
+  * Ignore if your system does not have a getpgrp system call.
+  */
+ #define CONF_getpgrp_arg 0
+ 
+ /*
+  * Suitable user for storing aegis' global files.
+  * The group will be derived from the relevant entry in /etc/passwd.
+  *
+  * Do not confuse this with the fact that aegis must be set-uid-root.
+  * Aegis MUST be set-uid-root to manipulate file ownersips, etc.
+  *
+  * This string defines the owner of aegis' global files, so that aegis
+  * may access them when they are on NFS mounted partitions (when root
+  * is mapped to "nobody").
+  */
+ #define AEGIS_USER	"bin"
+ 
+ /*
+  * This defines the file creation mask.  See umask(2) for more information.
+  * Some bits are not available, because aegis is _meant_ to be paranoid.
+  * Owner: always has read, write and search/exec.
+  * Group: always has read and search/exec, so that developers can get at the
+  *	baseline.  There is never group write, because then developers
+  *	could trash the baseline, which is counter-productive.
+  * Others: There is never others write, for the same reason as group.
+  *	Others read and search/execute is configurable.
+  *
+  * The permissions mask in binary looks like
+  *	000 010 X1X
+  * where the Xs may be configured.
+  *
+  * Alternatives for default umask are thus
+  *	027	others get nothing
+  *	026	others can execute the results if they know where they are going
+  *	022	others can see and copy and execute anything
+  *	023	don't do this (why is left as an exersize for the reader)
+  *
+  * Projects have a configurable umask, this is just the default.
+  *	See aepattr(1) for more information.
+  */
+ #define DEFAULT_UMASK 026
+ 
+ /*
+  * Define this symbol if your system does NOT have the strftime
+  * function mandated by the ANSI C standard.
+  *
+ #define CONF_NO_strftime
+  */
+ 
+ /*
+  * Define this symbol if your system does NOT
+  * have the pw_comment field in struct passwd in <pwd.h>
+  *
+ #define CONF_NO_pw_comment
+  */
+ 
+ /*
+  * Define this symbol if your system does NOT
+  * have the seteuid system call.
+  *
+ #define CONF_NO_seteuid
+  */
+ 
+ /*
+  * Define this symbol to be the pathname of your shell.
+  * Leave it as a Bourne shell whenever possible.
+  * Some systems have different versions of the Bourne shell,
+  * with and without functions; choose the one *with* functions if so.
+  */
+ #define CONF_SHELL "/bin/sh"
+ 
+ /*
+  * These symbols define where non-system user IDs start,
+  * and where non-system group IDs start.
+  * This is mostly to ensure that accounts "root" and "bin"
+  * and "uucp" are not project owners.
+  */
+ #define AEGIS_MIN_UID 100
+ #define AEGIS_MIN_GID 10
+ 
+ /*
+  * Define this symbol if your systems has setresuid,
+  * but does NOT have seteuid.  Similarly for setresgid.
+  * Hopefully, this us unique to HP-UX.
+  */
+ #define CONF_HAS_setresuid
+ 
+ #endif /* CONF_H */
Index: config
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 23,35 ****
  /*
   * how to build the project
   * mandatory
-  *
-  * %1 = project name
-  * %3 = change number
-  * %3 = identifying string, in the form "Dnnn"
-  *	where 'nnn' is the build number.
   */
! build_command = "cook -b %(aux/Howto.cook) project=%1 change=%2 version=%3 -nl";
  
  /*
   * When do -Integrate_Begin, link the baseline to the integration directory,
--- 23,32 ----
  /*
   * how to build the project
   * mandatory
   */
! build_command =
! 	"cook -b ${source aux/Howto.cook} project=$project \
! change=$change version=$version -nl";
  
  /*
   * When do -Integrate_Begin, link the baseline to the integration directory,
***************
*** 42,94 ****
  
  /*
   * create a new history
-  *	%1 = source file
-  *	%2 = history file
   * always executed as the project owner
   */
! history_create_command = "sc %F2 -create -i %1 -p %P2 -r";
  
  /*
   * get a file from history
-  *	%1 = history file
-  *	%2 = edit number
-  *	%3 = destination file
   * may be executed by developers
   */
! history_get_command = "sc %F1 -e '%2' -o %3 -p %P1 -v 0";
  
  /*
   * add a new change to the history
-  *	%1 = source file
-  *	%2 = history file
   * always executed as the project owner
   */
! history_put_command = "sc %F2 -u -i %1 -p %P2 -r";
  
  /*
   * query the topmost edit of a history file
-  *	%1 = history file
   * Result to be printed on stdout.
   * may be executed by developers
   */
! history_query_command = "sc %F1 -l 0 -p %P1 -q";
  
  /*
   * difference of 2 files
-  *	%1 = earlier file
-  *	%2 = later file	
-  *	%3 = output file
   */
! diff_command = "fcomp -w %1 %2 -o %3";
  
  /*
   * difference of 3 files
-  *	%1 = earliest file
-  *	%2 = one competing edit
-  *	%3 = another competing edit
-  *	%4 = output file
   */
! diff3_command = "fmerge %1 %2 %3 -o %4";
  
  /*
   * whenever files are added to or removed from the change,
--- 39,81 ----
  
  /*
   * create a new history
   * always executed as the project owner
   */
! history_create_command =
! 	"fhist ${basename $history} -create -i $input -p ${dirname $history} -r";
  
  /*
   * get a file from history
   * may be executed by developers
   */
! history_get_command =
! 	"fhist ${basename $history} -e '$edit' -o $output \
! -p ${dirname $history} -v 0";
  
  /*
   * add a new change to the history
   * always executed as the project owner
   */
! history_put_command =
! 	"fhist ${basename $history} -u -i $input -p ${dirname $history} -r";
  
  /*
   * query the topmost edit of a history file
   * Result to be printed on stdout.
   * may be executed by developers
   */
! history_query_command =
! 	"fhist ${basename $history} -l 0 -p ${dirname $history} -q";
  
  /*
   * difference of 2 files
   */
! diff_command = "fcomp -w -s $original $input -o $output";
  
  /*
   * difference of 3 files
   */
! diff3_command = "fmerge $original $mostrecent $input -o $output -c $input,C";
  
  /*
   * whenever files are added to or removed from the change,
***************
*** 106,118 ****
  		body ="\
  /*\n\
   *	aegis - project change supervisor\n\
!  *	Copyright (c) 1993 Peter Miller.\n\
   *	All rights reserved.\n\
   *\n\
   *	This program is free software; you can redistribute it and/or modify\n\
   *	it under the terms of the GNU General Public License as published by\n\
!  *	the Free Software Foundation; either version 1, or (at your option)\n\
!  *	any later version.\n\
   *\n\
   *	This program is distributed in the hope that it will be useful,\n\
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of\n\
--- 93,105 ----
  		body ="\
  /*\n\
   *	aegis - project change supervisor\n\
!  *	Copyright (C) ${date %Y} Peter Miller.\n\
   *	All rights reserved.\n\
   *\n\
   *	This program is free software; you can redistribute it and/or modify\n\
   *	it under the terms of the GNU General Public License as published by\n\
!  *	the Free Software Foundation; either version 2 of the License, or\n\
!  *	(at your option) any later version.\n\
   *\n\
   *	This program is distributed in the hope that it will be useful,\n\
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of\n\
***************
*** 123,129 ****
   *	along with this program; if not, write to the Free Software\n\
   *	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\n\
   *\n\
!  * MANIFEST: functions to ...\n\
   */\n";
  	},
  	{
--- 110,116 ----
   *	along with this program; if not, write to the Free Software\n\
   *	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\n\
   *\n\
!  * MANIFEST: functions to manipulate ${basename $fn .c}s\n\
   */\n";
  	},
  	{
***************
*** 131,143 ****
  		body = "\
  /*\n\
   *	aegis - project change supervisor\n\
!  *	Copyright (c) 1993 Peter Miller.\n\
   *	All rights reserved.\n\
   *\n\
   *	This program is free software; you can redistribute it and/or modify\n\
   *	it under the terms of the GNU General Public License as published by\n\
!  *	the Free Software Foundation; either version 1, or (at your option)\n\
!  *	any later version.\n\
   *\n\
   *	This program is distributed in the hope that it will be useful,\n\
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of\n\
--- 118,130 ----
  		body = "\
  /*\n\
   *	aegis - project change supervisor\n\
!  *	Copyright (C) ${date %Y} Peter Miller.\n\
   *	All rights reserved.\n\
   *\n\
   *	This program is free software; you can redistribute it and/or modify\n\
   *	it under the terms of the GNU General Public License as published by\n\
!  *	the Free Software Foundation; either version 2 of the License, or\n\
!  *	(at your option) any later version.\n\
   *\n\
   *	This program is distributed in the hope that it will be useful,\n\
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of\n\
***************
*** 148,162 ****
   *	along with this program; if not, write to the Free Software\n\
   *	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\n\
   *\n\
!  * MANIFEST: interface definition for file_name.c\n\
   */\n\
  \n\
! #ifndef file.name_H\n\
! #define file.name_H\n\
  \n\
  #include <main.h>\n\
  \n\
! #endif /* file.name_H */\n";
  	},
  	{
  		pattern = [ "test/*/*.sh" ];
--- 135,149 ----
   *	along with this program; if not, write to the Free Software\n\
   *	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\n\
   *\n\
!  * MANIFEST: interface definition for ${basename $fn .h}.c\n\
   */\n\
  \n\
! #ifndef ${upcase ${id $fn}}\n\
! #define ${upcase ${id $fn}}\n\
  \n\
  #include <main.h>\n\
  \n\
! #endif /* ${upcase ${id $fn}} */\n";
  	},
  	{
  		pattern = [ "test/*/*.sh" ];
***************
*** 164,176 ****
  #! /bin/sh\n\
  #\n\
  #	aegis - project change supervisor\n\
! #	Copyright (c) 1993 Peter Miller.\n\
  #	All rights reserved.\n\
  #\n\
  #	This program is free software; you can redistribute it and/or modify\n\
  #	it under the terms of the GNU General Public License as published by\n\
! #	the Free Software Foundation; either version 1, or (at your option)\n\
! #	any later version.\n\
  #\n\
  #	This program is distributed in the hope that it will be useful,\n\
  #	but WITHOUT ANY WARRANTY; without even the implied warranty of\n\
--- 151,163 ----
  #! /bin/sh\n\
  #\n\
  #	aegis - project change supervisor\n\
! #	Copyright (C) ${date %Y} Peter Miller.\n\
  #	All rights reserved.\n\
  #\n\
  #	This program is free software; you can redistribute it and/or modify\n\
  #	it under the terms of the GNU General Public License as published by\n\
! #	the Free Software Foundation; either version 2 of the License, or\n\
! #	(at your option) any later version.\n\
  #\n\
  #	This program is distributed in the hope that it will be useful,\n\
  #	but WITHOUT ANY WARRANTY; without even the implied warranty of\n\
***************
*** 181,201 ****
  #	along with this program; if not, write to the Free Software\n\
  #	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\n\
  #\n\
- # ----------------------------------------------------------------------\n\
- #\n\
  # MANIFEST: Test the ??? functionality\n\
  #\n\
  \n\
! work=/tmp/$$\n\
  PAGER=cat\n\
  export PAGER\n\
  \n\
  fail()\n\
  {\n\
  	set +x\n\
! 	echo FAILED 1>&2\n\
! 	find $work -type d -user $USER -exec chmod u+w {} \\;\n\
! 	rm -rf $work\n\
  	exit 1\n\
  }\n\
  pass()\n\
--- 168,195 ----
  #	along with this program; if not, write to the Free Software\n\
  #	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\n\
  #\n\
  # MANIFEST: Test the ??? functionality\n\
  #\n\
  \n\
! unset AEGIS_PROJECT\n\
! unset AEGIS_CHANGE\n\
! \n\
! work=$${AEGIS_TMP-/tmp}/$$$$\n\
  PAGER=cat\n\
  export PAGER\n\
  \n\
+ here=`pwd`\n\
+ if test $$? -ne 0 ; then exit 1; fi\n\
+ mkdir $$work\n\
+ if test $$? -ne 0 ; then exit 1; fi\n\
+ \n\
  fail()\n\
  {\n\
  	set +x\n\
! 	echo FAILED test of ... 1>&2\n\
! 	cd $$here\n\
! 	find $$work -type d -user $$USER -exec chmod u+w {} \\;\n\
! 	rm -rf $$work\n\
  	exit 1\n\
  }\n\
  pass()\n\
***************
*** 202,225 ****
  {\n\
  	set +x\n\
  	echo PASSED 1>&2\n\
! 	find $work -type d -user $USER -exec chmod u+w {} \\;\n\
! 	rm -rf $work\n\
  	exit 0\n\
  }\n\
  trap \"fail\" 1 2 3 15\n\
  \n\
! here=`pwd`\n\
! if test $? -ne 0 ; then exit 1; fi\n\
! mkdir $work\n\
! if test $? -ne 0 ; then exit 1; fi\n\
! cd $work\n\
! if test $? -ne 0 ; then fail; fi\n\
  \n\
  #\n\
  # put your test here\n\
  #\n\
! $here/myprog\n\
! if test $? -ne 0 ; then fail; fi\n\
  \n\
  #\n\
  # Only definite negatives are possible.\n\
--- 196,216 ----
  {\n\
  	set +x\n\
  	echo PASSED 1>&2\n\
! 	cd $$here\n\
! 	find $$work -type d -user $$USER -exec chmod u+w {} \\;\n\
! 	rm -rf $$work\n\
  	exit 0\n\
  }\n\
  trap \"fail\" 1 2 3 15\n\
  \n\
! cd $$work\n\
! if test $$? -ne 0 ; then fail; fi\n\
  \n\
  #\n\
  # put your test here\n\
  #\n\
! $$here/myprog\n\
! if test $$? -ne 0 ; then fail; fi\n\
  \n\
  #\n\
  # Only definite negatives are possible.\n\
***************
*** 234,246 ****
  #! /bin/sh\n\
  #\n\
  #	aegis - project change supervisor\n\
! #	Copyright (c) 1993 Peter Miller.\n\
  #	All rights reserved.\n\
  #\n\
  #	This program is free software; you can redistribute it and/or modify\n\
  #	it under the terms of the GNU General Public License as published by\n\
! #	the Free Software Foundation; either version 1, or (at your option)\n\
! #	any later version.\n\
  #\n\
  #	This program is distributed in the hope that it will be useful,\n\
  #	but WITHOUT ANY WARRANTY; without even the implied warranty of\n\
--- 225,237 ----
  #! /bin/sh\n\
  #\n\
  #	aegis - project change supervisor\n\
! #	Copyright (C) ${date %Y} Peter Miller.\n\
  #	All rights reserved.\n\
  #\n\
  #	This program is free software; you can redistribute it and/or modify\n\
  #	it under the terms of the GNU General Public License as published by\n\
! #	the Free Software Foundation; either version 2 of the License, or\n\
! #	(at your option) any later version.\n\
  #\n\
  #	This program is distributed in the hope that it will be useful,\n\
  #	but WITHOUT ANY WARRANTY; without even the implied warranty of\n\
***************
*** 251,257 ****
  #	along with this program; if not, write to the Free Software\n\
  #	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\n\
  #\n\
! # MANIFEST: shell script to ...\n\
  #\n\
  \n\
  exit 0\n";
--- 242,248 ----
  #	along with this program; if not, write to the Free Software\n\
  #	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\n\
  #\n\
! # MANIFEST: shell script to manipulate ${basename $fn .sh}s\n\
  #\n\
  \n\
  exit 0\n";
***************
*** 261,273 ****
  		body = "\
  '\\\" t\n\
  .\\\"	aegis - project change supervisor\n\
! .\\\"	Copyright (c) 1993 Peter Miller.\n\
  .\\\"	All rights reserved.\n\
  .\\\"\n\
  .\\\"	This program is free software; you can redistribute it and/or modify\n\
  .\\\"	it under the terms of the GNU General Public License as published by\n\
! .\\\"	the Free Software Foundation; either version 1, or (at your option)\n\
! .\\\"	any later version.\n\
  .\\\"\n\
  .\\\"	This program is distributed in the hope that it will be useful,\n\
  .\\\"	but WITHOUT ANY WARRANTY; without even the implied warranty of\n\
--- 252,264 ----
  		body = "\
  '\\\" t\n\
  .\\\"	aegis - project change supervisor\n\
! .\\\"	Copyright (C) ${date %Y} Peter Miller.\n\
  .\\\"	All rights reserved.\n\
  .\\\"\n\
  .\\\"	This program is free software; you can redistribute it and/or modify\n\
  .\\\"	it under the terms of the GNU General Public License as published by\n\
! .\\\"	the Free Software Foundation; either version 2 of the License, or\n\
! .\\\"	(at your option) any later version.\n\
  .\\\"\n\
  .\\\"	This program is distributed in the hope that it will be useful,\n\
  .\\\"	but WITHOUT ANY WARRANTY; without even the implied warranty of\n\
***************
*** 278,284 ****
  .\\\"	along with this program; if not, write to the Free Software\n\
  .\\\"	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\n\
  .\\\"\n\
! .\\\" MANIFEST: manual page describing ...\n\
  .\\\"\n\
  .TH aegis 1\n\
  .if n .ad l\n\
--- 269,275 ----
  .\\\"	along with this program; if not, write to the Free Software\n\
  .\\\"	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\n\
  .\\\"\n\
! .\\\" MANIFEST: manual page describing the ${basename $fn .1} command.\n\
  .\\\"\n\
  .TH aegis 1\n\
  .if n .ad l\n\
***************
*** 335,347 ****
  		body = "\
  .\\\"\n\
  .\\\"	aegis - project change supervisor\n\
! .\\\"	Copyright (c) 1993 Peter Miller.\n\
  .\\\"	All rights reserved.\n\
  .\\\"\n\
  .\\\"	This program is free software; you can redistribute it and/or modify\n\
  .\\\"	it under the terms of the GNU General Public License as published by\n\
! .\\\"	the Free Software Foundation; either version 1, or (at your option)\n\
! .\\\"	any later version.\n\
  .\\\"\n\
  .\\\"	This program is distributed in the hope that it will be useful,\n\
  .\\\"	but WITHOUT ANY WARRANTY; without even the implied warranty of\n\
--- 326,338 ----
  		body = "\
  .\\\"\n\
  .\\\"	aegis - project change supervisor\n\
! .\\\"	Copyright (C) ${date %Y} Peter Miller.\n\
  .\\\"	All rights reserved.\n\
  .\\\"\n\
  .\\\"	This program is free software; you can redistribute it and/or modify\n\
  .\\\"	it under the terms of the GNU General Public License as published by\n\
! .\\\"	the Free Software Foundation; either version 2 of the License, or\n\
! .\\\"	(at your option) any later version.\n\
  .\\\"\n\
  .\\\"	This program is distributed in the hope that it will be useful,\n\
  .\\\"	but WITHOUT ANY WARRANTY; without even the implied warranty of\n\
***************
*** 352,358 ****
  .\\\"	along with this program; if not, write to the Free Software\n\
  .\\\"	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\n\
  .\\\"\n\
! .\\\" MANIFEST: document describing ...\n\
  .\\\"\n";
  	},
  	{
--- 343,349 ----
  .\\\"	along with this program; if not, write to the Free Software\n\
  .\\\"	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\n\
  .\\\"\n\
! .\\\" MANIFEST: document describing ${basename $fn .ms}\n\
  .\\\"\n";
  	},
  	{
***************
*** 360,372 ****
  		body = "\
  #\n\
  #	aegis - project change supervisor\n\
! #	Copyright (c) 1993 Peter Miller.\n\
  #	All rights reserved.\n\
  #\n\
  #	This program is free software; you can redistribute it and/or modify\n\
  #	it under the terms of the GNU General Public License as published by\n\
! #	the Free Software Foundation; either version 1, or (at your option)\n\
! #	any later version.\n\
  #\n\
  #	This program is distributed in the hope that it will be useful,\n\
  #	but WITHOUT ANY WARRANTY; without even the implied warranty of\n\
--- 351,363 ----
  		body = "\
  #\n\
  #	aegis - project change supervisor\n\
! #	Copyright (C) ${date %Y} Peter Miller.\n\
  #	All rights reserved.\n\
  #\n\
  #	This program is free software; you can redistribute it and/or modify\n\
  #	it under the terms of the GNU General Public License as published by\n\
! #	the Free Software Foundation; either version 2 of the License, or\n\
! #	(at your option) any later version.\n\
  #\n\
  #	This program is distributed in the hope that it will be useful,\n\
  #	but WITHOUT ANY WARRANTY; without even the implied warranty of\n\
***************
*** 377,383 ****
  #	along with this program; if not, write to the Free Software\n\
  #	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\n\
  #\n\
! # MANIFEST: none\n\
  #\n";
  	}
  ];
--- 368,374 ----
  #	along with this program; if not, write to the Free Software\n\
  #	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\n\
  #\n\
! # MANIFEST: ${basename $fn}\n\
  #\n";
  	}
  ];
Index: doc/aegis.ms
***************
*** 1,11 ****
  .\"	aegis - project change supervisor
! .\"	Copyright (c) 1991-1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 1, or (at your option)
! .\"	any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
+ .\"
  .\"	aegis - project change supervisor
! .\"	Copyright (C) 1991, 1992, 1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 2 of the License, or
! .\"	(at your option) any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 33,39 ****
  \\$2
  .if !\\n(NS-2 \{\
  .XS \\n%
! \h'\\n(NSi/2u'\\*(SN \\$2
  .XE
  .\}
  ..
--- 34,40 ----
  \\$2
  .if !\\n(NS-2 \{\
  .XS \\n%
! \h'\\n(NSi/2u-0.5i'\\*(SN \\$2
  .XE
  .\}
  ..
***************
*** 56,63 ****
--- 57,66 ----
  .so c2.0.so
  .so c3.0.so
  .so c4.0.so
+ .so c8.0.so
  .so c5.0.so
  .so c6.0.so
  .so cA.0.so
  .so cB.0.so
+ .so cC.0.so
  .TC
Index: doc/c1.0.so
***************
*** 1,12 ****
  .\"
  .\"	aegis - project change supervisor
! .\"	Copyright (c) 1991-1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 1, or (at your option)
! .\"	any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  .\"
  .\"	aegis - project change supervisor
! .\"	Copyright (C) 1991, 1992, 1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 2 of the License, or
! .\"	(at your option) any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 49,55 ****
  .ce 4
  This user guide is dedicated to my wife
  Mary Therese Miller
! for all here love and support
  despite the computers.
  .sp
  .ce 4
--- 49,55 ----
  .ce 4
  This user guide is dedicated to my wife
  Mary Therese Miller
! for all her love and support
  despite the computers.
  .sp
  .ce 4
***************
*** 57,70 ****
  Jean Florence Pelham
  1905 \(em 1992
  Always in our hearts.
! .sp 2i
! .if n .ds c) (c)
! .if t .ds c) \(co
  This document describing the aegis program,
  and the aegis program itself,
  are
  .br
! Copyright \*(c) 1991-1993 Peter Miller.
  All rights reserved.
  .sp
  This program is free software; you can redistribute it and/or modify
--- 57,76 ----
  Jean Florence Pelham
  1905 \(em 1992
  Always in our hearts.
! .sp 1i
! This document describes aegis version
! .so version.so
! .br
! and was prepared \*(DY.
! .br
! .sp 1i
! .if n .ds C) (C)
! .if t .ds C) \(co
  This document describing the aegis program,
  and the aegis program itself,
  are
  .br
! Copyright \*(C) 1990, 1991, 1992, 1993 Peter Miller.
  All rights reserved.
  .sp
  This program is free software; you can redistribute it and/or modify
Index: doc/c1.1.so
***************
*** 1,12 ****
  .\"
  .\"	aegis - project change supervisor
! .\"	Copyright (c) 1991-1992 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 1, or (at your option)
! .\"	any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  .\"
  .\"	aegis - project change supervisor
! .\"	Copyright (C) 1991, 1992, 1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 2 of the License, or
! .\"	(at your option) any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
Index: doc/c1.2.so
***************
*** 1,12 ****
  .\"
  .\"	aegis - project change supervisor
! .\"	Copyright (c) 1991-1992 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 1, or (at your option)
! .\"	any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  .\"
  .\"	aegis - project change supervisor
! .\"	Copyright (C) 1991, 1992, 1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 2 of the License, or
! .\"	(at your option) any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
Index: doc/c1.3.so
***************
*** 1,12 ****
  .\"
  .\"	aegis - project change supervisor
! .\"	Copyright (c) 1991-1992 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 1, or (at your option)
! .\"	any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  .\"
  .\"	aegis - project change supervisor
! .\"	Copyright (C) 1991, 1992, 1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 2 of the License, or
! .\"	(at your option) any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
Index: doc/c1.4.so
***************
*** 1,12 ****
  .\"
  .\"	aegis - project change supervisor
! .\"	Copyright (c) 1991-1992 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 1, or (at your option)
! .\"	any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  .\"
  .\"	aegis - project change supervisor
! .\"	Copyright (C) 1991, 1992, 1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 2 of the License, or
! .\"	(at your option) any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 61,69 ****
  with the Dependency Maintenance Tool (DMT),
  and provides templates and suggestions for DMTs known to work with aegis.
  .IP "Chapter 6"
! describes the project configuration file
! and how the various parameters may be used for particular projects.
  .IP "Chapter 7"
  is a collection of helpful hints on how to use aegis effectively,
  based on real-world experience.
  This is of most use when initially placing projects under the supervision
--- 61,74 ----
  with the Dependency Maintenance Tool (DMT),
  and provides templates and suggestions for DMTs known to work with aegis.
  .IP "Chapter 6"
! is a discussion of how aegis interacts
! with the Difference Tools,
! and provides templates and suggestions for difference tools
! known to work with aegis.
  .IP "Chapter 7"
+ describes the project attributes
+ and how the various parameters may be used for particular projects.
+ .IP "Chapter 8"
  is a collection of helpful hints on how to use aegis effectively,
  based on real-world experience.
  This is of most use when initially placing projects under the supervision
Index: doc/c2.0.so
***************
*** 1,12 ****
  .\"
  .\"	aegis - project change supervisor
! .\"	Copyright (c) 1991-1992 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 1, or (at your option)
! .\"	any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  .\"
  .\"	aegis - project change supervisor
! .\"	Copyright (C) 1991, 1992, 1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 2 of the License, or
! .\"	(at your option) any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 61,63 ****
--- 61,64 ----
  .so c2.2.so
  .so c2.3.so
  .so c2.4.so
+ .so c2.5.so
Index: doc/c2.1.so
***************
*** 1,12 ****
  .\"
  .\"	aegis - project change supervisor
! .\"	Copyright (c) 1991-1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 1, or (at your option)
! .\"	any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  .\"
  .\"	aegis - project change supervisor
! .\"	Copyright (C) 1991, 1992, 1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 2 of the License, or
! .\"	(at your option) any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 39,57 ****
  later in this chapter.
  Pat then acquires the change and starts work.
  .E(
! pat% \fBaedb -l -p example\fP
  Project "example"
  List of Changes
! 
  Change  State           Description
  ------- -------         -------------
     1    awaiting_       Create initial skeleton.
          development
! pat% \fBaedb example 1\fP
  aegis: project "example": change 1: development directory "/u/pat/
          example.001"
  aegis: project "example": change 1: user "pat" has begun development
! pat% \fBaecd\fP
  aegis: project "example": change 1: /u/pat/example.001
  pat%
  .E)
--- 39,58 ----
  later in this chapter.
  Pat then acquires the change and starts work.
  .E(
! pat% \f(CBaedb -l -p example\fP
  Project "example"
  List of Changes
! .E)
! .E(
  Change  State           Description
  ------- -------         -------------
     1    awaiting_       Create initial skeleton.
          development
! pat% \f(CBaedb example 1\fP
  aegis: project "example": change 1: development directory "/u/pat/
          example.001"
  aegis: project "example": change 1: user "pat" has begun development
! pat% \f(CBaecd\fP
  aegis: project "example": change 1: /u/pat/example.001
  pat%
  .E)
***************
*** 65,71 ****
  .LP
  Five files will be created by this change.
  .E(
! pat% \fBaenf conf Howto.cook gram.y lex.l main.c\fP
  aegis: project "example": change 1: file "Howto.cook" added
  aegis: project "example": change 1: file "config" added
  aegis: project "example": change 1: file "gram.y" added
--- 66,72 ----
  .LP
  Five files will be created by this change.
  .E(
! pat% \f(CBaenf config Howto.cook gram.y lex.l main.c\fP
  aegis: project "example": change 1: file "Howto.cook" added
  aegis: project "example": change 1: file "config" added
  aegis: project "example": change 1: file "gram.y" added
***************
*** 95,101 ****
  Pat edits it to look like this
  .E(
  #include <stdio.h>
! 
  static void
  usage()
  {
--- 96,103 ----
  Pat edits it to look like this
  .E(
  #include <stdio.h>
! .E)
! .E(
  static void
  usage()
  {
***************
*** 102,108 ****
          fprintf(stderr, "usage: example\en");
          exit(1);
  }
! 
  void
  main(argc, argv)
          int     argc;
--- 104,111 ----
          fprintf(stderr, "usage: example\en");
          exit(1);
  }
! .E)
! .E(
  void
  main(argc, argv)
          int     argc;
***************
*** 122,136 ****
  and Pat edits it to look like this:
  .E(
  %token  DOUBLE
! 
  %union
  {
          int     lv_int;
          double  lv_double;
  }
! 
  %type <lv_double> DOUBLE expr
! 
  %prec '+' '-'
  %prec '*' '/'
  %prec UNARY
--- 125,144 ----
  and Pat edits it to look like this:
  .E(
  %token  DOUBLE
! %token  NAME
! .E)
! .E(
  %union
  {
          int     lv_int;
          double  lv_double;
  }
! .E)
! .E(
  %type <lv_double> DOUBLE expr
! %type <lv_int> NAME
! .E)
! .E(
  %prec '+' '-'
  %prec '*' '/'
  %prec UNARY
***************
*** 137,143 ****
  .E)
  .E(
  %%
! 
  example
          : /* empty */
          | example command
--- 145,152 ----
  .E)
  .E(
  %%
! .E)
! .E(
  example
          : /* empty */
          | example command
***************
*** 181,193 ****
                  yylval.lv_double = atof(yytext);
                  return DOUBLE;
          }
! \&.     return yytext[0];
  .E)
  .LP
  Note how the
  .I gram.h
  file is included using the
! \fC#include <\fIfilename\fC>\fR
  form.
  This is very important for builds in later changes,
  and is discussed more fully in the
--- 190,206 ----
                  yylval.lv_double = atof(yytext);
                  return DOUBLE;
          }
! [a-z]   {
!                 yylval.lv_int = yytext[0] - 'a';
!                 return NAME;
!         }
! \&.       return yytext[0];
  .E)
  .LP
  Note how the
  .I gram.h
  file is included using the
! \fC#include <\f(CIfilename\fC>\fR
  form.
  This is very important for builds in later changes,
  and is discussed more fully in the
***************
*** 217,223 ****
  This file describes the commands and dependencies for the various
  processing, compiling and linking.
  .E(
! pat% \fBaeb\fP
  aegis: project "example": change 1: development build started
  aegis: cook -b Howto.cook project=example change=1
          version=1.0.C001 -nl
--- 230,236 ----
  This file describes the commands and dependencies for the various
  processing, compiling and linking.
  .E(
! pat% \f(CBaeb\fP
  aegis: project "example": change 1: development build started
  aegis: cook -b Howto.cook project=example change=1
          version=1.0.C001 -nl
***************
*** 236,245 ****
  .LP
  The example program is built, and Pat could even try it out:
  .E(
! pat% \fBexample\fP
! \fB1 + 2\fP
  3
! \fB^D\fP
  pat%
  .E)
  .LP
--- 249,258 ----
  .LP
  The example program is built, and Pat could even try it out:
  .E(
! pat% \f(CBexample\fP
! \f(CB1 + 2\fP
  3
! \f(CB^D\fP
  pat%
  .E)
  .LP
***************
*** 248,254 ****
  .I "develop end"
  command:
  .E(
! pat% \fBaede\fP
  aegis: project "example": change 1: no current 'aegis -DIFFerence'
          registration
  pat%
--- 261,267 ----
  .I "develop end"
  command:
  .E(
! pat% \f(CBaede\fP
  aegis: project "example": change 1: no current 'aegis -DIFFerence'
          registration
  pat%
***************
*** 263,269 ****
  and not have to try to track them down and inevitably miss obscure
  but important edits to large or complex files.
  .E(
! pat% \fBaed\fP
  aegis: set +e; diff -c /dev/null /u/pat/example.001/Howto.cook >
          /u/pat/example.001/Howto.cook,D; test $? -eq 0 -o $? -eq 1
  aegis: set +e; diff -c /dev/null /u/pat/example.001/config >
--- 276,282 ----
  and not have to try to track them down and inevitably miss obscure
  but important edits to large or complex files.
  .E(
! pat% \f(CBaed\fP
  aegis: set +e; diff -c /dev/null /u/pat/example.001/Howto.cook >
          /u/pat/example.001/Howto.cook,D; test $? -eq 0 -o $? -eq 1
  aegis: set +e; diff -c /dev/null /u/pat/example.001/config >
***************
*** 297,303 ****
  the command
  .E(
  pat% \f(CBmore `find . -name "*,D" -print | sort`\fP
! \fI...examines each file...\fP
  pat%
  .E)
  could be used,
--- 310,316 ----
  the command
  .E(
  pat% \f(CBmore `find . -name "*,D" -print | sort`\fP
! \fI\&.\&.\&.examines each file.\&.\&.\fP
  pat%
  .E)
  could be used,
***************
*** 313,319 ****
  .LP
  So now Pat is done, let's try to sign off again:
  .E(
! pat% \fBaede\fP
  aegis: project "example": change 1: no current 'aegis -Test'
          registration
  pat%
--- 326,332 ----
  .LP
  So now Pat is done, let's try to sign off again:
  .E(
! pat% \f(CBaede\fP
  aegis: project "example": change 1: no current 'aegis -Test'
          registration
  pat%
***************
*** 339,345 ****
  before it can ever be reviewed.
  Pat adds the truant test:
  .E(
! pat% \fBaent\fP
  aegis: project "example": change 1: file "test/00/t0001a.sh" new
          test
  pat%
--- 352,358 ----
  before it can ever be reviewed.
  Pat adds the truant test:
  .E(
! pat% \f(CBaent\fP
  aegis: project "example": change 1: file "test/00/t0001a.sh" new
          test
  pat%
***************
*** 386,392 ****
  .E)
  .E(
  #
! # with input like this...
  #
  cat > test.in << 'foobar'
  1
--- 399,405 ----
  .E)
  .E(
  #
! # with input like this
  #
  cat > test.in << 'foobar'
  1
***************
*** 401,407 ****
  .E)
  .E(
  #
! # ...the output should look like this
  #
  cat > test.ok << 'foobar'
  1
--- 414,420 ----
  .E)
  .E(
  #
! # the output should look like this
  #
  cat > test.ok << 'foobar'
  1
***************
*** 423,429 ****
  if [ $? -ne 0 ]; then fail; fi
  diff test.ok test.out
  if [ $? -ne 0 ]; then fail; fi
! 
  #
  # this much worked
  #
--- 436,443 ----
  if [ $? -ne 0 ]; then fail; fi
  diff test.ok test.out
  if [ $? -ne 0 ]; then fail; fi
! .E)
! .E(
  #
  # this much worked
  #
***************
*** 491,497 ****
  .LP
  The difference with using this test script and doing it manually
  is that most development contains many iterations of
! the "build, test, \fIthink\fP, edit, build, test..." cycle.
  After a couple of iterations,
  the manual testing,
  the constant re-typing,
--- 505,511 ----
  .LP
  The difference with using this test script and doing it manually
  is that most development contains many iterations of
! the "build, test, \fIthink\fP, edit, build, test.\&.\&." cycle.
  After a couple of iterations,
  the manual testing,
  the constant re-typing,
***************
*** 506,515 ****
  .FE
  such as
  .E(
! pat% \fBaeb && aet ; vi aegis.log\fP
! \&...
! pat% \fB!!\fP
! \&...
  pat%
  .E)
  .LP
--- 520,529 ----
  .FE
  such as
  .E(
! pat% \f(CBaeb && aet ; vi aegis.log\fP
! \&.\&.\&.
! pat% \f(CB!!\fP
! \&.\&.\&.
  pat%
  .E)
  .LP
***************
*** 520,526 ****
  As you have already guessed,
  Pat now runs the test like this:
  .E(
! pat% \fBaet\fP
  aegis: sh /u/pat/example.001/test/00/t0001a.sh
  aegis: project "example": change 1: test "test/00/t0001a.sh"
          passed
--- 534,540 ----
  As you have already guessed,
  Pat now runs the test like this:
  .E(
! pat% \f(CBaet\fP
  aegis: sh /u/pat/example.001/test/00/t0001a.sh
  aegis: project "example": change 1: test "test/00/t0001a.sh"
          passed
***************
*** 534,540 ****
  and tested it.
  It is now ready for sign off.
  .E(
! pat% \fBaede\fP
  aegis: project "example": change1: no current 'aegis -Build'
          registration
  pat%
--- 548,554 ----
  and tested it.
  It is now ready for sign off.
  .E(
! pat% \f(CBaede\fP
  aegis: project "example": change1: no current 'aegis -Build'
          registration
  pat%
***************
*** 561,583 ****
  re-difference (yes, the test gets differenced, too)
  and sign off.
  .E(
! pat% \fBaeb\fP
  aegis: project "example": change 1: development build started
  aegis: cook -b Howto.cook project=example change=1
          version=1.0.C001 -nl
  cook: "all" is up-to-date
  aegis: project "example": change 1: development build complete
! pat% \fBaet\fP
  aegis: sh /u/pat/example.001/test/00/t0001a.sh
  aegis: project "example": change 1: test "test/00/t0001a.sh"
          passed
  aegis: project "example": change 1: passed 1 test
! pat% \fBaed\fP
  aegis: set +e; diff -c /dev/null /u/pat/example.001/test/00/
          t0001a.sh > /u/pat/example.001/test/00/t0001a.sh,D; test
          $? -eq 0 -o $? -eq 1
  aegis: project "example": change 1: difference complete
! pat% \fBaede\fP
  aegis: sh /usr/local/lib/aegis/de.sh example 1 pat
  aegis: project "example": change 1: development completed
  pat%
--- 575,600 ----
  re-difference (yes, the test gets differenced, too)
  and sign off.
  .E(
! pat% \f(CBaeb\fP
! aegis: logging to "/u/pat/example.001/aegis.log"
  aegis: project "example": change 1: development build started
  aegis: cook -b Howto.cook project=example change=1
          version=1.0.C001 -nl
  cook: "all" is up-to-date
  aegis: project "example": change 1: development build complete
! pat% \f(CBaet\fP
! aegis: logging to "/u/pat/example.001/aegis.log"
  aegis: sh /u/pat/example.001/test/00/t0001a.sh
  aegis: project "example": change 1: test "test/00/t0001a.sh"
          passed
  aegis: project "example": change 1: passed 1 test
! pat% \f(CBaed\fP
! aegis: logging to "/u/pat/example.001/aegis.log"
  aegis: set +e; diff -c /dev/null /u/pat/example.001/test/00/
          t0001a.sh > /u/pat/example.001/test/00/t0001a.sh,D; test
          $? -eq 0 -o $? -eq 1
  aegis: project "example": change 1: difference complete
! pat% \f(CBaede\fP
  aegis: sh /usr/local/lib/aegis/de.sh example 1 pat
  aegis: project "example": change 1: development completed
  pat%
***************
*** 600,610 ****
  and lists the changes awaiting development,
  the following list appeared:
  .E(
! jan% \fBaedb -l -p example\fP
! 
  Project "example"
  List of Changes
! 
  Change  State           Description
  ------  ------          ------------
     2    awaiting_       Add input and output file names to the
--- 617,627 ----
  and lists the changes awaiting development,
  the following list appeared:
  .E(
! jan% \f(CBaedb -l -p example\fP
  Project "example"
  List of Changes
! .E)
! .E(
  Change  State           Description
  ------  ------          ------------
     2    awaiting_       Add input and output file names to the
***************
*** 618,653 ****
  .LP
  The first on the list is chosen.
  .E(
! jan% \fBaedb -c 2 -p example\fP
  aegis: project "example": change 2: development directory "/u/
          jan/example.002"
  aegis: project "example": change 2: user "jan" has begun
          development
! jan% \fBaecd\fP
  aegis: project "example": change 2: /u/jan/example.002
! jan% \fBael cd\fP
  Project "example", Change 2
  Change Details
! 
  NAME
          Project "example", Change 2.
! 
  SUMMARY
          file names on command line
! 
  DESCRIPTION
          Optional input and output files may be specified on the
          command line.
! 
  CAUSE
          This change was caused by internal_bug.
! 
  STATE
          This change is in 'being_developed' state.
! 
  FILES
          Change has no files.
! 
  HISTORY
          What            When            Who     Comment
          ------          ------          -----   ---------
--- 635,683 ----
  .LP
  The first on the list is chosen.
  .E(
! jan% \f(CBaedb -c 2 -p example\fP
  aegis: project "example": change 2: development directory "/u/
          jan/example.002"
  aegis: project "example": change 2: user "jan" has begun
          development
! jan% \f(CBaecd\fP
  aegis: project "example": change 2: /u/jan/example.002
! jan%
! .E)
! .LP
! The best way to get details about a change is to used the "change details"
! listing.
! .E(
! jan% \f(CBael cd\fP
  Project "example", Change 2
  Change Details
! .E)
! .E(
  NAME
          Project "example", Change 2.
! .E)
! .E(
  SUMMARY
          file names on command line
! .E)
! .E(
  DESCRIPTION
          Optional input and output files may be specified on the
          command line.
! .E)
! .E(
  CAUSE
          This change was caused by internal_bug.
! .E)
! .E(
  STATE
          This change is in 'being_developed' state.
! .E)
! .E(
  FILES
          Change has no files.
! .E)
! .E(
  HISTORY
          What            When            Who     Comment
          ------          ------          -----   ---------
***************
*** 655,661 ****
                          14:55:06 1992
          develop_begin   Mon Dec 14      jan
                          09:07:08 1992
- 
  jan%
  .E)
  .LP
--- 685,690 ----
***************
*** 665,671 ****
  file is the one to be modified.
  This file is copied into the change:
  .E(
! jan% \fBaecp main.c\fP
  aegis: project "example": change 2: file "main.c" copied
  jan%
  .E)
--- 694,700 ----
  file is the one to be modified.
  This file is copied into the change:
  .E(
! jan% \f(CBaecp main.c\fP
  aegis: project "example": change 2: file "main.c" copied
  jan%
  .E)
***************
*** 673,679 ****
  This file is now extended to look like this:
  .E(
  #include <stdio.h>
! 
  static void
  usage()
  {
--- 702,709 ----
  This file is now extended to look like this:
  .E(
  #include <stdio.h>
! .E)
! .E(
  static void
  usage()
  {
***************
*** 716,722 ****
                  perror(out);
                  exit(1);
          }
! 
          yyparse();
          exit(0);
  }
--- 746,753 ----
                  perror(out);
                  exit(1);
          }
! .E)
! .E(
          yyparse();
          exit(0);
  }
***************
*** 724,730 ****
  .LP
  A new test is also required,
  .E(
! jan% \fBaent\fP
  aegis: project "example": change 2: file "test/00/t0002a.sh" new
          test
  jan%
--- 755,761 ----
  .LP
  A new test is also required,
  .E(
! jan% \f(CBaent\fP
  aegis: project "example": change 2: file "test/00/t0002a.sh" new
          test
  jan%
***************
*** 765,771 ****
  .E)
  .E(
  #
! # with input like this...
  #
  cat > test.in << 'foobar'
  1
--- 796,802 ----
  .E)
  .E(
  #
! # with input like this
  #
  cat > test.in << 'foobar'
  1
***************
*** 780,786 ****
  .E)
  .E(
  #
! # ...the output should look like this
  #
  cat > test.ok << 'foobar'
  1
--- 811,817 ----
  .E)
  .E(
  #
! # the output should look like this
  #
  cat > test.ok << 'foobar'
  1
***************
*** 817,823 ****
  #
  $here/example -trash < test.in > test.out
  if [ $? -ne 1 ]; then fail; fi
! 
  #
  # this much worked
  #
--- 848,855 ----
  #
  $here/example -trash < test.in > test.out
  if [ $? -ne 1 ]; then fail; fi
! .E)
! .E(
  #
  # this much worked
  #
***************
*** 829,835 ****
  this works first time,
  and here is how it goes:
  .E(
! jan% \fBaeb\fP
  aegis: project "example": change 2: development build started
  aegis: cook -b /projects/example/baseline/Howto.cook
          project=example change=2 version=1.0.C002 -nl
--- 861,868 ----
  this works first time,
  and here is how it goes:
  .E(
! jan% \f(CBaeb\fP
! aegis: logging to "/u/pat/example.002/aegis.log"
  aegis: project "example": change 2: development build started
  aegis: cook -b /projects/example/baseline/Howto.cook
          project=example change=2 version=1.0.C002 -nl
***************
*** 837,843 ****
  cook: cc -o example main.o /projects/example/baseline/gram.o
          /projects/example/baseline/lex.o -ll -ly
  aegis: project "example": change 2: development build complete
! jan% \fBaet\fP
  aegis: sh /u/jan/example.002/test/00/t0002a.sh
  aegis: project "example": change 2: test "test/00/t0002a.sh"
          passed
--- 870,877 ----
  cook: cc -o example main.o /projects/example/baseline/gram.o
          /projects/example/baseline/lex.o -ll -ly
  aegis: project "example": change 2: development build complete
! jan% \f(CBaet\fP
! aegis: logging to "/u/pat/example.002/aegis.log"
  aegis: sh /u/jan/example.002/test/00/t0002a.sh
  aegis: project "example": change 2: test "test/00/t0002a.sh"
          passed
***************
*** 847,865 ****
  .LP
  All that remains if to difference the change and sign off.
  .E(
! jan% \fBaed\fP
  aegis: set +e; diff -c /projects/example/main.c /u/jan/
          example.002/main.c > /u/jan/example.002/main.c,D; test $?
          -eq 0 -o $? -eq 1
  aegis: project "example": change 2: difference complete
! jan% \fBaedmore\fP
! \fI\&...examines the file...\fP
  jan%
  .E)
  Note how the context difference shows exactly what has changed.
  And now the sign-off:
  .E(
! jan% \fBaede\fP
  aegis: project "example": change 2: no current 'aegis -Test
          -BaseLine' registration
  jan%
--- 881,900 ----
  .LP
  All that remains if to difference the change and sign off.
  .E(
! jan% \f(CBaed\fP
! aegis: logging to "/u/pat/example.002/aegis.log"
  aegis: set +e; diff -c /projects/example/main.c /u/jan/
          example.002/main.c > /u/jan/example.002/main.c,D; test $?
          -eq 0 -o $? -eq 1
  aegis: project "example": change 2: difference complete
! jan% \f(CBaedmore\fP
! \fI\&.\&.\&.examines the file.\&.\&.\fP
  jan%
  .E)
  Note how the context difference shows exactly what has changed.
  And now the sign-off:
  .E(
! jan% \f(CBaede\fP
  aegis: project "example": change 2: no current 'aegis -Test
          -BaseLine' registration
  jan%
***************
*** 882,888 ****
  .I aet
  command.
  .E(
! jan% \fBaet -bl\fP
  aegis: sh /u/jan/example.002/test/00/t0002a.sh
  usage: example
  FAILED
--- 917,923 ----
  .I aet
  command.
  .E(
! jan% \f(CBaet -bl\fP
  aegis: sh /u/jan/example.002/test/00/t0002a.sh
  usage: example
  FAILED
***************
*** 893,900 ****
  .E)
  Running the regression tests is also a good idea
  .E(
! jan% \fBaet -reg\fP
! egis: sh /projects/example/baseline/test/00/t0001a.sh
  aegis: project "example": change 2: test "test/00/t0001a.sh"
          passed
  aegis: project "example": change 2: passed 1 test
--- 928,936 ----
  .E)
  Running the regression tests is also a good idea
  .E(
! jan% \f(CBaet -reg\fP
! aegis: logging to "/u/pat/example.002/aegis.log"
! aegis: sh /projects/example/baseline/test/00/t0001a.sh
  aegis: project "example": change 2: test "test/00/t0001a.sh"
          passed
  aegis: project "example": change 2: passed 1 test
***************
*** 903,909 ****
  .LP
  Now aegis will be satisfied
  .E(
! jan% \fBaede\fP
  aegis: sh /usr/local/lib/aegis/de.sh example 2 jan
  aegis: project "example": change 2: development completed
  jan%
--- 939,945 ----
  .LP
  Now aegis will be satisfied
  .E(
! jan% \f(CBaede\fP
  aegis: sh /usr/local/lib/aegis/de.sh example 2 jan
  aegis: project "example": change 2: development completed
  jan%
***************
*** 920,925 ****
--- 956,1801 ----
  .LP
  First Sam looks for a change to work on and starts,
  like this:
+ .E(
+ sam% \f(CBaedb -l\fP
+ Project "example"
+ List of Changes
+  
+ Change  State           Description
+ ------- -------         -------------
+    3    awaiting_       add powers
+         development
+    4    awaiting_       add variables
+         development
+ sam% \f(CBaedb 3\fP
+ aegis: project "example": change 3: development directory "/u/
+         sam/example.003"
+ aegis: project "example": change 3: user "sam" has begun
+         development
+ sam% \f(CBaecd\fP
+ aegis: project "example": change 3: /u/sam/example.003
+ sam%
+ .E)
+ .LP
+ A little siniffing around reveals that only the
+ .I gram.y
+ grammar file needs to be altered,
+ so it is compied into the change.
+ .E(
+ sam% \f(CBaecp gram.y\fP
+ aegis: project "example": change 3: file "gram.y" copied
+ sam%
+ .E)
+ .LP
+ The grammar file is changed to look like this:
+ .E(
+ %token DOUBLE
+ %token NAME
+ %union
+ {
+         double  lv_double;
+         int     lv_int;
+ };
+ .E)
+ .E(
+ %type <lv_double> DOUBLE expr
+ %type <lv_int> NAME
+ %left '+' '-'
+ %left '*' '/'
+ %right '^'
+ %right UNARY
+ .E)
+ .E(
+ %%
+ example
+         : /* empty */
+         | example command '\n'
+                 { yyerrflag = 0; fflush(stderr); fflush(stdout); }
+         ;
+ .E)
+ .E(
+ command
+         : expr
+                 { printf("%g\n", $1); }
+         | error
+         ;
+ .E)
+ .E(
+ expr
+         : DOUBLE
+         | '(' expr ')'
+                 { $$ = $2; }
+         | '-' expr
+                 %prec UNARY
+                 { $$ = -$2; }
+         | expr '^' expr
+                 { $$ = pow($1, $3); }
+         | expr '*' expr
+                 { $$ = $1 * $3; }
+         | expr '/' expr
+                 { $$ = $1 / $3; }
+         | expr '+' expr
+                 { $$ = $1 + $3; }
+         | expr '-' expr
+                 { $$ = $1 - $3; }
+         ;
+ .E)
+ .LP
+ The changes are very small.
+ Sam checks to make sure using the difference command:
+ .E(
+ sam% \f(CBaed\fP
+ aegis: logging to "/u/sam/example.003/aegis.log"
+ aegis: set +e; diff -c /projects/example/baseline/gram.y /u/sam/
+         example.003/gram.y > /u/sam/example.003/gram.y,D; test $?
+         -eq 0 -o $? -eq 1
+ aegis: project "example": change 3: difference complete
+ sam% \f(CBaedmore\fP
+ \fI\&.\&.\&.examines the file.\&.\&.\fP
+ sam%
+ .E)
+ The difference file looks like this
+ .E(
+ *** /projects/example/baseline/gram.y
+ --- /u/sam/example.003/gram.y
+ ***************
+ *** 1,5 ****
+ --- 1,6 ----
+   %{
+   #include <stdio.h>
+ + #include <math.h>
+   %}
+   %token DOUBLE
+   %token NAME
+ .E)
+ .E(
+ ***************
+ *** 13,18 ****
+ --- 14,20 ----
+   %type <lv_int> NAME
+   %left '+' '-'
+   %left '*' '/'
+ + %right '^'
+   %right UNARY
+   %%
+   example
+ .E)
+ .E(
+ ***************
+ *** 32,37 ****
+ --- 34,41 ----
+         | '-' expr
+                 %prec UNARY
+                 { $$ = -$2; }
+ +       | expr '^' expr
+ +               { $$ = pow($1, $3); }
+         | expr '*' expr
+                 { $$ = $1 * $3; }
+         | expr '/' expr
+ .E)
+ .LP
+ These are the differences Sam expected to see.
+ .LP
+ At this point Sam creates a test.
+ All good software developers create the tests first,
+ don't they?
+ .E(
+ sam% \f(CBaent\fP
+ aegis: project "example": change 3: file "test/00/t0003a.sh" new
+         test
+ sam%
+ .E)
+ .LP
+ The test is created empty,
+ and Sam edit it to look like this:
+ .E(
+ :
+ here=`pwd`
+ if test $? -ne 0 ; then exit 1; fi
+ tmp=/tmp/$$
+ mkdir $tmp
+ if test $? -ne 0 ; then exit 1; fi
+ cd $tmp
+ if test $? -ne 0 ; then exit 1; fi
+ .E)
+ .E(
+ fail()
+ {
+         echo FAILED 1>&2
+         cd $here
+         chmod u+w `find $tmp -type d -print`
+         rm -rf $tmp
+         exit 1
+ }
+ .E)
+ .E(
+ pass()
+ {
+         cd $here
+         chmod u+w `find $tmp -type d -print`
+         rm -rf $tmp
+         exit 0
+ }
+ trap "fail" 1 2 3 15
+ .E)
+ .E(
+ cat > test.in << 'end'
+ 5.3 ^ 0
+ 4 ^ 0.5
+ 27 ^ (1/3)
+ end
+ if test $? -ne 0 ; then fail; fi
+ .E)
+ .E(
+ cat > test.ok << 'end'
+ 1
+ 2
+ 3
+ end
+ if test $? -ne 0 ; then fail; fi
+ .E)
+ .E(
+ $here/example test.in < /dev/null > test.out 2>&1
+ if test $? -ne 0 ; then fail; fi
+ .E)
+ .E(
+ diff test.ok test.out
+ if test $? -ne 0 ; then fail; fi
+ .E)
+ .E(
+ $here/example test.in test.out.2 < /dev/null
+ if test $? -ne 0 ; then fail; fi
+ .E)
+ .E(
+ diff test.ok test.out.2
+ if test $? -ne 0 ; then fail; fi
+ .E)
+ .E(
+ # it probably worked
+ pass
+ .E)
+ .LP
+ Everything is ready.
+ Now the change cane be built and tested,
+ just like the earlier changes.
+ .E(
+ sam% \f(CBaeb\fP
+ aegis: logging to "/u/sam/example.003/aegis.log"
+ aegis: project "example": change 3: development build started
+ aegis: cook -b /projects/example/baseline/Howto.cook
+         project=example change=3 version=1.0.C003 -nl
+ cook: yacc -d gram.y
+ cook: mv y.tab.c gram.c
+ cook: mv y.tab.h gram.h
+ cook: cc -I. -I/projects/example/baseline -O -c gram.c
+ cook: cc -I. -I/projects/example/baseline -O -c /projects/
+         example/baseline/lex.c
+ cook: cc -o example gram.o lex.o /projects/example/baseline/
+         main.o -ll -ly -lm
+ aegis: project "example": change 3: development build complete
+ sam%
+ .E)
+ .LP
+ Notice how the yacc run produces a 
+ .I gram.h
+ which logically invalidates the
+ .I lex.o
+ in the baseline,
+ and so the
+ .I lex.c
+ file in the baseline is recompiled,
+ using the
+ .I gram.h
+ include file from the development directory,
+ leaving a new
+ .I lex.o
+ in the development directory.
+ This is the reason for the use of
+ .E(
+ #include <\f(CIfilename\fP>
+ .E)
+ directives, rather then the double quote form.
+ .PP
+ Now the change is tested.
+ .E(
+ sam% \f(CBaet\fP
+ aegis: logging to "/u/sam/example.003/aegis.log"
+ aegis: sh /u/sam/example.003/test/00/t0003a.sh
+ aegis: project "example": change 3: test "test/00/t0003a.sh"
+         passed
+ aegis: project "example": change 3: passed 1 test
+ sam%
+ .E)
+ .LP
+ The change must also be tested against the baseline, and fail.
+ Sam knows this, and does it here.
+ .E(
+ sam% \f(CBaet -bl\fP
+ aegis: logging to "/u/sam/example.003/aegis.log"
+ aegis: sh /u/sam/example.003/test/00/t0003a.sh
+ 1,3c1,6
+ < 1
+ < 2
+ < 3
+ ---
+ > syntax error
+ > 5.3
+ > syntax error
+ > 4
+ > syntax error
+ > 27
+ FAILED
+ aegis: project "example": change 3: test "test/00/t0003a.sh" on
+         baseline failed (as it should)
+ aegis: project "example": change 3: passed 1 test
+ sam%
+ .E)
+ .LP
+ Running the regression tests
+ is also a good idea.
+ .E(
+ sam% \f(CBaet -reg\fP
+ aegis: logging to "/u/sam/example.003/aegis.log"
+ aegis: sh /projects/example/baseline/test/00/t0001a.sh
+ aegis: project "example": change 3: test "test/00/t0001a.sh"
+         passed
+ aegis: sh /projects/example/baseline/test/00/t0002a.sh
+ aegis: project "example": change 3: test "test/00/t0002a.sh"
+         passed
+ aegis: project "example": change 3: passed 2 tests
+ sam%
+ .E)
+ .LP
+ A this point Sam has just enough time to get to the lunchtime aerobics class in the staff common room.
+ .LP
+ Earlier the same day,
+ Pat arrived for work a little after Sam,
+ and also looked for a change to work on.
+ .E(
+ pat% \f(CBaedb -l\fP
+ Project "example"
+ List of Changes
+  
+ Change  State           Description
+ ------- -------         -------------
+    4    awaiting_       add variables
+         development
+ pat%
+ .E)
+ .LP
+ With such a wide choice,
+ Pat selected change 4.
+ .E(
+ pat% \f(CBaedb 4\fP
+ aegis: project "example": change 4: development directory "/u/
+         pat/example.004"
+ aegis: project "example": change 4: user "pat" has begun
+         development
+ pat% \f(CBaecd\fP
+ aegis: project "example": change 4: /u/pat/example.004
+ pat%
+ .E)
+ .LP
+ To get more information about the change,
+ Pat then uases the "change details" listing:
+ .E(
+ pat% \f(CBael cd\fP
+ Project "example", Change 4
+ Change Details
+ .E)
+ .E(
+ NAME
+         Project "example", Change 4.
+ .E)
+ .E(
+ SUMMARY
+         add variables
+ .E)
+ .E(
+ DESCRIPTION
+         Enhance the grammar to allow variables. Only single
+         letter variable names are required.
+ .E)
+ .E(
+ CAUSE
+         This change was caused by internal_enhancement.
+ .E)
+ .E(
+ STATE
+         This change is in 'being_developed' state.
+ .E)
+ .E(
+ FILES
+         This change has no files.
+ .E)
+ .E(
+ HISTORY
+         What            When            Who     Comment
+         ------          ------          -----   ---------
+         new_change      Mon Dec 14      alex
+                         13:08:52 1992
+         develop_begin   Tue Dec 15      pat
+                         13:38:26 1992
+ pat%
+ .E)
+ .LP
+ To add the variables the grammer needs to be extended to understand them,
+ and a new file for remembering and recalling the values of the
+ variables needs to be added.
+ .E(
+ pat% \f(CBaecp gram.y\fP
+ aegis: project "example": change 4: file "gram.y" copied
+ pat% \f(CBaenf var.c\fP
+ aegis: project "example": change 4: file "var.c" added
+ pat%
+ .E)
+ .LP
+ Notice how aegis raises no objection to both Jan and Pat
+ having a copy of the
+ .I gram.y
+ file.
+ Resolving this contention is the subject of this section.
+ .LP
+ Pat now edits the grammar file.
+ .E(
+ pat% \f(CBvi gram.y\fP
+ \fI\&.\&.\&.edit the file.\&.\&.\fP
+ pat% \f(CBaed\fP
+ aegis: logging to "/u/pat/example.004/aegis.log"
+ aegis: set +e; diff -c /projects/example/baseline/gram.y /u/pat/
+         example.004/gram.y > /u/pat/example.004/gram.y,D; test $?
+         -eq 0 -o $? -eq 1
+ aegis: project "example": change 4: difference complete
+ pat%
+ .E)
+ .LP
+ The difference file looks like this
+ .E(
+ \&...
+ .E)
+ .LP
+ The new
+ .I var.c
+ file was created empty by aegis,
+ and Pat edits it to look like this:
+ .E(
+ static double memory[26];
+ .E)
+ .E(
+ void
+ assign(name, value)
+         int     name;
+         double  value;
+ {
+         memory[name] = value;
+ }
+ .E)
+ .E(
+ double
+ recall(name)
+         int     name;
+ {
+         return memory[name];
+ }
+ .E)
+ .LP
+ Little remains except to build the change.
+ .E(
+ pat% \f(CBaeb\fP
+ aegis: logging to "/u/pat/example.004/aegis.log"
+ aegis: cook -b /tmp/8508/example.proj/baseline/Howto.cook
+         project=example change=4 version=1.0.C004 -nl
+ cook: yacc -d gram.y
+ cook: mv y.tab.c gram.c
+ cook: mv y.tab.h gram.h
+ cook: cc -I. -I/projects/example/baseline -O -c gram.c
+ cook: cc -I. -I/projects/example/baseline -O -c /projects/
+         example/baseline/lex.c
+ cook: cc -I. -I/projects/example/baseline -O -c var.c
+ cook: cc -o example gram.o lex.o /projects/example/baseline/
+         main.o var.o -ll -ly -lm
+ aegis: project "example": change 4: development build complete
+ pat%
+ .E)
+ .LP
+ A new test for the new functionality is required.
+ .E(
+ :
+ here=`pwd`
+ if test $? -ne 0 ; then exit 1; fi
+ tmp=/tmp/$$
+ mkdir $tmp
+ if test $? -ne 0 ; then exit 1; fi
+ cd $tmp
+ if test $? -ne 0 ; then exit 1; fi
+ .E)
+ .E(
+ fail()
+ {
+         echo FAILED 1>&2
+         cd $here
+         chmod u+w `find $tmp -type d -print`
+         rm -rf $tmp
+         exit 1
+ }
+ pass()
+ {
+         cd $here
+         chmod u+w `find $tmp -type d -print`
+         rm -rf $tmp
+         exit 0
+ }
+ trap "fail" 1 2 3 15
+ .E)
+ .E(
+ cat > test.in << 'end'
+ a = 1
+ a + 1
+ c = a * 40 + 5
+ c / (a + 4)
+ end
+ if test $? -ne 0 ; then fail; fi
+ .E)
+ .E(
+ cat > test.ok << 'end'
+ 2
+ 9
+ end
+ if test $? -ne 0 ; then fail; fi
+ .E)
+ .E(
+ $here/example test.in < /dev/null > test.out 2>&1
+ if test $? -ne 0 ; then fail; fi
+ .E)
+ .E(
+ diff test.ok test.out
+ if test $? -ne 0 ; then fail; fi
+ .E)
+ .E(
+ $here/example test.in test.out.2 < /dev/null
+ if test $? -ne 0 ; then fail; fi
+ .E)
+ .E(
+ diff test.ok test.out.2
+ if test $? -ne 0 ; then fail; fi
+ .E)
+ .E(
+ # it probably worked
+ pass
+ .E)
+ .LP
+ The new files are then differenced:
+ .E(
+ pat% \f(CBaed\fP
+ aegis: logging to "/u/pat/example.004/aegis.log"
+ aegis: set +e; diff -c /projects/example/baseline/gram.y /u/pat/
+         example.004/gram.y > /u/pat/example.004/gram.y,D; test $?
+         -eq 0 -o $? -eq 1
+ aegis: set +e; diff -c /dev/null /u/pat/example.004/test/00/
+         t0004a.sh > /u/pat/example.004/test/00/t0004a.sh,D; test
+         $? -eq 0 -o $? -eq 1
+ aegis: set +e; diff -c /dev/null /u/pat/example.004/var.c > /u/
+         pat/example.004/var.c,D; test $? -eq 0 -o $? -eq 1
+ aegis: project "example": change 4: difference complete
+ pat%
+ .E)
+ .LP
+ Notice how the difference for the
+ .I gram.y
+ file is still current,
+ and so is not run again.
+ .LP
+ The change is tested.
+ .E(
+ pat% \f(CBaet\fP
+ aegis: logging to "/u/pat/example.004/aegis.log"
+ aegis: sh /u/pat/example.004/test/00/t0001a.sh
+ aegis: project "example": change 4: test "test/00/t0004a.sh"
+         passed
+ aegis: project "example": change 4: passed 2 tests
+ pat%
+ .E)
+ .LP
+ The change is tested against the baseline.
+ .E(
+ pat% \f(CBaet\fP
+ aegis: logging to "/u/pat/example.004/aegis.log"
+ aegis: sh /u/pat/example.004/test/00/t0001a.sh
+ 1,2c1,4
+ < 2
+ < 9
+ ---
+ > syntax error
+ > syntax error
+ > syntax error
+ > syntax error
+ FAILED
+ aegis: project "example": change 4: test "test/00/t0004a.sh" on
+         baseline failed (as it should)
+ pat%
+ .E)
+ .LP
+ And the regression tests
+ .E(
+ pat% \f(CBaet -reg\fP
+ aegis: logging to "/u/pat/example.004/aegis.log"
+ aegis: sh /projects/example/baseline/test/00/t0001a.sh
+ aegis: project "example": change 4: test "test/00/t0001a.sh"
+         passed
+ aegis: sh /projects/example/baseline/test/00/t0002a.sh
+ aegis: project "example": change 4: test "test/00/t0002a.sh"
+         passed
+ aegis: project "example": change 4: passed 2 tests
+ pat%
+ .E)
+ .LP
+ Note how test 3 has not been run,
+ in any form of testing.
+ This is because test 3 is part of another change,
+ and is not yet integrated with the baseline.
+ .LP
+ All is finished for this change,
+ .E(
+ pat% \f(CBaede\fP
+ aegis: sh /usr/local/lib/aegis/de.sh example 4 pat
+ aegis: project "example": change 4: development completed
+ pat%
+ .E)
+ .LP
+ Anxious to get this change into the baseline,
+ Pat now wanders down the hall in search of a reviewer,
+ but more of that in the next section.
+ .LP
+ Some time later,
+ Jan returns fram aerobics feeling much improved.
+ All that is required for change 3 is
+ to do develop end, or is it?
+ .E(
+ jan% \f(CBaede\fP
+ aegis: project "example": change 3: file "gram.y" in baseline
+         has changed since last 'aegis -DIFFerence' command
+ jan%
+ .E)
+ .LP
+ A little sleuthing on Jan's part with the aegis list command
+ will reveal how this came about.
+ The way to resolve this problem is with the difference command.
+ .E(
+ jan% \f(CBaed\fP
+ aegis: logging to "/u/pat/example.003/aegis.log"
+ aegis: co -u'1.1' -p /projects/example/history/gram.y,v > /tmp/
+         aegis.14594
+ /projects/example/history/gram.y,v  -->  stdout revision 1.1 (unlocked)
+ aegis: (diff3 -e /projects/example/baseline/gram.y /tmp/
+         aegis.14594 /u/jan/example.003/gram.y | sed -e '/^w$/d'
+         -e '/^q$/d'; \techo '1,$p' ) | ed - /projects/example/
+         baseline/gram.y > /u/jan/example.003/gram.y,D
+ aegis: project "example": change 3: difference complete
+ aegis: project "example": change 3: file "gram.y" was out of
+         date, see "gram.y,D" for details
+ aegis: new 'aegis -Build' required
+ jan%
+ .E)
+ .LP
+ This was caused by the conflicty between change 4,
+ which is now integrated,
+ and change 3;
+ both of which are editing the
+ .I gram.y
+ file.
+ Jan examines the
+ .I gram.y,D
+ file,
+ and discovers that it contains an accurate merge of
+ the edit done by change 4 and the edits for this change.
+ The difference file looks like this:
+ .E(
+ %{
+ #include <stdio.h>
+ #include <math.h>
+ %}
+ %token DOUBLE
+ %token NAME
+ %union
+ {
+         double  lv_double;
+         int     lv_int;
+ };
+ .E)
+ .E(
+ %type <lv_double> DOUBLE expr
+ %type <lv_int> NAME
+ %left '+' '-'
+ %left '*' '/'
+ %right '^'
+ %right UNARY
+ .E)
+ .E(
+ %%
+ example
+         : /* empty */
+         | example command '\en'
+                 { yyerrflag = 0; fflush(stderr); fflush(stdout); }
+         ;
+ .E)
+ .E(
+ command
+         : expr
+                 { printf("%g\n", $1); }
+         | NAME '=' expr
+                 { assign($1, $3); }
+         | error
+         ;
+ .E)
+ .E(
+ expr
+         : DOUBLE
+         | NAME
+                 { extern double recall(); $$ = recall($1); }
+         | '(' expr ')'
+                 { $$ = $2; }
+         | '-' expr
+                 %prec UNARY
+                 { $$ = -$2; }
+         | expr '^' expr
+                 { $$ = pow($1, $3); }
+         | expr '*' expr
+                 { $$ = $1 * $3; }
+         | expr '/' expr
+                 { $$ = $1 / $3; }
+         | expr '+' expr
+                 { $$ = $1 + $3; }
+         | expr '-' expr
+                 { $$ = $1 - $3; }
+         ;
+ .E)
+ This is because most such conflicts are actually working
+ on logically separate portions of the file.
+ Two diferent areas of the grammar in this case.
+ In practice,
+ there is rarely a real conflict,
+ and it is usually small enough to detect fairly quickly.
+ Notice that aegis did not automatically put the merge in
+ place of your edited file,
+ for just this reason.
+ .LP
+ Jan simply copies the difference file on top of the
+ original, and rebuilds:
+ .E(
+ jan% \f(CBmv gram.y,D gram.y\fP
+ jan% \f(CBaeb\fP
+ aegis: logging to "/u/jan/example.003/aegis.log"
+ aegis: project "example": change 3: development build started
+ aegis: cook -b /tmp/13906/example.proj/baseline/Howto.cook
+         project=example change=3 version=1.0.C003 -nl
+ cook: rm gram.c
+ cook: rm gram.h
+ cook: yacc -d gram.y
+ cook: mv y.tab.c gram.c
+ cook: mv y.tab.h gram.h
+ cook: rm gram.o
+ cook: cc -I. -I/projects/example/baseline -O -c gram.c
+ cook: rm lex.o
+ cook: cc -I. -I/projects/example/baseline -O -c /projects/
+         example/baseline/lex.c
+ cook: rm example
+ cook: cc -o example gram.o lex.o /projects/example/baseline/
+         main.o /projects/example/baseline/var.o -ll -ly -lm
+ aegis: project "example": change 3: development build complete
+ jan%
+ .E)
+ .LP
+ Notice how the list of object files linked has also adapted to the
+ addition of another file in the baseline,
+ without any extra work by Jan.
+ .LP
+ All that remains is to test the change again.
+ .E(
+ jan% \f(CBaet\fP
+ aegis: /bin/sh /tmp/13906/example.chan.3/test/00/t0003a.sh
+ aegis: project "example": change 3: test "test/00/t0003a.sh"
+         passed
+ aegis: project "example": change 3: passed 1 test
+ jan%
+ .E)
+ And test against the baseline,
+ .E(
+ jan% \f(CBaet -bl\fP
+ aegis: /bin/sh /tmp/13906/example.chan.3/test/00/t0003a.sh
+ 1,3c1,6
+ < 1
+ < 2
+ < 3
+ ---
+ > syntax error
+ > 5.3
+ > syntax error
+ > 4
+ > syntax error
+ > 27
+ FAILED
+ aegis: project "example": change 3: test "test/00/t0003a.sh" on
+         baseline failed (as it should)
+ aegis: project "example": change 3: passed 1 test
+ jan%
+ .E)
+ .LP
+ Perform the regression tests, too.
+ This is important for a merged chnage,
+ to make sure you didn't break the functionality
+ you merged with.
+ .E(
+ jan% \f(CBaet -reg\fP
+ aegis: logging to "/u/jan/example.003/aegis.log"
+ aegis: /bin/sh /projects/example/baseline/test/00/
+         t0001a.sh
+ aegis: project "example": change 3: test "test/00/t0001a.sh"
+         passed
+ aegis: /bin/sh /projects/example/baseline/test/00/
+         t0002a.sh
+ aegis: project "example": change 3: test "test/00/t0002a.sh"
+         passed
+ aegis: /bin/sh /projects/example/baseline/test/00/
+         t0004a.sh
+ aegis: project "example": change 3: test "test/00/t0004a.sh"
+         passed
+ aegis: project "example": change 3: passed 3 tests
+ jan%
+ .E)
+ All done, or are we?
+ .E(
+ jan% \f(CBaede\fP
+ aegis: project "example": change 3: no current 'aegis -Diff'
+         registration
+ jan%
+ .E)
+ The difference we did earlier,
+ which revealed that we were out of date,
+ does not show the differences since the two changes were
+ merged, and possibly further edited.
+ .E(
+ jan% \f(CBaed\fP
+ aegis: logging to "/u/jan/example.003/aegis.log"
+ aegis: set +e; diff /projects/example/baseline/gram.y /u/pat/
+         example.003/gram.y > /u/pat/example.003/gram.y,D; test $? -le 1
+ aegis: project "example": change 3: difference complete
+ jan%
+ .E)
+ This time everything will run smoothly, 
+ .E(
+ jan% \f(CBaede\fP
+ aegis: project "example": change 3: development completed
+ jan%
+ .E)
+ Some time soon
+ Jan will recieve email that this change passed review,
+ and later that it passed integration.
+ .LP
+ Within the scope of a limited example,
+ you have seen most of what aegis can do.
+ To get a true feeling for the program
+ you need to try it in a similarly simple case.
+ You could even try doing this example manually.
  .bp
  .nh 3 "Developer Command Summary"
  .LP
***************
*** 932,942 ****
  l l.
  Command;Description
  _
! aedb;Develop Begin
! aedbu;Develop Begin Undo
  aecd;Change Directory
  aecp;Copy File
  aecpu;Copy File Undo
  aenf;New File
  aenfu;New File Undo
  aent;New Test
--- 1808,1824 ----
  l l.
  Command;Description
  _
! aeb;Build
! aeca;Change Attributes
  aecd;Change Directory
  aecp;Copy File
  aecpu;Copy File Undo
+ aed;Difference
+ aedb;Develop Begin
+ aedbu;Develop Begin Undo
+ aede;Develop End
+ aedeu;Develop End Undo
+ ael;List Stuff
  aenf;New File
  aenfu;New File Undo
  aent;New Test
***************
*** 943,955 ****
  aentu;New Test Undo
  aerm;Remove File
  aermu;Remove File Undo
- aeb;Build
- aed;Difference
  aet;Test
- aeca;Change Attributes
- aede;Develop End
- aedeu;Develop End Undo
- ael;List Stuff
  .TE
  .LP
  You will want to read the manual entries for all of these commands.
--- 1825,1831 ----
Index: doc/c2.2.so
***************
*** 1,12 ****
  .\"
  .\"	aegis - project change supervisor
! .\"	Copyright (c) 1991-1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 1, or (at your option)
! .\"	any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  .\"
  .\"	aegis - project change supervisor
! .\"	Copyright (C) 1991, 1992, 1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 2 of the License, or
! .\"	(at your option) any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 22,97 ****
  .bp
  .nh 2 "The Reviewer"
  .LP
  .nh 3 "The First Change"
  .LP
! This hasn't all been typed in yet,
! only the aegis output has been copied across.
  .E(
! robyn% \fBaerpass -l -p example\fP
! \&...
  robyn%
  .E)
! words
  .E(
! robyn% \fBaecd -p example -c 1\fP
  aegis: project "example": change 1: /u/pat/example.001
! robyn% \fBaedmore\fP
! \fI\&...examines each file...\fP
  robyn%
  .E)
! words
  .E(
! robyn% \fBaerpass example 1\fP
  aegis: sh /usr/local/lib/aegis/rp.sh example 1 pat robyn
  aegis: project "example": change 1: passed review
  robyn%
  .E)
! word
  .nh 3 "The Second Change"
  .LP
! words
  .E(
! robyn% \fBaerpass -l -p example\fP
! \&...
  robyn%
  .E)
  .LP
! words
  .E(
! robyn% \fBaecd -p example -c 2\fP
  aegis: project "example": change 2: /u/jan/example.002
  robyn%
  .E)
  .LP
! words
  .E(
! robyn% \fBael cd -p example -c 2\fP
   
  Project "example", Change 2
  Change Details
!  
  NAME
          Project "example", Change 2.
!  
  SUMMARY
          file names on command line
!  
  DESCRIPTION
          Optional input and output files may be specified on
          the command line.
!  
  CAUSE
          This change was caused by internal_bug.
!  
  STATE
          This change is in 'being_integrated' state.
! 
  FILES
          Type    Action  Edit    File Name
          ------- ------- ------- -----------
          source  modify  1.1     main.c
          test    create          test/00/t0002a.sh
!  
  HISTORY
          What            When            Who     Comment
          ------          ------          -----   ---------
--- 22,157 ----
  .bp
  .nh 2 "The Reviewer"
  .LP
+ The role of a reviewer is to check another user's work.
+ You are helped in this by aegis,
+ because changes can never reach the
+ .I "being reviewed"
+ state without several preconditions:
+ .LP
+ \(bu The change is know to build.
+ You know that it compiled sucessfully,
+ so there is no need to search for syntax errors.
+ .LP
+ \(bu The change has tests,
+ and those tests have been run,
+ and have passed.
+ .LP
+ This information allows you to concentrate on implementation issues,
+ completeness issues,
+ and local standards issues.
+ .LP
+ To help the reviewer,
+ a set of "command D" files is available
+ in the change development directory.
+ Every files which is to be added to the baseline, 
+ removed from the baseline,
+ or changed in some way,
+ has a corresponding "comma D" file.
  .nh 3 "The First Change"
  .LP
! Robyn finds out what changes are available for review
! by asking aegis:
  .E(
! robyn% \f(CBaerpass -l -p example\fP
! 
! Project "example"
! List of Changes
! 
! Change  State           Description
! ------- -------         -------------
!    1    being_reviewed  Place under aegis
  robyn%
  .E)
! Any of the above changes could be reviewed,
! Robyn chooses the first.
  .E(
! robyn% \f(CBaecd -p example -c 1\fP
  aegis: project "example": change 1: /u/pat/example.001
! robyn% \f(CBaedmore\fP
! \fI\&.\&.\&.examines each file.\&.\&.\fP
  robyn%
  .E)
! The
! .I aedmore
! command walks the development directory tree to find all of
! the "comma D" files, and displays them using
! .IR more (1)
! There is a corresponding
! .I aedless
! for those who prefer the
! .IR less (1)
! command.
! .LP
! Once the change has bben reviewd and found acceptable,
! it is passed:
  .E(
! robyn% \f(CBaerpass example 1\fP
  aegis: sh /usr/local/lib/aegis/rp.sh example 1 pat robyn
  aegis: project "example": change 1: passed review
  robyn%
  .E)
! Some time soon Isa will notice the email
! notification and commence integration of the change.
  .nh 3 "The Second Change"
  .LP
! Most reviews have the same pattern as the first.
  .E(
! robyn% \f(CBaerpass -l -p example\fP
! 
! Project "example"
! List of Changes
! 
! Change  State           Description
! ------- -------         -------------
!    2    being_reviewed  file names on command line
  robyn%
  .E)
  .LP
! Always change directory to the change's development directory,
! otherwise you will not be able to review the files.
  .E(
! robyn% \f(CBaecd -p example -c 2\fP
  aegis: project "example": change 2: /u/jan/example.002
  robyn%
  .E)
  .LP
! Another useful way of finding out about a change
! is the "list change details" command, viz:
  .E(
! robyn% \f(CBael cd -p example -c 2\fP
   
  Project "example", Change 2
  Change Details
! .E)
! .E(
  NAME
          Project "example", Change 2.
! .E)
! .E(
  SUMMARY
          file names on command line
! .E)
! .E(
  DESCRIPTION
          Optional input and output files may be specified on
          the command line.
! .E)
! .E(
  CAUSE
          This change was caused by internal_bug.
! .E)
! .E(
  STATE
          This change is in 'being_integrated' state.
! .E)
! .E(
  FILES
          Type    Action  Edit    File Name
          ------- ------- ------- -----------
          source  modify  1.1     main.c
          test    create          test/00/t0002a.sh
! .E)
! .E(
  HISTORY
          What            When            Who     Comment
          ------          ------          -----   ---------
***************
*** 104,131 ****
  robyn%
  .E)
  .LP
! words
  .E(
! robyn% \fBaedmore\fP
! \fI\&...examines each file...\fP
  robyn%
  .E)
  .LP
! words
  .E(
! robyn% \fBaerpass example 2\fP
  aegis: sh /usr/local/lib/aegis/rp.sh example 2 jan robyn
  aegis: project "example": change 2: passed review
  robyn%
  .E)
  .LP
! words
! .nh 3 "The Fourth Change"
  .LP
! Because software production is so unpredicatable,
! the fourth change is reviewed before the third.
! .nh 3 "The Third Change"
! .LP
  .nh 3 "Reviewer Command Summary"
  .LP
  Only a few of the aegis commands available to reviewers have
--- 164,196 ----
  robyn%
  .E)
  .LP
! Once Robyn knows what the change is meant to be doing,
! the files are then examined:
  .E(
! robyn% \f(CBaedmore\fP
! \fI\&.\&.\&.examines each file.\&.\&.\fP
  robyn%
  .E)
  .LP
! Once the change is found to be acceptable,
! it is passed:
  .E(
! robyn% \f(CBaerpass example 2\fP
  aegis: sh /usr/local/lib/aegis/rp.sh example 2 jan robyn
  aegis: project "example": change 2: passed review
  robyn%
  .E)
  .LP
! Some time soon Isa will notice the email
! notification and commence integration of the change.
  .LP
! The reviews of the third and fourth changes will
! not be given here,
! because they are almost identical to the other changes.
! If you want to know how to fail a review,
! see the
! .IR aerfail (1)
! manual entry.
  .nh 3 "Reviewer Command Summary"
  .LP
  Only a few of the aegis commands available to reviewers have
Index: doc/c2.3.so
***************
*** 1,12 ****
  .\"
  .\"	aegis - project change supervisor
! .\"	Copyright (c) 1991-1992 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 1, or (at your option)
! .\"	any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  .\"
  .\"	aegis - project change supervisor
! .\"	Copyright (C) 1991, 1992, 1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 2 of the License, or
! .\"	(at your option) any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 22,35 ****
  .bp
  .nh 2 "The Integrator"
  .LP
  .nh 3 "The First Change"
  .LP
! This hasn't all been typed in yet,
! only the aegis output has been copied across.
  .E(
! isa% \fBaeib -l -p example\fP
! \&...
! isa% \fBaeib example 1\fP
  aegis: project "example": change 1: link baseline to integration
          directory
  aegis: project "example": change 1: apply change to integration
--- 22,56 ----
  .bp
  .nh 2 "The Integrator"
  .LP
+ This section shows what the integrator must do for each of the
+ changes shown to date.
+ The integrator does not have the ability to alter anything in the change;
+ if a change being integrated is defective,
+ it is simply failed back to the developer.
+ This documented example has no such failures,
+ in order to keep it managebly small.
  .nh 3 "The First Change"
  .LP
! The first change of a project is often the trickiest,
! and the integrator is the last to know.
! This example goes smoothly,
! and you may want to consider using the example project
! as a template.
! .LP
! The intergator for this example project is Isa.
! Isa knows there is a change ready for integration
! from the notification which arrived by email.
  .E(
! isa% \f(CBaeib -l -p example\fP
! 
! Project "example"
! List of Changes
! 
! Change  State           Description
! ------- -------         -------------
!    1    awaiting_       Place under aegis
!         integration
! isa% \f(CBaeib example 1\fP
  aegis: project "example": change 1: link baseline to integration
          directory
  aegis: project "example": change 1: apply change to integration
***************
*** 37,45 ****
  aegis: project "example": change 1: integration has begun
  isa%
  .E)
! word
  .E(
! isa% \fBaeb\fP
  aegis: project "example": change 1: integration build started
  aegis: cook -b Howto.cook project=example change=1
          version=1.0.D001 -nl
--- 58,70 ----
  aegis: project "example": change 1: integration has begun
  isa%
  .E)
! .LP
! The integrator must rebuild and retest each change.
! This ensures that it was no quirk of the developer's
! environment which resulted in the success at the development stage.
  .E(
! isa% \f(CBaeb\fP
! aegis: logging to "/projects/example/delta.001/aegis.log"
  aegis: project "example": change 1: integration build started
  aegis: cook -b Howto.cook project=example change=1
          version=1.0.D001 -nl
***************
*** 55,63 ****
  aegis: project "example": change 1: integration build complete
  isa%
  .E)
! word
  .E(
! isa% \fBaet\fP
  aegis: sh /project/example/delta.001/test/00/t0001a.sh
  aegis: project "example": change 1: test "test/00/t0001a.sh"
          passed
--- 80,107 ----
  aegis: project "example": change 1: integration build complete
  isa%
  .E)
! .LP
! Notice how the above build differed from the builds that were done
! while in the
! .I "being developed"
! state;
! the extra baseline include is gone.
! This is because the integration directory will shortly be the new baseline,
! and must be entirely internally coinsistent and self-sufficient.
! .LP
! You are probably wondering why this isn't all rolled into the
! one aegis command.
! It is not because there may be some manual process to be
! performed after the build and before the test.
! This may be making a command set-uid-root (as in the case of aegis)
! or it may require some tinkering with the local oracle or ingres database.
! Instructions for the integrator may be placed in the
! description field of the change attributes.
! .LP
! The change is now re-tested:
  .E(
! isa% \f(CBaet\fP
! aegis: logging to "/projects/example/delta.001/aegis.log"
  aegis: sh /project/example/delta.001/test/00/t0001a.sh
  aegis: project "example": change 1: test "test/00/t0001a.sh"
          passed
***************
*** 64,72 ****
  aegis: project "example": change 1: passed 1 test
  isa%
  .E)
! word
  .E(
! isa% \fBaeipass\fP
  aegis: ci -u -m/dev/null -t/dev/null /projects/example/delta.001/
          Howto.cook /projects/example/history/Howto.cook,v;
          rcs -U /projects/example/history/Howto.cook,v
--- 108,122 ----
  aegis: project "example": change 1: passed 1 test
  isa%
  .E)
! The change builds and tests.
! Once Isa is happy with the change,
! perhaps after browsing the files,
! Isa then passes the integration,
! causing the history files to be updated
! andf the integration directory becomes the baseline.
  .E(
! isa% \f(CBaeipass\fP
! aegis: logging to "/projects/example/delta.001/aegis.log"
  aegis: ci -u -m/dev/null -t/dev/null /projects/example/delta.001/
          Howto.cook /projects/example/history/Howto.cook,v;
          rcs -U /projects/example/history/Howto.cook,v
***************
*** 83,101 ****
  aegis: project "example": change 1: integrate pass
  isa%
  .E)
- word
- .nh 3 "The Second Change"
  .LP
! words
! .E(
! stuff here
! .E)
! .nh 3 "The Fourth Change"
  .LP
! Because software production is so upredicatable,
! the fourth change is integrated before the third.
! .nh 3 "The Third Change"
  .LP
  .nh 3 "Integrator Command Summary"
  .LP
  Only a few of the aegis commands available to integrators have
--- 133,161 ----
  aegis: project "example": change 1: integrate pass
  isa%
  .E)
  .LP
! All of the staff involved,
! will receive email to say that the change has been integrated.
! This notification is a shell script,
! so USENET could be useflly used instead.
! .nh 3 "The Other Changes"
  .LP
! There is no difference to integrating any of the later changes.
! The integration process is very simple,
! as it is a cut-down version of what the developer does,
! without all the complexity.
  .LP
+ Your project may elect to have the integrator also monitor
+ the quality of the reviews.
+ An answer to "who will watch the watchers" if you like.
+ .LP
+ It is also a good idea to rotate people out of the integrator
+ position after a few weeks in a busy project,
+ this is a very stressful position.
+ The position of integrator gives a unique perspective to software quality,
+ but the person also needs to be able to say "NO!" when a cruddy
+ change comes along.
+ .bp
  .nh 3 "Integrator Command Summary"
  .LP
  Only a few of the aegis commands available to integrators have
***************
*** 108,121 ****
  l l.
  Command;Description
  _
  aeib;Integrate Begin
  aeibu;Integrate Begin Undo
- aecd;Change Directory
- aeb;Build
- aet;Test
- aeupass;Integrate Pass
  aeifail;Integrate Fail
  ael;List Stuff
  .TE
  .LP
  You will want to read the manual entries for all of these commands.
--- 168,181 ----
  l l.
  Command;Description
  _
+ aeb;Build
+ aecd;Change Directory
  aeib;Integrate Begin
  aeibu;Integrate Begin Undo
  aeifail;Integrate Fail
  ael;List Stuff
+ aet;Test
+ aeupass;Integrate Pass
  .TE
  .LP
  You will want to read the manual entries for all of these commands.
Index: doc/c2.4.so
***************
*** 1,12 ****
  .\"
  .\"	aegis - project change supervisor
! .\"	Copyright (c) 1991-1992 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 1, or (at your option)
! .\"	any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  .\"
  .\"	aegis - project change supervisor
! .\"	Copyright (C) 1991, 1992, 1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 2 of the License, or
! .\"	(at your option) any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 58,71 ****
  the first change;
  the projecty must be created,
  the staff but be given access permissions,
! the chang must be created.
  .E(
! alex% \fBaenpr example -dir /projects/example\fP
  aegis: project "example": project directory "/projects/example"
  aegis: project "example": created
  alex%
  .E)
! words
  .E(
  description = "Aegis Documentation Example Project";
  developer_may_review = false;
--- 58,76 ----
  the first change;
  the projecty must be created,
  the staff but be given access permissions,
! the change must be created.
  .E(
! alex% \f(CBaenpr example -dir /projects/example\fP
  aegis: project "example": project directory "/projects/example"
  aegis: project "example": created
  alex%
  .E)
! Once the project has been created,
! the project attributes are set.
! Alex creates a file called "fred"
! (it could have been called anything)
! and edits it to reflect the desired project attributes.
! It looks like this:
  .E(
  description = "Aegis Documentation Example Project";
  developer_may_review = false;
***************
*** 72,82 ****
  developer_may_integrate = false;
  reviewer_may_integrate = false;
  .E)
! words
  .E(
! alex% \fBaepa fred -p example\fP
  aegis: project "example": attributes changed
! alex% \fBael p\fP
  List of Projects
  
  Project Directory               Description
--- 77,89 ----
  developer_may_integrate = false;
  reviewer_may_integrate = false;
  .E)
! Once this file has been created,
! the project  attributes ae set as follows:
  .E(
! alex% \f(CBaepa fred -p example\fP
  aegis: project "example": attributes changed
! alex% \f(CBrm fred\fP
! alex% \f(CBael p\fP
  List of Projects
  
  Project Directory               Description
***************
*** 85,112 ****
                                  Project
  alex%
  .E)
! words
  .E(
! alex% \fBaend pat jan sam -p example\fP
  aegis: project "example": user "pat" is now a developer
  aegis: project "example": user "jan" is now a developer
  aegis: project "example": user "sam" is now a developer
  alex%
  .E)
! words
  .E(
! alex% \fBaenr robyn jan -p example\fP
  aegis: project "example": user "robyn" is now a reviewer
  aegis: project "example": user "jan" is now a reviewer
  alex%
  .E)
! words
  .E(
! alex% \fBaeni isa -p example\fP
  aegis: project "example": user "isa" is now an integrator
  alex%
  .E)
! words
  .E(
  brief_description = "Create initial skeleton.";
  description = "A simple calculator using native \e
--- 92,125 ----
                                  Project
  alex%
  .E)
! The various staff must be added to the project.
! Developers are the only staff who may actually edit files.
  .E(
! alex% \f(CBaend pat jan sam -p example\fP
  aegis: project "example": user "pat" is now a developer
  aegis: project "example": user "jan" is now a developer
  aegis: project "example": user "sam" is now a developer
  alex%
  .E)
! Reviewers may veto c ahnge.
! There may be overlap between the various categories,
! as show here for Jan:
  .E(
! alex% \f(CBaenr robyn jan -p example\fP
  aegis: project "example": user "robyn" is now a reviewer
  aegis: project "example": user "jan" is now a reviewer
  alex%
  .E)
! The next role we need to fill is an integrator.
  .E(
! alex% \f(CBaeni isa -p example\fP
  aegis: project "example": user "isa" is now an integrator
  alex%
  .E)
! Once the staff have been given access,
! Alex creates the descrfiption of the first change.
! The temporary file name is again "fred",
! and is edited to look like this:
  .E(
  brief_description = "Create initial skeleton.";
  description = "A simple calculator using native \e
***************
*** 116,131 ****
  Parentheses and negation also required.";
  cause = internal_enhancement;
  .E)
! words
  .E(
! alex% \fBaenc ncf -p example\fP
  aegis: project "example": change 1: created
  alex%
  .E)
! words
  .nh 3 "The Second Change"
  .LP
! words
  .E(
  brief_description = "file names on command line";
  description = "Optional input and output files may be \e
--- 129,153 ----
  Parentheses and negation also required.";
  cause = internal_enhancement;
  .E)
! Once this description file is created,
! the change is created as follows:
  .E(
! alex% \f(CBaenc ncf -p example\fP
  aegis: project "example": change 1: created
+ alex% \f(CBrm fred\fP
  alex%
  .E)
! At this point,
! Alex walks down the hall to Jan's office,
! to ask Jan to develop the first change.
! Jand has had some practice using aegis,
! and can be relied on to do the rest of the project configuarion speedily.
  .nh 3 "The Second Change"
  .LP
! Some time later,
! Alex patiently sits through whining anf grumbing from an
! especially pedantic user.
! The following change description is duly entered:
  .E(
  brief_description = "file names on command line";
  description = "Optional input and output files may be \e
***************
*** 133,179 ****
  cause = internal_bug;
  .E)
  .LP
! words
  .E(
! alex% \fBaenc ncf -p example\fP
  aegis: project "example": change 2: created
  alex%
  .E)
! words
  .nh 3 "The Third Change"
  .LP
! words
  .E(
! brief_description = "add variables";
! description = "Enhance the grammar to allow variables.  \e
! Only single letter variable names are required.";
  cause = internal_enhancement;
  .E)
  .LP
! words
  .E(
! alex% \fBaenc ncf -p example\fP
  aegis: project "example": change 3: created
  alex%
  .E)
! words
  .nh 3 "The Fourth Change"
  .LP
! words
  .E(
! brief_description = "add powers";
! description = "Enhance the grammar to allow exponentiation.  \e
! No error checking required.";
  cause = internal_enhancement;
  .E)
  .LP
! words
  .E(
! alex% \fBaenc ncf -p example\fP
  aegis: project "example": change 4: created
  alex%
  .E)
! words
  .nh 3 "Administrator Command Summary"
  .LP
  Only a few of the aegis commands available to administrators have
--- 155,215 ----
  cause = internal_bug;
  .E)
  .LP
! The pedantic user wanted to be able to name
! files on the command line,
! rather than use I/O redirection.
! Also,
! having a bug in this example is useful.
! Alex is very systematic,
! and uses his trusty "fred" file again:
  .E(
! alex% \f(CBaenc fred -p example\fP
  aegis: project "example": change 2: created
  alex%
  .E)
! At some point a developer will notice this change
! and start work on it.
  .nh 3 "The Third Change"
  .LP
! Other features are required for the calculator,
! and also for this example.
! The second change adds exponentiation to the calculator,
! and is described as follows:
  .E(
! brief_description = "add powers";
! description = "Enhance the grammar to allow exponentiation.  \e
! No error checking required.";
  cause = internal_enhancement;
  .E)
  .LP
! The old-faithful fred file was used again:
  .E(
! alex% \f(CBaenc fred -p example\fP
  aegis: project "example": change 3: created
  alex%
  .E)
! At some point a developer will notice,
! and this change will be worked on.
  .nh 3 "The Fourth Change"
  .LP
! A fourth change,
! this time adding variables to the calculator
! is added.
  .E(
! brief_description = "add variables";
! description = "Enhance the grammar to allow variables.  \e
! Only single letter variable names are required.";
  cause = internal_enhancement;
  .E)
  .LP
! The old-faithful fred file was used again:
  .E(
! alex% \f(CBaenc fred -p example\fP
  aegis: project "example": change 4: created
  alex%
  .E)
! At some point a developer will notice,
! and this change will be worked on.
  .nh 3 "Administrator Command Summary"
  .LP
  Only a few of the aegis commands available to administrators have
***************
*** 185,205 ****
  l l.
  Command;Description
  _
! aenpr;New Project
! aerpr;Remove Project
  aena;New Administrator
! aera;Remove Administrator
! aeni;New Integrator
! aeri;Remove Integrator
  aend;New Developer
! aerd;Remove Developer
  aenrv;New Reviewer
  aerrv;Remove Reviewer
- aenc;New Change
- aencu;New Change Undo
- aepa;Project Attributes
- aeca;Change Attributes
- ael;List Stuff
  .TE
  .LP
  You will want to read the manual entries for all of these commands.
--- 221,241 ----
  l l.
  Command;Description
  _
! aeca;set Change Attributes
! ael;List Stuff
  aena;New Administrator
! aenc;New Change
! aencu;New Change Undo
  aend;New Developer
! aeni;New Integrator
! aenpr;New Project
  aenrv;New Reviewer
+ aepa;set Project Attributes
+ aera;Remove Administrator
+ aerd;Remove Developer
+ aeri;Remove Integrator
+ aerpr;Remove Project
  aerrv;Remove Reviewer
  .TE
  .LP
  You will want to read the manual entries for all of these commands.
Index: doc/c2.5.so
***************
*** 0 ****
--- 1,47 ----
+ .\"
+ .\"	aegis - project change supervisor
+ .\"	Copyright (c) 1993 Peter Miller.
+ .\"	All rights reserved.
+ .\"
+ .\"	This program is free software; you can redistribute it and/or modify
+ .\"	it under the terms of the GNU General Public License as published by
+ .\"	the Free Software Foundation; either version 1, or (at your option)
+ .\"	any later version.
+ .\"
+ .\"	This program is distributed in the hope that it will be useful,
+ .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
+ .\"	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ .\"	GNU General Public License for more details.
+ .\"
+ .\"	You should have received a copy of the GNU General Public License
+ .\"	along with this program; if not, write to the Free Software
+ .\"	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ .\"
+ .\" MANIFEST: User Guide, The Change Development Cycle, What to do Next
+ .\"
+ .bp
+ .2C
+ .nh 2 "What to do Next"
+ .LP
+ This chapter has given a vicareous view of what using aegis feels like.
+ As a next step in getting to know aegis,
+ it would be a good idea if you created a project and
+ went through this same exercise;
+ you could use this exact example,
+ or you could use a similar small project.
+ This idea simply to run through many of the same steps as in the example.
+ Typos and other natural events will ensure that you come across
+ a number of situations not directly covered by this chapter.
+ .LP
+ If you have not already done do,
+ a printed copy of the section 1 and 5 manual entries will be invaluable.
+ If you don't want to use that many trees,
+ they will be available on-line,
+ by using the "-Help" option of the appropriate command variant.
+ Try:
+ .E(
+ % \f(CBaedb -help\fP
+ \&.\&.\&.manual entry\&.\&.\&.
+ %
+ .E)
+ .1C
Index: doc/c3.0.so
***************
*** 1,12 ****
  .\"
  .\"	aegis - project change supervisor
! .\"	Copyright (c) 1991-1992 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 1, or (at your option)
! .\"	any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  .\"
  .\"	aegis - project change supervisor
! .\"	Copyright (C) 1991, 1992, 1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 2 of the License, or
! .\"	(at your option) any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 56,63 ****
  .TS
  tab(;);
  l l.
! %1;source file
! %2;history file
  .TE
  .DE
  .nh 3 "history_get_command"
--- 56,63 ----
  .TS
  tab(;);
  l l.
! ${Input};source file
! ${History};history file
  .TE
  .DE
  .nh 3 "history_get_command"
***************
*** 69,77 ****
  .TS
  tab(;);
  l l.
! %1;history file
! %2;edit number
! %3;destination file
  .TE
  .DE
  .nh 3 "history_put_command"
--- 69,77 ----
  .TS
  tab(;);
  l l.
! ${History};history file
! ${Edit};edit number
! ${Output};destination file
  .TE
  .DE
  .nh 3 "history_put_command"
***************
*** 83,96 ****
  .TS
  tab(;);
  l l.
! %1;source file
! %2;history file
  .TE
  .DE
  .nh 3 "history_query_command"
  .LP
  This field is used to query the topmost edit of a history file.
! Result to be printed on stdout.
  This command may be executed by developers.
  Substitutions available for the command string are:
  .DS
--- 83,96 ----
  .TS
  tab(;);
  l l.
! ${Input};source file
! ${History};history file
  .TE
  .DE
  .nh 3 "history_query_command"
  .LP
  This field is used to query the topmost edit of a history file.
! Result to be printed on the standard output.
  This command may be executed by developers.
  Substitutions available for the command string are:
  .DS
***************
*** 97,103 ****
  .TS
  tab(;);
  l l.
! %1;history file
  .TE
  .DE
  .so c3.1.so
--- 97,103 ----
  .TS
  tab(;);
  l l.
! ${History};history file
  .TE
  .DE
  .so c3.1.so
Index: doc/c3.1.so
***************
*** 1,12 ****
  .\"
  .\"	aegis - project change supervisor
! .\"	Copyright (c) 1991-1992 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 1, or (at your option)
! .\"	any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  .\"
  .\"	aegis - project change supervisor
! .\"	Copyright (C) 1991, 1992, 1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 2 of the License, or
! .\"	(at your option) any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 47,54 ****
  .TS
  tab(;);
  l l.
! %1;absolute path of the source file
! %2;absolute path of the history file
  .TE
  .DE
  .LP
--- 47,54 ----
  .TS
  tab(;);
  l l.
! ${Input};absolute path of the source file
! ${History};absolute path of the history file
  .TE
  .DE
  .LP
***************
*** 57,65 ****
  file looks like this:
  .E(
  history_create_command =
! 	"admin -n -i%1 -y %P2/s.%F2; \e
! 	admin -di %P2/s.%F2; \e
! 	get -e -t -p -s %P2/s.%F2 > /dev/null";
  .E)
  .LP
  Note that the "get -e" is necessary to put the s.file into the edit state,
--- 57,65 ----
  file looks like this:
  .E(
  history_create_command =
! 	"admin -n -i$i -y ${d $h}/s.${b $h}; \e
! 	admin -di ${d $h}/s.${b $h}; \e
! 	get -e -t -p -s ${d $h}/s.${b $h} > /dev/null";
  .E)
  .LP
  Note that the "get -e" is necessary to put the s.file into the edit state,
***************
*** 75,83 ****
  .TS
  tab(;);
  l l.
! %1;absolute path of the history file
! %2;edit number, as given by history_query_command
! %3;absolute path of the destination file
  .TE
  .DE
  .LP
--- 75,83 ----
  .TS
  tab(;);
  l l.
! ${History};absolute path of the history file
! ${Edit};edit number, as given by history_query_command
! ${Output};absolute path of the destination file
  .TE
  .DE
  .LP
***************
*** 86,92 ****
  file looks like this:
  .E(
  history_get_command =
! 	"get -r'%2' -s -p -k %P1/s.%F1 > %3";
  .E)
  .nh 3 "history_put_command"
  .LP
--- 86,92 ----
  file looks like this:
  .E(
  history_get_command =
! 	"get -r'$e' -s -p -k ${d $h}/s.${b $h} > $o";
  .E)
  .nh 3 "history_put_command"
  .LP
***************
*** 99,106 ****
  .TS
  tab(;);
  l l.
! %1;absolute path of source file
! %2;absolute path of history file
  .TE
  .DE
  .LP
--- 99,106 ----
  .TS
  tab(;);
  l l.
! ${Input};absolute path of source file
! ${History};absolute path of history file
  .TE
  .DE
  .LP
***************
*** 109,117 ****
  file looks like this:
  .E(
  history_put_command =
! 	"cd %P1; \e
! 	delta -s -y %P2/s.%F2; \e
! 	get -e -t -p -s %P2/s.%F2 > %1";
  .E)
  .LP
  Note that the SCCS file is left in the edit state,
--- 109,117 ----
  file looks like this:
  .E(
  history_put_command =
! 	"cd ${d $i}; \e
! 	delta -s -y ${d $h}/s.${b $h}; \e
! 	get -e -t -p -s ${d $h}/s.${b $h} > $i";
  .E)
  .LP
  Note that the SCCS file is left in the edit state,
***************
*** 134,140 ****
  .TS
  tab(;);
  l l.
! %1;absolute path of the history file
  .TE
  .DE
  .LP
--- 134,140 ----
  .TS
  tab(;);
  l l.
! ${History};absolute path of the history file
  .TE
  .DE
  .LP
***************
*** 143,149 ****
  file looks like this:
  .E(
  history_query_command =
! 	"get -t -g %P1/s.%F1 2>&1";
  .E)
  .LP
  Note that "get" reports the edit number on stderr.
--- 143,149 ----
  file looks like this:
  .E(
  history_query_command =
! 	"get -t -g ${d $h}/s.${b $h} 2>&1";
  .E)
  .LP
  Note that "get" reports the edit number on stderr.
Index: doc/c3.2.so
***************
*** 1,12 ****
  .\"
  .\"	aegis - project change supervisor
! .\"	Copyright (c) 1991-1992 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 1, or (at your option)
! .\"	any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  .\"
  .\"	aegis - project change supervisor
! .\"	Copyright (C) 1991, 1992, 1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 2 of the License, or
! .\"	(at your option) any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 58,65 ****
  .TS
  tab(;);
  l l.
! %1;absolute path of the source file
! %2;absolute path of the history file
  .TE
  .DE
  .LP
--- 58,65 ----
  .TS
  tab(;);
  l l.
! ${Input};absolute path of the source file
! ${History};absolute path of the history file
  .TE
  .DE
  .LP
***************
*** 68,75 ****
  file looks like this:
  .E(
  history_create_command =
! 	"ci -u -t/dev/null %1 %2,v; \e
! 	rcs -U %2,v";
  .E)
  .LP
  The "ci -u" is so that a copy remains in the baseline.
--- 68,75 ----
  file looks like this:
  .E(
  history_create_command =
! 	"ci -u -t/dev/null $i $h,v; \e
! 	rcs -U $h,v";
  .E)
  .LP
  The "ci -u" is so that a copy remains in the baseline.
***************
*** 84,92 ****
  .TS
  tab(;);
  l l.
! %1;absolute path of the history file
! %2;edit number, as given by history_query_command
! %3;absolute path of the destination file
  .TE
  .DE
  .LP
--- 84,92 ----
  .TS
  tab(;);
  l l.
! ${History};absolute path of the history file
! ${Edit};edit number, as given by history_query_command
! ${Output};absolute path of the destination file
  .TE
  .DE
  .LP
***************
*** 95,101 ****
  file looks like this:
  .E(
  history_get_command =
! 	"co -u'%2' -p %1,v > %3";
  .E)
  .LP
  Note that the destination filename will
--- 95,101 ----
  file looks like this:
  .E(
  history_get_command =
! 	"co -u'$e' -p $h,v > $o";
  .E)
  .LP
  Note that the destination filename will
***************
*** 113,120 ****
  .TS
  tab(;);
  l l.
! %1;absolute path of source file
! %2;absolute path of history file
  .TE
  .DE
  .LP
--- 113,120 ----
  .TS
  tab(;);
  l l.
! ${Input};absolute path of source file
! ${History};absolute path of history file
  .TE
  .DE
  .LP
***************
*** 123,129 ****
  file looks like this:
  .E(
  history_put_command =
! 	"ci -u -m/dev/null %1 %2,v";
  .E)
  .LP
  Note that the source file is left in the baseline.
--- 123,129 ----
  file looks like this:
  .E(
  history_put_command =
! 	"ci -u -m/dev/null $i $h,v";
  .E)
  .LP
  Note that the source file is left in the baseline.
***************
*** 133,143 ****
  viz:
  .E(
  history_create_command =
! 	"ci -u -m/dev/null -t/dev/null %1 %2,v; \e
! 	rcs -U %2,v";
  history_put_command =
! 	"ci -u -m/dev/null -t/dev/null %1 %2,v; \e
! 	rcs -U %2,v";
  .E)
  .nh 3 "history_query_command"
  .LP
--- 133,143 ----
  viz:
  .E(
  history_create_command =
! 	"ci -u -m/dev/null -t/dev/null $i $h,v; \e
! 	rcs -U $h,v";
  history_put_command =
! 	"ci -u -m/dev/null -t/dev/null $i $h,v; \e
! 	rcs -U $h,v";
  .E)
  .nh 3 "history_query_command"
  .LP
***************
*** 157,163 ****
  .TS
  tab(;);
  l l.
! %1;absolute path of the history file
  .TE
  .DE
  .LP
--- 157,163 ----
  .TS
  tab(;);
  l l.
! ${History};absolute path of the history file
  .TE
  .DE
  .LP
***************
*** 166,170 ****
  file looks like this:
  .E(
  history_query_command =
! 	"rlog -r %1,v | awk '/^head:/ {print $2}'";
  .E)
--- 166,170 ----
  file looks like this:
  .E(
  history_query_command =
! 	"rlog -r $h,v | awk '/^head:/ {print $$2}'";
  .E)
Index: doc/c3.3.so
***************
*** 1,12 ****
  .\"
  .\"	aegis - project change supervisor
! .\"	Copyright (c) 1991-1992 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 1, or (at your option)
! .\"	any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  .\"
  .\"	aegis - project change supervisor
! .\"	Copyright (C) 1991, 1992, 1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 2 of the License, or
! .\"	(at your option) any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 37,44 ****
  .TS
  tab(;);
  l l.
! %1;absolute path of the source file
! %2;absolute path of the history file
  .TE
  .DE
  .LP
--- 37,44 ----
  .TS
  tab(;);
  l l.
! ${Input};absolute path of the source file
! ${History};absolute path of the history file
  .TE
  .DE
  .LP
***************
*** 47,53 ****
  file looks like this:
  .E(
  history_create_command =
! 	"fhist %F2 -create -i %1 -p %P2 -r";
  .E)
  .nh 3 "history_get_command"
  .LP
--- 47,53 ----
  file looks like this:
  .E(
  history_create_command =
! 	"fhist ${b $i} -create -i $i -p ${d $h} -r";
  .E)
  .nh 3 "history_get_command"
  .LP
***************
*** 59,67 ****
  .TS
  tab(;);
  l l.
! %1;absolute path of the history file
! %2;edit number, as given by history_query_command
! %3;absolute path of the destination file
  .TE
  .DE
  .LP
--- 59,67 ----
  .TS
  tab(;);
  l l.
! ${History};absolute path of the history file
! ${Edit};edit number, as given by history_query_command
! ${Output};absolute path of the destination file
  .TE
  .DE
  .LP
***************
*** 70,76 ****
  file looks like this:
  .E(
  history_get_command =
! 	"fhist %F1 -e '%2' -o %3 -p %P1";
  .E)
  .LP
  Note that the destination filename will
--- 70,76 ----
  file looks like this:
  .E(
  history_get_command =
! 	"fhist ${b $h} -e '$e' -o $o -p ${d $h}";
  .E)
  .LP
  Note that the destination filename will
***************
*** 88,95 ****
  .TS
  tab(;);
  l l.
! %1;absolute path of source file
! %2;absolute path of history file
  .TE
  .DE
  .LP
--- 88,95 ----
  .TS
  tab(;);
  l l.
! ${Input};absolute path of source file
! ${History};absolute path of history file
  .TE
  .DE
  .LP
***************
*** 98,104 ****
  file looks like this:
  .E(
  history_put_command =
! 	"fhist %F2 -u -i %1 -p %P2 -r";
  .E)
  .LP
  Note that the source file is left in the baseline.
--- 98,104 ----
  file looks like this:
  .E(
  history_put_command =
! 	"fhist ${b $i} -u -i $i -p ${d $h} -r";
  .E)
  .LP
  Note that the source file is left in the baseline.
***************
*** 121,127 ****
  .TS
  tab(;);
  l l.
! %1;absolute path of the history file
  .TE
  .DE
  .LP
--- 121,127 ----
  .TS
  tab(;);
  l l.
! ${History};absolute path of the history file
  .TE
  .DE
  .LP
***************
*** 130,134 ****
  file looks like this:
  .E(
  history_query_command =
! 	"fhist %F1 -l 0 -p %P1 -q";
  .E)
--- 130,134 ----
  file looks like this:
  .E(
  history_query_command =
! 	"fhist ${b $h} -l 0 -p ${d $h} -q";
  .E)
Index: doc/c4.0.so
***************
*** 1,12 ****
  .\"
  .\"	aegis - project change supervisor
! .\"	Copyright (c) 1991-1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 1, or (at your option)
! .\"	any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  .\"
  .\"	aegis - project change supervisor
! .\"	Copyright (C) 1991, 1992, 1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 2 of the License, or
! .\"	(at your option) any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
Index: doc/c4.1.so
***************
*** 1,12 ****
  .\"
  .\"	aegis - project change supervisor
! .\"	Copyright (c) 1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 1, or (at your option)
! .\"	any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  .\"
  .\"	aegis - project change supervisor
! .\"	Copyright (C) 1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 2 of the License, or
! .\"	(at your option) any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
Index: doc/c4.2.so
***************
*** 1,12 ****
  .\"
  .\"	aegis - project change supervisor
! .\"	Copyright (c) 1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 1, or (at your option)
! .\"	any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  .\"
  .\"	aegis - project change supervisor
! .\"	Copyright (C) 1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 2 of the License, or
! .\"	(at your option) any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 65,78 ****
  In this case, it is set as follows
  .E(
  build_command =
! 	"cook -b %(Howto.cook) project=%1 change=%2 version=%3 -nl";
  .E)
  .LP
  This command tells cook
  where to find the recipes.
! The \f(CW%(Howto.cook)\fR expands to a path into the baseline
  during development
  if the file is not in the change.
  .LP
  The recipes which follow will all remove their targets before constructing
  them, which qualifies them for the next entry in the
--- 65,81 ----
  In this case, it is set as follows
  .E(
  build_command =
! 	"cook -b ${s Howto.cook} project=$p change=$c version=$v -nl";
  .E)
  .LP
  This command tells cook
  where to find the recipes.
! The \f(CW${s Howto.cook}\fR expands to a path into the baseline
  during development
  if the file is not in the change.
+ Look in
+ .I aesub (5)
+ for more information about command substitutions.
  .LP
  The recipes which follow will all remove their targets before constructing
  them, which qualifies them for the next entry in the
Index: doc/c4.3.so
***************
*** 1,12 ****
  .\"
  .\"	aegis - project change supervisor
! .\"	Copyright (c) 1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 1, or (at your option)
! .\"	any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  .\"
  .\"	aegis - project change supervisor
! .\"	Copyright (C) 1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 2 of the License, or
! .\"	(at your option) any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
Index: doc/c5.0.so
***************
*** 1,12 ****
  .\"
  .\"	aegis - project change supervisor
! .\"	Copyright (c) 1991-1992 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 1, or (at your option)
! .\"	any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  .\"
  .\"	aegis - project change supervisor
! .\"	Copyright (C) 1991, 1992, 1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 2 of the License, or
! .\"	(at your option) any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 17,56 ****
  .\"	along with this program; if not, write to the Free Software
  .\"	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  .\"
! .\" MANIFEST: User Guide, The Project Configuration File
  .\"
  .bp
! .nh 1 "The Project Configuration File"
  .LP
! Some of the project configuration file,
! .I config ,
! has already been discussed in the 
! preceeding chapters.
! This file is part of the beaseline and is subject to the
! same change controls as any other source file.
  .LP
  The
! .I config
! file breaks into several sections.
  .LP
! \(bu The build commands and options.
! These are discussed in the
! .I "Dependency Maintenence Tool"
! chapter.
  .LP
! \(bu The history commands.
! These are discussed in the
! .I "History Tool"
! chapter.
  .LP
! \(bu New File Templates.
! These are discussed later in this chapter.
  .LP
! \(bu The difference commands.
! These are discussed later in this chapter.
! .nh 2 "New File Templates"
  .LP
! Write this section.
! .nh 2 "The Difference Commands"
  .LP
! Write this section.
--- 17,312 ----
  .\"	along with this program; if not, write to the Free Software
  .\"	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  .\"
! .\" MANIFEST: User Guide, The Project Attributes
  .\"
  .bp
! .1C
! .nh 1 "The Project Attributes"
  .LP
! The project attributes are manipulated using the
! .I aepa (1)
! command.
! This command reads a project attributes file to set the project attributes.
! This file can be thought of as having several sections,
! each of which will be covered by this chapter.
! You should see the
! .I aepattr (50
! manual entry for more details.
! .nh 2 "Description and Access"
  .LP
  The
! .I description
! field is a string which contains
! a description of the project.
! Large amounts of prose are not required;
! a single line is sufficient.
  .LP
! The
! .I default_development_directory
! field is a string which contains
! the pathname of where to place new development directories.
! The pathname must be absolute.
! This field is only
! consulted if the
! .I uconf (5)
! field of the same name is not set.
! Defaults to
! .I $HOME .
  .LP
! The
! .I umask
! field is an integer which is set to the
! file permission mode mask.
! See
! .I umask (2)
! for more information.
! This value will always be OR'ed with 022,
! because aegis is paranoid.
! .nh 2 "Notification Commands"
! .LP
! The
! .I develop_end_notify_command
! field is a string which contains a command to be used to
! notify that a change requires reviewing.
! All of the substitutions described in
! .I aesub (5)
! are available.
! This field is optional, if it is not specified no notification will be issued.
! This command could also be used to notify other management systems,
! such as progress and defect tracking,
! in addition to notifying users.
! .LP
! The
! .I develop_end_undo_notify_command
! field is a string containing a command used to
! notify that a change has been withdrawn from review
! for further development.
! All of the substitutions described in
! .I aesub (5)
! are available.
! This field is optional, if it is not specified no notification will be issued.
! This command could also be used to notify other management systems,
! such as progress and defect tracking,
! in addition to notifying users.
! .LP
! The
! .I review_pass_notify_command
! field is a string containing the command to
! notify that the review has passed.
! All of the substitutions described in
! .I aesub (5)
! are available.
! This field is optional, if it is not specified no notification will be issued.
! This command could also be used to notify other management systems,
! such as progress and defect tracking,
! in addition to notifying users.
! .LP
! The
! .I review_pass_undo_notify_command
! field is a string comtaining the command to
! notify that a review pass has has been rescinded.
! All of the substitutions described in
! .I aesub (5)
! are available.
! This field is optional, and defaults to the
! .I develop_end_notify_command
! field if not specified.
! If neither is specified, no notification will be issued.
! This command could also be used to notify other management systems,
! such as progress and defect tracking,
! in addition to notifyin users.
! .LP
! The
! .I review_fail_notify_command
! field is a string containing the command to
! notify that the review has failed.
! All of the substitutions described in
! .I aesub (5)
! are available.
! This field is optional, if it is not specified no notification will be issued.
! This command could also be used to notify other management systems,
! such as progress and defect tracking,
! in addition to notifyin users.
! .LP
! The
! .I integrate_pass_notify_command
! field is a string comtaining the command to
! notify that the integration has passed.
! All of the substitutions described in
! .I aesub (5)
! are available.
! This field is optional, if it is not specified no notification will be issued.
! This command could also be used to notify other management systems,
! such as progress and defect tracking,
! in addition to notifying users.
! .LP
! The
! .I integrate_fail_notify_command
! field is a string containg the command to
! notify that the integration has failed.
! All of the substitutions described in
! .I aesub (5)
! are available.
! This field is optional, if it is not specified no notification will be issued.
! This command could also be used to notify other management systems,
! such as progress and defect tracking,
! in addition to notifying users.
! .nh 3 "Notification by email"
! .LP
! The aegis command is distributed with a set of shell scripts to
! perform these notifications by email.
! They are installed into the
! .I /usr/local/lib/aegis
! directory.
! The entries in the project attribute file look like this:
! .E(
! develop_end_notify_command =
!         "sh /usr/local/lib/aegis/de.sh $project $change \e
!         $developer";
! develop_end_undo_notify_command =
!         "sh /usr/local/lib/aegis/deu.sh $project $change \e
!         $developer";
! review_pass_notify_command =
!         "sh /usr/local/lib/aegis/rp.sh $project $change \e
!         $developer $reviewer";
! review_pass_undo_notify_command =
!         "sh /usr/local/lib/aegis/rpu.sh $project $change \e
!         $developer $reviewer";
! review_fail_notify_command =
!         "sh /usr/local/lib/aegis/rf.sh $project $change \e
!         $developer $reviewer";
! integrate_pass_notify_command =
!         "sh /usr/local/lib/aegis/ip.sh $project $change \e
!         $developer $reviewer $integrator";
! integrate_fail_notify_command =
!         "sh /usr/local/lib/aegis/if.sh $project $change \e
!         $developer $reviewer $integrator";
! .E)
! .nh 3 "Notification by USENET"
! .LP
! The aegis command is distributed with a set of shell scripts to
! perform these notifications by USENET.
! They are installed into the
! .I /usr/local/lib/aegis
! directory.
! The entries in the project attribute file look like this:
! .E(
! develop_end_notify_command =
!         "sh /usr/local/lib/aegis/de.inews.sh $p $c alt.$p";
! develop_end_undo_notify_command =
!         "sh /usr/local/lib/aegis/deu.inews.sh $p $c alt.$p";
! review_pass_notify_command =
!         "sh /usr/local/lib/aegis/rp.inews.sh $p $c alt.$p";
! review_pass_undo_notify_command =
!         "sh /usr/local/lib/aegis/rpu.inews.sh $p $c alt.$p";
! review_fail_notify_command =
!         "sh /usr/local/lib/aegis/rf.inews.sh $p $c alt.$p";
! integrate_pass_notify_command =
!         "sh /usr/local/lib/aegis/ip.inews.sh $p $c alt.$p";
! integrate_fail_notify_command =
!         "sh /usr/local/lib/aegis/if.inews.sh $p $c alt.$p";
! .E)
! .LP
! The last argument to each command is the newsgroup to post the article in,
! you may want to use some other group.
! Note that "$p" is an abbreviation for "$project" 
! and "$c" is an abbreviation for "$change".
! .nh 2 "Exemption Controls"
! .LP
! The
! .I developer_may_review
! field is a boolean.
! If this field is true,
! then a developer may review her own change.
! This is probably only a good idea for projects of less than 3 people.
! The idea is for as many people as possible to critically examine a change.
! .LP
! The
! .I developer_may_integrate
! field is a boolean.
! If this field is true,
! then a developer may integrate her own change.
! This is probably only a good idea for projects of less than 3 people.
! The idea is for as many people as possible to critically examine a change.
! .LP
! The
! .I reviewer_may_integrate
! field is a boolean.
! If this field is true,
! then a reviewer may integrate a change she reviewed.
! This is probably only a good idea for projects of less than 3 people.
! The idea is for as many people as possible to critically examine a change.
! .LP
! The
! .I developers_may_create_changes
! field is a boolean.
! This field is true if developers may created changes,
! in addition to administrators.
! This tends to be a very useful thing,
! since developers find most of the bugs.
  .LP
! The
! .I default_test_exemption
! field is a booean.
! This field contains what to do when a change is created with
! no test exemption specified.
! The default is "false", i.e. no testing exemption,
! tests must be provided.
  .LP
! This kind of blanket exemption should only be set when
! a project has absolutely no functionality available from the command line;
! examples include X11 programs.
! The program could possibly be improved by providing access to
! the functionality from the command line,
! thus allowing tests to be written.
! .nh 3 "One Person Projects"
  .LP
! The entries in the project attributes file for a
! one person project look like this:
! .E(
! developer_may_review = true;
! developer_may_integrate = true;
! reviewer_may_integrate = true;
! developers_may_create_changes = true;
! .E)
  .LP
! All of the staff roles
! (administrator, developer, reviewer and integertor)
! are all set to be the same user.
! .nh 3 "Two Person Projects"
! .LP
! A two person project has the opprotunity for each to review the other's work.
! .LP
! The entries in the project attributes file for a
! one person project look like this:
! .E(
! developer_may_review = false.
! developer_may_integrate = true;
! reviewer_may_integrate = true;
! developers_may_create_changes = true;
! .E)
! .LP
! All of the staff roles
! (developer, reviewer and integertor)
! are all set to allow both users.
! .nh 3 "Larger Projects"
! .LP
! Once you have 3 or more staff on a project,
! you can assign all of the rolews to separate people.
! The idea is for the greatest number of eyes to see each change
! and detect falus before they reach the baseline.
! .LP
! The entries in the project attributes file for a
! one person project look like this:
! .E(
! developer_may_review = false.
! developer_may_integrate = false;
! reviewer_may_integrate = false;
! developers_may_create_changes = true;
! .E)
! .LP
! For smaller teams,
! everyone may be a developer.
! As the teams get larger,
! the more experienced staff are often the reviewers,
! rather than everyone.
Index: doc/c6.0.so
***************
*** 1,12 ****
  .\"
  .\"	aegis - project change supervisor
! .\"	Copyright (c) 1991-1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 1, or (at your option)
! .\"	any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  .\"
  .\"	aegis - project change supervisor
! .\"	Copyright (C) 1991, 1992, 1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 2 of the License, or
! .\"	(at your option) any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 278,284 ****
  are obtained by appending a line of the form
  .E(
  .ps -3
! source /usr/local/lib/aegis/dot.cshrc
  .ps +3
  .E)
  to the
--- 278,284 ----
  are obtained by appending a line of the form
  .E(
  .ps -3
! source /usr/local/lib/aegis/cshrc
  .ps +3
  .E)
  to the
Index: doc/c7.0.so
***************
*** 1,12 ****
  .\"
  .\"	aegis - project change supervisor
! .\"	Copyright (c) 1991-1992 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 1, or (at your option)
! .\"	any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  .\"
  .\"	aegis - project change supervisor
! .\"	Copyright (C) 1991, 1992, 1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 2 of the License, or
! .\"	(at your option) any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
Index: doc/c7.1.so
***************
*** 1,12 ****
  .\"
  .\"	aegis - project change supervisor
! .\"	Copyright (c) 1991-1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 1, or (at your option)
! .\"	any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  .\"
  .\"	aegis - project change supervisor
! .\"	Copyright (C) 1991, 1992, 1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 2 of the License, or
! .\"	(at your option) any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 315,327 ****
  simultaneously.
  If any one of them is already locked,
  you can't leave the
! .I being_developed
  state,
  because the file is part of a change which is somewhere
  between
! .I being_reviewed
  and
! .I being_integrated .
  .LP
  If any one of them is out-of-date with respect to the baseline,
  the lock is not taken,
--- 315,327 ----
  simultaneously.
  If any one of them is already locked,
  you can't leave the
! .I "being developed"
  state,
  because the file is part of a change which is somewhere
  between
! .I "being reviewed"
  and
! .I "being integrated" .
  .LP
  If any one of them is out-of-date with respect to the baseline,
  the lock is not taken,
***************
*** 432,442 ****
  A change may fail an integration because it fails to build or fails tests,
  and also just because the integrator says so.
  This allows the
! .I being_integrated
  state to be another review state,
  if desired.
  The
! .I being_integrated
  state is also the place to monitor the quality
  of reviews and reviewers.
  .LP
--- 432,442 ----
  A change may fail an integration because it fails to build or fails tests,
  and also just because the integrator says so.
  This allows the
! .I "being integrated"
  state to be another review state,
  if desired.
  The
! .I "being integrated"
  state is also the place to monitor the quality
  of reviews and reviewers.
  .LP
***************
*** 686,692 ****
  .nh 4 "New Change Undo"
  .LP
  It is possible to abandon a change if it is in the
! .I awaiting_development
  state.
  All record of the change,
  including its description,
--- 686,692 ----
  .nh 4 "New Change Undo"
  .LP
  It is possible to abandon a change if it is in the
! .I "awaiting development"
  state.
  All record of the change,
  including its description,
***************
*** 824,832 ****
  to allow further work on a change.
  No reason need be given.
  This request may be issued to a change in either the
! .I being_reviewed
  or
! .I awaiting_integration
  states.
  .nh 4 "Review Pass"
  .LP
--- 824,832 ----
  to allow further work on a change.
  No reason need be given.
  This request may be issued to a change in either the
! .I "being reviewed"
  or
! .I "awaiting integration"
  states.
  .nh 4 "Review Pass"
  .LP
***************
*** 838,848 ****
  The reviewer of a change may rescind a
  .I "Review Pass"
  while the change remains in the
! .I awaiting_integration
  state.
  No reason must be supplied.
  The change will be returned to the
! .I being_reviewed
  state.
  .nh 4 "Review Fail"
  .LP
--- 838,848 ----
  The reviewer of a change may rescind a
  .I "Review Pass"
  while the change remains in the
! .I "awaiting integration"
  state.
  No reason must be supplied.
  The change will be returned to the
! .I "being reviewed"
  state.
  .nh 4 "Review Fail"
  .LP
***************
*** 854,860 ****
  and will be included in the change's history.
  .LP
  The change will be returned to the
! .I being_developed
  state for further work.
  .LP
  It is not the responsibility of any reviewer to fix a defective change.
--- 854,860 ----
  and will be included in the change's history.
  .LP
  The change will be returned to the
! .I "being developed"
  state for further work.
  .LP
  It is not the responsibility of any reviewer to fix a defective change.
***************
*** 900,906 ****
  and the summary will be included in the change's history.
  .LP
  The change will be returned to the
! .I being_developed
  state for further work.
  The integration copy of the baseline is deleted,
  leaving the original baseline unchanged.
--- 900,906 ----
  and the summary will be included in the change's history.
  .LP
  The change will be returned to the
! .I "being developed"
  state for further work.
  The integration copy of the baseline is deleted,
  leaving the original baseline unchanged.
Index: doc/c7.2.so
***************
*** 1,12 ****
  .\"
  .\"	aegis - project change supervisor
! .\"	Copyright (c) 1991-1992 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 1, or (at your option)
! .\"	any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  .\"
  .\"	aegis - project change supervisor
! .\"	Copyright (C) 1991, 1992, 1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 2 of the License, or
! .\"	(at your option) any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
Index: doc/c7.4.so
***************
*** 1,12 ****
  .\"
  .\"	aegis - project change supervisor
! .\"	Copyright (c) 1992 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 1, or (at your option)
! .\"	any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  .\"
  .\"	aegis - project change supervisor
! .\"	Copyright (C) 1992, 1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 2 of the License, or
! .\"	(at your option) any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 82,84 ****
--- 82,158 ----
  While there is freeware C code coverage tool available,
  based on GNU C,
  the interfacing and semantics still need more thought.
+ .nh 3 "Branching"
+ .LP
+ The aegis program does not provide support for branching
+ in the history files.
+ The semantics of the baseline,
+ the source files and their closure,
+ would appear to imply that a baseline is required for every leaf
+ in the history tree.
+ .LP
+ Branching is provided in this way with the
+ .I "new release"
+ functionality.
+ An entire new project is derived from an existing project,
+ including another baseline.
+ The history,
+ however,
+ is severed from the original project,
+ precluding automatic merging by aegis at a later date.
+ It also precludes haveing a single change to be applied
+ to more than one branch.
+ .LP
+ Should better semantics become available,
+ or a better algorithmic approach,
+ this is certainly one area of aegis which could be improved.
+ .nh 3 "Virtual File System"
+ .LP
+ There is almost sufficient information in the aegis data base to create a virtual file system,
+ overlaying the development directory atop the baseline\**.
+ .FS
+ Reminiscent of Sun's TFS,
+ but not the same.
+ .FE
+ This could be implemented similarly to automounters,
+ intercepting file system operations by pretending to be an NFS server.
+ Many commercial CASE products provide such a facility.
+ .LP
+ Such a virtual file system has a number of advantages:
+ you don't need such a capable DMT, for starters;
+ it only needs the dynamic include dependencies,
+ and does not need a search path\**.
+ .FS
+ Discussed in the
+ .I "Dependency Maintenance Tool"
+ chapter.
+ .FE
+ Second,
+ many horrible and dumb compilers,
+ notably FORTRAN and "fourth" GLs,
+ don't have adequate include semantics;
+ overlaying the two directories make this much easier to deal with\**.
+ .FS
+ There are other ways,
+ discussed in the
+ .I "Tips and Traps"
+ chapter.
+ .FE
+ Many graphical tools,
+ such as bubble chart drawers, etc,
+ when they do actually have include files,
+ have no command line specifiable search path.
+ .LP
+ The disadvantage is that this adds significant complexity
+ to an already large program.
+ Also,
+ implementation is limited to NFS capable systems,
+ or would have to be rewritten for a variety of other systems.
+ The semantics of interactions between the daemon and other aegis
+ commands, while clearly specifiable, are challenging to implement.
+ Performance could also be a significant factor.
+ .LP
+ The question is "is it really necessary?"
+ If the job can be done without it,
+ does the effort of writing such a beast result
+ in significant productivity gains?
Index: doc/c7.5.so
***************
*** 1,12 ****
  .\"
  .\"	aegis - project change supervisor
! .\"	Copyright (c) 1992 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 1, or (at your option)
! .\"	any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  .\"
  .\"	aegis - project change supervisor
! .\"	Copyright (C) 1992, 1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 2 of the License, or
! .\"	(at your option) any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
Index: doc/c8.0.so
***************
*** 0 ****
--- 1,34 ----
+ .\"
+ .\"	aegis - project change supervisor
+ .\"	Copyright (C) 1993 Peter Miller.
+ .\"	All rights reserved.
+ .\"
+ .\"	This program is free software; you can redistribute it and/or modify
+ .\"	it under the terms of the GNU General Public License as published by
+ .\"	the Free Software Foundation; either version 2 of the License, or
+ .\"	(at your option) any later version.
+ .\"
+ .\"	This program is distributed in the hope that it will be useful,
+ .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
+ .\"	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ .\"	GNU General Public License for more details.
+ .\"
+ .\"	You should have received a copy of the GNU General Public License
+ .\"	along with this program; if not, write to the Free Software
+ .\"	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ .\"
+ .\" MANIFEST: User Guide, The Difference Tools
+ .\"
+ .bp
+ .nh 1 "The Difference Tools"
+ .LP
+ This chapter describes the difference commands in the
+ project configuation file.
+ Usually these commands are used by the 
+ .I "aegis -DIFFerence"
+ command when differencing files,
+ but they may be used to accomplish some other things.
+ .so c8.1.so
+ .1C
+ .so c8.2.so
+ .so c8.3.so
Index: doc/c8.1.so
***************
*** 0 ****
--- 1,84 ----
+ .\"
+ .\"	aegis - project change supervisor
+ .\"	Copyright (C) 1993 Peter Miller.
+ .\"	All rights reserved.
+ .\"
+ .\"	This program is free software; you can redistribute it and/or modify
+ .\"	it under the terms of the GNU General Public License as published by
+ .\"	the Free Software Foundation; either version 2 of the License, or
+ .\"	(at your option) any later version.
+ .\"
+ .\"	This program is distributed in the hope that it will be useful,
+ .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
+ .\"	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ .\"	GNU General Public License for more details.
+ .\"
+ .\"	You should have received a copy of the GNU General Public License
+ .\"	along with this program; if not, write to the Free Software
+ .\"	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ .\"
+ .\" MANIFEST: User Guide, The Difference Tools, Interfacing
+ .\"
+ .nh 2 "Interfacing"
+ .LP
+ The build commands are accessed from two fields of the
+ project configuation file (\fIconfig\fP).
+ .nh 3 "diff_command"
+ .LP
+ This command is used by
+ .I aed (1)
+ to produce a difference listing when file in the development directory
+ was originally copied from the current version in the baseline\**.
+ .FS
+ Or this is logically the case.
+ .FE
+ .LP
+ All of the command sibstitutions described in
+ .I aesub (5)
+ are available.
+ In addition, the following substitutions are also available:
+ .IP ${ORiginal}
+ The absolute path name of a file containing the version originally copied.
+ Usually in the baseline.
+ .IP ${Input}
+ The absolute path name of the edited version of the file.
+ Usually in the development directory.
+ .IP ${Output}
+ The absolute path name of the file in which to write the difference listing.
+ Usually in the development directory.
+ .LP
+ An exit status of 0 means sucessful,
+ even of the files differ (and they usually do).
+ An exit status which is non-zero means something is wrong.
+ .LP
+ The non-zero exit status may be used to overload this command
+ with extra tests,
+ such as line length limits.
+ The difference files must be produced in addition to these extra tests.
+ .nh 3 "diff3_command"
+ .LP
+ This command is used by
+ .I aed (1)
+ to produce a difference listing when file in the development directory
+ is out of date compared to the current version in the baseline.
+ .LP
+ All of the command sibstitutions described in
+ .I aesub (5)
+ are available.
+ In addition, the following substitutions are also available:
+ .IP ${ORiginal}
+ The absolute path name of a file containing the version originally copied.
+ Usually in a temporary file.
+ .IP ${Most_Recent}
+ The absolute path name of a file containing the most recent version.
+ Usually in the baseline.
+ .IP ${Input}
+ The absolute path name of the edited version of the file.
+ Usually in the development directory.
+ .IP ${Output}
+ The absolute path name of the file in which to write the difference listing.
+ Usually in the development directory.
+ .LP
+ An exit status of 0 means sucessful,
+ even of the files differ (and they usually do).
+ An exit status which is non-zero means something is wrong.
Index: doc/c8.2.so
***************
*** 0 ****
--- 1,101 ----
+ .\"
+ .\"	aegis - project change supervisor
+ .\"	Copyright (C) 1993 Peter Miller.
+ .\"	All rights reserved.
+ .\"
+ .\"	This program is free software; you can redistribute it and/or modify
+ .\"	it under the terms of the GNU General Public License as published by
+ .\"	the Free Software Foundation; either version 2 of the License, or
+ .\"	(at your option) any later version.
+ .\"
+ .\"	This program is distributed in the hope that it will be useful,
+ .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
+ .\"	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ .\"	GNU General Public License for more details.
+ .\"
+ .\"	You should have received a copy of the GNU General Public License
+ .\"	along with this program; if not, write to the Free Software
+ .\"	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ .\"
+ .\" MANIFEST: User Guide, The Difference Tools, Using diff and diff3
+ .\"
+ .bp
+ .nh 2 "Using diff and diff3"
+ .LP
+ These two tools are available with most flavours of UNIX,
+ but often in a very limited form.
+ One severe limitation is the
+ .I diff3 (1)
+ command,
+ which often can only cope with 200 lines of differences.
+ The best alternative is to use GNU diff,
+ with context differences available,
+ and a far more robust diff3.
+ .nh 3 "diff_command"
+ .LP
+ See the earlier
+ .I Interfacing
+ section for substitution details.
+ .LP
+ The entry in the
+ .I config
+ file looks like this:
+ .E(
+ diff_command =
+         "set +e; diff -c $original $input > $output; test $? -le 1";
+ .E)
+ .LP
+ This needs a little explanation:
+ .br
+ \(bu
+ This command is always executed with the shell's
+ .B -e
+ option enabled,
+ causing the shell to exit on the first error.
+ The "set +e" turns this off.
+ .br
+ \(bu
+ The
+ .I diff (1)
+ command exits with a status of 0 if the files are identical,
+ and a status of 1 if they differ.
+ Any other status means something horrible happened.
+ The "test" command is used to chnage this to the exit status aegis expects.
+ .nh 3 "diff3_command"
+ .LP
+ See the earlier
+ .I Interfacing
+ section for substitution details.
+ .LP
+ The entry in the
+ .I config
+ file looks like this:
+ .E(
+ diff3_command =
+         "(diff3 -e $MostRecent $original $input | \e
+         sed -e '/^w$$/d' -e '/^q$$/d'; echo '1,$$p' ) | \e
+         ed - $MostRecent > $output";
+ .E)
+ .LP
+ This needs a lot of explanation.
+ .br
+ \(bu
+ The
+ .I diff3 (1)
+ command is used to produce an edit script that will
+ incorporate into $MostRecent,
+ all the changes between $original and $input.
+ .br
+ \(bu
+ The
+ .I sed (1)
+ command is used to remove the "write" and "quit" commands
+ from the generated edit script.
+ .br
+ \(bu
+ The
+ .I ed (1)
+ command is used to apply the generated edit script to
+ the $MostRecent file,
+ and print the results on the standard output,
+ which are redirected into the $output file.
Index: doc/c8.3.so
***************
*** 0 ****
--- 1,78 ----
+ .\"
+ .\"	aegis - project change supervisor
+ .\"	Copyright (C) 1993 Peter Miller.
+ .\"	All rights reserved.
+ .\"
+ .\"	This program is free software; you can redistribute it and/or modify
+ .\"	it under the terms of the GNU General Public License as published by
+ .\"	the Free Software Foundation; either version 2 of the License, or
+ .\"	(at your option) any later version.
+ .\"
+ .\"	This program is distributed in the hope that it will be useful,
+ .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
+ .\"	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ .\"	GNU General Public License for more details.
+ .\"
+ .\"	You should have received a copy of the GNU General Public License
+ .\"	along with this program; if not, write to the Free Software
+ .\"	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ .\"
+ .\" MANIFEST: User Guide, The Difference Tools, Using fhist
+ .\"
+ .bp
+ .nh 2 "Using fhist"
+ .LP
+ The
+ .B fhist
+ program by David I. Bell
+ also comes with two other utilities,
+ .I fcomp
+ and
+ .I fmerge ,
+ which use the same minimal diference algorithm.
+ .nh 3 "diff_command"
+ .LP
+ See the earlier
+ .I Interfacing
+ section for substitution details.
+ .LP
+ The entry in the
+ .I config
+ file looks like this:
+ .E(
+ diff_command =
+         "fcomp -w $original $input -o $output";
+ .E)
+ .LP
+ The
+ .B -w
+ option produces an output of the entire file,
+ with insertions an deletions marked by "change bars" in the left margin.
+ This is superior to context difference,
+ as it shows the entire file as context.
+ .LP
+ For more information,
+ see the
+ .I fcomp (1)
+ manual entry.
+ .nh 3 "diff3_command"
+ .LP
+ See the earlier
+ .I Interfacing
+ section for substitution details.
+ .LP
+ The entry in the
+ .I config
+ file looks like this:
+ .E(
+ diff3_command =
+         "fmerge $original $MostRecent $input -o $output -c /dev/null";
+ .E)
+ .LP
+ The output of this command is similar to the output of the diff3_command
+ in the last section.
+ Conflicts are marked in the output.
+ For more information,
+ see the
+ .I fmerge (1)
+ manual entry.
Index: doc/cA.0.so
***************
*** 1,12 ****
  .\"
  .\"	aegis - project change supervisor
! .\"	Copyright (c) 1991-1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 1, or (at your option)
! .\"	any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  .\"
  .\"	aegis - project change supervisor
! .\"	Copyright (C) 1991, 1992, 1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 2 of the License, or
! .\"	(at your option) any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
Index: doc/cB.0.so
***************
*** 1,12 ****
  .\"
  .\"	aegis - project change supervisor
! .\"	Copyright (c) 1992-1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 1, or (at your option)
! .\"	any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  .\"
  .\"	aegis - project change supervisor
! .\"	Copyright (C) 1992, 1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 2 of the License, or
! .\"	(at your option) any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 39,53 ****
  .br
  The repository;
  where the project master source is kept.
! .IP "being_developed"
  .br
  The state a change is in
  when it is being worked on.
! .IP "being_integrated"
  .br
  The state a change is in
  when it is being integrated with the baseline.
! .IP "being_reviewed"
  .br
  The state a change is in
  after it is developed.
--- 39,53 ----
  .br
  The repository;
  where the project master source is kept.
! .IP "being developed"
  .br
  The state a change is in
  when it is being worked on.
! .IP "being integrated"
  .br
  The state a change is in
  when it is being integrated with the baseline.
! .IP "being reviewed"
  .br
  The state a change is in
  after it is developed.
***************
*** 64,78 ****
  .br
  The state a change is in
  after it has been integrated with the baseline.
! .IP "delta"
  .br
! Each time a
  .I change
! is integrated into the
  .I baseline
  a unique number is assigned.
! .IP "delta number"
! .br
  .IP "dependency maintenance tool"
  .br
  A program or programs external to aegis which may be given a set of rules
--- 64,82 ----
  .br
  The state a change is in
  after it has been integrated with the baseline.
! .IP "delta number"
  .br
! Each time the
! .I aeib (1)
! command is used to start intgrating a
  .I change
! into the
  .I baseline
  a unique number is assigned.
! This number is the delta number.
! This allows ascending version numbers to be generated for the baseline,
! independent of change numbers, which are inevitably
! integrated in a different order to their creation.
  .IP "dependency maintenance tool"
  .br
  A program or programs external to aegis which may be given a set of rules
***************
*** 83,122 ****
--- 87,205 ----
  Abbreviation of Dependency Maintenance Tool.
  .IP "develop_begin"
  .br
+ The command issued to take a change from the
+ .I "awaiting development"
+ state to the
+ .I "being developed"
+ state.
+ The change will be assigned to the user who executed the command.
  .IP "develop_begin_undo"
  .br
+ The command issued to take a change from the
+ .I "being developed"
+ state to the
+ .I "awaiting development"
+ state.
+ The change must have no files associated with it.
  .IP "develop_end"
  .br
+ The command issued to take a change from the
+ .I "being developed"
+ state to the
+ .I "being reviewed"
+ state.
+ The change must be know to build and test sucessfully.
  .IP "develop_end_undo"
  .br
+ The command issued to take a change from the
+ .I "being reviewed"
+ state back to the
+ .I "being developed"
+ state.
+ The command must be executed by the original developer.
  .IP "developer"
  .br
+ A member of staff allowed to develop changes.
  .IP "development directory"
  .br
+ Each change is given a unique development directory
+ in which to edit files and build and test.
  .IP "history tool"
  .br
+ A program to save and restore previous versions of a file,
+ usually by storing edits between the versions for efficiency.
  .IP "integerate_pass"
  .br
+ The command used to take a change from the
+ .I "being integrated"
+ state to the
+ .I "completed"
+ state.
+ The change must be known to build and test successfully.
  .IP "integrate_begin"
  .br
+ The command used to take a change from the
+ .I "awaiting integration"
+ state to the
+ .I "being integrated"
+ state.
  .IP "integrate_begin_undo"
  .br
+ The command used to take a change from the
+ .I "being integrated"
+ state to the
+ .I "awaiting integration"
+ state.
  .IP "integrate_fail"
  .br
+ The command used to take a change from the
+ .I "being integrated"
+ state back to the
+ .I "being developed"
+ state.
  .IP "integration"
  .br
+ The process of merging the
+ .I baseline
+ with the
+ .I "development directory"
+ to form a new baseline.
+ This includes building and testing the merged directory,
+ before replacing the original
+ .I baseline
+ with the new merged version.
  .IP "integration directory"
  .br
+ The directory used during
+ .I integration
+ to merge the existing
+ .I baseline
+ with a chage's
+ .I "development directory" .
  .IP "integrator"
  .br
+ A staff member who performs
+ .I integration s.
  .IP "new_change"
  .br
+ The command uased to create new changes.
  .IP "new_change_undo"
  .br
+ The command used to destroy changes.
  .IP "review_fail"
  .br
+ The command used to take a change from the
+ .I "being reviewed"
+ state back to the
+ .I "bein developed"
+ state.
  .IP "review_pass"
  .br
+ The command used to take a change from the
+ .I "being reviewed"
+ state to the
+ .I "awaiting integration"
+ state.
  .IP "reviewer"
  .br
  A person who may review
***************
*** 128,140 ****
  Each
  .I change
  is in one of six states:
! .I awaiting_development ,
! .I being_developed ,
! .I being_reviewed ,
! .I awaiting_integration ,
! .I being_integrated
  or
! .I completed .
  .IP "state transition"
  .br
  The event resulting in a
--- 211,223 ----
  Each
  .I change
  is in one of six states:
! .I "awaiting development" ,
! .I "being developed" ,
! .I "being reviewed" ,
! .I "awaiting integration" ,
! .I "being integrated"
  or
! .I "completed" .
  .IP "state transition"
  .br
  The event resulting in a
Index: doc/cC.0.so
***************
*** 0 ****
--- 1,138 ----
+ .\"
+ .\"	aegis - project change supervisor
+ .\"	Copyright (C) 1993 Peter Miller.
+ .\"	All rights reserved.
+ .\"
+ .\"	This program is free software; you can redistribute it and/or modify
+ .\"	it under the terms of the GNU General Public License as published by
+ .\"	the Free Software Foundation; either version 2 of the License, or
+ .\"	(at your option) any later version.
+ .\"
+ .\"	This program is distributed in the hope that it will be useful,
+ .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
+ .\"	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ .\"	GNU General Public License for more details.
+ .\"
+ .\"	You should have received a copy of the GNU General Public License
+ .\"	along with this program; if not, write to the Free Software
+ .\"	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ .\"
+ .\" MANIFEST: User Guide, Appendix C, Product Comparisons
+ .\"
+ .bp
+ .2C
+ .nh 1 "Appendix C: Product Comparisons"
+ .LP
+ This appendix compares the aegis program with other pieces of software.
+ Only a few work in the same area as the aegis program,
+ or a commonly compared to the aegis program.
+ .nh 2 "CVS"
+ .LP
+ A comparison with CVS (Concurrent Version System) is frequently requested.
+ .LP
+ A fast comparison can be made by saying that
+ .I "CVS is over RCS"
+ and that
+ .I "aegis is over RCS and make."
+ This is a very simplistic view,
+ but it illustrates the fact that aegis has a wider scope than make.
+ While CVS covers a subset of the functionality covered by aegis,
+ it natuarally does that subset better.
+ .LP
+ The model used by aegis has a baseline
+ .I and
+ a repository.
+ The baseline is all of the most up to date source file
+ .B plus
+ all the implications flowing from those source files,
+ such as object files and executable programs or libraries.
+ This means there is always an "official" executable present,
+ representing the progress made by the project at that very instant.
+ These source files are available for linking or inclusion,
+ the object files available for linking,
+ at no extra effort for the developers.
+ .LP
+ The reporitory is only for history,
+ using the aegis model.  It is used to store everything that has happened,
+ so that developers may receraete earlier version when fixing bugs,
+ and aegis may use it for some other purposes.
+ .LP
+ CVS provides the repository functionality well.
+ It provides branching nicely,
+ and it has symbolic file sets.
+ While is does not provide a baseline,
+ it does not prevent a project implementing it in some other fashion.
+ .LP
+ The existence of the baseline for aegis is what limits branching.
+ The semantics of branching in the repository would appear to imply
+ that a (logically) separate baseline is required for each leaf in
+ the history tree.
+ This is why aegis only provides branching without the possibility of merging,
+ by deriving a whole new project from an existing one;
+ thus creating a whole new baseline as well.
+ Should a better set of semantics be made aparrent,
+ this is certainly an area for improvement.
+ .LP
+ Another aspect of Software Configuration Management (SCM) is
+ consistency checking.
+ For example,
+ if two developers are working on two (logically) separate changes,
+ which both need to alter the same file,
+ one of them will inevitably return it to the baseline first,
+ and the other will then be working on an out of date copy.
+ Both aegis is CVS provide a conflict resolution mechanism to handle this;
+ the same algorithm is used by both,
+ although implemented a little differently in each case.
+ .LP
+ There is a second aspect to consistency checking required by SCM;
+ it is important that a change does not "break" the project,
+ and it is thus important that all the source files in the project
+ agree with each other.
+ For example,
+ if a developer alters an include file as part of a change,
+ and the portion of this include file describing a function
+ prototype is changed,
+ it is essential that all of the clients of that function be recompiled,
+ to ensure that they are still compatible with that prototype,
+ and may need to be included with the change to update their use of
+ the function.
+ Similarly,
+ the definition of the function needs to be recompiled,
+ to ensure that it, too, agrees with the prototype,
+ and have the interface and 9implementation changed to agree with it.
+ This type of consistency checking is provided by aegis,
+ but not bu CVS;
+ although CVS does not prevent a project implementing this in a different way.
+ .LP
+ Another aspect of SCM provided by aegis is validation.
+ The aegis program insists that changes be accompanied by tests.
+ This allows greater confidence that a change actually works,
+ and the accumulation of such tests provides a regression test suite to verify
+ that later changes do not "break" the functionality provided by this one.
+ The aegis program also insists that each change be reviewed;
+ by whom is configurable.
+ While testing is not a silver bullet,
+ and neither is peer review,
+ both are vital components producing quality software.
+ CVS does not provide validation functionality;
+ althoug it does not prevent a project from implementing this in some other way.
+ .LP
+ The CVS program aims to provide the repository function for SCM,
+ and it does this well.
+ The
+ aegis program aims to provide a baseline,
+ to provide a reporitory,
+ to provide baseline consistency, and
+ to provide baseline change validation.
+ There are situations where one is more suited,
+ and the other less, and vice versa.
+ The tools selected for a project,
+ from Gandt charts to assemblers,
+ must be chosen for their "fit" with each individuat project.
+ .PP
+ Another point to note is that CVS requires RCS;
+ whereas aegis may be configured to use almost any history tool.
+ If SCCS is bundled with your operating system,
+ or your company has its own history tool,
+ aegis can be configured to use that, instead.
+ .1C
Index: fmtgen/id.c
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 32,41 ****
  
  
  #define HEADER \
! 	string_t	*id_name; \
! 	hash_t		id_hash; \
  	id		*id_next; \
! 	id_class_t	id_class;
  
  typedef struct id id;
  struct id
--- 32,41 ----
  
  
  #define HEADER \
! 	string_ty	*id_name; \
! 	str_hash_ty	id_hash; \
  	id		*id_next; \
! 	id_class_ty	id_class;
  
  typedef struct id id;
  struct id
***************
*** 57,69 ****
  	void		*id_value;
  };
  
! static	id	**hash_table;
! static	hash_t	hash_modulus;
! static	hash_t	hash_cutover;
! static	hash_t	hash_cutover_mask;
! static	hash_t	hash_cutover_split_mask;
! static	hash_t	hash_split;
! static	hash_t	hash_load;
  
  
  /*
--- 57,69 ----
  	void		*id_value;
  };
  
! static	id		**hash_table;
! static	str_hash_ty	hash_modulus;
! static	str_hash_ty	hash_cutover;
! static	str_hash_ty	hash_cutover_mask;
! static	str_hash_ty	hash_cutover_split_mask;
! static	str_hash_ty	hash_split;
! static	str_hash_ty	hash_load;
  
  
  /*
***************
*** 83,89 ****
  void
  id_initialize()
  {
! 	hash_t j;
  
  	hash_modulus = 1<<8; /* MUST be a power of 2 */
  	hash_cutover = hash_modulus;
--- 83,89 ----
  void
  id_initialize()
  {
! 	str_hash_ty	j;
  
  	hash_modulus = 1<<8; /* MUST be a power of 2 */
  	hash_cutover = hash_modulus;
***************
*** 119,128 ****
  static void
  split()
  {
! 	id	*p;
! 	id	**ipp;
! 	id	*p2;
! 	hash_t	index;
  
  	/*
  	 * get the list to be split across buckets 
--- 119,128 ----
  static void
  split()
  {
! 	id		*p;
! 	id		**ipp;
! 	id		*p2;
! 	str_hash_ty	index;
  
  	/*
  	 * get the list to be split across buckets 
***************
*** 217,223 ****
   *	id_search - search for a variable
   *
   * SYNOPSIS
!  *	int id_search(string_t *name, id_class_t class, long *value);
   *
   * DESCRIPTION
   *	Id_search is used to reference a variable.
--- 217,223 ----
   *	id_search - search for a variable
   *
   * SYNOPSIS
!  *	int id_search(string_ty *name, id_class_ty class, long *value);
   *
   * DESCRIPTION
   *	Id_search is used to reference a variable.
***************
*** 238,249 ****
  /*VARARGS2*/
  int
  id_search(name, class, valuep)
! 	string_t	*name;
! 	id_class_t	class;
  	long		*valuep;
  {
! 	hash_t		myhash;
! 	hash_t		index;
  	id		*p;
  
  	myhash = name->str_hash + (int)class;
--- 238,249 ----
  /*VARARGS2*/
  int
  id_search(name, class, valuep)
! 	string_ty	*name;
! 	id_class_ty	class;
  	long		*valuep;
  {
! 	str_hash_ty	myhash;
! 	str_hash_ty	index;
  	id		*p;
  
  	myhash = name->str_hash + (int)class;
***************
*** 313,319 ****
   *	size_by_class - determine symbol size
   *
   * SYNOPSIS
!  *	size_t size_by_class(id_class_t class);
   *
   * DESCRIPTION
   *	The size_by_class function is used to determine the correct size to
--- 313,319 ----
   *	size_by_class - determine symbol size
   *
   * SYNOPSIS
!  *	size_t size_by_class(id_class_ty class);
   *
   * DESCRIPTION
   *	The size_by_class function is used to determine the correct size to
***************
*** 326,336 ****
   *	Never malloc(sizeof(id)) as this will be too small.
   */
  
! static size_t size_by_class _((id_class_t));
  
  static size_t
  size_by_class(class)
! 	id_class_t class;
  {
  	switch ((int)class)
  	{
--- 326,336 ----
   *	Never malloc(sizeof(id)) as this will be too small.
   */
  
! static size_t size_by_class _((id_class_ty));
  
  static size_t
  size_by_class(class)
! 	id_class_ty class;
  {
  	switch ((int)class)
  	{
***************
*** 353,359 ****
   *	id_assign - assign a variable
   *
   * SYNOPSIS
!  *	void id_assign(string_t *name, id_class_t class, long value);
   *
   * DESCRIPTION
   *	Id_assign is used to assign a value to a given variable.
--- 353,359 ----
   *	id_assign - assign a variable
   *
   * SYNOPSIS
!  *	void id_assign(string_ty *name, id_class_ty class, long value);
   *
   * DESCRIPTION
   *	Id_assign is used to assign a value to a given variable.
***************
*** 367,378 ****
  /*VARARGS2*/
  void
  id_assign(name, class, value)
! 	string_t	*name;
! 	id_class_t	class;
  	long		value;
  {
! 	hash_t		myhash;
! 	hash_t		index;
  	id		*p;
  
  	myhash = name->str_hash + (int)class;
--- 367,378 ----
  /*VARARGS2*/
  void
  id_assign(name, class, value)
! 	string_ty	*name;
! 	id_class_ty	class;
  	long		value;
  {
! 	str_hash_ty	myhash;
! 	str_hash_ty	index;
  	id		*p;
  
  	myhash = name->str_hash + (int)class;
Index: fmtgen/id.h
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 27,33 ****
  #include <str.h>
  #include <word.h>
  
! enum id_class_t
  {
      ID_CLASS_KEYWORD,
      ID_CLASS_TYPE,
--- 27,33 ----
  #include <str.h>
  #include <word.h>
  
! enum id_class_ty
  {
      ID_CLASS_KEYWORD,
      ID_CLASS_TYPE,
***************
*** 34,46 ****
      ID_CLASS_FIELD,
      ID_CLASS_ENUMEL
  };
! typedef enum id_class_t id_class_t;
  
  typedef int (*bifp)_((wlist *, wlist *));
  
  void id_initialize _((void));
! int id_search _((string_t *, id_class_t, long *));
! void id_assign _((string_t *, id_class_t, long));
  void id_dump _((char *, int));
  
  #endif /* ID_H */
--- 34,46 ----
      ID_CLASS_FIELD,
      ID_CLASS_ENUMEL
  };
! typedef enum id_class_ty id_class_ty;
  
  typedef int (*bifp)_((wlist *, wlist *));
  
  void id_initialize _((void));
! int id_search _((string_ty *, id_class_ty, long *));
! void id_assign _((string_ty *, id_class_ty, long));
  void id_dump _((char *, int));
  
  #endif /* ID_H */
Index: fmtgen/indent.c
***************
*** 0 ****
--- 1,268 ----
+ /*
+  *	aegis - project change supervisor
+  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
+  *	All rights reserved.
+  *
+  *	This program is free software; you can redistribute it and/or modify
+  *	it under the terms of the GNU General Public License as published by
+  *	the Free Software Foundation; either version 2 of the License, or
+  *	(at your option) any later version.
+  *
+  *	This program is distributed in the hope that it will be useful,
+  *	but WITHOUT ANY WARRANTY; without even the implied warranty of
+  *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  *	GNU General Public License for more details.
+  *
+  *	You should have received a copy of the GNU General Public License
+  *	along with this program; if not, write to the Free Software
+  *	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+  *
+  * MANIFEST: functions to automatically indent output
+  */
+ 
+ #include <stdio.h>
+ #include <errno.h>
+ 
+ #include <error.h>
+ #include <indent.h>
+ #include <s-v-arg.h>
+ #include <trace.h>
+ 
+ 
+ #define INDENT 8
+ 
+ static	FILE	*fp;
+ static	char	*fn;
+ static int	depth;
+ static int	in_col;
+ static int	out_col;
+ static	int	continuation_line;
+ 
+ 
+ /*
+  * Function Name:
+  *	indent_more
+  *
+  * Description:
+  *	The indent_more function is used to increase the indenting
+  *	beyond the automatically calculated indent.
+  *
+  * Preconditions:
+  *	There must be a matching indent_less call.
+  *
+  * validataion:
+  *	none
+  *
+  * Passed:
+  *	nothing
+  *
+  * Returns:
+  *	nothing
+  */
+ 
+ void
+ indent_more()
+ {
+ 	++depth;
+ }
+ 
+ 
+ /*
+  * Function Name:
+  *	indent_less
+  *
+  * Description:
+  *	The indent_less function is used to decrease the indenting
+  *	to less than the automatically calculated indent.
+  *
+  * Preconditions:
+  *	There must be a matching indent_more call.
+  *
+  * validataion:
+  *	none
+  *
+  * Passed:
+  *	nothing
+  *
+  * Returns:
+  *	nothing
+  */
+ 
+ void
+ indent_less()
+ {
+ 	--depth;
+ }
+ 
+ 
+ /*
+  * Function Name:
+  *	indent_putchar
+  *
+  * Description:
+  *	The indent_putchar function is used to emity characters.
+  *	It keeps track of (){}[] pairs and indents between them.
+  *	Leading whitespace is suppressed and replaced with its own
+  *	idea of indenting.
+  *
+  * Preconditions:
+  *	none
+  *
+  * validation:
+  *	none
+  *
+  * Passed:
+  *	'c' the character to emit.
+  */
+ 
+ void
+ indent_putchar(c)
+ 	char	c;
+ {
+ 	assert(fp);
+ 	switch (c)
+ 	{
+ 	case '\n':
+ 		fputc('\n', fp);
+ #ifdef DEBUG
+ 		fflush(fp);
+ #endif
+ 		in_col = 0;
+ 		out_col = 0;
+ 		if (continuation_line == 1)
+ 			continuation_line = 2;
+ 		else
+ 			continuation_line = 0;
+ 		break;
+ 
+ 	case ' ':
+ 		if (out_col)
+ 			++in_col;
+ 		break;
+ 
+ 	case '\t':
+ 		if (out_col)
+ 			in_col = (in_col / INDENT + 1) * INDENT;
+ 		break;
+ 
+ 	case '\1':
+ 		if (!out_col)
+ 			break;
+ 		if (in_col >= INDENT * (depth + 2))
+ 			++in_col;
+ 		else
+ 			in_col = INDENT * (depth + 2);
+ 		break;
+ 
+ 	case /*{*/'}':
+ 	case /*(*/')':
+ 	case /*[*/']':
+ 		--depth;
+ 		/* fall through */
+ 
+ 	default:
+ 		if (!out_col && c != '#' && continuation_line != 2)
+ 			in_col += INDENT * depth;
+ 		while (((out_col + 8) & -8) <= in_col && out_col + 1 < in_col)
+ 		{
+ 			fputc('\t', fp);
+ 			out_col = (out_col + 8) & -8;
+ 		}
+ 		while (out_col < in_col)
+ 		{
+ 			fputc(' ', fp);
+ 			++out_col;
+ 		}
+ 		if (c == '{'/*}*/ || c == '('/*)*/ || c == '['/*]*/)
+ 			++depth;
+ 		fputc(c, fp);
+ 		in_col++;
+ 		out_col = in_col;
+ 		continuation_line = (c == '\\');
+ 		break;
+ 	}
+ 	if (ferror(fp))
+ 		nfatal("write \"%s\"", fn);
+ }
+ 
+ 
+ /*
+  * Function Name:
+  *	indent_printf
+  *
+  * Description:
+  *	As putchar is to indent_putchasr, printf is to indent_printf.
+  *
+  * Preconditions:
+  *	none
+  *
+  * Validation:
+  *	none
+  *
+  * Passed:
+  *	's' format string
+  *	... and optional arguments
+  *
+  * Returns:
+  *	nothing
+  */
+ 
+ /*VARARGS1*/
+ void
+ indent_printf(s sva_last)
+ 	char		*s;
+ 	sva_last_decl
+ {
+ 	va_list		ap;
+ 	char		buffer[2000];
+ 
+ 	sva_init(ap, s);
+ 	vsprintf(buffer, s, ap);
+ 	va_end(ap);
+ 	for (s = buffer; *s; ++s)
+ 		indent_putchar(*s);
+ }
+ 
+ 
+ void
+ indent_open(s)
+ 	char	*s;
+ {
+ 	trace(("indent_open(s = %08lX)\n{\n"/*}*/, s));
+ 	if (!s)
+ 	{
+ 		fp = stdout;
+ 		s = "(stdout)";
+ 	}
+ 	else
+ 	{
+ 		trace_string(s);
+ 		fp = fopen(s, "w");
+ 		if (!fp)
+ 			nfatal("open \"%s\"", s);
+ 	}
+ 	trace_pointer(fp);
+ 	fn = s;
+ 	depth = 0;
+ 	in_col = 0;
+ 	out_col = 0;
+ 	continuation_line = 0;
+ 	trace((/*{*/"}\n"));
+ }
+ 
+ 
+ void
+ indent_close()
+ {
+ 	trace(("indent_close()\n{\n"/*}*/));
+ 	trace_pointer(fp);
+ 	if (out_col)
+ 		indent_putchar('\n');
+ 	if (fflush(fp))
+ 		nfatal("write \"%s\"", fn);
+ 	if (fp != stdout && fclose(fp))
+ 		nfatal("close \"%s\"", fn);
+ 	fp = 0;
+ 	fn = 0;
+ 	trace((/*{*/"}\n"));
+ }
Index: fmtgen/indent.h
***************
*** 0 ****
--- 1,35 ----
+ /*
+  *	aegis - project change supervisor
+  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
+  *	All rights reserved.
+  *
+  *	This program is free software; you can redistribute it and/or modify
+  *	it under the terms of the GNU General Public License as published by
+  *	the Free Software Foundation; either version 2 of the License, or
+  *	(at your option) any later version.
+  *
+  *	This program is distributed in the hope that it will be useful,
+  *	but WITHOUT ANY WARRANTY; without even the implied warranty of
+  *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  *	GNU General Public License for more details.
+  *
+  *	You should have received a copy of the GNU General Public License
+  *	along with this program; if not, write to the Free Software
+  *	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+  *
+  * MANIFEST: interface definition for fmtgen/indent.c
+  */
+ 
+ #ifndef INDENT_H
+ #define INDENT_H
+ 
+ #include <main.h>
+ 
+ void indent_close _((void));
+ void indent_less _((void));
+ void indent_more _((void));
+ void indent_open _((char *));
+ void indent_printf _((char *, ...));
+ void indent_putchar _((int));
+ 
+ #endif /* INDENT_H */
Index: fmtgen/lex.c
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 37,52 ****
  
  #define strel(a, op, b) (strcmp(a, b) op 0)
  
! typedef struct file_t file_t;
! struct file_t
  {
  	FILE	*fp;
  	int	line_number;
  	char	*file_name;
! 	file_t	*next;
  };
  
! static	file_t		*file;
  static	int		error_count;
  extern	parse_STYPE	parse_lval;
  static	wlist		ifiles;
--- 37,52 ----
  
  #define strel(a, op, b) (strcmp(a, b) op 0)
  
! typedef struct file_ty file_ty;
! struct file_ty
  {
  	FILE	*fp;
  	int	line_number;
  	char	*file_name;
! 	file_ty	*next;
  };
  
! static	file_ty		*file;
  static	int		error_count;
  extern	parse_STYPE	parse_lval;
  static	wlist		ifiles;
***************
*** 73,86 ****
  static void
  lex_initialize()
  {
! 	typedef struct keyword_t keyword_t;
! 	struct keyword_t
  	{
  		char	*k_name;
  		int	k_token;
  	};
  
! 	static keyword_t keyword[] =
  	{
  		{ "type", TYPE, },
  		{ "string", STRING, },
--- 73,86 ----
  static void
  lex_initialize()
  {
! 	typedef struct keyword_ty keyword_ty;
! 	struct keyword_ty
  	{
  		char	*k_name;
  		int	k_token;
  	};
  
! 	static keyword_ty keyword[] =
  	{
  		{ "type", TYPE, },
  		{ "string", STRING, },
***************
*** 87,93 ****
  		{ "integer", INTEGER, },
  		{ "include", INCLUDE, },
  	};
! 	keyword_t *kp;
  	static int done;
  
  	if (done)
--- 87,93 ----
  		{ "integer", INTEGER, },
  		{ "include", INCLUDE, },
  	};
! 	keyword_ty *kp;
  	static int done;
  
  	if (done)
***************
*** 95,101 ****
  	done = 1;
  	for (kp = keyword; kp < ENDOF(keyword); ++kp)
  	{
! 		string_t *s;
  
  		s = str_from_c(kp->k_name);
  		id_assign(s, ID_CLASS_KEYWORD, kp->k_token);
--- 95,101 ----
  	done = 1;
  	for (kp = keyword; kp < ENDOF(keyword); ++kp)
  	{
! 		string_ty *s;
  
  		s = str_from_c(kp->k_name);
  		id_assign(s, ID_CLASS_KEYWORD, kp->k_token);
***************
*** 108,116 ****
  lex_open(s)
  	char	*s;
  {
! 	file_t	*f;
  
! 	f = (file_t *)mem_alloc_clear(sizeof(file_t));
  	if (!file)
  	{
  		lex_initialize();
--- 108,116 ----
  lex_open(s)
  	char	*s;
  {
! 	file_ty	*f;
  
! 	f = (file_ty *)mem_alloc_clear(sizeof(file_ty));
  	if (!file)
  	{
  		lex_initialize();
***************
*** 173,179 ****
  
  	for (;;)
  	{
! 		file_t	*old;
  
  		c = fgetc(file->fp);
  		if (c != EOF)
--- 173,179 ----
  
  	for (;;)
  	{
! 		file_ty	*old;
  
  		c = fgetc(file->fp);
  		if (c != EOF)
***************
*** 271,280 ****
  		case 's': case 't': case 'u': case 'v': case 'w':
  		case 'x': case 'y': case 'z': 
  			{
! 				char	*cp;
! 				char	buffer[1000];
! 				string_t *s;
! 				long	tok;
  	
  				cp = buffer;
  				for (;;)
--- 271,280 ----
  		case 's': case 't': case 'u': case 'v': case 'w':
  		case 'x': case 'y': case 'z': 
  			{
! 				char		*cp;
! 				char		buffer[1000];
! 				string_ty	*s;
! 				long		tok;
  	
  				cp = buffer;
  				for (;;)
Index: fmtgen/lex.h
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 26,36 ****
  #include <main.h>
  #include <str.h>
  
! typedef struct parse_list_t parse_list_t;
! struct parse_list_t
  {
! 	string_t	*name;
! 	parse_list_t	*next;
  };
  
  void lex_open _((char *));
--- 26,36 ----
  #include <main.h>
  #include <str.h>
  
! typedef struct parse_list_ty parse_list_ty;
! struct parse_list_ty
  {
! 	string_ty	*name;
! 	parse_list_ty	*next;
  };
  
  void lex_open _((char *));
Index: fmtgen/main.c
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 67,72 ****
--- 67,104 ----
  "	implement that format (with the help of gram.y and",
  "	indent.c).",
  "",
+ "OPTIONS",
+ "	The following options are understood:",
+ "",
+ "	-Help",
+ "		Give this help message.",
+ "",
+ "	-I<path>",
+ "		Specify and include search path.",
+ "",
+ "	All options may be abbreviated; the abbreviation is",
+ "	documented as the upper case letters, all lower case",
+ "	letters and underscores (_) are optional.  You must use",
+ "	consecutive sequences of optional letters.",
+ "",
+ "	All options are case insensitive, you may type them in",
+ "	upper case or lower case or a combination of both, case",
+ "	is not important.",
+ "",
+ "	For example: the arguments \"-project, \"-PROJ\" and \"-p\"",
+ "	are all interpreted to mean the -Project option.  The",
+ "	argument \"-prj\" will not be understood, because",
+ "	consecutive optional characters were not supplied.",
+ "",
+ "	Options and other command line arguments may be mixed",
+ "	arbitrarily on the command line, after the function",
+ "	selectors.",
+ "",
+ "	The GNU long option names are understood.  Since all",
+ "	option names for aegis are long, this means ignoring the",
+ "	extra leading '-'.  The \"--option=value\" convention is",
+ "	also understood.",
+ "",
  "EXIT STATUS",
  "	The %s program will exit with a status of 1 on any",
  "	error.	The %s program will only exit with a status",
***************
*** 73,79 ****
  "	of 0 if there are no errors.",
  "",
  "COPYRIGHT",
! "	The %s program is Copyright (c) 1991-1992 Peter Miller.",
  "	All rights reserved.",
  "",
  "	The %s program comes with ABSOLUTELY NO WARRANTY; for",
--- 105,111 ----
  "	of 0 if there are no errors.",
  "",
  "COPYRIGHT",
! "	The %s program is Copyright (C) 1990, 1991, 1992, 1993 Peter Miller.",
  "	All rights reserved.",
  "",
  "	The %s program comes with ABSOLUTELY NO WARRANTY; for",
***************
*** 83,90 ****
  "	-VERSion Redistribution' command.",
  "",
  "AUTHOR",
! "	Peter Miller	UUCP	uunet!munnari!bmr.gov.au!pmiller",
! "	/\\/\\*		CSNET	pmiller@bmr.gov.au",
  		0
  	};
  
--- 115,122 ----
  "	-VERSion Redistribution' command.",
  "",
  "AUTHOR",
! "	Peter Miller   UUCP     uunet!munnari!bmr.gov.au!pmiller",
! "	/\\/\\*          Internet pmiller@bmr.gov.au",
  		0
  	};
  
***************
*** 106,116 ****
  	arglex_token_include_long
  };
  
! static arglex_table_t argtab[] =
  {
! 	{ "-\\I*",	arglex_token_include_short,	},
! 	{ "-Include",	arglex_token_include_long,	},
! 	{ 0, 0, }, /* end marker */
  };
  
  
--- 138,148 ----
  	arglex_token_include_long
  };
  
! static arglex_table_ty argtab[] =
  {
! 	{ "-\\I*",	(arglex_token_ty)arglex_token_include_short,	},
! 	{ "-Include",	(arglex_token_ty)arglex_token_include_long,	},
! 	{ 0, (arglex_token_ty)0, }, /* end marker */
  };
  
  
Index: fmtgen/parse.h
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
Index: fmtgen/parse.y
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 54,63 ****
  
  %union
  {
! 	string_t	*lv_string;
  	long		lv_integer;
! 	parse_list_t	*lv_parse_list;
! 	type_t		*lv_type;
  }
  
  %type <lv_string> NAME
--- 54,63 ----
  
  %union
  {
! 	string_ty	*lv_string;
  	long		lv_integer;
! 	parse_list_ty	*lv_parse_list;
! 	type_ty		*lv_type;
  }
  
  %type <lv_string> NAME
***************
*** 68,97 ****
  
  %{
  
! typedef struct name_t name_t;
! struct name_t
  {
! 	string_t	*name;
! 	name_t		*prev;
  };
  
! static	parse_list_t	*type_root;
! static	name_t		*name_root;
  
  
! static void pl_append _((parse_list_t **, string_t *));
  
  static void
  pl_append(listp, s)
! 	parse_list_t	**listp;
! 	string_t	*s;
  {
! 	parse_list_t	*plp;
  
  	trace(("pl_append(listp = %08lX, s = \"%s\")\n{\n"/*}*/, listp, s->str_text));
  	while (*listp)
  		listp = &(*listp)->next;
! 	plp = (parse_list_t *)mem_alloc(sizeof(parse_list_t));
  	plp->name = str_copy(s);
  	plp->next = 0;
  	*listp = plp;
--- 68,97 ----
  
  %{
  
! typedef struct name_ty name_ty;
! struct name_ty
  {
! 	string_ty	*name;
! 	name_ty		*prev;
  };
  
! static	parse_list_ty	*type_root;
! static	name_ty		*name_root;
  
  
! static void pl_append _((parse_list_ty **, string_ty *));
  
  static void
  pl_append(listp, s)
! 	parse_list_ty	**listp;
! 	string_ty	*s;
  {
! 	parse_list_ty	*plp;
  
  	trace(("pl_append(listp = %08lX, s = \"%s\")\n{\n"/*}*/, listp, s->str_text));
  	while (*listp)
  		listp = &(*listp)->next;
! 	plp = (parse_list_ty *)mem_alloc(sizeof(parse_list_ty));
  	plp->name = str_copy(s);
  	plp->next = 0;
  	*listp = plp;
***************
*** 99,115 ****
  }
  
  
! static void push_name _((string_t *));
  
  static void
  push_name(s)
! 	string_t *s;
  {
! 	name_t	*np;
  
  	trace(("push_name(s = \"%s\")\n{\n"/*}*/, s->str_text));
  	assert(name_root);
! 	np = (name_t *)mem_alloc(sizeof(name_t));
  	np->name = str_format("%S_%S", name_root->name, s);
  	np->prev = name_root;
  	name_root = np;
--- 99,115 ----
  }
  
  
! static void push_name _((string_ty *));
  
  static void
  push_name(s)
! 	string_ty *s;
  {
! 	name_ty	*np;
  
  	trace(("push_name(s = \"%s\")\n{\n"/*}*/, s->str_text));
  	assert(name_root);
! 	np = (name_ty *)mem_alloc(sizeof(name_ty));
  	np->name = str_format("%S_%S", name_root->name, s);
  	np->prev = name_root;
  	name_root = np;
***************
*** 117,132 ****
  }
  
  
! static void push_name_abs _((string_t *));
  
  static void
  push_name_abs(s)
! 	string_t *s;
  {
! 	name_t	*np;
  
  	trace(("push_name_abs(s = \"%s\")\n{\n"/*}*/, s->str_text));
! 	np = (name_t *)mem_alloc(sizeof(name_t));
  	np->name = str_copy(s);
  	np->prev = name_root;
  	name_root = np;
--- 117,132 ----
  }
  
  
! static void push_name_abs _((string_ty *));
  
  static void
  push_name_abs(s)
! 	string_ty *s;
  {
! 	name_ty	*np;
  
  	trace(("push_name_abs(s = \"%s\")\n{\n"/*}*/, s->str_text));
! 	np = (name_ty *)mem_alloc(sizeof(name_ty));
  	np->name = str_copy(s);
  	np->prev = name_root;
  	name_root = np;
***************
*** 139,145 ****
  static void
  pop_name()
  {
! 	name_t	*np;
  
  	trace(("pop_name()\n{\n"/*}*/));
  	np = name_root;
--- 139,145 ----
  static void
  pop_name()
  {
! 	name_ty	*np;
  
  	trace(("pop_name()\n{\n"/*}*/));
  	np = name_root;
***************
*** 150,158 ****
  }
  
  
! static string_t *get_name _((void));
  
! static string_t *
  get_name()
  {
  	return str_copy(name_root->name);
--- 150,158 ----
  }
  
  
! static string_ty *get_name _((void));
  
! static string_ty *
  get_name()
  {
  	return str_copy(name_root->name);
***************
*** 159,170 ****
  }
  
  
! static void define_type _((string_t *, type_t *));
  
  static void
  define_type(name, type)
! 	string_t *name;
! 	type_t	*type;
  {
  	trace(("define_type(name = \"%s\")\n{\n"/*}*/, name->str_text));
  	type->included_flag = lex_in_include_file();
--- 159,170 ----
  }
  
  
! static void define_type _((string_ty *, type_ty *));
  
  static void
  define_type(name, type)
! 	string_ty *name;
! 	type_ty	*type;
  {
  	trace(("define_type(name = \"%s\")\n{\n"/*}*/, name->str_text));
  	type->included_flag = lex_in_include_file();
***************
*** 206,214 ****
  	char		*code_file;
  	char		*include_file;
  {
! 	string_t	*s;
  	char		*cp1;
! 	parse_list_t	*tnp;
  
  	trace(("parse(def = \"%s\", c = \"%s\", h = \"%s\")\n{\n"/*}*/,
  		definition_file, code_file, include_file));
--- 206,214 ----
  	char		*code_file;
  	char		*include_file;
  {
! 	string_ty	*s;
  	char		*cp1;
! 	parse_list_ty	*tnp;
  
  	trace(("parse(def = \"%s\", c = \"%s\", h = \"%s\")\n{\n"/*}*/,
  		definition_file, code_file, include_file));
***************
*** 239,245 ****
  	indent_printf("#include <parse.h>\n");
  	for (tnp = type_root; tnp; tnp = tnp->next)
  	{
! 		type_t	*tp;
  
  		if (!id_search(tnp->name, ID_CLASS_TYPE, (long *)&tp))
  			fatal("type \"%s\" lost!", tnp->name->str_text);
--- 239,245 ----
  	indent_printf("#include <parse.h>\n");
  	for (tnp = type_root; tnp; tnp = tnp->next)
  	{
! 		type_ty	*tp;
  
  		if (!id_search(tnp->name, ID_CLASS_TYPE, (long *)&tp))
  			fatal("type \"%s\" lost!", tnp->name->str_text);
***************
*** 284,290 ****
  	cp1 = basename(code_file);
  	for (tnp = type_root; tnp; tnp = tnp->next)
  	{
! 		type_t	*tp;
  
  		if (!id_search(tnp->name, ID_CLASS_TYPE, (long *)&tp))
  			fatal("type \"%s\" lost!", tnp->name->str_text);
--- 284,290 ----
  	cp1 = basename(code_file);
  	for (tnp = type_root; tnp; tnp = tnp->next)
  	{
! 		type_ty	*tp;
  
  		if (!id_search(tnp->name, ID_CLASS_TYPE, (long *)&tp))
  			fatal("type \"%s\" lost!", tnp->name->str_text);
***************
*** 302,308 ****
  	indent_printf("%s\1result;\n\n", cp1);
  	indent_printf("trace((\"%s_read_file(filename = \\\"%%s\\\")\\n{\\n\"/*}*/, filename));\n", cp1);
  	indent_printf("os_become_must_be_active();\n");
! 	indent_printf("result = parse(filename, &%s_type);\n", s->str_text);
  	indent_printf("trace((\"return %%08lX;\\n\", result));\n");
  	indent_printf("trace((/*{*/\"}\\n\"));\n");
  	indent_printf("return result;\n");
--- 302,313 ----
  	indent_printf("%s\1result;\n\n", cp1);
  	indent_printf("trace((\"%s_read_file(filename = \\\"%%s\\\")\\n{\\n\"/*}*/, filename));\n", cp1);
  	indent_printf("os_become_must_be_active();\n");
! 	indent_printf
! 	(
! 		"result = (%s)parse(filename, &%s_type);\n",
! 		s->str_text,
! 		s->str_text
! 	);
  	indent_printf("trace((\"return %%08lX;\\n\", result));\n");
  	indent_printf("trace((/*{*/\"}\\n\"));\n");
  	indent_printf("return result;\n");
***************
*** 338,345 ****
  description
  	: typedef_list field_list
  		{
! 			string_t	*s;
! 			type_t		*type;
  
  			s = get_name();
  			type = type_create_struct(s, $2, 1);
--- 343,350 ----
  description
  	: typedef_list field_list
  		{
! 			string_ty	*s;
! 			type_ty		*type;
  
  			s = get_name();
  			type = type_create_struct(s, $2, 1);
***************
*** 401,407 ****
  		}
  	| NAME
  		{
! 			type_t		*tp;
  
  			if (id_search($1, ID_CLASS_TYPE, (long *)&tp))
  			{
--- 406,412 ----
  		}
  	| NAME
  		{
! 			type_ty		*tp;
  
  			if (id_search($1, ID_CLASS_TYPE, (long *)&tp))
  			{
***************
*** 426,432 ****
  structure
  	: '{' field_list '}'
  		{
! 			string_t	*s;
  
  			s = get_name();
  			$$ = type_create_struct(s, $2, 0);
--- 431,437 ----
  structure
  	: '{' field_list '}'
  		{
! 			string_ty	*s;
  
  			s = get_name();
  			$$ = type_create_struct(s, $2, 0);
***************
*** 449,456 ****
  list
  	: '[' type ']'
  		{
! 			string_t	*s;
! 			static string_t	*list;
  
  			if (!list)
  				list = str_from_c("list");
--- 454,461 ----
  list
  	: '[' type ']'
  		{
! 			string_ty	*s;
! 			static string_ty	*list;
  
  			if (!list)
  				list = str_from_c("list");
***************
*** 465,471 ****
  enumeration
  	: '(' enum_list optional_comma ')'
  		{
! 			string_t *s;
  
  			s = get_name();
  			$$ = type_create_enum(s, $2);
--- 470,476 ----
  enumeration
  	: '(' enum_list optional_comma ')'
  		{
! 			string_ty *s;
  
  			s = get_name();
  			$$ = type_create_enum(s, $2);
***************
*** 494,500 ****
  enum_name
  	: NAME
  		{
! 			string_t *s;
  
  			push_name($1);
  			s = get_name();
--- 499,505 ----
  enum_name
  	: NAME
  		{
! 			string_ty *s;
  
  			push_name($1);
  			s = get_name();
Index: fmtgen/type.c
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 25,32 ****
  
  void
  type_gen_include_declarator(type, name, is_a_list)
! 	type_t		*type;
! 	string_t	*name;
  	int		is_a_list;
  {
  	if (type->method->gen_include_declarator)
--- 25,32 ----
  
  void
  type_gen_include_declarator(type, name, is_a_list)
! 	type_ty		*type;
! 	string_ty	*name;
  	int		is_a_list;
  {
  	if (type->method->gen_include_declarator)
***************
*** 36,43 ****
  
  void
  type_gen_include(type, name)
! 	type_t		*type;
! 	string_t 	*name;
  {
  	if (type->method->gen_include)
  		type->method->gen_include(type, name);
--- 36,43 ----
  
  void
  type_gen_include(type, name)
! 	type_ty		*type;
! 	string_ty 	*name;
  {
  	if (type->method->gen_include)
  		type->method->gen_include(type, name);
***************
*** 46,53 ****
  
  void
  type_gen_code_declarator(type, name, is_a_list)
! 	type_t		*type;
! 	string_t	*name;
  	int		is_a_list;
  {
  	if (type->method->gen_code_declarator)
--- 46,53 ----
  
  void
  type_gen_code_declarator(type, name, is_a_list)
! 	type_ty		*type;
! 	string_ty	*name;
  	int		is_a_list;
  {
  	if (type->method->gen_code_declarator)
***************
*** 57,64 ****
  
  void
  type_gen_code(type, name)
! 	type_t	*type;
! 	string_t *name;
  {
  	if (type->method->gen_code)
  		type->method->gen_code(type, name);
--- 57,64 ----
  
  void
  type_gen_code(type, name)
! 	type_ty		*type;
! 	string_ty	*name;
  {
  	if (type->method->gen_code)
  		type->method->gen_code(type, name);
***************
*** 67,74 ****
  
  void
  type_gen_free_declarator(type, name, is_a_list)
! 	type_t		*type;
! 	string_t	*name;
  	int		is_a_list;
  {
  	if (type->method->gen_free_declarator)
--- 67,74 ----
  
  void
  type_gen_free_declarator(type, name, is_a_list)
! 	type_ty		*type;
! 	string_ty	*name;
  	int		is_a_list;
  {
  	if (type->method->gen_free_declarator)
Index: fmtgen/type.h
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 27,33 ****
  #include <lex.h>
  #include <str.h>
  
! enum type_class_t
  {
  	type_class_enum,
  	type_class_integer,
--- 27,33 ----
  #include <lex.h>
  #include <str.h>
  
! enum type_class_ty
  {
  	type_class_enum,
  	type_class_integer,
***************
*** 36,75 ****
  	type_class_struct,
  	type_class_ref
  };
! typedef enum type_class_t type_class_t;
  
  #define TYPE_T \
! 	type_class_t	class; \
! 	struct type_method_t *method; \
! 	string_t	*name; \
  	int		included_flag;
  
! typedef struct type_t type_t;
! struct type_t
  {
  	TYPE_T
  };
  
! typedef struct type_method_t type_method_t;
! struct type_method_t
  {
! 	void (*gen_include)_((type_t *, string_t *));
! 	void (*gen_include_declarator)_((type_t *, string_t *, int));
! 	void (*gen_code)_((type_t *, string_t *));
! 	void (*gen_code_declarator)_((type_t *, string_t *, int));
! 	void (*gen_free_declarator)_((type_t *, string_t *, int));
  };
  
! void type_gen_include _((type_t *, string_t *));
! void type_gen_include_declarator _((type_t *, string_t *, int));
! void type_gen_code _((type_t *, string_t *));
! void type_gen_code_declarator _((type_t *, string_t *, int));
! void type_gen_free_declarator _((type_t *, string_t *, int));
! type_t *type_create_string _((void));
! type_t *type_create_integer _((void));
! type_t *type_create_ref _((string_t *name, string_t *ref));
! type_t *type_create_list _((string_t *name, type_t *subtype));
! type_t *type_create_struct _((string_t *name, parse_list_t *contents, int n));
! type_t *type_create_enum _((string_t *name, parse_list_t *plp));
  
  #endif /* TYPE_H */
--- 36,75 ----
  	type_class_struct,
  	type_class_ref
  };
! typedef enum type_class_ty type_class_ty;
  
  #define TYPE_T \
! 	type_class_ty	class; \
! 	struct type_method_ty *method; \
! 	string_ty	*name; \
  	int		included_flag;
  
! typedef struct type_ty type_ty;
! struct type_ty
  {
  	TYPE_T
  };
  
! typedef struct type_method_ty type_method_ty;
! struct type_method_ty
  {
! 	void (*gen_include)_((type_ty *, string_ty *));
! 	void (*gen_include_declarator)_((type_ty *, string_ty *, int));
! 	void (*gen_code)_((type_ty *, string_ty *));
! 	void (*gen_code_declarator)_((type_ty *, string_ty *, int));
! 	void (*gen_free_declarator)_((type_ty *, string_ty *, int));
  };
  
! void type_gen_include _((type_ty *, string_ty *));
! void type_gen_include_declarator _((type_ty *, string_ty *, int));
! void type_gen_code _((type_ty *, string_ty *));
! void type_gen_code_declarator _((type_ty *, string_ty *, int));
! void type_gen_free_declarator _((type_ty *, string_ty *, int));
! type_ty *type_create_string _((void));
! type_ty *type_create_integer _((void));
! type_ty *type_create_ref _((string_ty *name, string_ty *ref));
! type_ty *type_create_list _((string_ty *name, type_ty *subtype));
! type_ty *type_create_struct _((string_ty *name, parse_list_ty *contents, int n));
! type_ty *type_create_enum _((string_ty *name, parse_list_ty *plp));
  
  #endif /* TYPE_H */
Index: fmtgen/type_enum.c
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 26,53 ****
  #include <mem.h>
  
  
! typedef struct type_enum_t type_enum_t;
! struct type_enum_t
  {
  	/* inherited */
  	TYPE_T
  
  	/* instance variables */
! 	parse_list_t *list;
  };
  
  
! static void gen_include _((type_t *, string_t *));
  
  static void
  gen_include(type, name)
! 	type_t	*type;
! 	string_t *name;
  {
! 	type_enum_t	*type2;
! 	parse_list_t	*np;
  
! 	type2 = (type_enum_t *)type;
  	indent_putchar('\n');
  	indent_printf("#ifndef %s_DEF\n", name->str_text);
  	indent_printf("#define %s_DEF\n", name->str_text);
--- 26,53 ----
  #include <mem.h>
  
  
! typedef struct type_enum_ty type_enum_ty;
! struct type_enum_ty
  {
  	/* inherited */
  	TYPE_T
  
  	/* instance variables */
! 	parse_list_ty *list;
  };
  
  
! static void gen_include _((type_ty *, string_ty *));
  
  static void
  gen_include(type, name)
! 	type_ty		*type;
! 	string_ty	*name;
  {
! 	type_enum_ty	*type2;
! 	parse_list_ty	*np;
  
! 	type2 = (type_enum_ty *)type;
  	indent_putchar('\n');
  	indent_printf("#ifndef %s_DEF\n", name->str_text);
  	indent_printf("#define %s_DEF\n", name->str_text);
***************
*** 65,71 ****
  	indent_printf("#endif /* %s_DEF */\n", name->str_text);
  
  	indent_putchar('\n');
! 	indent_printf("extern type_t %s_type;\n", name->str_text);
  
  	indent_putchar('\n');
  	indent_printf("void %s_write _((char *, %s));\n", name->str_text, name->str_text);
--- 65,71 ----
  	indent_printf("#endif /* %s_DEF */\n", name->str_text);
  
  	indent_putchar('\n');
! 	indent_printf("extern type_ty %s_type;\n", name->str_text);
  
  	indent_putchar('\n');
  	indent_printf("void %s_write _((char *, %s));\n", name->str_text, name->str_text);
***************
*** 73,84 ****
  }
  
  
! static void gen_include_declarator _((type_t *, string_t *, int));
  
  static void
  gen_include_declarator(type, name, is_a_list)
! 	type_t		*type;
! 	string_t	*name;
  	int		is_a_list;
  {
  	char		*deref;
--- 73,84 ----
  }
  
  
! static void gen_include_declarator _((type_ty *, string_ty *, int));
  
  static void
  gen_include_declarator(type, name, is_a_list)
! 	type_ty		*type;
! 	string_ty	*name;
  	int		is_a_list;
  {
  	char		*deref;
***************
*** 88,111 ****
  }
  
  
! static void gen_code _((type_t *, string_t *));
  
  static void
  gen_code(type, name)
! 	type_t		*type;
! 	string_t	*name;
  {
! 	parse_list_t	*np;
! 	type_enum_t	*type2;
  	int		n;
  
! 	type2 = (type_enum_t *)type;
  	indent_putchar('\n');
  	indent_printf("static char *%s_s[] =\n", name->str_text);
  	indent_printf("{\n"/*}*/);
  	for (np = type2->list, n = 0; np; np = np->next, ++n)
  	{
! 		string_t *s;
  
  		id_search(np->name, ID_CLASS_ENUMEL, (long *)&s);
  		indent_printf("\"%s\",\n", s->str_text);
--- 88,111 ----
  }
  
  
! static void gen_code _((type_ty *, string_ty *));
  
  static void
  gen_code(type, name)
! 	type_ty		*type;
! 	string_ty	*name;
  {
! 	parse_list_ty	*np;
! 	type_enum_ty	*type2;
  	int		n;
  
! 	type2 = (type_enum_ty *)type;
  	indent_putchar('\n');
  	indent_printf("static char *%s_s[] =\n", name->str_text);
  	indent_printf("{\n"/*}*/);
  	for (np = type2->list, n = 0; np; np = np->next, ++n)
  	{
! 		string_ty *s;
  
  		id_search(np->name, ID_CLASS_ENUMEL, (long *)&s);
  		indent_printf("\"%s\",\n", s->str_text);
***************
*** 150,156 ****
  	indent_putchar('\n');
  	indent_printf
  	(
! 		"static int %s_parse _((string_t *, void *));\n",
  		name->str_text
  	);
  
--- 150,156 ----
  	indent_putchar('\n');
  	indent_printf
  	(
! 		"static int %s_parse _((string_ty *, void *));\n",
  		name->str_text
  	);
  
***************
*** 158,168 ****
  	indent_printf("static int\n");
  	indent_printf("%s_parse(name, addr)\n", name->str_text);
  	indent_more();
! 	indent_printf("%s\1*name;\n", "string_t");
  	indent_printf("%s\1*addr;\n", "void");
  	indent_less();
  	indent_printf("{\n"/*}*/);
! 	indent_printf("%s\1*%s_f[SIZEOF(%s_s)];\n", "static string_t", name->str_text, name->str_text);
  	indent_printf("%s\1j;\n", "int");
  	indent_putchar('\n');
  	indent_printf("slow_to_fast(%s_s, %s_f, SIZEOF(%s_s));\n", name->str_text, name->str_text, name->str_text);
--- 158,168 ----
  	indent_printf("static int\n");
  	indent_printf("%s_parse(name, addr)\n", name->str_text);
  	indent_more();
! 	indent_printf("%s\1*name;\n", "string_ty");
  	indent_printf("%s\1*addr;\n", "void");
  	indent_less();
  	indent_printf("{\n"/*}*/);
! 	indent_printf("%s\1*%s_f[SIZEOF(%s_s)];\n", "static string_ty", name->str_text, name->str_text);
  	indent_printf("%s\1j;\n", "int");
  	indent_putchar('\n');
  	indent_printf("slow_to_fast(%s_s, %s_f, SIZEOF(%s_s));\n", name->str_text, name->str_text, name->str_text);
***************
*** 178,184 ****
  	indent_printf(/*{*/"}\n");
  
  	indent_putchar('\n');
! 	indent_printf("type_t %s_type =\n", name->str_text);
  	indent_printf("{\n"/*}*/);
  	indent_printf("type_class_enum,\n");
  	indent_printf("\"%s\",\n", name->str_text);
--- 178,184 ----
  	indent_printf(/*{*/"}\n");
  
  	indent_putchar('\n');
! 	indent_printf("type_ty %s_type =\n", name->str_text);
  	indent_printf("{\n"/*}*/);
  	indent_printf("type_class_enum,\n");
  	indent_printf("\"%s\",\n", name->str_text);
***************
*** 191,202 ****
  }
  
  
! static void gen_code_declarator _((type_t *, string_t *, int));
  
  static void
  gen_code_declarator(type, name, is_a_list)
! 	type_t		*type;
! 	string_t	*name;
  	int		is_a_list;
  {
  	indent_printf("%s_write("/*)*/, type->name->str_text);
--- 191,202 ----
  }
  
  
! static void gen_code_declarator _((type_ty *, string_ty *, int));
  
  static void
  gen_code_declarator(type, name, is_a_list)
! 	type_ty		*type;
! 	string_ty	*name;
  	int		is_a_list;
  {
  	indent_printf("%s_write("/*)*/, type->name->str_text);
***************
*** 208,219 ****
  }
  
  
! static void gen_free_declarator _((type_t *, string_t *, int));
  
  static void
  gen_free_declarator(type, name, is_a_list)
! 	type_t		*type;
! 	string_t	*name;
  	int		is_a_list;
  {
  	if (is_a_list)
--- 208,219 ----
  }
  
  
! static void gen_free_declarator _((type_ty *, string_ty *, int));
  
  static void
  gen_free_declarator(type, name, is_a_list)
! 	type_ty		*type;
! 	string_ty	*name;
  	int		is_a_list;
  {
  	if (is_a_list)
***************
*** 221,227 ****
  }
  
  
! static type_method_t method =
  {
  	gen_include,
  	gen_include_declarator,
--- 221,227 ----
  }
  
  
! static type_method_ty method =
  {
  	gen_include,
  	gen_include_declarator,
***************
*** 231,248 ****
  };
  
  
! type_t *
  type_create_enum(name, list)
! 	string_t	*name;
! 	parse_list_t	*list;
  {
! 	type_enum_t	*type;
  
! 	type = (type_enum_t *)mem_alloc(sizeof(type_enum_t));
  	type->class = type_class_enum;
  	type->method = &method;
  	type->name = str_copy(name);
  	type->list = list;
  	id_assign(name, ID_CLASS_TYPE, (long)type);
! 	return (type_t *)type;
  }
--- 231,248 ----
  };
  
  
! type_ty *
  type_create_enum(name, list)
! 	string_ty	*name;
! 	parse_list_ty	*list;
  {
! 	type_enum_ty	*type;
  
! 	type = (type_enum_ty *)mem_alloc(sizeof(type_enum_ty));
  	type->class = type_class_enum;
  	type->method = &method;
  	type->name = str_copy(name);
  	type->list = list;
  	id_assign(name, ID_CLASS_TYPE, (long)type);
! 	return (type_ty *)type;
  }
Index: fmtgen/type_integ.c
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 25,36 ****
  #include <mem.h>
  
  
! static void gen_include_declarator _((type_t *, string_t *, int));
  
  static void
  gen_include_declarator(type, name, is_a_list)
! 	type_t		*type;
! 	string_t	*name;
  	int		is_a_list;
  {
  	char		*deref;
--- 25,36 ----
  #include <mem.h>
  
  
! static void gen_include_declarator _((type_ty *, string_ty *, int));
  
  static void
  gen_include_declarator(type, name, is_a_list)
! 	type_ty		*type;
! 	string_ty	*name;
  	int		is_a_list;
  {
  	char		*deref;
***************
*** 40,51 ****
  }
  
  
! static void gen_code_declarator _((type_t *, string_t *, int));
  
  static void
  gen_code_declarator(type, name, is_a_list)
! 	type_t		*type;
! 	string_t	*name;
  	int		is_a_list;
  {
  	indent_printf("integer_write("/*)*/);
--- 40,51 ----
  }
  
  
! static void gen_code_declarator _((type_ty *, string_ty *, int));
  
  static void
  gen_code_declarator(type, name, is_a_list)
! 	type_ty		*type;
! 	string_ty	*name;
  	int		is_a_list;
  {
  	indent_printf("integer_write("/*)*/);
***************
*** 57,68 ****
  }
  
  
! static void gen_free_declarator _((type_t *, string_t *, int));
  
  static void
  gen_free_declarator(type, name, is_a_list)
! 	type_t		*type;
! 	string_t	*name;
  	int		is_a_list;
  {
  	if (is_a_list)
--- 57,68 ----
  }
  
  
! static void gen_free_declarator _((type_ty *, string_ty *, int));
  
  static void
  gen_free_declarator(type, name, is_a_list)
! 	type_ty		*type;
! 	string_ty	*name;
  	int		is_a_list;
  {
  	if (is_a_list)
***************
*** 70,76 ****
  }
  
  
! static type_method_t method =
  {
  	0, /* gen_include */
  	gen_include_declarator,
--- 70,76 ----
  }
  
  
! static type_method_ty method =
  {
  	0, /* gen_include */
  	gen_include_declarator,
***************
*** 80,91 ****
  };
  
  
! type_t *
  type_create_integer()
  {
! 	type_t	*type;
  
! 	type = (type_t *)mem_alloc(sizeof(type_t));
  	type->class = type_class_integer;
  	type->method = &method;
  	type->name = str_from_c("integer");
--- 80,91 ----
  };
  
  
! type_ty *
  type_create_integer()
  {
! 	type_ty		*type;
  
! 	type = (type_ty *)mem_alloc(sizeof(type_ty));
  	type->class = type_class_integer;
  	type->method = &method;
  	type->name = str_from_c("integer");
Index: fmtgen/type_list.c
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 26,53 ****
  #include <id.h>
  
  
! typedef struct type_list_t type_list_t;
! struct type_list_t
  {
  	/* inherited */
  	TYPE_T
  
  	/* instance variables */
! 	type_t		*subtype;
  };
  
  
! static void gen_include _((type_t *, string_t *));
  
  static void
  gen_include(type, name)
! 	type_t	*type;
! 	string_t *name;
  {
! 	string_t	*s;
! 	type_list_t	*type2;
  
! 	type2 = (type_list_t *)type;
  	indent_putchar('\n');
  	indent_printf("#ifndef %s_DEF\n", name->str_text);
  	indent_printf("#define %s_DEF\n", name->str_text);
--- 26,53 ----
  #include <id.h>
  
  
! typedef struct type_list_ty type_list_ty;
! struct type_list_ty
  {
  	/* inherited */
  	TYPE_T
  
  	/* instance variables */
! 	type_ty		*subtype;
  };
  
  
! static void gen_include _((type_ty *, string_ty *));
  
  static void
  gen_include(type, name)
! 	type_ty		*type;
! 	string_ty	*name;
  {
! 	string_ty	*s;
! 	type_list_ty	*type2;
  
! 	type2 = (type_list_ty *)type;
  	indent_putchar('\n');
  	indent_printf("#ifndef %s_DEF\n", name->str_text);
  	indent_printf("#define %s_DEF\n", name->str_text);
***************
*** 62,68 ****
  	indent_printf("#endif /* %s_DEF */\n", name->str_text);
  
  	indent_putchar('\n');
! 	indent_printf("extern type_t %s_type;\n", name->str_text);
  
  	indent_putchar('\n');
  	indent_printf("void %s_write _((char *, %s));\n", name->str_text, name->str_text);
--- 62,68 ----
  	indent_printf("#endif /* %s_DEF */\n", name->str_text);
  
  	indent_putchar('\n');
! 	indent_printf("extern type_ty %s_type;\n", name->str_text);
  
  	indent_putchar('\n');
  	indent_printf("void %s_write _((char *, %s));\n", name->str_text, name->str_text);
***************
*** 69,80 ****
  }
  
  
! static void gen_include_declarator _((type_t *, string_t *, int));
  
  static void
  gen_include_declarator(type, name, is_a_list)
! 	type_t		*type;
! 	string_t	*name;
  	int		is_a_list;
  {
  	char		*deref;
--- 69,80 ----
  }
  
  
! static void gen_include_declarator _((type_ty *, string_ty *, int));
  
  static void
  gen_include_declarator(type, name, is_a_list)
! 	type_ty		*type;
! 	string_ty	*name;
  	int		is_a_list;
  {
  	char		*deref;
***************
*** 84,100 ****
  }
  
  
! static void gen_code _((type_t *, string_t *));
  
  static void
  gen_code(type, name)
! 	type_t		*type;
! 	string_t	*name;
  {
! 	string_t	*s;
! 	type_list_t	*type2;
  
! 	type2 = (type_list_t *)type;
  	indent_putchar('\n');
  	indent_printf("void\n");
  	indent_printf("%s_write(name, this)\n", name->str_text);
--- 84,100 ----
  }
  
  
! static void gen_code _((type_ty *, string_ty *));
  
  static void
  gen_code(type, name)
! 	type_ty		*type;
! 	string_ty	*name;
  {
! 	string_ty	*s;
! 	type_list_ty	*type2;
  
! 	type2 = (type_list_ty *)type;
  	indent_putchar('\n');
  	indent_printf("void\n");
  	indent_printf("%s_write(name, this)\n", name->str_text);
***************
*** 137,146 ****
  	indent_printf("static void *\n");
  	indent_printf("%s_alloc()\n", name->str_text);
  	indent_printf("{\n"/*}*/);
! 	indent_printf("struct %s\1*result;\n\n", name->str_text);
  	indent_printf("trace((\"%s_alloc()\\n{\\n\"/*}*/));\n", name->str_text);
! 	indent_printf("result = (struct %s *)mem_alloc_clear(sizeof(struct %s));\n", name->str_text, name->str_text);
! 	indent_printf("trace((\"return %%08lX;\\n\", result));\n");
  	indent_printf("trace((/*{*/\"}\\n\"));\n");
  	indent_printf("return result;\n");
  	indent_printf(/*{*/"}\n");
--- 137,150 ----
  	indent_printf("static void *\n");
  	indent_printf("%s_alloc()\n", name->str_text);
  	indent_printf("{\n"/*}*/);
! 	indent_printf("%s\1*result;\n\n", "void");
  	indent_printf("trace((\"%s_alloc()\\n{\\n\"/*}*/));\n", name->str_text);
! 	indent_printf
! 	(
! 		"result = (void *)mem_alloc_clear(sizeof(struct %s));\n",
! 		name->str_text
! 	);
! 	indent_printf("trace((\"return %%08lX;\\n\", (long)result));\n");
  	indent_printf("trace((/*{*/\"}\\n\"));\n");
  	indent_printf("return result;\n");
  	indent_printf(/*{*/"}\n");
***************
*** 180,186 ****
  	indent_putchar('\n');
  	indent_printf
  	(
! 		"static void %s_parse _((void *, type_t **, void **));\n",
  		name->str_text
  	);
  
--- 184,190 ----
  	indent_putchar('\n');
  	indent_printf
  	(
! 		"static void %s_parse _((void *, type_ty **, void **));\n",
  		name->str_text
  	);
  
***************
*** 189,195 ****
  	indent_printf("%s_parse(that, type_pp, addr_p)\n", name->str_text);
  	indent_more();
  	indent_printf("%s\1*that;\n", "void");
! 	indent_printf("%s\1**type_pp;\n", "type_t");
  	indent_printf("%s\1**addr_p;\n", "void");
  	indent_less();
  	indent_printf("{\n"/*}*/);
--- 193,199 ----
  	indent_printf("%s_parse(that, type_pp, addr_p)\n", name->str_text);
  	indent_more();
  	indent_printf("%s\1*that;\n", "void");
! 	indent_printf("%s\1**type_pp;\n", "type_ty");
  	indent_printf("%s\1**addr_p;\n", "void");
  	indent_less();
  	indent_printf("{\n"/*}*/);
***************
*** 204,210 ****
  	indent_printf(/*{*/"}\n");
  
  	indent_putchar('\n');
! 	indent_printf("type_t %s_type =\n", name->str_text);
  	indent_printf("{\n"/*}*/);
  	indent_printf("type_class_list,\n");
  	indent_printf("\"%s\",\n", name->str_text);
--- 208,214 ----
  	indent_printf(/*{*/"}\n");
  
  	indent_putchar('\n');
! 	indent_printf("type_ty %s_type =\n", name->str_text);
  	indent_printf("{\n"/*}*/);
  	indent_printf("type_class_list,\n");
  	indent_printf("\"%s\",\n", name->str_text);
***************
*** 217,228 ****
  }
  
  
! static void gen_code_declarator _((type_t *, string_t *, int));
  
  static void
  gen_code_declarator(type, name, is_a_list)
! 	type_t		*type;
! 	string_t	*name;
  	int		is_a_list;
  {
  	indent_printf("%s_write("/*)*/, type->name->str_text);
--- 221,232 ----
  }
  
  
! static void gen_code_declarator _((type_ty *, string_ty *, int));
  
  static void
  gen_code_declarator(type, name, is_a_list)
! 	type_ty		*type;
! 	string_ty	*name;
  	int		is_a_list;
  {
  	indent_printf("%s_write("/*)*/, type->name->str_text);
***************
*** 234,245 ****
  }
  
  
! static void gen_free_declarator _((type_t *, string_t *, int));
  
  static void
  gen_free_declarator(type, name, is_a_list)
! 	type_t		*type;
! 	string_t	*name;
  	int		is_a_list;
  {
  	indent_printf("%s_free(this->%s);\n", type->name->str_text, name->str_text);
--- 238,249 ----
  }
  
  
! static void gen_free_declarator _((type_ty *, string_ty *, int));
  
  static void
  gen_free_declarator(type, name, is_a_list)
! 	type_ty		*type;
! 	string_ty	*name;
  	int		is_a_list;
  {
  	indent_printf("%s_free(this->%s);\n", type->name->str_text, name->str_text);
***************
*** 246,252 ****
  }
  
  
! static type_method_t method =
  {
  	gen_include,
  	gen_include_declarator,
--- 250,256 ----
  }
  
  
! static type_method_ty method =
  {
  	gen_include,
  	gen_include_declarator,
***************
*** 256,273 ****
  };
  
  
! type_t *
  type_create_list(name, subtype)
! 	string_t	*name;
! 	type_t		*subtype;
  {
! 	type_list_t	*type;
  
! 	type = (type_list_t *)mem_alloc(sizeof(type_list_t));
  	type->class = type_class_list;
  	type->method = &method;
  	type->name = str_copy(name);
  	type->subtype = subtype;
  	id_assign(name, ID_CLASS_TYPE, (long)type);
! 	return (type_t *)type;
  }
--- 260,277 ----
  };
  
  
! type_ty *
  type_create_list(name, subtype)
! 	string_ty	*name;
! 	type_ty		*subtype;
  {
! 	type_list_ty	*type;
  
! 	type = (type_list_ty *)mem_alloc(sizeof(type_list_ty));
  	type->class = type_class_list;
  	type->method = &method;
  	type->name = str_copy(name);
  	type->subtype = subtype;
  	id_assign(name, ID_CLASS_TYPE, (long)type);
! 	return (type_ty *)type;
  }
Index: fmtgen/type_ref.c
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 27,55 ****
  #include <error.h>
  
  
! typedef struct type_ref_t type_ref_t;
! struct type_ref_t
  {
  	/* inherited */
  	TYPE_T
  
  	/* instance variables */
! 	string_t	*ref;
  };
  
  
! static void gen_include_declarator _((type_t *, string_t *, int));
  
  static void
  gen_include_declarator(type, name, is_a_list)
! 	type_t		*type;
! 	string_t	*name;
  	int		is_a_list;
  {
! 	type_ref_t	*type2;
! 	type_t		*tp;
  
! 	type2 = (type_ref_t *)type;
  	if (!id_search(type2->ref, ID_CLASS_TYPE, (long *)&tp))
  		fatal("type \"%s\" vanished", type2->ref->str_text);
  	type_gen_include_declarator(tp, name, is_a_list);
--- 27,55 ----
  #include <error.h>
  
  
! typedef struct type_ref_ty type_ref_ty;
! struct type_ref_ty
  {
  	/* inherited */
  	TYPE_T
  
  	/* instance variables */
! 	string_ty	*ref;
  };
  
  
! static void gen_include_declarator _((type_ty *, string_ty *, int));
  
  static void
  gen_include_declarator(type, name, is_a_list)
! 	type_ty		*type;
! 	string_ty	*name;
  	int		is_a_list;
  {
! 	type_ref_ty	*type2;
! 	type_ty		*tp;
  
! 	type2 = (type_ref_ty *)type;
  	if (!id_search(type2->ref, ID_CLASS_TYPE, (long *)&tp))
  		fatal("type \"%s\" vanished", type2->ref->str_text);
  	type_gen_include_declarator(tp, name, is_a_list);
***************
*** 56,73 ****
  }
  
  
! static void gen_code_declarator _((type_t *, string_t *, int));
  
  static void
  gen_code_declarator(type, name, is_a_list)
! 	type_t		*type;
! 	string_t	*name;
  	int		is_a_list;
  {
! 	type_ref_t	*type2;
! 	type_t		*tp;
  
! 	type2 = (type_ref_t *)type;
  	if (!id_search(type2->ref, ID_CLASS_TYPE, (long *)&tp))
  		fatal("type \"%s\" vanished", type2->ref->str_text);
  	type_gen_code_declarator(tp, name, is_a_list);
--- 56,73 ----
  }
  
  
! static void gen_code_declarator _((type_ty *, string_ty *, int));
  
  static void
  gen_code_declarator(type, name, is_a_list)
! 	type_ty		*type;
! 	string_ty	*name;
  	int		is_a_list;
  {
! 	type_ref_ty	*type2;
! 	type_ty		*tp;
  
! 	type2 = (type_ref_ty *)type;
  	if (!id_search(type2->ref, ID_CLASS_TYPE, (long *)&tp))
  		fatal("type \"%s\" vanished", type2->ref->str_text);
  	type_gen_code_declarator(tp, name, is_a_list);
***************
*** 74,91 ****
  }
  
  
! static void gen_free_declarator _((type_t *, string_t *, int));
  
  static void
  gen_free_declarator(type, name, is_a_list)
! 	type_t		*type;
! 	string_t	*name;
  	int		is_a_list;
  {
! 	type_ref_t	*type2;
! 	type_t		*tp;
  
! 	type2 = (type_ref_t *)type;
  	if (!id_search(type2->ref, ID_CLASS_TYPE, (long *)&tp))
  		fatal("type \"%s\" vanished", type2->ref->str_text);
  	type_gen_free_declarator(tp, name, is_a_list);
--- 74,91 ----
  }
  
  
! static void gen_free_declarator _((type_ty *, string_ty *, int));
  
  static void
  gen_free_declarator(type, name, is_a_list)
! 	type_ty		*type;
! 	string_ty	*name;
  	int		is_a_list;
  {
! 	type_ref_ty	*type2;
! 	type_ty		*tp;
  
! 	type2 = (type_ref_ty *)type;
  	if (!id_search(type2->ref, ID_CLASS_TYPE, (long *)&tp))
  		fatal("type \"%s\" vanished", type2->ref->str_text);
  	type_gen_free_declarator(tp, name, is_a_list);
***************
*** 92,98 ****
  }
  
  
! static type_method_t method =
  {
  	0, /* gen_include */
  	gen_include_declarator,
--- 92,98 ----
  }
  
  
! static type_method_ty method =
  {
  	0, /* gen_include */
  	gen_include_declarator,
***************
*** 102,121 ****
  };
  
  
! type_t *
  type_create_ref(name, ref)
! 	string_t	*name;
! 	string_t	*ref;
  {
! 	type_ref_t	*type;
! 	type_t		*tp;
  
  	if (id_search(ref, ID_CLASS_TYPE, (long *)&tp))
  		id_assign(name, ID_CLASS_TYPE, (long)tp);
! 	type = (type_ref_t *)mem_alloc(sizeof(type_ref_t));
  	type->class = type_class_ref;
  	type->method = &method;
  	type->name = str_copy(name);
  	type->ref = str_copy(ref);
! 	return (type_t *)type;
  }
--- 102,121 ----
  };
  
  
! type_ty *
  type_create_ref(name, ref)
! 	string_ty	*name;
! 	string_ty	*ref;
  {
! 	type_ref_ty	*type;
! 	type_ty		*tp;
  
  	if (id_search(ref, ID_CLASS_TYPE, (long *)&tp))
  		id_assign(name, ID_CLASS_TYPE, (long)tp);
! 	type = (type_ref_ty *)mem_alloc(sizeof(type_ref_ty));
  	type->class = type_class_ref;
  	type->method = &method;
  	type->name = str_copy(name);
  	type->ref = str_copy(ref);
! 	return (type_ty *)type;
  }
Index: fmtgen/type_strin.c
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 25,51 ****
  #include <mem.h>
  
  
! static void gen_include_declarator _((type_t *, string_t *, int));
  
  static void
  gen_include_declarator(type, name, is_a_list)
! 	type_t		*type;
! 	string_t	*name;
  	int		is_a_list;
  {
  	char		*deref;
  
  	deref = (is_a_list ? "*" : "");
! 	indent_printf("%s\1%s*%s;\n", "string_t", deref, name->str_text);
  }
  
  
! static void gen_code_declarator _((type_t *, string_t *, int));
  
  static void
  gen_code_declarator(type, name, is_a_list)
! 	string_t	*name;
! 	type_t		*type;
  	int		is_a_list;
  {
  	indent_printf("string_write("/*)*/);
--- 25,51 ----
  #include <mem.h>
  
  
! static void gen_include_declarator _((type_ty *, string_ty *, int));
  
  static void
  gen_include_declarator(type, name, is_a_list)
! 	type_ty		*type;
! 	string_ty	*name;
  	int		is_a_list;
  {
  	char		*deref;
  
  	deref = (is_a_list ? "*" : "");
! 	indent_printf("%s\1%s*%s;\n", "string_ty", deref, name->str_text);
  }
  
  
! static void gen_code_declarator _((type_ty *, string_ty *, int));
  
  static void
  gen_code_declarator(type, name, is_a_list)
! 	string_ty	*name;
! 	type_ty		*type;
  	int		is_a_list;
  {
  	indent_printf("string_write("/*)*/);
***************
*** 57,68 ****
  }
  
  
! static void gen_free_declarator _((type_t *, string_t *, int));
  
  static void
  gen_free_declarator(type, name, is_a_list)
! 	string_t	*name;
! 	type_t		*type;
  	int		is_a_list;
  {
  	indent_printf("str_free(this->%s);\n", name->str_text);
--- 57,68 ----
  }
  
  
! static void gen_free_declarator _((type_ty *, string_ty *, int));
  
  static void
  gen_free_declarator(type, name, is_a_list)
! 	string_ty	*name;
! 	type_ty		*type;
  	int		is_a_list;
  {
  	indent_printf("str_free(this->%s);\n", name->str_text);
***************
*** 69,75 ****
  }
  
  
! static type_method_t method =
  {
  	0, /* gen_include */
  	gen_include_declarator,
--- 69,75 ----
  }
  
  
! static type_method_ty method =
  {
  	0, /* gen_include */
  	gen_include_declarator,
***************
*** 79,90 ****
  };
  
  
! type_t *
  type_create_string()
  {
! 	type_t	*type;
  
! 	type = (type_t *)mem_alloc(sizeof(type_t));
  	type->class = type_class_string;
  	type->method = &method;
  	type->name = str_from_c("string");
--- 79,90 ----
  };
  
  
! type_ty *
  type_create_string()
  {
! 	type_ty		*type;
  
! 	type = (type_ty *)mem_alloc(sizeof(type_ty));
  	type->class = type_class_string;
  	type->method = &method;
  	type->name = str_from_c("string");
Index: fmtgen/type_struc.c
***************
*** 1,12 ****
  /*
   *	aegis - project change supervisor
!  *	Copyright (c) 1991-1992 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 1, or (at your option)
!  *	any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  /*
   *	aegis - project change supervisor
!  *	Copyright (C) 1991, 1992, 1993 Peter Miller.
   *	All rights reserved.
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License as published by
!  *	the Free Software Foundation; either version 2 of the License, or
!  *	(at your option) any later version.
   *
   *	This program is distributed in the hope that it will be useful,
   *	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 27,56 ****
  #include <error.h>
  
  
! typedef struct type_struct_t type_struct_t;
! struct type_struct_t
  {
  	/* inherited */
  	TYPE_T
  
  	/* instance variables */
! 	parse_list_t	*list;
  	int		toplevel;
  };
  
  
! static void gen_include _((type_t *, string_t *));
  
  static void
  gen_include(type, name)
! 	type_t		*type;
! 	string_t	*name;
  {
! 	parse_list_t	*np;
! 	type_struct_t	*type2;
  	int		bitno;
  
! 	type2 = (type_struct_t *)type;
  	indent_putchar('\n');
  	indent_printf("#ifndef %s_DEF\n", name->str_text);
  	indent_printf("#define %s_DEF\n", name->str_text);
--- 27,56 ----
  #include <error.h>
  
  
! typedef struct type_struct_ty type_struct_ty;
! struct type_struct_ty
  {
  	/* inherited */
  	TYPE_T
  
  	/* instance variables */
! 	parse_list_ty	*list;
  	int		toplevel;
  };
  
  
! static void gen_include _((type_ty *, string_ty *));
  
  static void
  gen_include(type, name)
! 	type_ty		*type;
! 	string_ty	*name;
  {
! 	parse_list_ty	*np;
! 	type_struct_ty	*type2;
  	int		bitno;
  
! 	type2 = (type_struct_ty *)type;
  	indent_putchar('\n');
  	indent_printf("#ifndef %s_DEF\n", name->str_text);
  	indent_printf("#define %s_DEF\n", name->str_text);
***************
*** 72,78 ****
  	indent_printf("%s\1mask;\n", "unsigned long");
  	for (np = type2->list; np; np = np->next)
  	{
! 		type_t		*tp;
  
  		if (!id_search(np->name, ID_CLASS_FIELD, (long *)&tp))
  			fatal("field \"%s\" vanished!", np->name->str_text);
--- 72,78 ----
  	indent_printf("%s\1mask;\n", "unsigned long");
  	for (np = type2->list; np; np = np->next)
  	{
! 		type_ty		*tp;
  
  		if (!id_search(np->name, ID_CLASS_FIELD, (long *)&tp))
  			fatal("field \"%s\" vanished!", np->name->str_text);
***************
*** 82,88 ****
  	indent_printf("#endif /* %s_DEF */\n", name->str_text);
  
  	indent_putchar('\n');
! 	indent_printf("extern type_t %s_type;\n", name->str_text);
  
  	indent_putchar('\n');
  	if (type2->toplevel)
--- 82,88 ----
  	indent_printf("#endif /* %s_DEF */\n", name->str_text);
  
  	indent_putchar('\n');
! 	indent_printf("extern type_ty %s_type;\n", name->str_text);
  
  	indent_putchar('\n');
  	if (type2->toplevel)
***************
*** 92,103 ****
  }
  
  
! static void gen_include_declarator _((type_t *, string_t *, int));
  
  static void
  gen_include_declarator(type, name, is_a_list)
! 	type_t		*type;
! 	string_t	*name;
  	int		is_a_list;
  {
  	char		*deref;
--- 92,103 ----
  }
  
  
! static void gen_include_declarator _((type_ty *, string_ty *, int));
  
  static void
  gen_include_declarator(type, name, is_a_list)
! 	type_ty		*type;
! 	string_ty	*name;
  	int		is_a_list;
  {
  	char		*deref;
***************
*** 107,121 ****
  }
  
  
! static void gen_code _((type_t *, string_t *));
  
  static void
  gen_code(type, name)
! 	type_t		*type;
! 	string_t	*name;
  {
! 	parse_list_t	*np;
! 	type_struct_t	*type2;
  	static int	done_table;
  	static int	done_offsetof;
  
--- 107,121 ----
  }
  
  
! static void gen_code _((type_ty *, string_ty *));
  
  static void
  gen_code(type, name)
! 	type_ty		*type;
! 	string_ty	*name;
  {
! 	parse_list_ty	*np;
! 	type_struct_ty	*type2;
  	static int	done_table;
  	static int	done_offsetof;
  
***************
*** 131,137 ****
  		indent_printf("#endif\n");
  	}
  
! 	type2 = (type_struct_t *)type;
  	indent_putchar('\n');
  	indent_printf("void\n");
  	if (type2->toplevel)
--- 131,137 ----
  		indent_printf("#endif\n");
  	}
  
! 	type2 = (type_struct_ty *)type;
  	indent_putchar('\n');
  	indent_printf("void\n");
  	if (type2->toplevel)
***************
*** 162,168 ****
  	}
  	for (np = type2->list; np; np = np->next)
  	{
! 		type_t *tp;
  
  		id_search(np->name, ID_CLASS_FIELD, (long *)&tp);
  		type_gen_code_declarator(tp, np->name, 0);
--- 162,168 ----
  	}
  	for (np = type2->list; np; np = np->next)
  	{
! 		type_ty *tp;
  
  		id_search(np->name, ID_CLASS_FIELD, (long *)&tp);
  		type_gen_code_declarator(tp, np->name, 0);
***************
*** 185,196 ****
  	indent_printf("static void *\n");
  	indent_printf("%s_alloc()\n", name->str_text);
  	indent_printf("{\n"/*}*/);
! 	indent_printf("%s\1*addr;\n", "void");
  	indent_putchar('\n');
  	indent_printf("trace((\"%s_alloc()\\n{\\n\"/*}*/));\n", name->str_text);
! 	indent_printf("addr = (struct %s *)mem_alloc_clear(sizeof(struct %s));\n", name->str_text, name->str_text);
! 	indent_printf("trace((/*{*/\"return %%08lX;\\n}\\n\", addr));\n");
! 	indent_printf("return addr;\n");
  	indent_printf(/*{*/"}\n");
  
  	indent_putchar('\n');
--- 185,200 ----
  	indent_printf("static void *\n");
  	indent_printf("%s_alloc()\n", name->str_text);
  	indent_printf("{\n"/*}*/);
! 	indent_printf("%s\1*result;\n", "void");
  	indent_putchar('\n');
  	indent_printf("trace((\"%s_alloc()\\n{\\n\"/*}*/));\n", name->str_text);
! 	indent_printf
! 	(
! 		"result = (void *)mem_alloc_clear(sizeof(struct %s));\n",
! 		name->str_text
! 	);
! 	indent_printf("trace((/*{*/\"return %%08lX;\\n}\\n\", (long)result));\n");
! 	indent_printf("return result;\n");
  	indent_printf(/*{*/"}\n");
  
  	indent_putchar('\n');
***************
*** 212,218 ****
  	indent_printf("trace((\"%s_free(this = %%08lX)\\n{\\n\"/*}*/, this));\n", name->str_text);
  	for (np = type2->list; np; np = np->next)
  	{
! 		type_t		*tp;
  
  		id_search(np->name, ID_CLASS_FIELD, (long *)&tp);
  		type_gen_free_declarator(tp, np->name, 0);
--- 216,222 ----
  	indent_printf("trace((\"%s_free(this = %%08lX)\\n{\\n\"/*}*/, this));\n", name->str_text);
  	for (np = type2->list; np; np = np->next)
  	{
! 		type_ty		*tp;
  
  		id_search(np->name, ID_CLASS_FIELD, (long *)&tp);
  		type_gen_free_declarator(tp, np->name, 0);
***************
*** 229,237 ****
  		indent_printf("{\n");
  		indent_printf("%s\1*name;\n", "char");
  		indent_printf("%s\1offset;\n", "size_t");
! 		indent_printf("%s\1*type;\n", "type_t");
  		indent_printf("%s\1mask;\n", "unsigned long");
! 		indent_printf("%s\1*fast_name;\n", "string_t");
  		indent_printf("};\n");
  		done_table = 1;
  	}
--- 233,241 ----
  		indent_printf("{\n");
  		indent_printf("%s\1*name;\n", "char");
  		indent_printf("%s\1offset;\n", "size_t");
! 		indent_printf("%s\1*type;\n", "type_ty");
  		indent_printf("%s\1mask;\n", "unsigned long");
! 		indent_printf("%s\1*fast_name;\n", "string_ty");
  		indent_printf("};\n");
  		done_table = 1;
  	}
***************
*** 239,245 ****
  	indent_putchar('\n');
  	indent_printf
  	(
! 		"static int %s_parse _((void *, string_t *, type_t **,\n\
  void **, unsigned long *));\n",
  		name->str_text
  	);
--- 243,249 ----
  	indent_putchar('\n');
  	indent_printf
  	(
! 		"static int %s_parse _((void *, string_ty *, type_ty **,\n\
  void **, unsigned long *));\n",
  		name->str_text
  	);
***************
*** 249,256 ****
  	indent_printf("%s_parse(that, name, type_pp, addr_p, mask_p)\n", name->str_text);
  	indent_more();
  	indent_printf("%s\1*that;\n", "void");
! 	indent_printf("%s\1*name;\n", "string_t");
! 	indent_printf("%s\1**type_pp;\n", "type_t");
  	indent_printf("%s\1**addr_p;\n", "void");
  	indent_printf("%s\1*mask_p;\n", "unsigned long");
  	indent_less();
--- 253,260 ----
  	indent_printf("%s_parse(that, name, type_pp, addr_p, mask_p)\n", name->str_text);
  	indent_more();
  	indent_printf("%s\1*that;\n", "void");
! 	indent_printf("%s\1*name;\n", "string_ty");
! 	indent_printf("%s\1**type_pp;\n", "type_ty");
  	indent_printf("%s\1**addr_p;\n", "void");
  	indent_printf("%s\1*mask_p;\n", "unsigned long");
  	indent_less();
***************
*** 259,265 ****
  	indent_printf("{\n"/*}*/);
  	for (np = type2->list; np; np = np->next)
  	{
! 		type_t		*tp;
  
  		id_search(np->name, ID_CLASS_FIELD, (long *)&tp);
  		indent_printf("{\n"/*}*/);
--- 263,269 ----
  	indent_printf("{\n"/*}*/);
  	for (np = type2->list; np; np = np->next)
  	{
! 		type_ty		*tp;
  
  		id_search(np->name, ID_CLASS_FIELD, (long *)&tp);
  		indent_printf("{\n"/*}*/);
***************
*** 298,304 ****
  	indent_printf("{\n"/*}*/);
  	indent_printf("*type_pp = tp->type;\n");
  	indent_printf("trace_pointer(*type_pp);\n");
! 	indent_printf("*addr_p = (char *)this + tp->offset;\n");
  	indent_printf("trace_pointer(*addr_p);\n");
  	indent_printf("*mask_p = tp->mask;\n");
  	indent_printf("result = 0;\n");
--- 302,308 ----
  	indent_printf("{\n"/*}*/);
  	indent_printf("*type_pp = tp->type;\n");
  	indent_printf("trace_pointer(*type_pp);\n");
! 	indent_printf("*addr_p = (void *)((char *)this + tp->offset);\n");
  	indent_printf("trace_pointer(*addr_p);\n");
  	indent_printf("*mask_p = tp->mask;\n");
  	indent_printf("result = 0;\n");
***************
*** 310,316 ****
  	indent_printf(/*{*/"}\n");
  
  	indent_putchar('\n');
! 	indent_printf("type_t %s_type =\n", name->str_text);
  	indent_printf("{\n"/*}*/);
  	indent_printf("type_class_struct,\n");
  	indent_printf("\"%s\",\n", name->str_text);
--- 314,320 ----
  	indent_printf(/*{*/"}\n");
  
  	indent_putchar('\n');
! 	indent_printf("type_ty %s_type =\n", name->str_text);
  	indent_printf("{\n"/*}*/);
  	indent_printf("type_class_struct,\n");
  	indent_printf("\"%s\",\n", name->str_text);
***************
*** 323,334 ****
  }
  
  
! static void gen_code_declarator _((type_t *, string_t *, int));
  
  static void
  gen_code_declarator(type, name, is_a_list)
! 	type_t		*type;
! 	string_t	*name;
  	int		is_a_list;
  {
  	indent_printf("%s_write("/*)*/, type->name->str_text);
--- 327,338 ----
  }
  
  
! static void gen_code_declarator _((type_ty *, string_ty *, int));
  
  static void
  gen_code_declarator(type, name, is_a_list)
! 	type_ty		*type;
! 	string_ty	*name;
  	int		is_a_list;
  {
  	indent_printf("%s_write("/*)*/, type->name->str_text);
***************
*** 340,351 ****
  }
  
  
! static void gen_free_declarator _((type_t *, string_t *, int));
  
  static void
  gen_free_declarator(type, name, is_a_list)
! 	type_t		*type;
! 	string_t	*name;
  	int		is_a_list;
  {
  	indent_printf("%s_free(this->%s);\n", type->name->str_text, name->str_text);
--- 344,355 ----
  }
  
  
! static void gen_free_declarator _((type_ty *, string_ty *, int));
  
  static void
  gen_free_declarator(type, name, is_a_list)
! 	type_ty		*type;
! 	string_ty	*name;
  	int		is_a_list;
  {
  	indent_printf("%s_free(this->%s);\n", type->name->str_text, name->str_text);
***************
*** 352,358 ****
  }
  
  
! static type_method_t method =
  {
  	gen_include,
  	gen_include_declarator,
--- 356,362 ----
  }
  
  
! static type_method_ty method =
  {
  	gen_include,
  	gen_include_declarator,
***************
*** 362,376 ****
  };
  
  
! type_t *
  type_create_struct(name, list, toplevel)
! 	string_t	*name;
! 	parse_list_t	*list;
  	int		toplevel;
  {
! 	type_struct_t	*type;
  
! 	type = (type_struct_t *)mem_alloc(sizeof(type_struct_t));
  	type->class = type_class_struct;
  	type->method = &method;
  	type->name = str_copy(name);
--- 366,380 ----
  };
  
  
! type_ty *
  type_create_struct(name, list, toplevel)
! 	string_ty	*name;
! 	parse_list_ty	*list;
  	int		toplevel;
  {
! 	type_struct_ty	*type;
  
! 	type = (type_struct_ty *)mem_alloc(sizeof(type_struct_ty));
  	type->class = type_class_struct;
  	type->method = &method;
  	type->name = str_copy(name);
***************
*** 377,381 ****
  	type->list = list;
  	type->toplevel = toplevel;
  	id_assign(name, ID_CLASS_TYPE, (long)type);
! 	return (type_t *)type;
  }
--- 381,385 ----
  	type->list = list;
  	type->toplevel = toplevel;
  	id_assign(name, ID_CLASS_TYPE, (long)type);
! 	return (type_ty *)type;
  }
Index: h/dirent.h
***************
*** 0 ****
--- 1,34 ----
+ /*
+  *	aegis - project change supervisor
+  *	Copyright (C) 1993 Peter Miller.
+  *	All rights reserved.
+  *
+  *	This program is free software; you can redistribute it and/or modify
+  *	it under the terms of the GNU General Public License as published by
+  *	the Free Software Foundation; either version 2 of the License, or
+  *	(at your option) any later version.
+  *
+  *	This program is distributed in the hope that it will be useful,
+  *	but WITHOUT ANY WARRANTY; without even the implied warranty of
+  *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  *	GNU General Public License for more details.
+  *
+  *	You should have received a copy of the GNU General Public License
+  *	along with this program; if not, write to the Free Software
+  *	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+  *
+  * MANIFEST: minimal replacement for dirent.h
+  */
+ 
+ #ifndef H_DIRENT_H
+ #define H_DIRENT_H
+ 
+ #ifdef apollo
+ #include <sys/dir.h>
+ #else
+ #include <direct.h>
+ #endif
+ 
+ #define direct dirent
+ 
+ #endif /* H_DIRENT_H */
Index: h/stdarg.h-min
***************
*** 1,5 ****
  /*
!  * This stadrg.h works for simple machines, such as 68K or 386.
   * It assumes the stack grows downwards, and that no arguments are
   * stored in registers.
   *
--- 1,5 ----
  /*
!  * This stdarg.h works for simple machines, such as 68K or 386.
   * It assumes the stack grows downwards, and that no arguments are
   * stored in registers.
   *
Index: h/unistd.h
***************
*** 0 ****
--- 1,104 ----
+ /*
+  *	aegis - project change supervisor
+  *
+  * MANIFEST: minimal substitute for unistd.h
+  */
+ 
+ #ifndef UNISTD_H
+ #define UNISTD_H
+ 
+ #ifndef NULL
+ #define	NULL 0
+ #endif
+ 
+ #ifndef SEEK_SET
+ #define	SEEK_SET 0
+ #define	SEEK_CUR 1
+ #define	SEEK_END 2
+ #endif
+ 
+ #ifndef F_OK
+ #define	F_OK 0
+ #define	X_OK 1
+ #define	W_OK 2
+ #define	R_OK 4
+ #endif
+ 
+ void _exit();
+ int access();
+ int acct();
+ unsigned alarm();
+ int brk();
+ int chroot();
+ int chdir();
+ int chmod();
+ int chown();
+ int close();
+ char *ctermid();
+ char *cuserid();
+ int dup();
+ int dup2();
+ int execl();
+ int execle();
+ int execlp();
+ int execv();
+ int execve();
+ int execvp();
+ void exit();
+ int fchdir();
+ int fchown();
+ pid_t fork();
+ long fpathconf();
+ int fsync();
+ int ftruncate();
+ char *getcwd();
+ gid_t getegid();
+ uid_t geteuid();
+ gid_t getgid();
+ int getgroups();
+ char *getlogin();
+ pid_t getpgrp();
+ pid_t getpid();
+ pid_t getppid();
+ pid_t getsid();
+ uid_t getuid();
+ int ioctl();
+ int isatty();
+ int lchown();
+ int link();
+ int lockf();
+ off_t lseek();
+ int mincore();
+ int nice();
+ long pathconf();
+ int pause();
+ int pipe();
+ void profil();
+ int ptrace();
+ int read();
+ int readlink();
+ int rmdir();
+ void *sbrk();
+ int setgid();
+ int setegid();
+ int setgroups();
+ int setpgid();
+ int setpgrp();
+ pid_t setsid();
+ int setuid();
+ int seteuid();
+ int symlink();
+ void sync();
+ unsigned sleep();
+ long sysconf();
+ pid_t tcgetpgrp();
+ int tcsetpgrp();
+ int truncate();
+ char *ttyname();
+ int unlink();
+ int vfork();
+ int wait();
+ int waitpid();
+ int write();
+ 
+ #endif /* UNISTD_H */
Index: h/utime.h
***************
*** 0 ****
--- 1,32 ----
+ /*
+  *	aegis - project change supervisor
+  *	Copyright (C) 1993 Peter Miller.
+  *	All rights reserved.
+  *
+  *	This program is free software; you can redistribute it and/or modify
+  *	it under the terms of the GNU General Public License as published by
+  *	the Free Software Foundation; either version 2 of the License, or
+  *	(at your option) any later version.
+  *
+  *	This program is distributed in the hope that it will be useful,
+  *	but WITHOUT ANY WARRANTY; without even the implied warranty of
+  *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  *	GNU General Public License for more details.
+  *
+  *	You should have received a copy of the GNU General Public License
+  *	along with this program; if not, write to the Free Software
+  *	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+  *
+  * MANIFEST: minimal replacement for utime.h
+  */
+ 
+ #ifndef H_UTIME_H
+ #define H_UTIME_H
+ 
+ struct utimbuf
+ {
+ 	long	actime;
+ 	long	modtime;
+ };
+ 
+ #endif /* H_UTIME_H */
Index: lib/cshrc
***************
*** 0 ****
--- 1,62 ----
+ #
+ #	aegis - project change supervisor
+ #	Copyright (C) 1991, 1992, 1993 Peter Miller.
+ #	All rights reserved.
+ #
+ #	This program is free software; you can redistribute it and/or modify
+ #	it under the terms of the GNU General Public License as published by
+ #	the Free Software Foundation; either version 2 of the License, or
+ #	(at your option) any later version.
+ #
+ #	This program is distributed in the hope that it will be useful,
+ #	but WITHOUT ANY WARRANTY; without even the implied warranty of
+ #	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ #	GNU General Public License for more details.
+ #
+ #	You should have received a copy of the GNU General Public License
+ #	along with this program; if not, write to the Free Software
+ #	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ #
+ # MANIFEST: csh user config for aegis
+ #
+ setenv AEGIS $HOME/lib/aegis
+ alias	aea	'aegis -a \!* -v'
+ alias	aeb	'aegis -b \!* -v'
+ alias	aeca	'aegis -ca \!* -v'
+ alias	aecd	'cd `aegis -cd \!* -v`'
+ alias	aecp	'aegis -cp \!* -v'
+ alias	aecpu	'aegis -cpu \!* -v'
+ alias	aed	'aegis -diff \!* -v'
+ alias	aedb	'aegis -db \!* -v'
+ alias	aedbu	'aegis -dbu \!* -v'
+ alias	aede	'aegis -de \!* -v'
+ alias	aedeu	'aegis -deu \!* -v'
+ alias	aedless	less `find . -name "*,D" -print | sort`
+ alias	aedmore	more `find . -name "*,D" -print | sort`
+ alias	aega	'aegis -ga \!* -v'
+ alias	aeib	'aegis -ib \!* -v'
+ alias	aeibu	'aegis -ibu \!* -v'
+ alias	aeifail	'aegis -ifail \!* -v'
+ alias	aeipass	'aegis -ipass \!* -v'
+ alias	ael	'aegis -l \!* -v'
+ alias	aena	'aegis -na \!* -v'
+ alias	aenc	'aegis -nc \!* -v'
+ alias	aend	'aegis -nd \!* -v'
+ alias	aenf	'aegis -nf \!* -v'
+ alias	aenfu	'aegis -nfu \!* -v'
+ alias	aeni	'aegis -ni \!* -v'
+ alias	aenpr	'aegis -npr \!* -v'
+ alias	aenrls	'aegis -nrls \!* -v'
+ alias	aenrv	'aegis -nrv \!* -v'
+ alias	aent	'aegis -nt \!* -v'
+ alias	aepa	'aegis -pa \!* -v'
+ alias	aera	'aegis -ra \!* -v'
+ alias	aerd	'aegis -rd \!* -v'
+ alias	aerfail	'aegis -rfail \!* -v'
+ alias	aeri	'aegis -ri \!* -v'
+ alias	aerm	'aegis -rm \!* -v'
+ alias	aermu	'aegis -rmu \!* -v'
+ alias	aerpass	'aegis -rpass \!* -v'
+ alias	aermpr	'aegis -rmpr \!* -v'
+ alias	aerrv	'aegis -rrv \!* -v'
+ alias	aet	'aegis -t \!* -v'
Index: lib/de.inews.sh
***************
*** 0 ****
--- 1,74 ----
+ #! /bin/sh
+ #
+ #	aegis - project change supervisor
+ #	Copyright (C) 1992, 1993 Peter Miller.
+ #	All rights reserved.
+ #
+ #	This program is free software; you can redistribute it and/or modify
+ #	it under the terms of the GNU General Public License as published by
+ #	the Free Software Foundation; either version 2 of the License, or
+ #	(at your option) any later version.
+ #
+ #	This program is distributed in the hope that it will be useful,
+ #	but WITHOUT ANY WARRANTY; without even the implied warranty of
+ #	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ #	GNU General Public License for more details.
+ #
+ #	You should have received a copy of the GNU General Public License
+ #	along with this program; if not, write to the Free Software
+ #	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ #
+ # MANIFEST: command used to notify by usenet that a change is ready for review
+ #
+ aegis=aegis
+ case $# in
+ 3)
+ 	project=$1
+ 	change=$2
+ 	newsgroups=$3
+ 	;;
+ 
+ *)
+ 	echo "Usage: $0 <project> <change> <newsgroups>" 1>&2
+ 	exit 1
+ 	;;
+ esac
+ 
+ tmp=/tmp/de.$$
+ trap "rm -f $tmp" 1 2 3 15
+ quit()
+ {
+ 	rm -f $tmp
+ 	exit 1
+ }
+ 
+ #
+ # build the notice
+ #
+ cat > $tmp << TheEnd
+ Subject: project $project, change $change, develop end
+ Newsgroups: $newsgroups
+ 
+ Development of the following change has been
+ completed and it is now ready for review.
+ 
+ TheEnd
+ if [ $? -ne 0 ]; then quit; fi
+ 
+ #
+ # include full details of the change
+ #
+ $aegis -list change_details -project $project -change $change -verbose >> $tmp
+ if [ $? -ne 0 ]; then quit; fi
+ 
+ #
+ # post on usenet
+ #
+ inews -h < $tmp
+ if [ $? -ne 0 ]; then quit; fi
+ 
+ #
+ # clean up and go home
+ #
+ rm $tmp
+ exit 0
Index: lib/de.sh
***************
*** 0 ****
--- 1,82 ----
+ #! /bin/sh
+ #
+ #	aegis - project change supervisor
+ #	Copyright (C) 1992, 1993 Peter Miller.
+ #	All rights reserved.
+ #
+ #	This program is free software; you can redistribute it and/or modify
+ #	it under the terms of the GNU General Public License as published by
+ #	the Free Software Foundation; either version 2 of the License, or
+ #	(at your option) any later version.
+ #
+ #	This program is distributed in the hope that it will be useful,
+ #	but WITHOUT ANY WARRANTY; without even the implied warranty of
+ #	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ #	GNU General Public License for more details.
+ #
+ #	You should have received a copy of the GNU General Public License
+ #	along with this program; if not, write to the Free Software
+ #	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ #
+ # MANIFEST: command used to notify by email that a change is ready for review
+ #
+ aegis=aegis
+ case $# in
+ 3)
+ 	project=$1
+ 	change=$2
+ 	developer=$3
+ 	;;
+ 
+ *)
+ 	echo "Usage: $0 <project> <change> <developer>" 1>&2
+ 	exit 1
+ 	;;
+ esac
+ 
+ tmp=/tmp/de.$$
+ trap "rm -f $tmp" 1 2 3 15
+ quit()
+ {
+ 	rm -f $tmp
+ 	exit 1
+ }
+ 
+ #
+ # find out who the reviewers are
+ #
+ reviewers=`$aegis -list reviewers -project $project -terse`
+ if [ $? -ne 0 ]; then quit; fi
+ if [ "$reviewers" = "" ]
+ then
+ 	reviewers=`$aegis -list administrators -project $project -terse`
+ 	if [ $? -ne 0 ]; then quit; fi
+ fi
+ 
+ #
+ # build the notice to be mailed
+ #
+ cat > $tmp << 'TheEnd'
+ Development of the following change has been
+ completed and it is now ready for review.
+ 
+ TheEnd
+ if [ $? -ne 0 ]; then quit; fi
+ 
+ #
+ # include full details of the change
+ #
+ $aegis -list change_details -project $project -change $change -verbose >> $tmp
+ if [ $? -ne 0 ]; then quit; fi
+ 
+ #
+ # mail it to all reviewers
+ #
+ mail $reviewers < $tmp
+ if [ $? -ne 0 ]; then quit; fi
+ 
+ #
+ # clean up and go home
+ #
+ rm $tmp
+ exit 0
Index: lib/deu.inews.sh
***************
*** 0 ****
--- 1,74 ----
+ #! /bin/sh
+ #
+ #	aegis - project change supervisor
+ #	Copyright (C) 1992, 1993 Peter Miller.
+ #	All rights reserved.
+ #
+ #	This program is free software; you can redistribute it and/or modify
+ #	it under the terms of the GNU General Public License as published by
+ #	the Free Software Foundation; either version 2 of the License, or
+ #	(at your option) any later version.
+ #
+ #	This program is distributed in the hope that it will be useful,
+ #	but WITHOUT ANY WARRANTY; without even the implied warranty of
+ #	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ #	GNU General Public License for more details.
+ #
+ #	You should have received a copy of the GNU General Public License
+ #	along with this program; if not, write to the Free Software
+ #	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ #
+ # MANIFEST: command used to notify by usenet that a change has been withdrawn from review
+ #
+ aegis=aegis
+ case $# in
+ 3)
+ 	project=$1
+ 	change=$2
+ 	newsgroups=$3
+ 	;;
+ 
+ *)
+ 	echo "Usage: $0 <project> <change> <newsgroups>" 1>&2
+ 	exit 1
+ 	;;
+ esac
+ 
+ tmp=/tmp/de.$$
+ trap "rm -f $tmp" 1 2 3 15
+ quit()
+ {
+ 	rm -f $tmp
+ 	exit 1
+ }
+ 
+ #
+ # build the notice
+ #
+ cat > $tmp << TheEnd
+ Subject: project $project, change $change, develop end undo
+ Newsgroups: $newsgroups
+ 
+ The change described below is no longer available for review.
+ It has been withdrawn for further development.
+ 
+ TheEnd
+ if [ $? -ne 0 ]; then quit; fi
+ 
+ #
+ # include full details of the change
+ #
+ $aegis -list change_details -project $project -change $change -verbose >> $tmp
+ if [ $? -ne 0 ]; then quit; fi
+ 
+ #
+ # post on usenet
+ #
+ inews -h < $tmp
+ if [ $? -ne 0 ]; then quit; fi
+ 
+ #
+ # clean up and go home
+ #
+ rm $tmp
+ exit 0;
Index: lib/deu.sh
***************
*** 0 ****
--- 1,82 ----
+ #! /bin/sh
+ #
+ #	aegis - project change supervisor
+ #	Copyright (C) 1992, 1993 Peter Miller.
+ #	All rights reserved.
+ #
+ #	This program is free software; you can redistribute it and/or modify
+ #	it under the terms of the GNU General Public License as published by
+ #	the Free Software Foundation; either version 2 of the License, or
+ #	(at your option) any later version.
+ #
+ #	This program is distributed in the hope that it will be useful,
+ #	but WITHOUT ANY WARRANTY; without even the implied warranty of
+ #	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ #	GNU General Public License for more details.
+ #
+ #	You should have received a copy of the GNU General Public License
+ #	along with this program; if not, write to the Free Software
+ #	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ #
+ # MANIFEST: command used to notify by email that a change has been withdrawn from review
+ #
+ aegis=aegis
+ case $# in
+ 3)
+ 	project=$1
+ 	change=$2
+ 	developer=$3
+ 	;;
+ 
+ *)
+ 	echo "Usage: $0 <project> <change> <developer>" 1>&2
+ 	exit 1
+ 	;;
+ esac
+ 
+ tmp=/tmp/de.$$
+ trap "rm -f $tmp" 1 2 3 15
+ quit()
+ {
+ 	rm -f $tmp
+ 	exit 1
+ }
+ 
+ #
+ # find out who the reviewers are
+ #
+ reviewers=`$aegis -list reviewers -project $project -terse`
+ if [ $? -ne 0 ]; then quit; fi
+ if [ "$reviewers" = "" ]
+ then
+ 	reviewers=`$aegis -list integrators -project $project -terse`
+ 	if [ $? -ne 0 ]; then quit; fi
+ fi
+ 
+ #
+ # build the notice to be mailed
+ #
+ cat > $tmp << 'TheEnd'
+ The change described below is no longer available for review.
+ It has been withdrawn for further development.
+ 
+ TheEnd
+ if [ $? -ne 0 ]; then quit; fi
+ 
+ #
+ # include full details of the change
+ #
+ $aegis -list change_details -project $project -change $change -verbose >> $tmp
+ if [ $? -ne 0 ]; then quit; fi
+ 
+ #
+ # mail it to all reviewers
+ #
+ mail $reviewers < $tmp
+ if [ $? -ne 0 ]; then quit; fi
+ 
+ #
+ # clean up and go home
+ #
+ rm $tmp
+ exit 0;
Index: lib/if.inews.sh
***************
*** 0 ****
--- 1,74 ----
+ #! /bin/sh
+ #
+ #	aegis - project change supervisor
+ #	Copyright (C) 1992, 1993 Peter Miller.
+ #	All rights reserved.
+ #
+ #	This program is free software; you can redistribute it and/or modify
+ #	it under the terms of the GNU General Public License as published by
+ #	the Free Software Foundation; either version 2 of the License, or
+ #	(at your option) any later version.
+ #
+ #	This program is distributed in the hope that it will be useful,
+ #	but WITHOUT ANY WARRANTY; without even the implied warranty of
+ #	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ #	GNU General Public License for more details.
+ #
+ #	You should have received a copy of the GNU General Public License
+ #	along with this program; if not, write to the Free Software
+ #	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ #
+ # MANIFEST: command used to notify by usenet that a change failed integration
+ #
+ aegis=aegis
+ case $# in
+ 3)
+ 	project=$1
+ 	change=$2
+ 	newsgroups=$3
+ 	;;
+ 
+ *)
+ 	echo "Usage: $0 <project> <change> <newsgroups>" 1>&2
+ 	exit 1
+ 	;;
+ esac
+ 
+ tmp=/tmp/de.$$
+ trap "rm -f $tmp" 1 2 3 15
+ quit()
+ {
+ 	rm -f $tmp
+ 	exit 1
+ }
+ 
+ #
+ # build the notice
+ #
+ cat > $tmp << TheEnd
+ Subject: project $project, change $change, integrate fail
+ Newsgroups: $newsgroups
+ 
+ The change described below has failed integration.
+ It has been returned to the developer for further work.
+ 
+ TheEnd
+ if [ $? -ne 0 ]; then quit; fi
+ 
+ #
+ # include full details of the change
+ #
+ $aegis -list change_details -project $project -change $change -verbose >> $tmp
+ if [ $? -ne 0 ]; then quit; fi
+ 
+ #
+ # post on usenet
+ #
+ inews -h < $tmp
+ if [ $? -ne 0 ]; then quit; fi
+ 
+ #
+ # clean up and go home
+ #
+ rm $tmp
+ exit 0
Index: lib/if.sh
***************
*** 0 ****
--- 1,73 ----
+ #! /bin/sh
+ #
+ #	aegis - project change supervisor
+ #	Copyright (C) 1992, 1993 Peter Miller.
+ #	All rights reserved.
+ #
+ #	This program is free software; you can redistribute it and/or modify
+ #	it under the terms of the GNU General Public License as published by
+ #	the Free Software Foundation; either version 2 of the License, or
+ #	(at your option) any later version.
+ #
+ #	This program is distributed in the hope that it will be useful,
+ #	but WITHOUT ANY WARRANTY; without even the implied warranty of
+ #	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ #	GNU General Public License for more details.
+ #
+ #	You should have received a copy of the GNU General Public License
+ #	along with this program; if not, write to the Free Software
+ #	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ #
+ # MANIFEST: command used to notify by email that a change failed integration
+ #
+ aegis=aegis
+ case $# in
+ 5)
+ 	project=$1
+ 	change=$2
+ 	developer=$3
+ 	reviewer=$4
+ 	integrator=$5
+ 	;;
+ 
+ *)
+ 	echo "Usage: $0 <project> <change> <developer> <reviewer> <integrator>" 1>&2
+ 	exit 1
+ 	;;
+ esac
+ 
+ tmp=/tmp/de.$$
+ trap "rm -f $tmp" 1 2 3 15
+ quit()
+ {
+ 	rm -f $tmp
+ 	exit 1
+ }
+ 
+ #
+ # build the notice to be mailed
+ #
+ cat > $tmp << 'TheEnd'
+ The change described below has failed integration.
+ It has been returned to the developer for further work.
+ 
+ TheEnd
+ if [ $? -ne 0 ]; then quit; fi
+ 
+ #
+ # include full details of the change
+ #
+ $aegis -list change_details -project $project -change $change -verbose >> $tmp
+ if [ $? -ne 0 ]; then quit; fi
+ 
+ #
+ # mail it to the developer and the reviewer
+ #
+ mail $developer $reviewer < $tmp
+ if [ $? -ne 0 ]; then quit; fi
+ 
+ #
+ # clean up and go home
+ #
+ rm $tmp
+ exit 0
Index: lib/ip.inews.sh
***************
*** 0 ****
--- 1,74 ----
+ #! /bin/sh
+ #
+ #	aegis - project change supervisor
+ #	Copyright (C) 1992, 1993 Peter Miller.
+ #	All rights reserved.
+ #
+ #	This program is free software; you can redistribute it and/or modify
+ #	it under the terms of the GNU General Public License as published by
+ #	the Free Software Foundation; either version 2 of the License, or
+ #	(at your option) any later version.
+ #
+ #	This program is distributed in the hope that it will be useful,
+ #	but WITHOUT ANY WARRANTY; without even the implied warranty of
+ #	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ #	GNU General Public License for more details.
+ #
+ #	You should have received a copy of the GNU General Public License
+ #	along with this program; if not, write to the Free Software
+ #	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ #
+ # MANIFEST: command used to notify by usenet that a change has passed integration
+ #
+ aegis=aegis
+ case $# in
+ 3)
+ 	project=$1
+ 	change=$2
+ 	newsgroups=$3
+ 	;;
+ 
+ *)
+ 	echo "Usage: $0 <project> <change> <newsgroups>" 1>&2
+ 	exit 1
+ 	;;
+ esac
+ 
+ tmp=/tmp/de.$$
+ trap "rm -f $tmp" 1 2 3 15
+ quit()
+ {
+ 	rm -f $tmp
+ 	exit 1
+ }
+ 
+ #
+ # build the notice
+ #
+ cat > $tmp << TheEnd
+ Subject: project $project, change $change, integrate pass
+ Newsgroups: $newsgroups
+ 
+ The change described below has passed integration
+ and is now part of the baseline.
+ 
+ TheEnd
+ if [ $? -ne 0 ]; then quit; fi
+ 
+ #
+ # include full details of the change
+ #
+ $aegis -list change_details -project $project -change $change -verbose >> $tmp
+ if [ $? -ne 0 ]; then quit; fi
+ 
+ #
+ # post on usenet
+ #
+ inews -h < $tmp
+ if [ $? -ne 0 ]; then quit; fi
+ 
+ #
+ # clean up and go home
+ #
+ rm $tmp
+ exit 0
Index: lib/ip.sh
***************
*** 0 ****
--- 1,73 ----
+ #! /bin/sh
+ #
+ #	aegis - project change supervisor
+ #	Copyright (C) 1992, 1993 Peter Miller.
+ #	All rights reserved.
+ #
+ #	This program is free software; you can redistribute it and/or modify
+ #	it under the terms of the GNU General Public License as published by
+ #	the Free Software Foundation; either version 2 of the License, or
+ #	(at your option) any later version.
+ #
+ #	This program is distributed in the hope that it will be useful,
+ #	but WITHOUT ANY WARRANTY; without even the implied warranty of
+ #	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ #	GNU General Public License for more details.
+ #
+ #	You should have received a copy of the GNU General Public License
+ #	along with this program; if not, write to the Free Software
+ #	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ #
+ # MANIFEST: command used to notify by email that a change has passed integration
+ #
+ aegis=aegis
+ case $# in
+ 5)
+ 	project=$1
+ 	change=$2
+ 	developer=$3
+ 	reviewer=$4
+ 	intgrator=$5
+ 	;;
+ 
+ *)
+ 	echo "Usage: $0 <project> <change> <developer> <reviewer> <integrator>" 1>&2
+ 	exit 1
+ 	;;
+ esac
+ 
+ tmp=/tmp/de.$$
+ trap "rm -f $tmp" 1 2 3 15
+ quit()
+ {
+ 	rm -f $tmp
+ 	exit 1
+ }
+ 
+ #
+ # build the notice to be mailed
+ #
+ cat > $tmp << 'TheEnd'
+ The change described below has passed integration
+ and is now part of the baseline.
+ 
+ TheEnd
+ if [ $? -ne 0 ]; then quit; fi
+ 
+ #
+ # include full details of the change
+ #
+ $aegis -list change_details -project $project -change $change -verbose >> $tmp
+ if [ $? -ne 0 ]; then quit; fi
+ 
+ #
+ # mail it to the developer and the reviewer
+ #
+ mail $developer $reviewer < $tmp
+ if [ $? -ne 0 ]; then quit; fi
+ 
+ #
+ # clean up and go home
+ #
+ rm $tmp
+ exit 0
Index: lib/profile
***************
*** 0 ****
--- 1,183 ----
+ #
+ #	aegis - project change supervisor
+ #	Copyright (C) 1991, 1992, 1993 Peter Miller.
+ #	All rights reserved.
+ #
+ #	This program is free software; you can redistribute it and/or modify
+ #	it under the terms of the GNU General Public License as published by
+ #	the Free Software Foundation; either version 2 of the License, or
+ #	(at your option) any later version.
+ #
+ #	This program is distributed in the hope that it will be useful,
+ #	but WITHOUT ANY WARRANTY; without even the implied warranty of
+ #	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ #	GNU General Public License for more details.
+ #
+ #	You should have received a copy of the GNU General Public License
+ #	along with this program; if not, write to the Free Software
+ #	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ #
+ # MANIFEST: Bourne shell user config for aegis
+ #
+ AEGIS=$HOME/lib/aegis
+ export AEGIS
+ aea()
+ {
+ 	aegis -a $* -v
+ }
+ aeb()
+ {
+ 	aegis -b $* -v
+ }
+ aeca()
+ {
+ 	aegis -ca $* -v
+ }
+ aecd()
+ {
+ 	cd `aegis -cd $* -v`
+ }
+ aecp()
+ {
+ 	aegis -cp $* -v
+ }
+ aecpu()
+ {
+ 	aegis -cpu $* -v
+ }
+ aed()
+ {
+ 	aegis -diff $* -v
+ }
+ aedb()
+ {
+ 	aegis -db $* -v
+ }
+ aedbu()
+ {
+ 	aegis -dbu $* -v
+ }
+ aede()
+ {
+ 	aegis -de $* -v
+ }
+ aedeu()
+ {
+ 	aegis -deu $* -v
+ }
+ aedless()
+ {
+ 	less `find . -name "*,D" -print | sort`
+ }
+ aedmore()
+ {
+ 	more `find . -name "*,D" -print | sort`
+ }
+ aega()
+ {
+ 	aegis -ga $* -v
+ }
+ aeib()
+ {
+ 	aegis -ib $* -v
+ }
+ aeibu()
+ {
+ 	aegis -ibu $* -v
+ }
+ aeifail()
+ {
+ 	aegis -ifail $* -v
+ }
+ aeipass()
+ {
+ 	aegis -ipass $* -v
+ }
+ ael()
+ {
+ 	aegis -l $* -v
+ }
+ aena()
+ {
+ 	aegis -na $* -v
+ }
+ aenc()
+ {
+ 	aegis -nc $* -v
+ }
+ aend()
+ {
+ 	aegis -nd $* -v
+ }
+ aenf()
+ {
+ 	aegis -nf $* -v
+ }
+ aenfu()
+ {
+ 	aegis -nfu $* -v
+ }
+ aeni()
+ {
+ 	aegis -ni $* -v
+ }
+ aenpr()
+ {
+ 	aegis -npr $* -v
+ }
+ aenrls()
+ {
+ 	aegis -nrls $* -v
+ }
+ aenrv()
+ {
+ 	aegis -nrv $* -v
+ }
+ aent()
+ {
+ 	aegis -nt $* -v
+ }
+ aepa()
+ {
+ 	aegis -pa $* -v
+ }
+ aera()
+ {
+ 	aegis -ra $* -v
+ }
+ aerd()
+ {
+ 	aegis -rd $* -v
+ }
+ aerfail()
+ {
+ 	aegis -rfail $* -v
+ }
+ aeri()
+ {
+ 	aegis -ri $* -v
+ }
+ aerm()
+ {
+ 	aegis -rm $* -v
+ }
+ aermu()
+ {
+ 	aegis -rmu $* -v
+ }
+ aerpass()
+ {
+ 	aegis -rpass $* -v
+ }
+ aermpr()
+ {
+ 	aegis -rmpr $* -v
+ }
+ aerrv()
+ {
+ 	aegis -rrv $* -v
+ }
+ aet()
+ {
+ 	aegis -t $* -v
+ }
Index: lib/rf.inews.sh
***************
*** 0 ****
--- 1,74 ----
+ #! /bin/sh
+ #
+ #	aegis - project change supervisor
+ #	Copyright (C) 1992, 1993 Peter Miller.
+ #	All rights reserved.
+ #
+ #	This program is free software; you can redistribute it and/or modify
+ #	it under the terms of the GNU General Public License as published by
+ #	the Free Software Foundation; either version 2 of the License, or
+ #	(at your option) any later version.
+ #
+ #	This program is distributed in the hope that it will be useful,
+ #	but WITHOUT ANY WARRANTY; without even the implied warranty of
+ #	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ #	GNU General Public License for more details.
+ #
+ #	You should have received a copy of the GNU General Public License
+ #	along with this program; if not, write to the Free Software
+ #	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ #
+ # MANIFEST: command used to notify by usenet that a change failed review
+ #
+ aegis=aegis
+ case $# in
+ 3)
+ 	project=$1
+ 	change=$2
+ 	newsgroups3
+ 	;;
+ 
+ *)
+ 	echo "Usage: $0 <project> <change> <newsgroups>" 1>&2
+ 	exit 1
+ 	;;
+ esac
+ 
+ tmp=/tmp/de.$$
+ trap "rm -f $tmp" 1 2 3 15
+ quit()
+ {
+ 	rm -f $tmp
+ 	exit 1
+ }
+ 
+ #
+ # build the notice
+ #
+ cat > $tmp << TheEnd
+ Subject: project $project, change $change, review fail
+ Newsgroups: $newsgroups
+ 
+ The change described below has failed review.
+ It has been returned to the developer for further work.
+ 
+ TheEnd
+ if [ $? -ne 0 ]; then quit; fi
+ 
+ #
+ # include full details of the change
+ #
+ $aegis -list change_details -project $project -change $change -verbose >> $tmp
+ if [ $? -ne 0 ]; then quit; fi
+ 
+ #
+ # post on usenet
+ #
+ inews -h < $tmp
+ if [ $? -ne 0 ]; then quit; fi
+ 
+ #
+ # clean up and go home
+ #
+ rm $tmp
+ exit 0
Index: lib/rf.sh
***************
*** 0 ****
--- 1,72 ----
+ #! /bin/sh
+ #
+ #	aegis - project change supervisor
+ #	Copyright (C) 1992, 1993 Peter Miller.
+ #	All rights reserved.
+ #
+ #	This program is free software; you can redistribute it and/or modify
+ #	it under the terms of the GNU General Public License as published by
+ #	the Free Software Foundation; either version 2 of the License, or
+ #	(at your option) any later version.
+ #
+ #	This program is distributed in the hope that it will be useful,
+ #	but WITHOUT ANY WARRANTY; without even the implied warranty of
+ #	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ #	GNU General Public License for more details.
+ #
+ #	You should have received a copy of the GNU General Public License
+ #	along with this program; if not, write to the Free Software
+ #	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ #
+ # MANIFEST: command used to notify by email that a change failed review
+ #
+ aegis=aegis
+ case $# in
+ 4)
+ 	project=$1
+ 	change=$2
+ 	developer=$3
+ 	reviewer=$4
+ 	;;
+ 
+ *)
+ 	echo "Usage: $0 <project> <change> <developer> <reviewer>" 1>&2
+ 	exit 1
+ 	;;
+ esac
+ 
+ tmp=/tmp/de.$$
+ trap "rm -f $tmp" 1 2 3 15
+ quit()
+ {
+ 	rm -f $tmp
+ 	exit 1
+ }
+ 
+ #
+ # build the notice to be mailed
+ #
+ cat > $tmp << 'TheEnd'
+ The change described below has failed review.
+ It has been returned to the developer for further work.
+ 
+ TheEnd
+ if [ $? -ne 0 ]; then quit; fi
+ 
+ #
+ # include full details of the change
+ #
+ $aegis -list change_details -project $project -change $change -verbose >> $tmp
+ if [ $? -ne 0 ]; then quit; fi
+ 
+ #
+ # mail it to the developer
+ #
+ mail $developer < $tmp
+ if [ $? -ne 0 ]; then quit; fi
+ 
+ #
+ # clean up and go home
+ #
+ rm $tmp
+ exit 0
Index: lib/rp.inews.sh
***************
*** 0 ****
--- 1,74 ----
+ #! /bin/sh
+ #
+ #	aegis - project change supervisor
+ #	Copyright (C) 1992, 1993 Peter Miller.
+ #	All rights reserved.
+ #
+ #	This program is free software; you can redistribute it and/or modify
+ #	it under the terms of the GNU General Public License as published by
+ #	the Free Software Foundation; either version 2 of the License, or
+ #	(at your option) any later version.
+ #
+ #	This program is distributed in the hope that it will be useful,
+ #	but WITHOUT ANY WARRANTY; without even the implied warranty of
+ #	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ #	GNU General Public License for more details.
+ #
+ #	You should have received a copy of the GNU General Public License
+ #	along with this program; if not, write to the Free Software
+ #	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ #
+ # MANIFEST: command used to notify by usenet that a change has passed review
+ #
+ aegis=aegis
+ case $# in
+ 3)
+ 	project=$1
+ 	change=$2
+ 	newsgroups=$3
+ 	;;
+ 
+ *)
+ 	echo "Usage: $0 <project> <change> <newsgroups>" 1>&2
+ 	exit 1
+ 	;;
+ esac
+ 
+ tmp=/tmp/de.$$
+ trap "rm -f $tmp" 1 2 3 15
+ quit()
+ {
+ 	rm -f $tmp
+ 	exit 1
+ }
+ 
+ #
+ # build the notice
+ #
+ cat > $tmp << TheEnd
+ Subject: project $project, change $change, review pass
+ Newsgroups: $newsgroups
+ 
+ The change described below has passed review.
+ It is now awaiting integration.
+ 
+ TheEnd
+ if [ $? -ne 0 ]; then quit; fi
+ 
+ #
+ # include full details of the change
+ #
+ $aegis -list change_details -project $project -change $change -verbose >> $tmp
+ if [ $? -ne 0 ]; then quit; fi
+ 
+ #
+ # post on usenet
+ #
+ inews -h < $tmp
+ if [ $? -ne 0 ]; then quit; fi
+ 
+ #
+ # clean up and go home
+ #
+ rm $tmp
+ exit 0;
Index: lib/rp.sh
***************
*** 0 ****
--- 1,83 ----
+ #! /bin/sh
+ #
+ #	aegis - project change supervisor
+ #	Copyright (C) 1992, 1993 Peter Miller.
+ #	All rights reserved.
+ #
+ #	This program is free software; you can redistribute it and/or modify
+ #	it under the terms of the GNU General Public License as published by
+ #	the Free Software Foundation; either version 2 of the License, or
+ #	(at your option) any later version.
+ #
+ #	This program is distributed in the hope that it will be useful,
+ #	but WITHOUT ANY WARRANTY; without even the implied warranty of
+ #	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ #	GNU General Public License for more details.
+ #
+ #	You should have received a copy of the GNU General Public License
+ #	along with this program; if not, write to the Free Software
+ #	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ #
+ # MANIFEST: command used to notify by email that a change has passed review
+ #
+ aegis=aegis
+ case $# in
+ 4)
+ 	project=$1
+ 	change=$2
+ 	developer=$3
+ 	reviewer=$4
+ 	;;
+ 
+ *)
+ 	echo "Usage: $0 <project> <change> <developer> <reviewer>" 1>&2
+ 	exit 1
+ 	;;
+ esac
+ 
+ tmp=/tmp/de.$$
+ trap "rm -f $tmp" 1 2 3 15
+ quit()
+ {
+ 	rm -f $tmp
+ 	exit 1
+ }
+ 
+ #
+ # find out who the integrators are
+ #
+ integrators=`$aegis -list integrators -project $project -terse`
+ if [ $? -ne 0 ]; then quit; fi
+ if [ "$integrators" = "" ]
+ then
+ 	integrators=`$aegis -list administrators -project $project -terse`
+ 	if [ $? -ne 0 ]; then quit; fi
+ fi
+ 
+ #
+ # build the notice to be mailed
+ #
+ cat > $tmp << 'TheEnd'
+ The change described below has passed review.
+ It is now awaiting integration.
+ 
+ TheEnd
+ if [ $? -ne 0 ]; then quit; fi
+ 
+ #
+ # include full details of the change
+ #
+ $aegis -list change_details -project $project -change $change -verbose >> $tmp
+ if [ $? -ne 0 ]; then quit; fi
+ 
+ #
+ # mail it to the developer and all integrators
+ #
+ mail $developer $integrators < $tmp
+ if [ $? -ne 0 ]; then quit; fi
+ 
+ #
+ # clean up and go home
+ #
+ rm $tmp
+ exit 0;
Index: lib/rpu.inews.sh
***************
*** 0 ****
--- 1,74 ----
+ #! /bin/sh
+ #
+ #	aegis - project change supervisor
+ #	Copyright (C) 1992, 1993 Peter Miller.
+ #	All rights reserved.
+ #
+ #	This program is free software; you can redistribute it and/or modify
+ #	it under the terms of the GNU General Public License as published by
+ #	the Free Software Foundation; either version 2 of the License, or
+ #	(at your option) any later version.
+ #
+ #	This program is distributed in the hope that it will be useful,
+ #	but WITHOUT ANY WARRANTY; without even the implied warranty of
+ #	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ #	GNU General Public License for more details.
+ #
+ #	You should have received a copy of the GNU General Public License
+ #	along with this program; if not, write to the Free Software
+ #	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ #
+ # MANIFEST: command used to notify by usenet that a change review passed is rescinded
+ #
+ aegis=aegis
+ case $# in
+ 3)
+ 	project=$1
+ 	change=$2
+ 	newsgroups=$3
+ 	;;
+ 
+ *)
+ 	echo "Usage: $0 <project> <change> <newsgroups>" 1>&2
+ 	exit 1
+ 	;;
+ esac
+ 
+ tmp=/tmp/de.$$
+ trap "rm -f $tmp" 1 2 3 15
+ quit()
+ {
+ 	rm -f $tmp
+ 	exit 1
+ }
+ 
+ #
+ # build the notice
+ #
+ cat > $tmp << TheEnd
+ Subject: project $project, change $change, review pass undo
+ Newsgroups: $newsgroups
+ 
+ The change described below has had its review
+ pass rescinded, pending further review.
+ 
+ TheEnd
+ if [ $? -ne 0 ]; then quit; fi
+ 
+ #
+ # include full details of the change
+ #
+ $aegis -list change_details -project $project -change $change -verbose >> $tmp
+ if [ $? -ne 0 ]; then quit; fi
+ 
+ #
+ # post on usenet
+ #
+ inews -h < $tmp
+ if [ $? -ne 0 ]; then quit; fi
+ 
+ #
+ # clean up and go home
+ #
+ rm $tmp
+ exit 0;
Index: lib/rpu.sh
***************
*** 0 ****
--- 1,82 ----
+ #! /bin/sh
+ #
+ #	aegis - project change supervisor
+ #	Copyright (C) 1992, 1993 Peter Miller.
+ #	All rights reserved.
+ #
+ #	This program is free software; you can redistribute it and/or modify
+ #	it under the terms of the GNU General Public License as published by
+ #	the Free Software Foundation; either version 2 of the License, or
+ #	(at your option) any later version.
+ #
+ #	This program is distributed in the hope that it will be useful,
+ #	but WITHOUT ANY WARRANTY; without even the implied warranty of
+ #	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ #	GNU General Public License for more details.
+ #
+ #	You should have received a copy of the GNU General Public License
+ #	along with this program; if not, write to the Free Software
+ #	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ #
+ # MANIFEST: command used to notify by email that a change review passed is rescinded
+ #
+ aegis=aegis
+ case $# in
+ 3)
+ 	project=$1
+ 	change=$2
+ 	developer=$3
+ 	;;
+ 
+ *)
+ 	echo "Usage: $0 <project> <change> <developer>" 1>&2
+ 	exit 1
+ 	;;
+ esac
+ 
+ tmp=/tmp/de.$$
+ trap "rm -f $tmp" 1 2 3 15
+ quit()
+ {
+ 	rm -f $tmp
+ 	exit 1
+ }
+ 
+ #
+ # find out who the reviewers are
+ #
+ reviewers=`$aegis -list reviewers -project $project -terse`
+ if [ $? -ne 0 ]; then quit; fi
+ if [ "$reviewers" = "" ]
+ then
+ 	reviewers=`$aegis -list administrators -project $project -terse`
+ 	if [ $? -ne 0 ]; then quit; fi
+ fi
+ 
+ #
+ # build the notice to be mailed
+ #
+ cat > $tmp << 'TheEnd'
+ The change described below has had its review
+ pass rescinded, pending further review.
+ 
+ TheEnd
+ if [ $? -ne 0 ]; then quit; fi
+ 
+ #
+ # include full details of the change
+ #
+ $aegis -list change_details -project $project -change $change -verbose >> $tmp
+ if [ $? -ne 0 ]; then quit; fi
+ 
+ #
+ # mail it to the developer and all reviewers
+ #
+ mail $developer $reviewers < $tmp
+ if [ $? -ne 0 ]; then quit; fi
+ 
+ #
+ # clean up and go home
+ #
+ rm $tmp
+ exit 0;
Index: man1/aeb.1
***************
*** 1,12 ****
  '\" t
  .\"	aegis - project change supervisor
! .\"	Copyright (c) 1991-1992 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 1, or (at your option)
! .\"	any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  '\" t
  .\"	aegis - project change supervisor
! .\"	Copyright (C) 1991, 1992, 1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 2 of the License, or
! .\"	(at your option) any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 60,66 ****
  .I "\*(n) -Build"
  command was exectuted.
  .PP
! If the change is in the 'being_integrated' state,
  references to the development directory, above,
  should be read as the integration directory.
  Integration build commands are executed with the user and group
--- 60,68 ----
  .I "\*(n) -Build"
  command was exectuted.
  .PP
! If the change is in the
! .I "being integrated"
! state,
  references to the development directory, above,
  should be read as the integration directory.
  Integration build commands are executed with the user and group
***************
*** 69,74 ****
--- 71,77 ----
  it is not necessary for an integrator to log in as someone else,
  the project account for instance,
  in order to do an integration.
+ .so o_bld_lk.so
  .SH OPTIONS
  The following options are understood:
  .so o_change.so
***************
*** 91,96 ****
  the change is not assigned to the curent user.
  .br
  It is an error if
! the change is not in one of the 'being_developed' or 'being_integrated' states.
  .so z_exit.so
  .so z_cr.so
--- 94,103 ----
  the change is not assigned to the curent user.
  .br
  It is an error if
! the change is not in one of the
! .I "being developed"
! or
! .I "being integrated"
! states.
  .so z_exit.so
  .so z_cr.so
Index: man1/aeca.1
***************
*** 1,12 ****
  '\" t
  .\"	aegis - project change supervisor
! .\"	Copyright (c) 1991-1992 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 1, or (at your option)
! .\"	any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  '\" t
  .\"	aegis - project change supervisor
! .\"	Copyright (C) 1991, 1992, 1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 2 of the License, or
! .\"	(at your option) any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
Index: man1/aecd.1
***************
*** 1,12 ****
  '\" t
  .\"	aegis - project change supervisor
! .\"	Copyright (c) 1991-1992 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 1, or (at your option)
! .\"	any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  '\" t
  .\"	aegis - project change supervisor
! .\"	Copyright (C) 1991, 1992, 1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 2 of the License, or
! .\"	(at your option) any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
Index: man1/aecp.1
***************
*** 1,11 ****
  .\"	aegis - project change supervisor
! .\"	Copyright (c) 1991-1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 1, or (at your option)
! .\"	any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
+ '\" t
  .\"	aegis - project change supervisor
! .\"	Copyright (C) 1991, 1992, 1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 2 of the License, or
! .\"	(at your option) any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 51,56 ****
--- 52,64 ----
  The named files will be copied from the baseline into
  the development directory,
  and added to the list of files in the change.
+ .PP
+ This command will cancel any build or test registrations,
+ because adding another file logically invalidates them.
+ If the
+ .I config
+ file was added,
+ any diff registration will also be cancelled.
  .SH OPTIONS
  The following options are understood:
  .so o_anticip.so
***************
*** 86,92 ****
  .fi
  .SH ERRORS
  It is an error if
! the change is not in the 'being_developed' state.
  .br
  It is an error if
  the change is not assigned to the current user.
--- 94,102 ----
  .fi
  .SH ERRORS
  It is an error if
! the change is not in the
! .I "being developed"
! state.
  .br
  It is an error if
  the change is not assigned to the current user.
Index: man1/aecpu.1
***************
*** 1,12 ****
  '\" t
  .\"	aegis - project change supervisor
! .\"	Copyright (c) 1991-1992 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 1, or (at your option)
! .\"	any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  '\" t
  .\"	aegis - project change supervisor
! .\"	Copyright (C) 1991, 1992, 1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 2 of the License, or
! .\"	(at your option) any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 60,65 ****
--- 60,72 ----
  as you can confuse tools such as
  .IR make (1)
  by leaving these files in place.
+ .PP
+ This command will cancel any build or test registrations,
+ because deleting a file logically invalidates them.
+ If the
+ .I config
+ file was deleted,
+ any diff registration will also be cancelled.
  .SH OPTIONS
  The following options are understood:
  .so o_change.so
***************
*** 78,84 ****
  .fi
  .SH ERRORS
  It is an error if
! the change is not in the 'being_developed' state.
  .br
  It is an error if
  the change is not assigned to the current user.
--- 85,93 ----
  .fi
  .SH ERRORS
  It is an error if
! the change is not in the
! .I "being developed"
! state.
  .br
  It is an error if
  the change is not assigned to the current user.
Index: man1/aed.1
***************
*** 1,12 ****
  '\" t
  .\"	aegis - project change supervisor
! .\"	Copyright (c) 1991-1992 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 1, or (at your option)
! .\"	any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  '\" t
  .\"	aegis - project change supervisor
! .\"	Copyright (C) 1991, 1992, 1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 2 of the License, or
! .\"	(at your option) any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
Index: man1/aedb.1
***************
*** 1,12 ****
  '\" t
  .\"	aegis - project change supervisor
! .\"	Copyright (c) 1991-1992 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 1, or (at your option)
! .\"	any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  '\" t
  .\"	aegis - project change supervisor
! .\"	Copyright (C) 1991, 1992, 1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 2 of the License, or
! .\"	(at your option) any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 49,58 ****
  commence development of a change.
  .PP
  The development directory for the change will be created automatically;
! below the directory specified in the default_development_directory of
  .IR aeuconf (5),
  or if not set
! below the directory specified in the default_development_directory of
  .IR aepattr (5),
  or if not set
  below the current user's home directory.
--- 49,58 ----
  commence development of a change.
  .PP
  The development directory for the change will be created automatically;
! below the directory specified in the default_\%development_\%directory field of
  .IR aeuconf (5),
  or if not set
! below the directory specified in the default_\%development_\%directory field of
  .IR aepattr (5),
  or if not set
  below the current user's home directory.
***************
*** 62,69 ****
  command can take you there at any time.
  .PP
  Successful execution of this command will move the
! specified change from the 'awaiting_development' state
! to the 'being_developed' state.
  .SH OPTIONS
  The following options are understood:
  .so o_change.so
--- 62,72 ----
  command can take you there at any time.
  .PP
  Successful execution of this command will move the
! specified change from the
! .I "awaiting development"
! state to the
! .I "being developed"
! state.
  .SH OPTIONS
  The following options are understood:
  .so o_change.so
***************
*** 86,92 ****
  the change does not exist.
  .br
  It is an error if
! the change is not in the 'awaiting_development' state.
  .br
  It is an error if
  the current user is not a developer of the specified project.
--- 89,97 ----
  the change does not exist.
  .br
  It is an error if
! the change is not in the
! .I "awaiting development"
! state.
  .br
  It is an error if
  the current user is not a developer of the specified project.
Index: man1/aedbu.1
***************
*** 1,12 ****
  '\" t
  .\"	aegis - project change supervisor
! .\"	Copyright (c) 1991-1992 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 1, or (at your option)
! .\"	any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  '\" t
  .\"	aegis - project change supervisor
! .\"	Copyright (C) 1991, 1992, 1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 2 of the License, or
! .\"	(at your option) any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
Index: man1/aede.1
***************
*** 1,12 ****
  '\" t
  .\"	aegis - project change supervisor
! .\"	Copyright (c) 1991-1992 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 1, or (at your option)
! .\"	any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  '\" t
  .\"	aegis - project change supervisor
! .\"	Copyright (C) 1991, 1992, 1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 2 of the License, or
! .\"	(at your option) any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
Index: man1/aedeu.1
***************
*** 1,12 ****
  '\" t
  .\"	aegis - project change supervisor
! .\"	Copyright (c) 1991-1992 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 1, or (at your option)
! .\"	any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  '\" t
  .\"	aegis - project change supervisor
! .\"	Copyright (C) 1991, 1992, 1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 2 of the License, or
! .\"	(at your option) any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
Index: man1/aegis.1
***************
*** 1,11 ****
  .\"	aegis - project change supervisor
! .\"	Copyright (c) 1991-1992 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 1, or (at your option)
! .\"	any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
+ .\"
  .\"	aegis - project change supervisor
! .\"	Copyright (C) 1991, 1992, 1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 2 of the License, or
! .\"	(at your option) any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 367,380 ****
  .IR aeri (1)
  for more information.
  .TP 8n
! .B -Remove_PRoject
  .br
  The 
! .I "\*(n) -Remove_PRoject"
  command is used to
  remove a project.
  See
! .IR aerpr (1)
  for more information.
  .TP 8n
  .B -Remove_ReViewer
--- 368,381 ----
  .IR aeri (1)
  for more information.
  .TP 8n
! .B -ReMove_PRoject
  .br
  The 
! .I "\*(n) -ReMove_PRoject"
  command is used to
  remove a project.
  See
! .IR aermpr (1)
  for more information.
  .TP 8n
  .B -Remove_ReViewer
Index: man1/aeib.1
***************
*** 1,12 ****
  '\" t
  .\"	aegis - project change supervisor
! .\"	Copyright (c) 1991-1992 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 1, or (at your option)
! .\"	any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  '\" t
  .\"	aegis - project change supervisor
! .\"	Copyright (C) 1991, 1992, 1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 2 of the License, or
! .\"	(at your option) any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
Index: man1/aeibu.1
***************
*** 1,12 ****
  '\" t
  .\"	aegis - project change supervisor
! .\"	Copyright (c) 1991-1992 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 1, or (at your option)
! .\"	any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  '\" t
  .\"	aegis - project change supervisor
! .\"	Copyright (C) 1991, 1992, 1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 2 of the License, or
! .\"	(at your option) any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
Index: man1/aeif.1
***************
*** 1,12 ****
  '\" t
  .\"	aegis - project change supervisor
! .\"	Copyright (c) 1991-1992 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 1, or (at your option)
! .\"	any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  '\" t
  .\"	aegis - project change supervisor
! .\"	Copyright (C) 1991, 1992, 1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 2 of the License, or
! .\"	(at your option) any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
Index: man1/aeip.1
***************
*** 1,12 ****
  '\" t
  .\"	aegis - project change supervisor
! .\"	Copyright (c) 1991-1992 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 1, or (at your option)
! .\"	any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  '\" t
  .\"	aegis - project change supervisor
! .\"	Copyright (C) 1991, 1992, 1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 2 of the License, or
! .\"	(at your option) any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 48,58 ****
  notify \*(n) that a change has passed integration.
  .PP
  The change is advanced
! from the 'being_integrated' state
! to the 'completed' state.
  The integration directory is renamed as the baseline directory,
  and the baseline directory is deleted.
  The change is no longer assigned to the current user.
  .SH OPTIONS
  The following options are understood:
  .so o_change.so
--- 48,62 ----
  notify \*(n) that a change has passed integration.
  .PP
  The change is advanced
! from the
! .I "being integrated"
! state to the
! .I "completed"
! state.
  The integration directory is renamed as the baseline directory,
  and the baseline directory is deleted.
  The change is no longer assigned to the current user.
+ .so o_bld_lk.so
  .SH OPTIONS
  The following options are understood:
  .so o_change.so
***************
*** 75,81 ****
  the change is not assigned to the current user.
  .br
  It is an error if
! The change is not in the 'being_integrated' state.
  .br
  It is an error if
  there has been no successful
--- 79,87 ----
  the change is not assigned to the current user.
  .br
  It is an error if
! The change is not in the
! .I "being integrated"
! state.
  .br
  It is an error if
  there has been no successful
Index: man1/ael.1
***************
*** 1,12 ****
  '\" t
  .\"	aegis - project change supervisor
! .\"	Copyright (c) 1991-1992 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 1, or (at your option)
! .\"	any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  '\" t
  .\"	aegis - project change supervisor
! .\"	Copyright (C) 1991, 1992, 1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 2 of the License, or
! .\"	(at your option) any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 99,104 ****
--- 99,112 ----
  Reviewers
  .br
  List the reviewers of a project.
+ .TP 8n
+ Users_Changes
+ .br
+ List of changes owned by the current user.
+ .TP 8n
+ Version
+ .br
+ List version of a project or change.
  .PP
  Most of these lists are available from other \*(n) functions.
  Many \*(n) functions provide more specific lists.
Index: man1/aena.1
***************
*** 1,12 ****
  '\" t
  .\"	aegis - project change supervisor
! .\"	Copyright (c) 1991-1992 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 1, or (at your option)
! .\"	any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  '\" t
  .\"	aegis - project change supervisor
! .\"	Copyright (C) 1991, 1992, 1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 2 of the License, or
! .\"	(at your option) any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
Index: man1/aenc.1
***************
*** 1,12 ****
  '\" t
  .\"	aegis - project change supervisor
! .\"	Copyright (c) 1991-1992 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 1, or (at your option)
! .\"	any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  '\" t
  .\"	aegis - project change supervisor
! .\"	Copyright (C) 1991, 1992, 1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 2 of the License, or
! .\"	(at your option) any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
Index: man1/aencu.1
***************
*** 1,12 ****
  '\" t
  .\"	aegis - project change supervisor
! .\"	Copyright (c) 1991-1992 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 1, or (at your option)
! .\"	any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  '\" t
  .\"	aegis - project change supervisor
! .\"	Copyright (C) 1991, 1992, 1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 2 of the License, or
! .\"	(at your option) any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
Index: man1/aend.1
***************
*** 1,12 ****
  '\" t
  .\"	aegis - project change supervisor
! .\"	Copyright (c) 1991-1992 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 1, or (at your option)
! .\"	any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  '\" t
  .\"	aegis - project change supervisor
! .\"	Copyright (C) 1991, 1992, 1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 2 of the License, or
! .\"	(at your option) any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
Index: man1/aenf.1
***************
*** 1,12 ****
  '\" t
  .\"	aegis - project change supervisor
! .\"	Copyright (c) 1991-1992 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 1, or (at your option)
! .\"	any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  '\" t
  .\"	aegis - project change supervisor
! .\"	Copyright (C) 1991, 1992, 1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 2 of the License, or
! .\"	(at your option) any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
Index: man1/aenfu.1
***************
*** 1,12 ****
  '\" t
  .\"	aegis - project change supervisor
! .\"	Copyright (c) 1991-1992 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 1, or (at your option)
! .\"	any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  '\" t
  .\"	aegis - project change supervisor
! .\"	Copyright (C) 1991, 1992, 1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 2 of the License, or
! .\"	(at your option) any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
Index: man1/aeni.1
***************
*** 1,12 ****
  '\" t
  .\"	aegis - project change supervisor
! .\"	Copyright (c) 1991-1992 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 1, or (at your option)
! .\"	any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  '\" t
  .\"	aegis - project change supervisor
! .\"	Copyright (C) 1991, 1992, 1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 2 of the License, or
! .\"	(at your option) any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
Index: man1/aenpr.1
***************
*** 1,12 ****
  '\" t
  .\"	aegis - project change supervisor
! .\"	Copyright (c) 1991-1992 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 1, or (at your option)
! .\"	any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  '\" t
  .\"	aegis - project change supervisor
! .\"	Copyright (C) 1991, 1992, 1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 2 of the License, or
! .\"	(at your option) any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 56,62 ****
  .B -DIRectory 
  option is not given,
  the project directory will be created in the
! directory specified by the default_project_directory of
  .IR aeuconf (5),
  or if not set
  in current user's home directory;
--- 56,62 ----
  .B -DIRectory 
  option is not given,
  the project directory will be created in the
! directory specified by the default_\%project_\%directory field of
  .IR aeuconf (5),
  or if not set
  in current user's home directory;
***************
*** 67,75 ****
  The current user is an administrator for the project.
  The project has no developers, reviewers, integrators or other administrators.
  .PP
! The project will be added to the first element of the search path.
  If this is inappropriate, use the
! -B -LIBrary
  option to explicitly set the desired location.
  See the
  .B -LIBrary
--- 67,78 ----
  The current user is an administrator for the project.
  The project has no developers, reviewers, integrators or other administrators.
  .PP
! The project pointer will be added to the first element of the search path,
! or
! .I /usr/local/lib/aegis
! if no path is set.
  If this is inappropriate, use the
! .B -LIBrary
  option to explicitly set the desired location.
  See the
  .B -LIBrary
Index: man1/aenrls.1
***************
*** 1,12 ****
  '\" t
  .\"	aegis - project change supervisor
! .\"	Copyright (c) 1991-1992 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 1, or (at your option)
! .\"	any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  '\" t
  .\"	aegis - project change supervisor
! .\"	Copyright (C) 1991, 1992, 1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 2 of the License, or
! .\"	(at your option) any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 64,70 ****
  and "foo" would become "foo.1.1" assiming the same minor version incriment.
  .PP
  The entire project baseline will be copied.
! The project state will as if change 1 had already been integrated,
  naming every file (in the old project) as a new file.
  The history files will reflect this.
  No build will be necessary;
--- 64,70 ----
  and "foo" would become "foo.1.1" assiming the same minor version incriment.
  .PP
  The entire project baseline will be copied.
! The project state will be as if change 1 had already been integrated,
  naming every file (in the old project) as a new file.
  The history files will reflect this.
  No build will be necessary;
***************
*** 78,86 ****
  If the major version number is incrimented or set,
  the minor version number will be set to zero if it is not explicitly given.
  .PP
! The new project will be added to the first element of the search path.
  If this is inappropriate, use the
! -B -LIBrary
  option to explicitly set the desired location.
  See the
  .B -LIBrary
--- 78,90 ----
  If the major version number is incrimented or set,
  the minor version number will be set to zero if it is not explicitly given.
  .PP
! The pointer to the new project will be added to the first element
! of the search path,
! or
! .I /usr/local/lib/aegis
! if none is set.
  If this is inappropriate, use the
! .B -LIBrary
  option to explicitly set the desired location.
  See the
  .B -LIBrary
***************
*** 94,104 ****
  .B -DIRectory 
  option is not given,
  the project directory will be created in the
! directory specified by the default_project_directory of
  .IR aeuconf (5),
  or if not set
! in current user's home directory;
  in either case with the same name as the project.
  .SH OPTIONS
  The following options are understood:
  .so o_dir.so
--- 98,113 ----
  .B -DIRectory 
  option is not given,
  the project directory will be created in the
! directory specified by the default_\%project_\%directory field of
! the project user's
  .IR aeuconf (5),
  or if not set
! in project user's home directory;
  in either case with the same name as the project.
+ .PP
+ All staff will be copied from the old project to the new project
+ without change,
+ as will all of the project attributes.
  .SH OPTIONS
  The following options are understood:
  .so o_dir.so
***************
*** 126,131 ****
  the old project named has not yet had any changes integrated.
  .PP
  It is an error if
! the old project named has any changes not in the 'completed' state.
  .so z_exit.so
  .so z_cr.so
--- 135,145 ----
  the old project named has not yet had any changes integrated.
  .PP
  It is an error if
! the old project named has any changes not in the
! .I completed
! state.
! .PP
! It is an error if
! the current user is not an administrator of the old project.
  .so z_exit.so
  .so z_cr.so
Index: man1/aenrv.1
***************
*** 1,12 ****
  '\" t
  .\"	aegis - project change supervisor
! .\"	Copyright (c) 1991-1992 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 1, or (at your option)
! .\"	any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  '\" t
  .\"	aegis - project change supervisor
! .\"	Copyright (C) 1991, 1992, 1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 2 of the License, or
! .\"	(at your option) any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
Index: man1/aent.1
***************
*** 1,12 ****
  '\" t
  .\"	aegis - project change supervisor
! .\"	Copyright (c) 1991-1992 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 1, or (at your option)
! .\"	any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  '\" t
  .\"	aegis - project change supervisor
! .\"	Copyright (C) 1991, 1992, 1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 2 of the License, or
! .\"	(at your option) any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
Index: man1/aentu.1
***************
*** 1,12 ****
  '\" t
  .\"	aegis - project change supervisor
! .\"	Copyright (c) 1991-1992 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 1, or (at your option)
! .\"	any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  '\" t
  .\"	aegis - project change supervisor
! .\"	Copyright (C) 1991, 1992, 1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 2 of the License, or
! .\"	(at your option) any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
Index: man1/aepa.1
***************
*** 1,12 ****
  '\" t
  .\"	aegis - project change supervisor
! .\"	Copyright (c) 1991-1992 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 1, or (at your option)
! .\"	any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  '\" t
  .\"	aegis - project change supervisor
! .\"	Copyright (C) 1991, 1992, 1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 2 of the License, or
! .\"	(at your option) any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
Index: man1/aera.1
***************
*** 1,12 ****
  '\" t
  .\"	aegis - project change supervisor
! .\"	Copyright (c) 1991-1992 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 1, or (at your option)
! .\"	any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  '\" t
  .\"	aegis - project change supervisor
! .\"	Copyright (C) 1991, 1992, 1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 2 of the License, or
! .\"	(at your option) any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
Index: man1/aerd.1
***************
*** 1,12 ****
  '\" t
  .\"	aegis - project change supervisor
! .\"	Copyright (c) 1991-1992 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 1, or (at your option)
! .\"	any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  '\" t
  .\"	aegis - project change supervisor
! .\"	Copyright (C) 1991, 1992, 1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 2 of the License, or
! .\"	(at your option) any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
Index: man1/aerf.1
***************
*** 1,12 ****
  '\" t
  .\"	aegis - project change supervisor
! .\"	Copyright (c) 1991-1992 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 1, or (at your option)
! .\"	any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  '\" t
  .\"	aegis - project change supervisor
! .\"	Copyright (C) 1991, 1992, 1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 2 of the License, or
! .\"	(at your option) any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
Index: man1/aeri.1
***************
*** 1,12 ****
  '\" t
  .\"	aegis - project change supervisor
! .\"	Copyright (c) 1991-1992 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 1, or (at your option)
! .\"	any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  '\" t
  .\"	aegis - project change supervisor
! .\"	Copyright (C) 1991, 1992, 1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 2 of the License, or
! .\"	(at your option) any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
Index: man1/aerm.1
***************
*** 1,12 ****
  '\" t
  .\"	aegis - project change supervisor
! .\"	Copyright (c) 1991-1992 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 1, or (at your option)
! .\"	any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  '\" t
  .\"	aegis - project change supervisor
! .\"	Copyright (C) 1991, 1992, 1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 2 of the License, or
! .\"	(at your option) any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
Index: man1/aermpr.1
***************
*** 0 ****
--- 1,82 ----
+ '\" t
+ .\"	aegis - project change supervisor
+ .\"	Copyright (C) 1991, 1992, 1993 Peter Miller.
+ .\"	All rights reserved.
+ .\"
+ .\"	This program is free software; you can redistribute it and/or modify
+ .\"	it under the terms of the GNU General Public License as published by
+ .\"	the Free Software Foundation; either version 2 of the License, or
+ .\"	(at your option) any later version.
+ .\"
+ .\"	This program is distributed in the hope that it will be useful,
+ .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
+ .\"	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ .\"	GNU General Public License for more details.
+ .\"
+ .\"	You should have received a copy of the GNU General Public License
+ .\"	along with this program; if not, write to the Free Software
+ .\"	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ .\"
+ .\" MANIFEST: manual entry for the 'aegis -ReMove_PRoject' command
+ .\"
+ .so z_name.so
+ .TH "\*(n) -ReMove_PRoject" 1 \*(N)
+ .if n .ad l
+ .if n .hy 0
+ .SH NAME
+ \*(n) -ReMove_PRoject \- remove project
+ .SH SYNOPSIS
+ .B \*(n)
+ .B -ReMove_Project
+ .I project-name
+ [
+ .IR option \&...
+ ]
+ .br
+ .B \*(n)
+ .B -ReMove_Project
+ .B -List
+ [
+ .IR option \&...
+ ]
+ .br
+ .B \*(n)
+ .B -ReMove_Project
+ .B -Help
+ .SH DESCRIPTION
+ The
+ .I \*(n)
+ .I -ReMove_PRoject
+ command is used to
+ remove a project, either entirely,
+ or just from \*(n)' supervision.
+ .SH OPTIONS
+ The following options are understood:
+ .so o_keep.so
+ .so o_lib.so
+ .so o_list.so
+ .so o_help.so
+ .so o_project.so
+ .so o_terse.so
+ .so o_verbose.so
+ .so o__rules.so
+ .SH RECOMMENDED ALIAS
+ The recommended alias for this command is
+ .nf
+ .ta 8n 16n
+ csh%	alias aermpr '\*(n) -rmpr \e!* -v'
+ sh$	aermpr(){\*(n) -rmpr $* -v}
+ .fi
+ .SH ERRORS
+ It is an error if
+ the project has any changes between the
+ .I "being developed"
+ and 
+ .I "being integrated"
+ states,
+ inclusive.
+ .br
+ It is an error if
+ the current user is not an administrator.
+ .so z_exit.so
+ .so z_cr.so
Index: man1/aermu.1
***************
*** 1,12 ****
  '\" t
  .\"	aegis - project change supervisor
! .\"	Copyright (c) 1991-1992 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 1, or (at your option)
! .\"	any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  '\" t
  .\"	aegis - project change supervisor
! .\"	Copyright (C) 1991, 1992, 1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 2 of the License, or
! .\"	(at your option) any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
Index: man1/aerp.1
***************
*** 1,12 ****
  '\" t
  .\"	aegis - project change supervisor
! .\"	Copyright (c) 1991-1992 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 1, or (at your option)
! .\"	any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  '\" t
  .\"	aegis - project change supervisor
! .\"	Copyright (C) 1991, 1992, 1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 2 of the License, or
! .\"	(at your option) any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
Index: man1/aerpu.1
***************
*** 1,12 ****
  '\" t
  .\"	aegis - project change supervisor
! .\"	Copyright (c) 1991-1992 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 1, or (at your option)
! .\"	any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  '\" t
  .\"	aegis - project change supervisor
! .\"	Copyright (C) 1991, 1992, 1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 2 of the License, or
! .\"	(at your option) any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
Index: man1/aerrv.1
***************
*** 1,12 ****
  '\" t
  .\"	aegis - project change supervisor
! .\"	Copyright (c) 1991-1992 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 1, or (at your option)
! .\"	any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  '\" t
  .\"	aegis - project change supervisor
! .\"	Copyright (C) 1991, 1992, 1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 2 of the License, or
! .\"	(at your option) any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
Index: man1/aet.1
***************
*** 1,12 ****
  '\" t
  .\"	aegis - project change supervisor
! .\"	Copyright (c) 1991-1992 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 1, or (at your option)
! .\"	any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  '\" t
  .\"	aegis - project change supervisor
! .\"	Copyright (C) 1991, 1992, 1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 2 of the License, or
! .\"	(at your option) any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 62,68 ****
  .so z_intuit.so
  .PP
  Tests are executed by 
! .IR /bin/sh .
  The current directory will be the top of the appropriate directory tree.
  If tests require temporary files, they should create them in
  .IR /tmp ,
--- 62,68 ----
  .so z_intuit.so
  .PP
  Tests are executed by 
! the Bourne shell.
  The current directory will be the top of the appropriate directory tree.
  If tests require temporary files, they should create them in
  .IR /tmp ,
Index: man1/aev.1
***************
*** 1,12 ****
  '\" t
  .\"	aegis - project change supervisor
! .\"	Copyright (c) 1991-1992 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 1, or (at your option)
! .\"	any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  '\" t
  .\"	aegis - project change supervisor
! .\"	Copyright (C) 1991, 1992, 1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 2 of the License, or
! .\"	(at your option) any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
Index: man1/o__rules.so
***************
*** 1,11 ****
  .\"	aegis - project change supervisor
! .\"	Copyright (c) 1991-1992 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 1, or (at your option)
! .\"	any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
+ .\"
  .\"	aegis - project change supervisor
! .\"	Copyright (C) 1991, 1992, 1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 2 of the License, or
! .\"	(at your option) any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 19,26 ****
  .\" MANIFEST: description of option up/down case convention
  .\"
  .PP
! All options are case insensitive.
! Options may be abbreviated;
! the abbreviation is the upper case letters.
  Options and other command line arguments may be
! mixed arbitrarily on the command line.
--- 20,47 ----
  .\" MANIFEST: description of option up/down case convention
  .\"
  .PP
! All options may be abbreviated;
! the abbreviation is documented as the upper case letters,
! all lower case letters and underscores (_) are optional.
! You must use consecutive sequences of optional letters.
! .PP
! All options are case insensitive,
! you may type them in upper case or lower case or a combination of both,
! case is not important.
! .PP
! For example:
! the arguments "-project, "-PROJ" and "-p" are
! all interpreted to mean the \fB-Project\fP option.
! The argument "-prj" will not be understood,
! because consecutive optional characters were not supplied.
! .PP
  Options and other command line arguments may be
! mixed arbitrarily on the command line,
! after the function selectors.
! .br
! .ne 4
! .PP
! The GNU long option names are understood.
! Since all option names for aegis are long,
! this means ignoring the extra leading '-'.
! The "\fB--\fIoption\fB=\fIvalue\fR" convention is also understood.
Index: man1/o_anticip.so
***************
*** 1,11 ****
  .\"	aegis - project change supervisor
! .\"	Copyright (c) 1991-1992 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 1, or (at your option)
! .\"	any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
+ .\"
  .\"	aegis - project change supervisor
! .\"	Copyright (C) 1991, 1992, 1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 2 of the License, or
! .\"	(at your option) any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
Index: man1/o_auto.so
***************
*** 1,11 ****
  .\"	aegis - project change supervisor
! .\"	Copyright (c) 1991-1992 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 1, or (at your option)
! .\"	any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
+ .\"
  .\"	aegis - project change supervisor
! .\"	Copyright (C) 1991, 1992, 1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 2 of the License, or
! .\"	(at your option) any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
Index: man1/o_baselin.so
***************
*** 1,11 ****
  .\"	aegis - project change supervisor
! .\"	Copyright (c) 1991-1992 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 1, or (at your option)
! .\"	any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
+ .\"
  .\"	aegis - project change supervisor
! .\"	Copyright (C) 1991, 1992, 1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 2 of the License, or
! .\"	(at your option) any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
Index: man1/o_bld_lk.so
***************
*** 0 ****
--- 1,30 ----
+ .\"
+ .\"	aegis - project change supervisor
+ .\"	Copyright (C) 1993 Peter Miller.
+ .\"	All rights reserved.
+ .\"
+ .\"	This program is free software; you can redistribute it and/or modify
+ .\"	it under the terms of the GNU General Public License as published by
+ .\"	the Free Software Foundation; either version 2 of the License, or
+ .\"	(at your option) any later version.
+ .\"
+ .\"	This program is distributed in the hope that it will be useful,
+ .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
+ .\"	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ .\"	GNU General Public License for more details.
+ .\"
+ .\"	You should have received a copy of the GNU General Public License
+ .\"	along with this program; if not, write to the Free Software
+ .\"	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ .\"
+ .\" MANIFEST: manual section describing the build lock
+ .\"
+ .PP
+ While there is a build in progress for any change in a project,
+ an integrate pass for the project will wait until all the builds are
+ completed before starting.
+ This is
+ to ensure that the baseline is consistent for the entire build.
+ Similarly,
+ while an integrate pass is in progress for a project,
+ any builds will wait until it is completed before starting.
Index: man1/o_change.so
***************
*** 1,11 ****
  .\"	aegis - project change supervisor
! .\"	Copyright (c) 1991-1992 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 1, or (at your option)
! .\"	any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
+ .\"
  .\"	aegis - project change supervisor
! .\"	Copyright (C) 1991, 1992, 1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 2 of the License, or
! .\"	(at your option) any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 21,25 ****
  .TP 8n
  \fB-Change\fP \fInumber\fP
  This option may be used to specify a particular change within a project.
! If the user is only working on one change within a project,
  that is the default change number.
--- 22,41 ----
  .TP 8n
  \fB-Change\fP \fInumber\fP
  This option may be used to specify a particular change within a project.
! When no
! .B -Change
! option is specified,
! the
! .I AEGIS_CHANGE
! environment variable is consulted.
! If that does not exist,
! the user's
! .I $HOME/.\*(n)rc
! file is examined for a default change field (see
! .IR aeuconf (5)
! for more information).
! If that does not exist,
! when the user is only working on one change within a project,
  that is the default change number.
+ Otherwise,
+ it is an error.
Index: man1/o_devdir.so
***************
*** 1,11 ****
  .\"	aegis - project change supervisor
! .\"	Copyright (c) 1991-1992 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 1, or (at your option)
! .\"	any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
+ .\"
  .\"	aegis - project change supervisor
! .\"	Copyright (C) 1991, 1992, 1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 2 of the License, or
! .\"	(at your option) any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
Index: man1/o_dir.so
***************
*** 1,11 ****
  .\"	aegis - project change supervisor
! .\"	Copyright (c) 1991-1992 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 1, or (at your option)
! .\"	any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
+ .\"
  .\"	aegis - project change supervisor
! .\"	Copyright (C) 1991, 1992, 1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 2 of the License, or
! .\"	(at your option) any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 20,25 ****
--- 21,34 ----
  .\"
  .TP 8n
  \fB-DIRectory\fP \fIpath\fP
+ .RS 8n
  This option may be used to specify which directory is to be used.
  It is an error if the current user does not have appropriate permissions
  to create the directory path given.
+ This must be an absolute path.
+ .PP
+ Caution:
+ If you are using an automounter
+ do not use `pwd` to make an absolute path,
+ it usually gives the wrong answer.
+ .RE
Index: man1/o_help.so
***************
*** 1,11 ****
  .\"	aegis - project change supervisor
! .\"	Copyright (c) 1991-1992 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 1, or (at your option)
! .\"	any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
+ .\"
  .\"	aegis - project change supervisor
! .\"	Copyright (C) 1991, 1992, 1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 2 of the License, or
! .\"	(at your option) any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
Index: man1/o_indep.so
***************
*** 1,11 ****
  .\"	aegis - project change supervisor
! .\"	Copyright (c) 1991-1992 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 1, or (at your option)
! .\"	any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
+ .\"
  .\"	aegis - project change supervisor
! .\"	Copyright (C) 1991, 1992, 1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 2 of the License, or
! .\"	(at your option) any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
Index: man1/o_keep.so
***************
*** 1,11 ****
  .\"	aegis - project change supervisor
! .\"	Copyright (c) 1991-1992 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 1, or (at your option)
! .\"	any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
+ .\"
  .\"	aegis - project change supervisor
! .\"	Copyright (C) 1991, 1992, 1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 2 of the License, or
! .\"	(at your option) any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 20,24 ****
--- 21,26 ----
  .\"
  .TP 8n
  .B -Keep
+ .br
  This option may be used to retain files and/or directories
  usually deleted by the command.
Index: man1/o_lib.so
***************
*** 1,11 ****
  .\"	aegis - project change supervisor
! .\"	Copyright (c) 1992 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 1, or (at your option)
! .\"	any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
+ .\"
  .\"	aegis - project change supervisor
! .\"	Copyright (C) 1992, 1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 2 of the License, or
! .\"	(at your option) any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
Index: man1/o_list.so
***************
*** 1,11 ****
  .\"	aegis - project change supervisor
! .\"	Copyright (c) 1991-1992 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 1, or (at your option)
! .\"	any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
+ .\"
  .\"	aegis - project change supervisor
! .\"	Copyright (C) 1991, 1992, 1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 2 of the License, or
! .\"	(at your option) any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
Index: man1/o_major.so
***************
*** 1,11 ****
  .\"	aegis - project change supervisor
! .\"	Copyright (c) 1992 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 1, or (at your option)
! .\"	any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
+ .\"
  .\"	aegis - project change supervisor
! .\"	Copyright (C) 1992, 1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 2 of the License, or
! .\"	(at your option) any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
Index: man1/o_manual.so
***************
*** 1,11 ****
  .\"	aegis - project change supervisor
! .\"	Copyright (c) 1991-1992 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 1, or (at your option)
! .\"	any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
+ .\"
  .\"	aegis - project change supervisor
! .\"	Copyright (C) 1991, 1992, 1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 2 of the License, or
! .\"	(at your option) any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
Index: man1/o_min.so
***************
*** 1,11 ****
  .\"	aegis - project change supervisor
! .\"	Copyright (c) 1991-1992 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 1, or (at your option)
! .\"	any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
+ .\"
  .\"	aegis - project change supervisor
! .\"	Copyright (C) 1991, 1992, 1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 2 of the License, or
! .\"	(at your option) any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
Index: man1/o_minor.so
***************
*** 1,11 ****
  .\"	aegis - project change supervisor
! .\"	Copyright (c) 1992 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 1, or (at your option)
! .\"	any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
+ .\"
  .\"	aegis - project change supervisor
! .\"	Copyright (C) 1992, 1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 2 of the License, or
! .\"	(at your option) any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
Index: man1/o_nolog.so
***************
*** 1,11 ****
  .\"	aegis - project change supervisor
! .\"	Copyright (c) 1992 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 1, or (at your option)
! .\"	any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
+ .\"
  .\"	aegis - project change supervisor
! .\"	Copyright (C) 1992, 1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 2 of the License, or
! .\"	(at your option) any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
Index: man1/o_overw.so
***************
*** 1,11 ****
  .\"	aegis - project change supervisor
! .\"	Copyright (c) 1991-1992 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 1, or (at your option)
! .\"	any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
+ .\"
  .\"	aegis - project change supervisor
! .\"	Copyright (C) 1991, 1992, 1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 2 of the License, or
! .\"	(at your option) any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
Index: man1/o_page.so
***************
*** 1,11 ****
  .\"	aegis - project change supervisor
! .\"	Copyright (c) 1991-1992 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 1, or (at your option)
! .\"	any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
+ .\"
  .\"	aegis - project change supervisor
! .\"	Copyright (C) 1991, 1992, 1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 2 of the License, or
! .\"	(at your option) any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
Index: man1/o_project.so
***************
*** 1,11 ****
  .\"	aegis - project change supervisor
! .\"	Copyright (c) 1991-1992 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 1, or (at your option)
! .\"	any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
+ .\"
  .\"	aegis - project change supervisor
! .\"	Copyright (C) 1991, 1992, 1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 2 of the License, or
! .\"	(at your option) any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 24,35 ****
  When no
  .B -Project
  option is specified,
! if the user is only working on changes within a single project,
! the project name defaults to that project;
! if the user is currently working on changes to more than one project,
! or is not working on changes to any project,
  the user's
  .I $HOME/.\*(n)rc
  file is examined for a default project field (see
  .IR aeuconf (5)
  for more information).
--- 25,41 ----
  When no
  .B -Project
  option is specified,
! the
! .I AEGIS_PROJECT
! environment variable is consulted.
! If that does not exist,
  the user's
  .I $HOME/.\*(n)rc
  file is examined for a default project field (see
  .IR aeuconf (5)
  for more information).
+ If that does not exist,
+ when the user is only working on changes within a single project,
+ the project name defaults to that project.
+ Otherwise,
+ it is an error.
Index: man1/o_terse.so
***************
*** 1,11 ****
  .\"	aegis - project change supervisor
! .\"	Copyright (c) 1991-1992 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 1, or (at your option)
! .\"	any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
+ .\"
  .\"	aegis - project change supervisor
! .\"	Copyright (C) 1991, 1992, 1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 2 of the License, or
! .\"	(at your option) any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
Index: man1/o_verbose.so
***************
*** 1,11 ****
  .\"	aegis - project change supervisor
! .\"	Copyright (c) 1991-1992 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 1, or (at your option)
! .\"	any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
+ .\"
  .\"	aegis - project change supervisor
! .\"	Copyright (C) 1991, 1992, 1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 2 of the License, or
! .\"	(at your option) any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
Index: man1/z_cr.so
***************
*** 1,11 ****
  .\"	aegis - project change supervisor
! .\"	Copyright (c) 1991-1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 1, or (at your option)
! .\"	any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
+ .\"
  .\"	aegis - project change supervisor
! .\"	Copyright (C) 1991, 1992, 1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 2 of the License, or
! .\"	(at your option) any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 18,28 ****
  .\"
  .\" MANIFEST: copyright and author parts of section 1 manual entries
  .\"
  .SH COPYRIGHT
! .if t .ds c) \(co
! .if n .ds c) (c)
! The \*(n) program is Copyright \*(c) 1991-1993 Peter Miller.
  .br
  All rights reserved.
  .PP
  The \*(n) program comes with ABSOLUTELY NO WARRANTY;
--- 19,34 ----
  .\"
  .\" MANIFEST: copyright and author parts of section 1 manual entries
  .\"
+ .br
+ .ne 2i
  .SH COPYRIGHT
! \*(n) version
! .so ../doc/version.so
  .br
+ .if t .ds C) \(co
+ .if n .ds C) (C)
+ Copyright \*(C) 1990, 1991, 1992, 1993 Peter Miller.
+ .br
  All rights reserved.
  .PP
  The \*(n) program comes with ABSOLUTELY NO WARRANTY;
***************
*** 30,39 ****
  This is free software
  and you are welcome to redistribute it under certain conditions;
  for details use the '\fI\*(n) -VERSion Redistribution\fP' command.
  .SH AUTHOR
  .TS
  tab(;);
  l l l.
  Peter Miller;UUCP;uunet!munnari!bmr.gov.au!pmiller
! \f(CW/\e/\e*\fR;CSNET;pmiller@bmr.gov.au
  .TE
--- 36,47 ----
  This is free software
  and you are welcome to redistribute it under certain conditions;
  for details use the '\fI\*(n) -VERSion Redistribution\fP' command.
+ .br
+ .ne 1i
  .SH AUTHOR
  .TS
  tab(;);
  l l l.
  Peter Miller;UUCP;uunet!munnari!bmr.gov.au!pmiller
! \f(CW/\e/\e*\fR;Internet;pmiller@bmr.gov.au
  .TE
Index: man1/z_exit.so
***************
*** 1,11 ****
  .\"	aegis - project change supervisor
! .\"	Copyright (c) 1991-1992 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 1, or (at your option)
! .\"	any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
+ .\"
  .\"	aegis - project change supervisor
! .\"	Copyright (C) 1991, 1992, 1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 2 of the License, or
! .\"	(at your option) any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
Index: man1/z_intuit.so
***************
*** 1,11 ****
  .\"	aegis - project change supervisor
! .\"	Copyright (c) 1991-1992 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 1, or (at your option)
! .\"	any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
+ .\"
  .\"	aegis - project change supervisor
! .\"	Copyright (C) 1991, 1992, 1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 2 of the License, or
! .\"	(at your option) any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
Index: man1/z_name.so
***************
*** 1,11 ****
  .\"	aegis - project change supervisor
! .\"	Copyright (c) 1991-1992 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 1, or (at your option)
! .\"	any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
+ .\"
  .\"	aegis - project change supervisor
! .\"	Copyright (C) 1991, 1992, 1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 2 of the License, or
! .\"	(at your option) any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
Index: man5/aecattr.5
***************
*** 1,12 ****
  '\" t
  .\"	aegis - project change supervisor
! .\"	Copyright (c) 1991-1992 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 1, or (at your option)
! .\"	any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  '\" t
  .\"	aegis - project change supervisor
! .\"	Copyright (C) 1991, 1992, 1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 2 of the License, or
! .\"	(at your option) any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 27,92 ****
  A change attributes file is used to describe the
  modifiable portion of a change.
  .SH CONTENTS
! A change attributes files contains the folowing fields:
! .TP 8n
! description = string;
! .br
! This field contains a detailed description of the change. 
! .TP 8n
! brief_description = string;
! .br
! This field contains a brief description of the change. 
! .TP 8n
! cause = ( ... );
! .br
! This field describes the cause which motivated the change.
! .RS 8n
! .TP 8n
! external_bug
! .br
! The change was created in response to
! a bug report
! from outside the development team.
! .TP 8n
! external_enhancement
! .br
! The change was created in response to
! an enhancement request
! from outside the development team.
! .TP 8n
! internal_bug
! .br
! The change was created in response to
! a bug report
! from inside the development team.
! .TP 8n
! internal_enhancement
! .br
! The change was created in response to
! an enhancement request
! from inside the development team.
! .TP 8n
! chain
! .br
! This cause is where you have a fix to fix a fix;
! tracking these is an interesting quality metric.
! .RE
! .TP 8n
! test_exempt = boolean;
! .br
! This field is true if it is not necessary
! to test the change.
! It is, in general, desirable to test all changes,
! whether new functionality or a bug fix.
! This is, however, a project management issue.
! .TP 8n
! test_baseline_exempt = boolean;
! .br
! This field is true if it is not necessary
! to test the change against the baseline before it is changed.
! The test of the baseline is required to fail;
! this is to establish that the test has isolated the bug,
! and that the change has fixed that isolated bug.
  .SH SEE ALSO
  .IR aenc (1),
  .IR aeca (1).
--- 27,34 ----
  A change attributes file is used to describe the
  modifiable portion of a change.
  .SH CONTENTS
! A change attributes file contains the folowing fields:
! .so aecattr.so
  .SH SEE ALSO
  .IR aenc (1),
  .IR aeca (1).
Index: man5/aecattr.so
***************
*** 0 ****
--- 1,80 ----
+ '\" t
+ .\"	aegis - project change supervisor
+ .\"	Copyright (C) 1991, 1992, 1993 Peter Miller.
+ .\"	All rights reserved.
+ .\"
+ .\"	This program is free software; you can redistribute it and/or modify
+ .\"	it under the terms of the GNU General Public License as published by
+ .\"	the Free Software Foundation; either version 2 of the License, or
+ .\"	(at your option) any later version.
+ .\"
+ .\"	This program is distributed in the hope that it will be useful,
+ .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
+ .\"	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ .\"	GNU General Public License for more details.
+ .\"
+ .\"	You should have received a copy of the GNU General Public License
+ .\"	along with this program; if not, write to the Free Software
+ .\"	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ .\"
+ .\" MANIFEST: description of aegis change attribute file format
+ .\"
+ .TP 8n
+ description = string;
+ .br
+ This field contains a detailed description of the change. 
+ .TP 8n
+ brief_description = string;
+ .br
+ This field contains a brief description of the change. 
+ .TP 8n
+ cause = ( ... );
+ .br
+ This field describes the cause which motivated the change.
+ .RS 8n
+ .TP 8n
+ external_bug
+ .br
+ The change was created in response to
+ a bug report
+ from outside the development team.
+ .TP 8n
+ external_enhancement
+ .br
+ The change was created in response to
+ an enhancement request
+ from outside the development team.
+ .TP 8n
+ internal_bug
+ .br
+ The change was created in response to
+ a bug report
+ from inside the development team.
+ .TP 8n
+ internal_enhancement
+ .br
+ The change was created in response to
+ an enhancement request
+ from inside the development team.
+ .TP 8n
+ chain
+ .br
+ This cause is where you have a fix to fix a fix;
+ tracking these is an interesting quality metric.
+ .RE
+ .TP 8n
+ test_exempt = boolean;
+ .br
+ This field is true if it is not necessary
+ to test the change.
+ It is, in general, desirable to test all changes,
+ whether new functionality or a bug fix.
+ This is, however, a project management issue.
+ .TP 8n
+ test_baseline_exempt = boolean;
+ .br
+ This field is true if it is not necessary
+ to test the change against the baseline before it is changed.
+ The test of the baseline is required to fail;
+ this is to establish that the test has isolated the bug,
+ and that the change has fixed that isolated bug.
Index: man5/aecstate.5
***************
*** 1,12 ****
  '\" t
  .\"	aegis - project change supervisor
! .\"	Copyright (c) 1991-1992 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 1, or (at your option)
! .\"	any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  '\" t
  .\"	aegis - project change supervisor
! .\"	Copyright (C) 1991, 1992, 1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 2 of the License, or
! .\"	(at your option) any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 40,104 ****
  to improve the directory search times,
  and to avoid various systems' directory length limitations.
  .SH CONTENTS
! .TP 8n
! description = string;
! .br
! This field contains a detailed description of the change. 
! .TP 8n
! brief_description = string;
! .br
! This field contains a brief description of the change. 
! .TP 8n
! cause = ( ... );
! .br
! This field describes the cause which motivated the change.
! .RS 8n
! .TP 8n
! external_bug
! .br
! The change was created in response to
! a bug report
! from outside the development team.
! .TP 8n
! external_enhancement
! .br
! The change was created in response to
! an enhancement request
! from outside the development team.
! .TP 8n
! internal_bug
! .br
! The change was created in response to
! a bug report
! from inside the development team.
! .TP 8n
! internal_enhancement
! .br
! The change was created in response to
! an enhancement request
! from inside the development team.
! .TP 8n
! chain
! .br
! This cause is where you have a fix to fix a fix;
! tracking these is an interesting quality metric.
! .RE
! .TP 8n
! test_exempt = boolean;
! .br
! This field is true if it is not necessary
! to test the change.
! It is, in general, desirable to test all changes,
! whether new functionality or a bug fix.
! This is, however, a project management issue.
! .TP 8n
! test_baseline_exempt = boolean;
! .br
! This field is true if it is not necessary
! to test the change against the baseline before it is changed.
! The test of the baseline is required to fail;
! this is to establish that the test has isolated the bug,
! and that the change has fixed that isolated bug.
  .TP 8n
  state = ( ... );
  .br
--- 40,46 ----
  to improve the directory search times,
  and to avoid various systems' directory length limitations.
  .SH CONTENTS
! .so aecattr.so
  .TP 8n
  state = ( ... );
  .br
Index: man5/aedir.5
***************
*** 1,12 ****
  '\" t
  .\"	aegis - project change supervisor
! .\"	Copyright (c) 1991-1992 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 1, or (at your option)
! .\"	any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  '\" t
  .\"	aegis - project change supervisor
! .\"	Copyright (C) 1991, 1992, 1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 2 of the License, or
! .\"	(at your option) any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
Index: man5/aegis.5
***************
*** 1,12 ****
  '\" t
  .\"	aegis - project change supervisor
! .\"	Copyright (c) 1991-1992 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 1, or (at your option)
! .\"	any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  '\" t
  .\"	aegis - project change supervisor
! .\"	Copyright (C) 1991, 1992, 1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 2 of the License, or
! .\"	(at your option) any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
Index: man5/aegstate.5
***************
*** 1,12 ****
  '\" t
  .\"	aegis - project change supervisor
! .\"	Copyright (c) 1991-1992 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 1, or (at your option)
! .\"	any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  '\" t
  .\"	aegis - project change supervisor
! .\"	Copyright (C) 1991, 1992, 1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 2 of the License, or
! .\"	(at your option) any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
Index: man5/aepattr.5
***************
*** 1,12 ****
  '\" t
  .\"	aegis - project change supervisor
! .\"	Copyright (c) 1991-1992 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 1, or (at your option)
! .\"	any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  '\" t
  .\"	aegis - project change supervisor
! .\"	Copyright (C) 1991, 1992, 1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 2 of the License, or
! .\"	(at your option) any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 28,225 ****
  project attribute
  file is used to store modifiable information about a project.
  .SH CONTENTS
! .TP 8n
! description = string;
! This field contains
! a description of the project.
! Large amounts of prose are not required;
! a single line is sufficient.
! .TP 8n
! owner_name = string;
! This field contains
! the name of the user to whom baseline files belong.
! .TP 8n
! group_name = string;
! This field contains
! the name of the group to which baseline files belong.
! .TP 8n
! developer_may_review = boolean;
! If this field is true, then a developer may review her own change.
! This is probably only a good idea for projects of less than 3 people.
! The idea is for as many people as possible to critically examine a change.
! .TP 8n
! developer_may_integrate = boolean;
! If this field is true, then a developer may integrate her own change.
! This is probably only a good idea for projects of less than 3 people.
! The idea is for as many people as possible to critically examine a change.
! .TP 8n
! reviewer_may_integrate = boolean;
! If this field is true, then a reviewer may integrate a change she reviewed.
! This is probably only a good idea for projects of less than 3 people.
! The idea is for as many people as possible to critically examine a change.
! .TP 8n
! developers_may_create_changes = boolean;
! This field is true if developers may created changes,
! in addition to administrators.
! This tends to be a very useful thing,
! since developers find most of the bugs.
! .TP 8n
! develop_end_notify_command = string;
! This command is used to
! notify that a change is ready for review.
! It will probably use mail,
! or it could be an in-house bulletin board.
! This field is optional,
! if not present no notification will be given.
! This command could also be used to notify other managament systems,
! such as progress and defect tracking.
! .RS 8n
! %1 = project name
! .br
! %2 = change number
! .br
! %3 = developer
! .RE
! .TP 8n
! develop_end_undo_notify_command = string;
! This command is used to
! notify that a change had been withdrawn from review
! for further development.
! It will probably use mail,
! or it could be an in-house bulletin board.
! This field is optional,
! if not present no notification will be given.
! This command could also be used to notify other managament systems,
! such as progress and defect tracking.
! .RS 8n
! %1 = project name
! .br
! %2 = change number
! .br
! %3 = developer
! .RE
! .TP 8n
! review_pass_notify_command = string;
! This command is used to
! notify that a review has passed.
! It will probably use mail,
! or it could be an in-house bulletin board.
! This field is optional,
! if not present no notification will be given.
! This command could also be used to notify other managament systems,
! such as progress and defect tracking.
! .RS 8n
! %1 = project name
! .br
! %2 = change number
! .br
! %3 = developer
! .br
! %4 = reviewer
! .RE
! .TP 8n
! review_pass_undo_notify_command = string;
! This command is used to
! notify that a review has passed.
! It will probably use mail,
! or it could be an in-house bulletin board.
! This field is optional,
! if not present no notification will be given.
! This command could also be used to notify other managament systems,
! such as progress and defect tracking.
! Defaults to the same action as the \fIdevelop_end_notify_command\fP field.
! .RS 8n
! %1 = project name
! .br
! %2 = change number
! .br
! %3 = developer
! .br
! %4 = reviewer
! .RE
! .TP 8n
! review_fail_notify_command = string;
! This command is used to
! notify that a review has failed.
! It will probably use mail,
! or it could be an in-house bulletin board.
! This field is optional,
! if not present no notification will be given.
! This command could also be used to notify other managament systems,
! such as progress and defect tracking.
! .RS 8n
! %1 = project name
! .br
! %2 = change number
! .br
! %3 = developer
! .br
! %4 = reviewer
! .RE
! .TP 8n
! integrate_pass_notify_command = string;
! This command is used to
! notify that an integration has passed.
! It will probably use mail,
! or it could be an in-house bulletin board.
! This field is optional,
! if not present no notification will be given.
! This command could also be used to notify other managament systems,
! such as progress and defect tracking.
! .RS 8n
! %1 = project name
! .br
! %2 = change number
! .br
! %3 = developer
! .br
! %4 = reviewer
! .br
! %5 = integrator
! .RE
! .TP 8n
! integrate_fail_notify_command = string;
! This command is used to
! notify that an integration has failed.
! It will probably use mail,
! or it could be an in-house bulletin board.
! This field is optional,
! if not present no notification will be given.
! This command could also be used to notify other managament systems,
! such as progress and defect tracking.
! .RS 8n
! %1 = project name
! .br
! %2 = change number
! .br
! %3 = developer
! .br
! %4 = reviewer
! .br
! %5 = integrator
! .RE
! .TP 8n
! default_development_directory = string;
! The pathname of where to place new development directories.
! The pathname must be absolute.
! This field is only consulted if
! the field of the same name in the user conf file is not set.
! .TP 8n
! umask = integer;
! .br
! File permission mode mask.
! See
! .IR umask (2)
! for more information.
! This value will always be OR'ed with 022,
! because
! .I aegis
! is paranoid.
! .TP 8n
! default_test_exemption = boolean;
! .br
! This field contains what to do when a change is created with
! no test exemption specified.
  .SH SEE ALSO
  .IR aepa (1)
  .so z_cr.so
--- 28,34 ----
  project attribute
  file is used to store modifiable information about a project.
  .SH CONTENTS
! .so aepattr.so
  .SH SEE ALSO
  .IR aepa (1)
  .so z_cr.so
Index: man5/aepattr.so
***************
*** 0 ****
--- 1,171 ----
+ '\" t
+ .\"	aegis - project change supervisor
+ .\"	Copyright (C) 1991, 1992, 1993 Peter Miller.
+ .\"	All rights reserved.
+ .\"
+ .\"	This program is free software; you can redistribute it and/or modify
+ .\"	it under the terms of the GNU General Public License as published by
+ .\"	the Free Software Foundation; either version 2 of the License, or
+ .\"	(at your option) any later version.
+ .\"
+ .\"	This program is distributed in the hope that it will be useful,
+ .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
+ .\"	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ .\"	GNU General Public License for more details.
+ .\"
+ .\"	You should have received a copy of the GNU General Public License
+ .\"	along with this program; if not, write to the Free Software
+ .\"	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ .\"
+ .\" MANIFEST: description of aegis project attribute file format
+ .\"
+ .TP 8n
+ description = string;
+ This field contains
+ a description of the project.
+ Large amounts of prose are not required;
+ a single line is sufficient.
+ .TP 8n
+ owner_name = string;
+ This field contains
+ the name of the user to whom baseline files belong.
+ .TP 8n
+ group_name = string;
+ This field contains
+ the name of the group to which baseline files belong.
+ .TP 8n
+ developer_may_review = boolean;
+ If this field is true, then a developer may review her own change.
+ This is probably only a good idea for projects of less than 3 people.
+ The idea is for as many people as possible to critically examine a change.
+ .TP 8n
+ developer_may_integrate = boolean;
+ If this field is true, then a developer may integrate her own change.
+ This is probably only a good idea for projects of less than 3 people.
+ The idea is for as many people as possible to critically examine a change.
+ .TP 8n
+ reviewer_may_integrate = boolean;
+ If this field is true, then a reviewer may integrate a change she reviewed.
+ This is probably only a good idea for projects of less than 3 people.
+ The idea is for as many people as possible to critically examine a change.
+ .TP 8n
+ developers_may_create_changes = boolean;
+ This field is true if developers may created changes,
+ in addition to administrators.
+ This tends to be a very useful thing,
+ since developers find most of the bugs.
+ .TP 8n
+ develop_end_notify_command = string;
+ This command is used to
+ notify that a change is ready for review.
+ It will probably use mail,
+ or it could be an in-house bulletin board.
+ This field is optional,
+ if not present no notification will be given.
+ This command could also be used to notify other managament systems,
+ such as progress and defect tracking.
+ All of the substitutions described by
+ .IR aesub (5)
+ are available.
+ .TP 8n
+ develop_end_undo_notify_command = string;
+ This command is used to
+ notify that a change had been withdrawn from review
+ for further development.
+ It will probably use mail,
+ or it could be an in-house bulletin board.
+ This field is optional,
+ if not present no notification will be given.
+ This command could also be used to notify other managament systems,
+ such as progress and defect tracking.
+ All of the substitutions described by
+ .IR aesub (5)
+ are available.
+ .TP 8n
+ review_pass_notify_command = string;
+ This command is used to
+ notify that a review has passed.
+ It will probably use mail,
+ or it could be an in-house bulletin board.
+ This field is optional,
+ if not present no notification will be given.
+ This command could also be used to notify other managament systems,
+ such as progress and defect tracking.
+ All of the substitutions described by
+ .IR aesub (5)
+ are available.
+ .TP 8n
+ review_pass_undo_notify_command = string;
+ This command is used to
+ notify that a review has passed.
+ It will probably use mail,
+ or it could be an in-house bulletin board.
+ This field is optional,
+ if not present no notification will be given.
+ This command could also be used to notify other managament systems,
+ such as progress and defect tracking.
+ Defaults to the same action as the \fIdevelop_end_notify_command\fP field.
+ All of the substitutions described by
+ .IR aesub (5)
+ are available.
+ .TP 8n
+ review_fail_notify_command = string;
+ This command is used to
+ notify that a review has failed.
+ It will probably use mail,
+ or it could be an in-house bulletin board.
+ This field is optional,
+ if not present no notification will be given.
+ This command could also be used to notify other managament systems,
+ such as progress and defect tracking.
+ All of the substitutions described by
+ .IR aesub (5)
+ are available.
+ .TP 8n
+ integrate_pass_notify_command = string;
+ This command is used to
+ notify that an integration has passed.
+ It will probably use mail,
+ or it could be an in-house bulletin board.
+ This field is optional,
+ if not present no notification will be given.
+ This command could also be used to notify other managament systems,
+ such as progress and defect tracking.
+ All of the substitutions described by
+ .IR aesub (5)
+ are available.
+ .TP 8n
+ integrate_fail_notify_command = string;
+ This command is used to
+ notify that an integration has failed.
+ It will probably use mail,
+ or it could be an in-house bulletin board.
+ This field is optional,
+ if not present no notification will be given.
+ This command could also be used to notify other managament systems,
+ such as progress and defect tracking.
+ All of the substitutions described by
+ .IR aesub (5)
+ are available.
+ .TP 8n
+ default_development_directory = string;
+ The pathname of where to place new development directories.
+ The pathname must be absolute.
+ This field is only consulted if
+ the field of the same name in the user conf file is not set.
+ .TP 8n
+ umask = integer;
+ .br
+ File permission mode mask.
+ See
+ .IR umask (2)
+ for more information.
+ This value will always be OR'ed with 022,
+ because
+ .I aegis
+ is paranoid.
+ .TP 8n
+ default_test_exemption = boolean;
+ .br
+ This field contains what to do when a change is created with
+ no test exemption specified.
Index: man5/aepconf.5
***************
*** 1,12 ****
  '\" t
  .\"	aegis - project change supervisor
! .\"	Copyright (c) 1991-1992 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 1, or (at your option)
! .\"	any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  '\" t
  .\"	aegis - project change supervisor
! .\"	Copyright (C) 1991, 1992, 1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 2 of the License, or
! .\"	(at your option) any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 38,86 ****
  This field describes how to build the project
  (actually, how to do an integration build).
  This field is mandatory.
! .RS 8n
! %1 = project name
! .br
! %2 = change number
! .br
! %3 = identifying string, in the form "a.b.Dnnn",
! where 'a' is the major version number, 'b' is the minor version number,
! and 'nnn' is the change number.
! .RE
  .TP 8n
  development_build_command = string;
  This field describes how to do a development build.
  If this field is absent, it defaults to the above.
! .RS 8n
! %1 = project name
! .br
! %2 = change number
! .br
! %3 = identifying string, in the form "a.b.Cnnn",
! where 'a' is the major version number, 'b' is the minor version number,
! and 'nnn' is the change number.
! .br
! %4 = the absolute path of the project baseline directory.
! .RE
  .TP 8n
  change_file_command = string;
  This field contains a command to be executed whenever
  a '\*(n) -CoPy_file', '\*(n) -CoPy_file_Undo', '\*(n) -New_File', '\*(n) -New_File_Undo', '\*(n) -ReMove_file'
  or '\*(n) -ReMove_file_Undo'
  command is successful.
  If this field is absent, nothing is done.
! .RS 8n
! %1 = project name
  .br
! %2 = change number
! .br
! %3 = identifying string, in the form "a.b.Cnnn",
! where 'a' is the major version number, 'b' is the minor version number,
! and 'nnn' is the change number.
! .br
! %4 = the absolute path of the project baseline directory.
! .br
! %5 = space separated list of files named
  .RE
  .TP 8n
  project_file_command = string;
--- 38,69 ----
  This field describes how to build the project
  (actually, how to do an integration build).
  This field is mandatory.
! All of the substitutions described by
! .IR aesub (5)
! are available.
  .TP 8n
  development_build_command = string;
  This field describes how to do a development build.
  If this field is absent, it defaults to the above.
! All of the substitutions described by
! .IR aesub (5)
! are available.
  .TP 8n
  change_file_command = string;
+ .RS 8n
  This field contains a command to be executed whenever
  a '\*(n) -CoPy_file', '\*(n) -CoPy_file_Undo', '\*(n) -New_File', '\*(n) -New_File_Undo', '\*(n) -ReMove_file'
  or '\*(n) -ReMove_file_Undo'
  command is successful.
  If this field is absent, nothing is done.
! All of the substitutions described by
! .IR aesub (5)
! are available;
! in addition,
! .TP 8n
! ${File_List}
  .br
! Space separated list of files named.
  .RE
  .TP 8n
  project_file_command = string;
***************
*** 87,108 ****
  .br
  This field contains a command to be executed
  during a development build
! before the 'development_build_command' above, when 
  (a) it is the first build after a develop begin, or
  (b) some other change has been integrated into
  the baseline since the last build.
  If this field is absent, nothing is done.
! .RS 8n
! %1 = project name
! .br
! %2 = change number
! .br
! %3 = identifying string, in the form "a.b.Cnnn",
! where 'a' is the major version number, 'b' is the minor version number,
! and 'nnn' is the change number.
! .br
! %4 = the absolute path of the project baseline directory.
! .RE
  .TP 8n
  integrate_begin_command = string;
  This field contains a command to be executed whenever
--- 70,85 ----
  .br
  This field contains a command to be executed
  during a development build
! before the
! .I "development build command"
! above, when 
  (a) it is the first build after a develop begin, or
  (b) some other change has been integrated into
  the baseline since the last build.
  If this field is absent, nothing is done.
! All of the substitutions described by
! .IR aesub (5)
! are available.
  .TP 8n
  integrate_begin_command = string;
  This field contains a command to be executed whenever
***************
*** 109,123 ****
  a '\*(n) -Integrate_Begin'
  command is successful.
  If this field is absent, nothing is done.
! .RS 8n
! %1 = project name
! .br
! %2 = change number
! .br
! %3 = identifying string, in the form "a.b.Dnnn",
! where 'a' is the major version number, 'b' is the minor version number,
! and 'nnn' is the change number.
! .RE
  .TP 8n
  link_integration_directory
  .br
--- 86,94 ----
  a '\*(n) -Integrate_Begin'
  command is successful.
  If this field is absent, nothing is done.
! All of the substitutions described by
! .IR aesub (5)
! are available.
  .TP 8n
  link_integration_directory
  .br
***************
*** 134,197 ****
  if this is not done the baseline will be corrupted.
  .TP 8n
  history_create_command = string;
  This field is used to create a new history.
  The command is always executed as the project owner.
! .RS 8n
! %1 = source file
  .br
! %2 = history file
  .RE
  .TP 8n
  history_get_command = string;
  This field is used to get a file from history.
  The command may be executed by developers.
! .RS 8n
! %1 = history file
  .br
! %2 = edit number
  .br
! %3 = destination file
  .RE
  .TP 8n
  history_put_command = string;
  This field is used to add a new change to the history.
  The command is always executed as the project owner.
! .RS 8n
! %1 = source file
  .br
! %2 = history file
  .RE
  .TP 8n
  history_query_command = string;
  This field is used to query the topmost edit of a history file.
! Result to be printed on stdout.
  This command may be executed by developers.
! .RS 8n
! %1 = history file
  .RE
  .TP 8n
  diff_command = string;
  This field is used to difference of 2 files.
  The command is always executed by developers.
! .RS 8n
! %1 = earlier file
  .br
! %2 = later file	
  .br
! %3 = output file
  .RE
  .TP 8n
  diff3_command = string;
  This field is used to difference 3 files.
  The command is always executed by developers.
! .RS 8n
! %1 = earliest file
  .br
! %2 = one competing edit
  .br
! %3 = another competing edit
  .br
! %4 = output file
  .RE
  .TP 8n
  file_template = [ { ... } ];
--- 105,256 ----
  if this is not done the baseline will be corrupted.
  .TP 8n
  history_create_command = string;
+ .RS 8n
  This field is used to create a new history.
  The command is always executed as the project owner.
! All of the substitutions described by
! .IR aesub (5)
! are available;
! in addition,
! .TP 8n
! ${Input}
  .br
! Absolute path of the source file.
! .TP 8n
! ${History}
! .br
! Absolute path of the history file.
! This may need to be reworked with the
! .I Dirname
! and
! .I Basename
! substitutions to yeild a string suitable for the history tool in question.
  .RE
  .TP 8n
  history_get_command = string;
+ .RS 8n
  This field is used to get a file from history.
  The command may be executed by developers.
! All of the substitutions described by
! .IR aesub (5)
! are available;
! in addition,
! .TP 8n
! ${History}
  .br
! The absolute path of the history file.
! This may need to be reworked with the
! .I Dirname
! and
! .I Basename
! substitutions to yeild a string suitable for the history tool in question.
! .TP 8n
! ${Edit}
  .br
! The edit number to be extracted.
! It may be an arbitrary string,
! varying on the particular history tool.
! .TP 8n
! ${Output}
! .br
! The absolute path of the destination file.
  .RE
  .TP 8n
  history_put_command = string;
+ .RS
  This field is used to add a new change to the history.
  The command is always executed as the project owner.
! All of the substitutions described by
! .IR aesub (5)
! are available;
! in addition,
! .TP 8n
! ${Input}
  .br
! The absolute path of the source file.
! .TP 8n
! ${History}
! .br
! The absolute path of the history file.
! This may need to be reworked with the
! .I Dirname
! and
! .I Basename
! substitutions to yeild a string suitable for the history tool in question.
  .RE
  .TP 8n
  history_query_command = string;
+ .RS 8n
  This field is used to query the topmost edit of a history file.
! Result to be printed on the standard output.
  This command may be executed by developers.
! All of the substitutions described by
! .IR aesub (5)
! are available;
! in addition,
! .TP 8n
! ${History}
! .br
! The absolute path of the history file.
! This may need to be reworked with the
! .I Dirname
! and
! .I Basename
! substitutions to yeild a string suitable for the history tool in question.
  .RE
  .TP 8n
  diff_command = string;
+ .RS
  This field is used to difference of 2 files.
  The command is always executed by developers.
! All of the substitutions described by
! .IR aesub (5)
! are available;
! in addition,
! .TP 8n
! ${ORiginal}
  .br
! The absolute path of the original
! file copied into the change.
! Usually in the baseline,
! but not always.
! .TP 8n
! ${Input}
  .br
! The absolute path of the file in the development directory.
! .TP 8n
! ${Output}
! .br
! The absolute path of the file in which to write the difference listing.
  .RE
  .TP 8n
  diff3_command = string;
+ .RS 8n
  This field is used to difference 3 files.
  The command is always executed by developers.
! All of the substitutions described by
! .IR aesub (5)
! are available;
! in addition,
! .TP 8n
! ${ORiginal}
  .br
! The absolute path of the original
! file copied into the change.
! Usually not in the baseline.
! .TP 8n
! ${Most_Recent}
  .br
! The absolute path of the competing edit,
! usually in the baseline.
! .TP 8n
! ${Input}
  .br
! The absolute path of the file in the development directory.
! .TP 8n
! ${Output}
! .br
! The absolute path of the file in which to write the difference listing.
  .RE
  .TP 8n
  file_template = [ { ... } ];
***************
*** 216,221 ****
--- 275,285 ----
  body = string;
  What to initialize the body of the file to.
  There are no substitutions.
+ .PP
+ All of the substitutions described in
+ .IR aesub (5)
+ are available for the body string.
+ In addition, ${File_Name} will be replaced by the name of the new file.
  .RE
  .SH SEE ALSO
  .IR aeb (1)
Index: man5/aepstate.5
***************
*** 1,12 ****
  '\" t
  .\"	aegis - project change supervisor
! .\"	Copyright (c) 1991-1992 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 1, or (at your option)
! .\"	any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  '\" t
  .\"	aegis - project change supervisor
! .\"	Copyright (C) 1991, 1992, 1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 2 of the License, or
! .\"	(at your option) any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 34,223 ****
  .B \*(n)
  and thus should not be edited by humans.
  .SH CONTENTS
! .TP 8n
! description = string;
! This field contains
! a description of the project.
! Large amounts of prose are not required;
! a single line is sufficient.
! .TP 8n
! owner_name = string;
! This field contains
! the name of the user to whom baseline files belong.
! .TP 8n
! group_name = string;
! This field contains
! the name of the group to which baseline files belong.
! .TP 8n
! developer_may_review = boolean;
! If this field is true, then a developer may review her own change.
! This is probably only a good idea for projects of less than 3 people.
! The idea is for as many people as possible to critically examine a change.
! .TP 8n
! developer_may_integrate = boolean;
! If this field is true, then a developer may integrate her own change.
! This is probably only a good idea for projects of less than 3 people.
! The idea is for as many people as possible to critically examine a change.
! .TP 8n
! reviewer_may_integrate = boolean;
! If this field is true, then a reviewer may integrate a change she reviewed.
! This is probably only a good idea for projects of less than 3 people.
! The idea is for as many people as possible to critically examine a change.
! .TP 8n
! developers_may_create_changes = boolean;
! This field is true if developers may created changes,
! in addition to administrators.
! This tends to be a very useful thing,
! since developers find most of the bugs.
! .TP 8n
! develop_end_notify_command = string;
! This command is used to
! notify that a change is ready for review.
! It will probably use mail,
! or it could be an in-house bulletin board.
! This field is optional,
! if not present no notification will be given.
! This command could also be used to notify other managament systems,
! such as progress and defect tracking.
! .RS 8n
! %1 = project name
! .br
! %2 = change number
! .br
! %3 = developer
! .RE
! .TP 8n
! develop_end_undo_notify_command = string;
! This command is used to
! notify that a change had been withdrawn from review
! for further development.
! It will probably use mail,
! or it could be an in-house bulletin board.
! This field is optional,
! if not present no notification will be given.
! This command could also be used to notify other managament systems,
! such as progress and defect tracking.
! .RS 8n
! %1 = project name
! .br
! %2 = change number
! .br
! %3 = developer
! .RE
! .TP 8n
! review_pass_notify_command = string;
! This command is used to
! notify that a review has passed.
! It will probably use mail,
! or it could be an in-house bulletin board.
! This field is optional,
! if not present no notification will be given.
! .RS 8n
! %1 = project name
! .br
! %2 = change number
! .br
! %3 = developer
! .br
! %4 = reviewer
! .RE
! .TP 8n
! review_pass_undo_notify_command = string;
! This command is used to
! notify that a review has passed.
! It will probably use mail,
! or it could be an in-house bulletin board.
! This field is optional,
! if not present no notification will be given.
! This command could also be used to notify other managament systems,
! such as progress and defect tracking.
! Defaults to the same action as the \fIdevelop_end_notify_command\fP field.
! .RS 8n
! %1 = project name
! .br
! %2 = change number
! .br
! %3 = developer
! .br
! %4 = reviewer
! .RE
! .TP 8n
! review_fail_notify_command = string;
! This command is used to
! notify that a review has failed.
! It will probably use mail,
! or it could be an in-house bulletin board.
! This field is optional,
! if not present no notification will be given.
! .RS 8n
! %1 = project name
! .br
! %2 = change number
! .br
! %3 = developer
! .br
! %4 = reviewer
! .RE
! .TP 8n
! integrate_pass_notify_command = string;
! This command is used to
! notify that an integration has passed.
! It will probably use mail,
! or it could be an in-house bulletin board.
! This field is optional,
! if not present no notification will be given.
! .RS 8n
! %1 = project name
! .br
! %2 = change number
! .br
! %3 = developer
! .br
! %4 = reviewer
! .br
! %5 = integrator
! .RE
! .TP 8n
! integrate_fail_notify_command = string;
! This command is used to
! notify that an integration has failed.
! It will probably use mail,
! or it could be an in-house bulletin board.
! This field is optional,
! if not present no notification will be given.
! .RS 8n
! %1 = project name
! .br
! %2 = change number
! .br
! %3 = developer
! .br
! %4 = reviewer
! .br
! %5 = integrator
! .RE
! .TP 8n
! default_development_directory = string;
! The pathname of where to place new development directories.
! The pathname must be absolute.
! This field is only consulted if
! the field of the same name in the user conf file is not set.
! .TP 8n
! umask = integer;
! .br
! File permission mode mask.
! See
! .IR umask (2)
! for more information.
! This value will always be OR'ed with 022,
! because
! .I aegis
! is paranoid.
! .TP 8n
! default_test_exemption = boolean;
! .br
! This field contains what to do when a change is created with
! no test exemption specified.
  .TP 8n
  next_change_number = integer;
  Changes are numbered sequentially from one.
--- 34,40 ----
  .B \*(n)
  and thus should not be edited by humans.
  .SH CONTENTS
! .so aepattr.so
  .TP 8n
  next_change_number = integer;
  Changes are numbered sequentially from one.
Index: man5/aesub.5
***************
*** 0 ****
--- 1,340 ----
+ '\" t
+ .\"	aegis - project change supervisor
+ .\"	Copyright (C) 1993 Peter Miller.
+ .\"	All rights reserved.
+ .\"
+ .\"	This program is free software; you can redistribute it and/or modify
+ .\"	it under the terms of the GNU General Public License as published by
+ .\"	the Free Software Foundation; either version 2 of the License, or
+ .\"	(at your option) any later version.
+ .\"
+ .\"	This program is distributed in the hope that it will be useful,
+ .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
+ .\"	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ .\"	GNU General Public License for more details.
+ .\"
+ .\"	You should have received a copy of the GNU General Public License
+ .\"	along with this program; if not, write to the Free Software
+ .\"	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ .\"
+ .\" MANIFEST: manual page describing command substitutions
+ .\"
+ .so z_name.so
+ .TH aesub 5 \*(N)
+ .if n .ad l
+ .if n .hy 0
+ .SH NAME
+ aesub \- available command substitutions
+ .SH DESCRIPTION
+ When other programs are invoked by the
+ .I aegis
+ program,
+ it is usually via a command string in a configuration file.
+ This section describes the format of these command strings.
+ .SH GENERAL FORM
+ The command strings are very similar to shell variables.
+ An example will illustrate this:
+ .RS 8n
+ .nf
+ build_command =
+ 	"cook project=${project} change=${change}";
+ .fi
+ .RE
+ In this command definition,
+ the "${project}" part is a substitution:
+ the name of the project will be substituted
+ in the command at this point.
+ .PP
+ Substitutions may take several forms:
+ .TP 8n
+ $name
+ .br
+ This is the same as saying "${name}".
+ The name must start with an alphabetic,
+ and be followed by zero or more alphanumerics.
+ .TP 8n
+ ${name}
+ .br
+ The name in this form may contain any non-blank characters,
+ and it may be subject to substitution.
+ .TP 8n
+ ${name \fIarg\fP...}
+ .br
+ The name and the arguments in this form may contain any non-blank characters,
+ and it may be subject to further substitution.
+ .TP 8n
+ $$
+ .br
+ This is replaced by a single $ character.
+ .PP
+ As another example,
+ the
+ .I dirname
+ substitution is replaced by the directory name of the argument,
+ rather like the
+ .IR dirname (1)
+ command.
+ In the command
+ .RS
+ .nf
+ history_query_command =
+ 	"get -t -g ${Dirname $History}/s.${Basename $History}";
+ .fi
+ .RE
+ the
+ .I Dirname
+ and
+ .I Basename
+ substitutions are used to construct a suitable path to the SCCS
+ file in the history directory.
+ .SH ABBREVIATIONS
+ The names of the various substitutions may be abbreviated.
+ In the above examples,
+ and in the lists which fillow,
+ the minimum abbreviation is the uppercase letters.
+ All substitution name sare case insensitive.
+ .PP
+ The above example could be abbreviated to
+ .RS
+ .nf
+ history_query_command =
+ 	"get -t -g ${d $h}/s.${b $h}";
+ .fi
+ .RE
+ .PP
+ Ambiguous abbreviations will result in a fatal error message.
+ .SH SUBSTITUTIONS
+ There are many substitutions which are always understood,
+ and some which are specific to the command being substituted.
+ Specific entries will be defined in the relevant manual section.
+ .PP
+ The following lists contains those substitutions which are always understood:
+ .TP 8n
+ Administrator_List
+ .br
+ Space separated list of the project's administrators.
+ .TP 8n
+ BaseLine
+ .br
+ Absolute path of the the project's baseline.
+ .TP 8n
+ Basename
+ .br
+ This substitution takes one argument,
+ a pathname.
+ The value of the substitution will be the last element of the pathname.
+ This is similar to the
+ .IR basename (1)
+ command.
+ .TP 8n
+ Change
+ .br
+ The change number.
+ .TP 8n
+ DAte
+ .br
+ With no arguments,
+ the output is the current date.
+ If there are arguments,
+ they forma format string.
+ This is similar to the
+ .IR date (1)
+ command on many UNIX systems.
+ For a description of the date formats,
+ see the
+ .I DATE
+ section,
+ below.
+ .TP 8n
+ DELta
+ .br
+ The delta number of the change.
+ This is only available when the change is in the
+ .I "being integrated"
+ state or the
+ .I completed
+ state.
+ .TP 8n
+ DEVeloper
+ .br
+ The name of the developer.
+ .TP 8n
+ DEVeloper_List
+ .br
+ Space separated list of the project's developers.
+ .TP 8n
+ Development_Directory
+ .br
+ The absolute path of the change's development directory.
+ Only available when the change is between the
+ .I "being developed"
+ state and the
+ .I "being intgrated"
+ state.
+ .TP 8n
+ Dirname
+ .br
+ This substitution takes one argument,
+ a pathname.
+ The value of the substitution will be everything but
+ the last element of the pathname.
+ This is similar to the
+ .IR dirname (1)
+ command.
+ .TP 8n
+ DownCase
+ .br
+ This substitution takes one argument.
+ The value of the substitution will be the argument with
+ any upper case letters mapped to lower case.
+ .TP 8n
+ IDentifier
+ .br
+ This substitution takes one argument.
+ The value of the substitution will be the argument with
+ all characters but alpha numerics mapped into an underscore (_),
+ so as to form a legal C identifier.
+ .TP 8n
+ INTegration_Directory
+ .br
+ The absolute path of the change's integration directory.
+ Only available when the change is in the
+ .I "being intgrated"
+ state.
+ .TP 8n
+ INTegrator
+ .br
+ The name of the change's integrator.
+ Only available when the change is in the
+ .I "being integrated"
+ state or the
+ .I "completed"
+ state.
+ .TP 8n
+ INTegrator_List
+ .br
+ Space separated list of the project's integrators.
+ .TP 8n
+ Project
+ .br
+ The name of the project.
+ .TP 8n
+ Reviewer
+ .br
+ The name of the change's reviewer.
+ Only available when the change is between the
+ .I "awaiting integration"
+ state and the
+ .I "completed"
+ state.
+ .TP 8n
+ Reviewer_List
+ .br
+ Space separated list of the project's reviewers.
+ .TP 8n
+ UpCase
+ .br
+ This substitution takes one argument.
+ The value of the substitution will be the argument with
+ any lower case letters mapped to upper case.
+ .TP 8n
+ Version
+ .br
+ The version of the change.
+ If the change is in the
+ .I "being integrated"
+ state or the
+ .I "completed"
+ state,
+ the version will be of the form "\fIa\fB.\fIb\fB.D\fIddd\fR",
+ where "a" is the project's major version number,
+ "b" is the project's minor version number, and
+ "ddd" is the change's delta number.
+ If the change is in any other state,
+ the version will be of the form "\fIa\fB.\fIb\fB.C\fIccc\fR",
+ where "ccc" is the change number.
+ .SH DATE
+ This section describes the format specifiers accepted by the
+ date substitution.
+ These are the same specifiers as defined
+ by the ANSI C standard
+ for the strftime function.
+ .TP 8n
+ %%
+ The percent character (%)
+ .TP 8n
+ %a
+ tyhe abbreviated weekday name
+ .TP 8n
+ %A
+ the full weekday name
+ .TP 8n
+ %b
+ the abbreviated month name
+ .TP 8n
+ %B
+ the full month name
+ .TP 8n
+ %c
+ the date and time
+ .TP 8n
+ %d
+ the day of the month,
+ zero padded
+ .TP 8n
+ %H
+ the hour of the 24-hour day
+ .TP 8n
+ %I
+ the hour of the 12-hour day
+ .TP 8n
+ %j
+ the day number of year,
+ zero padded, one based
+ .TP 8n
+ %m
+ the month of the year,
+ zero padded, one based
+ .TP 8n
+ %M
+ the minute of the hour,
+ zero padded
+ .TP 8n
+ %p
+ meridian indicator,
+ AM or PM as appropriate
+ .TP 8n
+ %S
+ the second of the minute
+ .TP 8n
+ %U
+ the Sunday week of the year
+ .TP 8n
+ %w
+ the day of the week,
+ Sunday is 0
+ .TP 8n
+ %W
+ the Monday week of the year
+ .TP 8n
+ %x
+ the date,
+ as \fImmm dd yyyy\fP
+ .TP 8n
+ %X
+ the time,
+ as \fIhh:mm:ss\fP
+ .TP 8n
+ %y
+ the year of the century
+ .TP 8n
+ %Y
+ the year including the century
+ .TP 8n
+ %Z
+ time zone abbreviation
+ .PP
+ Using an undefined format specifier will
+ produce random results,
+ depending on the version of UNIX you are on.
+ .so z_cr.so
Index: man5/aeuconf.5
***************
*** 1,12 ****
  '\" t
  .\"	aegis - project change supervisor
! .\"	Copyright (c) 1991-1992 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 1, or (at your option)
! .\"	any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  '\" t
  .\"	aegis - project change supervisor
! .\"	Copyright (C) 1991, 1992, 1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 2 of the License, or
! .\"	(at your option) any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 26,32 ****
  .SH SYNOPSIS
  \fI$HOME\f(CW/.\*(n)rc\fR
  .SH DESCTIPTION
! A user configuratiion file
  is used to hold user defaults.
  This file is created and edited by the user.
  This file is only ever read by \*(n).
--- 26,32 ----
  .SH SYNOPSIS
  \fI$HOME\f(CW/.\*(n)rc\fR
  .SH DESCTIPTION
! A user configuration file
  is used to hold user defaults.
  This file is created and edited by the user.
  This file is only ever read by \*(n).
***************
*** 34,39 ****
--- 34,40 ----
  The file contains the following fields:
  .TP 8n
  default_development_directory = string;
+ .br
  The pathname of where to place new development directories.
  The pathname may be relative,
  in which case it is relative to \fI$HOME\fP.
***************
*** 41,46 ****
--- 42,48 ----
  or \fI$HOME\fP neither is set.
  .TP 8n
  default_project_directory = string;
+ .br
  The pathname of where to place new project directories.
  The pathname may be relative.
  If this path is relative,
***************
*** 48,58 ****
  The default is \fI$HOME\fP.
  .TP 8n
  default_project_name = string;
  The name of a project.
  .PP
! Becase this file is not maintained by \*(n),
! it is not possible to place a default change here.
! .PP
! This file has higher precedence than \*(n)'s defaults,
! for the host on which it appears.
  .so z_cr.so
--- 50,68 ----
  The default is \fI$HOME\fP.
  .TP 8n
  default_project_name = string;
+ .br
  The name of a project.
+ .TP 8n
+ default_change_number = integer;
+ .br
+ The number of a change.
  .PP
! Please note that the
! .I default_project_name
! field and the
! .I default_change_number
! field
! are unrelated.
! Specifying both does not mean that single change within that single project,
! they have nothing to do with each other.
  .so z_cr.so
Index: man5/aeustate.5
***************
*** 1,12 ****
  '\" t
  .\"	aegis - project change supervisor
! .\"	Copyright (c) 1991-1992  Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 1, or (at your option)
! .\"	any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
  '\" t
  .\"	aegis - project change supervisor
! .\"	Copyright (C) 1991, 1992, 1993  Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 2 of the License, or
! .\"	(at your option) any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
Index: man5/z_cr.so
***************
*** 1,11 ****
  .\"	aegis - project change supervisor
! .\"	Copyright (c) 1991-1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 1, or (at your option)
! .\"	any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
+ .\"
  .\"	aegis - project change supervisor
! .\"	Copyright (C) 1991, 1992, 1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 2 of the License, or
! .\"	(at your option) any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 18,28 ****
  .\"
  .\" MANIFEST: copyright and author parts of section 5 manual entries
  .\"
  .SH COPYRIGHT
! .if t .ds c) \(co
! .if n .ds c) (c)
! The \*(n) program is Copyright \*(c) 1991-1993 Peter Miller.
  .br
  All rights reserved.
  .sp
  The \*(n) program comes with ABSOLUTELY NO WARRANTY;
--- 19,34 ----
  .\"
  .\" MANIFEST: copyright and author parts of section 5 manual entries
  .\"
+ .br
+ .ne 2i
  .SH COPYRIGHT
! \*(n) version
! .so ../doc/version.so
  .br
+ .if t .ds C) \(co
+ .if n .ds C) (C)
+ Copyright \*(C) 1990, 1991, 1992, 1993 Peter Miller.
+ .br
  All rights reserved.
  .sp
  The \*(n) program comes with ABSOLUTELY NO WARRANTY;
***************
*** 30,39 ****
  This is free software
  and you are welcome to redistribute it under certain conditions;
  for details use the '\fI\*(n) -VERSion Redistribution\fP' command.
  .SH AUTHOR
  .TS
  tab(;);
  l l l.
  Peter Miller;UUCP;uunet!munnari!bmr.gov.au!pmiller
! \f(CW/\e/\e*\fR;CSNET;pmiller@bmr.gov.au
  .TE
--- 36,47 ----
  This is free software
  and you are welcome to redistribute it under certain conditions;
  for details use the '\fI\*(n) -VERSion Redistribution\fP' command.
+ .br
+ .ne 1i
  .SH AUTHOR
  .TS
  tab(;);
  l l l.
  Peter Miller;UUCP;uunet!munnari!bmr.gov.au!pmiller
! \f(CW/\e/\e*\fR;Internet;pmiller@bmr.gov.au
  .TE
Index: man5/z_name.so
***************
*** 1,11 ****
  .\"	aegis - project change supervisor
! .\"	Copyright (c) 1991-1992 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 1, or (at your option)
! .\"	any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,12 ----
+ .\"
  .\"	aegis - project change supervisor
! .\"	Copyright (C) 1991, 1992, 1993 Peter Miller.
  .\"	All rights reserved.
  .\"
  .\"	This program is free software; you can redistribute it and/or modify
  .\"	it under the terms of the GNU General Public License as published by
! .\"	the Free Software Foundation; either version 2 of the License, or
! .\"	(at your option) any later version.
  .\"
  .\"	This program is distributed in the hope that it will be useful,
  .\"	but WITHOUT ANY WARRANTY; without even the implied warranty of
Index: test/00/t0001a.sh
***************
*** 1,13 ****
! #!/bin/sh
  #
  #	aegis - project change supervisor
! #	Copyright (c) 1991-1992 Peter Miller.
  #	All rights reserved.
  #
  #	This program is free software; you can redistribute it and/or modify
  #	it under the terms of the GNU General Public License as published by
! #	the Free Software Foundation; either version 1, or (at your option)
! #	any later version.
  #
  #	This program is distributed in the hope that it will be useful,
  #	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,13 ----
! #! /bin/sh
  #
  #	aegis - project change supervisor
! #	Copyright (C) 1991, 1992, 1993 Peter Miller.
  #	All rights reserved.
  #
  #	This program is free software; you can redistribute it and/or modify
  #	it under the terms of the GNU General Public License as published by
! #	the Free Software Foundation; either version 2 of the License, or
! #	(at your option) any later version.
  #
  #	This program is distributed in the hope that it will be useful,
  #	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 18,31 ****
  #	along with this program; if not, write to the Free Software
  #	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  #
- # ----------------------------------------------------------------------
- #
  # MANIFEST: test -Help for each function
  #
  
  fail()
  {
! 	echo FAILED 1>&2
  	exit 1
  }
  pass()
--- 18,32 ----
  #	along with this program; if not, write to the Free Software
  #	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  #
  # MANIFEST: test -Help for each function
  #
  
+ unset AEGIS_PROJECT
+ unset AEGIS_CHANGE
+ 
  fail()
  {
! 	echo FAILED test of -Help for each function 1>&2
  	exit 1
  }
  pass()
Index: test/00/t0002a.sh
***************
*** 1,13 ****
! #!/bin/sh
  #
  #	aegis - project change supervisor
! #	Copyright (c) 1991-1992 Peter Miller.
  #	All rights reserved.
  #
  #	This program is free software; you can redistribute it and/or modify
  #	it under the terms of the GNU General Public License as published by
! #	the Free Software Foundation; either version 1, or (at your option)
! #	any later version.
  #
  #	This program is distributed in the hope that it will be useful,
  #	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,13 ----
! #! /bin/sh
  #
  #	aegis - project change supervisor
! #	Copyright (C) 1991, 1992, 1993 Peter Miller.
  #	All rights reserved.
  #
  #	This program is free software; you can redistribute it and/or modify
  #	it under the terms of the GNU General Public License as published by
! #	the Free Software Foundation; either version 2 of the License, or
! #	(at your option) any later version.
  #
  #	This program is distributed in the hope that it will be useful,
  #	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 18,34 ****
  #	along with this program; if not, write to the Free Software
  #	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  #
- # ----------------------------------------------------------------------
- #
  # MANIFEST: Test core functionality.
  #
  
! work=/tmp/$$
  
  fail()
  {
  	set +x
! 	echo FAILED 1>&2
  	find $work -type d -user $USER -exec chmod u+w {} \;
  	rm -rf $work
  	exit 1
--- 18,35 ----
  #	along with this program; if not, write to the Free Software
  #	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  #
  # MANIFEST: Test core functionality.
  #
  
! unset AEGIS_PROJECT
! unset AEGIS_CHANGE
  
+ work=${AEGIS_TMP-/tmp}/$$
+ 
  fail()
  {
  	set +x
! 	echo FAILED test of core functionality 1>&2
  	find $work -type d -user $USER -exec chmod u+w {} \;
  	rm -rf $work
  	exit 1
***************
*** 79,85 ****
  developer_may_integrate = true;
  reviewer_may_integrate = true;
  end
! ./bin/aegis -proatt -list -proj foo -lib $worklib
  if test $? -ne 0 ; then fail; fi
  ./bin/aegis -proatt $tmp -proj foo -lib $worklib
  if test $? -ne 0 ; then fail; fi
--- 80,86 ----
  developer_may_integrate = true;
  reviewer_may_integrate = true;
  end
! ./bin/aegis -proatt -list --proj=foo -lib $worklib
  if test $? -ne 0 ; then fail; fi
  ./bin/aegis -proatt $tmp -proj foo -lib $worklib
  if test $? -ne 0 ; then fail; fi
***************
*** 157,193 ****
  }
  end
  cat > $workchan/config << 'end'
! /*
!  * %1 is set to the change number or build number
!  */
! build_command = "rm -f foo; cc -o foo -D'VERSION=\"%3\"' main.c";
  
  history_get_command =
! 	"co -u'%2' -p %1,v > %3";
  history_create_command =
! 	"ci -u -m/dev/null -t/dev/null %1 %2,v; rcs -U %2,v";
  history_put_command =
! 	"ci -u -m/dev/null -t/dev/null %1 %2,v; rcs -U %2,v";
  history_query_command =
! 	"rlog -r %1,v | awk '/^head:/ {print $2}'";
  
! /*
!  * difference of 2 files
!  * %1 is one input file
!  * %2 is the other input file
!  * %3 is the output file
!  */
! diff_command = "set +e; diff %1 %2 > %3; test $? -le 1";
  
! /*
!  * difference of 3 files
!  * %1 is one base file
!  * %2 is an input file
!  * %3 is an input file
!  * %4 is the output file
!  */
! diff3_command = "(diff3 -e %2 %1 %3 | sed -e '/^w$/d' -e '/^q$/d'; \
! 	echo '1,$p' ) | ed - %2 > %4";
  
  /*
   * file templates
--- 158,178 ----
  }
  end
  cat > $workchan/config << 'end'
! build_command = "rm -f foo; cc -o foo -D'VERSION=\"$v\"' main.c";
  
  history_get_command =
! 	"co -u'$e' -p $h,v > $o";
  history_create_command =
! 	"ci -u -m/dev/null -t/dev/null $i $h,v; rcs -U $h,v";
  history_put_command =
! 	"ci -u -m/dev/null -t/dev/null $i $h,v; rcs -U $h,v";
  history_query_command =
! 	"rlog -r $h,v | awk '/^head:/ {print $$2}'";
  
! diff_command = "set +e; diff $orig $i > $out; test $$? -le 1";
  
! diff3_command = "(diff3 -e $mr $orig $i | sed -e '/^w$$/d' -e '/^q$$/d'; \
! 	echo '1,$$p' ) | ed - $mr > $out";
  
  /*
   * file templates
***************
*** 221,227 ****
  
  fail()
  {
! 	echo FAILED 1>&2
  	exit 1
  }
  pass()
--- 206,212 ----
  
  fail()
  {
! 	echo SHUZBUTT 1>&2
  	exit 1
  }
  pass()
***************
*** 518,524 ****
  
  fail()
  {
! 	echo FAILED 1>&2
  	exit 1
  }
  pass()
--- 503,509 ----
  
  fail()
  {
! 	echo SHUZBUTT 1>&2
  	exit 1
  }
  pass()
Index: test/00/t0003a.sh
***************
*** 1,13 ****
! #!/bin/sh
  #
  #	aegis - project change supervisor
! #	Copyright (c) 1991-1992 Peter Miller.
  #	All rights reserved.
  #
  #	This program is free software; you can redistribute it and/or modify
  #	it under the terms of the GNU General Public License as published by
! #	the Free Software Foundation; either version 1, or (at your option)
! #	any later version.
  #
  #	This program is distributed in the hope that it will be useful,
  #	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,13 ----
! #! /bin/sh
  #
  #	aegis - project change supervisor
! #	Copyright (C) 1991, 1992, 1993 Peter Miller.
  #	All rights reserved.
  #
  #	This program is free software; you can redistribute it and/or modify
  #	it under the terms of the GNU General Public License as published by
! #	the Free Software Foundation; either version 2 of the License, or
! #	(at your option) any later version.
  #
  #	This program is distributed in the hope that it will be useful,
  #	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 18,31 ****
  #	along with this program; if not, write to the Free Software
  #	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  #
- # ----------------------------------------------------------------------
- #
  # MANIFEST: Test 'aegis -VERSion'
  #
  
  fail()
  {
! 	echo FAILED 1>&2
  	exit 1
  }
  pass()
--- 18,32 ----
  #	along with this program; if not, write to the Free Software
  #	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  #
  # MANIFEST: Test 'aegis -VERSion'
  #
  
+ unset AEGIS_PROJECT
+ unset AEGIS_CHANGE
+ 
  fail()
  {
! 	echo "FAILED test of 'aegis -VERSion'" 1>&2
  	exit 1
  }
  pass()
Index: test/00/t0004a.sh
***************
*** 1,13 ****
! #!/bin/sh
  #
  #	aegis - project change supervisor
! #	Copyright (c) 1991-1992 Peter Miller.
  #	All rights reserved.
  #
  #	This program is free software; you can redistribute it and/or modify
  #	it under the terms of the GNU General Public License as published by
! #	the Free Software Foundation; either version 1, or (at your option)
! #	any later version.
  #
  #	This program is distributed in the hope that it will be useful,
  #	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,13 ----
! #! /bin/sh
  #
  #	aegis - project change supervisor
! #	Copyright (C) 1991, 1992, 1993 Peter Miller.
  #	All rights reserved.
  #
  #	This program is free software; you can redistribute it and/or modify
  #	it under the terms of the GNU General Public License as published by
! #	the Free Software Foundation; either version 2 of the License, or
! #	(at your option) any later version.
  #
  #	This program is distributed in the hope that it will be useful,
  #	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 18,25 ****
  #	along with this program; if not, write to the Free Software
  #	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  #
- # ----------------------------------------------------------------------
- #
  # MANIFEST: Test the 'aegis -DIFFerence' command.
  #
  # File which are removed should be 'diff /baseline/x /dev/null'ed,
--- 18,23 ----
***************
*** 28,39 ****
  # file is used, because it will not be found.
  #
  
! work=/tmp/$$
  
  fail()
  {
  	set +x
! 	echo FAILED 1>&2
  	find $work -type d -user $USER -exec chmod u+w {} \;
  	rm -rf $work
  	exit 1
--- 26,40 ----
  # file is used, because it will not be found.
  #
  
! unset AEGIS_PROJECT
! unset AEGIS_CHANGE
  
+ work=${AEGIS_TMP-/tmp}/$$
+ 
  fail()
  {
  	set +x
! 	echo "FAILED test of 'aegis -DIFFerence' command" 1>&2
  	find $work -type d -user $USER -exec chmod u+w {} \;
  	rm -rf $work
  	exit 1
***************
*** 147,181 ****
  # put something in 'config'
  #
  cat > $workchan/config << 'end'
! build_command = "rm -f foo; cc -o foo -D'VERSION=\"%3\"' main.c";
  link_integration_directory = true;
  
  history_get_command =
! 	"co -u'%2' -p %1,v > %3";
  history_create_command =
! 	"ci -u -m/dev/null -t/dev/null %1 %2,v; rcs -U %2,v";
  history_put_command =
! 	"ci -u -m/dev/null -t/dev/null %1 %2,v; rcs -U %2,v";
  history_query_command =
! 	"rlog -r %1,v | awk '/^head:/ {print $2}'";
  
! /*
!  * difference of 2 files
!  * %1 is one input file
!  * %2 is the other input file
!  * %3 is the output file
!  */
! diff_command = "set +e; diff %1 %2 > %3; test $? -le 1";
  
! /*
!  * difference of 3 files
!  * %1 is one base file
!  * %2 is an input file
!  * %3 is an input file
!  * %4 is the output file
!  */
! diff3_command = "(diff3 -e %2 %1 %3 | sed -e '/^w$/d' -e '/^q$/d'; \
! 	echo '1,$p' ) | ed - %2 > %4";
  end
  
  #
--- 148,169 ----
  # put something in 'config'
  #
  cat > $workchan/config << 'end'
! build_command = "rm -f foo; cc -o foo -D'VERSION=\"$v\"' main.c";
  link_integration_directory = true;
  
  history_get_command =
! 	"co -u'$e' -p $h,v > $o";
  history_create_command =
! 	"ci -u -m/dev/null -t/dev/null $i $h,v; rcs -U $h,v";
  history_put_command =
! 	"ci -u -m/dev/null -t/dev/null $i $h,v; rcs -U $h,v";
  history_query_command =
! 	"rlog -r $h,v | awk '/^head:/ {print $$2}'";
  
! diff_command = "set +e; diff $orig $i > $out; test $$? -le 1";
  
! diff3_command = "(diff3 -e $mr $orig $i | sed -e '/^w$$/d' -e '/^q$$/d'; \
! 	echo '1,$$p' ) | ed - $mr > $out";
  end
  
  #
***************
*** 196,202 ****
  
  fail()
  {
! 	echo FAILED 1>&2
  	exit 1
  }
  pass()
--- 184,190 ----
  
  fail()
  {
! 	echo SHUZBUTT 1>&2
  	exit 1
  }
  pass()
***************
*** 349,355 ****
  
  fail()
  {
! 	echo FAILED 1>&2
  	exit 1
  }
  pass()
--- 337,343 ----
  
  fail()
  {
! 	echo SHUZBUTT 1>&2
  	exit 1
  }
  pass()
Index: test/00/t0005a.sh
***************
*** 1,13 ****
! #!/bin/sh
  #
  #	aegis - project change supervisor
! #	Copyright (c) 1991-1992 Peter Miller.
  #	All rights reserved.
  #
  #	This program is free software; you can redistribute it and/or modify
  #	it under the terms of the GNU General Public License as published by
! #	the Free Software Foundation; either version 1, or (at your option)
! #	any later version.
  #
  #	This program is distributed in the hope that it will be useful,
  #	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,13 ----
! #! /bin/sh
  #
  #	aegis - project change supervisor
! #	Copyright (C) 1991, 1992, 1993 Peter Miller.
  #	All rights reserved.
  #
  #	This program is free software; you can redistribute it and/or modify
  #	it under the terms of the GNU General Public License as published by
! #	the Free Software Foundation; either version 2 of the License, or
! #	(at your option) any later version.
  #
  #	This program is distributed in the hope that it will be useful,
  #	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 18,25 ****
  #	along with this program; if not, write to the Free Software
  #	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  #
- # ----------------------------------------------------------------------
- #
  # MANIFEST: Test the 'aegis -DevEnd' command.
  #
  # File which are removed should not be
--- 18,23 ----
***************
*** 26,39 ****
  # check to see if their last-modified-time is kosher.
  #
  
  PAGER=cat
  export PAGER
! work=/tmp/$$
  
  fail()
  {
  	set +x
! 	echo FAILED 1>&2
  	find $work -type d -user $USER -exec chmod u+w {} \;
  	rm -rf $work
  	exit 1
--- 24,40 ----
  # check to see if their last-modified-time is kosher.
  #
  
+ unset AEGIS_PROJECT
+ unset AEGIS_CHANGE
+ 
  PAGER=cat
  export PAGER
! work=${AEGIS_TMP-/tmp}/$$
  
  fail()
  {
  	set +x
! 	echo "FAILED test of 'aegis -DevEnd' command" 1>&2
  	find $work -type d -user $USER -exec chmod u+w {} \;
  	rm -rf $work
  	exit 1
***************
*** 145,179 ****
  # put something in 'config'
  #
  cat > $workchan/config << 'end'
! build_command = "rm -f foo; cc -o foo -D'VERSION=\"%3\"' main.c";
  link_integration_directory = true;
  
  history_get_command =
! 	"co -u'%2' -p %1,v > %3";
  history_create_command =
! 	"ci -u -m/dev/null -t/dev/null %1 %2,v; rcs -U %2,v";
  history_put_command =
! 	"ci -u -m/dev/null -t/dev/null %1 %2,v; rcs -U %2,v";
  history_query_command =
! 	"rlog -r %1,v | awk '/^head:/ {print $2}'";
  
! /*
!  * difference of 2 files
!  * %1 is one input file
!  * %2 is the other input file
!  * %3 is the output file
!  */
! diff_command = "set +e; diff %1 %2 > %3; test $? -le 1";
  
! /*
!  * difference of 3 files
!  * %1 is one base file
!  * %2 is an input file
!  * %3 is an input file
!  * %4 is the output file
!  */
! diff3_command = "(diff3 -e %2 %1 %3 | sed -e '/^w$/d' -e '/^q$/d'; \
! 	echo '1,$p' ) | ed - %2 > %4";
  end
  
  #
--- 146,167 ----
  # put something in 'config'
  #
  cat > $workchan/config << 'end'
! build_command = "rm -f foo; cc -o foo -D'VERSION=\"$vers\"' main.c";
  link_integration_directory = true;
  
  history_get_command =
! 	"co -u'$e' -p $h,v > $o";
  history_create_command =
! 	"ci -u -m/dev/null -t/dev/null $i $h,v; rcs -U $h,v";
  history_put_command =
! 	"ci -u -m/dev/null -t/dev/null $i $h,v; rcs -U $h,v";
  history_query_command =
! 	"rlog -r $h,v | awk '/^head:/ {print $$2}'";
  
! diff_command = "set +e; diff $orig $i > $out; test $$? -le 1";
  
! diff3_command = "(diff3 -e $mr $orig $i | sed -e '/^w$$/d' -e '/^q$$/d'; \
! 	echo '1,$$p' ) | ed - $mr > $out";
  end
  
  #
***************
*** 194,200 ****
  
  fail()
  {
! 	echo FAILED 1>&2
  	exit 1
  }
  pass()
--- 182,188 ----
  
  fail()
  {
! 	echo SHUZBUTT 1>&2
  	exit 1
  }
  pass()
***************
*** 347,353 ****
  
  fail()
  {
! 	echo FAILED 1>&2
  	exit 1
  }
  pass()
--- 335,341 ----
  
  fail()
  {
! 	echo SHUZBUTT 1>&2
  	exit 1
  }
  pass()
Index: test/00/t0006a.sh
***************
*** 1,13 ****
! #!/bin/sh
  #
  #	aegis - project change supervisor
! #	Copyright (c) 1991-1992 Peter Miller.
  #	All rights reserved.
  #
  #	This program is free software; you can redistribute it and/or modify
  #	it under the terms of the GNU General Public License as published by
! #	the Free Software Foundation; either version 1, or (at your option)
! #	any later version.
  #
  #	This program is distributed in the hope that it will be useful,
  #	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,13 ----
! #! /bin/sh
  #
  #	aegis - project change supervisor
! #	Copyright (C) 1991, 1992, 1993 Peter Miller.
  #	All rights reserved.
  #
  #	This program is free software; you can redistribute it and/or modify
  #	it under the terms of the GNU General Public License as published by
! #	the Free Software Foundation; either version 2 of the License, or
! #	(at your option) any later version.
  #
  #	This program is distributed in the hope that it will be useful,
  #	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 18,39 ****
  #	along with this program; if not, write to the Free Software
  #	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  #
- # ----------------------------------------------------------------------
- #
- #
  # MANIFEST: Test 'aegis -DIFFerence' when the edit number is out-of-date.
  #
  # The bug results in a string of length 0 being passed.
  #
  
  PAGER=cat
  export PAGER
! work=/tmp/$$
  
  fail()
  {
  	set +x
! 	echo FAILED 1>&2
  	find $work -type d -user $USER -exec chmod u+w {} \;
  	rm -rf $work
  	exit 1
--- 18,39 ----
  #	along with this program; if not, write to the Free Software
  #	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  #
  # MANIFEST: Test 'aegis -DIFFerence' when the edit number is out-of-date.
  #
  # The bug results in a string of length 0 being passed.
  #
  
+ unset AEGIS_PROJECT
+ unset AEGIS_CHANGE
+ 
  PAGER=cat
  export PAGER
! work=${AEGIS_TMP-/tmp}/$$
  
  fail()
  {
  	set +x
! 	echo "FAILED test of 'aegis -DIFFerence' when the edit number is out-of-date" 1>&2
  	find $work -type d -user $USER -exec chmod u+w {} \;
  	rm -rf $work
  	exit 1
***************
*** 148,182 ****
  }
  end
  cat > $workchan/config << 'end'
! build_command = "rm -f foo; cc -o foo -D'VERSION=\"%3\"' main.c";
  link_integration_directory = true;
  
  history_get_command =
! 	"co -u'%2' -p %1,v > %3";
  history_create_command =
! 	"ci -u -m/dev/null -t/dev/null %1 %2,v; rcs -U %2,v";
  history_put_command =
! 	"ci -u -m/dev/null -t/dev/null %1 %2,v; rcs -U %2,v";
  history_query_command =
! 	"rlog -r %1,v | awk '/^head:/ {print $2}'";
  
! /*
!  * difference of 2 files
!  * %1 is one input file
!  * %2 is the other input file
!  * %3 is the output file
!  */
! diff_command = "set +e; diff %1 %2 > %3; test $? -le 1";
  
! /*
!  * difference of 3 files
!  * %1 is one base file
!  * %2 is an input file
!  * %3 is an input file
!  * %4 is the output file
!  */
! diff3_command = "(diff3 -e %2 %1 %3 | sed -e '/^w$/d' -e '/^q$/d'; \
! 	echo '1,$p' ) | ed - %2 > %4";
  end
  
  #
--- 148,169 ----
  }
  end
  cat > $workchan/config << 'end'
! build_command = "rm -f foo; cc -o foo -D'VERSION=\"$version\"' main.c";
  link_integration_directory = true;
  
  history_get_command =
! 	"co -u'$e' -p $h,v > $o";
  history_create_command =
! 	"ci -u -m/dev/null -t/dev/null $i $h,v; rcs -U $h,v";
  history_put_command =
! 	"ci -u -m/dev/null -t/dev/null $i $h,v; rcs -U $h,v";
  history_query_command =
! 	"rlog -r $h,v | awk '/^head:/ {print $$2}'";
  
! diff_command = "set +e; diff $orig $i > $out; test $$? -le 1";
  
! diff3_command = "(diff3 -e $mr $orig $i | sed -e '/^w$$/d' -e '/^q$$/d'; \
! 	echo '1,$$p' ) | ed - $mr > $out";
  end
  
  #
***************
*** 195,201 ****
  
  fail()
  {
! 	echo FAILED 1>&2
  	exit 1
  }
  pass()
--- 182,188 ----
  
  fail()
  {
! 	echo SHUZBUTT 1>&2
  	exit 1
  }
  pass()
***************
*** 350,356 ****
  
  fail()
  {
! 	echo FAILED 1>&2
  	exit 1
  }
  pass()
--- 337,343 ----
  
  fail()
  {
! 	echo SHUZBUTT 1>&2
  	exit 1
  }
  pass()
Index: test/00/t0007a.sh
***************
*** 1,13 ****
! #!/bin/sh
  #
  #	aegis - project change supervisor
! #	Copyright (c) 1991-1992 Peter Miller.
  #	All rights reserved.
  #
  #	This program is free software; you can redistribute it and/or modify
  #	it under the terms of the GNU General Public License as published by
! #	the Free Software Foundation; either version 1, or (at your option)
! #	any later version.
  #
  #	This program is distributed in the hope that it will be useful,
  #	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,13 ----
! #! /bin/sh
  #
  #	aegis - project change supervisor
! #	Copyright (C) 1991, 1992, 1993 Peter Miller.
  #	All rights reserved.
  #
  #	This program is free software; you can redistribute it and/or modify
  #	it under the terms of the GNU General Public License as published by
! #	the Free Software Foundation; either version 2 of the License, or
! #	(at your option) any later version.
  #
  #	This program is distributed in the hope that it will be useful,
  #	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 18,25 ****
  #	along with this program; if not, write to the Free Software
  #	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  #
- # ----------------------------------------------------------------------
- #
  # MANIFEST: test for correct behaviour around symbolic links
  #
  # Make sure can cope with symbolic links.
--- 18,23 ----
***************
*** 26,48 ****
  # This test will always pass on systems without symbolic links.
  #
  
  PAGER=cat
  export PAGER
! work=/tmp/$$
  
! #
! # make sure machine has symbolic links
! # (machines without always pass this test)
! # ((fail if can't find /usr/include/sys/stat.h))
! #
! grep IFLNK /usr/include/sys/stat.h > /dev/null
! q=$?
! if test $q -eq 1 ; then exit 0; fi
! if test $q -ne 0 ; then exit 1; fi
  
  fail()
  {
! 	echo FAILED 1>&2
  	find $work -type d -user $USER -exec chmod u+w {} \;
  	rm -rf $work
  	exit 1
--- 24,46 ----
  # This test will always pass on systems without symbolic links.
  #
  
+ unset AEGIS_PROJECT
+ unset AEGIS_CHANGE
+ 
  PAGER=cat
  export PAGER
! work=${AEGIS_TMP-/tmp}/$$
  
! here=`pwd`
! if test $? -ne 0 ; then exit 1; fi
! mkdir $work
! if test $? -ne 0 ; then exit 1; fi
  
  fail()
  {
! 	set +x
! 	cd $here
! 	echo FAILED test for correct behaviour around symbolic links 1>&2
  	find $work -type d -user $USER -exec chmod u+w {} \;
  	rm -rf $work
  	exit 1
***************
*** 49,54 ****
--- 47,54 ----
  }
  pass()
  {
+ 	set +x
+ 	cd $here
  	find $work -type d -user $USER -exec chmod u+w {} \;
  	rm -rf $work
  	exit 0
***************
*** 55,61 ****
--- 55,101 ----
  }
  trap "fail" 1 2 3 15
  
+ cd $work
+ if test $? -ne 0 ; then fail; fi
+ 
  #
+ # program to ask questions about symlinks
+ #
+ cat > symlink.c << 'fubar'
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ void
+ main(argc, argv)
+ 	int	argc;
+ 	char	**argv;
+ {
+ #ifdef S_IFLNK
+ 	if (argc == 2)
+ 	{
+ 		struct stat st;
+ 		if (lstat(argv[1], &st))
+ 			exit(0);
+ 		/* fails if file exists */
+ 		exit(1);
+ 	}
+ 	exit(0);
+ #else
+ 	exit(2);
+ #endif
+ }
+ fubar
+ if test $? -ne 0 ; then fail; fi
+ cc -o symlink symlink.c
+ if test $? -ne 0 ; then fail; fi
+ 
+ #
+ # if this system has no symlinks
+ # automagically pass the test
+ #
+ ./symlink
+ if test $? -ge 2 ; then pass; fi
+ 
+ #
  # some variable to make things earier to read
  #
  worklib=$work/lib
***************
*** 66,80 ****
  symlinkdest=$workchan/symlinkdest
  
  #
- # make the directories
- #
- mkdir $work
- 
- #
  # make a new project
  #	and check files it should have made
  #
! ./bin/aegis -newpro foo -dir $workproj -lib $worklib
  if test $? -ne 0 ; then fail; fi
  
  #
--- 106,115 ----
  symlinkdest=$workchan/symlinkdest
  
  #
  # make a new project
  #	and check files it should have made
  #
! $here/bin/aegis -newpro foo -dir $workproj -lib $worklib
  if test $? -ne 0 ; then fail; fi
  
  #
***************
*** 86,92 ****
  developer_may_integrate = true;
  reviewer_may_integrate = true;
  end
! ./bin/aegis -proatt $tmp -proj foo -lib $worklib
  if test $? -ne 0 ; then fail; fi
  
  #
--- 121,127 ----
  developer_may_integrate = true;
  reviewer_may_integrate = true;
  end
! $here/bin/aegis -proatt $tmp -proj foo -lib $worklib
  if test $? -ne 0 ; then fail; fi
  
  #
***************
*** 98,110 ****
  with respect to change descriptions.";
  cause = internal_bug;
  end
! ./bin/aegis -new_change $tmp -project foo -lib $worklib
  if test $? -ne 0 ; then fail; fi
  
  #
  # add a new developer
  #
! ./bin/aegis -newdev $USER -p foo -lib $worklib
  if test $? -ne 0 ; then fail; fi
  
  #
--- 133,145 ----
  with respect to change descriptions.";
  cause = internal_bug;
  end
! $here/bin/aegis -new_change $tmp -project foo -lib $worklib
  if test $? -ne 0 ; then fail; fi
  
  #
  # add a new developer
  #
! $here/bin/aegis -newdev $USER -p foo -lib $worklib
  if test $? -ne 0 ; then fail; fi
  
  #
***************
*** 111,117 ****
  # begin development of a change
  #	check it made the files it should
  #
! ./bin/aegis -devbeg 1 -p foo -dir $workchan -lib $worklib
  if test $? -ne 0 ; then fail; fi
  
  #
--- 146,152 ----
  # begin development of a change
  #	check it made the files it should
  #
! $here/bin/aegis -devbeg 1 -p foo -dir $workchan -lib $worklib
  if test $? -ne 0 ; then fail; fi
  
  #
***************
*** 125,133 ****
  #
  # add a new files to the change
  #
! ./bin/aegis -new_file $workchan/main.c -nl -lib $worklib -p foo
  if test $? -ne 0 ; then fail; fi
! ./bin/aegis -new_file $workchan/config -nl -lib $worklib -p foo
  if test $? -ne 0 ; then fail; fi
  cat > $workchan/main.c << 'end'
  void
--- 160,168 ----
  #
  # add a new files to the change
  #
! $here/bin/aegis -new_file $workchan/main.c -nl -lib $worklib -p foo
  if test $? -ne 0 ; then fail; fi
! $here/bin/aegis -new_file $workchan/config -nl -lib $worklib -p foo
  if test $? -ne 0 ; then fail; fi
  cat > $workchan/main.c << 'end'
  void
***************
*** 137,177 ****
  }
  end
  cat > $workchan/config << 'end'
! build_command = "rm -f foo; cc -o foo -D'VERSION=\"%3\"' main.c";
  link_integration_directory = true;
  
  history_get_command =
! 	"co -u'%2' -p %1,v > %3";
  history_create_command =
! 	"ci -u -m/dev/null -t/dev/null %1 %2,v; rcs -U %2,v";
  history_put_command =
! 	"ci -u -m/dev/null -t/dev/null %1 %2,v; rcs -U %2,v";
  history_query_command =
! 	"rlog -r %1,v | awk '/^head:/ {print $2}'";
  
! /*
!  * difference of 2 files
!  * %1 is one input file
!  * %2 is the other input file
!  * %3 is the output file
!  */
! diff_command = "set +e; diff %1 %2 > %3; test $? -le 1";
  
! /*
!  * difference of 3 files
!  * %1 is one base file
!  * %2 is an input file
!  * %3 is an input file
!  * %4 is the output file
!  */
! diff3_command = "(diff3 -e %2 %1 %3 | sed -e '/^w$/d' -e '/^q$/d'; \
! 	echo '1,$p' ) | ed - %2 > %4";
  end
  
  #
  # create a new test
  #
! ./bin/aegis -nt -lib $worklib -p foo
  if test $? -ne 0 ; then fail; fi
  cat > $workchan/test/00/t0001a.sh << 'end'
  #!/bin/sh
--- 172,199 ----
  }
  end
  cat > $workchan/config << 'end'
! build_command = "rm -f foo; cc -o foo -D'VERSION=\"$v\"' main.c";
  link_integration_directory = true;
  
  history_get_command =
! 	"co -u'$e' -p $h,v > $o";
  history_create_command =
! 	"ci -u -m/dev/null -t/dev/null $i $h,v; rcs -U $h,v";
  history_put_command =
! 	"ci -u -m/dev/null -t/dev/null $i $h,v; rcs -U $h,v";
  history_query_command =
! 	"rlog -r $h,v | awk '/^head:/ {print $$2}'";
  
! diff_command = "set +e; diff $orig $i > $out; test $$? -le 1";
  
! diff3_command = "(diff3 -e $mr $orig $i | sed -e '/^w$$/d' -e '/^q$$/d'; \
! 	echo '1,$$p' ) | ed - $mr > $out";
  end
  
  #
  # create a new test
  #
! $here/bin/aegis -nt -lib $worklib -p foo
  if test $? -ne 0 ; then fail; fi
  cat > $workchan/test/00/t0001a.sh << 'end'
  #!/bin/sh
***************
*** 179,185 ****
  # Project: "foo"
  fail()
  {
! 	echo FAILED 1>&2
  	exit 1
  }
  pass()
--- 201,207 ----
  # Project: "foo"
  fail()
  {
! 	echo SHUZBUTT 1>&2
  	exit 1
  }
  pass()
***************
*** 215,277 ****
  #
  # build the change
  #
! ./bin/aegis -build -nl -lib $worklib -p foo > /dev/null 2>&1
  if test $? -ne 0 ; then fail; fi
  
  #
  # difference the change
  #
! ./bin/aegis -diff -nl -lib $worklib -p foo > /dev/null 2>&1
  if test $? -ne 0 ; then fail; fi
  
  #
  # test the change
  #
! ./bin/aegis -test -nl -lib $worklib -p foo > /dev/null 2>&1
  if test $? -ne 0 ; then fail; fi
  
  #
  # finish development of the change
  #
! ./bin/aegis -dev_end -lib $worklib -p foo
  if test $? -ne 0 ; then fail; fi
  
  #
  # add a new reviewer
  #
! ./bin/aegis -newrev $USER -p foo -lib $worklib
  if test $? -ne 0 ; then fail; fi
  
  #
  # pass the review
  #
! ./bin/aegis -review_pass -chan 1 -proj foo -lib $worklib
  if test $? -ne 0 ; then fail; fi
  
  #
  # add an integrator
  #
! ./bin/aegis -newint $USER -p foo -lib $worklib
  if test $? -ne 0 ; then fail; fi
  
  #
  # start integrating
  #
! ./bin/aegis -intbeg 1 -p foo -lib $worklib
  if test $? -ne 0 ; then fail; fi
  
  #
  # integrate build
  #
! ./bin/aegis -build -nl -lib $worklib -p foo > /dev/null 2>&1
  if test $? -ne 0 ; then fail; fi
! ./bin/aegis -test -nl -lib $worklib -p foo > /dev/null 2>&1
  if test $? -ne 0 ; then fail; fi
  
  #
  # pass the integration
  #
! ./bin/aegis -intpass -nl -lib $worklib -p foo > /dev/null 2>&1
  if test $? -ne 0 ; then fail; fi
  
  #
--- 237,299 ----
  #
  # build the change
  #
! $here/bin/aegis -build -nl -lib $worklib -p foo > /dev/null 2>&1
  if test $? -ne 0 ; then fail; fi
  
  #
  # difference the change
  #
! $here/bin/aegis -diff -nl -lib $worklib -p foo > /dev/null 2>&1
  if test $? -ne 0 ; then fail; fi
  
  #
  # test the change
  #
! $here/bin/aegis -test -nl -lib $worklib -p foo > /dev/null 2>&1
  if test $? -ne 0 ; then fail; fi
  
  #
  # finish development of the change
  #
! $here/bin/aegis -dev_end -lib $worklib -p foo
  if test $? -ne 0 ; then fail; fi
  
  #
  # add a new reviewer
  #
! $here/bin/aegis -newrev $USER -p foo -lib $worklib
  if test $? -ne 0 ; then fail; fi
  
  #
  # pass the review
  #
! $here/bin/aegis -review_pass -chan 1 -proj foo -lib $worklib
  if test $? -ne 0 ; then fail; fi
  
  #
  # add an integrator
  #
! $here/bin/aegis -newint $USER -p foo -lib $worklib
  if test $? -ne 0 ; then fail; fi
  
  #
  # start integrating
  #
! $here/bin/aegis -intbeg 1 -p foo -lib $worklib
  if test $? -ne 0 ; then fail; fi
  
  #
  # integrate build
  #
! $here/bin/aegis -build -nl -lib $worklib -p foo > /dev/null 2>&1
  if test $? -ne 0 ; then fail; fi
! $here/bin/aegis -test -nl -lib $worklib -p foo > /dev/null 2>&1
  if test $? -ne 0 ; then fail; fi
  
  #
  # pass the integration
  #
! $here/bin/aegis -intpass -nl -lib $worklib -p foo > /dev/null 2>&1
  if test $? -ne 0 ; then fail; fi
  
  #
***************
*** 278,284 ****
  # see if the symbolic link in the work area has been removed
  # or wether it is still there
  #
! if test -h $symlinktestfile ; then fail; fi
  
  # should be no automatic logging
  if test "`find $work -name 'aegis.log' -print`" != "" ; then fail; fi
--- 300,307 ----
  # see if the symbolic link in the work area has been removed
  # or wether it is still there
  #
! ./symlink $symlinktestfile
! if test $? -ne 0 ; then fail; fi
  
  # should be no automatic logging
  if test "`find $work -name 'aegis.log' -print`" != "" ; then fail; fi
Index: test/00/t0008a.sh
***************
*** 1,13 ****
! #!/bin/sh
  #
  #	aegis - project change supervisor
! #	Copyright (c) 1991-1992 Peter Miller.
  #	All rights reserved.
  #
  #	This program is free software; you can redistribute it and/or modify
  #	it under the terms of the GNU General Public License as published by
! #	the Free Software Foundation; either version 1, or (at your option)
! #	any later version.
  #
  #	This program is distributed in the hope that it will be useful,
  #	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,13 ----
! #! /bin/sh
  #
  #	aegis - project change supervisor
! #	Copyright (C) 1991, 1992, 1993 Peter Miller.
  #	All rights reserved.
  #
  #	This program is free software; you can redistribute it and/or modify
  #	it under the terms of the GNU General Public License as published by
! #	the Free Software Foundation; either version 2 of the License, or
! #	(at your option) any later version.
  #
  #	This program is distributed in the hope that it will be useful,
  #	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 18,36 ****
  #	along with this program; if not, write to the Free Software
  #	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  #
- # ----------------------------------------------------------------------
- #
  # MANIFEST: Test command substitutions
  #
  
  PAGER=cat
  export PAGER
! work=/tmp/$$
  
  fail()
  {
  	set +x
! 	echo FAILED 1>&2
  	find $work -type d -user $USER -exec chmod u+w {} \;
  	rm -rf $work
  	exit 1
--- 18,37 ----
  #	along with this program; if not, write to the Free Software
  #	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  #
  # MANIFEST: Test command substitutions
  #
  
+ unset AEGIS_PROJECT
+ unset AEGIS_CHANGE
+ 
  PAGER=cat
  export PAGER
! work=${AEGIS_TMP-/tmp}/$$
  
  fail()
  {
  	set +x
! 	echo FAILED test of command substitutions 1>&2
  	find $work -type d -user $USER -exec chmod u+w {} \;
  	rm -rf $work
  	exit 1
***************
*** 134,173 ****
  ./bin/aegis -new_file $workchan/config -nl -v -lib $worklib -p foo
  if test $? -ne 0 ; then fail; fi
  cat > $workchan/config << 'end'
! build_command = "make -f %(Makefile) PROJECT=%1 CHANGE=%2 VERSION=%3";
  link_integration_directory = true;
  
  history_get_command =
! 	"co -u'%2' -p %1,v > %3";
  history_create_command =
! 	"ci -u -m/dev/null -t/dev/null %1 %2,v; rcs -U %2,v";
  history_put_command =
! 	"ci -u -m/dev/null -t/dev/null %1 %2,v; rcs -U %2,v";
  history_query_command =
! 	"rlog -r %1,v | awk '/^head:/ {print $2}'";
  
! /*
!  * difference of 2 files
!  *	%1 = earlier file
!  *	%2 = later file	
!  *	%3 = output file
!  */
! diff_command = "\
! set +e; \
! diff %1 %2 > %3; \
! if test $? -ne 0 -a $? -ne 1  ; \
! then exit 1; \
! fi; exit 0";
  
! /*
!  * difference of 3 files
!  *	%1 = common ancestor
!  *	%2 = one competing edit
!  *	%3 = another competing edit
!  *	%4 = output file
!  */
! diff3_command = "diff3 %1 %2 %3 > %4";
! 
  end
  if test $? -ne 0 ; then fail; fi
  
--- 135,156 ----
  ./bin/aegis -new_file $workchan/config -nl -v -lib $worklib -p foo
  if test $? -ne 0 ; then fail; fi
  cat > $workchan/config << 'end'
! build_command = "make -f ${s Makefile} PROJECT=$p CHANGE=$c VERSION=$v";
  link_integration_directory = true;
  
  history_get_command =
! 	"co -u'$e' -p $h,v > $o";
  history_create_command =
! 	"ci -u -m/dev/null -t/dev/null $i $h,v; rcs -U $h,v";
  history_put_command =
! 	"ci -u -m/dev/null -t/dev/null $i $h,v; rcs -U $h,v";
  history_query_command =
! 	"rlog -r $h,v | awk '/^head:/ {print $$2}'";
  
! diff_command = "set +e; diff $orig $i > $out; test $$? -le 1";
  
! diff3_command = "(diff3 -e $mr $orig $i | sed -e '/^w$$/d' -e '/^q$$/d'; \
! 	echo '1,$$p' ) | ed - $mr > $out";
  end
  if test $? -ne 0 ; then fail; fi
  
***************
*** 190,196 ****
  #
  fail()
  {
! 	echo FAILED 1>&2
  	exit 1
  }
  pass()
--- 173,179 ----
  #
  fail()
  {
! 	echo SHUZBUTT 1>&2
  	exit 1
  }
  pass()
***************
*** 320,326 ****
  #
  fail()
  {
! 	echo FAILED 1>&2
  	exit 1
  }
  pass()
--- 303,309 ----
  #
  fail()
  {
! 	echo SHUZBUTT 1>&2
  	exit 1
  }
  pass()
Index: test/00/t0009a.sh
***************
*** 1,13 ****
! #!/bin/sh
  #
  #	aegis - project change supervisor
! #	Copyright (c) 1991-1992 Peter Miller.
  #	All rights reserved.
  #
  #	This program is free software; you can redistribute it and/or modify
  #	it under the terms of the GNU General Public License as published by
! #	the Free Software Foundation; either version 1, or (at your option)
! #	any later version.
  #
  #	This program is distributed in the hope that it will be useful,
  #	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,13 ----
! #! /bin/sh
  #
  #	aegis - project change supervisor
! #	Copyright (C) 1991, 1992, 1993 Peter Miller.
  #	All rights reserved.
  #
  #	This program is free software; you can redistribute it and/or modify
  #	it under the terms of the GNU General Public License as published by
! #	the Free Software Foundation; either version 2 of the License, or
! #	(at your option) any later version.
  #
  #	This program is distributed in the hope that it will be useful,
  #	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 18,36 ****
  #	along with this program; if not, write to the Free Software
  #	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  #
- # ----------------------------------------------------------------------
- #
  # MANIFEST: Test -New_ReLeaSe functionality.
  #
  
  PAGER=cat
  export PAGER
! work=/tmp/$$
  
  fail()
  {
  	set +x
! 	echo FAILED 1>&2
  	find $work -type d -user $USER -exec chmod u+w {} \;
  	rm -rf $work
  	exit 1
--- 18,37 ----
  #	along with this program; if not, write to the Free Software
  #	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  #
  # MANIFEST: Test -New_ReLeaSe functionality.
  #
  
+ unset AEGIS_PROJECT
+ unset AEGIS_CHANGE
+ 
  PAGER=cat
  export PAGER
! work=${AEGIS_TMP-/tmp}/$$
  
  fail()
  {
  	set +x
! 	echo FAILED test of -New_ReLeaSe functionality 1>&2
  	find $work -type d -user $USER -exec chmod u+w {} \;
  	rm -rf $work
  	exit 1
***************
*** 122,156 ****
  end
  if test $? -ne 0 ; then fail; fi
  cat > $workchan/config << 'end'
! build_command = "rm -f foo; cc -o foo -D'VERSION=\"%3\"' main.c";
  link_integration_directory = true;
  
  history_get_command =
! 	"co -u'%2' -p %1,v > %3";
  history_create_command =
! 	"ci -u -m/dev/null -t/dev/null %1 %2,v; rcs -U %2,v";
  history_put_command =
! 	"ci -u -m/dev/null -t/dev/null %1 %2,v; rcs -U %2,v";
  history_query_command =
! 	"rlog -r %1,v | awk '/^head:/ {print $2}'";
  
! /*
!  * difference of 2 files
!  * %1 is one input file
!  * %2 is the other input file
!  * %3 is the output file
!  */
! diff_command = "set +e; diff %1 %2 > %3; test $? -le 1";
  
! /*
!  * difference of 3 files
!  * %1 is one base file
!  * %2 is an input file
!  * %3 is an input file
!  * %4 is the output file
!  */
! diff3_command = "(diff3 -e %2 %1 %3 | sed -e '/^w$/d' -e '/^q$/d'; \
! 	echo '1,$p' ) | ed - %2 > %4";
  end
  if test $? -ne 0 ; then fail; fi
  
--- 123,144 ----
  end
  if test $? -ne 0 ; then fail; fi
  cat > $workchan/config << 'end'
! build_command = "rm -f foo; cc -o foo -D'VERSION=\"$v\"' main.c";
  link_integration_directory = true;
  
  history_get_command =
! 	"co -u'$e' -p $h,v > $o";
  history_create_command =
! 	"ci -u -m/dev/null -t/dev/null $i $h,v; rcs -U $h,v";
  history_put_command =
! 	"ci -u -m/dev/null -t/dev/null $i $h,v; rcs -U $h,v";
  history_query_command =
! 	"rlog -r $h,v | awk '/^head:/ {print $$2}'";
  
! diff_command = "set +e; diff $orig $i > $out; test $$? -le 1";
  
! diff3_command = "(diff3 -e $mr $orig $i | sed -e '/^w$$/d' -e '/^q$$/d'; \
! 	echo '1,$$p' ) | ed - $mr > $out";
  end
  if test $? -ne 0 ; then fail; fi
  
***************
*** 168,174 ****
  
  fail()
  {
! 	echo FAILED 1>&2
  	exit 1
  }
  pass()
--- 156,162 ----
  
  fail()
  {
! 	echo SHUZBUTT 1>&2
  	exit 1
  }
  pass()
***************
*** 348,354 ****
  
  fail()
  {
! 	echo FAILED 1>&2
  	exit 1
  }
  pass()
--- 336,342 ----
  
  fail()
  {
! 	echo SHUZBUTT 1>&2
  	exit 1
  }
  pass()
Index: test/00/t0010a.sh
***************
*** 1,13 ****
! #!/bin/sh
  #
  #	aegis - project change supervisor
! #	Copyright (c) 1991-1992 Peter Miller.
  #	All rights reserved.
  #
  #	This program is free software; you can redistribute it and/or modify
  #	it under the terms of the GNU General Public License as published by
! #	the Free Software Foundation; either version 1, or (at your option)
! #	any later version.
  #
  #	This program is distributed in the hope that it will be useful,
  #	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,13 ----
! #! /bin/sh
  #
  #	aegis - project change supervisor
! #	Copyright (C) 1991, 1992, 1993 Peter Miller.
  #	All rights reserved.
  #
  #	This program is free software; you can redistribute it and/or modify
  #	it under the terms of the GNU General Public License as published by
! #	the Free Software Foundation; either version 2 of the License, or
! #	(at your option) any later version.
  #
  #	This program is distributed in the hope that it will be useful,
  #	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 18,36 ****
  #	along with this program; if not, write to the Free Software
  #	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  #
- # ----------------------------------------------------------------------
- #
  # MANIFEST: Test -Review_Pass_Undo functionality.
  #
  
  PAGER=cat
  export PAGER
! work=/tmp/$$
  
  fail()
  {
  	set +x
! 	echo FAILED 1>&2
  	find $work -type d -user $USER -exec chmod u+w {} \;
  	rm -rf $work
  	exit 1
--- 18,37 ----
  #	along with this program; if not, write to the Free Software
  #	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  #
  # MANIFEST: Test -Review_Pass_Undo functionality.
  #
  
+ unset AEGIS_PROJECT
+ unset AEGIS_CHANGE
+ 
  PAGER=cat
  export PAGER
! work=${AEGIS_TMP-/tmp}/$$
  
  fail()
  {
  	set +x
! 	echo FAILED test of -Review_Pass_Undo functionality 1>&2
  	find $work -type d -user $USER -exec chmod u+w {} \;
  	rm -rf $work
  	exit 1
***************
*** 122,156 ****
  end
  if test $? -ne 0 ; then fail; fi
  cat > $workchan/config << 'end'
! build_command = "rm -f foo; cc -o foo -D'VERSION=\"%3\"' main.c";
  link_integration_directory = true;
  
  history_get_command =
! 	"co -u'%2' -p %1,v > %3";
  history_create_command =
! 	"ci -u -m/dev/null -t/dev/null %1 %2,v; rcs -U %2,v";
  history_put_command =
! 	"ci -u -m/dev/null -t/dev/null %1 %2,v; rcs -U %2,v";
  history_query_command =
! 	"rlog -r %1,v | awk '/^head:/ {print $2}'";
  
! /*
!  * difference of 2 files
!  * %1 is one input file
!  * %2 is the other input file
!  * %3 is the output file
!  */
! diff_command = "set +e; diff %1 %2 > %3; test $? -le 1";
  
! /*
!  * difference of 3 files
!  * %1 is one base file
!  * %2 is an input file
!  * %3 is an input file
!  * %4 is the output file
!  */
! diff3_command = "(diff3 -e %2 %1 %3 | sed -e '/^w$/d' -e '/^q$/d'; \
! 	echo '1,$p' ) | ed - %2 > %4";
  end
  if test $? -ne 0 ; then fail; fi
  
--- 123,144 ----
  end
  if test $? -ne 0 ; then fail; fi
  cat > $workchan/config << 'end'
! build_command = "rm -f foo; cc -o foo -D'VERSION=\"$v\"' main.c";
  link_integration_directory = true;
  
  history_get_command =
! 	"co -u'$e' -p $h,v > $o";
  history_create_command =
! 	"ci -u -m/dev/null -t/dev/null $i $h,v; rcs -U $h,v";
  history_put_command =
! 	"ci -u -m/dev/null -t/dev/null $i $h,v; rcs -U $h,v";
  history_query_command =
! 	"rlog -r $h,v | awk '/^head:/ {print $$2}'";
  
! diff_command = "set +e; diff $orig $i > $out; test $$? -le 1";
  
! diff3_command = "(diff3 -e $mr $orig $i | sed -e '/^w$$/d' -e '/^q$$/d'; \
! 	echo '1,$$p' ) | ed - $mr > $out";
  end
  if test $? -ne 0 ; then fail; fi
  
***************
*** 168,174 ****
  
  fail()
  {
! 	echo FAILED 1>&2
  	exit 1
  }
  pass()
--- 156,162 ----
  
  fail()
  {
! 	echo SHUZBUTT 1>&2
  	exit 1
  }
  pass()
Index: test/00/t0011a.sh
***************
*** 1,13 ****
! #!/bin/sh
  #
  #	aegis - project change supervisor
! #	Copyright (c) 1991-1993 Peter Miller.
  #	All rights reserved.
  #
  #	This program is free software; you can redistribute it and/or modify
  #	it under the terms of the GNU General Public License as published by
! #	the Free Software Foundation; either version 1, or (at your option)
! #	any later version.
  #
  #	This program is distributed in the hope that it will be useful,
  #	but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1,13 ----
! #! /bin/sh
  #
  #	aegis - project change supervisor
! #	Copyright (C) 1991, 1992, 1993 Peter Miller.
  #	All rights reserved.
  #
  #	This program is free software; you can redistribute it and/or modify
  #	it under the terms of the GNU General Public License as published by
! #	the Free Software Foundation; either version 2 of the License, or
! #	(at your option) any later version.
  #
  #	This program is distributed in the hope that it will be useful,
  #	but WITHOUT ANY WARRANTY; without even the implied warranty of
***************
*** 18,38 ****
  #	along with this program; if not, write to the Free Software
  #	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  #
- # ----------------------------------------------------------------------
- #
  # MANIFEST: Test documentation example.
  #
  
  PAGER=cat
  export PAGER
  COLS=65
  export COLS
! work=/tmp/$$
  
  fail()
  {
  	set +x
! 	echo FAILED 1>&2
  	find $work -type d -user $USER -exec chmod u+w {} \;
  	rm -rf $work
  	exit 1
--- 18,39 ----
  #	along with this program; if not, write to the Free Software
  #	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  #
  # MANIFEST: Test documentation example.
  #
  
+ unset AEGIS_PROJECT
+ unset AEGIS_CHANGE
+ 
  PAGER=cat
  export PAGER
  COLS=65
  export COLS
! work=${AEGIS_TMP-/tmp}/$$
  
  fail()
  {
  	set +x
! 	echo FAILED test of documentation example 1>&2
  	find $work -type d -user $USER -exec chmod u+w {} \;
  	rm -rf $work
  	exit 1
***************
*** 40,46 ****
  pass()
  {
  	set +x
! 	echo PASSED 1>&2
  	find $work -type d -user $USER -exec chmod u+w {} \;
  	rm -rf $work
  	exit 0
--- 41,47 ----
  pass()
  {
  	set +x
! 	echo PASSED test of documentation example 1>&2
  	find $work -type d -user $USER -exec chmod u+w {} \;
  	rm -rf $work
  	exit 0
***************
*** 64,79 ****
  # make the directories
  #
  mkdir $work
  
  AEGIS=$worklib
  export AEGIS
! PATH=`pwd`/bin:$PATH
  export PATH
  
  #
  # make a new project
  #
! ./bin/aegis -newpro example -dir $workproj -v -lib $worklib
  if test $? -ne 0 ; then fail; fi
  
  #
--- 65,85 ----
  # make the directories
  #
  mkdir $work
+ if test $? -ne 0 ; then fail; fi
+ here=`pwd`
+ if test $? -ne 0 ; then fail; fi
  
  AEGIS=$worklib
  export AEGIS
! PATH=$here/bin:$PATH
  export PATH
+ AEGIS_PROJECT=example
+ export AEGIS_PROJECT
  
  #
  # make a new project
  #
! $here/bin/aegis -newpro example -dir $workproj -v -lib $worklib
  if test $? -ne 0 ; then fail; fi
  
  #
***************
*** 87,93 ****
  TheEnd
  if test $? -ne 0 ; then fail; fi
  
! ./bin/aegis -proatt $tmp -proj example -v -lib $worklib
  if test $? -ne 0 ; then fail; fi
  
  #
--- 93,99 ----
  TheEnd
  if test $? -ne 0 ; then fail; fi
  
! $here/bin/aegis -proatt $tmp -proj example -v
  if test $? -ne 0 ; then fail; fi
  
  #
***************
*** 103,130 ****
  TheEnd
  if test $? -ne 0 ; then fail; fi
  
! ./bin/aegis -new_change $tmp -project example -v -lib $worklib
  if test $? -ne 0 ; then fail; fi
  
  #
  # add a new developer
  #
! ./bin/aegis -newdev $USER -p example -v -lib $worklib
  if test $? -ne 0 ; then fail; fi
  
  #
  # begin development of the change
  #
! ./bin/aegis -devbeg -l -p example -v -lib $worklib
  if test $? -ne 0 ; then fail; fi
! ./bin/aegis -devbeg 1 -p example -dir $workchan -v -lib $worklib
  if test $? -ne 0 ; then fail; fi
  
  #
  # add the new files to the change
  #
! ./bin/aegis -new_file $workchan/Howto.cook $workchan/config $workchan/gram.y \
! 	$workchan/lex.l $workchan/main.c -nl -v -lib $worklib -p example
  if test $? -ne 0 ; then fail; fi
  
  cat > $workchan/Howto.cook << 'TheEnd'
--- 109,136 ----
  TheEnd
  if test $? -ne 0 ; then fail; fi
  
! $here/bin/aegis -new_change $tmp -project example -v
  if test $? -ne 0 ; then fail; fi
  
  #
  # add a new developer
  #
! $here/bin/aegis -newdev $USER -v
  if test $? -ne 0 ; then fail; fi
  
  #
  # begin development of the change
  #
! $here/bin/aegis -devbeg -l -v
  if test $? -ne 0 ; then fail; fi
! $here/bin/aegis -devbeg 1 -dir $workchan -v
  if test $? -ne 0 ; then fail; fi
  
  #
  # add the new files to the change
  #
! $here/bin/aegis -new_file $workchan/Howto.cook $workchan/config $workchan/gram.y \
! 	$workchan/lex.l $workchan/main.c -nl -v
  if test $? -ne 0 ; then fail; fi
  
  cat > $workchan/Howto.cook << 'TheEnd'
***************
*** 216,256 ****
  	if [exists [target]] then
  		rm [target]
  			set clearstat;
! 	[cc] -o [target] [resolve [obj_files]] -ll -ly;
  }
  TheEnd
  if test $? -ne 0 ; then fail; fi
  
  cat > $workchan/config << 'TheEnd'
! build_command = "cook -b %(Howto.cook) project=%1 change=%2 version=%3 -nl";
  link_integration_directory = true;
  
  history_get_command =
! 	"co -u'%2' -p %1,v > %3";
  history_create_command =
! 	"ci -u -m/dev/null -t/dev/null %1 %2,v; rcs -U %2,v";
  history_put_command =
! 	"ci -u -m/dev/null -t/dev/null %1 %2,v; rcs -U %2,v";
  history_query_command =
! 	"rlog -r %1,v | awk '/^head:/ {print $2}'";
  
! /*
!  * difference of 2 files
!  * %1 is one input file
!  * %2 is the other input file
!  * %3 is the output file
!  */
! diff_command = "set +e; diff -c %1 %2 > %3; test $? -eq 0 -o $? -eq 1";
  
! /*
!  * difference of 3 files
!  * %1 is one base file
!  * %2 is an input file
!  * %3 is an input file
!  * %4 is the output file
!  */
! diff3_command = "(diff3 -e %2 %1 %3 | sed -e '/^w$/d' -e '/^q$/d'; \
! 	echo '1,$p' ) | ed - %2 > %4";
  TheEnd
  if test $? -ne 0 ; then fail; fi
  
--- 222,249 ----
  	if [exists [target]] then
  		rm [target]
  			set clearstat;
! 	[cc] -o [target] [resolve [obj_files]] -ll -ly -lm;
  }
  TheEnd
  if test $? -ne 0 ; then fail; fi
  
  cat > $workchan/config << 'TheEnd'
! build_command = "cook -b ${s Howto.cook} project=$p change=$c version=$v -nl";
  link_integration_directory = true;
  
  history_get_command =
! 	"co -u'$e' -p $h,v > $o";
  history_create_command =
! 	"ci -u -m/dev/null -t/dev/null $i $h,v; rcs -U $h,v";
  history_put_command =
! 	"ci -u -m/dev/null -t/dev/null $i $h,v; rcs -U $h,v";
  history_query_command =
! 	"rlog -r $h,v | awk '/^head:/ {print $$2}'";
  
! diff_command = "set +e; diff $orig $i > $out; test $$? -le 1";
  
! diff3_command = "(diff3 -e $mr $orig $i | sed -e '/^w$$/d' -e '/^q$$/d'; \
! 	echo '1,$$p' ) | ed - $mr > $out";
  TheEnd
  if test $? -ne 0 ; then fail; fi
  
***************
*** 264,269 ****
--- 257,266 ----
  		yylval.lv_double = atof(yytext);
  		return DOUBLE;
  	}
+ [a-z]	{
+ 		yylval.lv_int = yytext[0] - 'a';
+ 		return NAME;
+ 	}
  [ \t]+	;
  \n	|
  .	{ return yytext[0]; }
***************
*** 271,277 ****
--- 268,278 ----
  if test $? -ne 0 ; then fail; fi
  
  cat > $workchan/gram.y << 'TheEnd'
+ %{
+ #include <stdio.h>
+ %}
  %token DOUBLE
+ %token NAME
  %union
  {
  	double	lv_double;
***************
*** 279,284 ****
--- 280,286 ----
  };
  
  %type <lv_double> DOUBLE expr
+ %type <lv_int> NAME
  %left '+' '-'
  %left '*' '/'
  %right UNARY
***************
*** 286,291 ****
--- 288,294 ----
  example
  	: /* empty */
  	| example command '\n'
+ 		{ yyerrflag = 0; fflush(stderr); fflush(stdout); }
  	;
  command
  	: expr
***************
*** 337,343 ****
  #
  # create a new test
  #
! ./bin/aegis -nt -v -lib $worklib -p example
  if test $? -ne 0 ; then fail; fi
  
  sed -e 's/^X//' > $workchan/test/00/t0001a.sh << 'TheEnd'
--- 340,346 ----
  #
  # create a new test
  #
! $here/bin/aegis -nt -v
  if test $? -ne 0 ; then fail; fi
  
  sed -e 's/^X//' > $workchan/test/00/t0001a.sh << 'TheEnd'
***************
*** 352,358 ****
  X
  Xfail()
  X{
! X	echo FAILED 1>&2
  X	cd $here
  X	chmod u+w `find $tmp -type d -print`
  X	rm -rf $tmp
--- 355,361 ----
  X
  Xfail()
  X{
! X	echo SHUZBUTT 1>&2
  X	cd $here
  X	chmod u+w `find $tmp -type d -print`
  X	rm -rf $tmp
***************
*** 389,395 ****
  Xend
  Xif test $? -ne 0 ; then fail; fi
  X
! X$here/example < test.in > test.out
  Xif test $? -ne 0 ; then fail; fi
  X
  Xdiff test.ok test.out
--- 392,398 ----
  Xend
  Xif test $? -ne 0 ; then fail; fi
  X
! X$here/example < test.in > test.out 2>&1
  Xif test $? -ne 0 ; then fail; fi
  X
  Xdiff test.ok test.out
***************
*** 408,462 ****
  #
  # build the change
  #
! ./bin/aegis -build -nl -v -lib $worklib -p example
  if test $? -ne 0 ; then fail; fi
  
  #
  # difference the change
  #
! ./bin/aegis -diff -v -lib $worklib -p example -nl
  if test $? -ne 0 ; then fail; fi
  
  #
  # test the change
  #
! ./bin/aegis -test -nl -v -lib $worklib -p example
  if test $? -ne 0 ; then fail; fi
  
  #
  # finish development of the change
  #
! ./bin/aegis -dev_end -v -lib $worklib -p example
  if test $? -ne 0 ; then fail; fi
  
  #
  # add a new reviewer
  #
! ./bin/aegis -newrev $USER -p example -v -lib $worklib
  if test $? -ne 0 ; then fail; fi
  
  #
  # pass the review
  #
! ./bin/aegis -review_pass -list -proj example -v -lib $worklib
  if test $? -ne 0 ; then fail; fi
! ./bin/aegis -review_pass -chan 1 -proj example -v -lib $worklib
  if test $? -ne 0 ; then fail; fi
  
  #
  # add an integrator
  #
! ./bin/aegis -newint $USER -p example -v -lib $worklib
  if test $? -ne 0 ; then fail; fi
  
  #
  # start integrating
  #
! ./bin/aegis -intbeg -list -p example -v -lib $worklib
  if test $? -ne 0 ; then fail; fi
! ./bin/aegis -intbeg 1 -p example -v -lib $worklib
  if test $? -ne 0 ; then fail; fi
! ./bin/aegis -list cd -p example -v -lib $worklib
  if test $? -ne 0 ; then fail; fi
  
  #
--- 411,465 ----
  #
  # build the change
  #
! $here/bin/aegis -build -nl -v
  if test $? -ne 0 ; then fail; fi
  
  #
  # difference the change
  #
! $here/bin/aegis -diff -v -nl
  if test $? -ne 0 ; then fail; fi
  
  #
  # test the change
  #
! $here/bin/aegis -test -nl -v
  if test $? -ne 0 ; then fail; fi
  
  #
  # finish development of the change
  #
! $here/bin/aegis -dev_end -v
  if test $? -ne 0 ; then fail; fi
  
  #
  # add a new reviewer
  #
! $here/bin/aegis -newrev $USER -v
  if test $? -ne 0 ; then fail; fi
  
  #
  # pass the review
  #
! $here/bin/aegis -review_pass -list -proj example -v
  if test $? -ne 0 ; then fail; fi
! $here/bin/aegis -review_pass -chan 1 -proj example -v
  if test $? -ne 0 ; then fail; fi
  
  #
  # add an integrator
  #
! $here/bin/aegis -newint $USER -v
  if test $? -ne 0 ; then fail; fi
  
  #
  # start integrating
  #
! $here/bin/aegis -intbeg -list -v
  if test $? -ne 0 ; then fail; fi
! $here/bin/aegis -intbeg 1 -v
  if test $? -ne 0 ; then fail; fi
! $here/bin/aegis -list cd -v
  if test $? -ne 0 ; then fail; fi
  
  #
***************
*** 463,482 ****
  # integrate build and test
  #
  sleep 1
! ./bin/aegis -build -nl -v -lib $worklib -p example
  if test $? -ne 0 ; then fail; fi
! ./bin/aegis -test -nl -v -lib $worklib -p example
  if test $? -ne 0 ; then fail; fi
  
  #
  # pass the integration
  #
! ./bin/aegis -intpass -nl -v -lib $worklib -p example
  if test $? -ne 0 ; then fail; fi
  
  #
  # create the second and subsequent changes
! # 
  cat > $tmp << 'fubar'
  brief_description = "file names on command line";
  description = "Optional input and output files may be \
--- 466,487 ----
  # integrate build and test
  #
  sleep 1
! $here/bin/aegis -build -nl -v
  if test $? -ne 0 ; then fail; fi
! $here/bin/aegis -test -nl -v
  if test $? -ne 0 ; then fail; fi
  
  #
  # pass the integration
  #
! $here/bin/aegis -intpass -nl -v
  if test $? -ne 0 ; then fail; fi
  
+ # -- 2 -----------------------------------------------------------------
+ 
  #
  # create the second and subsequent changes
! #
  cat > $tmp << 'fubar'
  brief_description = "file names on command line";
  description = "Optional input and output files may be \
***************
*** 484,524 ****
  cause = internal_bug;
  fubar
  if test $? -ne 0 ; then fail; fi
! ./bin/aegis -new_change $tmp -project example -v -lib $worklib
  if test $? -ne 0 ; then fail; fi
  
  cat > $tmp << 'fubar'
! brief_description = "add variables";
! description = "Enhance the grammar to allow variables.  \
! Only single letter variable names are required.";
  cause = internal_enhancement;
  fubar
  if test $? -ne 0 ; then fail; fi
! ./bin/aegis -new_change $tmp -project example -v -lib $worklib
  if test $? -ne 0 ; then fail; fi
  
  cat > $tmp << 'fubar'
! brief_description = "add powers";
! description = "Enhance the grammar to allow exponentiation.  \
! No error checking required.";
  cause = internal_enhancement;
  fubar
  if test $? -ne 0 ; then fail; fi
! ./bin/aegis -new_change $tmp -project example -v -lib $worklib
  if test $? -ne 0 ; then fail; fi
  
  #
  # begin development of the change
  #
! ./bin/aegis -devbeg -l -p example -v -lib $worklib
  if test $? -ne 0 ; then fail; fi
! ./bin/aegis -devbeg 2 -p example -dir $workchan -v -lib $worklib
  if test $? -ne 0 ; then fail; fi
  
  #
  # add the new files to the change
  #
! ./bin/aegis -copy_file $workchan/main.c -nl -v -lib $worklib -p example
  if test $? -ne 0 ; then fail; fi
  
  cat > $workchan/main.c << 'TheEnd'
--- 489,529 ----
  cause = internal_bug;
  fubar
  if test $? -ne 0 ; then fail; fi
! $here/bin/aegis -new_change $tmp -project example -v
  if test $? -ne 0 ; then fail; fi
  
  cat > $tmp << 'fubar'
! brief_description = "add powers";
! description = "Enhance the grammar to allow exponentiation.  \
! No error checking required.";
  cause = internal_enhancement;
  fubar
  if test $? -ne 0 ; then fail; fi
! $here/bin/aegis -new_change $tmp -project example -v
  if test $? -ne 0 ; then fail; fi
  
  cat > $tmp << 'fubar'
! brief_description = "add variables";
! description = "Enhance the grammar to allow variables.  \
! Only single letter variable names are required.";
  cause = internal_enhancement;
  fubar
  if test $? -ne 0 ; then fail; fi
! $here/bin/aegis -new_change $tmp -project example -v
  if test $? -ne 0 ; then fail; fi
  
  #
  # begin development of the change
  #
! $here/bin/aegis -devbeg -l -v
  if test $? -ne 0 ; then fail; fi
! $here/bin/aegis -devbeg 2 -dir $workchan -v
  if test $? -ne 0 ; then fail; fi
  
  #
  # add the new files to the change
  #
! $here/bin/aegis -copy_file $workchan/main.c -nl -v
  if test $? -ne 0 ; then fail; fi
  
  cat > $workchan/main.c << 'TheEnd'
***************
*** 571,577 ****
  #
  # create a new test
  #
! ./bin/aegis -nt -v -lib $worklib -p example
  if test $? -ne 0 ; then fail; fi
  
  sed -e 's/^X//' > $workchan/test/00/t0002a.sh << 'TheEnd'
--- 576,582 ----
  #
  # create a new test
  #
! $here/bin/aegis -nt -v
  if test $? -ne 0 ; then fail; fi
  
  sed -e 's/^X//' > $workchan/test/00/t0002a.sh << 'TheEnd'
***************
*** 586,592 ****
  X
  Xfail()
  X{
! X	echo FAILED 1>&2
  X	cd $here
  X	chmod u+w `find $tmp -type d -print`
  X	rm -rf $tmp
--- 591,597 ----
  X
  Xfail()
  X{
! X	echo SHUZBUTT 1>&2
  X	cd $here
  X	chmod u+w `find $tmp -type d -print`
  X	rm -rf $tmp
***************
*** 623,629 ****
  Xend
  Xif test $? -ne 0 ; then fail; fi
  X
! X$here/example test.in < /dev/null > test.out
  Xif test $? -ne 0 ; then fail; fi
  X
  Xdiff test.ok test.out
--- 628,634 ----
  Xend
  Xif test $? -ne 0 ; then fail; fi
  X
! X$here/example test.in < /dev/null > test.out 2>&1
  Xif test $? -ne 0 ; then fail; fi
  X
  Xdiff test.ok test.out
***************
*** 648,694 ****
  #
  # build the change
  #
! ./bin/aegis -build -nl -v -lib $worklib -p example
  if test $? -ne 0 ; then fail; fi
  
  #
  # difference the change
  #
! ./bin/aegis -diff -v -lib $worklib -p example -nl
  if test $? -ne 0 ; then fail; fi
  
  #
  # test the change
  #
! ./bin/aegis -test -nl -v -lib $worklib -p example
  if test $? -ne 0 ; then fail; fi
! ./bin/aegis -test -bl -nl -v -lib $worklib -p example
  if test $? -ne 0 ; then fail; fi
! ./bin/aegis -test -reg -nl -v -lib $worklib -p example
  if test $? -ne 0 ; then fail; fi
  
  #
  # finish development of the change
  #
! ./bin/aegis -dev_end -v -lib $worklib -p example
  if test $? -ne 0 ; then fail; fi
  
  #
  # pass the review
  #
! ./bin/aegis -review_pass -list -proj example -v -lib $worklib
  if test $? -ne 0 ; then fail; fi
! ./bin/aegis -review_pass -chan 2 -proj example -v -lib $worklib
  if test $? -ne 0 ; then fail; fi
  
  #
  # start integrating
  #
! ./bin/aegis -intbeg -list -p example -v -lib $worklib
  if test $? -ne 0 ; then fail; fi
! ./bin/aegis -intbeg 2 -p example -v -lib $worklib
  if test $? -ne 0 ; then fail; fi
! ./bin/aegis -list cd -p example -v -lib $worklib
  if test $? -ne 0 ; then fail; fi
  
  #
--- 653,699 ----
  #
  # build the change
  #
! $here/bin/aegis -build -nl -v
  if test $? -ne 0 ; then fail; fi
  
  #
  # difference the change
  #
! $here/bin/aegis -diff -v -nl
  if test $? -ne 0 ; then fail; fi
  
  #
  # test the change
  #
! $here/bin/aegis -test -nl -v
  if test $? -ne 0 ; then fail; fi
! $here/bin/aegis -test -bl -nl -v
  if test $? -ne 0 ; then fail; fi
! $here/bin/aegis -test -reg -nl -v
  if test $? -ne 0 ; then fail; fi
  
  #
  # finish development of the change
  #
! $here/bin/aegis -dev_end -v
  if test $? -ne 0 ; then fail; fi
  
  #
  # pass the review
  #
! $here/bin/aegis -review_pass -list -proj example -v
  if test $? -ne 0 ; then fail; fi
! $here/bin/aegis -review_pass -chan 2 -proj example -v
  if test $? -ne 0 ; then fail; fi
  
  #
  # start integrating
  #
! $here/bin/aegis -intbeg -list -v
  if test $? -ne 0 ; then fail; fi
! $here/bin/aegis -intbeg 2 -v
  if test $? -ne 0 ; then fail; fi
! $here/bin/aegis -list cd -v
  if test $? -ne 0 ; then fail; fi
  
  #
***************
*** 695,714 ****
  # integrate build and test
  #
  sleep 1
! ./bin/aegis -build -nl -v -lib $worklib -p example
  if test $? -ne 0 ; then fail; fi
! ./bin/aegis -test -nl -v -lib $worklib -p example
  if test $? -ne 0 ; then fail; fi
! ./bin/aegis -test -bl -nl -v -lib $worklib -p example
  if test $? -ne 0 ; then fail; fi
! ./bin/aegis -test -reg -nl -v -lib $worklib -p example
  if test $? -ne 0 ; then fail; fi
  
  #
  # pass the integration
  #
! ./bin/aegis -intpass -nl -v -lib $worklib -p example
  if test $? -ne 0 ; then fail; fi
  
  #
  # the things tested in this test, worked
--- 700,1206 ----
  # integrate build and test
  #
  sleep 1
! $here/bin/aegis -build -nl -v
  if test $? -ne 0 ; then fail; fi
! $here/bin/aegis -test -nl -v
! if test $? -ne 0 ; then fail; fi
! $here/bin/aegis -test -bl -nl -v
! if test $? -ne 0 ; then fail; fi
! $here/bin/aegis -test -reg -nl -v
! if test $? -ne 0 ; then fail; fi
! 
! #
! # pass the integration
! #
! $here/bin/aegis -intpass -nl -v
! if test $? -ne 0 ; then fail; fi
! 
! # --- 3 ----------------------------------------------------------------
! 
! #
! # begin development of the change
! #
! $here/bin/aegis -devbeg -l -v
! if test $? -ne 0 ; then fail; fi
! $here/bin/aegis -devbeg 3 -dir $workchan.3 -v
! if test $? -ne 0 ; then fail; fi
! 
! #
! # add the new files to the change
! #
! $here/bin/aegis -copy_file $workchan.3/gram.y -nl -v
! if test $? -ne 0 ; then fail; fi
! 
! cat > $workchan.3/gram.y << 'TheEnd'
! %{
! #include <stdio.h>
! #include <math.h>
! %}
! %token DOUBLE
! %token NAME
! %union
! {
! 	double	lv_double;
! 	int	lv_int;
! };
! 
! %type <lv_double> DOUBLE expr
! %type <lv_int> NAME
! %left '+' '-'
! %left '*' '/'
! %right '^'
! %right UNARY
! %%
! example
! 	: /* empty */
! 	| example command '\n'
! 		{ yyerrflag = 0; fflush(stderr); fflush(stdout); }
! 	;
! command
! 	: expr
! 		{ printf("%g\n", $1); }
! 	| error
! 	;
! expr
! 	: DOUBLE
! 	| '(' expr ')'
! 		{ $$ = $2; }
! 	| '-' expr
! 		%prec UNARY
! 		{ $$ = -$2; }
! 	| expr '^' expr
! 		{ $$ = pow($1, $3); }
! 	| expr '*' expr
! 		{ $$ = $1 * $3; }
! 	| expr '/' expr
! 		{ $$ = $1 / $3; }
! 	| expr '+' expr
! 		{ $$ = $1 + $3; }
! 	| expr '-' expr
! 		{ $$ = $1 - $3; }
! 	;
! TheEnd
  if test $? -ne 0 ; then fail; fi
! 
! $here/bin/aegis -diff -v -nl
  if test $? -ne 0 ; then fail; fi
! cat $workchan.3/gram.y,D
  if test $? -ne 0 ; then fail; fi
  
  #
+ # create a new test
+ #
+ $here/bin/aegis -nt -v
+ if test $? -ne 0 ; then fail; fi
+ 
+ sed -e 's/^X//' > $workchan.3/test/00/t0003a.sh << 'TheEnd'
+ X:
+ Xhere=`pwd`
+ Xif test $? -ne 0 ; then exit 1; fi
+ Xtmp=/tmp/$$
+ Xmkdir $tmp
+ Xif test $? -ne 0 ; then exit 1; fi
+ Xcd $tmp
+ Xif test $? -ne 0 ; then exit 1; fi
+ X
+ Xfail()
+ X{
+ X	echo SHUZBUTT 1>&2
+ X	cd $here
+ X	chmod u+w `find $tmp -type d -print`
+ X	rm -rf $tmp
+ X	exit 1
+ X}
+ Xpass()
+ X{
+ X	cd $here
+ X	chmod u+w `find $tmp -type d -print`
+ X	rm -rf $tmp
+ X	exit 0
+ X}
+ Xtrap "fail" 1 2 3 15
+ X
+ Xcat > test.in << 'end'
+ X5.3 ^ 0
+ X4 ^ 0.5
+ X27 ^ (1/3)
+ Xend
+ Xif test $? -ne 0 ; then fail; fi
+ X
+ Xcat > test.ok << 'end'
+ X1
+ X2
+ X3
+ Xend
+ Xif test $? -ne 0 ; then fail; fi
+ X
+ X$here/example test.in < /dev/null > test.out 2>&1
+ Xif test $? -ne 0 ; then fail; fi
+ X
+ Xdiff test.ok test.out
+ Xif test $? -ne 0 ; then fail; fi
+ X
+ X$here/example test.in test.out.2 < /dev/null
+ Xif test $? -ne 0 ; then fail; fi
+ X
+ Xdiff test.ok test.out.2
+ Xif test $? -ne 0 ; then fail; fi
+ X
+ X# it probably worked
+ Xpass
+ TheEnd
+ if test $? -ne 0 ; then fail; fi
+ 
+ #
+ # let the clock tick over, so the build will be happy
+ #
+ sleep 1
+ 
+ #
+ # build the change
+ #
+ $here/bin/aegis -build -nl -v
+ if test $? -ne 0 ; then fail; fi
+ 
+ #
+ # difference the change
+ #
+ $here/bin/aegis -diff -v -nl
+ if test $? -ne 0 ; then fail; fi
+ 
+ #
+ # test the change
+ #
+ $here/bin/aegis -test -nl -v
+ if test $? -ne 0 ; then fail; fi
+ $here/bin/aegis -test -bl -nl -v
+ if test $? -ne 0 ; then fail; fi
+ $here/bin/aegis -test -reg -nl -v
+ if test $? -ne 0 ; then fail; fi
+ 
+ # --- 4 interrupts 3 ---------------------------------------------------
+ 
+ #
+ # begin development of the change
+ #
+ $here/bin/aegis -devbeg -l -v
+ if test $? -ne 0 ; then fail; fi
+ $here/bin/aegis -devbeg 4 -dir $workchan.4 -v
+ if test $? -ne 0 ; then fail; fi
+ $here/bin/aegis -l cd -v -c 4
+ if test $? -ne 0 ; then fail; fi
+ 
+ #
+ # add the new files to the change
+ #
+ $here/bin/aegis -copy_file $workchan.4/gram.y -nl -v -c 4
+ if test $? -ne 0 ; then fail; fi
+ 
+ cat > $workchan.4/gram.y << 'TheEnd'
+ %{
+ #include <stdio.h>
+ %}
+ %token DOUBLE
+ %token NAME
+ %union
+ {
+ 	double	lv_double;
+ 	int	lv_int;
+ };
+ 
+ %type <lv_double> DOUBLE expr
+ %type <lv_int> NAME
+ %left '+' '-'
+ %left '*' '/'
+ %right UNARY
+ %%
+ example
+ 	: /* empty */
+ 	| example command '\n'
+ 		{ yyerrflag = 0; fflush(stderr); fflush(stdout); }
+ 	;
+ command
+ 	: expr
+ 		{ printf("%g\n", $1); }
+ 	| NAME '=' expr
+ 		{ assign($1, $3); }
+ 	| error
+ 	;
+ expr
+ 	: DOUBLE
+ 	| NAME
+ 		{ extern double recall(); $$ = recall($1); }
+ 	| '(' expr ')'
+ 		{ $$ = $2; }
+ 	| '-' expr
+ 		%prec UNARY
+ 		{ $$ = -$2; }
+ 	| expr '*' expr
+ 		{ $$ = $1 * $3; }
+ 	| expr '/' expr
+ 		{ $$ = $1 / $3; }
+ 	| expr '+' expr
+ 		{ $$ = $1 + $3; }
+ 	| expr '-' expr
+ 		{ $$ = $1 - $3; }
+ 	;
+ TheEnd
+ if test $? -ne 0 ; then fail; fi
+ 
+ $here/bin/aegis -new_file $workchan.4/var.c -nl -v -c 4
+ if test $? -ne 0 ; then fail; fi
+ 
+ cat > $workchan.4/var.c << 'TheEnd'
+ static double memory[26];
+ 
+ void
+ assign(name, value)
+ 	int	name;
+ 	double	value;
+ {
+ 	memory[name] = value;
+ }
+ 
+ double
+ recall(name)
+ 	int	name;
+ {
+ 	return memory[name];
+ }
+ TheEnd
+ if test $? -ne 0 ; then fail; fi
+ 
+ #
+ # create a new test
+ #
+ $here/bin/aegis -nt -v -c 4
+ if test $? -ne 0 ; then fail; fi
+ 
+ sed -e 's/^X//' > $workchan.4/test/00/t0004a.sh << 'TheEnd'
+ X:
+ Xhere=`pwd`
+ Xif test $? -ne 0 ; then exit 1; fi
+ Xtmp=/tmp/$$
+ Xmkdir $tmp
+ Xif test $? -ne 0 ; then exit 1; fi
+ Xcd $tmp
+ Xif test $? -ne 0 ; then exit 1; fi
+ X
+ Xfail()
+ X{
+ X	echo SHUZBUTT 1>&2
+ X	cd $here
+ X	chmod u+w `find $tmp -type d -print`
+ X	rm -rf $tmp
+ X	exit 1
+ X}
+ Xpass()
+ X{
+ X	cd $here
+ X	chmod u+w `find $tmp -type d -print`
+ X	rm -rf $tmp
+ X	exit 0
+ X}
+ Xtrap "fail" 1 2 3 15
+ X
+ Xcat > test.in << 'end'
+ Xa = 1
+ Xa + 1
+ Xc = a * 40 + 5
+ Xc / (a + 4)
+ Xend
+ Xif test $? -ne 0 ; then fail; fi
+ X
+ Xcat > test.ok << 'end'
+ X2
+ X9
+ Xend
+ Xif test $? -ne 0 ; then fail; fi
+ X
+ X$here/example test.in < /dev/null > test.out 2>&1
+ Xif test $? -ne 0 ; then fail; fi
+ X
+ Xdiff test.ok test.out
+ Xif test $? -ne 0 ; then fail; fi
+ X
+ X$here/example test.in test.out.2 < /dev/null
+ Xif test $? -ne 0 ; then fail; fi
+ X
+ Xdiff test.ok test.out.2
+ Xif test $? -ne 0 ; then fail; fi
+ X
+ X# it probably worked
+ Xpass
+ TheEnd
+ if test $? -ne 0 ; then fail; fi
+ 
+ #
+ # let the clock tick over, so the build will be happy
+ #
+ sleep 1
+ 
+ #
+ # build the change
+ #
+ $here/bin/aegis -build -nl -v -c 4
+ if test $? -ne 0 ; then fail; fi
+ 
+ #
+ # difference the change
+ #
+ $here/bin/aegis -diff -v -nl -c 4
+ if test $? -ne 0 ; then fail; fi
+ cat $workchan.4/gram.y,D
+ if test $? -ne 0 ; then fail; fi
+ 
+ #
+ # test the change
+ #
+ $here/bin/aegis -test -nl -v -c 4
+ if test $? -ne 0 ; then fail; fi
+ $here/bin/aegis -test -bl -nl -v -c 4
+ if test $? -ne 0 ; then fail; fi
+ $here/bin/aegis -test -reg -nl -v -c 4
+ if test $? -ne 0 ; then fail; fi
+ 
+ #
+ # finish development of the change
+ #
+ $here/bin/aegis -dev_end -v -c 4
+ if test $? -ne 0 ; then fail; fi
+ 
+ #
+ # pass the review
+ #
+ $here/bin/aegis -review_pass -list -proj example -v
+ if test $? -ne 0 ; then fail; fi
+ $here/bin/aegis -review_pass -chan 4 -proj example -v
+ if test $? -ne 0 ; then fail; fi
+ 
+ #
+ # start integrating
+ #
+ $here/bin/aegis -intbeg -list -v
+ if test $? -ne 0 ; then fail; fi
+ $here/bin/aegis -intbeg 4 -v
+ if test $? -ne 0 ; then fail; fi
+ $here/bin/aegis -list cd -v -c 4
+ if test $? -ne 0 ; then fail; fi
+ 
+ #
+ # integrate build and test
+ #
+ sleep 1
+ $here/bin/aegis -build -nl -v -c 4
+ if test $? -ne 0 ; then fail; fi
+ $here/bin/aegis -test -nl -v -c 4
+ if test $? -ne 0 ; then fail; fi
+ $here/bin/aegis -test -bl -nl -v -c 4
+ if test $? -ne 0 ; then fail; fi
+ $here/bin/aegis -test -reg -nl -v -c 4
+ if test $? -ne 0 ; then fail; fi
+ 
+ #
  # pass the integration
  #
! $here/bin/aegis -intpass -nl -v -c 4
  if test $? -ne 0 ; then fail; fi
+ 
+ # --- 3, again ---------------------------------------------------------
+ 
+ #
+ # finish development of the change
+ #
+ $here/bin/aegis -dev_end -v -c 3
+ if test $? -ne 1 ; then fail; fi
+ 
+ #
+ # need a new difference
+ #
+ $here/bin/aegis -diff -nl -v -c 3
+ if test $? -ne 0 ; then fail; fi
+ 
+ #
+ # look at the merge file
+ #
+ cat $workchan.3/gram.y,D
+ if test $? -ne 0 ; then fail; fi
+ mv $workchan.3/gram.y,D $workchan.3/gram.y
+ if test $? -ne 0 ; then fail; fi
+ 
+ #
+ # need a new build
+ #
+ sleep 1
+ $here/bin/aegis -build -nl -v -c 3
+ if test $? -ne 0 ; then fail; fi
+ 
+ #
+ # test it again
+ #
+ $here/bin/aegis -test -nl -v -c 3
+ if test $? -ne 0 ; then fail; fi
+ $here/bin/aegis -test -bl -nl -v -c 3
+ if test $? -ne 0 ; then fail; fi
+ $here/bin/aegis -test -reg -nl -v -c 3
+ if test $? -ne 0 ; then fail; fi
+ 
+ #
+ # try to finish development of the change
+ #
+ $here/bin/aegis -dev_end -v -c 3
+ if test $? -ne 1 ; then fail; fi
+ 
+ #
+ # diff again
+ #
+ $here/bin/aegis -diff -nl -v -c 3
+ if test $? -ne 0 ; then fail; fi
+ 
+ #
+ # finish development of the change
+ #
+ $here/bin/aegis -dev_end -v -c 3
+ if test $? -ne 0 ; then fail; fi
+ 
+ #
+ # pass the review
+ #
+ $here/bin/aegis -review_pass -list -proj example -v
+ if test $? -ne 0 ; then fail; fi
+ $here/bin/aegis -review_pass -chan 3 -proj example -v
+ if test $? -ne 0 ; then fail; fi
+ 
+ #
+ # start integrating
+ #
+ $here/bin/aegis -intbeg -list -v
+ if test $? -ne 0 ; then fail; fi
+ $here/bin/aegis -intbeg 3 -v
+ if test $? -ne 0 ; then fail; fi
+ $here/bin/aegis -list cd -v
+ if test $? -ne 0 ; then fail; fi
+ 
+ #
+ # integrate build and test
+ #
+ sleep 1
+ $here/bin/aegis -build -nl -v
+ if test $? -ne 0 ; then fail; fi
+ $here/bin/aegis -test -nl -v
+ if test $? -ne 0 ; then fail; fi
+ $here/bin/aegis -test -bl -nl -v
+ if test $? -ne 0 ; then fail; fi
+ $here/bin/aegis -test -reg -nl -v
+ if test $? -ne 0 ; then fail; fi
+ 
+ #
+ # pass the integration
+ #
+ $here/bin/aegis -intpass -nl -v
+ if test $? -ne 0 ; then fail; fi
+ 
+ # ----------------------------------------------------------------------
  
  #
  # the things tested in this test, worked
Index: test/00/t0012a.sh
***************
*** 0 ****
--- 1,83 ----
+ #! /bin/sh
+ #
+ #	aegis - project change supervisor
+ #	Copyright (C) 1993 Peter Miller.
+ #	All rights reserved.
+ #
+ #	This program is free software; you can redistribute it and/or modify
+ #	it under the terms of the GNU General Public License as published by
+ #	the Free Software Foundation; either version 2 of the License, or
+ #	(at your option) any later version.
+ #
+ #	This program is distributed in the hope that it will be useful,
+ #	but WITHOUT ANY WARRANTY; without even the implied warranty of
+ #	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ #	GNU General Public License for more details.
+ #
+ #	You should have received a copy of the GNU General Public License
+ #	along with this program; if not, write to the Free Software
+ #	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ #
+ # MANIFEST: Test the aermpr functionality
+ #
+ 
+ unset AEGIS_PROJECT
+ unset AEGIS_CHANGE
+ 
+ work=${AEGIS_TMP-/tmp}/$$
+ PAGER=cat
+ export PAGER
+ 
+ here=`pwd`
+ if test $? -ne 0 ; then exit 1; fi
+ 
+ fail()
+ {
+ 	set +x
+ 	cd $here
+ 	echo FAILED test of aermpr functionality 1>&2
+ 	find $work -type d -user $USER -exec chmod u+w {} \;
+ 	rm -rf $work
+ 	exit 1
+ }
+ pass()
+ {
+ 	set +x
+ 	cd $here
+ 	echo PASSED 1>&2
+ 	find $work -type d -user $USER -exec chmod u+w {} \;
+ 	rm -rf $work
+ 	exit 0
+ }
+ trap "fail" 1 2 3 15
+ 
+ mkdir $work
+ if test $? -ne 0 ; then exit 1; fi
+ cd $work
+ if test $? -ne 0 ; then fail; fi
+ 
+ workproj=$work/proj
+ worklib=$work/lib
+ 
+ #
+ # create the project
+ #	and make sure it is there
+ #
+ $here/bin/aegis -newpro foo -dir $workproj -lib $worklib
+ if test $? -ne 0 ; then fail; fi
+ if test ! -d $workproj ; then fail; fi
+ 
+ #
+ # remove the project
+ #	and make sure it is gone
+ #
+ $here/bin/aegis -remproj foo -lib $worklib
+ if test $? -ne 0 ; then fail; fi
+ if test -d $workproj ; then fail; fi
+ 
+ #
+ # Only definite negatives are possible.
+ # The functionality exercised by this test appears to work,
+ # no other guarantees are made.
+ #
+ pass
Index: test/00/t0013a.sh
***************
*** 0 ****
--- 1,92 ----
+ #! /bin/sh
+ #
+ #	aegis - project change supervisor
+ #	Copyright (C) 1993 Peter Miller.
+ #	All rights reserved.
+ #
+ #	This program is free software; you can redistribute it and/or modify
+ #	it under the terms of the GNU General Public License as published by
+ #	the Free Software Foundation; either version 2 of the License, or
+ #	(at your option) any later version.
+ #
+ #	This program is distributed in the hope that it will be useful,
+ #	but WITHOUT ANY WARRANTY; without even the implied warranty of
+ #	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ #	GNU General Public License for more details.
+ #
+ #	You should have received a copy of the GNU General Public License
+ #	along with this program; if not, write to the Free Software
+ #	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ #
+ # MANIFEST: Test the -New_Change_Undo functionality
+ #
+ 
+ unset AEGIS_PROJECT
+ unset AEGIS_CHANGE
+ 
+ work=${AEGIS_TMP-/tmp}/$$
+ PAGER=cat
+ export PAGER
+ 
+ here=`pwd`
+ if test $? -ne 0 ; then exit 1; fi
+ 
+ fail()
+ {
+ 	set +x
+ 	cd $here
+ 	echo FAILED test of -New_Change_Undo functionality 1>&2
+ 	find $work -type d -user $USER -exec chmod u+w {} \;
+ 	rm -rf $work
+ 	exit 1
+ }
+ pass()
+ {
+ 	set +x
+ 	cd $here
+ 	echo PASSED 1>&2
+ 	find $work -type d -user $USER -exec chmod u+w {} \;
+ 	rm -rf $work
+ 	exit 0
+ }
+ trap "fail" 1 2 3 15
+ 
+ mkdir $work
+ if test $? -ne 0 ; then exit 1; fi
+ cd $work
+ if test $? -ne 0 ; then fail; fi
+ 
+ worklib=$work/lib
+ workproj=$work/foo
+ 
+ #
+ # create the project
+ #
+ $here/bin/aegis -npr foo -lib $worklib -dir $workproj
+ if test $? -ne 0 ; then fail; fi
+ 
+ #
+ # create a change
+ #
+ cat > ncf << 'fubar'
+ brief_description = "hello";
+ cause = internal_enhancement;
+ fubar
+ if test $? -ne 0 ; then fail; fi
+ $here/bin/aegis -nc ncf -lib $worklib -p foo
+ if test $? -ne 0 ; then fail; fi
+ if test ! -f $workproj/info/change/0/001; then fail; fi
+ 
+ #
+ # remove the change
+ #
+ $here/bin/aegis -ncu -lib $worklib -p foo -c 1
+ if test $? -ne 0 ; then fail; fi
+ if test -f $workproj/info/change/0/001; then fail; fi
+ 
+ #
+ # Only definite negatives are possible.
+ # The functionality exercised by this test appears to work,
+ # no other guarantees are made.
+ #
+ pass
Index: test/00/t0014a.sh
***************
*** 0 ****
--- 1,111 ----
+ #! /bin/sh
+ #
+ #	aegis - project change supervisor
+ #	Copyright (C) 1993 Peter Miller.
+ #	All rights reserved.
+ #
+ #	This program is free software; you can redistribute it and/or modify
+ #	it under the terms of the GNU General Public License as published by
+ #	the Free Software Foundation; either version 2 of the License, or
+ #	(at your option) any later version.
+ #
+ #	This program is distributed in the hope that it will be useful,
+ #	but WITHOUT ANY WARRANTY; without even the implied warranty of
+ #	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ #	GNU General Public License for more details.
+ #
+ #	You should have received a copy of the GNU General Public License
+ #	along with this program; if not, write to the Free Software
+ #	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ #
+ # MANIFEST: Test the -Develop_Begin_Undo functionality
+ #
+ 
+ unset AEGIS_PROJECT
+ unset AEGIS_CHANGE
+ 
+ work=${AEGIS_TMP-/tmp}/$$
+ PAGER=cat
+ export PAGER
+ 
+ here=`pwd`
+ if test $? -ne 0 ; then exit 1; fi
+ 
+ fail()
+ {
+ 	set +x
+ 	cd $here
+ 	echo FAILED test of -Develop_Begin_Undo functionality 1>&2
+ 	find $work -type d -user $USER -exec chmod u+w {} \;
+ 	rm -rf $work
+ 	exit 1
+ }
+ pass()
+ {
+ 	set +x
+ 	cd $here
+ 	echo PASSED 1>&2
+ 	find $work -type d -user $USER -exec chmod u+w {} \;
+ 	rm -rf $work
+ 	exit 0
+ }
+ trap "fail" 1 2 3 15
+ 
+ mkdir $work
+ if test $? -ne 0 ; then exit 1; fi
+ cd $work
+ if test $? -ne 0 ; then fail; fi
+ 
+ worklib=$work/lib
+ workproj=$work/foo
+ workchan=$work/bar
+ 
+ #
+ # new project
+ #
+ $here/bin/aegis -npr foo -lib $worklib -dir $workproj
+ if test $? -ne 0 ; then fail; fi
+ 
+ #
+ # new change
+ #
+ cat > ncf << 'fubar'
+ brief_description = "please hit me";
+ cause = internal_enhancement;
+ fubar
+ if test $? -ne 0 ; then fail; fi
+ $here/bin/aegis -nc ncf -lib $worklib -p foo
+ if test $? -ne 0 ; then fail; fi
+ 
+ #
+ # make current user a developer
+ #
+ $here/bin/aegis -nd $USER -lib $worklib -p foo
+ if test $? -ne 0 ; then fail; fi
+ 
+ #
+ # develop begin
+ #
+ $here/bin/aegis -db -lib $worklib -p foo -c 1 -dir $workchan
+ if test $? -ne 0 ; then fail; fi
+ if test ! -d $workchan ; then fail ; fi
+ 
+ #
+ # add a file just to spice it up a little
+ #
+ $here/bin/aegis -nf $workchan/snot -lib $worklib -p foo -c 1
+ if test $? -ne 0 ; then fail; fi
+ 
+ #
+ # develop begin undo
+ #
+ $here/bin/aegis -dbu -lib $worklib -p foo -c 1
+ if test $? -ne 0 ; then fail; fi
+ if test -d $workchan ; then fail ; fi
+ 
+ #
+ # Only definite negatives are possible.
+ # The functionality exercised by this test appears to work,
+ # no other guarantees are made.
+ #
+ pass
Index: test/00/t0015a.sh
***************
*** 0 ****
--- 1,245 ----
+ #! /bin/sh
+ #
+ #	aegis - project change supervisor
+ #	Copyright (C) 1993 Peter Miller.
+ #	All rights reserved.
+ #
+ #	This program is free software; you can redistribute it and/or modify
+ #	it under the terms of the GNU General Public License as published by
+ #	the Free Software Foundation; either version 2 of the License, or
+ #	(at your option) any later version.
+ #
+ #	This program is distributed in the hope that it will be useful,
+ #	but WITHOUT ANY WARRANTY; without even the implied warranty of
+ #	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ #	GNU General Public License for more details.
+ #
+ #	You should have received a copy of the GNU General Public License
+ #	along with this program; if not, write to the Free Software
+ #	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ #
+ # MANIFEST: Test the -Integrate_Begin_Undo functionality
+ #
+ 
+ unset AEGIS_PROJECT
+ unset AEGIS_CHANGE
+ 
+ work=${AEGIS_TMP-/tmp}/$$
+ PAGER=cat
+ export PAGER
+ 
+ here=`pwd`
+ if test $? -ne 0 ; then exit 1; fi
+ mkdir $work
+ if test $? -ne 0 ; then exit 1; fi
+ 
+ fail()
+ {
+ 	set +x
+ 	echo FAILED test of the -Integrate_Begin_Undo functionality 1>&2
+ 	cd $here
+ 	find $work -type d -user $USER -exec chmod u+w {} \;
+ 	rm -rf $work
+ 	exit 1
+ }
+ pass()
+ {
+ 	set +x
+ 	echo PASSED 1>&2
+ 	cd $here
+ 	find $work -type d -user $USER -exec chmod u+w {} \;
+ 	rm -rf $work
+ 	exit 0
+ }
+ trap "fail" 1 2 3 15
+ 
+ cd $work
+ if test $? -ne 0 ; then fail; fi
+ 
+ #
+ # some variable to make things earier to read
+ #
+ worklib=$work/lib
+ workproj=$work/foo.proj
+ workchan=$work/foo.chan
+ tmp=$work/tmp
+ 
+ #
+ # make a new project
+ #	and check files it should have made
+ #
+ $here/bin/aegis -newpro foo -dir $workproj -lib $worklib
+ if test $? -ne 0 ; then fail; fi
+ 
+ #
+ # change project attributes
+ #
+ cat > $tmp << 'end'
+ description = "A bogus project created to test things.";
+ developer_may_review = true;
+ developer_may_integrate = true;
+ reviewer_may_integrate = true;
+ end
+ $here/bin/aegis -proatt $tmp -proj foo -lib $worklib
+ if test $? -ne 0 ; then fail; fi
+ 
+ #
+ # create a new change
+ #	make sure it creates the files it should
+ #
+ cat > $tmp << 'end'
+ brief_description = "This change is used to test the aegis functionality \
+ with respect to change descriptions.";
+ cause = internal_bug;
+ end
+ $here/bin/aegis -new_change $tmp -project foo -lib $worklib
+ if test $? -ne 0 ; then fail; fi
+ 
+ #
+ # add a new developer
+ #
+ $here/bin/aegis -newdev $USER -p foo -lib $worklib
+ if test $? -ne 0 ; then fail; fi
+ 
+ #
+ # begin development of a change
+ #	check it made the files it should
+ #
+ $here/bin/aegis -devbeg 1 -p foo -dir $workchan -lib $worklib
+ if test $? -ne 0 ; then fail; fi
+ 
+ #
+ # add a new files to the change
+ #
+ $here/bin/aegis -new_file $workchan/main.c -nl -lib $worklib -p foo
+ if test $? -ne 0 ; then fail; fi
+ $here/bin/aegis -new_file $workchan/config -nl -lib $worklib -p foo
+ if test $? -ne 0 ; then fail; fi
+ cat > $workchan/main.c << 'end'
+ void
+ main()
+ {
+ 	exit(0);
+ }
+ end
+ cat > $workchan/config << 'end'
+ build_command = "rm -f foo; cc -o foo -D'VERSION=\"$v\"' main.c";
+ link_integration_directory = true;
+ 
+ history_get_command =
+ 	"co -u'$e' -p $h,v > $o";
+ history_create_command =
+ 	"ci -u -m/dev/null -t/dev/null $i $h,v; rcs -U $h,v";
+ history_put_command =
+ 	"ci -u -m/dev/null -t/dev/null $i $h,v; rcs -U $h,v";
+ history_query_command =
+ 	"rlog -r $h,v | awk '/^head:/ {print $$2}'";
+ 
+ diff_command = "set +e; diff $orig $i > $out; test $$? -le 1";
+ 
+ diff3_command = "(diff3 -e $mr $orig $i | sed -e '/^w$$/d' -e '/^q$$/d'; \
+ 	echo '1,$$p' ) | ed - $mr > $out";
+ end
+ 
+ #
+ # create a new test
+ #
+ $here/bin/aegis -nt -lib $worklib -p foo
+ if test $? -ne 0 ; then fail; fi
+ cat > $workchan/test/00/t0001a.sh << 'end'
+ #!/bin/sh
+ #
+ # Project: "foo"
+ fail()
+ {
+ 	echo SHUZBUTT 1>&2
+ 	exit 1
+ }
+ pass()
+ {
+ 	exit 0
+ }
+ trap "fail" 1 2 3 15
+ 
+ ./foo
+ q=$?
+ 
+ # check for signals
+ if test $q -ge 128 
+ then
+ 	fail
+ fi
+ 
+ # should not complain
+ if test $q -ne 0 
+ then
+ 	fail
+ fi
+ 
+ # it probably worked
+ pass
+ end
+ 
+ #
+ # let the clock tick over, so the build will be happy
+ #
+ sleep 1
+ 
+ #
+ # build the change
+ #
+ $here/bin/aegis -build -nl -lib $worklib -p foo > /dev/null 2>&1
+ if test $? -ne 0 ; then fail; fi
+ 
+ #
+ # difference the change
+ #
+ $here/bin/aegis -diff -nl -lib $worklib -p foo > /dev/null 2>&1
+ if test $? -ne 0 ; then fail; fi
+ 
+ #
+ # test the change
+ #
+ $here/bin/aegis -test -nl -lib $worklib -p foo > /dev/null 2>&1
+ if test $? -ne 0 ; then fail; fi
+ 
+ #
+ # finish development of the change
+ #
+ $here/bin/aegis -dev_end -lib $worklib -p foo
+ if test $? -ne 0 ; then fail; fi
+ 
+ #
+ # add a new reviewer
+ #
+ $here/bin/aegis -newrev $USER -p foo -lib $worklib
+ if test $? -ne 0 ; then fail; fi
+ 
+ #
+ # pass the review
+ #
+ $here/bin/aegis -review_pass -chan 1 -proj foo -lib $worklib
+ if test $? -ne 0 ; then fail; fi
+ 
+ #
+ # add an integrator
+ #
+ $here/bin/aegis -newint $USER -p foo -lib $worklib
+ if test $? -ne 0 ; then fail; fi
+ 
+ #
+ # start integrating
+ #
+ $here/bin/aegis -ib 1 -p foo -lib $worklib
+ if test $? -ne 0 ; then fail; fi
+ 
+ #
+ # integrate build
+ #
+ $here/bin/aegis -ibu -lib $worklib -p foo
+ if test $? -ne 0 ; then fail; fi
+ 
+ #
+ # the things tested in this test, worked
+ #
+ pass
fubar
