| jul93.tar |
SCCS: Keeping It under Control
Chris Hare Why Use SCCS or RCS? 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. Terminology SCCS makes special use of certain terms.
release.level.branch.sequence
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:
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:
*include(DELTA)
which, in actual fact, is an m4 macro command. This include command will cause the contents of DELTA to be substituted in its place. On the command line where m4 is called, I indicate that DELTA is the output of the earlier prs command. The end result is the file named.soa.
The finished product is shown in Figure 2. Conclusion There is a wide range of possiblilities where some form of Source Code Control System or Revision Control System can be implemented -- actual Source Code management is only one of them. As I've shown here, using SCCS in combination with other facilities, such as make and the m4 macro processor, the possibilities are almost limitless.
About the Author
Chris Hare is Ottawa Technical Services Manager for Choreo Systems, Inc. He has worked in the UNIX environment since 1986 and in 1988 became one of the first SCO authorized instructors in Canada. He teaches UNIX introductory, system administration, and programming classes. His current focus is on networking, Perl, and X. Chris can be reached at chare@choreo.ca, or chare@unilabs.org, which is his home.
|