From 9e723d65b3dbe4a3c599923d35ce1e637e0d32e1 Mon Sep 17 00:00:00 2001 From: peter Date: Sat, 30 Dec 1995 19:02:48 +0000 Subject: recording cvs-1.6 file death --- usr.bin/sccs/Makefile | 5 - usr.bin/sccs/PSD.doc/Makefile | 10 - usr.bin/sccs/PSD.doc/sccs.me | 1608 ---------------------------------------- usr.bin/sccs/PSD.doc/spell.ok | 77 -- usr.bin/sccs/pathnames.h | 51 -- usr.bin/sccs/sccs.1 | 398 ---------- usr.bin/sccs/sccs.c | 1621 ----------------------------------------- 7 files changed, 3770 deletions(-) delete mode 100644 usr.bin/sccs/Makefile delete mode 100644 usr.bin/sccs/PSD.doc/Makefile delete mode 100644 usr.bin/sccs/PSD.doc/sccs.me delete mode 100644 usr.bin/sccs/PSD.doc/spell.ok delete mode 100644 usr.bin/sccs/pathnames.h delete mode 100644 usr.bin/sccs/sccs.1 delete mode 100644 usr.bin/sccs/sccs.c (limited to 'usr.bin/sccs') diff --git a/usr.bin/sccs/Makefile b/usr.bin/sccs/Makefile deleted file mode 100644 index 0ee9d1b..0000000 --- a/usr.bin/sccs/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -# @(#)Makefile 8.1 (Berkeley) 6/6/93 - -PROG= sccs - -.include diff --git a/usr.bin/sccs/PSD.doc/Makefile b/usr.bin/sccs/PSD.doc/Makefile deleted file mode 100644 index 4d2ba7f..0000000 --- a/usr.bin/sccs/PSD.doc/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -# @(#)Makefile 8.1 (Berkeley) 6/8/93 - -DIR= psd/14.sccs -SRCS= sccs.me -MACROS= -me - -paper.ps: ${SRCS} - ${ROFF} ${SRCS} > ${.TARGET} - -.include diff --git a/usr.bin/sccs/PSD.doc/sccs.me b/usr.bin/sccs/PSD.doc/sccs.me deleted file mode 100644 index ab598c2..0000000 --- a/usr.bin/sccs/PSD.doc/sccs.me +++ /dev/null @@ -1,1608 +0,0 @@ -.\" Copyright (c) 1986, 1993 -.\" The Regents of the University of California. All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. -.\" 4. Neither the name of the University nor the names of its contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" @(#)sccs.me 8.1 (Berkeley) 6/8/93 -.\" -.eh '\fRPSD:14-%\fP''\fRAn Introduction to the Source Code Control System\fP' -.oh '\fRAn Introduction to the Source Code Control System\fP''\fRPSD:14-%\fP' -.ds S \s-1SCCS\s0 -.ds I \s-1SID\s0 -.nr bi 8n -.ev 1 \" only for keeps -.ss 16 -.ev -.\".he '\*S Introduction''%' -.+c -.(l C -.sz 14 -.b -An Introduction to the -Source Code Control System -.sz -.r -.sp -Eric Allman -.i "Project Ingres" -.i "University of California at Berkeley" -.)l -.sp 3 -.pp -.(f -This is version 1.21 of this document. -It was last modified on 12/5/80. -.)f -This document gives a quick introduction -to using the Source Code Control System -(\*S). -The presentation is geared to programmers -who are more concerned with -what -to do to get a task done -rather than how it works; -for this reason some of the examples -are not well explained. -For details of what the magic options do, -see the section on -.q "Further Information" . -.(l F -This is a working document. -Please send any comments or suggestions -to eric@Berkeley.Edu. -.)l -.sh 1 "Introduction" -.pp -\*S is a source management system. -Such a system maintains a record of versions of a system; -a record is kept with each set of changes -of what the changes are, -why they were made, -and who made them and when. -Old versions can be recovered, -and different versions can be maintained simultaneously. -In projects with more than one person, -\*S will insure that two people are not -editing the same file at the same time. -.pp -All versions of your program, -plus the log and other information, -is kept in a file called the -.q "s-file" . -There are three major operations -that can be performed on the s-file: -.np -Get a file for compilation (not for editing). -This operation retrieves a version of the file -from the s-file. -By default, the latest version is retrieved. -This file is intended for compilation, printing, or whatever; -it is specifically NOT intended to be edited -or changed in any way; -any changes made to a file retrieved -in this way will probably be lost. -.np -Get a file for editing. -This operation also retrieves a version of the file -from the s-file, -but this file is intended to be edited and then -incorporated back into the s-file. -Only one person may be editing a file at one time. -.np -Merge a file back into the s-file. -This is the companion operation to (2). -A new version number is assigned, -and comments are saved explaining why this change was made. -.sh 1 "Learning the Lingo" -.pp -There are a number of terms that are worth learning -before we go any farther. -.sh 2 "S-file" -.pp -The s-file -is a single file that holds all the different versions -of your file. -The s-file is stored in -differential format; -.i i.e. , -only the differences between versions are stored, -rather than the entire text of the new version. -This saves disk space -and allows selective changes to be removed later. -Also included in the s-file -is some header information for each version, -including the comments given by the person who -created the version explaining why the changes were made. -.sh 2 "Deltas" -.pp -Each set of changes to the s-file -(which is approximately [but not exactly!] equivalent -to a version of the file) -is called a -.i delta . -Although technically a delta only includes the -.i changes -made, -in practice -it is usual for -each delta to be made with respect to -all the deltas that have occurred before\**. -.(f -\**This matches normal usage, where the previous changes are not saved -at all, -so all changes are automatically based on all other changes -that have happened through history. -.)f -However, -it is possible to get a version of the file -that has selected deltas removed out of the middle -of the list of changes \*- -equivalent to removing your changes later. -.sh 2 "\*I's (or, version numbers)" -.pp -A \*I -(\*S Id) -is a number that represents a delta. -This is normally a two-part number -consisting of a -.q release -number and a -.q level -number. -Normally the release number stays the same, -however, -it is possible to move into a new release -if some major change is being made. -.pp -Since all past deltas are normally applied, -the \*I of the final delta applied -can be used to represent a version number of the file -as a whole. -.sh 2 "Id keywords" -.pp -When you get a version of a file -with intent to compile and install it -(\c -.i i.e. , -something other than edit it), -some special keywords are expanded inline -by \*S. -These -.i "Id Keywords" -can be used to include the current version number -or other information into the file. -All id keywords are of the form -.b % \c -.i x \c -.b % , -where -.i x -is an upper case letter. -For example, -.b %\&I\&% -is the \*I of the latest delta applied, -.b %\&W\&% -includes the module name, -\*I, -and a mark that makes it findable by a program, -and -.b %\&G\&% -is the date of the latest delta applied. -There are many others, -most of which are of dubious usefulness. -.pp -When you get a file for editing, -the id keywords are not expanded; -this is so that after you put them back in to the s-file, -they will be expanded automatically on each new version. -But notice: if you were to get them -expanded accidently, -then your file would appear to be the same version -forever more, -which would of course defeat the purpose. -Also, -if you should install a version of the program -without expanding the id keywords, -it will be impossible to tell what version it is -(since all it will have is -.q %\&W\&% -or whatever). -.sh 1 "Creating \*S Files" -.pp -To put source files -into -\*S -format, run the following shell script from csh: -.(b -mkdir SCCS save -foreach i (*.[ch]) - sccs admin \-i$i $i - mv $i save/$i -end -.)b -This will put the named files -into s-files -in the subdirectory -.q SCCS -The files will be removed from the current directory -and hidden away in the directory -.q save , -so the next thing you will probably want to do -is to get all the files -(described below). -When you are convinced that -\*S has correctly created the s-files, -you should remove the directory -.q save . -.pp -If you want to have id keywords in the files, -it is best to put them in before you create the s-files. -If you do not, -.i admin -will print -.q "No Id Keywords (cm7)" , -which is a warning message only. -.sh 1 "Getting Files for Compilation" -.pp -To get a copy of the latest version -of a file, -run -.(b -sccs get prog.c -.)b -\*S will respond: -.(b -1.1 -87 lines -.)b -meaning that version 1.1 was retrieved\** -.(f -\**Actually, -the \*I of the final delta applied was 1.1. -.)f -and that it has 87 lines. -The file -.i prog.c -will be created -in the current directory. -The file will be read-only -to remind you that you are not -supposed to change it. -.pp -This copy of the file -should not be changed, -since \*S is unable -to merge the changes -back into the s-file. -If you do make changes, -they will be lost the next time -someone does a -.i get . -.sh 1 "Changing Files (or, Creating Deltas)" -.sh 2 "Getting a copy to edit" -.pp -To edit a source file, -you must first get it, -requesting permission to edit it\**: -.(f -\**The -.q "edit" -command is equivalent to using the \-e -flag to -.i "get" , -as: -.(l -sccs get \-e prog.c -.)l -Keep this in mind when reading other documentation. -.)f -.(b -sccs edit prog.c -.)b -The response will be the same as with -.i get -except that it will also say: -.(b -New delta 1.2 -.)b -You then edit it, -using a standard text editor: -.(b -vi prog.c -.)b -.sh 2 "Merging the changes back into the s-file" -.pp -When the desired changes are made, -you can put your changes into the -\*S -file using the -.i delta -command: -.(b -sccs delta prog.c -.)b -.pp -Delta will prompt you for -.q "comments?" -before it merges the changes in. -At this prompt you should type a one-line description -of what the changes mean -(more lines can be entered by ending each line -except the last with a backslash\**). -.(f -\**Yes, this is a stupid default. -.)f -.i Delta -will then type: -.(b -1.2 -5 inserted -3 deleted -84 unchanged -.)b -saying that delta 1.2 was created, -and it inserted five lines, -removed three lines, -and left 84 lines unchanged\**. -.(f -\**Changes to a line are counted as a line deleted -and a line inserted. -.)f -The -.i prog.c -file will be removed; -it can be retrieved -using -.i get . -.sh 2 "When to make deltas" -.pp -It is probably unwise to make a delta -before every recompilation or test; -otherwise, -you tend to get a lot of deltas with comments like -.q "fixed compilation problem in previous delta" -or -.q "fixed botch in 1.3" . -However, -it is very important to delta everything -before installing a module for general use. -A good technique is to edit the files you need, -make all necessary changes and tests, -compiling and editing as often as necessary -without making deltas. -When you are satisfied that you have a working version, -delta everything being edited, -re-get them, -and recompile everything. -.sh 2 "What's going on: the info command" -.pp -To find out what files where being edited, -you can use: -.(b -sccs info -.)b -to print out all the files being edited -and other information such as the name of the user -who did the edit. -Also, -the command: -.(b -sccs check -.)b -is nearly equivalent to the -.i info -command, -except that it is silent if nothing is being edited, -and returns non-zero exit status if anything is being edited; -it can be used in an -.q install -entry in a makefile -to abort the install -if anything has not been properly deltaed. -.pp -If you know that everything being edited should be deltaed, -you can use: -.(b -sccs delta \`sccs tell\` -.)b -The -.i tell -command is similar to -.i info -except that only the names of files being edited -are output, -one per line. -.pp -All of these commands take a -.b \-b -flag -to ignore -.q branches -(alternate versions, described later) -and the -.b \-u -flag to only give files being edited by you. -The -.b \-u -flag takes an optional -.i user -argument, -giving only files being edited by that user. -For example, -.(b -sccs info \-ujohn -.)b -gives a listing of files being edited by john. -.sh 2 "ID keywords" -.pp -Id keywords can be inserted into your file -that will be expanded automatically by -.i get . -For example, -a line such as: -.(b -static char SccsId[] = "%\&W\&%\et%\&G\&%"; -.)b -will be replaced with something like: -.(b -static char SccsId[] = "@\&(#)prog.c 1.2 08/29/80"; -.)b -This tells you -the name and version -of the source file -and the time the delta was created. -The string -.q "@\&(#)" -is a special string -which signals the beginning -of an -\*S -Id keyword. -.sh 3 "The what command" -.pp -To find out what version of a program -is being run, -use: -.(b -sccs what prog.c /usr/bin/prog -.)b -which will print all strings -it finds that -begin with -.q "@\&(#)" . -This works on all types of files, -including binaries and libraries. -For example, the above command will output something like: -.(b -prog.c: - prog.c 1.2 08/29/80 -/usr/bin/prog: - prog.c 1.1 02/05/79 -.)b -From this I can see -that the source that I have in prog.c -will not compile into the same version -as the binary in /usr/bin/prog. -.sh 3 "Where to put id keywords" -.pp -ID keywords can be inserted anywhere, -including in comments, -but -Id Keywords that are compiled into the object module -are especially useful, -since it lets you find out what version of -the object is being run, -as well as the source. -However, -there is a cost: -data space is used up to store -the keywords, -and on small address space machines -this may be prohibitive. -.pp -When you put id keywords into header files, -it is important that you assign them to different variables. -For example, you might use: -.(b -static char AccessSid[] = "%\&W\&% %\&G\&%"; -.)b -in the file -.i access.h -and: -.(b -static char OpsysSid[] = "%\&W\&% %\&G\&%"; -.)b -in the file -.i opsys.h . -Otherwise, -you will get compilation errors because -.q SccsId -is redefined. -The problem with this is that if the header file -is included by many modules that are loaded together, -the version number of that header file is included -in the object module many times; -you may find it more to your taste -to put id keywords in header files -in comments. -.sh 2 "Keeping \*I's consistent across files" -.pp -With some care, -it is possible to keep the \*I's consistent -in multi-file systems. -The trick here is to always -.i edit -all files -at once. -The changes can then be made -to whatever files are necessary -and then all files -(even those not changed) -are redeltaed. -This can be done fairly easily -by just specifying the name of the directory -that the \*S files are in: -.(b -sccs edit SCCS -.)b -which will -.i edit -all files in that directory. -To make the delta, use: -.(b -sccs delta SCCS -.)b -You will be prompted for comments only once. -.sh 2 "Creating new releases" -.pp -When you want to create a new release -of a program, -you can specify the release number you want to create -on the -.i edit -command. -For example: -.(b -sccs edit \-r2 prog.c -.)b -will cause the next delta to be in release two -(that is, -it will be numbered 2.1). -Future deltas will automatically be in release two. -To change the release number -of an entire system, -use: -.(b -sccs edit \-r2 SCCS -.)b -.sh 1 "Restoring Old Versions" -.sh 2 "Reverting to old versions" -.pp -Suppose that after delta 1.2 -was stable -you made and released a delta 1.3. -But this introduced a bug, -so you made a delta 1.4 to correct it. -But 1.4 was still buggy, -and you decided you wanted to go back -to the old version. -You could -revert to delta 1.2 -by choosing the \*I in a get: -.(b -sccs get \-r1.2 prog.c -.)b -This will produce a version of -.i prog.c -that is delta 1.2 -that can be reinstalled so that work can proceed. -.pp -In some cases you don't know -what the \*I of the delta you want is. -However, -you can revert to the version of the program -that was running as of a certain date -by using the -.b \-c -(cutoff) flag. -For example, -.(b -sccs get \-c800722120000 prog.c -.)b -will retrieve whatever version was current -as of July 22, 1980 -at 12:00 noon. -Trailing components can be stripped off -(defaulting to their highest legal value), -and punctuation can be inserted in the obvious -places; -for example, -the above line could be equivalently stated: -.(b -sccs get \-c"80/07/22 12:00:00" prog.c -.)b -.sh 2 "Selectively deleting old deltas" -.pp -Suppose that you later decided -that you liked the changes in delta 1.4, -but that delta 1.3 should be removed. -You could do this by -.i excluding -delta 1.3: -.(b -sccs edit \-x1.3 prog.c -.)b -When delta 1.5 is made, -it will include the changes made -in delta 1.4, -but will exclude the changes made -in delta 1.3. -You can exclude a range of deltas -using a dash. -For example, -if you want to get rid of 1.3 and 1.4 -you can use: -.(b -sccs edit \-x1.3\-1.4 prog.c -.)b -which will exclude all deltas from 1.3 to 1.4. -Alternatively, -.(b -sccs edit \-x1.3\-1 prog.c -.)b -will exclude a range of deltas -from 1.3 to the current highest delta in release 1. -.pp -In certain cases when using -.b \-x -(or -.b \-i ; -see below) -there will be conflicts -between versions; -for example, it may be necessary -to both include and delete -a particular line. -If this happens, -\*S always prints out a message -telling the range of lines effected; -these lines should then be examined very carefully -to see if the version \*S got -is ok. -.pp -Since each delta -(in the sense of -.q "a set of changes" ) -can be excluded at will, -that this makes it most useful -to put each semantically distinct change -into its own delta. -.sh 1 "Auditing Changes" -.sh 2 "The prt command" -.pp -When you created a delta, -you presumably gave a reason for the delta -to the -.q "comments?" -prompt. -To print out these comments later, -use: -.(b -sccs prt prog.c -.)b -This will produce -a report -for each delta -of the \*I, -time and date of creation, -user who created the delta, -number of lines inserted, deleted, and unchanged, -and the comments associated with the delta. -For example, the output of the above command might be: -.(b -D 1.2 80/08/29 12:35:31 bill 2 1 00005/00003/00084 -removed "-q" option -.sp \n(psu -D 1.1 79/02/05 00:19:31 eric 1 0 00087/00000/00000 -date and time created 80/06/10 00:19:31 by eric -.)b -.sh 2 "Finding why lines were inserted" -.pp -To find out -why you inserted lines, -you can get a copy of the file -with each line -preceded by the \*I that created it: -.(b -sccs get \-m prog.c -.)b -You can then find out -what this delta did -by printing the comments using -.i prt . -.pp -To find out what lines are associated with a particular delta -(\c -.i e.g. , -1.3), -use: -.(b -sccs get \-m \-p prog.c \(bv grep \'^1.3\' -.)b -The -.b \-p -flag causes \*S to output the generated source -to the standard output rather than to a file. -.sh 2 "Finding what changes you have made" -.pp -When you are editing a file, -you can find out what changes you have made using: -.(b -sccs diffs prog.c -.)b -Most of the ``diff'' flags can be used. -To pass the -.b \-c -flag, -use -.b \-C . -.pp -To compare two versions that are in deltas, -use: -.(b -sccs sccsdiff -r1.3 -r1.6 prog.c -.)b -to see the differences between delta 1.3 and delta 1.6. -.sh 1 "Shorthand Notations" -.pp -There are several sequences of commands that get -executed frequently. -.i Sccs -tries to make it easy to do these. -.sh 2 "Delget" -.pp -A frequent requirement is to make a delta of some file -and then get that file. -This can be done by using: -.(b -sccs delget prog.c -.)b -which is entirely equivalent to using: -.(b -sccs delta prog.c -sccs get prog.c -.)b -The -.q deledit -command is equivalent to -.q delget -except that the -.q edit -command is used -instead of the -.q get -command. -.sh 2 "Fix" -.pp -Frequently, there are small bugs -in deltas, -e.g., compilation errors, -for which there is no reason to maintain an audit trail. -To -.i replace -a delta, use: -.(b -sccs fix \-r1.4 prog.c -.)b -This will get a copy of delta 1.4 of prog.c for you to edit -and then delete delta 1.4 from the \*S file. -When you do a delta of prog.c, -it will be delta 1.4 again. -The \-r flag must be specified, -and the delta that is specified must be a leaf delta, -i.e., no other deltas may have been made subsequent -to the creation of that delta. -.sh 2 "Unedit" -.pp -If you found you edited a file -that you did not want to edit, -you can back out by using: -.(b -sccs unedit prog.c -.)b -.sh 2 "The \-d flag" -.pp -If you are working on a project -where the \*S code is in a directory somewhere, -you may be able to simplify things -by using a shell alias. -For example, -the alias: -.(b -alias syssccs sccs \-d/usr/src -.)b -will allow you to issue commands such as: -.(b -syssccs edit cmd/who.c -.)b -which will look for the file -.q "/usr/src/cmd/SCCS/who.c" . -The file -.q who.c -will always be created in your current directory -regardless of the value of the \-d flag. -.sh 1 "Using \*S on a Project" -.pp -Working on a project with several people -has its own set of special problems. -The main problem occurs when two people -modify a file at the same time. -\*S prevents this by locking an s-file -while it is being edited. -.pp -As a result, -files should not be reserved for editing -unless they are actually being edited at the time, -since this will prevent other people on the project -from making necessary changes. -For example, -a good scenario for working might be: -.(b -sccs edit a.c g.c t.c -vi a.c g.c t.c -# do testing of the (experimental) version -sccs delget a.c g.c t.c -sccs info -# should respond "Nothing being edited" -make install -.)b -.pp -As a general rule, -all source files should be deltaed -before installing the program for general use. -This will insure that it is possible -to restore any version in use at any time. -.sh 1 "Saving Yourself" -.sh 2 "Recovering a munged edit file" -.pp -Sometimes you may find -that you have destroyed or trashed -a file that you were trying to edit\**. -.(f -\**Or given up and decided to start over. -.)f -Unfortunately, -you can't just remove it -and re-\c -.i edit -it; -\*S keeps track -of the fact -that someone is trying to edit it, -so it won't let you do it again. -Neither can you just get it using -.i get , -since that would expand the Id keywords. -Instead, -you can say: -.(b -sccs get \-k prog.c -.)b -This will not expand the Id keywords, -so it is safe to do a delta -with it. -.pp -Alternately, -you can -.i unedit -and -.i edit -the file. -.sh 2 "Restoring the s-file" -.pp -In particularly bad circumstances, -the \*S file itself -may get munged. -The most common way this happens -is that it gets edited. -Since \*S keeps a checksum, -you will get errors every time you read the file. -To fix this checksum, use: -.(b -sccs admin \-z prog.c -.)b -.sh 1 "Using the Admin Command" -.pp -There are a number of parameters that can be set -using the -.i admin -command. -The most interesting of these are flags. -Flags can be added by using the -.b \-f -flag. -For example: -.(b -sccs admin \-fd1 prog.c -.)b -sets the -.q d -flag to the value -.q 1 . -This flag can be deleted by using: -.(b -sccs admin \-dd prog.c -.)b -The most useful flags are: -.nr ii 7n -.ip "b" -Allow branches to be made using the -\-b -flag to -.i edit . -.ip "d\fISID\fP" -Default \*I to be used on a -.i get -or -.i edit . -If this is just a release number -it constrains the -version -to a particular release only. -.ip "i" -Give a fatal error -if there are no Id Keywords in a file. -This is useful to guarantee that a version of the -file does not get merged into the s-file -that has the Id Keywords inserted as constants -instead of internal forms. -.ip "y" -The -.q type -of the module. -Actually, -the value of this flag is unused by \*S -except that it replaces the -.b %\&Y\&% -keyword. -.pp -The -.b \-t\fIfile\fR -flag can be used -to store descriptive text -from -.i file . -This descriptive text might be the documentation -or a design and implementation document. -Using the -.b \-t -flag insures that if the \*S file is sent, -the documentation will be sent also. -If -.i file -is omitted, -the descriptive text is deleted. -To see the descriptive text, -use -.q "prt \-t" . -.pp -The -.i admin -command can be used safely -any number of times on files. -A file need not be gotten -for -.i admin -to work. -.sh 1 "Maintaining Different Versions (Branches)" -.pp -Sometimes it is convenient -to maintain an experimental version of a program -for an extended period -while normal maintenance continues -on the version in production. -This can be done using a -.q branch. -Normally deltas continue in a straight line, -each depending on the delta before. -Creating a branch -.q "forks off" -a version of the program. -.pp -The ability to create branches -must be enabled in advance using: -.(b -sccs admin \-fb prog.c -.)b -The -.b \-fb -flag can be specified when the -\*S file is first created. -.sh 2 "Creating a branch" -.pp -To create a branch, use: -.(b -sccs edit \-b prog.c -.)b -This will create a branch -with (for example) \*I 1.5.1.1. -The deltas for this version -will be numbered -1.5.1.\c -.i n . -.sh 2 "Getting from a branch" -.pp -Deltas in a branch are normally not included -when you do a get. -To get these versions, -you will have to say: -.(b -sccs get \-r1.5.1 prog.c -.)b -.sh 2 "Merging a branch back into the main trunk" -.pp -At some point you will have finished the experiment, -and if it was successful -you will want to incorporate it into the release version. -But in the meantime -someone may have created a delta 1.6 -that you don't want to lose. -The commands: -.(b -sccs edit \-i1.5.1.1\-1.5.1 prog.c -sccs delta prog.c -.)b -will merge all of your changes -into the release system. -If some of the changes conflict, -get will print an error; -the generated result -should be carefully examined -before the delta is made. -.sh 2 "A more detailed example" -.pp -The following technique might be used -to maintain a different version of a program. -First, -create a directory to contain the new version: -.(b -mkdir ../newxyz -cd ../newxyz -.)b -Edit a copy of the program -on a branch: -.(b -sccs \-d../xyz edit prog.c -.)b -When using the old version, -be sure to use the -.b \-b -flag to info, check, tell, and clean -to avoid confusion. -For example, use: -.(b -sccs info \-b -.)b -when in the directory -.q xyz . -.pp -If you want to save a copy of the program -(still on the branch) -back in the s-file, -you can use: -.(b -sccs -d../xyz deledit prog.c -.)b -which will do a delta on the branch -and reedit it for you. -.pp -When the experiment is complete, merge it back into the s-file -using delta: -.(b -sccs -d../xyz delta prog.c -.)b -At this point you must decide whether this version -should be merged back into the trunk -(\c -.i i.e. -the default version), -which may have undergone changes. -If so, it can be merged using the -.b \-i -flag to -.i edit -as described above. -.sh 2 "A warning" -.pp -Branches should be kept to a minimum. -After the first branch from the trunk, -\*I's are assigned rather haphazardly, -and the structure gets complex fast. -.sh 1 "Using \*S with Make" -.pp -\*S and make can be made to work together -with a little care. -A few sample makefiles -for common applications are shown. -.pp -There are a few basic entries that every makefile -ought to have. -These are: -.nr ii 1i -.ip a.out -(or whatever the makefile generates.) -This entry regenerates whatever this makefile is -supposed to regenerate. -If the makefile regenerates many things, -this should be called -.q all -and should in turn -have dependencies on everything -the makefile can generate. -.ip install -Moves the objects to the final -resting place, -doing any special -.i chmod 's -or -.i ranlib 's -as appropriate. -.ip sources -Creates all the source files from \*S files. -.ip clean -Removes all files from the current directory -that can be regenerated from \*S files. -.ip print -Prints the contents of the directory. -.lp -The examples shown below are only partial examples, -and may omit some of these entries -when they are deemed to be obvious. -.pp -The -.i clean -entry should not remove files that can be -regenerated from the \*S files. -It is sufficiently important to have the -source files around at all times -that the only time they should be removed -is when the directory is being mothballed. -To do this, the command: -.(b -sccs clean -.)b -can be used. -This will remove all files for which an s-file -exists, -but which is not being edited. -.sh 2 "To maintain single programs" -.pp -Frequently there are directories with several -largely unrelated programs -(such as simple commands). -These can be put into a single makefile: -.(b -LDFLAGS= \-i \-s -.sp \n(psu -prog: prog.o - $(CC) $(LDFLAGS) \-o prog prog.o -prog.o: prog.c prog.h -.sp \n(psu -example: example.o - $(CC) $(LDFLAGS) \-o example example.o -example.o: example.c -.sp \n(psu -\&.DEFAULT: - sccs get $< -.)b -The trick here -is that the .DEFAULT rule -is called every time -something is needed -that does not exist, -and no other rule exists to make it. -The explicit dependency of the -.b \&.o -file on the -.b \&.c -file is important. -Another way of doing the same thing is: -.(b -SRCS= prog.c prog.h example.c -.sp \n(psu -LDFLAGS= \-i \-s -.sp \n(psu -prog: prog.o - $(CC) $(LDFLAGS) \-o prog prog.o -prog.o: prog.h -.sp \n(psu -example: example.o - $(CC) $(LDFLAGS) \-o example example.o -.sp \n(psu -sources: $(SRCS) -$(SRCS): - sccs get $@ -.)b -There are a couple of advantages to this approach: -(1) the explicit dependencies of the .o on the .c files are -not needed, -(2) there is an entry called "sources" so if you want to get -all the sources you can just say -.q "make sources" , -and -(3) the makefile is less likely to do confusing things -since it won't try to -.i get -things that do not exist. -.sh 2 "To maintain a library" -.pp -Libraries that are largely static -are best updated using explicit commands, -since -.i make -doesn't know about updating them properly. -However, -libraries that are in the process of being developed -can be handled quite adequately. -The problem is that the .o files -have to be kept out of the library -as well as in the library. -.(b -# configuration information -OBJS= a.o b.o c.o d.o -SRCS= a.c b.c c.c d.s x.h y.h z.h -TARG= /usr/lib -.sp \n(psu -# programs -GET= sccs get -REL= -AR= \-ar -RANLIB= ranlib -.sp \n(psu -lib.a: $(OBJS) - $(AR) rvu lib.a $(OBJS) - $(RANLIB) lib.a -.sp \n(psu -install: lib.a - sccs check - cp lib.a $(TARG)/lib.a - $(RANLIB) $(TARG)/lib.a -.sp \n(psu -sources: $(SRCS) -$(SRCS): - $(GET) $(REL) $@ -.sp \n(psu -print: sources - pr *.h *.[cs] -clean: - rm \-f *.o - rm \-f core a.out $(LIB) -.)b -.pp -The -.q "$(REL)" -in the get -can be used to get old versions -easily; for example: -.(b -make b.o REL=\-r1.3 -.)b -.pp -The -.i install -entry includes the line -.q "sccs check" -before anything else. -This guarantees that all the s-files -are up to date -(\c -.i i.e. , -nothing is being edited), -and will abort the -.i make -if this condition is not met. -.sh 2 "To maintain a large program" -.(b -OBJS= a.o b.o c.o d.o -SRCS= a.c b.c c.y d.s x.h y.h z.h -.sp \n(psu -GET= sccs get -REL= -.sp \n(psu -a.out: $(OBJS) - $(CC) $(LDFLAGS) $(OBJS) $(LIBS) -.sp \n(psu -sources: $(SRCS) -$(SRCS): - $(GET) $(REL) $@ -.)b -(The -.i print -and -.i clean -entries are identical to the previous case.) -This makefile requires copies of the source and object files -to be kept during development. -It is probably also wise to include lines of the form: -.(b -a.o: x.h y.h -b.o: z.h -c.o: x.h y.h z.h -z.h: x.h -.)b -so that modules will be recompiled -if header files change. -.pp -Since -.i make -does not do transitive closure on dependencies, -you may find in some makefiles lines like: -.(b -z.h: x.h - touch z.h -.)b -This would be used in cases where file z.h -has a line: -.(b -#include "x.h" -.)b -in order to bring the mod date of z.h in line -with the mod date of x.h. -When you have a makefile such as above, -the -.i touch -command can be removed completely; -the equivalent effect will be achieved -by doing an automatic -.i get -on z.h. -.sh 1 "Further Information" -.pp -The -.i "SCCS/PWB User's Manual" -gives a deeper description -of how to use \*S. -Of particular interest -are the numbering of branches, -the l-file, -which gives a description of what deltas were used on a get, -and certain other \*S commands. -.pp -The \*S manual pages -are a good last resort. -These should be read by software managers -and by people who want to know -everything about everything. -.pp -Both of these documents were written without the -.i sccs -front end in mind, -so most of the examples are slightly different from those -in this document. -.bp -.sz 12 -.ce -.b "Quick Reference" -.sz -.sp 2 -.sh 1 Commands 1 -.pp -The following commands should all be preceded with -.q sccs . -This list is not exhaustive; -for more options see -.i "Further Information" . -.ip get 9n -Gets files for compilation (not for editing). -Id keywords are expanded. -.ba 9n -.nr ii 8n -.ip \-r\fI\*I\fP -Version to get. -.ip \-p -Send to standard output rather than to the actual file. -.ip \-k -Don't expand id keywords. -.ip \-i\fIlist\fP -List of deltas to include. -.ip \-x\fIlist\fP -List of deltas to exclude. -.ip \-m -Precede each line with \*I of creating delta. -.ip \-c\fIdate\fP -Don't apply any deltas created after -.i date. -.ba -.ip edit 9n -Gets files for editing. -Id keywords are not expanded. -Should be matched with a -.i delta -command. -.ba 9n -.nr ii 8n -.ip \-r\fI\*I\fP -Same as -.i get . -If -.i \*I -specifies a release that does not yet exist, -the highest numbered delta is retrieved -and the new delta is numbered with -.i \*I . -.ip \-b -Create a branch. -.ip \-i\fIlist\fP -Same as -.i get . -.ip \-x\fIlist\fP -Same as -.i get . -.ba -.ip delta 9n -Merge a file gotten using -.i edit -back into the s-file. -Collect comments about why this delta was made. -.ip unedit 9n -Remove a file that has been edited previously -without merging the changes into the s-file. -.ip prt 9n -Produce a report of changes. -.ba 9n -.nr ii 5n -.ip \-t -Print the descriptive text. -.ip \-e -Print (nearly) everything. -.ba -.ip info 9n -Give a list of all files being edited. -.ba 9n -.nr ii 5n -.ip \-b -Ignore branches. -.ip \-u[\fIuser\fP] -Ignore files not being edited by -.i user . -.ba -.ip check 9n -Same as -.i info , -except that nothing is printed if nothing is being edited -and exit status is returned. -.ip tell 9n -Same as -.i info , -except that one line is produced per file being edited containing -only the file name. -.ip clean 9n -Remove all files that can be regenerated from the -s-file. -.ip what 9n -Find and print id keywords. -.ip admin 9n -Create or set parameters on s-files. -.ba 9n -.nr ii 8n -.ip \-i\fIfile\fP -Create, using -.i file -as the initial contents. -.ip \-z -Rebuild the checksum in case -the file has been trashed. -.ip \-f\fIflag\fP -Turn on the -.i flag . -.ip \-d\fIflag\fP -Turn off (delete) the -.i flag . -.ip \-t\fIfile\fP -Replace the descriptive text -in the s-file with the contents of -.i file . -If -.i file -is omitted, -the text is deleted. -Useful for storing documentation -or -.q "design & implementation" -documents to insure they get distributed with the -s-file. -.lp -Useful flags are: -.ip b -Allow branches to be made using the \-b flag to -.i edit. -.ip d\fI\*I\fP -Default \*I to be used -on a -.i get -or -.i edit . -.ip i -Cause -.q "No Id Keywords" -error message -to be a fatal error rather than a warning. -.ip t -The module -.q type ; -the value of this flag replaces the -.b %\&Y\&% -keyword. -.ba -.ip fix 9n -Remove a delta and reedit it. -.ip delget 9n -Do a -.i delta -followed by a -.i get . -.ip deledit 9n -Do a -.i delta -followed by an -.i edit . -.sh 1 "Id Keywords" -.nr ii 6n -.ip "%\&Z\&%" -Expands to -.q @\&(#) -for the -.i what -command to find. -.ip "%\&M\&%" -The current module name, -.i e.g., -.q prog.c . -.ip "%\&I\&%" -The highest \*I applied. -.ip "%\&W\&%" -A shorthand for -.q "%\&Z\&%%\&M\&% %\&I\&%" . -.ip "%\&G\&%" -The date of the delta -corresponding to the -.q "%\&I\&%" -keyword. -.ip "%\&R\&%" -The current release number, -.i i.e. , -the first component of the -.q "%\&I\&%" -keyword. -.ip "%\&Y\&%" -Replaced by the value of the -.b t -flag -(set by -.i admin ). diff --git a/usr.bin/sccs/PSD.doc/spell.ok b/usr.bin/sccs/PSD.doc/spell.ok deleted file mode 100644 index fb2fe24..0000000 --- a/usr.bin/sccs/PSD.doc/spell.ok +++ /dev/null @@ -1,77 +0,0 @@ -AccessSid -Admin -Allman -Berkeley.Edu -Delget -Ingres -LDFLAGS -LIB -LIBS -OBJS -OpsysSid -PS1:14 -PWB -REL -SCCS -SID -SRCS -Sccs -SccsId -System''PS1:14 -TARG -a.c -a.o -a.out -access.h -admin -b.c -b.o -backslash -bi -c.c -c.o -c.y -ch -cm7 -cmd -cs -d.o -d.s -deledit -delget -eric -example.c -example.o -fb -fd1 -foreach -g.c -info -inline -john -lib -lib.a -makefile -makefiles -mod -mothballed -newxyz -ok -opsys.h -prog -prog.c -prog.h -prog.o -prt -rvu -sccs -sccsdiff -src -syssccs -t.c -ujohn -who.c -x.h -xyz -y.h -z.h diff --git a/usr.bin/sccs/pathnames.h b/usr.bin/sccs/pathnames.h deleted file mode 100644 index 4da6874..0000000 --- a/usr.bin/sccs/pathnames.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 1989, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)pathnames.h 8.1 (Berkeley) 6/6/93 - */ - -#include - -#define _PATH_SCCSADMIN "/usr/local/bin/admin" -#define _PATH_SCCSBDIFF "/usr/local/bin/bdiff" -#define _PATH_SCCSCOMB "/usr/local/bin/comb" -#define _PATH_SCCSDELTA "/usr/local/bin/delta" -#define _PATH_SCCSDIFF "/usr/local/bin/sccsdiff" -#define _PATH_SCCSGET "/usr/local/bin/get" -#define _PATH_SCCSHELP "/usr/local/bin/help" -#define _PATH_SCCSPRS "/usr/local/bin/prs" -#define _PATH_SCCSPRT "/usr/local/bin/prt" -#define _PATH_SCCSRMDEL "/usr/local/bin/rmdel" -#define _PATH_SCCSVAL "/usr/local/bin/val" -#define _PATH_SCCSWHAT "/usr/local/bin/what" -#undef _PATH_TMP -#define _PATH_TMP "/tmp/sccsXXXXX" diff --git a/usr.bin/sccs/sccs.1 b/usr.bin/sccs/sccs.1 deleted file mode 100644 index 7f4990c..0000000 --- a/usr.bin/sccs/sccs.1 +++ /dev/null @@ -1,398 +0,0 @@ -.\" Copyright (c) 1983, 1990, 1993 -.\" The Regents of the University of California. All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. -.\" 4. Neither the name of the University nor the names of its contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" @(#)sccs.1 8.1 (Berkeley) 6/6/93 -.\" -.Dd June 6, 1993 -.Dt SCCS 1 -.Os BSD 4.2 -.Sh NAME -.Nm sccs -.Nd front end for the -.Li SCCS -subsystem -.Sh SYNOPSIS -.Nm sccs -.Op Fl r -.Op Fl d Ar path -.Op Fl p Ar path -.Ar command -.Op flags -.Op Ar -.Sh DESCRIPTION -.Nm Sccs -is a front end to the -.Li SCCS -programs -that -helps them mesh more cleanly -with -the rest of UNIX. -It -also includes the capability to run -.Dq set user id -to another user -to -provide additional protection. -.Pp -Basically, -.Nm sccs -runs the command with the specified -.Ar flags -and -.Ar args . -Each argument is normally modified to be prepended with -.Dq Li SCCS/s. . -.Pp -Flags to be interpreted by the -.Nm sccs -program must be before the -.Ar command -argument. -Flags to be passed to the actual -.Li SCCS -program must come after the -.Ar command -argument. -These flags are specific to the command and -are discussed in the documentation for that command. -.Pp -Besides the usual -.Li SCCS -commands, -several -.Dq pseudo-commands -can be issued. -These are: -.Bl -tag -width deledit -.It Cm edit -Equivalent -to -.Dq Li get \-e . -.It Cm delget -Perform a delta on the named files and -then get new versions. -The new versions will have id keywords expanded, and -will not be editable. -The -.Fl m , -.Fl p , -.Fl r , -.Fl s , -and -.Fl y -flags will be passed to -.Nm delta , -and the -.Fl b, -.Fl c , -.Fl e , -.Fl i , -.Fl k , -.Fl l , -.Fl s , -.\" anybody who has a bad xterm which is almost anyone -and -.Fl x -flags will be passed to get. -.It Cm deledit -Equivalent -to -.Nm delget -except that the -.Nm get -phase includes the -.Fl e -flag. -This -option is useful for making a -.Em checkpoint -of your current editing phase. The same flags will be passed to delta -as described above, and -all the flags listed for -.om get -above except -.Fl e -and -.Fl k -are -passed to -.Nm edit . -.It Cm create -Creates -an -.Li SCCS -file , -taking -the initial contents from the file of the same name. -Any -flags to -.Nm admin -are accepted. If the creation is successful, -the files are renamed with a comma on the front. -These should be removed when you are convinced that the -.Li SCCS -files -have been created successfully. -.It Cm fix -Must -be followed by a -.Fl r -flag. -This command essentially removes the named delta, but -leaves you with a copy of the delta -with the changes that were in it. It -is useful for fixing small compiler bugs, etc. -Since it doesn't leave audit trails, it should be used carefully. -.It Cm clean -This routine removes everything from the current directory -that can be recreated from SCCS files. -It will not remove any files being edited. -If the -.Fl b -flag is given, branches are ignored in the determination of -whether they are being edited; this -is dangerous if you are keeping the branches in the -same directory. -.It Cm unedit -This -is the opposite of an -.Nm edit -or -a -.Dq Li get \-e . -It should be used with extreme caution, since -any changes you made since the get will be irretrievably lost. -.It Cm info -Gives a listing of all files being edited. -If the -.Fl b -flag -is given, branches (i.e., -.Li SID Ns \&\'s -with two or fewer components) -are ignored. If the -.Fl u -flag is given (with an optional argument) then -only files being edited by you (or the named user) are listed. -.It Cm check -Like -.Nm info -except that nothing is printed if nothing is being edited, and -a non-zero exit status is returned if anything is being edited. -The intent is to have this included in an -.Em install -entry in a makefile to insure that everything is included into the -.Li SCCS -file before a version is installed. -.It Cm tell -Gives a newline-separated list of the files being edited -on the standard output. Takes the -.Fl b -and -.Fl u -flags like -.Nm info -and -.Nm check . -.It Cm diffs -Gives a -.Nm diff -listing between the current version of the -program(s) you have out for editing and the versions in -.Li SCCS -format. -The -.Fl r , -.Fl c , -.Fl i , -.Fl x , -and -.Fl t -flags are passed to -.if n \{\ -. br -.\} -.Nm get ; -the -.Fl l , -.Fl s , -.Fl e , -.Fl f , -.Fl h , -and -.Fl b -options are passed to -.if n \{\ -. br -.\} -.Nm diff . -The -.Fl C -flag is passed to -.Nm diff -as -.Fl c . -.It Cm print -This command prints out verbose information -about the named files. -.Pp -.It Fl r -Runs -.Nm sccs -as the real user rather than as whatever effective user -.Nm sccs -is -.Dq Li set user id -to. -.It Fl d -Specifies a root directory for the -.Li SCCS -files. -The default is the current directory. -If environment variable -.Ev PROJECT -is set, -it will be used to determine the -.Fl d -flag. -.It Fl p -Defines the pathname of the directory in which the -.Li SCCS -files will be found; -.Dq Li SCCS -is the default. -The -.Fl p -flag -differs from the -.Fl d -flag -in that the -.Fl d -argument is prepended to the entire pathname and the -.Fl p -argument is inserted before the final component of the pathname. -For example, -.Dq Li sccs \-d/x \-py get a/b -will convert to -.Dq Li get /x/a/y/s.b . -The intent here is to create aliases such as -.Dq Li alias syssccs sccs -d/usr/src -which -will be used as -.Dq Li syssccs get cmd/who.c . -.Pp -Certain -commands (such as -.Nm admin ) -cannot be run -.Dq Li set user id -by all users, since this would allow anyone to change the authorizations. -These commands are always run as the real user. -.Sh EXAMPLES -To get a file for editing, -edit it, -and produce a new delta: -.Pp -.Dl sccs get \-e file.c -.Dl ex file.c -.Dl sccs delta file.c -.Pp -To get a file from another directory: -.Pp -.Dl sccs \-p/usr/src/sccs/s. get cc.c -.Pp -or -.Pp -.Dl sccs get /usr/src/sccs/s.cc.c -.Pp -To make a delta of a large number of files -in the current directory: -.Pp -.Dl sccs delta *.c -.Pp -To get a list of files being edited that are not on branches: -.Pp -.Dl sccs info \-b -.Pp -To delta everything being edited by you: -.Pp -.Dl sccs delta \`sccs tell \-u\` -.Pp -In a makefile, to get source files -from an -.Li SCCS -file if it does not already exist: -.Pp -.Dl SRCS = -.Dl $(SRCS): -.Dl \&\tsccs get $(REL) $@ -.Sh ENVIRONMENT -.Bl -tag -width Ar -.It Ev PROJECT -The PROJECT environment variable is checked by the -.Fl d -flag. If -it begins with a slash, it is taken directly; otherwise, -the home directory of a user of that name is -examined for a subdirectory -.Dq Li src -or -.Dq Li source . -If such a directory is found, it is used. -.El -.Sh SEE ALSO -.Xr what 1 -.Xr admin SCCS , -.Xr chghist SCCS , -.Xr comb SCCS , -.Xr delta SCCS , -.Xr get SCCS , -.Xr help SCCS , -.Xr prt SCCS , -.Xr rmdel SCCS , -.Xr sccsdiff SCCS , -.Rs -.%A Eric Allman -.%T "An Introduction to the Source Code Control System" -.Re -.Sh HISTORY -The -.Nm sccs -command -appeared in -.Bx 4.3 . -.Sh BUGS -It should be able to take directory arguments on pseudo-commands -like the -.Li SCCS -commands do. diff --git a/usr.bin/sccs/sccs.c b/usr.bin/sccs/sccs.c deleted file mode 100644 index 2dfd76d..0000000 --- a/usr.bin/sccs/sccs.c +++ /dev/null @@ -1,1621 +0,0 @@ -/* - * Copyright (c) 1980, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef lint -static char copyright[] = -"@(#) Copyright (c) 1980, 1993\n\ - The Regents of the University of California. All rights reserved.\n"; -#endif /* not lint */ - -#ifndef lint -static char sccsid[] = "@(#)sccs.c 8.1 (Berkeley) 6/6/93"; -#endif /* not lint */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "pathnames.h" - -/* -** SCCS.C -- human-oriented front end to the SCCS system. -** -** Without trying to add any functionality to speak of, this -** program tries to make SCCS a little more accessible to human -** types. The main thing it does is automatically put the -** string "SCCS/s." on the front of names. Also, it has a -** couple of things that are designed to shorten frequent -** combinations, e.g., "delget" which expands to a "delta" -** and a "get". -** -** This program can also function as a setuid front end. -** To do this, you should copy the source, renaming it to -** whatever you want, e.g., "syssccs". Change any defaults -** in the program (e.g., syssccs might default -d to -** "/usr/src/sys"). Then recompile and put the result -** as setuid to whomever you want. In this mode, sccs -** knows to not run setuid for certain programs in order -** to preserve security, and so forth. -** -** Usage: -** sccs [flags] command [args] -** -** Flags: -** -d represents a directory to search -** out of. It should be a full pathname -** for general usage. E.g., if is -** "/usr/src/sys", then a reference to the -** file "dev/bio.c" becomes a reference to -** "/usr/src/sys/dev/bio.c". -** -p prepends to the final component -** of the pathname. By default, this is -** "SCCS". For example, in the -d example -** above, the path then gets modified to -** "/usr/src/sys/dev/SCCS/s.bio.c". In -** more common usage (without the -d flag), -** "prog.c" would get modified to -** "SCCS/s.prog.c". In both cases, the -** "s." gets automatically prepended. -** -r run as the real user. -** -** Commands: -** admin, -** get, -** delta, -** rmdel, -** cdc, -** etc. Straight out of SCCS; only difference -** is that pathnames get modified as -** described above. -** enter Front end doing "sccs admin -i " -** create Macro for "enter" followed by "get". -** edit Macro for "get -e". -** unedit Removes a file being edited, knowing -** about p-files, etc. -** delget Macro for "delta" followed by "get". -** deledit Macro for "delta" followed by "get -e". -** branch Macro for "get -b -e", followed by "delta -** -s -n", followd by "get -e -t -g". -** diffs "diff" the specified version of files -** and the checked-out version. -** print Macro for "prs -e" followed by "get -p -m". -** tell List what files are being edited. -** info Print information about files being edited. -** clean Remove all files that can be -** regenerated from SCCS files. -** check Like info, but return exit status, for -** use in makefiles. -** fix Remove a top delta & reedit, but save -** the previous changes in that delta. -** -** Compilation Flags: -** UIDUSER -- determine who the user is by looking at the -** uid rather than the login name -- for machines -** where SCCS gets the user in this way. -** SCCSDIR -- if defined, forces the -d flag to take on -** this value. This is so that the setuid -** aspects of this program cannot be abused. -** This flag also disables the -p flag. -** SCCSPATH -- the default for the -p flag. -** MYNAME -- the title this program should print when it -** gives error messages. -** -** Compilation Instructions: -** cc -O -n -s sccs.c -** The flags listed above can be -D defined to simplify -** recompilation for variant versions. -** -** Author: -** Eric Allman, UCB/INGRES -** Copyright 1980 Regents of the University of California -*/ - - -/******************* Configuration Information ********************/ - -# ifndef SCCSPATH -# define SCCSPATH "SCCS" /* pathname in which to find s-files */ -# endif NOT SCCSPATH - -# ifndef MYNAME -# define MYNAME "sccs" /* name used for printing errors */ -# endif NOT MYNAME - -/**************** End of Configuration Information ****************/ - -typedef char bool; -# define TRUE 1 -# define FALSE 0 - -# define bitset(bit, word) ((bool) ((bit) & (word))) - -struct sccsprog -{ - char *sccsname; /* name of SCCS routine */ - short sccsoper; /* opcode, see below */ - short sccsflags; /* flags, see below */ - char *sccspath; /* pathname of binary implementing */ -}; - -/* values for sccsoper */ -# define PROG 0 /* call a program */ -# define CMACRO 1 /* command substitution macro */ -# define FIX 2 /* fix a delta */ -# define CLEAN 3 /* clean out recreatable files */ -# define UNEDIT 4 /* unedit a file */ -# define SHELL 5 /* call a shell file (like PROG) */ -# define DIFFS 6 /* diff between sccs & file out */ -# define DODIFF 7 /* internal call to diff program */ -# define ENTER 8 /* enter new files */ - -/* bits for sccsflags */ -# define NO_SDOT 0001 /* no s. on front of args */ -# define REALUSER 0002 /* protected (e.g., admin) */ - -/* modes for the "clean", "info", "check" ops */ -# define CLEANC 0 /* clean command */ -# define INFOC 1 /* info command */ -# define CHECKC 2 /* check command */ -# define TELLC 3 /* give list of files being edited */ - -/* -** Description of commands known to this program. -** First argument puts the command into a class. Second arg is -** info regarding treatment of this command. Third arg is a -** list of flags this command accepts from macros, etc. Fourth -** arg is the pathname of the implementing program, or the -** macro definition, or the arg to a sub-algorithm. -*/ - -struct sccsprog SccsProg[] = { - "admin", PROG, REALUSER, _PATH_SCCSADMIN, - "cdc", PROG, 0, _PATH_SCCSRMDEL, - "comb", PROG, 0, _PATH_SCCSCOMB, - "delta", PROG, 0, _PATH_SCCSDELTA, - "get", PROG, 0, _PATH_SCCSGET, - "help", PROG, NO_SDOT, _PATH_SCCSHELP, - "prs", PROG, 0, _PATH_SCCSPRS, - "prt", PROG, 0, _PATH_SCCSPRT, - "rmdel", PROG, REALUSER, _PATH_SCCSRMDEL, - "val", PROG, 0, _PATH_SCCSVAL, - "what", PROG, NO_SDOT, _PATH_SCCSWHAT, - "sccsdiff", SHELL, REALUSER, _PATH_SCCSDIFF, - "edit", CMACRO, NO_SDOT, "get -e", - "delget", CMACRO, NO_SDOT, "delta:mysrp/get:ixbeskcl -t", - "deledit", CMACRO, NO_SDOT, - "delta:mysrp -n/get:ixbskcl -e -t -g", - "fix", FIX, NO_SDOT, NULL, - "clean", CLEAN, REALUSER|NO_SDOT, - (char *) CLEANC, - "info", CLEAN, REALUSER|NO_SDOT, - (char *) INFOC, - "check", CLEAN, REALUSER|NO_SDOT, - (char *) CHECKC, - "tell", CLEAN, REALUSER|NO_SDOT, - (char *) TELLC, - "unedit", UNEDIT, NO_SDOT, NULL, - "diffs", DIFFS, NO_SDOT|REALUSER, - NULL, - "-diff", DODIFF, NO_SDOT|REALUSER, - _PATH_SCCSBDIFF, - "print", CMACRO, 0, "prs -e/get -p -m -s", - "branch", CMACRO, NO_SDOT, - "get:ixrc -e -b/delta: -s -n -ybranch-place-holder/get:pl -e -t -g", - "enter", ENTER, NO_SDOT, NULL, - "create", CMACRO, NO_SDOT, "enter/get:ixbeskcl -t", - NULL, -1, 0, NULL -}; - -/* one line from a p-file */ -struct pfile -{ - char *p_osid; /* old SID */ - char *p_nsid; /* new SID */ - char *p_user; /* user who did edit */ - char *p_date; /* date of get */ - char *p_time; /* time of get */ - char *p_aux; /* extra info at end */ -}; - -char *SccsPath = SCCSPATH; /* pathname of SCCS files */ -# ifdef SCCSDIR -char *SccsDir = SCCSDIR; /* directory to begin search from */ -# else -char *SccsDir = ""; -# endif -char MyName[] = MYNAME; /* name used in messages */ -int OutFile = -1; /* override output file for commands */ -bool RealUser; /* if set, running as real user */ -# ifdef DEBUG -bool Debug; /* turn on tracing */ -# endif -# ifndef V6 -extern char *getenv(); -# endif V6 - -char *gstrcat(), *strcat(); -char *gstrncat(), *strncat(); -char *gstrcpy(), *strcpy(); -#define FBUFSIZ BUFSIZ -#define PFILELG 120 - -main(argc, argv) - int argc; - char **argv; -{ - register char *p; - extern struct sccsprog *lookup(); - register int i; -# ifndef V6 -# ifndef SCCSDIR - register struct passwd *pw; - extern struct passwd *getpwnam(); - char buf[FBUFSIZ]; - - /* pull "SccsDir" out of the environment (possibly) */ - p = getenv("PROJECTDIR"); - if (p != NULL && p[0] != '\0') - { - if (p[0] == '/') - SccsDir = p; - else - { - pw = getpwnam(p); - if (pw == NULL) - { - usrerr("user %s does not exist", p); - exit(EX_USAGE); - } - gstrcpy(buf, pw->pw_dir, sizeof(buf)); - gstrcat(buf, "/src", sizeof(buf)); - if (access(buf, 0) < 0) - { - gstrcpy(buf, pw->pw_dir, sizeof(buf)); - gstrcat(buf, "/source", sizeof(buf)); - if (access(buf, 0) < 0) - { - usrerr("project %s has no source!", p); - exit(EX_USAGE); - } - } - SccsDir = buf; - } - } -# endif SCCSDIR -# endif V6 - - /* - ** Detect and decode flags intended for this program. - */ - - if (argc < 2) - { - fprintf(stderr, "Usage: %s [flags] command [flags]\n", MyName); - exit(EX_USAGE); - } - argv[argc] = NULL; - - if (lookup(argv[0]) == NULL) - { - while ((p = *++argv) != NULL) - { - if (*p != '-') - break; - switch (*++p) - { - case 'r': /* run as real user */ - setuid(getuid()); - RealUser++; - break; - -# ifndef SCCSDIR - case 'p': /* path of sccs files */ - SccsPath = ++p; - if (SccsPath[0] == '\0' && argv[1] != NULL) - SccsPath = *++argv; - break; - - case 'd': /* directory to search from */ - SccsDir = ++p; - if (SccsDir[0] == '\0' && argv[1] != NULL) - SccsDir = *++argv; - break; -# endif - -# ifdef DEBUG - case 'T': /* trace */ - Debug++; - break; -# endif - - default: - usrerr("unknown option -%s", p); - break; - } - } - if (SccsPath[0] == '\0') - SccsPath = "."; - } - - i = command(argv, FALSE, ""); - exit(i); -} - -/* -** COMMAND -- look up and perform a command -** -** This routine is the guts of this program. Given an -** argument vector, it looks up the "command" (argv[0]) -** in the configuration table and does the necessary stuff. -** -** Parameters: -** argv -- an argument vector to process. -** forkflag -- if set, fork before executing the command. -** editflag -- if set, only include flags listed in the -** sccsklets field of the command descriptor. -** arg0 -- a space-seperated list of arguments to insert -** before argv. -** -** Returns: -** zero -- command executed ok. -** else -- error status. -** -** Side Effects: -** none. -*/ - -command(argv, forkflag, arg0) - char **argv; - bool forkflag; - char *arg0; -{ - register struct sccsprog *cmd; - register char *p; - char buf[FBUFSIZ]; - extern struct sccsprog *lookup(); - char *nav[1000]; - char **np; - register char **ap; - register int i; - register char *q; - extern bool unedit(); - int rval = 0; - extern char *index(); - extern char *makefile(); - char *editchs; - extern char *tail(); - -# ifdef DEBUG - if (Debug) - { - printf("command:\n\t\"%s\"\n", arg0); - for (np = argv; *np != NULL; np++) - printf("\t\"%s\"\n", *np); - } -# endif - - /* - ** Copy arguments. - ** Copy from arg0 & if necessary at most one arg - ** from argv[0]. - */ - - np = ap = &nav[1]; - editchs = NULL; - for (p = arg0, q = buf; *p != '\0' && *p != '/'; ) - { - *np++ = q; - while (*p == ' ') - p++; - while (*p != ' ' && *p != '\0' && *p != '/' && *p != ':') - *q++ = *p++; - *q++ = '\0'; - if (*p == ':') - { - editchs = q; - while (*++p != '\0' && *p != '/' && *p != ' ') - *q++ = *p; - *q++ = '\0'; - } - } - *np = NULL; - if (*ap == NULL) - *np++ = *argv++; - - /* - ** Look up command. - ** At this point, *ap is the command name. - */ - - cmd = lookup(*ap); - if (cmd == NULL) - { - usrerr("Unknown command \"%s\"", *ap); - return (EX_USAGE); - } - - /* - ** Copy remaining arguments doing editing as appropriate. - */ - - for (; *argv != NULL; argv++) - { - p = *argv; - if (*p == '-') - { - if (p[1] == '\0' || editchs == NULL || index(editchs, p[1]) != NULL) - *np++ = p; - } - else - { - if (!bitset(NO_SDOT, cmd->sccsflags)) - p = makefile(p); - if (p != NULL) - *np++ = p; - } - } - *np = NULL; - - /* - ** Interpret operation associated with this command. - */ - - switch (cmd->sccsoper) - { - case SHELL: /* call a shell file */ - *ap = cmd->sccspath; - *--ap = "sh"; - rval = callprog(_PATH_BSHELL, cmd->sccsflags, ap, forkflag); - break; - - case PROG: /* call an sccs prog */ - rval = callprog(cmd->sccspath, cmd->sccsflags, ap, forkflag); - break; - - case CMACRO: /* command macro */ - /* step through & execute each part of the macro */ - for (p = cmd->sccspath; *p != '\0'; p++) - { - q = p; - while (*p != '\0' && *p != '/') - p++; - rval = command(&ap[1], *p != '\0', q); - if (rval != 0) - break; - } - break; - - case FIX: /* fix a delta */ - if (ap[1]==0 || strncmp(ap[1], "-r", 2)!=0) - { - usrerr("-r flag needed for fix command"); - rval = EX_USAGE; - break; - } - - /* get the version with all changes */ - rval = command(&ap[1], TRUE, "get -k"); - - /* now remove that version from the s-file */ - if (rval == 0) - rval = command(&ap[1], TRUE, "rmdel:r"); - - /* and edit the old version (but don't clobber new vers) */ - if (rval == 0) - rval = command(&ap[2], FALSE, "get -e -g"); - break; - - case CLEAN: - rval = clean((int) cmd->sccspath, ap); - break; - - case UNEDIT: - for (argv = np = &ap[1]; *argv != NULL; argv++) - { - if (unedit(*argv)) - *np++ = *argv; - } - *np = NULL; - - /* get all the files that we unedited successfully */ - if (np > &ap[1]) - rval = command(&ap[1], FALSE, "get"); - break; - - case DIFFS: /* diff between s-file & edit file */ - /* find the end of the flag arguments */ - for (np = &ap[1]; *np != NULL && **np == '-'; np++) - continue; - argv = np; - - /* for each file, do the diff */ - p = argv[1]; - while (*np != NULL) - { - /* messy, but we need a null terminated argv */ - *argv = *np++; - argv[1] = NULL; - i = dodiff(ap, tail(*argv)); - if (rval == 0) - rval = i; - argv[1] = p; - } - break; - - case DODIFF: /* internal diff call */ - setuid(getuid()); - for (np = ap; *np != NULL; np++) - { - if ((*np)[0] == '-' && (*np)[1] == 'C') - (*np)[1] = 'c'; - } - - /* insert "-" argument */ - np[1] = NULL; - np[0] = np[-1]; - np[-1] = "-"; - - /* execute the diff program of choice */ -# ifndef V6 - execvp("diff", ap); -# endif - execv(cmd->sccspath, argv); - syserr("cannot exec %s", cmd->sccspath); - exit(EX_OSERR); - - case ENTER: /* enter new sccs files */ - /* skip over flag arguments */ - for (np = &ap[1]; *np != NULL && **np == '-'; np++) - continue; - argv = np; - - /* do an admin for each file */ - p = argv[1]; - while (*np != NULL) - { - printf("\n%s:\n", *np); - strcpy(buf, "-i"); - gstrcat(buf, *np, sizeof(buf)); - ap[0] = buf; - argv[0] = tail(*np); - argv[1] = NULL; - rval = command(ap, TRUE, "admin"); - argv[1] = p; - if (rval == 0) - { - strcpy(buf, ","); - gstrcat(buf, tail(*np), sizeof(buf)); - if (link(*np, buf) >= 0) - unlink(*np); - } - np++; - } - break; - - default: - syserr("oper %d", cmd->sccsoper); - exit(EX_SOFTWARE); - } -# ifdef DEBUG - if (Debug) - printf("command: rval=%d\n", rval); -# endif - return (rval); -} - -/* -** LOOKUP -- look up an SCCS command name. -** -** Parameters: -** name -- the name of the command to look up. -** -** Returns: -** ptr to command descriptor for this command. -** NULL if no such entry. -** -** Side Effects: -** none. -*/ - -struct sccsprog * -lookup(name) - char *name; -{ - register struct sccsprog *cmd; - - for (cmd = SccsProg; cmd->sccsname != NULL; cmd++) - { - if (strcmp(cmd->sccsname, name) == 0) - return (cmd); - } - return (NULL); -} - -/* -** CALLPROG -- call a program -** -** Used to call the SCCS programs. -** -** Parameters: -** progpath -- pathname of the program to call. -** flags -- status flags from the command descriptors. -** argv -- an argument vector to pass to the program. -** forkflag -- if true, fork before calling, else just -** exec. -** -** Returns: -** The exit status of the program. -** Nothing if forkflag == FALSE. -** -** Side Effects: -** Can exit if forkflag == FALSE. -*/ - -callprog(progpath, flags, argv, forkflag) - char *progpath; - short flags; - char **argv; - bool forkflag; -{ - register int i; - register int wpid; - auto int st; - register int sigcode; - register int coredumped; - register const char *sigmsg; - char sigmsgbuf[10+1]; /* "Signal 127" + terminating '\0' */ - -# ifdef DEBUG - if (Debug) - { - printf("callprog:\n"); - for (i = 0; argv[i] != NULL; i++) - printf("\t\"%s\"\n", argv[i]); - } -# endif - - if (*argv == NULL) - return (-1); - - /* - ** Fork if appropriate. - */ - - if (forkflag) - { -# ifdef DEBUG - if (Debug) - printf("Forking\n"); -# endif - i = fork(); - if (i < 0) - { - syserr("cannot fork"); - exit(EX_OSERR); - } - else if (i > 0) - { - while ((wpid = wait(&st)) != -1 && wpid != i) - ; - if ((sigcode = st & 0377) == 0) - st = (st >> 8) & 0377; - else - { - coredumped = sigcode & 0200; - sigcode &= 0177; - if (sigcode != SIGINT && sigcode != SIGPIPE) - { - if (sigcode < NSIG) - sigmsg = sys_siglist[sigcode]; - else - { - sprintf(sigmsgbuf, "Signal %d", - sigcode); - sigmsg = sigmsgbuf; - } - fprintf(stderr, "sccs: %s: %s%s", argv[0], - sigmsg, - coredumped ? " - core dumped": ""); - } - st = EX_SOFTWARE; - } - if (OutFile >= 0) - { - close(OutFile); - OutFile = -1; - } - return (st); - } - } - else if (OutFile >= 0) - { - syserr("callprog: setting stdout w/o forking"); - exit(EX_SOFTWARE); - } - - /* set protection as appropriate */ - if (bitset(REALUSER, flags)) - setuid(getuid()); - - /* change standard input & output if needed */ - if (OutFile >= 0) - { - close(1); - dup(OutFile); - close(OutFile); - } - - /* call real SCCS program */ - execv(progpath, argv); - syserr("cannot execute %s", progpath); - exit(EX_UNAVAILABLE); - /*NOTREACHED*/ -} - -/* -** MAKEFILE -- make filename of SCCS file -** -** If the name passed is already the name of an SCCS file, -** just return it. Otherwise, munge the name into the name -** of the actual SCCS file. -** -** There are cases when it is not clear what you want to -** do. For example, if SccsPath is an absolute pathname -** and the name given is also an absolute pathname, we go -** for SccsPath (& only use the last component of the name -** passed) -- this is important for security reasons (if -** sccs is being used as a setuid front end), but not -** particularly intuitive. -** -** Parameters: -** name -- the file name to be munged. -** -** Returns: -** The pathname of the sccs file. -** NULL on error. -** -** Side Effects: -** none. -*/ - -char * -makefile(name) - char *name; -{ - register char *p; - char buf[3*FBUFSIZ]; - extern char *malloc(); - extern char *rindex(); - extern bool safepath(); - extern bool isdir(); - register char *q; - - p = rindex(name, '/'); - if (p == NULL) - p = name; - else - p++; - - /* - ** Check to see that the path is "safe", i.e., that we - ** are not letting some nasty person use the setuid part - ** of this program to look at or munge some presumably - ** hidden files. - */ - - if (SccsDir[0] == '/' && !safepath(name)) - return (NULL); - - /* - ** Create the base pathname. - */ - - /* first the directory part */ - if (SccsDir[0] != '\0' && name[0] != '/' && strncmp(name, "./", 2) != 0) - { - gstrcpy(buf, SccsDir, sizeof(buf)); - gstrcat(buf, "/", sizeof(buf)); - } - else - gstrcpy(buf, "", sizeof(buf)); - - /* then the head of the pathname */ - gstrncat(buf, name, p - name, sizeof(buf)); - q = &buf[strlen(buf)]; - - /* now copy the final part of the name, in case useful */ - gstrcpy(q, p, sizeof(buf)); - - /* so is it useful? */ - if (strncmp(p, "s.", 2) != 0 && !isdir(buf)) - { - /* sorry, no; copy the SCCS pathname & the "s." */ - gstrcpy(q, SccsPath, sizeof(buf)); - gstrcat(buf, "/s.", sizeof(buf)); - - /* and now the end of the name */ - gstrcat(buf, p, sizeof(buf)); - } - - /* if i haven't changed it, why did I do all this? */ - if (strcmp(buf, name) == 0) - p = name; - else - { - /* but if I have, squirrel it away */ - p = malloc(strlen(buf) + 1); - if (p == NULL) - { - perror("Sccs: no mem"); - exit(EX_OSERR); - } - strcpy(p, buf); - } - - return (p); -} - -/* -** ISDIR -- return true if the argument is a directory. -** -** Parameters: -** name -- the pathname of the file to check. -** -** Returns: -** TRUE if 'name' is a directory, FALSE otherwise. -** -** Side Effects: -** none. -*/ - -bool -isdir(name) - char *name; -{ - struct stat stbuf; - - return (stat(name, &stbuf) >= 0 && (stbuf.st_mode & S_IFMT) == S_IFDIR); -} - -/* -** SAFEPATH -- determine whether a pathname is "safe" -** -** "Safe" pathnames only allow you to get deeper into the -** directory structure, i.e., full pathnames and ".." are -** not allowed. -** -** Parameters: -** p -- the name to check. -** -** Returns: -** TRUE -- if the path is safe. -** FALSE -- if the path is not safe. -** -** Side Effects: -** Prints a message if the path is not safe. -*/ - -bool -safepath(p) - register char *p; -{ - extern char *index(); - - if (*p != '/') - { - while (strncmp(p, "../", 3) != 0 && strcmp(p, "..") != 0) - { - p = index(p, '/'); - if (p == NULL) - return (TRUE); - p++; - } - } - - printf("You may not use full pathnames or \"..\"\n"); - return (FALSE); -} - -/* -** CLEAN -- clean out recreatable files -** -** Any file for which an "s." file exists but no "p." file -** exists in the current directory is purged. -** -** Parameters: -** mode -- tells whether this came from a "clean", "info", or -** "check" command. -** argv -- the rest of the argument vector. -** -** Returns: -** none. -** -** Side Effects: -** Removes files in the current directory. -** Prints information regarding files being edited. -** Exits if a "check" command. -*/ - -clean(mode, argv) - int mode; - char **argv; -{ - struct direct *dir; - char buf[FBUFSIZ]; - char *bufend; - register DIR *dirp; - register char *basefile; - bool gotedit; - bool gotpfent; - FILE *pfp; - bool nobranch = FALSE; - extern struct pfile *getpfent(); - register struct pfile *pf; - register char **ap; - extern char *username(); - char *usernm = NULL; - char *subdir = NULL; - char *cmdname; - - /* - ** Process the argv - */ - - cmdname = *argv; - for (ap = argv; *++ap != NULL; ) - { - if (**ap == '-') - { - /* we have a flag */ - switch ((*ap)[1]) - { - case 'b': - nobranch = TRUE; - break; - - case 'u': - if ((*ap)[2] != '\0') - usernm = &(*ap)[2]; - else if (ap[1] != NULL && ap[1][0] != '-') - usernm = *++ap; - else - usernm = username(); - break; - } - } - else - { - if (subdir != NULL) - usrerr("too many args"); - else - subdir = *ap; - } - } - - /* - ** Find and open the SCCS directory. - */ - - gstrcpy(buf, SccsDir, sizeof(buf)); - if (buf[0] != '\0') - gstrcat(buf, "/", sizeof(buf)); - if (subdir != NULL) - { - gstrcat(buf, subdir, sizeof(buf)); - gstrcat(buf, "/", sizeof(buf)); - } - gstrcat(buf, SccsPath, sizeof(buf)); - bufend = &buf[strlen(buf)]; - - dirp = opendir(buf); - if (dirp == NULL) - { - usrerr("cannot open %s", buf); - return (EX_NOINPUT); - } - - /* - ** Scan the SCCS directory looking for s. files. - ** gotedit tells whether we have tried to clean any - ** files that are being edited. - */ - - gotedit = FALSE; - while (dir = readdir(dirp)) { - if (strncmp(dir->d_name, "s.", 2) != 0) - continue; - - /* got an s. file -- see if the p. file exists */ - gstrcpy(bufend, "/p.", sizeof(buf)); - basefile = bufend + 3; - gstrcpy(basefile, &dir->d_name[2], sizeof(buf)); - - /* - ** open and scan the p-file. - ** 'gotpfent' tells if we have found a valid p-file - ** entry. - */ - - pfp = fopen(buf, "r"); - gotpfent = FALSE; - if (pfp != NULL) - { - /* the file exists -- report it's contents */ - while ((pf = getpfent(pfp)) != NULL) - { - if (nobranch && isbranch(pf->p_nsid)) - continue; - if (usernm != NULL && strcmp(usernm, pf->p_user) != 0 && mode != CLEANC) - continue; - gotedit = TRUE; - gotpfent = TRUE; - if (mode == TELLC) - { - printf("%s\n", basefile); - break; - } - printf("%12s: being edited: ", basefile); - putpfent(pf, stdout); - } - fclose(pfp); - } - - /* the s. file exists and no p. file exists -- unlink the g-file */ - if (mode == CLEANC && !gotpfent) - { - char unlinkbuf[FBUFSIZ]; - gstrcpy(unlinkbuf, &dir->d_name[2], sizeof(unlinkbuf)); - unlink(unlinkbuf); - } - } - - /* cleanup & report results */ - closedir(dirp); - if (!gotedit && mode == INFOC) - { - printf("Nothing being edited"); - if (nobranch) - printf(" (on trunk)"); - if (usernm == NULL) - printf("\n"); - else - printf(" by %s\n", usernm); - } - if (mode == CHECKC) - exit(gotedit); - return (EX_OK); -} - -/* -** ISBRANCH -- is the SID a branch? -** -** Parameters: -** sid -- the sid to check. -** -** Returns: -** TRUE if the sid represents a branch. -** FALSE otherwise. -** -** Side Effects: -** none. -*/ - -isbranch(sid) - char *sid; -{ - register char *p; - int dots; - - dots = 0; - for (p = sid; *p != '\0'; p++) - { - if (*p == '.') - dots++; - if (dots > 1) - return (TRUE); - } - return (FALSE); -} - -/* -** UNEDIT -- unedit a file -** -** Checks to see that the current user is actually editting -** the file and arranges that s/he is not editting it. -** -** Parameters: -** fn -- the name of the file to be unedited. -** -** Returns: -** TRUE -- if the file was successfully unedited. -** FALSE -- if the file was not unedited for some -** reason. -** -** Side Effects: -** fn is removed -** entries are removed from pfile. -*/ - -bool -unedit(fn) - char *fn; -{ - register FILE *pfp; - char *cp, *pfn; - static char tfn[] = _PATH_TMP; - FILE *tfp; - register char *q; - bool delete = FALSE; - bool others = FALSE; - char *myname; - extern char *username(); - struct pfile *pent; - extern struct pfile *getpfent(); - char buf[PFILELG]; - extern char *makefile(), *rindex(), *tail(); - - /* make "s." filename & find the trailing component */ - pfn = makefile(fn); - if (pfn == NULL) - return (FALSE); - q = rindex(pfn, '/'); - if (q == NULL) - q = &pfn[-1]; - if (q[1] != 's' || q[2] != '.') - { - usrerr("bad file name \"%s\"", fn); - return (FALSE); - } - - /* turn "s." into "p." & try to open it */ - *++q = 'p'; - - pfp = fopen(pfn, "r"); - if (pfp == NULL) - { - printf("%12s: not being edited\n", fn); - return (FALSE); - } - - /* create temp file for editing p-file */ - mktemp(tfn); - tfp = fopen(tfn, "w"); - if (tfp == NULL) - { - usrerr("cannot create \"%s\"", tfn); - exit(EX_OSERR); - } - - /* figure out who I am */ - myname = username(); - - /* - ** Copy p-file to temp file, doing deletions as needed. - */ - - while ((pent = getpfent(pfp)) != NULL) - { - if (strcmp(pent->p_user, myname) == 0) - { - /* a match */ - delete++; - } - else - { - /* output it again */ - putpfent(pent, tfp); - others++; - } - } - - /* - * Before changing anything, make sure we can remove - * the file in question (assuming it exists). - */ - if (delete) { - extern int errno; - - cp = tail(fn); - errno = 0; - if (access(cp, 0) < 0 && errno != ENOENT) - goto bad; - if (errno == 0) - /* - * This is wrong, but the rest of the program - * has built in assumptions about "." as well, - * so why make unedit a special case? - */ - if (access(".", 2) < 0) { - bad: - printf("%12s: can't remove\n", cp); - fclose(tfp); - fclose(pfp); - unlink(tfn); - return (FALSE); - } - } - /* do final cleanup */ - if (others) - { - /* copy it back (perhaps it should be linked?) */ - if (freopen(tfn, "r", tfp) == NULL) - { - syserr("cannot reopen \"%s\"", tfn); - exit(EX_OSERR); - } - if (freopen(pfn, "w", pfp) == NULL) - { - usrerr("cannot create \"%s\"", pfn); - return (FALSE); - } - while (fgets(buf, sizeof buf, tfp) != NULL) - fputs(buf, pfp); - } - else - { - /* it's empty -- remove it */ - unlink(pfn); - } - fclose(tfp); - fclose(pfp); - unlink(tfn); - - /* actually remove the g-file */ - if (delete) - { - /* - * Since we've checked above, we can - * use the return from unlink to - * determine if the file existed or not. - */ - if (unlink(cp) >= 0) - printf("%12s: removed\n", cp); - return (TRUE); - } - else - { - printf("%12s: not being edited by you\n", fn); - return (FALSE); - } -} - -/* -** DODIFF -- diff an s-file against a g-file -** -** Parameters: -** getv -- argv for the 'get' command. -** gfile -- name of the g-file to diff against. -** -** Returns: -** Result of get. -** -** Side Effects: -** none. -*/ - -dodiff(getv, gfile) - char **getv; - char *gfile; -{ - int pipev[2]; - int rval; - register int i; - register int pid; - auto int st; - extern int errno; - sig_t osig; - - printf("\n------- %s -------\n", gfile); - fflush(stdout); - - /* create context for diff to run in */ - if (pipe(pipev) < 0) - { - syserr("dodiff: pipe failed"); - exit(EX_OSERR); - } - if ((pid = fork()) < 0) - { - syserr("dodiff: fork failed"); - exit(EX_OSERR); - } - else if (pid > 0) - { - /* in parent; run get */ - OutFile = pipev[1]; - close(pipev[0]); - rval = command(&getv[1], TRUE, "get:rcixt -s -k -p"); - osig = signal(SIGINT, SIG_IGN); - while (((i = wait(&st)) >= 0 && i != pid) || errno == EINTR) - errno = 0; - signal(SIGINT, osig); - /* ignore result of diff */ - } - else - { - /* in child, run diff */ - if (close(pipev[1]) < 0 || close(0) < 0 || - dup(pipev[0]) != 0 || close(pipev[0]) < 0) - { - syserr("dodiff: magic failed"); - exit(EX_OSERR); - } - command(&getv[1], FALSE, "-diff:elsfhbC"); - } - return (rval); -} - -/* -** TAIL -- return tail of filename. -** -** Parameters: -** fn -- the filename. -** -** Returns: -** a pointer to the tail of the filename; e.g., given -** "cmd/ls.c", "ls.c" is returned. -** -** Side Effects: -** none. -*/ - -char * -tail(fn) - register char *fn; -{ - register char *p; - - for (p = fn; *p != 0; p++) - if (*p == '/' && p[1] != '\0' && p[1] != '/') - fn = &p[1]; - return (fn); -} - -/* -** GETPFENT -- get an entry from the p-file -** -** Parameters: -** pfp -- p-file file pointer -** -** Returns: -** pointer to p-file struct for next entry -** NULL on EOF or error -** -** Side Effects: -** Each call wipes out results of previous call. -*/ - -struct pfile * -getpfent(pfp) - FILE *pfp; -{ - static struct pfile ent; - static char buf[PFILELG]; - register char *p; - extern char *nextfield(); - - if (fgets(buf, sizeof buf, pfp) == NULL) - return (NULL); - - ent.p_osid = p = buf; - ent.p_nsid = p = nextfield(p); - ent.p_user = p = nextfield(p); - ent.p_date = p = nextfield(p); - ent.p_time = p = nextfield(p); - ent.p_aux = p = nextfield(p); - - return (&ent); -} - - -char * -nextfield(p) - register char *p; -{ - if (p == NULL || *p == '\0') - return (NULL); - while (*p != ' ' && *p != '\n' && *p != '\0') - p++; - if (*p == '\n' || *p == '\0') - { - *p = '\0'; - return (NULL); - } - *p++ = '\0'; - return (p); -} - /* -** PUTPFENT -- output a p-file entry to a file -** -** Parameters: -** pf -- the p-file entry -** f -- the file to put it on. -** -** Returns: -** none. -** -** Side Effects: -** pf is written onto file f. -*/ - -putpfent(pf, f) - register struct pfile *pf; - register FILE *f; -{ - fprintf(f, "%s %s %s %s %s", pf->p_osid, pf->p_nsid, - pf->p_user, pf->p_date, pf->p_time); - if (pf->p_aux != NULL) - fprintf(f, " %s", pf->p_aux); - else - fprintf(f, "\n"); -} - -/* -** USRERR -- issue user-level error -** -** Parameters: -** f -- format string. -** p1-p3 -- parameters to a printf. -** -** Returns: -** -1 -** -** Side Effects: -** none. -*/ - -/*VARARGS1*/ -usrerr(f, p1, p2, p3) - char *f; -{ - fprintf(stderr, "\n%s: ", MyName); - fprintf(stderr, f, p1, p2, p3); - fprintf(stderr, "\n"); - - return (-1); -} - -/* -** SYSERR -- print system-generated error. -** -** Parameters: -** f -- format string to a printf. -** p1, p2, p3 -- parameters to f. -** -** Returns: -** never. -** -** Side Effects: -** none. -*/ - -/*VARARGS1*/ -syserr(f, p1, p2, p3) - char *f; -{ - extern int errno; - - fprintf(stderr, "\n%s SYSERR: ", MyName); - fprintf(stderr, f, p1, p2, p3); - fprintf(stderr, "\n"); - if (errno == 0) - exit(EX_SOFTWARE); - else - { - perror(NULL); - exit(EX_OSERR); - } -} - /* -** USERNAME -- return name of the current user -** -** Parameters: -** none -** -** Returns: -** name of current user -** -** Side Effects: -** none -*/ - -char * -username() -{ -# ifdef UIDUSER - extern struct passwd *getpwuid(); - register struct passwd *pw; - - pw = getpwuid(getuid()); - if (pw == NULL) - { - syserr("who are you? (uid=%d)", getuid()); - exit(EX_OSERR); - } - return (pw->pw_name); -# else - extern char *getlogin(); - register char *p; - - p = getenv("USER"); - if (p == NULL || p[0] == '\0') - p = getlogin(); - return (p); -# endif UIDUSER -} - -/* -** Guarded string manipulation routines; the last argument -** is the length of the buffer into which the strcpy or strcat -** is to be done. -*/ -char *gstrcat(to, from, length) - char *to, *from; - int length; -{ - if (strlen(from) + strlen(to) >= length) { - gstrbotch(to, from); - } - return(strcat(to, from)); -} - -char *gstrncat(to, from, n, length) - char *to, *from; - int n; - int length; -{ - if (n + strlen(to) >= length) { - gstrbotch(to, from); - } - return(strncat(to, from, n)); -} - -char *gstrcpy(to, from, length) - char *to, *from; - int length; -{ - if (strlen(from) >= length) { - gstrbotch(from, (char *)0); - } - return(strcpy(to, from)); -} -gstrbotch(str1, str2) - char *str1, *str2; -{ - usrerr("Filename(s) too long: %s %s", str1, str2); -} -- cgit v1.1