Recently, several colleagues and I were attempting to
discover who
had made the last set of changes to a particular file.
There was no
easy way to tell. All of us had the requisite permissions
to edit
the file, but there was no indication of who made the
changes. At
this point we began to consider whether we might use
a tool such as
SCCS (the Source Code Control System), which is a part
of the UNIX
development system. SCCS creates a read-only version
of the actual
file, so that changes must be forced through the SCCS
system. In addition,
the SCCS lines inserted to keep track of the version
information contain
the name of the user who made the last changes.
As a means of protecting ourselves and to keep a record
of changes
to the files, we decided to begin using SCCS on the
various configuration
files, starting first with our master Domain Name Server
files. Since
then, it has been easy to find out what changed when
and who made
the change. Equally important, SCCS has made it easy
to go back to
the previous version if something became broken as things
were updated.
In this article I describe how SCCS works and how it
can help you
manage both your configuration files and plain text
documents. Since
SCCS is available to me, the article focuses on that
system. If you
do not have SCCS, you may want to acquire one of the
many Revision
Control Systems (RCSs) that are freely available.
SCCS makes special use of certain terms.
An MR is a number used to track the changes in
the source file (e.g., bug report numbers).
Protection
Most of the protections implemented by SCCS rely upon
the operating
system to enforce and restrict changes made by non-SCCS
commands.
Protections directly implemented by SCCS are the release
lock, the
release floor and ceiling flags, and the user list.
A new file created for SCCS control via the SCCS admin
command
(which I discuss later) receives a protection mode of
read-only (444),
which prevents non-SCCS commands from making changes
to it. As a further
protection, the directory containing the SCCS files
should not be
publicly writeable (protection mode 755, which allows
only the directory
owner to add or delete files from it), and both SCCS
files and temporary
files should be kept in this directory.
There should be only one link to the SCCS files. This
is because a
number of files are created to indicate that the file
is being edited,
and name confusion could result in lost edits or difficulties
later.
The SCCS Command Set
The SCCS command set consists of thirteen commands.
admin creates and administers files under SCCS control.
cdc changes delta commentary.
comb combines multiple deltas into one.
delta makes a change to an SCCS file.
get retrieves a copy of an SCCS file, either for use
or for
editing.
help displays messages for the SCCS error codes.
prs prints information about SCCS files.
sact lists the SCCS files out for editing.
sccsdiff prints the differences between releases of
the same
file.
unget cancels a get -e prior to running delta.
val validates an SCCS file.
vc is a filter that may be used for version control.
what searches files for the @(#) sequence, and prints
those
lines.
Creating an SCCS File
You must use the admin command to create an SCCS file.
This
command places the file under the custody and watchful
eye of SCCS
and assigns an initial SID to the file. By default,
the initial assignment
is Release 1, Version 1 -- or 1.1.
For example, to place a file called names under SCCS
custody,
you would enter
admin -inames s.names
SCCS filenames consist of the original filename prefixed
with s., so in this example, I have instructed the admin
command to create a new SCCS file called s.names, and
to initialize
the contents of the file using the data in the file
called names.
If the command line does not include -i filename, the
command
reads from ROM standard input to create the initial
delta. Note that
you can create only one SCCS file at a time using admin.
If
you need to create a number of new SCCS files, you can
use the -n
flag, as in the following example, to create empty files.
admin -n s.a s.b
Once you've created the s.file, delete the original.
This ensures that all changes will be made to the SCCS
version.
SCCS Data
The SCCS file contains a number of pieces of information
aside from
the file itself. The information lines begin with a
Control-A
followed by a single letter and each line has a specific
meaning.
The first line is a checksum for entire file, not including
the checksum
itself.
The "s" line lists the number of lines inserted/deleted/unchanged,
respectively.
The "d" line indicates the type of delta (D
is normal, R is
removed), the SID of the file, the date and time of
creation of the
delta, the username which corresponds to the real userid
who created
it, and finally the serial numbers of the delta and
its predecessor.
If the "i", "x", and "g"
lines are present,
they contain the serial numbers of deltas which have
been included,
excluded, and ignored respectively. These lines are
optional.
The "m" lines contain MR or Modification Request
numbers,
one per line, which are associated with the delta, and
the "c"
lines contain a brief comment on what changed in this
delta.
The "e" line indicates the end of the delta
table entry.
The lines "u" and "U" mark an area
where you can specify
which users may (or may not) make changes to this file.
If there are
no names between these lines, then all users can make
deltas. The
names specified here can be either login names or their
associated
numerical UIDS. An exclamation point in front of login
name or UID
indicates that this user cannot make deltas.
You can add or eliminate users from the list of those
authorized to
make deltas by using the admin command with the appropriate
option (-alogin option, where login is the name or UID
of the
user to be added, -elogin for a user to be removed).
The "t" and "T" lines mark an area
that can contain
descriptive text. The text can be added to the SCCS
file using the
-t keyword on the admin command line
The "f" line allows for specification of flags.
The flags
available for the admin command are shown in Figure
1. The
format in the file is
^Af <L>ag <MIO><N> al text
Enabling MR Numbers
Modification Request numbers can be useful in tracking
the changes
in large software projects. Such a number allows for
the tracking
not only of the initial request (a bug report, for example),
but also
of the disposition of the request.
To enable MR tracking, use the admin command
admin -fv s.names
which turns on the v flag in the SCCS header of
the file. This flag is used by the delta command to
get an
MR number from the user when the delta is created.
After the initial delta where an MRU is requested, the
top of the
SCCS header looks like:
^Ah30338
^As 00002/00000/00006
^Ad D 1.4 93/02/27 13:37:04 chare 4 3
^Am 93.02.26.001
^Ac added more names
^Ae
The "m" line shows the MR number entered when
the user was prompted by the delta command.
Getting an SCCS File
You use the get command to retrieve a file from SCCS
either
for editing or for use in another program. get will
place a
copy of the current SID and data for that SID into the
non-s.file
file. The new file is known as the g-file.
Thus the command
get s.names
retrieves a read-only version of the file called names.
get prints the revision level of the retrieved file
and the
number of lines retrieved.
Editing this file is not permitted; that is, any edits
you make to
the file will be lost the next time the file is retrieved.
To edit
the file, you must use the -e option with the get command.
This option causes get to assign a new delta and create
a g-file
for you to edit.
In either case, you can also retrieve a specific version
of the file
other than the latest by specifiying the relase which
you want on
the command line, as in:
$ get -r1.1 s.names
Using this approach it is very easy to backtrack to
working
code or configuration files.
You can also use get to change the revision level of
the file:
$ get -e -r3 s.names
2.1
new delta 3.1
8 lines
get will report the old SID (2.1), and the new
SID once the delta is applied (3.1).
Same File, Multiple Edits
To allow the same file to be edited by multiple users
at the same
time and at the same revision level, you must either
set the j-
flag with admin or use a delta command in the course
of the in-progress edit. To set the j- flag, use admin
like this:
$ admin -fj s.names
Now different users can do multiple edits of the same
SID. Notice that the emphasis is on different users.
If the same file
is retrieved for editing in the same directory, then
the subsequent
get will fail as there will be a p-file for that SID
and file already in the current directory.
This recalls the problem mentioned earlier in the section
on protection.
If the directories are set to 755, only the user who
owns the directory
will be able to create the temporary files for editing.
You can circumvent this by using a project-specific
interface program
which is owned by the SCCS administrator of the project
(who will
also own all the files and diretories) and is SUID.
This enables other
users to have access to the files and programs.
Recording the Changes
SCCS itself will keep track of the lines inserted and
deleted, etc.,
in order to be able to recreate any version of the file.
To accomplish this, use the delta command as follows:
$ delta s.names
comments? Added more names
1.3
3 inserted
0 deleted
6 unchanged
delta responds by asking for a comment which describes
what you did, and then lists the current SID, followed
by the number
of affected lines. It then updates the s-file based
upon the
changes in the g-file. In addition, delta looks at a
third file called the p-file.
The p-file, which in the case of our names file would
be called p.names, contains the old SID, the new SID,
username,
and the date and time of the creation of the delta.
If you have configured
the file to use MR numbers, then delta will prompt for
the
MR number before asking for the comments for the delta.
If you prefer, you can provide this information on the
command line
rather than entering it interactively. The next example
demonstrates
the use of the -y option for the comment, and the -m
option for the MR number.
delta -y "Added more names" -m "93.02.26.002" s.names
Remember that the -m flag can only be used with
the delta command if the SCCS file was initially set
up with the v
flag on the admin command line.
Unlike admin, delta can be used on multiple files, but
there are some constraints. If you are using MR numbers,
then all
of the files must have the v flag set for MR number
tracking.
If the first file on the command line doesn't have this
flag, then
none of the files can have it.
The information in the p-file and the comments form
the new
entry at the top of the SCCS file.
Listing 1 shows a sample shell script which I use to
get a file for
editing, edit it, and record the delta.
Reviewing the Delta History
If you want simply to review the commentary and other
information
associated with a file without reading the file itself,
you can use
the get command to create what is called an l-file.
This file
contains information on all of the changes that have
been applied
to the SCCS file.
If you prefer simply to display the information, add
the p
option, which causes get to print the information to
standard
out rather than write it to a file.
Using the prs Command
An alternate method of information about a file is to
use the prs
command. This command will print all or parts of the
specified s-file.
Non-SCCS file, or unreadable files are silently ignored.
For example,
$ prs s.files
prints the information on each delta which has been
applied
to the file.
prs can also be used to print various parts of the file,
and
can intersperse SCCS keywords within the text. (SCCS
keywords and
get keywords are different entities; SCCS keywords have
a format
of the type :I:, while get keywords look like #I#.)
The prs command has the capability of formatting the
information
in many different ways -- you specify your preference
through what
is called a dataspec. The dataspec is entered on the
command line,
preceded by the option -d and is followed by the keywords
associated
with the data you want.
If you are working on C code, or some type of file which
expects to
find a character to delimit a comment, you will need
to specify something
in your file generation process to include these in
the finished product.
Listing 2 shows a sample which we use for the maintenance
of our DNS
files.
Keeping Track
If you are the only person working on the files controlled
by SCCS,
you will have little trouble keeping abreast of what's
being edited.
However, since it's more often the case that a number
of programmers
or administrators may be working on the same file, SCCS
provides a
special variant of the prs command -- the sact command
-- to keep track. This command reports on the files
which are currently
out for edit. It takes only one argument, which is the
name or
names of the file(s) you want to check on, or the name
of a directory
which contains SCCS files.
sact first checks the list of files for those which
are out
on edits. It reports an error on any file that isn't
an SCCS file
(that is, that doesn't start with s.). Finally, for
all SCCS
files out for edit, it displays the content of the p-file,
listing the delta, date, and time, and the ID of the
user who executed
the get -e.
Removing Deltas
It sometimes occurs that an entire delta must be deleted.
If the problem
is with the most recent delta, then you can remove the
offending delta
and related changes. This command should be used regularly,
but only
when it is necessary to correct a number of global errors.
The command is rmdel, and there are a number of restrictions
to its use:
The release cannot be locked against editing. If it
is, then the delta removal will fail.
You must run the command with the complete SID to be
removed. For
example, if you want to remove SID 2.1 from the file
s.names,
you would enter the command as
$ rmdel -r2.1 s.names
If the file is being edited, then you will see this
response
to the rmdel command:
ERROR [s.names]: being edited -- sid is in p-file (rc12)
If the SID requested is not the current SID, then you
will see this message:
ERROR [s.names]: not a 'leaf' delta (rc5)
This means that there is a delta which follows the specified
one.
Combining Deltas
You may also have occasion to combine deltas (you might
hope
to save some disk space, for example; though combining
deltas in fact
may take more disk space). The command for this purpose
is the comb
command. Using this command will effectively alter the
shape of
the SCCS tree by removing and merging multiple deltas
into a single
delta.
comb works by generating a shell procedure on the standard
output which reconstructs the SCCS file by removing
unwanted deltas
and combining others. In the absence of any options,
comb will
simply preserve the leaf deltas, and the minimum number
of ancestors
to preserve the shape of the tree.
The command
comb -s s.names
will generate a shell procedure which reports how much
space (if any) will be saved. The resulting shell program
is shown
in Listing 3.
So What Changed?
A key benefit of using SCCS is that you can find out
what changed
in each revision. There are a couple of methods of doing
this: one
with get, the other with sccsdif.
With get you would use the -m option, which instructs
get to print the SID responsible for adding the line
at the
beginning of each line. For the s.names file, you would
enter
$ get -m -p s.names
You could instead use the sccsdif command, which
determines and prints the differences between two releases
of the
same file. The two releases to be checked are specified
as the first
two arguments to sccsdif, followed by the name of the
file.
$ sccsdiff -r1.6 -r3.2 s.names
The output of the command is the same as with diff.
Auditing
If an SCCS file becomes corrupted or damaged, you must
the admin
command again to rebuild the s-file. In fact, no SCCS
command
except for admin will even process the corrupted file.
It's a good idea to audit SCCS files regularly for corruption.
To
do this, use the admin command with the -h option. This
will verify the contents of the file against the checksum
which is
at the top of the SCCS file. If there is a problem,
you may edit the
file after setting its permissions to 644.
Once the edit is complete, run admin -h again to verify
that
there are no problems. If the situation appears to be
resolved, run
admin -z to generate a new checksum, and then run admin
-h once again to verify that the file is still valid.
If the file is severely damaged, however, it will be
necessary to
restore it from a backup.
Getting Help
SCCS provides help only in conjunction with its various
error messages.
The help command prints the syntax of SCCS commands,
as well
as information on the specified error code. The argument
to be passed
to help is the error code reported (in brackets) after
the
command failed.
If no argument is given on the command line, then help
will prompt
for one. You can enter more than one error code as arguments,
and
each one will in turn be printed.
The help database containing all of the error messages
and information
is /usr/lib/help. There is a file for each group of
commands,
and the related text. These are flat ASCII files, so
you could print
them and study them at your leisure if you wished.
Putting It All Together
A practical example of using SCCS is our management
of the configuration
files for our Domain Name Server. DNS includes a number
of files that
need to be controlled. All of these files are included
in a Makefile,
which is installed in the directory where the DNS files
are (on our
system this is /usr/lib/named). Here is a list of the
files:
s.named.boot named.boot (normally in /etc)
s.named.hosts named.hosts - host/address information
s.named.rev named.rev - reversed address resolution
s.root.cache root.cache - root nameservers
s.named.local named.local - local system
s.named.soa named.soa - authority records
(It is not essential that you understand the Domain
Namer
Server technology; the focus is on a methodology for
controlling this
set of files.)
Each of the files has a header which looks like
;----- VERSION CONTROL ----------------------------------
; @(#)text 2.10 /u/chare/Filecabinet/sysadmin/sccs/s.text
;
;History
;-------
; MOD WHO DATE WHAT
; YYMMDD
; -------------------------------------------------------
*include(DELTA)
;----- END ----------------------------------------------
;
This header contains some get keywords which are
expanded during the extraction of the file. The #W#
puts in
a line of text that can be picked up by the what command;
the
#P# is the absolute pathname of the file.
With the exception of the line *include(DELTA), the
remainder
goes into the finished file as is.
The Makefile entry which creates the named.soa file
looks like this
NAMED = named.hosts named.rev named.local [etc]
named.soa: $(NAMED)
get -e -s s.named.soa
delta -y"Increment Serial Number to activate change" s.named.soa
get -g -lp s.named.soa | head -1 .m1
prs -e -r`cat .m1` -d';:I:\t:P:\t:D:\t:C:' s.named.soa | grep "^;" .m2
get -s -p s.named.soa .m4
m4 -DDELTA=.m2 .m4 named.soa
chmod 444 named.soa
rm .m1 .m2 .m3 .m4
kill -1 `cat /etc/named.pid`
When named.soa must be changed, executing this makefile
entry will perform the following steps: