summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--contrib/cvs/README.VMS159
-rw-r--r--contrib/cvs/contrib/ccvs-rsh.pl97
-rw-r--r--contrib/cvs/contrib/clmerge.pl152
-rw-r--r--contrib/cvs/contrib/cln_hist.pl91
-rw-r--r--contrib/cvs/contrib/commit_prep.pl215
-rw-r--r--contrib/cvs/contrib/cvs_acls.pl141
-rw-r--r--contrib/cvs/contrib/listen2.c107
-rw-r--r--contrib/cvs/contrib/listen2.mak188
-rw-r--r--contrib/cvs/contrib/log.pl182
-rw-r--r--contrib/cvs/contrib/log_accum.pl576
-rw-r--r--contrib/cvs/contrib/mfpipe.pl85
-rw-r--r--contrib/cvs/contrib/pvcs_to_rcs439
-rw-r--r--contrib/cvs/contrib/rcslock.pl235
-rw-r--r--contrib/cvs/contrib/sccs2rcs.csh280
-rw-r--r--contrib/cvs/doc/DIFFUTILS-2.7-BUG263
-rw-r--r--contrib/cvs/lib/getwd.c33
-rw-r--r--contrib/cvs/lib/strdup.c39
-rw-r--r--contrib/cvs/lib/strippath.c80
-rw-r--r--contrib/cvs/lib/vasprintf.c175
-rw-r--r--contrib/cvs/src/NOTES60
-rw-r--r--contrib/cvs/src/README-rm-add31
-rwxr-xr-xcontrib/cvs/src/cvsbug.sh526
-rw-r--r--contrib/cvs/src/rtag.c764
-rw-r--r--contrib/cvs/stamp-h.in1
-rw-r--r--contrib/cvs/tools/pcl-cvs/ChangeLog922
-rw-r--r--contrib/cvs/tools/pcl-cvs/ChangeLog.woods383
-rw-r--r--contrib/cvs/tools/pcl-cvs/INSTALL94
-rw-r--r--contrib/cvs/tools/pcl-cvs/Makefile.in238
-rw-r--r--contrib/cvs/tools/pcl-cvs/NEWS149
-rw-r--r--contrib/cvs/tools/pcl-cvs/README25
-rw-r--r--contrib/cvs/tools/pcl-cvs/ToDo44
-rw-r--r--contrib/cvs/tools/pcl-cvs/pcl-cvs-lucid.el134
-rw-r--r--contrib/cvs/tools/pcl-cvs/pcl-cvs-startup.el17
-rw-r--r--contrib/cvs/tools/pcl-cvs/pcl-cvs.el3461
-rw-r--r--contrib/cvs/tools/pcl-cvs/pcl-cvs.texinfo1565
-rw-r--r--gnu/usr.bin/cvs/BUGS248
-rw-r--r--gnu/usr.bin/cvs/FAQ10006
-rw-r--r--gnu/usr.bin/cvs/INSTALL356
-rw-r--r--gnu/usr.bin/cvs/MINOR-BUGS60
-rw-r--r--gnu/usr.bin/cvs/Makefile3
-rw-r--r--gnu/usr.bin/cvs/NEWS863
-rw-r--r--gnu/usr.bin/cvs/PROJECTS59
-rw-r--r--gnu/usr.bin/cvs/README207
-rw-r--r--gnu/usr.bin/cvs/TODO474
-rw-r--r--gnu/usr.bin/cvs/contrib/README90
-rw-r--r--gnu/usr.bin/cvs/contrib/ccvs-rsh.pl97
-rw-r--r--gnu/usr.bin/cvs/contrib/clmerge156
-rw-r--r--gnu/usr.bin/cvs/contrib/clmerge.pl152
-rw-r--r--gnu/usr.bin/cvs/contrib/cln_hist.pl92
-rw-r--r--gnu/usr.bin/cvs/contrib/commit_prep.pl216
-rw-r--r--gnu/usr.bin/cvs/contrib/cvs-format.el81
-rw-r--r--gnu/usr.bin/cvs/contrib/cvs_acls.pl143
-rw-r--r--gnu/usr.bin/cvs/contrib/cvscheck84
-rw-r--r--gnu/usr.bin/cvs/contrib/cvscheck.man53
-rw-r--r--gnu/usr.bin/cvs/contrib/cvscheck.sh84
-rw-r--r--gnu/usr.bin/cvs/contrib/cvshelp.man562
-rw-r--r--gnu/usr.bin/cvs/contrib/descend116
-rw-r--r--gnu/usr.bin/cvs/contrib/descend.man115
-rw-r--r--gnu/usr.bin/cvs/contrib/descend.sh116
-rw-r--r--gnu/usr.bin/cvs/contrib/dirfns481
-rw-r--r--gnu/usr.bin/cvs/contrib/dirfns.shar481
-rw-r--r--gnu/usr.bin/cvs/contrib/easy-import.perl365
-rw-r--r--gnu/usr.bin/cvs/contrib/intro.doc112
-rw-r--r--gnu/usr.bin/cvs/contrib/log.pl169
-rw-r--r--gnu/usr.bin/cvs/contrib/log_accum.pl496
-rw-r--r--gnu/usr.bin/cvs/contrib/mfpipe.pl88
-rw-r--r--gnu/usr.bin/cvs/contrib/pcl-cvs/ChangeLog774
-rw-r--r--gnu/usr.bin/cvs/contrib/pcl-cvs/INSTALL89
-rw-r--r--gnu/usr.bin/cvs/contrib/pcl-cvs/Makefile83
-rw-r--r--gnu/usr.bin/cvs/contrib/pcl-cvs/NEWS113
-rw-r--r--gnu/usr.bin/cvs/contrib/pcl-cvs/README29
-rw-r--r--gnu/usr.bin/cvs/contrib/pcl-cvs/compile-all.el52
-rw-r--r--gnu/usr.bin/cvs/contrib/pcl-cvs/cookie.el884
-rw-r--r--gnu/usr.bin/cvs/contrib/pcl-cvs/elib-dll-debug.el298
-rw-r--r--gnu/usr.bin/cvs/contrib/pcl-cvs/elib-dll.el386
-rw-r--r--gnu/usr.bin/cvs/contrib/pcl-cvs/elib-node.el89
-rw-r--r--gnu/usr.bin/cvs/contrib/pcl-cvs/pcl-cvs-lucid.el133
-rw-r--r--gnu/usr.bin/cvs/contrib/pcl-cvs/pcl-cvs-startup.el14
-rw-r--r--gnu/usr.bin/cvs/contrib/pcl-cvs/pcl-cvs.el2493
-rw-r--r--gnu/usr.bin/cvs/contrib/pcl-cvs/pcl-cvs.texinfo1744
-rw-r--r--gnu/usr.bin/cvs/contrib/rcs-to-cvs184
-rw-r--r--gnu/usr.bin/cvs/contrib/rcs-to-cvs.sh185
-rw-r--r--gnu/usr.bin/cvs/contrib/rcs2log326
-rw-r--r--gnu/usr.bin/cvs/contrib/rcs2log.sh592
-rw-r--r--gnu/usr.bin/cvs/contrib/rcs2sccs143
-rw-r--r--gnu/usr.bin/cvs/contrib/rcs2sccs.sh143
-rw-r--r--gnu/usr.bin/cvs/contrib/rcslock.pl235
-rw-r--r--gnu/usr.bin/cvs/contrib/sccs2rcs277
-rw-r--r--gnu/usr.bin/cvs/contrib/sccs2rcs.csh277
-rw-r--r--gnu/usr.bin/cvs/cvs/ChangeLog3205
-rw-r--r--gnu/usr.bin/cvs/cvs/Makefile18
-rw-r--r--gnu/usr.bin/cvs/cvs/NOTES60
-rw-r--r--gnu/usr.bin/cvs/cvs/README-rm-add48
-rw-r--r--gnu/usr.bin/cvs/cvs/add.c539
-rw-r--r--gnu/usr.bin/cvs/cvs/admin.c179
-rw-r--r--gnu/usr.bin/cvs/cvs/checkin.c204
-rw-r--r--gnu/usr.bin/cvs/cvs/checkout.c874
-rw-r--r--gnu/usr.bin/cvs/cvs/classify.c504
-rw-r--r--gnu/usr.bin/cvs/cvs/client.c3542
-rw-r--r--gnu/usr.bin/cvs/cvs/client.h163
-rw-r--r--gnu/usr.bin/cvs/cvs/commit.c1834
-rw-r--r--gnu/usr.bin/cvs/cvs/convert.sh28
-rw-r--r--gnu/usr.bin/cvs/cvs/create_adm.c144
-rw-r--r--gnu/usr.bin/cvs/cvs/cvs.12185
-rw-r--r--gnu/usr.bin/cvs/cvs/cvs.5367
-rw-r--r--gnu/usr.bin/cvs/cvs/cvs.h570
-rw-r--r--gnu/usr.bin/cvs/cvs/cvsbug.sh533
-rw-r--r--gnu/usr.bin/cvs/cvs/cvsrc.c151
-rw-r--r--gnu/usr.bin/cvs/cvs/diff.c633
-rw-r--r--gnu/usr.bin/cvs/cvs/entries.c555
-rw-r--r--gnu/usr.bin/cvs/cvs/expand_path.c139
-rw-r--r--gnu/usr.bin/cvs/cvs/find_names.c275
-rw-r--r--gnu/usr.bin/cvs/cvs/history.c1489
-rw-r--r--gnu/usr.bin/cvs/cvs/ignore.c286
-rw-r--r--gnu/usr.bin/cvs/cvs/import.c1181
-rw-r--r--gnu/usr.bin/cvs/cvs/lock.c608
-rw-r--r--gnu/usr.bin/cvs/cvs/log.c178
-rw-r--r--gnu/usr.bin/cvs/cvs/login.c287
-rw-r--r--gnu/usr.bin/cvs/cvs/logmsg.c486
-rw-r--r--gnu/usr.bin/cvs/cvs/main.c769
-rw-r--r--gnu/usr.bin/cvs/cvs/modules.c884
-rw-r--r--gnu/usr.bin/cvs/cvs/no_diff.c135
-rw-r--r--gnu/usr.bin/cvs/cvs/options.h286
-rw-r--r--gnu/usr.bin/cvs/cvs/parseinfo.c171
-rw-r--r--gnu/usr.bin/cvs/cvs/patch.c615
-rw-r--r--gnu/usr.bin/cvs/cvs/patchlevel.h1
-rw-r--r--gnu/usr.bin/cvs/cvs/rcs.c1726
-rw-r--r--gnu/usr.bin/cvs/cvs/rcs.h107
-rw-r--r--gnu/usr.bin/cvs/cvs/rcscmds.c102
-rw-r--r--gnu/usr.bin/cvs/cvs/recurse.c646
-rw-r--r--gnu/usr.bin/cvs/cvs/release.c259
-rw-r--r--gnu/usr.bin/cvs/cvs/remove.c213
-rw-r--r--gnu/usr.bin/cvs/cvs/repos.c147
-rw-r--r--gnu/usr.bin/cvs/cvs/root.c182
-rw-r--r--gnu/usr.bin/cvs/cvs/rtag.c692
-rw-r--r--gnu/usr.bin/cvs/cvs/sanity.el18
-rw-r--r--gnu/usr.bin/cvs/cvs/sanity.sh1674
-rw-r--r--gnu/usr.bin/cvs/cvs/server.c3992
-rw-r--r--gnu/usr.bin/cvs/cvs/server.h136
-rw-r--r--gnu/usr.bin/cvs/cvs/status.c282
-rw-r--r--gnu/usr.bin/cvs/cvs/tag.c582
-rw-r--r--gnu/usr.bin/cvs/cvs/update.c1908
-rw-r--r--gnu/usr.bin/cvs/cvs/update.h9
-rw-r--r--gnu/usr.bin/cvs/cvs/vers_ts.c326
-rw-r--r--gnu/usr.bin/cvs/cvs/wrapper.c371
-rw-r--r--gnu/usr.bin/cvs/cvsbug/cvsbug.8269
-rw-r--r--gnu/usr.bin/cvs/cvsbug/cvsbug.sh528
-rw-r--r--gnu/usr.bin/cvs/cvsinit/cvsinit161
-rw-r--r--gnu/usr.bin/cvs/cvsinit/cvsinit.8142
-rw-r--r--gnu/usr.bin/cvs/cvsinit/cvsinit.sh161
-rw-r--r--gnu/usr.bin/cvs/doc/cvs-paper.ms1073
-rw-r--r--gnu/usr.bin/cvs/doc/cvs.texinfo6931
-rw-r--r--gnu/usr.bin/cvs/doc/cvsclient.texi673
-rw-r--r--gnu/usr.bin/cvs/examples/checkoutlist20
-rw-r--r--gnu/usr.bin/cvs/examples/commitinfo27
-rw-r--r--gnu/usr.bin/cvs/examples/cvswrappers29
-rw-r--r--gnu/usr.bin/cvs/examples/editinfo32
-rw-r--r--gnu/usr.bin/cvs/examples/loginfo39
-rw-r--r--gnu/usr.bin/cvs/examples/modules581
-rw-r--r--gnu/usr.bin/cvs/examples/rcsinfo18
-rw-r--r--gnu/usr.bin/cvs/examples/rcstemplate7
-rw-r--r--gnu/usr.bin/cvs/examples/taginfo25
-rw-r--r--gnu/usr.bin/cvs/examples/unwrap21
-rw-r--r--gnu/usr.bin/cvs/examples/wrap21
-rw-r--r--gnu/usr.bin/cvs/lib/ChangeLog335
-rw-r--r--gnu/usr.bin/cvs/lib/Makefile8
-rw-r--r--gnu/usr.bin/cvs/lib/alloca.c191
-rw-r--r--gnu/usr.bin/cvs/lib/argmatch.c89
-rw-r--r--gnu/usr.bin/cvs/lib/config.h233
-rw-r--r--gnu/usr.bin/cvs/lib/dup2.c40
-rw-r--r--gnu/usr.bin/cvs/lib/error.c188
-rw-r--r--gnu/usr.bin/cvs/lib/error.h47
-rw-r--r--gnu/usr.bin/cvs/lib/filesubr.c640
-rw-r--r--gnu/usr.bin/cvs/lib/fnmatch.c183
-rw-r--r--gnu/usr.bin/cvs/lib/fnmatch.h45
-rw-r--r--gnu/usr.bin/cvs/lib/ftruncate.c76
-rw-r--r--gnu/usr.bin/cvs/lib/getdate.y996
-rw-r--r--gnu/usr.bin/cvs/lib/getline.c126
-rw-r--r--gnu/usr.bin/cvs/lib/getline.h15
-rw-r--r--gnu/usr.bin/cvs/lib/getopt.c763
-rw-r--r--gnu/usr.bin/cvs/lib/getopt.h131
-rw-r--r--gnu/usr.bin/cvs/lib/getopt1.c187
-rw-r--r--gnu/usr.bin/cvs/lib/getwd.c35
-rw-r--r--gnu/usr.bin/cvs/lib/hash.c400
-rw-r--r--gnu/usr.bin/cvs/lib/hash.h55
-rw-r--r--gnu/usr.bin/cvs/lib/hostname.c49
-rw-r--r--gnu/usr.bin/cvs/lib/md5.c277
-rw-r--r--gnu/usr.bin/cvs/lib/md5.h31
-rw-r--r--gnu/usr.bin/cvs/lib/memmove.c57
-rw-r--r--gnu/usr.bin/cvs/lib/mkdir.c129
-rw-r--r--gnu/usr.bin/cvs/lib/myndbm.c213
-rw-r--r--gnu/usr.bin/cvs/lib/myndbm.h36
-rw-r--r--gnu/usr.bin/cvs/lib/regex.h490
-rw-r--r--gnu/usr.bin/cvs/lib/rename.c72
-rw-r--r--gnu/usr.bin/cvs/lib/run.c533
-rw-r--r--gnu/usr.bin/cvs/lib/save-cwd.c141
-rw-r--r--gnu/usr.bin/cvs/lib/save-cwd.h20
-rw-r--r--gnu/usr.bin/cvs/lib/sighandle.c405
-rw-r--r--gnu/usr.bin/cvs/lib/strdup.c43
-rw-r--r--gnu/usr.bin/cvs/lib/strerror.c813
-rw-r--r--gnu/usr.bin/cvs/lib/strippath.c80
-rw-r--r--gnu/usr.bin/cvs/lib/stripslash.c44
-rw-r--r--gnu/usr.bin/cvs/lib/subr.c322
-rw-r--r--gnu/usr.bin/cvs/lib/system.h496
-rw-r--r--gnu/usr.bin/cvs/lib/version.c34
-rw-r--r--gnu/usr.bin/cvs/lib/wait.h32
-rw-r--r--gnu/usr.bin/cvs/lib/xgetwd.c79
-rw-r--r--gnu/usr.bin/cvs/lib/yesno.c41
-rw-r--r--gnu/usr.bin/cvs/mkmodules/Makefile8
-rw-r--r--gnu/usr.bin/cvs/mkmodules/mkmodules.165
-rw-r--r--gnu/usr.bin/cvs/mkmodules/mkmodules.c435
211 files changed, 0 insertions, 96103 deletions
diff --git a/contrib/cvs/README.VMS b/contrib/cvs/README.VMS
deleted file mode 100644
index b32ed8f995b6..000000000000
--- a/contrib/cvs/README.VMS
+++ /dev/null
@@ -1,159 +0,0 @@
- CVS port to VMS
-
-DISCLAIMER: This port must be considered experimental. Although
-previous versions have been in use at one large site since about
-October, 1995, and the port is believed to be quite usable, various
-VMS-specific quirks are known and the port cannot be considered as
-mature as the ports to, say, Windows NT or unix. As always, future
-progress of this port will depend on volunteer and customer interest.
-
-This port is of the CVS client only. Or in other words, the port
-implements the full set of CVS commands, but cannot access
-repositories located on the local machine. The repository must live
-on another machine (a Unix box) which runs a complete port of CVS.
-
-Most (all?) work to date has been done on OpenVMS/AXP 6.2. Other VMS
-variants might work too.
-
-You will also need GNU patch installed on your system. Here's a list
-of ftp servers which have VMS GNU resources, taken from
-
- ftp://prep.ai.mit.edu/pub/gnu/vms.README
-
- mvb.saic.com
- wuarchive.wustl.edu
- ftp.wku.edu
- ftp.spc.edu
- ftp.stacken.kth.se
-
-Please send bug reports to bug-cvs@prep.ai.mit.edu.
-
-As of CVS 1.5.something, this port passed most of the tests in
-[.src]sanity.sh. I say "most" because some tests to not apply to the
-CVS client. The tests were run by hand because the VMS POSIX shell
-was incapable of running the script. The tests that sanity.sh
-provides are not conclusive but at least provides some assurance that
-the client is usable.
-
-To compile, you will need DEC C (CC), DEC UCX, and of course DCL
-installed on your machine. Just type "@build" in the top level
-directory. This will build the sources in each subdirectory, and link
-the executable [.src]cvs.exe
-
-Copy the executable to an appropriate directory, and define the symbol "CVS"
-in a .COM file which everyone running CVS will need to run. Here's an example
-of what needs to be done.
-
-$ CVS :== $YOUR_DEVICE:[YOUR.DIRECTORY.CVS]CVS.EXE
-
-Accessing a remote repository can happen in several ways.
-
-1. pserver
-2. rsh - privileged (default)
-3. rsh - unprivileged (on VMS side)
-
-Here's how to do each of the above:
-
--------------------------------------------------------------------------------
-1. pserver. This is the preferred way. It works just as it is
-documented in the CVS manual (see the README file in the CVS
-distribution for more information on the manual).
-
--------------------------------------------------------------------------------
-2. Using CVS internal rsh support (privileged)
-
-VMS's RSH is unusable for CVS's purposes (that is, the one in UCX.
-Don't know about Multinet). However, there is code within CVS to
-emulate RSH for purposes of contacting a CVS server "in the usual way"
-via rshd. Unfortunately, this requires the VMS CVS client to be
-installed with OPER privilege, by your system administrator.
-
-RSH uses privileged ports and trusted software/hosts to determine
-which user on the client side is trying to connect. Part of this
-security is due to the fact that on VMS or UNIX, a non privileged
-process is not permitted to bind a socket to a privileged port.
-
-If rshd receives a connection on a non-privileged port, the connection is
-immediately aborted. Only connections arriving from a privileged port will
-be authenticated and served. The CVS client will therefore need privileges
-under VMS to produce such a connection.
-
-*** Please note that no careful examination has been done of the security
- implications of installing CVS with the OPER privilege. If some hole
- exists, then by doing so, you will enable users who are already on
- your system to gain unauthorized privileges ***
-
--------------------------------------------------------------------------------
-3. Using CVS internal rsh support (non-privileged)
-
-There is a workaround, but this is one case where I think the cure is worse
-than the disease. If you patch an rshd to not care that the RSH originating
-port is "non-privileged", the CVS VMS client will allow you to define the
-logical CVS_RCMD_PORT to the port number where this patched rshd will be
-listening. I leave the talk of patching rshd to the gentle reader and his/her
-friendly system administrator.
-
-If I put an entry in my /etc/services file:
-
-cvs_rcmd 4381/tcp cvs_rcmd
-
-And add a line to /etc/inetd.conf, then restart inetd via "kill -1"
-
-cvs_rcmd stream tcp nowait root /usr/sbin/tcpd /usr/local/sbin/cvs_rcmd
-
-On the VMS side, you will have to do this:
-
-$ define CVS_RCMD_PORT 4381
-
-Then run CVS in the "usual way".
-
-Note that the patched rshd will need to be invoked via inetd as root, so it can
-authenticate and _become_ the intended user, the same as the regular rshd.
-
-***Please note that you will be installing a security hole by doing this.***
-
-Please also note that this security hole is no larger than allowing a
-Macintosh, PC (OS/2, NT, etc.) to have it's hostname in any .rhosts file,
-as any user can create a privileged socket without authentication, under these
-environments. In fact, existing ports of CVS to these environment use this
-to their advantage.
-
--------------------------------------------------------------------------------
-Wildcard expansion is not yet implemented (i.e. CVS COMMIT *.c won't
-work.) I think that expand_wild should be calling lib$findfile
-(util.c in gzip is said to provide an example), but noone has gotten
-around to implementing this.
-
-Log messages must be entered on the command line using -m or -F. You
-can use -e or define the logical EDITOR to cause CVS to try other
-editors (TPU.EXE or any other editor which wants DCL command parsing
-will not work) if you want to test what's available on your system. I
-haven't tested this, but if you install vi or emacs, chances are it
-will probably work. Just make sure the .EXE files are in a directory
-listed in VAXC$PATH (is this a typo for DCL$PATH? Also, will a
-logical name work?). If someone gets around to implementing it, we
-should probably be using the callable editors (e.g. TPU$TPU), although
-of course we also need interface(s) which are not locked into any
-particular editors.
-
-----------------------------------------
-
-Notes regarding compiling on VAX/VMS 6.2 (not Alpha) (These are items
-which hopefully will have cleaner solutions in the future, but here is
-how to get around them for now):
-
-* Need to compile lib/getdate.c with vaxc instead of decc to avoid a
-compiler bugcheck. Therefore one must add SYS$LIBRARY:VAXCRTL/LIBRARY
-to the link.
-
-* In src/ignore.c, change lstat to stat. In vms/filesubr.c, change
-"#ifdef S_ISLNK" to "#if 0".
-
-* Ignore the warnings in vms/vmsmunch.c; the system include file
-declares something as an int when it should be void *. Not *our*
-fault!
-
-Credits:
-
-Initial VMS port by Benjamin J. Lee <benjamin@cyclic.com>, Cyclic
-Software, October 1, 1995 (Update March 1, 1996).
diff --git a/contrib/cvs/contrib/ccvs-rsh.pl b/contrib/cvs/contrib/ccvs-rsh.pl
deleted file mode 100644
index 8cfc6743ba3b..000000000000
--- a/contrib/cvs/contrib/ccvs-rsh.pl
+++ /dev/null
@@ -1,97 +0,0 @@
-#!/usr/bin/perl
-
-# The version of the remote shell program on some Linuxes, at least,
-# misuses GNU getopt in such a way that it plucks arguments to rsh
-# that look like command-line switches from anywhere in rsh's
-# arguments. This is the Wrong Thing to do, and causes older versions
-# of CCVS to break.
-
-# In addition, if we live behind a firewall and have to construct a
-# "pipeline" of rshes through different machines in order to get to
-# the outside world, each rshd along the way undoes the hard work CCVS
-# does to put the command to be executed at the far end into a single
-# argument. Sigh.
-
-# This script is a very minimal wrapper to rsh which makes sure that
-# the commands to be executed remotely are packed into a single
-# argument before we call exec(). It works on the idea of a "proxy
-# chain", which is a set of machines you go through to get to the CCVS
-# server machine.
-
-# Each host you go through before you reach the CCVS server machine
-# should have a copy of this script somewhere (preferably accessible
-# directly from your PATH envariable). In addition, each host you go
-# through before you reach the firewall should have the CVS_PROXY_HOST
-# envariable set to the next machine in the chain, and CVS_PROXY_USER
-# set if necessary.
-
-# This really isn't as complex as it sounds. Honest.
-
-# Bryan O'Sullivan <bos@serpentine.com> April 1995
-
-$usage = "usage: ccvs-rsh hostname [-l username] command [...]\n";
-
-if ($#ARGV < 1) {
- print STDERR $usage;
- exit 1;
-}
-
-# Try to pick a sane version of the remote shell command to run. This
-# only understands BSD and Linux machines; if your remote shell is
-# called "remsh" under some System V (e.g. HP-SUX), you should edit
-# the line manually to suit yourself.
-
-$rsh = (-x "/usr/ucb/rsh") ? "/usr/ucb/rsh" : "/usr/bin/rsh";
-
-# If you are not rshing directly to the CCVS server machine, make the
-# following variable point at ccvs-rsh on the next machine in the
-# proxy chain. If it's accessible through the PATH envariable, you
-# can just set this to "ccvs-rsh".
-
-$ccvs_rsh = "ccvs-rsh";
-
-# There shouldn't be any user-serviceable parts beyond this point.
-
-$host = $ARGV[0];
-
-if ($ARGV[1] eq "-l") {
- if ($#ARGV < 3) {
- print STDERR $usage;
- exit 1;
- }
- $user = $ARGV[2];
- $cbase = 3;
-} else {
- $cbase = 1;
-}
-
-# You might think you shoul be able to do something like
-# $command = join(' ', $ARGV[$cbase..$#ARGV]);
-# to achieve the effect of the following block of code, but it doesn't
-# work under Perl 4 on Linux, at least. Sigh.
-
-$command = $ARGV[$cbase];
-for ($cbase++; $cbase <= $#ARGV; $cbase++) {
- $command .= " " . $ARGV[$cbase];
-}
-
-if (defined $ENV{"CVS_PROXY_HOST"}) {
- $command = (defined $user)
- ? "$ccvs_rsh $host -l $user $command"
- : "$ccvs_rsh $host $command";
-
- if (defined $ENV{"CVS_PROXY_USER"}) {
- exec ($rsh, $ENV{"CVS_PROXY_HOST"}, "-l", $ENV{"CVS_PROXY_USER"},
- $command);
- } else {
- exec ($rsh, $ENV{"CVS_PROXY_HOST"}, $command);
- }
-} elsif (defined $user) {
- exec ($rsh, $host, "-l", $user, $command);
-} else {
- if (defined $ENV{"CVS_PROXY_USER"}) {
- exec ($rsh, $host, "-l", $ENV{"CVS_PROXY_USER"}, $command);
- } else {
- exec ($rsh, $host, $command);
- }
-}
diff --git a/contrib/cvs/contrib/clmerge.pl b/contrib/cvs/contrib/clmerge.pl
deleted file mode 100644
index ac813713a827..000000000000
--- a/contrib/cvs/contrib/clmerge.pl
+++ /dev/null
@@ -1,152 +0,0 @@
-#! xPERL_PATHx
-
-# Merge conflicted ChangeLogs
-# tromey Mon Aug 15 1994
-
-# Usage is:
-#
-# cl-merge [-i] file ...
-#
-# With -i, it works in place (backups put in a ~ file). Otherwise the
-# merged ChangeLog is printed to stdout.
-
-# Please report any bugs to me. I wrote this yesterday, so there are no
-# guarantees about its performance. I recommend checking its output
-# carefully. If you do send a bug report, please include the failing
-# ChangeLog, so I can include it in my test suite.
-#
-# Tom
-# ---
-# tromey@busco.lanl.gov Member, League for Programming Freedom
-# Sadism and farce are always inexplicably linked.
-# -- Alexander Theroux
-
-
-# Month->number mapping. Used for sorting.
-%months = ('Jan', 0,
- 'Feb', 1,
- 'Mar', 2,
- 'Apr', 3,
- 'May', 4,
- 'Jun', 5,
- 'Jul', 6,
- 'Aug', 7,
- 'Sep', 8,
- 'Oct', 9,
- 'Nov', 10,
- 'Dec', 11);
-
-# If '-i' is given, do it in-place.
-if ($ARGV[0] eq '-i') {
- shift (@ARGV);
- $^I = '~';
-}
-
-$lastkey = '';
-$lastval = '';
-$conf = 0;
-%conflist = ();
-
-$tjd = 0;
-
-# Simple state machine. The states:
-#
-# 0 Not in conflict. Just copy input to output.
-# 1 Beginning an entry. Next non-blank line is key.
-# 2 In entry. Entry beginner transitions to state 1.
-while (<>) {
- if (/^<<<</ || /^====/) {
- # Start of a conflict.
-
- # Copy last key into array.
- if ($lastkey ne '') {
- $conflist{$lastkey} = $lastval;
-
- $lastkey = '';
- $lastval = '';
- }
-
- $conf = 1;
- } elsif (/^>>>>/) {
- # End of conflict. Output.
-
- # Copy last key into array.
- if ($lastkey ne '') {
- $conflist{$lastkey} = $lastval;
-
- $lastkey = '';
- $lastval = '';
- }
-
- foreach (reverse sort clcmp keys %conflist) {
- print STDERR "doing $_" if $tjd;
- print $_;
- print $conflist{$_};
- }
-
- $lastkey = '';
- $lastval = '';
- $conf = 0;
- %conflist = ();
- } elsif ($conf == 1) {
- # Beginning an entry. Skip empty lines. Error if not a real
- # beginner.
- if (/^$/) {
- # Empty line; just skip at this point.
- } elsif (/^[MTWFS]/) {
- # Looks like the name of a day; assume opener and move to
- # "in entry" state.
- $lastkey = $_;
- $conf = 2;
- print STDERR "found $_" if $tjd;
- } else {
- die ("conflict crosses entry boundaries: $_");
- }
- } elsif ($conf == 2) {
- # In entry. Copy into variable until we see beginner line.
- if (/^[MTWFS]/) {
- # Entry beginner line.
-
- # Copy last key into array.
- if ($lastkey ne '') {
- $conflist{$lastkey} = $lastval;
-
- $lastkey = '';
- $lastval = '';
- }
-
- $lastkey = $_;
- print STDERR "found $_" if $tjd;
- $lastval = '';
- } else {
- $lastval .= $_;
- }
- } else {
- # Just copy.
- print;
- }
-}
-
-# Compare ChangeLog time strings like <=>.
-#
-# 0 1 2 3
-# Thu Aug 11 13:22:42 1994 Tom Tromey (tromey@creche.colorado.edu)
-# 0123456789012345678901234567890
-#
-sub clcmp {
- # First check year.
- $r = substr ($a, 20, 4) <=> substr ($b, 20, 4);
-
- # Now check month.
- $r = $months{substr ($a, 4, 3)} <=> $months{substr ($b, 4, 3)} if !$r;
-
- # Now check day.
- $r = substr ($a, 8, 2) <=> substr ($b, 8, 2) if !$r;
-
- # Now check time (3 parts).
- $r = substr ($a, 11, 2) <=> substr ($b, 11, 2) if !$r;
- $r = substr ($a, 14, 2) <=> substr ($b, 14, 2) if !$r;
- $r = substr ($a, 17, 2) <=> substr ($b, 17, 2) if !$r;
-
- $r;
-}
diff --git a/contrib/cvs/contrib/cln_hist.pl b/contrib/cvs/contrib/cln_hist.pl
deleted file mode 100644
index 19a0b815b783..000000000000
--- a/contrib/cvs/contrib/cln_hist.pl
+++ /dev/null
@@ -1,91 +0,0 @@
-#! xPERL_PATHx
-# -*-Perl-*-
-#
-# Contributed by David G. Grubbs <dgg@ksr.com>
-#
-# Clean up the history file. 10 Record types: MAR OFT WUCG
-#
-# WUCG records are thrown out.
-# MAR records are retained.
-# T records: retain only last tag with same combined tag/module.
-#
-# Two passes: Walk through the first time and remember the
-# 1. Last Tag record with same "tag" and "module" names.
-# 2. Last O record with unique user/module/directory, unless followed
-# by a matching F record.
-#
-
-$r = $ENV{"CVSROOT"};
-$c = "$r/CVSROOT";
-$h = "$c/history";
-
-eval "print STDERR \$die='Unknown parameter $1\n' if !defined \$$1; \$$1=\$';"
- while ($ARGV[0] =~ /^(\w+)=/ && shift(@ARGV));
-exit 255 if $die; # process any variable=value switches
-
-%tags = ();
-%outs = ();
-
-#
-# Move history file to safe place and re-initialize a new one.
-#
-rename($h, "$h.bak");
-open(XX, ">$h");
-close(XX);
-
-#
-# Pass1 -- remember last tag and checkout.
-#
-open(HIST, "$h.bak");
-while (<HIST>) {
- next if /^[MARWUCG]/;
-
- # Save whole line keyed by tag|module
- if (/^T/) {
- @tmp = split(/\|/, $_);
- $tags{$tmp[4] . '|' . $tmp[5]} = $_;
- }
- # Save whole line
- if (/^[OF]/) {
- @tmp = split(/\|/, $_);
- $outs{$tmp[1] . '|' . $tmp[2] . '|' . $tmp[5]} = $_;
- }
-}
-
-#
-# Pass2 -- print out what we want to save.
-#
-open(SAVE, ">$h.work");
-open(HIST, "$h.bak");
-while (<HIST>) {
- next if /^[FWUCG]/;
-
- # If whole line matches saved (i.e. "last") one, print it.
- if (/^T/) {
- @tmp = split(/\|/, $_);
- next if $tags{$tmp[4] . '|' . $tmp[5]} ne $_;
- }
- # Save whole line
- if (/^O/) {
- @tmp = split(/\|/, $_);
- next if $outs{$tmp[1] . '|' . $tmp[2] . '|' . $tmp[5]} ne $_;
- }
-
- print SAVE $_;
-}
-
-#
-# Put back the saved stuff
-#
-system "cat $h >> $h.work";
-
-if (-s $h) {
- rename ($h, "$h.interim");
- print "history.interim has non-zero size.\n";
-} else {
- unlink($h);
-}
-
-rename ("$h.work", $h);
-
-exit(0);
diff --git a/contrib/cvs/contrib/commit_prep.pl b/contrib/cvs/contrib/commit_prep.pl
deleted file mode 100644
index bf0ce92f22f4..000000000000
--- a/contrib/cvs/contrib/commit_prep.pl
+++ /dev/null
@@ -1,215 +0,0 @@
-#! xPERL_PATHx
-# -*-Perl-*-
-#
-#
-# Perl filter to handle pre-commit checking of files. This program
-# records the last directory where commits will be taking place for
-# use by the log_accum.pl script. For new files, it forces the
-# existence of a RCS "Id" keyword in the first ten lines of the file.
-# For existing files, it checks version number in the "Id" line to
-# prevent losing changes because an old version of a file was copied
-# into the direcory.
-#
-# Possible future enhancements:
-#
-# Check for cruft left by unresolved conflicts. Search for
-# "^<<<<<<<$", "^-------$", and "^>>>>>>>$".
-#
-# Look for a copyright and automagically update it to the
-# current year. [[ bad idea! -- woods ]]
-#
-#
-# Contributed by David Hampton <hampton@cisco.com>
-#
-# Hacked on lots by Greg A. Woods <woods@web.net>
-
-#
-# Configurable options
-#
-
-# Constants (remember to protect strings from RCS keyword substitution)
-#
-$LAST_FILE = "/tmp/#cvs.lastdir"; # must match name in log_accum.pl
-$ENTRIES = "CVS/Entries";
-
-# Patterns to find $Log keywords in files
-#
-$LogString1 = "\\\$\\Log: .* \\\$";
-$LogString2 = "\\\$\\Log\\\$";
-$NoLog = "%s - contains an RCS \$Log keyword. It must not!\n";
-
-# pattern to match an RCS Id keyword line with an existing ID
-#
-$IDstring = "\"@\\(#\\)[^:]*:.*\\\$\Id: .*\\\$\"";
-$NoId = "
-%s - Does not contain a properly formatted line with the keyword \"Id:\".
- I.e. no lines match \"" . $IDstring . "\".
- Please see the template files for an example.\n";
-
-# pattern to match an RCS Id keyword line for a new file (i.e. un-expanded)
-#
-$NewId = "\"@(#)[^:]*:.*\\$\Id\\$\"";
-
-$NoName = "
-%s - The ID line should contain only \"@(#)module/path:\$Name\$:\$\Id\$\"
- for a newly created file.\n";
-
-$BadName = "
-%s - The file name '%s' in the ID line does not match
- the actual filename.\n";
-
-$BadVersion = "
-%s - How dare you!!! You replaced your copy of the file '%s',
- which was based upon version %s, with an %s version based
- upon %s. Please move your '%s' out of the way, perform an
- update to get the current version, and them merge your changes
- into that file, then try the commit again.\n";
-
-#
-# Subroutines
-#
-
-sub write_line {
- local($filename, $line) = @_;
- open(FILE, ">$filename") || die("Cannot open $filename, stopped");
- print(FILE $line, "\n");
- close(FILE);
-}
-
-sub check_version {
- local($i, $id, $rname, $version);
- local($filename, $cvsversion) = @_;
-
- open(FILE, "<$filename") || return(0);
-
- @all_lines = ();
- $idpos = -1;
- $newidpos = -1;
- for ($i = 0; <FILE>; $i++) {
- chop;
- push(@all_lines, $_);
- if ($_ =~ /$IDstring/) {
- $idpos = $i;
- }
- if ($_ =~ /$NewId/) {
- $newidpos = $i;
- }
- }
-
- if (grep(/$LogString1/, @all_lines) || grep(/$LogString2/, @all_lines)) {
- print STDERR sprintf($NoLog, $filename);
- return(1);
- }
-
- if ($debug != 0) {
- print STDERR sprintf("file = %s, version = %d.\n", $filename, $cvsversion{$filename});
- }
-
- if ($cvsversion{$filename} == 0) {
- if ($newidpos != -1 && $all_lines[$newidpos] !~ /$NewId/) {
- print STDERR sprintf($NoName, $filename);
- return(1);
- }
- return(0);
- }
-
- if ($idpos == -1) {
- print STDERR sprintf($NoId, $filename);
- return(1);
- }
-
- $line = $all_lines[$idpos];
- $pos = index($line, "Id: ");
- if ($debug != 0) {
- print STDERR sprintf("%d in '%s'.\n", $pos, $line);
- }
- ($id, $rname, $version) = split(' ', substr($line, $pos));
- if ($rname ne "$filename,v") {
- print STDERR sprintf($BadName, $filename, substr($rname, 0, length($rname)-2));
- return(1);
- }
- if ($cvsversion{$filename} < $version) {
- print STDERR sprintf($BadVersion, $filename, $filename, $cvsversion{$filename},
- "newer", $version, $filename);
- return(1);
- }
- if ($cvsversion{$filename} > $version) {
- print STDERR sprintf($BadVersion, $filename, $filename, $cvsversion{$filename},
- "older", $version, $filename);
- return(1);
- }
- return(0);
-}
-
-#
-# Main Body
-#
-
-$id = getpgrp(); # You *must* use a shell that does setpgrp()!
-
-# Check each file (except dot files) for an RCS "Id" keyword.
-#
-$check_id = 0;
-
-# Record the directory for later use by the log_accumulate stript.
-#
-$record_directory = 0;
-
-# parse command line arguments
-#
-while (@ARGV) {
- $arg = shift @ARGV;
-
- if ($arg eq '-d') {
- $debug = 1;
- print STDERR "Debug turned on...\n";
- } elsif ($arg eq '-c') {
- $check_id = 1;
- } elsif ($arg eq '-r') {
- $record_directory = 1;
- } else {
- push(@files, $arg);
- }
-}
-
-$directory = shift @files;
-
-if ($debug != 0) {
- print STDERR "dir - ", $directory, "\n";
- print STDERR "files - ", join(":", @files), "\n";
- print STDERR "id - ", $id, "\n";
-}
-
-# Suck in the CVS/Entries file
-#
-open(ENTRIES, $ENTRIES) || die("Cannot open $ENTRIES.\n");
-while (<ENTRIES>) {
- local($filename, $version) = split('/', substr($_, 1));
- $cvsversion{$filename} = $version;
-}
-
-# Now check each file name passed in, except for dot files. Dot files
-# are considered to be administrative files by this script.
-#
-if ($check_id != 0) {
- $failed = 0;
- foreach $arg (@files) {
- if (index($arg, ".") == 0) {
- next;
- }
- $failed += &check_version($arg);
- }
- if ($failed) {
- print STDERR "\n";
- exit(1);
- }
-}
-
-# Record this directory as the last one checked. This will be used
-# by the log_accumulate script to determine when it is processing
-# the final directory of a multi-directory commit.
-#
-if ($record_directory != 0) {
- &write_line("$LAST_FILE.$id", $directory);
-}
-exit(0);
diff --git a/contrib/cvs/contrib/cvs_acls.pl b/contrib/cvs/contrib/cvs_acls.pl
deleted file mode 100644
index c1d64e948770..000000000000
--- a/contrib/cvs/contrib/cvs_acls.pl
+++ /dev/null
@@ -1,141 +0,0 @@
-#! xPERL_PATHx
-# -*-Perl-*-
-#
-# Access control lists for CVS. dgg@ksr.com (David G. Grubbs)
-#
-# CVS "commitinfo" for matching repository names, running the program it finds
-# on the same line. More information is available in the CVS man pages.
-#
-# ==== INSTALLATION:
-#
-# To use this program as I intended, do the following four things:
-#
-# 0. Install PERL. :-)
-#
-# 1. Put one line, as the *only* non-comment line, in your commitinfo file:
-#
-# DEFAULT /usr/local/bin/cvs_acls
-#
-# 2. Install this file as /usr/local/bin/cvs_acls and make it executable.
-#
-# 3. Create a file named $CVSROOT/CVSROOT/avail.
-#
-# ==== FORMAT OF THE avail FILE:
-#
-# The avail file determines whether you may commit files. It contains lines
-# read from top to bottom, keeping track of a single "bit". The "bit"
-# defaults to "on". It can be turned "off" by "unavail" lines and "on" by
-# "avail" lines. ==> Last one counts.
-#
-# Any line not beginning with "avail" or "unavail" is ignored.
-#
-# Lines beginning with "avail" or "unavail" are assumed to be '|'-separated
-# triples: (All spaces and tabs are ignored in a line.)
-#
-# {avail.*,unavail.*} [| user,user,... [| repos,repos,...]]
-#
-# 1. String starting with "avail" or "unavail".
-# 2. Optional, comma-separated list of usernames.
-# 3. Optional, comma-separated list of repository pathnames.
-# These are pathnames relative to $CVSROOT. They can be directories or
-# filenames. A directory name allows access to all files and
-# directories below it.
-#
-# Example: (Text from the ';;' rightward may not appear in the file.)
-#
-# unavail ;; Make whole repository unavailable.
-# avail|dgg ;; Except for user "dgg".
-# avail|fred, john|bin/ls ;; Except when "fred" or "john" commit to
-# ;; the module whose repository is "bin/ls"
-#
-# PROGRAM LOGIC:
-#
-# CVS passes to @ARGV an absolute directory pathname (the repository
-# appended to your $CVSROOT variable), followed by a list of filenames
-# within that directory.
-#
-# We walk through the avail file looking for a line that matches both
-# the username and repository.
-#
-# A username match is simply the user's name appearing in the second
-# column of the avail line in a space-or-comma separate list.
-#
-# A repository match is either:
-# - One element of the third column matches $ARGV[0], or some
-# parent directory of $ARGV[0].
-# - Otherwise *all* file arguments ($ARGV[1..$#ARGV]) must be
-# in the file list in one avail line.
-# - In other words, using directory names in the third column of
-# the avail file allows committing of any file (or group of
-# files in a single commit) in the tree below that directory.
-# - If individual file names are used in the third column of
-# the avail file, then files must be committed individually or
-# all files specified in a single commit must all appear in
-# third column of a single avail line.
-#
-
-$debug = 0;
-$cvsroot = $ENV{'CVSROOT'};
-$availfile = $cvsroot . "/CVSROOT/avail";
-$myname = $ENV{"USER"} if !($myname = $ENV{"LOGNAME"});
-
-eval "print STDERR \$die='Unknown parameter $1\n' if !defined \$$1; \$$1=\$';"
- while ($ARGV[0] =~ /^(\w+)=/ && shift(@ARGV));
-exit 255 if $die; # process any variable=value switches
-
-die "Must set CVSROOT\n" if !$cvsroot;
-($repos = shift) =~ s:^$cvsroot/::;
-grep($_ = $repos . '/' . $_, @ARGV);
-
-print "$$ Repos: $repos\n","$$ ==== ",join("\n$$ ==== ",@ARGV),"\n" if $debug;
-
-$exit_val = 0; # Good Exit value
-
-$universal_off = 0;
-open (AVAIL, $availfile) || exit(0); # It is ok for avail file not to exist
-while (<AVAIL>) {
- chop;
- next if /^\s*\#/;
- next if /^\s*$/;
- ($flagstr, $u, $m) = split(/[\s,]*\|[\s,]*/, $_);
-
- # Skip anything not starting with "avail" or "unavail" and complain.
- (print "Bad avail line: $_\n"), next
- if ($flagstr !~ /^avail/ && $flagstr !~ /^unavail/);
-
- # Set which bit we are playing with. ('0' is OK == Available).
- $flag = (($& eq "avail") ? 0 : 1);
-
- # If we find a "universal off" flag (i.e. a simple "unavail") remember it
- $universal_off = 1 if ($flag && !$u && !$m);
-
- # $myname considered "in user list" if actually in list or is NULL
- $in_user = (!$u || grep ($_ eq $myname, split(/[\s,]+/,$u)));
- print "$$ \$myname($myname) in user list: $_\n" if $debug && $in_user;
-
- # Module matches if it is a NULL module list in the avail line. If module
- # list is not null, we check every argument combination.
- if (!($in_repo = !$m)) {
- @tmp = split(/[\s,]+/,$m);
- for $j (@tmp) {
- # If the repos from avail is a parent(or equal) dir of $repos, OK
- $in_repo = 1, last if ($repos eq $j || $repos =~ /^$j\//);
- }
- if (!$in_repo) {
- $in_repo = 1;
- for $j (@ARGV) {
- last if !($in_repo = grep ($_ eq $j, @tmp));
- }
- }
- }
- print "$$ \$repos($repos) in repository list: $_\n" if $debug && $in_repo;
-
- $exit_val = $flag if ($in_user && $in_repo);
- print "$$ ==== \$exit_val = $exit_val\n$$ ==== \$flag = $flag\n" if $debug;
-}
-close(AVAIL);
-print "$$ ==== \$exit_val = $exit_val\n" if $debug;
-print "**** Access denied: Insufficient Karma ($myname|$repos)\n" if $exit_val;
-print "**** Access allowed: Personal Karma exceeds Environmental Karma.\n"
- if $universal_off && !$exit_val;
-exit($exit_val);
diff --git a/contrib/cvs/contrib/listen2.c b/contrib/cvs/contrib/listen2.c
deleted file mode 100644
index 20cfc6cd4556..000000000000
--- a/contrib/cvs/contrib/listen2.c
+++ /dev/null
@@ -1,107 +0,0 @@
-/* This will develop into the inted-like program which
- we may want to use for a server on Win95/NT. Right now
- it is just a test program ("telnet foo 2401" and you'll
- get a message). */
-
-#include <winsock.h>
-#include <stdio.h>
-#include <io.h>
-#include <process.h>
-
-int
-main ()
-{
- struct sockaddr_in sa;
- SOCKET t;
- SOCKET s;
- WSADATA data;
-
- if (WSAStartup (MAKEWORD (1, 1), &data))
- {
- fprintf (stderr, "cvs: unable to initialize winsock\n");
- exit (1);
- }
-
- t = socket (PF_INET, SOCK_STREAM, 0);
- if (t == INVALID_SOCKET)
- {
- printf ("Error in socket(): %d\n", WSAGetLastError ());
- exit (1);
- }
- sa.sin_family = AF_INET;
- sa.sin_addr.s_addr = INADDR_ANY;
- sa.sin_port = htons (2401);
- if (bind (t, (struct sockaddr *) &sa, sizeof (sa)) != 0)
- {
- printf ("Cannot bind(): %d\n", WSAGetLastError ());
- exit (1);
- }
- if (listen (t, 1) != 0)
- {
- printf ("Cannot listen(): %d\n", WSAGetLastError ());
- exit (1);
- }
- while (1)
- {
- int sasize = sizeof (sa);
-
-#if 0
- int save_stdin, save_stdout;
-#endif
-
- s = accept (t, (struct sockaddr *) &sa, &sasize);
- if (s == INVALID_SOCKET)
- {
- printf ("Cannot accept(): %d\n", WSAGetLastError ());
- exit (1);
- }
-#if 0
- /* This, of course, does not work because sockets are
- not file descriptors and file descriptors are not
- sockets. Duh! */
- save_stdin = _dup (0);
- if (save_stdin < 0)
- {
- printf ("Cannot save stdin: %s\n", strerror (errno));
- exit (1);
- }
- save_stdout = _dup (1);
- if (save_stdout < 0)
- {
- printf ("Cannot save stdout: %s\n", strerror (errno));
- exit (1);
- }
- if (_dup2 (s, 0) < 0)
- {
- printf ("Cannot dup stdin: %s\n", strerror (errno));
- exit (1);
- }
- if (_dup2 (s, 1) < 0)
- {
- printf ("Cannot dup stdout: %s\n", strerror (errno));
- exit (1);
- }
- /* Of course this will be "cvs" eventually, but "netstat"
- is for testing. */
- if (_spawnl (_P_DETACH, "netstat", "netstat", NULL) < 0)
- {
- printf ("Cannot spawn subprocess: %s\n", strerror (errno));
- exit (1);
- }
-#else
- if (send (s, "hello, world\n", 13, 0) == SOCKET_ERROR)
- {
- /* Note that we do not detect the case in which we sent
- less than the requested number of bytes. */
- printf ("Cannot send(): %d\n", WSAGetLastError ());
- exit (1);
- }
-#endif
- if (closesocket (s) != 0)
- {
- printf ("Cannot closesocket(): %d\n", WSAGetLastError ());
- exit (1);
- }
- }
- return 0;
-}
diff --git a/contrib/cvs/contrib/listen2.mak b/contrib/cvs/contrib/listen2.mak
deleted file mode 100644
index 12a80cede84e..000000000000
--- a/contrib/cvs/contrib/listen2.mak
+++ /dev/null
@@ -1,188 +0,0 @@
-# Microsoft Developer Studio Generated NMAKE File, Format Version 40001
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Console Application" 0x0103
-
-!IF "$(CFG)" == ""
-CFG=listen2 - Win32 Debug
-!MESSAGE No configuration specified. Defaulting to listen2 - Win32 Debug.
-!ENDIF
-
-!IF "$(CFG)" != "listen2 - Win32 Release" && "$(CFG)" !=\
- "listen2 - Win32 Debug"
-!MESSAGE Invalid configuration "$(CFG)" specified.
-!MESSAGE You can specify a configuration when running NMAKE on this makefile
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "listen2.mak" CFG="listen2 - Win32 Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "listen2 - Win32 Release" (based on "Win32 (x86) Console Application")
-!MESSAGE "listen2 - Win32 Debug" (based on "Win32 (x86) Console Application")
-!MESSAGE
-!ERROR An invalid configuration is specified.
-!ENDIF
-
-!IF "$(OS)" == "Windows_NT"
-NULL=
-!ELSE
-NULL=nul
-!ENDIF
-################################################################################
-# Begin Project
-RSC=rc.exe
-CPP=cl.exe
-
-!IF "$(CFG)" == "listen2 - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Release"
-# PROP Intermediate_Dir "Release"
-# PROP Target_Dir ""
-OUTDIR=.\Release
-INTDIR=.\Release
-
-ALL : "$(OUTDIR)\listen2.exe"
-
-CLEAN :
- -@erase ".\Release\listen2.exe"
- -@erase ".\Release\listen2.obj"
-
-"$(OUTDIR)" :
- if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
-
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /YX /c
-# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /YX /c
-CPP_PROJ=/nologo /ML /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE"\
- /Fp"$(INTDIR)/listen2.pch" /YX /Fo"$(INTDIR)/" /c
-CPP_OBJS=.\Release/
-CPP_SBRS=
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-BSC32_FLAGS=/nologo /o"$(OUTDIR)/listen2.bsc"
-BSC32_SBRS=
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib wsock32.lib /nologo /subsystem:console /machine:I386
-LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\
- advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib wsock32.lib /nologo\
- /subsystem:console /incremental:no /pdb:"$(OUTDIR)/listen2.pdb" /machine:I386\
- /out:"$(OUTDIR)/listen2.exe"
-LINK32_OBJS= \
- "$(INTDIR)/listen2.obj"
-
-"$(OUTDIR)\listen2.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
- $(LINK32) @<<
- $(LINK32_FLAGS) $(LINK32_OBJS)
-<<
-
-!ELSEIF "$(CFG)" == "listen2 - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "Debug"
-# PROP BASE Intermediate_Dir "Debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "Debug"
-# PROP Intermediate_Dir "Debug"
-# PROP Target_Dir ""
-OUTDIR=.\Debug
-INTDIR=.\Debug
-
-ALL : "$(OUTDIR)\listen2.exe"
-
-CLEAN :
- -@erase ".\Debug\listen2.exe"
- -@erase ".\Debug\listen2.obj"
- -@erase ".\Debug\listen2.ilk"
- -@erase ".\Debug\listen2.pdb"
- -@erase ".\Debug\vc40.pdb"
- -@erase ".\Debug\vc40.idb"
-
-"$(OUTDIR)" :
- if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
-
-# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c
-# ADD CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c
-CPP_PROJ=/nologo /MLd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE"\
- /Fp"$(INTDIR)/listen2.pch" /YX /Fo"$(INTDIR)/" /Fd"$(INTDIR)/" /c
-CPP_OBJS=.\Debug/
-CPP_SBRS=
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-BSC32_FLAGS=/nologo /o"$(OUTDIR)/listen2.bsc"
-BSC32_SBRS=
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:console /debug /machine:I386
-# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib wsock32.lib /nologo /subsystem:console /debug /machine:I386
-LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\
- advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib wsock32.lib /nologo\
- /subsystem:console /incremental:yes /pdb:"$(OUTDIR)/listen2.pdb" /debug\
- /machine:I386 /out:"$(OUTDIR)/listen2.exe"
-LINK32_OBJS= \
- "$(INTDIR)/listen2.obj"
-
-"$(OUTDIR)\listen2.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
- $(LINK32) @<<
- $(LINK32_FLAGS) $(LINK32_OBJS)
-<<
-
-!ENDIF
-
-.c{$(CPP_OBJS)}.obj:
- $(CPP) $(CPP_PROJ) $<
-
-.cpp{$(CPP_OBJS)}.obj:
- $(CPP) $(CPP_PROJ) $<
-
-.cxx{$(CPP_OBJS)}.obj:
- $(CPP) $(CPP_PROJ) $<
-
-.c{$(CPP_SBRS)}.sbr:
- $(CPP) $(CPP_PROJ) $<
-
-.cpp{$(CPP_SBRS)}.sbr:
- $(CPP) $(CPP_PROJ) $<
-
-.cxx{$(CPP_SBRS)}.sbr:
- $(CPP) $(CPP_PROJ) $<
-
-################################################################################
-# Begin Target
-
-# Name "listen2 - Win32 Release"
-# Name "listen2 - Win32 Debug"
-
-!IF "$(CFG)" == "listen2 - Win32 Release"
-
-!ELSEIF "$(CFG)" == "listen2 - Win32 Debug"
-
-!ENDIF
-
-################################################################################
-# Begin Source File
-
-SOURCE=.\listen2.c
-
-"$(INTDIR)\listen2.obj" : $(SOURCE) "$(INTDIR)"
-
-
-# End Source File
-# End Target
-# End Project
-################################################################################
diff --git a/contrib/cvs/contrib/log.pl b/contrib/cvs/contrib/log.pl
deleted file mode 100644
index ebdd32285b74..000000000000
--- a/contrib/cvs/contrib/log.pl
+++ /dev/null
@@ -1,182 +0,0 @@
-#! xPERL_PATHx
-# -*-Perl-*-
-#
-# XXX: FIXME: handle multiple '-f logfile' arguments
-#
-# XXX -- I HATE Perl! This *will* be re-written in shell/awk/sed soon!
-#
-
-# Usage: log.pl [-u user] [[-m mailto] ...] [-s] -f logfile 'dirname file ...'
-#
-# -u user - $USER passed from loginfo
-# -m mailto - for each user to receive cvs log reports
-# (multiple -m's permitted)
-# -s - to prevent "cvs status -v" messages
-# -f logfile - for the logfile to append to (mandatory,
-# but only one logfile can be specified).
-
-# here is what the output looks like:
-#
-# From: woods@kuma.domain.top
-# Subject: CVS update: testmodule
-#
-# Date: Wednesday November 23, 1994 @ 14:15
-# Author: woods
-#
-# Update of /local/src-CVS/testmodule
-# In directory kuma:/home/kuma/woods/work.d/testmodule
-#
-# Modified Files:
-# test3
-# Added Files:
-# test6
-# Removed Files:
-# test4
-# Log Message:
-# - wow, what a test
-#
-# (and for each file the "cvs status -v" output is appended unless -s is used)
-#
-# ==================================================================
-# File: test3 Status: Up-to-date
-#
-# Working revision: 1.41 Wed Nov 23 14:15:59 1994
-# Repository revision: 1.41 /local/src-CVS/cvs/testmodule/test3,v
-# Sticky Options: -ko
-#
-# Existing Tags:
-# local-v2 (revision: 1.7)
-# local-v1 (revision: 1.1.1.2)
-# CVS-1_4A2 (revision: 1.1.1.2)
-# local-v0 (revision: 1.2)
-# CVS-1_4A1 (revision: 1.1.1.1)
-# CVS (branch: 1.1.1)
-
-$cvsroot = $ENV{'CVSROOT'};
-
-# turn off setgid
-#
-$) = $(;
-
-$dostatus = 1;
-
-# parse command line arguments
-#
-while (@ARGV) {
- $arg = shift @ARGV;
-
- if ($arg eq '-m') {
- $users = "$users " . shift @ARGV;
- } elsif ($arg eq '-u') {
- $login = shift @ARGV;
- } elsif ($arg eq '-f') {
- ($logfile) && die "Too many '-f' args";
- $logfile = shift @ARGV;
- } elsif ($arg eq '-s') {
- $dostatus = 0;
- } else {
- ($donefiles) && die "Too many arguments!\n";
- $donefiles = 1;
- @files = split(/ /, $arg);
- }
-}
-
-# the first argument is the module location relative to $CVSROOT
-#
-$modulepath = shift @files;
-
-$mailcmd = "| Mail -s 'CVS update: $modulepath'";
-
-# Initialise some date and time arrays
-#
-@mos = (January,February,March,April,May,June,July,August,September,
- October,November,December);
-@days = (Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday);
-
-($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime;
-$year += 1900;
-
-# get a login name for the guy doing the commit....
-#
-if ($login eq '') {
- $login = getlogin || (getpwuid($<))[0] || "nobody";
-}
-
-# open log file for appending
-#
-open(OUT, ">>" . $logfile) || die "Could not open(" . $logfile . "): $!\n";
-
-# send mail, if there's anyone to send to!
-#
-if ($users) {
- $mailcmd = "$mailcmd $users";
- open(MAIL, $mailcmd) || die "Could not Exec($mailcmd): $!\n";
-}
-
-# print out the log Header
-#
-print OUT "\n";
-print OUT "****************************************\n";
-print OUT "Date:\t$days[$wday] $mos[$mon] $mday, $year @ $hour:" . sprintf("%02d", $min) . "\n";
-print OUT "Author:\t$login\n\n";
-
-if (MAIL) {
- print MAIL "\n";
- print MAIL "Date:\t$days[$wday] $mos[$mon] $mday, $year @ $hour:" . sprintf("%02d", $min) . "\n";
- print MAIL "Author:\t$login\n\n";
-}
-
-# print the stuff from logmsg that comes in on stdin to the logfile
-#
-open(IN, "-");
-while (<IN>) {
- print OUT $_;
- if (MAIL) {
- print MAIL $_;
- }
-}
-close(IN);
-
-print OUT "\n";
-
-# after log information, do an 'cvs -Qq status -v' on each file in the arguments.
-#
-if ($dostatus != 0) {
- while (@files) {
- $file = shift @files;
- if ($file eq "-") {
- print OUT "[input file was '-']\n";
- if (MAIL) {
- print MAIL "[input file was '-']\n";
- }
- last;
- }
- $pid = open(RCS, "-|");
- if ( !defined $pid )
- {
- die "fork failed: $!";
- }
- if ($pid == 0)
- {
- exec 'cvs', '-nQq', 'status', '-v', $file;
- die "cvs exec failed: $!";
- }
- while (<RCS>) {
- print OUT;
- if (MAIL) {
- print MAIL;
- }
- }
- close(RCS);
- }
-}
-
-close(OUT);
-die "Write to $logfile failed" if $?;
-
-close(MAIL);
-die "Pipe to $mailcmd failed" if $?;
-
-## must exit cleanly
-##
-exit 0;
diff --git a/contrib/cvs/contrib/log_accum.pl b/contrib/cvs/contrib/log_accum.pl
deleted file mode 100644
index 2520fe1409a8..000000000000
--- a/contrib/cvs/contrib/log_accum.pl
+++ /dev/null
@@ -1,576 +0,0 @@
-#! xPERL_PATHx
-# -*-Perl-*-
-#
-# Perl filter to handle the log messages from the checkin of files in
-# a directory. This script will group the lists of files by log
-# message, and mail a single consolidated log message at the end of
-# the commit.
-#
-# This file assumes a pre-commit checking program that leaves the
-# names of the first and last commit directories in a temporary file.
-#
-# Contributed by David Hampton <hampton@cisco.com>
-#
-# hacked greatly by Greg A. Woods <woods@planix.com>
-
-# Usage: log_accum.pl [-d] [-s] [-w] [-M module] [-u user] [[-m mailto] ...] [[-R replyto] ...] [-f logfile]
-# -d - turn on debugging
-# -m mailto - send mail to "mailto" (multiple)
-# -R replyto - set the "Reply-To:" to "replyto" (multiple)
-# -M modulename - set module name to "modulename"
-# -f logfile - write commit messages to logfile too
-# -s - *don't* run "cvs status -v" for each file
-# -w - show working directory with log message
-# -u user - $USER passed from loginfo
-
-#
-# Configurable options
-#
-
-# set this to something that takes a whole message on stdin
-$MAILER = "/usr/lib/sendmail -t";
-
-#
-# End user configurable options.
-#
-
-# Constants (don't change these!)
-#
-$STATE_NONE = 0;
-$STATE_CHANGED = 1;
-$STATE_ADDED = 2;
-$STATE_REMOVED = 3;
-$STATE_LOG = 4;
-
-$LAST_FILE = "/tmp/#cvs.lastdir";
-
-$CHANGED_FILE = "/tmp/#cvs.files.changed";
-$ADDED_FILE = "/tmp/#cvs.files.added";
-$REMOVED_FILE = "/tmp/#cvs.files.removed";
-$LOG_FILE = "/tmp/#cvs.files.log";
-
-$FILE_PREFIX = "#cvs.files";
-
-#
-# Subroutines
-#
-
-sub cleanup_tmpfiles {
- local($wd, @files);
-
- $wd = `pwd`;
- chdir("/tmp") || die("Can't chdir('/tmp')\n");
- opendir(DIR, ".");
- push(@files, grep(/^$FILE_PREFIX\..*\.$id$/, readdir(DIR)));
- closedir(DIR);
- foreach (@files) {
- unlink $_;
- }
- unlink $LAST_FILE . "." . $id;
-
- chdir($wd);
-}
-
-sub write_logfile {
- local($filename, @lines) = @_;
-
- open(FILE, ">$filename") || die("Cannot open log file $filename.\n");
- print FILE join("\n", @lines), "\n";
- close(FILE);
-}
-
-sub append_to_logfile {
- local($filename, @lines) = @_;
-
- open(FILE, ">$filename") || die("Cannot open log file $filename.\n");
- print FILE join("\n", @lines), "\n";
- close(FILE);
-}
-
-sub format_names {
- local($dir, @files) = @_;
- local(@lines);
-
- $format = "\t%-" . sprintf("%d", length($dir)) . "s%s ";
-
- $lines[0] = sprintf($format, $dir, ":");
-
- if ($debug) {
- print STDERR "format_names(): dir = ", $dir, "; files = ", join(":", @files), ".\n";
- }
- foreach $file (@files) {
- if (length($lines[$#lines]) + length($file) > 65) {
- $lines[++$#lines] = sprintf($format, " ", " ");
- }
- $lines[$#lines] .= $file . " ";
- }
-
- @lines;
-}
-
-sub format_lists {
- local(@lines) = @_;
- local(@text, @files, $lastdir);
-
- if ($debug) {
- print STDERR "format_lists(): ", join(":", @lines), "\n";
- }
- @text = ();
- @files = ();
- $lastdir = shift @lines; # first thing is always a directory
- if ($lastdir !~ /.*\/$/) {
- die("Damn, $lastdir doesn't look like a directory!\n");
- }
- foreach $line (@lines) {
- if ($line =~ /.*\/$/) {
- push(@text, &format_names($lastdir, @files));
- $lastdir = $line;
- @files = ();
- } else {
- push(@files, $line);
- }
- }
- push(@text, &format_names($lastdir, @files));
-
- @text;
-}
-
-sub append_names_to_file {
- local($filename, $dir, @files) = @_;
-
- if (@files) {
- open(FILE, ">>$filename") || die("Cannot open file $filename.\n");
- print FILE $dir, "\n";
- print FILE join("\n", @files), "\n";
- close(FILE);
- }
-}
-
-sub read_line {
- local($line);
- local($filename) = @_;
-
- open(FILE, "<$filename") || die("Cannot open file $filename.\n");
- $line = <FILE>;
- close(FILE);
- chop($line);
- $line;
-}
-
-sub read_logfile {
- local(@text);
- local($filename, $leader) = @_;
-
- open(FILE, "<$filename");
- while (<FILE>) {
- chop;
- push(@text, $leader.$_);
- }
- close(FILE);
- @text;
-}
-
-sub build_header {
- local($header);
- local($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
- $header = sprintf("CVSROOT:\t%s\nModule name:\t%s\nRepository:\t%s\nChanges by:\t%s@%s\t%02d/%02d/%02d %02d:%02d:%02d",
- $cvsroot,
- $modulename,
- $dir,
- $login, $hostdomain,
- $year%100, $mon+1, $mday,
- $hour, $min, $sec);
-}
-
-sub mail_notification {
- local(@text) = @_;
-
- # if only we had strftime()... stuff stolen from perl's ctime.pl:
- local($[) = 0;
-
- @DoW = ('Sun','Mon','Tue','Wed','Thu','Fri','Sat');
- @MoY = ('Jan','Feb','Mar','Apr','May','Jun',
- 'Jul','Aug','Sep','Oct','Nov','Dec');
-
- # Determine what time zone is in effect.
- # Use GMT if TZ is defined as null, local time if TZ undefined.
- # There's no portable way to find the system default timezone.
- #
- $TZ = defined($ENV{'TZ'}) ? ( $ENV{'TZ'} ? $ENV{'TZ'} : 'GMT' ) : '';
-
- # Hack to deal with 'PST8PDT' format of TZ
- # Note that this can't deal with all the esoteric forms, but it
- # does recognize the most common: [:]STDoff[DST[off][,rule]]
- #
- if ($TZ =~ /^([^:\d+\-,]{3,})([+-]?\d{1,2}(:\d{1,2}){0,2})([^\d+\-,]{3,})?/) {
- $TZ = $isdst ? $4 : $1;
- $tzoff = sprintf("%05d", -($2) * 100);
- }
-
- # perl-4.036 doesn't have the $zone or $gmtoff...
- ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst, $zone, $gmtoff) =
- ($TZ eq 'GMT') ? gmtime(time) : localtime(time);
-
- $year += ($year < 70) ? 2000 : 1900;
-
- if ($gmtoff != 0) {
- $tzoff = sprintf("%05d", ($gmtoff / 60) * 100);
- }
- if ($zone ne '') {
- $TZ = $zone;
- }
-
- # ok, let's try....
- $rfc822date = sprintf("%s, %2d %s %4d %2d:%02d:%02d %s (%s)",
- $DoW[$wday], $mday, $MoY[$mon], $year,
- $hour, $min, $sec, $tzoff, $TZ);
-
- open(MAIL, "| $MAILER");
- print MAIL "Date: " . $rfc822date . "\n";
- print MAIL "Subject: CVS Update: " . $modulename . "\n";
- print MAIL "To: " . $mailto . "\n";
- print MAIL "Reply-To: " . $replyto . "\n";
- print MAIL "\n";
- print MAIL join("\n", @text), "\n";
- close(MAIL);
-}
-
-sub write_commitlog {
- local($logfile, @text) = @_;
-
- open(FILE, ">>$logfile");
- print FILE join("\n", @text), "\n";
- close(FILE);
-}
-
-#
-# Main Body
-#
-
-# Initialize basic variables
-#
-$debug = 0;
-$id = getpgrp(); # note, you *must* use a shell which does setpgrp()
-$state = $STATE_NONE;
-chop($hostname = `hostname`);
-chop($domainname = `domainname`);
-if ($domainname !~ '^\..*') {
- $domainname = '.' . $domainname;
-}
-$hostdomain = $hostname . $domainname;
-$cvsroot = $ENV{'CVSROOT'};
-$do_status = 1; # moderately useful
-$show_wd = 0; # useless in client/server
-$modulename = "";
-
-# parse command line arguments (file list is seen as one arg)
-#
-while (@ARGV) {
- $arg = shift @ARGV;
-
- if ($arg eq '-d') {
- $debug = 1;
- print STDERR "Debug turned on...\n";
- } elsif ($arg eq '-m') {
- if ($mailto eq '') {
- $mailto = shift @ARGV;
- } else {
- $mailto = $mailto . ", " . shift @ARGV;
- }
- } elsif ($arg eq '-R') {
- if ($replyto eq '') {
- $replyto = shift @ARGV;
- } else {
- $replyto = $replyto . ", " . shift @ARGV;
- }
- } elsif ($arg eq '-M') {
- $modulename = shift @ARGV;
- } elsif ($arg eq '-u') {
- $login = shift @ARGV;
- } elsif ($arg eq '-s') {
- $do_status = 0;
- } elsif ($arg eq '-w') {
- $show_wd = 1;
- } elsif ($arg eq '-f') {
- ($commitlog) && die("Too many '-f' args\n");
- $commitlog = shift @ARGV;
- } else {
- ($donefiles) && die("Too many arguments! Check usage.\n");
- $donefiles = 1;
- @files = split(/ /, $arg);
- }
-}
-if ($login eq '') {
- $login = getlogin || (getpwuid($<))[0] || "nobody";
-}
-($mailto) || die("No mail recipient specified (use -m)\n");
-if ($replyto eq '') {
- $replyto = $login;
-}
-
-# for now, the first "file" is the repository directory being committed,
-# relative to the $CVSROOT location
-#
-@path = split('/', $files[0]);
-
-# XXX There are some ugly assumptions in here about module names and
-# XXX directories relative to the $CVSROOT location -- really should
-# XXX read $CVSROOT/CVSROOT/modules, but that's not so easy to do, since
-# XXX we have to parse it backwards.
-# XXX
-# XXX Fortunately it's relatively easy for the user to specify the
-# XXX module name as appropriate with a '-M' via the directory
-# XXX matching in loginfo.
-#
-if ($modulename eq "") {
- $modulename = $path[0]; # I.e. the module name == top-level dir
-}
-if ($#path == 0) {
- $dir = ".";
-} else {
- $dir = join('/', @path);
-}
-$dir = $dir . "/";
-
-if ($debug) {
- print STDERR "module - ", $modulename, "\n";
- print STDERR "dir - ", $dir, "\n";
- print STDERR "path - ", join(":", @path), "\n";
- print STDERR "files - ", join(":", @files), "\n";
- print STDERR "id - ", $id, "\n";
-}
-
-# Check for a new directory first. This appears with files set as follows:
-#
-# files[0] - "path/name/newdir"
-# files[1] - "-"
-# files[2] - "New"
-# files[3] - "directory"
-#
-if ($files[2] =~ /New/ && $files[3] =~ /directory/) {
- local(@text);
-
- @text = ();
- push(@text, &build_header());
- push(@text, "");
- push(@text, $files[0]);
- push(@text, "");
-
- while (<STDIN>) {
- chop; # Drop the newline
- push(@text, $_);
- }
-
- &mail_notification($mailto, @text);
-
- exit 0;
-}
-
-# Check for an import command. This appears with files set as follows:
-#
-# files[0] - "path/name"
-# files[1] - "-"
-# files[2] - "Imported"
-# files[3] - "sources"
-#
-if ($files[2] =~ /Imported/ && $files[3] =~ /sources/) {
- local(@text);
-
- @text = ();
- push(@text, &build_header());
- push(@text, "");
- push(@text, $files[0]);
- push(@text, "");
-
- while (<STDIN>) {
- chop; # Drop the newline
- push(@text, $_);
- }
-
- &mail_notification(@text);
-
- exit 0;
-}
-
-# Iterate over the body of the message collecting information.
-#
-while (<STDIN>) {
- chop; # Drop the newline
-
- if (/^In directory/) {
- if ($show_wd) { # useless in client/server mode
- push(@log_lines, $_);
- push(@log_lines, "");
- }
- next;
- }
-
- if (/^Modified Files/) { $state = $STATE_CHANGED; next; }
- if (/^Added Files/) { $state = $STATE_ADDED; next; }
- if (/^Removed Files/) { $state = $STATE_REMOVED; next; }
- if (/^Log Message/) { $state = $STATE_LOG; next; }
-
- s/^[ \t\n]+//; # delete leading whitespace
- s/[ \t\n]+$//; # delete trailing whitespace
-
- if ($state == $STATE_CHANGED) { push(@changed_files, split); }
- if ($state == $STATE_ADDED) { push(@added_files, split); }
- if ($state == $STATE_REMOVED) { push(@removed_files, split); }
- if ($state == $STATE_LOG) { push(@log_lines, $_); }
-}
-
-# Strip leading and trailing blank lines from the log message. Also
-# compress multiple blank lines in the body of the message down to a
-# single blank line.
-#
-while ($#log_lines > -1) {
- last if ($log_lines[0] ne "");
- shift(@log_lines);
-}
-while ($#log_lines > -1) {
- last if ($log_lines[$#log_lines] ne "");
- pop(@log_lines);
-}
-for ($i = $#log_lines; $i > 0; $i--) {
- if (($log_lines[$i - 1] eq "") && ($log_lines[$i] eq "")) {
- splice(@log_lines, $i, 1);
- }
-}
-
-if ($debug) {
- print STDERR "Searching for log file index...";
-}
-# Find an index to a log file that matches this log message
-#
-for ($i = 0; ; $i++) {
- local(@text);
-
- last if (! -e "$LOG_FILE.$i.$id"); # the next available one
- @text = &read_logfile("$LOG_FILE.$i.$id", "");
- last if ($#text == -1); # nothing in this file, use it
- last if (join(" ", @log_lines) eq join(" ", @text)); # it's the same log message as another
-}
-if ($debug) {
- print STDERR " found log file at $i.$id, now writing tmp files.\n";
-}
-
-# Spit out the information gathered in this pass.
-#
-&append_names_to_file("$CHANGED_FILE.$i.$id", $dir, @changed_files);
-&append_names_to_file("$ADDED_FILE.$i.$id", $dir, @added_files);
-&append_names_to_file("$REMOVED_FILE.$i.$id", $dir, @removed_files);
-&write_logfile("$LOG_FILE.$i.$id", @log_lines);
-
-# Check whether this is the last directory. If not, quit.
-#
-if ($debug) {
- print STDERR "Checking current dir against last dir.\n";
-}
-$_ = &read_line("$LAST_FILE.$id");
-
-if ($_ ne $cvsroot . "/" . $files[0]) {
- if ($debug) {
- print STDERR sprintf("Current directory %s is not last directory %s.\n", $cvsroot . "/" .$files[0], $_);
- }
- exit 0;
-}
-if ($debug) {
- print STDERR sprintf("Current directory %s is last directory %s -- all commits done.\n", $files[0], $_);
-}
-
-#
-# End Of Commits!
-#
-
-# This is it. The commits are all finished. Lump everything together
-# into a single message, fire a copy off to the mailing list, and drop
-# it on the end of the Changes file.
-#
-
-#
-# Produce the final compilation of the log messages
-#
-@text = ();
-@status_txt = ();
-push(@text, &build_header());
-push(@text, "");
-
-for ($i = 0; ; $i++) {
- last if (! -e "$LOG_FILE.$i.$id"); # we're done them all!
- @lines = &read_logfile("$CHANGED_FILE.$i.$id", "");
- if ($#lines >= 0) {
- push(@text, "Modified files:");
- push(@text, &format_lists(@lines));
- }
- @lines = &read_logfile("$ADDED_FILE.$i.$id", "");
- if ($#lines >= 0) {
- push(@text, "Added files:");
- push(@text, &format_lists(@lines));
- }
- @lines = &read_logfile("$REMOVED_FILE.$i.$id", "");
- if ($#lines >= 0) {
- push(@text, "Removed files:");
- push(@text, &format_lists(@lines));
- }
- if ($#text >= 0) {
- push(@text, "");
- }
- @lines = &read_logfile("$LOG_FILE.$i.$id", "\t");
- if ($#lines >= 0) {
- push(@text, "Log message:");
- push(@text, @lines);
- push(@text, "");
- }
- if ($do_status) {
- local(@changed_files);
-
- @changed_files = ();
- push(@changed_files, &read_logfile("$CHANGED_FILE.$i.$id", ""));
- push(@changed_files, &read_logfile("$ADDED_FILE.$i.$id", ""));
- push(@changed_files, &read_logfile("$REMOVED_FILE.$i.$id", ""));
-
- if ($debug) {
- print STDERR "main: pre-sort changed_files = ", join(":", @changed_files), ".\n";
- }
- sort(@changed_files);
- if ($debug) {
- print STDERR "main: post-sort changed_files = ", join(":", @changed_files), ".\n";
- }
-
- foreach $dofile (@changed_files) {
- if ($dofile =~ /\/$/) {
- next; # ignore the silly "dir" entries
- }
- if ($debug) {
- print STDERR "main(): doing 'cvs -nQq status -v $dofile'\n";
- }
- open(STATUS, "-|") || exec 'cvs', '-nQq', 'status', '-v', $dofile;
- while (<STATUS>) {
- chop;
- push(@status_txt, $_);
- }
- }
- }
-}
-
-# Write to the commitlog file
-#
-if ($commitlog) {
- &write_commitlog($commitlog, @text);
-}
-
-if ($#status_txt >= 0) {
- push(@text, @status_txt);
-}
-
-# Mailout the notification.
-#
-&mail_notification(@text);
-
-# cleanup
-#
-if (! $debug) {
- &cleanup_tmpfiles();
-}
-
-exit 0;
diff --git a/contrib/cvs/contrib/mfpipe.pl b/contrib/cvs/contrib/mfpipe.pl
deleted file mode 100644
index c74d71564908..000000000000
--- a/contrib/cvs/contrib/mfpipe.pl
+++ /dev/null
@@ -1,85 +0,0 @@
-#! xPERL_PATHx
-# -*-Perl-*-
-#
-# From: clyne@niwot.scd.ucar.EDU (John Clyne)
-# Date: Fri, 28 Feb 92 09:54:21 MST
-#
-# BTW, i wrote a perl script that is similar to 'nfpipe' except that in
-# addition to logging to a file it provides a command line option for mailing
-# change notices to a group of users. Obviously you probably wouldn't want
-# to mail every change. But there may be certain directories that are commonly
-# accessed by a group of users who would benefit from an email notice.
-# Especially if they regularly beat on the same directory. Anyway if you
-# think anyone would be interested here it is.
-#
-# File: mfpipe
-#
-# Author: John Clyne
-# National Center for Atmospheric Research
-# PO 3000, Boulder, Colorado
-#
-# Date: Wed Feb 26 18:34:53 MST 1992
-#
-# Description: Tee standard input to mail a list of users and to
-# a file. Used by CVS logging.
-#
-# Usage: mfpipe [-f file] [user@host...]
-#
-# Environment: CVSROOT
-# Path to CVS root.
-#
-# Files:
-#
-#
-# Options: -f file
-# Capture output to 'file'
-#
-
-$header = "Log Message:\n";
-
-$mailcmd = "| mail -s 'CVS update notice'";
-$whoami = `whoami`;
-chop $whoami;
-$date = `date`;
-chop $date;
-
-$cvsroot = $ENV{'CVSROOT'};
-
-while (@ARGV) {
- $arg = shift @ARGV;
-
- if ($arg eq '-f') {
- $file = shift @ARGV;
- }
- else {
- $users = "$users $arg";
- }
-}
-
-if ($users) {
- $mailcmd = "$mailcmd $users";
- open(MAIL, $mailcmd) || die "Execing $mail: $!\n";
-}
-
-if ($file) {
- $logfile = "$cvsroot/LOG/$file";
- open(FILE, ">> $logfile") || die "Opening $logfile: $!\n";
-}
-
-print FILE "$whoami $date--------BEGIN LOG ENTRY-------------\n" if ($logfile);
-
-while (<>) {
- print FILE $log if ($log && $logfile);
-
- print FILE $_ if ($logfile);
- print MAIL $_ if ($users);
-
- $log = "log: " if ($_ eq $header);
-}
-
-close FILE;
-die "Write failed" if $?;
-close MAIL;
-die "Mail failed" if $?;
-
-exit 0;
diff --git a/contrib/cvs/contrib/pvcs_to_rcs b/contrib/cvs/contrib/pvcs_to_rcs
deleted file mode 100644
index 7d526d81ad21..000000000000
--- a/contrib/cvs/contrib/pvcs_to_rcs
+++ /dev/null
@@ -1,439 +0,0 @@
-#! /opt/bin/perl5
-#
-# Beware of the fact that this script was not written to handle
-# branches in the PVCS archives, but it might work nontheless. I have
-# a specific addition in this latest version that would not be
-# globally useful: automatically making Framemaker files binary with
-# -kb (regardless of the file extension).
-# ---------------------------------
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2, or (at your option)
-# any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-
-###########################################################################
-# FUNCTION:
-# To recursively walk through a PVCS archive directory tree (archives
-# located in VCS/ or vcs/ subdirectories) and convert them to RCS archives.
-# The RCS archive name is the PVCS workfile name with ",v" appended.
-#
-# SYNTAX:
-# The calling syntax is:
-# pvcs_to_rcs [-l]
-#
-# where -l indicates the operation is to be performed only in the current
-# directory (no recursion)
-#
-# EXAMPLE:
-# pvcs_to_rcs
-#
-# Would walk through every VCS or vcs subdir starting at the current directory,
-# and produce corresponding RCS archives one level above the VCS or vcs subdir.
-#
-# NOTES:
-# * This script does not perform any error checking or logging of any kind
-# (i.e. USE AT YOUR OWN RISK)
-# * This script was developed using perl-5.003 on a Sun Solaris 2.5 machine
-# and executed from a csh
-# * PVCS archives in VCS/ or vcs/ subdirectories are left intact
-# * RCS archives are processed in the VCS/ or vcs/ subdirectories and
-# are moved (forcibly) up one level upon completion of the conversion
-# * This script has *not* been tested with PVCS archives with branches,
-# although the only thing I believe that might need to be changed
-# is the ORDER of revision processing (e.g. you can't checkin 1.2.4.1 if
-# you haven't yet checked in 1.2).
-# * All revisions are saved with correct "metadata" (i.e. check-in date,
-# author, and log message). Any blank log message is replaced with
-# "no comment". This is because RCS does not allow non-interactive
-# checkin of a new revision without a comment string.
-# * Revision numbers are incremented by 1 during the conversion (since
-# RCS does not allow revision 1.0).
-# * Version labels are assigned to the appropriate (incremented) revision
-# numbers. PVCS allows spaces and periods in version labels while RCS
-# does not. A global search and replace converts " " and "." to "_"
-# There may be other cases that ought to be added.
-# * Any workfile within the VCS/ or vcs/ will be deleted (or overwritten)
-# since it is used in the checkout of each revision
-# * Locks on PVCS archives should be removed (or the workfiles should be
-# checked-in) prior to conversion, although the script will blaze through
-# the archive nonetheless (But you would lose any checked out revision(s))
-# * The -kb option is added to the RCS archive for workfiles with the following
-# extensions: .bin .out .btl .rom .a07 .lib .exe .tco .obj .t8u .c8u .o .lku
-#########################################################################
-
-require("getcwd.pl");
-
-#NOTE: Each possible binary extension is delimited by '.'
-$bin_ext =
-".bin.out.btl.rom.a07.lib.exe.tco.obj.t8u.c8u.o.lku.BIN.OUT.BTL.ROM.A07.LIB.EXE.TCO.OBJ
-.T8U.C8U.O.LKU.";
-
-# the main procedure that is run once in each directory
-sub execdir
-{
- $curlevel= $curlevel +1;
-
-#local sets the variables directory and prev directory local to the procedure
-
- local($dir,$prevdir)=@_;
-
-#change into the directory to be processed
-
- chdir($dir);
-
-#open the current directory for listing
-
- opendir(CURDIR,".");
-
-#initialize the list of filenames
-
- local(@filenames);
-
-#set filenames equal to directory listing
-
- @filenames = readdir(CURDIR);
-
-#clean up by closing the directory
-
- closedir(CURDIR);
-
-#initialize a list for any subdirectories
- local(@subdirs);
-
-#begin a for loop to execute on each filename in the list @filename
- for (@filenames)
-
- {
-#if the file is a directory...
- if (-d $_)
- {
-#include it in @subdir
- push(@subdirs,$_);
- }
- }
-
-#for loop of subdirs
- for (@subdirs)
-#if not a parent directory, run execdir on each sub dir
- {
- if (($_ ne '.') and ($_ ne '..') and ($maxlevel > $curlevel))
- {
- &execdir($_,$dir);
- }
- }
-
-#save the current directory
- $cd = &getcwd;
-
-#Print output header for each directory
- print("Directory: $cd\n");
-
-#determine the last directory in this path (to only process vcs or VCS)
- $_ = $cd;
- $num_dirs = split /\//;
- @dirs = @_;
- $last_dir = $dirs[$num_dirs-1];
-# print"Last directory is $last_dir\n";
-
-#shell redirection: output from command in @ARGV is put in $output
-# $output = `@ARGV`;
-#begin a for loop to execute on each filename in the list @filename
- for (@filenames)
- {
- if ( (-f $_) and ($_ ne '.') and ($_ ne '..') and ($maxlevel > $curlevel)
- and ( ( $last_dir eq 'vcs' ) or ( $last_dir eq 'VCS' ) ) )
- {
- $got_archivefile = 0;
- $got_workfile = 0;
- $got_version_labels = 0;
- $got_description = 0;
- $got_rev_count = 0;
-
- $file = $_;
- $abs_file = $cd . "/" . $file;
- print("Converting $abs_file...\n");
- $vlog_output = `vlog $_`;
- $_ = $vlog_output;
-# Split the cvs status output into individual lines
- @vlog_strings = split /\n/;
- $num_vlog_strings = @vlog_strings;
- $_ = $vlog_string[0];
- if ( /^vlog: warning/ )
- {
- print("$abs_file is NOT a valid PVCS archive!!!\n");
- }
- elsif( $vlog_output )
- {
-
-# Collect all vlog output into appropriate variables
-
- $num = 0;
- while( $num < $num_vlog_strings )
- {
-# print("$vlog_strings[$num]\n");
-
- $_ = $vlog_strings[$num];
-
- if( ( /^Workfile:\s*/ ) && (!$got_workfile ) )
- {
- $got_workfile = 1;
-# get the string to the right of the above search (with any path stripped)
- $workfile = $';
- $_=$workfile;
- $num_fields = split /\//;
- if ( $num_fields > 1 )
- {
- $workfile = $_[$num_fields - 1 ];
- }
-# print"Workfile is $workfile\n";
- }
-
- elsif( ( /^Archive:\s*/ ) && (!$got_archivefile ) )
- {
- $got_archivefile = 1;
-# get the string to the right of the above search (with any path stripped)
- $archivefile = $';
- $_=$archivefile;
- $num_fields = split /\//;
- if ( $num_fields > 1 )
- {
- $archivefile = $_[$num_fields - 1 ];
- }
-# print"Archive is $archivefile\n";
- }
-
- elsif ( ( /^Rev count:\s*/ ) && (!$got_rev_count ) )
- {
- $got_rev_count = 1;
-# get the string to the right of the above search
- $rev_count = $';
- print"Revision count is $rev_count\n";
- }
-
- elsif ( ( /^Version labels:\s*/ ) && (!$got_version_labels ) )
- {
- $got_version_labels = 1;
- $first_vl = $num+1;
- }
-
- elsif ( ( /^Description:\s*/ ) && (!$got_description ) )
- {
- $got_description = 1;
- $description = "\"" . $vlog_strings[$num+1] . "\"";
-# print"Description is $description\n";
- $last_vl = $num - 1;
- }
-
- elsif ( /^Rev\s*/ ) # get all the revision information at once
- {
- $rev_index = 0;
- while ( $rev_index < $rev_count )
- {
- $_=$vlog_strings[$num];
- /^Rev\s*/;
- $rev_num[$rev_index] = $';
- $_=$vlog_strings[$num+1];
- if ( /^Locked\s*/ )
- {
- $num += 1;
- }
- $_=$vlog_strings[$num+1];
- /^Checked in:\s*/;
- $checked_in[$rev_index] = "\"" . $' . "\"";
- $_=$vlog_strings[$num+3];
- /^Author id:\s*/;
- split;
- $author[$rev_index] = "\"" . $_[2] . "\"";
- $relative_comment_index = 0;
- $comment_string = "";
- while( ( $vlog_strings[$num+4+$relative_comment_index] ne
- "-----------------------------------" ) &&
- ( $vlog_strings[$num+4+$relative_comment_index] ne
- "===================================" ) )
- {
-# We need the \n added for multi-line comments. There is no effect for
-# single-line comments since RCS inserts the \n if it doesn't exist already
- $comment_string = $comment_string .
-$vlog_strings[$num+4+$relative_comment_index] . "\n";
- $relative_comment_index += 1;
- }
-# Convert any double quotes to an escaped double quote
- $comment_string =~ s/\"/\\\"/g;
- $comment[$rev_index] = "\"" . $comment_string . "\"";
- $num += ( 5 + $relative_comment_index );
- $rev_index += 1;
- }
- $num -= 1; #although there should be nothing left for this to matter
- }
-
- $num += 1;
-
- }
-
-# Loop through each version label, checking for need to relabel ' ' with '_'.
- $num_version_labels = $last_vl - $first_vl + 1;
- print"Version label count is $num_version_labels\n";
- for( $i = $first_vl; $i <= $last_vl; $i += 1 )
- {
-# print("$vlog_strings[$i]\n");
- $label_index = $i - $first_vl;
- $_=$vlog_strings[$i];
- split /\"/;
- $label = @_[1];
- $_=@_[2];
- split;
- $label_revision[$label_index] = @_[1];
-
-# Create RCS revision numbers corresponding to PVCS version numbers by
-# adding 1 to the revision number (# after last .)
- $rcs_rev = &pvcs_to_rcs_rev_number( $label_revision[$label_index]);
- $label_revision[ $label_index ] = $rcs_rev;
-# replace ' ' with '_', if needed
- $_=$label;
- $new_label[$label_index] = $label;
- $new_label[$label_index] =~ s/ /_/g;
- $new_label[$label_index] =~ s/\./_/g;
- $new_label[$label_index] = "\"" . $new_label[$label_index] . "\"";
-# print"Label $new_label[$label_index] is for revision
-$label_revision[$label_index]\n";
- }
-
-# Create RCS revision numbers corresponding to PVCS version numbers by
-# adding 1 to the revision number (# after last .)
-
- for( $i = 0; $i < $rev_count; $i += 1 )
- {
- $rcs_rev_num[ $i ] = &pvcs_to_rcs_rev_number( $rev_num[ $i ] );
-# print"PVCS is $rev_num[ $i ]; RCS is $rcs_rev_num[ $i ]\n"
- }
-
-# Create RCS archive and check in all revisions, then label.
-# PVCS vlog lists revisions last-revision-first; reverse that ordering
- $first_time = 1;
-
- for( $i = $rev_count - 1; $i >= 0; $i -= 1 )
- {
- print "get -r$rev_num[$i] $archivefile\\($workfile\\)\n";
-# $vcs_output = `vcs -u -r$rev_num[$i] $file`;
- $get_output = `get -r$rev_num[$i] $archivefile\\($workfile\\)`;
- if( $first_time )
- {
- $first_time = 0;
- $file_output = `file $workfile`;
-# If an empty comment is specified, RCS will not check in the file;
-# check for this case. (but an empty -t- description is fine - go figure!)
-# Since RCS will pause and ask for a comment if one is not given,
-# substitute a dummy comment "no comment".
- if ( $comment[$i] eq "\"\"" )
- {
- $ci_command = "ci -f -r$rcs_rev_num[$i] -d$checked_in[$i] -w$author[$i]
--t-$description -m\"no comment\" $workfile";
- }
- else
- {
- $ci_command = "ci -f -r$rcs_rev_num[$i] -d$checked_in[$i] -w$author[$i]
--t-$description -m$comment[$i] $workfile";
- }
- print "$ci_command\n";
- $ci_output = `$ci_command`;
-
-# Also check here whether this file ought to be "binary"
- $_=$file_output;
- split;
- if( $_[1] eq "Frame" )
- {
- print"Binary attribute -kb added (file type is Frame)\n";
- $rcs_output = `rcs -kb $workfile,v`;
- }
- else
- {
- $_=$workfile;
- $num_fields = split /\./;
- if ( $num_fields > 1 )
- {
- $ext = "." . $_[$num_fields - 1] . ".";
- if ( ( index $bin_ext, $ext ) > - 1 )
- {
- print"Binary attribute -kb added (file type is $ext)\n";
- $rcs_output = `rcs -kb $workfile,v`;
- }
- }
- }
- }
- else
- {
- $rcs_output = `rcs -l $workfile`;
-# If an empty comment is specified, RCS will not check in the file;
-# check for this case. (but an empty -t- description is fine - go figure!)
- if ( $comment[$i] eq "\"\"" )
- {
- $ci_command = "ci -f -r$rcs_rev_num[$i] -d$checked_in[$i] -w$author[$i]
--m\"no comment\" $workfile";
- }
- else
- {
- $ci_command = "ci -f -r$rcs_rev_num[$i] -d$checked_in[$i] -w$author[$i]
--m$comment[$i] $workfile";
- }
- print "$ci_command\n";
- $ci_output = `$ci_command`;
- }
- }
-# Attach version labels
- for( $i = $num_version_labels - 1; $i >= 0; $i -= 1 )
- {
-# print "rcs -n$new_label[$i]:$label_revision[$i] $workfile\n";
- $rcs_output = `rcs -n$new_label[$i]:$label_revision[$i] $workfile`;
- print "Version label $new_label[$i] added to revision $label_revision[$i]\n";
- }
-
-# Move archive file up one directory level (above vcs/ or VCS/)
- $mv_output = `mv -f $workfile",v" ..`;
- }
- }
- }
-
-#print the output to STDOUT
-# print("$output");
-
- $curlevel=$curlevel - 1;
- if ($dir ne $prevdir)
- {
- chdir('..');
- }
-}
-
-sub pvcs_to_rcs_rev_number
-{
- local($input, $num_fields, @rev_string, $return_rev_num, $i);
-
- $input = @_[0];
- $_ = $input;
- $num_fields = split /\./;
- @rev_string = @_;
- @rev_string[$num_fields-1] += 1;
- $return_rev_num = @rev_string[ 0 ];
- for( $i = 1; $i < $num_fields; $i += 1 )
- {
- $return_rev_num = $return_rev_num . "." . @rev_string[ $i ];
- }
- return $return_rev_num;
-}
-
-##MAIN program: checks to see if there are command line parameters
-if ($#ARGV > 2) {
-
-#if not then end and print help message
-die "Usage: pvcsns [-l]\n"};
-$curlevel=0-1;$maxlevel=10000;
-
-if (@ARGV[0] eq "-l") {$maxlevel=1;shift @ARGV;}
-
-#start the whole thing
-&execdir(".",".");
-
diff --git a/contrib/cvs/contrib/rcslock.pl b/contrib/cvs/contrib/rcslock.pl
deleted file mode 100644
index 01e349ff0258..000000000000
--- a/contrib/cvs/contrib/rcslock.pl
+++ /dev/null
@@ -1,235 +0,0 @@
-#! xPERL_PATHx
-# -*-Perl-*-
-
-# Author: John Rouillard (rouilj@cs.umb.edu)
-# Supported: Yeah right. (Well what do you expect for 2 hours work?)
-# Blame-to: rouilj@cs.umb.edu
-# Complaints to: Anybody except Brian Berliner, he's blameless for
-# this script.
-# Acknowlegements: The base code for this script has been acquired
-# from the log.pl script.
-
-# rcslock.pl - A program to prevent commits when a file to be ckecked
-# in is locked in the repository.
-
-# There are times when you need exclusive access to a file. This
-# often occurs when binaries are checked into the repository, since
-# cvs's (actually rcs's) text based merging mechanism won't work. This
-# script allows you to use the rcs lock mechanism (rcs -l) to make
-# sure that no changes to a repository are able to be committed if
-# those changes would result in a locked file being changed.
-
-# WARNING:
-# This script will work only if locking is set to strict.
-#
-
-# Setup:
-# Add the following line to the commitinfo file:
-
-# ALL /local/location/for/script/lockcheck [options]
-
-# Where ALL is replaced by any suitable regular expression.
-# Options are -v for verbose info, or -d for debugging info.
-# The %s will provide the repository directory name and the names of
-# all changed files.
-
-# Use:
-# When a developer needs exclusive access to a version of a file, s/he
-# should use "rcs -l" in the repository tree to lock the version they
-# are working on. CVS will automagically release the lock when the
-# commit is performed.
-
-# Method:
-# An "rlog -h" is exec'ed to give info on all about to be
-# committed files. This (header) information is parsed to determine
-# if any locks are outstanding and what versions of the file are
-# locked. This filename, version number info is used to index an
-# associative array. All of the files to be committed are checked to
-# see if any locks are outstanding. If locks are outstanding, the
-# version number of the current file (taken from the CVS/Entries
-# subdirectory) is used in the key to determine if that version is
-# locked. If the file being checked in is locked by the person doing
-# the checkin, the commit is allowed, but if the lock is held on that
-# version of a file by another person, the commit is not allowed.
-
-$ext = ",v"; # The extension on your rcs files.
-
-$\="\n"; # I hate having to put \n's at the end of my print statements
-$,=' '; # Spaces should occur between arguments to print when printed
-
-# turn off setgid
-#
-$) = $(;
-
-#
-# parse command line arguments
-#
-require 'getopts.pl';
-
-&Getopts("vd"); # verbose or debugging
-
-# Verbose is useful when debugging
-$opt_v = $opt_d if defined $opt_d;
-
-# $files[0] is really the name of the subdirectory.
-# @files = split(/ /,$ARGV[0]);
-@files = @ARGV[0..$#ARGV];
-$cvsroot = $ENV{'CVSROOT'};
-
-#
-# get login name
-#
-$login = getlogin || (getpwuid($<))[0] || "nobody";
-
-#
-# save the current directory since we have to return here to parse the
-# CVS/Entries file if a lock is found.
-#
-$pwd = `/bin/pwd`;
-chop $pwd;
-
-print "Starting directory is $pwd" if defined $opt_d ;
-
-#
-# cd to the repository directory and check on the files.
-#
-print "Checking directory ", $files[0] if defined $opt_v ;
-
-if ( $files[0] =~ /^\// )
-{
- print "Directory path is $files[0]" if defined $opt_d ;
- chdir $files[0] || die "Can't change to repository directory $files[0]" ;
-}
-else
-{
- print "Directory path is $cvsroot/$files[0]" if defined $opt_d ;
- chdir ($cvsroot . "/" . $files[0]) ||
- die "Can't change to repository directory $files[0] in $cvsroot" ;
-}
-
-
-# Open the rlog process and apss all of the file names to that one
-# process to cut down on exec overhead. This may backfire if there
-# are too many files for the system buffer to handle, but if there are
-# that many files, chances are that the cvs repository is not set up
-# cleanly.
-
-print "opening rlog -h @files[1..$#files] |" if defined $opt_d;
-
-open( RLOG, "rlog -h @files[1..$#files] |") || die "Can't run rlog command" ;
-
-# Create the locks associative array. The elements in the array are
-# of two types:
-#
-# The name of the RCS file with a value of the total number of locks found
-# for that file,
-# or
-#
-# The name of the rcs file concatenated with the version number of the lock.
-# The value of this element is the name of the locker.
-
-# The regular expressions used to split the rcs info may have to be changed.
-# The current ones work for rcs 5.6.
-
-$lock = 0;
-
-while (<RLOG>)
-{
- chop;
- next if /^$/; # ditch blank lines
-
- if ( $_ =~ /^RCS file: (.*)$/ )
- {
- $curfile = $1;
- next;
- }
-
- if ( $_ =~ /^locks: strict$/ )
- {
- $lock = 1 ;
- next;
- }
-
- if ( $lock )
- {
- # access list: is the line immediately following the list of locks.
- if ( /^access list:/ )
- { # we are done getting lock info for this file.
- $lock = 0;
- }
- else
- { # We are accumulating lock info.
-
- # increment the lock count
- $locks{$curfile}++;
- # save the info on the version that is locked. $2 is the
- # version number $1 is the name of the locker.
- $locks{"$curfile" . "$2"} = $1
- if /[ ]*([a-zA-Z._]*): ([0-9.]*)$/;
-
- print "lock by $1 found on $curfile version $2" if defined $opt_d;
-
- }
- }
-}
-
-# Lets go back to the starting directory and see if any locked files
-# are ones we are interested in.
-
-chdir $pwd;
-
-# fo all of the file names (remember $files[0] is the directory name
-foreach $i (@files[1..$#files])
-{
- if ( defined $locks{$i . $ext} )
- { # well the file has at least one lock outstanding
-
- # find the base version number of our file
- &parse_cvs_entry($i,*entry);
-
- # is our version of this file locked?
- if ( defined $locks{$i . $ext . $entry{"version"}} )
- { # if so, it is by us?
- if ( $login ne ($by = $locks{$i . $ext . $entry{"version"}}) )
- {# crud somebody else has it locked.
- $outstanding_lock++ ;
- print "$by has file $i locked for version " , $entry{"version"};
- }
- else
- { # yeah I have it locked.
- print "You have a lock on file $i for version " , $entry{"version"}
- if defined $opt_v;
- }
- }
- }
-}
-
-exit $outstanding_lock;
-
-
-### End of main program
-
-sub parse_cvs_entry
-{ # a very simple minded hack at parsing an entries file.
-local ( $file, *entry ) = @_;
-local ( @pp );
-
-
-open(ENTRIES, "< CVS/Entries") || die "Can't open entries file";
-
-while (<ENTRIES>)
- {
- if ( $_ =~ /^\/$file\// )
- {
- @pp = split('/');
-
- $entry{"name"} = $pp[1];
- $entry{"version"} = $pp[2];
- $entry{"dates"} = $pp[3];
- $entry{"name"} = $pp[4];
- $entry{"name"} = $pp[5];
- $entry{"sticky"} = $pp[6];
- return;
- }
- }
-}
diff --git a/contrib/cvs/contrib/sccs2rcs.csh b/contrib/cvs/contrib/sccs2rcs.csh
deleted file mode 100644
index 15ebc9f63de1..000000000000
--- a/contrib/cvs/contrib/sccs2rcs.csh
+++ /dev/null
@@ -1,280 +0,0 @@
-#! xCSH_PATHx -f
-#
-# Sccs2rcs is a script to convert an existing SCCS
-# history into an RCS history without losing any of
-# the information contained therein.
-# It has been tested under the following OS's:
-# SunOS 3.5, 4.0.3, 4.1
-# Ultrix-32 2.0, 3.1
-#
-# Things to note:
-# + It will NOT delete or alter your ./SCCS history under any circumstances.
-#
-# + Run in a directory where ./SCCS exists and where you can
-# create ./RCS
-#
-# + /usr/local/bin is put in front of the default path.
-# (SCCS under Ultrix is set-uid sccs, bad bad bad, so
-# /usr/local/bin/sccs here fixes that)
-#
-# + Date, time, author, comments, branches, are all preserved.
-#
-# + If a command fails somewhere in the middle, it bombs with
-# a message -- remove what it's done so far and try again.
-# "rm -rf RCS; sccs unedit `sccs tell`; sccs clean"
-# There is no recovery and exit is far from graceful.
-# If a particular module is hanging you up, consider
-# doing it separately; move it from the current area so that
-# the next run will have a better chance or working.
-# Also (for the brave only) you might consider hacking
-# the s-file for simpler problems: I've successfully changed
-# the date of a delta to be in sync, then run "sccs admin -z"
-# on the thing.
-#
-# + After everything finishes, ./SCCS will be moved to ./old-SCCS.
-#
-# This file may be copied, processed, hacked, mutilated, and
-# even destroyed as long as you don't tell anyone you wrote it.
-#
-# Ken Cox
-# Viewlogic Systems, Inc.
-# kenstir@viewlogic.com
-# ...!harvard!cg-atla!viewlog!kenstir
-#
-# Various hacks made by Brian Berliner before inclusion in CVS contrib area.
-
-
-#we'll assume the user set up the path correctly
-# for the Pmax, /usr/ucb/sccs is suid sccs, what a pain
-# /usr/local/bin/sccs should override /usr/ucb/sccs there
-set path = (/usr/local/bin $path)
-
-
-############################################################
-# Error checking
-#
-if (! -w .) then
- echo "Error: ./ not writeable by you."
- exit 1
-endif
-if (! -d SCCS) then
- echo "Error: ./SCCS directory not found."
- exit 1
-endif
-set edits = (`sccs tell`)
-if ($#edits) then
- echo "Error: $#edits file(s) out for edit...clean up before converting."
- exit 1
-endif
-if (-d RCS) then
- echo "Warning: RCS directory exists"
- if (`ls -a RCS | wc -l` > 2) then
- echo "Error: RCS directory not empty
- exit 1
- endif
-else
- mkdir RCS
-endif
-
-sccs clean
-
-set logfile = /tmp/sccs2rcs_$$_log
-rm -f $logfile
-set tmpfile = /tmp/sccs2rcs_$$_tmp
-rm -f $tmpfile
-set emptyfile = /tmp/sccs2rcs_$$_empty
-echo -n "" > $emptyfile
-set initialfile = /tmp/sccs2rcs_$$_init
-echo "Initial revision" > $initialfile
-set sedfile = /tmp/sccs2rcs_$$_sed
-rm -f $sedfile
-set revfile = /tmp/sccs2rcs_$$_rev
-rm -f $revfile
-
-# the quotes surround the dollar signs to fool RCS when I check in this script
-set sccs_keywords = (\
- '%W%[ ]*%G%'\
- '%W%[ ]*%E%'\
- '%W%'\
- '%Z%%M%[ ]*%I%[ ]*%G%'\
- '%Z%%M%[ ]*%I%[ ]*%E%'\
- '%M%[ ]*%I%[ ]*%G%'\
- '%M%[ ]*%I%[ ]*%E%'\
- '%M%'\
- '%I%'\
- '%G%'\
- '%E%'\
- '%U%')
-set rcs_keywords = (\
- '$'Id'$'\
- '$'Id'$'\
- '$'Id'$'\
- '$'SunId'$'\
- '$'SunId'$'\
- '$'Id'$'\
- '$'Id'$'\
- '$'RCSfile'$'\
- '$'Revision'$'\
- '$'Date'$'\
- '$'Date'$'\
- '')
-
-
-############################################################
-# Get some answers from user
-#
-echo ""
-echo "Do you want to be prompted for a description of each"
-echo "file as it is checked in to RCS initially?"
-echo -n "(y=prompt for description, n=null description) [y] ?"
-set ans = $<
-if ((_$ans == _) || (_$ans == _y) || (_$ans == _Y)) then
- set nodesc = 0
-else
- set nodesc = 1
-endif
-echo ""
-echo "The default keyword substitutions are as follows and are"
-echo "applied in the order specified:"
-set i = 1
-while ($i <= $#sccs_keywords)
-# echo ' '\"$sccs_keywords[$i]\"' ==> '\"$rcs_keywords[$i]\"
- echo " $sccs_keywords[$i] ==> $rcs_keywords[$i]"
- @ i = $i + 1
-end
-echo ""
-echo -n "Do you want to change them [n] ?"
-set ans = $<
-if ((_$ans != _) && (_$ans != _n) && (_$ans != _N)) then
- echo "You can't always get what you want."
- echo "Edit this script file and change the variables:"
- echo ' $sccs_keywords'
- echo ' $rcs_keywords'
-else
- echo "good idea."
-endif
-
-# create the sed script
-set i = 1
-while ($i <= $#sccs_keywords)
- echo "s,$sccs_keywords[$i],$rcs_keywords[$i],g" >> $sedfile
- @ i = $i + 1
-end
-
-onintr ERROR
-
-############################################################
-# Loop over every s-file in SCCS dir
-#
-foreach sfile (SCCS/s.*)
- # get rid of the "s." at the beginning of the name
- set file = `echo $sfile:t | sed -e "s/^..//"`
-
- # work on each rev of that file in ascending order
- set firsttime = 1
- sccs prs $file | grep "^D " | awk '{print $2}' | sed -e 's/\./ /g' | sort -n -u +0 +1 +2 +3 +4 +5 +6 +7 +8 | sed -e 's/ /./g' > $revfile
- foreach rev (`cat $revfile`)
- if ($status != 0) goto ERROR
-
- # get file into current dir and get stats
- set year = `echo $date | cut -c3-4`
- if ($year < 70) then
- # Y2K Bug, change century to 20
- set date = `echo $date | sed -e s/19/20/`
- endif
- set date = `sccs prs -r$rev $file | grep "^D " | awk '{printf("19%s %s", $3, $4); exit}'`
- set author = `sccs prs -r$rev $file | grep "^D " | awk '{print $5; exit}'`
- echo ""
- echo "==> file $file, rev=$rev, date=$date, author=$author"
- sccs edit -r$rev $file >>& $logfile
- if ($status != 0) goto ERROR
- echo checked out of SCCS
-
- # add RCS keywords in place of SCCS keywords
- sed -f $sedfile $file > $tmpfile
- if ($status != 0) goto ERROR
- echo performed keyword substitutions
- cp $tmpfile $file
-
- # check file into RCS
- if ($firsttime) then
- set firsttime = 0
- if ($nodesc) then
- echo about to do ci
- echo ci -f -r$rev -d"$date" -w$author -t$emptyfile $file
- ci -f -r$rev -d"$date" -w$author -t$emptyfile $file < $initialfile >>& $logfile
- if ($status != 0) goto ERROR
- echo initial rev checked into RCS without description
- else
- echo ""
- echo Enter a brief description of the file $file \(end w/ Ctrl-D\):
- cat > $tmpfile
- ci -f -r$rev -d"$date" -w$author -t$tmpfile $file < $initialfile >>& $logfile
- if ($status != 0) goto ERROR
- echo initial rev checked into RCS
- endif
- else
- # get RCS lock
- set lckrev = `echo $rev | sed -e 's/\.[0-9]*$//'`
- if ("$lckrev" =~ [0-9]*.*) then
- # need to lock the brach -- it is OK if the lock fails
- rcs -l$lckrev $file >>& $logfile
- else
- # need to lock the trunk -- must succeed
- rcs -l $file >>& $logfile
- if ($status != 0) goto ERROR
- endif
- echo got lock
- sccs prs -r$rev $file | grep "." > $tmpfile
- # it's OK if grep fails here and gives status == 1
- # put the delta message in $tmpfile
- ed $tmpfile >>& $logfile <<EOF
-/COMMENTS
-1,.d
-w
-q
-EOF
- ci -f -r$rev -d"$date" -w$author $file < $tmpfile >>& $logfile
- if ($status != 0) goto ERROR
- echo checked into RCS
- endif
- sccs unedit $file >>& $logfile
- if ($status != 0) goto ERROR
- end
- rm -f $file
-end
-
-
-############################################################
-# Clean up
-#
-echo cleaning up...
-mv SCCS old-SCCS
-rm -f $tmpfile $emptyfile $initialfile $sedfile
-echo ===================================================
-echo " Conversion Completed Successfully"
-echo ""
-echo " SCCS history now in old-SCCS/"
-echo ===================================================
-set exitval = 0
-goto cleanup
-
-ERROR:
-foreach f (`sccs tell`)
- sccs unedit $f
-end
-echo ""
-echo ""
-echo Danger\! Danger\!
-echo Some command exited with a non-zero exit status.
-echo Log file exists in $logfile.
-echo ""
-echo Incomplete history in ./RCS -- remove it
-echo Original unchanged history in ./SCCS
-set exitval = 1
-
-cleanup:
-# leave log file
-rm -f $tmpfile $emptyfile $initialfile $sedfile $revfile
-
-exit $exitval
diff --git a/contrib/cvs/doc/DIFFUTILS-2.7-BUG b/contrib/cvs/doc/DIFFUTILS-2.7-BUG
deleted file mode 100644
index f258ee7f6aae..000000000000
--- a/contrib/cvs/doc/DIFFUTILS-2.7-BUG
+++ /dev/null
@@ -1,263 +0,0 @@
-The enclosed two messages describe a bug in GNU diff 2.6 and 2.7 which
-may cause CVS to perform an erroneous merge. You may wish to use GNU
-diff 2.5 or apply the patch supplied by Loren James Rittle below. It
-would be nice to add this to the CVS testsuite, but I haven't done so
-because probably a lot of people who would like to run the testsuite
-are using the buggy diff.
-
-From: friedman@splode.com (Noah Friedman)
-To: bug-gnu-utils@prep.ai.mit.edu
-Cc: info-cvs@prep.ai.mit.edu
-Subject: diffutils 2.7 -- diff3 merge bug
-Date: Tue, 29 Oct 96 17:02:54 CST
-
-I believe a change first introduced in GNU diff 2.6 causes diff3 sometimes
-to produce incorrect merges.
-
-Since this is a not a bug in CVS itself but can cause commits to CVS
-repositories to be incorrect, am warning info-cvs@prep.ai.mit.edu as
-well as reporting the bug to bug-gnu-utils@prep.ai.mit.edu.
-
-I am including a simple test case as well as some sample outputs from
-different versions of `diff' and `diff3' in the enclosed shar archive.
-In addition, the file DESCRIPTION in that archive describes the problem
-more fully.
-
-If anyone has any advice for how to fix or to work around this bug, I would
-appreciate it. Using diff 2.5 seems like the most immediately obvious
-solution, but I don't know if it will introduce other problems.
-I do not understand the algorithms used by GNU diff well enough to suggest
-any patches.
-
-Unshar and enjoy. ;-)
-
-begin 666 merge-testcase.shar.gz
-M'XL(",&,=C("`VUE<F=E+71E<W1C87-E+G-H87(`[5Q[;]M&$O_[^"FF;E#9
-M@41)?C!GYX&V;MPS<$F+V+FZP.&:%;F26)-<E;NTHC[NL]_,+%^29;USUP-L
-M&)9$[CQW]C?#W;$^_ZS="Y.V'CJ?P_4PU("_`O101A&(U!^&=Q+V1ZD*,E\&
-MT)O`MV_?XVV19B:,-!R[W0.72!7(CR85O@$SE-`/(ZFAGZH8/Q)'RZD)6B"_
-M$`<IT"J6<''Y]]=-2&6L[B2RD7<RG2!%,H">[*M4,K</A8X-B,)$@N@IXH6W
-M$C"3$0[00^;40%60RQL12%`)=$]/O5:WTSH\A:YW=G(,YU?79,*+?AK*(!;)
-MEWH4J4"ZOHI?D157*DM]"4&82M^H=`)CH>%#.]-I.U*^B-HZ]=N#)&L'8;_/
-M#FC',AW(EI':^$++7('7'T-MR`CKAW&(SGR:*/,4K0+4/1VGH3&H?9;@?131
-M\AOD>#V2?MA'W2P;G@_R-?@J,2),]!E>C60R,$.(47&P/XF(R7DM_LE?9MXN
-M^T%R_#DZ]:"5CO-?F+:M7;QI3=!-VE(\ZQRM0A'CM%D"[_1X%0(5!3*U%,<G
-MAPLHWHA;25[FL8?=PV<+QG[S^NK\W>7WUY??O<U9=Q;92Y-\Z)Y87>I&>R>K
-MD)'-=:I5A'ESA!T_6X'LOK"3%52LYH?N!ZM,:2%P'FFW>[1HJJ[>OWGSU;L?
-M,;2-ROPAM$0,W<,C_#TY/3V%)T]<>_U5.Y!W[23#17/XZHNN$_:!>,!GT.K7
-M";[XPE['JP7M<P8%!WC5_,277O)?1T9:3E\_PX_2'ZK\!1H_?/7N[>7;;\\`
-M5RI"DD8$H#5LPAC?BWBD78!SE>@09P@&TO`*%TG0*#CLX0HU(HKH.L'D/S^P
-MI$83$46;-.QE!C$T3/CF!08MO$<,"4THM>NZ>X4^_=!)XQE;"P,9%U[6?Q:O
-MTNFQ+^N^#*`Q`UZE]ZP_/D(+_%0*MK/"Q!DB'![?XMU[W,B.0AP:TUBH9Z.<
-MS9N])]T]^.PEOFGY>W-4TK?A:$0J+39\GU`!1(0&!!-,3C@#^J!1Q$'%+D];
-M*S`T./2`[-4XBPW=_M=-N]V`%R^@<?6WK][]]/J[BP:\6L%.I]V&KS-C5.+^
-M+.Z$<^.,A'\K!A)2C"85NV(TBD(?_:Z2YW@WC$<J-<5-2CON4[H^RGHX#/Q(
-M8`JQ#)W?G!N`]E.XI$A,3"A0/.9S>Q<3$28.C.H!QN!^IPF=`XI?^%6F"N\%
-M>),^#F4X&!J7.,%3^%%E$&<X,9C_L"1(,'XQ8D44(A5ZS`Q50-D<2X213*-)
-M[3;G[MQ0RZQ-+[G:N4K[!W2-U4;'9L@#+Y%U?.$G$YI(GJM(I?`2^-7M1>BM
-MY_E]7%BB%\G@^OZX02HFS^ML+C")XEUZ<0/9%UED^!++`_C#^<,I)A(G^4D%
-M%1:I.H>GW9-##U/D"E,,X`\Q0T/'\Y:/__WW,B(M[&"1T%\2C7V!X<W0PWKZ
-M*DO,R[T/8Q]:/KQ8)O(#@0TO-T[Y\A?8>U+QV;,:%:BVD-59'D\B`DUSCOR:
-MX&=I*M&S?*7.F#!A5?RBE/80?"W"$Z+;)9RP'CM$$\MO2S`IC'S$DI6Q!#VU
-M#$YHR&J(4C);"BHWN1>Q<KB322@3?,#`<A[K@8SR*>!3#H2EA[FDJ+LX]UP/
-MET^@X6,3)DWKWF;=OP"O?\G".Q'1JC,J)Z*?OE*H7B+'E9.>3]]VR<NP/\7:
-MLBU&SG-UB(*0A%XF]B4GI;<Y>6TV^"FP$`U+)*Z&Q,\6(7&Y/E8#8CM\/1SF
-M=;PI#+/`"H6YYMX,A8G3+`@CNQV!,#^.;(+"3+A+&+::[!"'<X9;`G%IYR,2
-M_TFKND<`_D0`O+`4KM;%:@B<CU\/@NT2WA2#K<@*A'EK:C,09E:S*(S\MD/A
-M8F]K#?PM2':`O*7T[3&W8K49VM:M<KZYO+@XPB5%.U%'_"G_@"N=Z<Z<F[^T
-MGNSSN`-HO>:8G4[;,Q$TL[-YPWNO:'(ZR&*</,T8@8[32#E68/"&Q*MCB>$9
-M2"-38LJ[X[CX9.K+$7D!N;".#6U1%@.9/C-L(.",I/65F9*$ZW*$R,];P*3$
-MQ.X>WXET@J)&,@F(!@&`R,)DE!G>9'8=8EW?/20O6">@#P2T6D.,SE]5TJ(M
-M=/VRV\%+B_V`L9)F$KW!K*L=QII_Y[/N3K&>=GB=\S*(\;K=.1`S%0P+P:4:
-MN1*LE%&Z)J"48BHHX3WKM:"D8#(+(LAI.Q"I;7JO@2,UJAU`25V'[=%DBMMF
-M@#)CGF-/6J2AJ+!G-KCHL#Q*\TJ+S2=*&`]YT=.Z9KU(O_QX3#MAXJN4]DEI
-M^Q@+$4W#$\ATL2-<GAO!H>OA3%-=(%.L'E@!7V0:N?@JCD.DQ?KK_!]7R&JD
-M=$B;T9*O]6C=YW*:H!5<`BZ81)FP/R$YYQ,?ZP3G2O7-6-A`)ZQ`);&DBD$0
-M;E'-IZ&7#5J#)&NQ1E^.4)`K0A=ENS+(L+ASD+/)]ZVG>*`6?,JGHDB-<06*
-M9$">"7'Q8I4K42IO<S/:H:%-A[`-ZU["2#2CSP4ELWC[^H<KL(N.(5:8:J\<
-M"<Z*DG'/==WO16J04M"$6/\V2Z<BQJK,$!JB'VG_7G[$X,'1)$2+&"-.6T[V
-M7-&%]SI#4)X0X/*19P_?Z!@OR;2)GC%\/LE[_U-#(L+^U-TCQ9PWDUIDU".F
-M\@[-B/9E(M)0Y=9\90W.S_1X`!V%^G2@1U$PE/XM>@KMH8Q""6<DU8@P_@8X
-M+_7#%(5B4:TQ#P0RDC9(^UGBD],XP11!Q'%E)\C.&C$I0VI2\M02]0D*ID3-
-MZ8B4&*'?*8H$^G5(]59=#@:(C$<<K<3*BJU)I4.3K\D2R=%MHQ'O<FQ@`/(Q
-MKEWA$"C)DV=5I"/A/.KD7:@R'4U:UMB@4B$_8I[1OU%))UY7J@BW/@.KKT9E
-M`%:NL)K<DS"DA2(1Z%@ISAVT-*[+4^ZI1-><2:G-F<Q'9]UHC^;'!)R,6;6)
-MI56D3`/V$OG:S,Q],=Y!AEQ-W,EH4E<.'CCHXW!.\J<>GR=%0`%==B[L0V7?
-M(9EFF$H)=R@3'8(FE.T`/*B.:2=N$:'H&>?^22B;,>=<==HK/`)#-TMNZ8X(
-M$%AI*5C4I<=2F>(BCLO0P34TQVQOKMEV]G-0K`";1U2F.?=,\W+3[!HH)#S-
-M@X"`5N!LJ0$&:K[2PK3P`'"VEBFM)`I)AQZ_N:XCV/9MF-]*:R'F%YJ3/#ZM
-M$V1,_0)<81;^H6'&R2>EK"T)12LF%+EF+*E-8JH:XV":BDM&>RN1P:S@A\H_
-ML"Z$G2HL2`MGLNNI@R1Q"'G4.&'M65H!Q[$PB&^ZOF1Y3"ZO5-A94>$RQ5C5
-M[:(GSJ1C/BWH9G2F`,K"D?5H,\]6ER@O"N6==&*LORS2QP@(.NSE*:F,.4-)
-MTU+Q-#)O*S!@_?B>4]W#B,+E6#C.75[M'I[.J79G*Y6%!>_4X)5JWGHMM6;9
-M6Q=65;ZV!6.MTK?&:+;Z)6[;E;_SP&;U,G@.]0[*X7DZ;5\6S^6Z67G\@-G.
-MC>M6K4\M',&?-GR\=`X[S:-.T#UU7@#^;K5'1^3K;]+E5`_NTDW?7[A-9X>V
-M^763C3JB^\URJ;;J[,=E8I=OU7F=><CRT"0O1)BY1"LAS;SP7!-QY@FO/7-W
-MUCW)GL/OWN-WQ]L-_M1JH/7AIR+>(?K4--H=^-29;H<]TS:O`SU+MY^<KM?L
-M_M7GO_DB6WPX7(U9>C(QPV[1Z02U7;Z")0<B^8"E<NN,%@E]!-T_!>C.1/=*
-MF%NG60MR:XMR0\2MB:Z=EYQL"KBUO>39,Y.3G>"MMU6]YWV2>L_[)/6>M[MZ
-MSUM:[WF/]=[_!?1T.P]"C[=)O>=M7.]YV]=[WH[K/>^_4.]YV]1[WJ>H][Q/
-M4>]Y.ZOWO&7UGK=EO7=X^C^O]^SB?02_3<'O?U(O;X>UZY=YWJ9EGK=UF><]
-M4.8=/]L09Q>4><<[VM:;W>%?_]EZAL,.'[!G==O=4_8]SML]:L]QP6,WXY^]
-MKWR5,O!PP1/HO$E?Z3'T'N%:SZ*SH;OA`^FL$O6R\&3#I](9GO=+PY/=E(;;
-M8I;WR3#+^V28Y>T6L[Q'S'K\7YC'5NP5@-[;%.B]K8#>VPW0>PN`?OW_F7F`
-MY\[_>R;_1_<U@#VGV`&0%[*W!^Z2TV9`73/)N;E(57P&<[YV`_;?*C&$B_S.
-M@7.MSA;W)3KG_ADNFKYJ^7?W;UYEO9^E;\ZF6G>>T09!U;(I28#S3HZB28O$
-MS5'+^08!_@RN,]F$PU/XSC?\92+\-2)'9]UC:'6\3@?VSZ^N#YP+'S7Z=UL:
-MOQUCD+>1NZ[V+O"QE1R8MP-JN_IIYP*?9LOV$VI+LDUZMK\+@:/HL<J_+J!H
-M=,F;1'-SRAY%QZ8*(IEM:N)6F:LPX3:CX@M>J$52D!^(/W69AD;+J,^-CSXF
-M(]NL-]V)ZBSN1$4T&HN4^QD?FAYJPBR:3XE96C;`DR;$<86.U)B$1EE@TX/&
-M+![)6AMFK;^5VRJUX`&V.]1^)XU3]D^536T$9!^XD913R0?;N%\T86&BBA1%
-M/W\92_YE-B[U'XD@"*F>:%8=4/66&J87IOPFG4!J/PU[>0-4WD[KQ(2D_2RR
-MS7N7U&DY48GDUD-\BT+NJ$F,LN-0C<E/_?`C=0_CN[%*;Y$]I40[O=Q3>8G7
-MLRAPL.+!R:%J!2<8,^-[;;_+P79VX8*6,07CK:TI8D6A%\<R(`JL.52/&R\=
-MK:+,6DGQ<0F!2AH&;A-4!D$M-+:7K0S:O$<N-P_CCR@XY%!+=+@IFAE%-,!@
-M,D-4(M/5UPNQ?CR),E'98,C?%I0-,)2-0_X8V28R<M;[Q$X)M9@E/ZL)VOB\
-M=;`\8YX<S<F8=<A:F"'+@2MEQ`)(U\R`A9`JX]GO5UDKY>5,9E,<<5J2XS!E
--&.@X_P&I*Y$W($H``"'+
-`
-end
-
-Date: Wed, 30 Oct 96 14:54:13 CST
-From: Loren James Rittle <rittle@comm.mot.com>
-To: friedman@splode.com
-Cc: bug-gnu-utils@prep.ai.mit.edu, info-cvs@prep.ai.mit.edu
-Subject: Re: diffutils 2.7 -- diff3 merge bug
-
-Noah,
-
-I have seen the problem you discuss in your e-mail, however I fail to
-see how this situation is as critical as might be implied since it can
-never arise without at least some user involvement (an update that
-caused a merge is never automatically followed by a commit --- the
-user has a chance to inspect the merged file). However, I will agree
-that I don't always look very closely at non-conflicted merges before
-checking them back in.
-
-You didn't give the exact CVS commands used to create a lossage,
-but I added the following to your Makefile, to help me see the problem
-in a CVS usage context:
-
-t-older: testcase-older
- cp testcase-older t-older
-
-t-yours: testcase-yours
- cp testcase-yours t-yours
-
-t-mine: testcase-mine
- cp testcase-mine t-mine
-
-# Assume cvs-1.9
-cvs-test: t-older t-yours t-mine
- rm -rf /tmp/cvs-test-root x x2
- cvs -d /tmp/cvs-test-root init
- mkdir x
- cp t-older x/testcase
- cd x; cvs -d /tmp/cvs-test-root import -m '' x X X1
- rm -rf x
- cvs -d /tmp/cvs-test-root co x
- cvs -d /tmp/cvs-test-root co -d x2 x
- cp t-yours x/testcase
- cp t-mine x2/testcase
- cd x; cvs ci -m ''
- -cd x2; cvs ci -m ''
- cd x2; cvs update
- cat x2/testcase # at this point, user may commit blindly
-
-It looks like whomever added shift_boundaries() in analyze.c, which
-seems to be the source of the diff3 induced mischief, already provided
-a means to disable the boundary shifting optimization (at least with
-a recompile).
-
-Here is the patch I applied to diff to disable this (currently)
-overaggressive optimization:
-
-[ rittle@supra ]; diff -c analyze.c-old analyze.c
-*** analyze.c-old Wed Oct 30 14:10:27 1996
---- analyze.c Wed Oct 30 13:48:57 1996
-***************
-*** 616,622 ****
- but usually it is cleaner to consider the following identical line
- to be the "change". */
-
-! int inhibit;
-
- static void
- shift_boundaries (filevec)
---- 616,622 ----
- but usually it is cleaner to consider the following identical line
- to be the "change". */
-
-! int inhibit = 1;
-
- static void
- shift_boundaries (filevec)
-
-Now, diff-2.7 with the above patch produces:
-
-[ rittle@supra ]; make diff-mine-yours 'DIFF=/usr/src/diffutils-2.7/diff'
-/usr/src/diffutils-2.7/diff -a --horizon-lines=11 -- testcase-mine testcase-yours; true
-16,18c16,18
-< // _titleColor = Color.black;
-< // _disabledTitleColor = Color.gray;
-< // _titleFont = Font.defaultFont ();
----
-> _titleColor = Color.black;
-> _disabledTitleColor = Color.gray;
-> _titleFont = Font.defaultFont ();
-20,30d19
-<
-< /* Convenience constructor for instantiating a Button with
-< * bounds x, y, width, and height. Equivalent to
-< * foo = new Button ();
-< * foo.init (x, y, width, height);
-< */
-< public Button (int x, int y, int width, int height)
-< {
-< this ();
-< init (x, y, width, height);
-< }
-
-Whereas, stock diff-2.7 produces:
-
-[ rittle@supra ]; make diff-mine-yours
-diff -a --horizon-lines=11 -- testcase-mine testcase-yours; true
-16,29c16,18
-< // _titleColor = Color.black;
-< // _disabledTitleColor = Color.gray;
-< // _titleFont = Font.defaultFont ();
-< }
-<
-< /* Convenience constructor for instantiating a Button with
-< * bounds x, y, width, and height. Equivalent to
-< * foo = new Button ();
-< * foo.init (x, y, width, height);
-< */
-< public Button (int x, int y, int width, int height)
-< {
-< this ();
-< init (x, y, width, height);
----
-> _titleColor = Color.black;
-> _disabledTitleColor = Color.gray;
-> _titleFont = Font.defaultFont ();
-
-A better solution might be to disable the boundary shifting code
-unless explicitly turned on via command line argument. That way
-programs, like diff3, expecting unoptimized diff regions will work
-correctly, yet users can get smaller diffs, if desired. The problem
-is that diff3 doesn't properly track changes once they have been
-optimized.
-
-BTW, I never did like the look of the `optimized diff regions', so I
-consider this a good change for other reasons... :-)
-
-Enjoy!
-
-Regards,
-Loren
---
-Loren J. Rittle (rittle@comm.mot.com) PGP KeyIDs: 1024/B98B3249 2048/ADCE34A5
-Systems Technology Research (IL02/2240) FP1024:6810D8AB3029874DD7065BC52067EAFD
-Motorola, Inc. FP2048:FDC0292446937F2A240BC07D42763672
-(847) 576-7794 Call for verification of fingerprints.
diff --git a/contrib/cvs/lib/getwd.c b/contrib/cvs/lib/getwd.c
deleted file mode 100644
index 5707dcbf4a5e..000000000000
--- a/contrib/cvs/lib/getwd.c
+++ /dev/null
@@ -1,33 +0,0 @@
-/* getwd.c -- get current working directory pathname
- Copyright (C) 1992 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details. */
-
-/* Some systems which include both getwd() and getcwd() have an implementation
- of getwd() which is much faster than getcwd(). As a result, we use the
- system's getwd() if it is available */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "system.h"
-
-/* Get the current working directory into PATHNAME */
-
-char *
-getwd (pathname)
- char *pathname;
-{
- char *getcwd();
-
- return (getcwd(pathname, PATH_MAX));
-}
diff --git a/contrib/cvs/lib/strdup.c b/contrib/cvs/lib/strdup.c
deleted file mode 100644
index c81969da00d7..000000000000
--- a/contrib/cvs/lib/strdup.c
+++ /dev/null
@@ -1,39 +0,0 @@
-/* strdup.c -- return a newly allocated copy of a string
- Copyright (C) 1990 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details. */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#ifdef STDC_HEADERS
-#include <string.h>
-#include <stdlib.h>
-#else
-char *malloc ();
-char *strcpy ();
-#endif
-
-/* Return a newly allocated copy of STR,
- or 0 if out of memory. */
-
-char *
-strdup (str)
- char *str;
-{
- char *newstr;
-
- newstr = (char *) malloc (strlen (str) + 1);
- if (newstr)
- strcpy (newstr, str);
- return newstr;
-}
diff --git a/contrib/cvs/lib/strippath.c b/contrib/cvs/lib/strippath.c
deleted file mode 100644
index 39687f92b804..000000000000
--- a/contrib/cvs/lib/strippath.c
+++ /dev/null
@@ -1,80 +0,0 @@
-/* strippath.c -- remove unnecessary components from a path specifier
- Copyright (C) 1992 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#if STDC_HEADERS || HAVE_STRING_H
-#include <string.h>
-/* An ANSI string.h and pre-ANSI memory.h might conflict. */
-#if !STDC_HEADERS && HAVE_MEMORY_H
-#include <memory.h>
-#endif /* not STDC_HEADERS and HAVE_MEMORY_H */
-#else /* not STDC_HJEADERS and not HAVE_STRING_H */
-#include <strings.h>
-/* memory.h and strings.h conflict on some systems. */
-#endif /* not STDC_HEADERS and not HAVE_STRING_H */
-
-#include <stdio.h>
-
-#if __STDC__
-static void remove_component(char *beginc, char *endc);
-void strip_trailing_slashes(char *path);
-#else
-static void remove_component();
-void strip_trailing_slashes();
-#endif /* __STDC__ */
-
-/* Remove unnecessary components from PATH. */
-
-void
-strip_path (path)
- char *path;
-{
- int stripped = 0;
- char *cp, *slash;
-
- for (cp = path; (slash = strchr(cp, '/')) != NULL; cp = slash)
- {
- *slash = '\0';
- if ((!*cp && (cp != path || stripped)) ||
- strcmp(cp, ".") == 0 || strcmp(cp, "/") == 0)
- {
- stripped = 1;
- remove_component(cp, slash);
- slash = cp;
- }
- else
- {
- *slash++ = '/';
- }
- }
- strip_trailing_slashes(path);
-}
-
-/* Remove the component delimited by BEGINC and ENDC from the path */
-
-static void
-remove_component (beginc, endc)
- char *beginc;
- char *endc;
-{
- for (endc++; *endc; endc++)
- *beginc++ = *endc;
- *beginc = '\0';
-}
diff --git a/contrib/cvs/lib/vasprintf.c b/contrib/cvs/lib/vasprintf.c
deleted file mode 100644
index 3dcfaaa1fd51..000000000000
--- a/contrib/cvs/lib/vasprintf.c
+++ /dev/null
@@ -1,175 +0,0 @@
-/* Like vsprintf but provides a pointer to malloc'd storage, which must
- be freed by the caller.
- Copyright (C) 1994 Free Software Foundation, Inc.
-
-This file is part of the libiberty library.
-Libiberty is free software; you can redistribute it and/or
-modify it under the terms of the GNU Library General Public
-License as published by the Free Software Foundation; either
-version 2 of the License, or (at your option) any later version.
-
-Libiberty is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-Library General Public License for more details. */
-
-#include <stdio.h>
-#include <string.h>
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#ifdef __STDC__
-#include <stdarg.h>
-#else
-#include <varargs.h>
-#endif
-
-#ifdef TEST
-int global_total_width;
-#endif
-
-#ifdef STDC_HEADERS
-#include <stdlib.h>
-#else
-extern int abs ();
-extern unsigned long strtoul ();
-extern char *malloc ();
-#endif
-
-static int
-int_vasprintf (result, format, args)
- char **result;
- const char *format;
- va_list *args;
-{
- const char *p = format;
- /* Add one to make sure that it is never zero, which might cause malloc
- to return NULL. */
- int total_width = strlen (format) + 1;
- va_list ap;
-
- memcpy (&ap, args, sizeof (va_list));
-
- while (*p != '\0')
- {
- if (*p++ == '%')
- {
- while (strchr ("-+ #0", *p))
- ++p;
- if (*p == '*')
- {
- ++p;
- total_width += abs (va_arg (ap, int));
- }
- else
- total_width += strtoul (p, (char **)&p, 10);
- if (*p == '.')
- {
- ++p;
- if (*p == '*')
- {
- ++p;
- total_width += abs (va_arg (ap, int));
- }
- else
- total_width += strtoul (p, (char **)&p, 10);
- }
- while (strchr ("hlL", *p))
- ++p;
- /* Should be big enough for any format specifier except %s. */
- total_width += 30;
- switch (*p)
- {
- case 'd':
- case 'i':
- case 'o':
- case 'u':
- case 'x':
- case 'X':
- case 'c':
- (void) va_arg (ap, int);
- break;
- case 'f':
- case 'e':
- case 'E':
- case 'g':
- case 'G':
- (void) va_arg (ap, double);
- break;
- case 's':
- total_width += strlen (va_arg (ap, char *));
- break;
- case 'p':
- case 'n':
- (void) va_arg (ap, char *);
- break;
- }
- }
- }
-#ifdef TEST
- global_total_width = total_width;
-#endif
- *result = malloc (total_width);
- if (*result != NULL)
- return vsprintf (*result, format, *args);
- else
- return 0;
-}
-
-int
-vasprintf (result, format, args)
- char **result;
- const char *format;
- va_list args;
-{
-#ifdef VA_LIST_IS_ARRAY
- /* If va_list is an array, we do not need the additional indirection */
- return int_vasprintf (result, format, args);
-#else
- /* va_list is some sort of pointer */
- return int_vasprintf (result, format, &args);
-#endif
-}
-
-#ifdef TEST
-void
-checkit
-#ifdef __STDC__
- (const char* format, ...)
-#else
- (va_alist)
- va_dcl
-#endif
-{
- va_list args;
- char *result;
-
-#ifdef __STDC__
- va_start (args, format);
-#else
- char *format;
- va_start (args);
- format = va_arg (args, char *);
-#endif
- vasprintf (&result, format, args);
- if (strlen (result) < global_total_width)
- printf ("PASS: ");
- else
- printf ("FAIL: ");
- printf ("%d %s\n", global_total_width, result);
-}
-
-int
-main ()
-{
- checkit ("%d", 0x12345678);
- checkit ("%200d", 5);
- checkit ("%.300d", 6);
- checkit ("%100.150d", 7);
- checkit ("%s", "jjjjjjjjjiiiiiiiiiiiiiiioooooooooooooooooppppppppppppaa\n\
-777777777777777777333333333333366666666666622222222222777777777777733333");
- checkit ("%f%s%d%s", 1.0, "foo", 77, "asdjffffffffffffffiiiiiiiiiiixxxxx");
-}
-#endif /* TEST */
diff --git a/contrib/cvs/src/NOTES b/contrib/cvs/src/NOTES
deleted file mode 100644
index 646ebdf85207..000000000000
--- a/contrib/cvs/src/NOTES
+++ /dev/null
@@ -1,60 +0,0 @@
-wishlist - Tue Nov 2 15:22:58 PST 1993
-
-* bcopy -> memcpy & friends.
- ** done 12/18/93
-
-* remove static buffers.
-* replace list & node cache with recursive obstacks, (xmalloc,
- getnode, getlist)
-* check all io functions for error return codes. also check all
- system calls.
-* error check mkdir.
-
----
-Old notes...
-
-* All sizing limits are gone. The rest of these items were incidental
- in that effort.
-
-* login name from history was duplicated. taught existing routine to
- cache and use that instead. Also add routines to cache uid, pid,
- etc.
-
-* ign strings were never freed. Now they are.
-
-* there was a printf("... %s ...", cp) vs *cp bug in history.c. Now
- fixed.
-
-* The environment variables TMPDIR, HOME, and LOGNAME were not
- honored. Now they are.
-
-* extra line inserted by do_editor() is gone. Then obviated. Editor
- is now called exactly once per checkin.
-
-* revised editor behaviour. Never use /dev/tty. If the editor
- session fails, we haven't yet done anything. Therefor the user can
- safely rerun cvs and we should just fail. Also use the editor for
- initial log messages on added files. Also omit the confirmation
- when adding directories. Adding directories will require an
- explicit "commit" step soon. Make it possible to prevent null login
- messages using #define REQUIRE_LOG_MESSAGES
-
-* prototypes for all callbacks.
-
-* all callbacks get ref pointers.
-
-* do_recursion/start_recursion now use recusion_frame's rather than a
- list of a lot of pointers and global variables.
-
-* corrected types on status_dirproc().
-
-* CONFIRM_DIRECTORY_ADDS
-
-* re_comp was innappropriate in a few places. I've eliminated it.
-
-* FORCE_MESSAGE_ON_ADD
-
-* So I built a regression test. Let's call it a sanity check to be
- less ambitious. It exposed that cvs is difficult to call from
- scripts.
-
diff --git a/contrib/cvs/src/README-rm-add b/contrib/cvs/src/README-rm-add
deleted file mode 100644
index 87fd7c6d2774..000000000000
--- a/contrib/cvs/src/README-rm-add
+++ /dev/null
@@ -1,31 +0,0 @@
-WHAT THE "DEATH SUPPORT" FEATURES DO:
-
-(Some of the death support stuff is documented in the main manual, but
-this file is for stuff which noone has gotten around to adding to the
-main manual yet).
-
-CVS with death support can record when a file is active, or alive, and
-when it is removed, or dead. With this facility you can record the
-history of a file, including the fact that at some point in its life
-the file was removed and then later added.
-
-Files can now be added or removed in a branch and later merged
-into the trunk.
-
- cvs update -A
- touch a b c
- cvs add a b c ; cvs ci -m "added" a b c
- cvs tag -b branchtag
- cvs update -r branchtag
- touch d ; cvs add d
- rm a ; cvs rm a
- cvs ci -m "added d, removed a"
- cvs update -A
- cvs update -jbranchtag
-
-Added and removed files may also be merged between branches.
-
-Files removed in the trunk may be merged into branches.
-
-Files added on the trunk are a special case. They cannot be merged
-into a branch. Instead, simply branch the file by hand.
diff --git a/contrib/cvs/src/cvsbug.sh b/contrib/cvs/src/cvsbug.sh
deleted file mode 100755
index ee3b7bb5cd83..000000000000
--- a/contrib/cvs/src/cvsbug.sh
+++ /dev/null
@@ -1,526 +0,0 @@
-#! /bin/sh
-# Submit a problem report to a GNATS site.
-# Copyright (C) 1993 Free Software Foundation, Inc.
-# Contributed by Brendan Kehoe (brendan@cygnus.com), based on a
-# version written by Heinz G. Seidl (hgs@ide.com).
-#
-# This file is part of GNU GNATS.
-# Modified by Berliner for CVS.
-#
-# GNU GNATS is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2, or (at your option)
-# any later version.
-#
-# GNU GNATS is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-
-# The version of this send-pr.
-VERSION=3.2
-
-# The submitter-id for your site.
-SUBMITTER=net
-
-## # Where the GNATS directory lives, if at all.
-## [ -z "$GNATS_ROOT" ] &&
-## GNATS_ROOT=/usr/local/lib/gnats/gnats-db
-
-# The default mail address for PR submissions.
-GNATS_ADDR=bug-cvs@gnu.org
-
-## # Where the gnats category tree lives.
-## DATADIR=/usr/local/lib
-
-## # If we've been moved around, try using GCC_EXEC_PREFIX.
-## [ ! -d $DATADIR/gnats -a -d "$GCC_EXEC_PREFIX" ] && DATADIR=${GCC_EXEC_PREFIX}..
-
-# The default release for this host.
-DEFAULT_RELEASE="xVERSIONx"
-
-# The default organization.
-DEFAULT_ORGANIZATION="net"
-
-## # The default site to look for.
-## GNATS_SITE=unknown
-
-## # Newer config information?
-## [ -f ${GNATS_ROOT}/gnats-adm/config ] && . ${GNATS_ROOT}/gnats-adm/config
-
-# What mailer to use. This must come after the config file, since it is
-# host-dependent.
-if [ -f /usr/sbin/sendmail ]; then
- MAIL_AGENT="/usr/sbin/sendmail -oi -t"
-else
- MAIL_AGENT="/usr/lib/sendmail -oi -t"
-fi
-MAILER=`echo $MAIL_AGENT | sed -e 's, .*,,'`
-if [ ! -f "$MAILER" ] ; then
- echo "$COMMAND: Cannot file mail program \"$MAILER\"."
- echo "$COMMAND: Please fix the MAIL_AGENT entry in the $COMMAND file."
- exit 1
-fi
-
-if test "`echo -n foo`" = foo ; then
- ECHON=bsd
-elif test "`echo 'foo\c'`" = foo ; then
- ECHON=sysv
-else
- ECHON=none
-fi
-
-if [ $ECHON = bsd ] ; then
- ECHON1="echo -n"
- ECHON2=
-elif [ $ECHON = sysv ] ; then
- ECHON1=echo
- ECHON2='\c'
-else
- ECHON1=echo
- ECHON2=
-fi
-
-#
-
-[ -z "$TMPDIR" ] && TMPDIR=/tmp
-
-TEMP=$TMPDIR/p$$
-BAD=$TMPDIR/pbad$$
-REF=$TMPDIR/pf$$
-
-if [ -z "$LOGNAME" -a -n "$USER" ]; then
- LOGNAME=$USER
-fi
-
-FROM="$LOGNAME"
-REPLY_TO="$LOGNAME"
-
-# Find out the name of the originator of this PR.
-if [ -n "$NAME" ]; then
- ORIGINATOR="$NAME"
-elif [ -f $HOME/.fullname ]; then
- ORIGINATOR="`sed -e '1q' $HOME/.fullname`"
-elif [ -f /bin/domainname ]; then
- if [ "`/bin/domainname`" != "" -a -f /usr/bin/ypcat ]; then
- # Must use temp file due to incompatibilities in quoting behavior
- # and to protect shell metacharacters in the expansion of $LOGNAME
- /usr/bin/ypcat passwd 2>/dev/null | cat - /etc/passwd | grep "^$LOGNAME:" |
- cut -f5 -d':' | sed -e 's/,.*//' > $TEMP
- ORIGINATOR="`cat $TEMP`"
- rm -f $TEMP
- fi
-fi
-
-if [ "$ORIGINATOR" = "" ]; then
- grep "^$LOGNAME:" /etc/passwd | cut -f5 -d':' | sed -e 's/,.*//' > $TEMP
- ORIGINATOR="`cat $TEMP`"
- rm -f $TEMP
-fi
-
-if [ -n "$ORGANIZATION" ]; then
- if [ -f "$ORGANIZATION" ]; then
- ORGANIZATION="`cat $ORGANIZATION`"
- fi
-else
- if [ -n "$DEFAULT_ORGANIZATION" ]; then
- ORGANIZATION="$DEFAULT_ORGANIZATION"
- elif [ -f $HOME/.organization ]; then
- ORGANIZATION="`cat $HOME/.organization`"
- elif [ -f $HOME/.signature ]; then
- ORGANIZATION="`cat $HOME/.signature`"
- fi
-fi
-
-# If they don't have a preferred editor set, then use
-if [ -z "$VISUAL" ]; then
- if [ -z "$EDITOR" ]; then
- EDIT=vi
- else
- EDIT="$EDITOR"
- fi
-else
- EDIT="$VISUAL"
-fi
-
-# Find out some information.
-SYSTEM=`( [ -f /bin/uname ] && /bin/uname -a ) || \
- ( [ -f /usr/bin/uname ] && /usr/bin/uname -a ) || echo ""`
-ARCH=`[ -f /bin/arch ] && /bin/arch`
-MACHINE=`[ -f /bin/machine ] && /bin/machine`
-
-COMMAND=`echo $0 | sed -e 's,.*/,,'`
-## USAGE="Usage: $COMMAND [-PVL] [-t address] [-f filename] [--request-id]
-USAGE="Usage: $COMMAND [-PVL]
-[--version]"
-REMOVE=
-BATCH=
-
-while [ $# -gt 0 ]; do
- case "$1" in
- -r) ;; # Ignore for backward compat.
-## -t | --to) if [ $# -eq 1 ]; then echo "$USAGE"; exit 1; fi
-## shift ; GNATS_ADDR="$1"
-## EXPLICIT_GNATS_ADDR=true
-## ;;
-## -f | --file) if [ $# -eq 1 ]; then echo "$USAGE"; exit 1; fi
-## shift ; IN_FILE="$1"
-## if [ "$IN_FILE" != "-" -a ! -r "$IN_FILE" ]; then
-## echo "$COMMAND: cannot read $IN_FILE"
-## exit 1
-## fi
-## ;;
- -b | --batch) BATCH=true ;;
- -p | -P | --print) PRINT=true ;;
- -L | --list) FORMAT=norm ;;
- -l | -CL | --lisp) FORMAT=lisp ;;
-## --request-id) REQUEST_ID=true ;;
- -h | --help) echo "$USAGE"; exit 0 ;;
- -V | --version) echo "$VERSION"; exit 0 ;;
- -*) echo "$USAGE" ; exit 1 ;;
- *) echo "$USAGE" ; exit 1
-## if [ -z "$USER_GNATS_SITE" ]; then
-## if [ ! -r "$DATADIR/gnats/$1" ]; then
-## echo "$COMMAND: the GNATS site $1 does not have a categories list."
-## exit 1
-## else
-## # The site name is the alias they'll have to have created.
-## USER_GNATS_SITE=$1
-## fi
-## else
-## echo "$USAGE" ; exit 1
-## fi
- ;;
- esac
- shift
-done
-
-if [ -n "$USER_GNATS_SITE" ]; then
- GNATS_SITE=$USER_GNATS_SITE
- GNATS_ADDR=$USER_GNATS_SITE-gnats
-fi
-
-if [ "$SUBMITTER" = "unknown" -a -z "$REQUEST_ID" -a -z "$IN_FILE" ]; then
- cat << '__EOF__'
-It seems that send-pr is not installed with your unique submitter-id.
-You need to run
-
- install-sid YOUR-SID
-
-where YOUR-SID is the identification code you received with `send-pr'.
-`send-pr' will automatically insert this value into the template field
-`>Submitter-Id'. If you've downloaded `send-pr' from the Net, use `net'
-for this value. If you do not know your id, run `send-pr --request-id' to
-get one from your support site.
-__EOF__
- exit 1
-fi
-
-## if [ -r "$DATADIR/gnats/$GNATS_SITE" ]; then
-## CATEGORIES=`grep -v '^#' $DATADIR/gnats/$GNATS_SITE | sort`
-## else
-## echo "$COMMAND: could not read $DATADIR/gnats/$GNATS_SITE for categories list."
-## exit 1
-## fi
-CATEGORIES="contrib cvs doc pcl-cvs portability"
-
-if [ -z "$CATEGORIES" ]; then
- echo "$COMMAND: the categories list for $GNATS_SITE was empty!"
- exit 1
-fi
-
-case "$FORMAT" in
- lisp) echo "$CATEGORIES" | \
- awk 'BEGIN {printf "( "}
- {printf "(\"%s\") ",$0}
- END {printf ")\n"}'
- exit 0
- ;;
- norm) l=`echo "$CATEGORIES" | \
- awk 'BEGIN {max = 0; }
- { if (length($0) > max) { max = length($0); } }
- END {print max + 1;}'`
- c=`expr 70 / $l`
- if [ $c -eq 0 ]; then c=1; fi
- echo "$CATEGORIES" | \
- awk 'BEGIN {print "Known categories:"; i = 0 }
- { printf ("%-'$l'.'$l's", $0); if ((++i % '$c') == 0) { print "" } }
- END { print ""; }'
- exit 0
- ;;
-esac
-
-ORIGINATOR_C='<name of the PR author (one line)>'
-ORGANIZATION_C='<organization of PR author (multiple lines)>'
-CONFIDENTIAL_C='<[ yes | no ] (one line)>'
-SYNOPSIS_C='<synopsis of the problem (one line)>'
-SEVERITY_C='<[ non-critical | serious | critical ] (one line)>'
-PRIORITY_C='<[ low | medium | high ] (one line)>'
-CATEGORY_C='<name of the product (one line)>'
-CLASS_C='<[ sw-bug | doc-bug | change-request | support ] (one line)>'
-RELEASE_C='<release number or tag (one line)>'
-ENVIRONMENT_C='<machine, os, target, libraries (multiple lines)>'
-DESCRIPTION_C='<precise description of the problem (multiple lines)>'
-HOW_TO_REPEAT_C='<code/input/activities to reproduce the problem (multiple lines)>'
-FIX_C='<how to correct or work around the problem, if known (multiple lines)>'
-
-# Catch some signals. ($xs kludge needed by Sun /bin/sh)
-xs=0
-trap 'rm -f $REF $TEMP; exit $xs' 0
-trap 'echo "$COMMAND: Aborting ..."; rm -f $REF $TEMP; xs=1; exit' 1 2 3 13 15
-
-# If they told us to use a specific file, then do so.
-if [ -n "$IN_FILE" ]; then
- if [ "$IN_FILE" = "-" ]; then
- # The PR is coming from the standard input.
- if [ -n "$EXPLICIT_GNATS_ADDR" ]; then
- sed -e "s;^[Tt][Oo]:.*;To: $GNATS_ADDR;" > $TEMP
- else
- cat > $TEMP
- fi
- else
- # Use the file they named.
- if [ -n "$EXPLICIT_GNATS_ADDR" ]; then
- sed -e "s;^[Tt][Oo]:.*;To: $GNATS_ADDR;" $IN_FILE > $TEMP
- else
- cat $IN_FILE > $TEMP
- fi
- fi
-else
-
- if [ -n "$PR_FORM" -a -z "$PRINT_INTERN" ]; then
- # If their PR_FORM points to a bogus entry, then bail.
- if [ ! -f "$PR_FORM" -o ! -r "$PR_FORM" -o ! -s "$PR_FORM" ]; then
- echo "$COMMAND: can't seem to read your template file (\`$PR_FORM'), ignoring PR_FORM"
- sleep 1
- PRINT_INTERN=bad_prform
- fi
- fi
-
- if [ -n "$PR_FORM" -a -z "$PRINT_INTERN" ]; then
- cp $PR_FORM $TEMP ||
- ( echo "$COMMAND: could not copy $PR_FORM" ; xs=1; exit )
- else
- for file in $TEMP $REF ; do
- cat > $file << '__EOF__'
-SEND-PR: -*- send-pr -*-
-SEND-PR: Lines starting with `SEND-PR' will be removed automatically, as
-SEND-PR: will all comments (text enclosed in `<' and `>').
-SEND-PR:
-SEND-PR: Choose from the following categories:
-SEND-PR:
-__EOF__
-
- # Format the categories so they fit onto lines.
- l=`echo "$CATEGORIES" | \
- awk 'BEGIN {max = 0; }
- { if (length($0) > max) { max = length($0); } }
- END {print max + 1;}'`
- c=`expr 61 / $l`
- if [ $c -eq 0 ]; then c=1; fi
- echo "$CATEGORIES" | \
- awk 'BEGIN {printf "SEND-PR: "; i = 0 }
- { printf ("%-'$l'.'$l's", $0);
- if ((++i % '$c') == 0) { printf "\nSEND-PR: " } }
- END { printf "\nSEND-PR:\n"; }' >> $file
-
- cat >> $file << __EOF__
-To: $GNATS_ADDR
-Subject:
-From: $FROM
-Reply-To: $REPLY_TO
-X-send-pr-version: $VERSION
-
-
->Submitter-Id: $SUBMITTER
->Originator: $ORIGINATOR
->Organization:
-${ORGANIZATION-$ORGANIZATION_C}
->Confidential: $CONFIDENTIAL_C
->Synopsis: $SYNOPSIS_C
->Severity: $SEVERITY_C
->Priority: $PRIORITY_C
->Category: $CATEGORY_C
->Class: $CLASS_C
->Release: ${DEFAULT_RELEASE-$RELEASE_C}
->Environment:
- $ENVIRONMENT_C
-`[ -n "$SYSTEM" ] && echo System: $SYSTEM`
-`[ -n "$ARCH" ] && echo Architecture: $ARCH`
-`[ -n "$MACHINE" ] && echo Machine: $MACHINE`
->Description:
- $DESCRIPTION_C
->How-To-Repeat:
- $HOW_TO_REPEAT_C
->Fix:
- $FIX_C
-__EOF__
- done
- fi
-
- if [ "$PRINT" = true -o "$PRINT_INTERN" = true ]; then
- cat $TEMP
- xs=0; exit
- fi
-
- chmod u+w $TEMP
- if [ -z "$REQUEST_ID" ]; then
- eval $EDIT $TEMP
- else
- ed -s $TEMP << '__EOF__'
-/^Subject/s/^Subject:.*/Subject: request for a customer id/
-/^>Category/s/^>Category:.*/>Category: send-pr/
-w
-q
-__EOF__
- fi
-
- if cmp -s $REF $TEMP ; then
- echo "$COMMAND: problem report not filled out, therefore not sent"
- xs=1; exit
- fi
-fi
-
-#
-# Check the enumeration fields
-
-# This is a "sed-subroutine" with one keyword parameter
-# (with workaround for Sun sed bug)
-#
-SED_CMD='
-/$PATTERN/{
-s|||
-s|<.*>||
-s|^[ ]*||
-s|[ ]*$||
-p
-q
-}'
-
-
-while [ -z "$REQUEST_ID" ]; do
- CNT=0
-
- # 1) Confidential
- #
- PATTERN=">Confidential:"
- CONFIDENTIAL=`eval sed -n -e "\"$SED_CMD\"" $TEMP`
- case "$CONFIDENTIAL" in
- ""|yes|no) CNT=`expr $CNT + 1` ;;
- *) echo "$COMMAND: \`$CONFIDENTIAL' is not a valid value for \`Confidential'." ;;
- esac
- #
- # 2) Severity
- #
- PATTERN=">Severity:"
- SEVERITY=`eval sed -n -e "\"$SED_CMD\"" $TEMP`
- case "$SEVERITY" in
- ""|non-critical|serious|critical) CNT=`expr $CNT + 1` ;;
- *) echo "$COMMAND: \`$SEVERITY' is not a valid value for \`Severity'."
- esac
- #
- # 3) Priority
- #
- PATTERN=">Priority:"
- PRIORITY=`eval sed -n -e "\"$SED_CMD\"" $TEMP`
- case "$PRIORITY" in
- ""|low|medium|high) CNT=`expr $CNT + 1` ;;
- *) echo "$COMMAND: \`$PRIORITY' is not a valid value for \`Priority'."
- esac
- #
- # 4) Category
- #
- PATTERN=">Category:"
- CATEGORY=`eval sed -n -e "\"$SED_CMD\"" $TEMP`
- FOUND=
- for C in $CATEGORIES
- do
- if [ "$C" = "$CATEGORY" ]; then FOUND=true ; break ; fi
- done
- if [ -n "$FOUND" ]; then
- CNT=`expr $CNT + 1`
- else
- if [ -z "$CATEGORY" ]; then
- echo "$COMMAND: you must include a Category: field in your report."
- else
- echo "$COMMAND: \`$CATEGORY' is not a known category."
- fi
- fi
- #
- # 5) Class
- #
- PATTERN=">Class:"
- CLASS=`eval sed -n -e "\"$SED_CMD\"" $TEMP`
- case "$CLASS" in
- ""|sw-bug|doc-bug|change-request|support) CNT=`expr $CNT + 1` ;;
- *) echo "$COMMAND: \`$CLASS' is not a valid value for \`Class'."
- esac
-
- [ $CNT -lt 5 -a -z "$BATCH" ] &&
- echo "Errors were found with the problem report."
-
- while true; do
- if [ -z "$BATCH" ]; then
- $ECHON1 "a)bort, e)dit or s)end? $ECHON2"
- read input
- else
- if [ $CNT -eq 5 ]; then
- input=s
- else
- input=a
- fi
- fi
- case "$input" in
- a*)
- if [ -z "$BATCH" ]; then
- echo "$COMMAND: the problem report remains in $BAD and is not sent."
- mv $TEMP $BAD
- else
- echo "$COMMAND: the problem report is not sent."
- fi
- xs=1; exit
- ;;
- e*)
- eval $EDIT $TEMP
- continue 2
- ;;
- s*)
- break 2
- ;;
- esac
- done
-done
-#
-# Remove comments and send the problem report
-# (we have to use patterns, where the comment contains regex chars)
-#
-# /^>Originator:/s;$ORIGINATOR;;
-sed -e "
-/^SEND-PR:/d
-/^>Organization:/,/^>[A-Za-z-]*:/s;$ORGANIZATION_C;;
-/^>Confidential:/s;<.*>;;
-/^>Synopsis:/s;$SYNOPSIS_C;;
-/^>Severity:/s;<.*>;;
-/^>Priority:/s;<.*>;;
-/^>Category:/s;$CATEGORY_C;;
-/^>Class:/s;<.*>;;
-/^>Release:/,/^>[A-Za-z-]*:/s;$RELEASE_C;;
-/^>Environment:/,/^>[A-Za-z-]*:/s;$ENVIRONMENT_C;;
-/^>Description:/,/^>[A-Za-z-]*:/s;$DESCRIPTION_C;;
-/^>How-To-Repeat:/,/^>[A-Za-z-]*:/s;$HOW_TO_REPEAT_C;;
-/^>Fix:/,/^>[A-Za-z-]*:/s;$FIX_C;;
-" $TEMP > $REF
-
-if $MAIL_AGENT < $REF; then
- echo "$COMMAND: problem report sent"
- xs=0; exit
-else
- echo "$COMMAND: mysterious mail failure."
- if [ -z "$BATCH" ]; then
- echo "$COMMAND: the problem report remains in $BAD and is not sent."
- mv $REF $BAD
- else
- echo "$COMMAND: the problem report is not sent."
- fi
- xs=1; exit
-fi
diff --git a/contrib/cvs/src/rtag.c b/contrib/cvs/src/rtag.c
deleted file mode 100644
index bc14d8819cb2..000000000000
--- a/contrib/cvs/src/rtag.c
+++ /dev/null
@@ -1,764 +0,0 @@
-/*
- * Copyright (c) 1992, Brian Berliner and Jeff Polk
- * Copyright (c) 1989-1992, Brian Berliner
- *
- * You may distribute under the terms of the GNU General Public License as
- * specified in the README file that comes with the CVS source distribution.
- *
- * Rtag
- *
- * Add or delete a symbolic name to an RCS file, or a collection of RCS files.
- * Uses the modules database, if necessary.
- */
-
-#include "cvs.h"
-
-static int check_fileproc PROTO ((void *callerdat, struct file_info *finfo));
-static int check_filesdoneproc PROTO ((void *callerdat, int err,
- char *repos, char *update_dir,
- List *entries));
-static int pretag_proc PROTO((char *repository, char *filter));
-static void masterlist_delproc PROTO((Node *p));
-static void tag_delproc PROTO((Node *p));
-static int pretag_list_proc PROTO((Node *p, void *closure));
-
-static Dtype rtag_dirproc PROTO ((void *callerdat, char *dir,
- char *repos, char *update_dir,
- List *entries));
-static int rtag_fileproc PROTO ((void *callerdat, struct file_info *finfo));
-static int rtag_filesdoneproc PROTO ((void *callerdat, int err,
- char *repos, char *update_dir,
- List *entries));
-static int rtag_proc PROTO((int argc, char **argv, char *xwhere,
- char *mwhere, char *mfile, int shorten,
- int local_specified, char *mname, char *msg));
-static int rtag_delete PROTO((RCSNode *rcsfile));
-
-
-struct tag_info
-{
- Ctype status;
- char *rev;
- char *tag;
- char *options;
-};
-
-struct master_lists
-{
- List *tlist;
-};
-
-static List *mtlist;
-static List *tlist;
-
-static char *symtag;
-static char *numtag;
-static int numtag_validated = 0;
-static int delete_flag; /* adding a tag by default */
-static int attic_too; /* remove tag from Attic files */
-static int branch_mode; /* make an automagic "branch" tag */
-static char *date;
-static int local; /* recursive by default */
-static int force_tag_match = 1; /* force by default */
-static int force_tag_move; /* don't move existing tags by default */
-
-static const char *const rtag_usage[] =
-{
- "Usage: %s %s [-aflRnF] [-b] [-d] [-r rev|-D date] tag modules...\n",
- "\t-a\tClear tag from removed files that would not otherwise be tagged.\n",
- "\t-f\tForce a head revision match if tag/date not found.\n",
- "\t-l\tLocal directory only, not recursive\n",
- "\t-R\tProcess directories recursively.\n",
- "\t-n\tNo execution of 'tag program'\n",
- "\t-d\tDelete the given Tag.\n",
- "\t-b\tMake the tag a \"branch\" tag, allowing concurrent development.\n",
- "\t-r rev\tExisting revision/tag.\n",
- "\t-D\tExisting date.\n",
- "\t-F\tMove tag if it already exists\n",
- "(Specify the --help global option for a list of other help options)\n",
- NULL
-};
-
-int
-rtag (argc, argv)
- int argc;
- char **argv;
-{
- register int i;
- int c;
- DBM *db;
- int run_module_prog = 1;
- int err = 0;
-
- if (argc == -1)
- usage (rtag_usage);
-
- optind = 0;
- while ((c = getopt (argc, argv, "+FanfQqlRdbr:D:")) != -1)
- {
- switch (c)
- {
- case 'a':
- attic_too = 1;
- break;
- case 'n':
- run_module_prog = 0;
- break;
- case 'Q':
- case 'q':
-#ifdef SERVER_SUPPORT
- /* The CVS 1.5 client sends these options (in addition to
- Global_option requests), so we must ignore them. */
- if (!server_active)
-#endif
- error (1, 0,
- "-q or -Q must be specified before \"%s\"",
- command_name);
- break;
- case 'l':
- local = 1;
- break;
- case 'R':
- local = 0;
- break;
- case 'd':
- delete_flag = 1;
- break;
- case 'f':
- force_tag_match = 0;
- break;
- case 'b':
- branch_mode = 1;
- break;
- case 'r':
- numtag = optarg;
- break;
- case 'D':
- if (date)
- free (date);
- date = Make_Date (optarg);
- break;
- case 'F':
- force_tag_move = 1;
- break;
- case '?':
- default:
- usage (rtag_usage);
- break;
- }
- }
- argc -= optind;
- argv += optind;
- if (argc < 2)
- usage (rtag_usage);
- symtag = argv[0];
- argc--;
- argv++;
-
- if (date && numtag)
- error (1, 0, "-r and -D options are mutually exclusive");
- if (delete_flag && branch_mode)
- error (0, 0, "warning: -b ignored with -d options");
- RCS_check_tag (symtag);
-
-#ifdef CLIENT_SUPPORT
- if (client_active)
- {
- /* We're the client side. Fire up the remote server. */
- start_server ();
-
- ign_setup ();
-
- if (!force_tag_match)
- send_arg ("-f");
- if (local)
- send_arg("-l");
- if (delete_flag)
- send_arg("-d");
- if (branch_mode)
- send_arg("-b");
- if (force_tag_move)
- send_arg("-F");
- if (!run_module_prog)
- send_arg("-n");
- if (attic_too)
- send_arg("-a");
-
- if (numtag)
- option_with_arg ("-r", numtag);
- if (date)
- client_senddate (date);
-
- send_arg (symtag);
-
- {
- int i;
- for (i = 0; i < argc; ++i)
- send_arg (argv[i]);
- }
-
- send_to_server ("rtag\012", 0);
- return get_responses_and_close ();
- }
-#endif
-
- db = open_module ();
- for (i = 0; i < argc; i++)
- {
- /* XXX last arg should be repository, but doesn't make sense here */
- history_write ('T', (delete_flag ? "D" : (numtag ? numtag :
- (date ? date : "A"))), symtag, argv[i], "");
- err += do_module (db, argv[i], TAG,
- delete_flag ? "Untagging" : "Tagging",
- rtag_proc, (char *) NULL, 0, 0, run_module_prog,
- symtag);
- }
- close_module (db);
- return (err);
-}
-
-/*
- * callback proc for doing the real work of tagging
- */
-/* ARGSUSED */
-static int
-rtag_proc (argc, argv, xwhere, mwhere, mfile, shorten, local_specified,
- mname, msg)
- int argc;
- char **argv;
- char *xwhere;
- char *mwhere;
- char *mfile;
- int shorten;
- int local_specified;
- char *mname;
- char *msg;
-{
- /* Begin section which is identical to patch_proc--should this
- be abstracted out somehow? */
- char *myargv[2];
- int err = 0;
- int which;
- char *repository;
- char *where;
-
- repository = xmalloc (strlen (CVSroot_directory) + strlen (argv[0])
- + (mfile == NULL ? 0 : strlen (mfile)) + 30);
- (void) sprintf (repository, "%s/%s", CVSroot_directory, argv[0]);
- where = xmalloc (strlen (argv[0]) + (mfile == NULL ? 0 : strlen (mfile))
- + 10);
- (void) strcpy (where, argv[0]);
-
- /* if mfile isn't null, we need to set up to do only part of the module */
- if (mfile != NULL)
- {
- char *cp;
- char *path;
-
- /* if the portion of the module is a path, put the dir part on repos */
- if ((cp = strrchr (mfile, '/')) != NULL)
- {
- *cp = '\0';
- (void) strcat (repository, "/");
- (void) strcat (repository, mfile);
- (void) strcat (where, "/");
- (void) strcat (where, mfile);
- mfile = cp + 1;
- }
-
- /* take care of the rest */
- path = xmalloc (strlen (repository) + strlen (mfile) + 5);
- (void) sprintf (path, "%s/%s", repository, mfile);
- if (isdir (path))
- {
- /* directory means repository gets the dir tacked on */
- (void) strcpy (repository, path);
- (void) strcat (where, "/");
- (void) strcat (where, mfile);
- }
- else
- {
- myargv[0] = argv[0];
- myargv[1] = mfile;
- argc = 2;
- argv = myargv;
- }
- free (path);
- }
-
- /* cd to the starting repository */
- if ( CVS_CHDIR (repository) < 0)
- {
- error (0, errno, "cannot chdir to %s", repository);
- free (repository);
- return (1);
- }
- free (repository);
- /* End section which is identical to patch_proc. */
-
- if (delete_flag || attic_too || (force_tag_match && numtag))
- which = W_REPOS | W_ATTIC;
- else
- which = W_REPOS;
-
- if (numtag != NULL && !numtag_validated)
- {
- tag_check_valid (numtag, argc - 1, argv + 1, local, 0, NULL);
- numtag_validated = 1;
- }
-
- /* check to make sure they are authorized to tag all the
- specified files in the repository */
-
- mtlist = getlist();
- err = start_recursion (check_fileproc, check_filesdoneproc,
- (DIRENTPROC) NULL, (DIRLEAVEPROC) NULL, NULL,
- argc - 1, argv + 1, local, which, 0, 1,
- where, 1);
-
- if (err)
- {
- error (1, 0, "correct the above errors first!");
- }
-
- /* start the recursion processor */
- err = start_recursion (rtag_fileproc, rtag_filesdoneproc, rtag_dirproc,
- (DIRLEAVEPROC) NULL, NULL,
- argc - 1, argv + 1, local,
- which, 0, 0, where, 1);
- free (where);
- dellist(&mtlist);
-
- return (err);
-}
-
-/* check file that is to be tagged */
-/* All we do here is add it to our list */
-
-static int
-check_fileproc (callerdat, finfo)
- void *callerdat;
- struct file_info *finfo;
-{
- char *xdir;
- Node *p;
- Vers_TS *vers;
-
- if (finfo->update_dir[0] == '\0')
- xdir = ".";
- else
- xdir = finfo->update_dir;
- if ((p = findnode (mtlist, xdir)) != NULL)
- {
- tlist = ((struct master_lists *) p->data)->tlist;
- }
- else
- {
- struct master_lists *ml;
-
- tlist = getlist ();
- p = getnode ();
- p->key = xstrdup (xdir);
- p->type = UPDATE;
- ml = (struct master_lists *)
- xmalloc (sizeof (struct master_lists));
- ml->tlist = tlist;
- p->data = (char *) ml;
- p->delproc = masterlist_delproc;
- (void) addnode (mtlist, p);
- }
- /* do tlist */
- p = getnode ();
- p->key = xstrdup (finfo->file);
- p->type = UPDATE;
- p->delproc = tag_delproc;
- vers = Version_TS (finfo, NULL, NULL, NULL, 0, 0);
- p->data = RCS_getversion(vers->srcfile, numtag, date, force_tag_match,
- (int *) NULL);
- if (p->data != NULL)
- {
- int addit = 1;
- char *oversion;
-
- oversion = RCS_getversion (vers->srcfile, symtag, (char *) NULL, 1,
- (int *) NULL);
- if (oversion == NULL)
- {
- if (delete_flag)
- {
- /* Deleting a tag which did not exist is a noop and
- should not be logged. */
- addit = 0;
- }
- }
- else if (delete_flag)
- {
- free (p->data);
- p->data = xstrdup (oversion);
- }
- else if (strcmp(oversion, p->data) == 0)
- {
- addit = 0;
- }
- else if (!force_tag_move)
- {
- addit = 0;
- }
- if (oversion != NULL)
- {
- free(oversion);
- }
- if (!addit)
- {
- free(p->data);
- p->data = NULL;
- }
- }
- freevers_ts (&vers);
- (void) addnode (tlist, p);
- return (0);
-}
-
-static int
-check_filesdoneproc (callerdat, err, repos, update_dir, entries)
- void *callerdat;
- int err;
- char *repos;
- char *update_dir;
- List *entries;
-{
- int n;
- Node *p;
-
- p = findnode(mtlist, update_dir);
- if (p != NULL)
- {
- tlist = ((struct master_lists *) p->data)->tlist;
- }
- else
- {
- tlist = (List *) NULL;
- }
- if ((tlist == NULL) || (tlist->list->next == tlist->list))
- {
- return (err);
- }
- if ((n = Parse_Info(CVSROOTADM_TAGINFO, repos, pretag_proc, 1)) > 0)
- {
- error (0, 0, "Pre-tag check failed");
- err += n;
- }
- return (err);
-}
-
-static int
-pretag_proc(repository, filter)
- char *repository;
- char *filter;
-{
- if (filter[0] == '/')
- {
- char *s, *cp;
-
- s = xstrdup(filter);
- for (cp=s; *cp; cp++)
- {
- if (isspace ((unsigned char) *cp))
- {
- *cp = '\0';
- break;
- }
- }
- if (!isfile(s))
- {
- error (0, errno, "cannot find pre-tag filter '%s'", s);
- free(s);
- return (1);
- }
- free(s);
- }
- run_setup (filter);
- run_arg (symtag);
- run_arg (delete_flag ? "del" : force_tag_move ? "mov" : "add");
- run_arg (repository);
- walklist(tlist, pretag_list_proc, NULL);
- return (run_exec (RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL));
-}
-
-static void
-masterlist_delproc(p)
- Node *p;
-{
- struct master_lists *ml;
-
- ml = (struct master_lists *)p->data;
- dellist(&ml->tlist);
- free(ml);
- return;
-}
-
-static void
-tag_delproc(p)
- Node *p;
-{
- if (p->data != NULL)
- {
- free(p->data);
- p->data = NULL;
- }
- return;
-}
-
-static int
-pretag_list_proc(p, closure)
- Node *p;
- void *closure;
-{
- if (p->data != NULL)
- {
- run_arg(p->key);
- run_arg(p->data);
- }
- return (0);
-}
-
-/*
- * Called to tag a particular file, as appropriate with the options that were
- * set above.
- */
-/* ARGSUSED */
-static int
-rtag_fileproc (callerdat, finfo)
- void *callerdat;
- struct file_info *finfo;
-{
- RCSNode *rcsfile;
- char *version, *rev;
- int retcode = 0;
-
- /* Lock the directory if it is not already locked. We might be
- able to rely on rtag_dirproc for this. */
-
- /* It would be nice to provide consistency with respect to
- commits; however CVS lacks the infrastructure to do that (see
- Concurrency in cvs.texinfo and comment in do_recursion). We
- can and will prevent simultaneous tag operations from
- interfering with each other, by write locking each directory as
- we enter it, and unlocking it as we leave it. */
-
- lock_dir_for_write (finfo->repository);
-
- /* find the parsed RCS data */
- if ((rcsfile = finfo->rcs) == NULL)
- return (1);
-
- /*
- * For tagging an RCS file which is a symbolic link, you'd best be
- * running with RCS 5.6, since it knows how to handle symbolic links
- * correctly without breaking your link!
- */
-
- if (delete_flag)
- return (rtag_delete (rcsfile));
-
- /*
- * If we get here, we are adding a tag. But, if -a was specified, we
- * need to check to see if a -r or -D option was specified. If neither
- * was specified and the file is in the Attic, remove the tag.
- */
- if (attic_too && (!numtag && !date))
- {
- if ((rcsfile->flags & VALID) && (rcsfile->flags & INATTIC))
- return (rtag_delete (rcsfile));
- }
-
- version = RCS_getversion (rcsfile, numtag, date, force_tag_match,
- (int *) NULL);
- if (version == NULL)
- {
- /* If -a specified, clean up any old tags */
- if (attic_too)
- (void) rtag_delete (rcsfile);
-
- if (!quiet && !force_tag_match)
- {
- error (0, 0, "cannot find tag `%s' in `%s'",
- numtag ? numtag : "head", rcsfile->path);
- return (1);
- }
- return (0);
- }
- if (numtag
- && isdigit ((unsigned char) *numtag)
- && strcmp (numtag, version) != 0)
- {
-
- /*
- * We didn't find a match for the numeric tag that was specified, but
- * that's OK. just pass the numeric tag on to rcs, to be tagged as
- * specified. Could get here if one tried to tag "1.1.1" and there
- * was a 1.1.1 branch with some head revision. In this case, we want
- * the tag to reference "1.1.1" and not the revision at the head of
- * the branch. Use a symbolic tag for that.
- */
- rev = branch_mode ? RCS_magicrev (rcsfile, version) : numtag;
- retcode = RCS_settag(rcsfile, symtag, numtag);
- if (retcode == 0)
- RCS_rewrite (rcsfile, NULL, NULL);
- }
- else
- {
- char *oversion;
-
- /*
- * As an enhancement for the case where a tag is being re-applied to
- * a large body of a module, make one extra call to RCS_getversion to
- * see if the tag is already set in the RCS file. If so, check to
- * see if it needs to be moved. If not, do nothing. This will
- * likely save a lot of time when simply moving the tag to the
- * "current" head revisions of a module -- which I have found to be a
- * typical tagging operation.
- */
- rev = branch_mode ? RCS_magicrev (rcsfile, version) : version;
- oversion = RCS_getversion (rcsfile, symtag, (char *) NULL, 1,
- (int *) NULL);
- if (oversion != NULL)
- {
- int isbranch = RCS_nodeisbranch (finfo->rcs, symtag);
-
- /*
- * if versions the same and neither old or new are branches don't
- * have to do anything
- */
- if (strcmp (version, oversion) == 0 && !branch_mode && !isbranch)
- {
- free (oversion);
- free (version);
- return (0);
- }
-
- if (!force_tag_move)
- {
- /* we're NOT going to move the tag */
- (void) printf ("W %s", finfo->fullname);
-
- (void) printf (" : %s already exists on %s %s",
- symtag, isbranch ? "branch" : "version",
- oversion);
- (void) printf (" : NOT MOVING tag to %s %s\n",
- branch_mode ? "branch" : "version", rev);
- free (oversion);
- free (version);
- return (0);
- }
- free (oversion);
- }
- retcode = RCS_settag(rcsfile, symtag, rev);
- if (retcode == 0)
- RCS_rewrite (rcsfile, NULL, NULL);
- }
-
- if (retcode != 0)
- {
- error (1, retcode == -1 ? errno : 0,
- "failed to set tag `%s' to revision `%s' in `%s'",
- symtag, rev, rcsfile->path);
- if (branch_mode)
- free (rev);
- free (version);
- return (1);
- }
- if (branch_mode)
- free (rev);
- free (version);
- return (0);
-}
-
-/*
- * If -d is specified, "force_tag_match" is set, so that this call to
- * RCS_getversion() will return a NULL version string if the symbolic
- * tag does not exist in the RCS file.
- *
- * If the -r flag was used, numtag is set, and we only delete the
- * symtag from files that have numtag.
- *
- * This is done here because it's MUCH faster than just blindly calling
- * "rcs" to remove the tag... trust me.
- */
-static int
-rtag_delete (rcsfile)
- RCSNode *rcsfile;
-{
- char *version;
- int retcode;
-
- if (numtag)
- {
- version = RCS_getversion (rcsfile, numtag, (char *) NULL, 1,
- (int *) NULL);
- if (version == NULL)
- return (0);
- free (version);
- }
-
- version = RCS_getversion (rcsfile, symtag, (char *) NULL, 1,
- (int *) NULL);
- if (version == NULL)
- return (0);
- free (version);
-
- if ((retcode = RCS_deltag(rcsfile, symtag)) != 0)
- {
- if (!quiet)
- error (0, retcode == -1 ? errno : 0,
- "failed to remove tag `%s' from `%s'", symtag,
- rcsfile->path);
- return (1);
- }
- RCS_rewrite (rcsfile, NULL, NULL);
- return (0);
-}
-
-/* Clear any lock we may hold on the current directory. */
-
-static int
-rtag_filesdoneproc (callerdat, err, repos, update_dir, entries)
- void *callerdat;
- int err;
- char *repos;
- char *update_dir;
- List *entries;
-{
- Lock_Cleanup ();
-
- return (err);
-}
-
-/*
- * Print a warm fuzzy message
- */
-/* ARGSUSED */
-static Dtype
-rtag_dirproc (callerdat, dir, repos, update_dir, entries)
- void *callerdat;
- char *dir;
- char *repos;
- char *update_dir;
- List *entries;
-{
- if (ignore_directory (update_dir))
- {
- /* print the warm fuzzy message */
- if (!quiet)
- error (0, 0, "Ignoring %s", update_dir);
- return R_SKIP_ALL;
- }
-
- if (!quiet)
- error (0, 0, "%s %s", delete_flag ? "Untagging" : "Tagging",
- update_dir);
- return (R_PROCESS);
-}
-
-
-
diff --git a/contrib/cvs/stamp-h.in b/contrib/cvs/stamp-h.in
deleted file mode 100644
index bb5e5e3873f8..000000000000
--- a/contrib/cvs/stamp-h.in
+++ /dev/null
@@ -1 +0,0 @@
-Wed Oct 5 15:45:29 EDT 1994
diff --git a/contrib/cvs/tools/pcl-cvs/ChangeLog b/contrib/cvs/tools/pcl-cvs/ChangeLog
deleted file mode 100644
index 7a4b2c377193..000000000000
--- a/contrib/cvs/tools/pcl-cvs/ChangeLog
+++ /dev/null
@@ -1,922 +0,0 @@
-1998-01-03 Jim Blandy <jimb@totoro.red-bean.com>
-
- * (cvs-changelog-ours-p): Recognize Emacs 20-style ChangeLog
- entries.
-
-Mon Oct 14 19:19:17 1996 Jim Blandy <jimb@totoro.cyclic.com>
-
- * pcl-cvs.el (cvs-parse-stderr): Ignore messages about patch hunks
- failing; CVS will refetch the file.
-
-Thu Oct 10 10:20:20 1996 Jim Blandy <jimb@totoro.cyclic.com>
-
- * Makefile.in: Allow pcl-cvs to find the site-lisp directory where
- it is installed in modern Emacsen. (Patch thanks to David Kågedal.)
-
-Wed Sep 25 05:38:09 1996 Jim Blandy <jimb@floss.cyclic.com>
-
- * pcl-cvs.el (cvs-find-program): New function.
- (cvs-program, cvs-diff-program): Use it to find the executables.
- (local-path, local-gnu-path): Variables deleted; nobody else was
- using them, and they didn't do the job right anyway.
-
-Wed Sep 11 15:43:50 1996 Jim Blandy <jimb@totoro.cyclic.com>
-
- * pcl-cvs.el (cvs-parse-stderr): Ignore messages about obtained locks.
-
-Fri Aug 9 09:44:53 1996 Jim Blandy <jimb@totoro.cyclic.com>
-
- * pcl-cvs.el (cvs-parse-stderr): Remove extra paren from regexp
- matching rcsmerge warnings.
-
-Mon Apr 15 01:34:27 1996 Karl Fogel <kfogel@floss.red-bean.com>
-
- * Makefile: removed. Why was this in the repository in the first
- place?
-
- * Makefile.in (BATCHFLAGS): don't pass -q to Emacs when compiling,
- because Emacs probably can't find Elib's cookie.el[c] if we do
- that. (Actually, it still can't, but that may be due to a bug in
- Emacs).
-
- * INSTALL: reflect changed location of elib in the CVS dist.
-
-Sun Apr 14 12:18:12 1996 Karl Fogel <kfogel@floss.red-bean.com>
-
- * pcl-cvs.el (cookie): Changed "(load \"cookie\")" to
- "(require 'cookie)", since elib is now included again.
- Moved "(provide 'pcl-cvs)" to the end of the file, so it's not
- provided if the package didn't load successfully.
-
- * Makefile.in (subdir): tools/pcl-cvs now, not contrib/pcl-cvs.
- (BATCHFLAGS): removed "-n" from BATCHFLAGS. Emacs 19.30 does not
- know about this flag.
- (OBJDIR_DISTFILES): don't include .elc files here, add comment
- explaining why.
-
-Thu Apr 11 20:22:34 1996 Karl Fogel <kfogel@floss.red-bean.com>
-
- * pcl-cvs.el (cvs-mode-map): conform to Emacs 19 keybinding
- conventions by not binding any regular letters under C-c.
-
-Fri Feb 9 14:29:07 1996 Jim Blandy <jimb@totoro.cyclic.com>
-
- * Makefile.in (mostlyclean clean realclean): Remove 'realclean'
- from this target list; it's already defined later in the file.
-
-Tue Jan 23 13:02:24 1996 Greg A. Woods <woods@most.weird.com>
-
- * pcl-cvs.el (pcl-cvs-bugs-address): change the default address
- as suggested by Per Cederqvist.
- * pcl-cvs.el: removed comments refering to Signum, etc.
-
-Sun Jan 21 12:51:12 1996 Greg A. Woods <woods@most.weird.com>
-
- * pcl-cvs.el (cvs-parse-stderr): fix typo (missing '\') that was
- causing occasional un-reported, un-traced, failures that simply
- said something like "RE missing '\(' or '\\('" -- hopefully this
- is the last such bug!
-
-Tue Jan 16 13:57:16 1996 Jim Kingdon <kingdon@harvey.cyclic.com>
-
- * Makefile.in: Rename "dist" target back to "dist-dir". The
- latter is what actually gets used.
- (pcl-cvs.dvi): Restore srcdir to pcl-cvs.texinfo. Fix typo
- (pcl-cvs.texifo -> pcl-cvs.texinfo).
- (TEXINDEX,TEX,SET_TEXINPUTS): New variables.
- (.el.elc): Copy .el file to build dir so .elc file gets put there.
- (dist-dir): Fix typo (cvs.info -> pcl-cvs.info).
- * cookie.el: New file, copied from elib 1.0.
- * README: Remove note about requiring elib; it claimed that CVS
- contained a copy of elib, but it lied.
- * pcl-cvs.el: Change (require 'cookie) to (load "cookie.el").
- * pcl-cvs-lucid.el: Change (require 'pcl-cvs) to (load "pcl-cvs.el").
-
-Fri Jan 12 10:32:14 1996 Greg A. Woods <woods@most.weird.com>
-
- * pcl-cvs.elc, pcl-cvs-lucid.elc: removed
-
- * pcl-cvs.el: run through the spell checker...
- - noted some free variables in comments
- (cvs-inhibit-copyright-message): move this above
- cvs-startup-message to keep the compiler quiet
-
- * compile-all.el: removed (use make for dependency checking!)
-
- * Makefile.in: tweak various comments and echo messages...
- (elcfiles): removed this target.
- (.SUFFIXES, .el.elc): added support for elisp files.
- (CORE): new macro -- list of files all .elc depend on [still empty]
- (BATCHFLAGS): new macro -- flags to pass to emacs
- (OBJDIR_DISTFILES): added ELCFILES to be shipped in distribution
-
- * README: fix the RCS Id.
-
- * INSTALL: re-copy formatted makeinfo output from pcl-cvs.info,
- just to keep everything in proper synchronisation.
-
- * pcl-cvs.texinfo (Pcl-cvs installation): update to match Karl's
- new wording from INSTALL.
-
-Wed Jan 10 22:04:35 1996 Karl Fogel <kfogel@floss.red-bean.com>
-
- * INSTALL: make first item read a little more smoothly.
-
- * README: note that pcl-cvs has been tested under 19.30.
-
-Wed Jan 10 17:59:00 1996 Greg A. Woods <woods@most.weird.com>
-
- * ChangeLog.woods: these are changes integrated in from my
- own pcl-cvs repository module, and based on the original PCL-CVS
- Version 1.05 release. They include most, if not all, of the
- changes from the Cygnus and Cyclic CVS contrib versions of
- PCL-CVS (i.e. the changes noted below).
-
-Sat Dec 30 15:01:45 1995 Karl Fogel <kfogel@floss.cyclic.com>
-
- * pcl-cvs.el (cvs-changelog-ours-p): check that
- `add-log-full-name' and `add-log-mailing-address' are non-nil, in
- addition to checking that they are boundp.
-
-Thu Dec 21 16:45:48 1995 Karl Fogel <kfogel@occs.cs.oberlin.edu>
-
- * pcl-cvs.el (cvs-parse-stderr): ignore kerberos connection
- failure, since CVS will automatically try rsh next. I think this
- is okay because if a person needs to know that kerberos failed,
- then chances are the rsh failed too, and *that* error message will
- clue them in that something's afoot.
-
-Wed Nov 22 11:01:50 1995 Joshua Cowan <jcowan@hermit.reslife.okstate.edu>
-
- * pcl-cvs.el (cvs-changelog-ours-p): use `user-full-name' if
- `add-log-full-name' unbound, as not every uses the stuff in
- add-log.el. Same with `add-log-mailing-address'.
- (cvs-changelog-entries): change to `change-log-mode' unless
- already in it.
-
-Sun Jul 9 20:57:11 1995 Karl Fogel <kfogel@floss.cyclic.com>
-
- * "/bin/rmdir" as default, not "/usr/local/bin/rmdir".
-
-Fri Jun 16 15:24:34 1995 Jim Kingdon (kingdon@cyclic.com)
-
- * pcl-cvs.elc, pcl-cvs-lucid.elc: Added.
-
- * Makefile.in: Rename from Makefile and set srcdir.
-
-Thu May 18 17:10:27 1995 Jim Blandy <jimb@totoro.bio.indiana.edu>
-
- Automatically guess CVS log entries from ChangeLog contents.
- * pcl-cvs.el (cvs-mode-changelog-commit): New command.
- (cvs-changelog-full-paragraphs): New variable.
- (cvs-changelog-name, cvs-narrow-changelog,
- cvs-changelog-paragraph, cvs-changelog-subparagraph,
- cvs-changelog-entry, cvs-changelog-ours-p, cvs-relative-path,
- cvs-changelog-entries, cvs-changelog-insert-entries, cvs-union,
- cvs-insert-changelog-entries, cvs-edit-delete-common-indentation):
- New functions.
- (cvs-mode-map): Bind 'C' to cvs-mode-changelog-commit.
- (cvs-mode): Mention cvs-mode-changelog-commit in docstring.
-
- Give the info files names ending in ".info".
- * Makefile (INFOFILES, install_info): Change pcl-cvs to
- pcl-cvs.info.
- (pcl-cvs.info): Target renamed from pcl-cvs.
- (DISTFILES): pcl-cvs removed; we handle the info files explicitly
- in the dist-dir target.
- (dist-dir): Depend on pcl-cvs.info. Distribute pcl-cvs.info*.
- * pcl-cvs.texinfo: Change @setfilename appropriately.
- * INSTALL: Updated.
- * .cvsignore: Correctly ignore the info files.
-
- * README: Note that pcl-cvs has been tested under 19.28, and that
- the "cookie" naming conflict was resolved in 19.11.
-
- * Makefile (pcl-cvs-lucid.elc): Changed this target from
- pcl-cvs-lucid.el. That's a source file, for goodness' sake!
-
-Tue May 9 13:56:50 1995 Jim Blandy <jimb@totoro.bio.indiana.edu>
-
- * Change references to "Cygnus's remote CVS" to "Cyclic CVS".
-
-Wed May 3 13:55:27 1995 Jim Blandy <jimb@totoro.bio.indiana.edu>
-
- * pcl-cvs.el (cvs-parse-stderr): Handle colons after both
- "rcsmerge" and "warning".
-
-Fri Apr 28 22:38:14 1995 Jim Blandy <jimb@totoro.bio.indiana.edu>
-
- * Makefile (ELFILES): Include pcl-cvs-startup.el.
- (info, pcl-cvs): Call makeinfo appropriately for modern versions.
- (pcl-cvs.aux): List dependency on pcl-cvs.texinfo.
- (pcl-cvs.ps): New target.
- (DVIPS): New variable.
- (dist-dir): Renamed from dist, updated to accept DISTDIR value
- passed from parent.
- (DISTFILES): New varible.
- (pcl-cvs.elc, pcl-cvs-lucid.elc): Add targets to elcfiles target.
-
-Tue Apr 25 21:33:49 1995 Jim Blandy <jimb@totoro.bio.indiana.edu>
-
- * pcl-cvs.el: (cvs-parse-stderr): Recognize "conflicts" as well as
- "overlaps" before "during merge."
-
-Thu Feb 16 12:17:20 1995 Jim Blandy <jimb@totoro.bio.indiana.edu>
-
- * pcl-cvs.el (cvs-parse-stderr): Recognize "conflicts found in..."
- messages attributed to "cvs server", as well as "cvs update".
-
-Sat Feb 4 01:47:01 1995 Jim Blandy <jimb@totoro.bio.indiana.edu>
-
- * pcl-cvs.el: Deal with the 'P' action, produced by remote CVS.
- (cvs-parse-stdout): Treat 'P' like 'U' --- file is updated.
-
-Tue Jan 31 23:31:39 1995 Jim Blandy <jimb@totoro.bio.indiana.edu>
-
- * pcl-cvs.el (cvs-cvsroot-required): New variable.
- (cvs-do-update): If cvs-cvsroot-required is not set, don't complain if
- CVSROOT and cvs-cvsroot are both unset.
-
-Sun Jan 22 21:22:22 1995 Jim Blandy <jimb@totoro.bio.indiana.edu>
-
- * pcl-cvs.el (cvs-parse-stderr):
- Some changes for Cygnus's Remote CVS. Treat
- messages like "cvs server: Updating DIRECTORY" as we treat those like
- "cvs update: Updating DIRECTORY". Ignore other messages starting with
- "cvs server".
-
- * pcl-cvs.el (cvs-parse-stderr): Re-indent.
-
- * .cvsignore: Add ignore list for Texinfo litter.
-
- * Makefile (lispdir): Set appropriately for totoro.
- * pcl-cvs.el (cvs-program, cvs-diff-program, cvs-rmdir-program): Same.
-
-Tue Jun 1 00:00:03 1993 Per Cederqvist (ceder@lysator.liu.se)
-
- * Release 1.05. (This release was promised before the end of May,
- but I didn't quite make it. No, I didn't fake the date above).
-
-Mon May 31 01:32:25 1993 Per Cederqvist (ceder@lysator.liu.se)
-
- * Removed the elib sub-directory. Users must now get the Elib
- library separately.
- * pcl-cvs.texinfo: Document it.
-
- * pcl-cvs-lucid.el: A new version, supplied by Jamie Zawinsky,
- added.
-
- * pcl-cvs Id 68: Transform RCS keywords
- * Makefile (pcl-cvs-$(VER)): Remove the $ signs in most files in
- the distribution.
-
- * pcl-cvs Id 76: Extra " in cvs-mode-add.
- * pcl-cvs.el (cvs-mode-add): Don't add the extra level of quotes
- around the log message, since it doesn't work with CVS.
-
- * pcl-cvs Id 56: '-d <CVSROOT>' support in pcl-cvs
- * pcl-cvs.el (cvs-change-cvsroot): New function.
-
- * pcl-cvs Id 77: *cvs* isn't cleared properly
- * pcl-cvs.el (cvs-do-update): Always erase the *cvs* buffer and
- re-create the collection.
-
- * pcl-cvs.el (cvs-do-update): Set mode-line-process in the *cvs*
- buffer.
- * pcl-cvs.el (cvs-mode): Reset mode-line-process.
-
- * pcl-cvs Id 59: sort .cvsignore alphabetically!
- * pcl-cvs.el (cvs-sort-ignore-file): New variable.
- * pcl-cvs.el (cvs-mode-ignore): Use it.
- * pcl-cvs.texinfo: Document it.
-
- * pcl-cvs Id 75: Require final newline.
- * pcl-cvs.el (cvs-commit-buffer-require-final-newline): New
- variable.
- * pcl-cvs.el (cvs-edit-done): Use it.
- * pcl-cvs.texinfo: Document it.
-
- * pcl-cvs Id 72: make clean deletes lucid-emacs.el
- * dist-makefile (ELCFILES): Fixed a typo.
-
- * pcl-cvs Id 46: "cvs remove f" "touch f" "cvs update f" -> parse err.
- * pcl-cvs.el (cvs-fileinfo->type): New type: REM-EXIST.
- * pcl-cvs.el (cvs-shadow-entry-p): A REMOVED that follows a
- REM-EXIST is a shadow.
- * pcl-cvs.el (cvs-parse-stderr): Recognize the "should be removed
- and is still there" message.
- * pcl-cvs.el (cvs-pp): Recognize REM-EXIST.
- * pcl-cvs.el (cvs-mode-undo-local-changes): Recognize and complain
- about REM-EXIST. Defensive test added: complain about unknown types.
-
- * pcl-cvs.el (cvs-mode-add): Add an extra level of quotes around
- the log message. This is apparently needed by RCVS. <This change
- has been removed. --ceder>.
-
- * pcl-cvs.el (cvs-parse-stderr): Ignore output from RCVS.
-
-Tue Apr 27 00:48:40 1993 Per Cederqvist (ceder@lysator.liu.se)
-
- * pcl-cvs.el (cvs-startup-message): Now a defconst instead of a
- defvar.
- * pcl-cvs.el (cvs-mode-commit): Add a defvar for it.
-
- * dist-makefile (EMACS): Use $(EMACS) instead of hard-coding 'emacs'.
-
-Sat Apr 17 12:47:10 1993 Per Cederqvist (ceder@lysator.liu.se)
-
- * Release 1.04.
-
- * pcl-cvs.texinfo: Updated the Contributors node.
-
- * pcl-cvs Id 58: Lucid GNU Emacs support
- * pcl-cvs-lucid.el: New file, contributed by the people at Lucid.
- * pcl-cvs.el: Autoload pcl-cvs-lucid if running in an Lucid GNU
- Emacs.
- * compile-all.el: (files-to-compile): Add pcl-cvs-lucid.
- * dist-makefile (ELFILES, ELCFILES): Dito.
-
- * pcl-cvs Id 55: cvs-diff-backup swaps old and new version.
- * pcl-cvs.el (cvs-diff-backup-extractor): Old version should be
- first.
- * pcl-cvs.el (cvs-mode-diff-backup): Call cvs-backup-diffable
- correctly.
-
- * pcl-cvs Id 64: elib substitute
- * dist-makefile (install): Warn about Elib.
- * pcl-cvs.texinfo: Talk about Elib.
-
- * pcl-cvs Id 50: Committing the *commit* buffer twice.
- * pcl-cvs.el (cvs-edit-done): Report an error if cvs-commit-list
- is empty, and empty it when the commit is done.
-
- * pcl-cvs Id 56: '-d <CVSROOT>' support.
- * pcl-cvs.el (cvs-cvsroot): New variable.
- * pcl-cvs.el (cvs-do-update, all callers of cvs-execute-list): Use
- it everywhere CVS is called, to override CVSROOT.
- * pcl-cvs.texinfo (Customization): Document it.
-
-Thu Apr 1 00:34:55 1993 Per Cederqvist (ceder@lysator.liu.se)
-
- * pcl-cvs.el (cvs-retrieve-revision-to-tmpfile): Exit status nil
- from call-process means everything was successful in some Emacs
- versions.
-
- * pcl-cvs.el (cvs-mode-map): Bind "q" to bury-buffer.
- * pcl-cvs.texinfo: Document it.
-
-Thu Mar 11 00:05:03 1993 Per Cederqvist (ceder@lysator.liu.se)
-
- * Release 1.03-Emerge (not released).
-
- * Makefile (pcl-cvs-$(VER)): Don't includ elib-dll-debug.el in the
- distribution. (It's included as elib/dll-debug.el).
-
- * pcl-cvs.el (cvs-mode): Document the "e" key (cvs-mode-emerge).
-
-Tue Mar 9 00:02:57 1993 Per Cederqvist (ceder@lysator.liu.se)
-
- * pcl-cvs.texinfo (Emerge): New node.
-
- * pcl-cvs.el (cvs-kill-buffer-visiting): New function.
-
- * pcl-cvs.el (cvs-mode-emerge): Handle Conflict and Merged files.
-
- * pcl-cvs.el (cvs-retrieve-revision-to-tmpfile): Handle any revision.
-
- * pcl-cvs.el (cvs-fileinfo-*): Store base-revision instead of
- backup-file.
-
- * pcl-cvs.el (cvs-backup-diffable): The file is only diffable if
- the backup file is readable.
-
- * pcl-cvs.el (cvs-mode-map): Bind "e" to cvs-mode-emerge instead
- of cvs-mode-find-file (which is anyhow bound to "f").
-
-Mon Mar 8 23:06:52 1993 Per Cederqvist (ceder@lysator.liu.se)
-
- * pcl-cvs.el (cvs-mode-emerge): New function. Currently only
- handles emerge of Modified files.
-
- * pcl-cvs.el (cvs-retrieve-revision-to-tmpfile): New function.
-
-Sun Jan 24 20:07:18 1993 Per Cederqvist (ceder@lysator.liu.se)
-
- * elib-dll-debug.el: Moved to elib.
-
-Mon Jan 18 00:35:59 1993 Per Cederqvist (ceder@mauritz)
-
- * pcl-cvs.el (cvs-do-update): Added a probably unnecessary sit-for.
-
- * Release 1.03-Elib-0.05.1 (not released).
-
- * Elib 0.05 compatibility:
- * elib-dll-debug.el, pcl-cvs-buffer.el, test-dll.el: Fix the
- require strings.
- * pcl-cvs.el (cvs-pp): Insert the string.
-
- * Release 1.03-Elib-0.05 (not released).
-
- * elib: New directory, containing the parts of elib that are
- required for pcl-cvs. Changes to the files in that directory
- that are present in Elib are documented in the ChangeLog of
- Elib, not here.
- * Makefile (pcl-cvs-$(VER)): Copy the new dir to the distribution.
- * dist-makefile (ELFILES, ELCFILES): Don't include the Elib files.
-
-Fri Jan 8 02:43:49 1993 Per Cederqvist (ceder@konrad)
-
- * pcl-cvs.el (cvs-mode-map): Bind "e" to cvs-mode-find-file, like
- in dired.
-
-Sun Jan 3 23:25:13 1993 Per Cederqvist (ceder@konrad)
-
- * elib-dll.el, elib-node.el, cookie.el: Moved to the elib package.
- Pcl-cvs now requires elib.
-
-Tue Dec 29 22:06:57 1992 Per Cederqvist (ceder@konrad)
-
- * pcl-cvs.el: Tracked the latest (last?) rename of all functions
- in cookie.el.
-
-Thu Sep 24 00:29:16 1992 Per Cederqvist (ceder@robert)
-
- * pcl-cvs.texinfo (Archives): This version is not distributed with
- CVS 1.3, so don't claim that it is.
-
-Fri Aug 21 15:17:08 1992 Per Cederqvist (ceder@maskros)
-
- * pcl-cvs.el (cvs-parse-stderr): Fixed two "(set head" that should
- be "(setq head".
-
-Thu Aug 20 05:53:58 1992 Per Cederqvist (ceder@robin)
-
- * cookie.el: Changes to this file is documented in the ChangeLog
- of elib in the future.
-
-Tue Aug 18 03:30:28 1992 Per Cederqvist (ceder@robin)
-
- * pcl-cvs.el: Don't use cookie-last-tin (which no longer exists).
-
- * cookie.el: Use prefix cookie:: for internal functions.
-
- * cookie.el: (cookie:enter-after, cookie:enter-before,
- cookie:nth-cookie): Implemented.
- * cookie.el: No longer define (impl).
-
- * cookie.el: More renames:
- cookie:next-cookie -> cookie:goto-next-tin
- cookie:previous-cookie -> cookie:goto-previous-tin
- tin-next -> cookie:next-tin
- tin-previous -> cookie:previous-tin
- tin-nth -> cookie:nth-tin
- tin-delete -> cookie:delete-tin
- cookie:collect -> cookie:collect-cookies
- cookie:tin-collect -> cookie:collect-tins
- (new) -> cookie:tin-collect-cookies
- (new) -> cookie:tin-collect-tins
- cookie:refresh -> cookie:refresh-all
- tin-invalidate-tins -> cookie:invalidate-tins
-
-Mon Aug 17 01:39:49 1992 Per Cederqvist (ceder@robin)
-
- * cookie.el (cookie:set-buffer-bind-dll-let*): New macro. Used in
- many places instead of cookie:set-buffer-bind-dll.
- * cookie.el (cookie:set-buffer-bind-dll): Renamed the macro
- cookie:set-buffer to this.
-
- * pcl-cvs.el (cvs-use-temp-buffer): Set default-directory.
-
-Sun Aug 16 20:51:30 1992 Per Cederqvist (ceder@robin)
-
- * pcl-cvs.el (cvs-add-sub): Fixed call to cvs-add-file-update-buffer.
-
-Sat Aug 8 20:28:21 1992 Per Cederqvist (ceder@robin)
-
- * Release 1.03-Cookie-II (not released).
-
- * pcl-cvs.el (cvs-mode-diff-cvs): Don't care about the exit status
- from ``cvs diff''.
-
- * pcl-cvs.el (cvs-mode): Document cvs-mode-undo-local-changes.
- * pcl-cvs.el (cvs-diffable): New function.
-
- * pcl-cvs.el: Use the new cookie package.
- * pcl-cvs.el (cvs-cookie-handle): New variable.
- * pcl-cvs.el (cvs-do-update): User the new cookie:create
- interface, and cookie:clear if the buffer already existed. Make
- the buffer read-only.
- * pcl-cvs.el (cvs-mode-next-line, cvs-mode-previous-line): New
- functions (used instead of cookie:next-cookie and
- cookie:previous-cookie).
-
- * cookie.el: Major redesign. The handle that is passed to all
- cookie functions is now a new datatype, and not the buffer that
- the cookies resides in. This way it is possible to have more than
- one set of cookies in a buffer. Things that used to be
- buffer-local variables are now fields in the handle data type.
- cookie-last-tin is no longer available.
- * cookie.el (cookie:create): The buffer is not cleared, nor set to
- be read-only.
- * cookie.el (cookie:next-cookie, cookie:previous-cookie): Since
- the first argument is now a handle and not a buffer, these can no
- longer be called interactively. You have to write a small wrapper
- about them.
- * cookie.el (cookie:buffer): New function.
-
-Tue Aug 4 03:02:25 1992 Per Cederqvist (ceder@robert)
-
- * pcl-cvs.texinfo (Bugs): Renamed "Reporting bugs and ideas" to
- "Bugs" and added a table of known bugs/FAQ:s.
-
-Mon Aug 3 00:19:39 1992 Per Cederqvist (ceder@robert)
-
- * pcl-cvs.el, pcl-cvs.texinfo: Big Renaming Time!
- The commands that operate in the *cvs* buffer:
- cvs-add-change-log-entry-other-window -> cvs-mode-add-change-log-entry-other-window
- cvs-mark-all-files -> cvs-mode-mark-all-files
- cvs-revert-updated-buffers -> cvs-mode-revert-updated-buffers
- cvs-undo-local-changes -> cvs-mode-undo-local-changes
- cvs-unmark-up -> cvs-mode-unmark-up
- cvs-acknowledge -> cvs-mode-acknowledge
- cvs-unmark-all-files -> cvs-mode-unmark-all-files
- cvs-add -> cvs-mode-add
- cvs-diff-backup -> cvs-mode-diff-backup
- cvs-commit -> cvs-mode-commit
- cvs-diff-cvs -> cvs-mode-diff-cvs
- cvs-find-file -> cvs-mode-find-file
- cvs-update-no-prompt -> cvs-mode-update-no-prompt
- cvs-ignore -> cvs-mode-ignore
- cvs-log -> cvs-mode-log
- cvs-mark -> cvs-mode-mark
- cvs-find-file-other-window -> cvs-mode-find-file-other-window
- cvs-remove-file -> cvs-mode-remove-file
- cvs-status -> cvs-mode-status
- cvs-remove-handled -> cvs-mode-remove-handled
- cvs-unmark -> cvs-mode-unmark
-
- * pcl-cvs.el (cvs-cvs-diff-flags): Variable deleted.
- * pcl-cvs.el (cvs-diff-cvs): Use cvs-diff-flags instead.
- * pcl-cvs.texinfo (Customization): Update the doc.
-
- * pcl-cvs.el (cvs-diff-cvs): Handle exit status 0 (no diffs), 1
- (diffs) and other (error).
- * pcl-cvs.el (cvs-execute-list): Add support for this kind of
- thing.
-
- * Revert buffers for committed files:
- * pcl-cvs.el (cvs-auto-revert-after-commit): New variable.
- * pcl-cvs.texinfo (Committing changes, Customization): Document
- it.
- * pcl-cvs.el (cvs-after-commit-function): New function.
-
- * pcl-cvs.el (cvs-execute-list): Return the exit status or nil.
- * pcl-cvs.el (cvs-edit-done, cvs-diff-cvs, cvs-remove-file,
- cvs-undo-local-changes, cvs-add, cvs-status, cvs-log): Use the
- exit status to generate an error message.
-
-
- * pcl-cvs.el (cvs-do-update): It should be "cvs -n update -l", not
- "cvs -l update -n". Put the -n and/or -l in the message that is
- displayed in the *cvs* buffer during the update.
-
-Sat Aug 1 00:55:49 1992 Per Cederqvist (ceder@robert)
-
- * cookie.el (cookie-sort): New function.
-
- * cookie.el (cookie-clear): Rewritten. No longer clears all local
- variables.
-
-Tue Jul 28 17:21:17 1992 Per Cederqvist (ceder@robin)
-
- * pcl-cvs.el (cvs-parse-stderr): Try to handle the output from RCS
- when it is compiled without DIFF3_BIN and a conflict occurs.
-
- * pcl-cvs.texinfo (Getting Started): Fixed typo.
-
- * pcl-cvs-startup.el (cvs-update-other-window): Make the autoload
- be interactive.
-
-Mon Jul 27 19:36:40 1992 Per Cederqvist (ceder@robin)
-
- * pcl-cvs.el (cvs-revert-updated-buffers, cvs-revert-fileinfo):
- New functions.
- * pcl-cvs.texinfo (Reverting your buffers): Document it.
-
- * pcl-cvs.el (cvs-fileinfo->full-path): New function.
- * pcl-cvs.el (cvs-full-path): Use it.
-
- * cookie.el (cookie-map, cookie-map-reverse): Better doc-
- string. Removed the unused local variable 'result'.
-
- * compile-all.el: Renamed elib-files to files-to-compare.
- * compile-all.el (compile-pcl-cvs): Bind load-path in a let
- statement instead of globally.
-
-Thu Jul 23 19:02:41 1992 Per Cederqvist (ceder@robin)
-
- * pcl-cvs.el (cvs-do-update): Check that CVSROOT is set.
- * pcl-cvs.el (cvs-diff-cvs): Check that cvs-cvs-diff-flags is a
- list.
- * pcl-cvs.el (cvs-diff-backup): Check that cvs-diff-flags is a
- list.
-
-Tue Jul 21 11:27:39 1992 Per Cederqvist (ceder@robin)
-
- * pcl-cvs.el (cvs-parse-error): Make the *cvs* buffer writeable
- before trying to write the email message. Require sendmail before
- trying to switch to mail-mode.
-
- * pcl-cvs.el (cvs-do-update): Check that cvs-program exists.
-
- * pcl-cvs.el (cvs-skip-line): Fixed bracketing error.
-
-Mon Jul 20 10:31:51 1992 Per Cederqvist (ceder@robin)
-
- * Release 1.03.
-
- * pcl-cvs.el, cookie.el: Indentation fixes.
-
- * Makefile (pcl-cvs-$(VER)): Include NEWS in the distribution.
-
- * pcl-cvs.el (cvs-rm-program): Deleted.
- * pcl-cvs.el (cvs-rmdir-program, cvs-lock-file): New variables.
-
- * Handle lock files in a nicer way:
- * pcl-cvs.el (cvs-update-filter, cvs-delete-lock,
- cvs-lock-file-p): New functions.
- * pcl-cvs.el (cvs-do-update, cvs-sentinel): Redirect stdout to the
- temporary file, not stderr. Use cvs-update-filter.
- * pcl-cvs.el (cvs-parse-update): New arguments.
- * pcl-cvs.el (cvs-parse-buffer): Renamed to cvs-parse-update.
- * pcl-cvs.el (cvs-stderr-file): Renamed to cvs-stdout-file.
- * pcl-cvs.texinfo (Miscellaneous commands, Updating the
- directory): Document cvs-delete-lock.
-
- * pcl-cvs.el (cvs-mode): Don't reset buffer-read-only.
-
- * pcl-cvs.el (cvs-find-file-other-window): Don't save-some-buffers.
-
-Thu Jul 16 00:19:58 1992 Per Cederqvist (ceder@robin)
-
- * pcl-cvs.el, test-cookie-el: Use the new names from cookie.el.
-
- * cookie.el: Big Renaming Time!
- External functions:
- cookie-next -> tin-next
- cookie-previous -> tin-previous
- cookie-nth -> tin-nth
- cookie-delete -> tin-delete
- cookie-filter-tins -> tin-filter
- cookie-get-selection -> tin-get-selection
- cookie-start-marker -> tin-start-marker
- cookie-end-marker -> tin-end-marker
- cookie-invalidate-tins -> tin-invalidate-tins
- cookie-collect-tins -> tin-collect
- cookie-collect-cookies -> cookie-collect
- Internal functions:
- cookie-create-tin -> cookie-create-wrapper
- cookie-tin-start-marker -> cookie-wrapper-start-marker
- cookie-tin-cookie-safe -> cookie-wrapper-cookie-safe
- cookie-tin-cookie -> cookie-wrapper-cookie
- set-cookie-tin-start-marker -> cookie-wrapper-set-start-marker
- set-cookie-tin-cookie -> cookie-wrapper-set-cookie
- cookie-tin-p -> cookie-wrapper-p
- cookie-create-tin-and-insert -> cookie-create-wrapper-and-insert
-
- * pcl-cvs.el (cvs-find-file, cvs-find-file-other-window): Signal
- an appropriate error message if the *cvs* buffer is empty.
-
- * cookie.el (cookie-create): Make the buffer read-only.
- * cookie.el (cookie-create-tin-and-insert, cookie-refresh,
- cookie-delete-tin-internal, cookie-refresh-tin): Bind
- buffer-read-only to nil while changing the contents of
- the buffer.
-
- * pcl-cvs.el (cvs-byte-compile-files): New function.
- * pcl-cvs.texinfo (Miscellaneous commands): Document it.
-
- * pcl-cvs.el (cvs-diff-ignore-marks): New variable.
- * pcl-cvs.el (cvs-diff-cvs, cvs-diff-backup): Don't consider
- marked files to be selected if a prefix argument is given XOR the
- variable cvs-diff-ignore-marks is non-nil.
- * pcl-cvs.el (cvs-get-marked): New optional argument `ignore-marks'.
- * pcl-cvs.texinfo (Customization, Viewing differences): Document
- this behaviour.
-
- * pcl-cvs.el (cvs-undo-local-changes): New function.
- * pcl-cvs.texinfo (Undoing changes): Document
- cvs-undo-local-changes.
- * pcl-cvs.el (cvs-mode-map): cvs-unmark-all-files moved from "U"
- to "ESC DEL". cvs-undo-local-changes bound to "U".
- * pcl-cvs.texinfo (Marking files): Document ESC DEL.
-
- * pcl-cvs.el (cvs-skip-line): New arguments. All callers updated.
- Now calls cvs-parse-error if a parse error occurs.
- * pcl-cvs.el (cvs-parse-error): New function that creates a bug
- report.
- * pcl-cvs.el (cvs-parse-stderr, cvs-parse-stdout): New arguments.
- The only caller (cvs-parse-buffer) updated. Call cvs-parse-error
- in case of parse error.
-
- * pcl-cvs.el (pcl-cvs-version): New variable.
-
- * cookie.el (cookie-create): Kill all local variables in the buffer.
-
-Fri Jul 10 11:17:40 1992 Per Cederqvist (ceder@robin)
-
- * Release 1.03beta1.
-
-Thu Jul 9 03:12:00 1992 Per Cederqvist (ceder@robin)
-
- * pcl-cvs.el (cvs-update-running): New variable.
- * pcl-cvs.el (cvs-do-update): Use it instead of the previous local
- variable cvs-process (that no longer exists). Make sure that only
- one `cvs update' runs at any given moment.
- * pcl-cvs.el (cvs-sentinel): Reset cvs-update-running when the
- update process exits.
-
- * pcl-cvs.el (cvs-update): Switch to the *cvs* buffer.
- * pcl-cvs.el (cvs-update-other-window): New function.
- * pcl-cvs-startup.el (cvs-update-other-window): Added a autoload
- for it.
- * pcl-cvs.el (cvs-do-update): Don't pop up any buffer in a window
- - let cvs-update or cvs-update-other-window handle that. Also
- don't kill the *cvs* buffer, but rather insert a "Running cvs..."
- message into it.
- * pcl-cvs.el (cvs-parse-buffer): Don't change the window
- configuration.
-
- * pcl-cvs.el (cvs-create-fileinfo, cvs-pp, cvs-fileninfo->type):
- New type for a fileinfo: MESSAGE.
-
- * pcl-cvs.el (cvs-cvs-buffer): Deleted the variable. Use
- cvs-buffer-name instead. (I no longer have any plans to allow more
- than one cvs update to run at the same time - things only get
- confusing). Changed all places where cvs-cvs-buffer was used.
-
- * pcl-cvs.el: Take care of update programs (the -u option in the
- modules file):
- * pcl-cvs.el (cvs-update-prog-output-skip-regexp): New variable.
- * pcl-cvs.el (cvs-parse-stdout): Skip output from the update
- program (using cvs-update-prog-output-skip-regexp).
- * pcl-cvs.texinfo (Future enhancements): Document that the
- solution is not as good as it should be.
- * pcl-cvs.texinfo (Customization): Document the variable.
-
-Wed Jul 8 20:29:44 1992 Per Cederqvist (ceder@robin)
-
- * pcl-cvs.el (cvs-do-update): Check that this-dir really exists
- and is a directory, and that this-dir/CVS exists and is a
- directory.
-
-Tue Jul 7 01:02:24 1992 Per Cederqvist (ceder@robin)
-
- * pcl-cvs.texinfo (Customization): Document TMPDIR.
-
- * This chunk of modifications should make it possible to run
- pcl-cvs on hosts that do not line-buffer stdout (such as
- DECstation). They work by diverting stdout and stderr from
- `cvs update' and later sorting them together.
- * pcl-cvs.el (cvs-parse-stderr): Don't fail to parse conflict
- data.
- * pcl-cvs.el (cvs-remove-stdout-shadows, cvs-shadow-entry-p): New
- functions.
- * pcl-cvs.el (cvs-parse-buffer): Use it.
- * pcl-cvs.el (cvs-remove-empty-directories): New function.
- * pcl-cvs.el (cvs-remove-handled, cvs-parse-buffer): Use it.
- * pcl-cvs.el (cvs-get-current-dir): New argument ROOT-DIR. All
- calls to cvs-get-current-dir updated.
- * pcl-cvs.el (cvs-do-update): Allocate a tmp file. Use cvs-shell
- (typically /bin/sh) to redirect stderr from CVS to the tmp file.
- * pcl-cvs.el (cvs-sentinel): Handle the tmp file. Remove it when
- it is parsed.
- * pcl-cvs.el (cvs-parse-buffer): New argument STDERR-BUFFER. All
- calls to cvs-parse-buffer updated. Rewritten to handle the
- separation of stderr and stdout.
- * pcl-cvs.el (cvs-shell, cvs-stderr-file): New variables.
- * pcl-cvs.el (cvs-compare-fileinfos, cvs-parse-stderr,
- cvs-parse-stdout): New functions.
-
- * pcl-cvs.el (cvs-parse-buffer): Some modifications for output
- from RCS 5.6.
-
-Tue Apr 7 09:11:27 1992 Per Cederqvist (ceder@leopold)
-
- * Release 1.02.
-
- * pcl-cvs.el (cvs-diff-backup, cvs-edit-done, cvs-status): Call
- save-some-buffers.
-
- * pcl-cvs.el (cvs-diff-backup-extractor): Fixed syntax error.
-
- * Makefile, README, compile-all.el, dist-makefile, pcl-cvs.el,
- pcl-cvs.texinfo (XXRELEASEXX): A magic string that is substituted
- for the current release number when a distribution is made.
- (Release 1.01 says that it is release 1.00).
-
- * pcl-cvs.el (cvs-find-file): Added missing pair of parenthesis.
-
-Mon Mar 30 14:25:26 1992 Per Cederqvist (ceder@leopold)
-
- * Release 1.01.
-
- * pcl-cvs.el (cvs-parse-buffer): The message when waiting for a
- lock has been changed.
-
-Sun Mar 29 05:29:57 1992 Per Cederqvist (ceder@leopold)
-
- * Release 1.00.
-
- * pcl-cvs.el (cvs-do-update, cvs-sentinel, cvs-parse-buffer):
- Major rewrite of buffer and window selection and handling.
- The *cvs* buffer is now killed whenever a new "cvs update" is
- initiated. The -update buffer is replaced with the *cvs*
- buffer when the update is completed.
-
-Sat Mar 28 21:03:05 1992 Per Cederqvist (ceder@robin)
-
- * pcl-cvs.el (cvs-delete-unused-temporary-buffers): Fixed it.
-
- * pcl-cvs.el (cvs-auto-remove-handled): New variable.
- * pcl-cvs.el (cvs-edit-done): Use it.
- * pcl-cvs.texinfo (Customization, Removing handled entries):
- Document it.
-
- * pcl-cvs.el (cvs-mode): Turn of the undo feature. It really
- isn't useful in a cookie buffer...
-
- * pcl-cvs.el (cvs-edit-done): Committing a file now looks more
- like diffing a file. The window handling is better.
- * pcl-cvs.el (cvs-use-temp-buffer): The &optional switch is no
- longer needed.
-
-Mon Mar 23 00:20:33 1992 Per Cederqvist (ceder@robin)
-
- * Release 0.97.
-
- * pcl-cvs.el (default-directory): Make sure it always ends in a
- slash. fileinfo->dir does NOT end in a slash, and I had forgotten
- to call file-name-as-directory in various places.
-
- * pcl-cvs.el (cvs-diff-backup-extractor): Signal an error if a
- fileinfo without backup file is given.
-
- * pcl-cvs.el (cvs-mode): Added documentation.
-
- * pcl-cvs.el (cvs-execute-list): Fix the order of files in the
- same directory.
-
- * pcl-cvs.el (cvs-log-flags, cvs-status-flags): New variables.
- * pcl-cvs.el (cvs-log, cvs-status): Use them.
- * pcl-cvs.texinfo (Customization): Document them.
-
- * pcl-cvs.el (cvs-diff-backup): Filter non-backup-diffable files
- at an earlier stage, like cvs-commit does.
-
- * pcl-cvs.el (cvs-diff-flags): New variable.
- * pcl-cvs.el (cvs-diff-backup): Use it.
- * pcl-cvs.texinfo (Customization): Document it.
-
- * pcl-cvs.el (cvs-execute-single-file-list): Remove &rest before
- last argument. No callers needed updating.
-
- * pcl-cvs.el (cvs-execute-list): Remove the &rest before the last
- argument (constant-args). Update all callers of cvs-execute-list
- to use the new calling convention.
- * pcl-cvs.el (cvs-cvs-diff-flags): Now a list of strings instead
- of a string.
- * pcl-cvs.texinfo (Customization): Document the change to
- cvs-cvs-diff-flags.
-
- * Release 0.96.
-
- * pcl-cvs.el (cvs-cvs-diff-flags): New variable.
- * pcl-cvs.el (cvs-diff-cvs): Use it.
- * pcl-cvs.texinfo (Customization, Viewing differences): Document it.
-
- * pcl-cvs.el (cvs-use-temp-buffe): Don't switch to the temporary
- buffer. Use display-buffer and set-buffer instead. This way
- cvs-log, cvs-status, cvs-diff-cvs and friends don't select the
- temporary buffer. The cursor will remain in the *cvs* buffer.
-
-Sun Mar 22 21:50:18 1992 Per Cederqvist (ceder@robin)
-
- * pcl-cvs.el (cvs-find-file, cvs-find-file-other-window): Don't
- prompt when reading in a directory in dired.
-
- * Makefile (pcl-cvs-$(VER)): Include pcl-cvs-startup.el in the
- distribution.
-
- * dist-makefile (pcl-cvs.dvi): Don't fail even if texindex does
- not exist.
-
- * pcl-cvs.texinfo (@setchapternewpage): Changed from 'off' to 'on'.
- * pcl-cvs.texinfo (Variable index): Joined into function index.
- * pcl-cvs.texinfo (Key index): add a description about the key.
- * pcl-cvs.texinfo: Many other small changes.
-
-Wed Mar 18 01:58:38 1992 Per Cederqvist (ceder@leopold)
-
- * Use GNU General Public License version 2.
-
diff --git a/contrib/cvs/tools/pcl-cvs/ChangeLog.woods b/contrib/cvs/tools/pcl-cvs/ChangeLog.woods
deleted file mode 100644
index 827c3f2e3fd7..000000000000
--- a/contrib/cvs/tools/pcl-cvs/ChangeLog.woods
+++ /dev/null
@@ -1,383 +0,0 @@
-Thu Jan 4 13:19:20 1996 Greg A. Woods <woods@most.weird.com>
-
- * pcl-cvs.el:
- - from Cyclic CVS version:
-
- Sat Dec 30 15:01:45 1995 Karl Fogel <kfogel@floss.cyclic.com>
-
- * pcl-cvs.el (cvs-changelog-ours-p): check that
- `add-log-full-name' and `add-log-mailing-address' are non-nil, in
- addition to checking that they are boundp.
-
-Fri Dec 22 17:52:17 1995 Greg A. Woods <woods@most.weird.com>
-
- * pcl-cvs.el:
- - (cvs-parse-stdout): make the "connection timed out" an error
-
- - from Cyclic CVS version:
-
- Thu Dec 21 16:45:48 1995 Karl Fogel <kfogel@occs.cs.oberlin.edu>
-
- * pcl-cvs.el (cvs-parse-stderr): ignore kerberos connection
- failure, since CVS will automatically try rsh next. I think this
- is okay because if a person needs to know that kerberos failed,
- then chances are the rsh failed too, and *that* error message will
- clue them in that something's afoot.
-
-Thu Dec 21 21:13:10 1995 Greg A. Woods <woods@most.weird.com>
-
- * pcl-cvs.el:
- - (cvs-parse-stdout): handle "Permission denied" (which will
- often precede the "premature EOF from server" message....)
-
- - from Cyclic CVS version:
-
- Wed Nov 22 11:01:50 1995 Joshua Cowan <jcowan@hermit.reslife.okstate.edu>
-
- * pcl-cvs.el (cvs-changelog-ours-p): use `user-full-name' if
- `add-log-full-name' unbound, as not every uses the stuff in
- add-log.el. Same with `add-log-mailing-address'.
- (cvs-changelog-entries): change to `change-log-mode' unless
- already in it.
-
- * ToDo:
- - more new ideas....
-
-Mon Nov 27 23:19:50 1995 Greg A. Woods <woods@most.weird.com>
-
- * pcl-cvs.el:
- - add more support for recognizing unknown directories
- - add initial support for properly supporting directories with cvs-mode-add
-
-Tue Nov 21 16:51:45 1995 Greg A. Woods <woods@most.weird.com>
-
- * pcl-cvs.el:
- - fix up the debug mail message buffer formatting
- - include bugs@most.weird.com on debug message list (i.e. my gnats)
- (cvs-parse-stderr): fix up handling of some transient errors, such as
- network server errors
-
-Mon Nov 20 19:13:34 1995 Greg A. Woods <woods@most.weird.com>
-
- * Makefile:
- - minor tweaks on version numbers, etc.
- - added '-n -q' to emacs arguments...
-
- * pcl-cvs.texinfo:
- - mention new pcl-cvs release properly
- - mention new CVS release
- - fix grammar & layout style here and there...
- - move GPL to the bottom and into an included file (should ref another
- info document)
- - add Ediff documentation, fix up Emerge docs.
- - updated Contributors section
- - add note about 'Patched' state (FIXME: more remote docs needed!!!!)
- - added some documentation for cvs-mode-changelog-commit
- - added a few more index entries, etc.
-
- * pcl-cvs.el:
- - update comments and documentation, fix grammar, etc.
- - mention new CVS release
- - re-sort cvs-mode-map setup, document key-map convention
- - re-write (cvs-mode-ediff), adding (cvs-old-ediff-interface)
- - fix (cvs-retrieve-revision-to-tmpfile) to handle empty revision arg.
-
- * ToDo:
- - lots of new ideas
- - give up on 'C-u' for cvs-mode-*
- - minor prioritisation
-
-Thu Nov 16 20:38:58 1995 Greg A. Woods <woods@most.weird.com>
-
- * pcl-cvs.el (cvs-mode-emerge):
- fix the quit-hook setup for ediff-*
- (cvs-mode-ediff): new, based on cvs-mode-emerge
-
- * pcl-cvs.el (cvs-mode-emerge):
- cleanups and use emerge-hooks, and protect from
- multiple invocations (idea from Loren James Rittle <rittle@comm.mot.com>)
-
- * pcl-cvs.el (cvs-diff-program):
- document problems with vendor versions
-
- * pcl-cvs.el, ToDo:
- - add minimal "cvs tag" and "cvs rtag" support
- (cvs-mod): clean up the documentation
- (cvs-mode-map): clean up a bit too
- (cvs-mode-log), (cvs-mode-status): clean up implementation
-
-Wed Nov 15 18:39:22 1995 Greg A. Woods <woods@most.weird.com>
-
- * pcl-cvs.el, ToDo:
- (cvs-parse-stderr) - handle some more error messages from CVS
-
- * pcl-cvs.el:
- Various tweaks and fixes after diffing with CVS-1.6.1 version:
- - spelling/typos
- - minor re-indentation
- - missed one check for PATCHED
- - more documentation and comment fixups
-
- * pcl-cvs.el:
- From: Loren James Rittle <rittle@comm.mot.com>
- To: info-cvs@prep.ai.mit.edu
- Subject: Change to allow pcl-cvs to use ediff instead of emerge
- Date: Mon, 6 Nov 95 17:17:31 CST
-
- 2) ensures the user wants to `update' in cases where a possible conflict
- currectly exists;
-
- * pcl-cvs.el:
- Message-Id: <9511062119.AA29213@supra.comm.mot.com>
- From: Loren James Rittle <rittle@comm.mot.com>
- To: info-cvs@prep.ai.mit.edu
- Subject: Change to allow pcl-cvs to use more hidden buffer names
- Date: Mon, 6 Nov 95 15:19:57 CST
-
-
- PCL-CVS uses hidden buffers in some places. This patch makes more
- PCL-CVS buffers hidden.
-
- Loren
-
-Tue Nov 14 20:56:41 1995 Greg A. Woods <woods@most.weird.com>
-
- * pcl-cvs.el (cvs-do-removal):
- don't fail if the file is missing or a directory
- (cvs-mode-add-change-log-entry-other-window): get the
- change-log-filename and entry name right
-
- * pcl-cvs.el, ChangeLog:
- * pcl-cvs.el (local-path, local-gnu-path): added documentation
- string
- (cvs-rmdir-program): use the proper default and leave it alone
-
- * pcl-cvs.el:
- - from ccvs official sources:
- revision 1.12
- pcl-cvs.el 1995/05/19 01:59:26 jimb
- Automatically guess CVS log entries from ChangeLog contents.
- * pcl-cvs.el (cvs-mode-changelog-commit): New command.
- (cvs-changelog-full-paragraphs): New variable.
- (cvs-changelog-name, cvs-narrow-changelog,
- cvs-changelog-paragraph, cvs-changelog-subparagraph,
- cvs-changelog-entry, cvs-changelog-ours-p, cvs-relative-path,
- cvs-changelog-entries, cvs-changelog-insert-entries, cvs-union,
- cvs-insert-changelog-entries, cvs-edit-delete-common-indentation): New functions.
- (cvs-mode-map): Bind 'C' to cvs-mode-changelog-commit.
- (cvs-mode): Mention cvs-mode-changelog-commit in docstring.
-
- * ChangeLog:
- - from ccvs official sources:
- revision 1.12
- ChangeLog 1995/05/19 01:59:26 jimb
- Automatically guess CVS log entries from ChangeLog contents.
- * pcl-cvs.el (cvs-mode-changelog-commit): New command.
- (cvs-changelog-full-paragraphs): New variable.
- (cvs-changelog-name, cvs-narrow-changelog,
- cvs-changelog-paragraph, cvs-changelog-subparagraph,
- cvs-changelog-entry, cvs-changelog-ours-p, cvs-relative-path,
- cvs-changelog-entries, cvs-changelog-insert-entries, cvs-union,
- cvs-insert-changelog-entries, cvs-edit-delete-common-indentation): New functions.
- (cvs-mode-map): Bind 'C' to cvs-mode-changelog-commit.
- (cvs-mode): Mention cvs-mode-changelog-commit in docstring.
-
- * pcl-cvs.el:
- - slight variant of this change ccvs official sources
- revision 1.10
- pcl-cvs.el 1995/05/03 18:56:20 jimb
- (cvs-parse-stderr): Handle colons after both "rcsmerge" and "warning".
-
- * pcl-cvs.el:
- - from ccvs official sources
- revision 1.9
- pcl-cvs.el 1995/04/26 02:36:15 jimb
- (cvs-parse-stderr): Recognize "conflicts" as well as "overlaps" before
- "during merge."
- - also fixed a few other minor inconsitencies in that region...
-
- * pcl-cvs.el:
- - from ccvs official sources
- revision 1.5
- pcl-cvs.el 1995/01/31 23:31:39 jimb
- (cvs-cvsroot-required): New variable.
- (cvs-do-update): If cvs-cvsroot-required is not set, don't complain if
- CVSROOT and cvs-cvsroot are both unset.
-
- * pcl-cvs.el:
- - use 'identity instead of '(lambda (foo) foo)
- - fix a botch in cvs-make-list
- - check cvs-status-flags and cvs-log-flags are lists before using them
-
-Mon Nov 13 23:49:25 1995 Greg A. Woods <woods@most.weird.com>
-
- * pcl-cvs.el:
- - fixed up version strings
- - minor changes to cvs-*-flags defaults
- - added functions parse-string and cvs-make-list
- - modified various parsers to handle "cvs server:" messages
- - added support for "P" flag (PATCHED)
- - fixed use of "-Q" for "cvs status"
- - use cvs-make-list when reading new values for cvs-*-flags
-
- * Makefile:
- - fix the info install rules...
-
- * ToDo:
- - more things to look into...
-
-Sun Mar 12 20:40:05 1995 Greg A. Woods <woods@most.weird.com>
-
- * pcl-cvs.el:
- - minor twiggle to old RCS Id's to match format
-
- * Makefile:
- - fix up RCS Id's
- - add clobber to "clean" targets
- - separate installation of *.el's and default off
- - fix INSTALL_DATA
-
- * pcl-cvs.el:
- - minor twiggles to automatically localise and to note this is a local version
-
- * ToDo:
- - first cut
-
- * .cvsignore:
- - first time in -- default generated targets
-
-Tue Nov 22 20:49:39 1994 Greg A. Woods <woods@most.weird.com>
-
- * pcl-cvs.el:
- - adjust RCS keywords
- - reset shell to just /bin/sh
-
-Fri Nov 4 21:14:55 1994 Greg A. Woods <woods@most.weird.com>
-
- * pcl-cvs.el:
- - fix directory for new CVS-1.4
- - add '-v' to cvs-status-flags
-
-Mon Dec 6 19:06:18 1993 Greg A. Woods <woods@most.weird.com>
-
- * pcl-cvs.el:
- - I don't quite know how that happened, but we had a variable and
- function with the same name, and an un-defined variable....
-
- * pcl-cvs.el:
- - re-format a few things....
- - replace numerous duplicate lambda expressions with a new common
- function: cvs-quote-multiword-string
-
-Fri Nov 26 20:54:25 1993 Greg A. Woods <woods@most.weird.com>
-
- * pcl-cvs.el:
- - oops! was changing the directory string we were comparing against!
-
- * pcl-cvs.el:
- - oops -- missing an end-sexp....
-
- * pcl-cvs.el:
- - in theory this fixes up all the local directory vs.
- default-directory problems
-
- * pcl-cvs.el:
- - ensure multi-word args are quoted in messages
- - enhance naming of diff buffers
-
-Fri Nov 12 18:43:09 1993 Greg A. Woods <woods@most.weird.com>
-
- * pcl-cvs.el:
- - update comment about "Conflict"...
- - fiddle with rcs-ident stuff
-
-Thu Nov 4 01:15:53 1993 Greg A. Woods <woods@most.weird.com>
-
- * pcl-cvs.el:
- - set default cvs-status-flags to '("-Q)
- - use cvs-bakprefix where intended
- - add functions and keymaps for setting cvs-*-flags.
- - re-pretty-print some stuff
-
-Wed Nov 3 23:11:15 1993 Greg A. Woods <woods@most.weird.com>
-
- * pcl-cvs.el:
- - use cvs-kill-buffer-visiting in cvs-mode-diff-vendor for cleanup.
- - fix last minibuffer message in cvs-mode-diff-vendor.
-
- * pcl-cvs.el:
- - OOPS! put (list ...) back where we need evaluation.
- - default to use of CVS/Root always for cvs-update, if it exits.
-
- * pcl-cvs.el:
- - oops -- minor bug with usage of mapconcat
- - changed (list ...) to '(...)
-
- * pcl-cvs.texinfo:
- - minor updates of filenames and versions.
- - added myself as a contributor
-
- * pcl-cvs.el:
- - re-justified multitueds of comments, and fixed minor bits too.
- - added support for CVS/Root file to supplement use of $CVSROOT and/or
- cvs-cvsroot.
- - added cvs-mode-map binding for cvs-change-cvsroot
- - added optional message-fmt argument to cvs-execute-list (prints
- message showing progress in minibuffer).
- - modified cvs-mode-diff-cvs to put results in
- cvs-fileinfo->cvs-diff-buffer.
- - modified cvs-mode-diff-backup to put results in
- cvs-fileinfo->backup-diff-buffer.
- - modified cvs-mode-diff-vendor to put results in
- cvs-fileinfo->vendor-diff-buffer.
- - modified cvs-mode-diff-* to use cvs-diff-flags.
- - added cvs-*-diffable.
- - fixed various minibuffer progress messages.
-
-Thu Oct 28 23:10:38 1993 Greg A. Woods <woods@most.weird.com>
-
- * pcl-cvs.el:
- - many minor improvements,
- - several bug fixes,
- - added some support for vendor branch merging,
-
-Tue Oct 26 18:26:33 1993 Greg A. Woods <woods@most.weird.com>
-
- * Makefile:
- - fixes, localisations, etc.
-
-Fri Oct 22 21:19:15 1993 Greg A. Woods <woods@most.weird.com>
-
- * pcl-cvs.el, Makefile:
- - localisations....
-
- * pcl-cvs.el:
- pick the 1.05 version over local edits....
-
-Thu Oct 21 21:40:26 1993 Greg A. Woods <woods@most.weird.com>
-
- * texinfo.tex, pcl-cvs.texinfo, pcl-cvs.el, pcl-cvs-startup.el, pcl-cvs-lucid.el, compile-all.el, README, NEWS, Makefile, INSTALL, ChangeLog:
- pcl-cvs version 1.05 distribution
-
-Tue Jun 1 16:25:35 1993 Greg A. Woods <woods@most.weird.com>
-
- * pcl-cvs.el:
- add a newline to the cvs-mode-add description
-
-Fri May 28 14:13:41 1993 Greg A. Woods <woods@most.weird.com>
-
- * pcl-cvs.el:
- add cvs-commit-buffer-require-final-newline to allow forcing a newline
- onto the commit buffer
-
-Fri May 14 22:35:01 1993 Greg A. Woods <woods@most.weird.com>
-
- * pcl-cvs.el:
- localizations....
-
- * ChangeLog, INSTALL, Makefile, NEWS, README, compile-all.el, pcl-cvs.el, pcl-cvs-lucid.el, pcl-cvs-startup.el, pcl-cvs.texinfo, texinfo.tex:
- pcl-cvs version 1.04 distribution
-
- * ChangeLog, INSTALL, Makefile, NEWS, README, compile-all.el, pcl-cvs.el, pcl-cvs-lucid.el, pcl-cvs-startup.el, pcl-cvs.texinfo, texinfo.tex:
- Initial revision
-
diff --git a/contrib/cvs/tools/pcl-cvs/INSTALL b/contrib/cvs/tools/pcl-cvs/INSTALL
deleted file mode 100644
index c4cf8dc45936..000000000000
--- a/contrib/cvs/tools/pcl-cvs/INSTALL
+++ /dev/null
@@ -1,94 +0,0 @@
-This text is copied from the TeXinfo manual for pcl-cvs.
-
-Installation of the pcl-cvs program
-===================================
-
- 1. Possibly edit the file `Makefile' to reflect the situation at your
- site. We say "possibly" because the version of pcl-cvs included
- with CVS uses a configuration mechanism integrated with the overall
- mechanisms used by the CVS build and install procedures. Thus the
- file `Makefile' will be generated automatically from the file
- `Makefile.in', and it should not be necessary to edit it further.
-
- If you do have to edit the `Makefile', the only things you have to
- change is the definition of `lispdir' and `infodir'. The elisp
- files will be copied to `lispdir', and the info file(s) to
- `infodir'.
-
- 2. Configure pcl-cvs.el
-
- There are a couple of pathnames that you have to check to make
- sure that they match your system. They appear early in the file
- `pcl-cvs.el'.
-
- *NOTE:* If your system is running emacs 18.57 or earlier you MUST
- uncomment the line that says:
- (setq delete-exited-processes nil)
-
- Setting `delete-exited-processes' to `nil' works around a bug in
- emacs that causes it to dump core. The bug was fixed in emacs
- 18.58.
-
- 3. Release 1.05 and later of pcl-cvs requires parts of the Elib
- library, version 1.0 or later. Elib is available via anonymous
- ftp from prep.ai.mit.edu in `pub/gnu/elib-1.0.tar.gz', and from a
- lot of other sites that mirror prep. Get Elib, and install it,
- before proceeding.
-
- *NOTE:* The version of pcl-cvs included with CVS includes a copy
- of Elib in the sub-directory `elib' under the `contrib/elib'
- directory.
-
- 4. Type `make install' in the source directory. This will
- byte-compile all `.el' files and copy the `*.elc' files into the
- directory you specified in step 1.
-
- If you want to install the `*.el' files too, you can type `make
- install-el' to do so.
-
- If you only want to create the compiled elisp files, but don't
- want to install them, you can type `make' without parameters.
-
- 5. Edit the file `default.el' in your emacs lisp directory (usually
- `/usr/gnu/lib/emacs/site-lisp' or something similar) and enter the
- contents of the file `pcl-cvs-startup.el' into it. It contains a
- couple of `auto-load's that facilitates the use of pcl-cvs.
-
-
-Installation of the on-line manual.
-===================================
-
- 1. Create the info file(s) `pcl-cvs.info*' from `pcl-cvs.texinfo' by
- typing `make info'. If you don't have the program `makeinfo' you
- can get it by anonymous ftp from e.g. `prep.ai.mit.edu' as
- `pub/gnu/texinfo-3.7.tar.gz' (there might be a newer version there
- when you read this).
-
- 2. Install the info file(s) `pcl-cvs.info*' into your standard `info'
- directory. You should be able to do this by typing `make
- install-info'.
-
- 3. Edit the file `dir' in the `info' directory and enter one line to
- contain a pointer to the info file(s) `pcl-cvs.info*'. The line
- can, for instance, look like this:
-
- * Pcl-cvs: (pcl-cvs). An Emacs front-end to CVS.
-
-How to make typeset documentation from pcl-cvs.texinfo
-======================================================
-
- If you have TeX installed at your site, you can make a typeset manual
-from `pcl-cvs.texinfo'.
-
- 1. Run TeX by typing ``make pcl-cvs.dvi''. You will not get the
- indices unless you have the `texindex' program.
-
- 2. Convert the resulting device independent file `pcl-cvs.dvi' to a
- form which your printer can output and print it. If you have a
- postscript printer there is a program, `dvi2ps', which does. There
- is also a program which comes together with TeX, `dvips', which
- you can use.
-
-
---
-#ident "@(#)cvs/contrib/pcl-cvs:$Name: $Id: INSTALL,v 1.2 1996/04/15 06:33:16 kfogel Exp $"
diff --git a/contrib/cvs/tools/pcl-cvs/Makefile.in b/contrib/cvs/tools/pcl-cvs/Makefile.in
deleted file mode 100644
index 23e47eec1c1e..000000000000
--- a/contrib/cvs/tools/pcl-cvs/Makefile.in
+++ /dev/null
@@ -1,238 +0,0 @@
-# Makefile for pcl-cvs, an Emacs interface to CVS.
-# NOTE: pcl-cvs requires Elib to run. See ../../contrib/elib/.
-
-#
-#ident "@(#)original: dist-makefile,v 1.19 1993/05/31 22:43:45 ceder Exp "
-#
-#ident "@(#)elisp/pcl-cvs:$Name: $:$Id: Makefile.in,v 1.6 1997/02/17 20:44:30 kingdon Exp $"
-#
-# Makefile for pcl-cvs release 1.05-CVS-$Name: $.
-# Copyright (C) 1992, 1993 Per Cederqvist
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-SHELL = /bin/sh
-
-#### Start of system configuration section. ####
-
-srcdir = @srcdir@
-top_srcdir = @top_srcdir@
-VPATH = @srcdir@
-
-prefix = @prefix@
-exec_prefix = @exec_prefix@
-
-# Where to put the system-wide supplementary files
-sharedir = $(prefix)/share
-
-# Where to put the Info files
-infodir = $(prefix)/info
-
-# Where to put the manual pages.
-mandir = $(prefix)/man
-
-# Used to batch-byte-compile files.
-EMACS = emacs
-# compile with noninteractive environment
-BATCHFLAGS = -batch
-
-# This is the directory in which the ELCFILES will be installed.
-lispdir = $(sharedir)/emacs/site-lisp
-
-#### End of system configuration section. ####
-
-srcdir = @srcdir@
-top_srcdir = @top_srcdir@
-VPATH = @srcdir@
-
-# Just in case...
-SHELL = /bin/sh
-@SET_MAKE@
-
-DISTFILES = \
- .cvsignore ChangeLog INSTALL Makefile.in NEWS README \
- ${ELFILES} \
- pcl-cvs.texinfo texinfo.tex
-
-
-# OBJDIR_DISTFILES used to include the byte-compiled elisp files, but
-# this seems wrong because the person building the dist cannot have
-# made the appropriate site-specific modifications to pcl-cvs.el.
-# Therefore, I've taken the .elc files out of OBJDIR_DISTFILES for
-# now, pending the Right Solution to this problem (which probably
-# involves moving the site-specific modification section of pcl-cvs.el
-# to a separate file and having autoconf generate as much of the file
-# as possible). -Karl
-#
-# OBJDIR_DISTFILES = $(ELCFILES) pcl-cvs.aux pcl-cvs.ps
-OBJDIR_DISTFILES = pcl-cvs.aux pcl-cvs.ps
-
-
-# files that contain key macro definitions. almost everything
-# depends on them because the byte-compiler inlines macro
-# expansions. everything also depends on the byte compiler
-# options file since this might do odd things like turn off
-# certain compiler optimizations.
-CORE =
-
-ELFILES = pcl-cvs.el pcl-cvs-lucid.el pcl-cvs-startup.el
-ELCFILES = pcl-cvs.elc pcl-cvs-lucid.elc
-INFOFILES = pcl-cvs.info*
-TEXTMPS = pcl-cvs.aux pcl-cvs.log pcl-cvs.toc pcl-cvs.dvi pcl-cvs.cp \
- pcl-cvs.fn pcl-cvs.vr pcl-cvs.tp pcl-cvs.ky pcl-cvs.pg \
- pcl-cvs.cps pcl-cvs.fns pcl-cvs.kys pcl-cvs.pgs pcl-cvs.tps \
- pcl-cvs.vrs
-
-# Use cp if you don't have install.
-INSTALL = @INSTALL@
-INSTALL_DATA = @INSTALL_DATA@
-
-MAKEINFO = makeinfo
-
-SET_TEXINPUTS = TEXINPUTS=.:$(srcdir):$$TEXINPUTS
-
-# Don Knuth's TeX formatter
-TEX = tex
-
-# auxiliary program for sorting Texinfo indices
-TEXINDEX = texindex
-
-DVIPS = dvips
-DVIPSFLAGS =
-
-# CYGNUS LOCAL: install does not depend on info
-all: $(ELCFILES) # info
-.PHONY: all
-
-.SUFFIXES: .el .elc
-# We copy the .el file to the build dir--is there a cleaner way to get
-# emacs to compile the .el file from srcdir and put the .elc in the build dir?
-# (that is also why we have separate rules for pcl-cvs.elc and
-# pcl-cvs-lucid.elc rather than just using a .el.elc rule).
-pcl-cvs.elc: pcl-cvs.el
- @echo "You can probably ignore free variable and unknown function warnings..."
- if test -f pcl-cvs.el; then \
- : OK, we are building in srcdir ; \
- else \
- ln $(srcdir)/pcl-cvs.el . ; \
- fi
- $(EMACS) $(BATCHFLAGS) -f batch-byte-compile pcl-cvs.el
-pcl-cvs-lucid.elc: pcl-cvs-lucid.el
- @echo "You can probably ignore free variable and unknown function warnings..."
- if test -f pcl-cvs-lucid.el; then \
- : OK, we are building in srcdir ; \
- else \
- ln $(srcdir)/pcl-cvs-lucid.el . ; \
- fi
- $(EMACS) $(BATCHFLAGS) -f batch-byte-compile pcl-cvs-lucid.el
-
-check installcheck:
- @echo "$@ not supported in this makefile..."
-.PHONY: check installcheck
-
-# CYGNUS LOCAL: install does not depend on install-info
-install: install-elc # install-info install-el
-
-install-el: $(ELFILES)
- for i in $(ELFILES) ; do \
- $(INSTALL_DATA) $$i $(lispdir)/$$i ; \
- done
-
-install-elc: $(ELCFILES)
- for i in $(ELCFILES) ; do \
- $(INSTALL_DATA) $$i $(lispdir)/$$i ; \
- done
-
-install-info: info
- test -f pcl-cvs.info || cd $(srcdir); \
- for i in *.info* ; do \
- $(INSTALL_DATA) $$i $(infodir)/$$i ; \
- done
-
-.PHONY: install install-el install-elc install-info
-
-# mkinstalldirs isn't supported for CVS yet....
-installdirs: $(top_srcdir)/mkinstalldirs
- $(SHELL) $(top_srcdir)/mkinstalldirs $(lispdir) $(infodir)
-.PHONY: installdirs
-
-uninstall:
- @echo "$@ not yet supported in this makefile..."
-.PHONY: uninstall
-
-info: pcl-cvs.info
-.PHONY: info
-
-pcl-cvs.info: pcl-cvs.texinfo
- $(MAKEINFO) ${srcdir}/pcl-cvs.texinfo -o pcl-cvs.info
-
-dvi: pcl-cvs.dvi
-.PHONY: dvi
-
-# this mess seems to be necessary to make the index right...
-pcl-cvs.dvi pcl-cvs.aux: pcl-cvs.texinfo
- $(SET_TEXINPUTS) $(TEX) $(srcdir)/pcl-cvs.texinfo
- $(SET_TEXINPUTS) $(TEX) $(srcdir)/pcl-cvs.texinfo
- -$(TEXINDEX) pcl-cvs.cp pcl-cvs.fn pcl-cvs.vr pcl-cvs.tp pcl-cvs.ky \
- pcl-cvs.pg
- $(SET_TEXINPUTS) $(TEX) $(srcdir)/pcl-cvs.texinfo
-
-pcl-cvs.ps: pcl-cvs.dvi
- $(DVIPS) $(DVIPSFLAGS) pcl-cvs.dvi -o pcl-cvs.ps
-
-mostlyclean clean:
- rm -f *~ core $(ELCFILES) $(INFOFILES) $(TEXTMPS)
-.PHONY: mostlyclean clean
-
-distclean: clean
- rm -f Makefile tags TAGS
-.PHONY: distclean
-
-realclean maintainer-clean: distclean
- rm -f pcl-cvs.info* pcl-cvs.ps
-.PHONY: realclean maintainer-clean
-
-# you can't use ctags for lisp...
-tags TAGS:
- etags *.el
-.PHONY: tags
-
-ls:
- @echo $(DISTFILES)
-.PHONY: ls
-
-dist-dir: ${OBJDIR_DISTFILES} ${DISTFILES} pcl-cvs.info
- mkdir ${DISTDIR}
- for i in ${DISTFILES}; do \
- ln $(srcdir)/$${i} ${DISTDIR}; \
- done
- ln ${OBJDIR_DISTFILES} ${DISTDIR}
- if [ -f pcl-cvs.info-1 ]; \
- then ln -f pcl-cvs.info-* ${DISTDIR}; \
- else : Pacify Ultrix sh; \
- fi
-.PHONY: dist-dir
-
-subdir = tools/pcl-cvs
-Makefile: ../../config.status Makefile.in
- cd ../.. && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= ./config.status
-
-# CYGNUS LOCAL: don't depend on auto-re-config
-#../config.status: ../configure
-# cd .. ; $(SHELL) config.status --recheck
-
-# CYGNUS LOCAL: don't depend on auto-re-config
-#../configure: ../configure.in
-# cd $(top_srcdir) ; autoconf
diff --git a/contrib/cvs/tools/pcl-cvs/NEWS b/contrib/cvs/tools/pcl-cvs/NEWS
deleted file mode 100644
index 48b0b667c927..000000000000
--- a/contrib/cvs/tools/pcl-cvs/NEWS
+++ /dev/null
@@ -1,149 +0,0 @@
-This is the NEWS file for pcl-cvs, an Emacs elisp front-end to CVS.
-
-User-visible changes in the un-official CVS release of pcl-cvs
-from the official 1.05 release to 1.05-CVS-$Name: $:
-
-* Support for using ChangeLog files, including hooks to automatically
- guess CVS log entries from ChangeLog contents.
-
-* Support for client/server CVS (versions 1.5 through 1.7 and newer).
-
-* New commands for tagging files and directory trees (still needs to
- be made to run in the background).
-
-* Better support for recognizing and handling unknown directories.
-
-* An attempt at new ediff and emerge interfaces (still needs work!),
- including attempts to make vendor-branch merging work.
-
-* In a possibly misguided attempt to make it easier to see the effects
- of changes that affect several files, diff output is now stored in a
- uniqe buffer for each file.
-
-* Some commands now have default flags (cvs-*-flags).
-
-* Proper quoting of command line arguments displayed in *cvs-tmp*.
-
-* More hacking with getting CVSROOT right, though probably all
- pointless, since CVS should do the right thing all the time.
-
-* Elib is back, at least in the CVS distribution.
-
-* Lots of minor bug fixes, tweaks, cleanup, re-indentation, etc.
-
-* Some minor tweaks, fixes, re-indentation, etc., in the
- documentation.
-
-
-User-visible changes in pcl-cvs from 1.04 to 1.05:
-
-* Elib is no longer distributed with pcl-cvs. You must get Elib
- separately, for instance from ftp.lysator.liu.se in pub/emacs.
-
-* The Lucid Emacs support works again.
-
-* A new function, cvs-change-cvsroot, can be used to interactively
- switch between CVS repositories.
-
-* The mode line in the *cvs* buffer now indicates when a "cvs update"
- is running.
-
-* The .cvsignore file is automatically sorted alphabetically (to
- reduce the risk of conflicts when two people add different files
- simultaneously). This behaviour can be turned off with
- cvs-sort-ignore-file.
-
-* A trailing newline is always added in commit log messages. This
- behaviour can be turned off with
- cvs-commit-buffer-require-final-newline.
-
-* This version of pcl-cvs should work together with RCVS. I have not
- tested this myself, though.
-
-* Plus some bug fixes. (Note that the version of cookie.el that is
- distributed with pcl-cvs 1.04 contains errors that affects pcl-cvs.
- You should get Elib 0.07).
-
-
-User-visible changes in pcl-cvs from 1.03 to 1.04:
-
-* Support for Emerge. Hitting "e" on a file that is Modified, Merged
- or in Conflict will start Emerge, an interactive file merger written
- in Emacs Lisp. This requires Emerge version 4. Emerge is not
- included in this package. If you can't find it anywhere else, you
- can get in from ftp.lysator.liu.se in pub/emacs. This package makes
- it a lot easier to resolve conflicts.
-
-* Emacs will now automatically revert your buffers when the CVS
- commands pcl-cvs issues causes the file to change. This automatic
- revert never occurs if the buffer contents did not agree with the
- file prior to the command.
-
-* If you are running Lucid GNU Emacs, you will get some fonts and
- mouse support. This was contributed from people at Lucid.
-
-* The variable cvs-cvsroot can be used to select the location if the
- repository. You no longer need to exit Emacs, setenv CVSROOT, and
- start a new Emacs if you work with multiple repositories.
-
-* The "q" key can be used to hide the *cvs* buffer.
-
-* The name of the commands in the *cvs* have changed. If it was called
- cvs-foo, it will now be called cvs-mode-foo. See the ChangeLog
- entry from Tue Aug 4 03:02:25 1992 for a complete list of changes.
-
-* The variable cvs-cvs-diff-flags is no longer used. Instead,
- cvs-diff-flags is always used.
-
-* Plus a lot of bug fixes.
-
-
-User-visible changes in pcl-cvs from 1.02 to 1.03:
-
-* Output from CVS to stdout and stderr is separated and parsed
- independently. In that way pcl-cvs should work regardless of
- whether stdout is buffered or line-buffered. Pcl-cvs should now
- work with CVS 1.3 without modifications on hosts such as
- DECstations.
-
-* Pcl-cvs now fully supports RCS version 5.6 as well as 5.5.
-
-* New functions:
-
- + cvs-undo-local-changes ("U") - Undo all your modifications
- to a file and get the newest
- version from the repository.
- + cvs-update-other-window - Similar to cvs-update.
- + cvs-byte-compile-files - Byte compile the selected files.
-
-* cvs-update now displays the *cvs* buffer, which initially contains a
- small message ("Running `cvs update' in /foo/bar/gazonk/...") until
- the update is ready. The *cvs* buffer no longer pops up when the
- update is ready. It often failed to pop up, due to race conditions
- that are very hard to solve (and I doubt that they were at all
- solvable).
-
-* cvs-unmark-all-files is moved from "U" to "ESC DEL" to be
- "compatible" with dired.
-
-* cvs-diff ("d") and cvs-diff-backup ("b") can be configured to work
- on only the file the cursor is positioned on, and ignore any marked
- files. A prefix argument toggles this.
-
-* Only one `cvs update' can be run at a time. (It was previously
- possible to start more than one simultaneously, but pcl-cvs could
- not really handle more than one.)
-
-* Some rudimentary support for programs that CVS runs at update (due
- to the -u switch in the modules file).
-
-* Pcl-cvs now automatically generates a bug report if it can't parse
- the output from CVS.
-
-* The *cvs* buffer is read-only.
-
-* Pcl-cvs now creates temporary files in $TMPDIR if that environment
- variable is set (otherwise it uses /tmp).
-
----End of file NEWS---
-#ident "@(#)cvs/contrib/pcl-cvs:$Name: $:$Id: NEWS,v 1.1 1996/04/14 15:17:54 kfogel Exp $"
diff --git a/contrib/cvs/tools/pcl-cvs/README b/contrib/cvs/tools/pcl-cvs/README
deleted file mode 100644
index 9574c146ab0b..000000000000
--- a/contrib/cvs/tools/pcl-cvs/README
+++ /dev/null
@@ -1,25 +0,0 @@
-This is the readme file for pcl-cvs, release 1.05-CVS-$Name: $.
-
-Pcl-cvs is a front-end to CVS versions 1.5 through 1.7. It integrates
-the most frequently used CVS commands into an emacs interface.
-
-There may be some configuration that needs to be done in pcl-cvs.el to
-get it to work. See the instructions in the file INSTALL.
-
-Full documentation is in Texinfo format in the file pcl-cvs.texinfo. To
-browse this document online, or in the emacs info mode, you will need to
-process this file with the makeinfo program, which can also be found on
-prep.ai.mit.edu in pub/gnu.
-
-If you have been using a previous version of pcl-cvs (for instance the
-official 1.05 release, or any previous releases) you should read through
-the file NEWS to see what has changed.
-
-This release has been tested under, Emacs 19.28 and Emacs 19.30.
-
-Per Cederqvist
-(updated by Jim Blandy, Greg A. Woods, Karl Fogel)
-
---
-#OrigId "@(#) Id: README,v 1.14 1993/05/31 22:43:36 ceder Exp "
-#ident "@(#)cvs/contrib/pcl-cvs:$Name: $:$Id: README,v 1.1 1996/04/14 15:17:55 kfogel Exp $"
diff --git a/contrib/cvs/tools/pcl-cvs/ToDo b/contrib/cvs/tools/pcl-cvs/ToDo
deleted file mode 100644
index 8e317f897cca..000000000000
--- a/contrib/cvs/tools/pcl-cvs/ToDo
+++ /dev/null
@@ -1,44 +0,0 @@
-- documentation.... (esp. ChangeLog support)
-
-- IMPORTANT: make cvs-mode-tag run in the background
-
-- fix 'cvs-mode-add' to "cvs update" in the added directory
-
-- write 'cvs-mode-import'
-
-- write 'cvs-mode-handle-new-vendor-version'
-
- - checks out module
- - does "cvs -n tag LAST_VENDOR" to find old files into *cvs*
-
-- add 'cvs-set-cvs-flags' for top level cvs command flags
-
-- add '\M-a' to do arbitrary 'cvs admin' commands
-
-- add 'cvs patch' support (with completion on tag names and hooks to
-help generate ChangeLog files with rcs2log, etc.)
-
-- add 'cvs export' support (with completion on tag names and hooks to
-help generate full releases)
-
-- add 'cvs-mode-version' to call 'cvs -v' [on ^C-cv ?] (really???)
-
-- re-write rcs2log in e-lisp.
-
-- add support for parsing 'modules' file ("cvs co -c")
-
-- enhance 'cvs-mode-rtag'
-
-- fix 'cvs-examine'
-
-- write 'cvs-mode-checkout' and 'cvs-mode-checkout-other-window'
-
-- write 'cvs-mode-release'
-
-- add an update mode that keeps all files
-
- - this will require all commands to work only on non-up-to-date
- files
-
---
-#ident "@(#)cvs/contrib/pcl-cvs:$Name: $Id: ToDo,v 1.1 1996/04/14 15:17:57 kfogel Exp $"
diff --git a/contrib/cvs/tools/pcl-cvs/pcl-cvs-lucid.el b/contrib/cvs/tools/pcl-cvs/pcl-cvs-lucid.el
deleted file mode 100644
index 8695f67aa117..000000000000
--- a/contrib/cvs/tools/pcl-cvs/pcl-cvs-lucid.el
+++ /dev/null
@@ -1,134 +0,0 @@
-;;; Mouse and font support for PCL-CVS 1.3 running in Lucid GNU Emacs
-;; @(#) Id: pcl-cvs-lucid.el,v 1.2 1993/05/31 19:37:34 ceder Exp
-;; Copyright (C) 1992-1993 Free Software Foundation, Inc.
-
-;; This file is part of GNU Emacs.
-
-;; GNU Emacs is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation; either version 2, or (at your option)
-;; any later version.
-
-;; GNU Emacs is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs; see the file COPYING. If not, write to
-;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
-
-;; This simply adds a menu of the common CVS commands to the menubar and to
-;; the right mouse button. Clicking right moves point, and then pops up a
-;; menu from which commands can be executed.
-;;
-;; This could stand to be a lot more clever: for example, the "Commit Changes"
-;; command should only be active on files for which there is something to
-;; commit. Also, some indication of which files the command applies to
-;; (especially in the presence of multiple marked files) would be nice.
-;;
-;; Middle-click runs find-file.
-
-
-;(require 'pcl-cvs)
-(load "pcl-cvs.el")
-
-(defvar cvs-menu
- '("CVS"
- ["Find File" cvs-mode-find-file t]
- ["Find File Other Window" cvs-mode-find-file-other-window t]
- ["Interactively Merge (emerge)" cvs-mode-emerge t]
- ["Diff against Repository" cvs-mode-diff-cvs t]
- ["Diff against Backup Version" cvs-mode-diff-backup t]
- "----"
- ["Commit Changes to Repository" cvs-mode-commit t]
- ["Revert File from Repository" cvs-mode-undo-local-changes t]
- ["Add File to Repository" cvs-mode-add t]
- ["Remove File from Repository" cvs-mode-remove-file t]
- ["Ignore File" cvs-mode-ignore t]
- ["Hide File" cvs-mode-acknowledge t]
- ["Hide Handled Files" cvs-mode-remove-handled t]
- "----"
- ["Add ChangeLog Entry" cvs-mode-add-change-log-entry-other-window t]
- ["Show CVS Log" cvs-mode-log t]
- ["Show CVS Status" cvs-mode-status t]
- "----"
- ["Mark File" cvs-mode-mark t]
- ["Unmark File" cvs-mode-unmark t]
- ["Mark All Files" cvs-mode-mark-all-files t]
- ["Unmark All Files" cvs-mode-unmark-all-files t]
- "----"
- ["Quit" bury-buffer t]
- ))
-
-(defun cvs-menu (e)
- (interactive "e")
- (mouse-set-point e)
- (beginning-of-line)
- (or (looking-at "^[* ] ") (error "No CVS file line here"))
- (popup-menu cvs-menu))
-
-(defun cvs-mouse-find-file (e)
- (interactive "e")
- (mouse-set-point e)
- (beginning-of-line)
- (or (looking-at "^[* ] ") (error "No CVS file line here"))
- (cvs-mode-find-file (point)))
-
-(define-key cvs-mode-map 'button3 'cvs-menu)
-(define-key cvs-mode-map 'button2 'cvs-mouse-find-file)
-
-(make-face 'cvs-header-face)
-(make-face 'cvs-filename-face)
-(make-face 'cvs-status-face)
-
-(or (face-differs-from-default-p 'cvs-header-face)
- (copy-face 'italic 'cvs-header-face))
-
-(or (face-differs-from-default-p 'cvs-filename-face)
- (copy-face 'bold 'cvs-filename-face))
-
-(or (face-differs-from-default-p 'cvs-status-face)
- (copy-face 'bold-italic 'cvs-status-face))
-
-
-(defun pcl-mode-motion-highlight-line (event)
- (if (save-excursion
- (let* ((window (event-window event))
- (buffer (and window (window-buffer window)))
- (point (and buffer (event-point event))))
- (and point
- (progn
- (set-buffer buffer)
- (goto-char point)
- (beginning-of-line)
- (looking-at "^[* ] ")))))
- (mode-motion-highlight-line event)))
-
-(defconst pcl-cvs-font-lock-keywords
- '(("^In directory \\(.+\\)$" 1 cvs-header-face)
- ("^[* ] \\w+ +\\(ci\\)" 1 cvs-status-face)
- ("^[* ] \\(Conflict\\|Merged\\)" 1 cvs-status-face)
- ("^[* ] \\w+ +\\(ci +\\)?\\(.+\\)$" 2 cvs-filename-face)
- )
- "Patterns to highlight in the *cvs* buffer.")
-
-(defun pcl-cvs-fontify ()
- ;;
- ;; set up line highlighting
- (require 'mode-motion)
- (setq mode-motion-hook 'pcl-mode-motion-highlight-line)
- ;;
- ;; set up menubar
- (if (and current-menubar (not (assoc "CVS" current-menubar)))
- (progn
- (set-buffer-menubar (copy-sequence current-menubar))
- (add-menu nil "CVS" (cdr cvs-menu))))
- ;;
- ;; fontify mousable lines
- (set (make-local-variable 'font-lock-keywords) pcl-cvs-font-lock-keywords)
- (font-lock-mode 1)
- )
-
-(add-hook 'cvs-mode-hook 'pcl-cvs-fontify)
diff --git a/contrib/cvs/tools/pcl-cvs/pcl-cvs-startup.el b/contrib/cvs/tools/pcl-cvs/pcl-cvs-startup.el
deleted file mode 100644
index 9db7a5fdc8f7..000000000000
--- a/contrib/cvs/tools/pcl-cvs/pcl-cvs-startup.el
+++ /dev/null
@@ -1,17 +0,0 @@
-;;;#ident "@(#)OrigId: pcl-cvs-startup.el,v 1.4 1993/05/31 18:40:33 ceder Exp "
-;;;
-;;;#ident "@(#)cvs/contrib/pcl-cvs:$Name: $:$Id: pcl-cvs-startup.el,v 1.1 1996/04/14 15:17:59 kfogel Exp $"
-;;;
-(autoload 'cvs-update "pcl-cvs"
- "Run a 'cvs update' in the current working directory. Feed the
-output to a *cvs* buffer and run cvs-mode on it.
-If optional prefix argument LOCAL is non-nil, 'cvs update -l' is run."
- t)
-
-(autoload 'cvs-update-other-window "pcl-cvs"
- "Run a 'cvs update' in the current working directory. Feed the
-output to a *cvs* buffer, display it in the other window, and run
-cvs-mode on it.
-
-If optional prefix argument LOCAL is non-nil, 'cvs update -l' is run."
- t)
diff --git a/contrib/cvs/tools/pcl-cvs/pcl-cvs.el b/contrib/cvs/tools/pcl-cvs/pcl-cvs.el
deleted file mode 100644
index 1dd7caebfbef..000000000000
--- a/contrib/cvs/tools/pcl-cvs/pcl-cvs.el
+++ /dev/null
@@ -1,3461 +0,0 @@
-;;;
-;;;#ident "@(#)OrigId: pcl-cvs.el,v 1.93 1993/05/31 22:44:00 ceder Exp "
-;;;
-;;;#ident "@(#)cvs/contrib/pcl-cvs:$Name: $:$Id: pcl-cvs.el,v 1.7 1998/01/04 14:24:13 kingdon Exp $"
-;;;
-;;; pcl-cvs.el -- A Front-end to CVS 1.3 or later.
-;;; Release 1.05-CVS-$Name: $.
-;;; Copyright (C) 1991, 1992, 1993 Per Cederqvist
-
-;;; This program is free software; you can redistribute it and/or modify
-;;; it under the terms of the GNU General Public License as published by
-;;; the Free Software Foundation; either version 2 of the License, or
-;;; (at your option) any later version.
-;;;
-;;; This program is distributed in the hope that it will be useful,
-;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;;; GNU General Public License for more details.
-;;;
-;;; You should have received a copy of the GNU General Public License
-;;; along with this program; if not, write to the Free Software
-;;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-;;; See below for installation instructions.
-
-;;; This package requires ELIB-1.0 to run. Elib is included in the
-;;; CVS distribution in the contrib/elib/ subdirectory, but you can
-;;; also download it at the following URL:
-;;;
-;;; ftp://ftp.lysator.liu.se/pub/emacs/elib-1.0.tar.gz
-;;;
-
-;;; There is an TeXinfo file that describes this package. You should read it
-;;; to get the most from this package.
-
-;;; Mail questions and bug reports regarding this version (as included in
-;;; CVS-1.7 or newer) to the pcl-cvs support team at <pcl-cvs@cyclic.com>.
-
-;;; Don't try to use this with CVS 1.2 or earlier. It won't work. Get CVS 1.7
-;;; or newer. Use the version of RCS best suited for the version of CVS you're
-;;; using.
-
-(require 'cookie) ; from ELIB-1.0
-(require 'add-log) ; for all the ChangeLog goodies
-
-;;; -------------------------------------------------------
-;;; START OF THINGS TO CHECK WHEN INSTALLING
-
-;; also use $GNU here, since may folks might install CVS as a GNU package
-;;
-(defun cvs-find-program (program)
- (let ((path (list (getenv "LOCAL")
- (getenv "GNU")
- "/usr/local/bin"
- "/usr/bin"
- "/bin")))
- (while path
- (if (stringp (car path))
- (let ((abs-program (expand-file-name program (car path))))
- (if (file-executable-p abs-program)
- (setq path nil
- program abs-program))))
- (setq path (cdr path)))
- program))
-
-(defvar cvs-program (cvs-find-program "cvs")
- "*Full path to the cvs executable.")
-
-;; SunOS-4.1.1_U1 has "diff.c 1.12 88/08/04 SMI; from UCB 4.6 86/04/03"
-;;
-(defvar cvs-diff-program (cvs-find-program "diff")
- "*Full path to the best diff program you've got.
-NOTE: there are some nasty bugs in the context diff variants of some vendor
-versions, such as the one in SunOS-4.1.1_U1")
-
-(defvar cvs-rmdir-program "/bin/rmdir"
- "*Full path to the rmdir program. Typically /bin/rmdir.")
-
-(defvar cvs-shell "/bin/sh"
- "*Full path to a shell that can do redirection on stdout.")
-
-;;; Options to control various features:
-
-(defvar cvs-changelog-full-paragraphs t
- "If non-nil, include full ChangeLog paragraphs in the CVS log.
-This may be set in the ``local variables'' section of a ChangeLog, to
-indicate the policy for that ChangeLog.
-
-A ChangeLog paragraph is a bunch of log text containing no blank lines;
-a paragraph usually describes a set of changes with a single purpose,
-but perhaps spanning several functions in several files. Changes in
-different paragraphs are unrelated.
-
-You could argue that the CVS log entry for a file should contain the
-full ChangeLog paragraph mentioning the change to the file, even though
-it may mention other files, because that gives you the full context you
-need to understand the change. This is the behaviour you get when this
-variable is set to t.
-
-On the other hand, you could argue that the CVS log entry for a change
-should contain only the text for the changes which occurred in that
-file, because the CVS log is per-file. This is the behaviour you get
-when this variable is set to nil.")
-
-(defvar cvs-cvsroot-required nil
- "*Specifies whether CVS needs to be told where the repository is.
-
-In CVS 1.3, if your CVSROOT environment variable is not set, and you
-do not set the `cvs-cvsroot' lisp variable, CVS will have no idea
-where to find the repository, and refuse to run. CVS 1.4 and later
-store the repository path with the working directories, so most
-operations don't need to be told where the repository is.
-
-If you work with multiple repositories with CVS 1.4, it's probably
-advisable to leave your CVSROOT environment variable unset, set this
-variable to nil, and let CVS figure out where the repository is for
-itself.")
-
-(defvar cvs-cvsroot nil
- "*Specifies where the (current) cvs master repository is.
-Overrides the $CVSROOT variable by sending \" -d dir\" to all cvs commands.
-This switch is useful if you have multiple CVS repositories, and are not using
-a modern version of CVS that stores the current repository in CVS/Root.")
-
-;; Uncomment the following line if you are running on 18.57 or earlier.
-;(setq delete-exited-processes nil)
-;; Emacs version 18.57 and earlier is likely to crash if
-;; delete-exited-processes is t, since the sentinel uses lots of
-;; memory, and 18.57 forgets to GCPROT a variable if
-;; delete-exited-processes is t.
-
-;;; END OF THINGS TO CHECK WHEN INSTALLING
-;;; --------------------------------------------------------
-
-(defconst pcl-cvs-version "1.05-CVS-$Name: $"
- "A string denoting the current release version of pcl-cvs.")
-
-;; You are NOT allowed to disable this message by default. However, you
-;; are encouraged to inform your users that by adding
-;; (setq cvs-inhibit-copyright-message t)
-;; to their .emacs they can get rid of it. Just don't add that line
-;; to your default.el!
-(defvar cvs-inhibit-copyright-message nil
- "*Non-nil means don't display a Copyright message in the ``*cvs*'' buffer.")
-
-(defconst cvs-startup-message
- (if cvs-inhibit-copyright-message
- "PCL-CVS release 1.05-CVS-$Name: $"
- "PCL-CVS release 1.05 from CVS release $Name: $.
-Copyright (C) 1992, 1993 Per Cederqvist
-Pcl-cvs comes with absolutely no warranty; for details consult the manual.
-This is free software, and you are welcome to redistribute it under certain
-conditions; again, consult the TeXinfo manual for details.")
- "*Startup message for CVS.")
-
-(defconst pcl-cvs-bugs-address "pcl-cvs-auto-bugs@cyclic.com"
- "The destination address used for the default bug report form.")
-
-(defvar cvs-stdout-file nil
- "Name of the file that holds the output that CVS sends to stdout.
-This variable is buffer local.")
-
-(defvar cvs-lock-file nil
- "Full path to a lock file that CVS is waiting for (or was waiting for).")
-
-(defvar cvs-bakprefix ".#"
- "The prefix that CVS prepends to files when rcsmerge'ing.")
-
-(defvar cvs-erase-input-buffer nil
- "*Non-nil if input buffers should be cleared before asking for new info.")
-
-(defvar cvs-auto-remove-handled nil
- "*Non-nil if cvs-mode-remove-handled should be called automatically.
-If this is set to any non-nil value, entries that do not need to be checked in
-will be removed from the *cvs* buffer after every cvs-mode-commit command.")
-
-(defvar cvs-auto-remove-handled-directories nil
- "*Non-nil if cvs-mode-remove-handled and cvs-update should automatically
-remove empty directories.
-If this is set to any non-nil value, directories that do not contain any files
-to be checked in will be removed from the *cvs* buffer.")
-
-(defvar cvs-sort-ignore-file t
- "*Non-nil if cvs-mode-ignore should sort the .cvsignore automatically.")
-
-(defvar cvs-auto-revert-after-commit t
- "*Non-nil if committed buffers should be automatically reverted.")
-
-(defconst cvs-cursor-column 14
- "Column to position cursor in in cvs-mode.
-Column 0 is left-most column.")
-
-(defvar cvs-mode-map nil
- "Keymap for the cvs mode.")
-
-(defvar cvs-edit-mode-map nil
- "Keymap for the cvs edit mode (used when editing cvs log messages).")
-
-(defvar cvs-buffer-name "*cvs*"
- "Name of the cvs buffer.")
-
-(defvar cvs-commit-prompt-buffer "*cvs-commit-message*"
- "Name of buffer in which the user is prompted for a log message when
-committing files.")
-
-(defvar cvs-commit-buffer-require-final-newline t
- "*t says silently put a newline at the end of commit log messages.
-Non-nil but not t says ask user whether to add a newline in each such case.
-nil means don't add newlines.")
-
-(defvar cvs-temp-buffer-name "*cvs-tmp*"
- "*Name of the cvs temporary buffer.
-Output from cvs is placed here by synchronous commands.")
-
-(defvar cvs-diff-ignore-marks nil
- "*Non-nil if cvs-diff and cvs-mode-diff-backup should ignore any marked files.
-Normally they run diff on the files that are marked (with cvs-mode-mark),
-or the file under the cursor if no files are marked. If this variable
-is set to a non-nil value they will always run diff on the file on the
-current line.")
-
-;;; (setq cvs-status-flags '("-v"))
-(defvar cvs-status-flags '("-v")
- "*List of flags to pass to ``cvs status''. Default is \"-v\".")
-
-;;; (setq cvs-log-flags nil)
-(defvar cvs-log-flags nil
- "*List of flags to pass to ``cvs log''. Default is none.")
-
-;;; (setq cvs-tag-flags nil)
-(defvar cvs-tag-flags nil
- "*List of extra flags to pass to ``cvs tag''. Default is none.")
-
-;;; (setq cvs-rtag-flags nil)
-(defvar cvs-rtag-flags nil
- "*List of extra flags to pass to ``cvs rtag''. Default is none.")
-
-;;; (setq cvs-diff-flags '("-u"))
-(defvar cvs-diff-flags '("-u")
- "*List of flags to use as flags to pass to ``diff'' and ``cvs diff''.
-Used by cvs-mode-diff-cvs and cvs-mode-diff-backup. Default is \"-u\".
-
-Set this to \"-u\" to get a Unidiff format, or \"-c\" to get context diffs.")
-
-;;; (setq cvs-update-optional-flags nil)
-(defvar cvs-update-optional-flags nil
- "*List of strings to use as optional flags to pass to ``cvs update''. Used
-by cvs-do-update, called by cvs-update, cvs-update-other-window,
-cvs-mode-update-no-prompt, and cvs-examine. Default is none.
-
-For example set this to \"-j VENDOR_PREV_RELEASE -j VENDOR_TOP_RELEASE\" to
-perform an update after a new vendor release has been imported.
-
-To restrict the update to the current working directory, set this to \"-l\".")
-
-(defvar cvs-update-prog-output-skip-regexp "$"
- "*A regexp that matches the end of the output from all cvs update programs.
-That is, output from any programs that are run by CVS (by the flag -u in the
-`modules' file - see cvs(5)) when `cvs update' is performed should terminate
-with a line that this regexp matches. It is enough that some part of the line
-is matched.
-
-The default (a single $) fits programs without output.")
-
-;;; --------------------------------------------------------
-;;; The variables below are used internally by pcl-cvs. You should
-;;; never change them.
-
-(defvar cvs-buffers-to-delete nil
- "List of temporary buffers that should be discarded as soon as possible.
-Due to a bug in emacs 18.57 the sentinel can't discard them reliably.")
-
-(defvar cvs-update-running nil
- "This is set to nil when no process is running, and to
-the process when a cvs update process is running.")
-
-(defvar cvs-cookie-handle nil
- "Handle for the cookie structure that is displayed in the *cvs* buffer.")
-
-(defvar cvs-commit-list nil
- "Used internally by pcl-cvs.")
-
-;;; The cvs data structure:
-;;;
-;;; When the `cvs update' is ready we parse the output. Every file
-;;; that is affected in some way is added as a cookie of fileinfo
-;;; (as defined below).
-;;;
-
-;;; cvs-fileinfo
-
-;;; Constructor:
-
-(defun cvs-create-fileinfo (type
- dir
- file-name
- full-log)
- "Create a fileinfo from all parameters.
-Arguments: TYPE DIR FILE-NAME FULL-LOG.
-A fileinfo is a vector with the following fields:
-
-[0] handled True if this file doesn't require further action.
-[1] marked t/nil
-[2] type One of
- UPDATED - file copied from repository
- PATCHED - file update with patch from repository
- MODIFIED - modified by you, unchanged in
- repository
- ADDED - added by you, not yet committed
- REMOVED - removed by you, not yet committed
- CVS-REMOVED- removed, since file no longer exists
- in the repository.
- MERGED - successful merge
- CONFLICT - conflict when merging (if pcl-cvs did it)
- REM-CONFLICT-removed in repository, but altered
- locally.
- MOD-CONFLICT-removed locally, changed in repository.
- REM-EXIST - removed locally, but still exists.
- DIRCHANGE - A change of directory.
- UNKNOWN - An unknown file.
- UNKNOWN-DIR- An unknown directory.
- MOVE-AWAY - A file that is in the way.
- REPOS-MISSING- The directory has vanished from the
- repository.
- MESSAGE - This is a special fileinfo that is used
- to display a text that should be in
- full-log.
-[3] dir Directory the file resides in. Should not end with slash.
-[4] file-name The file name.
-[5] backup-file The name of a backup file created during a merge.
- Only valid for MERGED and CONFLICT files.
-[6] base-revision The revision that the working file was based on.
- Only valid for MERGED and CONFLICT files.
-[7] head-revision The revision that the newly merged changes came from
- Only valid for MERGED and CONFLICT files.
-[8] backup-revision The revision of the cvs backup file (original working rev.)
- Only valid for MERGED and CONFLICT files.
-[9] cvs-diff-buffer A buffer that contains a 'cvs diff file'.
-[10] vendor-diff-buffer A buffer that contains a 'diff base-file head-file'.
-[11] backup-diff-buffer A buffer that contains a 'diff file backup-file'.
-[12] full-log The output from cvs, unparsed.
-[13] mod-time Modification time of file used for *-diff-buffer."
-
- (cons
- 'CVS-FILEINFO
- (vector nil nil type dir file-name nil nil nil nil nil nil nil full-log nil nil)))
-
-;;; Selectors:
-
-(defun cvs-fileinfo->handled (cvs-fileinfo)
- "Get the `handled' field from CVS-FILEINFO."
- (elt (cdr cvs-fileinfo) 0))
-
-(defun cvs-fileinfo->marked (cvs-fileinfo)
- "Check if CVS-FILEINFO is marked."
- (elt (cdr cvs-fileinfo) 1))
-
-(defun cvs-fileinfo->type (cvs-fileinfo)
- "Get type from CVS-FILEINFO.
-Type is one of UPDATED, PATCHED, MODIFIED, ADDED, REMOVED, CVS-REMOVED, MERGED,
-CONFLICT, REM-CONFLICT, MOD-CONFLICT, REM-EXIST, DIRCHANGE, UNKNOWN,
-UNKNOWN-DIR, MOVE-AWAY, REPOS-MISSING or MESSAGE."
- (elt (cdr cvs-fileinfo) 2))
-
-(defun cvs-fileinfo->dir (cvs-fileinfo)
- "Get dir from CVS-FILEINFO.
-The directory name does not end with a slash."
- (elt (cdr cvs-fileinfo) 3))
-
-(defun cvs-fileinfo->file-name (cvs-fileinfo)
- "Get file-name from CVS-FILEINFO."
- (elt (cdr cvs-fileinfo) 4))
-
-(defun cvs-fileinfo->backup-file (cvs-fileinfo)
- "Get backup-file from CVS-FILEINFO."
- (elt (cdr cvs-fileinfo) 5))
-
-(defun cvs-fileinfo->base-revision (cvs-fileinfo)
- "Get the base revision from CVS-FILEINFO."
- (elt (cdr cvs-fileinfo) 6))
-
-(defun cvs-fileinfo->head-revision (cvs-fileinfo)
- "Get the head revision from CVS-FILEINFO."
- (elt (cdr cvs-fileinfo) 7))
-
-(defun cvs-fileinfo->backup-revision (cvs-fileinfo)
- "Get the backup revision from CVS-FILEINFO."
- (elt (cdr cvs-fileinfo) 8))
-
-(defun cvs-fileinfo->cvs-diff-buffer (cvs-fileinfo)
- "Get cvs-diff-buffer from CVS-FILEINFO."
- (elt (cdr cvs-fileinfo) 9))
-
-(defun cvs-fileinfo->vendor-diff-buffer (cvs-fileinfo)
- "Get backup-diff-buffer from CVS-FILEINFO."
- (elt (cdr cvs-fileinfo) 10))
-
-(defun cvs-fileinfo->backup-diff-buffer (cvs-fileinfo)
- "Get backup-diff-buffer from CVS-FILEINFO."
- (elt (cdr cvs-fileinfo) 11))
-
-(defun cvs-fileinfo->full-log (cvs-fileinfo)
- "Get full-log from CVS-FILEINFO."
- (elt (cdr cvs-fileinfo) 12))
-
-(defun cvs-fileinfo->mod-time (cvs-fileinfo)
- "Get mod-time from CVS-FILEINFO."
- (elt (cdr cvs-fileinfo) 13))
-
-;;; Modifiers:
-
-(defun cvs-set-fileinfo->handled (cvs-fileinfo newval)
- "Set handled in CVS-FILEINFO to NEWVAL."
- (aset (cdr cvs-fileinfo) 0 newval))
-
-(defun cvs-set-fileinfo->marked (cvs-fileinfo newval)
- "Set marked in CVS-FILEINFO to NEWVAL."
- (aset (cdr cvs-fileinfo) 1 newval))
-
-(defun cvs-set-fileinfo->type (cvs-fileinfo newval)
- "Set type in CVS-FILEINFO to NEWVAL."
- (aset (cdr cvs-fileinfo) 2 newval))
-
-(defun cvs-set-fileinfo->dir (cvs-fileinfo newval)
- "Set dir in CVS-FILEINFO to NEWVAL.
-The directory should now end with a slash."
- (aset (cdr cvs-fileinfo) 3 newval))
-
-(defun cvs-set-fileinfo->file-name (cvs-fileinfo newval)
- "Set file-name in CVS-FILEINFO to NEWVAL."
- (aset (cdr cvs-fileinfo) 4 newval))
-
-(defun cvs-set-fileinfo->backup-file (cvs-fileinfo newval)
- "Set backup-file in CVS-FILEINFO to NEWVAL."
- (aset (cdr cvs-fileinfo) 5 newval))
-
-(defun cvs-set-fileinfo->base-revision (cvs-fileinfo newval)
- "Set base-revision in CVS-FILEINFO to NEWVAL."
- (aset (cdr cvs-fileinfo) 6 newval))
-
-(defun cvs-set-fileinfo->head-revision (cvs-fileinfo newval)
- "Set head-revision in CVS-FILEINFO to NEWVAL."
- (aset (cdr cvs-fileinfo) 7 newval))
-
-(defun cvs-set-fileinfo->backup-revision (cvs-fileinfo newval)
- "Set backup-revision in CVS-FILEINFO to NEWVAL."
- (aset (cdr cvs-fileinfo) 8 newval))
-
-(defun cvs-set-fileinfo->cvs-diff-buffer (cvs-fileinfo newval)
- "Set cvs-diff-buffer in CVS-FILEINFO to NEWVAL."
- (aset (cdr cvs-fileinfo) 9 newval))
-
-(defun cvs-set-fileinfo->vendor-diff-buffer (cvs-fileinfo newval)
- "Set vendor-diff-buffer in CVS-FILEINFO to NEWVAL."
- (aset (cdr cvs-fileinfo) 10 newval))
-
-(defun cvs-set-fileinfo->backup-diff-buffer (cvs-fileinfo newval)
- "Set backup-diff-buffer in CVS-FILEINFO to NEWVAL."
- (aset (cdr cvs-fileinfo) 11 newval))
-
-(defun cvs-set-fileinfo->full-log (cvs-fileinfo newval)
- "Set full-log in CVS-FILEINFO to NEWVAL."
- (aset (cdr cvs-fileinfo) 12 newval))
-
-(defun cvs-set-fileinfo->mod-time (cvs-fileinfo newval)
- "Set full-log in CVS-FILEINFO to NEWVAL."
- (aset (cdr cvs-fileinfo) 13 newval))
-
-;;; Predicate:
-
-(defun cvs-fileinfo-p (object)
- "Return t if OBJECT is a cvs-fileinfo."
- (eq (car-safe object) 'CVS-FILEINFO))
-
-;;;; End of types.
-
-;;----------
-(defun cvs-use-temp-buffer ()
- "Display a temporary buffer in another window and select it.
-The selected window will not be changed. The temporary buffer will
-be erased and writable."
-
- (let ((dir default-directory))
- (display-buffer (get-buffer-create cvs-temp-buffer-name))
- (set-buffer cvs-temp-buffer-name)
- (setq buffer-read-only nil)
- (setq default-directory dir)
- (erase-buffer)))
-
-;;----------
-(defun cvs-examine (directory &optional local)
- "Run a 'cvs -n update' in the current working directory.
-That is, check what needs to be done, but don't change the disc.
-Feed the output to a *cvs* buffer and run cvs-mode on it.
-If optional prefix argument LOCAL is non-nil, 'cvs update -l' is run.
-WARNING: this doesn't work very well yet...."
-
- ;; TODO: this should do everything cvs-update does...
- ;; for example, for CONFLICT files, it should setup fileinfo appropriately
-
- (interactive (list (read-file-name "CVS Update (directory): "
- nil default-directory nil)
- current-prefix-arg))
- (cvs-do-update directory local 'noupdate))
-
-;;----------
-(defun cvs-update (directory &optional local)
- "Run a 'cvs update' in the current working directory. Feed the
-output to a *cvs* buffer and run cvs-mode on it.
-If optional prefix argument LOCAL is non-nil, 'cvs update -l' is run."
-
- (interactive (list (read-file-name "CVS Update (directory): "
- nil default-directory nil)
- current-prefix-arg))
- (cvs-do-update directory local nil)
- (switch-to-buffer cvs-buffer-name))
-
-;;----------
-(defun cvs-update-other-window (directory &optional local)
- "Run a 'cvs update' in the current working directory. Feed the
-output to a *cvs* buffer, display it in the other window, and run
-cvs-mode on it.
-
-If optional prefix argument LOCAL is non-nil, 'cvs update -l' is run."
-
- (interactive (list (read-file-name "CVS Update other window (directory): "
- nil default-directory nil)
- current-prefix-arg))
- (cvs-do-update directory local nil)
- (switch-to-buffer-other-window cvs-buffer-name))
-
-;;----------
-(defun cvs-filter (predicate list &rest extra-args)
- "Apply PREDICATE to each element on LIST.
-Args: PREDICATE LIST &rest EXTRA-ARGS.
-
-Return a new list consisting of those elements that PREDICATE
-returns non-nil for.
-
-If more than two arguments are given the remaining args are
-passed to PREDICATE."
-
- ;; Avoid recursion - this should work for LONG lists also!
- (let* ((head (cons 'dummy-header nil))
- (tail head))
- (while list
- (if (apply predicate (car list) extra-args)
- (setq tail (setcdr tail (list (car list)))))
- (setq list (cdr list)))
- (cdr head)))
-
-;;----------
-(defun cvs-mode-update-no-prompt ()
- "Run cvs update in current directory."
-
- (interactive)
- (cvs-do-update default-directory nil nil))
-
-;;----------
-(defun cvs-do-update (directory local dont-change-disc)
- "Do a 'cvs update' in DIRECTORY.
-Args: DIRECTORY LOCAL DONT-CHANGE-DISC.
-
-If LOCAL is non-nil 'cvs update -l' is executed.
-If DONT-CHANGE-DISC is non-nil 'cvs -n update' is executed.
-Both LOCAL and DONT-CHANGE-DISC may be non-nil simultaneously.
-
-*Note*: DONT-CHANGE-DISC does not yet work. The parser gets confused."
-
- (save-some-buffers)
- ;; Ensure that it is safe to do an update. If not, ask user
- ;; for confirmation.
- (if (and (boundp 'cvs-cookie-handle) (collection-buffer cvs-cookie-handle))
- (if (collection-collect-tin
- cvs-cookie-handle
- '(lambda (cookie) (eq (cvs-fileinfo->type cookie) 'CONFLICT)))
- (if (not
- (yes-or-no-p
- "Only update if conflicts have been resolved. Continue? "))
- (error "Update aborted by user request."))))
- (if (not (file-exists-p cvs-program))
- (error "%s: file not found (check setting of cvs-program)"
- cvs-program))
- (let* ((this-dir (file-name-as-directory (expand-file-name directory)))
- (update-buffer (generate-new-buffer
- (concat " " (file-name-nondirectory
- (substring this-dir 0 -1))
- "-update")))
- (temp-name (make-temp-name
- (concat (file-name-as-directory
- (or (getenv "TMPDIR") "/tmp"))
- "pcl-cvs.")))
- (args nil))
-
- ;; Check that this-dir exists and is a directory that is under CVS contr.
-
- (if (not (file-directory-p this-dir))
- (error "%s is not a directory." this-dir))
- (if (not (file-directory-p (concat this-dir "CVS")))
- (error "%s does not contain CVS controlled files." this-dir))
- (if (file-readable-p (concat this-dir "CVS/Root"))
- (save-excursion ; read CVS/Root into cvs-cvsroot
- (find-file (concat this-dir "CVS/Root"))
- (goto-char (point-min))
- (setq cvs-cvsroot (buffer-substring (point)
- (progn (end-of-line) (point))))
- (if (not cvs-cvsroot)
- (error "Invalid contents of %sCVS/Root" this-dir))
- (kill-buffer (current-buffer)))
- (if (and cvs-cvsroot-required
- (not (or (getenv "CVSROOT") cvs-cvsroot)))
- (error "Both cvs-cvsroot and environment variable CVSROOT are unset, and no CVS/Root.")))
-
- ;; Check that at most one `cvs update' is run at any time.
-
- (if (and cvs-update-running (process-status cvs-update-running)
- (or (eq (process-status cvs-update-running) 'run)
- (eq (process-status cvs-update-running) 'stop)))
- (error "Can't run two `cvs update' simultaneously."))
-
- (if (not (listp cvs-update-optional-flags))
- (error "cvs-update-optional-flags should be set using cvs-set-update-optional-flags"))
-
- ;; Generate "-d /master -n update -l".
- (setq args (concat (if cvs-cvsroot (concat " -d " cvs-cvsroot))
- (if dont-change-disc " -n ")
- " update "
- (if local " -l ")
- (if cvs-update-optional-flags
- (mapconcat 'identity
- (copy-sequence cvs-update-optional-flags)
- " "))))
-
- ;; Set up the buffer that receives the stderr output from "cvs update".
- (set-buffer update-buffer)
- (setq default-directory this-dir)
- (make-local-variable 'cvs-stdout-file)
- (setq cvs-stdout-file temp-name)
-
- (setq cvs-update-running
- (let ((process-connection-type nil)) ; Use a pipe, not a pty.
- (start-process "cvs" update-buffer cvs-shell "-c"
- (concat cvs-program " " args " > " temp-name))))
-
- (setq mode-line-process
- (concat ": "
- (symbol-name (process-status cvs-update-running))))
- (set-buffer-modified-p (buffer-modified-p)) ; Update the mode line.
- (set-process-sentinel cvs-update-running 'cvs-sentinel)
- (set-process-filter cvs-update-running 'cvs-update-filter)
- (set-marker (process-mark cvs-update-running) (point-min))
-
- (save-excursion
- (set-buffer (get-buffer-create cvs-buffer-name))
- (setq buffer-read-only nil)
- (erase-buffer)
- (cvs-mode))
-
- (setq cvs-cookie-handle
- (collection-create
- cvs-buffer-name 'cvs-pp
- cvs-startup-message ;See comment above cvs-startup-message.
- "---------- End -----"))
-
- (cookie-enter-first
- cvs-cookie-handle
- (cvs-create-fileinfo
- 'MESSAGE nil nil (concat "\n Running `cvs " args "' in " this-dir
- "...\n")))
-
- (save-excursion
- (set-buffer cvs-buffer-name)
- (setq mode-line-process
- (concat ": "
- (symbol-name (process-status cvs-update-running))))
- (set-buffer-modified-p (buffer-modified-p)) ; Update the mode line.
- (setq buffer-read-only t))
-
- ;; Work around a bug in emacs 18.57 and earlier.
- (setq cvs-buffers-to-delete
- (cvs-delete-unused-temporary-buffers cvs-buffers-to-delete)))
-
- ;; The following line is said to improve display updates on some
- ;; emacses. It shouldn't be needed, but it does no harm.
- (sit-for 0))
-
-;;----------
-(defun cvs-delete-unused-temporary-buffers (list)
- "Delete all buffers on LIST that is not visible.
-Return a list of all buffers that still is alive."
-
- (cond
- ((null list) nil)
- ((get-buffer-window (car list))
- (cons (car list)
- (cvs-delete-unused-temporary-buffers (cdr list))))
- (t
- (kill-buffer (car list))
- (cvs-delete-unused-temporary-buffers (cdr list)))))
-
-;;----------
-(put 'cvs-mode 'mode-class 'special)
-
-;;----------
-(defun cvs-mode ()
- "\\<cvs-mode-map>Mode used for pcl-cvs, a front-end to CVS.
-
-To get to the \"*cvs*\" buffer you should use ``\\[execute-extended-command] cvs-update''.
-
-Full documentation is in the Texinfo file. Here are the most useful commands:
-
-\\[cvs-mode-previous-line] Move up. \\[cvs-mode-next-line] Move down.
-\\[cvs-mode-commit] Commit file. \\[cvs-mode-update-no-prompt] Re-update directory.
-\\[cvs-mode-mark] Mark file/dir. \\[cvs-mode-unmark] Unmark file/dir.
-\\[cvs-mode-mark-all-files] Mark all files. \\[cvs-mode-unmark-all-files] Unmark all files.
-\\[cvs-mode-find-file] Edit file/run Dired. \\[cvs-mode-find-file-other-window] Find file or run Dired in other window.
-\\[cvs-mode-ignore] Add file to ./.cvsignore. \\[cvs-mode-add-change-log-entry-other-window] Write ChangeLog in other window.
-\\[cvs-mode-add] Add to repository. \\[cvs-mode-remove-file] Remove file.
-\\[cvs-mode-diff-cvs] Diff with base revision. \\[cvs-mode-diff-backup] Diff backup file.
-\\[cvs-mode-ediff] Ediff base rev & backup. \\[cvs-mode-diff-vendor] Show merge from vendor branch.
-\\[cvs-mode-emerge] Emerge base rev & backup. \\[cvs-mode-diff-backup] Diff backup file.
-\\[cvs-mode-acknowledge] Delete line from buffer. \\[cvs-mode-remove-handled] Remove processed entries.
-\\[cvs-mode-log] Run ``cvs log''. \\[cvs-mode-status] Run ``cvs status''.
-\\[cvs-mode-tag] Run ``cvs tag''. \\[cvs-mode-rtag] Run ``cvs rtag''.
-\\[cvs-mode-changelog-commit] Like \\[cvs-mode-commit], but get default log text from ChangeLog.
-\\[cvs-mode-undo-local-changes] Revert the last checked in version - discard your changes to the file.
-
-Entry to this mode runs cvs-mode-hook.
-This description is updated for release 1.05-CVS-$Name: $ of pcl-cvs.
-
-All bindings:
-\\{cvs-mode-map}"
-
- (interactive)
- (setq major-mode 'cvs-mode)
- (setq mode-name "CVS")
- (setq mode-line-process nil)
-;; for older v18 emacs
-;;(buffer-flush-undo (current-buffer))
- (buffer-disable-undo (current-buffer))
- (make-local-variable 'goal-column)
- (setq goal-column cvs-cursor-column)
- (use-local-map cvs-mode-map)
- (run-hooks 'cvs-mode-hook))
-
-;;----------
-(defun cvs-sentinel (proc msg)
- "Sentinel for the cvs update process.
-This is responsible for parsing the output from the cvs update when
-it is finished."
-
- (cond
- ((null (buffer-name (process-buffer proc)))
- ;; buffer killed
- (set-process-buffer proc nil))
- ((memq (process-status proc) '(signal exit))
- (let* ((obuf (current-buffer))
- (omax (point-max))
- (opoint (point)))
- ;; save-excursion isn't the right thing if
- ;; process-buffer is current-buffer
- (unwind-protect
- (progn
- (set-buffer (process-buffer proc))
- (setq mode-line-process
- (concat ": "
- (symbol-name (process-status proc))))
- (let* ((out-file cvs-stdout-file)
- (stdout-buffer (find-file-noselect out-file)))
- (save-excursion
- (set-buffer stdout-buffer)
- (rename-buffer (concat " "
- (file-name-nondirectory out-file)) t))
- (cvs-parse-update stdout-buffer (process-buffer proc))
- (setq cvs-buffers-to-delete
- (cons (process-buffer proc)
- (cons stdout-buffer
- cvs-buffers-to-delete)))
- (delete-file out-file)))
- (set-buffer-modified-p (buffer-modified-p))
- (setq cvs-update-running nil))
- (if (equal obuf (process-buffer proc))
- nil
- (set-buffer (process-buffer proc))
- (if (< opoint omax)
- (goto-char opoint))
- (set-buffer obuf))))))
-
-;;----------
-(defun cvs-update-filter (proc string)
- "Filter function for pcl-cvs.
-This function gets the output that CVS sends to stderr. It inserts it
-into (process-buffer proc) but it also checks if CVS is waiting for a
-lock file. If so, it inserts a message cookie in the *cvs* buffer."
-
- (let ((old-buffer (current-buffer))
- (data (match-data)))
- (unwind-protect
- (progn
- (set-buffer (process-buffer proc))
- (save-excursion
- ;; Insert the text, moving the process-marker.
- (goto-char (process-mark proc))
- (insert string)
- (set-marker (process-mark proc) (point))
- ;; Delete any old lock message
- (if (tin-nth cvs-cookie-handle 1)
- (tin-delete cvs-cookie-handle
- (tin-nth cvs-cookie-handle 1)))
- ;; Check if CVS is waiting for a lock.
- (beginning-of-line 0) ;Move to beginning of last
- ;complete line.
- (cond
- ((looking-at
- "^cvs \\(update\\|server\\): \\[..:..:..\\] waiting for \\(.*\\)lock in \\(.*\\)$")
- (setq cvs-lock-file (buffer-substring (match-beginning 3)
- (match-end 3)))
- (cookie-enter-last
- cvs-cookie-handle
- (cvs-create-fileinfo
- 'MESSAGE nil nil
- (concat "\tWaiting for "
- (buffer-substring (match-beginning 2)
- (match-end 2))
- "lock in " cvs-lock-file
- ".\n\t (type M-x cvs-delete-lock to delete it)")))))))
- (store-match-data data)
- (set-buffer old-buffer))))
-
-;;----------
-(defun cvs-delete-lock ()
- "Delete the lock file that CVS is waiting for.
-Note that this can be dangerous. You should only do this
-if you are convinced that the process that created the lock is dead."
-
- (interactive)
- (cond
- ((not (or (file-exists-p
- (concat (file-name-as-directory cvs-lock-file) "#cvs.lock"))
- (cvs-filter (function cvs-lock-file-p)
- (directory-files cvs-lock-file))))
- (error "No lock files found."))
- ((yes-or-no-p (concat "Really delete locks in " cvs-lock-file "? "))
- ;; Re-read the directory -- the locks might have disappeared.
- (let ((locks (cvs-filter (function cvs-lock-file-p)
- (directory-files cvs-lock-file))))
- (while locks
- (delete-file (concat (file-name-as-directory cvs-lock-file)
- (car locks)))
- (setq locks (cdr locks)))
- (cvs-remove-directory
- (concat (file-name-as-directory cvs-lock-file) "#cvs.lock"))))))
-
-;;----------
-(defun cvs-remove-directory (dir)
- "Remove a directory."
-
- (if (file-directory-p dir)
- (call-process cvs-rmdir-program nil nil nil dir)
- (error "Not a directory: %s" dir))
- (if (file-exists-p dir)
- (error "Could not remove directory %s" dir)))
-
-;;----------
-(defun cvs-lock-file-p (file)
- "Return true if FILE looks like a CVS lock file."
-
- (or
- (string-match "^#cvs.tfl.[0-9]+$" file)
- (string-match "^#cvs.rfl.[0-9]+$" file)
- (string-match "^#cvs.wfl.[0-9]+$" file)))
-
-;;----------
-(defun cvs-quote-multiword-string (str)
- "Return STR surrounded in single quotes if it contains whitespace."
- (cond ((string-match "[ \t\n]" str)
- (concat "'" str "'"))
- (t
- str)))
-
-;;----------
-;; this should be in subr.el or some similar place....
-(defun parse-string (str &optional regexp)
- "Explode the string STR into a list of words ala strtok(3). Optional REGEXP
-defines regexp matching word separator, which defaults to \"[ \\t\\n]+\"."
- (let (str-list ; new list
- str-token ; "index" of next token
- (str-start 0) ; "index" of current token
- (str-sep (if regexp
- regexp
- "[ \t\n]+")))
- (while (setq str-token (string-match str-sep str str-start))
- (setq str-list
- (nconc str-list
- (list (substring str str-start str-token))))
- (setq str-start (match-end 0)))
- ;; tag on the remainder as the final item
- (if (not (>= str-start (length str)))
- (setq str-list
- (nconc str-list
- (list (substring str str-start)))))
- str-list))
-
-;;----------
-(defun cvs-make-list (str)
- "Return list of words made from the string STR."
- (cond ((string-match "[ \t\n]+" str)
- (let ((new-str (parse-string str "[ \t\n]+")))
- ;; this is ugly, but assume if the first element is empty, there are
- ;; no more elements.
- (cond ((string= (car new-str) "")
- nil)
- (t
- new-str))))
- ((string= str "")
- nil)
- (t
- (list str))))
-
-;;----------
-(defun cvs-skip-line (stdout stderr regexp &optional arg)
- "Like forward-line, but check that the skipped line matches REGEXP.
-Args: STDOUT STDERR REGEXP &optional ARG.
-
-If it doesn't match REGEXP a bug report is generated and displayed.
-STDOUT and STDERR is only used to do that.
-
-If optional ARG, a number, is given the ARGth parenthesized expression
-in the REGEXP is returned as a string.
-Point should be in column 1 when this function is called."
-
- (cond
- ((looking-at regexp)
- (forward-line 1)
- (if arg
- (buffer-substring (match-beginning arg)
- (match-end arg))))
- (t
- (cvs-parse-error stdout
- stderr
- (if (eq (current-buffer) stdout)
- 'STDOUT
- 'STDERR)
- (point)
- regexp))))
-
-;;----------
-(defun cvs-get-current-dir (root-dir dirname)
- "Return current working directory, suitable for cvs-parse-update.
-Args: ROOT-DIR DIRNAME.
-
-Concatenates ROOT-DIR and DIRNAME to form an absolute path."
-
- (if (string= "." dirname)
- (substring root-dir 0 -1)
- (concat root-dir dirname)))
-
-;;----------
-(defun cvs-compare-fileinfos (a b)
- "Compare fileinfo A with fileinfo B and return t if A is `less'."
-
- (cond
- ;; Sort acording to directories.
- ((string< (cvs-fileinfo->dir a) (cvs-fileinfo->dir b)) t)
- ((not (string= (cvs-fileinfo->dir a) (cvs-fileinfo->dir b))) nil)
- ;; The DIRCHANGE entry is always first within the directory.
- ((and (eq (cvs-fileinfo->type a) 'DIRCHANGE)
- (not (eq (cvs-fileinfo->type b) 'DIRCHANGE))) t)
- ((and (eq (cvs-fileinfo->type b) 'DIRCHANGE)
- (not (eq (cvs-fileinfo->type a) 'DIRCHANGE))) nil)
- ;; All files are sorted by file name.
- ((string< (cvs-fileinfo->file-name a) (cvs-fileinfo->file-name b)))))
-
-;;----------
-(defun cvs-parse-error (stdout-buffer stderr-buffer err-buf pos &optional indicator)
- "Handle a parse error when parsing the output from cvs.
-Args: STDOUT-BUFFER STDERR-BUFFER ERR-BUF POS &optional INDICATOR.
-
-ERR-BUF should be 'STDOUT or 'STDERR."
-
- (setq pos (1- pos))
- (set-buffer cvs-buffer-name)
- (setq buffer-read-only nil)
- (erase-buffer)
- (insert "To: " pcl-cvs-bugs-address "\n")
- (insert "Subject: pcl-cvs release" pcl-cvs-version " parse error.\n")
- (insert (concat mail-header-separator "\n"))
- (insert "This bug report is automatically generated by pcl-cvs\n")
- (insert "because it doesn't understand some output from CVS. Below\n")
- (insert "is detailed information about the error. Please send\n")
- (insert "this, together with any information you think might be\n")
- (insert "useful for me to fix the bug, to the address above. But\n")
- (insert "please check the \"known problems\" section of the\n")
- (insert "documentation first. Note that this buffer contains\n")
- (insert "information that you might consider confidential. You\n")
- (insert "are encouraged to read through it before sending it.\n")
- (insert "\n")
- (insert "Press C-c C-c to send this email.\n\n")
- (insert "Please state the version of these programs you are using:\n\n")
- (insert "RCS: \ndiff: \n\n")
-
- (let* ((stdout (save-excursion (set-buffer stdout-buffer) (buffer-string)))
- (stderr (save-excursion (set-buffer stderr-buffer) (buffer-string)))
- (errstr (if (eq err-buf 'STDOUT) stdout stderr))
- (errline-end (string-match "\n" errstr pos))
- (errline (substring errstr pos errline-end)))
- (insert (format "Offending line (%d chars): >" (- errline-end pos)))
- (insert errline)
- (insert "<\n")
- (insert "Sent to " (symbol-name err-buf) " at pos " (format "%d\n" pos))
- (if indicator
- (insert "Optional args: \"" indicator "\".\n"))
- (insert "\nEmacs-version: " (emacs-version) "\n")
- (insert "Pcl-cvs Version: "
- "@(#)OrigId: pcl-cvs.el,v 1.93 1993/05/31 22:44:00 ceder Exp\n")
- (insert "CVS Version: "
- "@(#)cvs/contrib/pcl-cvs:$Name: $:$Id: pcl-cvs.el,v 1.7 1998/01/04 14:24:13 kingdon Exp $\n\n")
- (insert (format "--- Contents of stdout buffer (%d chars) ---\n"
- (length stdout)))
- (insert stdout)
- (insert "--- End of stdout buffer ---\n")
- (insert (format "--- Contents of stderr buffer (%d chars) ---\n"
- (length stderr)))
- (insert stderr)
- (insert "--- End of stderr buffer ---\n")
- (insert "\nEnd of bug report.\n")
- (require 'sendmail)
- (mail-mode)
- (error "CVS parse error - please report this bug.")))
-
-;;----------
-(defun cvs-parse-update (stdout-buffer stderr-buffer)
- "Parse the output from `cvs update'.
-
-Args: STDOUT-BUFFER STDERR-BUFFER.
-
-This functions parses the from `cvs update' (which should be
-separated in its stdout- and stderr-components) and prints a
-pretty representation of it in the *cvs* buffer.
-
-Signals an error if unexpected output was detected in the buffer."
-
- (let* ((head (cons 'dummy nil))
- (tail (cvs-parse-stderr stdout-buffer stderr-buffer
- head default-directory))
- (root-dir default-directory))
- (cvs-parse-stdout stdout-buffer stderr-buffer tail root-dir)
- (setq head (sort (cdr head) (function cvs-compare-fileinfos)))
- (collection-clear cvs-cookie-handle)
- (collection-append-cookies cvs-cookie-handle head)
- (cvs-remove-stdout-shadows)
- (if cvs-auto-remove-handled-directories
- (cvs-remove-empty-directories))
- (set-buffer cvs-buffer-name)
- (cvs-mode)
- (goto-char (point-min))
- (tin-goto-previous cvs-cookie-handle (point-min) 1)
- (setq default-directory root-dir)))
-
-;;----------
-(defun cvs-remove-stdout-shadows ()
- "Remove entries in the *cvs* buffer that comes from both stdout and stderr.
-If there is two entries for a single file the second one should be
-deleted. (Remember that sort uses a stable sort algorithm, so one can
-be sure that the stderr entry is always first)."
-
- (collection-filter-tins cvs-cookie-handle
- (function
- (lambda (tin)
- (not (cvs-shadow-entry-p tin))))))
-
-;;----------
-(defun cvs-shadow-entry-p (tin)
- "Return non-nil if TIN is a shadow entry.
-Args: TIN.
-
-A TIN is a shadow entry if the previous tin contains the same file."
-
- (let* ((previous-tin (tin-previous cvs-cookie-handle tin))
- (curr (tin-cookie cvs-cookie-handle tin))
- (prev (and previous-tin
- (tin-cookie cvs-cookie-handle previous-tin))))
- (and
- prev curr
- (string= (cvs-fileinfo->file-name prev)
- (cvs-fileinfo->file-name curr))
- (string= (cvs-fileinfo->dir prev)
- (cvs-fileinfo->dir curr))
- (or
- (and (eq (cvs-fileinfo->type prev) 'CONFLICT)
- (eq (cvs-fileinfo->type curr) 'CONFLICT))
- (and (eq (cvs-fileinfo->type prev) 'MERGED)
- (eq (cvs-fileinfo->type curr) 'MODIFIED))
- (and (eq (cvs-fileinfo->type prev) 'REM-EXIST)
- (eq (cvs-fileinfo->type curr) 'REMOVED))))))
-
-;;----------
-(defun cvs-find-backup-file (filename &optional dirname)
- "Look for a backup file for FILENAME, optionally in directory DIRNAME, and if
-there is one, return the name of the first file found as a string."
-
- (if (eq dirname nil)
- (setq dirname default-directory))
- (car (directory-files dirname nil (concat "^\\" cvs-bakprefix filename
- "\\."))))
-
-;;----------
-(defun cvs-find-backup-revision (filename)
- "Take FILENAME as the name of a cvs backup file and return the revision of
-that file as a string."
-
- (substring filename
- (+ 1 (string-match "\\.\\([0-9.]+\\)$" filename))))
-
-;;----------
-(defun cvs-parse-stderr (stdout-buffer stderr-buffer head dir)
- "Parse the output from CVS that is written to stderr.
-Args: STDOUT-BUFFER STDERR-BUFFER HEAD DIR
-
-STDOUT-BUFFER holds the output that cvs sent to stdout. It is only
-used to create a bug report in case there is a parse error.
-STDERR-BUFFER is the buffer that holds the output to parse.
-HEAD is a cons-cell, the head of the list that is built.
-DIR is the directory the `cvs update' was run in.
-
-This function returns the last cons-cell in the list that is built."
-
- (save-window-excursion
- (set-buffer stderr-buffer)
- (goto-char (point-min))
- (let ((current-dir dir)
- (root-dir dir))
-
- (while (< (point) (point-max))
- (cond
-
- ;; CVS is descending a subdirectory.
-
- ((looking-at
- "^cvs \\(server\\|update\\): Updating \\(.*\\)$")
- (setq current-dir
- (cvs-get-current-dir
- root-dir
- (buffer-substring (match-beginning 2) (match-end 2))))
- (setcdr head (list (cvs-create-fileinfo
- 'DIRCHANGE
- current-dir
- "." ; the old version had nil here???
- (buffer-substring (match-beginning 0)
- (match-end 0)))))
- (setq head (cdr head))
- (forward-line 1))
-
- ;; File removed, since it is removed (by third party) in repository.
-
- ((or (looking-at
- "^cvs \\(update\\|server\\): warning: \\(.*\\) is not (any longer) pertinent")
- (looking-at
- "^cvs \\(update\\|server\\): \\(.*\\) is no longer in the repository"))
-
- (setcdr head (list (cvs-create-fileinfo
- 'CVS-REMOVED
- current-dir
- (file-name-nondirectory
- (buffer-substring (match-beginning 2)
- (match-end 2)))
- (buffer-substring (match-beginning 0)
- (match-end 0)))))
- (setq head (cdr head))
- (forward-line 1))
-
- ;; File removed by you, but recreated by cvs. Ignored. Will say
- ;; "Updated" on the next line.
-
- ((looking-at
- "^cvs \\(update\\|server\\): warning: .* was lost$")
- (forward-line 1))
-
- ;; Patch failed; CVS will refetch the file. Ignored.
- ((looking-at
- "^[0-9]+ out of [0-9]+ hunks failed--saving rejects to .*$")
- (forward-line 1))
-
- ;; File unknown for some reason.
- ;; FIXME: is it really a good idea to add this as unknown here?
-
- ((looking-at
- "cvs \\(update\\|server\\): nothing known about \\(.*\\)$")
- (let ((filename (buffer-substring (match-beginning 2)
- (match-end 2))))
- (if (file-directory-p filename)
- (setcdr head (list (cvs-create-fileinfo
- 'UNKNOWN-DIR
- current-dir
- "."
- (buffer-substring (match-beginning 0)
- (match-end 0)))))
- (setcdr head (list (cvs-create-fileinfo
- 'UNKNOWN
- current-dir
- (file-name-nondirectory filename)
- (buffer-substring (match-beginning 0)
- (match-end 0)))))))
- (setq head (cdr head))
- (forward-line 1))
-
- ;; A file that has been created by you, but added to the cvs
- ;; repository by another.
-
- ((looking-at
- "^cvs \\(update\\|server\\): move away \\(.*\\); it is in the way$")
- (setcdr head (list (cvs-create-fileinfo
- 'MOVE-AWAY
- current-dir
- (file-name-nondirectory
- (buffer-substring (match-beginning 2)
- (match-end 2)))
- (buffer-substring (match-beginning 0)
- (match-end 0)))))
- (setq head (cdr head))
- (forward-line 1))
-
- ;; Cvs waits for a lock. Ignore.
-
- ((looking-at
- "^cvs \\(update\\|server\\): \\[..:..:..\\] waiting for .*lock in ")
- (forward-line 1))
- ((looking-at
- "^cvs \\(update\\|server\\): \\[..:..:..\\] obtained lock in ")
- (forward-line 1))
-
- ;; File removed in repository, but edited by you.
-
- ((looking-at
- "^cvs \\(update\\|server\\): conflict: \\(.*\\) is modified but no longer in the repository$")
- (setcdr head (list
- (cvs-create-fileinfo
- 'REM-CONFLICT
- current-dir
- (file-name-nondirectory
- (buffer-substring (match-beginning 2)
- (match-end 2)))
- (buffer-substring (match-beginning 0)
- (match-end 0)))))
- (setq head (cdr head))
- (forward-line 1))
-
- ;; File removed in repository, but edited by someone else.
-
- ((looking-at
- "^cvs \\(update\\|server\\): conflict: removed \\(.*\\) was modified by second party")
- (setcdr head
- (list
- (cvs-create-fileinfo
- 'MOD-CONFLICT
- current-dir
- (buffer-substring (match-beginning 1)
- (match-end 1))
- (buffer-substring (match-beginning 0)
- (match-end 0)))))
- (setq head (cdr head))
- (forward-line 1))
-
- ;; File removed in repository, but not in local directory.
-
- ((looking-at
- "^cvs \\(update\\|server\\): \\(.*\\) should be removed and is still there")
- (setcdr head
- (list
- (cvs-create-fileinfo
- 'REM-EXIST
- current-dir
- (buffer-substring (match-beginning 2)
- (match-end 2))
- (buffer-substring (match-beginning 0)
- (match-end 0)))))
- (setq head (cdr head))
- (forward-line 1))
-
- ;; Error searching for repository
-
- ((looking-at
- "^cvs \\(update\\|server\\): in directory ")
- (let ((start (point)))
- (forward-line 1)
- (cvs-skip-line stdout-buffer stderr-buffer
- (regexp-quote "cvs [update aborted]: there is no repository "))
- (setcdr head (list (cvs-create-fileinfo
- 'REPOS-MISSING
- current-dir
- nil
- (buffer-substring start (point)))))
- (setq head (cdr head))))
-
- ;; Silly warning from attempted conflict resolution. Ignored.
- ;; FIXME: Should it be?
- ;; eg.: "cvs update: cannot find revision APC-web-update in file .cvsignore"
- ;;
- ((looking-at
- "^cvs \\(update\\|server\\): cannot find revision \\(.*\\) in file \\(.*\\)$")
- (forward-line 1)
- (message "%s" (buffer-substring (match-beginning 0) (match-end 0))))
-
- ;; CVS has decided to merge someone elses changes into this document.
- ;; About to start an rcsmerge operation...
- ;;
- ((looking-at
- "^RCS file: ")
-
- ;; skip the "RCS file:" line...
- (forward-line 1)
-
- (let ((complex-start (point))
- base-revision ; the first revision retrieved to merge from
- head-revision ; the second revision retrieved to merge from
- filename ; the name of the file being merged
- backup-file ; the name of the backup of the working file
- backup-revision) ; the revision of the original working file
-
- (setq base-revision
- (cvs-skip-line stdout-buffer stderr-buffer
- "^retrieving revision \\(.*\\)$"
- 1))
- (setq head-revision
- (cvs-skip-line stdout-buffer stderr-buffer
- "^retrieving revision \\(.*\\)$"
- 1))
- (setq filename
- (cvs-skip-line stdout-buffer stderr-buffer
- "^Merging differences between [0-9.]+ and [0-9.]+ into \\(.*\\)$"
- 1))
- (setq backup-file
- (cvs-find-backup-file filename current-dir))
- (setq backup-revision
- (cvs-find-backup-revision backup-file))
-
- ;; Was there a conflict during the merge?
-
- (cond
-
- ;;;; From CVS-1.3 & RCS-5.6.0.1 with GNU-Diffutils-2.5:
- ;;;; "cvs update -j OLD-REV -j NEW-REV ."
- ;;
- ;; RCS file: /big/web-CVS/apc/cmd/Main/logout.sh,v
- ;; retrieving revision 1.1.1.1
- ;; retrieving revision 1.1.1.2
- ;; Merging differences between 1.1.1.1 and 1.1.1.2 into logout.sh
- ;; rcsmerge warning: overlaps during merge
-
- ((looking-at
- ;; Allow both RCS 5.5 and 5.6. (5.6 prints "rcs" and " warning").
- "^\\(rcs\\)?merge[:]*\\( warning\\)?: \\(overlaps\\|conflicts\\) during merge$")
-
- ;; Yes, this is a conflict.
- (cvs-skip-line stdout-buffer stderr-buffer
- "^\\(rcs\\)?merge[:]*\\( warning\\)?: \\(overlaps\\|conflicts\\) during merge$")
-
- ;; this line doesn't seem to appear in all cases -- perhaps only
- ;; in "-j A -j B" usage, in which case this indicates ????
- (cvs-skip-line stdout-buffer stderr-buffer
- "^cvs \\(update\\|server\\): conflicts found in ")
-
- (let ((fileinfo
- (cvs-create-fileinfo
- 'CONFLICT current-dir
- filename
- (buffer-substring complex-start (point)))))
-
- ;; squirrel away info about the files that were retrieved for merging
- (cvs-set-fileinfo->base-revision fileinfo base-revision)
- (cvs-set-fileinfo->head-revision fileinfo head-revision)
- (cvs-set-fileinfo->backup-revision fileinfo backup-revision)
- (cvs-set-fileinfo->backup-file fileinfo backup-file)
-
- (setcdr head (list fileinfo))
- (setq head (cdr head))))
-
- ;; Was it a conflict, and was RCS compiled without DIFF3_BIN, in
- ;; which case this is a failed conflict resolution?
-
- ((looking-at
- ;; Allow both RCS 5.5 and 5.6. (5.6 prints "rcs" and " warning").
- "^\\(rcs\\)?merge\\( warning\\)?: overlaps or other problems during merge$")
-
- (cvs-skip-line stdout-buffer stderr-buffer
- "^\\(rcs\\)?merge\\( warning\\)?: overlaps or other problems during merge$")
- (cvs-skip-line stdout-buffer stderr-buffer
- "^cvs update: could not merge ")
- (cvs-skip-line stdout-buffer stderr-buffer
- "^cvs update: restoring .* from backup file ")
- (let ((fileinfo
- (cvs-create-fileinfo
- 'CONFLICT current-dir
- filename
- (buffer-substring complex-start (point)))))
- (setcdr head (list fileinfo))
- (setq head (cdr head))))
-
- ;; Not a conflict; it must be a succesful merge.
-
- (t
- (let ((fileinfo
- (cvs-create-fileinfo
- 'MERGED current-dir
- filename
- (buffer-substring complex-start (point)))))
- (cvs-set-fileinfo->base-revision fileinfo base-revision)
- (cvs-set-fileinfo->head-revision fileinfo head-revision)
- (cvs-set-fileinfo->backup-revision fileinfo backup-revision)
- (cvs-set-fileinfo->backup-file fileinfo backup-file)
- (setcdr head (list fileinfo))
- (setq head (cdr head)))))))
-
- ;; Error messages from CVS (incomplete)
-
- ((looking-at
- "^cvs \\(update\\|server\\): \\(invalid option .*\\)$")
- (error "Interface problem with CVS: %s"
- (buffer-substring (match-beginning 2) (match-end 2))))
-
- ;; network errors
-
- ;; Kerberos connection attempted but failed. This is not
- ;; really an error, as CVS will automatically fall back to
- ;; rsh. Plus it tries kerberos, if available, even when rsh
- ;; is what you really wanted.
-
- ((looking-at
- "^cvs update: kerberos connect:.*$")
- (forward-line 1)
- (message "Remote CVS: %s"
- (buffer-substring (match-beginning 0) (match-end 0))))
-
- ;; And when kerberos *does* fail, cvs prints out some stuff
- ;; as it tries rsh. Ignore that stuff too.
-
- ((looking-at
- "^cvs update: trying to start server using rsh$")
- (forward-line 1))
-
- ((looking-at
- "^\\([^:]*\\) Connection timed out")
- (error "Remote CVS: %s"
- (buffer-substring (match-beginning 0) (match-end 0))))
-
- ((looking-at
- "^Permission denied.")
- (error "Remote CVS: %s"
- (buffer-substring (match-beginning 0) (match-end 0))))
-
- ((looking-at
- "^cvs \\[update aborted\\]: premature end of file from server")
- (error "Remote CVS: %s"
- (buffer-substring (match-beginning 0) (match-end 0))))
-
- ;; Empty line. Probably inserted by mistake by user (or developer :-)
- ;; Ignore.
-
- ((looking-at
- "^$")
- (forward-line 1))
-
- ;; top-level parser (cond) default clause
-
- (t
- (cvs-skip-line stdout-buffer stderr-buffer
- "^UN-MATCHABLE-OUTPUT"))))))
-
- ;; cause this function to return the head of the parser output list
- head)
-
-;;----------
-(defun cvs-parse-stdout (stdout-buffer stderr-buffer head root-dir)
- "Parse the output from CVS that is written to stderr.
-Args: STDOUT-BUFFER STDERR-BUFFER HEAD ROOT-DIR
-
-STDOUT-BUFFER is the buffer that holds the output to parse.
-STDERR-BUFFER holds the output that cvs sent to stderr. It is only
-used to create a bug report in case there is a parse error.
-
-HEAD is a cons-cell, the head of the list that is built.
-ROOT-DIR is the directory the `cvs update' was run in.
-
-This function doesn't return anything particular."
-
- (save-window-excursion
- (set-buffer stdout-buffer)
- (goto-char (point-min))
- (while (< (point) (point-max))
- (cond
-
- ;; M: The file is modified by the user, and untouched in the repository.
- ;; A: The file is "cvs add"ed, but not "cvs ci"ed.
- ;; R: The file is "cvs remove"ed, but not "cvs ci"ed.
- ;; C: Conflict (only useful if a join was done and stderr has info...)
- ;; U: The file is copied from the repository.
- ;; ?: Unknown file or directory.
-
- ((looking-at
- "^\\([MARCUP?]\\) \\(.*\\)$")
- (let*
- ((c (char-after (match-beginning 1)))
- (full-path (concat (file-name-as-directory root-dir)
- (buffer-substring (match-beginning 2)
- (match-end 2))))
- (isdir (file-directory-p full-path))
- (fileinfo (cvs-create-fileinfo
- (cond ((eq c ?M) 'MODIFIED)
- ((eq c ?A) 'ADDED)
- ((eq c ?R) 'REMOVED)
- ((eq c ?C) 'CONFLICT)
- ((eq c ?U) 'UPDATED)
- ((eq c ?P) 'PATCHED)
- ((eq c ??) (if isdir
- 'UNKNOWN-DIR
- 'UNKNOWN)))
- (substring (file-name-directory full-path) 0 -1)
- (file-name-nondirectory full-path)
- (buffer-substring (match-beginning 0) (match-end 0)))))
- ;; Updated and Patched files require no further action.
- (if (memq c '(?U ?P))
- (cvs-set-fileinfo->handled fileinfo t))
-
- ;; Link this last on the list.
- (setcdr head (list fileinfo))
- (setq head (cdr head))
- (forward-line 1)))
-
- ;; Executing a program because of the -u option in modules.
- ((looking-at
- "^cvs \\(update\\|server\\): Executing")
- ;; Skip by any output the program may generate to stdout.
- ;; Note that pcl-cvs will get seriously confused if the
- ;; program prints anything to stderr.
- (re-search-forward cvs-update-prog-output-skip-regexp)
- (forward-line 1))
-
- (t
- (cvs-parse-error stdout-buffer stderr-buffer 'STDOUT (point)
- "cvs-parse-stdout"))))))
-
-;;----------
-(defun cvs-pp (fileinfo)
- "Pretty print FILEINFO. Insert a printed representation in current buffer.
-For use by the cookie package."
-
- (let ((a (cvs-fileinfo->type fileinfo))
- (s (if (cvs-fileinfo->marked fileinfo)
- "*" " "))
- (f (cvs-fileinfo->file-name fileinfo))
- (ci (if (cvs-fileinfo->handled fileinfo)
- " " "ci")))
- (insert
- (cond
- ((eq a 'UPDATED)
- (format "%s Updated %s" s f))
- ((eq a 'PATCHED)
- (format "%s Patched %s" s f))
- ((eq a 'MODIFIED)
- (format "%s Modified %s %s" s ci f))
- ((eq a 'MERGED)
- (format "%s Merged %s %s" s ci f))
- ((eq a 'CONFLICT)
- (format "%s Conflict %s" s f))
- ((eq a 'ADDED)
- (format "%s Added %s %s" s ci f))
- ((eq a 'REMOVED)
- (format "%s Removed %s %s" s ci f))
- ((eq a 'UNKNOWN)
- (format "%s Unknown %s" s f))
- ((eq a 'UNKNOWN-DIR)
- (format "%s Unknown dir %s" s f))
- ((eq a 'CVS-REMOVED)
- (format "%s Removed from repository: %s" s f))
- ((eq a 'REM-CONFLICT)
- (format "%s Conflict: Removed from repository, changed by you: %s" s f))
- ((eq a 'MOD-CONFLICT)
- (format "%s Conflict: Removed by you, changed in repository: %s" s f))
- ((eq a 'REM-EXIST)
- (format "%s Conflict: Removed by you, but still exists: %s" s f))
- ((eq a 'DIRCHANGE)
- (format "\nIn directory %s:" (cvs-fileinfo->dir fileinfo)))
- ((eq a 'MOVE-AWAY)
- (format "%s Move away %s - it is in the way" s f))
- ((eq a 'REPOS-MISSING)
- (format " This repository directory is missing! Remove this directory manually."))
- ((eq a 'MESSAGE)
- (cvs-fileinfo->full-log fileinfo))
- (t
- (format "%s Internal error! %s" s f))))))
-
-
-;;; You can define your own keymap in .emacs. pcl-cvs.el won't overwrite it.
-
-(if cvs-mode-map
- nil
- (setq cvs-mode-map (make-keymap))
- (suppress-keymap cvs-mode-map)
- (define-prefix-command 'cvs-mode-map-control-c-prefix)
- (define-key cvs-mode-map "\C-?" 'cvs-mode-unmark-up)
- (define-key cvs-mode-map "\C-k" 'cvs-mode-acknowledge)
- (define-key cvs-mode-map "\C-n" 'cvs-mode-next-line)
- (define-key cvs-mode-map "\C-p" 'cvs-mode-previous-line)
- ;; ^C- keys are used to set various flags to control CVS features
- (define-key cvs-mode-map "\C-c" 'cvs-mode-map-control-c-prefix)
- (define-key cvs-mode-map "\C-c\C-c" 'cvs-change-cvsroot)
- (define-key cvs-mode-map "\C-c\C-d" 'cvs-set-diff-flags)
- (define-key cvs-mode-map "\C-c\C-l" 'cvs-set-log-flags)
- (define-key cvs-mode-map "\C-c\C-s" 'cvs-set-status-flags)
- (define-key cvs-mode-map "\C-c\C-u" 'cvs-set-update-optional-flags)
- ;; M- keys are usually those that operate on modules
- (define-key cvs-mode-map "\M-\C-?" 'cvs-mode-unmark-all-files)
- (define-key cvs-mode-map "\M-C" 'cvs-mode-rcs2log) ; i.e. "Create a ChangeLog"
- (define-key cvs-mode-map "\M-a" 'cvs-mode-admin)
- (define-key cvs-mode-map "\M-c" 'cvs-mode-checkout)
- (define-key cvs-mode-map "\M-o" 'cvs-mode-checkout-other-window)
- (define-key cvs-mode-map "\M-p" 'cvs-mode-rdiff) ; i.e. "create a Patch"
- (define-key cvs-mode-map "\M-r" 'cvs-mode-release)
- (define-key cvs-mode-map "\M-t" 'cvs-mode-rtag)
- ;; keys that operate on files
- (define-key cvs-mode-map " " 'cvs-mode-next-line)
- (define-key cvs-mode-map "?" 'describe-mode)
- (define-key cvs-mode-map "A" 'cvs-mode-add-change-log-entry-other-window)
- (define-key cvs-mode-map "B" 'cvs-mode-byte-compile-files)
- (define-key cvs-mode-map "C" 'cvs-mode-changelog-commit)
- (define-key cvs-mode-map "E" 'cvs-mode-emerge)
- (define-key cvs-mode-map "G" 'cvs-update)
- (define-key cvs-mode-map "M" 'cvs-mode-mark-all-files)
- (define-key cvs-mode-map "Q" 'cvs-examine)
- (define-key cvs-mode-map "R" 'cvs-mode-revert-updated-buffers)
- (define-key cvs-mode-map "U" 'cvs-mode-undo-local-changes)
- (define-key cvs-mode-map "a" 'cvs-mode-add)
- (define-key cvs-mode-map "b" 'cvs-mode-diff-backup)
- (define-key cvs-mode-map "c" 'cvs-mode-commit)
- (define-key cvs-mode-map "d" 'cvs-mode-diff-cvs)
- (define-key cvs-mode-map "e" 'cvs-mode-ediff)
- (define-key cvs-mode-map "f" 'cvs-mode-find-file)
- (define-key cvs-mode-map "g" 'cvs-mode-update-no-prompt)
- (define-key cvs-mode-map "i" 'cvs-mode-ignore)
- (define-key cvs-mode-map "l" 'cvs-mode-log)
- (define-key cvs-mode-map "m" 'cvs-mode-mark)
- (define-key cvs-mode-map "n" 'cvs-mode-next-line)
- (define-key cvs-mode-map "o" 'cvs-mode-find-file-other-window)
- (define-key cvs-mode-map "p" 'cvs-mode-previous-line)
- (define-key cvs-mode-map "q" 'bury-buffer)
- (define-key cvs-mode-map "r" 'cvs-mode-remove-file)
- (define-key cvs-mode-map "s" 'cvs-mode-status)
- (define-key cvs-mode-map "t" 'cvs-mode-tag)
- (define-key cvs-mode-map "u" 'cvs-mode-unmark)
- (define-key cvs-mode-map "v" 'cvs-mode-diff-vendor)
- (define-key cvs-mode-map "x" 'cvs-mode-remove-handled))
-
-;;----------
-(defun cvs-get-marked (&optional ignore-marks ignore-contents)
- "Return a list of all selected tins.
-Args: &optional IGNORE-MARKS IGNORE-CONTENTS.
-
-If there are any marked tins, and IGNORE-MARKS is nil, return them. Otherwise,
-if the cursor selects a directory, return all files in it, unless there are
-none, in which case just return the directory; or unless IGNORE-CONTENTS is not
-nil, in which case also just return the directory. Otherwise return (a list
-containing) the file the cursor points to, or an empty list if it doesn't point
-to a file at all."
-
- (cond
- ;; Any marked cookies?
- ((and (not ignore-marks)
- (collection-collect-tin cvs-cookie-handle 'cvs-fileinfo->marked)))
- ;; Nope.
- ((and (not ignore-contents)
- (let ((sel (tin-locate cvs-cookie-handle (point))))
- (cond
- ;; If a directory is selected, all it members are returned.
- ((and sel (eq (cvs-fileinfo->type (tin-cookie cvs-cookie-handle
- sel))
- 'DIRCHANGE))
- (let ((retsel
- (collection-collect-tin cvs-cookie-handle
- 'cvs-dir-member-p
- (cvs-fileinfo->dir (tin-cookie
- cvs-cookie-handle sel)))))
- (if retsel
- retsel
- (list sel))))
- (t
- (list sel))))))
- (t
- (list (tin-locate cvs-cookie-handle (point))))))
-
-;;----------
-(defun cvs-dir-member-p (fileinfo dir)
- "Return true if FILEINFO represents a file in directory DIR."
-
- (and (not (eq (cvs-fileinfo->type fileinfo) 'DIRCHANGE))
- (string= (cvs-fileinfo->dir fileinfo) dir)))
-
-;;----------
-(defun cvs-dir-empty-p (tin)
- "Return non-nil if TIN is a directory that is empty.
-Args: CVS-BUF TIN."
-
- (and (eq (cvs-fileinfo->type (tin-cookie cvs-cookie-handle tin)) 'DIRCHANGE)
- (or (not (tin-next cvs-cookie-handle tin))
- (eq (cvs-fileinfo->type
- (tin-cookie cvs-cookie-handle
- (tin-next cvs-cookie-handle tin)))
- 'DIRCHANGE))))
-
-;;----------
-(defun cvs-mode-revert-updated-buffers ()
- "Revert any buffers that are UPDATED, PATCHED, MERGED or CONFLICT."
-
- (interactive)
- (cookie-map (function cvs-revert-fileinfo) cvs-cookie-handle))
-
-;;----------
-(defun cvs-revert-fileinfo (fileinfo)
- "Revert the buffer that holds the file in FILEINFO if it has changed,
-and if the type is UPDATED, PATCHED, MERGED or CONFLICT."
-
- (let* ((type (cvs-fileinfo->type fileinfo))
- (file (cvs-fileinfo->full-path fileinfo))
- (buffer (get-file-buffer file)))
- ;; For a revert to happen...
- (cond
- ((and
- ;; ...the type must be one that justifies a revert...
- (or (eq type 'UPDATED)
- (eq type 'PATCHED)
- (eq type 'MERGED)
- (eq type 'CONFLICT))
- ;; ...and the user must be editing the file...
- buffer)
- (save-excursion
- (set-buffer buffer)
- (cond
- ((buffer-modified-p)
- (error "%s: edited since last cvs-update."
- (buffer-file-name)))
- ;; Go ahead and revert the file.
- (t (revert-buffer 'dont-use-auto-save-file 'dont-ask))))))))
-
-;;----------
-(defun cvs-mode-remove-handled ()
- "Remove all lines that are handled.
-Empty directories are removed."
-
- (interactive)
- ;; Pass one: remove files that are handled.
- (collection-filter-cookies cvs-cookie-handle
- (function
- (lambda (fileinfo)
- (not (cvs-fileinfo->handled fileinfo)))))
- ;; Pass two: remove empty directories.
- (if cvs-auto-remove-handled-directories
- (cvs-remove-empty-directories)))
-
-;;----------
-(defun cvs-remove-empty-directories ()
- "Remove empty directories in the *cvs* buffer."
-
- (collection-filter-tins cvs-cookie-handle
- (function
- (lambda (tin)
- (not (cvs-dir-empty-p tin))))))
-
-;;----------
-(defun cvs-mode-mark (pos)
- "Mark a fileinfo.
-Args: POS.
-
-If the fileinfo is a directory, all the contents of that directory are marked
-instead. A directory can never be marked. POS is a buffer position."
-
- (interactive "d")
- (let* ((tin (tin-locate cvs-cookie-handle pos))
- (sel (tin-cookie cvs-cookie-handle tin)))
- (cond
- ;; Does POS point to a directory? If so, mark all files in that directory.
- ((eq (cvs-fileinfo->type sel) 'DIRCHANGE)
- (cookie-map
- (function (lambda (f dir)
- (cond
- ((cvs-dir-member-p f dir)
- (cvs-set-fileinfo->marked f t)
- t)))) ; Tell cookie to redisplay this cookie.
- cvs-cookie-handle
- (cvs-fileinfo->dir sel)))
- (t
- (cvs-set-fileinfo->marked sel t)
- (tin-invalidate cvs-cookie-handle tin)
- (tin-goto-next cvs-cookie-handle pos 1)))))
-
-;;----------
-(defun cvs-committable (tin)
- "Check if the TIN is committable.
-It is committable if it
- a) is not handled and
- b) is either MODIFIED, ADDED, REMOVED, MERGED or CONFLICT."
-
- (let* ((fileinfo (tin-cookie cvs-cookie-handle tin))
- (type (cvs-fileinfo->type fileinfo)))
- (and (not (cvs-fileinfo->handled fileinfo))
- (or (eq type 'MODIFIED)
- (eq type 'ADDED)
- (eq type 'REMOVED)
- (eq type 'MERGED)
- (eq type 'CONFLICT)))))
-
-;;----------
-(defun cvs-mode-commit ()
- "Check in all marked files, or the current file.
-The user will be asked for a log message in a buffer.
-If cvs-erase-input-buffer is non-nil that buffer will be erased.
-Otherwise mark and point will be set around the entire contents of the
-buffer so that it is easy to kill the contents of the buffer with \\[kill-region]."
-
- (interactive)
- (let* ((cvs-buf (current-buffer))
- (marked (cvs-filter (function cvs-committable)
- (cvs-get-marked))))
- (if (null marked)
- (error "Nothing to commit!")
- (pop-to-buffer (get-buffer-create cvs-commit-prompt-buffer))
- (goto-char (point-min))
-
- (if cvs-erase-input-buffer
- (erase-buffer)
- (push-mark (point-max)))
- (cvs-edit-mode)
- (make-local-variable 'cvs-commit-list)
- (setq cvs-commit-list marked)
- (message "Press C-c C-c when you are done editing."))))
-
-;;----------
-(defun cvs-edit-done ()
- "Commit the files to the repository."
-
- (interactive)
- (if (null cvs-commit-list)
- (error "You have already committed the files"))
- (if (and (> (point-max) 1)
- (/= (char-after (1- (point-max))) ?\n)
- (or (eq cvs-commit-buffer-require-final-newline t)
- (and cvs-commit-buffer-require-final-newline
- (yes-or-no-p
- (format "Buffer %s does not end in newline. Add one? "
- (buffer-name))))))
- (save-excursion
- (goto-char (point-max))
- (insert ?\n)))
- (save-some-buffers)
- (let ((cc-list cvs-commit-list)
- (cc-buffer (get-buffer cvs-buffer-name))
- (msg-buffer (current-buffer))
- (msg (buffer-substring (point-min) (point-max))))
- (pop-to-buffer cc-buffer)
- (bury-buffer msg-buffer)
- (cvs-use-temp-buffer)
- (message "Committing...")
- (if (cvs-execute-list cc-list cvs-program
- (if cvs-cvsroot
- (list "-d" cvs-cvsroot "commit" "-m" msg)
- (list "commit" "-m" msg))
- "Committing %s...")
- (error "Something went wrong. Check the %s buffer carefully."
- cvs-temp-buffer-name))
- ;; FIXME: don't do any of this if the commit fails.
- (let ((ccl cc-list))
- (while ccl
- (cvs-after-commit-function (tin-cookie cvs-cookie-handle (car ccl)))
- (setq ccl (cdr ccl))))
- (apply 'tin-invalidate cvs-cookie-handle cc-list)
- (set-buffer msg-buffer)
- (setq cvs-commit-list nil)
- (set-buffer cc-buffer)
- (if cvs-auto-remove-handled
- (cvs-mode-remove-handled)))
-
- (message "Committing... Done."))
-
-;;----------
-(defun cvs-after-commit-function (fileinfo)
- "Do everything that needs to be done when FILEINFO has been committed.
-The fileinfo->handle is set, and if the buffer is present it is reverted."
-
- (cvs-set-fileinfo->handled fileinfo t)
- (if cvs-auto-revert-after-commit
- (let* ((file (cvs-fileinfo->full-path fileinfo))
- (buffer (get-file-buffer file)))
- ;; For a revert to happen...
- (if buffer
- ;; ...the user must be editing the file...
- (save-excursion
- (set-buffer buffer)
- (if (not (buffer-modified-p))
- ;; ...but it must be unmodified.
- (revert-buffer 'dont-use-auto-save-file 'dont-ask)))))))
-
-;;----------
-(defun cvs-execute-list (tin-list program constant-args &optional message-fmt)
- "Run PROGRAM on all elements on TIN-LIST.
-Args: TIN-LIST PROGRAM CONSTANT-ARGS.
-
-The PROGRAM will be called with pwd set to the directory the files reside
-in. CONSTANT-ARGS should be a list of strings. The arguments given to the
-program will be CONSTANT-ARGS followed by all the files (from TIN-LIST) that
-resides in that directory. If the files in TIN-LIST resides in different
-directories the PROGRAM will be run once for each directory (if all files in
-the same directory appears after each other).
-
-Any output from PROGRAM will be inserted in the current buffer.
-
-This function return nil if all went well, or the numerical exit status or a
-signal name as a string. Note that PROGRAM might be called several times. This
-will return non-nil if something goes wrong, but there is no way to know which
-process that failed.
-
-If MESSAGE-FMT is not nil, then message is called to display progress with
-MESSAGE-FMT as the string. MESSAGE-FMT should contain one %s for the arg-list
-being passed to PROGRAM."
-
- ;; FIXME: something seems wrong with the error checking here....
-
- (let ((exitstatus nil))
- (while tin-list
- (let ((current-dir (cvs-fileinfo->dir (tin-cookie cvs-cookie-handle
- (car tin-list))))
- arg-list
- arg-str)
-
- ;; Collect all marked files in this directory.
-
- (while (and tin-list
- (string= current-dir
- (cvs-fileinfo->dir (tin-cookie cvs-cookie-handle
- (car tin-list)))))
- (setq arg-list
- (cons (cvs-fileinfo->file-name
- (tin-cookie cvs-cookie-handle (car tin-list)))
- arg-list))
- (setq tin-list (cdr tin-list)))
-
- (setq arg-list (nreverse arg-list))
-
- ;; Execute the command on all the files that were collected.
-
- (if message-fmt
- (message message-fmt
- (mapconcat 'cvs-quote-multiword-string
- arg-list
- " ")))
- (setq default-directory (file-name-as-directory current-dir))
- (insert (format "=== cd %s\n" default-directory))
- (insert (format "=== %s %s\n\n"
- program
- (mapconcat 'cvs-quote-multiword-string
- (nconc (copy-sequence constant-args)
- arg-list)
- " ")))
- (let ((res (apply 'call-process program nil t t
- (nconc (copy-sequence constant-args) arg-list))))
- ;; Remember the first, or highest, exitstatus.
- (if (and (not (and (integerp res) (zerop res)))
- (or (null exitstatus)
- (and (integerp exitstatus) (= 1 exitstatus))))
- (setq exitstatus res)))
- (goto-char (point-max))
- (if message-fmt
- (message message-fmt
- (mapconcat 'cvs-quote-multiword-string
- (nconc (copy-sequence arg-list) '("Done."))
- " ")))
- exitstatus))))
-
-;;----------
-;;;; +++ not currently used!
-(defun cvs-execute-single-file-list (tin-list extractor program constant-args
- &optional cleanup message-fmt)
- "Run PROGRAM on all elements on TIN-LIST.
-Args: TIN-LIST EXTRACTOR PROGRAM CONSTANT-ARGS &optional CLEANUP.
-
-The PROGRAM will be called with pwd set to the directory the files
-reside in. CONSTANT-ARGS is a list of strings to pass as arguments to
-PROGRAM. The arguments given to the program will be CONSTANT-ARGS
-followed by the list that EXTRACTOR returns.
-
-EXTRACTOR will be called once for each file on TIN-LIST. It is given
-one argument, the cvs-fileinfo. It can return t, which means ignore
-this file, or a list of arguments to send to the program.
-
-If CLEANUP is not nil, the filenames returned by EXTRACTOR are deleted.
-
-If MESSAGE-FMT is not nil, then message is called to display progress with
-MESSAGE-FMT as the string. MESSAGE-FMT should contain one %s for the arg-list
-being passed to PROGRAM."
-
- (while tin-list
- (let ((current-dir (file-name-as-directory
- (cvs-fileinfo->dir
- (tin-cookie cvs-cookie-handle
- (car tin-list)))))
- (arg-list
- (funcall extractor
- (tin-cookie cvs-cookie-handle (car tin-list)))))
-
- ;; Execute the command unless extractor returned t.
-
- (if (eq arg-list t)
- nil
- (setq default-directory current-dir)
- (insert (format "=== cd %s\n" default-directory))
- (insert (format "=== %s %s\n\n"
- program
- (mapconcat 'cvs-quote-multiword-string
- (nconc (copy-sequence constant-args)
- arg-list)
- " ")))
- (if message-fmt
- (message message-fmt (mapconcat 'cvs-quote-multiword-string
- arg-list
- " ")))
- (apply 'call-process program nil t t
- (nconc (copy-sequence constant-args) arg-list))
- (goto-char (point-max))
- (if message-fmt
- (message message-fmt (mapconcat 'cvs-quote-multiword-string
- (nconc arg-list '("Done."))
- " ")))
- (if cleanup
- (while arg-list
-;;;; (kill-buffer ?????)
- (delete-file (car arg-list))
- (setq arg-list (cdr arg-list))))))
- (setq tin-list (cdr tin-list))))
-
-;;----------
-(defun cvs-edit-mode ()
- "\\<cvs-edit-mode-map>Mode for editing cvs log messages.
-Commands:
-\\[cvs-edit-done] checks in the file when you are ready.
-This mode is based on fundamental mode."
-
- (interactive)
- (use-local-map cvs-edit-mode-map)
- (setq major-mode 'cvs-edit-mode)
- (setq mode-name "CVS Log")
- (auto-fill-mode 1))
-
-;;----------
-(if cvs-edit-mode-map
- nil
- (setq cvs-edit-mode-map (make-sparse-keymap))
- (define-prefix-command 'cvs-edit-mode-control-c-prefix)
- (define-key cvs-edit-mode-map "\C-c" 'cvs-edit-mode-control-c-prefix)
- (define-key cvs-edit-mode-map "\C-c\C-c" 'cvs-edit-done))
-
-;;----------
-(defun cvs-diffable (tins)
- "Return a list of all tins on TINS that it makes sense to run
-``cvs diff'' on."
-
- ;; +++ There is an unnecessary (nreverse) here. Get the list the
- ;; other way around instead!
- (let ((result nil))
- (while tins
- (let ((type (cvs-fileinfo->type
- (tin-cookie cvs-cookie-handle (car tins)))))
- (if (or (eq type 'MODIFIED)
- (eq type 'UPDATED)
- (eq type 'PATCHED)
- (eq type 'MERGED)
- (eq type 'CONFLICT)
- (eq type 'REMOVED) ;+++Does this line make sense?
- (eq type 'ADDED)) ;+++Does this line make sense?
- (setq result (cons (car tins) result)))
- (setq tins (cdr tins))))
- (nreverse result)))
-
-;;----------
-(defun cvs-mode-diff-cvs (&optional ignore-marks)
- "Diff the selected files against the head revisions in the repository.
-
-If the variable cvs-diff-ignore-marks is non-nil any marked files will not be
-considered to be selected. An optional prefix argument will invert the
-influence from cvs-diff-ignore-marks.
-
-The flags in the variable cvs-diff-flags will be passed to ``cvs diff''.
-
-The resulting diffs are placed in the cvs-fileinfo->cvs-diff-buffer."
-
- (interactive "P")
- (if (not (listp cvs-diff-flags))
- (error "cvs-diff-flags should be set using cvs-set-diff-flags."))
- (save-some-buffers)
- (message "cvsdiffing...")
- (let ((marked-file-list (cvs-diffable
- (cvs-get-marked
- (or (and ignore-marks (not cvs-diff-ignore-marks))
- (and (not ignore-marks) cvs-diff-ignore-marks))))))
- (while marked-file-list
- (let ((fileinfo-to-diff (tin-cookie cvs-cookie-handle
- (car marked-file-list)))
- (local-def-directory (file-name-as-directory
- (cvs-fileinfo->dir
- (tin-cookie cvs-cookie-handle
- (car marked-file-list))))))
- (message "cvsdiffing %s..."
- (cvs-fileinfo->file-name fileinfo-to-diff))
-
- ;; FIXME: this seems messy to test and set buffer name at this point....
- (if (not (cvs-fileinfo->cvs-diff-buffer fileinfo-to-diff))
- (cvs-set-fileinfo->cvs-diff-buffer fileinfo-to-diff
- (concat "*cvs-diff-"
- (cvs-fileinfo->file-name
- fileinfo-to-diff)
- "-in-"
- local-def-directory
- "*")))
- (display-buffer (get-buffer-create
- (cvs-fileinfo->cvs-diff-buffer fileinfo-to-diff)))
- (set-buffer (cvs-fileinfo->cvs-diff-buffer fileinfo-to-diff))
- (setq buffer-read-only nil)
- (setq default-directory local-def-directory)
- (erase-buffer)
- (insert (format "=== cd %s\n" default-directory))
- (insert (format "=== cvs %s\n\n"
- (mapconcat 'cvs-quote-multiword-string
- (nconc (if cvs-cvsroot
- (list "-d" cvs-cvsroot "diff")
- '("diff"))
- (copy-sequence cvs-diff-flags)
- (list (cvs-fileinfo->file-name
- fileinfo-to-diff)))
- " ")))
- (if (apply 'call-process cvs-program nil t t
- (nconc (if cvs-cvsroot
- (list "-d" cvs-cvsroot "diff")
- '("diff"))
- (copy-sequence cvs-diff-flags)
- (list (cvs-fileinfo->file-name fileinfo-to-diff))))
- (message "cvsdiffing %s... Done."
- (cvs-fileinfo->file-name fileinfo-to-diff))
- (message "cvsdiffing %s... No differences found."
- (cvs-fileinfo->file-name fileinfo-to-diff)))
- (goto-char (point-max))
- (setq marked-file-list (cdr marked-file-list)))))
- (message "cvsdiffing... Done."))
-
-;;----------
-(defun cvs-mode-diff-backup (&optional ignore-marks)
- "Diff the files against the backup file.
-This command can be used on files that are marked with \"Merged\"
-or \"Conflict\" in the *cvs* buffer.
-
-If the variable cvs-diff-ignore-marks is non-nil any marked files will
-not be considered to be selected. An optional prefix argument will
-invert the influence from cvs-diff-ignore-marks.
-
-The flags in cvs-diff-flags will be passed to ``diff''.
-
-The resulting diffs are placed in the cvs-fileinfo->backup-diff-buffer."
-
- (interactive "P")
- (if (not (listp cvs-diff-flags))
- (error "cvs-diff-flags should be set using cvs-set-diff-flags."))
- (save-some-buffers)
- (let ((marked-file-list (cvs-filter
- (function cvs-backup-diffable)
- (cvs-get-marked
- (or
- (and ignore-marks (not cvs-diff-ignore-marks))
- (and (not ignore-marks) cvs-diff-ignore-marks))))))
- (if (null marked-file-list)
- (error "No ``Conflict'' or ``Merged'' file selected!"))
- (message "backup diff...")
- (while marked-file-list
- (let ((fileinfo-to-diff (tin-cookie cvs-cookie-handle
- (car marked-file-list)))
- (local-def-directory (file-name-as-directory
- (cvs-fileinfo->dir
- (tin-cookie cvs-cookie-handle
- (car marked-file-list)))))
- (backup-temp-files (cvs-diff-backup-extractor
- (tin-cookie cvs-cookie-handle
- (car marked-file-list)))))
- (message "backup diff %s..."
- (cvs-fileinfo->file-name fileinfo-to-diff))
-
- ;; FIXME: this seems messy to test and set buffer name at this point....
- (if (not (cvs-fileinfo->backup-diff-buffer fileinfo-to-diff))
- (cvs-set-fileinfo->backup-diff-buffer fileinfo-to-diff
- (concat "*cvs-diff-"
- (cvs-fileinfo->backup-file
- fileinfo-to-diff)
- "-to-"
- (cvs-fileinfo->file-name
- fileinfo-to-diff)
- "-in"
- local-def-directory
- "*")))
- (display-buffer (get-buffer-create
- (cvs-fileinfo->backup-diff-buffer fileinfo-to-diff)))
- (set-buffer (cvs-fileinfo->backup-diff-buffer fileinfo-to-diff))
- (setq buffer-read-only nil)
- (setq default-directory local-def-directory)
- (erase-buffer)
- (insert (format "=== cd %s\n" default-directory))
- (insert (format "=== %s %s\n\n"
- cvs-diff-program
- (mapconcat 'cvs-quote-multiword-string
- (nconc (copy-sequence cvs-diff-flags)
- backup-temp-files)
- " ")))
- (apply 'call-process cvs-diff-program nil t t
- (nconc (copy-sequence cvs-diff-flags) backup-temp-files))
- (goto-char (point-max))
- (message "backup diff %s... Done."
- (cvs-fileinfo->file-name fileinfo-to-diff))
- (setq marked-file-list (cdr marked-file-list)))))
- (message "backup diff... Done."))
-
-;;----------
-(defun cvs-mode-diff-vendor (&optional ignore-marks)
- "Diff the revisions merged into the current file. I.e. show what changes
-were merged in.
-
-This command can be used on files that are marked with \"Merged\"
-or \"Conflict\" in the *cvs* buffer.
-
-If the variable cvs-diff-ignore-marks is non-nil any marked files will
-not be considered to be selected. An optional prefix argument will
-invert the influence from cvs-diff-ignore-marks.
-
-The flags in cvs-diff-flags will be passed to ``diff''.
-
-The resulting diffs are placed in the cvs-fileinfo->vendor-diff-buffer."
-
- (interactive "P")
- (if (not (listp cvs-diff-flags))
- (error "cvs-diff-flags should be set using cvs-set-diff-flags."))
- (save-some-buffers)
- (let ((marked-file-list (cvs-filter
- (function cvs-vendor-diffable)
- (cvs-get-marked
- (or
- (and ignore-marks (not cvs-diff-ignore-marks))
- (and (not ignore-marks) cvs-diff-ignore-marks))))))
- (if (null marked-file-list)
- (error "No ``Conflict'' or ``Merged'' file selected!"))
- (message "vendor diff...")
- (while marked-file-list
- (let ((fileinfo-to-diff (tin-cookie cvs-cookie-handle
- (car marked-file-list)))
- (local-def-directory (file-name-as-directory
- (cvs-fileinfo->dir
- (tin-cookie cvs-cookie-handle
- (car marked-file-list)))))
- (vendor-temp-files (cvs-diff-vendor-extractor
- (tin-cookie cvs-cookie-handle
- (car marked-file-list)))))
- (message "vendor diff %s..."
- (cvs-fileinfo->file-name fileinfo-to-diff))
- (if (not (cvs-fileinfo->vendor-diff-buffer fileinfo-to-diff))
- (cvs-set-fileinfo->vendor-diff-buffer fileinfo-to-diff
- (concat "*cvs-diff-"
- (cvs-fileinfo->file-name
- fileinfo-to-diff)
- "-of-"
- (cvs-fileinfo->base-revision
- fileinfo-to-diff)
- "-to-"
- (cvs-fileinfo->head-revision
- fileinfo-to-diff)
- "-in-"
- local-def-directory
- "*")))
- (display-buffer (get-buffer-create
- (cvs-fileinfo->vendor-diff-buffer fileinfo-to-diff)))
- (set-buffer (cvs-fileinfo->vendor-diff-buffer fileinfo-to-diff))
- (setq buffer-read-only nil)
- (setq default-directory local-def-directory)
- (erase-buffer)
- (insert (format "=== cd %s\n" default-directory))
- (insert (format "=== %s %s\n\n"
- cvs-diff-program
- (mapconcat 'cvs-quote-multiword-string
- (nconc (copy-sequence cvs-diff-flags)
- vendor-temp-files)
- " ")))
- (apply 'call-process cvs-diff-program nil t t
- (nconc (copy-sequence cvs-diff-flags) vendor-temp-files))
- (goto-char (point-max))
- (message "vendor diff %s... Done."
- (cvs-fileinfo->file-name fileinfo-to-diff))
- (while vendor-temp-files
- (cvs-kill-buffer-visiting (car vendor-temp-files))
- (delete-file (car vendor-temp-files))
- (setq vendor-temp-files (cdr vendor-temp-files)))
- (setq marked-file-list (cdr marked-file-list)))))
- (message "vendor diff... Done."))
-
-;;----------
-(defun cvs-backup-diffable (tin)
- "Check if the TIN is backup-diffable.
-It must have a backup file to be diffable."
-
- (file-readable-p
- (cvs-fileinfo->backup-file (tin-cookie cvs-cookie-handle tin))))
-
-;;----------
-(defun cvs-vendor-diffable (tin)
- "Check if the TIN is vendor-diffable.
-It must have head and base revision info to be diffable."
-
- (and
- (cvs-fileinfo->base-revision (tin-cookie cvs-cookie-handle tin))
- (cvs-fileinfo->head-revision (tin-cookie cvs-cookie-handle tin))))
-
-;;----------
-(defun cvs-diff-backup-extractor (fileinfo)
- "Return the filename and the name of the backup file as a list.
-Signal an error if there is no backup file."
-
- (if (not (file-readable-p (cvs-fileinfo->backup-file fileinfo)))
- (error "%s has no backup file."
- (concat
- (file-name-as-directory (cvs-fileinfo->dir fileinfo))
- (cvs-fileinfo->file-name fileinfo))))
- (list (cvs-fileinfo->backup-file fileinfo)
- (cvs-fileinfo->file-name fileinfo)))
-
-;;----------
-(defun cvs-diff-vendor-extractor (fileinfo)
- "Retrieve and return the filenames of the vendor branch revisions as a list.
-Signal an error if there is no info for the vendor revisions."
-
- (list (cvs-retrieve-revision-to-tmpfile fileinfo
- (cvs-fileinfo->base-revision
- fileinfo))
- (cvs-retrieve-revision-to-tmpfile fileinfo
- (cvs-fileinfo->head-revision
- fileinfo))))
-
-;;----------
-(defun cvs-mode-find-file-other-window (pos)
- "Select a buffer containing the file in another window.
-Args: POS."
-
- (interactive "d")
- (let ((tin (tin-locate cvs-cookie-handle pos)))
- (if tin
- (let ((type (cvs-fileinfo->type (tin-cookie cvs-cookie-handle tin))))
- (cond
- ((or (eq type 'REMOVED)
- (eq type 'CVS-REMOVED))
- (error "Can't visit a removed file."))
- ((eq type 'DIRCHANGE)
- (let ((obuf (current-buffer))
- (odir default-directory))
- (setq default-directory
- (file-name-as-directory
- (cvs-fileinfo->dir
- (tin-cookie cvs-cookie-handle tin))))
- (dired-other-window default-directory)
- (set-buffer obuf)
- (setq default-directory odir)))
- (t
- (find-file-other-window (cvs-full-path tin)))))
- (error "There is no file to find."))))
-
-;;----------
-(defun cvs-fileinfo->full-path (fileinfo)
- "Return the full path for the file that is described in FILEINFO."
-
- (concat
- (file-name-as-directory
- (cvs-fileinfo->dir fileinfo))
- (cvs-fileinfo->file-name fileinfo)))
-
-;;----------
-(defun cvs-full-path (tin)
- "Return the full path for the file that is described in TIN."
-
- (cvs-fileinfo->full-path (tin-cookie cvs-cookie-handle tin)))
-
-;;----------
-(defun cvs-mode-find-file (pos)
- "Select a buffer containing the file in another window.
-Args: POS."
-
- (interactive "d")
- (let* ((cvs-buf (current-buffer))
- (tin (tin-locate cvs-cookie-handle pos)))
- (if tin
- (let* ((fileinfo (tin-cookie cvs-cookie-handle tin))
- (type (cvs-fileinfo->type fileinfo)))
- (cond
- ((or (eq type 'REMOVED)
- (eq type 'CVS-REMOVED))
- (error "Can't visit a removed file."))
- ((eq type 'DIRCHANGE)
- (let ((odir default-directory))
- (setq default-directory
- (file-name-as-directory (cvs-fileinfo->dir fileinfo)))
- (dired default-directory)
- (set-buffer cvs-buf)
- (setq default-directory odir)))
- (t
- (find-file (cvs-full-path tin)))))
- (error "There is no file to find."))))
-
-;;----------
-(defun cvs-mode-mark-all-files ()
- "Mark all files.
-Directories are not marked."
-
- (interactive)
- (cookie-map (function (lambda (cookie)
- (cond
- ((not (eq (cvs-fileinfo->type cookie) 'DIRCHANGE))
- (cvs-set-fileinfo->marked cookie t)
- t))))
- cvs-cookie-handle))
-
-;;----------
-(defun cvs-mode-unmark (pos)
- "Unmark a fileinfo.
-Args: POS."
-
- (interactive "d")
- (let* ((tin (tin-locate cvs-cookie-handle pos))
- (sel (tin-cookie cvs-cookie-handle tin)))
- (cond
- ((eq (cvs-fileinfo->type sel) 'DIRCHANGE)
- (cookie-map
- (function (lambda (f dir)
- (cond
- ((cvs-dir-member-p f dir)
- (cvs-set-fileinfo->marked f nil)
- t))))
- cvs-cookie-handle
- (cvs-fileinfo->dir sel)))
- (t
- (cvs-set-fileinfo->marked sel nil)
- (tin-invalidate cvs-cookie-handle tin)
- (tin-goto-next cvs-cookie-handle pos 1)))))
-
-;;----------
-(defun cvs-mode-unmark-all-files ()
- "Unmark all files.
-Directories are also unmarked, but that doesn't matter, since
-they should always be unmarked."
-
- (interactive)
- (cookie-map (function (lambda (cookie)
- (cvs-set-fileinfo->marked cookie nil)
- t))
- cvs-cookie-handle))
-
-;;----------
-(defun cvs-do-removal (tins)
- "Remove files.
-Args: TINS.
-
-TINS is a list of tins that the user wants to delete. The files are deleted.
-If the type of the tin is 'UNKNOWN or 'UNKNOWN-DIR the tin is removed from the
-buffer. If it is anything else the file is added to a list that should be `cvs
-remove'd and the tin is changed to be of type 'REMOVED.
-
-Returns a list of tins files that should be `cvs remove'd."
-
- (cvs-use-temp-buffer)
- (mapcar 'cvs-insert-full-path tins)
- (cond
- ((and tins (yes-or-no-p (format "Delete %d files? " (length tins))))
- (let (files-to-remove)
- (while tins
- (let* ((tin (car tins))
- (fileinfo (tin-cookie cvs-cookie-handle tin))
- (filepath (cvs-full-path tin))
- (type (cvs-fileinfo->type fileinfo)))
- (if (or (eq type 'REMOVED)
- (eq type 'CVS-REMOVED))
- nil
- ;; if it doesn't exist, as a file or directory, ignore it
- (cond ((file-directory-p filepath)
- (call-process cvs-rmdir-program nil nil nil filepath))
- ((file-exists-p filepath)
- (delete-file filepath)))
- (if (or (eq type 'UNKNOWN)
- (eq type 'UNKNOWN-DIR)
- (eq type 'MOVE-AWAY))
- (tin-delete cvs-cookie-handle tin)
- (setq files-to-remove (cons tin files-to-remove))
- (cvs-set-fileinfo->type fileinfo 'REMOVED)
- (cvs-set-fileinfo->handled fileinfo nil)
- (tin-invalidate cvs-cookie-handle tin))))
- (setq tins (cdr tins)))
- files-to-remove))
- (t nil)))
-
-;;----------
-(defun cvs-mode-remove-file ()
- "Remove all marked files."
-
- (interactive)
- (let ((files-to-remove (cvs-do-removal (cvs-get-marked))))
- (if (null files-to-remove)
- nil
- (cvs-use-temp-buffer)
- (message "removing from repository...")
- (if (cvs-execute-list files-to-remove cvs-program
- (if cvs-cvsroot
- (list "-d" cvs-cvsroot "remove")
- '("remove"))
- "removing %s from repository...")
- (error "CVS exited with non-zero exit status.")
- (message "removing from repository... Done.")))))
-
-;;----------
-(defun cvs-mode-undo-local-changes ()
- "Undo local changes to all marked files.
-The file is removed and `cvs update FILE' is run."
-
- (interactive)
- (let ((tins-to-undo (cvs-get-marked)))
- (cvs-use-temp-buffer)
- (mapcar 'cvs-insert-full-path tins-to-undo)
- (cond
- ((and tins-to-undo (yes-or-no-p (format "Undo changes to %d files? "
- (length tins-to-undo))))
- (let (files-to-update)
- (while tins-to-undo
- (let* ((tin (car tins-to-undo))
- (fileinfo (tin-cookie cvs-cookie-handle tin))
- (type (cvs-fileinfo->type fileinfo)))
- (cond
- ((or
- (eq type 'UPDATED)
- (eq type 'PATCHED)
- (eq type 'MODIFIED)
- (eq type 'MERGED)
- (eq type 'CONFLICT)
- (eq type 'CVS-REMOVED)
- (eq type 'REM-CONFLICT)
- (eq type 'MOVE-AWAY)
- (eq type 'REMOVED))
- (if (not (eq type 'REMOVED))
- (delete-file (cvs-full-path tin)))
- (setq files-to-update (cons tin files-to-update))
- (cvs-set-fileinfo->type fileinfo 'UPDATED)
- (cvs-set-fileinfo->handled fileinfo t)
- (tin-invalidate cvs-cookie-handle tin))
-
- ((eq type 'MOD-CONFLICT)
- (error "Use cvs-mode-add instead on %s."
- (cvs-fileinfo->file-name fileinfo)))
-
- ((eq type 'REM-CONFLICT)
- (error "Can't deal with a file you have removed and recreated."))
-
- ((eq type 'DIRCHANGE)
- (error "Undo on directories not supported (yet)."))
-
- ((eq type 'ADDED)
- (error "There is no old revision to get for %s"
- (cvs-fileinfo->file-name fileinfo)))
- (t (error "cvs-mode-undo-local-changes: can't handle an %s"
- type)))
-
- (setq tins-to-undo (cdr tins-to-undo))))
- (cvs-use-temp-buffer)
- (message "Re-getting files from repository...")
- (if (cvs-execute-list files-to-update cvs-program
- (if cvs-cvsroot
- (list "-d" cvs-cvsroot "update")
- '("update"))
- "Re-getting %s from repository...")
- (error "CVS exited with non-zero exit status.")
- (message "Re-getting files from repository... Done.")))))))
-
-;;----------
-(defun cvs-mode-acknowledge ()
- "Remove all marked files from the buffer."
-
- (interactive)
- (mapcar (function (lambda (tin)
- (tin-delete cvs-cookie-handle tin)))
- (cvs-get-marked)))
-
-;;----------
-(defun cvs-mode-unmark-up (pos)
- "Unmark the file on the previous line.
-Takes one argument POS, a buffer position."
-
- (interactive "d")
- (let ((tin (tin-goto-previous cvs-cookie-handle pos 1)))
- (cond
- (tin
- (cvs-set-fileinfo->marked (tin-cookie cvs-cookie-handle tin)
- nil)
- (tin-invalidate cvs-cookie-handle tin)))))
-
-;;----------
-(defun cvs-mode-previous-line (arg)
- "Go to the previous line.
-If a prefix argument is given, move by that many lines."
-
- (interactive "p")
- (tin-goto-previous cvs-cookie-handle (point) arg))
-
-;;----------
-(defun cvs-mode-next-line (arg)
- "Go to the next line.
-If a prefix argument is given, move by that many lines."
-
- (interactive "p")
- (tin-goto-next cvs-cookie-handle (point) arg))
-
-;;----------
-(defun cvs-add-file-update-buffer (tin)
- "Sub-function to cvs-mode-add. Internal use only. Update the display. Return
-non-nil if `cvs add' should be called on this file.
-Args: TIN.
-
-Returns 'DIR, 'ADD, 'ADD-DIR, or 'RESURRECT."
-
- (let ((fileinfo (tin-cookie cvs-cookie-handle tin)))
- (cond
- ((eq (cvs-fileinfo->type fileinfo) 'UNKNOWN-DIR)
- (cvs-set-fileinfo->full-log fileinfo "new directory added with cvs-mode-add")
- 'ADD-DIR)
- ((eq (cvs-fileinfo->type fileinfo) 'UNKNOWN)
- (cvs-set-fileinfo->type fileinfo 'ADDED)
- (cvs-set-fileinfo->full-log fileinfo "new file added with cvs-mode-add")
- (tin-invalidate cvs-cookie-handle tin)
- 'ADD)
- ((eq (cvs-fileinfo->type fileinfo) 'REMOVED)
- (cvs-set-fileinfo->type fileinfo 'UPDATED)
- (cvs-set-fileinfo->full-log fileinfo "file resurrected with cvs-mode-add")
- (cvs-set-fileinfo->handled fileinfo t)
- (tin-invalidate cvs-cookie-handle tin)
- 'RESURRECT))))
-
-;;----------
-(defun cvs-add-sub (cvs-buf candidates)
- "Internal use only.
-Args: CVS-BUF CANDIDATES.
-
-CANDIDATES is a list of tins. Updates the CVS-BUF and returns a list of lists.
-The first list is unknown tins that shall be `cvs add -m msg'ed.
-The second list is unknown directory tins that shall be `cvs add -m msg'ed.
-The third list is removed files that shall be `cvs add'ed (resurrected)."
-
- (let (add add-dir resurrect)
- (while candidates
- (let ((type (cvs-add-file-update-buffer (car candidates))))
- (cond ((eq type 'ADD)
- (setq add (cons (car candidates) add)))
- ((eq type 'ADD-DIR)
- (setq add-dir (cons (car candidates) add-dir)))
- ((eq type 'RESURRECT)
- (setq resurrect (cons (car candidates) resurrect)))))
- (setq candidates (cdr candidates)))
- (list add add-dir resurrect)))
-
-;;----------
-(defun cvs-mode-add ()
- "Add marked files to the cvs repository."
-
- (interactive)
- (let* ((buf (current-buffer))
- (marked (cvs-get-marked))
- (result (cvs-add-sub buf marked))
- (added (car result))
- (newdirs (car (cdr result)))
- (resurrect (car (cdr (cdr result))))
- (msg (if (or added newdirs)
- (read-from-minibuffer "Enter description: "))))
-
- (if (or resurrect (or added newdirs))
- (cvs-use-temp-buffer))
-
- (cond (resurrect
- (message "Resurrecting files from repository...")
- (if (cvs-execute-list resurrect
- cvs-program
- (if cvs-cvsroot
- (list "-d" cvs-cvsroot "add")
- '("add"))
- "Resurrecting %s from repository...")
- (error "CVS exited with non-zero exit status.")
- (message "Resurrecting files from repository... Done."))))
-
- (cond (added
- (message "Adding new files to repository...")
- (if (cvs-execute-list added
- cvs-program
- (if cvs-cvsroot
- (list "-d" cvs-cvsroot "add" "-m" msg)
- (list "add" "-m" msg))
- "Adding %s to repository...")
- (error "CVS exited with non-zero exit status.")
- (message "Adding new files to repository... Done."))))
-
- (cond (newdirs
- (message "Adding new directories to repository...")
- (if (cvs-execute-list newdirs
- cvs-program
- (if cvs-cvsroot
- (list "-d" cvs-cvsroot "add" "-m" msg)
- (list "add" "-m" msg))
- "Adding %s to repository...")
- (error "CVS exited with non-zero exit status.")
- (while newdirs
- (let* ((tin (car newdirs))
- (fileinfo (tin-cookie cvs-cookie-handle tin))
- (newdir (cvs-fileinfo->file-name fileinfo)))
- (cvs-set-fileinfo->dir fileinfo
- (concat (cvs-fileinfo->dir fileinfo)
- "/"
- newdir))
- (cvs-set-fileinfo->type fileinfo 'DIRCHANGE)
- (cvs-set-fileinfo->file-name fileinfo ".")
- (tin-invalidate cvs-cookie-handle tin)
- (setq newdirs (cdr newdirs))))
- ;; FIXME: this should really run cvs-update-no-prompt on the
- ;; subdir and insert everthing in the current list.
- (message "You must re-update to visit the new directories."))))))
-
-;;----------
-(defun cvs-mode-ignore ()
- "Arrange so that CVS ignores the selected files and directories.
-This command ignores files/dirs that are flagged as `Unknown'."
-
- (interactive)
- (mapcar (function (lambda (tin)
- (let* ((fileinfo (tin-cookie cvs-cookie-handle tin))
- (type (cvs-fileinfo->type fileinfo)))
- (cond ((or (eq type 'UNKNOWN)
- (eq type 'UNKNOWN-DIR))
- (cvs-append-to-ignore fileinfo)
- (tin-delete cvs-cookie-handle tin))))))
- (cvs-get-marked)))
-
-;;----------
-(defun cvs-append-to-ignore (fileinfo)
- "Append the file in fileinfo to the .cvsignore file"
-
- (save-window-excursion
- (set-buffer (find-file-noselect (concat (file-name-as-directory
- (cvs-fileinfo->dir fileinfo))
- ".cvsignore")))
- (goto-char (point-max))
- (if (not (zerop (current-column)))
- (insert "\n"))
- (insert (cvs-fileinfo->file-name fileinfo) "\n")
- (if cvs-sort-ignore-file
- (sort-lines nil (point-min) (point-max)))
- (save-buffer)))
-
-;;----------
-(defun cvs-mode-status ()
- "Show cvs status for all marked files."
-
- (interactive)
- (save-some-buffers)
- (if (not (listp cvs-status-flags))
- (error "cvs-status-flags should be set using cvs-set-status-flags."))
- (let ((marked (cvs-get-marked nil t)))
- (cvs-use-temp-buffer)
- (message "Running cvs status ...")
- (if (cvs-execute-list marked
- cvs-program
- (append (if cvs-cvsroot (list "-d" cvs-cvsroot))
- (list "-Q" "status")
- cvs-status-flags)
- "Running cvs -Q status %s...")
- (error "CVS exited with non-zero exit status.")
- (message "Running cvs -Q status ... Done."))))
-
-;;----------
-(defun cvs-mode-log ()
- "Display the cvs log of all selected files."
-
- (interactive)
- (if (not (listp cvs-log-flags))
- (error "cvs-log-flags should be set using cvs-set-log-flags."))
- (let ((marked (cvs-get-marked nil t)))
- (cvs-use-temp-buffer)
- (message "Running cvs log ...")
- (if (cvs-execute-list marked
- cvs-program
- (append (if cvs-cvsroot (list "-d" cvs-cvsroot))
- (list "log")
- cvs-log-flags)
- "Running cvs log %s...")
- (error "CVS exited with non-zero exit status.")
- (message "Running cvs log ... Done."))))
-
-;;----------
-(defun cvs-mode-tag ()
- "Run 'cvs tag' on all selected files."
-
- (interactive)
- (if (not (listp cvs-tag-flags))
- (error "cvs-tag-flags should be set using cvs-set-tag-flags."))
- (let ((marked (cvs-get-marked nil t))
- (tag-args (cvs-make-list (read-string "Tag name (and flags): "))))
- (cvs-use-temp-buffer)
- (message "Running cvs tag ...")
- (if (cvs-execute-list marked
- cvs-program
- (append (if cvs-cvsroot (list "-d" cvs-cvsroot))
- (list "tag")
- cvs-tag-flags
- tag-args)
- "Running cvs tag %s...")
- (error "CVS exited with non-zero exit status.")
- (message "Running cvs tag ... Done."))))
-
-;;----------
-(defun cvs-mode-rtag ()
- "Run 'cvs rtag' on all selected files."
-
- (interactive)
- (if (not (listp cvs-rtag-flags))
- (error "cvs-rtag-flags should be set using cvs-set-rtag-flags."))
- (let ((marked (cvs-get-marked nil t))
- ;; FIXME: should give selection from the modules file
- (module-name (read-string "Module name: "))
- ;; FIXME: should also ask for an existing tag *or* date
- (rtag-args (cvs-make-list (read-string "Tag name (and flags): "))))
- (cvs-use-temp-buffer)
- (message "Running cvs rtag ...")
- (if (cvs-execute-list marked
- cvs-program
- (append (if cvs-cvsroot (list "-d" cvs-cvsroot))
- (list "rtag")
- cvs-rtag-flags
- rtag-args
- (list module-name))
- "Running cvs rtag %s...")
- (error "CVS rtag exited with non-zero exit status.")
- (message "Running cvs rtag ... Done."))))
-
-;;----------
-(defun cvs-mode-byte-compile-files ()
- "Run byte-compile-file on all selected files that end in '.el'."
-
- (interactive)
- (let ((marked (cvs-get-marked)))
- (while marked
- (let ((filename (cvs-full-path (car marked))))
- (if (string-match "\\.el$" filename)
- (byte-compile-file filename)))
- (setq marked (cdr marked)))))
-
-;;----------
-(defun cvs-insert-full-path (tin)
- "Insert full path to the file described in TIN in the current buffer."
-
- (insert (format "%s\n" (cvs-full-path tin))))
-
-;;----------
-(defun cvs-mode-add-change-log-entry-other-window (pos)
- "Add a ChangeLog entry in the ChangeLog of the current directory.
-Args: POS."
-
- (interactive "d")
- (let* ((cvs-buf (current-buffer))
- (odir default-directory)
- (obfname buffer-file-name)
- (tin (tin-locate cvs-cookie-handle pos))
- (fileinfo (tin-cookie cvs-cookie-handle tin))
- (fname (cvs-fileinfo->file-name fileinfo))
- (dname (file-name-as-directory (cvs-fileinfo->dir fileinfo))))
- (setq change-log-default-name nil) ; this rarely correct in 19.28
- (setq buffer-file-name (cond (fname
- fname)
- (t
- nil)))
- (setq default-directory (cond (dname
- dname)
- (t
- odir)))
- (add-change-log-entry-other-window)
- (set-buffer cvs-buf)
- (setq default-directory odir)
- (setq buffer-file-name obfname)))
-
-;;----------
-(defun print-cvs-tin (foo)
- "Debug utility."
-
- (let ((cookie (tin-cookie cvs-cookie-handle foo))
- (stream (get-buffer-create "pcl-cvs-debug")))
- (princ "==============\n" stream)
- (princ (cvs-fileinfo->file-name cookie) stream)
- (princ "\n" stream)
- (princ (cvs-fileinfo->dir cookie) stream)
- (princ "\n" stream)
- (princ (cvs-fileinfo->full-log cookie) stream)
- (princ "\n" stream)
- (princ (cvs-fileinfo->marked cookie) stream)
- (princ "\n" stream)))
-
-;;----------
-;; NOTE: the variable cvs-emerge-tmp-head-file will be "free" when compiling
-(defun cvs-mode-emerge (pos)
- "Emerge appropriate revisions of the selected file.
-Args: POS."
-
- (interactive "d")
- (let* ((cvs-buf (current-buffer))
- (tin (tin-locate cvs-cookie-handle pos)))
- (if (boundp 'cvs-emerge-tmp-head-file)
- (error "There can only be one emerge session active at a time."))
- (if tin
- (let* ((fileinfo (tin-cookie cvs-cookie-handle tin))
- (type (cvs-fileinfo->type fileinfo)))
- (cond
- ((eq type 'MODIFIED) ; merge repository head rev. with working file
- (require 'emerge)
- (setq cvs-emerge-tmp-head-file ; trick to prevent multiple runs
- (cvs-retrieve-revision-to-tmpfile fileinfo))
- (unwind-protect
- (if (not (emerge-files
- t ; arg
- (cvs-fileinfo->full-path fileinfo) ; file-A
- ;; this is an un-avoidable compiler reference to a free variable
- cvs-emerge-tmp-head-file ; file-B
- (cvs-fileinfo->full-path fileinfo) ; file-out
- nil ; start-hooks
- '(lambda () ; quit-hooks
- (delete-file cvs-emerge-tmp-head-file)
- (makunbound 'cvs-emerge-tmp-head-file))))
- (error "Emerge session failed"))))
-
- ;; re-do the same merge rcsmerge supposedly just did....
- ((or (eq type 'MERGED)
- (eq type 'CONFLICT)) ; merge backup-working=A, head=B, base=ancestor
- (require 'emerge)
- (setq cvs-emerge-tmp-head-file ; trick to prevent multiple runs
- (cvs-retrieve-revision-to-tmpfile fileinfo
- (cvs-fileinfo->head-revision
- fileinfo)))
- (let ((cvs-emerge-tmp-backup-working-file
- (cvs-fileinfo->backup-file fileinfo))
- (cvs-emerge-tmp-ancestor-file
- (cvs-retrieve-revision-to-tmpfile fileinfo
- (cvs-fileinfo->base-revision
- fileinfo))))
- (unwind-protect
- (if (not (emerge-files-with-ancestor
- t ; arg
- cvs-emerge-tmp-backup-working-file ; file-A
- ;; this is an un-avoidable compiler reference to a free variable
- cvs-emerge-tmp-head-file ; file-B
- cvs-emerge-tmp-ancestor-file ; file-ancestor
- (cvs-fileinfo->full-path fileinfo) ; file-out
- nil ; start-hooks
- '(lambda () ; quit-hooks
- (delete-file cvs-emerge-tmp-backup-file)
- (delete-file cvs-emerge-tmp-ancestor-file)
- (delete-file cvs-emerge-tmp-head-file)
- (makunbound 'cvs-emerge-tmp-head-file))))
- (error "Emerge session failed")))))
- (t
- (error "Can only e-merge \"Modified\", \"Merged\" or \"Conflict\" files"))))
- (error "There is no file to e-merge."))))
-
-;;----------
-;; NOTE: the variable ediff-version may be "free" when compiling
-(defun cvs-mode-ediff (pos)
- "Ediff appropriate revisions of the selected file.
-Args: POS."
-
- (interactive "d")
- (if (boundp 'cvs-ediff-tmp-head-file)
- (error "There can only be one ediff session active at a time."))
- (require 'ediff)
- (if (and (boundp 'ediff-version)
- (>= (string-to-number ediff-version) 2.0)) ; FIXME real number?
- (run-ediff-from-cvs-buffer pos)
- (cvs-old-ediff-interface pos)))
-
-(defun cvs-old-ediff-interface (pos)
- "Emerge like interface for older ediffs.
-Args: POS"
-
- (let* ((cvs-buf (current-buffer))
- (tin (tin-locate cvs-cookie-handle pos)))
- (if tin
- (let* ((fileinfo (tin-cookie cvs-cookie-handle tin))
- (type (cvs-fileinfo->type fileinfo)))
- (cond
- ((eq type 'MODIFIED) ; diff repository head rev. with working file
- ;; should this be inside the unwind-protect, and should the
- ;; makeunbound be an unwindform?
- (setq cvs-ediff-tmp-head-file ; trick to prevent multiple runs
- (cvs-retrieve-revision-to-tmpfile fileinfo))
- (unwind-protect
- (if (not (ediff-files ; check correct ordering of args
- (cvs-fileinfo->full-path fileinfo) ; file-A
- ;; this is an un-avoidable compiler reference to a free variable
- cvs-ediff-tmp-head-file ; file-B
- '(lambda () ; startup-hooks
- (make-local-hook 'ediff-cleanup-hooks)
- (add-hook 'ediff-cleanup-hooks
- '(lambda ()
- (ediff-janitor)
- (delete-file cvs-ediff-tmp-head-file)
- (makunbound 'cvs-ediff-tmp-head-file))
- nil t))))
- (error "Ediff session failed"))))
-
- ;; look at the merge rcsmerge supposedly just did....
- ((or (eq type 'MERGED)
- (eq type 'CONFLICT)) ; diff backup-working=A, head=B, base=ancestor
- (if (not (boundp 'ediff-version))
- (error "ediff version way too old for 3-way diff"))
- (if (<= (string-to-number ediff-version) 1.9) ; FIXME real number?
- (error "ediff version %s too old for 3-way diff" ediff-version))
- (setq cvs-ediff-tmp-head-file ; trick to prevent multiple runs
- (cvs-retrieve-revision-to-tmpfile fileinfo
- (cvs-fileinfo->head-revision
- fileinfo)))
- (let ((cvs-ediff-tmp-backup-working-file
- (cvs-fileinfo->backup-file fileinfo))
- (cvs-ediff-tmp-ancestor-file
- (cvs-retrieve-revision-to-tmpfile fileinfo
- (cvs-fileinfo->base-revision
- fileinfo))))
- (unwind-protect
- (if (not (ediff-files3 ; check correct ordering of args
- cvs-ediff-tmp-backup-working-file ; file-A
- ;; this is an un-avoidable compiler reference to a free variable
- cvs-ediff-tmp-head-file ; file-B
- cvs-ediff-tmp-ancestor-file ; file-ancestor
- '(lambda () ; start-hooks
- (make-local-hook 'ediff-cleanup-hooks)
- (add-hook 'ediff-cleanup-hooks
- '(lambda ()
- (ediff-janitor)
- (delete-file cvs-ediff-tmp-backup-file)
- (delete-file cvs-ediff-tmp-ancestor-file)
- (delete-file cvs-ediff-tmp-head-file)
- (makunbound 'cvs-ediff-tmp-head-file))
- nil t))))
- (error "Ediff session failed")))))
-
- ((not (or (eq type 'UNKNOWN)
- (eq type 'UNKNOWN-DIR))) ; i.e. UPDATED or PATCHED ????
- ;; this should really diff the current working file with the previous
- ;; rev. on the current branch (i.e. not the head, since that's what
- ;; the current file should be)
- (setq cvs-ediff-tmp-head-file ; trick to prevent multiple runs
- (cvs-retrieve-revision-to-tmpfile fileinfo
- (read-string "Rev #/tag to diff against: "
- (cvs-fileinfo->head-revision
- fileinfo))))
- (unwind-protect
- (if (not (ediff-files ; check correct ordering of args
- (cvs-fileinfo->full-path fileinfo) ; file-A
- ;; this is an un-avoidable compiler reference to a free variable
- cvs-ediff-tmp-head-file ; file-B
- '(lambda () ; startup-hooks
- (make-local-hook 'ediff-cleanup-hooks)
- (add-hook 'ediff-cleanup-hooks
- '(lambda ()
- (ediff-janitor)
- (delete-file cvs-ediff-tmp-head-file)
- (makunbound 'cvs-ediff-tmp-head-file))
- nil t))))
- (error "Ediff session failed"))))
- (t
- (error "Can not ediff \"Unknown\" files"))))
- (error "There is no file to ediff."))))
-
-;;----------
-(defun cvs-retrieve-revision-to-tmpfile (fileinfo &optional revision)
- "Retrieve the latest revision of the file in FILEINFO to a temporary file.
-If second optional argument REVISION is given, retrieve that revision instead."
-
- (let
- ((temp-name (make-temp-name
- (concat (file-name-as-directory
- (or (getenv "TMPDIR") "/tmp"))
- "pcl-cvs." revision))))
- (cvs-kill-buffer-visiting temp-name)
- (if (and revision
- (stringp revision)
- (not (string= revision "")))
- (message "Retrieving revision %s..." revision)
- (message "Retrieving latest revision..."))
- (let ((res (call-process cvs-shell nil nil nil "-c"
- (concat cvs-program " update -p "
- (if (and revision
- (stringp revision)
- (not (string= revision "")))
- (concat "-r " revision " ")
- "")
- (cvs-fileinfo->full-path fileinfo)
- " > " temp-name))))
- (if (and res (not (and (integerp res) (zerop res))))
- (error "Something went wrong retrieving revision %s: %s"
- revision res))
-
- (if revision
- (message "Retrieving revision %s... Done." revision)
- (message "Retrieving latest revision... Done."))
- (save-excursion
- (set-buffer (find-file-noselect temp-name))
- (rename-buffer (concat " " (file-name-nondirectory temp-name)) t))
- temp-name)))
-
-;;----------
-(defun cvs-kill-buffer-visiting (filename)
- "If there is any buffer visiting FILENAME, kill it (without confirmation)."
-
- (let ((l (buffer-list)))
- (while l
- (if (string= (buffer-file-name (car l)) filename)
- (kill-buffer (car l)))
- (setq l (cdr l)))))
-
-;;----------
-(defun cvs-change-cvsroot ()
- "Ask for a new cvsroot."
-
- (interactive)
- (cvs-set-cvsroot (read-file-name "New CVSROOT: " cvs-cvsroot)))
-
-;;----------
-(defun cvs-set-cvsroot (newroot)
- "Change the cvsroot."
-
- (if (or (file-directory-p (expand-file-name "CVSROOT" newroot))
- (y-or-n-p (concat "Warning: no CVSROOT found inside repository."
- " Change cvs-cvsroot anyhow?")))
- (setq cvs-cvsroot newroot)))
-
-;;----------
-(defun cvs-set-diff-flags ()
- "Ask for new setting of cvs-diff-flags."
-
- (interactive)
- (let ((old-value (mapconcat 'identity
- (copy-sequence cvs-diff-flags) " ")))
- (setq cvs-diff-flags
- (cvs-make-list (read-string "Diff flags: " old-value)))))
-
-;;----------
-(defun cvs-set-update-optional-flags ()
- "Ask for new setting of cvs-update-optional-flags."
-
- (interactive)
- (let ((old-value (mapconcat 'identity
- (copy-sequence cvs-update-optional-flags) " ")))
- (setq cvs-update-optional-flags
- (cvs-make-list (read-string "Update optional flags: " old-value)))))
-
-;;----------
-(defun cvs-set-status-flags ()
- "Ask for new setting of cvs-status-flags."
-
- (interactive)
- (let ((old-value (mapconcat 'identity
- (copy-sequence cvs-status-flags) " ")))
- (setq cvs-status-flags
- (cvs-make-list (read-string "Status flags: " old-value)))))
-
-;;----------
-(defun cvs-set-log-flags ()
- "Ask for new setting of cvs-log-flags."
-
- (interactive)
- (let ((old-value (mapconcat 'identity
- (copy-sequence cvs-log-flags) " ")))
- (setq cvs-log-flags
- (cvs-make-list (read-string "Log flags: " old-value)))))
-
-;;----------
-(defun cvs-set-tag-flags ()
- "Ask for new setting of cvs-tag-flags."
-
- (interactive)
- (let ((old-value (mapconcat 'identity
- (copy-sequence cvs-tag-flags) " ")))
- (setq cvs-tag-flags
- (cvs-make-list (read-string "Tag flags: " old-value)))))
-
-;;----------
-(defun cvs-set-rtag-flags ()
- "Ask for new setting of cvs-rtag-flags."
-
- (interactive)
- (let ((old-value (mapconcat 'identity
- (copy-sequence cvs-rtag-flags) " ")))
- (setq cvs-rtag-flags
- (cvs-make-list (read-string "Rtag flags: " old-value)))))
-
-;;----------
-(if (string-match "Lucid" emacs-version)
- (progn
- (autoload 'pcl-cvs-fontify "pcl-cvs-lucid")
- (add-hook 'cvs-mode-hook 'pcl-cvs-fontify)))
-
-(defun cvs-changelog-name (directory)
- "Return the name of the ChangeLog file that handles DIRECTORY.
-This is in DIRECTORY or one of its parents.
-Signal an error if we can't find an appropriate ChangeLog file."
- (let ((dir (file-name-as-directory directory))
- file)
- (while (and dir
- (not (file-exists-p
- (setq file (expand-file-name "ChangeLog" dir)))))
- (let ((last dir))
- (setq dir (file-name-directory (directory-file-name dir)))
- (if (equal last dir)
- (setq dir nil))))
- (or dir
- (error "Can't find ChangeLog for %s" directory))
- file))
-
-(defun cvs-narrow-changelog ()
- "Narrow to the top page of the current buffer, a ChangeLog file.
-Actually, the narrowed region doesn't include the date line.
-A \"page\" in a ChangeLog file is the area between two dates."
- (or (eq major-mode 'change-log-mode)
- (error "cvs-narrow-changelog: current buffer isn't a ChangeLog"))
-
- (goto-char (point-min))
-
- ;; Skip date line and subsequent blank lines.
- (forward-line 1)
- (if (looking-at "[ \t\n]*\n")
- (goto-char (match-end 0)))
-
- (let ((start (point)))
- (forward-page 1)
- (narrow-to-region start (point))
- (goto-char (point-min))))
-
-(defun cvs-changelog-paragraph ()
- "Return the bounds of the ChangeLog paragraph containing point.
-If we are between paragraphs, return the previous paragraph."
- (save-excursion
- (beginning-of-line)
- (if (looking-at "^[ \t]*$")
- (skip-chars-backward " \t\n" (point-min)))
- (list (progn
- (if (re-search-backward "^[ \t]*\n" nil 'or-to-limit)
- (goto-char (match-end 0)))
- (point))
- (if (re-search-forward "^[ \t\n]*$" nil t)
- (match-beginning 0)
- (point)))))
-
-(defun cvs-changelog-subparagraph ()
- "Return the bounds of the ChangeLog subparagraph containing point.
-A subparagraph is a block of non-blank lines beginning with an asterisk.
-If we are between sub-paragraphs, return the previous subparagraph."
- (save-excursion
- (end-of-line)
- (if (search-backward "*" nil t)
- (list (progn (beginning-of-line) (point))
- (progn
- (forward-line 1)
- (if (re-search-forward "^[ \t]*[\n*]" nil t)
- (match-beginning 0)
- (point-max))))
- (list (point) (point)))))
-
-(defun cvs-changelog-entry ()
- "Return the bounds of the ChangeLog entry containing point.
-The variable `cvs-changelog-full-paragraphs' decides whether an
-\"entry\" is a paragraph or a subparagraph; see its documentation string
-for more details."
- (if cvs-changelog-full-paragraphs
- (cvs-changelog-paragraph)
- (cvs-changelog-subparagraph)))
-
-;; NOTE: the variable user-full-name may be "free" when compiling
-(defun cvs-changelog-ours-p ()
- "See if ChangeLog entry at point is for the current user, today.
-Return non-nil iff it is."
- ;; Code adapted from add-change-log-entry.
- (or (looking-at
- (regexp-quote (format "%s %s <%s>"
- (format-time-string "%Y-%m-%d")
- add-log-full-name
- add-log-mailing-address)))
- (looking-at
- (concat (regexp-quote (substring (current-time-string)
- 0 10))
- ".* "
- (regexp-quote (substring (current-time-string) -4))
- "[ \t]+"
- (regexp-quote (if (and (boundp 'add-log-full-name)
- add-log-full-name)
- add-log-full-name
- user-full-name))
- " <"
- (regexp-quote (if (and (boundp 'add-log-mailing-address)
- add-log-mailing-address)
- add-log-mailing-address
- user-mail-address))))))
-
-(defun cvs-relative-path (base child)
- "Return a directory path relative to BASE for CHILD.
-If CHILD doesn't seem to be in a subdirectory of BASE, just return
-the full path to CHILD."
- (let ((base (file-name-as-directory (expand-file-name base)))
- (child (expand-file-name child)))
- (or (string= base (substring child 0 (length base)))
- (error "cvs-relative-path: %s isn't in %s" child base))
- (substring child (length base))))
-
-(defun cvs-changelog-entries (file)
- "Return the ChangeLog entries for FILE, and the ChangeLog they came from.
-The return value looks like this:
- (LOGBUFFER (ENTRYSTART . ENTRYEND) ...)
-where LOGBUFFER is the name of the ChangeLog buffer, and each
-\(ENTRYSTART . ENTRYEND\) pair is a buffer region."
- (save-excursion
- (set-buffer (find-file-noselect
- (cvs-changelog-name
- (file-name-directory
- (expand-file-name file)))))
- (or (eq major-mode 'change-log-mode)
- (change-log-mode))
- (goto-char (point-min))
- (if (looking-at "[ \t\n]*\n")
- (goto-char (match-end 0)))
- (if (not (cvs-changelog-ours-p))
- (list (current-buffer))
- (save-restriction
- (cvs-narrow-changelog)
- (goto-char (point-min))
-
- ;; Search for the name of FILE relative to the ChangeLog. If that
- ;; doesn't occur anywhere, they're not using full relative
- ;; filenames in the ChangeLog, so just look for FILE; we'll accept
- ;; some false positives.
- (let ((pattern (cvs-relative-path
- (file-name-directory buffer-file-name) file)))
- (if (or (string= pattern "")
- (not (save-excursion
- (search-forward pattern nil t))))
- (setq pattern file))
-
- (let (texts)
- (while (search-forward pattern nil t)
- (let ((entry (cvs-changelog-entry)))
- (setq texts (cons entry texts))
- (goto-char (elt entry 1))))
-
- (cons (current-buffer) texts)))))))
-
-(defun cvs-changelog-insert-entries (buffer regions)
- "Insert those regions in BUFFER specified in REGIONS.
-Sort REGIONS front-to-back first."
- (let ((regions (sort regions 'car-less-than-car))
- (last))
- (while regions
- (if (and last (< last (car (car regions))))
- (newline))
- (setq last (elt (car regions) 1))
- (apply 'insert-buffer-substring buffer (car regions))
- (setq regions (cdr regions)))))
-
-(defun cvs-union (set1 set2)
- "Return the union of SET1 and SET2, according to `equal'."
- (while set2
- (or (member (car set2) set1)
- (setq set1 (cons (car set2) set1)))
- (setq set2 (cdr set2)))
- set1)
-
-(defun cvs-insert-changelog-entries (files)
- "Given a list of files FILES, insert the ChangeLog entries for them."
- (let ((buffer-entries nil))
-
- ;; Add each buffer to buffer-entries, and associate it with the list
- ;; of entries we want from that file.
- (while files
- (let* ((entries (cvs-changelog-entries (car files)))
- (pair (assq (car entries) buffer-entries)))
- (if pair
- (setcdr pair (cvs-union (cdr pair) (cdr entries)))
- (setq buffer-entries (cons entries buffer-entries))))
- (setq files (cdr files)))
-
- ;; Now map over each buffer in buffer-entries, sort the entries for
- ;; each buffer, and extract them as strings.
- (while buffer-entries
- (cvs-changelog-insert-entries (car (car buffer-entries))
- (cdr (car buffer-entries)))
- (if (and (cdr buffer-entries) (cdr (car buffer-entries)))
- (newline))
- (setq buffer-entries (cdr buffer-entries)))))
-
-(defun cvs-edit-delete-common-indentation ()
- "Unindent the current buffer rigidly until at least one line is flush left."
- (save-excursion
- (let ((common 100000))
- (goto-char (point-min))
- (while (< (point) (point-max))
- (if (not (looking-at "^[ \t]*$"))
- (setq common (min common (current-indentation))))
- (forward-line 1))
- (indent-rigidly (point-min) (point-max) (- common)))))
-
-(defun cvs-mode-changelog-commit ()
- "Check in all marked files, or the current file.
-Ask the user for a log message in a buffer.
-
-This is just like `\\[cvs-mode-commit]', except that it tries to provide
-appropriate default log messages by looking at the ChangeLog. The
-idea is to write your ChangeLog entries first, and then use this
-command to commit your changes.
-
-To select default log text, we:
-- find the ChangeLog entries for the files to be checked in,
-- verify that the top entry in the ChangeLog is on the current date
- and by the current user; if not, we don't provide any default text,
-- search the ChangeLog entry for paragraphs containing the names of
- the files we're checking in, and finally
-- use those paragraphs as the log text."
-
- (interactive)
-
- (let* ((cvs-buf (current-buffer))
- (marked (cvs-filter (function cvs-committable)
- (cvs-get-marked))))
- (if (null marked)
- (error "Nothing to commit!")
- (pop-to-buffer (get-buffer-create cvs-commit-prompt-buffer))
- (goto-char (point-min))
-
- (erase-buffer)
- (cvs-insert-changelog-entries
- (mapcar (lambda (tin)
- (let ((cookie (tin-cookie cvs-cookie-handle tin)))
- (expand-file-name
- (cvs-fileinfo->file-name cookie)
- (cvs-fileinfo->dir cookie))))
- marked))
- (cvs-edit-delete-common-indentation)
-
- (cvs-edit-mode)
- (make-local-variable 'cvs-commit-list)
- (setq cvs-commit-list marked)
- (message "Press C-c C-c when you are done editing."))))
-
-(provide 'pcl-cvs)
-
-;;;; end of file pcl-cvs.el
diff --git a/contrib/cvs/tools/pcl-cvs/pcl-cvs.texinfo b/contrib/cvs/tools/pcl-cvs/pcl-cvs.texinfo
deleted file mode 100644
index 8bd36193bb18..000000000000
--- a/contrib/cvs/tools/pcl-cvs/pcl-cvs.texinfo
+++ /dev/null
@@ -1,1565 +0,0 @@
-\input texinfo @c -*-texinfo-*-
-
-@comment OrigId: pcl-cvs.texinfo,v 1.45 1993/05/31 22:38:15 ceder Exp
-@comment @@(#)cvs/contrib/pcl-cvs:$Name: $:$Id: pcl-cvs.texinfo,v 1.1 1996/04/14 15:18:04 kfogel Exp $
-
-@comment Documentation for the GNU Emacs CVS mode.
-@comment Copyright (C) 1992 Per Cederqvist
-
-@comment This file is part of the pcl-cvs distribution.
-
-@comment Pcl-cvs is free software; you can redistribute it and/or modify
-@comment it under the terms of the GNU General Public License as published by
-@comment the Free Software Foundation; either version 1, or (at your option)
-@comment any later version.
-
-@comment Pcl-cvs is distributed in the hope that it will be useful,
-@comment but WITHOUT ANY WARRANTY; without even the implied warranty of
-@comment MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-@comment GNU General Public License for more details.
-
-@comment You should have received a copy of the GNU General Public License
-@comment along with pcl-cvs; see the file COPYING. If not, write to
-@comment the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
-@setfilename pcl-cvs.info
-@settitle Pcl-cvs - The Emacs Front-End to CVS
-@setchapternewpage on
-
-@ifinfo
-Copyright @copyright{} 1992 Per Cederqvist
-
-Permission is granted to make and distribute verbatim copies of
-this manual provided the copyright notice and this permission notice
-are preserved on all copies.
-
-@ignore
-Permission is granted to process this file through Tex and print the
-results, provided the printed document carries copying permission
-notice identical to this one except for the removal of this paragraph
-(this paragraph not being relevant to the printed manual).
-
-@end ignore
-Permission is granted to copy and distribute modified versions of this
-manual under the conditions for verbatim copying, provided also that the
-section entitled ``GNU General Public License'' is included exactly as
-in the original, and provided that the entire resulting derived work is
-distributed under the terms of a permission notice identical to this one.
-
-Permission is granted to copy and distribute translations of this manual
-into another language, under the above conditions for modified versions,
-except that the section entitled ``GNU General Public License'' and
-this permission notice may be included in translations approved by the
-Free Software Foundation instead of in the original English.
-@end ifinfo
-
-@synindex vr fn
-@comment The titlepage section does not appear in the Info file.
-@titlepage
-@sp 4
-@comment The title is printed in a large font.
-@center @titlefont{User's Guide}
-@sp
-@center @titlefont{to}
-@sp
-@center @titlefont{pcl-cvs - the Emacs Front-End to CVS}
-@sp 2
-@center release 1.05-CVS-$Name: $
-@comment -release-
-@sp 3
-@center Per Cederqvist
-@sp 3
-@center last updated 20 Nov 1995
-@comment -date-
-
-@comment The following two commands start the copyright page
-@comment for the printed manual. This will not appear in the Info file.
-@page
-@vskip 0pt plus 1filll
-Copyright @copyright{} 1992 Per Cederqvist
-
-Permission is granted to make and distribute verbatim copies of
-this manual provided the copyright notice and this permission notice
-are preserved on all copies.
-
-Permission is granted to copy and distribute modified versions of this
-manual under the conditions for verbatim copying, provided also that the
-section entitled ``GNU General Public License'' is included exactly as
-in the original, and provided that the entire resulting derived work is
-distributed under the terms of a permission notice identical to this one.
-
-Permission is granted to copy and distribute translations of this manual
-into another language, under the above conditions for modified versions,
-except that the section entitled ``GNU General Public License'' and
-this permission notice may be included in translations approved by the
-Free Software Foundation instead of in the original English.
-@end titlepage
-
-@comment ================================================================
-@comment The real text starts here
-@comment ================================================================
-
-@node Top, Installation, (dir), (dir)
-@comment node-name, next, previous, up
-
-
-@ifinfo
-This info manual describes pcl-cvs which is a GNU Emacs front-end to
-CVS. It works with CVS versions 1.5 through 1.7 and newer, and possibly
-CVS-1.3 and CVS-1.4A2. This manual is updated to release
-1.05-CVS-$Name: $ of pcl-cvs.
-@end ifinfo
-@comment -release-
-
-@menu
-* Installation:: How to install pcl-cvs on your system.
-* About pcl-cvs:: Authors and ftp sites.
-
-* Getting started:: An introduction with a walk-through example.
-* Buffer contents:: An explanation of the buffer contents.
-* Commands:: All commands, grouped by type.
-
-* Customization:: How you can tailor pcl-cvs to suit your needs.
-* Future enhancements:: Future enhancements of pcl-cvs.
-* Bugs:: Bugs (known and unknown).
-* COPYING:: GNU General Public License
-* Function and Variable Index:: List of functions and variables.
-* Concept Index:: List of concepts.
-* Key Index:: List of keystrokes.
-
- --- The Detailed Node Listing ---
-
-Installation
-
-* Pcl-cvs installation:: How to install pcl-cvs on your system.
-* On-line manual installation:: How to install the on-line manual.
-* Typeset manual installation:: How to create typeset documentation
- about pcl-cvs.
-
-About pcl-cvs
-
-* Contributors:: Contributors to pcl-cvs.
-* Archives:: Where can I get a copy of Pcl-Cvs?
-
-Buffer contents
-
-* File status:: The meaning of the second field.
-* Selected files:: How selection works.
-
-Commands
-
-* Updating the directory:: Commands to update the local directory
-* Movement commands:: How to move up and down in the buffer
-* Marking files:: How to mark files that other commands
- will later operate on.
-* Committing changes:: Checking in your modifications to the
- CVS repository.
-* Editing files:: Loading files into Emacs.
-* Getting info about files:: Display the log and status of files.
-* Adding and removing files:: Adding and removing files
-* Undoing changes:: Undoing changes
-* Removing handled entries:: Uninteresting lines can easily be removed.
-* Ignoring files:: Telling CVS to ignore generated files.
-* Viewing differences:: Commands to @samp{diff} different versions.
-* Invoking Ediff:: Running @samp{ediff} from @samp{*cvs*} buffer.
-* Invoking Emerge:: Running @samp{emerge} from @samp{*cvs*} buffer.
-* Reverting your buffers:: Reverting your buffers
-* Miscellaneous commands:: Miscellaneous commands
-@end menu
-
-
-@node Installation, About pcl-cvs, Top, Top
-@comment node-name, next, previous, up
-
-@chapter Installation
-@cindex Installation
-
-This section describes the installation of pcl-cvs, the GNU Emacs CVS
-front-end. You should install not only the elisp files themselves, but
-also the on-line documentation so that your users will know how to use
-it. You can create typeset documentation from the file
-@file{pcl-cvs.texinfo} as well as an on-line info file. The following
-steps are also described in the file @file{INSTALL} in the source
-directory.
-
-@menu
-* Pcl-cvs installation:: How to install pcl-cvs on your system.
-* On-line manual installation:: How to install the on-line manual.
-* Typeset manual installation:: How to create typeset documentation
- about pcl-cvs.
-@end menu
-
-
-@node Pcl-cvs installation, On-line manual installation, Installation, Installation
-@comment node-name, next, previous, up
-@section Installation of the pcl-cvs program
-@cindex Installation of elisp files
-
-@enumerate
-@item
-Possibly edit the file @file{Makefile} to reflect the situation at your
-site. We say "possibly" because the version of pcl-cvs included with
-CVS uses a configuration mechanism integrated with the overall
-mechanisms used by the CVS build and install procedures. Thus the file
-@code{Makefile} will be generated automatically from the file
-@code{Makefile.in}, and it should not be necessary to edit it further.
-
-If you do have to edit the @file{Makefile}, the only things you have to
-change is the definition of @code{lispdir} and @code{infodir}. The
-elisp files will be copied to @code{lispdir}, and the info file(s) to
-@code{infodir}.
-
-@item
-Configure pcl-cvs.el
-
-There are a couple of pathnames that you have to check to make sure that
-they match your system. They appear early in the file
-@samp{pcl-cvs.el}.
-
-@strong{NOTE:} If your system is running emacs 18.57 or earlier you MUST
-uncomment the line that says:
-@example
-(setq delete-exited-processes nil)
-@end example
-
-Setting @code{delete-exited-processes} to @code{nil} works around a bug
-in emacs that causes it to dump core. The bug was fixed in emacs
-18.58.@refill
-
-@item
-Release 1.05 and later of pcl-cvs requires parts of the Elib library,
-version 1.0 or later. Elib is available via anonymous ftp from
-prep.ai.mit.edu in @file{pub/gnu/elib-1.0.tar.gz}, and from a lot of
-other sites that mirror prep. Get Elib, and install it, before
-proceeding.
-
-@strong{NOTE:} The version of pcl-cvs included with CVS includes a copy
-of Elib in the sub-directory @file{elib} under the
-@file{contrib/pcl-cvs} directory.
-
-@item
-Type @samp{make install} in the source directory. This will
-byte-compile all @file{.el} files and copy the @file{*.elc} files into
-the directory you specified in step 1.
-
-If you want to install the @file{*.el} files too, you can type
-@samp{make install-el} to do so.
-
-If you only want to create the compiled elisp files, but don't want to
-install them, you can type @samp{make} without parameters.
-
-@item
-Edit the file @file{default.el} in your emacs lisp directory (usually
-@file{/usr/gnu/lib/emacs/site-lisp} or something similar) and enter the
-contents of the file @file{pcl-cvs-startup.el} into it. It contains a
-couple of @code{auto-load}s that facilitates the use of pcl-cvs.
-
-@end enumerate
-
-
-@node On-line manual installation, Typeset manual installation, Pcl-cvs installation, Installation
-@comment node-name, next, previous, up
-
-@section Installation of the on-line manual.
-@cindex Manual installation (on-line)
-@cindex Installation of on-line manual
-@cindex Generating the on-line manual
-@cindex On-line manual (how to generate)
-@cindex Info-file (how to generate)
-
-@enumerate
-@item
-Create the info file(s) @file{pcl-cvs.info*} from @file{pcl-cvs.texinfo}
-by typing @samp{make info}. If you don't have the program
-@samp{makeinfo} you can get it by anonymous ftp from
-e.g. @samp{prep.ai.mit.edu} as @file{pub/gnu/texinfo-3.7.tar.gz} (there
-might be a newer version there when you read this).@refill
-
-@item
-Install the info file(s) @file{pcl-cvs.info*} into your standard
-@file{info} directory. You should be able to do this by typing
-@samp{make install-info}.@refill
-
-@item
-Edit the file @file{dir} in the @file{info} directory and enter one line
-to contain a pointer to the info file(s) @file{pcl-cvs.info*}. The line
-can, for instance, look like this:@refill
-
-@example
-* Pcl-cvs: (pcl-cvs). An Emacs front-end to CVS.
-@end example
-@end enumerate
-
-
-@node Typeset manual installation, , On-line manual installation, Installation
-@comment node-name, next, previous, up
-
-@section How to make typeset documentation from pcl-cvs.texinfo
-@cindex Manual installation (typeset)
-@cindex Installation of typeset manual
-@cindex Printing a manual
-@cindex TeX - generating a typeset manual
-@cindex Generating a typeset manual
-
-If you have @TeX{} installed at your site, you can make a typeset manual
-from @file{pcl-cvs.texinfo}.
-
-@enumerate
-@item
-Run @TeX{} by typing `@samp{make pcl-cvs.dvi}'. You will not get the
-indices unless you have the @code{texindex} program.
-
-@item
-Convert the resulting device independent file @file{pcl-cvs.dvi} to a
-form which your printer can output and print it. If you have a
-postscript printer there is a program, @code{dvi2ps}, which does. There
-is also a program which comes together with @TeX{}, @code{dvips}, which
-you can use.
-
-@end enumerate
-
-
-@node About pcl-cvs, Getting started, Installation, Top
-@comment node-name, next, previous, up
-
-@chapter About pcl-cvs
-@cindex About pcl-cvs
-
-Pcl-cvs is a front-end to CVS versions 1.5 through 1.7 and newer; and
-possibly verison 1.3 and 1.4A2. It integrates the most frequently used
-CVS commands into an emacs interface.
-
-@menu
-* Contributors:: Contributors to pcl-cvs.
-* Archives:: Where can I get a copy of Pcl-Cvs?
-@end menu
-
-
-@node Contributors, Archives, About pcl-cvs, About pcl-cvs
-@comment node-name, next, previous, up
-
-@section Contributors to pcl-cvs
-@cindex Contributors
-@cindex Authors
-
-Contributions to the package are welcome. I have limited time to work
-on this project, but I will gladly add any code that you contribute to
-me to this package (@pxref{Bugs}).
-
-The following persons have made contributions to pcl-cvs.
-
-@itemize @bullet
-@item
-Brian Berliner wrote CVS, together with some other contributors.
-Without his work on CVS this package would be useless@dots{}
-
-@item
-Per Cederqvist wrote most of the otherwise unattributed functions in
-pcl-cvs as well as all documentation.
-
-@item
-Inge Wallin (@samp{inge@@lysator.liu.se}) wrote the skeleton to
-@file{pcl-cvs.texinfo}, and gave useful comments on it. He also wrote
-the files @file{elib-node.el} and @file{compile-all.el}. The file
-@file{cookie.el} was inspired by Inge.@refill
-
-@item
-Linus Tolke (@samp{linus@@lysator.liu.se}) contributed useful comments
-on both the functionality and the documentation.@refill
-
-@item
-Jamie Zawinski (@samp{jwz@@lucid.com}) contributed
-@file{pcl-cvs-lucid.el}.
-
-@item
-Leif Lonnblad contributed RCVS support. (Since superceded by the new
-remote CVS support.)
-
-@item
-Jim Blandy (@samp{jimb@@cyclic.com}) contributed hooks to automatically
-guess CVS log entries from ChangeLog contents; and initial support of
-the new Cygnus / Cyclic remote CVS; as well as various sundry bug fixes
-and cleanups.
-
-@item
-Jim Kingdon (@samp{kingdon@@cyclic.com}) contributed lots of fixes to
-the build and install procedure.
-
-@item
-Greg A. Woods (@samp{woods@@planix.com}) contributed code to implement
-the use of per-file diff buffers; and vendor join diffs with emerge and
-ediff; as well as various an sundry bug fixes and cleanups.
-@end itemize
-
-Apart from these, a lot of people have send me suggestions, ideas,
-requests, bug reports and encouragement. Thanks a lot! Without your
-there would be no new releases of pcl-cvs.
-
-
-@node Archives, , Contributors, About pcl-cvs
-@comment node-name, next, previous, up
-
-@section Where can I get pcl-cvs?
-@cindex Sites
-@cindex Archives
-@cindex Ftp-sites
-@cindex Getting pcl-cvs
-@cindex Email archives
-
-The current release of pcl-cvs is included in CVS-1.7.
-
-The author's release of pcl-cvs can be fetched via anonymous ftp from
-@code{ftp.lysator.liu.se}, (IP no. 130.236.254.1) in the directory
-@code{pub/emacs}. If you don't live in Scandinavia you should probably
-check with archie to see if there is a site closer to you that archives
-pcl-cvs.
-
-New releases will be announced to appropriate newsgroups. If you send
-your email address to me I will add you to my list of people to mail
-when I make a new release.
-
-
-@node Getting started, Buffer contents, About pcl-cvs, Top
-@comment node-name, next, previous, up
-
-@chapter Getting started
-@cindex Introduction
-@cindex Example run
-
-This document assumes that you know what CVS is, and that you at least
-knows the fundamental concepts of CVS. If that is not the case you
-should read the man page for CVS.
-
-Pcl-cvs is only useful once you have checked out a module. So before
-you invoke it you must have a copy of a module somewhere in the file
-system.
-
-You invoke pcl-cvs by typing @kbd{M-x cvs-update RET}. If your emacs
-responds with @samp{[No match]} your system administrator has not
-installed pcl-cvs properly. Try @kbd{M-x load-library RET pcl-cvs RET}.
-If that also fails - talk to your root. If it succeeds you might put
-this line in your @file{.emacs} file so that you don't have to type the
-@samp{load-library} command every time you wish to use pcl-cvs:
-
-@example
-(autoload 'cvs-update "pcl-cvs" nil t)
-@end example
-
-The function @code{cvs-update} will ask for a directory. The command
-@samp{cvs update} will be run in that directory. (It should contain
-files that have been checked out from a CVS archive.) The output from
-@code{cvs} will be parsed and presented in a table in a buffer called
-@samp{*cvs*}. It might look something like this:
-
-@example
-PCL-CVS release 1.05-CVS-$Name: $.
-@comment -release-
-
-In directory /users/ceder/FOO/test:
- Updated bar
- Updated file.txt
- Modified ci namechange
- Updated newer
-
-In directory /users/ceder/FOO/test/sub:
- Modified ci ChangeLog
----------- End -----
-@end example
-
-In this example the two files (@file{bar}, @file{file.txt}, and
-@file{newer}) that are marked with @samp{Updated} have been copied from
-the CVS repository to @file{/users/ceder/FOO/test/} since someone else
-have checked in newer versions of them. Two files (@file{namechange}
-and @file{sub/ChangeLog}) have been modified locally, and needs to be
-checked in.
-
-You can move the cursor up and down in the buffer with @kbd{C-n} and
-@kbd{C-p} or @kbd{n} and @kbd{p}. If you press @kbd{c} on one of the
-@samp{Modified} files that file will be checked in to the CVS
-repository. @xref{Committing changes}. You can press @kbd{x} to get rid
-of the "uninteresting" files that have only been @samp{Updated} (and
-don't require any further action from you).@refill
-
-You can also easily get a @samp{diff} between your modified file and the
-base version that you started from, and you can get the output from
-@samp{cvs log} and @samp{cvs status} on the listed files simply by
-pressing a key (@pxref{Getting info about files}).
-
-
-@node Buffer contents, Commands, Getting started, Top
-@comment node-name, next, previous, up
-
-@chapter Buffer contents
-@cindex Buffer contents
-
-The display contains four columns. They contain, from left to right:
-
-@itemize @bullet
-@item
-An asterisk when the file is @dfn{marked} (@pxref{Selected
-files}).@refill
-@item
-The status of the file. See @xref{File status}, for more
-information.@refill
-@item
-A "need to be checked in"-marker (@samp{ci}).
-@item
-The file name.
-@end itemize
-
-@menu
-* File status:: The meaning of the second field.
-* Selected files:: How selection works.
-@end menu
-
-
-@node File status, Selected files, Buffer contents, Buffer contents
-@comment node-name, next, previous, up
-
-@section File status
-@cindex File status
-@cindex Updated (file status)
-@cindex Patched (file status)
-@cindex Modified (file status)
-@cindex Merged (file status)
-@cindex Conflict (file status)
-@cindex Added (file status)
-@cindex Removed (file status)
-@cindex Unknown (file status)
-@cindex Removed from repository (file status)
-@cindex Removed from repository, changed by you (file status)
-@cindex Removed by you, changed in repository (file status)
-@cindex Move away @var{file} - it is in the way (file status)
-@cindex This repository is missing!@dots{} (file status)
-
-The @samp{file status} field can have the following values:
-
-@table @samp
-
-@item Updated
-The file was brought up to date with respect to the repository. This is
-done for any file that exists in the repository but not in your source,
-and for files that you haven't changed but are not the most recent
-versions available in the repository.@refill
-
-@item Patched
-The file was brought up to date with respect to a remote repository by
-way of fetching and applying a patch to the file in your source. This
-is done for any file that exists in a remote repository and in your
-source; of which you haven't changed locally but is not the most recent
-version available in the remote repository.@refill
-
-@item Modified
-The file is modified in your working directory, and there was no
-modification to the same file in the repository.@refill
-
-@item Merged
-The file is modified in your working directory, and there were
-modifications in the repository as well as in your copy, but they were
-merged successfully, without conflict, in your working directory.@refill
-
-@item Conflict
-A conflict was detected while trying to merge your changes to @var{file}
-with changes from the source repository. @var{file} (the copy in your
-working directory) is now the output of the @samp{rcsmerge} command on
-the two versions; an unmodified copy of your file is also in your
-working directory, with the name @file{.#@var{file}.@var{version}},
-where @var{version} is the RCS revision that your modified file started
-from. @xref{Viewing differences}, for more details.@refill
-
-@item Added
-The file has been added by you, but it still needs to be checked in to
-the repository.@refill
-
-@item Removed
-The file has been removed by you, but it needs to be checked in to the
-repository. You can resurrect it by typing @kbd{a} (@pxref{Adding and
-removing files}).@refill
-
-@item Unknown
-A file that was detected in your directory, but that neither appears in
-the repository, nor is present on the list of files that CVS should
-ignore.@refill
-
-@end table
-
-There are also a few special cases, that rarely occur, which have longer
-strings in the fields:
-
-@table @samp
-@item Removed from repository
-The file has been removed from your directory since someone has removed
-it from the repository. (It is still present in the Attic directory, so
-no permanent loss has occurred). This, unlike the other entries in this
-table, is not an error condition.@refill
-
-@item Removed from repository, changed by you
-You have modified a file that someone have removed from the repository.
-You can correct this situation by removing the file manually (see
-@pxref{Adding and removing files}).@refill
-
-@item Removed by you, changed in repository
-You have removed a file, and before you committed the removal someone
-committed a change to that file. You could use @kbd{a} to resurrect the
-file (see @pxref{Adding and removing files}).@refill
-
-@item Move away @var{file} - it is in the way
-For some reason CVS does not like the file @var{file}. Rename or remove
-it.@refill
-
-@item This repository is missing! Remove this dir manually.
-It is impossible to remove a directory in the CVS repository in a clean
-way. Someone have tried to remove one, and CVS gets confused. Remove
-your copy of the directory.@refill
-@end table
-
-
-@node Selected files, , File status, Buffer contents
-@comment node-name, next, previous, up
-
-@section Selected files
-@cindex Selected files
-@cindex Marked files
-@cindex File selection
-@cindex Active files
-
-Many of the commands works on the current set of @dfn{selected} files.
-
-@itemize @bullet
-@item
-If there are any files that are marked they constitute the set of
-selected files.@refill
-@item
-Otherwise, if the cursor points to a file, that file is the selected
-file.@refill
-@item
-Otherwise, if the cursor points to a directory, all the files in that
-directory that appears in the buffer are the selected files.
-@end itemize
-
-This scheme might seem a little complicated, but once one get used to
-it, it is quite powerful.
-
-@xref{Marking files} tells how you mark and unmark files.
-
-
-@node Commands, Customization, Buffer contents, Top
-@comment node-name, next, previous, up
-
-@chapter Commands
-
-@iftex
-This chapter describes all the commands that you can use in pcl-cvs.
-@end iftex
-@ifinfo
-The nodes in this menu contains explanations about all the commands that
-you can use in pcl-cvs. They are grouped together by type.
-@end ifinfo
-
-@menu
-* Updating the directory:: Commands to update the local directory
-* Movement commands:: How to move up and down in the buffer
-* Marking files:: How to mark files that other commands
- will later operate on.
-* Committing changes:: Checking in your modifications to the
- CVS repository.
-* Editing files:: Loading files into Emacs.
-* Getting info about files:: Display the log and status of files.
-* Adding and removing files:: Adding and removing files
-* Undoing changes:: Undoing changes
-* Removing handled entries:: Uninteresting lines can easily be removed.
-* Ignoring files:: Telling CVS to ignore generated files.
-* Viewing differences:: Commands to @samp{diff} different versions.
-* Invoking Ediff:: Running @samp{ediff} from @samp{*cvs*} buffer.
-* Invoking Emerge:: Running @samp{emerge} from @samp{*cvs*} buffer.
-* Reverting your buffers:: Reverting your buffers
-* Miscellaneous commands:: Miscellaneous commands
-@end menu
-
-
-@node Updating the directory, Movement commands, Commands, Commands
-@comment node-name, next, previous, up
-
-@section Updating the directory
-@findex cvs-update
-@findex cvs-mode-update-no-prompt
-@findex cvs-delete-lock
-@cindex Getting the *cvs* buffer
-@kindex g - Rerun @samp{cvs update}
-
-
-@table @kbd
-
-@item M-x cvs-update
-Run a @samp{cvs update} command. You will be asked for the directory in
-which the @samp{cvs update} will be run. The output will be parsed by
-pcl-cvs, and the result printed in the @samp{*cvs*} buffer (see
-@pxref{Buffer contents} for a description of the contents).@refill
-
-By default, @samp{cvs-update} will descend recursively into
-subdirectories. You can avoid that behavior by giving a prefix
-argument to it (e.g., by typing @kbd{C-u M-x cvs-update RET}).@refill
-
-All other commands in pcl-cvs requires that you have a @samp{*cvs*}
-buffer. This is the command that you use to get one.@refill
-
-CVS uses lock files in the repository to ensure the integrity of the
-data files in the repository. They might be left behind i.e. if a
-workstation crashes in the middle of a CVS operation. CVS outputs a
-message when it is waiting for a lock file to go away. Pcl-cvs will
-show the same message in the *cvs* buffer, together with instructions
-for deleting the lock files. You should normally not have to delete
-them manually --- just wait a little while and the problem should fix
-itself. But if the lock files doesn't disappear you can delete them
-with @kbd{M-x cvs-delete-lock RET}.@refill
-
-@item g
-This will run @samp{cvs update} again. It will always use the same
-buffer that was used with the previous @samp{cvs update}. Give a prefix
-argument to avoid descending into subdirectories. This runs the command
-@samp{cvs-mode-update-no-prompt}.@refill
-
-@item G
-This will run @samp{cvs update} and prompt for a new directory to
-update. This runs the command @samp{cvs-update}.@refill
-
-@end table
-
-
-@node Movement commands, Marking files, Updating the directory, Commands
-@comment node-name, next, previous, up
-
-@section Movement Commands
-@cindex Movement Commands
-@findex cookie-next-cookie
-@findex cookie-previous-cookie
-@kindex SPC - Move down one file
-@kindex C-n - Move down one file
-@kindex n - Move down one file
-@kindex C-p - Move up one file
-@kindex p - Move up on file
-
-You can use most normal Emacs commands to move forward and backward in
-the buffer. Some keys are rebound to functions that take advantage of
-the fact that the buffer is a pcl-cvs buffer:
-
-
-@table @kbd
-@item SPC
-@itemx C-n
-@itemx n
-These keys move the cursor one file forward, towards the end of the
-buffer (@code{cookie-next-cookie}).
-
-@item C-p
-@itemx p
-These keys move one file backward, towards the beginning of the buffer
-(@code{cookie-previous-cookie}).
-@end table
-
-
-@node Marking files, Committing changes, Movement commands, Commands
-@comment node-name, next, previous, up
-
-@section Marking files
-@cindex Selecting files (commands to mark files)
-@cindex Marking files
-@kindex m - marking a file
-@kindex M - marking all files
-@kindex u - unmark a file
-@kindex ESC DEL - unmark all files
-@kindex DEL - unmark previous file
-@findex cvs-mode-mark
-@findex cvs-mode-unmark
-@findex cvs-mode-mark-all-files
-@findex cvs-mode-unmark-all-files
-@findex cvs-mode-unmark-up
-
-Pcl-cvs works on a set of @dfn{selected files} (@pxref{Selected files}).
-You can mark and unmark files with these commands:
-
-@table @kbd
-@item m
-This marks the file that the cursor is positioned on. If the cursor is
-positioned on a directory all files in that directory will be marked.
-(@code{cvs-mode-mark}).
-
-@item u
-Unmark the file that the cursor is positioned on. If the cursor is on a
-directory, all files in that directory will be unmarked.
-(@code{cvs-mode-unmark}).@refill
-
-@item M
-Mark @emph{all} files in the buffer (@code{cvs-mode-mark-all-files}).
-
-@item @key{ESC} @key{DEL}
-Unmark @emph{all} files (@code{cvs-mode-unmark-all-files}).
-
-@item @key{DEL}
-Unmark the file on the previous line, and move point to that line
-(@code{cvs-mode-unmark-up}).
-@end table
-
-
-@node Committing changes, Editing files, Marking files, Commands
-@comment node-name, next, previous, up
-
-@section Committing changes
-@cindex Committing changes
-@cindex Ci
-@findex cvs-mode-commit
-@findex cvs-mode-changelog-commit
-@kindex c - commit files
-@kindex C - commit files with ChangeLog message
-@vindex cvs-erase-input-buffer (variable)
-@vindex cvs-auto-revert-after-commit (variable)
-@cindex Commit buffer
-@cindex Edit buffer
-@cindex Erasing commit message
-@cindex Reverting buffers after commit
-
-@table @kbd
-
-@item c
-All files that have a "need to be checked in"-marker (@pxref{Buffer
-contents}) can be checked in with the @kbd{c} command. It checks in all
-selected files (@pxref{Selected files}) (except those who lack the
-"ci"-marker - they are ignored). Pressing @kbd{c} causes
-@code{cvs-mode-commit} to be run.@refill
-
-When you press @kbd{c} you will get a buffer called
-@samp{*cvs-commit-message*}. Enter the log message for the file(s) in
-it. When you are ready you should press @kbd{C-c C-c} to actually
-commit the files (using @code{cvs-edit-done}).
-
-Normally the @samp{*cvs-commit-message*} buffer will retain the log
-message from the previous commit, but if the variable
-@code{cvs-erase-input-buffer} is set to a non-@code{nil} value the
-buffer will be erased. Point and mark will always be located around the
-entire buffer so that you can easily erase it with @kbd{C-w}
-(@samp{kill-region}).@refill
-
-If you are editing the files in your emacs an automatic
-@samp{revert-buffer} will be performed. (If the file contains
-@samp{$@asis{Id}$} keywords @samp{cvs commit} will write a new file with
-the new values substituted. The auto-revert makes sure that you get
-them into your buffer). The revert will not occur if you have modified
-your buffer, or if @samp{cvs-auto-revert-after-commit} is set to
-@samp{nil}.@refill
-
-@item C
-This is just like @samp{cvs-mode-commit}, except that it tries to
-provide appropriate default log messages by looking at the
-@samp{ChangeLog}s in the current directory. The idea is to write your
-ChangeLog entries first, and then use this command to commit your
-changes. Pressing @kbd{C} causes @code{cvs-mode-changelog-commit} to be
-run.@refill
-
-To select default log text, pcl-cvs:
-@itemize @minus
-@item
-finds the ChangeLogs for the files to be checked in;
-@item
-verifies that the top entry in the ChangeLog is on the current date and
-by the current user; if not, no default text is provided;
-@item
-search the ChangeLog entry for paragraphs containing the names of the
-files we're checking in; and finally
-@item
-uses those paragraphs as the default log text in the
-@samp{*cvs-commit-message*} buffer.
-@end itemize
-
-You can then commit the @samp{ChangeLog} file once per day without any
-log message.@refill
-
-@end table
-
-
-@node Editing files, Getting info about files, Committing changes, Commands
-@comment node-name, next, previous, up
-
-@section Editing files
-@cindex Editing files
-@cindex Finding files
-@cindex Loading files
-@cindex Dired
-@cindex Invoking dired
-@findex cvs-mode-find-file
-@findex cvs-mode-find-file-other-window
-@findex cvs-mode-add-change-log-entry-other-window
-@kindex f - find file or directory
-@kindex o - find file in other window
-@kindex A - add ChangeLog entry
-
-There are currently three commands that can be used to find a file (that
-is, load it into a buffer and start editing it there). These commands
-work on the line that the cursor is situated at. They ignore any marked
-files.
-
-@table @kbd
-@item f
-Find the file that the cursor points to. Run @samp{dired}
-@ifinfo
-(@pxref{Dired,,,Emacs})
-@end ifinfo
-if the cursor points to a directory (@code{cvs-mode-find-file}).@refill
-
-@item o
-Like @kbd{f}, but use another window
-(@code{cvs-mode-find-file-other-window}).@refill
-
-@item A
-Invoke @samp{add-change-log-entry-other-window} to edit a
-@samp{ChangeLog} file. The @samp{ChangeLog} will be found in the
-directory of the file the cursor points to.
-(@code{cvs-mode-add-change-log-entry-other-window}).@refill
-@end table
-
-
-@node Getting info about files, Adding and removing files, Editing files, Commands
-@comment node-name, next, previous, up
-
-@section Getting info about files
-@cindex Status (cvs command)
-@cindex Log (RCS/cvs command)
-@cindex Getting status
-@kindex l - run @samp{cvs log}
-@kindex s - run @samp{cvs status}
-@findex cvs-mode-log
-@findex cvs-mode-status
-
-Both of the following commands can be customized.
-@xref{Customization}.@refill
-
-@table @kbd
-@item l
-Run @samp{cvs log} on all selected files, and show the result in a
-temporary buffer (@code{cvs-mode-log}).
-
-@item s
-Run @samp{cvs status} on all selected files, and show the result in a
-temporary buffer (@code{cvs-mode-status}).
-@end table
-
-
-@node Adding and removing files, Undoing changes, Getting info about files, Commands
-@comment node-name, next, previous, up
-
-@section Adding and removing files
-@cindex Adding files
-@cindex Removing files
-@cindex Resurrecting files
-@cindex Deleting files
-@cindex Putting files under CVS control
-@kindex a - add a file
-@kindex r - remove a file
-@findex cvs-mode-add
-@findex cvs-mode-remove-file
-
-The following commands are available to make it easy to add and remove
-files from the CVS repository.
-
-@table @kbd
-@item a
-Add all selected files. This command can be used on @samp{Unknown}
-files (see @pxref{File status}). The status of the file will change to
-@samp{Added}, and you will have to use @kbd{c} (@samp{cvs-mode-commit}, see
-@pxref{Committing changes}) to really add the file to the
-repository.@refill
-
-This command can also be used on @samp{Removed} files (before you commit
-them) to resurrect them.
-
-Selected files that are neither @samp{Unknown} nor @samp{Removed} will
-be ignored by this command.
-
-The command that is run is @code{cvs-mode-add}.
-
-@item r
-This command removes the selected files (after prompting for
-confirmation). The files are @samp{rm}ed from your directory and
-(unless the status was @samp{Unknown}; @pxref{File status}) they will
-also be @samp{cvs remove}d. If the files were @samp{Unknown} they will
-disappear from the buffer. Otherwise their status will change to
-@samp{Removed}, and you must use @kbd{c} (@samp{cvs-mode-commit},
-@pxref{Committing changes}) to commit the removal.@refill
-
-The command that is run is @code{cvs-mode-remove-file}.
-@end table
-
-
-@node Undoing changes, Removing handled entries, Adding and removing files, Commands
-@comment node-name, next, previous, up
-
-@section Undoing changes
-@cindex Undo changes
-@cindex Flush changes
-@kindex U - undo changes
-@findex cvs-mode-undo-local-changes
-
-@table @kbd
-@item U
-If you have modified a file, and for some reason decide that you don't
-want to keep the changes, you can undo them with this command. It works
-by removing your working copy of the file and then getting the latest
-version from the repository (@code{cvs-mode-undo-local-changes}.
-@end table
-
-
-@node Removing handled entries, Ignoring files, Undoing changes, Commands
-@comment node-name, next, previous, up
-
-@section Removing handled entries
-@cindex Expunging uninteresting entries
-@cindex Uninteresting entries, getting rid of them
-@cindex Getting rid of uninteresting lines
-@cindex Removing uninteresting (processed) lines
-@cindex Handled lines, removing them
-@kindex x - remove processed entries
-@kindex C-k - remove selected entries
-@findex cvs-mode-remove-handled
-@findex cvs-mode-acknowledge
-
-@table @kbd
-@item x
-This command allows you to remove all entries that you have processed.
-More specifically, the lines for @samp{Updated} files (@pxref{File
-status} and files that have been checked in (@pxref{Committing changes})
-are removed from the buffer. If a directory becomes empty the heading
-for that directory is also removed. This makes it easier to get an
-overview of what needs to be done.
-
-The command is called @code{cvs-mode-remove-handled}. If
-@samp{cvs-auto-remove-handled} is set to non-@code{nil} this will
-automatically be performed after every commit.@refill
-
-@item C-k
-This command can be used for lines that @samp{cvs-mode-remove-handled} would
-not delete, but that you want to delete (@code{cvs-mode-acknowledge}).
-@end table
-
-
-@node Ignoring files, Viewing differences, Removing handled entries, Commands
-@comment node-name, next, previous, up
-
-@section Ignoring files
-@kindex i - ignoring files
-@findex cvs-mode-ignore
-
-@table @kbd
-@item i
-Arrange so that CVS will ignore the selected files. The file names are
-added to the @file{.cvsignore} file in the corresponding directory. If
-the @file{.cvsignore} doesn't exist it will be created.
-
-The @file{.cvsignore} file should normally be added to the repository,
-but you could ignore it also if you like it better that way.
-
-This runs @code{cvs-mode-ignore}.
-@end table
-
-
-@node Viewing differences, Invoking Ediff, Ignoring files, Commands
-@comment node-name, next, previous, up
-
-@section Viewing differences
-@cindex Diff
-@cindex Ediff
-@cindex Invoking ediff
-@cindex Conflicts, how to resolve them
-@cindex Viewing differences
-@kindex d - run @samp{cvs diff}
-@kindex b - diff backup file
-@findex cvs-mode-diff-cvs
-@findex cvs-mode-diff-backup
-@vindex cvs-diff-ignore-marks (variable)
-
-@table @kbd
-@item d
-Display a @samp{cvs diff} between the selected files and the RCS version
-that they are based on. @xref{Customization} describes how you can send
-flags to @samp{cvs diff}. If @var{cvs-diff-ignore-marks} is set to a
-non-@code{nil} value or if a prefix argument is given (but not both) any
-marked files will not be considered to be selected.
-(@code{cvs-mode-diff-cvs}).@refill
-
-@item b
-If CVS finds a conflict while merging two versions of a file (during a
-@samp{cvs update}, @pxref{Updating the directory}) it will save the
-original file in a file called @file{.#@var{FILE}.@var{VERSION}} where
-@var{FILE} is the name of the file, and @var{VERSION} is the RCS version
-number that your file was based on.@refill
-
-With the @kbd{b} command you can run a @samp{diff} on the files
-@file{.#@var{FILE}.@var{VERSION}} and @file{@var{FILE}}. You can get a
-context- or Unidiff by setting @samp{cvs-diff-flags} -
-@pxref{Customization}. This command only works on files that have
-status @samp{Conflict} or @samp{Merged}.@refill
-
-If @var{cvs-diff-ignore-marks} is set to a non-@code{nil} value or if a
-prefix argument is given (but not both) any marked files will not be
-considered to be selected. (@code{cvs-mode-diff-backup}).@refill
-@end table
-
-
-@node Invoking Ediff, Invoking Emerge, Viewing differences, Commands
-@comment node-name, next, previous, up
-
-@section Running ediff
-@cindex Ediff
-@cindex Invoking ediff
-@cindex Viewing differences
-@cindex Conflicts, resolving
-@cindex Resolving conflicts
-@kindex e - invoke @samp{ediff}
-@findex cvs-mode-ediff
-@findex run-ediff-from-cvs-buffer
-@findex cvs-old-ediff-interface
-
-@table @kbd
-@item e
-This command works
-slightly different depending on the version of @samp{ediff} and the file
-status.@refill
-
-With modern versions of @samp{ediff}, this command invokes
-@samp{run-ediff-from-cvs-buffer} on one file.@refill
-
-@strong{Note:} When the file status is @samp{Merged} or @samp{Conflict},
-CVS has already performed a merge. The resulting file is not used in
-any way if you use this command. If you use the @kbd{q} command inside
-@samp{ediff} (to successfully terminate a merge) the file that CVS
-created will be overwritten.@refill
-
-Older versions of @samp{ediff} use an interface similar to
-@samp{emerge}. The function @samp{cvs-old-ediff-interface} is invoked
-if the version of @samp{ediff} you have doesn't support
-@samp{run-ediff-from-cvs-buffer}. These older versions do not support
-merging of revisions.@refill
-
-@table @asis
-@item @samp{Modified}
-Run @samp{ediff-files} with your working file as file A, and the latest
-revision in the repository as file B.
-
-@item @samp{Merged}
-@itemx @samp{Conflict}
-Run @samp{ediff-files3} with your working file (as it was prior to your
-invocation of @samp{cvs-update}) as file A, the latest revision in the
-repository as file B, and the revision that you based your local
-modifications on as ancestor.
-
-@item @samp{Updated}
-@itemx @samp{Patched}
-Run @samp{ediff-files} with your working file as file A, and a given
-revision in the repository as file B. You are prompted for the revision
-to ediff against, and you may specify either a tag name or a numerical
-revision number (@pxref{Getting info about files}).
-@end table
-
-@end table
-
-@node Invoking Emerge, Reverting your buffers, Invoking Ediff, Commands
-@comment node-name, next, previous, up
-
-@section Running emerge
-@cindex Emerge
-@cindex Ediff
-@cindex Viewing differences
-@cindex Invoking emerge
-@cindex Conflicts, resolving
-@cindex Resolving conflicts
-@kindex E - invoke @samp{emerge}
-@findex cvs-mode-emerge
-
-@table @kbd
-@item E
-Invoke @samp{emerge} on one file. This command works slightly different
-depending on the file status.
-
-@table @asis
-@item @samp{Modified}
-Run @samp{emerge-files} with your working file as file A, and the latest
-revision in the repository as file B.
-
-@item @samp{Merged}
-@itemx @samp{Conflict}
-Run @samp{emerge-files-with-ancestor} with your working file (as it was
-prior to your invocation of @samp{cvs-update}) as file A, the latest
-revision in the repository as file B, and the revision that you based
-your local modifications on as ancestor.
-@end table
-
-@strong{Note:} When the file status is @samp{Merged} or @samp{Conflict},
-CVS has already performed a merge. The resulting file is not used in
-any way if you use this command. If you use the @kbd{q} command inside
-@samp{emerge} (to successfully terminate the merge) the file that CVS
-created will be overwritten.
-
-@end table
-
-
-@node Reverting your buffers, Miscellaneous commands, Invoking Emerge, Commands
-@comment node-name, next, previous, up
-
-@section Reverting your buffers
-@findex cvs-mode-revert-updated-buffers
-@kindex R - revert buffers
-@cindex Syncing buffers
-@cindex Reverting buffers
-
-@table @kbd
-@item R
-If you are editing (or just viewing) a file in a buffer, and that file
-is changed by CVS during a @samp{cvs-update}, all you have to do is type
-@kbd{R} in the *cvs* buffer to read in the new versions of the
-files.@refill
-
-All files that are @samp{Updated}, @samp{Merged} or in @samp{Conflict}
-are reverted from the disk. Any other files are ignored. Only files
-that you were already editing are read.@refill
-
-An error is signalled if you have modified the buffer since it was last
-changed. (@code{cvs-mode-revert-updated-buffers}).@refill
-@end table
-
-
-@node Miscellaneous commands, , Reverting your buffers, Commands
-@comment node-name, next, previous, up
-
-@section Miscellaneous commands
-@findex cvs-byte-compile-files
-@cindex Recompiling elisp files
-@cindex Byte compilation
-@cindex Getting rid of lock files
-@cindex Lock files
-@kindex q - bury the *cvs* buffer
-@findex bury-buffer
-
-@table @kbd
-@item M-x cvs-byte-compile-files
-Byte compile all selected files that end in .el.
-
-@item M-x cvs-delete-lock
-This command can be used in any buffer, and deletes the lock files that
-the *cvs* buffer informs you about. You should normally never have to
-use this command since CVS tries very carefully to always remove the
-lock files itself.
-
-You can only use this command when a message in the *cvs* buffer tells
-you so. You should wait a while before using this command in case
-someone else is running a cvs command.
-
-@item q
-Bury the *cvs* buffer. (@code{bury-buffer}).
-
-@end table
-
-
-@node Customization, Future enhancements, Commands, Top
-@comment node-name, next, previous, up
-
-@chapter Customization
-@vindex cvs-erase-input-buffer (variable)
-@vindex cvs-inhibit-copyright-message (variable)
-@vindex cvs-diff-flags (variable)
-@vindex cvs-diff-ignore-marks (variable)
-@vindex cvs-log-flags (variable)
-@vindex cvs-status-flags (variable)
-@vindex cvs-auto-remove-handled (variable)
-@vindex cvs-update-prog-output-skip-regexp (variable)
-@vindex cvs-cvsroot (variable)
-@vindex TMPDIR (environment variable)
-@vindex cvs-auto-revert-after-commit (variable)
-@vindex cvs-commit-buffer-require-final-newline (variable)
-@vindex cvs-sort-ignore-file (variable)
-@cindex Inhibiting the Copyright message.
-@cindex Copyright message, getting rid of it
-@cindex Getting rid of the Copyright message.
-@cindex Customization
-@cindex Variables, list of all
-@cindex Erasing the input buffer
-@cindex Context diff, how to get
-@cindex Unidiff, how to get
-@cindex Automatically remove handled files
-@cindex -u option in modules file
-@cindex Modules file (-u option)
-@cindex Update program (-u option in modules file)
-@cindex Reverting buffers after commit
-@cindex Require final newline
-@cindex Automatically inserting newline
-@cindex Commit message, inserting newline
-@cindex Sorting the .cvsignore file
-@cindex .cvsignore file, sorting
-@cindex Automatically sorting .cvsignore
-
-If you have an idea about any customization that would be handy but
-isn't present in this list, please tell me! @xref{Bugs} for info on how
-to reach me.@refill
-
-@table @samp
-@item cvs-erase-input-buffer
-If set to anything else than @code{nil} the edit buffer will be erased
-before you write the log message (@pxref{Committing changes}).
-
-@item cvs-inhibit-copyright-message
-The copyright message that is displayed on startup can be annoying after
-a while. Set this variable to @samp{t} if you want to get rid of it.
-(But don't set this to @samp{t} in the system defaults file - new users
-should see this message at least once).
-
-@item cvs-diff-flags
-A list of strings to pass as arguments to the @samp{cvs diff} and
-@samp{diff} programs. This is used by @samp{cvs-mode-diff-cvs} and
-@samp{cvs-mode-diff-backup} (key @kbd{b}, @pxref{Viewing differences}). If
-you prefer the Unidiff format you could add this line to your
-@file{.emacs} file:@refill
-
-@example
-(setq cvs-diff-flags '("-u"))
-@end example
-
-@item cvs-diff-ignore-marks
-If this variable is non-@code{nil} or if a prefix argument is given (but
-not both) to @samp{cvs-mode-diff-cvs} or @samp{cvs-mode-diff-backup}
-marked files are not considered selected.
-
-@item cvs-log-flags
-List of strings to send to @samp{cvs log}. Used by @samp{cvs-mode-log}
-(key @kbd{l}, @pxref{Getting info about files}).
-
-@item cvs-status-flags
-List of strings to send to @samp{cvs status}. Used by @samp{cvs-mode-status}
-(key @kbd{s}, @pxref{Getting info about files}).
-
-@item cvs-auto-remove-handled
-If this variable is set to any non-@code{nil} value
-@samp{cvs-mode-remove-handled} will be called every time you check in
-files, after the check-in is ready. @xref{Removing handled
-entries}.@refill
-
-@item cvs-auto-revert-after-commit
-If this variable is set to any non-@samp{nil} value any buffers you have
-that visit a file that is committed will be automatically reverted.
-This variable is default @samp{t}. @xref{Committing changes}.@refill
-
-@item cvs-update-prog-output-skip-regexp
-The @samp{-u} flag in the @file{modules} file can be used to run a command
-whenever a @samp{cvs update} is performed (see cvs(5)). This regexp
-is used to search for the last line in that output. It is normally set
-to @samp{"$"}. That setting is only correct if the command outputs
-nothing. Note that pcl-cvs will get very confused if the command
-outputs @emph{anything} to @samp{stderr}.
-
-@item cvs-cvsroot
-This variable can be set to override @samp{CVSROOT}. It should be a
-string. If it is set then everytime a cvs command is run it will be
-called as @samp{cvs -d @var{cvs-cvsroot}@dots{}} This can be useful if
-your site has several repositories.
-
-@item TMPDIR
-Pcl-cvs uses this @emph{environment variable} to decide where to put the
-temporary files it needs. It defaults to @file{/tmp} if it is not set.
-
-@item cvs-commit-buffer-require-final-newline
-When you enter a log message in the @samp{*cvs-commit-message*} buffer
-pcl-cvs will normally automatically insert a trailing newline, unless
-there already is one. This behavior can be controlled via
-@samp{cvs-commit-buffer-require-final-newline}. If it is @samp{t} (the
-default behavior), a newline will always be appended. If it is
-@samp{nil}, newlines will never be appended. Any other value causes
-pcl-cvs to ask the user whenever there is no trailing newline in the
-commit message buffer.
-
-@item cvs-sort-ignore-file
-If this variable is set to any non-@samp{nil} value the
-@file{.cvsignore} will always be sorted whenever you use
-@samp{cvs-mode-ignore} to add a file to it. This option is on by
-default.
-
-@end table
-
-
-@node Future enhancements, Bugs, Customization, Top
-@comment node-name, next, previous, up
-
-@chapter Future enhancements
-@cindex Enhancements
-
-Pcl-cvs is still under development and needs a number of enhancements to
-be called complete. Below is my current wish-list for future releases
-of pcl-cvs. Please, let me know which of these features you want most.
-They are listed below in approximately the order that I currently think
-I will implement them in.
-
-@itemize @bullet
-@item
-Rewritten parser code. There are many situations where pcl-cvs will
-fail to recognize the output from CVS. The situation could be greatly
-increased.
-
-@item
-@samp{cvs-status}. This will run @samp{cvs status} in a directory and
-produce a buffer that looks pretty much like the current *cvs* buffer.
-That buffer will include information for all version-controlled files.
-(There will be a simple keystroke to remove all "uninteresting" files,
-that is, files that are "Up-to-date"). In this new buffer you will be
-able to update a file, commit a file, et c. The big win with this is
-that you will be able to watch the differences between your current
-working file and the head revision in the repository before you update
-the file, and you can then choose to update it or let it wait for a
-while longer.
-
-@item
-Log mode. When this mode is finished you will be able to move around
-(using @kbd{n} and @kbd{p}) between the revisions of a file, mark two of
-them, and run a diff between them. You will be able to hide branches
-(similar to the way you can hide sub-paragraphs in outline-mode) and do
-merges between revisions. Other ideas about this are welcome.
-
-@item
-The current model for marks in the *cvs* buffer seems to be confusing.
-I am considering to use the VM model instead, where marks are normally
-inactive. To activate the mark, you issue a command like
-@samp{cvs-mode-next-command-uses-marks}. I might implement a flag so
-that you can use either version. Feedback on this before I start coding
-it is very welcome.
-
-@item
-It should be possible to run commands such as @samp{cvs log}, @samp{cvs
-status} and @samp{cvs commit} directly from a buffer containing a file,
-instead of having to @samp{cvs-update}. If the directory contains many
-files the @samp{cvs-update} can take quite some time, especially on a
-slow machine. I planed to put these kind of commands on the prefix
-@kbd{C-c C-v}, but that turned out to be used by for instance c++-mode.
-If you have any suggestions for a better prefix key, please let me know.
-
-@item
-Increased robustness. For instance, you can not currently press
-@kbd{C-g} when you are entering the description of a file that you are
-adding without confusing pcl-cvs.
-
-@item
-Support for multiple active *cvs* buffers.
-
-@item
-Dired support. I have an experimental @file{dired-cvs.el} that works
-together with CVS 1.2. Unfortunately I wrote it on top of a
-non-standard @file{dired.el}, so it must be rewritten.@refill
-
-@item
-An ability to send user-supplied options to all the cvs commands.
-
-@item
-Pcl-cvs is not at all clever about what it should do when @samp{cvs
-update} runs a program (due to the @samp{-u} option in the
-@file{modules} file --- see @samp{cvs(5)}). The current release uses a
-regexp to search for the end. At the very least that regexp should be
-configured for different modules. Tell me if you have any idea about
-what is the right thing to do. In a perfect world the program should
-also be allowed to print to @samp{stderr} without causing pcl-cvs to
-crash.
-@end itemize
-
-
-If you miss something in this wish-list, let me know! I don't promise
-that I will write it, but I will at least try to coordinate the efforts
-of making a good Emacs front end to CVS. See @xref{Bugs} for
-information about how to reach me.@refill
-
-So far, I have written most of pcl-cvs in my all-to-rare spare time. If
-you want pcl-cvs to be developed faster you can write a contract with
-Signum Support to do the extension. You can reach Signum Support by
-email to @samp{info@@signum.se} or via mail to Signum Support AB, Box
-2044, S-580 02 Linkoping, Sweden. Phone: +46 (0) 13 - 21 46 00. Fax:
-+46 (0) 13 - 21 47 00.
-
-
-@node Bugs, COPYING, Future enhancements, Top
-@comment node-name, next, previous, up
-
-@chapter Bugs (known and unknown)
-@cindex Reporting bugs and ideas
-@cindex Bugs, how to report them
-@cindex Author, how to reach
-@cindex Email to the author
-@cindex Known bugs
-@cindex Bugs, known
-@cindex FAQ
-@cindex Problems, list of common
-
-If you find a bug or misfeature, don't hesitate to tell me! Send email
-to @samp{ceder@@lysator.liu.se}.
-
-If you have ideas for improvements, or if you have written some
-extensions to this package, I would like to hear from you. I hope that
-you find this package useful!
-
-Below is a partial list of currently known problems with pcl-cvs version
-1.05.
-
-@table @asis
-@item Commit causes Emacs to hang
-Emacs waits for the @samp{cvs commit} command to finish before you can
-do anything. If you start a background job from the loginfo file you
-must take care that it closes @samp{stdout} and @samp{stderr} if you do
-not want to wait for it. (You do that with @samp{background-command &>-
-2&>- &} if you are starting @samp{background-command} from a
-@samp{/bin/sh} shell script).
-
-Your emacs will also hang if there was a lock file in the repository.
-In this case you can type @kbd{C-g} to get control over your emacs
-again.
-
-@item Name clash in Emacs 19
-This is really a bug in Elib or the Emacs 19 distribution. Both Elib and
-Emacs 19.6 through at least 19.10 contains a file named
-@file{cookie.el}. One of the files will have to be renamed, and we are
-currently negotiating about which of the files to rename.
-
-@item Commands while cvs-update is running
-It is possible to type commands in the *cvs* buffer while the update is
-running, but error messages is all that you will get. The error
-messages should be better.
-
-@item Unexpected output from CVS
-Unexpected output from CVS confuses pcl-cvs. It will currently create a
-bug report that you can mail to me. It should do something more
-civilized.
-@end table
-
-
-@node COPYING, Function and Variable Index, Bugs, Top
-@comment node-name, next, previous, up
-
-@appendix GNU GENERAL PUBLIC LICENSE
-@c @include gpl.texinfo
-
-
-@node Function and Variable Index, Concept Index, COPYING, Top
-@comment node-name, next, previous, up
-
-@unnumbered Function and Variable Index
-
-@printindex fn
-
-
-@node Concept Index, Key Index, Function and Variable Index, Top
-@comment node-name, next, previous, up
-
-@unnumbered Concept Index
-
-@printindex cp
-
-
-@node Key Index, , Concept Index, Top
-@comment node-name, next, previous, up
-
-@unnumbered Key Index
-
-@printindex ky
-
-@summarycontents
-@contents
-@bye
diff --git a/gnu/usr.bin/cvs/BUGS b/gnu/usr.bin/cvs/BUGS
deleted file mode 100644
index 3ad13a82828d..000000000000
--- a/gnu/usr.bin/cvs/BUGS
+++ /dev/null
@@ -1,248 +0,0 @@
-* `cvs checkout -d nested/dir/path <module>' just doesn't work. The
- simpler version -- `cvs checkout -d single-dir <module>' works,
- however.
-
-
-* CVS leaves .#mumble files around when a conflict occurs. (Note:
- this is intentional and is documented in doc/cvs.texinfo. Of course
- whether it is a good idea is a separate question).
-
-
-* pcl-cvs doesn't like it when you try to check in a file which isn't
- up-to-date. The messages produced by the server perhaps don't match
- what pcl-cvs is looking for.
-
-
-* From: Roland McGrath <roland@gnu.ai.mit.edu>
- To: Cyclic CVS Hackers <cyclic-cvs@cyclic.com>
- Subject: weird bug
- Date: Sat, 25 Mar 1995 16:41:41 -0500
- X-Windows: Even your dog won't like it.
-
- I just noticed some droppings on my disk from what must be a pretty weird
- bug in remote CVS.
-
- In my home directory on a repository machine I use, I find:
-
- drwxr-xr-x 4 roland staff 512 Mar 7 14:08 cvs-serv28962
- drwxr-xr-x 4 roland staff 512 Mar 7 14:11 cvs-serv28978
- drwxr-xr-x 4 roland staff 512 Mar 7 15:13 cvs-serv29141
-
- OK, so these are leftover cruft from some cvs run that got aborted.
- Well, it should clean up after itself, but so what.
-
- The last one is pretty dull; the real weirdness is the contents of the
- first two directories.
-
- duality 77 # ls -RF cvs-serv28978/
- CVS/ cvs-serv28978/
-
- cvs-serv28978/CVS:
- Entries Repository
-
- cvs-serv28978/cvs-serv28978:
- arpa/
-
- cvs-serv28978/cvs-serv28978/arpa:
- CVS/ cvs-serv28978/
-
- cvs-serv28978/cvs-serv28978/arpa/CVS:
- Entries Repository
-
- cvs-serv28978/cvs-serv28978/arpa/cvs-serv28978:
- assert/
-
- cvs-serv28978/cvs-serv28978/arpa/cvs-serv28978/assert:
- CVS/ cvs-serv28978/
-
- cvs-serv28978/cvs-serv28978/arpa/cvs-serv28978/assert/CVS:
- Entries Repository
-
- cvs-serv28978/cvs-serv28978/arpa/cvs-serv28978/assert/cvs-serv28978:
- bare/
-
- cvs-serv28978/cvs-serv28978/arpa/cvs-serv28978/assert/cvs-serv28978/bare:
- CVS/ cvs-serv28978/
-
- cvs-serv28978/cvs-serv28978/arpa/cvs-serv28978/assert/cvs-serv28978/bare/CVS:
- Entries Repository
-
- cvs-serv28978/cvs-serv28978/arpa/cvs-serv28978/assert/cvs-serv28978/bare/cvs-serv28978:
- conf/
-
- cvs-serv28978/cvs-serv28978/arpa/cvs-serv28978/assert/cvs-serv28978/bare/cvs-serv28978/conf:
- CVS/ cvs-serv28978/
-
- cvs-serv28978/cvs-serv28978/arpa/cvs-serv28978/assert/cvs-serv28978/bare/cvs-serv28978/conf/CVS:
- Entries Repository
-
- cvs-serv28978/cvs-serv28978/arpa/cvs-serv28978/assert/cvs-serv28978/bare/cvs-serv28978/conf/cvs-serv28978:
- crypt/
-
- cvs-serv28978/cvs-serv28978/arpa/cvs-serv28978/assert/cvs-serv28978/bare/cvs-serv28978/conf/cvs-serv28978/crypt:
- CVS/ cvs-serv28978/
-
- cvs-serv28978/cvs-serv28978/arpa/cvs-serv28978/assert/cvs-serv28978/bare/cvs-serv28978/conf/cvs-serv28978/crypt/CVS:
- Entries Repository
-
- cvs-serv28978/cvs-serv28978/arpa/cvs-serv28978/assert/cvs-serv28978/bare/cvs-serv28978/conf/cvs-serv28978/crypt/cvs-serv28978:
- csu/
-
- cvs-serv28978/cvs-serv28978/arpa/cvs-serv28978/assert/cvs-serv28978/bare/cvs-serv28978/conf/cvs-serv28978/crypt/cvs-serv28978/csu:
- CVS/ cvs-serv28978/
-
- cvs-serv28978/cvs-serv28978/arpa/cvs-serv28978/assert/cvs-serv28978/bare/cvs-serv28978/conf/cvs-serv28978/crypt/cvs-serv28978/csu/CVS:
- Entries Repository
-
- cvs-serv28978/cvs-serv28978/arpa/cvs-serv28978/assert/cvs-serv28978/bare/cvs-serv28978/conf/cvs-serv28978/crypt/cvs-serv28978/csu/cvs-serv28978:
- ctype/
-
- cvs-serv28978/cvs-serv28978/arpa/cvs-serv28978/assert/cvs-serv28978/bare/cvs-serv28978/conf/cvs-serv28978/crypt/cvs-serv28978/csu/cvs-serv28978/ctype:
- CVS/ cvs-serv28978/
-
- [...]
-
- ls: cvs-serv28978/cvs-serv28978/arpa/cvs-serv28978/assert/cvs-serv28978/bare/cvs-serv28978/conf/cvs-serv28978/crypt/cvs-serv28978/csu/cvs-serv28978/ctype/cvs-serv28978/dirent/cvs-serv28978/elf/cvs-serv28978/gnu/cvs-serv28978/gnulib/cvs-serv28978/grp/cvs-serv28978/hurd/cvs-serv28978/hurd/hurd/cvs-serv28978/inet/cvs-serv28978/inet/arpa/cvs-serv28978/inet/netinet[...]/cvs-serv28978/posix/cvs-serv28978/posix/glob/cvs-serv28978/posix/gnu/cvs-serv28978/posix/sys/cvs-serv28978/protocols/cvs-serv28978/pwd/cvs-serv28978/resolv/cvs-serv28978/resolv/arpa/cvs-serv28978/resolv/sys/cvs-serv28978/resource/cvs-serv28978/resource/sys/cvs-serv28978/rpc/cvs-serv28978/setjmp/cvs-serv28978/signal/cvs-serv28978/signal/sys/cvs-serv28978/socket/cvs-serv28978/socket: File name too long
- cvs-serv28978/cvs-serv28978/arpa/cvs-serv28978/assert/cvs-serv28978/bare/cvs-serv28978/conf/cvs-serv28978/crypt/cvs-serv28978/csu/cvs-serv28978/ctype/cvs-serv28978/dirent/cvs-serv28978/elf/cvs-serv28978/gnu/cvs-serv28978/gnulib/cvs-serv28978/grp/cvs-serv28978/hurd/cvs-serv28978/hurd/hurd/cvs-serv28978/inet/cvs-serv28978/inet/arpa/cvs-serv28978/inet/netinet[...]/cvs-serv28978/posix/glob/cvs-serv28978/posix/gnu/cvs-serv28978/posix/sys/cvs-serv28978/protocols/cvs-serv28978/pwd/cvs-serv28978/resolv/cvs-serv28978/resolv/arpa/cvs-serv28978/resolv/sys/cvs-serv28978/resource/cvs-serv28978/resource/sys/cvs-serv28978/rpc/cvs-serv28978/setjmp/cvs-serv28978/signal/cvs-serv28978/signal/sys/cvs-serv28978/socket/cvs-serv28978:
-
-
-* From: billr@mpd.tandem.com (Bill Robertson)
- Subject: Problem with rtag and the -D option
- Date: Fri, 17 Mar 1995 10:53:29 -0600 (CST)
-
- I have been trying to use the -D option to specify a date for tagging, but
- rtag does not recognize the -D option. It is documented to do so and I've
- tested the use of -D with cvs update and cvs diff and it works fine there.
-
-
-* We need some version numbers really badly. Are there some
- (and Charles Hannum is just not including them in his reports), or do
- we simply have no reliable way to distinguish between the various
- versions of rCVS people on the list are running?
-
- Now that I think of it, version numbers present a problem when
- people can update their sources anytime and rebuild. I think the
- solution is to increment a minor version number *every* time a bug is
- fixed, so we can identify uniquely what someone is running when they
- submit a report. This implies recording the version increments in the
- ChangeLog; that way we can just look to see where a particular version
- lies in relation to the flow of changing code.
-
- Should we be doing same with Guppy? I guess not -- it's only
- important when you have people who are updating directly from your
- development tree, which is the case with the remote-cvs folks.
-
- Thoughts?
-
-
-* (Charles Hannum <mycroft@ai.mit.edu>) has these bugs:
-
- I just tossed remote CVS at a fairly large source tree that I already
- had, and noticed a few problems:
-
- 1) server.c assumes that /usr/tmp is a valid default for the place to
- store files uploaded from the client. There are a number of systems
- that now use /var/tmp. These should probably be detected by autoconf.
-
- 2) The server deals rather ungracefully with the tmp directory
- becoming full.
-
- 3) There's some oddness with relative paths in Repository files that
- causes the directory prefix to be added twice; e.g. if I have CVSROOT
- set to `machine:/this/dir', and I try to update in a directory whose
- Repository file says `src/bin', the server looks in
- `/this/dir/machine:/this/dir/src/bin'.
-
-* From: "Charles M. Hannum" <mycroft@ai.mit.edu>
- To: jimb@duality.gnu.ai.mit.edu, roland@duality.gnu.ai.mit.edu
- Subject: Serious flaw in remote CVS
- Date: Wed, 22 Feb 1995 20:54:36 -0500
-
- I just found a major flaw in the current implementation. Because the
- sockets are not changed to non-blocking mode, write(2)s can hang. In
- some cases, this happens on both sides at the same time, with the
- socket buffers full in both directions. This causes a deadlock,
- because both processes are stuck in I/O wait and thus never drain
- their input queues.
-
- Until this is fixed, I can't use it. I'll look at the problem myself
- at some point, but I don't know when.
-
-
- From: "Charles M. Hannum" <mycroft@ai.mit.edu>
- To: remote-cvs@cyclic.com
- Cc: jimb@totoro.bio.indiana.edu
- Subject: Re: forwarded message from Charles M. Hannum
- Date: Wed, 22 Feb 1995 22:07:07 -0500
-
- FYI, this happened because the tmp directory on the server became
- full. Somehow the server started interpreting the files the client
- was sending as commands, and started spewing tons of errors.
- Apparently the errors are sent with blocking I/O, or something, and
- thus allowed the deadlock to happen.
-
-
-* From: "Charles M. Hannum" <mycroft@ai.mit.edu>
- To: remote-cvs@cyclic.com
- Subject: Regarding that relative path problem
- Date: Thu, 23 Feb 1995 02:41:51 -0500
-
- This is actually more serious. If you have `bar.com:/foo' as your CVS
- root directory, then:
-
- 1) When you check things out, the Repository files will contain
- `/foo/...' (i.e. without the machine name), which makes little sense.
-
- 2) If you instead have a relative path, when the Repository file is
- read, `bar.com:/foo' is prepended. This is sent to the server, but
- confuses it, because it's not expecting the machine name to be
- prepended.
-
- A slightly klugy fix would be to have the client prepend the machine
- name when writing a new Repository file, and strip it off before
- sending one to the server. This would be backward-compatible with the
- current arrangement.
-
-
-* From: "Charles M. Hannum" <mycroft@ai.mit.edu>
- To: remote-cvs@cyclic.com
- Subject: Still one more bug
- Date: Sat, 25 Feb 1995 17:01:15 -0500
-
- mycroft@duality [1]; cd /usr/src/lib/libc
- mycroft@duality [1]; cvs diff -c2 '-D1 day ago' -Dnow
- cvs server: Diffing .
- cvs server: Diffing DB
- cvs [server aborted]: could not chdir to DB: No such file or directory
- mycroft@duality [1];
-
- `DB' is an old directory, which no longer has files in it, and is
- removed automatically when I use the `-P' option to checkout.
-
- This error doesn't occur when run locally.
-
- P.S. Is anyone working on fixing these bugs?
-
-
-* From: Roland McGrath <roland@gnu.ai.mit.edu>
- To: Cyclic CVS Hackers <cyclic-cvs@cyclic.com>
- Subject: bizarre failure mode
- Date: Tue, 7 Mar 95 14:17:28 -0500
-
- This is pretty weird:
-
- CVS_SERVER='TMPDIR=. /usr/local/bin/cvs' ../cvs-build/src/cvs update -q
- cvs [server aborted]: could not get working directory: Result too large
- [Exit 1]
- asylum 29 % grep 'Result too large' /usr/include/sys/errno.h
- #define ERANGE 34 /* Result too large */
-
- Now, getcwd fails with ERANGE when the buffer is too small. But I don't
- know why that would be the case; I don't think there are exceptionally long
- directory names involved. It would be robust to notice ERANGE and use a
- bigger buffer. But I suspect something weirder is going on.
-
- The repository in question in duality.gnu.ai.mit.edu:/gd4/gnu/cvsroot/libc.
-
- Send me a PGP-signed message if you want the password to use the machine
- where the problem showed up.
diff --git a/gnu/usr.bin/cvs/FAQ b/gnu/usr.bin/cvs/FAQ
deleted file mode 100644
index 84d4a3aa5fb0..000000000000
--- a/gnu/usr.bin/cvs/FAQ
+++ /dev/null
@@ -1,10006 +0,0 @@
-
-Archive-name: cvs-faq
-Hand Revision: 3.5 <<== Include this in your comments
-Last Updated: 1995/03/09
-$Revision: 1.4 $
-$Date: 1995/10/02 23:13:07 $
-
-===========================================================================
-== Frequently Asked Questions about CVS (The Concurrent Versions System) ==
-===========================================================================
-
- This document attempts to answer questions posed by users of CVS.
-
- CVS installers, administrators and maintainers looking for info on
- system setup should read the section entitled "Installing CVS".
-
-
- Disclaimer:
-
- Although an attempt has been made to ensure the veracity of the
- following material, no responsibility is assumed for any use, or
- for any consequences resulting from any use, of the information
- contained herein. No guarantee of suitability for any purpose
- is offered or implied. Nothing in this document may be assumed
- to represent the employers of its contributors.
-
- I also might have slipped in a whopper or two to see if you are
- paying attention. ;-) In other words, don't bet the house on
- anything you read here unless you have checked it out yourself.
-
-
-
- Send questions and answers (along with additions to, subtractions
- from, and divisions of existing questions -- no multiplications,
- square roots, or transcendental functions, my cabinet is full of them)
- to the author, who wrote all unattributed text: (Does it always
- feel strange to refer to oneself in the third person?)
-
- David G. Grubbs <dgg@world.std.com>
-
-
- Major revisions contain enough alterations to render change markers
- meaningless. (Major revisions are those with a final digit of '0',
- such as 2.0 or 3.0.) To help readers of previous versions of this
- document, minor revisions will be annotated:
-
- Change markers: Column 1 will contain a:
-
- '-' for a Question that has changed.
- '=' for an Answer that has changed.
- '#' for an entry with changes to both Question and Answer.
- '+' for a newly added Question and Answer.
-
-
- Trivial changes, such as question reordering or spelling and grammar
- corrections are not marked. Deleted questions will simply disappear,
- as will any question that can be answered by "get the latest release".
-
- Editorial comments are delimited by pairs of "[[" & "]]". They
- contain either references to the (usually unfinished) nature of the
- FAQ entry itself, version-specific comments to be removed (or
- altered) when new revisions of CVS are released or snide remarks from
- the editor.
-
- If you plan to do anything with this document other than:
-
- - Read it.
- - Redistribute the whole document along with the date and revision.
- - Post sections as answers to CVS questions (as long as you
- identify it as coming from the FAQ.)
-
- talk to the author first.
-
-
-
-============================================
-== Section 0 ==== Introduction ====
-============================================
-
-The questions in this document come from many sources in many forms. Some
-are simple, some verbose. A few are difficult, but all of them have been
-asked of the author at one time or another. Some questions are really
-three or more different problems rolled into one plaintive cry for help.
-Others reveal one of the bugs or weaknesses of CVS.
-
-CVS addresses some difficult problems to which there are no perfect
-solutions. CVS also changes over time as new features are required.
-
-Therefore, the questions are about a complicated moving target.
-
-Though in most cases I've tried to provide the simplest answer I can
-think of, some of the *questions* are difficult to follow. If you
-aren't using CVS regularly, don't expect to understand everything.
-
-A Frequently Asked Questions document is not a substitute for the man page
-or any other documentation. It is an attempt to answer questions.
-
-You should also keep in mind that FAQs are not really intended to be
-read in their entirety like a text book. You should use "grep" or
-your editor's search capability to hunt for keywords and read the
-sections you need.
-
-
-Questions are divided into five numbered Sections. Sections are divided
-into lettered sub-sections. The questions are numbered sequentially
-within each sub-section, though they are in no particular order.
-
-
- 1. What is CVS?
- A. What is CVS? What's it for? Why CVS?
- B. Where do I find it? Where can I find Help?
- C. How does CVS differ from other similar software?
- D. What do you mean by . . .? (Definitions)
-
- 2. User Tasks
- A. Getting Started
- B. Common User Tasks
- C. Less Common User Tasks
- D. General Questions
-
- 3. Commands
- A. through P. One section for each CVS command.
-
- 4. Advanced Topics
- A. Installing CVS
- B. Setting up and Managing the Repository
- C. Branching and Merging
- D. Tricks of the Trade
- E. Internal errors
- F. Related Software
- G. Engineering
- H. Other Systems
-
- 5. Past & Future
- A. Contributors.
- B. Bugs and Patches
- C. Development
- D. Professional Support
-
- 6. Table of Contents
-
-
-Final note:
-
- Except for the "Past & Future" section, all answers in this
- document refer to CVS version 1.4. The latest released version is
- 1.5.
-
-
-============================================
-== Section 1 ==== What is CVS? ====
-============================================
-
-----------------
--- Section 1A -- What is CVS? What's it for? Why CVS?
-----------------
-
- **** Questions:
-
- 1A.1 What does CVS stand for? Can you describe it in one sentence?
- 1A.2 What is CVS for? What does it do for me?
- 1A.3 How does CVS work?
- 1A.4 What is CVS useful for?
- 1A.5 What is CVS *not* useful for?
-
-
- **** Answers:
-
- 1A.1 What does CVS stand for? Can you describe it in one sentence?
-
- "CVS" is an acronym for the "Concurrent Versions System".
-
- CVS is a "Source Control" or "Revision Control" tool
- designed to keep track of source changes made by groups of
- developers working on the same files, allowing them to
- stay in sync with each other as each individual chooses.
-
-
- 1A.2 What is CVS for? What does it do for me?
-
- CVS is used to keep track of collections of files in a shared
- directory called "The Repository". Each collection of files
- can be given a "module" name, which is used to "checkout"
- that collection.
-
- After checkout, files can be modified (using your favorite
- editor), "committed" back into the Repository and compared
- against earlier revisions. Collections of files can be
- "tagged" with a symbolic name for later retrieval.
-
- You can add new files, remove files you no longer want, ask for
- information about sets of files in three different ways,
- produce patch "diffs" from a base revision and merge the
- committed changes of other developers into your working files.
-
-
- 1A.3 How does CVS work?
-
- CVS saves its version-control information in RCS files stored in a
- directory hierarchy, called the Repository, which is separate from
- the user's working directory.
-
- Files in the Repository are stored in a format dictated by the
- RCS commands CVS uses to do much of its real work. RCS files
- are standard byte-stream files with an internal format described
- by keywords stored in the files themselves.
-
- To begin work, you execute a "checkout" command, handing it a
- module name or directory path (relative to the $CVSROOT variable)
- you want to work on. CVS copies the latest revision of each file
- in the specified module or directory out of the Repository and
- into a directory tree created in your current directory. You may
- specify a particular branch to work on by symbolic name if you
- don't want to work on the default (main or trunk) branch.
-
- You may then modify files in the new directory tree, build them
- into output files and test the results. When you want to make
- your changes available to other developers, you "commit" them back
- into the Repository.
-
- Other developers can check out the same files at the same time.
- To merge the committed work of others into your working files
- you use the "update" command. When your merged files build
- and test correctly, you may commit the merged result. This
- method is referred to as "copy-modify-merge", which does not
- require locks on the source files.
-
- At any time, usually at some milestone, you can "tag" the
- committed files, producing a symbolic name that can be handed to a
- future "checkout" command. A special form of "tag" produces a
- branch in development, as usually happens at "release" time.
-
- When you no longer plan to modify or refer to your local copy
- of the files, they can be removed.
-
-
- 1A.4 What is CVS useful for?
-
- CVS is intended to handle source control for files in three major
- situations:
-
- 1. Multiple developers working on the same files.
-
- The major advantage of using CVS over the simpler tools like
- RCS or SCCS is that it allows multiple developers to work on
- the same sources at the same time.
-
- The shared Repository provides a rendezvous for committed
- sources that allows developers a fair amount of flexibility in
- how often to publish (via the "commit" command) changes or
- include work committed by others (via the "update" command).
-
-
- 2. Tracking a stream of releases from a source vendor.
-
- If you are making changes to sources distributed by someone
- else, the CVS feature, called the Vendor Branch, allows you to
- combine local modifications with repeated vendor releases.
-
- I have found this most useful when dealing with sources from
- three major classes of source vendor:
-
- a. Large companies who send you tapes full of the latest
- release (e.g. Unix OS vendors, database companies).
-
- b. Public Domain software which *always* requires work.
-
- c. Pseudo-Public sources which may require work.
- (e.g. GNU programs, X, CVS itself, etc.)
-
-
- 3. Branching development.
-
- Aside from the "Vendor Branch", there are three kinds of
- "branches in development" that CVS can support:
-
- a. Your working directory can be treated as a private branch.
-
- b. A Development branch can be shared by one or more developers.
-
- c. At release time, a branch is usually created for bug fixes.
-
- (See 1D.9 and Section 4C for more info on branches.)
-
- CVS's branch support is a bit primitive, but it was designed to
- allow you to create branches, work on them for while and merge
- them back into the main line of development. You should also
- be able to merge work performed on the main branch into the
- branch you are working on. Arbitrary sharing and merging
- between branches is not currently supported.
-
-
- 1A.5 What is CVS *not* useful for?
-
- CVS is not a build system.
-
- Though the structure of your Repository and modules file
- interact with your build system (e.g. a tree of Makefiles),
- they are essentially independent.
-
- CVS does not dictate how you build anything. It merely stores
- files for retrieval in a tree structure you devise.
-
- CVS does not dictate how to use disk space in the checked out
- working directories. If you require your Makefiles or build
- procedures to know the relative positions of everything else,
- you wind up requiring the entire Repository to be checked out.
- That's simply bad planning.
-
- If you modularize your work, and construct a build system
- that will share files (via links, mounts, VPATH in Makefiles,
- etc.), you can arrange your disk usage however you like.
-
- But you have to remember that *any* such system is a lot of
- work to construct and maintain. CVS does not address the
- issues involved. You must use your brain and a collection
- of other tools to provide a build scheme to match your plans.
-
- Of course, you should use CVS to maintain the tools created to
- support such a build system (scripts, Makefiles, etc).
-
-
- CVS is not a substitute for management.
-
- You and your project leaders are expected to plan what you are
- doing. Everyone involved must be aware of schedules, merge
- points, branch names, release dates and the range of
- procedures needed to build products. (If you produce it and
- someone else uses it, it is a product.) CVS can't cover for a
- failure to manage your project.
-
- CVS is an instrument for making sources dance to your tune.
- But you are the piper and the composer. No instrument plays
- itself or writes its own music.
-
-
- CVS is not a substitute for developer communication.
-
- When faced with conflicts within a single file, most
- developers manage to resolve them without too much effort.
- But a more general definition of "conflict" includes problems
- too difficult to solve without communication between
- developers.
-
- CVS cannot determine when simultaneous changes within a single
- file, or across a whole collection of files, will logically
- conflict with one another. Its concept of a "conflict" is
- purely textual, arising when two changes to the same base file
- are near enough to spook the merge command into dropping
- conflict markers into the merged file.
-
- CVS is not capable of figuring out distributed conflicts in
- program logic. For example, if you change the arguments to
- function X defined in file A and, at the same time, edit file
- B, adding new calls to function X using the old arguments.
- You are outside the realm of CVS's competence.
-
- Acquire the habit of reading specs and talking to your peers.
-
-
- CVS is not a configuration management system.
-
- CVS is a source control system. The phrase "configuration
- management" is a marketing term, not an industry-recognized
- set of functions.
-
- A true "configuration management system" would contain
- elements of the following:
-
- * Source control.
- * Dependency tracking.
- * Build systems (i.e. What to build and how to find
- things during a build. What is shared? What is local?)
- * Bug tracking.
- * Automated Testing procedures.
- * Release Engineering documentation and procedures.
- * Tape Construction.
- * Customer Installation.
- * A way for users to run different versions of the same
- software on the same host at the same time.
-
- CVS provides only the first.
-
-
-
-----------------
--- Section 1B -- Where do I find CVS? Where can I find Help?
-----------------
-
- **** Questions:
-
- 1B.1 How do I get more information about CVS?
- 1B.2 Is there an archive of CVS material?
- 1B.3 How do I get files out of the archive if I don't have FTP?
- 1B.4 How do I get a copy of the latest version of CVS?
- 1B.5 Is there a mailing list devoted to CVS? How do I find it?
- 1B.6 What happened to the CVS Usenet newsgroup I heard about?
-
-
- **** Answers:
-
- 1B.1 How do I get more information about CVS?
-
- 1. The first thing I would do is to read the Info file that comes
- with the CVS sources under "doc". You can format and read the
- cvs.texinfo file in two ways: 1. Use TeX to format it and a
- "dvips" command to print it and 2. Install the cvs.info files
- that are created by the Makefile and read them online using the
- Emacs "info-mode" or a stand-alone "info" reader.
-
- 2. Then I'd run "cvsinit" to set up a Repository and read the man
- page while trying out the commands.
-
- Type "cvs -H" for general help or "cvs -H command" for
- command-specific help.
-
- 3. For background, you can read the original CVS paper (in the
- source tree, under "doc"). It describes the purpose of CVS and
- some of how it was designed. Note that the emphasis of the
- document (especially on multiple vendors providing the same
- sources) is somewhat out of date.
-
- 4. For more detailed information about "internals", read the man
- pages for RCS. If you are a programmer, you can also read the
- source code to CVS.
-
- 5. Other information and tutorials may be available in the "doc"
- directory of the FTP archive described below.
-
- 6. For current information, and a fair amount of detail, join the
- info-cvs mailing list described below.
-
-
- 1B.2 Is there an archive of CVS material?
-
- An anonymous FTP area has been set up. It contains many of the
- CVS files you might want, including extra documentation, patches
- and a copy of the latest release.
-
- ftp ftp.delos.com
- >>> User: anonymous
- >>> Passwd: <Your Internet address>
- cd /pub/cvs
- get README
- get Index
-
- The README has more (and more up-to-date) information. The Index
- contains a terse list of what is in the archive.
-
- A WWW home page is also available at http://www.delos.com/cvs.
-
-
- 1B.3 How do I get files out of the archive if I don't have FTP?
-
- Use one of the FTP<->Email servers. These are the ones
- I've been told about:
-
-
- 1. FTPMAIL service is available from the same host as the FTP
- server described above. Send mail to "ftpmail@delos.com"
- containing "help" in the body of the message. For example,
- on most Unix systems, you can type:
-
- echo help | Mail ftpmail@delos.com
-
- The FTPMAIL server will respond with a document describing how
- to use the server. If the "Mail" command doesn't exist on your
- system, try "mailx", "/usr/ucb/mail" or "/bin/mail".
-
-
- 2. If you are on BITNET, use Princeton's BITFTP server. Type
-
- echo 'send help' | Mail bitftp@pucc.princeton.edu
-
- (It is likely that only BITNET addresses can use this one.)
-
-
- 3. Other possibilities I've heard of from the net:
- (Try the one closest to you.)
-
- ftpmail@decwrl.dec.com
- ftpmail@sunsite.unc.edu
- ftpmail@cs.arizona.edu
- ftpmail@cs.uow.edu.au
- ftpmail@doc.ic.ac.uk
-
-
- 1B.4 How do I get a copy of the latest version of CVS?
-
- The latest released version of CVS and all the programs it
- depends on should be available through anonymous FTP on any FSF
- archive. The main FSF archive is at "prep.ai.mit.edu". There are
- mirrors of the FSF archive on UUNET and other large Internet sites.
-
- Program(s) Suggested revision
- ----------- -----------------------
- CVS 1.5
- RCS 5.7 (latest version available today)
- GNU diff 2.7 (or later) [contained in diffutils-2.7]
- GDBM 1.5 (or later) [optional]
-
- The GNU version of diff is suggested by both the RCS and CVS
- configuration instructions because it works better than the
- standard version.
-
- It is a good idea not to accept the versions of CVS, RCS or diff
- you find lying on your system unless you have checked out their
- provenance. Using inconsistent collections of tools can cause you
- more trouble than you can probably afford.
-
- The FTP archive mentioned above should contain the latest official
- release of CVS, some official and unofficial patches and possibly
- complete patched versions of CVS in use somewhere.
-
-
- 1B.5 Is there a mailing list devoted to CVS? How do I find it?
-
- An Internet mailing list named "info-cvs" grew out of the private
- mailing list used by the CVS 1.3 alpha testers in early 1992.
- Throughout 1994, the list received an average of 100 messages per
- month.
-
- You can add yourself to the mailing list by sending an Email
- message to:
-
- info-cvs-request@prep.ai.mit.edu
-
- (Don't forget the "-request" or you'll send a message to the
- whole list, some of whom are capable of remote execution.)
-
- Mail to the whole list should be sent to:
-
- info-cvs@prep.ai.mit.edu
-
- An archive of the mailing list is maintained in the FTP archive
- mentioned above.
-
-
- 1B.6 What happened to the CVS Usenet newsgroup I heard about?
-
-
- A Usenet newsgroup named "gnu.cvs.info" was announced in April
- 1993, with an expected creation date of August, 1993.
-
- As of this writing (October, 1994) it hasn't appeared.
-
- If the newsgroup is ever created, it and the mailing list should
- be bidirectionally gatewayed, meaning that you only need access to
- one of them. Anything sent to the mailing list would be
- automatically posted to "gnu.cvs.info" and anything posted to the
- newsgroup would be automatically mailed to "info-cvs".
-
- A newsgroup would be easier to use than a mailing list. If the
- CVS newsgroup ever shows up, ask your system administrator whether
- you get the "gnu" hierarchy. If so, select a news reader and dive
- in.
-
-
-----------------
--- Section 1C -- How does CVS differ from other, similar software?
-----------------
-
-This section attempts to list programs purporting to cover some of the
-same territory as CVS. [[These are very sparsely documented here. If you
-know something about one of these tools, how about trying to flesh out an
-entry or two?]]
-
-
- **** Questions:
-
- 1C.1 How does CVS differ from RCS?
- 1C.2 How does CVS differ from SCCS?
- 1C.3 How does CVS differ from ClearCase?
-#1C.4 How does CVS differ from TeamWare/SparcWorks?
- 1C.5 How does CVS differ from Aegis?
- 1C.6 How does CVS differ from Shapetools?
- 1C.7 How does CVS differ from TeamNet?
- 1C.8 How does CVS differ from ProFrame?
- 1C.9 How does CVS differ from CaseWare/CM?
- 1C.10 How does CVS differ from Sublime?
- 1C.11 How does CVS differ from PVCS?
- 1C.12 How does CVS differ from CMVC?
-
-
- **** Answers:
-
-
- 1C.1 How does CVS differ from RCS?
-
- CVS uses RCS to do much of its work and absolutely all the work
- of changing the underlying RCS files in the Repository.
-
- RCS comprises a set of programs designed to keep track of changes
- to individual files. Of course, it also allows you to refer to
- multiple files on the command line, but they are handled by
- iterating over individual files. There is no pretense of
- coordinated interaction among groups of files.
-
- CVS's main intent is to provide a set of grouping functions that
- allow you to treat a collection of RCS files as a single object.
- Of course, CVS also has to do a lot of iteration, but it tries
- its best to hide that it is doing so. In addition, CVS has some
- truly group-oriented facets, such as the modules file and the CVS
- administrative files that refer to a whole directory or module.
-
- One group aspect that can be a bit confusing is that a CVS branch
- is not the same as an RCS branch. To support a CVS branch, CVS
- uses "tags" (what RCS calls "symbols") and some local state,
- in addition to RCS branches.
-
- Other features offered by CVS that are not supported directly by
- RCS are
-
- 1. Automatic determination of the state of a file, (e.g.
- modified, up-to-date with the Repository, already tagged
- with the same string, etc.) which helps in limiting the
- amount of displayed text you have to wade through to
- figure out what changed and what to do next.
-
- 2. A copy-modify-merge scheme that avoids locking the files
- and allows simultaneous development on a single file.
-
- 3. Serialization of commits. CVS requires you to merge all
- changes committed (via "update") since you checked out
- your working copy of the file. Although it is still
- possible to commit a file filled with old data, it is less
- likely than when using raw RCS.
-
- 4. Relatively easy merging of releases from external Vendors.
-
-
- 1C.2 How does CVS differ from SCCS?
-
- SCCS is much closer to RCS than to CVS, so some of the previous
- entry applies.
-
- You might want to take a look at Walter Tichy's papers on RCS,
- which are referred to in the RCS man pages.
-
- [[More info here?]]
-
-
- 1C.3 How does CVS differ from ClearCase?
-
- ClearCase is a distributed client-server version control system.
- ClearCase is a variant DSEE tools, formerly available on Apollo
- platforms. The ClearCase tool set includes a few X-based
- interface tools, a command-line interface, and C programmer API.
- It is currently available on Sun, HP, SGI and OSF/1 platforms.
-
- ClearCase uses a special Unix filesystem type, called "mvfs"
- for "multi-version file system". Conceptually, mvfs adds
- another dimension to a regular Unix filesystem. The new
- axis is used to store the different versions of files and to
- provide a tree-hierarchical view of a collection of objects that
- might be scattered across any number of separate hosts on your
- local network.
-
- Each user acquires a "view" into the file database by creating a
- special mvfs mount point on their machine. Each view has a
- "configuration spec" containing a set of selection rules that
- specify the particular version of each file to make visible in
- that view. You can think of a "view" as a work area in CVS, except
- that the files don't really exist on your local disk until you
- modify them. This technique conserves disk space because it
- doesn't keep private copies of read-only files.
-
- Another advantage is that a view is "transparent" in the sense that
- all of the files in a "view" appear to be regular Unix files to
- other tools and Unix system calls. An extended naming convention
- allows access to particular versions of a file directly:
- "test.cc@@/main/bugfix/3" identifies the third version of test.c
- on the bugfix branch.
-
- ClearCase supports both the copy-modify-merge model of CVS (by
- using what are called "unreserved checkouts" and the
- checkin/checkout development model with file locking. Directories
- are version-controlled objects as well as files. A graphical merge
- tool is provided. Like RCS, ClearCase supports branches, symbolic
- tags, and delta compression. ASCII as well as binary files are
- supported, and converters from RCS, SCCS, DSEE formats are also
- included.
-
- A make-compatible build facility is provided that can identify
- common object code and share it among developers. A build
- auditing feature automatically records file dependencies by
- tracking every file that is opened when producing a derived
- object, thus making explicit dependency lists unnecessary. Pre-
- and post-event triggers are available for most ClearCase
- operations to invoke user programs or shell scripts. User-defined
- attributes can be assigned to any version or object. Hyper-links
- between version controlled objects can record their relationship.
-
- For more information, contact:
-
- Atria Software, Inc.
- 24 Prime Park Way
- Natick, MA 01760
- info@atria.com
-
- (508) 650-1193 (phone)
- (508) 650-1196 (fax)
-
- Originally contributed by Steve Turner
- Edited by the author of this FAQ.
-
-
-#1C.4 How does CVS differ from TeamWare/SparcWorks?
-
- TeamWare is a configuration management tool from Sun Microsystems,
- a part of SparcWorks. It uses the same copy and merge model as
- CVS. The central abstraction is a workspace, which corresponds to
- either a CVS branch or a checked out module. TeamWare allows you
- to manipulate workspaces directly, including moving and merging
- code between workspaces. You can put your workspace on tape and
- continue to work with it at home, just like you can with CVS.
- TeamWare is built upon and compatible with SCCS.
-
- TeamWare provides both a command line interface and a graphical
- interface. The CodeManager tool will display the project as a
- tree of workspaces, and allows you to manipulate them with drag
- and drop. The other tools are VersionTool that displays and
- manipulates a dag with a version history of a single file,
- CheckPoint that will create symbolic tags, MakeTool, a make
- compatible tool with a GUI, and FileMerge which will interactively
- merge files when needed (like emerge for emacs). If you have a
- sun, you can try /usr/old/mergetool for an old SunView version of
- FileMerge.
-
- Email: sunprosig@sun.com
-
- Originally extracted from TeamWare
- Marketing literature by Per Abrahamsen.
- Edited by the author of this FAQ.
-
-
- For more information, contact:
-
- SunExpress, Inc.
- P.O. Box 4426
- Bridgeton, MO 63044-9863
- (800)873-7869
-
-
- 1C.5 How does CVS differ from Aegis?
-
- Aegis appears to be a policy-setting tool that allows you to use
- other sub-programs (make, RCS, etc.) to implement pieces of the
- imposed policy.
-
- The initial document seems to say that most Unix tools are
- inadequate for use under Aegis.
-
- It is not really similar to CVS and requires a different mindset.
-
- [[Need more info here.]]
-
-
- 1C.6 How does CVS differ from Shapetools?
-
- Shapetools includes a build mechanism (called Shape, not
- surprisingly) that is aware of the version mechanism, and some
- dependency tracking. It is based on a file system extension
- called Attributed File System, which allows arbitrary-sized
- "attributes" to be associated with a file. Files are version
- controlled in a manner similar to RCS. Configurations are managed
- through the Shapefile, an extension of the Makefile syntax and
- functionality. Shape includes version selection rules to allow
- sophisticated selection of component versions in a build.
-
- Shapetools' concurrency control is pessimistic, in contrast to
- that of CVS. Also, there's very limited support for branching and
- merging. It has a built-in policy for transitioning a system from
- initial development to production.
-
- Contributed by Don Dwiggins
-
-
- 1C.7 How does CVS differ from TeamNet?
-
- TeamNet is a configuration management tool from TeamOne.
-
- For more information, contact:
-
- TeamOne
- 710 Lakeway Drive, Ste 100
- Sunnyvale, CA 94086
- (800) 442-6650
-
- Contributed by Steve Turner
-
-
- 1C.8 How does CVS differ from ProFrame?
-
- ProFrame is a new system integration framework from IBM.
- ProFrame is compliant with the CFI (CAD Framework Initiative)
- industry standards, including the Scheme extension language.
-
- ProFrame consists of three major components: (1) the Process
- Manager that automates your local design methodology (2) the
- Design Data Manager handles configuration management, and (3)
- Inter-tool Communication to provide a communication path among
- tools running on heterogeneous servers.
-
- The Design Data Manager(2) is probably the appropriate
- component to compare to CVS. The Design Data Manager provides
- version control with checkin/checkout capability,
- configuration management, and data dependency tracking. A
- graphical data selection interface is provided. Using this
- interface, you may create and manipulate objects and hierarchy
- structures, view the revision history for an object, and view
- and assign attributes to a design object.
-
- The ProFrame server currently runs only on RS6000, but clients
- may be a wide variety of Unix platforms. Contact IBM for the
- latest platform information.
-
- For more information, contact:
-
- IBM
- EDA Marketing and Sales
- P.O. Box 950, M/S P121
- Poughkeepsie, NY 12602
- (800) 332-0066
-
-
- Contributed by Steve Turner
- [extracted from the ProFrame 1.1.0 datasheet]
-
-
- 1C.9 How does CVS differ from CaseWare/CM?
-
- CaseWare/CM is a software configuration management product
- from CaseWare, Inc. CaseWare/CM may be customized to support
- a wide variety of methodologies, including various phases of
- the software lifecycle, and different access rights for users.
-
- A GUI is provided to view version histories and
- configurations. A merge tools is also included. CaseWare
- supports type-specific lifecycles, which allows different types
- of files to move through different lifecycles. Also provided
- is a build facility to support automatic dependency analysis,
- parallel, distributed, and remote builds, and variant
- releases.
-
- CaseWare/CM has been integrated with other CASE tools,
- including FrameMaker, ALSYS Ada, CodeCenter/Object Center, HP
- SoftBench, and Software Through Pictures. CaseWare also
- offers CaseWare/PT, a problem tracking system to integrate
- change requests with configuration management.
-
- Multiple vendors and operating systems are supported.
-
- For more information, contact:
-
- CaseWare, Inc.
- 108 Pacifica, 2nd Floor
- Irvine, CA 92718-3332
- (714) 453-2200 (phone)
- (714) 453-2276 (fax)
-
- Contributed by Steve Turner
- [extracted from the CaseWare/CM data sheet]
-
-
- 1C.10 How does CVS differ from Sublime?
-
- Produced by AT&T.
-
- [[Need more info here.]]
-
-
- 1C.11 How does CVS differ from PVCS?
-
- PVCS works on single files like RCS and SCCS, CVS works on
- complete subsystems. PVCS has a make utility (called a
- configuration builder), CVS does not. PVCS has a GUI interface
- for Unix, DOS, OS/2, and MS Windows.
-
- Intersolv, Inc.
- 1700 NW 167th Place
- OR 97006
-
- Contributed by Per Abrahamsen
- [Extracted from Intersolv Marketing literature.]
-
-
- 1C.12 How does CVS differ from CMVC?
-
- CMVC is an IBM Configuration Management and Version Control
- system. (Though I'm not certain that's the right acronym
- expansion.) It runs on Suns, HPs, RS6000s, OS/2 and Windows.
-
- Other than revision control, it apparently has features to manage
- releases, bug tracking and the connection between alterations and
- reported bugs and feature requests. It is a client/server system,
- based on a choice of commercial Relational Database systems, and
- it provides a Motif or command line interface.
-
- Unlike CVS, it uses a strict locking protocol to serialize source
- code alterations.
-
-
-----------------
--- Section 1D -- What do you mean by . . .? (Definitions)
-----------------
-
- **** Questions:
-
- 1D.1 What are "The Repository", "$CVSROOT" and "CVSROOT"?
- 1D.2 What is an RCS file?
- 1D.3 What is a working file?
- 1D.4 What is a working directory (or working area)?
- 1D.5 What is "checking out"?
- 1D.6 What is a revision?
- 1D.7 What is a "Tag"?
- 1D.8 What are "HEAD" and "BASE"?
- 1D.9 What is a Branch?
- 1D.10 What is "the trunk"?
- 1D.11 What is a module?
- 1D.12 What does "merge" mean?
-
-
- **** Answers:
-
-
- 1D.1 What are "The Repository", "$CVSROOT" and "CVSROOT"?
-
- The Repository is a directory tree containing the CVS
- administrative files and all the RCS files that constitute
- "imported" or "committed" work. The Repository is kept in a
- shared area, separate from the working areas of all developers.
-
- Users of CVS must set their "CVSROOT" environment variable to the
- absolute pathname of the head of the Repository. Most command
- line interpreters replace an instance of "$CVSROOT" with the value
- of the "CVSROOT" environment variable. By analogy, in this
- document "$CVSROOT" is used as shorthand for "the absolute
- pathname of the directory at the head of the Repository".
-
- One of the things found in $CVSROOT is a directory named CVSROOT.
- It contains all the "state", the administrative files, that CVS
- needs during execution. The "modules", "history", "commitinfo",
- "loginfo" and other files can be found there. See 4B.2 for more
- information about CVSROOT files.
-
-
- 1D.2 What is an RCS file?
-
- An RCS file is a text file containing the source text and the
- revision history for all committed revisions of a source file. It
- is stored separately from the working files, in a directory
- hierarchy, called the Repository.
-
- RCS is the "Revision Control System" that CVS uses to manage
- individual files. RCS file names normally end in ",v", but
- that can be altered (via the RCS -x option) to conform to file
- naming standards on platforms with unusual filename limitations.
-
-
- 1D.3 What is a working file?
-
- A working file is a disk file containing a checked-out copy of a
- source file that earlier had been placed under CVS. If the
- working file has been edited, the changes since the last committed
- revision are invisible to other users of CVS.
-
-
- 1D.4 What is a working directory (or working area)?
-
- A working directory is the place where you work and the place
- from which you "commit" files.
-
- The "checkout" command creates a tree of working directories,
- filling them with working files. Each working directory contains
- a sub-directory named ./CVS containing three administrative files,
- which are created by "checkout" and are always present:
-
- ./CVS/Entries
- contains information about working files.
-
- ./CVS/Repository
- contains the location of the directory within the
- Repository that was used to create the working directory.
-
- ./CVS/Root
- contains the value of $CVSROOT at the time you created
- the working directory.
-
- Other files may also appear in ./CVS depending on the state of
- your working directory:
-
- ./CVS/Tag
- contains the "sticky tag" associated with the whole
- directory. See 3A.2 for its main purpose.
- [Created by "checkout" or "update" when using "-r <tag>".]
- [Deleted by "checkout" or "update" when using '-A'.]
-
- ./CVS/Entries.Static
- contains a fixed list of working files. If this file
- exists, an "update" doesn't automatically bring newly
- added files out of the Repository.
- [Created and maintained by hand.]
-
- ./CVS/Checkin.prog
- contains a program to run whenever anything in the
- working directory is committed.
- [Created by checkout if "-i <prog>" appears in the
- modules file for the checked-out module.]
-
- ./CVS/Update.prog
- contains a program to run whenever anything in the
- working directory is updated.
- [Created by checkout if "-u <prog>" appears in the
- modules file for the checked-out module.]
-
- ./CVS/<file>,p
- ./CVS/<file>,t
- contain (possibly zero-length) state information about an
- "add" that has not been committed.
- [Created by "add".]
- [Deleted by "commit" or "remove".]
-
-
- 1D.5 What is "checking out"?
-
- "Checking out" is the act of using the "checkout" command to
- copy a particular revision from a set of RCS files into your
- working area. You normally execute "checkout" only once per
- working directory (or tree of working directories), maintaining
- them thereafter with the "update" command.
-
- See section 3C on the "checkout" command.
-
-
- 1D.6 What is a revision?
-
- A "revision" is a version of a file that was "committed"
- ("checked in", in RCS terms) some time in the past. CVS (and
- RCS) can retrieve any file that was committed by specifying its
- revision number or its "tag" ("symbolic name", in RCS terms).
-
- In CVS, a "tag" is more useful than a revision number. It usually
- marks a milestone in development represented by different revision
- numbers in different files, all available as one "tagged"
- collection.
-
- Sometimes the word "revision" is used as shorthand for "the file
- you get if you retrieve (via "checkout" or "update") the given
- revision from the Repository."
-
-
- 1D.7 What is a "Tag"?
-
- A "Tag" is a symbolic name, a synonym or alias for a
- particular revision number in a file. The CVS "tag" command
- places the same "Tag" on all files in a working directory,
- allowing you to retrieve those files by name in the future.
-
- The CVS "Tag" is implemented by applying RCS "symbols" to each
- individual file. The Tags on a file (or collection of files) may
- be displayed using the "log" command.
-
-
- 1D.8 What are "HEAD" and "BASE"?
-
- HEAD and BASE are built-in tags that don't show up in the "log"
- or "status" listings. They are interpreted directly by CVS.
-
- "HEAD" refers to the latest revision on the current branch in the
- Repository. The current branch is either the main line of
- development, or a branch in development created by placing a
- branch tag on a set of files and checking out that branch.
-
- "BASE" refers to the revision on the current branch you last
- checked out, updated, or committed. If you have not modified
- your working file, "BASE" is the committed revision matching it.
-
- Most of the time BASE and HEAD refer to the same revision. They
- can become different in two ways:
-
- 1. Someone else changed HEAD by committing a new revision of your
- file to the Repository. You can pull BASE up to equal HEAD by
- executing "update".
-
- 2. You moved BASE backward by executing "checkout" or "update"
- with the option "-r <rev/tag>" or "-D <date>". CVS records a
- sticky tag and moves your files to the specified earlier
- revision. You can clear the sticky tag and pull BASE up to
- equal HEAD again by executing "update -A".
-
-
- 1D.9 What is a Branch?
-
- In general, a branch is any mechanism that allows one or more
- developers to modify a file without affecting anyone other than
- those working on the same branch.
-
- There are four kinds of "branch" CVS can manage:
-
- 1. The Vendor Branch.
-
- A single vendor branch is supported. The "import" command
- takes a sequence of releases from a source code vendor (called
- a "vendor" even if no money is involved), placing them on a
- special "Vendor" branch. The Vendor branch is considered part
- of the "Main line" of development, though it must be merged
- into locally modified files on the RCS Main branch before the
- "import" is complete.
-
- See Section 3H ("import").
-
- 2. Your Working directory.
-
- A checked-out working directory, can be treated like a private
- branch. No one but you can touch your files. You have
- complete control over when you include work committed by
- others. However, you can't commit or tag intermediate versions
- of your work.
-
- 3. A Development branch.
-
- A group of developers can share changes among the group,
- without affecting the Main line of development, by creating a
- branch. Only those who have checked-out the branch see the
- changes committed to that branch. This kind of branch is
- usually temporary, collapsing (i.e. merge and forget) into the
- Main line when the project requiring the branch is completed.
-
- You can also create a private branch of this type, allowing an
- individual to commit (and tag) intermediate revisions without
- changing the Main line. It should be managed exactly like a
- Development Branch -- collapsed into the Main line (or its
- parent branch, if that is not the Main Branch) and forgotten
- when the work is done.
-
- 4. A Release branch.
-
- At release time, a branch should be created marking what was
- released. Later, small changes (sometimes called "patches")
- can be made to the release without including everything else on
- the Main line of development. You avoid forcing the customer
- to accept new, possibly untested, features added since the
- release. This is also the way to correct bugs found during
- testing in an environment where other developers have continued
- to commit to the Main line while you are testing and packaging
- the release.
-
- Although the internal format of this type of branch (branch tag
- and RCS branches) is the same as in a development branch, its
- purpose and the way it is managed are different. The major
- difference is that a Release branch is normally Permanent.
- Once you let a release out the door to customers, or to the
- next stage of whatever process you are using, you should retain
- forever the branch marking that release.
-
- Since the branch is permanent, you cannot incorporate the
- branch fixes into the Main line by "collapsing" (merging and
- forgetting) the release branch. For large changes to many
- files on the release branch, you will have to perform a branch
- merge using "update -j <rev> -j <rev>". (See 4C.7)
-
- The most common way to merge small changes back into Main line
- development is to make the change in both places
- simultaneously. This is faster than trying to perform a
- selective merge.
-
- See 1D.12 (merges) and Section 4C, on Branching for more info.
-
-
- 1D.10 What is "the trunk"?
-
- Another name for the RCS Main Branch. The RCS Main Branch is
- related, but not equivalent, to both the CVS Main branch and what
- developers consider to be the Main line of development.
- See 3H.3 and Section 4C on Branching.
-
-
- 1D.11 What is a module?
-
- In essence, a module is a name you hand to the "checkout" command
- to retrieve one or more files to work on. It was originally
- intended to be a simple, unique name in the "modules" file
- attached to a directory or a subset of files within a directory.
-
- The module idea is now a somewhat slippery concept that can be
- defined in two different ways:
-
- A. A module is an argument to "checkout". There are three types:
-
- 1. An entry in the modules file. A "module" name as described
- in 'B.' below.
-
- 2. A relative path to a directory or file in the Repository.
-
- 3. A mixed-mode string of "modulename/relative-path".
- Everything up to the first slash ('/') is looked up as a
- module. The relative path is appended to the directory
- associated with the module name and the resulting path is
- checked out as in #2 above.
-
-
- B. A module is a unique (within the file) character string in the
- first column of the modules file. There are five types:
-
- 1. A name for a directory within the Repository that
- allows you to ignore the parent directories above it.
-
- Example:
-
- emacs gnu/emacs
-
-
- 2. A name for a subset of the files within such a directory.
-
- Example:
-
- ls unix/bin Makefile ls.c
-
- The 2nd through Nth strings in the above can be files,
- directories or module substitutions. No relative paths.
-
- A module substitution occurs when you use a '&module-name'
- reference. The module-name referred to is logically
- substituted for the '&module-name' string.
-
-
- 3. A relative pathname to a directory within the Repository
- which, when checked out, creates an image of part of the
- Repository structure in your current directory.
-
- Example:
-
- gnu/emacs -o /bin/emacs.helper gnu/emacs
-
- The files checked out are exactly the same as the files
- "checkout" would retrieve if the path weren't even in the
- modules file. The only reason to put this kind of relative
- pathname into the modules file is to hook one of the helper
- functions onto it.
-
-
- 4. A relative pathname to a single file within the Repository
- which, when checked out, creates something you probably
- don't want: It creates a directory by the name of the file
- and puts the file in it.
-
- Example:
-
- gnu/emacs/Makefile -o /bin/emacs.helper gnu/emacs Makefile
-
- The file checked out is the same as what you would get if
- you handed the relative pathname to the "checkout" command.
- But it puts it in a strange place. The only reason to do
- this is to hook a helper function onto a specific file name.
-
-
- 5. An alias consisting of a list of any of the above, including
- other aliases, plus exceptions.
-
- Example:
-
- my_work -a emacs !emacs/tests gnu/bison unix/bin/ls.c
-
-
- The exception "!emacs/test" above is functionally equivalent
- to specifying "!emacs/tests" on the "checkout" command line.
-
-
- Another way to look at it is that the modules file is simply
- another way to "name" files. The hierarchical directory
- structure provides another. You should use whatever turns out to
- be simplest for your development group.
-
- See 4G.2 for some specific ideas about how to use the modules file.
-
-
- 1D.12 What does "merge" mean?
-
- A merge is a way of combining changes made in two independent
- copies of a common starting file. Checking out an RCS revision
- produces a file, so for the purposes of a merge "file" and
- "revision" are equivalent. So, we can say there are always three
- "files" involved in a merge:
-
- 1. The original, starting, "base" or "branch point" file.
- 2. A copy of the base file modified in one way.
- 3. Another copy of the base file modified in a different way.
-
- Humans aren't very good at handling three things at once, so the
- terminology dealing with merges can become strained. One way to
- think about it is that all merges are performed by inserting the
- difference between a base revision and a later revision (committed
- by someone else) into your working file. Both the "later"
- revision and your working file are presumed to have started life
- as a copy of the "base" revision.
-
- In CVS, there are three main types of "merge":
-
- 1. The "update" command automatically merges revisions committed
- by others into your working file. In this case, the three
- files involved in the merge are:
-
- Base: The revision you originally checked out.
- Later: A revision committed onto the current branch
- after you checked out the Base revision.
- Working: Your working file. The one lying in the working
- directory containing changes you have made.
-
- 2. The "update -j <branch_tag> {optional files}" command merges
- changes made on the given branch into your working files, which
- is presumed to be on the Main line of development.
-
- See 4C.6
-
- 3. The "update -j <rev> -j <rev> {optional files}" command merges
- the difference between two specified revisions into files in
- your working directory. The two revisions <rev> are usually on
- the same branch and, when updating multiple files, they are
- most useful when they are Tag names rather than numeric
- revisions.
-
- See 4C.7
-
-
-
-
-==========================================
-== Section 2 ==== User Tasks ====
-==========================================
-
-----------------
--- Section 2A -- Getting Started
-----------------
-
- **** Questions:
-
- 2A.1 What is the first thing I have to know?
- 2A.2 Where do I work?
- 2A.3 What does CVS use from my environment?
- 2A.4 OK, I've been told that CVS is set up, my module is named
- "ralph" and I have to start editing. What do I type?
- 2A.5 I have been using RCS for a while. Can I convert to CVS without
- losing my revision history? How about converting from SCCS?
-
-
- **** Answers:
-
- 2A.1 What is the first thing I have to know?
-
- Your organization has most likely assigned one or more persons to
- understand, baby-sit and administer the CVS programs and the data
- Repository. I call these persons Repository Administrators. They
- should have set up a Repository and "imported" files into it.
-
- If you don't believe anyone has this responsibility, or you are
- just testing CVS, then *you* are the Repository Administrator.
-
- If you are a normal user of CVS ask your Repository Administrator
- what module you should check out.
-
- Then you can work.
-
- If you *are* the Repository Administrator, you will want to read
- everything you can get your hands on, including this FAQ. Source
- control issues can be difficult, especially when you get to
- branches and release planning. Expect to feel stupid for a few
- days/weeks.
-
- No tool in the universe avoids the need for intelligent
- organization. In other words, there are all sorts of related
- issues you will probably have to learn. Don't expect to dive in
- without any preparation, stuff your 300 Megabytes of sources into
- CVS and expect to start working. If you don't prepare first, you
- will probably spend a few sleepless nights.
-
-
- 2A.2 Where do I work?
-
- Wherever you have disk space. That's one of the advantages of
- CVS: you use the "checkout" command to copy files from the
- Repository to your working directory, which can be anywhere you
- have the space.
-
- Your local group might have conventions for where to work.
- Ask your peers.
-
-
- 2A.3 What does CVS use from my environment?
-
- You must set two environment variables. Some shells share these
- variables with local shell variables using a different syntax.
- You'll have to learn how your shell handles them.
-
- Variable Value (or action)
- --------- ---------------------
- CVSROOT Absolute pathname of the head of your Repository.
-
- PATH Normally set to a list of ':'-separated directory
- pathnames searched to find executables. You must
- make sure "cvs" is in one of the directories.
-
- If your CVS was built with the RCSBIN directory set
- to null (""), and you don't set the RCSBIN
- variable mentioned below, then the RCS commands
- also must be somewhere in your PATH.
-
-
- Optional variables: (Used if set, but ignored otherwise.)
-
- Variable Value (or action)
- --------- ---------------------
- CVSEDITOR The name of your favorite fast-start editor
- program. You'll be kicked into your editor to
- supply revision comments if you don't specify them
- via -m "Log message" on the command line.
-
- EDITOR Used if CVSEDITOR doesn't exist. If EDITOR
- doesn't exist, CVS uses a configured constant,
- usually, "vi".
-
- CVSREAD Sets files to read-only on "checkout".
-
- RCSBIN Changes where CVS finds the RCS commands.
-
- CVSIGNORE Adds to the ignore list. See Section 2D.
-
-
- Other variables used by CVS that are normally set upon login:
-
- Variable Value (or action)
- --------- ---------------------
- LOGNAME Used to find the real user name.
-
- USER Used to find the real user name if no LOGNAME.
-
- HOME Used to determine your home directory, if set.
- Otherwise LOGNAME/USER/getuid() are used to find
- your home directory from the passwd file.
-
- TMPDIR Used during import. It might also be used if your
- platform's version of mktemp(3) is unusual, or
- you have changed the source to use tmpnam(3).
-
-
-
- 2A.4 OK, I've been told that CVS is set up, my module is named
- "ralph" and I have to start editing. What do I type?
-
- cd <where you have some space to work>
- cvs checkout ralph
- cd ralph
-
- And hack away.
-
-
- 2A.5 I have been using RCS for a while. Can I convert to CVS without
- losing my revision history? How about converting from SCCS?
-
- If you are asking such questions, you are not a mere user of CVS,
- but one of its Administrators! You should take a look at Section
- 4A, "Installing CVS" and Section 4B, "Setting up and Managing
- the Repository".
-
-
-----------------
--- Section 2B -- Common User Tasks
-----------------
-
-What I consider a "common user task" generally involves combinations
-of the following commands:
-
- checkout, update, commit, diff, log, status, tag, add
-
-
-Conventions in this section:
-
- 1. Before each CVS command, you are assumed to have typed a "cd"
- command to move into a writable working directory.
-
- 2. All further "cd" commands specified in the examples are assumed
- to start in the above working directory.
-
- 3. Unless a point is being made about multiple instances, all modules
- are named <module>, all tags are named <tag> (branch tags are
- named <branch_tag>) and all files are named <file>.
-
- The checkout command will take a relative path name in place
- of a module name. If you use a relative pathname in place of
- <module>, you should use the same relative path every place
- you see <module> in that example.
-
-
- **** Questions:
-
- 2B.1 What is the absolute minimum I have to do to edit a file?
- 2B.2 If I edit multiple files, must I type "commit" for each one?
- 2B.3 How do I get rid of the <module> directory that "checkout" created?
- 2B.4 How do I find out what has changed since my last update?
- 2B.5 I just created a new file. How do I add it to the Repository?
- 2B.6 How do I merge changes made by others into my working directory?
- 2B.7 How do I label a set of revisions so I can retrieve them later?
- 2B.8 How do I checkout an old release of a module, directory or file?
- 2B.9 What do I have to remember to do periodically?
-
-
- **** Answers:
-
-
- 2B.1 What is the absolute minimum I have to do to edit a file?
-
- Tell your Repository Administrator to create a module covering the
- directory or files you care about. You will be told that your
- module name is <module>. Then type:
-
- cvs checkout <module>
- cd <module>
- emacs <file> # Isn't Emacs a synonym for edit?
- cvs commit <file>
-
- If you don't use modules (in my opinion, a mistake), you can check
- out a directory by substituting its relative path within the
- Repository for <module> in the example above.
-
- To work on a single file, you'll have to change "cd <module>" to
- "cd `dirname <module>`".
-
-
- 2B.2 If I edit multiple files, must I type "commit" for each one?
-
- No. You can commit a list of files and directories, including
- relative paths into multiple directories. You can also commit
- every modified file in the current directory or in all directories
- and subdirectories from your current directory downward. See 3D.2.
-
-
- 2B.3 How do I get rid of the <module> directory that "checkout" created?
-
- Change your directory to be the same as when you executed the
- "checkout" command that created <module>.
-
- If you want to get rid of the CVS control information, but leave
- the files and directories, type:
-
- cvs release <module>
-
- If you want to obliterate the entire directory, type:
-
- cvs release -d <module>
-
- ("release -d" searches through the output of "cvs -n update" and
- refuses to continue if the "update" command finds any modified
- files or non-ignored foreign files. Foreign directories too.)
-
- If you don't care about keeping "history", or checking for
- modified and foreign files, you can just remove the whole
- directory. That's "rm -rf <module>" under Unix.
-
-
- 2B.4 How do I find out what has changed since my last update?
-
- There are many ways to answer this.
-
- To find out what you've changed in your current working directory
- since your last checkout, update or commit, type:
-
- cvs diff
-
- To find out what other people have added (to your branch) since
- you last checked out or updated, type:
-
- cvs diff -r BASE -r HEAD
-
- To look at a revision history containing the comments for all
- changes, you can use the "log" command.
-
- You can also use "history" to trace a wide variety of events.
-
-
- 2B.5 I just created a new file. How do I add it to the Repository?
-
- The "update" command will mark files CVS doesn't know about in
- your working directory with a '?' indicator.
-
- ? <file>
-
- To add <file> to the Repository, type:
-
- cvs add <file>
- cvs commit <file>
-
- See 3A.[2-5] and 4C.8 for branch and merge considerations.
-
-
- 2B.6 How do I merge changes made by others into my working directory?
-
- If you are asking about other branches, see Section 4C on
- "Branching". You will have to use the "update -j" command.
-
- Retrieving changes made to the Repository on the *same* branch you
- are working on is the main purpose of the "update" command. The
- "update" command tries to merge work committed to the Repository
- by others since you last executed "checkout", "update" or "commit"
- into your working files.
-
- For a single file, there are six possible results when you type
- the "update" command:
-
- 1. If the file is lying in your working directory, but is not
- under CVS, it will do nothing but print:
-
- ? <file>
-
- 2. If neither you nor anyone else has committed changes to <file>,
- since your last "checkout", "update" or "commit", "update"
- will print nothing and do nothing.
-
- 3. If you have made no changes to a working file, but you or
- others have committed changes to the Repository since your last
- "checkout", "update" or "commit" of this working file, CVS will
- remove your working file and replace it with a copy of the
- latest revision of that file in the Repository. It will print:
-
- U <file>
-
- You might want to examine the changes (using the CVS "diff"
- command) to see if they mesh with your own in related files.
-
- 4. If you have made changes to a working file, but no one has
- changed your BASE revision (the revision you retrieved from the
- Repository in your last "checkout", "update" or "commit"),
- "update" will print:
-
- M <file>
-
- Nothing changes. You were told that you have a modified
- file in your directory.
-
- 5. If you have made changes to your working file and you or others
- have committed changes to the Repository, but in different
- sections of the file, CVS will merge the changes stored in the
- Repository since your last "checkout", "update" or "commit"
- into your working file. "update" will print:
-
- RCS file: /Repository/module/<file>
- retrieving revision 1.X
- retrieving revision 1.Y
- Merging differences between 1.X and 1.Y into <file>
- M <file>
-
- If you execute "diff" before and after this step, you should
- see the same output, since both the base file and your working
- file changed in parallel. This is one of the few times the
- otherwise nonsensical phrase "same difference" means something.
-
- 6. If both you and those who committed files (since your last
- checkout, update or commit) have made changes to the same
- section of a file, CVS will merge the changes into your file as
- in #5 above, but it will leave conflict indicators in the file.
- "update" will print:
-
- RCS file: /Repository/module/<file>
- retrieving revision 1.X
- retrieving revision 1.Y
- Merging differences between 1.X and 1.Y into <file>
- rcsmerge warning: overlaps during merge
- cvs update: conflicts found in <file>
- C <file>
-
- This is a "conflict". The file will contain markers
- surrounding the overlapping text. The 'C' conflict indicator
- is sticky -- subsequent "update" commands will continue to show
- a 'C' until you edit the file.
-
- You must examine the overlaps with care and resolve the problem
- by analyzing how to retain the features of both changes. See
- 2D.7 and 3P.6 for more details on conflict resolution.
-
-
- 2B.7 How do I label a set of revisions so I can retrieve them later?
-
- To "tag" the BASE revisions (the ones you last checked out,
- updated, or committed) you should "cd" to the head of the working
- directory you want to tag and type:
-
- cvs tag <tag>
-
- It recursively walks through your working directory tagging the
- BASE revisions of all files.
-
- To "tag" the latest revision on the Main branch in the
- Repository, you can use the following from anywhere:
- (No "cd" is required -- it works directly on the Repository.)
-
- cvs rtag <tag> <module>
-
-
- 2B.8 How do I checkout an old release of a module, directory or file?
-
- Module names and directories are simply ways to name sets of
- files. Once the names are determined, there are 6 ways to specify
- which revision of a particular file to check out:
-
- 1. By tag or symbolic name, via the "-r <tag>" option.
-
- 2. By date, via the "-D <date>" option.
-
- 3. By branch tag (a type of tag with a magic format), via the
- "-r <branch_tag>" option.
-
- 4. By date within a branch, via the "-r <branch_tag>:<date>"
- option.
-
- 5. By an explicit branch revision number ("-r <rev>"), which
- refers to the latest revision on the branch. This isn't really
- an "old" revision, from the branch's perspective, but from the
- user's perspective the whole branch might have been abandoned
- in the past.
-
- 6. An explicit revision number: "-r <rev>" Though this works, it
- is almost useless for more than one file.
-
-
- You type:
-
- cvs checkout <option-specified-above> <module>
- cd <module>
-
-
- 2B.9 What do I have to remember to do periodically?
-
- You should execute "cvs -n update" fairly often to keep track of
- what you and others have changed. It won't change anything -- it
- will just give you a report.
-
- Unless you are purposely delaying the inclusion of others' work,
- you should execute "update" once in a while and resolve the
- conflicts. It is not good to get too far out of sync with the
- rest of the developers working on your branch.
-
- It is assumed that your system administrators have arranged for
- editor backup and Unix temp files (#* and .#*) to be deleted after
- a few weeks. But you might want to look around for anything else
- that is ignored or hidden. Try "cvs -n update -I !" to see all
- the ignored files.
-
- If you are the Repository Administrator, see 4B.16 on
- Administrator responsibilities.
-
-
-----------------
--- Section 2C -- Less Common User Tasks
-----------------
-
-What I consider a "less common user task" generally involves one or
-more of the following commands:
-
- history, import, export, rdiff, release, remove, rtag
-
-
- **** Questions:
-
- 2C.1 Can I create non-CVS sub-directories in my working directory?
- 2C.2 How do I add new sub-directories to the Repository?
- 2C.3 How do I remove a file I don't need?
- 2C.4 How do I rename a file?
- 2C.5 How do I make sure that all the files and directories in my
- working directory are really in the Repository?
- 2C.6 How do I create a branch?
- 2C.7 How do I modify the modules file? How about the other files in
- the CVSROOT administrative area?
- 2C.8 How do I split a file into pieces, retaining revision histories?
-
-
- **** Answers:
-
-
- 2C.1 Can I create non-CVS sub-directories in my working directory?
-
- Yes. Unless the directory exists in the Repository, "update" will
- skip over them and print a '?' the way it does for files you
- forgot to add. You can avoid seeing the '?' by adding the name
- of the foreign directory to the ./.cvsignore file, just ask you
- can do with files.
-
- If you explicitly mention a foreign directory on the "update"
- command line, it will traverse the directory and waste a bit of
- time, but if any directory or sub-directory lacks the ./CVS
- administrative directory, CVS will print an error and abort.
-
-
- 2C.2 How do I add new sub-directories to the Repository?
-
- The "add" command will work on directories. You type:
-
- mkdir <dir>
- cvs add <dir>
-
- It will respond:
-
- Directory /Repos/<dir> added to the repository
-
- and will create both a matching directory in the Repository and a
- ./CVS administrative directory within the local <dir> directory.
-
-
- 2C.3 How do I remove a file I don't need?
-
- (See the questions in Section 4B on removing files from the
- Repository.)
-
- You type:
-
- rm <file>
- cvs remove <file>
-
- CVS registers the file for removal. To complete the removal, you
- must type:
-
- cvs commit <file>
-
- CVS moves the file to the Attic associated with your working
- directory. Each directory in the Repository stores its deleted
- files in an Attic sub-directory. A normal "checkout" doesn't
- look in the Attic, but if you specify a tag, a date or a
- revision, the "checkout" (or "update") command will retrieve
- files from the Attic with that tag, date or revision.
-
-
- 2C.4 How do I rename a file?
-
- CVS does not offer a way to rename a file in a way that CVS can
- track later. See Section 4B for more information.
-
- Here is the best (to some, the only acceptable) way to get the
- effect of renaming, while preserving the change log:
-
- 1. Copy the RCS (",v") file directly in the Repository.
-
- cp $CVSROOT/<odir>/<ofile>,v $CVSROOT/<ndir>/<nfile>,v
-
- By duplicating the file, you will preserve the change
- history and the ability to retrieve earlier revisions of the
- old file via the "-r <tag/rev>" or "-D <date>" options to
- "checkout" and "update".
-
- 2. Remove the old file using CVS.
-
- cd <working-dir>/<odir>
- rm <ofile>
- cvs remove <ofile>
- cvs commit <ofile>
-
- This will move the <ofile> to the Attic associated with
- <odir>.
-
- 3. Retrieve <nfile> and remove all the Tags from it.
-
- By stripping off all the old Tags, "checkout -r" and
- "update -r" won't retrieve revisions Tagged before
- the renaming.
-
- cd <working-dir>/<ndir>
- cvs update <nfile>
- cvs log <nfile> # Save the list of Tags
- cvs tag -d <tag1> <nfile>
- cvs tag -d <tag2> <nfile>
- . . .
-
-
- This technique can be used to rename files within one directory or
- across different directories. You can apply this idea to
- directories too, as long as you apply the above to each file and
- don't delete the old directory.
-
- Of course, you have to change your build system (e.g. Makefile) in
- your <working-dir> to know about the name change.
-
- Warning: Stripping the old tags from the copied file will allow
- "-r <tag>" to do the right thing, but you will still have problems
- with "-D <date>" because there is no place to store the "deletion
- time". See 5B.3 for more details.
-
-
- 2C.5 How do I make sure that all the files and directories in my
- working directory are really in the Repository?
-
- A "cvs update", or "cvs -n update" (which won't modify your
- working directory) will display foreign elements, which have no
- counterpart in the Repository, preceded by a '?'. To register
- foreign directories, you can use "cvs add". To register foreign
- files, you can use "cvs add" followed by "cvs commit".
-
- You could also checkout your module, or the Repository directory
- associated with your working directory, a second time into another
- work area and compare it to your working directory using the
- (non-CVS) "diff -r" command.
-
- By default many patterns of files are ignored. If you create a
- file named "core" or a file ending in ".o", it is usually
- ignored. If you really want to see all the files that aren't in
- the Repository, you can use a special "ignore" pattern to say
- "ignore no files". Try executing: (You may have to quote or
- backwhack (i.e. precede by '\') the '!' in your shell.)
-
- cvs -n update -I !
-
- The above command will display not only the normal modified,
- update and conflict indicators ('M', 'U', and 'C' respectively) on
- files within the Repository, but it will also display each file
- not in the Repository preceded by a '?' character.
-
- The '-n' option will not allow "update" to alter your working
- directory.
-
-
- 2C.6 How do I create a branch?
-
- Type this in your working directory:
-
- cvs tag -b <branch_tag>
-
- and you will create a branch. No files have real branches in them
- yet, but if you move onto the branch by typing:
-
- cvs update -r <branch_tag>
-
- and commit a file in the normal way:
-
- cvs commit <file>
-
- then a branch will be created in the underlying <file>,v file and
- the new revision of <file> will appear only on that branch.
-
- See Section 4C, on Branching.
-
-
- 2C.7 How do I modify the modules file? How about the other files in
- the CVSROOT administrative area?
-
- A module named "modules" has been provided in the default modules
- file, so you can type:
-
- cvs checkout modules
- cd modules
-
- Another module named CVSROOT has been provided in the default
- modules file, covering all the administrative files. Type:
-
- cvs checkout CVSROOT
- cd CVSROOT
-
- Then you can edit your files, followed by:
-
- cvs commit
-
- If you start with the provided template for the "modules" file,
- the CVSROOT and the "modules" module will have the "mkmodules"
- program as a "commit helper". After a file is committed to such a
- module, "mkmodules" will convert a number of standard files (See
- 4B.2) in the CVSROOT directory inside the Repository into a form
- that is usable by CVS.
-
-
- 2C.8 How do I split a file into pieces, retaining revision histories?
-
- If you and a coworker find yourselves repeatedly committing the
- same file, but never for changes in the same area of the file, you
- might want to split the file into two or more pieces. If you are
- both changing the same section of code, splitting the file is of
- no use. You should talk to each other instead.
-
- If you decide to split the file, here's a suggestion. In many
- ways, it is similar to multiple "renamings" as described in
- 2C.4 above.
-
- Say you want to split <fileA>, which already in the Repository,
- into three pieces, <fileA>, <fileB> and <fileC>.
-
- 1. Copy the RCS (",v") files directly in the Repository,
- creating the new files, then bring readable copies of the
- new files into the working directory via "update".
-
- cp $CVSROOT/<path>/<fileA>,v $CVSROOT/<path>/<fileB>,v
- cp $CVSROOT/<path>/<fileA>,v $CVSROOT/<path>/<fileC>,v
- cvs update <fileB> <fileC>
-
- 2. Then remove all the <tags> from the new files by using:
-
- cvs log <fileB> <fileC> # Save the list of <tag?>
- cvs tag -d <tag1> <fileB> <fileC>
- cvs tag -d <tag2> <fileB> <fileC>
- . . .
-
- 3. Edit each file until it has the data you want in it.
- This is a hand-editing job, not something CVS can handle.
- Then commit all the files.
-
- [From experience, I'd suggest making sure that only one copy
- of each line of code exists among the three files, except
- for "include" statements, which must be duplicated. And
- make sure the code compiles.]
-
- emacs <fileA> <fileB> <fileC>
- cvs commit <fileA> <fileB> <fileC>
-
-
- As in the "rename" case, by duplicating the files, you'll preserve
- the change history and the ability to retrieve earlier revisions.
-
- Of course, you have to alter your build system (e.g. Makefiles) to
- take the new names and the change in contents into account.
-
-
-
-----------------
--- Section 2D -- General Questions
-----------------
-
- **** Questions:
-
- 2D.1 How do I see what CVS is trying to do?
- 2D.2 If I work with multiple modules, should I check them all out and
- commit them occasionally? Is it OK to leave modules checked out?
- 2D.3 What is a "sticky" tag? What makes it sticky? How do I loosen it?
- 2D.4 How do I get an old revision without updating the "sticky tag"?
- 2D.5 What operations disregard sticky tags?
- 2D.6 Is there a way to avoid reverting my Emacs buffer after
- committing a file? Is there a "cvs-mode" for Emacs?
- 2D.7 How does conflict resolution work? What *really* happens if two
- of us change the same file?
- 2D.8 How can I tell who has a module checked out?
- 2D.9 Where did the .#<file>.1.3 file in my working directory come from?
- 2D.10 What is this "ignore" business? What is it ignoring?
- 2D.11 Is there a way to set user-specific configuration options?
- 2D.12 Is it safe to interrupt CVS using Control-C?
- 2D.13 How do I turn off the "admin" command?
- 2D.14 How do I turn off the ability to disable history via "cvs -l"?
- 2D.15 How do I keep certain people from accessing certain directories?
-
-
- **** Answers:
-
-
- 2D.1 How do I see what CVS is trying to do?
-
- The '-t' option on the main "cvs" command will display every
- external command (mostly RCS commands and file deletions) it
- executes. When combined with the '-n' option, which prevents the
- execution of any command that might modify a file, you can see
- what it will do before you let it fly. The '-t' option will *not*
- display every internal action, only calls to external programs.
-
- To see a harmless example, try typing:
-
- cvs -nt update
-
- Some systems offer a "trace" or "truss" command that will display
- all system calls as they happen. This is a *very* low-level
- interface that does not normally follow the execution of external
- commands, but it can be useful.
-
- The most complete answer is to read the source, compile it
- with the '-g' option and step through it under a debugger.
-
-
- 2D.2 If I work with multiple modules, should I check them all out and
- commit them occasionally? Is it OK to leave modules checked out?
-
- The simple answers are "Yes."
-
- There is no reason to remove working directories, other than to
- save disk space. As long as you have committed the files you
- choose to make public, your working directory is just like any
- other directory.
-
- CVS doesn't care whether you leave modules checked out or not.
- The advantage of leaving them checked out is that you can quickly
- visit them to make and commit changes.
-
-
- 2D.3 What is a "sticky" tag? What makes it sticky? How do I loosen it?
-
- When you execute "update -r <tag>", CVS remembers the <tag>. It
- has become "sticky" in the sense that until you change it or
- remove it, the tag is remembered and used in references to the
- file as if you had typed "-r <tag>" on the command line.
-
- It is most useful for a <branch_tag>, which is a sticky tag
- indicating what branch you are working on.
-
- A revision number ("-r <rev-number>") or date ("-D <date>") can
- also become sticky when they are specified on the command line.
-
- A sticky tag, revision or date remains until you specify another
- tag, revision or date the same way. The "update -A" command
- moves back to the Main branch, which has the side-effect of
- clearing all sticky items on the updated files.
-
- The "checkout" command creates sticky tags, revisions and dates
- the same way "update" does.
-
- Also, the '-k' option records a "sticky" keyword option that
- is used in further "updates until "update -A" is specified.
-
-
- 2D.4 How do I get an old revision without updating the "sticky tag"?
-
- Use the '-p' option to "pipe" data to standard output. The
- command "update -p -r <tag/rev>" sends the selected revision to
- your standard output (usually the terminal, unless redirected).
- The '-p' affects no disk files, leaving a "sticky tag" unaltered
- and avoiding all other side-effects of a normal "update".
-
- If you want to save the result, you can redirect "stdout" to a
- file using your shell's redirection capability. In most shells
- the following command works:
-
- cvs update -p -r <tag/rev> filename > diskfile
-
-
- 2D.5 What operations disregard sticky tags?
-
- The functions that routinely disregard sticky tags are:
-
- 1. Those that work directly on the Repository or its
- administrative files:
-
- admin rtag log status remove history
-
- 2. Those that take Tags or revisions as arguments and ignore
- everything else: (They also never *set* a sticky tag.)
-
- rdiff import export
-
- 3. The "release" command itself ignores sticky tags, but it
- calls "cvs -n update" (which *does* pay attention to a
- sticky tag) to figure out what inconsistencies exist in
- the working directory. If no discrepancies exist between
- the files you originally checked out (possibly marked by a
- sticky tag) and what is there now, "release -d" will
- delete them all.
-
- 4. The "tag" command works on the revision lying in the
- working directory however it got there. That the revision
- lying there might happen to have a sticky tag attached to
- it is not the "tag" command's concern.
-
-
- The main function that *does* read and write sticky tags is the
- "update" command. You can avoid referring to or changing the
- sticky tag by using the '-p' option, which sends files to your
- terminal, touching nothing else.
-
- The "checkout" command sets sticky tags when checking out a new
- module and it acts like "update" when checking out a module into
- an existing directory.
-
- The "diff" and "commit" commands use the sticky tags, unless
- overridden on the command line. They do not set sticky tags.
- Note that you can only "commit" to a file checked out with a
- sticky tag, if the tag identifies a branch.
-
- There are really two types of sticky tags, one attached to
- individual files (in the ./CVS/Entries file) and one attached to
- each directory (in the ./CVS/Tag file). They can differ.
-
- The "add" command registers the desire to add a new file. If the
- "directory tag" (./CVS/Tag) file exists at the time of the "add",
- the value stored in ./CVS/Tag becomes the "sticky tag" on the new
- file. The file doesn't exist in the Repository until you "commit"
- it, but the ./CVS/Entries file holds the sticky tag name from the
- time of the "add" forward.
-
-
- 2D.6 Is there a way to avoid reverting my Emacs buffer after
- committing a file? Is there a "cvs-mode" for Emacs?
-
- See Section 4F.1
-
-
- 2D.7 How does conflict resolution work? What *really* happens if two
- of us change the same file?
-
- While editing files, there is no conflict. You are working on
- separate copies of the file stored in the virtual "branch"
- represented by your working directories. After one of you commits
- a file, the other may not commit the same file until "update" has
- merged the earlier committed changes into the later working file.
-
- For example, say you both check out rev 1.2 of <file> and make
- change to your working files. Your coworker commits revision 1.3.
- When you try to commit your file, CVS says:
-
- cvs commit: Up-to-date check failed for `<file>'
-
- You must merge your coworker's changes into your working file by
- typing:
-
- cvs update <file>
-
- which will produce the output described in 2B.6.
-
- If a conflict occurs, the filename will be shown with a status of
- 'C'. After you resolve any overlaps caused by the merging
- process, you may then commit the file. See 3P.6 for info on
- "sticky conflicts".
-
- Even if you get a simple 'M', you should examine the differences
- before committing the file. A smooth, error-free text merge is
- still no indication that the file is in proper shape. Compile and
- test it at least.
-
- The answer to two obvious questions is "Yes".
-
- Yes, the first one who commits avoids the merge. Later developers
- have to merge the earlier changes into their working files before
- committing the merged result. Depending on how difficult the merge
- is and how important the contending projects are, the order of
- commits and updates might have to be carefully staged.
-
- And yes, between the time you execute "update" and "commit" (while
- you are fixing conflicts and testing the results) someone else may
- commit another revision of <file>. You will have to execute
- "update" again to merge the new work before committing. Most
- organizations don't have this problem. If you do, you might
- consider splitting the file. Or hiring a manager.
-
-
- 2D.8 How can I tell who has a module checked out?
-
- If you "checkout" module names (not relative pathnames) and you
- use the release command, the "history" command will display active
- checkouts, who has them and where they were checked out. It is
- advisory only; it can be circumvented by using the '-l' option on
- the main "cvs" command.
-
-
- 2D.9 Where did the .#<file>.1.3 file in my working directory come from?
-
- It was created during an "update" when CVS merged changes from the
- Repository into your modified working file.
-
- It serves the same purpose as any "backup" file: saving your bacon
- often enough to be worth retaining. It is invaluable in
- recovering when things go wrong.
-
- Say Developers A (you) and B check out rev 1.3 of file <file>.
- You both make changes -- different changes. B commits first, so
- <file>,v in the Repository contains revisions up through 1.4.
-
- At this point, there are 5 (yes, five) versions of the file of
- interest to you:
-
- 1. Revision 1.3 (What you originally checked out.)
- 2. Revision 1.4 (What you need from developer B.)
- 3. Your old working file. (Before the update.)
- 4. Your new working file. (After the merge caused by "update".)
- 5. Revision 1.5 (Which you will commit shortly.)
-
- In the case where your working file was not modified, #1 and #3
- will be the same, as will #2 and #4. In this degenerate case,
- there is no need to create #5. The following assumes that your
- working file was modified.
-
- If the merge executed by the "update" caused no overlaps, and you
- commit the file immediately, #4 and #5 will be the same. But you
- can make arbitrary changes before committing, so the difference
- between #4 and #5 might be more than just the correction of
- overlaps. In general, though, you don't need #4 after a commit.
-
- But #3 (which is the one saved as ".#<file>.1.3") holds all of
- your work, independent of B's work. It could represent a major
- effort that you couldn't afford to lose. If you don't save it
- somewhere, the merge makes #3 *disappear* under a potential
- blizzard of conflicts caused by overlapping changes.
-
- I have been saved a few times, and others I support have been
- saved hundreds of times, by the ability to "diff <original file>
- <original file with only my work added>", which can be done in the
- example above by the Unix shell command:
-
- cvs update -p -r 1.3 <file> | diff - .#<file>.1.3
-
- The assumption is that the ".#" files will be useful far beyond
- the "commit" point, but not forever. You are expected to run
- the "normal" Unix cleanup script from "cron", which removes "#*"
- and ".#*" files older than a some period chosen by your
- sysadmin, usually ranging from 7 to 30 days.
-
- A question was raised about the need for #3 after #5 has been
- committed, under the assumption that you won't commit files until
- everything is exactly as you like them.
-
- This assumes perfect humans, which violates one of the Cardinal
- rules of Software Engineering: Never assume any form of discipline
- on the part of the users of software. If restrictions are not
- bound into the software, then you, the toolsmith, have to arrange
- a recovery path.
-
- In other words, I've seen every possible variety of screwup you
- can imagine in #5. There is no way to make assumptions about
- what "should" happen. I've seen #5 filled with zeros because of
- NFS failures, I've seen emacs core dumps that leave #5 in an
- unreasonable state, I've seen a foolish developer uppercase the
- whole file (with his "undo" size set low so he couldn't undo it)
- and decide that it would be less work to play with the
- uppercased file than to blow it away and start over. I've even
- seen committed files with conflict markers still in them, a sure
- sign of carelessness.
-
- There are all sorts of scenarios where having #3 is incredibly
- useful. You can move it back into place and try again.
-
-
- 2D.10 What is this "ignore" business? What is it ignoring?
-
- The "update" and "import" commands use collections of Unix
- wildcards to skip over files and directories matching any of those
- patterns.
-
- You may add to the built-in ignore list by adding lines of
- whitespace-separated wildcards to the following places: (They are
- read in this order.)
-
- 1. In a file named "cvsignore" in $CVSROOT/CVSROOT.
-
- A Repository Administrator uses this to add site-specific
- files and patterns to the built-in ignore list.
-
- 2. In a file named ".cvsignore" in your home directory.
-
- For user-specific files. For example, if you use "__" as
- your default junk file prefix, you can put "__*" in your
- .cvsignore file.
-
- People who play around exclusively in directory trees where the
- Makefiles are generated by "imake" or "configure" might want to
- put "Makefile" in their ignore list, since they are all
- generated and usually don't end up in the Repository.
-
- 3. In the CVSIGNORE environment variable.
-
- For session-specific files.
-
- 4. Via the '-I' option on "import" or "update" commands.
-
- For this-command-only files.
-
- 5. In a file named ".cvsignore" within each directory.
-
- The contents of a ".cvsignore" file in each directory is
- temporarily added to the ignore list. This way you can ignore
- files that are peculiar to that directory, such as executables
- and other generated files without known wildcard patterns.
-
- In any of the places listed above, a single '!' character nulls
- out the ignore list. A Repository administrator can use this to
- override, rather than enhance, the built-in ignore list. A user
- can choose to override the system-wide ignore list. For example,
- if you place "! *.o *.a" in your .cvsignore file, only *.o *.a
- files, plus any files a local-directory .cvsignore file, are
- ignored.
-
- A variant of the ignore-file scheme is used internally during
- checkout. "Module names" found in the modules file (or on the
- "checkout" command line) that begin with a '!' are ignored during
- checkout. This is useful to permanently ignore (if the '!' path
- is in the modules file) or temporarily ignore (if the '!' path is
- on the command line) a sub-directory within a Repository
- hierarchy. For example:
-
- cvs checkout !gnu/emacs/tests gnu/emacs
-
- would checkout the module (or relative path within $CVSROOT) named
- "gnu/emacs", but ignore the "tests" directory within it.
-
-
- 2D.11 Is there a way to set user-specific configuration options?
-
- User-specific configuration is available through use of a ".cvsrc"
- file in your home directory.
-
- CVS searches the first column of your ~/.cvsrc file for the cvs
- command name you invoked. If the command is found, the rest of
- the line is treated like a set of command line options, stuffed
- into the command line before the arguments you actually typed.
-
- For example, if you always want to see context diffs and you never
- want to have to delete a file before you run "cvs remove", then
- you should create a .cvsrc file containing the following:
-
- diff -c
- remove -f
-
- which will add the given options to every invocation of the given
- commands.
-
- [[The rest of this will be removed someday, when CVS changes.]]
-
- I would like to stop here with a comment that the command name to
- use is the full, canonical one. But the command that the cvsrc
- support uses is the string you typed on the command line, not the
- proper command. So to get the full effect of the above example,
- you should also add all the alternate command names:
-
- di -c
- dif -c
- rm -f
- delete -f
-
- There are two other limitations that will probably be fixed when
- CVS sprouts long option names:
-
- 1. It only affects options made available on the command line.
-
- There is a limited number of short options. With long option
- names, there is no problem. You can have as many long options
- as you like, affecting anything that looks malleable.
-
- 2. The existing command line options do not come in on/off pairs,
- so there is no easy way to override your ~/.cvsrc configuration
- for a single invocation of a command.
-
- Choosing a good set of long option pairs would fix this.
-
-
- 2D.12 Is it safe to interrupt CVS using Control-C?
-
- It depends on what you mean by "safe". ("Ah," said Arthur,
- "this is obviously some strange usage of the word *safe* that I
- wasn't previously aware of." -- Hitchhiker's Guide to the Galaxy)
-
- You won't hurt the underlying RCS files and if you are executing a
- command that only *reads* data, you will have no cleanup to do.
-
- But you may have to hit Control-C repeatedly to stop it. CVS uses
- the Unix "system" routine which blocks signals in the CVS parent
- process. A single Control-C during "system" will only halt the
- child process, usually some form of RCS command.
-
- If you don't hit another Control-C while the CVS process has
- control, it is likely to continue onto the next task assuming that
- the earlier one did its job. It is not enough to hit two
- Control-C's. You might simply kill two child processes and not
- interrupt CVS at all. Depending on the speed of your processor,
- your terminal and your fingers, you might have to hit dozens of
- Control-C's to stop the damn thing.
-
-
- Executing a CVS command, such as "commit" or "tag" that writes
- to the files is a different matter.
-
- Since CVS is not a full-fledged database, with what database
- people call "commit points", merely stopping the process will not
- back out the "transaction" and place you back in the starting
- blocks. CVS has no concept of an "atomic" transaction or of
- "backtracking", which means that a command can be half-executed.
-
- Hitting Control-C will usually leave lock files that you have to
- go clean up in the Repository.
-
- Example1:
-
- If you interrupt a multi-file "commit" in the middle of
- an RCS checkin, RCS will leave the file either fully
- checked-in or in its original state. But CVS might have
- been half-way through the list of files to commit. The
- directory or module will be inconsistent.
-
- To recover, you must remove the lock files, then decide
- whether you want to back out or finish the job.
-
- To back out, you'll have to apply the "admin -o"
- command, very carefully, to remove the newly committed
- revisions. This is usually a bad idea, but is
- occasionally necessary.
-
- To finish, you can simply retype the same commit command.
- CVS will figure out what files are still modified and
- commit them. It helps that RCS doesn't leave a file in an
- intermediate state.
-
-
- Example2:
-
- If you interrupt a multi-file "tag" command, you have a
- problem similar, but not equivalent, to interrupting a
- "commit". The RCS file will still be consistent, but
- unlike "commit", which only *adds* to the RCS file, "tag"
- can *move* a tag and it doesn't keep a history of what
- revision a tag used to be attached to.
-
- Normally, you have little choice but to re-execute the
- command and allow it to tag everything consistently.
-
- You might be able to recover by carefully re-applying the
- tags via the "cvs admin -N" command, but you'll still have
- to dig up from outside sources the information you use to
- determine what tag was on what revision in what file.
- the Repository, or by using the equivalent: "cvs admin".
-
-
- Halting a new "checkout" should cause no harm. If you don't want
- it, "release" (or rm -rf) it. If you do want it, re-execute the
- command. A repeated "checkout" from above a directory acts like a
- repeated "update -d" within it.
-
- Halting "update" half-way will give you an unpredictable
- collection of files and revisions. To continue, you can rerun the
- update and it should move you forward into in a known state. To
- back out, you'll have to examine the output from the first
- "update" command, take a look at each file that was modified and
- reconstruct the previous state by editing the ./CVS/Entries file
- and by using "cvs admin". Good Luck.
-
-
- 2D.13 How do I turn off the "admin" command?
-
- In the current revision, you'd have to edit the source code.
-
-
- 2D.14 How do I turn off the ability to disable history via "cvs -l"?
-
- In the current revision, you'd have to edit the source code.
-
-
- 2D.15 How do I keep certain people from accessing certain directories?
-
- If you don't try to run CVS set[ug]id, you can use Unix groups and
- permissions to limit access to the Repository.
-
- If you only want to limit "commit" commands, you can write a
- program to put in the "commitinfo" file. In the "contrib"
- directory, there are a few scripts that might help you out.
-
-
-
-========================================
-== Section 3 ==== Commands ====
-========================================
-
-This section contains questions that are easily recognized to be about a
-single command, usually of the form: "Why does the 'xyz' command do this?"
-
-Questions about "missing" features and side-effects not attributable to a
-particular command are in Section 2D, "General Questions".
-
-I won't provide patches here that are longer than a few lines. Patches
-referred to in this section are available in the FTP archive described
-toward the beginning of this document.
-
-
-----------------
--- Section 3A -- "add", "ad", "new"
-----------------
-
- **** Questions:
-
- 3A.1 What is "add" for?
- 3A.2 How do I add a new file to the branch I'm working on?
- 3A.3 Why did my new file end up in the Attic?
- 3A.4 Now that it's in the Attic, how do I connect it to the Main branch?
- 3A.5 How do I avoid the hassle of reconnecting an Attic-only file to
- the Main Branch?
- 3A.6 How do I cancel an "add"?
- 3A.7 What are the ./CVS/file,p and ./CVS/file,t files for?
- 3A.8 How do I "add" a binary file?
-
-
- **** Answers:
-
- 3A.1 What is "add" for?
-
- To add a new directory to the Repository or to register the
- desire to add a new file to the Repository.
-
- The directory is created immediately, while the desire to add the
- file is recorded in the local ./CVS administrative directory. To
- really add the file to the Repository, you must then "commit" it.
-
-
- 3A.2 How do I add a new file to the branch I'm working on?
-
- The user actions for adding a file to any branch, including the
- Main Branch, are exactly the same.
-
- You are in a directory checked out (or updated) with the '-A'
- option (to place you on the Main Branch) or the "-r <branch_tag>"
- option (to place you on a branch tagged with <branch_tag>). To
- add <file> to the branch you are on, you type:
-
- cvs add <file>
- cvs commit <file>
-
- If no ./CVS/Tag file exists (the '-A' option deletes it), the
- file will be added to the Main Branch. If a ./CVS/Tag file exists
- (the "-r <branch_tag>" option creates it), the file will be added
- to the branch named (i.e. tagged with) <branch_tag>.
-
- Unless you took steps to first add the file to the Main Branch,
- your new file ends up in the Attic.
-
-
- 3A.3 Why did my new file end up in the Attic?
-
- The file is thrown into the Attic to keep it from being visible
- when you check out the Main Branch, since it was never committed
- to the Main Branch.
-
-
- 3A.4 Now that it's in the Attic, how do I connect it to the Main branch?
-
- That can be considered a kind of "merge". See 4C.8
-
-
- 3A.5 How do I avoid the hassle of reconnecting an Attic-only file to
- the Main Branch?
-
- You create it on the Main Branch first, then branch it.
-
- If you haven't yet added the file or if you decided to delete the
- new Attic file and start over, then do the following:
- (If you added the file (or worse, the 157 files) to the Attic and
- don't want to start over, try the procedure in 4C.8.)
-
-
- 1. Temporarily remove the sticky branch information. Either:
-
- A. Move the whole directory back to the Main Branch.
- [This might not be a good idea if you have modified files,
- since it will require a merge in each direction.]
-
- cvs update -A
-
- *or*
-
- B. Move the ./CVS/Tag file out of the way.
-
- mv ./CVS/Tag HOLD_Tag
-
- 2. Add and branch the file "normally":
-
- cvs add <file>
- cvs commit <file>
- cvs tag -b <branch_tag> <file>
-
- [<branch_tag> is the same Branch Tag as you used on all
- the other files. Look at ./CVS/Entries or the output
- from "cvs stat" for sticky tags.]
-
- 3. Clean up the temporary step.
-
- A. If you moved the ./CVS/Tag file, put it back. Then
- move the new file onto the branch where you are working.
-
- mv HOLD_Tag ./CVS/Tag
- cvs update -r <branch_tag> <file>
-
- B. If you ran "update -A" rather than moving the ./CVS/Tag
- file, move the whole directory (including the new file) back
- onto the branch where you were working:
-
- cvs update -r <branch_tag>
-
-
- 3A.6 How do I cancel an "add"?
-
- If you want to remove the file entirely and cancel the "add" at
- the same time, type:
-
- cvs remove -f <file>
-
- If you want to cancel the "add", but leave the file as it was
- before you typed "cvs add", then you have to fake it:
-
- mv <file> <file>.hold
- cvs remove <file>
- mv <file>.hold <file>
-
-
- 3A.7 What are the ./CVS/file,p and ./CVS/file,t files for?
-
- The ./CVS/file,p and ./CVS/file,t files are created by the "add"
- command to hold command line options and message text between the
- time of the "add" command and the expected "commit".
-
- The ./CVS/file,p file is always null, since its function was
- absorbed by the "options" field in the ./CVS/Entries file. If you
- put something in this file it will be used as arguments to the RCS
- "ci" command that commit uses to check the file in, but CVS itself
- doesn't put anything there.
-
- The ./CVS/file,t file is null unless you specify an initial
- message in an "add -m 'message'" command. The text is handed to
- "rcs -i -t./CVS/file,t" to create the initial RCS file container.
-
- Both files must exist to commit a newly added file. If the
- ./CVS/file,p file doesn't exist, CVS prints an error and aborts
- the commit. If the ./CVS/file,t file doesn't exist, RCS prints an
- error and CVS gets confused, but does no harm.
-
- To recover from missing ,p and ,t files, just create two
- zero-length files and rerun the "commit".
-
-
- 3A.8 How do I "add" a binary file?
-
- If you configured CVS to use the GNU version of "diff" and
- "diff3", you only need to turn off RCS keyword expansion.
-
- First you turn off RCS keyword expansion for the initial checkin
- by using "add -ko". It works like "update -ko" in creating a
- "sticky" option only for the copy of the file in the current
- working directory.
-
- cvs add -ko <file>
-
- Commit the file normally. The sticky -ko option will be used.
-
- cvs commit <file>
-
- Then mark the RCS file in the Repository so that keyword
- expansion is turned off for all checked out versions of the file.
-
- cvs admin -ko <file>
-
- Since "admin -ko" records the keyword substitution value in the
- Repository's RCS file, you no longer need the sticky option. You
- can turn it off with the "update -A" command, but if you were on a
- branch, you'll have to follow it "update -r <branch_tag>" to put
- yourself back on the branch.
-
-
- Managing that binary file is another problem. See 4D.1.
-
-
-
-----------------
--- Section 3B -- "admin", "adm", "rcs"
-----------------
-
- **** Questions:
-
- 3B.1 What is "admin" for?
- 3B.2 Wow! Isn't that dangerous?
- 3B.3 What would I normally use "admin" for?
- 3B.4 What should I avoid when using "admin"?
- 3B.5 How do I restrict the "admin" command? The -i flag in the modules
- file can restrict commits. What's the equivalent for "admin"?
- 3B.6 I backed out a revision with "admin -o" and committed a
- replacement. Why doesn't "update" retrieve the new revision?
-
-
- **** Answers:
-
-
- 3B.1 What is "admin" for?
-
- To provide direct access to the underlying "rcs" command (which
- is not documented in this FAQ) bypassing all safeguards and CVS
- assumptions.
-
-
- 3B.2 Wow! Isn't that dangerous?
-
- Yes.
-
- Though you can't hurt the internal structure of an RCS file using
- its own "rcs" command, you *can* change the underlying RCS
- files using "admin" in ways that CVS can't handle.
-
- If you feel the need to use "admin", create some test files
- with the RCS "ci" command and experiment on them with "rcs"
- before blasting any CVS files.
-
-
- 3B.3 What would I normally use "admin" for?
-
- Normally, you wouldn't use admin at all. In unusual
- circumstances, experts can use it to set up or restore the
- internal RCS state that CVS requires.
-
- You can use "admin -o" (for "outdate") to remove revisions
- you don't care about. This has its own problems, such as leaving
- dangling Tags and confusing the "update" command.
-
- There is some feeling among manipulators of binary files that
- "admin -l" should be used to serialize access. See 3C.8.
-
- An interesting use for "admin" came up while maintaining CVS
- itself. I import versions of CVS onto the Vendor branch of my
- copy of CVS, make changes to some files and ship the diffs
- (created by "cvs diff -c -r TO_BRIAN") off to Brian Berliner.
- After creating the diff, I retag ("cvs tag -F TO_BRIAN") the
- working directory, which is then ready to produce the next patch.
-
- I'll use "add.c" as an example (only because the name is short).
-
- When the next release came out, I discovered that the released
- "add.c" (version 1.1.1.3 on the Vendor branch) was exactly the
- same as my modified file (version 1.3). I didn't care about the
- changelog on versions 1.2 and 1.3 (or the evidence of having done
- the work), so I decided to revert the file to the state where it
- looked like I had not touched the file -- where I was just using
- the latest on the vendor branch after a sequence of imports.
-
- To do that, I removed all the revisions on the main branch, except
- for the original 1.1 from which the Vendor branch sprouts:
-
- cvs admin -o1.2: add.c
-
- Then I set the RCS "default branch" back to the Vendor branch, the
- way import would have created it:
-
- cvs admin -b1.1.1 add.c
-
- And I moved the "TO_BRIAN" Tag to the latest revision on the
- Vendor branch, since that is the base from which further patches
- would be created (if I made any):
-
- cvs admin -NTO_BRIAN:1.1.1.3 add.c
-
- Instead of 1.1.1.3, I could have used one of the "Release Tags"
- last applied by "import" (3rd through Nth arguments).
-
- Suggestion: Practice on non-essential files.
-
-
-
- 3B.4 What should I avoid when using "admin"?
-
- If you know exactly what you are doing, hack away. But under
- normal circumstances:
-
- Never use "admin" to alter branches (using the '-b' option), which
- CVS takes very seriously. If you change the default branch, CVS
- will not work as expected. If you create new branches without
- using the "tag -b" command, you may not be able to treat them as
- CVS branches.
-
- See 3C.8 for a short discussion of how to use "admin -l" for
- serializing access to binary files.
-
- The "admin -o <file>" allows you to delete revisions, usually a
- bad idea. You should commit a correction rather than back out a
- revision. Outdating a revision is prone to all sorts of problems:
-
- 1. Discarding data is always a bad idea. Unless something in the
- revision you just committed is a threat to your job or your
- life, (like naming a function "<boss's name>_is_a_dweeb", or
- including the combination to the local Mafioso's safe in a C
- comment), just leave it there. No one cares about simple
- mistakes -- just commit a corrected revision.
-
- 2. The time travel paradoxes you can cause by changing history
- are not worth the trouble. Even if CVS can't interfere with
- your parents' introduction, it *can* log commits in at least
- two ways (history and loginfo). The reports now lie -- the
- revision referred to in the logs no longer exists.
-
- 3. If you used "import" to place <file> into CVS, outdating all
- the revisions on the Main branch back to and including revision
- 1.2 (or worse, 1.1), will produce an invalid CVS file.
-
- If the <file>,v file only contains revision 1.1 (and the
- connected branch revision 1.1.1.1), then the default branch
- must be set to the Vendor branch as it was when you first
- imported the file. Outdating back through 1.2 doesn't restore
- the branch setting. Despite the above admonition against it,
- "admin -b" is the only way to recover:
-
- cvs admin -b1.1.1 <file>
-
- 4. Although you can't outdate a physical (RCS) branch point
- without removing the whole branch, you *can* outdate a revision
- referred to by a magic branch tag. If you do so, you will
- invalidate the branch.
-
- 5. If you "outdate" a tagged revision, you will invalidate all
- uses of the <tag>, not just the one on <file>. A tag is
- supposed to be attached to a consistent set of files, usually a
- set built as a unit. By discarding one of the files in the
- set, you have destroyed the utility of the <tag>. And it
- leaves a dangling tag, which points to nothing.
-
- 6. And even worse, if you commit a revision already tagged, you
- will alter what the <tag> pointed to without using the "tag"
- command. For example, if revision 1.3 has <tag> attached to it
- and you "outdate" the 1.3 revision, <tag> will point to a
- nonexistent revision. Although this is annoying, it is nowhere
- near as much trouble as the problem that will occur when you
- commit to this file again, recreating revision 1.3. The old
- tag will point to the new revision, a file that was not in
- existence when the <tag> was applied. And the discrepancy is
- nearly undetectable.
-
-
- If you don't understand the above, you should not use the admin
- command at all.
-
-
- 3B.5 How do I restrict the "admin" command? The -i flag in the modules
- file can restrict commits. What's the equivalent for "admin"?
-
- At this writing, to disable the "admin" command, you will have
- to change the program source code, recompile and reinstall.
-
-
- 3B.6 I backed out a revision with "admin -o" and committed a
- replacement. Why doesn't "update" retrieve the new revision?
-
- CVS is confused because the revision in the ./CVS/Entries file
- matches the latest revision in the Repository *and* the timestamp
- in the ./CVS/Entries file matches your working file. CVS believes
- that your file is "up-to-date" and doesn't need to be updated.
-
- You can cause CVS to notice the change by "touch"ing the file.
- Unfortunately what CVS will tell you is that you have a "Modified"
- file. If you then "commit" the file, you will bypass the
- normal CVS check for "up-to-date" and will probably commit the
- revision that was originally removed by "admin -o".
-
- Changing a file without changing the revision number confuses CVS
- no matter whether you did it by replacing the revision (using
- "admin -o" and "commit" or raw RCS commands) or by applying an
- editor directly to a Repository (",v") file. Don't do it unless
- you are absolutely certain no one has the latest revision of the
- file checked out.
-
- The best solution to this is to institute a program of deterrent
- flogging of abusers of "admin -o".
-
- The "admin" command has other problems." See 3B.4 above.
-
-
-----------------
--- Section 3C -- "checkout", "co", "get"
-----------------
-
- **** Questions:
-
- 3C.1 What is "checkout" for?
- 3C.2 What is the "module" that "checkout" takes on the command line?
- 3C.3 Isn't a CVS "checkout" just a bunch of RCS checkouts?
- 3C.4 What's the difference between "update" and "checkout"?
- 3C.5 Why can't I check out a file from within my working directory?
- 3C.6 How do I avoid dealing with those long relative pathnames?
- 3C.7 Can I move a checked-out directory? Does CVS remember where it
- was checked out?
- 3C.8 How can I lock files while I'm working on them the way RCS does?
- 3C.9 What is "checkout -s"? How is it different from "checkout -c"?
-
-
- **** Answers:
-
- 3C.1 What is "checkout" for?
-
- To acquire a copy of a module (or set of files) to work on.
-
- All work on files controlled by CVS starts with a "checkout".
-
-
- 3C.2 What is the "module" that "checkout" takes on the command line?
-
- It is a name for a directory or a collection of files in the
- Repository. It provides a compact name space and the ability to
- execute before and after helper functions based on definitions in
- the modules file.
-
- See 1D.11.
-
-
- 3C.3 Isn't a CVS "checkout" just a bunch of RCS checkouts?
-
- Like much of CVS, a similar RCS concept is used to support a CVS
- function. But a CVS checkout is *not* the same as an RCS
- checkout.
-
- Differences include:
-
- 1. CVS does not lock the files. Others may access them at the
- same time.
-
- 2. CVS works best when you provide a name for a collection of
- files (a module or a directory) rather than an explicit list of
- files to work on.
-
- 3. CVS remembers what revisions you checked out and what branch
- you are on, simplifying later commands.
-
-
- 3C.4 What's the difference between "update" and "checkout"?
-
- The "checkout" and "update" commands are nearly equivalent in how
- they treat individual files. They differ in the following ways:
-
- 1. The "checkout" command always creates a directory, moves into
- it, then becomes equivalent to "update -d".
-
- 2. The "update" command does not create directories unless you add
- the '-d' option.
-
- 3. "Update" is intended to be executed within a working directory
- created by "checkout". It doesn't take a module or directory
- argument, but figures out what Repository files to look at by
- reading the files in the ./CVS administrative directory.
-
- 4. The two commands generate completely different types of records
- in the "history" file.
-
-
- 3C.5 Why can't I check out a file from within my working directory?
-
- Though you *can* check out a file, you normally check out a module
- or directory. And you normally do it only once at the beginning
- of a project.
-
- After the initial "checkout", you can use the "update" command
- to retrieve any file you want within the checked-out directory.
- There is no need for further "checkout" commands.
-
- If you want to retrieve another module or directory to work on,
- you must provide two pathnames: where to find it in the Repository
- and where to put it on disk. The "modules" file and your current
- directory supply two pieces of naming information. While inside a
- checked-out working directory, the CVS administrative information
- provides most of the rest.
-
- You should be careful not to confuse CVS with RCS and use
- "checkout" in the RCS sense. An RCS "checkout" (which is
- performed by the RCS "co" command) is closer to a "cvs update"
- than to a "cvs checkout".
-
-
- 3C.6 How do I avoid dealing with those long relative pathnames?
-
- This question has also been phrased:
-
- How do I avoid all those layers of directories on checkout?
- or
- Why do I have to go to the top of my working directory and
- checkout some long pathname to get a file or two?
-
-
- This type of question occurs only among groups of people who
- decide not to use "modules". The answer is to use "modules".
-
- When you hand the "checkout" command a relative pathname rather
- than a module name, all directories in the path are created,
- maintaining the same directory hierarchy as in the Repository.
- The same kind of environment results if you specify a "module"
- that is really an alias expanding into a list of relative
- pathnames rather than a list of module names.
-
- If you use "module" names, "checkout" creates a single
- directory by the name of the module in your current directory.
- This "module" directory becomes your working directory.
-
- The "module" concept combines the ability to "name" a collection
- of files with the ability to structure the Repository so that
- consistent sets of files are checked out together. It is the
- responsibility of the Repository Administrators to set up a
- modules file that describes the software within the Repository.
-
-
- 3C.7 Can I move a checked-out directory? Does CVS remember where it
- was checked out?
-
- Yes and Yes.
-
- The ./CVS/Repository file in each working directory contains a
- pathname pointing to the matching directory within the
- Repository. The pathname is either absolute or relative to
- $CVSROOT, depending on how you configured CVS.
-
- When you move a checked-out directory, the CVS administrative
- files will move along with it. As long as you don't move the
- Repository itself, or alter your $CVSROOT variable, the moved
- directory will continue to be usable.
-
- CVS remembers where you checked out the directory in the
- "history" file, which can be edited, or even ignored if you
- don't use the "working directory" information displayed by the
- "history" command.
-
-
- 3C.8 How can I lock files while I'm working on them the way RCS does?
-
- Until the day arrives of the all-powerful merge tool, there are
- still files that must be accessed serially. For those instances,
- here's a potential solution:
-
- 1. Install a pre-commit program in the "commitinfo" file to check
- for RCS locks. The program "rcslock.pl" performs this
- function. It can be found in the contrib directory of the CVS
- source distribution.
-
- 2. When you want to make a change to a file you know can't be
- merged, first use "cvs admin -l" to lock the file. If you
- can't acquire the lock, use the standard "locked out" protocol:
- go talk to the person holding the lock.
-
- 3. Make sure the pre-commit program prints a message and exits
- with a non-zero status if someone besides the user running
- "commit" has the file locked. This non-zero exist status will
- cause the "commit" to fail cleanly.
-
- 4. Make sure the pre-commit program exits with a zero status if
- the file is either unlocked or locked by the user running
- "commit". The "cvs commit" command that kicked off the
- pre-commit program will take a zero exist status as an OK and
- checkin the file, which has the side-effect of unlocking it.
-
-
- ===> The following is opinion and context. Don't read it if you
- are looking for a quick fix.
-
- The topic of locking CVS files resurfaces on the network every so
- often, producing the same results each time:
-
- The Big Endians:
-
- CVS was designed to avoid locks, using a copy-modify-merge
- model. Locking is not necessary and you should take the time
- to learn the CVS model which many people find workable. So why
- not get with the program and learn how to think the CVS way?
-
- The Little Endians:
-
- The users determine how a tool is to be used, not the
- designers. We, the users, have always used locking, our bosses
- demand locking, locking is good, locking is God. I don't want
- to hear any more lectures on the CVS model. Make locking work.
-
- Any organization making active changes to a source base will
- eventually face the need to do parallel development. Parallel
- development implies merges. (If you plan to keep separate copies
- of everything and never merge, good luck. Tell me who you work
- for so I can buy stock in your disk suppliers this year and sell
- your stock short next year.)
-
- Merges will never go away. CVS chose to make "merges" stand
- front and center as an important, common occurrence in
- development. It is one way of looking at things.
-
- For free-format text, the merge paradigm gives you a considerable
- amount of freedom. It does take a bit of management, but any
- project should be ready to deal with it.
-
- On the other hand, there are many files that can't be merged using
- text merge techniques. Straight text merge programs like "diff3"
- are guaranteed to fail on executables (with relative branch
- statements), files with self-referential counts stored in the file
- (such as TAGS files), or files with relative motion statements in
- them (such as Frame MIF files, many postscript files). They
- aren't all binary files.
-
- For these types of files, and many others, there are only two
- solutions:
-
- 1. Complex merge tools that are intimately aware of the contents
- of the files to be merged. (ClearCase, and probably others,
- allow you to define your own "files types" with associated
- "merge tools".)
-
- 2. Serialization of access to the file. The only technical
- solution to the problem of serialization is "locking".
-
-
- Since you can call a program that offers:
-
- "Which one do you want? A/B?"
-
- a "merge tool", more and more merge tools will appear which can be
- hooked into a merge-intensive program like CVS. Think of a bitmap
- "merge" tool that displays the bitmaps on the screen and offers a
- "paint" interface to allow you to cut and paste, overlay, invert
- or fuse the two images such that the result is a "merged" file.
-
- My conclusion is that the need for locking is temporary, awaiting
- better technology. For large development groups, locking is not
- an alternative to merging for text files.
-
-
- 3C.9 What is "checkout -s"? How is it different from "checkout -c"?
-
- The '-c' and '-s' options to "checkout" both cause the modules
- file to appear on standard output, but formatted differently.
-
- "checkout -c" lists the modules file alphabetized by the module
- name. It also prints all data (including options like '-a' and
- "-o <prog>") specified in the modules file.
-
- "checkout -s" lists the modules file sorted by "status" field,
- then by module name. The status field was intended to allow you
- to mark modules with strings of your choice to get a quick sorted
- report based on the data you chose to put in the status fields. I
- have used it for priority ("Showstopper", etc as tied into a bug
- database), for porting status ("Ported", "Compiled", etc. when
- porting a large collection of modules), for "assignee" (the person
- responsible for maintenance), and for "test suite" (which
- automatic test procedure to run for a particular module).
-
-
-----------------
--- Section 3D -- "commit", "ci", "com"
-----------------
-
- **** Questions:
-
- 3D.1 What is "commit" for?
- 3D.2 If I edit ten files, do I have to type "commit" ten times?
- 3D.3 Explain: cvs commit: Up-to-date check failed for `<file>'
- 3D.4 What happens if two people try to "commit" conflicting changes?
- 3D.5 I committed something and I don't like it. How do I remove it?
- 3D.6 Explain: cvs commit: sticky tag `V3' for file `X' is not a branch
- 3D.7 Why does "commit -r <tag/rev>" put newly added files in the Attic?
- 3D.8 Why would a "commit" of a newly added file not produce rev 1.1?
-
-
- **** Answers:
-
- 3D.1 What is "commit" for?
-
- To store new revisions in the Repository, making them visible
- to other users.
-
-
- 3D.2 If I edit ten files, do I have to type "commit" ten times?
-
- No. The "commit" command will take multiple filenames, directory
- names and relative pathnames on the command line and commit them
- all with the same log message. If a file is unchanged, even if it
- is explicitly listed on the command line, CVS will skip it.
-
- Like all CVS commands, "commit" will work on the whole directory
- by default. Just type "cvs commit" to tell CVS to commit all
- modified files (i.e. the files that "update" would display
- preceded by 'M') in the current directory and in all
- sub-directories.
-
-
- 3D.3 Explain: cvs commit: Up-to-date check failed for `<file>'
-
- You may not "commit" a file if your BASE revision (i.e. the
- revision you last checked out, committed or retrieved via
- "update") doesn't match the HEAD revision (i.e the latest revision
- on your branch, usually the Main Branch).
-
- In other words, someone committed a revision since you last
- executed "checkout", "update" or "commit". You must now execute
- "update" to merge the other person's changes into your working
- file before "commit" will work. You are thus protected (somewhat)
- from a common form of race condition in source control systems,
- where a checkin of a minor alteration of a second copy of the same
- base file obliterates the changes made in the first.
-
- Normally, the "update" command's auto-merge should be followed
- by another round of building and testing before the "commit".
-
-
- 3D.4 What happens if two people try to "commit" conflicting changes?
-
- Conflicts can occur only when two developers check out the same
- revision of the same file and make changes. The first developer
- to commit the file has no chance of seeing the conflict. Only the
- second developer runs into it, usually when faced with the
- "Up-to-date" error explained in the previous question.
-
- There are two types of conflicts:
-
- 1. When two developers make changes to the same section of code,
- the auto-merge caused by "update" will print a 'C' on your
- terminal and leave "overlap" markers in the file.
-
- You are expected to examine and clean them up before committing
- the file. (That may be obvious to *some* of you, but . . .)
-
- 2. A more difficult problem arises when two developers change
- different sections of code, but make calls to, or somehow
- depend on, the old version of each other's code.
-
- The auto-merge does the "right" thing, if you view the file
- as a series of text lines. But as a program, the two
- developers have created a problem for themselves.
-
- This is no different from making cross-referential changes in
- *separate* files. CVS can't help you. In a perfect world, you
- would each refer to the specification and resolve it
- independently. In the real world you have to talk/argue, read
- code, test and debug until the combined changes work again.
-
- Welcome to the world of parallel development.
-
-
- 3D.5 I committed something and I don't like it. How do I remove it?
-
- Though you *can* use the "admin -o" (synonym: "rcs -o") command to
- delete revisions, unless the file you committed is so embarrassing
- that the need to eradicate it overrides the need to be careful,
- you should just grab an old version of the file ("update -p -r
- <previous-rev>" might help here) and commit it on top of the
- offending revision.
-
- See Section 3B on "admin".
-
-
- 3D.6 Explain: cvs commit: sticky tag `V3' for file `X' is not a branch
-
- The message implies two things:
-
- 1. You created your working directory by using "checkout -r
- V3", or you recently executed "update -r V3".
-
- 2. The tag named V3 is not a branch tag.
-
-
- CVS records (i.e. makes "sticky") any "-r <tag/rev>" argument
- handed to the "checkout" or "update" commands. The <tag/rev> is
- recorded as the CVS working branch, which is the branch to which
- "commit" will add a new revision.
-
- Branch tags are created when you use the -b switch on the "tag" or
- "rtag" commands. Branch tags are magic tags that don't create a
- physical branch, but merely mark the revision to branch from when
- the branch is needed. The first commit to a magic branch creates
- a physical branch in the RCS files.
-
- You can commit onto the end of the Main Trunk, if you have no
- sticky tag at all, or onto the end of a branch, if you have a
- sticky branch tag. But you can't commit a file that has a sticky
- tag not pointing to a branch. CVS assumes a sticky Tag or
- Revision that does not refer to a branch is attached to the middle
- of a series of revisions. You can't squeeze a new revision
- between two others. Sticky dates also block commits since they
- never refer to a branch.
-
-
- Scenario1:
-
- If you don't want a branch and were just looking at an old
- revision, then you can move back to the Main Branch by typing:
-
- cvs update -A {files or dirs, default is '.'}
-
- or you can move to the branch named <branch_tag> by:
-
- cvs update -r <branch_tag> {files or dirs, default is '.'}
-
-
- Scenario2:
-
- If you really wanted to be on a branch and made an earlier
- mistake by tagging your branch point with a non-branch tag,
- you can recover by adding a new branch tag to the old
- non-branch tag:
-
- cvs rtag -b -r <oldtag> <newtag> <module>
-
- (It was not a big mistake. Branch-point tags can be useful.
- But the <newtag> must have a different name.)
-
- If you don't know the <module> name or don't use "modules",
- you can also use "tag" this way:
-
- cvs update -r <oldtag>
- cvs tag -b <newtag> .
-
- Then, to put your working directory onto the branch, you type:
-
- cvs update -r <newtag>
-
-
- You can't delete <oldtag> before adding <newtag>, and I would
- not advise deleting the <oldtag> at all, because it is useful
- in referring to the branch point. If you must, you can delete
- the non-branch tag by:
-
- cvs rtag -d <oldtag> <module>
- or
- cvs tag -d <oldtag> .
-
-
- Scenario3:
-
- If you made the same mistake as in Scenario2 (of placing a
- non-branch tag where you wanted a branch tag), but really want
- <oldtag> to be the name of your branch, you can execute a
- slightly different series of commands to rename it and move
- your working directory onto the branch.
-
- Warning: This is not a way to rename a branch tag. It is a way
- to turn a non-branch tag into a branch tag with the
- same name.
-
- cvs rtag -r <oldtag> <branch_point_tag> <module>
- cvs rtag -d <oldtag> <module>
- cvs rtag -b -r <branch_point_tag> <oldtag> <module>
-
- Then, if you really must, delete the <branch_point_tag>:
-
- cvs rtag -d <branch_point_tag> <module>
-
-
-
- Note: The unwieldy mixture of "tag" and "rtag" is mostly
- because you can't specify a revision (-r <tag>) to the
- "tag" command.
-
- See 4C.3 for more info on creating a branch.
-
-
- 3D.7 Why does "commit -r <tag/rev>" put newly added files in the Attic?
-
- If you specify "-r <rev>" (where <rev> is a dotted numeric number
- like 2.4), it correctly sets the initial revision to <rev>, but it
- also attaches the numeric <rev> as a sticky tag and throws the
- file into the Attic. This is a bug. The obvious solution is to
- move the file out of the Attic into the associated Repository
- directory and "update -A" the file. There are no Tags to clean up.
-
- If you specify "-r <tag>" to commit a newly added file, the <tag>
- is treated like a <branch_tag>, which becomes a symbolic RCS label
- pointing to the string '1', which can be considered to be the
- "Main branch number" when the main branch is still at revision
- 1.N. The file is also thrown into the Attic. See 4C.8 for a way
- to recover from this.
-
- In fact, a plain "commit" without the "-r" will throw a newly
- added file into the Attic if you added it to a directory checked
- out on a branch. See 3A.[2-5].
-
- See Section 4C, on Branching, for many more details.
-
-
- 3D.8 Why would a "commit" of a newly added file not produce rev 1.1?
-
- When committing a newly added file CVS looks for the highest main
- branch major number in all files in the ./CVS/Entries file.
- Normally it is '1', but if you have a file of revision 3.27 in
- your directory, CVS will find the '3' and create revision 3.1 for
- the first rev of <file>. Normally, the first revision is 1.1.
-
-
-----------------
--- Section 3E -- "diff", "di", "dif"
-----------------
-
- **** Questions:
-
- 3E.1 What is "diff" for?
- 3E.2 Why did "diff" display nothing when I know there are later
- committed revisions in the Repository?
- 3E.3 How do I display what changed in the Repository since I last
- executed "checkout", "update" or "commit"?
- 3E.4 How do I display the difference between my working file and what
- I checked in last Thursday?
- 3E.5 Why can't I pass long options, like --unified, to "diff"?
-
-
- **** Answers:
-
- 3E.1 What is "diff" for?
-
- 1. To display the difference between a working file and its BASE
- revision (the revision last checked out, updated or committed):
-
- cvs diff <file>
-
- 2. To display the difference between a working file and a
- committed revision of the same file:
-
- cvs diff -r <tag/rev> <file>
-
- 3. To display the difference between two committed revisions of
- the same file:
-
- cvs diff -r <tag1/rev1> -r <tag2/rev2> <file>
-
- You can specify any number of <file> arguments. Without any
- <file> arguments, it compares the whole directory.
-
- In the examples above, "-D <date>" may be substituted wherever
- "-r <tag/rev>" appears. The revision a <date> refers to is the
- revision that existed on that date.
-
-
- 3E.2 Why did "diff" display nothing when I know there are later
- committed revisions in the Repository?
-
- By default, "diff" displays the difference between your working
- file and the BASE revision. If you haven't made any changes to
- the file since your last "checkout", "update" or "commit" there is
- no difference to display.
-
- To display the difference between your working file and the latest
- revision committed to your current branch, type:
-
- cvs diff -r HEAD <file>
-
-
- 3E.3 How do I display what changed in the Repository since I last
- executed "checkout", "update" or "commit"?
-
- A special tag (interpreted by CVS -- it does not appear in the Tag
- list) named "BASE" always refers to the revision you last checked
- out, updated or committed. Another special tag named "HEAD"
- always refers to the latest revision on your working branch.
-
- To compare BASE and HEAD, you type:
-
- cvs diff -r BASE -r HEAD <file>
-
-
- 3E.4 How do I display the difference between my working file and what
- I checked in last Thursday?
-
- cvs diff -D "last Thursday" <file>
-
- where "last Thursday" is a date string. To be more precise, the
- argument to the '-D' option is a timestamp. Many formats are
- accepted. See the man page under "-D date_spec" for details.
-
-
- 3E.5 Why can't I pass long options, like --unified, to "diff"?
-
- CVS only handles single character '-X' arguments, not the FSF long
- options. CVS also passes through only arguments it knows about,
- because a few arguments are captured and interpreted by CVS.
-
- If you didn't configure RCS and CVS to use the GNU version of
- diff, long options wouldn't work even if future versions of CVS
- acquire the ability to pass them through.
-
- Most of the long options have equivalent single-character options,
- which do work. The "--unified" option is equivalent to '-u' in
- revisions of GNU diff since 1.15.
-
-
-
-----------------
--- Section 3F -- "export", "exp", "ex"
-----------------
-
- **** Questions:
-
- 3F.1 What is "export" for?
- 3F.2 Why does it remove the RCS keywords so I can't use the "ident"
- command on the source files?
- 3F.3 Can I override the '-kv' flag CVS passes to RCS?
- 3F.4 Why doesn't "export" have a '-k' flag like "import" does?
- 3F.5 Why does "export -D" check out every file in the Attic?
-
-
- **** Answers:
-
- 3F.1 What is "export" for?
-
- "export" checks out a copy of a module in a form intended for
- export outside the CVS environment. The "export" command produces
- the same directory and file structure as the "checkout" command,
- but it doesn't create "CVS" sub-directories and it removes all the
- RCS keywords from the files.
-
-
- 3F.2 Why does it remove the RCS keywords so I can't use the "ident"
- command on the source files?
-
- It removes the RCS keywords, so that if the recipient of the
- exported sources checks them into another set of RCS files (with
- or without CVS), and then makes modifications through RCS or CVS
- commands, the revision numbers that they had when you exported
- them will be preserved. (That ident no longer works is just an
- unfortunate side effect.)
-
- The theory is that you are exporting the sources to someone else
- who will make independent changes, and at some point you or they
- will want to know what revisions from your Repository they started
- with (probably to merge changes, or to try to decide whether to
- merge changes).
-
- A better way to handle this situation would be to give them their
- own branch of your Repository. They would need to remember to
- checkin the exported sources with RCS IDs intact (ci -k) so that
- their changes would get revision numbers from the branch, rather
- than starting at 1.1 again. Perhaps a future version of CVS will
- provide a way to export sources this way.
-
- Contributed by Dan Franklin
-
-
- 3F.3 Can I override the '-kv' flag CVS passes to RCS?
-
- Not as of CVS version 1.4.
-
-
- 3F.4 Why doesn't "export" have a '-k' flag like "import" does?
-
- Export is intended for a specific purpose -- to remove all trace
- of revision control on the way *out* of CVS.
-
-
- 3F.5 Why does "export -D" check out every file in the Attic?
-
- See 5B.3 for an explanation of the same problem with "update".
-
-
-
-----------------
--- Section 3G -- "history", "hi", "his"
-----------------
-
- **** Questions:
-
- 3G.1 What is "history" for?
- 3G.2 Of what use is it?
- 3G.3 What is this, Big Brother?
- 3G.4 I deleted my working directory and "history" still says I have
- it checked out. How do I fix it?
- 3G.5 So I *can* edit the History file?
- 3G.6 Why does the history file grow so quickly?
- 3G.7 What is the difference between "cvs history -r <tag/rev>" and
- "cvs history -t <tag>"?
- 3G.8 Why does "cvs history -c -t <tag>" fail to print anything?
- 3G.9 "cvs history -a -o" only printed one line for each checked-out
- module. Shouldn't it print all the directories where the
- modules are checked out?
- 3G.10 I can't figure out "history", can you give me concrete examples?
- 3G.11 Can we merge history files when we merge Repositories?
-
-
- **** Answers:
-
- 3G.1 What is "history" for?
-
- To provide information difficult or impossible to extract out of
- the RCS files, such as a "tag" history or a summary of module
- activities.
-
-
- 3G.2 Of what use is it?
-
- I have found it useful in a number of ways, including:
-
- 1. Providing a list of files changed since
-
- - A tagged release.
- - Yesterday, last Thursday, or a specific date.
- - Someone changed a specific file.
-
- 2. Providing a list of special events:
-
- - Files added or removed since one of the above events.
- - Merge failures since one of the above events. (Where did the
- conflicts occur?)
- - Has anyone (and who) grabbed the revision of this file I
- committed last week, or are they still working blind?
-
- 3. Telling me how often a file/directory/module has been changed.
-
- 4. Dumping a summary of work done on a particular module,
- including who last worked on it and what changed.
-
- 5. Displaying the checked-out modules and where they are being
- worked on.
-
- 6. To tell me what users "joe" and "malcolm" have done this week.
-
-
- 3G.3 What is this, Big Brother?
-
- War is Peace.
- Freedom is Slavery.
- Ignorance is Strength.
-
- Normally manager types and those with the power to play Big
- Brother don't care about this information. The Software Engineer
- responsible for integration usually wants to know who is working
- on what and what changed. Use your imagination.
-
-
- 3G.4 I deleted my working directory and "history" still says I have
- it checked out. How do I fix it?
-
- You can use "release -f" to forcibly add a "release" record to the
- history file for a working directory associated with a "module".
- If your version of "release" doesn't have the '-f' option, or you
- checked out the directory using a relative path, you have to edit
- the $CVSROOT/CVSROOT/history file.
-
- You can remove the last 'O' line in the history file referring
- to the module in question or add an 'F' record.
-
-
- 3G.5 So I *can* edit the History file?
-
- Yes, but if you are using history at all, you should take a little
- care not to lose information. I normally use Emacs on the file,
- since it can detect that a file has changed out from under it.
- You could also copy and zero out the history file, edit the copy
- and append any new records to the edited copy before replacing it.
-
-
- 3G.6 Why does the history file grow so quickly?
-
- It stores 'U' records, which come in handy sometimes when you
- are tracking whether people have updated each other's code
- before testing. There should (and probably will sometime) be a
- way to choose what kinds of events go into the history file.
-
- The contributed "cln_hist.pl" script will remove all the 'U'
- records, plus matching pairs of 'O' and 'F' records during
- your normal clean up of the history file.
-
-
- 3G.7 What is the difference between "cvs history -r <tag/rev>" and
- "cvs history -t <tag>"?
-
- The '-t' option looks for a Tag record stored by "rtag" in the
- history file and limits the search to dates after the last <tag>
- of the given name was added.
-
- The '-r' option was intended to search all files looking for the
- <tag> in the RCS files. It takes forever and needs to be
- rewritten.
-
-
- 3G.8 Why does "cvs history -c -t <tag>" fail to print anything?
-
- You have been using "tag" instead of "rtag". The "tag" command
- currently doesn't store a history record. This is another remnant
- of CVS's earlier firm belief in "modules". But it also has a
- basis in how "rtag" and "tag" were originally used.
-
- "rtag" was intended for large-scale tagging of large chunks of the
- Repository, an event work recording. "tag" was intended for
- adding and updating tags on a few files or directories, though it
- could also be used to tag the entire checked-out working tree when
- there is no module defined to match the tree or when the working
- tree is the only place where the right collection of revisions to
- tag can be found.
-
-
- 3G.9 "cvs history -a -o" only printed one line for each checked-out
- module. Shouldn't it print all the directories where the
- modules are checked out?
-
- Not as designed.
-
- Command Question it is supposed to answer.
- ---------------- ------------------------------------------
- cvs history -o What modules do I have checked out?
- cvs history -a -o <same for all users>
-
- cvs history -o -w What working directories have I created
- and what modules are in them?
- cvs history -a -o -w <same for every user>
-
- The -o option chooses the "checked out modules" report, which is
- the default history report.
-
-
- 3G.10 I can't figure out "history", can you give me concrete examples?
-
- Default output selects records only for the user who executes the
- "history" command. To see records for other users, add one or
- more "-u user" options or the '-a' option to select *all* users.
-
- To list (for the selected users): Type "cvs history" and:
-
- * Checked out modules: -o (the default)
- * Files added since creation: -x A
- * Modified files since creation: -c
- * Modified files since last Friday: -c -D 'last Friday'
- * Modified files since TAG was added: -c -t <tag>
- * Modified files since TAG on files: -c -r <tag>
- * Last modifier of file/Repository X? -c -l -[fp] X
- * Modified files since string "str": -c -b str
- * Tag history: (Actually "rtag".) -T
- * History of file/Repository/module X: -[fpn] X
- * Module report on "module": -m module
-
-
- 3G.11 Can we merge history files when we merge Repositories?
-
- Assuming that the two Repositories have different sets of
- pathnames, it should be possible to merge two history files by
- sorting them together by the timestamp fields.
-
- You should be able to run:
-
- sort +0.1 ${dir1}/history ${dir2}/history > history
-
-
- If you "diff" a standard history file before and after such a
- sort, you might see other differences caused by garbage (split
- lines, nulls, etc) in the file. If your Repository is mounted
- through NFS onto multiple machines you will also see a few
- differences caused by different clocks on different machines.
- (Especially if you don't use NTP to keep the clocks in sync.)
-
-
-
-----------------
--- Section 3H -- "import", "im", "imp"
-----------------
-
- **** Questions:
-
- 3H.1 What is "import" for?
- 3H.2 How am I supposed to use "import"?
- 3H.3 Why does import put files on a branch? Why can't I work on the
- main trunk instead of a Vendor branch?
- 3H.4 Is there any way to import binary files?
- 3H.5 Why does "import" corrupt some binary files?
- 3H.6 How do I retain the original $\Revision$ strings in the sources?
-=3H.7 I imported some files for the Yarg compiler that compiles files
- with a suffix of ".yarg" and whose comment prefix is "YARG> ".
- When I check them out, they will no longer compile because they
- have this junk in them. Why?
- 3H.8 How do I make "import" save the timestamps on the original files?
- 3H.9 Why can't I "import" 3 releases on different branches?
- 3H.10 What do I do if the Vendor adds or deletes files between releases?
- 3H.11 What about if the Vendor changes the names of files or
- directories, or rearranges the whole structure between releases?
- 3H.12 I thought "import" was for Vendor releases, why would I use it
- for code of my own? Do I have to use import?
- 3H.13 How do I import a large Vendor release?
- 3H.14 Explain: ERROR: cannot create link to <file>: Permission denied
- 3H.15 Where does the -m <message> go when the file doesn't change?
- 3H.16 How do I "import" just the files ignored by a previous "import"?
- 3H.17 Why did "import" ignore all the symlinks?
-
-
- **** Answers:
-
- 3H.1 What is "import" for?
-
- The "import" command is a fast way to insert a whole tree of files
- into CVS.
-
- The first "import" to a particular file within the Repository
- creates an RCS file with a single revision on the "Vendor branch."
- Subsequent "import"s of the same file within the Repository append
- a new revision onto the Vendor branch. It does not, as some seem
- to believe, create a new branch for each "import". All "imports"
- are appended to the single Vendor branch.
-
- If the file hasn't changed, no new revision is created -- the new
- "Release-Tag" is added to the previous revision.
-
- After the import is finished, files you have not changed locally
- are considered to have changed in the "Main line of development".
- Files you *have* changed locally must have the new Vendor code
- merged into them before they are visible on the "Main line".
-
- See 4C.6 and 4C.15
-
-
- 3H.2 How am I supposed to use "import"?
-
- Create a source directory containing only the files you want to
- import. Make sure you clean up any cruft left over from previous
- builds or editing. You want to make sure that the directory
- contains only what you want to call "source" from which everything
- else is built.
-
- If this is not the first import from this "Vendor", you should
- also compare the output of "find . ! -name CVS -print | sort"
- executed both at the head of a checked out working directory and
- at the head of the sources to be imported. If you find any
- deleted or renamed files, you have to deal with them by hand.
- (See 4B.8 on renaming.)
-
- "cd" into your source directory and type:
-
- cvs import -m "Message" <repos> <Vendor-Tag> <Release-Tag>
-
- where <repos> is the relative directory pathname within the
- Repository that corresponds to the sources you are importing.
-
- You might also consider using the "-I !" option to avoid ignoring
- anything. It is easier to remove bogus files from the Repository
- than to create a sparse tree of the ignored files and rerun
- "import".
-
- For example, if the FSF, CVS, Make and I are still active in the
- year 2015, I'll import version 89.53 of GNU make this way:
-
- cvs import -m "GNUmake V89.53" gnu/make GNU GNUMAKE_89_53
-
- See 3H.13 for more details.
-
-
- 3H.3 Why does import put files on a branch? Why can't I work on the
- main trunk instead of a Vendor branch?
-
- This was a Design choice. The Vendor branch is the way "import"
- deals with a Vendor release. It is a solution to the Engineering
- problem of how to merge multiple external releases of
- Vendor-supplied sources into your ongoing work. The Vendor
- releases are kept on a separate, special, "Vendor" branch and your
- work is kept on the RCS trunk. New Vendor releases are imported
- onto the Vendor branch and then merged into your work, if there is
- any, on the trunk.
-
- This way, you can use CVS to find out not only about your work,
- but you can also find out what the Vendor changed by diffing
- between two of the Release Tags you handed to "import".
-
- CVS was designed to work this way. If you use CVS in some other
- way, you should think carefully about what you are doing.
-
- Note that the CVS "Main Branch" and the RCS Main Trunk are not the
- same. Placing files on the Vendor Branch doesn't keep you from
- creating a development branch to work on.
-
- See Section 4C, on Branching.
-
-
- If you are not working with 3rd party (i.e. Vendor) sources, you
- can skip the "import" and avoid the Vendor branch entirely. It
- works just as well to move pre-existing RCS files into Repository
- directories.
-
- You can create a whole Repository tree by copying a directory
- hierarchy of normal source files directly into the Repository and
- applying CVS to it. Here's an idea you should *test* before using:
-
- cd <your source tree>
- set source = `pwd`
- set module = xyzzy <<== Your choice of directory name
- mkdir $CVSROOT/$module
- cd $CVSROOT/$module
- (cd $source; tar cf - .) | tar xvpBf -
- find . -type f -exec ci -t-Original. {} \;
-
- The RCS "ci" command, without -u or -l options, will turn your
- source file into an RCS (",v") and delete the original source.
-
-
- 3H.4 Is there any way to import binary files?
-
- If you configured CVS to use the GNU version of "diff" and
- "diff3", then you can import any kind of file.
-
- Binary files with RCS keywords in them are a problem, since you
- don't want them to expand.
-
- If the tree you are about to "import" is entirely filled with
- binary files, you can use the '-ko' option on "import".
- Otherwise, I would run the import normally, then fix the binary
- files as described below in 3H.5.
-
- See 4D.1 on Binary files.
-
-
- 3H.5 Why does "import" corrupt some binary files?
-
- The RCS "co" command, when it is invoked by a CVS "checkout" or
- "update" (or after a "commit") command, searches for and expands a
- list of keywords within the file. They are documented in the RCS
- "co" man page. Strings such as "$\Id$" (or "$\Id:"), or
- "$\Revision$" (or "$\Revision:") are altered to the include the
- indicated information.
-
- [[Note: The keywords should appear in the text without the '\'
- character I have inserted to *avoid* expansion here. The only
- real RCS keywords in this document are at the top of the file,
- where I store the Revision and Date.]]
-
- If RCS keyword strings show up in a binary file, they will be
- altered unless you set the '-ko' option on the RCS files to tell
- RCS to keep the original keyword values and not to expand new
- ones. After "import", you can set the '-ko' option this way:
-
- cvs admin -ko <file>
- rm <file>
- cvs update <file>
-
- After an import that didn't use '-ko' (because the whole tree
- wasn't of binary files) you should fix up the binary files as
- described above before checking out any new copies of the files
- and before updating any working directories you checked out
- earlier.
-
- See 4D.1 on Binary files.
-
-
- 3H.6 How do I retain the original $\Revision$ strings in the sources?
-
- If you want to leave old RCS keywords as they are, you can use the
- '-ko' tricks described above.
-
-
-=3H.7 I imported some files for the Yarg compiler that compiles files
- with a suffix of ".yarg" and whose comment prefix is "YARG> ".
- When I check them out, they will no longer compile because they
- have this junk in them. Why?
-
- YARG>YARG>YARG>YARG>YARG>YARG>YARG>YARG>YARG>YARG>YARG>YARG>YARG>
- YARG> $\Log:
- # Revision 1.3 1998/03/03 00:16:16 bubba
- # What is 2+2 anyway?
- #
- # Revision 1.2 1998/03/03 00:15:15 bubba
- # Added scorekeeping.
- YARG>
- YARG>YARG>YARG>YARG>YARG>YARG>YARG>YARG>YARG>YARG>YARG>YARG>YARG>
-
-
- Well bubba, "Yarg" hasn't hit the big time yet. Neither RCS nor
- CVS know about your suffix or your comment prefix. So you have
- two choices:
-
- 1. Check out the Yarg-less module, and tell all the files about
- your comment prefix. Visit each directory and type:
-
- cvs admin -c"YARG> " *.yarg
-
- If *all* files in the whole directory tree are Yarg files,
- you can use this instead:
-
- cvs admin -c"YARG> " .
-
- Then save any changes you made, remove all the "*.yarg" files
- and grab new copies from the Repository:
-
- rm *.yarg
- (or: find . -name '*.yarg' -exec rm {} ';')
- (or: find . -name '*.yarg' -print | xargs rm)
- (or: find . -name '*.yarg' -print0 | xargs -0 rm
- if you have spaces in filenames and the GNU find/xargs.)
- cvs update
-
- It might be faster to remove the whole directory and check it
- out again.
-
- 2. Change the import.c file in the CVS sources and add the .yarg
- suffix, along with the "YARG> " comment prefix to the
- "comtable" array.
-
- If you ever plan to add new files with $\Log in them, you
- should also go into the RCS sources and make the same change in
- the table contained in the "rcsfnms.c" file.
-
- Then delete the imported files from the Repository and
- re-"import" the sources.
-
-
- 3H.8 How do I make "import" save the timestamps on the original files?
-
- Use "import -d" to save the current timestamps on the files as the
- RCS revision times.
-
- See 4D.8 for another aspect of file timestamps.
-
-
- 3H.9 Why can't I "import" 3 releases on different branches?
-
- I'll bet you typed something like this:
-
- cd /src/blasto.v2
- cvs import -b 1.1.2 VENDOR2 Version2
- cd /src/blasto.v3
- cvs import -b 1.1.3 VENDOR3 Version3
- cd /src/blasto.v4
- cvs import -b 1.1.4 VENDOR4 Version4
-
- This is wrong, or at least it won't help you much. You have
- created three separate Vendor branches, which is probably not
- what you wanted.
-
- Earlier versions of CVS, as described in Brian Berliner's Usenix
- paper, tried to support multiple Vendor branches on the theory
- that you might receive source for the *same* program from multiple
- vendors. It turns out that this is very rare, whereas the need to
- branch in *your* development, for releases and for project
- branches, is much greater.
-
- So the model now is to use a single vendor branch to contain a
- series of releases from the same vendor. Your work moves along
- on the Main Trunk, or on a CVS branch to support a real
- "branch in development".
-
- To set this up, you should type this instead of the above:
-
- cd /src/blasto.v2
- cvs import VENDOR Version2
- cd /src/blasto.v3
- cvs import VENDOR Version3
- cd /src/blasto.v4
- cvs import VENDOR Version4
-
-
- 3H.10 What do I do if the Vendor adds or deletes files between releases?
-
- Added files show up with no extra effort. To handle "removed"
- files, you should always compare the tree structure of the new
- release against the one you have in your Repository. If the
- Vendor has removed files since the previous release, go into a
- working directory containing your current version of the sources
- and "cvs remove" (followed by "cvs commit" to make it really take
- effect) each file that is no longer in the latest release.
-
- Using this scheme will allow you to "checkout" any version of
- the vendor's code, with the correct revisions and files, by
- using "checkout -r Version[234]".
-
- Renames are harder to find, since you have to compare file
- contents to determine that one has occurred. If you notice one,
- see 4B.8 on renaming files.
-
-
- 3H.11 What about if the Vendor changes the names of files or
- directories, or rearranges the whole structure between releases?
-
- Currently CVS can't handle this cleanly. It requires
- "renaming" a bunch of files or directories.
-
- See 4B.8 on "renaming" for more details.
-
- What I generally do is to close the Repository for a while and
- make changes in both the Repository and in a copy of the vendor
- release until the structure matches, then execute the import.
-
- If you ever have to check out and build an old version, you may
- have to use the new, or completely different Makefiles.
-
-
- 3H.12 I thought "import" was for Vendor releases, why would I use it
- for code of my own? Do I have to use import?
-
- For code you produce yourself, "import" is a convenience for fast
- insertion of whole trees. It is not necessary. You can just as
- easily create ",v" files using the RCS "ci" command and move
- them directly into the Repository.
-
- Other than the CVSROOT directory, the Repository consists entirely
- of directories of ",v" files. The Repository contains no other
- state information.
-
- See Section 4B, on Setting up and Managing the Repository.
-
-
- 3H.13 How do I import a large Vendor release?
-
- When the sum of the changes made by the Vendor and the changes
- made by local developers is small, "import" is not a big
- problem. But when you are managing a large Repository, any care
- taken up front will save you time later.
-
- First read the following, then, before executing "import", see the
- questions in Section 4C dealing with branch merges and Vendor
- branch merges.
-
- 0. If this is not the first import of this code, before starting,
- rtag the whole directory you will be changing.
-
- 1. The first step is to make sure the structure of the new files
- matches the structure of the current Repository.
-
- Run "find . -print | sort" on both trees and "diff" the output.
-
- 2. Alter the "source" tree until the "diff" (of the list of
- filenames, not of the whole trees) shows that the directory
- structures are equivalent.
-
- The "comm" command, if you have it, can help figure out what
- has been added or deleted between releases.
-
- 3. If they deleted any files, you can handle them cleanly with
- "cvs remove". The command "comm -23 files.old files.new" will
- show you a list of files that need to be removed.
-
- You should examine the list first to see if any have been
- renamed rather than simply deleted.
-
- 4. If they renamed any files, see 4B.8 on renaming files.
-
- 5. Remember to *SAVE* the output from the import command.
-
- 6. When you have dealt with removed and renamed files, then you
- can execute the import:
-
- cd <new source>
- cvs import -I ! -m "Message" <repos> <VendorTag> <ReleaseTag>
-
-
- Where
-
- "-I !" is an optional argument that keeps "import" from
- ignoring files. The comparison of the "find"
- commands above will probably avoid the need for
- this, but it is easier to remove files from the
- Repository than to run a subset "import" to catch
- just the ignored files.
- [You might have to quote or backwhack the '!'.]
-
- Message is the log message to be stored in the RCS files.
-
- <repos> is a relative path to a directory within the
- Repository. The directory <new source> must be at
- the same relative level within the new sources as
- the <repos> you give is within the Repository. (I
- realize this is not obvious. Experiment first.)
-
- <VendorTag> is a Tag used to identify the Vendor who sent you
- the files you are importing. All "imports" into
- the same <repos> *must* use the same VendorTag.
- You can find it later by using the "log" command.
-
- <ReleaseTag> is a Tag used to identify the particular release
- of the software you are importing. It must be
- unique and should be mnemonic -- at least include
- the revision number in it. (Note: you can't use
- '.' characters in a Tag. Substitute '_' or '-'.)
-
- 7. There will be six categories of files to deal with.
- (Actually there are eight, but you have already dealt with
- "removed" and "renamed" files.)
-
- If this is the first "import" into a given <repos> directory,
- only the first three of these ('I', 'L' and 'N') can occur.
-
-
- a. Ignored file.
-
- CVS prints: I filename
-
- You'll need to examine it to see if it *should* have been
- ignored. If you use "-I !", nothing will be ignored.
-
-
- b. Symbolic link.
-
- CVS prints: L linkname
-
- Links are "ignored", but you'll probably want to create
- a "checkout helper" function to regenerate them.
-
-
- c. New file.
-
- CVS prints: N filename
-
- CVS creates a new file in the Repository. You don't
- have to do anything to the file, but you might have to
- change Makefiles to refer to it if this is really a new
- file.
-
-
- d. A file unchanged by the Vendor since its last release.
-
- CVS prints: U filename
-
- CVS will notice this and simply add the new ReleaseTag
- to the latest rev on the Vendor branch.
-
- No work will be needed by you, whether you have changed
- the file or not. No one will notice anything.
-
- e. A file changed by the Vendor, but not by you.
-
- CVS prints: U filename
-
- CVS should add the file onto the vendor branch and
- attach the Release Tag to it.
-
- When you next execute "update" in any working directory
- you'll get the new revision.
-
-
- f. A file changed by both the Vendor and by you.
-
- CVS prints: C filename
-
- These are the trouble files. For each of these files
- (or in groups -- I usually do one directory at a
- time), you must execute:
-
- cvs update -j <PreviousReleaseTag> -j <ReleaseTag>
- or
- cvs update -j <VendorTag:yesterday> -j <VendorTag>
-
- It will print either 'M' (if no overlaps) or 'C', if
- overlaps. If a 'C' shows up, you'll need to edit the
- file by hand.
-
- Then, for every file, you'll need to execute "cvs commit".
-
- See the part of Section 4C dealing with branch merges.
-
-
- 8. If you are truly performing a large import, you will most
- likely need help. Managing those people is another problem
- area.
-
- Since the merge of the Vendor branch is just like any other
- merge, you should read section 4C for more info about
- performing and cleaning up merges.
-
- The larger the import, and the larger the group of people
- involved, the more often you should use "tag" and "rtag" to
- record even trivial milestones. See 4C.14, especially the
- "paranoid" section.
-
- Before starting the import, you should install and test a
- "commitinfo" procedure to record all commits in a file or via
- Email to a mail archive. Along with the tags you placed on the
- Repository before the import, this archive will help to track
- what was changed, if problems occur
-
- There are four stages to the recovery:
-
- A. Parcel out the work -- Effective Emacs Engineering.
-
- As input to the assignment process, you might want to
- examine the tree and record the last person who changed the
- file. You can also research, if you don't already know, who
- is expert in each area of the software.
-
- Examine the import log (you saved the output, right?),
- estimate how much work is involved in each area and assign
- groups of files to individual developers. Unless some
- directory is immense, it is easier to manage if you assign
- whole directories to one person.
-
- Keep a list. Suggest a completion date/time. Tell them to
- "commit" the file when they are finished with the merge.
- If you tagged the Repository before starting the import, you
- should have no trouble figuring out what happened.
-
- If you can, find out (or tell them) which working directory
- to use. You should verify that the working directory they
- use is on the Main Branch ("update -A") and without modified
- files.
-
- If you trust your crew, have them notify you by Email. Have
- them send you the output from "cvs update" in their working
- directory. You might have to poll some people until you are
- certain they have finished, or have given up. (This is not
- an invention. I've heard a false, "Yeah, sure. I finished
- yesterday," more times that you'd believe.)
-
- When all reports are in, go on to the Source Verification
- stage.
-
- B. Source Verification -- CVS and other Tools.
-
- If you didn't dictate which ones to use, find all working
- directories and run "cvs -n update" in all of them. The
- history command and the "commitinfo" log you set up might
- help to find checked out working directories.
-
- Sticky conflict flags will help, but they can't recover from
- sloppiness or incompetence. You might want to check
- everything out into a tree and grep for the parts of the
- merge conflict markers CVS doesn't look for. CVS looks for
- the string '^>>>>>>> '. The merge operation also puts
- '^<<<<<<< ' and '^======= ' markers in the file that
- careless developers might leave there.
-
- If you find problems simply by looking at the source files
- and working directories, start the flogging now. Resolving
- the textual conflicts is the easy part. Weed the turkeys
- out before reaching the next part of the cleanup -- the
- resolution of logical conflicts.
-
- Then apply a set of post-commit tags.
-
- C. Logical Verification -- Diff and powerful eyeballs.
-
- No source control system can solve the problem of resolving
- distributed conflicts in program logic. If you change the
- argument template for function A (defined in file A.c) and
- add new calls to function A from within function B (defined
- in file B.c) using the old argument format, you are outside
- the realm of CVS's competence.
-
- Assign someone to understand what the Vendor changed by
- running "cvs diff -c -r <PreviousReleaseTag> <ReleaseTag>",
- where the tags were those handed to the last two invocations
- of "import".
-
- Then have the same person compare that output (logically or
- you can actually diff the diffs) to the output of the
- similar "cvs diff -c -r <pre-import-tag> <post-commit-tag>".
- The two sets of differences should be almost identical.
- They should both show only the work *you* have performed.
-
- D. Product Verification -- Build and Test.
-
- Don't let your help off the hook until you verify that the
- merge actually produced something that can compile and pass
- tests. Compiling should really be part of the logical
- verification phase, but you should test the output of the
- build system before declaring victory and releasing the
- troops.
-
-
- 9. After it is all built, apply another set of tags to mark the
- end of the "import process". You can delete the intermediate
- tags you added during source and logic testing, but keep the
- "pre-import" and "post-import" tags forever.
-
-
- Of course, experience can tell you when to skip a step. But I'd
- start out by considering each one as necessary unless you can
- prove otherwise.
-
-
-
- 3H.14 Explain: ERROR: cannot create link to <file>: Permission denied
-
- This error appears when you try to execute a second (or later)
- "import" into the same module from a directory to which you don't
- have write access.
-
- The "link error" is caused by a feature purposely added to
- speed up the import.
-
- Though the error message is somewhat strange, it indicates that
- "import" is supposed to be executed only in writable directories.
-
-
- 3H.15 Where does the -m <message> go when the file doesn't change?
-
- The <message> handed to import is used as an RCS log message, but
- only if the imported file changed since the last version on the
- Vendor branch. If the imported file hasn't changed, then no new
- revision is created. The <ReleaseTag> is still applied, but to
- the previous revision. So the Tags are still correct, but the
- message is lost.
-
- Maybe it should be appended to the previous log message. But
- currently it isn't.
-
-
- 3H.16 How do I "import" just the files ignored by a previous "import"?
-
- A real answer follows, but first, an editorial:
-
- I am now convinced that you should always use the "-I !"
- option. Removing a few extraneous files from the Repository
- is a lot easier than the recovery step described below.
-
-
- Let's assume your original import procedure was:
- (We assume there is enough disk space in /tmp.)
-
- cd <head-of-vendor-tree>
- cvs import -m 'xyz 1.3' gnu/xyz GNU GNUXYZ_1_3 | tee /tmp/IMP
-
- To import just the files ignored by "import", I would do this:
-
- 1. Create a list of the ignored files to import:
-
- cd <head-of-vendor-tree>
- awk '/^I / {print $2}' /tmp/IMP | sed 's|^gnu/xyz/||' > /tmp/IG
- [Edit the IG file to contain just the files you want.]
-
- 2. Then create a sparse directory by handing your list to the GNU
- version of "tar", installed in many places as "gtar":
-
- mkdir /tmp/FIXUP
- gtar -T /tmp/IG -c -f - . | (cd /tmp/FIXUP; gtar xvBf -)
-
- 3. Then rerun the import. Use the exact same command, but execute
- it in the sparse directory tree you just created. And this
- time, tell it not to ignore anything.
-
- cd /tmp/FIXUP
- cvs import -I ! -m 'xyz 1.3' gnu/xyz GNU GNUXYZ_1_3
-
-
- 3H.17 Why did "import" ignore all the symlinks?
-
- This is another design choice.
-
- Like the Unix "tar" command, "import" could sprout an option to
- follow symbolic links, but I don't think CVS will ever follow
- symbolic links by default.
-
- Two possible future enhancements have been seriously discussed:
-
- 1. Treat symbolic links as data in its parent directory (the way
- ClearCase does) in some sort of per-directory control file.
-
- 2. Treat symbolic links as version-controlled elements themselves,
- whose data is the value of readlink(2).
-
- For now, they are simply ignored.
-
- If you want to save and reconstruct symlinks, you might want to
- define a "checkout" or "update" program in the modules file which
- could consult a file kept under CVS in your working directory and
- make sure the specified links are in place.
-
-
-
-----------------
--- Section 3I -- "log", "lo", "rlog"
-----------------
-
- **** Questions:
-
- 3I.1 What is "log" for?
- 3I.2 How do I extract the log entries between two revisions?
- 3I.3 How do I extract the log entries on a whole branch?
- 3I.4 How do I generate ChangeLogs from RCS logs?
- 3I.5 Why does "log" tell me a file was committed exactly 5 hours later
- than I know it was?
-
-
- **** Answers:
-
- 3I.1 What is "log" for?
-
- To provide an interface to the RCS "rlog" command, which displays
- information about the underlying RCS files, including the revision
- history and Tag (RCS calls it a "symbol") list.
-
-
- 3I.2 How do I extract the log entries between two revisions?
-
- If both <rev1> and <rev2> are on the same branch, you can get
- what you are looking for with: (If they aren't on the same branch
- you'll either get an error or a display of the whole change log.)
-
- cvs log -r<rev1>:<rev2> <file>
-
- If you want all the revisions on the branch from <rev1> to the end
- of the branch <rev1> is on, you can use:
-
- cvs log -r<rev1>: <file>
-
- (If <rev1> is a numeric RCS symbol attached to a branch revision
- with an even number of '.'s in it, you get the whole branch.)
-
- If you want all the revisions on the branch from the beginning of
- the branch <rev2> is on up to revision <rev2>, you can use:
-
- cvs log -r:<rev2> <file>
-
-
- Note: Depending on whether <rev1> and <rev2> are:
-
- - numeric or symbolic
- - in the file or not
- - on the same branch or not
-
- the RCS "rlog" (and therefore the "cvs log") command will
- display some combination of:
-
- - error messages
- - (intuitively correct) partial log listings
- - a display of the entire change log.
-
-
- 3I.3 How do I extract the log entries on a whole branch?
-
- cvs log -r<rev> <file>
-
- where <rev> must be a branch revision (one with an even number
- of dots) or a *non-branch* tag on a branch revision. Non-branch
- tags on a branch revision are not normally attached by CVS, to add
- one you will have to explicitly tag a physical branch number
- within each file. Since these branch numbers are almost never the
- same in different files, this command is not all that useful.
-
- The intuitive command (at least from the CVS perspective):
-
- cvs log -r<branch_tag> <file>
-
- does not work.
-
-
- 3I.4 How do I generate ChangeLogs from RCS logs?
-
- A program called rcs2log is distributed as part of GNU Emacs 19.
- A (possibly older) version of this program appears in the contrib
- directory of the cvs source tree.
-
-
- 3I.5 Why does "log" tell me a file was committed exactly 5 hours later
- than I know it was?
-
- I can tell by this question that you were working in a time zone
- that is 5 hours behind GMT (e.g. the U.S. East Coast in winter).
-
- RCS file dates are stored in GMT to allow users in different time
- zones to agree on the meaning of a timestamp. At first glance
- this doesn't seem necessary, but many companies use distributed
- file systems, such as NFS or AFS, across multiple timezones.
-
- Some standard form must be used. GMT, as the "grid origin", is an
- obvious candidate. The only other reasonable choice is to put the
- timezone information in all the time stamps, but that changes the
- RCS file format incompatibly, a step which has been avoided in the
- last few RCS releases.
-
-
-----------------
--- Section 3J -- "patch", "pa", "rdiff"
-----------------
-
- **** Questions:
-
- 3J.1 What is "patch" for?
- 3J.2 Why does "patch" include files from the Attic when I use '-D'?
- 3J.3 How do I make "patch" produce a patch for one or two files?
- It seems to work only with modules.
-
-
- **** Answers:
-
- 3J.1 What is "patch" for?
-
- To produce a "diff" between tagged releases to be handed to the
- "patch" command at other sites. This is the standard way that
- source patches are distributed on the network.
-
-
- 3J.2 Why does "patch" include files from the Attic when I use '-D'?
-
- See the explanation of the same problem with "update -D"
- contained in section 5B.
-
-
- 3J.3 How do I make "patch" produce a patch for one or two files?
- It seems to work only with modules.
-
- Patch is intended for producing patches of whole modules between
- releases to be distributed to remote sites. Instead of "patch",
- you can use the "diff" command with the '-c' context option:
-
- cvs diff -c -r <rev/tag> -r <rev/tag> <file1> . . .
-
- The patch command will be able to merge such a "diff" into the
- remote source files.
-
- If you configured CVS to use a version of "diff" that supports the
- '-u' option, you can produce a more compact "patch" in "unidiff"
- format. The latest revisions of the patch command can parse and
- apply patches in "unidiff" format.
-
-
-
-----------------
--- Section 3K -- "release", "re", "rel"
-----------------
-
-
- **** Questions:
-
- 3K.1 What is "release" for?
- 3K.2 Why can't I reverse a "cvs checkout path/name/subdir" with a
- "cvs release path/name/subdir" without an "unknown module name"?
- 3K.3 Why can't I "release" portions of a checked out directory? I
- should be able to "release" any file or sub-directory within
- my working directory.
- 3K.4 I removed the tree that I was about to start working on. How do I
- tell cvs that I want to release it if I don't have it anymore?
- 3K.5 Why doesn't "release -d module" reverse a "checkout module"?
- 3K.6 Why can't I release a module renamed with "cvs checkout -d"?
-
-
- **** Answers:
-
- 3K.1 What is "release" for?
-
- To register that a module is no longer in use. It is intended
- to reverse the effects of a "checkout" by adding a record to
- the history file to balance the checkout record and by
- optionally allowing you to delete the checked-out directory
- associated with the module name.
-
-
- 3K.2 Why can't I reverse a "cvs checkout path/name/subdir" with a
- "cvs release path/name/subdir" without an "unknown module name"?
-
- A simplistic implementation. (I can say this -- I wrote it.)
-
- The "release" function was written for CVS 1.2 under the
- assumption that the "module name" is a first class, unavoidable
- interface to the Repository, allowing no way to retrieve anything
- other than by module name. Though it is easier to program that
- way, many users of CVS believe the modules support to be too
- primitive to allow such a limitation.
-
- Since "release" was written, other parts of CVS broke that
- assumption. It needs to be revised.
-
-
- 3K.3 Why can't I "release" portions of a checked out directory? I
- should be able to "release" any file or sub-directory within
- my working directory.
-
- This isn't really a limitation in "release", per se. CVS doesn't
- try to keep track of which files in which directories are "checked
- out" and which are just lying there. You can delete directories
- and "update" will not bring them back unless you add a special
- "-d" option.
-
- In other words, CVS doesn't keep track of how you adjust the
- partition between files you consider part of your working set and
- files that were checked out because they are part of the same
- module or directory. And neither does "release".
-
- In future CVS releases, "release" might become sophisticated
- enough to handle both the reversal of a "checkout" and the
- deletion of random portions of the working directory, but it isn't
- that way now.
-
-
- 3K.4 I removed the tree that I was about to start working on. How do I
- tell cvs that I want to release it if I don't have it anymore?
-
- See 3G.4.
-
-
- 3K.5 Why doesn't "release -d module" reverse a "checkout module"?
-
- It does, if you are using "module" in a way that "release"
- expects: a non-alias string in the left column of the "modules"
- database.
-
- If "module" is really an alias, or if you are using a relative
- path in the place of "module", or if you renamed the directory
- with the -d option in the modules file or on the "checkout"
- command line, then the current version of "release" won't work.
-
- Future versions of "release" will probably fix most of these.
-
-
- 3K.6 Why can't I release a module renamed with "cvs checkout -d"?
-
- The current version of "release" doesn't know how to track the
- renaming option ('-d') of the "checkout" command. It will
- probably be fixed in the future.
-
-
-
-----------------
--- Section 3L -- "remove", "rm", "delete"
-----------------
-
- **** Questions:
-
- 3L.1 What is "remove" for?
- 3L.2 Why doesn't "remove" work on directories when it appears to try?
- 3L.3 I don't like removing files. Is there another way to ignore them?
- 3L.4 I just removed a file. How do I resurrect it?
- 3L.5 Why doesn't "remove" delete the file? Instead, it prints an
- error message and tells me to remove the file by hand.
-
-
- **** Answers:
-
- 3L.1 What is "remove" for?
-
- To remove a file from the working branch. It removes a file from
- the main branch by placing it in an "Attic" directory.
-
-
- 3L.2 Why doesn't "remove" work on directories when it appears to try?
-
- Oversight. It should be able to delete an empty directory, but
- you still don't have a way to remember when it was there and when
- it disappeared to allow the "-D <date>" option to work.
-
- You'll have to remove the working directory and the matching
- directory in the Repository.
-
-
- 3L.3 I don't like removing files. Is there another way to ignore them?
-
- There's no reason to be hasty in using the "remove" command.
-
- If there is a way to ignore files in your build procedures, I'd
- just do that. Later, when you decide that the files are really
- ancient, you can execute a "remove" command to clean up.
-
- The CVS "ignore" concept can't ignore files already in CVS.
-
-
- 3L.4 I just removed a file. How do I resurrect it?
-
- If you executed "remove", but haven't typed "commit" (you can
- tell this by the 'R' notation that "update" prints next to the
- file), you can execute "add" to reverse the "remove".
-
- If you followed the "remove" with a "commit", you'll have
- to move it back out of the Attic by hand:
-
- I use something like this: (csh-like syntax)
-
- set repos = `cat ./CVS/Repository`
- mv $repos/Attic/filename,v $repos/filename,v
-
- (If you use relative paths in your Repository files, that first
- line becomes: set repos = $CVSROOT/`cat ./CVS/Repository`)
-
- While a file is in the Attic, you can't "add" another file by
- the same name. To add such a file you either have to move it by
- hand as in the above, or delete it from the Attic.
-
- The main reason for the Attic is to retain files with tags in
- them. If you execute: "update -r <oldtag>", files with <oldtag>
- attached to some revision will be taken from the normal Repository
- area and from the Attic. That's why you can't "add" a file with
- the same name. "remove" only moves a file off the main branch, it
- doesn't obliterate it.
-
-
- 3L.5 Why doesn't "remove" delete the file? Instead, it prints an
- error message and tells me to remove the file by hand.
-
- Design choice. Unix software written within last decade, usually
- requires an extra verification step, such as answering a question
- or adding a flag on the command line. CVS currently requires that
- you delete the file first unless you specify the '-f' (force)
- option, which deletes the file before performing "cvs remove".
-
-
-
-----------------
--- Section 3M -- "rtag", "rt", "rfreeze"
-----------------
-
-(See the "tag" section below for the general questions about Tagging, which
- "tag" and "rtag" share in common.)
-
-
- **** Questions:
-
- 3M.1 What is "rtag" for?
- 3M.2 Why use "rtag"? It assumes no one is changing the Repository.
- 3M.3 What revision does "rtag -r <tag1> <tag2>" actually put the tag on?
- 3M.4 What happens if the tags are the same in "rtag -r <tag> <tag>"?
- 3M.5 Why doesn't "rtag -b -r <branch_tag1> <branch_tag2>" rename or
- duplicate a magic branch tag?
-
-
- **** Answers:
-
- 3M.1 What is "rtag" for?
-
- To add a symbolic label (a "tag") to the last committed revisions
- of a module directly in the Repository.
-
-
- 3M.2 Why use "rtag"? It assumes no one is changing the Repository.
-
- Though the "tag" command is more useful in marking the
- revisions you have in a particular working directory, "rtag" is
- much handier for whole-Repository actions, which occur at major
- release boundaries.
-
-
- 3M.3 What revision does "rtag -r <tag1> <tag2>" actually put the tag on?
-
- In short, the '-r' option is another way to select the revision to
- tag. The revision is selected the same way for all commands that
- accept a "-r <tag/rev>" option.
-
- Depending on whether <tag1> is a <branch_tag>, or a non-branch
- <tag> and on whether you use the '-b' option to "rtag", you get
- four different results:
-
- 1. rtag -r <tag1> <tag2>
-
- Adds the non-branch tag <tag2> to the same revision that the
- non-branch tag <tag1> is attached to.
-
- Example:
- <tag1> --> TT1
- <tag2> --> TT2
- <file> --> Symbols: TT1:1.4
- After --> Symbols: TT1:1.4,TT2:1.4
-
-
- 2. rtag -r <branch_tag1> <tag2>
-
- Adds the non-branch tag <tag2> to the HEAD of (the highest
- revision number on) the branch labelled with tag <branch_tag1>.
-
- Example:
- <branch_tag1> --> BR1
- <tag2> --> TT2
- <file> --> Symbols: BR1:1.2.0.2 (1.2.2.5 is HEAD)
- After --> Symbols: BR1:1.2.0.2,TT2:1.2.2.5
-
- If the branch tagged by <branch_tag1> has not been created,
- then the tag shows up on the branch point revision:
-
- Example:
- <branch_tag1> --> BR1
- <tag2> --> TT2
- <file> --> Symbols: BR1:1.2.0.2 (No 1.2.X exists.)
- After --> Symbols: BR1:1.2.0.2,TT2:1.2
-
-
- 3. rtag -b -r <tag1> <branch_tag2>
-
- Adds the magic branch tag <branch_tag2> to the revision that
- the non-branch tag <tag1> is attached to, preparing it to be a
- branch point.
-
- Example:
- <tag1> --> TT1
- <branch_tag2> --> BR2
- <file> --> Symbol: TT1:1.4
- After --> Symbol: TT1:1.4, BR2:1.4.0.2
-
-
- 4. rtag -b -r <branch_tag1> <branch_tag2>
-
- Adds the magic branch tag <branch_tag2> to the revision at the
- HEAD of (the highest revision number on) the branch labelled
- with <branch_tag1>, preparing it to be a branch point.
-
- Example:
- <branch_tag1> --> BR1
- <branch_tag2> --> BR2
- <file> --> Symbol: BR1:1.2.0.2 (1.2.2.5 is HEAD)
- After --> Symbol: BR1:1.2.0.2,BR2:1.2.2.5.0.2
-
- If the branch tagged by <branch_tag1> has not been created,
- then the tag shows up as a second branch off the same
- branch point revision:
-
- Example:
- <branch_tag1> --> BR1
- <tag2> --> TT2
- <file> --> Symbols: BR1:1.2.0.2 (No 1.2.X exists.)
- After --> Symbols: BR1:1.2.0.2,TT2:1.2.0.4
-
-
-
- In all four cases above, if <tag2> already exists on the file, you
- get an error unless you specify the '-F' option.
-
- In all four cases, if <tag1> does not exist on the file, <tag2> is
- not added unless you specify the '-f' option.
-
-
- 3M.4 What happens if the tags are the same in "rtag -r <tag> <tag>"?
-
- Again, there are four cases depending on whether <tag> is a
- branch tag, or a non-branch tag and on whether you use the
- '-b' option to "rtag":
-
- 1. rtag -r <tag> <tag>
-
- Is a no-op. It does nothing even with '-F' specified.
-
- If you add the '-f' option ("rtag -f -r <tag> <tag>"), then
- <tag> is attached to the latest revision on the Main Branch if
- the file does *not* already have <tag> on some revision.
-
- If the <tag> is already on the file, using "rtag -f" is still
- a no-op.
-
-
- 2. rtag -r <branch_tag> <branch_tag>
-
- Produces an error, since the <branch_tag> is already on some
- revision of the file.
-
- But, "rtag -F -r <branch_tag> <branch_tag>" turns the magic
- branch tag into a non-branch tag.
-
- Symbols: BR1:1.4.0.2
- becomes
- Symbols: BR1:1.4
-
-
- 3. rtag -b -r <tag> <tag>
-
- Produces an error, since the <tag> is already on the file.
-
- But, "rtag -F -b -r <tag> <tag>" turns the non-branch
- tag into a magic branch tag.
-
- Symbols: BR1:1.4
- becomes
- Symbols: BR1:1.4.0.2
-
-
- 4. rtag -b -r <branch_tag> <branch_tag>
-
- Produces an error, since the <branch_tag> is already on the
- file.
-
- But, "rtag -F -b -r <branch_tag> <branch_tag>" increments the
- branch number. It essentially removes the branch and creates a
- new one by the same name.
-
- Symbols: BR1:1.2.0.4
- becomes
- Symbols: BR1:1.2.0.6
-
-
-
- 3M.5 Why doesn't "rtag -b -r <branch_tag1> <branch_tag2>" rename or
- duplicate a magic branch tag?
-
- None of the "tag" or "rtag" options rename anything. They only
- apply (or, with the '-F' option, move) tags to specific revisions
- in the file.
-
- See 3M.[3-4] above for details of how it works.
-
- To rename a non-branch tag, see 3O.9.
- To rename a magic branch tag, see 4D.5
-
-
-
-----------------
--- Section 3N -- "status", "st", "stat"
-----------------
-
- **** Questions:
-
- 3N.1 What is "status" for?
- 3N.2 Why does "status" limit the File: at the top to 17 characters?
- 3N.3 Why does it print "Sticky" lines when the values are "(none)"?
- 3N.4 Shouldn't the status "Needs Checkout" be "Needs Update"?
-
-
- **** Answers:
-
- 3N.1 What is "status" for?
-
- To display the status of files, including the revision and branch
- you are working on and the existence of "sticky" information.
-
-
- 3N.2 Why does "status" limit the File: at the top to 17 characters?
-
- Designed that way to line up with other data. You can find the
- whole filename in the line beginning with "RCS version:", which is
- not limited in length.
-
-
- 3N.3 Why does it print "Sticky" lines when the values are "(none)"?
-
- Oversight. It should probably elide lines without information.
-
-
- 3N.4 Shouldn't the status "Needs Checkout" be "Needs Update"?
-
- Probably.
-
- [[Did this show up in CVS 1.4?]]
-
-
-
-----------------
--- Section 3O -- "tag", "ta", "freeze"
-----------------
-
- **** Questions:
-
- 3O.1 What is "tag" for?
- 3O.2 What is the difference between "tag" and "rtag"?
- 3O.3 Why does "tag -b" not put a tag on the Branch Point revision?
- How do I refer to the Branch Point?
- 3O.4 So "{r}tag" labels a bunch of files. What do you use a Tag for?
- 3O.5 How do I get "tag" and "rtag" to send mail the way "commit" does?
- 3O.6 Why can't "tag" handle the '-r' option that "rtag" takes?
- 3O.7 After a "tag <tag>" in my working directory, why doesn't "checkout
- -r <tag>" somewhere else produce copies of my current files?
- 3O.8 Why doesn't "tag" write a history record the way "rtag" does?
- 3O.9 How do I rename a <tag>?
-
-
- **** Answers:
-
- 3O.1 What is "tag" for?
-
- To add a symbolic label (a "tag") to the RCS files last checked
- out, updated or committed in a working directory.
-
-
- 3O.2 What is the difference between "tag" and "rtag"?
-
- The end result of both commands is that a <tag>, or symbolic name,
- is attached to a single revision in each of a collection of files.
-
- The differences lie in:
-
- 1. The collection of files they work on.
-
- "rtag" works on the collection of files referred to by a
- "module" name as defined in the "modules" file, or a relative
- path within the Repository.
-
- "tag" works on files and directories specified on the command
- line within the user's working directory. (Default is '.')
-
- Both commands recursively follow directory hierarchies within
- the named files and directories.
-
- 2. The revisions they choose to tag.
-
- "rtag" places a tag on the latest committed revision of
- each file on the branch specified by the '-r' option. By
- default it tags the Main Branch.
-
- "tag" places a tag on the BASE (i.e. last checked out, updated
- or committed) revision of each file found in the working
- directory. (The BASE revision of a file is the one stored in
- the ./CVS/Entries file.)
-
- 3. A different set of command line options.
-
- For example, "rtag" takes a "-r <oldtag>" option to retag an
- existing tag. The "tag" command does not.
-
- 4. How it is logged.
-
- Currently "rtag" records the <tag> and the module in the
- "history" file, while "tag" does not.
-
-
- 3O.3 Why does "tag -b" not put a tag on the Branch Point revision?
- How do I refer to the Branch Point?
-
- This is probably an oversight, or a disbelief in the need for it.
- If everything works perfectly, the "update -j" command will do the
- merge you need and you don't need to check up on it by playing
- with the branch point revision.
-
- The '-b' option attaches a magic branch tag to allow CVS later to
- figure out the branch point. The actual revision that <tag> is
- attached to does not exist. References to the branch tag are
- equivalent to references to the latest revision on the branch.
-
- There is no way to refer to the branch point without adding a
- non-branch tag. You might want to add non-branch tags as a
- habit and add branch tags later, possibly immediate after adding
- the non-branch tag. See 4C.3 on Creating a Branch.
-
-
- 3O.4 So "{r}tag" labels a bunch of files. What do you use a Tag for?
-
- You use it to "checkout" the labeled collection of files as a
- single object, referring to it by name.
-
- Anywhere a revision number can be used a Tag can be used. In fact
- tags are more useful because they draw a line through a collection
- of files, marking a development milestone.
-
- The way to think about a Tag is as a curve drawn through a matrix
- of filename vs. revision number. Consider this:
-
- Say we have 5 files (in some arbitrary modules, some may be in 2
- or more modules by name, some may be in 2 or more modules because
- of the Repository tree structure) with the following revisions:
-
- file1 file2 file3 file4 file5
-
- 1.1 1.1 1.1 1.1 /--1.1* <-*- <tag>
- 1.2*- 1.2 1.2 -1.2*-
- 1.3 \- 1.3*- 1.3 / 1.3
- 1.4 \ 1.4 / 1.4
- \-1.5*- 1.5
- 1.6
-
- At some time in the past, the '*' versions were tagged. Think
- of the <tag> as a handle attached to the curve drawn through the
- tagged revisions. When you pull on the handle, you get all the
- tagged revisions. Another way to look at it is that you draw a
- straight line through the set of revisions you care about and
- shuffle the other revisions accordingly. Like this:
-
- file1 file2 file3 file4 file5
-
- 1.1
- 1.2
- 1.1 1.3 _
- 1.1 1.2 1.4 1.1 /
- 1.2*----1.3*----1.5*----1.2*----1.1 (--- <-- Look here
- 1.3 1.6 1.3 \_
- 1.4 1.4
- 1.5
-
- I find that using these visual aids, it is much easier to
- understand what a <tag> is and what it is useful for.
-
-
- 3O.5 How do I get "tag" and "rtag" to send mail the way "commit" does?
-
- The "commit" command is supported by two files ("commitinfo"
- and "loginfo") not used by other commands. To do logging the
- same way for "tag" and "rtag" would require another file like
- loginfo, which currently doesn't exist.
-
- The "rtag" command requires a "module" entry, which can specify a
- "tag" program using the "-t programname" option on the module
- line.
-
- There is no equivalent support for "tag".
-
-
- 3O.6 Why can't "tag" handle the '-r' option that "rtag" takes?
-
- Oversight. The answer is probably "Fixed in a Future Release."
-
-
- 3O.7 After a "tag <tag>" in my working directory, why doesn't "checkout
- -r <tag>" somewhere else produce copies of my current files?
-
- The only reason this would fail, other than misspelling the <tag>
- string, is that you didn't "commit" your work before "tagging" it.
- Only committed revisions may be tagged. Modified files are not
- marked for later tagging.
-
-
- 3O.8 Why doesn't "tag" write a history record the way "rtag" does?
-
- The "rtag" command was originally intended to place major
- "release" tags onto modules. The "tag" functionality was
- developed to *move* the more significant tag when slight changes
- to individual files sneaked in after the release tag was stamped
- onto the Repository.
-
- The significant event was the "rtag", which was recorded in the
- "history" file for the "history -T" option to work.
-
- It turns out that "tag" is generally more useful than "rtag", so
- the model has changed. Future revisions of CVS will probably
- store both kinds of tags in the history file.
-
-
- 3O.9 How do I rename a <tag>?
-
- For a procedure to rename a branch tag, See section 4D.5
- The following covers only non-branch tags.
-
- First, pick a <newtag> that is not in use. You could reuse
- (i.e. move) an existing tag to the new revisions using the '-F'
- option, but that will confuse matters when both tags are not
- already on a file. (It will probably confuse "rtag -f" too.)
-
- Use "rtag" to place <newtag> only on revisions attached to
- <oldtag> in the whole Repository, then delete the old one.
-
- cvs rtag -r <oldtag> <newtag> world
- cvs rtag -d <oldtag> world.
-
-
- You can also checkout or update your working directory to the
- <oldtag> and "tag" rather than "rtag" the result. But that
- will take longer and it has the chance of producing conflicts.
-
- cvs update -r <oldtag>
- cvs tag <newtag>
- cvs tag -d <oldtag>
- cvs update -A (or cvs update -r <previous_tag>)
-
-
-----------------
--- Section 3P -- "update", "up", "upd"
-----------------
-
- **** Questions:
-
- 3P.1 What is "update" for?
- 3P.2 What do 'U', 'M' and 'C' mean when I type "update"? Are they
- different for "cvs -n update"?
- 3P.3 What's the difference between "update" and "checkout"?
- 3P.4 Why don't I get new files when I execute "update"?
- 3P.5 Why does "update" say 'M' both for plain modified files and for
- successful (i.e. conflict-free) merges? Aren't they different?
- 3P.6 What's a "sticky conflict"? How does it know a conflict occurred?
- 3P.7 Is there a feature to tell me what I have changed, added and
- removed without changing anything?
- 3P.8 Why were all my files deleted when I executed "update"?
-
-
- **** Answers:
-
- 3P.1 What is "update" for?
-
- The "update" command is by far the most important command and is
- probably also the most used command.
-
- It has five purposes: (And many options.)
-
- 1. To display the status of your working files.
-
- Though a plain "update" also displays the status, it does so
- after possibly altering your working directory. To see the
- status of your working files without changing anything, type:
-
- cvs -n update {optional list of files}
-
-
- 2. To merge changes made by others to the branch you are working
- on into your working files.
-
- Each working directory is attached to a branch, usually the
- Main branch. To merge changes made on your working branch
- since your last checkout, update or commit, type:
-
- cvs update {optional list of files}
-
-
- 3. To merge changes made on another branch into the branch you are
- working on (your "working branch").
-
- If you want to grab a whole branch, from the branch point,
- which is assumed to be on the Main Branch, to the end of the
- branch, you type:
-
- cvs update -j <branch_tag> {optional files}
-
- If you want to grab the changes made between two tags or
- revisions, you type:
-
- cvs update -j <tag1> -j <tag2> {optional files}
-
- (If you are working with a single file, the Tags could also be
- revisions numbers. Unless you take great care to match
- revision numbers across different files (a waste of time given
- the way Tags work), using revision numbers in place of the
- Tags for multiple files would be meaningless.)
-
-
- 4. To move your working directory to another branch.
-
- A working directory is presumed to be attached to (or working
- on) a particular branch, usually the Main branch. To alter
- what CVS believes to be your working branch, you "move" to that
- branch.
-
- To move to a tagged branch, type:
-
- cvs update -r <branch_tag> {optional files}
-
- To move to the Main Branch, type:
-
- cvs update -A {optional files}
-
- If you have modified files in your working directory, this is
- not a clean move. CVS will attempt to merge the changes
- necessary to make it look like you made the same changes to the
- new branch as you made in the old one. But if you do this
- twice without resolving the merge conflicts each time, you can
- lose work.
-
-
- 5. To retrieve old revisions of files.
-
- This option is similar to 4 above but you are not restricted to
- using a <branch_tag>. You may specify any revision or <tag>
- with '-r' and get the specified revision or the tagged
- revision:
-
- cvs update -r <tag/rev> {optional files}
-
- Or you may specify any date with '-D':
-
- cvs update -D <date> {optional files}
-
- The '-p' option sends the revisions to standard output
- (normally your terminal) rather than setting the "sticky" tag
- and changing the files.
-
-
- 3P.2 What do 'U', 'M' and 'C' mean when I type "update"? Are they
- different for "cvs -n update"?
-
- "cvs update" merges changes made to the Repository, since your
- last "checkout", "update" or "commit", into your working files.
- You can think of it as changing your BASE revision.
-
- "cvs update" prints lines beginning with:
-
- 'U' after replacing your unmodified file with a different
- revision from the Repository.
-
- 'M' for two different reasons:
-
- 1. for files you have modified that have not changed in
- the Repository.
-
- 2. after a merge, if it detected no conflicts.
-
- 'C' after a merge, if it detected conflicts. See 2D.7 and
- 3P.6 for more info on conflict resolution and "sticky
- conflicts."
-
- "cvs -n update" shows what it *would* do, rather than doing it.
- Or, another way of looking at it, "cvs -n update" displays the
- relationship between your current BASE revisions (identified in
- your ./CVS/Entries file) and the HEAD revisions (the latest
- revisions in the Repository).
-
- "cvs -n update" prints lines beginning with:
-
- 'U' for files you have not modified that have changed in the
- Repository.
-
- 'M' for files you have modified that have not changed in the
- Repository.
-
- 'C' for files you have modified that have also been changed in
- the Repository.
-
-
- See 4C.6 for what the letters mean when merging in from another
- branch. The output is almost the same for a normal update if you
- consider the Repository as the branch and your working directory
- as the "trunk".
-
-
- 3P.3 What's the difference between "update" and "checkout"?
-
- See 3C.4 above.
-
-
- 3P.4 Why don't I get new files when I execute "update"?
-
- There are six reasons for nothing to happen during an "update":
-
- 1. Nothing on your branch changed in the Repository.
-
- If no one has committed anything to the branch you are working
- on (normally the Main branch) since the last time you executed
- "checkout", "update" or "commit", nothing will happen.
-
- It's like shouting "xyzzy" or "plugh" in the wrong room.
-
- 2. You have a "sticky" non-branch <tag> or <date> attached to the
- working files you are trying to "update".
-
- At some time in the past you checked out or updated your
- directory with the "-r <tag>" or "-D <date>" option. Until you
- do it again with a different tag or date, or go back to the
- Main Branch with "update -A", you will never again see any
- updates.
-
- 3. The ./CVS/Entries.Static file exists and you are expecting a
- new file.
-
- If your ./CVS administrative directory contains a file named
- Entries.Static, no files will be checked out that aren't
- already in the Entries or Entries.Static file.
-
- 4. You forgot to use the '-d' option and are looking for new
- directories.
-
- If you execute "update" without the '-d' option, it will not
- create new directories that have been added to the Repository.
-
- 5. You typed "update" instead of "cvs update".
-
- On most Unix systems, your disk caches are now furiously being
- flushed by multiple update daemons, destroying performance and
- proving to management that you need more CPU power. :-)
-
- On HP systems you might be asked what package you want to
- install from the "update server".
-
- 6. Someone removed (using "admin -o") your BASE revision (the
- revision CVS thought you had in your working directory), then
- committed a "replacement". CVS is now confused because the
- revision in the Repository matches your BASE revision when the
- files themselves don't match. See 3B.6.
-
-
- 3P.5 Why does "update" say 'M' both for plain modified files and for
- successful (i.e. conflict-free) merges? Aren't they different?
-
- A design choice. Yes, they are different internally, but that
- shouldn't matter. Your files are in the same condition after the
- "update" as they were before -- a "diff" will display only your
- modifications. And you are expected to continue onward with parts
- two and three of the normal development cycle: "emacs" (a synonym
- for "edit" in most of the civilized world) and "commit".
-
-
- 3P.6 What's a "sticky conflict"? How does it know a conflict occurred?
-
- When a "cvs update" (or an "update -j") creates a conflict, it
- prints a 'C' and stores the timestamp of the file after the merge
- in a special field in the ./CVS/Entries file.
-
- This conflict indication implies that the merge command altered
- your working file to contain conflict markers surrounding the
- overlapping code segments. For example, say that
-
- - Two developers acquire revision 1.2 of <file> via "checkout" or
- "update".
-
- - Developer A changes line 1 from "9999" to "5555", then commits
- the file, creating revision 1.3.
-
- - Developer B changes line 1 from "9999" to "7777", then tries to
- commit the file, but is blocked because the file is not up to
- date. Developer B then runs "update" and sees the conflict
- marker 'C'. The beginning of the file would look like this:
-
- <<<<<<< <file> The working <file> in question.
- 7777 Change made to the working <file>.
- =======
- 5555 Change made in the first commit (1.3)
- >>>>>>> 1.3 The revision created by the first commit.
-
- The conflict is "sticky", which means that until the conflict is
- cleared, the "update" command will continue to display the file's
- status as 'C' and the "status" command will show the file's status
- as "Unresolved Conflict".
-
- Until the conflict is cleared, "commit" is blocked for this file.
-
- The sticky conflict indicator can be cleared by:
-
- 1. Resolving the conflict by editing the file. Two things must
- happen before the conflict is considered resolved:
-
- The timestamp of the file must change.
- *and*
- The file must contain no conflict markers. (The string
- searched for in the file is the regexp: "^>>>>>>> ".)
-
- After clearing the sticky conflict indicator, you may then
- commit the file normally.
-
- 2. Removing the file and running "update". This throws away the
- local changes and accepts the latest committed file on this
- branch. No commit is needed.
-
- 3. Forcing the commit to happen by using "commit -f". This is
- probably a mistake since there are few lines of real
- text that begin with ">>>>>>> ".
-
-
- 3P.7 Is there a feature to tell me what I have changed, added and
- removed without changing anything?
-
- The command "cvs -n update" will do exactly that.
-
-
- 3P.8 Why were all my files deleted when I executed "update"?
-
- You probably executed "update -r <tag>" some time ago, then
- removed <tag> from the Repository files. "update -r <tag>" will
- delete a file that doesn't contain <tag>.
-
- A way to fix this is to "cd" into your working directory and
- type:
-
- cvs update -A
-
- If you don't want the latest revisions on the Main (or Vendor)
- Branch, then decide what Tag (normal or branch) you want and type:
-
- cvs update -r <the_tag_you_want>
-
- Another way to make a file disappear is to execute "update -D
- <date>" where <date> is before the date stamped onto the first
- revision in the RCS file.
-
-
-
-===============================================
-== Section 4 ==== Advanced Topics ====
-===============================================
-
-----------------
--- Section 4A -- Installing CVS
-----------------
-
- **** Questions:
-
- 4A.1 What do I have to do before I install CVS?
- 4A.2 How do I configure the CVS programs?
- 4A.3 What do I have to install?
- 4A.4 How do I work around the merge problems in GNU diff version 2.1
- or later?
-
-
- **** Answers:
-
- 4A.1 What do I have to do before I install CVS?
-
- 1. You must decide where to set up a Repository.
-
- Though you can construct a Repository tree structure using
- links and mount points, there must be a single copy of each
- real file across your entire organization. You may not "rdist"
- files and expect to edit both copies.
-
- CVS does not support a truly distributed Repository. You can
- have multiple Repositories, but each one must be mounted (not
- copied or "rdist"ed) from a single place onto all machines
- where it will be used.
-
- Initially, a Repository takes about same amount of disk space
- as the sources you want to put into it, plus a bit of overhead
- for the RCS files.
-
- See Section 4B. For multiple Repositories, see 4G.3
-
- 2. You need a directory in everyone's $PATH variable where you can
- install all the executables. /usr/local/bin is a common place.
-
- 3. You need some helper tools besides CVS such as "RCS" and a
- good set of "diff" and "diff3" programs. See 1B.4 for
- suggestions.
-
- 4. Read the README, INSTALL and ChangeLog files to see what you
- are getting into.
-
- 5. Make sure you have versions of all the programs mentioned in
- the "cvs/src/options.h" and "cvs/src/rcs.h" files.
-
- 6. Though you can probably muddle along without it, you should
- appoint one or more "Repository Administrators" who will be
- responsible for maintaining the Repository structure,
- administrative files and the "modules" interface.
-
- Someone at your site should probably be on the info-cvs mailing
- list. See 1B.5.
-
-
- 4A.2 How do I configure the CVS programs?
-
- 1. You should certainly start by reading the README file, the
- INSTALL files and possibly the ChangeLogs in each directory,
- the Makefile.in files and the "cvsinit.sh" program.
-
- 2. Edit the "options.h" file in the "src" directory.
-
- You might need to specify a few site-specific pieces of
- information including the names of a number of functions.
-
- Hint1: You probably want to set the DIFF macro to use your
- version of the GNU diff program with the '-a' option.
- Ours is set to "gdiff -a".
-
- Hint2: You want to use RCS 5.6.0.1 or greater and set the
- "HAVE_RCS5" macro.
-
- 3. Execute the ./configure command.
-
- 4. Type "make".
-
- 5. After running "make" you might try running the "sanity.sh"
- script:
- ./src/sanity.sh `pwd`/src/cvs
-
- It writes into /tmp/cvs-sanity by default.
-
- 6. Finish reading the INSTALL file and test out the system.
-
-
- 4A.3 What do I have to install?
-
- 1. Install the "cvs" executable and "mkmodules" from the CVS
- sources. The man page is useful too. If you plan to report
- bugs, you should also install "cvsbug".
-
- 2. Make sure you have versions of all the programs mentioned in
- the options.h file, most of which are included in a standard
- Unix system.
-
- 3. Unless you plan to reimplement RCS [:-)], you must install RCS.
-
- It is a very good idea to examine the RCS installation
- instructions and make sure you are using the GNU versions of
- "diff" and "diff3" or merges (an important part of CVS) will
- not work as well as you'd like.
-
- 4. Set your $CVSROOT environment variable and create the
- Repository (which you planned out in 4A.1) with the "cvsinit"
- command at the top of the CVS sources.
-
- 5. You'll need to edit the Repository control files created by
- "cvsinit".
-
- 6. Install any helper programs mentioned in the modules file.
-
-
- 4A.4 How do I work around the merge problems in GNU diff version 2.1
- or later?
-
- See 1B.4 If you use recent versions of RCS and "diff", you won't
- run into the above. If you do, see 5B.8
-
-
-----------------
--- Section 4B -- Setting up and Managing the Repository
-----------------
-
- **** Questions:
-
- 4B.1 What do I do first? How do I create a Repository?
- 4B.2 What are those files in $CVSROOT/CVSROOT?
- 4B.3 Is there any other state stored in the Repository besides in the
- $CVSROOT/CVSROOT directory?
- 4B.4 How do I put sources into the Repository?
- 4B.5 What file permissions should I use on (and in) the Repository?
- 4B.6 How do I structure my Repository?
- 4B.7 Why would anyone use "modules"? They are too restrictive. I
- want to be able to select just the files I want to edit.
- 4B.8 How do I rename a file or directory? What are the consequences?
- 4B.9 What are "Attic" directories?
- 4B.10 Is it OK to remove anything from the Repository?
- 4B.11 Can I convert to CVS from RCS without losing my revision history?
- 4B.12 Can I move RCS files with branches in them into the Repository?
- 4B.13 Can I use raw RCS commands on the Repository?
- 4B.14 How do I convert from SCCS to RCS?
- 4B.15 How do I limit access to the Repository?
- 4B.16 What are the Repository Administrator's responsibilities?
- 4B.17 How do I move the whole Repository?
- 4B.18 How do I change permissions on a file in the Repository by using
- a CVS command? (i.e. without using "chmod 777 $CVSROOT/dir/file")
-
-
- **** Answers:
-
-
- 4B.1 What do I do first? How do I create a Repository?
-
- First, install all the programs. (See Section 4A.)
-
- Then create a Repository by executing "cvsinit", which works only
- from within the head of the CVS source directory. (It needs files
- from the distribution to work.)
-
- If you want a very primitive Repository and don't want to save a
- history log, refer to modules, or use any of the "info" files for
- logging, pre-commit checks, or editing templates, you can dispense
- with "cvsinit" entirely. I would advise executing it.
-
- The cvsinit program will create a short modules file containing
- the module named "CVSROOT". To to your work directory and type:
-
- cvs checkout CVSROOT
-
- Then read the files that are checked out.
-
- You will certainly want to add modules of your own. Edit the
- "modules" file and add lines to describe the items you want to
- "checkout" by module name. Here's a short list that could be
- used for storing a small number of GNU and PD sources:
-
- local local
-
- gnu local/gnu
- emacs local/gnu/emacs
- cvs local/gnu/cvs
-
- public local/public
- pdprog1 local/public/pdprog1
- pdprog2 local/public/pdprog2
-
- test test
- junk test/junk
-
-
- When you are done editing, "commit" the modules file. If you
- configured CVS to use "dbm", you might have to edit and commit the
- modules file twice to change the pathname of the mkmodules program
- in the modules file.
-
- Try using the "import" command to insert the "junk" module
- and play around until you are comfortable.
-
-
-
- 4B.2 What are those files in $CVSROOT/CVSROOT?
-
- There are eight Repository control (or "database") files of
- interest in the CVSROOT directory:
-
- 1. modules contains the "modules" database. See 1D.11, 2C.7,
- 4B.6 and 4B.7 for more details.
-
- 2. commitinfo contains two columns: 1. a regular expression to
- match against pathnames within the Repository and
- 2. a <command> to execute for matching pathnames.
-
- When you execute "commit", CVS passes the
- Repository pathname for each directory (and the
- files to commit within that directory) to
- <command>. If <command> exits with a non-zero
- status, the commit is blocked.
-
- A <command> associated with a pathname of
- "DEFAULT" is executed if nothing else matches.
- Every <command> associated with a pathname of
- "ALL" is executed separately.
-
- 3. rcsinfo contains the same first column as commitinfo, but
- the second column is a template file for
- specifying the log entry you are required to enter
- for each commit.
-
- "DEFAULT" and "ALL" work the same as in the
- commitinfo file.
-
- 4. editinfo contains the same two columns as commitinfo, but
- the <command> in the second column is intended to
- do some consistency checking on the commit log.
-
- "DEFAULT" works as in commitinfo.
-
- 5. loginfo contains the same two columns as commitinfo, but
- the <command> is expected to read a log message
- from its standard input. The <command> can do
- anything it wants with the log information, but
- normally it is appended to a log file or sent to
- mailing lists.
-
- "DEFAULT" & "ALL" work the same as in commitinfo.
-
- 6. cvsignore contains "ignore" patterns that are added to the
- built-in ignore list. See 2D.10.
-
- 7. checkoutlist contains a list of other files kept under RCS in
- $CVSROOT/CVSROOT that should be checked out by
- mkmodules to provide a readable copy.
-
- 8. history contains a stream of text records, one for each
- event that the "history" command is interested
- in. Though the contents of the history file can
- be read, it is intended to be read and displayed
- by the "history" command. This file is the only
- one in the above list that is not under RCS.
-
-
- 4B.3 Is there any other state stored in the Repository besides in the
- $CVSROOT/CVSROOT directory?
-
- Only in the RCS files. The Repository holds exactly two things:
- the tree of RCS files (each usually ending in ",v") and the
- CVSROOT directory described above.
-
-
- 4B.4 How do I put sources into the Repository?
-
- There are three main ways to put files in the Repository:
-
- 1. Use the "import" command described in Section 3H.
-
- This method is the fastest way to put trees of new code into
- the Repository and the *only* way to handle source releases
- from a 3rd party software vendor.
-
- 2. Use "add" followed by "commit".
-
- This is how to add new files and directories to the Repository,
- a few at a time. Directories don't need to be committed.
-
- 3. You can move RCS files directly into the Repository.
-
- You should create a directory hierarchy to hold them, but you
- can just move arbitrary ",v" files into the Repository. The
- only "state" in the Repository other than within ",v" files is
- in the required CVSROOT directory at the top of the Repository.
-
-
- 4B.5 What file permissions should I use on (and in) the Repository?
-
- If you run a completely open environment (which usually means that
- you don't have, or don't want to waste, the time to deal with it):
-
- - Set all directory permissions to 777.
-
- - Have everyone set their umasks to 0.
-
- (BTW, I don't suggest this. I am merely reporting it.)
-
-
- If you are a normal Unix shop and want to use groups effectively:
-
- - Set all the directory permissions in the Repository to 775.
-
- If you are using a system that handles both System V and BSD
- filesystems, you might have to set the permissions to 2775.)
-
- If you are using one of the many recent versions of Unix that
- don't allow you to use the full octal mode, then you'll have
- to type: chmod u=rwx,g=rwx,o=rx,g+s <dir>
-
- - Change all the groups on the directories to match the groups
- you want to write to various directories.
-
- - Make sure every user is in the appropriate groups.
-
- - Have everyone set their umask to 002, including root.
-
-
- If you don't want non-group members to even read the files, do the
- above, but change:
-
- - Repository directory permissions to 770. (or 2770)
-
- - umasks to 007.
-
-
- If you work in an environment where people can't be trusted to
- set their "umask" to something reasonable, you might want to set
- the umask for them:
-
- mv /usr/local/bin/cvs /usr/local/bin/cvs.real
- cat > /usr/local/bin/cvs
- #!/bin/sh
- umask 2 # Or whatever your site standard is.
- exec /usr/local/bin/cvs.real ${1+"$@"}
- ^D
-
-
- 4B.6 How do I structure my Repository?
-
- The Repository holds your software. It can be all interrelated
- or it can be a bunch of separately managed directories.
-
- How you break a whole system down into its component parts, while
- defining interfaces between them, is one aspect of "Software
- Engineering", a discipline that requires the study of dozens of
- strange and wonderful areas of the computer and management worlds.
-
- CVS provides a way to keep track of changes to individual files,
- a way to "tag" collections of files, and a way to "name"
- collections of files and directories. That's all. Everything
- else is in the way you apply it.
-
- In other words, you should structure your Repository to match your
- needs, usually tied in with the other tools you use to build,
- install and distribute your work. Common needs include the
- ability to:
-
- - mount (or automount) directories from many places in your
- organization.
- - check out just what you need and no more.
- - check out multiple sections in a fixed relation to each other.
- - check out large sections to match the assumptions built into
- your build system. (Makefiles?)
-
- In my opinion, you should start small and keep everything in one
- tree, placing each major sub-system into a separate directory.
- Later, when you know what you are doing, you can make it more
- sophisticated.
-
-
- 4B.7 Why would anyone use "modules"? They are too restrictive. I
- want to be able to select just the files I want to edit.
-
- Any form of structure is restrictive. If you believe that total
- chaos is a viable working paradigm, or if you believe you can keep
- track of the interrelations between all portions of your
- Repository in your head, then you can do what you please.
-
- If you believe that systems of files require management and
- structure, then the "modules" idea is very useful. It is a way
- to impose a naming scheme on a tree of files, a naming scheme that
- can be simpler than a large list of relative pathnames.
-
- The "modules" file represents a published interface to the
- Repository set up by your Repository Administrator. If s/he did a
- creditable job, the modules offered will be internally consistent
- and will smoothly interact with the rest of your environment.
-
-
- 4B.8 How do I rename a file or directory? What are the consequences?
-
- In CVS there is no single "rename" command.
-
- See 2C.4 for the suggested way to rename a file or directory.
-
- The rest of this section covers some of the consequences of
- renaming.
-
- A "renaming database" has been proposed that would keep track
- of name changes so that "update -r <tag>" would continue to
- work across the renaming. But as it stands, you have to pick
- one of the following options:
-
- 1. Use the technique described in 2C.4. (For each file, duplicate
- the file in the Repository, "remove" the old version so it
- winds up in the Attic and strip all Tags off the new version.)
-
- - "update -r <tag>" produces the correct files.
-
- - The duplicated revision history can be slightly misleading.
-
- - A plain (i.e. without the "-r <tag>") "checkout" or "update
- -d" will create directories "renamed" this way, but you can
- delete it and a plain "update" won't bring it back.
-
-
- 2. Move the files and directories in the Repository to the new
- names.
-
- - You save the revision history under a different file name.
-
- - You save a little space.
-
- - "update -r <tag>" produces the wrong files or directories.
-
- This is not a good general solution, but if you plan never to
- look back (someone may be gaining on you!), it is sometimes a
- useful notion.
-
- If you are clever with Makefiles, you might be able to rework
- them to handle either the new or old names, depending on
- which ones exist at the time. Then you can move an old <tag>
- onto the new, more sophisticated, revision of the Makefile.
- (Yes, this changes the "released" file if <tag> indicates a
- release. But it is an option.)
-
- - Important Note: If you rename a directory, you must rename
- the corresponding directory in every checked-out working
- directory. At the same time, you must edit the pathname
- stored in the ./CVS/Repository file within each of the moved
- directories.
-
- The easiest way to move a lot of directories around is to
- tell everyone to remove their working directories and check
- them out again from scratch.
-
- - The file exists in the working directory and in the
- ./CVS/Entries file, but not in the Repository. For the old
- file, "update" prints:
-
- cvs update: xyz.c is no longer in the repository
-
- and deletes the file. If the file was modified, "update"
- prints:
-
- cvs update: conflict: xyz.c is modified but
- no longer in the repository
- C xyz.c
-
- and leaves the file alone. In the new directory, you see:
-
- U xyz.c
-
- as you would if someone else executed "add" and "commit".
-
-
- 3. For each file, copy the working file to a new name in the
- working directory and use the "cvs remove" to get rid of the
- old old file and "cvs add" to add the new one. Since there is
- no way for CVS to remove a directory, this only works for files.
-
- - This is what most people think of first. Without a "rename"
- command, the remove/add technique seems obvious.
-
- - You lose the connection of your new working file to its past
- revision history.
-
-
- 4B.9 What are "Attic" directories?
-
- When you use the "remove" command on a file, CVS doesn't delete
- the file, it only registers your desire to delete it.
-
- When you "commit" a removed file, CVS moves the Repository's
- matching RCS file into a sub-directory named "Attic" within the
- Repository.
-
- Attic files are examined when the '-r' or '-D' option is used
- on "checkout" or "update". If the specified revision, tag or
- date matches one on a file in the Attic, that file is checked out
- with the others.
-
- You can think of the Attic as a sort of dead branch, which is only
- looked at when you refer to a <tag> or <date>.
-
-
- 4B.10 Is it OK to remove anything from the Repository?
-
- In general, removing anything from the Repository is a bad idea.
- The information in a deleted object is lost forever. There are
- many ways to skip over files, directories and revisions without
- deleting them.
-
- Here are some of the consequences of removing the following things
- stored in the Repository:
-
- 1. CVSROOT files (Repository control files)
-
- The Repository will work without any of them, but you should
- understand what you are losing by deleting them. See 4B.2.
-
- 2. Revisions
-
- The only way to remove revisions is to use the "admin -o"
- command (or the equivalent RCS command "rcs -o").
-
- They are lost forever. Any tags formerly attached to deleted
- revisions are now pointing into the Phantom Zone. You'll need
- to contact Jor-el to get them back.
-
- 3. Files
-
- You should not remove a file unless you truly never want to see
- it again. If you want to be able to check out an old revision
- of this file, use "cvs remove" instead.
-
- 4. Tags
-
- Tags take up little space and you can't recover from deleting
- them. If you depend on tags for releases you will lose vital
- information.
-
- 5. Directories
-
- There is no Attic for directories, so the only way to remove
- them is to use "rm -r". They are gone forever.
-
- If you delete (or move) a directory, all checked-out versions
- of that directory will cause CVS to halt. You'll have to visit
- each checked-out directory and remove the matching working
- directory by hand.
-
- 6. Attic files
-
- The "remove" command sends files to the Attic. To really
- delete them, you have to go into the Attic and use "rm".
-
- If a file in the Attic has a Tag on it that you might ever want
- to check out again, you probably don't want to delete it.
-
- 7. Lock files (named: "#cvs.[wr]fl.<pid>")
-
- These are lock files. If you are getting "lock" errors and
- the dates on the lock files indicate that they are old, you can
- delete them.
-
- Deleting lock files still in use by a CVS process might produce
- unusual errors.
-
-
- 4B.11 Can I convert to CVS from RCS without losing my revision history?
-
- Yes, you can simply move (or copy) your RCS files into a directory
- within the Repository, check out that directory and start working.
-
-
- 4B.12 Can I move RCS files with branches in them into the Repository?
-
- Yes, but they may not work if you created branches in a way that
- conflicts with CVS's assumptions:
-
- 1. You can't use .0. branches. (They are reserved for "Magic"
- branch tags.)
-
- 2. If you use branch 1.1.1, you can't use the Vendor branch.
-
- You can use other RCS branches under CVS. There is no need to
- create "magic" branch tags because the physical branch already
- exists.
-
-
- 4B.13 Can I use raw RCS commands on the Repository?
-
- You can use raw rcs commands directly on the Repository if you
- take a little care. The Repository itself contains no "CVS state"
- (as opposed to RCS revision histories) outside the CVSROOT
- directory.
-
- But using raw RCS commands to change branches, tags or other
- things that CVS depends on may render the files unusable.
-
- See 4D.7 on RCS/CVS sharing of the Repository and Section 3B on
- the "admin" command.
-
-
- 4B.14 How do I convert from SCCS to RCS?
-
- You'll have to execute something like "sccs2rcs" (in the CVS
- contrib directory) on every file. Then you can move the resulting
- RCS files into the Repository as described above.
-
-
- 4B.15 How do I limit access to the Repository?
-
- There are all sorts of ways to restrict access to Repository
- files, none of which are hooked directly into CVS.
-
- Techniques for limiting access include:
-
- 1. Training, management and good backups.
-
- The best form of Repository control is a combination of:
-
- - A reliable backup scheme (verify it!)
- - Enough training to ensure your developers are competent
- and knowledgeable about all areas of your sources.
- - Effective management of the boundaries and grey areas.
-
- In many cases, technical solutions to "security" problems are
- inadequate. You should first try to avoid them.
-
- Personal Opinion: In an environment where "unknowns" are
- allowed to touch important sources the "owner" of the CVS
- Repository must be a large, loud, vigorous lout with a
- well-balanced truncheon and the right to use it. Don't
- underestimate the effectiveness of letting everyone know they
- will be strapped into the stocks on the Town Common and pelted
- with vegetables if they break something they don't understand
- without first asking the experts.
-
- 2. Set Unix groups and permissions. See 4B.5.
- You can set different owners, groups and permissions for each
- sub-directory within the Repository if that helps.
-
- 3. Catch invocations of "commit" by defining pre-commit programs
- in the "commitinfo" file. This is fairly powerful, since it
- can block commits based on anything you can program. Take a
- look at the programs in the "contrib" directory of the CVS
- source tree.
-
- 4. Use multiple Repositories, each with its own protection scheme.
- If you use NFS (or AFS) you can even use "export" restrictions
- to various groups of machines to keep (for example) the
- Engineering Repository off the Customer Service machines.
-
- 5. Try the "setgid" trick described in 4D.13.
-
- 6. Try to use the RCS access control lists, though I don't
- think CVS will handle them cleanly.
-
- 7. Edit the source code to CVS to add your own access control.
-
-
- 4B.16 What are the Repository Administrator's responsibilities?
-
- Generally, the Administrator should set "policy", create the
- Repository and monitor its size and control files.
-
- Some specific responsibilities include:
-
- 1. Examining the Repository once in a while to clean up:
-
- a. Trash files left by misguided developers who mistake the
- Repository for a working directory.
-
- b. Non-RCS files. Other than the files CVS needs in the
- $CVSROOT/CVSROOT directory, every file in the Repository
- should be an RCS file.
-
- c. Lock files (both CVS '#*' and RCS ',*' files) left around
- after crashes.
-
- d. Wrong permissions, groups and ownerships.
-
- e. Locked files. (RCS locks, that is.)
-
- f. Attic files that should never have been under CVS at all.
- Don't blindly delete files from Attic directories -- they
- were mostly put there (via the "cvs remove") for a reason.
- Files that should be deleted are binary files (e.g. '*.o',
- 'core', executables) that were mistakenly inserted by
- "import -I !".
-
- 2. Maintaining the modules file.
-
- 3. Storing site-specific ignore patterns in the
- $CVSROOT/CVSROOT/cvsignore file.
-
- 4. Storing the names of non-standard CVSROOT files (See 4B.2) in
- the $CVSROOT/CVSROOT/checkoutlist
-
- 5. Maintaining the other Repository control files: commitinfo,
- loginfo, rcsinfo and editinfo.
-
- 6. Pruning the history file every once in a while. (Try the
- "cln_hist.pl" script in the "contrib" directory.)
-
- 7. Staying aware of developments on the info-cvs mailing list and
- what is available in the FTP and WWW archives.
-
- 8. Running "ps ax" once in a while and kill off any "update"
- programs not running as "root". It is too easy to leave the
- "cvs" off the front of the "cvs update" command.
-
- 9. Executing monitor programs to check the internal consistency of
- the Repository files. Ideas:
-
- a. Files that have a default RCS branch that is not 1.1.1
- (From an abuse of "admin -b".)
-
- b. Files that have only Revisions 1.1 and 1.1.1.1, with a
- default branch of "MAIN". (From an abuse of "admin -o".)
-
- c. Existing branch tags and various branch consistency checks.
-
-
- 4B.17 How do I move the whole Repository?
-
- Copy or move the tree. (On Unix systems, a set of piped "tar"
- commands works great. If the Repository does not contain any
- symlinks, which it normally doesn't, you can also use "cp -r".)
-
- If you can avoid changing $CVSROOT (i.e. the "logical" pathname of
- the Repository) by replacing the old location with a symbolic link
- to the new location, you don't have to do anything else.
-
- (You could also mount the new location on top of the old location
- if you are using NFS or some other filesystem that allows it.)
-
-
- If you must change $CVSROOT, you must also tell everyone to change
- the CVSROOT environment variable in all running shells and in any
- personal configuration files ('.' files on Unix) where it is set.
-
- The Repository itself contains no references to its own name,
- except possibly in some of the files in the CVSROOT directory. If
- your modules (or loginfo, commitinfo, etc.) file mentions helper
- programs directly in the Repository, you'll have to change the
- pathnames to point to the new Repository location.
-
- The main changes you'll have to make are to all the CVS
- administrative files (./CVS/Repository and ./CVS/Root) in every
- working directory ever checked out from the previous location of
- the Repository you just moved.
-
- You have three choices:
-
- 1. If all ./CVS/Repository files in all working directories
- contain relative pathnames, you don't have to do anything else.
-
- 2. Have everyone "release" or delete their working directories
- (after committing, or just saving, their work) and check them
- all out again from the new Repository after the move.
-
- 3. Use "find . ( -name Repository -o -name Root )" and a
- PERL or shell script to run through all the ./CVS/Repository
- and ./CVS/Root files and edit the values in the files.
-
-
- 4B.18 How do I change permissions on a file in the Repository by using
- a CVS command? (i.e. without using "chmod 777 $CVSROOT/dir/file")
-
- When you first "import" or "add"/"commit" a file, the read and
- execute bits on the Repository file are inherited from the
- original source file, while the write bits on the Repository file
- are are turned off. This is a standard RCS action.
-
- After that, there is no way to alter the permissions on a file in
- the Repository using CVS (or RCS) commands. You have to change
- the permissions on both your working file and on the Repository
- file from which it was retrieved.
-
- Whenever you "checkout" the file or retrieve a new revision via
- "update" (or after a "commit"), your working file is set to match
- the permissions of the Repository file, minus any "umask" bits you
- have set.
-
-
-
-----------------
--- Section 4C -- Branching and Merging
-----------------
-
- **** Questions:
-
- 4C.1 What is a branch?
- 4C.2 Why (or when) would I want to create a branch?
- 4C.3 How do I create and checkout a branch?
- 4C.4 Once created, how do I manage a branch?
- 4C.5 Are there any extra issues in managing multiple branches?
- 4C.6 How do I merge a whole branch back into the trunk?
-=4C.7 How do I merge changes from the trunk into my branch or between
- branches?
- 4C.8 How do I merge onto the Main Branch a file that exists only on a
- branch other than the Main Branch? (i.e. it is in the Attic)
- 4C.9 How do I know what branch I'm (working) on?
- 4C.10 Do I really have to know the name of the branch I'm working on?
- 4C.11 How do I refer to the revision where I branched so I can see
- what changed since the Branch Point on another branch?
- 4C.12 Why didn't the command "cvs admin -bBRANCH1 *" create a branch?
- 4C.13 Is it possible to set the "default CVS branch" for everyone?
- 4C.14 How do I perform a large merge?
- 4C.15 Is a Vendor merge any different from a branch merge?
- 4C.16 How do I go back to a previous version of the code on a branch?
- 4C.17 Once I've found the files I want, how do I start changing them?
- I keep getting warnings about sticky tags.
- 4C.18 Why do I get the latest files on the branch when I tried to
- "update -r <tag>"?
- 4C.19 How can I avoid a merge? I just want to move the latest revision
- on my working branch directly onto the trunk.
- 4C.20 How to I avoid merge collisions in the RCS $\Log$ data?
- 4C.21 Why should I trust automatic merges?
- 4C.22 How does CVS decide if it can safely perform a merge?
- 4C.23 After resolving merge conflicts in a file, what if I want to keep
- my previous version, and not take any of the branch changes?
-
-
- **** Answers:
-
- 4C.1 What is a branch?
-
- Unfortunately, the word "branch" is an overloaded technical term.
- It is used in too many different ways in three categories. It
- might help to understand some of the issues by going through
- the categories:
-
- 1. How Humans use the word "branch":
-
- Most development starts with everyone working on the same
- software, making changes and heading toward a single goal.
- This is called something like "Main Line Development". Note
- that though many people do main line development on CVS's
- "Main Branch", that is a choice, not a requirement.
-
- After a release or when one or more developers want to go off
- and work on some project for a while, the Software Engineers
- assigned to deal with large software issues generate a "Branch
- in Development" to support the release or project. (Keep in
- mind that a programmer is no more a Software Engineer than a
- carpenter is a Civil Engineer.)
-
- Essentially, the word "branch" implies a way to allow
- simultaneous development on the same files by multiple people.
-
- The above terms are human-oriented. They refer to actions
- that people would like to take. They do *not* imply any
- particular implementation or set of procedures. Branches in
- development can be supported in many different ways.
-
-
- 2. How CVS uses the word "branch":
-
- CVS uses the word "branch" in a number of ways. The two most
- important are:
-
- - The vendor branch holds releases from (normally) an
- outside software vendor. It is implemented using a
- specific RCS branch (i.e. 1.1.1).
-
- - The "Main Branch", which normally holds your "Main Line
- Development", but is defined as the collection of
- revisions you get when you "checkout" something fresh, or
- when you use the '-A' option to "update".
-
- Important Note: The CVS "Main Branch" is *not* the same as
- the RCS concept with the same name. If you are using Vendor
- Branches, files you have never changed are on three branches at
- the same time:
-
- - The RCS 1.1.1 branch.
- - The CVS Vendor branch.
- - The CVS "Main Branch".
-
- The concepts overlap, but they are not equivalent.
-
- In referring to CVS, "branch" can be used in four other ways:
-
- - A CVS working directory satisfies the definition of
- "branch" for a single developer -- you are on a private
- "virtual branch" that does not appear in any of the RCS
- files or the CVS control files.
-
- - The CVS "default branch" is the Repository source for the
- collection of files in your working directory. It is
- *not* the same as the RCS "default branch". Normally the
- CVS default branch is the same as the CVS Main branch. If
- you use the "-r <branch_tag>" option to the "checkout"
- command, you will record a "sticky" tag that changes your
- default branch to the one you checked out.
-
- - A "magic" branch can be a branch that hasn't happened
- yet. It is implemented by a special tag you can check out
- that is not attached to a real RCS branch. When you
- commit a file to a magic branch, the branch becomes real
- (i.e. a physical RCS branch).
-
- - And, of course, CVS uses "branch" to indicate a
- human-oriented "branch in development".
-
- 3. How RCS uses the word "branch":
-
- - The RCS "Main Branch" (Synonym: "The Trunk") contains a
- series of two-part revision numbers separated by a single '.'
- (e.g. 1.2). It is treated specially and is the initial
- default branch. (The default default?)
-
- - The RCS "Default" branch starts out attached to the RCS "Main
- Branch". For RCS purposes, it can be changed to point to any
- branch. Within CVS, you *must*not* alter the RCS default
- branch. It is used to support the CVS idea of a "Main
- Branch" and it must either point to the RCS Main Branch, or
- the Vendor Branch (1.1.1) if you haven't made any changes to
- the file since you executed "import".
-
-
- 4C.2 Why (or when) would I want to create a branch?
-
- Remember that you can think of your working directory as a
- "branch for one". You can consider yourself to be on a branch
- all the time because you can work without interfering with others
- until your project (big or small) is done.
-
- The four major situations when you should create a branch:
-
- 1. When you expect to take a long time or make a large set of
- changes that the merging process will be difficult. Both
- "long" and "large" are defined in your own environment.
-
- 2. When you want to be able to "commit" and "tag" your work
- repeatedly without affecting others.
-
- If you ever think you need Source Control for your own work,
- but don't want your changes to affect others, create a private
- branch. (Put your username in the branch tag, to make it
- obvious that it is private.)
-
- 3. When you need to share code among a group of developers, but
- not the whole development organization working on the files.
-
- Rather than trying to share a working directory, you can move
- onto a branch and share your work with others by "committing"
- your work onto the branch. Developers not working on the
- branch won't see your work unless they switch to your branch or
- explicitly merge your branch into theirs.
-
- 4. When you need to make minor changes to a released system.
-
- Normally a "release" is labeled by a branch tag, allowing later
- work on the released files. If the release is labeled by a
- non-branch tag, it is easy to add a branch tag to a previously
- tagged module with the "rtag" command. If the release is not
- tagged, you made a mistake. Recovery requires identifying all
- revisions involved in the release and adding a tag to them.
-
-
- 4C.3 How do I create and checkout a branch?
-
- Suggested technique:
-
- 1. Attach a non-branch tag to all the revisions you want to
- branch from. (i.e. the branch point revisions)
-
- 2. When you decide you really need a branch, attach a branch tag
- to the same revisions marked by the non-branch tag.
-
- 3. "Checkout" or "update" your working directory onto the branch.
-
-
- A. Suggested procedure when using modules:
-
- 1. cvs rtag <branch_point_tag> module
- 2. cvs rtag -b -r <branch_point_tag> <branch_tag> <module>
- 3. cvs checkout -r <branch_tag> module
-
-
- B. Suggested procedure when using your working directory, which
- contains the revisions of your working files you want to branch
- from:
-
- 1. cvs tag <branch_point_tag>
- 2. cvs rtag -b -r <branch_point_tag> <branch_tag> <module>
- 3. cvs update -r <branch_tag>
-
-
- In each procedure above, Step #1 applies a non-branch tag to all
- the branch point revisions in the module/directory. Though this
- is not strictly necessary, if you don't add a non-branch tag to
- the revisions you branch from, you won't be able to refer to the
- branch point in the future.
-
- Between steps 1 & 2 you may commit changes. The result would be
- same because "rtag -r <oldtag> <newtag>" applies <newtag> to the
- same revision that <oldtag> is attached to. You can use this
- technique to avoid attaching *any* branch tags until you need
- them.
-
- Step B.2 has two corollaries:
-
- 1. If you plan to create the branch tag before committing
- anything in your working directory, you can use "cvs tag -b
- <branch_tag>" instead of the "rtag" command.
-
- 2. The <module> can be a relative path to a directory
- from which your working directory was checked out.
-
- If you have trouble figuring out what <module> to use (or
- pathname to use in its place), you can aim it at whatever
- parent directories you believe will cover all your work.
-
- If you are sure the <branch_tag> is not being used anywhere
- else, you can even aim it at the whole Repository ($CVSROOT),
- if you have to. It might take some extra time, but assuming
- that your <tag> is a unique string and you don't use the '-f'
- option to "rtag -r", "rtag" will only add a <tag> to files in
- which it actually *finds* the earlier <tag>.
-
- In each procedure above, Step #3 may occur any time after step 2.
- Unless you explicitly remove them with "tag -d", a <tag> is
- permanent.
-
-
- The <branch_tag> is an unusual creature. It labels a branch in a
- way that allows you to "checkout" the branch, to "commit" files to
- the end of the branch and to refer to the end of the branch. It
- does not label the base of the branch (the branch point).
-
- There are two obvious ways to choose the <branch_point_tag> and
- <branch_tag> names. But keep in mind that the <branch_tag> is
- typed by any developer who wants to work on the branch -- you
- should make it mean something to them.
-
- Style #1 presumes that the simple version string refers to a set
- of designed, documented or promised features, not to a specific
- set of files. In this case, you tag the branch with the generic
- Version string and assume that whenever you refer to "Version",
- you want the "latest" set of files associated with that Version,
- including all patches. (You can substitute whatever you like for
- "bp_", as long as your <branch_point_tag> is some modification of
- the <branch_tag>.)
-
- <branch_point_tag> Matching <branch_tag>
-
- bp_V1_3 V1_3
- bp_Release2-3-5 Release2-3-5
- bp_Production4_5 Release4_5
-
-
- Style #2 presumes that the simple version string refers to the
- specific set of files used to construct the first release of
- "version". In this case, you tag the branch-point revisions with
- the generic Version string and assume that whenever you refer to
- this Version, you want the original set of released revisions. To
- get the latest patched revisions of the release, you refer to the
- branch tag "latest_<branch_point_tag>". (You can substitute what
- ever you like for "latest_", as long as your <branch_tag> is some
- modification of the <branch_point_tag>.)
-
- <branch_point_tag> Matching <branch_tag>
-
- V1_3 latest_V1_3
- Release2-3-5 latest_Release2-3-5
- Release4_5 latest_Production4_5
-
-
- In both styles you can find out what you had to change since the
- original release of this Version by typing:
-
- cvs diff -r <branch_point_tag> -r <branch_tag>
-
- For Style 1, this is:
-
- cvs diff -r bp_<branch_tag> -r <branch_tag>
-
- For Style 2, this is:
-
- cvs diff -r <branch_point_tag> -r latest_<branch_point_tag>
-
-
- Notes on "being on a branch":
-
- - "update -r <tag>" tells CVS to attach a "sticky tag" to
- working directory (in ./CVS/Tag) and the checked-out files (on
- each line of ./CVS/Entries).
-
- - A "sticky" <tag> (including a <branch_tag>) causes most CVS
- commands to act as if "-r <tag>" were on the command line.
-
- - A "sticky" <branch_tag> indicates that the working directory
- (and working files) are "on the branch".
-
-
- 4C.4 Once created, how do I manage a branch?
-
- The most important thing you should know about managing a branch
- is that the creation of a branch is not a lightweight act. When
- you create a branch, you must also create a set of procedures to
- keep track of it.
-
- Specifically, you must:
-
- - Remember that the branch exists. (This is non-trivial if you
- create a lot of them.)
-
- - Plan when to merge it back into the main line of development.
-
- - Schedule the order that multiple branch merges are to be done.
-
- - If you ever intend to merge branches into each other, instead of
- limiting merges of branch work back into the "main line", you
- must keep careful track of which parts of which branches have
- merged into which other branches.
-
-
- The simplest way to deal with branches is to limit their number,
- "collapse" them back into the main line as quickly as is
- reasonable and forget them. If a group wants to continue working,
- tell them to create another branch off the fully merged main line.
-
- Remember that CVS is just a tool. Over time, it will probably
- handle branching better, requiring less careful attendance.
- But no matter how good it becomes, the whole idea of "branching"
- is a complicated management problem. Don't take it lightly.
-
-
- 4C.5 Are there any extra issues in managing multiple branches?
-
- If you plan to split from the "main line" and merge back after a
- time, the only problem will be scheduling the order of branch
- merges. As each branch is merged, the main line must be rebuilt
- and tested. Merging multiple branches (i.e. "lines of
- development") before building and testing creates more problems
- than you are ready for.
-
- If you plan to collapse some branches into others, then move the
- combined branches back into the main line, you have to be careful
- with the revisions and tags you hand to your "update -j"
- command, but it shouldn't be much trouble.
-
- If you plan to allow every branch to incrementally take the work
- done on other branches, you are creating an almost insurmountable
- bookkeeping problem. Every developer will say "Hey, I can
- handle taking just this little bit," but for the system as a
- whole it is disaster. Try it once and see. If you are forced
- into this situation, you will need to keep track of the beginning
- and end points of every merge ever done. Good Luck.
-
-
- 4C.6 How do I merge a whole branch back into the trunk?
-
- If you don't have a working directory, you can checkout and merge
- in one command:
-
- cvs checkout -j <branch_tag> <module>
- cd <module>
-
- If you already have a working directory:
-
- cd <working_directory>
- cvs update <== Optional, to bring it up to date.
- cvs update -j <branch_tag>
-
- CVS will print lines beginning with
-
- 'U' for files that you hadn't changed, but the branch did.
-
- 'M' for files that you changed and the branch didn't
- *and* for files that you both changed that were merged
- without overlaps. (This overload is unfortunate.)
-
- 'C' for files that you both changed in a way that conflicts
- with each other.
-
- You need to go edit all the 'C' files and clean up the conflicts.
- Then you must commit them.
-
-
-=4C.7 How do I merge changes from the trunk into my branch or between
- branches?
-
- The idea is similar to the above, but since CVS doesn't treat the
- main branch like other branches, you'll have to be more careful.
- There are 5 different ways to look at the problem.
-
- A. The way to merge *all* changes made on the trunk into a working
- branch is to move to the branch you want via "checkout -r" or
- "update -r":
-
- cvs update -r <branch_tag> {optional files}
-
- Then merge the changes from the trunk into your working branch
- using the pseudo-tag named "HEAD":
-
- cvs up -j HEAD {optional files}
-
- You will get everything from the branch point of the branch
- named <branch_tag> up to the HEAD of the main branch. This is
- still kind of strange. If the file is on a branch, HEAD should
- be the latest thing on the branch, not the HEAD of MAIN. But
- that's not the way CVS (currently) works.
-
- If you run "cvs up -j HEAD" again after adding more revisions
- to the trunk, you may get overlaps for the text you have
- already merged. It depends on your version of your RCS "merge"
- command (actually the "co -j" option, which depends on the
- version of "diff3" you configured RCS to use).
-
-
- B. You can merge the difference between any two <tags> using
- two "-j" options on "update" or "checkout".
-
- Identify the two tags on the branch you want to merge from.
-
- cvs update -j <tag1> -j <tag2> {optional files}
-
- This step assumes you were careful about tagging milestones.
- You can use this technique for any two <tags> on the same
- branch, even the trunk. It is also possible to use tags on
- different branches, but you'll have to ponder the meaning of
- the difference between those two tags.
-
- In place of one of the <tags>, you can use a <branch_tag> to
- refer to the latest revision on that branch. See 4C.11 and
- 4C.3 for info on branch points.
-
- Merges can also be performed by handing RCS revisions to the
- '-j' options, but since revision numbers aren't the same in all
- files, merging by number is normally limited to one file. Sets
- of files with the exact same trees of branches and revision
- numbers would work too, but that's a rare situation.
-
-
- C. To "take" revisions from other branches instead of merging
- them, see 4C.19 for an idea.
-
-
- D. A way to gain the effect of merging the main to the branch is
- to merge the branch into the main using the normal
-
- cvs update -A {optional files}
- cvs update -j <branch_tag> {optional files}
- cvs commit
- cvs tag -F -b <same_branch_tag> {optional files}
-
- See part B of 4D.5
-
-
- E. Other oddities.
-
- This also works, but is probably not officially supported:
-
- cvs update -j N {optional files}
-
- where N is a number. This will merge all the changes from the
- branch point up to the highest revision on the main branch
- starting with N. For example, if your highest trunk revision
- is 1.52, you can use this to grab revisions from the trunk:
-
- cvs update -j 1 {optional files}
-
- Another example: Say you have a branch point at rev 1.2 for a
- branch named "BR1" and trunk revisions 1.3, 1.4, 2.1, 2.2, 2.3,
- 3.1, 3.2. Then:
-
- cvs update -j 1 {optional files}
-
- will merge the changes from 1.2 to 1.4
-
- cvs update -j 2 {optional files}
-
- will merge the changes from 1.2 to 2.3
-
- cvs update -j 3 {optional files}
-
- will merge the changes from 1.2 to 3.2, which in this example, is
- equivalent to the use of "-j HEAD" in part A above.
-
- The intuitive (at least to me):
-
- cvs up -j MAIN (or TRUNK) {optional files}
-
- doesn't work. If the trunk (i.e. "main branch") had an
- implicit branch named "MAIN", you could use:
-
- cvs up -j MAIN:10/26 -j MAIN:now {optional files}
-
- and refer to date-stamped revisions on the trunk using the
- <branch_tag>:<date> support that works on other branches.
-
- You might also think you could place an explicit tag on branch
- 1 (or higher) (e.g. MAINHACK:1) and use it in place of the
- implicit "MAIN", but I haven't found the right combination.
-
- [[If you find working techniques, I'll add them here.]]
-
-
- 4C.8 How do I merge onto the Main Branch a file that exists only on a
- branch other than the Main Branch? (i.e. it is in the Attic)
-
- For how such a file can exist, see 3A.2 and 3A.3.
-
- For how to avoid creating such a file, see 3A.5.
-
- Though you might think that the "update -j" command could perform
- the "merge" of a file from the side branch to the Main Branch, it
- isn't (yet) smart enough. Unfortunately, there is no single CVS
- command to do this -- it takes three steps:
-
- 1. To move something onto the Main Branch from the Attic, you have
- to physically move the file from the Attic to the main
- Repository directory associated with your working directory.
-
- It is exactly like resurrecting a removed file. See 3L.4
-
- I use something like this: (csh-like syntax)
-
- set repos = `cat ./CVS/Repository`
- mv $repos/Attic/filename,v $repos/filename,v
-
- (If you use relative paths in your Repository files, that first
- line becomes: set repos = $CVSROOT/`cat ./CVS/Repository`)
-
- 2. Now that the file is physically in the right place within the
- Repository, "update -A" will make it appear in your working
- directory on the Main Branch. Do that now.
-
- 3. You now have a choice. The act of physically moving the file
- has fused together the <branch_tag> branch and the Main Branch
- for this file. You can continue that way, making changes along
- the RCS Main Branch which CVS will (for this type of file only)
- treat as both the Main Branch and the <branch_tag> branch.
-
- The other choice, which I would suggest, is to re-tag the file
- with <branch_tag>, restoring a normal-looking magic branch tag
- to the file:
-
- cvs tag -F -b <branch_tag> <file>
-
-
- After you have done the above, you can run "update -A" or "update
- -r <branch_tag>" to resume whatever you were doing before you
- started this procedure.
-
- Caveat: The final result is a file whose revision tree doesn't
- look like it was ever on any branch but the Main Branch until the
- above "tag -F -b" command was executed. CVS and RCS have no way
- of saving the history of the actions you have just performed.
-
-
- 4C.9 How do I know what branch I'm (working) on?
-
- Type:
- cvs status
-
- and look at the "Sticky Tag" field for each file. If:
-
- 1. The *same* tag is on *every* file in your working tree, *and*
- 2. That tag matches the contents of the ./CVS/Tag file, *and*
- 3. That tag is a branch tag,
-
- then you know what branch you are working on. You can get sticky
- Tag information directly from the ./CVS/Entries file instead of
- "cvs status".
-
- If all the sticky Tags don't agree, then your directory is
- temporarily inconsistent. This is a feature allowing you to make
- changes (or perform merges) to individual files on multiple
- branches without checking out the whole directory.
-
- The sticky Tag on each file in the ./CVS/Entries file (as
- displayed by the "status" command) indicates what branch the
- working file is on. New files are added to the Tag stored
- in ./CVS/Tag.
-
- To force your entire working directory onto the same branch, type:
-
- cvs update -r <branch_tag>
-
-
- 4C.10 Do I really have to know the name of the branch I'm working on?
-
- If a developer can't be relied on to know what branch of
- development to work on, then either the developer's manager
- isn't planning branches properly or the developer has serious
- problems.
-
- I have found that one of the hardest concepts to get across to
- developers (and some managers) is that "a branch in development"
- (as opposed to the use of RCS branches to support some other
- scheme) is a heavyweight act. Every time you create a real branch
- in development, you must spawn a set of managerial procedures and
- a schedule by which you plan to merge each branch into each other
- branch. Unless you plan to keep it simple and collapse (by
- merging and forgetting) branches quickly, they are not to be
- created lightly.
-
- In other words, if you don't regularly attend group meetings in
- which the branch to be worked on is a major topic of discussion,
- then the group is not managing branches properly.
-
- We created a couple major branches a few months ago and even the
- customer service people refer to the "XYZ branch" as a shorthand
- for "continuing development on the XYZ project".
-
-
- 4C.11 How do I refer to the revision where I branched so I can see
- what changed since the Branch Point on another branch?
-
- Given the current <branch_tag> format, there is no direct way to
- refer to the branch point, which is more useful in many ways
- than referring to the branch, which always refers to the latest
- revision on the branch.
-
- When CVS adds a branch tag, it attaches an RCS symbol to a
- non-existent revision number containing the revision number of the
- branch point as a prefix. (See Section 3O, on the "tag" command.)
- RCS can't use the CVS magic branch tag and many of the CVS
- commands can't refer to it.
-
- To be certain of your ability to refer to a branch point, you must
- create a "branch point" tag at the same time as the Branch tag.
- See 4C.3.
-
-
- 4C.12 Why didn't the command "cvs admin -bBRANCH1 *" create a branch?
-
- Because your command creates an RCS branch, not a CVS branch. See
- the above discussion on branches. RCS branches are used to
- support CVS branches, but they are not the same. You can't act as
- if you have direct control over the RCS files.
-
- The "admin" command was placed there as a convenience to allow
- you to execute raw "rcs" commands on the Repository, taking
- advantage of CVS's ability to find the files in the Repository.
-
- But you have to remember that you are using RCS commands on a
- CVS Repository, which is not generally safe unless you know
- exactly what CVS depends on.
-
- For one thing, CVS insists on control of the default branch. It
- is set either to the Main branch or the Vendor branch depending
- on whether you have changed the Vendor's code. If you change
- the default branch, you are monkeying with the internals and
- you will get unexpected results.
-
- To set your "default CVS branch" to BRANCH1, you must use
- "checkout" or "update" with the "-r BRANCH1" option. Then you
- have changed CVS's idea of your "default branch", which has
- little to do with RCS's default branch.
-
-
- 4C.13 Is it possible to set the "default CVS branch" for everyone?
-
- No. It doesn't work that way.
-
- When using CVS, all administrative information (such as what
- branch you checked out) is stored in CVS sub-directories, local to
- the user. There is no global state, other than the description
- and logging files in the $CVSROOT/CVSROOT directory.
-
- You tell "checkout" or "update" what branch you want to check out
- via the "-r <tag>" option. The default is CVS's "Main Branch".
-
- I don't see a problem in *designing* a new way to indicate what
- branch you get by default, instead of the main one, but that's not
- how it currently works.
-
-
- 4C.14 How do I perform a large merge?
-
- Large merges require a bit more planning to be able to track
- what has happened in the inevitable cases where something goes
- wrong. No tool can force a "merge" to make perfect sense.
-
- Though you can handle the details in many different ways, the two
- ends of the spectrum of merge techniques are: gonzo and paranoid.
-
- A. The gonzo method assumes that you know everything about your
- sources so that recovery from failures is "just a matter of
- typing." You created the branch this way:
-
- cvs checkout <module>
- cd <module>
- cvs tag -b <branch_tag>
- cvs update -r <branch_tag>
- >>> Edit away.
- cvs commit <<== Onto branch
-
- Now you want to merge your branch back into the Main branch,
- you are certain you can make it work, or at least detect all
- the failures, so you dive in and hack away: (For simplicity, we
- will assume you are collapsing (i.e. merging and forgetting) a
- side-branch into the Main branch from your single working
- directory.)
-
- cvs update -A
- cvs update -j <branch_tag>
- >>> Edit the 'C' files and remove the overlaps.
- >>> Edit some more to make it all compile and work.
- cvs commit
-
- Looks simple. For more details on the output from the
- "update -j" command, see 3P.2 and 4C.6.
-
- Note: You could also checkout a whole new working directory and
- perform the merge at the same time by replacing the two
- update commands with these two commands:
-
- cvs checkout -j <branch_tag> <module>
- cd <module>
-
-
- B. The paranoid way is more difficult, but it can catch all sorts
- of problems. You created the branch this way:
-
- cvs checkout <module>
- cd <module>
- cvs tag <branch_point_tag>
- cvs tag -b <branch_tag>
- cvs update -r <branch_tag>
- >>> Edit away.
- cvs commit <<== Onto branch
-
- The extra tag command places a non-branch tag on the Branch
- Point, an act that makes it easier to do "diffs" later. Now we
- decide to perform the merge:
-
- cvs tag <latest_on_branch_tag>
- cvs update -A
- *1* cvs diff -r <branch_point_tag> -r <latest_on_branch_tag>
- >>> *1* shows all the changes on the branch.
- *2* cvs diff -r <branch_point_tag> -r HEAD
- >>> *2* shows the changes on the trunk since branching.
- cvs tag <premerge_tag>
- cvs update -j <branch_tag>
- >>> Edit the 'C' files and remove the overlaps.
- *3* cvs diff
- >>> Verify that *3* matches *1*, except for line numbers.
- cvs commit
- cvs tag <just_merge_changes_tag>
- >>> Edit some more to make it all compile and work.
- cvs commit
- cvs tag <after_merge_cleanup_tag>
-
-
- The reason *3* and *1* match so closely is that they are the
- differences between two pairs of starting points and ending points
- after the same data was inserted. If they are significantly
- different, you will want to figure out why.
-
- NOTE: You will have to tell everyone to stay the hell out of the
- Repository while you do this. If they commit something while you
- are in the middle of a merge, your job will be much more
- difficult. If they "update" at the wrong time, their work will
- be randomized until you finish. It's better to call a halt.
-
- See 3H.13 for some more information about dealing with merges
- after import. The last part of the procedure is applicable to any
- large merge.
-
-
- 4C.15 Is a Vendor merge any different from a branch merge?
-
- No. In most ways, a Vendor branch is exactly the same as any
- other branch. In a Vendor merge, the data is append to the branch
- by the "import" command, rather than by hand-editing, but the
- merge process is the same.
-
- See the "import" command in section 3H.
-
-
- 4C.16 How do I go back to a previous version of the code on a branch?
-
- You can avoid digging into RCS revision numbers (executing "update
- -r <rev>" on each file) by trying one of these:
-
- 1. Use non-branch tags as you normally would. Non-branch tags
- attach to specific revisions, so a "tag <tag>" command would
- mark the revisions you have in your working directory, which
- are on your branch. If you need to retrieve them, use "update
- -r <non-branch-tag>"
-
- Doing this overrides the sticky <branch_tag> attached to your
- working directory with a non-branch tag, which means you won't
- be able to commit until you again move forward to the end of
- the branch with "update -r <branch_tag>".
-
- 2. Use the "update -r <branch_tag>:<date>" trick.
-
- This is almost like using the '-D' option, but it looks for
- revisions extant on <date> only along the given branch.
-
- As in #1, you can't commit to this kind of working area,
- because it has a sticky date referring to revisions in the
- middle of a branch.
-
-
- 3. You can branch a branch.
-
- If you add a branch tag to file in a working directory that was
- checked out on a branch, you will branch the branch. This
- works just fine, though you'll have to play some games to merge
- everything back together again. You'll also create 6-part
- revision numbers. (They'll be 8-part revision numbers if you
- branch a branch that started out with some unmodified files on
- the Vendor branch. Think about it. How does revision
- 1.2.4.2.4.2.2.1 grab you?)
-
-
- 4C.17 Once I've found the files I want, how do I start changing them?
- I keep getting warnings about sticky tags.
-
- What you probably did was type "cvs update -r <tag>" where <tag>
- is a non-branch tag. "update" created a sticky tag for a specific
- revision, not a branch. To start working right there, you have to
- create a branch to work on.
-
- You have two choices.
-
- A. You can do it in place and keep working:
-
- cvs tag -b <branch_tag> <<== To tag the current files.
- cvs update -r <branch_tab> <<== To move onto the branch.
-
- B. You can do it "externally" and create a new working directory:
-
- cvs rtag -b -r <tag> <branch_tag> <module>
- cvs checkout -r <branch_tag> <module>
-
- <module> can be a relative path within the Repository.
-
- <tag> in the above is the non-branch tag you placed earlier
- that caused the error in your question. Be warned that
- if <tag> is not set on all the files (or all the right
- revisions) you won't get exactly what you wanted.
-
-
- 4C.18 Why do I get the latest files on the branch when I tried to
- "update -r <tag>"?
-
- If "update -r <tag>" always retrieves the latest files on a
- branch, then <tag> is really a <branch_tag>. A branch tag is
- supposed to be used to grab a branch to work on. Since you can't
- modify a file in the middle of a branch, checking out a
- <branch_tag> will give you the latest revision on the branch.
-
- If you want to "checkout" a specific collection of revisions, you
- must use a "non-branch" tag. See the first part of 4C.16.
-
-
- 4C.19 How can I avoid a merge? I just want to move the latest revision
- on my working branch directly onto the trunk.
-
- There is no direct way to do this using CVS, though the technique
- is not difficult using shell commands. Here's one way:
-
- 1. Move your working directory to the Main Branch.
-
- cvs update -A
-
- 2. Use "update -p" to grab the latest revision on the branch and
- write it over your working files. Make sure you don't have an
- modified files -- you will lose them. The following is in
- "csh" syntax. Change the wildcard to grab the files you want
-
- foreach i (Makefile *.cc *.hh)
- cvs update -p -r <branch_tag> $i > $i
- end
-
- 3. Commit all the working files onto the Main Branch.
-
- cvs commit -m 'Moved branch <branch_tag> onto MAIN'
-
- You should experiment with the above before blasting everything.
-
-
- 4C.20 How to I avoid merge collisions in the RCS $\Log$ data?
-
- In short, you can't. The RCS $\Log$ keyword is handled
- differently from all other RCS keywords.
-
- On the info-cvs mailing list, there is a periodic discussion that
- goes something like this:
-
- Question: How do I deal with $\Log$?
- Answer1: You can't do much with it. Here's how it works. . .
- Answer2: I've found a limited way to use it. . .
- Answer3: Get rid of it. $\Log$ is an abomination.
-
- I tend to lean toward answer #3. There are only two sets of
- people who would ever have access to logs stored within sources
- files, developers and source customers.
-
- For developers:
-
- 1. Log entries within sources files are notoriously incomplete,
- rushed, poorly phrased and in many cases incorrect, making them
- useless for debugging or file maintenance. I remember a maxim
- from "Software Tools" (I believe): "Read the code, not the
- comments." No managerial order or plan for programmer
- discipline will affect this in the real world.
-
- 2. Log entries are usually in an unreadable mixture of styles.
- Many log entries are just plain meaningless. Some are foolish.
- Some are even insulting. Examples:
-
- "Corrected spelling of misspelling."
- "Bug fix."
- "Reversed stupid change in previous revisions."
- "If Joe could do his job, this would already have worked."
-
- 3. Log entries are not managed well by the tools. Any merge can
- cause conflicts in the $\Log$ data. Branch merges produce
- incomplete logs. They can be edited into chaos and they are
- not regenerated. They waste space duplicating information
- available to the developer with a single command.
-
- 4. Even if correct when originally entered, as changes are made to
- the file, log entries become false over time. Humans are not
- good at reading down through a list and remembering only the
- last change affecting something. Over time *most* of the log
- is wrong.
-
- 5. Even if still correct, the log data is almost useless to
- developers without the code diffs. If you can get code diffs,
- you can display the log.
-
-
- For source customers the problem is even worse. The last thing
- you want to show customers is a hodge-podge of tiny comments about
- large changes followed by a series of emergency fixes before
- delivery. If you distribute sources, then you should provide
- documentation, or changelogs reviewed by people who won't let
- comments like "Fixed for stupid customer." out the door.
-
- Conclusion: Though some people would prefer to see in this FAQ
- techniques for making the $\Log$ entries the best they can be, I
- believe them to be a lost cause. My suggestion is to hunt down,
- root out and destroy all occurrences of $\Log$ and the unusable
- data attached to it wherever you may find it.
-
-
- 4C.21 Why should I trust automatic merges?
-
- Some developers have the feeling that three-way merging doesn't
- work. They fear and distrust the way the "update" command
- automatically merges committed changes from the Repository into
- the working file.
-
- Experience has shown that most merges are utterly painless and
- most of the rest are easily resolved. The few conflicts that
- cause headaches are nearly all due to poor communication between
- developers, a problem no source control system can obviate.
-
- Some developers were troubled in the past by flaky Unix software.
- I can't say that everything is perfect, but the tools CVS depends
- on (RCS and diff, mainly) are fairly solid nowadays. They work.
-
- Since it does seem to work for most of us, the algorithm is
- unlikely to change soon. Why not test it on a couple trouble
- spots and if it works for you, use it for a while? Then you can
- make an informed decision.
-
-
- 4C.22 How does CVS decide if it can safely perform a merge?
-
- CVS can merge any text file, possibly discovering a conflict and
- leaving overlaps for you to edit. Editing the conflict markers
- out of the file is a moment's work, but resolving the conflict
- could take an arbitrary amount of time. CVS works to determine if
- it *should* merge, not if it *can*.
-
- See 2B.6 for how the merge proceeds.
-
-
- 4C.23 After resolving merge conflicts in a file, what if I want to keep
- my previous version, and not take any of the branch changes?
-
- If you want to retain your previous version, a version on the
- MAIN branch greater than 1.1 (one you committed there), just throw
- the merged file away and "cvs update" the file.
-
- You don't need to commit something to remember it. The tags you
- place before and after the merge should give all the handles you
- need to find various versions. You don't have to create a new
- version of the file.
-
- If you want to retain the previous Vendor revision, you can grab a
- copy of it using "cvs update -p" and commit it or use the
- technique described in 3B.3 to revert back to the Vendor branch.
-
-
-
-----------------
--- Section 4D -- Tricks of the Trade
-----------------
-
-This section covers topics ranging from simple ideas that occur to every
-CVS user to time-saving procedures I consider difficult to understand.
-
-Some are therefore dangerous. Avoid anything you don't fully understand.
-
-
- **** Questions:
-
- 4D.1 How can you even check in binary files, let alone allow CVS to
- do its auto-merge trick on them?
- 4D.2 Can I edit the RCS (",v") files in the Repository?
- 4D.3 Can I edit the ./CVS/{Entries,Repository,Tag} files?
- 4D.4 Someone executed "admin -o" and removed revisions to which
- tags/symbols were attached. How do I fix them?
- 4D.5 How do I move or rename a magic branch tag?
- 4D.6 Can I use RCS locally to record my changes without making them
- globally visible by committing them?
- 4D.7 How can I allow access to the Repository by both CVS and RCS?
- 4D.8 I "updated" a file my friend, "bubba", committed yesterday.
- Why doesn't the file now have a modified date of yesterday?
- 4D.9 While in the middle of a large "commit", how do I run other
- commands, like "diff" or "stat" without seeing lock errors?
- 4D.10 Where did the ./CVS/Entries.Static file come from? What is it for?
- 4D.11 Why did I get the wrong Repository in the loginfo message?
- 4D.12 How do I run CVS setuid so I can only allow access through the
- CVS program itself?
- 4D.13 How about using groups and setgid() then?
- 4D.14 How do I use the "commitinfo" file?
- 4D.15 How do I use the "loginfo" files?
- 4D.16 How can I keep people with restrictive umask values from blocking
- access to the Repository?
- 4D.17 Why do timestamps sometimes get set to the date of the revision,
- sometimes not? The inconsistency causes unnecessary recompiles.
-
-
- **** Answers:
-
- 4D.1 How can you even check in binary files, let alone allow CVS to
- do its auto-merge trick on them?
-
- If you configure RCS and CVS to use the GNU version of diff with
- the '-a' option, CVS and RCS will handle binary files. See
- section 4A for configuration info.
-
- You may also need to apply the '-ko' flag to the files to avoid
- expanding RCS keywords, which can be done via:
-
- cvs admin -ko filename
-
-
- The only real problem occurs when "cvs update" attempts to merge
- binary revisions committed elsewhere into a modified working file.
- This can be a particular problem if you are trying to use CVS on
- Frame or Interleaf (document processing systems) that produce
- non-text output.
-
- See 3C.8 for a way to serialize access to binary files.
- See 3A.8 for adding binary files, 3H.4 for importing binary files
- and 3B.4 for some more information about "admin".
-
-
- 4D.2 Can I edit the RCS (",v") files in the Repository?
-
- Yes, but be very careful. The RCS files are not free-form files,
- they have a structure that is easily broken by hand-editing. The
- only time I would suggest doing this is to recover from emergency
- failures that are difficult to deal with using CVS commands,
- including the "admin" command, which can talk directly to RCS.
-
- Though no one actively encourages the editing of RCS files, many
- people have succumbed to the urge to do so when pressed for time.
- The reasons given, usually with evident contrition, include:
-
- - Editing mistakes in, or adding text to, log entries. (If you
- have RCS 5.6 or later, you should use `cvs admin -m'.)
- - Renaming or moving symbolic names. (You should `cvs admin -N'
- instead.)
- - Unlocking a file by changing the "locker" from someone else to
- yourself. (It's safer to use `cvs admin -u -l'.)
- - Making global changes to past history. Example: Eradicating
- former employees names from old documents and Author entries.
- (And someone thought the "history" command was evidence of Big
- Brother! I never realized how much help a wide-open revision
- control system could have provided to The Ministry of Truth.)
-
-
- 4D.3 Can I edit the ./CVS/{Entries,Repository,Tag} files?
-
- Yes, but with CVS 1.3 and later, there is almost no reason to edit
- any of the CVS administrative files.
-
- If you move pieces of your Repository around it can be faster to
- edit all the ./CVS/Repository files rather than checking out a
- large tree. But that is nearly the only reason to do so.
-
-
- 4D.4 Someone executed "admin -o" and removed revisions to which
- tags/symbols were attached. How do I fix them?
-
- It depends on what you mean by "fix". I can think of three ways
- to fix your predicament:
-
-
- 1. Remove the tags.
-
- Assuming you really wanted to get rid of the revision and its
- associated tags, you can remove them with the "admin" command.
- The "tag -d" command will only remove tags attached to existing
- revisions. You can remove a tag, even if it is attached to a
- non-existent revision, by typing:
-
- cvs admin -N<tag> <file>
-
- 2. Retrieve the outdated revision.
-
- You should first look in your backup system for recent versions
- of the file. If you can't use them, you can carefully extract
- each revision that followed the earliest outdated revision
- using RCS (or "cvs admin") commands and reconstruct the file
- with all the right revisions, branches and tags. This is a lot
- of work.
-
- You *can't* insert a revision into the current RCS file.
-
- 3. Move the Tags to another revision in each file.
-
- If you want to move the tags to another valid revision, you
- have two choices, both of which require that you find all the
- revision numbers of the files you want to "tag" and execute the
- following command sequences on each <file>.
-
- a. Use "update" to grab the revision you want, then
- execute a normal "tag" command to Tag that revision:
-
- cvs update -r <rev> <file>
- cvs tag <tag> <file>
-
- b. Use "admin" to set the tag to a specific revision:
-
- cvs admin -N<tag>:<rev> <file>
-
-
- 4D.5 How do I move or rename a magic branch tag?
-
- (To rename a non-branch <tag> see 3O.9.)
-
- Before reading this, read 3M.3 and 3M.4 and understand exactly
- how tag and rtag use '-r' and why it won't do the right job here.
-
- A. First, I have to explain exactly what a magic branch tag is.
-
- A magic <branch_tag> is an artificial tag attached to a
- non-existent revision on a non-existent branch number zero. It
- looks like this:
-
- TAG1:<X>.0.Y
-
- <X> is the "branch point revision", a normal revision with an
- odd number of '.'s in it. (e.g. 1.5, 1.3.1.6, etc)
-
- Y is an even number (e.g. 2, 4, 6, etc.) All CVS branches,
- other than the Vendor branch, are even numbered.
-
- TAG1 is considered by CVS to be attached to revision <X>. The
- first "update -r TAG1 <file>" after applying TAG1 will produce
- a copy of revision <X> with a sticky tag of TAG1. The first
- "commit" to that file will cause CVS to construct an RCS branch
- named <X>.Y and check in revision <X>.Y.1 on the new branch.
-
- Note: TAG1 is *not* considered to be attached to <X> by RCS,
- which explains why you can't refer directly to the branch point
- revision for some CVS commands.
-
-
- B. Moving a magic <branch_tag> is the act of reapplying the same
- tag to different revisions in the file:
-
- TAG1:<X>.0.Y
- to
- TAG1:<X>.0.Z or TAG1:<A>.0.B
-
- You can move a magic branch tag to the revisions of your choice
- by using "update" to find the revisions you want to tag and
- reapplying the tag to all the files with the '-F' option to
- force it to move the existing <branch_tag>.
-
- cvs update -r <tag/rev> (or '-A' for the Main Branch)
- cvs tag -F -b <branch_tag>
-
- If the earlier location of TAG1 refers to a physical branch
- within any RCS file, moving it will make the existing branch in
- the file seem to disappear from CVS's view. This is not a good
- idea unless you really want to forget the existence of those
- RCS branches.
-
- If the "update" above retrieves the original branch point
- revision (<X>), the "tag" command above will create the tag:
-
- TAG1:<X>.0.Z
-
- Where Z is 2 greater than the highest magic branch already on
- revision <X>. The TAG1 branch will still have the same branch
- point (i.e. revision <X>), but the first commit to the new TAG1
- branch will create a different RCS branch number (<X>.Z instead
- of <X>.Y).
-
-
- C. Renaming a magic <branch_tag> is the act of changing
-
- TAG1:<X>.0.Y
- to
- TAG2:<X>.0.Y
-
- There is no harm in changing a tag name as long as you forget
- that TAG1 ever existed and you clean up any working directories
- with sticky TAG1 tags on them by using "update -A", "update -r
- <other_tag>" or by removing the working directories.
-
- On the other hand, actually changing the tag is not easy.
-
- See 3M.3 for why the seemingly obvious solution won't work:
-
- cvs tag -b -r <old_branch_tag> <new_branch_tag>
-
- The only direct way to rename a magic tag is to use the "admin"
- command on each file: (You might want to use '-n'. Read "man
- rcs" and look at the '-n' and '-N' options.)
-
- cvs admin -N<new_branch_tag>:<old_branch_tag> .
- cvs tag -d <old_branch_tag>
-
- But you have to be careful because "admin" is different from
- other CVS commands:
-
- 1. "admin" can be used recursively, but only by specifying
- directory names in its argument list (e.g. '.'),
-
- 2. Where "rtag -r <old_branch_tag>" would interpret
- <old_branch_tag> as a magic CVS branch tag, "admin" is a
- direct interface to RCS which sees a magic branch tag as
- a simple (though non-existent) RCS revision number.
-
- This is good for us in this particular case, but different
- from normal CVS.
-
- 3. "admin" also skips the Attic and produces different kinds
- of errors than CVS usually does. (Because they are coming
- directly from RCS.)
-
-
- The other way to rename a magic <branch_tag> is to edit the
- Repository files with a script of some kind. I've done it in
- the past, but I'll leave it as an exercise for the reader.
-
-
- 4D.6 Can I use RCS locally to record my changes without making them
- globally visible by committing them?
-
- You can, but it will probably confuse CVS to have ",v" files in
- your working directory. And you will lose all your log entries
- when you finally commit it.
-
- Your best bet is to create your own CVS branch and work there.
- You can commit as many revisions as you want, then merge it back
- into the main line (or parent branch) when you are finished.
-
-
- 4D.7 How can I allow access to the Repository by both CVS and RCS?
-
- The first step is to try not to. If some people are using CVS,
- there is no reason for everyone not to. It is not hard to learn
- the basics and CVS makes certain operations *easier* than a series
- of RCS commands. Personal preference in what software tools can
- be applied to a shared Repository has to take second place to
- system integration needs. If you disagree, try writing some Lisp
- code for inclusion in your Unix kernel and see what kind of
- reception you get.
-
- If you really must allow routine RCS access to the CVS Repository,
- you can link an RCS sub-directory into a piece of the Repository:
-
- ln -s /Repository/some/directory/I/want RCS
-
- and RCS will work just fine.
-
-
- Those who are using RCS will have to keep the following in mind:
-
- 1. If a file was originally added to the Repository by "import"
- and has not been changed using CVS, the *RCS* default branch
- will remain attached to the Vendor branch, causing revisions
- checked-in by "ci" to wind up on the Vendor branch, instead of
- the main branch. Only CVS moves the RCS default branch on
- first commit.
-
- The way around this is to checkin (using "ci") all the files
- first and move them into the Repository. That way they won't
- have Vendor branches. Then RCS will work OK.
-
- 2. It is possible to use "rcs" and "ci" to make the files unusable
- by CVS. The same is true of the CVS "admin" command.
-
- 3. Normal RCS practice locks a file on checkout with "co -l". In
- such an environment, RCS users should plan to keep survival
- gear and food for at least 30 days near their desks. When
- faced with bizarre and unexpected permission errors, howling
- mobs of slavering CVS users will run the RCS users out of town
- with pitchforks and machetes.
-
- See 3C.8 for a way to avoid machetes aroused by lock collisions.
-
- 4. Though files checked in by RCS users will correctly cause
- "up-to-date" failures during CVS "commits" and they will be
- auto-merged into CVS working directories during "update", the
- opposite won't happen.
-
- RCS users will get no warning and will not be required to merge
- older work into their code. They can easily checkin an old
- file on top of a new revision added by CVS, discarding work
- committed earlier by CVS users.
-
- See the howling mob scenario described above.
-
-
- RCS is great. I have used it for years. But I wouldn't mix it
- this way. In a two-camp society, you are asking for real trouble,
- both in technical hassles to clean up and in political hassles to
- soothe. Branch merges will also be a major problem.
-
-
- 4D.8 I "updated" a file my friend, "bubba", committed yesterday.
- Why doesn't the file now have a modified date of yesterday?
-
- CVS restores dates from the RCS files only on first "checkout".
- After that, it is more important to maintain a timestamp relative
- to the other files in the working directory.
-
- Example: You committed a source file at 5PM. Bubba updated his
- copy of the file, grabbing your changes, then changed and
- committed a new revision of the file at 6PM. At 7PM, you compile
- your file. Then you execute "update". If CVS sets the date to
- the one in the RCS file, the file would be given a timestamp of
- 6PM and your Makefile wouldn't rebuild anything that depended on
- it. Bad news.
-
- Note that the same logic applies to retrieving a revision out of
- the Repository to replace a deleted file. If CVS changes your
- file in an existing working directory, whether it was because a
- new revision was committed by someone else or because you deleted
- your working file, the timestamp on the retrieved working file
- *must* be set to the current time.
-
- When you first retrieve a file, there is no reason to expect any
- particular timestamp on the file within your working area. But
- later, when dependency checking is performed during a build, it is
- more important for the timestamps on the local files to be
- consistent with each other than than it is for working files to
- match the timestamps on the files in the Repository.
- See 4D.17 for some more about timestamps.
-
-
- 4D.9 While in the middle of a large "commit", how do I run other
- commands, like "diff" or "stat" without seeing lock errors?
-
- Type:
- cvs -n <command>
-
-
- The '-n' option to the main cvs command turns off lock checking, a
- reasonable act for read-only commands given the promise offered by
- '-n' not to alter anything. The "diff", "log" and "stat" commands
- provide the same information (for files that are not being
- committed) when used with and without the '-n' option.
-
- Warning: Ignoring locks can produce inconsistent information
- across a collection of files if you are looking at the revisions
- affected by an active commit. Be careful when creating "patches"
- from the output of "cvs -n diff". If you are looking only at your
- working files, tagged revisions, and BASE revisions (revisions
- whose numbers are read from your ./CVS/Entries files), you should
- get consistent results. Of course, if you catch a single file in
- the middle of RCS activity, you might get some strange errors.
-
- Note that the suggested command is "cvs -n <command>". The
- visually similar command "cvs <command> -n" has no relation to the
- suggested usage and has an entirely different meaning for each
- command.
-
- "cvs -n update" also works in the middle of a commit, providing
- slightly different information from a plain "cvs update". But, of
- course, it also avoids modifying anything.
-
- You could also use the RCS functions, "rlog" and "rcsdiff" to
- display some of the information by referring directly to the
- Repository files.
-
- You need RCS version 5 or later for the commands described above
- to work reliably.
-
-
- 4D.10 Where did the ./CVS/Entries.Static file come from? What is it for?
-
- Each CVS working directory contains a ./CVS/Entries file listing
- the files managed by CVS in that working directory. Normally, if
- the "update" command finds a file in the Repository that is not in
- the ./CVS/Entries file, "update" copies the appropriate revision
- of the "new" file out of the Repository and adds the filename to
- the Entries file. This happens for files:
-
- 1. Added to the Repository from another working directory.
- 2. Dragged out of the Attic when switching branches with
- "update -A" or "update -r".
- 3. Whose names were deleted from the ./CVS/Entries file.
-
- If the ./CVS/Entries.Static file exists, CVS will only bring out
- revisions of files that are contained in either ./CVS/Entries or
- ./CVS/Entries.Static. If a Repository file is found in *neither*
- file, it is ignored.
-
- The ./CVS/Entries.Static file is created when you check out an
- individual file or a module that creates working directories that
- don't contain all files in the corresponding Repository directory.
- In those cases, without an ./CVS/Entries.Static file, a simple
- "update" would bring more files out of the Repository than the
- original "checkout" wanted.
-
- The ./CVS/Entries.Static file can be removed by hand. It is
- automatically removed if you run "update -d" to create new
- directories (even if no new directories are created).
- (Internally, since "checkout" turns on the '-d' flag and calls the
- "update" routine, a "checkout" of a module or directory that
- writes into an existing directory will also remove the
- ./CVS/Entries.Static file.)
-
-
- 4D.11 Why did I get the wrong Repository in the loginfo message?
-
- You probably:
-
- 1. Use multiple Repositories.
-
- 2. Configured CVS to use absolute pathnames in the
- ./CVS/Repository file.
-
- 3. Configured CVS not to use the ./CVS/Root file.
-
- 4. Typed the "commit" command in one Repository with your
- $CVSROOT pointing at another.
-
- "commit" and all other CVS commands will heed an absolute pathname
- in the ./CVS/Repository file (or in the "-d CVSrootdir" override),
- but the log function doesn't take arguments -- it just looks at
- $CVSROOT.
-
- If you avoid even one of the four steps above, you won't see this
- problem. If you configure ./CVS/Root, you won't be allowed to
- execute the program causing the error.
-
-
- 4D.12 How do I run CVS setuid so I can only allow access through the
- CVS program itself?
-
- Setuid to root is not a great idea. Any program that modifies
- files and is used by a widely distributed group of users is not a
- good candidate for a setuid program. (The worst suggestion I've
- ever heard was to make *Emacs* setuid to root.)
-
- Root access on Unix is too powerful. Also, it might not work in
- some (secure?) environments.
-
- Running it setuid to some user other than root might work, if you
- add this line to main.c near the beginning:
-
- setuid(geteuid());
-
- Otherwise it uses *your* access rights, rather than the effective
- uid's.
-
- Also, you have to invent a fake user whose name will show up in
- various places. But many sites, especially those who might want a
- setuid CVS for "security", want personal accountability -- no
- generic accounts. I don't know whether accountability outweighs
- file security.
-
- And finally, unless you take action to limit the "admin"
- command, you are leaving yourself unprotected anyway.
-
-
- 4D.13 How about using groups and setgid() then?
-
- Here is a way to run CVS setgid in some environments:
-
- 0. Stick this near the front of the main() in main.c:
-
- setgid(getegid());
-
- This will allow "access" to work on systems where it
- only works on the real gid.
-
- 1. Create a group named "cvsg". (This example uses "cvsg". You
- can name it as you wish.)
-
- 2. Put *no* users in the "cvsg" group. You can put Repository
- administrators in this group if you want to.
-
- 3. Set the cvs executable to setgid (not setuid):
-
- cd /usr/local/bin; chown root.cvsg cvs; chmod 2755 cvs
-
- 4. Make sure every file in the Repository is in group "cvsg":
-
- chown -R root.cvsg $CVSROOT
-
- 5. Change all directory permissions to 770. This allows all
- access to the files by the "cvsg" group (which has no members!)
- and no access at all to anyone else.
-
- find $CVSROOT -type d -exec chmod 2770 {} \;
-
- On some systems you might have to type:
-
- find $CVSROOT -type d -exec chmod u=rwx,g=rwx,o=,g+s {} \;
-
- This should allow only the cvs program (or other "setgid to group
- cvsg") programs to write into the area, but no one else. Yes the
- user winds up owning the file, but s/he can't find it again later
- since s/he can't traverse the tree. (If you enable the world
- execute bit (mode 2771) on directories, users can traverse the
- tree and the user who last wrote the file can still write to it.)
-
- If you want to allow read access, check out an entire tree
- somewhere. You have to do this anyway to build it.
-
- Note: If you are using a stupid file system that can't inherit
- file groups from the parent directory (even with the "setgid"
- (Octal 2000) bit set), you might have to modify CVS (or RCS) to
- reset the group every time you create a new file. I have not
- tested this.
-
- The setgid() method shares with the setuid() method the problem of
- keeping "admin" from breaking things.
-
-
- 4D.14 How do I use the "commitinfo" file?
-
- Go read 4B.2 first.
-
- The "commitinfo" file allows you to execute "sanity check"
- functions before allowing a commit. If any function called from
- within the commitinfo file exits with a non-zero status, the
- commit is denied.
-
- To fill out a "commitinfo" file, ask yourself (and those sharing
- your Repository) these questions:
-
- - Is there anything you want to check or change before someone is
- allowed to commit a file? If not, forget commitinfo.
-
- If you want to serialize binary files, you might consider
- something like the rcslock.pl program in the contrib directory
- of the CVS sources.
-
- - Do you want to execute the same exact thing before committing to
- every file in the Repository? (This is useful if you want to
- program the restrictions yourself.) If so, set up a single line
- in the commitinfo:
-
- DEFAULT /absolute/path/to/program
-
- CVS executes the program once for each directory that "commit"
- traverses, passing as arguments the directory and the files to
- be committed within that directory.
-
- Write your program accordingly. Some examples exist in the
- contrib directory.
-
- - Do you want a different kind of sanity check performed for
- different directories? If so, you'll have to decide what to do
- for all directories and enter lines like this:
-
- regexp1 /absolute/path/to/program-for-regexp1
- regexp2 /absolute/path/to/program-for-regexp2
- DEFAULT /absolute/path/to/program-for-all-else
-
-
- - Is there anything you want to happen before *all* commits, in
- addition to other pattern matches? If so, include a line like
- this:
-
- ALL /absolute/path/to/program
-
- It is executed independently of all the above. And it's
- repeatable -- you can have as many ALL lines as you like.
-
-
- 4D.15 How do I use the "loginfo" files?
-
- See 4B.2 and the "commitinfo" question above.
-
- The "loginfo" file has the same format as the "commitinfo"
- file, but its function is different. Where the "commitinfo"
- information is used before a commit, the "loginfo" file is used
- after a commit.
-
- All the commands in the "loginfo" file should read data from
- standard input, then either append it to a file or send a message
- to a mailing list. If you want to make it simple, you can put
- shell (the shell used by "popen(3)") command lines directly in the
- "loginfo" (or "commitinfo") file. These seem to work:
-
- ^special /usr/ucb/Mail -s %s special-mailing-list
- ^other /usr/ucb/Mail -s %s other-mailing-list
- DEFAULT (echo '===='; echo %s; cat) > /path/name/to/log/file
-
-
- 4D.16 How can I keep people with restrictive umask values from blocking
- access to the Repository?
-
- If a user creates a new file with restricted permissions
- (e.g. 0600), and commits it, the Repository will have a file in it
- that is unreadable by everyone. The 0600 example would be
- unreadable by *anyone* but root and the user who created it.
-
- There are 3 solutions to this:
-
- 0. Let it happen. This is a valid way to protect things. If
- everyone is working alone, a umask of 077 is OK. If everyone
- is working only in small groups, a umask of 007 is OK.
-
- 1. Train your users not to create such things if you expect to
- share them.
-
- 2. See 4B.5 for a small script that will reset the umask.
-
- I personally don't like the idea of a program automatically
- *loosening* security. It would be better for you all to talk
- about the issue and decide how to work together.
-
-
- 4D.17 Why do timestamps sometimes get set to the date of the revision,
- sometimes not? The inconsistency causes unnecessary recompiles.
-
- The "checkout" command normally sets the timestamp of a working
- file to match the timestamp stored on the revision in the
- Repository's RCS file.
-
- The "commit" command retains the timestamp of the file, if the
- act of checking it in didn't change it (by expanding keywords).
-
- The "update" command sets the time to the revision time the first
- time it sees the file. After that, it sets the time of the file
- to the current time. See 4D.8 for a reason why.
-
- Here's a two-line PERL program to set timestamps on files based on
- other timestamps. I've found this program useful. When you are
- certain you don't want a source file to be recompiled, you can set
- its timestamp to the stamp on the object file.
-
- #!/usr/local/bin/perl
- #
- # Set timestamp of args 2nd-Last to that of the first arg.
- #
- ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime)
- = stat(shift);
- utime($atime,$mtime,@ARGV);
-
-
-
-----------------
--- Section 4E -- Internal errors
-----------------
-
- **** Questions:
-
- 4E.1 Explain: "ci error: unexpected EOF in diff output"
- 4E.2 Explain: "RCS file /Repository/module/file.c,v is in use"
- 4E.3 Explain: "co error, line 2: Missing access list"
- 4E.4 Explain: "error: RCS file name `xyz .c' contains white space"
- 4E.5 Explain: cvs checkout: warning: <X> is not (any longer) pertinent
- 4E.6 Why did a Repository file change from <file>,v to ,<file>,?
-
-
- **** Answers:
-
- 4E.1 Explain: "ci error: unexpected EOF in diff output"
-
- RCS versions earlier than 5.5 print the above error when a file
- does not end in a newline character. It can be caused by:
-
- - Editing with Emacs and not using "require-final-newline".
- - Committing a binary file.
- - Filesystem failures (NFS!) that put nulls in your file.
-
- The solution is to upgrade to RCS 5.5 or later. (Of course, this
- won't fix filesystem failures. It will merely allow RCS (and
- therefore CVS) to handle the file without error.)
-
-
- 4E.2 Explain: "RCS file /Repository/module/file.c,v is in use"
-
- This is an RCS error that occurs when its internal lock file has
- been left around by an RCS command interrupted by some sort of
- system crash, disk failure or SIGKILL signal.
-
- Go into the Repository and look for files with names similar to
- "file.c,v", usually starting with ',', '_' or '#'. Make
- sure they are really crash remnants and do not belong to
- transactions in progress -- a recent last-modified timestamp
- is a good indicator of a live transaction. Delete them if they
- are old.
-
-
- 4E.3 Explain: "co error, line 2: Missing access list"
-
- This is an error message from RCS Version 3 when it tries to read
- a file created by a later version of RCS.
-
- HP decided to "standardize" on an ancient version of RCS some time
- ago. You can't use it for CVS. See 4H.6.
-
- Since the error comes from having a later version of RCS than HP
- supports, you probably did install the later version but must have
- recently changed your $PATH or installed the HP package that has
- RCS in it.
-
- You should either reconfigure CVS to use absolute pathnames to the
- proper versions of the RCS programs that CVS uses, or change your
- PATH to look there first. If you haven't installed the latest
- version of RCS, you should upgrade. See 1B.4
-
-
- 4E.4 Explain: "error: RCS file name `xyz .c' contains white space"
-
- RCS 5.6 doesn't allow white space in filenames. Apparently this
- restriction will be removed in RCS 5.7, but CVS may still require
- that filenames have no white space in them.
-
-
- 4E.5 Explain: cvs checkout: warning: <X> is not (any longer) pertinent
-
- This message occurs in three instances:
-
- 1. When there is an entry in the ./CVS/Entries for file <X> and
- there is no RCS file in the Repository to back it up.
-
- If the working file exists, and hasn't changed (determined from
- the timestamp) it is removed.
-
-
- 2. When you try to check out a piece of the Repository with:
-
- cvs checkout some/place/in/repository/tree
-
- and at least the first element of the path (i.e. "some" in the
- above) exists, but some part of the rest of it does not.
-
- The checkout command checks the modules file first for the
- whole path, then for a prefix of the path as a module name. If
- it doesn't find *any* portion of your path in the modules file,
- it says:
-
- cvs checkout: cannot find module `<module/path>' - ignored
-
- If it finds some set of prefix directories, it prints the
- message you see.
-
- In practice this is usually a spelling error.
-
- 3. If the Repository files you are trying to check out or update
- are not readable by you, the same problems can occur.
- Check the permissions on the files involved.
-
-
-
- 4E.6 Why did a Repository file change from <file>,v to ,<file>,?
-
- This is an RCS problem, since the ,<file>, syntax for file names
- is used by RCS and not CVS.
-
- RCS constructs a new <file>,v in a temporary file named ,<file>,
- (which doubles as a lock file) then renames it to <file>,v when it
- is done. The only way this is reliable is if your system's
- version of rename(2) is an atomic, as required by POSIX.
-
- If your system has a non-atomic (and therefore non-POSIX)
- rename(2) system call, RCS runs uses an internal version of this
- algorithm to approximate the atomic rename:
-
- rm <file>,v; ln ,<file>, <file>,v; rm ,<file>,
-
- If the system crashes, or you lose your NFS connection between the
- first "rm", but before the "ln", you can be left only with the
- ,<file>, file. If the crash or network failure occurs between the
- "ln" and the final "rm", you could be left with a pair of linked
- names.
-
- Recovery:
- - If only the ,<file>, exists, rename it to <file>,v.
-
- - If both ,<file>, and <file>,v exist and are linked, remove the
- ,<file>, file.
-
- - If both ,<file>, and <file>,v exist and are separate files, look
- at the dates, "diff" them and make your best guess. This sounds
- like the remnants of two separate events.
-
-
-
-----------------
--- Section 4F -- Related Software
-----------------
-
- **** Questions:
-
- 4F.1 How do I use CVS under Emacs? Is there an Emacs cvs-mode?
- 4F.2 What is GIC (Graphical Interface to CVS)?
- 4F.3 What is CAVEMAN?
-
-
- **** Answers:
-
-This section covers a small handful of subsystems that connect to CVS in
-some way. Most are "front ends" in that they offer a different user
-interface to CVS, but use CVS to perform the normal tasks.
-
- NOTE: The short summaries below combine details culled from public
- announcements of the listed software with the personal opinions of
- the author of the FAQ entry.
-
- 4F.1 How do I use CVS under Emacs? Is there an Emacs cvs-mode?
-
- The pcl-cvs package distributed with CVS is an emacs package that
- helps with the update/commit process. When you are ready to
- update, you use the 'cvs-update' command within emacs. This
- executes "update" and fills a cvs-mode buffer with a line for each
- file that changed. The most helpful features are: descriptive
- words for what happened (i.e. Merged or Conflict rather than 'U'
- or 'C'), single keys bound to diffs and commits, and the ability
- to mark arbitrary groups of files, possibly from different
- directories, for commit as a whole.
-
- All the developers in my group that use emacs find pcl-cvs a much
- friendlier and more helpful way to update/commit than raw cvs.
- One vi user even converted to emacs just to use pcl-cvs.
-
- Contributed by Jeffrey M Loomis
-
- 4F.2 What is GIC (Graphical Interface to CVS)?
-
- GIC provides a graphical user interface to the Concurrent Version
- System (CVS), a powerful revision control system. GIC is
- implemented in the Tcl/Tk programming language and is intended to
- augment the sometimes cumbersome CVS command line interface.
- Novices should find GIC to be much easier to learn than the CVS
- command line.
-
- While GIC is easy to use, it does not contain any documentation on
- CVS. Users of GIC must first learn the concepts of CVS such as
- modules and merging, as well as the simple functions, such as
- committing and updating. The CVS manual page and the README file
- are good places to look.
-
- contact
- David Marwood
- marwood@cpsc.ucalgary.ca
-
- [Extracted from an announcement by David Marwood.]
-
- GIC can be obtained by anonymous ftp to (on the date of this FAQ)
-
- ftp.cpsc.ucalgary.ca:/pub/users/marwood/gic-1.1.tar.Z
- ftp.cpsc.ucalgary.ca:/pub/users/marwood/gic-1.2b1.tar.Z
-
-
- 4F.3 What is CAVEMAN?
-
- CAVEMAN is a front end to CVS written in PERL providing a
- collection of features desired by the site where it was developed.
-
- - The ability to spread a "project" over multiple Repositories.
- - Optional automatic tagging after each commit.
- - Additional locking of files.
- - Extra before and after program hooks.
- - A layer of event logging.
- - All sorts of error messages.
- - Many changes to the semantics of commands.
-
- It is available via anonymous ftp on ftp.llnl.gov [128.115.54.18]
- in gnu/caveman_vX.Y.Z.tar.gz (The numbers X, Y, & Z vary.)
-
- contact
- Kathleen Dyer kdyer@llnl.gov
- (510)423-6803
- (510)423-5112 FAX
-
- [[Does someone want to elaborate?]]
-
-
-----------------
--- Section 4G -- Engineering
-----------------
-
- **** Questions:
-
- 4G.1 Where can I find out about Software Engineering?
- 4G.2 How do I flexibly arrange the modules file to describe my sources?
- 4G.3 Can I have multiple source repositories, one for each project?
- 4G.4 Who should administer the Repository and manage the modules file?
- 4G.5 Isn't disk space a big factor? CVS copies files out of the
- Repository, duplicating everything.
-
-
- **** Answers:
-
-This section is really beyond the scope of CVS, but so many people ask
-questions about how to do Software Configuration and Engineering that I
-thought I'd try to include some information. If you have any
-improvements, references or ideas, speak up.
-
-
-
- 4G.1 Where can I find out about Software Engineering?
-
- A couple different people suggested this book:
-
- Software Configuration Management: Coordination for Team
- Productivity; Wayne A. Babich; Addison Wesley; 1986;
- ISBN 0-201-10161-0
-
-
- A number of others suggested Appendix B of the book "Decline and
- Fall of the American Programmer" by Ed Yourdon, called "The
- Programmer's Bookshelf". It list 87 books you are expected to
- have read. Since they publish many of the books, Prentice-Hall
- distributes this list as "Prentice Hall Professional Technical
- reference PTR-125-AA3.
-
- One interesting item from the Yourdon book: The total number
- of professional computer books sold is less than the number
- of programmers currently in the United States. It wasn't clear
- from the book whether this meant "per year" or not, but it is
- still frightening.
-
-
- 4G.2 How do I flexibly arrange the modules file to describe my sources?
-
- An equivalent question might be, "How do I structure my sources?"
- This can be a difficult question especially in the areas that are
- more political than technical.
-
- Generally you want to think about which pieces of your system need
- to be checked out together, built as one system or tagged as a
- consistent whole. You should certainly create module names that
- correspond to complete, buildable collections that you would tag
- and release as one "product". It is also convenient to create
- module names for small sections of the Repository containing
- files that will all be worked on at the same time by the same
- person or group.
-
- Once you have defined the structure of your work, you can usually
- see how to lay it out in a Repository. After that the modules
- file is easy. You set up module names and aliases to match what
- you need to check out by name. If you like relative directories,
- it is possible, but not recommended, to work completely without a
- modules file. See 1D.11 and 2C.7 for some info about the modules
- file.
-
- Here are a few types of modules. You should experiment to see
- what kind of structure each of these produces. They all have
- different uses.
-
- 1. Connected projects in one group with two separate helper
- directories. The helper directories can contain build tools,
- header files, libraries, or whatever you like.
-
- These are all aliases that checkout relative pathnames. The
- equivalent results could be produced by placing the selected
- relative pathnames on the "cvs checkout" command line.
-
- pr1 -a P1 HELPERS
- pr2 -a P2 HELPERS
- pr3 -a P3 HELPERS
- pr12 -a P1 P2 HELPERS
- pr13 -a P1 P3 HELPERS
- pr23 -a P2 P3 HELPERS
-
- P1 -a group1/proj1
- P2 -a group1/proj2
- P3 -a group1/proj3
- HELPERS -a group1/helper1 group1/helper2 MAKEFILE
- MAKEFILE -a group1/Makefile
-
- Actual Repository directory structure: (from $CVSROOT down)
-
- group1/
- Makefile
- The top level Makefile.
- helper1/
- helper2/
- Helper files and dirs
- proj1/
- Files and dirs
- proj2/
- Files and dirs
- proj3/
- Files and dirs
-
- "checkout group1" produces a duplicate of the above.
- "checkout projX" produces all but "projY" and "projZ".
- "checkout projXY" produces all but "projZ".
-
-
- 2. Here is the exact same set of module names describing the same
- Repository layout using module names (and aliases containing
- module names) instead of merely aliases for relative pathnames.
-
- There is one difference in the result. The name of the top
- level directory in the checked out working tree will match the
- "module" name (e.g. pr1) instead of always being "group1" as it
- was in the first example above.
-
- pr1 group1 proj1 &HELPERS
- pr2 group1 proj2 &HELPERS
- pr3 group1 proj3 &HELPERS
- pr12 group1 proj1 proj2 &HELPERS
- pr13 group1 proj1 proj3 &HELPERS
- pr23 group1 proj2 proj3 &HELPERS
-
- HELPERS -a helper1 helper2 group1-Makefile
- helper1 group1/helper1
- helper2 group1/helper2
- group1-Makefile -d . group1 Makefile
-
- The above line (with the -d in it) says that when the
- module named "group1-Makefile" is checked out, the file
- named Makefile file will be found in a directory named
- $CVSROOT/group1 and will be checked out into a directory
- named '.', which obviously already exists.
-
- The & references say to interpret those pathnames relative
- to the directory where the whole module is stored. For
- the "pr1" module, that directory is "group1", so the
- &HELPERS reference winds up placing Makefile in '.'
- relative to "group1".
-
-
- 3. A short one containing the basic "module" actions:
-
- m1 head/path file1 dir2 file3 dir4 file5
-
- When checked out, a directory named "m1" appears in your
- current directory. Elements named file1, dir2, file3,
- dir4, and file5 appear in it. They were originally taken
- as relative paths from $CVSROOT/head/path.
-
-
- 4. Here's another way to construct a working directory out of
- pieces of the Repository:
-
- projX projX Makefile &projX_inc &projX_src &projX_doc
-
- # The first line selects a single file within projX, plus
- # the contents of three other modules. Those three other
- # modules rename their directories.
-
- projX_inc -d include projX/inc
- projX_src -d source projX/src
- projX_doc -d documentation projX/doc
-
-
- 5. A Unix tree. This is similar to what CVS was developed for and
- the way I have used it for years.
-
- # Top level
- unix unix
- u_bin unix/bin
- u_etc unix/etc
- u_man unix/man
- usr-bin unix/usr.bin
-
- # Subdirs of top level dirs. (tiny subset)
- ls unix/bin/ls
- fsck unix/etc/fsck
- man8 unix/man/man8
-
- # Programs without subdirs. (tiny subset)
- cat unix/bin Makefile cat.c
- uniq unix/usr.bin Makefile uniq.c
-
- # /usr/local/src
- localsrc localsrc
- gnu localsrc/gnu
- public localsrc/public
- X11 localsrc/X11
-
- # GNU and PD tools
- cvs localsrc/gnu/cvs
- emacs localsrc/gnu/emacs
- rcs localsrc/gnu/rcs
- btoa localsrc/public/btoa
- tcsh localsrc/public/tcsh
-
- # X11 related items.
- tvtwm localsrc/X11/contrib/tvtwm
-
- "unix" was checked out and built from the top down, using a set
- of Makefiles that knew about the whole structure. "localsrc"
- was kept checked out in /usr/local/src.
-
- At any time I could run "checkout ls" or "checkout cat" and get
- a simple directory with only that tool in it, plus a subset
- Makefile that knew how to build that tool against the installed
- (or alternate, via environment variables) headers and libraries.
-
- I found it very handy to be able to run "ls" and see the three
- tools I was porting that week.
-
-
- 4G.3 Can I have multiple source repositories, one for each project?
-
- Yes, you can have as many Repositories as you like. But each
- Repository must be managed separately, creating additional work.
-
- Question 4A.1 provides a short description of setting up a
- single Repository. A few additional considerations:
-
- 1. It is a good idea to start by creating a single Repository and
- split it up (or create additional Repositories) only if you
- believe it is really necessary. I would only create a new
- Repository if the data is completely disconnected from the rest
- of the main Repository.
-
- 2. If there is a lot of overlap among the developers working on
- the collections of files you want to place in different
- Repositories, or if there is any connection between those
- collections, I would go out of my way to create a single
- Repository. It is much easier to manage.
-
- 3. Disk space should not be a factor since you can build up a
- Repository using symbolic links and/or remote mounts.
-
- 4. Each Repository is completely distinct. You can't check out
- modules from different Repositories at the same time. A better
- way of looking at it is that if you *can* check out two modules
- or directories with a single "checkout" command (without
- contortions or explicit absolute pathnames), then they are in
- the same Repository.
-
- 5. To "checkout" modules from multiple Repositories, you must use
- the "cvs -d" option on all CVS commands or alter your $CVSROOT
- variable when you change focus to another Repository. If you
- work with multiple Repositories, it is a good idea to configure
- CVS to use absolute pathnames in the ./CVS/Repository file,
- since most commands (other than "checkout") will use that file
- rather than $CVSROOT.
-
- 6. If you configure CVS to use relative pathnames in your
- ./CVS/Repository files, you must always be careful to set your
- $CVSROOT properly or you will get unexpected results.
-
- If you have two modules or directories by the same name at the
- same relative path inside two different Repositories, you are
- asking for disaster. You could unexpectedly update a directory
- with completely unrelated files. This is not a fanciful
- example -- a Repository is occasionally duplicated for release
- purposes in which case *all* the paths in the two Repositories
- are the same.
-
-
- 4G.4 Who should administer the Repository and manage the modules file?
-
- This is a "management style" question. In large or traditional
- groups, the CVS procedures are warped to conform to local
- conventions. In small groups, in groups with strong personalities
- or on new projects the choice of source control procedures can
- help create some of the working environment. Here is a taxonomy
- of environments I have worked in or helped set up:
-
- Situation 1.
-
- A small number of competent developers working on a medium
- size project. We all got along and we all respected each
- other (at least technically). Anyone edited anything.
-
- Modules and Repository admin was mostly left to me. I never
- found a problem in minor changes made by anyone else.
-
-
- Situation 2.
-
- A large number of experienced developers sprinkled with
- wackos. Many of the developers didn't want to deal with any
- kind of source control. They wanted a full-service source
- control system that caused them zero thought.
-
- I learned "big stick" diplomacy here. There was a small
- number of "designated" (by me) people who were allowed to do
- *anything* other than "update" and "commit". Even "checkouts"
- were controlled. This is where I found "history" and
- "release" the most useful.
-
- Situation 3.
-
- A small number of developers who wanted me to "help", but who
- didn't want to deal with anything other than their favorite
- algorithms.
-
- I didn't have the time to baby-sit this group, so I designated
- one of them to be my official contact and made him do it all.
- He felt sullied by the requirement to pay attention to
- anything other than his pet coding projects, but enjoyed the
- "status" of being the only one who could touch the control
- files without my kicking the chair out from under him.
-
- Situation 4.
-
- A huge number of developers of covering the whole spectrum of
- competence and experience split into 20 groups, none of which
- cooperated with the others, working on 57 different projects,
- most of which didn't inter-operate.
-
- Managing it in any coherent way was not my responsibility (and
- beyond my tolerance for chaos). Too many people. So I
- privately designated a person in each group to be the contact
- and kept watch on the Repository activity. When something
- went wrong, I notified the contact for the group and told him
- what was happening and *he* kept his troops in line. They
- were tougher with their own group that I would have been.
-
- Eventually only a few people were willing to touch the control
- files, since they were flamed from all directions if they
- screwed up.
-
- Situation 5.
-
- In a medium group of really *serious*, and seriously
- overworked, people, someone else was designated the "master".
- I convinced the master I knew what I was doing and went on my
- way.
-
- No one else in the world was allowed to touch anything.
-
- Situation 6.
-
- In a large amorphous group of beginners, experts and clowns,
- over whom no one had official control, I was forced to employ
- a group of relative beginners (who became experts rather
- quickly) to police the world. The ultimate in locking the
- barn after the horse was stolen, we kept Chaos from destroying
- us only by use of superior firepower.
-
-
-
- My choice, if allowed, is to let anyone touch anything. I keep
- backups of important items and let people know individually
- whether I want them to touch things or not. If someone on my "no
- touch" list touches and succeeds, they are allowed more slack. If
- they screw up after being warned, their screwup becomes public.
- After a few months, I usually have no trouble keeping the world
- running smoothly, at least from my (and CVS's) perspective.
-
-
- 4G.5 Isn't disk space a big factor? CVS copies files out of the
- Repository, duplicating everything.
-
- Everyone knows that disk space is getting cheaper. How do we
- reconcile this with the equally well-known problem that *all* disk
- is *always* filled up?
-
- In my opinion, the main reason disk space will never be an
- unlimited resource is that it is the major variable in
- organizational time/space tradeoffs. It isn't a problem of waste
- or an aspect of Murphy's law, as some claim it is, but rather a
- direct consequence of good management. Disk space is, and will
- always be, a limited resource.
-
- First, the cost of *deploying* that disk is not dropping as fast
- as the cost of the storage medium. The cost of machines to hold
- the disks and the networks to connect them are dropping more
- slowly than disk media. And the cost of the human time necessary
- to manage the machines, networks, disks, and the developers using
- them, is not dropping at all. The cost of human time continues to
- rise.
-
- If management decides that expensive human time can be saved by
- using all that new disk space to keep the last three releases
- online, then that's what it will be used for. If each release
- takes up a Gigabyte and you support 30 platforms, a simple
- time-saving suggestion has just grabbed 100 Gigabytes of disk
- space. And we've ignored the potential disk storage needed to
- support "better Customer Service", another management refrain.
-
- Even at 30 cents per Megabyte (next year's price), you've just
- used up $30,000 of disk space. And that doesn't count the
- computers, tape drives and humans necessary to maintain and deploy
- all of it. Spending money to save time has its own overhead, too.
-
-
- Binaries are getting bigger. Graphics and data collection devices
- can eat up any amount of disk. There are more tools available,
- more libraries, more raw data than you can ever store. My home
- computer has a Gigabyte of disk on it. It could easily handle 30.
-
- The "economy" of disk storage media will never remove the need to
- manage disk space.
-
-
- So, here's an un-reviewed suggestion originally from Graydon Dodson
- <grdodson@lexmark.com>, which I've altered and edited heavily.
-
- - Keep a directory where the whole tree is checked out. (It might
- be built and tested once in a while to make sure it is worth
- linking to, but that doesn't affect the source control aspect of
- this procedure). Let's call it /master/build.
-
- - Write a tool that creates a tree of directories (like the X11
- "lndir" command) filled with links to the checked out files in
- the /master/build tree.
-
- This tool should also provide real copies of, not symlinks to,
- all the files within the CVS administrative directories.
-
- - You could also provide a way for the tool to take a list of
- whole directories that you will never change, for which it would
- create a single symlink to the directory and not a subtree of
- symlinks to files. Or you could rm -r pieces of the resulting
- working directory yourself and replace it with links.
-
- - If you want to edit a file, you have to grab a real copy and
- keep it until your revision shows up in the /master/build tree.
- I'd create a script to do this: cvsgrab <file>
-
- #!/bin/csh -f
- set f = $1
- if (! -l $f) then
- echo "file $f is not a symlink"
- exit 1
- endif
- rm $f
- set rev = `grep "^/$f/" CVS/Entries | awk -F/ '{print $3}'`
- cvs update -p -r $rev $f > $f
-
- You can't do a plain "cvs update" since that would grab newer
- revisions from the Repository, not the revision you wanted to
- start with. After the file is no longer a symlink, you can work
- normally. You'll have to run "update" before "commit" anyway if
- there are newer revisions.
-
- - Presumably there would also be a tool to traverse the link tree
- and revert it to links if there are no modified files and/or if
- all the real files match the revision of the /master/build tree.
-
- - To avoid confusing CVS when the /master/build revisions are
- updated but your CVS/Entries files is not, CVS would have to
- change to handle symlinks. It currently causes problems with
- this scenario:
-
- 1. ./<file> is a symlink.
- 2. ./CVS/Entries says you are revision 1.2.
- 3. The corresponding CVS/Entries file in /master/build
- says the latest revision is 1.3.
- 4. cvs update <file> shows a 'C' conflict flag.
-
-
-----------------
--- Section 4H -- Other Systems
-----------------
-
- **** Questions:
-
- 4H.1 I use a NeXT. Is there anything I need to know?
- 4H.2 I use OS/2 and/or DOS. Is there anything I need to know?
- 4H.3 I use SCO Unix. Is there anything I need to know?
- 4H.4 I use AIX. Is there anything I need to know?
- 4H.5 I use IRIX. Is there anything I need to know?
- 4H.6 I use an HP system. Is there anything I need to know?
- 4H.7 I use AFS. Is there anything I need to know?
- 4H.8 I use A/UX. Is there anything I need to know?
-
-
- **** Answers:
-
-Out of the box, CVS works on most varieties of Unix. Some near-Unix
-systems have a few problems and non-Unix systems have a *lot* of problems.
-
- 4H.1 I use a NeXT. Is there anything I need to know?
-
- NeXTSTEP 3.0's Interface Builder uses "nib" directories, rather
- than the files used in previous revisions. It removes files it
- doesn't recognize, making it impossible to place such a directory
- under CVS -- the CVS admin directory will be removed.
-
- Some time ago, <Bob_Vadnais@pdh.com> posted a palette named
- CVSPalette that claimed to resolve this problem. It was intended
- to preserve the CVS administrative directories within nib
- documents (directories) that Interface Builder usually removes.
-
- CVSPalette is no longer in its announced place:
-
- ftp.cs.orst.edu:/pub/next/submissions
-
- though I did find two other interesting files on ftp.cs.orst.edu:
-
- /software/NeXT/sources/tools/cvs-next-2_1_1.tar.Z
-
- which is a port of CVS 1.3 (along with RCS and diff) and:
-
- /software/NeXT/sources/programming/cvs.postamble-2.4.gz
-
- which appears to be a set of wrappers for CVS commands that claim
- to allow you to use CVS effectively (and without need for the
- "command line") on a NeXT machine.
-
-
- [[Anyone know the truth about CVS and NeXT?]]
-
-
- 4H.2 I use OS/2 and/or DOS. Is there anything I need to know?
-
- You can share RCS files between Unix and DOS while avoiding the
- MS-DOS file name limits by setting your RCSINIT environment
- variable to '-x/,v'. New RCS files will be created without the
- standard ",v" suffix, though files ending in ",v" will still be
- found if there is no matching file in the same directory without
- the ",v".
-
- Erik van Linstee <linstee@dutecaj.et.tudelft.nl> offers an
- OS/2 and a DOS port of CVS 1.3 in:
-
- ftp.informatik.tu-muenchen.de:/pub/comp/os/os2/gnu/devtools
- or
- ftp.rrzn.uni-hannover.de:/pub/os2-local
-
- The files are named:
-
- cvs13p?[bs].zip
-
- Where the ? stands for the patch level (currently 8) and the b is
- for the binaries, the s for the sources.
-
- There are three binaries. An OS/2 only one (32-bit), a DOS only one
- (16-bit) and an EMX one that runs on both (32-bit).
-
- There are many differences between the Unix and the DOS versions
- of CVS. Read the material that comes with the DOS version before
- using it.
-
- [[Updates?]].
-
-
- 4H.3 I use SCO Unix. Is there anything I need to know?
-
- On SCO/UNIX 3.2 V2.0 POSIX signals don't work. Unfortunately the
- configure program detects POSIXness and configures in the use of
- POSIX signals. Workaround : Edit out the check for POSIXness in
- the configure script. [[You could also remove all occurrences of
- "-DPOSIX=1" from the Makefiles after configure is run. -dgg-]]
-
- SCO/UNIX doesn't understand #!/<some shell> syntax. This breaks
- the use of log.pl as it gets invoked by /bin/sh instead of
- !#/usr/local/bin/perl. WorkAround : edit log.pl and change it into
- a shell script which invokes perl with log.perl (renamed from
- log.pl) as input.
- Contributed by Joe Drumgoole
-
-
- 4H.4 I use AIX. Is there anything I need to know?
-
- The only report on AIX claims to have no trouble using it in
- concert with SunOS and IRIX platforms.
-
-
- 4H.5 I use IRIX. Is there anything I need to know?
-
- If you see "uid" numbers where you would expect user names, try
- adding -lsun to the link line. Without it CVS is unable to
- retrieve "passwd" data through NIS.
-
-
- 4H.6 I use an HP system. Is there anything I need to know?
-
- HP distributes RCS version 3 (a circa 1983 release!) with HP-UX.
- CVS does not work with RCS version 3; it requires RCS version 4
- or later. Your best bet is to find the latest version of RCS
- and install it somewhere.
-
- HP-UX 8.07 has a serious bug with the mmap system call and NFS
- files; the bug can crash the operating system. Make sure that
- you configure RCS to avoid mmap by setting has_mmap to 0 in
- RCS's conf.h. This bug is fixed in HP-UX 9.
-
- Contributed by Paul Eggert
-
- If using the setgid() trick described in 4D.13, you will have to
- create an entry in the /etc/privgroup file to give the group
- assigned to the cvs executable setgid permission (see
- setprivgrp(1m)). Additionally, if you are restricting "read"
- access to the Repository by limiting access to the executable
- (this requires yet another group), then you will require that
- /etc/logingroup exists and is configured correctly (usually it's
- just alink to /etc/group).
-
- Contributed by Dale Woolridge
-
-
- 4H.7 I use AFS. Is there anything I need to know?
-
- There is a problem with the way CVS performs its locking when the
- files are within AFS. When your current PTS id != your uid, the
- locks are not deleted. The stat() system call returns the PTS id
- of the owner. If that id != your uid, CVS assumes you did not lock
- it, and leaves the lock files alone. The next time you try to use
- it, it complains that someone has the repository locked.
-
- Contributed by Michael Ganzberger
-
- [[This was against CVS 1.3. Is it still in CVS 1.4?]]
-
-
- 4H.8 I use A/UX. Is there anything I need to know?
-
- [[??]]
-
-
-
-
-=============================================
-== Section 5 ==== Past & Future ====
-=============================================
-
-----------------
--- Section 5A -- Contributors
-----------------
-
- **** Questions:
-
-=5A.1 Who wrote CVS?
- 5A.2 You didn't write all of this FAQ, did you?
-
-
- **** Answers:
-
-
-=5A.1 Who wrote CVS?
-
- Brian Berliner <berliner@sun.com> converted a collection of
- scripts written by Dick Grune <dick@cs.vu.nl> into a C program,
- then added all sorts of features. He continues to maintain CVS.
-
- Jeff Polk <polk@bsdi.com> wrote much of the code added between
- revisions 1.2 and 1.3. Many others were involved at some level.
-
- david d zuhn <zoo@armadillo.com> fixed a number of bugs, added
- some of the new features, reworked the whole thing to be more
- portable, and provided much of the energy to push CVS 1.4 out
- the door.
-
- Jim Kingdon implemented CVS 1.5's remote repository access
- features, fixed many bugs, and managed the release of version 1.5.
-
- Take a look at the README and the ChangeLog files in the CVS
- sources for more contributors.
-
-
- 5A.2 You didn't write all of this FAQ, did you?
-
- In the original hunt for questions to answer (performed in
- Jan/Feb, 1993), I polled hundreds of people and I rephrased all
- sorts of text found on the net. Between 2/93 and 10/93, I
- released about 20 versions, with corrections and additions from
- the info-cvs mailing list and private correspondence.
-
- Between 10/93 and 10/94 I extracted frequently asked questions
- from the 1200 mail messages to the info-cvs mailing list,
- turned them into focused questions and tried to answer them.
-
- 93/02/?? ~4000 lines
- 93/06/?? ~5000 lines
- 93/10/23 7839 lines 278K
- 94/10/29 9856 lines 360K
- 95/05/09 9981 lines 365K
-
- Because there are so many posers of questions, I will list only
- those who contribute answers or help significantly with the
- content and structure of this document.
-
- If I used someone else's text verbatim, I mentioned it in the
- given answer. The people whose email postings have added to this
- document or who have added to my understanding are:
-
- Brian Berliner <berliner@sun.com>, CVS maintainer.
- Paul Eggert <eggert@twinsun.com>, RCS maintainer.
-
- Gray Watson <gray@antaire.com>
- Per Cederqvist <ceder@signum.se>
- Pete Clark <pclark@is.com>
-
- all of whom have sent me copies of their tutorials
- and local CVS documentation.
-
- Additional contributors, who have sent me ideas, text, corrections
- and support include (in alphabetical order):
-
- Per Abrahamsen <amanda@iesd.auc.dk>
- Donald Amby <amby@mixcom.mixcom.com>
- Mark D Baushke <mdb@cisco.com>
- Jim Blandy <jimb@cyclic.com>
- Tom Cunningham <tomc@bouwsma,sps.mot.com>
- Graydon Dodson <grdodson@lexmark.com>
- Joe Drumgoole <joed@splatter.demon.co.uk>
- Don Dwiggins <dwig@markv.com>
- Bryant Eastham <bryant@ced.utah.edu>
- Dan Franklin <dan@diamond.bbn.com>
- Michael Ganzberger <ganzbergermd@ES.net>
- Steve Harris <vsh%etnibsd@uunet.uu.net>
- Erik van Linstee <linstee@dutecaj.et.tudelft.nl>
- Jeffrey M Loomis <jml@world.std.com>
- Barry Margolin <barmar@near.net>
- Mark K. Mellis <mkm@ncd.com>
- Chris Moore <Chris.Moore@src.bae.co.uk>
- Gary Oberbrunner <garyo@avs.com>
- Steve Turner <stevet@carrier.sps.mot.com>
- Dave Wolfe <dwolfe@pffft.sps.mot.com>
- Dale Woolridge <dwoolridge@cid.aes.doe.ca>
-
-
-
- Please send corrections. If I forgot you, remind me and I'll add
- your name to the list.
-
-
-----------------
--- Section 5B -- Bugs and Patches
-----------------
-
-This section addresses some known bugs and patches for them.
-Large patches will be stored in the FTP area.
-See the Development section later for stuff being worked on.
-
- **** Questions:
-
- 5B.1 Why can't CVS handle deletion of directories?
- 5B.2 Why can't CVS handle the moving of sources from one place in the
- directory hierarchy to another?
- 5B.3 When I typed "cvs update -D <date>", why did it check out all
- sorts of ancient files from the Attic? Shouldn't it just create
- the set of files and revisions that existed at that date?
- 5B.4 When I typed "cvs update -D <date>" in my branch, why did it
- screw up all my files?
- 5B.5 When I executed "checkout" into an existing directory I got "No
- such file or directory" errors. Why?
- 5B.6 Why does "update" send all output to the terminal after 26 files
- have been updated?
- 5B.7 Why does the merge occasionally resurrect lines of code?
- 5B.8 Why does the merge fail when my "rcsmerge" program is
- configured to use GNU diff version 2.1 or later?
-
-
- **** Answers:
-
- 5B.1 Why can't CVS handle deletion of directories?
-
- An oversight, probably. [[Fixed in a future release?]]
-
-
- 5B.2 Why can't CVS handle the moving of sources from one place in the
- directory hierarchy to another?
-
- A "renaming database" has been proposed to track the history of
- pathname changes in the Repository. A general solution is a
- difficult problem. See 4B.8.
-
-
- 5B.3 When I typed "cvs update -D <date>", why did it check out all
- sorts of ancient files from the Attic? Shouldn't it just create
- the set of files and revisions that existed at that date?
-
- This seems to be a bug, but is really the lack of any obvious
- place to store the date when a file is "removed".
-
- There are four ranges of dates that CVS has to deal with when
- trying to determine what revision was available on <date>:
-
- 1. Dates before the earliest revision in the file.
-
- 2. Dates between any two revisions in the file.
-
- 3. Dates between the latest revision in the file and the date
- when the file was moved to the Attic by "commit".
-
- 4. Dates after moving the file to the Attic.
-
- Since the date when a file is moved to the Attic is not stored
- anywhere, CVS can't tell the difference between #3 and #4.
- To avoid not producing a file that should exist in case #3, it
- produces extraneous files in case #4.
-
-
- For the above reason, if you have removed files in the Attic, it
- is better to use "-r <tag>, or even "-r HEAD" than to use a
- date spec.
-
- If you must use "-D <date>", then you should either archive and
- delete Attic files (losing some past history) or construct your
- Makefiles to work with an explicit list of files and let the old
- source files stay in the working directory. The contents of the
- revision-controlled Makefile can then be considered to contain
- deletion "information".
-
-
- 5B.4 When I typed "cvs update -D <date>" in my branch, why did it
- screw up all my files?
-
- Currently, the internal routine ("version_ts") that looks up
- info about a file, overrides both the tag and date if *either*
- the tag or date is specified on the command line. If only the
- date is specified, it should not override a branch tag, but it
- does.
-
- In CVS 1.3, the documented "-D <branch_tag>:<date>" syntax only
- works with the Main Branch and the Vendor Branch.
-
- [[Is this fixed in CVS 1.4? This is one item I didn't check.]]
-
-
- 5B.5 When I executed "checkout" into an existing directory I got "No
- such file or directory" errors. Why?
-
- Though the man page says that "checkout" turns into an
- "update -d" in directories that already exist, it is referring
- to directories that already exist *and* were created by CVS.
-
- When you try to run "checkout" on top of an existing directory
- structure, some of which wasn't created by CVS, it will handle
- directories and non-CVS files within directories already under
- CVS, but it will display the above error on non-CVS files within
- non-CVS directories.
-
-
- 5B.6 Why does "update" send all output to the terminal after 26 files
- have been updated?
-
- CVS uses the "tmpnam()" function to generate temporary file names.
- The ANSI standard for the "tmpnam()" function says:
-
- "The tmpnam function generates a different string each time it is
- called, up to TMP_MAX times. If it is called more than TMP_MAX
- times, the behavior is implementation defined."
-
- Later it says that the value of "TMP_MAX shall be at least 25."
-
- On some platforms, the above specification is taken literally by
- turning "at least 25" into "exactly 26" and by doing something
- foolish (i.e. "implementation defined") after that. Some
- systems return the same name repeatedly, which causes one form of
- trouble. Others return NULL or garbage, which causes a different
- form of trouble.
-
- The broken systems appear to be cycling a single character through
- the alphabet. SunOS cycles 3 characters through the alphabet, so
- it won't cause trouble until 26 cubed or 17576 calls to
- "tmpnam()".
-
- Since CVS doesn't depend on the exact format of the tmp files, the
- workaround is to provide a "tmpnam()" that doesn't have a limit
- on the number of calls to it.
-
-
- 5B.7 Why does the merge occasionally resurrect lines of code?
-
- The diff3 program provided by GNU diff version 1.15 has a bug
- that occasionally causes text to come back from the dead.
-
- This is an old problem which you can avoid by upgrading to the
- latest GNU "diffutils" package. If you were using GNU diff
- version 1.15 and plan to upgrade to the latest GNU diff program,
- see the next question.
-
-
- 5B.8 Why does the merge fail when my "rcsmerge" program is
- configured to use GNU diff version 2.1 or later?
-
- A change in the overlap format was introduced in GNU diff3
- between versions 2.0 and 2.1 that causes RCS versions before
- 5.6.0.1 to fail during a merge.
-
- To get consistent rcsmerge behavior, you have four choices:
-
- 1. Go back to using GNU diff 1.15 or 2.0 with RCS versions 5.5 or
- 5.6. If you want to use GNU diff 2.1 or later, you'll have to
- pick one of the other three choices in this list.
-
- 2. Grab RCS version 5.6.0.1 from an FSF archive and set the
- DIFF3_A macro to '1' as it tells you to in the Makefile:
-
- #define DIFF3_A 1
-
- 3. Patch the RCS 5.6 source. Change line 84 in "merger.c" from:
-
- DIFF3, "-am", "-L", label[0], "-L", label[1],
- to
- DIFF3, "-amE", "-L", label[0], "-L", "", "-L", label[1],
-
- 4. Wait both for RCS version 5.7 to be released and for a new
- version of CVS that can deal with it.
-
-
-----------------
--- Section 5C -- Development
-----------------
-
-
- **** Questions:
-
- 5C.1 Where do I send bug reports?
- 5C.2 Where do I send fixes and patches?
- 5C.3 Where do I send ideas for future development?
-=5C.4 What plans are there for new features?
- 5C.5 I have some time and I'd like to help. What can I do for you?
-
-
- **** Answers:
-
- 5C.1 Where do I send bug reports?
-
- First make sure it is a bug. Talk to your friends, coworkers and
- anyone you know who uses CVS. Search this FAQ for related issues.
- Then test it carefully. Try out variations to narrow down the
- problem. Make sure it is repeatable. Look for workarounds so you
- can report them.
-
- If you are still sure it's a bug and you tried to fix it, skip to
- the next question. Otherwise, send a message to the info-cvs
- mailing list containing one of the following:
-
- 1. If you have a good repeatable case and you think you know what
- is going on, then describe the problem in detail. Include
- a workaround if you have one.
-
- 2. If you have no idea what is going on, go ahead and send a
- question to the info-cvs mailing list. Include any information
- you have describing the symptoms.
-
-
- 5C.2 Where do I send fixes and patches?
-
- First make sure the "fix" does something useful. Have someone
- review your fix. Spend a bit of one person's time in a detailed
- analysis of your vast idea before displaying a half-vast idea to
- hundreds of people.
-
- If you tried to fix it and the patch is small, include the patch
- in your message. Make sure the patch is based on the latest
- released version of CVS.
-
- If you tried to fix it and the patch is large, you should think
- about why it is so large. Did you add a generally useful feature,
- or did it grow out of hand?
-
- If you still believe it is solid, produce a patch file using the
- CVS commands "patch" or "diff -c". [[You *are* keeping CVS under
- CVS, right?]] The patch should be based on the latest released
- version of CVS. Then use the "cvsbug" program (provided with the
- CVS sources) to send it to the CVS maintainers. A self-contained
- patch that provides a single useful feature or correction might
- show up independently in the patches directory of the FTP archive.
-
- If careful testing reveals an RCS bug rather than a CVS bug, you
- can send bug reports to: rcs-bugs@cs.purdue.edu
-
-
- 5C.3 Where do I send ideas for future development?
-
- If you have a bright idea, discuss it on the info-cvs mailing
- list. If you have the time to implement something you can test,
- send the diffs along too as described above.
-
-
-=5C.4 What plans are there for new features?
-
- A "rename" or "per-directory" database has been bandied about on
- the net for years. It is needed, but it is a lot of work.
-
- CVS version 1.5 supports remote repository access, but Paul
- F. Kunz <Paul_Kunz@slac.stanford.edu> has produced another version
- (rCVS) that also runs remotely. It is available for testing.
-
- On the host "preprint.slac.stanford.edu", you can find:
- Paper: slacpubs/5000/slac-pub-5923.ps.Z
-
- This was for a conference in Sept, 1993, before first beta.
-
- On the host "ftp.slac.stanford.edu", you can find:
- Sources: pub/sources/rcvs-0.8.1.tar.Z
-
- With the caveat that until version 1.0 is available, rCVS should
- be considered an unreliable Beta release, you are invited to
- grab a copy and test it.
-
-
- [[Others?]]
-
-
- 5C.5 I have some time and I'd like to help. What can I do for you?
-
- You can review this document, correct errors and fill in any of
- the incomplete sections.
-
- You can add to the contrib area, which contains useful ways to use
- some of the programmable CVS facilities (loginfo, commitinfo) or
- ways of connecting to work environments (pcl-cvs).
-
- You could write a regression test suite. Or at least a scaffold
- into which we can drop tests.
-
- You can write specs for new features, fix bugs, review the man
- page or . . .
-
- [[Brian?]]
-
- [[Is there some way we can register someone as working
- on something or should we just stay in the "implement it and
- send it to me" mode?]]
-
-----------------
--- Section 5D -- Professional Support
-----------------
-
-
- **** Questions:
-
-+5D.1 Doesn't Cygnus support CVS?
-+5D.2 What is Cyclic Software doing with CVS?
-
-
- **** Answers:
-
-+5D.1 Doesn't Cygnus support CVS?
-
- Cygnus is a company that supports a variety of FSF software. It
- uses a version of CVS and people from Cygnus are on the info-cvs
- mailing list.
-
- [[Could someone from Cygnus state Cygnus's official and unofficial
- relationship with CVS?]]
-
-
-+5D.2 What is Cyclic Software doing with CVS?
-
- Cyclic Software exists to provide support for CVS. Here's a copy
- of their product line sheet:
-
-
- Cyclic Software
- Standard Support
-
- Cyclic Software offers support contracts for CVS. This
- includes:
-
- * Full source, binaries, and documentation for CVS, RCS, GNU
- diffutils, patch, and gzip -- that is, CVS and everything it
- wants to run -- via FTP or tape;
-
- * guaranteed responses for bugs within 5 business days;
-
- * guaranteed fixes for reproducible bugs within 10 business days.
-
- (By "reproducible bugs", we mean instances where the software
- clearly does not behave as documentation or reasonable
- expectations indicate it should, and that we are able to
- reproduce this misbehavior reliably. Naturally, we will make
- every possible effort to reproduce the bugs you report; our
- experience has been that it's usually not difficult.)
-
- We charge a fixed fee for:
-
- * one year
-
- * one host type (hardware & operating system)
-
- * twenty users at your site, with two of those users designated
- as "contacts" for CVS, to reduce communication problems.
-
- If the host type is not one we have access to for testing
- purposes, you can either lend us a machine of the appropriate type
- for the duration of the contract, or pay an additional fee
- up-front. We have access to Solaris, Irix, HP-UX, Linux and
- Ultrix. (This list is subject to change; contact us for details.)
-
- If the above fee structure is not well-suited to your
- organization, please say so. We're interested in tailoring our
- services to be as useful to you as possible.
-
- Training
-
- We offer on-site training in the use of CVS at a daily rate,
- plus expenses (inc. travel, accommodations). The classes target
- new and intermediate users of CVS; we feel advanced users benefit
- more from a written manual and the source code.
-
- Custom Enhancements
-
- We will implement enhancements to CVS or its documentation, and
- port CVS to new architectures. Our rates for this work depend on
- the amount of work to be done.
-
- We strongly prefer to work on enhancements suitable for
- incorporation into the general CVS release upon completion; we
- will help you design the enhancement in a way that makes this
- possible.
-
- Short-Term Consulting
-
- We will do short-term consulting at hourly rates. These rates
- are calculated to include the overhead of dealing in short time
- periods. Therefore, in sufficiently large projects, we recommend
- arranging a long-term support contract instead of dealing on an
- hourly basis.
-
- Anything Else
-
- Cyclic Software is interested in arranging contracts for work
- in other areas, to be produced as free software. Everything is
- negotiable.
-
- How To Contact Us
-
- (Email is preferred.)
-
- Email: <info@cyclic.com>
- Phone: +1 812 335 9023
- Web: http://www.cyclic.com
- SnailMail: Cyclic Software
- P.O. Box 804
- Bloomington, IN 47402-0804
- USA
-
- Contributed by Jim Blandy
-
-
-
-=================================================
-== Section 6 ==== Table of Contents ====
-=================================================
-
-===========================================================================
-== Frequently Asked Questions about CVS (The Concurrent Versions System) ==
-===========================================================================
-
-============================================
-== Section 0 ==== Introduction ====
-============================================
-
-Questions are divided into five numbered Sections. Sections are divided
-into lettered sub-sections. The questions are numbered sequentially
-within each sub-section, though they are in no particular order.
-
- 1. What is CVS?
- A. What is CVS? What's it for? Why CVS?
- B. Where do I find it? Where can I find Help?
- C. How does CVS differ from other similar software?
- D. What do you mean by . . .? (Definitions)
-
- 2. User Tasks
- A. Getting Started
- B. Common User Tasks
- C. Less Common User Tasks
- D. General Questions
-
- 3. Commands
- A. through P. One section for each CVS command.
-
- 4. Advanced Topics
- A. Installing CVS
- B. Setting up and Managing the Repository
- C. Branching and Merging
- D. Tricks of the Trade
- E. Internal errors
- F. Related Software
- G. Engineering
- H. Other Systems
-
- 5. Past & Future
- A. Contributors.
- B. Bugs and Patches
- C. Development
- D. Professional Support
-
- 6. Table of Contents
-
-
-
-============================================
-== Section 1 ==== What is CVS? ====
-============================================
-
-----------------
--- Section 1A -- What is CVS? What's it for? Why CVS?
-----------------
- 1A.1 What does CVS stand for? Can you describe it in one sentence?
- 1A.2 What is CVS for? What does it do for me?
- 1A.3 How does CVS work?
- 1A.4 What is CVS useful for?
- 1A.5 What is CVS *not* useful for?
-
-----------------
--- Section 1B -- Where do I find CVS? Where can I find Help?
-----------------
- 1B.1 How do I get more information about CVS?
- 1B.2 Is there an archive of CVS material?
- 1B.3 How do I get files out of the archive if I don't have FTP?
- 1B.4 How do I get a copy of the latest version of CVS?
- 1B.5 Is there a mailing list devoted to CVS? How do I find it?
- 1B.6 What happened to the CVS Usenet newsgroup I heard about?
-
-----------------
--- Section 1C -- How does CVS differ from other, similar software?
-----------------
- 1C.1 How does CVS differ from RCS?
- 1C.2 How does CVS differ from SCCS?
- 1C.3 How does CVS differ from ClearCase?
-#1C.4 How does CVS differ from TeamWare/SparcWorks?
- 1C.5 How does CVS differ from Aegis?
- 1C.6 How does CVS differ from Shapetools?
- 1C.7 How does CVS differ from TeamNet?
- 1C.8 How does CVS differ from ProFrame?
- 1C.9 How does CVS differ from CaseWare/CM?
- 1C.10 How does CVS differ from Sublime?
- 1C.11 How does CVS differ from PVCS?
- 1C.12 How does CVS differ from CMVC?
-
-----------------
--- Section 1D -- What do you mean by . . .? (Definitions)
-----------------
- 1D.1 What are "The Repository", "$CVSROOT" and "CVSROOT"?
- 1D.2 What is an RCS file?
- 1D.3 What is a working file?
- 1D.4 What is a working directory (or working area)?
- 1D.5 What is "checking out"?
- 1D.6 What is a revision?
- 1D.7 What is a "Tag"?
- 1D.8 What are "HEAD" and "BASE"?
- 1D.9 What is a Branch?
- 1D.10 What is "the trunk"?
- 1D.11 What is a module?
- 1D.12 What does "merge" mean?
-
-
-==========================================
-== Section 2 ==== User Tasks ====
-==========================================
-
-----------------
--- Section 2A -- Getting Started
-----------------
- 2A.1 What is the first thing I have to know?
- 2A.2 Where do I work?
- 2A.3 What does CVS use from my environment?
- 2A.4 OK, I've been told that CVS is set up, my module is named
- "ralph" and I have to start editing. What do I type?
- 2A.5 I have been using RCS for a while. Can I convert to CVS without
- losing my revision history? How about converting from SCCS?
-
-----------------
--- Section 2B -- Common User Tasks
-----------------
- 2B.1 What is the absolute minimum I have to do to edit a file?
- 2B.2 If I edit multiple files, must I type "commit" for each one?
- 2B.3 How do I get rid of the <module> directory that "checkout" created?
- 2B.4 How do I find out what has changed since my last update?
- 2B.5 I just created a new file. How do I add it to the Repository?
- 2B.6 How do I merge changes made by others into my working directory?
- 2B.7 How do I label a set of revisions so I can retrieve them later?
- 2B.8 How do I checkout an old release of a module, directory or file?
- 2B.9 What do I have to remember to do periodically?
-
-----------------
--- Section 2C -- Less Common User Tasks
-----------------
- 2C.1 Can I create non-CVS sub-directories in my working directory?
- 2C.2 How do I add new sub-directories to the Repository?
- 2C.3 How do I remove a file I don't need?
- 2C.4 How do I rename a file?
- 2C.5 How do I make sure that all the files and directories in my
- working directory are really in the Repository?
- 2C.6 How do I create a branch?
- 2C.7 How do I modify the modules file? How about the other files in
- the CVSROOT administrative area?
- 2C.8 How do I split a file into pieces, retaining revision histories?
-
-----------------
--- Section 2D -- General Questions
-----------------
- 2D.1 How do I see what CVS is trying to do?
- 2D.2 If I work with multiple modules, should I check them all out and
- commit them occasionally? Is it OK to leave modules checked out?
- 2D.3 What is a "sticky" tag? What makes it sticky? How do I loosen it?
- 2D.4 How do I get an old revision without updating the "sticky tag"?
- 2D.5 What operations disregard sticky tags?
- 2D.6 Is there a way to avoid reverting my Emacs buffer after
- committing a file? Is there a "cvs-mode" for Emacs?
- 2D.7 How does conflict resolution work? What *really* happens if two
- of us change the same file?
- 2D.8 How can I tell who has a module checked out?
- 2D.9 Where did the .#<file>.1.3 file in my working directory come from?
- 2D.10 What is this "ignore" business? What is it ignoring?
- 2D.11 Is there a way to set user-specific configuration options?
- 2D.12 Is it safe to interrupt CVS using Control-C?
- 2D.13 How do I turn off the "admin" command?
- 2D.14 How do I turn off the ability to disable history via "cvs -l"?
- 2D.15 How do I keep certain people from accessing certain directories?
-
-
-========================================
-== Section 3 ==== Commands ====
-========================================
-
-----------------
--- Section 3A -- "add", "ad", "new"
-----------------
- 3A.1 What is "add" for?
- 3A.2 How do I add a new file to the branch I'm working on?
- 3A.3 Why did my new file end up in the Attic?
- 3A.4 Now that it's in the Attic, how do I connect it to the Main branch?
- 3A.5 How do I avoid the hassle of reconnecting an Attic-only file to
- the Main Branch?
- 3A.6 How do I cancel an "add"?
- 3A.7 What are the ./CVS/file,p and ./CVS/file,t files for?
- 3A.8 How do I "add" a binary file?
-
-----------------
--- Section 3B -- "admin", "adm", "rcs"
-----------------
- 3B.1 What is "admin" for?
- 3B.2 Wow! Isn't that dangerous?
- 3B.3 What would I normally use "admin" for?
- 3B.4 What should I avoid when using "admin"?
- 3B.5 How do I restrict the "admin" command? The -i flag in the modules
- file can restrict commits. What's the equivalent for "admin"?
- 3B.6 I backed out a revision with "admin -o" and committed a
- replacement. Why doesn't "update" retrieve the new revision?
-
-----------------
--- Section 3C -- "checkout", "co", "get"
-----------------
- 3C.1 What is "checkout" for?
- 3C.2 What is the "module" that "checkout" takes on the command line?
- 3C.3 Isn't a CVS "checkout" just a bunch of RCS checkouts?
- 3C.4 What's the difference between "update" and "checkout"?
- 3C.5 Why can't I check out a file from within my working directory?
- 3C.6 How do I avoid dealing with those long relative pathnames?
- 3C.7 Can I move a checked-out directory? Does CVS remember where it
- was checked out?
- 3C.8 How can I lock files while I'm working on them the way RCS does?
- 3C.9 What is "checkout -s"? How is it different from "checkout -c"?
-
-----------------
--- Section 3D -- "commit", "ci", "com"
-----------------
- 3D.1 What is "commit" for?
- 3D.2 If I edit ten files, do I have to type "commit" ten times?
- 3D.3 Explain: cvs commit: Up-to-date check failed for `<file>'
- 3D.4 What happens if two people try to "commit" conflicting changes?
- 3D.5 I committed something and I don't like it. How do I remove it?
- 3D.6 Explain: cvs commit: sticky tag `V3' for file `X' is not a branch
- 3D.7 Why does "commit -r <tag/rev>" put newly added files in the Attic?
- 3D.8 Why would a "commit" of a newly added file not produce rev 1.1?
-
-----------------
--- Section 3E -- "diff", "di", "dif"
-----------------
- 3E.1 What is "diff" for?
- 3E.2 Why did "diff" display nothing when I know there are later
- committed revisions in the Repository?
- 3E.3 How do I display what changed in the Repository since I last
- executed "checkout", "update" or "commit"?
- 3E.4 How do I display the difference between my working file and what
- I checked in last Thursday?
- 3E.5 Why can't I pass long options, like --unified, to "diff"?
-
-----------------
--- Section 3F -- "export", "exp", "ex"
-----------------
- 3F.1 What is "export" for?
- 3F.2 Why does it remove the RCS keywords so I can't use the "ident"
- command on the source files?
- 3F.3 Can I override the '-kv' flag CVS passes to RCS?
- 3F.4 Why doesn't "export" have a '-k' flag like "import" does?
- 3F.5 Why does "export -D" check out every file in the Attic?
-
-----------------
--- Section 3G -- "history", "hi", "his"
-----------------
- 3G.1 What is "history" for?
- 3G.2 Of what use is it?
- 3G.3 What is this, Big Brother?
- 3G.4 I deleted my working directory and "history" still says I have
- it checked out. How do I fix it?
- 3G.5 So I *can* edit the History file?
- 3G.6 Why does the history file grow so quickly?
- 3G.7 What is the difference between "cvs history -r <tag/rev>" and
- "cvs history -t <tag>"?
- 3G.8 Why does "cvs history -c -t <tag>" fail to print anything?
- 3G.9 "cvs history -a -o" only printed one line for each checked-out
- module. Shouldn't it print all the directories where the
- modules are checked out?
- 3G.10 I can't figure out "history", can you give me concrete examples?
- 3G.11 Can we merge history files when we merge Repositories?
-
-----------------
--- Section 3H -- "import", "im", "imp"
-----------------
- 3H.1 What is "import" for?
- 3H.2 How am I supposed to use "import"?
- 3H.3 Why does import put files on a branch? Why can't I work on the
- main trunk instead of a Vendor branch?
- 3H.4 Is there any way to import binary files?
- 3H.5 Why does "import" corrupt some binary files?
- 3H.6 How do I retain the original $\Revision$ strings in the sources?
-=3H.7 I imported some files for the Yarg compiler that compiles files
- with a suffix of ".yarg" and whose comment prefix is "YARG> ".
- When I check them out, they will no longer compile because they
- have this junk in them. Why?
- 3H.8 How do I make "import" save the timestamps on the original files?
- 3H.9 Why can't I "import" 3 releases on different branches?
- 3H.10 What do I do if the Vendor adds or deletes files between releases?
- 3H.11 What about if the Vendor changes the names of files or
- directories, or rearranges the whole structure between releases?
- 3H.12 I thought "import" was for Vendor releases, why would I use it
- for code of my own? Do I have to use import?
- 3H.13 How do I import a large Vendor release?
- 3H.14 Explain: ERROR: cannot create link to <file>: Permission denied
- 3H.15 Where does the -m <message> go when the file doesn't change?
- 3H.16 How do I "import" just the files ignored by a previous "import"?
- 3H.17 Why did "import" ignore all the symlinks?
-
-----------------
--- Section 3I -- "log", "lo", "rlog"
-----------------
- 3I.1 What is "log" for?
- 3I.2 How do I extract the log entries between two revisions?
- 3I.3 How do I extract the log entries on a whole branch?
- 3I.4 How do I generate ChangeLogs from RCS logs?
- 3I.5 Why does "log" tell me a file was committed exactly 5 hours later
- than I know it was?
-
-----------------
--- Section 3J -- "patch", "pa", "rdiff"
-----------------
- 3J.1 What is "patch" for?
- 3J.2 Why does "patch" include files from the Attic when I use '-D'?
- 3J.3 How do I make "patch" produce a patch for one or two files?
- It seems to work only with modules.
-
-----------------
--- Section 3K -- "release", "re", "rel"
-----------------
- 3K.1 What is "release" for?
- 3K.2 Why can't I reverse a "cvs checkout path/name/subdir" with a
- "cvs release path/name/subdir" without an "unknown module name"?
- 3K.3 Why can't I "release" portions of a checked out directory? I
- should be able to "release" any file or sub-directory within
- my working directory.
- 3K.4 I removed the tree that I was about to start working on. How do I
- tell cvs that I want to release it if I don't have it anymore?
- 3K.5 Why doesn't "release -d module" reverse a "checkout module"?
- 3K.6 Why can't I release a module renamed with "cvs checkout -d"?
-
-----------------
--- Section 3L -- "remove", "rm", "delete"
-----------------
- 3L.1 What is "remove" for?
- 3L.2 Why doesn't "remove" work on directories when it appears to try?
- 3L.3 I don't like removing files. Is there another way to ignore them?
- 3L.4 I just removed a file. How do I resurrect it?
- 3L.5 Why doesn't "remove" delete the file? Instead, it prints an
- error message and tells me to remove the file by hand.
-
-----------------
--- Section 3M -- "rtag", "rt", "rfreeze"
-----------------
- 3M.1 What is "rtag" for?
- 3M.2 Why use "rtag"? It assumes no one is changing the Repository.
- 3M.3 What revision does "rtag -r <tag1> <tag2>" actually put the tag on?
- 3M.4 What happens if the tags are the same in "rtag -r <tag> <tag>"?
- 3M.5 Why doesn't "rtag -b -r <branch_tag1> <branch_tag2>" rename or
- duplicate a magic branch tag?
-
-----------------
--- Section 3N -- "status", "st", "stat"
-----------------
- 3N.1 What is "status" for?
- 3N.2 Why does "status" limit the File: at the top to 17 characters?
- 3N.3 Why does it print "Sticky" lines when the values are "(none)"?
- 3N.4 Shouldn't the status "Needs Checkout" be "Needs Update"?
-
-----------------
--- Section 3O -- "tag", "ta", "freeze"
-----------------
- 3O.1 What is "tag" for?
- 3O.2 What is the difference between "tag" and "rtag"?
- 3O.3 Why does "tag -b" not put a tag on the Branch Point revision?
- How do I refer to the Branch Point?
- 3O.4 So "{r}tag" labels a bunch of files. What do you use a Tag for?
- 3O.5 How do I get "tag" and "rtag" to send mail the way "commit" does?
- 3O.6 Why can't "tag" handle the '-r' option that "rtag" takes?
- 3O.7 After a "tag <tag>" in my working directory, why doesn't "checkout
- -r <tag>" somewhere else produce copies of my current files?
- 3O.8 Why doesn't "tag" write a history record the way "rtag" does?
- 3O.9 How do I rename a <tag>?
-
-----------------
--- Section 3P -- "update", "up", "upd"
-----------------
- 3P.1 What is "update" for?
- 3P.2 What do 'U', 'M' and 'C' mean when I type "update"? Are they
- different for "cvs -n update"?
- 3P.3 What's the difference between "update" and "checkout"?
- 3P.4 Why don't I get new files when I execute "update"?
- 3P.5 Why does "update" say 'M' both for plain modified files and for
- successful (i.e. conflict-free) merges? Aren't they different?
- 3P.6 What's a "sticky conflict"? How does it know a conflict occurred?
- 3P.7 Is there a feature to tell me what I have changed, added and
- removed without changing anything?
- 3P.8 Why were all my files deleted when I executed "update"?
-
-
-===============================================
-== Section 4 ==== Advanced Topics ====
-===============================================
-
-----------------
--- Section 4A -- Installing CVS
-----------------
- 4A.1 What do I have to do before I install CVS?
- 4A.2 How do I configure the CVS programs?
- 4A.3 What do I have to install?
- 4A.4 How do I work around the merge problems in GNU diff version 2.1
- or later?
-
-----------------
--- Section 4B -- Setting up and Managing the Repository
-----------------
- 4B.1 What do I do first? How do I create a Repository?
- 4B.2 What are those files in $CVSROOT/CVSROOT?
- 4B.3 Is there any other state stored in the Repository besides in the
- $CVSROOT/CVSROOT directory?
- 4B.4 How do I put sources into the Repository?
- 4B.5 What file permissions should I use on (and in) the Repository?
- 4B.6 How do I structure my Repository?
- 4B.7 Why would anyone use "modules"? They are too restrictive. I
- want to be able to select just the files I want to edit.
- 4B.8 How do I rename a file or directory? What are the consequences?
- 4B.9 What are "Attic" directories?
- 4B.10 Is it OK to remove anything from the Repository?
- 4B.11 Can I convert to CVS from RCS without losing my revision history?
- 4B.12 Can I move RCS files with branches in them into the Repository?
- 4B.13 Can I use raw RCS commands on the Repository?
- 4B.14 How do I convert from SCCS to RCS?
- 4B.15 How do I limit access to the Repository?
- 4B.16 What are the Repository Administrator's responsibilities?
- 4B.17 How do I move the whole Repository?
- 4B.18 How do I change permissions on a file in the Repository by using
- a CVS command? (i.e. without using "chmod 777 $CVSROOT/dir/file")
-
-----------------
--- Section 4C -- Branching and Merging
-----------------
- 4C.1 What is a branch?
- 4C.2 Why (or when) would I want to create a branch?
- 4C.3 How do I create and checkout a branch?
- 4C.4 Once created, how do I manage a branch?
- 4C.5 Are there any extra issues in managing multiple branches?
- 4C.6 How do I merge a whole branch back into the trunk?
-=4C.7 How do I merge changes from the trunk into my branch or between
- branches?
- 4C.8 How do I merge onto the Main Branch a file that exists only on a
- branch other than the Main Branch? (i.e. it is in the Attic)
- 4C.9 How do I know what branch I'm (working) on?
- 4C.10 Do I really have to know the name of the branch I'm working on?
- 4C.11 How do I refer to the revision where I branched so I can see
- what changed since the Branch Point on another branch?
- 4C.12 Why didn't the command "cvs admin -bBRANCH1 *" create a branch?
- 4C.13 Is it possible to set the "default CVS branch" for everyone?
- 4C.14 How do I perform a large merge?
- 4C.15 Is a Vendor merge any different from a branch merge?
- 4C.16 How do I go back to a previous version of the code on a branch?
- 4C.17 Once I've found the files I want, how do I start changing them?
- I keep getting warnings about sticky tags.
- 4C.18 Why do I get the latest files on the branch when I tried to
- "update -r <tag>"?
- 4C.19 How can I avoid a merge? I just want to move the latest revision
- on my working branch directly onto the trunk.
- 4C.20 How to I avoid merge collisions in the RCS $\Log$ data?
- 4C.21 Why should I trust automatic merges?
- 4C.22 How does CVS decide if it can safely perform a merge?
- 4C.23 After resolving merge conflicts in a file, what if I want to keep
- my previous version, and not take any of the branch changes?
-
-----------------
--- Section 4D -- Tricks of the Trade
-----------------
- 4D.1 How can you even check in binary files, let alone allow CVS to
- do its auto-merge trick on them?
- 4D.2 Can I edit the RCS (",v") files in the Repository?
- 4D.3 Can I edit the ./CVS/{Entries,Repository,Tag} files?
- 4D.4 Someone executed "admin -o" and removed revisions to which
- tags/symbols were attached. How do I fix them?
- 4D.5 How do I move or rename a magic branch tag?
- 4D.6 Can I use RCS locally to record my changes without making them
- globally visible by committing them?
- 4D.7 How can I allow access to the Repository by both CVS and RCS?
- 4D.8 I "updated" a file my friend, "bubba", committed yesterday.
- Why doesn't the file now have a modified date of yesterday?
- 4D.9 While in the middle of a large "commit", how do I run other
- commands, like "diff" or "stat" without seeing lock errors?
- 4D.10 Where did the ./CVS/Entries.Static file come from? What is it for?
- 4D.11 Why did I get the wrong Repository in the loginfo message?
- 4D.12 How do I run CVS setuid so I can only allow access through the
- CVS program itself?
- 4D.13 How about using groups and setgid() then?
- 4D.14 How do I use the "commitinfo" file?
- 4D.15 How do I use the "loginfo" files?
- 4D.16 How can I keep people with restrictive umask values from blocking
- access to the Repository?
- 4D.17 Why do timestamps sometimes get set to the date of the revision,
- sometimes not? The inconsistency causes unnecessary recompiles.
-
-----------------
--- Section 4E -- Internal errors
-----------------
- 4E.1 Explain: "ci error: unexpected EOF in diff output"
- 4E.2 Explain: "RCS file /Repository/module/file.c,v is in use"
- 4E.3 Explain: "co error, line 2: Missing access list"
- 4E.4 Explain: "error: RCS file name `xyz .c' contains white space"
- 4E.5 Explain: cvs checkout: warning: <X> is not (any longer) pertinent
- 4E.6 Why did a Repository file change from <file>,v to ,<file>,?
-
-----------------
--- Section 4F -- Related Software
-----------------
- 4F.1 How do I use CVS under Emacs? Is there an Emacs cvs-mode?
- 4F.2 What is GIC (Graphical Interface to CVS)?
- 4F.3 What is CAVEMAN?
-
-----------------
--- Section 4G -- Engineering
-----------------
- 4G.1 Where can I find out about Software Engineering?
- 4G.2 How do I flexibly arrange the modules file to describe my sources?
- 4G.3 Can I have multiple source repositories, one for each project?
- 4G.4 Who should administer the Repository and manage the modules file?
- 4G.5 Isn't disk space a big factor? CVS copies files out of the
- Repository, duplicating everything.
-
-----------------
--- Section 4H -- Other Systems
-----------------
- 4H.1 I use a NeXT. Is there anything I need to know?
- 4H.2 I use OS/2 and/or DOS. Is there anything I need to know?
- 4H.3 I use SCO Unix. Is there anything I need to know?
- 4H.4 I use AIX. Is there anything I need to know?
- 4H.5 I use IRIX. Is there anything I need to know?
- 4H.6 I use an HP system. Is there anything I need to know?
- 4H.7 I use AFS. Is there anything I need to know?
- 4H.8 I use A/UX. Is there anything I need to know?
-
-
-=============================================
-== Section 5 ==== Past & Future ====
-=============================================
-
-----------------
--- Section 5A -- Contributors
-----------------
-=5A.1 Who wrote CVS?
- 5A.2 You didn't write all of this FAQ, did you?
-
-----------------
--- Section 5B -- Bugs and Patches
-----------------
- 5B.1 Why can't CVS handle deletion of directories?
- 5B.2 Why can't CVS handle the moving of sources from one place in the
- directory hierarchy to another?
- 5B.3 When I typed "cvs update -D <date>", why did it check out all
- sorts of ancient files from the Attic? Shouldn't it just create
- the set of files and revisions that existed at that date?
- 5B.4 When I typed "cvs update -D <date>" in my branch, why did it
- screw up all my files?
- 5B.5 When I executed "checkout" into an existing directory I got "No
- such file or directory" errors. Why?
- 5B.6 Why does "update" send all output to the terminal after 26 files
- have been updated?
- 5B.7 Why does the merge occasionally resurrect lines of code?
- 5B.8 Why does the merge fail when my "rcsmerge" program is
- configured to use GNU diff version 2.1 or later?
-
-----------------
--- Section 5C -- Development
-----------------
- 5C.1 Where do I send bug reports?
- 5C.2 Where do I send fixes and patches?
- 5C.3 Where do I send ideas for future development?
-=5C.4 What plans are there for new features?
- 5C.5 I have some time and I'd like to help. What can I do for you?
-
-----------------
--- Section 5D -- Professional Support
-----------------
-+5D.1 Doesn't Cygnus support CVS?
-+5D.2 What is Cyclic Software doing with CVS?
-
-
-=================================================
-== Section 6 ==== Table of Contents ====
-=================================================
-
-% End of Table of Contents
-% End of CVS FAQ document
-
-# Local Variables:
-# mode: text
-# fill-column: 74
-# fill-prefix: "\t"
-# End:
diff --git a/gnu/usr.bin/cvs/INSTALL b/gnu/usr.bin/cvs/INSTALL
deleted file mode 100644
index 898af66c1c1e..000000000000
--- a/gnu/usr.bin/cvs/INSTALL
+++ /dev/null
@@ -1,356 +0,0 @@
-#ident "$CVSid$"
-
-First, read the README file. If you're still happy...
-
-CVS has been tested on the following platforms. The most recent
-version of CVS reported to have been tested is indicated, but more
-recent versions of CVS probably will work too. Please send updates to
-this list to info-cvs@prep.ai.mit.edu.
-
-Alpha:
- DEC Alpha running OSF/1 version 1.3 using cc (about 1.4A2)
- DEC Alpha running OSF/1 version 2.0 (1.4.90)
- DEC Alpha running OSF/1 version 2.1 (about 1.4A2)
- DEC Alpha running OSF/1 version 3.0 (1.5.95) (footnote 7)
-HPPA:
- HP 9000/710 running HP-UX 8.07A using gcc (about 1.4A2)
- HP 9000/715 running HP-UX 9.01 (1.6)
- HPPA 1.1 running HP-UX A.09.03 (1.5.95) (footnote 8)
- NextSTEP 3.3 (1.4.92, a few tweaks needed)
-i386 family:
- Gateway P5-66 (pentium) running Solaris 2.4 using gcc (about 1.4A2)
- PC Clone running UnixWare v1.1.1 using gcc (about 1.4A2)
- PC Clone running ISC 4.0.1 (1.5.94)
- PC Clone running Fintronic Linux 1.2.5 (1.5)
- PC Clone running BSDI 2.0 (1.4.93) (footnote 5)
- PC Clone running Windows NT 3.51 (1.6.2 client-only)
- FreeBSD 2.0.5, i486, gcc (1.5.95)
- NextSTEP 3.3 (1.4.92, a few tweaks needed)
- SCO Unix 3.2.4.2 (1.4.93) (footnote 4)
- SCO OpenServer 5.0.0, "CC='cc -b elf' configure"
-m68k:
- Sun 3 running SunOS 4.1.1_U1 w/ bundled K&R /usr/5bin/cc (1.6)
- NextSTEP 3.3 (1.4.92, a few tweaks needed)
-m88k:
- Data General AViiON running dgux 5.4R2.10 (1.5)
- Harris Nighthawk 5800 running CX/UX 7.1 (1.5) (footnote 6)
-MIPS:
- DECstation running Ultrix 4.2a (1.4.90)
- DECstation running Ultrix 4.3 (1.5)
- SGI running Irix 4.0.5H using gcc and cc (about 1.4A2) (footnote 2)
- SGI running Irix 5.3 (1.4.93)
- SGI running Irix-6 (about 1.4.90) (footnote 3)
- Siemens-Nixdorf RM600 running SINIX-Y (1.6)
-PowerPC or RS/6000:
- IBM RS/6000 running AIX 3.2.5 (cc=xlc, CVS 1.5)
- IBM RS/6000 running AIX 4.1 using gcc and cc (about 1.4A2) (footnote 1)
-SPARC:
- Sun SPARC running SunOS 4.1.4 w/ bundled K&R /usr/5bin/cc (1.6)
- Sun SPARC running SunOS 4.1.3, 4.1.2, and 4.1.1 (1.5)
- Sun SPARC running SunOS 4.1.3, w/ bundled K&R cc (1.5.94)
- Sun SPARCstation 10 running Solaris 2.3 using gcc and cc (about 1.4A2)
- Sun SPARCstation running Solaris 2.4 using gcc and cc (about 1.5.91)
- Sun SPARC running Solaris 2.5 (2.5 beta?) (1.6.2)
- NextSTEP 3.3 (1.4.92, a few tweaks needed)
-
-(footnote 1)
- AIX 4.1 systems fail to run "configure" due to bugs in their
- "/bin/sh" implementation. You might want to try feeding the
- configure script to "bash" ported to AIX 4.1. (about 1.4A2).
-
-(footnote 2)
- Some Irix 4.0 systems may core dump in malloc while running
- CVS. We believe this is a bug in the Irix malloc. You can
- workaround this bug by linking with "-lmalloc" if necessary.
- (about 1.4A2).
-
-(footnote 3)
- There are some warnings about pointer casts which can safely be
- ignored. (about 1.4.90).
-
-(footnote 4) Comment out the include of sys/time.h in src/server.c. (1.4.93)
- You also may have to make sure TIME_WITH_SYS_TIME is undef'ed.
-
-(footnote 5) Change /usr/tmp to /var/tmp in src/server.c (2 places) (1.4.93).
-
-(footnote 6) Build in ucb universe with COFF compiler tools. Put
- /usr/local/bin first in PATH while doing a configure, make
- and install of GNU diffutils-2.7, rcs-5.7, then cvs-1.5.
-
-(footnote 7) Manoj Srivastava <srivasta@pilgrim.umass.edu> reports
- success with this configure command:
- CC=cc CFLAGS='-O2 -Olimit 2000 -std1' ./configure --verbose alpha-dec-osf
-
-(footnote 8) Manoj Srivastava <srivasta@pilgrim.umass.edu> reports
- success with this configure command:
- CC=cc CFLAGS='+O2 -Aa -D_HPUX_SOURCE' ./configure --verbose hppa1.1-hp-hpux
-
--------------------------------------------------------------------------------
-
-Installation under Unix:
-
-1) Run "configure":
-
- $ ./configure
-
- You can specify an alternate destination to override the default with
- the --prefix option:
-
- $ ./configure --prefix=/usr/local/gnu
-
- or some path that is more appropriate for your site. The default prefix
- value is "/usr/local", with binaries in sub-directory "bin", manual
- pages in sub-directory "man", and libraries in sub-directory "lib".
-
- This release of CVS also requires RCS commands to be installed in
- the user's PATH (or a path you have configured in src/options.h).
- If you don't have RCS, you will need to get it from GNU as well. It
- is best to get the version 5.7 (or later) version of RCS, available
- from prep.ai.mit.edu in the file pub/gnu/rcs-5.7.tar.gz. It is best
- (although not essential) to avoid RCS versions 5.6.[5-7] beta
- because the rcsmerge therein defaults to -A instead of -E which
- affects the way CVS handles conflicts (this is fixed in RCS 5.6.8
- and RCS 5.7).
-
- Along with RCS, you will want to run GNU diffutils. This will allow
- revision control of files with binary data (a real nice feature).
- You will need at least version 1.15 of GNU diff for this to work.
- The current version of GNU diffutils is 2.7, and it is also
- available from prep.ai.mit.edu in the file pub/gnu/diffutils-2.7.tar.gz.
-
- WARNING: Be sure that you (have) configure(d) RCS to work correctly
- with GNU diff to avoid other configuration problems.
-
- Configure will attempt to discern the location of your most capable
- version of diff, and tries to find the GNU Diffutils version first.
- You can explicitly tell configure to use the diffutils that's
- installed in the same place you intend to install CVS:
-
- $ ./configure --with-diffutils
-
- Or, if you've installed it somewhere else, you can give configure
- the full pathname:
-
- $ ./configure --with-diffutils=/usr/gnu/bin/diff
-
- Configure will also try to find a version of grep that supports the
- '-s' option, and tries to find the GNU Grep version first. You can
- similarly tell it where to find GNU Grep:
-
- $ ./configure --with-gnugrep
- $ ./configure --with-gnugrep=/usr/gnu/bin/grep
-
- If you are using the remote client, you will need a version of patch
- which understands unidiffs (such as any recent version of GNU
- patch). Configure does not yet check to see if you've got this, so
- be careful!
-
- NOTE: The configure program will cache the results of the previous
- configure execution. If you need to re-run configure from scratch, you
- may need to run "make distclean" first to remove the cached
- configuration information.
-
- Try './configure --help' for further information on its usage.
-
- NOTE ON CVS's USE OF NDBM:
-
- By default, CVS uses some built-in ndbm emulation code to allow
- CVS to work in a heterogeneous environment. However, if you have
- a very large modules database, this may not work well. You will
- need to edit src/options.h to turn off the MY_NDBM #define and
- re-run configure. If you do this, the following comments apply.
- If not, you may safely skip these comments.
-
- If you configure CVS to use the real ndbm(3) libraries and
- you do not have them installed in a "normal" place, you will
- probably want to get the GNU version of ndbm (gdbm) and install
- that before running the CVS configure script. Be aware that the
- GDBM 1.5 release does NOT install the <ndbm.h> header file included
- with the release automatically. You may have to install it by hand.
-
- If you configure CVS to use the ndbm(3) libraries, you cannot
- compile CVS with GNU cc (gcc) on Sun-4 SPARC systems. However, gcc
- 2.0 may have fixed this limitation if -fpcc-struct-return is
- defined. When using gcc on other systems to compile CVS, you *may*
- need to specify the -fpcc-struct-return option to gcc (you will
- *know* you have to if "cvs checkout" core dumps in some ndbm
- function). You can do this as follows:
-
- $ CC='gcc -fpcc-struct-return' ./configure
-
- for sh, bash, and ksh users and:
-
- % setenv CC 'gcc -fpcc-struct-return'
- % ./configure
-
- for csh and tcsh users.
-
- END OF NOTE FOR NDBM GUNK.
-
-2) Edit src/options.h. Appropriate things to look at may be the
- invocation locations of programs like DIFF, GREP, RM, and SORT.
- Also glance at the default values for the environment variables
- that CVS uses, in particular, the RCSBIN variable, which holds the
- path to where the RCS programs live on your system. The
- likelihood is that you don't have to change anything here, except
- perhaps adding the -a option to DIFF if you are using GNU diff.
-
-3) Try to build it:
-
- $ make
-
- This will (hopefully) make the needed CVS binaries within the "src"
- directory. If something fails for your system, using the "cvsbug"
- script submit your "config.status" file together with your host
- type, operating system and compiler information, make output, and
- anything else you think will be helpful.
-
- You may also wish to validate the correctness of the new binary by
- running the regression tests:
-
- $ make check
-
- Note that if your /bin/sh doesn't support shell functions, you'll
- have to try something like this, where "/bin/sh5" is replaced by the
- pathname of a shell which handles normal shell functions:
-
- $ make SHELL=/bin/sh5 check
-
- WARNING: This test can take quite a while to run, esp. if your
- disks are slow or over-loaded.
-
- If you receive any un-expected output from the regression tests,
- using the "cvsbug" script please submit your "config.status" file,
- together with your host type, operating system and compiler
- information, the contents of /tmp/cvs-sanity/check.log, and any
- "make check" output.
-
-4) Install the binaries/documentation:
-
- $ make install
-
- Depending on your installation's configuration, you may need to be
- root to do this.
-
-5) Take a look at the CVS documentation.
-
- $ man cvs
-
- and
-
- $ info cvs
-
- See what it can do for you, and if it fits your environment (or can
- possibly be made to fit your environment). If things look good,
- continue on...
-
-6) Setup the master source repository. Choose a directory with ample disk
- space available for source files. This is where the RCS ",v" files
- will be stored. Note that this should be some shared directory for your
- site. It should probably be auto-mounted, if you're running NFS.
-
- Say you choose "/src/master" as the root of your source repository.
- Run the "cvsinit" script to help you set it up. It will ask you to
- enter the path to your CVSROOT area. You would enter /src/master in
- this example.
-
- $ ./cvsinit
-
- The cvsinit script will setup a reasonable CVSROOT area to start with.
- It is also valuable to folks who already have a CVSROOT area setup from
- using earlier releases of CVS. It assumes that you have installed CVS
- already (step 4) and that the RCS programs (co and ci) are in your
- PATH. There are many ways to customize CVS for your site. Read the
- cvs(5) manual page when you get the chance.
-
-7) Have all users of the CVS system set the CVSROOT environment
- variable appropriately to reflect the placement of your source
- repository. If the above example is used, the following commands
- can be placed in user's ~/.profile, ~/.bash_profile file; or in the
- site-wide /etc/profile:
-
- CVSROOT=/src/master; export CVSROOT
-
- for sh/bash/ksh users, or place the following commands in the user's
- ~/.cshrc, ~/.login, or /etc/chsrc file:
-
- setenv CVSROOT /src/master
-
- for csh/tcsh users. If these environment variables are not already set
- in your current shell, set them now (or source the login script you
- just edited). You will need to have the CVSROOT environment variable
- set to continue on to the next step.
-
-8) It might be a good idea to jump right in and put the CVS distribution
- directly under CVS control. From within the top-level directory of the
- CVS distribution (the one that contains this README file) do the
- following commands:
-
- $ make distclean
- $ cvs import -m 'CVS 1.6 distribution' cvs CVS CVS-1_6
-
-9) Having done step 8, one should be able to checkout a fresh copy of the
- CVS distribution and hack away at the sources with the following command:
-
- $ cd
- $ cvs checkout cvs
-
- This will make the directory "cvs" in your current directory and
- populate it with the appropriate CVS files and directories.
-
-10) Remember to edit the modules file manually when sources are checked in
- with "cvs import" or "cvs add". A copy of the modules file for editing
- can usually be retrieved with the "cvs checkout modules" command, and
- definitely with the "cvs checkout CVSROOT" command. See cvs(5).
-
-11) Read the NEWS file to see what's new.
-
-12) Hack away.
-
--------------------------------------------------------------------------------
-
-Detailed information about your interaction with "configure":
-
-The "configure" script and its interaction with its options and the
-environment is described here. For more detailed documentation about
-"configure", please refer to the GNU Autoconf documentation.
-
-Supported options are:
-
- --srcdir=DIR Useful for compiling on many different
- machines sharing one source tree.
- --prefix=DIR The root of where to install the
- various pieces of CVS (/usr/local).
- --exec_prefix=DIR If you want executables in a
- host-dependent place and shared
- things in a host-independent place.
- --with-diffutils[=PATH] Assume use of GNU diffutils is possible.
- --with-gnugrep[=PATH] Assume use of GNU grep is possible.
-
-The following environment variables override configure's default
-behaviour:
-
- CC If not set, tries to use gcc first,
- then cc. Also tries to use "-g -O"
- as options, backing down to -g
- alone if that doesn't work.
- INSTALL If not set, tries to use "install", then
- "./install-sh" as a final choice.
- RANLIB If not set, tries to determine if "ranlib"
- is available, choosing "echo" if it doesn't
- appear to be.
- YACC If not set, tries to determine if "bison"
- is available, choosing "yacc" if it doesn't
- appear to be.
-
--------------------------------------------------------------------------------
-Installation under Windows NT:
-
-You may find interesting information in windows-NT/README.
-
-1) Using Microsoft Visual C++ version 2.1, open the project `cvsnt.mak',
- in the top directory of the CVS distribution.
-2) Choose "Build cvs.exe" from the "Project" menu.
-3) MSVC will place the executable file cvs.exe in WinDebug, or whatever
- your target directory is.
--------------------------------------------------------------------------------
diff --git a/gnu/usr.bin/cvs/MINOR-BUGS b/gnu/usr.bin/cvs/MINOR-BUGS
deleted file mode 100644
index 7b857193f86b..000000000000
--- a/gnu/usr.bin/cvs/MINOR-BUGS
+++ /dev/null
@@ -1,60 +0,0 @@
-Low-priority bugs go here. We don't have many yet -- everything is
-high-priority at the moment. :-)
-
-
-* From: Jeff Johnson <jbj@brewster.JBJ.ORG>
- To: cyclic-cvs@cyclic.com
- Subject: Named_Root assumes . on server
- Date: Wed, 17 May 1995 11:04:53 -0400 (EDT)
-
- Problem:
- On server, Name_Root() attempts (aggressively) to set CVSADM_Root.
- If ~/CVS/Root exists (wrto rsh login), then CVSADM_Root will be
- initialized from that file. The sanity check between the root
- repository and the invocation will fail if the two values are not
- coincidentally the same.
-
- Workaround:
- There's a zillion ways to fix this bugture/featurelet. My current
- workaround is to remove ~/CVS/Root on the server. I shall attempt
- a better fix as soon as I can determine what appears politically
- correct. IMHO, the CVS/Root stuff (and getenv("CVSROOT") also) is
- a bit fragile and tedious in an rcmd() driven CCVS environment.
-
-
-* (Jeff Johnson <jbj@jbj.org>)
- I tried a "cvs status -v" and received the following:
-
- ? CVS
- ? programs/CVS
- ? tests/CVS
- cvs server: Examining .
- ===================================================================
- File: Install.dec Status: Up-to-date
- ...
-
- I claim that CVS dirs should be ignored.
-
-
-* I sometimes get this message:
-
- Could not look up address for your host. Permission denied.
- cvs [update aborted]: premature end of file from server
-
- The client's response should be cleaned up.
-
-* In the gb-grep module, update-ChangeLog (and therefore, I assume,
- rcs2log) truncates file names --- I get entries for things called
- ring/lenstring.h instead of lenstring/lenstring.h.
-
-* On remote checkout, files don't have the right time/date stamps in
- the CVS/Entries files. Doesn't look like the C/S protocol has any
- way to send this information along (according to cvsclient.texi).
- Perhaps we can spiff it up a bit by using the conflict field for the
- stamp on the checkout/update command. Please note that this really
- doesn't do very much for us even if we get it done.
-
-* Does the function that lists the available modules in the repository
- belong under the "checkout" function? Perhaps it is more logically
- grouped with the "history" function or we should create a new "info"
- function?
diff --git a/gnu/usr.bin/cvs/Makefile b/gnu/usr.bin/cvs/Makefile
deleted file mode 100644
index d75858bc1e59..000000000000
--- a/gnu/usr.bin/cvs/Makefile
+++ /dev/null
@@ -1,3 +0,0 @@
-SUBDIR = lib cvs mkmodules
-
-.include <bsd.subdir.mk>
diff --git a/gnu/usr.bin/cvs/NEWS b/gnu/usr.bin/cvs/NEWS
deleted file mode 100644
index 89658192e2b0..000000000000
--- a/gnu/usr.bin/cvs/NEWS
+++ /dev/null
@@ -1,863 +0,0 @@
-Changes since 1.6:
-
-* RCS keyword "Name" supported for "cvs update -r <tag>" and "cvs
-checkout -r <tag>".
-
-* If there is a group whose name matches a compiled in value which
-defaults to "cvsadmin", only members of that group can use "cvs
-admin".
-
-* CVS now sets the modes of files in the repository based on the
-CVSUMASK environment variable or a compiled in value defaulting to
-002. This way other developers will be able to access the files in
-the repository regardless of the umask of the developer creating them.
-
-* The command name .cvsrc now matches the official name of the
-command, not the one (possibly an alias) by which it was invoked. If
-you had previously relied on "cvs di" and "cvs diff" using different
-options, instead use a shell function or alias (for example "alias
-cvsdi='cvs diff -u'").
-
-Changes from 1.5 to 1.6:
-
-* Del updated the man page to include all of the new features
-of CVS 1.6.
-
-* "cvs tag" now supports a "-r | -D" option for tagging an already
-tagged revision / specific revision of a file.
-
-* There is a "taginfo" file in CVSROOT that supports filtering and
-recording of tag operations.
-
-* Long options support added, including --help and --version options.
-
-* "cvs release" no longer cares whether or not the directory being
-released has an entry in the `modules' file.
-
-* The modules file now takes a -e option which is used instead of -o
-for "cvs export". If your modules file has a -o option which you want
-to be used for "cvs export", change it to specify -e as well as -o.
-
-* "cvs export" now takes a -k option to set RCS keyword expansion.
-This way you can export binary files. If you want the old behavior,
-you need to specify -kv.
-
-* "cvs update", "cvs rdiff", "cvs checkout", "cvs import", "cvs
-release", "cvs rtag", and "cvs tag" used to take -q and -Q options
-after the command name (e.g. "cvs update -q"). This was confusing
-because other commands, such as "cvs ci", did not. So the options
-after the command name have been removed and you must now specify, for
-example, "cvs -q update", which has been supported since CVS 1.3.
-
-* New "wrappers" feature. This allows you to set a hook which
-transforms files on their way in and out of cvs (apparently on the
-NeXT there is some particular usefulness in tarring things up in the
-repository). It also allows you to declare files as merge-by-copy
-which means that instead of trying to merge the file, CVS will merely
-copy the new version. There is a CVSROOT/cvswrappers file and an
-optionsl ~/.cvswrappers file to support this feature.
-
-* You can set CVSROOT to user@host:dir, not just host:dir, if your
-username on the server host is different than on the client host.
-
-* VISUAL is accepted as well as EDITOR.
-
-* $CVSROOT is expanded in *info files.
-
-Changes from 1.4A2 to 1.5:
-
-* Remote implementation. This is very helpful when collaborating on a
-project with someone across a wide-area network. This release can
-also be used locally, like other CVS versions, if you have no need for
-remote access.
-
-Here are some of the features of the remote implementation:
-- It uses reliable transport protocols (TCP/IP) for remote repository
- access, not NFS. NFS is unusable over long distances (and sometimes
- over short distances)
-- It transfers only those files that have changed in the repository or
- the working directory. To save transmission time, it will transfer
- patches when appropriate, and can compress data for transmission.
-- The server never holds CVS locks while waiting for a reply from the client;
- this makes the system robust when used over flaky networks.
-
-The remote features are documented in doc/cvsclient.texi in the CVS
-distribution, but the main doc file, cvs.texinfo, has not yet been
-updated to include the remote features.
-
-* Death support. See src/README-rm-add for more information on this.
-
-* Many speedups, especially from jtc@cygnus.com.
-
-* CVS 1.2 compatibility code has been removed as a speedup. If you
-have working directories checked out by CVS 1.2, CVS 1.3 or 1.4A2 will
-try to convert them, but CVS 1.5 and later will not (if the working
-directory is up to date and contains no extraneous files, you can just
-remove it, and then check out a new working directory). Likewise if
-your repository contains a CVSROOT.adm directory instead of a CVSROOT
-directory, you need to rename it.
-
-Fri Oct 21 20:58:54 1994 Brian Berliner <berliner@sun.com>
-
- * Changes between CVS 1.3 and CVS 1.4 Alpha-2
-
- * A new program, "cvsbug", is provided to let you send bug reports
- directly to the CVS maintainers. Please use it instead of sending
- mail to the info-cvs mailing list. If your build fails, you may
- have to invoke "cvsbug" directly from the "src" directory as
- "src/cvsbug.sh".
-
- * A new User's Guide and Tutorial, written by Per Cederqvist
- <ceder@signum.se> of Signum Support. See the "doc" directory. A
- PostScript version is included as "doc/cvs.ps".
-
- * The Frequesntly Asked Questions file, FAQ, has been added to the
- release. Unfortunately, its contents are likely out-of-date.
-
- * The "cvsinit" shell script is now installed in the $prefix/bin
- directory like the other programs. You can now create new
- CVS repositories with great ease.
-
- * Index: lines are now printed on output from 'diff' and 'rdiff',
- in order to facilitate application of patches to multiple subdirs.
-
- * Support for a ~/.cvsrc file, which allows you to specify options
- that are always supposed to be given to a specific command. This
- feature shows the non-orthogonality of the option set, since while
- there may be an option to turn something on, the option to turn
- that same thing off may not exist.
-
- * You can now list subdirectories that you wish to ignore in a
- modules listing, such as:
-
- gcc -a gnu/gcc, !gnu/gcc/testsuites
-
- which will check out everything underneath gnu/gcc, except
- everything underneath gnu/gcc/testsuites.
-
- * It is now much harder to accidentally overwrite an existing tag
- name, since attempting to move a tag name will result in a error,
- unless the -F (force) flag is given to the tag subcommands.
-
- * Better error checking on matching of the repository used to
- check code out from against the repository the current cvs
- commnands would use. (Thanks to Mark Baushke <mdb@cisco.com>)
-
- * Better support for sites with multiple CVSROOT repositories has
- been contributed. The file "CVS/Root" in your working directory
- is created to hold the full path to the CVS repository and a
- simple check is made against your current CVSROOT setting.
-
- * You can now specify an RCS keyword substitution value when you
- import files into the repository.
-
- * Uses a much newer version of Autoconf, and conforms to the GNU
- coding standards much more closely. No, it still doesn't have
- long option names.
-
- * Code cleanup. Many passes through gcc -Wall helped to identify
- a number of questionable constructs. Most arbitrary length limits
- were removed.
-
- * Profiling to determine bottlenecks helped to identify the best
- places to spend time speeding up the code, which was then done. A
- number of performance enhancements in filename matching have sped
- up checkouts.
-
- * Many more contributions have been added to the "contrib"
- directory. See the README file in that directory for more
- information.
-
- * "cvs commit" will try harder to not change the file's
- modification time after the commit. If the file does not change
- as a result of the commit operation, CVS will preserve the
- original modification time, thus speeding up future make-type
- builds.
-
- * "cvs commit" now includes any removed files in the (optional)
- pre-commit checking program that may be invoked. Previously, only
- added and modified files were included.
-
- * It is now possible to commit a file directly onto the trunk at a
- specific revision level by doing "cvs commit -r3.0 file.c", where
- "3.0" specifies the revision you wish to create. The file must be
- up-to-date with the current head of the trunk for this to succeed.
-
- * "cvs commit" will now function with a pre-commit program that
- has arguments specified in the "commitinfo" file.
-
- * The "mkmodules" program will now look within the
- $CVSROOT/CVSROOT/checkoutlist" file for any additional files that
- should be automatically checked out within CVSROOT; mkmodules also
- tries harder to preserve any execute bits the files may have
- originally had.
-
- * "cvs diff" is much more accurate about its exit status now. It
- now returns the maximum exit status of any invoked diff.
-
- * The "-I !" option is now supported for the import and update
- commands correctly. It will properly clear the ignore list now.
-
- * Some problems with "cvs import" handling of .cvsignore have been
- fixed; as well, some rampant recursion problems with import have
- also been fixed.
-
- * "cvs rdiff" (aka "cvs patch") now tries to set the modify time
- of any temporary files it uses to match those specified for the
- particular revision. This allows a more accurate patch image to
- be created.
-
- * "cvs status" has improved revision descriptions. "Working
- revision" is used for the revision of the working file that you
- edit directly; "Repository revision" is the revision of the file
- with the $CVSROOT source repository. Also, the output is clearer
- with regard to sticky and branch revisions.
-
- * CVS no longer dumps core when given a mixture of directories and
- files in sub-directories (as in "cvs ci file1 dir1/file2").
- Instead, arguments are now clumped into their respective directory
- and operated on in chunks, together.
-
- * If the CVSEDITOR environment variable is set, that editor is
- used for log messages instead of the EDITOR environment variable.
- This makes it easy to substitute intelligent programs to make more
- elaborate log messages. Contributed by Mark D Baushke
- (mdb@cisco.com).
-
- * Command argument changes:
- cvs: The "-f" option has been added to ignore
- the ~/.cvsrc file.
- commit: Renamed the "-f logfile" option to the
- "-F logfile" option. Added the "-f"
- option to force a commit of the specified
- files (this disables recursion).
- history: Added "-t timezone" option to force any
- date-specific output into the specified
- timezone.
- import: Added "-d" option to use the file's
- modification time as the time of the
- import. Added "-k sub" option to set the
- default RCS keyword substitution mode for
- newly-created files.
- remove: Added "-f" option to force the file's
- automatic removal if it still exists in
- the working directory (use with caution).
- rtag: Added "-F" option to move the tag if it
- already exists -- new default is to NOT
- move tags automatically.
- tag: Added "-F" option to move the tag if it
- already exists -- new default is to NOT
- move tags automatically.
-
-Tue Apr 7 15:55:25 1992 Brian Berliner (berliner at sun.com)
-
- * Changes between CVS 1.3 Beta-3 and official CVS 1.3!
-
- * A new shell script is provided, "./cvsinit", which can be run at
- install time to help setup your $CVSROOT area. This can greatly
- ease your entry into CVS usage.
-
- * The INSTALL file has been updated to include the machines on
- which CVS has compiled successfully. I think CVS 1.3 is finally
- portable. Thanks to all the Beta testers!
-
- * Support for the "editinfo" file was contributed. This file
- (located in $CVSROOT/CVSROOT) can be used to specify a special
- "editor" to run on a per-directory basis within the repository,
- instead of the usual user's editor. As such, it can verify that
- the log message entered by the user is of the appropriate form
- (contains a bugid and test validation, for example).
-
- * The manual pages cvs(1) and cvs(5) have been updated.
-
- * The "mkmodules" command now informs you when your modules file
- has duplicate entries.
-
- * The "add" command now preserves any per-directory sticky tag when
- you add a new directory to your checked-out sources.
-
- * The "admin" command is now a fully recursive interface to the
- "rcs" program which operates on your checked-out sources. It no
- longer requires you to specify the full path to the RCS file.
-
- * The per-file sticky tags can now be effectively removed with
- "cvs update -A file", even if you had checked out the whole
- directory with a per-directory sticky tag. This allows a great
- deal of flexibility in managing the revisions that your checked-out
- sources are based upon (both per-directory and per-file sticky
- tags).
-
- * The "cvs -n commit" command now works, to show which files are
- out-of-date and will cause the real commit to fail, or which files
- will fail any pre-commit checks. Also, the "cvs -n import ..."
- command will now show you what it would've done without actually
- doing it.
-
- * Doing "cvs commit modules" to checkin the modules file will no
- properly run the "mkmodules" program (assuming you have setup your
- $CVSROOT/CVSROOT/modules file to do so).
-
- * The -t option in the modules file (which specifies a program to
- run when you do a "cvs rtag" operation on a module) now gets the
- symbolic tag as the second argument when invoked.
-
- * When the source repository is locked by another user, that user's
- login name will be displayed as the holder of the lock.
-
- * Doing "cvs checkout module/file.c" now works even if
- module/file.c is in the Attic (has been removed from main-line
- development).
-
- * Doing "cvs commit */Makefile" now works as one would expect.
- Rather than trying to commit everything recursively, it will now
- commit just the files specified.
-
- * The "cvs remove" command is now fully recursive. To schedule a
- file for removal, all you have to do is "rm file" and "cvs rm".
- With no arguments, "cvs rm" will schedule all files that have been
- physically removed for removal from the source repository at the
- next "cvs commit".
-
- * The "cvs tag" command now prints "T file" for each file that was
- tagged by this invocation and "D file" for each file that had the
- tag removed (as with "cvs tag -d").
-
- * The -a option has been added to "cvs rtag" to force it to clean
- up any old, matching tags for files that have been removed (in the
- Attic) that may not have been touched by this tag operation. This
- can help keep a consistent view with your tag, even if you re-use
- it frequently.
-
-Sat Feb 29 16:02:05 1992 Brian Berliner (berliner at sun.com)
-
- * Changes between CVS 1.3 Beta-2 and CVS 1.3 Beta-3
-
- * Many portability fixes, thanks to all the Beta testers! With any
- luck, this Beta release will compile correctly on most anything.
- Hey, what are we without our dreams.
-
- * CVS finally has support for doing isolated development on a
- branch off the current (or previous!) revisions. This is also
- extremely nice for generating patches for previously released
- software while development is progressing on the next release.
- Here's an example of creating a branch to fix a patch with the 2.0
- version of the "foo" module, even though we are already well into
- the 3.0 release. Do:
-
- % cvs rtag -b -rFOO_2_0 FOO_2_0_Patch foo
- % cvs checkout -rFOO_2_0_Patch foo
- % cd foo
- [[ hack away ]]
- % cvs commit
-
- A physical branch will be created in the RCS file only when you
- actually commit the change. As such, forking development at some
- random point in time is extremely light-weight -- requiring just a
- symbolic tag in each file until a commit is done. To fork
- development at the currently checked out sources, do:
-
- % cvs tag -b Personal_Hack
- % cvs update -rPersonal_Hack
- [[ hack away ]]
- % cvs commit
-
- Now, if you decide you want the changes made in the Personal_Hack
- branch to be merged in with other changes made in the main-line
- development, you could do:
-
- % cvs commit # to make Personal_Hack complete
- % cvs update -A # to update sources to main-line
- % cvs update -jPersonal_Hack # to merge Personal_Hack
-
- to update your checked-out sources, or:
-
- % cvs checkout -jPersonal_Hack module
-
- to checkout a fresh copy.
-
- To support this notion of forked development, CVS reserves
- all even-numbered branches for its own use. In addition, CVS
- reserves the ".0" and ".1" branches. So, if you intend to do your
- own branches by hand with RCS, you should use odd-numbered branches
- starting with ".3", as in "1.1.3", "1.1.5", 1.2.9", ....
-
- * The "cvs commit" command now supports a fully functional -r
- option, allowing you to commit your changes to a specific numeric
- revision or symbolic tag with full consistency checks. Numeric
- tags are useful for bringing your sources all up to some revision
- level:
-
- % cvs commit -r2.0
-
- For symbolic tags, you can only commit to a tag that references a
- branch in the RCS file. One created by "cvs rtag -b" or from
- "cvs tag -b" is appropriate (see below).
-
- * Roland Pesch <pesch@cygnus.com> and K. Richard Pixley
- <rich@cygnus.com> were kind enough to contribute two new manual
- pages for CVS: cvs(1) and cvs(5). Most of the new CVS 1.3 features
- are now documented, with the exception of the new branch support
- added to commit/rtag/tag/checkout/update.
-
- * The -j options of checkout/update have been added. The "cvs join"
- command has been removed.
-
- With one -j option, CVS will merge the changes made between the
- resulting revision and the revision that it is based on (e.g., if
- the tag refers to a branch, CVS will merge all changes made in
- that branch into your working file).
-
- With two -j options, CVS will merge in the changes between the two
- respective revisions. This can be used to "remove" a certain delta
- from your working file. E.g., If the file foo.c is based on
- revision 1.6 and I want to remove the changes made between 1.3 and
- 1.5, I might do:
-
- % cvs update -j1.5 -j1.3 foo.c # note the order...
-
- In addition, each -j option can contain on optional date
- specification which, when used with branches, can limit the chosen
- revision to one within a specific date. An optional date is
- specified by adding a colon (:) to the tag, as in:
-
- -jSymbolic_Tag:Date_Specifier
-
- An example might be what "cvs import" tells you to do when you have
- just imported sources that have conflicts with local changes:
-
- % cvs checkout -jTAG:yesterday -jTAG module
-
- which tells CVS to merge in the changes made to the branch
- specified by TAG in the last 24 hours. If this is not what is
- intended, substitute "yesterday" for whatever format of date that
- is appropriate, like:
-
- % cvs checkout -jTAG:'1 week ago' -jTAG module
-
- * "cvs diff" now supports the special tags "BASE" and "HEAD". So,
- the command:
-
- % cvs diff -u -rBASE -rHEAD
-
- will effectively show the changes made by others (in unidiff
- format) that will be merged into your working sources with your
- next "cvs update" command. "-rBASE" resolves to the revision that
- your working file is based on. "-rHEAD" resolves to the current
- head of the branch or trunk that you are working on.
-
- * The -P option of "cvs checkout" now means to Prune empty
- directories, as with "update". The default is to not remove empty
- directories. However, if you do "checkout" with any -r options, -P
- will be implied. I.e., checking out with a tag will cause empty
- directories to be pruned automatically.
-
- * The new file INSTALL describes how to install CVS, including
- detailed descriptions of interfaces to "configure".
-
- * The example loginfo file in examples/loginfo has been updated to
- use the perl script included in contrib/log.pl. The nice thing
- about this log program is that it records the revision numbers of
- your change in the log message.
-
- Example files for commitinfo and rcsinfo are now included in the
- examples directory.
-
- * All "#if defined(__STDC__) && __STDC__ == 1" lines have been
- changed to be "#if __STDC__" to fix some problems with the former.
-
- * The lib/regex.[ch] files have been updated to the 1.3 release of
- the GNU regex package.
-
- * The ndbm emulation routines included with CVS 1.3 Beta-2 in the
- src/ndbm.[ch] files has been moved into the src/myndbm.[ch] files
- to avoid any conflict with the system <ndbm.h> header file. If
- you had a previous CVS 1.3 Beta release, you will want to "cvs
- remove ndbm.[ch]" form your copy of CVS as well.
-
- * "cvs add" and "cvs remove" are a bit more verbose, telling you
- what to do to add/remove your file permanently.
-
- * We no longer mess with /dev/tty in "commit" and "add".
-
- * More things are quiet with the -Q option set.
-
- * New src/config.h option: If CVS_BADROOT is set, CVS will not
- allow people really logged in as "root" to commit changes.
-
- * "cvs diff" exits with a status of 0 if there were no diffs, 1 if
- there were diffs, and 2 if there were errors.
-
- * "cvs -n diff" is now supported so that you can still run diffs
- even while in the middle of committing files.
-
- * Handling of the CVS/Entries file is now much more robust.
-
- * The default file ignore list now includes "*.so".
-
- * "cvs import" did not expand '@' in the log message correctly. It
- does now. Also, import now uses the ignore file facility
- correctly.
-
- Import will now tell you whether there were conflicts that need to
- be resolved, and how to resolve them.
-
- * "cvs log" has been changed so that you can "log" things that are
- not a part of the current release (in the Attic).
-
- * If you don't change the editor message on commit, CVS now prompts
- you with the choice:
-
- !)reuse this message unchanged for remaining dirs
-
- which allows you to tell CVS that you have no intention of changing
- the log message for the remainder of the commit.
-
- * It is no longer necessary to have CVSROOT set if you are using
- the -H option to get Usage information on the commands.
-
- * Command argument changes:
- checkout: -P handling changed as described above.
- New -j option (up to 2 can be specified)
- for doing rcsmerge kind of things on
- checkout.
- commit: -r option now supports committing to a
- numeric or symbolic tags, with some
- restrictions. Full consistency checks will
- be done.
- Added "-f logfile" option, which tells
- commit to glean the log message from the
- specified file, rather than invoking the
- editor.
- rtag: Added -b option to create a branch tag,
- useful for creating a patch for a previous
- release, or for forking development.
- tag: Added -b option to create a branch tag,
- useful for creating a patch for a previous
- release, or for forking development.
- update: New -j option (up to 2 can be specified)
- for doing rcsmerge kind of things on
- update.
-
-Thu Jan 9 10:51:35 MST 1992 Jeff Polk (polk at BSDI.COM)
-
- * Changes between CVS 1.3 Beta-1 and CVS 1.3 Beta-2
-
- * Thanks to K. Richard Pixley at Cygnus we now have function
- prototypes in all the files
-
- * Some small changes to configure for portability. There have
- been other portability problems submitted that have not been fixed
- (Brian will be working on those). Additionally all __STDC__
- tests have been modified to check __STDC__ against the constant 1
- (this is what the Second edition of K&R says must be true).
-
- * Lots of additional error checking for forked processes (run_exec)
- (thanks again to K. Richard Pixley)
-
- * Lots of miscellaneous bug fixes - including but certainly not
- limited to:
- various commit core dumps
- various update core dumps
- bogus results from status with numeric sticky tags
- commitprog used freed memory
- Entries file corruption caused by No_Difference
- commit to revision broken (now works if branch exists)
- ignore file processing broken for * and !
- ignore processing didn't handle memory reasonably
- miscellaneous bugs in the recursion processor
- file descriptor leak in ParseInfo
- CVSROOT.adm->CVSROOT rename bug
- lots of lint fixes
-
- * Reformatted all the code in src (with GNU indent) and then
- went back and fixed prototypes, etc since indent gets confused. The
- rationale is that it is better to do it sooner than later and now
- everything is consistent and will hopefully stay that way.
- The basic options to indent were: "-bad -bbb -bap -cdb -d0 -bl -bli0
- -nce -pcs -cs -cli4 -di1 -nbc -psl -lp -i4 -ip4 -c41" and then
- miscellaneous formatting fixes were applied. Note also that the
- "-nfc1" or "-nfca" may be appropriate in files where comments have
- been carefully formatted (e.g, modules.c).
-
-Sat Dec 14 20:35:22 1991 Brian Berliner (berliner at sun.com)
-
- * Changes between CVS 1.2 and CVS 1.3 Beta are described here.
-
- * Lots of portability work. CVS now uses the GNU "configure"
- script to dynamically determine the features provided by your
- system. It probably is not foolproof, but it is better than
- nothing. Please let me know of any portability problems. Some
- file names were changed to fit within 14-characters.
-
- * CVS has a new RCS parser that is much more flexible and
- extensible. It should read all known RCS ",v" format files.
-
- * Most of the commands now are fully recursive, rather than just
- operating on the current directory alone. This includes "commit",
- which makes it real easy to do an "atomic" commit of all the
- changes made to a CVS hierarchy of sources. Most of the commands
- also correctly handle file names that are in directories other than
- ".", including absolute path names. Commands now accept the "-R"
- option to force recursion on (though it is always the default now)
- and the "-l" option to force recursion off, doing just "." and not
- any sub-directories.
-
- * CVS supports many of the features provided with the RCS 5.x
- distribution - including the new "-k" keyword expansion options. I
- recommend using RCS 5.x (5.6 is the current official RCS version)
- and GNU diff 1.15 (or later) distributions with CVS.
-
- * Checking out files with symbolic tags/dates is now "sticky", in
- that CVS remembers the tag/date used for each file (and directory)
- and will use that tag/date automatically on the next "update" call.
- This stickyness also holds for files checked out with the the new
- RCS 5.x "-k" options.
-
- * The "cvs diff" command now recognizes all of the rcsdiff 5.x
- options. Unidiff format is available by installing the GNU
- diff 1.15 distribution.
-
- * The old "CVS.adm" directories created on checkout are now called
- "CVS" directories, to look more like "RCS" and "SCCS". Old CVS.adm
- directories are automagically converted to CVS directories. The
- old "CVSROOT.adm" directory within the source repository is
- automagically changed into a "CVSROOT" directory as well.
-
- * Symbolic links in the source repository are fully supported ONLY
- if you use RCS 5.6 or later and (of course) your system supports
- symlinks.
-
- * A history database has been contributed which maintains the
- history of certain CVS operations, as well as providing a wide array
- of querying options.
-
- * The "cvs" program has a "-n" option which can be used with the
- "update" command to show what would be updated without actually
- doing the update, like: "cvs -n update". All usage statements
- have been cleaned up and made more verbose.
-
- * The module database parsing has been rewritten. The new format
- is compatible with the old format, but with much more
- functionality. It allows modules to be created that grab pieces or
- whole directories from various different parts of your source
- repository. Module-relative specifications are also correctly
- recognized now, like "cvs checkout module/file.c".
-
- * A configurable template can be specified such that on a "commit",
- certain directories can supply a template that the user must fill
- before completing the commit operation.
-
- * A configurable pre-commit checking program can be specified which
- will run to verify that a "commit" can happen. This feature can be
- used to restrict certain users from changing certain pieces of the
- source repository, or denying commits to the entire source
- repository.
-
- * The new "cvs export" command is much like "checkout", but
- establishes defaults suitable for exporting code to others (expands
- out keywords, forces the use of a symbolic tag, and does not create
- "CVS" directories within the checked out sources.
-
- * The new "cvs import" command replaces the deprecated "checkin"
- shell script and is used to import sources into CVS control. It is
- also much faster for the first-time import. Some algorithmic
- improvements have also been made to reduce the number of
- conflicting files on next-time imports.
-
- * The new "cvs admin" command is basically an interface to the
- "rcs" program. (Not yet implemented very well).
-
- * Signal handling (on systems with BSD or POSIX signals) is much
- improved. Interrupting CVS now works with a single interrupt!
-
- * CVS now invokes RCS commands by direct fork/exec rather than
- calling system(3). This improves performance by removing a call to
- the shell to parse the arguments.
-
- * Support for the .cvsignore file has been contributed. CVS will
- now show "unknown" files as "? filename" as the result of an "update"
- command. The .cvsignore file can be used to add files to the
- current list of ignored files so that they won't show up as unknown.
-
- * Command argument changes:
- cvs: Added -l to turn off history logging.
- Added -n to show what would be done without actually
- doing anything.
- Added -q/-Q for quiet and really quiet settings.
- Added -t to show debugging trace.
- add: Added -k to allow RCS 5.x -k options to be specified.
- admin: New command; an interface to rcs(1).
- checkout: Added -A to reset sticky tags/date/options.
- Added -N to not shorten module paths.
- Added -R option to force recursion.
- Changed -p (prune empty directories) to -P option.
- Changed -f option; forcing tags match is now default.
- Added -p option to checkout module to standard output.
- Added -s option to cat the modules db with status.
- Added -d option to checkout in the specified directory.
- Added -k option to use RCS 5.x -k support.
- commit: Removed -a option; use -l instead.
- Removed -f option.
- Added -l option to disable recursion.
- Added -R option to force recursion.
- If no files specified, commit is recursive.
- diff: Now recognizes all RCS 5.x rcsdiff options.
- Added -l option to disable recursion.
- Added -R option to force recursion.
- history: New command; displays info about CVS usage.
- import: Replaces "checkin" shell script; imports sources
- under CVS control. Ignores files on the ignore
- list (see -I option or .cvsignore description above).
- export: New command; like "checkout", but w/special options
- turned on by default to facilitate exporting sources.
- join: Added -B option to join from base of the branch;
- join now defaults to only joining with the top two
- revisions on the branch.
- Added -k option for RCS 5.x -k support.
- log: Supports all RCS 5.x options.
- Added -l option to disable recursion.
- Added -R option to force recursion.
- patch: Changed -f option; forcing tags match is now default.
- Added -c option to force context-style diffs.
- Added -u option to support unidiff-style diffs.
- Added -V option to support RCS specific-version
- keyword expansion formats.
- Added -R option to force recursion.
- remove: No option changes. It's a bit more verbose.
- rtag: Equivalent to the old "cvs tag" command.
- No option changes. It's a lot faster for re-tag.
- status: New output formats with more information.
- Added -l option to disable recursion.
- Added -R option to force recursion.
- Added -v option to show symbolic tags for files.
- tag: Functionality changed to tag checked out files
- rather than modules; use "rtag" command to get the
- old "cvs tag" behaviour.
- update: Added -A to reset sticky tags/date/options.
- Changed -p (prune empty directories) to -P option.
- Changed -f option; forcing tags match is now default.
- Added -p option to checkout module to standard output.
- Added -I option to add files to the ignore list.
- Added -R option to force recursion.
-
- Major Contributors:
-
- * Jeff Polk <polk@bsdi.com> rewrote most of the grody code of CVS
- 1.2. He made just about everything dynamic (by using malloc),
- added a generic hashed list manager, re-wrote the modules database
- parsing in a compatible - but extended way, generalized directory
- hierarchy recursion for virtually all the commands (including
- commit!), generalized the loginfo file to be used for pre-commit
- checks and commit templates, wrote a new and flexible RCS parser,
- fixed an uncountable number of bugs, and helped in the design of
- future CVS features. If there's anything gross left in CVS, it's
- probably my fault!
-
- * David G. Grubbs <dgg@odi.com> contributed the CVS "history" and
- "release" commands. As well as the ever-so-useful "-n" option of
- CVS which tells CVS to show what it would do, without actually
- doing it. He also contributed support for the .cvsignore file.
-
- * Paul Sander, HaL Computer Systems, Inc. <paul@hal.com> wrote and
- contributed the code in lib/sighandle.c. I added support for
- POSIX, BSD, and non-POSIX/non-BSD systems.
-
- * Free Software Foundation contributed the "configure" script and
- other compatibility support in the "lib" directory, which will help
- make CVS much more portable.
-
- * Many others have contributed bug reports and enhancement requests.
- Some have even submitted actual code which I have not had time yet
- to integrate into CVS. Maybe for the next release.
-
- * Thanks to you all!
-
-Wed Feb 6 10:10:58 1991 Brian Berliner (berliner at sun.com)
-
- * Changes from CVS 1.0 Patchlevel 1 to CVS 1.0 Patchlevel 2; also
- known as "Changes from CVS 1.1 to CVS 1.2".
-
- * Major new support with this release is the ability to use the
- recently-posted RCS 5.5 distribution with CVS 1.2. See below for
- other assorted bug-fixes that have been thrown in.
-
- * ChangeLog (new): Added Emacs-style change-log file to CVS 1.2
- release. Chronological description of changes between release.
-
- * README: Small fixes to installation instructions. My email
- address is now "berliner@sun.com".
-
- * src/Makefile: Removed "rcstime.h". Removed "depend" rule.
-
- * src/partime.c: Updated to RCS 5.5 version with hooks for CVS.
- * src/maketime.c: Updated to RCS 5.5 version with hooks for CVS.
- * src/rcstime.h: Removed from the CVS 1.2 distribution.
- Thanks to Paul Eggert <eggert@twinsun.com> for these changes.
-
- * src/checkin.csh: Support for RCS 5.5 parsing.
- Thanks to Paul Eggert <eggert@twinsun.com> for this change.
-
- * src/collect_sets.c (Collect_Sets): Be quieter if "-f" option is
- specified. When checking out files on-top-of other files that CVS
- doesn't know about, run a diff in the hopes that they are really
- the same file before aborting.
-
- * src/commit.c (branch_number): Fix for RCS 5.5 parsing.
- Thanks to Paul Eggert <eggert@twinsun.com> for this change.
-
- * src/commit.c (do_editor): Bug fix - fprintf missing argument
- which sometimes caused core dumps.
-
- * src/modules.c (process_module): Properly NULL-terminate
- update_dir[] in all cases.
-
- * src/no_difference.c (No_Difference): The wrong RCS revision was
- being registered in certain (strange) cases.
-
- * src/patch.c (get_rcsdate): New algorithm. No need to call
- maketime() any longer.
- Thanks to Paul Eggert <eggert@twinsun.com> for this change.
-
- * src/patchlevel.h: Increased patch level to "2".
-
- * src/subr.c (isdir, islink): Changed to compare stat mode bits
- correctly.
-
- * src/tag.c (tag_file): Added support for following symbolic links
- that are in the master source repository when tagging. Made tag
- somewhat quieter in certain cases.
-
- * src/update.c (update_process_lists): Unlink the user's file if it
- was put on the Wlist, meaning that the user's file is not modified
- and its RCS file has been removed by someone else.
-
- * src/update.c (update): Support for "cvs update dir" to correctly
- just update the argument directory "dir".
-
- * src/cvs.h: Fixes for RCS 5.5 parsing.
- * src/version_number.c (Version_Number): Fixes for parsing RCS 5.5
- and older RCS-format files.
- Thanks to Paul Eggert <eggert@twinsun.com> for these changes.
-
- * src/version_number.c (Version_Number): Bug fixes for "-f" option.
- Bug fixes for parsing with certain branch numbers. RCS
- revision/symbol parsing is much more solid now.
-
-Wed Feb 14 10:01:33 1990 Brian Berliner (berliner at sun.com)
-
- * Changes from CVS 1.0 Patchlevel 0 to CVS 1.0 Patchlevel 1; also
- known as "Changes from CVS 1.0 to CVS 1.1".
-
- * src/patch.c (get_rcsdate): Portability fix. Replaced call to
- timelocal() with call to maketime().
-
-Mon Nov 19 23:15:11 1990 Brian Berliner (berliner at prisma.com)
-
- * Sent CVS 1.0 release to comp.sources.unix moderator and FSF.
-
- * Special thanks to Dick Grune <dick@cs.vu.nl> for his work on the
- 1986 version of CVS and making it available to the world. Dick's
- version is available on uunet.uu.net in the
- comp.sources.unix/volume6/cvs directory.
-
-$CVSid: @(#)ChangeLog 1.35 94/10/22 $
diff --git a/gnu/usr.bin/cvs/PROJECTS b/gnu/usr.bin/cvs/PROJECTS
deleted file mode 100644
index de765760631e..000000000000
--- a/gnu/usr.bin/cvs/PROJECTS
+++ /dev/null
@@ -1,59 +0,0 @@
-This is a list of projects for CVS. In general, unlike the things in
-the TODO file, these need more analysis to determine if and how
-worthwhile each task is.
-
-I haven't gone through TODO, but it's likely that it has entries that
-are actually more appropriate for this list.
-
-0. Improved Efficency
-
-* CVS uses a single doubly linked list/hash table data structure for
- all of its lists. Since the back links are only used for deleting
- list nodes it might be beneficial to use singly linked lists or a
- tree structure. Most likely, a single list implementation will not
- be appropriate for all uses.
-
- One easy change would be to remove the "type" field out of the list
- and node structures. I have found it to be of very little use when
- debugging, and each instance eats up a word of memory. This can add
- up and be a problem on memory-starved machines.
-
- Profiles have shown that on fast machines like the Alpha, fsortcmp()
- is one of the hot spots.
-
-* Dynamically allocated character strings are created, copied, and
- destroyed throughout CVS. The overhead of malloc()/strcpy()/free()
- needs to be measured. If significant, it could be minimized by using a
- reference counted string "class".
-
-* File modification time is stored as a character string. It might be
- worthwile to use a time_t internally if the time to convert a time_t
- (from struct stat) to a string is greater that the time to convert a
- ctime style string (from the entries file) to a time_t. time_t is
- an machine-dependant type (although it's pretty standard on UN*X
- systems), so we would have to have different conversion routines.
- Profiles show that both operations are called about the same number
- of times.
-
-* stat() is one of the largest performance bottlenecks on systems
- without the 4.4BSD filesystem. By spliting information out of
- the filesystem (perhaps the "rename database") we should be
- able to improve performance.
-
-* Parsing RCS files is very expensive. This might be unnecessary if
- RCS files are only used as containers for revisions, and tag,
- revision, and date information was available in easy to read
- (and modify) indexes. This becomes very apparent with files
- with several hundred revisions.
-
-* A RCS "library", so CVS could operate on RCS files directly.
-
- CVS parses RCS files in order to determine if work needs to be done,
- and then RCS parses the files again when it is performing the work.
- This would be much faster if CVS could do whatever is necessary
- by itself.
-
-1. Improved testsuite/sanity check script
-
-* Need to use a code coverage tool to determine how much the sanity
- script tests, and fill in the holes.
diff --git a/gnu/usr.bin/cvs/README b/gnu/usr.bin/cvs/README
deleted file mode 100644
index b257f8944399..000000000000
--- a/gnu/usr.bin/cvs/README
+++ /dev/null
@@ -1,207 +0,0 @@
-$CVSid: @(#)README 1.32 94/10/22 $
-
- CVS Kit
-
- Copyright (c) 1993-1994 Brian Berliner
- Copyright (c) 1992 Brian Berliner and Jeff Polk
- Copyright (c) 1989-1992, Brian Berliner
- All Rights Reserved
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 1, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
--------------------------------------------------------------------------------
-
-Welcome to CVS!
-
-Bug reports are accepted, however note that someone may or may not
-feel like taking care of your bug report. Support contracts are
-available from Cyclic Software (http://www.cyclic.com).
-
-To report bugs send mail to bug-cvs@prep.ai.mit.edu, or run the "cvsbug"
-program and fill out the template:
-
- $ cvsbug
-
-The "cvsbug" program is installed in the same location as the "cvs"
-program. If your installation failed, you may need to run "cvsbug"
-directly out of the "src" directory as "src/cvsbug.sh".
-
-Please consult the INSTALL file for information on tested
-configurations. If you have a comment about an already tested
-configuration, or have tried CVS on a new configuration, please write
-to the above address and let us know! Free software only works if we
-all help out.
-
-Finally, we cannot guarantee that this release will not completely wipe out
-all of your work from your system. We do some simple testing before each
-release, but you are completely on your own. We recommend testing this
-release on a source repository that is not critical to your work. THIS
-SOFTWARE IS SUPPLIED COMPLETELY "AS IS". NO WARRANTY....
-
-Thanks for your support!
-
- -The CVS Team, and the Cyclic CVS Hackers
-
--------------------------------------------------------------------------------
-
-CVS is a freely available collection of programs that provide for software
-release and revision control functions in a UNIX environment. It is
-designed to work on top of the RCS distribution, V4 and later. CVS does
-understand how to parse older RCS formats, but cannot do any of the fancier
-features (like vendor branch support) without RCS branch support.
-
-Short blurb from the manual page (larger blurb is included there):
- cvs is a front end to the rcs(1) revision control system
- which extends the notion of revision control from a collec-
- tion of files in a single directory to a hierarchical col-
- lection of directories consisting of revision controlled
- files. These directories and files can be combined together
- to form a software release. cvs provides the functions
- necessary to manage these software releases and to control
- the concurrent editing of source files among multiple
- software developers.
-
-And a whole lot more. See the man/cvs.1 file for more information.
-
--------------------------------------------------------------------------------
-
-Special note to current CVS 1.3 users:
-
---> You can skip this section and go straight to "Installation" if you <--
---> have not been running any previous releases of CVS. <--
-
-See the NEWS file for a description of features new in this version.
-
-Some files have been renamed from the CVS 1.3 distribution. If you're
-not careful, this can cause your CVS build to fail in strange ways.
-In particular, be sure to remove the src/config.h file (which is now
-src/options.h), as the correct config.h file is generated
-automatically by the "configure" stage of installation (and installed
-in this directory).
-
--------------------------------------------------------------------------------
-
-Installation:
-
-Please read the INSTALL file for installation instructions. Brief summary:
-
- $ ./configure
- $ make
- $ make check # optional, long-running, step
- $ make install
- $ cvsinit
-
--------------------------------------------------------------------------------
-
-* How do I get up-to-date information and information about other
-versions of CVS?
-
-On the web, http://www.winternet.com/~zoo/cvs/ or
-http://www.loria.fr/~molli/cvs-index.html.
-
-The mailing list for CVS is info-cvs@prep.ai.mit.edu. Send
-subscription and removal requests for that list to
-info-cvs-requests@prep.ai.mit.edu.
-
-[Historical note: info-cvs@prep.ai.mit.edu is now the union of
- info-cvs@prep and cyclic-cvs@cyclic.com. Please use the prep
- address.]
-
--------------------------------------------------------------------------------
-
-Credits:
-
-The conflict-resolution algorithms and much of the administrative file
-definitions of CVS were based on the original package written by Dick Grune
-at Vrije Universiteit in Amsterdam <dick@cs.vu.nl>, and posted to
-comp.sources.unix in the volume 6 release sometime in 1986. This original
-version was a collection of shell scripts. I am thankful that Dick made
-his work available.
-
-Brian Berliner from Prisma, Inc. (now at Sun Microsystems, Inc.)
-<berliner@sun.com> converted the original CVS shell scripts into reasonably
-fast C and added many, many features to support software release control
-functions. See the manual page in the "man" directory. A copy of the
-USENIX article presented at the Winter 1990 USENIX Conference, Washington
-D.C., is included in the "doc" directory.
-
-Jeff Polk from BSDI <polk@bsdi.com> converted the CVS 1.2
-sources into much more readable and maintainable C code. He also added a
-whole lot of functionality and modularity to the code in the process.
-See the ChangeLog file.
-
-david d `zoo' zuhn <zoo@armadillo.com> contributed the working base code
-for CVS 1.4 Alpha. His work carries on from work done by K. Richard Pixley
-and others at Cygnus Support. The CVS 1.4 upgrade is due in large part to
-Zoo's efforts.
-
-David G. Grubbs <dgg@odi.com> contributed the CVS "history" and "release"
-commands. As well as the ever-so-useful "-n" option of CVS which tells CVS
-to show what it would do, without actually doing it. He also contributed
-support for the .cvsignore file.
-
-The Free Software Foundation (GNU) contributed most of the portability
-framework that CVS now uses. This can be found in the "configure" script,
-the Makefile's, and basically most of the "lib" directory.
-
-K. Richard Pixley, Cygnus Support <rich@cygnus.com> contributed many bug
-fixes/enhancement as well as completing early reviews of the CVS 1.3 manual
-pages.
-
-Roland Pesch, then of Cygnus Support <roland@wrs.com> contributed brand new
-cvs(1) and cvs(5) manual pages. We should all thank him for saving us from
-my poor use of our language!
-
-Paul Sander, HaL Computer Systems, Inc. <paul@hal.com> wrote and
-contributed the code in lib/sighandle.c. I added support for POSIX, BSD,
-and non-POSIX/non-BSD systems.
-
-Jim Kingdon and others at Cygnus Support <info@cygnus.com> wrote the
-remote repository access code.
-
-In addition to the above contributors, the following Beta testers deserve
-special mention for their support. If I have left off your name, I
-apologize. Just write to me and let me know!
-
- Mark D. Baushke <mdb@cisco.com>
- Per Cederqvist <ceder@signum.se>
- J.T. Conklin (jtc@cygnus.com>
- Vince DeMarco <vdemarco@fdcsrvr.cs.mci.com>
- Paul Eggert <eggert@twinsun.com>
- Lal George <george@research.att.com>
- Dean E. Hardi <Dean.E.Hardi@ccmail.jpl.nasa.gov>
- Mike Heath <mike@pencom.com>
- Jim Kingdon <kingdon@cygnus.com>
- Bernd Leibing <bernd.leibing@rz.uni-ulm.de>
- Benedict Lofstedt <benedict@tusc.com.au>
- Dave Love <d.love@dl.ac.uk>
- Robert Lupton the Good <rhl@astro.princeton.edu>
- Tom McAliney <tom@hilco.com>
- Eberhard Mattes <mattes@azu.informatik.uni-stuttgart.de>
- Jim Meyering <meyering@comco.com>
- Thomas Mohr <mohr@lts.sel.alcatel.de>
- Thomas Nilsson <thoni@softlab.se>
- Raye Raskin <raye.raskin@lia.com>
- Harlan Stenn <harlan@landmark.com>
- Gunnar Tornblom <gunnar.tornblom@senet.abb.se>
- Greg A. Woods <woods@kuma.web.net>
-
-Many contributors have added code to the "contrib" directory. See the
-README file there for a list of what is available. There is also a
-contributed GNU Emacs CVS-mode in contrib/pcl-cvs.
-
--------------------------------------------------------------------------------
-
- Cyclic Software <info@cyclic.com>
diff --git a/gnu/usr.bin/cvs/TODO b/gnu/usr.bin/cvs/TODO
deleted file mode 100644
index 1b8cb601ce7b..000000000000
--- a/gnu/usr.bin/cvs/TODO
+++ /dev/null
@@ -1,474 +0,0 @@
-$CVSid: @(#)TODO 1.26 94/09/21 $
-
-14. Pathname stripper, for checkout, as well as for writing the
- Repository file.
- [[ I have a simple one, but need to make sure to call it at all the
- appropriate points ]]
- (I'm not sure what this means -kingdon, Jun 1995).
-
-16. List of current users of a directory needs to be maintained.
- [[ sort of solved by history database ]]
-
-22. Catch signals for cleanup when "add"ing files.
-
-24. Insist on a log message.
- (This should be configurable via commitinfo or some new config file
- -kingdon, Jun 1995).
-
-30. Add "patch" program option to the modules database.
-
-31. Think hard about ^C recovery.
-
-35. Add "admin" command as an interface to "rcs".
- [[ a cheesy version is there, but it should be re-done ]]
-
-38. Think hard about using RCS state information to allow one to checkin
- a new vendor release without having it be accessed until it has been
- integrated into the local changes.
-
-39. Think about allowing parallel source trees that can easily track
- each other.
- [[ sort of solved with the automagic branch support, but I want more ]]
-
-45. Consider enhancing the "patch" and "tag" command support in the module
- database -- they seem hard to use since these commands deal directly
- with the RCS ,v files.
-
-46. Perhaps checkout/checkin/tag/patch commands should be imbedded in the
- file system directly, using special known command names?
-
-49. cvs xxx commands should be able to deal with files in other
- directories. I want to do a cvs add foo/bar.c.
- [[ most commands now use the generic recursion processor, but not all;
- this note is left here to remind me to fix the others ]]
-
-51. a way to identify what files other people are working on. Imagine "cvs
- modified", which prints out a table like
-
- file modifiers
- ===== =========
- foo.c
- bar.c wsd
- baz.c nrt jda
-
- I think this would be pretty difficult; I don't know if this
- information is stored anywhere. Also it's hard to say how one gets a
- user name, maybe a path to their local hierarchy is all you could get.
- [[ the history stuff does some of this, but not all ]]
-
-52. SCCS has a feature that I would *love* to see in CVS, as it is very
- useful. One may make a private copy of SCCS suid to a particular user,
- so other users in the authentication list may check files in and out of
- a project directory without mucking about with groups. Is there any
- plan to provide a similar functionality to CVS? Our site (and, I'd
- imagine, many other sites with large user bases) has decided against
- having the user-groups feature of unix available to the users, due to
- perceived administrative, technical and performance headaches. A tool
- such as CVS with features that provide group-like functionality would
- be a huge help.
-
-53. I'd suggest a way to notify users if/when a file(s) is being worked on.
- I suggest:
- + Always checkout/update files a readonly.
- + To work on a file, the user should do:
- cvs advise filename
- + This would maintain their email address associated with that
- file name in the repository and change the file mode to writable.
- + If other references to that file exist, the registered individuals
- are notified via email that another user(s) is going to be working
- on same.
- + When a committ occurs, the user is automatically 'unadvise'd (the
- inverse command should be supported as well) and other's are notified
- that a merge will be necessary before their checkin can be
- successful.
-
-62. Consider using revision controlled files and directories to handle the
- new module format -- consider a cvs command front-end to
- add/delete/modify module contents, maybe.
-
-63. The "import" and vendor support commands (co -j) need to be documented
- better.
-
-64. Need to greatly increase the performance of an initial checkout.
- [[ it got better, then we added functionality, making it worse again ]]
-
-66. Length of the CVS temporary files must be limited to 14 characters for
- System-V stupid support. As weel as the length on the CVS.adm files.
-
-67. cvs import should populate the vendor sources with CVS.adm files so
- that one could use the vendor sources directly without having the check
- them out.
-
-69. Consider enhacing import to add a module automatically to the module
- database. Perhaps with a new option, or perhaps with an editor.
-
-72. Consider re-design of the module -o, -i, -t options to use the file
- system more intuitively.
-
-73. Consider an option (in .cvsrc?) to automatically add files that are new
- and specified to commit.
-
-74. Consider adding a way to remove directories/files that you are done
- with... somehow.
- [[ cvs release sort of does this ]]
-
-76. Consider adding a layer of abstraction so that CVS can work with both
- RCS and SCCS files. Larry says this should be #ifdef'ed.
-
-79. Might be nice to have some sort of interface to TFS and tagged
- revisions.
-
-82. Maybe the import stuff should allow an arbitrary revision to be
- specified.
-
-84. Improve the documentation about administration of the repository and
- how to add/remove files and the use of symbolic links.
-
-85. Add revision controlled symbolic links to CVS using one of the tag
- fields in the RCS file.
-
-91. Better document the format of the source repository and how one might
- convert their current SCCS or RCS files into CVS format.
-
-92. Look into this:
- After a bit of soul searching via dbx, I realized my sin was that I'd
- specified "echo" as the program to call from loginfo. The commit
- procedure worked fine till it hit my echo, then silently aborted
- leaving the lockfiles intact. Since I needn't use the loginfo
- facility, I simply removed those commands and it all works.
-
-93. Need to think hard about release and development environments. Think
- about execsets as well.
-
-98. If diff3 bombs out (too many differences) cvs then thinks that the file
- has been updated and is OK to be commited even though the file
- has not yet been merged.
-
-100. Checked out files should have revision control support. Maybe.
-
-102. Perhaps directory modes should be propagated on all import check-ins.
- Not necessarily uid/gid changes.
-
-103. setuid/setgid on files is suspect.
-
-104. cvs should recover nicely on unreadable files/directories.
-
-105. cvs should have administrative tools to allow for changing permissions
- and modes and what not. In particular, this would make cvs a
- more attractive alternative to rdist.
-
-107. It should be possible to specify a list of symbolic revisions to
- checkout such that the list is processed in reverse order looking for
- matches within the RCS file for the symbolic revision. If there is
- not a match, the next symbolic rev on the list is checked, and so on,
- until all symbolic revs are exhausted. This would allow one to, say,
- checkout "4.0" + "4.0.3" + "4.0.3Patch1" + "4.0.3Patch2" to get the
- most recent 4.x stuff. This is usually handled by just specifying the
- right release_tag, but most people forget to do this.
-
-108. If someone creates a whole new directory (i.e. adds it to the cvs
- repository) and you happen to have a directory in your source farm by
- the same name, when you do your cvs update -d it SILENTLY does
- *nothing* to that directory. At least, I think it was silent;
- certainly, it did *not* abort my cvs update, as it would have if the
- same thing had happened with a file instead of a directory.
-
-109. I had gotten pieces of the sys directory in the past but not a
- complete tree. I just did something like:
-
- cvs get *
-
- Where sys was in * and got the message
-
- cvs get: Executing 'sys/tools/make_links sys'
- sh: sys/tools/make_links: not found
-
- I suspect this is because I didn't have the file in question,
- but I do not understand how I could fool it into getting an
- error. I think a later cvs get sys seemed to work so perhaps
- something is amiss in handling multiple arguments to cvs get?
-
-113. The "cvs update" command should tee its output to a log file in ".".
- (why? What is wrong with piping stdout to "tee"? -kingdon, Jun 1995)
-
-115. I still think "cvs modules" is a good idea.
- Since everything else is inside cvs, "mkmodules" should be in there too:
-
- Add a "modules" (synonym "mod") command directly in cvs.
- ("checkout -c" is not really intuitive. I'd move it into "mod -s".)
-
- "mod" Print database as typed. (line count as record id?)
- "mod -s" Print the sorted database (as "checkout -c" does now)
- "mod -m" Internal replacement for "mkmodules" command.
- "mod module ..." Print the raw dbm record for the named modules
- "mod -p module ..." Print relative filenames contained in modules.(no ",v")
- "mod -l module ..." Prints more info about relative filenames ("ls -l"?)
- "mod -f file ..." Tells you what module(s) the filenames are in.
-
-119. Consider an option to have import checkout the RCS or SCCS files
- if necessary.
-
-122. If Name_Repository fails, it currently causes CVS to die completely. It
- should instead return NULL and have the caller do something reasonable.
-
-123. Add a flag to import to not build vendor branches for local code.
-
-124. Anyway, I thought you might want to add something like the following
- to the cvs and mkmodules man pages:
-
- BUGS
- The sum of the sizes of a module key and its contents are
- limited. See ndbm(3).
-
-126. Do an analysis to see if CVS is forgetting to close file descriptors.
- Especially when committing many files (more than the open file limit
- for the particular UNIX).
-
-127. Look at *info files; they should all be quiet if the files are not
- there. Should be able to point at a RCS directory and go.
-
-128. When I tag a file, the message tells me that I'm tagging a directory.
-
-129. Something strange seems to have happened here. When I check this out,
- the update lines (U CFTS/...) seem to report a bogus leading CFTS
- (e.g. U CFTS/Medusa_TS/...) when the later files are checked out.
-
- The directory structure doesn't seem to be botched, just the
- messages. I don't recall seeing this before.
-
-130. cvs diff with no -r arguments does not need to look up the current RCS
- version number since it only cares about what's in the Entries file.
- This should make it much faster.
-
- It should ParseEntries itself and access the entries list much like
- Version_TS does (sticky tags and sticky options may need to be
- supported here as well). Then it should only diff the things that
- have the wrong time stamp (the ones that look modified).
-
-134. Make a statement about using hard NFS mounts to your source
- repository. Look into checking NULL fgets() returns with ferror() to
- see if an error had occurred.
-
-135. The email CVS sends with each checkin, should include the version
- number of each file it is checking in.
- [[ Sort of solved by contrib/log.pl, which does a good job of this ]]
-
-137. Some sites might want CVS to fsync() the RCS ,v file to protect
- against nasty hardware errors. There is a slight performance hit with
- doing so, though, so it should be configurable in the .cvsrc file.
- Also, along with this, we should look at the places where CVS itself
- could be a little more synchronous so as not to lose data.
- [[ I've done some of this, but it could use much more ]]
-
-138. Some people have suggested that CVS use a VPATH-like environment
- variable to limit the amount of sources that need to be duplicated for
- sites with giant source trees and no disk space.
-
-141. Import should accept modules as its directory argument.
-
-143. Update the documentation to show that the source repository is
- something far away from the files that you work on.
-
-144. Have cvs checkout look for the environment variable CVSPREFIX
- (or CVSMODPREFIX or some such). If it's set, then when looking
- up an alias in the modules database, first look it up with the
- value of CVSPREFIX attached, and then look for the alias itself.
- This would be useful when you have several projects in a single
- repository. You could have aliases abc_src and xyz_src and
- tell people working on project abc to put "setenv CVSPREFIX abc_"
- in their .cshrc file (or equivalent for other shells).
- Then they could do "cvs co src" to get a copy of their src
- directory, not xyz's. (This should create a directory called
- src, not abc_src.)
-
-145. After you create revision 1.1.1.1 in the previous scenario, if
- you do "cvs update -r1 filename" you get revision 1.1, not
- 1.1.1.1. It would be nice to get the later revision. Again,
- this restriction comes from RCS and is probably hard to
- change in CVS. Sigh.
-
- |"cvs update -r1 filename" does not tell RCS to follow any branches. CVS
- |tries to be consistent with RCS in this fashion, so I would not change
- |this. Within CVS we do have the flexibility of extending things, like
- |making a revision of the form "-r1HEAD" find the most recent revision
- |(branch or not) with a "1." prefix in the RCS file. This would get what
- |you want maybe.
-
- This would be very useful. Though I would prefer an option
- such as "-v1" rather than "-r1HEAD". This option might be
- used quite often.
-
-146. The merging of files should be controlled via a hook so that programs
- other than "rcsmerge" can be used, like Sun's filemerge or emacs's
- emerge.el. (but be careful in making this work client/server--it means
- doing the interactive merging at the end after the server is done).
-
-149. On Sun, 2 Feb 92 22:01:38 EST, rouilj@dl5000.bc.edu (John P. Rouillard)
- said:
- Maybe there should be an option to cvs admin that allows a user to
- change the Repository file with some degree of error checking?
- Something like "cvs admin reposmv /old/path /new/pretty/path". Before
- it does the replace it check to see that the files
- /new/pretty/path/<dir>/<files> exist.
-
-150. I have a customer request for a way to specify log message per
- file, non-interactively before the commit, such that a single, fully
- recursive commit prompts for one commit message, and concatenates the
- per file messages for each file. In short, one commit, one editor
- session, log messages allowed to vary across files within the commit.
- Also, the per file messages should be allowed to be written when the
- files are changed, which may predate the commit considerably.
-
- A new command seems appropriate for this. The state can be saved in the
- CVS directory. I.e.,
-
- % cvs msg foo.c
- Enter log message for foo.c
- >> fixed an uninitialized variable
- >> ^D
-
- The text is saved as CVS/foo.c,m (or some such name) and commit is
- modified to append (prepend?) the text (if found) to the log message
- specified at commit time. Easy enough.
-
-151. Also, is there a flag I am missing that allows replacing Ulrtx_Build
- by Ultrix_build? I.E. I would like a tag replacement to be a one step
- operation rather than a two step "cvs rtag -r Ulrtx_Build Ultrix_Build"
- followed by "cvs trag -d Ulrtx_Build"
-
-152. The "cvs -n" option does not work as one would expect for all the
- commands. In particular, for "commit" and "import", where one would
- also like to see what it would do, without actually doing anything.
-
-153. There should be some command (maybe I just haven't figured
- out which one...) to import a source directory which is already
- RCS-administered without losing all prior RCS gathered data. Thus, it
- would have to examine the RCS files and choose a starting version and
- branch higher than previous ones used.
-
-154. When committing the modules file, a pre-commit check should be done to
- verify the validity of the new modules file before allowing it to be
- committed. This could easily be done by adding an option to mkmodules
- to perform the verification.
-
-155. The options for "cvs history" are mutually exclusive, even though
- useful queries can be done if they are not, as in specifying both a
- module and a tag. A workaround is to specify the module, then run the
- output through grep to only display lines that begin with T, which are
- tag lines.
-
-156. Also, how hard would it be to allow continuation lines in the
- {commit,rcs,log}info files? It would probably be useful with all of
- the various flags that are now available, or if somebody has a lot of
- files to put into a module.
-
-157. The "cvs release" command does not understand about module names with
- the same flexibility that the "checkout" and "rdiff" commands do.
- It should, though, since it's confusing right now.
-
-158. If I do a recursive commit and find that the same RCS file is checked
- out (and modified!) in two different places within my checked-out
- files (but within the realm of a single "commit"), CVS will commit the
- first change, then overwrite that change with the second change. We
- should catch this (typically unusual) case and issue an appropriate
- diagnostic and die.
-
-159. On "update", when a merge is done, CVS should remember that your file
- was merged into and should keep reminding you of this fact until you
- actually look at the file (change its access time). Once you do this,
- it should go back to being a normal, unmodified file. This way, after
- a big update, you can run update again to see which files just got
- merged and may need attention.
-
-160. The checks that the commit command does should be extended to make
- sure that the revision that we will lock is not already locked by
- someone else. Maybe it should also lock the new revision if the old
- revision was already locked by the user as well, thus moving the lock
- forward after the commit.
-
-161. The date parser included with CVS (lib/getdate.y) does not support
- such RCS-supported dates as "1992/03/07". It probably should.
-
-163. The rtag/tag commands should have an option that removes the specified
- tag from any file that is in the attic. This allows one to re-use a
- tag (like "Mon", "Tue", ...) all the time and still have it tag the
- real main-line code.
-
-164. The *info files should allow multiple ocurrences of $CVSROOT and/or
- other cvs variables. They probably should *not* expand environment
- variables, as their behavior probably should not depend on who is
- running CVS.
-
-165. The "import" command will create RCS files automatically, but will
- screw-up when trying to create long file names on short file name
- file systems. Perhaps import should be a bit more cautious.
-
-166. There really needs to be a "Getting Started" document which describes
- some of the new CVS philosophies. Folks coming straight from SCCS or
- RCS might be confused by "cvs import". Also need to explain:
- - How one might setup their $CVSROOT
- - What all the tags mean in an "import" command
- - Tags are important; revision numbers are not
-
-167. "cvs log" doesn't understand about CVS magic branch numbers. As such,
- the command:
-
- cvs log -r1.63.2
- cvs log -rC2
-
- where "C2" is a magic branch that resolves to 1.63.2 do not print the
- same things. Sigh.
-
-169. We are using CVS as the configuration control for a software reuse library.
- What we do is do system calls passing the needed arguments. In the next
- release, it would be nice to see an option to put cvs .o files into a
- archive library with an API. This enhancement would go nicely with the
- notion of being able to integrate tools into a large software engineering
- environment.
-
-170. Is there an "info" file that can be invoked when a file is checked out, or
- updated ? What I want to do is to advise users, particularly novices, of
- the state of their working source whenever they check something out, as
- a sanity check.
-
- For example, I've written a perl script which tells you what branch you're
- on, if any. Hopefully this will help guard against mistaken checkins to
- the trunk, or to the wrong branch. I suppose I can do this in
- "commitinfo", but it'd be nice to advise people before they edit their
- files.
-
- It would also be nice if there was some sort of "verboseness" switch to
- the checkout and update commands that could turn this invocation of the
- script off, for mature users.
-
-173. We have a tagged branch in CVS. How do we get the version of that branch
- (for an entire directory) that corresponds to the files on that branch on a
- certain day? I'd like to specify BOTH -r and -D to 'cvs checkout', but I
- can't. It looks like I can only specify the date for the main line (as
- opposed to any branches). True? Any workarounds to get what I need?
-
-174. I would like to see "cvs release" modified so that it only removes files
- which are known to CVS - all the files in the repository, plus those which
- are listed in .cvsignore. This way, if you do leave something valuable in
- a source tree you can "cvs release -d" the tree and your non-CVS goodies
- are still there. If a user is going to leave non-CVS files in their source
- trees, they really should have to clean them up by hand.
-
-175. And, in the feature request department, I'd dearly love a command-line
- interface to adding a new module to the CVSROOT/modules file.
-
-176. If you use the -i flag in the modules file, you can control access
- to source code; this is a Good Thing under certain circumstances. I
- just had a nasty thought, and on experiment discovered that the
- filter specified by -i is _not_ run before a cvs admin command; as
- this allows a user to go behind cvs's back and delete information
- (cvs admin -o1.4 file) this seems like a serious problem.
-
-177. We've got some external vendor source that sits under a source code
- hierarchy, and when we do a cvs update, it gets wiped out because
- its tag is different from the "main" distribution. I've tried to
- use "-I" to ignore the directory, as well as .cvsignore, but this
- doesn't work.
-
-179. "cvs admin" does not log its actions with loginfo, nor does it check
- whether the action is allowed with commitinfo. It should.
diff --git a/gnu/usr.bin/cvs/contrib/README b/gnu/usr.bin/cvs/contrib/README
deleted file mode 100644
index e84b1761c0b1..000000000000
--- a/gnu/usr.bin/cvs/contrib/README
+++ /dev/null
@@ -1,90 +0,0 @@
-$CVSid: @(#)README 1.12 94/09/25 $
-
-This "contrib" directory is a place holder for code/scripts sent to
-me by contributors around the world. This README file will be kept
-up-to-date from release to release. BUT, I must point out that these
-contributions are really, REALLY UNSUPPORTED. In fact, I probably
-don't even know what they do. Nor do I guarantee to have tried them,
-or ported them to work with this CVS distribution. If you have questions,
-you might contact the author, but you should not necessarily expect
-a reply. USE AT YOUR OWN RISK -- and all that stuff.
-
-Contents of this directory:
-
- README This file.
- log A perl script suitable for including in your
- $CVSROOT/CVSROOT/loginfo file for logging commit
- changes. Includes the RCS revision of the change
- as part of the log.
- Contributed by Kevin Samborn <samborn@sunrise.com>.
- pcl-cvs A directory that contains GNU Emacs lisp code which
- implements a CVS-mode for emacs.
- Contributed by Per Cederqvist <ceder@lysator.liu.se>.
- commit_prep A perl script, to be combined with log_accum.pl, to
- log_accum provide for a way to combine the individual log
- messages of a multi-directory "commit" into a
- single log message, and mail the result somewhere.
- Can also do other checks for $Id and that you are
- committing the correct revision of the file.
- Read the comments carefully.
- Contributed by David Hampton <hampton@cisco.com>.
- mfpipe Another perl script for logging. Allows you to
- pipe the log message to a file and/or send mail
- to some alias.
- Contributed by John Clyne <clyne@niwot.scd.ucar.edu>.
- rcs-to-cvs Script to import sources that may have been under
- RCS control already.
- Contributed by Per Cederqvist <ceder@lysator.liu.se>.
- cvscheck Identifies files added, changed, or removed in a
- cvscheck.man checked out CVS tree; also notices unknown files.
- Contributed by Lowell Skoog <fluke!lowell@uunet.uu.net>
- cvshelp.man An introductory manual page written by Lowell Skoog
- <fluke!lowell@uunet.uu.net>. It is most likely
- out-of-date relative to CVS 1.3, but still may be
- useful.
- dirfns A shar file which contains some code that might
- help your system support opendir/readdir/closedir,
- if it does not already.
- Copied from the C-News distribution.
- rcslock A perl script that can be added to your commitinfo
- file that tries to determine if your RCS file is
- currently locked by someone else, as might be the
- case for a binary file.
- Contributed by John Rouillard <rouilj@cs.umb.edu>.
- ccvs-rsh A Perl script which allows "rsh pipelines" to
- be built in order to use Cyclic CVS from
- behind some varieties of firewall.
- cvs_acls A perl script that implements Access Control Lists
- by using the "commitinfo" hook provided with the
- "cvs commit" command.
- Contributed by David G. Grubbs <dgg@ksr.com>.
- descend A shell script that can be used to recursively
- descend.man descend through a directory. In CVS 1.2, this was
- very useful, since many of the commands were not
- recursive. In CVS 1.3 (and later), however, most of
- the commands are recursive. However, this may still
- come in handy.
- Contributed by Lowell Skoog <fluke!lowell@uunet.uu.net>
- cln_hist A perl script to compress your
- $CVSROOT/CVSROOT/history file, as it can grow quite
- large after extended use.
- Contributed by David G. Grubbs <dgg@ksr.com>
- sccs2rcs A C-shell script that can convert (some) SCCS files
- into RCS files, retaining the info contained in the
- SCCS file (like dates, author, and log message).
- Contributed by Ken Cox <kenstir@viewlogic.com>.
- intro.doc A user's view of what you need to know to get
- started with CVS.
- Contributed by <Steven.Pemberton@cwi.nl>.
- rcs2sccs A shell script to convert simple RCS files into
- SCCS files, originally gleaned off the network
- somewhere (originally by "kenc") and modified by
- Jerry Jelinek <jerry@rmtc.Central.Sun.COM> and
- Brian Berliner <berliner@sun.com> to increase
- robustness and add support for one-level of branches.
- rcs2log A shell script to create a ChangeLog-format file
- given only a set of RCS files.
- Contributed by Paul Eggert <eggert@twinsun.com>.
- clmerge A perl script to handle merge conflicts in GNU
- style ChangeLog files .
- Contributed by Tom Tromey <tromey@busco.lanl.gov>.
diff --git a/gnu/usr.bin/cvs/contrib/ccvs-rsh.pl b/gnu/usr.bin/cvs/contrib/ccvs-rsh.pl
deleted file mode 100644
index 8cfc6743ba3b..000000000000
--- a/gnu/usr.bin/cvs/contrib/ccvs-rsh.pl
+++ /dev/null
@@ -1,97 +0,0 @@
-#!/usr/bin/perl
-
-# The version of the remote shell program on some Linuxes, at least,
-# misuses GNU getopt in such a way that it plucks arguments to rsh
-# that look like command-line switches from anywhere in rsh's
-# arguments. This is the Wrong Thing to do, and causes older versions
-# of CCVS to break.
-
-# In addition, if we live behind a firewall and have to construct a
-# "pipeline" of rshes through different machines in order to get to
-# the outside world, each rshd along the way undoes the hard work CCVS
-# does to put the command to be executed at the far end into a single
-# argument. Sigh.
-
-# This script is a very minimal wrapper to rsh which makes sure that
-# the commands to be executed remotely are packed into a single
-# argument before we call exec(). It works on the idea of a "proxy
-# chain", which is a set of machines you go through to get to the CCVS
-# server machine.
-
-# Each host you go through before you reach the CCVS server machine
-# should have a copy of this script somewhere (preferably accessible
-# directly from your PATH envariable). In addition, each host you go
-# through before you reach the firewall should have the CVS_PROXY_HOST
-# envariable set to the next machine in the chain, and CVS_PROXY_USER
-# set if necessary.
-
-# This really isn't as complex as it sounds. Honest.
-
-# Bryan O'Sullivan <bos@serpentine.com> April 1995
-
-$usage = "usage: ccvs-rsh hostname [-l username] command [...]\n";
-
-if ($#ARGV < 1) {
- print STDERR $usage;
- exit 1;
-}
-
-# Try to pick a sane version of the remote shell command to run. This
-# only understands BSD and Linux machines; if your remote shell is
-# called "remsh" under some System V (e.g. HP-SUX), you should edit
-# the line manually to suit yourself.
-
-$rsh = (-x "/usr/ucb/rsh") ? "/usr/ucb/rsh" : "/usr/bin/rsh";
-
-# If you are not rshing directly to the CCVS server machine, make the
-# following variable point at ccvs-rsh on the next machine in the
-# proxy chain. If it's accessible through the PATH envariable, you
-# can just set this to "ccvs-rsh".
-
-$ccvs_rsh = "ccvs-rsh";
-
-# There shouldn't be any user-serviceable parts beyond this point.
-
-$host = $ARGV[0];
-
-if ($ARGV[1] eq "-l") {
- if ($#ARGV < 3) {
- print STDERR $usage;
- exit 1;
- }
- $user = $ARGV[2];
- $cbase = 3;
-} else {
- $cbase = 1;
-}
-
-# You might think you shoul be able to do something like
-# $command = join(' ', $ARGV[$cbase..$#ARGV]);
-# to achieve the effect of the following block of code, but it doesn't
-# work under Perl 4 on Linux, at least. Sigh.
-
-$command = $ARGV[$cbase];
-for ($cbase++; $cbase <= $#ARGV; $cbase++) {
- $command .= " " . $ARGV[$cbase];
-}
-
-if (defined $ENV{"CVS_PROXY_HOST"}) {
- $command = (defined $user)
- ? "$ccvs_rsh $host -l $user $command"
- : "$ccvs_rsh $host $command";
-
- if (defined $ENV{"CVS_PROXY_USER"}) {
- exec ($rsh, $ENV{"CVS_PROXY_HOST"}, "-l", $ENV{"CVS_PROXY_USER"},
- $command);
- } else {
- exec ($rsh, $ENV{"CVS_PROXY_HOST"}, $command);
- }
-} elsif (defined $user) {
- exec ($rsh, $host, "-l", $user, $command);
-} else {
- if (defined $ENV{"CVS_PROXY_USER"}) {
- exec ($rsh, $host, "-l", $ENV{"CVS_PROXY_USER"}, $command);
- } else {
- exec ($rsh, $host, $command);
- }
-}
diff --git a/gnu/usr.bin/cvs/contrib/clmerge b/gnu/usr.bin/cvs/contrib/clmerge
deleted file mode 100644
index 1a29311a9c14..000000000000
--- a/gnu/usr.bin/cvs/contrib/clmerge
+++ /dev/null
@@ -1,156 +0,0 @@
-#!/usr/local/bin/perl
-
-# Merge conflicted ChangeLogs
-# tromey Mon Aug 15 1994
-
-# Due to popular demand, I'm posting my ChangeLog auto-merge tool. Run
-# this on your ChangeLog files when an update leaves them conflicted.
-# The code is appended.
-#
-# Usage is:
-#
-# cl-merge [-i] file ...
-#
-# With -i, it works in place (backups put in a ~ file). Otherwise the
-# merged ChangeLog is printed to stdout.
-#
-# Style comments are welcome. This is my third perl program ever.
-#
-# Please report any bugs to me. I wrote this yesterday, so there are no
-# guarantees about its performance. I recommend checking its output
-# carefully. If you do send a bug report, please includie the failing
-# ChangeLog, so I can include it in my test suite.
-#
-# Tom
-# ---
-# tromey@busco.lanl.gov Member, League for Programming Freedom
-# Sadism and farce are always inexplicably linked.
-# -- Alexander Theroux
-
-# If '-i' is given, do it in-place.
-if ($ARGV[0] eq '-i') {
- shift (@ARGV);
- $^I = '~';
-}
-
-$lastkey = '';
-$lastval = '';
-$conf = 0;
-%conflist = ();
-
-$tjd = 0;
-
-# Simple state machine. The states:
-#
-# 0 Not in conflict. Just copy input to output.
-# 1 Beginning an entry. Next non-blank line is key.
-# 2 In entry. Entry beginner transitions to state 1.
-while (<>) {
- if (/^<<<</ || /^====/) {
- # Start of a conflict.
-
- # Copy last key into array.
- if ($lastkey ne '') {
- $conflist{$lastkey} = $lastval;
-
- $lastkey = '';
- $lastval = '';
- }
-
- $conf = 1;
- } elsif (/^>>>>/) {
- # End of conflict. Output.
-
- # Copy last key into array.
- if ($lastkey ne '') {
- $conflist{$lastkey} = $lastval;
-
- $lastkey = '';
- $lastval = '';
- }
-
- foreach (reverse sort clcmp keys %conflist) {
- print STDERR "doing $_" if $tjd;
- print $_;
- print $conflist{$_};
- }
-
- $lastkey = '';
- $lastval = '';
- $conf = 0;
- %conflist = ();
- } elsif ($conf == 1) {
- # Beginning an entry. Skip empty lines. Error if not a real
- # beginner.
- if (/^$/) {
- # Empty line; just skip at this point.
- } elsif (/^[MTWFS]/) {
- # Looks like the name of a day; assume opener and move to
- # "in entry" state.
- $lastkey = $_;
- $conf = 2;
- print STDERR "found $_" if $tjd;
- } else {
- die ("conflict crosses entry boundaries: $_");
- }
- } elsif ($conf == 2) {
- # In entry. Copy into variable until we see beginner line.
- if (/^[MTWFS]/) {
- # Entry beginner line.
-
- # Copy last key into array.
- if ($lastkey ne '') {
- $conflist{$lastkey} = $lastval;
-
- $lastkey = '';
- $lastval = '';
- }
-
- $lastkey = $_;
- print STDERR "found $_" if $tjd;
- $lastval = '';
- } else {
- $lastval .= $_;
- }
- } else {
- # Just copy.
- print;
- }
-}
-
-%months = ('Jan', 0,
- 'Feb', 1,
- 'Mar', 2,
- 'Apr', 3,
- 'May', 4,
- 'Jun', 5,
- 'Jul', 6,
- 'Aug', 7,
- 'Sep', 8,
- 'Oct', 9,
- 'Nov', 10,
- 'Dec', 11);
-
-# Compare ChangeLog time strings like <=>.
-#
-# 0 1 2 3
-# Thu Aug 11 13:22:42 1994 Tom Tromey (tromey@creche.colorado.edu)
-# 0123456789012345678901234567890
-#
-sub clcmp {
- # First check year.
- $r = substr ($a, 20, 4) <=> substr ($b, 20, 4);
-
- # Now check month.
- $r = $months{$a} <=> $months{$b} if !$r;
-
- # Now check day.
- $r = substr ($a, 8, 2) <=> substr ($b, 8, 2) if !$r;
-
- # Now check time (3 parts).
- $r = substr ($a, 11, 2) <=> substr ($b, 11, 2) if !$r;
- $r = substr ($a, 14, 2) <=> substr ($b, 14, 2) if !$r;
- $r = substr ($a, 17, 2) <=> substr ($b, 17, 2) if !$r;
-
- $r;
-}
diff --git a/gnu/usr.bin/cvs/contrib/clmerge.pl b/gnu/usr.bin/cvs/contrib/clmerge.pl
deleted file mode 100644
index ac813713a827..000000000000
--- a/gnu/usr.bin/cvs/contrib/clmerge.pl
+++ /dev/null
@@ -1,152 +0,0 @@
-#! xPERL_PATHx
-
-# Merge conflicted ChangeLogs
-# tromey Mon Aug 15 1994
-
-# Usage is:
-#
-# cl-merge [-i] file ...
-#
-# With -i, it works in place (backups put in a ~ file). Otherwise the
-# merged ChangeLog is printed to stdout.
-
-# Please report any bugs to me. I wrote this yesterday, so there are no
-# guarantees about its performance. I recommend checking its output
-# carefully. If you do send a bug report, please include the failing
-# ChangeLog, so I can include it in my test suite.
-#
-# Tom
-# ---
-# tromey@busco.lanl.gov Member, League for Programming Freedom
-# Sadism and farce are always inexplicably linked.
-# -- Alexander Theroux
-
-
-# Month->number mapping. Used for sorting.
-%months = ('Jan', 0,
- 'Feb', 1,
- 'Mar', 2,
- 'Apr', 3,
- 'May', 4,
- 'Jun', 5,
- 'Jul', 6,
- 'Aug', 7,
- 'Sep', 8,
- 'Oct', 9,
- 'Nov', 10,
- 'Dec', 11);
-
-# If '-i' is given, do it in-place.
-if ($ARGV[0] eq '-i') {
- shift (@ARGV);
- $^I = '~';
-}
-
-$lastkey = '';
-$lastval = '';
-$conf = 0;
-%conflist = ();
-
-$tjd = 0;
-
-# Simple state machine. The states:
-#
-# 0 Not in conflict. Just copy input to output.
-# 1 Beginning an entry. Next non-blank line is key.
-# 2 In entry. Entry beginner transitions to state 1.
-while (<>) {
- if (/^<<<</ || /^====/) {
- # Start of a conflict.
-
- # Copy last key into array.
- if ($lastkey ne '') {
- $conflist{$lastkey} = $lastval;
-
- $lastkey = '';
- $lastval = '';
- }
-
- $conf = 1;
- } elsif (/^>>>>/) {
- # End of conflict. Output.
-
- # Copy last key into array.
- if ($lastkey ne '') {
- $conflist{$lastkey} = $lastval;
-
- $lastkey = '';
- $lastval = '';
- }
-
- foreach (reverse sort clcmp keys %conflist) {
- print STDERR "doing $_" if $tjd;
- print $_;
- print $conflist{$_};
- }
-
- $lastkey = '';
- $lastval = '';
- $conf = 0;
- %conflist = ();
- } elsif ($conf == 1) {
- # Beginning an entry. Skip empty lines. Error if not a real
- # beginner.
- if (/^$/) {
- # Empty line; just skip at this point.
- } elsif (/^[MTWFS]/) {
- # Looks like the name of a day; assume opener and move to
- # "in entry" state.
- $lastkey = $_;
- $conf = 2;
- print STDERR "found $_" if $tjd;
- } else {
- die ("conflict crosses entry boundaries: $_");
- }
- } elsif ($conf == 2) {
- # In entry. Copy into variable until we see beginner line.
- if (/^[MTWFS]/) {
- # Entry beginner line.
-
- # Copy last key into array.
- if ($lastkey ne '') {
- $conflist{$lastkey} = $lastval;
-
- $lastkey = '';
- $lastval = '';
- }
-
- $lastkey = $_;
- print STDERR "found $_" if $tjd;
- $lastval = '';
- } else {
- $lastval .= $_;
- }
- } else {
- # Just copy.
- print;
- }
-}
-
-# Compare ChangeLog time strings like <=>.
-#
-# 0 1 2 3
-# Thu Aug 11 13:22:42 1994 Tom Tromey (tromey@creche.colorado.edu)
-# 0123456789012345678901234567890
-#
-sub clcmp {
- # First check year.
- $r = substr ($a, 20, 4) <=> substr ($b, 20, 4);
-
- # Now check month.
- $r = $months{substr ($a, 4, 3)} <=> $months{substr ($b, 4, 3)} if !$r;
-
- # Now check day.
- $r = substr ($a, 8, 2) <=> substr ($b, 8, 2) if !$r;
-
- # Now check time (3 parts).
- $r = substr ($a, 11, 2) <=> substr ($b, 11, 2) if !$r;
- $r = substr ($a, 14, 2) <=> substr ($b, 14, 2) if !$r;
- $r = substr ($a, 17, 2) <=> substr ($b, 17, 2) if !$r;
-
- $r;
-}
diff --git a/gnu/usr.bin/cvs/contrib/cln_hist.pl b/gnu/usr.bin/cvs/contrib/cln_hist.pl
deleted file mode 100644
index ff49d0a3e9c7..000000000000
--- a/gnu/usr.bin/cvs/contrib/cln_hist.pl
+++ /dev/null
@@ -1,92 +0,0 @@
-#! xPERL_PATHx
-# -*-Perl-*-
-#
-# $Id: cln_hist.pl,v 1.2 1995/07/10 02:01:26 kfogel Exp $
-# Contributed by David G. Grubbs <dgg@ksr.com>
-#
-# Clean up the history file. 10 Record types: MAR OFT WUCG
-#
-# WUCG records are thrown out.
-# MAR records are retained.
-# T records: retain only last tag with same combined tag/module.
-#
-# Two passes: Walk through the first time and remember the
-# 1. Last Tag record with same "tag" and "module" names.
-# 2. Last O record with unique user/module/directory, unless followed
-# by a matching F record.
-#
-
-$r = $ENV{"CVSROOT"};
-$c = "$r/CVSROOT";
-$h = "$c/history";
-
-eval "print STDERR \$die='Unknown parameter $1\n' if !defined \$$1; \$$1=\$';"
- while ($ARGV[0] =~ /^(\w+)=/ && shift(@ARGV));
-exit 255 if $die; # process any variable=value switches
-
-%tags = ();
-%outs = ();
-
-#
-# Move history file to safe place and re-initialize a new one.
-#
-rename($h, "$h.bak");
-open(XX, ">$h");
-close(XX);
-
-#
-# Pass1 -- remember last tag and checkout.
-#
-open(HIST, "$h.bak");
-while (<HIST>) {
- next if /^[MARWUCG]/;
-
- # Save whole line keyed by tag|module
- if (/^T/) {
- @tmp = split(/\|/, $_);
- $tags{$tmp[4] . '|' . $tmp[5]} = $_;
- }
- # Save whole line
- if (/^[OF]/) {
- @tmp = split(/\|/, $_);
- $outs{$tmp[1] . '|' . $tmp[2] . '|' . $tmp[5]} = $_;
- }
-}
-
-#
-# Pass2 -- print out what we want to save.
-#
-open(SAVE, ">$h.work");
-open(HIST, "$h.bak");
-while (<HIST>) {
- next if /^[FWUCG]/;
-
- # If whole line matches saved (i.e. "last") one, print it.
- if (/^T/) {
- @tmp = split(/\|/, $_);
- next if $tags{$tmp[4] . '|' . $tmp[5]} ne $_;
- }
- # Save whole line
- if (/^O/) {
- @tmp = split(/\|/, $_);
- next if $outs{$tmp[1] . '|' . $tmp[2] . '|' . $tmp[5]} ne $_;
- }
-
- print SAVE $_;
-}
-
-#
-# Put back the saved stuff
-#
-system "cat $h >> $h.work";
-
-if (-s $h) {
- rename ($h, "$h.interim");
- print "history.interim has non-zero size.\n";
-} else {
- unlink($h);
-}
-
-rename ("$h.work", $h);
-
-exit(0);
diff --git a/gnu/usr.bin/cvs/contrib/commit_prep.pl b/gnu/usr.bin/cvs/contrib/commit_prep.pl
deleted file mode 100644
index 5272c0430ad3..000000000000
--- a/gnu/usr.bin/cvs/contrib/commit_prep.pl
+++ /dev/null
@@ -1,216 +0,0 @@
-#! xPERL_PATHx
-# -*-Perl-*-
-#
-#ident "@(#)cvs/contrib:$Name: $:$Id: commit_prep.pl,v 1.2 1995/07/10 02:01:29 kfogel Exp $"
-#
-# Perl filter to handle pre-commit checking of files. This program
-# records the last directory where commits will be taking place for
-# use by the log_accum.pl script. For new files, it forces the
-# existence of a RCS "Id" keyword in the first ten lines of the file.
-# For existing files, it checks version number in the "Id" line to
-# prevent losing changes because an old version of a file was copied
-# into the direcory.
-#
-# Possible future enhancements:
-#
-# Check for cruft left by unresolved conflicts. Search for
-# "^<<<<<<<$", "^-------$", and "^>>>>>>>$".
-#
-# Look for a copyright and automagically update it to the
-# current year. [[ bad idea! -- woods ]]
-#
-#
-# Contributed by David Hampton <hampton@cisco.com>
-#
-# Hacked on lots by Greg A. Woods <woods@web.net>
-
-#
-# Configurable options
-#
-
-# Constants (remember to protect strings from RCS keyword substitution)
-#
-$LAST_FILE = "/tmp/#cvs.lastdir"; # must match name in log_accum.pl
-$ENTRIES = "CVS/Entries";
-
-# Patterns to find $Log keywords in files
-#
-$LogString1 = "\\\$\\Log: .* \\\$";
-$LogString2 = "\\\$\\Log\\\$";
-$NoLog = "%s - contains an RCS \$Log keyword. It must not!\n";
-
-# pattern to match an RCS Id keyword line with an existing ID
-#
-$IDstring = "\"@\\(#\\)[^:]*:.*\\\$\Id: .*\\\$\"";
-$NoId = "
-%s - Does not contain a properly formatted line with the keyword \"Id:\".
- I.e. no lines match \"" . $IDstring . "\".
- Please see the template files for an example.\n";
-
-# pattern to match an RCS Id keyword line for a new file (i.e. un-expanded)
-#
-$NewId = "\"@(#)[^:]*:.*\\$\Id\\$\"";
-
-$NoName = "
-%s - The ID line should contain only \"@(#)module/path:\$Name\$:\$\Id\$\"
- for a newly created file.\n";
-
-$BadName = "
-%s - The file name '%s' in the ID line does not match
- the actual filename.\n";
-
-$BadVersion = "
-%s - How dare you!!! You replaced your copy of the file '%s',
- which was based upon version %s, with an %s version based
- upon %s. Please move your '%s' out of the way, perform an
- update to get the current version, and them merge your changes
- into that file, then try the commit again.\n";
-
-#
-# Subroutines
-#
-
-sub write_line {
- local($filename, $line) = @_;
- open(FILE, ">$filename") || die("Cannot open $filename, stopped");
- print(FILE $line, "\n");
- close(FILE);
-}
-
-sub check_version {
- local($i, $id, $rname, $version);
- local($filename, $cvsversion) = @_;
-
- open(FILE, "<$filename") || return(0);
-
- @all_lines = ();
- $idpos = -1;
- $newidpos = -1;
- for ($i = 0; <FILE>; $i++) {
- chop;
- push(@all_lines, $_);
- if ($_ =~ /$IDstring/) {
- $idpos = $i;
- }
- if ($_ =~ /$NewId/) {
- $newidpos = $i;
- }
- }
-
- if (grep(/$LogString1/, @all_lines) || grep(/$LogString2/, @all_lines)) {
- print STDERR sprintf($NoLog, $filename);
- return(1);
- }
-
- if ($debug != 0) {
- print STDERR sprintf("file = %s, version = %d.\n", $filename, $cvsversion{$filename});
- }
-
- if ($cvsversion{$filename} == 0) {
- if ($newidpos != -1 && $all_lines[$newidpos] !~ /$NewId/) {
- print STDERR sprintf($NoName, $filename);
- return(1);
- }
- return(0);
- }
-
- if ($idpos == -1) {
- print STDERR sprintf($NoId, $filename);
- return(1);
- }
-
- $line = $all_lines[$idpos];
- $pos = index($line, "Id: ");
- if ($debug != 0) {
- print STDERR sprintf("%d in '%s'.\n", $pos, $line);
- }
- ($id, $rname, $version) = split(' ', substr($line, $pos));
- if ($rname ne "$filename,v") {
- print STDERR sprintf($BadName, $filename, substr($rname, 0, length($rname)-2));
- return(1);
- }
- if ($cvsversion{$filename} < $version) {
- print STDERR sprintf($BadVersion, $filename, $filename, $cvsversion{$filename},
- "newer", $version, $filename);
- return(1);
- }
- if ($cvsversion{$filename} > $version) {
- print STDERR sprintf($BadVersion, $filename, $filename, $cvsversion{$filename},
- "older", $version, $filename);
- return(1);
- }
- return(0);
-}
-
-#
-# Main Body
-#
-
-$id = getpgrp(); # You *must* use a shell that does setpgrp()!
-
-# Check each file (except dot files) for an RCS "Id" keyword.
-#
-$check_id = 0;
-
-# Record the directory for later use by the log_accumulate stript.
-#
-$record_directory = 0;
-
-# parse command line arguments
-#
-while (@ARGV) {
- $arg = shift @ARGV;
-
- if ($arg eq '-d') {
- $debug = 1;
- print STDERR "Debug turned on...\n";
- } elsif ($arg eq '-c') {
- $check_id = 1;
- } elsif ($arg eq '-r') {
- $record_directory = 1;
- } else {
- push(@files, $arg);
- }
-}
-
-$directory = shift @files;
-
-if ($debug != 0) {
- print STDERR "dir - ", $directory, "\n";
- print STDERR "files - ", join(":", @files), "\n";
- print STDERR "id - ", $id, "\n";
-}
-
-# Suck in the CVS/Entries file
-#
-open(ENTRIES, $ENTRIES) || die("Cannot open $ENTRIES.\n");
-while (<ENTRIES>) {
- local($filename, $version) = split('/', substr($_, 1));
- $cvsversion{$filename} = $version;
-}
-
-# Now check each file name passed in, except for dot files. Dot files
-# are considered to be administrative files by this script.
-#
-if ($check_id != 0) {
- $failed = 0;
- foreach $arg (@files) {
- if (index($arg, ".") == 0) {
- next;
- }
- $failed += &check_version($arg);
- }
- if ($failed) {
- print STDERR "\n";
- exit(1);
- }
-}
-
-# Record this directory as the last one checked. This will be used
-# by the log_accumulate script to determine when it is processing
-# the final directory of a multi-directory commit.
-#
-if ($record_directory != 0) {
- &write_line("$LAST_FILE.$id", $directory);
-}
-exit(0);
diff --git a/gnu/usr.bin/cvs/contrib/cvs-format.el b/gnu/usr.bin/cvs/contrib/cvs-format.el
deleted file mode 100644
index cdbd8423ce2a..000000000000
--- a/gnu/usr.bin/cvs/contrib/cvs-format.el
+++ /dev/null
@@ -1,81 +0,0 @@
-;; -*- lisp-interaction -*-
-;; -*- emacs-lisp -*-
-;;
-;;
-;; originally from...
-;; Rich's personal .emacs file. feel free to copy.
-;;
-;; Last Mod Wed Feb 5 16:11:47 PST 1992, by rich@cygnus.com
-;;
-
-;;
-;;
-;; This section sets constants used by c-mode for formating
-;;
-;;
-
-;; If `c-auto-newline' is non-`nil', newlines are inserted both
-;;before and after braces that you insert, and after colons and semicolons.
-;;Correct C indentation is done on all the lines that are made this way.
-
-(setq c-auto-newline nil)
-
-
-;;*Non-nil means TAB in C mode should always reindent the current line,
-;;regardless of where in the line point is when the TAB command is used.
-;;It might be desirable to set this to nil for CVS, since unlike GNU
-;; CVS often uses comments over to the right separated by TABs.
-;; Depends some on whether you're in the habit of using TAB to
-;; reindent.
-;(setq c-tab-always-indent nil)
-
-;;; It seems to me that
-;;; `M-x set-c-style BSD RET'
-;;; or
-;;; (set-c-style "BSD")
-;;; takes care of the indentation parameters correctly.
-
-
-;; C does not have anything analogous to particular function names for which
-;;special forms of indentation are desirable. However, it has a different
-;;need for customization facilities: many different styles of C indentation
-;;are in common use.
-;;
-;; There are six variables you can set to control the style that Emacs C
-;;mode will use.
-;;
-;;`c-indent-level'
-;; Indentation of C statements within surrounding block. The surrounding
-;; block's indentation is the indentation of the line on which the
-;; open-brace appears.
-
-(setq c-indent-level 4)
-
-;;`c-continued-statement-offset'
-;; Extra indentation given to a substatement, such as the then-clause of
-;; an if or body of a while.
-
-(setq c-continued-statement-offset 4)
-
-;;`c-brace-offset'
-;; Extra indentation for line if it starts with an open brace.
-
-(setq c-brace-offset -4)
-
-;;`c-brace-imaginary-offset'
-;; An open brace following other text is treated as if it were this far
-;; to the right of the start of its line.
-
-(setq c-brace-imaginary-offset 0)
-
-;;`c-argdecl-indent'
-;; Indentation level of declarations of C function arguments.
-
-(setq c-argdecl-indent 4)
-
-;;`c-label-offset'
-;; Extra indentation for line that is a label, or case or default.
-
-(setq c-label-offset -4)
-
-;;;; eof
diff --git a/gnu/usr.bin/cvs/contrib/cvs_acls.pl b/gnu/usr.bin/cvs/contrib/cvs_acls.pl
deleted file mode 100644
index bcb544d46f5d..000000000000
--- a/gnu/usr.bin/cvs/contrib/cvs_acls.pl
+++ /dev/null
@@ -1,143 +0,0 @@
-#! xPERL_PATHx
-# -*-Perl-*-
-#
-# $Id: cvs_acls.pl,v 1.2 1995/07/10 02:01:33 kfogel Exp $
-#
-# Access control lists for CVS. dgg@ksr.com (David G. Grubbs)
-#
-# CVS "commitinfo" for matching repository names, running the program it finds
-# on the same line. More information is available in the CVS man pages.
-#
-# ==== INSTALLATION:
-#
-# To use this program as I intended, do the following four things:
-#
-# 0. Install PERL. :-)
-#
-# 1. Put one line, as the *only* non-comment line, in your commitinfo file:
-#
-# DEFAULT /usr/local/bin/cvs_acls
-#
-# 2. Install this file as /usr/local/bin/cvs_acls and make it executable.
-#
-# 3. Create a file named $CVSROOT/CVSROOT/avail.
-#
-# ==== FORMAT OF THE avail FILE:
-#
-# The avail file determines whether you may commit files. It contains lines
-# read from top to bottom, keeping track of a single "bit". The "bit"
-# defaults to "on". It can be turned "off" by "unavail" lines and "on" by
-# "avail" lines. ==> Last one counts.
-#
-# Any line not beginning with "avail" or "unavail" is ignored.
-#
-# Lines beginning with "avail" or "unavail" are assumed to be '|'-separated
-# triples: (All spaces and tabs are ignored in a line.)
-#
-# {avail.*,unavail.*} [| user,user,... [| repos,repos,...]]
-#
-# 1. String starting with "avail" or "unavail".
-# 2. Optional, comma-separated list of usernames.
-# 3. Optional, comma-separated list of repository pathnames.
-# These are pathnames relative to $CVSROOT. They can be directories or
-# filenames. A directory name allows access to all files and
-# directories below it.
-#
-# Example: (Text from the ';;' rightward may not appear in the file.)
-#
-# unavail ;; Make whole repository unavailable.
-# avail|dgg ;; Except for user "dgg".
-# avail|fred, john|bin/ls ;; Except when "fred" or "john" commit to
-# ;; the module whose repository is "bin/ls"
-#
-# PROGRAM LOGIC:
-#
-# CVS passes to @ARGV an absolute directory pathname (the repository
-# appended to your $CVSROOT variable), followed by a list of filenames
-# within that directory.
-#
-# We walk through the avail file looking for a line that matches both
-# the username and repository.
-#
-# A username match is simply the user's name appearing in the second
-# column of the avail line in a space-or-comma separate list.
-#
-# A repository match is either:
-# - One element of the third column matches $ARGV[0], or some
-# parent directory of $ARGV[0].
-# - Otherwise *all* file arguments ($ARGV[1..$#ARGV]) must be
-# in the file list in one avail line.
-# - In other words, using directory names in the third column of
-# the avail file allows committing of any file (or group of
-# files in a single commit) in the tree below that directory.
-# - If individual file names are used in the third column of
-# the avail file, then files must be committed individually or
-# all files specified in a single commit must all appear in
-# third column of a single avail line.
-#
-
-$debug = 0;
-$cvsroot = $ENV{'CVSROOT'};
-$availfile = $cvsroot . "/CVSROOT/avail";
-$myname = $ENV{"USER"} if !($myname = $ENV{"LOGNAME"});
-
-eval "print STDERR \$die='Unknown parameter $1\n' if !defined \$$1; \$$1=\$';"
- while ($ARGV[0] =~ /^(\w+)=/ && shift(@ARGV));
-exit 255 if $die; # process any variable=value switches
-
-die "Must set CVSROOT\n" if !$cvsroot;
-($repos = shift) =~ s:^$cvsroot/::;
-grep($_ = $repos . '/' . $_, @ARGV);
-
-print "$$ Repos: $repos\n","$$ ==== ",join("\n$$ ==== ",@ARGV),"\n" if $debug;
-
-$exit_val = 0; # Good Exit value
-
-$universal_off = 0;
-open (AVAIL, $availfile) || exit(0); # It is ok for avail file not to exist
-while (<AVAIL>) {
- chop;
- next if /^\s*\#/;
- next if /^\s*$/;
- ($flagstr, $u, $m) = split(/[\s,]*\|[\s,]*/, $_);
-
- # Skip anything not starting with "avail" or "unavail" and complain.
- (print "Bad avail line: $_\n"), next
- if ($flagstr !~ /^avail/ && $flagstr !~ /^unavail/);
-
- # Set which bit we are playing with. ('0' is OK == Available).
- $flag = (($& eq "avail") ? 0 : 1);
-
- # If we find a "universal off" flag (i.e. a simple "unavail") remember it
- $universal_off = 1 if ($flag && !$u && !$m);
-
- # $myname considered "in user list" if actually in list or is NULL
- $in_user = (!$u || grep ($_ eq $myname, split(/[\s,]+/,$u)));
- print "$$ \$myname($myname) in user list: $_\n" if $debug && $in_user;
-
- # Module matches if it is a NULL module list in the avail line. If module
- # list is not null, we check every argument combination.
- if (!($in_repo = !$m)) {
- @tmp = split(/[\s,]+/,$m);
- for $j (@tmp) {
- # If the repos from avail is a parent(or equal) dir of $repos, OK
- $in_repo = 1, last if ($repos eq $j || $repos =~ /^$j\//);
- }
- if (!$in_repo) {
- $in_repo = 1;
- for $j (@ARGV) {
- last if !($in_repo = grep ($_ eq $j, @tmp));
- }
- }
- }
- print "$$ \$repos($repos) in repository list: $_\n" if $debug && $in_repo;
-
- $exit_val = $flag if ($in_user && $in_repo);
- print "$$ ==== \$exit_val = $exit_val\n$$ ==== \$flag = $flag\n" if $debug;
-}
-close(AVAIL);
-print "$$ ==== \$exit_val = $exit_val\n" if $debug;
-print "**** Access denied: Insufficient Karma ($myname|$repos)\n" if $exit_val;
-print "**** Access allowed: Personal Karma exceeds Environmental Karma.\n"
- if $universal_off && !$exit_val;
-exit($exit_val);
diff --git a/gnu/usr.bin/cvs/contrib/cvscheck b/gnu/usr.bin/cvs/contrib/cvscheck
deleted file mode 100644
index 1c66688cbd34..000000000000
--- a/gnu/usr.bin/cvs/contrib/cvscheck
+++ /dev/null
@@ -1,84 +0,0 @@
-#! /bin/sh
-# $Id: cvscheck,v 1.2 1992/04/10 03:04:19 berliner Exp $
-#
-# cvscheck - identify files added, changed, or removed
-# in CVS working directory
-#
-# Contributed by Lowell Skoog <fluke!lowell@uunet.uu.net>
-#
-# This program should be run in a working directory that has been
-# checked out using CVS. It identifies files that have been added,
-# changed, or removed in the working directory, but not "cvs
-# committed". It also determines whether the files have been "cvs
-# added" or "cvs removed". For directories, it is only practical to
-# determine whether they have been added.
-
-name=cvscheck
-changes=0
-
-# If we can't run CVS commands in this directory
-cvs status . > /dev/null 2>&1
-if [ $? != 0 ] ; then
-
- # Bail out
- echo "$name: there is no version here; bailing out" 1>&2
- exit 1
-fi
-
-# Identify files added to working directory
-for file in .* * ; do
-
- # Skip '.' and '..'
- if [ $file = '.' -o $file = '..' ] ; then
- continue
- fi
-
- # If a regular file
- if [ -f $file ] ; then
- if cvs status $file | grep -s '^From:[ ]*New file' ; then
- echo "file added: $file - not CVS committed"
- changes=`expr $changes + 1`
- elif cvs status $file | grep -s '^From:[ ]*no entry for' ; then
- echo "file added: $file - not CVS added, not CVS committed"
- changes=`expr $changes + 1`
- fi
-
- # Else if a directory
- elif [ -d $file -a $file != CVS.adm ] ; then
-
- # Move into it
- cd $file
-
- # If CVS commands don't work inside
- cvs status . > /dev/null 2>&1
- if [ $? != 0 ] ; then
- echo "directory added: $file - not CVS added"
- changes=`expr $changes + 1`
- fi
-
- # Move back up
- cd ..
- fi
-done
-
-# Identify changed files
-changedfiles=`cvs diff | egrep '^diff' | awk '{print $3}'`
-for file in $changedfiles ; do
- echo "file changed: $file - not CVS committed"
- changes=`expr $changes + 1`
-done
-
-# Identify files removed from working directory
-removedfiles=`cvs status | egrep '^File:[ ]*no file' | awk '{print $4}'`
-
-# Determine whether each file has been cvs removed
-for file in $removedfiles ; do
- if cvs status $file | grep -s '^From:[ ]*-' ; then
- echo "file removed: $file - not CVS committed"
- else
- echo "file removed: $file - not CVS removed, not CVS committed"
- fi
- changes=`expr $changes + 1`
-done
-
-exit $changes
diff --git a/gnu/usr.bin/cvs/contrib/cvscheck.man b/gnu/usr.bin/cvs/contrib/cvscheck.man
deleted file mode 100644
index 61a064aeeaf7..000000000000
--- a/gnu/usr.bin/cvs/contrib/cvscheck.man
+++ /dev/null
@@ -1,53 +0,0 @@
-.\" $Id: cvscheck.man,v 1.1.1.3 1995/08/28 16:20:24 jimb Exp $
-.\" Contributed by Lowell Skoog <fluke!lowell@uunet.uu.net>
-.TH CVSCHECK LOCAL "4 March 1991" FLUKE
-.SH NAME
-cvscheck \- identify files added, changed, or removed in a CVS working
-directory
-.SH SYNOPSIS
-.B cvscheck
-.SH DESCRIPTION
-This command is a housekeeping aid. It should be run in a working
-directory that has been checked out using CVS. It identifies files
-that have been added, changed, or removed in the working directory, but
-not CVS
-.BR commit ted.
-It also determines whether the files have been CVS
-.BR add ed
-or CVS
-.BR remove d.
-For directories, this command determines only whether they have been
-.BR add ed.
-It operates in the current directory only.
-.LP
-This command provides information that is available using CVS
-.B status
-and CVS
-.BR diff .
-The advantage of
-.B cvscheck
-is that its output is very concise. It saves you the strain (and
-potential error) of interpreting the output of CVS
-.B status
-and
-.BR diff .
-.LP
-See
-.BR cvs (local)
-or
-.BR cvshelp (local)
-for instructions on how to add or remove a file or directory in a
-CVS-controlled package.
-.SH DIAGNOSTICS
-The exit status is 0 if no files have been added, changed, or removed
-from the current directory. Otherwise, the command returns a count of
-the adds, changes, and deletes.
-.SH SEE ALSO
-.BR cvs (local),
-.BR cvshelp (local)
-.SH AUTHOR
-Lowell Skoog
-.br
-Software Technology Group
-.br
-Technical Computing
diff --git a/gnu/usr.bin/cvs/contrib/cvscheck.sh b/gnu/usr.bin/cvs/contrib/cvscheck.sh
deleted file mode 100644
index 96dba6e1f87e..000000000000
--- a/gnu/usr.bin/cvs/contrib/cvscheck.sh
+++ /dev/null
@@ -1,84 +0,0 @@
-#! /bin/sh
-# $Id: cvscheck.sh,v 1.1 1995/07/10 02:26:29 kfogel Exp $
-#
-# cvscheck - identify files added, changed, or removed
-# in CVS working directory
-#
-# Contributed by Lowell Skoog <fluke!lowell@uunet.uu.net>
-#
-# This program should be run in a working directory that has been
-# checked out using CVS. It identifies files that have been added,
-# changed, or removed in the working directory, but not "cvs
-# committed". It also determines whether the files have been "cvs
-# added" or "cvs removed". For directories, it is only practical to
-# determine whether they have been added.
-
-name=cvscheck
-changes=0
-
-# If we can't run CVS commands in this directory
-cvs status . > /dev/null 2>&1
-if [ $? != 0 ] ; then
-
- # Bail out
- echo "$name: there is no version here; bailing out" 1>&2
- exit 1
-fi
-
-# Identify files added to working directory
-for file in .* * ; do
-
- # Skip '.' and '..'
- if [ $file = '.' -o $file = '..' ] ; then
- continue
- fi
-
- # If a regular file
- if [ -f $file ] ; then
- if cvs status $file | grep -s '^From:[ ]*New file' ; then
- echo "file added: $file - not CVS committed"
- changes=`expr $changes + 1`
- elif cvs status $file | grep -s '^From:[ ]*no entry for' ; then
- echo "file added: $file - not CVS added, not CVS committed"
- changes=`expr $changes + 1`
- fi
-
- # Else if a directory
- elif [ -d $file -a $file != CVS.adm ] ; then
-
- # Move into it
- cd $file
-
- # If CVS commands don't work inside
- cvs status . > /dev/null 2>&1
- if [ $? != 0 ] ; then
- echo "directory added: $file - not CVS added"
- changes=`expr $changes + 1`
- fi
-
- # Move back up
- cd ..
- fi
-done
-
-# Identify changed files
-changedfiles=`cvs diff | egrep '^diff' | awk '{print $3}'`
-for file in $changedfiles ; do
- echo "file changed: $file - not CVS committed"
- changes=`expr $changes + 1`
-done
-
-# Identify files removed from working directory
-removedfiles=`cvs status | egrep '^File:[ ]*no file' | awk '{print $4}'`
-
-# Determine whether each file has been cvs removed
-for file in $removedfiles ; do
- if cvs status $file | grep -s '^From:[ ]*-' ; then
- echo "file removed: $file - not CVS committed"
- else
- echo "file removed: $file - not CVS removed, not CVS committed"
- fi
- changes=`expr $changes + 1`
-done
-
-exit $changes
diff --git a/gnu/usr.bin/cvs/contrib/cvshelp.man b/gnu/usr.bin/cvs/contrib/cvshelp.man
deleted file mode 100644
index 2cfae1f2bb8c..000000000000
--- a/gnu/usr.bin/cvs/contrib/cvshelp.man
+++ /dev/null
@@ -1,562 +0,0 @@
-.\" $Id: cvshelp.man,v 1.1.1.3 1995/08/28 16:20:28 jimb Exp $
-.\" Contributed by Lowell Skoog <fluke!lowell@uunet.uu.net>
-.\" Full space in nroff; half space in troff
-.de SP
-.if n .sp
-.if t .sp .5
-..
-.\" Start a command example
-.de XS
-.SP
-.in +.5i
-.ft B
-.nf
-..
-.\" End a command example
-.de XE
-.fi
-.ft P
-.in -.5i
-.SP
-..
-.TH CVSHELP LOCAL "17 March 1991" FLUKE
-.SH NAME
-cvshelp \- advice on using the Concurrent Versions System
-.SH DESCRIPTION
-This man page is based on experience using CVS.
-It is bound to change as we gain more experience.
-If you come up with better advice than is found here,
-contact the Software Technology
-Group and we will add it to this page.
-.SS "Getting Started"
-Use the following steps to prepare to use CVS:
-.TP
-\(bu
-Take a look at the CVS manual page to see what it can do for you, and
-if it fits your environment (or can possibly be made to fit your
-environment).
-.XS
-man cvs
-.XE
-If things look good, continue on...
-.TP
-\(bu
-Setup the master source repository. Choose a directory with
-ample disk space available for source files. This is where the RCS
-`,v' files will be stored. Say you choose
-.B /src/master
-as the root
-of your source repository. Make the
-.SB CVSROOT.adm
-directory in the root of the source repository:
-.XS
-mkdir /src/master/CVSROOT.adm
-.XE
-.TP
-\(bu
-Populate this directory with the
-.I loginfo
-and
-.I modules
-files from the
-.B "/usr/doc/local/cvs"
-directory. Edit these files to reflect your local source repository
-environment \- they may be quite small initially, but will grow as
-sources are added to your source repository. Turn these files into
-RCS controlled files:
-.XS
-cd /src/master/CVSROOT.adm
-ci \-m'Initial loginfo file' loginfo
-ci \-m'Initial modules file' modules
-.XE
-.TP
-\(bu
-Run the command:
-.XS
-mkmodules /src/master/CVSROOT.adm
-.XE
-This will build the
-.BR ndbm (3)
-file for the modules database.
-.TP
-\(bu
-Remember to edit the
-.I modules
-file manually when sources are checked
-in with
-.B checkin
-or CVS
-.BR add .
-A copy of the
-.I modules
-file for editing can be retrieved with the command:
-.XS
-cvs checkout CVSROOT.adm
-.XE
-.TP
-\(bu
-Have all users of the CVS system set the
-.SM CVSROOT
-environment variable appropriately to reflect the placement of your
-source repository. If the above example is used, the following
-commands can be placed in a
-.I .login
-or
-.I .profile
-file:
-.XS
-setenv CVSROOT /src/master
-.XE
-for csh users, and
-.XS
-CVSROOT=/src/master; export CVSROOT
-.XE
-for sh users.
-.SS "Placing Locally Written Sources Under CVS Control"
-Say you want to place the `whizbang' sources under
-CVS control. Say further that the sources have never
-been under revision control before.
-.TP
-\(bu
-Move the source hierarchy (lock, stock, and barrel)
-into the master source repository:
-.XS
-mv ~/whizbang $CVSROOT
-.XE
-.TP
-\(bu
-Clean out unwanted object files:
-.XS
-cd $CVSROOT/whizbang
-make clean
-.XE
-.TP
-\(bu
-Turn every file in the hierarchy into an RCS controlled file:
-.XS
-descend \-f 'ci \-t/dev/null \-m"Placed under CVS control" \-nV\fR\fIx\fR\fB_\fR\fIy\fR\fB *'
-.XE
-In this example, the initial release tag is \fBV\fIx\fB_\fIy\fR,
-representing version \fIx\fR.\fIy\fR.
-.LP
-You can use CVS on sources that are already under RCS control.
-The following example shows how.
-In this example, the source package is called `skunkworks'.
-.TP
-\(bu
-Move the source hierarchy into the master source
-repository:
-.XS
-mv ~/skunkworks $CVSROOT
-.XE
-.TP
-\(bu
-Clean out unwanted object files:
-.XS
-cd $CVSROOT/skunkworks
-make clean
-.XE
-.TP
-\(bu
-Clean out unwanted working files, leaving only the RCS `,v' files:
-.XS
-descend \-r rcsclean
-.XE
-Note: If any working files have been checked out and changed,
-.B rcsclean
-will fail. Check in the modified working files
-and run the command again.
-.TP
-\(bu
-Get rid of
-.SB RCS
-subdirectories. CVS does not use them.
-.XS
-descend \-r \-f 'mv RCS/*,v .'
-descend \-r \-f 'rmdir RCS'
-.XE
-.TP
-\(bu
-Delete any unwanted files that remain in the source hierarchy. Then
-make sure all files are under RCS control:
-.XS
-descend \-f 'ci \-t/dev/null \-m"Placed under CVS control" \-n\fR\fItag\fR\fB *'
-.XE
-.I tag
-is the latest symbolic revision tag that you applied to your package
-(if any). Note: This command will probably generate lots of error
-messages (for directories and existing RCS files) that you can
-ignore.
-.SS "Placing a Third-Party Source Distribution Under CVS Control"
-The
-.B checkin
-command checks third-party sources into CVS. The
-difference between third-party sources and locally
-written sources is that third-party sources must be checked into a
-separate branch (called the
-.IR "vendor branch" )
-of the RCS tree. This makes it possible to merge local changes to
-the sources with later releases from the vendor.
-.TP
-\(bu
-Save the original distribution kit somewhere. For example, if the
-master source repository is
-.B /src/master
-the distribution kit could be saved in
-.BR /src/dist .
-Organize the distribution directory so that each release
-is clearly identifiable.
-.TP
-\(bu
-Unpack the package in a scratch directory, for example
-.BR ~/scratch .
-.TP
-\(bu
-Create a repository for the package.
-In this example, the package is called `Bugs-R-Us 4.3'.
-.XS
-mkdir $CVSROOT/bugs
-.XE
-.TP
-\(bu
-Check in the unpacked files:
-.XS
-cd ~/scratch
-checkin \-m 'Bugs-R-Us 4.3 distribution' bugs VENDOR V4_3
-.XE
-There is nothing magic about the tag `VENDOR', which is applied to
-the vendor branch. You can use whatever tag you want. `VENDOR' is a
-useful convention.
-.TP
-\(bu
-Never modify vendor files before checking them in.
-Check in the files
-.I exactly
-as you unpacked them.
-If you check in locally modified files, future vendor releases may
-wipe out your local changes.
-.SS "Working With CVS-Controlled Sources"
-To use or edit the sources, you must check out a private copy.
-For the following examples, the master files are assumed to reside in
-.BR "$CVSROOT/behemoth" .
-The working directory is
-.BR "~/work" .
-See
-.BR cvs (local)
-for more details on the commands mentioned below.
-.TP
-.I "To Check Out Working Files
-Use CVS
-.BR checkout :
-.XS
-cd ~/work
-cvs checkout behemoth
-.XE
-There is nothing magic about the working directory. CVS will check
-out sources anywhere you like. Once you have a working copy of the
-sources, you can compile or edit them as desired.
-.TP
-.I "To Display Changes You Have Made"
-Use CVS
-.BR diff
-to display detailed changes, equivalent to
-.BR rcsdiff (local).
-You can also use
-.BR cvscheck (local)
-to list files added, changed, and removed in
-the directory, but not yet
-.BR commit ted.
-You must be in a directory containing working files.
-.TP
-.I "To Display Revision Information"
-Use CVS
-.BR log ,
-which is equivalent to
-.BR rlog (local).
-You must be in a directory containing working files.
-.TP
-.I "To Update Working Files"
-Use CVS
-.BR update
-in a directory containing working files.
-This command brings your working files up
-to date with changes checked into the
-master repository since you last checked out or updated
-your files.
-.TP
-.I "To Check In Your Changes"
-Use CVS
-.BR commit
-in a directory containing working files.
-This command checks your changes into the master repository.
-You can specify files by name or use
-.XS
-cvs commit \-a
-.XE
-to
-.B commit
-all the files you have changed.
-.TP
-.I "To Add a File"
-Add the file to the working directory.
-Use CVS
-.B add
-to mark the file as added.
-Use CVS
-.B commit
-to add the file to the master repository.
-.TP
-.I "To Remove a File"
-Remove the file from the working directory.
-Use CVS
-.B remove
-to mark the file as removed.
-Use CVS
-.B commit
-to move the file from its current location in the master repository
-to the CVS
-.IR Attic
-directory.
-.TP
-.I "To Add a Directory"
-Add the directory to the working directory.
-Use CVS
-.B add
-to add the directory to the master repository.
-.TP
-.I "To Remove a Directory"
-.br
-You shouldn't remove directories under CVS. You should instead remove
-their contents and then prune them (using the
-.B \-f
-and
-.B \-p
-options) when you
-.B checkout
-or
-.B update
-your working files.
-.TP
-.I "To Tag a Release"
-Use CVS
-.B tag
-to apply a symbolic tag to the latest revision of each file in the
-master repository. For example:
-.XS
-cvs tag V2_1 behemoth
-.XE
-.TP
-.I "To Retrieve an Exact Copy of a Previous Release"
-During a CVS
-.B checkout
-or
-.BR update ,
-use the
-.B \-r
-option to retrieve revisions associated with a symbolic tag.
-Use the
-.B \-f
-option to ignore all RCS files that do not contain the
-tag.
-Use the
-.B \-p
-option to prune directories that wind up empty because none
-of their files matched the tag. Example:
-.XS
-cd ~/work
-cvs checkout \-r V2_1 \-f \-p behemoth
-.XE
-.SS "Logging Changes"
-It is a good idea to keep a change log together with the
-sources. As a minimum, the change log should name and describe each
-tagged release. The change log should also be under CVS control and
-should be tagged along with the sources.
-.LP
-.BR cvslog (local)
-can help. This command logs
-changes reported during CVS
-.B commit
-operations. It automatically
-updates a change log file in your working directory. When you are
-finished making changes, you (optionally) edit the change log file and
-then commit it to the master repository.
-.LP
-Note: You must edit the change log to describe a new release
-and
-.B commit
-it to the master repository
-.I before
-.BR tag ging
-the release using CVS. Otherwise, the release description will not be
-included in the tagged package.
-.LP
-See
-.BR cvslog (local)
-for more information.
-.SS "Merging a Subsequent Third-Party Distribution"
-The initial steps in this process are identical to placing a
-third-party distribution under CVS for the first time: save the
-distribution kit and unpack the package in a scratch directory. From
-that point the steps diverge.
-The following example considers release 5.0 of the
-Bugs-R-Us package.
-.TP
-\(bu
-Check in the sources after unpacking them:
-.XS
-cd ~/scratch
-checkin \-m 'Bugs-R-Us 5.0 distribution' bugs VENDOR V5_0 \\
- | tee ~/WARNINGS
-.XE
-It is important to save the output of
-.B checkin
-in a file
-because it lists the sources that have been locally modified.
-It is best to save the file in a different directory (for example,
-your home directory). Otherwise,
-.B checkin
-will try to check it into the master repository.
-.TP
-\(bu
-In your usual working directory, check out a fresh copy of the
-distribution that you just checked in.
-.XS
-cd ~/work
-cvs checkout \-r VENDOR bugs
-.XE
-The
-.B checkout
-command shown above retrieves the latest revision on the vendor branch.
-.TP
-\(bu
-See the `WARNINGS' file for a list of all locally modified
-sources.
-For each locally modified source,
-look at the differences between
-the new distribution and the latest local revision:
-.XS
-cvs diff \-r \fR\fILocalRev file\fR\fB
-.XE
-In this command,
-.I LocalRev
-is the latest
-numeric or symbolic revision
-on the RCS trunk of
-.IR file .
-You can use CVS
-.B log
-to get the revision history.
-.TP
-\(bu
-If your local modifications to a file have been incorporated into
-the vendor's distribution, then you should reset the default RCS
-branch for that file to the vendor branch. CVS doesn't provide a
-mechanism to do this. You have to do it by hand in the master
-repository:
-.XS
-rcs \-bVENDOR \fR\fIfile\fR\fB,v
-.XE
-.TP
-\(bu
-If your local modifications need to be merged with the
-new distribution, use CVS
-.B join
-to do it:
-.XS
-cvs join \-r VENDOR \fR\fIfile\fR\fB
-.XE
-The resulting file will be placed in your working directory.
-Edit it to resolve any overlaps.
-.TP
-\(bu
-Test the merged package.
-.TP
-\(bu
-Commit all modified files to the repository:
-.XS
-cvs commit \-a
-.XE
-.TP
-\(bu
-Tag the repository with a new local tag.
-.SS "Applying Patches to Third-Party Sources"
-Patches are handled in a manner very similar to complete
-third-party distributions. This example considers patches applied to
-Bugs-R-Us release 5.0.
-.TP
-\(bu
-Save the patch files together with the distribution kit
-to which they apply.
-The patch file names should clearly indicate the patch
-level.
-.TP
-\(bu
-In a scratch directory, check out the last `clean' vendor copy \- the
-highest revision on the vendor branch with
-.IR "no local changes" :
-.XS
-cd ~/scratch
-cvs checkout \-r VENDOR bugs
-.XE
-.TP
-\(bu
-Use
-.BR patch (local)
-to apply the patches. You should now have an image of the
-vendor's software just as though you had received a complete,
-new release.
-.TP
-\(bu
-Proceed with the steps described for merging a subsequent third-party
-distribution.
-.TP
-\(bu
-Note: When you get to the step that requires you
-to check out the new distribution after you have
-checked it into the vendor branch, you should move to a different
-directory. Do not attempt to
-.B checkout
-files in the directory in
-which you applied the patches. If you do, CVS will try to merge the
-changes that you made during patching with the version being checked
-out and things will get very confusing. Instead,
-go to a different directory (like your working directory) and
-check out the files there.
-.SS "Advice to Third-Party Source Hackers"
-As you can see from the preceding sections, merging local changes
-into third-party distributions remains difficult, and probably
-always will. This fact suggests some guidelines:
-.TP
-\(bu
-Minimize local changes.
-.I Never
-make stylistic changes.
-Change makefiles only as much as needed for installation. Avoid
-overhauling anything. Pray that the vendor does the same.
-.TP
-\(bu
-Avoid renaming files or moving them around.
-.TP
-\(bu
-Put independent, locally written files like help documents, local
-tools, or man pages in a sub-directory called `local-additions'.
-Locally written files that are linked into an existing executable
-should be added right in with the vendor's sources (not in a
-`local-additions' directory).
-If, in the future,
-the vendor distributes something
-equivalent to your locally written files
-you can CVS
-.B remove
-the files from the `local-additions' directory at that time.
-.SH SEE ALSO
-.BR cvs (local),
-.BR checkin (local),
-.BR cvslog (local),
-.BR cvscheck (local)
-.SH AUTHOR
-Lowell Skoog
-.br
-Software Technology Group
-.br
-Technical Computing
diff --git a/gnu/usr.bin/cvs/contrib/descend b/gnu/usr.bin/cvs/contrib/descend
deleted file mode 100644
index 999c46f4f0a8..000000000000
--- a/gnu/usr.bin/cvs/contrib/descend
+++ /dev/null
@@ -1,116 +0,0 @@
-#! /bin/sh
-# $Id: descend,v 1.1 1992/04/03 05:22:52 berliner Exp $
-#
-# descend - walk down a directory tree and execute a command at each node
-
-fullname=$0
-name=descend
-usage="Usage: $name [-afqrv] command [directory ...]\n
-\040\040-a\040\040All: descend into directories starting with '.'\n
-\040\040-f\040\040Force: ignore errors during descent\n
-\040\040-q\040\040Quiet: don't print directory names\n
-\040\040-r\040\040Restricted: don't descend into RCS, CVS.adm, SCCS directories\n
-\040\040-v\040\040Verbose: print command before executing it"
-
-# Scan for options
-while getopts afqrv option; do
- case $option in
- a)
- alldirs=$option
- options=$options" "-$option
- ;;
- f)
- force=$option
- options=$options" "-$option
- ;;
- q)
- verbose=
- quiet=$option
- options=$options" "-$option
- ;;
- r)
- restricted=$option
- options=$options" "-$option
- ;;
- v)
- verbose=$option
- quiet=
- options=$options" "-$option
- ;;
- \?)
- /usr/5bin/echo $usage 1>&2
- exit 1
- ;;
- esac
-done
-shift `expr $OPTIND - 1`
-
-# Get command to execute
-if [ $# -lt 1 ] ; then
- /usr/5bin/echo $usage 1>&2
- exit 1
-else
- command=$1
- shift
-fi
-
-# If no directory specified, use '.'
-if [ $# -lt 1 ] ; then
- default_dir=.
-fi
-
-# For each directory specified
-for dir in $default_dir "$@" ; do
-
- # Spawn sub-shell so we return to starting directory afterward
- (cd $dir
-
- # Execute specified command
- if [ -z "$quiet" ] ; then
- echo In directory `hostname`:`pwd`
- fi
- if [ -n "$verbose" ] ; then
- echo $command
- fi
- eval "$command" || if [ -z "$force" ] ; then exit 1; fi
-
- # Collect dot file names if necessary
- if [ -n "$alldirs" ] ; then
- dotfiles=.*
- else
- dotfiles=
- fi
-
- # For each file in current directory
- for file in $dotfiles * ; do
-
- # Skip '.' and '..'
- if [ "$file" = "." -o "$file" = ".." ] ; then
- continue
- fi
-
- # If a directory but not a symbolic link
- if [ -d "$file" -a ! -h "$file" ] ; then
-
- # If not skipping this type of directory
- if [ \( "$file" != "RCS" -a \
- "$file" != "SCCS" -a \
- "$file" != "CVS" -a \
- "$file" != "CVS.adm" \) \
- -o -z "$restricted" ] ; then
-
- # Recursively descend into it
- $fullname $options "$command" "$file" \
- || if [ -z "$force" ] ; then exit 1; fi
- fi
-
- # Else if a directory AND a symbolic link
- elif [ -d "$file" -a -h "$file" ] ; then
-
- if [ -z "$quiet" ] ; then
- echo In directory `hostname`:`pwd`/$file: symbolic link: skipping
- fi
- fi
- done
- ) || if [ -z "$force" ] ; then exit 1; fi
-done
diff --git a/gnu/usr.bin/cvs/contrib/descend.man b/gnu/usr.bin/cvs/contrib/descend.man
deleted file mode 100644
index 5ac46f499d25..000000000000
--- a/gnu/usr.bin/cvs/contrib/descend.man
+++ /dev/null
@@ -1,115 +0,0 @@
-.\" $Id: descend.man,v 1.1.1.3 1995/08/28 16:20:31 jimb Exp $
-.TH DESCEND 1 "31 March 1992"
-.SH NAME
-descend \- walk directory tree and execute a command at each node
-.SH SYNOPSIS
-.B descend
-[
-.B \-afqrv
-]
-.I command
-[
-.I directory
-\&.\|.\|.
-]
-.SH DESCRIPTION
-.B descend
-walks down a directory tree and executes a command at each node. It
-is not as versatile as
-.BR find (1),
-but it has a simpler syntax. If no
-.I directory
-is specified,
-.B descend
-starts at the current one.
-.LP
-Unlike
-.BR find ,
-.B descend
-can be told to skip the special directories associated with RCS,
-CVS, and SCCS. This makes
-.B descend
-especially handy for use with these packages. It can be used with
-other commands too, of course.
-.LP
-.B descend
-is a poor man's way to make any command recursive. Note:
-.B descend
-does not follow symbolic links to directories unless they are
-specified on the command line.
-.SH OPTIONS
-.TP 15
-.B \-a
-.I All.
-Descend into directories that begin with '.'.
-.TP
-.B \-f
-.I Force.
-Ignore errors during descent. Normally,
-.B descend
-quits when an error occurs.
-.TP
-.B \-q
-.I Quiet.
-Suppress the message `In directory
-.IR directory '
-that is normally printed during the descent.
-.TP
-.B \-r
-.I Restricted.
-Don't descend into the special directories
-.SB RCS,
-.SB CVS,
-.SB CVS.adm,
-and
-.SB SCCS.
-.TP
-.B \-v
-.I Verbose.
-Print
-.I command
-before executing it.
-.SH EXAMPLES
-.TP 15
-.B "descend ls"
-Cheap substitute for `ls -R'.
-.TP 15
-.B "descend -f 'rm *' tree"
-Strip `tree' of its leaves. This command descends the `tree'
-directory, removing all regular files. Since
-.BR rm (1)
-does not remove directories, this command leaves the directory
-structure of `tree' intact, but denuded. The
-.B \-f
-option is required to keep
-.B descend
-from quitting. You could use `rm \-f' instead.
-.TP
-.B "descend -r 'co RCS/*'" /project/src/
-Check out every RCS file under the directory
-.BR "/project/src" .
-.TP
-.B "descend -r 'cvs diff'"
-Perform CVS `diff' operation on every directory below (and including)
-the current one.
-.SH DIAGNOSTICS
-Returns 1 if errors occur (and the
-.B \-f
-option is not used). Otherwise returns 0.
-.SH SEE ALSO
-.BR find (1),
-.BR rcsintro (1),
-.BR cvs (1),
-.BR sccs (1)
-.SH AUTHOR
-Lowell Skoog
-.br
-Software Technology Group
-.br
-John Fluke Mfg. Co., Inc.
-.SH BUGS
-Shell metacharacters in
-.I command
-may have bizarre effects. In particular, compound commands
-(containing ';', '[', and ']' characters) will not work. It is best
-to enclose complicated commands in single quotes \(aa\ \(aa.
diff --git a/gnu/usr.bin/cvs/contrib/descend.sh b/gnu/usr.bin/cvs/contrib/descend.sh
deleted file mode 100644
index e6a788079416..000000000000
--- a/gnu/usr.bin/cvs/contrib/descend.sh
+++ /dev/null
@@ -1,116 +0,0 @@
-#! /bin/sh
-# $Id: descend.sh,v 1.1 1995/07/10 02:26:32 kfogel Exp $
-#
-# descend - walk down a directory tree and execute a command at each node
-
-fullname=$0
-name=descend
-usage="Usage: $name [-afqrv] command [directory ...]\n
-\040\040-a\040\040All: descend into directories starting with '.'\n
-\040\040-f\040\040Force: ignore errors during descent\n
-\040\040-q\040\040Quiet: don't print directory names\n
-\040\040-r\040\040Restricted: don't descend into RCS, CVS.adm, SCCS directories\n
-\040\040-v\040\040Verbose: print command before executing it"
-
-# Scan for options
-while getopts afqrv option; do
- case $option in
- a)
- alldirs=$option
- options=$options" "-$option
- ;;
- f)
- force=$option
- options=$options" "-$option
- ;;
- q)
- verbose=
- quiet=$option
- options=$options" "-$option
- ;;
- r)
- restricted=$option
- options=$options" "-$option
- ;;
- v)
- verbose=$option
- quiet=
- options=$options" "-$option
- ;;
- \?)
- /usr/5bin/echo $usage 1>&2
- exit 1
- ;;
- esac
-done
-shift `expr $OPTIND - 1`
-
-# Get command to execute
-if [ $# -lt 1 ] ; then
- /usr/5bin/echo $usage 1>&2
- exit 1
-else
- command=$1
- shift
-fi
-
-# If no directory specified, use '.'
-if [ $# -lt 1 ] ; then
- default_dir=.
-fi
-
-# For each directory specified
-for dir in $default_dir "$@" ; do
-
- # Spawn sub-shell so we return to starting directory afterward
- (cd $dir
-
- # Execute specified command
- if [ -z "$quiet" ] ; then
- echo In directory `hostname`:`pwd`
- fi
- if [ -n "$verbose" ] ; then
- echo $command
- fi
- eval "$command" || if [ -z "$force" ] ; then exit 1; fi
-
- # Collect dot file names if necessary
- if [ -n "$alldirs" ] ; then
- dotfiles=.*
- else
- dotfiles=
- fi
-
- # For each file in current directory
- for file in $dotfiles * ; do
-
- # Skip '.' and '..'
- if [ "$file" = "." -o "$file" = ".." ] ; then
- continue
- fi
-
- # If a directory but not a symbolic link
- if [ -d "$file" -a ! -h "$file" ] ; then
-
- # If not skipping this type of directory
- if [ \( "$file" != "RCS" -a \
- "$file" != "SCCS" -a \
- "$file" != "CVS" -a \
- "$file" != "CVS.adm" \) \
- -o -z "$restricted" ] ; then
-
- # Recursively descend into it
- $fullname $options "$command" "$file" \
- || if [ -z "$force" ] ; then exit 1; fi
- fi
-
- # Else if a directory AND a symbolic link
- elif [ -d "$file" -a -h "$file" ] ; then
-
- if [ -z "$quiet" ] ; then
- echo In directory `hostname`:`pwd`/$file: symbolic link: skipping
- fi
- fi
- done
- ) || if [ -z "$force" ] ; then exit 1; fi
-done
diff --git a/gnu/usr.bin/cvs/contrib/dirfns b/gnu/usr.bin/cvs/contrib/dirfns
deleted file mode 100644
index 8324c4198e35..000000000000
--- a/gnu/usr.bin/cvs/contrib/dirfns
+++ /dev/null
@@ -1,481 +0,0 @@
-echo 'directory.3':
-sed 's/^X//' >'directory.3' <<'!'
-X.TH DIRECTORY 3 imported
-X.DA 9 Oct 1985
-X.SH NAME
-Xopendir, readdir, telldir, seekdir, rewinddir, closedir \- high-level directory operations
-X.SH SYNOPSIS
-X.B #include <sys/types.h>
-X.br
-X.B #include <ndir.h>
-X.PP
-X.SM
-X.B DIR
-X.B *opendir(filename)
-X.br
-X.B char *filename;
-X.PP
-X.SM
-X.B struct direct
-X.B *readdir(dirp)
-X.br
-X.B DIR *dirp;
-X.PP
-X.SM
-X.B long
-X.B telldir(dirp)
-X.br
-X.B DIR *dirp;
-X.PP
-X.SM
-X.B seekdir(dirp, loc)
-X.br
-X.B DIR *dirp;
-X.br
-X.B long loc;
-X.PP
-X.SM
-X.B rewinddir(dirp)
-X.br
-X.B DIR *dirp;
-X.PP
-X.SM
-X.B closedir(dirp)
-X.br
-X.B DIR *dirp;
-X.SH DESCRIPTION
-XThis library provides high-level primitives for directory scanning,
-Xsimilar to those available for 4.2BSD's (very different) directory system.
-X.\"The purpose of this library is to simulate
-X.\"the new flexible length directory names of 4.2bsd UNIX
-X.\"on top of the old directory structure of v7.
-XIt incidentally provides easy portability to and from 4.2BSD (insofar
-Xas such portability is not compromised by other 4.2/VAX dependencies).
-X.\"It allows programs to be converted immediately
-X.\"to the new directory access interface,
-X.\"so that they need only be relinked
-X.\"when moved to 4.2bsd.
-X.\"It is obtained with the loader option
-X.\".BR \-lndir .
-X.PP
-X.I Opendir
-Xopens the directory named by
-X.I filename
-Xand associates a
-X.I directory stream
-Xwith it.
-X.I Opendir
-Xreturns a pointer to be used to identify the
-X.I directory stream
-Xin subsequent operations.
-XThe pointer
-X.SM
-X.B NULL
-Xis returned if
-X.I filename
-Xcannot be accessed or is not a directory.
-X.PP
-X.I Readdir
-Xreturns a pointer to the next directory entry.
-XIt returns
-X.B NULL
-Xupon reaching the end of the directory or detecting
-Xan invalid
-X.I seekdir
-Xoperation.
-X.PP
-X.I Telldir
-Xreturns the current location associated with the named
-X.I directory stream.
-X.PP
-X.I Seekdir
-Xsets the position of the next
-X.I readdir
-Xoperation on the
-X.I directory stream.
-XThe new position reverts to the one associated with the
-X.I directory stream
-Xwhen the
-X.I telldir
-Xoperation was performed.
-XValues returned by
-X.I telldir
-Xare good only for the lifetime of the DIR pointer from
-Xwhich they are derived.
-XIf the directory is closed and then reopened,
-Xthe
-X.I telldir
-Xvalue may be invalidated
-Xdue to undetected directory compaction in 4.2BSD.
-XIt is safe to use a previous
-X.I telldir
-Xvalue immediately after a call to
-X.I opendir
-Xand before any calls to
-X.I readdir.
-X.PP
-X.I Rewinddir
-Xresets the position of the named
-X.I directory stream
-Xto the beginning of the directory.
-X.PP
-X.I Closedir
-Xcauses the named
-X.I directory stream
-Xto be closed,
-Xand the structure associated with the DIR pointer to be freed.
-X.PP
-XA
-X.I direct
-Xstructure is as follows:
-X.PP
-X.RS
-X.nf
-Xstruct direct {
-X /* unsigned */ long d_ino; /* inode number of entry */
-X unsigned short d_reclen; /* length of this record */
-X unsigned short d_namlen; /* length of string in d_name */
-X char d_name[MAXNAMLEN + 1]; /* name must be no longer than this */
-X};
-X.fi
-X.RE
-X.PP
-XThe
-X.I d_reclen
-Xfield is meaningless in non-4.2BSD systems and should be ignored.
-XThe use of a
-X.I long
-Xfor
-X.I d_ino
-Xis also a 4.2BSDism;
-X.I ino_t
-X(see
-X.IR types (5))
-Xshould be used elsewhere.
-XThe macro
-X.I DIRSIZ(dp)
-Xgives the minimum memory size needed to hold the
-X.I direct
-Xvalue pointed to by
-X.IR dp ,
-Xwith the minimum necessary allocation for
-X.IR d_name .
-X.PP
-XThe preferred way to search the current directory for entry ``name'' is:
-X.PP
-X.RS
-X.nf
-X len = strlen(name);
-X dirp = opendir(".");
-X if (dirp == NULL) {
-X fprintf(stderr, "%s: can't read directory .\\n", argv[0]);
-X return NOT_FOUND;
-X }
-X while ((dp = readdir(dirp)) != NULL)
-X if (dp->d_namlen == len && strcmp(dp->d_name, name) == 0) {
-X closedir(dirp);
-X return FOUND;
-X }
-X closedir(dirp);
-X return NOT_FOUND;
-X.RE
-X.\".SH LINKING
-X.\"This library is accessed by specifying ``-lndir'' as the
-X.\"last argument to the compile line, e.g.:
-X.\".PP
-X.\" cc -I/usr/include/ndir -o prog prog.c -lndir
-X.SH "SEE ALSO"
-Xopen(2),
-Xclose(2),
-Xread(2),
-Xlseek(2)
-X.SH HISTORY
-XWritten by
-XKirk McKusick at Berkeley (ucbvax!mckusick).
-XMiscellaneous bug fixes from elsewhere.
-XThe size of the data structure has been decreased to avoid excessive
-Xspace waste under V7 (where filenames are 14 characters at most).
-XFor obscure historical reasons, the include file is also available
-Xas
-X.IR <ndir/sys/dir.h> .
-XThe Berkeley version lived in a separate library (\fI\-lndir\fR),
-Xwhereas ours is
-Xpart of the C library, although the separate library is retained to
-Xmaximize compatibility.
-X.PP
-XThis manual page has been substantially rewritten to be informative in
-Xthe absence of a 4.2BSD manual.
-X.SH BUGS
-XThe
-X.I DIRSIZ
-Xmacro actually wastes a bit of space due to some padding requirements
-Xthat are an artifact of 4.2BSD.
-X.PP
-XThe returned value of
-X.I readdir
-Xpoints to a static area that will be overwritten by subsequent calls.
-X.PP
-XThere are some unfortunate name conflicts with the \fIreal\fR V7
-Xdirectory structure definitions.
-!
-echo 'dir.h':
-sed 's/^X//' >'dir.h' <<'!'
-X/* dir.h 4.4 82/07/25 */
-X
-X/*
-X * A directory consists of some number of blocks of DIRBLKSIZ
-X * bytes, where DIRBLKSIZ is chosen such that it can be transferred
-X * to disk in a single atomic operation (e.g. 512 bytes on most machines).
-X *
-X * Each DIRBLKSIZ byte block contains some number of directory entry
-X * structures, which are of variable length. Each directory entry has
-X * a struct direct at the front of it, containing its inode number,
-X * the length of the entry, and the length of the name contained in
-X * the entry. These are followed by the name padded to a 4 byte boundary
-X * with null bytes. All names are guaranteed null terminated.
-X * The maximum length of a name in a directory is MAXNAMLEN.
-X *
-X * The macro DIRSIZ(dp) gives the amount of space required to represent
-X * a directory entry. Free space in a directory is represented by
-X * entries which have dp->d_reclen >= DIRSIZ(dp). All DIRBLKSIZ bytes
-X * in a directory block are claimed by the directory entries. This
-X * usually results in the last entry in a directory having a large
-X * dp->d_reclen. When entries are deleted from a directory, the
-X * space is returned to the previous entry in the same directory
-X * block by increasing its dp->d_reclen. If the first entry of
-X * a directory block is free, then its dp->d_ino is set to 0.
-X * Entries other than the first in a directory do not normally have
-X * dp->d_ino set to 0.
-X */
-X#define DIRBLKSIZ 512
-X#ifdef VMUNIX
-X#define MAXNAMLEN 255
-X#else
-X#define MAXNAMLEN 14
-X#endif
-X
-Xstruct direct {
-X /* unsigned */ long d_ino; /* inode number of entry */
-X unsigned short d_reclen; /* length of this record */
-X unsigned short d_namlen; /* length of string in d_name */
-X char d_name[MAXNAMLEN + 1]; /* name must be no longer than this */
-X};
-X
-X/*
-X * The DIRSIZ macro gives the minimum record length which will hold
-X * the directory entry. This requires the amount of space in struct direct
-X * without the d_name field, plus enough space for the name with a terminating
-X * null byte (dp->d_namlen+1), rounded up to a 4 byte boundary.
-X */
-X#undef DIRSIZ
-X#define DIRSIZ(dp) \
-X ((sizeof (struct direct) - (MAXNAMLEN+1)) + (((dp)->d_namlen+1 + 3) &~ 3))
-X
-X#ifndef KERNEL
-X/*
-X * Definitions for library routines operating on directories.
-X */
-Xtypedef struct _dirdesc {
-X int dd_fd;
-X long dd_loc;
-X long dd_size;
-X char dd_buf[DIRBLKSIZ];
-X} DIR;
-X#ifndef NULL
-X#define NULL 0
-X#endif
-Xextern DIR *opendir();
-Xextern struct direct *readdir();
-Xextern long telldir();
-X#ifdef void
-Xextern void seekdir();
-Xextern void closedir();
-X#endif
-X#define rewinddir(dirp) seekdir((dirp), (long)0)
-X#endif KERNEL
-!
-echo 'makefile':
-sed 's/^X//' >'makefile' <<'!'
-XDIR = closedir.o opendir.o readdir.o seekdir.o telldir.o
-XCFLAGS=-O -I. -Dvoid=int
-XDEST=..
-X
-Xall: $(DIR)
-X
-Xmv: $(DIR)
-X mv $(DIR) $(DEST)
-X
-Xcpif: dir.h
-X cp dir.h /usr/include/ndir.h
-X
-Xclean:
-X rm -f *.o
-!
-echo 'closedir.c':
-sed 's/^X//' >'closedir.c' <<'!'
-Xstatic char sccsid[] = "@(#)closedir.c 4.2 3/10/82";
-X
-X#include <sys/types.h>
-X#include <dir.h>
-X
-X/*
-X * close a directory.
-X */
-Xvoid
-Xclosedir(dirp)
-X register DIR *dirp;
-X{
-X close(dirp->dd_fd);
-X dirp->dd_fd = -1;
-X dirp->dd_loc = 0;
-X free((char *)dirp);
-X}
-!
-echo 'opendir.c':
-sed 's/^X//' >'opendir.c' <<'!'
-X/* Copyright (c) 1982 Regents of the University of California */
-X
-Xstatic char sccsid[] = "@(#)opendir.c 4.4 11/12/82";
-X
-X#include <sys/types.h>
-X#include <sys/stat.h>
-X#include <dir.h>
-X
-X/*
-X * open a directory.
-X */
-XDIR *
-Xopendir(name)
-X char *name;
-X{
-X register DIR *dirp;
-X register int fd;
-X struct stat statbuf;
-X char *malloc();
-X
-X if ((fd = open(name, 0)) == -1)
-X return NULL;
-X if (fstat(fd, &statbuf) == -1 || !(statbuf.st_mode & S_IFDIR)) {
-X close(fd);
-X return NULL;
-X }
-X if ((dirp = (DIR *)malloc(sizeof(DIR))) == NULL) {
-X close (fd);
-X return NULL;
-X }
-X dirp->dd_fd = fd;
-X dirp->dd_loc = 0;
-X dirp->dd_size = 0; /* so that telldir will work before readdir */
-X return dirp;
-X}
-!
-echo 'readdir.c':
-sed 's/^X//' >'readdir.c' <<'!'
-X/* Copyright (c) 1982 Regents of the University of California */
-X
-Xstatic char sccsid[] = "@(#)readdir.c 4.3 8/8/82";
-X
-X#include <sys/types.h>
-X#include <dir.h>
-X
-X/*
-X * read an old stlye directory entry and present it as a new one
-X */
-X#define ODIRSIZ 14
-X
-Xstruct olddirect {
-X ino_t od_ino;
-X char od_name[ODIRSIZ];
-X};
-X
-X/*
-X * get next entry in a directory.
-X */
-Xstruct direct *
-Xreaddir(dirp)
-X register DIR *dirp;
-X{
-X register struct olddirect *dp;
-X static struct direct dir;
-X
-X for (;;) {
-X if (dirp->dd_loc == 0) {
-X dirp->dd_size = read(dirp->dd_fd, dirp->dd_buf,
-X DIRBLKSIZ);
-X if (dirp->dd_size <= 0) {
-X dirp->dd_size = 0;
-X return NULL;
-X }
-X }
-X if (dirp->dd_loc >= dirp->dd_size) {
-X dirp->dd_loc = 0;
-X continue;
-X }
-X dp = (struct olddirect *)(dirp->dd_buf + dirp->dd_loc);
-X dirp->dd_loc += sizeof(struct olddirect);
-X if (dp->od_ino == 0)
-X continue;
-X dir.d_ino = dp->od_ino;
-X strncpy(dir.d_name, dp->od_name, ODIRSIZ);
-X dir.d_name[ODIRSIZ] = '\0'; /* insure null termination */
-X dir.d_namlen = strlen(dir.d_name);
-X dir.d_reclen = DIRBLKSIZ;
-X return (&dir);
-X }
-X}
-!
-echo 'seekdir.c':
-sed 's/^X//' >'seekdir.c' <<'!'
-Xstatic char sccsid[] = "@(#)seekdir.c 4.9 3/25/83";
-X
-X#include <sys/param.h>
-X#include <dir.h>
-X
-X/*
-X * seek to an entry in a directory.
-X * Only values returned by "telldir" should be passed to seekdir.
-X */
-Xvoid
-Xseekdir(dirp, loc)
-X register DIR *dirp;
-X long loc;
-X{
-X long curloc, base, offset;
-X struct direct *dp;
-X extern long lseek();
-X
-X curloc = telldir(dirp);
-X if (loc == curloc)
-X return;
-X base = loc & ~(DIRBLKSIZ - 1);
-X offset = loc & (DIRBLKSIZ - 1);
-X (void) lseek(dirp->dd_fd, base, 0);
-X dirp->dd_size = 0;
-X dirp->dd_loc = 0;
-X while (dirp->dd_loc < offset) {
-X dp = readdir(dirp);
-X if (dp == NULL)
-X return;
-X }
-X}
-!
-echo 'telldir.c':
-sed 's/^X//' >'telldir.c' <<'!'
-Xstatic char sccsid[] = "@(#)telldir.c 4.1 2/21/82";
-X
-X#include <sys/types.h>
-X#include <dir.h>
-X
-X/*
-X * return a pointer into a directory
-X */
-Xlong
-Xtelldir(dirp)
-X DIR *dirp;
-X{
-X long lseek();
-X
-X return (lseek(dirp->dd_fd, 0L, 1) - dirp->dd_size + dirp->dd_loc);
-X}
-!
-echo done
diff --git a/gnu/usr.bin/cvs/contrib/dirfns.shar b/gnu/usr.bin/cvs/contrib/dirfns.shar
deleted file mode 100644
index 8324c4198e35..000000000000
--- a/gnu/usr.bin/cvs/contrib/dirfns.shar
+++ /dev/null
@@ -1,481 +0,0 @@
-echo 'directory.3':
-sed 's/^X//' >'directory.3' <<'!'
-X.TH DIRECTORY 3 imported
-X.DA 9 Oct 1985
-X.SH NAME
-Xopendir, readdir, telldir, seekdir, rewinddir, closedir \- high-level directory operations
-X.SH SYNOPSIS
-X.B #include <sys/types.h>
-X.br
-X.B #include <ndir.h>
-X.PP
-X.SM
-X.B DIR
-X.B *opendir(filename)
-X.br
-X.B char *filename;
-X.PP
-X.SM
-X.B struct direct
-X.B *readdir(dirp)
-X.br
-X.B DIR *dirp;
-X.PP
-X.SM
-X.B long
-X.B telldir(dirp)
-X.br
-X.B DIR *dirp;
-X.PP
-X.SM
-X.B seekdir(dirp, loc)
-X.br
-X.B DIR *dirp;
-X.br
-X.B long loc;
-X.PP
-X.SM
-X.B rewinddir(dirp)
-X.br
-X.B DIR *dirp;
-X.PP
-X.SM
-X.B closedir(dirp)
-X.br
-X.B DIR *dirp;
-X.SH DESCRIPTION
-XThis library provides high-level primitives for directory scanning,
-Xsimilar to those available for 4.2BSD's (very different) directory system.
-X.\"The purpose of this library is to simulate
-X.\"the new flexible length directory names of 4.2bsd UNIX
-X.\"on top of the old directory structure of v7.
-XIt incidentally provides easy portability to and from 4.2BSD (insofar
-Xas such portability is not compromised by other 4.2/VAX dependencies).
-X.\"It allows programs to be converted immediately
-X.\"to the new directory access interface,
-X.\"so that they need only be relinked
-X.\"when moved to 4.2bsd.
-X.\"It is obtained with the loader option
-X.\".BR \-lndir .
-X.PP
-X.I Opendir
-Xopens the directory named by
-X.I filename
-Xand associates a
-X.I directory stream
-Xwith it.
-X.I Opendir
-Xreturns a pointer to be used to identify the
-X.I directory stream
-Xin subsequent operations.
-XThe pointer
-X.SM
-X.B NULL
-Xis returned if
-X.I filename
-Xcannot be accessed or is not a directory.
-X.PP
-X.I Readdir
-Xreturns a pointer to the next directory entry.
-XIt returns
-X.B NULL
-Xupon reaching the end of the directory or detecting
-Xan invalid
-X.I seekdir
-Xoperation.
-X.PP
-X.I Telldir
-Xreturns the current location associated with the named
-X.I directory stream.
-X.PP
-X.I Seekdir
-Xsets the position of the next
-X.I readdir
-Xoperation on the
-X.I directory stream.
-XThe new position reverts to the one associated with the
-X.I directory stream
-Xwhen the
-X.I telldir
-Xoperation was performed.
-XValues returned by
-X.I telldir
-Xare good only for the lifetime of the DIR pointer from
-Xwhich they are derived.
-XIf the directory is closed and then reopened,
-Xthe
-X.I telldir
-Xvalue may be invalidated
-Xdue to undetected directory compaction in 4.2BSD.
-XIt is safe to use a previous
-X.I telldir
-Xvalue immediately after a call to
-X.I opendir
-Xand before any calls to
-X.I readdir.
-X.PP
-X.I Rewinddir
-Xresets the position of the named
-X.I directory stream
-Xto the beginning of the directory.
-X.PP
-X.I Closedir
-Xcauses the named
-X.I directory stream
-Xto be closed,
-Xand the structure associated with the DIR pointer to be freed.
-X.PP
-XA
-X.I direct
-Xstructure is as follows:
-X.PP
-X.RS
-X.nf
-Xstruct direct {
-X /* unsigned */ long d_ino; /* inode number of entry */
-X unsigned short d_reclen; /* length of this record */
-X unsigned short d_namlen; /* length of string in d_name */
-X char d_name[MAXNAMLEN + 1]; /* name must be no longer than this */
-X};
-X.fi
-X.RE
-X.PP
-XThe
-X.I d_reclen
-Xfield is meaningless in non-4.2BSD systems and should be ignored.
-XThe use of a
-X.I long
-Xfor
-X.I d_ino
-Xis also a 4.2BSDism;
-X.I ino_t
-X(see
-X.IR types (5))
-Xshould be used elsewhere.
-XThe macro
-X.I DIRSIZ(dp)
-Xgives the minimum memory size needed to hold the
-X.I direct
-Xvalue pointed to by
-X.IR dp ,
-Xwith the minimum necessary allocation for
-X.IR d_name .
-X.PP
-XThe preferred way to search the current directory for entry ``name'' is:
-X.PP
-X.RS
-X.nf
-X len = strlen(name);
-X dirp = opendir(".");
-X if (dirp == NULL) {
-X fprintf(stderr, "%s: can't read directory .\\n", argv[0]);
-X return NOT_FOUND;
-X }
-X while ((dp = readdir(dirp)) != NULL)
-X if (dp->d_namlen == len && strcmp(dp->d_name, name) == 0) {
-X closedir(dirp);
-X return FOUND;
-X }
-X closedir(dirp);
-X return NOT_FOUND;
-X.RE
-X.\".SH LINKING
-X.\"This library is accessed by specifying ``-lndir'' as the
-X.\"last argument to the compile line, e.g.:
-X.\".PP
-X.\" cc -I/usr/include/ndir -o prog prog.c -lndir
-X.SH "SEE ALSO"
-Xopen(2),
-Xclose(2),
-Xread(2),
-Xlseek(2)
-X.SH HISTORY
-XWritten by
-XKirk McKusick at Berkeley (ucbvax!mckusick).
-XMiscellaneous bug fixes from elsewhere.
-XThe size of the data structure has been decreased to avoid excessive
-Xspace waste under V7 (where filenames are 14 characters at most).
-XFor obscure historical reasons, the include file is also available
-Xas
-X.IR <ndir/sys/dir.h> .
-XThe Berkeley version lived in a separate library (\fI\-lndir\fR),
-Xwhereas ours is
-Xpart of the C library, although the separate library is retained to
-Xmaximize compatibility.
-X.PP
-XThis manual page has been substantially rewritten to be informative in
-Xthe absence of a 4.2BSD manual.
-X.SH BUGS
-XThe
-X.I DIRSIZ
-Xmacro actually wastes a bit of space due to some padding requirements
-Xthat are an artifact of 4.2BSD.
-X.PP
-XThe returned value of
-X.I readdir
-Xpoints to a static area that will be overwritten by subsequent calls.
-X.PP
-XThere are some unfortunate name conflicts with the \fIreal\fR V7
-Xdirectory structure definitions.
-!
-echo 'dir.h':
-sed 's/^X//' >'dir.h' <<'!'
-X/* dir.h 4.4 82/07/25 */
-X
-X/*
-X * A directory consists of some number of blocks of DIRBLKSIZ
-X * bytes, where DIRBLKSIZ is chosen such that it can be transferred
-X * to disk in a single atomic operation (e.g. 512 bytes on most machines).
-X *
-X * Each DIRBLKSIZ byte block contains some number of directory entry
-X * structures, which are of variable length. Each directory entry has
-X * a struct direct at the front of it, containing its inode number,
-X * the length of the entry, and the length of the name contained in
-X * the entry. These are followed by the name padded to a 4 byte boundary
-X * with null bytes. All names are guaranteed null terminated.
-X * The maximum length of a name in a directory is MAXNAMLEN.
-X *
-X * The macro DIRSIZ(dp) gives the amount of space required to represent
-X * a directory entry. Free space in a directory is represented by
-X * entries which have dp->d_reclen >= DIRSIZ(dp). All DIRBLKSIZ bytes
-X * in a directory block are claimed by the directory entries. This
-X * usually results in the last entry in a directory having a large
-X * dp->d_reclen. When entries are deleted from a directory, the
-X * space is returned to the previous entry in the same directory
-X * block by increasing its dp->d_reclen. If the first entry of
-X * a directory block is free, then its dp->d_ino is set to 0.
-X * Entries other than the first in a directory do not normally have
-X * dp->d_ino set to 0.
-X */
-X#define DIRBLKSIZ 512
-X#ifdef VMUNIX
-X#define MAXNAMLEN 255
-X#else
-X#define MAXNAMLEN 14
-X#endif
-X
-Xstruct direct {
-X /* unsigned */ long d_ino; /* inode number of entry */
-X unsigned short d_reclen; /* length of this record */
-X unsigned short d_namlen; /* length of string in d_name */
-X char d_name[MAXNAMLEN + 1]; /* name must be no longer than this */
-X};
-X
-X/*
-X * The DIRSIZ macro gives the minimum record length which will hold
-X * the directory entry. This requires the amount of space in struct direct
-X * without the d_name field, plus enough space for the name with a terminating
-X * null byte (dp->d_namlen+1), rounded up to a 4 byte boundary.
-X */
-X#undef DIRSIZ
-X#define DIRSIZ(dp) \
-X ((sizeof (struct direct) - (MAXNAMLEN+1)) + (((dp)->d_namlen+1 + 3) &~ 3))
-X
-X#ifndef KERNEL
-X/*
-X * Definitions for library routines operating on directories.
-X */
-Xtypedef struct _dirdesc {
-X int dd_fd;
-X long dd_loc;
-X long dd_size;
-X char dd_buf[DIRBLKSIZ];
-X} DIR;
-X#ifndef NULL
-X#define NULL 0
-X#endif
-Xextern DIR *opendir();
-Xextern struct direct *readdir();
-Xextern long telldir();
-X#ifdef void
-Xextern void seekdir();
-Xextern void closedir();
-X#endif
-X#define rewinddir(dirp) seekdir((dirp), (long)0)
-X#endif KERNEL
-!
-echo 'makefile':
-sed 's/^X//' >'makefile' <<'!'
-XDIR = closedir.o opendir.o readdir.o seekdir.o telldir.o
-XCFLAGS=-O -I. -Dvoid=int
-XDEST=..
-X
-Xall: $(DIR)
-X
-Xmv: $(DIR)
-X mv $(DIR) $(DEST)
-X
-Xcpif: dir.h
-X cp dir.h /usr/include/ndir.h
-X
-Xclean:
-X rm -f *.o
-!
-echo 'closedir.c':
-sed 's/^X//' >'closedir.c' <<'!'
-Xstatic char sccsid[] = "@(#)closedir.c 4.2 3/10/82";
-X
-X#include <sys/types.h>
-X#include <dir.h>
-X
-X/*
-X * close a directory.
-X */
-Xvoid
-Xclosedir(dirp)
-X register DIR *dirp;
-X{
-X close(dirp->dd_fd);
-X dirp->dd_fd = -1;
-X dirp->dd_loc = 0;
-X free((char *)dirp);
-X}
-!
-echo 'opendir.c':
-sed 's/^X//' >'opendir.c' <<'!'
-X/* Copyright (c) 1982 Regents of the University of California */
-X
-Xstatic char sccsid[] = "@(#)opendir.c 4.4 11/12/82";
-X
-X#include <sys/types.h>
-X#include <sys/stat.h>
-X#include <dir.h>
-X
-X/*
-X * open a directory.
-X */
-XDIR *
-Xopendir(name)
-X char *name;
-X{
-X register DIR *dirp;
-X register int fd;
-X struct stat statbuf;
-X char *malloc();
-X
-X if ((fd = open(name, 0)) == -1)
-X return NULL;
-X if (fstat(fd, &statbuf) == -1 || !(statbuf.st_mode & S_IFDIR)) {
-X close(fd);
-X return NULL;
-X }
-X if ((dirp = (DIR *)malloc(sizeof(DIR))) == NULL) {
-X close (fd);
-X return NULL;
-X }
-X dirp->dd_fd = fd;
-X dirp->dd_loc = 0;
-X dirp->dd_size = 0; /* so that telldir will work before readdir */
-X return dirp;
-X}
-!
-echo 'readdir.c':
-sed 's/^X//' >'readdir.c' <<'!'
-X/* Copyright (c) 1982 Regents of the University of California */
-X
-Xstatic char sccsid[] = "@(#)readdir.c 4.3 8/8/82";
-X
-X#include <sys/types.h>
-X#include <dir.h>
-X
-X/*
-X * read an old stlye directory entry and present it as a new one
-X */
-X#define ODIRSIZ 14
-X
-Xstruct olddirect {
-X ino_t od_ino;
-X char od_name[ODIRSIZ];
-X};
-X
-X/*
-X * get next entry in a directory.
-X */
-Xstruct direct *
-Xreaddir(dirp)
-X register DIR *dirp;
-X{
-X register struct olddirect *dp;
-X static struct direct dir;
-X
-X for (;;) {
-X if (dirp->dd_loc == 0) {
-X dirp->dd_size = read(dirp->dd_fd, dirp->dd_buf,
-X DIRBLKSIZ);
-X if (dirp->dd_size <= 0) {
-X dirp->dd_size = 0;
-X return NULL;
-X }
-X }
-X if (dirp->dd_loc >= dirp->dd_size) {
-X dirp->dd_loc = 0;
-X continue;
-X }
-X dp = (struct olddirect *)(dirp->dd_buf + dirp->dd_loc);
-X dirp->dd_loc += sizeof(struct olddirect);
-X if (dp->od_ino == 0)
-X continue;
-X dir.d_ino = dp->od_ino;
-X strncpy(dir.d_name, dp->od_name, ODIRSIZ);
-X dir.d_name[ODIRSIZ] = '\0'; /* insure null termination */
-X dir.d_namlen = strlen(dir.d_name);
-X dir.d_reclen = DIRBLKSIZ;
-X return (&dir);
-X }
-X}
-!
-echo 'seekdir.c':
-sed 's/^X//' >'seekdir.c' <<'!'
-Xstatic char sccsid[] = "@(#)seekdir.c 4.9 3/25/83";
-X
-X#include <sys/param.h>
-X#include <dir.h>
-X
-X/*
-X * seek to an entry in a directory.
-X * Only values returned by "telldir" should be passed to seekdir.
-X */
-Xvoid
-Xseekdir(dirp, loc)
-X register DIR *dirp;
-X long loc;
-X{
-X long curloc, base, offset;
-X struct direct *dp;
-X extern long lseek();
-X
-X curloc = telldir(dirp);
-X if (loc == curloc)
-X return;
-X base = loc & ~(DIRBLKSIZ - 1);
-X offset = loc & (DIRBLKSIZ - 1);
-X (void) lseek(dirp->dd_fd, base, 0);
-X dirp->dd_size = 0;
-X dirp->dd_loc = 0;
-X while (dirp->dd_loc < offset) {
-X dp = readdir(dirp);
-X if (dp == NULL)
-X return;
-X }
-X}
-!
-echo 'telldir.c':
-sed 's/^X//' >'telldir.c' <<'!'
-Xstatic char sccsid[] = "@(#)telldir.c 4.1 2/21/82";
-X
-X#include <sys/types.h>
-X#include <dir.h>
-X
-X/*
-X * return a pointer into a directory
-X */
-Xlong
-Xtelldir(dirp)
-X DIR *dirp;
-X{
-X long lseek();
-X
-X return (lseek(dirp->dd_fd, 0L, 1) - dirp->dd_size + dirp->dd_loc);
-X}
-!
-echo done
diff --git a/gnu/usr.bin/cvs/contrib/easy-import.perl b/gnu/usr.bin/cvs/contrib/easy-import.perl
deleted file mode 100644
index 59d407a913d1..000000000000
--- a/gnu/usr.bin/cvs/contrib/easy-import.perl
+++ /dev/null
@@ -1,365 +0,0 @@
-#!/usr/bin/perl
-#
-# Support for importing a source collection into CVS.
-# Tries to prevent the user from the most common pitfalls (like creating
-# new top-level repositories or second-level areas accidentally), and
-# cares to do some of the `dirty' work like maintaining the modules
-# database accordingly.
-#
-# Written by Jörg Wunsch, 95/03/07, and placed in the public domain.
-#
-
-require "complete.pl";
-require "getopts.pl";
-
-
-sub scan_opts
-{
- &Getopts("n");
-
- $dont_do_it = "-n" if $opt_n;
-
- die "usage: $0 [-n] [moduledir]\n" .
- " -n: don't do any commit, show only\n"
- unless $#ARGV <= 0;
-
- $moduledir = $ARGV[0] if $#ARGV == 0;
-}
-
-sub lsdir
-{
- # find all subdirectories under @_
- # ignore all CVS entries, dot entries, and non-directories
-
- local($base) = @_;
- local(@ls, @rv, $fname);
-
- opendir(DIR, $base) || die "Cannot find dir $base.\n";
-
- @ls = readdir(DIR);
- closedir(DIR);
-
- @rv = ();
-
- foreach $fname (@ls) {
- next if $fname =~ /^CVS/ || $fname eq "Attic"
- || $fname =~ /^\./ || ! -d "$base/$fname";
- @rv = (@rv, $fname);
- }
-
- return sort(@rv);
-}
-
-
-sub contains
-{
- # look if the first parameter is contained in the list following it
- local($item, @list) = @_;
- local($found, $i);
-
- $found = 0;
- foreach $i (@list) {
- return 1 if $i eq $item;
- }
- return 0;
-}
-
-
-
-sub term_init
-{
- # first, get some terminal attributes
-
- # try bold mode first
- $so = `tput md`; $se = `tput me`;
-
- # if no bold mode available, use standout mode
- if ($so eq "") {
- $so = `tput so`; $se = `tput se`;
- }
-
- # try if we can underscore
- $us = `tput us`; $ue = `tput ue`;
- # if we don't have it available, or same as bold/standout, disable it
- if ($us eq "" || $us eq $so) {
- $us = $ue = "";
- }
-
- # look how many columns we've got
- if($ENV{'COLUMNS'} ne "") {
- $columns = $ENV{'COLUMNS'};
- } elsif(-t STDIN) { # if we operate on a terminal...
- local($word, $tmp);
-
- open(STTY, "stty -a|");
- $_ = <STTY>; # try getting the tty win structure value
- close(STTY);
- chop;
- $columns = 0;
- foreach $word (split) {
- $columns = $tmp if $word eq "columns;"; # the number preceding
- $tmp = $word;
- }
- } else {
- $columns = 80;
- }
- # sanity
- $columns = 80 unless $columns >= 5;
-}
-
-
-sub list
-{
- # pretty-print a list
- # imports: global variable $columns
- local(@items) = @_;
- local($longest,$i,$item,$cols,$width);
-
- # find the longest item
- $longest = 0;
- foreach $item (@items) {
- $i = length($item);
- $longest = $i if $longest < $i;
- }
- $width = $longest + 1;
- $cols = int($columns / $width);
-
- $i = 0;
- foreach $item (@items) {
- print $item;
- if(++$i == $cols) {
- $i = 0; print "\n";
- } else {
- print ' ' x ($width - length($item));
- }
- }
- print "\n" unless $i == 0;
-}
-
-sub cvs_init
-{
- # get the CVS repository(s)
-
- die "You need to have the \$CVSROOT variable set.\n"
- unless $ENV{'CVSROOT'} ne "";
-
- # get the list of available repositories
- $cvsroot = $ENV{'CVSROOT'};
- @reps = &lsdir($cvsroot);
-}
-
-
-sub lsmodules
-{
- # list all known CVS modules
- local(@rv, $mname, $_);
-
- @rv = ();
-
- open(CVS, "cvs co -c|");
- while($_ = <CVS>) {
- chop;
- ($mname) = split;
- next if $mname eq "";
- @rv = (@rv, $mname);
- }
- close(CVS);
-
- return @rv;
-}
-
-
-sub checktag
-{
- # check a given string for tag rules
- local($s) = @_;
- return 0 if($s !~ /^[A-Za-z][A-Za-z0-9_]*$/);
-
- return 1;
-}
-
-
-&scan_opts;
-&term_init;
-&cvs_init;
-
-if(! $moduledir) {
- @dirs = &lsdir(".");
- print "${so}Import from which directory?${se}\n";
- @dirs = (@dirs, ".");
- &list(@dirs);
- $moduledir = &Complete("Which? [.]: ", @dirs);
- $moduledir = "." unless $moduledir ne "";
-}
-
-chdir $moduledir || die "Cannot chdir to $moduledir\n";
-
-print "${so}Available repositories:${se}\n";
-&list(@reps);
-
-# the following kludge prevents the Complete package from starting
-# over with the string just selected; Complete should better provide
-# some reinitialize method
-$Complete'return = ""; $Complete'r = 0;
-
-$selected =
- &Complete("Enter repository (<TAB>=complete, ^D=show): ",
- @reps);
-
-die "\aYou cannot create new repositories with this script.\n"
- unless &contains($selected, @reps);
-
-$rep = $selected;
-
-print "\n${so}Selected repository:${se} ${us}$rep${ue}\n";
-
-
-@areas = &lsdir("$cvsroot/$rep");
-
-print "${so}Existent areas in this repository:${se}\n";
-&list(@areas);
-
-$Complete'return = ""; $Complete'r = 0;
-
-$selected =
- &Complete("Enter area name (<TAB>=complete, ^D=show): ",
- @areas);
-
-print "\a${us}Warning: this will create a new area.${ue}\n"
- unless &contains($selected, @areas);
-
-$area = "$rep/$selected";
-
-print "\n${so}[Working on:${se} ${us}$area${ue}${so}]${se}\n";
-
-for(;;) {
- $| = 1;
- print "${so}Enter the module path:${se} $area/";
- $| = 0;
- $modpath = <>;
- chop $modpath;
- if ($modpath eq "") {
- print "\a${us}You cannot use an empty module path.${ue}\n";
- next;
- }
- last if ! -d "$cvsroot/$area/$modpath";
- print "\a${us}This module path does already exist; " .
- "choose another one.${ue}\n";
-}
-
-
-@newdirs = ();
-$dir1 = "$cvsroot/$area";
-$dir2 = "$area";
-
-@newdirs = (@newdirs, "$dir2") if ! -d $dir1;
-
-foreach $ele (split(/\//, $modpath)) {
- $dir1 = "$dir1/$ele";
- $dir2 = "$dir2/$ele";
- @newdirs = (@newdirs, "$dir2") if ! -d $dir1;
-}
-
-print "${so}You're going to create the following new directories:${se}\n";
-
-&list(@newdirs);
-
-@cvsmods = &lsmodules();
-
-for(;;) {
- $| = 1;
- print "${so}Gimme the module name:${se} ";
- $| = 0;
- $modname = <>;
- chop $modname;
- if ($modname eq "") {
- print "\a${us}You cannot use an empty module name.${ue}\n";
- next;
- }
- last if !&contains($modname, @cvsmods);
- print "\a${us}This module name does already exist; " .
- "choose another one.${ue}\n";
-}
-
-
-for(;;) {
- $| = 1;
- print "${so}Enter a \`vendor\' tag (e. g. the authors ID):${se} ";
- $| = 0;
- $vtag = <>;
- chop $vtag;
- last if &checktag($vtag);
- print "\a${us}Valid tags must match the regexp " .
- "^[A-Za-z][A-Za-z0-9_]*\$.${ue}\n";
-}
-
-for(;;) {
- $| = 1;
- print "${so}Enter a \`release\' tag (e. g. the version #):${se} ";
- $| = 0;
- $rtag = <>;
- chop $rtag;
- last if &checktag($rtag);
- print "\a${us}Valid tags must match the regexp " .
- "^[A-Za-z][A-Za-z0-9_]*\$.${ue}\n";
-}
-
-
-$| = 1;
-print "${so}This is your last chance to interrupt, " .
- "hit <return> to go on:${se} ";
-$| = 0;
-<>;
-
-$mod = "";
-foreach $tmp (@cvsmods) {
- if($tmp gt $modname) {
- $mod = $tmp;
- last;
- }
-}
-
-if($mod eq "") {
- # we are going to append our module
- $cmd = "\$\na\n";
-} else {
- # we can insert it
- $cmd = "/^${mod}[ \t]/\ni\n";
-}
-
-print "${so}Checking out the modules database...${se}\n";
-system("cvs co modules") && die "${us}failed.\n${ue}";
-
-print "${so}Inserting new module...${se}\n";
-open(ED, "|ed modules/modules") || die "${us}Cannot start ed${ue}\n";
-print(ED "${cmd}${modname}" . ' ' x (16 - length($modname)) .
- "$area/${modpath}\n.\nw\nq\n");
-close(ED);
-
-print "${so}Commiting new modules database...${se}\n";
-system("cvs $dont_do_it commit -m \" " .
- "${modname} --> $area/${modpath}\" modules")
- && die "Commit failed\n";
-
-system("cvs $dont_do_it release -dQ modules");
-
-print "${so}Importing source. Enter a commit message in the editor.${se}\n";
-
-system("cvs $dont_do_it import $area/$modpath $vtag $rtag");
-
-print "${so}You are done now. Go to a different directory, perform a${se}\n".
- "${us}cvs co ${modname}${ue} ${so}command, and see if your new module" .
- " builds ok.${se}\n";
-
-if($dont_do_it) {
-print <<END
-
-
-${so}Since you did not allow to commit anything, you'll have${se}
-${so}to remove the edited modules' database yourself.${se}
-${so}To do this, perform a${se}
-${us}cd ${moduledir}; cvs release -dQ modules${ue}
-${so}command.${se}
-END
-;
-}
diff --git a/gnu/usr.bin/cvs/contrib/intro.doc b/gnu/usr.bin/cvs/contrib/intro.doc
deleted file mode 100644
index a6d4ec123387..000000000000
--- a/gnu/usr.bin/cvs/contrib/intro.doc
+++ /dev/null
@@ -1,112 +0,0 @@
-Date: Tue, 16 Jun 1992 17:05:23 +0200
-From: Steven.Pemberton@cwi.nl
-Message-Id: <9206161505.AA06927.steven@sijs.cwi.nl>
-To: berliner@Sun.COM
-Subject: cvs
-
-INTRODUCTION TO USING CVS
-
- CVS is a system that lets groups of people work simultaneously on
- groups of files (for instance program sources).
-
- It works by holding a central 'repository' of the most recent version
- of the files. You may at any time create a personal copy of these
- files; if at a later date newer versions of the files are put in the
- repository, you can 'update' your copy.
-
- You may edit your copy of the files freely. If new versions of the
- files have been put in the repository in the meantime, doing an update
- merges the changes in the central copy into your copy.
- (It can be that when you do an update, the changes in the
- central copy clash with changes you have made in your own
- copy. In this case cvs warns you, and you have to resolve the
- clash in your copy.)
-
- When you are satisfied with the changes you have made in your copy of
- the files, you can 'commit' them into the central repository.
- (When you do a commit, if you haven't updated to the most
- recent version of the files, cvs tells you this; then you have
- to first update, resolve any possible clashes, and then redo
- the commit.)
-
-USING CVS
-
- Suppose that a number of repositories have been stored in
- /usr/src/cvs. Whenever you use cvs, the environment variable
- CVSROOT must be set to this (for some reason):
-
- CVSROOT=/usr/src/cvs
- export CVSROOT
-
-TO CREATE A PERSONAL COPY OF A REPOSITORY
-
- Suppose you want a copy of the files in repository 'views' to be
- created in your directory src. Go to the place where you want your
- copy of the directory, and do a 'checkout' of the directory you
- want:
-
- cd $HOME/src
- cvs checkout views
-
- This creates a directory called (in this case) 'views' in the src
- directory, containing a copy of the files, which you may now work
- on to your heart's content.
-
-TO UPDATE YOUR COPY
-
- Use the command 'cvs update'.
-
- This will update your copy with any changes from the central
- repository, telling you which files have been updated (their names
- are displayed with a U before them), and which have been modified
- by you and not yet committed (preceded by an M). You will be
- warned of any files that contain clashes, the clashes will be
- marked in the file surrounded by lines of the form <<<< and >>>>.
-
-TO COMMIT YOUR CHANGES
-
- Use the command 'cvs commit'.
-
- You will be put in an editor to make a message that describes the
- changes that you have made (for future reference). Your changes
- will then be added to the central copy.
-
-ADDING AND REMOVING FILES
-
- It can be that the changes you want to make involve a completely
- new file, or removing an existing one. The commands to use here
- are:
-
- cvs add <filename>
- cvs remove <filename>
-
- You still have to do a commit after these commands. You may make
- any number of new files in your copy of the repository, but they
- will not be committed to the central copy unless you do a 'cvs add'.
-
-OTHER USEFUL COMMANDS AND HINTS
-
- To see the commit messages for files, and who made them, use:
-
- cvs log [filenames]
-
- To see the differences between your version and the central version:
-
- cvs diff [filenames]
-
- To give a file a new name, rename it and do an add and a remove.
-
- To lose your changes and go back to the version from the
- repository, delete the file and do an update.
-
- After an update where there have been clashes, your original
- version of the file is saved as .#file.version.
-
- All the cvs commands mentioned accept a flag '-n', that doesn't do
- the action, but lets you see what would happen. For instance, you
- can use 'cvs -n update' to see which files would be updated.
-
-MORE INFORMATION
-
- This is necessarily a very brief introduction. See the manual page
- (man cvs) for full details.
diff --git a/gnu/usr.bin/cvs/contrib/log.pl b/gnu/usr.bin/cvs/contrib/log.pl
deleted file mode 100644
index 5e3bf4883776..000000000000
--- a/gnu/usr.bin/cvs/contrib/log.pl
+++ /dev/null
@@ -1,169 +0,0 @@
-#! xPERL_PATHx
-# -*-Perl-*-
-#
-#ident "$CVSid$"
-#
-# XXX: FIXME: handle multiple '-f logfile' arguments
-#
-# XXX -- I HATE Perl! This *will* be re-written in shell/awk/sed soon!
-#
-
-# Usage: log.pl [[-m user] ...] [-s] -f logfile 'dirname file ...'
-#
-# -m user - for each user to receive cvs log reports
-# (multiple -m's permitted)
-# -s - to prevent "cvs status -v" messages
-# -f logfile - for the logfile to append to (mandatory,
-# but only one logfile can be specified).
-
-# here is what the output looks like:
-#
-# From: woods@kuma.domain.top
-# Subject: CVS update: testmodule
-#
-# Date: Wednesday November 23, 1994 @ 14:15
-# Author: woods
-#
-# Update of /local/src-CVS/testmodule
-# In directory kuma:/home/kuma/woods/work.d/testmodule
-#
-# Modified Files:
-# test3
-# Added Files:
-# test6
-# Removed Files:
-# test4
-# Log Message:
-# - wow, what a test
-#
-# (and for each file the "cvs status -v" output is appended unless -s is used)
-#
-# ==================================================================
-# File: test3 Status: Up-to-date
-#
-# Working revision: 1.41 Wed Nov 23 14:15:59 1994
-# Repository revision: 1.41 /local/src-CVS/cvs/testmodule/test3,v
-# Sticky Options: -ko
-#
-# Existing Tags:
-# local-v2 (revision: 1.7)
-# local-v1 (revision: 1.1.1.2)
-# CVS-1_4A2 (revision: 1.1.1.2)
-# local-v0 (revision: 1.2)
-# CVS-1_4A1 (revision: 1.1.1.1)
-# CVS (branch: 1.1.1)
-
-$cvsroot = $ENV{'CVSROOT'};
-
-# turn off setgid
-#
-$) = $(;
-
-$dostatus = 1;
-
-# parse command line arguments
-#
-while (@ARGV) {
- $arg = shift @ARGV;
-
- if ($arg eq '-m') {
- $users = "$users " . shift @ARGV;
- } elsif ($arg eq '-f') {
- ($logfile) && die "Too many '-f' args";
- $logfile = shift @ARGV;
- } elsif ($arg eq '-s') {
- $dostatus = 0;
- } else {
- ($donefiles) && die "Too many arguments!\n";
- $donefiles = 1;
- @files = split(/ /, $arg);
- }
-}
-
-# the first argument is the module location relative to $CVSROOT
-#
-$modulepath = shift @files;
-
-$mailcmd = "| Mail -s 'CVS update: $modulepath'";
-
-# Initialise some date and time arrays
-#
-@mos = (January,February,March,April,May,June,July,August,September,
- October,November,December);
-@days = (Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday);
-
-($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime;
-
-# get a login name for the guy doing the commit....
-#
-$login = getlogin || (getpwuid($<))[0] || "nobody";
-
-# open log file for appending
-#
-open(OUT, ">>" . $logfile) || die "Could not open(" . $logfile . "): $!\n";
-
-# send mail, if there's anyone to send to!
-#
-if ($users) {
- $mailcmd = "$mailcmd $users";
- open(MAIL, $mailcmd) || die "Could not Exec($mailcmd): $!\n";
-}
-
-# print out the log Header
-#
-print OUT "\n";
-print OUT "****************************************\n";
-print OUT "Date:\t$days[$wday] $mos[$mon] $mday, 19$year @ $hour:" . sprintf("%02d", $min) . "\n";
-print OUT "Author:\t$login\n\n";
-
-if (MAIL) {
- print MAIL "\n";
- print MAIL "Date:\t$days[$wday] $mos[$mon] $mday, 19$year @ $hour:" . sprintf("%02d", $min) . "\n";
- print MAIL "Author:\t$login\n\n";
-}
-
-# print the stuff from logmsg that comes in on stdin to the logfile
-#
-open(IN, "-");
-while (<IN>) {
- print OUT $_;
- if (MAIL) {
- print MAIL $_;
- }
-}
-close(IN);
-
-print OUT "\n";
-
-# after log information, do an 'cvs -Qq status -v' on each file in the arguments.
-#
-if ($dostatus != 0) {
- while (@files) {
- $file = shift @files;
- if ($file eq "-") {
- print OUT "[input file was '-']\n";
- if (MAIL) {
- print MAIL "[input file was '-']\n";
- }
- last;
- }
- open(RCS, "-|") || exec 'cvs', '-nQq', 'status', '-v', $file;
- while (<RCS>) {
- print OUT;
- if (MAIL) {
- print MAIL;
- }
- }
- close(RCS);
- }
-}
-
-close(OUT);
-die "Write to $logfile failed" if $?;
-
-close(MAIL);
-die "Pipe to $mailcmd failed" if $?;
-
-## must exit cleanly
-##
-exit 0;
diff --git a/gnu/usr.bin/cvs/contrib/log_accum.pl b/gnu/usr.bin/cvs/contrib/log_accum.pl
deleted file mode 100644
index b47f433b5622..000000000000
--- a/gnu/usr.bin/cvs/contrib/log_accum.pl
+++ /dev/null
@@ -1,496 +0,0 @@
-#! xPERL_PATHx
-# -*-Perl-*-
-#
-# Perl filter to handle the log messages from the checkin of files in
-# a directory. This script will group the lists of files by log
-# message, and mail a single consolidated log message at the end of
-# the commit.
-#
-# This file assumes a pre-commit checking program that leaves the
-# names of the first and last commit directories in a temporary file.
-#
-# Contributed by David Hampton <hampton@cisco.com>
-#
-# hacked greatly by Greg A. Woods <woods@planix.com>
-
-# Usage: log_accum.pl [-d] [-s] [-M module] [[-m mailto] ...] [-f logfile]
-# -d - turn on debugging
-# -m mailto - send mail to "mailto" (multiple)
-# -M modulename - set module name to "modulename"
-# -f logfile - write commit messages to logfile too
-# -s - *don't* run "cvs status -v" for each file
-
-#
-# Configurable options
-#
-
-$MAILER = "Mail"; # set this to something that takes "-s"
-
-#
-# End user configurable options.
-#
-
-# Constants (don't change these!)
-#
-$STATE_NONE = 0;
-$STATE_CHANGED = 1;
-$STATE_ADDED = 2;
-$STATE_REMOVED = 3;
-$STATE_LOG = 4;
-
-$LAST_FILE = "/tmp/#cvs.lastdir";
-
-$CHANGED_FILE = "/tmp/#cvs.files.changed";
-$ADDED_FILE = "/tmp/#cvs.files.added";
-$REMOVED_FILE = "/tmp/#cvs.files.removed";
-$LOG_FILE = "/tmp/#cvs.files.log";
-
-$FILE_PREFIX = "#cvs.files";
-
-#
-# Subroutines
-#
-
-sub cleanup_tmpfiles {
- local($wd, @files);
-
- $wd = `pwd`;
- chdir("/tmp") || die("Can't chdir('/tmp')\n");
- opendir(DIR, ".");
- push(@files, grep(/^$FILE_PREFIX\..*\.$id$/, readdir(DIR)));
- closedir(DIR);
- foreach (@files) {
- unlink $_;
- }
- unlink $LAST_FILE . "." . $id;
-
- chdir($wd);
-}
-
-sub write_logfile {
- local($filename, @lines) = @_;
-
- open(FILE, ">$filename") || die("Cannot open log file $filename.\n");
- print FILE join("\n", @lines), "\n";
- close(FILE);
-}
-
-sub append_to_logfile {
- local($filename, @lines) = @_;
-
- open(FILE, ">$filename") || die("Cannot open log file $filename.\n");
- print FILE join("\n", @lines), "\n";
- close(FILE);
-}
-
-sub format_names {
- local($dir, @files) = @_;
- local(@lines);
-
- $format = "\t%-" . sprintf("%d", length($dir)) . "s%s ";
-
- $lines[0] = sprintf($format, $dir, ":");
-
- if ($debug) {
- print STDERR "format_names(): dir = ", $dir, "; files = ", join(":", @files), ".\n";
- }
- foreach $file (@files) {
- if (length($lines[$#lines]) + length($file) > 65) {
- $lines[++$#lines] = sprintf($format, " ", " ");
- }
- $lines[$#lines] .= $file . " ";
- }
-
- @lines;
-}
-
-sub format_lists {
- local(@lines) = @_;
- local(@text, @files, $lastdir);
-
- if ($debug) {
- print STDERR "format_lists(): ", join(":", @lines), "\n";
- }
- @text = ();
- @files = ();
- $lastdir = shift @lines; # first thing is always a directory
- if ($lastdir !~ /.*\/$/) {
- die("Damn, $lastdir doesn't look like a directory!\n");
- }
- foreach $line (@lines) {
- if ($line =~ /.*\/$/) {
- push(@text, &format_names($lastdir, @files));
- $lastdir = $line;
- @files = ();
- } else {
- push(@files, $line);
- }
- }
- push(@text, &format_names($lastdir, @files));
-
- @text;
-}
-
-sub append_names_to_file {
- local($filename, $dir, @files) = @_;
-
- if (@files) {
- open(FILE, ">>$filename") || die("Cannot open file $filename.\n");
- print FILE $dir, "\n";
- print FILE join("\n", @files), "\n";
- close(FILE);
- }
-}
-
-sub read_line {
- local($line);
- local($filename) = @_;
-
- open(FILE, "<$filename") || die("Cannot open file $filename.\n");
- $line = <FILE>;
- close(FILE);
- chop($line);
- $line;
-}
-
-sub read_logfile {
- local(@text);
- local($filename, $leader) = @_;
-
- open(FILE, "<$filename");
- while (<FILE>) {
- chop;
- push(@text, $leader.$_);
- }
- close(FILE);
- @text;
-}
-
-sub build_header {
- local($header);
- local($sec,$min,$hour,$mday,$mon,$year) = localtime(time);
- $header = sprintf("CVSROOT:\t%s\nModule name:\t%s\nChanges by:\t%s@%s\t%02d/%02d/%02d %02d:%02d:%02d",
- $cvsroot,
- $modulename,
- $login, $hostdomain,
- $year%100, $mon+1, $mday,
- $hour, $min, $sec);
-}
-
-sub mail_notification {
- local($name, @text) = @_;
- open(MAIL, "| $MAILER -s \"CVS Update: " . $modulename . "\" " . $name);
- print MAIL join("\n", @text), "\n";
- close(MAIL);
-}
-
-sub write_commitlog {
- local($logfile, @text) = @_;
-
- open(FILE, ">>$logfile");
- print FILE join("\n", @text), "\n";
- close(FILE);
-}
-
-#
-# Main Body
-#
-
-# Initialize basic variables
-#
-$debug = 0;
-$id = getpgrp(); # note, you *must* use a shell which does setpgrp()
-$state = $STATE_NONE;
-$login = getlogin || (getpwuid($<))[0] || "nobody";
-chop($hostname = `hostname`);
-chop($domainname = `domainname`);
-$hostdomain = $hostname . $domainname;
-$cvsroot = $ENV{'CVSROOT'};
-$do_status = 1;
-$modulename = "";
-
-# parse command line arguments (file list is seen as one arg)
-#
-while (@ARGV) {
- $arg = shift @ARGV;
-
- if ($arg eq '-d') {
- $debug = 1;
- print STDERR "Debug turned on...\n";
- } elsif ($arg eq '-m') {
- $mailto = "$mailto " . shift @ARGV;
- } elsif ($arg eq '-M') {
- $modulename = shift @ARGV;
- } elsif ($arg eq '-s') {
- $do_status = 0;
- } elsif ($arg eq '-f') {
- ($commitlog) && die("Too many '-f' args\n");
- $commitlog = shift @ARGV;
- } else {
- ($donefiles) && die("Too many arguments! Check usage.\n");
- $donefiles = 1;
- @files = split(/ /, $arg);
- }
-}
-($mailto) || die("No -m mail recipient specified\n");
-
-# for now, the first "file" is the repository directory being committed,
-# relative to the $CVSROOT location
-#
-@path = split('/', $files[0]);
-
-# XXX there are some ugly assumptions in here about module names and
-# XXX directories relative to the $CVSROOT location -- really should
-# XXX read $CVSROOT/CVSROOT/modules, but that's not so easy to do, since
-# XXX we have to parse it backwards.
-#
-if ($modulename eq "") {
- $modulename = $path[0]; # I.e. the module name == top-level dir
-}
-if ($#path == 0) {
- $dir = ".";
-} else {
- $dir = join('/', @path);
-}
-$dir = $dir . "/";
-
-if ($debug) {
- print STDERR "module - ", $modulename, "\n";
- print STDERR "dir - ", $dir, "\n";
- print STDERR "path - ", join(":", @path), "\n";
- print STDERR "files - ", join(":", @files), "\n";
- print STDERR "id - ", $id, "\n";
-}
-
-# Check for a new directory first. This appears with files set as follows:
-#
-# files[0] - "path/name/newdir"
-# files[1] - "-"
-# files[2] - "New"
-# files[3] - "directory"
-#
-if ($files[2] =~ /New/ && $files[3] =~ /directory/) {
- local(@text);
-
- @text = ();
- push(@text, &build_header());
- push(@text, "");
- push(@text, $files[0]);
- push(@text, "");
-
- while (<STDIN>) {
- chop; # Drop the newline
- push(@text, $_);
- }
-
- &mail_notification($mailto, @text);
-
- exit 0;
-}
-
-# Check for an import command. This appears with files set as follows:
-#
-# files[0] - "path/name"
-# files[1] - "-"
-# files[2] - "Imported"
-# files[3] - "sources"
-#
-if ($files[2] =~ /Imported/ && $files[3] =~ /sources/) {
- local(@text);
-
- @text = ();
- push(@text, &build_header());
- push(@text, "");
- push(@text, $files[0]);
- push(@text, "");
-
- while (<STDIN>) {
- chop; # Drop the newline
- push(@text, $_);
- }
-
- &mail_notification($mailto, @text);
-
- exit 0;
-}
-
-# Iterate over the body of the message collecting information.
-#
-while (<STDIN>) {
- chop; # Drop the newline
-
- if (/^In directory/) {
- push(@log_lines, $_);
- push(@log_lines, "");
- next;
- }
-
- if (/^Modified Files/) { $state = $STATE_CHANGED; next; }
- if (/^Added Files/) { $state = $STATE_ADDED; next; }
- if (/^Removed Files/) { $state = $STATE_REMOVED; next; }
- if (/^Log Message/) { $state = $STATE_LOG; next; }
-
- s/^[ \t\n]+//; # delete leading whitespace
- s/[ \t\n]+$//; # delete trailing whitespace
-
- if ($state == $STATE_CHANGED) { push(@changed_files, split); }
- if ($state == $STATE_ADDED) { push(@added_files, split); }
- if ($state == $STATE_REMOVED) { push(@removed_files, split); }
- if ($state == $STATE_LOG) { push(@log_lines, $_); }
-}
-
-# Strip leading and trailing blank lines from the log message. Also
-# compress multiple blank lines in the body of the message down to a
-# single blank line.
-#
-while ($#log_lines > -1) {
- last if ($log_lines[0] ne "");
- shift(@log_lines);
-}
-while ($#log_lines > -1) {
- last if ($log_lines[$#log_lines] ne "");
- pop(@log_lines);
-}
-for ($i = $#log_lines; $i > 0; $i--) {
- if (($log_lines[$i - 1] eq "") && ($log_lines[$i] eq "")) {
- splice(@log_lines, $i, 1);
- }
-}
-
-if ($debug) {
- print STDERR "Searching for log file index...";
-}
-# Find an index to a log file that matches this log message
-#
-for ($i = 0; ; $i++) {
- local(@text);
-
- last if (! -e "$LOG_FILE.$i.$id"); # the next available one
- @text = &read_logfile("$LOG_FILE.$i.$id", "");
- last if ($#text == -1); # nothing in this file, use it
- last if (join(" ", @log_lines) eq join(" ", @text)); # it's the same log message as another
-}
-if ($debug) {
- print STDERR " found log file at $i.$id, now writing tmp files.\n";
-}
-
-# Spit out the information gathered in this pass.
-#
-&append_names_to_file("$CHANGED_FILE.$i.$id", $dir, @changed_files);
-&append_names_to_file("$ADDED_FILE.$i.$id", $dir, @added_files);
-&append_names_to_file("$REMOVED_FILE.$i.$id", $dir, @removed_files);
-&write_logfile("$LOG_FILE.$i.$id", @log_lines);
-
-# Check whether this is the last directory. If not, quit.
-#
-if ($debug) {
- print STDERR "Checking current dir against last dir.\n";
-}
-$_ = &read_line("$LAST_FILE.$id");
-
-if ($_ ne $cvsroot . "/" . $files[0]) {
- if ($debug) {
- print STDERR sprintf("Current directory %s is not last directory %s.\n", $cvsroot . "/" .$files[0], $_);
- }
- exit 0;
-}
-if ($debug) {
- print STDERR sprintf("Current directory %s is last directory %s -- all commits done.\n", $files[0], $_);
-}
-
-#
-# End Of Commits!
-#
-
-# This is it. The commits are all finished. Lump everything together
-# into a single message, fire a copy off to the mailing list, and drop
-# it on the end of the Changes file.
-#
-
-#
-# Produce the final compilation of the log messages
-#
-@text = ();
-@status_txt = ();
-push(@text, &build_header());
-push(@text, "");
-
-for ($i = 0; ; $i++) {
- last if (! -e "$LOG_FILE.$i.$id"); # we're done them all!
- @lines = &read_logfile("$CHANGED_FILE.$i.$id", "");
- if ($#lines >= 0) {
- push(@text, "Modified files:");
- push(@text, &format_lists(@lines));
- }
- @lines = &read_logfile("$ADDED_FILE.$i.$id", "");
- if ($#lines >= 0) {
- push(@text, "Added files:");
- push(@text, &format_lists(@lines));
- }
- @lines = &read_logfile("$REMOVED_FILE.$i.$id", "");
- if ($#lines >= 0) {
- push(@text, "Removed files:");
- push(@text, &format_lists(@lines));
- }
- if ($#text >= 0) {
- push(@text, "");
- }
- @lines = &read_logfile("$LOG_FILE.$i.$id", "\t");
- if ($#lines >= 0) {
- push(@text, "Log message:");
- push(@text, @lines);
- push(@text, "");
- }
- if ($do_status) {
- local(@changed_files);
-
- @changed_files = ();
- push(@changed_files, &read_logfile("$CHANGED_FILE.$i.$id", ""));
- push(@changed_files, &read_logfile("$ADDED_FILE.$i.$id", ""));
- push(@changed_files, &read_logfile("$REMOVED_FILE.$i.$id", ""));
-
- if ($debug) {
- print STDERR "main: pre-sort changed_files = ", join(":", @changed_files), ".\n";
- }
- sort(@changed_files);
- if ($debug) {
- print STDERR "main: post-sort changed_files = ", join(":", @changed_files), ".\n";
- }
-
- foreach $dofile (@changed_files) {
- if ($dofile =~ /\/$/) {
- next; # ignore the silly "dir" entries
- }
- if ($debug) {
- print STDERR "main(): doing 'cvs -nQq status -v $dofile'\n";
- }
- open(STATUS, "-|") || exec 'cvs', '-nQq', 'status', '-v', $dofile;
- while (<STATUS>) {
- chop;
- push(@status_txt, $_);
- }
- }
- }
-}
-
-# Write to the commitlog file
-#
-if ($commitlog) {
- &write_commitlog($commitlog, @text);
-}
-
-if ($#status_txt >= 0) {
- push(@text, @status_txt);
-}
-
-# Mailout the notification.
-#
-&mail_notification($mailto, @text);
-
-# cleanup
-#
-if (! $debug) {
- &cleanup_tmpfiles();
-}
-
-exit 0;
diff --git a/gnu/usr.bin/cvs/contrib/mfpipe.pl b/gnu/usr.bin/cvs/contrib/mfpipe.pl
deleted file mode 100644
index bae7a7243079..000000000000
--- a/gnu/usr.bin/cvs/contrib/mfpipe.pl
+++ /dev/null
@@ -1,88 +0,0 @@
-#! xPERL_PATHx
-# -*-Perl-*-
-#
-# From: clyne@niwot.scd.ucar.EDU (John Clyne)
-# Date: Fri, 28 Feb 92 09:54:21 MST
-#
-# BTW, i wrote a perl script that is similar to 'nfpipe' except that in
-# addition to logging to a file it provides a command line option for mailing
-# change notices to a group of users. Obviously you probably wouldn't want
-# to mail every change. But there may be certain directories that are commonly
-# accessed by a group of users who would benefit from an email notice.
-# Especially if they regularly beat on the same directory. Anyway if you
-# think anyone would be interested here it is.
-#
-# $Id: mfpipe.pl,v 1.2 1995/07/10 02:01:57 kfogel Exp $
-#
-#
-# File: mfpipe
-#
-# Author: John Clyne
-# National Center for Atmospheric Research
-# PO 3000, Boulder, Colorado
-#
-# Date: Wed Feb 26 18:34:53 MST 1992
-#
-# Description: Tee standard input to mail a list of users and to
-# a file. Used by CVS logging.
-#
-# Usage: mfpipe [-f file] [user@host...]
-#
-# Environment: CVSROOT
-# Path to CVS root.
-#
-# Files:
-#
-#
-# Options: -f file
-# Capture output to 'file'
-#
-
-$header = "Log Message:\n";
-
-$mailcmd = "| mail -s 'CVS update notice'";
-$whoami = `whoami`;
-chop $whoami;
-$date = `date`;
-chop $date;
-
-$cvsroot = $ENV{'CVSROOT'};
-
-while (@ARGV) {
- $arg = shift @ARGV;
-
- if ($arg eq '-f') {
- $file = shift @ARGV;
- }
- else {
- $users = "$users $arg";
- }
-}
-
-if ($users) {
- $mailcmd = "$mailcmd $users";
- open(MAIL, $mailcmd) || die "Execing $mail: $!\n";
-}
-
-if ($file) {
- $logfile = "$cvsroot/LOG/$file";
- open(FILE, ">> $logfile") || die "Opening $logfile: $!\n";
-}
-
-print FILE "$whoami $date--------BEGIN LOG ENTRY-------------\n" if ($logfile);
-
-while (<>) {
- print FILE $log if ($log && $logfile);
-
- print FILE $_ if ($logfile);
- print MAIL $_ if ($users);
-
- $log = "log: " if ($_ eq $header);
-}
-
-close FILE;
-die "Write failed" if $?;
-close MAIL;
-die "Mail failed" if $?;
-
-exit 0;
diff --git a/gnu/usr.bin/cvs/contrib/pcl-cvs/ChangeLog b/gnu/usr.bin/cvs/contrib/pcl-cvs/ChangeLog
deleted file mode 100644
index ac24f446af2a..000000000000
--- a/gnu/usr.bin/cvs/contrib/pcl-cvs/ChangeLog
+++ /dev/null
@@ -1,774 +0,0 @@
-Wed Nov 22 11:01:50 1995 Joshua Cowan <jcowan@hermit.reslife.okstate.edu>
-
- * pcl-cvs.el (cvs-changelog-ours-p): use `user-full-name' if
- `add-log-full-name' unbound, as not every uses the stuff in
- add-log.el. Same with `add-log-mailing-address'.
- (cvs-changelog-entries): change to `change-log-mode' unless
- already in it.
-
-Sun Jul 9 20:57:11 1995 Karl Fogel <kfogel@floss.cyclic.com>
-
- * "/bin/rmdir" as default, not "/usr/local/bin/rmdir".
-
-Fri Jun 16 15:24:34 1995 Jim Kingdon (kingdon@cyclic.com)
-
- * pcl-cvs.elc, pcl-cvs-lucid.elc: Added.
-
- * Makefile.in: Rename from Makefile and set srcdir.
-
-Thu May 18 17:10:27 1995 Jim Blandy <jimb@totoro.bio.indiana.edu>
-
- Automatically guess CVS log entries from ChangeLog contents.
- * pcl-cvs.el (cvs-mode-changelog-commit): New command.
- (cvs-changelog-full-paragraphs): New variable.
- (cvs-changelog-name, cvs-narrow-changelog,
- cvs-changelog-paragraph, cvs-changelog-subparagraph,
- cvs-changelog-entry, cvs-changelog-ours-p, cvs-relative-path,
- cvs-changelog-entries, cvs-changelog-insert-entries, cvs-union,
- cvs-insert-changelog-entries, cvs-edit-delete-common-indentation):
- New functions.
- (cvs-mode-map): Bind 'C' to cvs-mode-changelog-commit.
- (cvs-mode): Mention cvs-mode-changelog-commit in docstring.
-
- Give the info files names ending in ".info".
- * Makefile (INFOFILES, install_info): Change pcl-cvs to
- pcl-cvs.info.
- (pcl-cvs.info): Target renamed from pcl-cvs.
- (DISTFILES): pcl-cvs removed; we handle the info files explicitly
- in the dist-dir target.
- (dist-dir): Depend on pcl-cvs.info. Distribute pcl-cvs.info*.
- * pcl-cvs.texinfo: Change @setfilename appropriately.
- * INSTALL: Updated.
- * .cvsignore: Correctly ignore the info files.
-
- * README: Note that pcl-cvs has been tested under 19.28, and that
- the "cookie" naming conflict was resolved in 19.11.
-
- * Makefile (pcl-cvs-lucid.elc): Changed this target from
- pcl-cvs-lucid.el. That's a source file, for goodness' sake!
-
-Tue May 9 13:56:50 1995 Jim Blandy <jimb@totoro.bio.indiana.edu>
-
- * Change references to "Cygnus's remote CVS" to "Cyclic CVS".
-
-Wed May 3 13:55:27 1995 Jim Blandy <jimb@totoro.bio.indiana.edu>
-
- * pcl-cvs.el (cvs-parse-stderr): Handle colons after both
- "rcsmerge" and "warning".
-
-Fri Apr 28 22:38:14 1995 Jim Blandy <jimb@totoro.bio.indiana.edu>
-
- * Makefile (ELFILES): Include pcl-cvs-startup.el.
- (info, pcl-cvs): Call makeinfo appropriately for modern versions.
- (pcl-cvs.aux): List dependency on pcl-cvs.texinfo.
- (pcl-cvs.ps): New target.
- (DVIPS): New variable.
- (dist-dir): Renamed from dist, updated to accept DISTDIR value
- passed from parent.
- (DISTFILES): New varible.
- (pcl-cvs.elc, pcl-cvs-lucid.elc): Add targets to elcfiles target.
-
-Tue Apr 25 21:33:49 1995 Jim Blandy <jimb@totoro.bio.indiana.edu>
-
- * pcl-cvs.el: (cvs-parse-stderr): Recognize "conflicts" as well as
- "overlaps" before "during merge."
-
-Thu Feb 16 12:17:20 1995 Jim Blandy <jimb@totoro.bio.indiana.edu>
-
- * pcl-cvs.el (cvs-parse-stderr): Recognize "conflicts found in..."
- messages attributed to "cvs server", as well as "cvs update".
-
-Sat Feb 4 01:47:01 1995 Jim Blandy <jimb@totoro.bio.indiana.edu>
-
- * pcl-cvs.el: Deal with the 'P' action, produced by remote CVS.
- (cvs-parse-stdout): Treat 'P' like 'U' --- file is updated.
-
-Tue Jan 31 23:31:39 1995 Jim Blandy <jimb@totoro.bio.indiana.edu>
-
- * pcl-cvs.el (cvs-cvsroot-required): New variable.
- (cvs-do-update): If cvs-cvsroot-required is not set, don't complain if
- CVSROOT and cvs-cvsroot are both unset.
-
-Sun Jan 22 21:22:22 1995 Jim Blandy <jimb@totoro.bio.indiana.edu>
-
- * pcl-cvs.el (cvs-parse-stderr):
- Some changes for Cygnus's Remote CVS. Treat
- messages like "cvs server: Updating DIRECTORY" as we treat those like
- "cvs update: Updating DIRECTORY". Ignore other messages starting with
- "cvs server".
-
- * pcl-cvs.el (cvs-parse-stderr): Re-indent.
-
- * .cvsignore: Add ignore list for Texinfo litter.
-
- * Makefile (lispdir): Set appropriately for totoro.
- * pcl-cvs.el (cvs-program, cvs-diff-program, cvs-rmdir-program): Same.
-
-Tue Jun 1 00:00:03 1993 Per Cederqvist (ceder@lysator.liu.se)
-
- * Release 1.05. (This release was promised before the end of May,
- but I didn't quite make it. No, I didn't fake the date above).
-
-Mon May 31 01:32:25 1993 Per Cederqvist (ceder@lysator.liu.se)
-
- * Removed the elib sub-directory. Users must now get the Elib
- library separately.
- * pcl-cvs.texinfo: Document it.
-
- * pcl-cvs-lucid.el: A new version, supplied by Jamie Zawinsky,
- added.
-
- * pcl-cvs Id 68: Transform RCS keywords
- * Makefile (pcl-cvs-$(VER)): Remove the $ signs in most files in
- the distribution.
-
- * pcl-cvs Id 76: Extra " in cvs-mode-add.
- * pcl-cvs.el (cvs-mode-add): Don't add the extra level of quotes
- around the log message, since it doesn't work with CVS.
-
- * pcl-cvs Id 56: '-d <CVSROOT>' support in pcl-cvs
- * pcl-cvs.el (cvs-change-cvsroot): New function.
-
- * pcl-cvs Id 77: *cvs* isn't cleared properly
- * pcl-cvs.el (cvs-do-update): Always erase the *cvs* buffer and
- re-create the collection.
-
- * pcl-cvs.el (cvs-do-update): Set mode-line-process in the *cvs*
- buffer.
- * pcl-cvs.el (cvs-mode): Reset mode-line-process.
-
- * pcl-cvs Id 59: sort .cvsignore alphabetically!
- * pcl-cvs.el (cvs-sort-ignore-file): New variable.
- * pcl-cvs.el (cvs-mode-ignore): Use it.
- * pcl-cvs.texinfo: Document it.
-
- * pcl-cvs Id 75: Require final newline.
- * pcl-cvs.el (cvs-commit-buffer-require-final-newline): New
- variable.
- * pcl-cvs.el (cvs-edit-done): Use it.
- * pcl-cvs.texinfo: Document it.
-
- * pcl-cvs Id 72: make clean deletes lucid-emacs.el
- * dist-makefile (ELCFILES): Fixed a typo.
-
- * pcl-cvs Id 46: "cvs remove f" "touch f" "cvs update f" -> parse err.
- * pcl-cvs.el (cvs-fileinfo->type): New type: REM-EXIST.
- * pcl-cvs.el (cvs-shadow-entry-p): A REMOVED that follows a
- REM-EXIST is a shadow.
- * pcl-cvs.el (cvs-parse-stderr): Recognize the "should be removed
- and is still there" message.
- * pcl-cvs.el (cvs-pp): Recognize REM-EXIST.
- * pcl-cvs.el (cvs-mode-undo-local-changes): Recognize and complain
- about REM-EXIST. Defensive test added: complain about unknown types.
-
- * pcl-cvs.el (cvs-mode-add): Add an extra level of quotes around
- the log message. This is apparently needed by RCVS. <This change
- has been removed. --ceder>.
-
- * pcl-cvs.el (cvs-parse-stderr): Ignore output from RCVS.
-
-Tue Apr 27 00:48:40 1993 Per Cederqvist (ceder@lysator.liu.se)
-
- * pcl-cvs.el (cvs-startup-message): Now a defconst instead of a
- defvar.
- * pcl-cvs.el (cvs-mode-commit): Add a defvar for it.
-
- * dist-makefile (EMACS): Use $(EMACS) instead of hard-coding 'emacs'.
-
-Sat Apr 17 12:47:10 1993 Per Cederqvist (ceder@lysator.liu.se)
-
- * Release 1.04.
-
- * pcl-cvs.texinfo: Updated the Contributors node.
-
- * pcl-cvs Id 58: Lucid GNU Emacs support
- * pcl-cvs-lucid.el: New file, contributed by the people at Lucid.
- * pcl-cvs.el: Autoload pcl-cvs-lucid if running in an Lucid GNU
- Emacs.
- * compile-all.el: (files-to-compile): Add pcl-cvs-lucid.
- * dist-makefile (ELFILES, ELCFILES): Dito.
-
- * pcl-cvs Id 55: cvs-diff-backup swaps old and new version.
- * pcl-cvs.el (cvs-diff-backup-extractor): Old version should be
- first.
- * pcl-cvs.el (cvs-mode-diff-backup): Call cvs-backup-diffable
- correctly.
-
- * pcl-cvs Id 64: elib substitute
- * dist-makefile (install): Warn about Elib.
- * pcl-cvs.texinfo: Talk about Elib.
-
- * pcl-cvs Id 50: Committing the *commit* buffer twice.
- * pcl-cvs.el (cvs-edit-done): Report an error if cvs-commit-list
- is empty, and empty it when the commit is done.
-
- * pcl-cvs Id 56: '-d <CVSROOT>' support.
- * pcl-cvs.el (cvs-cvsroot): New variable.
- * pcl-cvs.el (cvs-do-update, all callers of cvs-execute-list): Use
- it everywhere CVS is called, to override CVSROOT.
- * pcl-cvs.texinfo (Customization): Document it.
-
-Thu Apr 1 00:34:55 1993 Per Cederqvist (ceder@lysator.liu.se)
-
- * pcl-cvs.el (cvs-retrieve-revision-to-tmpfile): Exit status nil
- from call-process means everything was successful in some Emacs
- versions.
-
- * pcl-cvs.el (cvs-mode-map): Bind "q" to bury-buffer.
- * pcl-cvs.texinfo: Document it.
-
-Thu Mar 11 00:05:03 1993 Per Cederqvist (ceder@lysator.liu.se)
-
- * Release 1.03-Emerge (not released).
-
- * Makefile (pcl-cvs-$(VER)): Don't includ elib-dll-debug.el in the
- distribution. (It's included as elib/dll-debug.el).
-
- * pcl-cvs.el (cvs-mode): Document the "e" key (cvs-mode-emerge).
-
-Tue Mar 9 00:02:57 1993 Per Cederqvist (ceder@lysator.liu.se)
-
- * pcl-cvs.texinfo (Emerge): New node.
-
- * pcl-cvs.el (cvs-kill-buffer-visiting): New function.
-
- * pcl-cvs.el (cvs-mode-emerge): Handle Conflict and Merged files.
-
- * pcl-cvs.el (cvs-retrieve-revision-to-tmpfile): Handle any revision.
-
- * pcl-cvs.el (cvs-fileinfo-*): Store base-revision instead of
- backup-file.
-
- * pcl-cvs.el (cvs-backup-diffable): The file is only diffable if
- the backup file is readable.
-
- * pcl-cvs.el (cvs-mode-map): Bind "e" to cvs-mode-emerge instead
- of cvs-mode-find-file (which is anyhow bound to "f").
-
-Mon Mar 8 23:06:52 1993 Per Cederqvist (ceder@lysator.liu.se)
-
- * pcl-cvs.el (cvs-mode-emerge): New function. Currently only
- handles emerge of Modified files.
-
- * pcl-cvs.el (cvs-retrieve-revision-to-tmpfile): New function.
-
-Sun Jan 24 20:07:18 1993 Per Cederqvist (ceder@lysator.liu.se)
-
- * elib-dll-debug.el: Moved to elib.
-
-Mon Jan 18 00:35:59 1993 Per Cederqvist (ceder@mauritz)
-
- * pcl-cvs.el (cvs-do-update): Added a probably unnecessary sit-for.
-
- * Release 1.03-Elib-0.05.1 (not released).
-
- * Elib 0.05 compatibility:
- * elib-dll-debug.el, pcl-cvs-buffer.el, test-dll.el: Fix the
- require strings.
- * pcl-cvs.el (cvs-pp): Insert the string.
-
- * Release 1.03-Elib-0.05 (not released).
-
- * elib: New directory, containing the parts of elib that are
- required for pcl-cvs. Changes to the files in that directory
- that are present in Elib are documented in the ChangeLog of
- Elib, not here.
- * Makefile (pcl-cvs-$(VER)): Copy the new dir to the distribution.
- * dist-makefile (ELFILES, ELCFILES): Don't include the Elib files.
-
-Fri Jan 8 02:43:49 1993 Per Cederqvist (ceder@konrad)
-
- * pcl-cvs.el (cvs-mode-map): Bind "e" to cvs-mode-find-file, like
- in dired.
-
-Sun Jan 3 23:25:13 1993 Per Cederqvist (ceder@konrad)
-
- * elib-dll.el, elib-node.el, cookie.el: Moved to the elib package.
- Pcl-cvs now requires elib.
-
-Tue Dec 29 22:06:57 1992 Per Cederqvist (ceder@konrad)
-
- * pcl-cvs.el: Tracked the latest (last?) rename of all functions
- in cookie.el.
-
-Thu Sep 24 00:29:16 1992 Per Cederqvist (ceder@robert)
-
- * pcl-cvs.texinfo (Archives): This version is not distributed with
- CVS 1.3, so don't claim that it is.
-
-Fri Aug 21 15:17:08 1992 Per Cederqvist (ceder@maskros)
-
- * pcl-cvs.el (cvs-parse-stderr): Fixed two "(set head" that should
- be "(setq head".
-
-Thu Aug 20 05:53:58 1992 Per Cederqvist (ceder@robin)
-
- * cookie.el: Changes to this file is documented in the ChangeLog
- of elib in the future.
-
-Tue Aug 18 03:30:28 1992 Per Cederqvist (ceder@robin)
-
- * pcl-cvs.el: Don't use cookie-last-tin (which no longer exists).
-
- * cookie.el: Use prefix cookie:: for internal functions.
-
- * cookie.el: (cookie:enter-after, cookie:enter-before,
- cookie:nth-cookie): Implemented.
- * cookie.el: No longer define (impl).
-
- * cookie.el: More renames:
- cookie:next-cookie -> cookie:goto-next-tin
- cookie:previous-cookie -> cookie:goto-previous-tin
- tin-next -> cookie:next-tin
- tin-previous -> cookie:previous-tin
- tin-nth -> cookie:nth-tin
- tin-delete -> cookie:delete-tin
- cookie:collect -> cookie:collect-cookies
- cookie:tin-collect -> cookie:collect-tins
- (new) -> cookie:tin-collect-cookies
- (new) -> cookie:tin-collect-tins
- cookie:refresh -> cookie:refresh-all
- tin-invalidate-tins -> cookie:invalidate-tins
-
-Mon Aug 17 01:39:49 1992 Per Cederqvist (ceder@robin)
-
- * cookie.el (cookie:set-buffer-bind-dll-let*): New macro. Used in
- many places instead of cookie:set-buffer-bind-dll.
- * cookie.el (cookie:set-buffer-bind-dll): Renamed the macro
- cookie:set-buffer to this.
-
- * pcl-cvs.el (cvs-use-temp-buffer): Set default-directory.
-
-Sun Aug 16 20:51:30 1992 Per Cederqvist (ceder@robin)
-
- * pcl-cvs.el (cvs-add-sub): Fixed call to cvs-add-file-update-buffer.
-
-Sat Aug 8 20:28:21 1992 Per Cederqvist (ceder@robin)
-
- * Release 1.03-Cookie-II (not released).
-
- * pcl-cvs.el (cvs-mode-diff-cvs): Don't care about the exit status
- from ``cvs diff''.
-
- * pcl-cvs.el (cvs-mode): Document cvs-mode-undo-local-changes.
- * pcl-cvs.el (cvs-diffable): New function.
-
- * pcl-cvs.el: Use the new cookie package.
- * pcl-cvs.el (cvs-cookie-handle): New variable.
- * pcl-cvs.el (cvs-do-update): User the new cookie:create
- interface, and cookie:clear if the buffer already existed. Make
- the buffer read-only.
- * pcl-cvs.el (cvs-mode-next-line, cvs-mode-previous-line): New
- functions (used instead of cookie:next-cookie and
- cookie:previous-cookie).
-
- * cookie.el: Major redesign. The handle that is passed to all
- cookie functions is now a new datatype, and not the buffer that
- the cookies resides in. This way it is possible to have more than
- one set of cookies in a buffer. Things that used to be
- buffer-local variables are now fields in the handle data type.
- cookie-last-tin is no longer available.
- * cookie.el (cookie:create): The buffer is not cleared, nor set to
- be read-only.
- * cookie.el (cookie:next-cookie, cookie:previous-cookie): Since
- the first argument is now a handle and not a buffer, these can no
- longer be called interactively. You have to write a small wrapper
- about them.
- * cookie.el (cookie:buffer): New function.
-
-Tue Aug 4 03:02:25 1992 Per Cederqvist (ceder@robert)
-
- * pcl-cvs.texinfo (Bugs): Renamed "Reporting bugs and ideas" to
- "Bugs" and added a table of known bugs/FAQ:s.
-
-Mon Aug 3 00:19:39 1992 Per Cederqvist (ceder@robert)
-
- * pcl-cvs.el, pcl-cvs.texinfo: Big Renaming Time!
- The commands that operate in the *cvs* buffer:
- cvs-add-change-log-entry-other-window -> cvs-mode-add-change-log-entry-other-window
- cvs-mark-all-files -> cvs-mode-mark-all-files
- cvs-revert-updated-buffers -> cvs-mode-revert-updated-buffers
- cvs-undo-local-changes -> cvs-mode-undo-local-changes
- cvs-unmark-up -> cvs-mode-unmark-up
- cvs-acknowledge -> cvs-mode-acknowledge
- cvs-unmark-all-files -> cvs-mode-unmark-all-files
- cvs-add -> cvs-mode-add
- cvs-diff-backup -> cvs-mode-diff-backup
- cvs-commit -> cvs-mode-commit
- cvs-diff-cvs -> cvs-mode-diff-cvs
- cvs-find-file -> cvs-mode-find-file
- cvs-update-no-prompt -> cvs-mode-update-no-prompt
- cvs-ignore -> cvs-mode-ignore
- cvs-log -> cvs-mode-log
- cvs-mark -> cvs-mode-mark
- cvs-find-file-other-window -> cvs-mode-find-file-other-window
- cvs-remove-file -> cvs-mode-remove-file
- cvs-status -> cvs-mode-status
- cvs-remove-handled -> cvs-mode-remove-handled
- cvs-unmark -> cvs-mode-unmark
-
- * pcl-cvs.el (cvs-cvs-diff-flags): Variable deleted.
- * pcl-cvs.el (cvs-diff-cvs): Use cvs-diff-flags instead.
- * pcl-cvs.texinfo (Customization): Update the doc.
-
- * pcl-cvs.el (cvs-diff-cvs): Handle exit status 0 (no diffs), 1
- (diffs) and other (error).
- * pcl-cvs.el (cvs-execute-list): Add support for this kind of
- thing.
-
- * Revert buffers for committed files:
- * pcl-cvs.el (cvs-auto-revert-after-commit): New variable.
- * pcl-cvs.texinfo (Committing changes, Customization): Document
- it.
- * pcl-cvs.el (cvs-after-commit-function): New function.
-
- * pcl-cvs.el (cvs-execute-list): Return the exit status or nil.
- * pcl-cvs.el (cvs-edit-done, cvs-diff-cvs, cvs-remove-file,
- cvs-undo-local-changes, cvs-add, cvs-status, cvs-log): Use the
- exit status to generate an error message.
-
-
- * pcl-cvs.el (cvs-do-update): It should be "cvs -n update -l", not
- "cvs -l update -n". Put the -n and/or -l in the message that is
- displayed in the *cvs* buffer during the update.
-
-Sat Aug 1 00:55:49 1992 Per Cederqvist (ceder@robert)
-
- * cookie.el (cookie-sort): New function.
-
- * cookie.el (cookie-clear): Rewritten. No longer clears all local
- variables.
-
-Tue Jul 28 17:21:17 1992 Per Cederqvist (ceder@robin)
-
- * pcl-cvs.el (cvs-parse-stderr): Try to handle the output from RCS
- when it is compiled without DIFF3_BIN and a conflict occurs.
-
- * pcl-cvs.texinfo (Getting Started): Fixed typo.
-
- * pcl-cvs-startup.el (cvs-update-other-window): Make the autoload
- be interactive.
-
-Mon Jul 27 19:36:40 1992 Per Cederqvist (ceder@robin)
-
- * pcl-cvs.el (cvs-revert-updated-buffers, cvs-revert-fileinfo):
- New functions.
- * pcl-cvs.texinfo (Reverting your buffers): Document it.
-
- * pcl-cvs.el (cvs-fileinfo->full-path): New function.
- * pcl-cvs.el (cvs-full-path): Use it.
-
- * cookie.el (cookie-map, cookie-map-reverse): Better doc-
- string. Removed the unused local variable 'result'.
-
- * compile-all.el: Renamed elib-files to files-to-compare.
- * compile-all.el (compile-pcl-cvs): Bind load-path in a let
- statement instead of globally.
-
-Thu Jul 23 19:02:41 1992 Per Cederqvist (ceder@robin)
-
- * pcl-cvs.el (cvs-do-update): Check that CVSROOT is set.
- * pcl-cvs.el (cvs-diff-cvs): Check that cvs-cvs-diff-flags is a
- list.
- * pcl-cvs.el (cvs-diff-backup): Check that cvs-diff-flags is a
- list.
-
-Tue Jul 21 11:27:39 1992 Per Cederqvist (ceder@robin)
-
- * pcl-cvs.el (cvs-parse-error): Make the *cvs* buffer writeable
- before trying to write the email message. Require sendmail before
- trying to switch to mail-mode.
-
- * pcl-cvs.el (cvs-do-update): Check that cvs-program exists.
-
- * pcl-cvs.el (cvs-skip-line): Fixed bracketing error.
-
-Mon Jul 20 10:31:51 1992 Per Cederqvist (ceder@robin)
-
- * Release 1.03.
-
- * pcl-cvs.el, cookie.el: Indentation fixes.
-
- * Makefile (pcl-cvs-$(VER)): Include NEWS in the distribution.
-
- * pcl-cvs.el (cvs-rm-program): Deleted.
- * pcl-cvs.el (cvs-rmdir-program, cvs-lock-file): New variables.
-
- * Handle lock files in a nicer way:
- * pcl-cvs.el (cvs-update-filter, cvs-delete-lock,
- cvs-lock-file-p): New functions.
- * pcl-cvs.el (cvs-do-update, cvs-sentinel): Redirect stdout to the
- temporary file, not stderr. Use cvs-update-filter.
- * pcl-cvs.el (cvs-parse-update): New arguments.
- * pcl-cvs.el (cvs-parse-buffer): Renamed to cvs-parse-update.
- * pcl-cvs.el (cvs-stderr-file): Renamed to cvs-stdout-file.
- * pcl-cvs.texinfo (Miscellaneous commands, Updating the
- directory): Document cvs-delete-lock.
-
- * pcl-cvs.el (cvs-mode): Don't reset buffer-read-only.
-
- * pcl-cvs.el (cvs-find-file-other-window): Don't save-some-buffers.
-
-Thu Jul 16 00:19:58 1992 Per Cederqvist (ceder@robin)
-
- * pcl-cvs.el, test-cookie-el: Use the new names from cookie.el.
-
- * cookie.el: Big Renaming Time!
- External functions:
- cookie-next -> tin-next
- cookie-previous -> tin-previous
- cookie-nth -> tin-nth
- cookie-delete -> tin-delete
- cookie-filter-tins -> tin-filter
- cookie-get-selection -> tin-get-selection
- cookie-start-marker -> tin-start-marker
- cookie-end-marker -> tin-end-marker
- cookie-invalidate-tins -> tin-invalidate-tins
- cookie-collect-tins -> tin-collect
- cookie-collect-cookies -> cookie-collect
- Internal functions:
- cookie-create-tin -> cookie-create-wrapper
- cookie-tin-start-marker -> cookie-wrapper-start-marker
- cookie-tin-cookie-safe -> cookie-wrapper-cookie-safe
- cookie-tin-cookie -> cookie-wrapper-cookie
- set-cookie-tin-start-marker -> cookie-wrapper-set-start-marker
- set-cookie-tin-cookie -> cookie-wrapper-set-cookie
- cookie-tin-p -> cookie-wrapper-p
- cookie-create-tin-and-insert -> cookie-create-wrapper-and-insert
-
- * pcl-cvs.el (cvs-find-file, cvs-find-file-other-window): Signal
- an appropriate error message if the *cvs* buffer is empty.
-
- * cookie.el (cookie-create): Make the buffer read-only.
- * cookie.el (cookie-create-tin-and-insert, cookie-refresh,
- cookie-delete-tin-internal, cookie-refresh-tin): Bind
- buffer-read-only to nil while changing the contents of
- the buffer.
-
- * pcl-cvs.el (cvs-byte-compile-files): New function.
- * pcl-cvs.texinfo (Miscellaneous commands): Document it.
-
- * pcl-cvs.el (cvs-diff-ignore-marks): New variable.
- * pcl-cvs.el (cvs-diff-cvs, cvs-diff-backup): Don't consider
- marked files to be selected if a prefix argument is given XOR the
- variable cvs-diff-ignore-marks is non-nil.
- * pcl-cvs.el (cvs-get-marked): New optional argument `ignore-marks'.
- * pcl-cvs.texinfo (Customization, Viewing differences): Document
- this behaviour.
-
- * pcl-cvs.el (cvs-undo-local-changes): New function.
- * pcl-cvs.texinfo (Undoing changes): Document
- cvs-undo-local-changes.
- * pcl-cvs.el (cvs-mode-map): cvs-unmark-all-files moved from "U"
- to "ESC DEL". cvs-undo-local-changes bound to "U".
- * pcl-cvs.texinfo (Marking files): Document ESC DEL.
-
- * pcl-cvs.el (cvs-skip-line): New arguments. All callers updated.
- Now calls cvs-parse-error if a parse error occurs.
- * pcl-cvs.el (cvs-parse-error): New function that creates a bug
- report.
- * pcl-cvs.el (cvs-parse-stderr, cvs-parse-stdout): New arguments.
- The only caller (cvs-parse-buffer) updated. Call cvs-parse-error
- in case of parse error.
-
- * pcl-cvs.el (pcl-cvs-version): New variable.
-
- * cookie.el (cookie-create): Kill all local variables in the buffer.
-
-Fri Jul 10 11:17:40 1992 Per Cederqvist (ceder@robin)
-
- * Release 1.03beta1.
-
-Thu Jul 9 03:12:00 1992 Per Cederqvist (ceder@robin)
-
- * pcl-cvs.el (cvs-update-running): New variable.
- * pcl-cvs.el (cvs-do-update): Use it instead of the previous local
- variable cvs-process (that no longer exists). Make sure that only
- one `cvs update' runs at any given moment.
- * pcl-cvs.el (cvs-sentinel): Reset cvs-update-running when the
- update process exits.
-
- * pcl-cvs.el (cvs-update): Switch to the *cvs* buffer.
- * pcl-cvs.el (cvs-update-other-window): New function.
- * pcl-cvs-startup.el (cvs-update-other-window): Added a autoload
- for it.
- * pcl-cvs.el (cvs-do-update): Don't pop up any buffer in a window
- - let cvs-update or cvs-update-other-window handle that. Also
- don't kill the *cvs* buffer, but rather insert a "Running cvs..."
- message into it.
- * pcl-cvs.el (cvs-parse-buffer): Don't change the window
- configuration.
-
- * pcl-cvs.el (cvs-create-fileinfo, cvs-pp, cvs-fileninfo->type):
- New type for a fileinfo: MESSAGE.
-
- * pcl-cvs.el (cvs-cvs-buffer): Deleted the variable. Use
- cvs-buffer-name instead. (I no longer have any plans to allow more
- than one cvs update to run at the same time - things only get
- confusing). Changed all places where cvs-cvs-buffer was used.
-
- * pcl-cvs.el: Take care of update programs (the -u option in the
- modules file):
- * pcl-cvs.el (cvs-update-prog-output-skip-regexp): New variable.
- * pcl-cvs.el (cvs-parse-stdout): Skip output from the update
- program (using cvs-update-prog-output-skip-regexp).
- * pcl-cvs.texinfo (Future enhancements): Document that the
- solution is not as good as it should be.
- * pcl-cvs.texinfo (Customization): Document the variable.
-
-Wed Jul 8 20:29:44 1992 Per Cederqvist (ceder@robin)
-
- * pcl-cvs.el (cvs-do-update): Check that this-dir really exists
- and is a directory, and that this-dir/CVS exists and is a
- directory.
-
-Tue Jul 7 01:02:24 1992 Per Cederqvist (ceder@robin)
-
- * pcl-cvs.texinfo (Customization): Document TMPDIR.
-
- * This chunk of modifications should make it possible to run
- pcl-cvs on hosts that do not line-buffer stdout (such as
- DECstation). They work by diverting stdout and stderr from
- `cvs update' and later sorting them together.
- * pcl-cvs.el (cvs-parse-stderr): Don't fail to parse conflict
- data.
- * pcl-cvs.el (cvs-remove-stdout-shadows, cvs-shadow-entry-p): New
- functions.
- * pcl-cvs.el (cvs-parse-buffer): Use it.
- * pcl-cvs.el (cvs-remove-empty-directories): New function.
- * pcl-cvs.el (cvs-remove-handled, cvs-parse-buffer): Use it.
- * pcl-cvs.el (cvs-get-current-dir): New argument ROOT-DIR. All
- calls to cvs-get-current-dir updated.
- * pcl-cvs.el (cvs-do-update): Allocate a tmp file. Use cvs-shell
- (typically /bin/sh) to redirect stderr from CVS to the tmp file.
- * pcl-cvs.el (cvs-sentinel): Handle the tmp file. Remove it when
- it is parsed.
- * pcl-cvs.el (cvs-parse-buffer): New argument STDERR-BUFFER. All
- calls to cvs-parse-buffer updated. Rewritten to handle the
- separation of stderr and stdout.
- * pcl-cvs.el (cvs-shell, cvs-stderr-file): New variables.
- * pcl-cvs.el (cvs-compare-fileinfos, cvs-parse-stderr,
- cvs-parse-stdout): New functions.
-
- * pcl-cvs.el (cvs-parse-buffer): Some modifications for output
- from RCS 5.6.
-
-Tue Apr 7 09:11:27 1992 Per Cederqvist (ceder@leopold)
-
- * Release 1.02.
-
- * pcl-cvs.el (cvs-diff-backup, cvs-edit-done, cvs-status): Call
- save-some-buffers.
-
- * pcl-cvs.el (cvs-diff-backup-extractor): Fixed syntax error.
-
- * Makefile, README, compile-all.el, dist-makefile, pcl-cvs.el,
- pcl-cvs.texinfo (XXRELEASEXX): A magic string that is substituted
- for the current release number when a distribution is made.
- (Release 1.01 says that it is release 1.00).
-
- * pcl-cvs.el (cvs-find-file): Added missing pair of parenthesis.
-
-Mon Mar 30 14:25:26 1992 Per Cederqvist (ceder@leopold)
-
- * Release 1.01.
-
- * pcl-cvs.el (cvs-parse-buffer): The message when waiting for a
- lock has been changed.
-
-Sun Mar 29 05:29:57 1992 Per Cederqvist (ceder@leopold)
-
- * Release 1.00.
-
- * pcl-cvs.el (cvs-do-update, cvs-sentinel, cvs-parse-buffer):
- Major rewrite of buffer and window selection and handling.
- The *cvs* buffer is now killed whenever a new "cvs update" is
- initiated. The -update buffer is replaced with the *cvs*
- buffer when the update is completed.
-
-Sat Mar 28 21:03:05 1992 Per Cederqvist (ceder@robin)
-
- * pcl-cvs.el (cvs-delete-unused-temporary-buffers): Fixed it.
-
- * pcl-cvs.el (cvs-auto-remove-handled): New variable.
- * pcl-cvs.el (cvs-edit-done): Use it.
- * pcl-cvs.texinfo (Customization, Removing handled entries):
- Document it.
-
- * pcl-cvs.el (cvs-mode): Turn of the undo feature. It really
- isn't useful in a cookie buffer...
-
- * pcl-cvs.el (cvs-edit-done): Committing a file now looks more
- like diffing a file. The window handling is better.
- * pcl-cvs.el (cvs-use-temp-buffer): The &optional switch is no
- longer needed.
-
-Mon Mar 23 00:20:33 1992 Per Cederqvist (ceder@robin)
-
- * Release 0.97.
-
- * pcl-cvs.el (default-directory): Make sure it always ends in a
- slash. fileinfo->dir does NOT end in a slash, and I had forgotten
- to call file-name-as-directory in various places.
-
- * pcl-cvs.el (cvs-diff-backup-extractor): Signal an error if a
- fileinfo without backup file is given.
-
- * pcl-cvs.el (cvs-mode): Added documentation.
-
- * pcl-cvs.el (cvs-execute-list): Fix the order of files in the
- same directory.
-
- * pcl-cvs.el (cvs-log-flags, cvs-status-flags): New variables.
- * pcl-cvs.el (cvs-log, cvs-status): Use them.
- * pcl-cvs.texinfo (Customization): Document them.
-
- * pcl-cvs.el (cvs-diff-backup): Filter non-backup-diffable files
- at an earlier stage, like cvs-commit does.
-
- * pcl-cvs.el (cvs-diff-flags): New variable.
- * pcl-cvs.el (cvs-diff-backup): Use it.
- * pcl-cvs.texinfo (Customization): Document it.
-
- * pcl-cvs.el (cvs-execute-single-file-list): Remove &rest before
- last argument. No callers needed updating.
-
- * pcl-cvs.el (cvs-execute-list): Remove the &rest before the last
- argument (constant-args). Update all callers of cvs-execute-list
- to use the new calling convention.
- * pcl-cvs.el (cvs-cvs-diff-flags): Now a list of strings instead
- of a string.
- * pcl-cvs.texinfo (Customization): Document the change to
- cvs-cvs-diff-flags.
-
- * Release 0.96.
-
- * pcl-cvs.el (cvs-cvs-diff-flags): New variable.
- * pcl-cvs.el (cvs-diff-cvs): Use it.
- * pcl-cvs.texinfo (Customization, Viewing differences): Document it.
-
- * pcl-cvs.el (cvs-use-temp-buffe): Don't switch to the temporary
- buffer. Use display-buffer and set-buffer instead. This way
- cvs-log, cvs-status, cvs-diff-cvs and friends don't select the
- temporary buffer. The cursor will remain in the *cvs* buffer.
-
-Sun Mar 22 21:50:18 1992 Per Cederqvist (ceder@robin)
-
- * pcl-cvs.el (cvs-find-file, cvs-find-file-other-window): Don't
- prompt when reading in a directory in dired.
-
- * Makefile (pcl-cvs-$(VER)): Include pcl-cvs-startup.el in the
- distribution.
-
- * dist-makefile (pcl-cvs.dvi): Don't fail even if texindex does
- not exist.
-
- * pcl-cvs.texinfo (@setchapternewpage): Changed from 'off' to 'on'.
- * pcl-cvs.texinfo (Variable index): Joined into function index.
- * pcl-cvs.texinfo (Key index): add a description about the key.
- * pcl-cvs.texinfo: Many other small changes.
-
-Wed Mar 18 01:58:38 1992 Per Cederqvist (ceder@leopold)
-
- * Use GNU General Public License version 2.
-
diff --git a/gnu/usr.bin/cvs/contrib/pcl-cvs/INSTALL b/gnu/usr.bin/cvs/contrib/pcl-cvs/INSTALL
deleted file mode 100644
index 76799679ac5d..000000000000
--- a/gnu/usr.bin/cvs/contrib/pcl-cvs/INSTALL
+++ /dev/null
@@ -1,89 +0,0 @@
-This text is copied from the TeXinfo manual for pcl-cvs.
-
-Installation of the pcl-cvs program
-===================================
-
- 1. Edit the file `Makefile' to reflect the situation at your site.
- The only things you have to change is the definition of `lispdir'
- and `infodir'. The elisp files will be copied to `lispdir', and
- the info file to `infodir'.
-
- 2. Configure pcl-cvs.el
-
- There are a couple of paths that you have to check to make sure
- that they match you system. They appear early in the file
- pcl-cvs.el.
-
- *NOTE:* If your system is running emacs 18.57 or earlier you
- MUST uncomment the line that says:
-
- (setq delete-exited-processes nil)
-
- Setting `delete-exited-processes' to `nil' works around a bug in
- emacs that causes it to dump core. The bug was fixed in emacs
- 18.58.
-
- 3. Release 1.05 and later of pcl-cvs requires parts of the Elib
- library, version 0.07 or later. Elib is available via anonymous
- ftp from prep.ai.mit.edu in `pub/gnu/elib-0.07.tar.z', and from
- a lot of other sites that mirrors prep. Get Elib, and install
- it, before proceeding.
-
- 4. Type `make install' in the source directory. This will
- byte-compile all `.el' files and copy both the `.el' and the
- `.elc' into the directory you specified in step 1.
-
- If you don't want to install the `.el' files but only the `.elc'
- files (the byte-compiled files), you can type ``make
- install_elc'' instead of ``make install''.
-
- If you only want to create the compiled elisp files, but don't
- want to install them, you can type `make elcfiles' instead.
- This is what happens if you only type `make' without parameters.
-
- 5. Edit the file `default.el' in your emacs lisp directory (usually
- `/usr/gnu/emacs/lisp' or something similar) and enter the
- contents of the file `pcl-cvs-startup.el' into it. It contains
- a couple of `auto-load's that facilitates the use of pcl-cvs.
-
-
-
-Installation of the on-line manual.
-===================================
-
- 1. Move the info file `pcl-cvs.info' to your standard info
- directory. This might be called something like
- `/usr/gnu/emacs/info'.
-
- 2. Edit the file `dir' in the info directory and enter one line to
- contain a pointer to the info file `pcl-cvs.info'. The line can,
- for instance, look like this:
-
- * Pcl-cvs: (pcl-cvs.info). An Emacs front-end to CVS.
-
-
-How to make the on-line manual from pcl-cvs.texinfo
-===================================================
-
- 1. Create the info file `pcl-cvs.info' from `pcl-cvs.texinfo' by
- typing `make info'. If you don't have the program `makeinfo' you
- can get it by anonymous ftp from e.g. `ftp.gnu.ai.mit.edu' as
- `pub/gnu/texinfo-2.14.tar.Z' (there might be a newer version
- there when you read this).
-
-
-How to make typeset documentation from pcl-cvs.texinfo
-======================================================
-
- If you have TeX installed at your site, you can make a typeset
-manual from `pcl-cvs.texinfo'.
-
- 1. Run TeX by typing ``make pcl-cvs.dvi''. You will not get the
- indices unless you have the `texindex' program.
-
- 2. Convert the resulting device independent file `pcl-cvs.dvi' to a
- form which your printer can output and print it. If you have a
- postscript printer there is a program, `dvi2ps', which does.
- There is also a program which comes together with TeX, `dvips',
- which you can use.
-
diff --git a/gnu/usr.bin/cvs/contrib/pcl-cvs/Makefile b/gnu/usr.bin/cvs/contrib/pcl-cvs/Makefile
deleted file mode 100644
index 7f6f5b118a69..000000000000
--- a/gnu/usr.bin/cvs/contrib/pcl-cvs/Makefile
+++ /dev/null
@@ -1,83 +0,0 @@
-# @(#) Id: dist-makefile,v 1.19 1993/05/31 22:43:45 ceder Exp
-# Makefile for pcl-cvs release 1.05.
-# Copyright (C) 1992, 1993 Per Cederqvist
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-# This is the directory in which the ELFILES and ELCFILES will be
-# installed.
-
-lispdir = /usr/local/lib/elisp
-
-# Where to install the info file.
-
-prefix=/usr/local
-infodir = $(prefix)/info
-
-# Used to byte-compile files.
-
-EMACS=emacs
-
-#
-# The rest of this file should not need to be modified.
-#
-
-# Just in case...
-SHELL = /bin/sh
-
-ELFILES = pcl-cvs.el pcl-cvs-lucid.el
-ELCFILES = pcl-cvs.elc pcl-cvs-lucid.elc
-INFOFILES = pcl-cvs
-TEXTMPS = pcl-cvs.aux pcl-cvs.log pcl-cvs.toc pcl-cvs.dvi pcl-cvs.cp \
- pcl-cvs.fn pcl-cvs.vr pcl-cvs.tp pcl-cvs.ky pcl-cvs.pg \
- pcl-cvs.cps pcl-cvs.fns pcl-cvs.kys pcl-cvs.pgs pcl-cvs.tps \
- pcl-cvs.vrs
-
-INSTALL = install
-INSTALL_DATA = $(INSTALL)
-
-elcfiles:
- $(EMACS) -batch -l ./compile-all.el -f compile-pcl-cvs
-
-all: elcfiles info
-
-# Don't install the info file yet, since it requires makeinfo
-# version 2.something (and version 1.something is distributed with emacs).
-#
-# install: install_elc install_info
-install: install_elc
- for i in $(ELFILES); do $(INSTALL_DATA) $$i $(lispdir)/$$i; done
-
-install_elc: elcfiles
- for i in $(ELCFILES); do $(INSTALL_DATA) $$i $(lispdir)/$$i; done
-
-install_info: pcl-cvs
- $(INSTALL_DATA) pcl-cvs $(infodir)/pcl-cvs
-
-info pcl-cvs: pcl-cvs.texinfo
- makeinfo +fill-column=70 pcl-cvs.texinfo
-
-pcl-cvs.dvi: pcl-cvs.texinfo
- tex pcl-cvs.texinfo
- tex pcl-cvs.texinfo
- -texindex pcl-cvs.cp pcl-cvs.fn pcl-cvs.vr pcl-cvs.tp pcl-cvs.ky \
- pcl-cvs.pg
- tex pcl-cvs.texinfo
-
-mostlyclean clean realclean:
- rm -f *~ core $(ELCFILES) $(INFOFILES) $(TEXTMPS)
-
-tags TAGS:
- etags *.el
diff --git a/gnu/usr.bin/cvs/contrib/pcl-cvs/NEWS b/gnu/usr.bin/cvs/contrib/pcl-cvs/NEWS
deleted file mode 100644
index 4f563ffc5019..000000000000
--- a/gnu/usr.bin/cvs/contrib/pcl-cvs/NEWS
+++ /dev/null
@@ -1,113 +0,0 @@
-This is the NEWS file for pcl-cvs, an Elisp front-end to CVS.
-
-User-visible changes in pcl-cvs from 1.04 to 1.05:
-
-* Elib is no longer distributed with pcl-cvs. You must get Elib
- separately, for instance from ftp.lysator.liu.se in pub/emacs.
-
-* The Lucid Emacs support works again.
-
-* A new function, cvs-change-cvsroot, can be used to interactively
- switch between CVS repositories.
-
-* The mode line in the *cvs* buffer now indicates when a "cvs update"
- is running.
-
-* The .cvsignore file is automatically sorted alphabetically (to
- reduce the risk of conflicts when two people add different files
- simultaneously). This behaviour can be turned off with
- cvs-sort-ignore-file.
-
-* A trailing newline is always added in commit log messages. This
- behaviour can be turned off with
- cvs-commit-buffer-require-final-newline.
-
-* This version of pcl-cvs should work together with RCVS. I have not
- tested this myself, though.
-
-* Plus some bug fixes. (Note that the version of cookie.el that is
- distributed with pcl-cvs 1.04 contains errors that affects pcl-cvs.
- You should get Elib 0.07).
-
-
-User-visible changes in pcl-cvs from 1.03 to 1.04:
-
-* Support for Emerge. Hitting "e" on a file that is Modified, Merged
- or in Conflict will start Emerge, an interactive file merger written
- in Emacs Lisp. This requires Emerge version 4. Emerge is not
- included in this package. If you can't find it anywhere else, you
- can get in from ftp.lysator.liu.se in pub/emacs. This package makes
- it a lot easier to resolve conflicts.
-
-* Emacs will now automatically revert your buffers when the CVS
- commands pcl-cvs issues causes the file to change. This automatic
- revert never occurs if the buffer contents did not agree with the
- file prior to the command.
-
-* If you are running Lucid GNU Emacs, you will get some fonts and
- mouse support. This was contributed from people at Lucid.
-
-* The variable cvs-cvsroot can be used to select the location if the
- repository. You no longer need to exit Emacs, setenv CVSROOT, and
- start a new Emacs if you work with multiple repositories.
-
-* The "q" key can be used to hide the *cvs* buffer.
-
-* The name of the commands in the *cvs* have changed. If it was called
- cvs-foo, it will now be called cvs-mode-foo. See the ChangeLog
- entry from Tue Aug 4 03:02:25 1992 for a complete list of changes.
-
-* The variable cvs-cvs-diff-flags is no longer used. Instead,
- cvs-diff-flags is always used.
-
-* Plus a lot of bug fixes.
-
-
-User-visible changes in pcl-cvs from 1.02 to 1.03:
-
-* Output from CVS to stdout and stderr is separated and parsed
- independently. In that way pcl-cvs should work regardless of
- whether stdout is buffered or line-buffered. Pcl-cvs should now
- work with CVS 1.3 without modifications on hosts such as
- DECstations.
-
-* Pcl-cvs now fully supports RCS version 5.6 as well as 5.5.
-
-* New functions:
-
- + cvs-undo-local-changes ("U") - Undo all your modifications
- to a file and get the newest
- version from the repository.
- + cvs-update-other-window - Similar to cvs-update.
- + cvs-byte-compile-files - Byte compile the selected files.
-
-* cvs-update now displays the *cvs* buffer, which initially contains a
- small message ("Running `cvs update' in /foo/bar/gazonk/...") until
- the update is ready. The *cvs* buffer no longer pops up when the
- update is ready. It often failed to pop up, due to race conditions
- that are very hard to solve (and I doubt that they were at all
- solvable).
-
-* cvs-unmark-all-files is moved from "U" to "ESC DEL" to be
- "compatible" with dired.
-
-* cvs-diff ("d") and cvs-diff-backup ("b") can be configured to work
- on only the file the cursor is positioned on, and ignore any marked
- files. A prefix argument toggles this.
-
-* Only one `cvs update' can be run at a time. (It was previously
- possible to start more than one simultaneously, but pcl-cvs could
- not really handle more than one.)
-
-* Some rudimentary support for programs that CVS runs at update (due
- to the -u switch in the modules file).
-
-* Pcl-cvs now automatically generates a bug report if it can't parse
- the output from CVS.
-
-* The *cvs* buffer is read-only.
-
-* Pcl-cvs now creates temporary files in $TMPDIR if that environment
- variable is set (otherwise it uses /tmp).
-
----End of file NEWS---
diff --git a/gnu/usr.bin/cvs/contrib/pcl-cvs/README b/gnu/usr.bin/cvs/contrib/pcl-cvs/README
deleted file mode 100644
index a9b810661373..000000000000
--- a/gnu/usr.bin/cvs/contrib/pcl-cvs/README
+++ /dev/null
@@ -1,29 +0,0 @@
-@(#) Id: README,v 1.14 1993/05/31 22:43:36 ceder Exp
-
-This is the readme file for pcl-cvs, release 1.05.
-
-This release of pcl-cvs requires Elib 0.07 or later. Elib is no
-longer distributed with pcl-cvs, since that caused too much confusion.
-You can get Elib from ftp.lysator.liu.se in pub/emacs/elib-*.tar.?.
-
-Pcl-cvs is a front-end to CVS version 1.3. It integrates the most
-frequently used CVS commands into emacs.
-
-There is some configuration that needs to be done in pcl-cvs.el to get
-it to work. See the instructions in file INSTALL.
-
-Full documentation is in pcl-cvs.texinfo. Since it requires makeinfo
-version 2 or 3 a preformatted info file is also included (pcl-cvs.info).
-
-If you have been using a previous version of pcl-cvs (for instance
-1.02 which is distributed with CVS 1.3) you should read through the
-file NEWS to see what has changed.
-
-This release has been tested under Emacs 18.59, Emacs 19.28 and Lucid
-Emacs 19.6. Emacs 19.10 unfortunately has a file named cookie.el that
-collides with the cookie.el that is distributed in Elib. This
-conflict was resolved in 19.11. For earlier versions, there are
-instructions in Elib 0.07 for how to work around the problem.
-
- Per Cederqvist
- (updated by Jim Blandy)
diff --git a/gnu/usr.bin/cvs/contrib/pcl-cvs/compile-all.el b/gnu/usr.bin/cvs/contrib/pcl-cvs/compile-all.el
deleted file mode 100644
index 656327750859..000000000000
--- a/gnu/usr.bin/cvs/contrib/pcl-cvs/compile-all.el
+++ /dev/null
@@ -1,52 +0,0 @@
-;;;; @(#) Id: compile-all.el,v 1.11 1993/05/31 18:40:25 ceder Exp
-;;;; This file byte-compiles all .el files in pcl-cvs release 1.05.
-;;;;
-;;;; Copyright (C) 1991 Inge Wallin
-;;;;
-;;;; This file was once upon a time part of Elib, but have since been
-;;;; modified by Per Cederqvist.
-;;;;
-;;;; GNU Elib is free software; you can redistribute it and/or modify
-;;;; it under the terms of the GNU General Public License as published by
-;;;; the Free Software Foundation; either version 1, or (at your option)
-;;;; any later version.
-;;;;
-;;;; GNU Elib is distributed in the hope that it will be useful,
-;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;;;; GNU General Public License for more details.
-;;;;
-;;;; You should have received a copy of the GNU General Public License
-;;;; along with GNU Emacs; see the file COPYING. If not, write to
-;;;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-;;;;
-
-
-(setq files-to-compile '("pcl-cvs" "pcl-cvs-lucid"))
-
-
-(defun compile-file-if-necessary (file)
- "Compile FILE if necessary.
-
-This is done if FILE.el is newer than FILE.elc or if FILE.elc doesn't exist."
- (let ((el-name (concat file ".el"))
- (elc-name (concat file ".elc")))
- (if (or (not (file-exists-p elc-name))
- (file-newer-than-file-p el-name elc-name))
- (progn
- (message (format "Byte-compiling %s..." el-name))
- (byte-compile-file el-name)))))
-
-
-(defun compile-pcl-cvs ()
- "Byte-compile all uncompiled files of pcl-cvs."
-
- (interactive)
-
- ;; Be sure to have . in load-path since a number of files
- ;; depend on other files and we always want the newer one even if
- ;; a previous version of pcl-cvs exists.
- (let ((load-path (append '(".") load-path)))
-
- (mapcar (function compile-file-if-necessary)
- files-to-compile)))
diff --git a/gnu/usr.bin/cvs/contrib/pcl-cvs/cookie.el b/gnu/usr.bin/cvs/contrib/pcl-cvs/cookie.el
deleted file mode 100644
index 8bd4bdff6ce0..000000000000
--- a/gnu/usr.bin/cvs/contrib/pcl-cvs/cookie.el
+++ /dev/null
@@ -1,884 +0,0 @@
-;;; cookie.el,v 1.2 1992/04/07 20:49:12 berliner Exp
-;;; cookie.el -- Utility to display cookies in buffers
-;;; Copyright (C) 1991, 1992 Per Cederqvist
-;;;
-;;; This program is free software; you can redistribute it and/or modify
-;;; it under the terms of the GNU General Public License as published by
-;;; the Free Software Foundation; either version 2 of the License, or
-;;; (at your option) any later version.
-;;;
-;;; This program is distributed in the hope that it will be useful,
-;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;;; GNU General Public License for more details.
-;;;
-;;; You should have received a copy of the GNU General Public License
-;;; along with this program; if not, write to the Free Software
-;;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-;;;; TO-DO: Byt namn! tin -> wrapper (eller n}got b{ttre).
-
-;;; Note that this file is still under development. Comments,
-;;; enhancements and bug fixes are welcome.
-;;; Send them to ceder@lysator.liu.se.
-
-(defun impl nil (error "Not yet implemented!"))
-
-;;; Cookie is a package that imlements a connection between an
-;;; elib-dll and the contents of a buffer. Possible uses are dired
-;;; (have all files in a list, and show them), buffer-list,
-;;; kom-prioritize (in the LysKOM elisp client) and others. pcl-cvs.el
-;;; uses cookie.el.
-;;;
-;;; A cookie buffer contains a header, any number of cookies, and a
-;;; footer. The header and footer are constant strings that are given
-;;; to cookie-create when the buffer is placed under cookie. Each cookie
-;;; is displayed in the buffer by calling a user-supplied function
-;;; that takes a cookie and returns a string. The string may be
-;;; empty, or contain any number of lines. An extra newline is always
-;;; appended unless the string is empty.
-;;;
-;;; Cookie does not affect the mode of the buffer in any way. It
-;;; merely makes it easy to connect an underlying data representation
-;;; to the buffer contents.
-;;;
-;;; The cookie-node data type:
-;;; start-marker
-;;; ;; end-marker This field is no longer present.
-;;; cookie The user-supplied element.
-;;;
-;;; A dll of cookie-nodes are held in the buffer local variable
-;;; cake-tin.
-;;;
-;;; A tin is an object that contains one cookie. You can get the next
-;;; and previous tin.
-;;;
-
-(require 'elib-dll)
-(provide 'cookie)
-
-(defvar cookies nil
- "A doubly linked list that contains the underlying data representation
-for the contents of a cookie buffer. The package elib-dll is used to
-manipulate this list.")
-
-(defvar cookie-pretty-printer nil
- "The function that is used to pretty-print a cookie in this buffer.")
-
-(defvar cookie-header nil
- "The tin that holds the header cookie.")
-
-(defvar cookie-footer nil
- "The tin that holds the footer cookie.")
-
-(defvar cookie-last-tin nil
- "The tin the cursor was positioned at, the last time the cookie
-package checked the cursor position. Buffer local in all buffers
-the cookie package works on. You may set this if your package
-thinks it knows where the cursor will be the next time this
-package is called. It can speed things up.
-
-It must never be set to a tin that has been deleted.")
-
-;;; ================================================================
-;;; Internal functions for use in the cookie package
-
-(put 'cookie-set-buffer 'lisp-indent-hook 1)
-
-(defmacro cookie-set-buffer (buffer &rest forms)
-
- ;; Execute FORMS with BUFFER selected as current buffer.
- ;; Return value of last form in FORMS. INTERNAL USE ONLY.
-
- (let ((old-buffer (make-symbol "old-buffer")))
- (` (let (((, old-buffer) (current-buffer)))
- (set-buffer (get-buffer-create (, buffer)))
- (unwind-protect
- (progn (,@ forms))
- (set-buffer (, old-buffer)))))))
-
-
-(defmacro cookie-filter-hf (tin)
-
- ;; Evaluate TIN once and return it. BUT if it is
- ;; equal to cookie-header or cookie-footer return nil instead.
- ;; INTERNAL USE ONLY.
-
- (let ((tempvar (make-symbol "tin")))
- (` (let (((, tempvar) (, tin)))
- (if (or (eq (, tempvar) cookie-header)
- (eq (, tempvar) cookie-footer))
- nil
- (, tempvar))))))
-
-
-;;; cookie-tin
-;;; Constructor:
-
-(defun cookie-create-tin (start-marker
- cookie)
- ;; Create a tin. INTERNAL USE ONLY.
- (cons 'COOKIE-TIN (vector start-marker nil cookie)))
-
-
-;;; Selectors:
-
-(defun cookie-tin-start-marker (cookie-tin)
- ;; Get start-marker from cookie-tin. INTERNAL USE ONLY.
- (elt (cdr cookie-tin) 0))
-
-;(defun cookie-tin-end-marker (cookie-tin)
-; ;;Get end-marker from cookie-tin. INTERNAL USE ONLY.
-; (elt (cdr cookie-tin) 1))
-
-(defun cookie-tin-cookie-safe (cookie-tin)
- ;; Get cookie from cookie-tin. INTERNAL USE ONLY.
- ;; Returns nil if given nil as input.
- ;; This is the same as cookie-tin-cookie in version 18.57
- ;; of emacs, but elt should signal an error when given nil
- ;; as input (according to the info files).
- (elt (cdr cookie-tin) 2))
-
-(defun cookie-tin-cookie (cookie-tin)
- ;; Get cookie from cookie-tin. INTERNAL USE ONLY.
- (elt (cdr cookie-tin) 2))
-
-
-;;; Modifiers:
-
-(defun set-cookie-tin-start-marker (cookie-tin newval)
- ;; Set start-marker in cookie-tin to NEWVAL. INTERNAL USE ONLY.
- (aset (cdr cookie-tin) 0 newval))
-
-;(defun set-cookie-tin-end-marker (cookie-tin newval)
-; ;; Set end-marker in cookie-tin to NEWVAL. INTERNAL USE ONLY.
-; (aset (cdr cookie-tin) 1 newval))
-
-(defun set-cookie-tin-cookie (cookie-tin newval)
- ;; Set cookie in cookie-tin to NEWVAL. INTERNAL USE ONLY.
- (aset (cdr cookie-tin) 2 newval))
-
-
-
-;;; Predicate:
-
-(defun cookie-tin-p (object)
- ;; Return t if OBJECT is a tin. INTERNAL USE ONLY.
- (eq (car-safe object) 'COOKIE-TIN))
-
-;;; end of cookie-tin data type.
-
-
-(defun cookie-create-tin-and-insert (cookie string pos)
- ;; Insert STRING at POS in current buffer. Remember start
- ;; position. Create a tin containing them and the COOKIE.
- ;; INTERNAL USE ONLY.
-
- (save-excursion
- (goto-char pos)
- ;; Remember the position as a number so that it doesn't move
- ;; when we insert the string.
- (let ((start (if (markerp pos)
- (marker-position pos)
- pos)))
- ;; Use insert-before-markers so that the marker for the
- ;; next cookie is updated.
- (insert-before-markers string)
- (insert-before-markers ?\n)
- (cookie-create-tin (copy-marker start) cookie))))
-
-
-(defun cookie-delete-tin-internal (tin)
- ;; Delete a cookie from the buffer. INTERNAL USE ONLY.
- ;; Can not be used on the footer.
- (delete-region (cookie-tin-start-marker (dll-element cookies tin))
- (cookie-tin-start-marker
- (dll-element cookies
- (dll-next cookies tin)))))
-
-
-
-(defun cookie-refresh-tin (tin)
- ;; Redisplay the cookie represented by TIN. INTERNAL USE ONLY.
- ;; Can not be used on the footer.
-
- (save-excursion
- ;; First, remove the string:
- (delete-region (cookie-tin-start-marker (dll-element cookies tin))
- (1- (marker-position
- (cookie-tin-start-marker
- (dll-element cookies
- (dll-next cookies tin))))))
-
- ;; Calculate and insert the string.
-
- (goto-char (cookie-tin-start-marker (dll-element cookies tin)))
- (insert
- (funcall cookie-pretty-printer
- (cookie-tin-cookie (dll-element cookies tin))))))
-
-
-;;; ================================================================
-;;; The public members of the cookie package
-
-
-(defun cookie-cookie (buffer tin)
- "Get the cookie from a TIN. Args: BUFFER TIN."
- (cookie-set-buffer buffer
- (cookie-tin-cookie (dll-element cookies tin))))
-
-
-
-
-(defun cookie-create (buffer pretty-printer &optional header footer)
-
- "Start to use the cookie package in BUFFER.
-BUFFER may be a buffer or a buffer name. It is created if it does not exist.
-Beware that the entire contents of the buffer will be erased.
-PRETTY-PRINTER is a function that takes one cookie and returns a string
-to be displayed in the buffer. The string may be empty. If it is not
-empty a newline will be added automatically. It may span several lines.
-Optional third argument HEADER is a string that will always be present
-at the top of the buffer. HEADER should end with a newline. Optionaly
-fourth argument FOOTER is similar, and will always be inserted at the
-bottom of the buffer."
-
- (cookie-set-buffer buffer
-
- (erase-buffer)
-
- (make-local-variable 'cookie-last-tin)
- (make-local-variable 'cookie-pretty-printer)
- (make-local-variable 'cookie-header)
- (make-local-variable 'cookie-footer)
- (make-local-variable 'cookies)
-
- (setq cookie-last-tin nil)
- (setq cookie-pretty-printer pretty-printer)
- (setq cookies (dll-create))
-
- (dll-enter-first cookies
- (cookie-create-tin-and-insert
- header header 0))
- (setq cookie-header (dll-nth cookies 0))
-
- (dll-enter-last cookies
- (cookie-create-tin-and-insert
- footer footer (point-max)))
- (setq cookie-footer (dll-nth cookies -1))
-
- (goto-char (point-min))
- (forward-line 1)))
-
-
-(defun cookie-set-header (buffer header)
- "Change the header. Args: BUFFER HEADER."
- (impl))
-
-
-(defun cookie-set-footer (buffer header)
- "Change the footer. Args: BUFFER FOOTER."
- (impl))
-
-
-
-(defun cookie-enter-first (buffer cookie)
- "Enter a COOKIE first in BUFFER.
-Args: BUFFER COOKIE."
-
- (cookie-set-buffer buffer
-
- ;; It is always safe to insert an element after the first element,
- ;; because the header is always present. (dll-nth cookies 0) should
- ;; never return nil.
-
- (dll-enter-after
- cookies
- (dll-nth cookies 0)
- (cookie-create-tin-and-insert
- cookie
- (funcall cookie-pretty-printer cookie)
- (cookie-tin-start-marker
- (dll-element cookies (dll-nth cookies 1)))))))
-
-
-
-(defun cookie-enter-last (buffer cookie)
- "Enter a COOKIE last in BUFFER.
-Args: BUFFER COOKIE."
-
- (cookie-set-buffer buffer
-
- ;; Remember that the header and footer are always present. There
- ;; is no need to check if (dll-nth cookies -2) returns nil.
-
- (dll-enter-before
- cookies
- (dll-nth cookies -1)
- (cookie-create-tin-and-insert
- cookie
- (funcall cookie-pretty-printer cookie)
- (cookie-tin-start-marker (dll-last cookies))))))
-
-
-(defun cookie-enter-after (buffer node cookie)
- (impl))
-
-
-(defun cookie-enter-before (buffer node cookie)
- (impl))
-
-
-
-(defun cookie-next (buffer tin)
- "Get the next tin. Args: BUFFER TIN.
-Returns nil if TIN is nil or the last cookie."
- (if tin
- (cookie-set-buffer buffer
- (cookie-filter-hf (dll-next cookies tin)))))
-
-
-
-(defun cookie-previous (buffer tin)
- "Get the previous tin. Args: BUFFER TIN.
-Returns nil if TIN is nil or the first cookie."
- (if tin
- (cookie-set-buffer buffer
- (cookie-filter-hf (dll-previous cookies tin)))))
-
-
-(defun cookie-nth (buffer n)
-
- "Return the Nth tin. Args: BUFFER N.
-N counts from zero. Nil is returned if there is less than N cookies.
-If N is negative, return the -(N+1)th last element.
-Thus, (cookie-nth dll 0) returns the first node,
-and (cookie-nth dll -1) returns the last node.
-
-Use cookie-cookie to extract the cookie from the tin."
-
- (cookie-set-buffer buffer
-
- ;; Skip the header (or footer, if n is negative).
- (if (< n 0)
- (setq n (1- n))
- (setq n (1+ n)))
-
- (cookie-filter-hf (dll-nth cookies n))))
-
-
-
-(defun cookie-delete (buffer tin)
- "Delete a cookie. Args: BUFFER TIN."
-
- (cookie-set-buffer buffer
- (if (eq cookie-last-tin tin)
- (setq cookie-last-tin nil))
-
- (cookie-delete-tin-internal tin)
- (dll-delete cookies tin)))
-
-
-
-(defun cookie-delete-first (buffer)
- "Delete first cookie and return it. Args: BUFFER.
-Returns nil if there is no cookie left."
-
- (cookie-set-buffer buffer
-
- ;; We have to check that we do not try to delete the footer.
-
- (let ((tin (dll-nth cookies 1))) ;Skip the header.
- (if (eq tin cookie-footer)
- nil
- (cookie-delete-tin-internal tin)
- (cookie-tin-cookie (dll-delete cookies tin))))))
-
-
-
-(defun cookie-delete-last (buffer)
- "Delete last cookie and return it. Args: BUFFER.
-Returns nil if there is no cookie left."
-
- (cookie-set-buffer buffer
-
- ;; We have to check that we do not try to delete the header.
-
- (let ((tin (dll-nth cookies -2))) ;Skip the footer.
- (if (eq tin cookie-header)
- nil
- (cookie-delete-tin-internal tin)
- (cookie-tin-cookie (dll-delete cookies tin))))))
-
-
-
-(defun cookie-first (buffer)
-
- "Return the first cookie in BUFFER. The cookie is not removed."
-
- (cookie-set-buffer buffer
- (let ((tin (cookie-filter-hf (dll-nth cookies -1))))
- (if tin
- (cookie-tin-cookie-safe
- (dll-element cookies tin))))))
-
-
-(defun cookie-last (buffer)
-
- "Return the last cookie in BUFFER. The cookie is not removed."
-
- (cookie-set-buffer buffer
- (let ((tin (cookie-filter-hf (dll-nth cookies -2))))
- (if tin
- (cookie-tin-cookie-safe
- (dll-element cookies tin))))))
-
-
-(defun cookie-empty (buffer)
-
- "Return true if there are no cookies in BUFFER."
-
- (cookie-set-buffer buffer
- (eq (dll-nth cookies 1) cookie-footer)))
-
-
-(defun cookie-length (buffer)
-
- "Return number of cookies in BUFFER."
-
- ;; Don't count the footer and header.
-
- (cookie-set-buffer buffer
- (- (dll-length cookies) 2)))
-
-
-(defun cookie-all (buffer)
-
- "Return a list of all cookies in BUFFER."
-
- (cookie-set-buffer buffer
- (let (result
- (tin (dll-nth cookies -2)))
- (while (not (eq tin cookie-header))
- (setq result (cons (cookie-tin-cookie (dll-element cookies tin))
- result))
- (setq tin (dll-previous cookies tin)))
- result)))
-
-(defun cookie-clear (buffer)
-
- "Remove all cookies in buffer."
-
- (cookie-set-buffer buffer
- (cookie-create buffer cookie-pretty-printer
- (cookie-tin-cookie (dll-element cookies cookie-header))
- (cookie-tin-cookie (dll-element cookies cookie-footer)))))
-
-
-
-(defun cookie-map (map-function buffer &rest map-args)
-
- "Apply MAP-FUNCTION to all cookies in BUFFER.
-MAP-FUNCTION is applied to the first element first.
-If MAP-FUNCTION returns non-nil the cookie will be refreshed.
-
-Note that BUFFER will be current buffer when MAP-FUNCTION is called.
-
-If more than two arguments are given to cookie-map, remaining
-arguments will be passed to MAP-FUNCTION."
-
- (cookie-set-buffer buffer
- (let ((tin (dll-nth cookies 1))
- result)
-
- (while (not (eq tin cookie-footer))
-
- (if (apply map-function
- (cookie-tin-cookie (dll-element cookies tin))
- map-args)
- (cookie-refresh-tin tin))
-
- (setq tin (dll-next cookies tin))))))
-
-
-
-(defun cookie-map-reverse (map-function buffer &rest map-args)
-
- "Apply MAP-FUNCTION to all cookies in BUFFER.
-MAP-FUNCTION is applied to the last cookie first.
-If MAP-FUNCTION returns non-nil the cookie will be refreshed.
-
-Note that BUFFER will be current buffer when MAP-FUNCTION is called.
-
-If more than two arguments are given to cookie-map, remaining
-arguments will be passed to MAP-FUNCTION."
-
- (cookie-set-buffer buffer
- (let ((tin (dll-nth cookies -2))
- result)
-
- (while (not (eq tin cookie-header))
-
- (if (apply map-function
- (cookie-tin-cookie (dll-element cookies tin))
- map-args)
- (cookie-refresh-tin tin))
-
- (setq tin (dll-previous cookies tin))))))
-
-
-
-(defun cookie-enter-cookies (buffer cookie-list)
-
- "Insert all cookies in the list COOKIE-LIST last in BUFFER.
-Args: BUFFER COOKIE-LIST."
-
- (while cookie-list
- (cookie-enter-last buffer (car cookie-list))
- (setq cookie-list (cdr cookie-list))))
-
-
-(defun cookie-filter (buffer predicate)
-
- "Remove all cookies in BUFFER for which PREDICATE returns nil.
-Note that BUFFER will be current-buffer when PREDICATE is called.
-
-The PREDICATE is called with one argument, the cookie."
-
- (cookie-set-buffer buffer
- (let ((tin (dll-nth cookies 1))
- next)
- (while (not (eq tin cookie-footer))
- (setq next (dll-next cookies tin))
- (if (funcall predicate (cookie-tin-cookie (dll-element cookies tin)))
- nil
- (cookie-delete-tin-internal tin)
- (dll-delete cookies tin))
- (setq tin next)))))
-
-
-(defun cookie-filter-tins (buffer predicate)
-
- "Remove all cookies in BUFFER for which PREDICATE returns nil.
-Note that BUFFER will be current-buffer when PREDICATE is called.
-
-The PREDICATE is called with one argument, the tin."
-
- (cookie-set-buffer buffer
- (let ((tin (dll-nth cookies 1))
- next)
- (while (not (eq tin cookie-footer))
- (setq next (dll-next cookies tin))
- (if (funcall predicate tin)
- nil
- (cookie-delete-tin-internal tin)
- (dll-delete cookies tin))
- (setq tin next)))))
-
-(defun cookie-pos-before-middle-p (pos tin1 tin2)
-
- "Return true if POS is in the first half of the region defined by TIN1 and
-TIN2."
-
- (< pos (/ (+ (cookie-tin-start-marker (dll-element cookeis tin1))
- (cookie-tin-start-marker (dll-element cookeis tin2)))
- 2)))
-
-
-(defun cookie-get-selection (buffer pos &optional guess force-guess)
-
- "Return the tin the POS is within.
-Args: BUFFER POS &optional GUESS FORCE-GUESS.
-GUESS should be a tin that it is likely that POS is near. If FORCE-GUESS
-is non-nil GUESS is always used as a first guess, otherwise the first
-guess is the first tin, last tin, or GUESS, whichever is nearest to
-pos in the BUFFER.
-
-If pos points within the header, the first cookie is returned.
-If pos points within the footer, the last cookie is returned.
-Nil is returned if there is no cookie.
-
-It is often good to specify cookie-last-tin as GUESS, but remember
-that cookie-last-tin is buffer local in all buffers that cookie
-operates on."
-
- (cookie-set-buffer buffer
-
- (cond
- ; No cookies present?
- ((eq (dll-nth cookies 1) (dll-nth cookies -1))
- nil)
-
- ; Before first cookie?
- ((< pos (cookie-tin-start-marker
- (dll-element cookies (dll-nth cookies 1))))
- (dll-nth cookies 1))
-
- ; After last cookie?
- ((>= pos (cookie-tin-start-marker (dll-last cookies)))
- (dll-nth cookies -2))
-
- ; We now now that pos is within a cookie.
- (t
- ; Make an educated guess about which of the three known
- ; cookies (the first, the last, or GUESS) is nearest.
- (setq
- guess
- (cond
- (force-guess guess)
- (guess
- (cond
- ;; Closest to first cookie?
- ((cookie-pos-before-middle-p
- pos guess
- (dll-nth cookies 1))
- (dll-nth cookies 1))
- ;; Closest to GUESS?
- ((cookie-pos-before-middle-p
- pos guess
- cookie-footer)
- guess)
- ;; Closest to last cookie.
- (t (dll-previous cookies cookie-footer))))
- (t
- ;; No guess given.
- (cond
- ;; First half?
- ((cookie-pos-before-middle-p
- pos (dll-nth cookies 1)
- cookie-footer)
- (dll-nth cookies 1))
- (t (dll-previous cookies cookie-footer))))))
-
- ;; GUESS is now a "best guess".
-
- ;; Find the correct cookie. First determine in which direction
- ;; it lies, and then move in that direction until it is found.
-
- (cond
- ;; Is pos after the guess?
- ((>= pos (cookie-tin-start-marker (dll-element cookiess guess)))
-
- ;; Loop until we are exactly one cookie too far down...
- (while (>= pos (cookie-tin-start-marker (dll-element cookiess guess)))
- (setq guess (dll-next cookies guess)))
-
- ;; ...and return the previous cookie.
- (dll-previous cookies guess))
-
- ;; Pos is before guess
- (t
-
- (while (< pos (cookie-tin-start-marker (dll-element cookiess guess)))
- (setq guess (dll-previous cookies guess)))
-
- guess))))))
-
-
-(defun cookie-start-marker (buffer tin)
-
- "Return start-position of a cookie in BUFFER.
-Args: BUFFER TIN.
-The marker that is returned should not be modified in any way,
-and is only valid until the contents of the cookie buffer changes."
-
- (cookie-set-buffer buffer
- (cookie-tin-start-marker (dll-element cookies tin))))
-
-
-(defun cookie-end-marker (buffer tin)
-
- "Return end-position of a cookie in BUFFER.
-Args: BUFFER TIN.
-The marker that is returned should not be modified in any way,
-and is only valid until the contents of the cookie buffer changes."
-
- (cookie-set-buffer buffer
- (cookie-tin-start-marker
- (dll-element cookies (dll-next cookies tin)))))
-
-
-
-(defun cookie-refresh (buffer)
-
- "Refresh all cookies in BUFFER.
-Cookie-pretty-printer will be called for all cookies and the new result
-displayed.
-
-See also cookie-invalidate-tins."
-
- (cookie-set-buffer buffer
-
- (erase-buffer)
-
- (set-marker (cookie-tin-start-marker (dll-element cookies cookie-header))
- (point) buffer)
- (insert (cookie-tin-cookie (dll-element cookies cookie-header)))
- (insert "\n")
-
- (let ((tin (dll-nth cookies 1)))
- (while (not (eq tin cookie-footer))
-
- (set-marker (cookie-tin-start-marker (dll-element cookies tin))
- (point) buffer)
- (insert
- (funcall cookie-pretty-printer
- (cookie-tin-cookie (dll-element cookies tin))))
- (insert "\n")
- (setq tin (dll-next cookies tin))))
-
- (set-marker (cookie-tin-start-marker (dll-element cookies cookie-footer))
- (point) buffer)
- (insert (cookie-tin-cookie (dll-element cookies cookie-footer)))
- (insert "\n")))
-
-
-(defun cookie-invalidate-tins (buffer &rest tins)
-
- "Refresh some cookies.
-Args: BUFFER &rest TINS."
-
- (cookie-set-buffer buffer
-
- (while tins
- (cookie-refresh-tin (car tins))
- (setq tins (cdr tins)))))
-
-
-;;; Cookie movement commands.
-
-(defun cookie-set-goal-column (buffer goal)
- "Set goal-column for BUFFER.
-Args: BUFFER GOAL.
-goal-column is made buffer-local."
- (cookie-set-buffer buffer
- (make-local-variable 'goal-column)
- (setq goal-column goal)))
-
-
-(defun cookie-previous-cookie (buffer pos arg)
- "Move point to the ARGth previous cookie.
-Don't move if we are at the first cookie.
-ARG is the prefix argument when called interactively.
-Args: BUFFER POS ARG.
-Sets cookie-last-tin to the cookie we move to."
-
- (interactive (list (current-buffer) (point)
- (prefix-numeric-value current-prefix-arg)))
-
- (cookie-set-buffer buffer
- (setq cookie-last-tin
- (cookie-get-selection buffer pos cookie-last-tin))
-
- (while (and cookie-last-tin (> arg 0))
- (setq arg (1- arg))
- (setq cookie-last-tin
- (dll-previous cookies cookie-last-tin)))
-
- ;; Never step above the first cookie.
-
- (if (null (cookie-filter-hf cookie-last-tin))
- (setq cookie-last-tin (dll-nth cookies 1)))
-
- (goto-char
- (cookie-tin-start-marker
- (dll-element cookies cookie-last-tin)))
-
- (if goal-column
- (move-to-column goal-column))))
-
-
-
-(defun cookie-next-cookie (buffer pos arg)
- "Move point to the ARGth next cookie.
-Don't move if we are at the last cookie.
-ARG is the prefix argument when called interactively.
-Args: BUFFER POS ARG.
-Sets cookie-last-tin to the cookie we move to."
-
- (interactive (list (current-buffer) (point)
- (prefix-numeric-value current-prefix-arg)))
-
- (cookie-set-buffer buffer
- (setq cookie-last-tin
- (cookie-get-selection buffer pos cookie-last-tin))
-
- (while (and cookie-last-tin (> arg 0))
- (setq arg (1- arg))
- (setq cookie-last-tin
- (dll-next cookies cookie-last-tin)))
-
- (if (null (cookie-filter-hf cookie-last-tin))
- (setq cookie-last-tin (dll-nth cookies -2)))
-
- (goto-char
- (cookie-tin-start-marker
- (dll-element cookies cookie-last-tin)))
-
- (if goal-column
- (move-to-column goal-column))))
-
-
-(defun cookie-collect-tins (buffer predicate &rest predicate-args)
-
- "Return a list of all tins in BUFFER whose cookie PREDICATE
-returns true for.
-PREDICATE is a function that takes a cookie as its argument.
-The tins on the returned list will appear in the same order
-as in the buffer. You should not rely on in which order PREDICATE
-is called. Note that BUFFER is current-buffer when PREDICATE
-is called. (If you call cookie-collect with another buffer set
-as current-buffer and need to access buffer-local variables
-from that buffer within PREDICATE you must send them via
-PREDICATE-ARGS).
-
-If more than two arguments are given to cookie-collect the remaining
-arguments will be passed to PREDICATE.
-
-Use cookie-cookie to get the cookie from the tin."
-
- (cookie-set-buffer buffer
- (let ((tin (dll-nth cookies -2))
- result)
-
- (while (not (eq tin cookie-header))
-
- (if (apply predicate
- (cookie-tin-cookie (dll-element cookies tin))
- predicate-args)
- (setq result (cons tin result)))
-
- (setq tin (dll-previous cookies tin)))
- result)))
-
-
-(defun cookie-collect-cookies (buffer predicate &rest predicate-args)
-
- "Return a list of all cookies in BUFFER that PREDICATE
-returns true for.
-PREDICATE is a function that takes a cookie as its argument.
-The cookie on the returned list will appear in the same order
-as in the buffer. You should not rely on in which order PREDICATE
-is called. Note that BUFFER is current-buffer when PREDICATE
-is called. (If you call cookie-collect with another buffer set
-as current-buffer and need to access buffer-local variables
-from that buffer within PREDICATE you must send them via
-PREDICATE-ARGS).
-
-If more than two arguments are given to cookie-collect the remaining
-arguments will be passed to PREDICATE."
-
- (cookie-set-buffer buffer
- (let ((tin (dll-nth cookies -2))
- result)
-
- (while (not (eq tin cookie-header))
-
- (if (apply predicate
- (cookie-tin-cookie (dll-element cookies tin))
- predicate-args)
- (setq result (cons (cookie-tin-cookie (dll-element cookies tin))
- result)))
-
- (setq tin (dll-previous cookies tin)))
- result)))
diff --git a/gnu/usr.bin/cvs/contrib/pcl-cvs/elib-dll-debug.el b/gnu/usr.bin/cvs/contrib/pcl-cvs/elib-dll-debug.el
deleted file mode 100644
index 733ff86f46c0..000000000000
--- a/gnu/usr.bin/cvs/contrib/pcl-cvs/elib-dll-debug.el
+++ /dev/null
@@ -1,298 +0,0 @@
-;;; elib-dll-debug -- A slow implementation of elib-dll for debugging.
-;;; elib-dll-debug.el,v 1.2 1992/04/07 20:49:13 berliner Exp
-;;; Copyright (C) 1991,1992 Per Cederqvist
-;;;
-;;; This program is free software; you can redistribute it and/or modify
-;;; it under the terms of the GNU General Public License as published by
-;;; the Free Software Foundation; either version 2 of the License, or
-;;; (at your option) any later version.
-;;;
-;;; This program is distributed in the hope that it will be useful,
-;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;;; GNU General Public License for more details.
-;;;
-;;; You should have received a copy of the GNU General Public License
-;;; along with this program; if not, write to the Free Software
-;;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-
-;;; This is a plug-in replacement for elib-dll.el. It is dreadfully
-;;; slow, but it facilitates debugging. Don't trust the comments in
-;;; this file too much.
-(provide 'elib-dll)
-
-;;;
-;;; A doubly linked list consists of one cons cell which holds the tag
-;;; 'DL-LIST in the car cell and the list in the cdr
-;;; cell. The doubly linked list is implemented as a normal list. You
-;;; should use elib-dll.el and not this package in debugged code. This
-;;; package is not written for speed...
-;;;
-
-;;; ================================================================
-;;; Internal functions for use in the doubly linked list package
-
-(defun dll-get-dummy-node (dll)
-
- ;; Return the dummy node. INTERNAL USE ONLY.
- dll)
-
-(defun dll-list-nodes (dll)
-
- ;; Return a list of all nodes in DLL. INTERNAL USE ONLY.
-
- (cdr dll))
-
-(defun dll-set-from-node-list (dll list)
-
- ;; Set the contents of DLL to the nodes in LIST.
- ;; INTERNAL USE ONLY.
-
- (setcdr dll list))
-
-(defun dll-get-node-before (dll node)
- ;; Return the node in DLL that points to NODE. Use
- ;; (dll-get-node-before some-list nil) to get the last node.
- ;; INTERNAL USE ONLY.
- (while (and dll (not (eq (cdr dll) node)))
- (setq dll (cdr dll)))
- (if (not dll)
- (error "Node not on list"))
- dll)
-
-(defmacro dll-insert-after (node element)
- (let ((node-v (make-symbol "node"))
- (element-v (make-symbol "element")))
- (` (let (((, node-v) (, node))
- ((, element-v) (, element)))
- (setcdr (, node-v) (cons (, element-v) (cdr (, node-v))))))))
-
-;;; ===================================================================
-;;; The public functions which operate on doubly linked lists.
-
-(defmacro dll-element (dll node)
-
- "Get the element of a NODE in a doubly linked list DLL.
-Args: DLL NODE."
-
- (` (car (, node))))
-
-
-(defun dll-create ()
- "Create an empty doubly linked list."
- (cons 'DL-LIST nil))
-
-
-(defun dll-p (object)
- "Return t if OBJECT is a doubly linked list, otherwise return nil."
- (eq (car-safe object) 'DL-LIST))
-
-
-(defun dll-enter-first (dll element)
- "Add an element first on a doubly linked list.
-Args: DLL ELEMENT."
- (setcdr dll (cons element (cdr dll))))
-
-
-(defun dll-enter-last (dll element)
- "Add an element last on a doubly linked list.
-Args: DLL ELEMENT."
- (dll-insert-after (dll-get-node-before dll nil) element))
-
-
-(defun dll-enter-after (dll node element)
- "In the doubly linked list DLL, insert a node containing ELEMENT after NODE.
-Args: DLL NODE ELEMENT."
-
- (dll-get-node-before dll node)
- (dll-insert-after node element))
-
-
-(defun dll-enter-before (dll node element)
- "In the doubly linked list DLL, insert a node containing ELEMENT before NODE.
-Args: DLL NODE ELEMENT."
-
- (dll-insert-after (dll-get-node-before dll node) element))
-
-
-
-(defun dll-next (dll node)
- "Return the node after NODE, or nil if NODE is the last node.
-Args: DLL NODE."
-
- (dll-get-node-before dll node)
- (cdr node))
-
-
-(defun dll-previous (dll node)
- "Return the node before NODE, or nil if NODE is the first node.
-Args: DLL NODE."
-
- (dll-get-node-before dll node))
-
-
-(defun dll-delete (dll node)
-
- "Delete NODE from the doubly linked list DLL.
-Args: DLL NODE. Return the element of node."
-
- ;; This is a no-op when applied to the dummy node. This will return
- ;; nil if applied to the dummy node since it always contains nil.
-
- (setcdr (dll-get-node-before dll node) (cdr node)))
-
-
-(defun dll-delete-first (dll)
-
- "Delete the first NODE from the doubly linked list DLL.
-Return the element. Args: DLL. Returns nil if the DLL was empty."
-
- ;; Relies on the fact that dll-delete does nothing and
- ;; returns nil if given the dummy node.
-
- (setcdr dll (cdr (cdr dll))))
-
-
-(defun dll-delete-last (dll)
-
- "Delete the last NODE from the doubly linked list DLL.
-Return the element. Args: DLL. Returns nil if the DLL was empty."
-
- ;; Relies on the fact that dll-delete does nothing and
- ;; returns nil if given the dummy node.
-
- (setcdr dll (dll-get-node-before dll nil) nil))
-
-
-(defun dll-first (dll)
-
- "Return the first element on the doubly linked list DLL.
-Return nil if the list is empty. The element is not removed."
-
- (car (cdr dll)))
-
-
-
-
-(defun dll-last (dll)
-
- "Return the last element on the doubly linked list DLL.
-Return nil if the list is empty. The element is not removed."
-
- (car (dll-get-node-before dll nil)))
-
-
-
-(defun dll-nth (dll n)
-
- "Return the Nth node from the doubly linked list DLL.
- Args: DLL N
-N counts from zero. If DLL is not that long, nil is returned.
-If N is negative, return the -(N+1)th last element.
-Thus, (dll-nth dll 0) returns the first node,
-and (dll-nth dll -1) returns the last node."
-
- ;; Branch 0 ("follow left pointer") is used when n is negative.
- ;; Branch 1 ("follow right pointer") is used otherwise.
-
- (if (>= n 0)
- (nthcdr n (cdr dll))
- (unwind-protect
- (progn (setcdr dll (nreverse (cdr dll)))
- (nthcdr (- n) dll))
- (setcdr dll (nreverse (cdr dll))))))
-
-(defun dll-empty (dll)
-
- "Return t if the doubly linked list DLL is empty, nil otherwise"
-
- (not (cdr dll)))
-
-(defun dll-length (dll)
-
- "Returns the number of elements in the doubly linked list DLL."
-
- (length (cdr dll)))
-
-
-
-(defun dll-copy (dll &optional element-copy-fnc)
-
- "Return a copy of the doubly linked list DLL.
-If optional second argument ELEMENT-COPY-FNC is non-nil it should be
-a function that takes one argument, an element, and returns a copy of it.
-If ELEMENT-COPY-FNC is not given the elements are not copied."
-
- (if element-copy-fnc
- (cons 'DL-LIST (mapcar element-copy-fnc (cdr dll)))
- (copy-sequence dll)))
-
-
-(defun dll-all (dll)
-
- "Return all elements on the double linked list DLL as an ordinary list."
-
- (cdr dll))
-
-
-(defun dll-clear (dll)
-
- "Clear the doubly linked list DLL, i.e. make it completely empty."
-
- (setcdr dll nil))
-
-
-(defun dll-map (map-function dll)
-
- "Apply MAP-FUNCTION to all elements in the doubly linked list DLL.
-The function is applied to the first element first."
-
- (mapcar map-function (cdr dll)))
-
-
-(defun dll-map-reverse (map-function dll)
-
- "Apply MAP-FUNCTION to all elements in the doubly linked list DLL.
-The function is applied to the last element first."
-
- (unwind-protect
- (setcdr dll (nreverse (cdr dll)))
- (mapcar map-function (cdr dll))
- (setcdr dll (nreverse (cdr dll)))))
-
-
-(defun dll-create-from-list (list)
-
- "Given an elisp LIST create a doubly linked list with the same elements."
-
- (cons 'DL-LIST list))
-
-
-
-(defun dll-sort (dll predicate)
-
- "Sort the doubly linked list DLL, stably, comparing elements using PREDICATE.
-Returns the sorted list. DLL is modified by side effects.
-PREDICATE is called with two elements of DLL, and should return T
-if the first element is \"less\" than the second."
-
- (setcdr dll (sort (cdr dll) predicate))
- dll)
-
-
-(defun dll-filter (dll predicate)
-
- "Remove all elements in the doubly linked list DLL for which PREDICATE
-return nil."
-
- (let* ((prev dll)
- (node (cdr dll)))
-
- (while node
- (cond
- ((funcall predicate (car node))
- (setq prev node))
- (t
- (setcdr prev (cdr node))))
- (setq node (cdr node)))))
diff --git a/gnu/usr.bin/cvs/contrib/pcl-cvs/elib-dll.el b/gnu/usr.bin/cvs/contrib/pcl-cvs/elib-dll.el
deleted file mode 100644
index 855bd19e8ee0..000000000000
--- a/gnu/usr.bin/cvs/contrib/pcl-cvs/elib-dll.el
+++ /dev/null
@@ -1,386 +0,0 @@
-;;; elib-dll.el,v 1.2 1992/04/07 20:49:15 berliner Exp
-;;; elib-dll.el -- Some primitives for Doubly linked lists.
-;;; Copyright (C) 1991, 1992 Per Cederqvist
-;;;
-;;; This program is free software; you can redistribute it and/or modify
-;;; it under the terms of the GNU General Public License as published by
-;;; the Free Software Foundation; either version 2 of the License, or
-;;; (at your option) any later version.
-;;;
-;;; This program is distributed in the hope that it will be useful,
-;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;;; GNU General Public License for more details.
-;;;
-;;; You should have received a copy of the GNU General Public License
-;;; along with this program; if not, write to the Free Software
-;;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-;;; Mail bug reports to ceder@lysator.liu.se.
-
-(require 'elib-node)
-(provide 'elib-dll)
-
-;;;
-;;; A doubly linked list consists of one cons cell which holds the tag
-;;; 'DL-LIST in the car cell and a pointer to a dummy node in the cdr
-;;; cell. The doubly linked list is implemented as a circular list
-;;; with the dummy node first and last. The dummy node is recognized
-;;; by comparing it to the node which the cdr of the cons cell points
-;;; to.
-;;;
-
-;;; ================================================================
-;;; Internal functions for use in the doubly linked list package
-
-(defun dll-get-dummy-node (dll)
-
- ;; Return the dummy node. INTERNAL USE ONLY.
- (cdr dll))
-
-(defun dll-list-nodes (dll)
-
- ;; Return a list of all nodes in DLL. INTERNAL USE ONLY.
-
- (let* ((result nil)
- (dummy (dll-get-dummy-node dll))
- (node (elib-node-left dummy)))
-
- (while (not (eq node dummy))
- (setq result (cons node result))
- (setq node (elib-node-left node)))
-
- result))
-
-(defun dll-set-from-node-list (dll list)
-
- ;; Set the contents of DLL to the nodes in LIST.
- ;; INTERNAL USE ONLY.
-
- (dll-clear dll)
- (let* ((dummy (dll-get-dummy-node dll))
- (left dummy))
- (while list
- (elib-node-set-left (car list) left)
- (elib-node-set-right left (car list))
- (setq left (car list))
- (setq list (cdr list)))
-
- (elib-node-set-right left dummy)
- (elib-node-set-left dummy left)))
-
-
-;;; ===================================================================
-;;; The public functions which operate on doubly linked lists.
-
-(defmacro dll-element (dll node)
-
- "Get the element of a NODE in a doubly linked list DLL.
-Args: DLL NODE."
-
- (` (elib-node-data (, node))))
-
-
-(defun dll-create ()
- "Create an empty doubly linked list."
- (let ((dummy-node (elib-node-create nil nil nil)))
- (elib-node-set-right dummy-node dummy-node)
- (elib-node-set-left dummy-node dummy-node)
- (cons 'DL-LIST dummy-node)))
-
-(defun dll-p (object)
- "Return t if OBJECT is a doubly linked list, otherwise return nil."
- (eq (car-safe object) 'DL-LIST))
-
-(defun dll-enter-first (dll element)
- "Add an element first on a doubly linked list.
-Args: DLL ELEMENT."
- (dll-enter-after
- dll
- (dll-get-dummy-node dll)
- element))
-
-
-(defun dll-enter-last (dll element)
- "Add an element last on a doubly linked list.
-Args: DLL ELEMENT."
- (dll-enter-before
- dll
- (dll-get-dummy-node dll)
- element))
-
-
-(defun dll-enter-after (dll node element)
- "In the doubly linked list DLL, insert a node containing ELEMENT after NODE.
-Args: DLL NODE ELEMENT."
-
- (let ((new-node (elib-node-create
- node (elib-node-right node)
- element)))
- (elib-node-set-left (elib-node-right node) new-node)
- (elib-node-set-right node new-node)))
-
-
-(defun dll-enter-before (dll node element)
- "In the doubly linked list DLL, insert a node containing ELEMENT before NODE.
-Args: DLL NODE ELEMENT."
-
- (let ((new-node (elib-node-create
- (elib-node-left node) node
- element)))
- (elib-node-set-right (elib-node-left node) new-node)
- (elib-node-set-left node new-node)))
-
-
-
-(defun dll-next (dll node)
- "Return the node after NODE, or nil if NODE is the last node.
-Args: DLL NODE."
-
- (if (eq (elib-node-right node) (dll-get-dummy-node dll))
- nil
- (elib-node-right node)))
-
-
-(defun dll-previous (dll node)
- "Return the node before NODE, or nil if NODE is the first node.
-Args: DLL NODE."
-
- (if (eq (elib-node-left node) (dll-get-dummy-node dll))
- nil
- (elib-node-left node)))
-
-
-(defun dll-delete (dll node)
-
- "Delete NODE from the doubly linked list DLL.
-Args: DLL NODE. Return the element of node."
-
- ;; This is a no-op when applied to the dummy node. This will return
- ;; nil if applied to the dummy node since it always contains nil.
-
- (elib-node-set-right (elib-node-left node) (elib-node-right node))
- (elib-node-set-left (elib-node-right node) (elib-node-left node))
- (dll-element dll node))
-
-
-
-(defun dll-delete-first (dll)
-
- "Delete the first NODE from the doubly linked list DLL.
-Return the element. Args: DLL. Returns nil if the DLL was empty."
-
- ;; Relies on the fact that dll-delete does nothing and
- ;; returns nil if given the dummy node.
-
- (dll-delete dll (elib-node-right (dll-get-dummy-node dll))))
-
-
-(defun dll-delete-last (dll)
-
- "Delete the last NODE from the doubly linked list DLL.
-Return the element. Args: DLL. Returns nil if the DLL was empty."
-
- ;; Relies on the fact that dll-delete does nothing and
- ;; returns nil if given the dummy node.
-
- (dll-delete dll (elib-node-left (dll-get-dummy-node dll))))
-
-
-(defun dll-first (dll)
-
- "Return the first element on the doubly linked list DLL.
-Return nil if the list is empty. The element is not removed."
-
- (if (eq (elib-node-right (dll-get-dummy-node dll))
- (dll-get-dummy-node dll))
- nil
- (elib-node-data (elib-node-right (dll-get-dummy-node dll)))))
-
-
-
-
-(defun dll-last (dll)
-
- "Return the last element on the doubly linked list DLL.
-Return nil if the list is empty. The element is not removed."
-
- (if (eq (elib-node-left (dll-get-dummy-node dll))
- (dll-get-dummy-node dll))
- nil
- (elib-node-data (elib-node-left (dll-get-dummy-node dll)))))
-
-
-
-(defun dll-nth (dll n)
-
- "Return the Nth node from the doubly linked list DLL.
- Args: DLL N
-N counts from zero. If DLL is not that long, nil is returned.
-If N is negative, return the -(N+1)th last element.
-Thus, (dll-nth dll 0) returns the first node,
-and (dll-nth dll -1) returns the last node."
-
- ;; Branch 0 ("follow left pointer") is used when n is negative.
- ;; Branch 1 ("follow right pointer") is used otherwise.
-
- (let* ((dummy (dll-get-dummy-node dll))
- (branch (if (< n 0) 0 1))
- (node (elib-node-branch dummy branch)))
-
- (if (< n 0)
- (setq n (- -1 n)))
-
- (while (and (not (eq dummy node))
- (> n 0))
- (setq node (elib-node-branch node branch))
- (setq n (1- n)))
-
- (if (eq dummy node)
- nil
- node)))
-
-
-(defun dll-empty (dll)
-
- "Return t if the doubly linked list DLL is empty, nil otherwise"
-
- (eq (elib-node-left (dll-get-dummy-node dll))
- (dll-get-dummy-node dll)))
-
-(defun dll-length (dll)
-
- "Returns the number of elements in the doubly linked list DLL."
-
- (let* ((dummy (dll-get-dummy-node dll))
- (node (elib-node-right dummy))
- (n 0))
-
- (while (not (eq node dummy))
- (setq node (elib-node-right node))
- (setq n (1+ n)))
-
- n))
-
-
-
-(defun dll-copy (dll &optional element-copy-fnc)
-
- "Return a copy of the doubly linked list DLL.
-If optional second argument ELEMENT-COPY-FNC is non-nil it should be
-a function that takes one argument, an element, and returns a copy of it.
-If ELEMENT-COPY-FNC is not given the elements are not copied."
-
- (let ((result (dll-create))
- (node (dll-nth dll 0)))
- (if element-copy-fnc
-
- ;; Copy the elements with the user-supplied function.
- (while node
- (dll-enter-last result
- (funcall element-copy-fnc
- (dll-element dll node)))
- (setq node (dll-next dll node)))
-
- ;; Don't try to copy the elements - they might be
- ;; circular lists, or anything at all...
- (while node
- (dll-enter-last result (dll-element dll node))
- (setq node (dll-next dll node))))
-
- result))
-
-
-
-(defun dll-all (dll)
-
- "Return all elements on the double linked list DLL as an ordinary list."
-
- (let* ((result nil)
- (dummy (dll-get-dummy-node dll))
- (node (elib-node-left dummy)))
-
- (while (not (eq node dummy))
- (setq result (cons (dll-element dll node) result))
- (setq node (elib-node-left node)))
-
- result))
-
-
-(defun dll-clear (dll)
-
- "Clear the doubly linked list DLL, i.e. make it completely empty."
-
- (elib-node-set-left (dll-get-dummy-node dll) (dll-get-dummy-node dll))
- (elib-node-set-right (dll-get-dummy-node dll) (dll-get-dummy-node dll)))
-
-
-(defun dll-map (map-function dll)
-
- "Apply MAP-FUNCTION to all elements in the doubly linked list DLL.
-The function is applied to the first element first."
-
- (let* ((dummy (dll-get-dummy-node dll))
- (node (elib-node-right dummy)))
-
- (while (not (eq node dummy))
- (funcall map-function (dll-element dll node))
- (setq node (elib-node-right node)))))
-
-
-(defun dll-map-reverse (map-function dll)
-
- "Apply MAP-FUNCTION to all elements in the doubly linked list DLL.
-The function is applied to the last element first."
-
- (let* ((dummy (dll-get-dummy-node dll))
- (node (elib-node-left dummy)))
-
- (while (not (eq node dummy))
- (funcall map-function (dll-element dll node))
- (setq node (elib-node-left node)))))
-
-
-(defun dll-create-from-list (list)
-
- "Given an elisp LIST create a doubly linked list with the same elements."
-
- (let ((dll (dll-create)))
- (while list
- (dll-enter-last dll (car list))
- (setq list (cdr list)))
- dll))
-
-
-
-(defun dll-sort (dll predicate)
-
- "Sort the doubly linked list DLL, stably, comparing elements using PREDICATE.
-Returns the sorted list. DLL is modified by side effects.
-PREDICATE is called with two elements of DLL, and should return T
-if the first element is \"less\" than the second."
-
- (dll-set-from-node-list
- dll (sort (dll-list-nodes dll)
- (function (lambda (x1 x2)
- (funcall predicate
- (dll-element dll x1)
- (dll-element dll x2))))))
- dll)
-
-
-(defun dll-filter (dll predicate)
-
- "Remove all elements in the doubly linked list DLL for which PREDICATE
-return nil."
-
- (let* ((dummy (dll-get-dummy-node dll))
- (node (elib-node-right dummy))
- next)
-
- (while (not (eq node dummy))
- (setq next (elib-node-right node))
- (if (funcall predicate (dll-element dll node))
- nil
- (dll-delete dll node))
- (setq node next))))
diff --git a/gnu/usr.bin/cvs/contrib/pcl-cvs/elib-node.el b/gnu/usr.bin/cvs/contrib/pcl-cvs/elib-node.el
deleted file mode 100644
index 6c476a35ef3d..000000000000
--- a/gnu/usr.bin/cvs/contrib/pcl-cvs/elib-node.el
+++ /dev/null
@@ -1,89 +0,0 @@
-;;;; elib-node.el,v 1.2 1992/04/07 20:49:16 berliner Exp
-;;;; This file implements the nodes used in binary trees and
-;;;; doubly linked lists
-;;;;
-;;;; Copyright (C) 1991 Inge Wallin
-;;;;
-;;;; This file is part of the GNU Emacs lisp library, Elib.
-;;;;
-;;;; GNU Elib is free software; you can redistribute it and/or modify
-;;;; it under the terms of the GNU General Public License as published by
-;;;; the Free Software Foundation; either version 1, or (at your option)
-;;;; any later version.
-;;;;
-;;;; GNU Elib is distributed in the hope that it will be useful,
-;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;;;; GNU General Public License for more details.
-;;;;
-;;;; You should have received a copy of the GNU General Public License
-;;;; along with GNU Emacs; see the file COPYING. If not, write to
-;;;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-;;;;
-;;;; Author: Inge Wallin
-;;;;
-
-;;;
-;;; A node is implemented as an array with three elements, using
-;;; (elt node 0) as the left pointer
-;;; (elt node 1) as the right pointer
-;;; (elt node 2) as the data
-;;;
-;;; Some types of trees, e.g. AVL trees, need bigger nodes, but
-;;; as long as the first three parts are the left pointer, the
-;;; right pointer and the data field, these macros can be used.
-;;;
-
-
-(provide 'elib-node)
-
-
-(defmacro elib-node-create (left right data)
- "Create a tree node from LEFT, RIGHT and DATA."
- (` (vector (, left) (, right) (, data))))
-
-
-(defmacro elib-node-left (node)
- "Return the left pointer of NODE."
- (` (aref (, node) 0)))
-
-
-(defmacro elib-node-right (node)
- "Return the right pointer of NODE."
- (` (aref (, node) 1)))
-
-
-(defmacro elib-node-data (node)
- "Return the data of NODE."
- (` (aref (, node) 2)))
-
-
-(defmacro elib-node-set-left (node newleft)
- "Set the left pointer of NODE to NEWLEFT."
- (` (aset (, node) 0 (, newleft))))
-
-
-(defmacro elib-node-set-right (node newright)
- "Set the right pointer of NODE to NEWRIGHT."
- (` (aset (, node) 1 (, newright))))
-
-
-(defmacro elib-node-set-data (node newdata)
- "Set the data of NODE to NEWDATA."
- (` (aset (, node) 2 (, newdata))))
-
-
-
-(defmacro elib-node-branch (node branch)
- "Get value of a branch of a node.
-NODE is the node, and BRANCH is the branch.
-0 for left pointer, 1 for right pointer and 2 for the data."
- (` (aref (, node) (, branch))))
-
-
-(defmacro elib-node-set-branch (node branch newval)
- "Set value of a branch of a node.
-NODE is the node, and BRANCH is the branch.
-0 for left pointer, 1 for the right pointer and 2 for the data.
-NEWVAL is new value of the branch."
- (` (aset (, node) (, branch) (, newval))))
diff --git a/gnu/usr.bin/cvs/contrib/pcl-cvs/pcl-cvs-lucid.el b/gnu/usr.bin/cvs/contrib/pcl-cvs/pcl-cvs-lucid.el
deleted file mode 100644
index d1f69e313d4a..000000000000
--- a/gnu/usr.bin/cvs/contrib/pcl-cvs/pcl-cvs-lucid.el
+++ /dev/null
@@ -1,133 +0,0 @@
-;;; Mouse and font support for PCL-CVS 1.3 running in Lucid GNU Emacs
-;; @(#) Id: pcl-cvs-lucid.el,v 1.2 1993/05/31 19:37:34 ceder Exp
-;; Copyright (C) 1992-1993 Free Software Foundation, Inc.
-
-;; This file is part of GNU Emacs.
-
-;; GNU Emacs is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation; either version 2, or (at your option)
-;; any later version.
-
-;; GNU Emacs is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs; see the file COPYING. If not, write to
-;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
-
-;; This simply adds a menu of the common CVS commands to the menubar and to
-;; the right mouse button. Clicking right moves point, and then pops up a
-;; menu from which commands can be executed.
-;;
-;; This could stand to be a lot more clever: for example, the "Commit Changes"
-;; command should only be active on files for which there is something to
-;; commit. Also, some indication of which files the command applies to
-;; (especially in the presence of multiple marked files) would be nice.
-;;
-;; Middle-click runs find-file.
-
-
-(require 'pcl-cvs)
-
-(defvar cvs-menu
- '("CVS"
- ["Find File" cvs-mode-find-file t]
- ["Find File Other Window" cvs-mode-find-file-other-window t]
- ["Interactively Merge (emerge)" cvs-mode-emerge t]
- ["Diff against Repository" cvs-mode-diff-cvs t]
- ["Diff against Backup Version" cvs-mode-diff-backup t]
- "----"
- ["Commit Changes to Repository" cvs-mode-commit t]
- ["Revert File from Repository" cvs-mode-undo-local-changes t]
- ["Add File to Repository" cvs-mode-add t]
- ["Remove File from Repository" cvs-mode-remove-file t]
- ["Ignore File" cvs-mode-ignore t]
- ["Hide File" cvs-mode-acknowledge t]
- ["Hide Handled Files" cvs-mode-remove-handled t]
- "----"
- ["Add ChangeLog Entry" cvs-mode-add-change-log-entry-other-window t]
- ["Show CVS Log" cvs-mode-log t]
- ["Show CVS Status" cvs-mode-status t]
- "----"
- ["Mark File" cvs-mode-mark t]
- ["Unmark File" cvs-mode-unmark t]
- ["Mark All Files" cvs-mode-mark-all-files t]
- ["Unmark All Files" cvs-mode-unmark-all-files t]
- "----"
- ["Quit" bury-buffer t]
- ))
-
-(defun cvs-menu (e)
- (interactive "e")
- (mouse-set-point e)
- (beginning-of-line)
- (or (looking-at "^[* ] ") (error "No CVS file line here"))
- (popup-menu cvs-menu))
-
-(defun cvs-mouse-find-file (e)
- (interactive "e")
- (mouse-set-point e)
- (beginning-of-line)
- (or (looking-at "^[* ] ") (error "No CVS file line here"))
- (cvs-mode-find-file (point)))
-
-(define-key cvs-mode-map 'button3 'cvs-menu)
-(define-key cvs-mode-map 'button2 'cvs-mouse-find-file)
-
-(make-face 'cvs-header-face)
-(make-face 'cvs-filename-face)
-(make-face 'cvs-status-face)
-
-(or (face-differs-from-default-p 'cvs-header-face)
- (copy-face 'italic 'cvs-header-face))
-
-(or (face-differs-from-default-p 'cvs-filename-face)
- (copy-face 'bold 'cvs-filename-face))
-
-(or (face-differs-from-default-p 'cvs-status-face)
- (copy-face 'bold-italic 'cvs-status-face))
-
-
-(defun pcl-mode-motion-highlight-line (event)
- (if (save-excursion
- (let* ((window (event-window event))
- (buffer (and window (window-buffer window)))
- (point (and buffer (event-point event))))
- (and point
- (progn
- (set-buffer buffer)
- (goto-char point)
- (beginning-of-line)
- (looking-at "^[* ] ")))))
- (mode-motion-highlight-line event)))
-
-(defconst pcl-cvs-font-lock-keywords
- '(("^In directory \\(.+\\)$" 1 cvs-header-face)
- ("^[* ] \\w+ +\\(ci\\)" 1 cvs-status-face)
- ("^[* ] \\(Conflict\\|Merged\\)" 1 cvs-status-face)
- ("^[* ] \\w+ +\\(ci +\\)?\\(.+\\)$" 2 cvs-filename-face)
- )
- "Patterns to highlight in the *cvs* buffer.")
-
-(defun pcl-cvs-fontify ()
- ;;
- ;; set up line highlighting
- (require 'mode-motion)
- (setq mode-motion-hook 'pcl-mode-motion-highlight-line)
- ;;
- ;; set up menubar
- (if (and current-menubar (not (assoc "CVS" current-menubar)))
- (progn
- (set-buffer-menubar (copy-sequence current-menubar))
- (add-menu nil "CVS" (cdr cvs-menu))))
- ;;
- ;; fontify mousable lines
- (set (make-local-variable 'font-lock-keywords) pcl-cvs-font-lock-keywords)
- (font-lock-mode 1)
- )
-
-(add-hook 'cvs-mode-hook 'pcl-cvs-fontify)
diff --git a/gnu/usr.bin/cvs/contrib/pcl-cvs/pcl-cvs-startup.el b/gnu/usr.bin/cvs/contrib/pcl-cvs/pcl-cvs-startup.el
deleted file mode 100644
index f9b2de0418a4..000000000000
--- a/gnu/usr.bin/cvs/contrib/pcl-cvs/pcl-cvs-startup.el
+++ /dev/null
@@ -1,14 +0,0 @@
-;;; @(#) Id: pcl-cvs-startup.el,v 1.4 1993/05/31 18:40:33 ceder Exp
-(autoload 'cvs-update "pcl-cvs"
- "Run a 'cvs update' in the current working directory. Feed the
-output to a *cvs* buffer and run cvs-mode on it.
-If optional prefix argument LOCAL is non-nil, 'cvs update -l' is run."
- t)
-
-(autoload 'cvs-update-other-window "pcl-cvs"
- "Run a 'cvs update' in the current working directory. Feed the
-output to a *cvs* buffer, display it in the other window, and run
-cvs-mode on it.
-
-If optional prefix argument LOCAL is non-nil, 'cvs update -l' is run."
- t)
diff --git a/gnu/usr.bin/cvs/contrib/pcl-cvs/pcl-cvs.el b/gnu/usr.bin/cvs/contrib/pcl-cvs/pcl-cvs.el
deleted file mode 100644
index d9c15d5aa484..000000000000
--- a/gnu/usr.bin/cvs/contrib/pcl-cvs/pcl-cvs.el
+++ /dev/null
@@ -1,2493 +0,0 @@
-;;; @(#) Id: pcl-cvs.el,v 1.93 1993/05/31 22:44:00 ceder Exp
-;;; pcl-cvs.el -- A Front-end to CVS 1.3 or later. Release 1.05.
-;;; Copyright (C) 1991, 1992, 1993 Per Cederqvist
-;;;
-;;; This program is free software; you can redistribute it and/or modify
-;;; it under the terms of the GNU General Public License as published by
-;;; the Free Software Foundation; either version 2 of the License, or
-;;; (at your option) any later version.
-;;;
-;;; This program is distributed in the hope that it will be useful,
-;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;;; GNU General Public License for more details.
-;;;
-;;; You should have received a copy of the GNU General Public License
-;;; along with this program; if not, write to the Free Software
-;;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-;;;; See below for installation instructions.
-;;;;
-;;;; There is an TeXinfo file that describes this package. The GNU
-;;;; General Public License is included in that file. You should read
-;;;; it to get the most from this package.
-
-;;;; Send bug reports and improvements to ceder@lysator.liu.se or
-;;;; ceder@signum.se. Talk some about Signum Support here. +++FIXME
-
-;;; Don't try to use this with CVS 1.2 or earlier. It won't work. Get
-;;; CVS 1.3. This package works together with RCS 5.6 and probably 5.5
-;;; as well.
-
-;;; Mail questions and bug reports to ceder@lysator.liu.se.
-
-(require 'cookie)
-(provide 'pcl-cvs)
-
-;;; -------------------------------------------------------
-;;; START OF THINGS TO CHECK WHEN INSTALLING
-
-(defvar cvs-program "/usr/local/bin/cvs"
- "*Full path to the cvs executable.")
-
-(defvar cvs-diff-program "/usr/local/bin/diff"
- "*Full path to the diff program.")
-
-(defvar cvs-rmdir-program "/bin/rmdir"
- "*Full path to the rmdir program. Typically /bin/rmdir.")
-
-;; Uncomment the following line if you are running on 18.57 or earlier.
-;(setq delete-exited-processes nil)
-;; Emacs version 18.57 and earlier is likely to crash if
-;; delete-exited-processes is t, since the sentinel uses lots of
-;; memory, and 18.57 forgets to GCPROT a variable if
-;; delete-exited-processes is t.
-
-(defvar cvs-shell "/bin/sh"
- "*Full path to a shell that can do redirection on stdout.")
-
-;;; END OF THINGS TO CHECK WHEN INSTALLING
-;;; --------------------------------------------------------
-
-(defvar cvs-cvsroot nil
- "*Specifies where the (current) cvs master repository is.
-Overrides the $CVSROOT variable by sending \" -d dir\" to all cvs commands.
-This switch is useful if you have multiple CVS repositories.")
-
-(defvar cvs-cvsroot-required t
- "*Specifies whether CVS needs to be told where the repository is.
-
-In CVS 1.3, if your CVSROOT environment variable is not set, and you
-do not set the `cvs-cvsroot' lisp variable, CVS will have no idea
-where to find the repository, and refuse to run. CVS 1.4 and later
-store the repository path with the working directories, so most
-operations don't need to be told where the repository is.
-
-If you work with multiple repositories with CVS 1.4, it's probably
-advisable to leave your CVSROOT environment variable unset, set this
-variable to nil, and let CVS figure out where the repository is for
-itself.")
-
-(defvar cvs-stdout-file nil
- "Name of the file that holds the output that CVS sends to stdout.
-This variable is buffer local.")
-
-(defvar cvs-lock-file nil
- "Full path to a lock file that CVS is waiting for (or was waiting for).")
-
-(defvar cvs-bakprefix ".#"
- "The prefix that CVS prepends to files when rcsmerge'ing.")
-
-(defvar cvs-erase-input-buffer nil
- "*Non-nil if input buffers should be cleared before asking for new info.")
-
-(defvar cvs-auto-remove-handled nil
- "*Non-nil if cvs-mode-remove-handled should be called automatically.
-If this is set to any non-nil value entries that does not need to be
-checked in will be removed from the *cvs* buffer after every cvs-mode-commit
-command.")
-
-(defvar cvs-sort-ignore-file t
- "*Non-nil if cvs-mode-ignore should sort the .cvsignore automatically.")
-
-(defvar cvs-auto-revert-after-commit t
- "*Non-nil if committed buffers should be automatically reverted.")
-
-(defconst cvs-cursor-column 14
- "Column to position cursor in in cvs-mode.
-Column 0 is left-most column.")
-
-(defvar cvs-mode-map nil
- "Keymap for the cvs mode.")
-
-(defvar cvs-edit-mode-map nil
- "Keymap for the cvs edit mode (used when editing cvs log messages).")
-
-(defvar cvs-buffer-name "*cvs*"
- "Name of the cvs buffer.")
-
-(defvar cvs-commit-prompt-buffer "*cvs-commit-message*"
- "Name of buffer in which the user is prompted for a log message when
-committing files.")
-
-(defvar cvs-commit-buffer-require-final-newline t
- "*t says silently put a newline at the end of commit log messages.
-Non-nil but not t says ask user whether to add a newline in each such case.
-nil means don't add newlines.")
-
-(defvar cvs-temp-buffer-name "*cvs-tmp*"
- "*Name of the cvs temporary buffer.
-Output from cvs is placed here by synchronous commands.")
-
-(defvar cvs-diff-ignore-marks nil
- "*Non-nil if cvs-diff and cvs-mode-diff-backup should ignore any marked files.
-Normally they run diff on the files that are marked (with cvs-mode-mark),
-or the file under the cursor if no files are marked. If this variable
-is set to a non-nil value they will always run diff on the file on the
-current line.")
-
-(defvar cvs-status-flags nil
- "*List of strings to pass to ``cvs status''.")
-
-(defvar cvs-log-flags nil
- "*List of strings to pass to ``cvs log''.")
-
-(defvar cvs-diff-flags nil
- "*List of strings to use as flags to pass to ``diff'' and ``cvs diff''.
-Used by cvs-mode-diff-cvs and cvs-mode-diff-backup.
-Set this to '(\"-u\") to get a Unidiff format, or '(\"-c\") to get context diffs.")
-
-(defvar cvs-update-prog-output-skip-regexp "$"
- "*A regexp that matches the end of the output from all cvs update programs.
-That is, output from any programs that are run by CVS (by the flag -u
-in the `modules' file - see cvs(5)) when `cvs update' is performed should
-terminate with a line that this regexp matches. It is enough that
-some part of the line is matched.
-
-The default (a single $) fits programs without output.")
-
-;; The variables below are used internally by pcl-cvs. You should
-;; never change them.
-
-(defvar cvs-buffers-to-delete nil
- "List of temporary buffers that should be discarded as soon as possible.
-Due to a bug in emacs 18.57 the sentinel can't discard them reliably.")
-
-;; You are NOT allowed to disable this message by default. However, you
-;; are encouraged to inform your users that by adding
-;; (setq cvs-inhibit-copyright-message t)
-;; to their .emacs they can get rid of it. Just don't add that line
-;; to your default.el!
-(defvar cvs-inhibit-copyright-message nil
- "*Non-nil means don't display a Copyright message in the ``*cvs*'' buffer.")
-
-(defconst pcl-cvs-version "1.05"
- "A string denoting the current release version of pcl-cvs.")
-
-(defconst cvs-startup-message
- (if cvs-inhibit-copyright-message
- "PCL-CVS release 1.05"
- "PCL-CVS release 1.05. Copyright (C) 1992, 1993 Per Cederqvist
-Pcl-cvs comes with absolutely no warranty; for details consult the manual.
-This is free software, and you are welcome to redistribute it under certain
-conditions; again, consult the TeXinfo manual for details.")
- "*Startup message for CVS.")
-
-(defvar cvs-update-running nil
- "This is set to nil when no process is running, and to
-the process when a cvs update process is running.")
-
-(defvar cvs-cookie-handle nil
- "Handle for the cookie structure that is displayed in the *cvs* buffer.")
-
-(defvar cvs-mode-commit nil
- "Used internally by pcl-cvs.")
-
-;;; The cvs data structure:
-;;;
-;;; When the `cvs update' is ready we parse the output. Every file
-;;; that is affected in some way is added as a cookie of fileinfo
-;;; (as defined below).
-;;;
-
-;;; cvs-fileinfo
-;;;
-;;; marked t/nil
-;;; type One of
-;;; UPDATED - file copied from repository
-;;; MODIFIED - modified by you, unchanged in
-;;; repository
-;;; ADDED - added by you, not yet committed
-;;; REMOVED - removed by you, not yet committed
-;;; CVS-REMOVED- removed, since file no longer exists
-;;; in the repository.
-;;; MERGED - successful merge
-;;; CONFLICT - conflict when merging
-;;; REM-CONFLICT-removed in repository, changed locally.
-;;; MOD-CONFLICT-removed locally, changed in repository.
-;;; REM-EXIST -removed locally, but still exists.
-;;; DIRCHANGE - A change of directory.
-;;; UNKNOWN - An unknown file.
-;;; MOVE-AWAY - A file that is in the way.
-;;; REPOS-MISSING- The directory is removed from the
-;;; repository. Go fetch a backup.
-;;; MESSAGE - This is a special fileinfo that is used
-;;; to display a text that should be in
-;;; full-log.
-;;; dir Directory the file resides in. Should not end with
-;;; slash.
-;;; file-name The file name.
-;;; base-revision The revision that the working file was based on.
-;;; Only valid for MERGED and CONFLICT files.
-;;; cvs-diff-buffer A buffer that contains a 'cvs diff file'.
-;;; backup-diff-buffer A buffer that contains a 'diff file backup-file'.
-;;; full-log The output from cvs, unparsed.
-;;; mod-time Modification time of file used for *-diff-buffer.
-;;; handled True if this file doesn't require further action.
-;;;
-;;; Constructor:
-
-;;; cvs-fileinfo
-
-;;; Constructor:
-
-(defun cvs-create-fileinfo (type
- dir
- file-name
- full-log)
- "Create a fileinfo from all parameters.
-Arguments: TYPE DIR FILE-NAME FULL-LOG.
-A fileinfo has the following fields:
-
- marked t/nil
- type One of
- UPDATED - file copied from repository
- MODIFIED - modified by you, unchanged in
- repository
- ADDED - added by you, not yet committed
- REMOVED - removed by you, not yet committed
- CVS-REMOVED- removed, since file no longer exists
- in the repository.
- MERGED - successful merge
- CONFLICT - conflict when merging
- REM-CONFLICT-removed in repository, but altered
- locally.
- MOD-CONFLICT-removed locally, changed in repository.
- REM-EXIST - removed locally, but still exists.
- DIRCHANGE - A change of directory.
- UNKNOWN - An unknown file.
- MOVE-AWAY - A file that is in the way.
- REPOS-MISSING- The directory has vanished from the
- repository.
- MESSAGE - This is a special fileinfo that is used
- to display a text that should be in
- full-log.
- dir Directory the file resides in. Should not end with slash.
- file-name The file name.
- backup-file Name of the backup file if MERGED or CONFLICT.
- cvs-diff-buffer A buffer that contains a 'cvs diff file'.
- backup-diff-buffer A buffer that contains a 'diff file backup-file'.
- full-log The output from cvs, unparsed.
- mod-time Modification time of file used for *-diff-buffer.
- handled True if this file doesn't require further action."
- (cons
- 'CVS-FILEINFO
- (vector nil nil type dir file-name nil nil nil full-log nil)))
-
-
-;;; Selectors:
-
-(defun cvs-fileinfo->handled (cvs-fileinfo)
- "Get the `handled' field from CVS-FILEINFO."
- (elt (cdr cvs-fileinfo) 0))
-
-(defun cvs-fileinfo->marked (cvs-fileinfo)
- "Check if CVS-FILEINFO is marked."
- (elt (cdr cvs-fileinfo) 1))
-
-(defun cvs-fileinfo->type (cvs-fileinfo)
- "Get type from CVS-FILEINFO.
-Type is one of UPDATED, MODIFIED, ADDED, REMOVED, CVS-REMOVED, MERGED,
-CONFLICT, REM-CONFLICT, MOD-CONFLICT, REM-EXIST, DIRCHANGE, UNKNOWN, MOVE-AWAY,
-REPOS-MISSING or MESSAGE."
- (elt (cdr cvs-fileinfo) 2))
-
-(defun cvs-fileinfo->dir (cvs-fileinfo)
- "Get dir from CVS-FILEINFO.
-The directory name does not end with a slash. "
- (elt (cdr cvs-fileinfo) 3))
-
-(defun cvs-fileinfo->file-name (cvs-fileinfo)
- "Get file-name from CVS-FILEINFO."
- (elt (cdr cvs-fileinfo) 4))
-
-(defun cvs-fileinfo->base-revision (cvs-fileinfo)
- "Get the base revision from CVS-FILEINFO."
- (elt (cdr cvs-fileinfo) 5))
-
-(defun cvs-fileinfo->cvs-diff-buffer (cvs-fileinfo)
- "Get cvs-diff-buffer from CVS-FILEINFO."
- (elt (cdr cvs-fileinfo) 6))
-
-(defun cvs-fileinfo->backup-diff-buffer (cvs-fileinfo)
- "Get backup-diff-buffer from CVS-FILEINFO."
- (elt (cdr cvs-fileinfo) 7))
-
-(defun cvs-fileinfo->full-log (cvs-fileinfo)
- "Get full-log from CVS-FILEINFO."
- (elt (cdr cvs-fileinfo) 8))
-
-(defun cvs-fileinfo->mod-time (cvs-fileinfo)
- "Get mod-time from CVS-FILEINFO."
- (elt (cdr cvs-fileinfo) 9))
-
-;;; Modifiers:
-
-(defun cvs-set-fileinfo->handled (cvs-fileinfo newval)
- "Set handled in CVS-FILEINFO to NEWVAL."
- (aset (cdr cvs-fileinfo) 0 newval))
-
-(defun cvs-set-fileinfo->marked (cvs-fileinfo newval)
- "Set marked in CVS-FILEINFO to NEWVAL."
- (aset (cdr cvs-fileinfo) 1 newval))
-
-(defun cvs-set-fileinfo->type (cvs-fileinfo newval)
- "Set type in CVS-FILEINFO to NEWVAL."
- (aset (cdr cvs-fileinfo) 2 newval))
-
-(defun cvs-set-fileinfo->dir (cvs-fileinfo newval)
- "Set dir in CVS-FILEINFO to NEWVAL.
-The directory should now end with a slash."
- (aset (cdr cvs-fileinfo) 3 newval))
-
-(defun cvs-set-fileinfo->file-name (cvs-fileinfo newval)
- "Set file-name in CVS-FILEINFO to NEWVAL."
- (aset (cdr cvs-fileinfo) 4 newval))
-
-(defun cvs-set-fileinfo->base-revision (cvs-fileinfo newval)
- "Set base-revision in CVS-FILEINFO to NEWVAL."
- (aset (cdr cvs-fileinfo) 5 newval))
-
-(defun cvs-set-fileinfo->cvs-diff-buffer (cvs-fileinfo newval)
- "Set cvs-diff-buffer in CVS-FILEINFO to NEWVAL."
- (aset (cdr cvs-fileinfo) 6 newval))
-
-(defun cvs-set-fileinfo->backup-diff-buffer (cvs-fileinfo newval)
- "Set backup-diff-buffer in CVS-FILEINFO to NEWVAL."
- (aset (cdr cvs-fileinfo) 7 newval))
-
-(defun cvs-set-fileinfo->full-log (cvs-fileinfo newval)
- "Set full-log in CVS-FILEINFO to NEWVAL."
- (aset (cdr cvs-fileinfo) 8 newval))
-
-(defun cvs-set-fileinfo->mod-time (cvs-fileinfo newval)
- "Set full-log in CVS-FILEINFO to NEWVAL."
- (aset (cdr cvs-fileinfo) 9 newval))
-
-
-
-;;; Predicate:
-
-(defun cvs-fileinfo-p (object)
- "Return t if OBJECT is a cvs-fileinfo."
- (eq (car-safe object) 'CVS-FILEINFO))
-
-;;;; End of types.
-
-(defun cvs-use-temp-buffer ()
- "Display a temporary buffer in another window and select it.
-The selected window will not be changed. The temporary buffer will
-be erased and writable."
-
- (let ((dir default-directory))
- (display-buffer (get-buffer-create cvs-temp-buffer-name))
- (set-buffer cvs-temp-buffer-name)
- (setq buffer-read-only nil)
- (setq default-directory dir)
- (erase-buffer)))
-
-; Too complicated to handle all the cases that are generated.
-; Maybe later.
-;(defun cvs-examine (directory &optional local)
-; "Run a 'cvs -n update' in the current working directory.
-;That is, check what needs to be done, but don't change the disc.
-;Feed the output to a *cvs* buffer and run cvs-mode on it.
-;If optional prefix argument LOCAL is non-nil, 'cvs update -l' is run."
-; (interactive (list (read-file-name "CVS Update (directory): "
-; nil default-directory nil)
-; current-prefix-arg))
-; (cvs-do-update directory local 'noupdate))
-
-(defun cvs-update (directory &optional local)
- "Run a 'cvs update' in the current working directory. Feed the
-output to a *cvs* buffer and run cvs-mode on it.
-If optional prefix argument LOCAL is non-nil, 'cvs update -l' is run."
- (interactive (list (read-file-name "CVS Update (directory): "
- nil default-directory nil)
- current-prefix-arg))
- (cvs-do-update directory local nil)
- (switch-to-buffer cvs-buffer-name))
-
-(defun cvs-update-other-window (directory &optional local)
- "Run a 'cvs update' in the current working directory. Feed the
-output to a *cvs* buffer, display it in the other window, and run
-cvs-mode on it.
-
-If optional prefix argument LOCAL is non-nil, 'cvs update -l' is run."
- (interactive (list (read-file-name "CVS Update other window (directory): "
- nil default-directory nil)
- current-prefix-arg))
- (cvs-do-update directory local nil)
- (switch-to-buffer-other-window cvs-buffer-name))
-
-(defun cvs-filter (predicate list &rest extra-args)
- "Apply PREDICATE to each element on LIST.
-Args: PREDICATE LIST &rest EXTRA-ARGS.
-Return a new list consisting of those elements that PREDICATE
-returns non-nil for.
-
-If more than two arguments are given the remaining args are
-passed to PREDICATE."
- ;; Avoid recursion - this should work for LONG lists also!
- (let* ((head (cons 'dummy-header nil))
- (tail head))
- (while list
- (if (apply predicate (car list) extra-args)
- (setq tail (setcdr tail (list (car list)))))
- (setq list (cdr list)))
- (cdr head)))
-
-(defun cvs-mode-update-no-prompt ()
- "Run cvs update in current directory."
- (interactive)
- (cvs-do-update default-directory nil nil))
-
-(defun cvs-do-update (directory local dont-change-disc)
- "Do a 'cvs update' in DIRECTORY.
-Args: DIRECTORY LOCAL DONT-CHANGE-DISC &optional NOTTHISWINDOW.
-If LOCAL is non-nil 'cvs update -l' is executed.
-If DONT-CHANGE-DISC is non-nil 'cvs -n update' is executed.
-Both LOCAL and DONT-CHANGE-DISC may be non-nil simultaneously.
-
-*Note*: DONT-CHANGE-DISC does not yet work. The parser gets confused."
- (save-some-buffers)
- (if (not (file-exists-p cvs-program))
- (error "%s: file not found (check setting of cvs-program)"
- cvs-program))
- (if (and cvs-cvsroot-required
- (not (or (getenv "CVSROOT") cvs-cvsroot)))
- (error "Both cvs-cvsroot and environment variable CVSROOT unset."))
- (let* ((this-dir (file-name-as-directory (expand-file-name directory)))
- (update-buffer (generate-new-buffer
- (concat (file-name-nondirectory
- (substring this-dir 0 -1))
- "-update")))
- (temp-name (make-temp-name
- (concat (file-name-as-directory
- (or (getenv "TMPDIR") "/tmp"))
- "pcl-cvs.")))
- (args nil))
-
- ;; Check that this-dir exists and is a directory that is under CVS contr.
-
- (if (not (file-directory-p this-dir))
- (error "%s is not a directory." this-dir))
- (if (not (file-directory-p (concat this-dir "CVS")))
- (error "%s does not contain CVS controlled files." this-dir))
-
- ;; Check that at most one `cvs update' is run at any time.
-
- (if (and cvs-update-running (process-status cvs-update-running)
- (or (eq (process-status cvs-update-running) 'run)
- (eq (process-status cvs-update-running) 'stop)))
- (error "Can't run two `cvs update' simultaneously."))
-
- ;; Generate "-d /master -n update -l".
- (setq args (concat (if cvs-cvsroot (concat " -d " cvs-cvsroot))
- (if dont-change-disc " -n ")
- " update "
- (if local " -l ")))
-
- ;; Set up the buffer that receives the stderr output from "cvs update".
- (set-buffer update-buffer)
- (setq default-directory this-dir)
- (make-local-variable 'cvs-stdout-file)
- (setq cvs-stdout-file temp-name)
-
- (setq cvs-update-running
- (let ((process-connection-type nil)) ; Use a pipe, not a pty.
- (start-process "cvs" update-buffer cvs-shell "-c"
- (concat cvs-program " " args " > " temp-name))))
-
- (setq mode-line-process
- (concat ": "
- (symbol-name (process-status cvs-update-running))))
- (set-buffer-modified-p (buffer-modified-p)) ; Update the mode line.
- (set-process-sentinel cvs-update-running 'cvs-sentinel)
- (set-process-filter cvs-update-running 'cvs-update-filter)
- (set-marker (process-mark cvs-update-running) (point-min))
-
- (save-excursion
- (set-buffer (get-buffer-create cvs-buffer-name))
- (setq buffer-read-only nil)
- (erase-buffer)
- (cvs-mode))
-
- (setq cvs-cookie-handle
- (collection-create
- cvs-buffer-name 'cvs-pp
- cvs-startup-message ;Se comment above cvs-startup-message.
- "---------- End -----"))
-
- (cookie-enter-first
- cvs-cookie-handle
- (cvs-create-fileinfo
- 'MESSAGE nil nil (concat "\n Running `cvs " args "' in " this-dir
- "...\n")))
-
- (save-excursion
- (set-buffer cvs-buffer-name)
- (setq mode-line-process
- (concat ": "
- (symbol-name (process-status cvs-update-running))))
- (set-buffer-modified-p (buffer-modified-p)) ; Update the mode line.
- (setq buffer-read-only t))
-
- ;; Work around a bug in emacs 18.57 and earlier.
- (setq cvs-buffers-to-delete
- (cvs-delete-unused-temporary-buffers cvs-buffers-to-delete)))
-
- ;; The following line is said to improve display updates on some
- ;; emacses. It shouldn't be needed, but it does no harm.
- (sit-for 0))
-
-
-(defun cvs-delete-unused-temporary-buffers (list)
- "Delete all buffers on LIST that is not visible.
-Return a list of all buffers that still is alive."
-
- (cond
- ((null list) nil)
- ((get-buffer-window (car list))
- (cons (car list)
- (cvs-delete-unused-temporary-buffers (cdr list))))
- (t
- (kill-buffer (car list))
- (cvs-delete-unused-temporary-buffers (cdr list)))))
-
-
-(put 'cvs-mode 'mode-class 'special)
-
-(defun cvs-mode ()
- "\\<cvs-mode-map>Mode used for pcl-cvs, a frontend to CVS.
-
-To get the *cvs* buffer you should use ``\\[cvs-update]''.
-
-Full documentation is in the Texinfo file. These are the most useful commands:
-
-\\[cvs-mode-previous-line] Move up. \\[cvs-mode-next-line] Move down.
-\\[cvs-mode-commit] Commit file. \\[cvs-mode-update-no-prompt] Reupdate directory.
-\\[cvs-mode-mark] Mark file/dir. \\[cvs-mode-unmark] Unmark file/dir.
-\\[cvs-mode-mark-all-files] Mark all files. \\[cvs-mode-unmark-all-files] Unmark all files.
-\\[cvs-mode-find-file] Edit file/run Dired. \\[cvs-mode-find-file-other-window] Find file or run Dired in other window.
-\\[cvs-mode-remove-handled] Remove processed entries. \\[cvs-mode-add-change-log-entry-other-window] Write ChangeLog in other window.
-\\[cvs-mode-add] Add to repository. \\[cvs-mode-remove-file] Remove file.
-\\[cvs-mode-diff-cvs] Diff between base revision. \\[cvs-mode-diff-backup] Diff backup file.
-\\[cvs-mode-emerge] Run emerge on base revision/backup file.
-\\[cvs-mode-acknowledge] Delete line from buffer. \\[cvs-mode-ignore] Add file to the .cvsignore file.
-\\[cvs-mode-log] Run ``cvs log''. \\[cvs-mode-status] Run ``cvs status''.
-\\[cvs-mode-changelog-commit] Like \\[cvs-mode-commit], but get default log text from ChangeLog.
-\\[cvs-mode-undo-local-changes] Revert the last checked in version - discard your changes to the file.
-
-Entry to this mode runs cvs-mode-hook.
-This description is updated for release 1.05 of pcl-cvs.
-
-All bindings:
-\\{cvs-mode-map}"
- (interactive)
- (setq major-mode 'cvs-mode)
- (setq mode-name "CVS")
- (setq mode-line-process nil)
- (buffer-flush-undo (current-buffer))
- (make-local-variable 'goal-column)
- (setq goal-column cvs-cursor-column)
- (use-local-map cvs-mode-map)
- (run-hooks 'cvs-mode-hook))
-
-(defun cvs-sentinel (proc msg)
- "Sentinel for the cvs update process.
-This is responsible for parsing the output from the cvs update when
-it is finished."
- (cond
- ((null (buffer-name (process-buffer proc)))
- ;; buffer killed
- (set-process-buffer proc nil))
- ((memq (process-status proc) '(signal exit))
- (let* ((obuf (current-buffer))
- (omax (point-max))
- (opoint (point)))
- ;; save-excursion isn't the right thing if
- ;; process-buffer is current-buffer
- (unwind-protect
- (progn
- (set-buffer (process-buffer proc))
- (setq mode-line-process
- (concat ": "
- (symbol-name (process-status proc))))
- (let* ((out-file cvs-stdout-file)
- (stdout-buffer (find-file-noselect out-file)))
- (cvs-parse-update stdout-buffer (process-buffer proc))
- (setq cvs-buffers-to-delete
- (cons (process-buffer proc)
- (cons stdout-buffer
- cvs-buffers-to-delete)))
- (delete-file out-file)))
- (set-buffer-modified-p (buffer-modified-p))
- (setq cvs-update-running nil))
- (if (equal obuf (process-buffer proc))
- nil
- (set-buffer (process-buffer proc))
- (if (< opoint omax)
- (goto-char opoint))
- (set-buffer obuf))))))
-
-(defun cvs-update-filter (proc string)
- "Filter function for pcl-cvs.
-This function gets the output that CVS sends to stderr. It inserts it
-into (process-buffer proc) but it also checks if CVS is waiting for a
-lock file. If so, it inserts a message cookie in the *cvs* buffer."
- (let ((old-buffer (current-buffer))
- (data (match-data)))
- (unwind-protect
- (progn
- (set-buffer (process-buffer proc))
- (save-excursion
- ;; Insert the text, moving the process-marker.
- (goto-char (process-mark proc))
- (insert string)
- (set-marker (process-mark proc) (point))
- ;; Delete any old lock message
- (if (tin-nth cvs-cookie-handle 1)
- (tin-delete cvs-cookie-handle
- (tin-nth cvs-cookie-handle 1)))
- ;; Check if CVS is waiting for a lock.
- (beginning-of-line 0) ;Move to beginning of last
- ;complete line.
- (cond
- ((looking-at
- "^cvs update: \\[..:..:..\\] waiting \
-for \\(.*\\)lock in \\(.*\\)$")
- (setq cvs-lock-file (buffer-substring (match-beginning 2)
- (match-end 2)))
- (cookie-enter-last
- cvs-cookie-handle
- (cvs-create-fileinfo
- 'MESSAGE nil nil
- (concat "\tWaiting for "
- (buffer-substring (match-beginning 1)
- (match-end 1))
- "lock in " cvs-lock-file
- ".\n\t (type M-x cvs-delete-lock to delete it)")))))))
- (store-match-data data)
- (set-buffer old-buffer))))
-
-(defun cvs-delete-lock ()
- "Delete the lock file that CVS is waiting for.
-Note that this can be dangerous. You should only do this
-if you are convinced that the process that created the lock is dead."
- (interactive)
- (cond
- ((not (or (file-exists-p
- (concat (file-name-as-directory cvs-lock-file) "#cvs.lock"))
- (cvs-filter (function cvs-lock-file-p)
- (directory-files cvs-lock-file))))
- (error "No lock files found."))
- ((yes-or-no-p (concat "Really delete locks in " cvs-lock-file "? "))
- ;; Re-read the directory -- the locks might have disappeared.
- (let ((locks (cvs-filter (function cvs-lock-file-p)
- (directory-files cvs-lock-file))))
- (while locks
- (delete-file (concat (file-name-as-directory cvs-lock-file)
- (car locks)))
- (setq locks (cdr locks)))
- (cvs-remove-directory
- (concat (file-name-as-directory cvs-lock-file) "#cvs.lock"))))))
-
-(defun cvs-remove-directory (dir)
- "Remove a directory."
- (if (file-directory-p dir)
- (call-process cvs-rmdir-program nil nil nil dir)
- (error "Not a directory: %s" dir))
- (if (file-exists-p dir)
- (error "Could not remove directory %s" dir)))
-
-(defun cvs-lock-file-p (file)
- "Return true if FILE looks like a CVS lock file."
- (or
- (string-match "^#cvs.tfl.[0-9]+$" file)
- (string-match "^#cvs.rfl.[0-9]+$" file)
- (string-match "^#cvs.wfl.[0-9]+$" file)))
-
-(defun cvs-skip-line (stdout stderr regexp &optional arg)
- "Like forward-line, but check that the skipped line matches REGEXP.
-Args: STDOUT STDERR REGEXP &optional ARG.
-
-If it doesn't match REGEXP a bug report is generated and displayed.
-STDOUT and STDERR is only used to do that.
-
-If optional ARG, a number, is given the ARGth parenthesized expression
-in the REGEXP is returned as a string.
-Point should be in column 1 when this function is called."
- (cond
- ((looking-at regexp)
- (forward-line 1)
- (if arg
- (buffer-substring (match-beginning arg)
- (match-end arg))))
- (t
- (cvs-parse-error stdout stderr
- (if (eq (current-buffer) stdout) 'STDOUT 'STDERR)
- (point)))))
-
-(defun cvs-get-current-dir (root-dir dirname)
- "Return current working directory, suitable for cvs-parse-update.
-Args: ROOT-DIR DIRNAME.
-Concatenates ROOT-DIR and DIRNAME to form an absolute path."
- (if (string= "." dirname)
- (substring root-dir 0 -1)
- (concat root-dir dirname)))
-
-(defun cvs-compare-fileinfos (a b)
- "Compare fileinfo A with fileinfo B and return t if A is `less'."
- (cond
- ;; Sort acording to directories.
- ((string< (cvs-fileinfo->dir a) (cvs-fileinfo->dir b)) t)
- ((not (string= (cvs-fileinfo->dir a) (cvs-fileinfo->dir b))) nil)
-
- ;; The DIRCHANGE entry is always first within the directory.
- ((and (eq (cvs-fileinfo->type a) 'DIRCHANGE)
- (not (eq (cvs-fileinfo->type b) 'DIRCHANGE))) t)
- ((and (eq (cvs-fileinfo->type b) 'DIRCHANGE)
- (not (eq (cvs-fileinfo->type a) 'DIRCHANGE))) nil)
- ;; All files are sorted by file name.
- ((string< (cvs-fileinfo->file-name a) (cvs-fileinfo->file-name b)))))
-
-(defun cvs-parse-error (stdout-buffer stderr-buffer err-buf pos)
- "Handle a parse error when parsing the output from cvs.
-Args: STDOUT-BUFFER STDERR-BUFFER ERR-BUF POS.
-ERR-BUF should be 'STDOUT or 'STDERR."
- (setq pos (1- pos))
- (set-buffer cvs-buffer-name)
- (setq buffer-read-only nil)
- (erase-buffer)
- (insert "To: ceder@lysator.liu.se\n")
- (insert "Subject: pcl-cvs " pcl-cvs-version " parse error.\n")
- (insert "--text follows this line--\n\n")
- (insert "This bug report is automatically generated by pcl-cvs\n")
- (insert "because it doesn't understand some output from CVS. Below\n")
- (insert "is detailed information about the error. Please send\n")
- (insert "this, together with any information you think might be\n")
- (insert "useful for me to fix the bug, to the address above. But\n")
- (insert "please check the \"known problems\" section of the\n")
- (insert "documentation first. Note that this buffer contains\n")
- (insert "information that you might consider confidential. You\n")
- (insert "are encouraged to read through it before sending it.\n")
- (insert "\n")
- (insert "Press C-c C-c to send this email.\n\n")
- (insert "Please state the version of these programs you are using:\n")
- (insert "RCS: \ndiff: \n\n")
-
- (let* ((stdout (save-excursion (set-buffer stdout-buffer) (buffer-string)))
- (stderr (save-excursion (set-buffer stderr-buffer) (buffer-string)))
- (errstr (if (eq err-buf 'STDOUT) stdout stderr))
- (errline-end (string-match "\n" errstr pos))
- (errline (substring errstr pos errline-end)))
- (insert (format "Offending line (%d chars): >" (- errline-end pos)))
- (insert errline)
- (insert "<\n")
- (insert "Sent to " (symbol-name err-buf) " at pos " (format "%d\n" pos))
- (insert "Emacs-version: " (emacs-version) "\n")
- (insert "Pcl-cvs $" "Id:" "$" ": " "Id: pcl-cvs.el,v 1.93 1993/05/31 22:44:00 ceder Exp \n")
- (insert "\n")
- (insert (format "--- Contents of stdout buffer (%d chars) ---\n"
- (length stdout)))
- (insert stdout)
- (insert "--- End of stdout buffer ---\n")
- (insert (format "--- Contents of stderr buffer (%d chars) ---\n"
- (length stderr)))
- (insert stderr)
- (insert "--- End of stderr buffer ---\n")
- (insert "End of bug report.\n")
- (require 'sendmail)
- (mail-mode)
- (error "CVS parse error - please report this bug.")))
-
-(defun cvs-parse-update (stdout-buffer stderr-buffer)
- "Parse the output from `cvs update'.
-
-Args: STDOUT-BUFFER STDERR-BUFFER.
-
-This functions parses the from `cvs update' (which should be
-separated in its stdout- and stderr-components) and prints a
-pretty representation of it in the *cvs* buffer.
-
-Signals an error if unexpected output was detected in the buffer."
- (let* ((head (cons 'dummy nil))
- (tail (cvs-parse-stderr stdout-buffer stderr-buffer
- head default-directory))
- (root-dir default-directory))
- (cvs-parse-stdout stdout-buffer stderr-buffer tail root-dir)
- (setq head (sort (cdr head) (function cvs-compare-fileinfos)))
-
- (collection-clear cvs-cookie-handle)
- (collection-append-cookies cvs-cookie-handle head)
- (cvs-remove-stdout-shadows)
- (cvs-remove-empty-directories)
- (set-buffer cvs-buffer-name)
- (cvs-mode)
- (goto-char (point-min))
- (tin-goto-previous cvs-cookie-handle (point-min) 1)
- (setq default-directory root-dir)))
-
-(defun cvs-remove-stdout-shadows ()
- "Remove entries in the *cvs* buffer that comes from both stdout and stderr.
-If there is two entries for a single file the second one should be
-deleted. (Remember that sort uses a stable sort algorithm, so one can
-be sure that the stderr entry is always first)."
- (collection-filter-tins cvs-cookie-handle
- (function
- (lambda (tin)
- (not (cvs-shadow-entry-p tin))))))
-
-(defun cvs-shadow-entry-p (tin)
- "Return non-nil if TIN is a shadow entry.
-Args: TIN.
-A TIN is a shadow entry if the previous tin contains the same file."
- (let* ((previous-tin (tin-previous cvs-cookie-handle tin))
- (curr (tin-cookie cvs-cookie-handle tin))
- (prev (and previous-tin
- (tin-cookie cvs-cookie-handle previous-tin))))
- (and
- prev curr
- (string= (cvs-fileinfo->file-name prev) (cvs-fileinfo->file-name curr))
- (string= (cvs-fileinfo->dir prev) (cvs-fileinfo->dir curr))
- (or
- (and (eq (cvs-fileinfo->type prev) 'CONFLICT)
- (eq (cvs-fileinfo->type curr) 'CONFLICT))
- (and (eq (cvs-fileinfo->type prev) 'MERGED)
- (eq (cvs-fileinfo->type curr) 'MODIFIED))
- (and (eq (cvs-fileinfo->type prev) 'REM-EXIST)
- (eq (cvs-fileinfo->type curr) 'REMOVED))))))
-
-
-(defun cvs-parse-stderr (stdout-buffer stderr-buffer head dir)
- "Parse the output from CVS that is written to stderr.
-Args: STDOUT-BUFFER STDERR-BUFFER HEAD DIR
-STDOUT-BUFFER holds the output that cvs sent to stdout. It is only
-used to create a bug report in case there is a parse error.
-STDERR-BUFFER is the buffer that holds the output to parse.
-HEAD is a cons-cell, the head of the list that is built.
-DIR is the directory the `cvs update' was run in.
-
-This function returns the last cons-cell in the list that is built."
-
- (save-window-excursion
- (set-buffer stderr-buffer)
- (goto-char (point-min))
- (let ((current-dir dir)
- (root-dir dir))
-
- (while (< (point) (point-max))
- (cond
-
- ;; RCVS support (for now, we simply ignore any output from
- ;; RCVS, including error messages!)
-
- ((looking-at "updating of .* finished$")
- (forward-line 1))
-
- ((looking-at "REMOTE FOLDER:.*")
- (forward-line 1)
- (while (and (< (point) (point-max)) (not (looking-at "phase 2.*")))
- (forward-line 1))
- (forward-line 2))
-
- ((looking-at "turn on remote mode$")
- (forward-line 1)
- (while (and (< (point) (point-max)) (not (looking-at "phase 2.*")))
- (forward-line 1))
- (forward-line 2))
-
- ((looking-at "phase 3.*")
- (goto-char (point-max)))
-
- ;; End of RCVS stuff.
-
- ;; CVS is descending a subdirectory.
- ;; (The "server" case is there to support Cyclic CVS.)
- ((looking-at "cvs \\(update\\|server\\): Updating \\(.*\\)$")
- (setq current-dir
- (cvs-get-current-dir
- root-dir
- (buffer-substring (match-beginning 2) (match-end 2))))
- (setcdr head (list (cvs-create-fileinfo
- 'DIRCHANGE current-dir
- nil (buffer-substring (match-beginning 0)
- (match-end 0)))))
- (setq head (cdr head))
- (forward-line 1))
-
- ;; File removed, since it is removed (by third party) in repository.
-
- ((or (looking-at
- "cvs update: warning: \\(.*\\) is not (any longer) pertinent")
- (looking-at
- "cvs update: \\(.*\\) is no longer in the repository"))
-
- (setcdr head (list (cvs-create-fileinfo
- 'CVS-REMOVED current-dir
- (file-name-nondirectory
- (buffer-substring (match-beginning 1)
- (match-end 1)))
- (buffer-substring (match-beginning 0)
- (match-end 0)))))
- (setq head (cdr head))
- (forward-line 1))
-
- ;; File removed by you, but recreated by cvs. Ignored.
-
- ((looking-at "cvs update: warning: .* was lost$")
- (forward-line 1))
-
- ;; A file that has been created by you, but added to the cvs
- ;; repository by another.
-
- ((looking-at "^cvs update: move away \\(.*\\); it is in the way$")
- (setcdr head (list (cvs-create-fileinfo
- 'MOVE-AWAY current-dir
- (file-name-nondirectory
- (buffer-substring (match-beginning 1)
- (match-end 1)))
- (buffer-substring (match-beginning 0)
- (match-end 0)))))
- (setq head (cdr head))
- (forward-line 1))
-
- ;; Empty line. Probably inserted by mistake by user (or developer :-)
- ;; Ignore.
-
- ((looking-at "^$")
- (forward-line 1))
-
- ;; Cvs waits for a lock. Ignore.
-
- ((looking-at
- "^cvs update: \\[..:..:..\\] waiting for .*lock in ")
- (forward-line 1))
-
- ;; File removed in repository, but edited by you.
-
- ((looking-at
- "cvs update: conflict: \\(.*\\) is modified but no longer \
-in the repository$")
- (setcdr head (list
- (cvs-create-fileinfo
- 'REM-CONFLICT current-dir
- (file-name-nondirectory
- (buffer-substring (match-beginning 1) (match-end 1)))
- (buffer-substring (match-beginning 0)
- (match-end 0)))))
- (setq head (cdr head))
- (forward-line 1))
-
- ((looking-at
- "cvs update: conflict: removed \\(.*\\) was modified by \
-second party")
- (setcdr head
- (list
- (cvs-create-fileinfo
- 'MOD-CONFLICT current-dir
- (buffer-substring (match-beginning 1) (match-end 1))
- (buffer-substring (match-beginning 0) (match-end 0)))))
- (setq head (cdr head))
- (forward-line 1))
-
- ((looking-at
- "cvs update: \\(.*\\) should be removed and is still there")
- (setcdr head
- (list
- (cvs-create-fileinfo
- 'REM-EXIST current-dir
- (buffer-substring (match-beginning 1) (match-end 1))
- (buffer-substring (match-beginning 0) (match-end 0)))))
- (setq head (cdr head))
- (forward-line 1))
-
- ((looking-at "cvs update: in directory ")
- (let ((start (point)))
- (forward-line 1)
- (cvs-skip-line
- stdout-buffer stderr-buffer
- (regexp-quote "cvs [update aborted]: there is no repository "))
- (setcdr head (list
- (cvs-create-fileinfo
- 'REPOS-MISSING current-dir
- nil
- (buffer-substring start (point)))))
- (setq head (cdr head))))
-
- ;; Ignore other messages from Cyclic CVS.
- ((looking-at "cvs server:")
- (forward-line 1))
-
- (t
-
- ;; CVS has decided to merge someone elses changes into this
- ;; document. This leads to a lot of garbage being printed.
- ;; First there is two lines that contains no information
- ;; that we skip (but we check that we recognize them).
-
- (let ((complex-start (point))
- initial-revision filename)
-
- (cvs-skip-line stdout-buffer stderr-buffer "^RCS file: .*$")
- (setq initial-revision
- (cvs-skip-line stdout-buffer stderr-buffer
- "^retrieving revision \\(.*\\)$" 1))
- (cvs-skip-line stdout-buffer stderr-buffer
- "^retrieving revision .*$")
-
- ;; Get the file name from the next line.
-
- (setq
- filename
- (cvs-skip-line
- stdout-buffer stderr-buffer
- "^Merging differences between [0-9.]+ and [0-9.]+ into \\(.*\\)$"
- 1))
-
- (cond
- ;; Was it a conflict?
- ((looking-at
- ;; Allow both RCS 5.5 and 5.6. (5.6 prints "rcs" and " warning").
- "^\\(rcs\\)?merge:?\\( warning\\)?: \\(overlaps\\|conflicts\\) during merge$")
-
- ;; Yes, this is a conflict.
- (cvs-skip-line
- stdout-buffer stderr-buffer
- "^\\(rcs\\)?merge:?\\( warning\\)?: \\(overlaps\\|conflicts\\) during merge$")
-
- (cvs-skip-line stdout-buffer stderr-buffer
- "^cvs \\(update\\|server\\): conflicts found in ")
-
- (let ((fileinfo
- (cvs-create-fileinfo
- 'CONFLICT current-dir
- filename
- (buffer-substring complex-start (point)))))
-
- (cvs-set-fileinfo->base-revision fileinfo initial-revision)
-
- (setcdr head (list fileinfo))
- (setq head (cdr head))))
-
- ;; Was it a conflict, and was RCS compiled without DIFF3_BIN?
-
- ((looking-at
- ;; Allow both RCS 5.5 and 5.6. (5.6 prints "rcs" and " warning").
- "^\\(rcs\\)?merge\\( warning\\)?: overlaps or other probl\
-ems during merge$")
-
- ;; Yes, this is a conflict.
- (cvs-skip-line
- stdout-buffer stderr-buffer
- "^\\(rcs\\)?merge\\( warning\\)?: overlaps .*during merge$")
-
- (cvs-skip-line stdout-buffer stderr-buffer
- "^cvs update: could not merge ")
- (cvs-skip-line stdout-buffer stderr-buffer
- "^cvs update: restoring .* from backup file ")
-
- (let ((fileinfo
- (cvs-create-fileinfo
- 'CONFLICT current-dir
- filename
- (buffer-substring complex-start (point)))))
-
- (setcdr head (list fileinfo))
- (setq head (cdr head))))
-
- (t
- ;; Not a conflict; it must be a succesful merge.
- (let ((fileinfo
- (cvs-create-fileinfo
- 'MERGED current-dir
- filename
- (buffer-substring complex-start (point)))))
- (cvs-set-fileinfo->base-revision fileinfo initial-revision)
- (setcdr head (list fileinfo))
- (setq head (cdr head)))))))))))
- head)
-
-
-(defun cvs-parse-stdout (stdout-buffer stderr-buffer head root-dir)
- "Parse the output from CVS that is written to stdout.
-Args: STDOUT-BUFFER STDERR-BUFFER HEAD ROOT-DIR
-STDOUT-BUFFER is the buffer that holds the output to parse.
-STDERR-BUFFER holds the output that cvs sent to stderr. It is only
-used to create a bug report in case there is a parse error.
-
-HEAD is a cons-cell, the head of the list that is built.
-ROOT-DIR is the directory the `cvs update' was run in.
-
-This function doesn't return anything particular."
- (save-window-excursion
- (set-buffer stdout-buffer)
- (goto-char (point-min))
- (while (< (point) (point-max))
- (cond
-
- ;; M: The file is modified by the user, and untouched in the repository.
- ;; A: The file is "cvs add"ed, but not "cvs ci"ed.
- ;; R: The file is "cvs remove"ed, but not "cvs ci"ed.
- ;; C: Conflict
- ;; U, P: The file is copied from the repository.
- ;; ?: Unknown file.
-
-
- ((looking-at "\\([MARCUP?]\\) \\(.*\\)$")
- (let*
- ((c (char-after (match-beginning 1)))
- (full-path
- (concat (file-name-as-directory root-dir)
- (buffer-substring (match-beginning 2) (match-end 2))))
- (fileinfo (cvs-create-fileinfo
- (cond ((eq c ?M) 'MODIFIED)
- ((eq c ?A) 'ADDED)
- ((eq c ?R) 'REMOVED)
- ((eq c ?C) 'CONFLICT)
- ((eq c ?U) 'UPDATED)
- ;; generated when Cyclic CVS sends a
- ;; patch instead of the full file:
- ((eq c ?P) 'UPDATED)
- ((eq c ??) 'UNKNOWN))
- (substring (file-name-directory full-path) 0 -1)
- (file-name-nondirectory full-path)
- (buffer-substring (match-beginning 0) (match-end 0)))))
- ;; Updated files require no further action.
- (if (memq c '(?U ?P))
- (cvs-set-fileinfo->handled fileinfo t))
-
- ;; Link this last on the list.
- (setcdr head (list fileinfo))
- (setq head (cdr head))
- (forward-line 1)))
-
- ;; Executing a program because of the -u option in modules.
- ((looking-at "cvs update: Executing")
- ;; Skip by any output the program may generate to stdout.
- ;; Note that pcl-cvs will get seriously confused if the
- ;; program prints anything to stderr.
- (re-search-forward cvs-update-prog-output-skip-regexp)
- (forward-line 1))
-
- (t (cvs-parse-error stdout-buffer stderr-buffer 'STDOUT (point)))))))
-
-(defun cvs-pp (fileinfo)
- "Pretty print FILEINFO. Insert a printed representation in current buffer.
-For use by the cookie package."
-
- (let ((a (cvs-fileinfo->type fileinfo))
- (s (if (cvs-fileinfo->marked fileinfo)
- "*" " "))
- (f (cvs-fileinfo->file-name fileinfo))
- (ci (if (cvs-fileinfo->handled fileinfo)
- " " "ci")))
- (insert
- (cond
- ((eq a 'UPDATED)
- (format "%s Updated %s" s f))
- ((eq a 'MODIFIED)
- (format "%s Modified %s %s" s ci f))
- ((eq a 'MERGED)
- (format "%s Merged %s %s" s ci f))
- ((eq a 'CONFLICT)
- (format "%s Conflict %s" s f))
- ((eq a 'ADDED)
- (format "%s Added %s %s" s ci f))
- ((eq a 'REMOVED)
- (format "%s Removed %s %s" s ci f))
- ((eq a 'UNKNOWN)
- (format "%s Unknown %s" s f))
- ((eq a 'CVS-REMOVED)
- (format "%s Removed from repository: %s" s f))
- ((eq a 'REM-CONFLICT)
- (format "%s Conflict: Removed from repository, changed by you: %s" s f))
- ((eq a 'MOD-CONFLICT)
- (format "%s Conflict: Removed by you, changed in repository: %s" s f))
- ((eq a 'REM-EXIST)
- (format "%s Conflict: Removed by you, but still exists: %s" s f))
- ((eq a 'DIRCHANGE)
- (format "\nIn directory %s:"
- (cvs-fileinfo->dir fileinfo)))
- ((eq a 'MOVE-AWAY)
- (format "%s Move away %s - it is in the way" s f))
- ((eq a 'REPOS-MISSING)
- (format " This repository is missing! Remove this dir manually."))
- ((eq a 'MESSAGE)
- (cvs-fileinfo->full-log fileinfo))
- (t
- (format "%s Internal error! %s" s f))))))
-
-
-;;; You can define your own keymap in .emacs. pcl-cvs.el won't overwrite it.
-
-(if cvs-mode-map
- nil
- (setq cvs-mode-map (make-keymap))
- (suppress-keymap cvs-mode-map)
- (define-key cvs-mode-map " " 'cvs-mode-next-line)
- (define-key cvs-mode-map "?" 'describe-mode)
- (define-key cvs-mode-map "A" 'cvs-mode-add-change-log-entry-other-window)
- (define-key cvs-mode-map "M" 'cvs-mode-mark-all-files)
- (define-key cvs-mode-map "R" 'cvs-mode-revert-updated-buffers)
- (define-key cvs-mode-map "U" 'cvs-mode-undo-local-changes)
- (define-key cvs-mode-map "\C-?" 'cvs-mode-unmark-up)
- (define-key cvs-mode-map "\C-k" 'cvs-mode-acknowledge)
- (define-key cvs-mode-map "\C-n" 'cvs-mode-next-line)
- (define-key cvs-mode-map "\C-p" 'cvs-mode-previous-line)
- (define-key cvs-mode-map "\M-\C-?" 'cvs-mode-unmark-all-files)
- (define-key cvs-mode-map "a" 'cvs-mode-add)
- (define-key cvs-mode-map "b" 'cvs-mode-diff-backup)
- (define-key cvs-mode-map "c" 'cvs-mode-commit)
- (define-key cvs-mode-map "C" 'cvs-mode-changelog-commit)
- (define-key cvs-mode-map "d" 'cvs-mode-diff-cvs)
- (define-key cvs-mode-map "e" 'cvs-mode-emerge)
- (define-key cvs-mode-map "f" 'cvs-mode-find-file)
- (define-key cvs-mode-map "g" 'cvs-mode-update-no-prompt)
- (define-key cvs-mode-map "i" 'cvs-mode-ignore)
- (define-key cvs-mode-map "l" 'cvs-mode-log)
- (define-key cvs-mode-map "m" 'cvs-mode-mark)
- (define-key cvs-mode-map "n" 'cvs-mode-next-line)
- (define-key cvs-mode-map "o" 'cvs-mode-find-file-other-window)
- (define-key cvs-mode-map "p" 'cvs-mode-previous-line)
- (define-key cvs-mode-map "q" 'bury-buffer)
- (define-key cvs-mode-map "r" 'cvs-mode-remove-file)
- (define-key cvs-mode-map "s" 'cvs-mode-status)
- (define-key cvs-mode-map "x" 'cvs-mode-remove-handled)
- (define-key cvs-mode-map "u" 'cvs-mode-unmark))
-
-
-(defun cvs-get-marked (&optional ignore-marks)
- "Return a list of all selected tins.
-If there are any marked tins, and IGNORE-MARKS is nil, return them.
-Otherwise, if the cursor selects a directory, return all files in it.
-Otherwise return (a list containing) the file the cursor points to, or
-an empty list if it doesn't point to a file at all.
-
-Args: &optional IGNORE-MARKS."
-
- (cond
- ;; Any marked cookies?
- ((and (not ignore-marks)
- (collection-collect-tin cvs-cookie-handle 'cvs-fileinfo->marked)))
- ;; Nope.
- (t
- (let ((sel (tin-locate cvs-cookie-handle (point))))
- (cond
- ;; If a directory is selected, all it members are returned.
- ((and sel (eq (cvs-fileinfo->type
- (tin-cookie cvs-cookie-handle sel))
- 'DIRCHANGE))
- (collection-collect-tin
- cvs-cookie-handle 'cvs-dir-member-p
- (cvs-fileinfo->dir (tin-cookie cvs-cookie-handle sel))))
- (t
- (list sel)))))))
-
-
-(defun cvs-dir-member-p (fileinfo dir)
- "Return true if FILEINFO represents a file in directory DIR."
- (and (not (eq (cvs-fileinfo->type fileinfo) 'DIRCHANGE))
- (string= (cvs-fileinfo->dir fileinfo) dir)))
-
-(defun cvs-dir-empty-p (tin)
- "Return non-nil if TIN is a directory that is empty.
-Args: CVS-BUF TIN."
- (and (eq (cvs-fileinfo->type (tin-cookie cvs-cookie-handle tin)) 'DIRCHANGE)
- (or (not (tin-next cvs-cookie-handle tin))
- (eq (cvs-fileinfo->type
- (tin-cookie cvs-cookie-handle
- (tin-next cvs-cookie-handle tin)))
- 'DIRCHANGE))))
-
-(defun cvs-mode-revert-updated-buffers ()
- "Revert any buffers that are UPDATED, MERGED or CONFLICT."
- (interactive)
- (cookie-map (function cvs-revert-fileinfo) cvs-cookie-handle))
-
-(defun cvs-revert-fileinfo (fileinfo)
- "Revert the buffer that holds the file in FILEINFO if it has changed,
-and if the type is UPDATED, MERGED or CONFLICT."
- (let* ((type (cvs-fileinfo->type fileinfo))
- (file (cvs-fileinfo->full-path fileinfo))
- (buffer (get-file-buffer file)))
- ;; For a revert to happen...
- (cond
- ((and
- ;; ...the type must be one that justifies a revert...
- (or (eq type 'UPDATED)
- (eq type 'MERGED)
- (eq type 'CONFLICT))
- ;; ...and the user must be editing the file...
- buffer)
- (save-excursion
- (set-buffer buffer)
- (cond
- ((buffer-modified-p)
- (error "%s: edited since last cvs-update."
- (buffer-file-name)))
- ;; Go ahead and revert the file.
- (t (revert-buffer 'dont-use-auto-save-file 'dont-ask))))))))
-
-
-(defun cvs-mode-remove-handled ()
- "Remove all lines that are handled.
-Empty directories are removed."
- (interactive)
- ;; Pass one: remove files that are handled.
- (collection-filter-cookies cvs-cookie-handle
- (function
- (lambda (fileinfo) (not (cvs-fileinfo->handled fileinfo)))))
- ;; Pass two: remove empty directories.
- (cvs-remove-empty-directories))
-
-
-(defun cvs-remove-empty-directories ()
- "Remove empty directories in the *cvs* buffer."
- (collection-filter-tins cvs-cookie-handle
- (function
- (lambda (tin)
- (not (cvs-dir-empty-p tin))))))
-
-(defun cvs-mode-mark (pos)
- "Mark a fileinfo. Args: POS.
-If the fileinfo is a directory, all the contents of that directory are
-marked instead. A directory can never be marked.
-POS is a buffer position."
-
- (interactive "d")
-
- (let* ((tin (tin-locate cvs-cookie-handle pos))
- (sel (tin-cookie cvs-cookie-handle tin)))
-
- (cond
- ;; Does POS point to a directory? If so, mark all files in that directory.
- ((eq (cvs-fileinfo->type sel) 'DIRCHANGE)
- (cookie-map
- (function (lambda (f dir)
- (cond
- ((cvs-dir-member-p f dir)
- (cvs-set-fileinfo->marked f t)
- t)))) ;Tell cookie to redisplay this cookie.
- cvs-cookie-handle
- (cvs-fileinfo->dir sel)))
- (t
- (cvs-set-fileinfo->marked sel t)
- (tin-invalidate cvs-cookie-handle tin)
- (tin-goto-next cvs-cookie-handle pos 1)))))
-
-
-(defun cvs-committable (tin)
- "Check if the TIN is committable.
-It is committable if it
- a) is not handled and
- b) is either MODIFIED, ADDED, REMOVED, MERGED or CONFLICT."
- (let* ((fileinfo (tin-cookie cvs-cookie-handle tin))
- (type (cvs-fileinfo->type fileinfo)))
- (and (not (cvs-fileinfo->handled fileinfo))
- (or (eq type 'MODIFIED)
- (eq type 'ADDED)
- (eq type 'REMOVED)
- (eq type 'MERGED)
- (eq type 'CONFLICT)))))
-
-(defun cvs-mode-commit ()
-
- "Check in all marked files, or the current file.
-The user will be asked for a log message in a buffer.
-If cvs-erase-input-buffer is non-nil that buffer will be erased.
-Otherwise mark and point will be set around the entire contents of the
-buffer so that it is easy to kill the contents of the buffer with \\[kill-region]."
-
- (interactive)
-
- (let* ((cvs-buf (current-buffer))
- (marked (cvs-filter (function cvs-committable)
- (cvs-get-marked))))
- (if (null marked)
- (error "Nothing to commit!")
- (pop-to-buffer (get-buffer-create cvs-commit-prompt-buffer))
- (goto-char (point-min))
-
- (if cvs-erase-input-buffer
- (erase-buffer)
- (push-mark (point-max)))
- (cvs-edit-mode)
- (make-local-variable 'cvs-commit-list)
- (setq cvs-commit-list marked)
- (message "Press C-c C-c when you are done editing."))))
-
-
-(defun cvs-edit-done ()
- "Commit the files to the repository."
- (interactive)
- (if (null cvs-commit-list)
- (error "You have already commited the files"))
- (if (and (> (point-max) 1)
- (/= (char-after (1- (point-max))) ?\n)
- (or (eq cvs-commit-buffer-require-final-newline t)
- (and cvs-commit-buffer-require-final-newline
- (yes-or-no-p
- (format "Buffer %s does not end in newline. Add one? "
- (buffer-name))))))
- (save-excursion
- (goto-char (point-max))
- (insert ?\n)))
- (save-some-buffers)
- (let ((cc-list cvs-commit-list)
- (cc-buffer (get-buffer cvs-buffer-name))
- (msg-buffer (current-buffer))
- (msg (buffer-substring (point-min) (point-max))))
- (pop-to-buffer cc-buffer)
- (bury-buffer msg-buffer)
- (cvs-use-temp-buffer)
- (message "Committing...")
- (if (cvs-execute-list cc-list cvs-program
- (if cvs-cvsroot
- (list "-d" cvs-cvsroot "commit" "-m" msg)
- (list "commit" "-m" msg)))
- (error "Something went wrong. Check the %s buffer carefully."
- cvs-temp-buffer-name))
- (let ((ccl cc-list))
- (while ccl
- (cvs-after-commit-function (tin-cookie cvs-cookie-handle (car ccl)))
- (setq ccl (cdr ccl))))
- (apply 'tin-invalidate cvs-cookie-handle cc-list)
- (set-buffer msg-buffer)
- (setq cvs-commit-list nil)
- (set-buffer cc-buffer)
- (if cvs-auto-remove-handled
- (cvs-mode-remove-handled)))
-
- (message "Committing... Done."))
-
-(defun cvs-after-commit-function (fileinfo)
- "Do everything that needs to be done when FILEINFO has been commited.
-The fileinfo->handle is set, and if the buffer is present it is reverted."
- (cvs-set-fileinfo->handled fileinfo t)
- (if cvs-auto-revert-after-commit
- (let* ((file (cvs-fileinfo->full-path fileinfo))
- (buffer (get-file-buffer file)))
- ;; For a revert to happen...
- (if buffer
- ;; ...the user must be editing the file...
- (save-excursion
- (set-buffer buffer)
- (if (not (buffer-modified-p))
- ;; ...but it must be unmodified.
- (revert-buffer 'dont-use-auto-save-file 'dont-ask)))))))
-
-
-(defun cvs-execute-list (tin-list program constant-args)
- "Run PROGRAM on all elements on TIN-LIST.
-Args: TIN-LIST PROGRAM CONSTANT-ARGS
-The PROGRAM will be called with pwd set to the directory the
-files reside in. CONSTANT-ARGS should be a list of strings. The
-arguments given to the program will be CONSTANT-ARGS followed by all
-the files (from TIN-LIST) that resides in that directory. If the files
-in TIN-LIST resides in different directories the PROGRAM will be run
-once for each directory (if all files in the same directory appears
-after each other).
-
-Any output from PROGRAM will be inserted in the current buffer.
-
-This function return nil if all went well, or the numerical exit
-status or a signal name as a string. Note that PROGRAM might be called
-several times. This will return non-nil if something goes wrong, but
-there is no way to know which process that failed."
-
- (let ((exitstatus nil))
- (while tin-list
- (let ((current-dir (cvs-fileinfo->dir
- (tin-cookie cvs-cookie-handle
- (car tin-list))))
- arg-list arg-str)
-
- ;; Collect all marked files in this directory.
-
- (while (and tin-list
- (string=
- current-dir
- (cvs-fileinfo->dir
- (tin-cookie cvs-cookie-handle (car tin-list)))))
- (setq arg-list
- (cons (cvs-fileinfo->file-name
- (tin-cookie cvs-cookie-handle (car tin-list)))
- arg-list))
- (setq tin-list (cdr tin-list)))
-
- (setq arg-list (nreverse arg-list))
-
- ;; Execute the command on all the files that were collected.
-
- (setq default-directory (file-name-as-directory current-dir))
- (insert (format "=== cd %s\n" default-directory))
- (insert (format "=== %s %s\n\n"
- program
- (mapconcat '(lambda (foo) foo)
- (nconc (copy-sequence constant-args)
- arg-list)
- " ")))
- (let ((res (apply 'call-process program nil t t
- (nconc (copy-sequence constant-args) arg-list))))
- ;; Remember the first, or highest, exitstatus.
- (if (and (not (and (integerp res) (zerop res)))
- (or (null exitstatus)
- (and (integerp exitstatus) (= 1 exitstatus))))
- (setq exitstatus res)))
- (goto-char (point-max))))
- exitstatus))
-
-
-(defun cvs-execute-single-file-list (tin-list extractor program constant-args)
- "Run PROGRAM on all elements on TIN-LIST.
-
-Args: TIN-LIST EXTRACTOR PROGRAM CONSTANT-ARGS
-
-The PROGRAM will be called with pwd set to the directory the files
-reside in. CONSTANT-ARGS is a list of strings to pass as arguments to
-PROGRAM. The arguments given to the program will be CONSTANT-ARGS
-followed by the list that EXTRACTOR returns.
-
-EXTRACTOR will be called once for each file on TIN-LIST. It is given
-one argument, the cvs-fileinfo. It can return t, which means ignore
-this file, or a list of arguments to send to the program."
-
- (while tin-list
- (let ((default-directory (file-name-as-directory
- (cvs-fileinfo->dir
- (tin-cookie cvs-cookie-handle
- (car tin-list)))))
- (arg-list
- (funcall extractor
- (tin-cookie cvs-cookie-handle (car tin-list)))))
-
- ;; Execute the command unless extractor returned t.
-
- (if (eq arg-list t)
- nil
- (insert (format "=== cd %s\n" default-directory))
- (insert (format "=== %s %s\n\n"
- program
- (mapconcat '(lambda (foo) foo)
- (nconc (copy-sequence constant-args)
- arg-list)
- " ")))
- (apply 'call-process program nil t t
- (nconc (copy-sequence constant-args) arg-list))
- (goto-char (point-max))))
- (setq tin-list (cdr tin-list))))
-
-
-(defun cvs-edit-mode ()
- "\\<cvs-edit-mode-map>Mode for editing cvs log messages.
-Commands:
-\\[cvs-edit-done] checks in the file when you are ready.
-This mode is based on fundamental mode."
- (interactive)
- (use-local-map cvs-edit-mode-map)
- (setq major-mode 'cvs-edit-mode)
- (setq mode-name "CVS Log")
- (auto-fill-mode 1))
-
-
-(if cvs-edit-mode-map
- nil
- (setq cvs-edit-mode-map (make-sparse-keymap))
- (define-prefix-command 'cvs-control-c-prefix)
- (define-key cvs-edit-mode-map "\C-c" 'cvs-control-c-prefix)
- (define-key cvs-edit-mode-map "\C-c\C-c" 'cvs-edit-done))
-
-
-(defun cvs-diffable (tins)
- "Return a list of all tins on TINS that it makes sense to run
-``cvs diff'' on."
- ;; +++ There is an unnecessary (nreverse) here. Get the list the
- ;; other way around instead!
- (let ((result nil))
- (while tins
- (let ((type (cvs-fileinfo->type
- (tin-cookie cvs-cookie-handle (car tins)))))
- (if (or (eq type 'MODIFIED)
- (eq type 'UPDATED)
- (eq type 'MERGED)
- (eq type 'CONFLICT)
- (eq type 'REMOVED) ;+++Does this line make sense?
- (eq type 'ADDED)) ;+++Does this line make sense?
- (setq result (cons (car tins) result)))
- (setq tins (cdr tins))))
- (nreverse result)))
-
-
-(defun cvs-mode-diff-cvs (&optional ignore-marks)
- "Diff the selected files against the repository.
-The flags in the variable cvs-diff-flags (which should be a list
-of strings) will be passed to ``cvs diff''. If the variable
-cvs-diff-ignore-marks is non-nil any marked files will not be
-considered to be selected. An optional prefix argument will invert
-the influence from cvs-diff-ignore-marks."
-
- (interactive "P")
-
- (if (not (listp cvs-diff-flags))
- (error "cvs-diff-flags should be a list of strings"))
-
- (save-some-buffers)
- (let ((marked (cvs-diffable
- (cvs-get-marked
- (or (and ignore-marks (not cvs-diff-ignore-marks))
- (and (not ignore-marks) cvs-diff-ignore-marks))))))
- (cvs-use-temp-buffer)
- (message "cvsdiffing...")
- ;; Don't care much about the exit status since it is the _sum_ of
- ;; the status codes from the different files (not the _max_ as it
- ;; should be).
- (if (cvs-execute-list marked cvs-program
- (if cvs-cvsroot
- (cons "-d" (cons cvs-cvsroot
- (cons "diff" cvs-diff-flags)))
- (cons "diff" cvs-diff-flags)))
- (message "cvsdiffing... Done.")
- (message "cvsdiffing... No differences found."))))
-
-
-(defun cvs-backup-diffable (tin)
- "Check if the TIN is backup-diffable.
-It must have a backup file to be diffable."
- (file-readable-p
- (cvs-fileinfo->backup-file (tin-cookie cvs-cookie-handle tin))))
-
-(defun cvs-mode-diff-backup (&optional ignore-marks)
- "Diff the files against the backup file.
-This command can be used on files that are marked with \"Merged\"
-or \"Conflict\" in the *cvs* buffer.
-
-If the variable cvs-diff-ignore-marks is non-nil any marked files will
-not be considered to be selected. An optional prefix argument will
-invert the influence from cvs-diff-ignore-marks.
-
-The flags in cvs-diff-flags will be passed to ``diff''."
-
- (interactive "P")
-
- (if (not (listp cvs-diff-flags))
- (error "cvs-diff-flags should be a list of strings."))
-
- (save-some-buffers)
- (let ((marked (cvs-filter
- (function cvs-backup-diffable)
- (cvs-get-marked
- (or
- (and ignore-marks (not cvs-diff-ignore-marks))
- (and (not ignore-marks) cvs-diff-ignore-marks))))))
- (if (null marked)
- (error "No ``Conflict'' or ``Merged'' file selected!"))
- (cvs-use-temp-buffer)
- (message "diffing...")
- (cvs-execute-single-file-list
- marked 'cvs-diff-backup-extractor cvs-diff-program cvs-diff-flags))
- (message "diffing... Done."))
-
-
-(defun cvs-diff-backup-extractor (fileinfo)
- "Return the filename and the name of the backup file as a list.
-Signal an error if there is no backup file."
- (if (not (file-readable-p (cvs-fileinfo->backup-file fileinfo)))
- (error "%s has no backup file."
- (concat
- (file-name-as-directory (cvs-fileinfo->dir fileinfo))
- (cvs-fileinfo->file-name fileinfo))))
- (list (cvs-fileinfo->backup-file fileinfo)
- (cvs-fileinfo->file-name fileinfo)))
-
-(defun cvs-mode-find-file-other-window (pos)
- "Select a buffer containing the file in another window.
-Args: POS"
- (interactive "d")
- (let ((tin (tin-locate cvs-cookie-handle pos)))
- (if tin
- (let ((type (cvs-fileinfo->type (tin-cookie cvs-cookie-handle
- tin))))
- (cond
- ((or (eq type 'REMOVED)
- (eq type 'CVS-REMOVED))
- (error "Can't visit a removed file."))
- ((eq type 'DIRCHANGE)
- (let ((obuf (current-buffer))
- (odir default-directory))
- (setq default-directory
- (file-name-as-directory
- (cvs-fileinfo->dir
- (tin-cookie cvs-cookie-handle tin))))
- (dired-other-window default-directory)
- (set-buffer obuf)
- (setq default-directory odir)))
- (t
- (find-file-other-window (cvs-full-path tin)))))
- (error "There is no file to find."))))
-
-(defun cvs-fileinfo->full-path (fileinfo)
- "Return the full path for the file that is described in FILEINFO."
- (concat
- (file-name-as-directory
- (cvs-fileinfo->dir fileinfo))
- (cvs-fileinfo->file-name fileinfo)))
-
-(defun cvs-full-path (tin)
- "Return the full path for the file that is described in TIN."
- (cvs-fileinfo->full-path (tin-cookie cvs-cookie-handle tin)))
-
-(defun cvs-mode-find-file (pos)
- "Select a buffer containing the file in another window.
-Args: POS"
- (interactive "d")
- (let* ((cvs-buf (current-buffer))
- (tin (tin-locate cvs-cookie-handle pos)))
- (if tin
- (let* ((fileinfo (tin-cookie cvs-cookie-handle tin))
- (type (cvs-fileinfo->type fileinfo)))
- (cond
- ((or (eq type 'REMOVED)
- (eq type 'CVS-REMOVED))
- (error "Can't visit a removed file."))
- ((eq type 'DIRCHANGE)
- (let ((odir default-directory))
- (setq default-directory
- (file-name-as-directory (cvs-fileinfo->dir fileinfo)))
- (dired default-directory)
- (set-buffer cvs-buf)
- (setq default-directory odir)))
- (t
- (find-file (cvs-full-path tin)))))
- (error "There is no file to find."))))
-
-(defun cvs-mode-mark-all-files ()
- "Mark all files.
-Directories are not marked."
- (interactive)
- (cookie-map (function (lambda (cookie)
- (cond
- ((not (eq (cvs-fileinfo->type cookie) 'DIRCHANGE))
- (cvs-set-fileinfo->marked cookie t)
- t))))
- cvs-cookie-handle))
-
-
-(defun cvs-mode-unmark (pos)
- "Unmark a fileinfo. Args: POS."
- (interactive "d")
-
- (let* ((tin (tin-locate cvs-cookie-handle pos))
- (sel (tin-cookie cvs-cookie-handle tin)))
-
- (cond
- ((eq (cvs-fileinfo->type sel) 'DIRCHANGE)
- (cookie-map
- (function (lambda (f dir)
- (cond
- ((cvs-dir-member-p f dir)
- (cvs-set-fileinfo->marked f nil)
- t))))
- cvs-cookie-handle
- (cvs-fileinfo->dir sel)))
- (t
- (cvs-set-fileinfo->marked sel nil)
- (tin-invalidate cvs-cookie-handle tin)
- (tin-goto-next cvs-cookie-handle pos 1)))))
-
-(defun cvs-mode-unmark-all-files ()
- "Unmark all files.
-Directories are also unmarked, but that doesn't matter, since
-they should always be unmarked."
- (interactive)
- (cookie-map (function (lambda (cookie)
- (cvs-set-fileinfo->marked cookie nil)
- t))
- cvs-cookie-handle))
-
-
-(defun cvs-do-removal (tins)
- "Remove files.
-Args: TINS.
-TINS is a list of tins that the
-user wants to delete. The files are deleted. If the type of
-the tin is 'UNKNOWN the tin is removed from the buffer. If it
-is anything else the file is added to a list that should be
-`cvs remove'd and the tin is changed to be of type 'REMOVED.
-
-Returns a list of tins files that should be `cvs remove'd."
- (cvs-use-temp-buffer)
- (mapcar 'cvs-insert-full-path tins)
- (cond
- ((and tins (yes-or-no-p (format "Delete %d files? " (length tins))))
- (let (files-to-remove)
- (while tins
- (let* ((tin (car tins))
- (fileinfo (tin-cookie cvs-cookie-handle tin))
- (type (cvs-fileinfo->type fileinfo)))
- (if (not (or (eq type 'REMOVED) (eq type 'CVS-REMOVED)))
- (progn
- (delete-file (cvs-full-path tin))
- (cond
- ((or (eq type 'UNKNOWN) (eq type 'MOVE-AWAY))
- (tin-delete cvs-cookie-handle tin))
- (t
- (setq files-to-remove (cons tin files-to-remove))
- (cvs-set-fileinfo->type fileinfo 'REMOVED)
- (cvs-set-fileinfo->handled fileinfo nil)
- (tin-invalidate cvs-cookie-handle tin))))))
- (setq tins (cdr tins)))
- files-to-remove))
- (t nil)))
-
-
-
-(defun cvs-mode-remove-file ()
- "Remove all marked files."
- (interactive)
- (let ((files-to-remove (cvs-do-removal (cvs-get-marked))))
- (if (null files-to-remove)
- nil
- (cvs-use-temp-buffer)
- (message "removing from repository...")
- (if (cvs-execute-list files-to-remove cvs-program
- (if cvs-cvsroot
- (list "-d" cvs-cvsroot "remove")
- '("remove")))
- (error "CVS exited with non-zero exit status.")
- (message "removing from repository... done.")))))
-
-(defun cvs-mode-undo-local-changes ()
- "Undo local changes to all marked files.
-The file is removed and `cvs update FILE' is run."
- (interactive)
- (let ((tins-to-undo (cvs-get-marked)))
- (cvs-use-temp-buffer)
- (mapcar 'cvs-insert-full-path tins-to-undo)
- (cond
- ((and tins-to-undo (yes-or-no-p (format "Undo changes to %d files? "
- (length tins-to-undo))))
- (let (files-to-update)
- (while tins-to-undo
- (let* ((tin (car tins-to-undo))
- (fileinfo (tin-cookie cvs-cookie-handle tin))
- (type (cvs-fileinfo->type fileinfo)))
- (cond
- ((or
- (eq type 'UPDATED) (eq type 'MODIFIED) (eq type 'MERGED)
- (eq type 'CONFLICT) (eq type 'CVS-REMOVED)
- (eq type 'REM-CONFLICT) (eq type 'MOVE-AWAY)
- (eq type 'REMOVED))
- (if (not (eq type 'REMOVED))
- (delete-file (cvs-full-path tin)))
- (setq files-to-update (cons tin files-to-update))
- (cvs-set-fileinfo->type fileinfo 'UPDATED)
- (cvs-set-fileinfo->handled fileinfo t)
- (tin-invalidate cvs-cookie-handle tin))
-
- ((eq type 'MOD-CONFLICT)
- (error "Use cvs-mode-add instead on %s."
- (cvs-fileinfo->file-name fileinfo)))
-
- ((eq type 'REM-CONFLICT)
- (error "Can't deal with a file you have removed and recreated."))
-
- ((eq type 'DIRCHANGE)
- (error "Undo on directories not supported (yet)."))
-
- ((eq type 'ADDED)
- (error "There is no old revision to get for %s"
- (cvs-fileinfo->file-name fileinfo)))
- (t (error "cvs-mode-undo-local-changes: can't handle an %s"
- type)))
-
- (setq tins-to-undo (cdr tins-to-undo))))
- (cvs-use-temp-buffer)
- (message "Regetting files from repository...")
- (if (cvs-execute-list files-to-update cvs-program
- (if cvs-cvsroot
- (list "-d" cvs-cvsroot "update")
- '("update")))
- (error "CVS exited with non-zero exit status.")
- (message "Regetting files from repository... done.")))))))
-
-(defun cvs-mode-acknowledge ()
- "Remove all marked files from the buffer."
- (interactive)
-
- (mapcar (function (lambda (tin)
- (tin-delete cvs-cookie-handle tin)))
- (cvs-get-marked)))
-
-
-(defun cvs-mode-unmark-up (pos)
- "Unmark the file on the previous line.
-Takes one argument POS, a buffer position."
- (interactive "d")
- (let ((tin (tin-goto-previous cvs-cookie-handle pos 1)))
- (cond
- (tin
- (cvs-set-fileinfo->marked (tin-cookie cvs-cookie-handle tin)
- nil)
- (tin-invalidate cvs-cookie-handle tin)))))
-
-(defun cvs-mode-previous-line (arg)
- "Go to the previous line.
-If a prefix argument is given, move by that many lines."
- (interactive "p")
- (tin-goto-previous cvs-cookie-handle (point) arg))
-
-(defun cvs-mode-next-line (arg)
- "Go to the next line.
-If a prefix argument is given, move by that many lines."
- (interactive "p")
- (tin-goto-next cvs-cookie-handle (point) arg))
-
-(defun cvs-add-file-update-buffer (tin)
- "Subfunction to cvs-mode-add. Internal use only.
-Update the display. Return non-nil if `cvs add' should be called on this
-file. Args: TIN.
-Returns 'ADD or 'RESURRECT."
- (let ((fileinfo (tin-cookie cvs-cookie-handle tin)))
- (cond
- ((eq (cvs-fileinfo->type fileinfo) 'UNKNOWN)
- (cvs-set-fileinfo->type fileinfo 'ADDED)
- (tin-invalidate cvs-cookie-handle tin)
- 'ADD)
- ((eq (cvs-fileinfo->type fileinfo) 'REMOVED)
- (cvs-set-fileinfo->type fileinfo 'UPDATED)
- (cvs-set-fileinfo->handled fileinfo t)
- (tin-invalidate cvs-cookie-handle tin)
- 'RESURRECT))))
-
-(defun cvs-add-sub (cvs-buf candidates)
- "Internal use only.
-Args: CVS-BUF CANDIDATES.
-CANDIDATES is a list of tins. Updates the CVS-BUF and returns a pair of lists.
-The first list is unknown tins that shall be `cvs add -m msg'ed.
-The second list is removed files that shall be `cvs add'ed (resurrected)."
- (let (add resurrect)
- (while candidates
- (let ((type (cvs-add-file-update-buffer (car candidates))))
- (cond ((eq type 'ADD)
- (setq add (cons (car candidates) add)))
- ((eq type 'RESURRECT)
- (setq resurrect (cons (car candidates) resurrect)))))
- (setq candidates (cdr candidates)))
- (cons add resurrect)))
-
-(defun cvs-mode-add ()
- "Add marked files to the cvs repository."
- (interactive)
-
- (let* ((buf (current-buffer))
- (result (cvs-add-sub buf (cvs-get-marked)))
- (added (car result))
- (resurrect (cdr result))
- (msg (if added (read-from-minibuffer "Enter description: "))))
-
- (if (or resurrect added)
- (cvs-use-temp-buffer))
-
- (cond (resurrect
- (message "Resurrecting files from repository...")
- (if (cvs-execute-list resurrect cvs-program
- (if cvs-cvsroot
- (list "-d" cvs-cvsroot "add")
- '("add")))
- (error "CVS exited with non-zero exit status.")
- (message "Done."))))
-
- (cond (added
- (message "Adding new files to repository...")
- (if (cvs-execute-list added cvs-program
- (if cvs-cvsroot
- (list "-d" cvs-cvsroot "add" "-m" msg)
- (list "add" "-m" msg)))
- (error "CVS exited with non-zero exit status.")
- (message "Done."))))))
-
-(defun cvs-mode-ignore ()
- "Arrange so that CVS ignores the selected files.
-This command ignores files that are not flagged as `Unknown'."
- (interactive)
-
- (mapcar (function (lambda (tin)
- (cond
- ((eq (cvs-fileinfo->type
- (tin-cookie cvs-cookie-handle tin))
- 'UNKNOWN)
- (cvs-append-to-ignore
- (tin-cookie cvs-cookie-handle tin))
- (tin-delete cvs-cookie-handle tin)))))
- (cvs-get-marked)))
-
-(defun cvs-append-to-ignore (fileinfo)
- "Append the file in fileinfo to the .cvsignore file"
- (save-window-excursion
- (set-buffer (find-file-noselect (concat (file-name-as-directory
- (cvs-fileinfo->dir fileinfo))
- ".cvsignore")))
- (goto-char (point-max))
- (if (not (zerop (current-column)))
- (insert "\n"))
- (insert (cvs-fileinfo->file-name fileinfo) "\n")
- (if cvs-sort-ignore-file
- (sort-lines nil (point-min) (point-max)))
- (save-buffer)))
-
-(defun cvs-mode-status ()
- "Show cvs status for all marked files."
- (interactive)
-
- (save-some-buffers)
- (let ((marked (cvs-get-marked)))
- (cvs-use-temp-buffer)
- (message "Running cvs status ...")
- (if (cvs-execute-list
- marked cvs-program
- (if cvs-cvsroot
- (cons "-d" (cons cvs-cvsroot (cons "status" cvs-status-flags)))
- (cons "status" cvs-status-flags)))
- (error "CVS exited with non-zero exit status.")
- (message "Running cvs status ... Done."))))
-
-(defun cvs-mode-log ()
- "Display the cvs log of all selected files."
- (interactive)
-
- (let ((marked (cvs-get-marked)))
- (cvs-use-temp-buffer)
- (message "Running cvs log ...")
- (if (cvs-execute-list marked cvs-program
- (if cvs-cvsroot
- (cons "-d" (cons cvs-cvsroot
- (cons "log" cvs-log-flags)))
- (cons "log" cvs-log-flags)))
- (error "CVS exited with non-zero exit status.")
- (message "Running cvs log ... Done."))))
-
-(defun cvs-byte-compile-files ()
- "Run byte-compile-file on all selected files that end in '.el'."
- (interactive)
- (let ((marked (cvs-get-marked)))
- (while marked
- (let ((filename (cvs-full-path (car marked))))
- (if (string-match "\\.el$" filename)
- (byte-compile-file filename)))
- (setq marked (cdr marked)))))
-
-(defun cvs-insert-full-path (tin)
- "Insert full path to the file described in TIN in the current buffer."
- (insert (format "%s\n" (cvs-full-path tin))))
-
-
-(defun cvs-mode-add-change-log-entry-other-window (pos)
- "Add a ChangeLog entry in the ChangeLog of the current directory.
-Args: POS."
- (interactive "d")
- (let* ((cvs-buf (current-buffer))
- (odir default-directory))
- (setq default-directory
- (file-name-as-directory
- (cvs-fileinfo->dir
- (tin-cookie
- cvs-cookie-handle
- (tin-locate cvs-cookie-handle pos)))))
- (if (not default-directory) ;In case there was no entries.
- (setq default-directory odir))
- (add-change-log-entry-other-window)
- (set-buffer cvs-buf)
- (setq default-directory odir)))
-
-
-(defun print-cvs-tin (foo)
- "Debug utility."
- (let ((cookie (tin-cookie cvs-cookie-handle foo))
- (stream (get-buffer-create "debug")))
- (princ "==============\n" stream)
- (princ (cvs-fileinfo->file-name cookie) stream)
- (princ "\n" stream)
- (princ (cvs-fileinfo->dir cookie) stream)
- (princ "\n" stream)
- (princ (cvs-fileinfo->full-log cookie) stream)
- (princ "\n" stream)
- (princ (cvs-fileinfo->marked cookie) stream)
- (princ "\n" stream)))
-
-(defun cvs-mode-emerge (pos)
- "Emerge appropriate revisions of the selected file.
-Args: POS"
- (interactive "d")
- (let* ((cvs-buf (current-buffer))
- (tin (tin-locate cvs-cookie-handle pos)))
- (if tin
- (let* ((fileinfo (tin-cookie cvs-cookie-handle tin))
- (type (cvs-fileinfo->type fileinfo)))
- (cond
- ((eq type 'MODIFIED)
- (require 'emerge)
- (let ((tmp-file
- (cvs-retrieve-revision-to-tmpfile fileinfo)))
- (unwind-protect
- (if (not (emerge-files
- t
- (cvs-fileinfo->full-path fileinfo)
- tmp-file
- (cvs-fileinfo->full-path fileinfo)))
- (error "Emerge session failed"))
- (delete-file tmp-file))))
-
- ((or (eq type 'MERGED)
- (eq type 'CONFLICT))
- (require 'emerge)
- (let ((tmp-file
- (cvs-retrieve-revision-to-tmpfile
- fileinfo))
- (ancestor-file
- (cvs-retrieve-revision-to-tmpfile
- fileinfo
- (cvs-fileinfo->base-revision fileinfo))))
- (unwind-protect
- (if (not (emerge-files-with-ancestor
- t
- (cvs-fileinfo->backup-file fileinfo)
- tmp-file
- ancestor-file
- (cvs-fileinfo->full-path fileinfo)))
- (error "Emerge session failed"))
- (delete-file tmp-file)
- (delete-file ancestor-file))))
- (t
- (error "Can only emerge \"Modified\", \"Merged\" or \"Conflict\"%s"
- " files"))))
- (error "There is no file to emerge."))))
-
-(defun cvs-retrieve-revision-to-tmpfile (fileinfo &optional revision)
- "Retrieve the latest revision of the file in FILEINFO to a temporary file.
-If second optional argument REVISION is given, retrieve that revision instead."
- (let
- ((temp-name (make-temp-name
- (concat (file-name-as-directory
- (or (getenv "TMPDIR") "/tmp"))
- "pcl-cvs." revision))))
- (cvs-kill-buffer-visiting temp-name)
- (if revision
- (message "Retrieving revision %s..." revision)
- (message "Retrieving latest revision..."))
- (let ((res (call-process cvs-shell nil nil nil "-c"
- (concat cvs-program " update -p "
- (if revision
- (concat "-r " revision " ")
- "")
- (cvs-fileinfo->full-path fileinfo)
- " > " temp-name))))
- (if (and res (not (and (integerp res) (zerop res))))
- (error "Something went wrong: %s" res))
-
- (if revision
- (message "Retrieving revision %s... Done." revision)
- (message "Retrieving latest revision... Done."))
- (find-file-noselect temp-name)
- temp-name)))
-
-(defun cvs-fileinfo->backup-file (fileinfo)
- "Construct the file name of the backup file for FILEINFO."
- (if (cvs-fileinfo->base-revision fileinfo)
- (concat cvs-bakprefix (cvs-fileinfo->file-name fileinfo)
- "." (cvs-fileinfo->base-revision fileinfo))))
-
-(defun cvs-kill-buffer-visiting (filename)
- "If there is any buffer visiting FILENAME, kill it (without confirmation)."
- (let ((l (buffer-list)))
- (while l
- (if (string= (buffer-file-name (car l)) filename)
- (kill-buffer (car l)))
- (setq l (cdr l)))))
-
-(defun cvs-change-cvsroot (newroot)
- "Change the cvsroot."
- (interactive "DNew repository: ")
- (if (or (file-directory-p (expand-file-name "CVSROOT" newroot))
- (y-or-n-p (concat "Warning: no CVSROOT found inside repository."
- " Change cvs-cvsroot anyhow?")))
- (setq cvs-cvsroot newroot)))
-
-(if (string-match "Lucid" emacs-version)
- (progn
- (autoload 'pcl-cvs-fontify "pcl-cvs-lucid")
- (add-hook 'cvs-mode-hook 'pcl-cvs-fontify)))
-
-
-(defvar cvs-changelog-full-paragraphs t
- "If non-nil, include full ChangeLog paragraphs in the CVS log.
-This may be set in the ``local variables'' section of a ChangeLog, to
-indicate the policy for that ChangeLog.
-
-A ChangeLog paragraph is a bunch of log text containing no blank lines;
-a paragraph usually describes a set of changes with a single purpose,
-but perhaps spanning several functions in several files. Changes in
-different paragraphs are unrelated.
-
-You could argue that the CVS log entry for a file should contain the
-full ChangeLog paragraph mentioning the change to the file, even though
-it may mention other files, because that gives you the full context you
-need to understand the change. This is the behavior you get when this
-variable is set to t.
-
-On the other hand, you could argue that the CVS log entry for a change
-should contain only the text for the changes which occurred in that
-file, because the CVS log is per-file. This is the behavior you get
-when this variable is set to nil.")
-
-(defun cvs-changelog-name (directory)
- "Return the name of the ChangeLog file that handles DIRECTORY.
-This is in DIRECTORY or one of its parents.
-Signal an error if we can't find an appropriate ChangeLog file."
- (let ((dir (file-name-as-directory directory))
- file)
- (while (and dir
- (not (file-exists-p
- (setq file (expand-file-name "ChangeLog" dir)))))
- (let ((last dir))
- (setq dir (file-name-directory (directory-file-name dir)))
- (if (equal last dir)
- (setq dir nil))))
- (or dir
- (error "Can't find ChangeLog for %s" directory))
- file))
-
-(defun cvs-narrow-changelog ()
- "Narrow to the top page of the current buffer, a ChangeLog file.
-Actually, the narrowed region doesn't include the date line.
-A \"page\" in a ChangeLog file is the area between two dates."
- (or (eq major-mode 'change-log-mode)
- (error "cvs-narrow-changelog: current buffer isn't a ChangeLog"))
-
- (goto-char (point-min))
-
- ;; Skip date line and subsequent blank lines.
- (forward-line 1)
- (if (looking-at "[ \t\n]*\n")
- (goto-char (match-end 0)))
-
- (let ((start (point)))
- (forward-page 1)
- (narrow-to-region start (point))
- (goto-char (point-min))))
-
-(defun cvs-changelog-paragraph ()
- "Return the bounds of the ChangeLog paragraph containing point.
-If we are between paragraphs, return the previous paragraph."
- (save-excursion
- (beginning-of-line)
- (if (looking-at "^[ \t]*$")
- (skip-chars-backward " \t\n" (point-min)))
- (list (progn
- (if (re-search-backward "^[ \t]*\n" nil 'or-to-limit)
- (goto-char (match-end 0)))
- (point))
- (if (re-search-forward "^[ \t\n]*$" nil t)
- (match-beginning 0)
- (point)))))
-
-(defun cvs-changelog-subparagraph ()
- "Return the bounds of the ChangeLog subparagraph containing point.
-A subparagraph is a block of non-blank lines beginning with an asterisk.
-If we are between subparagraphs, return the previous subparagraph."
- (save-excursion
- (end-of-line)
- (if (search-backward "*" nil t)
- (list (progn (beginning-of-line) (point))
- (progn
- (forward-line 1)
- (if (re-search-forward "^[ \t]*[\n*]" nil t)
- (match-beginning 0)
- (point-max))))
- (list (point) (point)))))
-
-(defun cvs-changelog-entry ()
- "Return the bounds of the ChangeLog entry containing point.
-The variable `cvs-changelog-full-paragraphs' decides whether an
-\"entry\" is a paragraph or a subparagraph; see its documentation string
-for more details."
- (if cvs-changelog-full-paragraphs
- (cvs-changelog-paragraph)
- (cvs-changelog-subparagraph)))
-
-(defun cvs-changelog-ours-p ()
- "See if ChangeLog entry at point is for the current user, today.
-Return non-nil iff it is."
- ;; Code adapted from add-change-log-entry.
- (looking-at (concat (regexp-quote (substring (current-time-string)
- 0 10))
- ".* "
- (regexp-quote (substring (current-time-string) -4))
- "[ \t]+"
- (regexp-quote (if (boundp 'add-log-full-name)
- add-log-full-name
- user-full-name))
- " <"
- (regexp-quote
- (if (boundp 'add-log-mailing-address)
- add-log-mailing-address
- user-mail-address)))))
-
-(defun cvs-relative-path (base child)
- "Return a directory path relative to BASE for CHILD.
-If CHILD doesn't seem to be in a subdirectory of BASE, just return
-the full path to CHILD."
- (let ((base (file-name-as-directory (expand-file-name base)))
- (child (expand-file-name child)))
- (or (string= base (substring child 0 (length base)))
- (error "cvs-relative-path: %s isn't in %s" child base))
- (substring child (length base))))
-
-(defun cvs-changelog-entries (file)
- "Return the ChangeLog entries for FILE, and the ChangeLog they came from.
-The return value looks like this:
- (LOGBUFFER (ENTRYSTART . ENTRYEND) ...)
-where LOGBUFFER is the name of the ChangeLog buffer, and each
-\(ENTRYSTART . ENTRYEND\) pair is a buffer region."
- (save-excursion
- (set-buffer (find-file-noselect
- (cvs-changelog-name
- (file-name-directory
- (expand-file-name file)))))
- (or (eq major-mode 'change-log-mode)
- (change-log-mode))
- (goto-char (point-min))
- (if (looking-at "[ \t\n]*\n")
- (goto-char (match-end 0)))
- (if (not (cvs-changelog-ours-p))
- (list (current-buffer))
- (save-restriction
- (cvs-narrow-changelog)
- (goto-char (point-min))
-
- ;; Search for the name of FILE relative to the ChangeLog. If that
- ;; doesn't occur anywhere, they're not using full relative
- ;; filenames in the ChangeLog, so just look for FILE; we'll accept
- ;; some false positives.
- (let ((pattern (cvs-relative-path
- (file-name-directory buffer-file-name) file)))
- (if (or (string= pattern "")
- (not (save-excursion
- (search-forward pattern nil t))))
- (setq pattern file))
-
- (let (texts)
- (while (search-forward pattern nil t)
- (let ((entry (cvs-changelog-entry)))
- (setq texts (cons entry texts))
- (goto-char (elt entry 1))))
-
- (cons (current-buffer) texts)))))))
-
-(defun cvs-changelog-insert-entries (buffer regions)
- "Insert those regions in BUFFER specified in REGIONS.
-Sort REGIONS front-to-back first."
- (let ((regions (sort regions 'car-less-than-car))
- (last))
- (while regions
- (if (and last (< last (car (car regions))))
- (newline))
- (setq last (elt (car regions) 1))
- (apply 'insert-buffer-substring buffer (car regions))
- (setq regions (cdr regions)))))
-
-(defun cvs-union (set1 set2)
- "Return the union of SET1 and SET2, according to `equal'."
- (while set2
- (or (member (car set2) set1)
- (setq set1 (cons (car set2) set1)))
- (setq set2 (cdr set2)))
- set1)
-
-(defun cvs-insert-changelog-entries (files)
- "Given a list of files FILES, insert the ChangeLog entries for them."
- (let ((buffer-entries nil))
-
- ;; Add each buffer to buffer-entries, and associate it with the list
- ;; of entries we want from that file.
- (while files
- (let* ((entries (cvs-changelog-entries (car files)))
- (pair (assq (car entries) buffer-entries)))
- (if pair
- (setcdr pair (cvs-union (cdr pair) (cdr entries)))
- (setq buffer-entries (cons entries buffer-entries))))
- (setq files (cdr files)))
-
- ;; Now map over each buffer in buffer-entries, sort the entries for
- ;; each buffer, and extract them as strings.
- (while buffer-entries
- (cvs-changelog-insert-entries (car (car buffer-entries))
- (cdr (car buffer-entries)))
- (if (and (cdr buffer-entries) (cdr (car buffer-entries)))
- (newline))
- (setq buffer-entries (cdr buffer-entries)))))
-
-(defun cvs-edit-delete-common-indentation ()
- "Unindent the current buffer rigidly until at least one line is flush left."
- (save-excursion
- (let ((common 100000))
- (goto-char (point-min))
- (while (< (point) (point-max))
- (if (not (looking-at "^[ \t]*$"))
- (setq common (min common (current-indentation))))
- (forward-line 1))
- (indent-rigidly (point-min) (point-max) (- common)))))
-
-(defun cvs-mode-changelog-commit ()
-
- "Check in all marked files, or the current file.
-Ask the user for a log message in a buffer.
-
-This is just like `\\[cvs-mode-commit]', except that it tries to provide
-appropriate default log messages by looking at the ChangeLogs. The
-idea is to write your ChangeLog entries first, and then use this
-command to commit your changes.
-
-To select default log text, we:
-- find the ChangeLogs for the files to be checked in,
-- verify that the top entry in the ChangeLog is on the current date
- and by the current user; if not, we don't provide any default text,
-- search the ChangeLog entry for paragraphs containing the names of
- the files we're checking in, and finally
-- use those paragraphs as the log text."
-
- (interactive)
-
- (let* ((cvs-buf (current-buffer))
- (marked (cvs-filter (function cvs-committable)
- (cvs-get-marked))))
- (if (null marked)
- (error "Nothing to commit!")
- (pop-to-buffer (get-buffer-create cvs-commit-prompt-buffer))
- (goto-char (point-min))
-
- (erase-buffer)
- (cvs-insert-changelog-entries
- (mapcar (lambda (tin)
- (let ((cookie (tin-cookie cvs-cookie-handle tin)))
- (expand-file-name
- (cvs-fileinfo->file-name cookie)
- (cvs-fileinfo->dir cookie))))
- marked))
- (cvs-edit-delete-common-indentation)
-
- (cvs-edit-mode)
- (make-local-variable 'cvs-commit-list)
- (setq cvs-commit-list marked)
- (message "Press C-c C-c when you are done editing."))))
diff --git a/gnu/usr.bin/cvs/contrib/pcl-cvs/pcl-cvs.texinfo b/gnu/usr.bin/cvs/contrib/pcl-cvs/pcl-cvs.texinfo
deleted file mode 100644
index bb0a4fec3d80..000000000000
--- a/gnu/usr.bin/cvs/contrib/pcl-cvs/pcl-cvs.texinfo
+++ /dev/null
@@ -1,1744 +0,0 @@
-\input texinfo @c -*-texinfo-*-
-
-@comment Id: pcl-cvs.texinfo,v 1.45 1993/05/31 22:38:15 ceder Exp
-@comment Documentation for the GNU Emacs CVS mode.
-@comment Copyright (C) 1992 Per Cederqvist
-
-@comment This file is part of the pcl-cvs distribution.
-
-@comment Pcl-cvs is free software; you can redistribute it and/or modify
-@comment it under the terms of the GNU General Public License as published by
-@comment the Free Software Foundation; either version 1, or (at your option)
-@comment any later version.
-
-@comment Pcl-cvs is distributed in the hope that it will be useful,
-@comment but WITHOUT ANY WARRANTY; without even the implied warranty of
-@comment MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-@comment GNU General Public License for more details.
-
-@comment You should have received a copy of the GNU General Public License
-@comment along with pcl-cvs; see the file COPYING. If not, write to
-@comment the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
-@setfilename pcl-cvs.info
-@settitle Pcl-cvs - The Emacs Front-End to CVS
-@setchapternewpage on
-
-@ifinfo
-Copyright @copyright{} 1992 Per Cederqvist
-
-Permission is granted to make and distribute verbatim copies of
-this manual provided the copyright notice and this permission notice
-are preserved on all copies.
-
-@ignore
-Permission is granted to process this file through Tex and print the
-results, provided the printed document carries copying permission
-notice identical to this one except for the removal of this paragraph
-(this paragraph not being relevant to the printed manual).
-
-@end ignore
-Permission is granted to copy and distribute modified versions of this
-manual under the conditions for verbatim copying, provided also that the
-section entitled ``GNU General Public License'' is included exactly as
-in the original, and provided that the entire resulting derived work is
-distributed under the terms of a permission notice identical to this one.
-
-Permission is granted to copy and distribute translations of this manual
-into another language, under the above conditions for modified versions,
-except that the section entitled ``GNU General Public License'' and
-this permission notice may be included in translations approved by the
-Free Software Foundation instead of in the original English.
-@end ifinfo
-
-@synindex vr fn
-@comment The titlepage section does not appear in the Info file.
-@titlepage
-@sp 4
-@comment The title is printed in a large font.
-@center @titlefont{User's Guide}
-@sp
-@center @titlefont{to}
-@sp
-@center @titlefont{pcl-cvs - the Emacs Front-End to CVS}
-@sp 2
-@center release 1.05
-@comment -release-
-@sp 3
-@center Per Cederqvist
-@sp 3
-@center last updated 31 May 1993
-@comment -date-
-
-@comment The following two commands start the copyright page
-@comment for the printed manual. This will not appear in the Info file.
-@page
-@vskip 0pt plus 1filll
-Copyright @copyright{} 1992 Per Cederqvist
-
-Permission is granted to make and distribute verbatim copies of
-this manual provided the copyright notice and this permission notice
-are preserved on all copies.
-
-Permission is granted to copy and distribute modified versions of this
-manual under the conditions for verbatim copying, provided also that the
-section entitled ``GNU General Public License'' is included exactly as
-in the original, and provided that the entire resulting derived work is
-distributed under the terms of a permission notice identical to this one.
-
-Permission is granted to copy and distribute translations of this manual
-into another language, under the above conditions for modified versions,
-except that the section entitled ``GNU General Public License'' and
-this permission notice may be included in translations approved by the
-Free Software Foundation instead of in the original English.
-@end titlepage
-
-@comment ================================================================
-@comment The real text starts here
-@comment ================================================================
-
-@node Top, Copying, (dir), (dir)
-@comment node-name, next, previous, up
-
-
-@ifinfo
-This info manual describes pcl-cvs which is a GNU Emacs front-end to
-CVS. It works with CVS version 1.3. This manual is updated to release
-1.05 of pcl-cvs.
-@end ifinfo
-@comment -release-
-
-@menu
-* Copying:: GNU General Public License
-* Installation:: How to install pcl-cvs on your system.
-* About pcl-cvs:: Authors and ftp sites.
-
-* Getting started:: An introduction with a walk-through example.
-* Buffer contents:: An explanation of the buffer contents.
-* Commands:: All commands, grouped by type.
-
-* Customization:: How you can tailor pcl-cvs to suit your needs.
-* Future enhancements:: Future enhancements of pcl-cvs.
-* Bugs:: Bugs (known and unknown).
-* Function and Variable Index:: List of functions and variables.
-* Concept Index:: List of concepts.
-* Key Index:: List of keystrokes.
-
- --- The Detailed Node Listing ---
-
-Installation
-
-* Pcl-cvs installation:: How to install pcl-cvs on your system.
-* On-line manual installation:: How to install the on-line manual.
-* Typeset manual installation:: How to create typeset documentation
- about pcl-cvs.
-
-About pcl-cvs
-
-* Contributors:: Contributors to pcl-cvs.
-* Archives:: Where can I get a copy of Pcl-Cvs?
-
-Buffer contents
-
-* File status:: The meaning of the second field.
-* Selected files:: How selection works.
-
-Commands
-
-* Updating the directory:: Commands to update the local directory
-* Movement commands:: How to move up and down in the buffer
-* Marking files:: How to mark files that other commands
- will later operate on.
-* Committing changes:: Checking in your modifications to the
- CVS repository.
-* Editing files:: Loading files into Emacs.
-* Getting info about files:: Display the log and status of files.
-* Adding and removing files:: Adding and removing files
-* Undoing changes:: Undoing changes
-* Removing handled entries:: Uninteresting lines can easily be removed.
-* Ignoring files:: Telling CVS to ignore generated files.
-* Viewing differences:: Commands to @samp{diff} different versions.
-* Emerge::
-* Reverting your buffers:: Reverting your buffers
-* Miscellaneous commands:: Miscellaneous commands
-@end menu
-
-@node Copying, Installation, Top, Top
-@unnumbered GNU GENERAL PUBLIC LICENSE
-@center Version 2, June 1991
-
-@display
-Copyright @copyright{} 1989, 1991 Free Software Foundation, Inc.
-675 Mass Ave, Cambridge, MA 02139, USA
-
-Everyone is permitted to copy and distribute verbatim copies
-of this license document, but changing it is not allowed.
-@end display
-
-@unnumberedsec Preamble
-
- The licenses for most software are designed to take away your
-freedom to share and change it. By contrast, the GNU General Public
-License is intended to guarantee your freedom to share and change free
-software---to make sure the software is free for all its users. This
-General Public License applies to most of the Free Software
-Foundation's software and to any other program whose authors commit to
-using it. (Some other Free Software Foundation software is covered by
-the GNU Library General Public License instead.) You can apply it to
-your programs, too.
-
- When we speak of free software, we are referring to freedom, not
-price. Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-this service if you wish), that you receive source code or can get it
-if you want it, that you can change the software or use pieces of it
-in new free programs; and that you know you can do these things.
-
- To protect your rights, we need to make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if you
-distribute copies of the software, or if you modify it.
-
- For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must give the recipients all the rights that
-you have. You must make sure that they, too, receive or can get the
-source code. And you must show them these terms so they know their
-rights.
-
- We protect your rights with two steps: (1) copyright the software, and
-(2) offer you this license which gives you legal permission to copy,
-distribute and/or modify the software.
-
- Also, for each author's protection and ours, we want to make certain
-that everyone understands that there is no warranty for this free
-software. If the software is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original, so
-that any problems introduced by others will not reflect on the original
-authors' reputations.
-
- Finally, any free program is threatened constantly by software
-patents. We wish to avoid the danger that redistributors of a free
-program will individually obtain patent licenses, in effect making the
-program proprietary. To prevent this, we have made it clear that any
-patent must be licensed for everyone's free use or not licensed at all.
-
- The precise terms and conditions for copying, distribution and
-modification follow.
-
-@iftex
-@unnumberedsec TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-@end iftex
-@ifinfo
-@center TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-@end ifinfo
-
-@enumerate
-@item
-This License applies to any program or other work which contains
-a notice placed by the copyright holder saying it may be distributed
-under the terms of this General Public License. The ``Program'', below,
-refers to any such program or work, and a ``work based on the Program''
-means either the Program or any derivative work under copyright law:
-that is to say, a work containing the Program or a portion of it,
-either verbatim or with modifications and/or translated into another
-language. (Hereinafter, translation is included without limitation in
-the term ``modification''.) Each licensee is addressed as ``you''.
-
-Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope. The act of
-running the Program is not restricted, and the output from the Program
-is covered only if its contents constitute a work based on the
-Program (independent of having been made by running the Program).
-Whether that is true depends on what the Program does.
-
-@item
-You may copy and distribute verbatim copies of the Program's
-source code as you receive it, in any medium, provided that you
-conspicuously and appropriately publish on each copy an appropriate
-copyright notice and disclaimer of warranty; keep intact all the
-notices that refer to this License and to the absence of any warranty;
-and give any other recipients of the Program a copy of this License
-along with the Program.
-
-You may charge a fee for the physical act of transferring a copy, and
-you may at your option offer warranty protection in exchange for a fee.
-
-@item
-You may modify your copy or copies of the Program or any portion
-of it, thus forming a work based on the Program, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
-@enumerate a
-@item
-You must cause the modified files to carry prominent notices
-stating that you changed the files and the date of any change.
-
-@item
-You must cause any work that you distribute or publish, that in
-whole or in part contains or is derived from the Program or any
-part thereof, to be licensed as a whole at no charge to all third
-parties under the terms of this License.
-
-@item
-If the modified program normally reads commands interactively
-when run, you must cause it, when started running for such
-interactive use in the most ordinary way, to print or display an
-announcement including an appropriate copyright notice and a
-notice that there is no warranty (or else, saying that you provide
-a warranty) and that users may redistribute the program under
-these conditions, and telling the user how to view a copy of this
-License. (Exception: if the Program itself is interactive but
-does not normally print such an announcement, your work based on
-the Program is not required to print an announcement.)
-@end enumerate
-
-These requirements apply to the modified work as a whole. If
-identifiable sections of that work are not derived from the Program,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works. But when you
-distribute the same sections as part of a whole which is a work based
-on the Program, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Program.
-
-In addition, mere aggregation of another work not based on the Program
-with the Program (or with a work based on the Program) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
-@item
-You may copy and distribute the Program (or a work based on it,
-under Section 2) in object code or executable form under the terms of
-Sections 1 and 2 above provided that you also do one of the following:
-
-@enumerate a
-@item
-Accompany it with the complete corresponding machine-readable
-source code, which must be distributed under the terms of Sections
-1 and 2 above on a medium customarily used for software interchange; or,
-
-@item
-Accompany it with a written offer, valid for at least three
-years, to give any third party, for a charge no more than your
-cost of physically performing source distribution, a complete
-machine-readable copy of the corresponding source code, to be
-distributed under the terms of Sections 1 and 2 above on a medium
-customarily used for software interchange; or,
-
-@item
-Accompany it with the information you received as to the offer
-to distribute corresponding source code. (This alternative is
-allowed only for noncommercial distribution and only if you
-received the program in object code or executable form with such
-an offer, in accord with Subsection b above.)
-@end enumerate
-
-The source code for a work means the preferred form of the work for
-making modifications to it. For an executable work, complete source
-code means all the source code for all modules it contains, plus any
-associated interface definition files, plus the scripts used to
-control compilation and installation of the executable. However, as a
-special exception, the source code distributed need not include
-anything that is normally distributed (in either source or binary
-form) with the major components (compiler, kernel, and so on) of the
-operating system on which the executable runs, unless that component
-itself accompanies the executable.
-
-If distribution of executable or object code is made by offering
-access to copy from a designated place, then offering equivalent
-access to copy the source code from the same place counts as
-distribution of the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
-@item
-You may not copy, modify, sublicense, or distribute the Program
-except as expressly provided under this License. Any attempt
-otherwise to copy, modify, sublicense or distribute the Program is
-void, and will automatically terminate your rights under this License.
-However, parties who have received copies, or rights, from you under
-this License will not have their licenses terminated so long as such
-parties remain in full compliance.
-
-@item
-You are not required to accept this License, since you have not
-signed it. However, nothing else grants you permission to modify or
-distribute the Program or its derivative works. These actions are
-prohibited by law if you do not accept this License. Therefore, by
-modifying or distributing the Program (or any work based on the
-Program), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Program or works based on it.
-
-@item
-Each time you redistribute the Program (or any work based on the
-Program), the recipient automatically receives a license from the
-original licensor to copy, distribute or modify the Program subject to
-these terms and conditions. You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties to
-this License.
-
-@item
-If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Program at all. For example, if a patent
-license would not permit royalty-free redistribution of the Program by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Program.
-
-If any portion of this section is held invalid or unenforceable under
-any particular circumstance, the balance of the section is intended to
-apply and the section as a whole is intended to apply in other
-circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system, which is
-implemented by public license practices. Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
-@item
-If the distribution and/or use of the Program is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Program under this License
-may add an explicit geographical distribution limitation excluding
-those countries, so that distribution is permitted only in or among
-countries not thus excluded. In such case, this License incorporates
-the limitation as if written in the body of this License.
-
-@item
-The Free Software Foundation may publish revised and/or new versions
-of the General Public License from time to time. Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-Each version is given a distinguishing version number. If the Program
-specifies a version number of this License which applies to it and ``any
-later version'', you have the option of following the terms and conditions
-either of that version or of any later version published by the Free
-Software Foundation. If the Program does not specify a version number of
-this License, you may choose any version ever published by the Free Software
-Foundation.
-
-@item
-If you wish to incorporate parts of the Program into other free
-programs whose distribution conditions are different, write to the author
-to ask for permission. For software which is copyrighted by the Free
-Software Foundation, write to the Free Software Foundation; we sometimes
-make exceptions for this. Our decision will be guided by the two goals
-of preserving the free status of all derivatives of our free software and
-of promoting the sharing and reuse of software generally.
-
-@iftex
-@heading NO WARRANTY
-@end iftex
-@ifinfo
-@center NO WARRANTY
-@end ifinfo
-
-@item
-BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
-FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
-OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
-PROVIDE THE PROGRAM ``AS IS'' WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
-OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
-TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
-PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
-REPAIR OR CORRECTION.
-
-@item
-IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
-REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
-INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
-OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
-TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
-YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
-PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGES.
-@end enumerate
-
-@iftex
-@heading END OF TERMS AND CONDITIONS
-@end iftex
-@ifinfo
-@center END OF TERMS AND CONDITIONS
-@end ifinfo
-
-@page
-@unnumberedsec Appendix: How to Apply These Terms to Your New Programs
-
- If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
- To do so, attach the following notices to the program. It is safest
-to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least
-the ``copyright'' line and a pointer to where the full notice is found.
-
-@smallexample
-@var{one line to give the program's name and a brief idea of what it does.}
-Copyright (C) 19@var{yy} @var{name of author}
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-@end smallexample
-
-Also add information on how to contact you by electronic and paper mail.
-
-If the program is interactive, make it output a short notice like this
-when it starts in an interactive mode:
-
-@smallexample
-Gnomovision version 69, Copyright (C) 19@var{yy} @var{name of author}
-Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
-This is free software, and you are welcome to redistribute it
-under certain conditions; type `show c' for details.
-@end smallexample
-
-The hypothetical commands @samp{show w} and @samp{show c} should show
-the appropriate parts of the General Public License. Of course, the
-commands you use may be called something other than @samp{show w} and
-@samp{show c}; they could even be mouse-clicks or menu items---whatever
-suits your program.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a ``copyright disclaimer'' for the program, if
-necessary. Here is a sample; alter the names:
-
-@example
-Yoyodyne, Inc., hereby disclaims all copyright interest in the program
-`Gnomovision' (which makes passes at compilers) written by James Hacker.
-
-@var{signature of Ty Coon}, 1 April 1989
-Ty Coon, President of Vice
-@end example
-
-This General Public License does not permit incorporating your program into
-proprietary programs. If your program is a subroutine library, you may
-consider it more useful to permit linking proprietary applications with the
-library. If this is what you want to do, use the GNU Library General
-Public License instead of this License.
-
-@node Installation, About pcl-cvs, Copying, Top
-@comment node-name, next, previous, up
-@chapter Installation
-@cindex Installation
-
-This section describes the installation of pcl-cvs, the GNU Emacs CVS
-front-end. You should install not only the elisp files themselves, but
-also the on-line documentation so that your users will know how to use
-it. You can create typeset documentation from the file
-@file{pcl-cvs.texinfo} as well as an on-line info file. The following
-steps are also described in the file @file{INSTALL} in the source
-directory.
-
-@menu
-* Pcl-cvs installation:: How to install pcl-cvs on your system.
-* On-line manual installation:: How to install the on-line manual.
-* Typeset manual installation:: How to create typeset documentation
- about pcl-cvs.
-@end menu
-
-@node Pcl-cvs installation, On-line manual installation, Installation, Installation
-@comment node-name, next, previous, up
-@section Installation of the pcl-cvs program
-@cindex Installation of elisp files
-
-@enumerate
-@item
-Edit the file @file{Makefile} to reflect the situation at your site.
-The only things you have to change is the definition of @code{lispdir}
-and @code{infodir}. The elisp files will be copied to @code{lispdir},
-and the info file to @code{infodir}.
-
-@item
-Configure pcl-cvs.el
-
-There are a couple of paths that you have to check to make sure that
-they match you system. They appear early in the file pcl-cvs.el.
-
-@strong{NOTE:} If your system is running emacs 18.57 or earlier you MUST
-uncomment the line that says:
-
-@example
-(setq delete-exited-processes nil)
-@end example
-
-Setting @code{delete-exited-processes} to @code{nil} works around a bug
-in emacs that causes it to dump core. The bug was fixed in emacs
-18.58.@refill
-
-@item
-Release 1.05 and later of pcl-cvs requires parts of the Elib library,
-version 0.07 or later. Elib is available via anonymous ftp from
-prep.ai.mit.edu in @file{pub/gnu/elib-0.07.tar.z}, and from a lot of
-other sites that mirrors prep. Get Elib, and install it, before
-proceeding.
-
-@item
-Type @samp{make install} in the source directory. This will
-byte-compile all @file{.el} files and copy both the @file{.el} and the
-@file{.elc} into the directory you specified in step 1.
-
-If you don't want to install the @file{.el} files but only the
-@file{.elc} files (the byte-compiled files), you can type `@samp{make
-install_elc}' instead of `@samp{make install}'.
-
-If you only want to create the compiled elisp files, but don't want to
-install them, you can type @samp{make elcfiles} instead. This is what
-happens if you only type @samp{make} without parameters.
-
-@item
-Edit the file @file{default.el} in your emacs lisp directory (usually
-@file{/usr/gnu/emacs/lisp} or something similar) and enter the contents
-of the file @file{pcl-cvs-startup.el} into it. It contains a couple of
-@code{auto-load}s that facilitates the use of pcl-cvs.
-
-@end enumerate
-
-@node On-line manual installation, Typeset manual installation, Pcl-cvs installation, Installation
-@comment node-name, next, previous, up
-@section Installation of the on-line manual.
-@cindex Manual installation (on-line)
-@cindex Installation of on-line manual
-@cindex Generating the on-line manual
-@cindex On-line manual (how to generate)
-@cindex Info-file (how to generate)
-
-@enumerate
-@item
-Create the info file @file{pcl-cvs} from @file{pcl-cvs.texinfo} by
-typing @samp{make info}. If you don't have the program @samp{makeinfo}
-you can get it by anonymous ftp from e.g. @samp{ftp.gnu.ai.mit.edu} as
-@file{pub/gnu/texinfo-2.14.tar.Z} (there might be a newer version there
-when you read this), or you could use the preformatted info file
-@file{pcl-cvs.info} that is included in the distribution (type
-@samp{cp pcl-cvs.info pcl-cvs}).@refill
-
-@item
-Move the info file @file{pcl-cvs} to your standard info directory.
-This might be called something like @file{/usr/gnu/emacs/info}.@refill
-
-@item
-Edit the file @file{dir} in the info directory and enter one line to
-contain a pointer to the info file @file{pcl-cvs}. The line can, for
-instance, look like this:@refill
-
-@example
-* Pcl-cvs: (pcl-cvs). An Emacs front-end to CVS.
-@end example
-@end enumerate
-
-@node Typeset manual installation, , On-line manual installation, Installation
-@comment node-name, next, previous, up
-@section How to make typeset documentation from pcl-cvs.texinfo
-@cindex Manual installation (typeset)
-@cindex Installation of typeset manual
-@cindex Printing a manual
-@cindex TeX - generating a typeset manual
-@cindex Generating a typeset manual
-
-If you have @TeX{} installed at your site, you can make a typeset manual
-from @file{pcl-cvs.texinfo}.
-
-@enumerate
-@item
-Run @TeX{} by typing `@samp{make pcl-cvs.dvi}'. You will not get the
-indices unless you have the @code{texindex} program.
-
-@item
-Convert the resulting device independent file @file{pcl-cvs.dvi} to a
-form which your printer can output and print it. If you have a
-postscript printer there is a program, @code{dvi2ps}, which does. There
-is also a program which comes together with @TeX{}, @code{dvips}, which
-you can use.
-
-@end enumerate
-
-@node About pcl-cvs, Getting started, Installation, Top
-@comment node-name, next, previous, up
-@chapter About pcl-cvs
-@cindex About pcl-cvs
-
-Pcl-cvs is a front-end to CVS version 1.3. It integrates the most
-frequently used CVS commands into emacs.
-
-@menu
-* Contributors:: Contributors to pcl-cvs.
-* Archives:: Where can I get a copy of Pcl-Cvs?
-@end menu
-
-@node Contributors, Archives, About pcl-cvs, About pcl-cvs
-@comment node-name, next, previous, up
-@section Contributors to pcl-cvs
-@cindex Contributors
-@cindex Authors
-
-Contributions to the package are welcome. I have limited time to work
-on this project, but I will gladly add any code that you contribute to
-me to this package (@pxref{Bugs}).
-
-The following persons have made contributions to pcl-cvs.
-
-@itemize @bullet
-@item
-Brian Berliner wrote CVS, together with some other contributors.
-Without his work on CVS this package would be useless@dots{}
-
-@item
-Per Cederqvist wrote most of the otherwise unattributed functions in
-pcl-cvs as well as all documentation.
-
-@item
-Inge Wallin (@samp{inge@@lysator.liu.se}) wrote the skeleton to
-@file{pcl-cvs.texinfo}, and gave useful comments on it. He also wrote
-the files @file{elib-node.el} and @file{compile-all.el}. The file
-@file{cookie.el} was inspired by Inge.@refill
-
-@item
-Linus Tolke (@samp{linus@@lysator.liu.se}) contributed useful comments
-on both the functionality and the documentation.@refill
-
-@item
-Jamie Zawinski (@samp{jwz@@lucid.com}) contributed
-@file{pcl-cvs-lucid.el}.
-
-@item
-Leif Lonnblad contributed RCVS support.
-@end itemize
-
-Apart from these, a lot of people have send me suggestions, ideas,
-requests, bug reports and encouragement. Thanks a lot! Without your
-there would be no new releases of pcl-cvs.
-
-@node Archives, , Contributors, About pcl-cvs
-@comment node-name, next, previous, up
-@section Where can I get pcl-cvs?
-@cindex Sites
-@cindex Archives
-@cindex Ftp-sites
-@cindex Getting pcl-cvs
-@cindex Email archives
-
-The latest release of pcl-cvs can be fetched via anonymous ftp from
-@code{ftp.lysator.liu.se}, (IP no. 130.236.254.1) in the directory
-@code{pub/emacs}. If you don't live in Scandinavia you should probably
-check with archie to see if there is a site closer to you that archives
-pcl-cvs.
-
-New releases will be announced to appropriate newsgroups. If you send
-your email address to me I will add you to my list of people to mail
-when I make a new release.
-
-@node Getting started, Buffer contents, About pcl-cvs, Top
-@comment node-name, next, previous, up
-@chapter Getting started
-@cindex Introduction
-@cindex Example run
-
-This document assumes that you know what CVS is, and that you at least
-knows the fundamental concepts of CVS. If that is not the case you
-should read the man page for CVS.
-
-Pcl-cvs is only useful once you have checked out a module. So before
-you invoke it you must have a copy of a module somewhere in the file
-system.
-
-You invoke pcl-cvs by typing @kbd{M-x cvs-update RET}. If your emacs
-responds with @samp{[No match]} your system administrator has not
-installed pcl-cvs properly. Try @kbd{M-x load-library RET pcl-cvs RET}.
-If that also fails - talk to your root. If it succeeds you might put
-this line in your @file{.emacs} file so that you don't have to type the
-@samp{load-library} command every time you wish to use pcl-cvs:
-
-@example
-(autoload 'cvs-update "pcl-cvs" nil t)
-@end example
-
-The function @code{cvs-update} will ask for a directory. The command
-@samp{cvs update} will be run in that directory. (It should contain
-files that have been checked out from a CVS archive.) The output from
-@code{cvs} will be parsed and presented in a table in a buffer called
-@samp{*cvs*}. It might look something like this:
-
-@example
-PCL-CVS release 1.05.
-@comment -release-
-
-In directory /users/ceder/FOO/test:
- Updated bar
- Updated file.txt
- Modified ci namechange
- Updated newer
-
-In directory /users/ceder/FOO/test/sub:
- Modified ci ChangeLog
----------- End -----
-@end example
-
-In this example the three files (@file{bar}, @file{file.txt} and
-@file{newer}) that are marked with @samp{Updated} have been copied from
-the CVS repository to @file{/users/ceder/FOO/test/} since someone else
-have checked in newer versions of them. Two files (@file{namechange}
-and @file{sub/ChangeLog}) have been modified locally, and needs to be
-checked in.
-
-You can move the cursor up and down in the buffer with @kbd{C-n} and
-@kbd{C-p} or @kbd{n} and @kbd{p}. If you press @kbd{c} on one of the
-@samp{Modified} files that file will be checked in to the CVS
-repository. @xref{Committing changes}. You can press @kbd{x} to get rid
-of the "uninteresting" files that have only been @samp{Updated} (and
-don't require any further action from you).@refill
-
-You can also easily get a @samp{diff} between your modified file and the
-base version that you started from, and you can get the output from
-@samp{cvs log} and @samp{cvs status} on the listed files simply by
-pressing a key (@pxref{Getting info about files}).
-
-@node Buffer contents, Commands, Getting started, Top
-@comment node-name, next, previous, up
-@chapter Buffer contents
-@cindex Buffer contents
-
-The display contains four columns. They contain, from left to right:
-
-@itemize @bullet
-@item
-An asterisk when the file is @dfn{marked} (@pxref{Selected
-files}).@refill
-@item
-The status of the file. See @xref{File status}, for more information.@refill
-@item
-A "need to be checked in"-marker (@samp{ci}).
-@item
-The file name.
-@end itemize
-
-@menu
-* File status:: The meaning of the second field.
-* Selected files:: How selection works.
-@end menu
-
-@node File status, Selected files, Buffer contents, Buffer contents
-@comment node-name, next, previous, up
-@section File status
-@cindex File status
-@cindex Updated (file status)
-@cindex Modified (file status)
-@cindex Merged (file status)
-@cindex Conflict (file status)
-@cindex Added (file status)
-@cindex Removed (file status)
-@cindex Unknown (file status)
-@cindex Removed from repository (file status)
-@cindex Removed from repository, changed by you (file status)
-@cindex Removed by you, changed in repository (file status)
-@cindex Move away @var{file} - it is in the way (file status)
-@cindex This repository is missing!@dots{} (file status)
-
-The @samp{file status} field can have the following values:
-
-@table @samp
-@item Updated
-The file was brought up to date with respect to the repository. This is
-done for any file that exists in the repository but not in your source,
-and for files that you haven't changed but are not the most recent
-versions available in the repository.@refill
-
-@item Modified
-The file is modified in your working directory, and there was no
-modification to the same file in the repository.@refill
-
-@item Merged
-The file is modified in your working directory, and there were
-modifications in the repository as well as in your copy, but they were
-merged successfully, without conflict, in your working directory.@refill
-
-@item Conflict
-A conflict was detected while trying to merge your changes to @var{file}
-with changes from the source repository. @var{file} (the copy in your
-working directory) is now the output of the @samp{rcsmerge} command on
-the two versions; an unmodified copy of your file is also in your
-working directory, with the name @file{.#@var{file}.@var{version}},
-where @var{version} is the RCS revision that your modified file started
-from. @xref{Viewing differences}, for more details.@refill
-
-@item Added
-The file has been added by you, but it still needs to be checked in to
-the repository.@refill
-
-@item Removed
-The file has been removed by you, but it needs to be checked in to the
-repository. You can resurrect it by typing @kbd{a} (@pxref{Adding and
-removing files}).@refill
-
-@item Unknown
-A file that was detected in your directory, but that neither appears in
-the repository, nor is present on the list of files that CVS should
-ignore.@refill
-
-@end table
-
-There are also a few special cases, that rarely occur, which have longer
-strings in the fields:
-
-@table @samp
-@item Removed from repository
-The file has been removed from your directory since someone has removed
-it from the repository. (It is still present in the Attic directory, so
-no permanent loss has occurred). This, unlike the other entries in this
-table, is not an error condition.@refill
-
-@item Removed from repository, changed by you
-You have modified a file that someone have removed from the repository.
-You can correct this situation by removing the file manually (see
-@pxref{Adding and removing files}).@refill
-
-@item Removed by you, changed in repository
-You have removed a file, and before you committed the removal someone
-committed a change to that file. You could use @kbd{a} to resurrect the
-file (see @pxref{Adding and removing files}).@refill
-
-@item Move away @var{file} - it is in the way
-For some reason CVS does not like the file @var{file}. Rename or remove
-it.@refill
-
-@item This repository is missing! Remove this dir manually.
-It is impossible to remove a directory in the CVS repository in a clean
-way. Someone have tried to remove one, and CVS gets confused. Remove
-your copy of the directory.@refill
-@end table
-
-@node Selected files, , File status, Buffer contents
-@comment node-name, next, previous, up
-@section Selected files
-@cindex Selected files
-@cindex Marked files
-@cindex File selection
-@cindex Active files
-
-Many of the commands works on the current set of @dfn{selected} files.
-
-@itemize @bullet
-@item
-If there are any files that are marked they constitute the set of
-selected files.@refill
-@item
-Otherwise, if the cursor points to a file, that file is the selected
-file.@refill
-@item
-Otherwise, if the cursor points to a directory, all the files in that
-directory that appears in the buffer are the selected files.
-@end itemize
-
-This scheme might seem a little complicated, but once one get used to
-it, it is quite powerful.
-
-@xref{Marking files} tells how you mark and unmark files.
-
-@node Commands, Customization, Buffer contents, Top
-@comment node-name, next, previous, up
-@chapter Commands
-
-@iftex
-This chapter describes all the commands that you can use in pcl-cvs.
-@end iftex
-@ifinfo
-The nodes in this menu contains explanations about all the commands that
-you can use in pcl-cvs. They are grouped together by type.
-@end ifinfo
-
-@menu
-* Updating the directory:: Commands to update the local directory
-* Movement commands:: How to move up and down in the buffer
-* Marking files:: How to mark files that other commands
- will later operate on.
-* Committing changes:: Checking in your modifications to the
- CVS repository.
-* Editing files:: Loading files into Emacs.
-* Getting info about files:: Display the log and status of files.
-* Adding and removing files:: Adding and removing files
-* Undoing changes:: Undoing changes
-* Removing handled entries:: Uninteresting lines can easily be removed.
-* Ignoring files:: Telling CVS to ignore generated files.
-* Viewing differences:: Commands to @samp{diff} different versions.
-* Emerge::
-* Reverting your buffers:: Reverting your buffers
-* Miscellaneous commands:: Miscellaneous commands
-@end menu
-
-@node Updating the directory, Movement commands, Commands, Commands
-@comment node-name, next, previous, up
-@section Updating the directory
-@findex cvs-update
-@findex cvs-mode-update-no-prompt
-@findex cvs-delete-lock
-@cindex Getting the *cvs* buffer
-@kindex g - Rerun @samp{cvs update}
-
-
-@table @kbd
-
-@item M-x cvs-update
-Run a @samp{cvs update} command. You will be asked for the directory in
-which the @samp{cvs update} will be run. The output will be parsed by
-pcl-cvs, and the result printed in the @samp{*cvs*} buffer (see
-@pxref{Buffer contents} for a description of the contents).@refill
-
-By default, @samp{cvs-update} will descend recursively into
-subdirectories. You can avoid that behavior by giving a prefix
-argument to it (e.g., by typing @kbd{C-u M-x cvs-update RET}).@refill
-
-All other commands in pcl-cvs requires that you have a @samp{*cvs*}
-buffer. This is the command that you use to get one.@refill
-
-CVS uses lock files in the repository to ensure the integrity of the
-data files in the repository. They might be left behind i.e. if a
-workstation crashes in the middle of a CVS operation. CVS outputs a
-message when it is waiting for a lock file to go away. Pcl-cvs will
-show the same message in the *cvs* buffer, together with instructions
-for deleting the lock files. You should normally not have to delete
-them manually --- just wait a little while and the problem should fix
-itself. But if the lock files doesn't disappear you can delete them
-with @kbd{M-x cvs-delete-lock RET}.@refill
-
-@item g
-This will run @samp{cvs update} again. It will always use the same
-buffer that was used with the previous @samp{cvs update}. Give a prefix
-argument to avoid descending into subdirectories. This runs the command
-@samp{cvs-mode-update-no-prompt}.@refill
-@end table
-@node Movement commands, Marking files, Updating the directory, Commands
-@comment node-name, next, previous, up
-@section Movement Commands
-@cindex Movement Commands
-@findex cookie-next-cookie
-@findex cookie-previous-cookie
-@kindex SPC - Move down one file
-@kindex C-n - Move down one file
-@kindex n - Move down one file
-@kindex C-p - Move up one file
-@kindex p - Move up on file
-
-You can use most normal Emacs commands to move forward and backward in
-the buffer. Some keys are rebound to functions that take advantage of
-the fact that the buffer is a pcl-cvs buffer:
-
-
-@table @kbd
-@item SPC
-@itemx C-n
-@itemx n
-These keys move the cursor one file forward, towards the end of the
-buffer (@code{cookie-next-cookie}).
-
-@item C-p
-@itemx p
-These keys move one file backward, towards the beginning of the buffer
-(@code{cookie-previous-cookie}).
-@end table
-
-@node Marking files, Committing changes, Movement commands, Commands
-@comment node-name, next, previous, up
-@section Marking files
-@cindex Selecting files (commands to mark files)
-@cindex Marking files
-@kindex m - marking a file
-@kindex M - marking all files
-@kindex u - unmark a file
-@kindex ESC DEL - unmark all files
-@kindex DEL - unmark previous file
-@findex cvs-mode-mark
-@findex cvs-mode-unmark
-@findex cvs-mode-mark-all-files
-@findex cvs-mode-unmark-all-files
-@findex cvs-mode-unmark-up
-
-Pcl-cvs works on a set of @dfn{selected files} (@pxref{Selected files}).
-You can mark and unmark files with these commands:
-
-@table @kbd
-@item m
-This marks the file that the cursor is positioned on. If the cursor is
-positioned on a directory all files in that directory will be marked.
-(@code{cvs-mode-mark}).
-
-@item u
-Unmark the file that the cursor is positioned on. If the cursor is on a
-directory, all files in that directory will be unmarked.
-(@code{cvs-mode-unmark}).@refill
-
-@item M
-Mark @emph{all} files in the buffer (@code{cvs-mode-mark-all-files}).
-
-@item @key{ESC} @key{DEL}
-Unmark @emph{all} files (@code{cvs-mode-unmark-all-files}).
-
-@item @key{DEL}
-Unmark the file on the previous line, and move point to that line
-(@code{cvs-mode-unmark-up}).
-@end table
-
-@node Committing changes, Editing files, Marking files, Commands
-@comment node-name, next, previous, up
-@section Committing changes
-@cindex Committing changes
-@cindex Ci
-@findex cvs-mode-commit
-@kindex c - commit files
-@vindex cvs-erase-input-buffer (variable)
-@vindex cvs-auto-revert-after-commit (variable)
-@cindex Commit buffer
-@cindex Edit buffer
-@cindex Erasing commit message
-@cindex Reverting buffers after commit
-
-@table @kbd
-@item c
-All files that have a "need to be checked in"-marker (@pxref{Buffer
-contents}) can be checked in with the @kbd{c} command. It checks in all
-selected files (@pxref{Selected files}) (except those who lack the
-"ci"-marker - they are ignored). Pressing @kbd{c} causes
-@code{cvs-mode-commit} to be run.@refill
-
-When you press @kbd{c} you will get a buffer called
-@samp{*cvs-commit-message*}. Enter the log message for the file(s) in
-it. When you are ready you should press @kbd{C-c C-c} to actually
-commit the files (using @code{cvs-edit-done}).
-
-Normally the @samp{*cvs-commit-message*} buffer will retain the log
-message from the previous commit, but if the variable
-@code{cvs-erase-input-buffer} is set to a non-@code{nil} value the
-buffer will be erased. Point and mark will always be located around the
-entire buffer so that you can easily erase it with @kbd{C-w}
-(@samp{kill-region}).@refill
-
-If you are editing the files in your emacs an automatic
-@samp{revert-buffer} will be performed. (If the file contains
-@samp{$@asis{Id}$} keywords @samp{cvs commit} will write a new file with
-the new values substituted. The auto-revert makes sure that you get
-them into your buffer). The revert will not occur if you have modified
-your buffer, or if @samp{cvs-auto-revert-after-commit} is set to
-@samp{nil}.@refill
-@end table
-
-@node Editing files, Getting info about files, Committing changes, Commands
-@comment node-name, next, previous, up
-@section Editing files
-
-@cindex Editing files
-@cindex Finding files
-@cindex Loading files
-@cindex Dired
-@cindex Invoking dired
-@findex cvs-mode-find-file
-@findex cvs-mode-find-file-other-window
-@findex cvs-mode-add-change-log-entry-other-window
-@kindex f - find file or directory
-@kindex o - find file in other window
-@kindex A - add ChangeLog entry
-
-There are currently three commands that can be used to find a file (that
-is, load it into a buffer and start editing it there). These commands
-work on the line that the cursor is situated at. They ignore any marked
-files.
-
-@table @kbd
-@item f
-Find the file that the cursor points to. Run @samp{dired}
-@ifinfo
-(@pxref{Dired,,,Emacs})
-@end ifinfo
-if the cursor points to a directory (@code{cvs-mode-find-file}).@refill
-
-@item o
-Like @kbd{f}, but use another window
-(@code{cvs-mode-find-file-other-window}).@refill
-
-@item A
-Invoke @samp{add-change-log-entry-other-window} to edit a
-@samp{ChangeLog} file. The @samp{ChangeLog} will be found in the
-directory of the file the cursor points to.
-(@code{cvs-mode-add-change-log-entry-other-window}).@refill
-@end table
-
-@node Getting info about files, Adding and removing files, Editing files, Commands
-@comment node-name, next, previous, up
-@section Getting info about files
-@cindex Status (cvs command)
-@cindex Log (RCS/cvs command)
-@cindex Getting status
-@kindex l - run @samp{cvs log}
-@kindex s - run @samp{cvs status}
-@findex cvs-mode-log
-@findex cvs-mode-status
-
-Both of the following commands can be customized.
-@xref{Customization}.@refill
-
-@table @kbd
-@item l
-Run @samp{cvs log} on all selected files, and show the result in a
-temporary buffer (@code{cvs-mode-log}).
-
-@item s
-Run @samp{cvs status} on all selected files, and show the result in a
-temporary buffer (@code{cvs-mode-status}).
-@end table
-
-@node Adding and removing files, Undoing changes, Getting info about files, Commands
-@comment node-name, next, previous, up
-@section Adding and removing files
-@cindex Adding files
-@cindex Removing files
-@cindex Resurrecting files
-@cindex Deleting files
-@cindex Putting files under CVS control
-@kindex a - add a file
-@kindex r - remove a file
-@findex cvs-mode-add
-@findex cvs-mode-remove-file
-
-The following commands are available to make it easy to add and remove
-files from the CVS repository.
-
-@table @kbd
-@item a
-Add all selected files. This command can be used on @samp{Unknown}
-files (see @pxref{File status}). The status of the file will change to
-@samp{Added}, and you will have to use @kbd{c} (@samp{cvs-mode-commit}, see
-@pxref{Committing changes}) to really add the file to the
-repository.@refill
-
-This command can also be used on @samp{Removed} files (before you commit
-them) to resurrect them.
-
-Selected files that are neither @samp{Unknown} nor @samp{Removed} will
-be ignored by this command.
-
-The command that is run is @code{cvs-mode-add}.
-
-@item r
-This command removes the selected files (after prompting for
-confirmation). The files are @samp{rm}ed from your directory and
-(unless the status was @samp{Unknown}; @pxref{File status}) they will
-also be @samp{cvs remove}d. If the files were @samp{Unknown} they will
-disappear from the buffer. Otherwise their status will change to
-@samp{Removed}, and you must use @kbd{c} (@samp{cvs-mode-commit},
-@pxref{Committing changes}) to commit the removal.@refill
-
-The command that is run is @code{cvs-mode-remove-file}.
-@end table
-
-@node Undoing changes, Removing handled entries, Adding and removing files, Commands
-@comment node-name, next, previous, up
-@section Undoing changes
-@cindex Undo changes
-@cindex Flush changes
-@kindex U - undo changes
-@findex cvs-mode-undo-local-changes
-
-@table @kbd
-@item U
-If you have modified a file, and for some reason decide that you don't
-want to keep the changes, you can undo them with this command. It works
-by removing your working copy of the file and then getting the latest
-version from the repository (@code{cvs-mode-undo-local-changes}.
-@end table
-
-@node Removing handled entries, Ignoring files, Undoing changes, Commands
-@comment node-name, next, previous, up
-@section Removing handled entries
-@cindex Expunging uninteresting entries
-@cindex Uninteresting entries, getting rid of them
-@cindex Getting rid of uninteresting lines
-@cindex Removing uninteresting (processed) lines
-@cindex Handled lines, removing them
-@kindex x - remove processed entries
-@kindex C-k - remove selected entries
-@findex cvs-mode-remove-handled
-@findex cvs-mode-acknowledge
-@findex cvs-mode-ignore
-
-@table @kbd
-@item x
-This command allows you to remove all entries that you have processed.
-More specifically, the lines for @samp{Updated} files (@pxref{File
-status} and files that have been checked in (@pxref{Committing changes})
-are removed from the buffer. If a directory becomes empty the heading
-for that directory is also removed. This makes it easier to get an
-overview of what needs to be done.
-
-The command is called @code{cvs-mode-remove-handled}. If
-@samp{cvs-auto-remove-handled} is set to non-@code{nil} this will
-automatically be performed after every commit.@refill
-
-@item C-k
-This command can be used for lines that @samp{cvs-mode-remove-handled} would
-not delete, but that you want to delete (@code{cvs-mode-acknowledge}).
-@end table
-
-@node Ignoring files, Viewing differences, Removing handled entries, Commands
-@comment node-name, next, previous, up
-@section Ignoring files
-
-@table @kbd
-@item i
-Arrange so that CVS will ignore the selected files. The file names are
-added to the @file{.cvsignore} file in the corresponding directory. If
-the @file{.cvsignore} doesn't exist it will be created.
-
-The @file{.cvsignore} file should normally be added to the repository,
-but you could ignore it also if you like it better that way.
-
-This runs @code{cvs-mode-ignore}.
-@end table
-
-@node Viewing differences, Emerge, Ignoring files, Commands
-@comment node-name, next, previous, up
-@section Viewing differences
-@cindex Diff
-@cindex Conflicts, how to resolve them
-@cindex Viewing differences
-@kindex d - run @samp{cvs diff}
-@kindex b - diff backup file
-@findex cvs-mode-diff-cvs
-@findex cvs-mode-diff-backup
-@vindex cvs-diff-ignore-marks (variable)
-
-@table @kbd
-@item d
-Display a @samp{cvs diff} between the selected files and the RCS version
-that they are based on. @xref{Customization} describes how you can send
-flags to @samp{cvs diff}. If @var{cvs-diff-ignore-marks} is set to a
-non-@code{nil} value or if a prefix argument is given (but not both) any
-marked files will not be considered to be selected.
-(@code{cvs-mode-diff-cvs}).@refill
-
-@item b
-If CVS finds a conflict while merging two versions of a file (during a
-@samp{cvs update}, @pxref{Updating the directory}) it will save the
-original file in a file called @file{.#@var{FILE}.@var{VERSION}} where
-@var{FILE} is the name of the file, and @var{VERSION} is the RCS version
-number that your file was based on.@refill
-
-With the @kbd{b} command you can run a @samp{diff} on the files
-@file{.#@var{FILE}.@var{VERSION}} and @file{@var{FILE}}. You can get a
-context- or Unidiff by setting @samp{cvs-diff-flags} -
-@pxref{Customization}. This command only works on files that have
-status @samp{Conflict} or @samp{Merged}.@refill
-
-If @var{cvs-diff-ignore-marks} is set to a non-@code{nil} value or if a
-prefix argument is given (but not both) any marked files will not be
-considered to be selected. (@code{cvs-mode-diff-backup}).@refill
-@end table
-
-@node Emerge, Reverting your buffers, Viewing differences, Commands
-@comment node-name, next, previous, up
-@section Running emerge
-@cindex Emerge
-@cindex Invoking emerge
-@cindex Conflicts, resolving
-@cindex Resolving conflicts
-@kindex e - invoke @samp{emerge}
-@findex cvs-mode-emerge
-
-@table @kbd
-@item e
-Invoke @samp{emerge} on one file. This command works slightly different
-depending on the file status.
-
-@table @asis
-@item @samp{Modified}
-Run @samp{emerge-files} with your working file as file A, and the latest
-revision in the repository as file B.
-
-@item @samp{Merged}
-@itemx @samp{Conflict}
-Run @samp{emerge-files-with-ancestor} with your working file (as it was
-prior to your invocation of @samp{cvs-update}) as file A, the latest
-revision in the repository as file B, and the revision that you based
-your local modifications on as ancestor.
-@end table
-
-@strong{Note:} CVS has already performed a merge. The resulting file is
-not used in any way if you use this command. If you use the @kbd{q}
-command inside @samp{emerge} (to successfully terminate the merge) the
-file that CVS created will be overwritten.
-@end table
-
-@node Reverting your buffers, Miscellaneous commands, Emerge, Commands
-@comment node-name, next, previous, up
-@section Reverting your buffers
-@findex cvs-mode-revert-updated-buffers
-@kindex R - revert buffers
-@cindex Syncing buffers
-@cindex Reverting buffers
-
-@table @kbd
-@item R
-If you are editing (or just viewing) a file in a buffer, and that file
-is changed by CVS during a @samp{cvs-update}, all you have to do is type
-@kbd{R} in the *cvs* buffer to read in the new versions of the
-files.@refill
-
-All files that are @samp{Updated}, @samp{Merged} or in @samp{Conflict}
-are reverted from the disk. Any other files are ignored. Only files
-that you were already editing are read.@refill
-
-An error is signalled if you have modified the buffer since it was last
-changed. (@code{cvs-mode-revert-updated-buffers}).@refill
-@end table
-
-@node Miscellaneous commands, , Reverting your buffers, Commands
-@comment node-name, next, previous, up
-@section Miscellaneous commands
-@findex cvs-byte-compile-files
-@cindex Recompiling elisp files
-@cindex Byte compilation
-@cindex Getting rid of lock files
-@cindex Lock files
-@kindex q - bury the *cvs* buffer
-@findex bury-buffer
-
-@table @kbd
-@item M-x cvs-byte-compile-files
-Byte compile all selected files that end in .el.
-
-@item M-x cvs-delete-lock
-This command can be used in any buffer, and deletes the lock files that
-the *cvs* buffer informs you about. You should normally never have to
-use this command since CVS tries very carefully to always remove the
-lock files itself.
-
-You can only use this command when a message in the *cvs* buffer tells
-you so. You should wait a while before using this command in case
-someone else is running a cvs command.
-
-@item q
-Bury the *cvs* buffer. (@code{bury-buffer}).
-
-@end table
-
-@node Customization, Future enhancements, Commands, Top
-@comment node-name, next, previous, up
-@chapter Customization
-@vindex cvs-erase-input-buffer (variable)
-@vindex cvs-inhibit-copyright-message (variable)
-@vindex cvs-diff-flags (variable)
-@vindex cvs-diff-ignore-marks (variable)
-@vindex cvs-log-flags (variable)
-@vindex cvs-status-flags (variable)
-@vindex cvs-auto-remove-handled (variable)
-@vindex cvs-update-prog-output-skip-regexp (variable)
-@vindex cvs-cvsroot (variable)
-@vindex TMPDIR (environment variable)
-@vindex cvs-auto-revert-after-commit (variable)
-@vindex cvs-commit-buffer-require-final-newline (variable)
-@vindex cvs-sort-ignore-file (variable)
-@cindex Inhibiting the Copyright message.
-@cindex Copyright message, getting rid of it
-@cindex Getting rid of the Copyright message.
-@cindex Customization
-@cindex Variables, list of all
-@cindex Erasing the input buffer
-@cindex Context diff, how to get
-@cindex Unidiff, how to get
-@cindex Automatically remove handled files
-@cindex -u option in modules file
-@cindex Modules file (-u option)
-@cindex Update program (-u option in modules file)
-@cindex Reverting buffers after commit
-@cindex Require final newline
-@cindex Automatically inserting newline
-@cindex Commit message, inserting newline
-@cindex Sorting the .cvsignore file
-@cindex .cvsignore file, sorting
-@cindex Automatically sorting .cvsignore
-
-If you have an idea about any customization that would be handy but
-isn't present in this list, please tell me! @xref{Bugs} for info on how
-to reach me.@refill
-
-@table @samp
-@item cvs-erase-input-buffer
-If set to anything else than @code{nil} the edit buffer will be erased
-before you write the log message (@pxref{Committing changes}).
-
-@item cvs-inhibit-copyright-message
-The copyright message that is displayed on startup can be annoying after
-a while. Set this variable to @samp{t} if you want to get rid of it.
-(But don't set this to @samp{t} in the system defaults file - new users
-should see this message at least once).
-
-@item cvs-diff-flags
-A list of strings to pass as arguments to the @samp{cvs diff} and
-@samp{diff} programs. This is used by @samp{cvs-mode-diff-cvs} and
-@samp{cvs-mode-diff-backup} (key @kbd{b}, @pxref{Viewing differences}). If
-you prefer the Unidiff format you could add this line to your
-@file{.emacs} file:@refill
-
-@example
-(setq cvs-diff-flags '("-u"))
-@end example
-
-@item cvs-diff-ignore-marks
-If this variable is non-@code{nil} or if a prefix argument is given (but
-not both) to @samp{cvs-mode-diff-cvs} or @samp{cvs-mode-diff-backup}
-marked files are not considered selected.
-
-@item cvs-log-flags
-List of strings to send to @samp{cvs log}. Used by @samp{cvs-mode-log}
-(key @kbd{l}, @pxref{Getting info about files}).
-
-@item cvs-status-flags
-List of strings to send to @samp{cvs status}. Used by @samp{cvs-mode-status}
-(key @kbd{s}, @pxref{Getting info about files}).
-
-@item cvs-auto-remove-handled
-If this variable is set to any non-@code{nil} value
-@samp{cvs-mode-remove-handled} will be called every time you check in
-files, after the check-in is ready. @xref{Removing handled
-entries}.@refill
-
-@item cvs-auto-revert-after-commit
-If this variable is set to any non-@samp{nil} value any buffers you have
-that visit a file that is committed will be automatically reverted.
-This variable is default @samp{t}. @xref{Committing changes}.@refill
-
-@item cvs-update-prog-output-skip-regexp
-The @samp{-u} flag in the @file{modules} file can be used to run a command
-whenever a @samp{cvs update} is performed (see cvs(5)). This regexp
-is used to search for the last line in that output. It is normally set
-to @samp{"$"}. That setting is only correct if the command outputs
-nothing. Note that pcl-cvs will get very confused if the command
-outputs @emph{anything} to @samp{stderr}.
-
-@item cvs-cvsroot
-This variable can be set to override @samp{CVSROOT}. It should be a
-string. If it is set then everytime a cvs command is run it will be
-called as @samp{cvs -d @var{cvs-cvsroot}@dots{}} This can be useful if
-your site has several repositories.
-
-@item TMPDIR
-Pcl-cvs uses this @emph{environment variable} to decide where to put the
-temporary files it needs. It defaults to @file{/tmp} if it is not set.
-
-@item cvs-commit-buffer-require-final-newline
-When you enter a log message in the @samp{*cvs-commit-message*} buffer
-pcl-cvs will normally automatically insert a trailing newline, unless
-there already is one. This behavior can be controlled via
-@samp{cvs-commit-buffer-require-final-newline}. If it is @samp{t} (the
-default behavior), a newline will always be appended. If it is
-@samp{nil}, newlines will never be appended. Any other value causes
-pcl-cvs to ask the user whenever there is no trailing newline in the
-commit message buffer.
-
-@item cvs-sort-ignore-file
-If this variable is set to any non-@samp{nil} value the
-@file{.cvsignore} will always be sorted whenever you use
-@samp{cvs-mode-ignore} to add a file to it. This option is on by
-default.
-
-@end table
-@node Future enhancements, Bugs, Customization, Top
-@comment node-name, next, previous, up
-@chapter Future enhancements
-@cindex Enhancements
-
-Pcl-cvs is still under development and needs a number of enhancements to
-be called complete. Below is my current wish-list for future releases
-of pcl-cvs. Please, let me know which of these features you want most.
-They are listed below in approximately the order that I currently think
-I will implement them in.
-
-@itemize @bullet
-@item
-Rewritten parser code. There are many situations where pcl-cvs will
-fail to recognize the output from CVS. The situation could be greatly
-increased.
-
-@item
-@samp{cvs-status}. This will run @samp{cvs status} in a directory and
-produce a buffer that looks pretty much like the current *cvs* buffer.
-That buffer will include information for all version-controlled files.
-(There will be a simple keystroke to remove all "uninteresting" files,
-that is, files that are "Up-to-date"). In this new buffer you will be
-able to update a file, commit a file, et c. The big win with this is
-that you will be able to watch the differences between your current
-working file and the head revision in the repository before you update
-the file, and you can then choose to update it or let it wait for a
-while longer.
-
-@item
-Log mode. When this mode is finished you will be able to move around
-(using @kbd{n} and @kbd{p}) between the revisions of a file, mark two of
-them, and run a diff between them. You will be able to hide branches
-(similar to the way you can hide sub-paragraphs in outline-mode) and do
-merges between revisions. Other ideas about this are welcome.
-
-@item
-The current model for marks in the *cvs* buffer seems to be confusing.
-I am considering to use the VM model instead, where marks are normally
-inactive. To activate the mark, you issue a command like
-@samp{cvs-mode-next-command-uses-marks}. I might implement a flag so
-that you can use either version. Feedback on this before I start coding
-it is very welcome.
-
-@item
-It should be possible to run commands such as @samp{cvs log}, @samp{cvs
-status} and @samp{cvs commit} directly from a buffer containing a file,
-instead of having to @samp{cvs-update}. If the directory contains many
-files the @samp{cvs-update} can take quite some time, especially on a
-slow machine. I planed to put these kind of commands on the prefix
-@kbd{C-c C-v}, but that turned out to be used by for instance c++-mode.
-If you have any suggestions for a better prefix key, please let me know.
-
-@item
-Increased robustness. For instance, you can not currently press
-@kbd{C-g} when you are entering the description of a file that you are
-adding without confusing pcl-cvs.
-
-@item
-Support for multiple active *cvs* buffers.
-
-@item
-Dired support. I have an experimental @file{dired-cvs.el} that works
-together with CVS 1.2. Unfortunately I wrote it on top of a
-non-standard @file{dired.el}, so it must be rewritten.@refill
-
-@item
-An ability to send user-supplied options to all the cvs commands.
-
-@item
-Pcl-cvs is not at all clever about what it should do when @samp{cvs
-update} runs a program (due to the @samp{-u} option in the
-@file{modules} file --- see @samp{cvs(5)}). The current release uses a
-regexp to search for the end. At the very least that regexp should be
-configured for different modules. Tell me if you have any idea about
-what is the right thing to do. In a perfect world the program should
-also be allowed to print to @samp{stderr} without causing pcl-cvs to
-crash.
-@end itemize
-
-
-If you miss something in this wish-list, let me know! I don't promise
-that I will write it, but I will at least try to coordinate the efforts
-of making a good Emacs front end to CVS. See @xref{Bugs} for
-information about how to reach me.@refill
-
-So far, I have written most of pcl-cvs in my all-to-rare spare time. If
-you want pcl-cvs to be developed faster you can write a contract with
-Signum Support to do the extension. You can reach Signum Support by
-email to @samp{info@@signum.se} or via mail to Signum Support AB, Box
-2044, S-580 02 Linkoping, Sweden. Phone: +46 (0) 13 - 21 46 00. Fax: +46
-(0) 13 - 21 47 00.
-
-@node Bugs, Function and Variable Index, Future enhancements, Top
-@comment node-name, next, previous, up
-@chapter Bugs (known and unknown)
-@cindex Reporting bugs and ideas
-@cindex Bugs, how to report them
-@cindex Author, how to reach
-@cindex Email to the author
-@cindex Known bugs
-@cindex Bugs, known
-@cindex FAQ
-@cindex Problems, list of common
-
-If you find a bug or misfeature, don't hesitate to tell me! Send email
-to @samp{ceder@@lysator.liu.se}.
-
-If you have ideas for improvements, or if you have written some
-extensions to this package, I would like to hear from you. I hope that
-you find this package useful!
-
-Below is a partial list of currently known problems with pcl-cvs version
-1.05.
-
-@table @asis
-@item Commit causes Emacs to hang
-Emacs waits for the @samp{cvs commit} command to finish before you can
-do anything. If you start a background job from the loginfo file you
-must take care that it closes @samp{stdout} and @samp{stderr} if you do
-not want to wait for it. (You do that with @samp{background-command &>-
-2&>- &} if you are starting @samp{background-command} from a
-@samp{/bin/sh} shell script).
-
-Your emacs will also hang if there was a lock file in the repository.
-In this case you can type @kbd{C-g} to get control over your emacs
-again.
-
-@item Name clash in Emacs 19
-This is really a bug in Elib or the Emacs 19 distribution. Both Elib and
-Emacs 19.6 through at least 19.10 contains a file named
-@file{cookie.el}. One of the files will have to be renamed, and we are
-currently negotiating about which of the files to rename.
-
-@item Commands while cvs-update is running
-It is possible to type commands in the *cvs* buffer while the update is
-running, but error messages is all that you will get. The error
-messages should be better.
-
-@item Unexpected output from CVS
-Unexpected output from CVS confuses pcl-cvs. It will currently create a
-bug report that you can mail to me. It should do something more
-civilized.
-@end table
-
-@node Function and Variable Index, Concept Index, Bugs, Top
-@comment node-name, next, previous, up
-@unnumbered Function and Variable Index
-
-@printindex fn
-
-@node Concept Index, Key Index, Function and Variable Index, Top
-@comment node-name, next, previous, up
-@unnumbered Concept Index
-
-@printindex cp
-
-@node Key Index, , Concept Index, Top
-@comment node-name, next, previous, up
-@unnumbered Key Index
-
-@printindex ky
-
-@summarycontents
-@contents
-@bye
diff --git a/gnu/usr.bin/cvs/contrib/rcs-to-cvs b/gnu/usr.bin/cvs/contrib/rcs-to-cvs
deleted file mode 100644
index 5863ed87414c..000000000000
--- a/gnu/usr.bin/cvs/contrib/rcs-to-cvs
+++ /dev/null
@@ -1,184 +0,0 @@
-#!/bin/sh
-#
-# $Id: rcs-to-cvs,v 1.4 1994/09/21 07:23:16 berliner Exp $
-# Based on the CVS 1.0 checkin csh script.
-# Contributed by Per Cederqvist <ceder@signum.se>.
-# Rewritten in sh by David MacKenzie <djm@cygnus.com>.
-#
-# Copyright (c) 1989, Brian Berliner
-#
-# You may distribute under the terms of the GNU General Public License.
-#
-#############################################################################
-#
-# Check in sources that previously were under RCS or no source control system.
-#
-# The repository is the directory where the sources should be deposited.
-#
-# Traverses the current directory, ensuring that an
-# identical directory structure exists in the repository directory. It
-# then checks the files in in the following manner:
-#
-# 1) If the file doesn't yet exist, check it in as revision 1.1
-#
-# The script also is somewhat verbose in letting the user know what is
-# going on. It prints a diagnostic when it creates a new file, or updates
-# a file that has been modified on the trunk.
-#
-# Bugs: doesn't put the files in branch 1.1.1
-# doesn't put in release and vendor tags
-#
-#############################################################################
-
-usage="Usage: rcs-to-cvs [-v] [-m message] [-f message_file] repository"
-vbose=0
-message=""
-message_file=/usr/tmp/checkin.$$
-got_one=0
-
-if [ $# -lt 1 ]; then
- echo "$usage" >&2
- exit 1
-fi
-
-while [ $# -ne 0 ]; do
- case "$1" in
- -v)
- vbose=1
- ;;
- -m)
- shift
- echo $1 > $message_file
- got_one=1
- ;;
- -f)
- shift
- message_file=$1
- got_one=2
- ;;
- *)
- break
- esac
- shift
-done
-
-if [ $# -lt 1 ]; then
- echo "$usage" >&2
- exit 1
-fi
-
-repository=$1
-shift
-
-if [ -z "$CVSROOT" ]; then
- echo "Please the environmental variable CVSROOT to the root" >&2
- echo " of the tree you wish to update" >&2
- exit 1
-fi
-
-if [ $got_one -eq 0 ]; then
- echo "Please Edit this file to contain the RCS log information" >$message_file
- echo "to be associated with this directory (please remove these lines)">>$message_file
- ${EDITOR-/usr/ucb/vi} $message_file
- got_one=1
-fi
-
-umask 22
-
-update_dir=${CVSROOT}/${repository}
-[ ! -d ${update_dir} ] && mkdir $update_dir
-
-if [ -d SCCS ]; then
- echo SCCS files detected! >&2
- exit 1
-fi
-if [ -d RCS ]; then
- co RCS/*
-fi
-
-for name in * .[a-zA-Z0-9]*
-do
- case "$name" in
- RCS | \* | .\[a-zA-Z0-9\]\* ) continue ;;
- esac
- echo $name
- if [ $vbose -ne 0 ]; then
- echo "Updating ${repository}/${name}"
- fi
- if [ -d "$name" ]; then
- if [ ! -d "${update_dir}/${name}" ]; then
- echo "WARNING: Creating new directory ${repository}/${name}"
- mkdir "${update_dir}/${name}"
- if [ $? -ne 0 ]; then
- echo "ERROR: mkdir failed - aborting" >&2
- exit 1
- fi
- fi
- cd "$name"
- if [ $? -ne 0 ]; then
- echo "ERROR: Couldn\'t cd to $name - aborting" >&2
- exit 1
- fi
- if [ $vbose -ne 0 ]; then
- $0 -v -f $message_file "${repository}/${name}"
- else
- $0 -f $message_file "${repository}/${name}"
- fi
- if [ $? -ne 0 ]; then
- exit 1
- fi
- cd ..
- else # if not directory
- if [ ! -f "$name" ]; then
- echo "WARNING: $name is neither a regular file"
- echo " nor a directory - ignored"
- continue
- fi
- file="${update_dir}/${name},v"
- comment=""
- if grep -s '\$Log.*\$' "${name}"; then # If $Log keyword
- myext=`echo $name | sed 's,.*\.,,'`
- [ "$myext" = "$name" ] && myext=
- case "$myext" in
- c | csh | e | f | h | l | mac | me | mm | ms | p | r | red | s | sh | sl | cl | ml | el | tex | y | ye | yr | "" )
- ;;
-
- * )
- echo "For file ${file}:"
- grep '\$Log.*\$' "${name}"
- echo -n "Please insert a comment leader for file ${name} > "
- read comment
- ;;
- esac
- fi
- if [ ! -f "$file" ]; then # If not exists in repository
- if [ ! -f "${update_dir}/Attic/${name},v" ]; then
- echo "WARNING: Creating new file ${repository}/${name}"
- if [ -f RCS/"${name}",v ]; then
- echo "MSG: Copying old rcs file."
- cp RCS/"${name}",v "$file"
- else
- if [ -n "${comment}" ]; then
- rcs -q -i -c"${comment}" -t${message_file} -m'.' "$file"
- fi
- ci -q -u1.1 -t${message_file} -m'.' "$file"
- if [ $? -ne 0 ]; then
- echo "ERROR: Initial check-in of $file failed - aborting" >&2
- exit 1
- fi
- fi
- else
- file="${update_dir}/Attic/${name},v"
- echo "WARNING: IGNORED: ${repository}/Attic/${name}"
- continue
- fi
- else # File existed
- echo "ERROR: File exists in repository: Ignored: $file"
- continue
- fi
- fi
-done
-
-[ $got_one -eq 1 ] && rm -f $message_file
-
-exit 0
diff --git a/gnu/usr.bin/cvs/contrib/rcs-to-cvs.sh b/gnu/usr.bin/cvs/contrib/rcs-to-cvs.sh
deleted file mode 100644
index 3af83d708ca4..000000000000
--- a/gnu/usr.bin/cvs/contrib/rcs-to-cvs.sh
+++ /dev/null
@@ -1,185 +0,0 @@
-#! /bin/sh
-#
-# $Id: rcs-to-cvs.sh,v 1.2 1995/07/15 03:40:34 jimb Exp $
-# Based on the CVS 1.0 checkin csh script.
-# Contributed by Per Cederqvist <ceder@signum.se>.
-# Rewritten in sh by David MacKenzie <djm@cygnus.com>.
-#
-# Copyright (c) 1989, Brian Berliner
-#
-# You may distribute under the terms of the GNU General Public License.
-#
-#############################################################################
-#
-# Check in sources that previously were under RCS or no source control system.
-#
-# The repository is the directory where the sources should be deposited.
-#
-# Traverses the current directory, ensuring that an
-# identical directory structure exists in the repository directory. It
-# then checks the files in in the following manner:
-#
-# 1) If the file doesn't yet exist, check it in as revision 1.1
-#
-# The script also is somewhat verbose in letting the user know what is
-# going on. It prints a diagnostic when it creates a new file, or updates
-# a file that has been modified on the trunk.
-#
-# Bugs: doesn't put the files in branch 1.1.1
-# doesn't put in release and vendor tags
-#
-#############################################################################
-
-usage="Usage: rcs-to-cvs [-v] [-m message] [-f message_file] repository"
-vbose=0
-message=""
-message_file=/usr/tmp/checkin.$$
-got_one=0
-
-if [ $# -lt 1 ]; then
- echo "$usage" >&2
- exit 1
-fi
-
-while [ $# -ne 0 ]; do
- case "$1" in
- -v)
- vbose=1
- ;;
- -m)
- shift
- echo $1 > $message_file
- got_one=1
- ;;
- -f)
- shift
- message_file=$1
- got_one=2
- ;;
- *)
- break
- esac
- shift
-done
-
-if [ $# -lt 1 ]; then
- echo "$usage" >&2
- exit 1
-fi
-
-repository=$1
-shift
-
-if [ -z "$CVSROOT" ]; then
- echo "Please the environmental variable CVSROOT to the root" >&2
- echo " of the tree you wish to update" >&2
- exit 1
-fi
-
-if [ $got_one -eq 0 ]; then
- echo "Please Edit this file to contain the RCS log information" >$message_file
- echo "to be associated with this directory (please remove these lines)">>$message_file
- ${EDITOR-/usr/ucb/vi} $message_file
- got_one=1
-fi
-
-# Ya gotta share.
-umask 0
-
-update_dir=${CVSROOT}/${repository}
-[ ! -d ${update_dir} ] && mkdir $update_dir
-
-if [ -d SCCS ]; then
- echo SCCS files detected! >&2
- exit 1
-fi
-if [ -d RCS ]; then
- co RCS/*
-fi
-
-for name in * .[a-zA-Z0-9]*
-do
- case "$name" in
- RCS | *~ | \* | .\[a-zA-Z0-9\]\* ) continue ;;
- esac
- echo $name
- if [ $vbose -ne 0 ]; then
- echo "Updating ${repository}/${name}"
- fi
- if [ -d "$name" ]; then
- if [ ! -d "${update_dir}/${name}" ]; then
- echo "WARNING: Creating new directory ${repository}/${name}"
- mkdir "${update_dir}/${name}"
- if [ $? -ne 0 ]; then
- echo "ERROR: mkdir failed - aborting" >&2
- exit 1
- fi
- fi
- cd "$name"
- if [ $? -ne 0 ]; then
- echo "ERROR: Couldn\'t cd to $name - aborting" >&2
- exit 1
- fi
- if [ $vbose -ne 0 ]; then
- $0 -v -f $message_file "${repository}/${name}"
- else
- $0 -f $message_file "${repository}/${name}"
- fi
- if [ $? -ne 0 ]; then
- exit 1
- fi
- cd ..
- else # if not directory
- if [ ! -f "$name" ]; then
- echo "WARNING: $name is neither a regular file"
- echo " nor a directory - ignored"
- continue
- fi
- file="${update_dir}/${name},v"
- comment=""
- if grep -s '\$Log.*\$' "${name}"; then # If $Log keyword
- myext=`echo $name | sed 's,.*\.,,'`
- [ "$myext" = "$name" ] && myext=
- case "$myext" in
- c | csh | e | f | h | l | mac | me | mm | ms | p | r | red | s | sh | sl | cl | ml | el | tex | y | ye | yr | "" )
- ;;
-
- * )
- echo "For file ${file}:"
- grep '\$Log.*\$' "${name}"
- echo -n "Please insert a comment leader for file ${name} > "
- read comment
- ;;
- esac
- fi
- if [ ! -f "$file" ]; then # If not exists in repository
- if [ ! -f "${update_dir}/Attic/${name},v" ]; then
- echo "WARNING: Creating new file ${repository}/${name}"
- if [ -f RCS/"${name}",v ]; then
- echo "MSG: Copying old rcs file."
- cp RCS/"${name}",v "$file"
- else
- if [ -n "${comment}" ]; then
- rcs -q -i -c"${comment}" -t${message_file} -m'.' "$file"
- fi
- ci -q -u1.1 -t${message_file} -m'.' "$file"
- if [ $? -ne 0 ]; then
- echo "ERROR: Initial check-in of $file failed - aborting" >&2
- exit 1
- fi
- fi
- else
- file="${update_dir}/Attic/${name},v"
- echo "WARNING: IGNORED: ${repository}/Attic/${name}"
- continue
- fi
- else # File existed
- echo "ERROR: File exists in repository: Ignored: $file"
- continue
- fi
- fi
-done
-
-[ $got_one -eq 1 ] && rm -f $message_file
-
-exit 0
diff --git a/gnu/usr.bin/cvs/contrib/rcs2log b/gnu/usr.bin/cvs/contrib/rcs2log
deleted file mode 100644
index d7900025b851..000000000000
--- a/gnu/usr.bin/cvs/contrib/rcs2log
+++ /dev/null
@@ -1,326 +0,0 @@
-#!/bin/sh
-
-# RCS to ChangeLog generator
-
-# Generate a change log prefix from RCS/* and the existing ChangeLog (if any).
-# Output the new prefix to standard output.
-# You can edit this prefix by hand, and then prepend it to ChangeLog.
-
-# Ignore log entries that start with `#'.
-# Clump together log entries that start with `{topic} ',
-# where `topic' contains neither white space nor `}'.
-
-# Author: Paul Eggert <eggert@twinsun.com>
-
-# OrigId: rcs2log,v 1.9 1993/01/15 05:33:29 eggert Exp
-
-# Copyright 1992, 1993 Free Software Foundation, Inc.
-
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2, or (at your option)
-# any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; see the file COPYING. If not, write to
-# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
-
-# Parse options.
-
-# defaults
-indent=8 # indent of log line
-length=79 # suggested max width of log line
-tabwidth=8 # width of horizontal tab
-
-while :
-do
- case $1 in
- -i) indent=${2?};;
- -l) length=${2?};;
- -t) tabwidth=${2?};;
- -*) echo >&2 "$0: usage: $0 [-i indent] [-l length] [-t tabwidth] [file ...]"
- exit 1;;
- *) break
- esac
- shift; shift
-done
-
-
-# Log into $rlogout the revisions checked in since the first ChangeLog entry.
-
-date=1970
-if test -s ChangeLog
-then
- # Add 1 to seconds to avoid duplicating most recent log.
- # It's a good thing `rlog' doesn't mind a time ending in `:60'.
- e='
- /^... ... [ 0-9][0-9] [ 0-9][0-9]:[0-9][0-9]:[0-9][0-9] [0-9]+ /{
- printf "%s%02d %s\n", substr($0,1,17), substr($0,18,2)+1, $5
- exit
- }
- '
- d=`awk "$e" <ChangeLog` || exit
- case $d in
- ?*) date=$d
- esac
-fi
-datearg="-d>$date"
-
-rlogout=/tmp/chg$$
-trap exit 1 2 13 15
-trap 'rm -f $rlogout; exit 1' 0
-
-case $# in
-0) set RCS/*
-esac
-
-rlog "$datearg" "$@" >$rlogout || exit
-
-
-# Get the full name of each author the logs mention, and set initialize_fullname
-# to awk code that initializes the `fullname' awk associative array.
-# Warning: foreign authors (i.e. not known in the passwd file) are mishandled;
-# you have to fix the resulting output by hand.
-
-initialize_fullname=
-authors=`
- sed -n 's|^date: *[0-9]*/[0-9][0-9]/[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9]; *author: *\([^; ]*\).*|\1|p' <$rlogout |
- sort -u
-`
-case $authors in
-?*)
- initialize_author=
- for author in $authors
- do
- initialize_author="$initialize_author
- author[\"$author\"] = 1
- "
- done
-
- awkscript='
- BEGIN {
- alphabet = "abcdefghijklmnopqrstuvwxyz"
- ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
- '"$initialize_author"'
- }
- {
- if (author[$1]) {
- fullname = $5
- abbr = index(fullname, "&")
- if (abbr) {
- a = substr($1, 1, 1)
- A = a
- i = index(alphabet, a)
- if (i) A = substr(ALPHABET, i, 1)
- fullname = substr(fullname, 1, abbr-1) A substr($1, 2) substr(fullname, abbr+1)
- }
- printf "fullname[\"%s\"] = \"%s\"\n", $1, fullname
- author[$1] = 0
- }
- }
- '
-
- initialize_fullname=`
- (cat /etc/passwd; ypmatch $authors passwd) 2>/dev/null |
- awk -F: "$awkscript"
- `
-esac
-
-
-# Function to print a single log line.
-# We don't use awk functions, to stay compatible with old awk versions.
-# `Log' is the log message (with \n replaced by \r).
-# `files' contains the affected files.
-printlogline='{
-
- # Following the GNU coding standards, rewrite
- # * file: (function): comment
- # to
- # * file (function): comment
- if (Log ~ /^\([^)]*\): /) {
- i = index(Log, ")")
- files = files " " substr(Log, 1, i)
- Log = substr(Log, i+3)
- }
-
- # If "label: comment" is too long, break the line after the ":".
- sep = " "
- if ('"$length"' <= '"$indent"' + 1 + length(files) + index(Log, "\r")) sep = "\n" indent_string
-
- # Print the label.
- printf "%s*%s:", indent_string, files
-
- # Print each line of the log, transliterating \r to \n.
- while ((i = index(Log, "\r")) != 0) {
- printf "%s%s\n", sep, substr(Log, 1, i-1)
- sep = indent_string
- Log = substr(Log, i+1)
- }
-}'
-
-hostname=`(
- hostname || cat /etc/whoami || uuname -l || uname -n
-) 2>/dev/null` || {
- echo >&2 "$0: cannot deduce hostname"
- exit 1
-}
-
-
-# Process the rlog output, generating ChangeLog style entries.
-
-# First, reformat the rlog output so that each line contains one log entry.
-# Transliterate \n to \r so that multiline entries fit on a single line.
-# Discard irrelevant rlog output.
-awk <$rlogout '
- /^Working file:/ { filename = $3 }
- /^date: /, /^(-----------*|===========*)$/ {
- if ($0 ~ /^branches: /) { next }
- if ($0 ~ /^date: [0-9][ /0-9:]*;/) {
- time = substr($3, 1, length($3)-1)
- author = substr($5, 1, length($5)-1)
- printf "%s %s %s %s \r", filename, $2, time, author
- next
- }
- if ($0 ~ /^(-----------*|===========*)$/) { print ""; next }
- printf "%s\r", $0
- }
-' |
-
-# Now each line is of the form
-# FILENAME YYYY/MM/DD HH:MM:SS AUTHOR \rLOG
-# where \r stands for a carriage return,
-# and each line of the log is terminated by \r instead of \n.
-# Sort the log entries, first by date+time (in reverse order),
-# then by author, then by log entry, and finally by file name (just in case).
-sort +1 -3r +3 +0 |
-
-# Finally, reformat the sorted log entries.
-awk '
- BEGIN {
-
- # Initialize the fullname associative array.
- '"$initialize_fullname"'
-
- # Initialize indent string.
- indent_string = ""
- i = '"$indent"'
- if (0 < '"$tabwidth"')
- for (; '"$tabwidth"' <= i; i -= '"$tabwidth"')
- indent_string = indent_string "\t"
- while (1 <= i--)
- indent_string = indent_string " "
-
- # Set up date conversion tables.
- # RCS uses a nice, clean, sortable format,
- # but ChangeLog wants the traditional, ugly ctime format.
-
- # January 1, 0 AD (Gregorian) was Saturday = 6
- EPOCH_WEEKDAY = 6
- # Of course, there was no 0 AD, but the algorithm works anyway.
-
- w[0]="Sun"; w[1]="Mon"; w[2]="Tue"; w[3]="Wed"
- w[4]="Thu"; w[5]="Fri"; w[6]="Sat"
-
- m[0]="Jan"; m[1]="Feb"; m[2]="Mar"
- m[3]="Apr"; m[4]="May"; m[5]="Jun"
- m[6]="Jul"; m[7]="Aug"; m[8]="Sep"
- m[9]="Oct"; m[10]="Nov"; m[11]="Dec"
-
- # days in non-leap year thus far, indexed by month (0-12)
- mo[0]=0; mo[1]=31; mo[2]=59; mo[3]=90
- mo[4]=120; mo[5]=151; mo[6]=181; mo[7]=212
- mo[8]=243; mo[9]=273; mo[10]=304; mo[11]=334
- mo[12]=365
- }
-
- {
- newlog = substr($0, 1 + index($0, "\r"))
-
- # Ignore log entries prefixed by "#".
- if (newlog ~ /^#/) { next }
-
- if (Log != newlog || date != $2 || author != $4) {
-
- # The previous log and this log differ.
-
- # Print the old log.
- if (date != "") '"$printlogline"'
-
- # Logs that begin with "{clumpname} " should be grouped together,
- # and the clumpname should be removed.
- # Extract the new clumpname from the log header,
- # and use it to decide whether to output a blank line.
- newclumpname = ""
- sep = "\n"
- if (date == "") sep = ""
- if (newlog ~ /^{[^ }]*}[ ]/) {
- i = index(newlog, "}")
- newclumpname = substr(newlog, 1, i)
- while (substr(newlog, i+1) ~ /^[ ]/) i++
- newlog = substr(newlog, i+1)
- if (clumpname == newclumpname) sep = ""
- }
- printf sep
- clumpname = newclumpname
-
- # Get ready for the next log.
- Log = newlog
- if (files != "")
- for (i in filesknown)
- filesknown[i] = 0
- files = ""
- }
- if (date != $2 || author != $4) {
- # The previous date+author and this date+author differ.
- # Print the new one.
- date = $2
- author = $4
-
- # Convert nice RCS date like "1992/01/03 00:03:44"
- # into ugly ctime date like "Fri Jan 3 00:03:44 1992".
- # Calculate day of week from Gregorian calendar.
- i = index($2, "/")
- year = substr($2, 1, i-1) + 0
- monthday = substr($2, i+1)
- i = index(monthday, "/")
- month = substr(monthday, 1, i-1) + 0
- day = substr(monthday, i+1) + 0
- leap = 0
- if (2 < month && year%4 == 0 && (year%100 != 0 || year%400 == 0)) leap = 1
- days_since_Sunday_before_epoch = EPOCH_WEEKDAY + year * 365 + int((year + 3) / 4) - int((year + 99) / 100) + int((year + 399) / 400) + mo[month-1] + leap + day - 1
-
- # Print "date fullname (email address)" if the fullname is known;
- # print "date author" otherwise.
- # Get the fullname from the associative array.
- # The email address is just author@thishostname.
- printf "%s %s %2d %s %d ", w[days_since_Sunday_before_epoch%7], m[month-1], day, $3, year
- if (fullname[author])
- printf "%s (%s@%s)\n\n", fullname[author], author, "'"$hostname"'"
- else
- printf "%s\n\n", author
- }
- if (! filesknown[$1]) {
- filesknown[$1] = 1
- if (files == "") files = " " $1
- else files = files ", " $1
- }
- }
- END {
- # Print the last log.
- if (date != "") {
- '"$printlogline"'
- printf "\n"
- }
- }
-' &&
-
-
-# Exit successfully.
-
-exec rm -f $rlogout
diff --git a/gnu/usr.bin/cvs/contrib/rcs2log.sh b/gnu/usr.bin/cvs/contrib/rcs2log.sh
deleted file mode 100644
index ccea907ea37b..000000000000
--- a/gnu/usr.bin/cvs/contrib/rcs2log.sh
+++ /dev/null
@@ -1,592 +0,0 @@
-#! /bin/sh
-
-# RCS to ChangeLog generator
-
-# Generate a change log prefix from RCS files and the ChangeLog (if any).
-# Output the new prefix to standard output.
-# You can edit this prefix by hand, and then prepend it to ChangeLog.
-
-# Ignore log entries that start with `#'.
-# Clump together log entries that start with `{topic} ',
-# where `topic' contains neither white space nor `}'.
-
-# Author: Paul Eggert <eggert@twinsun.com>
-
-# $Id: rcs2log.sh,v 1.2 1995/07/28 19:48:45 eggert Exp $
-
-# Copyright 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
-
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2, or (at your option)
-# any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; see the file COPYING. If not, write to
-# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
-tab=' '
-nl='
-'
-
-# Parse options.
-
-# defaults
-: ${AWK=awk}
-: ${TMPDIR=/tmp}
-hostname= # name of local host (if empty, will deduce it later)
-indent=8 # indent of log line
-length=79 # suggested max width of log line
-logins= # login names for people we know fullnames and mailaddrs of
-loginFullnameMailaddrs= # login<tab>fullname<tab>mailaddr triplets
-recursive= # t if we want recursive rlog
-rlog_options= # options to pass to rlog
-tabwidth=8 # width of horizontal tab
-
-while :
-do
- case $1 in
- -i) indent=${2?}; shift;;
- -h) hostname=${2?}; shift;;
- -l) length=${2?}; shift;;
- -[nu]) # -n is obsolescent; it is replaced by -u.
- case $1 in
- -n) case ${2?}${3?}${4?} in
- *"$tab"* | *"$nl"*)
- echo >&2 "$0: -n '$2' '$3' '$4': tabs, newlines not allowed"
- exit 1
- esac
- loginFullnameMailaddrs=$loginFullnameMailaddrs$nl$2$tab$3$tab$4
- shift; shift; shift;;
- -u)
- # If $2 is not tab-separated, use colon for separator.
- case ${2?} in
- *"$nl"*)
- echo >&2 "$0: -u '$2': newlines not allowed"
- exit 1;;
- *"$tab"*)
- t=$tab;;
- *)
- t=:
- esac
- case $2 in
- *"$t"*"$t"*"$t"*)
- echo >&2 "$0: -u '$2': too many fields"
- exit 1;;
- *"$t"*"$t"*)
- ;;
- *)
- echo >&2 "$0: -u '$2': not enough fields"
- exit 1
- esac
- loginFullnameMailaddrs=$loginFullnameMailaddrs$nl$2
- shift
- esac
- logins=$logins$nl$login
- ;;
- -r) rlog_options=$rlog_options$nl${2?}; shift;;
- -R) recursive=t;;
- -t) tabwidth=${2?}; shift;;
- -*) echo >&2 "$0: usage: $0 [options] [file ...]
-Options:
- [-h hostname] [-i indent] [-l length] [-R] [-r rlog_option]
- [-t tabwidth] [-u 'login<TAB>fullname<TAB>mailaddr']..."
- exit 1;;
- *) break
- esac
- shift
-done
-
-month_data='
- m[0]="Jan"; m[1]="Feb"; m[2]="Mar"
- m[3]="Apr"; m[4]="May"; m[5]="Jun"
- m[6]="Jul"; m[7]="Aug"; m[8]="Sep"
- m[9]="Oct"; m[10]="Nov"; m[11]="Dec"
-
- # days in non-leap year thus far, indexed by month (0-12)
- mo[0]=0; mo[1]=31; mo[2]=59; mo[3]=90
- mo[4]=120; mo[5]=151; mo[6]=181; mo[7]=212
- mo[8]=243; mo[9]=273; mo[10]=304; mo[11]=334
- mo[12]=365
-'
-
-
-# Put rlog output into $rlogout.
-
-# If no rlog options are given,
-# log the revisions checked in since the first ChangeLog entry.
-case $rlog_options in
-'')
- date=1970
- if test -s ChangeLog
- then
- # Add 1 to seconds to avoid duplicating most recent log.
- e='
- /^... ... [ 0-9][0-9] [ 0-9][0-9]:[0-9][0-9]:[0-9][0-9] [0-9]+ /{
- '"$month_data"'
- year = $5
- for (i=0; i<=11; i++) if (m[i] == $2) break
- dd = $3
- hh = substr($0,12,2)
- mm = substr($0,15,2)
- ss = substr($0,18,2)
- ss++
- if (ss == 60) {
- ss = 0
- mm++
- if (mm == 60) {
- mm = 0
- hh++
- if (hh == 24) {
- hh = 0
- dd++
- monthdays = mo[i+1] - mo[i]
- if (i == 1 && year%4 == 0 && (year%100 != 0 || year%400 == 0)) monthdays++
- if (dd == monthdays + 1) {
- dd = 1
- i++
- if (i == 12) {
- i = 0
- year++
- }
- }
- }
- }
- }
- # Output comma instead of space to avoid CVS 1.5 bug.
- printf "%d/%02d/%02d,%02d:%02d:%02d\n", year,i+1,dd,hh,mm,ss
- exit
- }
- '
- d=`$AWK "$e" <ChangeLog` || exit
- case $d in
- ?*) date=$d
- esac
- fi
- datearg="-d>$date"
-esac
-
-# If CVS is in use, examine its repository, not the normal RCS files.
-if test ! -f CVS/Repository
-then
- rlog=rlog
- repository=
-else
- rlog='cvs log'
- repository=`sed 1q <CVS/Repository` || exit
- test ! -f CVS/Root || CVSROOT=`cat <CVS/Root` || exit
- case $CVSROOT in
- *:/*)
- # remote repository
- ;;
- *)
- # local repository
- case $repository in
- /*) ;;
- *) repository=${CVSROOT?}/$repository
- esac
- if test ! -d "$repository"
- then
- echo >&2 "$0: $repository: bad repository (see CVS/Repository)"
- exit 1
- fi
- esac
-fi
-
-# With no arguments, examine all files under the RCS directory.
-case $# in
-0)
- case $repository in
- '')
- oldIFS=$IFS
- IFS=$nl
- case $recursive in
- t)
- RCSdirs=`find . -name RCS -type d -print`
- filesFromRCSfiles='s|,v$||; s|/RCS/|/|; s|^\./||'
- files=`
- {
- case $RCSdirs in
- ?*) find $RCSdirs -type f -print
- esac
- find . -name '*,v' -print
- } |
- sort -u |
- sed "$filesFromRCSfiles"
- `;;
- *)
- files=
- for file in RCS/.* RCS/* .*,v *,v
- do
- case $file in
- RCS/. | RCS/..) continue;;
- RCS/.\* | RCS/\* | .\*,v | \*,v) test -f "$file" || continue
- esac
- files=$files$nl$file
- done
- case $files in
- '') exit 0
- esac
- esac
- set x $files
- shift
- IFS=$oldIFS
- esac
-esac
-
-llogout=$TMPDIR/rcs2log$$l
-rlogout=$TMPDIR/rcs2log$$r
-trap exit 1 2 13 15
-trap "rm -f $llogout $rlogout; exit 1" 0
-
-case $rlog_options in
-?*) $rlog $rlog_options ${1+"$@"} >$rlogout;;
-'') $rlog "$datearg" ${1+"$@"} >$rlogout
-esac || exit
-
-
-# Get the full name of each author the logs mention, and set initialize_fullname
-# to awk code that initializes the `fullname' awk associative array.
-# Warning: foreign authors (i.e. not known in the passwd file) are mishandled;
-# you have to fix the resulting output by hand.
-
-initialize_fullname=
-initialize_mailaddr=
-
-case $loginFullnameMailaddrs in
-?*)
- case $loginFullnameMailaddrs in
- *\"* | *\\*)
- sed 's/["\\]/\\&/g' >$llogout <<EOF || exit
-$loginFullnameMailaddrs
-EOF
- loginFullnameMailaddrs=`cat $llogout`
- esac
-
- oldIFS=$IFS
- IFS=$nl
- for loginFullnameMailaddr in $loginFullnameMailaddrs
- do
- case $loginFullnameMailaddr in
- *"$tab"*) IFS=$tab;;
- *) IFS=:
- esac
- set x $loginFullnameMailaddr
- login=$2
- fullname=$3
- mailaddr=$4
- initialize_fullname="$initialize_fullname
- fullname[\"$login\"] = \"$fullname\""
- initialize_mailaddr="$initialize_mailaddr
- mailaddr[\"$login\"] = \"$mailaddr\""
- done
- IFS=$oldIFS
-esac
-
-case $llogout in
-?*) sort -u -o $llogout <<EOF || exit
-$logins
-EOF
-esac
-output_authors='/^date: / {
- if ($2 ~ /^[0-9]*[-\/][0-9][0-9][-\/][0-9][0-9]$/ && $3 ~ /^[0-9][0-9]:[0-9][0-9]:[0-9][0-9][-+0-9:]*;$/ && $4 == "author:" && $5 ~ /^[^;]*;$/) {
- print substr($5, 1, length($5)-1)
- }
-}'
-authors=`
- $AWK "$output_authors" <$rlogout |
- case $llogout in
- '') sort -u;;
- ?*) sort -u | comm -23 - $llogout
- esac
-`
-case $authors in
-?*)
- cat >$llogout <<EOF || exit
-$authors
-EOF
- initialize_author_script='s/["\\]/\\&/g; s/.*/author[\"&\"] = 1/'
- initialize_author=`sed -e "$initialize_author_script" <$llogout`
- awkscript='
- BEGIN {
- alphabet = "abcdefghijklmnopqrstuvwxyz"
- ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
- '"$initialize_author"'
- }
- {
- if (author[$1]) {
- fullname = $5
- if (fullname ~ /[0-9]+-[^(]*\([0-9]+\)$/) {
- # Remove the junk from fullnames like "0000-Admin(0000)".
- fullname = substr(fullname, index(fullname, "-") + 1)
- fullname = substr(fullname, 1, index(fullname, "(") - 1)
- }
- if (fullname ~ /,[^ ]/) {
- # Some sites put comma-separated junk after the fullname.
- # Remove it, but leave "Bill Gates, Jr" alone.
- fullname = substr(fullname, 1, index(fullname, ",") - 1)
- }
- abbr = index(fullname, "&")
- if (abbr) {
- a = substr($1, 1, 1)
- A = a
- i = index(alphabet, a)
- if (i) A = substr(ALPHABET, i, 1)
- fullname = substr(fullname, 1, abbr-1) A substr($1, 2) substr(fullname, abbr+1)
- }
-
- # Quote quotes and backslashes properly in full names.
- # Do not use gsub; traditional awk lacks it.
- quoted = ""
- rest = fullname
- for (;;) {
- p = index(rest, "\\")
- q = index(rest, "\"")
- if (p) {
- if (q && q<p) p = q
- } else {
- if (!q) break
- p = q
- }
- quoted = quoted substr(rest, 1, p-1) "\\" substr(rest, p, 1)
- rest = substr(rest, p+1)
- }
-
- printf "fullname[\"%s\"] = \"%s%s\"\n", $1, quoted, rest
- author[$1] = 0
- }
- }
- '
-
- initialize_fullname=`
- (cat /etc/passwd; ypmatch $authors passwd) 2>/dev/null |
- $AWK -F: "$awkscript"
- `$initialize_fullname
-esac
-
-
-# Function to print a single log line.
-# We don't use awk functions, to stay compatible with old awk versions.
-# `Log' is the log message (with \n replaced by \r).
-# `files' contains the affected files.
-printlogline='{
-
- # Following the GNU coding standards, rewrite
- # * file: (function): comment
- # to
- # * file (function): comment
- if (Log ~ /^\([^)]*\): /) {
- i = index(Log, ")")
- files = files " " substr(Log, 1, i)
- Log = substr(Log, i+3)
- }
-
- # If "label: comment" is too long, break the line after the ":".
- sep = " "
- if ('"$length"' <= '"$indent"' + 1 + length(files) + index(Log, CR)) sep = "\n" indent_string
-
- # Print the label.
- printf "%s*%s:", indent_string, files
-
- # Print each line of the log, transliterating \r to \n.
- while ((i = index(Log, CR)) != 0) {
- logline = substr(Log, 1, i-1)
- if (logline ~ /[^'"$tab"' ]/) {
- printf "%s%s\n", sep, logline
- } else {
- print ""
- }
- sep = indent_string
- Log = substr(Log, i+1)
- }
-}'
-
-case $hostname in
-'')
- hostname=`(
- hostname || uname -n || uuname -l || cat /etc/whoami
- ) 2>/dev/null` || {
- echo >&2 "$0: cannot deduce hostname"
- exit 1
- }
-esac
-
-
-# Process the rlog output, generating ChangeLog style entries.
-
-# First, reformat the rlog output so that each line contains one log entry.
-# Transliterate \n to \r so that multiline entries fit on a single line.
-# Discard irrelevant rlog output.
-$AWK <$rlogout '
- BEGIN { repository = "'"$repository"'" }
- /^RCS file:/ {
- if (repository != "") {
- filename = $3
- if (substr(filename, 1, length(repository) + 1) == repository "/") {
- filename = substr(filename, length(repository) + 2)
- }
- if (filename ~ /,v$/) {
- filename = substr(filename, 1, length(filename) - 2)
- }
- }
- }
- /^Working file:/ { if (repository == "") filename = $3 }
- /^date: /, /^(-----------*|===========*)$/ {
- if ($0 ~ /^branches: /) { next }
- if ($0 ~ /^date: [0-9][- +\/0-9:]*;/) {
- date = $2
- if (date ~ /-/) {
- # An ISO format date. Replace all "-"s with "/"s.
- newdate = ""
- while ((i = index(date, "-")) != 0) {
- newdate = newdate substr(date, 1, i-1) "/"
- date = substr(date, i+1)
- }
- date = newdate date
- }
- # Ignore any time zone; ChangeLog has no room for it.
- time = substr($3, 1, 8)
- author = substr($5, 1, length($5)-1)
- printf "%s %s %s %s %c", filename, date, time, author, 13
- next
- }
- if ($0 ~ /^(-----------*|===========*)$/) { print ""; next }
- printf "%s%c", $0, 13
- }
-' |
-
-# Now each line is of the form
-# FILENAME YYYY/MM/DD HH:MM:SS AUTHOR \rLOG
-# where \r stands for a carriage return,
-# and each line of the log is terminated by \r instead of \n.
-# Sort the log entries, first by date+time (in reverse order),
-# then by author, then by log entry, and finally by file name (just in case).
-sort +1 -3r +3 +0 |
-
-# Finally, reformat the sorted log entries.
-$AWK '
- BEGIN {
- # Some awk variants do not understand "\r" or "\013", so we have to
- # put a carriage return directly in the file.
- CR=" " # <-- There is a single CR between the " chars here.
-
- # Initialize the fullname and mailaddr associative arrays.
- '"$initialize_fullname"'
- '"$initialize_mailaddr"'
-
- # Initialize indent string.
- indent_string = ""
- i = '"$indent"'
- if (0 < '"$tabwidth"')
- for (; '"$tabwidth"' <= i; i -= '"$tabwidth"')
- indent_string = indent_string "\t"
- while (1 <= i--)
- indent_string = indent_string " "
-
- # Set up date conversion tables.
- # RCS uses a nice, clean, sortable format,
- # but ChangeLog wants the traditional, ugly ctime format.
-
- # January 1, 0 AD (Gregorian) was Saturday = 6
- EPOCH_WEEKDAY = 6
- # Of course, there was no 0 AD, but the algorithm works anyway.
-
- w[0]="Sun"; w[1]="Mon"; w[2]="Tue"; w[3]="Wed"
- w[4]="Thu"; w[5]="Fri"; w[6]="Sat"
-
- '"$month_data"'
- }
-
- {
- newlog = substr($0, 1 + index($0, CR))
-
- # Ignore log entries prefixed by "#".
- if (newlog ~ /^#/) { next }
-
- if (Log != newlog || date != $2 || author != $4) {
-
- # The previous log and this log differ.
-
- # Print the old log.
- if (date != "") '"$printlogline"'
-
- # Logs that begin with "{clumpname} " should be grouped together,
- # and the clumpname should be removed.
- # Extract the new clumpname from the log header,
- # and use it to decide whether to output a blank line.
- newclumpname = ""
- sep = "\n"
- if (date == "") sep = ""
- if (newlog ~ /^\{[^'"$tab"' }]*}['"$tab"' ]/) {
- i = index(newlog, "}")
- newclumpname = substr(newlog, 1, i)
- while (substr(newlog, i+1) ~ /^['"$tab"' ]/) i++
- newlog = substr(newlog, i+1)
- if (clumpname == newclumpname) sep = ""
- }
- printf sep
- clumpname = newclumpname
-
- # Get ready for the next log.
- Log = newlog
- if (files != "")
- for (i in filesknown)
- filesknown[i] = 0
- files = ""
- }
- if (date != $2 || author != $4) {
- # The previous date+author and this date+author differ.
- # Print the new one.
- date = $2
- author = $4
-
- # Convert nice RCS date like "1992/01/03 00:03:44"
- # into ugly ctime date like "Fri Jan 3 00:03:44 1992".
- # Calculate day of week from Gregorian calendar.
- i = index($2, "/")
- year = substr($2, 1, i-1) + 0
- monthday = substr($2, i+1)
- i = index(monthday, "/")
- month = substr(monthday, 1, i-1) + 0
- day = substr(monthday, i+1) + 0
- leap = 0
- if (2 < month && year%4 == 0 && (year%100 != 0 || year%400 == 0)) leap = 1
- days_since_Sunday_before_epoch = EPOCH_WEEKDAY + year * 365 + int((year + 3) / 4) - int((year + 99) / 100) + int((year + 399) / 400) + mo[month-1] + leap + day - 1
-
- # Print "date fullname (email address)".
- # Get fullname and email address from associative arrays;
- # default to author and author@hostname if not in arrays.
- if (fullname[author])
- auth = fullname[author]
- else
- auth = author
- printf "%s %s %2d %s %d %s ", w[days_since_Sunday_before_epoch%7], m[month-1], day, $3, year, auth
- if (mailaddr[author])
- printf "<%s>\n\n", mailaddr[author]
- else
- printf "<%s@%s>\n\n", author, "'"$hostname"'"
- }
- if (! filesknown[$1]) {
- filesknown[$1] = 1
- if (files == "") files = " " $1
- else files = files ", " $1
- }
- }
- END {
- # Print the last log.
- if (date != "") {
- '"$printlogline"'
- printf "\n"
- }
- }
-' &&
-
-
-# Exit successfully.
-
-exec rm -f $llogout $rlogout
diff --git a/gnu/usr.bin/cvs/contrib/rcs2sccs b/gnu/usr.bin/cvs/contrib/rcs2sccs
deleted file mode 100644
index 054ac6c1eca9..000000000000
--- a/gnu/usr.bin/cvs/contrib/rcs2sccs
+++ /dev/null
@@ -1,143 +0,0 @@
-#!/bin/sh
-#
-#
-# OrigId: rcs2sccs,v 1.12 90/10/04 20:52:23 kenc Exp Locker: kenc
-# $Id: rcs2sccs,v 1.1 1993/12/06 06:37:14 berliner Exp $
-
-############################################################
-# Error checking
-#
-if [ ! -d SCCS ] ; then
- mkdir SCCS
-fi
-
-logfile=/tmp/rcs2sccs_$$_log
-rm -f $logfile
-tmpfile=/tmp/rcs2sccs_$$_tmp
-rm -f $tmpfile
-emptyfile=/tmp/rcs2sccs_$$_empty
-echo -n "" > $emptyfile
-initialfile=/tmp/rcs2sccs_$$_init
-echo "Initial revision" > $initialfile
-sedfile=/tmp/rcs2sccs_$$_sed
-rm -f $sedfile
-revfile=/tmp/rcs2sccs_$$_rev
-rm -f $revfile
-commentfile=/tmp/rcs2sccs_$$_comment
-rm -f $commentfile
-
-# create the sed script
-cat > $sedfile << EOF
-s,;Id;,%Z%%M% %I% %E%,g
-s,;SunId;,%Z%%M% %I% %E%,g
-s,;RCSfile;,%M%,g
-s,;Revision;,%I%,g
-s,;Date;,%E%,g
-s,;Id:.*;,%Z%%M% %I% %E%,g
-s,;SunId:.*;,%Z%%M% %I% %E%,g
-s,;RCSfile:.*;,%M%,g
-s,;Revision:.*;,%I%,g
-s,;Date:.*;,%E%,g
-EOF
-sed -e 's/;/\\$/g' $sedfile > $tmpfile
-cp $tmpfile $sedfile
-############################################################
-# Loop over every RCS file in RCS dir
-#
-for vfile in *,v; do
- # get rid of the ",v" at the end of the name
- file=`echo $vfile | sed -e 's/,v$//'`
-
- # work on each rev of that file in ascending order
- firsttime=1
- rlog $file | grep "^revision [0-9][0-9]*\." | awk '{print $2}' | sed -e 's/\./ /g' | sort -n -u +0 +1 +2 +3 +4 +5 +6 +7 +8 | sed -e 's/ /./g' > $revfile
- for rev in `cat $revfile`; do
- if [ $? != 0 ]; then
- echo ERROR - revision
- exit
- fi
- # get file into current dir and get stats
- date=`rlog -r$rev $file | grep "^date: " | awk '{print $2; exit}' | sed -e 's/^19//'`
- time=`rlog -r$rev $file | grep "^date: " | awk '{print $3; exit}' | sed -e 's/;//'`
- author=`rlog -r$rev $file | grep "^date: " | awk '{print $5; exit}' | sed -e 's/;//'`
- date="$date $time"
- echo ""
- rlog -r$rev $file | sed -e '/^branches: /d' -e '1,/^date: /d' -e '/^===========/d' -e 's/$/\\/' | awk '{if ((total += length($0) + 1) < 510) print $0}' > $commentfile
- echo "==> file $file, rev=$rev, date=$date, author=$author"
- rm -f $file
- co -r$rev $file >> $logfile 2>&1
- if [ $? != 0 ]; then
- echo ERROR - co
- exit
- fi
- echo checked out of RCS
-
- # add SCCS keywords in place of RCS keywords
- sed -f $sedfile $file > $tmpfile
- if [ $? != 0 ]; then
- echo ERROR - sed
- exit
- fi
- echo performed keyword substitutions
- rm -f $file
- cp $tmpfile $file
-
- # check file into SCCS
- if [ "$firsttime" = "1" ]; then
- firsttime=0
- echo about to do sccs admin
- echo sccs admin -n -i$file $file < $commentfile
- sccs admin -n -i$file $file < $commentfile >> $logfile 2>&1
- if [ $? != 0 ]; then
- echo ERROR - sccs admin
- exit
- fi
- echo initial rev checked into SCCS
- else
- case $rev in
- *.*.*.*)
- brev=`echo $rev | sed -e 's/\.[0-9]*$//'`
- sccs admin -fb $file 2>>$logfile
- echo sccs get -e -p -r$brev $file
- sccs get -e -p -r$brev $file >/dev/null 2>>$logfile
- ;;
- *)
- echo sccs get -e -p $file
- sccs get -e -p $file >/dev/null 2>> $logfile
- ;;
- esac
- if [ $? != 0 ]; then
- echo ERROR - sccs get
- exit
- fi
- sccs delta $file < $commentfile >> $logfile 2>&1
- if [ $? != 0 ]; then
- echo ERROR - sccs delta -r$rev $file
- exit
- fi
- echo checked into SCCS
- fi
- sed -e "s;^d D $rev ../../.. ..:..:.. [^ ][^ ]*;d D $rev $date $author;" SCCS/s.$file > $tmpfile
- rm -f SCCS/s.$file
- cp $tmpfile SCCS/s.$file
- chmod 444 SCCS/s.$file
- sccs admin -z $file
- if [ $? != 0 ]; then
- echo ERROR - sccs admin -z
- exit
- fi
- done
- rm -f $file
-done
-
-
-############################################################
-# Clean up
-#
-echo cleaning up...
-rm -f $tmpfile $emptyfile $initialfile $sedfile $commentfile
-echo ===================================================
-echo " Conversion Completed Successfully"
-echo ===================================================
-
-rm -f *,v
diff --git a/gnu/usr.bin/cvs/contrib/rcs2sccs.sh b/gnu/usr.bin/cvs/contrib/rcs2sccs.sh
deleted file mode 100644
index af701384e4b6..000000000000
--- a/gnu/usr.bin/cvs/contrib/rcs2sccs.sh
+++ /dev/null
@@ -1,143 +0,0 @@
-#! /bin/sh
-#
-#
-# OrigId: rcs2sccs,v 1.12 90/10/04 20:52:23 kenc Exp Locker: kenc
-# $Id: rcs2sccs.sh,v 1.1 1995/07/10 02:26:45 kfogel Exp $
-
-############################################################
-# Error checking
-#
-if [ ! -d SCCS ] ; then
- mkdir SCCS
-fi
-
-logfile=/tmp/rcs2sccs_$$_log
-rm -f $logfile
-tmpfile=/tmp/rcs2sccs_$$_tmp
-rm -f $tmpfile
-emptyfile=/tmp/rcs2sccs_$$_empty
-echo -n "" > $emptyfile
-initialfile=/tmp/rcs2sccs_$$_init
-echo "Initial revision" > $initialfile
-sedfile=/tmp/rcs2sccs_$$_sed
-rm -f $sedfile
-revfile=/tmp/rcs2sccs_$$_rev
-rm -f $revfile
-commentfile=/tmp/rcs2sccs_$$_comment
-rm -f $commentfile
-
-# create the sed script
-cat > $sedfile << EOF
-s,;Id;,%Z%%M% %I% %E%,g
-s,;SunId;,%Z%%M% %I% %E%,g
-s,;RCSfile;,%M%,g
-s,;Revision;,%I%,g
-s,;Date;,%E%,g
-s,;Id:.*;,%Z%%M% %I% %E%,g
-s,;SunId:.*;,%Z%%M% %I% %E%,g
-s,;RCSfile:.*;,%M%,g
-s,;Revision:.*;,%I%,g
-s,;Date:.*;,%E%,g
-EOF
-sed -e 's/;/\\$/g' $sedfile > $tmpfile
-cp $tmpfile $sedfile
-############################################################
-# Loop over every RCS file in RCS dir
-#
-for vfile in *,v; do
- # get rid of the ",v" at the end of the name
- file=`echo $vfile | sed -e 's/,v$//'`
-
- # work on each rev of that file in ascending order
- firsttime=1
- rlog $file | grep "^revision [0-9][0-9]*\." | awk '{print $2}' | sed -e 's/\./ /g' | sort -n -u +0 +1 +2 +3 +4 +5 +6 +7 +8 | sed -e 's/ /./g' > $revfile
- for rev in `cat $revfile`; do
- if [ $? != 0 ]; then
- echo ERROR - revision
- exit
- fi
- # get file into current dir and get stats
- date=`rlog -r$rev $file | grep "^date: " | awk '{print $2; exit}' | sed -e 's/^19//'`
- time=`rlog -r$rev $file | grep "^date: " | awk '{print $3; exit}' | sed -e 's/;//'`
- author=`rlog -r$rev $file | grep "^date: " | awk '{print $5; exit}' | sed -e 's/;//'`
- date="$date $time"
- echo ""
- rlog -r$rev $file | sed -e '/^branches: /d' -e '1,/^date: /d' -e '/^===========/d' -e 's/$/\\/' | awk '{if ((total += length($0) + 1) < 510) print $0}' > $commentfile
- echo "==> file $file, rev=$rev, date=$date, author=$author"
- rm -f $file
- co -r$rev $file >> $logfile 2>&1
- if [ $? != 0 ]; then
- echo ERROR - co
- exit
- fi
- echo checked out of RCS
-
- # add SCCS keywords in place of RCS keywords
- sed -f $sedfile $file > $tmpfile
- if [ $? != 0 ]; then
- echo ERROR - sed
- exit
- fi
- echo performed keyword substitutions
- rm -f $file
- cp $tmpfile $file
-
- # check file into SCCS
- if [ "$firsttime" = "1" ]; then
- firsttime=0
- echo about to do sccs admin
- echo sccs admin -n -i$file $file < $commentfile
- sccs admin -n -i$file $file < $commentfile >> $logfile 2>&1
- if [ $? != 0 ]; then
- echo ERROR - sccs admin
- exit
- fi
- echo initial rev checked into SCCS
- else
- case $rev in
- *.*.*.*)
- brev=`echo $rev | sed -e 's/\.[0-9]*$//'`
- sccs admin -fb $file 2>>$logfile
- echo sccs get -e -p -r$brev $file
- sccs get -e -p -r$brev $file >/dev/null 2>>$logfile
- ;;
- *)
- echo sccs get -e -p $file
- sccs get -e -p $file >/dev/null 2>> $logfile
- ;;
- esac
- if [ $? != 0 ]; then
- echo ERROR - sccs get
- exit
- fi
- sccs delta $file < $commentfile >> $logfile 2>&1
- if [ $? != 0 ]; then
- echo ERROR - sccs delta -r$rev $file
- exit
- fi
- echo checked into SCCS
- fi
- sed -e "s;^d D $rev ../../.. ..:..:.. [^ ][^ ]*;d D $rev $date $author;" SCCS/s.$file > $tmpfile
- rm -f SCCS/s.$file
- cp $tmpfile SCCS/s.$file
- chmod 444 SCCS/s.$file
- sccs admin -z $file
- if [ $? != 0 ]; then
- echo ERROR - sccs admin -z
- exit
- fi
- done
- rm -f $file
-done
-
-
-############################################################
-# Clean up
-#
-echo cleaning up...
-rm -f $tmpfile $emptyfile $initialfile $sedfile $commentfile
-echo ===================================================
-echo " Conversion Completed Successfully"
-echo ===================================================
-
-rm -f *,v
diff --git a/gnu/usr.bin/cvs/contrib/rcslock.pl b/gnu/usr.bin/cvs/contrib/rcslock.pl
deleted file mode 100644
index 01e349ff0258..000000000000
--- a/gnu/usr.bin/cvs/contrib/rcslock.pl
+++ /dev/null
@@ -1,235 +0,0 @@
-#! xPERL_PATHx
-# -*-Perl-*-
-
-# Author: John Rouillard (rouilj@cs.umb.edu)
-# Supported: Yeah right. (Well what do you expect for 2 hours work?)
-# Blame-to: rouilj@cs.umb.edu
-# Complaints to: Anybody except Brian Berliner, he's blameless for
-# this script.
-# Acknowlegements: The base code for this script has been acquired
-# from the log.pl script.
-
-# rcslock.pl - A program to prevent commits when a file to be ckecked
-# in is locked in the repository.
-
-# There are times when you need exclusive access to a file. This
-# often occurs when binaries are checked into the repository, since
-# cvs's (actually rcs's) text based merging mechanism won't work. This
-# script allows you to use the rcs lock mechanism (rcs -l) to make
-# sure that no changes to a repository are able to be committed if
-# those changes would result in a locked file being changed.
-
-# WARNING:
-# This script will work only if locking is set to strict.
-#
-
-# Setup:
-# Add the following line to the commitinfo file:
-
-# ALL /local/location/for/script/lockcheck [options]
-
-# Where ALL is replaced by any suitable regular expression.
-# Options are -v for verbose info, or -d for debugging info.
-# The %s will provide the repository directory name and the names of
-# all changed files.
-
-# Use:
-# When a developer needs exclusive access to a version of a file, s/he
-# should use "rcs -l" in the repository tree to lock the version they
-# are working on. CVS will automagically release the lock when the
-# commit is performed.
-
-# Method:
-# An "rlog -h" is exec'ed to give info on all about to be
-# committed files. This (header) information is parsed to determine
-# if any locks are outstanding and what versions of the file are
-# locked. This filename, version number info is used to index an
-# associative array. All of the files to be committed are checked to
-# see if any locks are outstanding. If locks are outstanding, the
-# version number of the current file (taken from the CVS/Entries
-# subdirectory) is used in the key to determine if that version is
-# locked. If the file being checked in is locked by the person doing
-# the checkin, the commit is allowed, but if the lock is held on that
-# version of a file by another person, the commit is not allowed.
-
-$ext = ",v"; # The extension on your rcs files.
-
-$\="\n"; # I hate having to put \n's at the end of my print statements
-$,=' '; # Spaces should occur between arguments to print when printed
-
-# turn off setgid
-#
-$) = $(;
-
-#
-# parse command line arguments
-#
-require 'getopts.pl';
-
-&Getopts("vd"); # verbose or debugging
-
-# Verbose is useful when debugging
-$opt_v = $opt_d if defined $opt_d;
-
-# $files[0] is really the name of the subdirectory.
-# @files = split(/ /,$ARGV[0]);
-@files = @ARGV[0..$#ARGV];
-$cvsroot = $ENV{'CVSROOT'};
-
-#
-# get login name
-#
-$login = getlogin || (getpwuid($<))[0] || "nobody";
-
-#
-# save the current directory since we have to return here to parse the
-# CVS/Entries file if a lock is found.
-#
-$pwd = `/bin/pwd`;
-chop $pwd;
-
-print "Starting directory is $pwd" if defined $opt_d ;
-
-#
-# cd to the repository directory and check on the files.
-#
-print "Checking directory ", $files[0] if defined $opt_v ;
-
-if ( $files[0] =~ /^\// )
-{
- print "Directory path is $files[0]" if defined $opt_d ;
- chdir $files[0] || die "Can't change to repository directory $files[0]" ;
-}
-else
-{
- print "Directory path is $cvsroot/$files[0]" if defined $opt_d ;
- chdir ($cvsroot . "/" . $files[0]) ||
- die "Can't change to repository directory $files[0] in $cvsroot" ;
-}
-
-
-# Open the rlog process and apss all of the file names to that one
-# process to cut down on exec overhead. This may backfire if there
-# are too many files for the system buffer to handle, but if there are
-# that many files, chances are that the cvs repository is not set up
-# cleanly.
-
-print "opening rlog -h @files[1..$#files] |" if defined $opt_d;
-
-open( RLOG, "rlog -h @files[1..$#files] |") || die "Can't run rlog command" ;
-
-# Create the locks associative array. The elements in the array are
-# of two types:
-#
-# The name of the RCS file with a value of the total number of locks found
-# for that file,
-# or
-#
-# The name of the rcs file concatenated with the version number of the lock.
-# The value of this element is the name of the locker.
-
-# The regular expressions used to split the rcs info may have to be changed.
-# The current ones work for rcs 5.6.
-
-$lock = 0;
-
-while (<RLOG>)
-{
- chop;
- next if /^$/; # ditch blank lines
-
- if ( $_ =~ /^RCS file: (.*)$/ )
- {
- $curfile = $1;
- next;
- }
-
- if ( $_ =~ /^locks: strict$/ )
- {
- $lock = 1 ;
- next;
- }
-
- if ( $lock )
- {
- # access list: is the line immediately following the list of locks.
- if ( /^access list:/ )
- { # we are done getting lock info for this file.
- $lock = 0;
- }
- else
- { # We are accumulating lock info.
-
- # increment the lock count
- $locks{$curfile}++;
- # save the info on the version that is locked. $2 is the
- # version number $1 is the name of the locker.
- $locks{"$curfile" . "$2"} = $1
- if /[ ]*([a-zA-Z._]*): ([0-9.]*)$/;
-
- print "lock by $1 found on $curfile version $2" if defined $opt_d;
-
- }
- }
-}
-
-# Lets go back to the starting directory and see if any locked files
-# are ones we are interested in.
-
-chdir $pwd;
-
-# fo all of the file names (remember $files[0] is the directory name
-foreach $i (@files[1..$#files])
-{
- if ( defined $locks{$i . $ext} )
- { # well the file has at least one lock outstanding
-
- # find the base version number of our file
- &parse_cvs_entry($i,*entry);
-
- # is our version of this file locked?
- if ( defined $locks{$i . $ext . $entry{"version"}} )
- { # if so, it is by us?
- if ( $login ne ($by = $locks{$i . $ext . $entry{"version"}}) )
- {# crud somebody else has it locked.
- $outstanding_lock++ ;
- print "$by has file $i locked for version " , $entry{"version"};
- }
- else
- { # yeah I have it locked.
- print "You have a lock on file $i for version " , $entry{"version"}
- if defined $opt_v;
- }
- }
- }
-}
-
-exit $outstanding_lock;
-
-
-### End of main program
-
-sub parse_cvs_entry
-{ # a very simple minded hack at parsing an entries file.
-local ( $file, *entry ) = @_;
-local ( @pp );
-
-
-open(ENTRIES, "< CVS/Entries") || die "Can't open entries file";
-
-while (<ENTRIES>)
- {
- if ( $_ =~ /^\/$file\// )
- {
- @pp = split('/');
-
- $entry{"name"} = $pp[1];
- $entry{"version"} = $pp[2];
- $entry{"dates"} = $pp[3];
- $entry{"name"} = $pp[4];
- $entry{"name"} = $pp[5];
- $entry{"sticky"} = $pp[6];
- return;
- }
- }
-}
diff --git a/gnu/usr.bin/cvs/contrib/sccs2rcs b/gnu/usr.bin/cvs/contrib/sccs2rcs
deleted file mode 100644
index 654024bf3fc3..000000000000
--- a/gnu/usr.bin/cvs/contrib/sccs2rcs
+++ /dev/null
@@ -1,277 +0,0 @@
-#!/bin/csh -f
-#
-# Sccs2rcs is a script to convert an existing SCCS
-# history into an RCS history without losing any of
-# the information contained therein.
-# It has been tested under the following OS's:
-# SunOS 3.5, 4.0.3, 4.1
-# Ultrix-32 2.0, 3.1
-#
-# Things to note:
-# + It will NOT delete or alter your ./SCCS history under any circumstances.
-#
-# + Run in a directory where ./SCCS exists and where you can
-# create ./RCS
-#
-# + /usr/local/bin is put in front of the default path.
-# (SCCS under Ultrix is set-uid sccs, bad bad bad, so
-# /usr/local/bin/sccs here fixes that)
-#
-# + Date, time, author, comments, branches, are all preserved.
-#
-# + If a command fails somewhere in the middle, it bombs with
-# a message -- remove what it's done so far and try again.
-# "rm -rf RCS; sccs unedit `sccs tell`; sccs clean"
-# There is no recovery and exit is far from graceful.
-# If a particular module is hanging you up, consider
-# doing it separately; move it from the current area so that
-# the next run will have a better chance or working.
-# Also (for the brave only) you might consider hacking
-# the s-file for simpler problems: I've successfully changed
-# the date of a delta to be in sync, then run "sccs admin -z"
-# on the thing.
-#
-# + After everything finishes, ./SCCS will be moved to ./old-SCCS.
-#
-# This file may be copied, processed, hacked, mutilated, and
-# even destroyed as long as you don't tell anyone you wrote it.
-#
-# Ken Cox
-# Viewlogic Systems, Inc.
-# kenstir@viewlogic.com
-# ...!harvard!cg-atla!viewlog!kenstir
-#
-# Various hacks made by Brian Berliner before inclusion in CVS contrib area.
-#
-# $Id: sccs2rcs,v 1.1 1992/04/10 03:04:26 berliner Exp $
-
-
-#we'll assume the user set up the path correctly
-# for the Pmax, /usr/ucb/sccs is suid sccs, what a pain
-# /usr/local/bin/sccs should override /usr/ucb/sccs there
-set path = (/usr/local/bin $path)
-
-
-############################################################
-# Error checking
-#
-if (! -w .) then
- echo "Error: ./ not writeable by you."
- exit 1
-endif
-if (! -d SCCS) then
- echo "Error: ./SCCS directory not found."
- exit 1
-endif
-set edits = (`sccs tell`)
-if ($#edits) then
- echo "Error: $#edits file(s) out for edit...clean up before converting."
- exit 1
-endif
-if (-d RCS) then
- echo "Warning: RCS directory exists"
- if (`ls -a RCS | wc -l` > 2) then
- echo "Error: RCS directory not empty
- exit 1
- endif
-else
- mkdir RCS
-endif
-
-sccs clean
-
-set logfile = /tmp/sccs2rcs_$$_log
-rm -f $logfile
-set tmpfile = /tmp/sccs2rcs_$$_tmp
-rm -f $tmpfile
-set emptyfile = /tmp/sccs2rcs_$$_empty
-echo -n "" > $emptyfile
-set initialfile = /tmp/sccs2rcs_$$_init
-echo "Initial revision" > $initialfile
-set sedfile = /tmp/sccs2rcs_$$_sed
-rm -f $sedfile
-set revfile = /tmp/sccs2rcs_$$_rev
-rm -f $revfile
-
-# the quotes surround the dollar signs to fool RCS when I check in this script
-set sccs_keywords = (\
- '%W%[ ]*%G%'\
- '%W%[ ]*%E%'\
- '%W%'\
- '%Z%%M%[ ]*%I%[ ]*%G%'\
- '%Z%%M%[ ]*%I%[ ]*%E%'\
- '%M%[ ]*%I%[ ]*%G%'\
- '%M%[ ]*%I%[ ]*%E%'\
- '%M%'\
- '%I%'\
- '%G%'\
- '%E%'\
- '%U%')
-set rcs_keywords = (\
- '$'Id'$'\
- '$'Id'$'\
- '$'Id'$'\
- '$'SunId'$'\
- '$'SunId'$'\
- '$'Id'$'\
- '$'Id'$'\
- '$'RCSfile'$'\
- '$'Revision'$'\
- '$'Date'$'\
- '$'Date'$'\
- '')
-
-
-############################################################
-# Get some answers from user
-#
-echo ""
-echo "Do you want to be prompted for a description of each"
-echo "file as it is checked in to RCS initially?"
-echo -n "(y=prompt for description, n=null description) [y] ?"
-set ans = $<
-if ((_$ans == _) || (_$ans == _y) || (_$ans == _Y)) then
- set nodesc = 0
-else
- set nodesc = 1
-endif
-echo ""
-echo "The default keyword substitutions are as follows and are"
-echo "applied in the order specified:"
-set i = 1
-while ($i <= $#sccs_keywords)
-# echo ' '\"$sccs_keywords[$i]\"' ==> '\"$rcs_keywords[$i]\"
- echo " $sccs_keywords[$i] ==> $rcs_keywords[$i]"
- @ i = $i + 1
-end
-echo ""
-echo -n "Do you want to change them [n] ?"
-set ans = $<
-if ((_$ans != _) && (_$ans != _n) && (_$ans != _N)) then
- echo "You can't always get what you want."
- echo "Edit this script file and change the variables:"
- echo ' $sccs_keywords'
- echo ' $rcs_keywords'
-else
- echo "good idea."
-endif
-
-# create the sed script
-set i = 1
-while ($i <= $#sccs_keywords)
- echo "s,$sccs_keywords[$i],$rcs_keywords[$i],g" >> $sedfile
- @ i = $i + 1
-end
-
-onintr ERROR
-
-############################################################
-# Loop over every s-file in SCCS dir
-#
-foreach sfile (SCCS/s.*)
- # get rid of the "s." at the beginning of the name
- set file = `echo $sfile:t | sed -e "s/^..//"`
-
- # work on each rev of that file in ascending order
- set firsttime = 1
- sccs prs $file | grep "^D " | awk '{print $2}' | sed -e 's/\./ /g' | sort -n -u +0 +1 +2 +3 +4 +5 +6 +7 +8 | sed -e 's/ /./g' > $revfile
- foreach rev (`cat $revfile`)
- if ($status != 0) goto ERROR
-
- # get file into current dir and get stats
- set date = `sccs prs -r$rev $file | grep "^D " | awk '{printf("19%s %s", $3, $4); exit}'`
- set author = `sccs prs -r$rev $file | grep "^D " | awk '{print $5; exit}'`
- echo ""
- echo "==> file $file, rev=$rev, date=$date, author=$author"
- sccs edit -r$rev $file >>& $logfile
- if ($status != 0) goto ERROR
- echo checked out of SCCS
-
- # add RCS keywords in place of SCCS keywords
- sed -f $sedfile $file > $tmpfile
- if ($status != 0) goto ERROR
- echo performed keyword substitutions
- cp $tmpfile $file
-
- # check file into RCS
- if ($firsttime) then
- set firsttime = 0
- if ($nodesc) then
- echo about to do ci
- echo ci -f -r$rev -d"$date" -w$author -t$emptyfile $file
- ci -f -r$rev -d"$date" -w$author -t$emptyfile $file < $initialfile >>& $logfile
- if ($status != 0) goto ERROR
- echo initial rev checked into RCS without description
- else
- echo ""
- echo Enter a brief description of the file $file \(end w/ Ctrl-D\):
- cat > $tmpfile
- ci -f -r$rev -d"$date" -w$author -t$tmpfile $file < $initialfile >>& $logfile
- if ($status != 0) goto ERROR
- echo initial rev checked into RCS
- endif
- else
- # get RCS lock
- set lckrev = `echo $rev | sed -e 's/\.[0-9]*$//'`
- if ("$lckrev" =~ [0-9]*.*) then
- # need to lock the brach -- it is OK if the lock fails
- rcs -l$lckrev $file >>& $logfile
- else
- # need to lock the trunk -- must succeed
- rcs -l $file >>& $logfile
- if ($status != 0) goto ERROR
- endif
- echo got lock
- sccs prs -r$rev $file | grep "." > $tmpfile
- # it's OK if grep fails here and gives status == 1
- # put the delta message in $tmpfile
- ed $tmpfile >>& $logfile <<EOF
-/COMMENTS
-1,.d
-w
-q
-EOF
- ci -f -r$rev -d"$date" -w$author $file < $tmpfile >>& $logfile
- if ($status != 0) goto ERROR
- echo checked into RCS
- endif
- sccs unedit $file >>& $logfile
- if ($status != 0) goto ERROR
- end
- rm -f $file
-end
-
-
-############################################################
-# Clean up
-#
-echo cleaning up...
-mv SCCS old-SCCS
-rm -f $tmpfile $emptyfile $initialfile $sedfile
-echo ===================================================
-echo " Conversion Completed Successfully"
-echo ""
-echo " SCCS history now in old-SCCS/"
-echo ===================================================
-set exitval = 0
-goto cleanup
-
-ERROR:
-foreach f (`sccs tell`)
- sccs unedit $f
-end
-echo ""
-echo ""
-echo Danger\! Danger\!
-echo Some command exited with a non-zero exit status.
-echo Log file exists in $logfile.
-echo ""
-echo Incomplete history in ./RCS -- remove it
-echo Original unchanged history in ./SCCS
-set exitval = 1
-
-cleanup:
-# leave log file
-rm -f $tmpfile $emptyfile $initialfile $sedfile $revfile
-
-exit $exitval
diff --git a/gnu/usr.bin/cvs/contrib/sccs2rcs.csh b/gnu/usr.bin/cvs/contrib/sccs2rcs.csh
deleted file mode 100644
index 0f31893d3b24..000000000000
--- a/gnu/usr.bin/cvs/contrib/sccs2rcs.csh
+++ /dev/null
@@ -1,277 +0,0 @@
-#! xCSH_PATHx -f
-#
-# Sccs2rcs is a script to convert an existing SCCS
-# history into an RCS history without losing any of
-# the information contained therein.
-# It has been tested under the following OS's:
-# SunOS 3.5, 4.0.3, 4.1
-# Ultrix-32 2.0, 3.1
-#
-# Things to note:
-# + It will NOT delete or alter your ./SCCS history under any circumstances.
-#
-# + Run in a directory where ./SCCS exists and where you can
-# create ./RCS
-#
-# + /usr/local/bin is put in front of the default path.
-# (SCCS under Ultrix is set-uid sccs, bad bad bad, so
-# /usr/local/bin/sccs here fixes that)
-#
-# + Date, time, author, comments, branches, are all preserved.
-#
-# + If a command fails somewhere in the middle, it bombs with
-# a message -- remove what it's done so far and try again.
-# "rm -rf RCS; sccs unedit `sccs tell`; sccs clean"
-# There is no recovery and exit is far from graceful.
-# If a particular module is hanging you up, consider
-# doing it separately; move it from the current area so that
-# the next run will have a better chance or working.
-# Also (for the brave only) you might consider hacking
-# the s-file for simpler problems: I've successfully changed
-# the date of a delta to be in sync, then run "sccs admin -z"
-# on the thing.
-#
-# + After everything finishes, ./SCCS will be moved to ./old-SCCS.
-#
-# This file may be copied, processed, hacked, mutilated, and
-# even destroyed as long as you don't tell anyone you wrote it.
-#
-# Ken Cox
-# Viewlogic Systems, Inc.
-# kenstir@viewlogic.com
-# ...!harvard!cg-atla!viewlog!kenstir
-#
-# Various hacks made by Brian Berliner before inclusion in CVS contrib area.
-#
-# $Id: sccs2rcs.csh,v 1.1 1995/07/10 02:26:48 kfogel Exp $
-
-
-#we'll assume the user set up the path correctly
-# for the Pmax, /usr/ucb/sccs is suid sccs, what a pain
-# /usr/local/bin/sccs should override /usr/ucb/sccs there
-set path = (/usr/local/bin $path)
-
-
-############################################################
-# Error checking
-#
-if (! -w .) then
- echo "Error: ./ not writeable by you."
- exit 1
-endif
-if (! -d SCCS) then
- echo "Error: ./SCCS directory not found."
- exit 1
-endif
-set edits = (`sccs tell`)
-if ($#edits) then
- echo "Error: $#edits file(s) out for edit...clean up before converting."
- exit 1
-endif
-if (-d RCS) then
- echo "Warning: RCS directory exists"
- if (`ls -a RCS | wc -l` > 2) then
- echo "Error: RCS directory not empty
- exit 1
- endif
-else
- mkdir RCS
-endif
-
-sccs clean
-
-set logfile = /tmp/sccs2rcs_$$_log
-rm -f $logfile
-set tmpfile = /tmp/sccs2rcs_$$_tmp
-rm -f $tmpfile
-set emptyfile = /tmp/sccs2rcs_$$_empty
-echo -n "" > $emptyfile
-set initialfile = /tmp/sccs2rcs_$$_init
-echo "Initial revision" > $initialfile
-set sedfile = /tmp/sccs2rcs_$$_sed
-rm -f $sedfile
-set revfile = /tmp/sccs2rcs_$$_rev
-rm -f $revfile
-
-# the quotes surround the dollar signs to fool RCS when I check in this script
-set sccs_keywords = (\
- '%W%[ ]*%G%'\
- '%W%[ ]*%E%'\
- '%W%'\
- '%Z%%M%[ ]*%I%[ ]*%G%'\
- '%Z%%M%[ ]*%I%[ ]*%E%'\
- '%M%[ ]*%I%[ ]*%G%'\
- '%M%[ ]*%I%[ ]*%E%'\
- '%M%'\
- '%I%'\
- '%G%'\
- '%E%'\
- '%U%')
-set rcs_keywords = (\
- '$'Id'$'\
- '$'Id'$'\
- '$'Id'$'\
- '$'SunId'$'\
- '$'SunId'$'\
- '$'Id'$'\
- '$'Id'$'\
- '$'RCSfile'$'\
- '$'Revision'$'\
- '$'Date'$'\
- '$'Date'$'\
- '')
-
-
-############################################################
-# Get some answers from user
-#
-echo ""
-echo "Do you want to be prompted for a description of each"
-echo "file as it is checked in to RCS initially?"
-echo -n "(y=prompt for description, n=null description) [y] ?"
-set ans = $<
-if ((_$ans == _) || (_$ans == _y) || (_$ans == _Y)) then
- set nodesc = 0
-else
- set nodesc = 1
-endif
-echo ""
-echo "The default keyword substitutions are as follows and are"
-echo "applied in the order specified:"
-set i = 1
-while ($i <= $#sccs_keywords)
-# echo ' '\"$sccs_keywords[$i]\"' ==> '\"$rcs_keywords[$i]\"
- echo " $sccs_keywords[$i] ==> $rcs_keywords[$i]"
- @ i = $i + 1
-end
-echo ""
-echo -n "Do you want to change them [n] ?"
-set ans = $<
-if ((_$ans != _) && (_$ans != _n) && (_$ans != _N)) then
- echo "You can't always get what you want."
- echo "Edit this script file and change the variables:"
- echo ' $sccs_keywords'
- echo ' $rcs_keywords'
-else
- echo "good idea."
-endif
-
-# create the sed script
-set i = 1
-while ($i <= $#sccs_keywords)
- echo "s,$sccs_keywords[$i],$rcs_keywords[$i],g" >> $sedfile
- @ i = $i + 1
-end
-
-onintr ERROR
-
-############################################################
-# Loop over every s-file in SCCS dir
-#
-foreach sfile (SCCS/s.*)
- # get rid of the "s." at the beginning of the name
- set file = `echo $sfile:t | sed -e "s/^..//"`
-
- # work on each rev of that file in ascending order
- set firsttime = 1
- sccs prs $file | grep "^D " | awk '{print $2}' | sed -e 's/\./ /g' | sort -n -u +0 +1 +2 +3 +4 +5 +6 +7 +8 | sed -e 's/ /./g' > $revfile
- foreach rev (`cat $revfile`)
- if ($status != 0) goto ERROR
-
- # get file into current dir and get stats
- set date = `sccs prs -r$rev $file | grep "^D " | awk '{printf("19%s %s", $3, $4); exit}'`
- set author = `sccs prs -r$rev $file | grep "^D " | awk '{print $5; exit}'`
- echo ""
- echo "==> file $file, rev=$rev, date=$date, author=$author"
- sccs edit -r$rev $file >>& $logfile
- if ($status != 0) goto ERROR
- echo checked out of SCCS
-
- # add RCS keywords in place of SCCS keywords
- sed -f $sedfile $file > $tmpfile
- if ($status != 0) goto ERROR
- echo performed keyword substitutions
- cp $tmpfile $file
-
- # check file into RCS
- if ($firsttime) then
- set firsttime = 0
- if ($nodesc) then
- echo about to do ci
- echo ci -f -r$rev -d"$date" -w$author -t$emptyfile $file
- ci -f -r$rev -d"$date" -w$author -t$emptyfile $file < $initialfile >>& $logfile
- if ($status != 0) goto ERROR
- echo initial rev checked into RCS without description
- else
- echo ""
- echo Enter a brief description of the file $file \(end w/ Ctrl-D\):
- cat > $tmpfile
- ci -f -r$rev -d"$date" -w$author -t$tmpfile $file < $initialfile >>& $logfile
- if ($status != 0) goto ERROR
- echo initial rev checked into RCS
- endif
- else
- # get RCS lock
- set lckrev = `echo $rev | sed -e 's/\.[0-9]*$//'`
- if ("$lckrev" =~ [0-9]*.*) then
- # need to lock the brach -- it is OK if the lock fails
- rcs -l$lckrev $file >>& $logfile
- else
- # need to lock the trunk -- must succeed
- rcs -l $file >>& $logfile
- if ($status != 0) goto ERROR
- endif
- echo got lock
- sccs prs -r$rev $file | grep "." > $tmpfile
- # it's OK if grep fails here and gives status == 1
- # put the delta message in $tmpfile
- ed $tmpfile >>& $logfile <<EOF
-/COMMENTS
-1,.d
-w
-q
-EOF
- ci -f -r$rev -d"$date" -w$author $file < $tmpfile >>& $logfile
- if ($status != 0) goto ERROR
- echo checked into RCS
- endif
- sccs unedit $file >>& $logfile
- if ($status != 0) goto ERROR
- end
- rm -f $file
-end
-
-
-############################################################
-# Clean up
-#
-echo cleaning up...
-mv SCCS old-SCCS
-rm -f $tmpfile $emptyfile $initialfile $sedfile
-echo ===================================================
-echo " Conversion Completed Successfully"
-echo ""
-echo " SCCS history now in old-SCCS/"
-echo ===================================================
-set exitval = 0
-goto cleanup
-
-ERROR:
-foreach f (`sccs tell`)
- sccs unedit $f
-end
-echo ""
-echo ""
-echo Danger\! Danger\!
-echo Some command exited with a non-zero exit status.
-echo Log file exists in $logfile.
-echo ""
-echo Incomplete history in ./RCS -- remove it
-echo Original unchanged history in ./SCCS
-set exitval = 1
-
-cleanup:
-# leave log file
-rm -f $tmpfile $emptyfile $initialfile $sedfile $revfile
-
-exit $exitval
diff --git a/gnu/usr.bin/cvs/cvs/ChangeLog b/gnu/usr.bin/cvs/cvs/ChangeLog
deleted file mode 100644
index 36c39062d15b..000000000000
--- a/gnu/usr.bin/cvs/cvs/ChangeLog
+++ /dev/null
@@ -1,3205 +0,0 @@
-Sat Dec 9 22:01:41 1995 Dan O'Connor <doconnor@tii.com>
-
- * commit.c (check_fileproc): pass RUN_REALLY flag to run_exec,
- because it's okay to examine the file with noexec set.
-
-Sat Dec 9 20:28:01 1995 Karl Fogel <kfogel@floss.cyclic.com>
-
- * client.c (update_entries): new var, `bin, init to 0.
- Use it in determining whether to convert the file.
- (send_modified): same as above.
-
-Fri Dec 8 17:47:39 1995 Karl Fogel <kfogel@floss.cyclic.com>
-
- * server.c (downcase_string): removed.
- (check_repository_password): don't deal with case-insensitivity
- anymore.
-
- * options.h.in (CVS_PASSWORDS_CASE_SENSITIVE): deleted this. No
- need for it anymore.
-
-Thu Dec 7 21:08:39 1995 Karl Fogel <kfogel@floss.cyclic.com>
-
- * server.c (check_repository_password): when checking for false
- prefix-matches, look for ':', not '@'. Duh.
-
-Thu Dec 7 18:44:51 1995 Karl Fogel <kfogel@floss.cyclic.com>
-
- * options.h.in (CVS_PASSWORDS_CASE_SENSITIVE): replaces
- CVS_PASSWORDS_CASE_INSENSITIVE; passwords are now insensitive by
- default. Expanded explanatory comment.
-
- * login.c (get_cvs_password): Use memset(), not bzero(). I
- botched this change earlier.
-
- * server.c (check_repository_password): no need to check
- xmalloc()'s return value.
- (check_repository_password): check for false prefix-matches (for
- example, username is "theo" and linebuf contains user
- "theocracy").
-
-Thu Dec 7 14:49:16 1995 Jim Meyering (meyering@comco.com)
-
- * filesubr.c (isaccessible): Rename from isaccessable.
- Update callers.
- * cvs.h: Update prototype.
- * main.c (main): Update callers.
- * server.c (main): Update callers.
-
-Thu Dec 7 12:50:20 1995 Adam Glass <glass@NetBSD.ORG>
-
- * cvs.h: "isaccessible" is the correct spelling.
- Also add "const" to second arg to make prototype match
- declaration.
-
-Thu Dec 7 11:06:51 1995 Karl Fogel <kfogel@floss.cyclic.com>
-
- * client.c, login.c: memset() instead of bzero().
-
-Thu Dec 7 00:08:53 1995 Karl Fogel <kfogel@floss.cyclic.com>
-
- * server.c (authenticate_connection): document server's side of
- the Authentication Protocol too.
-
- * client.c (connect_to_pserver): when printing out "unrecognized
- response", also print out the offending response.
-
- * server.c (check_password): take `repository' arg too now.
- Call check_repository_password() before checking /etc/passwd.
- (check_repository_password): new func.
-
- * options.h.in (CVS_PASSWORDS_CASE_INSENSITIVE): new define, unset
- by default.
-
-Wed Dec 6 18:51:16 1995 Karl Fogel <kfogel@floss.cyclic.com>
-
- * server.c (check_password): If user has a null password, then
- return 1 if arg is also null.
- Reverse sense of return value. Caller changed.
-
-Wed Dec 6 14:42:57 1995 Karl Fogel <kfogel@floss.cyclic.com>
-
- * server.c (check_password): new func.
- (authenticate_connection): call above new func.
-
- * login.c (login): use construct_cvspass_filename().
- If CVSroot is not "fully-qualified", then insist the user qualify
- it before going on.
- (get_cvs_password): fleshed out. Now reads from ~/.cvspass, or
- prompts if no appropriate password found.
- (construct_cvspass_filename): new func.
-
- * server.c (authenticate_connection): send ACK or NACK to client.
-
- * client.c (connect_to_pserver): check for ACK vs NACK response
- from server after sending authorization request.
-
- * login.c (get_cvs_password): new func.
-
- * client.c (connect_to_pserver): use new func get_cvs_password().
- Prototype it at top of file. Hmmm.
-
-Wed Dec 6 13:29:22 1995 Karl Fogel <kfogel@floss.cyclic.com>
-
- * server.c: same as below (AUTH_SERVER_SUPPORT).
-
- * main.c: same as below (AUTH_SERVER_SUPPORT where appropriate).
-
- * login.c: same same as below.
-
- * cvs.h: same as below.
-
- * client.c: use AUTH_CLIENT_SUPPORT, not CVS_LOGIN.
-
- * options.h.in (AUTH_CLIENT_SUPPORT, AUTH_SERVER_SUPPORT): these
- replace CVS_LOGIN.
-
-Wed Dec 6 00:04:58 1995 Karl Fogel <kfogel@floss.cyclic.com>
-
- * server.c (authenticate_connection): expanded comment.
-
-Tue Dec 5 23:37:39 1995 Karl Fogel <kfogel@floss.cyclic.com>
-
- * client.c (connect_to_pserver): read password from prompt for
- now.
-
- * server.c (authenticate_connection): if the password passes
- muster, then don't abort.
-
-Tue Dec 5 22:46:37 1995 Karl Fogel <kfogel@floss.cyclic.com>
-
- * subr.c (strip_trailing_newlines): new func.
-
- * client.c (connect_to_pserver): took out print statements.
-
- * server.c (authenticate_connection): removed print statments.
- Use new func strip_trailing_newlines() to purify `repository',
- `username', and `password'.
- Run a primitive password check, just for testing.
-
- * client.c (connect_to_pserver): use CVS_AUTH_PORT.
- Take tofdp, fromfdp, and log args. Caller changed.
- (get_responses_and_close): either kerberos and CVS_LOGIN might
- have one fd for both directions, so adjust #ifdef accordingly.
-
- * cvs.h (CVS_AUTH_PORT): new define, default to 2401.
- Prototype strip_trailing_newlines().
-
-Tue Dec 5 16:53:35 1995 Karl Fogel <kfogel@floss.cyclic.com>
-
- * server.c (authenticate_connection): new func.
-
- * client.c (init_sockaddr): func moved here from login.c.
- (connect_to_pserver): same as above. Take no args, now.
- Include <sys/socket.h>, <netinet/in.h>, <netdb.h>, if CVS_LOGIN.
-
- * cvs.h: Declare use_authenticating_server, as extern int.
- Declare connect_to_pserver().
-
- * main.c (main): call authenticate_connection(). Removed testing
- code.
- Add 'a' to the short-option string in the getopt() call.
-
- * login.c (connect_to_pserver): moved to client.c.
-
-Tue Dec 5 16:01:42 1995 Peter Chubb <peterc@bookworm.sw.oz.au>
- (patch applied by Karl Fogel <kfogel@cyclic.com>)
-
- * update.c (join_file): if vers->vn_user is "0", file has been
- removed on the current branch, so print an error and return.
-
-Mon Dec 4 14:27:42 1995 Jim Kingdon <kingdon@harvey.cyclic.com>
-
- * Version 1.6.3.
-
-Mon Dec 4 16:28:25 1995 Norbert Kiesel <nk@col.sw-ley.de>
-
- * release.c (release): add return (0) as last line
-
- * cvs.h: declare program_path
-
- * main.c define program_path
- (main): set program_path
-
- * release.c (release): use program_path for update_cmd
-
-Mon Dec 4 11:22:42 1995 Jim Kingdon <kingdon@harvey.cyclic.com>
-
- * Version 1.6.2.
-
-Sun Dec 3 20:02:29 1995 Jim Kingdon <kingdon@harvey.cyclic.com>
-
- * rcs.h (struct rcsnode), rcs.c (freercsnode): Add expand field.
- * rcs.h (RCSEXPAND): New #define.
- * rcs.c (RCS_reparsercsfile): Record keyword expansion in expand
- field of struct rcsnode.
- * update.c (checkout_file): Set keyword expansion in Entries file
- from rcs file if there is nowhere else to set it from.
- * client.c (send_modified, update_entries) [LINES_CRLF_TERMINATED]:
- If -kb is in effect, don't convert.
-
- * update.c (update_file_proc), commit.c (check_fileproc),
- rcscmds.c (RCS_merge): Direct stdout to DEVNULL rather than
- passing -s option to grep. This avoids trouble with respect to
- finding a grep which support -s and whether we should use the (GNU
- grep) -q option if it exists.
- * options.h.in: Change "@ggrep_path@" to "grep".
-
-Fri Dec 1 11:53:19 1995 Norbert Kiesel <nk@col.sw-ley.de>
-
- * rcs.c (RCS_gettag): new parameter return_both force return both
- tags: the symbolic and the numeric one.
- (RCS_getversion): new parameter return_both is forwarded to
- RCS_gettag.
-
- * rtag.c, tag.c, commit.c, patch.c, update.c: pass 0 as additional
- last parameter to RCS_getversion and RCS_gettag
-
- * rcs.h (RCS_gettag): new parameter return_both.
- (RCS_getversion): new parameter return_both.
-
- * cvs.h (struct vers_ts): add vn_tag slot for symbolic tag name
-
- * vers_ts.c (Version_TS): call RCS_getversion with 1 for
- return_both and split output into vn_rcs and vn_tag
- (freevers_ts): free vn_tag
-
- * update.c (checkout_file): use vn_tag instead of vn_rcs when
- calling 'rcs co' to allow rcs expansion of :$Name :
-
-Thu Nov 30 20:44:30 1995 Karl Fogel <kfogel@floss.cyclic.com>
-
- * client.c (get_responses_and_close): undo previous change
- regarding waitpid(). The problem has been solved by modifying
- os2/waitpid.c instead of its callers.
-
-Thu Nov 30 16:37:10 1995 Karl Fogel <kfogel@floss.cyclic.com>
-
- * client.c: All these changes are for OS/2, which will no longer have
- a separate client.c:
- (start_kerberos_server): new func, contains code that
- used to be in start_server().
- (start_server): moved kerberos code to above function, reorganized
- the rest. Added authentication clause.
- (call_in_directory): test errno against EACCESS, if EACCESS is
- defined (this is for OS/2's oddball mkdir).
- (change_mode): don't set execute permission on anything if
- EXECUTE_PERMISSION_LOSES is defined.
- (get_responses_and_close): if START_RSH_WITH_POPEN_RW, then use
- pclose() instead of fclose().
- If waitpid errors with ECHILD, don't die. This is okay.
- (start_rsh_server): alternate definition if
- START_RSH_WITH_POPEN_RW.
-
- * main.c: [all these changes conditional on CVS_LOGIN: ]
- Don't prototype connect_to_pserver, don't enter it in cmds[]
- (actually, it was never in there, I don't know why my previous
- change said it was).
- (use_authenticating_server): new global var.
- (main): if "-a", then set above new var to TRUE.
- (usg): document "-a" option.
-
-Wed Nov 29 12:55:10 1995 Karl Fogel <kfogel@floss.cyclic.com>
-
- * main.c: Prototype connect_to_pserver(), and enter it in cmds[].
- (main): test some extremely primitive authentication.
-
- * login.c: Include <sys/socket.h>
- (connect_to_pserver): new func.
- (init_sockaddr): new func.
-
-Mon Nov 20 14:07:41 1995 Jim Kingdon <kingdon@harvey.cyclic.com>
-
- * Makefile.in (TAGFILES): Separate out from DISTFILES, for C code.
- (TAGS,tags): Use TAGFILES not DISTFILES.
-
-Sun Nov 19 11:22:43 1995 Jim Kingdon <kingdon@harvey.cyclic.com>
-
- * recurse.c (do_recursion): Don't call server_pause_check if there
- are writelocks around. Revise comment to reflect fact we are no
- longer relying on a writelock'd operations being "unable" to
- generate enough data to pause.
-
-Sun Nov 19 10:04:50 1995 Peter Wemm <peter@haywire.DIALix.COM>
-
- * server.c, server.h, options.h.in: Implement hooks for doing
- simple flow control on the server to prevent VM exhaustion on a
- slow network with a fast server.
- * recurse.c: Call the flow control check at a convenient location
- while no locks are active. This is a convenience tradeoff against
- accurate flow control - if you have a large directory it will all
- be queued up, bypassing the flow control check until the next
- directory is processed.
-
-Sat Nov 18 16:22:06 1995 Karl Fogel <kfogel@floss.cyclic.com>
-
- * client.c, update.c, vers_ts.c, server.c, rcs.c, lock.c,
- ignore.c, entries.c, diff.c, commit.c, checkin.c:
- Use new macro `existence_error', instead of comparing errno to
- ENOENT directly.
-
-Fri Nov 17 14:56:12 1995 Karl Fogel <kfogel@floss.cyclic.com>
-
- * client.c (start_server): removed alternate version of this func,
- since os2/client.c will now be used under OS/2.
-
-Thu Nov 16 22:57:12 1995 Karl Fogel <kfogel@floss.cyclic.com>
-
- * client.c (start_server): ifdef HAVE_POPEN_RW, use a different
- version of start_server(). This is maybe not the cleanest cut to
- make, but it's better than mucking around with yet more #ifdefs in
- the middle of the old start_server() function. Once things are
- up, I may reposition this code.
-
-Wed Nov 15 15:33:37 1995 Karl Fogel <kfogel@floss.cyclic.com>
-
- * main.c (main): ifdef NEED_CALL_SOCKINIT, then call SockInit().
- Only OS/2 needs this initialization.
-
-Tue Nov 14 18:54:01 1995 Greg A. Woods <woods@most.weird.com>
-
- * patch.c:
- - fix orientation of test for result of getline() call
- - use fputs() not printf() when just copying file out
-
- * cvsbug.sh:
- - add space after #!
- - new rcs id
- - allow version to be edited by Makefile.
-
- * Makefile.in:
- - make Makefile a dependent of all (this might not be perfect, but
- it at least gives you a chance to catch up on the second
- go-around).
- - filter cvsbug.sh in a manner similar to cvsinit.sh to get the
- version number set from version.c
-
-Tue Nov 14 13:28:17 1995 Jim Kingdon <kingdon@harvey.cyclic.com>
-
- * sanity.sh: Call old log file check.plog, not check.olog.
-
- * sanity.sh: Convert remaining tests from old-style ('***' on fail
- and nothing on pass), to new-style (FAIL on fail and PASS on pass).
-
- * sanity.sh: Fix ability to run only some of the tests (always run
- tests 1-4.75 to set up repository, document better how it works).
-
- * sanity.sh: Change "completed successfully" to "completed" in
- message--many tests, but not all, exit if they fail.
-
-Tue Nov 14 15:10:00 1995 Greg A. Woods <woods@most.weird.com>
-
- * sanity.sh: test 63 doesn't work and probably can't
-
-Tue Nov 14 12:22:00 1995 Greg A. Woods <woods@most.weird.com>
-
- * sanity.sh: many minor tweaks:
- - make the optional arguments almost work
- - use a function 'directory_cmp' instead of 'diff -r'
- - fix up a few more tests that weren't working....
-
-Mon Nov 13 07:33:55 1995 Karl Fogel <kfogel@floss.cyclic.com>
-
- * cvs.h: ifdef USE_OWN_POPEN, #include "popen.h". Only OS/2 has
- its own popen()/pclose() right now.
-
-Mon Nov 13 04:06:10 1995 Karl Fogel <kfogel@floss.cyclic.com>
-
- * cvs.h: conform to 80 column standard (yes, I'm a pedant).
-
-Sat Nov 11 13:45:13 1995 Karl Fogel <kfogel@floss.cyclic.com>
-
- * client.c (process_prune_candidates): use unlink_file_dir() to
- remove the directory, instead of invoking "rm" via run_exec().
-
-Fri Nov 10 14:38:56 1995 Karl Fogel <kfogel@floss.cyclic.com>
-
- * main.c (main): removed "#define KF_GETOPT_LONG 1", since that
- change is no longer in testing.
-
-Thu Nov 9 20:32:12 1995 Karl Fogel <kfogel@floss.cyclic.com>
-
- * release.c (release): Use Popen(), not popen().
-
-Wed Nov 8 10:20:20 1995 Jim Meyering (meyering@comco.com)
-
- * entries.c (ParseTag): Remove dcl of unused local.
-
- * patch.c: Include getline.h.
-
-Wed Nov 8 11:57:31 1995 Norbert Kiesel <nk@col.sw-ley.de>
-
- * options.h.in: add configuration option STEXID_SUPPORT (default
- is off i.e. old semantics)
-
- * filesubr.c (isaccessable): new function. Checks access-rights
- for files like access(), but is getxid-safe. Falls back to
- access() if SETXID_SUPPORT is not enabled.
- (isfile): replace stat() by isaccessable(file, F_OK)
- (isreadable): replace access() by isaccessable()
- (iswritable): ditto
- (make_directory): rename local variable buf to sb
-
- * cvs.h: add prototype for new function isaccessable.
-
- * server.c (serve_root): replace access() by isaccessable()
-
- * cvsrc.c (read_cvsrc): replace access() by isreadable()
-
- * main.c (main): replace access() by isaccessable()
-
-Wed Nov 8 10:22:41 1995 Greg A. Woods <woods@most.weird.com>
-
- * entries.c (fgetentent): change definition to static to match the
- declaration at the top of the file
-
-Tue Nov 7 16:59:25 1995 J.T. Conklin <jtc@lestat.cygnus.com>
-
- * rcs.c (RCS_getbranch, RCS_getdate, RCS_getrevtime, RCS_gettag,
- RCS_getversion, RCS_head): Use assert() instead of attempting to
- "do the right thing" with a bogus RCSNode argument.
-
-Mon Nov 6 14:24:34 1995 Jim Kingdon <kingdon@harvey.cyclic.com>
-
- * vers_ts.c: Remove ctime define. It is just asking for trouble.
-
-Mon Nov 6 11:58:26 1995 Karl Fogel <kfogel@floss.cyclic.com>
-
- * vers_ts.c: ifdef ctime, undef it before redefining it. It is a
- macro on some systems.
-
- * lock.c: don't prototype ctime() here. (See note below about
- fgetentent() in entries.c.)
-
-Sun Nov 5 16:06:01 1995 Karl Fogel <kfogel@floss.cyclic.com>
-
- * entries.c (fgetentent): don't prototype ctime here; we include
- cvs.h, which includes system.h, which includes <time.h>
- unconditionally (either as <time.h> or <sys/time.h>). Anyway, IBM
- C/C++ chokes on mid-function, or even mid-file, prototypes. Sigh.
-
-Thu Nov 2 21:51:04 1995 Dan Wilder <dan@gasboy.com>
-
- * rtag.c (rtag): Fix typo ("-T" -> "-F").
-
-Tue Oct 31 19:09:11 1995 Dan Wilder <dan@gasboy.com>
-
- * diff.c (diff_dirproc): just return R_SKIP_ALL if dir not exist.
- (diff_file_nodiff): don't complain if file doesn't exist, just
- ignore.
-
-Tue Oct 31 09:25:10 1995 Norbert Kiesel <nk@col.sw-ley.de>
-
- * sanity.sh: Use absolute pathname for mkmodules.
-
-Sat Oct 28 01:01:41 1995 Jim Meyering (meyering@comco.com)
-
- * entries.c (ParseTag): Use getline instead of fgets.
-
-Fri Oct 27 13:44:20 1995 Karl Fogel <kfogel@floss.cyclic.com>
-
- * cvs.h: do nothing about alloca ifdef ALLOCA_IN_STDLIB. I am
- rather suspicious of this solution, and will not be surprised to
- find out that there's a Right Way to handle this situation ("this
- situation" being that OS/2 simply declares alloca in <stdlib.h>).
- Suggestions are welcome; see src/cvs.h and lib/system.h to see why
- I was getting a conflict in the first place.
-
-Wed Oct 25 16:03:20 1995 J.T. Conklin <jtc@slave.cygnus.com>
-
- * cvs.h (struct entnode): Add user field.
- * entries.c (fputentent): New function, write entries line.
- (write_ent_proc): Call fputentent to write entries line.
- (Entnode_Create): New function, construct new Entnode.
- (Entnode_Destroy): New function, destruct old Entnode.
- (AddEntryNode): Changed to take an Entnode argument instead of
- separate user, version, timestamp, etc. arguments.
- (fgetentent): Changed to return Entnode.
- (struct entent, free_entent): Removed.
-
-Wed Oct 25 12:44:32 1995 Jim Kingdon <kingdon@harvey.cyclic.com>
-
- * admin.c (admin): Don't rely on ANSI C string concatenation;
- SunOS 4.1.3 /bin/cc doesn't support it.
-
-Tue Oct 24 22:34:22 1995 Anthony J. Lill <ajlill@ajlc.waterloo.on.ca>
-
- * import.c (expand_at_signs): Check errno as well as return value
- from putc. Some systems bogusly return EOF when successfully
- writing 0xff.
-
-Tue Oct 24 14:32:45 1995 Norbert Kiesel <nk@col.sw-ley.de>
-
- * admin.c (admin): use getcaller() instead of getpwuid
-
- * subr.c (getcaller): prefer getlogin() to $USER and $LOGNAME
- (especially useful for NT where getuid always returns 0)
-
-Tue Oct 24 06:22:08 1995 Jim Meyering (meyering@comco.com)
-
- * cvsrc.c (read_cvsrc): Use getline instead of fgets.
- * patch.c (patch_fileproc): Use getline instead of fgets.
-
- * entries.c (fgetentent): Use getline instead of fgets.
- Use xmalloc to allocate space for each returned entry.
- Since LINE is no longer static, save it in struct entent.
- (struct entent): New member, line.
- (free_entent): New function.
- (Entries_Open): Call it after each call to fgetentent.
-
-Tue Oct 24 11:13:15 1995 Norbert Kiesel <nk@col.sw-ley.de>
-
- * cvs.h: Declare valloc again, but this time with the right
- signature (also changed in libs/valloc.c)
-
-Mon Oct 23 12:17:03 1995 Jim Kingdon <kingdon@harvey.cyclic.com>
-
- * logmsg.c (do_editor): Check for errors from stdio calls.
-
-Mon Oct 23 12:37:06 1995 Jim Kingdon <kingdon@harvey.cyclic.com>
-
- * cvs.h: Don't declare valloc. Some systems (e.g. linux) declare
- it in stdlib.h in a conflicting way.
-
-Mon Oct 23 08:41:25 1995 Jim Meyering (meyering@comco.com)
-
- * commit.c (commit_filesdoneproc): Use getline instead of fgets.
-
- * logmsg.c (do_editor): Use getline instead of fgets.
- (rcsinfo_proc): Likewise.
-
- * logmsg.c (do_editor): Lose if fclose of temp file output
- stream fails.
-
-Mon Oct 23 11:59:41 1995 Norbert Kiesel <nk@col.sw-ley.de>
-
- * cvs.h: add valloc declaration
-
- * server.h: add server_cleanup prototype
-
- * server.c: remove server_cleanup prototype
-
- * mkmodules.c (server_cleanup): fix parameter type
-
- * server.c: encapsulate wait_sig in #ifdef sun (it's only used in
- code which is also encapsulated in #ifdef sun)
-
- * rcscmds.c (RCS_deltag, RCS_lock): add definition of noerr
- parameter
-
- * error.c: include cvs.h instead of config.h, add USE(rcsid)
-
- * error.c (error): fix parameter type
-
- * update.c (join_file): encapsulate recent changes from garyo
- within #ifdef SERVER_SUPPORT
-
-Sun Oct 22 13:47:53 1995 J.T. Conklin <jtc@slave.cygnus.com>
-
- * client.c (update_entries): Fix memory leak; free mode_string and
- file_timestamp.
- (send_fileproc): Fix memory leak; call freevers_ts before exiting.
-
- * module.c (do_module): Partially fix memory leak; added
- variable so that the address of memory allocated by line2argv
- is retained, but comment out the call to free_names. Freeing
- the vector at that point loses because some of the elements
- may be used later in the function.
- (cat_module): fix memory leak.
-
- * recurse.c (start_recursion): Fix memory leak; free return
- value of Name_Repository after it has been used.
-
-Sat Oct 21 23:24:26 1995 Jim Meyering (meyering@comco.com)
-
- * client.c (send_modified) [LINES_CRLF_TERMINATED]: Comment text
- after #endif.
-
-Fri Oct 20 14:41:49 1995 Jim Kingdon <kingdon@harvey.cyclic.com>
-
- * sanity.sh: Add test 87a, to test for bug fixed by garyo in
- change below.
-
-Fri Oct 20 10:59:58 1995 Gary Oberbrunner <garyo@darkstar.avs.com>
-
- * update.c (join_file): send file back to client even if no
- conflicts were detected, by calling Register().
-
-Fri Oct 20 10:46:45 1995 Norbert Kiesel <nk@col.sw-ley.de>
-
- * lock.c: Add prototype for Check_Owner
-
-Thu Oct 19 16:38:14 1995 Jim Meyering (meyering@comco.com)
-
- * lock.c (Check_Owner): Declare function `static int'.
-
-Thu Oct 19 14:58:40 1995 Jim Kingdon <kingdon@harvey.cyclic.com>
-
- * expand_path.c (expand_variable): Fix typo ('*'->'(').
-
-Thu Oct 19 14:58:40 1995 Jim Kingdon <kingdon@harvey.cyclic.com>
-
- * commit.c (commit_filesdoneproc): Check for errors from fopen,
- fgets, and fclose.
-
- * rcscmds.c (RCS_merge): Remove comment about rcsmerge -E.
- Hacking CVS was never a very good solution; the situation is fixed
- in RCS 5.7, and is documented in ../INSTALL.
-
-Thu Oct 19 15:06:15 1995 Jim Meyering (meyering@comco.com)
-
- * filesubr.c (xchmod): Parenthesize arithmetic in operand of |
- to placate gcc -Wall.
-
- * expand_path.c (expand_path): Parenthesize assignments used as
- truth values to placate gcc -Wall.
-
- * commit.c (checkaddfile): Remove dcls of unused variables.
- * lock.c (unlock): Remove dcl of unused variable.
-
-Thu Oct 19 14:58:40 1995 Jim Kingdon <kingdon@harvey.cyclic.com>
-
- * root.c (Create_Root): If noexec, don't create CVS/Root.
-
-Wed Oct 18 11:19:40 1995 J.T. Conklin <jtc@slave.cygnus.com>
-
- * lock.c (unlock): Change order of comparison so that Check_Owner
- is called only if other conditions are true. This performance
- enhancement was broken when the AFS support was added.
-
-Wed Oct 18 12:51:33 1995 Karl Fogel <kfogel@floss.cyclic.com>
-
- * main.c (main): check if argv[0] is "pserver" with else-if, not
- if, since we've already asked if it's "kserver".
-
-Tue Oct 17 18:09:23 1995 Warren Jones <wjones@tc.fluke.com>
- and Jim Kingdon <kingdon@harvey.cyclic.com>
-
- * sanity.sh: Deal with supplying a relative cvs filename, or
- with a cvs filename which doesn't have basename "cvs".
-
-Mon Oct 16 15:58:31 1995 Vince Demarco <vdemarco@bou.shl.com>
-
- * parseinfo.c (Parse_Info): if the Keyword isn't ALL the current
- version doesn't use the expanded variable, It should.
-
-Mon Oct 16 15:58:31 1995 Gary Oberbrunner <garyo@avs.com>
- and Jim Kingdon <kingdon@harvey.cyclic.com>
-
- * server.c (server_register): Don't pass NULL to printf if tag,
- date, or conflict is NULL.
-
-Thu Oct 12 12:13:42 1995 Karl Fogel <kfogel@floss.cyclic.com>
-
- * main.c (main): begin to handle "pserver"; support not complete
- yet, however.
-
-Thu Oct 12 02:52:13 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
-
- * expand_path.c: Don't #include <pwd.h>, since cvs.h already does,
- and not all systems' <pwd.h>s are protected from multiple inclusion.
- * login.c: Likewise.
-
-Wed Oct 11 15:23:24 1995 Karl Fogel <kfogel@floss.cyclic.com>
-
- * login.c (login): handle everything correctly now.
-
-Wed Oct 11 12:02:48 1995 Norbert Kiesel <nk@col.sw-ley.de>
-
- * rcs.c (RCS_gettag): support RCS keyword Name
-
-Tue Oct 10 19:11:16 1995 Karl Fogel <kfogel@floss.cyclic.com>
-
- * options.h.in (CVS_LOGIN): discuss, but leave commented out.
- The "cvs login" command is still under construction; however, the
- repository was changing so fast that instead of creating a branch
- and dealing with the attendant hair, I'm just developing on the
- trunk, making sure that everything is surrounded by "#ifdef
- CVS_LOGIN ... #endif" so I don't get in anyone's way.
-
- * login.c: include cvs.h before checking CVS_LOGIN, so it has a
- chance to get defined before we ask if it's defined.
- (login): oops, use semi not comma in `for' loop init.
-
- * Makefile.in (SOURCES, OBJECTS): include login.c, login.o.
-
- * main.c: added protoype for login().
- Added "login" entry to cmds[].
- (usg): added line about "login".
-
- * login.c: new file.
-
-Tue Oct 10 18:33:47 1995 Karl Fogel <kfogel@totoro.cyclic.com>
-
- * Makefile.in (COMMON_OBJECTS): added error.o.
- (OBJECTS): took error.o out; it's in COMMON_OBJECTS now.
-
-Tue Oct 10 12:02:37 1995 Thorsten Lockert <tholo@sigmasoft.com>
-
- * cvsbug.sh: Cater to lame versions of sh (4.4BSD ash) by using
- ${foo-bar} instead of `if....`.
-
-Tue Oct 10 12:02:37 1995 Jim Kingdon <kingdon@harvey.cyclic.com>
-
- * remove.c (remove_fileproc): If noexec, don't remove file. Check
- for error when removing file.
-
-Sun Oct 8 12:32:15 1995 Peter Wemm <peter@haywire.DIALix.COM>
-
- * run.c: detect/use POSIX/BSD style reliable signals for critical
- section masking etc. Helps prevent stray locks on interruption.
-
-Sat Oct 7 23:26:54 1995 Norbert Kiesel <nk@col.sw-ley.de>
-
- * admin.c (admin): If group CVS_ADMIN_GROUP exists, allow only
- users in that group to use "cvs admin".
- * options.h.in: Default CVS_ADMIN_GROUP to "cvsadmin".
-
-Sat Oct 7 23:05:24 1995 Norbert Kiesel <nk@col.sw-ley.de>
-
- * add.c, checkout.c, commit.c, cvs.h, filesubr.c, import.c,
- lock.c, main.c, modules.c, options.h.in: New variable cvsumask
- which is used to set mode of files in repository (regardless of
- umask in effect when cvs is run).
-
-Sat Oct 7 22:40:17 1995 Stephen Bailey <sjbailey@sand.npl.washington.edu>
-
- * lock.c: Include AFSCVS ifdefs to deal with AFS's lack of
- correspondance between userid's from stat and from geteuid.
-
-Sat Oct 7 22:28:49 1995 Scott Carson <sdc@TracerTech.COM>
-
- * add.c (add): Pass -ko, not -k -ko, to set keyword expansion options.
-
- * admin.c (admin): Don't skip first argument when sending to server.
-
-Fri Oct 6 21:45:03 1995 Jim Kingdon <kingdon@harvey.cyclic.com>
-
- * version.c: Version 1.6.1.
-
-Fri Oct 6 21:31:28 1995 Jeff Johnson <jbj@brewster.jbj.org>
-
- * cvs.h, admin.c, client.c, commit.c, log.c, modules.c,
- parseinfo.c, patch.c, recurse.c, rtag.c, status.c, tag.c:
- Prototype when dealing in pointers to functions.
-
-Fri Oct 6 21:07:22 1995 Mark H. Wilkinson <mhw@minster.york.ac.uk>
-
- * cvsrc.c (read_cvsrc): fix look up of command names in cvsrc file
- to use full name from command table rather than possible nickname
- in argv. Fixes errors with things like `cvs di' when cvsrc has
- `diff -u5' in it.
-
-Thu Aug 3 01:03:52 1995 Vince DeMarco <vdemarco@bou.shl.com>
-
- * parseinfo.c (Parse_Info): Add code to call expand_path function
- instead of using built in code.
-
- * wrapper.c (wrap_add): Add code to call expand_path function to
- expand all built in variables.
-
- * expand_path.c (New file): expand things that look like
- environmental variables (only expand local CVS environmental
- variables) and user names like ~/.
- * cvs.h: Declare expand_path.
-
- * Makefile.in (SOURCES, OBJECTS): Added expand_path.c,
- expand_path.o.
-
-Fri Oct 6 14:03:09 1995 Jim Kingdon <kingdon@harvey.cyclic.com>
-
- * ignore.c (ign_setup): Don't try to look for a file in CVSroot if
- client. (The recent tightening of the error checking detects this).
-
- * commit.c (checkaddfile): Don't try to pass options if it is "".
-
-Thu Oct 5 18:04:46 1995 Karl Fogel <kfogel@totoro.cyclic.com>
-
- * sanity.sh: unset CVSREAD, since it causes the script to bomb.
-
-Thu Oct 5 18:29:17 1995 Jim Kingdon <kingdon@harvey.cyclic.com>
-
- * remove.c, add.c, commit.c, cvs.h: Remove CVSEXT_OPT stuff; it
- has been broken for ages and the options are already stored in the
- Entries file.
-
-Thu Oct 5 18:20:13 1995 Norbert Kiesel <nk@col.sw-ley.de>
-
- * commit.c (checkaddfile): New argument options; pass it to RCS.
- (commit_fileproc): Pass it.
-
-Tue Oct 3 09:26:00 1995 Karl Fogel <kfogel@totoro.cyclic.com>
-
- * version.c: upped to 1.6.
-
-Mon Oct 2 18:10:35 1995 Larry Jones <larry.jones@sdrc.com>
-
- * server.c: if HAVE_SYS_BSDTYPES_H, include <sys/bsdtypes.h>.
-
-Mon Oct 2 10:34:53 1995 Karl Fogel <kfogel@totoro.cyclic.com>
-
- * version.c: Upped version to 1.5.95.
-
-Mon Oct 2 15:16:47 1995 Norbert Kiesel <nk@col.sw-ley.de>
-
- * tag.c, rtag.c: pass "mov" instead of "add" if tag will be moved
- (i.e. invoked with -F)
-
-Sun Oct 1 18:36:34 1995 Karl Fogel <kfogel@totoro.cyclic.com>
-
- * version.c: upped to 1.5.94.
-
- * server.c: reverted earlier ISC change (of Sep. 28).
-
- * version.c: upped to 1.5.93, for Peter Wemm's new SVR4 patch.
-
-Sun Oct 1 14:51:59 1995 Harlan Stenn <Harlan.Stenn@pfcs.com>
-
- * main.c: don't #include <pwd.h>; cvs.h does that already.
-
-Fri Sep 29 15:21:35 1995 Karl Fogel <kfogel@floss.cyclic.com>
-
- * version.c: upped to 1.5.91 for another pre-1.6 release.
-
-Fri Sep 29 14:41:14 1995 <bmeier@rzu.unizh.ch>
-
- * root.c: start rcsid[] with "CVSid".
-
-Fri Sep 29 13:22:44 1995 Jim Blandy <jimb@totoro.cyclic.com>
-
- * diff.c (diff): Doc fix.
-
-Fri Sep 29 14:32:36 1995 Norbert Kiesel <nk@col.sw-ley.de>
-
- * repos.c (Short_Repository): chop superfluous "/".
-
- * tag.c (pretag_proc): correct user-visible string.
-
- * rtag.c (pretag_proc): correct user-visible string.
-
-Fri Sep 29 13:45:36 1995 Karl Fogel <kfogel@floss.cyclic.com>
-
- * cvs.h (USE): if __GNUC__ != 2, expand to a dummy var instead of
- nothing.
-
-Thu Sep 28 13:37:05 1995 Larry Jones <larry.jones@sdrc.com>
-
- * server.c: ifdef ISC, include <sys/bsdtypes.h>.
-
-Fri Sep 29 07:54:22 1995 Mike Sutton <mws115@llcoolj.dayton.saic.com>
-
- * filesubr.c (last_component): Don't use ANSI style declaration.
-
-Wed Sep 27 15:24:00 1995 Del <del@matra.com.au>
-
- * tag.c, rtag.c: Pass a few extra options to the script
- named in taginfo (del/add, and revision number).
-
- * tag.c: Support a -r option (at long last). Also needs
- a -f option to tag the head if there is no matching -r tag.
-
-Tue Sep 26 11:41:08 1995 Karl Fogel <kfogel@totoro.cyclic.com>
-
- * version.c: Upped version to 1.5.89 for test release preceding
- 1.6.
-
-Wed Sep 20 15:32:49 1995 Jim Kingdon <kingdon@harvey.cyclic.com>
-
- * ignore.c (ign_add_file): Check for errors from fopen and fclose.
-
-Tue Sep 19 18:02:16 1995 Jim Blandy <jimb@totoro.cyclic.com>
-
- * Makefile.in (DISTFILES): Remove sanity.el from this list; the
- file has been deleted.
-
-Thu Sep 14 14:17:52 1995 Peter Wemm <peter@haywire.dialix.com>
-
- * import.c: Recover from being unable to open the user file.
-
- * update.c (join_file): Print a message in the case where the file
- was added.
-
- * mkmodules.c: Deal with .db as well as .pag/.dir (for use with
- BSD 4.4 and real dbm support).
-
-Mon Sep 11 15:44:13 1995 Jim Kingdon <kingdon@harvey.cyclic.com>
-
- * release.c (release): Revise comment regarding why and how we
- skip argv[0].
-
-Mon Sep 11 10:03:59 1995 Karl Fogel <kfogel@floss.cyclic.com>
-
- * release.c (release): use return value of pclose to determine
- success of update.
-
-Mon Sep 11 09:56:33 1995 Jim Kingdon <kingdon@harvey.cyclic.com>
-
- * release.c (release_delete): Fix comment.
-
-Sun Sep 10 18:48:35 1995 Karl Fogel <kfogel@floss.cyclic.com>
-
- * release.c (release): made work with client/server.
- Don't ask if <arg> is mentioned in `modules'.
-
-Fri Sep 8 13:25:55 1995 Jim Kingdon <kingdon@harvey.cyclic.com>
-
- * sanity.sh: When committing a removal, send stdout to LOGFILE;
- this is no longer a silent operation.
-
- * sanity.sh: Remove OUTPUT variable; it is unused.
-
- * client.c: Add comment regarding deleting temp file.
- * main.c: Add comment regarding getopt REQUIRE_ORDER.
-
-Thu Sep 7 20:24:46 1995 Karl Fogel <kfogel@floss.cyclic.com>
-
- * main.c (main): use getopt_long(), accept "--help" and
- "--version".
- Don't assume EOF is -1.
-
-Thu Sep 7 19:18:00 1995 Jim Blandy <jimb@cyclic.com>
-
- * cvs.h (unlink_file_dir): Add prototype for this.
-
-Thu Sep 7 14:38:06 1995 Karl Fogel <kfogel@floss.cyclic.com>
-
- * ALL FILES: add semicolon, as indicated below.
-
- * cvs.h (USE): don't provide semicolon in the expansion of the USE
- macro; we'd rather the callers provided it themselves because that
- way etags doesn't get fooled.
-
-Mon Sep 4 23:30:41 1995 Magnus Hyllander <mhy@os.se>
-
- * checkout.c: cvs export now takes -k option and does not default
- to -kv.
- * checkout.c, cvs.h, modules.c: Modules file now takes -e option
- for cvs export.
-
-Mon Sep 4 23:30:41 1995 Kirby Koster <koster@sctc.com>
-
- * commit.c: When committing a removal, print a message saying what
- we are doing.
-
-Wed Aug 2 10:06:51 1995 Vince DeMarco <vdemarco@bou.shl.com>
-
- * server.c: fix compiler warnings (on NeXT) (declare functions as
- static inline instead of just static) functions: get_buffer_date,
- buf_append_char, and buf_append_data
-
-Mon Sep 4 22:31:28 1995 Jim Kingdon <kingdon@harvey.cyclic.com>
-
- * client.c (update_entries), import.c (expand_at_signs): Check for
- errors from fread and putc.
-
-Fri Sep 1 00:03:17 1995 Jim Kingdon <kingdon@harvey.cyclic.com>
-
- * sanity.sh: Fix TODO item pathname.
-
- * sanity.el: Removed. It was out of date, didn't do much, and I
- doubt anyone was using it.
-
- * no_diff.c (No_Difference): Don't change the modes of the files.
-
-Thu Aug 31 13:14:34 1995 Jim Kingdon <kingdon@harvey.cyclic.com>
-
- * version.c: Change version to 1.5.1.
-
- * client.c (start_rsh_server): Don't pass -d to "cvs server"
- invocation via rsh (restore change which was lost when NT stuff
- was merged in).
- * sanity.sh: Add TODO item suggesting test for bug which this fixes.
-
-Wed Aug 30 12:36:37 1995 Jim Blandy <jimb@totoro.cyclic.com>
-
- * sanity.sh (basic1): Make sure first-dir is deleted before
- running this set of tests.
-
- * subr.c: Extract file twiddling functions to a different file,
- because we want to use different versions of many of these
- routines under Windows NT.
- (copy_file, isdir, islink, isfile, isreadable, iswritable,
- open_file, make_directory, make_directories, xchmod,
- rename_file, link_file, unlink_file, xcmp, tmpnam,
- unlink_file_dir, deep_remove_dir): Moved to...
- * filesubr.c: ...this file, which is new.
- * Makefile.in (SOURCES): Mention filesubr.c.
- (COMMON_OBJECTS): Mention filesubr.o.
-
- * subr.c: Extract process execution guts to a different file,
- because we want to replace these routines entirely under
- Windows NT.
- (VA_START, va_alist, va_dcl): Move this stuff...
- (run_add_arg, run_init_prog): and these declarations...
- (run_prog, run_argv, run_argc, run_argc_allocated): and these
- variables...
- (run_setup, run_arg, run_args, run_add_arg, run_init_prog,
- run_exec, run_print, Popen): and these functions...
- * run.c: To this file, which is new.
- * Makefile.in (SOURCES): Mention run.c.
- (COMMON_OBJECTS): Mention run.o.
-
- * status.c (status): Call ign_setup, if client_active. Otherwise,
- we don't end up ignoring CVS directories and such.
-
- * server.c (mkdir_p, dirswitch): Use CVS_MKDIR instead of mkdir.
-
- * repos.c (Name_Repository): Use the isabsolute function instead of
- checking the first character of the path.
- * root.c (Name_Root): Same.
-
- * release.c (release): Use fncmp instead of strcmp to compare
- filenames.
-
- * rcs.c (RCS_parse, RCS_parsercsfile) [LINES_CRLF_TERMINATED]:
- Abort, because we have strong reason to believe this code is
- wrong.
-
- * patch.c (patch): Register signal handlers iff the signal name is
- #defined.
-
- * no_diff.c (No_Difference): Don't try to include server_active in
- trace message unless SERVER_SUPPORT is #defined.
-
- * modules.c (do_module): Use CVS_MKDIR instead of mkdir.
-
- * mkmodules.c (main): Call last_component instead of writing it out.
-
- * main.c (main): Call last_component instead of writing it out.
- Break up the long copyright string into several strings; Microsoft
- Visual C++ can't handle a line that long. Feh.
- Use fncmp instead of strcmp to compare filenames.
- Register signal handlers iff the signal name is #defined.
-
- * lock.c (readers_exist): Don't check return value of closedir.
- Most of the rest of the code doesn't, and some systems don't
- provide a return value anyway.
- (set_lock): Use CVS_MKDIR instead of mkdir.
-
- * import.c (import): Use the isabsolute function instead of
- checking the first character of the path.
- Try to delete the temporary file again after we close it, so it'll
- get deleted on systems that don't let you delete files that are
- open.
- (add_rev): Instead of making a hard link to the working file and
- checking in the revision with ci -r, use ci -u and restore the
- permission bits.
- (comtable): Include lines from SYSTEM_COMMENT_TABLE, if it is
- #defined.
- (add_rcs_file) [LINES_CRLF_TERMINATED]: Abort, because we have
- strong reason to believe this code is wrong.
- (import_descend_dir): Use CVS_MKDIR instead of mkdir.
-
- * history.c (read_hrecs): Open the file with OPEN_BINARY.
-
- * find_names.c (add_entries_proc, fsortcmp): Add prototypes.
- * entries.c (write_ent_proc): Add prototype.
- * hash.c (walklist): Add prototype for PROC argument.
- (sortlist): Add prototype for COMP argument.
- (printnode): Add a prototype, and make it static.
-
- * cvs.h (wrap_add_file, wrap_add): Add extern decls for these;
- they're used in import.c and update.c.
- * wrapper.c (wrap_add_file, wrap_add): Remove them from here.
-
- * cvs.h (RUN_NORMAL, RUN_COMBINED, RUN_REALLY, RUN_STDOUT_APPEND,
- RUN_STDERR_APPEND, RUN_SIGNIGNORE, RUN_TTY, run_arg, run_print,
- run_setup, run_args, run_exec, Popen, piped_child, close_on_exec,
- filter_stream_through_program, waitpid): Move all these
- declarations and definitions to the same section.
-
- * cvs.h (error_set_cleanup): Fix prototype.
-
- * cvs.h (isabsolute, last_component): New extern decls.
-
- * cvs.h (link_file): Function is deleted; remove extern decl.
-
- * cvs.h (DEATH_STATE, DEATH_SUPPORT): Move #definitions of these
- above the point where we #include rcs.h, since rcs.h tests them
- (or DEATH_SUPPORT, at least).
-
- * cvs.h (DEVNULL): #define this iff it isn't already #defined.
- config.h may want to override it.
-
- * cvs.h (SERVER_SUPPORT, CLIENT_SUPPORT): Don't #define these
- here; let config.h do that. On some systems, we don't have any
- server support.
-
- * cvs.h: Don't #include <io.h> or <direct.h>; we take care of
- those in lib/system.h.
-
- * commit.c (commit): Open logfile with the OPEN_BINARY flag.
- (precommit_proc): Use the isabsolute function, instead of
- comparing the first character with /.
- (remove_file, checkaddfile): Use CVS_MKDIR instead of mkdir.
-
- * client.c (send_repository): Use larger line buffers.
-
- * client.c [LINES_CRLF_TERMINATED] (update_entries): If we've just
- received a gzipped file, copy it over, converting LF to CRLF,
- instead of just renaming it into place.
- [LINES_CRLF_TERMINATED] (send_modified): Convert file to LF format
- before sending with gzip.
- (send_modified): Don't be disturbed if we get fewer than
- sb.st_size characters when we read. The read function may be
- collapsing CRLF to LF for us.
-
- * client.c: Add forward declarations for all the cvs command
- functions we call.
-
- * client.c: Add forward static declarations for all the
- handle_mumble functions.
-
- On some systems, RSH converts LF to CRLF; this screws us up.
- * client.c (rsh_pid): Declare this iff RSH_NOT_TRANSPARENT is not
- #defined.
- (get_responses_and_close): Use SHUTDOWN_SERVER if it is #defined.
- Only wait for rsh process to exit if RSH_NOT_TRANSPARENT is not
- #defined.
- (start_rsh_server): Declare and define only if
- RSH_NOT_TRANSPARENT is not #defined. Use piped_child, instead of
- writing all that out.
- (start_server): Only try to call start_rsh_server if
- RSH_NOT_TRANSPARENT is not #defined. Use START_SERVER if it is
- #defined. Convert file descriptors to stdio file pointers using
- the FOPEN_BINARY_WRITE and FOPEN_BINARY_READ strings.
-
- * client.h (rsh_pid): Don't declare this; it's never used elsewhere.
- (supported_request): Add external declaration for this;
- it's used in checkout.c.
-
- Move process-running functions to run.c; we need to totally
- replace these on other systems, like Windows NT.
- * client.c (close_on_exec, filter_stream_through_program): Moved
- to run.c.
- * run.c (close_on_exec, filter_stream_through_program): Here they
- are.
-
- * add.c (add_directory): Use CVS_MKDIR instead of straight mkdir.
- * checkout.c (checkout, build_dirs_and_chdir): Same.
- (checkout_proc): Use fncmp instead of strcmp.
- * client.c (call_in_directory): Use CVS_MKDIR instead of straight
- mkdir.
-
- * client.c (handle_checksum): Cast return value of strtol.
-
-Wed Aug 30 10:35:46 1995 Stefan Monnier <stefan.monnier@epfl.ch>
-
- * main.c (main): Allow -d to override CVSROOT_ENV.
-
-Thu Aug 24 18:57:49 1995 Jim Kingdon <kingdon@harvey.cyclic.com>
-
- * cvs.h, rcscmds.c (RCS_unlock, RCS_deltag, RCS_lock): Add extra
- parameter for whether to direct stderr to DEVNULL.
- * checkin.c, tag.c, rtag.c, import.c, commit.c: Pass extra
- argument. 1 if stderr had been directed to DEVNULL before
- rcscmds.c was in use, 0 if it was RUN_TTY.
-
- * cvs.h: Add comment regarding attic.
-
-Tue Aug 22 10:09:29 1995 Alexander Dupuy <dupuy@smarts.com>
-
- * rcs.c (whitespace): Cast to unsigned char in case char is signed
- and value is negative.
-
-Tue Aug 22 10:09:29 1995 Kirby Koster <koster@sctc.com>
- and Jim Kingdon <kingdon@harvey.cyclic.com>
-
- * update.c (join_file): If vers->vn_user is NULL, just return.
-
-Tue Aug 22 10:09:29 1995 Jim Kingdon <kingdon@harvey.cyclic.com>
-
- * server.c, client.c: Add comments about modes and umasks.
-
-Mon Aug 21 12:54:14 1995 Rick Sladkey <jrs@world.std.com>
-
- * update.c (update_filesdone_proc): If pipeout, don't try to
- create CVS/Root.
-
-Mon Aug 21 12:54:14 1995 Jim Kingdon <kingdon@harvey.cyclic.com>
-
- * client.c (start_rsh_server): Don't pass -d to "cvs server"
- invocation via rsh.
-
- * server.c (serve_root): Report errors via pending_error_text.
- (serve_valid_requests): Check for pending errors.
-
-Sun Aug 20 00:59:46 1995 Jim Kingdon <kingdon@harvey.cyclic.com>
-
- * options.h.in: Document usage of DIFF in update.c
- * update.c: Use DIFF -c, not DIFF -u. The small improvement in
- diff size is not worth the hassle in terms of everyone having to
- make sure that DIFF is GNU diff (IMHO).
-
-Sat Aug 19 22:05:46 1995 Jim Blandy <jimb@totoro.cyclic.com>
-
- * recurse.c (start_recursion): Doc fix.
-
- * server.c (do_cvs_command): Clear error_use_protocol in the
- child.
- (server): Set error_use_protocol.
-
-Sun Aug 13 15:33:37 1995 Jim Kingdon <kingdon@harvey.cyclic.com>
-
- * server.c (do_cvs_command): Don't select on exceptions.
-
-Fri Aug 4 00:13:47 1995 Jim Meyering (meyering@comco.com)
-
- * Makefile.in (LDFLAGS): Set to @LDFLAGS@.
- (options.h): Depend on ../config.status and options.h.in.
- Add rule to build it from dependents.
-
- * add.c: Include save-cwd.h.
- (add_directory): Use save_cwd and restore_cwd instead of
- explicit getwd then chdir.
- * import.c (import_descend_dir): Likewise.
- * modules.c (do_module): Likewise.
-
- * recurse.c (save_cwd, restore_cwd, free_cwd): Remove functions.
- New versions have been broken out into save-cwd.c.
- (do_dir_proc): Adapt to handle status code returned by new versions
- of save_cwd and restore_cwd -- and one fewer argument to restore_cwd.
- (unroll_files_proc): Likewise.
-
- * wrapper.c (wrap_name_has): Add default: abort () to switch
- statement to avoid warning from gcc -Wall.
- (wrap_matching_entry): Remove dcl of unused TEMP.
- (wrap_tocvs_process_file): Remove dcl of unused ERR.
- (wrap_fromcvs_process_file): Likewise.
-
- * cvs.h: Remove prototype for error. Instead, include error.h.
- Also, remove trailing white space.
-
-Thu Aug 3 10:12:20 1995 Jim Meyering (meyering@comco.com)
-
- * import.c (import_descend_dir): Don't print probably-bogus CWD
- in error messages saying `cannot get working directory'.
-
-Sun Jul 30 20:52:04 1995 James Kingdon <kingdon@harvey.cyclic.com>
-
- * parseinfo.c (Parse_Info): Revise comments and indentation.
-
-Sun Jul 30 15:30:16 1995 Vince DeMarco <vdemarco@bou.shl.com>
-
- * history.c: put ifdef SERVER_SUPPORT around tracing code incase
- the client/server code is not compiled into the program.
-
-Sat Jul 29 16:59:49 1995 James Kingdon <kingdon@harvey.cyclic.com>
-
- * subr.c (deep_remove_dir): Use struct dirent, not struct direct.
-
-Sat Jul 29 18:32:06 1995 Vince DeMarco <vdemarco@bou.shl.com>
-
- * add.c: Check wrap_name_has.
-
- * diff.c, checkin.c, import.c: have code call unlink_file_dir in
- the appropriate places instead of just calling unlink_file.
-
- * checkin.c: Remove one unlink call.
-
- * import.c (comtable): Add .m .psw .pswm.
-
- * import.c (add_rcs_file): Remove tocvsPath before returning.
-
- * subr.c (unlink_file_dir): Add new function. unlinks the file if
- it is a file. or will do a recursive delete if the path is
- actually a directory.
- (deep_remove_dir): New function, helps unlink_file_dir.
-
- * mkmodules.c: Added CVSROOTADM_WRAPPER (cvswrappers file) to the
- checkout file list.
-
-Fri Jul 28 16:27:56 1995 James Kingdon <kingdon@harvey.cyclic.com>
-
- * checkout.c (safe_location): Use PATH_MAX not MAXPATHLEN.
-
-Fri Jul 28 19:37:03 1995 Paul Eggert <eggert@twinsun.com>
-
- * log.c (cvslog, log_fileproc): Pass all options (except -l)
- to rlog as-is, so that users can put spaces in options,
- can specify multiple -d options, etc.
- (ac, av): New variables.
- (log_option_with_arg, options): Remove.
-
- (log_fileproc): Don't prepend `/' to file name if update_dir is empty.
-
-Tue Jul 25 00:52:26 1995 James Kingdon <kingdon@harvey.cyclic.com>
-
- * checkout.c (safe_location): Don't use PROTO in function definition.
-
-Mon Jul 24 18:32:06 1995 Vince DeMarco <vdemarco@bou.shl.com>
-
- * checkout.c (safe_location): fix a compiler warning. (Declare
- safe_location). Changed code in safe_location to call getwd
- instead of getcwd. getwd is declared in the ../lib directory and
- used exclusively thoughout the code. (this helps portability on
- non POSIX systems).
-
- * wrapper.c: updated Andrew Athan's email address.
-
- * main.c: fix an ifdef so the code will compile. syntax error in
- the ifdef for CVS_NOADMIN.
-
-Mon Jul 24 13:25:00 1995 Del <del@babel.dialix.oz.au>
-
- * checkout.c: New procedure safe_location.
- Ensures that you don't check out into the repository
- itself.
-
- * tag.c, rtag.c, cvs.h, mkmodules.c: Added a "taginfo" file in
- CVSROOT to perform pre-tag checks.
-
- * main.c, options.h.in: Added a compile time option to
- disable the admin command.
-
-Fri Jul 21 17:07:42 1995 James Kingdon <kingdon@harvey.cyclic.com>
-
- * update.c, status.c, patch.c, checkout.c, import.c, release.c,
- rtag.c, tag.c: Now -q and -Q options just print an error message
- telling you to use global -q and -Q options. The non-global
- options were a mess because some commands accepted them and some
- did not, and they were redundant with -q and -Q global options.
-
- * rcs.c, cvs.h, commit.c, log.c, find_names.c: Remove CVS.dea
- stuff. It is slower than the alternatives and I don't think
- anyone ever actually used it.
-
-Fri Jul 21 10:35:10 1995 Vince DeMarco <vdemarco@bou.shl.com>
-
- * Makefile.in (SOURCES, OBJECTS): Add wrapper.c, wrapper.o.
- * add.c, admin.c, checkout.c, commit.c, diff.c, import.c, log.c,
- remove.c, status.c: Call wrap_setup at start of commands.
- * add.c (add): Check for wrapper, as well as directory, in repository.
- * checkin.c: Add tocvsPath variable and associated handling.
- * cvs.h: Add wrapper declarations.
- * diff.c: Add tocvsPath variable and associated handling.
- * import.c: Add -W option, CVSDOTWRAPPER handling.
- (import_descend): check wrap_name_has.
- (update_rcs_file, add_rev, add_rcs_file): add tocvsPath
- variable and associated handling.
- * no_diff.c: Add tocvsPath variable and associated handling.
- * recurse.c (start_recursion): Check wrap_name_has.
- * update.c: Copy, don't merge, copy-by-merge files. Attempt to
- use -j on a copy-by-merge file generates a warning and no further
- action.
- * update.c: Add CVSDOTWRAPPER handling.
- * wrapper.c: Added.
-
-Fri Jul 21 00:20:52 1995 James Kingdon <kingdon@harvey.cyclic.com>
-
- * client.c: Revert David Lamkin patch, except for the bits about
- removing temp_filename and the .rej file.
- * sanity.sh (errmsg1): Test for the underlying bug which Lamkin
- kludged around.
- * client.c (call_in_directory): Set short_pathname to include the
- filename, not just the directory. Improve comments regarding what
- is passed to FUNC.
-
-Thu Jul 20 17:51:54 1995 David Lamkin <drl@net-tel.co.uk>
-
- * client.c (short_pathname): Fixes the fetching of the whole file
- after a patch to bring it up to date has failed:
- - failed_patches[] now holds short path to file that failed
- - patch temp files are unlinked where the patch is done
-
-Thu Jul 20 12:37:10 1995 James Kingdon <kingdon@harvey.cyclic.com>
-
- * cvs.h: Declare error_set_cleanup
- * main.c: Call it.
- (error_cleanup): New function.
-
-Thu Jul 20 12:17:16 1995 Mark H. Wilkinson <mhw@minster.york.ac.uk>
-
- * add.c, admin.c, checkin.c, checkout.c, classify.c, client.c,
- client.h, commit.c, create_adm.c, cvs.h, diff.c, entries.c,
- history.c, import.c, log.c, main.c, modules.c, no_diff.c, patch.c,
- release.c, remove.c, repos.c, rtag.c, server.c, server.h,
- status.c, subr.c, tag.c, update.c, vers_ts.c, version.c: Put
- client code inside #ifdef CLIENT_SUPPORT, server code inside
- #ifdef SERVER_SUPPORT. When reporting version, report whether
- client and/or server are compiled in.
-
-Wed Jul 19 18:00:00 1995 Jim Blandy <jimb@cyclic.com>
-
- * subr.c (copy_file): Declare local var n to be an int,
- not a size_t. size_t is unsigned, and the return values
- of read and write are definitely not unsigned.
-
- * cvs.h [HAVE_IO_H]: #include <io.h>.
- [HAVE_DIRECT_H]: #include <direct.h>.
-
-Fri Jul 14 22:28:46 1995 Jim Blandy <jimb@totoro.cyclic.com>
-
- * server.c (dirswitch, serve_static_directory, serve_sticky,
- serve_lost, server_write_entries, serve_checkin_prog,
- serve_update_prog): Include more information in error messages.
- (Thanks, DJM.)
-
- * cvsbug.sh: Use /usr/sbin/sendmail, unless it doesn't
- exist, in which case use /usr/lib/sendmail. (Thanks, DJM.)
-
- * server.c (server, server_cleanup): Use "/tmp" instead of
- "/usr/tmp" when the TMPDIR environment variable isn't set. This
- is what the rest of the code uses.
-
-Thu Jul 13 11:03:17 1995 Jim Meyering (meyering@comco.com)
-
- * recurse.c (free_cwd): New function.
- (save_cwd, restore_cwd): Use it instead of simply freeing any
- string. The function also closes any open file descriptor.
-
- * import.c (comtable): Now static.
- (comtable): Put braces around each element of initializer.
-
- * cvs.h: Add prototype for xgetwd.
- * recurse.c (save_cwd, restore_cwd): New functions to encapsulate
- run-time solution to secure-SunOS vs. fchown problem.
- (do_dir_proc, unroll_files_proc): Use new functions instead of
- open-coded fchdir/chdir calls with cpp directives.
-
- * sanity.sh: Change out of TESTDIR before removing it.
- Some versions of rm fail when asked to delete the current directory.
-
-Wed Jul 12 22:35:04 1995 Jim Meyering (meyering@comco.com)
-
- * client.c (get_short_pathname): Add const qualifier to parameter dcl.
- (copy_a_file): Remove set-but-not-used variable, LEN.
- (handle_clear_static_directory): Likewise: SHORT_PATHNAME.
- (set_sticky): Likewise: LEN.
- (handle_set_sticky): Likewise: SHORT_PATHNAME.
- (handle_clear_sticky): Likewise: SHORT_PATHNAME.
- (start_rsh_server): Convert perl-style `cond || stmt' to more
- conventional C-style `if (cond) stmt.' Sheesh.
- Remove dcl of unused file-static, SEND_CONTENTS.
-
- * history.c: Remove dcls of set-but-not-used file-statics,
- HISTSIZE, HISTDATA.
- (read_hrecs): Don't set them.
-
- * import.c (add_rev): Remove dcl of set-but-not-used local, RETCODE.
-
- * repos.c (Name_Repository): Remove dcl of set-but-not-used local,
- HAS_CVSADM.
-
- * cvsrc.c (read_cvsrc): Parenthesize assignment used as truth value.
-
-Tue Jul 11 16:49:41 1995 J.T. Conklin <jtc@rtl.cygnus.com>
-
- * hash.h (struct entnode, Entnode): moved from here...
- * cvs.h: to here.
-
-Wed Jul 12 19:45:24 1995 Dominik Westner (dominik@gowest.ppp.informatik.uni-muenchen.de)
-
- * client.c (server_user): new var.
- (parse_cvsroot): set above if repo is "user@host:/dir".
- (start_rsh_server): if server_user set, then use it.
-
-Wed Jul 12 10:53:36 1995 Karl Fogel <kfogel@floss.cyclic.com>
-
- * sanity.sh: remove the TESTDIR after done.
-
- * cvsbug.sh (GNATS_ADDR): now bug-cvs@prep.ai.mit.edu again.
-
-Tue Jul 11 15:53:08 1995 Greg A. Woods <woods@most.weird.com>
-
- * options.h.in: depend on configure for grep and diff, now that
- changes to configure.in are applied.
-
-Tue Jul 11 14:32:14 1995 Michael Shields <shields@tembel.org>
-
- * Makefile.in (LDFLAGS): Pick up from configure.
-
-Tue Jul 11 14:20:00 1995 Loren James Rittle <rittle@supra.comm.mot.com>
-
- * import.c (add_rev), commit.c (remove_file, ci_new_rev),
- checkin.c (Checkin), subr.c (make_message_rcslegal), cvs.h:
- Always perform sanity check and fix-up on messages to be passed
- directly to RCS via the '-m' switch. RCS 5.7 requires that a
- non-total-whitespace, non-null message be provided or it will
- abort with an error. CVS is not setup to handle any returned
- error from 'ci' gracefully and, thus, the repository entered a
- trashed state.
-
- * sanity.sh: Add regression tests for new code and interactions
- with RCS 5.7.
-
-Sun Jul 9 19:03:00 1995 Greg A. Woods <woods@most.weird.com>
-
- * .cvsignore: added new backup file
-
- * options.h.in: our new configure.in finds the right diff and
- grep paths now....
-
- * subr.c: quote the string in run_print() for visibility
- - indent a comment
- - Jun Hamano's xchmod() patch to prevent writable files
- (from previous local changes)
-
- * logmsg.c: fix a NULL pointer de-reference
- - clean up some string handling code...
- (from previous local changes)
-
- * parseinfo.c: add hack to expand $CVSROOT in an *info file.
- - document "ALL" and "DEFAULT" in opening comment for Parse_Info()
- - fix the code to match the comments w.r.t. callbacks for "ALL"
- - add a line of trace output...
- (from previous local changes)
-
- * mkmodules.c: add support for comments in CVSROOT/checkoutlist
- - add CVSroot used by something other .o, ala main.c
- (from previous local changes)
-
- * main.c, cvs.h: add support for $VISUAL as log msg editor
- (from previous local changes)
-
- * status.c: add support for -q and -Q (from previous local changes)
-
-
-Sun Jul 9 18:44:32 1995 Karl Fogel <kfogel@floss.cyclic.com>
-
- * log.c: trivial change to test ChangeLog stuff.
-
-Sat Jul 8 20:33:57 1995 Paul Eggert <eggert@twinsun.com>
-
- * history.c: (history_write): Don't assume that fopen(..., "a")
- lets one interleave writes to the history file from different processes
- without interlocking. Use open's O_APPEND option instead.
- Throw in an lseek to lessen the race bugs on non-Posix hosts.
- * cvs.h, subr.c (Fopen): Remove.
-
- * log.c (log_fileproc): Pass working file name to rlog, so that
- the name is reported correctly.
-
-Fri Jul 7 18:29:37 1995 Michael Hohmuth <hohmuth@inf.tu-dresden.de>
-
- * client.c, client.h (client_import_setup): New function.
- (client_import_done, client_process_import_file): Add comments
- regarding now-redundant code.
- * import.c (import): Call client_import_setup.
-
-Tue Jul 4 09:21:26 1995 Bernd Leibing <bernd.leibing@rz.uni-ulm.de>
-
- * rcs.c (RCS_parsercsfile_i): Rename error to l_error; SunOS4 /bin/cc
- doesn't like a label and function with the same name.
-
-Sun Jul 2 12:51:33 1995 Fred Appelman <Fred.Appelman@cv.ruu.nl>
-
- * logmsg.c: Rename strlist to str_list to avoid conflict with
- Unixware 2.01.
-
-Thu Jun 29 17:37:22 1995 Paul Eggert <eggert@twinsun.com>
-
- * rcs.c (RCS_check_kflag): Allow RCS 5.7's new -kb option.
-
-Wed Jun 28 09:53:14 1995 James Kingdon <kingdon@harvey.cyclic.com>
-
- * Makefile.in (HEADERS): Remove options.h.in.
- (DISTFILES): Add options.h.in.
- Depend on options.h in addition to HEADERS.
-
-Tue Jun 27 22:37:28 1995 Vince Demarco <vdemarco@bou.shl.com>
-
- * subr.c: Don't try to do fancy waitstatus stuff for NeXT,
- lib/wait.h is sufficient.
-
-Mon Jun 26 15:17:45 1995 James Kingdon <kingdon@harvey.cyclic.com>
-
- * Makefile.in (DISTFILES): Remove RCS-patches and convert.sh.
-
-Fri Jun 23 13:38:28 1995 J.T. Conklin (jtc@rtl.cygnus.com)
-
- * server.c (dirswitch, serve_co): Use CVSADM macro instead of
- literal "CVS".
-
-Fri Jun 23 00:00:51 1995 James Kingdon <kingdon@harvey.cyclic.com>
-
- * README-rm-add: Do not talk about patching RCS, that only
- confuses people.
- * RCS-patches, convert.sh: Removed (likewise).
-
-Thu Jun 22 10:41:41 1995 James Kingdon <kingdon@harvey.cyclic.com>
-
- * subr.c: Change -1 to (size_t)-1 when comparing against a size_t.
-
-Wed Jun 21 16:51:54 1995 nk@ipgate.col.sw-ley.de (Norbert Kiesel)
-
- * create_adm.c, entries.c, modules.c: Avoid coredumps if
- timestamps, tags, etc., are NULL.
-
-Tue Jun 20 15:52:53 1995 Jim Meyering (meyering@comco.com)
-
- * checkout.c (checkout): Remove dcl of unused variable.
- * client.c (call_in_directory, handle_clear_static_directory,
- handle_set_sticky, handle_clear_sticky, send_a_repository,
- send_modified, send_dirent_proc): Remove dcls of unused variables.
- * server.c (receive_file, serve_modified, server_cleanup):
- Remove dcls of unused variables.
- * subr.c (copy_file): Remove dcl of unused variable.
- * vers_ts.c (time_stamp_server): Remove dcl of unused variable.
-
-Mon Jun 19 13:49:35 1995 Jim Blandy <jimb@totoro.cyclic.com>
-
- * sanity.sh: Fix commencement message --- the test suite says
- "Ok." when it's done.
-
-Fri Jun 16 11:23:44 1995 Jim Meyering (meyering@comco.com)
-
- * entries.c (fgetentent): Parenthesize assignment in if-conditional.
-
-Thu Jun 15 17:33:28 1995 J.T. Conklin <jtc@rtl.cygnus.com>
-
- * server.c (get_buffer_data, buf_append_char, buf_append_data):
- Don't conditionalize use of "inline". Autoconf takes care of
- defining it away on systems that don't grok it.
-
-Thu Jun 15 13:43:38 1995 Jim Kingdon (kingdon@cyclic.com)
-
- * options.h.in (DIFF): Default to "diff" not "diff -a" since diff
- might not support the -a option.
-
-Wed Jun 14 11:29:42 1995 J.T. Conklin <jtc@rtl.cygnus.com>
-
- * import.c (import_descend): Initialize dirlist to NULL.
-
- * subr.c (copy_file): Fix infinite loop.
-
- * server.c (serve_directory): fix a memory leak.
-
- * checkout.c, commit.c, diff.c, history.c, import.c, log.c,
- patch.c, release.c, remove.c, rtag.c, status.c, tag.c, update.c:
- Use send_arg() to send command line arguments to server.
-
- * commit.c (fsortcmp), find_names (fsortcmp), hash.c (hashp,
- findnode), hash.h (findnode), rcs.c (RCS_addnode,
- RCS_check_kflag, RCS_check_tag, RCS_isdead, RCS_parse,
- RCS_parsercsfile_i), rcs.h (RCS_addnode, RCS_check_kflag,
- RCS_check_tag, RCS_parse): Added const qualifiers as
- appropriate.
- * rcs.h (RCS_isdead): Added prototype.
-
- * hash.h (walklist, sortlist): correct function prototypes.
-
- * ignore.c (ign_setup): don't bother checking to see if file
- exists before calling ign_add_file.
-
-Fri Jun 9 11:24:06 1995 J.T. Conklin <jtc@rtl.cygnus.com>
-
- * all source files (rcsid): Added const qualifer.
- * ignore.c (ign_default): Added const qualifier.
- * subr.c (numdots): Added const qualifier to function argument.
- * cvs.h (numdots): Added const qualifier to prototype argument.
-
- * client.c (change_mode): Tied consecutive if statements testing
- the same variable together with else if.
-
- * import.c (import_descend): Build list of subdirectories when
- reading directory, and then process the subdirectories in that
- list. This change avoids I/O overhead of rereading directory
- and reloading ignore list (.cvsignore) for each subdirectory.
-
-Thu Jun 8 11:54:24 1995 J.T. Conklin <jtc@rtl.cygnus.com>
-
- * import.c (import_descend): Use 4.4BSD d_type field if it is
- present.
-
- * lock.c (set_lockers_name): Use %lu in format and cast st_uid
- field to unsigned long.
-
- * import.c (import): Use RCS_check_kflag() to check -k options.
- (keyword_usage, str2expmode, strn2expmode, expand_names):
- Removed.
- * rcs.c (RCS_check_kflag): Added keyword_usage array from import.c
- for more descriptive error messages.
-
- * subr.c (run_setup, run_args): Changed variable argument
- processing to work on machines that use <varargs.h>.
-
- * subr.c (copy_file, xcmp): Changed to read the file(s) by blocks
- rather than by reading the whole file into a huge buffer. The
- claim that this was reasonable because source files tend to be
- small does not hold up in real world situations. CVS is used
- to manage non-source files, and mallocs of 400K+ buffers (x2
- for xcmp) can easily fail due to lack of available memory or
- even memory pool fragmentation.
- (block_read): New function, taken from GNU cmp and slightly
- modified.
-
- * subr.c (xcmp): Added const qualifier to function arguments.
- * cvs.h (xcmp): Added const qualifer to prototype arguments.
-
-Wed Jun 7 11:28:31 1995 J.T. Conklin <jtc@rtl.cygnus.com>
-
- * cvs.h (Popen): Added prototype.
- (Fopen, open_file, isreadable, iswritable, isdir, isfile,
- islink, make_directory, make_directories, rename_file,
- link_file, unlink_file, copy_file): Added const qualifer to
- prototype arguments.
- * subr.c (Fopen, Popen, open_file, isreadable, iswritable, isdir,
- isfile, islink, make_directory, make_directories, rename_file,
- link_file, unlink_file, copy_file): Added const qualifier to
- function arguments.
-
- * logmsg.c (logfile_write), recurse.c (do_recursion, addfile):
- Don't cast void functions to a void expression. There is at
- least one compiler (MPW) that balks at this.
-
- * rcs.c (keysize, valsize): Change type to size_t.
-
- * add.c (add_directory): Don't cast umask() argument to int.
-
- * import.c (add_rcs_file): Changed type of mode to mode_t.
-
- * rcscmds.c (RCS_merge): New function.
- * cvs.h (RCS_merge): Declare.
- * update.c (merge_file, join_file): Call RCS_merge instead of
- invoking rcsmerge directly.
-
- * cvs.h: Include <stdlib.h> if HAVE_STDC_HEADERS, otherwise
- declared getenv().
- * cvsrc.c, ignore.c, main.c: Removed getenv() declaration.
-
- * client.c (mode_to_string): Changed to take mode_t instead of
- struct statb argument. Simplified implementation, no longer
- overallocates storage for returned mode string.
- * client.h (mode_to_string): Updated declaration.
- * server.c (server_updated): Updated for new calling conventions,
- pass st_mode instead of pointer to struct statb.
-
- * cvs.h (CONST): Removed definition, use of const qualifier is
- determined by autoconf.
- * history.c, modules.c, parseinfo.c: Use const instead of CONST.
-
- * add.c, admin.c, checkout.c, commit.c, diff.c, import.c, log.c,
- main.c, mkmodules.c, patch.c, recurse.c, remove.c, rtag.c,
- server.c, status.c, subr.c, tag.c, update.c: Changed function
- arguments "char *argv[]" to "char **argv" to silence lint
- warnings about performing arithmetic on arrays.
-
-Tue Jun 6 18:57:21 1995 Jim Blandy <jimb@totoro.cyclic.com>
-
- * version.c: Fix up version string, to say that this is Cyclic
- CVS.
-
-Tue Jun 6 15:26:16 1995 J.T. Conklin <jtc@rtl.cygnus.com>
-
- * subr.c (run_setup, run_args, run_add_arg, xstrdup): Add const
- qualifier to format argument.
- * cvs.h (run_setup, run_args, xstrdup): Likewise.
-
- * Makefile.in (SOURCES): Added rcscmds.c.
- (OBJECTS): Added rcscmds.o.
-
- * rcscmds.c: New file, with new functions RCS_settag, RCS_deltag,
- RCS_setbranch, RCS_lock, RCS_unlock.
- * checkin.c, commit.c, import.c, rtag.c, tag.c: Call above
- functions instead of exec'ing rcs commands.
- * cvs.h: Declare new functions.
-
-Mon May 29 21:40:54 1995 J.T. Conklin (jtc@rtl.cygnus.com)
-
- * recurse.c (start_recursion, do_recursion): Set entries to NULL
- after calling Entries_Close().
-
-Sat May 27 08:08:18 1995 Jim Meyering (meyering@comco.com)
-
- * Makefile.in (check): Export RCSBIN only if there exists an
- `rcs' executable in ../../rcs/src. Before, tests would fail when
- the directory existed but contained no executables.
- (distclean): Remove options.h, now that it's generated.
- (Makefile): Regenerate only *this* file when Makefile.in is
- out of date. Depend on ../config.status.
-
-Fri May 26 14:34:28 1995 J.T. Conklin <jtc@rtl.cygnus.com>
-
- * entries.c (Entries_Open): Added missing fclose().
- (Entries_Close): Don't write Entries unless Entries.Log exists.
-
- * entries.c (Entries_Open): Renamed from ParseEntries; changed to
- process Entries Log files left over from previous crashes or
- aborted runs.
- (Entries_Close): New function, write out Entries file if
- neccessary and erase Log file.
- (Register): Append changed records to Log file instead of
- re-writing file.
- (fgetentent): New function, parse one Entry record from a file.
- (AddEntryNode): It's no longer an error for two records with the
- same name to be added to the list. New records replace older
- ones.
- * cvs.h (Entries_Open, Entries_Close): Add prototypes.
- (CVSADM_ENTLOG): New constant, name of Entries Log file.
- * add.c, checkout.c, client.c, find_names.c, recurse.c: Use
- Entries_Open()/Entries_Close() instead of ParseEntries()/dellist().
-
- * add.c, admin.c, checkout.c, client.c, commit.c, diff.c,
- history.c, import.c, log.c, patch.c, release.c, remove.c,
- rtag.c, server.c, status.c, tag.c, update.c: Changed
- conditionals so that return value of *printf is tested less than
- 0 instead of equal to EOF.
-
-Thu May 25 08:30:12 1995 Jim Kingdon (kingdon@lioth.cygnus.com)
-
- * subr.c (xmalloc): Never try to malloc zero bytes; if the user
- asks for zero bytes, malloc one instead.
-
-Wed May 24 12:44:25 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
-
- * subr.c (xmalloc): Don't complain about NULL if zero bytes were
- requested.
-
-Tue May 16 21:49:05 1995 Jim Blandy <jimb@totoro.bio.indiana.edu>
-
- * subr.c (xmalloc): Never try to malloc zero bytes; if the user
- asks for zero bytes, malloc one instead.
-
-Mon May 15 14:35:11 1995 J.T. Conklin <jtc@rtl.cygnus.com>
-
- * lock.c (L_LOCK_OWNED): Removed.
-
- * add.c, checkout.c, client.c, create_adm.c, cvs.h, entries.c,
- find_names.c modules.c, recurse.c, release.c, repos.c, update.c:
- removed CVS 1.2 compatibility/upgrade code.
-
-Mon May 8 11:25:07 1995 J.T. Conklin <jtc@rtl.cygnus.com>
-
- * lock.c (write_lock): Missed one instance where rmdir(tmp) should
- have been changed to clear_lock().
-
-Wed May 3 11:08:32 1995 J.T. Conklin <jtc@rtl.cygnus.com>
-
- * create_adm.c, entries.c, import.c, root.c: Changed conditionals
- so that return value of *printf is tested less than 0 instead of
- equal to EOF --- That's all Standard C requires.
-
-Wed May 3 18:03:37 1995 Samuel Tardieu <tardieu@emma.enst.fr>
-
- * rcs.h: removed #ifdef CVS_PRIVATE and #endif because cvs didn't
- compile anymore.
-
-Mon May 1 13:58:53 1995 J.T. Conklin <jtc@rtl.cygnus.com>
-
- * rcs.c, rcs.h: Implemented lazy parsing of rcs files.
- RCS_parsercsfile_i modified to read only the first two records
- of rcs files, a new function RCS_reparsercsfile is called only
- when additional information (tags, revision numbers, dates,
- etc.) is required.
-
-Mon May 1 12:20:02 1995 Jim Kingdon (kingdon@lioth.cygnus.com)
-
- * Makefile.in (INCLUDES): Include -I. for options.h.
-
-Fri Apr 28 16:16:33 1995 Jim Blandy <jimb@totoro.bio.indiana.edu>
-
- * Makefile.in (SOURCES, HEADERS, DISTFILES): Updated.
- (dist-dir): Renamed from dist; changed to work with DISTDIR
- variable passed from parent.
-
- We don't want to include a file the user has to edit in the
- distribution.
- * options.h: No longer distributed.
- * options.h.in: Distribute this instead.
- * ../INSTALL, ../README: Installation instructions updated.
-
- * client.c (start_rsh_server): Send the remote command to rsh as a
- single string.
-
-Fri Apr 28 00:29:49 1995 Noel Cragg <noel@vo.com>
-
- * commit.c: Added initializer for FORCE_CI
-
- * sanity.sh: Fix tests added 25 Apr -- they were expecting the
- server to make noise, but the CVS_SERVER variable had been
- accidentally set with the `-Q' flag. Ran all tests -- both
- locally and remotely -- to verify that the change didn't break
- anything.
-
-Thu Apr 27 12:41:52 1995 Jim Kingdon (kingdon@lioth.cygnus.com)
-
- * Makefile.in: Revise comment regarding check vs. remotecheck.
-
-Thu Apr 27 12:52:28 1995 Bryan O'Sullivan <bos@cyclic.com>
-
- * client.c (start_rsh_server): If the CVS_RSH environment variable
- is set, use its contents as the name of the program to invoke
- instead of `rsh'.
-
-Thu Apr 27 12:18:38 1995 Noel Cragg <noel@vo.com>
-
- * checkout.c (checkout): To fix new bug created by Apr 23 change,
- re-enabled "expand-module" functionality, because it has the side
- effect of setting the checkin/update programs for a directory. To
- solve the local/remote checkout problem that prompted this change
- in the first place, I performed the next change.
- * server.c (expand_proc): Now returns expansions for aliases only.
-
-Wed Apr 26 12:07:42 1995 J.T. Conklin <jtc@rtl.cygnus.com>
-
- * rcs.c (getrcskey): Rewritten to process runs of whitespace chars
- and rcs @ strings instead of using state variables "white" and
- "funky".
-
-Fri Apr 7 15:49:25 1995 J.T. Conklin <jtc@rtl.cygnus.com>
-
- * lock.c (unlock): Only call stat if we need to.
-
-Wed Apr 26 10:48:44 1995 Jim Kingdon (kingdon@lioth.cygnus.com)
-
- * server.c (new_entries_line): Don't prototype.
-
-Tue Apr 25 22:19:16 1995 Jim Blandy <jimb@totoro.bio.indiana.edu>
-
- * sanity.sh: Add new tests to catch bugs in Apr 23 change.
-
-Tue Apr 25 17:10:55 1995 Roland McGrath <roland@baalperazim.frob.com>
-
- * create_adm.c (Create_Admin): Use getwd instead of getcwd.
-
-Sun Apr 23 20:58:32 1995 Noel Cragg <noel@vo.com>
-
- * checkout.c (checkout): Disabled "expand-module" functionality on
- remote checkout, since it makes modules behave like aliases (see
- longer note there). This change necessitated the change below.
- Also merged the like parts of a conditional.
-
- * client.c (call_in_directory): Changed the algorithm that created
- nested and directories and the "CVS" administration directories
- therein. The algoithm wrongly assumed that the name of the
- directory that that was to be created and the repository name were
- the same, which breaks modules.
-
- * create_adm.c (Create_Admin), module.c (do_module), server.c
- (server_register), subr.c, entries.c: Added fprintfs for trace-mode
- debugging.
-
- * client.c (client_send_expansions): Argument to function didn't
- have a type -- added one.
-
- * server.c (new_entries_line): Arguments to this function are
- never used -- reoved them and fixed callers.
-
-Sat Apr 22 11:17:20 1995 Jim Kingdon (kingdon@lioth.cygnus.com)
-
- * rcs.c (RCS_parse): If we can't open the file, give an error
- message (except for ENOENT in case callers rely on that).
-
-Wed Apr 19 08:52:37 1995 Jim Kingdon (kingdon@lioth.cygnus.com)
-
- * client.c (send_repository): Check for CVSADM_ENTSTAT in `dir', not
- in `.'.
-
- * sanity.sh: Add TODO list. Revise some comments. Add tests of
- one working directory adding a file and other updating it.
-
-Sat Apr 8 14:52:55 1995 Jim Blandy <jimb@totoro.bio.indiana.edu>
-
- * Makefile.in (CFLAGS): Let configure set the default for CFLAGS.
- Under GCC, we want -g -O.
-
-Fri Apr 7 15:49:25 1995 J.T. Conklin <jtc@rtl.cygnus.com>
-
- * root.c (Name_Root): merge identical adjacent conditionals.
-
- * create_admin.c (Create_Admin): Rearranged check for CVSADM and
- OCVSADM directories so that CVSADM pathname is only built once.
-
- * update.c (update_dirleave_proc): Removed code to remove CVS
- administration directory if command_name == "export" and to
- create CVS/Root file if it is not present. Identical code
- in update_filesdone_proc() will perform these same actions.
- Also removed code that read and verfied CVS/Root. This is
- expensive, and if it is necessary should happen in the
- general recursion processor rather than in the update
- callbacks.
-
- * lock.c (masterlock): New variable, pathname of master lockdir.
- (set_lock): removed lockdir argument, now constructs it itself
- and stores it in masterlock.
- (clear_lock): new function, removes master lockdir.
- (Reader_Lock, write_lock): call clear_lock instead of removing
- master lockdir.
- (Reader_Lock, write_lock): #ifdef'd out CVSTFL code.
-
- * main.c (main): register Lock_Cleanup signal handler.
- * lock.c (Reader_Lock, write_lock): no longer register
- Lock_Cleanup.
-
- * main.c (main): initialize new array hostname.
- * lock.c (Reader_Lock, write_lock): Use global hostname array.
- * logmsg.c (logfile_write): Likewise.
-
- * recurse.c (do_dir_proc, unroll_files_proc): Use open()/fchdir()
- instead of getwd()/chdir() on systems that support the fchdir()
- system call.
-
-Fri Apr 7 06:57:20 1995 Jim Kingdon (kingdon@lioth.cygnus.com)
-
- * server.c: Include the word "server" in error message for memory
- exhausted, so the user knows which machine ran out of memory.
-
- * sanity.sh: For remote, set CVS_SERVER to test the right server,
- rather than a random one from the PATH.
-
- * commit.c [DEATH_STATE]: Pass -f to `ci'.
-
-Thu Apr 6 13:05:15 1995 Jim Blandy <jimb@totoro.bio.indiana.edu>
-
- * commit.c (checkaddfile): If we didn't manage to fopen the file,
- don't try to fclose it.
-
- * client.c (handle_m, handle_e): Use fwrite, rather than a loop of
- putc's. Sometimes these streams are unbuffered.
-
-Tue Apr 4 11:33:56 1995 Jim Blandy <jimb@totoro.bio.indiana.edu>
-
- * (DISTFILES): Include cvsbug.sh, ChangeLog, NOTES, RCS-patches,
- README-rm-add, ChangeLog.fsf, sanity.sh, sanity.el, and
- .cvsignore.
-
-Mon Mar 27 08:58:42 1995 Jim Kingdon (kingdon@lioth.cygnus.com)
-
- * rcs.c (RCS_parsercsfile_i): Accept `dead' state regardless of
- DEATH_STATE define. Revise comments regarding DEATH_STATE versus
- CVSDEA versus the scheme which uses a patched RCS.
- * README-rm-add, RCS-patches: Explain what versions of CVS need
- RCS patches.
-
-Sat Mar 25 18:51:39 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
-
- * server.c (server_cleanup): Only do the abysmal kludge of waiting
- for command and draining the pipe #ifdef sun. The code makes
- assumptions not valid on all systems, and is only there to
- workaround a SunOS bug.
-
-Wed Mar 22 21:55:56 1995 Jim Kingdon (kingdon@lioth.cygnus.com)
-
- * server.c (mkdir_p): Call stat only if we get the EACCES. Faster
- and more elegant.
-
-Tue Jan 31 20:59:19 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
-
- * server.c: Try to avoid starting the "rm -rf" at cleanup time
- until after subprocesses have finished.
- (command_fds_to_drain, max_command_fd): New variables.
- (do_cvs_command): Set them.
- (command_pid_is_dead): New variable.
- (wait_sig): New function.
- (server_cleanup): If command_pid is nonzero, wait for it to die,
- draining output from it in the meantime. If nonzero SIG was
- passed, send a signal to the subprocess, to encourage it to die
- soon.
-
- * main.c (usage): Argument is now `const char *const *'.
- * cvs.h (usage): Changed prototype.
- (USE): Make new variable `const'.
- * add.c (add_usage), admin.c (admin_usage), checkout.c
- (checkout_usage, export_usage, checkout), commit.c (commit_usage),
- diff.c (diff_usage), history.c (history_usg), import.c
- (import_usage, keyword_usage), log.c (log_usage), main.c (usg),
- patch.c (patch_usage), release.c (release_usage), remove.c
- (remove_usage), rtag.c (rtag_usage), server.c (server), status.c
- (status_usage), tag.c (tag_usage), update.c (update_usage): Usage
- messages are now const arrays of pointers to const char.
-
- * import.c (comtable): Now const.
- * main.c (rcsid): Now static.
- (cmd): Now const.
- (main): Local variable CM now points to const.
- * server.c (outbuf_memory_error): Local var MSG now const.
-
- * client.c (client_commit_usage): Deleted.
-
-Sat Dec 31 15:51:55 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
-
- * logmsg.c (do_editor): Allocate enough space for trailing '\0'.
-
-Fri Mar 3 11:59:49 1995 Jim Blandy <jimb@totoro.bio.indiana.edu>
-
- * cvsbug.sh: Call it "Cyclic CVS" now, not "Remote CVS". Call it
- version C1.4A, not 1.4A2-remote. Send bugs to cyclic-cvs, not
- remote-cvs.
-
- * classify.c (Classify_File): Put check for dead file inside
- "#ifdef DEATH_SUPPORT".
-
-Thu Feb 23 23:03:43 1995 Jim Blandy <jimb@totoro.bio.indiana.edu>
-
- * update.c (join_file): Don't pass the -E option to rcsmerge here,
- either (see Jan 22 change).
-
-Mon Feb 13 13:28:46 1995 Jim Blandy <jimb@totoro.bio.indiana.edu>
-
- * cvsbug.sh: Send bug reports to remote-cvs@cyclic.com, rather
- than to the ordinary CVS bug address. This does mean we'll have
- to wade through GNATS-style bug reports, sigh.
-
-Wed Feb 8 06:42:27 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
-
- * server.c: Don't include <sys/stat.h>; system.h already does, and
- 4.3BSD can't take it twice.
-
- * subr.c [! HAVE_VPRINTF] (run_setup, run_args): Don't use va_dcl
- in declaration. Declare the a1..a8 args which are used in the
- sprintf call.
- * cvs.h [! HAVE_VPRINTF] (run_setup, run_args): Don't prototype
- args, to avoid conflicting with the function definitions
- themselves.
-
-Tue Feb 7 20:10:00 1995 Jim Blandy <jimb@totoro.bio.indiana.edu>
-
- * client.c (update_entries): Pass the patch subprocess the switch
- "-b ~", not "-b~"; the latter form seems not to work with patch
- version 2.0 and earlier --- it takes the next argv element as the
- backup suffix, and thus doesn't notice that the patch file's name
- has been specified, thus doesn't find the patch, thus... *aargh*
-
-Fri Feb 3 20:28:21 1995 Jim Blandy <jimb@totoro.bio.indiana.edu>
-
- * log.c (log_option_with_arg): New function.
- (cvslog): Use it and send_arg to handle the rlog options that take
- arguments. The code used to use send_option_string for
- everything, which assumes that "-d1995/01/02" is equivalent to
- "-d -1 -9 -9 -5 ...".
-
-Tue Jan 31 15:02:01 1995 Jim Blandy <jimb@floss.life.uiuc.edu>
-
- * server.c: #include <sys/stat.h> for the new stat call in mkdir_p.
- (mkdir_p): Don't try to create the intermediate directory if it
- exists already. Some systems return EEXIST, but others return
- EACCES, which we can't otherwise distinguish from a real access
- problem.
-
-Sun Jan 22 15:25:45 1995 Jim Blandy <jimb@totoro.bio.indiana.edu>
-
- * update.c (merge_file): My rcsmerge doesn't accept a -E option,
- and it doesn't look too important, so don't pass it.
-
-Fri Jan 20 14:24:58 1995 Ian Lance Taylor <ian@sanguine.cygnus.com>
-
- * client.c (do_deferred_progs): Don't try to chdir to toplevel_wd
- if it has not been set.
- (process_prune_candidates): Likewise.
-
-Mon Nov 28 09:59:14 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
-
- * client.c (client_commit): Move guts of function from here...
- * commit.c (commit): ...to here.
-
-Mon Nov 28 15:14:36 1994 Ken Raeburn <raeburn@cujo.cygnus.com>
-
- * server.c (buf_input_data, buf_send_output): Start cpp directives
- in column 1, otherwise Sun 4 pcc complains.
-
-Mon Nov 28 09:59:14 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
-
- * client.c (add_prune_candidate): Don't try to prune ".".
-
-Tue Nov 22 05:27:10 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
-
- * server.c, client.c: More formatting cleanups.
-
- * client.h, client.c: New variable client_prune_dirs.
- * update.c (update), checkout.c (checkout): Set it.
- * client.c (add_prune_candidate, process_prune_candidates): New
- functions.
- (send_repository, call_in_directory, get_responses_and_close):
- Call them.
-
-Wed Nov 23 01:17:32 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
-
- * server.c (do_cvs_command): Don't select on STDOUT_FILENO unless
- we have something to write.
-
-Tue Nov 22 05:27:10 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
-
- * remove.c (remove_fileproc): Only call server_checked_in if we
- actually are changing the entries file.
-
- * server.c (server_write_entries): New function.
- (dirswitch, do_cvs_command): Call it.
- (serve_entry, serve_updated): Just update in-memory data
- structures, don't mess with CVS/Entries file.
-
-Mon Nov 21 10:15:11 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
-
- * server.c (server_checked_in): Set scratched_file to NULL after
- using it.
-
- * checkin.c (Checkin): If the file was changed by the checkin,
- call server_updated not server_checked_in.
-
-Sun Nov 20 08:01:51 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
-
- * client.c (send_repository): Move check for update_dir NULL to
- before where we check last_update_dir. Check for "" here too.
-
- * client.c (send_repository): Use new argument dir.
-
- * client.c: Pass new argument dir to send_repository and
- send_a_repository.
-
- * server.c, server.h (server_prog): New function.
- * modules.c (do_modules): Call it if server_expanding.
- * client.c: Support Set-checkin-prog and Set-update-prog responses.
- * server.c, client.c: Add Checkin-prog and Update-prog requests.
-
-Fri Nov 18 14:04:38 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
-
- * client.c (get_short_pathname, is_cvsroot_level,
- call_in_directory): Base whether this is new-style or
- old-style based on whether we actually used the Directory request,
- not based on whether the pathname is absolute. Rename
- directory_supported to use_directory.
- * server.c: Rename use_relative_pathnames to use_dir_and_repos.
- * client.c (send_a_repository): If update_dir is absolute, don't
- use it to try to reconstruct how far we have recursed.
-
- * server.c, server.h, client.c, client.h, vers_ts.c, update.h:
- More cosmetic changes (identation, PARAMS vs. PROTO, eliminate
- alloca, etc.) to remote CVS to make it more like the rest of CVS.
-
- * server.c: Make server_temp_dir just the dir name, not the name
- with "%s" at the end.
- * server.c, client.c: Add "Max-dotdot" request, and use it to make
- extra directories in server_temp_dir if needed.
-
-Thu Nov 17 09:03:28 1994 Jim Kingdon <kingdon@cygnus.com>
-
- * client.c: Fix two cases where NULL was used and 0 was meant.
-
-Mon Nov 14 08:48:41 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
-
- * server.c (serve_unchanged): Set noexec to 0 when calling Register.
-
- * update.c (merge_file): Don't call xcmp if noexec.
-
-Fri Nov 11 13:58:22 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
-
- * client.c (call_in_directory): Deal with it if reposdirname is
- not a subdirectory of toplevel_repos.
-
-Mon Nov 7 09:12:01 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
-
- * patch.c: If file is removed and we don't have a tag or date,
- just print "current release".
-
- * classify.c (Classify_File): Treat dead files appropriately.
-
-Fri Nov 4 07:33:03 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
-
- * main.c (main) [SERVER_SUPPORT]: Move call to getwd past where we
- know whether we are the server or not. Set CurDir to "<remote>"
- if we are the server.
-
- * client.c: Remove #if 0'd function option_with_arg.
- Remove #if 0'd code pertaining to the old way of logging the
- session.
-
- * client.c (start_rsh_server): Don't invoke the server with the
- -d option.
- * server.c (serve_root): Test root for validity, just like main.c
- does for non-remote CVS.
- * main.c (main): If `cvs server' happens with a colon in the
- CVSroot, just handle it normally; don't make it an error.
-
-Wed Nov 2 11:09:38 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
-
- * client.c (send_dirent_proc): If dir does not exist, just return
- R_SKIP_ALL.
-
- * server.c, client.c: Add Directory request and support for
- local relative pathnames (along with the repository absolute
- pathnames).
- * update.c, add.c, checkout.c, checkin.c, cvs.h, create_adm.c,
- commit.c, modules.c, server.c, server.h, remove.c, client.h:
- Pass update_dir to server_* functions. Include update_dir in
- more error messages.
-
-Fri Oct 28 08:54:00 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
-
- * client.c: Reformat to bring closer to cvs standards for brace
- position, comment formatting, etc.
-
- * sanity.sh: Remove wrong "last mod" line. Convert more tests to
- put PASS or FAIL in log file. Change it so arguments to the
- script specify which tests to run.
-
- * client.c, client.h, server.c, checkout.c: Expand modules in
- separate step from the checkout itself.
-
-Sat Oct 22 20:33:35 1994 Ken Raeburn (raeburn@kr-pc.cygnus.com)
-
- * update.c (join_file): When checking for null return from
- RCS_getversion, still do return even if quiet flag is set.
-
-Thu Oct 13 07:36:11 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
-
- * client.c (send_files): Call send_repository even if
- toplevel_repos was NULL.
-
- * server.c (server_updated): If joining, don't remove file.
-
- * update.c (join_file): If server and file is unmodified, check it
- out before joining. After joining, call server_updated. New
- argument repository.
-
- * server.c, server.h (server_copy_file): New function.
- * update.c (update_file_proc, join_file): Call it.
- * client.c (copy_file, handle_copy_file): New functions.
- * client.c (responses): Add "Copy-file".
-
- * client.c, client.h: Make toplevel_wd, failed_patches and
- failed_patches_count extern.
- * client.c (client_update): Move guts of function from here...
- * update.c (update): ...to here.
-
- * client.c, checkout.c: Likewise for checkout.
-
- * client.c (is_cvsroot_level): New function.
- (handle_set_sticky, handle_clear_sticky,
- handle_clear_static_directory): Call it, instead of checking
- short_pathname for a slash.
-
- * client.c, client.h (client_process_import_file,
- client_import_done): New functions.
- * import.c (import, import_descend): Use them.
- * import.c (import_descend): If server, don't mention ignored CVS
- directories.
- * import.c (import_descend_dir): If client, don't print warm
- fuzzies, or make directories in repository. If server, print warm
- fuzzies to stdout not stderr.
- * client.c (send_modified): New function, broken out from
- send_fileproc.
- (send_fileproc): Call it.
-
- * client.c (handle_clear_sticky, handle_set_sticky,
- handle_clear_static_directory, handle_set_static_directory): If
- command is export, just return.
- (call_in_directory, update_entries): If command is export, don't
- create CVS directories, CVS/Entries files, etc.
- * update.c (update_filesdone_proc): Don't remove CVS directories if
- client_active.
-
- * client.c (send_a_repository): Instead of insisting that
- repository end with update_dir, just strip as many pathname
- components from the end as there are in update_dir.
-
- * Makefile.in (remotecheck): New target, pass -r to sanity.sh.
- * sanity.sh: Accept -r argument which means to test remote cvs.
-
- * tag.c (tag), rtag.c (rtag), patch.c (patch), import.c (import),
- admin.c (admin), release.c (release): If client_active, connect to
- the server and send the right requests.
- * main.c (cmds): Add these commands.
- (main): Remove code which would strip hostname off cvsroot and try
- the command locally. There are no longer any commands which are
- not supported.
- * client.c, client.h (client_rdiff, client_tag, client_rtag,
- client_import, client_admin, client_export, client_history,
- client_release): New functions.
- * server.c (serve_rdiff, serve_tag, serve_rtag, serve_import,
- serve_admin, serve_export, serve_history, serve_release): New
- functions.
- (requests): List them.
- * server.c: Declare cvs commands (add, admin, etc.).
- * cvs.h, server.h: Don't declare any of them here.
- * main.c: Restore declarations of cvs commands which were
- previously removed.
-
- * cvs.h: New define DEATH_STATE, commented out for now.
- * rcs.c (RCS_parsercsfile_i), commit.c (remove_file, checkaddfile)
- [DEATH_STATE]: Use RCS state to record a dead file.
-
-Mon Oct 3 09:44:54 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
-
- * status.c (status_fileproc): Now that ts_rcs is just one time,
- don't try to print the second time from it. (Same as raeburn 20
- Aug change, it accidentally got lost in 1.4 Alpha-1 merge).
-
- * cvs.h (CVSDEA): Added (but commented out for now).
- * rcs.c (RCS_parsercsfile_i) [CVSDEA]: Also look in CVSDEA to see if
- something is dead.
- * commit.c (ci_new_rev, mark_file) [CVSDEA]: New functions.
- (remove_file, checkaddfile) [CVSDEA]: Use them instead of ci -K.
- * find_names.c (find_dirs) [CVSDEA]: Don't match CVSDEA directories.
- * update.c (checkout_file): Check RCS_isdead rather than relying
- on co to not create the file.
-
- * sanity.sh: Direct output to logfile, not /dev/null.
-
- * subr.c (run_exec): Print error message if we are unable to exec.
-
- * commit.c (remove_file): Call Scratch_Entry when removing tag
- from file. The DEATH_SUPPORT ifdef was erroneous.
-
-Sun Oct 2 20:33:27 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
-
- * commit.c (checkaddfile): Instead of calling isdir before
- attempting to create the directory, just ignore EEXIST errors from
- mkdir. (This removes some DEATH_SUPPORT ifdefs which actually had
- nothing to do with death support).
-
-Thu Sep 29 09:23:57 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
-
- * diff.c (diff): Search attic too if we have a second tag/date.
- (diff_fileproc): If we have a second tag/date, don't do all the
- checking regarding the user file.
-
-Mon Sep 26 12:02:15 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
-
- * checkin.c (Checkin): Check for error from unlink_file.
-
-Mon Sep 26 08:51:10 1994 Anthony J. Lill (ajlill@ajlc.waterloo.on.ca)
-
- * rcs.c (getrcskey): Allocate space for terminating '\0' if
- necessary.
-
-Sat Sep 24 09:07:37 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
-
- * commit.c (commit_fileproc): Set got_message = 1 when calling
- do_editor (accidentally omitted from last change).
-
-Fri Sep 23 11:59:25 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
-
- Revert buggy parts of Rich's change of 1 Nov 1993 (keeping the
- dynamic buffer allocation, which was the point of that change).
- * logmsg.c (do_editor): Reinstate message arg, but make it char
- **messagep instead of char *message. Change occurances of message
- to *messagep. Char return type from char * back to void.
- * cvs.h: Change do_editor declaration.
- * commit.c: Reinstate got_message variable
- (commit_filesdoneproc, commit_fileproc, commit_direntproc): Use it.
- * import.c (import), commit.c (commit_fileproc,
- commit_direntproc): Pass &message to do_editor; don't expect it to
- return a value.
- * client.c (client_commit): Likewise.
- * import.c (import): Deal with it if message is NULL.
-
-Wed Sep 21 09:43:25 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
-
- * server.c (server_updated): If the file doesn't exist, skip it.
-
- * diff.c, client.h, client.c: Rename diff_client_senddate to
- client_senddate and move from diff.c to client.c.
- * client.c (client_update, client_checkout): Use it.
-
-Sat Sep 17 08:36:58 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
-
- * checkout.c (checkout_proc): Don't pass NULL to Register for
- version. (should fix "cvs co -r <nonexistent-tag> <file>"
- coredump on Solaris).
-
-Fri Sep 16 08:38:02 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
-
- * diff.c (diff_fileproc): Set top_rev from vn_user, not vn_rcs.
- Rename it to user_file_rev because it need not be the head of any
- branch.
- (diff_file_nodiff): After checking user_file_rev, if we have both
- use_rev1 and use_rev2, compare them instead of going on to code
- which assumes use_rev2 == NULL.
-
-Thu Sep 15 08:20:23 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
-
- * status.c (status): Return a value in client_active case.
-
-Thu Sep 15 15:02:12 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
-
- * server.c (serve_modified): Create the file even if the size is
- zero.
-
-Thu Sep 15 08:20:23 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
-
- * lock.c (readers_exist): Clear errno each time around the loop,
- not just the first time.
-
- * client.c (start_server): Don't send Global_option -q twice.
-
- * no_diff.c (No_Difference): Check for error from unlink.
-
- * no_diff.c, cvs.h (No_Difference): New args repository,
- update_dir. Call server_update_entries if needed. Use update_dir
- in error message.
- * classify.c (Classify_File): Pass new args to No_Difference.
-
- * server.c (server_update_entries, server_checked_in,
- server_updated): Don't do anything if noexec.
-
- * client.c (send_fileproc): Rather than guessing how big the gzip
- output may be, just realloc the buffer as needed.
-
-Tue Sep 13 13:22:03 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
-
- * lock.c: Check for errors from unlink, readdir, and closedir.
-
- * classify.c (Classify_File): Pass repository and update_dir to
- sticky_ck.
- (sticky_ck): New args repository and update_dir.
- * server.c, server.h (server_update_entries): New function.
- * classify.c (sticky_ck): Call it.
- * client.c: New response "New-entry".
- * client.c (send_fileproc): Send tag/date from vers->entdata, not
- from vers itself.
-
-Mon Sep 12 07:07:05 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
-
- * server.c: Clean up formatting ("= (errno)" -> "= errno").
-
- * cvs.h: Declare strerror.
-
- * client.c: Add code to deal with Set-sticky and Clear-sticky
- responses, and Sticky request.
- * server.c: Add code to deal with Sticky request.
- * server.c, server.h (server_set_sticky): New function.
- * create_adm.c (Create_Admin), update.c (update, update_dirent_proc),
- commit.c (commit_dirleaveproc): Call it.
- * client.c, client.h (send_files): Add parameter aflag.
- * add.c (add), diff.c (diff), log.c (cvslog), remove.c (cvsremove),
- status.c (status),
- client.c (client_commit, client_update, client_checkout): Pass it.
- * client.c (client_update): Add -A flag.
-
-Fri Sep 9 07:05:35 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
-
- * entries.c (WriteTag): Check for error from unlink_file.
-
- * server.c (server_updated): Initialize size to 0. Previously if
- the file was zero length, the variable size got used without being
- set.
-
-Thu Sep 8 14:23:05 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
-
- * server.c (serve_repository): Check for error from fopen on
- CVSADM_ENT.
-
- * update.c (update, update_dirent_proc): Check for errors when
- removing Entries.Static.
-
- * client.c: Add code to deal with Set-static-directory and
- Clear-static-directory responses, and Static-directory request.
- * server.c, server.h (server_clear_entstat, server_set_entstat):
- New functions.
- * update.c, checkout.c, modules.c: Call them.
- * server.c: Add code to deal with Static-directory request.
-
- * server.c, client.c: Use strchr and strrchr instead of index and
- rindex.
-
- * server.c (serve_unchanged, serve_lost): Change comments which
- referred to changing timestamp; we don't always change the
- timestamp in those cases anymore.
-
-Wed Sep 7 10:58:12 1994 J.T. Conklin (jtc@rtl.cygnus.com)
-
- * cvsrc.c (read_cvsrc): Don't call getenv() three times when one
- time will do.
-
- * subr.c (xmalloc, xrealloc): Change type of bytes argument from
- int to size_t and remove the test that checks if it is less than
- zero.
- * cvs.h (xmalloc, xrealloc): Update prototype.
-
-Thu Sep 1 12:22:20 1994 Jim Kingdon (kingdon@cygnus.com)
-
- * update.c (merge_file, join_file): Pass -E to rcsmerge.
- (merge_file): If rcsmerge doesn't change the file, say so.
-
- * recurse.c, cvs.h (start_recursion): New argument wd_is_repos.
- * recurse.c (start_recursion): Use it instead of checking whether
- command_name is rtag to find out if we are cd'd to the repository.
- * client.c, update.c, commit.c, status.c, diff.c, log.c, admin.c,
- remove.c, tag.c: Pass 0 for wd_is_repos.
- * rtag.c, patch.c: Pass 1 for wd_is_repos.
-
- * classify.c, cvs.h (Classify_File): New argument pipeout.
- * classify.c (Classify_File): If pipeout, don't complain if the
- file is already there.
- * update.c, commit.c, status.c: Change callers.
-
- * mkmodules.c (main): Don't print "reminders" if commitinfo,
- loginfo, rcsinfo, or editinfo files are missing.
-
-Mon Aug 22 23:22:59 1994 Ken Raeburn (raeburn@kr-pc.cygnus.com)
-
- * server.c (strerror): Static definition replaced by extern
- declaration.
-
-Sun Aug 21 07:16:27 1994 Ken Raeburn (raeburn@kr-pc.cygnus.com)
-
- * client.c (update_entries): Run "patch" with input from
- /dev/null, so if it's the wrong version, it fails quickly rather
- than waiting for EOF from terminal before failing.
-
-Sat Aug 20 04:16:33 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
-
- * server.c (serve_unchanged): Instead of creating a file with a
- zero timestamp, rewrite the entries file to have "=" in the
- timestamp field.
- * vers_ts.c (mark_lost, mark_unchanged): New macros.
- (time_stamp_server): Use them, for clarity. Interpret "="
- timestamp as an unchanged file. A zero-timestamp file should
- never be encountered now in use_unchanged mode.
-
- * client.c (start_server): If CVS_CLIENT_PORT indicates a
- non-positive port number, skip straight to rsh connection.
-
- * status.c (status_fileproc): Fix ts_rcs reference when printing
- version info, to correspond to new Entries file format. Don't
- print it at all if server_active, because it won't have any useful
- data.
-
-Thu Aug 18 14:38:21 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
-
- * cvs.h (status): Declare.
- * client.c (client_status): New function.
-
- * client.h (client_status): Declare.
- * main.c (cmds): Include it.
- * server.c (serve_status): New function.
- (requests): Add it.
- * status.c (status): Do the remote thing if client_active.
-
- * client.c (supported_request): New function.
- (start_server): Use it.
-
- * server.c (receive_partial_file): New function, broken out from
- serve_modified. Operate with fixed-size local buffer, instead of
- growing stack frame by entire file size.
- (receive_file): New function, broken out from serve_modified.
- (serve_modified): Call it.
- (server): Print out name of unrecognized request.
-
- More generic stream-filtering support:
- * client.c (close_on_exec, filter_stream_through_program): New
- functions.
- (server_fd): New variable.
- (get_responses_and_close): Direct non-rsh connection is now
- indicated by server_fd being non-negative. File descriptors for
- to_server and from_server may now be different in case "tee"
- filtering is being done. Wait for rsh_pid specifically.
- (start_server): Use filter_stream_through_program for "tee"
- filter, and enable it for direct Kerberos-authenticated
- connections. Use dup to create new file descriptors for server
- connection if logging is enabled.
- (start_rsh_server): Disable code that deals with logging.
-
- Per-file compression support:
- * cvs.h (gzip_level): Declare.
- * main.c (usg): Describe new -z argument.
- (main): Recognize it and set gzip_level.
- * client.c (filter_through_gzip, filter_through_gunzip): New
- functions to handle compression.
- (update_entries): If size starts with "z", uncompress
- (start_server): If gzip_level is non-zero and server supports it,
- issue gzip-file-contents request.
- (send_fileproc): Optionally compress file contents. Use a
- slightly larger buffer, anticipating the worst case.
- * server.c (gzip_level): Define here.
- (receive_file): Uncompress file contents if needed.
- (serve_modified): Recognize "z" in file size and pass receive_file
- appropriate flag.
- (buf_read_file_to_eof, buf_chain_length): New functions.
- (server_updated): Call them when sending a compressed file.
- (serve_gzip_contents): New function; set gzip_level.
- (requests): Added gzip-file-contents request.
-
-Wed Aug 17 09:37:44 1994 J.T. Conklin (jtc@cygnus.com)
-
- * find_names.c (find_dirs): Use 4.4BSD filesystem feature (it
- contains the file type in the dirent structure) to avoid
- stat'ing each file.
-
- * commit.c (remove_file,checkaddfile): Change type of umask
- variables from int to mode_t.
- * subr.c (): Likewise.
-
-Tue Aug 16 19:56:34 1994 Mark Eichin (eichin@cygnus.com)
-
- * diff.c (diff_fileproc): Don't use diff_rev* because they're
- invariant across calls -- add new variable top_rev.
- (diff_file_nodiff): After checking possible use_rev* values, if
- top_rev is set drop it in as well (if we don't already have two
- versions) and then clear it for next time around.
-
-Wed Aug 10 20:50:47 1994 Mark Eichin (eichin@cygnus.com)
-
- * diff.c (diff_fileproc): if ts_user and ts_rcs match, then the
- file is at the top of the tree -- so we might not even have a
- copy. Put the revision into diff_rev1 or diff_rev2.
-
-Wed Aug 10 14:55:38 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
-
- * server.c (do_cvs_command): Use waitpid.
-
- * subr.c (run_exec): Always use waitpid.
-
- * Makefile.in (CC, LIBS): Define here, in case "make" is run in
- this directory instead of top level.
-
-Wed Aug 10 13:57:06 1994 Mark Eichin (eichin@cygnus.com)
-
- * client.c (krb_get_err_text): use HAVE_KRB_GET_ERR_TEXT to
- determine if we need to use the array or the function.
- * main.c: ditto.
-
-Tue Aug 9 16:43:30 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
-
- * entries.c (ParseEntries): If timestamp is in old format, rebuild
- it in the new format. Fudge an unmatchable entry that won't
- trigger this code next time around, if the file is modified.
-
- * vers_ts.c (time_stamp): Only put st_mtime field into timestamp,
- and use GMT time for it. With st_ctime or in local time, copying
- trees between machines in different time zones makes all the files
- look modified.
- (time_stamp_server): Likewise.
-
-Tue Aug 9 19:40:51 1994 Mark Eichin (eichin@cygnus.com)
-
- * main.c (main): use krb_get_err_text function instead of
- krb_err_txt array.
-
-Thu Aug 4 15:37:50 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
-
- * main.c (main): When invoked as kserver, set LOGNAME and USER
- environment variables to the remote user name.
-
-Thu Aug 4 07:44:37 1994 Mark Eichin (eichin@cygnus.com)
-
- * client.c: (handle_valid_requests): if we get an option that has
- rq_enableme set, then send that option. If it is UseUnchanged, set
- use_unchanged so that the rest of the client knows about
- it. (Could become a more general method for dealing with protocol
- upgrades.)
- (send_fileproc): if use_unchanged didn't get set, send an
- old-style "Lost" request, otherwise send an "Unchanged" request.
- * server.c (serve_unchanged): new function, same as serve_lost,
- but used in the opposite case.
- (requests): add new UseUnchanged and Unchanged requests, and make
- "Lost" optional (there isn't a good way to interlock these.)
- * server.h (request.status): rq_enableme, new value for detecting
- compatibility changes.
- * vers_ts.c (time_stamp_server): swap meaning of zero timestamp if
- use_unchanged is set.
-
-Tue Jul 26 10:19:30 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
-
- * sanity.sh: Separate CVSROOT_FILENAME, which must be the filename
- of the root, from CVSROOT, which can include a hostname for
- testing remote CVS. (but the tests aren't yet prepared to deal
- with the bugs in remote CVS).
-
- * import.c (update_rcs_file): Change temporary file name in TMPDIR
- from FILE_HOLDER to cvs-imp<process-id>.
-
- * sanity.sh: Add ">/dev/null" and "2>/dev/null" many places to
- suppress spurious output. Comment out tests which don't work (cvs
- add on top-level directory, cvs diff when non-committed adds or
- removes have been made, cvs release, test 53 (already commented as
- broken), retagging without deleting old tag, test 63). Now 'make
- check' runs without any failures.
-
-Fri Jul 15 12:58:29 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
-
- * Makefile.in (install): Do not depend upon installdirs.
-
-Thu Jul 14 15:49:42 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
-
- * client.c, server.c: Don't try to handle alloca here; it's
- handled by cvs.h.
-
-Tue Jul 12 13:32:40 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
-
- * client.c (update_entries): Reset stored_checksum_valid if we
- quit early because of a patch failure.
-
-Fri Jul 8 11:13:05 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
-
- * client.c (responses): Mark "Remove-entry" as optional.
-
-Thu Jul 7 14:07:58 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
-
- * server.c (server_updated): Add new checksum argument. If it is
- not NULL, and the client supports the "Checksum" response, send
- it.
- * server.h (server_updated): Update prototype.
- * update.c: Include md5.h.
- (update_file_proc): Pass new arguments to patch_file and
- server_updated.
- (patch_file): Add new checksum argument. Set it to the MD5
- checksum of the version of the file being checked out.
- (merge_file): Pass new argument to server_updated.
- * client.c: Include md5.h.
- (stored_checksum_valid, stored_checksum): New static variables.
- (handle_checksum): New static function.
- (update_entries): If a checksum was received, check it against the
- MD5 checksum of the final file.
- (responses): Add "Checksum".
- (start_server): Clear stored_checksum_valid.
- * commit.c (commit_fileproc): Pass new argument to server_updated.
-
- * client.h (struct response): Move definition in from client.c,
- add status field.
- (responses): Declare.
- * client.c (struct response): Remove definition; moved to
- client.h.
- (responses): Make non-static. Initialize status field.
- * server.c (serve_valid_responses): Check and record valid
- responses, just as in handle_valid_requests in client.c.
-
- * diff.c (diff_client_senddate): New function.
- (diff): Use it to send -D arguments to server.
-
-Wed Jul 6 12:52:37 1994 J.T. Conklin (jtc@phishhead.cygnus.com)
-
- * rcs.c (RCS_parsercsfile_i): New function, parse RCS file
- referenced by file ptr argument.
- (RCS_parsercsfile): Open file and pass its file ptr to above function.
- (RCS_parse): Likewise.
-
-Wed Jul 6 01:25:38 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
-
- * client.c (update_entries): Print message indicating that an
- unpatchable file will be refetched.
- (client_update): Print message when refetching unpatchable files.
-
-Fri Jul 1 07:16:29 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
-
- * client.c (send_dirent_proc): Don't call send_a_repository if
- repository is "".
-
-Fri Jul 1 13:58:11 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
-
- * client.c (last_dirname, last_repos): Move out of function.
- (failed_patches, failed_patches_count): New static variables.
- (update_entries): If patch program fails, save short_pathname in
- failed_patches array, only exit program if retcode is -1, and
- return out of the function rather than update the Entries line.
- (start_server): Clear toplevel_repos, last_dirname, last_repos.
- (client_update): If failed_patches is not NULL after doing first
- update, do another update, but remove all the failed files first.
-
-Thu Jun 30 09:08:57 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
-
- * server.c (requests): Add request "Global_option".
- (serve_global_option): New function, to handle it.
- * client.c (start_server): Deal with global options. Check for
- errors from fprintf.
-
- * client.c (send_fileproc): Split out code which sends repository
- into new function send_a_repository. Also, deal with update_dir
- being ".".
- (send_dirent_proc): Call send_a_repository.
- * add.c (add): If client_active, do special processing for
- directories.
- (add_directory): If server_active, don't try to create CVSADM
- directory.
-
-Thu Jun 30 11:58:52 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
-
- * client.c (update_entries): If patch succeeds, remove the backup
- file.
- * server.c (server_updated): Add new argument file_info. If it is
- not NULL, use it rather than sb to get the file mode.
- * server.h (server_updated): Update prototype for new argument.
- * update.c (update_file_proc): Pass new arguments to patch_file
- and server_updated.
- (patch_file): Add new argument file_info. Don't use -p to check
- out new version, check it out into file and rename that to file2.
- If result is not readable, assume file is dead and set docheckout.
- Call xchmod on file2. Close the patch file after checking for a
- binary diff. Set file_info to the results of stat on file2.
- (merge_file): Pass new argument to server_updated.
- * commit.c (commit_fileproc): Pass new argument to server_updated.
-
-Wed Jun 29 13:00:41 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
-
- * client.c (krb_realmofhost): Declare, since it's not the current
- <krb.h>.
- (start_server): Save the name returned by gethostbyname. Call
- krb_realmofhost to get the realm. Pass the resulting realm to
- krb_sendauth. Pass the saved real name to krb_sendauth, rather
- than server_host.
-
- * update.c (update_file_proc): Pass &docheckout to patch_file. If
- it is set to 1, fall through to T_CHECKOUT case.
- (patch_file): Add docheckout argument. Set it to 1 if we can't
- make a patch. Check out the files and run diff rather than
- rcsdiff. If either file does not end in a newline, we can't make
- a patch. If the patch starts with the string "Binary", assume
- one or the other is a binary file, and that we can't make a patch.
-
-Tue Jun 28 11:57:29 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
-
- * client.c (update_entries): If the patch file is empty, don't run
- patch program; avoids error message.
-
- * classify.c (Classify_File): Return T_CHECKOUT, not T_PATCH, if
- the file is in the Attic.
-
- * cvs.h (enum classify_type): Add T_PATCH.
- * config.h (PATCH_PROGRAM): Define.
- * classify.c (Classify_File): If user file exists and is not
- modified, and using the same -k options, return T_PATCH instead of
- T_CHECKOUT.
- * update.c (patches): New static variable.
- (update): Add u to gnu_getopt argument. Handle it.
- (update_file_proc): Handle T_PATCH.
- (patch_file): New static function.
- * server.h (enum server_updated_arg4): Add SERVER_PATCHED.
- * server.c (server_updated): Handle SERVER_PATCHED by sending
- "Patched" command.
- (serve_ignore): New static function.
- (requests): Add "update-patches".
- (client_update): If the server supports "update-patches", send -u.
- * client.c (struct update_entries_data): Change contents field
- from int to an unnamed enum.
- (update_entries): Correponding change. If contents is
- UPDATE_ENTRIES_PATCH, pass the input to the patch program.
- (handle_checked_in): Initialize contents to enum value, not int.
- (handle_updated, handle_merged): Likewise.
- (handle_patched): New static function.
- (responses): Add "Patched".
- * commit.c (check_fileproc): Handle T_PATCH.
- * status.c (status_fileproc): Likewise.
-
- * client.c (start_server): If CVS_CLIENT_PORT is set in the
- environment, connect to that port, rather than looking up "cvs" in
- /etc/services. For debugging.
-
-Tue Jun 21 12:48:16 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
-
- * update.c (joining): Return result of comparing pointer with
- NULL, not result of casting (truncating, on Alpha) pointer to int.
-
- * main.c (main) [HAVE_KERBEROS]: Impose a umask if starting as
- Kerberos server, so temp directories won't be world-writeable.
-
- * update.c (update_filesdone_proc) [CVSADM_ROOT]: If environment
- variable CVS_IGNORE_REMOTE_ROOT is set and repository is remote,
- don't create CVS/Root file.
- * main.c (main): If env var CVS_IGNORE_REMOTE_ROOT is set, don't
- check CVS/Root.
-
-Fri Jun 10 18:48:32 1994 Mark Eichin (eichin@cygnus.com)
-
- * server.c (O_NDELAY): use POSIX O_NONBLOCK by default, unless it
- isn't available (in which case substitute O_NDELAY.)
-
-Thu Jun 9 19:17:44 1994 Mark Eichin (eichin@cygnus.com)
-
- * server.c (server_cleanup): chdir out of server_temp_dir before
- deleting it (so that it works on non-BSD systems.) Code for choice
- of directory cloned from server().
-
-Fri May 27 18:16:01 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
-
- * client.c (update_entries): Add return type of void.
- (get_responses_and_close): If using Kerberos and from_server and
- to_server are using the same file descriptor, use shutdown, not
- fclose. Close from_server.
- (start_server): New function; most of old version renamed to
- start_rsh_server.
- (start_rsh_server): Mostly renamed from old start_server.
- (send_fileproc): Use %lu and cast sb.st_size in fprintf call.
- (send_files): Remove unused variables repos and i.
- (option_no_arg): Comment out; unused.
- * main.c (main): Initialize cvs_update_env to 0. If command is
- "kserver", authenticate and change command to "server". If
- command is "server", don't call Name_Root, don't check access to
- history file, and don't assume that CVSroot is not NULL.
- * server.c (my_memmove): Removed.
- (strerror): Change check from STRERROR_MISSING to HAVE_STRERROR.
- (serve_root): Likewise for putenv.
- (serve_modified): Initialize buf to NULL.
- (struct output_buffer, buf_try_send): Remove old buffering code.
- (struct buffer, struct buffer_data, BUFFER_DATA_SIZE,
- allocate_buffer_datas, get_buffer_data, buf_empty_p,
- buf_append_char, buf_append_data, buf_read_file, buf_input_data,
- buf_copy_lines): New buffering code.
- (buf_output, buf_output0, buf_send_output, set_nonblock,
- set_block, buf_send_counted, buf_copy_counted): Rewrite for new
- buffering code.
- (protocol, protocol_memory_error, outbuf_memory_error,
- do_cvs_command, server_updated): Rewrite for new buffering code.
- (input_memory_error): New function.
- (server): Put Rcsbin at start of PATH in environment.
- * Makefile.in: Add @includeopt@ to DEFS.
-
-Fri May 20 08:13:10 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
-
- * cvs.h, classify.c (Classify_File): New argument update_dir.
- Include it in user messages.
- * commit.c (check_fileproc), status.c (status_fileproc), update.c
- (update_file_proc): Pass update_dir to Classify_File.
- * commit.c (check_fileproc), update.c (checkout_file):
- Include update_dir in user messages.
- * commit.c (check_fileproc) update.c (update_file_proc): Re-word
- "unknown status" message.
-
- * server.c (server_checked_in): Deal with the case where
- scratched_file is set rather than entries_line.
-
- * entries.c (Register): Write file even if server_active.
- * add.c (add): Add comment about how we depend on above behavior.
-
-Tue May 17 08:16:42 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
-
- * mkmodules.c: Add dummy server_active and server_cleanup, to go
- with the dummy Lock_Cleanup already there.
-
- * server.c (server_cleanup): No longer static.
-
-Sat May 7 10:17:17 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
-
- Deal with add and remove:
- * commit.c (checkaddfile): If CVSEXT_OPT or CVSEXT_LOG file does
- not exist, just silently keep going.
- (remove_file): If server_active, remove file before creating
- temporary file with that name.
- * server.c (serve_remove, serve_add): New functions.
- (requests): Add them.
- * server.c (server_register): If options is NULL, it means there
- are no options.
- * server.c, server.h (server_scratch_entry_only): New function.
- New variable kill_scratched_file.
- (server_scratch, server_updated): Deal with kill_scratched_file.
- * commit.c (commit_fileproc): If server_active, call
- server_scratch_entry_only and server_updated.
- * add.c (add): Add client_active code.
- (add): If server_active, call server_checked_in for each file added.
- * remove.c (remove): Add client_active code.
- (remove_fileproc): If server_active, call server_checked_in.
- * main.c (cmds), client.c, client.h: New functions client_add and
- client_remove.
- * Move declarations of add, cvsremove, diff, and cvslog from
- main.c to cvs.h.
- * client.c (call_in_directory): Update comment regarding Root and
- Repository files.
- (send_fileproc): Only send Entries line if Version_TS really finds
- an entry. If it doesn't find one, send Modified.
- (update_entries): If version is empty or starts with 0 or -,
- create a dummy timestamp.
-
-Thu May 5 19:02:51 1994 Per Bothner (bothner@kalessin.cygnus.com)
-
- * recurse/c (start_recursion): If we're doing rtag, and thus
- have cd'd to the reporsitory, add ,v to a file name before stat'ing.
-
-Wed Apr 20 15:01:45 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
-
- * client.c (client_commit): Call ign_setup.
- (client_update, client_checkout): Likewise.
- * diff.c (diff): If client, call ign_setup.
- * log.c (cvslog): Likewise.
- * update.h (ignlist): Change definition to declaration to avoid
- depending upon common semantics (not required by ANSI C, and not
- the default on Irix 5).
- * update.c (ignlist): Define.
-
-Tue Apr 19 00:02:54 1994 John Gilmore (gnu@cygnus.com)
-
- Add support for remote `cvs log'; clean up `cvs diff' a bit.
-
- * client.c (send_arg): Make external.
- (send_option_string): New function.
- (client_diff_usage): Remove, unused.
- (client_diff): Just call diff, not do_diff.
- (client_log): Add.
- * client.h (client_log, send_arg, send_option_string): Declare.
- * cvs.h (cvslog): Declare.
- * diff.c (do_diff): Fold back into diff(), distinguish by checking
- client_active.
- (diff): Remove `-*' arg parsing crud; use send_option_string.
- * log.c (cvslog): If a client, start the server, pass options
- and files, and handle server responses.
- * main.c (cmds): Add client_log.
- (main): Remove obnoxious message every time CVS/Root is used.
- Now CVS will be quiet about it -- unless there is a conflict
- between $CVSROOT or -d value versus CVS/Root.
- * server.c (serve_log): Add.
- (requests): Add "log".
-
-Mon Apr 18 22:07:53 1994 John Gilmore (gnu@cygnus.com)
-
- Add support for remote `cvs diff'.
-
- * diff.c (diff): Break guts out into new fn do_diff.
- Add code to handle starting server, writing args,
- sending files, and retrieving responses.
- (includes): Use PARAMS for static function declarations.
- * client.c (to_server, from_server, rsh_pid,
- get_responses_and_close, start_server, send_files,
- option_with_arg): Make external.
- (send_file_names): New function.
- (client_diff): New function.
- * client.h (client_diff, to_server, from_server,
- rsh_pid, option_with_arg, get_responses_and_close, start_server,
- send_file_names, send_files): Declare.
- * cvs.h (diff): Declare.
- * main.c (cmds): Add client_diff to command table.
- * server.c (serve_diff): New function.
- (requests): Add serve_diff.
- (server): Bug fix: avoid free()ing incremented cmd pointer.
- * update.h (update_filesdone_proc): Declare with PARAMS.
-
-Sat Apr 16 04:20:09 1994 John Gilmore (gnu@cygnus.com)
-
- * root.c (Name_root): Fix tyop (CVSroot when root meant).
-
-Sat Apr 16 03:49:36 1994 John Gilmore (gnu@cygnus.com)
-
- Clean up remote `cvs update' to properly handle ignored
- files (and files that CVS can't identify), and to create
- CVS/Root entries on the client side, not the server side.
-
- * client.c (send_fileproc): Handle the ignore list.
- (send_dirent_proc): New function for handling ignores.
- (send_files): Use update_filesdone_proc and send_dirent_proc
- while recursing through the local filesystem.
- * update.h: New file.
- * update.c: Move a few things into update.h so that client.c
- can use them.
-
-Fri Mar 11 13:13:20 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
-
- * server.c: If O_NDELAY is not defined, but O_NONBLOCK is, define
- O_NDELAY to O_NONBLOCK.
-
-Wed Mar 9 21:08:30 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
-
- Fix some spurious remote CVS errors caused by the CVS/Root patches:
- * update.c (update_filesdone_proc): If server_active, don't try to
- create CVS/Root.
- * root.c (Name_Root): Make error messages which happen if root is
- not an absolute pathname or if it doesn't exist a bit clearer.
- Skip them if root contains a colon.
-
-Mon Nov 1 15:54:51 1993 K. Richard Pixley (rich@sendai.cygnus.com)
-
- * client.c (client_commit): dynamically allocate message.
-
-Tue Jun 1 17:03:05 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
-
- * server.h: remove alloca cruft
-
- * server.c: replace with better alloca cruft
-
-Mon May 24 11:25:11 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
-
- * entries.c (Scratch_Entry): Update our local Entries file even if
- server_active.
-
- * server.c (server_scratch, server_register): If both Register
- and Scratch_Entry happen, use whichever one happened later.
- If neither happen, silently continue.
-
- * client.c (client_checkout): Initialize tag and date (eichin and
- I independently discovered this bug at the same time).
-
-Wed May 19 10:11:51 1993 Mark Eichin (eichin@cygnus.com)
-
- * client.c (update_entries): handle short reads over the net
- (SVR4 fread is known to be broken, specifically for short
- reads off of streams.)
-
-Tue May 18 15:53:44 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
-
- * server.c (do_cvs_command): Fix fencepost error in setting
- num_to_check.
-
- * server.c (do_cvs_command): If terminated with a core dump, print
- message and set dont_delete_temp.
- (server_cleanup): If dont_delete_temp, don't delete it.
-
- * client.c (get_server_responses): Don't change cmd since we
- are going to "free (cmd)".
-
- * server.c: Rename memmove to my_memmove pending a real fix.
-
- * server.c (do_cvs_command): Set num_to_check to largest descriptor
- we try to use, rather than using (non-portable) getdtablesize.
-
-Wed May 12 15:31:40 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
-
- Add CVS client feature:
- * client.{c,h}: New files.
- * cvs.h: Include client.h.
- * main.c: If CVSROOT has a colon, use client commands instead.
- * vers_ts.c (Version_TS): If repository arg is NULL, don't worry
- about the repository.
- * logmsg.c (do_editor): If repository or changes is NULL, just don't
- use those features.
- * create_adm.c (Create_Admin), callers: Move the test for whether
- the repository exists from here to callers.
- * repos.c (Name_Repository): Don't test whether the repository exists
- if client_active set (might be better to move test to callers).
-
- Add CVS server feature:
- * server.{c,h}: New files.
- * cvs.h: Include server.h.
- * checkin.c (Checkin): Call server_checked_in.
- * update.c (update_file_proc, merge_files): Call server_updated.
- * entries.c (Register): Call server_register.
- (Scratch_Entry): Call server_scratch.
- * main.c: Add server to cmds.
- * vers_ts.c (Version_TS): If server_active, call new function
- time_stamp_server to set ts_user.
-
diff --git a/gnu/usr.bin/cvs/cvs/Makefile b/gnu/usr.bin/cvs/cvs/Makefile
deleted file mode 100644
index 5be0fbe3238c..000000000000
--- a/gnu/usr.bin/cvs/cvs/Makefile
+++ /dev/null
@@ -1,18 +0,0 @@
-PROG = cvs
-CFLAGS += -I${.CURDIR}/../lib \
- -DDIRENT -DSTDC_HEADERS -DPOSIX -DBROKEN_SIGISMEMBER \
- -DFTIME_MISSING -DHAVE_TIMEZONE -DUTIME_NULL_MISSING
-
-LDADD= -L${.CURDIR}/../lib/obj -lcvs
-
-SRCS = add.c admin.c checkin.c checkout.c classify.c commit.c \
-create_adm.c diff.c entries.c find_names.c history.c ignore.c \
-import.c lock.c log.c logmsg.c main.c rcs.c modules.c \
-no_diff.c parseinfo.c patch.c recurse.c release.c remove.c repos.c rtag.c \
-status.c tag.c update.c vers_ts.c version.c
-
-MAN1= cvs.0
-MAN5= cvs.0
-
-.include <bsd.prog.mk>
-.include "../../Makefile.inc"
diff --git a/gnu/usr.bin/cvs/cvs/NOTES b/gnu/usr.bin/cvs/cvs/NOTES
deleted file mode 100644
index 646ebdf85207..000000000000
--- a/gnu/usr.bin/cvs/cvs/NOTES
+++ /dev/null
@@ -1,60 +0,0 @@
-wishlist - Tue Nov 2 15:22:58 PST 1993
-
-* bcopy -> memcpy & friends.
- ** done 12/18/93
-
-* remove static buffers.
-* replace list & node cache with recursive obstacks, (xmalloc,
- getnode, getlist)
-* check all io functions for error return codes. also check all
- system calls.
-* error check mkdir.
-
----
-Old notes...
-
-* All sizing limits are gone. The rest of these items were incidental
- in that effort.
-
-* login name from history was duplicated. taught existing routine to
- cache and use that instead. Also add routines to cache uid, pid,
- etc.
-
-* ign strings were never freed. Now they are.
-
-* there was a printf("... %s ...", cp) vs *cp bug in history.c. Now
- fixed.
-
-* The environment variables TMPDIR, HOME, and LOGNAME were not
- honored. Now they are.
-
-* extra line inserted by do_editor() is gone. Then obviated. Editor
- is now called exactly once per checkin.
-
-* revised editor behaviour. Never use /dev/tty. If the editor
- session fails, we haven't yet done anything. Therefor the user can
- safely rerun cvs and we should just fail. Also use the editor for
- initial log messages on added files. Also omit the confirmation
- when adding directories. Adding directories will require an
- explicit "commit" step soon. Make it possible to prevent null login
- messages using #define REQUIRE_LOG_MESSAGES
-
-* prototypes for all callbacks.
-
-* all callbacks get ref pointers.
-
-* do_recursion/start_recursion now use recusion_frame's rather than a
- list of a lot of pointers and global variables.
-
-* corrected types on status_dirproc().
-
-* CONFIRM_DIRECTORY_ADDS
-
-* re_comp was innappropriate in a few places. I've eliminated it.
-
-* FORCE_MESSAGE_ON_ADD
-
-* So I built a regression test. Let's call it a sanity check to be
- less ambitious. It exposed that cvs is difficult to call from
- scripts.
-
diff --git a/gnu/usr.bin/cvs/cvs/README-rm-add b/gnu/usr.bin/cvs/cvs/README-rm-add
deleted file mode 100644
index 17c721fd958a..000000000000
--- a/gnu/usr.bin/cvs/cvs/README-rm-add
+++ /dev/null
@@ -1,48 +0,0 @@
-WHAT THE "DEATH SUPPORT" FEATURES DO:
-
-(this really should be in the main manual, but noone has gotten around
-to updating it).
-
-CVS with death support can record when a file is active, or alive, and
-when it is removed, or dead. With this facility you can record the
-history of a file, including the fact that at some point in its life
-the file was removed and then later added.
-
-First, the following now works as expected:
-
- touch foo
- cvs add foo ; cvs ci -m "added" foo
- rm foo
- cvs rm foo ; cvs ci -m "removed" foo
- touch foo
- cvs add foo ; cvs ci -m "resurrected" foo
-
-Second, files can now be added or removed in a branch and later merged
-into the trunk.
-
- cvs update -A
- touch a b c
- cvs add a b c ; cvs ci -m "added" a b c
- cvs tag -b branchtag
- cvs update -r branchtag
- touch d ; cvs add d
- rm a ; cvs rm a
- cvs ci -m "added d, removed a"
- cvs update -A
- cvs update -jbranchtag
-
-Added and removed files may also be merged between branches.
-
-Files removed in the trunk may be merged into branches.
-
-Files added on the trunk are a special case. They cannot be merged
-into a branch. Instead, simply branch the file by hand.
-
-I also extended the "cvs update -j" semantic slightly. Like before,
-if you use two -j options, the changes made between the first and the
-second will be merged into your working files. This has not changed.
-
-If you use only one -j option, it is used as the second -j option.
-The first is assumed to be the greatest common ancestor revision
-between the revision specified by the -j and the BASE revision of your
-working file.
diff --git a/gnu/usr.bin/cvs/cvs/add.c b/gnu/usr.bin/cvs/cvs/add.c
deleted file mode 100644
index f798a225cc9e..000000000000
--- a/gnu/usr.bin/cvs/cvs/add.c
+++ /dev/null
@@ -1,539 +0,0 @@
-/*
- * Copyright (c) 1992, Brian Berliner and Jeff Polk
- * Copyright (c) 1989-1992, Brian Berliner
- *
- * You may distribute under the terms of the GNU General Public License as
- * specified in the README file that comes with the CVS 1.4 kit.
- *
- * Add
- *
- * Adds a file or directory to the RCS source repository. For a file,
- * the entry is marked as "needing to be added" in the user's own CVS
- * directory, and really added to the repository when it is committed.
- * For a directory, it is added at the appropriate place in the source
- * repository and a CVS directory is generated within the directory.
- *
- * The -m option is currently the only supported option. Some may wish to
- * supply standard "rcs" options here, but I've found that this causes more
- * trouble than anything else.
- *
- * The user files or directories must already exist. For a directory, it must
- * not already have a CVS file in it.
- *
- * An "add" on a file that has been "remove"d but not committed will cause the
- * file to be resurrected.
- */
-
-#include "cvs.h"
-#include "save-cwd.h"
-
-#ifndef lint
-static const char rcsid[] = "$CVSid: @(#)add.c 1.55 94/10/22 $";
-USE(rcsid);
-#endif
-
-static int add_directory PROTO((char *repository, char *dir));
-static int build_entry PROTO((char *repository, char *user, char *options,
- char *message, List * entries, char *tag));
-
-static const char *const add_usage[] =
-{
- "Usage: %s %s [-k rcs-kflag] [-m message] files...\n",
- "\t-k\tUse \"rcs-kflag\" to add the file with the specified kflag.\n",
- "\t-m\tUse \"message\" for the creation log.\n",
- NULL
-};
-
-int
-add (argc, argv)
- int argc;
- char **argv;
-{
- char *message = NULL;
- char *user;
- int i;
- char *repository;
- int c;
- int err = 0;
- int added_files = 0;
- char *options = NULL;
- List *entries;
- Vers_TS *vers;
-
- if (argc == 1 || argc == -1)
- usage (add_usage);
-
- wrap_setup ();
-
- /* parse args */
- optind = 1;
- while ((c = getopt (argc, argv, "k:m:")) != -1)
- {
- switch (c)
- {
- case 'k':
- if (options)
- free (options);
- options = RCS_check_kflag (optarg);
- break;
-
- case 'm':
- message = xstrdup (optarg);
- break;
- case '?':
- default:
- usage (add_usage);
- break;
- }
- }
- argc -= optind;
- argv += optind;
-
- if (argc <= 0)
- usage (add_usage);
-
- /* find the repository associated with our current dir */
- repository = Name_Repository ((char *) NULL, (char *) NULL);
-
-#ifdef CLIENT_SUPPORT
- if (client_active)
- {
- int i;
- start_server ();
- ign_setup ();
- if (options) send_arg(options);
- option_with_arg ("-m", message);
- for (i = 0; i < argc; ++i)
- /* FIXME: Does this erroneously call Create_Admin in error
- conditions which are only detected once the server gets its
- hands on things? */
- if (isdir (argv[i]))
- {
- char *tag;
- char *date;
- char *rcsdir = xmalloc (strlen (repository)
- + strlen (argv[i]) + 10);
-
- /* before we do anything else, see if we have any
- per-directory tags */
- ParseTag (&tag, &date);
-
- sprintf (rcsdir, "%s/%s", repository, argv[i]);
-
- Create_Admin (argv[i], argv[i], rcsdir, tag, date);
-
- if (tag)
- free (tag);
- if (date)
- free (date);
- free (rcsdir);
- }
- send_files (argc, argv, 0, 0);
- if (fprintf (to_server, "add\n") < 0)
- error (1, errno, "writing to server");
- return get_responses_and_close ();
- }
-#endif
-
- entries = Entries_Open (0);
-
- /* walk the arg list adding files/dirs */
- for (i = 0; i < argc; i++)
- {
- int begin_err = err;
- int begin_added_files = added_files;
-
- user = argv[i];
- strip_trailing_slashes (user);
- if (strchr (user, '/') != NULL)
- {
- error (0, 0,
- "cannot add files with '/' in their name; %s not added", user);
- err++;
- continue;
- }
-
- vers = Version_TS (repository, options, (char *) NULL, (char *) NULL,
- user, 0, 0, entries, (List *) NULL);
- if (vers->vn_user == NULL)
- {
- /* No entry available, ts_rcs is invalid */
- if (vers->vn_rcs == NULL)
- {
- /* There is no RCS file either */
- if (vers->ts_user == NULL)
- {
- /* There is no user file either */
- error (0, 0, "nothing known about %s", user);
- err++;
- }
- else if (!isdir (user) || wrap_name_has (user, WRAP_TOCVS))
- {
- /*
- * See if a directory exists in the repository with
- * the same name. If so, blow this request off.
- */
- char dname[PATH_MAX];
- (void) sprintf (dname, "%s/%s", repository, user);
- if (isdir (dname))
- {
- error (0, 0,
- "cannot add file `%s' since the directory",
- user);
- error (0, 0, "`%s' already exists in the repository",
- dname);
- error (1, 0, "illegal filename overlap");
- }
-
- /* There is a user file, so build the entry for it */
- if (build_entry (repository, user, vers->options,
- message, entries, vers->tag) != 0)
- err++;
- else
- {
- added_files++;
- if (!quiet)
- {
-#ifdef DEATH_SUPPORT
- if (vers->tag)
- error (0, 0, "\
-scheduling %s `%s' for addition on branch `%s'",
- (wrap_name_has (user, WRAP_TOCVS)
- ? "wrapper"
- : "file"),
- user, vers->tag);
- else
-#endif /* DEATH_SUPPORT */
- error (0, 0, "scheduling %s `%s' for addition",
- (wrap_name_has (user, WRAP_TOCVS)
- ? "wrapper"
- : "file"),
- user);
- }
- }
- }
- }
-#ifdef DEATH_SUPPORT
- else if (RCS_isdead (vers->srcfile, vers->vn_rcs))
- {
- if (isdir (user) && !wrap_name_has (user, WRAP_TOCVS))
- {
- error (0, 0, "the directory `%s' cannot be added because a file of the", user);
- error (1, 0, "same name already exists in the repository.");
- }
- else
- {
- if (vers->tag)
- error (0, 0, "file `%s' will be added on branch `%s' from version %s",
- user, vers->tag, vers->vn_rcs);
- else
- error (0, 0, "version %s of `%s' will be resurrected",
- vers->vn_rcs, user);
- Register (entries, user, "0", vers->ts_user, NULL,
- vers->tag, NULL, NULL);
- ++added_files;
- }
- }
-#endif /* DEATH_SUPPORT */
- else
- {
- /*
- * There is an RCS file already, so somebody else must've
- * added it
- */
- error (0, 0, "%s added independently by second party", user);
- err++;
- }
- }
- else if (vers->vn_user[0] == '0' && vers->vn_user[1] == '\0')
- {
-
- /*
- * An entry for a new-born file, ts_rcs is dummy, but that is
- * inappropriate here
- */
- error (0, 0, "%s has already been entered", user);
- err++;
- }
- else if (vers->vn_user[0] == '-')
- {
- /* An entry for a removed file, ts_rcs is invalid */
- if (vers->ts_user == NULL)
- {
- /* There is no user file (as it should be) */
- if (vers->vn_rcs == NULL)
- {
-
- /*
- * There is no RCS file, so somebody else must've removed
- * it from under us
- */
- error (0, 0,
- "cannot resurrect %s; RCS file removed by second party", user);
- err++;
- }
- else
- {
-
- /*
- * There is an RCS file, so remove the "-" from the
- * version number and restore the file
- */
- char *tmp = xmalloc (strlen (user) + 50);
-
- (void) strcpy (tmp, vers->vn_user + 1);
- (void) strcpy (vers->vn_user, tmp);
- (void) sprintf (tmp, "Resurrected %s", user);
- Register (entries, user, vers->vn_user, tmp, vers->options,
- vers->tag, vers->date, vers->ts_conflict);
- free (tmp);
-
- /* XXX - bugs here; this really resurrect the head */
- /* Note that this depends on the Register above actually
- having written Entries, or else it won't really
- check the file out. */
- if (update (2, argv + i - 1) == 0)
- {
- error (0, 0, "%s, version %s, resurrected", user,
- vers->vn_user);
- }
- else
- {
- error (0, 0, "could not resurrect %s", user);
- err++;
- }
- }
- }
- else
- {
- /* The user file shouldn't be there */
- error (0, 0, "%s should be removed and is still there (or is back again)", user);
- err++;
- }
- }
- else
- {
- /* A normal entry, ts_rcs is valid, so it must already be there */
- error (0, 0, "%s already exists, with version number %s", user,
- vers->vn_user);
- err++;
- }
- freevers_ts (&vers);
-
- /* passed all the checks. Go ahead and add it if its a directory */
- if (begin_err == err
- && isdir (user)
- && !wrap_name_has (user, WRAP_TOCVS))
- {
- err += add_directory (repository, user);
- continue;
- }
-#ifdef SERVER_SUPPORT
- if (server_active && begin_added_files != added_files)
- server_checked_in (user, ".", repository);
-#endif
- }
- if (added_files)
- error (0, 0, "use 'cvs commit' to add %s permanently",
- (added_files == 1) ? "this file" : "these files");
-
- Entries_Close (entries);
-
- if (message)
- free (message);
-
- return (err);
-}
-
-/*
- * The specified user file is really a directory. So, let's make sure that
- * it is created in the RCS source repository, and that the user's directory
- * is updated to include a CVS directory.
- *
- * Returns 1 on failure, 0 on success.
- */
-static int
-add_directory (repository, dir)
- char *repository;
- char *dir;
-{
- char rcsdir[PATH_MAX];
- struct saved_cwd cwd;
- char message[PATH_MAX + 100];
- char *tag, *date;
-
- if (strchr (dir, '/') != NULL)
- {
- error (0, 0,
- "directory %s not added; must be a direct sub-directory", dir);
- return (1);
- }
- if (strcmp (dir, CVSADM) == 0)
- {
- error (0, 0, "cannot add a `%s' directory", CVSADM);
- return (1);
- }
-
- /* before we do anything else, see if we have any per-directory tags */
- ParseTag (&tag, &date);
-
- /* now, remember where we were, so we can get back */
- if (save_cwd (&cwd))
- return (1);
- if (chdir (dir) < 0)
- {
- error (0, errno, "cannot chdir to %s", dir);
- return (1);
- }
-#ifdef SERVER_SUPPORT
- if (!server_active && isfile (CVSADM))
-#else
- if (isfile (CVSADM))
-#endif
- {
- error (0, 0, "%s/%s already exists", dir, CVSADM);
- goto out;
- }
-
- (void) sprintf (rcsdir, "%s/%s", repository, dir);
- if (isfile (rcsdir) && !isdir (rcsdir))
- {
- error (0, 0, "%s is not a directory; %s not added", rcsdir, dir);
- goto out;
- }
-
- /* setup the log message */
- (void) sprintf (message, "Directory %s added to the repository\n", rcsdir);
- if (tag)
- {
- (void) strcat (message, "--> Using per-directory sticky tag `");
- (void) strcat (message, tag);
- (void) strcat (message, "'\n");
- }
- if (date)
- {
- (void) strcat (message, "--> Using per-directory sticky date `");
- (void) strcat (message, date);
- (void) strcat (message, "'\n");
- }
-
- if (!isdir (rcsdir))
- {
- mode_t omask;
- Node *p;
- List *ulist;
-
-#if 0
- char line[MAXLINELEN];
-
- (void) printf ("Add directory %s to the repository (y/n) [n] ? ",
- rcsdir);
- (void) fflush (stdout);
- clearerr (stdin);
- if (fgets (line, sizeof (line), stdin) == NULL ||
- (line[0] != 'y' && line[0] != 'Y'))
- {
- error (0, 0, "directory %s not added", rcsdir);
- goto out;
- }
-#endif
-
- omask = umask (cvsumask);
- if (CVS_MKDIR (rcsdir, 0777) < 0)
- {
- error (0, errno, "cannot mkdir %s", rcsdir);
- (void) umask (omask);
- goto out;
- }
- (void) umask (omask);
-
- /*
- * Set up an update list with a single title node for Update_Logfile
- */
- ulist = getlist ();
- p = getnode ();
- p->type = UPDATE;
- p->delproc = update_delproc;
- p->key = xstrdup ("- New directory");
- p->data = (char *) T_TITLE;
- (void) addnode (ulist, p);
- Update_Logfile (rcsdir, message, (char *) NULL, (FILE *) NULL, ulist);
- dellist (&ulist);
- }
-
-#ifdef SERVER_SUPPORT
- if (!server_active)
- Create_Admin (".", dir, rcsdir, tag, date);
-#else
- Create_Admin (".", dir, rcsdir, tag, date);
-#endif
- if (tag)
- free (tag);
- if (date)
- free (date);
-
- (void) printf ("%s", message);
-out:
- if (restore_cwd (&cwd, NULL))
- exit (1);
- free_cwd (&cwd);
- return (0);
-}
-
-/*
- * Builds an entry for a new file and sets up "CVS/file",[pt] by
- * interrogating the user. Returns non-zero on error.
- */
-static int
-build_entry (repository, user, options, message, entries, tag)
- char *repository;
- char *user;
- char *options;
- char *message;
- List *entries;
- char *tag;
-{
- char fname[PATH_MAX];
- char line[MAXLINELEN];
- FILE *fp;
-
-#ifndef DEATH_SUPPORT
- /* when using the rcs death support, this case is not a problem. */
- /*
- * There may be an old file with the same name in the Attic! This is,
- * perhaps, an awkward place to check for this, but other places are
- * equally awkward.
- */
- (void) sprintf (fname, "%s/%s/%s%s", repository, CVSATTIC, user, RCSEXT);
- if (isreadable (fname))
- {
- error (0, 0, "there is an old file %s already in %s/%s", user,
- repository, CVSATTIC);
- return (1);
- }
-#endif /* no DEATH_SUPPORT */
-
- if (noexec)
- return (0);
-
- /*
- * The requested log is read directly from the user and stored in the
- * file user,t. If the "message" argument is set, use it as the
- * initial creation log (which typically describes the file).
- */
- (void) sprintf (fname, "%s/%s%s", CVSADM, user, CVSEXT_LOG);
- fp = open_file (fname, "w+");
- if (message && fputs (message, fp) == EOF)
- error (1, errno, "cannot write to %s", fname);
- if (fclose(fp) == EOF)
- error(1, errno, "cannot close %s", fname);
-
- /*
- * Create the entry now, since this allows the user to interrupt us above
- * without needing to clean anything up (well, we could clean up the
- * ,t file, but who cares).
- */
- (void) sprintf (line, "Initial %s", user);
- Register (entries, user, "0", line, options, tag, (char *) 0, (char *) 0);
- return (0);
-}
diff --git a/gnu/usr.bin/cvs/cvs/admin.c b/gnu/usr.bin/cvs/cvs/admin.c
deleted file mode 100644
index f12e143dc512..000000000000
--- a/gnu/usr.bin/cvs/cvs/admin.c
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * Copyright (c) 1992, Brian Berliner and Jeff Polk
- * Copyright (c) 1989-1992, Brian Berliner
- *
- * You may distribute under the terms of the GNU General Public License as
- * specified in the README file that comes with the CVS 1.4 kit.
- *
- * Administration
- *
- * For now, this is basically a front end for rcs. All options are passed
- * directly on.
- */
-
-#include "cvs.h"
-#ifdef CVS_ADMIN_GROUP
-#include <grp.h>
-#endif
-
-#ifndef lint
-static const char rcsid[] = "$CVSid: @(#)admin.c 1.20 94/09/30 $";
-USE(rcsid);
-#endif
-
-static Dtype admin_dirproc PROTO((char *dir, char *repos, char *update_dir));
-static int admin_fileproc PROTO((char *file, char *update_dir,
- char *repository, List *entries,
- List *srcfiles));
-
-static const char *const admin_usage[] =
-{
- "Usage: %s %s rcs-options files...\n",
- NULL
-};
-
-static int ac;
-static char **av;
-
-int
-admin (argc, argv)
- int argc;
- char **argv;
-{
- int err;
-#ifdef CVS_ADMIN_GROUP
- struct group *grp;
-#endif
- if (argc <= 1)
- usage (admin_usage);
-
-#ifdef CVS_ADMIN_GROUP
- grp = getgrnam(CVS_ADMIN_GROUP);
- /* skip usage right check if group CVS_ADMIN_GROUP does not exist */
- if (grp != NULL)
- {
- char *me = getcaller();
- char **grnam = grp->gr_mem;
- int denied = 1;
-
- while (*grnam)
- {
- if (strcmp(*grnam, me) == 0)
- {
- denied = 0;
- break;
- }
- grnam++;
- }
-
- if (denied)
- error (1, 0, "usage is restricted to members of the group %s",
- CVS_ADMIN_GROUP);
- }
-#endif
-
- wrap_setup ();
-
- /* skip all optional arguments to see if we have any file names */
- for (ac = 1; ac < argc; ac++)
- if (argv[ac][0] != '-')
- break;
- argc -= ac;
- av = argv + 1;
- argv += ac;
- ac--;
- if (ac == 0 || argc == 0)
- usage (admin_usage);
-
-#ifdef CLIENT_SUPPORT
- if (client_active)
- {
- int i;
-
- /* We're the client side. Fire up the remote server. */
- start_server ();
-
- ign_setup ();
-
- for (i = 0; i <= ac; ++i) /* XXX send -ko too with i = 0 */
- send_arg (av[i]);
-
-#if 0
- /* FIXME: We shouldn't have to send current files, but I'm not sure
- whether it works. So send the files --
- it's slower but it works. */
- send_file_names (argc, argv);
-#else
- send_files (argc, argv, 0, 0);
-#endif
- if (fprintf (to_server, "admin\n") < 0)
- error (1, errno, "writing to server");
- return get_responses_and_close ();
- }
-#endif /* CLIENT_SUPPORT */
-
- /* start the recursion processor */
- err = start_recursion (admin_fileproc, (FILESDONEPROC) NULL, admin_dirproc,
- (DIRLEAVEPROC) NULL, argc, argv, 0,
- W_LOCAL, 0, 1, (char *) NULL, 1, 0);
- return (err);
-}
-
-/*
- * Called to run "rcs" on a particular file.
- */
-/* ARGSUSED */
-static int
-admin_fileproc (file, update_dir, repository, entries, srcfiles)
- char *file;
- char *update_dir;
- char *repository;
- List *entries;
- List *srcfiles;
-{
- Vers_TS *vers;
- char *version;
- char **argv;
- int argc;
- int retcode = 0;
-
- vers = Version_TS (repository, (char *) NULL, (char *) NULL, (char *) NULL,
- file, 0, 0, entries, srcfiles);
-
- version = vers->vn_user;
- if (version == NULL)
- return (0);
- else if (strcmp (version, "0") == 0)
- {
- error (0, 0, "cannot admin newly added file `%s'", file);
- return (0);
- }
-
- run_setup ("%s%s", Rcsbin, RCS);
- for (argc = ac, argv = av; argc; argc--, argv++)
- run_arg (*argv);
- run_arg (vers->srcfile->path);
- if ((retcode = run_exec (RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL)) != 0)
- {
- if (!quiet)
- error (0, retcode == -1 ? errno : 0,
- "%s failed for `%s'", RCS, file);
- return (1);
- }
- return (0);
-}
-
-/*
- * Print a warm fuzzy message
- */
-/* ARGSUSED */
-static Dtype
-admin_dirproc (dir, repos, update_dir)
- char *dir;
- char *repos;
- char *update_dir;
-{
- if (!quiet)
- error (0, 0, "Administrating %s", update_dir);
- return (R_PROCESS);
-}
diff --git a/gnu/usr.bin/cvs/cvs/checkin.c b/gnu/usr.bin/cvs/cvs/checkin.c
deleted file mode 100644
index ef3b81a7fe3e..000000000000
--- a/gnu/usr.bin/cvs/cvs/checkin.c
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- * Copyright (c) 1992, Brian Berliner and Jeff Polk
- * Copyright (c) 1989-1992, Brian Berliner
- *
- * You may distribute under the terms of the GNU General Public License as
- * specified in the README file that comes with the CVS 1.4 kit.
- *
- * Check In
- *
- * Does a very careful checkin of the file "user", and tries not to spoil its
- * modification time (to avoid needless recompilations). When RCS ID keywords
- * get expanded on checkout, however, the modification time is updated and
- * there is no good way to get around this.
- *
- * Returns non-zero on error.
- */
-
-#include "cvs.h"
-
-#ifndef lint
-static const char rcsid[] = "$CVSid: @(#)checkin.c 1.48 94/10/07 $";
-USE(rcsid);
-#endif
-
-int
-Checkin (type, file, update_dir, repository,
- rcs, rev, tag, options, message, entries)
- int type;
- char *file;
- char *update_dir;
- char *repository;
- char *rcs;
- char *rev;
- char *tag;
- char *options;
- char *message;
- List *entries;
-{
- char fname[PATH_MAX];
- Vers_TS *vers;
- int set_time;
- char *fullname;
-
- char *tocvsPath = NULL;
-
- fullname = xmalloc (strlen (update_dir) + strlen (file) + 10);
- if (update_dir[0] == '\0')
- strcpy (fullname, file);
- else
- sprintf (fullname, "%s/%s", update_dir, file);
-
- (void) printf ("Checking in %s;\n", fullname);
- (void) sprintf (fname, "%s/%s%s", CVSADM, CVSPREFIX, file);
-
- /*
- * Move the user file to a backup file, so as to preserve its
- * modification times, then place a copy back in the original file name
- * for the checkin and checkout.
- */
-
- tocvsPath = wrap_tocvs_process_file (fullname);
-
- if (!noexec)
- {
- if (tocvsPath)
- {
- copy_file (tocvsPath, fname);
- if (unlink_file_dir (file) < 0)
- if (! existence_error (errno))
- error (1, errno, "cannot remove %s", file);
- copy_file (tocvsPath, file);
- }
- else
- {
- copy_file (file, fname);
- }
- }
-
- run_setup ("%s%s -f %s%s", Rcsbin, RCS_CI,
- rev ? "-r" : "", rev ? rev : "");
- run_args ("-m%s", make_message_rcslegal (message));
- run_arg (rcs);
-
- switch (run_exec (RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL))
- {
- case 0: /* everything normal */
-
- /*
- * The checkin succeeded, so now check the new file back out and
- * see if it matches exactly with the one we checked in. If it
- * does, just move the original user file back, thus preserving
- * the modes; otherwise, we have no recourse but to leave the
- * newly checkout file as the user file and remove the old
- * original user file.
- */
-
- if (strcmp (options, "-V4") == 0) /* upgrade to V5 now */
- options[0] = '\0';
- run_setup ("%s%s -q %s %s%s", Rcsbin, RCS_CO, options,
- rev ? "-r" : "", rev ? rev : "");
- run_arg (rcs);
- (void) run_exec (RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL);
- xchmod (file, 1);
- if (xcmp (file, fname) == 0)
- {
- rename_file (fname, file);
- /* the time was correct, so leave it alone */
- set_time = 0;
- }
- else
- {
- if (unlink_file (fname) < 0)
- error (0, errno, "cannot remove %s", fname);
- /* sync up with the time from the RCS file */
- set_time = 1;
- }
-
- wrap_fromcvs_process_file (file);
-
- /*
- * If we want read-only files, muck the permissions here, before
- * getting the file time-stamp.
- */
- if (cvswrite == FALSE)
- xchmod (file, 0);
-
-#ifndef DEATH_SUPPORT
- /* With death_support, files added with tags go into branches immediately. */
-
- /* for added files with symbolic tags, need to add the tag too */
- if (type == 'A' && tag && !isdigit (*tag))
- {
- (void) RCS_settag(rcs, tag, rev);
- }
-#endif /* No DEATH_SUPPORT */
-
- /* re-register with the new data */
- vers = Version_TS (repository, (char *) NULL, tag, (char *) NULL,
- file, 1, set_time, entries, (List *) NULL);
- if (strcmp (vers->options, "-V4") == 0)
- vers->options[0] = '\0';
- Register (entries, file, vers->vn_rcs, vers->ts_user,
- vers->options, vers->tag, vers->date, (char *) 0);
- history_write (type, (char *) 0, vers->vn_rcs, file, repository);
- freevers_ts (&vers);
-
- if (tocvsPath)
- if (unlink_file_dir (tocvsPath) < 0)
- error (0, errno, "cannot remove %s", tocvsPath);
-
- break;
-
- case -1: /* fork failed */
- if (tocvsPath)
- if (unlink_file_dir (tocvsPath) < 0)
- error (0, errno, "cannot remove %s", tocvsPath);
-
- if (!noexec)
- error (1, errno, "could not check in %s -- fork failed",
- fullname);
- return (1);
-
- default: /* ci failed */
-
- /*
- * The checkin failed, for some unknown reason, so we restore the
- * original user file, print an error, and return an error
- */
- if (tocvsPath)
- if (unlink_file_dir (tocvsPath) < 0)
- error (0, errno, "cannot remove %s", tocvsPath);
-
- if (!noexec)
- {
- rename_file (fname, file);
- error (0, 0, "could not check in %s", fullname);
- }
- return (1);
- }
-
- /*
- * When checking in a specific revision, we may have locked the wrong
- * branch, so to be sure, we do an extra unlock here before
- * returning.
- */
- if (rev)
- {
- (void) RCS_unlock (rcs, NULL, 1);
- }
-
-#ifdef SERVER_SUPPORT
- if (server_active)
- {
- if (set_time)
- /* Need to update the checked out file on the client side. */
- server_updated (file, update_dir, repository, SERVER_UPDATED,
- NULL, NULL);
- else
- server_checked_in (file, update_dir, repository);
- }
-#endif
-
- return (0);
-}
diff --git a/gnu/usr.bin/cvs/cvs/checkout.c b/gnu/usr.bin/cvs/cvs/checkout.c
deleted file mode 100644
index bb126dd2de5d..000000000000
--- a/gnu/usr.bin/cvs/cvs/checkout.c
+++ /dev/null
@@ -1,874 +0,0 @@
-/*
- * Copyright (c) 1992, Brian Berliner and Jeff Polk
- * Copyright (c) 1989-1992, Brian Berliner
- *
- * You may distribute under the terms of the GNU General Public License as
- * specified in the README file that comes with the CVS 1.4 kit.
- *
- * Create Version
- *
- * "checkout" creates a "version" of an RCS repository. This version is owned
- * totally by the user and is actually an independent copy, to be dealt with
- * as seen fit. Once "checkout" has been called in a given directory, it
- * never needs to be called again. The user can keep up-to-date by calling
- * "update" when he feels like it; this will supply him with a merge of his
- * own modifications and the changes made in the RCS original. See "update"
- * for details.
- *
- * "checkout" can be given a list of directories or files to be updated and in
- * the case of a directory, will recursivley create any sub-directories that
- * exist in the repository.
- *
- * When the user is satisfied with his own modifications, the present version
- * can be committed by "commit"; this keeps the present version in tact,
- * usually.
- *
- * The call is cvs checkout [options] <module-name>...
- *
- * "checkout" creates a directory ./CVS, in which it keeps its administration,
- * in two files, Repository and Entries. The first contains the name of the
- * repository. The second contains one line for each registered file,
- * consisting of the version number it derives from, its time stamp at
- * derivation time and its name. Both files are normal files and can be
- * edited by the user, if necessary (when the repository is moved, e.g.)
- */
-
-#include "cvs.h"
-
-#ifndef lint
-static const char rcsid[] = "$CVSid: @(#)checkout.c 1.78 94/10/07 $";
-USE(rcsid);
-#endif
-
-static char *findslash PROTO((char *start, char *p));
-static int build_dirs_and_chdir PROTO((char *dir, char *prepath, char *realdir,
- int sticky));
-static int checkout_proc PROTO((int *pargc, char **argv, char *where,
- char *mwhere, char *mfile, int shorten,
- int local_specified, char *omodule,
- char *msg));
-static int safe_location PROTO((void));
-
-static const char *const checkout_usage[] =
-{
- "Usage:\n %s %s [-ANPcflnps] [-r rev | -D date] [-d dir] [-k kopt] modules...\n",
- "\t-A\tReset any sticky tags/date/kopts.\n",
- "\t-N\tDon't shorten module paths if -d specified.\n",
- "\t-P\tPrune empty directories.\n",
- "\t-c\t\"cat\" the module database.\n",
- "\t-f\tForce a head revision match if tag/date not found.\n",
- "\t-l\tLocal directory only, not recursive\n",
- "\t-n\tDo not run module program (if any).\n",
- "\t-p\tCheck out files to standard output.\n",
- "\t-s\tLike -c, but include module status.\n",
- "\t-r rev\tCheck out revision or tag. (implies -P)\n",
- "\t-D date\tCheck out revisions as of date. (implies -P)\n",
- "\t-d dir\tCheck out into dir instead of module name.\n",
- "\t-k kopt\tUse RCS kopt -k option on checkout.\n",
- "\t-j rev\tMerge in changes made between current revision and rev.\n",
- NULL
-};
-
-static const char *const export_usage[] =
-{
- "Usage: %s %s [-NPfln] [-r rev | -D date] [-d dir] [-k kopt] module...\n",
- "\t-N\tDon't shorten module paths if -d specified.\n",
- "\t-f\tForce a head revision match if tag/date not found.\n",
- "\t-l\tLocal directory only, not recursive\n",
- "\t-n\tDo not run module program (if any).\n",
- "\t-r rev\tCheck out revision or tag.\n",
- "\t-D date\tCheck out revisions as of date.\n",
- "\t-d dir\tCheck out into dir instead of module name.\n",
- "\t-k kopt\tUse RCS kopt -k option on checkout.\n",
- NULL
-};
-
-static int checkout_prune_dirs;
-static int force_tag_match = 1;
-static int pipeout;
-static int aflag;
-static char *options = NULL;
-static char *tag = NULL;
-static char *date = NULL;
-static char *join_rev1 = NULL;
-static char *join_rev2 = NULL;
-static char *preload_update_dir = NULL;
-
-int
-checkout (argc, argv)
- int argc;
- char **argv;
-{
- int i;
- int c;
- DBM *db;
- int cat = 0, err = 0, status = 0;
- int run_module_prog = 1;
- int local = 0;
- int shorten = -1;
- char *where = NULL;
- char *valid_options;
- const char *const *valid_usage;
- enum mtype m_type;
-
- /*
- * A smaller subset of options are allowed for the export command, which
- * is essentially like checkout, except that it hard-codes certain
- * options to be default (like -kv) and takes care to remove the CVS
- * directory when it has done its duty
- */
- if (strcmp (command_name, "export") == 0)
- {
- m_type = EXPORT;
- valid_options = "Nnk:d:flRQqr:D:";
- valid_usage = export_usage;
- }
- else
- {
- m_type = CHECKOUT;
- valid_options = "ANnk:d:flRpQqcsr:D:j:P";
- valid_usage = checkout_usage;
- }
-
- if (argc == -1)
- usage (valid_usage);
-
- ign_setup ();
- wrap_setup ();
-
- optind = 1;
- while ((c = getopt (argc, argv, valid_options)) != -1)
- {
- switch (c)
- {
- case 'A':
- aflag = 1;
- break;
- case 'N':
- shorten = 0;
- break;
- case 'k':
- if (options)
- free (options);
- options = RCS_check_kflag (optarg);
- break;
- case 'n':
- run_module_prog = 0;
- break;
- case 'Q':
- case 'q':
-#ifdef SERVER_SUPPORT
- /* The CVS 1.5 client sends these options (in addition to
- Global_option requests), so we must ignore them. */
- if (!server_active)
-#endif
- error (1, 0,
- "-q or -Q must be specified before \"%s\"",
- command_name);
- break;
- case 'l':
- local = 1;
- break;
- case 'R':
- local = 0;
- break;
- case 'P':
- checkout_prune_dirs = 1;
- break;
- case 'p':
- pipeout = 1;
- run_module_prog = 0; /* don't run module prog when piping */
- noexec = 1; /* so no locks will be created */
- break;
- case 'c':
- cat = 1;
- break;
- case 'd':
- where = optarg;
- if (shorten == -1)
- shorten = 1;
- break;
- case 's':
- status = 1;
- break;
- case 'f':
- force_tag_match = 0;
- break;
- case 'r':
- tag = optarg;
- checkout_prune_dirs = 1;
- break;
- case 'D':
- date = Make_Date (optarg);
- checkout_prune_dirs = 1;
- break;
- case 'j':
- if (join_rev2)
- error (1, 0, "only two -j options can be specified");
- if (join_rev1)
- join_rev2 = optarg;
- else
- join_rev1 = optarg;
- break;
- case '?':
- default:
- usage (valid_usage);
- break;
- }
- }
- argc -= optind;
- argv += optind;
-
- if (shorten == -1)
- shorten = 0;
-
- if ((!(cat + status) && argc == 0) || ((cat + status) && argc != 0)
- || (tag && date))
- usage (valid_usage);
-
- if (where && pipeout)
- error (1, 0, "-d and -p are mutually exclusive");
-
- if (strcmp (command_name, "export") == 0)
- {
- if (!tag && !date)
- {
- error (0, 0, "must specify a tag or date");
- usage (valid_usage);
- }
- if (tag && isdigit (tag[0]))
- error (1, 0, "tag `%s' must be a symbolic tag", tag);
-/*
- * mhy 950615: -kv doesn't work for binaries with RCS keywords.
- * Instead use the default provided in the RCS file (-ko for binaries).
- */
-#if 0
- if (!options)
- options = RCS_check_kflag ("v");/* -kv is default */
-#endif
- }
-
- if (!safe_location()) {
- error(1, 0, "Cannot check out files into the repository itself");
- }
-
-#ifdef CLIENT_SUPPORT
- if (client_active)
- {
- int expand_modules;
-
- start_server ();
-
- ign_setup ();
-
- /* We have to expand names here because the "expand-modules"
- directive to the server has the side-effect of having the
- server send the check-in and update programs for the
- various modules/dirs requested. If we turn this off and
- simply request the names of the modules and directories (as
- below in !expand_modules), those files (CVS/Checking.prog
- or CVS/Update.prog) don't get created. Grrr. */
-
- expand_modules = (!cat && !status && !pipeout
- && supported_request ("expand-modules"));
-
- if (expand_modules)
- {
- /* This is done here because we need to read responses
- from the server before we send the command checkout or
- export files. */
-
- client_expand_modules (argc, argv, local);
- }
-
- if (!run_module_prog) send_arg ("-n");
- if (local) send_arg ("-l");
- if (pipeout) send_arg ("-p");
- if (!force_tag_match) send_arg ("-f");
- if (aflag)
- send_arg("-A");
- if (!shorten)
- send_arg("-N");
- if (checkout_prune_dirs && strcmp (command_name, "export") != 0)
- send_arg("-P");
- client_prune_dirs = checkout_prune_dirs;
- if (cat)
- send_arg("-c");
- if (where != NULL)
- {
- option_with_arg ("-d", where);
- }
- if (status)
- send_arg("-s");
- if (strcmp (command_name, "export") != 0
- && options != NULL
- && options[0] != '\0')
- send_arg (options);
- option_with_arg ("-r", tag);
- if (date)
- client_senddate (date);
- if (join_rev1 != NULL)
- option_with_arg ("-j", join_rev1);
- if (join_rev2 != NULL)
- option_with_arg ("-j", join_rev2);
-
- if (expand_modules)
- {
- client_send_expansions (local);
- }
- else
- {
- int i;
- for (i = 0; i < argc; ++i)
- send_arg (argv[i]);
- client_nonexpanded_setup ();
- }
-
- if (fprintf
- (to_server,
- strcmp (command_name, "export") == 0 ? "export\n" : "co\n")
- < 0)
- error (1, errno, "writing to server");
-
- return get_responses_and_close ();
- }
-#endif
-
- if (cat || status)
- {
- cat_module (status);
- return (0);
- }
- db = open_module ();
-
- /*
- * if we have more than one argument and where was specified, we make the
- * where, cd into it, and try to shorten names as much as possible.
- * Otherwise, we pass the where as a single argument to do_module.
- */
- if (argc > 1 && where != NULL)
- {
- char repository[PATH_MAX];
-
- (void) CVS_MKDIR (where, 0777);
- if (chdir (where) < 0)
- error (1, errno, "cannot chdir to %s", where);
- preload_update_dir = xstrdup (where);
- where = (char *) NULL;
- if (!isfile (CVSADM))
- {
- (void) sprintf (repository, "%s/%s/%s", CVSroot, CVSROOTADM,
- CVSNULLREPOS);
- if (!isfile (repository))
- {
- mode_t omask;
- omask = umask (cvsumask);
- (void) CVS_MKDIR (repository, 0777);
- (void) umask (omask);
- }
-
- /* I'm not sure whether this check is redundant. */
- if (!isdir (repository))
- error (1, 0, "there is no repository %s", repository);
-
- Create_Admin (".", where, repository,
- (char *) NULL, (char *) NULL);
- if (!noexec)
- {
- FILE *fp;
-
- fp = open_file (CVSADM_ENTSTAT, "w+");
- if (fclose(fp) == EOF)
- error(1, errno, "cannot close %s", CVSADM_ENTSTAT);
-#ifdef SERVER_SUPPORT
- if (server_active)
- server_set_entstat (preload_update_dir, repository);
-#endif
- }
- }
- }
-
- /*
- * if where was specified (-d) and we have not taken care of it already
- * with the multiple arg stuff, and it was not a simple directory name
- * but rather a path, we strip off everything but the last component and
- * attempt to cd to the indicated place. where then becomes simply the
- * last component
- */
- if (where != NULL && strchr (where, '/') != NULL)
- {
- char *slash;
-
- slash = strrchr (where, '/');
- *slash = '\0';
-
- if (chdir (where) < 0)
- error (1, errno, "cannot chdir to %s", where);
-
- preload_update_dir = xstrdup (where);
-
- where = slash + 1;
- if (*where == '\0')
- where = NULL;
- }
-
- for (i = 0; i < argc; i++)
- err += do_module (db, argv[i], m_type, "Updating", checkout_proc,
- where, shorten, local, run_module_prog,
- (char *) NULL);
- close_module (db);
- return (err);
-}
-
-static int
-safe_location ()
-{
- char current[PATH_MAX];
- char hardpath[PATH_MAX+5];
- int x;
-
- x = readlink(CVSroot, hardpath, sizeof hardpath - 1);
- if (x == -1)
- {
- strcpy(hardpath, CVSroot);
- }
- hardpath[x] = '\0';
- getwd (current);
- if (strncmp(current, hardpath, strlen(hardpath)) == 0)
- {
- return (0);
- }
- return (1);
-}
-
-/*
- * process_module calls us back here so we do the actual checkout stuff
- */
-/* ARGSUSED */
-static int
-checkout_proc (pargc, argv, where, mwhere, mfile, shorten,
- local_specified, omodule, msg)
- int *pargc;
- char **argv;
- char *where;
- char *mwhere;
- char *mfile;
- int shorten;
- int local_specified;
- char *omodule;
- char *msg;
-{
- int err = 0;
- int which;
- char *cp;
- char *cp2;
- char repository[PATH_MAX];
- char xwhere[PATH_MAX];
- char *oldupdate = NULL;
- char *prepath;
- char *realdirs;
-
- /*
- * OK, so we're doing the checkout! Our args are as follows:
- * argc,argv contain either dir or dir followed by a list of files
- * where contains where to put it (if supplied by checkout)
- * mwhere contains the module name or -d from module file
- * mfile says do only that part of the module
- * shorten = TRUE says shorten as much as possible
- * omodule is the original arg to do_module()
- */
-
- /* set up the repository (maybe) for the bottom directory */
- (void) sprintf (repository, "%s/%s", CVSroot, argv[0]);
-
- /* save the original value of preload_update_dir */
- if (preload_update_dir != NULL)
- oldupdate = xstrdup (preload_update_dir);
-
- /* fix up argv[] for the case of partial modules */
- if (mfile != NULL)
- {
- char file[PATH_MAX];
-
- /* if mfile is really a path, straighten it out first */
- if ((cp = strrchr (mfile, '/')) != NULL)
- {
- *cp = 0;
- (void) strcat (repository, "/");
- (void) strcat (repository, mfile);
-
- /*
- * Now we need to fill in the where correctly. if !shorten, tack
- * the rest of the path onto where if where is filled in
- * otherwise tack the rest of the path onto mwhere and make that
- * the where
- *
- * If shorten is enabled, we might use mwhere to set where if
- * nobody set it yet, so we'll need to setup mwhere as the last
- * component of the path we are tacking onto repository
- */
- if (!shorten)
- {
- if (where != NULL)
- (void) sprintf (xwhere, "%s/%s", where, mfile);
- else
- (void) sprintf (xwhere, "%s/%s", mwhere, mfile);
- where = xwhere;
- }
- else
- {
- char *slash;
-
- if ((slash = strrchr (mfile, '/')) != NULL)
- mwhere = slash + 1;
- else
- mwhere = mfile;
- }
- mfile = cp + 1;
- }
-
- (void) sprintf (file, "%s/%s", repository, mfile);
- if (isdir (file))
- {
-
- /*
- * The portion of a module was a directory, so kludge up where to
- * be the subdir, and fix up repository
- */
- (void) strcpy (repository, file);
-
- /*
- * At this point, if shorten is not enabled, we make where either
- * where with mfile concatenated, or if where hadn't been set we
- * set it to mwhere with mfile concatenated.
- *
- * If shorten is enabled and where hasn't been set yet, then where
- * becomes mfile
- */
- if (!shorten)
- {
- if (where != NULL)
- (void) sprintf (xwhere, "%s/%s", where, mfile);
- else
- (void) sprintf (xwhere, "%s/%s", mwhere, mfile);
- where = xwhere;
- }
- else if (where == NULL)
- where = mfile;
- }
- else
- {
- int i;
-
- /*
- * The portion of a module was a file, so kludge up argv to be
- * correct
- */
- for (i = 1; i < *pargc; i++)/* free the old ones */
- free (argv[i]);
- argv[1] = xstrdup (mfile); /* set up the new one */
- *pargc = 2;
-
- /* where gets mwhere if where isn't set */
- if (where == NULL)
- where = mwhere;
- }
- }
-
- /*
- * if shorten is enabled and where isn't specified yet, we pluck the last
- * directory component of argv[0] and make it the where
- */
- if (shorten && where == NULL)
- {
- if ((cp = strrchr (argv[0], '/')) != NULL)
- {
- (void) strcpy (xwhere, cp + 1);
- where = xwhere;
- }
- }
-
- /* if where is still NULL, use mwhere if set or the argv[0] dir */
- if (where == NULL)
- {
- if (mwhere)
- where = mwhere;
- else
- {
- (void) strcpy (xwhere, argv[0]);
- where = xwhere;
- }
- }
-
- if (preload_update_dir != NULL)
- {
- char tmp[PATH_MAX];
-
- (void) sprintf (tmp, "%s/%s", preload_update_dir, where);
- free (preload_update_dir);
- preload_update_dir = xstrdup (tmp);
- }
- else
- preload_update_dir = xstrdup (where);
-
- /*
- * At this point, where is the directory we want to build, repository is
- * the repository for the lowest level of the path.
- */
-
- /*
- * If we are sending everything to stdout, we can skip a whole bunch of
- * work from here
- */
- if (!pipeout)
- {
-
- /*
- * We need to tell build_dirs not only the path we want it to build,
- * but also the repositories we want it to populate the path with. To
- * accomplish this, we pass build_dirs a ``real path'' with valid
- * repositories and a string to pre-pend based on how many path
- * elements exist in where. Big Black Magic
- */
- prepath = xstrdup (repository);
- cp = strrchr (where, '/');
- cp2 = strrchr (prepath, '/');
- while (cp != NULL)
- {
- cp = findslash (where, cp - 1);
- cp2 = findslash (prepath, cp2 - 1);
- }
- *cp2 = '\0';
- realdirs = cp2 + 1;
-
- /*
- * build dirs on the path if necessary and leave us in the bottom
- * directory (where if where was specified) doesn't contain a CVS
- * subdir yet, but all the others contain CVS and Entries.Static
- * files
- */
- if (build_dirs_and_chdir (where, prepath, realdirs, *pargc <= 1) != 0)
- {
- error (0, 0, "ignoring module %s", omodule);
- free (prepath);
- free (preload_update_dir);
- preload_update_dir = oldupdate;
- return (1);
- }
-
- /* clean up */
- free (prepath);
-
- /* set up the repository (or make sure the old one matches) */
- if (!isfile (CVSADM))
- {
- FILE *fp;
-
- if (!noexec && *pargc > 1)
- {
- /* I'm not sure whether this check is redundant. */
- if (!isdir (repository))
- error (1, 0, "there is no repository %s", repository);
-
- Create_Admin (".", where, repository,
- (char *) NULL, (char *) NULL);
- fp = open_file (CVSADM_ENTSTAT, "w+");
- if (fclose(fp) == EOF)
- error(1, errno, "cannot close %s", CVSADM_ENTSTAT);
-#ifdef SERVER_SUPPORT
- if (server_active)
- server_set_entstat (where, repository);
-#endif
- }
- else
- {
- /* I'm not sure whether this check is redundant. */
- if (!isdir (repository))
- error (1, 0, "there is no repository %s", repository);
-
- Create_Admin (".", where, repository, tag, date);
- }
- }
- else
- {
- char *repos;
-
- /* get the contents of the previously existing repository */
- repos = Name_Repository ((char *) NULL, preload_update_dir);
- if (fncmp (repository, repos) != 0)
- {
- error (0, 0, "existing repository %s does not match %s",
- repos, repository);
- error (0, 0, "ignoring module %s", omodule);
- free (repos);
- free (preload_update_dir);
- preload_update_dir = oldupdate;
- return (1);
- }
- free (repos);
- }
- }
-
- /*
- * If we are going to be updating to stdout, we need to cd to the
- * repository directory so the recursion processor can use the current
- * directory as the place to find repository information
- */
- if (pipeout)
- {
- if (chdir (repository) < 0)
- {
- error (0, errno, "cannot chdir to %s", repository);
- free (preload_update_dir);
- preload_update_dir = oldupdate;
- return (1);
- }
- which = W_REPOS;
- }
- else
- which = W_LOCAL | W_REPOS;
-
- if (tag != NULL || date != NULL)
- which |= W_ATTIC;
-
- /*
- * if we are going to be recursive (building dirs), go ahead and call the
- * update recursion processor. We will be recursive unless either local
- * only was specified, or we were passed arguments
- */
- if (!(local_specified || *pargc > 1))
- {
- if (strcmp (command_name, "export") != 0 && !pipeout)
- history_write ('O', preload_update_dir, tag ? tag : date, where,
- repository);
- err += do_update (0, (char **) NULL, options, tag, date,
- force_tag_match, 0 /* !local */ ,
- 1 /* update -d */ , aflag, checkout_prune_dirs,
- pipeout, which, join_rev1, join_rev2,
- preload_update_dir);
- free (preload_update_dir);
- preload_update_dir = oldupdate;
- return (err);
- }
-
- if (!pipeout)
- {
- int i;
- List *entries;
-
- /* we are only doing files, so register them */
- entries = Entries_Open (0);
- for (i = 1; i < *pargc; i++)
- {
- char line[MAXLINELEN];
- char *user;
- Vers_TS *vers;
-
- user = argv[i];
- vers = Version_TS (repository, options, tag, date, user,
- force_tag_match, 0, entries, (List *) NULL);
- if (vers->ts_user == NULL)
- {
- (void) sprintf (line, "Initial %s", user);
- Register (entries, user, vers->vn_rcs ? vers->vn_rcs : "0",
- line, vers->options, vers->tag,
- vers->date, (char *) 0);
- }
- freevers_ts (&vers);
- }
-
- Entries_Close (entries);
- }
-
- /* Don't log "export", just regular "checkouts" */
- if (strcmp (command_name, "export") != 0 && !pipeout)
- history_write ('O', preload_update_dir, (tag ? tag : date), where,
- repository);
-
- /* go ahead and call update now that everything is set */
- err += do_update (*pargc - 1, argv + 1, options, tag, date,
- force_tag_match, local_specified, 1 /* update -d */,
- aflag, checkout_prune_dirs, pipeout, which, join_rev1,
- join_rev2, preload_update_dir);
- free (preload_update_dir);
- preload_update_dir = oldupdate;
- return (err);
-}
-
-static char *
-findslash (start, p)
- char *start;
- char *p;
-{
- while (p >= start && *p != '/')
- p--;
- if (p < start)
- return (NULL);
- else
- return (p);
-}
-
-/*
- * build all the dirs along the path to dir with CVS subdirs with appropriate
- * repositories and Entries.Static files
- */
-static int
-build_dirs_and_chdir (dir, prepath, realdir, sticky)
- char *dir;
- char *prepath;
- char *realdir;
- int sticky;
-{
- FILE *fp;
- char repository[PATH_MAX];
- char path[PATH_MAX];
- char path2[PATH_MAX];
- char *slash;
- char *slash2;
- char *cp;
- char *cp2;
-
- (void) strcpy (path, dir);
- (void) strcpy (path2, realdir);
- for (cp = path, cp2 = path2;
- (slash = strchr (cp, '/')) != NULL && (slash2 = strchr (cp2, '/')) != NULL;
- cp = slash + 1, cp2 = slash2 + 1)
- {
- *slash = '\0';
- *slash2 = '\0';
- (void) CVS_MKDIR (cp, 0777);
- if (chdir (cp) < 0)
- {
- error (0, errno, "cannot chdir to %s", cp);
- return (1);
- }
- if (!isfile (CVSADM) && strcmp (command_name, "export") != 0)
- {
- (void) sprintf (repository, "%s/%s", prepath, path2);
- /* I'm not sure whether this check is redundant. */
- if (!isdir (repository))
- error (1, 0, "there is no repository %s", repository);
- Create_Admin (".", cp, repository, sticky ? (char *) NULL : tag,
- sticky ? (char *) NULL : date);
- if (!noexec)
- {
- fp = open_file (CVSADM_ENTSTAT, "w+");
- if (fclose(fp) == EOF)
- error(1, errno, "cannot close %s", CVSADM_ENTSTAT);
-#ifdef SERVER_SUPPORT
- if (server_active)
- server_set_entstat (path, repository);
-#endif
- }
- }
- *slash = '/';
- *slash2 = '/';
- }
- (void) CVS_MKDIR (cp, 0777);
- if (chdir (cp) < 0)
- {
- error (0, errno, "cannot chdir to %s", cp);
- return (1);
- }
- return (0);
-}
diff --git a/gnu/usr.bin/cvs/cvs/classify.c b/gnu/usr.bin/cvs/cvs/classify.c
deleted file mode 100644
index 23fafca9b2c5..000000000000
--- a/gnu/usr.bin/cvs/cvs/classify.c
+++ /dev/null
@@ -1,504 +0,0 @@
-/*
- * Copyright (c) 1992, Brian Berliner and Jeff Polk
- * Copyright (c) 1989-1992, Brian Berliner
- *
- * You may distribute under the terms of the GNU General Public License as
- * specified in the README file that comes with the CVS 1.4 kit.
- *
- */
-
-#include "cvs.h"
-
-#ifndef lint
-static const char rcsid[] = "$CVSid: @(#)classify.c 1.17 94/10/07 $";
-USE(rcsid);
-#endif
-
-#ifdef SERVER_SUPPORT
-static void sticky_ck PROTO((char *file, int aflag, Vers_TS * vers,
- List * entries,
- char *repository, char *update_dir));
-#else
-static void sticky_ck PROTO((char *file, int aflag, Vers_TS * vers, List * entries));
-#endif
-
-/*
- * Classify the state of a file
- */
-Ctype
-Classify_File (file, tag, date, options, force_tag_match, aflag, repository,
- entries, srcfiles, versp, update_dir, pipeout)
- char *file;
- char *tag;
- char *date;
- char *options;
- int force_tag_match;
- int aflag;
- char *repository;
- List *entries;
- List *srcfiles;
- Vers_TS **versp;
- char *update_dir;
- int pipeout;
-{
- Vers_TS *vers;
- Ctype ret;
- char *fullname;
-
- fullname = xmalloc (strlen (update_dir) + strlen (file) + 10);
- if (update_dir[0] == '\0')
- strcpy (fullname, file);
- else
- sprintf (fullname, "%s/%s", update_dir, file);
-
- /* get all kinds of good data about the file */
- vers = Version_TS (repository, options, tag, date, file,
- force_tag_match, 0, entries, srcfiles);
-
- if (vers->vn_user == NULL)
- {
- /* No entry available, ts_rcs is invalid */
- if (vers->vn_rcs == NULL)
- {
- /* there is no RCS file either */
- if (vers->ts_user == NULL)
- {
- /* there is no user file */
- if (!force_tag_match || !(vers->tag || vers->date))
- if (!really_quiet)
- error (0, 0, "nothing known about %s", fullname);
- ret = T_UNKNOWN;
- }
- else
- {
- /* there is a user file */
- if (!force_tag_match || !(vers->tag || vers->date))
- if (!really_quiet)
- error (0, 0, "use `cvs add' to create an entry for %s",
- fullname);
- ret = T_UNKNOWN;
- }
- }
-#ifdef DEATH_SUPPORT
- else if (RCS_isdead (vers->srcfile, vers->vn_rcs))
- {
- if (vers->ts_user == NULL)
- /*
- * Logically seems to me this should be T_UPTODATE.
- * But the joining code in update.c seems to expect
- * T_CHECKOUT, and that is what has traditionally been
- * returned for this case.
- */
- ret = T_CHECKOUT;
- else
- {
- error (0, 0, "use `cvs add' to create an entry for %s",
- fullname);
- ret = T_UNKNOWN;
- }
- }
-#endif
- else
- {
- /* there is an rcs file */
-
- if (vers->ts_user == NULL)
- {
- /* There is no user file; needs checkout */
- ret = T_CHECKOUT;
- }
- else
- {
- if (pipeout)
- {
- /*
- * The user file doesn't necessarily have anything
- * to do with this.
- */
- ret = T_CHECKOUT;
- }
- /*
- * There is a user file; print a warning and add it to the
- * conflict list, only if it is indeed different from what we
- * plan to extract
- */
- else if (No_Difference (file, vers, entries,
- repository, update_dir))
- {
- /* the files were different so it is a conflict */
- if (!really_quiet)
- error (0, 0, "move away %s; it is in the way",
- fullname);
- ret = T_CONFLICT;
- }
- else
- /* since there was no difference, still needs checkout */
- ret = T_CHECKOUT;
- }
- }
- }
- else if (strcmp (vers->vn_user, "0") == 0)
- {
- /* An entry for a new-born file; ts_rcs is dummy */
-
- if (vers->ts_user == NULL)
- {
- /*
- * There is no user file, but there should be one; remove the
- * entry
- */
- if (!really_quiet)
- error (0, 0, "warning: new-born %s has disappeared", fullname);
- ret = T_REMOVE_ENTRY;
- }
- else
- {
- /* There is a user file */
-
- if (vers->vn_rcs == NULL)
- /* There is no RCS file, added file */
- ret = T_ADDED;
-#ifdef DEATH_SUPPORT
- else if (RCS_isdead (vers->srcfile, vers->vn_rcs))
- /* we are resurrecting. */
- ret = T_ADDED;
-#endif /* DEATH_SUPPORT */
- else
- {
-#ifdef DEATH_SUPPORT
- if (vers->srcfile->flags & INATTIC
- && vers->srcfile->flags & VALID)
- {
- /* This file has been added on some branch other than
- the one we are looking at. In the branch we are
- looking at, the file was already valid. */
- if (!really_quiet)
- error (0, 0,
- "conflict: %s has been added, but already exists",
- fullname);
- }
- else
- {
-#endif /* DEATH_SUPPORT */
- /*
- * There is an RCS file, so someone else must have checked
- * one in behind our back; conflict
- */
- if (!really_quiet)
- error (0, 0,
- "conflict: %s created independently by second party",
- fullname);
-#ifdef DEATH_SUPPORT
- }
-#endif
- ret = T_CONFLICT;
- }
- }
- }
- else if (vers->vn_user[0] == '-')
- {
- /* An entry for a removed file, ts_rcs is invalid */
-
- if (vers->ts_user == NULL)
- {
- char tmp[PATH_MAX];
-
- /* There is no user file (as it should be) */
-
- (void) sprintf (tmp, "-%s", vers->vn_rcs ? vers->vn_rcs : "");
-
- if (vers->vn_rcs == NULL)
- {
-
- /*
- * There is no RCS file; this is all-right, but it has been
- * removed independently by a second party; remove the entry
- */
- ret = T_REMOVE_ENTRY;
- }
- else if (strcmp (tmp, vers->vn_user) == 0)
-
- /*
- * The RCS file is the same version as the user file was, and
- * that's OK; remove it
- */
- ret = T_REMOVED;
- else
- {
-
- /*
- * The RCS file is a newer version than the removed user file
- * and this is definitely not OK; make it a conflict.
- */
- if (!really_quiet)
- error (0, 0,
- "conflict: removed %s was modified by second party",
- fullname);
- ret = T_CONFLICT;
- }
- }
- else
- {
- /* The user file shouldn't be there */
- if (!really_quiet)
- error (0, 0, "%s should be removed and is still there",
- fullname);
- ret = T_REMOVED;
- }
- }
- else
- {
- /* A normal entry, TS_Rcs is valid */
- if (vers->vn_rcs == NULL)
- {
- /* There is no RCS file */
-
- if (vers->ts_user == NULL)
- {
- /* There is no user file, so just remove the entry */
- if (!really_quiet)
- error (0, 0, "warning: %s is not (any longer) pertinent",
- fullname);
- ret = T_REMOVE_ENTRY;
- }
- else if (strcmp (vers->ts_user, vers->ts_rcs) == 0)
- {
-
- /*
- * The user file is still unmodified, so just remove it from
- * the entry list
- */
- if (!really_quiet)
- error (0, 0, "%s is no longer in the repository",
- fullname);
- ret = T_REMOVE_ENTRY;
- }
- else
- {
- /*
- * The user file has been modified and since it is no longer
- * in the repository, a conflict is raised
- */
- if (No_Difference (file, vers, entries,
- repository, update_dir))
- {
- /* they are different -> conflict */
- if (!really_quiet)
- error (0, 0,
- "conflict: %s is modified but no longer in the repository",
- fullname);
- ret = T_CONFLICT;
- }
- else
- {
- /* they weren't really different */
- if (!really_quiet)
- error (0, 0,
- "warning: %s is not (any longer) pertinent",
- fullname);
- ret = T_REMOVE_ENTRY;
- }
- }
- }
- else if (strcmp (vers->vn_rcs, vers->vn_user) == 0)
- {
- /* The RCS file is the same version as the user file */
-
- if (vers->ts_user == NULL)
- {
-
- /*
- * There is no user file, so note that it was lost and
- * extract a new version
- */
- if (strcmp (command_name, "update") == 0)
- if (!really_quiet)
- error (0, 0, "warning: %s was lost", fullname);
- ret = T_CHECKOUT;
- }
- else if (strcmp (vers->ts_user, vers->ts_rcs) == 0)
- {
-
- /*
- * The user file is still unmodified, so nothing special at
- * all to do -- no lists updated, unless the sticky -k option
- * has changed. If the sticky tag has changed, we just need
- * to re-register the entry
- */
- if (vers->entdata->options &&
- strcmp (vers->entdata->options, vers->options) != 0)
- ret = T_CHECKOUT;
- else
- {
-#ifdef SERVER_SUPPORT
- sticky_ck (file, aflag, vers, entries,
- repository, update_dir);
-#else
- sticky_ck (file, aflag, vers, entries);
-#endif
- ret = T_UPTODATE;
- }
- }
- else
- {
-
- /*
- * The user file appears to have been modified, but we call
- * No_Difference to verify that it really has been modified
- */
- if (No_Difference (file, vers, entries,
- repository, update_dir))
- {
-
- /*
- * they really are different; modified if we aren't
- * changing any sticky -k options, else needs merge
- */
-#ifdef XXX_FIXME_WHEN_RCSMERGE_IS_FIXED
- if (strcmp (vers->entdata->options ?
- vers->entdata->options : "", vers->options) == 0)
- ret = T_MODIFIED;
- else
- ret = T_NEEDS_MERGE;
-#else
- ret = T_MODIFIED;
-#ifdef SERVER_SUPPORT
- sticky_ck (file, aflag, vers, entries,
- repository, update_dir);
-#else
- sticky_ck (file, aflag, vers, entries);
-#endif /* SERVER_SUPPORT */
-#endif
- }
- else
- {
- /* file has not changed; check out if -k changed */
- if (strcmp (vers->entdata->options ?
- vers->entdata->options : "", vers->options) != 0)
- {
- ret = T_CHECKOUT;
- }
- else
- {
-
- /*
- * else -> note that No_Difference will Register the
- * file already for us, using the new tag/date. This
- * is the desired behaviour
- */
- ret = T_UPTODATE;
- }
- }
- }
- }
- else
- {
- /* The RCS file is a newer version than the user file */
-
- if (vers->ts_user == NULL)
- {
- /* There is no user file, so just get it */
-
- if (strcmp (command_name, "update") == 0)
- if (!really_quiet)
- error (0, 0, "warning: %s was lost", fullname);
- ret = T_CHECKOUT;
- }
- else if (strcmp (vers->ts_user, vers->ts_rcs) == 0)
- {
-
- /*
- * The user file is still unmodified, so just get it as well
- */
-#ifdef SERVER_SUPPORT
- if (strcmp (vers->entdata->options ?
- vers->entdata->options : "", vers->options) != 0
- || (vers->srcfile != NULL
- && (vers->srcfile->flags & INATTIC) != 0))
- ret = T_CHECKOUT;
- else
- ret = T_PATCH;
-#else
- ret = T_CHECKOUT;
-#endif
- }
- else
- {
- if (No_Difference (file, vers, entries,
- repository, update_dir))
- /* really modified, needs to merge */
- ret = T_NEEDS_MERGE;
-#ifdef SERVER_SUPPORT
- else if ((strcmp (vers->entdata->options ?
- vers->entdata->options : "", vers->options)
- != 0)
- || (vers->srcfile != NULL
- && (vers->srcfile->flags & INATTIC) != 0))
- /* not really modified, check it out */
- ret = T_CHECKOUT;
- else
- ret = T_PATCH;
-#else
- else
- /* not really modified, check it out */
- ret = T_CHECKOUT;
-#endif
- }
- }
- }
-
- /* free up the vers struct, or just return it */
- if (versp != (Vers_TS **) NULL)
- *versp = vers;
- else
- freevers_ts (&vers);
-
- free (fullname);
-
- /* return the status of the file */
- return (ret);
-}
-
-static void
-#ifdef SERVER_SUPPORT
-sticky_ck (file, aflag, vers, entries, repository, update_dir)
-#else
-sticky_ck (file, aflag, vers, entries)
-#endif
- char *file;
- int aflag;
- Vers_TS *vers;
- List *entries;
-#ifdef SERVER_SUPPORT
- char *repository;
- char *update_dir;
-#endif
-{
- if (aflag || vers->tag || vers->date)
- {
- char *enttag = vers->entdata->tag;
- char *entdate = vers->entdata->date;
-
- if ((enttag && vers->tag && strcmp (enttag, vers->tag)) ||
- ((enttag && !vers->tag) || (!enttag && vers->tag)) ||
- (entdate && vers->date && strcmp (entdate, vers->date)) ||
- ((entdate && !vers->date) || (!entdate && vers->date)))
- {
- Register (entries, file, vers->vn_user, vers->ts_rcs,
- vers->options, vers->tag, vers->date, vers->ts_conflict);
-
-#ifdef SERVER_SUPPORT
- if (server_active)
- {
- /* We need to update the entries line on the client side.
- It is possible we will later update it again via
- server_updated or some such, but that is OK. */
- server_update_entries
- (file, update_dir, repository,
- strcmp (vers->ts_rcs, vers->ts_user) == 0 ?
- SERVER_UPDATED : SERVER_MERGED);
- }
-#endif
- }
- }
-}
diff --git a/gnu/usr.bin/cvs/cvs/client.c b/gnu/usr.bin/cvs/cvs/client.c
deleted file mode 100644
index dd96db8f091d..000000000000
--- a/gnu/usr.bin/cvs/cvs/client.c
+++ /dev/null
@@ -1,3542 +0,0 @@
-/* CVS client-related stuff. */
-
-#include "cvs.h"
-
-#ifdef CLIENT_SUPPORT
-
-#include "update.h" /* Things shared with update.c */
-#include "md5.h"
-
-#ifdef AUTH_CLIENT_SUPPORT
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <netdb.h>
-char *get_cvs_password PROTO((char *user, char *host, char *cvsrooot));
-#endif /* AUTH_CLIENT_SUPPORT */
-
-#if HAVE_KERBEROS
-#define CVS_PORT 1999
-
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <netdb.h>
-#include <krb.h>
-
-extern char *krb_realmofhost ();
-#ifndef HAVE_KRB_GET_ERR_TEXT
-#define krb_get_err_text(status) krb_err_txt[status]
-#endif /* HAVE_KRB_GET_ERR_TEXT */
-#endif /* HAVE_KERBEROS */
-
-static void add_prune_candidate PROTO((char *));
-
-/* All the commands. */
-int add PROTO((int argc, char **argv));
-int admin PROTO((int argc, char **argv));
-int checkout PROTO((int argc, char **argv));
-int commit PROTO((int argc, char **argv));
-int diff PROTO((int argc, char **argv));
-int history PROTO((int argc, char **argv));
-int import PROTO((int argc, char **argv));
-int cvslog PROTO((int argc, char **argv));
-int patch PROTO((int argc, char **argv));
-int release PROTO((int argc, char **argv));
-int cvsremove PROTO((int argc, char **argv));
-int rtag PROTO((int argc, char **argv));
-int status PROTO((int argc, char **argv));
-int tag PROTO((int argc, char **argv));
-int update PROTO((int argc, char **argv));
-
-/* All the response handling functions. */
-static void handle_ok PROTO((char *, int));
-static void handle_error PROTO((char *, int));
-static void handle_valid_requests PROTO((char *, int));
-static void handle_checked_in PROTO((char *, int));
-static void handle_new_entry PROTO((char *, int));
-static void handle_checksum PROTO((char *, int));
-static void handle_copy_file PROTO((char *, int));
-static void handle_updated PROTO((char *, int));
-static void handle_merged PROTO((char *, int));
-static void handle_patched PROTO((char *, int));
-static void handle_removed PROTO((char *, int));
-static void handle_remove_entry PROTO((char *, int));
-static void handle_set_static_directory PROTO((char *, int));
-static void handle_clear_static_directory PROTO((char *, int));
-static void handle_set_sticky PROTO((char *, int));
-static void handle_clear_sticky PROTO((char *, int));
-static void handle_set_checkin_prog PROTO((char *, int));
-static void handle_set_update_prog PROTO((char *, int));
-static void handle_module_expansion PROTO((char *, int));
-static void handle_m PROTO((char *, int));
-static void handle_e PROTO((char *, int));
-
-#endif /* CLIENT_SUPPORT */
-
-#if defined(CLIENT_SUPPORT) || defined(SERVER_SUPPORT)
-
-/* Shared with server. */
-
-/*
- * Return a malloc'd, '\0'-terminated string
- * corresponding to the mode in SB.
- */
-char *
-#ifdef __STDC__
-mode_to_string (mode_t mode)
-#else /* ! __STDC__ */
-mode_to_string (mode)
- mode_t mode;
-#endif /* __STDC__ */
-{
- char buf[18], u[4], g[4], o[4];
- int i;
-
- i = 0;
- if (mode & S_IRUSR) u[i++] = 'r';
- if (mode & S_IWUSR) u[i++] = 'w';
- if (mode & S_IXUSR) u[i++] = 'x';
- u[i] = '\0';
-
- i = 0;
- if (mode & S_IRGRP) g[i++] = 'r';
- if (mode & S_IWGRP) g[i++] = 'w';
- if (mode & S_IXGRP) g[i++] = 'x';
- g[i] = '\0';
-
- i = 0;
- if (mode & S_IROTH) o[i++] = 'r';
- if (mode & S_IWOTH) o[i++] = 'w';
- if (mode & S_IXOTH) o[i++] = 'x';
- o[i] = '\0';
-
- sprintf(buf, "u=%s,g=%s,o=%s", u, g, o);
- return xstrdup(buf);
-}
-
-/*
- * Change mode of FILENAME to MODE_STRING.
- * Returns 0 for success or errno code.
- */
-int
-change_mode (filename, mode_string)
- char *filename;
- char *mode_string;
-{
- char *p;
- mode_t mode = 0;
-
- p = mode_string;
- while (*p != '\0')
- {
- if ((p[0] == 'u' || p[0] == 'g' || p[0] == 'o') && p[1] == '=')
- {
- int can_read = 0, can_write = 0, can_execute = 0;
- char *q = p + 2;
- while (*q != ',' && *q != '\0')
- {
- if (*q == 'r')
- can_read = 1;
- else if (*q == 'w')
- can_write = 1;
- else if (*q == 'x')
- can_execute = 1;
- ++q;
- }
- if (p[0] == 'u')
- {
- if (can_read)
- mode |= S_IRUSR;
- if (can_write)
- mode |= S_IWUSR;
- if (can_execute)
- {
-#ifdef EXECUTE_PERMISSION_LOSES
- KFF_DEBUG (printf ("*** S_IXUSR in change_mode().\n"));
-#else /* ! EXECUTE_PERMISSION_LOSES */
- mode |= S_IXUSR;
-#endif /* EXECUTE_PERMISSION_LOSES */
- }
- }
- else if (p[0] == 'g')
- {
- if (can_read)
- mode |= S_IRGRP;
- if (can_write)
- mode |= S_IWGRP;
- if (can_execute)
- {
-#ifdef EXECUTE_PERMISSION_LOSES
- KFF_DEBUG (printf ("*** S_IXGRP in change_mode().\n"));
-#else /* ! EXECUTE_PERMISSION_LOSES */
- mode |= S_IXGRP;
-#endif /* EXECUTE_PERMISSION_LOSES */
- }
- }
- else if (p[0] == 'o')
- {
- if (can_read)
- mode |= S_IROTH;
- if (can_write)
- mode |= S_IWOTH;
- if (can_execute)
- {
-#ifdef EXECUTE_PERMISSION_LOSES
- KFF_DEBUG (printf ("*** S_IXOTH in change_mode().\n"));
-#else /* ! EXECUTE_PERMISSION_LOSES */
- mode |= S_IXOTH;
-#endif /* EXECUTE_PERMISSION_LOSES */
- }
- }
- }
- /* Skip to the next field. */
- while (*p != ',' && *p != '\0')
- ++p;
- if (*p == ',')
- ++p;
- }
- if (chmod (filename, mode) < 0)
- return errno;
- return 0;
-}
-
-#endif /* CLIENT_SUPPORT or SERVER_SUPPORT */
-
-#ifdef CLIENT_SUPPORT
-
-/* The host part of CVSROOT. */
-static char *server_host;
-/* The user part of CVSROOT */
-static char *server_user;
-/* The repository part of CVSROOT. */
-static char *server_cvsroot;
-
-int client_active;
-
-int client_prune_dirs;
-
-/* Set server_host and server_cvsroot. */
-static void
-parse_cvsroot ()
-{
- char *p;
-
- server_host = xstrdup (CVSroot);
- server_cvsroot = strchr (server_host, ':');
- *server_cvsroot = '\0';
- ++server_cvsroot;
-
- if ( (p = strchr (server_host, '@')) == NULL) {
- server_user = NULL;
- } else {
- server_user = server_host;
- server_host = p;
- ++server_host;
- *p = '\0';
- }
-
- client_active = 1;
-}
-
-/* Stream to write to the server. */
-FILE *to_server;
-/* Stream to read from the server. */
-FILE *from_server;
-
-#if ! RSH_NOT_TRANSPARENT
-/* Process ID of rsh subprocess. */
-static int rsh_pid = -1;
-#endif /* ! RSH_NOT_TRANSPARENT */
-
-
-/*
- * Read a line from the server.
- *
- * Space for the result is malloc'd and should be freed by the caller.
- *
- * Returns number of bytes read. If EOF_OK, then return 0 on end of file,
- * else end of file is an error.
- */
-static int
-read_line (resultp, eof_ok)
- char **resultp;
- int eof_ok;
-{
- int c;
- char *result;
- int input_index = 0;
- int result_size = 80;
-
- fflush (to_server);
- result = (char *) xmalloc (result_size);
-
- while (1)
- {
- c = getc (from_server);
-
- if (c == EOF)
- {
- free (result);
- if (ferror (from_server))
- error (1, errno, "reading from server");
- /* It's end of file. */
- if (eof_ok)
- return 0;
- else
- error (1, 0, "premature end of file from server");
- }
-
- if (c == '\n')
- break;
-
- result[input_index++] = c;
- while (input_index + 1 >= result_size)
- {
- result_size *= 2;
- result = (char *) xrealloc (result, result_size);
- }
- }
-
- if (resultp)
- *resultp = result;
-
- /* Terminate it just for kicks, but we *can* deal with embedded NULs. */
- result[input_index] = '\0';
-
- if (resultp == NULL)
- free (result);
- return input_index;
-}
-
-#endif /* CLIENT_SUPPORT */
-
-
-#if defined(CLIENT_SUPPORT) || defined(SERVER_SUPPORT)
-
-/*
- * Zero if compression isn't supported or requested; non-zero to indicate
- * a compression level to request from gzip.
- */
-int gzip_level;
-
-int filter_through_gzip (fd, dir, level, pidp)
- int fd, dir, level;
- pid_t *pidp;
-{
- static char buf[5] = "-";
- static char *gzip_argv[3] = { "gzip", buf };
-
- sprintf (buf+1, "%d", level);
- return filter_stream_through_program (fd, dir, &gzip_argv[0], pidp);
-}
-
-int filter_through_gunzip (fd, dir, pidp)
- int fd, dir;
- pid_t *pidp;
-{
- static char *gunzip_argv[2] = { "gunzip" };
- return filter_stream_through_program (fd, dir, &gunzip_argv[0], pidp);
-}
-
-#endif /* CLIENT_SUPPORT or SERVER_SUPPORT */
-
-#ifdef CLIENT_SUPPORT
-
-/*
- * The Repository for the top level of this command (not necessarily
- * the CVSROOT, just the current directory at the time we do it).
- */
-static char *toplevel_repos;
-
-/* Working directory when we first started. */
-char toplevel_wd[PATH_MAX];
-
-static void
-handle_ok (args, len)
- char *args;
- int len;
-{
- return;
-}
-
-static void
-handle_error (args, len)
- char *args;
- int len;
-{
- int something_printed;
-
- /*
- * First there is a symbolic error code followed by a space, which
- * we ignore.
- */
- char *p = strchr (args, ' ');
- if (p == NULL)
- {
- error (0, 0, "invalid data from cvs server");
- return;
- }
- ++p;
- len -= p - args;
- something_printed = 0;
- for (; len > 0; --len)
- {
- something_printed = 1;
- putc (*p++, stderr);
- }
- if (something_printed)
- putc ('\n', stderr);
-}
-
-static void
-handle_valid_requests (args, len)
- char *args;
- int len;
-{
- char *p = args;
- char *q;
- struct request *rq;
- do
- {
- q = strchr (p, ' ');
- if (q != NULL)
- *q++ = '\0';
- for (rq = requests; rq->name != NULL; ++rq)
- {
- if (strcmp (rq->name, p) == 0)
- break;
- }
- if (rq->name == NULL)
- /*
- * It is a request we have never heard of (and thus never
- * will want to use). So don't worry about it.
- */
- ;
- else
- {
- if (rq->status == rq_enableme)
- {
- /*
- * Server wants to know if we have this, to enable the
- * feature.
- */
- if (fprintf(to_server, "%s\n", rq->name) < 0)
- error (1, errno, "writing to server");
- if (!strcmp("UseUnchanged",rq->name))
- use_unchanged = 1;
- }
- else
- rq->status = rq_supported;
- }
- p = q;
- } while (q != NULL);
- for (rq = requests; rq->name != NULL; ++rq)
- {
- if (rq->status == rq_essential)
- error (1, 0, "request `%s' not supported by server", rq->name);
- else if (rq->status == rq_optional)
- rq->status = rq_not_supported;
- }
-}
-
-static int use_directory = -1;
-
-static char *get_short_pathname PROTO((const char *));
-
-static char *
-get_short_pathname (name)
- const char *name;
-{
- const char *retval;
- if (use_directory)
- return (char *) name;
- if (strncmp (name, toplevel_repos, strlen (toplevel_repos)) != 0)
- error (1, 0, "server bug: name `%s' doesn't specify file in `%s'",
- name, toplevel_repos);
- retval = name + strlen (toplevel_repos) + 1;
- if (retval[-1] != '/')
- error (1, 0, "server bug: name `%s' doesn't specify file in `%s'",
- name, toplevel_repos);
- return (char *) retval;
-}
-
-/*
- * Do all the processing for PATHNAME, where pathname consists of the
- * repository and the filename. The parameters we pass to FUNC are:
- * DATA is just the DATA parameter which was passed to
- * call_in_directory; ENT_LIST is a pointer to an entries list (which
- * we manage the storage for); SHORT_PATHNAME is the pathname of the
- * file relative to the (overall) directory in which the command is
- * taking place; and FILENAME is the filename portion only of
- * SHORT_PATHNAME. When we call FUNC, the curent directory points to
- * the directory portion of SHORT_PATHNAME. */
-
-static char *last_dirname;
-
-static void
-call_in_directory (pathname, func, data)
- char *pathname;
- void (*func) PROTO((char *data, List *ent_list, char *short_pathname,
- char *filename));
- char *data;
-{
- static List *last_entries;
-
- char *dirname;
- char *filename;
- /* Just the part of pathname relative to toplevel_repos. */
- char *short_pathname = get_short_pathname (pathname);
- char *p;
-
- /*
- * Do the whole descent in parallel for the repositories, so we
- * know what to put in CVS/Repository files. I'm not sure the
- * full hair is necessary since the server does a similar
- * computation; I suspect that we only end up creating one
- * directory at a time anyway.
- *
- * Also note that we must *only* worry about this stuff when we
- * are creating directories; `cvs co foo/bar; cd foo/bar; cvs co
- * CVSROOT; cvs update' is legitimate, but in this case
- * foo/bar/CVSROOT/CVS/Repository is not a subdirectory of
- * foo/bar/CVS/Repository.
- */
- char *reposname;
- char *short_repos;
- char *reposdirname;
- char *rdirp;
- int reposdirname_absolute;
-
- reposname = NULL;
- if (use_directory)
- read_line (&reposname, 0);
-
- reposdirname_absolute = 0;
- if (reposname != NULL)
- {
- if (strncmp (reposname, toplevel_repos, strlen (toplevel_repos)) != 0)
- {
- reposdirname_absolute = 1;
- short_repos = reposname;
- }
- else
- {
- short_repos = reposname + strlen (toplevel_repos) + 1;
- if (short_repos[-1] != '/')
- {
- reposdirname_absolute = 1;
- short_repos = reposname;
- }
- }
- }
- else
- {
- short_repos = short_pathname;
- }
- reposdirname = xstrdup (short_repos);
- p = strrchr (reposdirname, '/');
- if (p == NULL)
- {
- reposdirname = xrealloc (reposdirname, 2);
- reposdirname[0] = '.'; reposdirname[1] = '\0';
- }
- else
- *p = '\0';
-
- dirname = xstrdup (short_pathname);
- p = strrchr (dirname, '/');
- if (p == NULL)
- {
- dirname = xrealloc (dirname, 2);
- dirname[0] = '.'; dirname[1] = '\0';
- }
- else
- *p = '\0';
- if (client_prune_dirs)
- add_prune_candidate (dirname);
-
- filename = strrchr (short_repos, '/');
- if (filename == NULL)
- filename = short_repos;
- else
- ++filename;
-
- if (reposname != NULL)
- {
- /* This is the use_directory case. */
-
- short_pathname = xmalloc (strlen (pathname) + strlen (filename) + 5);
- strcpy (short_pathname, pathname);
- strcat (short_pathname, filename);
- }
-
- if (last_dirname == NULL
- || strcmp (last_dirname, dirname) != 0)
- {
- if (last_dirname)
- free (last_dirname);
- last_dirname = dirname;
-
- if (toplevel_wd[0] == '\0')
- if (getwd (toplevel_wd) == NULL)
- error (1, 0,
- "could not get working directory: %s", toplevel_wd);
-
- if (chdir (toplevel_wd) < 0)
- error (1, errno, "could not chdir to %s", toplevel_wd);
- if (chdir (dirname) < 0)
- {
- char *dir;
- char *dirp;
-
- if (! existence_error (errno))
- error (1, errno, "could not chdir to %s", dirname);
-
- /* Directory does not exist, we need to create it. */
- dir = xmalloc (strlen (dirname) + 1);
- dirp = dirname;
- rdirp = reposdirname;
-
- /* This algorithm makes nested directories one at a time
- and create CVS administration files in them. For
- example, we're checking out foo/bar/baz from the
- repository:
-
- 1) create foo, point CVS/Repository to <root>/foo
- 2) .. foo/bar .. <root>/foo/bar
- 3) .. foo/bar/baz .. <root>/foo/bar/baz
-
- As you can see, we're just stepping along DIRNAME (with
- DIRP) and REPOSDIRNAME (with RDIRP) respectively.
-
- We need to be careful when we are checking out a
- module, however, since DIRNAME and REPOSDIRNAME are not
- going to be the same. Since modules will not have any
- slashes in their names, we should watch the output of
- STRCHR to decide whether or not we should use STRCHR on
- the RDIRP. That is, if we're down to a module name,
- don't keep picking apart the repository directory name. */
-
- do
- {
- dirp = strchr (dirp, '/');
- if (dirp)
- {
- strncpy (dir, dirname, dirp - dirname);
- dir[dirp - dirname] = '\0';
- /* Skip the slash. */
- ++dirp;
- if (rdirp == NULL)
- error (0, 0,
- "internal error: repository string too short.");
- else
- rdirp = strchr (rdirp, '/');
- }
- else
- {
- /* If there are no more slashes in the dir name,
- we're down to the most nested directory -OR- to
- the name of a module. In the first case, we
- should be down to a DIRP that has no slashes,
- so it won't help/hurt to do another STRCHR call
- on DIRP. It will definitely hurt, however, if
- we're down to a module name, since a module
- name can point to a nested directory (that is,
- DIRP will still have slashes in it. Therefore,
- we should set it to NULL so the routine below
- copies the contents of REMOTEDIRNAME onto the
- root repository directory (does this if rdirp
- is set to NULL, because we used to do an extra
- STRCHR call here). */
-
- rdirp = NULL;
- strcpy (dir, dirname);
- }
-
- if (CVS_MKDIR (dir, 0777) < 0)
- {
- /* Now, let me get this straight. In IBM C/C++
- * under OS/2, the error string for EEXIST is:
- *
- * "The file already exists",
- *
- * and the error string for EACCESS is:
- *
- * "The file or directory specified is read-only".
- *
- * Nonetheless, mkdir() will set EACCESS if the
- * directory *exists*, according both to the
- * documentation and its actual behavior.
- *
- * I'm sure that this made sense, to someone,
- * somewhere, sometime. Just not me, here, now.
- */
-#ifdef EACCESS
- if ((errno != EACCESS) && (errno != EEXIST))
- error (1, errno, "cannot make directory %s", dir);
-#else /* ! defined(EACCESS) */
- if ((errno != EEXIST))
- error (1, errno, "cannot make directory %s", dir);
-#endif /* defined(EACCESS) */
-
- /* It already existed, fine. Just keep going. */
- }
- else if (strcmp (command_name, "export") == 0)
- /* Don't create CVSADM directories if this is export. */
- ;
- else
- {
- /*
- * Put repository in CVS/Repository. For historical
- * (pre-CVS/Root) reasons, this is an absolute pathname,
- * but what really matters is the part of it which is
- * relative to cvsroot.
- */
- char *repo;
- char *r;
-
- repo = xmalloc (strlen (reposdirname)
- + strlen (toplevel_repos)
- + 80);
- if (reposdirname_absolute)
- r = repo;
- else
- {
- strcpy (repo, toplevel_repos);
- strcat (repo, "/");
- r = repo + strlen (repo);
- }
-
- if (rdirp)
- {
- strncpy (r, reposdirname, rdirp - reposdirname);
- r[rdirp - reposdirname] = '\0';
- }
- else
- strcpy (r, reposdirname);
-
- Create_Admin (dir, dir, repo,
- (char *)NULL, (char *)NULL);
- free (repo);
- }
-
- if (rdirp != NULL)
- {
- /* Skip the slash. */
- ++rdirp;
- }
-
- } while (dirp != NULL);
- free (dir);
- /* Now it better work. */
- if (chdir (dirname) < 0)
- error (1, errno, "could not chdir to %s", dirname);
- }
-
- if (strcmp (command_name, "export") != 0)
- {
- if (last_entries)
- Entries_Close (last_entries);
- last_entries = Entries_Open (0);
- }
- }
- else
- free (dirname);
- free (reposdirname);
- (*func) (data, last_entries, short_pathname, filename);
- if (reposname != NULL)
- {
- free (short_pathname);
- free (reposname);
- }
-}
-
-static void
-copy_a_file (data, ent_list, short_pathname, filename)
- char *data;
- List *ent_list;
- char *short_pathname;
- char *filename;
-{
- char *newname;
-
- read_line (&newname, 0);
- copy_file (filename, newname);
- free (newname);
-}
-
-static void
-handle_copy_file (args, len)
- char *args;
- int len;
-{
- call_in_directory (args, copy_a_file, (char *)NULL);
-}
-
-/*
- * The Checksum response gives the checksum for the file transferred
- * over by the next Updated, Merged or Patch response. We just store
- * it here, and then check it in update_entries.
- */
-
-static int stored_checksum_valid;
-static unsigned char stored_checksum[16];
-
-static void
-handle_checksum (args, len)
- char *args;
- int len;
-{
- char *s;
- char buf[3];
- int i;
-
- if (stored_checksum_valid)
- error (1, 0, "Checksum received before last one was used");
-
- s = args;
- buf[2] = '\0';
- for (i = 0; i < 16; i++)
- {
- char *bufend;
-
- buf[0] = *s++;
- buf[1] = *s++;
- stored_checksum[i] = (char) strtol (buf, &bufend, 16);
- if (bufend != buf + 2)
- break;
- }
-
- if (i < 16 || *s != '\0')
- error (1, 0, "Invalid Checksum response: `%s'", args);
-
- stored_checksum_valid = 1;
-}
-
-/*
- * If we receive a patch, but the patch program fails to apply it, we
- * want to request the original file. We keep a list of files whose
- * patches have failed.
- */
-
-char **failed_patches;
-int failed_patches_count;
-
-struct update_entries_data
-{
- enum {
- /*
- * We are just getting an Entries line; the local file is
- * correct.
- */
- UPDATE_ENTRIES_CHECKIN,
- /* We are getting the file contents as well. */
- UPDATE_ENTRIES_UPDATE,
- /*
- * We are getting a patch against the existing local file, not
- * an entire new file.
- */
- UPDATE_ENTRIES_PATCH
- } contents;
-
- /*
- * String to put in the timestamp field or NULL to use the timestamp
- * of the file.
- */
- char *timestamp;
-};
-
-/* Update the Entries line for this file. */
-static void
-update_entries (data_arg, ent_list, short_pathname, filename)
- char *data_arg;
- List *ent_list;
- char *short_pathname;
- char *filename;
-{
- char *entries_line;
- struct update_entries_data *data = (struct update_entries_data *)data_arg;
-
- char *cp;
- char *user;
- char *vn;
- /* Timestamp field. Always empty according to the protocol. */
- char *ts;
- char *options;
- char *tag;
- char *date;
- char *tag_or_date;
- char *scratch_entries;
- int bin = 0;
-
- read_line (&entries_line, 0);
-
- /*
- * Parse the entries line.
- */
- if (strcmp (command_name, "export") != 0)
- {
- scratch_entries = xstrdup (entries_line);
-
- if (scratch_entries[0] != '/')
- error (1, 0, "bad entries line `%s' from server", entries_line);
- user = scratch_entries + 1;
- if ((cp = strchr (user, '/')) == NULL)
- error (1, 0, "bad entries line `%s' from server", entries_line);
- *cp++ = '\0';
- vn = cp;
- if ((cp = strchr (vn, '/')) == NULL)
- error (1, 0, "bad entries line `%s' from server", entries_line);
- *cp++ = '\0';
-
- ts = cp;
- if ((cp = strchr (ts, '/')) == NULL)
- error (1, 0, "bad entries line `%s' from server", entries_line);
- *cp++ = '\0';
- options = cp;
- if ((cp = strchr (options, '/')) == NULL)
- error (1, 0, "bad entries line `%s' from server", entries_line);
- *cp++ = '\0';
- tag_or_date = cp;
-
- /* If a slash ends the tag_or_date, ignore everything after it. */
- cp = strchr (tag_or_date, '/');
- if (cp != NULL)
- *cp = '\0';
- tag = (char *) NULL;
- date = (char *) NULL;
- if (*tag_or_date == 'T')
- tag = tag_or_date + 1;
- else if (*tag_or_date == 'D')
- date = tag_or_date + 1;
- }
-
- if (data->contents == UPDATE_ENTRIES_UPDATE
- || data->contents == UPDATE_ENTRIES_PATCH)
- {
- char *size_string;
- char *mode_string;
- int size;
- int size_read;
- int size_left;
- int fd;
- char *buf;
- char *buf2;
- char *temp_filename;
- int use_gzip, gzip_status;
- pid_t gzip_pid = 0;
-
- read_line (&mode_string, 0);
-
- read_line (&size_string, 0);
- if (size_string[0] == 'z')
- {
- use_gzip = 1;
- size = atoi (size_string+1);
- }
- else
- {
- use_gzip = 0;
- size = atoi (size_string);
- }
- free (size_string);
-
- temp_filename = xmalloc (strlen (filename) + 80);
-#ifdef _POSIX_NO_TRUNC
- sprintf (temp_filename, ".new.%.9s", filename);
-#else /* _POSIX_NO_TRUNC */
- sprintf (temp_filename, ".new.%s", filename);
-#endif /* _POSIX_NO_TRUNC */
- buf = xmalloc (size);
-
- /* Some systems, like OS/2 and Windows NT, end lines with CRLF
- instead of just LF. Format translation is done in the C
- library I/O funtions. Here we tell them whether or not to
- convert -- if this file is marked "binary" with the RCS -kb
- flag, then we don't want to convert, else we do (because
- CVS assumes text files by default). */
-
- bin = !(strcmp (options, "-kb"));
- fd = open (temp_filename,
- O_WRONLY | O_CREAT | O_TRUNC | (bin ? OPEN_BINARY : 0),
- 0777);
-
- if (fd < 0)
- error (1, errno, "writing %s", short_pathname);
-
- if (use_gzip)
- fd = filter_through_gunzip (fd, 0, &gzip_pid);
-
- if (size > 0)
- {
- buf2 = buf;
- size_left = size;
- while ((size_read = fread (buf2, 1, size_left, from_server)) != size_left)
- {
- if (feof (from_server))
- /* FIXME: Should delete temp_filename. */
- error (1, 0, "unexpected end of file from server");
- else if (ferror (from_server))
- /* FIXME: Should delete temp_filename. */
- error (1, errno, "reading from server");
- else
- {
- /* short reads are ok if we keep trying */
- buf2 += size_read;
- size_left -= size_read;
- }
- }
- if (write (fd, buf, size) != size)
- error (1, errno, "writing %s", short_pathname);
- }
- if (close (fd) < 0)
- error (1, errno, "writing %s", short_pathname);
- if (gzip_pid > 0)
- {
- if (waitpid (gzip_pid, &gzip_status, 0) == -1)
- error (1, errno, "waiting for gzip process %d", gzip_pid);
- else if (gzip_status != 0)
- error (1, 0, "gzip process exited %d", gzip_status);
- }
-
- gzip_pid = -1;
-
- /* Since gunzip writes files without converting LF to CRLF
- (a reasonable behavior), we now have a patch file in LF
- format. Leave the file as is if we're just going to feed
- it to patch; patch can handle it. However, if it's the
- final source file, convert it. */
-
- if (data->contents == UPDATE_ENTRIES_UPDATE)
- {
-#ifdef LINES_CRLF_TERMINATED
-
- /* `bin' is non-zero iff `options' contains "-kb", meaning
- treat this file as binary. */
-
- if (use_gzip && (! bin))
- {
- convert_file (temp_filename, O_RDONLY | OPEN_BINARY,
- filename, O_WRONLY | O_CREAT | O_TRUNC);
- if (unlink (temp_filename) < 0)
- error (0, errno, "warning: couldn't delete %s",
- temp_filename);
- }
- else
- rename_file (temp_filename, filename);
-
-#else /* ! LINES_CRLF_TERMINATED */
- rename_file (temp_filename, filename);
-#endif /* LINES_CRLF_TERMINATED */
- }
- else
- {
- int retcode;
- char backup[PATH_MAX];
- struct stat s;
-
- (void) sprintf (backup, "%s~", filename);
- (void) unlink_file (backup);
- if (!isfile (filename))
- error (1, 0, "patch original file %s does not exist",
- short_pathname);
- if (stat (temp_filename, &s) < 0)
- error (1, 1, "can't stat patch file %s", temp_filename);
- if (s.st_size == 0)
- retcode = 0;
- else
- {
- run_setup ("%s -f -s -b ~ %s %s", PATCH_PROGRAM,
- filename, temp_filename);
- retcode = run_exec (DEVNULL, RUN_TTY, RUN_TTY, RUN_NORMAL);
- }
- /* FIXME: should we really be silently ignoring errors? */
- (void) unlink_file (temp_filename);
- if (retcode == 0)
- {
- /* FIXME: should we really be silently ignoring errors? */
- (void) unlink_file (backup);
- }
- else
- {
- int old_errno = errno;
- char *path_tmp;
-
- if (isfile (backup))
- rename_file (backup, filename);
-
- /* Get rid of the patch reject file. */
- path_tmp = xmalloc (strlen (filename + 10));
- strcpy (path_tmp, filename);
- strcat (path_tmp, ".rej");
- /* FIXME: should we really be silently ignoring errors? */
- (void) unlink_file (path_tmp);
- free (path_tmp);
-
- /* Save this file to retrieve later. */
- failed_patches =
- (char **) xrealloc ((char *) failed_patches,
- ((failed_patches_count + 1)
- * sizeof (char *)));
- failed_patches[failed_patches_count] =
- xstrdup (short_pathname);
- ++failed_patches_count;
-
- error (retcode == -1 ? 1 : 0, retcode == -1 ? old_errno : 0,
- "could not patch %s%s", filename,
- retcode == -1 ? "" : "; will refetch");
-
- stored_checksum_valid = 0;
-
- return;
- }
- }
- free (temp_filename);
-
- if (stored_checksum_valid)
- {
- FILE *e;
- struct MD5Context context;
- unsigned char buf[8192];
- unsigned len;
- unsigned char checksum[16];
-
- /*
- * Compute the MD5 checksum. This will normally only be
- * used when receiving a patch, so we always compute it
- * here on the final file, rather than on the received
- * data.
- *
- * Note that if the file is a text file, we should read it
- * here using text mode, so its lines will be terminated the same
- * way they were transmitted.
- */
- e = fopen (filename, "r");
- if (e == NULL)
- error (1, errno, "could not open %s", short_pathname);
-
- MD5Init (&context);
- while ((len = fread (buf, 1, sizeof buf, e)) != 0)
- MD5Update (&context, buf, len);
- if (ferror (e))
- error (1, errno, "could not read %s", short_pathname);
- MD5Final (checksum, &context);
-
- fclose (e);
-
- stored_checksum_valid = 0;
-
- if (memcmp (checksum, stored_checksum, 16) != 0)
- {
- if (data->contents != UPDATE_ENTRIES_PATCH)
- error (1, 0, "checksum failure on %s",
- short_pathname);
-
- error (0, 0,
- "checksum failure after patch to %s; will refetch",
- short_pathname);
-
- /* Save this file to retrieve later. */
- failed_patches =
- (char **) xrealloc ((char *) failed_patches,
- ((failed_patches_count + 1)
- * sizeof (char *)));
- failed_patches[failed_patches_count] =
- xstrdup (short_pathname);
- ++failed_patches_count;
-
- return;
- }
- }
-
- {
- /* FIXME: we should be respecting the umask. */
- int status = change_mode (filename, mode_string);
- if (status != 0)
- error (0, status, "cannot change mode of %s", short_pathname);
- }
-
- free (mode_string);
- free (buf);
- }
-
- /*
- * Process the entries line. Do this after we've written the file,
- * since we need the timestamp.
- */
- if (strcmp (command_name, "export") != 0)
- {
- char *local_timestamp;
- char *file_timestamp;
-
- local_timestamp = data->timestamp;
- if (local_timestamp == NULL || ts[0] == '+')
- file_timestamp = time_stamp (filename);
- else
- file_timestamp = NULL;
-
- /*
- * These special version numbers signify that it is not up to
- * date. Create a dummy timestamp which will never compare
- * equal to the timestamp of the file.
- */
- if (vn[0] == '\0' || vn[0] == '0' || vn[0] == '-')
- local_timestamp = "dummy timestamp";
- else if (local_timestamp == NULL)
- local_timestamp = file_timestamp;
-
- Register (ent_list, filename, vn, local_timestamp,
- options, tag, date, ts[0] == '+' ? file_timestamp : NULL);
-
- if (file_timestamp)
- free (file_timestamp);
-
- free (scratch_entries);
- }
- free (entries_line);
-}
-
-static void
-handle_checked_in (args, len)
- char *args;
- int len;
-{
- struct update_entries_data dat;
- dat.contents = UPDATE_ENTRIES_CHECKIN;
- dat.timestamp = NULL;
- call_in_directory (args, update_entries, (char *)&dat);
-}
-
-static void
-handle_new_entry (args, len)
- char *args;
- int len;
-{
- struct update_entries_data dat;
- dat.contents = UPDATE_ENTRIES_CHECKIN;
- dat.timestamp = "dummy timestamp from new-entry";
- call_in_directory (args, update_entries, (char *)&dat);
-}
-
-static void
-handle_updated (args, len)
- char *args;
- int len;
-{
- struct update_entries_data dat;
- dat.contents = UPDATE_ENTRIES_UPDATE;
- dat.timestamp = NULL;
- call_in_directory (args, update_entries, (char *)&dat);
-}
-
-static void
-handle_merged (args, len)
- char *args;
- int len;
-{
- struct update_entries_data dat;
- dat.contents = UPDATE_ENTRIES_UPDATE;
- dat.timestamp = "Result of merge";
- call_in_directory (args, update_entries, (char *)&dat);
-}
-
-static void
-handle_patched (args, len)
- char *args;
- int len;
-{
- struct update_entries_data dat;
- dat.contents = UPDATE_ENTRIES_PATCH;
- dat.timestamp = NULL;
- call_in_directory (args, update_entries, (char *)&dat);
-}
-
-static void
-remove_entry (data, ent_list, short_pathname, filename)
- char *data;
- List *ent_list;
- char *short_pathname;
- char *filename;
-{
- Scratch_Entry (ent_list, filename);
-}
-
-static void
-handle_remove_entry (args, len)
- char *args;
- int len;
-{
- call_in_directory (args, remove_entry, (char *)NULL);
-}
-
-static void
-remove_entry_and_file (data, ent_list, short_pathname, filename)
- char *data;
- List *ent_list;
- char *short_pathname;
- char *filename;
-{
- Scratch_Entry (ent_list, filename);
- if (unlink_file (filename) < 0)
- error (0, errno, "unable to remove %s", short_pathname);
-}
-
-static void
-handle_removed (args, len)
- char *args;
- int len;
-{
- call_in_directory (args, remove_entry_and_file, (char *)NULL);
-}
-
-/* Is this the top level (directory containing CVSROOT)? */
-static int
-is_cvsroot_level (pathname)
- char *pathname;
-{
- char *short_pathname;
-
- if (strcmp (toplevel_repos, server_cvsroot) != 0)
- return 0;
-
- if (!use_directory)
- {
- if (strncmp (pathname, server_cvsroot, strlen (server_cvsroot)) != 0)
- error (1, 0,
- "server bug: pathname `%s' doesn't specify file in `%s'",
- pathname, server_cvsroot);
- short_pathname = pathname + strlen (server_cvsroot) + 1;
- if (short_pathname[-1] != '/')
- error (1, 0,
- "server bug: pathname `%s' doesn't specify file in `%s'",
- pathname, server_cvsroot);
- return strchr (short_pathname, '/') == NULL;
- }
- else
- {
- return strchr (pathname, '/') == NULL;
- }
-}
-
-static void
-set_static (data, ent_list, short_pathname, filename)
- char *data;
- List *ent_list;
- char *short_pathname;
- char *filename;
-{
- FILE *fp;
- fp = open_file (CVSADM_ENTSTAT, "w+");
- if (fclose (fp) == EOF)
- error (1, errno, "cannot close %s", CVSADM_ENTSTAT);
-}
-
-static void
-handle_set_static_directory (args, len)
- char *args;
- int len;
-{
- if (strcmp (command_name, "export") == 0)
- {
- /* Swallow the repository. */
- read_line (NULL, 0);
- return;
- }
- call_in_directory (args, set_static, (char *)NULL);
-}
-
-static void
-clear_static (data, ent_list, short_pathname, filename)
- char *data;
- List *ent_list;
- char *short_pathname;
- char *filename;
-{
- if (unlink_file (CVSADM_ENTSTAT) < 0 && ! existence_error (errno))
- error (1, errno, "cannot remove file %s", CVSADM_ENTSTAT);
-}
-
-static void
-handle_clear_static_directory (pathname, len)
- char *pathname;
- int len;
-{
- if (strcmp (command_name, "export") == 0)
- {
- /* Swallow the repository. */
- read_line (NULL, 0);
- return;
- }
-
- if (is_cvsroot_level (pathname))
- {
- /*
- * Top level (directory containing CVSROOT). This seems to normally
- * lack a CVS directory, so don't try to create files in it.
- */
- return;
- }
- call_in_directory (pathname, clear_static, (char *)NULL);
-}
-
-static void
-set_sticky (data, ent_list, short_pathname, filename)
- char *data;
- List *ent_list;
- char *short_pathname;
- char *filename;
-{
- char *tagspec;
- FILE *f;
-
- read_line (&tagspec, 0);
- f = open_file (CVSADM_TAG, "w+");
- if (fprintf (f, "%s\n", tagspec) < 0)
- error (1, errno, "writing %s", CVSADM_TAG);
- if (fclose (f) == EOF)
- error (1, errno, "closing %s", CVSADM_TAG);
- free (tagspec);
-}
-
-static void
-handle_set_sticky (pathname, len)
- char *pathname;
- int len;
-{
- if (strcmp (command_name, "export") == 0)
- {
- /* Swallow the repository. */
- read_line (NULL, 0);
- /* Swallow the tag line. */
- (void) read_line (NULL, 0);
- return;
- }
- if (is_cvsroot_level (pathname))
- {
- /*
- * Top level (directory containing CVSROOT). This seems to normally
- * lack a CVS directory, so don't try to create files in it.
- */
-
- /* Swallow the repository. */
- read_line (NULL, 0);
- /* Swallow the tag line. */
- (void) read_line (NULL, 0);
- return;
- }
-
- call_in_directory (pathname, set_sticky, (char *)NULL);
-}
-
-static void
-clear_sticky (data, ent_list, short_pathname, filename)
- char *data;
- List *ent_list;
- char *short_pathname;
- char *filename;
-{
- if (unlink_file (CVSADM_TAG) < 0 && ! existence_error (errno))
- error (1, errno, "cannot remove %s", CVSADM_TAG);
-}
-
-static void
-handle_clear_sticky (pathname, len)
- char *pathname;
- int len;
-{
- if (strcmp (command_name, "export") == 0)
- {
- /* Swallow the repository. */
- read_line (NULL, 0);
- return;
- }
-
- if (is_cvsroot_level (pathname))
- {
- /*
- * Top level (directory containing CVSROOT). This seems to normally
- * lack a CVS directory, so don't try to create files in it.
- */
- return;
- }
-
- call_in_directory (pathname, clear_sticky, (char *)NULL);
-}
-
-struct save_prog {
- char *name;
- char *dir;
- struct save_prog *next;
-};
-
-static struct save_prog *checkin_progs;
-static struct save_prog *update_progs;
-
-/*
- * Unlike some requests this doesn't include the repository. So we can't
- * just call call_in_directory and have the right thing happen; we save up
- * the requests and do them at the end.
- */
-static void
-handle_set_checkin_prog (args, len)
- char *args;
- int len;
-{
- char *prog;
- struct save_prog *p;
- read_line (&prog, 0);
- p = (struct save_prog *) xmalloc (sizeof (struct save_prog));
- p->next = checkin_progs;
- p->dir = xstrdup (args);
- p->name = prog;
- checkin_progs = p;
-}
-
-static void
-handle_set_update_prog (args, len)
- char *args;
- int len;
-{
- char *prog;
- struct save_prog *p;
- read_line (&prog, 0);
- p = (struct save_prog *) xmalloc (sizeof (struct save_prog));
- p->next = update_progs;
- p->dir = xstrdup (args);
- p->name = prog;
- update_progs = p;
-}
-
-static void do_deferred_progs PROTO((void));
-
-static void
-do_deferred_progs ()
-{
- struct save_prog *p;
- struct save_prog *q;
-
- char fname[PATH_MAX];
- FILE *f;
- if (toplevel_wd[0] != '\0')
- {
- if (chdir (toplevel_wd) < 0)
- error (1, errno, "could not chdir to %s", toplevel_wd);
- }
- for (p = checkin_progs; p != NULL; )
- {
- sprintf (fname, "%s/%s", p->dir, CVSADM_CIPROG);
- f = open_file (fname, "w");
- if (fprintf (f, "%s\n", p->name) < 0)
- error (1, errno, "writing %s", fname);
- if (fclose (f) == EOF)
- error (1, errno, "closing %s", fname);
- free (p->name);
- free (p->dir);
- q = p->next;
- free (p);
- p = q;
- }
- checkin_progs = NULL;
- for (p = update_progs; p != NULL; p = p->next)
- {
- sprintf (fname, "%s/%s", p->dir, CVSADM_UPROG);
- f = open_file (fname, "w");
- if (fprintf (f, "%s\n", p->name) < 0)
- error (1, errno, "writing %s", fname);
- if (fclose (f) == EOF)
- error (1, errno, "closing %s", fname);
- free (p->name);
- free (p->dir);
- free (p);
- }
- update_progs = NULL;
-}
-
-static int client_isemptydir PROTO((char *));
-
-/*
- * Returns 1 if the argument directory exists and is completely empty,
- * other than the existence of the CVS directory entry. Zero otherwise.
- */
-static int
-client_isemptydir (dir)
- char *dir;
-{
- DIR *dirp;
- struct dirent *dp;
-
- if ((dirp = opendir (dir)) == NULL)
- {
- if (! existence_error (errno))
- error (0, errno, "cannot open directory %s for empty check", dir);
- return (0);
- }
- errno = 0;
- while ((dp = readdir (dirp)) != NULL)
- {
- if (strcmp (dp->d_name, ".") != 0 && strcmp (dp->d_name, "..") != 0 &&
- strcmp (dp->d_name, CVSADM) != 0)
- {
- (void) closedir (dirp);
- return (0);
- }
- }
- if (errno != 0)
- {
- error (0, errno, "cannot read directory %s", dir);
- (void) closedir (dirp);
- return (0);
- }
- (void) closedir (dirp);
- return (1);
-}
-
-struct save_dir {
- char *dir;
- struct save_dir *next;
-};
-
-struct save_dir *prune_candidates;
-
-static void
-add_prune_candidate (dir)
- char *dir;
-{
- struct save_dir *p;
-
- if (dir[0] == '.' && dir[1] == '\0')
- return;
- p = (struct save_dir *) xmalloc (sizeof (struct save_dir));
- p->dir = xstrdup (dir);
- p->next = prune_candidates;
- prune_candidates = p;
-}
-
-static void process_prune_candidates PROTO((void));
-
-static void
-process_prune_candidates ()
-{
- struct save_dir *p;
- struct save_dir *q;
-
- if (toplevel_wd[0] != '\0')
- {
- if (chdir (toplevel_wd) < 0)
- error (1, errno, "could not chdir to %s", toplevel_wd);
- }
- for (p = prune_candidates; p != NULL; )
- {
- if (client_isemptydir (p->dir))
- {
- unlink_file_dir (p->dir);
- }
- free (p->dir);
- q = p->next;
- free (p);
- p = q;
- }
-}
-
-/* Send a Repository line. */
-
-static char *last_repos;
-static char *last_update_dir;
-
-static void send_repository PROTO((char *, char *, char *));
-
-static void
-send_repository (dir, repos, update_dir)
- char *dir;
- char *repos;
- char *update_dir;
-{
- char *adm_name;
-
- if (update_dir == NULL || update_dir[0] == '\0')
- update_dir = ".";
-
- if (last_repos != NULL
- && strcmp (repos, last_repos) == 0
- && last_update_dir != NULL
- && strcmp (update_dir, last_update_dir) == 0)
- /* We've already sent it. */
- return;
-
- if (client_prune_dirs)
- add_prune_candidate (update_dir);
-
- /* 80 is large enough for any of CVSADM_*. */
- adm_name = xmalloc (strlen (dir) + 80);
-
- if (use_directory == -1)
- use_directory = supported_request ("Directory");
-
- if (use_directory)
- {
- if (fprintf (to_server, "Directory ") < 0)
- error (1, errno, "writing to server");
- if (fprintf (to_server, "%s", update_dir) < 0)
- error (1, errno, "writing to server");
-
- if (fprintf (to_server, "\n%s\n", repos)
- < 0)
- error (1, errno, "writing to server");
- }
- else
- {
- if (fprintf (to_server, "Repository %s\n", repos) < 0)
- error (1, errno, "writing to server");
- }
- if (supported_request ("Static-directory"))
- {
- adm_name[0] = '\0';
- if (dir[0] != '\0')
- {
- strcat (adm_name, dir);
- strcat (adm_name, "/");
- }
- strcat (adm_name, CVSADM_ENTSTAT);
- if (isreadable (adm_name))
- {
- if (fprintf (to_server, "Static-directory\n") < 0)
- error (1, errno, "writing to server");
- }
- }
- if (supported_request ("Sticky"))
- {
- FILE *f;
- if (dir[0] == '\0')
- strcpy (adm_name, CVSADM_TAG);
- else
- sprintf (adm_name, "%s/%s", dir, CVSADM_TAG);
-
- f = fopen (adm_name, "r");
- if (f == NULL)
- {
- if (! existence_error (errno))
- error (1, errno, "reading %s", adm_name);
- }
- else
- {
- char line[80];
- char *nl;
- if (fprintf (to_server, "Sticky ") < 0)
- error (1, errno, "writing to server");
- while (fgets (line, sizeof (line), f) != NULL)
- {
- if (fprintf (to_server, "%s", line) < 0)
- error (1, errno, "writing to server");
- nl = strchr (line, '\n');
- if (nl != NULL)
- break;
- }
- if (nl == NULL)
- if (fprintf (to_server, "\n") < 0)
- error (1, errno, "writing to server");
- if (fclose (f) == EOF)
- error (0, errno, "closing %s", adm_name);
- }
- }
- if (supported_request ("Checkin-prog"))
- {
- FILE *f;
- if (dir[0] == '\0')
- strcpy (adm_name, CVSADM_CIPROG);
- else
- sprintf (adm_name, "%s/%s", dir, CVSADM_CIPROG);
-
- f = fopen (adm_name, "r");
- if (f == NULL)
- {
- if (! existence_error (errno))
- error (1, errno, "reading %s", adm_name);
- }
- else
- {
- char line[80];
- char *nl;
- if (fprintf (to_server, "Checkin-prog ") < 0)
- error (1, errno, "writing to server");
- while (fgets (line, sizeof (line), f) != NULL)
- {
- if (fprintf (to_server, "%s", line) < 0)
- error (1, errno, "writing to server");
- nl = strchr (line, '\n');
- if (nl != NULL)
- break;
- }
- if (nl == NULL)
- if (fprintf (to_server, "\n") < 0)
- error (1, errno, "writing to server");
- if (fclose (f) == EOF)
- error (0, errno, "closing %s", adm_name);
- }
- }
- if (supported_request ("Update-prog"))
- {
- FILE *f;
- if (dir[0] == '\0')
- strcpy (adm_name, CVSADM_UPROG);
- else
- sprintf (adm_name, "%s/%s", dir, CVSADM_UPROG);
-
- f = fopen (adm_name, "r");
- if (f == NULL)
- {
- if (! existence_error (errno))
- error (1, errno, "reading %s", adm_name);
- }
- else
- {
- char line[80];
- char *nl;
- if (fprintf (to_server, "Update-prog ") < 0)
- error (1, errno, "writing to server");
- while (fgets (line, sizeof (line), f) != NULL)
- {
- if (fprintf (to_server, "%s", line) < 0)
- error (1, errno, "writing to server");
- nl = strchr (line, '\n');
- if (nl != NULL)
- break;
- }
- if (nl == NULL)
- if (fprintf (to_server, "\n") < 0)
- error (1, errno, "writing to server");
- if (fclose (f) == EOF)
- error (0, errno, "closing %s", adm_name);
- }
- }
- if (last_repos != NULL)
- free (last_repos);
- if (last_update_dir != NULL)
- free (last_update_dir);
- last_repos = xstrdup (repos);
- last_update_dir = xstrdup (update_dir);
-}
-
-/* Send a Repository line and set toplevel_repos. */
-static void send_a_repository PROTO((char *, char *, char *));
-
-static void
-send_a_repository (dir, repository, update_dir)
- char *dir;
- char *repository;
- char *update_dir;
-{
- if (toplevel_repos == NULL && repository != NULL)
- {
- if (update_dir[0] == '\0'
- || (update_dir[0] == '.' && update_dir[1] == '\0'))
- toplevel_repos = xstrdup (repository);
- else
- {
- /*
- * Get the repository from a CVS/Repository file if update_dir
- * is absolute. This is not correct in general, because
- * the CVS/Repository file might not be the top-level one.
- * This is for cases like "cvs update /foo/bar" (I'm not
- * sure it matters what toplevel_repos we get, but it does
- * matter that we don't hit the "internal error" code below).
- */
- if (update_dir[0] == '/')
- toplevel_repos = Name_Repository (update_dir, update_dir);
- else
- {
- /*
- * Guess the repository of that directory by looking at a
- * subdirectory and removing as many pathname components
- * as are in update_dir. I think that will always (or at
- * least almost always) be 1.
- *
- * So this deals with directories which have been
- * renamed, though it doesn't necessarily deal with
- * directories which have been put inside other
- * directories (and cvs invoked on the containing
- * directory). I'm not sure the latter case needs to
- * work.
- */
- /*
- * This gets toplevel_repos wrong for "cvs update ../foo"
- * but I'm not sure toplevel_repos matters in that case.
- */
- int slashes_in_update_dir;
- int slashes_skipped;
- char *p;
-
- slashes_in_update_dir = 0;
- for (p = update_dir; *p != '\0'; ++p)
- if (*p == '/')
- ++slashes_in_update_dir;
-
- slashes_skipped = 0;
- p = repository + strlen (repository);
- while (1)
- {
- if (p == repository)
- error (1, 0,
- "internal error: not enough slashes in %s",
- repository);
- if (*p == '/')
- ++slashes_skipped;
- if (slashes_skipped < slashes_in_update_dir + 1)
- --p;
- else
- break;
- }
- toplevel_repos = xmalloc (p - repository + 1);
- /* Note that we don't copy the trailing '/'. */
- strncpy (toplevel_repos, repository, p - repository);
- toplevel_repos[p - repository] = '\0';
- }
- }
- }
-
- send_repository (dir, repository, update_dir);
-}
-
-static int modules_count;
-static int modules_allocated;
-static char **modules_vector;
-
-static void
-handle_module_expansion (args, len)
- char *args;
- int len;
-{
- if (modules_vector == NULL)
- {
- modules_allocated = 1; /* Small for testing */
- modules_vector = (char **) xmalloc
- (modules_allocated * sizeof (modules_vector[0]));
- }
- else if (modules_count >= modules_allocated)
- {
- modules_allocated *= 2;
- modules_vector = (char **) xrealloc
- ((char *) modules_vector,
- modules_allocated * sizeof (modules_vector[0]));
- }
- modules_vector[modules_count] = xmalloc (strlen (args) + 1);
- strcpy (modules_vector[modules_count], args);
- ++modules_count;
-}
-
-void
-client_expand_modules (argc, argv, local)
- int argc;
- char **argv;
- int local;
-{
- int errs;
- int i;
-
- for (i = 0; i < argc; ++i)
- send_arg (argv[i]);
- send_a_repository ("", server_cvsroot, "");
- if (fprintf (to_server, "expand-modules\n") < 0)
- error (1, errno, "writing to server");
- errs = get_server_responses ();
- if (last_repos != NULL)
- free (last_repos);
- last_repos = NULL;
- if (last_update_dir != NULL)
- free (last_update_dir);
- last_update_dir = NULL;
- if (errs)
- error (errs, 0, "");
-}
-
-void
-client_send_expansions (local)
- int local;
-{
- int i;
- char *argv[1];
- for (i = 0; i < modules_count; ++i)
- {
- argv[0] = modules_vector[i];
- if (isfile (argv[0]))
- send_files (1, argv, local, 0);
- else
- send_file_names (1, argv);
- }
- send_a_repository ("", server_cvsroot, "");
-}
-
-void
-client_nonexpanded_setup ()
-{
- send_a_repository ("", server_cvsroot, "");
-}
-
-static void
-handle_m (args, len)
- char *args;
- int len;
-{
- fwrite (args, len, sizeof (*args), stdout);
- putc ('\n', stdout);
-}
-
-static void
-handle_e (args, len)
- char *args;
- int len;
-{
- fwrite (args, len, sizeof (*args), stderr);
- putc ('\n', stderr);
-}
-
-#endif /* CLIENT_SUPPORT */
-#if defined(CLIENT_SUPPORT) || defined(SERVER_SUPPORT)
-
-/* This table must be writeable if the server code is included. */
-struct response responses[] =
-{
-#ifdef CLIENT_SUPPORT
-#define RSP_LINE(n, f, t, s) {n, f, t, s}
-#else /* ! CLIENT_SUPPORT */
-#define RSP_LINE(n, f, t, s) {n, s}
-#endif /* CLIENT_SUPPORT */
-
- RSP_LINE("ok", handle_ok, response_type_ok, rs_essential),
- RSP_LINE("error", handle_error, response_type_error, rs_essential),
- RSP_LINE("Valid-requests", handle_valid_requests, response_type_normal,
- rs_essential),
- RSP_LINE("Checked-in", handle_checked_in, response_type_normal,
- rs_essential),
- RSP_LINE("New-entry", handle_new_entry, response_type_normal, rs_optional),
- RSP_LINE("Checksum", handle_checksum, response_type_normal, rs_optional),
- RSP_LINE("Copy-file", handle_copy_file, response_type_normal, rs_optional),
- RSP_LINE("Updated", handle_updated, response_type_normal, rs_essential),
- RSP_LINE("Merged", handle_merged, response_type_normal, rs_essential),
- RSP_LINE("Patched", handle_patched, response_type_normal, rs_optional),
- RSP_LINE("Removed", handle_removed, response_type_normal, rs_essential),
- RSP_LINE("Remove-entry", handle_remove_entry, response_type_normal,
- rs_optional),
- RSP_LINE("Set-static-directory", handle_set_static_directory,
- response_type_normal,
- rs_optional),
- RSP_LINE("Clear-static-directory", handle_clear_static_directory,
- response_type_normal,
- rs_optional),
- RSP_LINE("Set-sticky", handle_set_sticky, response_type_normal,
- rs_optional),
- RSP_LINE("Clear-sticky", handle_clear_sticky, response_type_normal,
- rs_optional),
- RSP_LINE("Set-checkin-prog", handle_set_checkin_prog, response_type_normal,
- rs_optional),
- RSP_LINE("Set-update-prog", handle_set_update_prog, response_type_normal,
- rs_optional),
- RSP_LINE("Module-expansion", handle_module_expansion, response_type_normal,
- rs_optional),
- RSP_LINE("M", handle_m, response_type_normal, rs_essential),
- RSP_LINE("E", handle_e, response_type_normal, rs_essential),
- /* Possibly should be response_type_error. */
- RSP_LINE(NULL, NULL, response_type_normal, rs_essential)
-
-#undef RSP_LINE
-};
-
-#endif /* CLIENT_SUPPORT or SERVER_SUPPORT */
-#ifdef CLIENT_SUPPORT
-
-/*
- * Get some server responses and process them. Returns nonzero for
- * error, 0 for success.
- */
-int
-get_server_responses ()
-{
- struct response *rs;
- do
- {
- char *cmd;
- int len;
-
- len = read_line (&cmd, 0);
- for (rs = responses; rs->name != NULL; ++rs)
- if (strncmp (cmd, rs->name, strlen (rs->name)) == 0)
- {
- int cmdlen = strlen (rs->name);
- if (cmd[cmdlen] == '\0')
- ;
- else if (cmd[cmdlen] == ' ')
- ++cmdlen;
- else
- /*
- * The first len characters match, but it's a different
- * response. e.g. the response is "oklahoma" but we
- * matched "ok".
- */
- continue;
- (*rs->func) (cmd + cmdlen, len - cmdlen);
- break;
- }
- if (rs->name == NULL)
- /* It's OK to print just to the first '\0'. */
- error (0, 0,
- "warning: unrecognized response `%s' from cvs server",
- cmd);
- free (cmd);
- } while (rs->type == response_type_normal);
- return rs->type == response_type_error ? 1 : 0;
-}
-
-/* Get the responses and then close the connection. */
-int server_fd = -1;
-
-int
-get_responses_and_close ()
-{
- int errs = get_server_responses ();
-
- do_deferred_progs ();
-
- if (client_prune_dirs)
- process_prune_candidates ();
-
-#if defined(HAVE_KERBEROS) || defined(AUTH_CLIENT_SUPPORT)
- if (server_fd != -1)
- {
- if (shutdown (server_fd, 1) < 0)
- error (1, errno, "shutting down connection to %s", server_host);
- /*
- * In this case, both sides of the net connection will use the
- * same fd.
- */
- if (fileno (from_server) != fileno (to_server))
- {
- if (fclose (to_server) != 0)
- error (1, errno, "closing down connection to %s", server_host);
- }
- }
- else
-#endif /* HAVE_KERBEROS || AUTH_CLIENT_SUPPORT */
-
-#ifdef SHUTDOWN_SERVER
- SHUTDOWN_SERVER (fileno (to_server));
-#else /* ! SHUTDOWN_SERVER */
- {
-
-#ifdef START_RSH_WITH_POPEN_RW
- if (pclose (to_server) == EOF)
-#else /* ! START_RSH_WITH_POPEN_RW */
- if (fclose (to_server) == EOF)
-#endif /* START_RSH_WITH_POPEN_RW */
- {
- error (1, errno, "closing connection to %s", server_host);
- }
- }
-
- if (getc (from_server) != EOF)
- error (0, 0, "dying gasps from %s unexpected", server_host);
- else if (ferror (from_server))
- error (0, errno, "reading from %s", server_host);
-
- fclose (from_server);
-#endif /* SHUTDOWN_SERVER */
-
-#if ! RSH_NOT_TRANSPARENT
- if (rsh_pid != -1
- && waitpid (rsh_pid, (int *) 0, 0) == -1)
- if (errno != ECHILD)
- error (1, errno, "waiting for process %d", rsh_pid);
-#endif /* ! RSH_NOT_TRANSPARENT */
-
- return errs;
-}
-
-#ifndef RSH_NOT_TRANSPARENT
-static void start_rsh_server PROTO((int *, int *));
-#endif /* RSH_NOT_TRANSPARENT */
-
-int
-supported_request (name)
- char *name;
-{
- struct request *rq;
-
- for (rq = requests; rq->name; rq++)
- if (!strcmp (rq->name, name))
- return rq->status == rq_supported;
- error (1, 0, "internal error: testing support for unknown option?");
-}
-
-
-#ifdef AUTH_CLIENT_SUPPORT
-void
-init_sockaddr (name, hostname, port)
- struct sockaddr_in *name;
- const char *hostname;
- unsigned short int port;
-{
- struct hostent *hostinfo;
-
- name->sin_family = AF_INET;
- name->sin_port = htons (port);
- hostinfo = gethostbyname (hostname);
- if (hostinfo == NULL)
- {
- fprintf (stderr, "Unknown host %s.\n", hostname);
- exit (EXIT_FAILURE);
- }
- name->sin_addr = *(struct in_addr *) hostinfo->h_addr;
-}
-
-void
-connect_to_pserver (tofdp, fromfdp, log)
- int *tofdp, *fromfdp;
- char *log;
-{
- int sock;
- int tofd, fromfd;
- struct hostent *host;
- struct sockaddr_in client_sai;
-
- sock = socket (AF_INET, SOCK_STREAM, 0);
- if (sock == -1)
- {
- fprintf (stderr, "socket() failed\n");
- exit (1);
- }
- init_sockaddr (&client_sai, server_host, CVS_AUTH_PORT);
- connect (sock, (struct sockaddr *) &client_sai, sizeof (client_sai));
-
- /* Run the authorization mini-protocol before anything else. */
- {
- int i;
- char ch, read_buf[PATH_MAX];
- char *begin = "BEGIN AUTH REQUEST\n";
- char *repository = server_cvsroot;
- char *username = server_user;
- char *password = NULL;
- char *end = "END AUTH REQUEST\n";
-
- /* Get the password, probably from ~/.cvspass. */
- password = get_cvs_password (server_user, server_host, server_cvsroot);
-
- /* Announce that we're starting the authorization protocol. */
- write (sock, begin, strlen (begin));
-
- /* Send the data the server needs. */
- write (sock, repository, strlen (repository));
- write (sock, "\n", 1);
- write (sock, username, strlen (username));
- write (sock, "\n", 1);
- write (sock, password, strlen (password));
- write (sock, "\n", 1);
-
- /* Announce that we're ending the authorization protocol. */
- write (sock, end, strlen (end));
-
- /* Paranoia. */
- memset (password, 0, strlen (password));
-
- /* Get ACK or NACK from the server.
- *
- * We could avoid this careful read-char loop by having the ACK
- * and NACK cookies be of the same length, so we'd simply read
- * that length and see what we got. But then there'd be Yet
- * Another Protocol Requirement floating around, and someday
- * someone would make a change that breaks it and spend a hellish
- * day tracking it down. Therefore, we use "\n" to mark off the
- * end of both ACK and NACK, and we read until "\n".
- */
- ch = 0;
- memset (read_buf, 0, PATH_MAX);
- for (i = 0; (i < (PATH_MAX - 1)) && (ch != '\n'); i++)
- {
- read (sock, &ch, 1);
- read_buf[i] = ch;
- }
-
- if (strcmp (read_buf, "I HATE YOU\n") == 0)
- {
- /* Authorization not granted. */
- if (shutdown (sock, 2) < 0)
- error (1, errno, "shutdown() failed (server %s)", server_host);
- error (1, 0,
- "authorization failed: server %s rejected access",
- server_host);
- }
- else if (strcmp (read_buf, "I LOVE YOU\n") != 0)
- {
- /* Unrecognized response from server. */
- if (shutdown (sock, 2) < 0)
- error (1, errno, "shutdown() failed (server %s)", server_host);
- error (1, 0,
- "unrecognized auth response from %s: %s",
- server_host, read_buf);
- }
- /* Else authorization granted, so we can go on... */
- }
-
- /* This was stolen straight from start_kerberos_server(). */
- {
- server_fd = sock;
- close_on_exec (server_fd);
- /*
- * If we do any filtering, TOFD and FROMFD will be
- * closed. So make sure they're copies of SERVER_FD,
- * and not the same fd number.
- */
- if (log)
- {
- tofd = dup (sock);
- fromfd = dup (sock);
- }
- else
- tofd = fromfd = sock;
- }
-
- /* Hand them back to the caller. */
- *tofdp = tofd;
- *fromfdp = fromfd;
-}
-#endif /* AUTH_CLIENT_SUPPORT */
-
-
-#if HAVE_KERBEROS
-void
-start_kerberos_server (tofdp, fromfdp, log)
- int *tofdp, *fromfdp;
- char *log;
-{
- int tofd, fromfd;
-
- struct hostent *hp;
- char *hname;
- const char *realm;
- const char *portenv;
- int port;
- struct sockaddr_in sin;
- int s;
- KTEXT_ST ticket;
- int status;
-
- /*
- * We look up the host to give a better error message if it
- * does not exist. However, we then pass server_host to
- * krb_sendauth, rather than the canonical name, because
- * krb_sendauth is going to do its own canonicalization anyhow
- * and that lets us not worry about the static storage used by
- * gethostbyname.
- */
- hp = gethostbyname (server_host);
- if (hp == NULL)
- error (1, 0, "%s: unknown host", server_host);
- hname = xmalloc (strlen (hp->h_name) + 1);
- strcpy (hname, hp->h_name);
-
- realm = krb_realmofhost (hname);
-
- portenv = getenv ("CVS_CLIENT_PORT");
- if (portenv != NULL)
- {
- port = atoi (portenv);
- if (port <= 0)
- goto try_rsh_no_message;
- port = htons (port);
- }
- else
- {
- struct servent *sp;
-
- sp = getservbyname ("cvs", "tcp");
- if (sp == NULL)
- port = htons (CVS_PORT);
- else
- port = sp->s_port;
- }
-
- s = socket (AF_INET, SOCK_STREAM, 0);
- if (s < 0)
- error (1, errno, "socket");
-
- memset (&sin, 0, sizeof sin);
- sin.sin_family = AF_INET;
- sin.sin_addr.s_addr = INADDR_ANY;
- sin.sin_port = 0;
-
- if (bind (s, (struct sockaddr *) &sin, sizeof sin) < 0)
- error (1, errno, "bind");
-
- memcpy (&sin.sin_addr, hp->h_addr, hp->h_length);
- sin.sin_port = port;
-
- tofd = -1;
- if (connect (s, (struct sockaddr *) &sin, sizeof sin) < 0)
- {
- error (0, errno, "connect");
- close (s);
- }
- else
- {
- struct sockaddr_in laddr;
- int laddrlen;
- MSG_DAT msg_data;
- CREDENTIALS cred;
- Key_schedule sched;
-
- laddrlen = sizeof (laddr);
- if (getsockname (s, (struct sockaddr *) &laddr, &laddrlen) < 0)
- error (1, errno, "getsockname");
-
- /* We don't care about the checksum, and pass it as zero. */
- status = krb_sendauth (KOPT_DO_MUTUAL, s, &ticket, "rcmd",
- hname, realm, (unsigned long) 0, &msg_data,
- &cred, sched, &laddr, &sin, "KCVSV1.0");
- if (status != KSUCCESS)
- {
- error (0, 0, "kerberos: %s", krb_get_err_text(status));
- close (s);
- }
- else
- {
- server_fd = s;
- close_on_exec (server_fd);
- /*
- * If we do any filtering, TOFD and FROMFD will be
- * closed. So make sure they're copies of SERVER_FD,
- * and not the same fd number.
- */
- if (log)
- {
- tofd = dup (s);
- fromfd = dup (s);
- }
- else
- tofd = fromfd = s;
- }
- }
-
- if (tofd == -1)
- {
- error (0, 0, "trying to start server using rsh");
- try_rsh_no_message:
- server_fd = -1;
-#if ! RSH_NOT_TRANSPARENT
- start_rsh_server (&tofd, &fromfd);
-#else /* RSH_NOT_TRANSPARENT */
-#if defined (START_SERVER)
- START_SERVER (&tofd, &fromfd, getcaller (),
- server_user, server_host, server_cvsroot);
-#endif /* defined (START_SERVER) */
-#endif /* ! RSH_NOT_TRANSPARENT */
- }
- free (hname);
-
- /* Give caller the values it wants. */
- *tofdp = tofd;
- *fromfdp = fromfd;
-}
-
-#endif /* HAVE_KERBEROS */
-
-/* Contact the server. */
-void
-start_server ()
-{
- int tofd, fromfd;
- char *log = getenv ("CVS_CLIENT_LOG");
-
-#if HAVE_KERBEROS
- start_kerberos_server (&tofd, &fromfd, log);
-
-#else /* ! HAVE_KERBEROS */
-
-#ifdef AUTH_CLIENT_SUPPORT
- if (use_authenticating_server)
- {
- connect_to_pserver (&tofd, &fromfd, log);
- }
- else
-#endif /* AUTH_CLIENT_SUPPORT */
- {
-#if ! RSH_NOT_TRANSPARENT
- start_rsh_server (&tofd, &fromfd);
-#else /* RSH_NOT_TRANSPARENT */
-
-#if defined(START_SERVER)
- START_SERVER (&tofd, &fromfd, getcaller (),
- server_user, server_host, server_cvsroot);
-#endif /* defined(START_SERVER) */
-#endif /* ! RSH_NOT_TRANSPARENT */
- }
-#endif /* HAVE_KERBEROS */
-
- /* todo: some OS's don't need these calls... */
- close_on_exec (tofd);
- close_on_exec (fromfd);
-
- if (log)
- {
- int len = strlen (log);
- char *buf = xmalloc (5 + len);
- char *p;
- static char *teeprog[3] = { "tee" };
-
- teeprog[1] = buf;
- strcpy (buf, log);
- p = buf + len;
-
- strcpy (p, ".in");
- tofd = filter_stream_through_program (tofd, 0, teeprog, 0);
-
- strcpy (p, ".out");
- fromfd = filter_stream_through_program (fromfd, 1, teeprog, 0);
-
- free (buf);
- }
-
- /* These will use binary mode on systems which have it. */
- to_server = fdopen (tofd, FOPEN_BINARY_WRITE);
- if (to_server == NULL)
- error (1, errno, "cannot fdopen %d for write", tofd);
- from_server = fdopen (fromfd, FOPEN_BINARY_READ);
- if (from_server == NULL)
- error (1, errno, "cannot fdopen %d for read", fromfd);
-
- /* Clear static variables. */
- if (toplevel_repos != NULL)
- free (toplevel_repos);
- toplevel_repos = NULL;
- if (last_dirname != NULL)
- free (last_dirname);
- last_dirname = NULL;
- if (last_repos != NULL)
- free (last_repos);
- last_repos = NULL;
- if (last_update_dir != NULL)
- free (last_update_dir);
- last_update_dir = NULL;
- stored_checksum_valid = 0;
-
- if (fprintf (to_server, "Root %s\n", server_cvsroot) < 0)
- error (1, errno, "writing to server");
- {
- struct response *rs;
- if (fprintf (to_server, "Valid-responses") < 0)
- error (1, errno, "writing to server");
- for (rs = responses; rs->name != NULL; ++rs)
- {
- if (fprintf (to_server, " %s", rs->name) < 0)
- error (1, errno, "writing to server");
- }
- if (fprintf (to_server, "\n") < 0)
- error (1, errno, "writing to server");
- }
- if (fprintf (to_server, "valid-requests\n") < 0)
- error (1, errno, "writing to server");
- if (get_server_responses ())
- exit (1);
-
- /*
- * Now handle global options.
- *
- * -H, -f, -d, -e should be handled OK locally.
- *
- * -b we ignore (treating it as a server installation issue).
- * FIXME: should be an error message.
- *
- * -v we print local version info; FIXME: Add a protocol request to get
- * the version from the server so we can print that too.
- *
- * -l -t -r -w -q -n and -Q need to go to the server.
- */
-
- {
- int have_global = supported_request ("Global_option");
-
- if (noexec)
- {
- if (have_global)
- {
- if (fprintf (to_server, "Global_option -n\n") < 0)
- error (1, errno, "writing to server");
- }
- else
- error (1, 0,
- "This server does not support the global -n option.");
- }
- if (quiet)
- {
- if (have_global)
- {
- if (fprintf (to_server, "Global_option -q\n") < 0)
- error (1, errno, "writing to server");
- }
- else
- error (1, 0,
- "This server does not support the global -q option.");
- }
- if (really_quiet)
- {
- if (have_global)
- {
- if (fprintf (to_server, "Global_option -Q\n") < 0)
- error (1, errno, "writing to server");
- }
- else
- error (1, 0,
- "This server does not support the global -Q option.");
- }
- if (!cvswrite)
- {
- if (have_global)
- {
- if (fprintf (to_server, "Global_option -r\n") < 0)
- error (1, errno, "writing to server");
- }
- else
- error (1, 0,
- "This server does not support the global -r option.");
- }
- if (trace)
- {
- if (have_global)
- {
- if (fprintf (to_server, "Global_option -t\n") < 0)
- error (1, errno, "writing to server");
- }
- else
- error (1, 0,
- "This server does not support the global -t option.");
- }
- if (logoff)
- {
- if (have_global)
- {
- if (fprintf (to_server, "Global_option -l\n") < 0)
- error (1, errno, "writing to server");
- }
- else
- error (1, 0,
- "This server does not support the global -l option.");
- }
- }
- if (gzip_level)
- {
- if (supported_request ("gzip-file-contents"))
- {
- if (fprintf (to_server, "gzip-file-contents %d\n", gzip_level) < 0)
- error (1, 0, "writing to server");
- }
- else
- {
- fprintf (stderr, "server doesn't support gzip-file-contents\n");
- gzip_level = 0;
- }
- }
-}
-
-#ifndef RSH_NOT_TRANSPARENT
-/* Contact the server by starting it with rsh. */
-
-/* Right now, we have two different definitions for this function,
- depending on whether we start the rsh server using popenRW or not.
- This isn't ideal, and the best thing would probably be to change
- the OS/2 port to be more like the regular Unix client (i.e., by
- implementing piped_child)... but I'm doing something else at the
- moment, and wish to make only one change at a time. -Karl */
-
-#ifdef START_RSH_WITH_POPEN_RW
-
-static void
-start_rsh_server (tofdp, fromfdp)
- int *tofdp, *fromfdp;
-{
- int pipes[2];
-
- /* If you're working through firewalls, you can set the
- CVS_RSH environment variable to a script which uses rsh to
- invoke another rsh on a proxy machine. */
- char *cvs_rsh = getenv ("CVS_RSH");
- char *cvs_server = getenv ("CVS_SERVER");
- char command[PATH_MAX];
- int i = 0;
- /* This needs to fit "rsh", "-b", "-l", "USER", "host",
- "cmd (w/ args)", and NULL. We leave some room to grow. */
- char *rsh_argv[10];
-
- if (!cvs_rsh)
- cvs_rsh = "rsh";
- if (!cvs_server)
- cvs_server = "cvs";
-
- /* If you are running a very old (Nov 3, 1994, before 1.5)
- * version of the server, you need to make sure that your .bashrc
- * on the server machine does not set CVSROOT to something
- * containing a colon (or better yet, upgrade the server). */
-
- /* The command line starts out with rsh. */
- rsh_argv[i++] = cvs_rsh;
-
- /* "-b" for binary, under OS/2. */
- rsh_argv[i++] = "-b";
-
- /* Then we strcat more things on the end one by one. */
- if (server_user != NULL)
- {
- rsh_argv[i++] = "-l";
- rsh_argv[i++] = server_user;
- }
-
- rsh_argv[i++] = server_host;
- rsh_argv[i++] = cvs_server;
- rsh_argv[i++] = "server";
-
- /* Mark the end of the arg list. */
- rsh_argv[i] = (char *) NULL;
-
- if (trace)
- {
- fprintf (stderr, " -> Starting server: ");
- fprintf (stderr, "%s", command);
- putc ('\n', stderr);
- }
-
- /* Do the deed. */
- rsh_pid = popenRW (rsh_argv, pipes);
- if (rsh_pid < 0)
- error (1, errno, "cannot start server via rsh");
-
- /* Give caller the file descriptors. */
- *tofdp = pipes[0];
- *fromfdp = pipes[1];
-}
-
-#else /* ! START_RSH_WITH_POPEN_RW */
-
-static void
-start_rsh_server (tofdp, fromfdp)
- int *tofdp;
- int *fromfdp;
-{
- /* If you're working through firewalls, you can set the
- CVS_RSH environment variable to a script which uses rsh to
- invoke another rsh on a proxy machine. */
- char *cvs_rsh = getenv ("CVS_RSH");
- char *cvs_server = getenv ("CVS_SERVER");
- char *command;
-
- if (!cvs_rsh)
- cvs_rsh = "rsh";
- if (!cvs_server)
- cvs_server = "cvs";
-
- /* Pass the command to rsh as a single string. This shouldn't
- affect most rsh servers at all, and will pacify some buggy
- versions of rsh that grab switches out of the middle of the
- command (they're calling the GNU getopt routines incorrectly). */
- command = xmalloc (strlen (cvs_server)
- + strlen (server_cvsroot)
- + 50);
-
- /* If you are running a very old (Nov 3, 1994, before 1.5)
- * version of the server, you need to make sure that your .bashrc
- * on the server machine does not set CVSROOT to something
- * containing a colon (or better yet, upgrade the server). */
- sprintf (command, "%s server", cvs_server);
-
- {
- char *argv[10];
- char **p = argv;
-
- *p++ = cvs_rsh;
- *p++ = server_host;
-
- /* If the login names differ between client and server
- * pass it on to rsh.
- */
- if (server_user != NULL)
- {
- *p++ = "-l";
- *p++ = server_user;
- }
-
- *p++ = command;
- *p++ = NULL;
-
- if (trace)
- {
- int i;
-
- fprintf (stderr, " -> Starting server: ");
- for (i = 0; argv[i]; i++)
- fprintf (stderr, "%s ", argv[i]);
- putc ('\n', stderr);
- }
- rsh_pid = piped_child (argv, tofdp, fromfdp);
-
- if (rsh_pid < 0)
- error (1, errno, "cannot start server via rsh");
- }
-}
-
-#endif /* START_RSH_WITH_POPEN_RW */
-#endif /* ! RSH_NOT_TRANSPARENT */
-
-
-
-/* Send an argument STRING. */
-void
-send_arg (string)
- char *string;
-{
- char *p = string;
- if (fprintf (to_server, "Argument ") < 0)
- error (1, errno, "writing to server");
- while (*p)
- {
- if (*p == '\n')
- {
- if (fprintf (to_server, "\nArgumentx ") < 0)
- error (1, errno, "writing to server");
- }
- else if (putc (*p, to_server) == EOF)
- error (1, errno, "writing to server");
- ++p;
- }
- if (putc ('\n', to_server) == EOF)
- error (1, errno, "writing to server");
-}
-
-static void send_modified PROTO ((char *, char *, Vers_TS *));
-
-static void
-send_modified (file, short_pathname, vers)
- char *file;
- char *short_pathname;
- Vers_TS *vers;
-{
- /* File was modified, send it. */
- struct stat sb;
- int fd;
- char *buf;
- char *mode_string;
- int bufsize;
- int bin = 0;
-
- /* Don't think we can assume fstat exists. */
- if (stat (file, &sb) < 0)
- error (1, errno, "reading %s", short_pathname);
-
- mode_string = mode_to_string (sb.st_mode);
-
- /* Beware: on systems using CRLF line termination conventions,
- the read and write functions will convert CRLF to LF, so the
- number of characters read is not the same as sb.st_size. Text
- files should always be transmitted using the LF convention, so
- we don't want to disable this conversion. */
- bufsize = sb.st_size;
- buf = xmalloc (bufsize);
-
- /* Is the file marked as containing binary data by the "-kb" flag?
- If so, make sure to open it in binary mode: */
-
- bin = !(strcmp (vers->options, "-kb"));
- fd = open (file, O_RDONLY | (bin ? OPEN_BINARY : 0));
-
- if (fd < 0)
- error (1, errno, "reading %s", short_pathname);
-
- if (gzip_level && sb.st_size > 100)
- {
- int nread, newsize = 0, gzip_status;
- pid_t gzip_pid;
- char *bufp = buf;
- int readsize = 8192;
-#ifdef LINES_CRLF_TERMINATED
- char tempfile[L_tmpnam];
- int converting;
-#endif /* LINES_CRLF_TERMINATED */
-
-#ifdef LINES_CRLF_TERMINATED
- /* Assume everything in a "cvs import" is text. */
- if (vers == NULL)
- converting = 1;
- else
- /* Otherwise, we convert things unless they're binary. */
- converting = (! bin);
-
- if (converting)
- {
- /* gzip reads and writes files without munging CRLF
- sequences, as it should, but files should be
- transmitted in LF form. Convert CRLF to LF before
- gzipping, on systems where this is necessary.
-
- If Windows NT supported fork, we could do this by
- pushing another filter on in front of gzip. But it
- doesn't. I'd have to write a trivial little program to
- do the conversion and have CVS spawn it off. But
- little executables like that always get lost.
-
- Alternatively, this cruft could go away if we switched
- to a gzip library instead of a subprocess; then we
- could tell gzip to open the file with CRLF translation
- enabled. */
- if (close (fd) < 0)
- error (0, errno, "warning: can't close %s", short_pathname);
-
- tmpnam (tempfile);
- convert_file (file, O_RDONLY,
- tempfile,
- O_WRONLY | O_CREAT | O_TRUNC | OPEN_BINARY);
-
- /* This OPEN_BINARY doesn't make any difference, I think, because
- gzip will deal with the inherited handle as it pleases. But I
- do remember something obscure in the manuals about propagating
- the translation mode to created processes via environment
- variables, ick. */
- fd = open (tempfile, O_RDONLY | OPEN_BINARY);
- if (fd < 0)
- error (1, errno, "reading %s", short_pathname);
- }
-#endif /* LINES_CRLF_TERMINATED */
-
- fd = filter_through_gzip (fd, 1, gzip_level, &gzip_pid);
- while (1)
- {
- if ((bufp - buf) + readsize >= bufsize)
- {
- /*
- * We need to expand the buffer if gzip ends up expanding
- * the file.
- */
- newsize = bufp - buf;
- while (newsize + readsize >= bufsize)
- bufsize *= 2;
- buf = xrealloc (buf, bufsize);
- bufp = buf + newsize;
- }
- nread = read (fd, bufp, readsize);
- if (nread < 0)
- error (1, errno, "reading from gzip pipe");
- else if (nread == 0)
- /* eof */
- break;
- bufp += nread;
- }
- newsize = bufp - buf;
- if (close (fd) < 0)
- error (0, errno, "warning: can't close %s", short_pathname);
-
- if (waitpid (gzip_pid, &gzip_status, 0) != gzip_pid)
- error (1, errno, "waiting for gzip proc %d", gzip_pid);
- else if (gzip_status != 0)
- error (1, errno, "gzip exited %d", gzip_status);
-
-#if LINES_CRLF_TERMINATED
- if (converting)
- {
- if (unlink (tempfile) < 0)
- error (0, errno,
- "warning: can't remove temp file %s", tempfile);
- }
-#endif /* LINES_CRLF_TERMINATED */
-
- fprintf (to_server, "Modified %s\n%s\nz%lu\n", file, mode_string,
- (unsigned long) newsize);
- fwrite (buf, newsize, 1, to_server);
- if (feof (to_server) || ferror (to_server))
- error (1, errno, "writing to server");
- }
- else
- {
- int newsize;
-
- {
- char *bufp = buf;
- int len;
-
- while ((len = read (fd, bufp, (buf + sb.st_size) - bufp)) > 0)
- bufp += len;
-
- if (len < 0)
- error (1, errno, "reading %s", short_pathname);
-
- newsize = bufp - buf;
- }
- if (close (fd) < 0)
- error (0, errno, "warning: can't close %s", short_pathname);
-
- if (fprintf (to_server, "Modified %s\n%s\n%lu\n", file,
- mode_string, (unsigned long) newsize) < 0)
- error (1, errno, "writing to server");
-
- /*
- * Note that this only ends with a newline if the file ended with
- * one.
- */
- if (newsize > 0)
- if (fwrite (buf, newsize, 1, to_server) != 1)
- error (1, errno, "writing to server");
- }
- free (buf);
- free (mode_string);
-}
-
-/* Deal with one file. */
-static int
-send_fileproc (file, update_dir, repository, entries, srcfiles)
- char *file;
- char *update_dir;
- char *repository;
- List *entries;
- List *srcfiles;
-{
- Vers_TS *vers;
- int update_dir_len = strlen (update_dir);
- char *short_pathname = xmalloc (update_dir_len + strlen (file) + 40);
- strcpy (short_pathname, update_dir);
- if (update_dir[0] != '\0')
- strcat (short_pathname, "/");
- strcat (short_pathname, file);
-
- send_a_repository ("", repository, update_dir);
-
- vers = Version_TS ((char *)NULL, (char *)NULL, (char *)NULL,
- (char *)NULL,
- file, 0, 0, entries, (List *)NULL);
-
- if (vers->vn_user != NULL)
- {
- /* The Entries request. */
- /* Not sure about whether this deals with -k and stuff right. */
- if (fprintf (to_server, "Entry /%s/%s/%s%s/%s/", file, vers->vn_user,
- vers->ts_conflict == NULL ? "" : "+",
- (vers->ts_conflict == NULL ? ""
- : (vers->ts_user != NULL &&
- strcmp (vers->ts_conflict, vers->ts_user) == 0
- ? "="
- : "modified")),
- vers->options) < 0)
- error (1, errno, "writing to server");
- if (vers->entdata != NULL && vers->entdata->tag)
- {
- if (fprintf (to_server, "T%s", vers->entdata->tag) < 0)
- error (1, errno, "writing to server");
- }
- else if (vers->entdata != NULL && vers->entdata->date)
- if (fprintf (to_server, "D%s", vers->entdata->date) < 0)
- error (1, errno, "writing to server");
- if (fprintf (to_server, "\n") < 0)
- error (1, errno, "writing to server");
- }
-
- if (vers->ts_user == NULL)
- {
- /*
- * Do we want to print "file was lost" like normal CVS?
- * Would it always be appropriate?
- */
- /* File no longer exists. */
- if (!use_unchanged)
- {
- /* if the server is old, use the old request... */
- if (fprintf (to_server, "Lost %s\n", file) < 0)
- error (1, errno, "writing to server");
- /*
- * Otherwise, don't do anything for missing files,
- * they just happen.
- */
- }
- }
- else if (vers->ts_rcs == NULL
- || strcmp (vers->ts_user, vers->ts_rcs) != 0)
- {
- send_modified (file, short_pathname, vers);
- }
- else
- {
- /* Only use this request if the server supports it... */
- if (use_unchanged)
- if (fprintf (to_server, "Unchanged %s\n", file) < 0)
- error (1, errno, "writing to server");
- }
-
- /* if this directory has an ignore list, add this file to it */
- if (ignlist)
- {
- Node *p;
-
- p = getnode ();
- p->type = FILES;
- p->key = xstrdup (file);
- (void) addnode (ignlist, p);
- }
-
- freevers_ts (&vers);
- free (short_pathname);
- return 0;
-}
-
-/*
- * send_dirent_proc () is called back by the recursion processor before a
- * sub-directory is processed for update.
- * A return code of 0 indicates the directory should be
- * processed by the recursion code. A return of non-zero indicates the
- * recursion code should skip this directory.
- *
- */
-static Dtype
-send_dirent_proc (dir, repository, update_dir)
- char *dir;
- char *repository;
- char *update_dir;
-{
- int dir_exists;
- char *cvsadm_repos_name;
-
- /*
- * If the directory does not exist yet (e.g. "cvs update -d
- * foo"), no need to send any files from it.
- */
- dir_exists = isdir (dir);
-
- if (ignore_directory (update_dir))
- {
- /* print the warm fuzzy message */
- if (!quiet)
- error (0, 0, "Ignoring %s", update_dir);
- return (R_SKIP_ALL);
- }
-
- /* initialize the ignore list for this directory */
- ignlist = getlist ();
-
- /*
- * If there is an empty directory (e.g. we are doing `cvs add' on a
- * newly-created directory), the server still needs to know about it.
- */
-
- cvsadm_repos_name = xmalloc (strlen (dir) + sizeof (CVSADM_REP) + 80);
- sprintf (cvsadm_repos_name, "%s/%s", dir, CVSADM_REP);
- if (dir_exists && isreadable (cvsadm_repos_name))
- {
- /*
- * Get the repository from a CVS/Repository file whenever possible.
- * The repository variable is wrong if the names in the local
- * directory don't match the names in the repository.
- */
- char *repos = Name_Repository (dir, update_dir);
- send_a_repository (dir, repos, update_dir);
- free (repos);
- }
- else
- send_a_repository (dir, repository, update_dir);
- free (cvsadm_repos_name);
-
- return (dir_exists ? R_PROCESS : R_SKIP_ALL);
-}
-
-/*
- * Send each option in a string to the server, one by one.
- * This assumes that the options are single characters. For
- * more complex parsing, do it yourself.
- */
-
-void
-send_option_string (string)
- char *string;
-{
- char *p;
- char it[3];
-
- for (p = string; p[0]; p++) {
- if (p[0] == ' ')
- continue;
- if (p[0] == '-')
- continue;
- it[0] = '-';
- it[1] = p[0];
- it[2] = '\0';
- send_arg (it);
- }
-}
-
-
-/* Send the names of all the argument files to the server. */
-
-void
-send_file_names (argc, argv)
- int argc;
- char **argv;
-{
- int i;
- char *p;
- char *q;
- int level;
- int max_level;
-
- /* Send Max-dotdot if needed. */
- max_level = 0;
- for (i = 0; i < argc; ++i)
- {
- p = argv[i];
- level = 0;
- do
- {
- q = strchr (p, '/');
- if (q != NULL)
- ++q;
- if (p[0] == '.' && p[1] == '.' && (p[2] == '\0' || p[2] == '/'))
- {
- --level;
- if (-level > max_level)
- max_level = -level;
- }
- else if (p[0] == '.' && (p[1] == '\0' || p[1] == '/'))
- ;
- else
- ++level;
- p = q;
- } while (p != NULL);
- }
- if (max_level > 0)
- {
- if (supported_request ("Max-dotdot"))
- {
- if (fprintf (to_server, "Max-dotdot %d\n", max_level) < 0)
- error (1, errno, "writing to server");
- }
- else
- /*
- * "leading .." is not strictly correct, as this also includes
- * cases like "foo/../..". But trying to explain that in the
- * error message would probably just confuse users.
- */
- error (1, 0,
- "leading .. not supported by old (pre-Max-dotdot) servers");
- }
-
- for (i = 0; i < argc; ++i)
- send_arg (argv[i]);
-}
-
-
-/*
- * Send Repository, Modified and Entry. argc and argv contain only
- * the files to operate on (or empty for everything), not options.
- * local is nonzero if we should not recurse (-l option). Also sends
- * Argument lines for argc and argv, so should be called after options
- * are sent.
- */
-void
-send_files (argc, argv, local, aflag)
- int argc;
- char **argv;
- int local;
- int aflag;
-{
- int err;
-
- send_file_names (argc, argv);
-
- /*
- * aflag controls whether the tag/date is copied into the vers_ts.
- * But we don't actually use it, so I don't think it matters what we pass
- * for aflag here.
- */
- err = start_recursion
- (send_fileproc, update_filesdone_proc,
- send_dirent_proc, (DIRLEAVEPROC)NULL,
- argc, argv, local, W_LOCAL, aflag, 0, (char *)NULL, 0, 0);
- if (err)
- exit (1);
- if (toplevel_repos == NULL)
- /*
- * This happens if we are not processing any files,
- * or for checkouts in directories without any existing stuff
- * checked out. The following assignment is correct for the
- * latter case; I don't think toplevel_repos matters for the
- * former.
- */
- toplevel_repos = xstrdup (server_cvsroot);
- send_repository ("", toplevel_repos, ".");
-}
-
-void
-client_import_setup (repository)
- char *repository;
-{
- if (toplevel_repos == NULL) /* should always be true */
- send_a_repository ("", repository, "");
-}
-
-/*
- * Process the argument import file.
- */
-int
-client_process_import_file (message, vfile, vtag, targc, targv, repository)
- char *message;
- char *vfile;
- char *vtag;
- int targc;
- char *targv[];
- char *repository;
-{
- char *short_pathname;
- int first_time;
-
- /* FIXME: I think this is always false now that we call
- client_import_setup at the start. */
-
- first_time = toplevel_repos == NULL;
-
- if (first_time)
- send_a_repository ("", repository, "");
-
- if (strncmp (repository, toplevel_repos, strlen (toplevel_repos)) != 0)
- error (1, 0,
- "internal error: pathname `%s' doesn't specify file in `%s'",
- repository, toplevel_repos);
- short_pathname = repository + strlen (toplevel_repos) + 1;
-
- if (!first_time)
- {
- send_a_repository ("", repository, short_pathname);
- }
- send_modified (vfile, short_pathname, NULL);
- return 0;
-}
-
-void
-client_import_done ()
-{
- if (toplevel_repos == NULL)
- /*
- * This happens if we are not processing any files,
- * or for checkouts in directories without any existing stuff
- * checked out. The following assignment is correct for the
- * latter case; I don't think toplevel_repos matters for the
- * former.
- */
- /* FIXME: "can't happen" now that we call client_import_setup
- at the beginning. */
- toplevel_repos = xstrdup (server_cvsroot);
- send_repository ("", toplevel_repos, ".");
-}
-
-/*
- * Send an option with an argument, dealing correctly with newlines in
- * the argument. If ARG is NULL, forget the whole thing.
- */
-void
-option_with_arg (option, arg)
- char *option;
- char *arg;
-{
- if (arg == NULL)
- return;
- if (fprintf (to_server, "Argument %s\n", option) < 0)
- error (1, errno, "writing to server");
- send_arg (arg);
-}
-
-/*
- * Send a date to the server. This will passed a string which is the
- * result of Make_Date, and looks like YY.MM.DD.HH.MM.SS, where all
- * the letters are single digits. The time will be GMT. getdate on
- * the server can't parse that, so we turn it back into something
- * which it can parse.
- */
-
-void
-client_senddate (date)
- const char *date;
-{
- int year, month, day, hour, minute, second;
- char buf[100];
-
- if (sscanf (date, DATEFORM, &year, &month, &day, &hour, &minute, &second)
- != 6)
- {
- error (1, 0, "diff_client_senddate: sscanf failed on date");
- }
-
-#ifndef HAVE_RCS5
- /* We need to fix the timezone in this case; see Make_Date. */
- abort ();
-#endif /* HAVE_RCS5 */
-
- sprintf (buf, "%d/%d/%d %d:%d:%d GMT", month, day, year,
- hour, minute, second);
- option_with_arg ("-D", buf);
-}
-
-int
-client_commit (argc, argv)
- int argc;
- char **argv;
-{
- parse_cvsroot ();
-
- return commit (argc, argv);
-}
-
-int
-client_update (argc, argv)
- int argc;
- char **argv;
-{
- parse_cvsroot ();
-
- return update (argc, argv);
-}
-
-int
-client_checkout (argc, argv)
- int argc;
- char **argv;
-{
- parse_cvsroot ();
-
- return checkout (argc, argv);
-}
-
-int
-client_diff (argc, argv)
- int argc;
- char **argv;
-{
- parse_cvsroot ();
-
- return diff (argc, argv); /* Call real code */
-}
-
-int
-client_status (argc, argv)
- int argc;
- char **argv;
-{
- parse_cvsroot ();
- return status (argc, argv);
-}
-
-int
-client_log (argc, argv)
- int argc;
- char **argv;
-{
-
- parse_cvsroot ();
-
- return cvslog (argc, argv); /* Call real code */
-}
-
-int
-client_add (argc, argv)
- int argc;
- char **argv;
-{
-
- parse_cvsroot ();
-
- return add (argc, argv); /* Call real code */
-}
-
-int
-client_remove (argc, argv)
- int argc;
- char **argv;
-{
-
- parse_cvsroot ();
-
- return cvsremove (argc, argv); /* Call real code */
-}
-
-int
-client_rdiff (argc, argv)
- int argc;
- char **argv;
-{
-
- parse_cvsroot ();
-
- return patch (argc, argv); /* Call real code */
-}
-
-int
-client_tag (argc, argv)
- int argc;
- char **argv;
-{
-
- parse_cvsroot ();
-
- return tag (argc, argv); /* Call real code */
-}
-
-int
-client_rtag (argc, argv)
- int argc;
- char **argv;
-{
-
- parse_cvsroot ();
-
- return rtag (argc, argv); /* Call real code */
-}
-
-int
-client_import (argc, argv)
- int argc;
- char **argv;
-{
-
- parse_cvsroot ();
-
- return import (argc, argv); /* Call real code */
-}
-
-int
-client_admin (argc, argv)
- int argc;
- char **argv;
-{
-
- parse_cvsroot ();
-
- return admin (argc, argv); /* Call real code */
-}
-
-int
-client_export (argc, argv)
- int argc;
- char **argv;
-{
-
- parse_cvsroot ();
-
- return checkout (argc, argv); /* Call real code */
-}
-
-int
-client_history (argc, argv)
- int argc;
- char **argv;
-{
-
- parse_cvsroot ();
-
- return history (argc, argv); /* Call real code */
-}
-
-int
-client_release (argc, argv)
- int argc;
- char **argv;
-{
-
- parse_cvsroot ();
-
- return release (argc, argv); /* Call real code */
-}
-
-#endif /* CLIENT_SUPPORT */
diff --git a/gnu/usr.bin/cvs/cvs/client.h b/gnu/usr.bin/cvs/cvs/client.h
deleted file mode 100644
index 0602900aaf50..000000000000
--- a/gnu/usr.bin/cvs/cvs/client.h
+++ /dev/null
@@ -1,163 +0,0 @@
-/* Interface between the client and the rest of CVS. */
-
-/* Stuff shared with the server. */
-extern char *mode_to_string PROTO((mode_t));
-extern int change_mode PROTO((char *, char *));
-
-extern int gzip_level;
-extern int filter_through_gzip PROTO((int, int, int, pid_t *));
-extern int filter_through_gunzip PROTO((int, int, pid_t *));
-
-#ifdef CLIENT_SUPPORT
-/*
- * Functions to perform CVS commands via the protocol. argc and argv
- * are the arguments and the return value is the exit status (zero success
- * nonzero failure).
- */
-extern int client_commit PROTO((int argc, char **argv));
-extern int client_update PROTO((int argc, char **argv));
-extern int client_checkout PROTO((int argc, char **argv));
-extern int client_diff PROTO((int argc, char **argv));
-extern int client_log PROTO((int argc, char **argv));
-extern int client_add PROTO((int argc, char **argv));
-extern int client_remove PROTO((int argc, char **argv));
-extern int client_status PROTO((int argc, char **argv));
-extern int client_rdiff PROTO((int argc, char **argv));
-extern int client_tag PROTO((int argc, char **argv));
-extern int client_rtag PROTO((int argc, char **argv));
-extern int client_import PROTO((int argc, char **argv));
-extern int client_admin PROTO((int argc, char **argv));
-extern int client_export PROTO((int argc, char **argv));
-extern int client_history PROTO((int argc, char **argv));
-extern int client_release PROTO((int argc, char **argv));
-
-/*
- * Flag variable for seeing whether common code is running as a client
- * or to do a local operation.
- */
-extern int client_active;
-
-/* Is the -P option to checkout or update specified? */
-extern int client_prune_dirs;
-
-/* Stream to write to the server. */
-extern FILE *to_server;
-/* Stream to read from the server. */
-extern FILE *from_server;
-
-/* Internal functions that handle client communication to server, etc. */
-int supported_request PROTO ((char *));
-void option_with_arg PROTO((char *option, char *arg));
-
-/* Get the responses and then close the connection. */
-extern int get_responses_and_close PROTO((void));
-
-extern int get_server_responses PROTO((void));
-
-/* Start up the connection to the server on the other end. */
-void
-start_server PROTO((void));
-
-/* Send the names of all the argument files to the server. */
-void
-send_file_names PROTO((int argc, char **argv));
-
-/*
- * Send Repository, Modified and Entry. argc and argv contain only
- * the files to operate on (or empty for everything), not options.
- * local is nonzero if we should not recurse (-l option). Also sends
- * Argument lines for argc and argv, so should be called after options
- * are sent.
- */
-void
-send_files PROTO((int argc, char **argv, int local, int aflag));
-
-/*
- * Like send_files but never send "Unchanged"--just send the contents of the
- * file in that case. This is used to fix it if you import a directory which
- * happens to have CVS directories (yes it is obscure but the testsuite tests
- * it).
- */
-void
-send_files_contents PROTO((int argc, char **argv, int local, int aflag));
-
-/* Send an argument to the remote server. */
-void
-send_arg PROTO((char *string));
-
-/* Send a string of single-char options to the remote server, one by one. */
-void
-send_option_string PROTO((char *string));
-
-#endif /* CLIENT_SUPPORT */
-
-/*
- * This structure is used to catalog the responses the client is
- * prepared to see from the server.
- */
-
-struct response
-{
- /* Name of the response. */
- char *name;
-
-#ifdef CLIENT_SUPPORT
- /*
- * Function to carry out the response. ARGS is the text of the
- * command after name and, if present, a single space, have been
- * stripped off. The function can scribble into ARGS if it wants.
- */
- void (*func) PROTO((char *args, int len));
-
- /*
- * ok and error are special; they indicate we are at the end of the
- * responses, and error indicates we should exit with nonzero
- * exitstatus.
- */
- enum {response_type_normal, response_type_ok, response_type_error} type;
-#endif
-
- /* Used by the server to indicate whether response is supported by
- the client, as set by the Valid-responses request. */
- enum {
- /*
- * Failure to implement this response can imply a fatal
- * error. This should be set only for responses which were in the
- * original version of the protocol; it should not be set for new
- * responses.
- */
- rs_essential,
-
- /* Some clients might not understand this response. */
- rs_optional,
-
- /*
- * Set by the server to one of the following based on what this
- * client actually supports.
- */
- rs_supported,
- rs_not_supported
- } status;
-};
-
-/* Table of responses ending in an entry with a NULL name. */
-
-extern struct response responses[];
-
-#ifdef CLIENT_SUPPORT
-
-extern void client_senddate PROTO((const char *date));
-extern void client_expand_modules PROTO((int argc, char **argv, int local));
-extern void client_send_expansions PROTO((int local));
-extern void client_nonexpanded_setup PROTO((void));
-
-extern char **failed_patches;
-extern int failed_patches_count;
-extern char toplevel_wd[];
-extern void client_import_setup PROTO((char *repository));
-extern int client_process_import_file
- PROTO((char *message, char *vfile, char *vtag,
- int targc, char *targv[], char *repository));
-extern void client_import_done PROTO((void));
-
-#endif /* CLIENT_SUPPORT */
diff --git a/gnu/usr.bin/cvs/cvs/commit.c b/gnu/usr.bin/cvs/cvs/commit.c
deleted file mode 100644
index 888804e52fce..000000000000
--- a/gnu/usr.bin/cvs/cvs/commit.c
+++ /dev/null
@@ -1,1834 +0,0 @@
-/*
- * Copyright (c) 1992, Brian Berliner and Jeff Polk
- * Copyright (c) 1989-1992, Brian Berliner
- *
- * You may distribute under the terms of the GNU General Public License as
- * specified in the README file that comes with the CVS 1.4 kit.
- *
- * Commit Files
- *
- * "commit" commits the present version to the RCS repository, AFTER
- * having done a test on conflicts.
- *
- * The call is: cvs commit [options] files...
- *
- */
-
-#include "cvs.h"
-#include "getline.h"
-
-#ifndef lint
-static const char rcsid[] = "$CVSid: @(#)commit.c 1.101 94/10/07 $";
-USE(rcsid);
-#endif
-
-static Dtype check_direntproc PROTO((char *dir, char *repos, char *update_dir));
-static int check_fileproc PROTO((char *file, char *update_dir, char *repository,
- List * entries, List * srcfiles));
-static int check_filesdoneproc PROTO((int err, char *repos, char *update_dir));
-static int checkaddfile PROTO((char *file, char *repository, char *tag,
- char *options, List *srcfiles));
-static Dtype commit_direntproc PROTO((char *dir, char *repos, char *update_dir));
-static int commit_dirleaveproc PROTO((char *dir, int err, char *update_dir));
-static int commit_fileproc PROTO((char *file, char *update_dir, char *repository,
- List * entries, List * srcfiles));
-static int commit_filesdoneproc PROTO((int err, char *repository, char *update_dir));
-static int finaladd PROTO((char *file, char *revision, char *tag,
- char *options, char *update_dir,
- char *repository, List *entries));
-static int findmaxrev PROTO((Node * p, void *closure));
-static int fsortcmp PROTO((const Node * p, const Node * q));
-static int lock_RCS PROTO((char *user, char *rcs, char *rev, char *repository));
-static int lock_filesdoneproc PROTO((int err, char *repository, char *update_dir));
-static int lockrcsfile PROTO((char *file, char *repository, char *rev));
-static int precommit_list_proc PROTO((Node * p, void *closure));
-static int precommit_proc PROTO((char *repository, char *filter));
-static int remove_file PROTO((char *file, char *repository, char *tag,
- char *message, List *entries, List *srcfiles));
-static void fix_rcs_modes PROTO((char *rcs, char *user));
-static void fixaddfile PROTO((char *file, char *repository));
-static void fixbranch PROTO((char *file, char *repository, char *branch));
-static void unlockrcs PROTO((char *file, char *repository));
-static void ci_delproc PROTO((Node *p));
-static void masterlist_delproc PROTO((Node *p));
-static void locate_rcs PROTO((char *file, char *repository, char *rcs));
-
-struct commit_info
-{
- Ctype status; /* as returned from Classify_File() */
- char *rev; /* a numeric rev, if we know it */
- char *tag; /* any sticky tag, or -r option */
- char *options; /* Any sticky -k option */
-};
-struct master_lists
-{
- List *ulist; /* list for Update_Logfile */
- List *cilist; /* list with commit_info structs */
-};
-
-static int force_ci = 0;
-static int got_message;
-static int run_module_prog = 1;
-static int aflag;
-static char *tag;
-static char *write_dirtag;
-static char *logfile;
-static List *mulist;
-static List *locklist;
-static char *message;
-
-static const char *const commit_usage[] =
-{
- "Usage: %s %s [-nRlf] [-m msg | -F logfile] [-r rev] files...\n",
- "\t-n\tDo not run the module program (if any).\n",
- "\t-R\tProcess directories recursively.\n",
- "\t-l\tLocal directory only (not recursive).\n",
- "\t-f\tForce the file to be committed; disables recursion.\n",
- "\t-F file\tRead the log message from file.\n",
- "\t-m msg\tLog message.\n",
- "\t-r rev\tCommit to this branch or trunk revision.\n",
- NULL
-};
-
-int
-commit (argc, argv)
- int argc;
- char **argv;
-{
- int c;
- int err = 0;
- int local = 0;
-
- if (argc == -1)
- usage (commit_usage);
-
-#ifdef CVS_BADROOT
- /*
- * For log purposes, do not allow "root" to commit files. If you look
- * like root, but are really logged in as a non-root user, it's OK.
- */
- if (geteuid () == (uid_t) 0)
- {
- struct passwd *pw;
-
- if ((pw = (struct passwd *) getpwnam (getcaller ())) == NULL)
- error (1, 0, "you are unknown to this system");
- if (pw->pw_uid == (uid_t) 0)
- error (1, 0, "cannot commit files as 'root'");
- }
-#endif /* CVS_BADROOT */
-
- optind = 1;
- while ((c = getopt (argc, argv, "nlRm:fF:r:")) != -1)
- {
- switch (c)
- {
- case 'n':
- run_module_prog = 0;
- break;
- case 'm':
-#ifdef FORCE_USE_EDITOR
- use_editor = TRUE;
-#else
- use_editor = FALSE;
-#endif
- if (message)
- {
- free (message);
- message = NULL;
- }
-
- message = xstrdup(optarg);
- break;
- case 'r':
- if (tag)
- free (tag);
- tag = xstrdup (optarg);
- break;
- case 'l':
- local = 1;
- break;
- case 'R':
- local = 0;
- break;
- case 'f':
- force_ci = 1;
- local = 1; /* also disable recursion */
- break;
- case 'F':
-#ifdef FORCE_USE_EDITOR
- use_editor = TRUE;
-#else
- use_editor = FALSE;
-#endif
- logfile = optarg;
- break;
- case '?':
- default:
- usage (commit_usage);
- break;
- }
- }
- argc -= optind;
- argv += optind;
-
- /* numeric specified revision means we ignore sticky tags... */
- if (tag && isdigit (*tag))
- {
- aflag = 1;
- /* strip trailing dots */
- while (tag[strlen (tag) - 1] == '.')
- tag[strlen (tag) - 1] = '\0';
- }
-
- /* some checks related to the "-F logfile" option */
- if (logfile)
- {
- int n, logfd;
- struct stat statbuf;
-
- if (message)
- error (1, 0, "cannot specify both a message and a log file");
-
- if ((logfd = open (logfile, O_RDONLY | OPEN_BINARY)) < 0)
- error (1, errno, "cannot open log file %s", logfile);
-
- if (fstat(logfd, &statbuf) < 0)
- error (1, errno, "cannot find size of log file %s", logfile);
-
- message = xmalloc (statbuf.st_size + 1);
-
- if ((n = read (logfd, message, statbuf.st_size + 1)) < 0)
- error (1, errno, "cannot read log message from %s", logfile);
-
- (void) close (logfd);
- message[n] = '\0';
- }
-
-#ifdef CLIENT_SUPPORT
- if (client_active)
- {
- /*
- * Do this now; don't ask for a log message if we can't talk to the
- * server. But if there is a syntax error in the options, give
- * an error message without connecting.
- */
- start_server ();
-
- ign_setup ();
-
- /*
- * We do this once, not once for each directory as in normal CVS.
- * The protocol is designed this way. This is a feature.
- *
- * We could provide the lists of changed, modified, etc. files,
- * however. Our failure to do so is just laziness, not design.
- */
- if (use_editor)
- do_editor (".", &message, (char *)NULL, (List *)NULL);
-
- /* We always send some sort of message, even if empty. */
- option_with_arg ("-m", message);
-
- if (local)
- send_arg("-l");
- if (force_ci)
- send_arg("-f");
- if (!run_module_prog)
- send_arg("-n");
- option_with_arg ("-r", tag);
-
- send_files (argc, argv, local, 0);
-
- if (fprintf (to_server, "ci\n") < 0)
- error (1, errno, "writing to server");
- return get_responses_and_close ();
- }
-#endif
-
- /* XXX - this is not the perfect check for this */
- if (argc <= 0)
- write_dirtag = tag;
-
- wrap_setup ();
-
- /*
- * Run the recursion processor to find all the dirs to lock and lock all
- * the dirs
- */
- locklist = getlist ();
- err = start_recursion ((FILEPROC) NULL, lock_filesdoneproc,
- (DIRENTPROC) NULL, (DIRLEAVEPROC) NULL, argc,
- argv, local, W_LOCAL, aflag, 0, (char *) NULL, 0,
- 0);
- sortlist (locklist, fsortcmp);
- if (Writer_Lock (locklist) != 0)
- error (1, 0, "lock failed - giving up");
-
- /*
- * Set up the master update list
- */
- mulist = getlist ();
-
- /*
- * Run the recursion processor to verify the files are all up-to-date
- */
- err = start_recursion (check_fileproc, check_filesdoneproc,
- check_direntproc, (DIRLEAVEPROC) NULL, argc,
- argv, local, W_LOCAL, aflag, 0, (char *) NULL, 1,
- 0);
- if (err)
- {
- Lock_Cleanup ();
- error (1, 0, "correct above errors first!");
- }
-
- /*
- * Run the recursion processor to commit the files
- */
- if (noexec == 0)
- err = start_recursion (commit_fileproc, commit_filesdoneproc,
- commit_direntproc, commit_dirleaveproc,
- argc, argv, local, W_LOCAL, aflag, 0,
- (char *) NULL, 1, 0);
-
- /*
- * Unlock all the dirs and clean up
- */
- Lock_Cleanup ();
- dellist (&mulist);
- dellist (&locklist);
- return (err);
-}
-
-/*
- * compare two lock list nodes (for sort)
- */
-static int
-fsortcmp (p, q)
- const Node *p;
- const Node *q;
-{
- return (strcmp (p->key, q->key));
-}
-
-/*
- * Create a list of repositories to lock
- */
-/* ARGSUSED */
-static int
-lock_filesdoneproc (err, repository, update_dir)
- int err;
- char *repository;
- char *update_dir;
-{
- Node *p;
-
- p = getnode ();
- p->type = LOCK;
- p->key = xstrdup (repository);
- /* FIXME-KRP: this error condition should not simply be passed by. */
- if (p->key == NULL || addnode (locklist, p) != 0)
- freenode (p);
- return (err);
-}
-
-/*
- * Check to see if a file is ok to commit and make sure all files are
- * up-to-date
- */
-/* ARGSUSED */
-static int
-check_fileproc (file, update_dir, repository, entries, srcfiles)
- char *file;
- char *update_dir;
- char *repository;
- List *entries;
- List *srcfiles;
-{
- Ctype status;
- char *xdir;
- Node *p;
- List *ulist, *cilist;
- Vers_TS *vers;
- struct commit_info *ci;
- int save_noexec, save_quiet, save_really_quiet;
-
- save_noexec = noexec;
- save_quiet = quiet;
- save_really_quiet = really_quiet;
- noexec = quiet = really_quiet = 1;
-
- /* handle specified numeric revision specially */
- if (tag && isdigit (*tag))
- {
- /* If the tag is for the trunk, make sure we're at the head */
- if (numdots (tag) < 2)
- {
- status = Classify_File (file, (char *) NULL, (char *) NULL,
- (char *) NULL, 1, aflag, repository,
- entries, srcfiles, &vers, update_dir, 0);
- if (status == T_UPTODATE || status == T_MODIFIED ||
- status == T_ADDED)
- {
- Ctype xstatus;
-
- freevers_ts (&vers);
- xstatus = Classify_File (file, tag, (char *) NULL,
- (char *) NULL, 1, aflag, repository,
- entries, srcfiles, &vers, update_dir,
- 0);
- if (xstatus == T_REMOVE_ENTRY)
- status = T_MODIFIED;
- else if (status == T_MODIFIED && xstatus == T_CONFLICT)
- status = T_MODIFIED;
- else
- status = xstatus;
- }
- }
- else
- {
- char *xtag, *cp;
-
- /*
- * The revision is off the main trunk; make sure we're
- * up-to-date with the head of the specified branch.
- */
- xtag = xstrdup (tag);
- if ((numdots (xtag) & 1) != 0)
- {
- cp = strrchr (xtag, '.');
- *cp = '\0';
- }
- status = Classify_File (file, xtag, (char *) NULL,
- (char *) NULL, 1, aflag, repository,
- entries, srcfiles, &vers, update_dir, 0);
- if ((status == T_REMOVE_ENTRY || status == T_CONFLICT)
- && (cp = strrchr (xtag, '.')) != NULL)
- {
- /* pluck one more dot off the revision */
- *cp = '\0';
- freevers_ts (&vers);
- status = Classify_File (file, xtag, (char *) NULL,
- (char *) NULL, 1, aflag, repository,
- entries, srcfiles, &vers, update_dir,
- 0);
- if (status == T_UPTODATE || status == T_REMOVE_ENTRY)
- status = T_MODIFIED;
- }
- /* now, muck with vers to make the tag correct */
- free (vers->tag);
- vers->tag = xstrdup (tag);
- free (xtag);
- }
- }
- else
- status = Classify_File (file, tag, (char *) NULL, (char *) NULL,
- 1, 0, repository, entries, srcfiles, &vers,
- update_dir, 0);
- noexec = save_noexec;
- quiet = save_quiet;
- really_quiet = save_really_quiet;
-
- /*
- * If the force-commit option is enabled, and the file in question
- * appears to be up-to-date, just make it look modified so that
- * it will be committed.
- */
- if (force_ci && status == T_UPTODATE)
- status = T_MODIFIED;
-
- switch (status)
- {
- case T_CHECKOUT:
-#ifdef SERVER_SUPPORT
- case T_PATCH:
-#endif
- case T_NEEDS_MERGE:
- case T_CONFLICT:
- case T_REMOVE_ENTRY:
- if (update_dir[0] == '\0')
- error (0, 0, "Up-to-date check failed for `%s'", file);
- else
- error (0, 0, "Up-to-date check failed for `%s/%s'",
- update_dir, file);
- freevers_ts (&vers);
- return (1);
- case T_MODIFIED:
- case T_ADDED:
- case T_REMOVED:
- /*
- * some quick sanity checks; if no numeric -r option specified:
- * - can't have a sticky date
- * - can't have a sticky tag that is not a branch
- * Also,
- * - if status is T_REMOVED, can't have a numeric tag
- * - if status is T_ADDED, rcs file must not exist
- * - if status is T_ADDED, can't have a non-trunk numeric rev
- * - if status is T_MODIFIED and a Conflict marker exists, don't
- * allow the commit if timestamp is identical or if we find
- * an RCS_MERGE_PAT in the file.
- */
- if (!tag || !isdigit (*tag))
- {
- if (vers->date)
- {
- if (update_dir[0] == '\0')
- error (0, 0,
- "cannot commit with sticky date for file `%s'",
- file);
- else
- error
- (0, 0,
- "cannot commit with sticky date for file `%s/%s'",
- update_dir, file);
- freevers_ts (&vers);
- return (1);
- }
- if (status == T_MODIFIED && vers->tag &&
- !RCS_isbranch (file, vers->tag, srcfiles))
- {
- if (update_dir[0] == '\0')
- error (0, 0,
- "sticky tag `%s' for file `%s' is not a branch",
- vers->tag, file);
- else
- error
- (0, 0,
- "sticky tag `%s' for file `%s/%s' is not a branch",
- vers->tag, update_dir, file);
- freevers_ts (&vers);
- return (1);
- }
- }
- if (status == T_MODIFIED && !force_ci && vers->ts_conflict)
- {
- char *filestamp;
- int retcode;
-
- /*
- * We found a "conflict" marker.
- *
- * If the timestamp on the file is the same as the
- * timestamp stored in the Entries file, we block the commit.
- */
-#ifdef SERVER_SUPPORT
- if (server_active)
- retcode = vers->ts_conflict[0] != '=';
- else {
- filestamp = time_stamp (file);
- retcode = strcmp (vers->ts_conflict, filestamp);
- free (filestamp);
- }
-#else
- filestamp = time_stamp (file);
- retcode = strcmp (vers->ts_conflict, filestamp);
- free (filestamp);
-#endif
- if (retcode == 0)
- {
- if (update_dir[0] == '\0')
- error (0, 0,
- "file `%s' had a conflict and has not been modified",
- file);
- else
- error (0, 0,
- "file `%s/%s' had a conflict and has not been modified",
- update_dir, file);
- freevers_ts (&vers);
- return (1);
- }
-
- /*
- * If the timestamps differ, look for Conflict indicators
- * in the file to see if we should block the commit anyway
- */
- run_setup ("%s", GREP);
- run_arg (RCS_MERGE_PAT);
- run_arg (file);
- retcode = run_exec (RUN_TTY, DEVNULL, RUN_TTY, RUN_REALLY);
-
- if (retcode == -1)
- {
- if (update_dir[0] == '\0')
- error (1, errno,
- "fork failed while examining conflict in `%s'",
- file);
- else
- error (1, errno,
- "fork failed while examining conflict in `%s/%s'",
- update_dir, file);
- }
- else if (retcode == 0)
- {
- if (update_dir[0] == '\0')
- error (0, 0,
- "file `%s' still contains conflict indicators",
- file);
- else
- error (0, 0,
- "file `%s/%s' still contains conflict indicators",
- update_dir, file);
- freevers_ts (&vers);
- return (1);
- }
- }
-
- if (status == T_REMOVED && vers->tag && isdigit (*vers->tag))
- {
- if (update_dir[0] == '\0')
- error (0, 0,
- "cannot remove file `%s' which has a numeric sticky tag of `%s'",
- file, vers->tag);
- else
- error (0, 0,
- "cannot remove file `%s/%s' which has a numeric sticky tag of `%s'",
- update_dir, file, vers->tag);
- freevers_ts (&vers);
- return (1);
- }
- if (status == T_ADDED)
- {
- char rcs[PATH_MAX];
-
-#ifdef DEATH_SUPPORT
- /* Don't look in the attic; if it exists there we will
- move it back out in checkaddfile. */
- sprintf(rcs, "%s/%s%s", repository, file, RCSEXT);
-#else
- locate_rcs (file, repository, rcs);
-#endif
- if (isreadable (rcs))
- {
- if (update_dir[0] == '\0')
- error (0, 0,
- "cannot add file `%s' when RCS file `%s' already exists",
- file, rcs);
- else
- error (0, 0,
- "cannot add file `%s/%s' when RCS file `%s' already exists",
- update_dir, file, rcs);
- freevers_ts (&vers);
- return (1);
- }
- if (vers->tag && isdigit (*vers->tag) &&
- numdots (vers->tag) > 1)
- {
- if (update_dir[0] == '\0')
- error (0, 0,
- "cannot add file `%s' with revision `%s'; must be on trunk",
- file, vers->tag);
- else
- error (0, 0,
- "cannot add file `%s/%s' with revision `%s'; must be on trunk",
- update_dir, file, vers->tag);
- freevers_ts (&vers);
- return (1);
- }
- }
-
- /* done with consistency checks; now, to get on with the commit */
- if (update_dir[0] == '\0')
- xdir = ".";
- else
- xdir = update_dir;
- if ((p = findnode (mulist, xdir)) != NULL)
- {
- ulist = ((struct master_lists *) p->data)->ulist;
- cilist = ((struct master_lists *) p->data)->cilist;
- }
- else
- {
- struct master_lists *ml;
-
- ulist = getlist ();
- cilist = getlist ();
- p = getnode ();
- p->key = xstrdup (xdir);
- p->type = UPDATE;
- ml = (struct master_lists *)
- xmalloc (sizeof (struct master_lists));
- ml->ulist = ulist;
- ml->cilist = cilist;
- p->data = (char *) ml;
- p->delproc = masterlist_delproc;
- (void) addnode (mulist, p);
- }
-
- /* first do ulist, then cilist */
- p = getnode ();
- p->key = xstrdup (file);
- p->type = UPDATE;
- p->delproc = update_delproc;
- p->data = (char *) status;
- (void) addnode (ulist, p);
-
- p = getnode ();
- p->key = xstrdup (file);
- p->type = UPDATE;
- p->delproc = ci_delproc;
- ci = (struct commit_info *) xmalloc (sizeof (struct commit_info));
- ci->status = status;
- if (vers->tag)
- if (isdigit (*vers->tag))
- ci->rev = xstrdup (vers->tag);
- else
- ci->rev = RCS_whatbranch (file, vers->tag, srcfiles);
- else
- ci->rev = (char *) NULL;
- ci->tag = xstrdup (vers->tag);
- ci->options = xstrdup(vers->options);
- p->data = (char *) ci;
- (void) addnode (cilist, p);
- break;
- case T_UNKNOWN:
- if (update_dir[0] == '\0')
- error (0, 0, "nothing known about `%s'", file);
- else
- error (0, 0, "nothing known about `%s/%s'", update_dir, file);
- freevers_ts (&vers);
- return (1);
- case T_UPTODATE:
- break;
- default:
- error (0, 0, "CVS internal error: unknown status %d", status);
- break;
- }
-
- freevers_ts (&vers);
- return (0);
-}
-
-/*
- * Print warm fuzzies while examining the dirs
- */
-/* ARGSUSED */
-static Dtype
-check_direntproc (dir, repos, update_dir)
- char *dir;
- char *repos;
- char *update_dir;
-{
- if (!quiet)
- error (0, 0, "Examining %s", update_dir);
-
- return (R_PROCESS);
-}
-
-/*
- * Walklist proc to run pre-commit checks
- */
-static int
-precommit_list_proc (p, closure)
- Node *p;
- void *closure;
-{
- if (p->data == (char *) T_ADDED || p->data == (char *) T_MODIFIED ||
- p->data == (char *) T_REMOVED)
- {
- run_arg (p->key);
- }
- return (0);
-}
-
-/*
- * Callback proc for pre-commit checking
- */
-static List *ulist;
-static int
-precommit_proc (repository, filter)
- char *repository;
- char *filter;
-{
- /* see if the filter is there, only if it's a full path */
- if (isabsolute (filter))
- {
- char *s, *cp;
-
- s = xstrdup (filter);
- for (cp = s; *cp; cp++)
- if (isspace (*cp))
- {
- *cp = '\0';
- break;
- }
- if (!isfile (s))
- {
- error (0, errno, "cannot find pre-commit filter `%s'", s);
- free (s);
- return (1); /* so it fails! */
- }
- free (s);
- }
-
- run_setup ("%s %s", filter, repository);
- (void) walklist (ulist, precommit_list_proc, NULL);
- return (run_exec (RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL|RUN_REALLY));
-}
-
-/*
- * Run the pre-commit checks for the dir
- */
-/* ARGSUSED */
-static int
-check_filesdoneproc (err, repos, update_dir)
- int err;
- char *repos;
- char *update_dir;
-{
- int n;
- Node *p;
-
- /* find the update list for this dir */
- p = findnode (mulist, update_dir);
- if (p != NULL)
- ulist = ((struct master_lists *) p->data)->ulist;
- else
- ulist = (List *) NULL;
-
- /* skip the checks if there's nothing to do */
- if (ulist == NULL || ulist->list->next == ulist->list)
- return (err);
-
- /* run any pre-commit checks */
- if ((n = Parse_Info (CVSROOTADM_COMMITINFO, repos, precommit_proc, 1)) > 0)
- {
- error (0, 0, "Pre-commit check failed");
- err += n;
- }
-
- return (err);
-}
-
-/*
- * Do the work of committing a file
- */
-static int maxrev;
-static char sbranch[PATH_MAX];
-
-/* ARGSUSED */
-static int
-commit_fileproc (file, update_dir, repository, entries, srcfiles)
- char *file;
- char *update_dir;
- char *repository;
- List *entries;
- List *srcfiles;
-{
- Node *p;
- int err = 0;
- List *ulist, *cilist;
- struct commit_info *ci;
- char rcs[PATH_MAX];
-
- if (update_dir[0] == '\0')
- p = findnode (mulist, ".");
- else
- p = findnode (mulist, update_dir);
-
- /*
- * if p is null, there were file type command line args which were
- * all up-to-date so nothing really needs to be done
- */
- if (p == NULL)
- return (0);
- ulist = ((struct master_lists *) p->data)->ulist;
- cilist = ((struct master_lists *) p->data)->cilist;
-
- /*
- * At this point, we should have the commit message unless we were called
- * with files as args from the command line. In that latter case, we
- * need to get the commit message ourselves
- */
- if (use_editor && !got_message)
- {
- got_message = 1;
- do_editor (update_dir, &message, repository, ulist);
- }
-
- p = findnode (cilist, file);
- if (p == NULL)
- return (0);
-
- ci = (struct commit_info *) p->data;
- if (ci->status == T_MODIFIED)
- {
- if (lockrcsfile (file, repository, ci->rev) != 0)
- {
- unlockrcs (file, repository);
- err = 1;
- goto out;
- }
- }
- else if (ci->status == T_ADDED)
- {
- if (checkaddfile (file, repository, ci->tag, ci->options,
- srcfiles) != 0)
- {
- fixaddfile (file, repository);
- err = 1;
- goto out;
- }
-
-#ifdef DEATH_SUPPORT
- /* adding files with a tag, now means adding them on a branch.
- Since the branch test was done in check_fileproc for
- modified files, we need to stub it in again here. */
-
- if (ci->tag) {
- locate_rcs (file, repository, rcs);
- ci->rev = RCS_whatbranch (file, ci->tag, srcfiles);
- err = Checkin ('A', file, update_dir, repository, rcs, ci->rev,
- ci->tag, ci->options, message, entries);
- if (err != 0)
- {
- unlockrcs (file, repository);
- fixbranch (file, repository, sbranch);
- }
-
- ci->status = T_UPTODATE;
- }
-#endif /* DEATH_SUPPORT */
- }
-
- /*
- * Add the file for real
- */
- if (ci->status == T_ADDED)
- {
- char *xrev = (char *) NULL;
-
- if (ci->rev == NULL)
- {
- /* find the max major rev number in this directory */
- maxrev = 0;
- (void) walklist (entries, findmaxrev, NULL);
- if (maxrev == 0)
- maxrev = 1;
- xrev = xmalloc (20);
- (void) sprintf (xrev, "%d", maxrev);
- }
-
- /* XXX - an added file with symbolic -r should add tag as well */
- err = finaladd (file, ci->rev ? ci->rev : xrev, ci->tag, ci->options,
- update_dir, repository, entries);
- if (xrev)
- free (xrev);
- }
- else if (ci->status == T_MODIFIED)
- {
- locate_rcs (file, repository, rcs);
- err = Checkin ('M', file, update_dir, repository,
- rcs, ci->rev, ci->tag,
- ci->options, message, entries);
- if (err != 0)
- {
- unlockrcs (file, repository);
- fixbranch (file, repository, sbranch);
- }
- }
- else if (ci->status == T_REMOVED)
- {
- err = remove_file (file, repository, ci->tag, message,
- entries, srcfiles);
-#ifdef SERVER_SUPPORT
- if (server_active) {
- server_scratch_entry_only ();
- server_updated (file, update_dir, repository,
- /* Doesn't matter, it won't get checked. */
- SERVER_UPDATED, (struct stat *) NULL,
- (unsigned char *) NULL);
- }
-#endif
- }
-
-out:
- if (err != 0)
- {
- /* on failure, remove the file from ulist */
- p = findnode (ulist, file);
- if (p)
- delnode (p);
- }
-
- return (err);
-}
-
-/*
- * Log the commit and clean up the update list
- */
-/* ARGSUSED */
-static int
-commit_filesdoneproc (err, repository, update_dir)
- int err;
- char *repository;
- char *update_dir;
-{
- char *xtag = (char *) NULL;
- Node *p;
- List *ulist;
-
- p = findnode (mulist, update_dir);
- if (p == NULL)
- return (err);
-
- ulist = ((struct master_lists *) p->data)->ulist;
-
- got_message = 0;
-
- /* see if we need to specify a per-directory or -r option tag */
- if (tag == NULL)
- ParseTag (&xtag, (char **) NULL);
-
- Update_Logfile (repository, message, tag ? tag : xtag, (FILE *) 0, ulist);
- if (xtag)
- free (xtag);
-
- if (err == 0 && run_module_prog)
- {
- FILE *fp;
-
- if ((fp = fopen (CVSADM_CIPROG, "r")) != NULL)
- {
- char *line;
- int line_length;
- size_t line_chars_allocated;
- char *repository;
-
- line = NULL;
- line_chars_allocated = 0;
- line_length = getline (&line, &line_chars_allocated, fp);
- if (line_length > 0)
- {
- /* Remove any trailing newline. */
- if (line[line_length - 1] == '\n')
- line[--line_length] = '\0';
- repository = Name_Repository ((char *) NULL, update_dir);
- run_setup ("%s %s", line, repository);
- (void) printf ("%s %s: Executing '", program_name,
- command_name);
- run_print (stdout);
- (void) printf ("'\n");
- (void) run_exec (RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL);
- free (repository);
- }
- else
- {
- if (ferror (fp))
- error (0, errno, "warning: error reading %s",
- CVSADM_CIPROG);
- }
- if (line != NULL)
- free (line);
- if (fclose (fp) < 0)
- error (0, errno, "warning: cannot close %s", CVSADM_CIPROG);
- }
- else
- {
- if (! existence_error (errno))
- error (0, errno, "warning: cannot open %s", CVSADM_CIPROG);
- }
- }
-
- return (err);
-}
-
-/*
- * Get the log message for a dir and print a warm fuzzy
- */
-/* ARGSUSED */
-static Dtype
-commit_direntproc (dir, repos, update_dir)
- char *dir;
- char *repos;
- char *update_dir;
-{
- Node *p;
- List *ulist;
- char *real_repos;
-
- /* find the update list for this dir */
- p = findnode (mulist, update_dir);
- if (p != NULL)
- ulist = ((struct master_lists *) p->data)->ulist;
- else
- ulist = (List *) NULL;
-
- /* skip the files as an optimization */
- if (ulist == NULL || ulist->list->next == ulist->list)
- return (R_SKIP_FILES);
-
- /* print the warm fuzzy */
- if (!quiet)
- error (0, 0, "Committing %s", update_dir);
-
- /* get commit message */
- if (use_editor)
- {
- got_message = 1;
- real_repos = Name_Repository (dir, update_dir);
- do_editor (update_dir, &message, real_repos, ulist);
- free (real_repos);
- }
- return (R_PROCESS);
-}
-
-/*
- * Process the post-commit proc if necessary
- */
-/* ARGSUSED */
-static int
-commit_dirleaveproc (dir, err, update_dir)
- char *dir;
- int err;
- char *update_dir;
-{
- /* update the per-directory tag info */
- if (err == 0 && write_dirtag != NULL)
- {
- WriteTag ((char *) NULL, write_dirtag, (char *) NULL);
-#ifdef SERVER_SUPPORT
- if (server_active)
- server_set_sticky (update_dir, Name_Repository (dir, update_dir),
- write_dirtag, (char *) NULL);
-#endif
- }
-
- return (err);
-}
-
-/*
- * find the maximum major rev number in an entries file
- */
-static int
-findmaxrev (p, closure)
- Node *p;
- void *closure;
-{
- char *cp;
- int thisrev;
- Entnode *entdata;
-
- entdata = (Entnode *) p->data;
- cp = strchr (entdata->version, '.');
- if (cp != NULL)
- *cp = '\0';
- thisrev = atoi (entdata->version);
- if (cp != NULL)
- *cp = '.';
- if (thisrev > maxrev)
- maxrev = thisrev;
- return (0);
-}
-
-/*
- * Actually remove a file by moving it to the attic
- * XXX - if removing a ,v file that is a relative symbolic link to
- * another ,v file, we probably should add a ".." component to the
- * link to keep it relative after we move it into the attic.
- */
-static int
-remove_file (file, repository, tag, message, entries, srcfiles)
- char *file;
- char *repository;
- char *tag;
- char *message;
- List *entries;
- List *srcfiles;
-{
- mode_t omask;
- int retcode;
- char rcs[PATH_MAX];
- char *tmp;
-
-#ifdef DEATH_SUPPORT
- int branch;
- char *lockflag;
- char *corev;
- char *rev;
- char *prev_rev;
- Node *p;
- RCSNode *rcsfile;
-
- corev = NULL;
- rev = NULL;
- prev_rev = NULL;
- lockflag = 0;
-#endif /* DEATH_SUPPORT */
-
- retcode = 0;
-
- locate_rcs (file, repository, rcs);
-
-#ifdef DEATH_SUPPORT
- branch = 0;
- if (tag && !(branch = RCS_isbranch (file, tag, srcfiles)))
-#else
- if (tag)
-#endif
- {
- /* a symbolic tag is specified; just remove the tag from the file */
- if ((retcode = RCS_deltag (rcs, tag, 1)) != 0)
- {
- if (!quiet)
- error (0, retcode == -1 ? errno : 0,
- "failed to remove tag `%s' from `%s'", tag, rcs);
- return (1);
- }
- Scratch_Entry (entries, file);
- return (0);
- }
-
-#ifdef DEATH_SUPPORT
- /* we are removing the file from either the head or a branch */
- /* commit a new, dead revision. */
-
- /* Print message indicating that file is going to be removed. */
- (void) printf ("Removing %s;\n", file);
-
- rev = NULL;
- lockflag = "-l";
- if (branch)
- {
- char *branchname;
-
- rev = RCS_whatbranch (file, tag, srcfiles);
- if (rev == NULL)
- {
- error (0, 0, "cannot find branch \"%s\".", tag);
- return (1);
- }
-
- p = findnode (srcfiles, file);
- if (p == NULL)
- {
- error (0, 0, "boy, I'm confused.");
- return (1);
- }
- rcsfile = (RCSNode *) p->data;
- branchname = RCS_getbranch (rcsfile, rev, 1);
- if (branchname == NULL)
- {
- /* no revision exists on this branch. use the previous
- revision but do not lock. */
- corev = RCS_gettag (rcsfile, tag, 1, 0);
- prev_rev = xstrdup(rev);
- lockflag = "";
- } else
- {
- corev = xstrdup (rev);
- prev_rev = xstrdup(branchname);
- free (branchname);
- }
-
- } else /* Not a branch */
- {
-
- /* Get current head revision of file. */
- p = findnode (srcfiles, file);
- if (p == NULL)
- {
- error (0, 0, "could not find parsed rcsfile %s", file);
- return (1);
- }
- rcsfile = (RCSNode *) p->data;
- prev_rev = RCS_head (rcsfile);
- }
-
- /* if removing without a tag or a branch, then make sure the default
- branch is the trunk. */
- if (!tag && !branch)
- {
- if (RCS_setbranch (rcs, NULL) != 0)
- {
- error (0, 0, "cannot change branch to default for %s",
- rcs);
- return (1);
- }
- }
-
-#ifdef SERVER_SUPPORT
- if (server_active) {
- /* If this is the server, there will be a file sitting in the
- temp directory which is the kludgy way in which server.c
- tells time_stamp that the file is no longer around. Remove
- it so we can create temp files with that name (ignore errors). */
- unlink_file (file);
- }
-#endif
-
- /* check something out. Generally this is the head. If we have a
- particular rev, then name it. except when creating a branch,
- lock the rev we're checking out. */
- run_setup ("%s%s %s %s%s %s", Rcsbin, RCS_CO,
- lockflag,
- rev ? "-r" : "",
- rev ? corev : "", rcs);
- if ((retcode = run_exec (RUN_TTY, RUN_TTY, DEVNULL, RUN_NORMAL))
- != 0) {
- if (!quiet)
- error (0, retcode == -1 ? errno : 0,
- "failed to check out `%s'", rcs);
- return (1);
- }
-
- if (corev != NULL)
- free (corev);
-
-#ifdef DEATH_STATE
- run_setup ("%s%s -f -sdead %s%s", Rcsbin, RCS_CI, rev ? "-r" : "",
-#else
- run_setup ("%s%s -K %s%s", Rcsbin, RCS_CI, rev ? "-r" : "",
-#endif
- rev ? rev : "");
- run_args ("-m%s", make_message_rcslegal (message));
- run_arg (rcs);
- if ((retcode = run_exec (RUN_TTY, RUN_TTY, DEVNULL, RUN_NORMAL))
- != 0) {
- if (!quiet)
- error (0, retcode == -1 ? errno : 0,
- "failed to commit dead revision for `%s'", rcs);
- return (1);
- }
-
- if (rev != NULL)
- free (rev);
-
- if (!branch)
-#else /* No DEATH_SUPPORT */
- else
-#endif /* No DEATH_SUPPORT */
- {
- /* this was the head; really move it into the Attic */
- tmp = xmalloc(strlen(repository) +
- sizeof('/') +
- sizeof(CVSATTIC) +
- sizeof('/') +
- strlen(file) +
- sizeof(RCSEXT) + 1);
- (void) sprintf (tmp, "%s/%s", repository, CVSATTIC);
- omask = umask (cvsumask);
- (void) CVS_MKDIR (tmp, 0777);
- (void) umask (omask);
- (void) sprintf (tmp, "%s/%s/%s%s", repository, CVSATTIC, file, RCSEXT);
-
-#ifdef DEATH_SUPPORT
- if (strcmp (rcs, tmp) != 0
- && rename (rcs, tmp) == -1
- && (isreadable (rcs) || !isreadable (tmp)))
- {
- free(tmp);
- return (1);
- }
- free(tmp);
- }
-
- /* Print message that file was removed. */
- (void) printf ("%s <-- %s\n", rcs, file);
- (void) printf ("new revision: delete; ");
- (void) printf ("previous revision: %s\n", prev_rev);
- (void) printf ("done\n");
- free(prev_rev);
-
- Scratch_Entry (entries, file);
- return (0);
-#else /* No DEATH_SUPPORT */
-
- if ((strcmp (rcs, tmp) == 0 || rename (rcs, tmp) != -1) ||
- (!isreadable (rcs) && isreadable (tmp)))
- {
- Scratch_Entry (entries, file);
- /* FIXME: should free tmp. */
- return (0);
- }
- /* FIXME: should free tmp. */
- }
- return (1);
-#endif /* No DEATH_SUPPORT */
-}
-
-/*
- * Do the actual checkin for added files
- */
-static int
-finaladd (file, rev, tag, options, update_dir, repository, entries)
- char *file;
- char *rev;
- char *tag;
- char *options;
- char *update_dir;
- char *repository;
- List *entries;
-{
- int ret;
- char tmp[PATH_MAX];
- char rcs[PATH_MAX];
-
- locate_rcs (file, repository, rcs);
- ret = Checkin ('A', file, update_dir, repository, rcs, rev, tag, options,
- message, entries);
- if (ret == 0)
- {
- (void) sprintf (tmp, "%s/%s%s", CVSADM, file, CVSEXT_LOG);
- (void) unlink_file (tmp);
- }
- else
- fixaddfile (file, repository);
- return (ret);
-}
-
-/*
- * Unlock an rcs file
- */
-static void
-unlockrcs (file, repository)
- char *file;
- char *repository;
-{
- char rcs[PATH_MAX];
- int retcode = 0;
-
- locate_rcs (file, repository, rcs);
-
- if ((retcode = RCS_unlock (rcs, NULL, 0)) != 0)
- error (retcode == -1 ? 1 : 0, retcode == -1 ? errno : 0,
- "could not unlock %s", rcs);
-}
-
-/*
- * remove a partially added file. if we can parse it, leave it alone.
- */
-static void
-fixaddfile (file, repository)
- char *file;
- char *repository;
-{
- RCSNode *rcsfile;
- char rcs[PATH_MAX];
- int save_really_quiet;
-
- locate_rcs (file, repository, rcs);
- save_really_quiet = really_quiet;
- really_quiet = 1;
- if ((rcsfile = RCS_parsercsfile (rcs)) == NULL)
- (void) unlink_file (rcs);
- else
- freercsnode (&rcsfile);
- really_quiet = save_really_quiet;
-}
-
-/*
- * put the branch back on an rcs file
- */
-static void
-fixbranch (file, repository, branch)
- char *file;
- char *repository;
- char *branch;
-{
- char rcs[PATH_MAX];
- int retcode = 0;
-
- if (branch != NULL && branch[0] != '\0')
- {
- locate_rcs (file, repository, rcs);
- if ((retcode = RCS_setbranch (rcs, branch)) != 0)
- error (retcode == -1 ? 1 : 0, retcode == -1 ? errno : 0,
- "cannot restore branch to %s for %s", branch, rcs);
- }
-}
-
-/*
- * do the initial part of a file add for the named file. if adding
- * with a tag, put the file in the Attic and point the symbolic tag
- * at the committed revision.
- */
-
-static int
-checkaddfile (file, repository, tag, options, srcfiles)
- char *file;
- char *repository;
- char *tag;
- char *options;
- List *srcfiles;
-{
- char rcs[PATH_MAX];
- char fname[PATH_MAX];
- mode_t omask;
- int retcode = 0;
-#ifdef DEATH_SUPPORT
- int newfile = 0;
-#endif
-
- if (tag)
- {
- (void) sprintf(rcs, "%s/%s", repository, CVSATTIC);
- omask = umask (cvsumask);
- if (CVS_MKDIR (rcs, 0777) != 0 && errno != EEXIST)
- error (1, errno, "cannot make directory `%s'", rcs);;
- (void) umask (omask);
- (void) sprintf (rcs, "%s/%s/%s%s", repository, CVSATTIC, file, RCSEXT);
- }
- else
- locate_rcs (file, repository, rcs);
-
-#ifdef DEATH_SUPPORT
- if (isreadable(rcs))
- {
- /* file has existed in the past. Prepare to resurrect. */
- char oldfile[PATH_MAX];
- char *rev;
- Node *p;
- RCSNode *rcsfile;
-
- if (tag == NULL)
- {
- /* we are adding on the trunk, so move the file out of the
- Attic. */
- strcpy (oldfile, rcs);
- sprintf (rcs, "%s/%s%s", repository, file, RCSEXT);
-
- if (strcmp (oldfile, rcs) == 0
- || rename (oldfile, rcs) != 0
- || isreadable (oldfile)
- || !isreadable (rcs))
- {
- error (0, 0, "failed to move `%s' out of the attic.",
- file);
- return (1);
- }
- }
-
- p = findnode (srcfiles, file);
- if (p == NULL)
- {
- error (0, 0, "could not find parsed rcsfile %s", file);
- return (1);
- }
-
- rcsfile = (RCSNode *) p->data;
- rev = RCS_getversion (rcsfile, tag, NULL, 1, 0);
- /* and lock it */
- if (lock_RCS (file, rcs, rev, repository)) {
- error (0, 0, "cannot lock `%s'.", rcs);
- free (rev);
- return (1);
- }
-
- free (rev);
- } else {
- /* this is the first time we have ever seen this file; create
- an rcs file. */
- run_setup ("%s%s -i", Rcsbin, RCS);
-
- (void) sprintf (fname, "%s/%s%s", CVSADM, file, CVSEXT_LOG);
- /* If the file does not exist, no big deal. In particular, the
- server does not (yet at least) create CVSEXT_LOG files. */
- if (isfile (fname))
- run_args ("-t%s/%s%s", CVSADM, file, CVSEXT_LOG);
-
- /* Set RCS keyword expansion options. */
- if (options && options[0] == '-' && options[1] == 'k')
- run_arg (options);
- run_arg (rcs);
- if ((retcode = run_exec (RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL)) != 0)
- {
- error (retcode == -1 ? 1 : 0, retcode == -1 ? errno : 0,
- "could not create %s", rcs);
- return (1);
- }
- newfile = 1;
- }
-
- /* when adding a file for the first time, and using a tag, we need
- to create a dead revision on the trunk. */
- if (tag && newfile)
- {
- char tmp[PATH_MAX];
-
- /* move the new file out of the way. */
- (void) sprintf (fname, "%s/%s%s", CVSADM, CVSPREFIX, file);
- rename_file (file, fname);
- copy_file (DEVNULL, file);
-
- /* commit a dead revision. */
- (void) sprintf (tmp, "-mfile %s was initially added on branch %s.", file, tag);
-#ifdef DEATH_STATE
- run_setup ("%s%s -q -f -sdead", Rcsbin, RCS_CI);
-#else
- run_setup ("%s%s -q -K", Rcsbin, RCS_CI);
-#endif
- run_arg (tmp);
- run_arg (rcs);
- if ((retcode = run_exec (RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL)) != 0)
- {
- error (retcode == -1 ? 1 : 0, retcode == -1 ? errno : 0,
- "could not create initial dead revision %s", rcs);
- return (1);
- }
-
- /* put the new file back where it was */
- rename_file (fname, file);
-
- /* and lock it once again. */
- if (lock_RCS (file, rcs, NULL, repository)) {
- error (0, 0, "cannot lock `%s'.", rcs);
- return (1);
- }
- }
-
- if (tag != NULL)
- {
- /* when adding with a tag, we need to stub a branch, if it
- doesn't already exist. */
- Node *p;
- RCSNode *rcsfile;
-
- rcsfile = RCS_parse (file, repository);
- if (rcsfile == NULL)
- {
- error (0, 0, "could not read %s", rcs);
- return (1);
- }
-
- if (!RCS_nodeisbranch (tag, rcsfile)) {
- /* branch does not exist. Stub it. */
- char *head;
- char *magicrev;
-
- head = RCS_getversion (rcsfile, NULL, NULL, 0, 0);
- magicrev = RCS_magicrev (rcsfile, head);
- if ((retcode = RCS_settag(rcs, tag, magicrev)) != 0)
- {
- error (retcode == -1 ? 1 : 0, retcode == -1 ? errno : 0,
- "could not stub branch %s for %s", tag, rcs);
- return (1);
- }
-
- freercsnode (&rcsfile);
-
- /* reparse the file, then add it to our list. */
- rcsfile = RCS_parse (file, repository);
- if (rcsfile == NULL)
- {
- error (0, 0, "could not reparse %s", rcs);
- return (1);
- }
-
- free (head);
- free (magicrev);
- }
- else
- {
- /* lock the branch. (stubbed branches need not be locked.) */
- if (lock_RCS (file, rcs, NULL, repository)) {
- error (0, 0, "cannot lock `%s'.", rcs);
- return (1);
- }
- }
-
- /* add (replace) this rcs file to our list */
- p = findnode (srcfiles, file);
-
- if (p != NULL)
- freercsnode((RCSNode **) &p->data);
-
- delnode(p);
-
- RCS_addnode (file, rcsfile, srcfiles);
- }
-#else /* No DEATH_SUPPORT */
- run_setup ("%s%s -i", Rcsbin, RCS);
- run_args ("-t%s/%s%s", CVSADM, file, CVSEXT_LOG);
- /* Set RCS keyword expansion options. */
- if (options && options[0] == '-' && options[1] == 'k')
- run_arg (options);
- run_arg (rcs);
- if ((retcode = run_exec (RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL)) != 0)
- {
- error (retcode == -1 ? 1 : 0, retcode == -1 ? errno : 0,
- "could not create %s", rcs);
- return (1);
- }
-#endif /* No DEATH_SUPPORT */
-
- fix_rcs_modes (rcs, file);
- return (0);
-}
-
-/*
- * Lock the rcs file ``file''
- */
-static int
-lockrcsfile (file, repository, rev)
- char *file;
- char *repository;
- char *rev;
-{
- char rcs[PATH_MAX];
-
- locate_rcs (file, repository, rcs);
- if (lock_RCS (file, rcs, rev, repository) != 0)
- return (1);
- else
- return (0);
-}
-
-/*
- * Attempt to place a lock on the RCS file; returns 0 if it could and 1 if it
- * couldn't. If the RCS file currently has a branch as the head, we must
- * move the head back to the trunk before locking the file, and be sure to
- * put the branch back as the head if there are any errors.
- */
-static int
-lock_RCS (user, rcs, rev, repository)
- char *user;
- char *rcs;
- char *rev;
- char *repository;
-{
- RCSNode *rcsfile;
- char *branch = NULL;
- int err = 0;
-
- /*
- * For a specified, numeric revision of the form "1" or "1.1", (or when
- * no revision is specified ""), definitely move the branch to the trunk
- * before locking the RCS file.
- *
- * The assumption is that if there is more than one revision on the trunk,
- * the head points to the trunk, not a branch... and as such, it's not
- * necessary to move the head in this case.
- */
- if (rev == NULL || (rev && isdigit (*rev) && numdots (rev) < 2))
- {
- if ((rcsfile = RCS_parsercsfile (rcs)) == NULL)
- {
- /* invalid rcs file? */
- err = 1;
- }
- else
- {
- /* rcsfile is valid */
- branch = xstrdup (rcsfile->branch);
- freercsnode (&rcsfile);
- if (branch != NULL)
- {
- if (RCS_setbranch (rcs, NULL) != 0)
- {
- error (0, 0, "cannot change branch to default for %s",
- rcs);
- if (branch)
- free (branch);
- return (1);
- }
- }
- err = RCS_lock(rcs, NULL, 0);
- }
- }
- else
- {
- (void) RCS_lock(rcs, rev, 1);
- }
-
- if (err == 0)
- {
- if (branch)
- {
- (void) strcpy (sbranch, branch);
- free (branch);
- }
- else
- sbranch[0] = '\0';
- return (0);
- }
-
- /* try to restore the branch if we can on error */
- if (branch != NULL)
- fixbranch (user, repository, branch);
-
- if (branch)
- free (branch);
- return (1);
-}
-
-/*
- * Called when "add"ing files to the RCS respository, as it is necessary to
- * preserve the file modes in the same fashion that RCS does. This would be
- * automatic except that we are placing the RCS ,v file very far away from
- * the user file, and I can't seem to convince RCS of the location of the
- * user file. So we munge it here, after the ,v file has been successfully
- * initialized with "rcs -i".
- */
-static void
-fix_rcs_modes (rcs, user)
- char *rcs;
- char *user;
-{
- struct stat sb;
-
- if (stat (user, &sb) != -1)
- (void) chmod (rcs, (int) sb.st_mode & ~0222);
-}
-
-/*
- * free an UPDATE node's data (really nothing to do)
- */
-void
-update_delproc (p)
- Node *p;
-{
- p->data = (char *) NULL;
-}
-
-/*
- * Free the commit_info structure in p.
- */
-static void
-ci_delproc (p)
- Node *p;
-{
- struct commit_info *ci;
-
- ci = (struct commit_info *) p->data;
- if (ci->rev)
- free (ci->rev);
- if (ci->tag)
- free (ci->tag);
- if (ci->options)
- free (ci->options);
- free (ci);
-}
-
-/*
- * Free the commit_info structure in p.
- */
-static void
-masterlist_delproc (p)
- Node *p;
-{
- struct master_lists *ml;
-
- ml = (struct master_lists *) p->data;
- dellist (&ml->ulist);
- dellist (&ml->cilist);
- free (ml);
-}
-
-/*
- * Find an RCS file in the repository.
- */
-static void
-locate_rcs (file, repository, rcs)
- char *file;
- char *repository;
- char *rcs;
-{
- (void) sprintf (rcs, "%s/%s%s", repository, file, RCSEXT);
- if (!isreadable (rcs))
- {
- (void) sprintf (rcs, "%s/%s/%s%s", repository, CVSATTIC, file, RCSEXT);
- if (!isreadable (rcs))
- (void) sprintf (rcs, "%s/%s%s", repository, file, RCSEXT);
- }
-}
diff --git a/gnu/usr.bin/cvs/cvs/convert.sh b/gnu/usr.bin/cvs/cvs/convert.sh
deleted file mode 100644
index 94bbdcc8b551..000000000000
--- a/gnu/usr.bin/cvs/cvs/convert.sh
+++ /dev/null
@@ -1,28 +0,0 @@
-#!/bin/sh
-#
-# short script to convert cvs repositories to support file death.
-#
-
-WORKDIR=/tmp/$$-cvs-convert
-mkdir ${WORKDIR}
-cd ${WORKDIR}
-
-case $# in
-1) ;;
-*)
- echo Usage: convert repository 2>&1
- exit 1
- ;;
-esac
-
-attics=`find $1 -name Attic -print`
-
-for i in ${attics} ; do
- mkdir $i/SAVE
- for j in $i/*,v ; do
- echo $j
- cp $j $i/SAVE
- co -l $j
- ci -K -m"recording file death" $j
- done
-done
diff --git a/gnu/usr.bin/cvs/cvs/create_adm.c b/gnu/usr.bin/cvs/cvs/create_adm.c
deleted file mode 100644
index 1fe81855adf3..000000000000
--- a/gnu/usr.bin/cvs/cvs/create_adm.c
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * Copyright (c) 1992, Brian Berliner and Jeff Polk
- * Copyright (c) 1989-1992, Brian Berliner
- *
- * You may distribute under the terms of the GNU General Public License as
- * specified in the README file that comes with the CVS 1.4 kit.
- *
- * Create Administration.
- *
- * Creates a CVS administration directory based on the argument repository; the
- * "Entries" file is prefilled from the "initrecord" argument.
- */
-
-#include "cvs.h"
-
-#ifndef lint
-static const char rcsid[] = "$CVSid: @(#)create_adm.c 1.28 94/09/23 $";
-USE(rcsid);
-#endif
-
-/* update_dir includes dir as its last component. */
-
-void
-Create_Admin (dir, update_dir, repository, tag, date)
- char *dir;
- char *update_dir;
- char *repository;
- char *tag;
- char *date;
-{
- FILE *fout;
- char *cp;
- char tmp[PATH_MAX];
-
-#ifdef SERVER_SUPPORT
- if (trace)
- {
- char wd[PATH_MAX];
- getwd (wd);
- fprintf (stderr, "%c-> Create_Admin (%s, %s, %s, %s, %s) in %s\n",
- (server_active) ? 'S' : ' ',
- dir, update_dir, repository, tag ? tag : "",
- date ? date : "", wd);
- }
-#endif
-
- if (noexec)
- return;
-
- if (dir != NULL)
- (void) sprintf (tmp, "%s/%s", dir, CVSADM);
- else
- (void) strcpy (tmp, CVSADM);
- if (isfile (tmp))
- error (1, 0, "there is a version in %s already", update_dir);
-
- make_directory (tmp);
-
-#ifdef CVSADM_ROOT
- /* record the current cvs root for later use */
-
- Create_Root (dir, CVSroot);
-#endif /* CVSADM_ROOT */
- if (dir != NULL)
- (void) sprintf (tmp, "%s/%s", dir, CVSADM_REP);
- else
- (void) strcpy (tmp, CVSADM_REP);
- fout = fopen (tmp, "w+");
- if (fout == NULL)
- {
- if (update_dir[0] == '\0')
- error (1, errno, "cannot open %s", tmp);
- else
- error (1, errno, "cannot open %s/%s", update_dir, CVSADM_REP);
- }
- cp = repository;
- strip_path (cp);
-
-#ifdef RELATIVE_REPOS
- /*
- * If the Repository file is to hold a relative path, try to strip off
- * the leading CVSroot argument.
- */
- if (CVSroot != NULL)
- {
- char path[PATH_MAX];
-
- (void) sprintf (path, "%s/", CVSroot);
- if (strncmp (repository, path, strlen (path)) == 0)
- cp = repository + strlen (path);
- }
-#endif
-
- if (fprintf (fout, "%s\n", cp) < 0)
- {
- if (update_dir[0] == '\0')
- error (1, errno, "write to %s failed", tmp);
- else
- error (1, errno, "write to %s/%s failed", update_dir, CVSADM_REP);
- }
- if (fclose (fout) == EOF)
- {
- if (update_dir[0] == '\0')
- error (1, errno, "cannot close %s", tmp);
- else
- error (1, errno, "cannot close %s/%s", update_dir, CVSADM_REP);
- }
-
- /* now, do the Entries file */
- if (dir != NULL)
- (void) sprintf (tmp, "%s/%s", dir, CVSADM_ENT);
- else
- (void) strcpy (tmp, CVSADM_ENT);
- fout = fopen (tmp, "w+");
- if (fout == NULL)
- {
- if (update_dir[0] == '\0')
- error (1, errno, "cannot open %s", tmp);
- else
- error (1, errno, "cannot open %s/%s", update_dir, CVSADM_ENT);
- }
- if (fclose (fout) == EOF)
- {
- if (update_dir[0] == '\0')
- error (1, errno, "cannot close %s", tmp);
- else
- error (1, errno, "cannot close %s/%s", update_dir, CVSADM_ENT);
- }
-
- /* Create a new CVS/Tag file */
- WriteTag (dir, tag, date);
-
-#ifdef SERVER_SUPPORT
- if (server_active)
- server_set_sticky (update_dir, repository, tag, date);
-
- if (trace)
- {
- fprintf (stderr, "%c<- Create_Admin\n",
- (server_active) ? 'S' : ' ');
- }
-#endif
-
-}
diff --git a/gnu/usr.bin/cvs/cvs/cvs.1 b/gnu/usr.bin/cvs/cvs/cvs.1
deleted file mode 100644
index 5a703016ce38..000000000000
--- a/gnu/usr.bin/cvs/cvs/cvs.1
+++ /dev/null
@@ -1,2185 +0,0 @@
-.de Id
-.ds Rv \\$3
-.ds Dt \\$4
-..
-.Id $Id: cvs.1,v 1.7 1995/11/15 01:02:41 woods Exp $
-.TH CVS 1 "\*(Dt"
-.\" Full space in nroff; half space in troff
-.de SP
-.if n .sp
-.if t .sp .5
-..
-.\" quoted command
-.de `
-.RB ` "\|\\$1\|" '\\$2
-..
-.SH "NAME"
-cvs \- Concurrent Versions System
-.SH "SYNOPSIS"
-.TP
-\fBcvs\fP [ \fIcvs_options\fP ]
-.I cvs_command
-[
-.I command_options
-] [
-.I command_args
-]
-.SH "DESCRIPTION"
-.IX "revision control system" "\fLcvs\fR"
-.IX cvs "" "\fLcvs\fP \- concurrent versions system"
-.IX "concurrent versions system \- \fLcvs\fP"
-.IX "release control system" "cvs command" "" "\fLcvs\fP \- concurrent versions system"
-.IX "source control system" "cvs command" "" "\fLcvs\fP \- concurrent versions system"
-.IX revisions "cvs command" "" "\fLcvs\fP \- source control"
-.B cvs
-is a front end to the
-.BR rcs ( 1 )
-revision control system which extends
-the notion of revision control from a collection of files in a single
-directory to a hierarchical collection of directories consisting of
-revision controlled files.
-These directories and files can be combined together to form a software
-release.
-.B cvs
-provides the functions necessary to manage these software releases and to
-control the concurrent editing of source files among multiple software
-developers.
-.SP
-.B cvs
-keeps a single copy of the master sources.
-This copy is called the source ``repository''; it contains all the
-information to permit extracting previous software releases at any
-time based on either a symbolic revision tag, or a date in the past.
-.SH "ESSENTIAL COMMANDS"
-.B cvs
-provides a rich variety of commands (\fIcvs_command\fP in the
-Synopsis), each of which often has a wealth of options, to satisfy the
-many needs of source management in distributed environments. However,
-you don't have to master every detail to do useful work with
-.BR cvs ;
-in fact, five commands are sufficient to use (and contribute to)
-the source repository.
-.TP
-\fBcvs checkout\fP \fImodules\fP\|.\|.\|.
-A necessary preliminary for most \fBcvs\fP work: creates your private
-copy of the source for \fImodules\fP (named collections of source; you
-can also use a path relative to the source repository here). You can
-work with this copy without interfering with others' work. At least
-one subdirectory level is always created.
-.TP
-.B cvs update
-Execute this command from \fIwithin\fP your private source
-directory when you wish to update your copies of source files from
-changes that other developers have made to the source in the
-repository.
-.TP
-\fBcvs add\fP \fIfile\fP\|.\|.\|.
-Use this command to enroll new files in \fBcvs\fP records of your
-working directory. The files will be added to the repository the next
-time you run
-.` "cvs commit".
-Note:
-You should use the
-.` "cvs import"
-command to bootstrap new sources into the source repository.
-.` "cvs add"
-is only used for new files to an already checked-out module.
-.TP
-\fBcvs remove\fP \fIfile\fP\|.\|.\|.
-Use this command (after erasing any files listed) to declare that you
-wish to eliminate files from the repository. The removal does not
-affect others until you run
-.` "cvs commit".
-.TP
-\fBcvs commit\fP \fIfile\fP\|.\|.\|.
-Use this command when you wish to ``publish'' your changes to other
-developers, by incorporating them in the source repository.
-.SH "OPTIONS"
-The
-.B cvs
-command line can include
-.IR cvs_options ,
-which apply to the overall
-.B cvs
-program; a
-.IR cvs_command ,
-which specifies a particular action on the source repository; and
-.I command_options
-and
-.I command_arguments
-to fully specify what the
-.I cvs_command
-will do.
-.SP
-.I Warning:
-you must be careful of precisely where you place options relative to the
-.IR cvs_command .
-The same option can mean different things depending on whether it
-is in the
-.I cvs_options
-position (to the left of a
-.B cvs
-command) or in the
-.I command_options
-position (to the right of a
-.B cvs
-command).
-.SP
-There are only two situations where you may omit
-.IR cvs_command :
-.` "cvs \-H"
-or
-.` "cvs --help"
-elicits a list of available commands, and
-.` "cvs \-v"
-or
-.` "cvs --version"
-displays version information on \fBcvs\fP itself.
-.SP
-.SH "CVS OPTIONS"
-As of release 1.6,
-.B cvs
-supports
-.SM GNU
-style long options as well as short options. Only
-a few long options are currently supported, these are listed in
-brackets after the short options whose functions they duplicate.
-.SP
-Use these options to control the overall
-.B cvs
-program:
-.TP
-.B \-H [ --help ]
-Display usage information about the specified
-.I cvs_command
-(but do not actually execute the command). If you don't specify a
-command name,
-.` "cvs \-H"
-displays a summary of all the commands available.
-.TP
-.B \-Q
-Causes the command to be
-.I really
-quiet; the command will generate output only for serious problems.
-.TP
-.B \-q
-Causes the command to be somewhat quiet; informational messages, such
-as reports of recursion through subdirectories, are suppressed.
-.TP
-\fB\-b\fP \fIbindir\fP
-Use
-.I bindir
-as the directory where
-.SM RCS
-programs are located.
-Overrides the setting of the
-.SM RCSBIN
-environment variable.
-This value should be specified as an absolute pathname.
-.TP
-\fB\-d\fP \fICVS_root_directory\fP
-Use
-.I CVS_root_directory
-as the root directory pathname of the master
-.SM RCS
-source repository.
-Overrides the setting of the
-.SM CVSROOT
-environment variable.
-This value should be specified as an absolute pathname.
-.TP
-\fB\-e\fP \fIeditor\fP
-Use
-.I editor
-to enter revision log information.
-Overrides the setting of the
-.SM CVSEDITOR
-and the
-.SM EDITOR
-environment variables.
-.TP
-.B \-f
-Do not read the
-.B cvs
-startup file (\fI~/.cvsrc\fP).
-.TP
-.B \-l
-Do not log the
-.I cvs_command
-in the command history (but execute it anyway). See the description
-of the
-.B history
-command for information on command history.
-.TP
-.B \-n
-Do not change any files. Attempt to execute the
-.IR cvs_command ,
-but only to issue reports; do not remove, update, or merge any
-existing files, or create any new files.
-.TP
-.B \-t
-Trace program execution; display messages showing the steps of
-.B cvs
-activity. Particularly useful with
-.B \-n
-to explore the potential impact of an unfamiliar command.
-.TP
-.B \-r
-Makes new working files read-only.
-Same effect as if the
-.SM CVSREAD
-environment variable is set.
-.TP
-.B \-v [ --version ]
-Displays version and copyright information for
-.BR cvs .
-.TP
-.B \-w
-Makes new working files read-write (default).
-Overrides the setting of the
-.SM CVSREAD
-environment variable.
-.TP
-\fB\-z\fP \fIcompression\-level\fP
-When transferring files across the network use
-.B gzip
-with compression level \fIcompression\-level\fP to compress and
-de-compress data as it is transferred. Requires the presence of
-the
-.SM GNU
-.B gzip
-program in the current search path at both ends of the link.
-.SH "USAGE"
-Except when requesting general help with
-.` "cvs \-H",
-you must specify a
-.I cvs_command
-to
-.B cvs
-to select a specific release control function to perform.
-Each
-.B cvs
-command accepts its own collection of options and arguments.
-However, many options are available across several commands.
-You can display a usage summary for each command by specifying the
-.B \-H
-option with the command.
-.SH "CVS STARTUP FILE"
-Normally, when CVS starts up, it reads the
-.I .cvsrc
-file from the home directory of the user reading it. This startup
-procedure can be turned off with the
-.B \-f
-flag.
-.SP
-The
-.I .cvsrc
-file lists CVS commands with a list of arguments, one command per
-line. For example, the following line in \fI.cvsrc\fP:
-.SP
-diff \-c
-.SP
-will mean that the
-.` "cvs diff"
-command will always be passed the \-c option in addition to any
-other options that are specified in the command line (in this case
-it will have the effect of producing context sensitive diffs for
-all executions of
-.` "cvs diff"
-).
-.SH "CVS COMMAND SUMMARY"
-Here are brief descriptions of all the
-.B cvs
-commands:
-.TP
-.B add
-Add a new file or directory to the repository, pending a
-.` "cvs commit"
-on the same file.
-Can only be done from within sources created by a previous
-.` "cvs checkout"
-invocation.
-Use
-.` "cvs import"
-to place whole new hierarchies of sources under
-.B cvs
-control.
-(Does not directly affect repository; changes
-working directory.)
-.TP
-.B admin
-Execute
-.SM RCS
-control functions on the source repository. (Changes
-repository directly; uses working directory without changing it.)
-.TP
-.B checkout
-Make a working directory of source files for editing. (Creates or changes
-working directory.)
-.TP
-.B commit
-Apply to the source repository changes, additions, and deletions from your
-working directory. (Changes repository.)
-.TP
-.B diff
-Show differences between files in working directory and source
-repository, or between two revisions in source repository.
-(Does not change either repository or working directory.)
-.TP
-.B export
-Prepare copies of a set of source files for shipment off site.
-Differs from
-.` "cvs checkout"
-in that no
-.B cvs
-administrative directories are created (and therefore
-.` "cvs commit"
-cannot be executed from a directory prepared with
-.` "cvs export"),
-and a symbolic tag must be specified.
-(Does not change repository; creates directory similar to working
-directories).
-.TP
-.B history
-Show reports on
-.B cvs
-commands that you or others have executed on a particular file or
-directory in the source repository. (Does not change repository or
-working directory.) History logs are kept only if enabled by creation
-of the
-.` "$CVSROOT/CVSROOT/history"
-file; see
-.BR cvs ( 5 ).
-.TP
-.B import
-Incorporate a set of updates from off-site into the source repository,
-as a ``vendor branch''. (Changes repository.)
-.TP
-.B log
-Display
-.SM RCS
-log information.
-(Does not change repository or working directory.)
-.TP
-.B rdiff
-Prepare a collection of diffs as a patch file between two releases in
-the repository. (Does not change repository or working directory.)
-.TP
-.B release
-Cancel a
-.` "cvs checkout",
-abandoning any changes.
-(Can delete working directory; no effect on repository.)
-.TP
-.B remove
-Remove files from the source repository, pending a
-.` "cvs commit"
-on the same files. (Does not directly affect repository;
-changes working directory.)
-.TP
-.B rtag
-Explicitly specify a symbolic tag for particular revisions of files in the
-source repository. See also
-.` "cvs tag".
-(Changes repository directly; does not require or affect
-working directory.)
-.TP
-.B status
-Show current status of files: latest version, version in working
-directory, whether working version has been edited and, optionally,
-symbolic tags in the
-.SM RCS
-file. (Does not change
-repository or working directory.)
-.TP
-.B tag
-Specify a symbolic tag for files in the repository. By default, tags
-the revisions
-that were last synchronized with your working directory. (Changes
-repository directly; uses working directory without changing it.)
-.TP
-.B update
-Bring your working directory up to date with changes from the
-repository. Merges are performed automatically when possible; a
-warning is issued if manual resolution is required for conflicting
-changes. (Changes working directory; does not change repository.)
-.SH "COMMON COMMAND OPTIONS"
-This section describes the
-.I command_options
-that are available across several
-.B cvs
-commands. Not all commands support all of these options; each option
-is only supported for commands where it makes sense. However, when
-a command has one of these options you can count on the same meaning
-for the option as in other commands. (Other command
-options, which are listed with the individual commands, may have
-different meanings from one
-.B cvs
-command to another.)
-.I "Warning:"
-the
-.B history
-command is an exception;
-it supports many options that conflict
-even with these standard options.
-.TP
-\fB\-D\fP \fIdate_spec\fP
-Use the most recent revision no later than \fIdate_spec\fP (a single
-argument, date description specifying a date in the
-past). A wide variety of date formats are supported by the underlying
-.SM RCS
-facilities, similar to those described in
-.BR co ( 1 ),
-but not exactly the same.
-The \fIdate_spec\fP is interpreted as being in the local timezone, unless a
-specific timezone is specified.
-The specification is ``sticky'' when you use it to make a
-private copy of a source file; that is, when you get a working file
-using \fB\-D\fP, \fBcvs\fP records the date you
-specified, so that further updates in the same directory will use the
-same date (unless you explicitly override it; see the description of
-the \fBupdate\fP command).
-.B \-D
-is available with the
-.BR checkout ", " diff ", " history ", " export ", "
-.BR rdiff ", " rtag ", and "
-.B update
-commands.
-Examples of valid date specifications include:
-.in +1i
-.ft B
-.nf
-1 month ago
-2 hours ago
-400000 seconds ago
-last year
-last Monday
-yesterday
-a fortnight ago
-3/31/92 10:00:07 PST
-January 23, 1987 10:05pm
-22:00 GMT
-.fi
-.ft P
-.in -1i
-.TP
-.B \-f
-When you specify a particular date or tag to \fBcvs\fP commands, they
-normally ignore files that do not contain the tag (or did not exist on
-the date) that you specified. Use the \fB\-f\fP option if you want
-files retrieved even when there is no match for the tag or date. (The
-most recent version is used in this situation.)
-.B \-f
-is available with these commands:
-.BR checkout ", " export ", "
-.BR rdiff ", " rtag ", and " update .
-.TP
-.B \-H
-Help; describe the options available for this command. This is the
-only option supported for
-.I all
-.B cvs
-commands.
-.TP
-\fB\-k\fP \fIkflag\fP
-Alter the default
-.SM RCS
-processing of keywords; all the
-.B \-k
-options described in
-.BR co ( 1 )
-are available. The \fB\-k\fP option is available with the
-.BR add ", " checkout ", " diff ", " export ", "
-.BR rdiff ", and " update
-commands. Your \fIkflag\fP specification is ``sticky'' when you use
-it to create a private copy of a source file; that is, when you use
-this option with the \fBcheckout\fP or \fBupdate\fP commands,
-\fBcvs\fP associates your selected \fIkflag\fP with the file, and
-continues to use it with future \fBupdate\fP commands on the same file
-until you specify otherwise.
-.SP
-Some of the more useful \fIkflag\fPs are \-ko and \-kb (for binary files,
-only compatible with
-.SM RCS
-version 5.7 or later), and \-kv which is useful for an
-.B export
-where you wish to retain keyword information after an
-.B import
-at some other site.
-.TP
-.B \-l
-Local; run only in current working directory, rather than recurring through
-subdirectories. Available with the following commands:
-.BR checkout ", " commit ", " diff ", "
-.BR export ", " remove ", " rdiff ", " rtag ", "
-.BR status ", " tag ", and " update .
-.I Warning:
-this is not the same
-as the overall
-.` "cvs \-l"
-option, which you can specify to the
-.I left
-of a
-.B cvs
-command!
-.TP
-.B \-n
-Do
-.I not
-run any
-.BR checkout / commit / tag / update
-program. (A program can be specified to run on each of these
-activities, in the modules database; this option bypasses it.)
-Available with the
-.BR checkout ", " commit ", " export ", and "
-.B rtag
-commands.
-.I Warning:
-this is not the same
-as the overall
-.` "cvs \-n"
-option, which you can specify to the
-.I left
-of a
-.B cvs
-command!
-.TP
-.B \-P
-Prune (remove) directories that are empty after being updated, on
-.BR checkout ", or " update .
-Normally, an empty directory (one that is void of revision-controlled
-files) is left alone.
-Specifying
-.B \-P
-will cause these directories to be silently removed from your checked-out
-sources.
-This does not remove the directory from the repository, only from your
-checked out copy.
-Note that this option is implied by the
-.B \-r
-or
-.B \-D
-options of
-.BR checkout " and " export .
-.TP
-.B \-p
-Pipe the files retrieved from the repository to standard output,
-rather than writing them in the current directory. Available with the
-.BR checkout " and " update
-commands.
-.TP
-\fB\-r\fP \fItag\fP
-Use the revision specified by the
-.I tag
-argument instead of the default ``head'' revision. As well as
-arbitrary tags defined with the \fBtag\fP or \fBrtag\fP command, two
-special tags are always available:
-.` "HEAD"
-refers to the most
-recent version available in the repository, and
-.` "BASE"
-refers to the revision you last checked out into the current working
-directory.
-.SP
-The \fItag\fP specification is ``sticky'' when you use
-this option with
-.` "cvs checkout"
-or
-.` "cvs update"
-to
-make your own copy of a file: \fBcvs\fP remembers the \fItag\fP and
-continues to use it on future \fBupdate\fP commands, until you specify
-otherwise.
-.I tag
-can be either a symbolic or numeric tag, in
-.SM RCS
-fashion.
-Specifying the
-.B \-q
-global option along with the
-.B \-r
-command option is often useful, to suppress the warning messages when the
-.SM RCS
-file does not contain the specified tag.
-.B \-r
-is available with the
-.BR checkout ", " commit ", " diff ", "
-.BR history ", " export ", "
-.BR rdiff ", " rtag ", and " update
-commands.
-.I Warning:
-this is not the same
-as the overall
-.` "cvs \-r"
-option, which you can specify to the
-.I left
-of a
-.B cvs
-command!
-.SH "CVS COMMANDS"
-Here (finally) are details on all the
-.B cvs
-commands and the options each accepts. The summary lines at the top
-of each command's description highlight three kinds of things:
-.TP 1i
-\ \ \ \ Command Options and Arguments
-Special options are described in detail below; common command options
-may appear only in the summary line.
-.TP 1i
-\ \ \ \ Working Directory, or Repository?
-Some \fBcvs\fP commands require a working directory to operate; some
-require a repository. Also, some commands \fIchange\fP the
-repository, some change the working directory, and some change
-nothing.
-.TP 1i
-\ \ \ \ Synonyms
-Many commands have synonyms, which you may find easier to
-remember (or type) than the principal name.
-.PP
-.TP
-\fBadd\fP [\fB\-k\fP \fIkflag\fP] [\fB\-m '\fP\fImessage\fP\fB'\fP] \fIfiles.\|.\|.\fP
-.I Requires:
-repository, working directory.
-.br
-.I Changes:
-working directory.
-.br
-.I Synonym:
-.B new
-.br
-Use the
-.B add
-command to create a new file or directory in the
-.SM RCS
-source repository.
-The files or directories specified with
-.B add
-must already exist in the current directory (which must have been created
-with the
-.B checkout
-command).
-To add a whole new directory hierarchy to the source repository
-(for example, files received from a third-party vendor), use the
-.` "cvs import"
-command instead.
-.SP
-If the argument to
-.` "cvs add"
-refers to an immediate sub-directory, the directory is
-created at the correct place in the
-.SM RCS
-source repository, and the necessary
-.B cvs
-administration files are created in your working directory.
-If the directory already exists in the source repository,
-.` "cvs add"
-still creates the administration files in your version of the directory.
-This allows you to use
-.` "cvs add"
-to add a particular directory to your private sources even if
-someone else created that directory after your
-.B checkout
-of the sources. You can do the following:
-.SP
-.in +1i
-.ft B
-.nf
-example% mkdir new_directory
-example% cvs add new_directory
-example% cvs update new_directory
-.fi
-.ft P
-.in -1i
-.SP
-An alternate approach using
-.` "cvs update"
-might be:
-.SP
-.in +1i
-.ft B
-.nf
-example% cvs update -d new_directory
-.fi
-.ft P
-.in -1i
-.SP
-(To add \fIany available\fP new directories to your working directory, it's
-probably simpler to use
-.` "cvs checkout"
-or
-.` "cvs update -d".)
-.SP
-The added files are not placed in the
-.SM RCS
-source repository until you use
-.` "cvs commit"
-to make the change permanent.
-Doing a
-.` "cvs add"
-on a file that was removed with the
-.` "cvs remove"
-command will resurrect the file, if no
-.` "cvs commit"
-command intervened.
-.SP
-You will have the opportunity to specify a logging message, as usual,
-when you use
-.` "cvs commit"
-to make the new file permanent. If you'd like to have another
-logging message associated with just
-.I creation
-of the file (for example, to describe the file's purpose), you can
-specify it with the
-.` "\-m \fImessage\fP"
-option to the
-.B add
-command.
-.SP
-The
-.` "-k kflag"
-option specifies the default way that this
-file will be checked out.
-The
-.` "kflag"
-argument is stored in the
-.SM RCS
-file and can be changed with
-.` "cvs admin".
-Specifying
-.` "-ko"
-is useful for checking in binaries that
-shouldn't have the
-.SM RCS
-id strings expanded.
-.TP
-\fBadmin\fP [\fIrcs-options\fP] \fIfiles.\|.\|.\fP
-.I Requires:
-repository, working directory.
-.br
-.I Changes:
-repository.
-.br
-.I Synonym:
-.B rcs
-.br
-This is the
-.B cvs
-interface to assorted administrative
-.SM RCS
-facilities, documented in
-.BR rcs ( 1 ).
-.` "cvs admin"
-simply passes all its options and arguments to the
-.B rcs
-command; it does no filtering or other processing.
-This command does work recursively, however, so extreme care should be
-used.
-.TP
-\fBcheckout\fP [\fBoptions\fP] \fImodules\fP.\|.\|.
-.I Requires:
-repository.
-.br
-.I Changes:
-working directory.
-.br
-.I Synonyms:
-.BR co ", " get
-.br
-Make a working directory containing copies of the source files specified by
-.IR modules .
-You must execute
-.` "cvs checkout"
-before using most of the other
-.B cvs
-commands, since most of them operate on your working directory.
-.SP
-\fImodules\fP are either symbolic names (themselves defined as the
-module
-.` "modules"
-in the source repository; see
-.BR cvs ( 5 ))
-for some collection of source directories and files, or paths to
-directories or files in the repository.
-.SP
-Depending on the
-.I modules
-you specify,
-.B checkout
-may recursively create directories and populate them with the appropriate
-source files.
-You can then edit these source files at any time (regardless of whether
-other software developers are editing their own copies of the sources);
-update them to include new changes applied by others to the source
-repository; or commit your work as a permanent change to the
-.SM RCS
-repository.
-.SP
-Note that
-.B checkout
-is used to create directories.
-The top-level directory created is always added to the directory
-where
-.B checkout
-is invoked, and usually has the same name as the specified
-.IR module .
-In the case of a
-.I module
-alias, the created sub-directory may have a different name, but you can be
-sure that it will be a sub-directory, and that
-.B checkout
-will show the relative path leading to each file as it is extracted into
-your private work area (unless you specify the
-.B \-Q
-global option).
-.SP
-Running
-.` "cvs checkout"
-on a directory that was already built by a prior
-.B checkout
-is also permitted, and
-has the same effect as specifying the
-.B \-d
-option to the
-.B update
-command described below.
-.SP
-The
-.I options
-permitted with
-.` "cvs checkout"
-include the standard command options
-.BR \-P ", " \-f ", "
-.BI \-k " kflag"
-\&,
-.BR \-l ", " \-n ", " \-p ", "
-.BR \-r
-.IR tag ", and"
-.BI \-D " date"\c
-\&.
-.SP
-In addition to those, you can use these special command options
-with
-.BR checkout :
-.SP
-Use the
-.B \-A
-option to reset any sticky tags, dates, or
-.B \-k
-options. (If you get a working file using one of the
-\fB\-r\fP, \fB\-D\fP, or \fB\-k\fP options, \fBcvs\fP remembers the
-corresponding tag, date, or \fIkflag\fP and continues using it on
-future updates; use the \fB\-A\fP option to make \fBcvs\fP forget these
-specifications, and retrieve the ``head'' version of the file).
-.SP
-The
-.BI \-j " branch"
-option merges the changes made between the
-resulting revision and the revision that it is based on (e.g., if
-the tag refers to a branch,
-.B cvs
-will merge all changes made in that branch into your working file).
-.SP
-With two \fB-j\fP options,
-.B cvs
-will merge in the changes between the two respective revisions.
-This can be used to ``remove'' a certain delta from your working file.
-.SP
-In addition, each \fB-j\fP option can contain on optional date
-specification which, when used with branches, can limit the chosen
-revision to one within a specific date.
-An optional date is specified by adding a colon (:) to the tag.
-An example might be what
-.` "cvs import"
-tells you to do when you have
-just imported sources that have conflicts with local changes:
-.SP
-.in +1i
-.ft B
-.nf
-example% cvs checkout -jTAG:yesterday -jTAG module
-.fi
-.ft P
-.in -1i
-.SP
-Use the
-.B \-N
-option with
-.` "\-d \fIdir\fP"
-to avoid shortening module paths in your working directory. (Normally, \fBcvs\fP shortens paths as much as possible when you specify an explicit target directory.)
-.SP
-Use the
-.B \-c
-option to copy the module file, sorted, to the standard output,
-instead of creating or modifying any files or directories in your
-working directory.
-.SP
-Use the
-.BI \-d " dir"
-option to create a directory called
-.I dir
-for the working files, instead of using the module name. Unless you
-also use \fB\-N\fP, the paths created under \fIdir\fP will be as short
-as possible.
-.SP
-Use the
-.B \-s
-option to display per-module status information stored with
-the
-.B \-s
-option within the modules file.
-.TP
-\fBcommit\fP [\fB\-lnR\fP] [\fB\-m\fP '\fIlog_message\fP' | \fB\-f\fP \fIfile\fP] [\fB\-r\fP \fIrevision\fP] [\fIfiles.\|.\|.\fP]
-.I Requires:
-working directory, repository.
-.br
-.I Changes:
-repository.
-.br
-.I Synonym:
-.B ci
-.br
-Use
-.` "cvs commit"
-when you want to incorporate changes from your working source
-files into the general source repository.
-.SP
-If you don't specify particular \fIfiles\fP to commit, all
-of the files in your working current directory are examined.
-.B commit
-is careful to change in the repository only those files that you have
-really changed. By default (or if you explicitly specify the
-.B \-R
-option), files
-in subdirectories are also examined and committed if they have
-changed; you can use the
-.B \-l
-option to limit
-.B commit
-to the current directory only.
-Sometimes you may want to force a file to be committed even though it
-is unchanged; this is achieved with the
-.B \-f
-flag, which also has the effect of disabling recursion (you can turn
-it back on with
-.B \-R
-of course).
-.SP
-.B commit
-verifies that the selected files are up to date with the current revisions
-in the source repository; it will notify you, and exit without
-committing, if any of the specified files must be made current first
-with
-.` "cvs update".
-.B commit
-does not call the
-.B update
-command for you, but rather leaves that for you to do when
-the time is right.
-.SP
-When all is well, an editor is invoked to allow you to enter a log
-message that will be written to one or more logging programs and placed in the
-.SM RCS
-source repository file.
-You can instead specify the log message on the command line with the
-.B \-m
-option, thus suppressing the editor invocation, or use the
-.B \-F
-option to specify that the argument \fIfile\fP contains the log message.
-.SP
-The
-.B \-r
-option can be used to commit to a particular symbolic or numeric revision
-within the
-.SM RCS
-file.
-For example, to bring all your files up to the
-.SM RCS
-revision ``3.0'' (including those that haven't changed), you might do:
-.SP
-.in +1i
-.ft B
-.nf
-example% cvs commit -r3.0
-.fi
-.ft P
-.in -1i
-.SP
-.B cvs
-will only allow you to commit to a revision that is on the main trunk (a
-revision with a single dot).
-However, you can also commit to a branch revision (one that has an even
-number of dots) with the
-.B \-r
-option.
-To create a branch revision, one typically use the
-.B \-b
-option of the
-.BR rtag " or " tag
-commands.
-Then, either
-.BR checkout " or " update
-can be used to base your sources on the newly created branch.
-From that point on, all
-.B commit
-changes made within these working sources will be automatically added
-to a branch revision, thereby not perturbing main-line development in any
-way.
-For example, if you had to create a patch to the 1.2 version of the
-product, even though the 2.0 version is already under development, you
-might do:
-.SP
-.in +1i
-.ft B
-.nf
-example% cvs rtag -b -rFCS1_2 FCS1_2_Patch product_module
-example% cvs checkout -rFCS1_2_Patch product_module
-example% cd product_module
-[[ hack away ]]
-example% cvs commit
-.fi
-.ft P
-.in -1i
-.SP
-Say you have been working on some extremely experimental software, based on
-whatever revision you happened to checkout last week.
-If others in your group would like to work on this software with you, but
-without disturbing main-line development, you could commit your change to a
-new branch.
-Others can then checkout your experimental stuff and utilize the full
-benefit of
-.B cvs
-conflict resolution.
-The scenario might look like:
-.SP
-.in +1i
-.ft B
-.nf
-example% cvs tag -b EXPR1
-example% cvs update -rEXPR1
-[[ hack away ]]
-example% cvs commit
-.fi
-.ft P
-.in -1i
-.SP
-Others would simply do
-.` "cvs checkout -rEXPR1 whatever_module"
-to work with you on the experimental change.
-.TP
-\fBdiff\fP [\fB\-kl\fP] [\fIrcsdiff_options\fP] [[\fB\-r\fP \fIrev1\fP | \fB\-D\fP \fIdate1\fP] [\fB\-r\fP \fIrev2\fP | \fB\-D\fP \fIdate2\fP]] [\fIfiles.\|.\|.\fP]
-.I Requires:
-working directory, repository.
-.br
-.I Changes:
-nothing.
-.br
-You can compare your working files with revisions in the source
-repository, with the
-.` "cvs diff"
-command. If you don't specify a particular revision, your files
-are compared with the revisions they were based on. You can also use
-the standard
-.B cvs
-command option
-.B \-r
-to specify a particular revision to compare your files with. Finally,
-if you use
-.B \-r
-twice, you can see differences between two revisions in the
-repository.
-You can also specify
-.B \-D
-options to diff against a revision in the past.
-The
-.B \-r
-and
-.B \-D
-options can be mixed together with at most two options ever specified.
-.SP
-See
-.BR rcsdiff ( 1 )
-for a list of other accepted options.
-.SP
-If you don't specify any files,
-.B diff
-will display differences for all those files in the current directory
-(and its subdirectories, unless you use the standard option
-.BR \-l )
-that
-differ from the corresponding revision in the source repository
-(i.e. files that
-.I you
-have changed), or that differ from the revision specified.
-.TP
-\fBexport\fP [\-\fBf\|lNnQq\fP] \fB\-r\fP \fIrev\fP\||\|\fB\-D\fP \fIdate\fP [\fB\-d\fP \fIdir\fP] [\fB\-k\fP \fIkflag\fP] \fImodule\fP.\|.\|.
-.I Requires:
-repository.
-.br
-.I Changes:
-current directory.
-.br
-This command is a variant of
-.` "cvs checkout";
-use it when you want a copy of the source for \fImodule\fP
-without the \fBcvs\fP administrative directories. For example, you
-might use
-.` "cvs export"
-to prepare source for shipment
-off-site. This command \fIrequires\fP that you specify a date or tag
-(with \fB\-D\fP or \fB\-r\fP), so that you can count on reproducing
-the source you ship to others.
-.SP
-The only non-standard options are
-.` "\-d \fIdir\fP"
-(write the
-source into directory \fIdir\fP) and
-.` "\-N"
-(don't shorten
-module paths).
-These have the same meanings as the same options in
-.` "cvs checkout".
-.SP
-The
-.B \-kv
-option is useful when
-.B export
-is used.
-This causes any
-.SM RCS
-keywords to be expanded such that an
-.B import
-done at some other site will not lose the keyword revision information.
-Other \fIkflag\fPs may be used with
-.` "cvs export"
-and are described in
-.BR co ( 1 ).
-.TP
-\fBhistory\fP [\fB\-\fP\fIreport\fP] [\fB\-\fP\fIflags\fP] [\fB\-\fP\fIoptions args\fP] [\fIfiles\fP.\|.\|.]
-.I Requires:
-the file
-.` "$CVSROOT/CVSROOT/history"
-.br
-.I Changes:
-nothing.
-.br
-\fBcvs\fP keeps a history file that tracks each use of the
-\fBcheckout\fP, \fBcommit\fP, \fBrtag\fP, \fBupdate\fP, and \fBrelease\fP
-commands. You can use
-.` "cvs history"
-to display this
-information in various formats.
-.SP
-.I Warning:
-.` "cvs history"
-uses
-.` "\-f",
-.` "\-l",
-.` "\-n",
-and
-.` "\-p"
-in ways that conflict with the
-descriptions in
-.SM
-COMMON COMMAND OPTIONS\c
-\&.
-.SP
-Several options (shown above as \fB\-\fP\fIreport\fP) control what
-kind of report is generated:
-.TP 1i
-.B \ \ \ \ \ \ \-c
-Report on each time \fBcommit\fP was used (i.e., each time the
-repository was modified).
-.TP 1i
-\fB\ \ \ \ \ \ \-m\fP \fImodule\fP
-Report on a particular \fImodule\fP. (You can meaningfully use
-\fB\-m\fP more than once on the command line.)
-.TP 1i
-.B \ \ \ \ \ \ \-o
-Report on checked-out modules.
-.TP 1i
-.B \ \ \ \ \ \ \-T
-Report on all tags.
-.TP 1i
-\fB\ \ \ \ \ \ \-x\fP \fItype\fP
-Extract a particular set of record types \fIX\fP from the \fBcvs\fP
-history. The types are indicated by single letters, which you may
-specify in combination.
-Certain commands have a single record type: \fBcheckout\fP (type `O'),
-\fBrelease\fP (type `F'), and \fBrtag\fP (type `T'). One of four
-record types may result from an \fBupdate\fP: `W', when the working copy
-of a file is deleted during update (because it was gone from the
-repository); `U', when a working file was copied from the
-repository; `G', when a merge was necessary and it succeeded; and 'C',
-when a merge was necessary but collisions were detected (requiring
-manual merging). Finally, one of three record types results from
-\fBcommit\fP: `M', when a file was modified; `A', when a file is first
-added; and `R', when a file is removed.
-.TP 1i
-.B \ \ \ \ \ \ \-e
-Everything (all record types); equivalent to specifying
-.` "\-xMACFROGWUT".
-.TP 1i
-\fB\ \ \ \ \ \ \-z\fP \fIzone\fP
-Use time zone
-.I zone
-when outputting history records.
-The zone name
-.B LT
-stands for local time;
-numeric offsets stand for hours and minutes ahead of UTC.
-For example,
-.B +0530
-stands for 5 hours and 30 minutes ahead of (i.e. east of) UTC.
-.PP
-.RS .5i
-The options shown as \fB\-\fP\fIflags\fP constrain the report without
-requiring option arguments:
-.RE
-.TP 1i
-.B \ \ \ \ \ \ \-a
-Show data for all users (the default is to show data only for the user
-executing
-.` "cvs history").
-.TP 1i
-.B \ \ \ \ \ \ \-l
-Show last modification only.
-.TP 1i
-.B \ \ \ \ \ \ \-w
-Show only the records for modifications done from the same working
-directory where
-.` "cvs history"
-is executing.
-.PP
-.RS .5i
-The options shown as \fB\-\fP\fIoptions args\fP constrain the report
-based on an argument:
-.RE
-.TP 1i
-\fB\ \ \ \ \ \ \-b\fP \fIstr\fP
-Show data back to a record containing the string \fIstr\fP in either
-the module name, the file name, or the repository path.
-.TP 1i
-\fB\ \ \ \ \ \ \-D\fP \fIdate\fP
-Show data since \fIdate\fP.
-.TP 1i
-\fB\ \ \ \ \ \ \-p\fP \fIrepository\fP
-Show data for a particular source repository (you can specify several
-\fB\-p\fP options on the same command line).
-.TP 1i
-\fB\ \ \ \ \ \ \-r\fP \fIrev\fP
-Show records referring to revisions since the revision or tag
-named \fIrev\fP appears in individual RCS files.
-Each
-.SM RCS
-file is searched for the revision or tag.
-.TP 1i
-\fB\ \ \ \ \ \ \-t\fP \fItag\fP
-Show records since tag \fItag\fP was last added to the the history file.
-This differs from the \fB-r\fP flag above in that it reads
-only the history file, not the
-.SM RCS
-files, and is much faster.
-.TP 1i
-\fB\ \ \ \ \ \ \-u\fP \fIname\fP
-Show records for user \fIname\fP.
-.PP
-.TP
-\fBimport\fP [\fB\-\fP\fIoptions\fP] \fIrepository vendortag releasetag\fP.\|.\|.
-.I Requires:
-Repository, source distribution directory.
-.br
-.I Changes:
-repository.
-.br
-Use
-.` "cvs import"
-to incorporate an entire source
-distribution from an outside source (e.g., a source vendor) into your
-source repository directory. You can use this command both for
-initial creation of a repository, and for wholesale updates to the
-module form the outside source.
-.SP
-The \fIrepository\fP argument gives a directory name (or a path to a
-directory) under the CVS root directory for repositories; if the
-directory did not exist, \fBimport\fP creates it.
-.SP
-When you use \fBimport\fP for updates to source that has been modified in your
-source repository (since a prior \fBimport\fP), it
-will notify you of any files that conflict in the two branches of
-development; use
-.` "cvs checkout -j"
-to reconcile the differences, as \fBimport\fP instructs you to do.
-.SP
-By default, certain file names are ignored during
-.` "cvs import":
-names associated with
-.SM CVS
-administration, or with other common source control systems; common
-names for patch files, object files, archive files, and editor backup
-files; and other names that are usually artifacts of assorted utilities.
-Currently, the default list of ignored files includes files matching
-these names:
-.SP
-.in +1i
-.ft B
-.nf
-RCSLOG RCS SCCS
-CVS* cvslog.*
-tags TAGS
-\&.make.state .nse_depinfo
-*~ #* .#* ,*
-*.old *.bak *.BAK *.orig *.rej .del\-*
-*.a *.o *.so *.Z *.elc *.ln core
-.fi
-.ft P
-.in -1i
-.SP
-The outside source is saved in a first-level
-.SM RCS
-branch, by default
-.` "1.1.1".
-Updates are leaves of this
-branch; for example, files from the first imported collection of
-source will be revision
-.` "1.1.1.1",
-then files from the first
-imported update will be revision
-.` "1.1.1.2",
-and so on.
-.SP
-At least three arguments are required. \fIrepository\fP is needed to
-identify the collection of source. \fIvendortag\fP is a tag for the
-entire branch (e.g., for
-.` "1.1.1").
-You must also specify at
-least one \fIreleasetag\fP to identify the files at the leaves created
-each time you execute
-.` "cvs import".
-.SP
-One of the standard
-.B cvs
-command options is available: \fB\-m\fP
-\fImessage\fP. If you do not specify a logging message with
-\fB\-m\fP, your editor is invoked (as with \fBcommit\fP) to allow you
-to enter one.
-.SP
-There are three additional special options.
-.SP
-Use
-.` "\-d"
-to specify that each file's time of last modification should be used
-for the checkin date and time.
-.SP
-Use
-.` "\-b \fIbranch\fP"
-to specify a first-level branch other
-than
-.` "1.1.1".
-.SP
-Use
-.` "\-I \fIname\fP"
-to specify file names that should be
-ignored during \fBimport\fP. You can use this option repeatedly.
-To avoid ignoring any files at all (even those ignored by default),
-specify
-.` "\-I !".
-.TP
-\fBlog\fP [\fB\-l\fP] \fIrlog-options [files\fP\|.\|.\|.]
-.I Requires:
-repository, working directory.
-.br
-.I Changes:
-nothing.
-.br
-.I Synonym:
-.B rlog
-.br
-Display log information for \fIfiles\fP.
-.` "cvs log"
-calls
-the
-.SM RCS
-utility \fBrlog\fP; all the options described in
-.BR rlog ( 1 )
-are available. Among the more useful \fBrlog\fP options are \fB\-h\fP
-to display only the header (including tag definitions, but omitting
-most of the full log); \fB\-r\fP to select logs on particular
-revisions or ranges of revisions; and \fB\-d\fP to select particular
-dates or date ranges. See
-.BR rlog ( 1 )
-for full explanations.
-This command is recursive by default, unless the
-.B \-l
-option is specified.
-.TP
-\fBrdiff\fP [\fB\-\fP\fIflags\fP] [\fB\-V\fP \fIvn\fP] [\fB\-r\fP \fIt\fP|\fB\-D\fP \fId\fP [\fB\-r\fP \fIt2\fP|\fB\-D\fP \fId2\fP]] \fImodules\|.\|.\|.\fP
-.I Requires:
-repository.
-.br
-.I Changes:
-nothing.
-.br
-.I Synonym:
-.B patch
-.br
-Builds a Larry Wall format
-.BR patch ( 1 )
-file between two releases, that can be fed directly into the
-.B patch
-program to bring an old release up-to-date with the new release.
-(This is one of the few \fBcvs\fP commands that operates directly from
-the repository, and doesn't require a prior
-.BR checkout .)
-The diff output is sent to the standard output device.
-You can specify (using the standard \fB\-r\fP and \fB\-D\fP options)
-any combination of one or two revisions or dates.
-If only one revision or date is specified, the
-patch file reflects differences between that revision or date and the
-current ``head'' revisions in the
-.SM RCS
-file.
-.SP
-Note that if the software release affected
-is contained in more than one directory, then it may be necessary to
-specify the
-.B \-p
-option to the
-.B patch
-command when patching the old sources, so that
-.B patch
-is able to find the files that are located in other directories.
-.SP
-If you use the option \fB\-V\fP \fIvn\fP,
-.SM RCS
-keywords are expanded according to the rules current in
-.SM RCS
-version \fIvn\fP (the expansion format changed with
-.SM RCS
-version 5).
-.SP
-The standard option \fIflags\fP \fB\-f\fP, and \fB\-l\fP
-are available with this command. There are also several
-special options flags:
-.SP
-If you use the
-.B \-s
-option, no patch output is produced.
-Instead, a summary of the changed or added files between the two
-releases is sent to the standard output device.
-This is useful for finding out, for example, which files have changed
-between two dates or revisions.
-.SP
-If you use the
-.B \-t
-option, a diff of the top two revisions is sent to the standard output device.
-This is most useful for seeing what the last change to a file was.
-.SP
-If you use the
-.B \-u
-option, the patch output uses the newer ``unidiff'' format for context
-diffs.
-.SP
-You can use
-.B \-c
-to explicitly specify the
-.` "diff \-c"
-form of context diffs
-(which is the default), if you like.
-.TP
-\fBrelease\fP [\fB\-dQq\fP] \fImodules\fP\|.\|.\|.
-.I Requires:
-Working directory.
-.br
-.I Changes:
-Working directory, history log.
-.br
-This command is meant to safely cancel the effect of
-.` "cvs checkout'.
-Since
-.B cvs
-doesn't lock files, it isn't strictly necessary to use this command.
-You can always simply delete your working directory, if you
-like; but you risk losing changes you may have forgotten, and you
-leave no trace in the
-.B cvs
-history file that you've abandoned your checkout.
-.SP
-Use
-.` "cvs release"
-to avoid these problems. This command
-checks that no un-committed changes are present; that you are
-executing it from immediately above, or inside, a \fBcvs\fP working
-directory; and that the repository recorded for your files is the same
-as the repository defined in the module database.
-.SP
-If all these conditions are true,
-.` "cvs release"
-leaves a
-record of its execution (attesting to your intentionally abandoning
-your checkout) in the
-.B cvs
-history log.
-.SP
-You can use the \fB\-d\fP flag to request that your working copies of
-the source files be deleted if the \fBrelease\fP succeeds.
-.TP
-\fBremove\fP [\fB\-lR\fP] [\fIfiles\|.\|.\|.\fP]
-.I Requires:
-Working directory.
-.br
-.I Changes:
-Working directory.
-.br
-.I Synonyms:
-.BR rm ", " delete
-.br
-Use this command to declare that you wish to remove \fIfiles\fP from
-the source repository. Like most
-.B cvs
-commands,
-.` "cvs remove"
-works on files in your working
-directory, not directly on the repository. As a safeguard, it also
-requires that you first erase the specified files from your working
-directory.
-.SP
-The files are not actually removed until you apply your changes to the
-repository with
-.BR commit ;
-at that point, the corresponding
-.SM RCS
-files in the source repository are
-.I moved
-into the
-.` "Attic"
-directory (also within the source repository).
-.SP
-This command is recursive by default, scheduling all physically removed
-files that it finds for removal by the next
-.BR commit .
-Use the
-.B \-l
-option to avoid this recursion, or just specify that actual files that you
-wish remove to consider.
-.TP
-\fBrtag\fP [\fB\-f\|alnRQq\fP] [\fB\-b\fP] [\fB\-d\fP] [\fB\-r\fP \fItag\fP | \fB\-D\fP \fIdate\fP] \fIsymbolic_tag\fP \fImodules\|.\|.\|.\fP
-.I Requires:
-repository.
-.br
-.I Changes:
-repository.
-.br
-.I Synonym:
-.B rfreeze
-.br
-You can use this command to assign symbolic tags to particular,
-explicitly specified source versions in the repository.
-.` "cvs rtag"
-works directly on the repository contents (and requires no
-prior
-.BR checkout ).
-Use
-.` "cvs tag"
-instead, to base the selection of
-versions to tag on the contents of your working directory.
-.SP
-In general, tags (often the symbolic names of software distributions)
-should not be removed, but the
-.B \-d
-option is available as a means to remove completely obsolete symbolic names
-if necessary (as might be the case for an Alpha release, say).
-.SP
-.` "cvs rtag"
-will not move a tag that already exists. With the \fB\-F\fP option,
-however,
-.` "cvs rtag"
-will re-locate any instance of \fIsymbolic_tag\fP that already exists
-on that file to the new repository versions. Without the \fB\-F\fP
-option, attempting to use
-.` "cvs rtag"
-to apply a tag that already exists on that file will produce an error
-message.
-.SP
-The \fB-b\fP option makes the tag a ``branch'' tag, allowing
-concurrent, isolated development.
-This is most useful for creating a patch to a previously released software
-distribution.
-.SP
-You can use the standard \fB\-r\fP and \fB\-D\fP options to tag only those
-files that already contain a certain tag. This method would be used
-to rename a tag: tag only the files identified by the old tag, then delete the
-old tag, leaving the new tag on exactly the same files as the old tag.
-.SP
-.B rtag
-executes recursively by default, tagging all subdirectories of
-\fImodules\fP you specify in the argument. You can restrict its
-operation to top-level directories with the standard \fB\-l\fP option;
-or you can explicitly request recursion with \fB\-R\fP.
-.SP
-The modules database can specify a program to execute whenever a tag
-is specified; a typical use is to send electronic mail to a group of
-interested parties. If you want to bypass that program, use the
-standard \fB\-n\fP option.
-.SP
-Use the
-.B \-a
-option to have
-.B rtag
-look in the
-.` "Attic"
-for removed files that contain the specified tag.
-The tag is removed from these files, which makes it convenient to re-use a
-symbolic tag as development continues (and files get removed from the
-up-coming distribution).
-.TP
-\fBstatus\fP [\fB\-lRqQ\fP] [\fB\-v\fP] [\fIfiles\fP\|.\|.\|.]
-.I Requires:
-working directory, repository.
-.br
-.I Changes:
-nothing.
-.br
-Display a brief report on the current status of \fIfiles\fP with
-respect to the source repository, including any ``sticky'' tags,
-dates, or \fB\-k\fP options. (``Sticky'' options will restrict how
-.` "cvs update"
-operates until you reset them; see the
-description of
-.` "cvs update \-A\|.\|.\|.".)
-.SP
-You can also use this command to anticipate the potential impact of a
-.` "cvs update"
-on your working source directory. If you do
-not specify any \fIfiles\fP explicitly, reports are shown for all
-files that \fBcvs\fP has placed in your working directory. You can
-limit the scope of this search to the current directory itself (not
-its subdirectories) with the standard \fB\-l\fP option flag; or you
-can explicitly request recursive status reports with the \fB\-R\fP
-option.
-.SP
-The
-.B \-v
-option causes the symbolic tags for the
-.SM RCS
-file to be displayed as well.
-.TP
-\fBtag\fP [\fB\-lQqR\fP] [\fB\-F\fP] [\fB\-b\fP] [\fB\-d\fP] [\fB\-r\fP \fItag\fP | \fB\-D\fP \fIdate\fP] [\fB\-f\fP] \fIsymbolic_tag\fP [\fIfiles\fP\|.\|.\|.\|]
-.I Requires:
-working directory, repository.
-.br
-.I Changes:
-repository.
-.br
-.I Synonym:
-.B freeze
-.br
-Use this command to assign symbolic tags to the nearest repository
-versions to your working sources. The tags are applied immediately to
-the repository, as with \fBrtag\fP.
-.SP
-One use for tags is to record a ``snapshot'' of the current sources
-when the software freeze date of a project arrives. As bugs are fixed
-after the freeze date, only those changed sources that are to be part
-of the release need be re-tagged.
-.SP
-The symbolic tags are meant to permanently record which revisions of which
-files were used in creating a software distribution.
-The
-.BR checkout ,
-.B export
-and
-.B update
-commands allow you to extract an exact copy of a tagged release at any time in
-the future, regardless of whether files have been changed, added, or removed
-since the release was tagged.
-.SP
-You can use the standard \fB\-r\fP and \fB\-D\fP options to tag only those
-files that already contain a certain tag. This method would be used
-to rename a tag: tag only the files identified by the old tag, then delete the
-old tag, leaving the new tag on exactly the same files as the old tag.
-.SP
-Specifying the \fB\-f\fP flag in addition to the \fB\-r\fP or \fB\-D\fP
-flags will tag those files named on the command line even if they do not
-contain the old tag or did not exist on the specified date.
-.SP
-By default (without a \fB\-r\fP or \fB\-D\fP flag)
-the versions to be tagged are supplied
-implicitly by the \fBcvs\fP records of your working files' history
-rather than applied explicitly.
-.SP
-If you use
-.` "cvs tag \-d \fIsymbolic_tag\fP\|.\|.\|.",
-the
-symbolic tag you specify is
-.I deleted
-instead of being added. \fIWarning\fP: Be very certain of your ground
-before you delete a tag; doing this effectively discards some
-historical information, which may later turn out to have been valuable.
-.SP
-.` "cvs tag"
-will not move a tag that already exists. With the \fB\-F\fP option,
-however,
-.` "cvs tag"
-will re-locate any instance of \fIsymbolic_tag\fP that already exists
-on that file to the new repository versions. Without the \fB\-F\fP
-option, attempting to use
-.` "cvs tag"
-to apply a tag that already exists on that file will produce an error
-message.
-.SP
-The \fB-b\fP option makes the tag a ``branch'' tag, allowing
-concurrent, isolated development.
-This is most useful for creating a patch to a previously released software
-distribution.
-.SP
-Normally,
-.B tag
-executes recursively through subdirectories; you can prevent this by
-using the standard \fB\-l\fP option, or specify the recursion
-explicitly by using \fB\-R\fP.
-.TP
-\fBupdate\fP [\fB\-Adf\|lPpQqR\fP] [\fB\-d\fP] [\fB\-r\fP \fItag\fP|\fB\-D\fP \fIdate\fP] \fIfiles\|.\|.\|.\fP
-.I Requires:
-repository, working directory.
-.br
-.I Changes:
-working directory.
-.br
-After you've run
-.B checkout
-to create your private copy of source from the common repository,
-other developers will continue changing the central source. From time
-to time, when it is convenient in your development process, you can
-use the
-.B update
-command
-from within your working directory to reconcile your work with any
-revisions applied to the source repository since your last
-.B checkout
-or
-.BR update .
-.SP
-.B update
-keeps you informed of its progress by printing a line for each file,
-prefaced with one of the characters
-.` "U A R M C ?"
-to indicate the status of the file:
-.TP 1i
-\fBU\fP \fIfile\fP
-The file was brought \fIup to date\fP with respect to the repository.
-This is done for any file that exists in the repository but not in
-your source, and for files that you haven't changed but are not the most
-recent versions available in the repository.
-.TP 1i
-\fBA\fP \fIfile\fP
-The file has been \fIadded\fP to your private copy of the sources, and
-will be added to the
-.SM RCS
-source repository when you run
-.` "cvs commit"
-on the file.
-This is a reminder to you that the file needs to be committed.
-.TP 1i
-\fBR\fP \fIfile\fP
-The file has been \fIremoved\fP from your private copy of the sources, and
-will be removed from the
-.SM RCS
-source repository when you run
-.` "cvs commit"
-on the file.
-This is a reminder to you that the file needs to be committed.
-.TP 1i
-\fBM\fP \fIfile\fP
-The file is \fImodified\fP in your working directory.
-.` "M"
-can indicate one of two states for a file you're working on: either
-there were no modifications to the same file in the repository, so
-that your file remains as you last saw it; or there were modifications
-in the repository as well as in your copy, but they were
-\fImerged\fP successfully, without conflict, in your working
-directory.
-.TP 1i
-\fBC\fP \fIfile\fP
-A \fIconflict\fP was detected while trying to merge your changes to
-\fIfile\fP with changes from the source repository. \fIfile\fP (the
-copy in your working directory) is now the output of the
-.BR rcsmerge ( 1 )
-command on the two versions; an unmodified copy of your file is also
-in your working directory, with the name `\fB.#\fP\fIfile\fP\fB.\fP\fIversion\fP',
-where
-.I version
-is the
-.SM RCS
-revision that your modified file started from.
-(Note that some systems automatically purge files that begin with
-\&
-.` ".#"
-if they have not been accessed for a few days.
-If you intend to keep a copy of your original file, it is a very good
-idea to rename it.)
-.TP 1i
-\fB?\fP \fIfile\fP
-\fIfile\fP is in your working directory, but does not correspond to
-anything in the source repository, and is not in the list of files
-for \fBcvs\fP to ignore (see the description of the \fB\-I\fP option).
-.PP
-.RS .5i
-.SP
-Use the
-.B \-A
-option to reset any sticky tags, dates, or
-.B \-k
-options. (If you get a working copy of a file by using one of the
-\fB\-r\fP, \fB\-D\fP, or \fB\-k\fP options, \fBcvs\fP remembers the
-corresponding tag, date, or \fIkflag\fP and continues using it on
-future updates; use the \fB\-A\fP option to make \fBcvs\fP forget these
-specifications, and retrieve the ``head'' version of the file).
-.SP
-The \fB\-j\fP\fIbranch\fP option
-merges the changes made between the
-resulting revision and the revision that it is based on (e.g., if
-the tag refers to a branch,
-.B cvs
-will merge all changes made in
-that branch into your working file).
-.SP
-With two \fB-j\fP options,
-.B cvs
-will merge in the changes between the two respective revisions.
-This can be used to ``remove'' a certain delta from your working file.
-E.g., If the file foo.c is based on
-revision 1.6 and I want to remove the changes made between 1.3 and
-1.5, I might do:
-.SP
-.in +1i
-.ft B
-.nf
-example% cvs update -j1.5 -j1.3 foo.c # note the order...
-.fi
-.ft P
-.in -1i
-.SP
-In addition, each \fB-j\fP option can contain on optional date
-specification which, when used with branches, can limit the chosen
-revision to one within a specific date.
-An optional date is specified by adding a colon (:) to the tag.
-.SP
-.in +1i
-.ft B
-.nf
--jSymbolic_Tag:Date_Specifier
-.fi
-.ft P
-.in -1i
-.SP
-Use the
-.B \-d
-option to create any directories that exist in the repository if they're
-missing from the working directory. (Normally, update acts only on
-directories and files that were already enrolled in your
-working directory.) This is useful for updating directories
-that were created in the repository since the initial
-\fBcheckout\fP; but it has an unfortunate side effect. If you
-deliberately avoided certain directories in the repository when you
-created your working directory (either through use of a module name or by
-listing explicitly the files and directories you wanted on the
-command line), then updating with
-.B \-d
-will create those directories, which may not be what you want.
-.SP
-Use \fB\-I\fP \fIname\fP to ignore files whose names match \fIname\fP
-(in your working directory) during the update. You can specify
-\fB\-I\fP more than once on the command line to specify several files
-to ignore. By default,
-\fBupdate\fP ignores files whose names match any of the following:
-.SP
-.in +1i
-.ft B
-.nf
-RCSLOG RCS SCCS
-CVS* cvslog.*
-tags TAGS
-\&.make.state .nse_depinfo
-*~ #* .#* ,*
-*.old *.bak *.BAK *.orig *.rej .del\-*
-*.a *.o *.so *.Z *.elc *.ln core
-.fi
-.ft P
-.in -1i
-.SP
-Use
-.` "\-I !"
-to avoid ignoring any files at all.
-.SP
-The standard \fBcvs\fP command options \fB\-f\fP, \fB\-k\fP,
-\fB\-l\fP, \fB\-P\fP, \fB\-p\fP, and \fB\-r\fP
-are also available with \fBupdate\fP.
-.RE
-.SH "FILES"
-For more detailed information on
-.B cvs
-supporting files, see
-.BR cvs ( 5 ).
-.LP
-.I
-Files in home directories:
-.TP
-\&.cvsrc
-The
-.B cvs
-initialisation file. Lines in this file can be used to specify default
-options for each
-.B cvs
-command. For example the line
-.` "diff \-c"
-will ensure that
-.` "cvs diff"
-is always passed the
-.B \-c
-option in addition to any other options passed on the command line.
-.TP
-\&.cvswrappers
-Specifies wrappers to be used in addition to those specified in the
-CVSROOT/cvswrappers file in the repository.
-.LP
-.I
-Files in working directories:
-.TP
-CVS
-A directory of \fBcvs\fP administrative files.
-.I
-Do not delete.
-.TP
-CVS/Entries
-List and status of files in your working directory.
-.TP
-CVS/Entries.Backup
-A backup of
-.` "CVS/Entries".
-.TP
-CVS/Entries.Static
-Flag: do not add more entries on
-.` "cvs update".
-.TP
-CVS/Root
-Pathname to the repository (
-.SM CVSROOT
-) location at the time of checkout. This file is used instead
-of the
-.SM CVSROOT
-environment variable if the environment variable is not
-set. A warning message will be issued when the contents of this
-file and the
-.SM CVSROOT
-environment variable differ. The file may be over-ridden by the
-presence of the
-.SM CVS_IGNORE_REMOTE_ROOT
-environment variable.
-.TP
-CVS/Repository
-Pathname to the corresponding directory in the source repository.
-.TP
-CVS/Tag
-Contains the per-directory ``sticky'' tag or date information.
-This file is created/updated when you specify
-.B \-r
-or
-.B \-D
-to the
-.B checkout
-or
-.B update
-commands, and no files are specified.
-.TP
-CVS/Checkin.prog
-Name of program to run on
-.` "cvs commit".
-.TP
-CVS/Update.prog
-Name of program to run on
-.` "cvs update".
-.LP
-.I
-Files in source repositories:
-.TP
-$CVSROOT/CVSROOT
-Directory of global administrative files for repository.
-.TP
-CVSROOT/commitinfo,v
-Records programs for filtering
-.` "cvs commit"
-requests.
-.TP
-CVSROOT/cvswrappers,v
-Records
-.B cvs
-wrapper commands to be used when checking files into and out of the
-repository. Wrappers allow the file or directory to be processed
-on the way in and out of CVS. The intended uses are many, one
-possible use would be to reformat a C file before the file is checked
-in, so all of the code in the repository looks the same.
-.TP
-CVSROOT/editinfo,v
-Records programs for editing/validating
-.` "cvs commit"
-log entries.
-.TP
-CVSROOT/history
-Log file of \fBcvs\fP transactions.
-.TP
-CVSROOT/loginfo,v
-Records programs for piping
-.` "cvs commit"
-log entries.
-.TP
-CVSROOT/modules,v
-Definitions for modules in this repository.
-.TP
-CVSROOT/rcsinfo,v
-Records pathnames to templates used during a
-.` "cvs commit"
-operation.
-.TP
-CVSROOT/taginfo,v
-Records programs for validating/logging
-.` "cvs tag"
-and
-.` "cvs rtag"
-operations.
-.TP
-MODULE/Attic
-Directory for removed source files.
-.TP
-#cvs.lock
-A lock directory created by
-.B cvs
-when doing sensitive changes to the
-.SM RCS
-source repository.
-.TP
-#cvs.tfl.\fIpid\fP
-Temporary lock file for repository.
-.TP
-#cvs.rfl.\fIpid\fP
-A read lock.
-.TP
-#cvs.wfl.\fIpid\fP
-A write lock.
-.SH "ENVIRONMENT VARIABLES"
-.TP
-.SM CVSROOT
-Should contain the full pathname to the root of the
-.B cvs
-source repository (where the
-.SM RCS
-files are kept). This information must be available to \fBcvs\fP for
-most commands to execute; if
-.SM CVSROOT
-is not set, or if you wish to override it for one invocation, you can
-supply it on the command line:
-.` "cvs \-d \fIcvsroot cvs_command\fP\|.\|.\|."
-You may not need to set
-.SM CVSROOT
-if your \fBcvs\fP binary has the right path compiled in; use
-.` "cvs \-v"
-to display all compiled-in paths.
-.TP
-.SM CVSREAD
-If this is set,
-.B checkout
-and
-.B update
-will try hard to make the files in your working directory read-only.
-When this is not set, the default behavior is to permit modification
-of your working files.
-.TP
-.SM RCSBIN
-Specifies the full pathname where to find
-.SM RCS
-programs, such as
-.BR co ( 1 )
-and
-.BR ci ( 1 ).
-If not set, a compiled-in value is used; see the display from
-.` "cvs \-v".
-.TP
-.SM CVSEDITOR
-Specifies the program to use for recording log messages during
-.BR commit .
-If not set, the
-.SM EDITOR
-environment variable is used instead.
-If
-.SM EDITOR
-is not set either, the default is
-.BR /usr/ucb/vi .
-.TP
-.SM CVS_IGNORE_REMOTE_ROOT
-If this variable is set then
-.B cvs
-will ignore all references to remote repositories in the CVS/Root file.
-.TP
-.SM CVS_RSH
-.B cvs
-uses the contents of this variable to determine the name of the
-remote shell command to use when starting a
-.B cvs
-server. If this variable is not set then
-.` "rsh"
-is used.
-.TP
-.SM CVS_SERVER
-.B cvs
-uses the contents of this variable to determine the name of the
-.B cvs
-server command. If this variable is not set then
-.` "cvs"
-is used.
-.TP
-.SM CVSWRAPPERS
-This variable is used by the
-.` "cvswrappers"
-script to determine the name of the wrapper file, in addition to the
-wrappers defaults contained in the repository
-.SM (CVSROOT/cvswrappers)
-and the user's home directory (~/.cvswrappers).
-.SH "AUTHORS"
-.TP
-Dick Grune
-Original author of the
-.B cvs
-shell script version posted to
-.B comp.sources.unix
-in the volume6 release of December, 1986.
-Credited with much of the
-.B cvs
-conflict resolution algorithms.
-.TP
-Brian Berliner
-Coder and designer of the
-.B cvs
-program itself in April, 1989, based on the original work done by Dick.
-.TP
-Jeff Polk
-Helped Brian with the design of the
-.B cvs
-module and vendor branch support and author of the
-.BR checkin ( 1 )
-shell script (the ancestor of
-.` "cvs import").
-.SH "SEE ALSO"
-.BR ci ( 1 ),
-.BR co ( 1 ),
-.BR cvs ( 5 ),
-.BR cvsbug ( 8 ),
-.BR cvsinit ( 8 ),
-.BR diff ( 1 ),
-.BR grep ( 1 ),
-.BR mkmodules ( 1 ),
-.BR patch ( 1 ),
-.BR rcs ( 1 ),
-.BR rcsdiff ( 1 ),
-.BR rcsmerge ( 1 ),
-.BR rlog ( 1 ),
-.BR rm ( 1 ),
-.BR sort ( 1 ).
diff --git a/gnu/usr.bin/cvs/cvs/cvs.5 b/gnu/usr.bin/cvs/cvs/cvs.5
deleted file mode 100644
index cb4f45588043..000000000000
--- a/gnu/usr.bin/cvs/cvs/cvs.5
+++ /dev/null
@@ -1,367 +0,0 @@
-.TH cvs 5 "12 February 1992"
-.\" Full space in nroff; half space in troff
-.de SP
-.if n .sp
-.if t .sp .5
-..
-.SH NAME
-cvs \- Concurrent Versions System support files
-.SH SYNOPSIS
-.hy 0
-.na
-.TP
-.B $CVSROOT/CVSROOT/commitinfo,v
-.TP
-.B $CVSROOT/CVSROOT/cvsignore,v
-.TP
-.B $CVSROOT/CVSROOT/cvswrappers,v
-.TP
-.B $CVSROOT/CVSROOT/editinfo,v
-.TP
-.B $CVSROOT/CVSROOT/history
-.TP
-.B $CVSROOT/CVSROOT/loginfo,v
-.TP
-.B $CVSROOT/CVSROOT/modules,v
-.TP
-.B $CVSROOT/CVSROOT/rcsinfo,v
-.TP
-.B $CVSROOT/CVSROOT/taginfo,v
-.ad b
-.hy 1
-.SH DESCRIPTION
-.B cvs
-is a system for providing source control to hierarchical collections
-of source directories. Commands and procedures for using \fBcvs\fP
-are described in
-.BR cvs ( 1 ).
-.SP
-.B cvs
-manages \fIsource repositories\fP, the directories containing master
-copies of the revision-controlled files, by copying particular
-revisions of the files to (and modifications back from) developers'
-private \fIworking directories\fP. In terms of file structure, each
-individual source repository is an immediate subdirectory of
-\fB$CVSROOT\fP.
-.SP
-The files described here are supporting files; they do not have to
-exist for \fBcvs\fP to operate, but they allow you to make \fBcvs\fP
-operation more flexible.
-.SP
-The
-.BR cvsinit ( 1 )
-shell script included at the top-level of the
-.B cvs
-distribution can be used to setup an initial
-.B $CVSROOT/CVSROOT
-area, if you don't have one already.
-.SP
-You can use the `\|modules\|' file to define symbolic names for
-collections of source maintained with \fBcvs\fP. If there is no
-`\|modules\|' file, developers must specify complete path names
-(absolute, or relative to \fB$CVSROOT\fP) for the files they wish to
-manage with \fBcvs\fP commands.
-.SP
-You can use the `\|commitinfo\|' file to define programs to execute
-whenever `\|\fBcvs commit\fP\|' is about to execute.
-These programs are used for ``pre-commit'' checking to verify that the
-modified, added, and removed files are really ready to be committed.
-Some uses for this check might be to turn off a portion (or all) of the
-source repository from a particular person or group.
-Or, perhaps, to verify that the changed files conform to the site's
-standards for coding practice.
-.SP
-You can use the `\|cvswrappers\|' file to record
-.B cvs
-wrapper commands to be used when checking files into and out of the
-repository. Wrappers allow the file or directory to be processed
-on the way in and out of CVS. The intended uses are many, one
-possible use would be to reformat a C file before the file is checked
-in, so all of the code in the repository looks the same.
-.SP
-You can use the `\|loginfo\|' file to define programs to execute after
-any
-.BR commit ,
-which writes a log entry for changes in the repository.
-These logging programs might be used to append the log message to a file.
-Or send the log message through electronic mail to a group of developers.
-Or, perhaps, post the log message to a particular newsgroup.
-.SP
-You can use the `\|taginfo\|' file to define programs to execute after
-any
-.BR tag or rtag
-operation. These programs might be used to append a message to a file
-listing the new tag name and the programmer who created it, or send mail
-to a group of developers, or, perhaps, post a message to a particular
-newsgroup.
-.SP
-You can use the `\|rcsinfo\|' file to define forms for log messages.
-.SP
-You can use the `\|editinfo\|' file to define a program to execute for
-editing/validating `\|\fBcvs commit\fP\|' log entries.
-This is most useful when used with a `\|rcsinfo\|' forms specification, as
-it can verify that the proper fields of the form have been filled in by the
-user committing the change.
-.SP
-You can use the `\|cvsignore\|' file to specify the default list of
-files to ignore during \fBupdate\fP.
-.SP
-You can use the `\|history\|' file to record the \fBcvs\fP commands
-that affect the repository.
-The creation of this file enables history logging.
-.SH FILES
-.TP
-.B modules
-The `\|modules\|' file records your definitions of names for
-collections of source code. \fBcvs\fP will use these definitions if
-you create a file with the right format in
-`\|\fB$CVSROOT/CVSROOT/modules,v\fP\|'.
-The
-.BR mkmodules ( 1 )
-command should be run whenever the modules file changes, so that the
-appropriate files can be generated (depending on how you have configured
-.B cvs
-operation).
-.SP
-To allow convenient editing of the `\|modules\|' file itself, the file should
-include an entry like the following (where \fIlocalbin\fP represents the
-directory where your site installs programs like
-.BR mkmodules ( 1 )):
-.SP
-.nf
-\&\fBmodules \-i /\fP\fIlocalbin\fP\fB/mkmodules CVSROOT modules\fP
-.fi
-.SP
-This defines the name `\|\fBmodules\fP\|' as the module name for the
-file itself, so that you can use
-.SP
-.in +1i
-.ft B
-.nf
-example% cvs checkout modules
-.fi
-.ft P
-.in -1i
-.SP
-to get an editable copy of the file. You should define similar module
-entries for the other configuration files described here (except
-\&`\|history\|').
-The
-.BR cvsinit ( 8 )
-script will setup a smilar `\|modules\|' file for you automatically.
-.SP
-The `\|modules\|' file may contain blank lines and comments (lines
-beginning with `\|\fB#\fP\|') as well as module definitions.
-Long lines can be continued on the next line by specifying a backslash
-(``\e'') as the last character on the line.
-.SP
-A \fImodule definition\fP is a single line of the `\|modules\|' file,
-in either of two formats. In both cases, \fImname\fP represents the
-symbolic module name, and the remainder of the line is its definition.
-.SP
-\fImname\fP \fB\-a\fP \fIaliases\fP\|.\|.\|.
-.br
-This represents the simplest way of defining a module \fImname\fP.
-The `\|\fB\-a\fP\|' flags the definition as a simple alias: \fBcvs\fP
-will treat any use of \fImname\fP (as a command argument) as if the list
-of names \fIaliases\fP had been specified instead. \fIaliases\fP may
-contain either other module names or paths. When you use paths in
-\fIaliases\fP, `\|\fBcvs checkout\fP\|' creates all intermediate
-directories in the working directory, just as if the path had been
-specified explicitly in the \fBcvs\fP arguments.
-.SP
-.nf
-\fImname\fP [ \fIoptions\fP ] \fIdir\fP [ \fIfiles\fP\|.\|.\|. ] [ \fB&\fP\fImodule\fP\|.\|.\|. ]
-.fi
-.SP
-In the simplest case, this form of module definition reduces to
-`\|\fImname dir\fP\|'. This defines all the files in directory
-\fIdir\fP as module \fImname\fP. \fIdir\fP is a relative path (from
-\fB$CVSROOT\fP) to a directory of source in one of the source
-repositories. In this case, on \fBcheckout\fP, a single directory
-called \fImname\fP is created as a working directory; no intermediate
-directory levels are used by default, even if \fIdir\fP was a path
-involving several directory levels.
-.SP
-By explicitly specifying \fIfiles\fP in the module definition after
-\fIdir\fP, you can select particular files from directory
-\fIdir\fP. The sample definition for \fBmodules\fP is an example of
-a module defined with a single file from a particular directory. Here
-is another example:
-.SP
-.nf
-.ft B
-m4test unsupported/gnu/m4 foreach.m4 forloop.m4
-.ft P
-.fi
-.SP
-With this definition, executing `\|\fBcvs checkout m4test\fP\|'
-will create a single working directory `\|m4test\|' containing the two
-files listed, which both come from a common directory several levels
-deep in the \fBcvs\fP source repository.
-.SP
-A module definition can refer to other modules by including
-`\|\fB&\fP\fImodule\fP\|' in its definition. \fBcheckout\fP creates
-a subdirectory for each such \fImodule\fP, in your working directory.
-.br
-.I
-New in \fBcvs\fP 1.3;
-avoid this feature if sharing module definitions with older versions
-of \fBcvs\fP.
-.SP
-Finally, you can use one or more of the following \fIoptions\fP in
-module definitions:
-.SP
-\&`\|\fB\-d\fP \fIname\fP\|', to name the working directory something
-other than the module name.
-.br
-.I
-New in \fBcvs\fP 1.3;
-avoid this feature if sharing module definitions with older versions
-of \fBcvs\fP.
-.SP
-\&`\|\fB\-i\fP \fIprog\fP\|' allows you to specify a program \fIprog\fP
-to run whenever files in a module are committed. \fIprog\fP runs with a
-single argument, the full pathname of the affected directory in a
-source repository. The `\|commitinfo\|', `\|loginfo\|', and
-`\|editinfo\|' files provide other ways to call a program on \fBcommit\fP.
-.SP
-`\|\fB\-o\fP \fIprog\fP\|' allows you to specify a program \fIprog\fP
-to run whenever files in a module are checked out. \fIprog\fP runs
-with a single argument, the module name.
-.SP
-`\|\fB\-e\fP \fIprog\fP\|' allows you to specify a program \fIprog\fP
-to run whenever files in a module are exported. \fIprog\fP runs
-with a single argument, the module name.
-.SP
-`\|\fB\-t\fP \fIprog\fP\|' allows you to specify a program \fIprog\fP
-to run whenever files in a module are tagged. \fIprog\fP runs with two
-arguments: the module name and the symbolic tag specified to \fBrtag\fP.
-.SP
-`\|\fB\-u\fP \fIprog\fP\|' allows you to specify a program \fIprog\fP
-to run whenever `\|\fBcvs update\fP\|' is executed from the top-level
-directory of the checked-out module. \fIprog\fP runs with a
-single argument, the full path to the source repository for this module.
-.TP
-\&\fBcommitinfo\fP, \fBloginfo\fP, \fBrcsinfo\fP, \fBeditinfo\fP
-These files all specify programs to call at different points in the
-`\|\fBcvs commit\fP\|' process. They have a common structure.
-Each line is a pair of fields: a regular expression, separated by
-whitespace from a filename or command-line template.
-Whenever one of the regular expression matches a directory name in the
-repository, the rest of the line is used.
-If the line begins with a \fB#\fP character, the entire line is considered
-a comment and is ignored.
-Whitespace between the fields is also ignored.
-.SP
-For `\|loginfo\|', the rest of the
-line is a command-line template to execute.
-The templates can include not only
-a program name, but whatever list of arguments you wish. If you write
-`\|\fB%s\fP\|' somewhere on the argument list, \fBcvs\fP supplies, at
-that point, the list of files affected by the \fBcommit\fP.
-The first entry in the list is the relative path within the source
-repository where the change is being made.
-The remaining arguments list the files that are being modified, added, or
-removed by this \fBcommit\fP invocation.
-.SP
-For `\|taginfo\|', the rest of the
-line is a command-line template to execute.
-The arguments passed to the command are, in order, the
-.I tagname ,
-.I operation
-(i.e.
-.B add
-for `tag',
-.B mov
-for `tag -F', and
-.B del
-for `tag -d`),
-.I repository ,
-and any remaining are pairs of
-.B "filename revision" .
-A non-zero exit of the filter program will cause the tag to be aborted.
-.SP
-For `\|commitinfo\|', the rest of the line is a command-line template to
-execute.
-The template can include not only a program name, but whatever
-list of arguments you wish.
-The full path to the current source repository is appended to the template,
-followed by the file names of any files involved in the commit (added,
-removed, and modified files).
-.SP
-For `\|rcsinfo\|', the rest of the line is the full path to a file that
-should be loaded into the log message template.
-.SP
-For `\|editinfo\|', the rest of the line is a command-line template to
-execute.
-The template can include not only a program name, but whatever
-list of arguments you wish.
-The full path to the current log message template file is appended to the
-template.
-.SP
-You can use one of two special strings instead of a regular
-expression: `\|\fBALL\fP\|' specifies a command line template that
-must always be executed, and `\|\fBDEFAULT\fP\|' specifies a command
-line template to use if no regular expression is a match.
-.SP
-The `\|commitinfo\|' file contains commands to execute \fIbefore\fP any
-other \fBcommit\fP activity, to allow you to check any conditions that
-must be satisfied before \fBcommit\fP can proceed. The rest of the
-\fBcommit\fP will execute only if all selected commands from this file
-exit with exit status \fB0\fP.
-.SP
-The `\|rcsinfo\|' file allows you to specify \fIlog templates\fP for
-the \fBcommit\fP logging session; you can use this to provide a form
-to edit when filling out the \fBcommit\fP log. The field after the
-regular expression, in this file, contains filenames (of files
-containing the logging forms) rather than command templates.
-.SP
-The `\|editinfo\|' file allows you to execute a script \fIbefore the
-commit starts\fP, but after the log information is recorded. These
-"edit" scripts can verify information recorded in the log file. If
-the edit script exits wth a non-zero exit status, the commit is aborted.
-.SP
-The `\|loginfo\|' file contains commands to execute \fIat the end\fP
-of a commit. The text specified as a commit log message is piped
-through the command; typical uses include sending mail, filing an
-article in a newsgroup, or appending to a central file.
-.TP
-\&\fBcvsignore\fP, \fB.cvsignore\fP
-The default list of files (or
-.BR sh ( 1 )
-file name patterns) to ignore during `\|\fBcvs update\fP\|'.
-At startup time, \fBcvs\fP loads the compiled in default list of file name
-patterns (see
-.BR cvs ( 1 )).
-Then the per-repository list included in \fB$CVSROOT/CVSROOT/cvsignore\fP
-is loaded, if it exists.
-Then the per-user list is loaded from `\|$HOME/.cvsignore\|'.
-Finally, as \fBcvs\fP traverses through your directories, it will load any
-per-directory `\|.cvsignore\|' files whenever it finds one.
-These per-directory files are only valid for exactly the directory that
-contains them, not for any sub-directories.
-.TP
-.B history
-Create this file in \fB$CVSROOT/CVSROOT\fP to enable history logging
-(see the description of `\|\fBcvs history\fP\|').
-.SH "SEE ALSO"
-.BR cvs ( 1 ),
-.BR mkmodules ( 1 ).
-.SH COPYING
-Copyright \(co 1992 Cygnus Support, Brian Berliner, and Jeff Polk
-.PP
-Permission is granted to make and distribute verbatim copies of
-this manual provided the copyright notice and this permission notice
-are preserved on all copies.
-.PP
-Permission is granted to copy and distribute modified versions of this
-manual under the conditions for verbatim copying, provided that the
-entire resulting derived work is distributed under the terms of a
-permission notice identical to this one.
-.PP
-Permission is granted to copy and distribute translations of this
-manual into another language, under the above conditions for modified
-versions, except that this permission notice may be included in
-translations approved by the Free Software Foundation instead of in
-the original English.
diff --git a/gnu/usr.bin/cvs/cvs/cvs.h b/gnu/usr.bin/cvs/cvs/cvs.h
deleted file mode 100644
index 34c9d8c71f3b..000000000000
--- a/gnu/usr.bin/cvs/cvs/cvs.h
+++ /dev/null
@@ -1,570 +0,0 @@
-/* $CVSid: @(#)cvs.h 1.86 94/10/22 $ */
-
-/*
- * basic information used in all source files
- *
- */
-
-
-#include "config.h" /* this is stuff found via autoconf */
-#include "options.h" /* these are some larger questions which
- can't easily be automatically checked
- for */
-
-/* AIX requires this to be the first thing in the file. */
-#ifdef __GNUC__
-#define alloca __builtin_alloca
-#else /* not __GNUC__ */
-#if HAVE_ALLOCA_H
-#include <alloca.h>
-#else /* not HAVE_ALLOCA_H */
-#ifdef _AIX
- #pragma alloca
-#else /* not _AIX */
-#ifdef ALLOCA_IN_STDLIB
- /* then we need do nothing */
-#else
-char *alloca ();
-#endif /* not ALLOCA_IN_STDLIB */
-#endif /* not _AIX */
-#endif /* not HAVE_ALLOCA_H */
-#endif /* not __GNUC__ */
-
-/* Changed from if __STDC__ to ifdef __STDC__ because of Sun's acc compiler */
-
-#ifdef __STDC__
-#define PTR void *
-#else
-#define PTR char *
-#endif
-
-/* Add prototype support. */
-#ifndef PROTO
-#if defined (USE_PROTOTYPES) ? USE_PROTOTYPES : defined (__STDC__)
-#define PROTO(ARGS) ARGS
-#else
-#define PROTO(ARGS) ()
-#endif
-#endif
-
-#if __GNUC__ == 2
-#define USE(var) static const char sizeof##var = sizeof(sizeof##var) + sizeof(var)
-#else
-#define USE(var) static const char standalone_semis_illegal_sigh
-#endif
-
-
-#include <stdio.h>
-
-/* Under OS/2, <stdio.h> doesn't define popen()/pclose(). */
-#ifdef USE_OWN_POPEN
-#include "popen.h"
-#endif
-
-#ifdef STDC_HEADERS
-#include <stdlib.h>
-#else
-extern void exit ();
-extern char *getenv();
-#endif
-
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
-#ifdef HAVE_STRING_H
-#include <string.h>
-#else
-#include <strings.h>
-#endif
-
-#ifdef SERVER_SUPPORT
-/* If the system doesn't provide strerror, it won't be declared in
- string.h. */
-char *strerror ();
-#endif
-
-#include <fnmatch.h> /* This is supposed to be available on Posix systems */
-
-#include <ctype.h>
-#include <pwd.h>
-#include <signal.h>
-
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#else
-#ifndef errno
-extern int errno;
-#endif /* !errno */
-#endif /* HAVE_ERRNO_H */
-
-#include "system.h"
-
-#include "hash.h"
-#if defined(SERVER_SUPPORT) || defined(CLIENT_SUPPORT)
-#include "server.h"
-#include "client.h"
-#endif
-
-#ifdef AUTH_CLIENT_SUPPORT
-extern int use_authenticating_server;
-void connect_to_pserver();
-# ifndef CVS_AUTH_PORT
-# define CVS_AUTH_PORT 2401
-# endif /* CVS_AUTH_PORT */
-#endif /* AUTH_CLIENT_SUPPORT */
-
-#ifdef MY_NDBM
-#include "myndbm.h"
-#else
-#include <ndbm.h>
-#endif /* MY_NDBM */
-
-#include "regex.h"
-#include "getopt.h"
-#include "wait.h"
-
-/* Define to enable alternate death support (which uses the RCS state). */
-#define DEATH_STATE 1
-
-#define DEATH_SUPPORT 1
-
-#include "rcs.h"
-
-
-/* XXX - for now this is static */
-#ifndef PATH_MAX
-#ifdef MAXPATHLEN
-#define PATH_MAX MAXPATHLEN+2
-#else
-#define PATH_MAX 1024+2
-#endif
-#endif /* PATH_MAX */
-
-/* just in case this implementation does not define this */
-#ifndef L_tmpnam
-#define L_tmpnam 50
-#endif
-
-
-/*
- * Copyright (c) 1992, Brian Berliner and Jeff Polk
- * Copyright (c) 1989-1992, Brian Berliner
- *
- * You may distribute under the terms of the GNU General Public License as
- * specified in the README file that comes with the CVS 1.4 kit.
- *
- * Definitions for the CVS Administrative directory and the files it contains.
- * Here as #define's to make changing the names a simple task.
- */
-#define CVSADM "CVS"
-#define CVSADM_ENT "CVS/Entries"
-#define CVSADM_ENTBAK "CVS/Entries.Backup"
-#define CVSADM_ENTLOG "CVS/Entries.Log"
-#define CVSADM_ENTSTAT "CVS/Entries.Static"
-#define CVSADM_REP "CVS/Repository"
-#define CVSADM_ROOT "CVS/Root"
-#define CVSADM_CIPROG "CVS/Checkin.prog"
-#define CVSADM_UPROG "CVS/Update.prog"
-#define CVSADM_TAG "CVS/Tag"
-
-/*
- * Definitions for the CVSROOT Administrative directory and the files it
- * contains. This directory is created as a sub-directory of the $CVSROOT
- * environment variable, and holds global administration information for the
- * entire source repository beginning at $CVSROOT.
- */
-#define CVSROOTADM "CVSROOT"
-#define CVSROOTADM_MODULES "modules"
-#define CVSROOTADM_LOGINFO "loginfo"
-#define CVSROOTADM_RCSINFO "rcsinfo"
-#define CVSROOTADM_COMMITINFO "commitinfo"
-#define CVSROOTADM_TAGINFO "taginfo"
-#define CVSROOTADM_EDITINFO "editinfo"
-#define CVSROOTADM_HISTORY "history"
-#define CVSROOTADM_IGNORE "cvsignore"
-#define CVSROOTADM_CHECKOUTLIST "checkoutlist"
-#define CVSROOTADM_WRAPPER "cvswrappers"
-#define CVSNULLREPOS "Emptydir" /* an empty directory */
-
-/* support for the modules file (CVSROOTADM_MODULES) */
-#define CVSMODULE_OPTS "ad:i:lo:e:s:t:u:"/* options in modules file */
-#define CVSMODULE_SPEC '&' /* special delimiter */
-
-/* Other CVS file names */
-
-/* Files go in the attic if the head main branch revision is dead,
- otherwise they go in the regular repository directories. The whole
- concept of having an attic is sort of a relic from before death
- support but on the other hand, it probably does help the speed of
- some operations (such as main branch checkouts and updates). */
-#define CVSATTIC "Attic"
-
-#define CVSLCK "#cvs.lock"
-#define CVSTFL "#cvs.tfl"
-#define CVSRFL "#cvs.rfl"
-#define CVSWFL "#cvs.wfl"
-#define CVSRFLPAT "#cvs.rfl.*" /* wildcard expr to match read locks */
-#define CVSEXT_LOG ",t"
-#define CVSPREFIX ",,"
-#define CVSDOTIGNORE ".cvsignore"
-#define CVSDOTWRAPPER ".cvswrappers"
-
-/* miscellaneous CVS defines */
-#define CVSEDITPREFIX "CVS: "
-#define CVSLCKAGE (60*60) /* 1-hour old lock files cleaned up */
-#define CVSLCKSLEEP 30 /* wait 30 seconds before retrying */
-#define CVSBRANCH "1.1.1" /* RCS branch used for vendor srcs */
-#define BAKPREFIX ".#" /* when rcsmerge'ing */
-#ifndef DEVNULL
-#define DEVNULL "/dev/null"
-#endif
-
-#define FALSE 0
-#define TRUE 1
-
-/*
- * Special tags. -rHEAD refers to the head of an RCS file, regardless of any
- * sticky tags. -rBASE refers to the current revision the user has checked
- * out This mimics the behaviour of RCS.
- */
-#define TAG_HEAD "HEAD"
-#define TAG_BASE "BASE"
-
-/* Environment variable used by CVS */
-#define CVSREAD_ENV "CVSREAD" /* make files read-only */
-#define CVSREAD_DFLT FALSE /* writable files by default */
-
-#define RCSBIN_ENV "RCSBIN" /* RCS binary directory */
-/* #define RCSBIN_DFLT Set by config.h */
-
-#define EDITOR1_ENV "CVSEDITOR" /* which editor to use */
-#define EDITOR2_ENV "VISUAL" /* which editor to use */
-#define EDITOR3_ENV "EDITOR" /* which editor to use */
-/* #define EDITOR_DFLT Set by config.h */
-
-#define CVSROOT_ENV "CVSROOT" /* source directory root */
-#define CVSROOT_DFLT NULL /* No dflt; must set for checkout */
-
-#define IGNORE_ENV "CVSIGNORE" /* More files to ignore */
-#define WRAPPER_ENV "CVSWRAPPERS" /* name of the wrapper file */
-
-#define CVSUMASK_ENV "CVSUMASK" /* Effective umask for repository */
-/* #define CVSUMASK_DFLT Set by config.h */
-
-/*
- * If the beginning of the Repository matches the following string, strip it
- * so that the output to the logfile does not contain a full pathname.
- *
- * If the CVSROOT environment variable is set, it overrides this define.
- */
-#define REPOS_STRIP "/master/"
-
-/*
- * The maximum number of files per each CVS directory. This is mainly for
- * sizing arrays statically rather than dynamically. 3000 seems plenty for
- * now.
- */
-#define MAXFILEPERDIR 3000
-#define MAXLINELEN 5000 /* max input line from a file */
-#define MAXPROGLEN 30000 /* max program length to system() */
-#define MAXLISTLEN 40000 /* For [A-Z]list holders */
-#define MAXDATELEN 50 /* max length for a date */
-
-/* structure of a entry record */
-struct entnode
-{
- char *user;
- char *version;
- char *timestamp;
- char *options;
- char *tag;
- char *date;
- char *conflict;
-};
-typedef struct entnode Entnode;
-
-/* The type of request that is being done in do_module() */
-enum mtype
-{
- CHECKOUT, TAG, PATCH, EXPORT
-};
-
-/*
- * defines for Classify_File() to determine the current state of a file.
- * These are also used as types in the data field for the list we make for
- * Update_Logfile in commit, import, and add.
- */
-enum classify_type
-{
- T_UNKNOWN = 1, /* no old-style analog existed */
- T_CONFLICT, /* C (conflict) list */
- T_NEEDS_MERGE, /* G (needs merging) list */
- T_MODIFIED, /* M (needs checked in) list */
- T_CHECKOUT, /* O (needs checkout) list */
- T_ADDED, /* A (added file) list */
- T_REMOVED, /* R (removed file) list */
- T_REMOVE_ENTRY, /* W (removed entry) list */
- T_UPTODATE, /* File is up-to-date */
-#ifdef SERVER_SUPPORT
- T_PATCH, /* P Like C, but can patch */
-#endif
- T_TITLE /* title for node type */
-};
-typedef enum classify_type Ctype;
-
-/*
- * a struct vers_ts contains all the information about a file including the
- * user and rcs file names, and the version checked out and the head.
- *
- * this is usually obtained from a call to Version_TS which takes a tag argument
- * for the RCS file if desired
- */
-struct vers_ts
-{
- char *vn_user; /* rcs version user file derives from
- * it can have the following special
- * values:
- * empty = no user file
- * 0 = user file is new
- * -vers = user file to be removed */
- char *vn_rcs; /* the version for the rcs file
- * (tag version?) */
- char *vn_tag; /* the symbolic tag name */
- char *ts_user; /* the timestamp for the user file */
- char *ts_rcs; /* the user timestamp from entries */
- char *options; /* opts from Entries file
- * (keyword expansion) */
- char *ts_conflict; /* Holds time_stamp of conflict */
- char *tag; /* tag stored in the Entries file */
- char *date; /* date stored in the Entries file */
- Entnode *entdata; /* pointer to entries file node */
- RCSNode *srcfile; /* pointer to parsed src file info */
-};
-typedef struct vers_ts Vers_TS;
-
-/*
- * structure used for list-private storage by Entries_Open() and
- * Version_TS().
- */
-struct stickydirtag
-{
- int aflag;
- char *tag;
- char *date;
- char *options;
-};
-
-/* Flags for find_{names,dirs} routines */
-#define W_LOCAL 0x01 /* look for files locally */
-#define W_REPOS 0x02 /* look for files in the repository */
-#define W_ATTIC 0x04 /* look for files in the attic */
-
-/* Flags for return values of direnter procs for the recursion processor */
-enum direnter_type
-{
- R_PROCESS = 1, /* process files and maybe dirs */
- R_SKIP_FILES, /* don't process files in this dir */
- R_SKIP_DIRS, /* don't process sub-dirs */
- R_SKIP_ALL /* don't process files or dirs */
-};
-typedef enum direnter_type Dtype;
-
-extern char *program_name, *program_path, *command_name;
-extern char *Rcsbin, *Editor, *CVSroot;
-#ifdef CVSADM_ROOT
-extern char *CVSADM_Root;
-extern int cvsadmin_root;
-#endif /* CVSADM_ROOT */
-extern char *CurDir;
-extern int really_quiet, quiet;
-extern int use_editor;
-extern int cvswrite;
-extern mode_t cvsumask;
-
-extern int trace; /* Show all commands */
-extern int noexec; /* Don't modify disk anywhere */
-extern int logoff; /* Don't write history entry */
-
-extern char hostname[];
-
-/* Externs that are included directly in the CVS sources */
-int RCS_settag PROTO((const char *, const char *, const char *));
-int RCS_deltag PROTO((const char *, const char *, int));
-int RCS_setbranch PROTO((const char *, const char *));
-int RCS_lock PROTO((const char *, const char *, int));
-int RCS_unlock PROTO((const char *, const char *, int));
-int RCS_merge PROTO((const char *, const char *, const char *, const char *));
-
-#include "error.h"
-
-DBM *open_module PROTO((void));
-FILE *open_file PROTO((const char *, const char *));
-List *Find_Dirs PROTO((char *repository, int which));
-void Entries_Close PROTO((List *entries));
-List *Entries_Open PROTO((int aflag));
-char *Make_Date PROTO((char *rawdate));
-char *Name_Repository PROTO((char *dir, char *update_dir));
-#ifdef CVSADM_ROOT
-char *Name_Root PROTO((char *dir, char *update_dir));
-void Create_Root PROTO((char *dir, char *rootdir));
-int same_directories PROTO((char *dir1, char *dir2));
-#endif /* CVSADM_ROOT */
-char *Short_Repository PROTO((char *repository));
-char *gca PROTO((char *rev1, char *rev2));
-char *getcaller PROTO((void));
-char *time_stamp PROTO((char *file));
-char *xmalloc PROTO((size_t bytes));
-char *xrealloc PROTO((char *ptr, size_t bytes));
-char *xstrdup PROTO((const char *str));
-void strip_trailing_newlines PROTO((char *str));
-int No_Difference PROTO((char *file, Vers_TS * vers, List * entries,
- char *repository, char *update_dir));
-typedef int (*CALLPROC) PROTO((char *repository, char *value));
-int Parse_Info PROTO((char *infofile, char *repository, CALLPROC callproc, int all));
-int Reader_Lock PROTO((char *xrepository));
-typedef RETSIGTYPE (*SIGCLEANUPPROC) PROTO(());
-int SIG_register PROTO((int sig, SIGCLEANUPPROC sigcleanup));
-int Writer_Lock PROTO((List * list));
-int ign_name PROTO((char *name));
-int isdir PROTO((const char *file));
-int isfile PROTO((const char *file));
-int islink PROTO((const char *file));
-int isreadable PROTO((const char *file));
-int iswritable PROTO((const char *file));
-int isaccessible PROTO((const char *file, const int mode));
-int isabsolute PROTO((const char *filename));
-char *last_component PROTO((char *path));
-
-int joining PROTO((void));
-int numdots PROTO((const char *s));
-int unlink_file PROTO((const char *f));
-int unlink_file_dir PROTO((const char *f));
-int update PROTO((int argc, char *argv[]));
-int xcmp PROTO((const char *file1, const char *file2));
-int yesno PROTO((void));
-void *valloc PROTO((size_t bytes));
-time_t get_date PROTO((char *date, struct timeb *now));
-void Create_Admin PROTO((char *dir, char *update_dir,
- char *repository, char *tag, char *date));
-void Lock_Cleanup PROTO((void));
-void ParseTag PROTO((char **tagp, char **datep));
-void Scratch_Entry PROTO((List * list, char *fname));
-void WriteTag PROTO((char *dir, char *tag, char *date));
-void cat_module PROTO((int status));
-void check_entries PROTO((char *dir));
-void close_module PROTO((DBM * db));
-void copy_file PROTO((const char *from, const char *to));
-void (*error_set_cleanup PROTO((void (*) (void)))) PROTO ((void));
-void fperror PROTO((FILE * fp, int status, int errnum, char *message,...));
-void free_names PROTO((int *pargc, char *argv[]));
-void freevers_ts PROTO((Vers_TS ** versp));
-void ign_add PROTO((char *ign, int hold));
-void ign_add_file PROTO((char *file, int hold));
-void ign_setup PROTO((void));
-void ign_dir_add PROTO((char *name));
-int ignore_directory PROTO((char *name));
-void line2argv PROTO((int *pargc, char *argv[], char *line));
-void make_directories PROTO((const char *name));
-void make_directory PROTO((const char *name));
-void rename_file PROTO((const char *from, const char *to));
-void strip_path PROTO((char *path));
-void strip_trailing_slashes PROTO((char *path));
-void update_delproc PROTO((Node * p));
-void usage PROTO((const char *const *cpp));
-void xchmod PROTO((char *fname, int writable));
-char *xgetwd PROTO((void));
-int Checkin PROTO((int type, char *file, char *update_dir,
- char *repository, char *rcs, char *rev,
- char *tag, char *options, char *message, List *entries));
-Ctype Classify_File PROTO((char *file, char *tag, char *date, char *options,
- int force_tag_match, int aflag, char *repository,
- List *entries, List *srcfiles, Vers_TS **versp,
- char *update_dir, int pipeout));
-List *Find_Names PROTO((char *repository, int which, int aflag,
- List ** optentries));
-void Register PROTO((List * list, char *fname, char *vn, char *ts,
- char *options, char *tag, char *date, char *ts_conflict));
-void Update_Logfile PROTO((char *repository, char *xmessage, char *xrevision,
- FILE * xlogfp, List * xchanges));
-Vers_TS *Version_TS PROTO((char *repository, char *options, char *tag,
- char *date, char *user, int force_tag_match,
- int set_time, List * entries, List * xfiles));
-void do_editor PROTO((char *dir, char **messagep,
- char *repository, List * changes));
-
-typedef int (*CALLBACKPROC) PROTO((int *pargc, char *argv[], char *where,
- char *mwhere, char *mfile, int horten, int local_specified,
- char *omodule, char *msg));
-typedef int (*FILEPROC) PROTO((char *file, char *update_dir, char *repository,
- List * entries, List * srcfiles));
-typedef int (*FILESDONEPROC) PROTO((int err, char *repository, char *update_dir));
-typedef Dtype (*DIRENTPROC) PROTO((char *dir, char *repos, char *update_dir));
-typedef int (*DIRLEAVEPROC) PROTO((char *dir, int err, char *update_dir));
-
-int do_module PROTO((DBM * db, char *mname, enum mtype m_type, char *msg,
- CALLBACKPROC callback_proc, char *where, int shorten,
- int local_specified, int run_module_prog, char *extra_arg));
-int do_recursion PROTO((FILEPROC xfileproc, FILESDONEPROC xfilesdoneproc,
- DIRENTPROC xdirentproc, DIRLEAVEPROC xdirleaveproc,
- Dtype xflags, int xwhich, int xaflag, int xreadlock,
- int xdosrcs));
-int do_update PROTO((int argc, char *argv[], char *xoptions, char *xtag,
- char *xdate, int xforce, int local, int xbuild,
- int xaflag, int xprune, int xpipeout, int which,
- char *xjoin_rev1, char *xjoin_rev2, char *preload_update_dir));
-void history_write PROTO((int type, char *update_dir, char *revs, char *name,
- char *repository));
-int start_recursion PROTO((FILEPROC fileproc, FILESDONEPROC filesdoneproc,
- DIRENTPROC direntproc, DIRLEAVEPROC dirleaveproc,
- int argc, char *argv[], int local, int which,
- int aflag, int readlock, char *update_preload,
- int dosrcs, int wd_is_repos));
-void SIG_beginCrSect PROTO((void));
-void SIG_endCrSect PROTO((void));
-void read_cvsrc PROTO((int *argc, char ***argv));
-
-char *make_message_rcslegal PROTO((char *message));
-
-/* flags for run_exec(), the fast system() for CVS */
-#define RUN_NORMAL 0x0000 /* no special behaviour */
-#define RUN_COMBINED 0x0001 /* stdout is duped to stderr */
-#define RUN_REALLY 0x0002 /* do the exec, even if noexec is on */
-#define RUN_STDOUT_APPEND 0x0004 /* append to stdout, don't truncate */
-#define RUN_STDERR_APPEND 0x0008 /* append to stderr, don't truncate */
-#define RUN_SIGIGNORE 0x0010 /* ignore interrupts for command */
-#define RUN_TTY (char *)0 /* for the benefit of lint */
-
-void run_arg PROTO((const char *s));
-void run_print PROTO((FILE * fp));
-#ifdef HAVE_VPRINTF
-void run_setup PROTO((const char *fmt,...));
-void run_args PROTO((const char *fmt,...));
-#else
-void run_setup ();
-void run_args ();
-#endif
-int run_exec PROTO((char *stin, char *stout, char *sterr, int flags));
-
-/* other similar-minded stuff from run.c. */
-FILE *Popen PROTO((const char *, const char *));
-int piped_child PROTO((char **, int *, int *));
-void close_on_exec PROTO((int));
-int filter_stream_through_program PROTO((int, int, char **, pid_t *));
-
-pid_t waitpid PROTO((pid_t, int *, int));
-
-/* Wrappers. */
-
-typedef enum { WRAP_MERGE, WRAP_COPY } WrapMergeMethod;
-typedef enum { WRAP_TOCVS, WRAP_FROMCVS, WRAP_CONFLICT } WrapMergeHas;
-
-void wrap_setup PROTO((void));
-int wrap_name_has PROTO((const char *name,WrapMergeHas has));
-char *wrap_tocvs_process_file PROTO((const char *fileName));
-int wrap_merge_is_copy PROTO((const char *fileName));
-char *wrap_fromcvs_process_file PROTO((const char *fileName));
-/* Pathname expansion */
-char *expand_path PROTO((char *name));
-void wrap_add_file PROTO((const char *file,int temp));
-void wrap_add PROTO((char *line,int temp));
diff --git a/gnu/usr.bin/cvs/cvs/cvsbug.sh b/gnu/usr.bin/cvs/cvs/cvsbug.sh
deleted file mode 100644
index 8c6a5bbd36b1..000000000000
--- a/gnu/usr.bin/cvs/cvs/cvsbug.sh
+++ /dev/null
@@ -1,533 +0,0 @@
-#!/bin/sh
-# Submit a problem report to a GNATS site.
-# Copyright (C) 1993 Free Software Foundation, Inc.
-# Contributed by Brendan Kehoe (brendan@cygnus.com), based on a
-# version written by Heinz G. Seidl (hgs@ide.com).
-#
-# This file is part of GNU GNATS.
-# Modified by Berliner for CVS.
-# $CVSid: @(#)cvsbug.sh 1.2 94/10/22 $
-#
-# GNU GNATS is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2, or (at your option)
-# any later version.
-#
-# GNU GNATS is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with GNU GNATS; see the file COPYING. If not, write to
-# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
-# The version of this send-pr.
-VERSION=3.2
-
-# The submitter-id for your site.
-SUBMITTER=net
-
-## # Where the GNATS directory lives, if at all.
-## [ -z "$GNATS_ROOT" ] &&
-## GNATS_ROOT=/usr/local/lib/gnats/gnats-db
-
-# The default mail address for PR submissions.
-GNATS_ADDR=bug-cvs@prep.ai.mit.edu
-
-## # Where the gnats category tree lives.
-## DATADIR=/usr/local/lib
-
-## # If we've been moved around, try using GCC_EXEC_PREFIX.
-## [ ! -d $DATADIR/gnats -a -d "$GCC_EXEC_PREFIX" ] && DATADIR=${GCC_EXEC_PREFIX}..
-
-# The default release for this host.
-DEFAULT_RELEASE="cvs-1.4A2"
-
-# The default organization.
-DEFAULT_ORGANIZATION="net"
-
-## # The default site to look for.
-## GNATS_SITE=unknown
-
-## # Newer config information?
-## [ -f ${GNATS_ROOT}/gnats-adm/config ] && . ${GNATS_ROOT}/gnats-adm/config
-
-# What mailer to use. This must come after the config file, since it is
-# host-dependent.
-MAIL_AGENT="/usr/lib/sendmail -oi -t"
-MAILER=`echo $MAIL_AGENT | sed -e 's, .*,,'`
-if [ ! -f "$MAILER" ] ; then
- echo "$COMMAND: Cannot file mail program \"$MAILER\"."
- echo "$COMMAND: Please fix the MAIL_AGENT entry in the $COMMAND file."
- exit 1
-fi
-
-if test "`echo -n foo`" = foo ; then
- ECHON=bsd
-elif test "`echo 'foo\c'`" = foo ; then
- ECHON=sysv
-else
- ECHON=none
-fi
-
-if [ $ECHON = bsd ] ; then
- ECHON1="echo -n"
- ECHON2=
-elif [ $ECHON = sysv ] ; then
- ECHON1=echo
- ECHON2='\c'
-else
- ECHON1=echo
- ECHON2=
-fi
-
-#
-
-[ -z "$TMPDIR" ] && TMPDIR=/tmp
-
-TEMP=$TMPDIR/p$$
-BAD=$TMPDIR/pbad$$
-REF=$TMPDIR/pf$$
-
-if [ -z "$LOGNAME" -a -n "$USER" ]; then
- LOGNAME=$USER
-fi
-
-FROM="$LOGNAME"
-REPLY_TO="$LOGNAME"
-
-# Find out the name of the originator of this PR.
-if [ -n "$NAME" ]; then
- ORIGINATOR="$NAME"
-elif [ -f $HOME/.fullname ]; then
- ORIGINATOR="`sed -e '1q' $HOME/.fullname`"
-elif [ -f /bin/domainname ]; then
- if [ "`/bin/domainname`" != "" -a -f /usr/bin/ypcat ]; then
- # Must use temp file due to incompatibilities in quoting behavior
- # and to protect shell metacharacters in the expansion of $LOGNAME
- /usr/bin/ypcat passwd 2>/dev/null | cat - /etc/passwd | grep "^$LOGNAME:" |
- cut -f5 -d':' | sed -e 's/,.*//' > $TEMP
- ORIGINATOR="`cat $TEMP`"
- rm -f $TEMP
- fi
-fi
-
-if [ "$ORIGINATOR" = "" ]; then
- grep "^$LOGNAME:" /etc/passwd | cut -f5 -d':' | sed -e 's/,.*//' > $TEMP
- ORIGINATOR="`cat $TEMP`"
- rm -f $TEMP
-fi
-
-if [ -n "$ORGANIZATION" ]; then
- if [ -f "$ORGANIZATION" ]; then
- ORGANIZATION="`cat $ORGANIZATION`"
- fi
-else
- if [ -n "$DEFAULT_ORGANIZATION" ]; then
- ORGANIZATION="$DEFAULT_ORGANIZATION"
- elif [ -f $HOME/.organization ]; then
- ORGANIZATION="`cat $HOME/.organization`"
- elif [ -f $HOME/.signature ]; then
- ORGANIZATION="`cat $HOME/.signature`"
- fi
-fi
-
-# If they don't have a preferred editor set, then use
-if [ -z "$VISUAL" ]; then
- if [ -z "$EDITOR" ]; then
- EDIT=vi
- else
- EDIT="$EDITOR"
- fi
-else
- EDIT="$VISUAL"
-fi
-
-# Find out some information.
-SYSTEM=`( [ -f /bin/uname ] && /bin/uname -a ) || \
- ( [ -f /usr/bin/uname ] && /usr/bin/uname -a ) || echo ""`
-ARCH=`[ -f /bin/arch ] && /bin/arch`
-MACHINE=`[ -f /bin/machine ] && /bin/machine`
-
-COMMAND=`echo $0 | sed -e 's,.*/,,'`
-## USAGE="Usage: $COMMAND [-PVL] [-t address] [-f filename] [--request-id]
-USAGE="Usage: $COMMAND [-PVL]
-[--version]"
-REMOVE=
-BATCH=
-
-while [ $# -gt 0 ]; do
- case "$1" in
- -r) ;; # Ignore for backward compat.
-## -t | --to) if [ $# -eq 1 ]; then echo "$USAGE"; exit 1; fi
-## shift ; GNATS_ADDR="$1"
-## EXPLICIT_GNATS_ADDR=true
-## ;;
-## -f | --file) if [ $# -eq 1 ]; then echo "$USAGE"; exit 1; fi
-## shift ; IN_FILE="$1"
-## if [ "$IN_FILE" != "-" -a ! -r "$IN_FILE" ]; then
-## echo "$COMMAND: cannot read $IN_FILE"
-## exit 1
-## fi
-## ;;
- -b | --batch) BATCH=true ;;
- -p | -P | --print) PRINT=true ;;
- -L | --list) FORMAT=norm ;;
- -l | -CL | --lisp) FORMAT=lisp ;;
-## --request-id) REQUEST_ID=true ;;
- -h | --help) echo "$USAGE"; exit 0 ;;
- -V | --version) echo "$VERSION"; exit 0 ;;
- -*) echo "$USAGE" ; exit 1 ;;
- *) echo "$USAGE" ; exit 1
-## if [ -z "$USER_GNATS_SITE" ]; then
-## if [ ! -r "$DATADIR/gnats/$1" ]; then
-## echo "$COMMAND: the GNATS site $1 does not have a categories list."
-## exit 1
-## else
-## # The site name is the alias they'll have to have created.
-## USER_GNATS_SITE=$1
-## fi
-## else
-## echo "$USAGE" ; exit 1
-## fi
- ;;
- esac
- shift
-done
-
-if [ -n "$USER_GNATS_SITE" ]; then
- GNATS_SITE=$USER_GNATS_SITE
- GNATS_ADDR=$USER_GNATS_SITE-gnats
-fi
-
-if [ "$SUBMITTER" = "unknown" -a -z "$REQUEST_ID" -a -z "$IN_FILE" ]; then
- cat << '__EOF__'
-It seems that send-pr is not installed with your unique submitter-id.
-You need to run
-
- install-sid YOUR-SID
-
-where YOUR-SID is the identification code you received with `send-pr'.
-`send-pr' will automatically insert this value into the template field
-`>Submitter-Id'. If you've downloaded `send-pr' from the Net, use `net'
-for this value. If you do not know your id, run `send-pr --request-id' to
-get one from your support site.
-__EOF__
- exit 1
-fi
-
-## if [ -r "$DATADIR/gnats/$GNATS_SITE" ]; then
-## CATEGORIES=`grep -v '^#' $DATADIR/gnats/$GNATS_SITE | sort`
-## else
-## echo "$COMMAND: could not read $DATADIR/gnats/$GNATS_SITE for categories list."
-## exit 1
-## fi
-CATEGORIES="contrib cvs doc pcl-cvs portability"
-
-if [ -z "$CATEGORIES" ]; then
- echo "$COMMAND: the categories list for $GNATS_SITE was empty!"
- exit 1
-fi
-
-case "$FORMAT" in
- lisp) echo "$CATEGORIES" | \
- awk 'BEGIN {printf "( "} {printf "(\"%s\") ",$0} END {printf ")\n"}'
- exit 0
- ;;
- norm) l=`echo "$CATEGORIES" | \
- awk 'BEGIN {max = 0; } { if (length($0) > max) { max = length($0); } }
- END {print max + 1;}'`
- c=`expr 70 / $l`
- if [ $c -eq 0 ]; then c=1; fi
- echo "$CATEGORIES" | \
- awk 'BEGIN {print "Known categories:"; i = 0 }
- { printf ("%-'$l'.'$l's", $0); if ((++i % '$c') == 0) { print "" } }
- END { print ""; }'
- exit 0
- ;;
-esac
-
-ORIGINATOR_C='<name of the PR author (one line)>'
-ORGANIZATION_C='<organization of PR author (multiple lines)>'
-CONFIDENTIAL_C='<[ yes | no ] (one line)>'
-SYNOPSIS_C='<synopsis of the problem (one line)>'
-SEVERITY_C='<[ non-critical | serious | critical ] (one line)>'
-PRIORITY_C='<[ low | medium | high ] (one line)>'
-CATEGORY_C='<name of the product (one line)>'
-CLASS_C='<[ sw-bug | doc-bug | change-request | support ] (one line)>'
-RELEASE_C='<release number or tag (one line)>'
-ENVIRONMENT_C='<machine, os, target, libraries (multiple lines)>'
-DESCRIPTION_C='<precise description of the problem (multiple lines)>'
-HOW_TO_REPEAT_C='<code/input/activities to reproduce the problem (multiple lines)>'
-FIX_C='<how to correct or work around the problem, if known (multiple lines)>'
-
-# Catch some signals. ($xs kludge needed by Sun /bin/sh)
-xs=0
-trap 'rm -f $REF $TEMP; exit $xs' 0
-trap 'echo "$COMMAND: Aborting ..."; rm -f $REF $TEMP; xs=1; exit' 1 2 3 13 15
-
-# If they told us to use a specific file, then do so.
-if [ -n "$IN_FILE" ]; then
- if [ "$IN_FILE" = "-" ]; then
- # The PR is coming from the standard input.
- if [ -n "$EXPLICIT_GNATS_ADDR" ]; then
- sed -e "s;^[Tt][Oo]:.*;To: $GNATS_ADDR;" > $TEMP
- else
- cat > $TEMP
- fi
- else
- # Use the file they named.
- if [ -n "$EXPLICIT_GNATS_ADDR" ]; then
- sed -e "s;^[Tt][Oo]:.*;To: $GNATS_ADDR;" $IN_FILE > $TEMP
- else
- cat $IN_FILE > $TEMP
- fi
- fi
-else
-
- if [ -n "$PR_FORM" -a -z "$PRINT_INTERN" ]; then
- # If their PR_FORM points to a bogus entry, then bail.
- if [ ! -f "$PR_FORM" -o ! -r "$PR_FORM" -o ! -s "$PR_FORM" ]; then
- echo "$COMMAND: can't seem to read your template file (\`$PR_FORM'), ignoring PR_FORM"
- sleep 1
- PRINT_INTERN=bad_prform
- fi
- fi
-
- if [ -n "$PR_FORM" -a -z "$PRINT_INTERN" ]; then
- cp $PR_FORM $TEMP ||
- ( echo "$COMMAND: could not copy $PR_FORM" ; xs=1; exit )
- else
- for file in $TEMP $REF ; do
- cat > $file << '__EOF__'
-SEND-PR: -*- send-pr -*-
-SEND-PR: Lines starting with `SEND-PR' will be removed automatically, as
-SEND-PR: will all comments (text enclosed in `<' and `>').
-SEND-PR:
-SEND-PR: Choose from the following categories:
-SEND-PR:
-__EOF__
-
- # Format the categories so they fit onto lines.
- l=`echo "$CATEGORIES" | \
- awk 'BEGIN {max = 0; } { if (length($0) > max) { max = length($0); } }
- END {print max + 1;}'`
- c=`expr 61 / $l`
- if [ $c -eq 0 ]; then c=1; fi
- echo "$CATEGORIES" | \
- awk 'BEGIN {printf "SEND-PR: "; i = 0 }
- { printf ("%-'$l'.'$l's", $0);
- if ((++i % '$c') == 0) { printf "\nSEND-PR: " } }
- END { printf "\nSEND-PR:\n"; }' >> $file
-
- cat >> $file << __EOF__
-To: $GNATS_ADDR
-Subject:
-From: $FROM
-Reply-To: $REPLY_TO
-X-send-pr-version: $VERSION
-
-
->Submitter-Id: $SUBMITTER
->Originator: $ORIGINATOR
->Organization:
-`
- if [ -n "$ORGANIZATION" ]; then
- echo "$ORGANIZATION"
- else
- echo " $ORGANIZATION_C" ;
- fi ;
-`
->Confidential: $CONFIDENTIAL_C
->Synopsis: $SYNOPSIS_C
->Severity: $SEVERITY_C
->Priority: $PRIORITY_C
->Category: $CATEGORY_C
->Class: $CLASS_C
->Release: `if [ -n "$DEFAULT_RELEASE" ]; then
- echo "$DEFAULT_RELEASE"
- else
- echo " $RELEASE_C"
- fi; `
->Environment:
- $ENVIRONMENT_C
-`[ -n "$SYSTEM" ] && echo System: $SYSTEM`
-`[ -n "$ARCH" ] && echo Architecture: $ARCH`
-`[ -n "$MACHINE" ] && echo Machine: $MACHINE`
->Description:
- $DESCRIPTION_C
->How-To-Repeat:
- $HOW_TO_REPEAT_C
->Fix:
- $FIX_C
-__EOF__
- done
- fi
-
- if [ "$PRINT" = true -o "$PRINT_INTERN" = true ]; then
- cat $TEMP
- xs=0; exit
- fi
-
- chmod u+w $TEMP
- if [ -z "$REQUEST_ID" ]; then
- eval $EDIT $TEMP
- else
- ed -s $TEMP << '__EOF__'
-/^Subject/s/^Subject:.*/Subject: request for a customer id/
-/^>Category/s/^>Category:.*/>Category: send-pr/
-w
-q
-__EOF__
- fi
-
- if cmp -s $REF $TEMP ; then
- echo "$COMMAND: problem report not filled out, therefore not sent"
- xs=1; exit
- fi
-fi
-
-#
-# Check the enumeration fields
-
-# This is a "sed-subroutine" with one keyword parameter
-# (with workaround for Sun sed bug)
-#
-SED_CMD='
-/$PATTERN/{
-s|||
-s|<.*>||
-s|^[ ]*||
-s|[ ]*$||
-p
-q
-}'
-
-
-while [ -z "$REQUEST_ID" ]; do
- CNT=0
-
- # 1) Confidential
- #
- PATTERN=">Confidential:"
- CONFIDENTIAL=`eval sed -n -e "\"$SED_CMD\"" $TEMP`
- case "$CONFIDENTIAL" in
- ""|yes|no) CNT=`expr $CNT + 1` ;;
- *) echo "$COMMAND: \`$CONFIDENTIAL' is not a valid value for \`Confidential'." ;;
- esac
- #
- # 2) Severity
- #
- PATTERN=">Severity:"
- SEVERITY=`eval sed -n -e "\"$SED_CMD\"" $TEMP`
- case "$SEVERITY" in
- ""|non-critical|serious|critical) CNT=`expr $CNT + 1` ;;
- *) echo "$COMMAND: \`$SEVERITY' is not a valid value for \`Severity'."
- esac
- #
- # 3) Priority
- #
- PATTERN=">Priority:"
- PRIORITY=`eval sed -n -e "\"$SED_CMD\"" $TEMP`
- case "$PRIORITY" in
- ""|low|medium|high) CNT=`expr $CNT + 1` ;;
- *) echo "$COMMAND: \`$PRIORITY' is not a valid value for \`Priority'."
- esac
- #
- # 4) Category
- #
- PATTERN=">Category:"
- CATEGORY=`eval sed -n -e "\"$SED_CMD\"" $TEMP`
- FOUND=
- for C in $CATEGORIES
- do
- if [ "$C" = "$CATEGORY" ]; then FOUND=true ; break ; fi
- done
- if [ -n "$FOUND" ]; then
- CNT=`expr $CNT + 1`
- else
- if [ -z "$CATEGORY" ]; then
- echo "$COMMAND: you must include a Category: field in your report."
- else
- echo "$COMMAND: \`$CATEGORY' is not a known category."
- fi
- fi
- #
- # 5) Class
- #
- PATTERN=">Class:"
- CLASS=`eval sed -n -e "\"$SED_CMD\"" $TEMP`
- case "$CLASS" in
- ""|sw-bug|doc-bug|change-request|support) CNT=`expr $CNT + 1` ;;
- *) echo "$COMMAND: \`$CLASS' is not a valid value for \`Class'."
- esac
-
- [ $CNT -lt 5 -a -z "$BATCH" ] &&
- echo "Errors were found with the problem report."
-
- while true; do
- if [ -z "$BATCH" ]; then
- $ECHON1 "a)bort, e)dit or s)end? $ECHON2"
- read input
- else
- if [ $CNT -eq 5 ]; then
- input=s
- else
- input=a
- fi
- fi
- case "$input" in
- a*)
- if [ -z "$BATCH" ]; then
- echo "$COMMAND: the problem report remains in $BAD and is not sent."
- mv $TEMP $BAD
- else
- echo "$COMMAND: the problem report is not sent."
- fi
- xs=1; exit
- ;;
- e*)
- eval $EDIT $TEMP
- continue 2
- ;;
- s*)
- break 2
- ;;
- esac
- done
-done
-#
-# Remove comments and send the problem report
-# (we have to use patterns, where the comment contains regex chars)
-#
-# /^>Originator:/s;$ORIGINATOR;;
-sed -e "
-/^SEND-PR:/d
-/^>Organization:/,/^>[A-Za-z-]*:/s;$ORGANIZATION_C;;
-/^>Confidential:/s;<.*>;;
-/^>Synopsis:/s;$SYNOPSIS_C;;
-/^>Severity:/s;<.*>;;
-/^>Priority:/s;<.*>;;
-/^>Category:/s;$CATEGORY_C;;
-/^>Class:/s;<.*>;;
-/^>Release:/,/^>[A-Za-z-]*:/s;$RELEASE_C;;
-/^>Environment:/,/^>[A-Za-z-]*:/s;$ENVIRONMENT_C;;
-/^>Description:/,/^>[A-Za-z-]*:/s;$DESCRIPTION_C;;
-/^>How-To-Repeat:/,/^>[A-Za-z-]*:/s;$HOW_TO_REPEAT_C;;
-/^>Fix:/,/^>[A-Za-z-]*:/s;$FIX_C;;
-" $TEMP > $REF
-
-if $MAIL_AGENT < $REF; then
- echo "$COMMAND: problem report sent"
- xs=0; exit
-else
- echo "$COMMAND: mysterious mail failure."
- if [ -z "$BATCH" ]; then
- echo "$COMMAND: the problem report remains in $BAD and is not sent."
- mv $REF $BAD
- else
- echo "$COMMAND: the problem report is not sent."
- fi
- xs=1; exit
-fi
diff --git a/gnu/usr.bin/cvs/cvs/cvsrc.c b/gnu/usr.bin/cvs/cvs/cvsrc.c
deleted file mode 100644
index 5882afceb265..000000000000
--- a/gnu/usr.bin/cvs/cvs/cvsrc.c
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * Copyright (c) 1993 david d zuhn
- *
- * written by david d `zoo' zuhn while at Cygnus Support
- *
- * You may distribute under the terms of the GNU General Public License
- * as specified in the README file that comes with the CVS 1.4 kit.
- *
- */
-
-
-#include "cvs.h"
-#include "getline.h"
-
-#ifndef lint
-static const char rcsid[] = "$CVSid: @(#)cvsrc.c 1.9 94/09/30 $";
-USE(rcsid);
-#endif /* lint */
-
-/* this file is to be found in the user's home directory */
-
-#ifndef CVSRC_FILENAME
-#define CVSRC_FILENAME ".cvsrc"
-#endif
-char cvsrc[] = CVSRC_FILENAME;
-
-#define GROW 10
-
-extern char *strtok ();
-
-void
-read_cvsrc (argc, argv)
- int *argc;
- char ***argv;
-{
- char *homedir;
- char *homeinit;
- FILE *cvsrcfile;
-
- char *line;
- int line_length;
- size_t line_chars_allocated;
-
- char *optstart;
-
- int command_len;
- int found = 0;
-
- int i;
-
- int new_argc;
- int max_new_argv;
- char **new_argv;
-
- /* don't do anything if argc is -1, since that implies "help" mode */
- if (*argc == -1)
- return;
-
- /* setup the new options list */
-
- new_argc = 1;
- max_new_argv = (*argc) + GROW;
- new_argv = (char **) xmalloc (max_new_argv * sizeof (char*));
- new_argv[0] = xstrdup ((*argv)[0]);
-
- /* determine filename for ~/.cvsrc */
-
- homedir = getenv ("HOME");
- if (!homedir)
- return;
-
- homeinit = (char *) xmalloc (strlen (homedir) + strlen (cvsrc) + 10);
- strcpy (homeinit, homedir);
- strcat (homeinit, "/");
- strcat (homeinit, cvsrc);
-
- /* if it can't be read, there's no point to continuing */
-
- if (!isreadable (homeinit))
- {
- free (homeinit);
- return;
- }
-
- /* now scan the file until we find the line for the command in question */
-
- line = NULL;
- line_chars_allocated = 0;
- command_len = strlen (command_name);
- cvsrcfile = open_file (homeinit, "r");
- while ((line_length = getline (&line, &line_chars_allocated, cvsrcfile))
- >= 0)
- {
- /* skip over comment lines */
- if (line[0] == '#')
- continue;
-
- /* stop if we match the current command */
- if (!strncmp (line, command_name, command_len)
- && isspace (*(line + command_len)))
- {
- found = 1;
- break;
- }
- }
-
- fclose (cvsrcfile);
-
- if (found)
- {
- /* skip over command in the options line */
- optstart = strtok (line + command_len, "\t \n");
-
- do
- {
- new_argv [new_argc] = xstrdup (optstart);
- new_argv [new_argc+1] = NULL;
- new_argc += 1;
-
- if (new_argc >= max_new_argv)
- {
- char **tmp_argv;
- max_new_argv += GROW;
- tmp_argv = (char **) xmalloc (max_new_argv * sizeof (char*));
- for (i = 0; i <= new_argc; i++)
- tmp_argv[i] = new_argv[i];
- free(new_argv);
- new_argv = tmp_argv;
- }
-
- }
- while ((optstart = strtok (NULL, "\t \n")) != NULL);
- }
-
- if (line != NULL)
- free (line);
-
- /* now copy the remaining arguments */
-
- for (i=1; i < *argc; i++)
- {
- new_argv [new_argc] = (*argv)[i];
- new_argc += 1;
- }
-
- *argc = new_argc;
- *argv = new_argv;
-
- free (homeinit);
- return;
-}
diff --git a/gnu/usr.bin/cvs/cvs/diff.c b/gnu/usr.bin/cvs/cvs/diff.c
deleted file mode 100644
index 22fda750c30b..000000000000
--- a/gnu/usr.bin/cvs/cvs/diff.c
+++ /dev/null
@@ -1,633 +0,0 @@
-/*
- * Copyright (c) 1992, Brian Berliner and Jeff Polk
- * Copyright (c) 1989-1992, Brian Berliner
- *
- * You may distribute under the terms of the GNU General Public License as
- * specified in the README file that comes with the CVS 1.4 kit.
- *
- * Difference
- *
- * Run diff against versions in the repository. Options that are specified are
- * passed on directly to "rcsdiff".
- *
- * Without any file arguments, runs diff against all the currently modified
- * files.
- */
-
-#include "cvs.h"
-
-#ifndef lint
-static const char rcsid[] = "$CVSid: @(#)diff.c 1.61 94/10/22 $";
-USE(rcsid);
-#endif
-
-static Dtype diff_dirproc PROTO((char *dir, char *pos_repos, char *update_dir));
-static int diff_filesdoneproc PROTO((int err, char *repos, char *update_dir));
-static int diff_dirleaveproc PROTO((char *dir, int err, char *update_dir));
-static int diff_file_nodiff PROTO((char *file, char *repository, List *entries,
- List *srcfiles, Vers_TS *vers));
-static int diff_fileproc PROTO((char *file, char *update_dir, char *repository,
- List * entries, List * srcfiles));
-static void diff_mark_errors PROTO((int err));
-
-static char *diff_rev1, *diff_rev2;
-static char *diff_date1, *diff_date2;
-static char *use_rev1, *use_rev2;
-
-#ifdef SERVER_SUPPORT
-/* Revision of the user file, if it is unchanged from something in the
- repository and we want to use that fact. */
-static char *user_file_rev;
-#endif
-
-static char *options;
-static char opts[PATH_MAX];
-static int diff_errors;
-static int empty_files = 0;
-
-static const char *const diff_usage[] =
-{
- "Usage: %s %s [-lN] [rcsdiff-options]\n",
-#ifdef CVS_DIFFDATE
- " [[-r rev1 | -D date1] [-r rev2 | -D date2]] [files...] \n",
-#else
- " [-r rev1 [-r rev2]] [files...] \n",
-#endif
- "\t-l\tLocal directory only, not recursive\n",
- "\t-D d1\tDiff revision for date against working file.\n",
- "\t-D d2\tDiff rev1/date1 against date2.\n",
- "\t-N\tinclude diffs for added and removed files.\n",
- "\t-r rev1\tDiff revision for rev1 against working file.\n",
- "\t-r rev2\tDiff rev1/date1 against rev2.\n",
- NULL
-};
-
-int
-diff (argc, argv)
- int argc;
- char **argv;
-{
- char tmp[50];
- int c, err = 0;
- int local = 0;
- int which;
-
- if (argc == -1)
- usage (diff_usage);
-
- /*
- * Note that we catch all the valid arguments here, so that we can
- * intercept the -r arguments for doing revision diffs; and -l/-R for a
- * non-recursive/recursive diff.
- */
-#ifdef SERVER_SUPPORT
- /* Need to be able to do this command more than once (according to
- the protocol spec, even if the current client doesn't use it). */
- opts[0] = '\0';
-#endif
- optind = 1;
- while ((c = getopt (argc, argv,
- "abcdefhilnpqtuw0123456789BHNQRTC:D:F:I:L:V:k:r:")) != -1)
- {
- switch (c)
- {
- case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
- case 'h': case 'i': case 'n': case 'p': case 't': case 'u':
- case 'w': case '0': case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9': case 'B':
- case 'H': case 'T': case 'Q':
- (void) sprintf (tmp, " -%c", (char) c);
- (void) strcat (opts, tmp);
- if (c == 'Q')
- {
- quiet = 1;
- really_quiet = 1;
- c = 'q';
- }
- break;
- case 'C': case 'F': case 'I': case 'L': case 'V':
-#ifndef CVS_DIFFDATE
- case 'D':
-#endif
- (void) sprintf (tmp, " -%c%s", (char) c, optarg);
- (void) strcat (opts, tmp);
- break;
- case 'R':
- local = 0;
- break;
- case 'l':
- local = 1;
- break;
- case 'q':
- quiet = 1;
- break;
- case 'k':
- if (options)
- free (options);
- options = RCS_check_kflag (optarg);
- break;
- case 'r':
- if (diff_rev2 != NULL || diff_date2 != NULL)
- error (1, 0,
- "no more than two revisions/dates can be specified");
- if (diff_rev1 != NULL || diff_date1 != NULL)
- diff_rev2 = optarg;
- else
- diff_rev1 = optarg;
- break;
-#ifdef CVS_DIFFDATE
- case 'D':
- if (diff_rev2 != NULL || diff_date2 != NULL)
- error (1, 0,
- "no more than two revisions/dates can be specified");
- if (diff_rev1 != NULL || diff_date1 != NULL)
- diff_date2 = Make_Date (optarg);
- else
- diff_date1 = Make_Date (optarg);
- break;
-#endif
- case 'N':
- empty_files = 1;
- break;
- case '?':
- default:
- usage (diff_usage);
- break;
- }
- }
- argc -= optind;
- argv += optind;
-
- /* make sure options is non-null */
- if (!options)
- options = xstrdup ("");
-
-#ifdef CLIENT_SUPPORT
- if (client_active) {
- /* We're the client side. Fire up the remote server. */
- start_server ();
-
- ign_setup ();
-
- if (local)
- send_arg("-l");
- if (empty_files)
- send_arg("-N");
- send_option_string (opts);
- if (diff_rev1)
- option_with_arg ("-r", diff_rev1);
- if (diff_date1)
- client_senddate (diff_date1);
- if (diff_rev2)
- option_with_arg ("-r", diff_rev2);
- if (diff_date2)
- client_senddate (diff_date2);
-
-#if 0
-/* FIXME: We shouldn't have to send current files to diff two revs, but it
- doesn't work yet and I haven't debugged it. So send the files --
- it's slower but it works. gnu@cygnus.com Apr94 */
-
-/* Idea: often times the changed region of a file is relatively small.
- It would be cool if the client could just divide the file into 4k
- blocks or whatever and send hash values for the blocks. Send hash
- values for blocks aligned with the beginning of the file and the
- end of the file. Then the server can tell how much of the head and
- tail of the file is unchanged. Well, hash collisions will screw
- things up, but MD5 has 128 bits of hash value... */
-
- /* Send the current files unless diffing two revs from the archive */
- if (diff_rev2 == NULL && diff_date2 == NULL)
- send_files (argc, argv, local);
- else
- send_file_names (argc, argv);
-#else
- send_files (argc, argv, local, 0);
-#endif
-
- if (fprintf (to_server, "diff\n") < 0)
- error (1, errno, "writing to server");
- err = get_responses_and_close ();
- free (options);
- return (err);
- }
-#endif
-
- which = W_LOCAL;
- if (diff_rev2 != NULL || diff_date2 != NULL)
- which |= W_REPOS | W_ATTIC;
-
- wrap_setup ();
-
- /* start the recursion processor */
- err = start_recursion (diff_fileproc, diff_filesdoneproc, diff_dirproc,
- diff_dirleaveproc, argc, argv, local,
- which, 0, 1, (char *) NULL, 1, 0);
-
- /* clean up */
- free (options);
- return (err);
-}
-
-/*
- * Do a file diff
- */
-/* ARGSUSED */
-static int
-diff_fileproc (file, update_dir, repository, entries, srcfiles)
- char *file;
- char *update_dir;
- char *repository;
- List *entries;
- List *srcfiles;
-{
- int status, err = 2; /* 2 == trouble, like rcsdiff */
- Vers_TS *vers;
- enum {
- DIFF_ERROR,
- DIFF_ADDED,
- DIFF_REMOVED,
- DIFF_NEITHER
- } empty_file = DIFF_NEITHER;
- char tmp[L_tmpnam+1];
- char *tocvsPath;
- char fname[PATH_MAX];
-
-#ifdef SERVER_SUPPORT
- user_file_rev = 0;
-#endif
- vers = Version_TS (repository, (char *) NULL, (char *) NULL, (char *) NULL,
- file, 1, 0, entries, srcfiles);
-
- if (diff_rev2 != NULL || diff_date2 != NULL)
- {
- /* Skip all the following checks regarding the user file; we're
- not using it. */
- }
- else if (vers->vn_user == NULL)
- {
- error (0, 0, "I know nothing about %s", file);
- freevers_ts (&vers);
- diff_mark_errors (err);
- return (err);
- }
- else if (vers->vn_user[0] == '0' && vers->vn_user[1] == '\0')
- {
- if (empty_files)
- empty_file = DIFF_ADDED;
- else
- {
- error (0, 0, "%s is a new entry, no comparison available", file);
- freevers_ts (&vers);
- diff_mark_errors (err);
- return (err);
- }
- }
- else if (vers->vn_user[0] == '-')
- {
- if (empty_files)
- empty_file = DIFF_REMOVED;
- else
- {
- error (0, 0, "%s was removed, no comparison available", file);
- freevers_ts (&vers);
- diff_mark_errors (err);
- return (err);
- }
- }
- else
- {
- if (vers->vn_rcs == NULL && vers->srcfile == NULL)
- {
- error (0, 0, "cannot find revision control file for %s", file);
- freevers_ts (&vers);
- diff_mark_errors (err);
- return (err);
- }
- else
- {
- if (vers->ts_user == NULL)
- {
- error (0, 0, "cannot find %s", file);
- freevers_ts (&vers);
- diff_mark_errors (err);
- return (err);
- }
-#ifdef SERVER_SUPPORT
- else if (!strcmp (vers->ts_user, vers->ts_rcs))
- {
- /* The user file matches some revision in the repository
- Diff against the repository (for remote CVS, we might not
- have a copy of the user file around). */
- user_file_rev = vers->vn_user;
- }
-#endif
- }
- }
-
- if (empty_file == DIFF_NEITHER && diff_file_nodiff (file, repository, entries, srcfiles, vers))
- {
- freevers_ts (&vers);
- return (0);
- }
-
-#ifdef DEATH_SUPPORT
- /* FIXME: Check whether use_rev1 and use_rev2 are dead and deal
- accordingly. */
-#endif
-
- /* Output an "Index:" line for patch to use */
- (void) fflush (stdout);
- if (update_dir[0])
- (void) printf ("Index: %s/%s\n", update_dir, file);
- else
- (void) printf ("Index: %s\n", file);
- (void) fflush (stdout);
-
- tocvsPath = wrap_tocvs_process_file(file);
- if (tocvsPath)
- {
- /* Backup the current version of the file to CVS/,,filename */
- sprintf(fname,"%s/%s%s",CVSADM, CVSPREFIX, file);
- if (unlink_file_dir (fname) < 0)
- if (! existence_error (errno))
- error (1, errno, "cannot remove %s", file);
- rename_file (file, fname);
- /* Copy the wrapped file to the current directory then go to work */
- copy_file (tocvsPath, file);
- }
-
- if (empty_file == DIFF_ADDED || empty_file == DIFF_REMOVED)
- {
- (void) printf ("===================================================================\nRCS file: %s\n",
- file);
- (void) printf ("diff -N %s\n", file);
-
- if (empty_file == DIFF_ADDED)
- {
- run_setup ("%s %s %s %s", DIFF, opts, DEVNULL, file);
- }
- else
- {
- /*
- * FIXME: Should be setting use_rev1 using the logic in
- * diff_file_nodiff, and using that revision. This code
- * is broken for "cvs diff -N -r foo".
- */
- run_setup ("%s%s -p -q %s -r%s", Rcsbin, RCS_CO,
- *options ? options : vers->options, vers->vn_rcs);
- run_arg (vers->srcfile->path);
- if (run_exec (RUN_TTY, tmpnam (tmp), RUN_TTY, RUN_REALLY) == -1)
- {
- (void) unlink (tmp);
- error (1, errno, "fork failed during checkout of %s",
- vers->srcfile->path);
- }
-
- run_setup ("%s %s %s %s", DIFF, opts, tmp, DEVNULL);
- }
- }
- else
- {
- if (use_rev2)
- {
- run_setup ("%s%s %s %s -r%s -r%s", Rcsbin, RCS_DIFF,
- opts, *options ? options : vers->options,
- use_rev1, use_rev2);
- }
- else
- {
- run_setup ("%s%s %s %s -r%s", Rcsbin, RCS_DIFF, opts,
- *options ? options : vers->options, use_rev1);
- }
- run_arg (vers->srcfile->path);
- }
-
- switch ((status = run_exec (RUN_TTY, RUN_TTY, RUN_TTY,
- RUN_REALLY|RUN_COMBINED)))
- {
- case -1: /* fork failed */
- error (1, errno, "fork failed during rcsdiff of %s",
- vers->srcfile->path);
- case 0: /* everything ok */
- err = 0;
- break;
- default: /* other error */
- err = status;
- break;
- }
-
- if (tocvsPath)
- {
- if (unlink_file_dir (file) < 0)
- if (! existence_error (errno))
- error (1, errno, "cannot remove %s", file);
-
- rename_file (fname,file);
- if (unlink_file (tocvsPath) < 0)
- error (1, errno, "cannot remove %s", file);
- }
-
- if (empty_file == DIFF_REMOVED)
- (void) unlink (tmp);
-
- (void) fflush (stdout);
- freevers_ts (&vers);
- diff_mark_errors (err);
- return (err);
-}
-
-/*
- * Remember the exit status for each file.
- */
-static void
-diff_mark_errors (err)
- int err;
-{
- if (err > diff_errors)
- diff_errors = err;
-}
-
-/*
- * Print a warm fuzzy message when we enter a dir
- *
- * Don't try to diff directories that don't exist! -- DW
- */
-/* ARGSUSED */
-static Dtype
-diff_dirproc (dir, pos_repos, update_dir)
- char *dir;
- char *pos_repos;
- char *update_dir;
-{
- /* XXX - check for dirs we don't want to process??? */
-
- /* YES ... for instance dirs that don't exist!!! -- DW */
- if (!isdir (dir) )
- return (R_SKIP_ALL);
-
- if (!quiet)
- error (0, 0, "Diffing %s", update_dir);
- return (R_PROCESS);
-}
-
-/*
- * Concoct the proper exit status - done with files
- */
-/* ARGSUSED */
-static int
-diff_filesdoneproc (err, repos, update_dir)
- int err;
- char *repos;
- char *update_dir;
-{
- return (diff_errors);
-}
-
-/*
- * Concoct the proper exit status - leaving directories
- */
-/* ARGSUSED */
-static int
-diff_dirleaveproc (dir, err, update_dir)
- char *dir;
- int err;
- char *update_dir;
-{
- return (diff_errors);
-}
-
-/*
- * verify that a file is different 0=same 1=different
- */
-static int
-diff_file_nodiff (file, repository, entries, srcfiles, vers)
- char *file;
- char *repository;
- List *entries;
- List *srcfiles;
- Vers_TS *vers;
-{
- Vers_TS *xvers;
- char tmp[L_tmpnam+1];
-
- /* free up any old use_rev* variables and reset 'em */
- if (use_rev1)
- free (use_rev1);
- if (use_rev2)
- free (use_rev2);
- use_rev1 = use_rev2 = (char *) NULL;
-
- if (diff_rev1 || diff_date1)
- {
- /* special handling for TAG_HEAD */
- if (diff_rev1 && strcmp (diff_rev1, TAG_HEAD) == 0)
- use_rev1 = xstrdup (vers->vn_rcs);
- else
- {
- xvers = Version_TS (repository, (char *) NULL, diff_rev1,
- diff_date1, file, 1, 0, entries, srcfiles);
- if (xvers->vn_rcs == NULL)
- {
- /* Don't gripe if it doesn't exist, just ignore! */
- if (! isfile (file))
- /* null statement */ ;
- else if (diff_rev1)
- error (0, 0, "tag %s is not in file %s", diff_rev1, file);
- else
- error (0, 0, "no revision for date %s in file %s",
- diff_date1, file);
- return (1);
- }
- use_rev1 = xstrdup (xvers->vn_rcs);
- freevers_ts (&xvers);
- }
- }
- if (diff_rev2 || diff_date2)
- {
- /* special handling for TAG_HEAD */
- if (diff_rev2 && strcmp (diff_rev2, TAG_HEAD) == 0)
- use_rev2 = xstrdup (vers->vn_rcs);
- else
- {
- xvers = Version_TS (repository, (char *) NULL, diff_rev2,
- diff_date2, file, 1, 0, entries, srcfiles);
- if (xvers->vn_rcs == NULL)
- {
- /* Don't gripe if it doesn't exist, just ignore! */
- if (! isfile (file))
- /* null statement */ ;
- else if (diff_rev1)
- error (0, 0, "tag %s is not in file %s", diff_rev2, file);
- else
- error (0, 0, "no revision for date %s in file %s",
- diff_date2, file);
- return (1);
- }
- use_rev2 = xstrdup (xvers->vn_rcs);
- freevers_ts (&xvers);
- }
-
- /* now, see if we really need to do the diff */
- if (use_rev1 && use_rev2) {
- return (strcmp (use_rev1, use_rev2) == 0);
- } else {
- error(0, 0, "No HEAD revision for file %s", file);
- return (1);
- }
- }
-#ifdef SERVER_SUPPORT
- if (user_file_rev)
- {
- /* drop user_file_rev into first unused use_rev */
- if (!use_rev1)
- use_rev1 = xstrdup (user_file_rev);
- else if (!use_rev2)
- use_rev2 = xstrdup (user_file_rev);
- /* and if not, it wasn't needed anyhow */
- user_file_rev = 0;
- }
-
- /* now, see if we really need to do the diff */
- if (use_rev1 && use_rev2)
- {
- return (strcmp (use_rev1, use_rev2) == 0);
- }
-#endif /* SERVER_SUPPORT */
- if (use_rev1 == NULL || strcmp (use_rev1, vers->vn_user) == 0)
- {
- if (strcmp (vers->ts_rcs, vers->ts_user) == 0 &&
- (!(*options) || strcmp (options, vers->options) == 0))
- {
- return (1);
- }
- if (use_rev1 == NULL)
- use_rev1 = xstrdup (vers->vn_user);
- }
-
- /*
- * with 0 or 1 -r option specified, run a quick diff to see if we
- * should bother with it at all.
- */
- run_setup ("%s%s -p -q %s -r%s", Rcsbin, RCS_CO,
- *options ? options : vers->options, use_rev1);
- run_arg (vers->srcfile->path);
- switch (run_exec (RUN_TTY, tmpnam (tmp), RUN_TTY, RUN_REALLY))
- {
- case 0: /* everything ok */
- if (xcmp (file, tmp) == 0)
- {
- (void) unlink (tmp);
- return (1);
- }
- break;
- case -1: /* fork failed */
- (void) unlink (tmp);
- error (1, errno, "fork failed during checkout of %s",
- vers->srcfile->path);
- default:
- break;
- }
- (void) unlink (tmp);
- return (0);
-}
diff --git a/gnu/usr.bin/cvs/cvs/entries.c b/gnu/usr.bin/cvs/cvs/entries.c
deleted file mode 100644
index 7ae3e5827fd8..000000000000
--- a/gnu/usr.bin/cvs/cvs/entries.c
+++ /dev/null
@@ -1,555 +0,0 @@
-/*
- * Copyright (c) 1992, Brian Berliner and Jeff Polk
- * Copyright (c) 1989-1992, Brian Berliner
- *
- * You may distribute under the terms of the GNU General Public License as
- * specified in the README file that comes with the CVS 1.4 kit.
- *
- * Entries file to Files file
- *
- * Creates the file Files containing the names that comprise the project, from
- * the Entries file.
- */
-
-#include "cvs.h"
-#include "getline.h"
-
-#ifndef lint
-static const char rcsid[] = "$CVSid: @(#)entries.c 1.44 94/10/07 $";
-USE(rcsid);
-#endif
-
-static Node *AddEntryNode PROTO((List * list, Entnode *entnode));
-
-static Entnode *fgetentent PROTO((FILE *));
-static int fputentent PROTO((FILE *, Entnode *));
-
-static FILE *entfile;
-static char *entfilename; /* for error messages */
-
-/*
- * Construct an Entnode
- */
-Entnode *
-Entnode_Create(user, vn, ts, options, tag, date, ts_conflict)
- const char *user;
- const char *vn;
- const char *ts;
- const char *options;
- const char *tag;
- const char *date;
- const char *ts_conflict;
-{
- Entnode *ent;
-
- /* Note that timestamp and options must be non-NULL */
- ent = (Entnode *) xmalloc (sizeof (Entnode));
- ent->user = xstrdup (user);
- ent->version = xstrdup (vn);
- ent->timestamp = xstrdup (ts ? ts : "");
- ent->options = xstrdup (options ? options : "");
- ent->tag = xstrdup (tag);
- ent->date = xstrdup (date);
- ent->conflict = xstrdup (ts_conflict);
-
- return ent;
-}
-
-/*
- * Destruct an Entnode
- */
-void
-Entnode_Destroy (ent)
- Entnode *ent;
-{
- free (ent->user);
- free (ent->version);
- free (ent->timestamp);
- free (ent->options);
- if (ent->tag)
- free (ent->tag);
- if (ent->date)
- free (ent->date);
- if (ent->conflict)
- free (ent->conflict);
- free (ent);
-}
-
-/*
- * Write out the line associated with a node of an entries file
- */
-static int write_ent_proc PROTO ((Node *, void *));
-static int
-write_ent_proc (node, closure)
- Node *node;
- void *closure;
-{
- if (fputentent(entfile, (Entnode *) node->data))
- error (1, errno, "cannot write %s", entfilename);
-
- return (0);
-}
-
-/*
- * write out the current entries file given a list, making a backup copy
- * first of course
- */
-static void
-write_entries (list)
- List *list;
-{
- /* open the new one and walk the list writing entries */
- entfilename = CVSADM_ENTBAK;
- entfile = open_file (entfilename, "w+");
- (void) walklist (list, write_ent_proc, NULL);
- if (fclose (entfile) == EOF)
- error (1, errno, "error closing %s", entfilename);
-
- /* now, atomically (on systems that support it) rename it */
- rename_file (entfilename, CVSADM_ENT);
-
- /* now, remove the log file */
- unlink_file (CVSADM_ENTLOG);
-}
-
-/*
- * Removes the argument file from the Entries file if necessary.
- */
-void
-Scratch_Entry (list, fname)
- List *list;
- char *fname;
-{
- Node *node;
-
- if (trace)
-#ifdef SERVER_SUPPORT
- (void) fprintf (stderr, "%c-> Scratch_Entry(%s)\n",
- (server_active) ? 'S' : ' ', fname);
-#else
- (void) fprintf (stderr, "-> Scratch_Entry(%s)\n", fname);
-#endif
-
- /* hashlookup to see if it is there */
- if ((node = findnode (list, fname)) != NULL)
- {
- delnode (node); /* delete the node */
-#ifdef SERVER_SUPPORT
- if (server_active)
- server_scratch (fname);
-#endif
- if (!noexec)
- write_entries (list); /* re-write the file */
- }
-}
-
-/*
- * Enters the given file name/version/time-stamp into the Entries file,
- * removing the old entry first, if necessary.
- */
-void
-Register (list, fname, vn, ts, options, tag, date, ts_conflict)
- List *list;
- char *fname;
- char *vn;
- char *ts;
- char *options;
- char *tag;
- char *date;
- char *ts_conflict;
-{
- Entnode *entnode;
- Node *node;
-
-#ifdef SERVER_SUPPORT
- if (server_active)
- {
- server_register (fname, vn, ts, options, tag, date, ts_conflict);
- }
-#endif
-
- if (trace)
- {
-#ifdef SERVER_SUPPORT
- (void) fprintf (stderr, "%c-> Register(%s, %s, %s%s%s, %s, %s %s)\n",
- (server_active) ? 'S' : ' ',
- fname, vn, ts ? ts : "",
- ts_conflict ? "+" : "", ts_conflict ? ts_conflict : "",
- options, tag ? tag : "", date ? date : "");
-#else
- (void) fprintf (stderr, "-> Register(%s, %s, %s%s%s, %s, %s %s)\n",
- fname, vn, ts ? ts : "",
- ts_conflict ? "+" : "", ts_conflict ? ts_conflict : "",
- options, tag ? tag : "", date ? date : "");
-#endif
- }
-
- entnode = Entnode_Create(fname, vn, ts, options, tag, date, ts_conflict);
- node = AddEntryNode (list, entnode);
-
- if (!noexec)
- {
- entfile = open_file (CVSADM_ENTLOG, "a");
-
- write_ent_proc (node, NULL);
-
- if (fclose (entfile) == EOF)
- error (1, errno, "error closing %s", CVSADM_ENTLOG);
- }
-}
-
-/*
- * Node delete procedure for list-private sticky dir tag/date info
- */
-static void
-freesdt (p)
- Node *p;
-{
- struct stickydirtag *sdtp;
-
- sdtp = (struct stickydirtag *) p->data;
- if (sdtp->tag)
- free (sdtp->tag);
- if (sdtp->date)
- free (sdtp->date);
- if (sdtp->options)
- free (sdtp->options);
- free ((char *) sdtp);
-}
-
-static Entnode *
-fgetentent(fpin)
- FILE *fpin;
-{
- Entnode *ent;
- char *line;
- size_t line_chars_allocated;
- register char *cp;
- char *user, *vn, *ts, *options;
- char *tag_or_date, *tag, *date, *ts_conflict;
-
- line = NULL;
- line_chars_allocated = 0;
-
- ent = NULL;
- while (getline (&line, &line_chars_allocated, fpin) > 0)
- {
- if (line[0] != '/')
- continue;
-
- user = line + 1;
- if ((cp = strchr (user, '/')) == NULL)
- continue;
- *cp++ = '\0';
- vn = cp;
- if ((cp = strchr (vn, '/')) == NULL)
- continue;
- *cp++ = '\0';
- ts = cp;
- if ((cp = strchr (ts, '/')) == NULL)
- continue;
- *cp++ = '\0';
- options = cp;
- if ((cp = strchr (options, '/')) == NULL)
- continue;
- *cp++ = '\0';
- tag_or_date = cp;
- if ((cp = strchr (tag_or_date, '\n')) == NULL)
- continue;
- *cp = '\0';
- tag = (char *) NULL;
- date = (char *) NULL;
- if (*tag_or_date == 'T')
- tag = tag_or_date + 1;
- else if (*tag_or_date == 'D')
- date = tag_or_date + 1;
-
- if ((ts_conflict = strchr (ts, '+')))
- *ts_conflict++ = '\0';
-
- /*
- * XXX - Convert timestamp from old format to new format.
- *
- * If the timestamp doesn't match the file's current
- * mtime, we'd have to generate a string that doesn't
- * match anyways, so cheat and base it on the existing
- * string; it doesn't have to match the same mod time.
- *
- * For an unmodified file, write the correct timestamp.
- */
- {
- struct stat sb;
- if (strlen (ts) > 30 && stat (user, &sb) == 0)
- {
- char *c = ctime (&sb.st_mtime);
-
- if (!strncmp (ts + 25, c, 24))
- ts = time_stamp (user);
- else
- {
- ts += 24;
- ts[0] = '*';
- }
- }
- }
-
- ent = Entnode_Create(user, vn, ts, options, tag, date, ts_conflict);
- break;
- }
-
- free (line);
- return ent;
-}
-
-static int
-fputentent(fp, p)
- FILE *fp;
- Entnode *p;
-{
- if (fprintf (fp, "/%s/%s/%s", p->user, p->version, p->timestamp) < 0)
- return 1;
- if (p->conflict)
- {
- if (fprintf (fp, "+%s", p->conflict) < 0)
- return 1;
- }
- if (fprintf (fp, "/%s/", p->options) < 0)
- return 1;
-
- if (p->tag)
- {
- if (fprintf (fp, "T%s\n", p->tag) < 0)
- return 1;
- }
- else if (p->date)
- {
- if (fprintf (fp, "D%s\n", p->date) < 0)
- return 1;
- }
- else
- {
- if (fprintf (fp, "\n") < 0)
- return 1;
- }
-
- return 0;
-}
-
-
-/*
- * Read the entries file into a list, hashing on the file name.
- */
-List *
-Entries_Open (aflag)
- int aflag;
-{
- List *entries;
- Entnode *ent;
- char *dirtag, *dirdate;
- int do_rewrite = 0;
- FILE *fpin;
-
- /* get a fresh list... */
- entries = getlist ();
-
- /*
- * Parse the CVS/Tag file, to get any default tag/date settings. Use
- * list-private storage to tuck them away for Version_TS().
- */
- ParseTag (&dirtag, &dirdate);
- if (aflag || dirtag || dirdate)
- {
- struct stickydirtag *sdtp;
-
- sdtp = (struct stickydirtag *) xmalloc (sizeof (*sdtp));
- memset ((char *) sdtp, 0, sizeof (*sdtp));
- sdtp->aflag = aflag;
- sdtp->tag = xstrdup (dirtag);
- sdtp->date = xstrdup (dirdate);
-
- /* feed it into the list-private area */
- entries->list->data = (char *) sdtp;
- entries->list->delproc = freesdt;
- }
-
- fpin = fopen (CVSADM_ENT, "r");
- if (fpin == NULL)
- error (0, errno, "cannot open %s for reading", CVSADM_ENT);
- else
- {
- while ((ent = fgetentent (fpin)) != NULL)
- {
- (void) AddEntryNode (entries, ent);
- }
-
- fclose (fpin);
- }
-
- fpin = fopen (CVSADM_ENTLOG, "r");
- if (fpin != NULL)
- {
- while ((ent = fgetentent (fpin)) != NULL)
- {
- (void) AddEntryNode (entries, ent);
- }
- do_rewrite = 1;
- fclose (fpin);
- }
-
- if (do_rewrite && !noexec)
- write_entries (entries);
-
- /* clean up and return */
- if (fpin)
- (void) fclose (fpin);
- if (dirtag)
- free (dirtag);
- if (dirdate)
- free (dirdate);
- return (entries);
-}
-
-void
-Entries_Close(list)
- List *list;
-{
- if (list)
- {
- if (!noexec)
- {
- if (isfile (CVSADM_ENTLOG))
- write_entries (list);
- }
- dellist(&list);
- }
-}
-
-
-/*
- * Free up the memory associated with the data section of an ENTRIES type
- * node
- */
-static void
-Entries_delproc (node)
- Node *node;
-{
- Entnode *p;
-
- p = (Entnode *) node->data;
- Entnode_Destroy(p);
-}
-
-/*
- * Get an Entries file list node, initialize it, and add it to the specified
- * list
- */
-static Node *
-AddEntryNode (list, entdata)
- List *list;
- Entnode *entdata;
-{
- Node *p;
-
- /* was it already there? */
- if ((p = findnode (list, entdata->user)) != NULL)
- {
- /* take it out */
- delnode (p);
- }
-
- /* get a node and fill in the regular stuff */
- p = getnode ();
- p->type = ENTRIES;
- p->delproc = Entries_delproc;
-
- /* this one gets a key of the name for hashing */
- /* FIXME This results in duplicated data --- the hash package shouldn't
- assume that the key is dynamically allocated. The user's free proc
- should be responsible for freeing the key. */
- p->key = xstrdup (entdata->user);
- p->data = (char *) entdata;
-
- /* put the node into the list */
- addnode (list, p);
- return (p);
-}
-
-/*
- * Write out/Clear the CVS/Tag file.
- */
-void
-WriteTag (dir, tag, date)
- char *dir;
- char *tag;
- char *date;
-{
- FILE *fout;
- char tmp[PATH_MAX];
-
- if (noexec)
- return;
-
- if (dir == NULL)
- (void) strcpy (tmp, CVSADM_TAG);
- else
- (void) sprintf (tmp, "%s/%s", dir, CVSADM_TAG);
-
- if (tag || date)
- {
- fout = open_file (tmp, "w+");
- if (tag)
- {
- if (fprintf (fout, "T%s\n", tag) < 0)
- error (1, errno, "write to %s failed", tmp);
- }
- else
- {
- if (fprintf (fout, "D%s\n", date) < 0)
- error (1, errno, "write to %s failed", tmp);
- }
- if (fclose (fout) == EOF)
- error (1, errno, "cannot close %s", tmp);
- }
- else
- if (unlink_file (tmp) < 0 && ! existence_error (errno))
- error (1, errno, "cannot remove %s", tmp);
-}
-
-/*
- * Parse the CVS/Tag file for the current directory.
- */
-void
-ParseTag (tagp, datep)
- char **tagp;
- char **datep;
-{
- FILE *fp;
-
- if (tagp)
- *tagp = (char *) NULL;
- if (datep)
- *datep = (char *) NULL;
- fp = fopen (CVSADM_TAG, "r");
- if (fp)
- {
- char *line;
- int line_length;
- size_t line_chars_allocated;
-
- line = NULL;
- line_chars_allocated = 0;
-
- if ((line_length = getline (&line, &line_chars_allocated, fp)) > 0)
- {
- /* Remove any trailing newline. */
- if (line[line_length - 1] == '\n')
- line[--line_length] = '\0';
- if (*line == 'T' && tagp)
- *tagp = xstrdup (line + 1);
- else if (*line == 'D' && datep)
- *datep = xstrdup (line + 1);
- }
- (void) fclose (fp);
- free (line);
- }
-}
diff --git a/gnu/usr.bin/cvs/cvs/expand_path.c b/gnu/usr.bin/cvs/cvs/expand_path.c
deleted file mode 100644
index 7cc939fa269f..000000000000
--- a/gnu/usr.bin/cvs/cvs/expand_path.c
+++ /dev/null
@@ -1,139 +0,0 @@
-/* expand_path.c -- expand environmental variables in passed in string
- The main routine is expand_pathname, it is the routine
- that handles the '~' character in four forms:
- ~name
- ~name/
- ~/
- ~
- and handles environment variables contained within the pathname
- which are defined by:
- c is some character
- ${var_name} var_name is the name of the environ variable
- $var_name var_name ends with a non ascii character
- char *expand_pathname(char *name)
- This routine will expand the pathname to account for ~
- and $ characters as described above.If an error occurs, NULL
- is returned.
- Will only expand Built in CVS variables all others are ignored.
- */
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-#include "cvs.h"
-#include <stdio.h>
-#include <ctype.h>
-#include <sys/types.h>
-#if HAVE_STRING_H
-#include <string.h>
-#else
-#include <strings.h>
-#endif
-static char *expand_variable PROTO((char *env));
-extern char *xmalloc ();
-extern void free ();
-char *
-expand_path (name)
- char *name;
-{
- char *s;
- char *d;
- char mybuf[PATH_MAX];
- char buf[PATH_MAX];
- char *result;
- s = name;
- d = mybuf;
- while ((*d++ = *s))
- if (*s++ == '$')
- {
- char *p = d;
- char *e;
- int flag = (*s == '{');
-
- for (; (*d++ = *s); s++)
- if (flag ? *s =='}' :
- isalnum (*s) == 0 && *s!='_' )
- break;
- *--d = 0;
- e = expand_variable (&p[flag]);
-
- if (e)
- {
- for (d = &p[-1]; (*d++ = *e++);)
- ;
- --d;
- if (flag && *s)
- s++;
- }
- else
- return NULL; /* no env variable */
- }
- *d = 0;
- s = mybuf;
- d = buf;
- /* If you don't want ~username ~/ to be expanded simply remove
- * This entire if statement including the else portion
- */
- if (*s++ == '~')
- {
- char *t;
- char *p=s;
- if (*s=='/' || *s==0)
- t = getenv ("HOME");
- else
- {
- struct passwd *ps;
- for (; *p!='/' && *p; p++)
- ;
- *p = 0;
- ps = getpwnam (s);
- if (ps == 0)
- return NULL; /* no such user */
- t = ps->pw_dir;
- }
- while ((*d++ = *t++))
- ;
- --d;
- if (*p == 0)
- *p = '/'; /* always add / */
- s=p;
- }
- else
- --s;
- /* Kill up to here */
- while ((*d++ = *s++))
- ;
- *d=0;
- result = xmalloc (sizeof(char) * strlen(buf)+1);
- strcpy (result, buf);
- return result;
-}
-static char *
-expand_variable (name)
- char *name;
-{
- /* There is nothing expanding this function to allow it
- * to read a file in the $CVSROOT/CVSROOT directory that
- * says which environmental variables could be expanded
- * or just say everything is fair game to be expanded
- */
- if ( strcmp (name, CVSROOT_ENV) == 0 )
- return CVSroot;
- else
- if ( strcmp (name, RCSBIN_ENV) == 0 )
- return Rcsbin;
- else
- if ( strcmp (name, EDITOR1_ENV) == 0 )
- return Editor;
- else
- if ( strcmp (name, EDITOR2_ENV) == 0 )
- return Editor;
- else
- if ( strcmp (name, EDITOR3_ENV) == 0 )
- return Editor;
- else
- return NULL;
- /* The code here could also just
- * return whatever getenv would
- * return.
- */
-}
diff --git a/gnu/usr.bin/cvs/cvs/find_names.c b/gnu/usr.bin/cvs/cvs/find_names.c
deleted file mode 100644
index 82959b5754b9..000000000000
--- a/gnu/usr.bin/cvs/cvs/find_names.c
+++ /dev/null
@@ -1,275 +0,0 @@
-/*
- * Copyright (c) 1992, Brian Berliner and Jeff Polk
- * Copyright (c) 1989-1992, Brian Berliner
- *
- * You may distribute under the terms of the GNU General Public License as
- * specified in the README file that comes with the CVS 1.4 kit.
- *
- * Find Names
- *
- * Finds all the pertinent file names, both from the administration and from the
- * repository
- *
- * Find Dirs
- *
- * Finds all pertinent sub-directories of the checked out instantiation and the
- * repository (and optionally the attic)
- */
-
-#include "cvs.h"
-
-#ifndef lint
-static const char rcsid[] = "$CVSid: @(#)find_names.c 1.45 94/10/22 $";
-USE(rcsid);
-#endif
-
-static int find_dirs PROTO((char *dir, List * list, int checkadm));
-static int find_rcs PROTO((char *dir, List * list));
-
-static List *filelist;
-
-/*
- * add the key from entry on entries list to the files list
- */
-static int add_entries_proc PROTO((Node *, void *));
-static int
-add_entries_proc (node, closure)
- Node *node;
- void *closure;
-{
- Node *fnode;
-
- fnode = getnode ();
- fnode->type = FILES;
- fnode->key = xstrdup (node->key);
- if (addnode (filelist, fnode) != 0)
- freenode (fnode);
- return (0);
-}
-
-/*
- * compare two files list node (for sort)
- */
-static int fsortcmp PROTO ((const Node *, const Node *));
-static int
-fsortcmp (p, q)
- const Node *p;
- const Node *q;
-{
- return (strcmp (p->key, q->key));
-}
-
-List *
-Find_Names (repository, which, aflag, optentries)
- char *repository;
- int which;
- int aflag;
- List **optentries;
-{
- List *entries;
- List *files;
- char dir[PATH_MAX];
-
- /* make a list for the files */
- files = filelist = getlist ();
-
- /* look at entries (if necessary) */
- if (which & W_LOCAL)
- {
- /* parse the entries file (if it exists) */
- entries = Entries_Open (aflag);
- if (entries != NULL)
- {
- /* walk the entries file adding elements to the files list */
- (void) walklist (entries, add_entries_proc, NULL);
-
- /* if our caller wanted the entries list, return it; else free it */
- if (optentries != NULL)
- *optentries = entries;
- else
- Entries_Close (entries);
- }
- }
-
- if ((which & W_REPOS) && repository && !isreadable (CVSADM_ENTSTAT))
- {
- /* search the repository */
- if (find_rcs (repository, files) != 0)
- error (1, errno, "cannot open directory %s", repository);
-
- /* search the attic too */
- if (which & W_ATTIC)
- {
- (void) sprintf (dir, "%s/%s", repository, CVSATTIC);
- (void) find_rcs (dir, files);
- }
- }
-
- /* sort the list into alphabetical order and return it */
- sortlist (files, fsortcmp);
- return (files);
-}
-
-/*
- * create a list of directories to traverse from the current directory
- */
-List *
-Find_Dirs (repository, which)
- char *repository;
- int which;
-{
- List *dirlist;
-
- /* make a list for the directories */
- dirlist = getlist ();
-
- /* find the local ones */
- if (which & W_LOCAL)
- {
- /* look only for CVS controlled sub-directories */
- if (find_dirs (".", dirlist, 1) != 0)
- error (1, errno, "cannot open current directory");
- }
-
- /* look for sub-dirs in the repository */
- if ((which & W_REPOS) && repository)
- {
- /* search the repository */
- if (find_dirs (repository, dirlist, 0) != 0)
- error (1, errno, "cannot open directory %s", repository);
-
-#ifdef ATTIC_DIR_SUPPORT /* XXX - FIXME */
- /* search the attic too */
- if (which & W_ATTIC)
- {
- char dir[PATH_MAX];
-
- (void) sprintf (dir, "%s/%s", repository, CVSATTIC);
- (void) find_dirs (dir, dirlist, 0);
- }
-#endif
- }
-
- /* sort the list into alphabetical order and return it */
- sortlist (dirlist, fsortcmp);
- return (dirlist);
-}
-
-/*
- * Finds all the ,v files in the argument directory, and adds them to the
- * files list. Returns 0 for success and non-zero if the argument directory
- * cannot be opened.
- */
-static int
-find_rcs (dir, list)
- char *dir;
- List *list;
-{
- Node *p;
- struct dirent *dp;
- DIR *dirp;
-
- /* set up to read the dir */
- if ((dirp = opendir (dir)) == NULL)
- return (1);
-
- /* read the dir, grabbing the ,v files */
- while ((dp = readdir (dirp)) != NULL)
- {
- if (fnmatch (RCSPAT, dp->d_name, 0) == 0)
- {
- char *comma;
-
- comma = strrchr (dp->d_name, ','); /* strip the ,v */
- *comma = '\0';
- p = getnode ();
- p->type = FILES;
- p->key = xstrdup (dp->d_name);
- if (addnode (list, p) != 0)
- freenode (p);
- }
- }
- (void) closedir (dirp);
- return (0);
-}
-
-/*
- * Finds all the subdirectories of the argument dir and adds them to the
- * specified list. Sub-directories without a CVS administration directory
- * are optionally ignored Returns 0 for success or 1 on error.
- */
-static int
-find_dirs (dir, list, checkadm)
- char *dir;
- List *list;
- int checkadm;
-{
- Node *p;
- char tmp[PATH_MAX];
- struct dirent *dp;
- DIR *dirp;
-
- /* set up to read the dir */
- if ((dirp = opendir (dir)) == NULL)
- return (1);
-
- /* read the dir, grabbing sub-dirs */
- while ((dp = readdir (dirp)) != NULL)
- {
- if (strcmp (dp->d_name, ".") == 0 ||
- strcmp (dp->d_name, "..") == 0 ||
- strcmp (dp->d_name, CVSATTIC) == 0 ||
- strcmp (dp->d_name, CVSLCK) == 0)
- continue;
-
-#ifdef DT_DIR
- if (dp->d_type != DT_DIR)
- {
- if (dp->d_type != DT_UNKNOWN && dp->d_type != DT_LNK)
- continue;
-#endif
- /* don't bother stating ,v files */
- if (fnmatch (RCSPAT, dp->d_name, 0) == 0)
- continue;
-
- sprintf (tmp, "%s/%s", dir, dp->d_name);
- if (!isdir (tmp))
- continue;
-
-#ifdef DT_DIR
- }
-#endif
-
- /* check for administration directories (if needed) */
- if (checkadm)
- {
- /* blow off symbolic links to dirs in local dir */
-#ifdef DT_DIR
- if (dp->d_type != DT_DIR)
- {
- /* we're either unknown or a symlink at this point */
- if (dp->d_type == DT_LNK)
- continue;
-#endif
- if (islink (tmp))
- continue;
-#ifdef DT_DIR
- }
-#endif
-
- /* check for new style */
- (void) sprintf (tmp, "%s/%s/%s", dir, dp->d_name, CVSADM);
- if (!isdir (tmp))
- continue;
- }
-
- /* put it in the list */
- p = getnode ();
- p->type = DIRS;
- p->key = xstrdup (dp->d_name);
- if (addnode (list, p) != 0)
- freenode (p);
- }
- (void) closedir (dirp);
- return (0);
-}
diff --git a/gnu/usr.bin/cvs/cvs/history.c b/gnu/usr.bin/cvs/cvs/history.c
deleted file mode 100644
index 7a40b7bd8bd0..000000000000
--- a/gnu/usr.bin/cvs/cvs/history.c
+++ /dev/null
@@ -1,1489 +0,0 @@
-/*
- *
- * You may distribute under the terms of the GNU General Public License
- * as specified in the README file that comes with the CVS 1.0 kit.
- *
- * **************** History of Users and Module ****************
- *
- * LOGGING: Append record to "${CVSROOT}/CVSROOTADM/CVSROOTADM_HISTORY".
- *
- * On For each Tag, Add, Checkout, Commit, Update or Release command,
- * one line of text is written to a History log.
- *
- * X date | user | CurDir | special | rev(s) | argument '\n'
- *
- * where: [The spaces in the example line above are not in the history file.]
- *
- * X is a single character showing the type of event:
- * T "Tag" cmd.
- * O "Checkout" cmd.
- * F "Release" cmd.
- * W "Update" cmd - No User file, Remove from Entries file.
- * U "Update" cmd - File was checked out over User file.
- * G "Update" cmd - File was merged successfully.
- * C "Update" cmd - File was merged and shows overlaps.
- * M "Commit" cmd - "Modified" file.
- * A "Commit" cmd - "Added" file.
- * R "Commit" cmd - "Removed" file.
- *
- * date is a fixed length 8-char hex representation of a Unix time_t.
- * [Starting here, variable fields are delimited by '|' chars.]
- *
- * user is the username of the person who typed the command.
- *
- * CurDir The directory where the action occurred. This should be the
- * absolute path of the directory which is at the same level as
- * the "Repository" field (for W,U,G,C & M,A,R).
- *
- * Repository For record types [W,U,G,C,M,A,R] this field holds the
- * repository read from the administrative data where the
- * command was typed.
- * T "A" --> New Tag, "D" --> Delete Tag
- * Otherwise it is the Tag or Date to modify.
- * O,F A "" (null field)
- *
- * rev(s) Revision number or tag.
- * T The Tag to apply.
- * O The Tag or Date, if specified, else "" (null field).
- * F "" (null field)
- * W The Tag or Date, if specified, else "" (null field).
- * U The Revision checked out over the User file.
- * G,C The Revision(s) involved in merge.
- * M,A,R RCS Revision affected.
- *
- * argument The module (for [TOUF]) or file (for [WUGCMAR]) affected.
- *
- *
- *** Report categories: "User" and "Since" modifiers apply to all reports.
- * [For "sort" ordering see the "sort_order" routine.]
- *
- * Extract list of record types
- *
- * -e, -x [TOFWUGCMAR]
- *
- * Extracted records are simply printed, No analysis is performed.
- * All "field" modifiers apply. -e chooses all types.
- *
- * Checked 'O'ut modules
- *
- * -o, -w
- * Checked out modules. 'F' and 'O' records are examined and if
- * the last record for a repository/file is an 'O', a line is
- * printed. "-w" forces the "working dir" to be used in the
- * comparison instead of the repository.
- *
- * Committed (Modified) files
- *
- * -c, -l, -w
- * All 'M'odified, 'A'dded and 'R'emoved records are examined.
- * "Field" modifiers apply. -l forces a sort by file within user
- * and shows only the last modifier. -w works as in Checkout.
- *
- * Warning: Be careful with what you infer from the output of
- * "cvs hi -c -l". It means the last time *you*
- * changed the file, not the list of files for which
- * you were the last changer!!!
- *
- * Module history for named modules.
- * -m module, -l
- *
- * This is special. If one or more modules are specified, the
- * module names are remembered and the files making up the
- * modules are remembered. Only records matching exactly those
- * files and repositories are shown. Sorting by "module", then
- * filename, is implied. If -l ("last modified") is specified,
- * then "update" records (types WUCG), tag and release records
- * are ignored and the last (by date) "modified" record.
- *
- * TAG history
- *
- * -T All Tag records are displayed.
- *
- *** Modifiers.
- *
- * Since ... [All records contain a timestamp, so any report
- * category can be limited by date.]
- *
- * -D date - The "date" is parsed into a Unix "time_t" and
- * records with an earlier time stamp are ignored.
- * -r rev/tag - A "rev" begins with a digit. A "tag" does not. If
- * you use this option, every file is searched for the
- * indicated rev/tag.
- * -t tag - The "tag" is searched for in the history file and no
- * record is displayed before the tag is found. An
- * error is printed if the tag is never found.
- * -b string - Records are printed only back to the last reference
- * to the string in the "module", "file" or
- * "repository" fields.
- *
- * Field Selections [Simple comparisons on existing fields. All field
- * selections are repeatable.]
- *
- * -a - All users.
- * -u user - If no user is given and '-a' is not given, only
- * records for the user typing the command are shown.
- * ==> If -a or -u is not specified, just use "self".
- *
- * -f filematch - Only records in which the "file" field contains the
- * string "filematch" are considered.
- *
- * -p repository - Only records in which the "repository" string is a
- * prefix of the "repos" field are considered.
- *
- * -m modulename - Only records which contain "modulename" in the
- * "module" field are considered.
- *
- *
- * EXAMPLES: ("cvs history", "cvs his" or "cvs hi")
- *
- *** Checked out files for username. (default self, e.g. "dgg")
- * cvs hi [equivalent to: "cvs hi -o -u dgg"]
- * cvs hi -u user [equivalent to: "cvs hi -o -u user"]
- * cvs hi -o [equivalent to: "cvs hi -o -u dgg"]
- *
- *** Committed (modified) files from the beginning of the file.
- * cvs hi -c [-u user]
- *
- *** Committed (modified) files since Midnight, January 1, 1990:
- * cvs hi -c -D 'Jan 1 1990' [-u user]
- *
- *** Committed (modified) files since tag "TAG" was stored in the history file:
- * cvs hi -c -t TAG [-u user]
- *
- *** Committed (modified) files since tag "TAG" was placed on the files:
- * cvs hi -c -r TAG [-u user]
- *
- *** Who last committed file/repository X?
- * cvs hi -c -l -[fp] X
- *
- *** Modified files since tag/date/file/repos?
- * cvs hi -c {-r TAG | -D Date | -b string}
- *
- *** Tag history
- * cvs hi -T
- *
- *** History of file/repository/module X.
- * cvs hi -[fpn] X
- *
- *** History of user "user".
- * cvs hi -e -u user
- *
- *** Dump (eXtract) specified record types
- * cvs hi -x [TOFWUGCMAR]
- *
- *
- * FUTURE: J[Join], I[Import] (Not currently implemented.)
- *
- */
-
-#include "cvs.h"
-
-#ifndef lint
-static const char rcsid[] = "$CVSid: @(#)history.c 1.33 94/09/21 $";
-USE(rcsid);
-#endif
-
-static struct hrec
-{
- char *type; /* Type of record (In history record) */
- char *user; /* Username (In history record) */
- char *dir; /* "Compressed" Working dir (In history record) */
- char *repos; /* (Tag is special.) Repository (In history record) */
- char *rev; /* Revision affected (In history record) */
- char *file; /* Filename (In history record) */
- char *end; /* Ptr into repository to copy at end of workdir */
- char *mod; /* The module within which the file is contained */
- time_t date; /* Calculated from date stored in record */
- int idx; /* Index of record, for "stable" sort. */
-} *hrec_head;
-
-
-static char *fill_hrec PROTO((char *line, struct hrec * hr));
-static int accept_hrec PROTO((struct hrec * hr, struct hrec * lr));
-static int select_hrec PROTO((struct hrec * hr));
-static int sort_order PROTO((const PTR l, const PTR r));
-static int within PROTO((char *find, char *string));
-static time_t date_and_time PROTO((char *date_str));
-static void expand_modules PROTO((void));
-static void read_hrecs PROTO((char *fname));
-static void report_hrecs PROTO((void));
-static void save_file PROTO((char *dir, char *name, char *module));
-static void save_module PROTO((char *module));
-static void save_user PROTO((char *name));
-
-#define ALL_REC_TYPES "TOFWUCGMAR"
-#define USER_INCREMENT 2
-#define FILE_INCREMENT 128
-#define MODULE_INCREMENT 5
-#define HREC_INCREMENT 128
-
-static short report_count;
-
-static short extract;
-static short v_checkout;
-static short modified;
-static short tag_report;
-static short module_report;
-static short working;
-static short last_entry;
-static short all_users;
-
-static short user_sort;
-static short repos_sort;
-static short file_sort;
-static short module_sort;
-
-#ifdef HAVE_RCS5
-static short tz_local;
-static time_t tz_seconds_east_of_GMT;
-static char *tz_name = "+0000";
-#else
-static char tz_name[] = "LT";
-#endif
-
-static time_t since_date;
-static char since_rev[20]; /* Maxrev ~= 99.99.99.999 */
-static char since_tag[64];
-static struct hrec *last_since_tag;
-static char backto[128];
-static struct hrec *last_backto;
-static char rec_types[20];
-
-static int hrec_count;
-static int hrec_max;
-
-static char **user_list; /* Ptr to array of ptrs to user names */
-static int user_max; /* Number of elements allocated */
-static int user_count; /* Number of elements used */
-
-static struct file_list_str
-{
- char *l_file;
- char *l_module;
-} *file_list; /* Ptr to array file name structs */
-static int file_max; /* Number of elements allocated */
-static int file_count; /* Number of elements used */
-
-static char **mod_list; /* Ptr to array of ptrs to module names */
-static int mod_max; /* Number of elements allocated */
-static int mod_count; /* Number of elements used */
-
-static char *histfile; /* Ptr to the history file name */
-
-static const char *const history_usg[] =
-{
- "Usage: %s %s [-report] [-flags] [-options args] [files...]\n\n",
- " Reports:\n",
- " -T Produce report on all TAGs\n",
- " -c Committed (Modified) files\n",
- " -o Checked out modules\n",
- " -m <module> Look for specified module (repeatable)\n",
- " -x [TOFWUCGMAR] Extract by record type\n",
- " Flags:\n",
- " -a All users (Default is self)\n",
- " -e Everything (same as -x, but all record types)\n",
- " -l Last modified (committed or modified report)\n",
- " -w Working directory must match\n",
- " Options:\n",
- " -D <date> Since date (Many formats)\n",
- " -b <str> Back to record with str in module/file/repos field\n",
- " -f <file> Specified file (same as command line) (repeatable)\n",
- " -n <modulename> In module (repeatable)\n",
- " -p <repos> In repository (repeatable)\n",
- " -r <rev/tag> Since rev or tag (looks inside RCS files!)\n",
- " -t <tag> Since tag record placed in history file (by anyone).\n",
- " -u <user> For user name (repeatable)\n",
- " -z <tz> Output for time zone <tz> (e.g. -z -0700)\n",
- NULL};
-
-/* Sort routine for qsort:
- - If a user is selected at all, sort it first. User-within-file is useless.
- - If a module was selected explicitly, sort next on module.
- - Then sort by file. "File" is "repository/file" unless "working" is set,
- then it is "workdir/file". (Revision order should always track date.)
- - Always sort timestamp last.
-*/
-static int
-sort_order (l, r)
- const PTR l;
- const PTR r;
-{
- int i;
- const struct hrec *left = (const struct hrec *) l;
- const struct hrec *right = (const struct hrec *) r;
-
- if (user_sort) /* If Sort by username, compare users */
- {
- if ((i = strcmp (left->user, right->user)) != 0)
- return (i);
- }
- if (module_sort) /* If sort by modules, compare module names */
- {
- if (left->mod && right->mod)
- if ((i = strcmp (left->mod, right->mod)) != 0)
- return (i);
- }
- if (repos_sort) /* If sort by repository, compare them. */
- {
- if ((i = strcmp (left->repos, right->repos)) != 0)
- return (i);
- }
- if (file_sort) /* If sort by filename, compare files, NOT dirs. */
- {
- if ((i = strcmp (left->file, right->file)) != 0)
- return (i);
-
- if (working)
- {
- if ((i = strcmp (left->dir, right->dir)) != 0)
- return (i);
-
- if ((i = strcmp (left->end, right->end)) != 0)
- return (i);
- }
- }
-
- /*
- * By default, sort by date, time
- * XXX: This fails after 2030 when date slides into sign bit
- */
- if ((i = ((long) (left->date) - (long) (right->date))) != 0)
- return (i);
-
- /* For matching dates, keep the sort stable by using record index */
- return (left->idx - right->idx);
-}
-
-static time_t
-date_and_time (date_str)
- char *date_str;
-{
- time_t t;
-
- t = get_date (date_str, (struct timeb *) NULL);
- if (t == (time_t) - 1)
- error (1, 0, "Can't parse date/time: %s", date_str);
- return (t);
-}
-
-int
-history (argc, argv)
- int argc;
- char **argv;
-{
- int i, c;
- char fname[PATH_MAX];
-
- if (argc == -1)
- usage (history_usg);
-
- optind = 1;
- while ((c = getopt (argc, argv, "Tacelow?D:b:f:m:n:p:r:t:u:x:X:z:")) != -1)
- {
- switch (c)
- {
- case 'T': /* Tag list */
- report_count++;
- tag_report++;
- break;
- case 'a': /* For all usernames */
- all_users++;
- break;
- case 'c':
- report_count++;
- modified = 1;
- break;
- case 'e':
- report_count++;
- extract++;
- (void) strcpy (rec_types, ALL_REC_TYPES);
- break;
- case 'l': /* Find Last file record */
- last_entry = 1;
- break;
- case 'o':
- report_count++;
- v_checkout = 1;
- break;
- case 'w': /* Match Working Dir (CurDir) fields */
- working = 1;
- break;
- case 'X': /* Undocumented debugging flag */
- histfile = optarg;
- break;
- case 'D': /* Since specified date */
- if (*since_rev || *since_tag || *backto)
- {
- error (0, 0, "date overriding rev/tag/backto");
- *since_rev = *since_tag = *backto = '\0';
- }
- since_date = date_and_time (optarg);
- break;
- case 'b': /* Since specified file/Repos */
- if (since_date || *since_rev || *since_tag)
- {
- error (0, 0, "backto overriding date/rev/tag");
- *since_rev = *since_tag = '\0';
- since_date = 0;
- }
- if (strlen (optarg) >= sizeof (backto))
- {
- error (0, 0, "backto truncated to %d bytes",
- sizeof (backto) - 1);
- optarg[sizeof (backto) - 1] = '\0';
- }
- (void) strcpy (backto, optarg);
- break;
- case 'f': /* For specified file */
- save_file ("", optarg, (char *) NULL);
- break;
- case 'm': /* Full module report */
- report_count++;
- module_report++;
- case 'n': /* Look for specified module */
- save_module (optarg);
- break;
- case 'p': /* For specified directory */
- save_file (optarg, "", (char *) NULL);
- break;
- case 'r': /* Since specified Tag/Rev */
- if (since_date || *since_tag || *backto)
- {
- error (0, 0, "rev overriding date/tag/backto");
- *since_tag = *backto = '\0';
- since_date = 0;
- }
- (void) strcpy (since_rev, optarg);
- break;
- case 't': /* Since specified Tag/Rev */
- if (since_date || *since_rev || *backto)
- {
- error (0, 0, "tag overriding date/marker/file/repos");
- *since_rev = *backto = '\0';
- since_date = 0;
- }
- (void) strcpy (since_tag, optarg); /* tag */
- break;
- case 'u': /* For specified username */
- save_user (optarg);
- break;
- case 'x':
- report_count++;
- extract++;
- {
- char *cp;
-
- for (cp = optarg; *cp; cp++)
- if (!strchr (ALL_REC_TYPES, *cp))
- error (1, 0, "%c is not a valid report type", *cp);
- }
- (void) strcpy (rec_types, optarg);
- break;
- case 'z':
-#ifndef HAVE_RCS5
- error (0, 0, "-z not supported with RCS 4");
-#else
- tz_local =
- (optarg[0] == 'l' || optarg[0] == 'L')
- && (optarg[1] == 't' || optarg[1] == 'T')
- && !optarg[2];
- if (tz_local)
- tz_name = optarg;
- else
- {
- /*
- * Convert a known time with the given timezone to time_t.
- * Use the epoch + 23 hours, so timezones east of GMT work.
- */
- static char f[] = "1/1/1970 23:00 %s";
- char *buf = xmalloc (sizeof (f) - 2 + strlen (optarg));
- time_t t;
- sprintf (buf, f, optarg);
- t = get_date (buf, (struct timeb *) NULL);
- free (buf);
- if (t == (time_t) -1)
- error (0, 0, "%s is not a known time zone", optarg);
- else
- {
- /*
- * Convert to seconds east of GMT, removing the
- * 23-hour offset mentioned above.
- */
- tz_seconds_east_of_GMT = (time_t)23 * 60 * 60 - t;
- tz_name = optarg;
- }
- }
-#endif
- break;
- case '?':
- default:
- usage (history_usg);
- break;
- }
- }
- c = optind; /* Save the handled option count */
-
- /* ================ Now analyze the arguments a bit */
- if (!report_count)
- v_checkout++;
- else if (report_count > 1)
- error (1, 0, "Only one report type allowed from: \"-Tcomx\".");
-
-#ifdef CLIENT_SUPPORT
- if (client_active)
- {
- struct file_list_str *f1;
- char **mod;
-
- /* We're the client side. Fire up the remote server. */
- start_server ();
-
- ign_setup ();
-
- if (tag_report)
- send_arg("-T");
- if (all_users)
- send_arg("-a");
- if (modified)
- send_arg("-c");
- if (last_entry)
- send_arg("-l");
- if (v_checkout)
- send_arg("-o");
- if (working)
- send_arg("-w");
- if (histfile)
- send_arg("-X");
- if (since_date)
- option_with_arg ("-D", asctime (gmtime (&since_date)));
- if (backto[0] != '\0')
- option_with_arg ("-b", backto);
- for (f1 = file_list; f1 < &file_list[file_count]; ++f1)
- {
- if (f1->l_file[0] == '*')
- option_with_arg ("-p", f1->l_file + 1);
- else
- option_with_arg ("-f", f1->l_file);
- }
- if (module_report)
- send_arg("-m");
- for (mod = mod_list; mod < &mod_list[mod_count]; ++mod)
- option_with_arg ("-n", *mod);
- if (since_rev != NULL)
- option_with_arg ("-r", since_rev);
- if (since_tag != NULL)
- option_with_arg ("-t", since_tag);
- for (mod = user_list; mod < &user_list[user_count]; ++mod)
- option_with_arg ("-u", *mod);
- if (extract)
- option_with_arg ("-x", rec_types);
- option_with_arg ("-z", tz_name);
-
- if (fprintf (to_server, "history\n") < 0)
- error (1, errno, "writing to server");
- return get_responses_and_close ();
- }
-#endif
-
- if (all_users)
- save_user ("");
-
- if (mod_list)
- expand_modules ();
-
- if (tag_report)
- {
- if (!strchr (rec_types, 'T'))
- (void) strcat (rec_types, "T");
- }
- else if (extract)
- {
- if (user_list)
- user_sort++;
- }
- else if (modified)
- {
- (void) strcpy (rec_types, "MAR");
- /*
- * If the user has not specified a date oriented flag ("Since"), sort
- * by Repository/file before date. Default is "just" date.
- */
- if (!since_date && !*since_rev && !*since_tag && !*backto)
- {
- repos_sort++;
- file_sort++;
- /*
- * If we are not looking for last_modified and the user specified
- * one or more users to look at, sort by user before filename.
- */
- if (!last_entry && user_list)
- user_sort++;
- }
- }
- else if (module_report)
- {
- (void) strcpy (rec_types, last_entry ? "OMAR" : ALL_REC_TYPES);
- module_sort++;
- repos_sort++;
- file_sort++;
- working = 0; /* User's workdir doesn't count here */
- }
- else
- /* Must be "checkout" or default */
- {
- (void) strcpy (rec_types, "OF");
- /* See comments in "modified" above */
- if (!last_entry && user_list)
- user_sort++;
- if (!since_date && !*since_rev && !*since_tag && !*backto)
- file_sort++;
- }
-
- /* If no users were specified, use self (-a saves a universal ("") user) */
- if (!user_list)
- save_user (getcaller ());
-
- /* If we're looking back to a Tag value, must consider "Tag" records */
- if (*since_tag && !strchr (rec_types, 'T'))
- (void) strcat (rec_types, "T");
-
- argc -= c;
- argv += c;
- for (i = 0; i < argc; i++)
- save_file ("", argv[i], (char *) NULL);
-
- if (histfile)
- (void) strcpy (fname, histfile);
- else
- (void) sprintf (fname, "%s/%s/%s", CVSroot,
- CVSROOTADM, CVSROOTADM_HISTORY);
-
- read_hrecs (fname);
- qsort ((PTR) hrec_head, hrec_count, sizeof (struct hrec), sort_order);
- report_hrecs ();
-
- return (0);
-}
-
-void
-history_write (type, update_dir, revs, name, repository)
- int type;
- char *update_dir;
- char *revs;
- char *name;
- char *repository;
-{
- char fname[PATH_MAX], workdir[PATH_MAX], homedir[PATH_MAX];
- static char username[20]; /* !!! Should be global */
- int fd;
- char *line;
- char *slash = "", *cp, *cp2, *repos;
- int i;
- static char *tilde = "";
- static char *PrCurDir = NULL;
-
- if (logoff) /* History is turned off by cmd line switch */
- return;
- (void) sprintf (fname, "%s/%s/%s", CVSroot, CVSROOTADM, CVSROOTADM_HISTORY);
-
- /* turn off history logging if the history file does not exist */
- if (!isfile (fname))
- {
- logoff = 1;
- return;
- }
-
- if (trace)
-#ifdef SERVER_SUPPORT
- fprintf (stderr, "%c-> fopen(%s,a)\n",
- (server_active) ? 'S' : ' ', fname);
-#else
- fprintf (stderr, "-> fopen(%s,a)\n", fname);
-#endif
- if (noexec)
- return;
- if ((fd = open (fname, O_WRONLY | O_APPEND | O_CREAT, 0666)) < 0)
- error (1, errno, "cannot open history file: %s", fname);
-
- repos = Short_Repository (repository);
-
- if (!PrCurDir)
- {
- struct passwd *pw;
-
- (void) strcpy (username, getcaller ());
- PrCurDir = CurDir;
- if (!(pw = (struct passwd *) getpwnam (username)))
- error (0, 0, "cannot find own username");
- else
- {
- /* Assumes neither CurDir nor pw->pw_dir ends in '/' */
- i = strlen (pw->pw_dir);
- if (!strncmp (CurDir, pw->pw_dir, i))
- {
- PrCurDir += i; /* Point to '/' separator */
- tilde = "~";
- }
- else
- {
- /* Try harder to find a "homedir" */
- if (!getwd (workdir))
- error (1, errno, "can't getwd in history");
- if (chdir (pw->pw_dir) < 0)
- error (1, errno, "can't chdir(%s)", pw->pw_dir);
- if (!getwd (homedir))
- error (1, errno, "can't getwd in %s", pw->pw_dir);
- (void) chdir (workdir);
-
- i = strlen (homedir);
- if (!strncmp (CurDir, homedir, i))
- {
- PrCurDir += i; /* Point to '/' separator */
- tilde = "~";
- }
- }
- }
- }
-
- if (type == 'T')
- {
- repos = update_dir;
- update_dir = "";
- }
- else if (update_dir && *update_dir)
- slash = "/";
- else
- update_dir = "";
-
- (void) sprintf (workdir, "%s%s%s%s", tilde, PrCurDir, slash, update_dir);
-
- /*
- * "workdir" is the directory where the file "name" is. ("^~" == $HOME)
- * "repos" is the Repository, relative to $CVSROOT where the RCS file is.
- *
- * "$workdir/$name" is the working file name.
- * "$CVSROOT/$repos/$name,v" is the RCS file in the Repository.
- *
- * First, note that the history format was intended to save space, not
- * to be human readable.
- *
- * The working file directory ("workdir") and the Repository ("repos")
- * usually end with the same one or more directory elements. To avoid
- * duplication (and save space), the "workdir" field ends with
- * an integer offset into the "repos" field. This offset indicates the
- * beginning of the "tail" of "repos", after which all characters are
- * duplicates.
- *
- * In other words, if the "workdir" field has a '*' (a very stupid thing
- * to put in a filename) in it, then every thing following the last '*'
- * is a hex offset into "repos" of the first character from "repos" to
- * append to "workdir" to finish the pathname.
- *
- * It might be easier to look at an example:
- *
- * M273b3463|dgg|~/work*9|usr/local/cvs/examples|1.2|loginfo
- *
- * Indicates that the workdir is really "~/work/cvs/examples", saving
- * 10 characters, where "~/work*d" would save 6 characters and mean that
- * the workdir is really "~/work/examples". It will mean more on
- * directories like: usr/local/gnu/emacs/dist-19.17/lisp/term
- *
- * "workdir" is always an absolute pathname (~/xxx is an absolute path)
- * "repos" is always a relative pathname. So we can assume that we will
- * never run into the top of "workdir" -- there will always be a '/' or
- * a '~' at the head of "workdir" that is not matched by anything in
- * "repos". On the other hand, we *can* run off the top of "repos".
- *
- * Only "compress" if we save characters.
- */
-
- if (!repos)
- repos = "";
-
- cp = workdir + strlen (workdir) - 1;
- cp2 = repos + strlen (repos) - 1;
- for (i = 0; cp2 >= repos && cp > workdir && *cp == *cp2--; cp--)
- i++;
-
- if (i > 2)
- {
- i = strlen (repos) - i;
- (void) sprintf ((cp + 1), "*%x", i);
- }
-
- if (!revs)
- revs = "";
- line = xmalloc (strlen (username) + strlen (workdir) + strlen (repos)
- + strlen (revs) + strlen (name) + 100);
- sprintf (line, "%c%08lx|%s|%s|%s|%s|%s\n",
- type, (long) time ((time_t *) NULL),
- username, workdir, repos, revs, name);
-
- /* Lessen some race conditions on non-Posix-compliant hosts. */
- if (lseek (fd, (off_t) 0, SEEK_END) == -1)
- error (1, errno, "cannot seek to end of history file: %s", fname);
-
- if (write (fd, line, strlen (line)) < 0)
- error (1, errno, "cannot write to history file: %s", fname);
- free (line);
- if (close (fd) != 0)
- error (1, errno, "cannot close history file: %s", fname);
-}
-
-/*
- * save_user() adds a user name to the user list to select. Zero-length
- * username ("") matches any user.
- */
-static void
-save_user (name)
- char *name;
-{
- if (user_count == user_max)
- {
- user_max += USER_INCREMENT;
- user_list = (char **) xrealloc ((char *) user_list,
- (int) user_max * sizeof (char *));
- }
- user_list[user_count++] = xstrdup (name);
-}
-
-/*
- * save_file() adds file name and associated module to the file list to select.
- *
- * If "dir" is null, store a file name as is.
- * If "name" is null, store a directory name with a '*' on the front.
- * Else, store concatenated "dir/name".
- *
- * Later, in the "select" stage:
- * - if it starts with '*', it is prefix-matched against the repository.
- * - if it has a '/' in it, it is matched against the repository/file.
- * - else it is matched against the file name.
- */
-static void
-save_file (dir, name, module)
- char *dir;
- char *name;
- char *module;
-{
- char *cp;
- struct file_list_str *fl;
-
- if (file_count == file_max)
- {
- file_max += FILE_INCREMENT;
- file_list = (struct file_list_str *) xrealloc ((char *) file_list,
- file_max * sizeof (*fl));
- }
- fl = &file_list[file_count++];
- fl->l_file = cp = xmalloc (strlen (dir) + strlen (name) + 2);
- fl->l_module = module;
-
- if (dir && *dir)
- {
- if (name && *name)
- {
- (void) strcpy (cp, dir);
- (void) strcat (cp, "/");
- (void) strcat (cp, name);
- }
- else
- {
- *cp++ = '*';
- (void) strcpy (cp, dir);
- }
- }
- else
- {
- if (name && *name)
- {
- (void) strcpy (cp, name);
- }
- else
- {
- error (0, 0, "save_file: null dir and file name");
- }
- }
-}
-
-static void
-save_module (module)
- char *module;
-{
- if (mod_count == mod_max)
- {
- mod_max += MODULE_INCREMENT;
- mod_list = (char **) xrealloc ((char *) mod_list,
- mod_max * sizeof (char *));
- }
- mod_list[mod_count++] = xstrdup (module);
-}
-
-static void
-expand_modules ()
-{
-}
-
-/* fill_hrec
- *
- * Take a ptr to 7-part history line, ending with a newline, for example:
- *
- * M273b3463|dgg|~/work*9|usr/local/cvs/examples|1.2|loginfo
- *
- * Split it into 7 parts and drop the parts into a "struct hrec".
- * Return a pointer to the character following the newline.
- */
-
-#define NEXT_BAR(here) do { while (isspace(*line)) line++; hr->here = line; while ((c = *line++) && c != '|') ; if (!c) return(rtn); *(line - 1) = '\0'; } while (0)
-
-static char *
-fill_hrec (line, hr)
- char *line;
- struct hrec *hr;
-{
- char *cp, *rtn;
- int c;
- int off;
- static int idx = 0;
-
- memset ((char *) hr, 0, sizeof (*hr));
- while (isspace (*line))
- line++;
- if (!(rtn = strchr (line, '\n')))
- return ("");
- *rtn++ = '\0';
-
- hr->type = line++;
- (void) sscanf (line, "%x", &hr->date);
- while (*line && strchr ("0123456789abcdefABCDEF", *line))
- line++;
- if (*line == '\0')
- return (rtn);
-
- line++;
- NEXT_BAR (user);
- NEXT_BAR (dir);
- if ((cp = strrchr (hr->dir, '*')) != NULL)
- {
- *cp++ = '\0';
- (void) sscanf (cp, "%x", &off);
- hr->end = line + off;
- }
- else
- hr->end = line - 1; /* A handy pointer to '\0' */
- NEXT_BAR (repos);
- NEXT_BAR (rev);
- hr->idx = idx++;
- if (strchr ("FOT", *(hr->type)))
- hr->mod = line;
-
- NEXT_BAR (file); /* This returns ptr to next line or final '\0' */
- return (rtn); /* If it falls through, go on to next record */
-}
-
-/* read_hrecs's job is to read the history file and fill in all the "hrec"
- * (history record) array elements with the ones we need to print.
- *
- * Logic:
- * - Read the whole history file into a single buffer.
- * - Walk through the buffer, parsing lines out of the buffer.
- * 1. Split line into pointer and integer fields in the "next" hrec.
- * 2. Apply tests to the hrec to see if it is wanted.
- * 3. If it *is* wanted, bump the hrec pointer down by one.
- */
-static void
-read_hrecs (fname)
- char *fname;
-{
- char *cp, *cp2;
- int i, fd;
- struct hrec *hr;
- struct stat st_buf;
-
- if ((fd = open (fname, O_RDONLY)) < 0)
- error (1, errno, "cannot open history file: %s", fname);
-
- if (fstat (fd, &st_buf) < 0)
- error (1, errno, "can't stat history file");
-
- /* Exactly enough space for lines data */
- if (!(i = st_buf.st_size))
- error (1, 0, "history file is empty");
- cp = xmalloc (i + 2);
-
- if (read (fd, cp, i) != i)
- error (1, errno, "cannot read log file");
- (void) close (fd);
-
- if (*(cp + i - 1) != '\n')
- {
- *(cp + i) = '\n'; /* Make sure last line ends in '\n' */
- i++;
- }
- *(cp + i) = '\0';
- for (cp2 = cp; cp2 - cp < i; cp2++)
- {
- if (*cp2 != '\n' && !isprint (*cp2))
- *cp2 = ' ';
- }
-
- hrec_max = HREC_INCREMENT;
- hrec_head = (struct hrec *) xmalloc (hrec_max * sizeof (struct hrec));
-
- while (*cp)
- {
- if (hrec_count == hrec_max)
- {
- struct hrec *old_head = hrec_head;
-
- hrec_max += HREC_INCREMENT;
- hrec_head = (struct hrec *) xrealloc ((char *) hrec_head,
- hrec_max * sizeof (struct hrec));
- if (hrec_head != old_head)
- {
- if (last_since_tag)
- last_since_tag = hrec_head + (last_since_tag - old_head);
- if (last_backto)
- last_backto = hrec_head + (last_backto - old_head);
- }
- }
-
- hr = hrec_head + hrec_count;
- cp = fill_hrec (cp, hr); /* cp == next line or '\0' at end of buffer */
-
- if (select_hrec (hr))
- hrec_count++;
- }
-
- /* Special selection problem: If "since_tag" is set, we have saved every
- * record from the 1st occurrence of "since_tag", when we want to save
- * records since the *last* occurrence of "since_tag". So what we have
- * to do is bump hrec_head forward and reduce hrec_count accordingly.
- */
- if (last_since_tag)
- {
- hrec_count -= (last_since_tag - hrec_head);
- hrec_head = last_since_tag;
- }
-
- /* Much the same thing is necessary for the "backto" option. */
- if (last_backto)
- {
- hrec_count -= (last_backto - hrec_head);
- hrec_head = last_backto;
- }
-}
-
-/* Utility program for determining whether "find" is inside "string" */
-static int
-within (find, string)
- char *find, *string;
-{
- int c, len;
-
- if (!find || !string)
- return (0);
-
- c = *find++;
- len = strlen (find);
-
- while (*string)
- {
- if (!(string = strchr (string, c)))
- return (0);
- string++;
- if (!strncmp (find, string, len))
- return (1);
- }
- return (0);
-}
-
-/* The purpose of "select_hrec" is to apply the selection criteria based on
- * the command arguments and defaults and return a flag indicating whether
- * this record should be remembered for printing.
- */
-static int
-select_hrec (hr)
- struct hrec *hr;
-{
- char **cpp, *cp, *cp2;
- struct file_list_str *fl;
- int count;
-
- /* "Since" checking: The argument parser guarantees that only one of the
- * following four choices is set:
- *
- * 1. If "since_date" is set, it contains a Unix time_t specified on the
- * command line. hr->date fields earlier than "since_date" are ignored.
- * 2. If "since_rev" is set, it contains either an RCS "dotted" revision
- * number (which is of limited use) or a symbolic TAG. Each RCS file
- * is examined and the date on the specified revision (or the revision
- * corresponding to the TAG) in the RCS file (CVSROOT/repos/file) is
- * compared against hr->date as in 1. above.
- * 3. If "since_tag" is set, matching tag records are saved. The field
- * "last_since_tag" is set to the last one of these. Since we don't
- * know where the last one will be, all records are saved from the
- * first occurrence of the TAG. Later, at the end of "select_hrec"
- * records before the last occurrence of "since_tag" are skipped.
- * 4. If "backto" is set, all records with a module name or file name
- * matching "backto" are saved. In addition, all records with a
- * repository field with a *prefix* matching "backto" are saved.
- * The field "last_backto" is set to the last one of these. As in
- * 3. above, "select_hrec" adjusts to include the last one later on.
- */
- if (since_date)
- {
- if (hr->date < since_date)
- return (0);
- }
- else if (*since_rev)
- {
- Vers_TS *vers;
- time_t t;
-
- vers = Version_TS (hr->repos, (char *) NULL, since_rev, (char *) NULL,
- hr->file, 1, 0, (List *) NULL, (List *) NULL);
- if (vers->vn_rcs)
- {
- if ((t = RCS_getrevtime (vers->srcfile, vers->vn_rcs, (char *) 0, 0))
- != (time_t) 0)
- {
- if (hr->date < t)
- {
- freevers_ts (&vers);
- return (0);
- }
- }
- }
- freevers_ts (&vers);
- }
- else if (*since_tag)
- {
- if (*(hr->type) == 'T')
- {
- /*
- * A 'T'ag record, the "rev" field holds the tag to be set,
- * while the "repos" field holds "D"elete, "A"dd or a rev.
- */
- if (within (since_tag, hr->rev))
- {
- last_since_tag = hr;
- return (1);
- }
- else
- return (0);
- }
- if (!last_since_tag)
- return (0);
- }
- else if (*backto)
- {
- if (within (backto, hr->file) || within (backto, hr->mod) ||
- within (backto, hr->repos))
- last_backto = hr;
- else
- return (0);
- }
-
- /* User checking:
- *
- * Run down "user_list", match username ("" matches anything)
- * If "" is not there and actual username is not there, return failure.
- */
- if (user_list && hr->user)
- {
- for (cpp = user_list, count = user_count; count; cpp++, count--)
- {
- if (!**cpp)
- break; /* null user == accept */
- if (!strcmp (hr->user, *cpp)) /* found listed user */
- break;
- }
- if (!count)
- return (0); /* Not this user */
- }
-
- /* Record type checking:
- *
- * 1. If Record type is not in rec_types field, skip it.
- * 2. If mod_list is null, keep everything. Otherwise keep only modules
- * on mod_list.
- * 3. If neither a 'T', 'F' nor 'O' record, run through "file_list". If
- * file_list is null, keep everything. Otherwise, keep only files on
- * file_list, matched appropriately.
- */
- if (!strchr (rec_types, *(hr->type)))
- return (0);
- if (!strchr ("TFO", *(hr->type))) /* Don't bother with "file" if "TFO" */
- {
- if (file_list) /* If file_list is null, accept all */
- {
- for (fl = file_list, count = file_count; count; fl++, count--)
- {
- /* 1. If file_list entry starts with '*', skip the '*' and
- * compare it against the repository in the hrec.
- * 2. If file_list entry has a '/' in it, compare it against
- * the concatenation of the repository and file from hrec.
- * 3. Else compare the file_list entry against the hrec file.
- */
- char cmpfile[PATH_MAX];
-
- if (*(cp = fl->l_file) == '*')
- {
- cp++;
- /* if argument to -p is a prefix of repository */
- if (!strncmp (cp, hr->repos, strlen (cp)))
- {
- hr->mod = fl->l_module;
- break;
- }
- }
- else
- {
- if (strchr (cp, '/'))
- {
- (void) sprintf (cp2 = cmpfile, "%s/%s",
- hr->repos, hr->file);
- }
- else
- {
- cp2 = hr->file;
- }
-
- /* if requested file is found within {repos}/file fields */
- if (within (cp, cp2))
- {
- hr->mod = fl->l_module;
- break;
- }
- }
- }
- if (!count)
- return (0); /* String specified and no match */
- }
- }
- if (mod_list)
- {
- for (cpp = mod_list, count = mod_count; count; cpp++, count--)
- {
- if (hr->mod && !strcmp (hr->mod, *cpp)) /* found module */
- break;
- }
- if (!count)
- return (0); /* Module specified & this record is not one of them. */
- }
-
- return (1); /* Select this record unless rejected above. */
-}
-
-/* The "sort_order" routine (when handed to qsort) has arranged for the
- * hrecs files to be in the right order for the report.
- *
- * Most of the "selections" are done in the select_hrec routine, but some
- * selections are more easily done after the qsort by "accept_hrec".
- */
-static void
-report_hrecs ()
-{
- struct hrec *hr, *lr;
- struct tm *tm;
- int i, count, ty;
- char *cp;
- int user_len, file_len, rev_len, mod_len, repos_len;
-
- if (*since_tag && !last_since_tag)
- {
- (void) printf ("No tag found: %s\n", since_tag);
- return;
- }
- else if (*backto && !last_backto)
- {
- (void) printf ("No module, file or repository with: %s\n", backto);
- return;
- }
- else if (hrec_count < 1)
- {
- (void) printf ("No records selected.\n");
- return;
- }
-
- user_len = file_len = rev_len = mod_len = repos_len = 0;
-
- /* Run through lists and find maximum field widths */
- hr = lr = hrec_head;
- hr++;
- for (count = hrec_count; count--; lr = hr, hr++)
- {
- char repos[PATH_MAX];
-
- if (!count)
- hr = NULL;
- if (!accept_hrec (lr, hr))
- continue;
-
- ty = *(lr->type);
- (void) strcpy (repos, lr->repos);
- if ((cp = strrchr (repos, '/')) != NULL)
- {
- if (lr->mod && !strcmp (++cp, lr->mod))
- {
- (void) strcpy (cp, "*");
- }
- }
- if ((i = strlen (lr->user)) > user_len)
- user_len = i;
- if ((i = strlen (lr->file)) > file_len)
- file_len = i;
- if (ty != 'T' && (i = strlen (repos)) > repos_len)
- repos_len = i;
- if (ty != 'T' && (i = strlen (lr->rev)) > rev_len)
- rev_len = i;
- if (lr->mod && (i = strlen (lr->mod)) > mod_len)
- mod_len = i;
- }
-
- /* Walk through hrec array setting "lr" (Last Record) to each element.
- * "hr" points to the record following "lr" -- It is NULL in the last
- * pass.
- *
- * There are two sections in the loop below:
- * 1. Based on the report type (e.g. extract, checkout, tag, etc.),
- * decide whether the record should be printed.
- * 2. Based on the record type, format and print the data.
- */
- for (lr = hrec_head, hr = (lr + 1); hrec_count--; lr = hr, hr++)
- {
- char workdir[PATH_MAX], repos[PATH_MAX];
-
- if (!hrec_count)
- hr = NULL;
- if (!accept_hrec (lr, hr))
- continue;
-
- ty = *(lr->type);
-#ifdef HAVE_RCS5
- if (!tz_local)
- {
- time_t t = lr->date + tz_seconds_east_of_GMT;
- tm = gmtime (&t);
- }
- else
-#endif
- tm = localtime (&(lr->date));
- (void) printf ("%c %02d/%02d %02d:%02d %s %-*s", ty, tm->tm_mon + 1,
- tm->tm_mday, tm->tm_hour, tm->tm_min, tz_name,
- user_len, lr->user);
-
- (void) sprintf (workdir, "%s%s", lr->dir, lr->end);
- if ((cp = strrchr (workdir, '/')) != NULL)
- {
- if (lr->mod && !strcmp (++cp, lr->mod))
- {
- (void) strcpy (cp, "*");
- }
- }
- (void) strcpy (repos, lr->repos);
- if ((cp = strrchr (repos, '/')) != NULL)
- {
- if (lr->mod && !strcmp (++cp, lr->mod))
- {
- (void) strcpy (cp, "*");
- }
- }
-
- switch (ty)
- {
- case 'T':
- /* 'T'ag records: repository is a "tag type", rev is the tag */
- (void) printf (" %-*s [%s:%s]", mod_len, lr->mod, lr->rev,
- repos);
- if (working)
- (void) printf (" {%s}", workdir);
- break;
- case 'F':
- case 'O':
- if (lr->rev && *(lr->rev))
- (void) printf (" [%s]", lr->rev);
- (void) printf (" %-*s =%s%-*s %s", repos_len, repos, lr->mod,
- mod_len + 1 - strlen (lr->mod), "=", workdir);
- break;
- case 'W':
- case 'U':
- case 'C':
- case 'G':
- case 'M':
- case 'A':
- case 'R':
- (void) printf (" %-*s %-*s %-*s =%s= %s", rev_len, lr->rev,
- file_len, lr->file, repos_len, repos,
- lr->mod ? lr->mod : "", workdir);
- break;
- default:
- (void) printf ("Hey! What is this junk? RecType[0x%2.2x]", ty);
- break;
- }
- (void) putchar ('\n');
- }
-}
-
-static int
-accept_hrec (lr, hr)
- struct hrec *hr, *lr;
-{
- int ty;
-
- ty = *(lr->type);
-
- if (last_since_tag && ty == 'T')
- return (1);
-
- if (v_checkout)
- {
- if (ty != 'O')
- return (0); /* Only interested in 'O' records */
-
- /* We want to identify all the states that cause the next record
- * ("hr") to be different from the current one ("lr") and only
- * print a line at the allowed boundaries.
- */
-
- if (!hr || /* The last record */
- strcmp (hr->user, lr->user) || /* User has changed */
- strcmp (hr->mod, lr->mod) ||/* Module has changed */
- (working && /* If must match "workdir" */
- (strcmp (hr->dir, lr->dir) || /* and the 1st parts or */
- strcmp (hr->end, lr->end)))) /* the 2nd parts differ */
-
- return (1);
- }
- else if (modified)
- {
- if (!last_entry || /* Don't want only last rec */
- !hr || /* Last entry is a "last entry" */
- strcmp (hr->repos, lr->repos) || /* Repository has changed */
- strcmp (hr->file, lr->file))/* File has changed */
- return (1);
-
- if (working)
- { /* If must match "workdir" */
- if (strcmp (hr->dir, lr->dir) || /* and the 1st parts or */
- strcmp (hr->end, lr->end)) /* the 2nd parts differ */
- return (1);
- }
- }
- else if (module_report)
- {
- if (!last_entry || /* Don't want only last rec */
- !hr || /* Last entry is a "last entry" */
- strcmp (hr->mod, lr->mod) ||/* Module has changed */
- strcmp (hr->repos, lr->repos) || /* Repository has changed */
- strcmp (hr->file, lr->file))/* File has changed */
- return (1);
- }
- else
- {
- /* "extract" and "tag_report" always print selected records. */
- return (1);
- }
-
- return (0);
-}
diff --git a/gnu/usr.bin/cvs/cvs/ignore.c b/gnu/usr.bin/cvs/cvs/ignore.c
deleted file mode 100644
index f70fe782a898..000000000000
--- a/gnu/usr.bin/cvs/cvs/ignore.c
+++ /dev/null
@@ -1,286 +0,0 @@
-/*
- * .cvsignore file support contributed by David G. Grubbs <dgg@odi.com>
- */
-
-#include "cvs.h"
-
-#ifndef lint
-static const char rcsid[] = "$CVSid: @(#)ignore.c 1.16 94/09/24 $";
-USE(rcsid);
-#endif
-
-/*
- * Ignore file section.
- *
- * "!" may be included any time to reset the list (i.e. ignore nothing);
- * "*" may be specified to ignore everything. It stays as the first
- * element forever, unless a "!" clears it out.
- */
-
-static char **ign_list; /* List of files to ignore in update
- * and import */
-static char **s_ign_list = NULL;
-static int ign_count; /* Number of active entries */
-static int s_ign_count = 0;
-static int ign_size; /* This many slots available (plus
- * one for a NULL) */
-static int ign_hold; /* Index where first "temporary" item
- * is held */
-
-const char *ign_default = ". .. core RCSLOG tags TAGS RCS SCCS .make.state .nse_depinfo #* .#* cvslog.* ,* CVS* .del-* *.a *.o *.so *.Z *~ *.old *.elc *.ln *.bak *.BAK *.orig *.rej";
-
-#define IGN_GROW 16 /* grow the list by 16 elements at a
- * time */
-
-/*
- * To the "ignore list", add the hard-coded default ignored wildcards above,
- * the wildcards found in $CVSROOT/CVSROOT/cvsignore, the wildcards found in
- * ~/.cvsignore and the wildcards found in the CVSIGNORE environment
- * variable.
- */
-void
-ign_setup ()
-{
- struct passwd *pw;
- char file[PATH_MAX];
- char *tmp;
-
- /* Start with default list and special case */
- tmp = xstrdup (ign_default);
- ign_add (tmp, 0);
- free (tmp);
-
-#ifdef CLIENT_SUPPORT
- /* Chances are we should have some way to provide this feature
- client/server, but I'm not sure how (surely not by introducing
- another network turnaround to each operation--perhaps by
- putting a file in the CVS directory on checkout, or with some
- sort of "slave cvsroot" on the client). */
- if (!client_active)
-#endif
- {
- /* Then add entries found in repository, if it exists */
- (void) sprintf (file, "%s/%s/%s", CVSroot, CVSROOTADM,
- CVSROOTADM_IGNORE);
- ign_add_file (file, 0);
- }
-
- /* Then add entries found in home dir, (if user has one) and file exists */
- if ((pw = (struct passwd *) getpwuid (getuid ())) && pw->pw_dir)
- {
- (void) sprintf (file, "%s/%s", pw->pw_dir, CVSDOTIGNORE);
- ign_add_file (file, 0);
- }
-
- /* Then add entries found in CVSIGNORE environment variable. */
- ign_add (getenv (IGNORE_ENV), 0);
-
- /* Later, add ignore entries found in -I arguments */
-}
-
-/*
- * Open a file and read lines, feeding each line to a line parser. Arrange
- * for keeping a temporary list of wildcards at the end, if the "hold"
- * argument is set.
- */
-void
-ign_add_file (file, hold)
- char *file;
- int hold;
-{
- FILE *fp;
- char line[1024];
-
- /* restore the saved list (if any) */
- if (s_ign_list != NULL)
- {
- int i;
-
- for (i = 0; i < s_ign_count; i++)
- ign_list[i] = s_ign_list[i];
- ign_count = s_ign_count;
- ign_list[ign_count] = NULL;
-
- s_ign_count = 0;
- free (s_ign_list);
- s_ign_list = NULL;
- }
-
- /* is this a temporary ignore file? */
- if (hold)
- {
- /* re-set if we had already done a temporary file */
- if (ign_hold)
- {
- int i;
-
- for (i = ign_hold; i < ign_count; i++)
- free (ign_list[i]);
- ign_count = ign_hold;
- ign_list[ign_count] = NULL;
- }
- else
- {
- ign_hold = ign_count;
- }
- }
-
- /* load the file */
- fp = fopen (file, "r");
- if (fp == NULL)
- {
- if (! existence_error (errno))
- error (0, errno, "cannot open %s", file);
- return;
- }
- while (fgets (line, sizeof (line), fp))
- ign_add (line, hold);
- if (fclose (fp) < 0)
- error (0, errno, "cannot close %s", file);
-}
-
-/* Parse a line of space-separated wildcards and add them to the list. */
-void
-ign_add (ign, hold)
- char *ign;
- int hold;
-{
- if (!ign || !*ign)
- return;
-
- for (; *ign; ign++)
- {
- char *mark;
- char save;
-
- /* ignore whitespace before the token */
- if (isspace (*ign))
- continue;
-
- /*
- * if we find a single character !, we must re-set the ignore list
- * (saving it if necessary). We also catch * as a special case in a
- * global ignore file as an optimization
- */
- if ((!*(ign+1) || isspace (*(ign+1))) && (*ign == '!' || *ign == '*'))
- {
- if (!hold)
- {
- /* permanently reset the ignore list */
- int i;
-
- for (i = 0; i < ign_count; i++)
- free (ign_list[i]);
- ign_count = 0;
- ign_list[0] = NULL;
-
- /* if we are doing a '!', continue; otherwise add the '*' */
- if (*ign == '!')
- continue;
- }
- else if (*ign == '!')
- {
- /* temporarily reset the ignore list */
- int i;
-
- if (ign_hold)
- {
- for (i = ign_hold; i < ign_count; i++)
- free (ign_list[i]);
- ign_hold = 0;
- }
- s_ign_list = (char **) xmalloc (ign_count * sizeof (char *));
- for (i = 0; i < ign_count; i++)
- s_ign_list[i] = ign_list[i];
- s_ign_count = ign_count;
- ign_count = 0;
- ign_list[0] = NULL;
- continue;
- }
- }
-
- /* If we have used up all the space, add some more */
- if (ign_count >= ign_size)
- {
- ign_size += IGN_GROW;
- ign_list = (char **) xrealloc ((char *) ign_list,
- (ign_size + 1) * sizeof (char *));
- }
-
- /* find the end of this token */
- for (mark = ign; *mark && !isspace (*mark); mark++)
- /* do nothing */ ;
-
- save = *mark;
- *mark = '\0';
-
- ign_list[ign_count++] = xstrdup (ign);
- ign_list[ign_count] = NULL;
-
- *mark = save;
- if (save)
- ign = mark;
- else
- ign = mark - 1;
- }
-}
-
-/* Return 1 if the given filename should be ignored by update or import. */
-int
-ign_name (name)
- char *name;
-{
- char **cpp = ign_list;
-
- if (cpp == NULL)
- return (0);
-
- while (*cpp)
- if (fnmatch (*cpp++, name, 0) == 0)
- return (1);
- return (0);
-}
-
-
-static char **dir_ign_list = NULL;
-static int dir_ign_max = 0;
-static int dir_ign_current = 0;
-
-/* add a directory to list of dirs to ignore */
-void ign_dir_add (name)
- char *name;
-{
- /* make sure we've got the space for the entry */
- if (dir_ign_current <= dir_ign_max)
- {
- dir_ign_max += IGN_GROW;
- dir_ign_list = (char **) xrealloc ((char *) dir_ign_list, (dir_ign_max+1) * sizeof(char*));
- }
-
- dir_ign_list[dir_ign_current] = name;
-
- dir_ign_current += 1 ;
-}
-
-
-/* this function returns 1 (true) if the given directory name is part of
- * the list of directories to ignore
- */
-
-int ignore_directory (name)
- char *name;
-{
- int i;
-
- if (!dir_ign_list)
- return 0;
-
- i = dir_ign_current;
- while (i--)
- {
- if (strncmp(name, dir_ign_list[i], strlen(dir_ign_list[i])) == 0)
- return 1;
- }
-
- return 0;
-}
diff --git a/gnu/usr.bin/cvs/cvs/import.c b/gnu/usr.bin/cvs/cvs/import.c
deleted file mode 100644
index 9980763d4253..000000000000
--- a/gnu/usr.bin/cvs/cvs/import.c
+++ /dev/null
@@ -1,1181 +0,0 @@
-/*
- * Copyright (c) 1992, Brian Berliner and Jeff Polk
- * Copyright (c) 1989-1992, Brian Berliner
- *
- * You may distribute under the terms of the GNU General Public License as
- * specified in the README file that comes with the CVS 1.4 kit.
- *
- * "import" checks in the vendor release located in the current directory into
- * the CVS source repository. The CVS vendor branch support is utilized.
- *
- * At least three arguments are expected to follow the options:
- * repository Where the source belongs relative to the CVSROOT
- * VendorTag Vendor's major tag
- * VendorReleTag Tag for this particular release
- *
- * Additional arguments specify more Vendor Release Tags.
- */
-
-#include "cvs.h"
-#include "save-cwd.h"
-
-#ifndef lint
-static const char rcsid[] = "$CVSid: @(#)import.c 1.63 94/09/30 $";
-USE(rcsid);
-#endif
-
-#define FILE_HOLDER ".#cvsxxx"
-
-static char *get_comment PROTO((char *user));
-static int add_rcs_file PROTO((char *message, char *rcs, char *user, char *vtag,
- int targc, char *targv[]));
-static int expand_at_signs PROTO((char *buf, off_t size, FILE *fp));
-static int add_rev PROTO((char *message, char *rcs, char *vfile, char *vers));
-static int add_tags PROTO((char *rcs, char *vfile, char *vtag, int targc,
- char *targv[]));
-static int import_descend PROTO((char *message, char *vtag, int targc, char *targv[]));
-static int import_descend_dir PROTO((char *message, char *dir, char *vtag,
- int targc, char *targv[]));
-static int process_import_file PROTO((char *message, char *vfile, char *vtag,
- int targc, char *targv[]));
-static int update_rcs_file PROTO((char *message, char *vfile, char *vtag, int targc,
- char *targv[], int inattic));
-static void add_log PROTO((int ch, char *fname));
-
-static int repos_len;
-static char vhead[50];
-static char vbranch[50];
-static FILE *logfp;
-static char repository[PATH_MAX];
-static int conflicts;
-static int use_file_modtime;
-static char *keyword_opt = NULL;
-
-static const char *const import_usage[] =
-{
- "Usage: %s %s [-d] [-k subst] [-I ign] [-m msg] [-b branch]\n",
- " [-W spec] repository vendor-tag release-tags...\n",
- "\t-d\tUse the file's modification time as the time of import.\n",
- "\t-k sub\tSet default RCS keyword substitution mode.\n",
- "\t-I ign\tMore files to ignore (! to reset).\n",
- "\t-b bra\tVendor branch id.\n",
- "\t-m msg\tLog message.\n",
- "\t-W spec\tWrappers specification line.\n",
- NULL
-};
-
-int
-import (argc, argv)
- int argc;
- char **argv;
-{
- char *message = NULL;
- char tmpfile[L_tmpnam+1];
- char *cp;
- int i, c, msglen, err;
- List *ulist;
- Node *p;
-
- if (argc == -1)
- usage (import_usage);
-
- ign_setup ();
- wrap_setup ();
-
- (void) strcpy (vbranch, CVSBRANCH);
- optind = 1;
- while ((c = getopt (argc, argv, "Qqdb:m:I:k:W:")) != -1)
- {
- switch (c)
- {
- case 'Q':
- case 'q':
-#ifdef SERVER_SUPPORT
- /* The CVS 1.5 client sends these options (in addition to
- Global_option requests), so we must ignore them. */
- if (!server_active)
-#endif
- error (1, 0,
- "-q or -Q must be specified before \"%s\"",
- command_name);
- break;
- case 'd':
- use_file_modtime = 1;
- break;
- case 'b':
- (void) strcpy (vbranch, optarg);
- break;
- case 'm':
-#ifdef FORCE_USE_EDITOR
- use_editor = TRUE;
-#else
- use_editor = FALSE;
-#endif
- message = xstrdup(optarg);
- break;
- case 'I':
- ign_add (optarg, 0);
- break;
- case 'k':
- /* RCS_check_kflag returns strings of the form -kxx. We
- only use it for validation, so we can free the value
- as soon as it is returned. */
- free (RCS_check_kflag(optarg));
- keyword_opt = optarg;
- break;
- case 'W':
- wrap_add (optarg, 0);
- break;
- case '?':
- default:
- usage (import_usage);
- break;
- }
- }
- argc -= optind;
- argv += optind;
- if (argc < 3)
- usage (import_usage);
-
- for (i = 1; i < argc; i++) /* check the tags for validity */
- RCS_check_tag (argv[i]);
-
- /* XXX - this should be a module, not just a pathname */
- if (! isabsolute (argv[0]))
- {
- if (CVSroot == NULL)
- {
- error (0, 0, "missing CVSROOT environment variable\n");
- error (1, 0, "Set it or specify the '-d' option to %s.",
- program_name);
- }
- (void) sprintf (repository, "%s/%s", CVSroot, argv[0]);
- repos_len = strlen (CVSroot);
- }
- else
- {
- (void) strcpy (repository, argv[0]);
- repos_len = 0;
- }
-
- /*
- * Consistency checks on the specified vendor branch. It must be
- * composed of only numbers and dots ('.'). Also, for now we only
- * support branching to a single level, so the specified vendor branch
- * must only have two dots in it (like "1.1.1").
- */
- for (cp = vbranch; *cp != '\0'; cp++)
- if (!isdigit (*cp) && *cp != '.')
- error (1, 0, "%s is not a numeric branch", vbranch);
- if (numdots (vbranch) != 2)
- error (1, 0, "Only branches with two dots are supported: %s", vbranch);
- (void) strcpy (vhead, vbranch);
- cp = strrchr (vhead, '.');
- *cp = '\0';
-
-#ifdef CLIENT_SUPPORT
- if (client_active)
- {
- /* Do this now; don't ask for a log message if we can't talk to the
- server. But if there is a syntax error in the options, give
- an error message without connecting. */
- start_server ();
- }
-#endif
-
- if (use_editor)
- {
- do_editor ((char *) NULL, &message, repository,
- (List *) NULL);
- }
-
- msglen = message == NULL ? 0 : strlen (message);
- if (msglen == 0 || message[msglen - 1] != '\n')
- {
- char *nm = xmalloc (msglen + 2);
- if (message != NULL)
- {
- (void) strcpy (nm, message);
- free (message);
- }
- (void) strcat (nm + msglen, "\n");
- message = nm;
- }
-
-#ifdef CLIENT_SUPPORT
- if (client_active)
- {
- int err;
-
- ign_setup ();
-
- if (use_file_modtime)
- send_arg("-d");
-
- if (vbranch[0] != '\0')
- option_with_arg ("-b", vbranch);
- if (message)
- option_with_arg ("-m", message);
- if (keyword_opt != NULL)
- option_with_arg ("-k", keyword_opt);
-
- {
- int i;
- for (i = 0; i < argc; ++i)
- send_arg (argv[i]);
- }
-
- logfp = stdin;
- client_import_setup (repository);
- err = import_descend (message, argv[1], argc - 2, argv + 2);
- client_import_done ();
- if (fprintf (to_server, "import\n") < 0)
- error (1, errno, "writing to server");
- err += get_responses_and_close ();
- return err;
- }
-#endif
-
- /*
- * Make all newly created directories writable. Should really use a more
- * sophisticated security mechanism here.
- */
- (void) umask (cvsumask);
- make_directories (repository);
-
- /* Create the logfile that will be logged upon completion */
- if ((logfp = fopen (tmpnam (tmpfile), "w+")) == NULL)
- error (1, errno, "cannot create temporary file `%s'", tmpfile);
- (void) unlink (tmpfile); /* to be sure it goes away */
- (void) fprintf (logfp, "\nVendor Tag:\t%s\n", argv[1]);
- (void) fprintf (logfp, "Release Tags:\t");
- for (i = 2; i < argc; i++)
- (void) fprintf (logfp, "%s\n\t\t", argv[i]);
- (void) fprintf (logfp, "\n");
-
- /* Just Do It. */
- err = import_descend (message, argv[1], argc - 2, argv + 2);
- if (conflicts)
- {
- if (!really_quiet)
- {
- (void) printf ("\n%d conflicts created by this import.\n",
- conflicts);
- (void) printf ("Use the following command to help the merge:\n\n");
- (void) printf ("\t%s checkout -j%s:yesterday -j%s %s\n\n",
- program_name, argv[1], argv[1], argv[0]);
- }
-
- (void) fprintf (logfp, "\n%d conflicts created by this import.\n",
- conflicts);
- (void) fprintf (logfp,
- "Use the following command to help the merge:\n\n");
- (void) fprintf (logfp, "\t%s checkout -j%s:yesterday -j%s %s\n\n",
- program_name, argv[1], argv[1], argv[0]);
- }
- else
- {
- if (!really_quiet)
- (void) printf ("\nNo conflicts created by this import\n\n");
- (void) fprintf (logfp, "\nNo conflicts created by this import\n\n");
- }
-
- /*
- * Write out the logfile and clean up.
- */
- ulist = getlist ();
- p = getnode ();
- p->type = UPDATE;
- p->delproc = update_delproc;
- p->key = xstrdup ("- Imported sources");
- p->data = (char *) T_TITLE;
- (void) addnode (ulist, p);
- Update_Logfile (repository, message, vbranch, logfp, ulist);
- dellist (&ulist);
- (void) fclose (logfp);
-
- /* Make sure the temporary file goes away, even on systems that don't let
- you delete a file that's in use. */
- unlink (tmpfile);
-
- if (message)
- free (message);
-
- return (err);
-}
-
-/*
- * process all the files in ".", then descend into other directories.
- */
-static int
-import_descend (message, vtag, targc, targv)
- char *message;
- char *vtag;
- int targc;
- char *targv[];
-{
- DIR *dirp;
- struct dirent *dp;
- int err = 0;
- List *dirlist = NULL;
-
- /* first, load up any per-directory ignore lists */
- ign_add_file (CVSDOTIGNORE, 1);
- wrap_add_file (CVSDOTWRAPPER, 1);
-
- if ((dirp = opendir (".")) == NULL)
- {
- err++;
- }
- else
- {
- while ((dp = readdir (dirp)) != NULL)
- {
- if (strcmp (dp->d_name, ".") == 0 || strcmp (dp->d_name, "..") == 0)
- continue;
- if (ign_name (dp->d_name))
- {
-#ifdef SERVER_SUPPORT
- /* CVS directories are created by server.c because it doesn't
- special-case import. So don't print a message about them.
- Do print a message about other ignored files (although
- most of these will get ignored on the client side). */
- if (server_active && strcmp (dp->d_name, CVSADM) == 0)
- continue;
-#endif
- add_log ('I', dp->d_name);
- continue;
- }
-
- if (
-#ifdef DT_DIR
- (dp->d_type == DT_DIR
- || (dp->d_type == DT_UNKNOWN && isdir (dp->d_name)))
-#else
- isdir (dp->d_name)
-#endif
- && !wrap_name_has (dp->d_name, WRAP_TOCVS)
- )
- {
- Node *n;
-
- if (dirlist == NULL)
- dirlist = getlist();
-
- n = getnode();
- n->key = xstrdup (dp->d_name);
- addnode(dirlist, n);
- }
- else if (
-#ifdef DT_DIR
- dp->d_type == DT_LNK || dp->d_type == DT_UNKNOWN &&
-#endif
- islink (dp->d_name))
- {
- add_log ('L', dp->d_name);
- err++;
- }
- else
- {
-#ifdef CLIENT_SUPPORT
- if (client_active)
- err += client_process_import_file (message, dp->d_name,
- vtag, targc, targv,
- repository);
- else
-#endif
- err += process_import_file (message, dp->d_name,
- vtag, targc, targv);
- }
- }
- (void) closedir (dirp);
- }
-
- if (dirlist != NULL)
- {
- Node *head, *p;
-
- head = dirlist->list;
- for (p = head->next; p != head; p = p->next)
- {
- err += import_descend_dir (message, p->key, vtag, targc, targv);
- }
-
- dellist(&dirlist);
- }
-
- return (err);
-}
-
-/*
- * Process the argument import file.
- */
-static int
-process_import_file (message, vfile, vtag, targc, targv)
- char *message;
- char *vfile;
- char *vtag;
- int targc;
- char *targv[];
-{
- char attic_name[PATH_MAX];
- char rcs[PATH_MAX];
- int inattic = 0;
-
- (void) sprintf (rcs, "%s/%s%s", repository, vfile, RCSEXT);
- if (!isfile (rcs))
- {
- (void) sprintf (attic_name, "%s/%s/%s%s", repository, CVSATTIC,
- vfile, RCSEXT);
- if (!isfile (attic_name))
- {
-
- /*
- * A new import source file; it doesn't exist as a ,v within the
- * repository nor in the Attic -- create it anew.
- */
- add_log ('N', vfile);
- return (add_rcs_file (message, rcs, vfile, vtag, targc, targv));
- }
- inattic = 1;
- }
-
- /*
- * an rcs file exists. have to do things the official, slow, way.
- */
- return (update_rcs_file (message, vfile, vtag, targc, targv, inattic));
-}
-
-/*
- * The RCS file exists; update it by adding the new import file to the
- * (possibly already existing) vendor branch.
- */
-static int
-update_rcs_file (message, vfile, vtag, targc, targv, inattic)
- char *message;
- char *vfile;
- char *vtag;
- int targc;
- char *targv[];
- int inattic;
-{
- Vers_TS *vers;
- int letter;
- int ierrno;
- char *tmpdir;
- char *tocvsPath;
-
- vers = Version_TS (repository, (char *) NULL, vbranch, (char *) NULL, vfile,
- 1, 0, (List *) NULL, (List *) NULL);
-#ifdef DEATH_SUPPORT
- if (vers->vn_rcs != NULL
- && !RCS_isdead(vers->srcfile, vers->vn_rcs))
-#else
- if (vers->vn_rcs != NULL)
-#endif
- {
- char xtmpfile[PATH_MAX];
- int different;
- int retcode = 0;
-
- tmpdir = getenv ("TMPDIR");
- if (tmpdir == NULL || tmpdir[0] == '\0')
- tmpdir = "/tmp";
-
- (void) sprintf (xtmpfile, "%s/cvs-imp%d", tmpdir, getpid());
-
- /*
- * The rcs file does have a revision on the vendor branch. Compare
- * this revision with the import file; if they match exactly, there
- * is no need to install the new import file as a new revision to the
- * branch. Just tag the revision with the new import tags.
- *
- * This is to try to cut down the number of "C" conflict messages for
- * locally modified import source files.
- */
-#ifdef HAVE_RCS5
- run_setup ("%s%s -q -f -r%s -p -ko", Rcsbin, RCS_CO, vers->vn_rcs);
-#else
- run_setup ("%s%s -q -f -r%s -p", Rcsbin, RCS_CO, vers->vn_rcs);
-#endif
- run_arg (vers->srcfile->path);
- if ((retcode = run_exec (RUN_TTY, xtmpfile, RUN_TTY,
- RUN_NORMAL|RUN_REALLY)) != 0)
- {
- ierrno = errno;
- fperror (logfp, 0, retcode == -1 ? ierrno : 0,
- "ERROR: cannot co revision %s of file %s", vers->vn_rcs,
- vers->srcfile->path);
- error (0, retcode == -1 ? ierrno : 0,
- "ERROR: cannot co revision %s of file %s", vers->vn_rcs,
- vers->srcfile->path);
- (void) unlink_file (xtmpfile);
- return (1);
- }
-
- tocvsPath = wrap_tocvs_process_file (vfile);
- different = xcmp (xtmpfile, vfile);
- if (tocvsPath)
- if (unlink_file_dir (tocvsPath) < 0)
- error (0, errno, "cannot remove %s", tocvsPath);
-
- (void) unlink_file (xtmpfile);
- if (!different)
- {
- int retval = 0;
-
- /*
- * The two files are identical. Just update the tags, print the
- * "U", signifying that the file has changed, but needs no
- * attention, and we're done.
- */
- if (add_tags (vers->srcfile->path, vfile, vtag, targc, targv))
- retval = 1;
- add_log ('U', vfile);
- freevers_ts (&vers);
- return (retval);
- }
- }
-
- /* We may have failed to parse the RCS file; check just in case */
- if (vers->srcfile == NULL ||
- add_rev (message, vers->srcfile->path, vfile, vers->vn_rcs) ||
- add_tags (vers->srcfile->path, vfile, vtag, targc, targv))
- {
- freevers_ts (&vers);
- return (1);
- }
-
- if (vers->srcfile->branch == NULL || inattic ||
- strcmp (vers->srcfile->branch, vbranch) != 0)
- {
- conflicts++;
- letter = 'C';
- }
- else
- letter = 'U';
- add_log (letter, vfile);
-
- freevers_ts (&vers);
- return (0);
-}
-
-/*
- * Add the revision to the vendor branch
- */
-static int
-add_rev (message, rcs, vfile, vers)
- char *message;
- char *rcs;
- char *vfile;
- char *vers;
-{
- int locked, status, ierrno;
- char *tocvsPath;
- struct stat vfile_stat;
-
- if (noexec)
- return (0);
-
- locked = 0;
- if (vers != NULL)
- {
- /* Before RCS_lock existed, we were directing stdout, as well as
- stderr, from the RCS command, to DEVNULL. I wouldn't guess that
- was necessary, but I don't know for sure. */
- if (RCS_lock (rcs, vbranch, 1) != 0)
- {
- error (0, errno, "fork failed");
- return (1);
- }
- locked = 1;
- }
- tocvsPath = wrap_tocvs_process_file (vfile);
-
- /* We used to deposit the revision with -r; RCS would delete the
- working file, but we'd keep a hard link to it, and rename it
- back after running RCS (ooh, atomicity). However, that
- strategy doesn't work on operating systems without hard links
- (like Windows NT). Instead, let's deposit it using -u, and
- restore its permission bits afterwards. This also means the
- file always exists under its own name. */
- if (! tocvsPath)
- stat (vfile, &vfile_stat);
-
- run_setup ("%s%s -q -f %s%s", Rcsbin, RCS_CI,
- (tocvsPath ? "-r" : "-u"),
- vbranch);
- run_args ("-m%s", make_message_rcslegal (message));
- if (use_file_modtime)
- run_arg ("-d");
- run_arg (tocvsPath == NULL ? vfile : tocvsPath);
- run_arg (rcs);
- status = run_exec (RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL);
- ierrno = errno;
-
- /* Restore the permissions on vfile. */
- if (! tocvsPath)
- chmod (vfile, vfile_stat.st_mode);
-
- if (status)
- {
- if (!noexec)
- {
- fperror (logfp, 0, status == -1 ? ierrno : 0, "ERROR: Check-in of %s failed", rcs);
- error (0, status == -1 ? ierrno : 0, "ERROR: Check-in of %s failed", rcs);
- }
- if (locked)
- {
- (void) RCS_unlock(rcs, vbranch, 0);
- }
- return (1);
- }
- return (0);
-}
-
-/*
- * Add the vendor branch tag and all the specified import release tags to the
- * RCS file. The vendor branch tag goes on the branch root (1.1.1) while the
- * vendor release tags go on the newly added leaf of the branch (1.1.1.1,
- * 1.1.1.2, ...).
- */
-static int
-add_tags (rcs, vfile, vtag, targc, targv)
- char *rcs;
- char *vfile;
- char *vtag;
- int targc;
- char *targv[];
-{
- int i, ierrno;
- Vers_TS *vers;
- int retcode = 0;
-
- if (noexec)
- return (0);
-
- if ((retcode = RCS_settag(rcs, vtag, vbranch)) != 0)
- {
- ierrno = errno;
- fperror (logfp, 0, retcode == -1 ? ierrno : 0,
- "ERROR: Failed to set tag %s in %s", vtag, rcs);
- error (0, retcode == -1 ? ierrno : 0,
- "ERROR: Failed to set tag %s in %s", vtag, rcs);
- return (1);
- }
- vers = Version_TS (repository, (char *) NULL, vtag, (char *) NULL, vfile,
- 1, 0, (List *) NULL, (List *) NULL);
- for (i = 0; i < targc; i++)
- {
- if ((retcode = RCS_settag (rcs, targv[i], vers->vn_rcs)) != 0)
- {
- ierrno = errno;
- fperror (logfp, 0, retcode == -1 ? ierrno : 0,
- "WARNING: Couldn't add tag %s to %s", targv[i], rcs);
- error (0, retcode == -1 ? ierrno : 0,
- "WARNING: Couldn't add tag %s to %s", targv[i], rcs);
- }
- }
- freevers_ts (&vers);
- return (0);
-}
-
-/*
- * Stolen from rcs/src/rcsfnms.c, and adapted/extended.
- */
-struct compair
-{
- char *suffix, *comlead;
-};
-
-static const struct compair comtable[] =
-{
-
-/*
- * comtable pairs each filename suffix with a comment leader. The comment
- * leader is placed before each line generated by the $Log keyword. This
- * table is used to guess the proper comment leader from the working file's
- * suffix during initial ci (see InitAdmin()). Comment leaders are needed for
- * languages without multiline comments; for others they are optional.
- */
- {"a", "-- "}, /* Ada */
- {"ada", "-- "},
- {"adb", "-- "},
- {"asm", ";; "}, /* assembler (MS-DOS) */
- {"ads", "-- "}, /* Ada */
- {"bat", ":: "}, /* batch (MS-DOS) */
- {"body", "-- "}, /* Ada */
- {"c", " * "}, /* C */
- {"c++", "// "}, /* C++ in all its infinite guises */
- {"cc", "// "},
- {"cpp", "// "},
- {"cxx", "// "},
- {"m", "// "}, /* Objective-C */
- {"cl", ";;; "}, /* Common Lisp */
- {"cmd", ":: "}, /* command (OS/2) */
- {"cmf", "c "}, /* CM Fortran */
- {"cs", " * "}, /* C* */
- {"csh", "# "}, /* shell */
- {"e", "# "}, /* efl */
- {"epsf", "% "}, /* encapsulated postscript */
- {"epsi", "% "}, /* encapsulated postscript */
- {"el", "; "}, /* Emacs Lisp */
- {"f", "c "}, /* Fortran */
- {"for", "c "},
- {"h", " * "}, /* C-header */
- {"hh", "// "}, /* C++ header */
- {"hpp", "// "},
- {"hxx", "// "},
- {"in", "# "}, /* for Makefile.in */
- {"l", " * "}, /* lex (conflict between lex and
- * franzlisp) */
- {"mac", ";; "}, /* macro (DEC-10, MS-DOS, PDP-11,
- * VMS, etc) */
- {"me", ".\\\" "}, /* me-macros t/nroff */
- {"ml", "; "}, /* mocklisp */
- {"mm", ".\\\" "}, /* mm-macros t/nroff */
- {"ms", ".\\\" "}, /* ms-macros t/nroff */
- {"man", ".\\\" "}, /* man-macros t/nroff */
- {"1", ".\\\" "}, /* feeble attempt at man pages... */
- {"2", ".\\\" "},
- {"3", ".\\\" "},
- {"4", ".\\\" "},
- {"5", ".\\\" "},
- {"6", ".\\\" "},
- {"7", ".\\\" "},
- {"8", ".\\\" "},
- {"9", ".\\\" "},
- {"p", " * "}, /* pascal */
- {"pas", " * "},
- {"pl", "# "}, /* perl (conflict with Prolog) */
- {"ps", "% "}, /* postscript */
- {"psw", "% "}, /* postscript wrap */
- {"pswm", "% "}, /* postscript wrap */
- {"r", "# "}, /* ratfor */
- {"red", "% "}, /* psl/rlisp */
-#ifdef sparc
- {"s", "! "}, /* assembler */
-#endif
-#ifdef mc68000
- {"s", "| "}, /* assembler */
-#endif
-#ifdef pdp11
- {"s", "/ "}, /* assembler */
-#endif
-#ifdef vax
- {"s", "# "}, /* assembler */
-#endif
-#ifdef __ksr__
- {"s", "# "}, /* assembler */
- {"S", "# "}, /* Macro assembler */
-#endif
- {"sh", "# "}, /* shell */
- {"sl", "% "}, /* psl */
- {"spec", "-- "}, /* Ada */
- {"tex", "% "}, /* tex */
- {"y", " * "}, /* yacc */
- {"ye", " * "}, /* yacc-efl */
- {"yr", " * "}, /* yacc-ratfor */
-#ifdef SYSTEM_COMMENT_TABLE
- SYSTEM_COMMENT_TABLE
-#endif
- {"", "# "}, /* default for empty suffix */
- {NULL, "# "} /* default for unknown suffix; */
-/* must always be last */
-};
-
-static char *
-get_comment (user)
- char *user;
-{
- char *cp, *suffix;
- char suffix_path[PATH_MAX];
- int i;
-
- cp = strrchr (user, '.');
- if (cp != NULL)
- {
- cp++;
-
- /*
- * Convert to lower-case, since we are not concerned about the
- * case-ness of the suffix.
- */
- (void) strcpy (suffix_path, cp);
- for (cp = suffix_path; *cp; cp++)
- if (isupper (*cp))
- *cp = tolower (*cp);
- suffix = suffix_path;
- }
- else
- suffix = ""; /* will use the default */
- for (i = 0;; i++)
- {
- if (comtable[i].suffix == NULL) /* default */
- return (comtable[i].comlead);
- if (strcmp (suffix, comtable[i].suffix) == 0)
- return (comtable[i].comlead);
- }
-}
-
-static int
-add_rcs_file (message, rcs, user, vtag, targc, targv)
- char *message;
- char *rcs;
- char *user;
- char *vtag;
- int targc;
- char *targv[];
-{
- FILE *fprcs, *fpuser;
- struct stat sb;
- struct tm *ftm;
- time_t now;
- char altdate1[50];
-#ifndef HAVE_RCS5
- char altdate2[50];
-#endif
- char *author, *buf;
- int i, ierrno, err = 0;
- mode_t mode;
- char *tocvsPath;
- char *userfile;
-
- if (noexec)
- return (0);
-
-#ifdef LINES_CRLF_TERMINATED
- /* There exits a port of RCS to such a system that stores files with
- straight newlines. If we ever reach this point on such a system,
- we'll need to decide what to do with the open_file call below. */
- abort ();
-#endif
- tocvsPath = wrap_tocvs_process_file (user);
- userfile = (tocvsPath == NULL ? user : tocvsPath);
- fpuser = fopen (userfile, "r");
- if (fpuser == NULL) {
- /* not fatal, continue import */
- fperror (logfp, 0, errno, "ERROR: cannot read file %s", userfile);
- error (0, errno, "ERROR: cannot read file %s", userfile);
- goto read_error;
- }
- fprcs = fopen (rcs, "w+");
- if (fprcs == NULL) {
- ierrno = errno;
- goto write_error_noclose;
- }
-
- /*
- * putadmin()
- */
- if (fprintf (fprcs, "head %s;\n", vhead) < 0 ||
- fprintf (fprcs, "branch %s;\n", vbranch) < 0 ||
- fprintf (fprcs, "access ;\n") < 0 ||
- fprintf (fprcs, "symbols ") < 0)
- {
- goto write_error;
- }
-
- for (i = targc - 1; i >= 0; i--) /* RCS writes the symbols backwards */
- if (fprintf (fprcs, "%s:%s.1 ", targv[i], vbranch) < 0)
- goto write_error;
-
- if (fprintf (fprcs, "%s:%s;\n", vtag, vbranch) < 0 ||
- fprintf (fprcs, "locks ; strict;\n") < 0 ||
- /* XXX - make sure @@ processing works in the RCS file */
- fprintf (fprcs, "comment @%s@;\n", get_comment (user)) < 0)
- {
- goto write_error;
- }
-
- if (keyword_opt != NULL)
- if (fprintf (fprcs, "expand @%s@;\n", keyword_opt) < 0)
- {
- goto write_error;
- }
-
- if (fprintf (fprcs, "\n") < 0)
- goto write_error;
-
- /*
- * puttree()
- */
- if (fstat (fileno (fpuser), &sb) < 0)
- error (1, errno, "cannot fstat %s", user);
- if (use_file_modtime)
- now = sb.st_mtime;
- else
- (void) time (&now);
-#ifdef HAVE_RCS5
- ftm = gmtime (&now);
-#else
- ftm = localtime (&now);
-#endif
- (void) sprintf (altdate1, DATEFORM,
- ftm->tm_year + (ftm->tm_year < 100 ? 0 : 1900),
- ftm->tm_mon + 1, ftm->tm_mday, ftm->tm_hour,
- ftm->tm_min, ftm->tm_sec);
-#ifdef HAVE_RCS5
-#define altdate2 altdate1
-#else
- /*
- * If you don't have RCS V5 or later, you need to lie about the ci
- * time, since RCS V4 and earlier insist that the times differ.
- */
- now++;
- ftm = localtime (&now);
- (void) sprintf (altdate2, DATEFORM,
- ftm->tm_year + (ftm->tm_year < 100 ? 0 : 1900),
- ftm->tm_mon + 1, ftm->tm_mday, ftm->tm_hour,
- ftm->tm_min, ftm->tm_sec);
-#endif
- author = getcaller ();
-
- if (fprintf (fprcs, "\n%s\n", vhead) < 0 ||
- fprintf (fprcs, "date %s; author %s; state Exp;\n",
- altdate1, author) < 0 ||
- fprintf (fprcs, "branches %s.1;\n", vbranch) < 0 ||
- fprintf (fprcs, "next ;\n") < 0 ||
- fprintf (fprcs, "\n%s.1\n", vbranch) < 0 ||
- fprintf (fprcs, "date %s; author %s; state Exp;\n",
- altdate2, author) < 0 ||
- fprintf (fprcs, "branches ;\n") < 0 ||
- fprintf (fprcs, "next ;\n\n") < 0 ||
- /*
- * putdesc()
- */
- fprintf (fprcs, "\ndesc\n") < 0 ||
- fprintf (fprcs, "@@\n\n\n") < 0 ||
- /*
- * putdelta()
- */
- fprintf (fprcs, "\n%s\n", vhead) < 0 ||
- fprintf (fprcs, "log\n") < 0 ||
- fprintf (fprcs, "@Initial revision\n@\n") < 0 ||
- fprintf (fprcs, "text\n@") < 0)
- {
- goto write_error;
- }
-
- if (sb.st_size > 0)
- {
- off_t size;
-
- size = sb.st_size;
- buf = xmalloc ((int) size);
- if (fread (buf, (int) size, 1, fpuser) != 1)
- error (1, errno, "cannot read file %s for copying", user);
- if (expand_at_signs (buf, size, fprcs) < 0)
- {
- free (buf);
- goto write_error;
- }
- free (buf);
- }
- if (fprintf (fprcs, "@\n\n") < 0 ||
- fprintf (fprcs, "\n%s.1\n", vbranch) < 0 ||
- fprintf (fprcs, "log\n@") < 0 ||
- expand_at_signs (message, (off_t) strlen (message), fprcs) < 0 ||
- fprintf (fprcs, "@\ntext\n") < 0 ||
- fprintf (fprcs, "@@\n") < 0)
- {
- goto write_error;
- }
- if (fclose (fprcs) == EOF)
- {
- ierrno = errno;
- goto write_error_noclose;
- }
- (void) fclose (fpuser);
-
- /*
- * Fix the modes on the RCS files. The user modes of the original
- * user file are propagated to the group and other modes as allowed
- * by the repository umask, except that all write permissions are
- * turned off.
- */
- mode = (sb.st_mode |
- (sb.st_mode & S_IRWXU) >> 3 |
- (sb.st_mode & S_IRWXU) >> 6) &
- ~cvsumask &
- ~(S_IWRITE | S_IWGRP | S_IWOTH);
- if (chmod (rcs, mode) < 0)
- {
- ierrno = errno;
- fperror (logfp, 0, ierrno,
- "WARNING: cannot change mode of file %s", rcs);
- error (0, ierrno, "WARNING: cannot change mode of file %s", rcs);
- err++;
- }
- if (tocvsPath)
- if (unlink_file_dir (tocvsPath) < 0)
- error (0, errno, "cannot remove %s", tocvsPath);
- return (err);
-
-write_error:
- ierrno = errno;
- (void) fclose (fprcs);
-write_error_noclose:
- (void) fclose (fpuser);
- fperror (logfp, 0, ierrno, "ERROR: cannot write file %s", rcs);
- error (0, ierrno, "ERROR: cannot write file %s", rcs);
- if (ierrno == ENOSPC)
- {
- (void) unlink (rcs);
- fperror (logfp, 0, 0, "ERROR: out of space - aborting");
- error (1, 0, "ERROR: out of space - aborting");
- }
-read_error:
- if (tocvsPath)
- if (unlink_file_dir (tocvsPath) < 0)
- error (0, errno, "cannot remove %s", tocvsPath);
-
- return (err + 1);
-}
-
-/*
- * Write SIZE bytes at BUF to FP, expanding @ signs into double @
- * signs. If an error occurs, return a negative value and set errno
- * to indicate the error. If not, return a nonnegative value.
- */
-static int
-expand_at_signs (buf, size, fp)
- char *buf;
- off_t size;
- FILE *fp;
-{
- char *cp, *end;
-
- errno = 0;
- for (cp = buf, end = buf + size; cp < end; cp++)
- {
- if (*cp == '@')
- {
- if (putc ('@', fp) == EOF && errno != 0)
- return EOF;
- }
- if (putc (*cp, fp) == EOF && errno != 0)
- return (EOF);
- }
- return (1);
-}
-
-/*
- * Write an update message to (potentially) the screen and the log file.
- */
-static void
-add_log (ch, fname)
- int ch;
- char *fname;
-{
- if (!really_quiet) /* write to terminal */
- {
- if (repos_len)
- (void) printf ("%c %s/%s\n", ch, repository + repos_len + 1, fname);
- else if (repository[0])
- (void) printf ("%c %s/%s\n", ch, repository, fname);
- else
- (void) printf ("%c %s\n", ch, fname);
- }
-
- if (repos_len) /* write to logfile */
- (void) fprintf (logfp, "%c %s/%s\n", ch,
- repository + repos_len + 1, fname);
- else if (repository[0])
- (void) fprintf (logfp, "%c %s/%s\n", ch, repository, fname);
- else
- (void) fprintf (logfp, "%c %s\n", ch, fname);
-}
-
-/*
- * This is the recursive function that walks the argument directory looking
- * for sub-directories that have CVS administration files in them and updates
- * them recursively.
- *
- * Note that we do not follow symbolic links here, which is a feature!
- */
-static int
-import_descend_dir (message, dir, vtag, targc, targv)
- char *message;
- char *dir;
- char *vtag;
- int targc;
- char *targv[];
-{
- struct saved_cwd cwd;
- char *cp;
- int ierrno, err;
-
- if (islink (dir))
- return (0);
- if (save_cwd (&cwd))
- {
- fperror (logfp, 0, 0, "ERROR: cannot get working directory");
- return (1);
- }
- if (repository[0] == '\0')
- (void) strcpy (repository, dir);
- else
- {
- (void) strcat (repository, "/");
- (void) strcat (repository, dir);
- }
-#ifdef CLIENT_SUPPORT
- if (!quiet && !client_active)
-#else
- if (!quiet)
-#endif
-#ifdef SERVER_SUPPORT
- /* Needs to go on stdout, not stderr, to avoid being interspersed
- with the add_log messages. */
- printf ("%s %s: Importing %s\n",
- program_name, command_name, repository);
-#else
- error (0, 0, "Importing %s", repository);
-#endif
-
- if (chdir (dir) < 0)
- {
- ierrno = errno;
- fperror (logfp, 0, ierrno, "ERROR: cannot chdir to %s", repository);
- error (0, ierrno, "ERROR: cannot chdir to %s", repository);
- err = 1;
- goto out;
- }
-#ifdef CLIENT_SUPPORT
- if (!client_active && !isdir (repository))
-#else
- if (!isdir (repository))
-#endif
- {
- if (isfile (repository))
- {
- fperror (logfp, 0, 0, "ERROR: %s is a file, should be a directory!",
- repository);
- error (0, 0, "ERROR: %s is a file, should be a directory!",
- repository);
- err = 1;
- goto out;
- }
- if (noexec == 0 && CVS_MKDIR (repository, 0777) < 0)
- {
- ierrno = errno;
- fperror (logfp, 0, ierrno,
- "ERROR: cannot mkdir %s -- not added", repository);
- error (0, ierrno,
- "ERROR: cannot mkdir %s -- not added", repository);
- err = 1;
- goto out;
- }
- }
- err = import_descend (message, vtag, targc, targv);
- out:
- if ((cp = strrchr (repository, '/')) != NULL)
- *cp = '\0';
- else
- repository[0] = '\0';
- if (restore_cwd (&cwd, NULL))
- exit (1);
- free_cwd (&cwd);
- return (err);
-}
diff --git a/gnu/usr.bin/cvs/cvs/lock.c b/gnu/usr.bin/cvs/cvs/lock.c
deleted file mode 100644
index 3e15fbb90c96..000000000000
--- a/gnu/usr.bin/cvs/cvs/lock.c
+++ /dev/null
@@ -1,608 +0,0 @@
-/*
- * Copyright (c) 1992, Brian Berliner and Jeff Polk
- * Copyright (c) 1989-1992, Brian Berliner
- *
- * You may distribute under the terms of the GNU General Public License as
- * specified in the README file that comes with the CVS 1.4 kit.
- *
- * Set Lock
- *
- * Lock file support for CVS.
- */
-
-#include "cvs.h"
-
-#ifndef lint
-static const char rcsid[] = "$CVSid: @(#)lock.c 1.50 94/09/30 $";
-USE(rcsid);
-#endif
-
-static int readers_exist PROTO((char *repository));
-static int set_lock PROTO((char *repository, int will_wait));
-static void clear_lock PROTO((void));
-static void set_lockers_name PROTO((struct stat *statp));
-static int set_writelock_proc PROTO((Node * p, void *closure));
-static int unlock_proc PROTO((Node * p, void *closure));
-static int write_lock PROTO((char *repository));
-static void unlock PROTO((char *repository));
-static void lock_wait PROTO((char *repository));
-static int Check_Owner PROTO((char *lockdir));
-
-static char lockers_name[20];
-static char *repository;
-static char readlock[PATH_MAX], writelock[PATH_MAX], masterlock[PATH_MAX];
-static int cleanup_lckdir;
-static List *locklist;
-
-#define L_OK 0 /* success */
-#define L_ERROR 1 /* error condition */
-#define L_LOCKED 2 /* lock owned by someone else */
-
-/*
- * Clean up all outstanding locks
- */
-void
-Lock_Cleanup ()
-{
- /* clean up simple locks (if any) */
- if (repository != NULL)
- {
- unlock (repository);
- repository = (char *) NULL;
- }
-
- /* clean up multiple locks (if any) */
- if (locklist != (List *) NULL)
- {
- (void) walklist (locklist, unlock_proc, NULL);
- locklist = (List *) NULL;
- }
-}
-
-/*
- * walklist proc for removing a list of locks
- */
-static int
-unlock_proc (p, closure)
- Node *p;
- void *closure;
-{
- unlock (p->key);
- return (0);
-}
-
-/*
- * Remove the lock files (without complaining if they are not there),
- */
-static void
-unlock (repository)
- char *repository;
-{
- char tmp[PATH_MAX];
-
- if (readlock[0] != '\0')
- {
- (void) sprintf (tmp, "%s/%s", repository, readlock);
- if (unlink (tmp) < 0 && ! existence_error (errno))
- error (0, errno, "failed to remove lock %s", tmp);
- }
-
- if (writelock[0] != '\0')
- {
- (void) sprintf (tmp, "%s/%s", repository, writelock);
- if (unlink (tmp) < 0 && ! existence_error (errno))
- error (0, errno, "failed to remove lock %s", tmp);
- }
-
- /*
- * Only remove the lock directory if it is ours, note that this does
- * lead to the limitation that one user ID should not be committing
- * files into the same Repository directory at the same time. Oh well.
- */
- if (writelock[0] != '\0' || (readlock[0] != '\0' && cleanup_lckdir))
- {
- (void) sprintf (tmp, "%s/%s", repository, CVSLCK);
- if (Check_Owner(tmp))
- {
-#ifdef AFSCVS
- char rmuidlock[PATH_MAX];
- sprintf(rmuidlock, "rm -f %s/uidlock%d", tmp, geteuid() );
- system(rmuidlock);
-#endif
- (void) rmdir (tmp);
- }
- }
- cleanup_lckdir = 0;
-}
-
-/*
- * Check the owner of a lock. Returns 1 if we own it, 0 otherwise.
- */
-static int
-Check_Owner(lockdir)
- char *lockdir;
-{
- struct stat sb;
-
-#ifdef AFSCVS
- /* In the Andrew File System (AFS), user ids from stat don't match
- those from geteuid(). The AFSCVS code can deal with either AFS or
- non-AFS repositories; the non-AFSCVS code is faster. */
- char uidlock[PATH_MAX];
-
- /* Check if the uidlock is in the lock directory */
- sprintf(uidlock, "%s/uidlock%d", lockdir, geteuid() );
- if( stat(uidlock, &sb) != -1)
- return 1; /* The file exists, therefore we own the lock */
- else
- return 0; /* The file didn't exist or some other error.
- * Assume that we don't own it.
- */
-#else
- if (stat (lockdir, &sb) != -1 && sb.st_uid == geteuid ())
- return 1;
- else
- return 0;
-#endif
-} /* end Check_Owner() */
-
-
-/*
- * Create a lock file for readers
- */
-int
-Reader_Lock (xrepository)
- char *xrepository;
-{
- int err = 0;
- FILE *fp;
- char tmp[PATH_MAX];
-
- if (noexec)
- return (0);
-
- /* we only do one directory at a time for read locks! */
- if (repository != NULL)
- {
- error (0, 0, "Reader_Lock called while read locks set - Help!");
- return (1);
- }
-
- if (readlock[0] == '\0')
- (void) sprintf (readlock,
-#ifdef HAVE_LONG_FILE_NAMES
- "%s.%s.%d", CVSRFL, hostname,
-#else
- "%s.%d", CVSRFL,
-#endif
- getpid ());
-
- /* remember what we're locking (for lock_cleanup) */
- repository = xrepository;
-
-#ifdef BOGUS_UNLESS_PROVEN_OTHERWISE
- /* make sure we can write the repository */
- (void) sprintf (tmp,
-#ifdef HAVE_LONG_FILE_NAMES
- "%s/%s.%s.%d", xrepository, CVSTFL, hostname,
-#else
- "%s/%s.%d", xrepository, CVSTFL,
-#endif
- getpid());
- if ((fp = fopen (tmp, "w+")) == NULL || fclose (fp) == EOF)
- {
- error (0, errno, "cannot create read lock in repository `%s'",
- xrepository);
- readlock[0] = '\0';
- if (unlink (tmp) < 0 && ! existence_error (errno))
- error (0, errno, "failed to remove lock %s", tmp);
- return (1);
- }
- if (unlink (tmp) < 0)
- error (0, errno, "failed to remove lock %s", tmp);
-#endif
-
- /* get the lock dir for our own */
- if (set_lock (xrepository, 1) != L_OK)
- {
- error (0, 0, "failed to obtain dir lock in repository `%s'",
- xrepository);
- readlock[0] = '\0';
- return (1);
- }
-
- /* write a read-lock */
- (void) sprintf (tmp, "%s/%s", xrepository, readlock);
- if ((fp = fopen (tmp, "w+")) == NULL || fclose (fp) == EOF)
- {
- error (0, errno, "cannot create read lock in repository `%s'",
- xrepository);
- readlock[0] = '\0';
- err = 1;
- }
-
- /* free the lock dir */
- clear_lock();
-
- return (err);
-}
-
-/*
- * Lock a list of directories for writing
- */
-static char *lock_error_repos;
-static int lock_error;
-int
-Writer_Lock (list)
- List *list;
-{
- if (noexec)
- return (0);
-
- /* We only know how to do one list at a time */
- if (locklist != (List *) NULL)
- {
- error (0, 0, "Writer_Lock called while write locks set - Help!");
- return (1);
- }
-
- for (;;)
- {
- /* try to lock everything on the list */
- lock_error = L_OK; /* init for set_writelock_proc */
- lock_error_repos = (char *) NULL; /* init for set_writelock_proc */
- locklist = list; /* init for Lock_Cleanup */
- (void) strcpy (lockers_name, "unknown");
-
- (void) walklist (list, set_writelock_proc, NULL);
-
- switch (lock_error)
- {
- case L_ERROR: /* Real Error */
- Lock_Cleanup (); /* clean up any locks we set */
- error (0, 0, "lock failed - giving up");
- return (1);
-
- case L_LOCKED: /* Someone already had a lock */
- Lock_Cleanup (); /* clean up any locks we set */
- lock_wait (lock_error_repos); /* sleep a while and try again */
- continue;
-
- case L_OK: /* we got the locks set */
- return (0);
-
- default:
- error (0, 0, "unknown lock status %d in Writer_Lock",
- lock_error);
- return (1);
- }
- }
-}
-
-/*
- * walklist proc for setting write locks
- */
-static int
-set_writelock_proc (p, closure)
- Node *p;
- void *closure;
-{
- /* if some lock was not OK, just skip this one */
- if (lock_error != L_OK)
- return (0);
-
- /* apply the write lock */
- lock_error_repos = p->key;
- lock_error = write_lock (p->key);
- return (0);
-}
-
-/*
- * Create a lock file for writers returns L_OK if lock set ok, L_LOCKED if
- * lock held by someone else or L_ERROR if an error occurred
- */
-static int
-write_lock (repository)
- char *repository;
-{
- int status;
- FILE *fp;
- char tmp[PATH_MAX];
-
- if (writelock[0] == '\0')
- (void) sprintf (writelock,
-#ifdef HAVE_LONG_FILE_NAMES
- "%s.%s.%d", CVSWFL, hostname,
-#else
- "%s.%d", CVSWFL,
-#endif
- getpid());
-
-#ifdef BOGUS_UNLESS_PROVEN_OTHERWISE
- /* make sure we can write the repository */
- (void) sprintf (tmp,
-#ifdef HAVE_LONG_FILE_NAMES
- "%s/%s.%s.%d", repository, CVSTFL, hostname,
-#else
- "%s/%s.%d", repository, CVSTFL,
-#endif
- getpid ());
- if ((fp = fopen (tmp, "w+")) == NULL || fclose (fp) == EOF)
- {
- error (0, errno, "cannot create write lock in repository `%s'",
- repository);
- if (unlink (tmp) < 0 && ! existence_error (errno))
- error (0, errno, "failed to remove lock %s", tmp);
- return (L_ERROR);
- }
- if (unlink (tmp) < 0)
- error (0, errno, "failed to remove lock %s", tmp);
-#endif
-
- /* make sure the lock dir is ours (not necessarily unique to us!) */
- status = set_lock (repository, 0);
- if (status == L_OK)
- {
- /* we now own a writer - make sure there are no readers */
- if (readers_exist (repository))
- {
- /* clean up the lock dir if we created it */
- if (status == L_OK)
- {
- clear_lock();
- }
-
- /* indicate we failed due to read locks instead of error */
- return (L_LOCKED);
- }
-
- /* write the write-lock file */
- (void) sprintf (tmp, "%s/%s", repository, writelock);
- if ((fp = fopen (tmp, "w+")) == NULL || fclose (fp) == EOF)
- {
- int xerrno = errno;
-
- if (unlink (tmp) < 0 && ! existence_error (errno))
- error (0, errno, "failed to remove lock %s", tmp);
-
- /* free the lock dir if we created it */
- if (status == L_OK)
- {
- clear_lock();
- }
-
- /* return the error */
- error (0, xerrno, "cannot create write lock in repository `%s'",
- repository);
- return (L_ERROR);
- }
- return (L_OK);
- }
- else
- return (status);
-}
-
-/*
- * readers_exist() returns 0 if there are no reader lock files remaining in
- * the repository; else 1 is returned, to indicate that the caller should
- * sleep a while and try again.
- */
-static int
-readers_exist (repository)
- char *repository;
-{
- char line[MAXLINELEN];
- DIR *dirp;
- struct dirent *dp;
- struct stat sb;
- int ret = 0;
-
-#ifdef CVS_FUDGELOCKS
-again:
-#endif
-
- if ((dirp = opendir (repository)) == NULL)
- error (1, 0, "cannot open directory %s", repository);
-
- errno = 0;
- while ((dp = readdir (dirp)) != NULL)
- {
- if (fnmatch (CVSRFLPAT, dp->d_name, 0) == 0)
- {
-#ifdef CVS_FUDGELOCKS
- time_t now;
- (void) time (&now);
-#endif
-
- (void) sprintf (line, "%s/%s", repository, dp->d_name);
- if (stat (line, &sb) != -1)
- {
-#ifdef CVS_FUDGELOCKS
- /*
- * If the create time of the file is more than CVSLCKAGE
- * seconds ago, try to clean-up the lock file, and if
- * successful, re-open the directory and try again.
- */
- if (now >= (sb.st_ctime + CVSLCKAGE) && unlink (line) != -1)
- {
- (void) closedir (dirp);
- goto again;
- }
-#endif
- set_lockers_name (&sb);
- }
-
- ret = 1;
- break;
- }
- errno = 0;
- }
- if (errno != 0)
- error (0, errno, "error reading directory %s", repository);
-
- closedir (dirp);
- return (ret);
-}
-
-/*
- * Set the static variable lockers_name appropriately, based on the stat
- * structure passed in.
- */
-static void
-set_lockers_name (statp)
- struct stat *statp;
-{
- struct passwd *pw;
-
- if ((pw = (struct passwd *) getpwuid (statp->st_uid)) !=
- (struct passwd *) NULL)
- {
- (void) strcpy (lockers_name, pw->pw_name);
- }
- else
- (void) sprintf (lockers_name, "uid%lu", (unsigned long) statp->st_uid);
-}
-
-/*
- * Persistently tries to make the directory "lckdir",, which serves as a
- * lock. If the create time on the directory is greater than CVSLCKAGE
- * seconds old, just try to remove the directory.
- */
-static int
-set_lock (repository, will_wait)
- char *repository;
- int will_wait;
-{
- struct stat sb;
- mode_t omask;
-#ifdef CVS_FUDGELOCKS
- time_t now;
-#endif
-
- (void) sprintf (masterlock, "%s/%s", repository, CVSLCK);
-
- /*
- * Note that it is up to the callers of set_lock() to arrange for signal
- * handlers that do the appropriate things, like remove the lock
- * directory before they exit.
- */
- cleanup_lckdir = 0;
- for (;;)
- {
- int status = -1;
- omask = umask (cvsumask);
- SIG_beginCrSect ();
- if (CVS_MKDIR (masterlock, 0777) == 0)
- {
-#ifdef AFSCVS
- char uidlock[PATH_MAX];
- FILE *fp;
-
- sprintf(uidlock, "%s/uidlock%d", masterlock, geteuid() );
- if ((fp = fopen(uidlock, "w+")) == NULL)
- {
- /* We failed to create the uidlock,
- so rm masterlock and leave */
- rmdir(masterlock);
- SIG_endCrSect ();
- status = L_ERROR;
- goto out;
- }
-
- /* We successfully created the uid lock, so close the file */
- fclose(fp);
-#endif
- cleanup_lckdir = 1;
- SIG_endCrSect ();
- status = L_OK;
- goto out;
- }
- SIG_endCrSect ();
- out:
- (void) umask (omask);
- if (status != -1)
- return status;
-
- if (errno != EEXIST)
- {
- error (0, errno,
- "failed to create lock directory in repository `%s'",
- repository);
- return (L_ERROR);
- }
-
- /*
- * stat the dir - if it is non-existent, re-try the loop since
- * someone probably just removed it (thus releasing the lock)
- */
- if (stat (masterlock, &sb) < 0)
- {
- if (existence_error (errno))
- continue;
-
- error (0, errno, "couldn't stat lock directory `%s'", masterlock);
- return (L_ERROR);
- }
-
-#ifdef CVS_FUDGELOCKS
- /*
- * If the create time of the directory is more than CVSLCKAGE seconds
- * ago, try to clean-up the lock directory, and if successful, just
- * quietly retry to make it.
- */
- (void) time (&now);
- if (now >= (sb.st_ctime + CVSLCKAGE))
- {
-#ifdef AFSCVS
- /* Remove the uidlock first */
- char rmuidlock[PATH_MAX];
- sprintf(rmuidlock, "rm -f %s/uidlock%d", masterlock, geteuid() );
- system(rmuidlock);
-#endif
- if (rmdir (masterlock) >= 0)
- continue;
- }
-#endif
-
- /* set the lockers name */
- set_lockers_name (&sb);
-
- /* if he wasn't willing to wait, return an error */
- if (!will_wait)
- return (L_LOCKED);
- lock_wait (repository);
- }
-}
-
-/*
- * Clear master lock. We don't have to recompute the lock name since
- * clear_lock is never called except after a successful set_lock().
- */
-static void
-clear_lock()
-{
-#ifdef AFSCVS
- /* Remove the uidlock first */
- char rmuidlock[PATH_MAX];
- sprintf(rmuidlock, "rm -f %s/uidlock%d", masterlock, geteuid() );
- system(rmuidlock);
-#endif
- if (rmdir (masterlock) < 0)
- error (0, errno, "failed to remove lock dir `%s'", masterlock);
- cleanup_lckdir = 0;
-}
-
-/*
- * Print out a message that the lock is still held, then sleep a while.
- */
-static void
-lock_wait (repos)
- char *repos;
-{
- time_t now;
-
- (void) time (&now);
- error (0, 0, "[%8.8s] waiting for %s's lock in %s", ctime (&now) + 11,
- lockers_name, repos);
- (void) sleep (CVSLCKSLEEP);
-}
diff --git a/gnu/usr.bin/cvs/cvs/log.c b/gnu/usr.bin/cvs/cvs/log.c
deleted file mode 100644
index 88c9adc73865..000000000000
--- a/gnu/usr.bin/cvs/cvs/log.c
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- * Copyright (c) 1992, Brian Berliner and Jeff Polk
- * Copyright (c) 1989-1992, Brian Berliner
- *
- * You may distribute under the terms of the GNU General Public License as
- * specified in the README file that comes with the CVS 1.4 kit.
- *
- * Print Log Information
- *
- * This line exists solely to test some pcl-cvs/ChangeLog stuff. You
- * can delete it, if indeed it's still here when you read it. -Karl
- *
- * Prints the RCS "log" (rlog) information for the specified files. With no
- * argument, prints the log information for all the files in the directory
- * (recursive by default).
- */
-
-#include "cvs.h"
-
-#ifndef lint
-static const char rcsid[] = "$CVSid: @(#)log.c 1.44 94/09/30 $";
-USE(rcsid);
-#endif
-
-static Dtype log_dirproc PROTO((char *dir, char *repository, char *update_dir));
-static int log_fileproc PROTO((char *file, char *update_dir, char *repository,
- List * entries, List * srcfiles));
-
-static const char *const log_usage[] =
-{
- "Usage: %s %s [-l] [rlog-options] [files...]\n",
- "\t-l\tLocal directory only, no recursion.\n",
- NULL
-};
-
-static int ac;
-static char **av;
-
-int
-cvslog (argc, argv)
- int argc;
- char **argv;
-{
- int i;
- int err = 0;
- int local = 0;
-
- if (argc == -1)
- usage (log_usage);
-
- /*
- * All 'log' command options except -l are passed directly on to 'rlog'
- */
- for (i = 1; i < argc && argv[i][0] == '-'; i++)
- if (argv[i][1] == 'l')
- local = 1;
-
- wrap_setup ();
-
-#ifdef CLIENT_SUPPORT
- if (client_active) {
- /* We're the local client. Fire up the remote server. */
- start_server ();
-
- ign_setup ();
-
- for (i = 1; i < argc && argv[i][0] == '-'; i++)
- send_arg (argv[i]);
-
-#if 0
-/* FIXME: We shouldn't have to send current files to get log entries, but it
- doesn't work yet and I haven't debugged it. So send the files --
- it's slower but it works. gnu@cygnus.com Apr94 */
- send_file_names (argc - i, argv + i);
-#else
- send_files (argc - i, argv + i, local, 0);
-#endif
-
- if (fprintf (to_server, "log\n") < 0)
- error (1, errno, "writing to server");
- err = get_responses_and_close ();
- return err;
- }
-
- ac = argc;
- av = argv;
-#endif
-
- err = start_recursion (log_fileproc, (FILESDONEPROC) NULL, log_dirproc,
- (DIRLEAVEPROC) NULL, argc - i, argv + i, local,
- W_LOCAL | W_REPOS | W_ATTIC, 0, 1,
- (char *) NULL, 1, 0);
- return (err);
-}
-
-
-/*
- * Do an rlog on a file
- */
-/* ARGSUSED */
-static int
-log_fileproc (file, update_dir, repository, entries, srcfiles)
- char *file;
- char *update_dir;
- char *repository;
- List *entries;
- List *srcfiles;
-{
- Node *p;
- RCSNode *rcsfile;
- int retcode = 0;
-
- p = findnode (srcfiles, file);
- if (p == NULL || (rcsfile = (RCSNode *) p->data) == NULL)
- {
- /* no rcs file. What *do* we know about this file? */
- p = findnode (entries, file);
- if (p != NULL)
- {
- Entnode *e;
-
- e = (Entnode *) p->data;
- if (e->version[0] == '0' || e->version[1] == '\0')
- {
- if (!really_quiet)
- error (0, 0, "%s has been added, but not committed",
- file);
- return(0);
- }
- }
-
- if (!really_quiet)
- error (0, 0, "nothing known about %s", file);
-
- return (1);
- }
-
- run_setup ("%s%s", Rcsbin, RCS_RLOG);
- {
- int i;
- for (i = 1; i < ac && av[i][0] == '-'; i++)
- if (av[i][1] != 'l')
- run_arg (av[i]);
- }
- run_arg (rcsfile->path);
-
- if (*update_dir)
- {
- char *workfile = xmalloc (strlen (update_dir) + strlen (file) + 2);
- sprintf (workfile, "%s/%s", update_dir, file);
- run_arg (workfile);
- free (workfile);
- }
-
- if ((retcode = run_exec (RUN_TTY, RUN_TTY, RUN_TTY, RUN_REALLY)) == -1)
- {
- error (1, errno, "fork failed for rlog on %s", file);
- }
- return (retcode);
-}
-
-/*
- * Print a warm fuzzy message
- */
-/* ARGSUSED */
-static Dtype
-log_dirproc (dir, repository, update_dir)
- char *dir;
- char *repository;
- char *update_dir;
-{
- if (!isdir (dir))
- return (R_SKIP_ALL);
-
- if (!quiet)
- error (0, 0, "Logging %s", update_dir);
- return (R_PROCESS);
-}
diff --git a/gnu/usr.bin/cvs/cvs/login.c b/gnu/usr.bin/cvs/cvs/login.c
deleted file mode 100644
index ccb757ca3452..000000000000
--- a/gnu/usr.bin/cvs/cvs/login.c
+++ /dev/null
@@ -1,287 +0,0 @@
-/*
- * Copyright (c) 1995, Cyclic Software, Bloomington, IN, USA
- *
- * You may distribute under the terms of the GNU General Public License as
- * specified in the README file that comes with CVS.
- *
- * Allow user to log in for an authenticating server.
- */
-
-#include "cvs.h"
-
-#ifdef AUTH_CLIENT_SUPPORT /* This covers the rest of the file. */
-
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <netdb.h>
-
-#ifndef lint
-static const char rcsid[] = "$CVSid: @(#)login.c 1.1 95/10/01 $";
-USE(rcsid);
-#endif
-
-#ifndef CVS_PASSWORD_FILE
-#define CVS_PASSWORD_FILE ".cvspass"
-#endif
-
-
-/* The return value will need to be freed. */
-char *
-construct_cvspass_filename ()
-{
- char *homedir;
- char *passfile;
-
- /* Construct absolute pathname to user's password file. */
- /* todo: does this work under Win-NT and OS/2 ? */
- homedir = getenv ("HOME");
- if (! homedir)
- {
- error (1, errno, "could not find out home directory");
- return (char *) NULL;
- }
-
- passfile =
- (char *) xmalloc (strlen (homedir) + strlen (CVS_PASSWORD_FILE) + 3);
- strcpy (passfile, homedir);
- strcat (passfile, "/");
- strcat (passfile, CVS_PASSWORD_FILE);
-
- /* Safety first and last, Scouts. */
- if (isfile (passfile))
- /* xchmod() is too polite. */
- chmod (passfile, 0600);
-
- return passfile;
-}
-
-
-/* Prompt for a password, and store it in the file "CVS/.cvspass".
- *
- * Because the user might be accessing multiple repositories, with
- * different passwords for each one, the format of ~/.cvspass is:
- *
- * user@host:/path cleartext_password
- * user@host:/path cleartext_password
- * ...
- *
- * Of course, the "user@" might be left off -- it's just based on the
- * value of CVSroot.
- *
- * Like .netrc, the file's permissions are the only thing preventing
- * it from being read by others. Unlike .netrc, we will not be
- * fascist about it, at most issuing a warning, and never refusing to
- * work.
- */
-int
-login (argc, argv)
- int argc;
- char **argv;
-{
- char *username;
- int i;
- char *passfile;
- FILE *fp;
- char *typed_password, *found_password;
- char linebuf[MAXLINELEN];
- int root_len, already_entered = 0;
-
- /* Make this a "fully-qualified" CVSroot if necessary. */
- if (! strchr (CVSroot, '@'))
- {
- /* We need to prepend "user@host:". */
- char *tmp;
-
- printf ("Repository \"%s\" not fully-qualified.\n", CVSroot);
- printf ("Please enter \"user@host:/path\": ");
- fflush (stdout);
- fgets (linebuf, MAXLINELEN, stdin);
-
- tmp = xmalloc (strlen (linebuf) + 1);
-
- strcpy (tmp, linebuf);
- tmp[strlen (linebuf) - 1] = '\0';
- CVSroot = tmp;
- }
-
- /* Check to make sure it's fully-qualified before going on. */
- if (! CVSroot)
- {
- error (1, 0, "CVSroot is NULL");
- }
- else if ((! strchr (CVSroot, '@')) && (! strchr (CVSroot, ':')))
- {
- error (1, 0, "CVSroot not fully-qualified: %s", CVSroot);
- }
-
-
- passfile = construct_cvspass_filename ();
- typed_password = getpass ("Enter CVS password: ");
-
- /* IF we have a password for this "[user@]host:/path" already
- * THEN
- * IF it's the same as the password we read from the prompt
- * THEN
- * do nothing
- * ELSE
- * replace the old password with the new one
- * ELSE
- * append new entry to the end of the file.
- */
-
- root_len = strlen (CVSroot);
-
- /* Yes, the method below reads the user's password file twice. It's
- inefficient, but we're not talking about a gig of data here. */
-
- fp = fopen (passfile, "r");
- if (fp == NULL)
- {
- error (1, errno, "unable to open %s", passfile);
- return 1;
- }
-
- /* Check each line to see if we have this entry already. */
- while (fgets (linebuf, MAXLINELEN, fp) != NULL)
- {
- if (! strncmp (CVSroot, linebuf, root_len))
- {
- already_entered = 1;
- break;
- }
- }
- fclose (fp);
-
-
- if (already_entered)
- {
- /* This user/host has a password in the file already. */
-
- /* todo: what about these charsets??? */
- strtok (linebuf, " \n");
- found_password = strtok (NULL, " \n");
- if (strcmp (found_password, typed_password))
- {
- /* typed_password and found_password don't match, so we'll
- * have to update passfile. We replace the old password
- * with the new one by writing a tmp file whose contents are
- * exactly the same as passfile except that this one entry
- * gets typed_password instead of found_password. Then we
- * rename the tmp file on top of passfile.
- */
- char *tmp_name;
- FILE *tmp_fp;
-
- tmp_name = tmpnam (NULL);
- if ((tmp_fp = fopen (tmp_name, "w")) == NULL)
- {
- error (1, errno, "unable to open temp file %s", tmp_name);
- return 1;
- }
- chmod (tmp_name, 0600);
-
- fp = fopen (passfile, "r");
- if (fp == NULL)
- {
- error (1, errno, "unable to open %s", passfile);
- return 1;
- }
- /* I'm not paranoid, they really ARE out to get me: */
- chmod (passfile, 0600);
-
- while (fgets (linebuf, MAXLINELEN, fp) != NULL)
- {
- if (strncmp (CVSroot, linebuf, root_len))
- fprintf (tmp_fp, "%s", linebuf);
- else
- fprintf (tmp_fp, "%s %s\n", CVSroot, typed_password);
- }
- fclose (tmp_fp);
- fclose (fp);
- rename_file (tmp_name, passfile);
- chmod (passfile, 0600);
- }
- }
- else
- {
- if ((fp = fopen (passfile, "a")) == NULL)
- {
- error (1, errno, "could not open %s", passfile);
- free (passfile);
- return 1;
- }
-
- /* It's safer this way, and blank lines in the file are OK. */
- fprintf (fp, "\n%s %s\n", CVSroot, typed_password);
- fclose (fp);
- }
-
- /* Utter, total, raving paranoia, I know. */
- chmod (passfile, 0600);
- memset (typed_password, 0, strlen (typed_password));
-
- free (passfile);
- return 0;
-}
-
-/* todo: "cvs logout" could erase an entry from the file.
- * But to what purpose?
- */
-
-
-char *
-get_cvs_password (user, host, cvsroot)
-{
- int root_len;
- int found_it = 0;
- char *password;
- char linebuf[MAXLINELEN];
- FILE *fp;
- char *passfile;
-
- passfile = construct_cvspass_filename ();
- fp = fopen (passfile, "r");
- if (fp == NULL)
- {
- error (0, errno, "could not open %s", passfile);
- free (passfile);
- goto prompt_for_it;
- }
-
- root_len = strlen (CVSroot);
-
- /* Check each line to see if we have this entry already. */
- while (fgets (linebuf, MAXLINELEN, fp) != NULL)
- {
- if (strncmp (CVSroot, linebuf, root_len) == 0)
- {
- /* This is it! So break out and deal with linebuf. */
- found_it = 1;
- break;
- }
- }
-
- if (found_it)
- {
- /* linebuf now contains the line with the password. */
- char *tmp;
-
- strtok (linebuf, " ");
- password = strtok (NULL, "\n");
-
- /* Give it permanent storage. */
- tmp = xmalloc (strlen (password) + 1);
- strcpy (tmp, password);
- tmp[strlen (password)] = '\0';
- memset (password, 0, strlen (password));
- return tmp;
- }
- else
- {
- prompt_for_it:
- return getpass ("CVS password: ");
- }
-}
-
-#endif /* AUTH_CLIENT_SUPPORT from beginning of file. */
-
diff --git a/gnu/usr.bin/cvs/cvs/logmsg.c b/gnu/usr.bin/cvs/cvs/logmsg.c
deleted file mode 100644
index 5f2763fcce5f..000000000000
--- a/gnu/usr.bin/cvs/cvs/logmsg.c
+++ /dev/null
@@ -1,486 +0,0 @@
-/*
- * Copyright (c) 1992, Brian Berliner and Jeff Polk
- * Copyright (c) 1989-1992, Brian Berliner
- *
- * You may distribute under the terms of the GNU General Public License as
- * specified in the README file that comes with the CVS 1.4 kit.
- */
-
-#include "cvs.h"
-#include "getline.h"
-
-#ifndef lint
-static const char rcsid[] = "$CVSid: @(#)logmsg.c 1.48 94/09/29 $";
-USE(rcsid);
-#endif
-
-static int find_type PROTO((Node * p, void *closure));
-static int fmt_proc PROTO((Node * p, void *closure));
-static int logfile_write PROTO((char *repository, char *filter, char *title,
- char *message, char *revision, FILE * logfp,
- List * changes));
-static int rcsinfo_proc PROTO((char *repository, char *template));
-static int title_proc PROTO((Node * p, void *closure));
-static int update_logfile_proc PROTO((char *repository, char *filter));
-static void setup_tmpfile PROTO((FILE * xfp, char *xprefix, List * changes));
-static int editinfo_proc PROTO((char *repository, char *template));
-
-static FILE *fp;
-static char *str_list;
-static char *editinfo_editor;
-static Ctype type;
-
-/*
- * Puts a standard header on the output which is either being prepared for an
- * editor session, or being sent to a logfile program. The modified, added,
- * and removed files are included (if any) and formatted to look pretty. */
-static char *prefix;
-static int col;
-static void
-setup_tmpfile (xfp, xprefix, changes)
- FILE *xfp;
- char *xprefix;
- List *changes;
-{
- /* set up statics */
- fp = xfp;
- prefix = xprefix;
-
- type = T_MODIFIED;
- if (walklist (changes, find_type, NULL) != 0)
- {
- (void) fprintf (fp, "%sModified Files:\n", prefix);
- (void) fprintf (fp, "%s\t", prefix);
- col = 8;
- (void) walklist (changes, fmt_proc, NULL);
- (void) fprintf (fp, "\n");
- }
- type = T_ADDED;
- if (walklist (changes, find_type, NULL) != 0)
- {
- (void) fprintf (fp, "%sAdded Files:\n", prefix);
- (void) fprintf (fp, "%s\t", prefix);
- col = 8;
- (void) walklist (changes, fmt_proc, NULL);
- (void) fprintf (fp, "\n");
- }
- type = T_REMOVED;
- if (walklist (changes, find_type, NULL) != 0)
- {
- (void) fprintf (fp, "%sRemoved Files:\n", prefix);
- (void) fprintf (fp, "%s\t", prefix);
- col = 8;
- (void) walklist (changes, fmt_proc, NULL);
- (void) fprintf (fp, "\n");
- }
-}
-
-/*
- * Looks for nodes of a specified type and returns 1 if found
- */
-static int
-find_type (p, closure)
- Node *p;
- void *closure;
-{
- if (p->data == (char *) type)
- return (1);
- else
- return (0);
-}
-
-/*
- * Breaks the files list into reasonable sized lines to avoid line wrap...
- * all in the name of pretty output. It only works on nodes whose types
- * match the one we're looking for
- */
-static int
-fmt_proc (p, closure)
- Node *p;
- void *closure;
-{
- if (p->data == (char *) type)
- {
- if ((col + (int) strlen (p->key)) > 70)
- {
- (void) fprintf (fp, "\n%s\t", prefix);
- col = 8;
- }
- (void) fprintf (fp, "%s ", p->key);
- col += strlen (p->key) + 1;
- }
- return (0);
-}
-
-/*
- * Builds a temporary file using setup_tmpfile() and invokes the user's
- * editor on the file. The header garbage in the resultant file is then
- * stripped and the log message is stored in the "message" argument.
- *
- * rcsinfo - is the name of a file containing lines tacked onto the end of the
- * RCS info offered to the user for editing. If specified, the '-m' flag to
- * "commit" is disabled -- users are forced to run the editor.
- *
- */
-void
-do_editor (dir, messagep, repository, changes)
- char *dir;
- char **messagep;
- char *repository;
- List *changes;
-{
- static int reuse_log_message = 0;
- char *line;
- int line_length;
- size_t line_chars_allocated;
- char fname[L_tmpnam+1];
- struct stat pre_stbuf, post_stbuf;
- int retcode = 0;
- char *p;
-
- if (noexec || reuse_log_message)
- return;
-
- /* Create a temporary file */
- (void) tmpnam (fname);
- again:
- if ((fp = fopen (fname, "w+")) == NULL)
- error (1, 0, "cannot create temporary file %s", fname);
-
- if (*messagep)
- {
- (void) fprintf (fp, "%s", *messagep);
-
- if ((*messagep)[strlen (*messagep) - 1] != '\n')
- (void) fprintf (fp, "\n");
- }
- else
- (void) fprintf (fp, "\n");
-
- if (repository != NULL)
- /* tack templates on if necessary */
- (void) Parse_Info (CVSROOTADM_RCSINFO, repository, rcsinfo_proc, 1);
-
- (void) fprintf (fp,
- "%s----------------------------------------------------------------------\n",
- CVSEDITPREFIX);
- (void) fprintf (fp,
- "%sEnter Log. Lines beginning with `%s' are removed automatically\n%s\n",
- CVSEDITPREFIX, CVSEDITPREFIX, CVSEDITPREFIX);
- if (dir != NULL && *dir)
- (void) fprintf (fp, "%sCommitting in %s\n%s\n", CVSEDITPREFIX,
- dir, CVSEDITPREFIX);
- if (changes != NULL)
- setup_tmpfile (fp, CVSEDITPREFIX, changes);
- (void) fprintf (fp,
- "%s----------------------------------------------------------------------\n",
- CVSEDITPREFIX);
-
- /* finish off the temp file */
- if (fclose (fp) == EOF)
- error (1, errno, "%s", fname);
- if (stat (fname, &pre_stbuf) == -1)
- pre_stbuf.st_mtime = 0;
-
- if (editinfo_editor)
- free (editinfo_editor);
- editinfo_editor = (char *) NULL;
- if (repository != NULL)
- (void) Parse_Info (CVSROOTADM_EDITINFO, repository, editinfo_proc, 0);
-
- /* run the editor */
- run_setup ("%s", editinfo_editor ? editinfo_editor : Editor);
- run_arg (fname);
- if ((retcode = run_exec (RUN_TTY, RUN_TTY, RUN_TTY,
- RUN_NORMAL | RUN_SIGIGNORE)) != 0)
- error (editinfo_editor ? 1 : 0, retcode == -1 ? errno : 0,
- editinfo_editor ? "Logfile verification failed" :
- "warning: editor session failed");
-
- /* put the entire message back into the *messagep variable */
-
- fp = open_file (fname, "r");
-
- if (*messagep)
- free (*messagep);
-
- if (stat (fname, &post_stbuf) != 0)
- error (1, errno, "cannot find size of temp file %s", fname);
-
- if (post_stbuf.st_size == 0)
- *messagep = NULL;
- else
- {
- *messagep = (char *) xmalloc (post_stbuf.st_size + 1);
- *messagep[0] = '\0';
- }
-
- line = NULL;
- line_chars_allocated = 0;
-
- if (*messagep)
- {
- p = *messagep;
- while (1)
- {
- line_length = getline (&line, &line_chars_allocated, fp);
- if (line_length == -1)
- {
- if (ferror (fp))
- error (0, errno, "warning: cannot read %s", fname);
- break;
- }
- if (strncmp (line, CVSEDITPREFIX, sizeof (CVSEDITPREFIX) - 1) == 0)
- continue;
- (void) strcpy (p, line);
- p += line_length;
- }
- }
- if (fclose (fp) < 0)
- error (0, errno, "warning: cannot close %s", fname);
-
- if (pre_stbuf.st_mtime == post_stbuf.st_mtime ||
- *messagep == NULL ||
- strcmp (*messagep, "\n") == 0)
- {
- for (;;)
- {
- (void) printf ("\nLog message unchanged or not specified\n");
- (void) printf ("a)bort, c)ontinue, e)dit, !)reuse this message unchanged for remaining dirs\n");
- (void) printf ("Action: (continue) ");
- (void) fflush (stdout);
- line_length = getline (&line, &line_chars_allocated, stdin);
- if (line_length <= 0
- || *line == '\n' || *line == 'c' || *line == 'C')
- break;
- if (*line == 'a' || *line == 'A')
- error (1, 0, "aborted by user");
- if (*line == 'e' || *line == 'E')
- goto again;
- if (*line == '!')
- {
- reuse_log_message = 1;
- break;
- }
- (void) printf ("Unknown input\n");
- }
- }
- if (line)
- free (line);
- if (unlink_file (fname) < 0)
- error (0, errno, "warning: cannot remove temp file %s", fname);
-}
-
-/*
- * callback proc for Parse_Info for rcsinfo templates this routine basically
- * copies the matching template onto the end of the tempfile we are setting
- * up
- */
-/* ARGSUSED */
-static int
-rcsinfo_proc (repository, template)
- char *repository;
- char *template;
-{
- static char *last_template;
- FILE *tfp;
-
- /* nothing to do if the last one included is the same as this one */
- if (last_template && strcmp (last_template, template) == 0)
- return (0);
- if (last_template)
- free (last_template);
- last_template = xstrdup (template);
-
- if ((tfp = fopen (template, "r")) != NULL)
- {
- char *line;
- size_t line_chars_allocated;
-
- while (getline (&line, &line_chars_allocated, tfp) >= 0)
- (void) fputs (line, fp);
- if (ferror (tfp))
- error (0, errno, "warning: cannot read %s", template);
- if (fclose (tfp) < 0)
- error (0, errno, "warning: cannot close %s", template);
- if (line)
- free (line);
- return (0);
- }
- else
- {
- error (0, errno, "Couldn't open rcsinfo template file %s", template);
- return (1);
- }
-}
-
-/*
- * Uses setup_tmpfile() to pass the updated message on directly to any
- * logfile programs that have a regular expression match for the checked in
- * directory in the source repository. The log information is fed into the
- * specified program as standard input.
- */
-static char *title;
-static FILE *logfp;
-static char *message;
-static char *revision;
-static List *changes;
-
-void
-Update_Logfile (repository, xmessage, xrevision, xlogfp, xchanges)
- char *repository;
- char *xmessage;
- char *xrevision;
- FILE *xlogfp;
- List *xchanges;
-{
- char *srepos;
-
- /* nothing to do if the list is empty */
- if (xchanges == NULL || xchanges->list->next == xchanges->list)
- return;
-
- /* set up static vars for update_logfile_proc */
- message = xmessage;
- revision = xrevision;
- logfp = xlogfp;
- changes = xchanges;
-
- /* figure out a good title string */
- srepos = Short_Repository (repository);
-
- /* allocate a chunk of memory to hold the title string */
- if (!str_list)
- str_list = xmalloc (MAXLISTLEN);
- str_list[0] = '\0';
-
- type = T_TITLE;
- (void) walklist (changes, title_proc, NULL);
- type = T_ADDED;
- (void) walklist (changes, title_proc, NULL);
- type = T_MODIFIED;
- (void) walklist (changes, title_proc, NULL);
- type = T_REMOVED;
- (void) walklist (changes, title_proc, NULL);
- title = xmalloc (strlen (srepos) + strlen (str_list) + 1 + 2); /* for 's */
- (void) sprintf (title, "'%s%s'", srepos, str_list);
-
- /* to be nice, free up this chunk of memory */
- free (str_list);
- str_list = (char *) NULL;
-
- /* call Parse_Info to do the actual logfile updates */
- (void) Parse_Info (CVSROOTADM_LOGINFO, repository, update_logfile_proc, 1);
-
- /* clean up */
- free (title);
-}
-
-/*
- * callback proc to actually do the logfile write from Update_Logfile
- */
-static int
-update_logfile_proc (repository, filter)
- char *repository;
- char *filter;
-{
- return (logfile_write (repository, filter, title, message, revision,
- logfp, changes));
-}
-
-/*
- * concatenate each name onto str_list
- */
-static int
-title_proc (p, closure)
- Node *p;
- void *closure;
-{
- if (p->data == (char *) type)
- {
- (void) strcat (str_list, " ");
- (void) strcat (str_list, p->key);
- }
- return (0);
-}
-
-/*
- * Since some systems don't define this...
- */
-#ifndef MAXHOSTNAMELEN
-#define MAXHOSTNAMELEN 256
-#endif
-
-/*
- * Writes some stuff to the logfile "filter" and returns the status of the
- * filter program.
- */
-static int
-logfile_write (repository, filter, title, message, revision, logfp, changes)
- char *repository;
- char *filter;
- char *title;
- char *message;
- char *revision;
- FILE *logfp;
- List *changes;
-{
- char cwd[PATH_MAX];
- FILE *pipefp, *Popen ();
- char *prog = xmalloc (MAXPROGLEN);
- char *cp;
- int c;
-
- /* XXX <woods@web.net> -- this is gross, ugly, and a hack! FIXME! */
- /*
- * A maximum of 6 %s arguments are supported in the filter
- */
- (void) sprintf (prog, filter, title, title, title, title, title, title);
- if ((pipefp = Popen (prog, "w")) == NULL)
- {
- if (!noexec)
- error (0, 0, "cannot write entry to log filter: %s", prog);
- free (prog);
- return (1);
- }
- (void) fprintf (pipefp, "Update of %s\n", repository);
- (void) fprintf (pipefp, "In directory %s:%s\n\n", hostname,
- ((cp = getwd (cwd)) != NULL) ? cp : cwd);
- if (revision && *revision)
- (void) fprintf (pipefp, "Revision/Branch: %s\n\n", revision);
- setup_tmpfile (pipefp, "", changes);
- (void) fprintf (pipefp, "Log Message:\n%s\n", message);
- if (logfp != (FILE *) 0)
- {
- (void) fprintf (pipefp, "Status:\n");
- rewind (logfp);
- while ((c = getc (logfp)) != EOF)
- (void) putc ((char) c, pipefp);
- }
- free (prog);
- return (pclose (pipefp));
-}
-
-/*
- * We choose to use the *last* match within the editinfo file for this
- * repository. This allows us to have a global editinfo program for the
- * root of some hierarchy, for example, and different ones within different
- * sub-directories of the root (like a special checker for changes made to
- * the "src" directory versus changes made to the "doc" or "test"
- * directories.
- */
-/* ARGSUSED */
-static int
-editinfo_proc(repository, editor)
- char *repository;
- char *editor;
-{
- /* nothing to do if the last match is the same as this one */
- if (editinfo_editor && strcmp (editinfo_editor, editor) == 0)
- return (0);
- if (editinfo_editor)
- free (editinfo_editor);
-
- editinfo_editor = xstrdup (editor);
- return (0);
-}
diff --git a/gnu/usr.bin/cvs/cvs/main.c b/gnu/usr.bin/cvs/cvs/main.c
deleted file mode 100644
index 91e376d63fc0..000000000000
--- a/gnu/usr.bin/cvs/cvs/main.c
+++ /dev/null
@@ -1,769 +0,0 @@
-/*
- * Copyright (c) 1992, Brian Berliner and Jeff Polk
- * Copyright (c) 1989-1992, Brian Berliner
- *
- * You may distribute under the terms of the GNU General Public License
- * as specified in the README file that comes with the CVS 1.4 kit.
- *
- * This is the main C driver for the CVS system.
- *
- * Credit to Dick Grune, Vrije Universiteit, Amsterdam, for writing
- * the shell-script CVS system that this is based on.
- *
- * Usage:
- * cvs [options] command [options] [files/modules...]
- *
- * Where "command" is composed of:
- * admin RCS command
- * checkout Check out a module/dir/file
- * export Like checkout, but used for exporting sources
- * update Brings work tree in sync with repository
- * commit Checks files into the repository
- * diff Runs diffs between revisions
- * log Prints "rlog" information for files
- * login Record user, host, repos, password
- * add Adds an entry to the repository
- * remove Removes an entry from the repository
- * status Status info on the revisions
- * rdiff "patch" format diff listing between releases
- * tag Add/delete a symbolic tag to the RCS file
- * rtag Add/delete a symbolic tag to the RCS file
- * import Import sources into CVS, using vendor branches
- * release Indicate that Module is no longer in use.
- * history Display history of Users and Modules.
- */
-
-#include "cvs.h"
-#include "patchlevel.h"
-
-#if HAVE_KERBEROS
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <krb.h>
-#ifndef HAVE_KRB_GET_ERR_TEXT
-#define krb_get_err_text(status) krb_err_txt[status]
-#endif
-#endif
-
-#ifndef lint
-static const char rcsid[] = "$CVSid: @(#)main.c 1.78 94/10/07 $\n";
-USE(rcsid);
-#endif
-
-char *program_name;
-char *program_path;
-/*
- * Initialize comamnd_name to "cvs" so that the first call to
- * read_cvsrc tries to find global cvs options.
- */
-char *command_name = "cvs";
-
-/*
- * Since some systems don't define this...
- */
-#ifndef MAXHOSTNAMELEN
-#define MAXHOSTNAMELEN 256
-#endif
-
-char hostname[MAXHOSTNAMELEN];
-
-#ifdef AUTH_CLIENT_SUPPORT
-int use_authenticating_server = FALSE;
-#endif /* AUTH_CLIENT_SUPPORT */
-int use_editor = TRUE;
-int use_cvsrc = TRUE;
-int cvswrite = !CVSREAD_DFLT;
-int really_quiet = FALSE;
-int quiet = FALSE;
-int trace = FALSE;
-int noexec = FALSE;
-int logoff = FALSE;
-mode_t cvsumask = UMASK_DFLT;
-
-char *CurDir;
-
-/*
- * Defaults, for the environment variables that are not set
- */
-char *Rcsbin = RCSBIN_DFLT;
-char *Editor = EDITOR_DFLT;
-char *CVSroot = CVSROOT_DFLT;
-#ifdef CVSADM_ROOT
-/*
- * The path found in CVS/Root must match $CVSROOT and/or 'cvs -d root'
- */
-char *CVSADM_Root = CVSROOT_DFLT;
-#endif /* CVSADM_ROOT */
-
-int add PROTO((int argc, char **argv));
-int admin PROTO((int argc, char **argv));
-int checkout PROTO((int argc, char **argv));
-int commit PROTO((int argc, char **argv));
-int diff PROTO((int argc, char **argv));
-int history PROTO((int argc, char **argv));
-int import PROTO((int argc, char **argv));
-int cvslog PROTO((int argc, char **argv));
-#ifdef AUTH_CLIENT_SUPPORT
-int login PROTO((int argc, char **argv));
-#endif /* AUTH_CLIENT_SUPPORT */
-int patch PROTO((int argc, char **argv));
-int release PROTO((int argc, char **argv));
-int cvsremove PROTO((int argc, char **argv));
-int rtag PROTO((int argc, char **argv));
-int status PROTO((int argc, char **argv));
-int tag PROTO((int argc, char **argv));
-int update PROTO((int argc, char **argv));
-
-const struct cmd
-{
- char *fullname; /* Full name of the function (e.g. "commit") */
- char *nick1; /* alternate name (e.g. "ci") */
- char *nick2; /* another alternate names (e.g. "ci") */
- int (*func) (); /* Function takes (argc, argv) arguments. */
-#ifdef CLIENT_SUPPORT
- int (*client_func) (); /* Function to do it via the protocol. */
-#endif
-} cmds[] =
-
-{
-#ifdef CLIENT_SUPPORT
-#define CMD_ENTRY(n1, n2, n3, f1, f2) { n1, n2, n3, f1, f2 }
-#else
-#define CMD_ENTRY(n1, n2, n3, f1, f2) { n1, n2, n3, f1 }
-#endif
-
- CMD_ENTRY("add", "ad", "new", add, client_add),
-#ifndef CVS_NOADMIN
- CMD_ENTRY("admin", "adm", "rcs", admin, client_admin),
-#endif
- CMD_ENTRY("checkout", "co", "get", checkout, client_checkout),
- CMD_ENTRY("commit", "ci", "com", commit, client_commit),
- CMD_ENTRY("diff", "di", "dif", diff, client_diff),
- CMD_ENTRY("export", "exp", "ex", checkout, client_export),
- CMD_ENTRY("history", "hi", "his", history, client_history),
- CMD_ENTRY("import", "im", "imp", import, client_import),
- CMD_ENTRY("log", "lo", "rlog", cvslog, client_log),
-#ifdef AUTH_CLIENT_SUPPORT
- CMD_ENTRY("login", "logon", "lgn", login, login),
-#endif /* AUTH_CLIENT_SUPPORT */
- CMD_ENTRY("rdiff", "patch", "pa", patch, client_rdiff),
- CMD_ENTRY("release", "re", "rel", release, client_release),
- CMD_ENTRY("remove", "rm", "delete", cvsremove, client_remove),
- CMD_ENTRY("status", "st", "stat", status, client_status),
- CMD_ENTRY("rtag", "rt", "rfreeze", rtag, client_rtag),
- CMD_ENTRY("tag", "ta", "freeze", tag, client_tag),
- CMD_ENTRY("update", "up", "upd", update, client_update),
-
-#ifdef SERVER_SUPPORT
- /*
- * The client_func is also server because we might have picked up a
- * CVSROOT environment variable containing a colon. The client will send
- * the real root later.
- */
- CMD_ENTRY("server", "server", "server", server, server),
-#endif
- CMD_ENTRY(NULL, NULL, NULL, NULL, NULL),
-
-#undef CMD_ENTRY
-};
-
-static const char *const usg[] =
-{
- "Usage: %s [cvs-options] command [command-options] [files...]\n",
- " Where 'cvs-options' are:\n",
- " -H Displays Usage information for command\n",
- " -Q Cause CVS to be really quiet.\n",
- " -q Cause CVS to be somewhat quiet.\n",
-#ifdef AUTH_CLIENT_SUPPORT
- " -a Use the authenticating server, not rsh.\n",
-#endif /* AUTH_CLIENT_SUPPORT */
- " -r Make checked-out files read-only\n",
- " -w Make checked-out files read-write (default)\n",
- " -l Turn History logging off\n",
- " -n Do not execute anything that will change the disk\n",
- " -t Show trace of program execution -- Try with -n\n",
- " -v CVS version and copyright\n",
- " -b bindir Find RCS programs in 'bindir'\n",
- " -e editor Use 'editor' for editing log information\n",
- " -d CVS_root Overrides $CVSROOT as the root of the CVS tree\n",
- " -f Do not use the ~/.cvsrc file\n",
-#ifdef CLIENT_SUPPORT
- " -z # Use 'gzip -#' for net traffic if possible.\n",
-#endif
- "\n",
- " and where 'command' is:\n",
- " add Adds a new file/directory to the repository\n",
- " admin Administration front end for rcs\n",
- " checkout Checkout sources for editing\n",
- " commit Checks files into the repository\n",
- " diff Runs diffs between revisions\n",
- " history Shows status of files and users\n",
- " import Import sources into CVS, using vendor branches\n",
- " export Export sources from CVS, similar to checkout\n",
- " log Prints out 'rlog' information for files\n",
-#ifdef AUTH_CLIENT_SUPPORT
- " login Prompt for password for authenticating server.\n",
-#endif /* AUTH_CLIENT_SUPPORT */
- " rdiff 'patch' format diffs between releases\n",
- " release Indicate that a Module is no longer in use\n",
- " remove Removes an entry from the repository\n",
- " status Status info on the revisions\n",
- " tag Add a symbolic tag to checked out version of RCS file\n",
- " rtag Add a symbolic tag to the RCS file\n",
- " update Brings work tree in sync with repository\n",
- NULL,
-};
-
-static RETSIGTYPE
-main_cleanup ()
-{
- exit (1);
-}
-
-static void
-error_cleanup ()
-{
- Lock_Cleanup();
-#ifdef SERVER_SUPPORT
- if (server_active)
- server_cleanup (0);
-#endif
-}
-
-int
-main (argc, argv)
- int argc;
- char **argv;
-{
- extern char *version_string;
- extern char *config_string;
- char *cp, *end;
- const struct cmd *cm;
- int c, err = 0;
- static int help = FALSE, version_flag = FALSE;
- int rcsbin_update_env, cvs_update_env = 0;
- char tmp[PATH_MAX];
- static struct option long_options[] =
- {
- {"help", 0, &help, TRUE},
- {"version", 0, &version_flag, TRUE},
- {0, 0, 0, 0}
- };
- /* `getopt_long' stores the option index here, but right now we
- don't use it. */
- int option_index = 0;
-
- error_set_cleanup (error_cleanup);
-
-/* The IBM TCP/IP library under OS/2 needs to be initialized: */
-#ifdef NEED_CALL_SOCKINIT
- if (SockInit () != TRUE)
- {
- fprintf (stderr, "SockInit() failed!\n");
- exit (1);
- }
-#endif /* NEED_CALL_SOCKINIT */
-
- /*
- * Just save the last component of the path for error messages
- */
- program_path = xstrdup (argv[0]);
- program_name = last_component (argv[0]);
-
- CurDir = xmalloc (PATH_MAX);
-#ifndef SERVER_SUPPORT
- if (!getwd (CurDir))
- error (1, 0, "cannot get working directory: %s", CurDir);
-#endif
-
- /*
- * Query the environment variables up-front, so that
- * they can be overridden by command line arguments
- */
- rcsbin_update_env = *Rcsbin; /* RCSBIN_DFLT must be set */
- cvs_update_env = 0;
- if ((cp = getenv (RCSBIN_ENV)) != NULL)
- {
- Rcsbin = cp;
- rcsbin_update_env = 0; /* it's already there */
- }
- if ((cp = getenv (EDITOR1_ENV)) != NULL)
- Editor = cp;
- else if ((cp = getenv (EDITOR2_ENV)) != NULL)
- Editor = cp;
- else if ((cp = getenv (EDITOR3_ENV)) != NULL)
- Editor = cp;
- if ((cp = getenv (CVSROOT_ENV)) != NULL)
- {
- CVSroot = cp;
- cvs_update_env = 0; /* it's already there */
- }
- if (getenv (CVSREAD_ENV) != NULL)
- cvswrite = FALSE;
- if ((cp = getenv (CVSUMASK_ENV)) != NULL)
- {
- /* FIXME: Should be accepting symbolic as well as numeric mask. */
- cvsumask = strtol (cp, &end, 8) & 0777;
- if (*end != '\0')
- error (1, errno, "invalid umask value in %s (%s)",
- CVSUMASK_ENV, cp);
- }
-
- /*
- * Scan cvsrc file for global options.
- */
- read_cvsrc(&argc, &argv);
-
- /* This has the effect of setting getopt's ordering to REQUIRE_ORDER,
- which is what we need to distinguish between global options and
- command options. FIXME: It would appear to be possible to do this
- much less kludgily by passing "+" as the first character to the
- option string we pass to getopt_long. */
- optind = 1;
-
- while ((c = getopt_long
- (argc, argv, "Qqrawtnlvb:e:d:Hfz:", long_options, &option_index))
- != EOF)
- {
- switch (c)
- {
- case 0:
- /* getopt_long took care of setting the flag. */
- break;
- case 'Q':
- really_quiet = TRUE;
- /* FALL THROUGH */
- case 'q':
- quiet = TRUE;
- break;
- case 'r':
- cvswrite = FALSE;
- break;
-#ifdef AUTH_CLIENT_SUPPORT
- case 'a':
- use_authenticating_server = TRUE;
- break;
-#endif /* AUTH_CLIENT_SUPPORT */
- case 'w':
- cvswrite = TRUE;
- break;
- case 't':
- trace = TRUE;
- break;
- case 'n':
- noexec = TRUE;
- case 'l': /* Fall through */
- logoff = TRUE;
- break;
- case 'v':
- version_flag = TRUE;
- break;
- case 'b':
- Rcsbin = optarg;
- rcsbin_update_env = 1; /* need to update environment */
- break;
- case 'e':
- Editor = optarg;
- break;
- case 'd':
- CVSroot = optarg;
- cvs_update_env = 1; /* need to update environment */
- break;
- case 'H':
- use_cvsrc = FALSE; /* this ensure that cvs -H works */
- help = TRUE;
- break;
- case 'f':
- use_cvsrc = FALSE;
- break;
-#ifdef CLIENT_SUPPORT
- case 'z':
- gzip_level = atoi (optarg);
- if (gzip_level <= 0 || gzip_level > 9)
- error (1, 0,
- "gzip compression level must be between 1 and 9");
- break;
-#endif
- case '?':
- default:
- usage (usg);
- }
- }
-
- if (version_flag == TRUE)
- {
- (void) fputs (version_string, stdout);
- (void) fputs (config_string, stdout);
- (void) sprintf (tmp, "Patch Level: %d\n", PATCHLEVEL);
- (void) fputs (tmp, stdout);
- (void) fputs ("\n", stdout);
- (void) fputs ("Copyright (c) 1993-1994 Brian Berliner\n", stdout);
- (void) fputs ("Copyright (c) 1993-1994 david d `zoo' zuhn\n", stdout);
- (void) fputs ("Copyright (c) 1992, Brian Berliner and Jeff Polk\n", stdout);
- (void) fputs ("Copyright (c) 1989-1992, Brian Berliner\n", stdout);
- (void) fputs ("\n", stdout);
- (void) fputs ("CVS may be copied only under the terms of the GNU General Public License,\n", stdout);
- (void) fputs ("a copy of which can be found with the CVS distribution kit.\n", stdout);
- exit (0);
- }
-
- argc -= optind;
- argv += optind;
- if (argc < 1)
- usage (usg);
-
-#ifdef HAVE_KERBEROS
- /* If we are invoked with a single argument "kserver", then we are
- running as Kerberos server as root. Do the authentication as
- the very first thing, to minimize the amount of time we are
- running as root. */
- if (strcmp (argv[0], "kserver") == 0)
- {
- int status;
- char instance[INST_SZ];
- struct sockaddr_in peer;
- struct sockaddr_in laddr;
- int len;
- KTEXT_ST ticket;
- AUTH_DAT auth;
- char version[KRB_SENDAUTH_VLEN];
- Key_schedule sched;
- char user[ANAME_SZ];
- struct passwd *pw;
-
- strcpy (instance, "*");
- len = sizeof peer;
- if (getpeername (STDIN_FILENO, (struct sockaddr *) &peer, &len) < 0
- || getsockname (STDIN_FILENO, (struct sockaddr *) &laddr,
- &len) < 0)
- {
- printf ("E Fatal error, aborting.\n\
-error %s getpeername or getsockname failed\n", strerror (errno));
- exit (1);
- }
-
- status = krb_recvauth (KOPT_DO_MUTUAL, STDIN_FILENO, &ticket, "rcmd",
- instance, &peer, &laddr, &auth, "", sched,
- version);
- if (status != KSUCCESS)
- {
- printf ("E Fatal error, aborting.\n\
-error 0 kerberos: %s\n", krb_get_err_text(status));
- exit (1);
- }
-
- /* Get the local name. */
- status = krb_kntoln (&auth, user);
- if (status != KSUCCESS)
- {
- printf ("E Fatal error, aborting.\n\
-error 0 kerberos: can't get local name: %s\n", krb_get_err_text(status));
- exit (1);
- }
-
- pw = getpwnam (user);
- if (pw == NULL)
- {
- printf ("E Fatal error, aborting.\n\
-error 0 %s: no such user\n", user);
- exit (1);
- }
-
- initgroups (pw->pw_name, pw->pw_gid);
- setgid (pw->pw_gid);
- setuid (pw->pw_uid);
- /* Inhibit access by randoms. Don't want people randomly
- changing our temporary tree before we check things in. */
- umask (077);
-
-#if HAVE_PUTENV
- /* Set LOGNAME and USER in the environment, in case they are
- already set to something else. */
- {
- char *env;
-
- env = xmalloc (sizeof "LOGNAME=" + strlen (user));
- (void) sprintf (env, "LOGNAME=%s", user);
- (void) putenv (env);
-
- env = xmalloc (sizeof "USER=" + strlen (user));
- (void) sprintf (env, "USER=%s", user);
- (void) putenv (env);
- }
-#endif
-
- /* Pretend we were invoked as a plain server. */
- argv[0] = "server";
- }
-#endif /* HAVE_KERBEROS */
-
-
-#if defined(AUTH_SERVER_SUPPORT) && defined(SERVER_SUPPORT)
- if (strcmp (argv[0], "pserver") == 0)
- {
- /* Gets username and password from client, authenticates, then
- switches to run as that user and sends an ACK back to the
- client. */
- authenticate_connection ();
-
- /* Pretend we were invoked as a plain server. */
- argv[0] = "server";
- }
-#endif /* AUTH_SERVER_SUPPORT && SERVER_SUPPORT */
-
-
-#ifdef CVSADM_ROOT
- /*
- * See if we are able to find a 'better' value for CVSroot in the
- * CVSADM_ROOT directory.
- */
-#ifdef SERVER_SUPPORT
- if (strcmp (argv[0], "server") == 0 && CVSroot == NULL)
- CVSADM_Root = NULL;
- else
- CVSADM_Root = Name_Root((char *) NULL, (char *) NULL);
-#else /* No SERVER_SUPPORT */
- CVSADM_Root = Name_Root((char *) NULL, (char *) NULL);
-#endif /* No SERVER_SUPPORT */
- if (CVSADM_Root != NULL)
- {
- if (CVSroot == NULL || !cvs_update_env)
- {
- CVSroot = CVSADM_Root;
- cvs_update_env = 1; /* need to update environment */
- }
-#ifdef CLIENT_SUPPORT
- else if (!getenv ("CVS_IGNORE_REMOTE_ROOT"))
-#else
- else
-#endif
- {
- /*
- * Now for the hard part, compare the two directories. If they
- * are not identical, then abort this command.
- */
- if ((fncmp (CVSroot, CVSADM_Root) != 0) &&
- !same_directories(CVSroot, CVSADM_Root))
- {
- error (0, 0, "%s value for CVS Root found in %s",
- CVSADM_Root, CVSADM_ROOT);
- error (0, 0, "does not match command line -d %s setting",
- CVSroot);
- error (1, 0,
- "you may wish to try the cvs command again without the -d option ");
- }
- }
- }
-#endif /* CVSADM_ROOT */
-
- /*
- * Specifying just the '-H' flag to the sub-command causes a Usage
- * message to be displayed.
- */
- command_name = cp = argv[0];
- if (help == TRUE || (argc > 1 && strcmp (argv[1], "-H") == 0))
- argc = -1;
- else
- {
- /*
- * Check to see if we can write into the history file. If not,
- * we assume that we can't work in the repository.
- * BUT, only if the history file exists.
- */
-#ifdef SERVER_SUPPORT
- if (strcmp (command_name, "server") != 0 || CVSroot != NULL)
-#endif
- {
- char path[PATH_MAX];
- int save_errno;
-
- if (!CVSroot || !*CVSroot)
- error (1, 0, "You don't have a %s environment variable",
- CVSROOT_ENV);
- (void) sprintf (path, "%s/%s", CVSroot, CVSROOTADM);
- if (!isaccessible (path, R_OK | X_OK))
- {
- save_errno = errno;
-#ifdef CLIENT_SUPPORT
- if (strchr (CVSroot, ':') == NULL)
- {
-#endif
- error (0, 0,
- "Sorry, you don't have sufficient access to %s", CVSroot);
- error (1, save_errno, "%s", path);
-#ifdef CLIENT_SUPPORT
- }
-#endif
- }
- (void) strcat (path, "/");
- (void) strcat (path, CVSROOTADM_HISTORY);
- if (isfile (path) && !isaccessible (path, R_OK | W_OK))
- {
- save_errno = errno;
- error (0, 0,
- "Sorry, you don't have read/write access to the history file");
- error (1, save_errno, "%s", path);
- }
- }
- }
-
-#ifdef SERVER_SUPPORT
- if (strcmp (command_name, "server") == 0)
- /* This is only used for writing into the history file. Might
- be nice to have hostname and/or remote path, on the other hand
- I'm not sure whether it is worth the trouble. */
- strcpy (CurDir, "<remote>");
- else if (!getwd (CurDir))
- error (1, 0, "cannot get working directory: %s", CurDir);
-#endif
-
-#ifdef HAVE_PUTENV
- /* Now, see if we should update the environment with the Rcsbin value */
- if (cvs_update_env)
- {
- char *env;
-
- env = xmalloc (strlen (CVSROOT_ENV) + strlen (CVSroot) + 1 + 1);
- (void) sprintf (env, "%s=%s", CVSROOT_ENV, CVSroot);
- (void) putenv (env);
- /* do not free env, as putenv has control of it */
- }
- if (rcsbin_update_env)
- {
- char *env;
-
- env = xmalloc (strlen (RCSBIN_ENV) + strlen (Rcsbin) + 1 + 1);
- (void) sprintf (env, "%s=%s", RCSBIN_ENV, Rcsbin);
- (void) putenv (env);
- /* do not free env, as putenv has control of it */
- }
-#endif
-
- /*
- * If Rcsbin is set to something, make sure it is terminated with
- * a slash character. If not, add one.
- */
- if (*Rcsbin)
- {
- int len = strlen (Rcsbin);
- char *rcsbin;
-
- if (Rcsbin[len - 1] != '/')
- {
- rcsbin = Rcsbin;
- Rcsbin = xmalloc (len + 2); /* one for '/', one for NULL */
- (void) strcpy (Rcsbin, rcsbin);
- (void) strcat (Rcsbin, "/");
- }
- }
-
- for (cm = cmds; cm->fullname; cm++)
- {
- if (cm->nick1 && !strcmp (cp, cm->nick1))
- break;
- if (cm->nick2 && !strcmp (cp, cm->nick2))
- break;
- if (!strcmp (cp, cm->fullname))
- break;
- }
-
- if (!cm->fullname)
- usage (usg); /* no match */
- else
- {
- command_name = cm->fullname; /* Global pointer for later use */
-
- /* make sure we clean up on error */
-#ifdef SIGHUP
- (void) SIG_register (SIGHUP, main_cleanup);
- (void) SIG_register (SIGHUP, Lock_Cleanup);
-#endif
-#ifdef SIGINT
- (void) SIG_register (SIGINT, main_cleanup);
- (void) SIG_register (SIGINT, Lock_Cleanup);
-#endif
-#ifdef SIGQUIT
- (void) SIG_register (SIGQUIT, main_cleanup);
- (void) SIG_register (SIGQUIT, Lock_Cleanup);
-#endif
-#ifdef SIGPIPE
- (void) SIG_register (SIGPIPE, main_cleanup);
- (void) SIG_register (SIGPIPE, Lock_Cleanup);
-#endif
-#ifdef SIGTERM
- (void) SIG_register (SIGTERM, main_cleanup);
- (void) SIG_register (SIGTERM, Lock_Cleanup);
-#endif
-
- gethostname(hostname, sizeof (hostname));
-
-#ifdef HAVE_SETVBUF
- /*
- * Make stdout line buffered, so 'tail -f' can monitor progress.
- * Patch creates too much output to monitor and it runs slowly.
- */
- if (strcmp (cm->fullname, "patch"))
- (void) setvbuf (stdout, (char *) NULL, _IOLBF, 0);
-#endif
-
- if (use_cvsrc)
- read_cvsrc(&argc, &argv);
-
-#ifdef CLIENT_SUPPORT
- /* If cvsroot contains a colon, try to do it via the protocol. */
- {
- char *p = CVSroot == NULL ? NULL : strchr (CVSroot, ':');
- if (p)
- err = (*(cm->client_func)) (argc, argv);
- else
- err = (*(cm->func)) (argc, argv);
- }
-#else /* No CLIENT_SUPPORT */
- err = (*(cm->func)) (argc, argv);
-
-#endif /* No CLIENT_SUPPORT */
- }
- /*
- * If the command's error count is modulo 256, we need to change it
- * so that we don't overflow the 8-bits we get to report exit status
- */
- if (err && (err % 256) == 0)
- err = 1;
- Lock_Cleanup ();
- return (err);
-}
-
-char *
-Make_Date (rawdate)
- char *rawdate;
-{
- struct tm *ftm;
- time_t unixtime;
- char date[256]; /* XXX bigger than we'll ever need? */
- char *ret;
-
- unixtime = get_date (rawdate, (struct timeb *) NULL);
- if (unixtime == (time_t) - 1)
- error (1, 0, "Can't parse date/time: %s", rawdate);
-#ifdef HAVE_RCS5
- ftm = gmtime (&unixtime);
-#else
- ftm = localtime (&unixtime);
-#endif
- (void) sprintf (date, DATEFORM,
- ftm->tm_year + (ftm->tm_year < 100 ? 0 : 1900),
- ftm->tm_mon + 1, ftm->tm_mday, ftm->tm_hour,
- ftm->tm_min, ftm->tm_sec);
- ret = xstrdup (date);
- return (ret);
-}
-
-void
-usage (cpp)
- register const char *const *cpp;
-{
- (void) fprintf (stderr, *cpp++, program_name, command_name);
- for (; *cpp; cpp++)
- (void) fprintf (stderr, *cpp);
- exit (1);
-}
diff --git a/gnu/usr.bin/cvs/cvs/modules.c b/gnu/usr.bin/cvs/cvs/modules.c
deleted file mode 100644
index 528287ad054f..000000000000
--- a/gnu/usr.bin/cvs/cvs/modules.c
+++ /dev/null
@@ -1,884 +0,0 @@
-/*
- * Copyright (c) 1992, Brian Berliner and Jeff Polk
- * Copyright (c) 1989-1992, Brian Berliner
- *
- * You may distribute under the terms of the GNU General Public License
- * as specified in the README file that comes with the CVS 1.4 kit.
- *
- * Modules
- *
- * Functions for accessing the modules file.
- *
- * The modules file supports basically three formats of lines:
- * key [options] directory files... [ -x directory [files] ] ...
- * key [options] directory [ -x directory [files] ] ...
- * key -a aliases...
- *
- * The -a option allows an aliasing step in the parsing of the modules
- * file. The "aliases" listed on a line following the -a are
- * processed one-by-one, as if they were specified as arguments on the
- * command line.
- */
-
-#include "cvs.h"
-#include "save-cwd.h"
-
-#ifndef lint
-static const char rcsid[] = "$CVSid: @(#)modules.c 1.62 94/09/29 $";
-USE(rcsid);
-#endif
-
-struct sortrec
-{
- char *modname;
- char *status;
- char *rest;
- char *comment;
-};
-
-static int sort_order PROTO((const PTR l, const PTR r));
-static void save_d PROTO((char *k, int ks, char *d, int ds));
-
-
-/*
- * Open the modules file, and die if the CVSROOT environment variable
- * was not set. If the modules file does not exist, that's fine, and
- * a warning message is displayed and a NULL is returned.
- */
-DBM *
-open_module ()
-{
- char mfile[PATH_MAX];
-
- if (CVSroot == NULL)
- {
- (void) fprintf (stderr,
- "%s: must set the CVSROOT environment variable\n",
- program_name);
- error (1, 0, "or specify the '-d' option to %s", program_name);
- }
- (void) sprintf (mfile, "%s/%s/%s", CVSroot, CVSROOTADM, CVSROOTADM_MODULES);
- return (dbm_open (mfile, O_RDONLY, 0666));
-}
-
-/*
- * Close the modules file, if the open succeeded, that is
- */
-void
-close_module (db)
- DBM *db;
-{
- if (db != NULL)
- dbm_close (db);
-}
-
-/*
- * This is the recursive function that processes a module name.
- * It calls back the passed routine for each directory of a module
- * It runs the post checkout or post tag proc from the modules file
- */
-int
-do_module (db, mname, m_type, msg, callback_proc, where,
- shorten, local_specified, run_module_prog, extra_arg)
- DBM *db;
- char *mname;
- enum mtype m_type;
- char *msg;
- CALLBACKPROC callback_proc;
- char *where;
- int shorten;
- int local_specified;
- int run_module_prog;
- char *extra_arg;
-{
- char *checkin_prog = NULL;
- char *checkout_prog = NULL;
- char *export_prog = NULL;
- char *tag_prog = NULL;
- char *update_prog = NULL;
- struct saved_cwd cwd;
- char line[MAXLINELEN];
- int modargc;
- int xmodargc;
- char **modargv;
- char *xmodargv[MAXFILEPERDIR];
- char *value;
- char *zvalue;
- char *mwhere = NULL;
- char *mfile = NULL;
- char *spec_opt = NULL;
- char xvalue[PATH_MAX];
- int alias = 0;
- datum key, val;
- char *cp;
- int c, err = 0;
-
-#ifdef SERVER_SUPPORT
- if (trace)
- {
- fprintf (stderr, "%c-> do_module (%s, %s, %s, %s)\n",
- (server_active) ? 'S' : ' ',
- mname, msg, where ? where : "",
- extra_arg ? extra_arg : "");
- }
-#endif
-
- /* remember where we start */
- if (save_cwd (&cwd))
- exit (1);
-
- /* if this is a directory to ignore, add it to that list */
- if (mname[0] == '!' && mname[1] != '\0')
- {
- ign_dir_add (mname+1);
- return(err);
- }
-
- /* strip extra stuff from the module name */
- strip_path (mname);
-
- /*
- * Look up the module using the following scheme:
- * 1) look for mname as a module name
- * 2) look for mname as a directory
- * 3) look for mname as a file
- * 4) take mname up to the first slash and look it up as a module name
- * (this is for checking out only part of a module)
- */
-
- /* look it up as a module name */
- key.dptr = mname;
- key.dsize = strlen (key.dptr);
- if (db != NULL)
- val = dbm_fetch (db, key);
- else
- val.dptr = NULL;
- if (val.dptr != NULL)
- {
- /* null terminate the value XXX - is this space ours? */
- val.dptr[val.dsize] = '\0';
-
- /* If the line ends in a comment, strip it off */
- if ((cp = strchr (val.dptr, '#')) != NULL)
- {
- do
- *cp-- = '\0';
- while (isspace (*cp));
- }
- else
- {
- /* Always strip trailing spaces */
- cp = strchr (val.dptr, '\0');
- while (cp > val.dptr && isspace(*--cp))
- *cp = '\0';
- }
-
- value = val.dptr;
- mwhere = xstrdup (mname);
- goto found;
- }
- else
- {
- char file[PATH_MAX];
- char attic_file[PATH_MAX];
- char *acp;
-
- /* check to see if mname is a directory or file */
-
- (void) sprintf (file, "%s/%s", CVSroot, mname);
- if ((acp = strrchr (mname, '/')) != NULL)
- {
- *acp = '\0';
- (void) sprintf (attic_file, "%s/%s/%s/%s%s", CVSroot, mname,
- CVSATTIC, acp + 1, RCSEXT);
- *acp = '/';
- }
- else
- (void) sprintf (attic_file, "%s/%s/%s%s", CVSroot, CVSATTIC,
- mname, RCSEXT);
-
- if (isdir (file))
- {
- value = mname;
- goto found;
- }
- else
- {
- (void) strcat (file, RCSEXT);
- if (isfile (file) || isfile (attic_file))
- {
- /* if mname was a file, we have to split it into "dir file" */
- if ((cp = strrchr (mname, '/')) != NULL && cp != mname)
- {
- char *slashp;
-
- /* put the ' ' in a copy so we don't mess up the original */
- value = strcpy (xvalue, mname);
- slashp = strrchr (value, '/');
- *slashp = ' ';
- }
- else
- {
- /*
- * the only '/' at the beginning or no '/' at all
- * means the file we are interested in is in CVSROOT
- * itself so the directory should be '.'
- */
- if (cp == mname)
- {
- /* drop the leading / if specified */
- value = strcpy (xvalue, ". ");
- (void) strcat (xvalue, mname + 1);
- }
- else
- {
- /* otherwise just copy it */
- value = strcpy (xvalue, ". ");
- (void) strcat (xvalue, mname);
- }
- }
- goto found;
- }
- }
- }
-
- /* look up everything to the first / as a module */
- if (mname[0] != '/' && (cp = strchr (mname, '/')) != NULL)
- {
- /* Make the slash the new end of the string temporarily */
- *cp = '\0';
- key.dptr = mname;
- key.dsize = strlen (key.dptr);
-
- /* do the lookup */
- if (db != NULL)
- val = dbm_fetch (db, key);
- else
- val.dptr = NULL;
-
- /* if we found it, clean up the value and life is good */
- if (val.dptr != NULL)
- {
- char *cp2;
-
- /* null terminate the value XXX - is this space ours? */
- val.dptr[val.dsize] = '\0';
-
- /* If the line ends in a comment, strip it off */
- if ((cp2 = strchr (val.dptr, '#')) != NULL)
- {
- do
- *cp2-- = '\0';
- while (isspace (*cp2));
- }
- value = val.dptr;
-
- /* mwhere gets just the module name */
- mwhere = xstrdup (mname);
- mfile = cp + 1;
-
- /* put the / back in mname */
- *cp = '/';
-
- goto found;
- }
-
- /* put the / back in mname */
- *cp = '/';
- }
-
- /* if we got here, we couldn't find it using our search, so give up */
- error (0, 0, "cannot find module `%s' - ignored", mname);
- err++;
- if (mwhere)
- free (mwhere);
- return (err);
-
-
- /*
- * At this point, we found what we were looking for in one
- * of the many different forms.
- */
- found:
-
- /* copy value to our own string since if we go recursive we'll be
- really screwed if we do another dbm lookup */
- zvalue = xstrdup (value);
- value = zvalue;
-
- /* search the value for the special delimiter and save for later */
- if ((cp = strchr (value, CVSMODULE_SPEC)) != NULL)
- {
- *cp = '\0'; /* null out the special char */
- spec_opt = cp + 1; /* save the options for later */
-
- if (cp != value) /* strip whitespace if necessary */
- while (isspace (*--cp))
- *cp = '\0';
-
- if (cp == value)
- {
- /*
- * we had nothing but special options, so skip arg
- * parsing and regular stuff entirely
- *
- * If there were only special ones though, we must
- * make the appropriate directory and cd to it
- */
- char *dir;
-
- /* XXX - XXX - MAJOR HACK - DO NOT SHIP - this needs to
- be !pipeout, but we don't know that here yet */
- if (!run_module_prog)
- goto out;
-
- dir = where ? where : mname;
- /* XXX - think about making null repositories at each dir here
- instead of just at the bottom */
- make_directories (dir);
- if (chdir (dir) < 0)
- {
- error (0, errno, "cannot chdir to %s", dir);
- spec_opt = NULL;
- err++;
- goto out;
- }
- if (!isfile (CVSADM))
- {
- char nullrepos[PATH_MAX];
-
- (void) sprintf (nullrepos, "%s/%s/%s", CVSroot,
- CVSROOTADM, CVSNULLREPOS);
- if (!isfile (nullrepos))
- {
- mode_t omask;
- omask = umask (cvsumask);
- (void) CVS_MKDIR (nullrepos, 0777);
- (void) umask (omask);
- }
- if (!isdir (nullrepos))
- error (1, 0, "there is no repository %s", nullrepos);
-
- Create_Admin (".", dir,
- nullrepos, (char *) NULL, (char *) NULL);
- if (!noexec)
- {
- FILE *fp;
-
- fp = open_file (CVSADM_ENTSTAT, "w+");
- if (fclose (fp) == EOF)
- error (1, errno, "cannot close %s", CVSADM_ENTSTAT);
-#ifdef SERVER_SUPPORT
- if (server_active)
- server_set_entstat (dir, nullrepos);
-#endif
- }
- }
- out:
- goto do_special;
- }
- }
-
- /* don't do special options only part of a module was specified */
- if (mfile != NULL)
- spec_opt = NULL;
-
- /*
- * value now contains one of the following:
- * 1) dir
- * 2) dir file
- * 3) the value from modules without any special args
- * [ args ] dir [file] [file] ...
- * or -a module [ module ] ...
- */
-
- /* Put the value on a line with XXX prepended for getopt to eat */
- (void) sprintf (line, "%s %s", "XXX", value);
-
- /* turn the line into an argv[] array */
- line2argv (&xmodargc, xmodargv, line);
- modargc = xmodargc;
- modargv = xmodargv;
-
- /* parse the args */
- optind = 1;
- while ((c = getopt (modargc, modargv, CVSMODULE_OPTS)) != -1)
- {
- switch (c)
- {
- case 'a':
- alias = 1;
- break;
- case 'd':
- if (mwhere)
- free (mwhere);
- mwhere = xstrdup (optarg);
- break;
- case 'i':
- checkin_prog = optarg;
- break;
- case 'l':
- local_specified = 1;
- case 'o':
- checkout_prog = optarg;
- break;
- case 'e':
- export_prog = optarg;
- break;
- case 't':
- tag_prog = optarg;
- break;
- case 'u':
- update_prog = optarg;
- break;
- case '?':
- error (0, 0,
- "modules file has invalid option for key %s value %s",
- key.dptr, val.dptr);
- err++;
- if (mwhere)
- free (mwhere);
- free (zvalue);
- return (err);
- }
- }
- modargc -= optind;
- modargv += optind;
- if (modargc == 0)
- {
- error (0, 0, "modules file missing directory for module %s", mname);
- if (mwhere)
- free (mwhere);
- free (zvalue);
- return (++err);
- }
-
- /* if this was an alias, call ourselves recursively for each module */
- if (alias)
- {
- int i;
-
- for (i = 0; i < modargc; i++)
- {
- if (strcmp (mname, modargv[i]) == 0)
- error (0, 0,
- "module `%s' in modules file contains infinite loop",
- mname);
- else
- err += do_module (db, modargv[i], m_type, msg, callback_proc,
- where, shorten, local_specified,
- run_module_prog, extra_arg);
- }
- if (mwhere)
- free (mwhere);
- free (zvalue);
- return (err);
- }
-
- /* otherwise, process this module */
- err += callback_proc (&modargc, modargv, where, mwhere, mfile, shorten,
- local_specified, mname, msg);
-
-#if 0
- /* FIXME: I've fixed this so that the correct arguments are called,
- but now this fails because there is code below this point that
- uses optarg values extracted from the arg vector. */
- free_names (&xmodargc, xmodargv);
-#endif
-
- /* if there were special include args, process them now */
-
- do_special:
-
- /* blow off special options if -l was specified */
- if (local_specified)
- spec_opt = NULL;
-
- while (spec_opt != NULL)
- {
- char *next_opt;
-
- cp = strchr (spec_opt, CVSMODULE_SPEC);
- if (cp != NULL)
- {
- /* save the beginning of the next arg */
- next_opt = cp + 1;
-
- /* strip whitespace off the end */
- do
- *cp = '\0';
- while (isspace (*--cp));
- }
- else
- next_opt = NULL;
-
- /* strip whitespace from front */
- while (isspace (*spec_opt))
- spec_opt++;
-
- if (*spec_opt == '\0')
- error (0, 0, "Mal-formed %c option for module %s - ignored",
- CVSMODULE_SPEC, mname);
- else
- err += do_module (db, spec_opt, m_type, msg, callback_proc,
- (char *) NULL, 0, local_specified,
- run_module_prog, extra_arg);
- spec_opt = next_opt;
- }
-
- /* write out the checkin/update prog files if necessary */
-#ifdef SERVER_SUPPORT
- if (err == 0 && !noexec && m_type == CHECKOUT && server_expanding)
- {
- if (checkin_prog != NULL)
- server_prog (where ? where : mname, checkin_prog, PROG_CHECKIN);
- if (update_prog != NULL)
- server_prog (where ? where : mname, update_prog, PROG_UPDATE);
- }
- else
-#endif
- if (err == 0 && !noexec && m_type == CHECKOUT && run_module_prog)
- {
- FILE *fp;
-
- if (checkin_prog != NULL)
- {
- fp = open_file (CVSADM_CIPROG, "w+");
- (void) fprintf (fp, "%s\n", checkin_prog);
- if (fclose (fp) == EOF)
- error (1, errno, "cannot close %s", CVSADM_CIPROG);
- }
- if (update_prog != NULL)
- {
- fp = open_file (CVSADM_UPROG, "w+");
- (void) fprintf (fp, "%s\n", update_prog);
- if (fclose (fp) == EOF)
- error (1, errno, "cannot close %s", CVSADM_UPROG);
- }
- }
-
- /* cd back to where we started */
- if (restore_cwd (&cwd, NULL))
- exit (1);
- free_cwd (&cwd);
-
- /* run checkout or tag prog if appropriate */
- if (err == 0 && run_module_prog)
- {
- if ((m_type == TAG && tag_prog != NULL) ||
- (m_type == CHECKOUT && checkout_prog != NULL) ||
- (m_type == EXPORT && export_prog != NULL))
- {
- /*
- * If a relative pathname is specified as the checkout, tag
- * or export proc, try to tack on the current "where" value.
- * if we can't find a matching program, just punt and use
- * whatever is specified in the modules file.
- */
- char real_prog[PATH_MAX];
- char *prog = (m_type == TAG ? tag_prog :
- (m_type == CHECKOUT ? checkout_prog : export_prog));
- char *real_where = (where != NULL ? where : mwhere);
-
- if ((*prog != '/') && (*prog != '.'))
- {
- (void) sprintf (real_prog, "%s/%s", real_where, prog);
- if (isfile (real_prog))
- prog = real_prog;
- }
-
- run_setup ("%s %s", prog, real_where);
- if (extra_arg)
- run_arg (extra_arg);
-
- if (!quiet)
- {
- (void) printf ("%s %s: Executing '", program_name,
- command_name);
- run_print (stdout);
- (void) printf ("'\n");
- }
- err += run_exec (RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL);
- }
- }
-
- /* clean up */
- if (mwhere)
- free (mwhere);
- free (zvalue);
-
- return (err);
-}
-
-/* - Read all the records from the modules database into an array.
- - Sort the array depending on what format is desired.
- - Print the array in the format desired.
-
- Currently, there are only two "desires":
-
- 1. Sort by module name and format the whole entry including switches,
- files and the comment field: (Including aliases)
-
- modulename -s switches, one per line, even if
- -i it has many switches.
- Directories and files involved, formatted
- to cover multiple lines if necessary.
- # Comment, also formatted to cover multiple
- # lines if necessary.
-
- 2. Sort by status field string and print: (*not* including aliases)
-
- modulename STATUS Directories and files involved, formatted
- to cover multiple lines if necessary.
- # Comment, also formatted to cover multiple
- # lines if necessary.
-*/
-
-static struct sortrec *s_head;
-
-static int s_max = 0; /* Number of elements allocated */
-static int s_count = 0; /* Number of elements used */
-
-static int Status; /* Nonzero if the user is
- interested in status
- information as well as
- module name */
-static char def_status[] = "NONE";
-
-/* Sort routine for qsort:
- - If we want the "Status" field to be sorted, check it first.
- - Then compare the "module name" fields. Since they are unique, we don't
- have to look further.
-*/
-static int
-sort_order (l, r)
- const PTR l;
- const PTR r;
-{
- int i;
- const struct sortrec *left = (const struct sortrec *) l;
- const struct sortrec *right = (const struct sortrec *) r;
-
- if (Status)
- {
- /* If Sort by status field, compare them. */
- if ((i = strcmp (left->status, right->status)) != 0)
- return (i);
- }
- return (strcmp (left->modname, right->modname));
-}
-
-static void
-save_d (k, ks, d, ds)
- char *k;
- int ks;
- char *d;
- int ds;
-{
- char *cp, *cp2;
- struct sortrec *s_rec;
-
- if (Status && *d == '-' && *(d + 1) == 'a')
- return; /* We want "cvs co -s" and it is an alias! */
-
- if (s_count == s_max)
- {
- s_max += 64;
- s_head = (struct sortrec *) xrealloc ((char *) s_head, s_max * sizeof (*s_head));
- }
- s_rec = &s_head[s_count];
- s_rec->modname = cp = xmalloc (ks + 1);
- (void) strncpy (cp, k, ks);
- *(cp + ks) = '\0';
-
- s_rec->rest = cp2 = xmalloc (ds + 1);
- cp = d;
- *(cp + ds) = '\0'; /* Assumes an extra byte at end of static dbm buffer */
-
- while (isspace (*cp))
- cp++;
- /* Turn <spaces> into one ' ' -- makes the rest of this routine simpler */
- while (*cp)
- {
- if (isspace (*cp))
- {
- *cp2++ = ' ';
- while (isspace (*cp))
- cp++;
- }
- else
- *cp2++ = *cp++;
- }
- *cp2 = '\0';
-
- /* Look for the "-s statusvalue" text */
- if (Status)
- {
- s_rec->status = def_status;
-
- /* Minor kluge, but general enough to maintain */
- for (cp = s_rec->rest; (cp2 = strchr (cp, '-')) != NULL; cp = ++cp2)
- {
- if (*(cp2 + 1) == 's' && *(cp2 + 2) == ' ')
- {
- s_rec->status = (cp2 += 3);
- while (*cp2 != ' ')
- cp2++;
- *cp2++ = '\0';
- cp = cp2;
- break;
- }
- }
- }
- else
- cp = s_rec->rest;
-
- /* Find comment field, clean up on all three sides & compress blanks */
- if ((cp2 = cp = strchr (cp, '#')) != NULL)
- {
- if (*--cp2 == ' ')
- *cp2 = '\0';
- if (*++cp == ' ')
- cp++;
- s_rec->comment = cp;
- }
- else
- s_rec->comment = "";
-
- s_count++;
-}
-
-/* Print out the module database as we know it. If STATUS is
- non-zero, print out status information for each module. */
-
-void
-cat_module (status)
- int status;
-{
- DBM *db;
- datum key, val;
- int i, c, wid, argc, cols = 80, indent, fill;
- int moduleargc;
- struct sortrec *s_h;
- char *cp, *cp2, **argv;
- char line[MAXLINELEN], *moduleargv[MAXFILEPERDIR];
-
-#ifdef sun
-#ifdef TIOCGSIZE
- struct ttysize ts;
-
- (void) ioctl (0, TIOCGSIZE, &ts);
- cols = ts.ts_cols;
-#endif
-#else
-#ifdef TIOCGWINSZ
- struct winsize ws;
-
- (void) ioctl (0, TIOCGWINSZ, &ws);
- cols = ws.ws_col;
-#endif
-#endif
-
- Status = status;
-
- /* Read the whole modules file into allocated records */
- if (!(db = open_module ()))
- error (1, 0, "failed to open the modules file");
-
- for (key = dbm_firstkey (db); key.dptr != NULL; key = dbm_nextkey (db))
- {
- val = dbm_fetch (db, key);
- if (val.dptr != NULL)
- save_d (key.dptr, key.dsize, val.dptr, val.dsize);
- }
-
- /* Sort the list as requested */
- qsort ((PTR) s_head, s_count, sizeof (struct sortrec), sort_order);
-
- /*
- * Run through the sorted array and format the entries
- * indent = space for modulename + space for status field
- */
- indent = 12 + (status * 12);
- fill = cols - (indent + 2);
- for (s_h = s_head, i = 0; i < s_count; i++, s_h++)
- {
- /* Print module name (and status, if wanted) */
- (void) printf ("%-12s", s_h->modname);
- if (status)
- {
- (void) printf (" %-11s", s_h->status);
- if (s_h->status != def_status)
- *(s_h->status + strlen (s_h->status)) = ' ';
- }
-
- /* Parse module file entry as command line and print options */
- (void) sprintf (line, "%s %s", s_h->modname, s_h->rest);
- line2argv (&moduleargc, moduleargv, line);
- argc = moduleargc;
- argv = moduleargv;
-
- optind = 1;
- wid = 0;
- while ((c = getopt (argc, argv, CVSMODULE_OPTS)) != -1)
- {
- if (!status)
- {
- if (c == 'a' || c == 'l')
- {
- (void) printf (" -%c", c);
- wid += 3; /* Could just set it to 3 */
- }
- else
- {
- if (strlen (optarg) + 4 + wid > (unsigned) fill)
- {
- (void) printf ("\n%*s", indent, "");
- wid = 0;
- }
- (void) printf (" -%c %s", c, optarg);
- wid += strlen (optarg) + 4;
- }
- }
- }
- argc -= optind;
- argv += optind;
-
- /* Format and Print all the files and directories */
- for (; argc--; argv++)
- {
- if (strlen (*argv) + wid > (unsigned) fill)
- {
- (void) printf ("\n%*s", indent, "");
- wid = 0;
- }
- (void) printf (" %s", *argv);
- wid += strlen (*argv) + 1;
- }
- (void) printf ("\n");
-
- /* Format the comment field -- save_d (), compressed spaces */
- for (cp2 = cp = s_h->comment; *cp; cp2 = cp)
- {
- (void) printf ("%*s # ", indent, "");
- if (strlen (cp2) < (unsigned) (fill - 2))
- {
- (void) printf ("%s\n", cp2);
- break;
- }
- cp += fill - 2;
- while (*cp != ' ' && cp > cp2)
- cp--;
- if (cp == cp2)
- {
- (void) printf ("%s\n", cp2);
- break;
- }
-
- *cp++ = '\0';
- (void) printf ("%s\n", cp2);
- }
-
- free_names(&moduleargc, moduleargv);
- }
-}
diff --git a/gnu/usr.bin/cvs/cvs/no_diff.c b/gnu/usr.bin/cvs/cvs/no_diff.c
deleted file mode 100644
index 281d34866bc3..000000000000
--- a/gnu/usr.bin/cvs/cvs/no_diff.c
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * Copyright (c) 1992, Brian Berliner and Jeff Polk
- * Copyright (c) 1989-1992, Brian Berliner
- *
- * You may distribute under the terms of the GNU General Public License as
- * specified in the README file that comes with the CVS 1.4 kit.
- *
- * No Difference
- *
- * The user file looks modified judging from its time stamp; however it needn't
- * be. No_difference() finds out whether it is or not. If it is not, it
- * updates the administration.
- *
- * returns 0 if no differences are found and non-zero otherwise
- */
-
-#include "cvs.h"
-
-#ifndef lint
-static const char rcsid[] = "$CVSid: @(#)no_diff.c 1.39 94/10/07 $";
-USE(rcsid);
-#endif
-
-int
-No_Difference (file, vers, entries, repository, update_dir)
- char *file;
- Vers_TS *vers;
- List *entries;
- char *repository;
- char *update_dir;
-{
- Node *p;
- char tmp[L_tmpnam+1];
- int ret;
- char *ts, *options;
- int retcode = 0;
- char *tocvsPath;
-
- if (!vers->srcfile || !vers->srcfile->path)
- return (-1); /* different since we couldn't tell */
-
- if (vers->entdata && vers->entdata->options)
- options = xstrdup (vers->entdata->options);
- else
- options = xstrdup ("");
-
- run_setup ("%s%s -p -q -r%s %s", Rcsbin, RCS_CO,
- vers->vn_user ? vers->vn_user : "", options);
- run_arg (vers->srcfile->path);
- if ((retcode = run_exec (RUN_TTY, tmpnam (tmp), RUN_TTY, RUN_REALLY)) == 0)
- {
-#if 0
- /* Why would we want to munge the modes? And only if the timestamps
- are different? And even for commands like "cvs status"???? */
- if (!iswritable (file)) /* fix the modes as a side effect */
- xchmod (file, 1);
-#endif
-
- tocvsPath = wrap_tocvs_process_file (file);
-
- /* do the byte by byte compare */
- if (xcmp (tocvsPath == NULL ? file : tocvsPath, tmp) == 0)
- {
-#if 0
- /* Why would we want to munge the modes? And only if the
- timestamps are different? And even for commands like
- "cvs status"???? */
- if (cvswrite == FALSE) /* fix the modes as a side effect */
- xchmod (file, 0);
-#endif
-
- /* no difference was found, so fix the entries file */
- ts = time_stamp (file);
- Register (entries, file,
- vers->vn_user ? vers->vn_user : vers->vn_rcs, ts,
- options, vers->tag, vers->date, (char *) 0);
-#ifdef SERVER_SUPPORT
- if (server_active)
- {
- /* We need to update the entries line on the client side. */
- server_update_entries
- (file, update_dir, repository, SERVER_UPDATED);
- }
-#endif
- free (ts);
-
- /* update the entdata pointer in the vers_ts structure */
- p = findnode (entries, file);
- vers->entdata = (Entnode *) p->data;
-
- ret = 0;
- }
- else
- ret = 1; /* files were really different */
- if (tocvsPath)
- {
- /* Need to call unlink myself because the noexec variable
- * has been set to 1. */
- if (trace)
- (void) fprintf (stderr, "%c-> unlink (%s)\n",
-#ifdef SERVER_SUPPORT
- (server_active) ? 'S' : ' ',
-#else
- ' ',
-#endif
- tocvsPath);
- if (unlink (tocvsPath) < 0)
- error (0, errno, "could not remove %s", tocvsPath);
- }
- }
- else
- {
- if (update_dir[0] == '\0')
- error (0, retcode == -1 ? errno : 0,
- "could not check out revision %s of %s",
- vers->vn_user, file);
- else
- error (0, retcode == -1 ? errno : 0,
- "could not check out revision %s of %s/%s",
- vers->vn_user, update_dir, file);
- ret = -1; /* different since we couldn't tell */
- }
-
- if (trace)
-#ifdef SERVER_SUPPORT
- (void) fprintf (stderr, "%c-> unlink2 (%s)\n",
- (server_active) ? 'S' : ' ', tmp);
-#else
- (void) fprintf (stderr, "-> unlink (%s)\n", tmp);
-#endif
- if (unlink (tmp) < 0)
- error (0, errno, "could not remove %s", tmp);
- free (options);
- return (ret);
-}
diff --git a/gnu/usr.bin/cvs/cvs/options.h b/gnu/usr.bin/cvs/cvs/options.h
deleted file mode 100644
index 8af48de08b15..000000000000
--- a/gnu/usr.bin/cvs/cvs/options.h
+++ /dev/null
@@ -1,286 +0,0 @@
-/*
- * Copyright (c) 1992, Brian Berliner and Jeff Polk
- * Copyright (c) 1989-1992, Brian Berliner
- *
- * You may distribute under the terms of the GNU General Public License as
- * specified in the README file that comes with the CVS 1.4 kit.
- *
- * This file holds (most of) the configuration tweaks that can be made to
- * customize CVS for your site. CVS comes configured for a typical SunOS 4.x
- * environment. The comments for each configurable item are intended to be
- * self-explanatory. All #defines are tested first to see if an over-riding
- * option was specified on the "make" command line.
- *
- * If special libraries are needed, you will have to edit the Makefile.in file
- * or the configure script directly. Sorry.
- */
-
-/*
- * CVS provides the most features when used in conjunction with the Version-5
- * release of RCS. Thus, it is the default. This also assumes that GNU diff
- * Version-1.15 is being used as well -- you will have to configure your RCS
- * V5 release separately to make this the case. If you do not have RCS V5 and
- * GNU diff V1.15, comment out this define. You should not try mixing and
- * matching other combinations of these tools.
- */
-#ifndef HAVE_RCS5
-#define HAVE_RCS5
-#endif
-
-/*
- * If, before installing this version of CVS, you were running RCS V4 AND you
- * are installing this CVS and RCS V5 and GNU diff 1.15 all at the same time,
- * you should turn on the following define. It only exists to try to do
- * reasonable things with your existing checked out files when you upgrade to
- * RCS V5, since the keyword expansion formats have changed with RCS V5.
- *
- * If you already have been running with RCS5, or haven't been running with CVS
- * yet at all, or are sticking with RCS V4 for now, leave the commented out.
- */
-#ifndef HAD_RCS4
-/* #define HAD_RCS4 */
-#endif
-
-/*
- * For portability and heterogeneity reasons, CVS is shipped by default using
- * my own text-file version of the ndbm database library in the src/myndbm.c
- * file. If you want better performance and are not concerned about
- * heterogeneous hosts accessing your modules file, turn this option off.
- */
-#ifndef MY_NDBM
-#define MY_NDBM
-#endif
-
-/*
- * The "diff" program to execute when creating patch output. This "diff"
- * must support the "-c" option for context diffing. Specify a full
- * pathname if your site wants to use a particular diff. If you are
- * using the GNU version of diff (version 1.15 or later), this should
- * be "diff -a".
- *
- * NOTE: this program is only used for the ``patch'' sub-command (and
- * for ``update'' if you are using the server). The other commands
- * use rcsdiff which will use whatever version of diff was specified
- * when rcsdiff was built on your system.
- */
-
-#ifndef DIFF
-#define DIFF "diff -a"
-#endif
-
-/*
- * The "grep" program to execute when checking to see if a merged file had
- * any conflicts. This "grep" must support a standard basic
- * regular expression as an argument. Specify a full pathname if your site
- * wants to use a particular grep.
- */
-
-#ifndef GREP
-#define GREP "grep"
-#endif
-
-/*
- * The "rm" program to execute when pruning directories that are not part of
- * a release. This "rm" must support the "-fr" options. Specify a full
- * pathname if your site wants to use a particular rm.
- */
-#ifndef RM
-#define RM "rm"
-#endif
-
-/*
- * The "sort" program to execute when displaying the module database. Specify
- * a full pathname if your site wants to use a particular sort.
- */
-#ifndef SORT
-#define SORT "sort"
-#endif
-
-/*
- * The "patch" program to run when using the CVS server and accepting
- * patches across the network. Specify a full pathname if your site
- * wants to use a particular patch.
- */
-#ifndef PATCH_PROGRAM
-#define PATCH_PROGRAM "patch"
-#endif
-
-/*
- * By default, RCS programs are executed with the shell or through execlp(),
- * so the user's PATH environment variable is searched. If you'd like to
- * bind all RCS programs to a certain directory (perhaps one not in most
- * people's PATH) then set the default in RCSBIN_DFLT. Note that setting
- * this here will cause all RCS programs to be executed from this directory,
- * unless the user overrides the default with the RCSBIN environment variable
- * or the "-b" option to CVS.
- *
- * This define should be either the empty string ("") or a full pathname to the
- * directory containing all the installed programs from the RCS distribution.
- */
-#ifndef RCSBIN_DFLT
-#define RCSBIN_DFLT ""
-#endif
-
-/*
- * The default editor to use, if one does not specify the "-e" option to cvs,
- * or does not have an EDITOR environment variable. I set this to just "vi",
- * and use the shell to find where "vi" actually is. This allows sites with
- * /usr/bin/vi or /usr/ucb/vi to work equally well (assuming that your PATH
- * is reasonable).
- */
-#ifndef EDITOR_DFLT
-#define EDITOR_DFLT "vi"
-#endif
-
-/*
- * The default umask to use when creating or otherwise setting file or
- * directory permissions in the repository. Must be a value in the
- * range of 0 through 0777. For example, a value of 002 allows group
- * rwx access and world rx access; a value of 007 allows group rwx
- * access but no world access. This value is overridden by the value
- * of the CVSUMASK environment variable, which is interpreted as an
- * octal number.
- */
-#ifndef UMASK_DFLT
-#define UMASK_DFLT 002
-#endif
-
-/*
- * The cvs admin command is restricted to the members of the group
- * CVS_ADMIN_GROUP. If this group does not exist, all users are
- * allowed to run cvs admin. To disable the cvs admin for all users,
- * create an empty group CVS_ADMIN_GROUP. To disable access control for
- * cvs admin, comment out the define below.
- */
-#ifndef CVS_ADMIN_GROUP
-#define CVS_ADMIN_GROUP "cvsadmin"
-#endif
-
-/*
- * The Repository file holds the path to the directory within the source
- * repository that contains the RCS ,v files for each CVS working directory.
- * This path is either a full-path or a path relative to CVSROOT.
- *
- * The only advantage that I can see to having a relative path is that One can
- * change the physical location of the master source repository, change one's
- * CVSROOT environment variable, and CVS will work without problems. I
- * recommend using full-paths.
- */
-#ifndef RELATIVE_REPOS
-/* #define RELATIVE_REPOS */
-#endif
-
-/*
- * When committing or importing files, you must enter a log message.
- * Normally, you can do this either via the -m flag on the command line or an
- * editor will be started for you. If you like to use logging templates (the
- * rcsinfo file within the $CVSROOT/CVSROOT directory), you might want to
- * force people to use the editor even if they specify a message with -m.
- * Enabling FORCE_USE_EDITOR will cause the -m message to be appended to the
- * temp file when the editor is started.
- */
-#ifndef FORCE_USE_EDITOR
-/* #define FORCE_USE_EDITOR */
-#endif
-
-/*
- * When locking the repository, some sites like to remove locks and assume
- * the program that created them went away if the lock has existed for a long
- * time. This used to be the default for previous versions of CVS. CVS now
- * attempts to be much more robust, so lock files should not be left around
- * by mistake. The new behaviour will never remove old locks (they must now
- * be removed by hand). Enabling CVS_FUDGELOCKS will cause CVS to remove
- * locks that are older than CVSLCKAGE seconds.
- * Use of this option is NOT recommended.
- */
-#ifndef CVS_FUDGELOCKS
-/* #define CVS_FUDGELOCKS */
-#endif
-
-/*
- * When committing a permanent change, CVS and RCS make a log entry of
- * who committed the change. If you are committing the change logged in
- * as "root" (not under "su" or other root-priv giving program), CVS/RCS
- * cannot determine who is actually making the change.
- *
- * As such, by default, CVS disallows changes to be committed by users
- * logged in as "root". You can disable this option by commenting
- * out the lines below.
- */
-#ifndef CVS_BADROOT
-#define CVS_BADROOT
-#endif
-
-/*
- * The "cvs admin" command allows people to get around most of the logging
- * and info procedures within CVS. For exmaple, "cvs tag tagname filename"
- * will perform some validity checks on the tag, while "cvs admin -Ntagname"
- * will not perform those checks. For this reason, some sites may wish to
- * disable the admin function completely.
- *
- * To disable the admin function, uncomment the lines below.
- */
-#ifndef CVS_NOADMIN
-/* #define CVS_NOADMIN */
-#endif
-
-/*
- * The "cvs diff" command accepts all the single-character options that GNU
- * diff (1.15) accepts. Except -D. GNU diff uses -D as a way to put
- * cpp-style #define's around the output differences. CVS, by default, uses
- * -D to specify a free-form date (like "cvs diff -D '1 week ago'"). If
- * you would prefer that the -D option of "cvs diff" work like the GNU diff
- * option, then comment out this define.
- */
-#ifndef CVS_DIFFDATE
-#define CVS_DIFFDATE
-#endif
-
-/*
- * define this to enable the SETXID support (see FAQ 4D.13)
- */
-#ifndef SETXID_SUPPORT
-/* #define SETXID_SUPPORT */
-#endif
-
-/*
- * The authenticated client/server is under construction. Don't
- * define either of these unless you're testing them, in which case
- * you're me and you already know that.
- */
-#undef AUTH_CLIENT_SUPPORT
-#undef AUTH_SERVER_SUPPORT
-
-/*
- * If you are working with a large remote repository and a 'cvs checkout' is
- * swamping your network and memory, define these to enable flow control.
- * You will end up with even less guarantees of a consistant checkout,
- * but that may be better than no checkout at all. The master server process
- * will monitor how far it is getting behind, if it reaches the high water
- * mark, it will signal the child process to stop generating data when
- * convenient (ie: no locks are held, currently at the beginning of a
- * new directory). Once the buffer has drained sufficiently to reach the
- * low water mark, it will be signalled to start again.
- * -- EXPERIMENTAL! -- A better solution may be in the works.
- * You may override the default hi/low watermarks here too.
- */
-#ifndef SERVER_FLOWCONTROL
-/* #define SERVER_FLOWCONTROL */
-/* #define SERVER_HI_WATER (2 * 1024 * 1024) */
-/* #define SERVER_LO_WATER (1 * 1024 * 1024) */
-#endif
-
-/* End of CVS configuration section */
-
-/*
- * Externs that are included in libc, but are used frequently enough to
- * warrant defining here.
- */
-#ifndef STDC_HEADERS
-extern void exit ();
-#endif
-
-#ifndef getwd
-extern char *getwd ();
-#endif
-
diff --git a/gnu/usr.bin/cvs/cvs/parseinfo.c b/gnu/usr.bin/cvs/cvs/parseinfo.c
deleted file mode 100644
index 6d59884db9ad..000000000000
--- a/gnu/usr.bin/cvs/cvs/parseinfo.c
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * Copyright (c) 1992, Brian Berliner and Jeff Polk
- * Copyright (c) 1989-1992, Brian Berliner
- *
- * You may distribute under the terms of the GNU General Public License as
- * specified in the README file that comes with the CVS 1.4 kit.
- */
-
-#include "cvs.h"
-
-#ifndef lint
-static const char rcsid[] = "$CVSid: @(#)parseinfo.c 1.18 94/09/23 $";
-USE(rcsid);
-#endif
-
-/*
- * Parse the INFOFILE file for the specified REPOSITORY. Invoke CALLPROC for
- * the first line in the file that matches the REPOSITORY, or if ALL != 0, any lines
- * matching "ALL", or if no lines match, the last line matching "DEFAULT".
- *
- * Return 0 for success, -1 if there was not an INFOFILE, and >0 for failure.
- */
-int
-Parse_Info (infofile, repository, callproc, all)
- char *infofile;
- char *repository;
- CALLPROC callproc;
- int all;
-{
- int err = 0;
- FILE *fp_info;
- char infopath[PATH_MAX];
- char line[MAXLINELEN];
- char *default_value = NULL;
- char *expanded_value= NULL;
- int callback_done, line_number;
- char *cp, *exp, *value, *srepos;
- const char *regex_err;
-
- if (CVSroot == NULL)
- {
- /* XXX - should be error maybe? */
- error (0, 0, "CVSROOT variable not set");
- return (1);
- }
-
- /* find the info file and open it */
- (void) sprintf (infopath, "%s/%s/%s", CVSroot,
- CVSROOTADM, infofile);
- if ((fp_info = fopen (infopath, "r")) == NULL)
- return (0); /* no file -> nothing special done */
-
- /* strip off the CVSROOT if repository was absolute */
- srepos = Short_Repository (repository);
-
- if (trace)
- (void) fprintf (stderr, "-> ParseInfo(%s, %s, %s)\n",
- infopath, srepos, all ? "ALL" : "not ALL");
-
- /* search the info file for lines that match */
- callback_done = line_number = 0;
- while (fgets (line, sizeof (line), fp_info) != NULL)
- {
- line_number++;
-
- /* skip lines starting with # */
- if (line[0] == '#')
- continue;
-
- /* skip whitespace at beginning of line */
- for (cp = line; *cp && isspace (*cp); cp++)
- ;
-
- /* if *cp is null, the whole line was blank */
- if (*cp == '\0')
- continue;
-
- /* the regular expression is everything up to the first space */
- for (exp = cp; *cp && !isspace (*cp); cp++)
- ;
- if (*cp != '\0')
- *cp++ = '\0';
-
- /* skip whitespace up to the start of the matching value */
- while (*cp && isspace (*cp))
- cp++;
-
- /* no value to match with the regular expression is an error */
- if (*cp == '\0')
- {
- error (0, 0, "syntax error at line %d file %s; ignored",
- line_number, infofile);
- continue;
- }
- value = cp;
-
- /* strip the newline off the end of the value */
- if ((cp = strrchr (value, '\n')) != NULL)
- *cp = '\0';
-
- expanded_value = expand_path (value);
- if (!expanded_value)
- {
- error (0, 0,
- "Invalid environmental variable at line %d in file %s",
- line_number, infofile);
- continue;
-
- }
-
- /*
- * At this point, exp points to the regular expression, and value
- * points to the value to call the callback routine with. Evaluate
- * the regular expression against srepos and callback with the value
- * if it matches.
- */
-
- /* save the default value so we have it later if we need it */
- if (strcmp (exp, "DEFAULT") == 0)
- {
- default_value = xstrdup (expanded_value);
- continue;
- }
-
- /*
- * For a regular expression of "ALL", do the callback always We may
- * execute lots of ALL callbacks in addition to *one* regular matching
- * callback or default
- */
- if (strcmp (exp, "ALL") == 0)
- {
- if (all)
- err += callproc (repository, expanded_value);
- else
- error(0, 0, "Keyword `ALL' is ignored at line %d in %s file",
- line_number, infofile);
- continue;
- }
-
- if (callback_done)
- /* only first matching, plus "ALL"'s */
- continue;
-
- /* see if the repository matched this regular expression */
- if ((regex_err = re_comp (exp)) != NULL)
- {
- error (0, 0, "bad regular expression at line %d file %s: %s",
- line_number, infofile, regex_err);
- continue;
- }
- if (re_exec (srepos) == 0)
- continue; /* no match */
-
- /* it did, so do the callback and note that we did one */
- err += callproc (repository, expanded_value);
- callback_done = 1;
- }
- (void) fclose (fp_info);
-
- /* if we fell through and didn't callback at all, do the default */
- if (callback_done == 0 && default_value != NULL)
- err += callproc (repository, default_value);
-
- /* free up space if necessary */
- if (default_value != NULL)
- free (default_value);
- if (expanded_value != NULL)
- free (expanded_value);
-
- return (err);
-}
diff --git a/gnu/usr.bin/cvs/cvs/patch.c b/gnu/usr.bin/cvs/cvs/patch.c
deleted file mode 100644
index 560f4b4d3d25..000000000000
--- a/gnu/usr.bin/cvs/cvs/patch.c
+++ /dev/null
@@ -1,615 +0,0 @@
-/*
- * Copyright (c) 1992, Brian Berliner and Jeff Polk
- * Copyright (c) 1989-1992, Brian Berliner
- *
- * You may distribute under the terms of the GNU General Public License as
- * specified in the README file that comes with the CVS 1.4 kit.
- *
- * Patch
- *
- * Create a Larry Wall format "patch" file between a previous release and the
- * current head of a module, or between two releases. Can specify the
- * release as either a date or a revision number.
- */
-
-#include "cvs.h"
-#include "getline.h"
-
-#ifndef lint
-static const char rcsid[] = "$CVSid: @(#)patch.c 1.57 94/09/30 $";
-USE(rcsid);
-#endif
-
-static RETSIGTYPE patch_cleanup PROTO((void));
-static Dtype patch_dirproc PROTO((char *dir, char *repos, char *update_dir));
-static int patch_fileproc PROTO((char *file, char *update_dir, char *repository,
- List * entries, List * srcfiles));
-static int patch_proc PROTO((int *pargc, char **argv, char *xwhere,
- char *mwhere, char *mfile, int shorten,
- int local_specified, char *mname, char *msg));
-
-static int force_tag_match = 1;
-static int patch_short = 0;
-static int toptwo_diffs = 0;
-static int local = 0;
-static char *options = NULL;
-static char *rev1 = NULL;
-static char *rev2 = NULL;
-static char *date1 = NULL;
-static char *date2 = NULL;
-static char tmpfile1[L_tmpnam+1], tmpfile2[L_tmpnam+1], tmpfile3[L_tmpnam+1];
-static int unidiff = 0;
-
-static const char *const patch_usage[] =
-{
- "Usage: %s %s [-fl] [-c|-u] [-s|-t] [-V %%d]\n",
- " -r rev|-D date [-r rev2 | -D date2] modules...\n",
- "\t-f\tForce a head revision match if tag/date not found.\n",
- "\t-l\tLocal directory only, not recursive\n",
- "\t-c\tContext diffs (default)\n",
- "\t-u\tUnidiff format.\n",
- "\t-s\tShort patch - one liner per file.\n",
- "\t-t\tTop two diffs - last change made to the file.\n",
- "\t-D date\tDate.\n",
- "\t-r rev\tRevision - symbolic or numeric.\n",
- "\t-V vers\tUse RCS Version \"vers\" for keyword expansion.\n",
- NULL
-};
-
-int
-patch (argc, argv)
- int argc;
- char **argv;
-{
- register int i;
- int c;
- int err = 0;
- DBM *db;
-
- if (argc == -1)
- usage (patch_usage);
-
- optind = 1;
- while ((c = getopt (argc, argv, "V:k:cuftsQqlRD:r:")) != -1)
- {
- switch (c)
- {
- case 'Q':
- case 'q':
-#ifdef SERVER_SUPPORT
- /* The CVS 1.5 client sends these options (in addition to
- Global_option requests), so we must ignore them. */
- if (!server_active)
-#endif
- error (1, 0,
- "-q or -Q must be specified before \"%s\"",
- command_name);
- break;
- case 'f':
- force_tag_match = 0;
- break;
- case 'l':
- local = 1;
- break;
- case 'R':
- local = 0;
- break;
- case 't':
- toptwo_diffs = 1;
- break;
- case 's':
- patch_short = 1;
- break;
- case 'D':
- if (rev2 != NULL || date2 != NULL)
- error (1, 0,
- "no more than two revisions/dates can be specified");
- if (rev1 != NULL || date1 != NULL)
- date2 = Make_Date (optarg);
- else
- date1 = Make_Date (optarg);
- break;
- case 'r':
- if (rev2 != NULL || date2 != NULL)
- error (1, 0,
- "no more than two revisions/dates can be specified");
- if (rev1 != NULL || date1 != NULL)
- rev2 = optarg;
- else
- rev1 = optarg;
- break;
- case 'k':
- if (options)
- free (options);
- options = RCS_check_kflag (optarg);
- break;
- case 'V':
- if (atoi (optarg) <= 0)
- error (1, 0, "must specify a version number to -V");
- if (options)
- free (options);
- options = xmalloc (strlen (optarg) + 1 + 2); /* for the -V */
- (void) sprintf (options, "-V%s", optarg);
- break;
- case 'u':
- unidiff = 1; /* Unidiff */
- break;
- case 'c': /* Context diff */
- unidiff = 0;
- break;
- case '?':
- default:
- usage (patch_usage);
- break;
- }
- }
- argc -= optind;
- argv += optind;
-
- /* Sanity checks */
- if (argc < 1)
- usage (patch_usage);
-
- if (toptwo_diffs && patch_short)
- error (1, 0, "-t and -s options are mutually exclusive");
- if (toptwo_diffs && (date1 != NULL || date2 != NULL ||
- rev1 != NULL || rev2 != NULL))
- error (1, 0, "must not specify revisions/dates with -t option!");
-
- if (!toptwo_diffs && (date1 == NULL && date2 == NULL &&
- rev1 == NULL && rev2 == NULL))
- error (1, 0, "must specify at least one revision/date!");
- if (date1 != NULL && date2 != NULL)
- if (RCS_datecmp (date1, date2) >= 0)
- error (1, 0, "second date must come after first date!");
-
- /* if options is NULL, make it a NULL string */
- if (options == NULL)
- options = xstrdup ("");
-
-#ifdef CLIENT_SUPPORT
- if (client_active)
- {
- /* We're the client side. Fire up the remote server. */
- start_server ();
-
- ign_setup ();
-
- if (local)
- send_arg("-l");
- if (force_tag_match)
- send_arg("-f");
- if (toptwo_diffs)
- send_arg("-t");
- if (patch_short)
- send_arg("-s");
- if (unidiff)
- send_arg("-u");
-
- if (rev1)
- option_with_arg ("-r", rev1);
- if (date1)
- client_senddate (date1);
- if (rev2)
- option_with_arg ("-r", rev2);
- if (date2)
- client_senddate (date2);
- if (options[0] != '\0')
- send_arg (options);
-
- {
- int i;
- for (i = 0; i < argc; ++i)
- send_arg (argv[i]);
- }
-
- if (fprintf (to_server, "rdiff\n") < 0)
- error (1, errno, "writing to server");
- return get_responses_and_close ();
- }
-#endif
-
- /* clean up if we get a signal */
-#ifdef SIGHUP
- (void) SIG_register (SIGHUP, patch_cleanup);
-#endif
-#ifdef SIGINT
- (void) SIG_register (SIGINT, patch_cleanup);
-#endif
-#ifdef SIGQUIT
- (void) SIG_register (SIGQUIT, patch_cleanup);
-#endif
-#ifdef SIGPIPE
- (void) SIG_register (SIGPIPE, patch_cleanup);
-#endif
-#ifdef SIGTERM
- (void) SIG_register (SIGTERM, patch_cleanup);
-#endif
-
- db = open_module ();
- for (i = 0; i < argc; i++)
- err += do_module (db, argv[i], PATCH, "Patching", patch_proc,
- (char *) NULL, 0, 0, 0, (char *) NULL);
- close_module (db);
- free (options);
- patch_cleanup ();
- return (err);
-}
-
-/*
- * callback proc for doing the real work of patching
- */
-/* ARGSUSED */
-static char where[PATH_MAX];
-static int
-patch_proc (pargc, argv, xwhere, mwhere, mfile, shorten, local_specified,
- mname, msg)
- int *pargc;
- char **argv;
- char *xwhere;
- char *mwhere;
- char *mfile;
- int shorten;
- int local_specified;
- char *mname;
- char *msg;
-{
- int err = 0;
- int which;
- char repository[PATH_MAX];
-
- (void) sprintf (repository, "%s/%s", CVSroot, argv[0]);
- (void) strcpy (where, argv[0]);
-
- /* if mfile isn't null, we need to set up to do only part of the module */
- if (mfile != NULL)
- {
- char *cp;
- char path[PATH_MAX];
-
- /* if the portion of the module is a path, put the dir part on repos */
- if ((cp = strrchr (mfile, '/')) != NULL)
- {
- *cp = '\0';
- (void) strcat (repository, "/");
- (void) strcat (repository, mfile);
- (void) strcat (where, "/");
- (void) strcat (where, mfile);
- mfile = cp + 1;
- }
-
- /* take care of the rest */
- (void) sprintf (path, "%s/%s", repository, mfile);
- if (isdir (path))
- {
- /* directory means repository gets the dir tacked on */
- (void) strcpy (repository, path);
- (void) strcat (where, "/");
- (void) strcat (where, mfile);
- }
- else
- {
- int i;
-
- /* a file means muck argv */
- for (i = 1; i < *pargc; i++)
- free (argv[i]);
- argv[1] = xstrdup (mfile);
- (*pargc) = 2;
- }
- }
-
- /* cd to the starting repository */
- if (chdir (repository) < 0)
- {
- error (0, errno, "cannot chdir to %s", repository);
- return (1);
- }
-
- if (force_tag_match)
- which = W_REPOS | W_ATTIC;
- else
- which = W_REPOS;
-
- /* start the recursion processor */
- err = start_recursion (patch_fileproc, (FILESDONEPROC) NULL, patch_dirproc,
- (DIRLEAVEPROC) NULL, *pargc - 1, argv + 1, local,
- which, 0, 1, where, 1, 1);
-
- return (err);
-}
-
-/*
- * Called to examine a particular RCS file, as appropriate with the options
- * that were set above.
- */
-/* ARGSUSED */
-static int
-patch_fileproc (file, update_dir, repository, entries, srcfiles)
- char *file;
- char *update_dir;
- char *repository;
- List *entries;
- List *srcfiles;
-{
- struct utimbuf t;
- char *vers_tag, *vers_head;
- char rcsspace[PATH_MAX];
- char *rcs = rcsspace;
- Node *p;
- RCSNode *rcsfile;
- FILE *fp1, *fp2, *fp3;
- int ret = 0;
- int isattic = 0;
- int retcode = 0;
- char file1[PATH_MAX], file2[PATH_MAX], strippath[PATH_MAX];
- char *line1, *line2;
- size_t line1_chars_allocated;
- size_t line2_chars_allocated;
- char *cp1, *cp2, *commap;
- FILE *fp;
-
- /* find the parsed rcs file */
- p = findnode (srcfiles, file);
- if (p == NULL)
- return (1);
- rcsfile = (RCSNode *) p->data;
- if ((rcsfile->flags & VALID) && (rcsfile->flags & INATTIC))
- isattic = 1;
-
- (void) sprintf (rcs, "%s%s", file, RCSEXT);
-
- /* if vers_head is NULL, may have been removed from the release */
- if (isattic && rev2 == NULL && date2 == NULL)
- vers_head = NULL;
- else
- vers_head = RCS_getversion (rcsfile, rev2, date2, force_tag_match, 0);
-
- if (toptwo_diffs)
- {
- if (vers_head == NULL)
- return (1);
-
- if (!date1)
- date1 = xmalloc (50); /* plenty big :-) */
- *date1 = '\0';
- if (RCS_getrevtime (rcsfile, vers_head, date1, 1) == -1)
- {
- if (!really_quiet)
- error (0, 0, "cannot find date in rcs file %s revision %s",
- rcs, vers_head);
- return (1);
- }
- }
- vers_tag = RCS_getversion (rcsfile, rev1, date1, force_tag_match, 0);
-
- if (vers_tag == NULL && (vers_head == NULL || isattic))
- return (0); /* nothing known about specified revs */
-
- if (vers_tag && vers_head && strcmp (vers_head, vers_tag) == 0)
- return (0); /* not changed between releases */
-
- if (patch_short)
- {
- (void) printf ("File ");
- if (vers_tag == NULL)
- (void) printf ("%s is new; current revision %s\n", rcs, vers_head);
- else if (vers_head == NULL)
-#ifdef DEATH_SUPPORT
- {
- (void) printf ("%s is removed; not included in ", rcs);
- if (rev2 != NULL)
- (void) printf ("release tag %s", rev2);
- else if (date2 != NULL)
- (void) printf ("release date %s", date2);
- else
- (void) printf ("current release");
- (void) printf ("\n");
- }
-#else
- (void) printf ("%s is removed; not included in release %s\n",
- rcs, rev2 ? rev2 : date2);
-#endif
- else
- (void) printf ("%s changed from revision %s to %s\n",
- rcs, vers_tag, vers_head);
- return (0);
- }
- if ((fp1 = fopen (tmpnam (tmpfile1), "w+")) != NULL)
- (void) fclose (fp1);
- if ((fp2 = fopen (tmpnam (tmpfile2), "w+")) != NULL)
- (void) fclose (fp2);
- if ((fp3 = fopen (tmpnam (tmpfile3), "w+")) != NULL)
- (void) fclose (fp3);
- if (fp1 == NULL || fp2 == NULL || fp3 == NULL)
- {
- error (0, 0, "cannot create temporary files");
- ret = 1;
- goto out;
- }
- if (vers_tag != NULL)
- {
- run_setup ("%s%s %s -p -q -r%s", Rcsbin, RCS_CO, options, vers_tag);
- run_arg (rcsfile->path);
- if ((retcode = run_exec (RUN_TTY, tmpfile1, RUN_TTY, RUN_NORMAL)) != 0)
- {
- if (!really_quiet)
- error (retcode == -1 ? 1 : 0, retcode == -1 ? errno : 0,
- "co of revision %s in %s failed", vers_tag, rcs);
- ret = 1;
- goto out;
- }
- memset ((char *) &t, 0, sizeof (t));
- if ((t.actime = t.modtime = RCS_getrevtime (rcsfile, vers_tag,
- (char *) 0, 0)) != -1)
- (void) utime (tmpfile1, &t);
- }
- else if (toptwo_diffs)
- {
- ret = 1;
- goto out;
- }
- if (vers_head != NULL)
- {
- run_setup ("%s%s %s -p -q -r%s", Rcsbin, RCS_CO, options, vers_head);
- run_arg (rcsfile->path);
- if ((retcode = run_exec (RUN_TTY, tmpfile2, RUN_TTY, RUN_NORMAL)) != 0)
- {
- if (!really_quiet)
- error (retcode == -1 ? 1 : 0, retcode == -1 ? errno : 0,
- "co of revision %s in %s failed", vers_head, rcs);
- ret = 1;
- goto out;
- }
- if ((t.actime = t.modtime = RCS_getrevtime (rcsfile, vers_head,
- (char *) 0, 0)) != -1)
- (void) utime (tmpfile2, &t);
- }
- run_setup ("%s -%c", DIFF, unidiff ? 'u' : 'c');
- run_arg (tmpfile1);
- run_arg (tmpfile2);
-
- line1 = NULL;
- line1_chars_allocated = 0;
- line2 = NULL;
- line2_chars_allocated = 0;
-
- switch (run_exec (RUN_TTY, tmpfile3, RUN_TTY, RUN_NORMAL))
- {
- case -1: /* fork/wait failure */
- error (1, errno, "fork for diff failed on %s", rcs);
- break;
- case 0: /* nothing to do */
- break;
- case 1:
- /*
- * The two revisions are really different, so read the first two
- * lines of the diff output file, and munge them to include more
- * reasonable file names that "patch" will understand.
- */
-
- /* Output an "Index:" line for patch to use */
- (void) fflush (stdout);
- if (update_dir[0])
- (void) printf ("Index: %s/%s\n", update_dir, file);
- else
- (void) printf ("Index: %s\n", file);
- (void) fflush (stdout);
-
- fp = open_file (tmpfile3, "r");
- if (getline (&line1, &line1_chars_allocated, fp) < 0 ||
- getline (&line2, &line2_chars_allocated, fp) < 0)
- {
- error (0, errno, "failed to read diff file header %s for %s",
- tmpfile3, rcs);
- ret = 1;
- (void) fclose (fp);
- goto out;
- }
- if (!unidiff)
- {
- if (strncmp (line1, "*** ", 4) != 0 ||
- strncmp (line2, "--- ", 4) != 0 ||
- (cp1 = strchr (line1, '\t')) == NULL ||
- (cp2 = strchr (line2, '\t')) == NULL)
- {
- error (0, 0, "invalid diff header for %s", rcs);
- ret = 1;
- (void) fclose (fp);
- goto out;
- }
- }
- else
- {
- if (strncmp (line1, "--- ", 4) != 0 ||
- strncmp (line2, "+++ ", 4) != 0 ||
- (cp1 = strchr (line1, '\t')) == NULL ||
- (cp2 = strchr (line2, '\t')) == NULL)
- {
- error (0, 0, "invalid unidiff header for %s", rcs);
- ret = 1;
- (void) fclose (fp);
- goto out;
- }
- }
- if (CVSroot != NULL)
- (void) sprintf (strippath, "%s/", CVSroot);
- else
- (void) strcpy (strippath, REPOS_STRIP);
- if (strncmp (rcs, strippath, strlen (strippath)) == 0)
- rcs += strlen (strippath);
- commap = strrchr (rcs, ',');
- *commap = '\0';
- if (vers_tag != NULL)
- {
- (void) sprintf (file1, "%s%s%s:%s", update_dir,
- update_dir[0] ? "/" : "", rcs, vers_tag);
- }
- else
- {
- (void) strcpy (file1, DEVNULL);
- }
- (void) sprintf (file2, "%s%s%s:%s", update_dir,
- update_dir[0] ? "/" : "", rcs,
- vers_head ? vers_head : "removed");
- if (unidiff)
- {
- (void) printf ("diff -u %s %s\n", file1, file2);
- (void) printf ("--- %s%s+++ ", file1, cp1);
- }
- else
- {
- (void) printf ("diff -c %s %s\n", file1, file2);
- (void) printf ("*** %s%s--- ", file1, cp1);
- }
-
- if (update_dir[0] != '\0')
- (void) printf ("%s/", update_dir);
- (void) printf ("%s%s", rcs, cp2);
- /* spew the rest of the diff out */
- while (getline (&line1, &line1_chars_allocated, fp) >= 0)
- (void) fputs (line1, stdout);
- (void) fclose (fp);
- break;
- default:
- error (0, 0, "diff failed for %s", rcs);
- }
- out:
- if (line1)
- free (line1);
- if (line2)
- free (line2);
- (void) unlink_file (tmpfile1);
- (void) unlink_file (tmpfile2);
- (void) unlink_file (tmpfile3);
- return (ret);
-}
-
-/*
- * Print a warm fuzzy message
- */
-/* ARGSUSED */
-static Dtype
-patch_dirproc (dir, repos, update_dir)
- char *dir;
- char *repos;
- char *update_dir;
-{
- if (!quiet)
- error (0, 0, "Diffing %s", update_dir);
- return (R_PROCESS);
-}
-
-/*
- * Clean up temporary files
- */
-static RETSIGTYPE
-patch_cleanup ()
-{
- if (tmpfile1[0] != '\0')
- (void) unlink_file (tmpfile1);
- if (tmpfile2[0] != '\0')
- (void) unlink_file (tmpfile2);
- if (tmpfile3[0] != '\0')
- (void) unlink_file (tmpfile3);
-}
diff --git a/gnu/usr.bin/cvs/cvs/patchlevel.h b/gnu/usr.bin/cvs/cvs/patchlevel.h
deleted file mode 100644
index 50d3863dcd40..000000000000
--- a/gnu/usr.bin/cvs/cvs/patchlevel.h
+++ /dev/null
@@ -1 +0,0 @@
-#define PATCHLEVEL 2
diff --git a/gnu/usr.bin/cvs/cvs/rcs.c b/gnu/usr.bin/cvs/cvs/rcs.c
deleted file mode 100644
index 43282a668ff3..000000000000
--- a/gnu/usr.bin/cvs/cvs/rcs.c
+++ /dev/null
@@ -1,1726 +0,0 @@
-/*
- * Copyright (c) 1992, Brian Berliner and Jeff Polk
- *
- * You may distribute under the terms of the GNU General Public License as
- * specified in the README file that comes with the CVS 1.4 kit.
- *
- * The routines contained in this file do all the rcs file parsing and
- * manipulation
- */
-
-#include <assert.h>
-#include "cvs.h"
-
-#ifndef lint
-static const char rcsid[] = "$CVSid: @(#)rcs.c 1.40 94/10/07 $";
-USE(rcsid);
-#endif
-
-static RCSNode *RCS_parsercsfile_i PROTO((FILE * fp, const char *rcsfile));
-static char *RCS_getdatebranch PROTO((RCSNode * rcs, char *date, char *branch));
-static int getrcskey PROTO((FILE * fp, char **keyp, char **valp));
-static int parse_rcs_proc PROTO((Node * file, void *closure));
-static int checkmagic_proc PROTO((Node *p, void *closure));
-static void do_branches PROTO((List * list, char *val));
-static void do_symbols PROTO((List * list, char *val));
-static void null_delproc PROTO((Node * p));
-static void rcsnode_delproc PROTO((Node * p));
-static void rcsvers_delproc PROTO((Node * p));
-
-static List *rcslist;
-static char *repository;
-
-/*
- * We don't want to use isspace() from the C library because:
- *
- * 1. The definition of "whitespace" in RCS files includes ASCII
- * backspace, but the C locale doesn't.
- * 2. isspace is an very expensive function call in some implementations
- * due to the addition of wide character support.
- */
-static const char spacetab[] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, /* 0x00 - 0x0f */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10 - 0x1f */
- 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x20 - 0x2f */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x30 - 0x3f */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x40 - 0x4f */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x50 - 0x5f */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x60 - 0x8f */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x70 - 0x7f */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x80 - 0x8f */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x90 - 0x9f */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xa0 - 0xaf */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xb0 - 0xbf */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xc0 - 0xcf */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xd0 - 0xdf */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xe0 - 0xef */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 /* 0xf0 - 0xff */
-};
-
-#define whitespace(c) (spacetab[(unsigned char)c] != 0)
-
-/*
- * Parse all the rcs files specified and return a list
- */
-List *
-RCS_parsefiles (files, xrepos)
- List *files;
- char *xrepos;
-{
- /* initialize */
- repository = xrepos;
- rcslist = getlist ();
-
- /* walk the list parsing files */
- if (walklist (files, parse_rcs_proc, NULL) != 0)
- {
- /* free the list and return NULL on error */
- dellist (&rcslist);
- return ((List *) NULL);
- }
- else
- /* return the list we built */
- return (rcslist);
-}
-
-/*
- * Parse an rcs file into a node on the rcs list
- */
-static int
-parse_rcs_proc (file, closure)
- Node *file;
- void *closure;
-{
- RCSNode *rdata;
-
- /* parse the rcs file into rdata */
- rdata = RCS_parse (file->key, repository);
-
- /* if we got a valid RCSNode back, put it on the list */
- if (rdata != (RCSNode *) NULL)
- RCS_addnode (file->key, rdata, rcslist);
-
- return (0);
-}
-
-/*
- * Add an RCSNode to a list of them.
- */
-
-void
-RCS_addnode (file, rcs, list)
- const char *file;
- RCSNode *rcs;
- List *list;
-{
- Node *p;
-
- p = getnode ();
- p->key = xstrdup (file);
- p->delproc = rcsnode_delproc;
- p->type = RCSNODE;
- p->data = (char *) rcs;
- (void) addnode (list, p);
-}
-
-
-/*
- * Parse an rcsfile given a user file name and a repository
- */
-RCSNode *
-RCS_parse (file, repos)
- const char *file;
- const char *repos;
-{
- RCSNode *rcs;
- FILE *fp;
- char rcsfile[PATH_MAX];
-
-#ifdef LINES_CRLF_TERMINATED
- /* Some ports of RCS to Windows NT write RCS files with newline-
- delimited lines. We would need to pass fopen a "binary" flag. */
- abort ();
-#endif
-
- (void) sprintf (rcsfile, "%s/%s%s", repos, file, RCSEXT);
- if ((fp = fopen (rcsfile, "r")) != NULL)
- {
- rcs = RCS_parsercsfile_i(fp, rcsfile);
- if (rcs != NULL)
- rcs->flags |= VALID;
-
- fclose (fp);
- return (rcs);
- }
- else if (! existence_error (errno))
- {
- error (0, errno, "cannot open %s", rcsfile);
- return NULL;
- }
-
-#ifdef LINES_CRLF_TERMINATED
- /* Some ports of RCS to Windows NT write RCS files with newline-
- delimited lines. We would need to pass fopen a "binary" flag. */
- abort ();
-#endif
-
- (void) sprintf (rcsfile, "%s/%s/%s%s", repos, CVSATTIC, file, RCSEXT);
- if ((fp = fopen (rcsfile, "r")) != NULL)
- {
- rcs = RCS_parsercsfile_i(fp, rcsfile);
- if (rcs != NULL)
- {
- rcs->flags |= INATTIC;
- rcs->flags |= VALID;
- }
-
- fclose (fp);
- return (rcs);
- }
- else if (! existence_error (errno))
- {
- error (0, errno, "cannot open %s", rcsfile);
- return NULL;
- }
-
- return (NULL);
-}
-
-/*
- * Parse a specific rcsfile.
- */
-RCSNode *
-RCS_parsercsfile (rcsfile)
- char *rcsfile;
-{
- FILE *fp;
- RCSNode *rcs;
-
-#ifdef LINES_CRLF_TERMINATED
- /* Some ports of RCS to Windows NT write RCS files with newline-
- delimited lines. We would need to pass fopen a "binary" flag. */
- abort ();
-#endif
-
- /* open the rcsfile */
- if ((fp = fopen (rcsfile, "r")) == NULL)
- {
- error (0, errno, "Couldn't open rcs file `%s'", rcsfile);
- return (NULL);
- }
-
- rcs = RCS_parsercsfile_i (fp, rcsfile);
-
- fclose (fp);
- return (rcs);
-}
-
-
-/*
- */
-static RCSNode *
-RCS_parsercsfile_i (fp, rcsfile)
- FILE *fp;
- const char *rcsfile;
-{
- RCSNode *rdata;
- char *key, *value;
-
- /* make a node */
- rdata = (RCSNode *) xmalloc (sizeof (RCSNode));
- memset ((char *) rdata, 0, sizeof (RCSNode));
- rdata->refcount = 1;
- rdata->path = xstrdup (rcsfile);
-
- /* Process HEAD and BRANCH keywords from the RCS header.
- *
- * Most cvs operatations on the main branch don't need any more
- * information. Those that do call XXX to completely parse the
- * RCS file. */
-
- if (getrcskey (fp, &key, &value) == -1 || key == NULL)
- goto l_error;
-
- if (strcmp (RCSHEAD, key) == 0 && value != NULL)
- rdata->head = xstrdup (value);
-
- if (getrcskey (fp, &key, &value) == -1 || key == NULL)
- goto l_error;
-
- if (strcmp (RCSBRANCH, key) == 0 && value != NULL)
- {
- char *cp;
-
- rdata->branch = xstrdup (value);
- if ((numdots (rdata->branch) & 1) != 0)
- {
- /* turn it into a branch if it's a revision */
- cp = strrchr (rdata->branch, '.');
- *cp = '\0';
- }
- }
-
- rdata->flags |= PARTIAL;
- return rdata;
-
-l_error:
- if (!really_quiet)
- {
- if (ferror(fp))
- {
- error (1, 0, "error reading `%s'", rcsfile);
- }
- else
- {
- error (0, 0, "`%s' does not appear to be a valid rcs file",
- rcsfile);
- }
- }
- freercsnode (&rdata);
- return (NULL);
-}
-
-
-/*
- * Do the real work of parsing an RCS file
- *
- * There are no allowances for error here.
- */
-void
-RCS_reparsercsfile (rdata)
- RCSNode *rdata;
-{
- FILE *fp;
- char *rcsfile;
-
- Node *q, *r;
- RCSVers *vnode;
- int n;
- char *cp;
- char *key, *value;
-
- rcsfile = rdata->path;
-
-#ifdef LINES_CRLF_TERMINATED
- /* Some ports of RCS to Windows NT write RCS files with newline-
- delimited lines. We would need to pass fopen a "binary" flag. */
- abort ();
-#endif
-
- fp = fopen(rcsfile, "r");
- if (fp == NULL)
- error (1, 0, "unable to reopen `%s'", rcsfile);
-
- /* make a node */
- rdata->versions = getlist ();
- rdata->dates = getlist ();
-
- /*
- * process all the special header information, break out when we get to
- * the first revision delta
- */
- for (;;)
- {
- /* get the next key/value pair */
-
- /* if key is NULL here, then the file is missing some headers
- or we had trouble reading the file. */
- if (getrcskey (fp, &key, &value) == -1 || key == NULL)
- {
- if (ferror(fp))
- {
- error (1, 0, "error reading `%s'", rcsfile);
- }
- else
- {
- error (1, 0, "`%s' does not appear to be a valid rcs file",
- rcsfile);
- }
- }
-
- if (strcmp (RCSSYMBOLS, key) == 0)
- {
- if (value != NULL)
- {
- rdata->symbols_data = xstrdup(value);
- continue;
- }
- }
-
- if (strcmp (RCSEXPAND, key) == 0)
- {
- rdata->expand = xstrdup (value);
- continue;
- }
-
- /*
- * check key for '.''s and digits (probably a rev) if it is a
- * revision, we are done with the headers and are down to the
- * revision deltas, so we break out of the loop
- */
- for (cp = key; (isdigit (*cp) || *cp == '.') && *cp != '\0'; cp++)
- /* do nothing */ ;
- if (*cp == '\0' && strncmp (RCSDATE, value, strlen (RCSDATE)) == 0)
- break;
-
- /* if we haven't grabbed it yet, we didn't want it */
- }
-
- /*
- * we got out of the loop, so we have the first part of the first
- * revision delta in our hand key=the revision and value=the date key and
- * its value
- */
- for (;;)
- {
- char *valp;
- char date[MAXDATELEN];
-
- /* grab the value of the date from value */
- valp = value + strlen (RCSDATE);/* skip the "date" keyword */
- while (whitespace (*valp)) /* take space off front of value */
- valp++;
- (void) strcpy (date, valp);
-
- /* get the nodes (q is by version, r is by date) */
- q = getnode ();
- r = getnode ();
- q->type = RCSVERS;
- r->type = RCSVERS;
- q->delproc = rcsvers_delproc;
- r->delproc = null_delproc;
- q->data = r->data = xmalloc (sizeof (RCSVers));
- memset (q->data, 0, sizeof (RCSVers));
- vnode = (RCSVers *) q->data;
-
- /* fill in the version before we forget it */
- q->key = vnode->version = xstrdup (key);
-
- /* throw away the author field */
- (void) getrcskey (fp, &key, &value);
-
- /* throw away the state field */
- (void) getrcskey (fp, &key, &value);
-#ifdef DEATH_SUPPORT
- /* Accept this regardless of DEATH_STATE, so that we can read
- repositories created with different versions of CVS. */
- if (strcmp (key, "state") != 0)
- error (1, 0, "\
-unable to parse rcs file; `state' not in the expected place");
- if (strcmp (value, "dead") == 0)
- {
- vnode->dead = 1;
- }
-#endif
-
- /* fill in the date field */
- r->key = vnode->date = xstrdup (date);
-
- /* fill in the branch list (if any branches exist) */
- (void) getrcskey (fp, &key, &value);
- if (value != (char *) NULL)
- {
- vnode->branches = getlist ();
- do_branches (vnode->branches, value);
- }
-
- /* fill in the next field if there is a next revision */
- (void) getrcskey (fp, &key, &value);
- if (value != (char *) NULL)
- vnode->next = xstrdup (value);
-
- /*
- * at this point, we skip any user defined fields XXX - this is where
- * we put the symbolic link stuff???
- */
- while ((n = getrcskey (fp, &key, &value)) >= 0)
- {
-#ifdef DEATH_SUPPORT
- /* Enable use of repositories created with a CVS which defines
- DEATH_SUPPORT and not DEATH_STATE. */
- if (strcmp(key, RCSDEAD) == 0)
- {
- vnode->dead = 1;
- continue;
- }
-#endif
- /* if we have a revision, break and do it */
- for (cp = key; (isdigit (*cp) || *cp == '.') && *cp != '\0'; cp++)
- /* do nothing */ ;
- if (*cp == '\0' && strncmp (RCSDATE, value, strlen (RCSDATE)) == 0)
- break;
- }
-
- /* add the nodes to the lists */
- (void) addnode (rdata->versions, q);
- (void) addnode (rdata->dates, r);
-
- /*
- * if we left the loop because there were no more keys, we break out
- * of the revision processing loop
- */
- if (n < 0)
- break;
- }
-
- fclose (fp);
- rdata->flags &= ~PARTIAL;
-}
-
-/*
- * rcsnode_delproc - free up an RCS type node
- */
-static void
-rcsnode_delproc (p)
- Node *p;
-{
- freercsnode ((RCSNode **) & p->data);
-}
-
-/*
- * freercsnode - free up the info for an RCSNode
- */
-void
-freercsnode (rnodep)
- RCSNode **rnodep;
-{
- if (rnodep == NULL || *rnodep == NULL)
- return;
-
- ((*rnodep)->refcount)--;
- if ((*rnodep)->refcount != 0)
- {
- *rnodep = (RCSNode *) NULL;
- return;
- }
- free ((*rnodep)->path);
- dellist (&(*rnodep)->versions);
- dellist (&(*rnodep)->dates);
- if ((*rnodep)->symbols != (List *) NULL)
- dellist (&(*rnodep)->symbols);
- if ((*rnodep)->symbols_data != (char *) NULL)
- free ((*rnodep)->symbols_data);
- if ((*rnodep)->expand != NULL)
- free ((*rnodep)->expand);
- if ((*rnodep)->head != (char *) NULL)
- free ((*rnodep)->head);
- if ((*rnodep)->branch != (char *) NULL)
- free ((*rnodep)->branch);
- free ((char *) *rnodep);
- *rnodep = (RCSNode *) NULL;
-}
-
-/*
- * rcsvers_delproc - free up an RCSVers type node
- */
-static void
-rcsvers_delproc (p)
- Node *p;
-{
- RCSVers *rnode;
-
- rnode = (RCSVers *) p->data;
-
- if (rnode->branches != (List *) NULL)
- dellist (&rnode->branches);
- if (rnode->next != (char *) NULL)
- free (rnode->next);
- free ((char *) rnode);
-}
-
-/*
- * null_delproc - don't free anything since it will be free'd by someone else
- */
-/* ARGSUSED */
-static void
-null_delproc (p)
- Node *p;
-{
- /* don't do anything */
-}
-
-/*
- * getrcskey - fill in the key and value from the rcs file the algorithm is
- * as follows
- *
- * o skip whitespace o fill in key with everything up to next white
- * space or semicolon
- * o if key == "desc" then key and data are NULL and return -1
- * o if key wasn't terminated by a semicolon, skip white space and fill
- * in value with everything up to a semicolon
- * o compress all whitespace down to a single space
- * o if a word starts with @, do funky rcs processing
- * o strip whitespace off end of value or set value to NULL if it empty
- * o return 0 since we found something besides "desc"
- */
-
-static char *key = NULL;
-static char *value = NULL;
-static size_t keysize = 0;
-static size_t valsize = 0;
-
-#define ALLOCINCR 1024
-
-static int
-getrcskey (fp, keyp, valp)
- FILE *fp;
- char **keyp;
- char **valp;
-{
- char *cur, *max;
- int c;
-
- /* skip leading whitespace */
- do
- {
- c = getc (fp);
- if (c == EOF)
- {
- *keyp = (char *) NULL;
- *valp = (char *) NULL;
- return (-1);
- }
- } while (whitespace (c));
-
- /* fill in key */
- cur = key;
- max = key + keysize;
- while (!whitespace (c) && c != ';')
- {
- if (cur >= max)
- {
- key = xrealloc (key, keysize + ALLOCINCR);
- cur = key + keysize;
- keysize += ALLOCINCR;
- max = key + keysize;
- }
- *cur++ = c;
-
- c = getc (fp);
- if (c == EOF)
- {
- *keyp = (char *) NULL;
- *valp = (char *) NULL;
- return (-1);
- }
- }
- if (cur >= max)
- {
- key = xrealloc (key, keysize + ALLOCINCR);
- cur = key + keysize;
- keysize += ALLOCINCR;
- max = key + keysize;
- }
- *cur = '\0';
-
- /* if we got "desc", we are done with the file */
- if (strcmp (RCSDESC, key) == 0)
- {
- *keyp = (char *) NULL;
- *valp = (char *) NULL;
- return (-1);
- }
-
- /* skip whitespace between key and val */
- while (whitespace (c))
- {
- c = getc (fp);
- if (c == EOF)
- {
- *keyp = (char *) NULL;
- *valp = (char *) NULL;
- return (-1);
- }
- }
-
- /* if we ended key with a semicolon, there is no value */
- if (c == ';')
- {
- *keyp = key;
- *valp = (char *) NULL;
- return (0);
- }
-
- /* otherwise, there might be a value, so fill it in */
- cur = value;
- max = value + valsize;
-
- /* process the value */
- for (;;)
- {
- /* handle RCS "strings" */
- if (c == '@')
- {
- for (;;)
- {
- c = getc (fp);
- if (c == EOF)
- {
- *keyp = (char *) NULL;
- *valp = (char *) NULL;
- return (-1);
- }
-
- if (c == '@')
- {
- c = getc (fp);
- if (c == EOF)
- {
- *keyp = (char *) NULL;
- *valp = (char *) NULL;
- return (-1);
- }
-
- if (c != '@')
- break;
- }
-
- if (cur >= max)
- {
- value = xrealloc (value, valsize + ALLOCINCR);
- cur = value + valsize;
- valsize += ALLOCINCR;
- max = value + valsize;
- }
- *cur++ = c;
- }
- }
-
- /* compress whitespace down to a single space */
- if (whitespace (c))
- {
- do {
- c = getc (fp);
- if (c == EOF)
- {
- *keyp = (char *) NULL;
- *valp = (char *) NULL;
- return (-1);
- }
- } while (whitespace (c));
-
- if (cur >= max)
- {
- value = xrealloc (value, valsize + ALLOCINCR);
- cur = value + valsize;
- valsize += ALLOCINCR;
- max = value + valsize;
- }
- *cur++ = ' ';
- }
-
- /* if we got a semi-colon we are done with the entire value */
- if (c == ';')
- break;
-
- if (cur >= max)
- {
- value = xrealloc (value, valsize + ALLOCINCR);
- cur = value + valsize;
- valsize += ALLOCINCR;
- max = value + valsize;
- }
- *cur++ = c;
-
- c = getc (fp);
- if (c == EOF)
- {
- *keyp = (char *) NULL;
- *valp = (char *) NULL;
- return (-1);
- }
- }
-
- /* terminate the string */
- if (cur >= max)
- {
- value = xrealloc (value, valsize + ALLOCINCR);
- cur = value + valsize;
- valsize += ALLOCINCR;
- max = value + valsize;
- }
- *cur = '\0';
-
- /* if the string is empty, make it null */
- if (value && *value != '\0')
- *valp = value;
- else
- *valp = NULL;
- *keyp = key;
- return (0);
-}
-
-/*
- * process the symbols list of the rcs file
- */
-static void
-do_symbols (list, val)
- List *list;
- char *val;
-{
- Node *p;
- char *cp = val;
- char *tag, *rev;
-
- for (;;)
- {
- /* skip leading whitespace */
- while (whitespace (*cp))
- cp++;
-
- /* if we got to the end, we are done */
- if (*cp == '\0')
- break;
-
- /* split it up into tag and rev */
- tag = cp;
- cp = strchr (cp, ':');
- *cp++ = '\0';
- rev = cp;
- while (!whitespace (*cp) && *cp != '\0')
- cp++;
- if (*cp != '\0')
- *cp++ = '\0';
-
- /* make a new node and add it to the list */
- p = getnode ();
- p->key = xstrdup (tag);
- p->data = xstrdup (rev);
- (void) addnode (list, p);
- }
-}
-
-/*
- * process the branches list of a revision delta
- */
-static void
-do_branches (list, val)
- List *list;
- char *val;
-{
- Node *p;
- char *cp = val;
- char *branch;
-
- for (;;)
- {
- /* skip leading whitespace */
- while (whitespace (*cp))
- cp++;
-
- /* if we got to the end, we are done */
- if (*cp == '\0')
- break;
-
- /* find the end of this branch */
- branch = cp;
- while (!whitespace (*cp) && *cp != '\0')
- cp++;
- if (*cp != '\0')
- *cp++ = '\0';
-
- /* make a new node and add it to the list */
- p = getnode ();
- p->key = xstrdup (branch);
- (void) addnode (list, p);
- }
-}
-
-/*
- * Version Number
- *
- * Returns the requested version number of the RCS file, satisfying tags and/or
- * dates, and walking branches, if necessary.
- *
- * The result is returned; null-string if error.
- */
-char *
-RCS_getversion (rcs, tag, date, force_tag_match, return_both)
- RCSNode *rcs;
- char *tag;
- char *date;
- int force_tag_match;
- int return_both;
-{
- /* make sure we have something to look at... */
- assert (rcs != NULL);
-
- if (tag && date)
- {
- char *cp, *rev, *tagrev;
-
- /*
- * first lookup the tag; if that works, turn the revision into
- * a branch and lookup the date.
- */
- tagrev = RCS_gettag (rcs, tag, force_tag_match, 0);
- if (tagrev == NULL)
- return ((char *) NULL);
-
- if ((cp = strrchr (tagrev, '.')) != NULL)
- *cp = '\0';
- rev = RCS_getdatebranch (rcs, date, tagrev);
- free (tagrev);
- return (rev);
- }
- else if (tag)
- return (RCS_gettag (rcs, tag, force_tag_match, return_both));
- else if (date)
- return (RCS_getdate (rcs, date, force_tag_match));
- else
- return (RCS_head (rcs));
-
-}
-
-/*
- * Find the revision for a specific tag.
- * If force_tag_match is set, return NULL if an exact match is not
- * possible otherwise return RCS_head (). We are careful to look for
- * and handle "magic" revisions specially.
- *
- * If the matched tag is a branch tag, find the head of the branch.
- */
-char *
-RCS_gettag (rcs, symtag, force_tag_match, return_both)
- RCSNode *rcs;
- char *symtag;
- int force_tag_match;
- int return_both;
-{
- Node *p;
- char *tag = symtag;
-
- /* make sure we have something to look at... */
- assert (rcs != NULL);
-
- /* XXX this is probably not necessary, --jtc */
- if (rcs->flags & PARTIAL)
- RCS_reparsercsfile (rcs);
-
- /* If tag is "HEAD", special case to get head RCS revision */
- if (tag && (strcmp (tag, TAG_HEAD) == 0 || *tag == '\0'))
-#if 0 /* This #if 0 is only in the Cygnus code. Why? Death support? */
- if (force_tag_match && (rcs->flags & VALID) && (rcs->flags & INATTIC))
- return ((char *) NULL); /* head request for removed file */
- else
-#endif
- return (RCS_head (rcs));
-
- if (!isdigit (tag[0]))
- {
- /* If we got a symbolic tag, resolve it to a numeric */
- if (rcs == NULL)
- p = NULL;
- else {
- p = findnode (RCS_symbols(rcs), tag);
- }
- if (p != NULL)
- {
- int dots;
- char *magic, *branch, *cp;
-
- tag = p->data;
-
- /*
- * If this is a magic revision, we turn it into either its
- * physical branch equivalent (if one exists) or into
- * its base revision, which we assume exists.
- */
- dots = numdots (tag);
- if (dots > 2 && (dots & 1) != 0)
- {
- branch = strrchr (tag, '.');
- cp = branch++ - 1;
- while (*cp != '.')
- cp--;
-
- /* see if we have .magic-branch. (".0.") */
- magic = xmalloc (strlen (tag) + 1);
- (void) sprintf (magic, ".%d.", RCS_MAGIC_BRANCH);
- if (strncmp (magic, cp, strlen (magic)) == 0)
- {
- char *xtag;
-
- /* it's magic. See if the branch exists */
- *cp = '\0'; /* turn it into a revision */
- xtag = xstrdup (tag);
- *cp = '.'; /* and back again */
- (void) sprintf (magic, "%s.%s", xtag, branch);
- branch = RCS_getbranch (rcs, magic, 1);
- free (magic);
- if (branch != NULL)
- {
- free (xtag);
- return (branch);
- }
- return (xtag);
- }
- free (magic);
- }
- }
- else
- {
- /* The tag wasn't there, so return the head or NULL */
- if (force_tag_match)
- return (NULL);
- else
- return (RCS_head (rcs));
- }
- }
-
- /*
- * numeric tag processing:
- * 1) revision number - just return it
- * 2) branch number - find head of branch
- */
-
- /* strip trailing dots */
- while (tag[strlen (tag) - 1] == '.')
- tag[strlen (tag) - 1] = '\0';
-
- if ((numdots (tag) & 1) == 0)
- {
- /* we have a branch tag, so we need to walk the branch */
- return (RCS_getbranch (rcs, tag, force_tag_match));
- }
- else
- {
- /* we have a revision tag, so make sure it exists */
- if (rcs == NULL)
- p = NULL;
- else
- p = findnode (rcs->versions, tag);
- if (p != NULL)
- {
- /*
- * we have found a numeric revision for the revision tag.
- * To support expanding the RCS keyword Name, return both
- * the numeric tag and the supplied tag (which might be
- * symbolic). They are separated with a ':' which is not
- * a valid tag char. The variable return_both is only set
- * if this function is called through Version_TS ->
- * RCS_getversion.
- */
- if (return_both)
- {
- char *both = xmalloc(strlen(tag) + 2 + strlen(symtag));
- sprintf(both, "%s:%s", tag, symtag);
- return both;
- }
- else
- return (xstrdup (tag));
- }
- else
- {
- /* The revision wasn't there, so return the head or NULL */
- if (force_tag_match)
- return (NULL);
- else
- return (RCS_head (rcs));
- }
- }
-}
-
-/*
- * Return a "magic" revision as a virtual branch off of REV for the RCS file.
- * A "magic" revision is one which is unique in the RCS file. By unique, I
- * mean we return a revision which:
- * - has a branch of 0 (see rcs.h RCS_MAGIC_BRANCH)
- * - has a revision component which is not an existing branch off REV
- * - has a revision component which is not an existing magic revision
- * - is an even-numbered revision, to avoid conflicts with vendor branches
- * The first point is what makes it "magic".
- *
- * As an example, if we pass in 1.37 as REV, we will look for an existing
- * branch called 1.37.2. If it did not exist, we would look for an
- * existing symbolic tag with a numeric part equal to 1.37.0.2. If that
- * didn't exist, then we know that the 1.37.2 branch can be reserved by
- * creating a symbolic tag with 1.37.0.2 as the numeric part.
- *
- * This allows us to fork development with very little overhead -- just a
- * symbolic tag is used in the RCS file. When a commit is done, a physical
- * branch is dynamically created to hold the new revision.
- *
- * Note: We assume that REV is an RCS revision and not a branch number.
- */
-static char *check_rev;
-char *
-RCS_magicrev (rcs, rev)
- RCSNode *rcs;
- char *rev;
-{
- int rev_num;
- char *xrev, *test_branch;
-
- xrev = xmalloc (strlen (rev) + 14); /* enough for .0.number */
- check_rev = xrev;
-
- /* only look at even numbered branches */
- for (rev_num = 2; ; rev_num += 2)
- {
- /* see if the physical branch exists */
- (void) sprintf (xrev, "%s.%d", rev, rev_num);
- test_branch = RCS_getbranch (rcs, xrev, 1);
- if (test_branch != NULL) /* it did, so keep looking */
- {
- free (test_branch);
- continue;
- }
-
- /* now, create a "magic" revision */
- (void) sprintf (xrev, "%s.%d.%d", rev, RCS_MAGIC_BRANCH, rev_num);
-
- /* walk the symbols list to see if a magic one already exists */
- if (walklist (RCS_symbols(rcs), checkmagic_proc, NULL) != 0)
- continue;
-
- /* we found a free magic branch. Claim it as ours */
- return (xrev);
- }
-}
-
-/*
- * walklist proc to look for a match in the symbols list.
- * Returns 0 if the symbol does not match, 1 if it does.
- */
-static int
-checkmagic_proc (p, closure)
- Node *p;
- void *closure;
-{
- if (strcmp (check_rev, p->data) == 0)
- return (1);
- else
- return (0);
-}
-
-/*
- * Given a list of RCSNodes, returns non-zero if the specified
- * revision number or symbolic tag resolves to a "branch" within the
- * rcs file.
- */
-int
-RCS_isbranch (file, rev, srcfiles)
- char *file;
- char *rev;
- List *srcfiles;
-{
- Node *p;
- RCSNode *rcs;
-
- /* numeric revisions are easy -- even number of dots is a branch */
- if (isdigit (*rev))
- return ((numdots (rev) & 1) == 0);
-
- /* assume a revision if you can't find the RCS info */
- p = findnode (srcfiles, file);
- if (p == NULL)
- return (0);
-
- /* now, look for a match in the symbols list */
- rcs = (RCSNode *) p->data;
- return (RCS_nodeisbranch (rev, rcs));
-}
-
-/*
- * Given an RCSNode, returns non-zero if the specified revision number
- * or symbolic tag resolves to a "branch" within the rcs file. We do
- * take into account any magic branches as well.
- */
-int
-RCS_nodeisbranch (rev, rcs)
- char *rev;
- RCSNode *rcs;
-{
- int dots;
- Node *p;
-
- /* numeric revisions are easy -- even number of dots is a branch */
- if (isdigit (*rev))
- return ((numdots (rev) & 1) == 0);
-
- p = findnode (RCS_symbols(rcs), rev);
- if (p == NULL)
- return (0);
- dots = numdots (p->data);
- if ((dots & 1) == 0)
- return (1);
-
- /* got a symbolic tag match, but it's not a branch; see if it's magic */
- if (dots > 2)
- {
- char *magic;
- char *branch = strrchr (p->data, '.');
- char *cp = branch - 1;
- while (*cp != '.')
- cp--;
-
- /* see if we have .magic-branch. (".0.") */
- magic = xmalloc (strlen (p->data) + 1);
- (void) sprintf (magic, ".%d.", RCS_MAGIC_BRANCH);
- if (strncmp (magic, cp, strlen (magic)) == 0)
- {
- free (magic);
- return (1);
- }
- free (magic);
- }
- return (0);
-}
-
-/*
- * Returns a pointer to malloc'ed memory which contains the branch
- * for the specified *symbolic* tag. Magic branches are handled correctly.
- */
-char *
-RCS_whatbranch (file, rev, srcfiles)
- char *file;
- char *rev;
- List *srcfiles;
-{
- int dots;
- Node *p;
- RCSNode *rcs;
-
- /* assume no branch if you can't find the RCS info */
- p = findnode (srcfiles, file);
- if (p == NULL)
- return ((char *) NULL);
-
- /* now, look for a match in the symbols list */
- rcs = (RCSNode *) p->data;
- p = findnode (RCS_symbols(rcs), rev);
- if (p == NULL)
- return ((char *) NULL);
- dots = numdots (p->data);
- if ((dots & 1) == 0)
- return (xstrdup (p->data));
-
- /* got a symbolic tag match, but it's not a branch; see if it's magic */
- if (dots > 2)
- {
- char *magic;
- char *branch = strrchr (p->data, '.');
- char *cp = branch++ - 1;
- while (*cp != '.')
- cp--;
-
- /* see if we have .magic-branch. (".0.") */
- magic = xmalloc (strlen (p->data) + 1);
- (void) sprintf (magic, ".%d.", RCS_MAGIC_BRANCH);
- if (strncmp (magic, cp, strlen (magic)) == 0)
- {
- /* yep. it's magic. now, construct the real branch */
- *cp = '\0'; /* turn it into a revision */
- (void) sprintf (magic, "%s.%s", p->data, branch);
- *cp = '.'; /* and turn it back */
- return (magic);
- }
- free (magic);
- }
- return ((char *) NULL);
-}
-
-/*
- * Get the head of the specified branch. If the branch does not exist,
- * return NULL or RCS_head depending on force_tag_match
- */
-char *
-RCS_getbranch (rcs, tag, force_tag_match)
- RCSNode *rcs;
- char *tag;
- int force_tag_match;
-{
- Node *p, *head;
- RCSVers *vn;
- char *xtag;
- char *nextvers;
- char *cp;
-
- /* make sure we have something to look at... */
- assert (rcs != NULL);
-
- if (rcs->flags & PARTIAL)
- RCS_reparsercsfile (rcs);
-
- /* find out if the tag contains a dot, or is on the trunk */
- cp = strrchr (tag, '.');
-
- /* trunk processing is the special case */
- if (cp == NULL)
- {
- xtag = xmalloc (strlen (tag) + 1 + 1); /* +1 for an extra . */
- (void) strcpy (xtag, tag);
- (void) strcat (xtag, ".");
- for (cp = rcs->head; cp != NULL;)
- {
- if (strncmp (xtag, cp, strlen (xtag)) == 0)
- break;
- p = findnode (rcs->versions, cp);
- if (p == NULL)
- {
- free (xtag);
- if (force_tag_match)
- return (NULL);
- else
- return (RCS_head (rcs));
- }
- vn = (RCSVers *) p->data;
- cp = vn->next;
- }
- free (xtag);
- if (cp == NULL)
- {
- if (force_tag_match)
- return (NULL);
- else
- return (RCS_head (rcs));
- }
- return (xstrdup (cp));
- }
-
- /* if it had a `.', terminate the string so we have the base revision */
- *cp = '\0';
-
- /* look up the revision this branch is based on */
- p = findnode (rcs->versions, tag);
-
- /* put the . back so we have the branch again */
- *cp = '.';
-
- if (p == NULL)
- {
- /* if the base revision didn't exist, return head or NULL */
- if (force_tag_match)
- return (NULL);
- else
- return (RCS_head (rcs));
- }
-
- /* find the first element of the branch we are looking for */
- vn = (RCSVers *) p->data;
- if (vn->branches == NULL)
- return (NULL);
- xtag = xmalloc (strlen (tag) + 1 + 1); /* 1 for the extra '.' */
- (void) strcpy (xtag, tag);
- (void) strcat (xtag, ".");
- head = vn->branches->list;
- for (p = head->next; p != head; p = p->next)
- if (strncmp (p->key, xtag, strlen (xtag)) == 0)
- break;
- free (xtag);
-
- if (p == head)
- {
- /* we didn't find a match so return head or NULL */
- if (force_tag_match)
- return (NULL);
- else
- return (RCS_head (rcs));
- }
-
- /* now walk the next pointers of the branch */
- nextvers = p->key;
- do
- {
- p = findnode (rcs->versions, nextvers);
- if (p == NULL)
- {
- /* a link in the chain is missing - return head or NULL */
- if (force_tag_match)
- return (NULL);
- else
- return (RCS_head (rcs));
- }
- vn = (RCSVers *) p->data;
- nextvers = vn->next;
- } while (nextvers != NULL);
-
- /* we have the version in our hand, so go for it */
- return (xstrdup (vn->version));
-}
-
-/*
- * Get the head of the RCS file. If branch is set, this is the head of the
- * branch, otherwise the real head
- */
-char *
-RCS_head (rcs)
- RCSNode *rcs;
-{
- /* make sure we have something to look at... */
- assert (rcs != NULL);
-
- /*
- * NOTE: we call getbranch with force_tag_match set to avoid any
- * possibility of recursion
- */
- if (rcs->branch)
- return (RCS_getbranch (rcs, rcs->branch, 1));
- else
- return (xstrdup (rcs->head));
-}
-
-/*
- * Get the most recent revision, based on the supplied date, but use some
- * funky stuff and follow the vendor branch maybe
- */
-char *
-RCS_getdate (rcs, date, force_tag_match)
- RCSNode *rcs;
- char *date;
- int force_tag_match;
-{
- char *cur_rev = NULL;
- char *retval = NULL;
- Node *p;
- RCSVers *vers = NULL;
-
- /* make sure we have something to look at... */
- assert (rcs != NULL);
-
- if (rcs->flags & PARTIAL)
- RCS_reparsercsfile (rcs);
-
- /* if the head is on a branch, try the branch first */
- if (rcs->branch != NULL)
- retval = RCS_getdatebranch (rcs, date, rcs->branch);
-
- /* if we found a match, we are done */
- if (retval != NULL)
- return (retval);
-
- /* otherwise if we have a trunk, try it */
- if (rcs->head)
- {
- p = findnode (rcs->versions, rcs->head);
- while (p != NULL)
- {
- /* if the date of this one is before date, take it */
- vers = (RCSVers *) p->data;
- if (RCS_datecmp (vers->date, date) <= 0)
- {
- cur_rev = vers->version;
- break;
- }
-
- /* if there is a next version, find the node */
- if (vers->next != NULL)
- p = findnode (rcs->versions, vers->next);
- else
- p = (Node *) NULL;
- }
- }
-
- /*
- * at this point, either we have the revision we want, or we have the
- * first revision on the trunk (1.1?) in our hands
- */
-
- /* if we found what we're looking for, and it's not 1.1 return it */
- if (cur_rev != NULL && strcmp (cur_rev, "1.1") != 0)
- return (xstrdup (cur_rev));
-
- /* look on the vendor branch */
- retval = RCS_getdatebranch (rcs, date, CVSBRANCH);
-
- /*
- * if we found a match, return it; otherwise, we return the first
- * revision on the trunk or NULL depending on force_tag_match and the
- * date of the first rev
- */
- if (retval != NULL)
- return (retval);
-
- if (!force_tag_match || RCS_datecmp (vers->date, date) <= 0)
- return (xstrdup (vers->version));
- else
- return (NULL);
-}
-
-/*
- * Look up the last element on a branch that was put in before the specified
- * date (return the rev or NULL)
- */
-static char *
-RCS_getdatebranch (rcs, date, branch)
- RCSNode *rcs;
- char *date;
- char *branch;
-{
- char *cur_rev = NULL;
- char *cp;
- char *xbranch, *xrev;
- Node *p;
- RCSVers *vers;
-
- /* look up the first revision on the branch */
- xrev = xstrdup (branch);
- cp = strrchr (xrev, '.');
- if (cp == NULL)
- {
- free (xrev);
- return (NULL);
- }
- *cp = '\0'; /* turn it into a revision */
-
- assert (rcs != NULL);
-
- if (rcs->flags & PARTIAL)
- RCS_reparsercsfile (rcs);
-
- p = findnode (rcs->versions, xrev);
- free (xrev);
- if (p == NULL)
- return (NULL);
- vers = (RCSVers *) p->data;
-
- /* if no branches list, return NULL */
- if (vers->branches == NULL)
- return (NULL);
-
- /* walk the branches list looking for the branch number */
- xbranch = xmalloc (strlen (branch) + 1 + 1); /* +1 for the extra dot */
- (void) strcpy (xbranch, branch);
- (void) strcat (xbranch, ".");
- for (p = vers->branches->list->next; p != vers->branches->list; p = p->next)
- if (strncmp (p->key, xbranch, strlen (xbranch)) == 0)
- break;
- free (xbranch);
- if (p == vers->branches->list)
- return (NULL);
-
- p = findnode (rcs->versions, p->key);
-
- /* walk the next pointers until you find the end, or the date is too late */
- while (p != NULL)
- {
- vers = (RCSVers *) p->data;
- if (RCS_datecmp (vers->date, date) <= 0)
- cur_rev = vers->version;
- else
- break;
-
- /* if there is a next version, find the node */
- if (vers->next != NULL)
- p = findnode (rcs->versions, vers->next);
- else
- p = (Node *) NULL;
- }
-
- /* if we found something acceptable, return it - otherwise NULL */
- if (cur_rev != NULL)
- return (xstrdup (cur_rev));
- else
- return (NULL);
-}
-
-/*
- * Compare two dates in RCS format. Beware the change in format on January 1,
- * 2000, when years go from 2-digit to full format.
- */
-int
-RCS_datecmp (date1, date2)
- char *date1, *date2;
-{
- int length_diff = strlen (date1) - strlen (date2);
-
- return (length_diff ? length_diff : strcmp (date1, date2));
-}
-
-/*
- * Lookup the specified revision in the ,v file and return, in the date
- * argument, the date specified for the revision *minus one second*, so that
- * the logically previous revision will be found later.
- *
- * Returns zero on failure, RCS revision time as a Unix "time_t" on success.
- */
-time_t
-RCS_getrevtime (rcs, rev, date, fudge)
- RCSNode *rcs;
- char *rev;
- char *date;
- int fudge;
-{
- char tdate[MAXDATELEN];
- struct tm xtm, *ftm;
- time_t revdate = 0;
- Node *p;
- RCSVers *vers;
-
- /* make sure we have something to look at... */
- assert (rcs != NULL);
-
- if (rcs->flags & PARTIAL)
- RCS_reparsercsfile (rcs);
-
- /* look up the revision */
- p = findnode (rcs->versions, rev);
- if (p == NULL)
- return (-1);
- vers = (RCSVers *) p->data;
-
- /* split up the date */
- ftm = &xtm;
- (void) sscanf (vers->date, SDATEFORM, &ftm->tm_year, &ftm->tm_mon,
- &ftm->tm_mday, &ftm->tm_hour, &ftm->tm_min,
- &ftm->tm_sec);
- if (ftm->tm_year > 1900)
- ftm->tm_year -= 1900;
-
- /* put the date in a form getdate can grok */
-#ifdef HAVE_RCS5
- (void) sprintf (tdate, "%d/%d/%d GMT %d:%d:%d", ftm->tm_mon,
- ftm->tm_mday, ftm->tm_year, ftm->tm_hour,
- ftm->tm_min, ftm->tm_sec);
-#else
- (void) sprintf (tdate, "%d/%d/%d %d:%d:%d", ftm->tm_mon,
- ftm->tm_mday, ftm->tm_year, ftm->tm_hour,
- ftm->tm_min, ftm->tm_sec);
-#endif
-
- /* turn it into seconds since the epoch */
- revdate = get_date (tdate, (struct timeb *) NULL);
- if (revdate != (time_t) -1)
- {
- revdate -= fudge; /* remove "fudge" seconds */
- if (date)
- {
- /* put an appropriate string into ``date'' if we were given one */
-#ifdef HAVE_RCS5
- ftm = gmtime (&revdate);
-#else
- ftm = localtime (&revdate);
-#endif
- (void) sprintf (date, DATEFORM,
- ftm->tm_year + (ftm->tm_year < 100 ? 0 : 1900),
- ftm->tm_mon + 1, ftm->tm_mday, ftm->tm_hour,
- ftm->tm_min, ftm->tm_sec);
- }
- }
- return (revdate);
-}
-
-List *
-RCS_symbols(rcs)
- RCSNode *rcs;
-{
- assert(rcs != NULL);
-
- if (rcs->flags & PARTIAL)
- RCS_reparsercsfile (rcs);
-
- if (rcs->symbols_data) {
- rcs->symbols = getlist ();
- do_symbols (rcs->symbols, rcs->symbols_data);
- free(rcs->symbols_data);
- rcs->symbols_data = NULL;
- }
-
- return rcs->symbols;
-}
-
-/*
- * The argument ARG is the getopt remainder of the -k option specified on the
- * command line. This function returns malloc'ed space that can be used
- * directly in calls to RCS V5, with the -k flag munged correctly.
- */
-char *
-RCS_check_kflag (arg)
- const char *arg;
-{
- static const char *const kflags[] =
- {"kv", "kvl", "k", "v", "o", "b", (char *) NULL};
- static const char *const keyword_usage[] =
- {
- "%s %s: invalid RCS keyword expansion mode\n",
- "Valid expansion modes include:\n",
- " -kkv\tGenerate keywords using the default form.\n",
- " -kkvl\tLike -kkv, except locker's name inserted.\n",
- " -kk\tGenerate only keyword names in keyword strings.\n",
- " -kv\tGenerate only keyword values in keyword strings.\n",
- " -ko\tGenerate the old keyword string (no changes from checked in file).\n",
- " -kb\tGenerate binary file unmodified (merges not allowed) (RCS 5.7).\n",
- NULL,
- };
- char karg[10];
- char const *const *cpp = NULL;
-
-#ifndef HAVE_RCS5
- error (1, 0, "%s %s: your version of RCS does not support the -k option",
- program_name, command_name);
-#endif
-
- if (arg)
- {
- for (cpp = kflags; *cpp != NULL; cpp++)
- {
- if (strcmp (arg, *cpp) == 0)
- break;
- }
- }
-
- if (arg == NULL || *cpp == NULL)
- {
- usage (keyword_usage);
- }
-
- (void) sprintf (karg, "-k%s", *cpp);
- return (xstrdup (karg));
-}
-
-/*
- * Do some consistency checks on the symbolic tag... These should equate
- * pretty close to what RCS checks, though I don't know for certain.
- */
-void
-RCS_check_tag (tag)
- const char *tag;
-{
- char *invalid = "$,.:;@"; /* invalid RCS tag characters */
- const char *cp;
-
- /*
- * The first character must be an alphabetic letter. The remaining
- * characters cannot be non-visible graphic characters, and must not be
- * in the set of "invalid" RCS identifier characters.
- */
- if (isalpha (*tag))
- {
- for (cp = tag; *cp; cp++)
- {
- if (!isgraph (*cp))
- error (1, 0, "tag `%s' has non-visible graphic characters",
- tag);
- if (strchr (invalid, *cp))
- error (1, 0, "tag `%s' must not contain the characters `%s'",
- tag, invalid);
- }
- }
- else
- error (1, 0, "tag `%s' must start with a letter", tag);
-}
-
-#ifdef DEATH_SUPPORT
-/*
- * Return true if RCS revision with TAG is a dead revision.
- */
-int
-RCS_isdead (rcs, tag)
- RCSNode *rcs;
- const char *tag;
-{
- Node *p;
- RCSVers *version;
-
- if (rcs->flags & PARTIAL)
- RCS_reparsercsfile (rcs);
-
- p = findnode (rcs->versions, tag);
- if (p == NULL)
- return (0);
-
- version = (RCSVers *) p->data;
- return (version->dead);
-}
-#endif /* DEATH_SUPPORT */
diff --git a/gnu/usr.bin/cvs/cvs/rcs.h b/gnu/usr.bin/cvs/cvs/rcs.h
deleted file mode 100644
index f64501d71e6b..000000000000
--- a/gnu/usr.bin/cvs/cvs/rcs.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/* $CVSid: @(#)rcs.h 1.18 94/09/23 $ */
-
-/*
- * Copyright (c) 1992, Brian Berliner and Jeff Polk
- * Copyright (c) 1989-1992, Brian Berliner
- *
- * You may distribute under the terms of the GNU General Public License as
- * specified in the README file that comes with the CVS 1.4 kit.
- *
- * RCS source control definitions needed by rcs.c and friends
- */
-
-#define RCS "rcs"
-#define RCS_CI "ci"
-#define RCS_CO "co"
-#define RCS_RLOG "rlog"
-#define RCS_DIFF "rcsdiff"
-#define RCS_MERGE "merge"
-#define RCS_RCSMERGE "rcsmerge"
-#define RCS_MERGE_PAT "^>>>>>>> " /* runs "grep" with this pattern */
-#define RCSEXT ",v"
-#define RCSPAT "*,v"
-#define RCSHEAD "head"
-#define RCSBRANCH "branch"
-#define RCSSYMBOLS "symbols"
-#define RCSDATE "date"
-#define RCSDESC "desc"
-#define RCSEXPAND "expand"
-
-/* Used by the version of death support which results if you define
- DEATH_SUPPORT and not DEATH_STATE. Requires a hacked up RCS. Considered
- obsolete. */
-#define RCSDEAD "dead"
-
-#define DATEFORM "%02d.%02d.%02d.%02d.%02d.%02d"
-#define SDATEFORM "%d.%d.%d.%d.%d.%d"
-
-/*
- * Opaque structure definitions used by RCS specific lookup routines
- */
-#define VALID 0x1 /* flags field contains valid data */
-#define INATTIC 0x2 /* RCS file is located in the Attic */
-#define PARTIAL 0x4 /* RCS file not completly parsed */
-
-struct rcsnode
-{
- int refcount;
- int flags;
- char *path;
- char *head;
- char *branch;
- char *symbols_data;
- char *expand;
- List *symbols;
- List *versions;
- List *dates;
-};
-
-typedef struct rcsnode RCSNode;
-
-struct rcsversnode
-{
- char *version;
- char *date;
- char *next;
- int dead;
- List *branches;
-};
-typedef struct rcsversnode RCSVers;
-
-/*
- * CVS reserves all even-numbered branches for its own use. "magic" branches
- * (see rcs.c) are contained as virtual revision numbers (within symbolic
- * tags only) off the RCS_MAGIC_BRANCH, which is 0. CVS also reserves the
- * ".1" branch for vendor revisions. So, if you do your own branching, you
- * should limit your use to odd branch numbers starting at 3.
- */
-#define RCS_MAGIC_BRANCH 0
-
-/*
- * exported interfaces
- */
-List *RCS_parsefiles PROTO((List * files, char *xrepos));
-RCSNode *RCS_parse PROTO((const char *file, const char *repos));
-RCSNode *RCS_parsercsfile PROTO((char *rcsfile));
-char *RCS_check_kflag PROTO((const char *arg));
-char *RCS_getdate PROTO((RCSNode * rcs, char *date, int force_tag_match));
-char *RCS_gettag PROTO((RCSNode * rcs, char *symtag, int force_tag_match,
- int return_both));
-char *RCS_getversion PROTO((RCSNode * rcs, char *tag, char *date,
- int force_tag_match, int return_both));
-char *RCS_magicrev PROTO((RCSNode *rcs, char *rev));
-int RCS_isbranch PROTO((char *file, char *rev, List *srcfiles));
-int RCS_nodeisbranch PROTO((char *rev, RCSNode *rcs));
-char *RCS_whatbranch PROTO((char *file, char *tag, List *srcfiles));
-char *RCS_head PROTO((RCSNode * rcs));
-int RCS_datecmp PROTO((char *date1, char *date2));
-time_t RCS_getrevtime PROTO((RCSNode * rcs, char *rev, char *date, int fudge));
-List *RCS_symbols PROTO((RCSNode *rcs));
-void RCS_check_tag PROTO((const char *tag));
-void freercsnode PROTO((RCSNode ** rnodep));
-void RCS_addnode PROTO((const char *file, RCSNode *rcs, List *list));
-char *RCS_getbranch PROTO((RCSNode * rcs, char *tag, int force_tag_match));
-
-#ifdef DEATH_SUPPORT
-int RCS_isdead PROTO((RCSNode *, const char *));
-#endif
diff --git a/gnu/usr.bin/cvs/cvs/rcscmds.c b/gnu/usr.bin/cvs/cvs/rcscmds.c
deleted file mode 100644
index af32cea1d6d9..000000000000
--- a/gnu/usr.bin/cvs/cvs/rcscmds.c
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright (c) 1992, Brian Berliner and Jeff Polk
- * Copyright (c) 1989-1992, Brian Berliner
- *
- * You may distribute under the terms of the GNU General Public License as
- * specified in the README file that comes with the CVS 1.4 kit.
- *
- * The functions in this file provide an interface for performing
- * operations directly on RCS files.
- */
-
-#include "cvs.h"
-
-int
-RCS_settag(path, tag, rev)
- const char *path;
- const char *tag;
- const char *rev;
-{
- run_setup ("%s%s -q -N%s:%s", Rcsbin, RCS, tag, rev);
- run_arg (path);
- return run_exec (RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL);
-}
-
-/* NOERR is 1 to suppress errors--FIXME it would
- be better to avoid the errors or some cleaner solution. */
-int
-RCS_deltag(path, tag, noerr)
- const char *path;
- const char *tag;
- int noerr;
-{
- run_setup ("%s%s -q -N%s", Rcsbin, RCS, tag);
- run_arg (path);
- return run_exec (RUN_TTY, RUN_TTY, noerr ? DEVNULL : RUN_TTY, RUN_NORMAL);
-}
-
-/* set RCS branch to REV */
-int
-RCS_setbranch(path, rev)
- const char *path;
- const char *rev;
-{
- run_setup ("%s%s -q -b%s", Rcsbin, RCS, rev ? rev : "");
- run_arg (path);
- return run_exec (RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL);
-}
-
-/* Lock revision REV. NOERR is 1 to suppress errors--FIXME it would
- be better to avoid the errors or some cleaner solution. */
-int
-RCS_lock(path, rev, noerr)
- const char *path;
- const char *rev;
- int noerr;
-{
- run_setup ("%s%s -q -l%s", Rcsbin, RCS, rev ? rev : "");
- run_arg (path);
- return run_exec (RUN_TTY, RUN_TTY, noerr ? DEVNULL : RUN_TTY, RUN_NORMAL);
-}
-
-/* Unlock revision REV. NOERR is 1 to suppress errors--FIXME it would
- be better to avoid the errors or some cleaner solution. */
-int
-RCS_unlock(path, rev, noerr)
- const char *path;
- const char *rev;
- int noerr;
-{
- run_setup ("%s%s -q -u%s", Rcsbin, RCS, rev ? rev : "");
- run_arg (path);
- return run_exec (RUN_TTY, RUN_TTY, noerr ? DEVNULL : RUN_TTY, RUN_NORMAL);
-}
-
-/* Merge revisions REV1 and REV2. */
-int
-RCS_merge(path, options, rev1, rev2)
- const char *path;
- const char *options;
- const char *rev1;
- const char *rev2;
-{
- int status;
-
- /* XXX - Do merge by hand instead of using rcsmerge, due to -k handling */
-
- run_setup ("%s%s %s -r%s -r%s %s", Rcsbin, RCS_RCSMERGE,
- options, rev1, rev2, path);
- status = run_exec (RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL);
-#ifndef HAVE_RCS5
- if (status == 0)
- {
- /* Run GREP to see if there appear to be conflicts in the file */
- run_setup ("%s", GREP);
- run_arg (RCS_MERGE_PAT);
- run_arg (path);
- status = (run_exec (RUN_TTY, DEVNULL, RUN_TTY, RUN_NORMAL) == 0);
-
- }
-#endif
- return status;
-}
diff --git a/gnu/usr.bin/cvs/cvs/recurse.c b/gnu/usr.bin/cvs/cvs/recurse.c
deleted file mode 100644
index f5d943318582..000000000000
--- a/gnu/usr.bin/cvs/cvs/recurse.c
+++ /dev/null
@@ -1,646 +0,0 @@
-/*
- * Copyright (c) 1992, Brian Berliner and Jeff Polk
- *
- * You may distribute under the terms of the GNU General Public License as
- * specified in the README file that comes with the CVS 1.4 kit.
- *
- * General recursion handler
- *
- */
-
-#include "cvs.h"
-#include "save-cwd.h"
-
-#ifndef lint
-static const char rcsid[] = "$CVSid: @(#)recurse.c 1.31 94/09/30 $";
-USE(rcsid);
-#endif
-
-static int do_dir_proc PROTO((Node * p, void *closure));
-static int do_file_proc PROTO((Node * p, void *closure));
-static void addlist PROTO((List ** listp, char *key));
-static int unroll_files_proc PROTO((Node *p, void *closure));
-static void addfile PROTO((List **listp, char *dir, char *file));
-
-
-/*
- * Local static versions eliminates the need for globals
- */
-static FILEPROC fileproc;
-static FILESDONEPROC filesdoneproc;
-static DIRENTPROC direntproc;
-static DIRLEAVEPROC dirleaveproc;
-static int which;
-static Dtype flags;
-static int aflag;
-static int readlock;
-static int dosrcs;
-static char update_dir[PATH_MAX];
-static char *repository = NULL;
-static List *entries = NULL;
-static List *srcfiles = NULL;
-
-static List *filelist = NULL; /* holds list of files on which to operate */
-static List *dirlist = NULL; /* holds list of directories on which to operate */
-
-struct recursion_frame {
- FILEPROC fileproc;
- FILESDONEPROC filesdoneproc;
- DIRENTPROC direntproc;
- DIRLEAVEPROC dirleaveproc;
- Dtype flags;
- int which;
- int aflag;
- int readlock;
- int dosrcs;
-};
-
-/*
- * Called to start a recursive command.
- *
- * Command line arguments dictate the directories and files on which
- * we operate. In the special case of no arguments, we default to
- * ".".
- *
- * The general algorithm is as follows.
- */
-int
-start_recursion (fileproc, filesdoneproc, direntproc, dirleaveproc,
- argc, argv, local, which, aflag, readlock,
- update_preload, dosrcs, wd_is_repos)
- FILEPROC fileproc;
- FILESDONEPROC filesdoneproc;
- DIRENTPROC direntproc;
- DIRLEAVEPROC dirleaveproc;
- int argc;
- char **argv;
- int local;
- int which;
- int aflag;
- int readlock;
- char *update_preload;
- int dosrcs;
- int wd_is_repos; /* Set if caller has already cd'd to the repository */
-{
- int i, err = 0;
- Dtype flags;
- List *files_by_dir = NULL;
- struct recursion_frame frame;
-
- if (update_preload == NULL)
- update_dir[0] = '\0';
- else
- (void) strcpy (update_dir, update_preload);
-
- if (local)
- flags = R_SKIP_DIRS;
- else
- flags = R_PROCESS;
-
- /* clean up from any previous calls to start_recursion */
- if (repository)
- {
- free (repository);
- repository = (char *) NULL;
- }
- if (entries)
- {
- Entries_Close (entries);
- entries = NULL;
- }
- if (srcfiles)
- dellist (&srcfiles);
- if (filelist)
- dellist (&filelist); /* FIXME-krp: no longer correct. */
-/* FIXME-krp: clean up files_by_dir */
- if (dirlist)
- dellist (&dirlist);
-
- if (argc == 0)
- {
-
- /*
- * There were no arguments, so we'll probably just recurse. The
- * exception to the rule is when we are called from a directory
- * without any CVS administration files. That has always meant to
- * process each of the sub-directories, so we pretend like we were
- * called with the list of sub-dirs of the current dir as args
- */
- if ((which & W_LOCAL) && !isdir (CVSADM))
- dirlist = Find_Dirs ((char *) NULL, W_LOCAL);
- else
- addlist (&dirlist, ".");
-
- err += do_recursion (fileproc, filesdoneproc, direntproc,
- dirleaveproc, flags, which, aflag,
- readlock, dosrcs);
- return(err);
- }
-
-
- /*
- * There were arguments, so we have to handle them by hand. To do
- * that, we set up the filelist and dirlist with the arguments and
- * call do_recursion. do_recursion recognizes the fact that the
- * lists are non-null when it starts and doesn't update them.
- *
- * explicitly named directories are stored in dirlist.
- * explicitly named files are stored in filelist.
- * other possibility is named entities whicha are not currently in
- * the working directory.
- */
-
- for (i = 0; i < argc; i++)
- {
- /* if this argument is a directory, then add it to the list of
- directories. */
-
- if (!wrap_name_has (argv[i], WRAP_TOCVS) && isdir (argv[i]))
- addlist (&dirlist, argv[i]);
- else
- {
- /* otherwise, split argument into directory and component names. */
- char *dir;
- char *comp;
- char tmp[PATH_MAX];
- char *file_to_try;
-
- dir = xstrdup (argv[i]);
- if ((comp = strrchr (dir, '/')) == NULL)
- {
- /* no dir component. What we have is an implied "./" */
- comp = dir;
- dir = xstrdup(".");
- }
- else
- {
- char *p = comp;
-
- *p++ = '\0';
- comp = xstrdup (p);
- }
-
- /* if this argument exists as a file in the current
- working directory tree, then add it to the files list. */
-
- if (wd_is_repos)
- {
- /* If doing rtag, we've done a chdir to the repository. */
- sprintf (tmp, "%s%s", argv[i], RCSEXT);
- file_to_try = tmp;
- }
- else
- file_to_try = argv[i];
-
- if(isfile(file_to_try))
- addfile (&files_by_dir, dir, comp);
- else if (isdir (dir))
- {
- if (isdir (CVSADM))
- {
- /* otherwise, look for it in the repository. */
- char *save_update_dir;
- char *repos;
-
- /* save & set (aka push) update_dir */
- save_update_dir = xstrdup (update_dir);
-
- if (*update_dir != '\0')
- (void) strcat (update_dir, "/");
-
- (void) strcat (update_dir, dir);
-
- /* look for it in the repository. */
- repos = Name_Repository (dir, update_dir);
- (void) sprintf (tmp, "%s/%s", repos, comp);
- free (repos);
-
- if (!wrap_name_has (comp, WRAP_TOCVS) && isdir(tmp))
- addlist (&dirlist, argv[i]);
- else
- addfile (&files_by_dir, dir, comp);
-
- (void) sprintf (update_dir, "%s", save_update_dir);
- free (save_update_dir);
- }
- else
- addfile (&files_by_dir, dir, comp);
- }
- else
- error (1, 0, "no such directory `%s'", dir);
-
- free (dir);
- free (comp);
- }
- }
-
- /* At this point we have looped over all named arguments and built
- a coupla lists. Now we unroll the lists, setting up and
- calling do_recursion. */
-
- frame.fileproc = fileproc;
- frame.filesdoneproc = filesdoneproc;
- frame.direntproc = direntproc;
- frame.dirleaveproc = dirleaveproc;
- frame.flags = flags;
- frame.which = which;
- frame.aflag = aflag;
- frame.readlock = readlock;
- frame.dosrcs = dosrcs;
- err += walklist (files_by_dir, unroll_files_proc, (void *) &frame);
-
- /* then do_recursion on the dirlist. */
- if (dirlist != NULL)
- err += do_recursion (frame.fileproc, frame.filesdoneproc,
- frame.direntproc, frame.dirleaveproc,
- frame.flags, frame.which, frame.aflag,
- frame.readlock, frame.dosrcs);
-
-
- return (err);
-}
-
-/*
- * Implement the recursive policies on the local directory. This may be
- * called directly, or may be called by start_recursion
- */
-int
-do_recursion (xfileproc, xfilesdoneproc, xdirentproc, xdirleaveproc,
- xflags, xwhich, xaflag, xreadlock, xdosrcs)
- FILEPROC xfileproc;
- FILESDONEPROC xfilesdoneproc;
- DIRENTPROC xdirentproc;
- DIRLEAVEPROC xdirleaveproc;
- Dtype xflags;
- int xwhich;
- int xaflag;
- int xreadlock;
- int xdosrcs;
-{
- int err = 0;
- int dodoneproc = 1;
- char *srepository;
-
- /* do nothing if told */
- if (xflags == R_SKIP_ALL)
- return (0);
-
- /* set up the static vars */
- fileproc = xfileproc;
- filesdoneproc = xfilesdoneproc;
- direntproc = xdirentproc;
- dirleaveproc = xdirleaveproc;
- flags = xflags;
- which = xwhich;
- aflag = xaflag;
- readlock = noexec ? 0 : xreadlock;
- dosrcs = xdosrcs;
-
-#if defined(SERVER_SUPPORT) && defined(SERVER_FLOWCONTROL)
- /*
- * Now would be a good time to check to see if we need to stop
- * generating data, to give the buffers a chance to drain to the
- * remote client. We should not have locks active at this point.
- */
- if (server_active
- /* If there are writelocks around, we cannot pause here. */
- && (readlock || noexec))
- server_pause_check();
-#endif
-
- /*
- * Fill in repository with the current repository
- */
- if (which & W_LOCAL)
- {
- if (isdir (CVSADM))
- repository = Name_Repository ((char *) NULL, update_dir);
- else
- repository = NULL;
- }
- else
- {
- repository = xmalloc (PATH_MAX);
- (void) getwd (repository);
- }
- srepository = repository; /* remember what to free */
-
- /*
- * The filesdoneproc needs to be called for each directory where files
- * processed, or each directory that is processed by a call where no
- * directories were passed in. In fact, the only time we don't want to
- * call back the filesdoneproc is when we are processing directories that
- * were passed in on the command line (or in the special case of `.' when
- * we were called with no args
- */
- if (dirlist != NULL && filelist == NULL)
- dodoneproc = 0;
-
- /*
- * If filelist or dirlist is already set, we don't look again. Otherwise,
- * find the files and directories
- */
- if (filelist == NULL && dirlist == NULL)
- {
- /* both lists were NULL, so start from scratch */
- if (fileproc != NULL && flags != R_SKIP_FILES)
- {
- int lwhich = which;
-
- /* be sure to look in the attic if we have sticky tags/date */
- if ((lwhich & W_ATTIC) == 0)
- if (isreadable (CVSADM_TAG))
- lwhich |= W_ATTIC;
-
- /* find the files and fill in entries if appropriate */
- filelist = Find_Names (repository, lwhich, aflag, &entries);
- }
-
- /* find sub-directories if we will recurse */
- if (flags != R_SKIP_DIRS)
- dirlist = Find_Dirs (repository, which);
- }
- else
- {
- /* something was passed on the command line */
- if (filelist != NULL && fileproc != NULL)
- {
- /* we will process files, so pre-parse entries */
- if (which & W_LOCAL)
- entries = Entries_Open (aflag);
- }
- }
-
- /* process the files (if any) */
- if (filelist != NULL)
- {
- /* read lock it if necessary */
- if (readlock && repository && Reader_Lock (repository) != 0)
- error (1, 0, "read lock failed - giving up");
-
- /* pre-parse the source files */
- if (dosrcs && repository)
- srcfiles = RCS_parsefiles (filelist, repository);
- else
- srcfiles = (List *) NULL;
-
- /* process the files */
- err += walklist (filelist, do_file_proc, NULL);
-
- /* unlock it */
- if (readlock)
- Lock_Cleanup ();
-
- /* clean up */
- dellist (&filelist);
- dellist (&srcfiles);
- Entries_Close (entries);
- entries = NULL;
- }
-
- /* call-back files done proc (if any) */
- if (dodoneproc && filesdoneproc != NULL)
- err = filesdoneproc (err, repository, update_dir[0] ? update_dir : ".");
-
- /* process the directories (if necessary) */
- if (dirlist != NULL)
- err += walklist (dirlist, do_dir_proc, NULL);
-#ifdef notdef
- else if (dirleaveproc != NULL)
- err += dirleaveproc(".", err, ".");
-#endif
- dellist (&dirlist);
-
- /* free the saved copy of the pointer if necessary */
- if (srepository)
- {
- free (srepository);
- repository = (char *) NULL;
- }
-
- return (err);
-}
-
-/*
- * Process each of the files in the list with the callback proc
- */
-static int
-do_file_proc (p, closure)
- Node *p;
- void *closure;
-{
- if (fileproc != NULL)
- return (fileproc (p->key, update_dir, repository, entries, srcfiles));
- else
- return (0);
-}
-
-/*
- * Process each of the directories in the list (recursing as we go)
- */
-static int
-do_dir_proc (p, closure)
- Node *p;
- void *closure;
-{
- char *dir = p->key;
- char newrepos[PATH_MAX];
- List *sdirlist;
- char *srepository;
- char *cp;
- Dtype dir_return = R_PROCESS;
- int stripped_dot = 0;
- int err = 0;
- struct saved_cwd cwd;
-
- /* set up update_dir - skip dots if not at start */
- if (strcmp (dir, ".") != 0)
- {
- if (update_dir[0] != '\0')
- {
- (void) strcat (update_dir, "/");
- (void) strcat (update_dir, dir);
- }
- else
- (void) strcpy (update_dir, dir);
-
- /*
- * Here we need a plausible repository name for the sub-directory. We
- * create one by concatenating the new directory name onto the
- * previous repository name. The only case where the name should be
- * used is in the case where we are creating a new sub-directory for
- * update -d and in that case the generated name will be correct.
- */
- if (repository == NULL)
- newrepos[0] = '\0';
- else
- (void) sprintf (newrepos, "%s/%s", repository, dir);
- }
- else
- {
- if (update_dir[0] == '\0')
- (void) strcpy (update_dir, dir);
-
- if (repository == NULL)
- newrepos[0] = '\0';
- else
- (void) strcpy (newrepos, repository);
- }
-
- /* call-back dir entry proc (if any) */
- if (direntproc != NULL)
- dir_return = direntproc (dir, newrepos, update_dir);
-
- /* only process the dir if the return code was 0 */
- if (dir_return != R_SKIP_ALL)
- {
- /* save our current directory and static vars */
- if (save_cwd (&cwd))
- exit (1);
- sdirlist = dirlist;
- srepository = repository;
- dirlist = NULL;
-
- /* cd to the sub-directory */
- if (chdir (dir) < 0)
- error (1, errno, "could not chdir to %s", dir);
-
- /* honor the global SKIP_DIRS (a.k.a. local) */
- if (flags == R_SKIP_DIRS)
- dir_return = R_SKIP_DIRS;
-
- /* remember if the `.' will be stripped for subsequent dirs */
- if (strcmp (update_dir, ".") == 0)
- {
- update_dir[0] = '\0';
- stripped_dot = 1;
- }
-
- /* make the recursive call */
- err += do_recursion (fileproc, filesdoneproc, direntproc, dirleaveproc,
- dir_return, which, aflag, readlock, dosrcs);
-
- /* put the `.' back if necessary */
- if (stripped_dot)
- (void) strcpy (update_dir, ".");
-
- /* call-back dir leave proc (if any) */
- if (dirleaveproc != NULL)
- err = dirleaveproc (dir, err, update_dir);
-
- /* get back to where we started and restore state vars */
- if (restore_cwd (&cwd, NULL))
- exit (1);
- free_cwd (&cwd);
- dirlist = sdirlist;
- repository = srepository;
- }
-
- /* put back update_dir */
- if ((cp = strrchr (update_dir, '/')) != NULL)
- *cp = '\0';
- else
- update_dir[0] = '\0';
-
- return (err);
-}
-
-/*
- * Add a node to a list allocating the list if necessary.
- */
-static void
-addlist (listp, key)
- List **listp;
- char *key;
-{
- Node *p;
-
- if (*listp == NULL)
- *listp = getlist ();
- p = getnode ();
- p->type = FILES;
- p->key = xstrdup (key);
- if (addnode (*listp, p) != 0)
- freenode (p);
-}
-
-static void
-addfile (listp, dir, file)
- List **listp;
- char *dir;
- char *file;
-{
- Node *n;
-
- /* add this dir. */
- addlist (listp, dir);
-
- n = findnode (*listp, dir);
- if (n == NULL)
- {
- error (1, 0, "can't find recently added dir node `%s' in start_recursion.",
- dir);
- }
-
- n->type = DIRS;
- addlist ((List **) &n->data, file);
- return;
-}
-
-static int
-unroll_files_proc (p, closure)
- Node *p;
- void *closure;
-{
- Node *n;
- struct recursion_frame *frame = (struct recursion_frame *) closure;
- int err = 0;
- List *save_dirlist;
- char *save_update_dir = NULL;
- struct saved_cwd cwd;
-
- /* if this dir was also an explicitly named argument, then skip
- it. We'll catch it later when we do dirs. */
- n = findnode (dirlist, p->key);
- if (n != NULL)
- return (0);
-
- /* otherwise, call dorecusion for this list of files. */
- filelist = (List *) p->data;
- save_dirlist = dirlist;
- dirlist = NULL;
-
- if (strcmp(p->key, ".") != 0)
- {
- if (save_cwd (&cwd))
- exit (1);
- if (chdir (p->key) < 0)
- error (1, errno, "could not chdir to %s", p->key);
-
- save_update_dir = xstrdup (update_dir);
-
- if (*update_dir != '\0')
- (void) strcat (update_dir, "/");
-
- (void) strcat (update_dir, p->key);
- }
-
- err += do_recursion (frame->fileproc, frame->filesdoneproc,
- frame->direntproc, frame->dirleaveproc,
- frame->flags, frame->which, frame->aflag,
- frame->readlock, frame->dosrcs);
-
- if (save_update_dir != NULL)
- {
- (void) strcpy (update_dir, save_update_dir);
- free (save_update_dir);
-
- if (restore_cwd (&cwd, NULL))
- exit (1);
- free_cwd (&cwd);
- }
-
- dirlist = save_dirlist;
- filelist = NULL;
- return(err);
-}
diff --git a/gnu/usr.bin/cvs/cvs/release.c b/gnu/usr.bin/cvs/cvs/release.c
deleted file mode 100644
index c768bd3d7ccb..000000000000
--- a/gnu/usr.bin/cvs/cvs/release.c
+++ /dev/null
@@ -1,259 +0,0 @@
-/*
- * Release: "cancel" a checkout in the history log.
- *
- * - Don't allow release if anything is active - Don't allow release if not
- * above or inside repository. - Don't allow release if ./CVS/Repository is
- * not the same as the directory specified in the module database.
- *
- * - Enter a line in the history log indicating the "release". - If asked to,
- * delete the local working directory.
- */
-
-#include "cvs.h"
-
-#ifndef lint
-static const char rcsid[] = "$CVSid: @(#)release.c 1.23 94/09/21 $";
-USE(rcsid);
-#endif
-
-static void release_delete PROTO((char *dir));
-
-static const char *const release_usage[] =
-{
- "Usage: %s %s [-d] modules...\n",
- "\t-d\tDelete the given directory.\n",
- NULL
-};
-
-static short delete;
-
-int
-release (argc, argv)
- int argc;
- char **argv;
-{
- FILE *fp;
- register int i, c;
- char *repository, *srepos;
- char line[PATH_MAX], update_cmd[PATH_MAX];
- char *thisarg;
- int arg_start_idx;
-
-#ifdef SERVER_SUPPORT
- if (!server_active)
- {
-#endif /* SERVER_SUPPORT */
- if (argc == -1)
- usage (release_usage);
- optind = 1;
- while ((c = getopt (argc, argv, "Qdq")) != -1)
- {
- switch (c)
- {
- case 'Q':
- case 'q':
-#ifdef SERVER_SUPPORT
- /* The CVS 1.5 client sends these options (in addition to
- Global_option requests), so we must ignore them. */
- if (!server_active)
-#endif
- error (1, 0,
- "-q or -Q must be specified before \"%s\"",
- command_name);
- break;
- case 'd':
- delete++;
- break;
- case '?':
- default:
- usage (release_usage);
- break;
- }
- }
- argc -= optind;
- argv += optind;
-#ifdef SERVER_SUPPORT
- }
-#endif /* SERVER_SUPPORT */
-
- /* We're going to run "cvs -n -q update" and check its output; if
- * the output is sufficiently unalarming, then we release with no
- * questions asked. Else we prompt, then maybe release.
- */
- /* Construct the update command. */
- sprintf (update_cmd, "%s -n -q -d %s update",
- program_path, CVSroot);
-
-#ifdef CLIENT_SUPPORT
- /* Start the server; we'll close it after looping. */
- if (client_active)
- {
- start_server ();
- ign_setup ();
- }
-#endif /* CLIENT_SUPPORT */
-
- /* If !server_active, we already skipped over argv[0] in the "argc
- -= optind;" statement above. But if server_active, we need to
- skip it now. */
-#ifdef SERVER_SUPPORT
- if (server_active)
- arg_start_idx = 1;
- else
- arg_start_idx = 0;
-#endif /* SERVER_SUPPORT */
-
- for (i = arg_start_idx; i < argc; i++)
- {
- thisarg = argv[i];
-
-#ifdef SERVER_SUPPORT
- if (server_active)
- {
- /* Just log the release -- all the interesting stuff happened
- * on the client.
- */
- history_write ('F', thisarg, "", thisarg, ""); /* F == Free */
- }
- else
- {
-#endif /* SERVER_SUPPORT */
-
- /*
- * If we are in a repository, do it. Else if we are in the parent of
- * a directory with the same name as the module, "cd" into it and
- * look for a repository there.
- */
- if (isdir (thisarg))
- {
- if (chdir (thisarg) < 0)
- {
- if (!really_quiet)
- error (0, 0, "can't chdir to: %s", thisarg);
- continue;
- }
- if (!isdir (CVSADM))
- {
- if (!really_quiet)
- error (0, 0, "no repository module: %s", thisarg);
- continue;
- }
- }
- else
- {
- if (!really_quiet)
- error (0, 0, "no such directory: %s", thisarg);
- continue;
- }
-
- repository = Name_Repository ((char *) NULL, (char *) NULL);
- srepos = Short_Repository (repository);
-
- if (!really_quiet)
- {
- /* The "release" command piggybacks on "update", which
- * does the real work of finding out if anything is not
- * up-to-date with the repository. Then "release" prompts
- * the user, telling her how many files have been
- * modified, and asking if she still wants to do the
- * release.
- */
- fp = Popen (update_cmd, "r");
- c = 0;
-
- while (fgets (line, sizeof (line), fp))
- {
- if (strchr ("MARCZ", *line))
- c++;
- (void) printf (line);
- }
-
- /* If the update exited with an error, then we just want to
- * complain and go on to the next arg. Especially, we do
- * not want to delete the local copy, since it's obviously
- * not what the user thinks it is.
- */
- if ((pclose (fp)) != 0)
- {
- error (0, 0, "unable to release `%s'", thisarg);
- continue;
- }
-
- (void) printf ("You have [%d] altered files in this repository.\n",
- c);
- (void) printf ("Are you sure you want to release %smodule `%s': ",
- delete ? "(and delete) " : "", thisarg);
- c = !yesno ();
- if (c) /* "No" */
- {
- (void) fprintf (stderr, "** `%s' aborted by user choice.\n",
- command_name);
- free (repository);
- continue;
- }
- }
-
-#ifdef CLIENT_SUPPORT
- if (client_active)
- {
- if (fprintf (to_server, "Argument %s\n", thisarg) < 0)
- error (1, errno, "writing to server");
- if (fprintf (to_server, "release\n") < 0)
- error (1, errno, "writing to server");
- }
- else
- {
-#endif /* CLIENT_SUPPORT */
- history_write ('F', thisarg, "", thisarg, ""); /* F == Free */
-#ifdef CLIENT_SUPPORT
- } /* else client not active */
-#endif /* CLIENT_SUPPORT */
-
- free (repository);
- if (delete) release_delete (thisarg);
-
-#ifdef CLIENT_SUPPORT
- if (client_active)
- return get_responses_and_close ();
- else
-#endif /* CLIENT_SUPPORT */
- return (0);
-
-#ifdef SERVER_SUPPORT
- } /* else server not active */
-#endif /* SERVER_SUPPORT */
- } /* `for' loop */
- return (0);
-}
-
-
-/* We want to "rm -r" the working directory, but let us be a little
- paranoid. */
-static void
-release_delete (dir)
- char *dir;
-{
- struct stat st;
- ino_t ino;
- int retcode = 0;
-
- (void) stat (".", &st);
- ino = st.st_ino;
- (void) chdir ("..");
- (void) stat (dir, &st);
- if (ino != st.st_ino)
- {
- error (0, 0,
- "Parent dir on a different disk, delete of %s aborted", dir);
- return;
- }
- /*
- * XXX - shouldn't this just delete the CVS-controlled files and, perhaps,
- * the files that would normally be ignored and leave everything else?
- */
- run_setup ("%s -fr", RM);
- run_arg (dir);
- if ((retcode = run_exec (RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL)) != 0)
- error (0, retcode == -1 ? errno : 0,
- "deletion of module %s failed.", dir);
-}
diff --git a/gnu/usr.bin/cvs/cvs/remove.c b/gnu/usr.bin/cvs/cvs/remove.c
deleted file mode 100644
index a33c4f9280e7..000000000000
--- a/gnu/usr.bin/cvs/cvs/remove.c
+++ /dev/null
@@ -1,213 +0,0 @@
-/*
- * Copyright (c) 1992, Brian Berliner and Jeff Polk
- * Copyright (c) 1989-1992, Brian Berliner
- *
- * You may distribute under the terms of the GNU General Public License as
- * specified in the README file that comes with the CVS 1.4 kit.
- *
- * Remove a File
- *
- * Removes entries from the present version. The entries will be removed from
- * the RCS repository upon the next "commit".
- *
- * "remove" accepts no options, only file names that are to be removed. The
- * file must not exist in the current directory for "remove" to work
- * correctly.
- */
-
-#include "cvs.h"
-
-#ifndef lint
-static const char rcsid[] = "$CVSid: @(#)remove.c 1.39 94/10/07 $";
-USE(rcsid);
-#endif
-
-static int remove_fileproc PROTO((char *file, char *update_dir,
- char *repository, List *entries,
- List *srcfiles));
-static Dtype remove_dirproc PROTO((char *dir, char *repos, char *update_dir));
-
-static int force;
-static int local;
-static int removed_files;
-static int existing_files;
-
-static const char *const remove_usage[] =
-{
- "Usage: %s %s [-flR] [files...]\n",
- "\t-f\tDelete the file before removing it.\n",
- "\t-l\tProcess this directory only (not recursive).\n",
- "\t-R\tProcess directories recursively.\n",
- NULL
-};
-
-int
-cvsremove (argc, argv)
- int argc;
- char **argv;
-{
- int c, err;
-
- if (argc == -1)
- usage (remove_usage);
-
- optind = 1;
- while ((c = getopt (argc, argv, "flR")) != -1)
- {
- switch (c)
- {
- case 'f':
- force = 1;
- break;
- case 'l':
- local = 1;
- break;
- case 'R':
- local = 0;
- break;
- case '?':
- default:
- usage (remove_usage);
- break;
- }
- }
- argc -= optind;
- argv += optind;
-
- wrap_setup ();
-
-#ifdef CLIENT_SUPPORT
- if (client_active) {
- start_server ();
- ign_setup ();
- if (local)
- send_arg("-l");
- send_files (argc, argv, local, 0);
- if (fprintf (to_server, "remove\n") < 0)
- error (1, errno, "writing to server");
- return get_responses_and_close ();
- }
-#endif
-
- /* start the recursion processor */
- err = start_recursion (remove_fileproc, (int (*) ()) NULL, remove_dirproc,
- (int (*) ()) NULL, argc, argv, local,
- W_LOCAL, 0, 1, (char *) NULL, 1, 0);
-
- if (removed_files)
- error (0, 0, "use '%s commit' to remove %s permanently", program_name,
- (removed_files == 1) ? "this file" : "these files");
-
- if (existing_files)
- error (0, 0,
- ((existing_files == 1) ?
- "%d file exists; use `%s' to remove it first" :
- "%d files exist; use `%s' to remove them first"),
- existing_files, RM);
-
- return (err);
-}
-
-/*
- * remove the file, only if it has already been physically removed
- */
-/* ARGSUSED */
-static int
-remove_fileproc (file, update_dir, repository, entries, srcfiles)
- char *file;
- char *update_dir;
- char *repository;
- List *entries;
- List *srcfiles;
-{
- char fname[PATH_MAX];
- Vers_TS *vers;
-
- if (force)
- {
- if (!noexec)
- {
- if (unlink (file) < 0 && ! existence_error (errno))
- {
- if (update_dir[0] == '\0')
- error (0, errno, "unable to remove %s", file);
- else
- error (0, errno, "unable to remove %s/%s", update_dir,
- file);
- }
- }
- /* else FIXME should probably act as if the file doesn't exist
- in doing the following checks. */
- }
-
- vers = Version_TS (repository, (char *) NULL, (char *) NULL, (char *) NULL,
- file, 0, 0, entries, srcfiles);
-
- if (vers->ts_user != NULL)
- {
- existing_files++;
- if (!quiet)
- error (0, 0, "file `%s' still in working directory", file);
- }
- else if (vers->vn_user == NULL)
- {
- if (!quiet)
- error (0, 0, "nothing known about `%s'", file);
- }
- else if (vers->vn_user[0] == '0' && vers->vn_user[1] == '\0')
- {
- /*
- * It's a file that has been added, but not commited yet. So,
- * remove the ,t file for it and scratch it from the
- * entries file. */
- Scratch_Entry (entries, file);
- (void) sprintf (fname, "%s/%s%s", CVSADM, file, CVSEXT_LOG);
- (void) unlink_file (fname);
- if (!quiet)
- error (0, 0, "removed `%s'", file);
-
-#ifdef SERVER_SUPPORT
- if (server_active)
- server_checked_in (file, update_dir, repository);
-#endif
- }
- else if (vers->vn_user[0] == '-')
- {
- if (!quiet)
- error (0, 0, "file `%s' already scheduled for removal", file);
- }
- else
- {
- /* Re-register it with a negative version number. */
- (void) strcpy (fname, "-");
- (void) strcat (fname, vers->vn_user);
- Register (entries, file, fname, vers->ts_rcs, vers->options,
- vers->tag, vers->date, vers->ts_conflict);
- if (!quiet)
- error (0, 0, "scheduling `%s' for removal", file);
- removed_files++;
-
-#ifdef SERVER_SUPPORT
- if (server_active)
- server_checked_in (file, update_dir, repository);
-#endif
- }
-
- freevers_ts (&vers);
- return (0);
-}
-
-/*
- * Print a warm fuzzy message
- */
-/* ARGSUSED */
-static Dtype
-remove_dirproc (dir, repos, update_dir)
- char *dir;
- char *repos;
- char *update_dir;
-{
- if (!quiet)
- error (0, 0, "Removing %s", update_dir);
- return (R_PROCESS);
-}
diff --git a/gnu/usr.bin/cvs/cvs/repos.c b/gnu/usr.bin/cvs/cvs/repos.c
deleted file mode 100644
index 85664334afe7..000000000000
--- a/gnu/usr.bin/cvs/cvs/repos.c
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * Copyright (c) 1992, Brian Berliner and Jeff Polk
- * Copyright (c) 1989-1992, Brian Berliner
- *
- * You may distribute under the terms of the GNU General Public License as
- * specified in the README file that comes with the CVS 1.4 kit.
- *
- * Name of Repository
- *
- * Determine the name of the RCS repository and sets "Repository" accordingly.
- */
-
-#include "cvs.h"
-
-#ifndef lint
-static const char rcsid[] = "$CVSid: @(#)repos.c 1.32 94/09/23 $";
-USE(rcsid);
-#endif
-
-char *
-Name_Repository (dir, update_dir)
- char *dir;
- char *update_dir;
-{
- FILE *fpin;
- char *ret, *xupdate_dir;
- char repos[PATH_MAX];
- char path[PATH_MAX];
- char tmp[PATH_MAX];
- char cvsadm[PATH_MAX];
- char *cp;
-
- if (update_dir && *update_dir)
- xupdate_dir = update_dir;
- else
- xupdate_dir = ".";
-
- if (dir != NULL)
- (void) sprintf (cvsadm, "%s/%s", dir, CVSADM);
- else
- (void) strcpy (cvsadm, CVSADM);
-
- /* sanity checks */
- if (!isdir (cvsadm))
- {
- error (0, 0, "in directory %s:", xupdate_dir);
- error (1, 0, "there is no version here; do '%s checkout' first",
- program_name);
- }
-
- if (dir != NULL)
- (void) sprintf (tmp, "%s/%s", dir, CVSADM_ENT);
- else
- (void) strcpy (tmp, CVSADM_ENT);
-
- if (!isreadable (tmp))
- {
- error (0, 0, "in directory %s:", xupdate_dir);
- error (1, 0, "*PANIC* administration files missing");
- }
-
- if (dir != NULL)
- (void) sprintf (tmp, "%s/%s", dir, CVSADM_REP);
- else
- (void) strcpy (tmp, CVSADM_REP);
-
- if (!isreadable (tmp))
- {
- error (0, 0, "in directory %s:", xupdate_dir);
- error (1, 0, "*PANIC* administration files missing");
- }
-
- /*
- * The assumption here is that the repository is always contained in the
- * first line of the "Repository" file.
- */
- fpin = open_file (tmp, "r");
-
- if (fgets (repos, PATH_MAX, fpin) == NULL)
- {
- error (0, 0, "in directory %s:", xupdate_dir);
- error (1, errno, "cannot read %s", CVSADM_REP);
- }
- (void) fclose (fpin);
- if ((cp = strrchr (repos, '\n')) != NULL)
- *cp = '\0'; /* strip the newline */
-
- /*
- * If this is a relative repository pathname, turn it into an absolute
- * one by tacking on the CVSROOT environment variable. If the CVSROOT
- * environment variable is not set, die now.
- */
- if (strcmp (repos, "..") == 0 || strncmp (repos, "../", 3) == 0)
- {
- error (0, 0, "in directory %s:", xupdate_dir);
- error (0, 0, "`..'-relative repositories are not supported.");
- error (1, 0, "illegal source repository");
- }
- if (! isabsolute(repos))
- {
- if (CVSroot == NULL)
- {
- error (0, 0, "in directory %s:", xupdate_dir);
- error (0, 0, "must set the CVSROOT environment variable\n");
- error (0, 0, "or specify the '-d' option to %s.", program_name);
- error (1, 0, "illegal repository setting");
- }
- (void) strcpy (path, repos);
- (void) sprintf (repos, "%s/%s", CVSroot, path);
- }
-#ifdef CLIENT_SUPPORT
- if (!client_active && !isdir (repos))
-#else
- if (!isdir (repos))
-#endif
- {
- error (0, 0, "in directory %s:", xupdate_dir);
- error (1, 0, "there is no repository %s", repos);
- }
-
- /* allocate space to return and fill it in */
- strip_path (repos);
- ret = xstrdup (repos);
- return (ret);
-}
-
-/*
- * Return a pointer to the repository name relative to CVSROOT from a
- * possibly fully qualified repository
- */
-char *
-Short_Repository (repository)
- char *repository;
-{
- if (repository == NULL)
- return (NULL);
-
- /* If repository matches CVSroot at the beginning, strip off CVSroot */
- /* And skip leading '/' in rep, in case CVSroot ended with '/'. */
- if (strncmp (CVSroot, repository, strlen (CVSroot)) == 0)
- {
- char *rep = repository + strlen (CVSroot);
- return (*rep == '/') ? rep+1 : rep;
- }
- else
- return (repository);
-}
diff --git a/gnu/usr.bin/cvs/cvs/root.c b/gnu/usr.bin/cvs/cvs/root.c
deleted file mode 100644
index e3cb979e31ff..000000000000
--- a/gnu/usr.bin/cvs/cvs/root.c
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * Copyright (c) 1992, Mark D. Baushke
- *
- * You may distribute under the terms of the GNU General Public License as
- * specified in the README file that comes with the CVS 1.4 kit.
- *
- * Name of Root
- *
- * Determine the path to the CVSROOT and set "Root" accordingly.
- * If this looks like of modified clone of Name_Repository() in
- * repos.c, it is...
- */
-
-#include "cvs.h"
-
-#ifndef lint
-static const char rcsid[] = "$CVSid: @(#)root.c,v 1.2 1994/09/15 05:32:17 zoo Exp";
-USE(rcsid);
-#endif
-
-char *
-Name_Root(dir, update_dir)
- char *dir;
- char *update_dir;
-{
- FILE *fpin;
- char *ret, *xupdate_dir;
- char root[PATH_MAX];
- char tmp[PATH_MAX];
- char cvsadm[PATH_MAX];
- char *cp;
-
- if (update_dir && *update_dir)
- xupdate_dir = update_dir;
- else
- xupdate_dir = ".";
-
- if (dir != NULL)
- {
- (void) sprintf (cvsadm, "%s/%s", dir, CVSADM);
- (void) sprintf (tmp, "%s/%s", dir, CVSADM_ROOT);
- }
- else
- {
- (void) strcpy (cvsadm, CVSADM);
- (void) strcpy (tmp, CVSADM_ROOT);
- }
-
- /*
- * Do not bother looking for a readable file if there is no cvsadm
- * directory present.
- *
- * It is possible that not all repositories will have a CVS/Root
- * file. This is ok, but the user will need to specify -d
- * /path/name or have the environment variable CVSROOT set in
- * order to continue.
- */
- if ((!isdir (cvsadm)) || (!isreadable (tmp)))
- {
- if (CVSroot == NULL)
- {
- error (0, 0, "in directory %s:", xupdate_dir);
- error (0, 0, "must set the CVSROOT environment variable");
- error (0, 0, "or specify the '-d' option to %s.", program_name);
- }
- return (NULL);
- }
-
- /*
- * The assumption here is that the CVS Root is always contained in the
- * first line of the "Root" file.
- */
- fpin = open_file (tmp, "r");
-
- if (fgets (root, PATH_MAX, fpin) == NULL)
- {
- error (0, 0, "in directory %s:", xupdate_dir);
- error (0, errno, "cannot read %s", CVSADM_ROOT);
- error (0, 0, "please correct this problem");
- return (NULL);
- }
- (void) fclose (fpin);
- if ((cp = strrchr (root, '\n')) != NULL)
- *cp = '\0'; /* strip the newline */
-
- /*
- * root now contains a candidate for CVSroot. It must be an
- * absolute pathname
- */
-
-#ifdef CLIENT_SUPPORT
- /* It must specify a server via remote CVS or be an absolute pathname. */
- if ((strchr (root, ':') == NULL)
- && ! isabsolute (root))
-#else
- if (root[0] != '/')
-#endif
- {
- error (0, 0, "in directory %s:", xupdate_dir);
- error (0, 0,
- "ignoring %s because it does not contain an absolute pathname.",
- CVSADM_ROOT);
- return (NULL);
- }
-
-#ifdef CLIENT_SUPPORT
- if ((strchr (root, ':') == NULL) && !isdir (root))
-#else
- if (!isdir (root))
-#endif
- {
- error (0, 0, "in directory %s:", xupdate_dir);
- error (0, 0,
- "ignoring %s because it specifies a non-existent repository %s",
- CVSADM_ROOT, root);
- return (NULL);
- }
-
- /* allocate space to return and fill it in */
- strip_path (root);
- ret = xstrdup (root);
- return (ret);
-}
-
-/*
- * Returns non-zero if the two directories have the same stat values
- * which indicates that they are really the same directories.
- */
-int
-same_directories (dir1, dir2)
- char *dir1;
- char *dir2;
-{
- struct stat sb1;
- struct stat sb2;
- int ret;
-
- if (stat (dir1, &sb1) < 0)
- return (0);
- if (stat (dir2, &sb2) < 0)
- return (0);
-
- ret = 0;
- if ( (memcmp( &sb1.st_dev, &sb2.st_dev, sizeof(dev_t) ) == 0) &&
- (memcmp( &sb1.st_ino, &sb2.st_ino, sizeof(ino_t) ) == 0))
- ret = 1;
-
- return (ret);
-}
-
-
-/*
- * Write the CVS/Root file so that the environment variable CVSROOT
- * and/or the -d option to cvs will be validated or not necessary for
- * future work.
- */
-void
-Create_Root (dir, rootdir)
- char *dir;
- char *rootdir;
-{
- FILE *fout;
- char tmp[PATH_MAX];
-
- if (noexec)
- return;
-
- /* record the current cvs root */
-
- if (rootdir != NULL)
- {
- if (dir != NULL)
- (void) sprintf (tmp, "%s/%s", dir, CVSADM_ROOT);
- else
- (void) strcpy (tmp, CVSADM_ROOT);
- fout = open_file (tmp, "w+");
- if (fprintf (fout, "%s\n", rootdir) < 0)
- error (1, errno, "write to %s failed", tmp);
- if (fclose (fout) == EOF)
- error (1, errno, "cannot close %s", tmp);
- }
-}
diff --git a/gnu/usr.bin/cvs/cvs/rtag.c b/gnu/usr.bin/cvs/cvs/rtag.c
deleted file mode 100644
index 76e17767a620..000000000000
--- a/gnu/usr.bin/cvs/cvs/rtag.c
+++ /dev/null
@@ -1,692 +0,0 @@
-/*
- * Copyright (c) 1992, Brian Berliner and Jeff Polk
- * Copyright (c) 1989-1992, Brian Berliner
- *
- * You may distribute under the terms of the GNU General Public License as
- * specified in the README file that comes with the CVS 1.4 kit.
- *
- * Rtag
- *
- * Add or delete a symbolic name to an RCS file, or a collection of RCS files.
- * Uses the modules database, if necessary.
- */
-
-#include "cvs.h"
-
-#ifndef lint
-static const char rcsid[] = "$CVSid: @(#)rtag.c 1.61 94/09/30 $";
-USE(rcsid);
-#endif
-
-static int check_fileproc PROTO((char *file, char *update_dir,
- char *repository, List * entries,
- List * srcfiles));
-static int check_filesdoneproc PROTO((int err, char *repos, char *update_dir));
-static int pretag_proc PROTO((char *repository, char *filter));
-static void masterlist_delproc PROTO((Node *p));
-static void tag_delproc PROTO((Node *p));
-static int pretag_list_proc PROTO((Node *p, void *closure));
-
-static Dtype rtag_dirproc PROTO((char *dir, char *repos, char *update_dir));
-static int rtag_fileproc PROTO((char *file, char *update_dir,
- char *repository, List * entries,
- List * srcfiles));
-static int rtag_proc PROTO((int *pargc, char **argv, char *xwhere,
- char *mwhere, char *mfile, int shorten,
- int local_specified, char *mname, char *msg));
-static int rtag_delete PROTO((RCSNode *rcsfile));
-
-
-struct tag_info
-{
- Ctype status;
- char *rev;
- char *tag;
- char *options;
-};
-
-struct master_lists
-{
- List *tlist;
-};
-
-static List *mtlist;
-static List *tlist;
-
-static char *symtag;
-static char *numtag;
-static int delete; /* adding a tag by default */
-static int attic_too; /* remove tag from Attic files */
-static int branch_mode; /* make an automagic "branch" tag */
-static char *date;
-static int local; /* recursive by default */
-static int force_tag_match = 1; /* force by default */
-static int force_tag_move; /* don't move existing tags by default */
-
-static const char *const rtag_usage[] =
-{
- "Usage: %s %s [-aflRnF] [-b] [-d] [-r tag|-D date] tag modules...\n",
- "\t-a\tClear tag from removed files that would not otherwise be tagged.\n",
- "\t-f\tForce a head revision match if tag/date not found.\n",
- "\t-l\tLocal directory only, not recursive\n",
- "\t-R\tProcess directories recursively.\n",
- "\t-n\tNo execution of 'tag program'\n",
- "\t-d\tDelete the given Tag.\n",
- "\t-b\tMake the tag a \"branch\" tag, allowing concurrent development.\n",
- "\t-[rD]\tExisting tag or Date.\n",
- "\t-F\tMove tag if it already exists\n",
- NULL
-};
-
-int
-rtag (argc, argv)
- int argc;
- char **argv;
-{
- register int i;
- int c;
- DBM *db;
- int run_module_prog = 1;
- int err = 0;
-
- if (argc == -1)
- usage (rtag_usage);
-
- optind = 1;
- while ((c = getopt (argc, argv, "FanfQqlRdbr:D:")) != -1)
- {
- switch (c)
- {
- case 'a':
- attic_too = 1;
- break;
- case 'n':
- run_module_prog = 0;
- break;
- case 'Q':
- case 'q':
-#ifdef SERVER_SUPPORT
- /* The CVS 1.5 client sends these options (in addition to
- Global_option requests), so we must ignore them. */
- if (!server_active)
-#endif
- error (1, 0,
- "-q or -Q must be specified before \"%s\"",
- command_name);
- break;
- case 'l':
- local = 1;
- break;
- case 'R':
- local = 0;
- break;
- case 'd':
- delete = 1;
- break;
- case 'f':
- force_tag_match = 0;
- break;
- case 'b':
- branch_mode = 1;
- break;
- case 'r':
- numtag = optarg;
- break;
- case 'D':
- if (date)
- free (date);
- date = Make_Date (optarg);
- break;
- case 'F':
- force_tag_move = 1;
- break;
- case '?':
- default:
- usage (rtag_usage);
- break;
- }
- }
- argc -= optind;
- argv += optind;
- if (argc < 2)
- usage (rtag_usage);
- symtag = argv[0];
- argc--;
- argv++;
-
- if (date && numtag)
- error (1, 0, "-r and -D options are mutually exclusive");
- if (delete && branch_mode)
- error (0, 0, "warning: -b ignored with -d options");
- RCS_check_tag (symtag);
-
-#ifdef CLIENT_SUPPORT
- if (client_active)
- {
- /* We're the client side. Fire up the remote server. */
- start_server ();
-
- ign_setup ();
-
- if (local)
- send_arg("-l");
- if (delete)
- send_arg("-d");
- if (branch_mode)
- send_arg("-b");
- if (force_tag_move)
- send_arg("-F");
- if (run_module_prog)
- send_arg("-n");
- if (attic_too)
- send_arg("-a");
-
- if (numtag)
- option_with_arg ("-r", numtag);
- if (date)
- client_senddate (date);
-
- send_arg (symtag);
-
- {
- int i;
- for (i = 0; i < argc; ++i)
- send_arg (argv[i]);
- }
-
- if (fprintf (to_server, "rtag\n") < 0)
- error (1, errno, "writing to server");
- return get_responses_and_close ();
- }
-#endif
-
- db = open_module ();
- for (i = 0; i < argc; i++)
- {
- /* XXX last arg should be repository, but doesn't make sense here */
- history_write ('T', (delete ? "D" : (numtag ? numtag :
- (date ? date : "A"))), symtag, argv[i], "");
- err += do_module (db, argv[i], TAG, delete ? "Untagging" : "Tagging",
- rtag_proc, (char *) NULL, 0, 0, run_module_prog,
- symtag);
- }
- close_module (db);
- return (err);
-}
-
-/*
- * callback proc for doing the real work of tagging
- */
-/* ARGSUSED */
-static int
-rtag_proc (pargc, argv, xwhere, mwhere, mfile, shorten, local_specified,
- mname, msg)
- int *pargc;
- char **argv;
- char *xwhere;
- char *mwhere;
- char *mfile;
- int shorten;
- int local_specified;
- char *mname;
- char *msg;
-{
- int err = 0;
- int which;
- char repository[PATH_MAX];
- char where[PATH_MAX];
-
- (void) sprintf (repository, "%s/%s", CVSroot, argv[0]);
- (void) strcpy (where, argv[0]);
-
- /* if mfile isn't null, we need to set up to do only part of the module */
- if (mfile != NULL)
- {
- char *cp;
- char path[PATH_MAX];
-
- /* if the portion of the module is a path, put the dir part on repos */
- if ((cp = strrchr (mfile, '/')) != NULL)
- {
- *cp = '\0';
- (void) strcat (repository, "/");
- (void) strcat (repository, mfile);
- (void) strcat (where, "/");
- (void) strcat (where, mfile);
- mfile = cp + 1;
- }
-
- /* take care of the rest */
- (void) sprintf (path, "%s/%s", repository, mfile);
- if (isdir (path))
- {
- /* directory means repository gets the dir tacked on */
- (void) strcpy (repository, path);
- (void) strcat (where, "/");
- (void) strcat (where, mfile);
- }
- else
- {
- int i;
-
- /* a file means muck argv */
- for (i = 1; i < *pargc; i++)
- free (argv[i]);
- argv[1] = xstrdup (mfile);
- (*pargc) = 2;
- }
- }
-
- /* chdir to the starting directory */
- if (chdir (repository) < 0)
- {
- error (0, errno, "cannot chdir to %s", repository);
- return (1);
- }
-
- if (delete || attic_too || (force_tag_match && numtag))
- which = W_REPOS | W_ATTIC;
- else
- which = W_REPOS;
-
- /* check to make sure they are authorized to tag all the
- specified files in the repository */
-
- mtlist = getlist();
- err = start_recursion (check_fileproc, check_filesdoneproc,
- (DIRENTPROC) NULL, (DIRLEAVEPROC) NULL,
- *pargc - 1, argv + 1, local, which, 0, 1,
- where, 1, 1);
-
- if (err)
- {
- error (1, 0, "correct the above errors first!");
- }
-
- /* start the recursion processor */
- err = start_recursion (rtag_fileproc, (FILESDONEPROC) NULL, rtag_dirproc,
- (DIRLEAVEPROC) NULL, *pargc - 1, argv + 1, local,
- which, 0, 1, where, 1, 1);
-
- dellist(&mtlist);
-
- return (err);
-}
-
-/* check file that is to be tagged */
-/* All we do here is add it to our list */
-
-static int
-check_fileproc(file, update_dir, repository, entries, srcfiles)
- char *file;
- char *update_dir;
- char *repository;
- List * entries;
- List * srcfiles;
-{
- char *xdir;
- Node *p;
- Vers_TS *vers;
-
- if (update_dir[0] == '\0')
- xdir = ".";
- else
- xdir = update_dir;
- if ((p = findnode (mtlist, xdir)) != NULL)
- {
- tlist = ((struct master_lists *) p->data)->tlist;
- }
- else
- {
- struct master_lists *ml;
-
- tlist = getlist ();
- p = getnode ();
- p->key = xstrdup (xdir);
- p->type = UPDATE;
- ml = (struct master_lists *)
- xmalloc (sizeof (struct master_lists));
- ml->tlist = tlist;
- p->data = (char *) ml;
- p->delproc = masterlist_delproc;
- (void) addnode (mtlist, p);
- }
- /* do tlist */
- p = getnode ();
- p->key = xstrdup (file);
- p->type = UPDATE;
- p->delproc = tag_delproc;
- vers = Version_TS (repository, (char *) NULL, (char *) NULL,
- (char *) NULL, file, 0, 0, entries, srcfiles);
- p->data = RCS_getversion(vers->srcfile, numtag, date, force_tag_match, 0);
- if (p->data != NULL)
- {
- int addit = 1;
- char *oversion;
-
- oversion = RCS_getversion (vers->srcfile, symtag, (char *) NULL, 1, 0);
- if (oversion == NULL)
- {
- if (delete)
- {
- addit = 0;
- }
- }
- else if (strcmp(oversion, p->data) == 0)
- {
- addit = 0;
- }
- else if (!force_tag_move)
- {
- addit = 0;
- }
- if (oversion != NULL)
- {
- free(oversion);
- }
- if (!addit)
- {
- free(p->data);
- p->data = NULL;
- }
- }
- freevers_ts (&vers);
- (void) addnode (tlist, p);
- return (0);
-}
-
-static int
-check_filesdoneproc(err, repos, update_dir)
- int err;
- char *repos;
- char *update_dir;
-{
- int n;
- Node *p;
-
- p = findnode(mtlist, update_dir);
- if (p != NULL)
- {
- tlist = ((struct master_lists *) p->data)->tlist;
- }
- else
- {
- tlist = (List *) NULL;
- }
- if ((tlist == NULL) || (tlist->list->next == tlist->list))
- {
- return (err);
- }
- if ((n = Parse_Info(CVSROOTADM_TAGINFO, repos, pretag_proc, 1)) > 0)
- {
- error (0, 0, "Pre-tag check failed");
- err += n;
- }
- return (err);
-}
-
-static int
-pretag_proc(repository, filter)
- char *repository;
- char *filter;
-{
- if (filter[0] == '/')
- {
- char *s, *cp;
-
- s = xstrdup(filter);
- for (cp=s; *cp; cp++)
- {
- if (isspace(*cp))
- {
- *cp = '\0';
- break;
- }
- }
- if (!isfile(s))
- {
- error (0, errno, "cannot find pre-tag filter '%s'", s);
- free(s);
- return (1);
- }
- free(s);
- }
- run_setup("%s %s %s %s",
- filter,
- symtag,
- delete ? "del" : force_tag_move ? "mov" : "add",
- repository);
- walklist(tlist, pretag_list_proc, NULL);
- return (run_exec(RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL|RUN_REALLY));
-}
-
-static void
-masterlist_delproc(p)
- Node *p;
-{
- struct master_lists *ml;
-
- ml = (struct master_lists *)p->data;
- dellist(&ml->tlist);
- free(ml);
- return;
-}
-
-static void
-tag_delproc(p)
- Node *p;
-{
- if (p->data != NULL)
- {
- free(p->data);
- p->data = NULL;
- }
- return;
-}
-
-static int
-pretag_list_proc(p, closure)
- Node *p;
- void *closure;
-{
- if (p->data != NULL)
- {
- run_arg(p->key);
- run_arg(p->data);
- }
- return (0);
-}
-
-/*
- * Called to tag a particular file, as appropriate with the options that were
- * set above.
- */
-/* ARGSUSED */
-static int
-rtag_fileproc (file, update_dir, repository, entries, srcfiles)
- char *file;
- char *update_dir;
- char *repository;
- List *entries;
- List *srcfiles;
-{
- Node *p;
- RCSNode *rcsfile;
- char *version, *rev;
- int retcode = 0;
-
- /* find the parsed RCS data */
- p = findnode (srcfiles, file);
- if (p == NULL)
- return (1);
- rcsfile = (RCSNode *) p->data;
-
- /*
- * For tagging an RCS file which is a symbolic link, you'd best be
- * running with RCS 5.6, since it knows how to handle symbolic links
- * correctly without breaking your link!
- */
-
- if (delete)
- return (rtag_delete (rcsfile));
-
- /*
- * If we get here, we are adding a tag. But, if -a was specified, we
- * need to check to see if a -r or -D option was specified. If neither
- * was specified and the file is in the Attic, remove the tag.
- */
- if (attic_too && (!numtag && !date))
- {
- if ((rcsfile->flags & VALID) && (rcsfile->flags & INATTIC))
- return (rtag_delete (rcsfile));
- }
-
- version = RCS_getversion (rcsfile, numtag, date, force_tag_match, 0);
- if (version == NULL)
- {
- /* If -a specified, clean up any old tags */
- if (attic_too)
- (void) rtag_delete (rcsfile);
-
- if (!quiet && !force_tag_match)
- {
- error (0, 0, "cannot find tag `%s' in `%s'",
- numtag ? numtag : "head", rcsfile->path);
- return (1);
- }
- return (0);
- }
- if (numtag && isdigit (*numtag) && strcmp (numtag, version) != 0)
- {
-
- /*
- * We didn't find a match for the numeric tag that was specified, but
- * that's OK. just pass the numeric tag on to rcs, to be tagged as
- * specified. Could get here if one tried to tag "1.1.1" and there
- * was a 1.1.1 branch with some head revision. In this case, we want
- * the tag to reference "1.1.1" and not the revision at the head of
- * the branch. Use a symbolic tag for that.
- */
- rev = branch_mode ? RCS_magicrev (rcsfile, version) : numtag;
- retcode = RCS_settag(rcsfile->path, symtag, numtag);
- }
- else
- {
- char *oversion;
-
- /*
- * As an enhancement for the case where a tag is being re-applied to
- * a large body of a module, make one extra call to Version_Number to
- * see if the tag is already set in the RCS file. If so, check to
- * see if it needs to be moved. If not, do nothing. This will
- * likely save a lot of time when simply moving the tag to the
- * "current" head revisions of a module -- which I have found to be a
- * typical tagging operation.
- */
- rev = branch_mode ? RCS_magicrev (rcsfile, version) : version;
- oversion = RCS_getversion (rcsfile, symtag, (char *) NULL, 1, 0);
- if (oversion != NULL)
- {
- int isbranch = RCS_isbranch (file, symtag, srcfiles);
-
- /*
- * if versions the same and neither old or new are branches don't
- * have to do anything
- */
- if (strcmp (version, oversion) == 0 && !branch_mode && !isbranch)
- {
- free (oversion);
- free (version);
- return (0);
- }
-
- if (!force_tag_move) { /* we're NOT going to move the tag */
- if (update_dir[0])
- (void) printf ("W %s/%s", update_dir, file);
- else
- (void) printf ("W %s", file);
-
- (void) printf (" : %s already exists on %s %s",
- symtag, isbranch ? "branch" : "version", oversion);
- (void) printf (" : NOT MOVING tag to %s %s\n",
- branch_mode ? "branch" : "version", rev);
- free (oversion);
- free (version);
- return (0);
- }
- free (oversion);
- }
- retcode = RCS_settag(rcsfile->path, symtag, rev);
- }
-
- if (retcode != 0)
- {
- error (1, retcode == -1 ? errno : 0,
- "failed to set tag `%s' to revision `%s' in `%s'",
- symtag, rev, rcsfile->path);
- free (version);
- return (1);
- }
- free (version);
- return (0);
-}
-
-/*
- * If -d is specified, "force_tag_match" is set, so that this call to
- * Version_Number() will return a NULL version string if the symbolic
- * tag does not exist in the RCS file.
- *
- * If the -r flag was used, numtag is set, and we only delete the
- * symtag from files that have numtag.
- *
- * This is done here because it's MUCH faster than just blindly calling
- * "rcs" to remove the tag... trust me.
- */
-static int
-rtag_delete (rcsfile)
- RCSNode *rcsfile;
-{
- char *version;
- int retcode;
-
- if (numtag)
- {
- version = RCS_getversion (rcsfile, numtag, (char *) NULL, 1, 0);
- if (version == NULL)
- return (0);
- free (version);
- }
-
- version = RCS_getversion (rcsfile, symtag, (char *) NULL, 1, 0);
- if (version == NULL)
- return (0);
- free (version);
-
- if ((retcode = RCS_deltag(rcsfile->path, symtag, 1)) != 0)
- {
- if (!quiet)
- error (0, retcode == -1 ? errno : 0,
- "failed to remove tag `%s' from `%s'", symtag,
- rcsfile->path);
- return (1);
- }
- return (0);
-}
-
-/*
- * Print a warm fuzzy message
- */
-/* ARGSUSED */
-static Dtype
-rtag_dirproc (dir, repos, update_dir)
- char *dir;
- char *repos;
- char *update_dir;
-{
- if (!quiet)
- error (0, 0, "%s %s", delete ? "Untagging" : "Tagging", update_dir);
- return (R_PROCESS);
-}
-
-
-
diff --git a/gnu/usr.bin/cvs/cvs/sanity.el b/gnu/usr.bin/cvs/cvs/sanity.el
deleted file mode 100644
index a1470570a011..000000000000
--- a/gnu/usr.bin/cvs/cvs/sanity.el
+++ /dev/null
@@ -1,18 +0,0 @@
-;;;; -*- lisp-interaction -*-
-;;;; Time-stamp: <29 Nov 93 14:25:28, by rich@sendai.cygnus.com>
-
-(defun reset-fail-counter (arg)
- (interactive "p")
- (setq fail-counter arg)
- (message (concat "fail-counter = " (int-to-string arg))))
-
-
-(defun inc-next-fail-counter nil
- (interactive)
- (search-forward "failed test ")
- (kill-word 1)
- (insert-string fail-counter)
- (setq fail-counter (+ 1 fail-counter)))
-
-(global-set-key [f15] 'reset-fail-counter)
-(global-set-key [f16] 'inc-next-fail-counter)
diff --git a/gnu/usr.bin/cvs/cvs/sanity.sh b/gnu/usr.bin/cvs/cvs/sanity.sh
deleted file mode 100644
index 21aa454d2d4b..000000000000
--- a/gnu/usr.bin/cvs/cvs/sanity.sh
+++ /dev/null
@@ -1,1674 +0,0 @@
-#! /bin/sh
-:
-# sanity.sh -- a growing sanity test for cvs.
-#
-#ident "$CVSid$"
-#
-# Copyright (C) 1992, 1993 Cygnus Support
-#
-# Original Author: K. Richard Pixley
-
-# usage: sanity.sh [-r] @var{cvs-to-test} @var{tests-to-run}
-# -r means to test remote instead of local cvs.
-# @var{tests-to-run} are the names of the tests to run; if omitted run all
-# tests.
-
-# See TODO list at end of file.
-
-# required to make this script work properly.
-unset CVSREAD
-
-TESTDIR=/tmp/cvs-sanity
-
-# "debugger"
-#set -x
-
-echo 'This test should produce no other output than this line, and a final "OK".'
-
-if test x"$1" = x"-r"; then
- shift
- remote=yes
-else
- remote=no
-fi
-
-# Use full path for CVS executable, so that CVS_SERVER gets set properly
-# for remote.
-case $1 in
-/*)
- testcvs=$1
- ;;
-*)
- testcvs=`pwd`/$1
- ;;
-esac
-
-shift
-
-# Use full path for mkmodules, so that the right one will be invoked
-#
-testmkmodules=`pwd`/mkmodules
-
-# FIXME: try things (what things? checkins?) without -m.
-#
-# Some of these tests are written to expect -Q. But testing with
-# -Q is kind of bogus, it is not the way users actually use CVS (usually).
-# So new tests probably should invoke ${testcvs} directly, rather than ${CVS}.
-# and then they've obviously got to do something with the output....
-#
-CVS="${testcvs} -Q -f"
-
-LOGFILE=`pwd`/check.log
-
-# Save the previous log in case the person running the tests decides
-# they want to look at it. The extension ".plog" is chosen for consistency
-# with dejagnu.
-if test -f check.log; then
- mv check.log check.plog
-fi
-
-# clean any old remnants
-rm -rf ${TESTDIR}
-mkdir ${TESTDIR}
-cd ${TESTDIR}
-
-# Remaining arguments are the names of tests to run.
-#
-# FIXME: not all combinations are possible; basic3 depends on files set up
-# by previous tests, for example. This should be changed.
-# The goal is that tests can be run in manageably-sized chunks, so
-# that one can quickly get a result from a cvs or testsuite change,
-# and to facilitate understanding the tests.
-
-if test x"$*" = x; then
- tests="basic0 basic1 basic2 basic3 rtags death import new conflicts modules mflag errmsg1"
-else
- tests="$*"
-fi
-
-# this should die
-if ${CVS} -d `pwd`/cvsroot co cvs-sanity 2>> ${LOGFILE} ; then
- echo "FAIL: test 1" | tee -a ${LOGFILE}
- exit 1
-else
- echo "PASS: test 1" >>${LOGFILE}
-fi
-
-# this should still die
-mkdir cvsroot
-if ${CVS} -d `pwd`/cvsroot co cvs-sanity 2>> ${LOGFILE} ; then
- echo "FAIL: test 2" | tee -a ${LOGFILE}
- exit 1
-else
- echo "PASS: test 2" >>${LOGFILE}
-fi
-
-# this should still die
-mkdir cvsroot/CVSROOT
-if ${CVS} -d `pwd`/cvsroot co cvs-sanity 2>> ${LOGFILE} ; then
- echo "FAIL: test 3" | tee -a ${LOGFILE}
- exit 1
-else
- echo "PASS: test 3" >>${LOGFILE}
-fi
-
-# This one should work, although it should spit a warning.
-mkdir tmp ; cd tmp
-${CVS} -d `pwd`/../cvsroot co CVSROOT 2>> ${LOGFILE}
-cd .. ; rm -rf tmp
-
-# set up a minimal modules file...
-echo "CVSROOT -i ${testmkmodules} CVSROOT" > cvsroot/CVSROOT/modules
-
-# This one should succeed. No warnings.
-mkdir tmp ; cd tmp
-if ${CVS} -d `pwd`/../cvsroot co CVSROOT ; then
- echo "PASS: test 4" >>${LOGFILE}
-else
- echo "FAIL: test 4" | tee -a ${LOGFILE}
- exit 1
-fi
-
-if echo "yes" | ${CVS} -d `pwd`/../cvsroot release -d CVSROOT ; then
- echo "PASS: test 4.5" >>${LOGFILE}
-else
- echo "FAIL: test 4.5" | tee -a ${LOGFILE}
- exit 1
-fi
-# this had better be empty
-cd ..; rmdir tmp
-if [ -d tmp ] ; then
- echo "FAIL: test 4.75" | tee -a ${LOGFILE}
- exit 1
-fi
-
-# a simple function to compare directory contents
-#
-# BTW, I don't care any more -- if you don't have a /bin/sh that handles
-# shell functions, well get one.
-#
-# Returns: ISDIFF := true|false
-#
-directory_cmp ()
-{
- OLDPWD=`pwd`
- DIR_1=$1
- DIR_2=$2
- ISDIFF=false
-
- cd $DIR_1
- find . -print | fgrep -v /CVS | sort > /tmp/dc$$d1
-
- # go back where we were to avoid symlink hell...
- cd $OLDPWD
- cd $DIR_2
- find . -print | fgrep -v /CVS | sort > /tmp/dc$$d2
-
- if diff /tmp/dc$$d1 /tmp/dc$$d2 >/dev/null 2>&1
- then
- :
- else
- ISDIFF=true
- return
- fi
- cd $OLDPWD
- while read a
- do
- if [ -f $DIR_1/"$a" ] ; then
- cmp -s $DIR_1/"$a" $DIR_2/"$a"
- if [ $? -ne 0 ] ; then
- ISDIFF=true
- fi
- fi
- done < /tmp/dc$$d1
-### FIXME:
-### rm -f /tmp/dc$$*
-}
-
-# so much for the setup. Let's try something harder.
-
-# Try setting CVSROOT so we don't have to worry about it anymore. (now that
-# we've tested -d cvsroot.)
-CVSROOT_DIRNAME=${TESTDIR}/cvsroot
-CVSROOT=${CVSROOT_DIRNAME} ; export CVSROOT
-if test "x$remote" = xyes; then
- CVSROOT=`hostname`:${CVSROOT_DIRNAME} ; export CVSROOT
- # Use rsh so we can test it without having to muck with inetd or anything
- # like that. Also needed to get CVS_SERVER to work.
- CVS_CLIENT_PORT=-1; export CVS_CLIENT_PORT
- CVS_SERVER=${testcvs}; export CVS_SERVER
-fi
-
-mkdir tmp ; cd tmp
-if ${CVS} co CVSROOT ; then
- if [ -r CVSROOT/CVS/Entries ] ; then
- echo "PASS: test 5" >>${LOGFILE}
- else
- echo "FAIL: test 5" | tee -a ${LOGFILE}
- exit 1
- fi
-else
- echo "FAIL: test 5" | tee -a ${LOGFILE}; exit 1
-fi
-
-if echo "yes" | ${CVS} release -d CVSROOT ; then
- echo "PASS: test 5.5" >>${LOGFILE}
-else
- echo "FAIL: test 5.5" | tee -a ${LOGFILE}
- exit 1
-fi
-# this had better etmpy now...
-cd ..; rmdir tmp
-if [ -d tmp ] ; then
- echo "FAIL: test 5.75" | tee -a ${LOGFILE}
- exit 1
-fi
-
-# start keeping history
-touch ${CVSROOT_DIRNAME}/CVSROOT/history
-
-### The big loop
-for what in $tests; do
- case $what in
- basic0) # Now, let's build something.
-# mkdir first-dir
- # this doesn't yet work, though I think maybe it should. xoxorich.
-# if ${CVS} add first-dir ; then
-# true
-# else
-# echo cvs does not yet add top level directories cleanly.
- mkdir ${CVSROOT_DIRNAME}/first-dir
-# fi
-# rm -rf first-dir
-
- # check out an empty directory
- if ${CVS} co first-dir ; then
- if [ -r first-dir/CVS/Entries ] ; then
- echo "PASS: test 6" >>${LOGFILE}
- else
- echo "FAIL: test 6" | tee -a ${LOGFILE}; exit 1
- fi
- else
- echo "FAIL: test 6" | tee -a ${LOGFILE}; exit 1
- fi
-
- # update the empty directory
- if ${CVS} update first-dir ; then
- echo "PASS: test 7" >>${LOGFILE}
- else
- echo "FAIL: test 7" | tee -a ${LOGFILE}; exit 1
- fi
-
- # diff -u the empty directory
- if ${CVS} diff -u first-dir ; then
- echo "PASS: test 8" >>${LOGFILE}
- else
- echo "FAIL: test 8" | tee -a ${LOGFILE}; exit 1
- fi
-
- # diff -c the empty directory
- if ${CVS} diff -c first-dir ; then
- echo "PASS: test 9" >>${LOGFILE}
- else
- echo "FAIL: test 9" | tee -a ${LOGFILE}; exit 1
- fi
-
- # log the empty directory
- if ${CVS} log first-dir ; then
- echo "PASS: test 10" >>${LOGFILE}
- else
- echo "FAIL: test 10" | tee -a ${LOGFILE}; exit 1
- fi
-
- # status the empty directory
- if ${CVS} status first-dir ; then
- echo "PASS: test 11" >>${LOGFILE}
- else
- echo "FAIL: test 11" | tee -a ${LOGFILE}; exit 1
- fi
-
- # tag the empty directory
- if ${CVS} tag first first-dir ; then
- echo "PASS: test 12" >>${LOGFILE}
- else
- echo "FAIL: test 12" | tee -a ${LOGFILE}; exit 1
- fi
-
- # rtag the empty directory
- if ${CVS} rtag empty first-dir ; then
- echo "PASS: test 13" >>${LOGFILE}
- else
- echo "FAIL: test 13" | tee -a ${LOGFILE}; exit 1
- fi
- ;;
-
- basic1) # first dive - add a files, first singly, then in a group.
- rm -rf ${CVSROOT_DIRNAME}/first-dir
- rm -rf first-dir
- mkdir ${CVSROOT_DIRNAME}/first-dir
- # check out an empty directory
- if ${CVS} co first-dir ; then
- echo "PASS: test 13a" >>${LOGFILE}
- else
- echo "FAIL: test 13a" | tee -a ${LOGFILE}; exit 1
- fi
-
- cd first-dir
- files=first-file
- for i in a b ; do
- for j in ${files} ; do
- echo $j > $j
- done
-
- for do in add rm ; do
- for j in ${do} "commit -m test" ; do
- # ${do}
- if ${CVS} $j ${files} >> ${LOGFILE} 2>&1; then
- echo "PASS: test 14-${do}-$j" >>${LOGFILE}
- else
- echo "FAIL: test 14-${do}-$j" | tee -a ${LOGFILE}; exit 1
- fi
-
- # update it.
- if [ "${do}" = "rm" -a "$j" != "commit -m test" ] || ${CVS} update ${files} ; then
- echo "PASS: test 15-${do}-$j" >>${LOGFILE}
- else
- echo "FAIL: test 15-${do}-$j" | tee -a ${LOGFILE}; exit 1
- fi
-
- # update all.
- if ${CVS} update ; then
- echo "PASS: test 16-${do}-$j" >>${LOGFILE}
- else
- echo "FAIL: test 16-${do}-$j" | tee -a ${LOGFILE}; exit 1
- fi
-
- # status all.
- if ${CVS} status >> ${LOGFILE}; then
- echo "PASS: test 17-${do}-$j" >>${LOGFILE}
- else
- echo "FAIL: test 17-${do}-$j" | tee -a ${LOGFILE}; exit 1
- fi
-
- # FIXME: this one doesn't work yet for added files.
- # log all.
- if ${CVS} log >> ${LOGFILE}; then
- echo "PASS: test 18-${do}-$j" >>${LOGFILE}
- else
- echo "FAIL: test 18-${do}-$j" | tee -a ${LOGFILE}
- fi
-
- if test "x${do}-$j" = "xadd-add" || test "x${do}-$j" = "xrm-rm" ; then
- true
- else
- # diff -c all
- if ${CVS} diff -c >> ${LOGFILE} || [ $? = 1 ] ; then
- echo "PASS: test 19-${do}-$j" >>${LOGFILE}
- else
- echo "FAIL: test 19-${do}-$j" | tee -a ${LOGFILE}
- fi
-
- # diff -u all
- if ${CVS} diff -u >> ${LOGFILE} || [ $? = 1 ] ; then
- echo "PASS: test 20-${do}-$j" >>${LOGFILE}
- else
- echo "FAIL: test 20-${do}-$j" | tee -a ${LOGFILE}
- fi
- fi
-
- cd ..
- # update all.
- if ${CVS} update ; then
- echo "PASS: test 21-${do}-$j" >>${LOGFILE}
- else
- echo "FAIL: test 21-${do}-$j" | tee -a ${LOGFILE}; exit 1
- fi
-
- # log all.
- # FIXME: doesn't work right for added files.
- if ${CVS} log first-dir >> ${LOGFILE}; then
- echo "PASS: test 22-${do}-$j" >>${LOGFILE}
- else
- echo "FAIL: test 22-${do}-$j" | tee -a ${LOGFILE}
- fi
-
- # status all.
- if ${CVS} status first-dir >> ${LOGFILE}; then
- echo "PASS: test 23-${do}-$j" >>${LOGFILE}
- else
- echo "FAIL: test 23-${do}-$j" | tee -a ${LOGFILE}; exit 1
- fi
-
- # update all.
- if ${CVS} update first-dir ; then
- echo "PASS: test 24-${do}-$j" >>${LOGFILE}
- else
- echo "FAIL: test 24-${do}-$j" | tee -a ${LOGFILE} ; exit 1
- fi
-
- if test "x${do}-$j" = "xadd-add" || test "x${do}-$j" = "xrm-rm" ; then
- echo "PASS: test 25-${do}-$j" >>${LOGFILE}
- else
- # diff all
- if ${CVS} diff -u >> ${LOGFILE} || [ $? = 1 ] ; then
- echo "PASS: test 25-${do}-$j" >>${LOGFILE}
- else
- echo "FAIL: test 25-${do}-$j" | tee -a ${LOGFILE}
- # FIXME; exit 1
- fi
-
- # diff all
- if ${CVS} diff -u first-dir >> ${LOGFILE} || [ $? = 1 ] ; then
- echo "PASS: test 26-${do}-$j" >>${LOGFILE}
- else
- echo "FAIL: test 26-${do}-$j" | tee -a ${LOGFILE}
- # FIXME; exit 1
- fi
- fi
-
- # update all.
- if ${CVS} co first-dir ; then
- echo "PASS: test 27-${do}-$j" >>${LOGFILE}
- else
- echo "FAIL: test 27-${do}-$j" | tee -a ${LOGFILE} ; exit 1
- fi
-
- cd first-dir
- done # j
- rm -f ${files}
- done # do
-
- files="file2 file3 file4 file5"
- done
- if ${CVS} tag first-dive ; then
- echo "PASS: test 28" >>${LOGFILE}
- else
- echo "FAIL: test 28" | tee -a ${LOGFILE} ; exit 1
- fi
- cd ..
- ;;
-
- basic2) # second dive - add bunch o' files in bunch o' added directories
- for i in first-dir dir1 dir2 dir3 dir4 ; do
- if [ ! -d $i ] ; then
- mkdir $i
- if ${CVS} add $i >> ${LOGFILE}; then
- echo "PASS: test 29-$i" >>${LOGFILE}
- else
- echo "FAIL: test 29-$i" | tee -a ${LOGFILE} ; exit 1
- fi
- fi
-
- cd $i
-
- for j in file6 file7 file8 file9 file10 file11 file12 file13; do
- echo $j > $j
- done
-
- if ${CVS} add file6 file7 file8 file9 file10 file11 file12 file13 2>> ${LOGFILE}; then
- echo "PASS: test 30-$i-$j" >>${LOGFILE}
- else
- echo "FAIL: test 30-$i-$j" | tee -a ${LOGFILE} ; exit 1
- fi
- done
- cd ../../../../..
- if ${CVS} update first-dir ; then
- echo "PASS: test 31" >>${LOGFILE}
- else
- echo "FAIL: test 31" | tee -a ${LOGFILE} ; exit 1
- fi
-
- # fixme: doesn't work right for added files.
- if ${CVS} log first-dir >> ${LOGFILE}; then
- echo "PASS: test 32" >>${LOGFILE}
- else
- echo "FAIL: test 32" | tee -a ${LOGFILE} # ; exit 1
- fi
-
- if ${CVS} status first-dir >> ${LOGFILE}; then
- echo "PASS: test 33" >>${LOGFILE}
- else
- echo "FAIL: test 33" | tee -a ${LOGFILE} ; exit 1
- fi
-
-# if ${CVS} diff -u first-dir >> ${LOGFILE} || [ $? = 1 ] ; then
-# echo "PASS: test 34" >>${LOGFILE}
-# else
-# echo "FAIL: test 34" | tee -a ${LOGFILE} # ; exit 1
-# fi
-
- if ${CVS} ci -m "second dive" first-dir >> ${LOGFILE} 2>&1; then
- echo "PASS: test 35" >>${LOGFILE}
- else
- echo "FAIL: test 35" | tee -a ${LOGFILE} ; exit 1
- fi
-
- if ${CVS} tag second-dive first-dir ; then
- echo "PASS: test 36" >>${LOGFILE}
- else
- echo "FAIL: test 36" | tee -a ${LOGFILE} ; exit 1
- fi
- ;;
-
- basic3) # third dive - in bunch o' directories, add bunch o' files, delete some, change some.
- for i in first-dir dir1 dir2 dir3 dir4 ; do
- cd $i
-
- # modify some files
- for j in file6 file8 file10 file12 ; do
- echo $j >> $j
- done
-
- # delete some files
- rm file7 file9 file11 file13
-
- if ${CVS} rm file7 file9 file11 file13 2>> ${LOGFILE}; then
- echo "PASS: test 37-$i" >>${LOGFILE}
- else
- echo "FAIL: test 37-$i" | tee -a ${LOGFILE} ; exit 1
- fi
-
- # and add some new ones
- for j in file14 file15 file16 file17 ; do
- echo $j > $j
- done
-
- if ${CVS} add file14 file15 file16 file17 2>> ${LOGFILE}; then
- echo "PASS: test 38-$i" >>${LOGFILE}
- else
- echo "FAIL: test 38-$i" | tee -a ${LOGFILE} ; exit 1
- fi
- done
- cd ../../../../..
- if ${CVS} update first-dir ; then
- echo "PASS: test 39" >>${LOGFILE}
- else
- echo "FAIL: test 39" | tee -a ${LOGFILE} ; exit 1
- fi
-
- # fixme: doesn't work right for added files
- if ${CVS} log first-dir >> ${LOGFILE}; then
- echo "PASS: test 40" >>${LOGFILE}
- else
- echo "FAIL: test 40" | tee -a ${LOGFILE} # ; exit 1
- fi
-
- if ${CVS} status first-dir >> ${LOGFILE}; then
- echo "PASS: test 41" >>${LOGFILE}
- else
- echo "FAIL: test 41" | tee -a ${LOGFILE} ; exit 1
- fi
-
-# if ${CVS} diff -u first-dir >> ${LOGFILE} || [ $? = 1 ] ; then
-# echo "PASS: test 42" >>${LOGFILE}
-# else
-# echo "FAIL: test 42" | tee -a ${LOGFILE} # ; exit 1
-# fi
-
- if ${CVS} ci -m "third dive" first-dir >>${LOGFILE} 2>&1; then
- echo "PASS: test 43" >>${LOGFILE}
- else
- echo "FAIL: test 43" | tee -a ${LOGFILE} ; exit 1
- fi
-
- if ${CVS} tag third-dive first-dir ; then
- echo "PASS: test 44" >>${LOGFILE}
- else
- echo "FAIL: test 44" | tee -a ${LOGFILE} ; exit 1
- fi
-
- if echo "yes" | ${CVS} release -d first-dir ; then
- echo "PASS: test 45" >>${LOGFILE}
- else
- echo "FAIL: test 45" | tee -a ${LOGFILE} ; exit 1
- fi
-
- # end of third dive
- if [ -d test-dir ] ; then
- echo "FAIL: test 45.5" | tee -a ${LOGFILE} ; exit 1
- else
- echo "PASS: test 45.5" >>${LOGFILE}
- fi
-
- ;;
-
- rtags) # now try some rtags
- # rtag HEADS
- if ${CVS} rtag rtagged-by-head first-dir ; then
- echo "PASS: test 46" >>${LOGFILE}
- else
- echo "FAIL: test 46" | tee -a ${LOGFILE} ; exit 1
- fi
-
- # tag by tag
- if ${CVS} rtag -r rtagged-by-head rtagged-by-tag first-dir ; then
- echo "PASS: test 47" >>${LOGFILE}
- else
- echo "FAIL: test 47" | tee -a ${LOGFILE} ; exit 1
- fi
-
- # tag by revision
- if ${CVS} rtag -r1.1 rtagged-by-revision first-dir ; then
- echo "PASS: test 48" >>${LOGFILE}
- else
- echo "FAIL: test 48" | tee -a ${LOGFILE} ; exit 1
- fi
-
- # rdiff by revision
- if ${CVS} rdiff -r1.1 -rrtagged-by-head first-dir >> ${LOGFILE} || [ $? = 1 ] ; then
- echo "PASS: test 49" >>${LOGFILE}
- else
- echo "FAIL: test 49" | tee -a ${LOGFILE} ; exit 1
- fi
-
- # now export by rtagged-by-head and rtagged-by-tag and compare.
- rm -rf first-dir
- if ${CVS} export -r rtagged-by-head first-dir ; then
- echo "PASS: test 50" >>${LOGFILE}
- else
- echo "FAIL: test 50" | tee -a ${LOGFILE} ; exit 1
- fi
-
- mv first-dir 1dir
- if ${CVS} export -r rtagged-by-tag first-dir ; then
- echo "PASS: test 51" >>${LOGFILE}
- else
- echo "FAIL: test 51" | tee -a ${LOGFILE} ; exit 1
- fi
-
- directory_cmp 1dir first-dir
-
- if $ISDIFF ; then
- echo "FAIL: test 52" | tee -a ${LOGFILE} ; exit 1
- else
- echo "PASS: test 52" >>${LOGFILE}
- fi
- rm -rf 1dir first-dir
-
- # checkout by revision vs export by rtagged-by-revision and compare.
- if ${CVS} export -rrtagged-by-revision -d export-dir first-dir ; then
- echo "PASS: test 53" >>${LOGFILE}
- else
- echo "FAIL: test 53" | tee -a ${LOGFILE} ; exit 1
- fi
-
- if ${CVS} co -r1.1 first-dir ; then
- echo "PASS: test 54" >>${LOGFILE}
- else
- echo "FAIL: test 54" | tee -a ${LOGFILE} ; exit 1
- fi
-
- # directory copies are done in an oblique way in order to avoid a bug in sun's tmp filesystem.
- mkdir first-dir.cpy ; (cd first-dir ; tar cf - * | (cd ../first-dir.cpy ; tar xf -))
-
- directory_cmp first-dir export-dir
-
- if $ISDIFF ; then
- echo "FAIL: test 55" | tee -a ${LOGFILE} ; exit 1
- else
- echo "PASS: test 55" >>${LOGFILE}
- fi
-
- # interrupt, while we've got a clean 1.1 here, let's import it into another tree.
- cd export-dir
- if ${CVS} import -m "first-import" second-dir first-immigration immigration1 immigration1_0 ; then
- echo "PASS: test 56" >>${LOGFILE}
- else
- echo "FAIL: test 56" | tee -a ${LOGFILE} ; exit 1
- fi
- cd ..
-
- if ${CVS} export -r HEAD second-dir ; then
- echo "PASS: test 57" >>${LOGFILE}
- else
- echo "FAIL: test 57" | tee -a ${LOGFILE} ; exit 1
- fi
-
- directory_cmp first-dir second-dir
-
- if $ISDIFF ; then
- echo "FAIL: test 58" | tee -a ${LOGFILE} ; exit 1
- else
- echo "PASS: test 58" >>${LOGFILE}
- fi
-
- rm -rf export-dir first-dir
- mkdir first-dir
- (cd first-dir.cpy ; tar cf - * | (cd ../first-dir ; tar xf -))
-
- # update the top, cancelling sticky tags, retag, update other copy, compare.
- cd first-dir
- if ${CVS} update -A -l *file* 2>> ${LOGFILE}; then
- echo "PASS: test 59" >>${LOGFILE}
- else
- echo "FAIL: test 59" | tee -a ${LOGFILE} ; exit 1
- fi
-
- # If we don't delete the tag first, cvs won't retag it.
- # This would appear to be a feature.
- if ${CVS} tag -l -d rtagged-by-revision ; then
- echo "PASS: test 60a" >>${LOGFILE}
- else
- echo "FAIL: test 60a" | tee -a ${LOGFILE} ; exit 1
- fi
- if ${CVS} tag -l rtagged-by-revision ; then
- echo "PASS: test 60b" >>${LOGFILE}
- else
- echo "FAIL: test 60b" | tee -a ${LOGFILE} ; exit 1
- fi
-
- cd ..
- mv first-dir 1dir
- mv first-dir.cpy first-dir
- cd first-dir
-
- if ${CVS} diff -u >> ${LOGFILE} || [ $? = 1 ] ; then
- echo "PASS: test 61" >>${LOGFILE}
- else
- echo "FAIL: test 61" | tee -a ${LOGFILE} ; exit 1
- fi
-
- if ${CVS} update ; then
- echo "PASS: test 62" >>${LOGFILE}
- else
- echo "FAIL: test 62" | tee -a ${LOGFILE} ; exit 1
- fi
-
- cd ..
-
- #### FIXME: is this expected to work??? Need to investigate
- #### and fix or remove the test.
-# directory_cmp 1dir first-dir
-#
-# if $ISDIFF ; then
-# echo "FAIL: test 63" | tee -a ${LOGFILE} # ; exit 1
-# else
-# echo "PASS: test 63" >>${LOGFILE}
-# fi
- rm -rf 1dir first-dir
-
- if ${CVS} his -e -a >> ${LOGFILE}; then
- echo "PASS: test 64" >>${LOGFILE}
- else
- echo "FAIL: test 64" | tee -a ${LOGFILE} ; exit 1
- fi
- ;;
-
- death) # next dive. test death support.
- rm -rf ${CVSROOT_DIRNAME}/first-dir
- mkdir ${CVSROOT_DIRNAME}/first-dir
- if ${CVS} co first-dir ; then
- echo "PASS: test 65" >>${LOGFILE}
- else
- echo "FAIL: test 65" | tee -a ${LOGFILE} ; exit 1
- fi
-
- cd first-dir
-
- # add a file.
- touch file1
- if ${CVS} add file1 2>> ${LOGFILE}; then
- echo "PASS: test 66" >>${LOGFILE}
- else
- echo "FAIL: test 66" | tee -a ${LOGFILE} ; exit 1
- fi
-
- # commit
- if ${CVS} ci -m test >> ${LOGFILE} 2>&1; then
- echo "PASS: test 67" >>${LOGFILE}
- else
- echo "FAIL: test 67" | tee -a ${LOGFILE} ; exit 1
- fi
-
- # remove
- rm file1
- if ${CVS} rm file1 2>> ${LOGFILE}; then
- echo "PASS: test 68" >>${LOGFILE}
- else
- echo "FAIL: test 68" | tee -a ${LOGFILE} ; exit 1
- fi
-
- # commit
- if ${CVS} ci -m test >>${LOGFILE} ; then
- echo "PASS: test 69" >>${LOGFILE}
- else
- echo "FAIL: test 69" | tee -a ${LOGFILE} ; exit 1
- fi
-
- # add again and create second file
- touch file1 file2
- if ${CVS} add file1 file2 2>> ${LOGFILE}; then
- echo "PASS: test 70" >>${LOGFILE}
- else
- echo "FAIL: test 70" | tee -a ${LOGFILE} ; exit 1
- fi
-
- # commit
- if ${CVS} ci -m test >> ${LOGFILE} 2>&1; then
- echo "PASS: test 71" >>${LOGFILE}
- else
- echo "FAIL: test 71" | tee -a ${LOGFILE} ; exit 1
- fi
-
- # log
- if ${CVS} log file1 >> ${LOGFILE}; then
- echo "PASS: test 72" >>${LOGFILE}
- else
- echo "FAIL: test 72" | tee -a ${LOGFILE} ; exit 1
- fi
-
-
- # branch1
- if ${CVS} tag -b branch1 ; then
- echo "PASS: test 73" >>${LOGFILE}
- else
- echo "FAIL: test 73" | tee -a ${LOGFILE} ; exit 1
- fi
-
- # and move to the branch.
- if ${CVS} update -r branch1 ; then
- echo "PASS: test 74" >>${LOGFILE}
- else
- echo "FAIL: test 74" | tee -a ${LOGFILE} ; exit 1
- fi
-
- # add a file in the branch
- echo line1 from branch1 >> file3
- if ${CVS} add file3 2>> ${LOGFILE}; then
- echo "PASS: test 75" >>${LOGFILE}
- else
- echo "FAIL: test 75" | tee -a ${LOGFILE} ; exit 1
- fi
-
- # commit
- if ${CVS} ci -m test >> ${LOGFILE} 2>&1; then
- echo "PASS: test 76" >>${LOGFILE}
- else
- echo "FAIL: test 76" | tee -a ${LOGFILE} ; exit 1
- fi
-
- # remove
- rm file3
- if ${CVS} rm file3 2>> ${LOGFILE}; then
- echo "PASS: test 77" >>${LOGFILE}
- else
- echo "FAIL: test 77" | tee -a ${LOGFILE} ; exit 1
- fi
-
- # commit
- if ${CVS} ci -m test >>${LOGFILE} ; then
- echo "PASS: test 78" >>${LOGFILE}
- else
- echo "FAIL: test 78" | tee -a ${LOGFILE} ; exit 1
- fi
-
- # add again
- echo line1 from branch1 >> file3
- if ${CVS} add file3 2>> ${LOGFILE}; then
- echo "PASS: test 79" >>${LOGFILE}
- else
- echo "FAIL: test 79" | tee -a ${LOGFILE} ; exit 1
- fi
-
- # commit
- if ${CVS} ci -m test >> ${LOGFILE} 2>&1; then
- echo "PASS: test 80" >>${LOGFILE}
- else
- echo "FAIL: test 80" | tee -a ${LOGFILE} ; exit 1
- fi
-
- # change the first file
- echo line2 from branch1 >> file1
-
- # commit
- if ${CVS} ci -m test >> ${LOGFILE} 2>&1; then
- echo "PASS: test 81" >>${LOGFILE}
- else
- echo "FAIL: test 81" | tee -a ${LOGFILE} ; exit 1
- fi
-
- # remove the second
- rm file2
- if ${CVS} rm file2 2>> ${LOGFILE}; then
- echo "PASS: test 82" >>${LOGFILE}
- else
- echo "FAIL: test 82" | tee -a ${LOGFILE} ; exit 1
- fi
-
- # commit
- if ${CVS} ci -m test >>${LOGFILE}; then
- echo "PASS: test 83" >>${LOGFILE}
- else
- echo "FAIL: test 83" | tee -a ${LOGFILE} ; exit 1
- fi
-
- # back to the trunk.
- if ${CVS} update -A 2>> ${LOGFILE}; then
- echo "PASS: test 84" >>${LOGFILE}
- else
- echo "FAIL: test 84" | tee -a ${LOGFILE} ; exit 1
- fi
-
- if [ -f file3 ] ; then
- echo "FAIL: test 85" | tee -a ${LOGFILE} ; exit 1
- else
- echo "PASS: test 85" >>${LOGFILE}
- fi
-
- # join
- if ${CVS} update -j branch1 >> ${LOGFILE} 2>&1; then
- echo "PASS: test 86" >>${LOGFILE}
- else
- echo "FAIL: test 86" | tee -a ${LOGFILE} ; exit 1
- fi
-
- if [ -f file3 ] ; then
- echo "PASS: test 87" >>${LOGFILE}
- else
- echo "FAIL: test 87" | tee -a ${LOGFILE} ; exit 1
- fi
-
- # Make sure that we joined the correct change to file1
- if echo line2 from branch1 | cmp - file1 >/dev/null; then
- echo 'PASS: test 87a' >>${LOGFILE}
- else
- echo 'FAIL: test 87a' | tee -a ${LOGFILE}
- exit 1
- fi
-
- # update
- if ${CVS} update ; then
- echo "PASS: test 88" >>${LOGFILE}
- else
- echo "FAIL: test 88" | tee -a ${LOGFILE} ; exit 1
- fi
-
- # commit
- if ${CVS} ci -m test >>${LOGFILE} 2>&1; then
- echo "PASS: test 89" >>${LOGFILE}
- else
- echo "FAIL: test 89" | tee -a ${LOGFILE} ; exit 1
- fi
-
- # remove first file.
- rm file1
- if ${CVS} rm file1 2>> ${LOGFILE}; then
- echo "PASS: test 90" >>${LOGFILE}
- else
- echo "FAIL: test 90" | tee -a ${LOGFILE} ; exit 1
- fi
-
- # commit
- if ${CVS} ci -m test >>${LOGFILE}; then
- echo "PASS: test 91" >>${LOGFILE}
- else
- echo "FAIL: test 91" | tee -a ${LOGFILE} ; exit 1
- fi
-
- if [ -f file1 ] ; then
- echo "FAIL: test 92" | tee -a ${LOGFILE} ; exit 1
- else
- echo "PASS: test 92" >>${LOGFILE}
- fi
-
- # back to branch1
- if ${CVS} update -r branch1 2>> ${LOGFILE}; then
- echo "PASS: test 93" >>${LOGFILE}
- else
- echo "FAIL: test 93" | tee -a ${LOGFILE} ; exit 1
- fi
-
- if [ -f file1 ] ; then
- echo "PASS: test 94" >>${LOGFILE}
- else
- echo "FAIL: test 94" | tee -a ${LOGFILE} ; exit 1
- fi
-
- # and join
- if ${CVS} update -j HEAD >> ${LOGFILE} 2>&1; then
- echo "PASS: test 95" >>${LOGFILE}
- else
- echo "FAIL: test 95" | tee -a ${LOGFILE} ; exit 1
- fi
-
- cd .. ; rm -rf first-dir ${CVSROOT_DIRNAME}/first-dir
- ;;
-
- import) # test death after import
- # import
- mkdir import-dir ; cd import-dir
-
- for i in 1 2 3 4 ; do
- echo imported file"$i" > imported-file"$i"
- done
-
- if ${CVS} import -m first-import first-dir vendor-branch junk-1_0 ; then
- echo "PASS: test 96" >>${LOGFILE}
- else
- echo "FAIL: test 96" | tee -a ${LOGFILE} ; exit 1
- fi
- cd ..
-
- # co
- if ${CVS} co first-dir ; then
- echo "PASS: test 97" >>${LOGFILE}
- else
- echo "FAIL: test 97" | tee -a ${LOGFILE} ; exit 1
- fi
-
- cd first-dir
- for i in 1 2 3 4 ; do
- if [ -f imported-file"$i" ] ; then
- echo "PASS: test 98-$i" >>${LOGFILE}
- else
- echo "FAIL: test 98-$i" | tee -a ${LOGFILE} ; exit 1
- fi
- done
-
- # remove
- rm imported-file1
- if ${CVS} rm imported-file1 2>> ${LOGFILE}; then
- echo "PASS: test 99" >>${LOGFILE}
- else
- echo "FAIL: test 99" | tee -a ${LOGFILE} ; exit 1
- fi
-
- # change
- # this sleep is significant. Otherwise, on some machines, things happen so
- # fast that the file mod times do not differ.
- sleep 1
- echo local-change >> imported-file2
-
- # commit
- if ${CVS} ci -m local-changes >> ${LOGFILE} 2>&1; then
- echo "PASS: test 100" >>${LOGFILE}
- else
- echo "FAIL: test 100" | tee -a ${LOGFILE} ; exit 1
- fi
-
- # log
- if ${CVS} log imported-file1 | grep '1.1.1.2 (dead)' ; then
- echo "FAIL: test 101" | tee -a ${LOGFILE} ; exit 1
- else
- echo "PASS: test 101" >>${LOGFILE}
- fi
-
- # update into the vendor branch.
- if ${CVS} update -rvendor-branch ; then
- echo "PASS: test 102" >>${LOGFILE}
- else
- echo "FAIL: test 102" | tee -a ${LOGFILE} ; exit 1
- fi
-
- # remove file4 on the vendor branch
- rm imported-file4
-
- if ${CVS} rm imported-file4 2>> ${LOGFILE}; then
- echo "PASS: test 103" >>${LOGFILE}
- else
- echo "FAIL: test 103" | tee -a ${LOGFILE} ; exit 1
- fi
-
- # commit
- if ${CVS} ci -m vendor-removed imported-file4 >>${LOGFILE}; then
- echo "PASS: test 104" >>${LOGFILE}
- else
- echo "FAIL: test 104" | tee -a ${LOGFILE} ; exit 1
- fi
-
- # update to main line
- if ${CVS} update -A 2>> ${LOGFILE}; then
- echo "PASS: test 105" >>${LOGFILE}
- else
- echo "FAIL: test 105" | tee -a ${LOGFILE} ; exit 1
- fi
-
- # second import - file4 deliberately unchanged
- cd ../import-dir
- for i in 1 2 3 ; do
- echo rev 2 of file $i >> imported-file"$i"
- done
-
- if ${CVS} import -m second-import first-dir vendor-branch junk-2_0 ; then
- echo "PASS: test 106" >>${LOGFILE}
- else
- echo "FAIL: test 106" | tee -a ${LOGFILE} ; exit 1
- fi
- cd ..
-
- # co
- if ${CVS} co first-dir ; then
- echo "PASS: test 107" >>${LOGFILE}
- else
- echo "FAIL: test 107" | tee -a ${LOGFILE} ; exit 1
- fi
-
- cd first-dir
-
- if [ -f imported-file1 ] ; then
- echo "FAIL: test 108" | tee -a ${LOGFILE} ; exit 1
- else
- echo "PASS: test 108" >>${LOGFILE}
- fi
-
- for i in 2 3 ; do
- if [ -f imported-file"$i" ] ; then
- echo "PASS: test 109-$i" >>${LOGFILE}
- else
- echo "FAIL: test 109-$i" | tee -a ${LOGFILE} ; exit 1
- fi
- done
-
- # check vendor branch for file4
- if ${CVS} update -rvendor-branch ; then
- echo "PASS: test 110" >>${LOGFILE}
- else
- echo "FAIL: test 110" | tee -a ${LOGFILE} ; exit 1
- fi
-
- if [ -f imported-file4 ] ; then
- echo "PASS: test 111" >>${LOGFILE}
- else
- echo "FAIL: test 111" | tee -a ${LOGFILE} ; exit 1
- fi
-
- # update to main line
- if ${CVS} update -A 2>> ${LOGFILE}; then
- echo "PASS: test 112" >>${LOGFILE}
- else
- echo "FAIL: test 112" | tee -a ${LOGFILE} ; exit 1
- fi
-
- cd ..
-
- if ${CVS} co -jjunk-1_0 -jjunk-2_0 first-dir >>${LOGFILE} 2>&1; then
- echo "PASS: test 113" >>${LOGFILE}
- else
- echo "FAIL: test 113" | tee -a ${LOGFILE} ; exit 1
- fi
-
- cd first-dir
-
- if [ -f imported-file1 ] ; then
- echo "FAIL: test 114" | tee -a ${LOGFILE} ; exit 1
- else
- echo "PASS: test 114" >>${LOGFILE}
- fi
-
- for i in 2 3 ; do
- if [ -f imported-file"$i" ] ; then
- echo "PASS: test 115-$i" >>${LOGFILE}
- else
- echo "FAIL: test 115-$i" | tee -a ${LOGFILE} ; exit 1
- fi
- done
-
- if cat imported-file2 | grep '====' >> ${LOGFILE}; then
- echo "PASS: test 116" >>${LOGFILE}
- else
- echo "FAIL: test 116" | tee -a ${LOGFILE} ; exit 1
- fi
- cd .. ; rm -rf first-dir ${CVSROOT_DIRNAME}/first-dir
- ;;
-
- new) # look for stray "no longer pertinent" messages.
- rm -rf first-dir ${CVSROOT_DIRNAME}/first-dir
- mkdir ${CVSROOT_DIRNAME}/first-dir
-
- if ${CVS} co first-dir ; then
- echo "PASS: test 117" >>${LOGFILE}
- else
- echo "FAIL: test 117" | tee -a ${LOGFILE} ; exit 1
- fi
-
- cd first-dir
- touch a
-
- if ${CVS} add a 2>>${LOGFILE}; then
- echo "PASS: test 118" >>${LOGFILE}
- else
- echo "FAIL: test 118" | tee -a ${LOGFILE} ; exit 1
- fi
-
- if ${CVS} ci -m added >>${LOGFILE} 2>&1; then
- echo "PASS: test 119" >>${LOGFILE}
- else
- echo "FAIL: test 119" | tee -a ${LOGFILE} ; exit 1
- fi
-
- rm a
-
- if ${CVS} rm a 2>>${LOGFILE}; then
- echo "PASS: test 120" >>${LOGFILE}
- else
- echo "FAIL: test 120" | tee -a ${LOGFILE} ; exit 1
- fi
-
- if ${CVS} ci -m removed >>${LOGFILE} ; then
- echo "PASS: test 121" >>${LOGFILE}
- else
- echo "FAIL: test 121" | tee -a ${LOGFILE} ; exit 1
- fi
-
- if ${CVS} update -A 2>&1 | grep longer ; then
- echo "FAIL: test 122" | tee -a ${LOGFILE} ; exit 1
- else
- echo "PASS: test 122" >>${LOGFILE}
- fi
-
- if ${CVS} update -rHEAD 2>&1 | grep longer ; then
- echo "FAIL: test 123" | tee -a ${LOGFILE} ; exit 1
- else
- echo "PASS: test 123" >>${LOGFILE}
- fi
-
- cd .. ; rm -rf first-dir ; rm -rf ${CVSROOT_DIRNAME}/first-dir
- ;;
-
- conflicts)
- rm -rf first-dir ${CVSROOT_DIRNAME}/first-dir
- mkdir ${CVSROOT_DIRNAME}/first-dir
-
- mkdir 1
- cd 1
-
- if ${CVS} co first-dir ; then
- echo 'PASS: test 124' >>${LOGFILE}
- else
- echo 'FAIL: test 124' | tee -a ${LOGFILE}
- fi
-
- cd first-dir
- touch a
-
- if ${CVS} add a 2>>${LOGFILE} ; then
- echo 'PASS: test 125' >>${LOGFILE}
- else
- echo 'FAIL: test 125' | tee -a ${LOGFILE}
- fi
-
- if ${CVS} ci -m added >>${LOGFILE} 2>&1; then
- echo 'PASS: test 126' >>${LOGFILE}
- else
- echo 'FAIL: test 126' | tee -a ${LOGFILE}
- fi
-
- cd ../..
- mkdir 2
- cd 2
-
- if ${CVS} co first-dir ; then
- echo 'PASS: test 127' >>${LOGFILE}
- else
- echo 'FAIL: test 127' | tee -a ${LOGFILE}
- fi
- cd first-dir
- if test -f a; then
- echo 'PASS: test 127a' >>${LOGFILE}
- else
- echo 'FAIL: test 127a' | tee -a ${LOGFILE}
- fi
-
- cd ../../1/first-dir
- echo add a line >>a
- if ${CVS} ci -m changed >>${LOGFILE} 2>&1; then
- echo 'PASS: test 128' >>${LOGFILE}
- else
- echo 'FAIL: test 128' | tee -a ${LOGFILE}
- fi
-
- cd ../../2/first-dir
- echo add a conflicting line >>a
- if ${CVS} ci -m changed >>${LOGFILE} 2>&1; then
- echo 'FAIL: test 129' | tee -a ${LOGFILE}
- else
- # Should be printing `out of date check failed'.
- echo 'PASS: test 129' >>${LOGFILE}
- fi
-
- if ${CVS} update 2>>${LOGFILE}; then
- # We should get a conflict, but that doesn't affect
- # exit status
- echo 'PASS: test 130' >>${LOGFILE}
- else
- echo 'FAIL: test 130' | tee -a ${LOGFILE}
- fi
-
- # Try to check in the file with the conflict markers in it.
- if ${CVS} ci -m try 2>>${LOGFILE}; then
- echo 'FAIL: test 131' | tee -a ${LOGFILE}
- else
- # Should tell us to resolve conflict first
- echo 'PASS: test 131' >>${LOGFILE}
- fi
-
- echo lame attempt at resolving it >>a
- # Try to check in the file with the conflict markers in it.
- if ${CVS} ci -m try >>${LOGFILE} 2>&1; then
- echo 'FAIL: test 132' | tee -a ${LOGFILE}
- else
- # Should tell us to resolve conflict first
- echo 'PASS: test 132' >>${LOGFILE}
- fi
-
- echo resolve conflict >a
- if ${CVS} ci -m resolved >>${LOGFILE} 2>&1; then
- echo 'PASS: test 133' >>${LOGFILE}
- else
- echo 'FAIL: test 133' | tee -a ${LOGFILE}
- fi
-
- # Now test that we can add a file in one working directory
- # and have an update in another get it.
- cd ../../1/first-dir
- echo abc >abc
- if ${testcvs} add abc >>${LOGFILE} 2>&1; then
- echo 'PASS: test 134' >>${LOGFILE}
- else
- echo 'FAIL: test 134' | tee -a ${LOGFILE}
- fi
- if ${testcvs} ci -m 'add abc' abc >>${LOGFILE} 2>&1; then
- echo 'PASS: test 135' >>${LOGFILE}
- else
- echo 'FAIL: test 135' | tee -a ${LOGFILE}
- fi
- cd ../../2
- if ${testcvs} -q update >>${LOGFILE}; then
- echo 'PASS: test 136' >>${LOGFILE}
- else
- echo 'FAIL: test 136' | tee -a ${LOGFILE}
- fi
- if test -f first-dir/abc; then
- echo 'PASS: test 137' >>${LOGFILE}
- else
- echo 'FAIL: test 137' | tee -a ${LOGFILE}
- fi
-
- # Now test something similar, but in which the parent directory
- # (not the directory in question) has the Entries.Static flag
- # set.
- cd ../1/first-dir
- mkdir subdir
- if ${testcvs} add subdir >>${LOGFILE}; then
- echo 'PASS: test 138' >>${LOGFILE}
- else
- echo 'FAIL: test 138' | tee -a ${LOGFILE}
- fi
- cd ../..
- mkdir 3
- cd 3
- if ${testcvs} -q co first-dir/abc first-dir/subdir \
- >>${LOGFILE}; then
- echo 'PASS: test 139' >>${LOGFILE}
- else
- echo 'FAIL: test 139' | tee -a ${LOGFILE}
- fi
- cd ../1/first-dir/subdir
- echo sss >sss
- if ${testcvs} add sss >>${LOGFILE} 2>&1; then
- echo 'PASS: test 140' >>${LOGFILE}
- else
- echo 'FAIL: test 140' | tee -a ${LOGFILE}
- fi
- if ${testcvs} ci -m adding sss >>${LOGFILE} 2>&1; then
- echo 'PASS: test 140' >>${LOGFILE}
- else
- echo 'FAIL: test 140' | tee -a ${LOGFILE}
- fi
- cd ../../../3/first-dir
- if ${testcvs} -q update >>${LOGFILE}; then
- echo 'PASS: test 141' >>${LOGFILE}
- else
- echo 'FAIL: test 141' | tee -a ${LOGFILE}
- fi
- if test -f subdir/sss; then
- echo 'PASS: test 142' >>${LOGFILE}
- else
- echo 'FAIL: test 142' | tee -a ${LOGFILE}
- fi
-
- cd ../..
- rm -rf 1 2 3 ; rm -rf ${CVSROOT_DIRNAME}/first-dir
- ;;
- modules)
- # The following line stolen from cvsinit.sh. FIXME: create our
- # repository via cvsinit.sh; that way we test it too.
- (cd ${CVSROOT_DIRNAME}/CVSROOT; ci -q -u -t/dev/null \
- -m'initial checkin of modules' modules)
-
- rm -rf first-dir ${CVSROOT_DIRNAME}/first-dir
- mkdir ${CVSROOT_DIRNAME}/first-dir
-
- mkdir 1
- cd 1
-
- if ${testcvs} -q co first-dir; then
- echo 'PASS: test 143' >>${LOGFILE}
- else
- echo 'FAIL: test 143' | tee -a ${LOGFILE}
- exit 1
- fi
-
- cd first-dir
- mkdir subdir
- ${testcvs} add subdir >>${LOGFILE}
- cd subdir
-
- touch a
-
- if ${testcvs} add a 2>>${LOGFILE} ; then
- echo 'PASS: test 144' >>${LOGFILE}
- else
- echo 'FAIL: test 144' | tee -a ${LOGFILE}
- exit 1
- fi
-
- if ${testcvs} ci -m added >>${LOGFILE} 2>&1; then
- echo 'PASS: test 145' >>${LOGFILE}
- else
- echo 'FAIL: test 145' | tee -a ${LOGFILE}
- exit 1
- fi
-
- cd ..
- if ${testcvs} -q co CVSROOT >>${LOGFILE}; then
- echo 'PASS: test 146' >>${LOGFILE}
- else
- echo 'FAIL: test 146' | tee -a ${LOGFILE}
- exit 1
- fi
-
- # Here we test that CVS can deal with CVSROOT (whose repository
- # is at top level) in the same directory as subdir (whose repository
- # is a subdirectory of first-dir). TODO: Might want to check that
- # files can actually get updated in this state.
- if ${testcvs} -q update; then
- echo 'PASS: test 147' >>${LOGFILE}
- else
- echo 'FAIL: test 147' | tee -a ${LOGFILE}
- exit 1
- fi
-
- echo realmodule first-dir/subdir a >>CVSROOT/modules
- echo aliasmodule -a first-dir/subdir/a >>CVSROOT/modules
- if ${testcvs} ci -m 'add modules' CVSROOT/modules \
- >>${LOGFILE} 2>&1; then
- echo 'PASS: test 148' >>${LOGFILE}
- else
- echo 'FAIL: test 148' | tee -a ${LOGFILE}
- exit 1
- fi
- cd ..
- if ${testcvs} co realmodule >>${LOGFILE}; then
- echo 'PASS: test 149' >>${LOGFILE}
- else
- echo 'FAIL: test 149' | tee -a ${LOGFILE}
- exit 1
- fi
- if test -d realmodule && test -f realmodule/a; then
- echo 'PASS: test 150' >>${LOGFILE}
- else
- echo 'FAIL: test 150' | tee -a ${LOGFILE}
- exit 1
- fi
- if ${testcvs} co aliasmodule >>${LOGFILE}; then
- echo 'PASS: test 151' >>${LOGFILE}
- else
- echo 'FAIL: test 151' | tee -a ${LOGFILE}
- exit 1
- fi
- if test -d aliasmodule; then
- echo 'FAIL: test 152' | tee -a ${LOGFILE}
- exit 1
- else
- echo 'PASS: test 152' >>${LOGFILE}
- fi
- echo abc >>first-dir/subdir/a
- if (${testcvs} -q co aliasmodule | tee test153.tmp) \
- >>${LOGFILE}; then
- echo 'PASS: test 153' >>${LOGFILE}
- else
- echo 'FAIL: test 153' | tee -a ${LOGFILE}
- exit 1
- fi
- echo 'M first-dir/subdir/a' >ans153.tmp
- if cmp test153.tmp ans153.tmp; then
- echo 'PASS: test 154' >>${LOGFILE}
- else
- echo 'FAIL: test 154' | tee -a ${LOGFILE}
- exit 1
- fi
- if ${testcvs} -q co realmodule; then
- echo 'PASS: test 155' >>${LOGFILE}
- else
- echo 'FAIL: test 155' | tee -a ${LOGFILE}
- exit 1
- fi
- cd ..
- rm -rf 1 ; rm -rf ${CVSROOT_DIRNAME}/first-dir
- ;;
- mflag)
- for message in '' ' ' '
- ' ' test' ; do
- # Set up
- mkdir a-dir; cd a-dir
- # Test handling of -m during import
- echo testa >>test
- if ${testcvs} import -m "$message" a-dir A A1 >>${LOGFILE} 2>&1;then
- echo 'PASS: test 156' >>${LOGFILE}
- else
- echo 'FAIL: test 156' | tee -a ${LOGFILE}
- exit 1
- fi
- # Must import twice since the first time uses inline code that
- # avoids RCS call.
- echo testb >>test
- if ${testcvs} import -m "$message" a-dir A A2 >>${LOGFILE} 2>&1;then
- echo 'PASS: test 157' >>${LOGFILE}
- else
- echo 'FAIL: test 157' | tee -a ${LOGFILE}
- exit 1
- fi
- # Test handling of -m during ci
- cd ..; rm -rf a-dir;
- if ${testcvs} co a-dir >>${LOGFILE} 2>&1; then
- echo 'PASS: test 158' >>${LOGFILE}
- else
- echo 'FAIL: test 158' | tee -a ${LOGFILE}
- exit 1
- fi
- cd a-dir
- echo testc >>test
- if ${testcvs} ci -m "$message" >>${LOGFILE} 2>&1; then
- echo 'PASS: test 159' >>${LOGFILE}
- else
- echo 'FAIL: test 159' | tee -a ${LOGFILE}
- exit 1
- fi
- # Test handling of -m during rm/ci
- rm test;
- if ${testcvs} rm test >>${LOGFILE} 2>&1; then
- echo 'PASS: test 160' >>${LOGFILE}
- else
- echo 'FAIL: test 160' | tee -a ${LOGFILE}
- exit 1
- fi
- if ${testcvs} ci -m "$message" >>${LOGFILE} 2>&1; then
- echo 'PASS: test 161' >>${LOGFILE}
- else
- echo 'FAIL: test 161' | tee -a ${LOGFILE}
- exit 1
- fi
- # Clean up
- cd ..; rm -rf a-dir ${CVSROOT_DIRNAME}/a-dir
- done
- ;;
- errmsg1)
- mkdir ${CVSROOT_DIRNAME}/1dir
- mkdir 1
- cd 1
- if ${testcvs} -q co 1dir; then
- echo 'PASS: test 162' >>${LOGFILE}
- else
- echo 'FAIL: test 162' | tee -a ${LOGFILE}
- exit 1
- fi
- cd 1dir
- touch foo
- if ${testcvs} add foo 2>>${LOGFILE}; then
- echo 'PASS: test 163' >>${LOGFILE}
- else
- echo 'FAIL: test 163' | tee -a ${LOGFILE}
- exit 1
- fi
- if ${testcvs} ci -m added >>${LOGFILE} 2>&1; then
- echo 'PASS: test 164' >>${LOGFILE}
- else
- echo 'FAIL: test 164' | tee -a ${LOGFILE}
- exit 1
- fi
- cd ../..
- mkdir 2
- cd 2
- if ${testcvs} -q co 1dir >>${LOGFILE}; then
- echo 'PASS: test 165' >>${LOGFILE}
- else
- echo 'FAIL: test 165' | tee -a ${LOGFILE}
- exit 1
- fi
- chmod a-w 1dir
- cd ../1/1dir
- rm foo;
- if ${testcvs} rm foo >>${LOGFILE} 2>&1; then
- echo 'PASS: test 166' >>${LOGFILE}
- else
- echo 'FAIL: test 166' | tee -a ${LOGFILE}
- exit 1
- fi
- if ${testcvs} ci -m removed >>${LOGFILE} 2>&1; then
- echo 'PASS: test 167' >>${LOGFILE}
- else
- echo 'FAIL: test 167' | tee -a ${LOGFILE}
- exit 1
- fi
- cd ../../2/1dir
- ${testcvs} -q update 2>../tst167.err
- CVSBASE=`basename $testcvs` # Get basename of CVS executable.
- cat <<EOF >../tst167.ans
-$CVSBASE server: warning: foo is not (any longer) pertinent
-$CVSBASE update: unable to remove ./foo: Permission denied
-EOF
- if cmp ../tst167.ans ../tst167.err >/dev/null ||
- ( echo "$CVSBASE [update aborted]: cannot rename file foo to CVS/,,foo: Permission denied" | cmp - ../tst167.err >/dev/null )
- then
- echo 'PASS: test 168' >>${LOGFILE}
- else
- echo 'FAIL: test 168' | tee -a ${LOGFILE}
- exit 1
- fi
-
- cd ..
- chmod u+w 1dir
- cd ..
- rm -rf 1 2 ${CVSROOT_DIRNAME}/1dir
- ;;
-
- *)
- echo $what is not the name of a test -- ignored
- ;;
- esac
-done
-
-echo "OK, all tests completed."
-
-# TODO:
-# * Test `cvs admin'.
-# * Test `cvs update -d foo' (where foo does not exist).
-# * Test `cvs update foo bar' (where foo and bar are both from the same
-# repository). Suppose one is a branch--make sure that both directories
-# get updated with the respective correct thing.
-# * Zero length files (check in, check out).
-# * `cvs update ../foo'. Also ../../foo ./../foo foo/../../bar /foo/bar
-# foo/.././../bar foo/../bar etc.
-# * Test all flags in modules file.
-# Test that ciprog gets run both on checkin in that directory, or a
-# higher-level checkin which recurses into it.
-# * Test that $ followed by "Header" followed by $ gets expanded on checkin.
-# * Test operations on a directory that contains other directories but has
-# no files of its own.
-# * -t global option
-# * cvs rm followed by cvs add or vice versa (with no checkin in between).
-# * cvs rm twice (should be a nice error message).
-# * -P option to checkout--(a) refrains from checking out new empty dirs,
-# (b) prunes empty dirs already there.
-# * Test that cvs -d `hostname`:/tmp/cvs-sanity/non/existent co foo
-# gives an appropriate error (e.g.
-# Cannot access /tmp/cvs-sanity/non-existent/CVSROOT
-# No such file or directory).
-# End of TODO list.
-
-# Remove the test directory, but first change out of it.
-cd /tmp
-rm -rf ${TESTDIR}
-
-# end of sanity.sh
diff --git a/gnu/usr.bin/cvs/cvs/server.c b/gnu/usr.bin/cvs/cvs/server.c
deleted file mode 100644
index fbfca86d393d..000000000000
--- a/gnu/usr.bin/cvs/cvs/server.c
+++ /dev/null
@@ -1,3992 +0,0 @@
-#include "cvs.h"
-
-#ifdef SERVER_SUPPORT
-
-/* for select */
-#include <sys/types.h>
-#ifdef HAVE_SYS_BSDTYPES_H
-#include <sys/bsdtypes.h>
-#endif
-#include <sys/time.h>
-
-#if HAVE_SYS_SELECT_H
-#include <sys/select.h>
-#endif
-
-#if HAVE_FCNTL_H
-#include <fcntl.h>
-#endif
-
-#ifndef O_NONBLOCK
-#define O_NONBLOCK O_NDELAY
-#endif
-
-
-/* Functions which the server calls. */
-int add PROTO((int argc, char **argv));
-int admin PROTO((int argc, char **argv));
-int checkout PROTO((int argc, char **argv));
-int commit PROTO((int argc, char **argv));
-int diff PROTO((int argc, char **argv));
-int history PROTO((int argc, char **argv));
-int import PROTO((int argc, char **argv));
-int cvslog PROTO((int argc, char **argv));
-int patch PROTO((int argc, char **argv));
-int release PROTO((int argc, char **argv));
-int cvsremove PROTO((int argc, char **argv));
-int rtag PROTO((int argc, char **argv));
-int status PROTO((int argc, char **argv));
-int tag PROTO((int argc, char **argv));
-int update PROTO((int argc, char **argv));
-
-
-/*
- * This is where we stash stuff we are going to use. Format string
- * which expects a single directory within it, starting with a slash.
- */
-static char *server_temp_dir;
-
-/* Nonzero if we should keep the temp directory around after we exit. */
-static int dont_delete_temp;
-
-static char no_mem_error;
-#define NO_MEM_ERROR (&no_mem_error)
-
-static void server_write_entries PROTO((void));
-
-/*
- * Read a line from the stream "instream" without command line editing.
- *
- * Action is compatible with "readline", e.g. space for the result is
- * malloc'd and should be freed by the caller.
- *
- * A NULL return means end of file. A return of NO_MEM_ERROR means
- * that we are out of memory.
- */
-static char *read_line PROTO((FILE *));
-
-static char *
-read_line (stream)
- FILE *stream;
-{
- int c;
- char *result;
- int input_index = 0;
- int result_size = 80;
-
- fflush (stdout);
- result = (char *) malloc (result_size);
- if (result == NULL)
- return NO_MEM_ERROR;
-
- while (1)
- {
- c = fgetc (stream);
-
- if (c == EOF)
- {
- free (result);
- return NULL;
- }
-
- if (c == '\n')
- break;
-
- result[input_index++] = c;
- while (input_index >= result_size)
- {
- result_size *= 2;
- result = (char *) realloc (result, result_size);
- if (result == NULL)
- return NO_MEM_ERROR;
- }
- }
-
- result[input_index++] = '\0';
- return result;
-}
-
-/*
- * Make directory DIR, including all intermediate directories if necessary.
- * Returns 0 for success or errno code.
- */
-static int mkdir_p PROTO((char *));
-
-static int
-mkdir_p (dir)
- char *dir;
-{
- char *p;
- char *q = malloc (strlen (dir) + 1);
- int retval;
-
- if (q == NULL)
- return ENOMEM;
-
- /*
- * Skip over leading slash if present. We won't bother to try to
- * make '/'.
- */
- p = dir + 1;
- while (1)
- {
- while (*p != '/' && *p != '\0')
- ++p;
- if (*p == '/')
- {
- strncpy (q, dir, p - dir);
- q[p - dir] = '\0';
- if (CVS_MKDIR (q, 0777) < 0)
- {
- if (errno != EEXIST
- && (errno != EACCES || !isdir(q)))
- {
- retval = errno;
- goto done;
- }
- }
- ++p;
- }
- else
- {
- if (CVS_MKDIR (dir, 0777) < 0)
- retval = errno;
- else
- retval = 0;
- goto done;
- }
- }
- done:
- free (q);
- return retval;
-}
-
-/*
- * Print the error response for error code STATUS. The caller is
- * reponsible for making sure we get back to the command loop without
- * any further output occuring.
- */
-static void
-print_error (status)
- int status;
-{
- char *msg;
- printf ("error ");
- msg = strerror (status);
- if (msg)
- printf ("%s", msg);
- printf ("\n");
-}
-
-static int pending_error;
-/*
- * Malloc'd text for pending error. Each line must start with "E ". The
- * last line should not end with a newline.
- */
-static char *pending_error_text;
-
-/* If an error is pending, print it and return 1. If not, return 0. */
-static int
-print_pending_error ()
-{
- if (pending_error_text)
- {
- printf ("%s\n", pending_error_text);
- if (pending_error)
- print_error (pending_error);
- else
- printf ("error \n");
- pending_error = 0;
- free (pending_error_text);
- pending_error_text = NULL;
- return 1;
- }
- else if (pending_error)
- {
- print_error (pending_error);
- pending_error = 0;
- return 1;
- }
- else
- return 0;
-}
-
-/* Is an error pending? */
-#define error_pending() (pending_error || pending_error_text)
-
-int
-supported_response (name)
- char *name;
-{
- struct response *rs;
-
- for (rs = responses; rs->name != NULL; ++rs)
- if (strcmp (rs->name, name) == 0)
- return rs->status == rs_supported;
- error (1, 0, "internal error: testing support for unknown response?");
-}
-
-static void
-serve_valid_responses (arg)
- char *arg;
-{
- char *p = arg;
- char *q;
- struct response *rs;
- do
- {
- q = strchr (p, ' ');
- if (q != NULL)
- *q++ = '\0';
- for (rs = responses; rs->name != NULL; ++rs)
- {
- if (strcmp (rs->name, p) == 0)
- break;
- }
- if (rs->name == NULL)
- /*
- * It is a response we have never heard of (and thus never
- * will want to use). So don't worry about it.
- */
- ;
- else
- rs->status = rs_supported;
- p = q;
- } while (q != NULL);
- for (rs = responses; rs->name != NULL; ++rs)
- {
- if (rs->status == rs_essential)
- {
- printf ("E response `%s' not supported by client\nerror \n",
- rs->name);
- exit (1);
- }
- else if (rs->status == rs_optional)
- rs->status = rs_not_supported;
- }
-}
-
-static int use_dir_and_repos = 0;
-
-static void
-serve_root (arg)
- char *arg;
-{
- char *env;
- extern char *CVSroot;
- char path[PATH_MAX];
- int save_errno;
-
- if (error_pending()) return;
-
- (void) sprintf (path, "%s/%s", arg, CVSROOTADM);
- if (!isaccessible (path, R_OK | X_OK))
- {
- save_errno = errno;
- pending_error_text = malloc (80 + strlen (path));
- if (pending_error_text != NULL)
- sprintf (pending_error_text, "E Cannot access %s", path);
- pending_error = save_errno;
- }
- (void) strcat (path, "/");
- (void) strcat (path, CVSROOTADM_HISTORY);
- if (isfile (path) && !isaccessible (path, R_OK | W_OK))
- {
- save_errno = errno;
- pending_error_text = malloc (80 + strlen (path));
- if (pending_error_text != NULL)
- sprintf (pending_error_text, "E \
-Sorry, you don't have read/write access to the history file %s", path);
- pending_error = save_errno;
- }
-
- CVSroot = malloc (strlen (arg) + 1);
- if (CVSroot == NULL)
- {
- pending_error = ENOMEM;
- return;
- }
- strcpy (CVSroot, arg);
-#ifdef HAVE_PUTENV
- env = malloc (strlen (CVSROOT_ENV) + strlen (CVSroot) + 1 + 1);
- if (env == NULL)
- {
- pending_error = ENOMEM;
- return;
- }
- (void) sprintf (env, "%s=%s", CVSROOT_ENV, arg);
- (void) putenv (env);
- /* do not free env, as putenv has control of it */
-#endif
-}
-
-/*
- * Add as many directories to the temp directory as the client tells us it
- * will use "..", so we never try to access something outside the temp
- * directory via "..".
- */
-static void
-serve_max_dotdot (arg)
- char *arg;
-{
- int lim = atoi (arg);
- int i;
- char *p;
-
- if (lim < 0)
- return;
- p = malloc (strlen (server_temp_dir) + 2 * lim + 10);
- if (p == NULL)
- {
- pending_error = ENOMEM;
- return;
- }
- strcpy (p, server_temp_dir);
- for (i = 0; i < lim; ++i)
- strcat (p, "/d");
- free (server_temp_dir);
- server_temp_dir = p;
-}
-
-static void
-dirswitch (dir, repos)
- char *dir;
- char *repos;
-{
- char *dirname;
- int status;
- FILE *f;
-
- server_write_entries ();
-
- if (error_pending()) return;
-
- dirname = malloc (strlen (server_temp_dir) + strlen (dir) + 40);
- if (dirname == NULL)
- {
- pending_error = ENOMEM;
- return;
- }
-
- strcpy (dirname, server_temp_dir);
- strcat (dirname, "/");
- strcat (dirname, dir);
-
- status = mkdir_p (dirname);
- if (status != 0
- && status != EEXIST)
- {
- pending_error = status;
- pending_error_text = malloc (80 + strlen(dirname));
- sprintf(pending_error_text, "E cannot mkdir %s", dirname);
- return;
- }
- if (chdir (dirname) < 0)
- {
- pending_error = errno;
- pending_error_text = malloc (80 + strlen(dirname));
- sprintf(pending_error_text, "E cannot change to %s", dirname);
- return;
- }
- /*
- * This is pretty much like calling Create_Admin, but Create_Admin doesn't
- * report errors in the right way for us.
- */
- if (CVS_MKDIR (CVSADM, 0777) < 0)
- {
- if (errno == EEXIST)
- /* Don't create the files again. */
- return;
- pending_error = errno;
- return;
- }
- f = fopen (CVSADM_REP, "w");
- if (f == NULL)
- {
- pending_error = errno;
- return;
- }
- if (fprintf (f, "%s\n", repos) < 0)
- {
- pending_error = errno;
- fclose (f);
- return;
- }
- if (fclose (f) == EOF)
- {
- pending_error = errno;
- return;
- }
- f = fopen (CVSADM_ENT, "w+");
- if (f == NULL)
- {
- pending_error = errno;
- pending_error_text = malloc (80 + strlen(CVSADM_ENT));
- sprintf(pending_error_text, "E cannot open %s", CVSADM_ENT);
- return;
- }
- if (fclose (f) == EOF)
- {
- pending_error = errno;
- pending_error_text = malloc (80 + strlen(CVSADM_ENT));
- sprintf(pending_error_text, "E cannot close %s", CVSADM_ENT);
- return;
- }
- free (dirname);
-}
-
-static void
-serve_repository (arg)
- char *arg;
-{
- dirswitch (arg + 1, arg);
-}
-
-static void
-serve_directory (arg)
- char *arg;
-{
- char *repos;
- use_dir_and_repos = 1;
- repos = read_line (stdin);
- if (repos == NULL)
- {
- pending_error_text = malloc (80 + strlen (arg));
- if (pending_error_text)
- {
- if (feof (stdin))
- sprintf (pending_error_text,
- "E end of file reading mode for %s", arg);
- else
- {
- sprintf (pending_error_text,
- "E error reading mode for %s", arg);
- pending_error = errno;
- }
- }
- else
- pending_error = ENOMEM;
- }
- else if (repos == NO_MEM_ERROR)
- {
- pending_error = ENOMEM;
- }
- else
- {
- dirswitch (arg, repos);
- free (repos);
- }
-}
-
-static void
-serve_static_directory (arg)
- char *arg;
-{
- FILE *f;
- f = fopen (CVSADM_ENTSTAT, "w+");
- if (f == NULL)
- {
- pending_error = errno;
- pending_error_text = malloc (80 + strlen(CVSADM_ENTSTAT));
- sprintf(pending_error_text, "E cannot open %s", CVSADM_ENTSTAT);
- return;
- }
- if (fclose (f) == EOF)
- {
- pending_error = errno;
- pending_error_text = malloc (80 + strlen(CVSADM_ENTSTAT));
- sprintf(pending_error_text, "E cannot close %s", CVSADM_ENTSTAT);
- return;
- }
-}
-
-static void
-serve_sticky (arg)
- char *arg;
-{
- FILE *f;
- f = fopen (CVSADM_TAG, "w+");
- if (f == NULL)
- {
- pending_error = errno;
- pending_error_text = malloc (80 + strlen(CVSADM_TAG));
- sprintf(pending_error_text, "E cannot open %s", CVSADM_TAG);
- return;
- }
- if (fprintf (f, "%s\n", arg) < 0)
- {
- pending_error = errno;
- pending_error_text = malloc (80 + strlen(CVSADM_TAG));
- sprintf(pending_error_text, "E cannot write to %s", CVSADM_TAG);
- return;
- }
- if (fclose (f) == EOF)
- {
- pending_error = errno;
- pending_error_text = malloc (80 + strlen(CVSADM_TAG));
- sprintf(pending_error_text, "E cannot close %s", CVSADM_TAG);
- return;
- }
-}
-
-/*
- * Read SIZE bytes from stdin, write them to FILE.
- *
- * Currently this isn't really used for receiving parts of a file --
- * the file is still sent over in one chunk. But if/when we get
- * spiffy in-process gzip support working, perhaps the compressed
- * pieces could be sent over as they're ready, if the network is fast
- * enough. Or something.
- */
-static void
-receive_partial_file (size, file)
- int size;
- int file;
-{
- char buf[16*1024], *bufp;
- int toread, nread, nwrote;
- while (size > 0)
- {
- toread = sizeof (buf);
- if (toread > size)
- toread = size;
-
- nread = fread (buf, 1, toread, stdin);
- if (nread <= 0)
- {
- if (feof (stdin))
- {
- pending_error_text = malloc (80);
- if (pending_error_text)
- {
- sprintf (pending_error_text,
- "E premature end of file from client");
- pending_error = 0;
- }
- else
- pending_error = ENOMEM;
- }
- else if (ferror (stdin))
- {
- pending_error_text = malloc (40);
- if (pending_error_text)
- sprintf (pending_error_text,
- "E error reading from client");
- pending_error = errno;
- }
- else
- {
- pending_error_text = malloc (40);
- if (pending_error_text)
- sprintf (pending_error_text,
- "E short read from client");
- pending_error = 0;
- }
- return;
- }
- size -= nread;
- bufp = buf;
- while (nread)
- {
- nwrote = write (file, bufp, nread);
- if (nwrote < 0)
- {
- pending_error_text = malloc (40);
- if (pending_error_text)
- sprintf (pending_error_text, "E unable to write");
- pending_error = errno;
- return;
- }
- nread -= nwrote;
- bufp += nwrote;
- }
- }
-}
-
-/* Receive SIZE bytes, write to filename FILE. */
-static void
-receive_file (size, file, gzipped)
- int size;
- char *file;
- int gzipped;
-{
- int fd;
- char *arg = file;
- pid_t gzip_pid = 0;
- int gzip_status;
-
- /* Write the file. */
- fd = open (arg, O_WRONLY | O_CREAT | O_TRUNC, 0600);
- if (fd < 0)
- {
- pending_error_text = malloc (40 + strlen (arg));
- if (pending_error_text)
- sprintf (pending_error_text, "E cannot open %s", arg);
- pending_error = errno;
- return;
- }
-
- /*
- * FIXME: This doesn't do anything reasonable with gunzip's stderr, which
- * means that if gunzip writes to stderr, it will cause all manner of
- * protocol violations.
- */
- if (gzipped)
- fd = filter_through_gunzip (fd, 0, &gzip_pid);
-
- receive_partial_file (size, fd);
-
- if (pending_error_text)
- {
- char *p = realloc (pending_error_text,
- strlen (pending_error_text) + strlen (arg) + 30);
- if (p)
- {
- pending_error_text = p;
- sprintf (p + strlen (p), ", file %s", arg);
- }
- /* else original string is supposed to be unchanged */
- }
-
- if (close (fd) < 0 && !error_pending ())
- {
- pending_error_text = malloc (40 + strlen (arg));
- if (pending_error_text)
- sprintf (pending_error_text, "E cannot close %s", arg);
- pending_error = errno;
- if (gzip_pid)
- waitpid (gzip_pid, (int *) 0, 0);
- return;
- }
-
- if (gzip_pid)
- {
- if (waitpid (gzip_pid, &gzip_status, 0) != gzip_pid)
- error (1, errno, "waiting for gunzip process %d", gzip_pid);
- else if (gzip_status != 0)
- error (1, 0, "gunzip exited %d", gzip_status);
- }
-}
-
-static void
-serve_modified (arg)
- char *arg;
-{
- int size;
- char *size_text;
- char *mode_text;
-
- int gzipped = 0;
-
- if (error_pending ()) return;
-
- mode_text = read_line (stdin);
- if (mode_text == NULL)
- {
- pending_error_text = malloc (80 + strlen (arg));
- if (pending_error_text)
- {
- if (feof (stdin))
- sprintf (pending_error_text,
- "E end of file reading mode for %s", arg);
- else
- {
- sprintf (pending_error_text,
- "E error reading mode for %s", arg);
- pending_error = errno;
- }
- }
- else
- pending_error = ENOMEM;
- return;
- }
- else if (mode_text == NO_MEM_ERROR)
- {
- pending_error = ENOMEM;
- return;
- }
- size_text = read_line (stdin);
- if (size_text == NULL)
- {
- pending_error_text = malloc (80 + strlen (arg));
- if (pending_error_text)
- {
- if (feof (stdin))
- sprintf (pending_error_text,
- "E end of file reading size for %s", arg);
- else
- {
- sprintf (pending_error_text,
- "E error reading size for %s", arg);
- pending_error = errno;
- }
- }
- else
- pending_error = ENOMEM;
- return;
- }
- else if (size_text == NO_MEM_ERROR)
- {
- pending_error = ENOMEM;
- return;
- }
- if (size_text[0] == 'z')
- {
- gzipped = 1;
- size = atoi (size_text + 1);
- }
- else
- size = atoi (size_text);
- free (size_text);
-
- if (size >= 0)
- {
- receive_file (size, arg, gzipped);
- if (error_pending ()) return;
- }
-
- {
- int status = change_mode (arg, mode_text);
- free (mode_text);
- if (status)
- {
- pending_error_text = malloc (40 + strlen (arg));
- if (pending_error_text)
- sprintf (pending_error_text,
- "E cannot change mode for %s", arg);
- pending_error = status;
- return;
- }
- }
-}
-
-#endif /* SERVER_SUPPORT */
-
-#if defined(SERVER_SUPPORT) || defined(CLIENT_SUPPORT)
-
-int use_unchanged = 0;
-
-#endif
-#ifdef SERVER_SUPPORT
-
-static void
-serve_enable_unchanged (arg)
- char *arg;
-{
- use_unchanged = 1;
-}
-
-static void
-serve_lost (arg)
- char *arg;
-{
- if (use_unchanged)
- {
- /* A missing file already indicates it is nonexistent. */
- return;
- }
- else
- {
- struct utimbuf ut;
- int fd = open (arg, O_WRONLY | O_CREAT | O_TRUNC, 0666);
- if (fd < 0 || close (fd) < 0)
- {
- pending_error = errno;
- pending_error_text = malloc (80 + strlen(arg));
- sprintf(pending_error_text, "E cannot open %s", arg);
- return;
- }
- /*
- * Set the times to the beginning of the epoch to tell time_stamp()
- * that the file was lost.
- */
- ut.actime = 0;
- ut.modtime = 0;
- if (utime (arg, &ut) < 0)
- {
- pending_error = errno;
- pending_error_text = malloc (80 + strlen(arg));
- sprintf(pending_error_text, "E cannot utime %s", arg);
- return;
- }
- }
-}
-
-struct an_entry {
- struct an_entry *next;
- char *entry;
-};
-
-static struct an_entry *entries;
-
-static void
-serve_unchanged (arg)
- char *arg;
-{
- if (error_pending ())
- return;
- if (!use_unchanged)
- {
- /* A missing file already indicates it is unchanged. */
- return;
- }
- else
- {
- struct an_entry *p;
- char *name;
- char *cp;
- char *timefield;
-
- /* Rewrite entries file to have `=' in timestamp field. */
- for (p = entries; p != NULL; p = p->next)
- {
- name = p->entry + 1;
- cp = strchr (name, '/');
- if (cp != NULL
- && strlen (arg) == cp - name
- && strncmp (arg, name, cp - name) == 0)
- {
- timefield = strchr (cp + 1, '/') + 1;
- if (*timefield != '=')
- {
- cp = timefield + strlen (timefield);
- cp[1] = '\0';
- while (cp > timefield)
- {
- *cp = cp[-1];
- --cp;
- }
- *timefield = '=';
- }
- break;
- }
- }
- }
-}
-
-static void
-serve_entry (arg)
- char *arg;
-{
- struct an_entry *p;
- char *cp;
- if (error_pending()) return;
- p = (struct an_entry *) malloc (sizeof (struct an_entry));
- if (p == NULL)
- {
- pending_error = ENOMEM;
- return;
- }
- /* Leave space for serve_unchanged to write '=' if it wants. */
- cp = malloc (strlen (arg) + 2);
- if (cp == NULL)
- {
- pending_error = ENOMEM;
- return;
- }
- strcpy (cp, arg);
- p->next = entries;
- p->entry = cp;
- entries = p;
-}
-
-static void
-server_write_entries ()
-{
- FILE *f;
- struct an_entry *p;
- struct an_entry *q;
-
- if (entries == NULL)
- return;
-
- f = NULL;
- /* Note that we free all the entries regardless of errors. */
- if (!error_pending ())
- {
- f = fopen (CVSADM_ENT, "w");
- if (f == NULL)
- {
- pending_error = errno;
- pending_error_text = malloc (80 + strlen(CVSADM_ENT));
- sprintf(pending_error_text, "E cannot open %s", CVSADM_ENT);
- }
- }
- for (p = entries; p != NULL;)
- {
- if (!error_pending ())
- {
- if (fprintf (f, "%s\n", p->entry) < 0)
- {
- pending_error = errno;
- pending_error_text = malloc (80 + strlen(CVSADM_ENT));
- sprintf(pending_error_text, "E cannot write to %s", CVSADM_ENT);
- }
- }
- free (p->entry);
- q = p->next;
- free (p);
- p = q;
- }
- entries = NULL;
- if (f != NULL && fclose (f) == EOF && !error_pending ())
- {
- pending_error = errno;
- pending_error_text = malloc (80 + strlen(CVSADM_ENT));
- sprintf(pending_error_text, "E cannot close %s", CVSADM_ENT);
- }
-}
-
-static int argument_count;
-static char **argument_vector;
-static int argument_vector_size;
-
-static void
-serve_argument (arg)
- char *arg;
-{
- char *p;
-
- if (error_pending()) return;
-
- if (argument_vector_size <= argument_count)
- {
- argument_vector_size *= 2;
- argument_vector =
- (char **) realloc ((char *)argument_vector,
- argument_vector_size * sizeof (char *));
- if (argument_vector == NULL)
- {
- pending_error = ENOMEM;
- return;
- }
- }
- p = malloc (strlen (arg) + 1);
- if (p == NULL)
- {
- pending_error = ENOMEM;
- return;
- }
- strcpy (p, arg);
- argument_vector[argument_count++] = p;
-}
-
-static void
-serve_argumentx (arg)
- char *arg;
-{
- char *p;
-
- if (error_pending()) return;
-
- p = argument_vector[argument_count - 1];
- p = realloc (p, strlen (p) + 1 + strlen (arg) + 1);
- if (p == NULL)
- {
- pending_error = ENOMEM;
- return;
- }
- strcat (p, "\n");
- strcat (p, arg);
- argument_vector[argument_count - 1] = p;
-}
-
-static void
-serve_global_option (arg)
- char *arg;
-{
- if (arg[0] != '-' || arg[1] == '\0' || arg[2] != '\0')
- {
- error_return:
- pending_error_text = malloc (strlen (arg) + 80);
- sprintf (pending_error_text, "E Protocol error: bad global option %s",
- arg);
- return;
- }
- switch (arg[1])
- {
- case 'n':
- noexec = 1;
- break;
- case 'q':
- quiet = 1;
- break;
- case 'r':
- cvswrite = 0;
- break;
- case 'Q':
- really_quiet = 1;
- break;
- case 'l':
- logoff = 1;
- break;
- case 't':
- trace = 1;
- break;
- default:
- goto error_return;
- }
-}
-
-/*
- * We must read data from a child process and send it across the
- * network. We do not want to block on writing to the network, so we
- * store the data from the child process in memory. A BUFFER
- * structure holds the status of one communication, and uses a linked
- * list of buffer_data structures to hold data.
- */
-
-struct buffer
-{
- /* Data. */
- struct buffer_data *data;
-
- /* Last buffer on data chain. */
- struct buffer_data *last;
-
- /* File descriptor to write to or read from. */
- int fd;
-
- /* Nonzero if this is an output buffer (sanity check). */
- int output;
-
- /* Nonzero if the file descriptor is in nonblocking mode. */
- int nonblocking;
-
- /* Function to call if we can't allocate memory. */
- void (*memory_error) PROTO((struct buffer *));
-};
-
-/* Data is stored in lists of these structures. */
-
-struct buffer_data
-{
- /* Next buffer in linked list. */
- struct buffer_data *next;
-
- /*
- * A pointer into the data area pointed to by the text field. This
- * is where to find data that has not yet been written out.
- */
- char *bufp;
-
- /* The number of data bytes found at BUFP. */
- int size;
-
- /*
- * Actual buffer. This never changes after the structure is
- * allocated. The buffer is BUFFER_DATA_SIZE bytes.
- */
- char *text;
-};
-
-/* The size we allocate for each buffer_data structure. */
-#define BUFFER_DATA_SIZE (4096)
-
-#ifdef SERVER_FLOWCONTROL
-/* The maximum we'll queue to the remote client before blocking. */
-# ifndef SERVER_HI_WATER
-# define SERVER_HI_WATER (2 * 1024 * 1024)
-# endif /* SERVER_HI_WATER */
-/* When the buffer drops to this, we restart the child */
-# ifndef SERVER_LO_WATER
-# define SERVER_LO_WATER (1 * 1024 * 1024)
-# endif /* SERVER_LO_WATER */
-#endif /* SERVER_FLOWCONTROL */
-
-/* Linked list of available buffer_data structures. */
-static struct buffer_data *free_buffer_data;
-
-static void allocate_buffer_datas PROTO((void));
-static inline struct buffer_data *get_buffer_data PROTO((void));
-static int buf_empty_p PROTO((struct buffer *));
-static void buf_output PROTO((struct buffer *, const char *, int));
-static void buf_output0 PROTO((struct buffer *, const char *));
-static inline void buf_append_char PROTO((struct buffer *, int));
-static int buf_send_output PROTO((struct buffer *));
-static int set_nonblock PROTO((struct buffer *));
-static int set_block PROTO((struct buffer *));
-static int buf_send_counted PROTO((struct buffer *));
-static inline void buf_append_data PROTO((struct buffer *,
- struct buffer_data *,
- struct buffer_data *));
-static int buf_read_file PROTO((FILE *, long, struct buffer_data **,
- struct buffer_data **));
-static int buf_input_data PROTO((struct buffer *, int *));
-static void buf_copy_lines PROTO((struct buffer *, struct buffer *, int));
-static int buf_copy_counted PROTO((struct buffer *, struct buffer *));
-
-#ifdef SERVER_FLOWCONTROL
-static int buf_count_mem PROTO((struct buffer *));
-static int set_nonblock_fd PROTO((int));
-#endif /* SERVER_FLOWCONTROL */
-
-/* Allocate more buffer_data structures. */
-
-static void
-allocate_buffer_datas ()
-{
- struct buffer_data *alc;
- char *space;
- int i;
-
- /* Allocate buffer_data structures in blocks of 16. */
-#define ALLOC_COUNT (16)
-
- alc = ((struct buffer_data *)
- malloc (ALLOC_COUNT * sizeof (struct buffer_data)));
- space = (char *) valloc (ALLOC_COUNT * BUFFER_DATA_SIZE);
- if (alc == NULL || space == NULL)
- return;
- for (i = 0; i < ALLOC_COUNT; i++, alc++, space += BUFFER_DATA_SIZE)
- {
- alc->next = free_buffer_data;
- free_buffer_data = alc;
- alc->text = space;
- }
-}
-
-/* Get a new buffer_data structure. */
-
-static inline struct buffer_data *
-get_buffer_data ()
-{
- struct buffer_data *ret;
-
- if (free_buffer_data == NULL)
- {
- allocate_buffer_datas ();
- if (free_buffer_data == NULL)
- return NULL;
- }
-
- ret = free_buffer_data;
- free_buffer_data = ret->next;
- return ret;
-}
-
-/* See whether a buffer is empty. */
-
-static int
-buf_empty_p (buf)
- struct buffer *buf;
-{
- struct buffer_data *data;
-
- for (data = buf->data; data != NULL; data = data->next)
- if (data->size > 0)
- return 0;
- return 1;
-}
-
-#ifdef SERVER_FLOWCONTROL
-/*
- * Count how much data is stored in the buffer..
- * Note that each buffer is a malloc'ed chunk BUFFER_DATA_SIZE.
- */
-
-static int
-buf_count_mem (buf)
- struct buffer *buf;
-{
- struct buffer_data *data;
- int mem = 0;
-
- for (data = buf->data; data != NULL; data = data->next)
- mem += BUFFER_DATA_SIZE;
-
- return mem;
-}
-#endif /* SERVER_FLOWCONTROL */
-
-/* Add data DATA of length LEN to BUF. */
-
-static void
-buf_output (buf, data, len)
- struct buffer *buf;
- const char *data;
- int len;
-{
- if (! buf->output)
- abort ();
-
- if (buf->data != NULL
- && (((buf->last->text + BUFFER_DATA_SIZE)
- - (buf->last->bufp + buf->last->size))
- >= len))
- {
- memcpy (buf->last->bufp + buf->last->size, data, len);
- buf->last->size += len;
- return;
- }
-
- while (1)
- {
- struct buffer_data *newdata;
-
- newdata = get_buffer_data ();
- if (newdata == NULL)
- {
- (*buf->memory_error) (buf);
- return;
- }
-
- if (buf->data == NULL)
- buf->data = newdata;
- else
- buf->last->next = newdata;
- newdata->next = NULL;
- buf->last = newdata;
-
- newdata->bufp = newdata->text;
-
- if (len <= BUFFER_DATA_SIZE)
- {
- newdata->size = len;
- memcpy (newdata->text, data, len);
- return;
- }
-
- newdata->size = BUFFER_DATA_SIZE;
- memcpy (newdata->text, data, BUFFER_DATA_SIZE);
-
- data += BUFFER_DATA_SIZE;
- len -= BUFFER_DATA_SIZE;
- }
-
- /*NOTREACHED*/
-}
-
-/* Add a '\0' terminated string to BUF. */
-
-static void
-buf_output0 (buf, string)
- struct buffer *buf;
- const char *string;
-{
- buf_output (buf, string, strlen (string));
-}
-
-/* Add a single character to BUF. */
-
-static inline void
-buf_append_char (buf, ch)
- struct buffer *buf;
- int ch;
-{
- if (buf->data != NULL
- && (buf->last->text + BUFFER_DATA_SIZE
- != buf->last->bufp + buf->last->size))
- {
- *(buf->last->bufp + buf->last->size) = ch;
- ++buf->last->size;
- }
- else
- {
- char b;
-
- b = ch;
- buf_output (buf, &b, 1);
- }
-}
-
-/*
- * Send all the output we've been saving up. Returns 0 for success or
- * errno code. If the buffer has been set to be nonblocking, this
- * will just write until the write would block.
- */
-
-static int
-buf_send_output (buf)
- struct buffer *buf;
-{
- if (! buf->output)
- abort ();
-
- while (buf->data != NULL)
- {
- struct buffer_data *data;
-
- data = buf->data;
- while (data->size > 0)
- {
- int nbytes;
-
- nbytes = write (buf->fd, data->bufp, data->size);
- if (nbytes <= 0)
- {
- int status;
-
- if (buf->nonblocking
- && (nbytes == 0
-#ifdef EWOULDBLOCK
- || errno == EWOULDBLOCK
-#endif
- || errno == EAGAIN))
- {
- /*
- * A nonblocking write failed to write any data.
- * Just return.
- */
- return 0;
- }
-
- /*
- * An error, or EOF. Throw away all the data and
- * return.
- */
- if (nbytes == 0)
- status = EIO;
- else
- status = errno;
-
- buf->last->next = free_buffer_data;
- free_buffer_data = buf->data;
- buf->data = NULL;
- buf->last = NULL;
-
- return status;
- }
-
- data->size -= nbytes;
- data->bufp += nbytes;
- }
-
- buf->data = data->next;
- data->next = free_buffer_data;
- free_buffer_data = data;
- }
-
- buf->last = NULL;
-
- return 0;
-}
-
-#ifdef SERVER_FLOWCONTROL
-/*
- * Set buffer BUF to non-blocking I/O. Returns 0 for success or errno
- * code.
- */
-
-static int
-set_nonblock_fd (fd)
- int fd;
-{
- int flags;
-
- flags = fcntl (fd, F_GETFL, 0);
- if (flags < 0)
- return errno;
- if (fcntl (fd, F_SETFL, flags | O_NONBLOCK) < 0)
- return errno;
- return 0;
-}
-#endif /* SERVER_FLOWCONTROL */
-
-static int
-set_nonblock (buf)
- struct buffer *buf;
-{
- int flags;
-
- if (buf->nonblocking)
- return 0;
- flags = fcntl (buf->fd, F_GETFL, 0);
- if (flags < 0)
- return errno;
- if (fcntl (buf->fd, F_SETFL, flags | O_NONBLOCK) < 0)
- return errno;
- buf->nonblocking = 1;
- return 0;
-}
-
-/*
- * Set buffer BUF to blocking I/O. Returns 0 for success or errno
- * code.
- */
-
-static int
-set_block (buf)
- struct buffer *buf;
-{
- int flags;
-
- if (! buf->nonblocking)
- return 0;
- flags = fcntl (buf->fd, F_GETFL, 0);
- if (flags < 0)
- return errno;
- if (fcntl (buf->fd, F_SETFL, flags & ~O_NONBLOCK) < 0)
- return errno;
- buf->nonblocking = 0;
- return 0;
-}
-
-/*
- * Send a character count and some output. Returns errno code or 0 for
- * success.
- *
- * Sending the count in binary is OK since this is only used on a pipe
- * within the same system.
- */
-
-static int
-buf_send_counted (buf)
- struct buffer *buf;
-{
- int size;
- struct buffer_data *data;
-
- if (! buf->output)
- abort ();
-
- size = 0;
- for (data = buf->data; data != NULL; data = data->next)
- size += data->size;
-
- data = get_buffer_data ();
- if (data == NULL)
- {
- (*buf->memory_error) (buf);
- return ENOMEM;
- }
-
- data->next = buf->data;
- buf->data = data;
- if (buf->last == NULL)
- buf->last = data;
-
- data->bufp = data->text;
- data->size = sizeof (int);
-
- *((int *) data->text) = size;
-
- return buf_send_output (buf);
-}
-
-/* Append a list of buffer_data structures to an buffer. */
-
-static inline void
-buf_append_data (buf, data, last)
- struct buffer *buf;
- struct buffer_data *data;
- struct buffer_data *last;
-{
- if (data != NULL)
- {
- if (buf->data == NULL)
- buf->data = data;
- else
- buf->last->next = data;
- buf->last = last;
- }
-}
-
-/*
- * Copy the contents of file F into buffer_data structures. We can't
- * copy directly into an buffer, because we want to handle failure and
- * succeess differently. Returns 0 on success, or -2 if out of
- * memory, or a status code on error. Since the caller happens to
- * know the size of the file, it is passed in as SIZE. On success,
- * this function sets *RETP and *LASTP, which may be passed to
- * buf_append_data.
- */
-
-static int
-buf_read_file (f, size, retp, lastp)
- FILE *f;
- long size;
- struct buffer_data **retp;
- struct buffer_data **lastp;
-{
- int status;
-
- *retp = NULL;
- *lastp = NULL;
-
- while (size > 0)
- {
- struct buffer_data *data;
- int get;
-
- data = get_buffer_data ();
- if (data == NULL)
- {
- status = -2;
- goto error_return;
- }
-
- if (*retp == NULL)
- *retp = data;
- else
- (*lastp)->next = data;
- data->next = NULL;
- *lastp = data;
-
- data->bufp = data->text;
- data->size = 0;
-
- if (size > BUFFER_DATA_SIZE)
- get = BUFFER_DATA_SIZE;
- else
- get = size;
-
- errno = EIO;
- if (fread (data->text, get, 1, f) != 1)
- {
- status = errno;
- goto error_return;
- }
-
- data->size += get;
- size -= get;
- }
-
- return 0;
-
- error_return:
- if (*retp != NULL)
- {
- (*lastp)->next = free_buffer_data;
- free_buffer_data = *retp;
- }
- return status;
-}
-
-static int
-buf_read_file_to_eof (f, retp, lastp)
- FILE *f;
- struct buffer_data **retp;
- struct buffer_data **lastp;
-{
- int status;
-
- *retp = NULL;
- *lastp = NULL;
-
- while (!feof (f))
- {
- struct buffer_data *data;
- int get, nread;
-
- data = get_buffer_data ();
- if (data == NULL)
- {
- status = -2;
- goto error_return;
- }
-
- if (*retp == NULL)
- *retp = data;
- else
- (*lastp)->next = data;
- data->next = NULL;
- *lastp = data;
-
- data->bufp = data->text;
- data->size = 0;
-
- get = BUFFER_DATA_SIZE;
-
- errno = EIO;
- nread = fread (data->text, 1, get, f);
- if (nread == 0 && !feof (f))
- {
- status = errno;
- goto error_return;
- }
-
- data->size = nread;
- }
-
- return 0;
-
- error_return:
- if (*retp != NULL)
- {
- (*lastp)->next = free_buffer_data;
- free_buffer_data = *retp;
- }
- return status;
-}
-
-static int
-buf_chain_length (buf)
- struct buffer_data *buf;
-{
- int size = 0;
- while (buf)
- {
- size += buf->size;
- buf = buf->next;
- }
- return size;
-}
-
-/*
- * Read an arbitrary amount of data from a file descriptor into an
- * input buffer. The file descriptor will be in nonblocking mode, and
- * we just grab what we can. Return 0 on success, or -1 on end of
- * file, or -2 if out of memory, or an error code. If COUNTP is not
- * NULL, *COUNTP is set to the number of bytes read.
- */
-
-static int
-buf_input_data (buf, countp)
- struct buffer *buf;
- int *countp;
-{
- if (buf->output)
- abort ();
-
- if (countp != NULL)
- *countp = 0;
-
- while (1)
- {
- int get;
- int nbytes;
-
- if (buf->data == NULL
- || (buf->last->bufp + buf->last->size
- == buf->last->text + BUFFER_DATA_SIZE))
- {
- struct buffer_data *data;
-
- data = get_buffer_data ();
- if (data == NULL)
- {
- (*buf->memory_error) (buf);
- return -2;
- }
-
- if (buf->data == NULL)
- buf->data = data;
- else
- buf->last->next = data;
- data->next = NULL;
- buf->last = data;
-
- data->bufp = data->text;
- data->size = 0;
- }
-
- get = ((buf->last->text + BUFFER_DATA_SIZE)
- - (buf->last->bufp + buf->last->size));
- nbytes = read (buf->fd, buf->last->bufp + buf->last->size, get);
- if (nbytes <= 0)
- {
- if (nbytes == 0)
- {
- /*
- * This assumes that we are using POSIX or BSD style
- * nonblocking I/O. On System V we will get a zero
- * return if there is no data, even when not at EOF.
- */
- return -1;
- }
-
- if (errno == EAGAIN
-#ifdef EWOULDBLOCK
- || errno == EWOULDBLOCK
-#endif
- )
- return 0;
-
- return errno;
- }
-
- buf->last->size += nbytes;
- if (countp != NULL)
- *countp += nbytes;
- }
-
- /*NOTREACHED*/
-}
-
-/*
- * Copy lines from an input buffer to an output buffer. This copies
- * all complete lines (characters up to a newline) from INBUF to
- * OUTBUF. Each line in OUTBUF is preceded by the character COMMAND
- * and a space.
- */
-
-static void
-buf_copy_lines (outbuf, inbuf, command)
- struct buffer *outbuf;
- struct buffer *inbuf;
- int command;
-{
- if (! outbuf->output || inbuf->output)
- abort ();
-
- while (1)
- {
- struct buffer_data *data;
- struct buffer_data *nldata;
- char *nl;
- int len;
-
- /* See if there is a newline in INBUF. */
- nldata = NULL;
- nl = NULL;
- for (data = inbuf->data; data != NULL; data = data->next)
- {
- nl = memchr (data->bufp, '\n', data->size);
- if (nl != NULL)
- {
- nldata = data;
- break;
- }
- }
-
- if (nldata == NULL)
- {
- /* There are no more lines in INBUF. */
- return;
- }
-
- /* Put in the command. */
- buf_append_char (outbuf, command);
- buf_append_char (outbuf, ' ');
-
- if (inbuf->data != nldata)
- {
- /*
- * Simply move over all the buffers up to the one containing
- * the newline.
- */
- for (data = inbuf->data; data->next != nldata; data = data->next)
- ;
- data->next = NULL;
- buf_append_data (outbuf, inbuf->data, data);
- inbuf->data = nldata;
- }
-
- /*
- * If the newline is at the very end of the buffer, just move
- * the buffer onto OUTBUF. Otherwise we must copy the data.
- */
- len = nl + 1 - nldata->bufp;
- if (len == nldata->size)
- {
- inbuf->data = nldata->next;
- if (inbuf->data == NULL)
- inbuf->last = NULL;
-
- nldata->next = NULL;
- buf_append_data (outbuf, nldata, nldata);
- }
- else
- {
- buf_output (outbuf, nldata->bufp, len);
- nldata->bufp += len;
- nldata->size -= len;
- }
- }
-}
-
-/*
- * Copy counted data from one buffer to another. The count is an
- * integer, host size, host byte order (it is only used across a
- * pipe). If there is enough data, it should be moved over. If there
- * is not enough data, it should remain on the original buffer. This
- * returns the number of bytes it needs to see in order to actually
- * copy something over.
- */
-
-static int
-buf_copy_counted (outbuf, inbuf)
- struct buffer *outbuf;
- struct buffer *inbuf;
-{
- if (! outbuf->output || inbuf->output)
- abort ();
-
- while (1)
- {
- struct buffer_data *data;
- int need;
- union
- {
- char intbuf[sizeof (int)];
- int i;
- } u;
- char *intp;
- int count;
- struct buffer_data *start;
- int startoff;
- struct buffer_data *stop;
- int stopwant;
-
- /* See if we have enough bytes to figure out the count. */
- need = sizeof (int);
- intp = u.intbuf;
- for (data = inbuf->data; data != NULL; data = data->next)
- {
- if (data->size >= need)
- {
- memcpy (intp, data->bufp, need);
- break;
- }
- memcpy (intp, data->bufp, data->size);
- intp += data->size;
- need -= data->size;
- }
- if (data == NULL)
- {
- /* We don't have enough bytes to form an integer. */
- return need;
- }
-
- count = u.i;
- start = data;
- startoff = need;
-
- /*
- * We have an integer in COUNT. We have gotten all the data
- * from INBUF in all buffers before START, and we have gotten
- * STARTOFF bytes from START. See if we have enough bytes
- * remaining in INBUF.
- */
- need = count - (start->size - startoff);
- if (need <= 0)
- {
- stop = start;
- stopwant = count;
- }
- else
- {
- for (data = start->next; data != NULL; data = data->next)
- {
- if (need <= data->size)
- break;
- need -= data->size;
- }
- if (data == NULL)
- {
- /* We don't have enough bytes. */
- return need;
- }
- stop = data;
- stopwant = need;
- }
-
- /*
- * We have enough bytes. Free any buffers in INBUF before
- * START, and remove STARTOFF bytes from START, so that we can
- * forget about STARTOFF.
- */
- start->bufp += startoff;
- start->size -= startoff;
-
- if (start->size == 0)
- start = start->next;
-
- if (stop->size == stopwant)
- {
- stop = stop->next;
- stopwant = 0;
- }
-
- while (inbuf->data != start)
- {
- data = inbuf->data;
- inbuf->data = data->next;
- data->next = free_buffer_data;
- free_buffer_data = data;
- }
-
- /*
- * We want to copy over the bytes from START through STOP. We
- * only want STOPWANT bytes from STOP.
- */
-
- if (start != stop)
- {
- /* Attach the buffers from START through STOP to OUTBUF. */
- for (data = start; data->next != stop; data = data->next)
- ;
- inbuf->data = stop;
- data->next = NULL;
- buf_append_data (outbuf, start, data);
- }
-
- if (stopwant > 0)
- {
- buf_output (outbuf, stop->bufp, stopwant);
- stop->bufp += stopwant;
- stop->size -= stopwant;
- }
- }
-
- /*NOTREACHED*/
-}
-
-static struct buffer protocol;
-
-static void
-protocol_memory_error (buf)
- struct buffer *buf;
-{
- error (1, ENOMEM, "Virtual memory exhausted");
-}
-
-/*
- * Process IDs of the subprocess, or negative if that subprocess
- * does not exist.
- */
-static pid_t command_pid;
-
-static void
-outbuf_memory_error (buf)
- struct buffer *buf;
-{
- static const char msg[] = "E Fatal server error\n\
-error ENOMEM Virtual memory exhausted.\n";
- if (command_pid > 0)
- kill (command_pid, SIGTERM);
-
- /*
- * We have arranged things so that printing this now either will
- * be legal, or the "E fatal error" line will get glommed onto the
- * end of an existing "E" or "M" response.
- */
-
- /* If this gives an error, not much we could do. syslog() it? */
- write (STDOUT_FILENO, msg, sizeof (msg) - 1);
- server_cleanup (0);
- exit (1);
-}
-
-static void
-input_memory_error (buf)
- struct buffer *buf;
-{
- outbuf_memory_error (buf);
-}
-
-/* Execute COMMAND in a subprocess with the approriate funky things done. */
-
-static struct fd_set_wrapper { fd_set fds; } command_fds_to_drain;
-static int max_command_fd;
-
-#ifdef SERVER_FLOWCONTROL
-static int flowcontrol_pipe[2];
-#endif /* SERVER_FLOWCONTROL */
-
-static void
-do_cvs_command (command)
- int (*command) PROTO((int argc, char **argv));
-{
- /*
- * The following file descriptors are set to -1 if that file is not
- * currently open.
- */
-
- /* Data on these pipes is a series of '\n'-terminated lines. */
- int stdout_pipe[2];
- int stderr_pipe[2];
-
- /*
- * Data on this pipe is a series of counted (see buf_send_counted)
- * packets. Each packet must be processed atomically (i.e. not
- * interleaved with data from stdout_pipe or stderr_pipe).
- */
- int protocol_pipe[2];
-
- int dev_null_fd = -1;
-
- int errs;
-
- command_pid = -1;
- stdout_pipe[0] = -1;
- stdout_pipe[1] = -1;
- stderr_pipe[0] = -1;
- stderr_pipe[1] = -1;
- protocol_pipe[0] = -1;
- protocol_pipe[1] = -1;
-
- server_write_entries ();
-
- if (print_pending_error ())
- goto free_args_and_return;
-
- /*
- * We use a child process which actually does the operation. This
- * is so we can intercept its standard output. Even if all of CVS
- * were written to go to some special routine instead of writing
- * to stdout or stderr, we would still need to do the same thing
- * for the RCS commands.
- */
-
- if (pipe (stdout_pipe) < 0)
- {
- print_error (errno);
- goto error_exit;
- }
- if (pipe (stderr_pipe) < 0)
- {
- print_error (errno);
- goto error_exit;
- }
- if (pipe (protocol_pipe) < 0)
- {
- print_error (errno);
- goto error_exit;
- }
-#ifdef SERVER_FLOWCONTROL
- if (pipe (flowcontrol_pipe) < 0)
- {
- print_error (errno);
- goto error_exit;
- }
- set_nonblock_fd (flowcontrol_pipe[0]);
- set_nonblock_fd (flowcontrol_pipe[1]);
-#endif /* SERVER_FLOWCONTROL */
-
- dev_null_fd = open ("/dev/null", O_RDONLY);
- if (dev_null_fd < 0)
- {
- print_error (errno);
- goto error_exit;
- }
-
- /* Don't use vfork; we're not going to exec(). */
- command_pid = fork ();
- if (command_pid < 0)
- {
- print_error (errno);
- goto error_exit;
- }
- if (command_pid == 0)
- {
- int exitstatus;
-
- /* Since we're in the child, and the parent is going to take
- care of packaging up our error messages, we can clear this
- flag. */
- error_use_protocol = 0;
-
- protocol.data = protocol.last = NULL;
- protocol.fd = protocol_pipe[1];
- protocol.output = 1;
- protocol.nonblocking = 0;
- protocol.memory_error = protocol_memory_error;
-
- if (dup2 (dev_null_fd, STDIN_FILENO) < 0)
- error (1, errno, "can't set up pipes");
- if (dup2 (stdout_pipe[1], STDOUT_FILENO) < 0)
- error (1, errno, "can't set up pipes");
- if (dup2 (stderr_pipe[1], STDERR_FILENO) < 0)
- error (1, errno, "can't set up pipes");
- close (stdout_pipe[0]);
- close (stderr_pipe[0]);
- close (protocol_pipe[0]);
-#ifdef SERVER_FLOWCONTROL
- close (flowcontrol_pipe[1]);
-#endif /* SERVER_FLOWCONTROL */
-
- /*
- * Set this in .bashrc if you want to give yourself time to attach
- * to the subprocess with a debugger.
- */
- if (getenv ("CVS_SERVER_SLEEP"))
- {
- int secs = atoi (getenv ("CVS_SERVER_SLEEP"));
- sleep (secs);
- }
-
- exitstatus = (*command) (argument_count, argument_vector);
-
- /*
- * When we exit, that will close the pipes, giving an EOF to
- * the parent.
- */
- exit (exitstatus);
- }
-
- /* OK, sit around getting all the input from the child. */
- {
- struct buffer outbuf;
- struct buffer stdoutbuf;
- struct buffer stderrbuf;
- struct buffer protocol_inbuf;
- /* Number of file descriptors to check in select (). */
- int num_to_check;
- int count_needed = 0;
-#ifdef SERVER_FLOWCONTROL
- int have_flowcontrolled = 0;
-#endif /* SERVER_FLOWCONTROL */
-
- FD_ZERO (&command_fds_to_drain.fds);
- num_to_check = stdout_pipe[0];
- FD_SET (stdout_pipe[0], &command_fds_to_drain.fds);
- if (stderr_pipe[0] > num_to_check)
- num_to_check = stderr_pipe[0];
- FD_SET (stderr_pipe[0], &command_fds_to_drain.fds);
- if (protocol_pipe[0] > num_to_check)
- num_to_check = protocol_pipe[0];
- FD_SET (protocol_pipe[0], &command_fds_to_drain.fds);
- if (STDOUT_FILENO > num_to_check)
- num_to_check = STDOUT_FILENO;
- max_command_fd = num_to_check;
- /*
- * File descriptors are numbered from 0, so num_to_check needs to
- * be one larger than the largest descriptor.
- */
- ++num_to_check;
- if (num_to_check > FD_SETSIZE)
- {
- printf ("E internal error: FD_SETSIZE not big enough.\nerror \n");
- goto error_exit;
- }
-
- outbuf.data = outbuf.last = NULL;
- outbuf.fd = STDOUT_FILENO;
- outbuf.output = 1;
- outbuf.nonblocking = 0;
- outbuf.memory_error = outbuf_memory_error;
-
- stdoutbuf.data = stdoutbuf.last = NULL;
- stdoutbuf.fd = stdout_pipe[0];
- stdoutbuf.output = 0;
- stdoutbuf.nonblocking = 0;
- stdoutbuf.memory_error = input_memory_error;
-
- stderrbuf.data = stderrbuf.last = NULL;
- stderrbuf.fd = stderr_pipe[0];
- stderrbuf.output = 0;
- stderrbuf.nonblocking = 0;
- stderrbuf.memory_error = input_memory_error;
-
- protocol_inbuf.data = protocol_inbuf.last = NULL;
- protocol_inbuf.fd = protocol_pipe[0];
- protocol_inbuf.output = 0;
- protocol_inbuf.nonblocking = 0;
- protocol_inbuf.memory_error = input_memory_error;
-
- set_nonblock (&outbuf);
- set_nonblock (&stdoutbuf);
- set_nonblock (&stderrbuf);
- set_nonblock (&protocol_inbuf);
-
- if (close (stdout_pipe[1]) < 0)
- {
- print_error (errno);
- goto error_exit;
- }
- stdout_pipe[1] = -1;
-
- if (close (stderr_pipe[1]) < 0)
- {
- print_error (errno);
- goto error_exit;
- }
- stderr_pipe[1] = -1;
-
- if (close (protocol_pipe[1]) < 0)
- {
- print_error (errno);
- goto error_exit;
- }
- protocol_pipe[1] = -1;
-
-#ifdef SERVER_FLOWCONTROL
- if (close (flowcontrol_pipe[0]) < 0)
- {
- print_error (errno);
- goto error_exit;
- }
- flowcontrol_pipe[0] = -1;
-#endif /* SERVER_FLOWCONTROL */
-
- if (close (dev_null_fd) < 0)
- {
- print_error (errno);
- goto error_exit;
- }
- dev_null_fd = -1;
-
- while (stdout_pipe[0] >= 0
- || stderr_pipe[0] >= 0
- || protocol_pipe[0] >= 0)
- {
- fd_set readfds;
- fd_set writefds;
- int numfds;
-#ifdef SERVER_FLOWCONTROL
- int bufmemsize;
-
- /*
- * See if we are swamping the remote client and filling our VM.
- * Tell child to hold off if we do.
- */
- bufmemsize = buf_count_mem (&outbuf);
- if (!have_flowcontrolled && (bufmemsize > SERVER_HI_WATER))
- {
- if (write(flowcontrol_pipe[1], "S", 1) == 1)
- have_flowcontrolled = 1;
- }
- else if (have_flowcontrolled && (bufmemsize < SERVER_LO_WATER))
- {
- if (write(flowcontrol_pipe[1], "G", 1) == 1)
- have_flowcontrolled = 0;
- }
-#endif /* SERVER_FLOWCONTROL */
-
- FD_ZERO (&readfds);
- FD_ZERO (&writefds);
- if (! buf_empty_p (&outbuf))
- FD_SET (STDOUT_FILENO, &writefds);
-
- if (stdout_pipe[0] >= 0)
- {
- FD_SET (stdout_pipe[0], &readfds);
- }
- if (stderr_pipe[0] >= 0)
- {
- FD_SET (stderr_pipe[0], &readfds);
- }
- if (protocol_pipe[0] >= 0)
- {
- FD_SET (protocol_pipe[0], &readfds);
- }
-
- do {
- /* This used to select on exceptions too, but as far
- as I know there was never any reason to do that and
- SCO doesn't let you select on exceptions on pipes. */
- numfds = select (num_to_check, &readfds, &writefds,
- (fd_set *)0, (struct timeval *)NULL);
- if (numfds < 0
- && errno != EINTR)
- {
- print_error (errno);
- goto error_exit;
- }
- } while (numfds < 0);
-
- if (FD_ISSET (STDOUT_FILENO, &writefds))
- {
- /* What should we do with errors? syslog() them? */
- buf_send_output (&outbuf);
- }
-
- if (stdout_pipe[0] >= 0
- && (FD_ISSET (stdout_pipe[0], &readfds)))
- {
- int status;
-
- status = buf_input_data (&stdoutbuf, (int *) NULL);
-
- buf_copy_lines (&outbuf, &stdoutbuf, 'M');
-
- if (status == -1)
- stdout_pipe[0] = -1;
- else if (status > 0)
- {
- print_error (status);
- goto error_exit;
- }
-
- /* What should we do with errors? syslog() them? */
- buf_send_output (&outbuf);
- }
-
- if (stderr_pipe[0] >= 0
- && (FD_ISSET (stderr_pipe[0], &readfds)))
- {
- int status;
-
- status = buf_input_data (&stderrbuf, (int *) NULL);
-
- buf_copy_lines (&outbuf, &stderrbuf, 'E');
-
- if (status == -1)
- stderr_pipe[0] = -1;
- else if (status > 0)
- {
- print_error (status);
- goto error_exit;
- }
-
- /* What should we do with errors? syslog() them? */
- buf_send_output (&outbuf);
- }
-
- if (protocol_pipe[0] >= 0
- && (FD_ISSET (protocol_pipe[0], &readfds)))
- {
- int status;
- int count_read;
-
- status = buf_input_data (&protocol_inbuf, &count_read);
-
- /*
- * We only call buf_copy_counted if we have read
- * enough bytes to make it worthwhile. This saves us
- * from continually recounting the amount of data we
- * have.
- */
- count_needed -= count_read;
- if (count_needed <= 0)
- count_needed = buf_copy_counted (&outbuf, &protocol_inbuf);
-
- if (status == -1)
- protocol_pipe[0] = -1;
- else if (status > 0)
- {
- print_error (status);
- goto error_exit;
- }
-
- /* What should we do with errors? syslog() them? */
- buf_send_output (&outbuf);
- }
- }
-
- /*
- * OK, we've gotten EOF on all the pipes. If there is
- * anything left on stdoutbuf or stderrbuf (this could only
- * happen if there was no trailing newline), send it over.
- */
- if (! buf_empty_p (&stdoutbuf))
- {
- buf_append_char (&stdoutbuf, '\n');
- buf_copy_lines (&outbuf, &stdoutbuf, 'M');
- }
- if (! buf_empty_p (&stderrbuf))
- {
- buf_append_char (&stderrbuf, '\n');
- buf_copy_lines (&outbuf, &stderrbuf, 'E');
- }
- if (! buf_empty_p (&protocol_inbuf))
- buf_output0 (&outbuf,
- "E Protocol error: uncounted data discarded\n");
-
- errs = 0;
-
- while (command_pid > 0)
- {
- int status;
- pid_t waited_pid;
- waited_pid = waitpid (command_pid, &status, 0);
- if (waited_pid < 0)
- {
- /*
- * Intentionally ignoring EINTR. Other errors
- * "can't happen".
- */
- continue;
- }
-
- if (WIFEXITED (status))
- errs += WEXITSTATUS (status);
- else
- {
- int sig = WTERMSIG (status);
- /*
- * This is really evil, because signals might be numbered
- * differently on the two systems. We should be using
- * signal names (either of the "Terminated" or the "SIGTERM"
- * variety). But cvs doesn't currently use libiberty...we
- * could roll our own.... FIXME.
- */
- printf ("E Terminated with fatal signal %d\n", sig);
-
- /* Test for a core dump. Is this portable? */
- if (status & 0x80)
- {
- printf ("E Core dumped; preserving %s on server.\n\
-E CVS locks may need cleaning up.\n",
- server_temp_dir);
- dont_delete_temp = 1;
- }
- ++errs;
- }
- if (waited_pid == command_pid)
- command_pid = -1;
- }
-
- /*
- * OK, we've waited for the child. By now all CVS locks are free
- * and it's OK to block on the network.
- */
- set_block (&outbuf);
- buf_send_output (&outbuf);
- }
-
- if (errs)
- /* We will have printed an error message already. */
- printf ("error \n");
- else
- printf ("ok\n");
- goto free_args_and_return;
-
- error_exit:
- if (command_pid > 0)
- kill (command_pid, SIGTERM);
-
- while (command_pid > 0)
- {
- pid_t waited_pid;
- waited_pid = waitpid (command_pid, (int *) 0, 0);
- if (waited_pid < 0 && errno == EINTR)
- continue;
- if (waited_pid == command_pid)
- command_pid = -1;
- }
-
- close (dev_null_fd);
- close (protocol_pipe[0]);
- close (protocol_pipe[1]);
- close (stderr_pipe[0]);
- close (stderr_pipe[1]);
- close (stdout_pipe[0]);
- close (stdout_pipe[1]);
-
- free_args_and_return:
- /* Now free the arguments. */
- {
- /* argument_vector[0] is a dummy argument, we don't mess with it. */
- char **cp;
- for (cp = argument_vector + 1;
- cp < argument_vector + argument_count;
- ++cp)
- free (*cp);
-
- argument_count = 1;
- }
- return;
-}
-
-#ifdef SERVER_FLOWCONTROL
-/*
- * Called by the child at convenient points in the server's execution for
- * the server child to block.. ie: when it has no locks active.
- */
-void
-server_pause_check()
-{
- int paused = 0;
- char buf[1];
-
- while (read (flowcontrol_pipe[0], buf, 1) == 1)
- {
- if (*buf == 'S') /* Stop */
- paused = 1;
- else if (*buf == 'G') /* Go */
- paused = 0;
- else
- return; /* ??? */
- }
- while (paused) {
- int numfds, numtocheck;
- fd_set fds;
-
- FD_ZERO (&fds);
- FD_SET (flowcontrol_pipe[0], &fds);
- numtocheck = flowcontrol_pipe[0] + 1;
-
- do {
- numfds = select (numtocheck, &fds, (fd_set *)0,
- (fd_set *)0, (struct timeval *)NULL);
- if (numfds < 0
- && errno != EINTR)
- {
- print_error (errno);
- return;
- }
- } while (numfds < 0);
-
- if (FD_ISSET (flowcontrol_pipe[0], &fds))
- {
- while (read (flowcontrol_pipe[0], buf, 1) == 1)
- {
- if (*buf == 'S') /* Stop */
- paused = 1;
- else if (*buf == 'G') /* Go */
- paused = 0;
- else
- return; /* ??? */
- }
- }
- }
-}
-#endif /* SERVER_FLOWCONTROL */
-
-static void output_dir PROTO((char *, char *));
-
-static void
-output_dir (update_dir, repository)
- char *update_dir;
- char *repository;
-{
- if (use_dir_and_repos)
- {
- if (update_dir[0] == '\0')
- buf_output0 (&protocol, ".");
- else
- buf_output0 (&protocol, update_dir);
- buf_output0 (&protocol, "/\n");
- }
- buf_output0 (&protocol, repository);
- buf_output0 (&protocol, "/");
-}
-
-/*
- * Entries line that we are squirreling away to send to the client when
- * we are ready.
- */
-static char *entries_line;
-
-/*
- * File which has been Scratch_File'd, we are squirreling away that fact
- * to inform the client when we are ready.
- */
-static char *scratched_file;
-
-/*
- * The scratched_file will need to be removed as well as having its entry
- * removed.
- */
-static int kill_scratched_file;
-
-void
-server_register (name, version, timestamp, options, tag, date, conflict)
- char *name;
- char *version;
- char *timestamp;
- char *options;
- char *tag;
- char *date;
- char *conflict;
-{
- int len;
-
- if (trace)
- {
- (void) fprintf (stderr,
- "%c-> server_register(%s, %s, %s, %s, %s, %s, %s)\n",
- (server_active) ? 'S' : ' ', /* silly */
- name, version, timestamp, options, tag ? tag : "",
- date ? date : "", conflict ? conflict : "");
- }
-
- if (options == NULL)
- options = "";
-
- if (entries_line != NULL)
- {
- /*
- * If CVS decides to Register it more than once (which happens
- * on "cvs update foo/foo.c" where foo and foo.c are already
- * checked out), use the last of the entries lines Register'd.
- */
- free (entries_line);
- }
-
- /*
- * I have reports of Scratch_Entry and Register both happening, in
- * two different cases. Using the last one which happens is almost
- * surely correct; I haven't tracked down why they both happen (or
- * even verified that they are for the same file).
- */
- if (scratched_file != NULL)
- {
- free (scratched_file);
- scratched_file = NULL;
- }
-
- len = (strlen (name) + strlen (version) + strlen (options) + 80);
- if (tag)
- len += strlen (tag);
- if (date)
- len += strlen (date);
-
- entries_line = xmalloc (len);
- sprintf (entries_line, "/%s/%s/", name, version);
- if (conflict != NULL)
- {
- strcat (entries_line, "+=");
- }
- strcat (entries_line, "/");
- strcat (entries_line, options);
- strcat (entries_line, "/");
- if (tag != NULL)
- {
- strcat (entries_line, "T");
- strcat (entries_line, tag);
- }
- else if (date != NULL)
- {
- strcat (entries_line, "D");
- strcat (entries_line, date);
- }
-}
-
-void
-server_scratch (fname)
- char *fname;
-{
- /*
- * I have reports of Scratch_Entry and Register both happening, in
- * two different cases. Using the last one which happens is almost
- * surely correct; I haven't tracked down why they both happen (or
- * even verified that they are for the same file).
- */
- if (entries_line != NULL)
- {
- free (entries_line);
- entries_line = NULL;
- }
-
- if (scratched_file != NULL)
- {
- buf_output0 (&protocol,
- "E CVS server internal error: duplicate Scratch_Entry\n");
- buf_send_counted (&protocol);
- return;
- }
- scratched_file = xstrdup (fname);
- kill_scratched_file = 1;
-}
-
-void
-server_scratch_entry_only ()
-{
- kill_scratched_file = 0;
-}
-
-/* Print a new entries line, from a previous server_register. */
-static void
-new_entries_line ()
-{
- if (entries_line)
- {
- buf_output0 (&protocol, entries_line);
- buf_output (&protocol, "\n", 1);
- }
- else
- /* Return the error message as the Entries line. */
- buf_output0 (&protocol,
- "CVS server internal error: Register missing\n");
- free (entries_line);
- entries_line = NULL;
-}
-
-static void
-serve_ci (arg)
- char *arg;
-{
- do_cvs_command (commit);
-}
-
-void
-server_checked_in (file, update_dir, repository)
- char *file;
- char *update_dir;
- char *repository;
-{
- if (noexec)
- return;
- if (scratched_file != NULL && entries_line == NULL)
- {
- /*
- * This happens if we are now doing a "cvs remove" after a previous
- * "cvs add" (without a "cvs ci" in between).
- */
- buf_output0 (&protocol, "Remove-entry ");
- output_dir (update_dir, repository);
- buf_output0 (&protocol, file);
- buf_output (&protocol, "\n", 1);
- free (scratched_file);
- scratched_file = NULL;
- }
- else
- {
- buf_output0 (&protocol, "Checked-in ");
- output_dir (update_dir, repository);
- buf_output0 (&protocol, file);
- buf_output (&protocol, "\n", 1);
- new_entries_line ();
- }
- buf_send_counted (&protocol);
-}
-
-void
-server_update_entries (file, update_dir, repository, updated)
- char *file;
- char *update_dir;
- char *repository;
- enum server_updated_arg4 updated;
-{
- if (noexec)
- return;
- if (updated == SERVER_UPDATED)
- buf_output0 (&protocol, "Checked-in ");
- else
- {
- if (!supported_response ("New-entry"))
- return;
- buf_output0 (&protocol, "New-entry ");
- }
-
- output_dir (update_dir, repository);
- buf_output0 (&protocol, file);
- buf_output (&protocol, "\n", 1);
- new_entries_line ();
- buf_send_counted (&protocol);
-}
-
-static void
-serve_update (arg)
- char *arg;
-{
- do_cvs_command (update);
-}
-
-static void
-serve_diff (arg)
- char *arg;
-{
- do_cvs_command (diff);
-}
-
-static void
-serve_log (arg)
- char *arg;
-{
- do_cvs_command (cvslog);
-}
-
-static void
-serve_add (arg)
- char *arg;
-{
- do_cvs_command (add);
-}
-
-static void
-serve_remove (arg)
- char *arg;
-{
- do_cvs_command (cvsremove);
-}
-
-static void
-serve_status (arg)
- char *arg;
-{
- do_cvs_command (status);
-}
-
-static void
-serve_rdiff (arg)
- char *arg;
-{
- do_cvs_command (patch);
-}
-
-static void
-serve_tag (arg)
- char *arg;
-{
- do_cvs_command (tag);
-}
-
-static void
-serve_rtag (arg)
- char *arg;
-{
- do_cvs_command (rtag);
-}
-
-static void
-serve_import (arg)
- char *arg;
-{
- do_cvs_command (import);
-}
-
-static void
-serve_admin (arg)
- char *arg;
-{
- do_cvs_command (admin);
-}
-
-static void
-serve_history (arg)
- char *arg;
-{
- do_cvs_command (history);
-}
-
-static void
-serve_release (arg)
- char *arg;
-{
- do_cvs_command (release);
-}
-
-static void
-serve_co (arg)
- char *arg;
-{
- char *tempdir;
- int status;
-
- if (print_pending_error ())
- return;
-
- if (!isdir (CVSADM))
- {
- /*
- * The client has not sent a "Repository" line. Check out
- * into a pristine directory.
- */
- tempdir = malloc (strlen (server_temp_dir) + 80);
- if (tempdir == NULL)
- {
- printf ("E Out of memory\n");
- return;
- }
- strcpy (tempdir, server_temp_dir);
- strcat (tempdir, "/checkout-dir");
- status = mkdir_p (tempdir);
- if (status != 0 && status != EEXIST)
- {
- printf ("E Cannot create %s\n", tempdir);
- print_error (errno);
- free (tempdir);
- return;
- }
-
- if (chdir (tempdir) < 0)
- {
- printf ("E Cannot change to directory %s\n", tempdir);
- print_error (errno);
- free (tempdir);
- return;
- }
- free (tempdir);
- }
- do_cvs_command (checkout);
-}
-
-static void
-serve_export (arg)
- char *arg;
-{
- /* Tell checkout() to behave like export not checkout. */
- command_name = "export";
- serve_co (arg);
-}
-
-void
-server_copy_file (file, update_dir, repository, newfile)
- char *file;
- char *update_dir;
- char *repository;
- char *newfile;
-{
- if (!supported_response ("Copy-file"))
- return;
- buf_output0 (&protocol, "Copy-file ");
- output_dir (update_dir, repository);
- buf_output0 (&protocol, file);
- buf_output0 (&protocol, "\n");
- buf_output0 (&protocol, newfile);
- buf_output0 (&protocol, "\n");
-}
-
-void
-server_updated (file, update_dir, repository, updated, file_info, checksum)
- char *file;
- char *update_dir;
- char *repository;
- enum server_updated_arg4 updated;
- struct stat *file_info;
- unsigned char *checksum;
-{
- char *short_pathname;
-
- if (noexec)
- return;
-
- short_pathname = xmalloc (strlen (update_dir) + strlen (file) + 10);
- if (update_dir[0] == '\0')
- strcpy (short_pathname, file);
- else
- sprintf (short_pathname, "%s/%s", update_dir, file);
-
- if (entries_line != NULL && scratched_file == NULL)
- {
- FILE *f;
- struct stat sb;
- struct buffer_data *list, *last;
- unsigned long size;
- char size_text[80];
-
- if (stat (file, &sb) < 0)
- {
- if (existence_error (errno))
- {
- /*
- * If we have a sticky tag for a branch on which the
- * file is dead, and cvs update the directory, it gets
- * a T_CHECKOUT but no file. So in this case just
- * forget the whole thing.
- */
- free (entries_line);
- entries_line = NULL;
- goto done;
- }
- error (1, errno, "reading %s", short_pathname);
- }
-
- if (checksum != NULL)
- {
- static int checksum_supported = -1;
-
- if (checksum_supported == -1)
- {
- checksum_supported = supported_response ("Checksum");
- }
-
- if (checksum_supported)
- {
- int i;
- char buf[3];
-
- buf_output0 (&protocol, "Checksum ");
- for (i = 0; i < 16; i++)
- {
- sprintf (buf, "%02x", (unsigned int) checksum[i]);
- buf_output0 (&protocol, buf);
- }
- buf_append_char (&protocol, '\n');
- }
- }
-
- if (updated == SERVER_UPDATED)
- buf_output0 (&protocol, "Updated ");
- else if (updated == SERVER_MERGED)
- buf_output0 (&protocol, "Merged ");
- else if (updated == SERVER_PATCHED)
- buf_output0 (&protocol, "Patched ");
- else
- abort ();
- output_dir (update_dir, repository);
- buf_output0 (&protocol, file);
- buf_output (&protocol, "\n", 1);
-
- new_entries_line ();
-
- {
- char *mode_string;
-
- /* FIXME: When we check out files the umask of the server
- (set in .bashrc if rsh is in use, or set in main.c in
- the kerberos case, I think) affects what mode we send,
- and it shouldn't. */
- if (file_info != NULL)
- mode_string = mode_to_string (file_info->st_mode);
- else
- mode_string = mode_to_string (sb.st_mode);
- buf_output0 (&protocol, mode_string);
- buf_output0 (&protocol, "\n");
- free (mode_string);
- }
-
- list = last = NULL;
- size = 0;
- if (sb.st_size > 0)
- {
- if (gzip_level
- /*
- * For really tiny files, the gzip process startup
- * time will outweigh the compression savings. This
- * might be computable somehow; using 100 here is just
- * a first approximation.
- */
- && sb.st_size > 100)
- {
- int status, fd, gzip_status;
- pid_t gzip_pid;
-
- fd = open (file, O_RDONLY, 0);
- if (fd < 0)
- error (1, errno, "reading %s", short_pathname);
- fd = filter_through_gzip (fd, 1, gzip_level, &gzip_pid);
- f = fdopen (fd, "r");
- status = buf_read_file_to_eof (f, &list, &last);
- size = buf_chain_length (list);
- if (status == -2)
- (*protocol.memory_error) (&protocol);
- else if (status != 0)
- error (1, ferror (f) ? errno : 0, "reading %s",
- short_pathname);
- if (fclose (f) == EOF)
- error (1, errno, "reading %s", short_pathname);
- if (waitpid (gzip_pid, &gzip_status, 0) == -1)
- error (1, errno, "waiting for gzip process %d", gzip_pid);
- else if (gzip_status != 0)
- error (1, 0, "gzip exited %d", gzip_status);
- /* Prepending length with "z" is flag for using gzip here. */
- buf_output0 (&protocol, "z");
- }
- else
- {
- long status;
-
- size = sb.st_size;
- f = fopen (file, "r");
- if (f == NULL)
- error (1, errno, "reading %s", short_pathname);
- status = buf_read_file (f, sb.st_size, &list, &last);
- if (status == -2)
- (*protocol.memory_error) (&protocol);
- else if (status != 0)
- error (1, ferror (f) ? errno : 0, "reading %s",
- short_pathname);
- if (fclose (f) == EOF)
- error (1, errno, "reading %s", short_pathname);
- }
- }
-
- sprintf (size_text, "%lu\n", size);
- buf_output0 (&protocol, size_text);
-
- buf_append_data (&protocol, list, last);
- /* Note we only send a newline here if the file ended with one. */
-
- /*
- * Avoid using up too much disk space for temporary files.
- * A file which does not exist indicates that the file is up-to-date,
- * which is now the case. If this is SERVER_MERGED, the file is
- * not up-to-date, and we indicate that by leaving the file there.
- * I'm thinking of cases like "cvs update foo/foo.c foo".
- */
- if ((updated == SERVER_UPDATED || updated == SERVER_PATCHED)
- /* But if we are joining, we'll need the file when we call
- join_file. */
- && !joining ())
- unlink (file);
- }
- else if (scratched_file != NULL && entries_line == NULL)
- {
- if (strcmp (scratched_file, file) != 0)
- error (1, 0,
- "CVS server internal error: `%s' vs. `%s' scratched",
- scratched_file,
- file);
- free (scratched_file);
- scratched_file = NULL;
-
- if (kill_scratched_file)
- buf_output0 (&protocol, "Removed ");
- else
- buf_output0 (&protocol, "Remove-entry ");
- output_dir (update_dir, repository);
- buf_output0 (&protocol, file);
- buf_output (&protocol, "\n", 1);
- }
- else if (scratched_file == NULL && entries_line == NULL)
- {
- /*
- * This can happen with death support if we were processing
- * a dead file in a checkout.
- */
- }
- else
- error (1, 0,
- "CVS server internal error: Register *and* Scratch_Entry.\n");
- buf_send_counted (&protocol);
- done:
- free (short_pathname);
-}
-
-void
-server_set_entstat (update_dir, repository)
- char *update_dir;
- char *repository;
-{
- static int set_static_supported = -1;
- if (set_static_supported == -1)
- set_static_supported = supported_response ("Set-static-directory");
- if (!set_static_supported) return;
-
- buf_output0 (&protocol, "Set-static-directory ");
- output_dir (update_dir, repository);
- buf_output0 (&protocol, "\n");
- buf_send_counted (&protocol);
-}
-
-void
-server_clear_entstat (update_dir, repository)
- char *update_dir;
- char *repository;
-{
- static int clear_static_supported = -1;
- if (clear_static_supported == -1)
- clear_static_supported = supported_response ("Clear-static-directory");
- if (!clear_static_supported) return;
-
- if (noexec)
- return;
-
- buf_output0 (&protocol, "Clear-static-directory ");
- output_dir (update_dir, repository);
- buf_output0 (&protocol, "\n");
- buf_send_counted (&protocol);
-}
-
-void
-server_set_sticky (update_dir, repository, tag, date)
- char *update_dir;
- char *repository;
- char *tag;
- char *date;
-{
- static int set_sticky_supported = -1;
- if (set_sticky_supported == -1)
- set_sticky_supported = supported_response ("Set-sticky");
- if (!set_sticky_supported) return;
-
- if (noexec)
- return;
-
- if (tag == NULL && date == NULL)
- {
- buf_output0 (&protocol, "Clear-sticky ");
- output_dir (update_dir, repository);
- buf_output0 (&protocol, "\n");
- }
- else
- {
- buf_output0 (&protocol, "Set-sticky ");
- output_dir (update_dir, repository);
- buf_output0 (&protocol, "\n");
- if (tag != NULL)
- {
- buf_output0 (&protocol, "T");
- buf_output0 (&protocol, tag);
- }
- else
- {
- buf_output0 (&protocol, "D");
- buf_output0 (&protocol, date);
- }
- buf_output0 (&protocol, "\n");
- }
- buf_send_counted (&protocol);
-}
-
-static void
-serve_gzip_contents (arg)
- char *arg;
-{
- int level;
- level = atoi (arg);
- if (level == 0)
- level = 6;
- gzip_level = level;
-}
-
-static void
-serve_ignore (arg)
- char *arg;
-{
- /*
- * Just ignore this command. This is used to support the
- * update-patches command, which is not a real command, but a signal
- * to the client that update will accept the -u argument.
- */
-}
-
-static int
-expand_proc (pargc, argv, where, mwhere, mfile, shorten,
- local_specified, omodule, msg)
- int *pargc;
- char **argv;
- char *where;
- char *mwhere;
- char *mfile;
- int shorten;
- int local_specified;
- char *omodule;
- char *msg;
-{
- int i;
- char *dir = argv[0];
-
- /* If mwhere has been specified, the thing we're expanding is a
- module -- just return its name so the client will ask for the
- right thing later. If it is an alias or a real directory,
- mwhere will not be set, so send out the appropriate
- expansion. */
-
- if (mwhere != NULL)
- printf ("Module-expansion %s\n", mwhere);
- else
- {
- /* We may not need to do this anymore -- check the definition
- of aliases before removing */
- if (*pargc == 1)
- printf ("Module-expansion %s\n", dir);
- else
- for (i = 1; i < *pargc; ++i)
- printf ("Module-expansion %s/%s\n", dir, argv[i]);
- }
- return 0;
-}
-
-static void
-serve_expand_modules (arg)
- char *arg;
-{
- int i;
- int err;
- DBM *db;
- err = 0;
-
- /*
- * FIXME: error handling is bogus; do_module can write to stdout and/or
- * stderr and we're not using do_cvs_command.
- */
-
- server_expanding = 1;
- db = open_module ();
- for (i = 1; i < argument_count; i++)
- err += do_module (db, argument_vector[i],
- CHECKOUT, "Updating", expand_proc,
- NULL, 0, 0, 0,
- (char *) NULL);
- close_module (db);
- server_expanding = 0;
- {
- /* argument_vector[0] is a dummy argument, we don't mess with it. */
- char **cp;
- for (cp = argument_vector + 1;
- cp < argument_vector + argument_count;
- ++cp)
- free (*cp);
-
- argument_count = 1;
- }
- if (err)
- /* We will have printed an error message already. */
- printf ("error \n");
- else
- printf ("ok\n");
-}
-
-void
-server_prog (dir, name, which)
- char *dir;
- char *name;
- enum progs which;
-{
- if (!supported_response ("Set-checkin-prog"))
- {
- printf ("E \
-warning: this client does not support -i or -u flags in the modules file.\n");
- return;
- }
- switch (which)
- {
- case PROG_CHECKIN:
- printf ("Set-checkin-prog ");
- break;
- case PROG_UPDATE:
- printf ("Set-update-prog ");
- break;
- }
- printf ("%s\n%s\n", dir, name);
-}
-
-static void
-serve_checkin_prog (arg)
- char *arg;
-{
- FILE *f;
- f = fopen (CVSADM_CIPROG, "w+");
- if (f == NULL)
- {
- pending_error = errno;
- pending_error_text = malloc (80 + strlen(CVSADM_CIPROG));
- sprintf(pending_error_text, "E cannot open %s", CVSADM_CIPROG);
- return;
- }
- if (fprintf (f, "%s\n", arg) < 0)
- {
- pending_error = errno;
- pending_error_text = malloc (80 + strlen(CVSADM_CIPROG));
- sprintf(pending_error_text, "E cannot write to %s", CVSADM_CIPROG);
- return;
- }
- if (fclose (f) == EOF)
- {
- pending_error = errno;
- pending_error_text = malloc (80 + strlen(CVSADM_CIPROG));
- sprintf(pending_error_text, "E cannot close %s", CVSADM_CIPROG);
- return;
- }
-}
-
-static void
-serve_update_prog (arg)
- char *arg;
-{
- FILE *f;
- f = fopen (CVSADM_UPROG, "w+");
- if (f == NULL)
- {
- pending_error = errno;
- pending_error_text = malloc (80 + strlen(CVSADM_UPROG));
- sprintf(pending_error_text, "E cannot open %s", CVSADM_UPROG);
- return;
- }
- if (fprintf (f, "%s\n", arg) < 0)
- {
- pending_error = errno;
- pending_error_text = malloc (80 + strlen(CVSADM_UPROG));
- sprintf(pending_error_text, "E cannot write to %s", CVSADM_UPROG);
- return;
- }
- if (fclose (f) == EOF)
- {
- pending_error = errno;
- pending_error_text = malloc (80 + strlen(CVSADM_UPROG));
- sprintf(pending_error_text, "E cannot close %s", CVSADM_UPROG);
- return;
- }
-}
-
-static void serve_valid_requests PROTO((char *arg));
-
-#endif /* SERVER_SUPPORT */
-#if defined(SERVER_SUPPORT) || defined(CLIENT_SUPPORT)
-
-/*
- * Parts of this table are shared with the client code,
- * but the client doesn't need to know about the handler
- * functions.
- */
-
-struct request requests[] =
-{
-#ifdef SERVER_SUPPORT
-#define REQ_LINE(n, f, s) {n, f, s}
-#else
-#define REQ_LINE(n, f, s) {n, s}
-#endif
-
- REQ_LINE("Root", serve_root, rq_essential),
- REQ_LINE("Valid-responses", serve_valid_responses, rq_essential),
- REQ_LINE("valid-requests", serve_valid_requests, rq_essential),
- REQ_LINE("Repository", serve_repository, rq_essential),
- REQ_LINE("Directory", serve_directory, rq_optional),
- REQ_LINE("Max-dotdot", serve_max_dotdot, rq_optional),
- REQ_LINE("Static-directory", serve_static_directory, rq_optional),
- REQ_LINE("Sticky", serve_sticky, rq_optional),
- REQ_LINE("Checkin-prog", serve_checkin_prog, rq_optional),
- REQ_LINE("Update-prog", serve_update_prog, rq_optional),
- REQ_LINE("Entry", serve_entry, rq_essential),
- REQ_LINE("Modified", serve_modified, rq_essential),
- REQ_LINE("Lost", serve_lost, rq_optional),
- REQ_LINE("UseUnchanged", serve_enable_unchanged, rq_enableme),
- REQ_LINE("Unchanged", serve_unchanged, rq_optional),
- REQ_LINE("Argument", serve_argument, rq_essential),
- REQ_LINE("Argumentx", serve_argumentx, rq_essential),
- REQ_LINE("Global_option", serve_global_option, rq_optional),
- REQ_LINE("expand-modules", serve_expand_modules, rq_optional),
- REQ_LINE("ci", serve_ci, rq_essential),
- REQ_LINE("co", serve_co, rq_essential),
- REQ_LINE("update", serve_update, rq_essential),
- REQ_LINE("diff", serve_diff, rq_optional),
- REQ_LINE("log", serve_log, rq_optional),
- REQ_LINE("add", serve_add, rq_optional),
- REQ_LINE("remove", serve_remove, rq_optional),
- REQ_LINE("update-patches", serve_ignore, rq_optional),
- REQ_LINE("gzip-file-contents", serve_gzip_contents, rq_optional),
- REQ_LINE("status", serve_status, rq_optional),
- REQ_LINE("rdiff", serve_rdiff, rq_optional),
- REQ_LINE("tag", serve_tag, rq_optional),
- REQ_LINE("rtag", serve_rtag, rq_optional),
- REQ_LINE("import", serve_import, rq_optional),
- REQ_LINE("admin", serve_admin, rq_optional),
- REQ_LINE("export", serve_export, rq_optional),
- REQ_LINE("history", serve_history, rq_optional),
- REQ_LINE("release", serve_release, rq_optional),
- REQ_LINE(NULL, NULL, rq_optional)
-
-#undef REQ_LINE
-};
-
-#endif /* SERVER_SUPPORT or CLIENT_SUPPORT */
-#ifdef SERVER_SUPPORT
-
-static void
-serve_valid_requests (arg)
- char *arg;
-{
- struct request *rq;
- if (print_pending_error ())
- return;
- printf ("Valid-requests");
- for (rq = requests; rq->name != NULL; rq++)
- if (rq->func != NULL)
- printf (" %s", rq->name);
- printf ("\nok\n");
-}
-
-#ifdef sun
-/*
- * Delete temporary files. SIG is the signal making this happen, or
- * 0 if not called as a result of a signal.
- */
-static int command_pid_is_dead;
-static void wait_sig (sig)
- int sig;
-{
- int status;
- pid_t r = wait (&status);
- if (r == command_pid)
- command_pid_is_dead++;
-}
-#endif
-
-void
-server_cleanup (sig)
- int sig;
-{
- /* Do "rm -rf" on the temp directory. */
- int len;
- char *cmd;
- char *temp_dir;
-
- if (dont_delete_temp)
- return;
-
- /* What a bogus kludge. This disgusting code makes all kinds of
- assumptions about SunOS, and is only for a bug in that system.
- So only enable it on Suns. */
-#ifdef sun
- if (command_pid > 0) {
- /* To avoid crashes on SunOS due to bugs in SunOS tmpfs
- triggered by the use of rename() in RCS, wait for the
- subprocess to die. Unfortunately, this means draining output
- while waiting for it to unblock the signal we sent it. Yuck! */
- int status;
- pid_t r;
-
- signal (SIGCHLD, wait_sig);
- if (sig)
- /* Perhaps SIGTERM would be more correct. But the child
- process will delay the SIGINT delivery until its own
- children have exited. */
- kill (command_pid, SIGINT);
- /* The caller may also have sent a signal to command_pid, so
- always try waiting. First, though, check and see if it's still
- there.... */
- do_waitpid:
- r = waitpid (command_pid, &status, WNOHANG);
- if (r == 0)
- ;
- else if (r == command_pid)
- command_pid_is_dead++;
- else if (r == -1)
- switch (errno) {
- case ECHILD:
- command_pid_is_dead++;
- break;
- case EINTR:
- goto do_waitpid;
- }
- else
- /* waitpid should always return one of the above values */
- abort ();
- while (!command_pid_is_dead) {
- struct timeval timeout;
- struct fd_set_wrapper readfds;
- char buf[100];
- int i;
-
- /* Use a non-zero timeout to avoid eating up CPU cycles. */
- timeout.tv_sec = 2;
- timeout.tv_usec = 0;
- readfds = command_fds_to_drain;
- switch (select (max_command_fd + 1, &readfds.fds,
- (fd_set *)0, (fd_set *)0,
- &timeout)) {
- case -1:
- if (errno != EINTR)
- abort ();
- case 0:
- /* timeout */
- break;
- case 1:
- for (i = 0; i <= max_command_fd; i++)
- {
- if (!FD_ISSET (i, &readfds.fds))
- continue;
- /* this fd is non-blocking */
- while (read (i, buf, sizeof (buf)) >= 1)
- ;
- }
- break;
- default:
- abort ();
- }
- }
- }
-#endif
-
- /* This might be set by the user in ~/.bashrc, ~/.cshrc, etc. */
- temp_dir = getenv ("TMPDIR");
- if (temp_dir == NULL || temp_dir[0] == '\0')
- temp_dir = "/tmp";
- chdir(temp_dir);
-
- len = strlen (server_temp_dir) + 80;
- cmd = malloc (len);
- if (cmd == NULL)
- {
- printf ("E Cannot delete %s on server; out of memory\n",
- server_temp_dir);
- return;
- }
- sprintf (cmd, "rm -rf %s", server_temp_dir);
- system (cmd);
- free (cmd);
-}
-
-int server_active = 0;
-int server_expanding = 0;
-
-int
-server (argc, argv)
- int argc;
- char **argv;
-{
- if (argc == -1)
- {
- static const char *const msg[] =
- {
- "Usage: %s %s\n",
- " Normally invoked by a cvs client on a remote machine.\n",
- NULL
- };
- usage (msg);
- }
- /* Ignore argc and argv. They might be from .cvsrc. */
-
- /* Since we're in the server parent process, error should use the
- protocol to report error messages. */
- error_use_protocol = 1;
-
- /*
- * Put Rcsbin at the start of PATH, so that rcs programs can find
- * themselves.
- */
-#ifdef HAVE_PUTENV
- if (Rcsbin != NULL && *Rcsbin)
- {
- char *p;
- char *env;
-
- p = getenv ("PATH");
- if (p != NULL)
- {
- env = malloc (strlen (Rcsbin) + strlen (p) + sizeof "PATH=:");
- if (env != NULL)
- sprintf (env, "PATH=%s:%s", Rcsbin, p);
- }
- else
- {
- env = malloc (strlen (Rcsbin) + sizeof "PATH=");
- if (env != NULL)
- sprintf (env, "PATH=%s", Rcsbin);
- }
- if (env == NULL)
- {
- printf ("E Fatal server error, aborting.\n\
-error ENOMEM Virtual memory exhausted.\n");
- exit (1);
- }
- putenv (env);
- }
-#endif
-
- /* OK, now figure out where we stash our temporary files. */
- {
- char *p;
-
- /* This might be set by the user in ~/.bashrc, ~/.cshrc, etc. */
- char *temp_dir = getenv ("TMPDIR");
- if (temp_dir == NULL || temp_dir[0] == '\0')
- temp_dir = "/tmp";
-
- server_temp_dir = malloc (strlen (temp_dir) + 80);
- if (server_temp_dir == NULL)
- {
- /*
- * Strictly speaking, we're not supposed to output anything
- * now. But we're about to exit(), give it a try.
- */
- printf ("E Fatal server error, aborting.\n\
-error ENOMEM Virtual memory exhausted.\n");
- exit (1);
- }
- strcpy (server_temp_dir, temp_dir);
-
- /* Remove a trailing slash from TMPDIR if present. */
- p = server_temp_dir + strlen (server_temp_dir) - 1;
- if (*p == '/')
- *p = '\0';
-
- /*
- * I wanted to use cvs-serv/PID, but then you have to worry about
- * the permissions on the cvs-serv directory being right. So
- * use cvs-servPID.
- */
- strcat (server_temp_dir, "/cvs-serv");
-
- p = server_temp_dir + strlen (server_temp_dir);
- sprintf (p, "%d", getpid ());
- }
-
- (void) SIG_register (SIGHUP, server_cleanup);
- (void) SIG_register (SIGINT, server_cleanup);
- (void) SIG_register (SIGQUIT, server_cleanup);
- (void) SIG_register (SIGPIPE, server_cleanup);
- (void) SIG_register (SIGTERM, server_cleanup);
-
- /* Now initialize our argument vector (for arguments from the client). */
-
- /* Small for testing. */
- argument_vector_size = 1;
- argument_vector =
- (char **) malloc (argument_vector_size * sizeof (char *));
- if (argument_vector == NULL)
- {
- /*
- * Strictly speaking, we're not supposed to output anything
- * now. But we're about to exit(), give it a try.
- */
- printf ("E Fatal server error, aborting.\n\
-error ENOMEM Virtual memory exhausted.\n");
- exit (1);
- }
-
- argument_count = 1;
- argument_vector[0] = "Dummy argument 0";
-
- server_active = 1;
- while (1)
- {
- char *cmd, *orig_cmd;
- struct request *rq;
-
- orig_cmd = cmd = read_line (stdin);
- if (cmd == NULL)
- break;
- if (cmd == NO_MEM_ERROR)
- {
- printf ("E Fatal server error, aborting.\n\
-error ENOMEM Virtual memory exhausted.\n");
- break;
- }
- for (rq = requests; rq->name != NULL; ++rq)
- if (strncmp (cmd, rq->name, strlen (rq->name)) == 0)
- {
- int len = strlen (rq->name);
- if (cmd[len] == '\0')
- cmd += len;
- else if (cmd[len] == ' ')
- cmd += len + 1;
- else
- /*
- * The first len characters match, but it's a different
- * command. e.g. the command is "cooperate" but we matched
- * "co".
- */
- continue;
- (*rq->func) (cmd);
- break;
- }
- if (rq->name == NULL)
- {
- if (!print_pending_error ())
- printf ("error unrecognized request `%s'\n", cmd);
- }
- free (orig_cmd);
- }
- server_cleanup (0);
- return 0;
-}
-
-
-#ifdef AUTH_SERVER_SUPPORT
-
-/* This was test code, which we may need again. */
-#if 0
- /* If we were invoked this way, then stdin comes from the
- client and stdout/stderr writes to it. */
- int c;
- while ((c = getc (stdin)) != EOF && c != '*')
- {
- printf ("%c", toupper (c));
- fflush (stdout);
- }
- exit (0);
-#endif /* 1/0 */
-
-
-/*
- * 0 means no entry found for this user.
- * 1 means entry found and password matches.
- * 2 means entry found, but password does not match.
- */
-int
-check_repository_password (username, password, repository)
- char *username, *password, *repository;
-{
- int retval = 0;
- FILE *fp;
- char *filename;
- char linebuf[MAXLINELEN];
- int found_it = 0, len;
-
- filename = xmalloc (strlen (repository)
- + 1
- + strlen ("CVSROOT")
- + 1
- + strlen ("passwd")
- + 1);
-
- strcpy (filename, repository);
- strcat (filename, "/CVSROOT");
- strcat (filename, "/passwd");
-
- fp = fopen (filename, "r");
- if (fp == NULL)
- {
- /* This is ok -- the cvs passwd file might not exist. */
- fclose (fp);
- return 0;
- }
-
- /* Look for a relevant line -- one with this user's name. */
- len = strlen (username);
- while (fgets (linebuf, MAXPATHLEN - 1, fp))
- {
- if ((strncmp (linebuf, username, len) == 0)
- && (linebuf[len] == ':'))
- {
- found_it = 1;
- break;
- }
- }
- fclose (fp);
-
- /* If found_it != 0, then linebuf contains the information we need. */
- if (found_it)
- {
- char *found_password;
-
- strtok (linebuf, ":");
- found_password = strtok (NULL, ": \n");
-
- if (strcmp (found_password, crypt (password, found_password)) == 0)
- retval = 1;
- else
- retval = 2;
- }
- else
- retval = 0;
-
- free (filename);
-
- return retval;
-}
-
-
-/* Return 1 if password matches, else 0. */
-int
-check_password (username, password, repository)
- char *username, *password, *repository;
-{
- int rc;
-
- /* First we see if this user has a password in the CVS-specific
- password file. If so, that's enough to authenticate with. If
- not, we'll check /etc/passwd. */
-
- rc = check_repository_password (username, password, repository);
-
- if (rc == 1)
- return 1;
- else if (rc == 2)
- return 0;
- else if (rc == 0)
- {
- /* No cvs password found, so try /etc/passwd. */
-
- struct passwd *pw;
- char *found_passwd;
-
- pw = getpwnam (username);
- if (pw == NULL)
- {
- printf ("E Fatal error, aborting.\n"
- "error 0 %s: no such user\n", username);
- exit (1);
- }
- found_passwd = pw->pw_passwd;
-
- if (found_passwd && *found_passwd)
- return (! strcmp (found_passwd, crypt (password, found_passwd)));
- else if (password && *password)
- return 1;
- else
- return 0;
- }
- else
- {
- /* Something strange happened. We don't know what it was, but
- we certainly won't grant authorization. */
- return 0;
- }
-}
-
-
-/* Read username and password from client (i.e., stdin).
- If correct, then switch to run as that user and send an ACK to the
- client via stdout, else send NACK and die. */
-void
-authenticate_connection ()
-{
- int len;
- char tmp[PATH_MAX];
- char repository[PATH_MAX];
- char username[PATH_MAX];
- char password[PATH_MAX];
- char server_user[PATH_MAX];
- struct passwd *pw;
-
- /* The Authentication Protocol. Client sends:
- *
- * BEGIN AUTH REQUEST\n
- * <REPOSITORY>\n
- * <USERNAME>\n
- * <PASSWORD>\n
- * END AUTH REQUEST\n
- *
- * Server uses above information to authenticate, then sends
- *
- * I LOVE YOU\n
- *
- * if it grants access, else
- *
- * I HATE YOU\n
- *
- * if it denies access (and it exits if denying).
- *
- * Note that the actual client/server protocol has not started up
- * yet, because we haven't authenticated! Therefore, there are
- * certain things we can't take for granted. For example, don't use
- * error() because `error_use_protocol' has not yet been set by
- * server().
- *
- * We need to know where the repository is too, to look up the
- * password in the special CVS passwd file before we try
- * /etc/passwd. However, the repository is normally transmitted in
- * the regular client/server protocol, which has not yet started,
- * blah blah blah. This is why the client transmits the repository
- * as part of the "authentication protocol". Thus, the repository
- * will be redundantly retransmitted later, but that's no big deal.
- */
-
- /* Make sure the protocol starts off on the right foot... */
- fgets (tmp, PATH_MAX, stdin);
- if (strcmp (tmp, "BEGIN AUTH REQUEST\n"))
- {
- printf ("error: bad auth protocol start: %s", tmp);
- fflush (stdout);
- exit (1);
- }
-
- /* Get the three important pieces of information in order. */
- fgets (repository, PATH_MAX, stdin);
- fgets (username, PATH_MAX, stdin);
- fgets (password, PATH_MAX, stdin);
-
- /* Make them pure. */
- strip_trailing_newlines (repository);
- strip_trailing_newlines (username);
- strip_trailing_newlines (password);
-
- /* ... and make sure the protocol ends on the right foot. */
- fgets (tmp, PATH_MAX, stdin);
- if (strcmp (tmp, "END AUTH REQUEST\n"))
- {
- printf ("error: bad auth protocol end: %s", tmp);
- fflush (stdout);
- exit (1);
- }
-
- if (check_password (username, password, repository))
- {
- printf ("I LOVE YOU\n");
- fflush (stdout);
- }
- else
- {
- printf ("I HATE YOU\n");
- fflush (stdout);
- exit (1);
- }
-
- /* Do everything that kerberos did. */
- pw = getpwnam (username);
- if (pw == NULL)
- {
- printf ("E Fatal error, aborting.\n"
- "error 0 %s: no such user\n", username);
- exit (1);
- }
-
- initgroups (pw->pw_name, pw->pw_gid);
- setgid (pw->pw_gid);
- setuid (pw->pw_uid);
- /* Inhibit access by randoms. Don't want people randomly
- changing our temporary tree before we check things in. */
- umask (077);
-
-#if HAVE_PUTENV
- /* Set LOGNAME and USER in the environment, in case they are
- already set to something else. */
- {
- char *env;
-
- env = xmalloc (sizeof "LOGNAME=" + strlen (username));
- (void) sprintf (env, "LOGNAME=%s", username);
- (void) putenv (env);
-
- env = xmalloc (sizeof "USER=" + strlen (username));
- (void) sprintf (env, "USER=%s", username);
- (void) putenv (env);
- }
-#endif /* HAVE_PUTENV */
-}
-
-#endif AUTH_SERVER_SUPPORT
-
-
-#endif /* SERVER_SUPPORT */
-
diff --git a/gnu/usr.bin/cvs/cvs/server.h b/gnu/usr.bin/cvs/cvs/server.h
deleted file mode 100644
index cb49267e991e..000000000000
--- a/gnu/usr.bin/cvs/cvs/server.h
+++ /dev/null
@@ -1,136 +0,0 @@
-/* Interface between the server and the rest of CVS. */
-
-/* Miscellaneous stuff which isn't actually particularly server-specific. */
-#ifndef STDIN_FILENO
-#define STDIN_FILENO 0
-#define STDOUT_FILENO 1
-#define STDERR_FILENO 2
-#endif
-
-#ifdef SERVER_SUPPORT
-
-/*
- * Nonzero if we are using the server. Used by various places to call
- * server-specific functions.
- */
-extern int server_active;
-extern int server_expanding;
-
-/* Server functions exported to the rest of CVS. */
-
-/* Run the server. */
-extern int server PROTO((int argc, char **argv));
-
-/* We have a new Entries line for a file. TAG or DATE can be NULL. */
-extern void server_register
- PROTO((char *name, char *version, char *timestamp,
- char *options, char *tag, char *date, char *conflict));
-
-/*
- * We want to nuke the Entries line for a file, and (unless
- * server_scratch_entry_only is subsequently called) the file itself.
- */
-extern void server_scratch PROTO((char *name));
-
-/*
- * The file which just had server_scratch called on it needs to have only
- * the Entries line removed, not the file itself.
- */
-extern void server_scratch_entry_only PROTO((void));
-
-/*
- * We just successfully checked in FILE (which is just the bare
- * filename, with no directory). REPOSITORY is the directory for the
- * repository.
- */
-extern void server_checked_in
- PROTO((char *file, char *update_dir, char *repository));
-
-extern void server_copy_file
- PROTO((char *file, char *update_dir, char *repository, char *newfile));
-
-/*
- * We just successfully updated FILE (bare filename, no directory).
- * REPOSITORY is the directory for the repository. This is called
- * after server_register or server_scratch, in the latter case the
- * file is to be removed. UPDATED indicates whether the file is now
- * up to date (SERVER_UPDATED, yes, SERVER_MERGED, no, SERVER_PATCHED,
- * yes, but file is a diff from user version to repository version).
- */
-enum server_updated_arg4 {SERVER_UPDATED, SERVER_MERGED, SERVER_PATCHED};
-extern void server_updated
- PROTO((char *file, char *update_dir, char *repository,
- enum server_updated_arg4 updated, struct stat *,
- unsigned char *checksum));
-
-/* Set the Entries.Static flag. */
-extern void server_set_entstat PROTO((char *update_dir, char *repository));
-/* Clear it. */
-extern void server_clear_entstat PROTO((char *update_dir, char *repository));
-
-/* Set or clear a per-directory sticky tag or date. */
-extern void server_set_sticky PROTO((char *update_dir, char *repository,
- char *tag,
- char *date));
-
-extern void server_update_entries
- PROTO((char *file, char *update_dir, char *repository,
- enum server_updated_arg4 updated));
-
-enum progs {PROG_CHECKIN, PROG_UPDATE};
-extern void server_prog PROTO((char *, char *, enum progs));
-extern void server_cleanup PROTO((int sig));
-
-#ifdef SERVER_FLOWCONTROL
-/* Pause if it's convenient to avoid memory blowout */
-extern void server_check_pause PROTO((void));
-#endif /* SERVER_FLOWCONTROL */
-
-#endif /* SERVER_SUPPORT */
-
-/* Stuff shared with the client. */
-struct request
-{
- /* Name of the request. */
- char *name;
-
-#ifdef SERVER_SUPPORT
- /*
- * Function to carry out the request. ARGS is the text of the command
- * after name and, if present, a single space, have been stripped off.
- */
- void (*func) PROTO((char *args));
-#endif
-
- /* Stuff for use by the client. */
- enum {
- /*
- * Failure to implement this request can imply a fatal
- * error. This should be set only for commands which were in the
- * original version of the protocol; it should not be set for new
- * commands.
- */
- rq_essential,
-
- /* Some servers might lack this request. */
- rq_optional,
-
- /*
- * Set by the client to one of the following based on what this
- * server actually supports.
- */
- rq_supported,
- rq_not_supported,
-
- /*
- * If the server supports this request, and we do too, tell the
- * server by making the request.
- */
- rq_enableme
- } status;
-};
-
-/* Table of requests ending with an entry with a NULL name. */
-extern struct request requests[];
-
-extern int use_unchanged;
diff --git a/gnu/usr.bin/cvs/cvs/status.c b/gnu/usr.bin/cvs/cvs/status.c
deleted file mode 100644
index fe53bcb21684..000000000000
--- a/gnu/usr.bin/cvs/cvs/status.c
+++ /dev/null
@@ -1,282 +0,0 @@
-/*
- * Copyright (c) 1992, Brian Berliner and Jeff Polk
- * Copyright (c) 1989-1992, Brian Berliner
- *
- * You may distribute under the terms of the GNU General Public License as
- * specified in the README file that comes with the CVS 1.4 kit.
- *
- * Status Information
- */
-
-#include "cvs.h"
-
-#ifndef lint
-static const char rcsid[] = "$CVSid: @(#)status.c 1.56 94/10/07 $";
-USE(rcsid);
-#endif
-
-static Dtype status_dirproc PROTO((char *dir, char *repos, char *update_dir));
-static int status_fileproc PROTO((char *file, char *update_dir,
- char *repository, List * entries,
- List * srcfiles));
-static int tag_list_proc PROTO((Node * p, void *closure));
-
-static int local = 0;
-static int long_format = 0;
-static char *xfile;
-static List *xsrcfiles;
-
-static const char *const status_usage[] =
-{
- "Usage: %s %s [-vlR] [files...]\n",
- "\t-v\tVerbose format; includes tag information for the file\n",
- "\t-l\tProcess this directory only (not recursive).\n",
- "\t-R\tProcess directories recursively.\n",
- NULL
-};
-
-int
-status (argc, argv)
- int argc;
- char **argv;
-{
- int c;
- int err = 0;
-
- if (argc == -1)
- usage (status_usage);
-
- optind = 1;
- while ((c = getopt (argc, argv, "vlR")) != -1)
- {
- switch (c)
- {
- case 'v':
- long_format = 1;
- break;
- case 'l':
- local = 1;
- break;
- case 'R':
- local = 0;
- break;
- case '?':
- default:
- usage (status_usage);
- break;
- }
- }
- argc -= optind;
- argv += optind;
-
- wrap_setup ();
-
-#ifdef CLIENT_SUPPORT
- if (client_active) {
- start_server ();
-
- ign_setup ();
-
- if (long_format)
- send_arg("-v");
- if (local)
- send_arg("-l");
-
- /* XXX This should only need to send file info; the file
- contents themselves will not be examined. */
- send_files (argc, argv, local, 0);
-
- if (fprintf (to_server, "status\n") < 0)
- error (1, errno, "writing to server");
- err = get_responses_and_close ();
-
- return err;
- }
-#endif
-
- /* start the recursion processor */
- err = start_recursion (status_fileproc, (FILESDONEPROC) NULL, status_dirproc,
- (DIRLEAVEPROC) NULL, argc, argv, local,
- W_LOCAL, 0, 1, (char *) NULL, 1, 0);
-
- return (err);
-}
-
-/*
- * display the status of a file
- */
-/* ARGSUSED */
-static int
-status_fileproc (file, update_dir, repository, entries, srcfiles)
- char *file;
- char *update_dir;
- char *repository;
- List *entries;
- List *srcfiles;
-{
- Ctype status;
- char *sstat;
- Vers_TS *vers;
-
- status = Classify_File (file, (char *) NULL, (char *) NULL, (char *) NULL,
- 1, 0, repository, entries, srcfiles, &vers,
- update_dir, 0);
- switch (status)
- {
- case T_UNKNOWN:
- sstat = "Unknown";
- break;
- case T_CHECKOUT:
- sstat = "Needs Checkout";
- break;
-#ifdef SERVER_SUPPORT
- case T_PATCH:
- sstat = "Needs Patch";
- break;
-#endif
- case T_CONFLICT:
- sstat = "Unresolved Conflict";
- break;
- case T_ADDED:
- sstat = "Locally Added";
- break;
- case T_REMOVED:
- sstat = "Locally Removed";
- break;
- case T_MODIFIED:
- if (vers->ts_conflict)
- sstat = "Unresolved Conflict";
- else
- sstat = "Locally Modified";
- break;
- case T_REMOVE_ENTRY:
- sstat = "Entry Invalid";
- break;
- case T_UPTODATE:
- sstat = "Up-to-date";
- break;
- case T_NEEDS_MERGE:
- sstat = "Needs Merge";
- break;
- default:
- sstat = "Classify Error";
- break;
- }
-
- (void) printf ("===================================================================\n");
- if (vers->ts_user == NULL)
- (void) printf ("File: no file %s\t\tStatus: %s\n\n", file, sstat);
- else
- (void) printf ("File: %-17s\tStatus: %s\n\n", file, sstat);
-
- if (vers->vn_user == NULL)
- (void) printf (" Working revision:\tNo entry for %s\n", file);
- else if (vers->vn_user[0] == '0' && vers->vn_user[1] == '\0')
- (void) printf (" Working revision:\tNew file!\n");
-#ifdef SERVER_SUPPORT
- else if (server_active)
- (void) printf (" Working revision:\t%s\n", vers->vn_user);
-#endif
- else
- (void) printf (" Working revision:\t%s\t%s\n", vers->vn_user,
- vers->ts_rcs);
-
- if (vers->vn_rcs == NULL)
- (void) printf (" Repository revision:\tNo revision control file\n");
- else
- (void) printf (" Repository revision:\t%s\t%s\n", vers->vn_rcs,
- vers->srcfile->path);
-
- if (vers->entdata)
- {
- Entnode *edata;
-
- edata = vers->entdata;
- if (edata->tag)
- {
- if (vers->vn_rcs == NULL)
- (void) printf (
- " Sticky Tag:\t\t%s - MISSING from RCS file!\n",
- edata->tag);
- else
- {
- if (isdigit (edata->tag[0]))
- (void) printf (" Sticky Tag:\t\t%s\n", edata->tag);
- else
- {
- int isbranch = RCS_isbranch (file, edata->tag, srcfiles);
-
- (void) printf (" Sticky Tag:\t\t%s (%s: %s)\n",
- edata->tag,
- isbranch ? "branch" : "revision",
- isbranch ?
- RCS_whatbranch(file, edata->tag, srcfiles) :
- vers->vn_rcs);
- }
- }
- }
- else if (!really_quiet)
- (void) printf (" Sticky Tag:\t\t(none)\n");
-
- if (edata->date)
- (void) printf (" Sticky Date:\t\t%s\n", edata->date);
- else if (!really_quiet)
- (void) printf (" Sticky Date:\t\t(none)\n");
-
- if (edata->options && edata->options[0])
- (void) printf (" Sticky Options:\t%s\n", edata->options);
- else if (!really_quiet)
- (void) printf (" Sticky Options:\t(none)\n");
-
- if (long_format && vers->srcfile)
- {
- List *symbols = RCS_symbols(vers->srcfile);
-
- (void) printf ("\n Existing Tags:\n");
- if (symbols)
- {
- xfile = file;
- xsrcfiles = srcfiles;
- (void) walklist (symbols, tag_list_proc, NULL);
- }
- else
- (void) printf ("\tNo Tags Exist\n");
- }
- }
-
- (void) printf ("\n");
- freevers_ts (&vers);
- return (0);
-}
-
-/*
- * Print a warm fuzzy message
- */
-/* ARGSUSED */
-static Dtype
-status_dirproc (dir, repos, update_dir)
- char *dir;
- char *repos;
- char *update_dir;
-{
- if (!quiet)
- error (0, 0, "Examining %s", update_dir);
- return (R_PROCESS);
-}
-
-/*
- * Print out a tag and its type
- */
-static int
-tag_list_proc (p, closure)
- Node *p;
- void *closure;
-{
- int isbranch = RCS_isbranch (xfile, p->key, xsrcfiles);
-
- (void) printf ("\t%-25.25s\t(%s: %s)\n", p->key,
- isbranch ? "branch" : "revision",
- isbranch ? RCS_whatbranch(xfile, p->key, xsrcfiles) :
- p->data);
- return (0);
-}
diff --git a/gnu/usr.bin/cvs/cvs/tag.c b/gnu/usr.bin/cvs/cvs/tag.c
deleted file mode 100644
index 55c86593f01c..000000000000
--- a/gnu/usr.bin/cvs/cvs/tag.c
+++ /dev/null
@@ -1,582 +0,0 @@
-/*
- * Copyright (c) 1992, Brian Berliner and Jeff Polk
- * Copyright (c) 1989-1992, Brian Berliner
- *
- * You may distribute under the terms of the GNU General Public License as
- * specified in the README file that comes with the CVS 1.4 kit.
- *
- * Tag
- *
- * Add or delete a symbolic name to an RCS file, or a collection of RCS files.
- * Uses the checked out revision in the current directory.
- */
-
-#include "cvs.h"
-
-#ifndef lint
-static const char rcsid[] = "$CVSid: @(#)tag.c 1.60 94/09/30 $";
-USE(rcsid);
-#endif
-
-static int check_fileproc PROTO((char *file, char *update_dir,
- char *repository, List * entries,
- List * srcfiles));
-static int check_filesdoneproc PROTO((int err, char *repos, char *update_dir));
-static int pretag_proc PROTO((char *repository, char *filter));
-static void masterlist_delproc PROTO((Node *p));
-static void tag_delproc PROTO((Node *p));
-static int pretag_list_proc PROTO((Node *p, void *closure));
-
-static Dtype tag_dirproc PROTO((char *dir, char *repos, char *update_dir));
-static int tag_fileproc PROTO((char *file, char *update_dir,
- char *repository, List * entries,
- List * srcfiles));
-
-static char *numtag;
-static char *date = NULL;
-static char *symtag;
-static int delete; /* adding a tag by default */
-static int branch_mode; /* make an automagic "branch" tag */
-static int local; /* recursive by default */
-static int force_tag_match = 1; /* force tag to match by default */
-static int force_tag_move; /* don't force tag to move by default */
-
-struct tag_info
-{
- Ctype status;
- char *rev;
- char *tag;
- char *options;
-};
-
-struct master_lists
-{
- List *tlist;
-};
-
-static List *mtlist;
-static List *tlist;
-
-static const char *const tag_usage[] =
-{
- "Usage: %s %s [-lRF] [-b] [-d] tag [files...]\n",
- "\t-l\tLocal directory only, not recursive.\n",
- "\t-R\tProcess directories recursively.\n",
- "\t-d\tDelete the given Tag.\n",
- "\t-[rD]\tExisting tag or date.\n",
- "\t-f\tForce a head revision if tag etc not found.\n",
- "\t-b\tMake the tag a \"branch\" tag, allowing concurrent development.\n",
- "\t-F\tMove tag if it already exists\n",
- NULL
-};
-
-int
-tag (argc, argv)
- int argc;
- char **argv;
-{
- int c;
- int err = 0;
-
- if (argc == -1)
- usage (tag_usage);
-
- optind = 1;
- while ((c = getopt (argc, argv, "FQqlRdr:D:bf")) != -1)
- {
- switch (c)
- {
- case 'Q':
- case 'q':
-#ifdef SERVER_SUPPORT
- /* The CVS 1.5 client sends these options (in addition to
- Global_option requests), so we must ignore them. */
- if (!server_active)
-#endif
- error (1, 0,
- "-q or -Q must be specified before \"%s\"",
- command_name);
- break;
- case 'l':
- local = 1;
- break;
- case 'R':
- local = 0;
- break;
- case 'd':
- delete = 1;
- break;
- case 'r':
- numtag = optarg;
- break;
- case 'D':
- if (date)
- free (date);
- date = Make_Date (optarg);
- break;
- case 'f':
- force_tag_match = 0;
- break;
- case 'b':
- branch_mode = 1;
- break;
- case 'F':
- force_tag_move = 1;
- break;
- case '?':
- default:
- usage (tag_usage);
- break;
- }
- }
- argc -= optind;
- argv += optind;
-
- if (argc == 0)
- usage (tag_usage);
- symtag = argv[0];
- argc--;
- argv++;
-
- if (delete && branch_mode)
- error (0, 0, "warning: -b ignored with -d options");
- RCS_check_tag (symtag);
-
-#ifdef CLIENT_SUPPORT
- if (client_active)
- {
- /* We're the client side. Fire up the remote server. */
- start_server ();
-
- ign_setup ();
-
- if (local)
- send_arg("-l");
- if (delete)
- send_arg("-d");
- if (branch_mode)
- send_arg("-b");
- if (force_tag_move)
- send_arg("-F");
-
- send_arg (symtag);
-
-#if 0
- /* FIXME: We shouldn't have to send current files, but I'm not sure
- whether it works. So send the files --
- it's slower but it works. */
- send_file_names (argc, argv);
-#else
- send_files (argc, argv, local, 0);
-#endif
- if (fprintf (to_server, "tag\n") < 0)
- error (1, errno, "writing to server");
- return get_responses_and_close ();
- }
-#endif
-
- /* check to make sure they are authorized to tag all the
- specified files in the repository */
-
- mtlist = getlist();
- err = start_recursion (check_fileproc, check_filesdoneproc,
- (DIRENTPROC) NULL, (DIRLEAVEPROC) NULL,
- argc, argv, local, W_LOCAL, 0, 1,
- (char *) NULL, 1, 0);
-
- if (err)
- {
- error (1, 0, "correct the above errors first!");
- }
-
- /* start the recursion processor */
- err = start_recursion (tag_fileproc, (FILESDONEPROC) NULL, tag_dirproc,
- (DIRLEAVEPROC) NULL, argc, argv, local,
- W_LOCAL, 0, 1, (char *) NULL, 1, 0);
- dellist(&mtlist);
- return (err);
-}
-
-/* check file that is to be tagged */
-/* All we do here is add it to our list */
-
-static int
-check_fileproc(file, update_dir, repository, entries, srcfiles)
- char *file;
- char *update_dir;
- char *repository;
- List * entries;
- List * srcfiles;
-{
- char *xdir;
- Node *p;
- Vers_TS *vers;
-
- if (update_dir[0] == '\0')
- xdir = ".";
- else
- xdir = update_dir;
- if ((p = findnode (mtlist, xdir)) != NULL)
- {
- tlist = ((struct master_lists *) p->data)->tlist;
- }
- else
- {
- struct master_lists *ml;
-
- tlist = getlist ();
- p = getnode ();
- p->key = xstrdup (xdir);
- p->type = UPDATE;
- ml = (struct master_lists *)
- xmalloc (sizeof (struct master_lists));
- ml->tlist = tlist;
- p->data = (char *) ml;
- p->delproc = masterlist_delproc;
- (void) addnode (mtlist, p);
- }
- /* do tlist */
- p = getnode ();
- p->key = xstrdup (file);
- p->type = UPDATE;
- p->delproc = tag_delproc;
- vers = Version_TS (repository, (char *) NULL, (char *) NULL, (char *) NULL,
- file, 0, 0, entries, srcfiles);
- p->data = RCS_getversion(vers->srcfile, numtag, date, force_tag_match, 0);
- if (p->data != NULL)
- {
- int addit = 1;
- char *oversion;
-
- oversion = RCS_getversion (vers->srcfile, symtag, (char *) NULL, 1, 0);
- if (oversion == NULL)
- {
- if (delete)
- {
- addit = 0;
- }
- }
- else if (strcmp(oversion, p->data) == 0)
- {
- addit = 0;
- }
- else if (!force_tag_move)
- {
- addit = 0;
- }
- if (oversion != NULL)
- {
- free(oversion);
- }
- if (!addit)
- {
- free(p->data);
- p->data = NULL;
- }
- }
- freevers_ts(&vers);
- (void) addnode (tlist, p);
- return (0);
-}
-
-static int
-check_filesdoneproc(err, repos, update_dir)
- int err;
- char *repos;
- char *update_dir;
-{
- int n;
- Node *p;
-
- p = findnode(mtlist, update_dir);
- if (p != NULL)
- {
- tlist = ((struct master_lists *) p->data)->tlist;
- }
- else
- {
- tlist = (List *) NULL;
- }
- if ((tlist == NULL) || (tlist->list->next == tlist->list))
- {
- return (err);
- }
- if ((n = Parse_Info(CVSROOTADM_TAGINFO, repos, pretag_proc, 1)) > 0)
- {
- error (0, 0, "Pre-tag check failed");
- err += n;
- }
- return (err);
-}
-
-static int
-pretag_proc(repository, filter)
- char *repository;
- char *filter;
-{
- if (filter[0] == '/')
- {
- char *s, *cp;
-
- s = xstrdup(filter);
- for (cp=s; *cp; cp++)
- {
- if (isspace(*cp))
- {
- *cp = '\0';
- break;
- }
- }
- if (!isfile(s))
- {
- error (0, errno, "cannot find pre-tag filter '%s'", s);
- free(s);
- return (1);
- }
- free(s);
- }
- run_setup("%s %s %s %s",
- filter,
- symtag,
- delete ? "del" : force_tag_move ? "mov" : "add",
- repository);
- walklist(tlist, pretag_list_proc, NULL);
- return (run_exec(RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL|RUN_REALLY));
-}
-
-static void
-masterlist_delproc(p)
- Node *p;
-{
- struct master_lists *ml;
-
- ml = (struct master_lists *)p->data;
- dellist(&ml->tlist);
- free(ml);
- return;
-}
-
-static void
-tag_delproc(p)
- Node *p;
-{
- if (p->data != NULL)
- {
- free(p->data);
- p->data = NULL;
- }
- return;
-}
-
-static int
-pretag_list_proc(p, closure)
- Node *p;
- void *closure;
-{
- if (p->data != NULL)
- {
- run_arg(p->key);
- run_arg(p->data);
- }
- return (0);
-}
-
-
-/*
- * Called to tag a particular file (the currently checked out version is
- * tagged with the specified tag - or the specified tag is deleted).
- */
-/* ARGSUSED */
-static int
-tag_fileproc (file, update_dir, repository, entries, srcfiles)
- char *file;
- char *update_dir;
- char *repository;
- List *entries;
- List *srcfiles;
-{
- char *version, *oversion;
- char *nversion = NULL;
- char *rev;
- Vers_TS *vers;
- int retcode = 0;
-
- vers = Version_TS (repository, (char *) NULL, (char *) NULL, (char *) NULL,
- file, 0, 0, entries, srcfiles);
-
- if ((numtag != NULL) || (date != NULL))
- {
- nversion = RCS_getversion(vers->srcfile,
- numtag,
- date,
- force_tag_match, 0);
- if (nversion == NULL)
- {
- freevers_ts (&vers);
- return (0);
- }
- }
- if (delete)
- {
-
- /*
- * If -d is specified, "force_tag_match" is set, so that this call to
- * Version_Number() will return a NULL version string if the symbolic
- * tag does not exist in the RCS file.
- *
- * This is done here because it's MUCH faster than just blindly calling
- * "rcs" to remove the tag... trust me.
- */
-
- version = RCS_getversion (vers->srcfile, symtag, (char *) NULL, 1, 0);
- if (version == NULL || vers->srcfile == NULL)
- {
- freevers_ts (&vers);
- return (0);
- }
- free (version);
-
- if ((retcode = RCS_deltag(vers->srcfile->path, symtag, 1)) != 0)
- {
- if (!quiet)
- error (0, retcode == -1 ? errno : 0,
- "failed to remove tag %s from %s", symtag,
- vers->srcfile->path);
- freevers_ts (&vers);
- return (1);
- }
-
- /* warm fuzzies */
- if (!really_quiet)
- {
- if (update_dir[0])
- (void) printf ("D %s/%s\n", update_dir, file);
- else
- (void) printf ("D %s\n", file);
- }
-
- freevers_ts (&vers);
- return (0);
- }
-
- /*
- * If we are adding a tag, we need to know which version we have checked
- * out and we'll tag that version.
- */
- if (nversion == NULL)
- {
- version = vers->vn_user;
- }
- else
- {
- version = nversion;
- }
- if (version == NULL)
- {
- freevers_ts (&vers);
- return (0);
- }
- else if (strcmp (version, "0") == 0)
- {
- if (!quiet)
- error (0, 0, "couldn't tag added but un-commited file `%s'", file);
- freevers_ts (&vers);
- return (0);
- }
- else if (version[0] == '-')
- {
- if (!quiet)
- error (0, 0, "skipping removed but un-commited file `%s'", file);
- freevers_ts (&vers);
- return (0);
- }
- else if (vers->srcfile == NULL)
- {
- if (!quiet)
- error (0, 0, "cannot find revision control file for `%s'", file);
- freevers_ts (&vers);
- return (0);
- }
-
- /*
- * As an enhancement for the case where a tag is being re-applied to a
- * large number of files, make one extra call to Version_Number to see if
- * the tag is already set in the RCS file. If so, check to see if it
- * needs to be moved. If not, do nothing. This will likely save a lot of
- * time when simply moving the tag to the "current" head revisions of a
- * module -- which I have found to be a typical tagging operation.
- */
- rev = branch_mode ? RCS_magicrev (vers->srcfile, version) : version;
- oversion = RCS_getversion (vers->srcfile, symtag, (char *) NULL, 1, 0);
- if (oversion != NULL)
- {
- int isbranch = RCS_isbranch (file, symtag, srcfiles);
-
- /*
- * if versions the same and neither old or new are branches don't have
- * to do anything
- */
- if (strcmp (version, oversion) == 0 && !branch_mode && !isbranch)
- {
- free (oversion);
- freevers_ts (&vers);
- return (0);
- }
-
- if (!force_tag_move) { /* we're NOT going to move the tag */
- if (update_dir[0])
- (void) printf ("W %s/%s", update_dir, file);
- else
- (void) printf ("W %s", file);
-
- (void) printf (" : %s already exists on %s %s",
- symtag, isbranch ? "branch" : "version", oversion);
- (void) printf (" : NOT MOVING tag to %s %s\n",
- branch_mode ? "branch" : "version", rev);
- free (oversion);
- freevers_ts (&vers);
- return (0);
- }
- free (oversion);
- }
-
- if ((retcode = RCS_settag(vers->srcfile->path, symtag, rev)) != 0)
- {
- error (1, retcode == -1 ? errno : 0,
- "failed to set tag %s to revision %s in %s",
- symtag, rev, vers->srcfile->path);
- freevers_ts (&vers);
- return (1);
- }
-
- /* more warm fuzzies */
- if (!really_quiet)
- {
- if (update_dir[0])
- (void) printf ("T %s/%s\n", update_dir, file);
- else
- (void) printf ("T %s\n", file);
- }
-
- freevers_ts (&vers);
- if (nversion != NULL)
- {
- free(nversion);
- }
- return (0);
-}
-
-/*
- * Print a warm fuzzy message
- */
-/* ARGSUSED */
-static Dtype
-tag_dirproc (dir, repos, update_dir)
- char *dir;
- char *repos;
- char *update_dir;
-{
- if (!quiet)
- error (0, 0, "%s %s", delete ? "Untagging" : "Tagging", update_dir);
- return (R_PROCESS);
-}
diff --git a/gnu/usr.bin/cvs/cvs/update.c b/gnu/usr.bin/cvs/cvs/update.c
deleted file mode 100644
index 0dd0e1b4a3f3..000000000000
--- a/gnu/usr.bin/cvs/cvs/update.c
+++ /dev/null
@@ -1,1908 +0,0 @@
-/*
- * Copyright (c) 1992, Brian Berliner and Jeff Polk
- * Copyright (c) 1989-1992, Brian Berliner
- *
- * You may distribute under the terms of the GNU General Public License as
- * specified in the README file that comes with the CVS 1.4 kit.
- *
- * "update" updates the version in the present directory with respect to the RCS
- * repository. The present version must have been created by "checkout". The
- * user can keep up-to-date by calling "update" whenever he feels like it.
- *
- * The present version can be committed by "commit", but this keeps the version
- * in tact.
- *
- * Arguments following the options are taken to be file names to be updated,
- * rather than updating the entire directory.
- *
- * Modified or non-existent RCS files are checked out and reported as U
- * <user_file>
- *
- * Modified user files are reported as M <user_file>. If both the RCS file and
- * the user file have been modified, the user file is replaced by the result
- * of rcsmerge, and a backup file is written for the user in .#file.version.
- * If this throws up irreconcilable differences, the file is reported as C
- * <user_file>, and as M <user_file> otherwise.
- *
- * Files added but not yet committed are reported as A <user_file>. Files
- * removed but not yet committed are reported as R <user_file>.
- *
- * If the current directory contains subdirectories that hold concurrent
- * versions, these are updated too. If the -d option was specified, new
- * directories added to the repository are automatically created and updated
- * as well.
- */
-
-#include "cvs.h"
-#ifdef CLIENT_SUPPORT
-#include "update.h"
-#endif
-#ifdef SERVER_SUPPORT
-#include "md5.h"
-#endif
-
-#ifndef lint
-static const char rcsid[] = "$CVSid: @(#)update.c 1.95 94/10/22 $";
-USE(rcsid);
-#endif
-
-static int checkout_file PROTO((char *file, char *repository, List *entries,
- List *srcfiles, Vers_TS *vers_ts, char *update_dir));
-#ifdef SERVER_SUPPORT
-static int patch_file PROTO((char *file, char *repository, List *entries,
- List *srcfiles, Vers_TS *vers_ts, char *update_dir,
- int *docheckout, struct stat *file_info,
- unsigned char *checksum));
-#endif
-static int isemptydir PROTO((char *dir));
-static int merge_file PROTO((char *file, char *repository, List *entries,
- Vers_TS *vers, char *update_dir));
-static int scratch_file PROTO((char *file, char *repository, List * entries,
- char *update_dir));
-static Dtype update_dirent_proc PROTO((char *dir, char *repository, char *update_dir));
-static int update_dirleave_proc PROTO((char *dir, int err, char *update_dir));
-static int update_file_proc PROTO((char *file, char *update_dir, char *repository,
- List * entries, List * srcfiles));
-#ifndef CLIENT_SUPPORT
-static int update_filesdone_proc PROTO((int err, char *repository, char *update_dir));
-#endif
-static int write_letter PROTO((char *file, int letter, char *update_dir));
-static void ignore_files PROTO((List * ilist, char *update_dir));
-#ifdef SERVER_SUPPORT
-static void join_file PROTO((char *file, List *srcfiles, Vers_TS *vers_ts,
- char *update_dir, List *entries, char *repository));
-#else
-static void join_file PROTO((char *file, List *srcfiles, Vers_TS *vers_ts,
- char *update_dir, List *entries));
-#endif
-
-static char *options = NULL;
-static char *tag = NULL;
-static char *date = NULL;
-static char *join_rev1, *date_rev1;
-static char *join_rev2, *date_rev2;
-static int aflag = 0;
-static int force_tag_match = 1;
-static int update_build_dirs = 0;
-static int update_prune_dirs = 0;
-static int pipeout = 0;
-#ifdef SERVER_SUPPORT
-static int patches = 0;
-#endif
-#ifdef CLIENT_SUPPORT
-List *ignlist = (List *) NULL;
-#else
-static List *ignlist = (List *) NULL;
-#endif
-static time_t last_register_time;
-static const char *const update_usage[] =
-{
- "Usage: %s %s [-APdflRp] [-k kopt] [-r rev|-D date] [-j rev]\n",
- " [-I ign] [-W spec] [files...]\n",
- "\t-A\tReset any sticky tags/date/kopts.\n",
- "\t-P\tPrune empty directories.\n",
- "\t-d\tBuild directories, like checkout does.\n",
- "\t-f\tForce a head revision match if tag/date not found.\n",
- "\t-l\tLocal directory only, no recursion.\n",
- "\t-R\tProcess directories recursively.\n",
- "\t-p\tSend updates to standard output.\n",
- "\t-k kopt\tUse RCS kopt -k option on checkout.\n",
- "\t-r rev\tUpdate using specified revision/tag.\n",
- "\t-D date\tSet date to update from.\n",
- "\t-j rev\tMerge in changes made between current revision and rev.\n",
- "\t-I ign\tMore files to ignore (! to reset).\n",
- "\t-W spec\tWrappers specification line.\n",
- NULL
-};
-
-/*
- * update is the argv,argc based front end for arg parsing
- */
-int
-update (argc, argv)
- int argc;
- char **argv;
-{
- int c, err;
- int local = 0; /* recursive by default */
- int which; /* where to look for files and dirs */
-
- if (argc == -1)
- usage (update_usage);
-
- ign_setup ();
- wrap_setup ();
-
- /* parse the args */
- optind = 1;
- while ((c = getopt (argc, argv, "ApPflRQqduk:r:D:j:I:W:")) != -1)
- {
- switch (c)
- {
- case 'A':
- aflag = 1;
- break;
- case 'I':
- ign_add (optarg, 0);
- break;
- case 'W':
- wrap_add (optarg, 0);
- break;
- case 'k':
- if (options)
- free (options);
- options = RCS_check_kflag (optarg);
- break;
- case 'l':
- local = 1;
- break;
- case 'R':
- local = 0;
- break;
- case 'Q':
- case 'q':
-#ifdef SERVER_SUPPORT
- /* The CVS 1.5 client sends these options (in addition to
- Global_option requests), so we must ignore them. */
- if (!server_active)
-#endif
- error (1, 0,
- "-q or -Q must be specified before \"%s\"",
- command_name);
- break;
- case 'd':
- update_build_dirs = 1;
- break;
- case 'f':
- force_tag_match = 0;
- break;
- case 'r':
- tag = optarg;
- break;
- case 'D':
- date = Make_Date (optarg);
- break;
- case 'P':
- update_prune_dirs = 1;
- break;
- case 'p':
- pipeout = 1;
- noexec = 1; /* so no locks will be created */
- break;
- case 'j':
- if (join_rev2)
- error (1, 0, "only two -j options can be specified");
- if (join_rev1)
- join_rev2 = optarg;
- else
- join_rev1 = optarg;
- break;
- case 'u':
-#ifdef SERVER_SUPPORT
- if (server_active)
- patches = 1;
- else
-#endif
- usage (update_usage);
- break;
- case '?':
- default:
- usage (update_usage);
- break;
- }
- }
- argc -= optind;
- argv += optind;
-
-#ifdef CLIENT_SUPPORT
- if (client_active)
- {
- /* The first pass does the regular update. If we receive at least
- one patch which failed, we do a second pass and just fetch
- those files whose patches failed. */
- do
- {
- int status;
-
- start_server ();
-
- ign_setup ();
-
- if (local)
- send_arg("-l");
- if (update_build_dirs)
- send_arg("-d");
- if (pipeout)
- send_arg("-p");
- if (!force_tag_match)
- send_arg("-f");
- if (aflag)
- send_arg("-A");
- if (update_prune_dirs)
- send_arg("-P");
- client_prune_dirs = update_prune_dirs;
- option_with_arg ("-r", tag);
- if (date)
- client_senddate (date);
- if (join_rev1)
- option_with_arg ("-j", join_rev1);
- if (join_rev2)
- option_with_arg ("-j", join_rev2);
-
- /* If the server supports the command "update-patches", that means
- that it knows how to handle the -u argument to update, which
- means to send patches instead of complete files. */
- if (failed_patches == NULL)
- {
- struct request *rq;
-
- for (rq = requests; rq->name != NULL; rq++)
- {
- if (strcmp (rq->name, "update-patches") == 0)
- {
- if (rq->status == rq_supported)
- {
- send_arg("-u");
- }
- break;
- }
- }
- }
-
- if (failed_patches == NULL)
- send_files (argc, argv, local, aflag);
- else
- {
- int i;
-
- (void) printf ("%s client: refetching unpatchable files\n",
- program_name);
-
- if (toplevel_wd[0] != '\0'
- && chdir (toplevel_wd) < 0)
- {
- error (1, errno, "could not chdir to %s", toplevel_wd);
- }
-
- for (i = 0; i < failed_patches_count; i++)
- (void) unlink_file (failed_patches[i]);
- send_files (failed_patches_count, failed_patches, local,
- aflag);
- }
-
- failed_patches = NULL;
- failed_patches_count = 0;
-
- if (fprintf (to_server, "update\n") < 0)
- error (1, errno, "writing to server");
-
- status = get_responses_and_close ();
- if (status != 0)
- return status;
-
- } while (failed_patches != NULL);
-
- return 0;
- }
-#endif
-
- /*
- * If we are updating the entire directory (for real) and building dirs
- * as we go, we make sure there is no static entries file and write the
- * tag file as appropriate
- */
- if (argc <= 0 && !pipeout)
- {
- if (update_build_dirs)
- {
- if (unlink_file (CVSADM_ENTSTAT) < 0 && ! existence_error (errno))
- error (1, errno, "cannot remove file %s", CVSADM_ENTSTAT);
-#ifdef SERVER_SUPPORT
- if (server_active)
- server_clear_entstat (".", Name_Repository (NULL, NULL));
-#endif
- }
-
- /* keep the CVS/Tag file current with the specified arguments */
- if (aflag || tag || date)
- {
- WriteTag ((char *) NULL, tag, date);
-#ifdef SERVER_SUPPORT
- if (server_active)
- server_set_sticky (".", Name_Repository (NULL, NULL), tag, date);
-#endif
- }
- }
-
- /* look for files/dirs locally and in the repository */
- which = W_LOCAL | W_REPOS;
-
- /* look in the attic too if a tag or date is specified */
- if (tag != NULL || date != NULL || joining())
- which |= W_ATTIC;
-
- /* call the command line interface */
- err = do_update (argc, argv, options, tag, date, force_tag_match,
- local, update_build_dirs, aflag, update_prune_dirs,
- pipeout, which, join_rev1, join_rev2, (char *) NULL);
-
- /* free the space Make_Date allocated if necessary */
- if (date != NULL)
- free (date);
-
- return (err);
-}
-
-/*
- * Command line interface to update (used by checkout)
- */
-int
-do_update (argc, argv, xoptions, xtag, xdate, xforce, local, xbuild, xaflag,
- xprune, xpipeout, which, xjoin_rev1, xjoin_rev2, preload_update_dir)
- int argc;
- char **argv;
- char *xoptions;
- char *xtag;
- char *xdate;
- int xforce;
- int local;
- int xbuild;
- int xaflag;
- int xprune;
- int xpipeout;
- int which;
- char *xjoin_rev1;
- char *xjoin_rev2;
- char *preload_update_dir;
-{
- int err = 0;
- char *cp;
-
- /* fill in the statics */
- options = xoptions;
- tag = xtag;
- date = xdate;
- force_tag_match = xforce;
- update_build_dirs = xbuild;
- aflag = xaflag;
- update_prune_dirs = xprune;
- pipeout = xpipeout;
-
- /* setup the join support */
- join_rev1 = xjoin_rev1;
- join_rev2 = xjoin_rev2;
- if (join_rev1 && (cp = strchr (join_rev1, ':')) != NULL)
- {
- *cp++ = '\0';
- date_rev1 = Make_Date (cp);
- }
- else
- date_rev1 = (char *) NULL;
- if (join_rev2 && (cp = strchr (join_rev2, ':')) != NULL)
- {
- *cp++ = '\0';
- date_rev2 = Make_Date (cp);
- }
- else
- date_rev2 = (char *) NULL;
-
- /* call the recursion processor */
- err = start_recursion (update_file_proc, update_filesdone_proc,
- update_dirent_proc, update_dirleave_proc,
- argc, argv, local, which, aflag, 1,
- preload_update_dir, 1, 0);
-
- /* see if we need to sleep before returning */
- if (last_register_time)
- {
- time_t now;
-
- (void) time (&now);
- if (now == last_register_time)
- sleep (1); /* to avoid time-stamp races */
- }
-
- return (err);
-}
-
-/*
- * This is the callback proc for update. It is called for each file in each
- * directory by the recursion code. The current directory is the local
- * instantiation. file is the file name we are to operate on. update_dir is
- * set to the path relative to where we started (for pretty printing).
- * repository is the repository. entries and srcfiles are the pre-parsed
- * entries and source control files.
- *
- * This routine decides what needs to be done for each file and does the
- * appropriate magic for checkout
- */
-static int
-update_file_proc (file, update_dir, repository, entries, srcfiles)
- char *file;
- char *update_dir;
- char *repository;
- List *entries;
- List *srcfiles;
-{
- int retval;
- Ctype status;
- Vers_TS *vers;
-
- status = Classify_File (file, tag, date, options, force_tag_match,
- aflag, repository, entries, srcfiles, &vers,
- update_dir, pipeout);
- if (pipeout)
- {
- /*
- * We just return success without doing anything if any of the really
- * funky cases occur
- *
- * If there is still a valid RCS file, do a regular checkout type
- * operation
- */
- switch (status)
- {
- case T_UNKNOWN: /* unknown file was explicitly asked
- * about */
- case T_REMOVE_ENTRY: /* needs to be un-registered */
- case T_ADDED: /* added but not committed */
- retval = 0;
- break;
- case T_CONFLICT: /* old punt-type errors */
- retval = 1;
- break;
- case T_UPTODATE: /* file was already up-to-date */
- case T_NEEDS_MERGE: /* needs merging */
- case T_MODIFIED: /* locally modified */
- case T_REMOVED: /* removed but not committed */
- case T_CHECKOUT: /* needs checkout */
-#ifdef SERVER_SUPPORT
- case T_PATCH: /* needs patch */
-#endif
- retval = checkout_file (file, repository, entries, srcfiles,
- vers, update_dir);
- break;
-
- default: /* can't ever happen :-) */
- error (0, 0,
- "unknown file status %d for file %s", status, file);
- retval = 0;
- break;
- }
- }
- else
- {
- switch (status)
- {
- case T_UNKNOWN: /* unknown file was explicitly asked
- * about */
- case T_UPTODATE: /* file was already up-to-date */
- retval = 0;
- break;
- case T_CONFLICT: /* old punt-type errors */
- retval = 1;
- (void) write_letter (file, 'C', update_dir);
- break;
- case T_NEEDS_MERGE: /* needs merging */
- if (noexec)
- {
- retval = 1;
- (void) write_letter (file, 'C', update_dir);
- }
- else
- {
- if (wrap_merge_is_copy (file))
- /* Should we be warning the user that we are
- * overwriting the user's copy of the file? */
- retval = checkout_file (file, repository, entries,
- srcfiles, vers, update_dir);
- else
- retval = merge_file (file, repository, entries,
- vers, update_dir);
- }
- break;
- case T_MODIFIED: /* locally modified */
- retval = 0;
- if (vers->ts_conflict)
- {
- char *filestamp;
- int retcode;
-
- /*
- * If the timestamp has changed and no conflict indicators
- * are found, it isn't a 'C' any more.
- */
-#ifdef SERVER_SUPPORT
- if (server_active)
- retcode = vers->ts_conflict[0] != '=';
- else {
- filestamp = time_stamp (file);
- retcode = strcmp (vers->ts_conflict, filestamp);
- free (filestamp);
- }
-#else
- filestamp = time_stamp (file);
- retcode = strcmp (vers->ts_conflict, filestamp);
- free (filestamp);
-#endif
-
- if (retcode)
- {
- /*
- * If the timestamps differ, look for Conflict
- * indicators to see if 'C' anyway.
- */
- run_setup ("%s", GREP);
- run_arg (RCS_MERGE_PAT);
- run_arg (file);
- retcode = run_exec (RUN_TTY, DEVNULL,
- RUN_TTY,RUN_NORMAL);
- if (retcode == -1)
- {
- if (update_dir[0] == '\0')
- error (1, errno,
- "fork failed while examining conflict in `%s'",
- file);
- else
- error (1, errno,
- "fork failed while examining conflict in `%s/%s'",
- update_dir, file);
- }
- }
- if (!retcode)
- {
- (void) write_letter (file, 'C', update_dir);
- retval = 1;
- }
- else
- {
- /* Reregister to clear conflict flag. */
- Register (entries, file, vers->vn_rcs, vers->ts_rcs,
- vers->options, vers->tag,
- vers->date, (char *)0);
- }
- }
- if (!retval)
- retval = write_letter (file, 'M', update_dir);
- break;
-#ifdef SERVER_SUPPORT
- case T_PATCH: /* needs patch */
- if (patches)
- {
- int docheckout;
- struct stat file_info;
- unsigned char checksum[16];
-
- retval = patch_file (file, repository, entries, srcfiles,
- vers, update_dir, &docheckout,
- &file_info, checksum);
- if (! docheckout)
- {
- if (server_active && retval == 0)
- server_updated (file, update_dir, repository,
- SERVER_PATCHED, &file_info,
- checksum);
- break;
- }
- }
- /* Fall through. */
- /* If we're not running as a server, just check the
- file out. It's simpler and faster than starting up
- two new processes (diff and patch). */
- /* Fall through. */
-#endif
- case T_CHECKOUT: /* needs checkout */
- retval = checkout_file (file, repository, entries, srcfiles,
- vers, update_dir);
-#ifdef SERVER_SUPPORT
- if (server_active && retval == 0)
- server_updated (file, update_dir, repository,
- SERVER_UPDATED, (struct stat *) NULL,
- (unsigned char *) NULL);
-#endif
- break;
- case T_ADDED: /* added but not committed */
- retval = write_letter (file, 'A', update_dir);
- break;
- case T_REMOVED: /* removed but not committed */
- retval = write_letter (file, 'R', update_dir);
- break;
- case T_REMOVE_ENTRY: /* needs to be un-registered */
- retval = scratch_file (file, repository, entries, update_dir);
-#ifdef SERVER_SUPPORT
- if (server_active && retval == 0)
- server_updated (file, update_dir, repository,
- SERVER_UPDATED, (struct stat *) NULL,
- (unsigned char *) NULL);
-#endif
- break;
- default: /* can't ever happen :-) */
- error (0, 0,
- "unknown file status %d for file %s", status, file);
- retval = 0;
- break;
- }
- }
-
- /* only try to join if things have gone well thus far */
- if (retval == 0 && join_rev1)
-#ifdef SERVER_SUPPORT
- join_file (file, srcfiles, vers, update_dir, entries, repository);
-#else
- join_file (file, srcfiles, vers, update_dir, entries);
-#endif
-
- /* if this directory has an ignore list, add this file to it */
- if (ignlist)
- {
- Node *p;
-
- p = getnode ();
- p->type = FILES;
- p->key = xstrdup (file);
- if (addnode (ignlist, p) != 0)
- freenode (p);
- }
-
- freevers_ts (&vers);
- return (retval);
-}
-
-/*
- * update_filesdone_proc () is used
- */
-/* ARGSUSED */
-#ifdef CLIENT_SUPPORT
-/* Also used by client.c */
-int
-#else
-static int
-#endif
-update_filesdone_proc (err, repository, update_dir)
- int err;
- char *repository;
- char *update_dir;
-{
- /* if this directory has an ignore list, process it then free it */
- if (ignlist)
- {
- ignore_files (ignlist, update_dir);
- dellist (&ignlist);
- }
-
- /* Clean up CVS admin dirs if we are export */
-#ifdef CLIENT_SUPPORT
- /* In the client, we need to clean these up after we create them. Doing
- it here might would clean up the user's previous contents even on
- SIGINT which probably is bad. */
- if (!client_active && strcmp (command_name, "export") == 0)
-#else
- if (strcmp (command_name, "export") == 0)
-#endif
- {
- run_setup ("%s -fr", RM);
- run_arg (CVSADM);
- (void) run_exec (RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL);
- }
-#ifdef CVSADM_ROOT
-#ifdef SERVER_SUPPORT
- else if (!server_active && !pipeout)
-#else
- else if (!pipeout)
-#endif /* SERVER_SUPPORT */
- {
- /* If there is no CVS/Root file, add one */
-#ifdef CLIENT_SUPPORT
- if (!isfile (CVSADM_ROOT)
- /* but only if we want it */
- && ! (getenv ("CVS_IGNORE_REMOTE_ROOT") && strchr (CVSroot, ':'))
- )
-#else /* No CLIENT_SUPPORT */
- if (!isfile (CVSADM_ROOT))
-#endif /* No CLIENT_SUPPORT */
- Create_Root( (char *) NULL, CVSroot );
- }
-#endif /* CVSADM_ROOT */
-
- return (err);
-}
-
-/*
- * update_dirent_proc () is called back by the recursion processor before a
- * sub-directory is processed for update. In this case, update_dirent proc
- * will probably create the directory unless -d isn't specified and this is a
- * new directory. A return code of 0 indicates the directory should be
- * processed by the recursion code. A return of non-zero indicates the
- * recursion code should skip this directory.
- */
-static Dtype
-update_dirent_proc (dir, repository, update_dir)
- char *dir;
- char *repository;
- char *update_dir;
-{
- if (ignore_directory (update_dir))
- {
- /* print the warm fuzzy message */
- if (!quiet)
- error (0, 0, "Ignoring %s", update_dir);
- return R_SKIP_ALL;
- }
-
- if (!isdir (dir))
- {
- /* if we aren't building dirs, blow it off */
- if (!update_build_dirs)
- return (R_SKIP_ALL);
-
- if (noexec)
- {
- /* ignore the missing dir if -n is specified */
- error (0, 0, "New directory `%s' -- ignored", dir);
- return (R_SKIP_ALL);
- }
- else
- {
- /* otherwise, create the dir and appropriate adm files */
- make_directory (dir);
- Create_Admin (dir, update_dir, repository, tag, date);
- }
- }
-
- /*
- * If we are building dirs and not going to stdout, we make sure there is
- * no static entries file and write the tag file as appropriate
- */
- if (!pipeout)
- {
- if (update_build_dirs)
- {
- char tmp[PATH_MAX];
-
- (void) sprintf (tmp, "%s/%s", dir, CVSADM_ENTSTAT);
- if (unlink_file (tmp) < 0 && ! existence_error (errno))
- error (1, errno, "cannot remove file %s", tmp);
-#ifdef SERVER_SUPPORT
- if (server_active)
- server_clear_entstat (update_dir, repository);
-#endif
- }
-
- /* keep the CVS/Tag file current with the specified arguments */
- if (aflag || tag || date)
- {
- WriteTag (dir, tag, date);
-#ifdef SERVER_SUPPORT
- if (server_active)
- server_set_sticky (update_dir, repository, tag, date);
-#endif
- }
-
- /* initialize the ignore list for this directory */
- ignlist = getlist ();
- }
-
- /* print the warm fuzzy message */
- if (!quiet)
- error (0, 0, "Updating %s", update_dir);
-
- return (R_PROCESS);
-}
-
-/*
- * update_dirleave_proc () is called back by the recursion code upon leaving
- * a directory. It will prune empty directories if needed and will execute
- * any appropriate update programs.
- */
-/* ARGSUSED */
-static int
-update_dirleave_proc (dir, err, update_dir)
- char *dir;
- int err;
- char *update_dir;
-{
- FILE *fp;
-
- /* run the update_prog if there is one */
- if (err == 0 && !pipeout && !noexec &&
- (fp = fopen (CVSADM_UPROG, "r")) != NULL)
- {
- char *cp;
- char *repository;
- char line[MAXLINELEN];
-
- repository = Name_Repository ((char *) NULL, update_dir);
- if (fgets (line, sizeof (line), fp) != NULL)
- {
- if ((cp = strrchr (line, '\n')) != NULL)
- *cp = '\0';
- run_setup ("%s %s", line, repository);
- (void) printf ("%s %s: Executing '", program_name, command_name);
- run_print (stdout);
- (void) printf ("'\n");
- (void) run_exec (RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL);
- }
- (void) fclose (fp);
- free (repository);
- }
-
- /* FIXME: chdir ("..") loses with symlinks. */
- /* Prune empty dirs on the way out - if necessary */
- (void) chdir ("..");
- if (update_prune_dirs && isemptydir (dir))
- {
- run_setup ("%s -fr", RM);
- run_arg (dir);
- (void) run_exec (RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL);
- }
-
- return (err);
-}
-
-/*
- * Returns 1 if the argument directory is completely empty, other than the
- * existence of the CVS directory entry. Zero otherwise.
- */
-static int
-isemptydir (dir)
- char *dir;
-{
- DIR *dirp;
- struct dirent *dp;
-
- if ((dirp = opendir (dir)) == NULL)
- {
- error (0, 0, "cannot open directory %s for empty check", dir);
- return (0);
- }
- while ((dp = readdir (dirp)) != NULL)
- {
- if (strcmp (dp->d_name, ".") != 0 && strcmp (dp->d_name, "..") != 0 &&
- strcmp (dp->d_name, CVSADM) != 0)
- {
- (void) closedir (dirp);
- return (0);
- }
- }
- (void) closedir (dirp);
- return (1);
-}
-
-/*
- * scratch the Entries file entry associated with a file
- */
-static int
-scratch_file (file, repository, entries, update_dir)
- char *file;
- char *repository;
- List *entries;
- char *update_dir;
-{
- history_write ('W', update_dir, "", file, repository);
- Scratch_Entry (entries, file);
- (void) unlink_file (file);
- return (0);
-}
-
-/*
- * check out a file - essentially returns the result of the fork on "co".
- */
-static int
-checkout_file (file, repository, entries, srcfiles, vers_ts, update_dir)
- char *file;
- char *repository;
- List *entries;
- List *srcfiles;
- Vers_TS *vers_ts;
- char *update_dir;
-{
- char backup[PATH_MAX];
- int set_time, retval = 0;
- int retcode = 0;
-#ifdef DEATH_SUPPORT
- int file_is_dead;
-#endif
-
- /* don't screw with backup files if we're going to stdout */
- if (!pipeout)
- {
- (void) sprintf (backup, "%s/%s%s", CVSADM, CVSPREFIX, file);
- if (isfile (file))
- rename_file (file, backup);
- else
- (void) unlink_file (backup);
- }
-
-#ifdef DEATH_SUPPORT
- file_is_dead = RCS_isdead (vers_ts->srcfile, vers_ts->vn_rcs);
-
- if (!file_is_dead) {
-#endif
-
- run_setup ("%s%s -q -r%s %s", Rcsbin, RCS_CO, vers_ts->vn_tag,
- vers_ts->options);
-
- /*
- * if we are checking out to stdout, print a nice message to stderr, and
- * add the -p flag to the command
- */
- if (pipeout)
- {
- run_arg ("-p");
- if (!quiet)
- {
- (void) fprintf (stderr, "===================================================================\n");
- if (update_dir[0])
- (void) fprintf (stderr, "Checking out %s/%s\n",
- update_dir, file);
- else
- (void) fprintf (stderr, "Checking out %s\n", file);
- (void) fprintf (stderr, "RCS: %s\n", vers_ts->srcfile->path);
- (void) fprintf (stderr, "VERS: %s\n", vers_ts->vn_rcs);
- (void) fprintf (stderr, "***************\n");
- }
- }
-
- /* tack on the rcs and maybe the user file */
- run_arg (vers_ts->srcfile->path);
- if (!pipeout)
- run_arg (file);
-
-#ifdef DEATH_SUPPORT
- }
- if (file_is_dead || (retcode = run_exec (RUN_TTY, RUN_TTY, RUN_TTY,
-#else
- if ((retcode = run_exec (RUN_TTY, RUN_TTY, RUN_TTY,
-#endif
- (pipeout ? (RUN_NORMAL|RUN_REALLY) : RUN_NORMAL))) == 0)
- {
- if (!pipeout)
- {
- Vers_TS *xvers_ts;
-#ifdef DEATH_SUPPORT
- int resurrecting;
-
- resurrecting = 0;
-
- if (file_is_dead && joining())
- {
- /* when joining, we need to get dead files checked
- out. Try harder. */
- run_setup ("%s%s -q -r%s %s", Rcsbin, RCS_CO, vers_ts->vn_rcs,
- vers_ts->options);
-
- run_arg ("-f");
- run_arg (vers_ts->srcfile->path);
- run_arg (file);
- if ((retcode = run_exec (RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL)) != 0)
- {
- error (retcode == -1 ? 1 : 0, retcode == -1 ? errno : 0,
- "could not check out %s", file);
- (void) unlink_file (backup);
- return (retcode);
- }
- file_is_dead = 0;
- resurrecting = 1;
- }
-
- if (cvswrite == TRUE && !file_is_dead)
- xchmod (file, 1);
-#else /* No DEATH_SUPPORT */
- if (cvswrite == TRUE)
- xchmod (file, 1);
-#endif /* No DEATH_SUPPORT */
-
- /* set the time from the RCS file iff it was unknown before */
- if (vers_ts->vn_user == NULL ||
- strncmp (vers_ts->ts_rcs, "Initial", 7) == 0)
- {
- set_time = 1;
- }
- else
- set_time = 0;
-
- wrap_fromcvs_process_file (file);
-
- xvers_ts = Version_TS (repository, options, tag, date, file,
- force_tag_match, set_time, entries, srcfiles);
- if (strcmp (xvers_ts->options, "-V4") == 0)
- xvers_ts->options[0] = '\0';
- /* If no keyword expansion was specified on command line,
- use whatever was in the file. This is how we tell the client
- whether a file is binary. */
- if (xvers_ts->options[0] == '\0')
- {
- if (vers_ts->srcfile->expand != NULL)
- {
- free (xvers_ts->options);
- xvers_ts->options =
- xmalloc (strlen (vers_ts->srcfile->expand) + 3);
- strcpy (xvers_ts->options, "-k");
- strcat (xvers_ts->options, vers_ts->srcfile->expand);
- }
- }
-
- (void) time (&last_register_time);
-
-#ifdef DEATH_SUPPORT
- if (file_is_dead)
- {
- if (xvers_ts->vn_user != NULL)
- {
- if (update_dir[0] == '\0')
- error (0, 0,
- "warning: %s is not (any longer) pertinent",
- file);
- else
- error (0, 0,
- "warning: %s/%s is not (any longer) pertinent",
- update_dir, file);
- }
- Scratch_Entry (entries, file);
- if (unlink_file (file) < 0 && ! existence_error (errno))
- {
- if (update_dir[0] == '\0')
- error (0, errno, "cannot remove %s", file);
- else
- error (0, errno, "cannot remove %s/%s", update_dir,
- file);
- }
- }
- else
- Register (entries, file,
- resurrecting ? "0" : xvers_ts->vn_rcs,
- xvers_ts->ts_user, xvers_ts->options,
- xvers_ts->tag, xvers_ts->date,
- (char *)0); /* Clear conflict flag on fresh checkout */
-#else /* No DEATH_SUPPORT */
- Register (entries, file, xvers_ts->vn_rcs, xvers_ts->ts_user,
- xvers_ts->options, xvers_ts->tag, xvers_ts->date,
- (char *)0); /* Clear conflict flag on fresh checkout */
-#endif /* No DEATH_SUPPORT */
-
- /* fix up the vers structure, in case it is used by join */
- if (join_rev1)
- {
- if (vers_ts->vn_user != NULL)
- free (vers_ts->vn_user);
- if (vers_ts->vn_rcs != NULL)
- free (vers_ts->vn_rcs);
- vers_ts->vn_user = xstrdup (xvers_ts->vn_rcs);
- vers_ts->vn_rcs = xstrdup (xvers_ts->vn_rcs);
- }
-
- /* If this is really Update and not Checkout, recode history */
- if (strcmp (command_name, "update") == 0)
- history_write ('U', update_dir, xvers_ts->vn_rcs, file,
- repository);
-
- freevers_ts (&xvers_ts);
-
-#ifdef DEATH_SUPPORT
- if (!really_quiet && !file_is_dead)
-#else
- if (!really_quiet)
-#endif
- {
- if (update_dir[0])
- (void) printf ("U %s/%s\n", update_dir, file);
- else
- (void) printf ("U %s\n", file);
- }
- }
- }
- else
- {
- int old_errno = errno; /* save errno value over the rename */
-
- if (!pipeout && isfile (backup))
- rename_file (backup, file);
-
- error (retcode == -1 ? 1 : 0, retcode == -1 ? old_errno : 0,
- "could not check out %s", file);
-
- retval = retcode;
- }
-
- if (!pipeout)
- (void) unlink_file (backup);
-
- return (retval);
-}
-
-#ifdef SERVER_SUPPORT
-/* Patch a file. Runs rcsdiff. This is only done when running as the
- * server. The hope is that the diff will be smaller than the file
- * itself.
- */
-static int
-patch_file (file, repository, entries, srcfiles, vers_ts, update_dir,
- docheckout, file_info, checksum)
- char *file;
- char *repository;
- List *entries;
- List *srcfiles;
- Vers_TS *vers_ts;
- char *update_dir;
- int *docheckout;
- struct stat *file_info;
- unsigned char *checksum;
-{
- char backup[PATH_MAX];
- char file1[PATH_MAX];
- char file2[PATH_MAX];
- int retval = 0;
- int retcode = 0;
- int fail;
- FILE *e;
-
- *docheckout = 0;
-
- if (pipeout || joining ())
- {
- *docheckout = 1;
- return 0;
- }
-
- (void) sprintf (backup, "%s/%s%s", CVSADM, CVSPREFIX, file);
- if (isfile (file))
- rename_file (file, backup);
- else
- (void) unlink_file (backup);
-
- (void) sprintf (file1, "%s/%s%s-1", CVSADM, CVSPREFIX, file);
- (void) sprintf (file2, "%s/%s%s-2", CVSADM, CVSPREFIX, file);
-
- fail = 0;
-
- /* We need to check out both revisions first, to see if either one
- has a trailing newline. Because of this, we don't use rcsdiff,
- but just use diff. */
- run_setup ("%s%s -q -p -r%s %s %s", Rcsbin, RCS_CO, vers_ts->vn_user,
- vers_ts->options, vers_ts->srcfile->path);
- if (run_exec (RUN_TTY, file1, RUN_TTY, RUN_NORMAL) != 0)
- fail = 1;
- else
- {
- e = fopen (file1, "r");
- if (e == NULL)
- fail = 1;
- else
- {
- if (fseek (e, (long) -1, SEEK_END) == 0
- && getc (e) != '\n')
- {
- fail = 1;
- }
- fclose (e);
- }
- }
-
- if (! fail)
- {
- /* Check it out into file, and then move to file2, so that we
- can get the right modes into *FILE_INFO. We can't check it
- out directly into file2 because co doesn't understand how
- to do that. */
- run_setup ("%s%s -q -r%s %s %s %s", Rcsbin, RCS_CO, vers_ts->vn_rcs,
- vers_ts->options, vers_ts->srcfile->path, file);
- if (run_exec (RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL) != 0)
- fail = 1;
- else
- {
- if (!isreadable (file))
- {
- /* File is dead. */
- fail = 1;
- }
- else
- {
- rename_file (file, file2);
- if (cvswrite == TRUE)
- xchmod (file2, 1);
- e = fopen (file2, "r");
- if (e == NULL)
- fail = 1;
- else
- {
- struct MD5Context context;
- int nl;
- unsigned char buf[8192];
- unsigned len;
-
- nl = 0;
-
- /* Compute the MD5 checksum and make sure there is
- a trailing newline. */
- MD5Init (&context);
- while ((len = fread (buf, 1, sizeof buf, e)) != 0)
- {
- nl = buf[len - 1] == '\n';
- MD5Update (&context, buf, len);
- }
- MD5Final (checksum, &context);
-
- if (ferror (e) || ! nl)
- {
- fail = 1;
- }
-
- fclose (e);
- }
- }
- }
- }
-
- if (! fail)
- {
- /* FIXME: This whole thing with diff/patch is rather more
- convoluted than necessary (lots of forks and execs, need to
- worry about versions of diff and patch, etc.). Also, we
- send context lines which aren't needed (in the rare case in
- which the diff doesn't apply, the checksum would catches it).
- Solution perhaps is to librarify the RCS routines which apply
- deltas or something equivalent. */
- /* This is -c, not -u, because we have no way of knowing which
- DIFF is in use. */
- run_setup ("%s -c %s %s", DIFF, file1, file2);
-
- /* A retcode of 0 means no differences. 1 means some differences. */
- if ((retcode = run_exec (RUN_TTY, file, RUN_TTY, RUN_NORMAL)) != 0
- && retcode != 1)
- {
- fail = 1;
- }
- else
- {
-#define BINARY "Binary"
- char buf[sizeof BINARY];
- unsigned int c;
-
- /* Check the diff output to make sure patch will be handle it. */
- e = fopen (file, "r");
- if (e == NULL)
- error (1, errno, "could not open diff output file %s", file);
- c = fread (buf, 1, sizeof BINARY - 1, e);
- buf[c] = '\0';
- if (strcmp (buf, BINARY) == 0)
- {
- /* These are binary files. We could use diff -a, but
- patch can't handle that. */
- fail = 1;
- }
- fclose (e);
- }
- }
-
- if (! fail)
- {
- Vers_TS *xvers_ts;
-
- /* This stuff is just copied blindly from checkout_file. I
- don't really know what it does. */
- xvers_ts = Version_TS (repository, options, tag, date, file,
- force_tag_match, 0, entries, srcfiles);
- if (strcmp (xvers_ts->options, "-V4") == 0)
- xvers_ts->options[0] = '\0';
-
- Register (entries, file, xvers_ts->vn_rcs,
- xvers_ts->ts_user, xvers_ts->options,
- xvers_ts->tag, xvers_ts->date, NULL);
-
- if (stat (file2, file_info) < 0)
- error (1, errno, "could not stat %s", file2);
-
- /* If this is really Update and not Checkout, recode history */
- if (strcmp (command_name, "update") == 0)
- history_write ('P', update_dir, xvers_ts->vn_rcs, file,
- repository);
-
- freevers_ts (&xvers_ts);
-
- if (!really_quiet)
- {
- if (update_dir[0])
- (void) printf ("P %s/%s\n", update_dir, file);
- else
- (void) printf ("P %s\n", file);
- }
- }
- else
- {
- int old_errno = errno; /* save errno value over the rename */
-
- if (isfile (backup))
- rename_file (backup, file);
-
- if (retcode != 0 && retcode != 1)
- error (retcode == -1 ? 1 : 0, retcode == -1 ? old_errno : 0,
- "could not diff %s", file);
-
- *docheckout = 1;
- retval = retcode;
- }
-
- (void) unlink_file (backup);
- (void) unlink_file (file1);
- (void) unlink_file (file2);
-
- return (retval);
-}
-#endif
-
-/*
- * Several of the types we process only print a bit of information consisting
- * of a single letter and the name.
- */
-static int
-write_letter (file, letter, update_dir)
- char *file;
- int letter;
- char *update_dir;
-{
- if (!really_quiet)
- {
- if (update_dir[0])
- (void) printf ("%c %s/%s\n", letter, update_dir, file);
- else
- (void) printf ("%c %s\n", letter, file);
- }
- return (0);
-}
-
-/*
- * Do all the magic associated with a file which needs to be merged
- */
-static int
-merge_file (file, repository, entries, vers, update_dir)
- char *file;
- char *repository;
- List *entries;
- Vers_TS *vers;
- char *update_dir;
-{
- char user[PATH_MAX];
- char backup[PATH_MAX];
- int status;
- int retcode = 0;
-
- /*
- * The users currently modified file is moved to a backup file name
- * ".#filename.version", so that it will stay around for a few days
- * before being automatically removed by some cron daemon. The "version"
- * is the version of the file that the user was most up-to-date with
- * before the merge.
- */
- (void) sprintf (backup, "%s%s.%s", BAKPREFIX, file, vers->vn_user);
- if (update_dir[0])
- (void) sprintf (user, "%s/%s", update_dir, file);
- else
- (void) strcpy (user, file);
-
- (void) unlink_file (backup);
- copy_file (file, backup);
- xchmod (file, 1);
-
- status = RCS_merge(vers->srcfile->path,
- vers->options, vers->vn_user, vers->vn_rcs);
- if (status != 0 && status != 1)
- {
- error (0, status == -1 ? errno : 0,
- "could not merge revision %s of %s", vers->vn_user, user);
- error (status == -1 ? 1 : 0, 0, "restoring %s from backup file %s",
- user, backup);
- rename_file (backup, file);
- return (1);
- }
-
- if (strcmp (vers->options, "-V4") == 0)
- vers->options[0] = '\0';
- (void) time (&last_register_time);
- {
- char *cp = 0;
-
- if (status)
- cp = time_stamp (file);
- Register (entries, file, vers->vn_rcs, vers->ts_rcs, vers->options,
- vers->tag, vers->date, cp);
- if (cp)
- free (cp);
- }
-
- /* fix up the vers structure, in case it is used by join */
- if (join_rev1)
- {
- if (vers->vn_user != NULL)
- free (vers->vn_user);
- vers->vn_user = xstrdup (vers->vn_rcs);
- }
-
-#ifdef SERVER_SUPPORT
- /* Send the new contents of the file before the message. If we
- wanted to be totally correct, we would have the client write
- the message only after the file has safely been written. */
- if (server_active)
- {
- server_copy_file (file, update_dir, repository, backup);
- server_updated (file, update_dir, repository, SERVER_MERGED,
- (struct stat *) NULL, (unsigned char *) NULL);
- }
-#endif
-
- if (!noexec && !xcmp (backup, file))
- {
- printf ("%s already contains the differences between %s and %s\n",
- user, vers->vn_user, vers->vn_rcs);
- history_write ('G', update_dir, vers->vn_rcs, file, repository);
- return (0);
- }
-
- if (status == 1)
- {
- if (!noexec)
- error (0, 0, "conflicts found in %s", user);
-
- if (!really_quiet)
- (void) printf ("C %s\n", user);
-
- history_write ('C', update_dir, vers->vn_rcs, file, repository);
-
- }
- else if (retcode == -1)
- {
- error (1, errno, "fork failed while examining update of %s", user);
- }
- else
- {
- if (!really_quiet)
- (void) printf ("M %s\n", user);
- history_write ('G', update_dir, vers->vn_rcs, file, repository);
- }
- return (0);
-}
-
-/*
- * Do all the magic associated with a file which needs to be joined
- * (-j option)
- */
-static void
-#ifdef SERVER_SUPPORT
-join_file (file, srcfiles, vers, update_dir, entries, repository)
- char *repository;
-#else
-join_file (file, srcfiles, vers, update_dir, entries)
-#endif
- char *file;
- List *srcfiles;
- Vers_TS *vers;
- char *update_dir;
- List *entries;
-{
- char user[PATH_MAX];
- char backup[PATH_MAX];
- char *options;
- int status;
-
- char *rev1;
- char *rev2;
- char *jrev1;
- char *jrev2;
- char *jdate1;
- char *jdate2;
-
- jrev1 = join_rev1;
- jrev2 = join_rev2;
- jdate1 = date_rev1;
- jdate2 = date_rev2;
-
- if (wrap_merge_is_copy (file))
- {
- /* FIXME: Should be including update_dir in message. */
- error (0, 0,
- "Cannot merge %s because it is a merge-by-copy file.", file);
- return;
- }
-
- /* determine if we need to do anything at all */
- if (vers->srcfile == NULL ||
- vers->srcfile->path == NULL)
- {
- return;
- }
-
- /* in all cases, use two revs. */
-
- /* if only one rev is specified, it becomes the second rev */
- if (jrev2 == NULL)
- {
- jrev2 = jrev1;
- jrev1 = NULL;
- jdate2 = jdate1;
- jdate1 = NULL;
- }
-
- /* The file in the working directory doesn't exist in CVS/Entries.
- FIXME: Shouldn't this case result in additional processing (if
- the file was added going from rev1 to rev2, then do the equivalent
- of a "cvs add")? (yes; easier said than done.. :-) */
- if (vers->vn_user == NULL)
- {
- /* No merge possible YET. */
- if (jdate2 != NULL)
- error (0, 0,
- "file %s is present in revision %s as of %s",
- file, jrev2, jdate2);
- else
- error (0, 0,
- "file %s is present in revision %s",
- file, jrev2);
- return;
- }
-
- /* Fix for bug CVS/193:
- * Used to dump core if the file had been removed on the current branch.
- */
- if (strcmp(vers->vn_user, "0") == 0)
- {
- error(0, 0,
- "file %s has been deleted",
- file);
- return;
- }
-
- /* convert the second rev spec, walking branches and dates. */
-
- rev2 = RCS_getversion (vers->srcfile, jrev2, jdate2, 1, 0);
- if (rev2 == NULL)
- {
- if (!quiet)
- {
- if (jdate2 != NULL)
- error (0, 0,
- "cannot find revision %s as of %s in file %s",
- jrev2, jdate2, file);
- else
- error (0, 0,
- "cannot find revision %s in file %s",
- jrev2, file);
- }
- return;
- }
-
- /* skip joining identical revs */
- if (strcmp (rev2, vers->vn_user) == 0)
- {
- /* No merge necessary. */
- free (rev2);
- return;
- }
-
- if (jrev1 == NULL)
- {
- char *tst;
- /* if the first rev is missing, then it is implied to be the
- greatest common ancestor of both the join rev, and the
- checked out rev. */
-
- /* FIXME: What is this check for '!' about? If it is legal to
- have '!' in the first character of vn_user, it isn't
- documented at struct vers_ts in cvs.h. */
- tst = vers->vn_user;
- if (*tst == '!')
- {
- /* file was dead. merge anyway and pretend it's been
- added. */
- ++tst;
- Register (entries, file, "0", vers->ts_user, vers->options,
- vers->tag, (char *) 0, (char *) 0);
- }
- rev1 = gca (tst, rev2);
- if (rev1 == NULL)
- {
- /* this should not be possible */
- error (0, 0, "bad gca");
- abort();
- }
-
- tst = RCS_gettag (vers->srcfile, rev2, 1, 0);
- if (tst == NULL)
- {
- /* this should not be possible. */
- error (0, 0, "cannot find gca");
- abort();
- }
-
- free (tst);
-
- /* these two cases are noops */
- if (strcmp (rev1, rev2) == 0)
- {
- free (rev1);
- free (rev2);
- return;
- }
- }
- else
- {
- /* otherwise, convert the first rev spec, walking branches and
- dates. */
-
- rev1 = RCS_getversion (vers->srcfile, jrev1, jdate1, 1, 0);
- if (rev1 == NULL)
- {
- if (!quiet) {
- if (jdate1 != NULL)
- error (0, 0,
- "cannot find revision %s as of %s in file %s",
- jrev1, jdate1, file);
- else
- error (0, 0,
- "cannot find revision %s in file %s",
- jrev1, file);
- }
- return;
- }
- }
-
- /* do the join */
-
-#if 0
- dome {
- /* special handling when two revisions are specified */
- if (join_rev1 && join_rev2)
- {
- rev = RCS_getversion (vers->srcfile, join_rev2, date_rev2, 1, 0);
- if (rev == NULL)
- {
- if (!quiet && date_rev2 == NULL)
- error (0, 0,
- "cannot find revision %s in file %s", join_rev2, file);
- return;
- }
-
- baserev = RCS_getversion (vers->srcfile, join_rev1, date_rev1, 1, 0);
- if (baserev == NULL)
- {
- if (!quiet && date_rev1 == NULL)
- error (0, 0,
- "cannot find revision %s in file %s", join_rev1, file);
- free (rev);
- return;
- }
-
- /*
- * nothing to do if:
- * second revision matches our BASE revision (vn_user) &&
- * both revisions are on the same branch
- */
- if (strcmp (vers->vn_user, rev) == 0 &&
- numdots (baserev) == numdots (rev))
- {
- /* might be the same branch. take a real look */
- char *dot = strrchr (baserev, '.');
- int len = (dot - baserev) + 1;
-
- if (strncmp (baserev, rev, len) == 0)
- return;
- }
- }
- else
- {
- rev = RCS_getversion (vers->srcfile, join_rev1, date_rev1, 1, 0);
- if (rev == NULL)
- return;
- if (strcmp (rev, vers->vn_user) == 0) /* no merge necessary */
- {
- free (rev);
- return;
- }
-
- baserev = RCS_whatbranch (file, join_rev1, srcfiles);
- if (baserev)
- {
- char *cp;
-
- /* we get a branch -- turn it into a revision, or NULL if trunk */
- if ((cp = strrchr (baserev, '.')) == NULL)
- {
- free (baserev);
- baserev = (char *) NULL;
- }
- else
- *cp = '\0';
- }
- }
- if (baserev && strcmp (baserev, rev) == 0)
- {
- /* they match -> nothing to do */
- free (rev);
- free (baserev);
- return;
- }
- }
-#endif
-
- /* OK, so we have two revisions; continue on */
-
-#ifdef SERVER_SUPPORT
- if (server_active && !isreadable (file))
- {
- int retcode;
- /* The file is up to date. Need to check out the current contents. */
- run_setup ("%s%s -q -r%s", Rcsbin, RCS_CO, vers->vn_user);
- run_arg (vers->srcfile->path);
- retcode = run_exec (RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL);
- if (retcode != 0)
- error (1, retcode == -1 ? errno : 0,
- "failed to check out %s file", file);
- }
-#endif
-
- /*
- * The users currently modified file is moved to a backup file name
- * ".#filename.version", so that it will stay around for a few days
- * before being automatically removed by some cron daemon. The "version"
- * is the version of the file that the user was most up-to-date with
- * before the merge.
- */
- (void) sprintf (backup, "%s%s.%s", BAKPREFIX, file, vers->vn_user);
- if (update_dir[0])
- (void) sprintf (user, "%s/%s", update_dir, file);
- else
- (void) strcpy (user, file);
-
- (void) unlink_file (backup);
- copy_file (file, backup);
- xchmod (file, 1);
-
- options = vers->options;
-#ifdef HAVE_RCS5
-#if 0
- if (*options == '\0')
- options = "-kk"; /* to ignore keyword expansions */
-#endif
-#endif
-
- status = RCS_merge (vers->srcfile->path, options, rev1, rev2);
- if (status != 0 && status != 1)
- {
- error (0, status == -1 ? errno : 0,
- "could not merge revision %s of %s", rev2, user);
- error (status == -1 ? 1 : 0, 0, "restoring %s from backup file %s",
- user, backup);
- rename_file (backup, file);
- }
- free (rev1);
- free (rev2);
-
-#ifdef SERVER_SUPPORT
- /*
- * If we're in server mode, then we need to re-register the file
- * even if there were no conflicts (status == 0).
- * This tells server_updated() to send the modified file back to
- * the client.
- */
- if (status == 1 || (status == 0 && server_active))
-#else
- if (status == 1)
-#endif
- {
- char *cp = 0;
-
- if (status)
- cp = time_stamp (file);
- Register (entries, file, vers->vn_rcs, vers->ts_rcs, vers->options,
- vers->tag, vers->date, cp);
- if (cp)
- free(cp);
- }
-
-#ifdef SERVER_SUPPORT
- if (server_active)
- {
- server_copy_file (file, update_dir, repository, backup);
- server_updated (file, update_dir, repository, SERVER_MERGED,
- (struct stat *) NULL, (unsigned char *) NULL);
- }
-#endif
-}
-
-/*
- * Process the current directory, looking for files not in ILIST and not on
- * the global ignore list for this directory.
- */
-static void
-ignore_files (ilist, update_dir)
- List *ilist;
- char *update_dir;
-{
- DIR *dirp;
- struct dirent *dp;
- struct stat sb;
- char *file;
- char *xdir;
-
- /* we get called with update_dir set to "." sometimes... strip it */
- if (strcmp (update_dir, ".") == 0)
- xdir = "";
- else
- xdir = update_dir;
-
- dirp = opendir (".");
- if (dirp == NULL)
- return;
-
- ign_add_file (CVSDOTIGNORE, 1);
- wrap_add_file (CVSDOTWRAPPER, 1);
-
- while ((dp = readdir (dirp)) != NULL)
- {
- file = dp->d_name;
- if (strcmp (file, ".") == 0 || strcmp (file, "..") == 0)
- continue;
- if (findnode (ilist, file) != NULL)
- continue;
-
- if (
-#ifdef DT_DIR
- dp->d_type != DT_UNKNOWN ||
-#endif
- lstat(file, &sb) != -1)
- {
-
- if (
-#ifdef DT_DIR
- dp->d_type == DT_DIR || dp->d_type == DT_UNKNOWN &&
-#endif
- S_ISDIR(sb.st_mode))
- {
- char temp[PATH_MAX];
-
- (void) sprintf (temp, "%s/%s", file, CVSADM);
- if (isdir (temp))
- continue;
- }
-#ifdef S_ISLNK
- else if (
-#ifdef DT_DIR
- dp->d_type == DT_LNK || dp->d_type == DT_UNKNOWN &&
-#endif
- S_ISLNK(sb.st_mode))
- {
- continue;
- }
-#endif
- }
-
- if (ign_name (file))
- continue;
- (void) write_letter (file, '?', xdir);
- }
- (void) closedir (dirp);
-}
-
-int
-joining ()
-{
- return (join_rev1 != NULL);
-}
diff --git a/gnu/usr.bin/cvs/cvs/update.h b/gnu/usr.bin/cvs/cvs/update.h
deleted file mode 100644
index 68c91d55ab93..000000000000
--- a/gnu/usr.bin/cvs/cvs/update.h
+++ /dev/null
@@ -1,9 +0,0 @@
-/* Definitions of routines shared between local and client/server
- "update" code. */
-
-/* List of files that we have either processed or are willing to
- ignore. Any file not on this list gets a question mark printed. */
-extern List *ignlist;
-
-extern int
-update_filesdone_proc PROTO((int err, char *repository, char *update_dir));
diff --git a/gnu/usr.bin/cvs/cvs/vers_ts.c b/gnu/usr.bin/cvs/cvs/vers_ts.c
deleted file mode 100644
index ebb7ca8d305f..000000000000
--- a/gnu/usr.bin/cvs/cvs/vers_ts.c
+++ /dev/null
@@ -1,326 +0,0 @@
-/*
- * Copyright (c) 1992, Brian Berliner and Jeff Polk
- * Copyright (c) 1989-1992, Brian Berliner
- *
- * You may distribute under the terms of the GNU General Public License as
- * specified in the README file that comes with the CVS 1.4 kit.
- */
-
-#include "cvs.h"
-
-#ifndef lint
-static const char rcsid[] = "$CVSid: @(#)vers_ts.c 1.45 94/10/07 $";
-USE(rcsid);
-#endif
-
-#ifdef SERVER_SUPPORT
-static void time_stamp_server PROTO((char *, Vers_TS *));
-#endif
-
-/*
- * Fill in and return a Vers_TS structure "user" is the name of the local
- * file; entries is the entries file - preparsed for our pleasure. xfiles is
- * all source code control files, preparsed for our pleasure
- */
-Vers_TS *
-Version_TS (repository, options, tag, date, user, force_tag_match,
- set_time, entries, xfiles)
- char *repository;
- char *options;
- char *tag;
- char *date;
- char *user;
- int force_tag_match;
- int set_time;
- List *entries;
- List *xfiles;
-{
- Node *p;
- RCSNode *rcsdata;
- Vers_TS *vers_ts;
- struct stickydirtag *sdtp;
-
- /* get a new Vers_TS struct */
- vers_ts = (Vers_TS *) xmalloc (sizeof (Vers_TS));
- memset ((char *) vers_ts, 0, sizeof (*vers_ts));
-
- /*
- * look up the entries file entry and fill in the version and timestamp
- * if entries is NULL, there is no entries file so don't bother trying to
- * look it up (used by checkout -P)
- */
- if (entries == NULL)
- {
- sdtp = NULL;
- p = NULL;
- }
- else
- {
- p = findnode (entries, user);
- sdtp = (struct stickydirtag *) entries->list->data; /* list-private */
- }
-
- if (p != NULL)
- {
- Entnode *entdata = (Entnode *) p->data;
-
- vers_ts->vn_user = xstrdup (entdata->version);
- vers_ts->ts_rcs = xstrdup (entdata->timestamp);
- vers_ts->ts_conflict = xstrdup (entdata->conflict);
- if (!tag)
- {
- if (!(sdtp && sdtp->aflag))
- vers_ts->tag = xstrdup (entdata->tag);
- }
- if (!date)
- {
- if (!(sdtp && sdtp->aflag))
- vers_ts->date = xstrdup (entdata->date);
- }
- if (!options || (options && *options == '\0'))
- {
- if (!(sdtp && sdtp->aflag))
- vers_ts->options = xstrdup (entdata->options);
- }
- vers_ts->entdata = entdata;
- }
-
- /*
- * -k options specified on the command line override (and overwrite)
- * options stored in the entries file
- */
- if (options)
- vers_ts->options = xstrdup (options);
- else if (sdtp && sdtp->aflag == 0)
- {
- if (!vers_ts->options)
- vers_ts->options = xstrdup (sdtp->options);
- }
- if (!vers_ts->options)
- vers_ts->options = xstrdup ("");
-
- /*
- * if tags were specified on the command line, they override what is in
- * the Entries file
- */
- if (tag || date)
- {
- vers_ts->tag = xstrdup (tag);
- vers_ts->date = xstrdup (date);
- }
- else if (!vers_ts->entdata && (sdtp && sdtp->aflag == 0))
- {
- if (!vers_ts->tag)
- vers_ts->tag = xstrdup (sdtp->tag);
- if (!vers_ts->date)
- vers_ts->date = xstrdup (sdtp->date);
- }
-
- /* Now look up the info on the source controlled file */
- if (xfiles != (List *) NULL)
- {
- p = findnode (xfiles, user);
- if (p != NULL)
- {
- rcsdata = (RCSNode *) p->data;
- rcsdata->refcount++;
- }
- else
- rcsdata = NULL;
- }
- else if (repository != NULL)
- rcsdata = RCS_parse (user, repository);
- else
- rcsdata = NULL;
-
- if (rcsdata != NULL)
- {
- /* squirrel away the rcsdata pointer for others */
- vers_ts->srcfile = rcsdata;
-
-#ifndef DEATH_SUPPORT
- /* (is this indeed death support? I haven't looked carefully). */
- /* get RCS version number into vn_rcs (if appropriate) */
- if (((vers_ts->tag || vers_ts->date) && force_tag_match) ||
- ((rcsdata->flags & VALID) && (rcsdata->flags & INATTIC) == 0))
- {
-#endif
- if (vers_ts->tag && strcmp (vers_ts->tag, TAG_BASE) == 0)
- {
- vers_ts->vn_rcs = xstrdup (vers_ts->vn_user);
- vers_ts->vn_tag = xstrdup (vers_ts->vn_user);
- }
- else
- {
- vers_ts->vn_rcs = RCS_getversion (rcsdata, vers_ts->tag,
- vers_ts->date, force_tag_match, 1);
- if (vers_ts->vn_rcs == NULL)
- vers_ts->vn_tag = NULL;
- else
- {
- char *colon = strchr (vers_ts->vn_rcs, ':');
- if (colon)
- {
- vers_ts->vn_tag = xstrdup (colon+1);
- *colon = '\0';
- }
- else
- vers_ts->vn_tag = xstrdup (vers_ts->vn_rcs);
- }
- }
-#ifndef DEATH_SUPPORT
- }
-#endif
-
- /*
- * If the source control file exists and has the requested revision,
- * get the Date the revision was checked in. If "user" exists, set
- * its mtime.
- */
- if (set_time)
- {
- struct utimbuf t;
-
- memset ((char *) &t, 0, sizeof (t));
- if (vers_ts->vn_rcs &&
- (t.actime = t.modtime = RCS_getrevtime (rcsdata,
- vers_ts->vn_rcs, (char *) 0, 0)) != -1)
- (void) utime (user, &t);
- }
- }
-
- /* get user file time-stamp in ts_user */
- if (entries != (List *) NULL)
- {
-#ifdef SERVER_SUPPORT
- if (server_active)
- time_stamp_server (user, vers_ts);
- else
-#endif
- vers_ts->ts_user = time_stamp (user);
- }
-
- return (vers_ts);
-}
-
-#ifdef SERVER_SUPPORT
-
-/* Set VERS_TS->TS_USER to time stamp for FILE. */
-
-/* Separate these out to keep the logic below clearer. */
-#define mark_lost(V) ((V)->ts_user = 0)
-#define mark_unchanged(V) ((V)->ts_user = xstrdup ((V)->ts_rcs))
-
-static void
-time_stamp_server (file, vers_ts)
- char *file;
- Vers_TS *vers_ts;
-{
- struct stat sb;
- char *cp;
-
- if (stat (file, &sb) < 0)
- {
- if (! existence_error (errno))
- error (1, errno, "cannot stat temp file");
- if (use_unchanged)
- {
- /* Missing file means lost or unmodified; check entries
- file to see which.
-
- XXX FIXME - If there's no entries file line, we
- wouldn't be getting the file at all, so consider it
- lost. I don't know that that's right, but it's not
- clear to me that either choice is. Besides, would we
- have an RCS string in that case anyways? */
- if (vers_ts->entdata == NULL)
- mark_lost (vers_ts);
- else if (vers_ts->entdata->timestamp
- && vers_ts->entdata->timestamp[0] == '=')
- mark_unchanged (vers_ts);
- else
- mark_lost (vers_ts);
- }
- else
- {
- /* Missing file in the temp directory means that the file
- was not modified. */
- mark_unchanged (vers_ts);
- }
- }
- else if (sb.st_mtime == 0)
- {
- if (use_unchanged)
- /* We shouldn't reach this case any more! */
- abort ();
-
- /* Special code used by server.c to indicate the file was lost. */
- mark_lost (vers_ts);
- }
- else
- {
- vers_ts->ts_user = xmalloc (25);
- cp = asctime (gmtime (&sb.st_mtime)); /* copy in the modify time */
- cp[24] = 0;
- (void) strcpy (vers_ts->ts_user, cp);
- }
-}
-
-#endif /* SERVER_SUPPORT */
-/*
- * Gets the time-stamp for the file "file" and returns it in space it
- * allocates
- */
-char *
-time_stamp (file)
- char *file;
-{
- struct stat sb;
- char *cp;
- char *ts;
-
- if (stat (file, &sb) < 0)
- {
- ts = NULL;
- }
- else
- {
- ts = xmalloc (25);
- cp = asctime (gmtime (&sb.st_mtime)); /* copy in the modify time */
- cp[24] = 0;
- (void) strcpy (ts, cp);
- }
-
- return (ts);
-}
-
-/*
- * free up a Vers_TS struct
- */
-void
-freevers_ts (versp)
- Vers_TS **versp;
-{
- if ((*versp)->srcfile)
- freercsnode (&((*versp)->srcfile));
- if ((*versp)->vn_user)
- free ((*versp)->vn_user);
- if ((*versp)->vn_rcs)
- free ((*versp)->vn_rcs);
- if ((*versp)->vn_tag)
- free ((*versp)->vn_tag);
- if ((*versp)->ts_user)
- free ((*versp)->ts_user);
- if ((*versp)->ts_rcs)
- free ((*versp)->ts_rcs);
- if ((*versp)->options)
- free ((*versp)->options);
- if ((*versp)->tag)
- free ((*versp)->tag);
- if ((*versp)->date)
- free ((*versp)->date);
- if ((*versp)->ts_conflict)
- free ((*versp)->ts_conflict);
- free ((char *) *versp);
- *versp = (Vers_TS *) NULL;
-}
diff --git a/gnu/usr.bin/cvs/cvs/wrapper.c b/gnu/usr.bin/cvs/cvs/wrapper.c
deleted file mode 100644
index ec5f43e8dcf4..000000000000
--- a/gnu/usr.bin/cvs/cvs/wrapper.c
+++ /dev/null
@@ -1,371 +0,0 @@
-#include "cvs.h"
-
-/*
- Original Author: athan@morgan.com <Andrew C. Athan> 2/1/94
- Modified By: vdemarco@bou.shl.com
-
- This package was written to support the NEXTSTEP concept of
- "wrappers." These are essentially directories that are to be
- treated as "files." This package allows such wrappers to be
- "processed" on the way in and out of CVS. The intended use is to
- wrap up a wrapper into a single tar, such that that tar can be
- treated as a single binary file in CVS. To solve the problem
- effectively, it was also necessary to be able to prevent rcsmerge
- application at appropriate times.
-
- ------------------
- Format of wrapper file ($CVSROOT/CVSROOT/cvswrappers or .cvswrappers)
-
- wildcard [option value][option value]...
-
- where option is one of
- -f from cvs filter value: path to filter
- -t to cvs filter value: path to filter
- -m update methodology value: MERGE or COPY
-
- and value is a single-quote delimited value.
-
- E.g:
- *.nib -f 'gunzipuntar' -t 'targzip' -m 'COPY'
-*/
-
-
-typedef struct {
- char *wildCard;
- char *tocvsFilter;
- char *fromcvsFilter;
- char *conflictHook;
- WrapMergeMethod mergeMethod;
-} WrapperEntry;
-
-static WrapperEntry **wrap_list=NULL;
-static WrapperEntry **wrap_saved_list=NULL;
-
-static int wrap_size=0;
-static int wrap_count=0;
-static int wrap_tempcount=0;
-static int wrap_saved_count=0;
-static int wrap_saved_tempcount=0;
-
-#define WRAPPER_GROW 8
-
-void wrap_add_entry PROTO((WrapperEntry *e,int temp));
-void wrap_kill PROTO((void));
-void wrap_kill_temp PROTO((void));
-void wrap_free_entry PROTO((WrapperEntry *e));
-void wrap_free_entry_internal PROTO((WrapperEntry *e));
-void wrap_restore_saved PROTO((void));
-
-void wrap_setup()
-{
- char file[PATH_MAX];
- struct passwd *pw;
-
- /* Then add entries found in repository, if it exists */
- (void) sprintf (file, "%s/%s/%s", CVSroot, CVSROOTADM, CVSROOTADM_WRAPPER);
- if (isfile (file)){
- wrap_add_file(file,0);
- }
-
- /* Then add entries found in home dir, (if user has one) and file exists */
- if ((pw = (struct passwd *) getpwuid (getuid ())) && pw->pw_dir){
- (void) sprintf (file, "%s/%s", pw->pw_dir, CVSDOTWRAPPER);
- if (isfile (file)){
- wrap_add_file (file, 0);
- }
- }
-
- /* Then add entries found in CVSWRAPPERS environment variable. */
- wrap_add (getenv (WRAPPER_ENV), 0);
-}
-
-/*
- * Open a file and read lines, feeding each line to a line parser. Arrange
- * for keeping a temporary list of wrappers at the end, if the "temp"
- * argument is set.
- */
-void
-wrap_add_file (file, temp)
- const char *file;
- int temp;
-{
- FILE *fp;
- char line[1024];
-
- wrap_restore_saved();
- wrap_kill_temp();
-
- /* load the file */
- if (!(fp = fopen (file, "r")))
- return;
- while (fgets (line, sizeof (line), fp))
- wrap_add (line, temp);
- (void) fclose (fp);
-}
-
-void
-wrap_kill()
-{
- wrap_kill_temp();
- while(wrap_count)
- wrap_free_entry(wrap_list[--wrap_count]);
-}
-
-void
-wrap_kill_temp()
-{
- WrapperEntry **temps=wrap_list+wrap_count;
-
- while(wrap_tempcount)
- wrap_free_entry(temps[--wrap_tempcount]);
-}
-
-void
-wrap_free_entry(e)
- WrapperEntry *e;
-{
- wrap_free_entry_internal(e);
- free(e);
-}
-
-void
-wrap_free_entry_internal(e)
- WrapperEntry *e;
-{
- free(e->wildCard);
- if(e->tocvsFilter)
- free(e->tocvsFilter);
- if(e->fromcvsFilter)
- free(e->fromcvsFilter);
- if(e->conflictHook)
- free(e->conflictHook);
-}
-
-void
-wrap_restore_saved()
-{
- if(!wrap_saved_list)
- return;
-
- wrap_kill();
-
- free(wrap_list);
-
- wrap_list=wrap_saved_list;
- wrap_count=wrap_saved_count;
- wrap_tempcount=wrap_saved_tempcount;
-
- wrap_saved_list=NULL;
- wrap_saved_count=0;
- wrap_saved_tempcount=0;
-}
-
-void
-wrap_add (line, isTemp)
- char *line;
- int isTemp;
-{
- char *temp;
- char ctemp;
- WrapperEntry e;
- char opt;
-
- if (!line || line[0] == '#')
- return;
-
- memset (&e, 0, sizeof(e));
-
- /* Search for the wild card */
- while(*line && isspace(*line))
- ++line;
- for(temp=line;*line && !isspace(*line);++line)
- ;
- if(temp==line)
- return;
-
- ctemp=*line;
- *line='\0';
-
- e.wildCard=xstrdup(temp);
- *line=ctemp;
-
- while(*line){
- /* Search for the option */
- while(*line && *line!='-')
- ++line;
- if(!*line)
- break;
- ++line;
- if(!*line)
- break;
- opt=*line;
-
- /* Search for the filter commandline */
- for(++line;*line && *line!='\'';++line);
- if(!*line)
- break;
-
- for(temp=++line;*line && (*line!='\'' || line[-1]=='\\');++line)
- ;
-
- if(line==temp+1)
- break;
-
- ctemp=*line;
- *line='\0';
- switch(opt){
- case 'f':
- if(e.fromcvsFilter)
- free(e.fromcvsFilter);
- e.fromcvsFilter=expand_path (temp);
- if (!e.fromcvsFilter)
- error (1, 0,
- "Invalid environmental variable string '%s'",temp);
- break;
- case 't':
- if(e.tocvsFilter)
- free(e.tocvsFilter);
- e.tocvsFilter=expand_path (temp);
- if (!e.tocvsFilter)
- error (1, 0,
- "Invalid environmental variable string '%s'",temp);
- break;
- case 'c':
- if(e.conflictHook)
- free(e.conflictHook);
- e.conflictHook=expand_path (temp);
- if (!e.conflictHook)
- error (1, 0,
- "Invalid environmental variable string '%s'",temp);
- break;
- case 'm':
- if(*temp=='C' || *temp=='c')
- e.mergeMethod=WRAP_COPY;
- else
- e.mergeMethod=WRAP_MERGE;
- break;
- default:
- break;
- }
- *line=ctemp;
- if(!*line)break;
- ++line;
- }
-
- wrap_add_entry(&e, isTemp);
-}
-
-void
-wrap_add_entry(e, temp)
- WrapperEntry *e;
- int temp;
-{
- int x;
- if(wrap_count+wrap_tempcount>=wrap_size){
- wrap_size += WRAPPER_GROW;
- wrap_list = (WrapperEntry **) xrealloc ((char *) wrap_list,
- wrap_size *
- sizeof (WrapperEntry *));
- }
-
- if(!temp && wrap_tempcount){
- for(x=wrap_count+wrap_tempcount-1;x>=wrap_count;--x)
- wrap_list[x+1]=wrap_list[x];
- }
-
- x=(temp ? wrap_count+(wrap_tempcount++):(wrap_count++));
- wrap_list[x]=(WrapperEntry *)xmalloc(sizeof(WrapperEntry));
- wrap_list[x]->wildCard=e->wildCard;
- wrap_list[x]->fromcvsFilter=e->fromcvsFilter;
- wrap_list[x]->tocvsFilter=e->tocvsFilter;
- wrap_list[x]->conflictHook=e->conflictHook;
- wrap_list[x]->mergeMethod=e->mergeMethod;
-}
-
-/* Return 1 if the given filename is a wrapper filename */
-int
-wrap_name_has (name,has)
- const char *name;
- WrapMergeHas has;
-{
- int x,count=wrap_count+wrap_saved_count;
- char *temp;
-
- for(x=0;x<count;++x)
- if (fnmatch (wrap_list[x]->wildCard, name, 0) == 0){
- switch(has){
- case WRAP_TOCVS:
- temp=wrap_list[x]->tocvsFilter;
- break;
- case WRAP_FROMCVS:
- temp=wrap_list[x]->fromcvsFilter;
- break;
- case WRAP_CONFLICT:
- temp=wrap_list[x]->conflictHook;
- break;
- default:
- abort ();
- }
- if(temp==NULL)
- return (0);
- else
- return (1);
- }
- return (0);
-}
-
-WrapperEntry *
-wrap_matching_entry (name)
- const char *name;
-{
- int x,count=wrap_count+wrap_saved_count;
-
- for(x=0;x<count;++x)
- if (fnmatch (wrap_list[x]->wildCard, name, 0) == 0)
- return wrap_list[x];
- return (WrapperEntry *)NULL;
-}
-
-char *
-wrap_tocvs_process_file(fileName)
- const char *fileName;
-{
- WrapperEntry *e=wrap_matching_entry(fileName);
- static char buf[L_tmpnam+1];
-
- if(e==NULL || e->tocvsFilter==NULL)
- return NULL;
-
- tmpnam(buf);
-
- run_setup(e->tocvsFilter,fileName,buf);
- run_exec(RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL|RUN_REALLY );
-
- return buf;
-}
-
-int
-wrap_merge_is_copy (fileName)
- const char *fileName;
-{
- WrapperEntry *e=wrap_matching_entry(fileName);
- if(e==NULL || e->mergeMethod==WRAP_MERGE)
- return 0;
-
- return 1;
-}
-
-char *
-wrap_fromcvs_process_file(fileName)
- const char *fileName;
-{
- WrapperEntry *e=wrap_matching_entry(fileName);
- static char buf[PATH_MAX];
-
- if(e==NULL || e->fromcvsFilter==NULL)
- return NULL;
-
- run_setup(e->fromcvsFilter,fileName);
- run_exec(RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL );
- return buf;
-}
diff --git a/gnu/usr.bin/cvs/cvsbug/cvsbug.8 b/gnu/usr.bin/cvs/cvsbug/cvsbug.8
deleted file mode 100644
index 496ef1458b60..000000000000
--- a/gnu/usr.bin/cvs/cvsbug/cvsbug.8
+++ /dev/null
@@ -1,269 +0,0 @@
-.\" -*- nroff -*-
-.\" ---------------------------------------------------------------------------
-.\" man page for send-pr (by Heinz G. Seidl, hgs@cygnus.com)
-.\" updated Feb 1993 for GNATS 3.00 by Jeffrey Osier, jeffrey@cygnus.com
-.\"
-.\" This file is part of the Problem Report Management System (GNATS)
-.\" Copyright 1992 Cygnus Support
-.\"
-.\" This program is free software; you can redistribute it and/or
-.\" modify it under the terms of the GNU General Public
-.\" License as published by the Free Software Foundation; either
-.\" version 2 of the License, or (at your option) any later version.
-.\"
-.\" This program is distributed in the hope that it will be useful,
-.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
-.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-.\" General Public License for more details.
-.\"
-.\" You should have received a copy of the GNU Library General Public
-.\" License along with this program; if not, write to the Free
-.\" Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
-.\"
-.\" ---------------------------------------------------------------------------
-.nh
-.TH CVSBUG 1 xVERSIONx "February 1993"
-.SH NAME
-cvsbug \- send problem report (PR) about CVS to a central support site
-.SH SYNOPSIS
-.B cvsbug
-[
-.I site
-]
-[
-.B \-f
-.I problem-report
-]
-[
-.B \-t
-.I mail-address
-]
-.br
-.in +0.8i
-[
-.B \-P
-]
-[
-.B \-L
-]
-[
-.B \-\-request-id
-]
-[
-.B \-v
-]
-.SH DESCRIPTION
-.B cvsbug
-is a tool used to submit
-.I problem reports
-.\" SITE ADMINISTRATORS - change this if you use a local default
-(PRs) to a central support site. In most cases the correct
-.I site
-will be the default. This argument indicates the support site which
-is responsible for the category of problem involved. Some sites may
-use a local address as a default.
-.I site
-values are defined by using the
-.BR aliases (5).
-.LP
-.B cvsbug
-invokes an editor on a problem report template (after trying to fill
-in some fields with reasonable default values). When you exit the
-editor,
-.B cvsbug
-sends the completed form to the
-.I Problem Report Management System
-(\fBGNATS\fR) at a central support site. At the support site, the PR
-is assigned a unique number and is stored in the \fBGNATS\fR database
-according to its category and submitter-id. \fBGNATS\fR automatically
-replies with an acknowledgement, citing the category and the PR
-number.
-.LP
-To ensure that a PR is handled promptly, it should contain your (unique)
-\fIsubmitter-id\fR and one of the available \fIcategories\fR to identify the
-problem area. (Use
-.B `cvsbug -L'
-to see a list of categories.)
-.LP
-The
-.B cvsbug
-template at your site should already be customized with your
-submitter-id (running `\|\fBinstall-sid\fP \fIsubmitter-id\fP\|' to
-accomplish this is part of the installation procedures for
-.BR cvsbug ).
-If this hasn't been done, see your system administrator for your
-submitter-id, or request one from your support site by invoking
-.B `cvsbug \-\-request\-id'.
-If your site does not distinguish between different user sites, or if
-you are not affiliated with the support site, use
-.B `net'
-for this field.
-.LP
-The more precise your problem description and the more complete your
-information, the faster your support team can solve your problems.
-.SH OPTIONS
-.TP
-.BI \-f " problem-report"
-specify a file (\fIproblem-report\fR) which already contains a
-complete problem report.
-.B cvsbug
-sends the contents of the file without invoking the editor. If
-the value for
-.I problem-report
-is
-.BR `\|\-\|' ,
-then
-.B cvsbug
-reads from standard input.
-.TP
-.BI \-t " mail-address"
-Change mail address at the support site for problem reports. The
-default
-.I mail-address
-is the address used for the default
-.IR site .
-Use the
-.I site
-argument rather than this option in nearly all cases.
-.TP
-.B \-P
-print the form specified by the environment variable
-.B PR_FORM
-on standard output. If
-.B PR_FORM
-is not set, print the standard blank PR template. No mail is sent.
-.TP
-.B -L
-print the list of available categories. No mail is sent.
-.TP
-.B \-\-request\-id
-sends mail to the default support site, or
-.I site
-if specified, with a request for your
-.IR submitter-id .
-If you are
-not affiliated with
-.IR site ,
-use a
-.I submitter-id
-of
-.BR net \|'.
-.TP
-.B \-v
-Display the
-.B cvsbug
-version number.
-.LP
-Note: use
-.B cvsbug
-to submit problem reports rather than mailing them directly. Using
-both the template and
-.B cvsbug
-itself will help ensure all necessary information will reach the
-support site.
-.SH ENVIRONMENT
-The environment variable
-.B EDITOR
-specifies the editor to invoke on the template.
-.br
-default:
-.B vi
-.sp
-If the environment variable
-.B PR_FORM
-is set, then its value is used as the file name of the template for
-your problem-report editing session. You can use this to start with a
-partially completed form (for example, a form with the identification
-fields already completed).
-.SH "HOW TO FILL OUT A PROBLEM REPORT"
-Problem reports have to be in a particular form so that a program can
-easily manage them. Please remember the following guidelines:
-.IP \(bu 3m
-describe only
-.B one problem
-with each problem report.
-.IP \(bu 3m
-For follow-up mail, use the same subject line as the one in the automatic
-acknowledgent. It consists of category, PR number and the original synopsis
-line. This allows the support site to relate several mail messages to a
-particular PR and to record them automatically.
-.IP \(bu 3m
-Please try to be as accurate as possible in the subject and/or synopsis line.
-.IP \(bu 3m
-The subject and the synopsis line are not confidential. This is
-because open-bugs lists are compiled from them. Avoid confidential
-information there.
-.LP
-See the GNU
-.B Info
-file
-.B cvsbug.info
-or the document \fIReporting Problems With cvsbug\fR\ for detailed
-information on reporting problems
-.SH "HOW TO SUBMIT TEST CASES, CODE, ETC."
-Submit small code samples with the PR. Contact the support site for
-instructions on submitting larger test cases and problematic source
-code.
-.SH FILES
-.ta \w'/tmp/pbad$$ 'u
-/tmp/p$$ copy of PR used in editing session
-.br
-/tmp/pf$$ copy of empty PR form, for testing purposes
-.br
-/tmp/pbad$$ file for rejected PRs
-.SH EMACS USER INTERFACE
-An Emacs user interface for
-.B cvsbug
-with completion of field values is part of the
-.B cvsbug
-distribution (invoked with
-.BR "M-x cvsbug" ).
-See the file
-.B cvsbug.info
-or the ASCII file
-.B INSTALL
-in the top level directory of the distribution for configuration and
-installation information. The Emacs LISP template file is
-.B cvsbug-el.in
-and is installed as
-.BR cvsbug.el .
-.SH INSTALLATION AND CONFIGURATION
-See
-.B cvsbug.info
-or
-.B INSTALL
-for installation instructions.
-.SH SEE ALSO
-.I Reporting Problems Using cvsbug
-(also installed as the GNU Info file
-.BR cvsbug.info ).
-.LP
-.BR gnats (l),
-.BR query-pr (1),
-.BR edit-pr (1),
-.BR gnats (8),
-.BR queue-pr (8),
-.BR at-pr (8),
-.BR mkcat (8),
-.BR mkdist (8).
-.SH AUTHORS
-Jeffrey Osier, Brendan Kehoe, Jason Merrill, Heinz G. Seidl (Cygnus
-Support)
-.SH COPYING
-Copyright (c) 1992, 1993 Free Software Foundation, Inc.
-.PP
-Permission is granted to make and distribute verbatim copies of
-this manual provided the copyright notice and this permission notice
-are preserved on all copies.
-.PP
-Permission is granted to copy and distribute modified versions of this
-manual under the conditions for verbatim copying, provided that the
-entire resulting derived work is distributed under the terms of a
-permission notice identical to this one.
-.PP
-Permission is granted to copy and distribute translations of this
-manual into another language, under the above conditions for modified
-versions, except that this permission notice may be included in
-translations approved by the Free Software Foundation instead of in
-the original English.
-
diff --git a/gnu/usr.bin/cvs/cvsbug/cvsbug.sh b/gnu/usr.bin/cvs/cvsbug/cvsbug.sh
deleted file mode 100644
index ab26cfce570a..000000000000
--- a/gnu/usr.bin/cvs/cvsbug/cvsbug.sh
+++ /dev/null
@@ -1,528 +0,0 @@
-#! /bin/sh
-# Submit a problem report to a GNATS site.
-# Copyright (C) 1993 Free Software Foundation, Inc.
-# Contributed by Brendan Kehoe (brendan@cygnus.com), based on a
-# version written by Heinz G. Seidl (hgs@ide.com).
-#
-# This file is part of GNU GNATS.
-# Modified by Berliner for CVS.
-#
-#ident "@(#)cvs/src:$Name: $:$Id: cvsbug.sh,v 1.10 1995/11/15 00:18:00 woods Exp $"
-#
-# GNU GNATS is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2, or (at your option)
-# any later version.
-#
-# GNU GNATS is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with GNU GNATS; see the file COPYING. If not, write to
-# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
-# The version of this send-pr.
-VERSION=3.2
-
-# The submitter-id for your site.
-SUBMITTER=net
-
-## # Where the GNATS directory lives, if at all.
-## [ -z "$GNATS_ROOT" ] &&
-## GNATS_ROOT=/usr/local/lib/gnats/gnats-db
-
-# The default mail address for PR submissions.
-GNATS_ADDR=bug-cvs@prep.ai.mit.edu
-
-## # Where the gnats category tree lives.
-## DATADIR=/usr/local/lib
-
-## # If we've been moved around, try using GCC_EXEC_PREFIX.
-## [ ! -d $DATADIR/gnats -a -d "$GCC_EXEC_PREFIX" ] && DATADIR=${GCC_EXEC_PREFIX}..
-
-# The default release for this host.
-DEFAULT_RELEASE="xVERSIONx"
-
-# The default organization.
-DEFAULT_ORGANIZATION="net"
-
-## # The default site to look for.
-## GNATS_SITE=unknown
-
-## # Newer config information?
-## [ -f ${GNATS_ROOT}/gnats-adm/config ] && . ${GNATS_ROOT}/gnats-adm/config
-
-# What mailer to use. This must come after the config file, since it is
-# host-dependent.
-if [ -f /usr/sbin/sendmail ]; then
- MAIL_AGENT="/usr/sbin/sendmail -oi -t"
-else
- MAIL_AGENT="/usr/lib/sendmail -oi -t"
-fi
-MAILER=`echo $MAIL_AGENT | sed -e 's, .*,,'`
-if [ ! -f "$MAILER" ] ; then
- echo "$COMMAND: Cannot file mail program \"$MAILER\"."
- echo "$COMMAND: Please fix the MAIL_AGENT entry in the $COMMAND file."
- exit 1
-fi
-
-if test "`echo -n foo`" = foo ; then
- ECHON=bsd
-elif test "`echo 'foo\c'`" = foo ; then
- ECHON=sysv
-else
- ECHON=none
-fi
-
-if [ $ECHON = bsd ] ; then
- ECHON1="echo -n"
- ECHON2=
-elif [ $ECHON = sysv ] ; then
- ECHON1=echo
- ECHON2='\c'
-else
- ECHON1=echo
- ECHON2=
-fi
-
-#
-
-[ -z "$TMPDIR" ] && TMPDIR=/tmp
-
-TEMP=$TMPDIR/p$$
-BAD=$TMPDIR/pbad$$
-REF=$TMPDIR/pf$$
-
-if [ -z "$LOGNAME" -a -n "$USER" ]; then
- LOGNAME=$USER
-fi
-
-FROM="$LOGNAME"
-REPLY_TO="$LOGNAME"
-
-# Find out the name of the originator of this PR.
-if [ -n "$NAME" ]; then
- ORIGINATOR="$NAME"
-elif [ -f $HOME/.fullname ]; then
- ORIGINATOR="`sed -e '1q' $HOME/.fullname`"
-elif [ -f /bin/domainname ]; then
- if [ "`/bin/domainname`" != "" -a -f /usr/bin/ypcat ]; then
- # Must use temp file due to incompatibilities in quoting behavior
- # and to protect shell metacharacters in the expansion of $LOGNAME
- /usr/bin/ypcat passwd 2>/dev/null | cat - /etc/passwd | grep "^$LOGNAME:" |
- cut -f5 -d':' | sed -e 's/,.*//' > $TEMP
- ORIGINATOR="`cat $TEMP`"
- rm -f $TEMP
- fi
-fi
-
-if [ "$ORIGINATOR" = "" ]; then
- grep "^$LOGNAME:" /etc/passwd | cut -f5 -d':' | sed -e 's/,.*//' > $TEMP
- ORIGINATOR="`cat $TEMP`"
- rm -f $TEMP
-fi
-
-if [ -n "$ORGANIZATION" ]; then
- if [ -f "$ORGANIZATION" ]; then
- ORGANIZATION="`cat $ORGANIZATION`"
- fi
-else
- if [ -n "$DEFAULT_ORGANIZATION" ]; then
- ORGANIZATION="$DEFAULT_ORGANIZATION"
- elif [ -f $HOME/.organization ]; then
- ORGANIZATION="`cat $HOME/.organization`"
- elif [ -f $HOME/.signature ]; then
- ORGANIZATION="`cat $HOME/.signature`"
- fi
-fi
-
-# If they don't have a preferred editor set, then use
-if [ -z "$VISUAL" ]; then
- if [ -z "$EDITOR" ]; then
- EDIT=vi
- else
- EDIT="$EDITOR"
- fi
-else
- EDIT="$VISUAL"
-fi
-
-# Find out some information.
-SYSTEM=`( [ -f /bin/uname ] && /bin/uname -a ) || \
- ( [ -f /usr/bin/uname ] && /usr/bin/uname -a ) || echo ""`
-ARCH=`[ -f /bin/arch ] && /bin/arch`
-MACHINE=`[ -f /bin/machine ] && /bin/machine`
-
-COMMAND=`echo $0 | sed -e 's,.*/,,'`
-## USAGE="Usage: $COMMAND [-PVL] [-t address] [-f filename] [--request-id]
-USAGE="Usage: $COMMAND [-PVL]
-[--version]"
-REMOVE=
-BATCH=
-
-while [ $# -gt 0 ]; do
- case "$1" in
- -r) ;; # Ignore for backward compat.
-## -t | --to) if [ $# -eq 1 ]; then echo "$USAGE"; exit 1; fi
-## shift ; GNATS_ADDR="$1"
-## EXPLICIT_GNATS_ADDR=true
-## ;;
-## -f | --file) if [ $# -eq 1 ]; then echo "$USAGE"; exit 1; fi
-## shift ; IN_FILE="$1"
-## if [ "$IN_FILE" != "-" -a ! -r "$IN_FILE" ]; then
-## echo "$COMMAND: cannot read $IN_FILE"
-## exit 1
-## fi
-## ;;
- -b | --batch) BATCH=true ;;
- -p | -P | --print) PRINT=true ;;
- -L | --list) FORMAT=norm ;;
- -l | -CL | --lisp) FORMAT=lisp ;;
-## --request-id) REQUEST_ID=true ;;
- -h | --help) echo "$USAGE"; exit 0 ;;
- -V | --version) echo "$VERSION"; exit 0 ;;
- -*) echo "$USAGE" ; exit 1 ;;
- *) echo "$USAGE" ; exit 1
-## if [ -z "$USER_GNATS_SITE" ]; then
-## if [ ! -r "$DATADIR/gnats/$1" ]; then
-## echo "$COMMAND: the GNATS site $1 does not have a categories list."
-## exit 1
-## else
-## # The site name is the alias they'll have to have created.
-## USER_GNATS_SITE=$1
-## fi
-## else
-## echo "$USAGE" ; exit 1
-## fi
- ;;
- esac
- shift
-done
-
-if [ -n "$USER_GNATS_SITE" ]; then
- GNATS_SITE=$USER_GNATS_SITE
- GNATS_ADDR=$USER_GNATS_SITE-gnats
-fi
-
-if [ "$SUBMITTER" = "unknown" -a -z "$REQUEST_ID" -a -z "$IN_FILE" ]; then
- cat << '__EOF__'
-It seems that send-pr is not installed with your unique submitter-id.
-You need to run
-
- install-sid YOUR-SID
-
-where YOUR-SID is the identification code you received with `send-pr'.
-`send-pr' will automatically insert this value into the template field
-`>Submitter-Id'. If you've downloaded `send-pr' from the Net, use `net'
-for this value. If you do not know your id, run `send-pr --request-id' to
-get one from your support site.
-__EOF__
- exit 1
-fi
-
-## if [ -r "$DATADIR/gnats/$GNATS_SITE" ]; then
-## CATEGORIES=`grep -v '^#' $DATADIR/gnats/$GNATS_SITE | sort`
-## else
-## echo "$COMMAND: could not read $DATADIR/gnats/$GNATS_SITE for categories list."
-## exit 1
-## fi
-CATEGORIES="contrib cvs doc pcl-cvs portability"
-
-if [ -z "$CATEGORIES" ]; then
- echo "$COMMAND: the categories list for $GNATS_SITE was empty!"
- exit 1
-fi
-
-case "$FORMAT" in
- lisp) echo "$CATEGORIES" | \
- awk 'BEGIN {printf "( "} {printf "(\"%s\") ",$0} END {printf ")\n"}'
- exit 0
- ;;
- norm) l=`echo "$CATEGORIES" | \
- awk 'BEGIN {max = 0; } { if (length($0) > max) { max = length($0); } }
- END {print max + 1;}'`
- c=`expr 70 / $l`
- if [ $c -eq 0 ]; then c=1; fi
- echo "$CATEGORIES" | \
- awk 'BEGIN {print "Known categories:"; i = 0 }
- { printf ("%-'$l'.'$l's", $0); if ((++i % '$c') == 0) { print "" } }
- END { print ""; }'
- exit 0
- ;;
-esac
-
-ORIGINATOR_C='<name of the PR author (one line)>'
-ORGANIZATION_C='<organization of PR author (multiple lines)>'
-CONFIDENTIAL_C='<[ yes | no ] (one line)>'
-SYNOPSIS_C='<synopsis of the problem (one line)>'
-SEVERITY_C='<[ non-critical | serious | critical ] (one line)>'
-PRIORITY_C='<[ low | medium | high ] (one line)>'
-CATEGORY_C='<name of the product (one line)>'
-CLASS_C='<[ sw-bug | doc-bug | change-request | support ] (one line)>'
-RELEASE_C='<release number or tag (one line)>'
-ENVIRONMENT_C='<machine, os, target, libraries (multiple lines)>'
-DESCRIPTION_C='<precise description of the problem (multiple lines)>'
-HOW_TO_REPEAT_C='<code/input/activities to reproduce the problem (multiple lines)>'
-FIX_C='<how to correct or work around the problem, if known (multiple lines)>'
-
-# Catch some signals. ($xs kludge needed by Sun /bin/sh)
-xs=0
-trap 'rm -f $REF $TEMP; exit $xs' 0
-trap 'echo "$COMMAND: Aborting ..."; rm -f $REF $TEMP; xs=1; exit' 1 2 3 13 15
-
-# If they told us to use a specific file, then do so.
-if [ -n "$IN_FILE" ]; then
- if [ "$IN_FILE" = "-" ]; then
- # The PR is coming from the standard input.
- if [ -n "$EXPLICIT_GNATS_ADDR" ]; then
- sed -e "s;^[Tt][Oo]:.*;To: $GNATS_ADDR;" > $TEMP
- else
- cat > $TEMP
- fi
- else
- # Use the file they named.
- if [ -n "$EXPLICIT_GNATS_ADDR" ]; then
- sed -e "s;^[Tt][Oo]:.*;To: $GNATS_ADDR;" $IN_FILE > $TEMP
- else
- cat $IN_FILE > $TEMP
- fi
- fi
-else
-
- if [ -n "$PR_FORM" -a -z "$PRINT_INTERN" ]; then
- # If their PR_FORM points to a bogus entry, then bail.
- if [ ! -f "$PR_FORM" -o ! -r "$PR_FORM" -o ! -s "$PR_FORM" ]; then
- echo "$COMMAND: can't seem to read your template file (\`$PR_FORM'), ignoring PR_FORM"
- sleep 1
- PRINT_INTERN=bad_prform
- fi
- fi
-
- if [ -n "$PR_FORM" -a -z "$PRINT_INTERN" ]; then
- cp $PR_FORM $TEMP ||
- ( echo "$COMMAND: could not copy $PR_FORM" ; xs=1; exit )
- else
- for file in $TEMP $REF ; do
- cat > $file << '__EOF__'
-SEND-PR: -*- send-pr -*-
-SEND-PR: Lines starting with `SEND-PR' will be removed automatically, as
-SEND-PR: will all comments (text enclosed in `<' and `>').
-SEND-PR:
-SEND-PR: Choose from the following categories:
-SEND-PR:
-__EOF__
-
- # Format the categories so they fit onto lines.
- l=`echo "$CATEGORIES" | \
- awk 'BEGIN {max = 0; } { if (length($0) > max) { max = length($0); } }
- END {print max + 1;}'`
- c=`expr 61 / $l`
- if [ $c -eq 0 ]; then c=1; fi
- echo "$CATEGORIES" | \
- awk 'BEGIN {printf "SEND-PR: "; i = 0 }
- { printf ("%-'$l'.'$l's", $0);
- if ((++i % '$c') == 0) { printf "\nSEND-PR: " } }
- END { printf "\nSEND-PR:\n"; }' >> $file
-
- cat >> $file << __EOF__
-To: $GNATS_ADDR
-Subject:
-From: $FROM
-Reply-To: $REPLY_TO
-X-send-pr-version: $VERSION
-
-
->Submitter-Id: $SUBMITTER
->Originator: $ORIGINATOR
->Organization:
-${ORGANIZATION-$ORGANIZATION_C}
->Confidential: $CONFIDENTIAL_C
->Synopsis: $SYNOPSIS_C
->Severity: $SEVERITY_C
->Priority: $PRIORITY_C
->Category: $CATEGORY_C
->Class: $CLASS_C
->Release: ${DEFAULT_RELEASE-$RELEASE_C}
->Environment:
- $ENVIRONMENT_C
-`[ -n "$SYSTEM" ] && echo System: $SYSTEM`
-`[ -n "$ARCH" ] && echo Architecture: $ARCH`
-`[ -n "$MACHINE" ] && echo Machine: $MACHINE`
->Description:
- $DESCRIPTION_C
->How-To-Repeat:
- $HOW_TO_REPEAT_C
->Fix:
- $FIX_C
-__EOF__
- done
- fi
-
- if [ "$PRINT" = true -o "$PRINT_INTERN" = true ]; then
- cat $TEMP
- xs=0; exit
- fi
-
- chmod u+w $TEMP
- if [ -z "$REQUEST_ID" ]; then
- eval $EDIT $TEMP
- else
- ed -s $TEMP << '__EOF__'
-/^Subject/s/^Subject:.*/Subject: request for a customer id/
-/^>Category/s/^>Category:.*/>Category: send-pr/
-w
-q
-__EOF__
- fi
-
- if cmp -s $REF $TEMP ; then
- echo "$COMMAND: problem report not filled out, therefore not sent"
- xs=1; exit
- fi
-fi
-
-#
-# Check the enumeration fields
-
-# This is a "sed-subroutine" with one keyword parameter
-# (with workaround for Sun sed bug)
-#
-SED_CMD='
-/$PATTERN/{
-s|||
-s|<.*>||
-s|^[ ]*||
-s|[ ]*$||
-p
-q
-}'
-
-
-while [ -z "$REQUEST_ID" ]; do
- CNT=0
-
- # 1) Confidential
- #
- PATTERN=">Confidential:"
- CONFIDENTIAL=`eval sed -n -e "\"$SED_CMD\"" $TEMP`
- case "$CONFIDENTIAL" in
- ""|yes|no) CNT=`expr $CNT + 1` ;;
- *) echo "$COMMAND: \`$CONFIDENTIAL' is not a valid value for \`Confidential'." ;;
- esac
- #
- # 2) Severity
- #
- PATTERN=">Severity:"
- SEVERITY=`eval sed -n -e "\"$SED_CMD\"" $TEMP`
- case "$SEVERITY" in
- ""|non-critical|serious|critical) CNT=`expr $CNT + 1` ;;
- *) echo "$COMMAND: \`$SEVERITY' is not a valid value for \`Severity'."
- esac
- #
- # 3) Priority
- #
- PATTERN=">Priority:"
- PRIORITY=`eval sed -n -e "\"$SED_CMD\"" $TEMP`
- case "$PRIORITY" in
- ""|low|medium|high) CNT=`expr $CNT + 1` ;;
- *) echo "$COMMAND: \`$PRIORITY' is not a valid value for \`Priority'."
- esac
- #
- # 4) Category
- #
- PATTERN=">Category:"
- CATEGORY=`eval sed -n -e "\"$SED_CMD\"" $TEMP`
- FOUND=
- for C in $CATEGORIES
- do
- if [ "$C" = "$CATEGORY" ]; then FOUND=true ; break ; fi
- done
- if [ -n "$FOUND" ]; then
- CNT=`expr $CNT + 1`
- else
- if [ -z "$CATEGORY" ]; then
- echo "$COMMAND: you must include a Category: field in your report."
- else
- echo "$COMMAND: \`$CATEGORY' is not a known category."
- fi
- fi
- #
- # 5) Class
- #
- PATTERN=">Class:"
- CLASS=`eval sed -n -e "\"$SED_CMD\"" $TEMP`
- case "$CLASS" in
- ""|sw-bug|doc-bug|change-request|support) CNT=`expr $CNT + 1` ;;
- *) echo "$COMMAND: \`$CLASS' is not a valid value for \`Class'."
- esac
-
- [ $CNT -lt 5 -a -z "$BATCH" ] &&
- echo "Errors were found with the problem report."
-
- while true; do
- if [ -z "$BATCH" ]; then
- $ECHON1 "a)bort, e)dit or s)end? $ECHON2"
- read input
- else
- if [ $CNT -eq 5 ]; then
- input=s
- else
- input=a
- fi
- fi
- case "$input" in
- a*)
- if [ -z "$BATCH" ]; then
- echo "$COMMAND: the problem report remains in $BAD and is not sent."
- mv $TEMP $BAD
- else
- echo "$COMMAND: the problem report is not sent."
- fi
- xs=1; exit
- ;;
- e*)
- eval $EDIT $TEMP
- continue 2
- ;;
- s*)
- break 2
- ;;
- esac
- done
-done
-#
-# Remove comments and send the problem report
-# (we have to use patterns, where the comment contains regex chars)
-#
-# /^>Originator:/s;$ORIGINATOR;;
-sed -e "
-/^SEND-PR:/d
-/^>Organization:/,/^>[A-Za-z-]*:/s;$ORGANIZATION_C;;
-/^>Confidential:/s;<.*>;;
-/^>Synopsis:/s;$SYNOPSIS_C;;
-/^>Severity:/s;<.*>;;
-/^>Priority:/s;<.*>;;
-/^>Category:/s;$CATEGORY_C;;
-/^>Class:/s;<.*>;;
-/^>Release:/,/^>[A-Za-z-]*:/s;$RELEASE_C;;
-/^>Environment:/,/^>[A-Za-z-]*:/s;$ENVIRONMENT_C;;
-/^>Description:/,/^>[A-Za-z-]*:/s;$DESCRIPTION_C;;
-/^>How-To-Repeat:/,/^>[A-Za-z-]*:/s;$HOW_TO_REPEAT_C;;
-/^>Fix:/,/^>[A-Za-z-]*:/s;$FIX_C;;
-" $TEMP > $REF
-
-if $MAIL_AGENT < $REF; then
- echo "$COMMAND: problem report sent"
- xs=0; exit
-else
- echo "$COMMAND: mysterious mail failure."
- if [ -z "$BATCH" ]; then
- echo "$COMMAND: the problem report remains in $BAD and is not sent."
- mv $REF $BAD
- else
- echo "$COMMAND: the problem report is not sent."
- fi
- xs=1; exit
-fi
diff --git a/gnu/usr.bin/cvs/cvsinit/cvsinit b/gnu/usr.bin/cvs/cvsinit/cvsinit
deleted file mode 100644
index 23c6651a6c84..000000000000
--- a/gnu/usr.bin/cvs/cvsinit/cvsinit
+++ /dev/null
@@ -1,161 +0,0 @@
-#! /bin/sh
-:
-#
-#ident "@(#)cvs:$Name: $:$Id: cvsinit.sh,v 1.7 1995/11/14 23:44:18 woods Exp $"
-# Copyright (c) 1992, Brian Berliner
-#
-# You may distribute under the terms of the GNU General Public License as
-# specified in the README file that comes with the CVS 1.4 kit.
-
-# This script should be run for each repository you create to help you
-# setup your site for CVS. You may also run it to update existing
-# repositories if you install a new version of CVS.
-
-# this line is edited by Makefile when creating cvsinit.inst
-CVSLIB="/usr/share/examples/cvs"
-
-CVS_VERSION="cvs-1.6.3"
-
-# All purpose usage message, also suffices for --help and --version.
-if test $# -gt 0; then
- echo "cvsinit version $CVS_VERSION"
- echo "usage: $0"
- echo "(set CVSROOT to the repository that you want to initialize)"
- exit 0
-fi
-
-# Make sure that the CVSROOT variable is set
-if [ "x$CVSROOT" = x ]; then
- echo "The CVSROOT environment variable is not set."
- echo ""
- echo "You should choose a location for your source repository"
- echo "that can be shared by many developers. It also helps to"
- echo "place the source repository on a file system that has"
- echo "plenty of free space."
- echo ""
- echo "Please enter the full path for your CVSROOT source repository:"
- read CVSROOT junk
- unset junk
- remind_cvsroot=yes
-else
- remind_cvsroot=no
-fi
-
-# Now, create the $CVSROOT if it is not already there
-if [ ! -d $CVSROOT ]; then
- echo "Creating $CVSROOT..."
- path=
- for comp in `echo $CVSROOT | sed -e 's,/, ,g'`; do
- path=$path/$comp
- if [ ! -d $path ]; then
- mkdir $path
- fi
- done
-else
- true
-fi
-
-# Next, check for $CVSROOT/CVSROOT
-if [ ! -d $CVSROOT/CVSROOT ]; then
- if [ -d $CVSROOT/CVSROOT.adm ]; then
- echo "You have the old $CVSROOT/CVSROOT.adm directory."
- echo "I will rename it to $CVSROOT/CVSROOT for you..."
- mv $CVSROOT/CVSROOT.adm $CVSROOT/CVSROOT
- else
- echo "Creating the $CVSROOT/CVSROOT directory..."
- mkdir $CVSROOT/CVSROOT
- fi
-else
- true
-fi
-if [ ! -d $CVSROOT/CVSROOT ]; then
- echo "Unable to create $CVSROOT/CVSROOT."
- echo "I give up."
- exit 1
-fi
-
-# Create the special control files and templates within $CVSROOT/CVSROOT
-
-EXAMPLES="checkoutlist commitinfo cvswrappers editinfo loginfo modules
-rcsinfo rcstemplate taginfo wrap unwrap"
-
-NEWSAMPLE=false
-for info in $EXAMPLES; do
- if [ -f $CVSROOT/CVSROOT/${info},v ]; then
- if [ ! -f $CVSROOT/CVSROOT/$info ]; then
- echo "Checking out $CVSROOT/CVSROOT/$info"
- echo " from $CVSROOT/CVSROOT/${info},v..."
- (cd $CVSROOT/CVSROOT; co -q $info)
- fi
- else
- NEWSAMPLE=true
- if [ -f $CVSROOT/CVSROOT/$info ]; then
- echo "Checking in $CVSROOT/CVSROOT/${info},v"
- echo " from $CVSROOT/CVSROOT/$info..."
- else
- echo "Creating a sample $CVSROOT/CVSROOT/$info file..."
- case $info in
- modules)
- sed -n -e '/END_REQUIRED_CONTENT/q' \
- -e p $CVSLIB/examples/modules > $CVSROOT/CVSROOT/modules
- ;;
- rcstemplate)
- cp $CVSLIB/examples/$info $CVSROOT/CVSROOT/$info
- ;;
- wrap|unwrap)
- cp $CVSLIB/examples/$info $CVSROOT/CVSROOT/$info
- chmod +x $CVSROOT/CVSROOT/$info
- ;;
- *)
- # comment out everything in all the other examples....
- sed -e 's/^\([^#]\)/#\1/' $CVSLIB/examples/$info > $CVSROOT/CVSROOT/$info
- ;;
- esac
- fi
- (cd $CVSROOT/CVSROOT; ci -q -u -t/dev/null -m"initial checkin of $info" $info)
- fi
-done
-
-if $NEWSAMPLE ; then
- echo "NOTE: You may wish to check out the CVSROOT module and edit any new"
- echo "configuration files to match your local requirements."
- echo ""
-fi
-
-# check to see if there are any references to the old CVSROOT.adm directory
-if grep CVSROOT.adm $CVSROOT/CVSROOT/modules >/dev/null 2>&1; then
- echo "Warning: your $CVSROOT/CVSROOT/modules file still"
- echo " contains references to the old CVSROOT.adm directory"
- echo " You should really change these to the new CVSROOT directory"
- echo ""
-fi
-
-# These files are generated from the contrib files.
-# FIXME: Is it really wise to overwrite possible local changes like this?
-# Normal folks will keep these up to date by modifying the source in
-# their CVS module and re-installing CVS, but is everyone OK with that?
-#
-#
-CONTRIBS="log commit_prep log_accum cln_hist"
-#
-for contrib in $CONTRIBS; do
- echo "Copying the new version of '${contrib}'"
- echo " to $CVSROOT/CVSROOT for you..."
- cp $CVSLIB/contrib/$contrib $CVSROOT/CVSROOT/$contrib
-done
-
-# XXX - also add a stub for the cvsignore file
-
-# Turn on history logging by default
-if [ ! -f $CVSROOT/CVSROOT/history ]; then
- echo "Enabling CVS history logging..."
- touch $CVSROOT/CVSROOT/history
- chmod g+w $CVSROOT/CVSROOT/history
- echo "(Remove $CVSROOT/CVSROOT/history to disable.)"
-fi
-
-# finish up by running mkmodules
-echo "All done! Running 'mkmodules' as my final step..."
-mkmodules $CVSROOT/CVSROOT
-
-exit 0
diff --git a/gnu/usr.bin/cvs/cvsinit/cvsinit.8 b/gnu/usr.bin/cvs/cvsinit/cvsinit.8
deleted file mode 100644
index 1012d62b687e..000000000000
--- a/gnu/usr.bin/cvs/cvsinit/cvsinit.8
+++ /dev/null
@@ -1,142 +0,0 @@
-.de Id
-.ds Rv \\$4
-.ds Dt \\$5
-..
-.Id @(#)ccvs/man:$Name: $:$Id: cvsinit.8,v 1.2 1995/11/14 20:48:54 woods Exp $
-.TH CVSINIT 8 "\*(Dt"
-.\" Full space in nroff; half space in troff
-.de SP
-.if n .sp
-.if t .sp .5
-..
-.\" quoted command
-.de `
-.RB ` "\|\\$1\|" '\\$2
-..
-.\"
-.SH "NAME"
-cvsinit \- Concurrent Versions System repository initialization script
-.SH "SYNOPSIS"
-.TP
-.B cvsinit
-.\"
-.SH "DESCRIPTION"
-.\"
-The
-.B cvsinit
-script initializes a repository in the location specified by the
-.SM CVSROOT
-environment variable.
-.SH "FILES"
-For more detailed information on
-.B cvs
-supporting files, see
-.BR cvs ( 5 ).
-.LP
-Files in source repositories (created by
-.BR cvsinit ):
-.TP
-$CVSROOT/CVSROOT
-Directory of global administrative files for repository.
-.TP
-$CVSROOT/commitinfo,v
-Records programs for filtering
-.` "cvs commit"
-requests.
-.TP
-$CVSROOT/history
-Log file of \fBcvs\fP transactions.
-.TP
-$CVSROOT/modules,v
-Definitions for modules in this repository.
-.TP
-$CVSROOT/loginfo,v
-Records programs for piping
-.` "cvs commit"
-log entries.
-.TP
-$CVSROOT/rcsinfo,v
-Records pathnames to templates used during a
-.` "cvs commit"
-operation.
-.TP
-$CVSROOT/editinfo,v
-Records programs for editing/validating
-.` "cvs commit"
-log entries.
-.TP
-$CVSROOT/log
-Sample logging script for use in
-.IR loginfo .
-.TP
-$CVSROOT/commit_prep
-Sample logging script for use in
-.I commitinfo
-with the
-.I log_accum
-script
-.TP
-$CVSROOT/log_accum
-Sample loggin script for use in
-.I loginfo
-with the
-.I commit_prep
-script
-.\"
-.SH "ENVIRONMENT VARIABLES"
-.TP
-.SM CVSROOT
-Should contain the full pathname to the root of the
-.B cvs
-source repository (where the
-.SM RCS
-files are kept). This information must be available to \fBcvs\fP for
-most commands to execute; if
-.SM CVSROOT
-is not set, or if you wish to override it for one invocation, you can
-supply it on the command line:
-.` "cvs \-d \fIcvsroot cvs_command\fP\|.\|.\|."
-You may not need to set
-.SM CVSROOT
-if your \fBcvs\fP binary has the right path compiled in; use
-.` "cvs \-v"
-to display all compiled-in paths.
-.\"
-.SH "AUTHORS"
-.TP
-Dick Grune
-Original author of the
-.B cvs
-shell script version posted to
-.B comp.sources.unix
-in the volume6 release of December, 1986.
-Credited with much of the
-.B cvs
-conflict resolution algorithms.
-.TP
-Brian Berliner
-Coder and designer of the
-.B cvs
-program itself in April, 1989, based on the original work done by Dick.
-.TP
-Jeff Polk
-Helped Brian with the design of the
-.B cvs
-module and vendor branch support and author of the
-.BR checkin ( 1 )
-shell script (the ancestor of
-.` "cvs import").
-.SH "SEE ALSO"
-.BR ci ( 1 ),
-.BR co ( 1 ),
-.BR cvs ( 5 ),
-.BR diff ( 1 ),
-.BR grep ( 1 ),
-.BR mkmodules ( 1 ),
-.BR patch ( 1 ),
-.BR rcs ( 1 ),
-.BR rcsdiff ( 1 ),
-.BR rcsmerge ( 1 ),
-.BR rlog ( 1 ),
-.BR rm ( 1 ),
-.BR sort ( 1 ).
diff --git a/gnu/usr.bin/cvs/cvsinit/cvsinit.sh b/gnu/usr.bin/cvs/cvsinit/cvsinit.sh
deleted file mode 100644
index 49c545190b58..000000000000
--- a/gnu/usr.bin/cvs/cvsinit/cvsinit.sh
+++ /dev/null
@@ -1,161 +0,0 @@
-#! /bin/sh
-:
-#
-#ident "@(#)cvs:$Name: $:$Id: cvsinit.sh,v 1.7 1995/11/14 23:44:18 woods Exp $"
-# Copyright (c) 1992, Brian Berliner
-#
-# You may distribute under the terms of the GNU General Public License as
-# specified in the README file that comes with the CVS 1.4 kit.
-
-# This script should be run for each repository you create to help you
-# setup your site for CVS. You may also run it to update existing
-# repositories if you install a new version of CVS.
-
-# this line is edited by Makefile when creating cvsinit.inst
-CVSLIB="xLIBDIRx"
-
-CVS_VERSION="xVERSIONx"
-
-# All purpose usage message, also suffices for --help and --version.
-if test $# -gt 0; then
- echo "cvsinit version $CVS_VERSION"
- echo "usage: $0"
- echo "(set CVSROOT to the repository that you want to initialize)"
- exit 0
-fi
-
-# Make sure that the CVSROOT variable is set
-if [ "x$CVSROOT" = x ]; then
- echo "The CVSROOT environment variable is not set."
- echo ""
- echo "You should choose a location for your source repository"
- echo "that can be shared by many developers. It also helps to"
- echo "place the source repository on a file system that has"
- echo "plenty of free space."
- echo ""
- echo "Please enter the full path for your CVSROOT source repository:"
- read CVSROOT junk
- unset junk
- remind_cvsroot=yes
-else
- remind_cvsroot=no
-fi
-
-# Now, create the $CVSROOT if it is not already there
-if [ ! -d $CVSROOT ]; then
- echo "Creating $CVSROOT..."
- path=
- for comp in `echo $CVSROOT | sed -e 's,/, ,g'`; do
- path=$path/$comp
- if [ ! -d $path ]; then
- mkdir $path
- fi
- done
-else
- true
-fi
-
-# Next, check for $CVSROOT/CVSROOT
-if [ ! -d $CVSROOT/CVSROOT ]; then
- if [ -d $CVSROOT/CVSROOT.adm ]; then
- echo "You have the old $CVSROOT/CVSROOT.adm directory."
- echo "I will rename it to $CVSROOT/CVSROOT for you..."
- mv $CVSROOT/CVSROOT.adm $CVSROOT/CVSROOT
- else
- echo "Creating the $CVSROOT/CVSROOT directory..."
- mkdir $CVSROOT/CVSROOT
- fi
-else
- true
-fi
-if [ ! -d $CVSROOT/CVSROOT ]; then
- echo "Unable to create $CVSROOT/CVSROOT."
- echo "I give up."
- exit 1
-fi
-
-# Create the special control files and templates within $CVSROOT/CVSROOT
-
-EXAMPLES="checkoutlist commitinfo cvswrappers editinfo loginfo modules
-rcsinfo rcstemplate taginfo wrap unwrap"
-
-NEWSAMPLE=false
-for info in $EXAMPLES; do
- if [ -f $CVSROOT/CVSROOT/${info},v ]; then
- if [ ! -f $CVSROOT/CVSROOT/$info ]; then
- echo "Checking out $CVSROOT/CVSROOT/$info"
- echo " from $CVSROOT/CVSROOT/${info},v..."
- (cd $CVSROOT/CVSROOT; co -q $info)
- fi
- else
- NEWSAMPLE=true
- if [ -f $CVSROOT/CVSROOT/$info ]; then
- echo "Checking in $CVSROOT/CVSROOT/${info},v"
- echo " from $CVSROOT/CVSROOT/$info..."
- else
- echo "Creating a sample $CVSROOT/CVSROOT/$info file..."
- case $info in
- modules)
- sed -n -e '/END_REQUIRED_CONTENT/q' \
- -e p $CVSLIB/examples/modules > $CVSROOT/CVSROOT/modules
- ;;
- rcstemplate)
- cp $CVSLIB/examples/$info $CVSROOT/CVSROOT/$info
- ;;
- wrap|unwrap)
- cp $CVSLIB/examples/$info $CVSROOT/CVSROOT/$info
- chmod +x $CVSROOT/CVSROOT/$info
- ;;
- *)
- # comment out everything in all the other examples....
- sed -e 's/^\([^#]\)/#\1/' $CVSLIB/examples/$info > $CVSROOT/CVSROOT/$info
- ;;
- esac
- fi
- (cd $CVSROOT/CVSROOT; ci -q -u -t/dev/null -m"initial checkin of $info" $info)
- fi
-done
-
-if $NEWSAMPLE ; then
- echo "NOTE: You may wish to check out the CVSROOT module and edit any new"
- echo "configuration files to match your local requirements."
- echo ""
-fi
-
-# check to see if there are any references to the old CVSROOT.adm directory
-if grep CVSROOT.adm $CVSROOT/CVSROOT/modules >/dev/null 2>&1; then
- echo "Warning: your $CVSROOT/CVSROOT/modules file still"
- echo " contains references to the old CVSROOT.adm directory"
- echo " You should really change these to the new CVSROOT directory"
- echo ""
-fi
-
-# These files are generated from the contrib files.
-# FIXME: Is it really wise to overwrite possible local changes like this?
-# Normal folks will keep these up to date by modifying the source in
-# their CVS module and re-installing CVS, but is everyone OK with that?
-#
-#
-CONTRIBS="log commit_prep log_accum cln_hist"
-#
-for contrib in $CONTRIBS; do
- echo "Copying the new version of '${contrib}'"
- echo " to $CVSROOT/CVSROOT for you..."
- cp $CVSLIB/contrib/$contrib $CVSROOT/CVSROOT/$contrib
-done
-
-# XXX - also add a stub for the cvsignore file
-
-# Turn on history logging by default
-if [ ! -f $CVSROOT/CVSROOT/history ]; then
- echo "Enabling CVS history logging..."
- touch $CVSROOT/CVSROOT/history
- chmod g+w $CVSROOT/CVSROOT/history
- echo "(Remove $CVSROOT/CVSROOT/history to disable.)"
-fi
-
-# finish up by running mkmodules
-echo "All done! Running 'mkmodules' as my final step..."
-mkmodules $CVSROOT/CVSROOT
-
-exit 0
diff --git a/gnu/usr.bin/cvs/doc/cvs-paper.ms b/gnu/usr.bin/cvs/doc/cvs-paper.ms
deleted file mode 100644
index 567179b393f8..000000000000
--- a/gnu/usr.bin/cvs/doc/cvs-paper.ms
+++ /dev/null
@@ -1,1073 +0,0 @@
-.\" soelim cvs.ms | pic | tbl | troff -ms
-.\" @(#)cvs.ms 1.2 92/01/30
-.\"
-.\" troff source to the cvs USENIX article, Winter 1990, Washington, D.C.
-.\" Copyright (c) 1989, Brian Berliner
-.\"
-.\" This program is free software; you can redistribute it and/or modify
-.\" it under the terms of the GNU General Public License as published by
-.\" the Free Software Foundation; either version 1, or (at your option)
-.\" any later version.
-.\"
-.\" This program is distributed in the hope that it will be useful,
-.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
-.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-.\" GNU General Public License for more details.
-.\"
-.\" You should have received a copy of the GNU General Public License
-.\" along with this program; if not, write to the Free Software
-.\" Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-.\"
-.\" The author can be reached at: berliner@prisma.com
-.\"
-.de SP
-.if n .sp
-.if t .sp .5
-..
-.de hl
-.br
-.in +0.5i
-\l'\\n(LLu-1i'
-.in -0.5i
-.sp
-..
-.OH ""
-.nr PS 11
-.nr PO 1.25i
-.pl -0.2i
-.TL
-.ps 14
-.ft B
-.nf
-CVS II:
-Parallelizing Software Development
-.fi
-.ft
-.ps
-.AU
-.ps 12
-.ft I
-Brian Berliner
-.ft
-.ps
-.AI
-.ps 12
-.ft I
-Prisma, Inc.
-5465 Mark Dabling Blvd.
-Colorado Springs, CO 80918
-berliner@prisma.com
-.ft
-.ps
-.AB
-The program described in this paper fills a need in the UNIX
-community for a freely available tool to manage software revision and
-release control in a multi-developer, multi-directory, multi-group
-environment.
-This tool also addresses the increasing need for tracking third-party vendor
-source distributions while trying to maintain local modifications to
-earlier releases.
-.AE
-.NH
-Background
-.PP
-In large software development projects, it is usually necessary for more
-than one software developer to be modifying (usually different) modules of the
-code at the same time.
-Some of these code modifications are done in an
-experimental sense, at least until the code functions correctly, and some
-testing of the entire program is usually necessary.
-Then, the modifications are returned to a master source repository
-so that others in the project can
-enjoy the new bug-fix or functionality.
-In order to manage such a project, some sort of revision control system is
-necessary.
-.PP
-Specifically, UNIX\**
-.FS
-UNIX is a registered trademark of AT&T.
-.FE
-kernel development is an excellent example of the
-problems that an adequate revision control system must address.
-The SunOS\**
-.FS
-SunOS is a trademark of Sun Microsystems, Inc.
-.FE
-kernel is composed of over a thousand files spread across a
-hierarchy of dozens of directories.\**
-.FS
-Yes, the SunOS 4.0 kernel is composed of over a \fIthousand\fP files!
-.FE
-Pieces of the kernel must be edited
-by many software developers within an organization.
-While undesirable in
-theory, it is not uncommon to have two or more people making
-modifications to the same file within the kernel sources in
-order to facilitate a desired change.
-Existing revision control systems like
-.SM
-RCS
-.LG
-[Tichy] or
-.SM
-SCCS
-.LG
-[Bell] serialize file modifications by
-allowing only one developer to have a writable copy of a particular file at
-any one point in time.
-That developer is said to
-have \*Qlocked\*U the file for his exclusive use, and no other developer is
-allowed to check out a writable copy of the file until the locking
-developer has finished impeding others' productivity.
-Development pressures of productivity and deadlines
-often force organizations to require that multiple developers be able to
-simultaneously edit
-copies of the same revision controlled file.
-.PP
-The necessity for multiple developers to modify the same file concurrently
-questions the value of serialization-based policies in traditional revision
-control.
-This paper discusses the approach that
-Prisma took in adapting a standard revision control system,
-.SM
-RCS\c
-.LG
-, along with an existing public-domain collection of shell scripts that sits
-atop
-.SM
-RCS
-.LG
-and provides the basic conflict-resolution algorithms.
-The resulting
-program, \fBcvs\fP, addresses not only the issue of conflict-resolution in
-a multi-developer open-editing environment, but also the issues of
-software release control and vendor source support and integration.
-.NH
-The CVS Program
-.PP
-\fBcvs\fP
-(Concurrent Versions System)
-is a front end to the
-.SM
-RCS
-.LG
-revision control system which extends
-the notion of revision control from a collection of files in a single
-directory to a hierarchical collection of directories each containing
-revision controlled files.
-Directories and files in the \fBcvs\fP system can be combined together in
-many ways to form a software release.
-\fBcvs\fP
-provides the functions necessary to manage these software releases and to
-control the concurrent editing of source files among multiple software
-developers.
-.PP
-The six major features of \fBcvs\fP are listed below, and will be
-described in more detail in the following sections:
-.RS
-.IP 1.
-Concurrent access and conflict-resolution algorithms to guarantee that
-source changes are not \*Qlost.\*U
-.IP 2.
-Support for tracking third-party vendor source distributions while
-maintaining the local modifications made to those sources.
-.IP 3.
-A flexible module database that provides a symbolic mapping of names to
-components of a larger software distribution.
-This symbolic mapping provides for location independence within the software
-release and, for example, allows one to check out a copy of the \*Qdiff\*U
-program without ever knowing that the sources to \*Qdiff\*U actually reside
-in the \*Qbin/diff\*U directory.
-.IP 4.
-Configurable logging support allows all \*Qcommitted\*U source file changes
-to be logged using an arbitrary program to save the log messages in a file,
-notesfile, or news database.
-.IP 5.
-A software release can be symbolically tagged and checked out at any time
-based on that tag.
-An exact copy of a previous software release can be checked out at
-any time, \fIregardless\fP of whether files or directories have been
-added/removed from the \*Qcurrent\*U software release.
-As well,
-a \*Qdate\*U can be used to check out the \fIexact\fP version of the software
-release as of the specified date.
-.IP 6.
-A \*Qpatch\*U format file [Wall] can be produced between two software
-releases, even if the releases span multiple directories.
-.RE
-.PP
-The sources maintained by \fBcvs\fP are kept within a single directory
-hierarchy known as the \*Qsource repository.\*U
-This \*Qsource repository\*U holds the actual
-.SM
-RCS
-.LG
-\*Q,v\*U files directly, as well as a special per-repository directory
-(\c
-.SM
-CVSROOT.adm\c
-.LG
-) which contains a small number of administrative files that describe the
-repository and how it can be accessed.
-See Figure 1 for a picture of the \fBcvs\fP tree.
-.KF
-.hl
-.DS B
-.PS
-line from 4.112,9.200 to 5.550,8.887
-line from 5.447,8.884 to 5.550,8.887 to 5.458,8.933
-line from 4.112,9.200 to 4.550,8.950
-line from 4.451,8.978 to 4.550,8.950 to 4.476,9.021
-line from 4.112,9.200 to 3.737,8.887
-line from 3.798,8.971 to 3.737,8.887 to 3.830,8.932
-line from 3.612,8.762 to 4.737,8.137
-line from 4.638,8.164 to 4.737,8.137 to 4.662,8.208
-line from 3.612,8.762 to 3.737,8.137
-line from 3.693,8.231 to 3.737,8.137 to 3.742,8.240
-line from 3.612,8.762 to 2.612,8.200
-line from 2.687,8.271 to 2.612,8.200 to 2.712,8.227
-line from 2.362,9.262 to 2.737,8.950
-line from 2.645,8.995 to 2.737,8.950 to 2.677,9.033
-line from 2.362,9.262 to 1.925,8.950
-line from 1.992,9.028 to 1.925,8.950 to 2.021,8.988
-line from 3.362,9.762 to 4.050,9.387
-line from 3.950,9.413 to 4.050,9.387 to 3.974,9.457
-line from 3.362,9.762 to 2.487,9.387
-line from 2.570,9.450 to 2.487,9.387 to 2.589,9.404
-.ps 11
-"newfs.c,v" at 4.487,8.043 ljust
-.ps 11
-"mkfs.c,v" at 3.487,8.043 ljust
-.ps 11
-"Makefile,v" at 2.237,8.043 ljust
-.ps 11
-"newfs" at 3.487,8.793 ljust
-.ps 11
-"halt.c,v" at 5.487,8.793 ljust
-.ps 11
-"Makefile,v" at 4.237,8.793 ljust
-.ps 11
-"modules,v" at 2.487,8.793 ljust
-.ps 11
-"loginfo,v" at 1.488,8.793 ljust
-.ps 11
-"etc" at 3.987,9.293 ljust
-.ps 11
-"CVSROOT.adm" at 1.988,9.293 ljust
-.ps 11
-"/src/master" at 2.987,9.793 ljust
-.PE
-.DE
-.hl
-.ce 100
-.LG
-\fBFigure 1.\fP
-.SM
-\fBcvs\fP Source Repository
-.ce 0
-.sp
-.KE
-.NH 2
-Software Conflict Resolution\**
-.FS
-The basic conflict-resolution algorithms
-used in the \fBcvs\fP program find their roots
-in the original work done by Dick Grune at Vrije Universiteit in Amsterdam
-and posted to \fBcomp.sources.unix\fP in the volume 6 release sometime in 1986.
-This original version of \fBcvs\fP was a collection of shell scripts that
-combined to form a front end to the
-.SM
-RCS
-.LG
-programs.
-.FE
-.PP
-\fBcvs\fP allows several software developers to edit personal copies of a
-revision controlled file concurrently.
-The revision number of each checked out file is maintained independently
-for each user, and \fBcvs\fP forces the checked out file to be current with
-the \*Qhead\*U revision before it can be \*Qcommitted\*U as a permanent change.
-A checked out file is brought up-to-date with the \*Qhead\*U revision using
-the \*Qupdate\*U command of \fBcvs\fP.
-This command compares the \*Qhead\*U revision number with that of the user's
-file and performs an
-.SM
-RCS
-.LG
-merge operation if they are not the same.
-The result of the merge is a file that contains the user's modifications
-and those modifications that were \*Qcommitted\*U after the user
-checked out his version of the file (as well as a backup copy of the
-user's original file).
-\fBcvs\fP points out any conflicts during the merge.
-It is the user's responsibility to resolve these conflicts
-and to \*Qcommit\*U his/her changes when ready.
-.PP
-Although the \fBcvs\fP conflict-resolution algorithm was defined in 1986,
-it is remarkably similar to the \*QCopy-Modify-Merge\*U scenario included
-with NSE\**
-.FS
-NSE is the Network Software Environment, a product of Sun Microsystems, Inc.
-.FE
-and described in [Honda] and [Courington].
-The following explanation from [Honda] also applies to \fBcvs\fP:
-.QP
-Simply stated, a developer copies an object without locking it, modifies
-the copy, and then merges the modified copy with the original.
-This paradigm allows developers to work in isolation from one another since
-changes are made to copies of objects.
-Because locks are not used, development is not serialized and can proceed
-in parallel.
-Developers, however, must merge objects after the changes have been made.
-In particular, a developer must resolve conflicts when the same object has
-been modified by someone else.
-.PP
-In practice, Prisma has found that conflicts that occur when the same
-object has been modified by someone else are quite rare.
-When they do happen, the changes made by the other developer are usually
-easily resolved.
-This practical use has shown that the \*QCopy-Modify-Merge\*U paradigm is a
-correct and useful one.
-.NH 2
-Tracking Third-Party Source Distributions
-.PP
-Currently, a large amount of software is based on source
-distributions from a third-party distributor.
-It is often the case that local modifications are to be made to this
-distribution, \fIand\fP that the vendor's future releases should be
-tracked.
-Rolling your local modifications forward into the new vendor release is a
-time-consuming task, but \fBcvs\fP can ease this burden somewhat.
-The \fBcheckin\fP program of \fBcvs\fP initially sets up a source
-repository by integrating the source modules directly from the vendor's
-release, preserving the directory hierarchy of the vendor's distribution.
-The branch support of
-.SM
-RCS
-.LG
-is used to build this vendor release as a branch of the main
-.SM
-RCS
-.LG
-trunk.
-Figure 2 shows how the \*Qhead\*U tracks a sample vendor
-branch when no local modifications have been made to the file.
-.KF
-.hl
-.DS B
-.PS
-ellipse at 3.237,6.763 wid 1.000 ht 0.500
-dashwid = 0.050i
-line dashed from 3.237,7.513 to 3.737,7.513 to 3.737,9.762 to 4.237,9.762
-line from 4.138,9.737 to 4.237,9.762 to 4.138,9.787
-line dashed from 2.237,8.262 to 3.237,8.262 to 3.237,7.013
-line from 3.212,7.112 to 3.237,7.013 to 3.262,7.112
-line from 3.737,6.763 to 4.237,6.763
-line from 4.138,6.737 to 4.237,6.763 to 4.138,6.788
-line from 2.237,6.763 to 2.737,6.763
-line from 2.637,6.737 to 2.737,6.763 to 2.637,6.788
-line from 1.738,6.013 to 1.738,6.513
-line from 1.762,6.413 to 1.738,6.513 to 1.713,6.413
-line from 1.238,7.013 to 2.237,7.013 to 2.237,6.513 to 1.238,6.513 to 1.238,7.013
-line from 4.237,9.012 to 5.237,9.012 to 5.237,8.512 to 4.237,8.512 to 4.237,9.012
-line from 4.237,8.012 to 5.237,8.012 to 5.237,7.513 to 4.237,7.513 to 4.237,8.012
-line from 4.237,7.013 to 5.237,7.013 to 5.237,6.513 to 4.237,6.513 to 4.237,7.013
-line from 4.737,7.013 to 4.737,7.513
-line from 4.763,7.413 to 4.737,7.513 to 4.712,7.413
-line from 4.737,8.012 to 4.737,8.512
-line from 4.763,8.412 to 4.737,8.512 to 4.712,8.412
-line from 4.237,10.012 to 5.237,10.012 to 5.237,9.512 to 4.237,9.512 to 4.237,10.012
-line from 4.737,9.012 to 4.737,9.512
-line from 4.763,9.412 to 4.737,9.512 to 4.712,9.412
-line from 5.987,5.013 to 5.987,6.013 to 0.988,6.013 to 0.988,5.013 to 5.987,5.013
-.ps 11
-"\"HEAD\"" at 1.550,8.231 ljust
-.ps 11
-"'SunOS'" at 2.987,6.293 ljust
-.ps 11
-"1.1.1" at 3.050,6.793 ljust
-.ps 11
-"1.1" at 1.613,6.793 ljust
-.ps 11
-"1.1.1.1" at 4.487,6.793 ljust
-.ps 11
-"1.1.1.2" at 4.487,7.793 ljust
-.ps 11
-"1.1.1.3" at 4.487,8.793 ljust
-.ps 11
-"1.1.1.4" at 4.487,9.793 ljust
-.ps 11
-"'SunOS_4_0'" at 5.487,6.793 ljust
-.ps 11
-"'SunOS_4_0_1'" at 5.487,7.793 ljust
-.ps 11
-"'YAPT_5_5C'" at 5.487,8.793 ljust
-.ps 11
-"'SunOS_4_0_3'" at 5.487,9.793 ljust
-.ps 11
-"rcsfile.c,v" at 2.987,5.543 ljust
-.PE
-.DE
-.hl
-.ce 100
-.LG
-\fBFigure 2.\fP
-.SM
-\fBcvs\fP Vendor Branch Example
-.ce 0
-.sp .3
-.KE
-Once this is done, developers can check out files and make local changes to
-the vendor's source distribution.
-These local changes form a new branch to the tree which is then used as the
-source for future check outs.
-Figure 3 shows how the \*Qhead\*U moves to the main
-.SM
-RCS
-.LG
-trunk when a local modification is made.
-.KF
-.hl
-.DS B
-.PS
-ellipse at 3.237,6.763 wid 1.000 ht 0.500
-dashwid = 0.050i
-line dashed from 2.800,9.075 to 1.738,9.075 to 1.738,8.012
-line from 1.713,8.112 to 1.738,8.012 to 1.762,8.112
-line from 1.738,7.013 to 1.738,7.513
-line from 1.762,7.413 to 1.738,7.513 to 1.713,7.413
-line from 1.238,8.012 to 2.237,8.012 to 2.237,7.513 to 1.238,7.513 to 1.238,8.012
-line from 3.737,6.763 to 4.237,6.763
-line from 4.138,6.737 to 4.237,6.763 to 4.138,6.788
-line from 2.237,6.763 to 2.737,6.763
-line from 2.637,6.737 to 2.737,6.763 to 2.637,6.788
-line from 1.738,6.013 to 1.738,6.513
-line from 1.762,6.413 to 1.738,6.513 to 1.713,6.413
-line from 1.238,7.013 to 2.237,7.013 to 2.237,6.513 to 1.238,6.513 to 1.238,7.013
-line from 4.237,9.012 to 5.237,9.012 to 5.237,8.512 to 4.237,8.512 to 4.237,9.012
-line from 4.237,8.012 to 5.237,8.012 to 5.237,7.513 to 4.237,7.513 to 4.237,8.012
-line from 4.237,7.013 to 5.237,7.013 to 5.237,6.513 to 4.237,6.513 to 4.237,7.013
-line from 4.737,7.013 to 4.737,7.513
-line from 4.763,7.413 to 4.737,7.513 to 4.712,7.413
-line from 4.737,8.012 to 4.737,8.512
-line from 4.763,8.412 to 4.737,8.512 to 4.712,8.412
-line from 4.237,10.012 to 5.237,10.012 to 5.237,9.512 to 4.237,9.512 to 4.237,10.012
-line from 4.737,9.012 to 4.737,9.512
-line from 4.763,9.412 to 4.737,9.512 to 4.712,9.412
-line from 5.987,5.013 to 5.987,6.013 to 0.988,6.013 to 0.988,5.013 to 5.987,5.013
-.ps 11
-"1.2" at 1.613,7.793 ljust
-.ps 11
-"\"HEAD\"" at 2.862,9.043 ljust
-.ps 11
-"'SunOS'" at 2.987,6.293 ljust
-.ps 11
-"1.1.1" at 3.050,6.793 ljust
-.ps 11
-"1.1" at 1.613,6.793 ljust
-.ps 11
-"1.1.1.1" at 4.487,6.793 ljust
-.ps 11
-"1.1.1.2" at 4.487,7.793 ljust
-.ps 11
-"1.1.1.3" at 4.487,8.793 ljust
-.ps 11
-"1.1.1.4" at 4.487,9.793 ljust
-.ps 11
-"'SunOS_4_0'" at 5.487,6.793 ljust
-.ps 11
-"'SunOS_4_0_1'" at 5.487,7.793 ljust
-.ps 11
-"'YAPT_5_5C'" at 5.487,8.793 ljust
-.ps 11
-"'SunOS_4_0_3'" at 5.487,9.793 ljust
-.ps 11
-"rcsfile.c,v" at 2.987,5.543 ljust
-.PE
-.DE
-.hl
-.ce 100
-.LG
-\fBFigure 3.\fP
-.SM
-\fBcvs\fP Local Modification to Vendor Branch
-.ce 0
-.sp
-.KE
-.PP
-When a new version of the vendor's source distribution arrives, the
-\fBcheckin\fP program adds the new and changed vendor's files to the
-already existing source repository.
-For files that have not been changed locally, the new file from the
-vendor becomes the current \*Qhead\*U revision.
-For files that have been modified locally, \fBcheckin\fP warns that the
-file must be merged with the new vendor release.
-The \fBcvs\fP \*Qjoin\*U command is a useful tool that aids this process by
-performing the necessary
-.SM
-RCS
-.LG
-merge, as is done above when performing an \*Qupdate.\*U
-.PP
-There is also limited support for \*Qdual\*U derivations for source files.
-See Figure 4 for a sample dual-derived file.
-.KF
-.hl
-.DS B
-.PS
-ellipse at 2.337,8.575 wid 0.700 ht 0.375
-ellipse at 2.312,9.137 wid 0.700 ht 0.375
-line from 1.225,9.012 to 1.225,9.363
-line from 1.250,9.263 to 1.225,9.363 to 1.200,9.263
-line from 0.875,9.725 to 1.600,9.725 to 1.600,9.363 to 0.875,9.363 to 0.875,9.725
-line from 0.875,9.012 to 1.600,9.012 to 1.600,8.650 to 0.875,8.650 to 0.875,9.012
-line from 4.050,10.200 to 4.775,10.200 to 4.775,9.850 to 4.050,9.850 to 4.050,10.200
-line from 4.050,9.475 to 4.775,9.475 to 4.775,9.113 to 4.050,9.113 to 4.050,9.475
-line from 4.050,8.762 to 4.775,8.762 to 4.775,8.400 to 4.050,8.400 to 4.050,8.762
-line from 4.425,8.762 to 4.425,9.113
-line from 4.450,9.013 to 4.425,9.113 to 4.400,9.013
-line from 4.425,9.475 to 4.425,9.850
-line from 4.450,9.750 to 4.425,9.850 to 4.400,9.750
-line from 3.050,10.000 to 3.775,10.000 to 3.775,9.637 to 3.050,9.637 to 3.050,10.000
-line from 3.050,9.312 to 3.775,9.312 to 3.775,8.950 to 3.050,8.950 to 3.050,9.312
-line from 0.713,7.325 to 0.713,8.075 to 4.925,8.075 to 4.925,7.325 to 0.713,7.325
-line from 1.238,8.075 to 1.238,8.637
-line from 1.262,8.537 to 1.238,8.637 to 1.213,8.537
-line from 1.613,8.825 to 1.975,8.575
-line from 1.878,8.611 to 1.975,8.575 to 1.907,8.652
-line from 2.675,8.575 to 4.050,8.575
-line from 3.950,8.550 to 4.050,8.575 to 3.950,8.600
-line from 2.675,9.137 to 3.050,9.137
-line from 2.950,9.112 to 3.050,9.137 to 2.950,9.162
-line from 3.425,9.325 to 3.425,9.637
-line from 3.450,9.537 to 3.425,9.637 to 3.400,9.537
-line from 1.613,8.825 to 1.925,9.137
-line from 1.872,9.049 to 1.925,9.137 to 1.837,9.084
-.ps 11
-"'BSD'" at 2.138,9.481 ljust
-.ps 11
-"1.2" at 1.113,9.543 ljust
-.ps 11
-"1.1" at 1.125,8.831 ljust
-.ps 11
-"1.1.1.1" at 4.175,8.543 ljust
-.ps 11
-"1.1.1.2" at 4.175,9.281 ljust
-.ps 11
-"1.1.1.3" at 4.175,9.993 ljust
-.ps 11
-"1.1.2.2" at 3.175,9.793 ljust
-.ps 11
-"1.1.2.1" at 3.175,9.106 ljust
-.ps 11
-"rcsfile.c,v" at 2.425,7.706 ljust
-.ps 11
-"1.1.1" at 2.175,8.568 ljust
-.ps 11
-"'SunOS'" at 2.125,8.243 ljust
-.ps 11
-"1.1.2" at 2.163,9.131 ljust
-.PE
-.DE
-.hl
-.ce 100
-.LG
-\fBFigure 4.\fP
-.SM
-\fBcvs\fP Support For \*QDual\*U Derivations
-.ce 0
-.sp
-.KE
-This example tracks the SunOS distribution but includes major changes from
-Berkeley.
-These BSD files are saved directly in the
-.SM
-RCS
-.LG
-file off a new branch.
-.NH 2
-Location Independent Module Database
-.PP
-\fBcvs\fP contains support for a simple, yet powerful, \*Qmodule\*U database.
-For reasons of efficiency, this database is stored in \fBndbm\fP\|(3) format.
-The module database is used to apply names to collections of directories
-and files as a matter of convenience for checking out pieces of a large
-software distribution.
-The database records the physical location of the sources as a form of
-information hiding, allowing one to check out whole directory hierarchies
-or individual files without regard for their actual location within the
-global source distribution.
-.PP
-Consider the following small sample of a module database, which must be
-tailored manually to each specific source repository environment:
-.DS
-\f(CW #key [-option argument] directory [files...]
- diff bin/diff
- libc lib/libc
- sys -o sys/tools/make_links sys
- modules -i mkmodules CVSROOT.adm modules
- kernel -a sys lang/adb
- ps bin Makefile ps.c\fP
-.DE
-.PP
-The \*Qdiff\*U and \*Qlibc\*U modules refer to whole directory hierarchies that
-are extracted on check out.
-The \*Qsys\*U module extracts the \*Qsys\*U hierarchy, and runs the
-\*Qmake_links\*U program at the end of the check out process (the \fI-o\fP
-option specifies a program to run on check\fIo\fPut).
-The \*Qmodules\*U module allows one to edit the module database file and
-runs the \*Qmkmodules\*U program on check\fIi\fPn to regenerate the
-\fBndbm\fP database that \fBcvs\fP uses.
-The \*Qkernel\*U module is an alias (as the \fI-a\fP option specifies)
-which causes the remaining arguments after the \fI-a\fP to be interpreted
-exactly as if they had been specified on the command line.
-This is useful for objects that require shared pieces of code from far away
-places to be compiled (as is the case with the kernel debugger, \fBkadb\fP,
-which shares code with the standard \fBadb\fP debugger).
-The \*Qps\*U module shows that the source for \*Qps\*U lives in the \*Qbin\*U
-directory, but only \fIMakefile\fP and \fIps.c\fP are required to build the
-object.
-.PP
-The module database at Prisma is now populated for the entire UNIX
-distribution and thereby allows us to issue the
-following convenient commands to check out components of the UNIX
-distribution without regard for their actual location within the master source
-repository:
-.DS
-\f(CW example% cvs checkout diff
- example% cvs checkout libc ps
- example% cd diff; make\fP
-.DE
-.PP
-In building the module database file, it is quite possible to have name
-conflicts within a global software distribution.
-For example, SunOS provides two \fBcat\fP programs:
-one for the standard environment, \fI/bin/cat\fP, and one for the System V
-environment, \fI/usr/5bin/cat\fP.
-We resolved this conflict by naming the standard \fBcat\fP module
-\*Qcat\*U, and the System V \fBcat\fP module \*Q5cat\*U.
-Similar name modifications must be applied to other conflicting names, as
-might be found between a utility program and a library function, though
-Prisma chose not to include individual library functions within the module
-database at this time.
-.NH 2
-Configurable Logging Support
-.PP
-The \fBcvs\fP \*Qcommit\*U command is used to make a permanent change to the
-master source repository (where the
-.SM
-RCS
-.LG
-\*Q,v\*U files live).
-Whenever a \*Qcommit\*U is done, the log message for the change is carefully
-logged by an arbitrary program (in a file, notesfile, news database, or
-mail).
-For example, a collection of these updates can be used to produce release
-notices.
-\fBcvs\fP can be configured to send log updates through one or more filter
-programs, based on a regular expression match on the directory that is
-being changed.
-This allows multiple related or unrelated projects to exist within a single
-\fBcvs\fP source repository tree, with each different project sending its
-\*Qcommit\*U reports to a unique log device.
-.PP
-A sample logging configuration file might look as follows:
-.DS
-\f(CW #regex filter-program
- DEFAULT /usr/local/bin/nfpipe -t %s utils.updates
- ^diag /usr/local/bin/nfpipe -t %s diag.updates
- ^local /usr/local/bin/nfpipe -t %s local.updates
- ^perf /usr/local/bin/nfpipe -t %s perf.updates
- ^sys /usr/local/bin/nfpipe -t %s kernel.updates\fP
-.DE
-.PP
-This sample allows the diagnostics and performance groups to
-share the same source repository with the kernel and utilities groups.
-Changes that they make are sent directly to their own notesfile [Essick]
-through the \*Qnfpipe\*U program.
-A sufficiently simple title is substituted for the \*Q%s\*U argument before
-the filter program is executed.
-This logging configuration file is tailored manually to each specific
-source repository environment.
-.NH 2
-Tagged Releases and Dates
-.PP
-Any release can be given a symbolic tag name that is stored directly in the
-.SM
-RCS
-.LG
-files.
-This tag can be used at any time to get an exact copy of any previous
-release.
-With equal ease, one can also extract an exact copy of the source files as
-of any arbitrary date in the past as well.
-Thus, all that's required to tag the current kernel, and to tag the kernel
-as of the Fourth of July is:
-.DS
-\f(CW example% cvs tag TEST_KERNEL kernel
- example% cvs tag -D 'July 4' PATRIOTIC_KERNEL kernel\fP
-.DE
-The following command would retrieve an exact copy of the test kernel at
-some later date:
-.DS
-\f(CW example% cvs checkout -fp -rTEST_KERNEL kernel\fP
-.DE
-The \fI-f\fP option causes only files that match the specified tag to be
-extracted, while the \fI-p\fP option automatically prunes empty directories.
-Consequently, directories added to the kernel after the test kernel was
-tagged are not included in the newly extracted copy of the test kernel.
-.PP
-The \fBcvs\fP date support has exactly the same interface as that provided
-with
-.SM
-RCS\c
-.LG
-, however \fBcvs\fP must process the \*Q,v\*U files directly due to the
-special handling required by the vendor branch support.
-The standard
-.SM
-RCS
-.LG
-date handling only processes one branch (or the main trunk) when checking
-out based on a date specification.
-\fBcvs\fP must instead process the current \*Qhead\*U branch and, if a
-match is not found, proceed to look for a match on the vendor branch.
-This, combined with reasons of performance, is why \fBcvs\fP processes
-revision (symbolic and numeric) and date specifications directly from the
-\*Q,v\*U files.
-.NH 2
-Building \*Qpatch\*U Source Distributions
-.PP
-\fBcvs\fP can produce a \*Qpatch\*U format [Wall] output file which can be
-used to bring a previously released software distribution current with the
-newest release.
-This patch file supports an entire directory hierarchy within a single
-patch, as well as being able to add whole new files to the previous
-release.
-One can combine symbolic revisions and dates together to display changes in
-a very generic way:
-.DS
-\f(CW example% cvs patch -D 'December 1, 1988' \e
- -D 'January 1, 1989' sys\fP
-.DE
-This example displays the kernel changes made in the month of December,
-1988.
-To release a patch file, for example, to take the \fBcvs\fP distribution
-from version 1.0 to version 1.4 might be done as follows:
-.DS
-\f(CW example% cvs patch -rCVS_1_0 -rCVS_1_4 cvs\fP
-.DE
-.NH
-CVS Experience
-.NH 2
-Statistics
-.PP
-A quick summary of the scale that \fBcvs\fP is addressing today
-can be found in Table 1.
-.KF
-.TS
-box center tab(:);
-c s
-c s
-c | c
-l | n .
-\fB\s+2Revision Control Statistics at Prisma
-as of 11/11/89\fP\s-2
-_
-How Many...:Total
-=
-Files:17243
-Directories:1005
-Lines of code:3927255
-Removed files:131
-Software developers:14
-Software groups:6
-Megabytes of source:128
-.TE
-.ce 100
-.LG
-\fBTable 1.\fP
-.SM
-\fBcvs\fP Statistics
-.ce 0
-.sp .3
-.KE
-Table 2 shows the history of files changed or added and the number
-of source lines affected by the change at Prisma.
-Only changes made to the kernel sources are included.
-.KF
-.TS
-box center tab(:);
-c s s s s
-c s s s s
-c || c | c || c | c
-c || c | c || c | c
-l || n | n || n | n.
-\fB\s+2Prisma Kernel Source File Changes
-By Month, 1988-1989\fP\s-2
-_
-Month:# Changed:# Lines:# Added:# Lines
-\^:Files:Changed:Files:Added
-=
-Dec:87:3619:68:9266
-Jan:39:4324:0:0
-Feb:73:1578:5:3550
-Mar:99:5301:18:11461
-Apr:112:7333:11:5759
-May:138:5371:17:13986
-Jun:65:2261:27:12875
-Jul:34:2000:1:58
-Aug:65:6378:8:4724
-Sep:266:23410:113:39965
-Oct:22:621:1:155
-Total:1000:62196:269:101799
-.TE
-.ce 100
-.LG
-\fBTable 2.\fP
-.SM
-\fBcvs\fP Usage History for the Kernel
-.ce 0
-.sp
-.KE
-The large number of source file changes made in September are the result of
-merging the SunOS 4.0.3 sources into the kernel.
-This merge process is described in section 3.3.
-.NH 2
-Performance
-.PP
-The performance of \fBcvs\fP is currently quite reasonable.
-Little effort has been expended on tuning \fBcvs\fP, although performance
-related decisions were made during the \fBcvs\fP design.
-For example, \fBcvs\fP parses the
-.SM
-RCS
-.LG
-\*Q,v\*U files directly instead of running an
-.SM
-RCS
-.LG
-process.
-This includes following branches as well as integrating with the vendor
-source branches and the main trunk when checking out files based on a date.
-.PP
-Checking out the entire kernel source tree (1223 files/59 directories)
-currently takes 16 wall clock minutes on a Sun-4/280.
-However, bringing the tree up-to-date with the current kernel sources, once
-it has been checked out, takes only 1.5 wall clock minutes.
-Updating the \fIcomplete\fP 128 MByte source tree under \fBcvs\fP control
-(17243 files/1005 directories) takes roughly 28 wall clock minutes and
-utilizes one-third of the machine.
-For now this is entirely acceptable; improvements on these numbers will
-possibly be made in the future.
-.NH 2
-The SunOS 4.0.3 Merge
-.PP
-The true test of the \fBcvs\fP vendor branch support came with the arrival
-of the SunOS 4.0.3 source upgrade tape.
-As described above, the \fBcheckin\fP program was used to install the new
-sources and the resulting output file listed the files that had been
-locally modified, needing to be merged manually.
-For the kernel, there were 94 files in conflict.
-The \fBcvs\fP \*Qjoin\*U command was used on each of the 94 conflicting
-files, and the remaining conflicts were resolved.
-.PP
-The \*Qjoin\*U command performs an \fBrcsmerge\fP operation.
-This in turn uses \fI/usr/lib/diff3\fP to produce a three-way diff file.
-As it happens, the \fBdiff3\fP program has a hard-coded limit of 200
-source-file changes maximum.
-This proved to be too small for a few of the kernel files that needed
-merging by hand, due to the large number of local changes that Prisma had
-made.
-The \fBdiff3\fP problem was solved by increasing the hard-coded limit by an
-order of magnitude.
-.PP
-The SunOS 4.0.3 kernel source upgrade distribution contained
-346 files, 233 of which were modifications to previously released files,
-and 113 of which were newly added files.
-\fBcheckin\fP added the 113 new files to the source repository
-without intervention.
-Of the 233 modified files, 139 dropped in cleanly by \fBcheckin\fP, since
-Prisma had not made any local changes to them, and 94 required manual
-merging due to local modifications.
-The 233 modified files consisted of 20,766 lines of differences.
-It took one developer two days to manually merge the 94 files using the
-\*Qjoin\*U command and resolving conflicts manually.
-An additional day was required for kernel debugging.
-The entire process of merging over 20,000 lines of differences was
-completed in less than a week.
-This one time-savings alone was justification enough for the \fBcvs\fP
-development effort; we expect to gain even more when tracking future SunOS
-releases.
-.NH
-Future Enhancements and Current Bugs
-.PP
-Since \fBcvs\fP was designed to be incomplete, for reasons of design
-simplicity, there are naturally a good
-number of enhancements that can be made to make it more useful.
-As well, some nuisances exist in the current implementation.
-.RS
-.IP \(bu 3
-\fBcvs\fP does not currently \*Qremember\*U who has a checked out a copy of a
-module.
-As a result, it is impossible to know who might be working on the same
-module that you are.
-A simple-minded database that is updated nightly would likely suffice.
-.IP \(bu 3
-Signal processing, keyboard interrupt handling in particular, is currently
-somewhat weak.
-This is due to the heavy use of the \fBsystem\fP\|(3) library
-function to execute
-.SM
-RCS
-.LG
-programs like \fBco\fP and \fBci\fP.
-It sometimes takes multiple interrupts to make \fBcvs\fP quit.
-This can be fixed by using a home-grown \fBsystem\fP\|() replacement.
-.IP \(bu 3
-Security of the source repository is currently not dealt with directly.
-The usual UNIX approach of user-group-other security permissions through
-the file system is utilized, but nothing else.
-\fBcvs\fP could likely be a set-group-id executable that checks a
-protected database to verify user access permissions for particular objects
-before allowing any operations to affect those objects.
-.IP \(bu 3
-With every checked-out directory, \fBcvs\fP maintains some administrative
-files that record the current revision numbers of the checked-out files as
-well as the location of the respective source repository.
-\fBcvs\fP does not recover nicely at all if these administrative files are
-removed.
-.IP \(bu 3
-The source code for \fBcvs\fP has been tested extensively on Sun-3 and
-Sun-4 systems, all running SunOS 4.0 or later versions of the operating
-system.
-Since the code has not yet been compiled under other platforms, the overall
-portability of the code is still questionable.
-.IP \(bu 3
-As witnessed in the previous section, the \fBcvs\fP method for tracking
-third party vendor source distributions can work quite nicely.
-However, if the vendor changes the directory structure or the file names
-within the source distribution, \fBcvs\fP has no way of matching the old
-release with the new one.
-It is currently unclear as to how to solve this, though it is certain to
-happen in practice.
-.RE
-.NH
-Availability
-.PP
-The \fBcvs\fP program sources can be found in a recent posting to the
-\fBcomp.sources.unix\fP newsgroup.
-It is also currently available via anonymous ftp from \*Qprisma.com\*U.
-Copying rights for \fBcvs\fP will be covered by the GNU General Public
-License.
-.NH
-Summary
-.PP
-Prisma has used \fBcvs\fP since December, 1988.
-It has evolved to meet our specific needs of revision and release control.
-We will make our code freely available so that others can
-benefit from our work, and can enhance \fBcvs\fP to meet broader needs yet.
-.PP
-Many of the other software release and revision control systems, like the
-one described in [Glew], appear to use a collection of tools that are
-geared toward specific environments \(em one set of tools for the kernel,
-one set for \*Qgeneric\*U software, one set for utilities, and one set for
-kernel and utilities.
-Each of these tool sets apparently handle some specific aspect of the
-problem uniquely.
-\fBcvs\fP took a somewhat different approach.
-File sharing through symbolic or hard links is not addressed; instead, the
-disk space is simply burned since it is \*Qcheap.\*U
-Support for producing objects for multiple architectures is not addressed;
-instead, a parallel checked-out source tree must be used for each
-architecture, again wasting disk space to simplify complexity and ease of
-use \(em punting on this issue allowed \fIMakefile\fPs to remain
-unchanged, unlike the approach taken in [Mahler], thereby maintaining closer
-compatibility with the third-party vendor sources.
-\fBcvs\fP is essentially a source-file server, making no assumptions or
-special handling of the sources that it controls.
-To \fBcvs\fP:
-.QP
-A source is a source, of course, of course, unless of course the source is
-Mr. Ed.\**
-.FS
-\fBcvs\fP, of course, does not really discriminate against Mr. Ed.\**
-.FE
-.FS
-Yet.
-.FE
-.LP
-Sources are maintained, saved, and retrievable at any time based on
-symbolic or numeric revision or date in the past.
-It is entirely up to \fBcvs\fP wrapper programs to provide for release
-environments and such.
-.PP
-The major advantage of \fBcvs\fP over the
-many other similar systems that have already been designed is the
-simplicity of \fBcvs\fP.
-\fBcvs\fP contains only three programs that do all the work of release
-and revision control, and two manually-maintained administrative
-files for each source repository.
-Of course, the deciding factor of any tool is whether people use it, and if
-they even \fIlike\fP to use it.
-At Prisma, \fBcvs\fP prevented members of the kernel
-group from killing each other.
-.NH
-Acknowledgements
-.PP
-Many thanks to Dick Grune at Vrije Universiteit in Amsterdam for his work
-on the original version of \fBcvs\fP and for making it available to the
-world.
-Thanks to Jeff Polk of Prisma for helping with the design of the module
-database, vendor branch support, and for writing the \fBcheckin\fP shell
-script.
-Thanks also to the entire software group at Prisma for taking the
-time to review the paper and correct my grammar.
-.NH
-References
-.IP [Bell] 12
-Bell Telephone Laboratories.
-\*QSource Code Control System User's Guide.\*U
-\fIUNIX System III Programmer's Manual\fP, October 1981.
-.IP [Courington] 12
-Courington, W.
-\fIThe Network Software Environment\fP,
-Sun Technical Report FE197-0, Sun Microsystems Inc, February 1989.
-.IP [Essick] 12
-Essick, Raymond B. and Robert Bruce Kolstad.
-\fINotesfile Reference Manual\fP,
-Department of Computer Science Technical Report #1081,
-University of Illinois at Urbana-Champaign, Urbana, Illinois,
-1982, p. 26.
-.IP [Glew] 12
-Glew, Andy.
-\*QBoxes, Links, and Parallel Trees:
-Elements of a Configuration Management System.\*U
-\fIWorkshop Proceedings of the Software Management Conference\fP, USENIX,
-New Orleans, April 1989.
-.IP [Grune] 12
-Grune, Dick.
-Distributed the original shell script version of \fBcvs\fP in the
-\fBcomp.sources.unix\fP volume 6 release in 1986.
-.IP [Honda] 12
-Honda, Masahiro and Terrence Miller.
-\*QSoftware Management Using a CASE Environment.\*U
-\fIWorkshop Proceedings of the Software Management Conference\fP, USENIX,
-New Orleans, April 1989.
-.IP [Mahler] 12
-Mahler, Alex and Andreas Lampen.
-\*QAn Integrated Toolset for Engineering Software Configurations.\*U
-\fIProceedings of the ACM SIGSOFT/SIGPLAN Software Engineering Symposium on
-Practical Software Development Environments\fP, ACM, Boston, November 1988.
-Described is the \fBshape\fP toolkit posted to the
-\fBcomp.sources.unix\fP newsgroup in the volume 19 release.
-.IP [Tichy] 12
-Tichy, Walter F.
-\*QDesign, Implementation, and Evaluation of a Revision Control System.\*U
-\fIProceedings of the 6th International Conference on Software
-Engineering\fP, IEEE, Tokyo, September 1982.
-.IP [Wall] 12
-Wall, Larry.
-The \fBpatch\fP program is an indispensable tool for applying a diff file
-to an original.
-Can be found on uunet.uu.net in ~ftp/pub/patch.tar.
diff --git a/gnu/usr.bin/cvs/doc/cvs.texinfo b/gnu/usr.bin/cvs/doc/cvs.texinfo
deleted file mode 100644
index ef125f524b6e..000000000000
--- a/gnu/usr.bin/cvs/doc/cvs.texinfo
+++ /dev/null
@@ -1,6931 +0,0 @@
-\input texinfo @c -*-texinfo-*-
-@comment cvs.texinfo,v 1.6 1995/10/12 23:39:26 kfogel Exp
-@comment Documentation for CVS.
-@comment Copyright (C) 1992, 1993 Signum Support AB
-@comment Copyright (C) 1993 Free Software Foundation, Inc.
-
-@comment This file is part of the CVS distribution.
-
-@comment CVS is free software; you can redistribute it and/or modify
-@comment it under the terms of the GNU General Public License as published by
-@comment the Free Software Foundation; either version 1, or (at your option)
-@comment any later version.
-
-@comment CVS is distributed in the hope that it will be useful,
-@comment but WITHOUT ANY WARRANTY; without even the implied warranty of
-@comment MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-@comment GNU General Public License for more details.
-
-@comment You should have received a copy of the GNU General Public License
-@comment along with CVS; see the file COPYING. If not, write to
-@comment the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
-@afourpaper
-@setfilename cvs.info
-@settitle CVS---Concurrent Versions System
-@setchapternewpage odd
-
-@c -- TODO list:
-@c -- Fix all lines that match "^@c -- "
-@c -- Document how CVS finds the binaries it executes.
-@c Things to include in the index:
-@c Finding RCS binaries
-@c Path to RCS binaries
-@c RCS, how CVS finds them
-@c s/RCS/diff/
-@c -- More on binary files
-
-@ifinfo
-Copyright @copyright{} 1992, 1993 Signum Support AB
-Copyright @copyright{} 1993, 1994 Free Software Foundation, Inc.
-
-Permission is granted to make and distribute verbatim copies of
-this manual provided the copyright notice and this permission notice
-are preserved on all copies.
-
-@ignore
-Permission is granted to process this file through Tex and print the
-results, provided the printed document carries copying permission
-notice identical to this one except for the removal of this paragraph
-(this paragraph not being relevant to the printed manual).
-
-@end ignore
-Permission is granted to copy and distribute modified versions of this
-manual under the conditions for verbatim copying, provided also that the
-section entitled ``GNU General Public License'' is included exactly as
-in the original, and provided that the entire resulting derived work is
-distributed under the terms of a permission notice identical to this one.
-
-Permission is granted to copy and distribute translations of this manual
-into another language, under the above conditions for modified versions,
-except that the section entitled ``GNU General Public License'' and
-this permission notice may be included in translations approved by the
-Free Software Foundation instead of in the original English.
-@end ifinfo
-
-@comment The titlepage section does not appear in the Info file.
-@titlepage
-@sp 4
-@comment The title is printed in a large font.
-@center @titlefont{Version Management}
-@sp
-@center @titlefont{with}
-@sp
-@center @titlefont{CVS}
-@sp 2
-@center for @sc{cvs} 1.6+
-@comment -release-
-@sp 3
-@center Per Cederqvist
-@sp 3
-@center last updated 12 Oct 1995
-@comment -date-
-
-@comment The following two commands start the copyright page
-@comment for the printed manual. This will not appear in the Info file.
-@page
-@vskip 0pt plus 1filll
-Copyright @copyright{} 1992, 1993 Signum Support AB
-
-Permission is granted to make and distribute verbatim copies of
-this manual provided the copyright notice and this permission notice
-are preserved on all copies.
-
-Permission is granted to copy and distribute modified versions of this
-manual under the conditions for verbatim copying, provided also that the
-section entitled ``GNU General Public License'' is included exactly as
-in the original, and provided that the entire resulting derived work is
-distributed under the terms of a permission notice identical to this one.
-
-Permission is granted to copy and distribute translations of this manual
-into another language, under the above conditions for modified versions,
-except that the section entitled ``GNU General Public License'' and
-this permission notice may be included in translations approved by the
-Free Software Foundation instead of in the original English.
-@end titlepage
-
-@comment ================================================================
-@comment The real text starts here
-@comment ================================================================
-
-@ifinfo
-@c ---------------------------------------------------------------------
-@node Top
-@top
-
-This info manual describes how to use and administer
-@sc{cvs} and is updated to release 1.4 or something
-similar.
-@end ifinfo
-
-@menu
-* Preface:: About this manual
-* What is CVS?:: What is CVS?
-* Basic concepts:: Basic concepts of revision management
-* A sample session:: A tour of basic CVS usage
-* Repository:: Where all your sources are stored
-* Starting a new project:: Starting a project with CVS
-* Multiple developers:: How CVS helps a group of developers
-* Branches:: Parallel development explained
-* Merging:: How to move changes between branches
-* Recursive behavior:: CVS descends directories
-* Adding files:: Adding files to a module
-* Removing files:: Removing files from a module
-* Tracking sources:: Tracking third-party sources
-* Moving files:: Moving and renaming files
-* Moving directories:: Moving and renaming directories
-* Keyword substitution:: CVS can include the revision inside the file
-* Revision management:: Policy questions for revision management
-* Invoking CVS:: Reference manual for CVS commands
-* Administrative files:: Reference manual for the Administrative files
-* Environment variables:: All environment variables which affect CVS
-* Troubleshooting:: Some tips when nothing works
-* Copying:: GNU GENERAL PUBLIC LICENSE
-* Index:: Index
-@end menu
-
-@c ---------------------------------------------------------------------
-@node Preface
-@unnumbered About this manual
-@cindex Preface
-@cindex About this manual
-
-Up to this point, one of the weakest parts of @sc{cvs}
-has been the documentation. @sc{cvs} is a complex
-program. Previous versions of the manual were written
-in the manual page format, which is not really well
-suited for such a complex program.
-
-When writing this manual, I had several goals in mind:
-
-@itemize @bullet
-@item
-No knowledge of @sc{rcs} should be necessary.
-
-@item
-No previous knowledge of revision control software
-should be necessary. All terms, such as @dfn{revision
-numbers}, @dfn{revision trees} and @dfn{merging} are
-explained as they are introduced.
-
-@item
-The manual should concentrate on the things @sc{cvs} users
-want to do, instead of what the @sc{cvs} commands can do.
-The first part of this manual leads you through things
-you might want to do while doing development, and
-introduces the relevant @sc{cvs} commands as they are
-needed.
-
-@item
-Information should be easy to find. In the reference
-manual in the appendices almost all information about
-every @sc{cvs} command is gathered together. There is also
-an extensive index, and a lot of cross references.
-@end itemize
-
-@cindex Signum Support
-@cindex Support, getting CVS support
-This manual was contributed by Signum Support AB in
-Sweden. Signum is yet another in the growing list of
-companies that support free software. You are free to
-copy both this manual and the @sc{cvs} program.
-@xref{Copying}, for the details. Signum Support offers
-@c -- Check this reference! It has been bogus in the past.
-support contracts and binary distribution for many
-programs, such as @sc{cvs}, @sc{gnu} Emacs, the
-@sc{gnu} C compiler and others. You can also buy
-hardcopies of this manual from us. Write to us for
-more information.
-
-@example
-Signum Support AB
-Box 2044
-S-580 02 Linkoping
-Sweden
-
-Email: info@@signum.se
-Phone: +46 (0)13 - 21 46 00
-Fax: +46 (0)13 - 21 47 00
-@end example
-
-@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-@menu
-* Checklist::
-* Credits::
-* BUGS::
-@end menu
-
-@node Checklist
-@unnumberedsec Checklist for the impatient reader
-
-@sc{cvs} is a complex system. You will need to read
-the manual to be able to use all of its capabilities.
-There are dangers that can easily be avoided if you
-know about them, and this manual tries to warn you
-about them. This checklist is intended to help you
-avoid the dangers without reading the entire manual.
-If you intend to read the entire manual you can skip
-this table.
-
-@table @asis
-@item Binary files
-@sc{cvs} can handle binary files, but
-you must have @sc{rcs} release 5.5 or later and
-a release of @sc{gnu} diff that supports the @samp{-a}
-flag (release 1.15 and later are OK). You must also
-configure both @sc{rcs} and @sc{cvs} to handle binary
-files when you install them.
-
-Keword substitution can be a source of trouble with
-binary files. @xref{Keyword substitution}, for
-solutions.
-
-@item The @code{admin} command
-Uncareful use of the @code{admin} command can cause
-@sc{cvs} to cease working. @xref{admin}, before trying
-to use it.
-@end table
-
-@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-@node Credits
-@unnumberedsec Credits
-
-@cindex Contributors (manual)
-@cindex Credits (manual)
-Roland Pesch, Cygnus Support <@t{pesch@@cygnus.com}>
-wrote the manual pages which were distributed with
-@sc{cvs} 1.3. Appendix A and B contain much text that
-was extracted from them. He also read an early draft
-of this manual and contributed many ideas and
-corrections.
-
-The mailing-list @code{info-cvs} is sometimes
-informative. I have included information from postings
-made by the following persons:
-David G. Grubbs <@t{dgg@@think.com}>.
-
-Some text has been extracted from the man pages for
-@sc{rcs}.
-
-The @sc{cvs} @sc{faq} (@pxref{What is CVS?}) by David
-G. Grubbs has been used as a check-list to make sure
-that this manual is as complete as possible. (This
-manual does however not include all of the material in
-the @sc{faq}). The @sc{faq} contains a lot of useful
-information.
-
-In addition, the following persons have helped by
-telling me about mistakes I've made:
-Roxanne Brunskill <@t{rbrunski@@datap.ca}>,
-Kathy Dyer <@t{dyer@@phoenix.ocf.llnl.gov}>,
-Karl Pingle <@t{pingle@@acuson.com}>,
-Thomas A Peterson <@t{tap@@src.honeywell.com}>,
-Inge Wallin <@t{ingwa@@signum.se}>,
-Dirk Koschuetzki <@t{koschuet@@fmi.uni-passau.de}>
-and Michael Brown <@t{brown@@wi.extrel.com}>.
-
-@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-@node BUGS
-@unnumberedsec BUGS
-
-@cindex Bugs, known in this manual
-@cindex Known bugs in this manual
-This manual is known to have room for improvement.
-Here is a list of known deficiencies:
-
-@itemize @bullet
-@item
-In the examples, the output from @sc{cvs} is sometimes
-displayed, sometimes not.
-
-@item
-The input that you are supposed to type in the examples
-should have a different font than the output from the
-computer.
-
-@item
-This manual should be clearer about what file
-permissions you should set up in the repository, and
-about setuid/setgid.
-
-@item
-Some of the chapters are not yet complete. They are
-noted by comments in the @file{cvs.texinfo} file.
-
-@item
-@cindex Reporting bugs (manual)
-@cindex Bugs, reporting (manual)
-@cindex Errors, reporting (manual)
-This list is not complete. If you notice any error,
-omission, or something that is unclear, please send
-mail to @t{bug-cvs@@prep.ai.mit.edu}.
-@end itemize
-
-I hope that you will find this manual useful, despite
-the above-mentioned shortcomings.
-
-@flushright
-
-Linkoping, October 1993
-Per Cederqvist
-@end flushright
-
-@c ---------------------------------------------------------------------
-@node What is CVS?
-@chapter What is CVS?
-@cindex What is CVS?
-@cindex Introduction to CVS
-@cindex CVS, introduction to
-
-@sc{cvs} is a version control system. Using it, you can
-record the history of your source files.
-
-@c -- ///
-@c -- ///Those who cannot remember the past are condemned to repeat it.
-@c -- /// -- George Santayana
-@c -- //////
-
-@c -- Insert history quote here!
-For example, bugs sometimes creep in when
-software is modified, and you might not detect the bug
-until a long time after you make the modification.
-With @sc{cvs}, you can easily retrieve old versions to see
-exactly which change caused the bug. This can
-sometimes be a big help.
-
-You could of course save every version of every file
-you have ever created. This would
-however waste an enormous amount of disk space. @sc{cvs}
-stores all the versions of a file in a single file in a
-clever way that only stores the differences between
-versions.
-
-@sc{cvs} also helps you if you are part of a group of people working
-on the same project. It is all too easy to overwrite
-each others' changes unless you are extremely careful.
-Some editors, like @sc{gnu} Emacs, try to make sure that
-the same file is never modified by two people at the
-same time. Unfortunately, if someone is using another
-editor, that safeguard will not work. @sc{cvs} solves this problem
-by insulating the different developers from each other. Every
-developer works in his own directory, and @sc{cvs} merges
-the work when each developer is done.
-
-@cindex History of CVS
-@cindex CVS, history of
-@cindex Credits (CVS program)
-@cindex Contributors (CVS program)
-@sc{cvs} started out as a bunch of shell scripts written by
-Dick Grune, posted to @code{comp.sources.unix} in the volume 6
-release of December, 1986. While no actual code from
-these shell scripts is present in the current version
-of @sc{cvs} much of the @sc{cvs} conflict resolution algorithms
-come from them.
-
-In April, 1989, Brian Berliner designed and coded @sc{cvs}.
-Jeff Polk later helped Brian with the design of the @sc{cvs}
-module and vendor branch support.
-
-@cindex Source, getting CVS source
-You can get @sc{cvs} via anonymous ftp from a number of
-sites, for instance @t{prep.ai.mit.edu} in
-@file{pub/gnu}.
-
-@cindex Mailing list
-@cindex List, mailing list
-There is a mailing list for @sc{cvs} where bug reports
-can be sent, questions can be asked, an FAQ is posted,
-and discussion about future enhancements to @sc{cvs}
-take place. To submit a message to the list, write to
-<@t{info-cvs@@prep.ai.mit.edu}>. To subscribe or
-unsubscribe, write to
-<@t{info-cvs-request@@prep.ai.mit.edu}>. Please be
-specific about your email address.
-
-Work is in progress on creating a newsgroup for
-@sc{cvs}-related topics. It will appear somewhere
-under the @samp{gnu.} hierarchy. Gateways to and from
-the mailing list will be set up.
-@c -- Newsgroup? gnu.cvs.info?
-
-@cindex FTP site
-@cindex Patches to CVS
-@cindex CVS FTP site
-@cindex Fixes to CVS
-@cindex FAQ
-@cindex CVS FAQ
-The @sc{ftp} site @t{think.com} has some @sc{cvs}
-material in the @file{/pub/cvs} subdirectory.
-Currently (late summer 1993) it contains an excellent
-@sc{faq} (Frequently Asked Questions, with answers),
-and an improved (but unofficial) version of @sc{cvs}.
-
-@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-@unnumberedsec CVS is not@dots{}
-
-@sc{cvs} can do a lot of things for you, but it does
-not try to be everything for everyone.
-
-@table @asis
-@item @sc{cvs} is not a build system.
-
-Though the structure of your repository and modules
-file interact with your build system
-(e.g. @file{Makefile}s), they are essentially
-independent.
-
-@sc{cvs} does not dictate how you build anything. It
-merely stores files for retrieval in a tree structure
-you devise.
-
-@sc{cvs} does not dictate how to use disk space in the
-checked out working directories. If you write your
-@file{Makefile}s or scripts in every directory so they
-have to know the relative positions of everything else,
-you wind up requiring the entire repository to be
-checked out. That's simply bad planning.
-
-If you modularize your work, and construct a build
-system that will share files (via links, mounts,
-@code{VPATH} in @file{Makefile}s, etc.), you can
-arrange your disk usage however you like.
-
-But you have to remember that @emph{any} such system is
-a lot of work to construct and maintain. @sc{cvs} does
-not address the issues involved. You must use your
-brain and a collection of other tools to provide a
-build scheme to match your plans.
-
-Of course, you should place the tools created to
-support such a build system (scripts, @file{Makefile}s,
-etc) under @sc{cvs}.
-
-@item @sc{cvs} is not a substitute for management.
-
-Your managers and project leaders are expected to talk
-to you frequently enough to make certain you are aware
-of schedules, merge points, branch names and release
-dates. If they don't, @sc{cvs} can't help.
-
-@sc{cvs} is an instrument for making sources dance to
-your tune. But you are the piper and the composer. No
-instrument plays itself or writes its own music.
-
-@item @sc{cvs} is not a substitute for developer communication.
-
-When faced with conflicts within a single file, most
-developers manage to resolve them without too much
-effort. But a more general definition of ``conflict''
-includes problems too difficult to solve without
-communication between developers.
-
-@sc{cvs} cannot determine when simultaneous changes
-within a single file, or across a whole collection of
-files, will logically conflict with one another. Its
-concept of a @dfn{conflict} is purely textual, arising
-when two changes to the same base file are near enough
-to spook the merge (i.e. @code{diff3}) command.
-
-@sc{cvs} does not claim to help at all in figuring out
-non-textual or distributed conflicts in program logic.
-
-For example: Say you change the arguments to function
-@code{X} defined in file @file{A}. At the same time,
-someone edits file @file{B}, adding new calls to
-function @code{X} using the old arguments. You are
-outside the realm of @sc{cvs}'s competence.
-
-Acquire the habit of reading specs and talking to your
-peers.
-
-
-@item @sc{cvs} is not a configuration management system.
-
-@sc{cvs} is a source control system. The phrase
-``configuration management'' is a marketing term, not
-an industry-recognized set of functions.
-
-A true ``configuration management system'' would contain
-elements of the following:
-
-@itemize @bullet
-@item Source control.
-@item Dependency tracking.
-@item Build systems (i.e. What to build and how to find
-things during a build. What is shared? What is local?)
-@item Bug tracking.
-@item Automated Testing procedures.
-@item Release Engineering documentation and procedures.
-@item Tape Construction.
-@item Customer Installation.
-@item A way for users to run different versions of the same
-software on the same host at the same time.
-@end itemize
-
-@sc{cvs} provides only the first.
-@end table
-
-This section is taken from release 2.3 of the @sc{cvs}
-@sc{faq}.
-
-@c ---------------------------------------------------------------------
-@node Basic concepts
-@chapter Basic concepts
-@cindex Modules (intro)
-@cindex Repository (intro)
-
-@sc{cvs} stores all files in a centralized
-@dfn{repository}: a directory (such as
-@file{/usr/local/cvsroot} or
-@file{user@@remotehost:/usr/local/cvsroot}) which is
-populated with a hierarchy of files and directories.
-(@pxref{Remote repositories} for information about
-keeping the repository on a remote machine.)
-
-Normally, you never access any of the files in the
-repository directly. Instead, you use @sc{cvs}
-commands to get your own copy of the files, and then
-work on that copy. When you've finished a set of
-changes, you check (or @dfn{commit}) them back into the
-repository.
-
-The files in the repository are organized in
-@dfn{modules}. Each module is made up of one or more
-files, and can include files from several directories.
-A typical usage is to define one module per project.
-
-@menu
-* Revision numbers:: The meaning of a revision number
-* Versions revisions releases:: Terminology used in this manual
-@end menu
-
-@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-@node Revision numbers
-@section Revision numbers
-@cindex Revision numbers
-@cindex Revision tree
-@cindex Linear development
-@cindex Number, revision-
-@cindex Decimal revision number
-@cindex Main trunk (intro)
-@cindex Branch number
-@cindex Number, branch
-
-Each version of a file has a unique @dfn{revision
-number}. Revision numbers look like @samp{1.1},
-@samp{1.2}, @samp{1.3.2.2} or even @samp{1.3.2.2.4.5}.
-A revision number always has an even number of
-period-separated decimal integers. By default revision
-1.1 is the first revision of a file. Each successive
-revision is given a new number by increasing the
-rightmost number by one. The following figure displays
-a few revisions, with newer revisions to the right.
-
-@example
- +-----+ +-----+ +-----+ +-----+ +-----+
- ! 1.1 !----! 1.2 !----! 1.3 !----! 1.4 !----! 1.5 !
- +-----+ +-----+ +-----+ +-----+ +-----+
-@end example
-
-@sc{cvs} is not limited to linear development. The
-@dfn{revision tree} can be split into @dfn{branches},
-where each branch is a self-maintained line of
-development. Changes made on one branch can easily be
-moved back to the main trunk.
-
-Each branch has a @dfn{branch number}, consisting of an
-odd number of period-separated decimal integers. The
-branch number is created by appending an integer to the
-revision number where the corresponding branch forked
-off. Having branch numbers allows more than one branch
-to be forked off from a certain revision.
-
-@need 3500
-All revisions on a branch have revision numbers formed
-by appending an ordinal number to the branch number.
-The following figure illustrates branching with an
-example.
-
-@example
-@group
- +-------------+
- Branch 1.2.2.3.2 -> ! 1.2.2.3.2.1 !
- / +-------------+
- /
- /
- +---------+ +---------+ +---------+ +---------+
-Branch 1.2.2 -> _! 1.2.2.1 !----! 1.2.2.2 !----! 1.2.2.3 !----! 1.2.2.4 !
- / +---------+ +---------+ +---------+ +---------+
- /
- /
-+-----+ +-----+ +-----+ +-----+ +-----+
-! 1.1 !----! 1.2 !----! 1.3 !----! 1.4 !----! 1.5 ! <- The main trunk
-+-----+ +-----+ +-----+ +-----+ +-----+
- !
- !
- ! +---------+ +---------+ +---------+
-Branch 1.2.4 -> +---! 1.2.4.1 !----! 1.2.4.2 !----! 1.2.4.3 !
- +---------+ +---------+ +---------+
-
-@end group
-@end example
-
-@c -- However, at least for me the figure is not enough. I suggest more
-@c -- text to accompany it. "A picture is worth a thousand words", so you
-@c -- have to make sure the reader notices the couple of hundred words
-@c -- *you* had in mind more than the others!
-
-@c -- Why an even number of segments? This section implies that this is
-@c -- how the main trunk is distinguished from branch roots, but you never
-@c -- explicitly say that this is the purpose of the [by itself rather
-@c -- surprising] restriction to an even number of segments.
-
-The exact details of how the branch number is
-constructed is not something you normally need to be
-concerned about, but here is how it works: When
-@sc{cvs} creates a branch number it picks the first
-unused even integer, starting with 2. So when you want
-to create a branch from revision 6.4 it will be
-numbered 6.4.2. All branch numbers ending in a zero
-(such as 6.4.0) are used internally by @sc{cvs}
-(@pxref{Magic branch numbers}). The branch 1.1.1 has a
-special meaning. @xref{Tracking sources}.
-
-@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-@node Versions revisions releases
-@section Versions, revisions and releases
-@cindex Revisions, versions and releases
-@cindex Versions, revisions and releases
-@cindex Releases, revisions and versions
-
-A file can have several versions, as described above.
-Likewise, a software product can have several versions.
-A software product is often given a version number such
-as @samp{4.1.1}.
-
-Versions in the first sense are called @dfn{revisions}
-in this document, and versions in the second sense are
-called @dfn{releases}. To avoid confusion, the word
-@dfn{version} is almost never used in this document.
-
-@c ---------------------------------------------------------------------
-@node A sample session
-@chapter A sample session
-@cindex A sample session
-@cindex Example of a work-session
-@cindex Getting started
-@cindex Work-session, example of
-@cindex tc, Trivial Compiler (example)
-@cindex Trivial Compiler (example)
-
-This section describes a typical work-session using
-@sc{cvs}. It assumes that a repository is set up
-(@pxref{Repository}).
-
-Suppose you are working on a simple compiler. The source
-consists of a handful of C files and a @file{Makefile}.
-The compiler is called @samp{tc} (Trivial Compiler),
-and the repository is set up so that there is a module
-called @samp{tc}.
-
-@menu
-* Getting the source:: Creating a workspace
-* Committing your changes:: Making your work available to others
-* Cleaning up:: Cleaning up
-* Viewing differences:: Viewing differences
-@end menu
-
-@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-@node Getting the source
-@section Getting the source
-@cindex Getting the source
-@cindex Checking out source
-@cindex Fetching source
-@cindex Source, getting from CVS
-@cindex Checkout, example
-
-The first thing you must do is to get your own working copy of the
-source for @samp{tc}. For this, you use the @code{checkout} command:
-
-@example
-$ cvs checkout tc
-@end example
-
-@noindent
-This will create a new directory called @file{tc} and populate it with
-the source files.
-
-@example
-$ cd tc
-$ ls tc
-CVS Makefile backend.c driver.c frontend.c parser.c
-@end example
-
-The @file{CVS} directory is used internally by
-@sc{cvs}. Normally, you should not modify or remove
-any of the files in it.
-
-You start your favorite editor, hack away at @file{backend.c}, and a couple
-of hours later you have added an optimization pass to the compiler.
-A note to @sc{rcs} and @sc{sccs} users: There is no need to lock the files that
-you want to edit. @xref{Multiple developers} for an explanation.
-
-@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-@node Committing your changes
-@section Committing your changes
-@cindex Committing changes
-@cindex Log message entry
-@cindex CVSEDITOR, environment variable
-@cindex EDITOR, environment variable
-
-When you have checked that the compiler is still compilable you decide
-to make a new version of @file{backend.c}.
-
-@example
-$ cvs commit backend.c
-@end example
-
-@noindent
-@sc{cvs} starts an editor, to allow you to enter a log
-message. You type in ``Added an optimization pass.'',
-save the temporary file, and exit the editor.
-
-The environment variable @code{$CVSEDITOR} determines
-which editor is started. If @code{$CVSEDITOR} is not
-set, then if the environment variable @code{$EDITOR} is
-set, it will be used. If both @code{$CVSEDITOR} and
-@code{$EDITOR} are not set then the editor defaults to
-@code{vi}. If you want to avoid the overhead of
-starting an editor you can specify the log message on
-the command line using the @samp{-m} flag instead, like
-this:
-
-@example
-$ cvs commit -m "Added an optimization pass" backend.c
-@end example
-
-@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-@node Cleaning up
-@section Cleaning up
-@cindex Cleaning up
-@cindex Working copy, removing
-@cindex Removing your working copy
-@cindex Releasing your working copy
-
-Before you turn to other tasks you decide to remove your working copy of
-tc. One acceptable way to do that is of course
-
-@example
-$ cd ..
-$ rm -r tc
-@end example
-
-@noindent
-but a better way is to use the @code{release} command (@pxref{release}):
-
-@example
-$ cd ..
-$ cvs release -d tc
-M driver.c
-? tc
-You have [1] altered files in this repository.
-Are you sure you want to release (and delete) module `tc': n
-** `release' aborted by user choice.
-@end example
-
-The @code{release} command checks that all your modifications have been
-committed. If history logging is enabled it also makes a note in the
-history file. @xref{history file}.
-
-When you use the @samp{-d} flag with @code{release}, it
-also removes your working copy.
-
-In the example above, the @code{release} command wrote a couple of lines
-of output. @samp{? tc} means that the file @file{tc} is unknown to @sc{cvs}.
-That is nothing to worry about: @file{tc} is the executable compiler,
-and it should not be stored in the repository. @xref{cvsignore},
-for information about how to make that warning go away.
-@xref{release output}, for a complete explanation of
-all possible output from @code{release}.
-
-@samp{M driver.c} is more serious. It means that the
-file @file{driver.c} has been modified since it was
-checked out.
-
-The @code{release} command always finishes by telling
-you how many modified files you have in your working
-copy of the sources, and then asks you for confirmation
-before deleting any files or making any note in the
-history file.
-
-You decide to play it safe and answer @kbd{n @key{RET}}
-when @code{release} asks for confirmation.
-
-@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-@node Viewing differences
-@section Viewing differences
-@cindex Viewing differences
-@cindex Diff
-
-You do not remember modifying @file{driver.c}, so you want to see what
-has happened to that file.
-
-@example
-$ cd tc
-$ cvs diff driver.c
-@end example
-
-This command runs @code{diff} to compare the version of @file{driver.c}
-that you checked out with your working copy. When you see the output
-you remember that you added a command line option that enabled the
-optimization pass. You check it in, and release the module.
-
-@example
-$ cvs commit -m "Added an optimization pass" driver.c
-Checking in driver.c;
-/usr/local/cvsroot/tc/driver.c,v <-- driver.c
-new revision: 1.2; previous revision: 1.1
-done
-$ cd ..
-$ cvs release -d tc
-? tc
-You have [0] altered files in this repository.
-Are you sure you want to release (and delete) module `tc': y
-@end example
-
-@c ---------------------------------------------------------------------
-@node Repository
-@chapter The Repository
-@cindex Repository, example
-@cindex Layout of repository
-@cindex Typical repository
-@cindex CVSROOT, environment variable
-@cindex .profile
-@cindex .cshrc
-@cindex .tcshrc
-@cindex .bashrc
-@cindex /usr/local/cvsroot
-@cindex cvsroot
-
-Figure 3 below shows a typical setup of a repository.
-Only directories are shown below.
-
-@example
-@t{/usr}
- |
- +--@t{local}
- | |
- | +--@t{cvsroot}
- | | |
- | | +--@t{CVSROOT}
- | (administrative files)
- |
- +--@t{gnu}
- | |
- | +--@t{diff}
- | | (source code to @sc{gnu} diff)
- | |
- | +--@t{rcs}
- | | (source code to @sc{rcs})
- | |
- | +--@t{cvs}
- | (source code to @sc{cvs})
- |
- +--@t{yoyodyne}
- |
- +--@t{tc}
- | |
- | +--@t{man}
- | |
- | +--@t{testing}
- |
- +--(other Yoyodyne software)
-@end example
-
-
-There are a couple of different ways to tell @sc{cvs}
-where to find the repository. You can name the
-repository on the command line explicitly, with the
-@code{-d} (for "directory") option:
-
-@example
-cvs -d /usr/local/cvsroot checkout yoyodyne/tc
-@end example
-
- Or you can set the @code{$CVSROOT} environment
-variable to an absolute path to the root of the
-repository, @file{/usr/local/cvsroot} in this example.
-To set @code{$CVSROOT}, all @code{csh} and @code{tcsh}
-users should have this line in their @file{.cshrc} or
-@file{.tcshrc} files:
-
-@example
-setenv CVSROOT /usr/local/cvsroot
-@end example
-
-@noindent
-@code{sh} and @code{bash} users should instead have these lines in their
-@file{.profile} or @file{.bashrc}:
-
-@example
-CVSROOT=/usr/local/cvsroot
-export CVSROOT
-@end example
-
- A repository specified with @code{-d} will
-override the @code{$CVSROOT} environment variable.
-Once you've checked a working copy out from the
-repository, it will remember where its repository is
-(the information is recorded in the
-@file{CVS/Root} file in the working copy).
-
-The @code{-d} option and the @file{CVS/Root} file
-both override the @code{$CVSROOT} environment variable;
-however, @sc{CVS} will complain if the @file{-d}
-argument and the @file{CVS/Root} file disagree.
-
-There is nothing magical about the name
-@file{/usr/local/cvsroot}. You can choose to place the
-repository anywhere you like.
-@xref{Remote repositories} to learn how the repository can be on a
-different machine than your working copy of the sources.
-
-The repository is split in two parts. @file{$CVSROOT/CVSROOT} contains
-administrative files for @sc{cvs}. The other directories contain the actual
-user-defined modules.
-
-@menu
-* User modules:: The structure of the repository
-* Intro administrative files:: Defining modules
-* Multiple repositories:: Multiple repositories
-* Creating a repository:: Creating a repository
-* Remote repositories:: Accessing repositories on remote machines
-@end menu
-
-@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-@node User modules
-@section User modules
-@cindex User modules
-@cindex Repository, user parts
-
-@example
- @code{$CVSROOT}
- |
- +--@t{yoyodyne}
- | |
- | +--@t{tc}
- | | |
- +--@t{Makefile,v}
- +--@t{backend.c,v}
- +--@t{driver.c,v}
- +--@t{frontend.c,v}
- +--@t{parser.c,v}
- +--@t{man}
- | |
- | +--@t{tc.1,v}
- |
- +--@t{testing}
- |
- +--@t{testpgm.t,v}
- +--@t{test2.t,v}
-@end example
-
-@cindex History files
-@cindex RCS history files
-@cindex RCS, CVS uses RCS
-The figure above shows the contents of the @samp{tc}
-module inside the repository. As you can see all file
-names end in @samp{,v}. The files are @dfn{history
-files}. They contain, among other things, enough
-information to recreate any revision of the file, a log
-of all commit messages and the user-name of the person
-who committed the revision. @sc{cvs} uses the
-facilities of @sc{rcs}, a simpler version control
-system, to maintain these files. For a full
-description of the file format, see the @code{man} page
-@cite{rcsfile(5)}.
-@c -- Use this format for all references to man pages,
-@c -- or use something better!
-
-@menu
-* File permissions:: File permissions
-@end menu
-
-@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
-@node File permissions
-@subsection File permissions
-@c -- Move this to @node Setting up
-@cindex Security
-@cindex File permissions
-@cindex Group
-All @samp{,v} files are created read-only, and you
-should not change the permission of those files. The
-directories inside the repository should be writable by
-the persons that have permission to modify the files in
-each directory. This normally means that you must
-create a UNIX group (see group(5)) consisting of the
-persons that are to edit the files in a project, and
-set up the repository so that it is that group that
-owns the directory.
-
-This means that you can only control access to files on
-a per-directory basis.
-
-@sc{cvs} tries to set up reasonable file permissions
-for new directories that are added inside the tree, but
-you must fix the permissions manually when a new
-directory should have different permissions than its
-parent directory.
-
-@cindex setuid
-@cindex setgid
-Since @sc{cvs} was not written to be run setuid, it is
-unsafe to try to run it setuid. You cannot use the
-setuid features of @sc{rcs} together with @sc{cvs}.
-
-@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-@node Intro administrative files
-@section The administrative files
-@cindex Administrative files (intro)
-@cindex Modules file
-@cindex CVSROOT, module name
-@cindex Defining modules (intro)
-
-The directory @file{$CVSROOT/CVSROOT} contains some @dfn{administrative
-files}. @xref{Administrative files}, for a complete description.
-You can use @sc{cvs} without any of these files, but
-some commands work better when at least the
-@file{modules} file is properly set up.
-
-The most important of these files is the @file{modules}
-file. It defines all modules in the repository. This
-is a sample @file{modules} file.
-
-@example
-CVSROOT -i mkmodules CVSROOT
-modules -i mkmodules CVSROOT modules
-cvs gnu/cvs
-rcs gnu/rcs
-diff gnu/diff
-tc yoyodyne/tc
-@end example
-
-The @file{modules} file is line oriented. In its simplest form each
-line contains the name of the module, whitespace, and the directory
-where the module resides. The directory is a path relative to
-@code{$CVSROOT}. The last for lines in the example
-above are examples of such lines.
-
-@cindex mkmodules
-Each module definition can contain options. The @samp{-i mkmodules} is
-an example of an option. It arranges for @sc{cvs} to run the
-@code{mkmodules} program whenever any file in the module CVSROOT is
-committed. That program is responsible for checking out read-only
-copies from the @sc{rcs} @dfn{history files} of all the administrative files.
-These read-only copies are used internally by @sc{cvs}. You
-should never edit them directly.
-
-The line that defines the module called @samp{modules}
-uses features that are not explained here.
-@xref{modules}, for a full explanation of all the
-available features.
-
-@subsection Editing administrative files
-@cindex Editing administrative files
-@cindex Administrative files, editing them
-
-You edit the administrative files in the same way that you would edit
-any other module. Use @samp{cvs checkout CVSROOT} to get a working
-copy, edit it, and commit your changes in the normal way.
-
-It is possible to commit an erroneous administrative
-file. You can often fix the error and check in a new
-revision, but sometimes a particularly bad error in the
-administrative file makes it impossible to commit new
-revisions.
-@c @xref{Bad administrative files} for a hint
-@c about how to solve such situations.
-@c -- administrative file checking--
-
-@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-@node Multiple repositories
-@section Multiple repositories
-@cindex Multiple repositories
-@cindex Repositories, multiple
-@cindex Many repositories
-@cindex Parallel repositories
-@cindex Disjoint repositories
-@cindex CVSROOT, multiple repositories
-
-In some situations it is a good idea to have more than
-one repository, for instance if you have two
-development groups that work on separate projects
-without sharing any code. All you have to do to have
-several repositories is to specify the appropriate
-repository, using the @code{CVSROOT} environment
-variable, the @samp{-d} option to @sc{cvs}, or (once
-you have checked out a working directories) by
-simply allowing @sc{cvs} to use the repository that was
-used to check out the working directory (@pxref{Repository}).
-
-Notwithstanding, it can be confusing to have two or
-more repositories.
-
-None of the examples in this manual show multiple
-repositories.
-
-@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-@node Creating a repository
-@section Creating a repository
-@c -- Well, how do you do?
-
-See the instructions in the @file{INSTALL} file in the
-@sc{cvs} distribution.
-
-@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-@node Remote repositories
-@section Remote repositories
-@cindex Repositories, remote
-@cindex Remote repositories
-@cindex Client/Server Operation
-
-The repository and your working copy of the sources can
-be on different machines. To access a remote
-repository, use the following format for its name:
-
-@example
- user@@hostname:/path/to/repository
-@end example
-
-(The @file{user@@} can be omitted if it's the same on
-both the local and remote hosts.)
-
-The details of exactly what needs to be set up depends
-on how you are connecting to the server.
-
-@menu
-* Connecting via rsh:: Using the rsh program to connect
-* Kerberos authenticated:: Direct connections with kerberos
-@end menu
-
-@node Connecting via rsh
-@subsection Connecting with rsh
-
-@cindex rsh
-CVS uses the @file{rsh} protocol to perform these
-operations, so the remote user host needs to have a
-@file{.rhosts} file which grants access to the local
-user.
-
-For example, suppose you are the user @file{mozart} on
-the local machine @file{anklet.grunge.com}, and the
-server machine is @file{chainsaw.brickyard.com}. On
-chainsaw, put the following line into the file
-@file{.rhosts} in @file{bach}'s home directory:
-
-@example
-anklet.grunge.com mozart
-@end example
-
-Then test that rsh is working with
-
-@example
-rsh -l bach chainsaw.brickyard.com echo $PATH
-@end example
-
-@cindex CVS_SERVER
-Next you have to make sure that rsh will be able to
-find the server. Make sure that the path which rsh
-printed in the above example includes the directory
-containing a program named @code{cvs} which is the
-server. You need to set the path in @file{.bashrc},
-@file{.cshrc}, etc., not @file{.login} or
-@file{.profile}. Alternately, you can set the
-environment variable @code{CVS_SERVER} on the client
-machine to the filename of the server you want to use,
-for example @file{/usr/local/bin/cvs-1.6}.
-
-There is no need to edit @code{inetd.conf} or start a
-@sc{cvs} server daemon.
-
-Continuing our example, supposing you want to access
-the module @file{foo} in the repository
-@file{/usr/local/cvsroot/}, on machine
-@file{chainsaw.brickyard.com}, you are ready to go:
-
-@example
-cvs -d bach@@chainsaw.brickyard.com:/user/local/cvsroot checkout foo
-@end example
-
-@node Kerberos authenticated
-@subsection Direct connection with kerberos
-
-@cindex kerberos
-The main disadvantage of using rsh is that all the data
-needs to pass through additional programs, so it may be
-slower. So if you have kerberos installed you can
-connect via a direct @sc{tcp} connection,
-authenticating with kerberos (note that the data
-transmitted is @emph{not} encrypted).
-
-To do this, @sc{cvs} needs to be compiled with kerberos
-support; when configuring @sc{cvs} it tries to detect
-whether kerberos is present or you can use the
-@file{--with-krb4} flag to configure.
-
-@cindex CVS_CLIENT_PORT
-You need to edit @code{inetd.conf} on the server
-machine to run @code{cvs kserver}. The client uses
-port 1999 by default; if you want to use another port
-specify it in the @code{CVS_CLIENT_PORT} environment
-variable on the client. Set @code{CVS_CLIENT_PORT} to
-@samp{-1} to force an rsh connection.
-
-@cindex kinit
-When you want to use @sc{cvs}, get a ticket in the
-usual way (generally @code{kinit}); it must be a ticket
-which allows you to log into the server machine. Then
-you are ready to go:
-
-@example
-cvs -d chainsaw.brickyard.com:/user/local/cvsroot checkout foo
-@end example
-
-If @sc{cvs} fails to connect, it will fall back to
-trying rsh.
-
-@c ---------------------------------------------------------------------
-@node Starting a new project
-@chapter Starting a project with CVS
-@cindex Starting a project with CVS
-@cindex Creating a project
-
-@comment --moduledb--
-Since @sc{cvs} 1.x is bad at renaming files and moving
-them between directories, the first thing you do when
-you start a new project should be to think through your
-file organization. It is not impossible---just
-awkward---to rename or move files.
-@xref{Moving files}.
-
-What to do next depends on the situation at hand.
-
-@menu
-* Setting up the files:: Getting the files into the repository
-* Defining the module:: How to make a module of the files
-@end menu
-@c -- File permissions!
-
-@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-@node Setting up the files
-@section Setting up the files
-
-The first step is to create the files inside the repository. This can
-be done in a couple of different ways.
-
-@c -- The contributed scripts
-@menu
-* From files:: This method is useful with old projects
- where files already exists.
-
-* From scratch:: Creating a module from scratch.
-@end menu
-
-@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
-@node From files
-@subsection Creating a module from a number of files
-@cindex Importing files
-
-When you begin using @sc{cvs}, you will probably already have several
-projects that can be
-put under @sc{cvs} control. In these cases the easiest way is to use the
-@code{import} command. An example is probably the easiest way to
-explain how to use it. If the files you want to install in
-@sc{cvs} reside in @file{@var{dir}}, and you want them to appear in the
-repository as @file{$CVSROOT/yoyodyne/@var{dir}}, you can do this:
-
-@example
-$ cd @var{dir}
-$ cvs import -m "Imported sources" yoyodyne/@var{dir} yoyo start
-@end example
-
-Unless you supply a log message with the @samp{-m}
-flag, @sc{cvs} starts an editor and prompts for a
-message. The string @samp{yoyo} is a @dfn{vendor tag},
-and @samp{start} is a @dfn{release tag}. They may fill
-no purpose in this context, but since @sc{cvs} requires
-them they must be present. @xref{Tracking sources}, for
-more information about them.
-
-You can now verify that it worked, and remove your
-original source directory.
-
-@example
-$ cd ..
-$ mv @var{dir} @var{dir}.orig
-$ cvs checkout yoyodyne/@var{dir} # @r{Explanation below}
-$ ls -R yoyodyne
-$ rm -r @var{dir}.orig
-@end example
-
-@noindent
-Erasing the original sources is a good idea, to make sure that you do
-not accidentally edit them in @var{dir}, bypassing @sc{cvs}.
-Of course, it would be wise to make sure that you have
-a backup of the sources before you remove them.
-
-The @code{checkout} command can either take a module
-name as argument (as it has done in all previous
-examples) or a path name relative to @code{$CVSROOT},
-as it did in the example above.
-
-It is a good idea to check that the permissions
-@sc{cvs} sets on the directories inside @samp{$CVSROOT}
-are reasonable, and that they belong to the proper
-groups. @xref{File permissions}.
-
-@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
-@node From scratch
-@subsection Creating a module from scratch
-
-For a new project, the easiest thing to do is probably
-to create an empty directory structure, like this:
-
-@example
-$ mkdir tc
-$ mkdir tc/man
-$ mkdir tc/testing
-@end example
-
-After that, you use the @code{import} command to create
-the corresponding (empty) directory structure inside
-the repository:
-
-@example
-$ cd tc
-$ cvs import -m "Created directory structure" yoyodyne/@var{dir} yoyo start
-@end example
-
-Then, use @code{add} to add files (and new directories)
-as they appear.
-
-Check that the permissions @sc{cvs} sets on the
-directories inside @samp{$CVSROOT} are reasonable.
-
-@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-@node Defining the module
-@section Defining the module
-@cindex Defining a module
-@cindex Editing the modules file
-@cindex Module, defining
-@cindex Modules file, changing
-
-The next step is to define the module in the
-@file{modules} file. This is not strictly necessary,
-but modules can be convenient in grouping together
-related files and directories.
-
-In simple cases these steps are sufficient to define a module.
-
-@enumerate
-@item
-Get a working copy of the modules file.
-
-@example
-$ cvs checkout modules
-$ cd modules
-@end example
-
-@item
-Edit the file and insert a line that defines the module. @xref{Intro
-administrative files}, for an introduction. @xref{modules}, for a full
-description of the modules file. You can use the
-following line to define the module @samp{tc}:
-
-@example
-tc yoyodyne/tc
-@end example
-
-@item
-Commit your changes to the modules file.
-
-@example
-$ cvs commit -m "Added the tc module." modules
-@end example
-
-@item
-Release the modules module.
-
-@example
-$ cd ..
-$ cvs release -d modules
-@end example
-@end enumerate
-
-@c ---------------------------------------------------------------------
-@node Multiple developers
-@chapter Multiple developers
-@cindex Multiple developers
-@cindex Team of developers
-@cindex File locking
-@cindex Locking files
-@cindex Working copy
-
-When more than one person works on a software project
-things often get complicated. Often, two people try to
-edit the same file simultaneously. Some other version
-control systems (including @sc{rcs} and @sc{sccs})
-try to solve that particular problem by introducing
-@dfn{file locking}, so that only one person can edit
-each file at a time. Unfortunately, file locking can
-be very counter-productive. If two persons want
-to edit different parts of a file, there may be no
-reason to prevent either of them from doing so.
-
-@sc{cvs} does not use file locking. Instead, it allows many
-people to edit their own @dfn{working copy} of a file
-simultaneously. The first person that commits his
-changes has no automatic way of knowing that another has started to
-edit it. Others will get an error message when they
-try to commit the file. They must then use @sc{cvs}
-commands to bring their working copy up to date with
-the repository revision. This process is almost
-automatic, and explained in this chapter.
-
-There are many ways to organize a team of developers.
-@sc{cvs} does not try to enforce a certain
-organization. It is a tool that can be used in several
-ways. It is often useful to inform the group of
-commits you have done. @sc{cvs} has several ways of
-automating that process. @xref{Informing others}.
-@xref{Revision management}, for more tips on how to use
-@sc{cvs}.
-
-@menu
-* File status:: A file can be in several states
-* Updating a file:: Bringing a file up-to-date
-* Conflicts example:: An informative example
-* Informing others:: To cooperate you must inform
-* Concurrency:: Simultaneous repository access
-@end menu
-
-@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-@node File status
-@section File status
-@cindex File status
-@cindex Status of a file
-@cindex Four states of a file
-
-After you have checked out a file out from @sc{cvs}, it is in
-one of these four states:
-
-@table @asis
-@cindex Up-to-date
-@item Up-to-date
-The file is identical with the latest revision in the
-repository.
-@c -- The above is not always true if branching is used.
-
-@item Locally modified
-@cindex Locally modified
-You have edited the file, and not yet committed your changes.
-
-@item Needing update
-@cindex Needing update
-Someone else has committed a newer revision to the repository.
-
-@item Needing merge
-@cindex Needing merge
-Someone else have committed a newer revision to the repository, and you
-have also made modifications to the file.
-@c -- What about "added" "removed" and so on?
-@end table
-
-You can use the @code{status} command to find out the status of a given
-file. @xref{status}.
-
-@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-@node Updating a file
-@section Bringing a file up to date
-@cindex Bringing a file up to date
-@cindex Updating a file
-@cindex Merging a file
-@cindex update, introduction
-
-When you want to update or merge a file, use the @code{update}
-command. For files that are not up to date this is roughly equivalent
-to a @code{checkout} command: the newest revision of the file is
-extracted from the repository and put in your working copy of the
-module.
-
-Your modifications to a file are never lost when you
-use @code{update}. If no newer revision exists,
-running @code{update} has no effect. If you have
-edited the file, and a newer revision is available,
-@sc{cvs} will merge all changes into your working copy.
-
-For instance, imagine that you checked out revision 1.4 and started
-editing it. In the meantime someone else committed revision 1.5, and
-shortly after that revision 1.6. If you run @code{update} on the file
-now, @sc{cvs} will incorporate all changes between revision 1.4 and 1.6 into
-your file.
-
-@cindex Overlap
-If any of the changes between 1.4 and 1.6 were made too
-close to any of the changes you have made, an
-@dfn{overlap} occurs. In such cases a warning is
-printed, and the resulting file includes both
-versions of the lines that overlap, delimited by
-special markers.
-@xref{update}, for a complete description of the
-@code{update} command.
-
-@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-@node Conflicts example
-@section Conflicts example
-@cindex Merge, an example
-@cindex Example of merge
-@cindex driver.c (merge example)
-
-Suppose revision 1.4 of @file{driver.c} contains this:
-
-@example
-#include <stdio.h>
-
-void main()
-@{
- parse();
- if (nerr == 0)
- gencode();
- else
- fprintf(stderr, "No code generated.\n");
- exit(nerr == 0 ? 0 : 1);
-@}
-@end example
-
-@noindent
-Revision 1.6 of @file{driver.c} contains this:
-
-@example
-#include <stdio.h>
-
-int main(int argc,
- char **argv)
-@{
- parse();
- if (argc != 1)
- @{
- fprintf(stderr, "tc: No args expected.\n");
- exit(1);
- @}
- if (nerr == 0)
- gencode();
- else
- fprintf(stderr, "No code generated.\n");
- exit(!!nerr);
-@}
-@end example
-
-@noindent
-Your working copy of @file{driver.c}, based on revision
-1.4, contains this before you run @samp{cvs update}:
-@c -- Really include "cvs"?
-
-@example
-#include <stdlib.h>
-#include <stdio.h>
-
-void main()
-@{
- init_scanner();
- parse();
- if (nerr == 0)
- gencode();
- else
- fprintf(stderr, "No code generated.\n");
- exit(nerr == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
-@}
-@end example
-
-@noindent
-You run @samp{cvs update}:
-@c -- Really include "cvs"?
-
-@example
-$ cvs update driver.c
-RCS file: /usr/local/cvsroot/yoyodyne/tc/driver.c,v
-retrieving revision 1.4
-retrieving revision 1.6
-Merging differences between 1.4 and 1.6 into driver.c
-rcsmerge warning: overlaps during merge
-cvs update: conflicts found in driver.c
-C driver.c
-@end example
-
-@noindent
-@cindex Conflicts (merge example)
-@sc{cvs} tells you that there were some conflicts.
-Your original working file is saved unmodified in
-@file{.#driver.c.1.4}. The new version of
-@file{driver.c} contains this:
-
-@example
-#include <stdlib.h>
-#include <stdio.h>
-
-int main(int argc,
- char **argv)
-@{
- init_scanner();
- parse();
- if (argc != 1)
- @{
- fprintf(stderr, "tc: No args expected.\n");
- exit(1);
- @}
- if (nerr == 0)
- gencode();
- else
- fprintf(stderr, "No code generated.\n");
-<<<<<<< driver.c
- exit(nerr == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
-=======
- exit(!!nerr);
->>>>>>> 1.6
-@}
-@end example
-
-@noindent
-@cindex Markers, conflict
-@cindex Conflict markers
-@cindex <<<<<<<
-@cindex >>>>>>>
-@cindex =======
-
-Note how all non-overlapping modifications are incorporated in your working
-copy, and that the overlapping section is clearly marked with
-@samp{<<<<<<<}, @samp{=======} and @samp{>>>>>>>}.
-
-@cindex Resolving a conflict
-@cindex Conflict resolution
-You resolve the conflict by editing the file, removing the markers and
-the erroneous line. Suppose you end up with this file:
-@c -- Add xref to the pcl-cvs manual when it talks
-@c -- about this.
-@example
-#include <stdlib.h>
-#include <stdio.h>
-
-int main(int argc,
- char **argv)
-@{
- init_scanner();
- parse();
- if (argc != 1)
- @{
- fprintf(stderr, "tc: No args expected.\n");
- exit(1);
- @}
- if (nerr == 0)
- gencode();
- else
- fprintf(stderr, "No code generated.\n");
- exit(nerr == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
-@}
-@end example
-
-@noindent
-You can now go ahead and commit this as revision 1.7.
-
-@example
-$ cvs commit -m "Initialize scanner. Use symbolic exit values." driver.c
-Checking in driver.c;
-/usr/local/cvsroot/yoyodyne/tc/driver.c,v <-- driver.c
-new revision: 1.7; previous revision: 1.6
-done
-@end example
-
-@cindex emerge
-If you use release 1.04 or later of pcl-cvs (a @sc{gnu}
-Emacs front-end for @sc{cvs}) you can use an Emacs
-package called emerge to help you resolve conflicts.
-See the documentation for pcl-cvs.
-
-@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-@node Informing others
-@section Informing others about commits
-@cindex Informing others
-@cindex Spreading information
-@cindex Mail, automatic mail on commit
-
-It is often useful to inform others when you commit a
-new revision of a file. The @samp{-i} option of the
-@file{modules} file, or the @file{loginfo} file, can be
-used to automate this process. @xref{modules}.
-@xref{loginfo}. You can use these features of @sc{cvs}
-to, for instance, instruct @sc{cvs} to mail a
-message to all developers, or post a message to a local
-newsgroup.
-@c -- More text would be nice here.
-
-@node Concurrency
-@section Several developers simultaneously attempting to run CVS
-
-@cindex locks, cvs
-If several developers try to run @sc{cvs} at the same
-time, one may get the following message:
-
-@example
-[11:43:23] waiting for bach's lock in /usr/local/cvsroot/foo
-@end example
-
-@sc{cvs} will try again every 30 seconds, and either
-continue with the operation or print the message again,
-if it still needs to wait. If a lock seems to stick
-around for an undue amount of time, find the person
-holding the lock and ask them about the cvs command
-they are running. If they aren't running a cvs
-command, look for and remove files starting with
-@file{#cvs.tfl}, @file{#cvs.rfl}, or @file{#cvs.wfl}
-from the repository.
-
-Note that these locks are to protect @sc{cvs}'s
-internal data structures and have no relationship to
-the word @dfn{lock} in the sense used by @sc{rcs}--a
-way to prevent other developers from working on a
-particular file.
-
-Any number of people can be reading from a given
-repository at a time; only when someone is writing do
-the locks prevent other people from reading or writing.
-
-One might hope for the following property
-
-@example
-If someone commits some changes in one cvs command,
-then an update by someone else will either get all the
-changes, or none of them.
-@end example
-
-but @sc{cvs} does @emph{not} have this property. For
-example, given the files
-
-@example
-a/one.c
-a/two.c
-b/three.c
-b/four.c
-@end example
-
-if someone runs
-
-@example
-cvs ci a/two.c b/three.c
-@end example
-
-and someone else runs @code{cvs update}, the person
-running update might get only the change to
-@file{b/three.c} and not the change to @file{a/two.c}.
-
-@c ---------------------------------------------------------------------
-@node Branches
-@chapter Branches
-@cindex Branches
-@cindex Main trunk and branches
-@cindex Revision tree, making branches
-
-So far, all revisions shown in this manual have been on
-the @dfn{main trunk}
-of the revision tree, i.e., all revision numbers
-have been of the form @var{x}.@var{y}. One useful
-feature, especially when maintaining several releases
-of a software product at once, is the ability to make
-branches on the revision tree. @dfn{Tags}, symbolic
-names for revisions, will also be
-introduced in this chapter.
-
-@menu
-* Tags:: Tags--Symbolic revisions
-* Branches motivation:: What branches are good for
-* Creating a branch:: Creating a branch
-* Sticky tags:: Sticky tags
-@end menu
-
-@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-@node Tags
-@section Tags--Symbolic revisions
-@cindex Tags
-
-The revision numbers live a life of their own. They
-need not have anything at all to do with the release
-numbers of your software product. Depending
-on how you use @sc{cvs} the revision numbers might change several times
-between two releases. As an example, some of the
-source files that make up @sc{rcs} 5.6 have the following
-revision numbers:
-@cindex RCS revision numbers
-
-@example
-ci.c 5.21
-co.c 5.9
-ident.c 5.3
-rcs.c 5.12
-rcsbase.h 5.11
-rcsdiff.c 5.10
-rcsedit.c 5.11
-rcsfcmp.c 5.9
-rcsgen.c 5.10
-rcslex.c 5.11
-rcsmap.c 5.2
-rcsutil.c 5.10
-@end example
-
-@cindex tag, command, introduction
-@cindex Tag, symbolic name
-@cindex Symbolic name (tag)
-@cindex Name, symbolic (tag)
-You can use the @code{tag} command to give a symbolic name to a
-certain revision of a file. You can use the @samp{-v} flag to the
-@code{status} command to see all tags that a file has, and
-which revision numbers they represent.
-
-@cindex Adding a tag
-@cindex tag, example
-The following example shows how you can add a tag to a
-file. The commands must be issued inside your working
-copy of the module. That is, you should issue the
-command in the directory where @file{backend.c}
-resides.
-
-@example
-$ cvs tag release-0-4 backend.c
-T backend.c
-$ cvs status -v backend.c
-===================================================================
-File: backend.c Status: Up-to-date
-
- Version: 1.4 Tue Dec 1 14:39:01 1992
- RCS Version: 1.4 /usr/local/cvsroot/yoyodyne/tc/backend.c,v
- Sticky Tag: (none)
- Sticky Date: (none)
- Sticky Options: (none)
-
- Existing Tags:
- release-0-4 (revision: 1.4)
-
-@end example
-
-There is seldom reason to tag a file in isolation. A more common use is
-to tag all the files that constitute a module with the same tag at
-strategic points in the development life-cycle, such as when a release
-is made.
-
-@example
-$ cvs tag release-1-0 .
-cvs tag: Tagging .
-T Makefile
-T backend.c
-T driver.c
-T frontend.c
-T parser.c
-@end example
-
-(When you give @sc{cvs} a directory as argument, it generally applies the
-operation to all the files in that directory, and (recursively), to any
-subdirectories that it may contain. @xref{Recursive behavior}.)
-
-@cindex Retrieving an old revision using tags
-@cindex Tag, retrieving old revisions
-The @code{checkout} command has a flag, @samp{-r}, that lets you check out
-a certain revision of a module. This flag makes it easy to
-retrieve the sources that make up release 1.0 of the module @samp{tc} at
-any time in the future:
-
-@example
-$ cvs checkout -r release-1-0 tc
-@end example
-
-@noindent
-This is useful, for instance, if someone claims that there is a bug in
-that release, but you cannot find the bug in the current working copy.
-
-You can also check out a module as it was at any given date.
-@xref{checkout options}.
-
-When you tag more than one file with the same tag you
-can think about the tag as "a curve drawn through a
-matrix of filename vs. revision number." Say we have 5
-files with the following revisions:
-
-@example
-@group
- file1 file2 file3 file4 file5
-
- 1.1 1.1 1.1 1.1 /--1.1* <-*- TAG
- 1.2*- 1.2 1.2 -1.2*-
- 1.3 \- 1.3*- 1.3 / 1.3
- 1.4 \ 1.4 / 1.4
- \-1.5*- 1.5
- 1.6
-@end group
-@end example
-
-At some time in the past, the @code{*} versions were tagged.
-You can think of the tag as a handle attached to the curve
-drawn through the tagged revisions. When you pull on
-the handle, you get all the tagged revisions. Another
-way to look at it is that you "sight" through a set of
-revisions that is "flat" along the tagged revisions,
-like this:
-
-@example
-@group
- file1 file2 file3 file4 file5
-
- 1.1
- 1.2
- 1.1 1.3 _
- 1.1 1.2 1.4 1.1 /
- 1.2*----1.3*----1.5*----1.2*----1.1 (--- <--- Look here
- 1.3 1.6 1.3 \_
- 1.4 1.4
- 1.5
-@end group
-@end example
-
-@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-@node Branches motivation
-@section What branches are good for
-@cindex Branches motivation
-@cindex What branches are good for
-@cindex Motivation for branches
-
-Suppose that release 1.0 of tc has been made. You are continuing to
-develop tc, planning to create release 1.1 in a couple of months. After a
-while your customers start to complain about a fatal bug. You check
-out release 1.0 (@pxref{Tags}) and find the bug
-(which turns out to have a trivial fix). However, the current revision
-of the sources are in a state of flux and are not expected to be stable
-for at least another month. There is no way to make a
-bugfix release based on the newest sources.
-
-The thing to do in a situation like this is to create a @dfn{branch} on
-the revision trees for all the files that make up
-release 1.0 of tc. You can then make
-modifications to the branch without disturbing the main trunk. When the
-modifications are finished you can select to either incorporate them on
-the main trunk, or leave them on the branch.
-
-@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-@node Creating a branch
-@section Creating a branch
-@cindex Creating a branch
-@cindex Branch, creating a
-@cindex rtag, creating a branch using
-
-The @code{rtag} command can be used to create a branch.
-The @code{rtag} command is much like @code{tag}, but it
-does not require that you have a working copy of the
-module. @xref{rtag}. (You can also use the @code{tag}
-command; @pxref{tag}).
-
-@example
-$ cvs rtag -b -r release-1-0 release-1-0-patches tc
-@end example
-
-The @samp{-b} flag makes @code{rtag} create a branch
-(rather than just a symbolic revision name). @samp{-r
-release-1-0} says that this branch should be rooted at the node (in
-the revision tree) that corresponds to the tag
-@samp{release-1-0}. Note that the numeric revision number that matches
-@samp{release-1-0} will probably be different from file to file. The
-name of the new branch is @samp{release-1-0-patches}, and the
-module affected is @samp{tc}.
-
-To fix the problem in release 1.0, you need a working
-copy of the branch you just created.
-
-@example
-$ cvs checkout -r release-1-0-patches tc
-$ cvs status -v driver.c backend.c
-===================================================================
-File: driver.c Status: Up-to-date
-
- Version: 1.7 Sat Dec 5 18:25:54 1992
- RCS Version: 1.7 /usr/local/cvsroot/yoyodyne/tc/driver.c,v
- Sticky Tag: release-1-0-patches (branch: 1.7.2)
- Sticky Date: (none)
- Sticky Options: (none)
-
- Existing Tags:
- release-1-0-patches (branch: 1.7.2)
- release-1-0 (revision: 1.7)
-
-===================================================================
-File: backend.c Status: Up-to-date
-
- Version: 1.4 Tue Dec 1 14:39:01 1992
- RCS Version: 1.4 /usr/local/cvsroot/yoyodyne/tc/backend.c,v
- Sticky Tag: release-1-0-patches (branch: 1.4.2)
- Sticky Date: (none)
- Sticky Options: (none)
-
- Existing Tags:
- release-1-0-patches (branch: 1.4.2)
- release-1-0 (revision: 1.4)
- release-0-4 (revision: 1.4)
-
-@end example
-
-@cindex Branch numbers
-As the output from the @code{status} command shows the branch
-number is created by adding a digit at the tail of the revision number
-it is based on. (If @samp{release-1-0} corresponds to revision 1.4, the
-branch's revision number will be 1.4.2. For obscure reasons @sc{cvs} always
-gives branches even numbers, starting at 2.
-@xref{Revision numbers}).
-
-@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-@node Sticky tags
-@section Sticky tags
-@cindex Sticky tags
-@cindex Tags, sticky
-@cindex Branches, sticky
-
-The @samp{-r release-1-0-patches} flag that was given to @code{checkout}
-is @dfn{sticky}, that is, it will apply to subsequent commands
-in this directory. If you commit any modifications, they are
-committed on the branch. You can later merge the modifications into
-the main trunk. @xref{Merging}.
-
-@example
-$ vi driver.c # @r{Fix the bugs}
-$ cvs commit -m "Fixed initialization bug" driver.c
-Checking in driver.c;
-/usr/local/cvsroot/yoyodyne/tc/driver.c,v <-- driver.c
-new revision: 1.7.2.1; previous revision: 1.7
-done
-$ cvs status -v driver.c
-===================================================================
-File: driver.c Status: Up-to-date
-
- Version: 1.7.2.1 Sat Dec 5 19:35:03 1992
- RCS Version: 1.7.2.1 /usr/local/cvsroot/yoyodyne/tc/driver.c,v
- Sticky Tag: release-1-0-patches (branch: 1.7.2)
- Sticky Date: (none)
- Sticky Options: (none)
-
- Existing Tags:
- release-1-0-patches (branch: 1.7.2)
- release-1-0 (revision: 1.7)
-
-@end example
-
-@cindex Resetting sticky tags
-@cindex Sticky tags, resetting
-@cindex Deleting sticky tags
-The sticky tags will remain on your working files until
-you delete them with @samp{cvs update -A}. @xref{update}.
-
-Sticky tags are not just for branches. If you check
-out a certain revision (such as 1.4) it will also
-become sticky. Subsequent @samp{cvs update} will not
-retrieve the latest revision until you reset the tag
-with @samp{cvs update -A}.
-
-See the descriptions in Appendix A for more information
-about sticky tags. Dates and some other options can
-also be sticky. Again, see Appendix A for details.
-@c -- xref to relevant part of App A.
-@c -- Re-evaluate this node.
-
-@c ---------------------------------------------------------------------
-@node Merging
-@chapter Merging
-@cindex Merging
-@cindex Copying changes
-@cindex Branches, copying changes between
-@cindex Changes, copying between branches
-@cindex Modifications, copying between branches
-
-You can include the changes made between any two
-revisions into your working copy, by @dfn{merging}.
-You can then commit that revision, and thus effectively
-copy the changes onto another branch.
-
-@menu
-* Merging a branch:: Merging an entire branch
-* Merging more than once:: Merging from a branch several times
-* Merging two revisions:: Merging differences between two revisions
-@end menu
-
-@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-@node Merging a branch
-@section Merging an entire branch
-@cindex Merging a branch
-@cindex -j (merging branches)
-
-You can merge changes made on a branch into your working copy by giving
-the @samp{-j @var{branch}} flag to the @code{update} command. With one
-@samp{-j @var{branch}} option it merges the changes made between the
-point where the branch forked and newest revision on that branch (into
-your working copy).
-
-@cindex Join
-The @samp{-j} stands for ``join''.
-
-@cindex Branch merge example
-@cindex Example, branch merge
-@cindex Merge, branch example
-Consider this revision tree:
-
-@example
-+-----+ +-----+ +-----+ +-----+
-! 1.1 !----! 1.2 !----! 1.3 !----! 1.4 ! <- The main trunk
-+-----+ +-----+ +-----+ +-----+
- !
- !
- ! +---------+ +---------+
-Branch R1fix -> +---! 1.2.2.1 !----! 1.2.2.2 !
- +---------+ +---------+
-@end example
-
-@noindent
-The branch 1.2.2 has been given the tag (symbolic name) @samp{R1fix}. The
-following example assumes that the module @samp{mod} contains only one
-file, @file{m.c}.
-
-@example
-$ cvs checkout mod # @r{Retrieve the latest revision, 1.4}
-
-$ cvs update -j R1fix m.c # @r{Merge all changes made on the branch,}
- # @r{i.e. the changes between revision 1.2}
- # @r{and 1.2.2.2, into your working copy}
- # @r{of the file.}
-
-$ cvs commit -m "Included R1fix" # @r{Create revision 1.5.}
-@end example
-
-A conflict can result from a merge operation. If that
-happens, you should resolve it before committing the
-new revision. @xref{Conflicts example}.
-
-The @code{checkout} command also supports the @samp{-j @var{branch}} flag. The
-same effect as above could be achieved with this:
-
-@example
-$ cvs checkout -j R1fix mod
-$ cvs commit -m "Included R1fix"
-@end example
-
-@node Merging more than once
-@section Merging from a branch several times
-
-Continuing our example, the revision tree now looks
-like this:
-
-@example
-+-----+ +-----+ +-----+ +-----+ +-----+
-! 1.1 !----! 1.2 !----! 1.3 !----! 1.4 !----! 1.5 ! <- The main trunk
-+-----+ +-----+ +-----+ +-----+ +-----+
- ! *
- ! *
- ! +---------+ +---------+
-Branch R1fix -> +---! 1.2.2.1 !----! 1.2.2.2 !
- +---------+ +---------+
-@end example
-
-where the starred line represents the merge from the
-@samp{R1fix} branch to the main trunk, as just
-discussed.
-
-Now suppose that development continues on the
-@samp{R1fix} branch:
-
-@example
-+-----+ +-----+ +-----+ +-----+ +-----+
-! 1.1 !----! 1.2 !----! 1.3 !----! 1.4 !----! 1.5 ! <- The main trunk
-+-----+ +-----+ +-----+ +-----+ +-----+
- ! *
- ! *
- ! +---------+ +---------+ +---------+
-Branch R1fix -> +---! 1.2.2.1 !----! 1.2.2.2 !----! 1.2.2.3 !
- +---------+ +---------+ +---------+
-@end example
-
-and then you want to merge those new changes onto the
-main trunk. If you just use the @code{cvs update -j
-R1fix m.c} command again, @sc{cvs} will attempt to
-merge again the changes which you have already merged,
-which can have undesirable side effects.
-
-So instead you need to specify that you only want to
-merge the changes on the branch which have not yet been
-merged into the trunk. To do that you specify two
-@samp{-j} options, and @sc{cvs} merges the changes from
-the first revision to the second revision. For
-example, in this case the simplest way would be
-
-@example
-cvs update -j 1.2.2.2 -j R1fix m.c # @r{Merge changes from 1.2.2.2 to the}
- # @r{head of the R1fix branch}
-@end example
-
-The problem with this is that you need to specify the
-1.2.2.2 revision manually. A slightly better approach
-might be to use the date the last merge was done:
-
-@example
-cvs update -j R1fix:yesterday -j R1fix m.c
-@end example
-
-Better yet, tag the R1fix branch after every merge into
-the trunk, and then use that tag for subsequent merges:
-
-@example
-cvs update -j merged_from_R1fix_to_trunk -j R1fix m.c
-@end example
-
-@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-@node Merging two revisions
-@section Merging differences between any two revisions
-@cindex Merging two revisions
-@cindex Revisions, merging differences between
-@cindex Differences, merging
-
-With two @samp{-j @var{revision}} flags, the @code{update}
-(and @code{checkout}) command can merge the differences
-between any two revisions into your working file.
-
-@cindex Undoing a change
-@cindex Removing a change
-@example
-$ cvs update -j 1.5 -j 1.3 backend.c
-@end example
-
-@noindent
-will @emph{remove} all changes made between revision
-1.3 and 1.5. Note the order of the revisions!
-
-If you try to use this option when operating on
-multiple files, remember that the numeric revisions will
-probably be very different between the various files
-that make up a module. You almost always use symbolic
-tags rather than revision numbers when operating on
-multiple files.
-
-@c ---------------------------------------------------------------------
-@node Recursive behavior
-@chapter Recursive behavior
-@cindex Recursive (directory descending)
-@cindex Directory, descending
-@cindex Descending directories
-@cindex Subdirectories
-
-Almost all of the subcommands of @sc{cvs} work
-recursively when you specify a directory as an
-argument. For instance, consider this directory
-structure:
-
-@example
- @code{$HOME}
- |
- +--@t{tc}
- | |
- +--@t{CVS}
- | (internal @sc{cvs} files)
- +--@t{Makefile}
- +--@t{backend.c}
- +--@t{driver.c}
- +--@t{frontend.c}
- +--@t{parser.c}
- +--@t{man}
- | |
- | +--@t{CVS}
- | | (internal @sc{cvs} files)
- | +--@t{tc.1}
- |
- +--@t{testing}
- |
- +--@t{CVS}
- | (internal @sc{cvs} files)
- +--@t{testpgm.t}
- +--@t{test2.t}
-@end example
-
-@noindent
-If @file{tc} is the current working directory, the
-following is true:
-
-@itemize @bullet
-@item
-@samp{cvs update testing} is equivalent to @samp{cvs
-update testing/testpgm.t testing/test2.t}
-
-@item
-@samp{cvs update testing man} updates all files in the
-subdirectories
-
-@item
-@samp{cvs update .} or just @samp{cvs update} updates
-all files in the @code{tc} module
-@end itemize
-
-If no arguments are given to @code{update} it will
-update all files in the current working directory and
-all its subdirectories. In other words, @file{.} is a
-default argument to @code{update}. This is also true
-for most of the @sc{cvs} subcommands, not only the
-@code{update} command.
-
-The recursive behavior of the @sc{cvs} subcommands can be
-turned off with the @samp{-l} option.
-
-@example
-$ cvs update -l # @r{Don't update files in subdirectories}
-@end example
-
-@c ---------------------------------------------------------------------
-@node Adding files
-@chapter Adding files to a module
-@cindex Adding files
-
-To add a new file to a module, follow these steps.
-
-@itemize @bullet
-@item
-You must have a working copy of the module.
-@xref{Getting the source}.
-
-@item
-Create the new file inside your working copy of the module.
-
-@item
-Use @samp{cvs add @var{filename}} to tell @sc{cvs} that you
-want to version control the file.
-
-@item
-Use @samp{cvs commit @var{filename}} to actually check
-in the file into the repository. Other developers
-cannot see the file until you perform this step.
-
-@item
-If the file contains binary data it might be necessary
-to change the default keyword substitution.
-@xref{Keyword substitution}. @xref{admin examples}.
-@end itemize
-
-You can also use the @code{add} command to add a new
-directory inside a module.
-
-Unlike most other commands, the @code{add} command is
-not recursive. You cannot even type @samp{cvs add
-foo/bar}! Instead, you have to
-
-@example
-$ cd foo
-$ cvs add bar
-@end example
-
-@xref{add}, for a more complete description of the @code{add}
-command.
-
-@c ---------------------------------------------------------------------
-@node Removing files
-@chapter Removing files from a module
-@cindex Removing files
-@cindex Deleting files
-
-Modules change. New files are added, and old files
-disappear. Still, you want to be able to retrieve an
-exact copy of old releases of the module.
-
-Here is what you can do to remove a file from a module,
-but remain able to retrieve old revisions:
-
-@itemize @bullet
-@item
-Make sure that you have not made any uncommitted
-modifications to the file. @xref{Viewing differences},
-for one way to do that. You can also use the
-@code{status} or @code{update} command. If you remove
-the file without committing your changes, you will of
-course not be able to retrieve the file as it was
-immediately before you deleted it.
-
-@item
-Remove the file from your working copy of the module.
-You can for instance use @code{rm}.
-
-@item
-Use @samp{cvs remove @var{filename}} to tell @sc{cvs} that
-you really want to delete the file.
-
-@item
-Use @samp{cvs commit @var{filename}} to actually
-perform the removal of the file from the repository.
-@end itemize
-
-What happens when you commit the removal of the file is
-that inside the source repository, it is moved into a
-subdirectory called @file{Attic}. @sc{cvs} normally doesn't
-look in that directory when you run e.g.
-@code{checkout}. However, if you are retrieving a
-certain revision via e.g. @samp{cvs checkout -r
-@var{some-tag}}, it will look at the files inside the
-@file{Attic} and include any files that contain the
-specified tag.
-
-@c ---------------------------------------------------------------------
-@node Tracking sources
-@chapter Tracking third-party sources
-@cindex Third-party sources
-@cindex Tracking sources
-
-If you modify a program to better fit your site, you
-probably want to include your modifications when the next
-release of the program arrives. @sc{cvs} can help you with
-this task.
-
-@cindex Vendor
-@cindex Vendor branch
-@cindex Branch, vendor-
-In the terminology used in @sc{cvs}, the supplier of the
-program is called a @dfn{vendor}. The unmodified
-distribution from the vendor is checked in on its own
-branch, the @dfn{vendor branch}. @sc{cvs} reserves branch
-1.1.1 for this use.
-
-When you modify the source and commit it, your revision
-will end up on the main trunk. When a new release is
-made by the vendor, you commit it on the vendor branch
-and copy the modifications onto the main trunk.
-
-Use the @code{import} command to create and update
-the vendor branch. After a successful @code{import}
-the vendor branch is made the `head' revision, so
-anyone that checks out a copy of the file gets that
-revision. When a local modification is committed it is
-placed on the main trunk, and made the `head'
-revision.
-
-@menu
-* First import:: Importing a module for the first time
-* Update imports:: Updating a module with the import command
-@end menu
-
-@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-@node First import
-@section Importing a module for the first time
-@cindex Importing modules
-
-Use the @code{import} command to check in the sources
-for the first time. When you use the @code{import}
-command to track third-party sources, the @dfn{vendor
-tag} and @dfn{release tags} are useful. The
-@dfn{vendor tag} is a symbolic name for the branch
-(which is always 1.1.1, unless you use the @samp{-b
-@var{branch}} flag---@xref{import options}). The
-@dfn{release tags} are symbolic names for a particular
-release, such as @samp{FSF_0_04}.
-
-@cindex Wdiff (import example)
-Suppose you use @code{wdiff} (a variant of @code{diff}
-that ignores changes that only involve whitespace), and
-are going to make private modifications that you want
-to be able to use even when new releases are made in
-the future. You start by importing the source to your
-repository:
-
-@example
-$ tar xfz wdiff-0.04.tar.gz
-$ cd wdiff-0.04
-$ cvs import -m "Import of FSF v. 0.04" fsf/wdiff FSF WDIFF_0_04
-@end example
-
-The vendor tag is named @samp{FSF} in the above
-example, and the only release tag assigned is
-@samp{WDIFF_0_04}.
-
-@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-@node Update imports
-@section Updating a module with the import command
-
-When a new release of the source arrives, you import it into the
-repository with the same @code{import} command that you used to set up
-the repository in the first place. The only difference is that you
-specify a different release tag this time.
-
-@example
-$ tar xfz wdiff-0.05.tar.gz
-$ cd wdiff-0.05
-$ cvs import -m "Import of FSF v. 0.05" fsf/wdiff FSF WDIFF_0_05
-@end example
-
-For files that have not been modified locally, the newly created
-revision becomes the head revision. If you have made local
-changes, @code{import} will warn you that you must merge the changes
-into the main trunk, and tell you to use @samp{checkout -j} to do so.
-
-@example
-$ cvs checkout -jFSF:yesterday -jFSF wdiff
-@end example
-
-@noindent
-The above command will check out the latest revision of
-@samp{wdiff}, merging the changes made on the vendor branch @samp{FSF}
-since yesterday into the working copy. If any conflicts arise during
-the merge they should be resolved in the normal way (@pxref{Conflicts
-example}). Then, the modified files may be committed.
-
-Using a date, as suggested above, assumes that you do
-not import more than one release of a product per
-day. If you do, you can always use something like this
-instead:
-
-@example
-$ cvs checkout -jWDIFF_0_04 -jWDIFF_0_05 wdiff
-@end example
-
-@noindent
-In this case, the two above commands are equivalent.
-
-@c ---------------------------------------------------------------------
-@node Moving files
-@chapter Moving and renaming files
-@cindex Moving files
-@cindex Renaming files
-@cindex Files, moving
-
-Moving files to a different directory or renaming them
-is not difficult, but some of the ways in which this
-works may be non-obvious. (Moving or renaming a
-directory is even harder. @xref{Moving directories}).
-
-The examples below assume that the file @var{old} is renamed to
-@var{new}.
-
-@menu
-* Outside:: The normal way to Rename
-* Inside:: A tricky, alternative way
-* Rename by copying:: Another tricky, alternative way
-@end menu
-
-@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-@node Outside
-@section The Normal way to Rename
-
-The normal way to move a file is to copy @var{old} to
-@var{new}, and then issue the normal @sc{cvs} commands
-to remove @var{old} from the repository, and add
-@var{new} to it. (Both @var{old} and @var{new} could
-contain relative paths, for example @file{foo/bar.c}).
-
-@example
-$ mv @var{old} @var{new}
-$ cvs remove @var{old}
-$ cvs add @var{new}
-$ cvs commit -m "Renamed @var{old} to @var{new}" @var{old} @var{new}
-@end example
-
-This is the simplest way to move a file, it is not
-error-prone, and it preserves the history of what was
-done. Note that to access the history of the file you
-must specify the old or the new name, depending on what
-portion of the history you are accessing. For example,
-@code{cvs log @var{old}} will give the log up until the
-time of the rename.
-
-When @var{new} is committed its revision numbers will
-start at 1.0 again, so if that bothers you, use the
-@samp{-r rev} option to commit (@pxref{commit options})
-
-@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-@node Inside
-@section Moving the history file
-
-This method is more dangerous, since it involves moving
-files inside the repository. Read this entire section
-before trying it out!
-
-@example
-$ cd $CVSROOT/@var{module}
-$ mv @var{old},v @var{new},v
-@end example
-
-@noindent
-Advantages:
-
-@itemize @bullet
-@item
-The log of changes is maintained intact.
-
-@item
-The revision numbers are not affected.
-@end itemize
-
-@noindent
-Disadvantages:
-
-@itemize @bullet
-@item
-Old releases of the module cannot easily be fetched from the
-repository. (The file will show up as @var{new} even
-in revisions from the time before it was renamed).
-
-@item
-There is no log information of when the file was renamed.
-
-@item
-Nasty things might happen if someone accesses the history file
-while you are moving it. Make sure no one else runs any of the @sc{cvs}
-commands while you move it.
-@end itemize
-
-@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-@node Rename by copying
-@section Copying the history file
-
-This way also involves direct modifications to the
-repository. It is safe, but not without drawbacks.
-
-@example
-# @r{Copy the @sc{rcs} file inside the repository}
-$ cd $CVSROOT/@var{module}
-$ cp @var{old},v @var{new},v
-# @r{Remove the old file}
-$ cd ~/@var{module}
-$ rm @var{old}
-$ cvs remove @var{old}
-$ cvs commit @var{old}
-# @r{Remove all tags from @var{new}}
-$ cvs update @var{new}
-$ cvs log @var{new} # @r{Remember the tag names}
-$ cvs tag -d @var{tag1}
-$ cvs tag -d @var{tag2}
-@dots{}
-@end example
-
-By removing the tags you will be able to check out old
-revisions of the module.
-
-@noindent
-Advantages:
-
-@itemize @bullet
-@item
-@c FIXME: Is this true about -D now that we have death
-@c support? See 5B.3 in the FAQ.
-Checking out old revisions works correctly, as long as
-you use @samp{-r@var{tag}} and not @samp{-D@var{date}}
-to retrieve the revisions.
-
-@item
-The log of changes is maintained intact.
-
-@item
-The revision numbers are not affected.
-@end itemize
-
-@noindent
-Disadvantages:
-
-@itemize @bullet
-@item
-You cannot easily see the history of the file across the rename.
-
-@item
-Unless you use the @samp{-r rev} (@pxref{commit
-options}) flag when @var{new} is committed its revision
-numbers will start at 1.0 again.
-@end itemize
-
-@c ---------------------------------------------------------------------
-@node Moving directories
-@chapter Moving and renaming directories
-@cindex Moving directories
-@cindex Renaming directories
-@cindex Directories, moving
-
-If you want to be able to retrieve old versions of the
-module, you must move each file in the directory
-with the @sc{cvs} commands. @xref{Outside}. The old, empty
-directory will remain inside the repository, but it
-will not appear in your workspace when you check out
-the module in the future.
-@c -- rephrase
-
-If you really want to rename or delete a directory, you
-can do it like this:
-
-@enumerate
-@item
-Inform everyone who has a copy of the module that the
-directory will be renamed. They should commit all
-their changes, and remove their working copies of the
-module, before you take the steps below.
-
-@item
-Rename the directory inside the repository.
-
-@example
-$ cd $CVSROOT/@var{module}
-$ mv @var{old-dir} @var{new-dir}
-@end example
-
-@item
-Fix the @sc{cvs} administrative files, if necessary (for
-instance if you renamed an entire module).
-
-@item
-Tell everyone that they can check out the module and continue
-working.
-
-@end enumerate
-
-If someone had a working copy of the module the @sc{cvs} commands will
-cease to work for him, until he removes the directory
-that disappeared inside the repository.
-
-It is almost always better to move the files in the
-directory instead of moving the directory. If you move the
-directory you are unlikely to be able to retrieve old
-releases correctly, since they probably depend on the
-name of the directories.
-
-@ignore
-@c ---------------------------------------------------------------------
-@c @node History browsing
-@chapter History browsing
-@cindex History browsing
-@cindex Traceability
-@cindex Isolation
-
-@c -- @quote{To lose ones history is to lose ones soul.}
-@c -- ///
-@c -- ///Those who cannot remember the past are condemned to repeat it.
-@c -- /// -- George Santayana
-@c -- ///
-
-@sc{cvs} tries to make it easy for a group of people to work
-together. This is done in two ways:
-
-@itemize @bullet
-@item
-Isolation---You have your own working copy of the
-source. You are not affected by modifications made by
-others until you decide to incorporate those changes
-(via the @code{update} command---@pxref{update}).
-
-@item
-Traceability---When something has changed, you can
-always see @emph{exactly} what changed.
-@end itemize
-
-There are several features of @sc{cvs} that together lead
-to traceability:
-
-@itemize @bullet
-@item
-Each revision of a file has an accompanying log
-message.
-
-@item
-All commits are optionally logged to a central history
-database.
-
-@item
-Logging information can be sent to a user-defined
-program (@pxref{loginfo}).
-@end itemize
-
-@c -- More text here.
-
-This chapter should talk about the history file, the
-@code{log} command, the usefulness of ChangeLogs
-even when you run @sc{cvs}, and things like that.
-
-@menu
-* log messages:: Log messages
-* history database:: The history database
-* user-defined logging:: User-defined logging
-@end menu
-
-@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-@node log messages
-@section Log messages
-
-Whenever you commit a file you specify a log message. ///
-@c --
-
-@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-@node history database
-@section The history database
-
-///
-
-@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-@node user-defined logging
-@section User-defined logging
-
-///
-
-@end ignore
-
-@c ---------------------------------------------------------------------
-@node Keyword substitution
-@chapter Keyword substitution
-@cindex Keyword substitution
-@cindex Keyword expansion
-@cindex Identifying files
-
-@comment Be careful when editing this chapter.
-@comment Remember that this file is kept under
-@comment version control, so we must not accidentally
-@comment include a valid keyword in the running text.
-
-As long as you edit source files inside your working
-copy of a module you can always find out the state of
-your files via @samp{cvs status} and @samp{cvs log}.
-But as soon as you export the files from your
-development environment it becomes harder to identify
-which revisions they are.
-
-@sc{Rcs} uses a mechanism known as @dfn{keyword
-substitution} (or @dfn{keyword expansion}) to help
-identifying the files. Embedded strings of the form
-@code{$@var{keyword}$} and
-@code{$@var{keyword}:@dots{}$} in a file are replaced
-with strings of the form
-@code{$@var{keyword}:@var{value}$} whenever you obtain
-a new revision of the file.
-
-@menu
-* Keyword list:: RCS Keywords
-* Using keywords:: Using keywords
-* Avoiding substitution:: Avoiding substitution
-* Substitution modes:: Substitution modes
-* Log keyword:: Problems with the $@asis{}Log$ keyword.
-@end menu
-
-@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-@node Keyword list
-@section RCS Keywords
-@cindex RCS keywords
-
-This is a list of the keywords that @sc{rcs} currently
-(in release 5.6.0.1) supports:
-
-@table @code
-@cindex Author keyword
-@item $@asis{Author}$
-The login name of the user who checked in the revision.
-
-@cindex Date keyword
-@item $@asis{Date}$
-The date and time (UTC) the revision was checked in.
-
-@cindex Header keyword
-@item $@asis{Header}$
-A standard header containing the full pathname of the
-@sc{rcs} file, the revision number, the date (UTC), the
-author, the state, and the locker (if locked). Files
-will normally never be locked when you use @sc{cvs}.
-
-@cindex Id keyword
-@item $@asis{Id}$
-Same as @code{$@asis{Header}$}, except that the @sc{rcs}
-filename is without a path.
-
-@cindex Locker keyword
-@item $@asis{Locker}$
-The login name of the user who locked the revision
-(empty if not locked, and thus almost always useless
-when you are using @sc{cvs}).
-
-@cindex Log keyword
-@item $@asis{Log}$
-The log message supplied during commit, preceded by a
-header containing the @sc{rcs} filename, the revision
-number, the author, and the date (UTC). Existing log
-messages are @emph{not} replaced. Instead, the new log
-message is inserted after @code{$@asis{Log:@dots{}}$}.
-Each new line is prefixed with a @dfn{comment leader}
-which @sc{rcs} guesses from the file name extension.
-It can be changed with @code{cvs admin -c}.
-@xref{admin options}. This keyword is useful for
-accumulating a complete change log in a source file,
-but for several reasons it can be problematic.
-@xref{Log keyword}.
-
-@cindex RCSfile keyword
-@item $@asis{RCSfile}$
-The name of the RCS file without a path.
-
-@cindex Revision keyword
-@item $@asis{Revision}$
-The revision number assigned to the revision.
-
-@cindex Source keyword
-@item $@asis{Source}$
-The full pathname of the RCS file.
-
-@cindex State keyword
-@item $@asis{State}$
-The state assigned to the revision. States can be
-assigned with @code{cvs admin -s}---@xref{admin options}.
-
-@end table
-
-@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-@node Using keywords
-@section Using keywords
-
-To include a keyword string you simply include the
-relevant text string, such as @code{$@asis{Id}$}, inside the
-file, and commit the file. @sc{cvs} will automatically
-expand the string as part of the commit operation.
-
-@need 800
-It is common to embed @code{$@asis{}Id$} string in the
-C source code. This example shows the first few lines
-of a typical file, after keyword substitution has been
-performed:
-
-@example
-static char *rcsid="$@asis{}Id: samp.c,v 1.5 1993/10/19 14:57:32 ceder Exp $";
-/* @r{The following lines will prevent @code{gcc} version 2.@var{x}}
- @r{from issuing an "unused variable" warning}. */
-#if __GNUC__ == 2
-#define USE(var) static void * use_##var = (&use_##var, (void *) &var)
-USE (rcsid);
-#endif
-@end example
-
-Even though a clever optimizing compiler could remove
-the unused variable @code{rcsid}, most compilers tend
-to include the string in the binary. Some compilers
-have a @code{#pragma} directive to include literal text
-in the binary.
-
-@cindex Ident (shell command)
-The @code{ident} command (which is part of the @sc{rcs}
-package) can be used to extract keywords and their
-values from a file. This can be handy for text files,
-but it is even more useful for extracting keywords from
-binary files.
-
-@example
-$ ident samp.c
-samp.c:
- $@asis{}Id: samp.c,v 1.5 1993/10/19 14:57:32 ceder Exp $
-$ gcc samp.c
-$ ident a.out
-a.out:
- $@asis{}Id: samp.c,v 1.5 1993/10/19 14:57:32 ceder Exp $
-@end example
-
-@cindex What (shell command)
-S@sc{ccs} is another popular revision control system.
-It has a command, @code{what}, which is very similar to
-@code{ident} and used for the same purpose. Many sites
-without @sc{rcs} have @sc{sccs}. Since @code{what}
-looks for the character sequence @code{@@(#)} it is
-easy to include keywords that are detected by either
-command. Simply prefix the @sc{rcs} keyword with the
-magic @sc{sccs} phrase, like this:
-
-@example
-static char *id="@@(#) $@asis{}Id: ab.c,v 1.5 1993/10/19 14:57:32 ceder Exp $";
-@end example
-
-@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-@node Avoiding substitution
-@section Avoiding substitution
-
-Keyword substitution has its disadvantages. Sometimes
-you might want the literal text string
-@samp{$@asis{}Author$} to appear inside a file without
-@sc{rcs} interpreting it as a keyword and expanding it
-into something like @samp{$@asis{}Author: ceder $}.
-
-There is unfortunately no way to selectively turn off
-keyword substitution. You can use @samp{-ko}
-(@pxref{Substitution modes}) to turn off keyword
-substitution entirely. (If you put binaries under
-version control you are strongly encouraged to use that
-option, for obvious reasons).
-
-In many cases you can avoid using @sc{rcs} keywords in
-the source, even though they appear in the final
-product. For example, the source for this manual
-contains @samp{$@@asis@{@}Author$} whenever the text
-@samp{$@asis{}Author$} should appear. In @code{nroff}
-and @code{troff} you can embed the null-character
-@code{\&} inside the keyword for a similar effect.
-
-@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-@node Substitution modes
-@section Substitution modes
-@cindex -k (RCS kflags)
-@cindex Kflag
-
-You can control how @sc{rcs} expands keywords
-through the use of the @samp{-k} option (@pxref{Common
-options}). The @samp{-k} option is available with the
-@code{add}, @code{checkout}, @code{diff} and
-@code{update} commands.
-
-Five different modes are available. They are:
-
-@table @samp
-@item -kkv
-Generate keyword strings using the default form, e.g.
-@code{$@asis{}Revision: 5.7 $} for the @code{Revision}
-keyword.
-
-@item -kkvl
-Like @samp{-kkv}, except that a locker's name is always
-inserted if the given revision is currently locked.
-This option is normally not useful when @sc{cvs} is used.
-
-@item -kk
-Generate only keyword names in keyword strings; omit
-their values. For example, for the @code{Revision}
-keyword, generate the string @code{$@asis{}Revision$}
-instead of @code{$@asis{}Revision: 5.7 $}. This option
-is useful to ignore differences due to keyword
-substitution when comparing different revisions of a
-file.
-
-@item -ko
-Generate the old keyword string, present in the working
-file just before it was checked in. For example, for
-the @code{Revision} keyword, generate the string
-@code{$@asis{}Revision: 1.1 $} instead of
-@code{$@asis{}Revision: 5.7 $} if that is how the
-string appeared when the file was checked in. This can
-be useful for binary file formats that cannot tolerate
-any changes to substrings that happen to take the form
-of keyword strings.
-
-@item -kv
-Generate only keyword values for keyword strings. For
-example, for the @code{Revision} keyword, generate the string
-@code{5.7} instead of @code{$@asis{}Revision: 5.7 $}.
-This can help generate files in programming languages
-where it is hard to strip keyword delimiters like
-@code{$@asis{}Revision: $} from a string. However,
-further keyword substitution cannot be performed once
-the keyword names are removed, so this option should be
-used with care.
-
-This option is always use by @code{cvs
-export}---@pxref{export}.
-
-@end table
-
-@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-@node Log keyword
-@section Problems with the $@asis{}Log$ keyword.
-
-The @code{$@asis{}Log$} keyword is somewhat
-controversial. As long as you are working on your
-development system the information is easily accessible
-even if you do not use the @code{$@asis{}Log$}
-keyword---just do a @code{cvs log}. Once you export
-the file the history information might be useless
-anyhow.
-
-A more serious concern is that @sc{rcs} is not good at
-handling @code{$@asis{}Log$} entries when a branch is
-merged onto the main trunk. Conflicts often result
-from the merging operation.
-
-People also tend to "fix" the log entries in the file
-(correcting spelling mistakes and maybe even factual
-errors). If that is done the information from
-@code{cvs log} will not be consistent with the
-information inside the file. This may or may not be a
-problem in real life.
-
-It has been suggested that the @code{$@asis{}Log$}
-keyword should be inserted @emph{last} in the file, and
-not in the files header, if it is to be used at all.
-That way the long list of change messages will not
-interfere with everyday source file browsing.
-
-@c ---------------------------------------------------------------------
-@node Revision management
-@chapter Revision management
-@cindex Revision management
-
-@c -- This chapter could be expanded a lot.
-@c -- Experiences are very welcome!
-
-If you have read this far, you probably have a pretty
-good grasp on what @sc{cvs} can do for you. This
-chapter talks a little about things that you still have
-to decide.
-
-If you are doing development on your own using @sc{cvs}
-you could probably skip this chapter. The questions
-this chapter takes up become more important when more
-than one person is working in a repository.
-
-@menu
-* When to commit:: Some discussion on the subject
-@end menu
-
-@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-@node When to commit
-@section When to commit?
-@cindex When to commit
-@cindex Commit, when to
-@cindex Policy
-
-Your group should decide which policy to use regarding
-commits. Several policies are possible, and as your
-experience with @sc{cvs} grows you will probably find
-out what works for you.
-
-If you commit files too quickly you might commit files
-that do not even compile. If your partner updates his
-working sources to include your buggy file, he will be
-unable to compile the code. On the other hand, other
-persons will not be able to benefit from the
-improvements you make to the code if you commit very
-seldom, and conflicts will probably be more common.
-
-It is common to only commit files after making sure
-that they can be compiled. Some sites require that the
-files pass a test suite. Policies like this can be
-enforced using the commitinfo file
-(@pxref{commitinfo}), but you should think twice before
-you enforce such a convention. By making the
-development environment too controlled it might become
-too regimented and thus counter-productive to the real
-goal, which is to get software written.
-
-@c ---------------------------------------------------------------------
-@node Invoking CVS
-@appendix Reference manual for CVS commands
-@cindex Command reference
-@cindex Reference, commands
-@cindex Invoking CVS
-
-This appendix describes every subcommand of @sc{cvs} in
-detail. It also describes how to invoke CVS.
-
-@menu
-* Structure:: Overall structure of CVS commands
-* ~/.cvsrc:: Default options with the ~/.csvrc file
-* Global options:: Options you give to the left of cvs_command
-* Common options:: Options you give to the right of cvs_command
-* add:: Add a new file/directory to the repository
-* admin:: Administration front end for rcs
-* checkout:: Checkout sources for editing
-* commit:: Check files into the repository
-* diff:: Run diffs between revisions
-* export:: Export sources from CVS, similar to checkout
-* history:: Show status of files and users
-* import:: Import sources into CVS, using vendor branches
-* log:: Print out 'rlog' information for files
-* rdiff:: 'patch' format diffs between releases
-* release:: Indicate that a Module is no longer in use
-* remove:: Remove an entry from the repository
-* rtag:: Add a tag to a module
-* status:: Status info on the revisions
-* tag:: Add a tag to checked out version
-* update:: Bring work tree in sync with repository
-@end menu
-
-@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-@node Structure
-@appendixsec Overall structure of CVS commands
-@cindex Structure
-@cindex CVS command structure
-@cindex Command structure
-@cindex Format of CVS commands
-
-The first release of @sc{cvs} consisted of a number of shell-scripts.
-Today @sc{cvs} is implemented as a single program that is a front-end
-to @sc{rcs} and @code{diff}. The overall format of all
-@sc{cvs} commands is:
-
-@example
-cvs [ cvs_options ] cvs_command [ command_options ] [ command_args ]
-@end example
-
-@table @code
-@item cvs
-The program that is a front-end to @sc{rcs}.
-
-@item cvs_options
-Some options that affect all sub-commands of @sc{cvs}. These are
-described below.
-
-@item cvs_command
-One of several different sub-commands. Some of the commands have
-aliases that can be used instead; those aliases are noted in the
-reference manual for that command. There are only two situations
-where you may omit @samp{cvs_command}: @samp{cvs -H} elicits a
-list of available commands, and @samp{cvs -v} displays version
-information on @sc{cvs} itself.
-
-@item command_options
-Options that are specific for the command.
-
-@item command_args
-Arguments to the commands.
-@end table
-
-There is unfortunately some confusion between
-@code{cvs_options} and @code{command_options}.
-@samp{-l}, when given as a @code{cvs_option}, only
-affects some of the commands. When it is given as a
-@code{command_option} is has a different meaning, and
-is accepted by more commands. In other words, do not
-take the above categorization too seriously. Look at
-the documentation instead.
-
-@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-@node ~/.cvsrc
-@appendixsec Default options and the ~/.cvsrc file
-@cindex .cvsrc file
-@cindex option defaults
-
-There are some @code{command_options} that are used so
-often that you might have set up an alias or some other
-means to make sure you always specify that option. One
-example (the one that drove the implementation of the
-.cvsrc support, actually) is that many people find the
-default output of the @samp{diff} command to be very
-hard to read, and that either context diffs or unidiffs
-are much easier to understand.
-
-The @file{~/.cvsrc} file is a way that you can add
-default options to @code{cvs_commands} within cvs,
-instead of relying on aliases or other shell scripts.
-
-The format of the @file{~/.cvsrc} file is simple. The
-file is searched for a line that begins with the same
-name as the @code{cvs_command} being executed. If a
-match is found, then the remainder of the line is split
-up (at whitespace characters) into separate options and
-added to the command arguments @emph{before} any
-options from the command line.
-
-If a command has two names (e.g., @code{checkout} and
-@code{co}), the official name, not necessarily the one
-used on the command line, will be used to match against
-the file. So if this is the contents of the user's
-@file{~/.cvsrc} file:
-
-@example
-log -N
-diff -u
-update -P
-co -P
-@end example
-
-@noindent
-the command @samp{cvs checkout foo} would have the
-@samp{-P} option added to the arguments, as well as
-@samp{cvs co foo}.
-
-With the example file above, the output from @samp{cvs
-diff foobar} will be in unidiff format. @samp{cvs diff
--c foobar} will provide context diffs, as usual.
-Getting "old" format diffs would be slightly more
-complicated, because @code{diff} doesn't have an option
-to specify use of the "old" format, so you would need
-@samp{cvs -f diff foobar}.
-
-
-
-@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-@node Global options
-@appendixsec Global options
-@cindex Options, global
-@cindex Global options
-@cindex Left-hand options
-
-The available @samp{cvs_options} (that are given to the
-left of @samp{cvs_command}) are:
-
-@table @code
-@cindex RCSBIN, overriding
-@cindex Overriding RCSBIN
-@item -b @var{bindir}
-Use @var{bindir} as the directory where @sc{rcs} programs are
-located. Overrides the setting of the @code{$RCSBIN} environment
-variable and any precompiled directory. This parameter should be
-specified as an absolute pathname.
-
-@cindex CVSROOT, overriding
-@cindex Overriding CVSROOT
-@item -d @var{cvs_root_directory}
-Use @var{cvs_root_directory} as the root directory
-pathname of the repository. Overrides the setting of
-the @code{$CVSROOT} environment variable. @xref{Repository}.
-
-@cindex EDITOR, overriding
-@cindex Overriding EDITOR
-@item -e @var{editor}
-Use @var{editor} to enter revision log information. Overrides the
-setting of the @code{$CVSEDITOR} and @code{$EDITOR} environment variables.
-
-@item -f
-Do not read the @file{~/.cvsrc} file. This
-option is most often used because of the
-non-orthogonality of the @sc{cvs} option set. For
-example, the @samp{cvs log} option @samp{-N} (turn off
-display of tag names) does not have a corresponding
-option to turn the display on. So if you have
-@samp{-N} in the @file{~/.cvsrc} entry for @samp{diff},
-you may need to use @samp{-f} to show the tag names.
-@footnote{Yes, this really should be fixed, and it's
-being worked on}
-
-@item -H
-Display usage information about the specified @samp{cvs_command}
-(but do not actually execute the command). If you don't specify
-a command name, @samp{cvs -H} displays a summary of all the
-commands available.
-
-@item -l
-Do not log the cvs_command in the command history (but execute it
-anyway). @xref{history}, for information on command history.
-
-@cindex Read-only mode
-@item -n
-Do not change any files. Attempt to execute the
-@samp{cvs_command}, but only to issue reports; do not remove,
-update, or merge any existing files, or create any new files.
-
-@item -Q
-Cause the command to be really quiet; the command will only
-generate output for serious problems.
-
-@item -q
-Cause the command to be somewhat quiet; informational messages,
-such as reports of recursion through subdirectories, are
-suppressed.
-
-@cindex Read-only files
-@item -r
-Make new working files files read-only. Same effect
-as if the @code{$CVSREAD} environment variable is set
-(@pxref{Environment variables}). The default is to
-make working files writable.
-
-@cindex Trace
-@item -t
-Trace program execution; display messages showing the steps of
-@sc{cvs} activity. Particularly useful with @samp{-n} to explore the
-potential impact of an unfamiliar command.
-
-@item -v
-Display version and copyright information for @sc{cvs}.
-
-@cindex CVSREAD, overriding
-@cindex Overriding CVSREAD
-@item -w
-Make new working files read-write. Overrides the
-setting of the @code{$CVSREAD} environment variable.
-Files are created read-write by default, unless @code{$CVSREAD} is
-set or @samp{-r} is given.
-
-@end table
-
-@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-@node Common options
-@appendixsec Common command options
-@cindex Common options
-@cindex Right-hand options
-
-This section describes the @samp{command_options} that
-are available across several @sc{cvs} commands. These
-options are always given to the right of
-@samp{cvs_command}. Not all
-commands support all of these options; each option is
-only supported for commands where it makes sense.
-However, when a command has one of these options you
-can almost always count on the same behavior of the
-option as in other commands. (Other command options,
-which are listed with the individual commands, may have
-different behavior from one @sc{cvs} command to the other).
-
-@strong{Warning:} the @samp{history} command is an exception; it supports
-many options that conflict even with these standard options.
-
-@table @code
-@cindex Dates
-@cindex Time
-@cindex Specifying dates
-@item -D @var{date_spec}
-Use the most recent revision no later than @var{date_spec}.
-@var{date_spec} is a single argument, a date description
-specifying a date in the past.
-
-The specification is @dfn{sticky} when you use it to make a
-private copy of a source file; that is, when you get a working
-file using @samp{-D}, @sc{cvs} records the date you specified, so that
-further updates in the same directory will use the same date
-(unless you explicitly override it; @pxref{update}).
-
-A wide variety of date formats are supported by the underlying
-@sc{rcs} facilities, similar to those described in co(1), but not
-exactly the same. The @var{date_spec} is interpreted as being
-in the local timezone, unless a specific timezone is specified.
-Examples of valid date specifications include:
-
-@example
- 1 month ago
- 2 hours ago
- 400000 seconds ago
- last year
- last Monday
- yesterday
- a fortnight ago
- 3/31/92 10:00:07 PST
- January 23, 1987 10:05pm
- 22:00 GMT
-@end example
-
-@samp{-D} is available with the @code{checkout},
-@code{diff}, @code{export}, @code{history},
-@code{rdiff}, @code{rtag}, and @code{update} commands.
-(The @code{history} command uses this option in a
-slightly different way; @pxref{history options}).
-
-Remember to quote the argument to the @samp{-D}
-flag so that your shell doesn't interpret spaces as
-argument separators. A command using the @samp{-D}
-flag can look like this:
-
-@example
-$ cvs diff -D "1 hour ago" cvs.texinfo
-@end example
-
-@cindex Forcing a tag match
-@item -f
-When you specify a particular date or tag to @sc{cvs} commands, they
-normally ignore files that do not contain the tag (or did not
-exist prior to the date) that you specified. Use the @samp{-f} option
-if you want files retrieved even when there is no match for the
-tag or date. (The most recent revision of the file
-will be used).
-
-@need 800
-@samp{-f} is available with these commands: @code{checkout},
-@code{export}, @code{rdiff}, @code{rtag}, and @code{update}.
-
-@strong{Warning:} The @code{commit} command also has a
-@samp{-f} option, but it has a different behavior for
-that command. @xref{commit options}.
-
-@item -H
-Help; describe the options available for this command. This is
-the only option supported for all @sc{cvs} commands.
-
-@item -k @var{kflag}
-Alter the default @sc{rcs} processing of keywords.
-@xref{Keyword substitution}, for the meaning of
-@var{kflag}. Your @var{kflag} specification is
-@dfn{sticky} when you use it to create a private copy
-of a source file; that is, when you use this option
-with the @code{checkout} or @code{update} commands,
-@sc{cvs} associates your selected @var{kflag} with the
-file, and continues to use it with future update
-commands on the same file until you specify otherwise.
-
-The @samp{-k} option is available with the @code{add},
-@code{checkout}, @code{diff} and
-@code{update} commands.
-
-@item -l
-Local; run only in current working directory, rather than
-recursing through subdirectories.
-
-@strong{Warning:} this is not the same
-as the overall @samp{cvs -l} option, which you can specify to the
-left of a cvs command!
-
-Available with the following commands: @code{checkout},
-@code{commit}, @code{diff}, @code{export}, @code{log},
-@code{remove}, @code{rdiff}, @code{rtag},
-@code{status}, @code{tag}, and @code{update}.
-
-@cindex Editor, avoiding invocation of
-@cindex Avoiding editor invocation
-@item -m @var{message}
-Use @var{message} as log information, instead of
-invoking an editor.
-
-Available with the following commands: @code{add},
-@code{commit} and @code{import}.
-
-@item -n
-Do not run any checkout/commit/tag program. (A program can be
-specified to run on each of these activities, in the modules
-database (@pxref{modules}); this option bypasses it).
-
-@strong{Warning:} this is not the same as the overall @samp{cvs -n}
-option, which you can specify to the left of a cvs command!
-
-Available with the @code{checkout}, @code{commit}, @code{export},
-and @code{rtag} commands.
-
-@item -P
-Prune (remove) directories that are empty after being updated, on
-@code{checkout}, or @code{update}. Normally, an empty directory
-(one that is void of revision-controlled files) is left alone.
-Specifying @samp{-P} will cause these directories to be silently
-removed from your checked-out sources. This does not remove the
-directory from the repository, only from your checked out copy.
-Note that this option is implied by the @samp{-r} or @samp{-D}
-options of @code{checkout} and @code{export}.
-@c -- implied--
-
-@item -p
-Pipe the files retrieved from the repository to standard output,
-rather than writing them in the current directory. Available
-with the @code{checkout} and @code{update} commands.
-
-@item -W
-Specify file names that should be filtered. You can
-use this option repeatedly. The spec can be a file
-name pattern of the same type that you can specify in
-the @file{.cvswrappers} file.
-Avaliable with the following commands: @code{import},
-and @code{update}.
-
-@item -r @var{tag}
-Use the revision specified by the @var{tag} argument instead of the
-default @dfn{head} revision. As well as arbitrary tags defined
-with the @code{tag} or @code{rtag} command, two special tags are
-always available: @samp{HEAD} refers to the most recent version
-available in the repository, and @samp{BASE} refers to the
-revision you last checked out into the current working directory.
-
-The tag specification is sticky when you use this option
-with @code{checkout} or @code{update} to make your own
-copy of a file: @sc{cvs} remembers the tag and continues to use it on
-future update commands, until you specify otherwise. The
-tag can be either a symbolic or numeric tag.
-@xref{Tags}.
-
-Specifying the @samp{-q} global option along with the
-@samp{-r} command option is often useful, to suppress
-the warning messages when the @sc{rcs} history file
-does not contain the specified tag.
-
-@strong{Warning:} this is not the same as the overall `cvs -r' option,
-which you can specify to the left of a cvs command!
-
-@samp{-r} is available with the @code{checkout}, @code{commit},
-@code{diff}, @code{history}, @code{export}, @code{rdiff},
-@code{rtag}, and @code{update} commands.
-
-@end table
-
-@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-@node add
-@appendixsec add---Add a new file/directory to the repository
-@cindex Add (subcommand)
-
-@itemize @bullet
-@item
-Synopsis: add [-k kflag] [-m 'message'] files@dots{}
-@item
-Requires: repository, working directory.
-@item
-Changes: working directory.
-@item
-Synonym: new
-@end itemize
-
-Use the @code{add} command to create a new file or directory in the
-source repository. The files or directories specified with @code{add}
-must already exist in the current directory (which must have been
-created with the @code{checkout} command). To add a whole new directory
-hierarchy to the source repository (for example, files received
-from a third-party vendor), use the @code{import} command
-instead. @xref{import}.
-
-If the argument to @code{add} refers to an immediate
-sub-directory, the directory is created at the correct place in
-the source repository, and the necessary @sc{cvs} administration
-files are created in your working directory. If the directory
-already exists in the source repository, @code{add} still creates
-the administration files in your version of the directory.
-This allows you to use @code{add} to add a particular directory
-to your private sources even if someone else created that
-directory after your checkout of the sources. You can do the
-following:
-
-@example
-$ mkdir new_directory
-$ cvs add new_directory
-$ cvs update new_directory
-@end example
-
-An alternate approach using @code{update} might be:
-
-@example
-$ cvs update -d new_directory
-@end example
-
-(To add any available new directories to your working directory,
-it's probably simpler to use @code{checkout} (@pxref{checkout})
-or @samp{update -d} (@pxref{update})).
-
-The added files are not placed in the source repository until you
-use @code{commit} to make the change permanent. Doing an
-@code{add} on a file that was removed with the @code{remove}
-command will resurrect the file, unless a @code{commit} command
-intervened.
-@xref{remove examples} for an example.
-
-
-Unlike most other commands @code{add} never recurses down
-directories. It cannot yet handle relative paths. Instead of
-
-@example
-$ cvs add foo/bar.c
-@end example
-
-you have to do
-
-@example
-$ cd foo
-$ cvs add bar.c
-@end example
-
-@menu
-* add options:: add options
-* add examples:: add examples
-@end menu
-
-@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
-@node add options
-@appendixsubsec add options
-@cindex Add options
-
-There are only two options you can give to @samp{add}:
-
-@table @code
-@item -k @var{kflag}
-This option specifies the default way that this file
-will be checked out. See rcs(1) and co(1). The
-@var{kflag} argument (@pxref{Substitution modes}) is
-stored in the @sc{rcs} file and can be changed with
-@code{admin -k} (@pxref{admin options}). Specifying
-@samp{-ko} is useful for checking in binaries that
-should not have the @sc{rcs} id strings expanded.
-
-@strong{Warning:} this option is reported to be broken in
-version 1.3 and 1.3-s2 of @sc{cvs}. Use @samp{admin -k}
-after the commit instead. @xref{admin examples}.
-@c -- broken--
-
-@item -m @var{description}
-Using this option, you can give a description for the file. This
-description appears in the history log (if it is enabled,
-@pxref{history file}). It will also be saved in the @sc{rcs} history
-file inside the repository when the file is committed. The
-@code{log} command displays this description.
-
-The description can be changed using @samp{admin -t}.
-@xref{admin}.
-
-If you omit the @samp{-m @var{description}} flag, an empty string will be
-used. You will not be prompted for a description.
-@end table
-
-@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
-@node add examples
-@appendixsubsec add examples
-
-To add the file @file{backend.c} to the repository, with a
-description, the following can be used.
-
-@example
-$ cvs add -m "Optimizer and code generation passes." backend.c
-$ cvs commit -m "Early version. Not yet compilable." backend.c
-@end example
-
-@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-@node admin
-@appendixsec admin---Administration front end for rcs
-@cindex Admin (subcommand)
-
-@itemize @bullet
-@item
-Requires: repository, working directory.
-@item
-Changes: repository.
-@item
-Synonym: rcs
-@end itemize
-
-This is the @sc{cvs} interface to assorted administrative @sc{rcs}
-facilities, documented in rcs(1). @code{admin} simply passes
-all its options and arguments to the @code{rcs} command; it does
-no filtering or other processing. This command @emph{does} work
-recursively, however, so extreme care should be used.
-
-If there is a group whose name matches a compiled in
-value which defaults to @code{cvsadmin}, only members
-of that group can use @code{cvs admin}. To disallow
-@code{cvs admin} for all users, create a group with no
-users in it.
-
-@menu
-* admin options:: admin options
-* admin examples:: admin examples
-@end menu
-
-@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
-@node admin options
-@appendixsubsec admin options
-
-Not all valid @code{rcs} options are useful together
-with @sc{cvs}. Some even makes it impossible to use
-@sc{cvs} until you undo the effect!
-
-This description of the available options is based on
-the @samp{rcs(1)} man page, but modified to suit
-readers that are more interrested in @sc{cvs} than
-@sc{rcs}.
-
-@table @code
-@item -A@var{oldfile}
-Might not work together with @sc{cvs}. Append the
-access list of @var{oldfile} to the access list of the
-@sc{rcs} file.
-
-@item -a@var{logins}
-Might not work together with @sc{cvs}. Append the
-login names appearing in the comma-separated list
-@var{logins} to the access list of the @sc{rcs} file.
-
-@item -b[@var{rev}]
-Breaks @sc{cvs}. When used with bare @sc{rcs}, this
-option sets the default branch to @var{rev}.
-If @var{rev} is omitted, the default branch is reset to
-the (dynamically) highest branch on the trunk. Use
-sticky tags instead, as in @code{cvs co -r}.
-@xref{Sticky tags}.
-
-@item -c@var{string}
-Useful with @sc{cvs}. Sets the comment leader to
-@var{string}. The comment leader is printed before
-every log message line generated by the keyword
-@code{$@asis{}Log$} (@pxref{Keyword substitution}).
-This is useful for programming languages without
-multi-line comments. @sc{Rcs} initially guesses the
-value of the comment leader from the file name
-extension when the file is first committed.
-
-@item -e[@var{logins}]
-Might not work together with @sc{cvs}. Erase the login
-names appearing in the comma-separated list
-@var{logins} from the access list of the RCS file. If
-@var{logins} is omitted, erase the entire access list.
-
-@item -I
-Run interactively, even if the standard input is not a
-terminal.
-
-@item -i
-Useless with @sc{cvs}. When using bare @sc{rcs}, this
-is used to create and initialize a new @sc{rcs} file,
-without depositing a revision.
-
-@item -k@var{subst}
-Useful with @sc{cvs}. Set the default keyword
-substitution to @var{subst}. @xref{Keyword
-substitution}. Giving an explicit @samp{-k} option to
-@code{cvs update} or @code{cvs checkout} overrides this
-default. @code{cvs export} always uses @code{-kv},
-regardless of which keyword substitution is set with
-@code{cvs admin}.
-
-@item -l[@var{rev}]
-Probably useless with @sc{cvs}. With bare @sc{rcs},
-this option can be used to lock the revision with
-number @var{rev}. If a branch is given, lock the
-latest revision on that branch. If @var{rev} is
-omitted, lock the latest revision on the default
-branch.
-
-@item -L
-Probably useless with @sc{cvs}. Used with bare
-@sc{rcs} to set locking to strict. Strict
-locking means that the owner of an RCS file is not
-exempt from locking for checkin.
-
-@cindex Changing a log message
-@cindex Replacing a log message
-@cindex Correcting a log message
-@cindex Fixing a log message
-@cindex Log message, correcting
-@item -m@var{rev}:@var{msg}
-Replace the log message of revision @var{rev} with
-@var{msg}.
-
-@item -N@var{name}[:[@var{rev}]]
-Act like @samp{-n}, except override any previous
-assignment of @var{name}.
-
-@item -n@var{name}[:[@var{rev}]]
-Associate the symbolic name @var{name} with the branch
-or revision @var{rev}. It is normally better to use
-@samp{cvs tag} or @samp{cvs rtag} instead. Delete the
-symbolic name if both @samp{:} and @var{rev} are
-omitted; otherwise, print an error message if
-@var{name} is already associated with another number.
-If @var{rev} is symbolic, it is expanded before
-association. A @var{rev} consisting of a branch number
-followed by a @samp{.} stands for the current latest
-revision in the branch. A @samp{:} with an empty
-@var{rev} stands for the current latest revision on the
-default branch, normally the trunk. For example,
-@samp{rcs -n@var{name}: RCS/*} associates @var{name} with the
-current latest revision of all the named RCS files;
-this contrasts with @samp{rcs -n@var{name}:$ RCS/*} which
-associates @var{name} with the revision numbers
-extracted from keyword strings in the corresponding
-working files.
-
-@cindex Deleting revisions
-@cindex Outdating revisions
-@cindex Saving space
-@item -o@var{range}
-Potentially useful, but dangerous, with @sc{cvs} (see below).
-Deletes (@dfn{outdates}) the revisions given by
-@var{range}. A range consisting of a single revision
-number means that revision. A range consisting of a
-branch number means the latest revision on that branch.
-A range of the form @samp{@var{rev1}:@var{rev2}} means
-revisions @var{rev1} to @var{rev2} on the same branch,
-@samp{:@var{rev}} means from the beginning of the
-branch containing @var{rev} up to and including
-@var{rev}, and @samp{@var{rev}:} means from revision
-@var{rev} to the end of the branch containing
-@var{rev}. None of the outdated revisions may have
-branches or locks.
-
-Due to the way @sc{cvs} handles branches @var{rev}
-cannot be specified symbolically if it is a branch.
-@xref{Magic branch numbers}, for an explanation.
-
-Make sure that no-one has checked out a copy of the
-revision you outdate. Strange things will happen if he
-starts to edit it and tries to check it back in. For
-this reason, this option is not a good way to take back
-a bogus commit; commit a new revision undoing the bogus
-change instead (@pxref{Merging two revisions}).
-
-@item -q
-Run quietly; do not print diagnostics.
-
-@item -s@var{state}[:@var{rev}]
-Useful with @sc{cvs}. Set the state attribute of the
-revision @var{rev} to @var{state}. If @var{rev} is a
-branch number, assume the latest revision on that
-branch. If @var{rev} is omitted, assume the latest
-revision on the default branch. Any identifier is
-acceptable for @var{state}. A useful set of states is
-@samp{Exp} (for experimental), @samp{Stab} (for
-stable), and @samp{Rel} (for released). By default,
-the state of a new revision is set to @samp{Exp} when
-it is created. The state is visible in the output from
-@var{cvs log} (@pxref{log}), and in the
-@samp{$@asis{}Log$} and @samp{$@asis{}State$} keywords
-(@pxref{Keyword substitution}).
-
-@item -t[@var{file}]
-Useful with @sc{cvs}. Write descriptive text from the
-contents of the named @var{file} into the RCS file,
-deleting the existing text. The @var{file} pathname
-may not begin with @samp{-}. If @var{file} is omitted,
-obtain the text from standard input, terminated by
-end-of-file or by a line containing @samp{.} by itself.
-Prompt for the text if interaction is possible; see
-@samp{-I}. The descriptive text can be seen in the
-output from @samp{cvs log} (@pxref{log}).
-
-@item -t-@var{string}
-Similar to @samp{-t@var{file}}. Write descriptive text
-from the @var{string} into the @sc{rcs} file, deleting
-the existing text.
-
-@item -U
-Probably useless with @sc{cvs}. Used with bare
-@sc{rcs} to set locking to non-strict. Non-strict
-locking means that the owner of a file need not lock a
-revision for checkin.
-
-@item -u[@var{rev}]
-Probably useless with @sc{cvs}. With bare @sc{rcs},
-unlock the revision with number @var{rev}. If a branch
-is given, unlock the latest revision on that branch.
-If @var{rev} is omitted, remove the latest lock held by
-the caller. Normally, only the locker of a revision
-may unlock it. Somebody else unlocking a revision
-breaks the lock. This causes a mail message to be sent
-to the original locker. The message contains a
-commentary solicited from the breaker. The commentary
-is terminated by end-of-file or by a line containing
-@code{.} by itself.
-
-@item -V@var{n}
-Emulate @sc{rcs} version @var{n}. Use -V@var{n} to make
-an @sc{rcs} file acceptable to @sc{rcs} version @var{n}
-by discarding information that would confuse version
-@var{n}.
-
-@item -x@var{suffixes}
-Useless with @sc{cvs}. Use @var{suffixes} to
-characterize RCS files.
-@end table
-
-
-@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
-@node admin examples
-@appendixsubsec admin examples
-
-@appendixsubsubsec Outdating is dangerous
-
-First, an example of how @emph{not} to use the
-@code{admin} command. It is included to stress the
-fact that this command can be quite dangerous unless
-you know @emph{exactly} what you are doing.
-
-The @samp{-o} option can be used to @dfn{outdate} old revisions
-from the history file. If you are short on disc this option
-might help you. But think twice before using it---there is no
-way short of restoring the latest backup to undo this command!
-
-The next line is an example of a command that you would
-@emph{not} like to execute.
-
-@example
-$ cvs admin -o:R_1_02 .
-@end example
-
-The above command will delete all revisions up to, and
-including, the revision that corresponds to the tag
-R_1_02. But beware! If there are files that have not
-changed between R_1_02 and R_1_03 the file will have
-@emph{the same} numerical revision number assigned to
-the tags R_1_02 and R_1_03. So not only will it be
-impossible to retrieve R_1_02; R_1_03 will also have to
-be restored from the tapes!
-
-@need 1200
-@appendixsubsubsec Handling binary files
-@cindex Binary files (inhibit keyword expansion)
-@cindex Inhibiting keyword expansion
-@cindex Keyword expansion, inhibiting
-
-If you use @sc{cvs} to store binary files, where
-keyword strings (@pxref{Keyword substitution}) might
-accidentally appear inside the file, you should use
-@code{cvs admin -ko} to make sure that they are not
-modified automatically. Here is an example of how you
-can create a new file using the @samp{-ko} flag:
-
-@example
-$ echo '$@asis{}Id$' > kotest
-$ cvs add -m"A test file" kotest
-$ cvs ci -m"First checkin; contains a keyword" kotest
-$ cvs admin -ko kotest
-$ rm kotest
-$ cvs update kotest
-@end example
-
-When you check in the file @file{kotest} the keywords
-are expanded. (Try the above example, and do a
-@code{cat kotest} after every command!) The @code{cvs
-admin -ko} command sets the default keyword
-substitution method for this file, but it does not
-alter the working copy of the file that you have. The
-easiest way to get the unexpanded version of
-@file{kotest} is to remove it and check it out again.
-
-@appendixsubsubsec Comment leaders
-@cindex Comment leader
-@cindex Log keyword, selecting comment leader
-@cindex Nroff (selecting comment leader)
-
-If you use the @code{$@asis{}Log$} keyword and you do
-not agree with the guess for comment leader that
-@sc{cvs} has done, you can enforce your will with
-@code{cvs admin -c}. This might be suitable for
-@code{nroff} source:
-
-@example
-$ cvs admin -c'.\" ' *.man
-$ rm *.man
-$ cvs update
-@end example
-
-The two last steps are to make sure that you get the
-versions with correct comment leaders in your working
-files.
-
-@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-@node checkout
-@appendixsec checkout---Check out sources for editing
-@cindex Checkout (subcommand)
-@cindex Co (subcommand)
-
-@itemize @bullet
-@item
-Synopsis: checkout [options] modules@dots{}
-@item
-Requires: repository.
-@item
-Changes: working directory.
-@item
-Synonyms: co, get
-@end itemize
-
-Make a working directory containing copies of the
-source files specified by @var{modules}. You must execute
-@code{checkout} before using most of the other @sc{cvs}
-commands, since most of them operate on your working
-directory.
-
-The @var{modules} part of the command are either
-symbolic names for some
-collection of source directories and files, or paths to
-directories or files in the repository. The symbolic
-names are defined in the @samp{modules} file.
-@xref{modules}.
-
-Depending on the modules you specify, @code{checkout} may
-recursively create directories and populate them with
-the appropriate source files. You can then edit these
-source files at any time (regardless of whether other
-software developers are editing their own copies of the
-sources); update them to include new changes applied by
-others to the source repository; or commit your work as
-a permanent change to the source repository.
-
-Note that @code{checkout} is used to create
-directories. The top-level directory created is always
-added to the directory where @code{checkout} is
-invoked, and usually has the same name as the specified
-module. In the case of a module alias, the created
-sub-directory may have a different name, but you can be
-sure that it will be a sub-directory, and that
-@code{checkout} will show the relative path leading to
-each file as it is extracted into your private work
-area (unless you specify the @samp{-Q} global option).
-
-Running @code{checkout} on a directory that was already
-built by a prior @code{checkout} is also permitted, and
-has the same effect as specifying the @samp{-d} option
-to the @code{update} command, that is, any new
-directories that have been created in the repository
-will appear in your work area. @xref{update}.
-
-@menu
-* checkout options:: checkout options
-* checkout examples:: checkout examples
-@end menu
-
-@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
-@node checkout options
-@appendixsubsec checkout options
-
-These standard options are supported by @code{checkout}
-(@pxref{Common options}, for a complete description of
-them):
-
-@table @code
-@item -D @var{date}
-Use the most recent revision no later than @var{date}.
-This option is sticky, and implies @samp{-P}.
-
-@item -f
-Only useful with the @samp{-D @var{date}} or @samp{-r
-@var{tag}} flags. If no matching revision is found,
-retrieve the most recent revision (instead of ignoring
-the file).
-
-@item -k @var{kflag}
-Process @sc{rcs} keywords according to @var{kflag}. See
-co(1). This option is sticky; future updates of
-this file in this working directory will use the same
-@var{kflag}. The @code{status} command can be viewed
-to see the sticky options. @xref{status}.
-
-@item -l
-Local; run only in current working directory.
-
-@item -n
-Do not run any checkout program (as specified
-with the @samp{-o} option in the modules file;
-@pxref{modules}).
-
-@item -P
-Prune empty directories.
-
-@item -p
-Pipe files to the standard output.
-
-@item -r @var{tag}
-Use revision @var{tag}. This option is sticky, and implies @samp{-P}.
-@end table
-
-In addition to those, you can use these special command
-options with @code{checkout}:
-
-@table @code
-@item -A
-Reset any sticky tags, dates, or @samp{-k} options.
-(If you get a working file using one of the @samp{-r},
-@samp{-D}, or @samp{-k} options, @sc{cvs} remembers the
-corresponding tag, date, or @var{kflag} and continues using
-it for future updates; use the @samp{-A} option to make
-@sc{cvs} forget these specifications, and retrieve the
-`head' revision of the file).
-
-@item -c
-Copy the module file, sorted, to the standard output,
-instead of creating or modifying any files or
-directories in your working directory.
-
-@item -d @var{dir}
-Create a directory called @var{dir} for the working
-files, instead of using the module name. Unless you
-also use @samp{-N}, the paths created under @var{dir}
-will be as short as possible.
-
-@item -j @var{tag}
-With two @samp{-j} options, merge changes from the
-revision specified with the first @samp{-j} option to
-the revision specified with the second @samp{j} option,
-into the working directory.
-
-With one @samp{-j} option, merge changes from the
-ancestor revision to the revision specified with the
-@samp{-j} option, into the working directory. The
-ancestor revision is the common ancestor of the
-revision which the working directory is based on, and
-the revision specified in the @samp{-j} option.
-
-In addition, each -j option can contain an optional
-date specification which, when used with branches, can
-limit the chosen revision to one within a specific
-date. An optional date is specified by adding a colon
-(:) to the tag:
-@samp{-j@var{Symbolic_Tag}:@var{Date_Specifier}}.
-
-@xref{Merging}.
-
-@item -N
-Only useful together with @samp{-d @var{dir}}. With this
-option, @sc{cvs} will not shorten module paths in your
-working directory. (Normally, @sc{cvs} shortens paths as
-much as possible when you specify an explicit target
-directory).
-
-@item -s
-Like @samp{-c}, but include the status of all modules,
-and sort it by the status string. @xref{modules}, for
-info about the @samp{-s} option that is used inside the
-modules file to set the module status.
-@end table
-
-@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
-@node checkout examples
-@appendixsubsec checkout examples
-
-Get a copy of the module @samp{tc}:
-
-@example
-$ cvs checkout tc
-@end example
-
-Get a copy of the module @samp{tc} as it looked one day
-ago:
-
-@example
-$ cvs checkout -D yesterday tc
-@end example
-
-@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-@node commit
-@appendixsec commit---Check files into the repository
-@cindex Commit (subcommand)
-
-@itemize @bullet
-@item
-Version 1.3 Synopsis: commit [-lnR] [-m 'log_message' |
--f file] [-r revision] [files@dots{}]
-@item
-Version 1.3.1 Synopsis: commit [-lnRf] [-m 'log_message' |
--F file] [-r revision] [files@dots{}]
-@c -- rename-f-F--
-@item
-Requires: working directory, repository.
-@item
-Changes: repository.
-@item
-Synonym: ci
-@end itemize
-
-@strong{Warning:} The @samp{-f @var{file}} option will
-probably be renamed to @samp{-F @var{file}}, and @samp{-f}
-will be given a new behavior in future releases of @sc{cvs}.
-@c -- rename-f-F--
-
-Use @code{commit} when you want to incorporate changes
-from your working source files into the source
-repository.
-
-If you don't specify particular files to commit, all of
-the files in your working current directory are
-examined. @code{commit} is careful to change in the
-repository only those files that you have really
-changed. By default (or if you explicitly specify the
-@samp{-R} option), files in subdirectories are also
-examined and committed if they have changed; you can
-use the @samp{-l} option to limit @code{commit} to the
-current directory only.
-
-@code{commit} verifies that the selected files are up
-to date with the current revisions in the source
-repository; it will notify you, and exit without
-committing, if any of the specified files must be made
-current first with @code{update} (@pxref{update}).
-@code{commit} does not call the @code{update} command
-for you, but rather leaves that for you to do when the
-time is right.
-
-When all is well, an editor is invoked to allow you to
-enter a log message that will be written to one or more
-logging programs (@pxref{modules}, and @pxref{loginfo})
-and placed in the @sc{rcs} history file inside the
-repository. This log message can be retrieved with the
-@code{log} command; @xref{log}. You can specify the
-log message on the command line with the @samp{-m
-@var{message}} option, and thus avoid the editor invocation,
-or use the @samp{-f @var{file}} option to specify
-@c -- rename-f-F--
-that the argument file contains the log message.
-
-@menu
-* commit options:: commit options
-* commit examples:: commit examples
-@end menu
-
-@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
-@node commit options
-@appendixsubsec commit options
-
-These standard options are supported by @code{commit}
-(@pxref{Common options}, for a complete description of
-them):
-
-@table @code
-@item -l
-Local; run only in current working directory.
-
-@item -n
-Do not run any module program.
-
-@item -R
-Commit directories recursively. This is on by default.
-
-@item -r @var{revision}
-Commit to @var{revision}. @var{revision} must be
-either a branch, or a revision on the main trunk that
-is higher than any existing revision number. You
-cannot commit to a specific revision on a branch.
-@end table
-
-@code{commit} also supports these options:
-
-@table @code
-@item -F @var{file}
-This option is present in @sc{cvs} releases 1.3-s3 and
-later. Read the log message from @var{file}, instead
-of invoking an editor.
-
-@item -f
-@c -- rename-f-F--
-This option is present in @sc{cvs} 1.3-s3 and later releases
-of @sc{cvs}. Note that this is not the standard behavior of
-the @samp{-f} option as defined in @xref{Common options}.
-
-Force @sc{cvs} to commit a new revision even if you haven't
-made any changes to the file. If the current revision
-of @var{file} is 1.7, then the following two commands
-are equivalent:
-
-@example
-$ cvs commit -f @var{file}
-$ cvs commit -r 1.8 @var{file}
-@end example
-
-@item -f @var{file}
-@c -- rename-f-F--
-This option is present in @sc{cvs} releases 1.3, 1.3-s1 and
-1.3-s2. Note that this is not the standard behavior of
-the @samp{-f} option as defined in @xref{Common options}.
-
-Read the log message from @var{file}, instead
-of invoking an editor.
-
-@item -m @var{message}
-Use @var{message} as the log message, instead of
-invoking an editor.
-@end table
-
-@need 2000
-@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
-@node commit examples
-@appendixsubsec commit examples
-
-@appendixsubsubsec New major release number
-
-When you make a major release of your product, you
-might want the revision numbers to track your major
-release number. You should normally not care about
-the revision numbers, but this is a thing that many
-people want to do, and it can be done without doing any
-harm.
-
-To bring all your files up to the @sc{rcs} revision 3.0
-(including those that haven't changed), you might do:
-
-@example
-$ cvs commit -r 3.0
-@end example
-
-Note that it is generally a bad idea to try to make the
-@sc{rcs} revision number equal to the current release number
-of your product. You should think of the revision
-number as an internal number that the @sc{cvs} package
-maintains, and that you generally never need to care
-much about. Using the @code{tag} and @code{rtag}
-commands you can give symbolic names to the releases
-instead. @xref{tag} and @xref{rtag}.
-
-Note that the number you specify with @samp{-r} must be
-larger than any existing revision number. That is, if
-revision 3.0 exists, you cannot @samp{cvs commit
--r 1.3}.
-
-@appendixsubsubsec Committing to a branch
-
-You can commit to a branch revision (one that has an
-even number of dots) with the @samp{-r} option. To
-create a branch revision, use the @samp{-b} option
-of the @code{rtag} or @code{tag} commands (@pxref{tag}
-or @pxref{rtag}). Then, either @code{checkout} or
-@code{update} can be used to base your sources on the
-newly created branch. From that point on, all
-@code{commit} changes made within these working sources
-will be automatically added to a branch revision,
-thereby not disturbing main-line development in any
-way. For example, if you had to create a patch to the
-1.2 version of the product, even though the 2.0 version
-is already under development, you might do:
-
-@example
-$ cvs rtag -b -r FCS1_2 FCS1_2_Patch product_module
-$ cvs checkout -r FCS1_2_Patch product_module
-$ cd product_module
-[[ hack away ]]
-$ cvs commit
-@end example
-
-@noindent
-This works automatically since the @samp{-r} option is
-sticky.
-
-@appendixsubsubsec Creating the branch after editing
-
-Say you have been working on some extremely
-experimental software, based on whatever revision you
-happened to checkout last week. If others in your
-group would like to work on this software with you, but
-without disturbing main-line development, you could
-commit your change to a new branch. Others can then
-checkout your experimental stuff and utilize the full
-benefit of @sc{cvs} conflict resolution. The scenario might
-look like:
-
-@example
-[[ hacked sources are present ]]
-$ cvs tag -b EXPR1
-$ cvs update -r EXPR1
-$ cvs commit
-@end example
-
-The @code{update} command will make the @samp{-r
-EXPR1} option sticky on all files. Note that your
-changes to the files will never be removed by the
-@code{update} command. The @code{commit} will
-automatically commit to the correct branch, because the
-@samp{-r} is sticky. You could also do like this:
-
-@example
-[[ hacked sources are present ]]
-$ cvs tag -b EXPR1
-$ cvs commit -r EXPR1
-@end example
-
-@noindent
-but then, only those files that were changed by you
-will have the @samp{-r EXPR1} sticky flag. If you hack
-away, and commit without specifying the @samp{-r EXPR1}
-flag, some files may accidentally end up on the main
-trunk.
-
-To work with you on the experimental change, others
-would simply do
-
-@example
-$ cvs checkout -r EXPR1 whatever_module
-@end example
-
-@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-@node diff
-@appendixsec diff---Run diffs between revisions
-@cindex Diff (subcommand)
-
-@itemize @bullet
-@item
-Synopsis: diff [-l] [rcsdiff_options] [[-r rev1 | -D date1] [-r rev2 | -D date2]] [files@dots{}]
-@item
-Requires: working directory, repository.
-@item
-Changes: nothing.
-@end itemize
-
-The @code{diff} command is used to compare different
-revisions of files. The default action is to compare
-your working files with the revisions they were based
-on, and report any differences that are found.
-
-If any file names are given, only those files are
-compared. If any directories are given, all files
-under them will be compared.
-
-The exit status will be 0 if no differences were found,
-1 if some differences were found, and 2 if any error
-occurred.
-
-@menu
-* diff options:: diff options
-* diff examples:: diff examples
-@end menu
-
-@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
-@node diff options
-@appendixsubsec diff options
-
-These standard options are supported by @code{diff}
-(@pxref{Common options}, for a complete description of
-them):
-
-@table @code
-@item -D @var{date}
-Use the most recent revision no later than @var{date}.
-See @samp{-r} for how this affects the comparison.
-
-@sc{cvs} can be configured to pass the @samp{-D} option
-through to @code{rcsdiff} (which in turn passes it on
-to @code{diff}. @sc{Gnu} diff uses @samp{-D} as a way to
-put @code{cpp}-style @samp{#define} statements around the output
-differences. There is no way short of testing to
-figure out how @sc{cvs} was configured. In the default
-configuration @sc{cvs} will use the @samp{-D @var{date}} option.
-
-@item -k @var{kflag}
-Process @sc{rcs} keywords according to @var{kflag}. See
-co(1).
-
-@item -l
-Local; run only in current working directory.
-
-@item -R
-Examine directories recursively. This option is on by
-default.
-
-@item -r @var{tag}
-Compare with revision @var{tag}. Zero, one or two
-@samp{-r} options can be present. With no @samp{-r}
-option, the working file will be compared with the
-revision it was based on. With one @samp{-r}, that
-revision will be compared to your current working file.
-With two @samp{-r} options those two revisions will be
-compared (and your working file will not affect the
-outcome in any way).
-
-One or both @samp{-r} options can be replaced by a
-@samp{-D @var{date}} option, described above.
-@end table
-
-Any other options that are found are passed through to
-@code{rcsdiff}, which in turn passes them to
-@code{diff}. The exact meaning of the options depends
-on which @code{diff} you are using. The long options
-introduced in @sc{gnu} diff 2.0 are not yet supported in
-@sc{cvs}. See the documentation for your @code{diff} to see
-which options are supported.
-
-@c -- Document some common useful diff options, such as
-@c -u and -c.
-@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
-@node diff examples
-@appendixsubsec diff examples
-
-The following line produces a Unidiff (@samp{-u} flag)
-between revision 1.14 and 1.19 of
-@file{backend.c}. Due to the @samp{-kk} flag no
-keywords are substituted, so differences that only depend
-on keyword substitution are ignored.
-
-@example
-$ cvs diff -kk -u -r 1.14 -r 1.19 backend.c
-@end example
-
-Suppose the experimental branch EXPR1 was based on a
-set of files tagged RELEASE_1_0. To see what has
-happened on that branch, the following can be used:
-
-@example
-$ cvs diff -r RELEASE_1_0 -r EXPR1
-@end example
-
-A command like this can be used to produce a context
-diff between two releases:
-
-@example
-$ cvs diff -c -r RELEASE_1_0 -r RELEASE_1_1 > diffs
-@end example
-
-If you are maintaining ChangeLogs, a command like the following
-just before you commit your changes may help you write
-the ChangeLog entry. All local modifications that have
-not yet been committed will be printed.
-
-@example
-$ cvs diff -u | less
-@end example
-
-@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-@node export
-@appendixsec export---Export sources from CVS, similar to checkout
-@cindex Export (subcommand)
-
-@itemize @bullet
-@item
-Synopsis: export [-flNn] -r rev|-D date [-d dir] module@dots{}
-@item
-Requires: repository.
-@item
-Changes: current directory.
-@end itemize
-
-This command is a variant of @code{checkout}; use it
-when you want a copy of the source for module without
-the @sc{cvs} administrative directories. For example, you
-might use @code{export} to prepare source for shipment
-off-site. This command requires that you specify a
-date or tag (with @samp{-D} or @samp{-r}), so that you
-can count on reproducing the source you ship to others.
-
-The keyword substitution option @samp{-kv} is always set when
-export is used. This causes any @sc{rcs} keywords to be
-expanded such that an import done at some other site
-will not lose the keyword revision information. There
-is no way to override this. Note that this breaks the
-@code{ident} command (which is part of the @sc{rcs}
-suite---see ident(1)) which looks for @sc{rcs} keyword
-strings. If you want to be able to use @code{ident}
-you must use @code{checkout} instead.
-
-@menu
-* export options:: export options
-@end menu
-
-@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
-@node export options
-@appendixsubsec export options
-
-These standard options are supported by @code{export}
-(@pxref{Common options}, for a complete description of
-them):
-
-@table @code
-@item -D @var{date}
-Use the most recent revision no later than @var{date}.
-
-@item -f
-If no matching revision is found, retrieve the most
-recent revision (instead of ignoring the file).
-
-@item -l
-Local; run only in current working directory.
-
-@item -n
-Do not run any checkout program.
-
-@item -R
-Export directories recursively. This is on by default.
-
-@item -r @var{tag}
-Use revision @var{tag}.
-@end table
-
-In addition, these options (that are common to
-@code{checkout} and @code{export}) are also supported:
-
-@table @code
-@item -d @var{dir}
-Create a directory called @var{dir} for the working
-files, instead of using the module name. Unless you
-also use @samp{-N}, the paths created under @var{dir}
-will be as short as possible.
-
-@item -N
-Only useful together with @samp{-d @var{dir}}. With this
-option, @sc{cvs} will not shorten module paths in your
-working directory. (Normally, @sc{cvs} shortens paths as
-much as possible when you specify an explicit target
-directory.)
-@end table
-
-@ignore
-@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
-@c @node export examples
-@appendixsubsec export examples
-
-Contributed examples are gratefully accepted.
-@c -- Examples here!!
-@end ignore
-
-@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-@node history
-@appendixsec history---Show status of files and users
-@cindex History (subcommand)
-
-@itemize @bullet
-@item
-Synopsis: history [-report] [-flags] [-options args] [files@dots{}]
-@item
-Requires: the file @file{$CVSROOT/CVSROOT/history}
-@item
-Changes: nothing.
-@end itemize
-
-@sc{cvs} can keep a history file that tracks each use of the
-@code{checkout}, @code{commit}, @code{rtag},
-@code{update}, and @code{release} commands. You can
-use @code{history} to display this information in
-various formats.
-
-Logging must be enabled by creating the file
-@file{$CVSROOT/CVSROOT/history}.
-
-@strong{Warning:} @code{history} uses @samp{-f}, @samp{-l},
-@samp{-n}, and @samp{-p} in ways that conflict with the
-normal use inside @sc{cvs} (@pxref{Common options}).
-
-@menu
-* history options:: history options
-@end menu
-
-@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
-@node history options
-@appendixsubsec history options
-
-Several options (shown above as @samp{-report}) control what
-kind of report is generated:
-
-@table @code
-@item -c
-Report on each time commit was used (i.e., each time
-the repository was modified).
-
-@item -e
-Everything (all record types); equivalent to specifying
-@samp{-xMACFROGWUT}.
-
-@item -m @var{module}
-Report on a particular module. (You can meaningfully
-use @samp{-m} more than once on the command line.)
-
-@item -o
-Report on checked-out modules.
-
-@item -T
-Report on all tags.
-
-@item -x @var{type}
-Extract a particular set of record types @var{type} from the @sc{cvs}
-history. The types are indicated by single letters,
-which you may specify in combination.
-
-Certain commands have a single record type:
-
-@table @code
-@item F
-release
-@item O
-checkout
-@item T
-rtag
-@end table
-
-@noindent
-One of four record types may result from an update:
-
-@table @code
-@item C
-A merge was necessary but collisions were
-detected (requiring manual merging).
-@item G
-A merge was necessary and it succeeded.
-@item U
-A working file was copied from the repository.
-@item W
-The working copy of a file was deleted during
-update (because it was gone from the repository).
-@end table
-
-@noindent
-One of three record types results from commit:
-
-@table @code
-@item A
-A file was added for the first time.
-@item M
-A file was modified.
-@item R
-A file was removed.
-@end table
-@end table
-
-The options shown as @samp{-flags} constrain or expand
-the report without requiring option arguments:
-
-@table @code
-@item -a
-Show data for all users (the default is to show data
-only for the user executing @code{history}).
-
-@item -l
-Show last modification only.
-
-@item -w
-Show only the records for modifications done from the
-same working directory where @code{history} is
-executing.
-@end table
-
-The options shown as @samp{-options @var{args}} constrain the report
-based on an argument:
-
-@table @code
-@item -b @var{str}
-Show data back to a record containing the string
-@var{str} in either the module name, the file name, or
-the repository path.
-
-@item -D @var{date}
-Show data since @var{date}. This is slightly different
-from the normal use of @samp{-D @var{date}}, which
-selects the newest revision older than @var{date}.
-
-@item -p @var{repository}
-Show data for a particular source repository (you
-can specify several @samp{-p} options on the same command
-line).
-
-@item -r @var{rev}
-Show records referring to revisions since the revision
-or tag named @var{rev} appears in individual @sc{rcs}
-files. Each @sc{rcs} file is searched for the revision or
-tag.
-
-@item -t @var{tag}
-Show records since tag @var{tag} was last added to the the
-history file. This differs from the @samp{-r} flag
-above in that it reads only the history file, not the
-@sc{rcs} files, and is much faster.
-
-@item -u @var{name}
-Show records for user @var{name}.
-@end table
-
-@ignore
-@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
-@c @node history examples
-@appendixsubsec history examples
-
-Contributed examples will gratefully be accepted.
-@c -- Examples here!
-@end ignore
-
-@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-@node import
-@appendixsec import---Import sources into CVS, using vendor branches
-@cindex Import (subcommand)
-
-@itemize @bullet
-@item
-Synopsis: import [-options] repository vendortag releasetag@dots{}
-@item
-Requires: Repository, source distribution directory.
-@item
-Changes: repository.
-@end itemize
-
-Use @code{import} to incorporate an entire source
-distribution from an outside source (e.g., a source
-vendor) into your source repository directory. You can
-use this command both for initial creation of a
-repository, and for wholesale updates to the module
-from the outside source. @xref{Tracking sources}, for
-a discussion on this subject.
-
-The @var{repository} argument gives a directory name
-(or a path to a directory) under the @sc{cvs} root directory
-for repositories; if the directory did not exist,
-import creates it.
-
-When you use import for updates to source that has been
-modified in your source repository (since a prior
-import), it will notify you of any files that conflict
-in the two branches of development; use @samp{checkout
--j} to reconcile the differences, as import instructs
-you to do.
-
-By default, certain file names are ignored during
-@code{import}: names associated with @sc{cvs}
-administration, or with other common source control
-systems; common names for patch files, object files,
-archive files, and editor backup files; and other names
-that are usually artifacts of assorted utilities.
-Currently, the default list of ignored files includes
-files matching these names:
-
-@example
- RCSLOG RCS SCCS
- CVS* cvslog.*
- tags TAGS
- .make.state .nse_depinfo
- *~ #* .#* ,*
- *.old *.bak *.BAK *.orig *.rej .del-*
- *.a *.o *.so *.Z *.elc *.ln
- core
-@end example
-
-If the file @file{$CVSROOT/CVSROOT/cvsignore} exists,
-any files whose names match the specifications in that
-file will also be ignored.
-
-If the file @file{$CVSROOT/CVSROOT/cvswrappers} exists,
-any file whose names match the specifications in that
-file will be treated as packages and the appropriate
-filtering will be performed on the file/directory
-before being imported, @xref{Wrappers}.
-
-The outside source is saved in a first-level @sc{rcs}
-branch, by default 1.1.1. Updates are leaves of this
-branch; for example, files from the first imported
-collection of source will be revision 1.1.1.1, then
-files from the first imported update will be revision
-1.1.1.2, and so on.
-
-At least three arguments are required.
-@var{repository} is needed to identify the collection
-of source. @var{vendortag} is a tag for the entire
-branch (e.g., for 1.1.1). You must also specify at
-least one @var{releasetag} to identify the files at
-the leaves created each time you execute @code{import}.
-
-@menu
-* import options:: import options
-* import examples:: import examples
-@end menu
-
-@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
-@node import options
-@appendixsubsec import options
-
-This standard option is supported by @code{import}
-(@pxref{Common options}, for a complete description):
-
-@table @code
-@item -m @var{message}
-Use @var{message} as log information, instead of
-invoking an editor.
-@end table
-
-There are three additional special options.
-
-@table @code
-@item -b @var{branch}
-Specify a first-level branch other than 1.1.1. Unless
-the @samp{-b @var{branch}} flag is given, revisions will
-@emph{always} be made to the branch 1.1.1---even if a
-@var{vendortag} that matches another branch is given!
-What happens in that case, is that the tag will be
-reset to 1.1.1. Warning: This behavior might change
-in the future.
-
-@item -k @var{subst}
-Indicate the RCS keyword expansion mode desired. This setting will
-apply to all files created during the import, but not to any files that
-previously existed in the repository. See co(1) for a complete list of
-valid @samp{-k} settings.
-
-If you are checking in sources that contain @sc{rcs} keywords, and you
-wish those keywords to remain intact, use the @samp{-ko} flag when
-importing the files. This setting indicates that no keyword expansion
-is to be performed by @sc{rcs} when checking files out. It is also
-useful for checking in binaries.
-
-@item -I @var{name}
-Specify file names that should be ignored during
-import. You can use this option repeatedly. To avoid
-ignoring any files at all (even those ignored by
-default), specify `-I !'.
-
-@var{name} can be a file name pattern of the same type
-that you can specify in the @file{.cvsignore} file.
-@xref{cvsignore}.
-@c -- Is this really true?
-
-@item -W @var{spec}
-Specify file names that should be filtered during
-import. You can use this option repeatedly.
-
-@var{spec} can be a file name pattern of the same type
-that you can specify in the @file{.cvswrappers}
-file. @xref{Wrappers}.
-@end table
-
-@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
-@node import examples
-@appendixsubsec import examples
-
-@xref{Tracking sources}, and @xref{From files}.
-
-@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-@node log
-@appendixsec log---Print out 'rlog' information for files
-@cindex Log (subcommand)
-
-@itemize @bullet
-@item
-Synopsis: log [-l] rlog-options [files@dots{}]
-@item
-Requires: repository, working directory.
-@item
-Changes: nothing.
-@item
-Synonym: rlog
-@end itemize
-
-Display log information for files. @code{log} calls
-the @sc{rcs} utility @code{rlog}, which prints all available
-information about the @sc{rcs} history file. This includes
-the location of the @sc{rcs} file, the @dfn{head} revision
-(the latest revision on the trunk), all symbolic names (tags)
-and some other things. For each revision, the revision
-number, the author, the number of lines added/deleted and
-the log message are printed. All times are displayed in
-Coordinated Universal Time (UTC). (Other parts of @sc{cvs}
-print times in the local timezone).
-@c -- timezone--
-
-@menu
-* log options:: log options
-* log examples:: log examples
-@end menu
-
-@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
-@node log options
-@appendixsubsec log options
-
-Only one option is interpreted by @sc{cvs} and not passed on to @code{rlog}:
-
-@table @code
-@item -l
-Local; run only in current working directory. (Default
-is to run recursively).
-@end table
-
-By default, @code{rlog} prints all information that is
-available. All other options (including those that
-normally behave differently) are passed through to
-@code{rlog} and restrict the output. See rlog(1) for a
-complete description of options. This incomplete list
-(which is a slightly edited extract from rlog(1)) lists
-all options that are useful in conjunction with @sc{cvs}.
-
-@strong{Please note:} There can be no space between the option
-and its argument, since @code{rlog} parses its options
-in a different way than @sc{cvs}.
-
-@table @code
-@item -b
-Print information about the revisions on the default
-branch, normally the highest branch on the trunk.
-
-@item -d@var{dates}
-Print information about revisions with a checkin
-date/time in the range given by the
-semicolon-separated list of dates. The following table
-explains the available range formats:
-
-@table @code
-@item @var{d1}<@var{d2}
-@itemx @var{d2}>@var{d1}
-Select the revisions that were deposited between
-@var{d1} and @var{d2} inclusive.
-
-@item <@var{d}
-@itemx @var{d}>
-Select all revisions dated @var{d} or earlier.
-
-@item @var{d}<
-@itemx >@var{d}
-Select all revisions dated @var{d} or later.
-
-@item @var{d}
-Select the single, latest revision dated @var{d} or
-earlier.
-@end table
-
-The date/time strings @var{d}, @var{d1}, and @var{d2}
-are in the free format explained in co(1). Quoting is
-normally necessary, especially for < and >. Note that
-the separator is a semicolon (;).
-
-@item -h
-Print only the @sc{rcs} pathname, working pathname, head,
-default branch, access list, locks, symbolic names, and
-suffix.
-
-@item -N
-Do not print the list of tags for this file. This
-option can be very useful when your site uses a lot of
-tags, so rather than "more"'ing over 3 pages of tag
-information, the log information is presented without
-tags at all.
-
-@item -R
-Print only the name of the @sc{rcs} history file.
-
-@item -r@var{revisions}
-Print information about revisions given in the
-comma-separated list @var{revisions} of revisions and
-ranges. The following table explains the available
-range formats:
-
-@table @code
-@item @var{rev1}:@var{rev2}
-Revisions @var{rev1} to @var{rev2} (which must be on
-the same branch).
-
-@item :@var{rev}
-Revisions from the beginning of the branch up to
-and including @var{rev}.
-
-@item @var{rev}:
-Revisions starting with @var{rev} to the end of the
-branch containing @var{rev}.
-
-@item @var{branch}
-An argument that is a branch means all revisions on
-that branch. You can unfortunately not specify a
-symbolic branch here. You must specify the numeric
-branch number. @xref{Magic branch numbers}, for an
-explanation.
-
-@item @var{branch1}:@var{branch2}
-A range of branches means all revisions
-on the branches in that range.
-
-@item @var{branch}.
-The latest revision in @var{branch}.
-@end table
-
-A bare @samp{-r} with no revisions means the latest
-revision on the default branch, normally the trunk.
-
-@item -s@var{states}
-Print information about revisions whose state
-attributes match one of the states given in the
-comma-separated list @var{states}.
-
-@item -t
-Print the same as @samp{-h}, plus the descriptive text.
-
-@item -w@var{logins}
-Print information about revisions checked in by users
-with login names appearing in the comma-separated list
-@var{logins}. If @var{logins} is omitted, the user's
-login is assumed.
-@end table
-
-@code{rlog} prints the intersection of the revisions
-selected with the options @samp{-d}, @samp{-l},
-@samp{-s}, and @samp{-w}, intersected with the union of
-the revisions selected by @samp{-b} and @samp{-r}.
-
-@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
-@node log examples
-@appendixsubsec log examples
-
-Contributed examples are gratefully accepted.
-
-@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-@node rdiff
-@appendixsec rdiff---'patch' format diffs between releases
-@cindex Rdiff (subcommand)
-
-@itemize @bullet
-@item
-rdiff [-flags] [-V vn] [-r t|-D d [-r t2|-D d2]] modules@dots{}
-@item
-Requires: repository.
-@item
-Changes: nothing.
-@item
-Synonym: patch
-@end itemize
-
-Builds a Larry Wall format patch(1) file between two
-releases, that can be fed directly into the patch
-program to bring an old release up-to-date with the new
-release. (This is one of the few @sc{cvs} commands that
-operates directly from the repository, and doesn't
-require a prior checkout.) The diff output is sent to
-the standard output device.
-
-You can specify (using the standard @samp{-r} and
-@samp{-D} options) any combination of one or two
-revisions or dates. If only one revision or date is
-specified, the patch file reflects differences between
-that revision or date and the current head revisions in
-the @sc{rcs} file.
-
-Note that if the software release affected is contained
-in more than one directory, then it may be necessary to
-specify the @samp{-p} option to the patch command when
-patching the old sources, so that patch is able to find
-the files that are located in other directories.
-
-@menu
-* rdiff options:: rdiff options
-* rdiff examples:: rdiff examples
-@end menu
-
-@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
-@node rdiff options
-@appendixsubsec rdiff options
-
-These standard options are supported by @code{rdiff}
-(@pxref{Common options}, for a complete description of
-them):
-
-@table @code
-@item -D @var{date}
-Use the most recent revision no later than @var{date}.
-
-@item -f
-If no matching revision is found, retrieve the most
-recent revision (instead of ignoring the file).
-
-@item -l
-Local; don't descend subdirectories.
-
-@item -r @var{tag}
-Use revision @var{tag}.
-@end table
-
-In addition to the above, these options are available:
-
-@table @code
-@item -c
-Use the context diff format. This is the default format.
-
-@item -s
-Create a summary change report instead of a patch. The
-summary includes information about files that were
-changed or added between the releases. It is sent to
-the standard output device. This is useful for finding
-out, for example, which files have changed between two
-dates or revisions.
-
-@item -t
-A diff of the top two revisions is sent to the standard
-output device. This is most useful for seeing what the
-last change to a file was.
-
-@item -u
-Use the unidiff format for the context diffs.
-This option is not available if your diff does not
-support the unidiff format. Remember that old versions
-of the @code{patch} program can't handle the unidiff
-format, so if you plan to post this patch to the net
-you should probably not use @samp{-u}.
-
-@item -V @var{vn}
-Expand @sc{rcs} keywords according to the rules current in
-@sc{rcs} version @var{vn} (the expansion format changed with
-@sc{rcs} version 5).
-@end table
-
-@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
-@node rdiff examples
-@appendixsubsec rdiff examples
-
-Suppose you receive mail from @t{foo@@bar.com} asking for an
-update from release 1.2 to 1.4 of the tc compiler. You
-have no such patches on hand, but with @sc{cvs} that can
-easily be fixed with a command such as this:
-
-@example
-$ cvs rdiff -c -r FOO1_2 -r FOO1_4 tc | \
-$$ Mail -s 'The patches you asked for' foo@@bar.com
-@end example
-
-Suppose you have made release 1.3, and forked a branch
-called @samp{R_1_3fix} for bugfixes. @samp{R_1_3_1}
-corresponds to release 1.3.1, which was made some time
-ago. Now, you want to see how much development has been
-done on the branch. This command can be used:
-
-@example
-$ cvs patch -s -r R_1_3_1 -r R_1_3fix module-name
-cvs rdiff: Diffing module-name
-File ChangeLog,v changed from revision 1.52.2.5 to 1.52.2.6
-File foo.c,v changed from revision 1.52.2.3 to 1.52.2.4
-File bar.h,v changed from revision 1.29.2.1 to 1.2
-@end example
-
-@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-@node release
-@appendixsec release---Indicate that a Module is no longer in use
-@cindex Release (subcommand)
-
-@itemize @bullet
-@item
-release [-d] modules@dots{}
-@item
-Requires: Working directory.
-@item
-Changes: Working directory, history log.
-@end itemize
-
-This command is meant to safely cancel the effect of
-@samp{cvs checkout}. Since @sc{cvs} doesn't lock files, it
-isn't strictly necessary to use this command. You can
-always simply delete your working directory, if you
-like; but you risk losing changes you may have
-forgotten, and you leave no trace in the @sc{cvs} history
-file (@pxref{history file}) that you've abandoned your
-checkout.
-
-Use @samp{cvs release} to avoid these problems. This
-command checks that no uncommitted changes are
-present; that you are executing it from immediately
-above a @sc{cvs} working directory; and that the repository
-recorded for your files is the same as the repository
-defined in the module database.
-
-If all these conditions are true, @samp{cvs release}
-leaves a record of its execution (attesting to your
-intentionally abandoning your checkout) in the @sc{cvs}
-history log.
-
-@menu
-* release options:: release options
-* release output:: release options
-* release examples:: release examples
-@end menu
-
-@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
-@node release options
-@appendixsubsec release options
-
-The @code{release} command supports one command option:
-
-@table @code
-@item -d
-Delete your working copy of the file if the release
-succeeds. If this flag is not given your files will
-remain in your working directory.
-
-@strong{Warning:} The @code{release} command uses
-@samp{rm -r @file{module}} to delete your file. This
-has the very serious side-effect that any directory
-that you have created inside your checked-out sources,
-and not added to the repository (using the @code{add}
-command; @pxref{add}) will be silently deleted---even
-if it is non-empty!
-@end table
-
-@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
-@node release output
-@appendixsubsec release output
-
-Before @code{release} releases your sources it will
-print a one-line message for any file that is not
-up-to-date.
-
-@strong{Warning:} Any new directories that you have
-created, but not added to the @sc{cvs} directory hierarchy
-with the @code{add} command (@pxref{add}) will be
-silently ignored (and deleted, if @samp{-d} is
-specified), even if they contain files.
-
-@table @code
-@item U @var{file}
-There exists a newer revision of this file in the
-repository, and you have not modified your local copy
-of the file.
-
-@item A @var{file}
-The file has been added to your private copy of the
-sources, but has not yet been committed to the
-repository. If you delete your copy of the sources
-this file will be lost.
-
-@item R @var{file}
-The file has been removed from your private copy of the
-sources, but has not yet been removed from the
-repository, since you have not yet committed the
-removal. @xref{commit}.
-
-@item M @var{file}
-The file is modified in your working directory. There
-might also be a newer revision inside the repository.
-
-@item ? @var{file}
-@var{file} is in your working directory, but does not
-correspond to anything in the source repository, and is
-not in the list of files for @sc{cvs} to ignore (see the
-description of the @samp{-I} option, and
-@pxref{cvsignore}). If you remove your working
-sources, this file will be lost.
-
-Note that no warning message like this is printed for
-spurious directories that @sc{cvs} encounters. The
-directory, and all its contents, are silently ignored.
-
-@c FIXME -- CVS should be fixed to print "? foo" for
-@c such spurious directories
-@end table
-
-@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
-@node release examples
-@appendixsubsec release examples
-
-Release the module, and delete your local working copy
-of the files.
-
-@example
-$ cd .. # @r{You must stand immediately above the}
- # @r{sources when you issue @samp{cvs release}.}
-$ cvs release -d tc
-You have [0] altered files in this repository.
-Are you sure you want to release (and delete) module `tc': y
-$
-@end example
-
-@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-@node remove
-@appendixsec remove---Remove an entry from the repository
-@cindex Remove (subcommand)
-
-@itemize @bullet
-@item
-remove [-lR] [files@dots{}]
-@item
-Requires: Working directory.
-@item
-Changes: Working directory.
-@item
-Synonyms: rm, delete
-@end itemize
-
-Use this command to declare that you wish to remove
-files from the source repository. Like most @sc{cvs}
-commands, @samp{cvs remove} works on files in your working
-directory, not directly on the repository. As a
-safeguard, it also requires that you first erase the
-specified files from your working directory.
-
-The files are not actually removed until you apply your
-changes to the repository with @code{commit}; at that
-point, the corresponding @sc{rcs} files in the source
-repository are moved into the @file{Attic} directory
-(also within the source repository).
-
-This command is recursive by default, scheduling all
-physically removed files that it finds for removal by
-the next commit. Use the @samp{-l} option to avoid
-this recursion, or just specify the actual files that
-you wish removed.
-
-
-@menu
-* remove options:: remove options
-* remove examples:: remove examples
-@end menu
-
-@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
-@node remove options
-@appendixsubsec remove options
-
-Two of the standard options are the only options
-supported by @code{remove}.
-
-@table @code
-@item -l
-Local; run only in current working directory.
-
-@item -R
-Commit directories recursively. This is on by default.
-@end table
-
-@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
-@node remove examples
-@appendixsubsec remove examples
-
-@appendixsubsubsec Remove a couple of files.
-
-@example
-$ cd test
-$ rm ?.c
-$ cvs remove
-cvs remove: Removing .
-cvs remove: scheduling a.c for removal
-cvs remove: scheduling b.c for removal
-cvs remove: use 'cvs commit' to remove these files permanently
-$ cvs ci -m "Removed unneeded files"
-cvs commit: Examining .
-cvs commit: Committing .
-@end example
-
-@appendixsubsubsec Resurrecting removed files
-
-If you change your mind you can easily resurrect the
-file before you commit it, using the @code{add}
-command.
-
-@example
-$ ls
-CVS ja.h oj.c
-$ rm oj.c
-$ cvs remove oj.c
-cvs remove: scheduling oj.c for removal
-cvs remove: use 'cvs commit' to remove this file permanently
-$ cvs add oj.c
-U oj.c
-cvs add: oj.c, version 1.1.1.1, resurrected
-@end example
-
-If you realize your mistake before you run the
-@code{remove} command you can use @code{update} to
-resurrect the file:
-
-@example
-$ rm oj.c
-$ cvs update oj.c
-cvs update: warning: oj.c was lost
-U oj.c
-@end example
-
-@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-@node rtag
-@appendixsec rtag---Add a tag to the RCS file
-@cindex Rtag (subcommand)
-
-@itemize @bullet
-@item
-rtag [-falnR] [-b] [-d] [-r tag | -Ddate] symbolic_tag modules@dots{}
-@item
-Requires: repository.
-@item
-Changes: repository.
-@item
-Synonym: rfreeze
-@end itemize
-
-You can use this command to assign symbolic tags to
-particular, explicitly specified source revisions in
-the repository. @code{rtag} works directly on the
-repository contents (and requires no prior checkout).
-Use @code{tag} instead (@pxref{tag}), to base the
-selection of revisions on the contents of your
-working directory.
-
-If you attempt to use a tag name that already exists,
-@sc{cvs} will complain and not overwrite that tag. Use
-the @samp{-F} option to force the new tag value.
-
-@menu
-* rtag options:: rtag options
-@end menu
-
-@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
-@node rtag options
-@appendixsubsec rtag options
-
-These standard options are supported by @code{rtag}
-(@pxref{Common options}, for a complete description of
-them):
-
-@table @code
-@item -D @var{date}
-Tag the most recent revision no later than @var{date}.
-
-@item -f
-Only useful with the @samp{-D @var{date}} or @samp{-r @var{tag}}
-flags. If no matching revision is found, use the most
-recent revision (instead of ignoring the file).
-
-@item -F
-Overwrite an existing tag of the same name on a
-different revision. This option is new in @sc{cvs}
-1.4. The old behavior is matched by @samp{cvs tag -F}.
-
-@item -l
-Local; run only in current working directory.
-
-@item -n
-Do not run any tag program that was specified with the
-@samp{-t} flag inside the @file{modules} file.
-(@pxref{modules}).
-
-@item -R
-Commit directories recursively. This is on by default.
-
-@item -r @var{tag}
-Only tag those files that contain @var{tag}. This can
-be used to rename a tag: tag only the files identified
-by the old tag, then delete the old tag, leaving the
-new tag on exactly the same files as the old tag.
-@end table
-
-In addition to the above common options, these options
-are available:
-
-@table @code
-@item -a
-Use the @samp{-a} option to have @code{rtag} look in the
-@file{Attic} (@pxref{Removing files}) for removed files
-that contain the specified tag. The tag is removed from
-these files, which makes it convenient to re-use a
-symbolic tag as development continues (and files get
-removed from the up-coming distribution).
-
-@item -b
-Make the tag a branch tag. @xref{Branches}.
-
-@item -d
-Delete the tag instead of creating it.
-
-In general, tags (often the symbolic names of software
-distributions) should not be removed, but the @samp{-d}
-option is available as a means to remove completely
-obsolete symbolic names if necessary (as might be the
-case for an Alpha release, or if you mistagged a
-module).
-@end table
-
-@ignore
-@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
-@c @node rtag examples
-@appendixsubsec rtag examples
-
-@c -- Examples here!
-@end ignore
-
-@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-@node status
-@appendixsec status---Status info on the revisions
-@cindex Status (subcommand)
-
-@itemize @bullet
-@item
-status [-lR] [-v] [files@dots{}]
-@item
-Requires: working directory, repository.
-@item
-Changes: nothing.
-@end itemize
-
-Display a brief report on the current status of files
-with respect to the source repository, including any
-sticky tags, dates, or @samp{-k} options.
-
-You can also use this command to determine the
-potential impact of a @samp{cvs update} on your working
-source directory---but remember that things might
-change in the repository before you run @code{update}.
-
-@menu
-* status options:: status options
-@end menu
-
-@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
-@node status options
-@appendixsubsec status options
-
-These standard options are supported by @code{status}
-(@pxref{Common options}, for a complete description of
-them):
-
-@table @code
-@item -l
-Local; run only in current working directory.
-
-@item -R
-Commit directories recursively. This is on by default.
-@end table
-
-There is one additional option:
-
-@table @code
-@item -v
-Verbose. In addition to the information normally
-displayed, print all symbolic tags, together with the
-numerical value of the revision or branch they refer
-to.
-@end table
-
-@ignore
-@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
-@c @node status examples
-@appendixsubsec status examples
-
-@c -- FIXME
-@end ignore
-
-@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-@node tag
-@appendixsec tag---Add a symbolic tag to checked out version of RCS file
-@c -- //////// - unnecessary. Also
-@c -- in a lot of other
-@c -- places.
-@cindex Tag (subcommand)
-
-@itemize @bullet
-@item
-tag [-lR] [-b] [-d] symbolic_tag [files@dots{}]
-@item
-Requires: working directory, repository.
-@item
-Changes: repository.
-@item
-Synonym: freeze
-@end itemize
-
-Use this command to assign symbolic tags to the nearest
-repository versions to your working sources. The tags
-are applied immediately to the repository, as with
-@code{rtag}, but the versions are supplied implicitly by the
-@sc{cvs} records of your working files' history rather than
-applied explicitly.
-
-One use for tags is to record a snapshot of the
-current sources when the software freeze date of a
-project arrives. As bugs are fixed after the freeze
-date, only those changed sources that are to be part of
-the release need be re-tagged.
-
-The symbolic tags are meant to permanently record which
-revisions of which files were used in creating a
-software distribution. The @code{checkout} and
-@code{update} commands allow you to extract an exact
-copy of a tagged release at any time in the future,
-regardless of whether files have been changed, added,
-or removed since the release was tagged.
-
-This command can also be used to delete a symbolic tag,
-or to create a branch. See the options section below.
-
-If you attempt to use a tag name that already exists,
-@sc{cvs} will complain and not overwrite that tag. Use
-the @samp{-F} option to force the new tag value.
-
-
-@menu
-* tag options:: tag options
-@end menu
-
-@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
-@node tag options
-@appendixsubsec tag options
-
-These standard options are supported by @code{tag}
-(@pxref{Common options}, for a complete description of
-them):
-
-@table @code
-@item -F
-Overwrite an existing tag of the same name on a
-different revision. This option is new in @sc{cvs}
-1.4. The old behavior is matched by @samp{cvs tag -F}.
-
-@item -l
-Local; run only in current working directory.
-
-@item -R
-Commit directories recursively. This is on by default.
-@end table
-
-Two special options are available:
-
-@table @code
-@item -b
-The -b option makes the tag a branch tag
-(@pxref{Branches}), allowing concurrent, isolated
-development. This is most useful for creating a patch
-to a previously released software distribution.
-
-@item -d
-Delete a tag.
-
-If you use @samp{cvs tag -d symbolic_tag}, the symbolic
-tag you specify is deleted instead of being added.
-Warning: Be very certain of your ground before you
-delete a tag; doing this permanently discards some
-historical information, which may later turn out to
-be valuable.
-@end table
-
-@ignore
-@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
-@c @node tag examples
-@appendixsubsec tag examples
-
-@c -- FIXME
-@end ignore
-
-@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-@node update
-@appendixsec update---Bring work tree in sync with repository
-@cindex Update (subcommand)
-
-@itemize @bullet
-@item
-update [-AdflPpR] [-d] [-r tag|-D date] files@dots{}
-@item
-Requires: repository, working directory.
-@item
-Changes: working directory.
-@end itemize
-
-After you've run checkout to create your private copy
-of source from the common repository, other developers
-will continue changing the central source. From time
-to time, when it is convenient in your development
-process, you can use the @code{update} command from
-within your working directory to reconcile your work
-with any revisions applied to the source repository
-since your last checkout or update.
-
-@menu
-* update options:: update options
-* update output:: update output
-* update examples:: update examples
-@end menu
-
-@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
-@node update options
-@appendixsubsec update options
-
-These standard options are available with @code{update}
-(@pxref{Common options}, for a complete description of
-them):
-
-@table @code
-@item -D date
-Use the most recent revision no later than @var{date}.
-This option is sticky, and implies @samp{-P}.
-
-@item -f
-Only useful with the @samp{-D @var{date}} or @samp{-r
-@var{tag}} flags. If no matching revision is found,
-retrieve the most recent revision (instead of ignoring
-the file).
-
-@item -k @var{kflag}
-Process @sc{rcs} keywords according to @var{kflag}. See
-co(1). This option is sticky; future updates of
-this file in this working directory will use the same
-@var{kflag}. The @code{status} command can be viewed
-to see the sticky options. @xref{status}.
-
-@item -l
-Local; run only in current working directory. @xref{Recursive behavior}.
-
-@item -P
-Prune empty directories.
-
-@item -p
-Pipe files to the standard output.
-
-@item -R
-Operate recursively. This is on by default.
-@xref{Recursive behavior}.
-
-@item -r tag
-Retrieve revision @var{tag}. This option is sticky,
-and implies @samp{-P}.
-@end table
-
-@need 800
-These special options are also available with
-@code{update}.
-
-@table @code
-@item -A
-Reset any sticky tags, dates, or @samp{-k} options.
-(If you get a working copy of a file by using one of
-the @samp{-r}, @samp{-D}, or @samp{-k} options, @sc{cvs}
-remembers the corresponding tag, date, or @var{kflag} and
-continues using it on future updates; use the @samp{-A}
-option to make @sc{cvs} forget these specifications, and
-retrieve the head revision of the file).
-
-@item -d
-Create any directories that exist in the repository if
-they're missing from the working directory. Normally,
-@code{update} acts only on directories and files that
-were already enrolled in your working directory.
-
-This is useful for updating directories that were
-created in the repository since the initial checkout;
-but it has an unfortunate side effect. If you
-deliberately avoided certain directories in the
-repository when you created your working directory
-(either through use of a module name or by listing
-explicitly the files and directories you wanted on the
-command line), then updating with @samp{-d} will create
-those directories, which may not be what you want.
-
-@item -I @var{name}
-Ignore files whose names match @var{name} (in your
-working directory) during the update. You can specify
-@samp{-I} more than once on the command line to specify
-several files to ignore. By default, @code{update}
-ignores files whose names match any of the following:
-
-@example
- RCSLOG RCS SCCS
- CVS* cvslog.*
- tags TAGS
- .make.state .nse_depinfo
- *~ #* .#* ,*
- *.old *.bak *.BAK *.orig *.rej .del-*
- *.a *.o *.so *.Z *.elc *.ln
- core
-@end example
-
-Use @samp{-I !} to avoid ignoring any files at all.
-@xref{cvsignore}, for other ways to make @sc{cvs} ignore
-some files.
-
-@item -W@var{spec}
-Specify file names that should be filtered during
-update. You can use this option repeatedly.
-
-@var{spec} can be a file name pattern of the same type
-that you can specify in the @file{.cvswrappers}
-file. @xref{Wrappers}.
-
-@item -j@var{revision}
-With two @samp{-j} options, merge changes from the
-revision specified with the first @samp{-j} option to
-the revision specified with the second @samp{j} option,
-into the working directory.
-
-With one @samp{-j} option, merge changes from the
-ancestor revision to the revision specified with the
-@samp{-j} option, into the working directory. The
-ancestor revision is the common ancestor of the
-revision which the working directory is based on, and
-the revision specified in the @samp{-j} option.
-
-In addition, each -j option can contain an optional
-date specification which, when used with branches, can
-limit the chosen revision to one within a specific
-date. An optional date is specified by adding a colon
-(:) to the tag:
-@samp{-j@var{Symbolic_Tag}:@var{Date_Specifier}}.
-
-@xref{Merging}.
-
-@end table
-
-@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
-@node update output
-@appendixsubsec update output
-
-@code{update} keeps you informed of its progress by
-printing a line for each file, preceded by one
-character indicating the status of the file:
-
-@table @code
-@item U @var{file}
-The file was brought up to date with respect to the
-repository. This is done for any file that exists in
-the repository but not in your source, and for files
-that you haven't changed but are not the most recent
-versions available in the repository.
-
-@item A @var{file}
-The file has been added to your private copy of the
-sources, and will be added to the source repository
-when you run @code{commit} on the file. This is a
-reminder to you that the file needs to be committed.
-
-@item R @var{file}
-The file has been removed from your private copy of the
-sources, and will be removed from the source repository
-when you run @code{commit} on the file. This is a
-reminder to you that the file needs to be committed.
-
-@item M @var{file}
-The file is modified in your working directory.
-
-@samp{M} can indicate one of two states for a file
-you're working on: either there were no modifications
-to the same file in the repository, so that your file
-remains as you last saw it; or there were modifications
-in the repository as well as in your copy, but they
-were merged successfully, without conflict, in your
-working directory.
-
-@sc{cvs} will print some messages if it merges your work,
-and a backup copy of your working file (as it looked
-before you ran @code{update}) will be made. The exact
-name of that file is printed while @code{update} runs.
-
-@item C @var{file}
-A conflict was detected while trying to merge your
-changes to @var{file} with changes from the source
-repository. @var{file} (the copy in your working
-directory) is now the output of the rcsmerge(1) command
-on the two revisions; an unmodified copy of your file
-is also in your working directory, with the name
-@file{.#@var{file}.@var{revision}} where @var{revision}
-is the @sc{rcs} revision that your modified file started
-from. (Note that some systems automatically purge
-files that begin with @file{.#} if they have not been
-accessed for a few days. If you intend to keep a copy
-of your original file, it is a very good idea to rename
-it.)
-
-@item ? @var{file}
-@var{file} is in your working directory, but does not
-correspond to anything in the source repository, and is
-not in the list of files for @sc{cvs} to ignore (see the
-description of the @samp{-I} option, and
-@pxref{cvsignore}).
-
-Note that no warning message like this is printed for
-spurious directories that @sc{cvs} encounters. The
-directory, and all its contents, are silently ignored.
-@end table
-
-@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
-@node update examples
-@appendixsubsec update examples
-
-The following line will display all files which are not
-up-to-date without actually change anything in your
-working directory. It can be used to check what has
-been going on with the project.
-
-@example
-$ cvs -n -q update
-@end example
-
-@c ---------------------------------------------------------------------
-@node Administrative files
-@appendix Reference manual for the Administrative files
-@cindex Administrative files (reference)
-@cindex Files, reference manual
-@cindex Reference manual (files)
-@cindex CVSROOT (file)
-
-Inside the repository, in the directory
-@file{$CVSROOT/CVSROOT}, there are a number of
-supportive files for @sc{cvs}. You can use @sc{cvs} in a limited
-fashion without any of them, but if they are set up
-properly they can help make life easier.
-
-The most important of these files is the @file{modules}
-file, which defines the modules inside the repository.
-
-@menu
-* modules:: Defining modules
-* Wrappers:: Treat directories as files
-* commit files:: The commit support files
-* commitinfo:: Pre-commit checking
-* editinfo:: Specifying how log messages are created
-* loginfo:: Where should log messages be sent?
-* rcsinfo:: Templates for the log messages
-* cvsignore:: Ignoring files via cvsignore
-* history file:: History information
-* Setting up:: Setting up the repository
-@end menu
-
-@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-@node modules
-@appendixsec The modules file
-@cindex Modules (admin file)
-@cindex Defining modules (reference manual)
-
-The @file{modules} file records your definitions of
-names for collections of source code. @sc{cvs} will use
-these definitions if you create a file with the right
-format in @file{$CVSROOT/CVSROOT/modules,v}. The
-mkmodules(1) command should be run whenever the modules
-file changes, so that the appropriate files can be
-generated (depending on how you have configured @sc{cvs}
-operation).
-
-To allow convenient editing of the @file{modules} file
-itself, the file should include an entry like the
-following (where @var{localbin} represents the
-directory where your site installs programs like
-mkmodules(1)):
-
-@example
-modules -i /@var{localbin}/mkmodules CVSROOT modules
-@end example
-
-@noindent
-This defines the name @samp{modules} as the module name
-for the file itself, so that you can use
-
-@example
-$ cvs checkout modules
-@end example
-
-@noindent
-to get a copy of the file that you can edit. You should define
-similar module entries for the other configuration
-files described in this appendix, except
-@file{history}).
-
-The @file{modules} file may contain blank lines and
-comments (lines beginning with @samp{#}) as well as
-module definitions. Long lines can be continued on the
-next line by specifying a backslash (@samp{\}) as the
-last character on the line.
-
-A module definition is a single line of the
-@file{modules} file, in either of two formats. In both
-cases, @var{mname} represents the symbolic module name,
-and the remainder of the line is its definition.
-
-@table @code
-@item @var{mname} -a @var{aliases}@dots{}
-This represents the simplest way of defining a module
-@var{mname}. The @samp{-a} flags the definition as a
-simple alias: @sc{cvs} will treat any use of @var{mname} (as
-a command argument) as if the list of names
-@var{aliases} had been specified instead.
-@var{aliases} may contain either other module names or
-paths. When you use paths in aliases, @code{checkout}
-creates all intermediate directories in the working
-directory, just as if the path had been specified
-explicitly in the @sc{cvs} arguments.
-
-@item @var{mname} [ options ] @var{dir} [ @var{files}@dots{} ] [ &@var{module}@dots{} ]
-In the simplest case, this form of module definition
-reduces to @samp{@var{mname} @var{dir}}. This defines
-all the files in directory @var{dir} as module mname.
-@var{dir} is a relative path (from @code{$CVSROOT}) to a
-directory of source in the source repository. In this
-case, on checkout, a single directory called
-@var{mname} is created as a working directory; no
-intermediate directory levels are used by default, even
-if @var{dir} was a path involving several directory
-levels.
-
-By explicitly specifying files in the module definition
-after @var{dir}, you can select particular files from
-directory @var{dir}. The sample definition for
-@samp{modules} is an example of a module defined with a
-single file from a particular directory. Here is
-another example:
-
-@example
-m4test unsupported/gnu/m4 foreach.m4 forloop.m4
-@end example
-
-@noindent
-With this definition, executing @samp{cvs checkout
-m4test} will create a single working directory
-@file{m4test} containing the two files listed, which
-both come from a common directory several levels deep
-in the @sc{cvs} source repository.
-
-A module definition can refer to other modules by
-including @samp{&@var{module}} in its definition.
-@code{checkout} creates a subdirectory for each such
-module, in your working directory.
-@c -- Nope. "in your working directory" is wrong. What
-@c -- is right?
-
-@table @code
-@item -d @var{name}
-Name the working directory something other than the
-module name.
-
-@cindex Export program
-@item -e @var{prog}
-Specify a program @var{prog} to run whenever files in a
-module are exported. @var{prog} runs with a single
-argument, the module name.
-
-@cindex Checkin program
-@item -i @var{prog}
-Specify a program @var{prog} to run whenever files in a
-module are committed. @var{prog} runs with a single
-argument, the full pathname of the affected directory
-in a source repository. The @file{commitinfo},
-@file{loginfo}, and @file{editinfo} files provide other
-ways to call a program on commit.
-
-@cindex Checkout program
-@item -o @var{prog}
-Specify a program @var{prog} to run whenever files in a
-module are checked out. @var{prog} runs with a single
-argument, the module name.
-
-@cindex Status of a module
-@cindex Module status
-@item -s @var{status}
-Assign a status to the module. When the module file is
-printed with @samp{cvs checkout -s} the modules are
-sorted according to primarily module status, and
-secondarily according to the module name. This option
-has no other meaning. You can use this option for
-several things besides status: for instance, list the
-person that is responsible for this module.
-
-@cindex Tag program
-@item -t @var{prog}
-Specify a program @var{prog} to run whenever files in a
-module are tagged with @code{rtag}. @var{prog} runs
-with two arguments: the module name and the symbolic
-tag specified to @code{rtag}. There is no way to
-specify a program to run when @code{tag} is executed.
-
-@cindex Update program
-@item -u @var{prog}
-Specify a program @var{prog} to run whenever @samp{cvs
-update} is executed from the top-level directory of the
-checked-out module. @var{prog} runs with a single
-argument, the full path to the source repository for
-this module.
-@end table
-@end table
-
-@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-@node Wrappers
-@appendixsec The cvswrappers file
-@cindex cvswrappers (admin file)
-@cindex CVSWRAPPERS, environment variable
-@cindex Wrappers
-
-Wrappers are essentially
-directories that are to be treated as "files." This
-package allows such wrappers to be "processed" on the
-way in and out of CVS. The intended use is to wrap up
-a wrapper into a single tar, such that that tar can be
-treated as a single binary file in CVS. Apparently
-this is particularly useful on NEXTSTEP. To solve
-the problem effectively, it was also necessary to be
-able to prevent rcsmerge application at appropriate
-times.
-
-The file @file{cvswrappers} defines the script that will be
-run on a file when its name matches a regular
-expresion. There are two scripts that can be run on a
-file or directory.
-@c FIXME: Is this talking about comb and uncom? If so,
-@c mention them by name
-A script to filter the directory/file before it gets
-checked in and another that is run when the
-file/directory gets checked out.
-
-The @file{cvswrappers} also specifies the merge
-methodology that should be used when the file is
-updated, that is should a MERGE or a straight COPY of
-the diferences be used when checking into the
-repository.
-
-The basic format of the file @file{cvswrappers} is given as
-such:
-
-@example
-wildcard [option value][option value]...
-
-where option is one of
--f from cvs filter value: path tofilter
--t to cvs filter value: path to filter
--m update methodology value: MERGE or COPY
-
-and value is a single-quote delimited value.
-@end example
-
-@example
-*.nib -f 'uncom %s' -t 'comb %s %s' -m 'COPY'
-*.rtfd -f 'uncom %s' -t 'comb %s %s' -m 'COPY'
-@end example
-
-@noindent
-The above example of a @file{cvswrappers} file
-states that all files/directories that end with a @code{.nib}
-should be filtered with the @file{comb} program before
-checking the file into the repository. The file should
-be filtered though the @file{uncom} program when the
-file is checked out of the repository. The
-@file{cvswrappers} file also states that a @code{COPY}
-methodology should be used when updating the files in
-the repository (that is no merging should be performed).
-
-@noindent
-The @file{comb} filter is called with two arguments,
-the first is the name of the file/directory to filter
-and the second is the pathname to where the resulting
-filtered file should be placed.
-
-@noindent
-The @file{uncom} filter is called with one argument,
-which is the name of the file to filter from. The end
-result of the @file{uncom} filter will be a
-file/directory in the users current working directory,
-that represents the source before being filtered.
-
-@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-@node commit files
-@appendixsec The commit support files
-@cindex Commit files
-
-The @samp{-i} flag in the @file{modules} file can be
-used to run a certain program whenever files are
-committed (@pxref{modules}). The files described in
-this section provide other, more flexible, ways to run
-programs whenever something is committed.
-
-There are three kind of programs that can be run on
-commit. They are specified in files in the repository,
-as described below. The following table summarizes the
-file names and the purpose of the corresponding
-programs.
-
-@table @file
-@item commitinfo
-The program is responsible for checking that the commit
-is allowed. If it exits with a non-zero exit status
-the commit will be aborted.
-
-@item editinfo
-The specified program is used to edit the log message,
-and possibly verify that it contains all required
-fields. This is most useful in combination with the
-@file{rcsinfo} file, which can hold a log message
-template (@pxref{rcsinfo}).
-
-@item loginfo
-The specified program is called when the commit is
-complete. It receives the log message and some
-additional information and can store the log message in
-a file, or mail it to appropriate persons, or maybe
-post it to a local newsgroup, or@dots{} Your
-imagination is the limit!
-@end table
-
-@menu
-* syntax:: The common syntax
-@end menu
-
-@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
-@node syntax
-@appendixsubsec The common syntax
-@cindex Info files (syntax)
-@cindex Syntax of info files
-@cindex Common syntax of info files
-
-The four files @file{commitinfo}, @file{loginfo},
-@file{rcsinfo} and @file{editinfo} all have a common
-format. The purpose of the files are described later
-on. The common syntax is described here.
-
-Each line contains the following:
-@itemize @bullet
-@item
-A regular expression
-
-@item
-A whitespace separator---one or more spaces and/or tabs.
-
-@item
-A file name or command-line template.
-@end itemize
-
-@noindent
-Blank lines are ignored. Lines that start with the
-character @samp{#} are treated as comments. Long lines
-unfortunately can @emph{not} be broken in two parts in
-any way.
-
-The first regular expression that matches the current
-directory name in the repository is used. The rest of the line
-is used as a file name or command-line as appropriate.
-
-@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-@node commitinfo
-@appendixsec Commitinfo
-@cindex Commitinfo
-@cindex Checking commits
-@cindex Precommit checking
-
-The @file{commitinfo} file defines programs to execute
-whenever @samp{cvs commit} is about to execute. These
-programs are used for pre-commit checking to verify
-that the modified, added and removed files are really
-ready to be committed. This could be used, for
-instance, to verify that the changed files conform to
-to your site's standards for coding practice.
-
-As mentioned earlier, each line in the
-@file{commitinfo} file consists of a regular expression
-and a command-line template. The template can include
-a program name and any number of arguments you wish to
-supply to it. The full path to the current source
-repository is appended to the template, followed by the
-file names of any files involved in the commit (added,
-removed, and modified files).
-
-The first line with a regular expression matching the
-relative path to the module will be used. If the
-command returns a non-zero exit status the commit will
-be aborted.
-
-@cindex DEFAULT in commitinfo
-If the repository name does not match any of the
-regular expressions in this file, the @samp{DEFAULT}
-line is used, if it is specified.
-
-@cindex ALL in commitinfo
-All occurances of the name @samp{ALL} appearing as a
-regular expression are used in addition to the first
-matching regular expression or the name @samp{DEFAULT}.
-
-Note: when @sc{CVS} is accessing a remote repository,
-@file{commitinfo} will be run on the @emph{remote}
-(i.e., server) side, not the client side (@pxref{Remote
-repositories}).
-
-@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-@node editinfo
-@appendixsec Editinfo
-@cindex Editinfo
-@cindex Editor, specifying per module
-@cindex Per-module editor
-@cindex Log messages, editing
-
-If you want to make sure that all log messages look the
-same way, you can use the @file{editinfo} file to
-specify a program that is used to edit the log message.
-This program could be a custom-made editor that always
-enforces a certain style of the log message, or maybe a
-simple shell script that calls an editor, and checks
-that the entered message contains the required fields.
-
-If no matching line is found in the @file{editinfo}
-file, the editor specified in the environment variable
-@code{$CVSEDITOR} is used instead. If that variable is
-not set, then the environment variable @code{$EDITOR}
-is used instead. If that variable is not
-set a precompiled default, normally @code{vi}, will be
-used.
-
-The @file{editinfo} file is often most useful together
-with the @file{rcsinfo} file, which can be used to
-specify a log message template.
-
-Each line in the @file{editinfo} file consists of a
-regular expression and a command-line template. The
-template must include a program name, and can include
-any number of arguments. The full path to the current
-log message template file is appended to the template.
-
-One thing that should be noted is that the @samp{ALL}
-keyword is not supported. If more than one matching
-line is found, the first one is used. This can be
-useful for specifying a default edit script in a
-module, and then overriding it in a subdirectory.
-
-@cindex DEFAULT in editinfo
-If the repository name does not match any of the
-regular expressions in this file, the @samp{DEFAULT}
-line is used, if it is specified.
-
-If the edit script exits with a non-zero exit status,
-the commit is aborted.
-
-Note: when @sc{CVS} is accessing a remote repository,
-@file{editinfo} will be run on the @emph{remote}
-(i.e., server) side, not the client side (@pxref{Remote
-repositories}).
-
-@menu
-* editinfo example:: Editinfo example
-@end menu
-
-@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
-@node editinfo example
-@appendixsubsec Editinfo example
-
-The following is a little silly example of a
-@file{editinfo} file, together with the corresponding
-@file{rcsinfo} file, the log message template and an
-editor script. We begin with the log message template.
-We want to always record a bug-id number on the first
-line of the log message. The rest of log message is
-free text. The following template is found in the file
-@file{/usr/cvssupport/tc.template}.
-
-@example
-BugId:
-@end example
-
-The script @file{/usr/cvssupport/bugid.edit} is used to
-edit the log message.
-
-@example
-#!/bin/sh
-#
-# bugid.edit filename
-#
-# Call $EDITOR on FILENAME, and verify that the
-# resulting file contains a valid bugid on the first
-# line.
-if [ "x$EDITOR" = "x" ]; then EDITOR=vi; fi
-if [ "x$CVSEDITOR" = "x" ]; then CVSEDITOR=$EDITOR; fi
-$CVSEDITOR $1
-until head -1|grep '^BugId:[ ]*[0-9][0-9]*$' < $1
-do echo -n "No BugId found. Edit again? ([y]/n)"
- read ans
- case $@{ans@} in
- n*) exit 1;;
- esac
- $CVSEDITOR $1
-done
-@end example
-
-The @file{editinfo} file contains this line:
-
-@example
-^tc /usr/cvssupport/bugid.edit
-@end example
-
-The @file{rcsinfo} file contains this line:
-
-@example
-^tc /usr/cvssupport/tc.template
-@end example
-
-@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-@node loginfo
-@appendixsec Loginfo
-@cindex Loginfo
-@cindex Storing log messages
-@cindex Mailing log messages
-@cindex Distributing log messages
-@cindex Log messages
-
-The @file{loginfo} file is used to control where
-@samp{cvs commit} log information is sent. The first
-entry on a line is a regular expression which is tested
-against the directory that the change is being made to,
-relative to the @code{$CVSROOT}. If a match is found, then
-the remainder of the line is a filter program that
-should expect log information on its standard input.
-
-The filter program may use one and only one % modifier
-(a la printf). If @samp{%s} is specified in the filter
-program, a brief title is included (enclosed in single
-quotes) showing the modified file names.
-
-If the repository name does not match any of the
-regular expressions in this file, the @samp{DEFAULT}
-line is used, if it is specified.
-
-All occurances of the name @samp{ALL} appearing as a
-regular expression are used in addition to the first
-matching regular expression or @samp{DEFAULT}.
-
-The first matching regular expression is used.
-
-@xref{commit files}, for a description of the syntax of
-the @file{loginfo} file.
-
-Note: when @sc{CVS} is accessing a remote repository,
-@file{loginfo} will be run on the @emph{remote}
-(i.e., server) side, not the client side (@pxref{Remote
-repositories}).
-
-@menu
-* loginfo example:: Loginfo example
-@end menu
-
-@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
-@node loginfo example
-@appendixsubsec Loginfo example
-
-The following @file{loginfo} file, together with the
-tiny shell-script below, appends all log messages
-to the file @file{$CVSROOT/CVSROOT/commitlog},
-and any commits to the administrative files (inside
-the @file{CVSROOT} directory) are also logged in
-@file{/usr/adm/cvsroot-log} and mailed to @t{ceder}.
-
-@example
-ALL /usr/local/bin/cvs-log $CVSROOT/CVSROOT/commitlog
-^CVSROOT Mail -s %s ceder
-^CVSROOT /usr/local/bin/cvs-log /usr/adm/cvsroot-log
-@end example
-
-The shell-script @file{/usr/local/bin/cvs-log} looks
-like this:
-
-@example
-#!/bin/sh
-(echo "-----------------------------------------------------------------";
- echo -n $USER" ";
- date;
- echo;
- sed '1s+'$@{CVSROOT@}'++') >> $1
-@end example
-
-@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-@node rcsinfo
-@appendixsec Rcsinfo
-@cindex Rcsinfo
-@cindex Form for log message
-@cindex Log message template
-@cindex Template for log message
-
-The @file{rcsinfo} file can be used to specify a form to
-edit when filling out the commit log. The
-@file{rcsinfo} file has a syntax similar to the
-@file{editinfo}, @file{commitinfo} and @file{loginfo}
-files. @xref{syntax}. Unlike the other files the second
-part is @emph{not} a command-line template. Instead,
-the part after the regular expression should be a full pathname to
-a file containing the log message template.
-
-If the repository name does not match any of the
-regular expressions in this file, the @samp{DEFAULT}
-line is used, if it is specified.
-
-All occurances of the name @samp{ALL} appearing as a
-regular expression are used in addition to the first
-matching regular expression or @samp{DEFAULT}.
-
-The log message template will be used as a default log
-message. If you specify a log message with @samp{cvs
-commit -m @var{message}} or @samp{cvs commit -f
-@var{file}} that log message will override the
-template.
-
-@xref{editinfo example}, for an example @file{rcsinfo}
-file.
-
-Note: when @sc{CVS} is accessing a remote repository,
-@file{rcsinfo} will be run on the @emph{remote}
-(i.e., server) side, not the client side (@pxref{Remote
-repositories}).
-
-@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-@node cvsignore
-@appendixsec Ignoring files via cvsignore
-@cindex Cvsignore, global
-@cindex Global cvsignore
-@cindex Ignoring files
-@c -- This chapter should maybe be moved to the
-@c tutorial part of the manual?
-
-There are certain file names that frequently occur
-inside your working copy, but that you don't want to
-put under @sc{cvs} control. Examples are all the object
-files that you get while you compile your sources.
-Normally, when you run @samp{cvs update}, it prints a
-line for each file it encounters that it doesn't know
-about (@pxref{update output}).
-
-@sc{cvs} has a list of files (or sh(1) file name patterns)
-that it should ignore while running @code{update},
-@code{import} and @code{release}.
-@c -- Are those the only three commands affected?
-This list is constructed in the following way.
-
-@itemize @bullet
-@item
-The list is initialized to the following file name
-patterns:
-
-@cindex Ignored files
-@cindex Automatically ignored files
-@example
- RCSLOG RCS SCCS
- CVS* cvslog.*
- tags TAGS
- .make.state .nse_depinfo
- *~ #* .#* ,*
- *.old *.bak *.BAK *.orig *.rej .del-*
- *.a *.o *.so *.Z *.elc *.ln
- core
-@end example
-
-@item
-The per-repository list in
-@file{$CVSROOT/CVSROOT/cvsignore} is appended to
-the list, if that file exists.
-
-@item
-The per-user list in @file{.cvsignore} in your home
-directory is appended to the list, if it exists.
-
-@item
-Any entries in the environment variable
-@code{$CVSIGNORE} is appended to the list.
-
-@item
-Any @samp{-I} options given to @sc{cvs} is appended.
-
-@item
-As @sc{cvs} traverses through your directories, the contents
-of any @file{.cvsignore} will be appended to the list.
-The patterns found in @file{.cvsignore} are only valid
-for the directory that contains them, not for
-any sub-directories.
-@end itemize
-
-In any of the 5 places listed above, a single
-exclamation mark (@samp{!}) clears the ignore list.
-This can be used if you want to store any file which
-normally is ignored by @sc{cvs}.
-
-@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-@node history file
-@appendixsec The history file
-@cindex History file
-@cindex Log information, saving
-
-The file @file{$CVSROOT/CVSROOT/history} is used
-to log information for the @code{history} command
-(@pxref{history}). This file must be created to turn
-on logging. This is done automatically if the
-@code{cvsinit} script is used to set up the repository.
-
-The file format of the @file{history} file is
-unfortunately not yet documented anywhere, but it is
-fairly easy to understand most of it.
-@c -- document it here?
-
-@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-@node Setting up
-@appendixsec Setting up the repository
-@cindex Repository, setting up
-@cindex Creating a repository
-@cindex Setting up a repository
-
-When you install @sc{cvs} for the first time, you should
-follow the instructions in the @file{INSTALL} file to
-set up the repository.
-
-If you want to set up another repository, the easiest
-way to get a reasonable set of working administrative
-files is to run the @code{cvsinit} shell script. It
-will set up an empty repository in the directory
-defined by the environment variable @code{$CVSROOT}.
-(@code{cvsinit} is careful to never overwrite any
-existing files in the repository, so no harm is done if
-you run @code{cvsinit} on an already set-up
-repository. In fact, running it on an already set-up
-repository is the best way to update the various
-scripts from the @samp{contrib} directory.)
-
-@c ---------------------------------------------------------------------
-@node Environment variables
-@appendix All environment variables which affect CVS
-@cindex Environment variables
-@cindex Reference manual for variables
-
-This is a complete list of all environment variables
-that affect @sc{cvs}.
-
-@table @code
-@cindex CVSIGNORE
-@item $CVSIGNORE
-A whitespace-separated list of file name patterns that
-@sc{cvs} should ignore. @xref{cvsignore}.
-
-@item $CVSWRAPPERS
-A whitespace-separated list of file name patterns that
-@sc{cvs} should treat as wrappers. @xref{Wrappers}.
-
-@cindex CVSREAD
-@item $CVSREAD
-If this is set, @code{checkout} and @code{update} will
-try hard to make the files in your working directory
-read-only. When this is not set, the default behavior
-is to permit modification of your working files.
-
-@cindex CVSROOT
-@item $CVSROOT
-Should contain the full pathname to the root of the @sc{cvs}
-source repository (where the @sc{rcs} history files are
-kept). This information must be available to @sc{cvs} for
-most commands to execute; if @code{$CVSROOT} is not set,
-or if you wish to override it for one invocation, you
-can supply it on the command line: @samp{cvs -d cvsroot
-cvs_command@dots{}} Once you have checked out a working
-directory, @sc{cvs} stores the appropriate root (in
-the file @file{CVS/Root}), so normally you only need to
-worry about this when initially checking out a working
-directory.
-
-@cindex EDITOR
-@cindex CVSEDITOR
-@item $EDITOR
-@itemx $CVSEDITOR
-Specifies the program to use for recording log messages
-during commit. If not set, the default is
-@samp{/usr/ucb/vi}. @code{$CVSEDITOR} overrides
-@code{$EDITOR}. @code{$CVSEDITOR} does not exist in
-@sc{cvs} 1.3, but the next release will probably
-include it.
-
-@cindex PATH
-@item $PATH
-If @code{$RCSBIN} is not set, and no path is compiled
-into @sc{cvs}, it will use @code{$PATH} to try to find all
-programs it uses.
-
-@cindex RCSBIN
-@item $RCSBIN
-Specifies the full pathname of the location of @sc{rcs} programs,
-such as co(1) and ci(1). If not set, a compiled-in
-value is used, or your @code{$PATH} is searched.
-@end table
-
-@sc{cvs} is a front-end to @sc{rcs}. The following environment
-variables affect @sc{rcs}:
-
-@table @code
-@cindex LOGNAME
-@item $LOGNAME
-@cindex USER
-@itemx $USER
-If set, they affect who @sc{rcs} thinks you are. If you
-have trouble checking in files it might be because your
-login name differs from the setting of e.g.
-@code{$LOGNAME}.
-
-@cindex RCSINIT
-@item $RCSINIT
-Options prepended to the argument list, separated by
-spaces. A backslash escapes spaces within an option.
-The @code{$RCSINIT} options are prepended to the
-argument lists of most @sc{rcs} commands.
-
-@cindex TMPDIR
-@item $TMPDIR
-@cindex TMP
-@itemx $TMP
-@cindex TEMP
-@itemx $TEMP
-Name of the temporary directory. The environment
-variables are inspected in the order they appear above
-and the first value found is taken; if none of them are
-set, a host-dependent default is used, typically
-@file{/tmp}.
-@end table
-
-@c ---------------------------------------------------------------------
-@node Troubleshooting
-@appendix Troubleshooting
-
-@menu
-* Magic branch numbers:: Magic branch numbers
-@end menu
-
-@ignore
-@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-@c @node Bad administrative files
-@appendixsec Bad administrative files
-
-@c -- Give hints on how to fix them
-@end ignore
-
-@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-@node Magic branch numbers
-@appendixsec Magic branch numbers
-
-Externally, branch numbers consist of an odd number of
-dot-separated decimal integers. @xref{Revision
-numbers}. That is not the whole truth, however. For
-efficiency reasons @sc{cvs} sometimes inserts an extra 0
-in the second rightmost position (1.2.3 becomes
-1.2.0.3, 8.9.10.11.12 becomes 8.9.10.11.0.12 and so
-on).
-
-@sc{cvs} does a pretty good job at hiding these so
-called magic branches, but in at least four places the
-hiding is incomplete.
-
-@itemize @bullet
-@item
-The magic branch can appear in the output from
-@code{cvs status} in vanilla @sc{cvs} 1.3. This is
-fixed in @sc{cvs} 1.3-s2.
-
-@item
-The magic branch number appears in the output from
-@code{cvs log}. This is much harder to fix, since
-@code{cvs log} runs @code{rlog} (which is part of the
-@sc{rcs} distribution), and modifying @code{rlog} to
-know about magic branches would probably break someone's
-habits (if they use branch 0 for their own purposes).
-
-@item
-You cannot specify a symbolic branch name to @code{cvs log}.
-
-@item
-You cannot specify a symbolic branch name to @code{cvs
-admin}.
-
-@end itemize
-
-You can use the @code{admin} command to reassign a
-symbolic name to a branch the way @sc{rcs} expects it
-to be. If @code{R4patches} is assigned to the branch
-1.4.2 (magic branch number 1.4.0.2) in file
-@file{numbers.c} you can do this:
-
-@example
-$ cvs admin -NR4patches:1.4.2 numbers.c
-@end example
-
-It only works if at least one revision is already
-committed on the branch. Be very careful so that you
-do not assign the tag to the wrong number. (There is
-no way to see how the tag was assigned yesterday).
-
-@c ---------------------------------------------------------------------
-@node Copying
-@appendix GNU GENERAL PUBLIC LICENSE
-@c @include gpl.texinfo
-
-@c ---------------------------------------------------------------------
-@node Index
-@unnumbered Index
-@cindex Index
-
-@printindex cp
-
-@summarycontents
-
-@contents
-
-@bye
-
-Local Variables:
-fill-column: 55
-End:
diff --git a/gnu/usr.bin/cvs/doc/cvsclient.texi b/gnu/usr.bin/cvs/doc/cvsclient.texi
deleted file mode 100644
index 9c8f326bd186..000000000000
--- a/gnu/usr.bin/cvs/doc/cvsclient.texi
+++ /dev/null
@@ -1,673 +0,0 @@
-\input texinfo
-
-@setfilename cvsclient.info
-
-@node Top
-@top CVS Client/Server
-
-This manual describes the client/server protocol used by CVS. It does
-not describe how to use or administer client/server CVS; see the
-regular CVS manual for that.
-
-@menu
-* Goals:: Basic design decisions, requirements, scope, etc.
-* Notes:: Notes on the current implementation
-* How To:: How to remote your favorite CVS command
-* Protocol Notes:: Possible enhancements, limitations, etc. of the protocol
-* Protocol:: Complete description of the protocol
-@end menu
-
-@node Goals
-@chapter Goals
-
-@itemize @bullet
-@item
-Do not assume any access to the repository other than via this protocol.
-It does not depend on NFS, rdist, etc.
-
-@item
-Providing a reliable transport is outside this protocol. It is expected
-that it runs over TCP, UUCP, etc.
-
-@item
-Security and authentication are handled outside this protocol (but see
-below about @samp{cvs kserver}).
-
-@item
-This might be a first step towards adding transactions to CVS (i.e. a
-set of operations is either executed atomically or none of them is
-executed), improving the locking, or other features. The current server
-implementation is a long way from being able to do any of these
-things. The protocol, however, is not known to contain any defects
-which would preclude them.
-
-@item
-The server never has to have any CVS locks in place while it is waiting
-for communication with the client. This makes things robust in the face
-of flaky networks.
-
-@item
-Data is transferred in large chunks, which is necessary for good
-performance. In fact, currently the client uploads all the data
-(without waiting for server responses), and then waits for one server
-response (which consists of a massive download of all the data). There
-may be cases in which it is better to have a richer interraction, but
-the need for the server to release all locks whenever it waits for the
-client makes it complicated.
-@end itemize
-
-@node Notes
-@chapter Notes on the Current Implementation
-
-The client is built in to the normal @code{cvs} program, triggered by a
-@code{CVSROOT} variable containing a colon, for example
-@code{cygnus.com:/rel/cvsfiles}.
-
-The client stores what is stored in checked-out directories (including
-@file{CVS}). The way these are stored is totally compatible with
-standard CVS. The server requires no storage other than the repository,
-which also is totally compatible with standard CVS.
-
-The server is started by @code{cvs server}. There is no particularly
-compelling reason for this rather than making it a separate program
-which shares a lot of sources with cvs.
-
-The server can also be started by @code{cvs kserver}, in which case it
-does an initial Kerberos authentication on stdin. If the authentication
-succeeds, it subsequently runs identically to @code{cvs server}.
-
-The current server implementation can use up huge amounts of memory
-when transmitting a lot of data over a slow link (i.e. the network is
-slower than the server can generate the data). Avoiding this is
-tricky because of the goal of not having the server block on the
-network when it has locks open (this could lock the repository for
-hours if things are running smoothly or longer if not). Several
-solutions are possible. The two-pass design would involve first
-noting what versions of everything we need (with locks in place) and
-then sending the data, blocking on the network, with no locks needed.
-The lather-rinse-repeat design would involve doing things as it does
-now until a certain amount of server memory is being used (10M?), then
-releasing locks, and trying the whole update again (some of it is
-presumably already done). One problem with this is getting merges to
-work right. The two-pass design appears to be the more elegant of the
-two (it actually reduces the amount of time that locks need to be in
-place), but people have expressed concerns about whether it would be
-slower (because it traverses the repository twice). It is not clear
-whether this is a real problem (looking for whether a file needs to be
-updated and actually checking it out are done separately already), but
-I don't think anyone has investigated carefully. One hybrid approach
-which avoids the problem with merges would be to start out in one-pass
-mode and switch to two-pass mode if data is backing up--but this
-complicates the code and should be undertaken only if the pure
-two-pass design is shown to be flawed.
-
-@node How To
-@chapter How to add more remote commands
-
-It's the usual simple twelve step process. Let's say you're making
-the existing @code{cvs fix} command work remotely.
-
-@itemize @bullet
-@item
-Add a declaration for the @code{fix} function, which already implements
-the @code{cvs fix} command, to @file{server.c}.
-@item
-Now, the client side.
-Add a function @code{client_fix} to @file{client.c}, which calls
-@code{parse_cvsroot} and then calls the usual @code{fix} function.
-@item
-Add a declaration for @code{client_fix} to @file{client.h}.
-@item
-Add @code{client_fix} to the "fix" entry in the table of commands in
-@file{main.c}.
-@item
-Now for the server side.
-Add the @code{serve_fix} routine to @file{server.c}; make it do:
-@example @code
-static void
-serve_fix (arg)
- char *arg;
-@{
- do_cvs_command (fix);
-@}
-@end example
-@item
-Add the server command @code{"fix"} to the table of requests in @file{server.c}.
-@item
-The @code{fix} function can now be entered in three different situations:
-local (the old situation), client, and server. On the server side it probably
-will not need any changes to cope.
-Modify the @code{fix} function so that if it is run when the variable
-@code{client_active} is set, it starts the server, sends over parsed
-arguments and possibly files, sends a "fix" command to the server,
-and handles responses from the server. Sample code:
-@example @code
- if (!client_active) @{
- /* Do whatever you used to do */
- @} else @{
- /* We're the local client. Fire up the remote server. */
- start_server ();
-
- if (local)
- if (fprintf (to_server, "Argument -l\n") == EOF)
- error (1, errno, "writing to server");
- send_option_string (options);
-
- send_files (argc, argv, local);
-
- if (fprintf (to_server, "fix\n") == EOF)
- error (1, errno, "writing to server");
- err = get_responses_and_close ();
- @}
-@end example
-@item
-Build it locally. Copy the new version into somewhere on the
-remote system, in your path so that @code{rsh host cvs} finds it.
-Now you can test it.
-@item
-You may want to set the environment variable @code{CVS_CLIENT_PORT} to
--1 to prevent the client from contacting the server via a direct TCP
-link. That will force the client to fall back to using @code{rsh},
-which will run your new binary.
-@item
-Set the environment variable @code{CVS_CLIENT_LOG} to a filename prefix
-such as @file{/tmp/cvslog}. Whenever you run a remote CVS command,
-the commands and responses sent across the client/server connection
-will be logged in @file{/tmp/cvslog.in} and @file{/tmp/cvslog.out}.
-Examine them for problems while you're testing.
-@end itemize
-
-This should produce a good first cut at a working remote @code{cvs fix}
-command. You may have to change exactly how arguments are passed,
-whether files or just their names are sent, and how some of the deeper
-infrastructure of your command copes with remoteness.
-
-@node Protocol Notes
-@chapter Notes on the Protocol
-
-A number of enhancements are possible:
-
-@itemize @bullet
-@item
-The @code{Modified} request could be speeded up by sending diffs rather
-than entire files. The client would need some way to keep the version
-of the file which was originally checked out, which would double client
-disk space requirements or require coordination with editors (e.g. maybe
-it could use emacs numbered backups). This would also allow local
-operation of @code{cvs diff} without arguments.
-
-@item
-Have the client keep a copy of some part of the repository. This allows
-all of @code{cvs diff} and large parts of @code{cvs update} and
-@code{cvs ci} to be local. The local copy could be made consistent with
-the master copy at night (but if the master copy has been updated since
-the latest nightly re-sync, then it would read what it needs to from the
-master).
-
-@item
-Provide encryption using kerberos.
-
-@item
-The current procedure for @code{cvs update} is highly sub-optimal if
-there are many modified files. One possible alternative would be to
-have the client send a first request without the contents of every
-modified file, then have the server tell it what files it needs. Note
-the server needs to do the what-needs-to-be-updated check twice (or
-more, if changes in the repository mean it has to ask the client for
-more files), because it can't keep locks open while waiting for the
-network. Perhaps this whole thing is irrelevant if client-side
-repositories are implemented, and the rcsmerge is done by the client.
-@end itemize
-
-@node Protocol
-@chapter The CVS client/server protocol
-
-@menu
-* Entries Lines::
-* Modes::
-* Requests::
-* Responses::
-* Example::
-@end menu
-
-@node Entries Lines
-@section Entries Lines
-
-Entries lines are transmitted as:
-
-@example
-/ @var{name} / @var{version} / @var{conflict} / @var{options} / @var{tag_or_date}
-@end example
-
-@var{tag_or_date} is either @samp{T} @var{tag} or @samp{D} @var{date}
-or empty. If it is followed by a slash, anything after the slash
-shall be silently ignored.
-
-@var{version} can be empty, or start with @samp{0} or @samp{-}, for no
-user file, new user file, or user file to be removed, respectively.
-
-@var{conflict}, if it starts with @samp{+}, indicates that the file had
-conflicts in it. The rest of @var{conflict} is @samp{=} if the
-timestamp matches the file, or anything else if it doesn't. If
-@var{conflict} does not start with a @samp{+}, it is silently ignored.
-
-@node Modes
-@section Modes
-
-A mode is any number of repetitions of
-
-@example
-@var{mode-type} = @var{data}
-@end example
-
-separated by @samp{,}.
-
-@var{mode-type} is an identifier composed of alphanumeric characters.
-Currently specified: @samp{u} for user, @samp{g} for group, @samp{o} for
-other, as specified in POSIX. If at all possible, give these their
-POSIX meaning and use other mode-types for other behaviors. For
-example, on VMS it shouldn't be hard to make the groups behave like
-POSIX, but you would need to use ACLs for some cases.
-
-@var{data} consists of any data not containing @samp{,}, @samp{\0} or
-@samp{\n}. For @samp{u}, @samp{g}, and @samp{o} mode types, data
-consists of alphanumeric characters, where @samp{r} means read, @samp{w}
-means write, @samp{x} means execute, and unrecognized letters are
-silently ignored.
-
-@node Requests
-@section Requests
-
-File contents (noted below as @var{file transmission}) can be sent in
-one of two forms. The simpler form is a number of bytes, followed by a
-newline, followed by the specified number of bytes of file contents.
-These are the entire contents of the specified file. Second, if both
-client and server support @samp{gzip-file-contents}, a @samp{z} may
-precede the length, and the `file contents' sent are actually compressed
-with @samp{gzip}. The length specified is that of the compressed
-version of the file.
-
-In neither case are the file content followed by any additional data.
-The transmission of a file will end with a newline iff that file (or its
-compressed form) ends with a newline.
-
-@table @code
-@item Root @var{pathname} \n
-Response expected: no.
-Tell the server which @code{CVSROOT} to use.
-
-@item Valid-responses @var{request-list} \n
-Response expected: no.
-Tell the server what responses the client will accept.
-request-list is a space separated list of tokens.
-
-@item valid-requests \n
-Response expected: yes.
-Ask the server to send back a @code{Valid-requests} response.
-
-@item Repository @var{repository} \n
-Response expected: no. Tell the server what repository to use. This
-should be a directory name from a previous server response. Note that
-this both gives a default for @code{Entry } and @code{Modified } and
-also for @code{ci} and the other commands; normal usage is to send a
-@code{Repository } for each directory in which there will be an
-@code{Entry } or @code{Modified }, and then a final @code{Repository }
-for the original directory, then the command.
-
-@item Directory @var{local-directory} \n
-Additional data: @var{repository} \n. This is like @code{Repository},
-but the local name of the directory may differ from the repository name.
-If the client uses this request, it affects the way the server returns
-pathnames; see @ref{Responses}. @var{local-directory} is relative to
-the top level at which the command is occurring (i.e. the last
-@code{Directory} or @code{Repository} which is sent before the command).
-
-@item Max-dotdot @var{level} \n
-Tell the server that @var{level} levels of directories above the
-directory which @code{Directory} requests are relative to will be
-needed. For example, if the client is planning to use a
-@code{Directory} request for @file{../../foo}, it must send a
-@code{Max-dotdot} request with a @var{level} of at least 2.
-@code{Max-dotdot} must be sent before the first @code{Directory}
-request.
-
-@item Static-directory \n
-Response expected: no. Tell the server that the directory most recently
-specified with @code{Repository} or @code{Directory} should not have
-additional files checked out unless explicitly requested. The client
-sends this if the @code{Entries.Static} flag is set, which is controlled
-by the @code{Set-static-directory} and @code{Clear-static-directory}
-responses.
-
-@item Sticky @var{tagspec} \n
-Response expected: no. Tell the server that the directory most recently
-specified with @code{Repository} has a sticky tag or date @var{tagspec}.
-The first character of @var{tagspec} is @samp{T} for a tag, or @samp{D}
-for a date. The remainder of @var{tagspec} contains the actual tag or
-date.
-
-@item Checkin-prog @var{program} \n
-Response expected: no. Tell the server that the directory most recently
-specified with @code{Directory} has a checkin program @var{program}.
-Such a program would have been previously set with the
-@code{Set-checkin-prog} response.
-
-@item Update-prog @var{program} \n
-Response expected: no. Tell the server that the directory most recently
-specified with @code{Directory} has an update program @var{program}.
-Such a program would have been previously set with the
-@code{Set-update-prog} response.
-
-@item Entry @var{entry-line} \n
-Response expected: no. Tell the server what version of a file is on the
-local machine. The name in @var{entry-line} is a name relative to the
-directory most recently specified with @code{Repository}. If the user
-is operating on only some files in a directory, @code{Entry} requests
-for only those files need be included. If an @code{Entry} request is
-sent without @code{Modified}, @code{Unchanged}, or @code{Lost} for that
-file the meaning depends on whether @code{UseUnchanged} has been sent;
-if it has been it means the file is lost, if not it means the file is
-unchanged.
-
-@item Modified @var{filename} \n
-Response expected: no. Additional data: mode, \n, file transmission.
-Send the server a copy of one locally modified file. @var{filename} is
-relative to the most recent repository sent with @code{Repository}. If
-the user is operating on only some files in a directory, only those
-files need to be included. This can also be sent without @code{Entry},
-if there is no entry for the file.
-
-@item Lost @var{filename} \n
-Response expected: no. Tell the server that @var{filename} no longer
-exists. The name is relative to the most recent repository sent with
-@code{Repository}. This is used for any case in which @code{Entry} is
-being sent but the file no longer exists. If the client has issued the
-@code{UseUnchanged} request, then this request is not used.
-
-@item Unchanged @var{filename} \n
-Response expected: no. Tell the server that @var{filename} has not been
-modified in the checked out directory. The name is relative to the most
-recent repository sent with @code{Repository}. This request can only be
-issued if @code{UseUnchanged} has been sent.
-
-@item UseUnchanged \n
-Response expected: no. Tell the server that the client will be
-indicating unmodified files with @code{Unchanged}, and that files for
-which no information is sent are nonexistent on the client side, not
-unchanged. This is necessary for correct behavior since only the server
-knows what possible files may exist, and thus what files are
-nonexistent.
-
-@item Argument @var{text} \n
-Response expected: no.
-Save argument for use in a subsequent command. Arguments
-accumulate until an argument-using command is given, at which point
-they are forgotten.
-
-@item Argumentx @var{text} \n
-Response expected: no. Append \n followed by text to the current
-argument being saved.
-
-@item Global_option @var{option} \n
-Transmit one of the global options @samp{-q}, @samp{-Q}, @samp{-l},
-@samp{-t}, @samp{-r}, or @samp{-n}. @var{option} must be one of those
-strings, no variations (such as combining of options) are allowed. For
-graceful handling of @code{valid-requests}, it is probably better to
-make new global options separate requests, rather than trying to add
-them to this request.
-
-@item expand-modules \n
-Response expected: yes. Expand the modules which are specified in the
-arguments. Returns the data in @code{Module-expansion} responses. Note
-that the server can assume that this is checkout or export, not rtag or
-rdiff; the latter do not access the working directory and thus have no
-need to expand modules on the client side.
-
-@item co \n
-@itemx update \n
-@itemx ci \n
-@itemx diff \n
-@itemx tag \n
-@itemx status \n
-@itemx log \n
-@itemx add \n
-@itemx remove \n
-@itemx rdiff \n
-@itemx rtag \n
-@itemx import \n
-@itemx admin \n
-@itemx export \n
-@itemx history \n
-@itemx release \n
-Response expected: yes. Actually do a cvs command. This uses any
-previous @code{Argument}, @code{Repository}, @code{Entry},
-@code{Modified}, or @code{Lost} requests, if they have been sent. The
-last @code{Repository} sent specifies the working directory at the time
-of the operation. No provision is made for any input from the user.
-This means that @code{ci} must use a @code{-m} argument if it wants to
-specify a log message.
-
-@item update-patches \n
-This request does not actually do anything. It is used as a signal that
-the server is able to generate patches when given an @code{update}
-request. The client must issue the @code{-u} argument to @code{update}
-in order to receive patches.
-
-@item gzip-file-contents @var{level} \n
-This request asks the server to filter files it sends to the client
-through the @samp{gzip} program, using the specified level of
-compression. If this request is not made, the server must not do any
-compression.
-
-This is only a hint to the server. It may still decide (for example, in
-the case of very small files, or files that already appear to be
-compressed) not to do the compression. Compression is indicated by a
-@samp{z} preceding the file length.
-
-Availability of this request in the server indicates to the client that
-it may compress files sent to the server, regardless of whether the
-client actually uses this request.
-
-@item @var{other-request} @var{text} \n
-Response expected: yes.
-Any unrecognized request expects a response, and does not
-contain any additional data. The response will normally be something like
-@samp{error unrecognized request}, but it could be a different error if
-a previous command which doesn't expect a response produced an error.
-@end table
-
-When the client is done, it drops the connection.
-
-@node Responses
-@section Responses
-
-After a command which expects a response, the server sends however many
-of the following responses are appropriate. Pathnames are of the actual
-files operated on (i.e. they do not contain @samp{,v} endings), and are
-suitable for use in a subsequent @code{Repository} request. However, if
-the client has used the @code{Directory} request, then it is instead a
-local directory name relative to the directory in which the command was
-given (i.e. the last @code{Directory} before the command). Then a
-newline and a repository name (the pathname which is sent if
-@code{Directory} is not used). Then the slash and the filename. For
-example, for a file @file{i386.mh} which is in the local directory
-@file{gas.clean/config} and for which the repository is
-@file{/rel/cvsfiles/devo/gas/config}:
-
-@example
-gas.clean/config/
-/rel/cvsfiles/devo/gas/config/i386.mh
-@end example
-
-Any response always ends with @samp{error} or @samp{ok}. This indicates
-that the response is over.
-
-@table @code
-@item Valid-requests @var{request-list} \n
-Indicate what requests the server will accept. @var{request-list}
-is a space separated list of tokens. If the server supports sending
-patches, it will include @samp{update-patches} in this list. The
-@samp{update-patches} request does not actually do anything.
-
-@item Checked-in @var{pathname} \n
-Additional data: New Entries line, \n. This means a file @var{pathname}
-has been successfully operated on (checked in, added, etc.). name in
-the Entries line is the same as the last component of @var{pathname}.
-
-@item New-entry @var{pathname} \n
-Additional data: New Entries line, \n. Like @code{Checked-in}, but the
-file is not up to date.
-
-@item Updated @var{pathname} \n
-Additional data: New Entries line, \n, mode, \n, file transmission. A
-new copy of the file is enclosed. This is used for a new revision of an
-existing file, or for a new file, or for any other case in which the
-local (client-side) copy of the file needs to be updated, and after
-being updated it will be up to date. If any directory in pathname does
-not exist, create it.
-
-@item Merged @var{pathname} \n
-This is just like @code{Updated} and takes the same additional data,
-with the one difference that after the new copy of the file is enclosed,
-it will still not be up to date. Used for the results of a merge, with
-or without conflicts.
-
-@item Patched @var{pathname} \n
-This is just like @code{Updated} and takes the same additional data,
-with the one difference that instead of sending a new copy of the file,
-the server sends a patch produced by @samp{diff -u}. This client must
-apply this patch, using the @samp{patch} program, to the existing file.
-This will only be used when the client has an exact copy of an earlier
-revision of a file. This response is only used if the @code{update}
-command is given the @samp{-u} argument.
-
-@item Checksum @var{checksum}\n
-The @var{checksum} applies to the next file sent over via
-@code{Updated}, @code{Merged}, or @code{Patched}. In the case of
-@code{Patched}, the checksum applies to the file after being patched,
-not to the patch itself. The client should compute the checksum itself,
-after receiving the file or patch, and signal an error if the checksums
-do not match. The checksum is the 128 bit MD5 checksum represented as
-32 hex digits. This response is optional, and is only used if the
-client supports it (as judged by the @code{Valid-responses} request).
-
-@item Copy-file @var{pathname} \n
-Additional data: @var{newname} \n. Copy file @var{pathname} to
-@var{newname} in the same directory where it already is. This does not
-affect @code{CVS/Entries}.
-
-@item Removed @var{pathname} \n
-The file has been removed from the repository (this is the case where
-cvs prints @samp{file foobar.c is no longer pertinent}).
-
-@item Remove-entry @var{pathname} \n
-The file needs its entry removed from @code{CVS/Entries}, but the file
-itself is already gone (this happens in response to a @code{ci} request
-which involves committing the removal of a file).
-
-@item Set-static-directory @var{pathname} \n
-This instructs the client to set the @code{Entries.Static} flag, which
-it should then send back to the server in a @code{Static-directory}
-request whenever the directory is operated on. @var{pathname} ends in a
-slash; its purpose is to specify a directory, not a file within a
-directory.
-
-@item Clear-static-directory @var{pathname} \n
-Like @code{Set-static-directory}, but clear, not set, the flag.
-
-@item Set-sticky @var{pathname} \n
-Additional data: @var{tagspec} \n. Tell the client to set a sticky tag
-or date, which should be supplied with the @code{Sticky} request for
-future operations. @var{pathname} ends in a slash; its purpose is to
-specify a directory, not a file within a directory. The first character
-of @var{tagspec} is @samp{T} for a tag, or @samp{D} for a date. The
-remainder of @var{tagspec} contains the actual tag or date.
-
-@item Clear-sticky @var{pathname} \n
-Clear any sticky tag or date set by @code{Set-sticky}.
-
-@item Set-checkin-prog @var{dir} \n
-Additional data: @var{prog} \n. Tell the client to set a checkin
-program, which should be supplied with the @code{Checkin-prog} request
-for future operations.
-
-@item Set-update-prog @var{dir} \n
-Additional data: @var{prog} \n. Tell the client to set an update
-program, which should be supplied with the @code{Update-prog} request
-for future operations.
-
-@item Module-expansion @var{pathname} \n
-Return a file or directory which is included in a particular module.
-@var{pathname} is relative to cvsroot, unlike most pathnames in
-responses.
-
-@item M @var{text} \n
-A one-line message for the user.
-
-@item E @var{text} \n
-Same as @code{M} but send to stderr not stdout.
-
-@item error @var{errno-code} @samp{ } @var{text} \n
-The command completed with an error. @var{errno-code} is a symbolic
-error code (e.g. @code{ENOENT}); if the server doesn't support this
-feature, or if it's not appropriate for this particular message, it just
-omits the errno-code (in that case there are two spaces after
-@samp{error}). Text is an error message such as that provided by
-strerror(), or any other message the server wants to use.
-
-@item ok \n
-The command completed successfully.
-@end table
-
-@node Example
-@section Example
-
-Lines beginning with @samp{c>} are sent by the client; lines beginning
-with @samp{s>} are sent by the server; lines beginning with @samp{#} are
-not part of the actual exchange.
-
-@example
-c> Root /rel/cvsfiles
-# In actual practice the lists of valid responses and requests would
-# be longer
-c> Valid-responses Updated Checked-in M ok error
-c> valid-requests
-s> Valid-requests Root co Modified Entry Repository ci Argument Argumentx
-s> ok
-# cvs co devo/foo
-c> Argument devo/foo
-c> co
-s> Updated /rel/cvsfiles/devo/foo/foo.c
-s> /foo.c/1.4/Mon Apr 19 15:36:47 1993 Mon Apr 19 15:36:47 1993//
-s> 26
-s> int mein () @{ abort (); @}
-s> Updated /rel/cvsfiles/devo/foo/Makefile
-s> /Makefile/1.2/Mon Apr 19 15:36:47 1993 Mon Apr 19 15:36:47 1993//
-s> 28
-s> foo: foo.c
-s> $(CC) -o foo $<
-s> ok
-# In actual practice the next part would be a separate connection.
-# Here it is shown as part of the same one.
-c> Repository /rel/cvsfiles/devo/foo
-# foo.c relative to devo/foo just set as Repository.
-c> Entry /foo.c/1.4/Mon Apr 19 15:36:47 1993 Mon Apr 19 15:36:47 1993//
-c> Entry /Makefile/1.2/Mon Apr 19 15:36:47 1993 Mon Apr 19 15:36:47 1993//
-c> Modified foo.c
-c> 26
-c> int main () @{ abort (); @}
-# cvs ci -m <log message> foo.c
-c> Argument -m
-c> Argument Well, you see, it took me hours and hours to find this typo and I
-c> Argumentx searched and searched and eventually had to ask John for help.
-c> Argument foo.c
-c> ci
-s> Checked-in /rel/cvsfiles/devo/foo/foo.c
-s> /foo.c/1.5/ Mon Apr 19 15:54:22 CDT 1993//
-s> M Checking in foo.c;
-s> M /cygint/rel/cvsfiles/devo/foo/foo.c,v <-- foo.c
-s> M new revision: 1.5; previous revision: 1.4
-s> M done
-s> ok
-@end example
-@bye
diff --git a/gnu/usr.bin/cvs/examples/checkoutlist b/gnu/usr.bin/cvs/examples/checkoutlist
deleted file mode 100644
index 45ee6dc44f15..000000000000
--- a/gnu/usr.bin/cvs/examples/checkoutlist
+++ /dev/null
@@ -1,20 +0,0 @@
-#
-#ident "@(#)cvs/examples:$Name: $:$Id: checkoutlist,v 1.2 1995/11/14 23:24:49 woods Exp $"
-#
-# The "checkoutlist" file is used to support additional version controlled
-# administrative files in $CVSROOT/CVSROOT, such as template files.
-#
-# The first entry on a line is a filename which will be checked out from
-# the corresponding RCS file in the $CVSROOT/CVSROOT directory.
-# The remainder of the line is an error message to use if the file cannot
-# be checked out.
-#
-# File format:
-#
-# [<whitespace>]<filename><whitespace><error message><end-of-line>
-#
-# comment lines begin with '#'
-#
-rcstemplate
-wrap
-unwrap
diff --git a/gnu/usr.bin/cvs/examples/commitinfo b/gnu/usr.bin/cvs/examples/commitinfo
deleted file mode 100644
index 39647983b609..000000000000
--- a/gnu/usr.bin/cvs/examples/commitinfo
+++ /dev/null
@@ -1,27 +0,0 @@
-#
-#ident "@(#)cvs/examples:$Name: $:$Id: commitinfo,v 1.3 1995/11/14 23:30:05 woods Exp $"
-#
-# The "commitinfo" file is used to control pre-commit checks.
-# The filter on the right is invoked with the repository and a list
-# of files to check. A non-zero exit of the filter program will
-# cause the commit to be aborted.
-#
-# The first entry on a line is a regular expression which is tested
-# against the directory that the change is being committed to, relative
-# to the $CVSROOT. For the first match that is found, then the remainder
-# of the line is the name of the filter to run.
-#
-# If the repository name does not match any of the regular expressions in this
-# file, the "DEFAULT" line is used, if it is specified.
-#
-# If the name "ALL" appears as a regular expression it is always used
-# in addition to the first matching regex or "DEFAULT".
-#
-# NOTE: contrib/commit_prep usage:
-# -r - record directories affected by commit for use with contrib/log_accum
-# -c - check for things like "$Id" near head of file, no "$Log", etc.
-#
-^apc $CVSROOT/CVSROOT/commit_prep -r -c
-^misc $CVSROOT/CVSROOT/commit_prep -r
-CVSROOT $CVSROOT/CVSROOT/commit_prep -r -c
-DEFAULT $CVSROOT/CVSROOT/commit_prep
diff --git a/gnu/usr.bin/cvs/examples/cvswrappers b/gnu/usr.bin/cvs/examples/cvswrappers
deleted file mode 100644
index c666292e6460..000000000000
--- a/gnu/usr.bin/cvs/examples/cvswrappers
+++ /dev/null
@@ -1,29 +0,0 @@
-#
-#ident "@(#)cvs/examples:$Name: $:$Id: cvswrappers,v 1.3 1995/11/14 23:23:11 woods Exp $"
-#
-# This file describes wrappers and other binary files to CVS.
-#
-# Wrappers are the concept where directories of files are to be
-# treated as a single file. The intended use is to wrap up a wrapper
-# into a single tar such that the tar archive can be treated as a
-# single binary file in CVS.
-#
-# To solve the problem effectively, it was also necessary to be able to
-# prevent rcsmerge from merging these files.
-#
-# Format of wrapper file ($CVSROOT/CVSROOT/cvswrappers or .cvswrappers)
-#
-# wildcard [option value][option value]...
-#
-# where option is one of
-# -f from cvs filter value: path to filter
-# -t to cvs filter value: path to filter
-# -m update methodology value: MERGE or COPY
-#
-# and value is a single-quote delimited value.
-#
-#
-*.nib -f '$CVSROOT/CVSROOT/unwrap %s' -t '$CVSROOT/CVSROOT/wrap %s %s'
-*.rtfd -f '$CVSROOT/CVSROOT/unwrap %s' -t '$CVSROOT/CVSROOT/wrap %s %s'
-*.draw -f '$CVSROOT/CVSROOT/unwrap %s' -t '$CVSROOT/CVSROOT/wrap %s %s'
-*.tiff -m 'COPY'
diff --git a/gnu/usr.bin/cvs/examples/editinfo b/gnu/usr.bin/cvs/examples/editinfo
deleted file mode 100644
index 976a9862ffd0..000000000000
--- a/gnu/usr.bin/cvs/examples/editinfo
+++ /dev/null
@@ -1,32 +0,0 @@
-#
-#ident "@(#)cvs/examples:$Name: $:$Id: editinfo,v 1.2 1995/11/14 23:30:07 woods Exp $"
-#
-# The "editinfo" file is used to allow verification of logging
-# information. It works best when a template (as specified in the
-# rcsinfo file) is provided for the logging procedure. Given a
-# template with locations for, a bug-id number, a list of people who
-# reviewed the code before it can be checked in, and an external
-# process to catalog the differences that were code reviewed, the
-# following test can be applied to the code:
-#
-# Making sure that the entered bug-id number is correct.
-# Validating that the code that was reviewed is indeed the code being
-# checked in (using the bug-id number or a seperate review
-# number to identify this particular code set.).
-#
-# If any of the above test failed, then the commit would be aborted.
-#
-# Actions such as mailing a copy of the report to each reviewer are
-# better handled by an entry in the loginfo file.
-#
-# Although these test could be handled by an interactive script being
-# called via an entry in commitinfo, The information reported in
-# such a script can't be easily merged into the report.
-#
-# One thing that should be noted is the the ALL keyword is not
-# supported. There can be only one entry that matches a given
-# repository.
-#
-# Note there is no "edit" example script currently available....
-#
-DEFAULT $CVSROOT/CVSROOT/edit "%s"
diff --git a/gnu/usr.bin/cvs/examples/loginfo b/gnu/usr.bin/cvs/examples/loginfo
deleted file mode 100644
index 1d68e7d9cc9b..000000000000
--- a/gnu/usr.bin/cvs/examples/loginfo
+++ /dev/null
@@ -1,39 +0,0 @@
-#
-#ident "@(#)cvs/examples:$Name: $:$Id: loginfo,v 1.4 1995/11/14 23:30:08 woods Exp $"
-#
-# The "loginfo" file is used to control where "cvs commit" log information
-# is sent. The first entry on a line is a regular expression which is tested
-# against the directory that the change is being made to, relative to the
-# $CVSROOT. For the first match that is found, then the remainder of the
-# line is a filter program that should expect log information on its standard
-# input.
-#
-# If the repository name does not match any of the regular expressions in the
-# first field of this file, the "DEFAULT" line is used, if it is specified.
-#
-# If the name "ALL" appears as a regular expression it is always used
-# in addition to the first matching regex or "DEFAULT".
-#
-# The filter program may use one and only one "%s" modifier (ala printf). If
-# such a "%s" is specified in the filter program, a brief title is included
-# (as one argument, enclosed in single quotes) showing the relative directory
-# name and listing the modified file names.
-#
-# NOTE: contrib/log usage: (currently requires perl)
-# -d - turn debugging on....
-# -m mailto - send mail to "mailto" (multiple -m's permitted)
-# -f logfile - required arg: save messages to logfile
-# %s - may follow other options at the end of the line
-#
-# NOTE: contrib/log_accum usage: (currently requires perl)
-# (must have 'commit_prep -r' in commitinfo)
-# -d - turn debugging on....
-# -M modulename - use this as the module name (necessary for sub-dirs)
-# -m mailto - send mail to "mailto" (multiple -m's permitted) [optional]
-# -f logfile - save messages to logfile [optional]
-# %s - must follow other options at the end of the line
-#
-# without perl you could do this:
-#DEFAULT (echo ""; who am i; date; cat) >> $CVSROOT/CVSROOT/commitlog
-#
-DEFAULT $CVSROOT/CVSROOT/log -f $CVSROOT/CVSROOT/commitlog %s
diff --git a/gnu/usr.bin/cvs/examples/modules b/gnu/usr.bin/cvs/examples/modules
deleted file mode 100644
index ac8cd4dc840b..000000000000
--- a/gnu/usr.bin/cvs/examples/modules
+++ /dev/null
@@ -1,581 +0,0 @@
-#
-# The CVS Modules File
-#
-#ident "@(#)cvs/examples:$Name: $:$Id: modules,v 1.4 1995/11/14 23:28:48 woods Exp $"
-#
-# Three different line formats are valid:
-# key -a aliases...
-# key [options] directory
-# key [options] directory files...
-#
-# Where "options" are composed of:
-# -i prog Run "prog" on "cvs commit" from top-level of module.
-# -o prog Run "prog" on "cvs checkout" of module.
-# -e prog Run "prog" on "cvs export" of module.
-# -t prog Run "prog" on "cvs rtag" of module.
-# -u prog Run "prog" on "cvs update" of module.
-# -d dir Place module in directory "dir" instead of module name.
-# -l Top-level directory only -- do not recurse.
-#
-# And "directory" is a path to a directory relative to $CVSROOT.
-#
-# The "-a" option specifies an alias. An alias is interpreted as if
-# everything on the right of the "-a" had been typed on the command line.
-#
-# You can encode a module within a module by using the special '&'
-# character to interpose another module into the current module. This
-# can be useful for creating a module that consists of many directories
-# spread out over the entire source repository.
-#
-
-# Convenient aliases
-world -a .
-
-# CVSROOT support
-CVSROOT -i /usr/local/bin/mkmodules CVSROOT
-commitinfo -i /usr/local/bin/mkmodules CVSROOT commitinfo
-cvswrappers -i /usr/local/bin/mkmodules CVSROOT cvswrappers
-editinfo -i /usr/local/bin/mkmodules CVSROOT editinfo
-modules -i /usr/local/bin/mkmodules CVSROOT modules
-loginfo -i /usr/local/bin/mkmodules CVSROOT loginfo
-rcsinfo -i /usr/local/bin/mkmodules CVSROOT rcsinfo
-rcstemplate -i /usr/local/bin/mkmodules CVSROOT rcstemplate
-taginfo -i /usr/local/bin/mkmodules CVSROOT taginfo
-
-# Add more modules here
-#
-# END_REQUIRED_CONTENT (this comment for cvsinit)
-#
-# The remainder was for the Prisma OS sources
-#
-
-# another convenient alias
-kernel -a sys lang/adb sparcsim
-
-# The "sys" entry exists only to make symbolic links after checkout
-sys -o sys/tools/make_links sys
-
-# Sub-directories of "bin"
-awk bin/awk
-csh bin/csh
-diff bin/diff
-make bin/make
-sed bin/sed
-sh bin/sh
-
-# Programs that live in "bin"
-cat bin Makefile cat.c
-chgrp bin Makefile chgrp.c
-chmod bin Makefile chmod.c
-cmp bin Makefile cmp.c
-cp bin Makefile cp.c
-date bin Makefile date.c
-dd bin Makefile dd.c
-df bin Makefile df.c
-domainname bin Makefile domainname.c
-du bin Makefile du.c
-echo bin Makefile echo.c
-ed bin Makefile ed.c
-env bin Makefile env.c
-expr bin Makefile expr.c
-grep bin Makefile grep.c
-hostid bin Makefile hostid.c
-hostname bin Makefile hostname.c
-kill bin Makefile kill.c
-ldd bin Makefile ldd.c
-line bin Makefile line.c
-ln bin Makefile ln.c
-login bin Makefile login.c
-ls bin Makefile ls.c
-mail bin Makefile mail.c
-mkdir bin Makefile mkdir.c
-mt bin Makefile mt.c
-mv bin Makefile mv.c
-newgrp bin Makefile newgrp.c
-nice bin Makefile nice.c
-od bin Makefile od.c
-pagesize bin Makefile pagesize.c
-passwd bin Makefile passwd.c
-pr bin Makefile pr.c
-ps bin Makefile ps.c
-pwd bin Makefile pwd.c
-rm bin Makefile rm.c
-rmail bin Makefile rmail.c
-rmdir bin Makefile rmdir.c
-stty bin Makefile stty.c
-su bin Makefile su.c
-sync bin Makefile sync.c
-tar bin Makefile tar.c
-tee bin Makefile tee.c
-test bin Makefile test.c
-time bin Makefile time.c
-wall bin Makefile wall.c
-who bin Makefile who.c
-write bin Makefile write.c
-
-# Sub-directories of "etc"
-dump etc/dump
-files etc/files
-fsck etc/fsck
-getty etc/getty
-in.routed etc/in.routed
-restore etc/restore
-rpc.lockd etc/rpc.lockd
-rpc.statd etc/rpc.statd
-
-# Programs that live in "etc"
-arp etc Makefile arp.c
-biod etc Makefile biod.c
-chown etc Makefile chown.c
-clri etc Makefile clri.c
-dkinfo etc Makefile dkinfo.c
-dmesg etc Makefile dmesg.c
-fsirand etc Makefile fsirand.c
-halt etc Makefile halt.c
-ifconfig etc Makefile ifconfig.c
-in.rlogind etc Makefile in.rlogind.c
-in.rshd etc Makefile in.rshd.c
-inetd etc Makefile inetd.c
-init etc Makefile init.c
-mkfs etc Makefile mkfs.c
-mknod etc Makefile mknod.c
-mount etc Makefile mount.c
-newfs etc Makefile newfs.c
-nfsd etc Makefile nfsd.c
-portmap etc Makefile portmap.c
-pstat etc Makefile pstat.c
-reboot etc Makefile reboot.c
-renice etc Makefile renice.c
-rmt etc Makefile rmt.c
-shutdown etc Makefile shutdown.c
-syslogd etc Makefile syslogd.c
-umount etc Makefile umount.c
-update etc Makefile update.c
-vipw etc Makefile vipw.c
-ypbind etc Makefile ypbind.c
-
-# Sub-directories of "games"
-adventure games/adventure
-backgammon games/backgammon
-battlestar games/battlestar
-boggle games/boggle
-chess games/chess
-ching games/ching
-cribbage games/cribbage
-fortune games/fortune
-hack games/hack
-hangman games/hangman
-hunt games/hunt
-life games/life
-mille games/mille
-monop games/monop
-quiz games/quiz
-robots games/robots
-sail games/sail
-snake games/snake
-trek games/trek
-
-# Programs that live in "games"
-arithmetic games Makefile arithmetic.c
-banner games Makefile banner.c
-bcd games Makefile bcd.c
-bj games Makefile bj.c
-btlgammon games Makefile btlgammon.c
-canfield games Makefile canfield.c
-cfscores games Makefile cfscores.c
-craps games Makefile craps.c
-factor games Makefile factor.c
-fish games Makefile fish.c
-moo games Makefile moo.c
-number games Makefile number.c
-primes games Makefile primes.c
-rain games Makefile rain.c
-random games Makefile random.c
-worm games Makefile worm.c
-worms games Makefile worms.c
-wump games Makefile wump.c
-
-# Sub-directories of "lang"
-adb lang/adb
-as lang/as
-boot lang/boot
-c2 lang/c2
-cgrdr lang/cgrdr
-compile lang/compile
-cpp lang/cpp
-dbx lang/dbx
-f77 lang/f77
-inline lang/inline
-iropt lang/iropt
-ld lang/ld
-lint lang/lint
-m4 lang/m4
-pascal lang/pascal
-pcc lang/pcc
-ratfor lang/ratfor
-rtld lang/rtld
-tcov lang/tcov
-vroot lang/vroot
-
-# Programs that live in "lang"
-ar lang Makefile ar.c
-nm lang Makefile nm.c
-ranlib lang Makefile ranlib.c
-size lang Makefile size.c
-strip lang Makefile strip.c
-symorder lang Makefile symorder.c
-
-# Sub-directories of "lib"
-csu lib/csu
-libc lib/libc
-
-# Programs that live in "lib"
-# NONE
-
-# Sub-directories of "lib/libc"
-libc_compat lib/libc/compat
-libc_crt lib/libc/crt
-libc_des lib/libc/des
-libc_gen lib/libc/gen
-libc_net lib/libc/net
-libc_inet lib/libc/inet
-libc_rpc lib/libc/rpc
-libc_stdio lib/libc/stdio
-libc_sun lib/libc/sun
-libc_sys lib/libc/sys
-libc_yp lib/libc/yp
-
-# Programs that live in "lib/libc"
-# NONE
-
-#Sub-directories of "local"
-notes local/notes
-
-# Sub-directories of "man"
-man1 man/man1
-man2 man/man2
-man3 man/man3
-man4 man/man4
-man5 man/man5
-man6 man/man6
-man7 man/man7
-man8 man/man8
-manl man/manl
-
-# Programs that live in "man"
-# NONE
-
-# Sub-directories of "old"
-old_compact old/compact
-old_eyacc old/eyacc
-old_filemerge old/filemerge
-old_make old/make
-
-# Programs that live in "old"
-old_analyze old Makefile analyze.c
-old_prmail old Makefile prmail.c
-old_pti old Makefile pti.c
-old_syslog old Makefile syslog.c
-
-# Sub-directories of "ucb"
-Mail ucb/Mail
-compress ucb/compress
-error ucb/error
-ex ucb/ex
-ftp ucb/ftp
-gprof ucb/gprof
-indent ucb/indent
-lpr ucb/lpr
-more ucb/more
-msgs ucb/msgs
-netstat ucb/netstat
-rdist ucb/rdist
-talk ucb/talk
-tftp ucb/tftp
-tset ucb/tset
-vgrind ucb/vgrind
-
-# Programs that live in "ucb"
-biff ucb Makefile biff.c
-checknr ucb Makefile checknr.c
-clear ucb Makefile clear.c
-colcrt ucb Makefile colcrt.c
-colrm ucb Makefile colrm.c
-ctags ucb Makefile ctags.c
-expand ucb Makefile expand.c
-finger ucb Makefile finger.c
-fold ucb Makefile fold.c
-from ucb Makefile from.c
-fsplit ucb Makefile fsplit.c
-gcore ucb Makefile gcore.c
-groups ucb Makefile groups.c
-head ucb Makefile head.c
-last ucb Makefile last.c
-lastcomm ucb Makefile lastcomm.c
-leave ucb Makefile leave.c
-logger ucb Makefile logger.c
-man_prog ucb Makefile man.c
-mkstr ucb Makefile mkstr.c
-printenv ucb Makefile printenv.c
-quota ucb Makefile quota.c
-rcp ucb Makefile rcp.c
-rdate ucb Makefile rdate.c
-rlogin ucb Makefile rlogin.c
-rsh ucb Makefile rsh.c
-rup ucb Makefile rup.c
-ruptime ucb Makefile ruptime.c
-rusers ucb Makefile rusers.c
-rwho ucb Makefile rwho.c
-sccs ucb Makefile sccs.c
-script ucb Makefile script.c
-soelim ucb Makefile soelim.c
-strings ucb Makefile strings.c
-tail ucb Makefile tail.c
-tcopy ucb Makefile tcopy.c
-telnet ucb Makefile telnet.c
-ul ucb Makefile ul.c
-unexpand ucb Makefile unexpand.c
-unifdef ucb Makefile unifdef.c
-users ucb Makefile users.c
-vmstat ucb Makefile vmstat.c
-w ucb Makefile w.c
-wc ucb Makefile wc.c
-what ucb Makefile what.c
-whatis ucb Makefile whatis.c
-whereis ucb Makefile whereis.c
-whoami ucb Makefile whoami.c
-whois ucb Makefile whois.c
-xstr ucb Makefile xstr.c
-yes ucb Makefile yes.c
-
-# Sub-directories of "usr.bin"
-calendar usr.bin/calendar
-cflow usr.bin/cflow
-ctrace usr.bin/ctrace
-cxref usr.bin/cxref
-dc usr.bin/dc
-des usr.bin/des
-diff3 usr.bin/diff3
-sun_eqn usr.bin/eqn
-file usr.bin/file
-find usr.bin/find
-graph usr.bin/graph
-lex usr.bin/lex
-sun_neqn usr.bin/neqn
-sun_nroff usr.bin/nroff
-sun_plot usr.bin/plot
-prof usr.bin/prof
-refer usr.bin/refer
-rpcgen usr.bin/rpcgen
-spell usr.bin/spell
-sun_tbl usr.bin/tbl
-tip usr.bin/tip
-trace usr.bin/trace
-sun_troff usr.bin/troff
-uucp usr.bin/uucp
-xsend usr.bin/xsend
-yacc usr.bin/yacc
-
-# Programs that live in "usr.bin"
-basename usr.bin Makefile basename.c
-bc usr.bin Makefile bc.c
-cal usr.bin Makefile cal.c
-cb usr.bin Makefile cb.c
-checkeq usr.bin Makefile checkeq.c
-chkey usr.bin Makefile chkey.c
-click usr.bin Makefile click.c
-col usr.bin Makefile col.c
-comm usr.bin Makefile comm.c
-cpio usr.bin Makefile cpio.c
-crypt usr.bin Makefile crypt.c
-csplit usr.bin Makefile csplit.c
-cut usr.bin Makefile cut.c
-deroff usr.bin Makefile deroff.c
-egrep usr.bin Makefile egrep.c
-fgrep usr.bin Makefile fgrep.c
-getopt usr.bin Makefile getopt.c
-id usr.bin Makefile id.c
-installcmd usr.bin Makefile installcmd.c
-iostat usr.bin Makefile iostat.c
-ipcrm usr.bin Makefile ipcrm.c
-ipcs usr.bin Makefile ipcs.c
-join usr.bin Makefile join.c
-keylogin usr.bin Makefile keylogin.c
-logname usr.bin Makefile logname.c
-look usr.bin Makefile look.c
-mesg usr.bin Makefile mesg.c
-nl usr.bin Makefile nl.c
-pack usr.bin Makefile pack.c
-paste usr.bin Makefile paste.c
-ptx usr.bin Makefile ptx.c
-rev usr.bin Makefile rev.c
-screenblank usr.bin Makefile screenblank.c
-sdiff usr.bin Makefile sdiff.c
-sleep usr.bin Makefile sleep.c
-sort usr.bin Makefile sort.c
-spline usr.bin Makefile spline.c
-split usr.bin Makefile split.c
-sum usr.bin Makefile sum.c
-touch usr.bin Makefile touch.c
-tr usr.bin Makefile tr.c
-tsort usr.bin Makefile tsort.c
-tty usr.bin Makefile tty.c
-uniq usr.bin Makefile uniq.c
-units usr.bin Makefile units.c
-unpack usr.bin Makefile unpack.c
-xargs usr.bin Makefile xargs.c
-ypcat usr.bin Makefile ypcat.c
-ypmatch usr.bin Makefile ypmatch.c
-yppasswd usr.bin Makefile yppasswd.c
-ypwhich usr.bin Makefile ypwhich.c
-
-# Sub-directories of "usr.etc"
-automount usr.etc/automount
-c2convert usr.etc/c2convert
-config usr.etc/config
-cron usr.etc/cron
-eeprom usr.etc/eeprom
-etherfind usr.etc/etherfind
-format usr.etc/format
-htable usr.etc/htable
-implog usr.etc/implog
-in.ftpd -a usr.etc/in.ftpd ucb/ftp
-in.named usr.etc/in.named
-in.rwhod usr.etc/in.rwhod
-keyserv usr.etc/keyserv
-ndbootd usr.etc/ndbootd
-praudit usr.etc/praudit
-rexd usr.etc/rexd
-rpc.bootparamd usr.etc/rpc.bootparamd
-termcap usr.etc/termcap
-upgrade usr.etc/upgrade
-yp usr.etc/yp
-zic usr.etc/zic
-
-# Programs that live in "usr.etc"
-ac usr.etc Makefile ac.c
-accton usr.etc Makefile accton.c
-audit usr.etc Makefile audit.c
-auditd usr.etc Makefile auditd.c
-catman usr.etc Makefile catman.c
-chroot usr.etc Makefile chroot.c
-dcheck usr.etc Makefile dcheck.c
-devnm usr.etc Makefile devnm.c
-dumpfs usr.etc Makefile dumpfs.c
-edquota usr.etc Makefile edquota.c
-exportfs usr.etc Makefile exportfs.c
-foption usr.etc Makefile foption.c
-gettable usr.etc Makefile gettable.c
-grpck usr.etc Makefile grpck.c
-icheck usr.etc Makefile icheck.c
-in.comsat usr.etc Makefile in.comsat.c
-in.fingerd usr.etc Makefile in.fingerd.c
-in.rexecd usr.etc Makefile in.rexecd.c
-in.telnetd usr.etc Makefile in.telnetd.c
-in.tnamed usr.etc Makefile in.tnamed.c
-kgmon usr.etc Makefile kgmon.c
-link usr.etc Makefile link.c
-mkfile usr.etc Makefile mkfile.c
-mkproto usr.etc Makefile mkproto.c
-mount_lo usr.etc Makefile mount_lo.c
-ncheck usr.etc Makefile ncheck.c
-nfsstat usr.etc Makefile nfsstat.c
-ping usr.etc Makefile ping.c
-pwck usr.etc Makefile pwck.c
-quot usr.etc Makefile quot.c
-quotacheck usr.etc Makefile quotacheck.c
-quotaon usr.etc Makefile quotaon.c
-rarpd usr.etc Makefile rarpd.c
-repquota usr.etc Makefile repquota.c
-route usr.etc Makefile route.c
-rpc.etherd usr.etc Makefile rpc.etherd.c
-rpc.mountd usr.etc Makefile rpc.mountd.c
-rpc.pwdauthd usr.etc Makefile rpc.pwdauthd.c
-rpc.rquotad usr.etc Makefile rpc.rquotad.c
-rpc.rstatd usr.etc Makefile rpc.rstatd.c
-rpc.rusersd usr.etc Makefile rpc.rusersd.c
-rpc.rwalld usr.etc Makefile rpc.rwalld.c
-rpc.sprayd usr.etc Makefile rpc.sprayd.c
-rpc.yppasswdd usr.etc Makefile rpc.yppasswdd.c
-rpc.ypupdated usr.etc Makefile rpc.ypupdated.c
-rpcinfo usr.etc Makefile rpcinfo.c
-rwall usr.etc Makefile rwall.c
-sa usr.etc Makefile sa.c
-savecore usr.etc Makefile savecore.c
-showmount usr.etc Makefile showmount.c
-spray usr.etc Makefile spray.c
-swapon usr.etc Makefile swapon.c
-trpt usr.etc Makefile trpt.c
-tunefs usr.etc Makefile tunefs.c
-unlink usr.etc Makefile unlink.c
-
-# Sub-directories of "usr.lib"
-bb_count usr.lib/bb_count
-fixedwidthfonts usr.lib/fixedwidthfonts
-libcurses usr.lib/libcurses
-libdbm usr.lib/libdbm
-libg usr.lib/libg
-libkvm usr.lib/libkvm
-libln usr.lib/libln
-liblwp usr.lib/liblwp
-libm usr.lib/libm
-libmp usr.lib/libmp
-libpixrect usr.lib/libpixrect
-libplot usr.lib/libplot
-libresolv usr.lib/libresolv
-librpcsvc usr.lib/librpcsvc
-libtermlib usr.lib/libtermlib
-liby usr.lib/liby
-me usr.lib/me
-ms usr.lib/ms
-sendmail usr.lib/sendmail
-sun_tmac usr.lib/tmac
-vfont usr.lib/vfont
-
-# Programs that live in "usr.lib"
-getNAME usr.lib Makefile getNAME
-makekey usr.lib Makefile makekey
-
-# Sub-directories of "5bin"
-5diff3 5bin/diff3
-5m4 5bin/m4
-
-# Sub-directories of "5bin", but use sources from other places
-5cxref -a 5bin/cxref usr.bin/cxref
-5sed -a 5bin/sed bin/sed
-5lint -a 5bin/lint lang/pcc lang/lint
-
-# Programs that live in "5bin"
-5banner 5bin Makefile banner.c
-5cat 5bin Makefile cat.c
-5du 5bin Makefile du.c
-5echo 5bin Makefile echo.c
-5expr 5bin Makefile expr.c
-5ls 5bin Makefile ls.c
-5nohup 5bin Makefile nohup.c
-5od 5bin Makefile od.c
-5pg 5bin Makefile pg.c
-5pr 5bin Makefile pr.c
-5sum 5bin Makefile sum.c
-5tabs 5bin Makefile tabs.c
-5time 5bin Makefile time.c
-5tr 5bin Makefile tr.c
-5uname 5bin Makefile uname.c
-
-# Programs that live in "5bin", but use sources from other places
-5chmod -a 5bin/Makefile bin/chmod.c
-5date -a 5bin/Makefile bin/date.c
-5grep -a 5bin/Makefile bin/grep.c
-5stty -a 5bin/Makefile bin/stty.c
-5col -a 5bin/Makefile usr.bin/col.c
-5sort -a 5bin/Makefile usr.bin/sort.c
-5touch -a 5bin/Makefile usr.bin/touch.c
-
-# Sub-directories of "5lib"
-5compile 5lib/compile
-5libcurses 5lib/libcurses
-5liby 5lib/liby
-5terminfo 5lib/terminfo
-
-# Programs that live in "5lib"
-# NONE
diff --git a/gnu/usr.bin/cvs/examples/rcsinfo b/gnu/usr.bin/cvs/examples/rcsinfo
deleted file mode 100644
index c90e9e083704..000000000000
--- a/gnu/usr.bin/cvs/examples/rcsinfo
+++ /dev/null
@@ -1,18 +0,0 @@
-#
-#ident "@(#)cvs/examples:$Name: $:$Id: rcsinfo,v 1.3 1995/11/14 23:30:10 woods Exp $"
-#
-# The "rcsinfo" file is used to control templates with which the editor
-# is invoked on commit and import.
-#
-# The first entry on a line is a regular expression which is tested
-# against the directory that the change is being made to, relative to the
-# $CVSROOT. For the first match that is found, then the remainder of the
-# line is the name of the file that contains the template.
-#
-# If the repository name does not match any of the regular expressions in this
-# file, the "DEFAULT" line is used, if it is specified.
-#
-# If the name "ALL" appears as a regular expression it is always used
-# in addition to the first matching regex or "DEFAULT".
-#
-DEFAULT $CVSROOT/CVSROOT/rcstemplate
diff --git a/gnu/usr.bin/cvs/examples/rcstemplate b/gnu/usr.bin/cvs/examples/rcstemplate
deleted file mode 100644
index c9a2d1eb248c..000000000000
--- a/gnu/usr.bin/cvs/examples/rcstemplate
+++ /dev/null
@@ -1,7 +0,0 @@
-CVS:
-CVS: WARNING: You are commiting a change to the main source repository.
-CVS:
-CVS: This change will be immediately available to all other users
-CVS: of this repository! Please be sure your changes have been
-CVS: adequately tested.
-CVS:
diff --git a/gnu/usr.bin/cvs/examples/taginfo b/gnu/usr.bin/cvs/examples/taginfo
deleted file mode 100644
index 02de62b2808e..000000000000
--- a/gnu/usr.bin/cvs/examples/taginfo
+++ /dev/null
@@ -1,25 +0,0 @@
-#
-#ident "@(#)cvs/examples:$Name: $:$Id: taginfo,v 1.3 1995/11/14 23:27:52 woods Exp $"
-#
-# The "taginfo" file is used to control pre-tag checks.
-# The filter on the right is invoked with the following arguments:
-#
-# $1 -- tagname
-# $2 -- operation "add" for tag, "mov" for tag -F, and "del" for tag -d
-# $3 -- repository
-# $4-> file revision [file revision ...]
-#
-# A non-zero exit of the filter program will cause the tag to be aborted.
-#
-# The first entry on a line is a regular expression which is tested
-# against the directory that the change is being committed to, relative
-# to the $CVSROOT. For the first match that is found, then the remainder
-# of the line is the name of the filter to run.
-#
-# If the repository name does not match any of the regular expressions in this
-# file, the "DEFAULT" line is used, if it is specified.
-#
-# If the name "ALL" appears as a regular expression it is always used
-# in addition to the first matching regex or "DEFAULT".
-#
-DEFAULT $CVSROOT/CVSROOT/tag_logging_program
diff --git a/gnu/usr.bin/cvs/examples/unwrap b/gnu/usr.bin/cvs/examples/unwrap
deleted file mode 100644
index def05610f551..000000000000
--- a/gnu/usr.bin/cvs/examples/unwrap
+++ /dev/null
@@ -1,21 +0,0 @@
-#! /bin/sh
-#
-# unwrap - extract the combined package (created with wrap)
-#
-#ident "@(#)cvs/examples:$Name: $:$Id: unwrap,v 1.1 1995/11/14 23:20:30 woods Exp $"
-
-# move the file to a new name with an extension
-rm -rf $1.cvswrap
-mv $1 $1.cvswrap
-
-# untar the file
-
-if `gzip -t $1.cvswrap > /dev/null 2>&1`
-then
- gzcat -d $1.cvswrap | gnutar --preserve --sparse -x -f -
-else
- gnutar --preserve --sparse -x -f $1.cvswrap
-fi
-
-# remove the original
-rm -rf $1.cvswrap
diff --git a/gnu/usr.bin/cvs/examples/wrap b/gnu/usr.bin/cvs/examples/wrap
deleted file mode 100644
index b6a6a772c240..000000000000
--- a/gnu/usr.bin/cvs/examples/wrap
+++ /dev/null
@@ -1,21 +0,0 @@
-#! /bin/sh
-#
-# wrap - Combine a directory into a single tar package.
-#
-#ident "@(#)cvs/examples:$Name: $:$Id: wrap,v 1.1 1995/11/14 23:20:32 woods Exp $"
-
-# This script is always called with the current directory set to
-# where the file to be combined exists. but i may get called with a
-# path to where cvs first started executing. (this probably should be
-# fixed in cvs) so strip out all of the directory information. The
-# first sed expression will only work if the path has a leading /
-# if it doesn't the one in the if statement will work.
-DIRNAME=`echo $1 | sed -e "s|/.*/||g"`
-if [ ! -d $DIRNAME ] ; then
- DIRNAME=`echo $1 | sed -e "s|.*/||g"`
-fi
-#
-# Now tar up the directory but we now will only get a relative path
-# even if the user did a cvs commit . at the top.
-#
-gnutar --preserve --sparse -cf - $DIRNAME | gzip --no-name --best -c > $2
diff --git a/gnu/usr.bin/cvs/lib/ChangeLog b/gnu/usr.bin/cvs/lib/ChangeLog
deleted file mode 100644
index c8aa4a480682..000000000000
--- a/gnu/usr.bin/cvs/lib/ChangeLog
+++ /dev/null
@@ -1,335 +0,0 @@
-Mon Dec 4 10:54:04 1995 Jim Kingdon <kingdon@harvey.cyclic.com>
-
- * getdate.c: Remove #line directives. I know, this is a kludge,
- but Visual C++ 2.1 seems to require it (why, I have no idea. It
- has no trouble with the #line directives in getdate in CVS 1.6).
-
-Sat Nov 18 16:20:37 1995 Karl Fogel <kfogel@floss.cyclic.com>
-
- * rename.c: same.
-
- * mkdir.c: Use new macro `existence_error', instead of comparing
- errno to ENOENT directly.
-
- * system.h (existence_error): new macro, tries to portably ask if
- errno represents a file-not-exist error.
-
-Fri Nov 17 20:08:58 1995 Karl Fogel <kfogel@floss.cyclic.com>
-
- * system.h (NEED_DECOY_PERMISSIONS): moved this section to where
- it belongs, duh.
-
- * getdate.c: if STDC_HEADERS, then just include <stdlib.h> instead
- of declaring malloc() and realloc() to be char *.
-
- * system.h: ifdef NEED_DECOY_PERMISSIONS, then define the S_I*
- permission masks for USR, GRP, and OTH in terms of the simpler
- OS/2 masks.
-
-Wed Nov 15 15:36:03 1995 Karl Fogel <kfogel@floss.cyclic.com>
-
- * system.h: ifdef USE_OWN_TCPIP_H, then include "tcpip.h". Only
- OS/2 does this right now.
-
-Tue Nov 14 18:44:57 1995 Greg A. Woods <woods@most.weird.com>
-
- * getdate.c: OK, this one is from SunOS-4.1 yacc and may be more
- portable -- at least it compiles silently here! ;-)
-
-Mon Nov 13 03:53:45 1995 Karl Fogel <kfogel@floss.cyclic.com>
-
- * fnmatch.c: conform to 80 column standard (yes, I'm a pedant).
-
-Wed Nov 8 11:10:59 1995 Karl Fogel <kfogel@floss.cyclic.com>
-
- * system.h (STAT_MACROS): ifdef S_IFMT, then use it as before; but
- if it's not defined, then just do a single mask and assume
- acceptance any of non-zero result. Norbert, I trust you'll let me
- know if this is unsatisfactory. :-)
- Ifdef HAVE_SYS_UTIME_H, then include <sys/utime.h>. Only OS/2
- defines this right now.
-
-Wed Nov 8 13:18:51 1995 Norbert Kiesel <nk@col.sw-ley.de>
-
- * valloc.c: omit malloc declaration (it's already in system.h
- which is included and conflicts with <stdlib.h> on some
- systems).
-
-Tue Nov 7 19:38:48 1995 Norbert Kiesel <nk@col.sw-ley.de>
-
- * system.h (STAT_MACROS_BROKEN): undo previous change, because
- else all regular files will be identified as links (the mask for
- links is S_IFREG|S_IFCHR).
-
-Mon Nov 6 19:20:56 1995 Karl Fogel <kfogel@floss.cyclic.com>
-
- * system.h (STAT_MACROS_BROKEN): in defining the S_IF* macros,
- don't fold to 1 or 0 by first masking with S_IFMT; not all
- systems have that macro, and anyway it's only necessary that we
- return non-zero.
-
-Fri Oct 27 13:43:35 1995 Karl Fogel <kfogel@floss.cyclic.com>
-
- * save-cwd.c: use __PROTO instead of __P (see below).
-
- * getline.h (__PROTO): same as below.
-
- * save-cwd.h (__PROTO): replaces __P. New name, so don't ask if
- already defined. The conflict was that OS/2 w/ IBM C/C++ uses
- `__P' for something else, in <ctype.h> of all places.
-
- * system.h: do nothing about alloca ifdef ALLOCA_IN_STDLIB (see
- ../src/ChangeLog).
-
-Tue Oct 24 13:01:25 1995 Norbert Kiesel <nk@col.sw-ley.de>
-
- * wait.h: include sys/resource.h if available. This is needed at
- least under AIX-3.2 where <sys/wait.h> doesn't include it.
-
-Mon Oct 23 17:39:11 1995 Norbert Kiesel <nk@col.sw-ley.de>
-
- * valloc.c (valloc): change parameter definition
-
-Sun Oct 22 14:15:44 1995 Jim Meyering (meyering@comco.com)
-
- * getline.c, getline.h: New files.
- * Makefile.in (SOURCES, OBJECTS, HEADERS): Add getline.c, getline.o,
- and getline.h, respectively.
-
-Tue Oct 10 18:01:50 1995 Karl Fogel <kfogel@totoro.cyclic.com>
-
- * Makefile.in (cvs_srcdir): define cvs_srcdir to be ../src, then
- include it with -I so save_cwd.c can find error.h (for example).
-
-Sun Oct 8 12:27:57 1995 Peter Wemm <peter@haywire.DIALix.COM>
-
- * system.h: define POSIX_SIGNALS or BSD_SIGNALS if configure has
- located all the necessary functions for each "type".
- * sighandle.c: detect/use POSIX/BSD reliable signals (especially
- for blocking signals in critical sections). Helps prevent stray
- locks on interruption.
-
-Mon Oct 2 18:11:23 1995 Jim Blandy <jimb@totoro.cyclic.com>
-
- * system.h: Doc fix.
-
-Mon Oct 2 18:10:35 1995 Larry Jones <larry.jones@sdrc.com>
-
- * regex.c: compile 4.2 BSD compatible functions even when
- _POSIX_SOURCE is defined since we need them and we wouldn't be
- compiling this file unless they don't exist.
-
-Mon Oct 2 10:32:20 1995 Michael Finken <finken@conware.de>
-
- * strstr.c (strstr): new file and func.
-
- * Makefile.in (SOURCES): added strstr.c.
-
-Sun Oct 1 21:03:40 1995 Karl Fogel <kfogel@totoro.cyclic.com>
-
- * regex.c: reverted below change.
-
-Thu Sep 28 13:37:04 1995 Larry Jones <larry.jones@sdrc.com>
-
- * regexp.c: check for ISC.
-
-Thu Sep 7 19:18:00 1995 Jim Blandy <jimb@cyclic.com>
-
- * save-cwd.c: #include <direct.h> and <io.h>, on systems that
- have them.
-
- * getopt.c (_getopt_internal): Cast the return value of strlen,
- which is unsigned, before comparing it with the difference between
- two pointers, which is unsigned.
-
-Thu Aug 31 11:31:42 1995 Jim Blandy <jimb@totoro.cyclic.com>
-
- * getdate.y [STDC_HEADERS]: #include <stdlib.h>, for abort.
- [HAVE_ALLOCA_H]: #include <alloca.h>, for alloca on Windows NT.
-
-Wed Aug 30 18:48:44 1995 Jim Blandy <jimb@totoro.cyclic.com>
-
- * system.h [HAVE_IO_H]: #include <io.h>, for Windows NT.
- [HAVE_DIRECT_H]: #include <direct.h>, for Windows NT.
- (CVS_MKDIR, FOLD_FN_CHAR, fnfold, fncmp, ISDIRSEP, OPEN_BINARY,
- FOPEN_BINARY_READ, FOPEN_BINARY_WRITE): New macros/functions, for
- use in system-sensitive code.
-
- * regex.c (re_set_registers): start and end are pointers, not
- integers. Cast the initializing value appropriately.
-
- * getopt.c [HAVE_STRING_H]: #include <string.h>, to avoid
- warnings.
-
- * fnmatch.c (FOLD_FN_CHAR): Give this a dummy #definition if
- config.h didn't #define it.
- (fnmatch): Pass filename characters through FOLD_FN_CHAR before
- comparing them.
-
- * argmatch.c: #include <sys/types.h>.
- (argmatch): Declare arglen to be a size_t, rather than an int,
- to avoid signed/unsigned comparison "problems".
-
- * .cvsignore: Remove getdate.c from this file. We want to
- distribute it, for systems that don't have a Yacc-equivalent
- installed (like Windows NT).
-
-Sat Aug 19 22:00:51 1995 Jim Blandy <jimb@totoro.cyclic.com>
-
- * error.c: Don't #define CVS_SUPPORT here. config.h takes care of
- that for us.
- [CVS_SUPPORT] (error_use_protocol): New variable, with apology.
- (error): If error_use_protocol is set, report errors using the
- client/server protocol.
- * error.h [CVS_SUPPORT]: Extern decl for error_use_protocol.
-
-Fri Aug 4 00:01:24 1995 Jim Meyering (meyering@comco.com)
-
- * xgetwd.c: Don't declare free. A K&R style declaration gets
- a conflict on some Sun systems when compiling with acc.
-
- * save-cwd.c: New file.
- * save-cwd.h: New file.
- * Makefile.in (SOURCES): Add save-cwd.c
- (OBJECTS): Add save-cwd.o.
- (HEADERS): Add save-cwd.h.
-
-Thu Aug 3 00:55:54 1995 Jim Meyering (meyering@comco.com)
-
- * error.h: New file.
- * Makefile.in (HEADERS): Add error.h.
-
-Sat Jul 29 15:53:55 1995 James Kingdon <kingdon@harvey.cyclic.com>
-
- * Makefile.in (SOURCES): Add getdate.c.
-
-Thu Jul 27 09:11:41 1995 Robert Lipe <robertl@rjlhome.arnet.com>
-
- * system.h: Check for PATHSIZE before falling back to _POSIX_PATH_MAX.
-
-Thu Jul 20 12:38:03 1995 James Kingdon <kingdon@harvey.cyclic.com>
-
- * error.c: Instead of calling cvs functions to clean up, allow cvs
- to register a callback via error_set_cleanup. Avoids hassles with
- include files and SERVER_SUPPORT and so on.
-
-Tue Jul 18 21:18:00 1995 Jim Blandy <jimb@cyclic.com>
-
- * system.h: Include <sys/param.h> only if HAVE_SYS_PARAM_H
- is #defined. We've added a test to configure.in to #define this
- on most systems.
-
-Thu Jul 13 11:22:21 1995 Jim Meyering (meyering@comco.com)
-
- * xgetwd.c: New file.
- * Makefile.in (SOURCES): Add xgetwd.c
- (OBJECTS): Add xgetwd.o.
-
-Wed Jul 12 09:18:49 1995 Jim Meyering (meyering@comco.com)
-
- * Makefile.in (OBJECTS): Remove fnmatch.o. Now configure adds it
- to LIBOBJS when necessary.
-
-Fri Jun 30 16:27:18 1995 James Kingdon <kingdon@harvey.cyclic.com>
-
- * rename.c (rename): If MVDIR is not defined, just give an error
- on attempt to rename a directory.
-
-Thu Jun 29 00:46:31 1995 James Kingdon <kingdon@harvey.cyclic.com>
-
- * system.h: Check HAVE_SYS_TIMEB_H not non-existent HAVE_TIMEB_H.
-
- * system.h: Don't define alloca if it is already defined.
-
-Wed Jun 28 15:24:51 1995 James Kingdon <kingdon@harvey.cyclic.com>
-
- * system.h: If NeXT, define utimbuf ourself.
-
-Mon May 29 22:32:40 1995 J.T. Conklin <jtc@rtl.cygnus.com>
-
- * system.h: Handle time and directory headers as recommended in
- the autoconf manual.
- Undefine the S_FOO() macros if STAT_MACROS_BROKEN is set.
- Don't define mode_t, as it is handled by config.h.
-
-Sat May 27 08:46:00 1995 Jim Meyering (meyering@comco.com)
-
- * Makefile.in (Makefile): Regenerate only Makefile in current
- directory when Makefile.in is out of date. Depend on ../config.status.
-
-Fri Apr 28 22:49:25 1995 Jim Blandy <jimb@totoro.bio.indiana.edu>
-
- * Makefile.in (SOURCES, OBJECTS): Updated.
- (HEADERS): New variable.
- (DISTFILES): Updated.
- (dist-dir): Renamed from dist; changed to work with DISTDIR
- variable passed from parent.
-
-Wed Feb 8 06:37:53 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
-
- * system.h (S_IRUSR et al): Define if not already defined.
-
- * waitpid.c [HAVE_CONFIG_H]: Include "config.h".
- (ualloc): Return OLDPTR rather than running off the end.
-
-Mon Aug 22 22:48:19 1994 Ken Raeburn (raeburn@kr-pc.cygnus.com)
-
- * error.c (strerror): Replaced conditional static definition
- (always used, since the condition variable was never set) with an
- extern declaration, since it's provided by libc or strerror.c.
-
-Wed Aug 10 14:54:25 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
-
- * Makefile.in (SOURCES): Add waitpid.c.
- * waitpid.c: New file.
-
-Tue Aug 9 16:00:12 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
-
- * md5.h (uint32): If SIZEOF_LONG isn't 4, don't define this to be
- "unsigned long"; try SIZEOF_INT and "unsigned int", otherwise
- complain.
-
- * md5.c: Include config.h.
- (const): Don't bother defining here, config.h should take care of
- it.
-
- * valloc.c (malloc): Declare.
-
-Fri Jul 15 12:57:20 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
-
- * getopt.c: Do not include <stdlib.h> unless __GNU_LIBRARY__ is
- defined. On Irix 5.2, <stdlib.h> includes <getopt.h>, which
- causes a multiple definition of struct option.
-
-Fri Jul 8 10:04:59 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
-
- * md5.h, md5.c: Remove ANSI-isms.
-
-Thu Jul 7 20:24:18 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
-
- * md5.h, md5.c: New files.
- * Makefile.in (SOURCES): Add md5.c.
- (OBJECTS): Add md5.o.
- (DISTFILES): Add md5.h.
- (md5.o): New target; depend upon md5.h.
-
-Fri May 27 18:15:34 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
-
- * valloc.c: New file.
-
-Tue May 17 08:18:26 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
-
- * error.c (error, fperror): If server_active, call server_cleanup
- as well as Lock_Cleanup.
-
-Thu Jan 6 13:45:04 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
-
- * system.h: Fix Dec 27 change to work correctly. Makes Sep 9
- change unnecessary, so backed that one out. Never define PATH_MAX
- in terms of pathconf, because that doesn't produce a constant, and
- PATH_MAX is used to set array sizes.
-
-Mon Dec 27 14:22:07 1993 Mark Eichin (eichin@cygnus.com)
-
- * system.h: don't touch PATH_MAX or MAXPATHLEN if *both* of them
- are already defined, as one may be defined in terms of the other.
diff --git a/gnu/usr.bin/cvs/lib/Makefile b/gnu/usr.bin/cvs/lib/Makefile
deleted file mode 100644
index cf3f20fd2802..000000000000
--- a/gnu/usr.bin/cvs/lib/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
-LIB = cvs
-
-CFLAGS += -I${.CURDIR} -I${.CURDIR}/../cvs -DFTIME_MISSING -DHAVE_TIMEZONE
-
-SRCS = argmatch.c error.c getopt.c sighandle.c strippath.c stripslash.c yesno.c \
- getdate.y fnmatch.c regex.c subr.c myndbm.c hash.c
-
-.include <bsd.lib.mk>
diff --git a/gnu/usr.bin/cvs/lib/alloca.c b/gnu/usr.bin/cvs/lib/alloca.c
deleted file mode 100644
index b57659e418c4..000000000000
--- a/gnu/usr.bin/cvs/lib/alloca.c
+++ /dev/null
@@ -1,191 +0,0 @@
-/*
- alloca -- (mostly) portable public-domain implementation -- D A Gwyn
-
- last edit: 86/05/30 rms
- include config.h, since on VMS it renames some symbols.
- Use xmalloc instead of malloc.
-
- This implementation of the PWB library alloca() function,
- which is used to allocate space off the run-time stack so
- that it is automatically reclaimed upon procedure exit,
- was inspired by discussions with J. Q. Johnson of Cornell.
-
- It should work under any C implementation that uses an
- actual procedure stack (as opposed to a linked list of
- frames). There are some preprocessor constants that can
- be defined when compiling for your specific system, for
- improved efficiency; however, the defaults should be okay.
-
- The general concept of this implementation is to keep
- track of all alloca()-allocated blocks, and reclaim any
- that are found to be deeper in the stack than the current
- invocation. This heuristic does not reclaim storage as
- soon as it becomes invalid, but it will do so eventually.
-
- As a special case, alloca(0) reclaims storage without
- allocating any. It is a good idea to use alloca(0) in
- your main control loop, etc. to force garbage collection.
-*/
-#ifndef lint
-static char SCCSid[] = "@(#)alloca.c 1.1"; /* for the "what" utility */
-#endif
-
-#if defined(emacs) || defined(HAVE_CONFIG_H)
-#include "config.h"
-#ifdef static
-/* actually, only want this if static is defined as ""
- -- this is for usg, in which emacs must undefine static
- in order to make unexec workable
- */
-#ifndef STACK_DIRECTION
-you
-lose
--- must know STACK_DIRECTION at compile-time
-#endif /* STACK_DIRECTION undefined */
-#endif /* static */
-#endif /* emacs || HAVE_CONFIG_H*/
-
-#if __STDC__
-typedef void *pointer; /* generic pointer type */
-#else
-typedef char *pointer; /* generic pointer type */
-#endif
-
-#define NULL 0 /* null pointer constant */
-
-extern void free();
-extern pointer xmalloc();
-
-/*
- Define STACK_DIRECTION if you know the direction of stack
- growth for your system; otherwise it will be automatically
- deduced at run-time.
-
- STACK_DIRECTION > 0 => grows toward higher addresses
- STACK_DIRECTION < 0 => grows toward lower addresses
- STACK_DIRECTION = 0 => direction of growth unknown
-*/
-
-#ifndef STACK_DIRECTION
-#define STACK_DIRECTION 0 /* direction unknown */
-#endif
-
-#if STACK_DIRECTION != 0
-
-#define STACK_DIR STACK_DIRECTION /* known at compile-time */
-
-#else /* STACK_DIRECTION == 0; need run-time code */
-
-static int stack_dir; /* 1 or -1 once known */
-#define STACK_DIR stack_dir
-
-static void
-find_stack_direction (/* void */)
-{
- static char *addr = NULL; /* address of first
- `dummy', once known */
- auto char dummy; /* to get stack address */
-
- if (addr == NULL)
- { /* initial entry */
- addr = &dummy;
-
- find_stack_direction (); /* recurse once */
- }
- else /* second entry */
- if (&dummy > addr)
- stack_dir = 1; /* stack grew upward */
- else
- stack_dir = -1; /* stack grew downward */
-}
-
-#endif /* STACK_DIRECTION == 0 */
-
-/*
- An "alloca header" is used to:
- (a) chain together all alloca()ed blocks;
- (b) keep track of stack depth.
-
- It is very important that sizeof(header) agree with malloc()
- alignment chunk size. The following default should work okay.
-*/
-
-#ifndef ALIGN_SIZE
-#define ALIGN_SIZE sizeof(double)
-#endif
-
-typedef union hdr
-{
- char align[ALIGN_SIZE]; /* to force sizeof(header) */
- struct
- {
- union hdr *next; /* for chaining headers */
- char *deep; /* for stack depth measure */
- } h;
-} header;
-
-/*
- alloca( size ) returns a pointer to at least `size' bytes of
- storage which will be automatically reclaimed upon exit from
- the procedure that called alloca(). Originally, this space
- was supposed to be taken from the current stack frame of the
- caller, but that method cannot be made to work for some
- implementations of C, for example under Gould's UTX/32.
-*/
-
-static header *last_alloca_header = NULL; /* -> last alloca header */
-
-pointer
-alloca (size) /* returns pointer to storage */
- unsigned size; /* # bytes to allocate */
-{
- auto char probe; /* probes stack depth: */
- register char *depth = &probe;
-
-#if STACK_DIRECTION == 0
- if (STACK_DIR == 0) /* unknown growth direction */
- find_stack_direction ();
-#endif
-
- /* Reclaim garbage, defined as all alloca()ed storage that
- was allocated from deeper in the stack than currently. */
-
- {
- register header *hp; /* traverses linked list */
-
- for (hp = last_alloca_header; hp != NULL;)
- if (STACK_DIR > 0 && hp->h.deep > depth
- || STACK_DIR < 0 && hp->h.deep < depth)
- {
- register header *np = hp->h.next;
-
- free ((pointer) hp); /* collect garbage */
-
- hp = np; /* -> next header */
- }
- else
- break; /* rest are not deeper */
-
- last_alloca_header = hp; /* -> last valid storage */
- }
-
- if (size == 0)
- return NULL; /* no allocation required */
-
- /* Allocate combined header + user data storage. */
-
- {
- register pointer new = xmalloc (sizeof (header) + size);
- /* address of header */
-
- ((header *)new)->h.next = last_alloca_header;
- ((header *)new)->h.deep = depth;
-
- last_alloca_header = (header *)new;
-
- /* User storage begins just after header. */
-
- return (pointer)((char *)new + sizeof(header));
- }
-}
-
diff --git a/gnu/usr.bin/cvs/lib/argmatch.c b/gnu/usr.bin/cvs/lib/argmatch.c
deleted file mode 100644
index cc360ee1d940..000000000000
--- a/gnu/usr.bin/cvs/lib/argmatch.c
+++ /dev/null
@@ -1,89 +0,0 @@
-/* argmatch.c -- find a match for a string in an array
- Copyright (C) 1990 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
-
-/* Written by David MacKenzie <djm@ai.mit.edu> */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <sys/types.h>
-
-#include <stdio.h>
-#ifdef STDC_HEADERS
-#include <string.h>
-#endif
-
-extern char *program_name;
-
-/* If ARG is an unambiguous match for an element of the
- null-terminated array OPTLIST, return the index in OPTLIST
- of the matched element, else -1 if it does not match any element
- or -2 if it is ambiguous (is a prefix of more than one element). */
-
-int
-argmatch (arg, optlist)
- char *arg;
- char **optlist;
-{
- int i; /* Temporary index in OPTLIST. */
- size_t arglen; /* Length of ARG. */
- int matchind = -1; /* Index of first nonexact match. */
- int ambiguous = 0; /* If nonzero, multiple nonexact match(es). */
-
- arglen = strlen (arg);
-
- /* Test all elements for either exact match or abbreviated matches. */
- for (i = 0; optlist[i]; i++)
- {
- if (!strncmp (optlist[i], arg, arglen))
- {
- if (strlen (optlist[i]) == arglen)
- /* Exact match found. */
- return i;
- else if (matchind == -1)
- /* First nonexact match found. */
- matchind = i;
- else
- /* Second nonexact match found. */
- ambiguous = 1;
- }
- }
- if (ambiguous)
- return -2;
- else
- return matchind;
-}
-
-/* Error reporting for argmatch.
- KIND is a description of the type of entity that was being matched.
- VALUE is the invalid value that was given.
- PROBLEM is the return value from argmatch. */
-
-void
-invalid_arg (kind, value, problem)
- char *kind;
- char *value;
- int problem;
-{
- fprintf (stderr, "%s: ", program_name);
- if (problem == -1)
- fprintf (stderr, "invalid");
- else /* Assume -2. */
- fprintf (stderr, "ambiguous");
- fprintf (stderr, " %s `%s'\n", kind, value);
-}
diff --git a/gnu/usr.bin/cvs/lib/config.h b/gnu/usr.bin/cvs/lib/config.h
deleted file mode 100644
index ce06c629b7be..000000000000
--- a/gnu/usr.bin/cvs/lib/config.h
+++ /dev/null
@@ -1,233 +0,0 @@
-/* config.h. Generated automatically by configure. */
-/* config.h.in. Generated automatically from configure.in by autoheader. */
-
-/* Define if on AIX 3.
- System headers sometimes define this.
- We just want to avoid a redefinition error message. */
-#ifndef _ALL_SOURCE
-/* #undef _ALL_SOURCE */
-#endif
-
-/* Define if using alloca.c. */
-/* #undef C_ALLOCA */
-
-/* Define if type char is unsigned and you are not using gcc. */
-#ifndef __CHAR_UNSIGNED__
-/* #undef __CHAR_UNSIGNED__ */
-#endif
-
-/* Define to empty if the keyword does not work. */
-/* #undef const */
-
-/* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems.
- This function is required for alloca.c support on those systems. */
-/* #undef CRAY_STACKSEG_END */
-
-/* Define to `int' if <sys/types.h> doesn't define. */
-/* #undef gid_t */
-
-/* Define if you have alloca, as a function or macro. */
-#define HAVE_ALLOCA 1
-
-/* Define if you have <alloca.h> and it should be used (not on Ultrix). */
-/* #undef HAVE_ALLOCA_H */
-
-/* Define if you support file names longer than 14 characters. */
-#define HAVE_LONG_FILE_NAMES 1
-
-/* Define if you have <sys/wait.h> that is POSIX.1 compatible. */
-#define HAVE_SYS_WAIT_H 1
-
-/* Define if utime(file, NULL) sets file's timestamp to the present. */
-#define HAVE_UTIME_NULL 1
-
-/* Define as __inline if that's what the C compiler calls it. */
-/* #undef inline */
-
-/* Define if on MINIX. */
-/* #undef _MINIX */
-
-/* Define to `int' if <sys/types.h> doesn't define. */
-/* #undef mode_t */
-
-/* Define to `int' if <sys/types.h> doesn't define. */
-/* #undef pid_t */
-
-/* Define if the system does not provide POSIX.1 features except
- with this defined. */
-/* #undef _POSIX_1_SOURCE */
-
-/* Define if you need to in order for stat and other things to work. */
-/* #undef _POSIX_SOURCE */
-
-/* Define as the return type of signal handlers (int or void). */
-#define RETSIGTYPE void
-
-/* Define to `unsigned' if <sys/types.h> doesn't define. */
-/* #undef size_t */
-
-/* If using the C implementation of alloca, define if you know the
- direction of stack growth for your system; otherwise it will be
- automatically deduced at run-time.
- STACK_DIRECTION > 0 => grows toward higher addresses
- STACK_DIRECTION < 0 => grows toward lower addresses
- STACK_DIRECTION = 0 => direction of growth unknown
- */
-/* #undef STACK_DIRECTION */
-
-/* Define if the `S_IS*' macros in <sys/stat.h> do not work properly. */
-/* #undef STAT_MACROS_BROKEN */
-
-/* Define if you have the ANSI C header files. */
-#define STDC_HEADERS 1
-
-/* Define if you can safely include both <sys/time.h> and <time.h>. */
-#define TIME_WITH_SYS_TIME 1
-
-/* Define to `int' if <sys/types.h> doesn't define. */
-/* #undef uid_t */
-
-/* Define if you have MIT Kerberos version 4 available. */
-/* #undef HAVE_KERBEROS */
-
-/* Define if you want CVS to be able to be a remote repository client. */
-#define CLIENT_SUPPORT 1
-
-/* Define if you want CVS to be able to serve repositories to remote
- clients. */
-#define SERVER_SUPPORT 1
-
-/* the path to the gnu diff program on your system */
-#define DIFF "/usr/bin/diff -a"
-
-/* The number of bytes in a int. */
-#define SIZEOF_INT 4
-
-/* The number of bytes in a long. */
-#define SIZEOF_LONG 4
-
-/* Define if you have the connect function. */
-/* #undef HAVE_CONNECT */
-
-/* Define if you have the fchdir function. */
-#define HAVE_FCHDIR 1
-
-/* Define if you have the fchmod function. */
-#define HAVE_FCHMOD 1
-
-/* Define if you have the fsync function. */
-#define HAVE_FSYNC 1
-
-/* Define if you have the ftime function. */
-/* #undef HAVE_FTIME */
-
-/* Define if you have the ftruncate function. */
-#define HAVE_FTRUNCATE 1
-
-/* Define if you have the getpagesize function. */
-#define HAVE_GETPAGESIZE 1
-
-/* Define if you have the krb_get_err_text function. */
-/* #undef HAVE_KRB_GET_ERR_TEXT */
-
-/* Define if you have the mkfifo function. */
-#define HAVE_MKFIFO 1
-
-/* Define if you have the putenv function. */
-#define HAVE_PUTENV 1
-
-/* Define if you have the setvbuf function. */
-#define HAVE_SETVBUF 1
-
-/* Define if you have the sigaction function. */
-#define HAVE_SIGACTION 1
-
-/* Define if you have the sigblock function. */
-#define HAVE_SIGBLOCK 1
-
-/* Define if you have the sigprocmask function. */
-#define HAVE_SIGPROCMASK 1
-
-/* Define if you have the sigsetmask function. */
-#define HAVE_SIGSETMASK 1
-
-/* Define if you have the sigvec function. */
-#define HAVE_SIGVEC 1
-
-/* Define if you have the timezone function. */
-#define HAVE_TIMEZONE 1
-
-/* Define if you have the vfork function. */
-#define HAVE_VFORK 1
-
-/* Define if you have the vprintf function. */
-#define HAVE_VPRINTF 1
-
-/* Define if you have the <direct.h> header file. */
-/* #undef HAVE_DIRECT_H */
-
-/* Define if you have the <dirent.h> header file. */
-#define HAVE_DIRENT_H 1
-
-/* Define if you have the <errno.h> header file. */
-#define HAVE_ERRNO_H 1
-
-/* Define if you have the <fcntl.h> header file. */
-#define HAVE_FCNTL_H 1
-
-/* Define if you have the <io.h> header file. */
-/* #undef HAVE_IO_H */
-
-/* Define if you have the <memory.h> header file. */
-#define HAVE_MEMORY_H 1
-
-/* Define if you have the <ndbm.h> header file. */
-#define HAVE_NDBM_H 1
-
-/* Define if you have the <ndir.h> header file. */
-/* #undef HAVE_NDIR_H */
-
-/* Define if you have the <string.h> header file. */
-#define HAVE_STRING_H 1
-
-/* Define if you have the <sys/bsdtypes.h> header file. */
-/* #undef HAVE_SYS_BSDTYPES_H */
-
-/* Define if you have the <sys/dir.h> header file. */
-/* #undef HAVE_SYS_DIR_H */
-
-/* Define if you have the <sys/ndir.h> header file. */
-/* #undef HAVE_SYS_NDIR_H */
-
-/* Define if you have the <sys/param.h> header file. */
-#define HAVE_SYS_PARAM_H 1
-
-/* Define if you have the <sys/resource.h> header file. */
-#define HAVE_SYS_RESOURCE_H 1
-
-/* Define if you have the <sys/select.h> header file. */
-#define HAVE_SYS_SELECT_H 1
-
-/* Define if you have the <sys/time.h> header file. */
-#define HAVE_SYS_TIME_H 1
-
-/* Define if you have the <sys/timeb.h> header file. */
-#define HAVE_SYS_TIMEB_H 1
-
-/* Define if you have the <unistd.h> header file. */
-#define HAVE_UNISTD_H 1
-
-/* Define if you have the <utime.h> header file. */
-#define HAVE_UTIME_H 1
-
-/* Define if you have the inet library (-linet). */
-/* #undef HAVE_LIBINET */
-
-/* Define if you have the nsl library (-lnsl). */
-/* #undef HAVE_LIBNSL */
-
-/* Define if you have the nsl_s library (-lnsl_s). */
-/* #undef HAVE_LIBNSL_S */
-
-/* Define if you have the socket library (-lsocket). */
-/* #undef HAVE_LIBSOCKET */
diff --git a/gnu/usr.bin/cvs/lib/dup2.c b/gnu/usr.bin/cvs/lib/dup2.c
deleted file mode 100644
index 19743830ca6e..000000000000
--- a/gnu/usr.bin/cvs/lib/dup2.c
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- dup2 -- 7th Edition UNIX system call emulation for UNIX System V
-
- last edit: 11-Feb-1987 D A Gwyn
-*/
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <errno.h>
-#include <fcntl.h>
-
-extern int close(), fcntl();
-
-int
-dup2( oldfd, newfd )
- int oldfd; /* already-open file descriptor */
- int newfd; /* desired duplicate descriptor */
-{
- register int ret; /* for fcntl() return value */
- register int save; /* for saving entry errno */
-
- if ( oldfd == newfd )
- return oldfd; /* be careful not to close() */
-
- save = errno; /* save entry errno */
- (void) close( newfd ); /* in case newfd is open */
- /* (may have just clobbered the original errno value) */
-
- ret = fcntl( oldfd, F_DUPFD, newfd ); /* dupe it */
-
- if ( ret >= 0 )
- errno = save; /* restore entry errno */
- else /* fcntl() returned error */
- if ( errno == EINVAL )
- errno = EBADF; /* we think of everything */
-
- return ret; /* return file descriptor */
-}
diff --git a/gnu/usr.bin/cvs/lib/error.c b/gnu/usr.bin/cvs/lib/error.c
deleted file mode 100644
index 0398103f434a..000000000000
--- a/gnu/usr.bin/cvs/lib/error.c
+++ /dev/null
@@ -1,188 +0,0 @@
-/* error.c -- error handler for noninteractive utilities
- Copyright (C) 1990-1992 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
-
-/* David MacKenzie */
-/* Brian Berliner added support for CVS */
-
-#include "cvs.h"
-
-#ifndef lint
-static const char rcsid[] = "$CVSid: @(#)error.c 1.13 94/09/30 $";
-USE(rcsid);
-#endif /* not lint */
-
-#include <stdio.h>
-
-/* If non-zero, error will use the CVS protocol to stdout to report error
- messages. This will only be set in the CVS server parent process;
- most other code is run via do_cvs_command, which forks off a child
- process and packages up its stderr in the protocol. */
-int error_use_protocol;
-
-#ifdef HAVE_VPRINTF
-
-#if __STDC__
-#include <stdarg.h>
-#define VA_START(args, lastarg) va_start(args, lastarg)
-#else
-#include <varargs.h>
-#define VA_START(args, lastarg) va_start(args)
-#endif
-
-#else
-
-#ifdef HAVE_DOPRNT
-#define va_alist args
-#define va_dcl int args;
-#else
-#define va_alist a1, a2, a3, a4, a5, a6, a7, a8
-#define va_dcl char *a1, *a2, *a3, *a4, *a5, *a6, *a7, *a8;
-#endif
-
-#endif
-
-#if STDC_HEADERS
-#include <stdlib.h>
-#include <string.h>
-#else
-#if __STDC__
-void exit(int status);
-#else
-void exit ();
-#endif /* __STDC__ */
-#endif
-
-extern char *strerror ();
-
-typedef void (*fn_returning_void) ();
-
-/* Function to call before exiting. */
-static fn_returning_void cleanup_fn;
-
-fn_returning_void
-error_set_cleanup (arg)
- fn_returning_void arg;
-{
- fn_returning_void retval = cleanup_fn;
- cleanup_fn = arg;
- return retval;
-}
-
-/* Print the program name and error message MESSAGE, which is a printf-style
- format string with optional args.
- If ERRNUM is nonzero, print its corresponding system error message.
- Exit with status STATUS if it is nonzero. */
-/* VARARGS */
-void
-#if defined (HAVE_VPRINTF) && __STDC__
-error (int status, int errnum, const char *message, ...)
-#else
-error (status, errnum, message, va_alist)
- int status;
- int errnum;
- const char *message;
- va_dcl
-#endif
-{
- FILE *out = stderr;
- extern char *program_name;
- extern char *command_name;
-#ifdef HAVE_VPRINTF
- va_list args;
-#endif
-
- if (error_use_protocol)
- {
- out = stdout;
- printf ("E ");
- }
-
- if (command_name && *command_name)
- if (status)
- fprintf (out, "%s [%s aborted]: ", program_name, command_name);
- else
- fprintf (out, "%s %s: ", program_name, command_name);
- else
- fprintf (out, "%s: ", program_name);
-#ifdef HAVE_VPRINTF
- VA_START (args, message);
- vfprintf (out, message, args);
- va_end (args);
-#else
-#ifdef HAVE_DOPRNT
- _doprnt (message, &args, out);
-#else
- fprintf (out, message, a1, a2, a3, a4, a5, a6, a7, a8);
-#endif
-#endif
- if (errnum)
- fprintf (out, ": %s", strerror (errnum));
- putc ('\n', out);
- fflush (out);
- if (status)
- {
- if (cleanup_fn)
- (*cleanup_fn) ();
- exit (status);
- }
-}
-
-/* Print the program name and error message MESSAGE, which is a printf-style
- format string with optional args to the file specified by FP.
- If ERRNUM is nonzero, print its corresponding system error message.
- Exit with status STATUS if it is nonzero. */
-/* VARARGS */
-void
-#if defined (HAVE_VPRINTF) && __STDC__
-fperror (FILE *fp, int status, int errnum, char *message, ...)
-#else
-fperror (fp, status, errnum, message, va_alist)
- FILE *fp;
- int status;
- int errnum;
- char *message;
- va_dcl
-#endif
-{
- extern char *program_name;
-#ifdef HAVE_VPRINTF
- va_list args;
-#endif
-
- fprintf (fp, "%s: ", program_name);
-#ifdef HAVE_VPRINTF
- VA_START (args, message);
- vfprintf (fp, message, args);
- va_end (args);
-#else
-#ifdef HAVE_DOPRNT
- _doprnt (message, &args, fp);
-#else
- fprintf (fp, message, a1, a2, a3, a4, a5, a6, a7, a8);
-#endif
-#endif
- if (errnum)
- fprintf (fp, ": %s", strerror (errnum));
- putc ('\n', fp);
- fflush (fp);
- if (status)
- {
- if (cleanup_fn)
- (*cleanup_fn) ();
- exit (status);
- }
-}
diff --git a/gnu/usr.bin/cvs/lib/error.h b/gnu/usr.bin/cvs/lib/error.h
deleted file mode 100644
index 7d4f5353797a..000000000000
--- a/gnu/usr.bin/cvs/lib/error.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/* error.h -- declaration for error-reporting function
- Copyright (C) 1995 Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
-
-#ifndef _error_h_
-#define _error_h_
-
-#ifndef __attribute__
-/* This feature is available in gcc versions 2.5 and later. */
-# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5) || __STRICT_ANSI__
-# define __attribute__(Spec) /* empty */
-# endif
-/* The __-protected variants of `format' and `printf' attributes
- are accepted by gcc versions 2.6.4 (effectively 2.7) and later. */
-# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7)
-# define __format__ format
-# define __printf__ printf
-# endif
-#endif
-
-#if __STDC__
-void error (int, int, const char *, ...) \
- __attribute__ ((__format__ (__printf__, 3, 4)));
-#else
-void error ();
-#endif
-
-/* If non-zero, error will use the CVS protocol to report error
- messages. This will only be set in the CVS server parent process;
- most other code is run via do_cvs_command, which forks off a child
- process and packages up its stderr in the protocol. */
-extern int error_use_protocol;
-
-#endif /* _error_h_ */
diff --git a/gnu/usr.bin/cvs/lib/filesubr.c b/gnu/usr.bin/cvs/lib/filesubr.c
deleted file mode 100644
index 3a5269104266..000000000000
--- a/gnu/usr.bin/cvs/lib/filesubr.c
+++ /dev/null
@@ -1,640 +0,0 @@
-/* filesubr.c --- subroutines for dealing with files
- Jim Blandy <jimb@cyclic.com>
-
- This file is part of GNU CVS.
-
- GNU CVS is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License as published by the
- Free Software Foundation; either version 2, or (at your option) any
- later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
-
-/* These functions were moved out of subr.c because they need different
- definitions under operating systems (like, say, Windows NT) with different
- file system semantics. */
-
-#include "cvs.h"
-
-#ifndef lint
-static const char rcsid[] = "$CVSid:$";
-USE(rcsid);
-#endif
-
-/*
- * I don't know of a convenient way to test this at configure time, or else
- * I'd certainly do it there.
- */
-#if defined(NeXT)
-#define LOSING_TMPNAM_FUNCTION
-#endif
-
-static int deep_remove_dir PROTO((const char *path));
-
-/*
- * Copies "from" to "to".
- */
-void
-copy_file (from, to)
- const char *from;
- const char *to;
-{
- struct stat sb;
- struct utimbuf t;
- int fdin, fdout;
-
- if (trace)
-#ifdef SERVER_SUPPORT
- (void) fprintf (stderr, "%c-> copy(%s,%s)\n",
- (server_active) ? 'S' : ' ', from, to);
-#else
- (void) fprintf (stderr, "-> copy(%s,%s)\n", from, to);
-#endif
- if (noexec)
- return;
-
- if ((fdin = open (from, O_RDONLY)) < 0)
- error (1, errno, "cannot open %s for copying", from);
- if (fstat (fdin, &sb) < 0)
- error (1, errno, "cannot fstat %s", from);
- if ((fdout = creat (to, (int) sb.st_mode & 07777)) < 0)
- error (1, errno, "cannot create %s for copying", to);
- if (sb.st_size > 0)
- {
- char buf[BUFSIZ];
- int n;
-
- for (;;)
- {
- n = read (fdin, buf, sizeof(buf));
- if (n == -1)
- {
-#ifdef EINTR
- if (errno == EINTR)
- continue;
-#endif
- error (1, errno, "cannot read file %s for copying", from);
- }
- else if (n == 0)
- break;
-
- if (write(fdout, buf, n) != n) {
- error (1, errno, "cannot write file %s for copying", to);
- }
- }
-
-#ifdef HAVE_FSYNC
- if (fsync (fdout))
- error (1, errno, "cannot fsync file %s after copying", to);
-#endif
- }
-
- if (close (fdin) < 0)
- error (0, errno, "cannot close %s", from);
- if (close (fdout) < 0)
- error (1, errno, "cannot close %s", to);
-
- /* now, set the times for the copied file to match those of the original */
- memset ((char *) &t, 0, sizeof (t));
- t.actime = sb.st_atime;
- t.modtime = sb.st_mtime;
- (void) utime (to, &t);
-}
-
-/* FIXME-krp: these functions would benefit from caching the char * &
- stat buf. */
-
-/*
- * Returns non-zero if the argument file is a directory, or is a symbolic
- * link which points to a directory.
- */
-int
-isdir (file)
- const char *file;
-{
- struct stat sb;
-
- if (stat (file, &sb) < 0)
- return (0);
- return (S_ISDIR (sb.st_mode));
-}
-
-/*
- * Returns non-zero if the argument file is a symbolic link.
- */
-int
-islink (file)
- const char *file;
-{
-#ifdef S_ISLNK
- struct stat sb;
-
- if (lstat (file, &sb) < 0)
- return (0);
- return (S_ISLNK (sb.st_mode));
-#else
- return (0);
-#endif
-}
-
-/*
- * Returns non-zero if the argument file exists.
- */
-int
-isfile (file)
- const char *file;
-{
- return isaccessible(file, F_OK);
-}
-
-/*
- * Returns non-zero if the argument file is readable.
- */
-int
-isreadable (file)
- const char *file;
-{
- return isaccessible(file, R_OK);
-}
-
-/*
- * Returns non-zero if the argument file is writable.
- */
-int
-iswritable (file)
- const char *file;
-{
- return isaccessible(file, W_OK);
-}
-
-/*
- * Returns non-zero if the argument file is accessable according to
- * mode. If compiled with SETXID_SUPPORT also works if cvs has setxid
- * bits set.
- */
-int
-isaccessible (file, mode)
- const char *file;
- const int mode;
-{
-#ifdef SETXID_SUPPORT
- struct stat sb;
- int umask = 0;
- int gmask = 0;
- int omask = 0;
- int uid;
-
- if (stat(file, &sb) == -1)
- return 0;
- if (mode == F_OK)
- return 1;
-
- uid = geteuid();
- if (uid == 0) /* superuser */
- {
- if (mode & X_OK)
- return sb.st_mode & (S_IXUSR|S_IXGRP|S_IXOTH);
- else
- return 1;
- }
-
- if (mode & R_OK)
- {
- umask |= S_IRUSR;
- gmask |= S_IRGRP;
- omask |= S_IROTH;
- }
- if (mode & W_OK)
- {
- umask |= S_IWUSR;
- gmask |= S_IWGRP;
- omask |= S_IWOTH;
- }
- if (mode & X_OK)
- {
- umask |= S_IXUSR;
- gmask |= S_IXGRP;
- omask |= S_IXOTH;
- }
-
- if (sb.st_uid == uid)
- return (sb.st_mode & umask) == umask;
- else if (sb.st_gid == getegid())
- return (sb.st_mode & gmask) == gmask;
- else
- return (sb.st_mode & omask) == omask;
-#else
- return access(file, mode) == 0;
-#endif
-}
-
-/*
- * Open a file and die if it fails
- */
-FILE *
-open_file (name, mode)
- const char *name;
- const char *mode;
-{
- FILE *fp;
-
- if ((fp = fopen (name, mode)) == NULL)
- error (1, errno, "cannot open %s", name);
- return (fp);
-}
-
-/*
- * Make a directory and die if it fails
- */
-void
-make_directory (name)
- const char *name;
-{
- struct stat sb;
-
- if (stat (name, &sb) == 0 && (!S_ISDIR (sb.st_mode)))
- error (0, 0, "%s already exists but is not a directory", name);
- if (!noexec && mkdir (name, 0777) < 0)
- error (1, errno, "cannot make directory %s", name);
-}
-
-/*
- * Make a path to the argument directory, printing a message if something
- * goes wrong.
- */
-void
-make_directories (name)
- const char *name;
-{
- char *cp;
-
- if (noexec)
- return;
-
- if (mkdir (name, 0777) == 0 || errno == EEXIST)
- return;
- if (! existence_error (errno))
- {
- error (0, errno, "cannot make path to %s", name);
- return;
- }
- if ((cp = strrchr (name, '/')) == NULL)
- return;
- *cp = '\0';
- make_directories (name);
- *cp++ = '/';
- if (*cp == '\0')
- return;
- (void) mkdir (name, 0777);
-}
-
-/*
- * Change the mode of a file, either adding write permissions, or removing
- * all write permissions. Either change honors the current umask setting.
- */
-void
-xchmod (fname, writable)
- char *fname;
- int writable;
-{
- struct stat sb;
- mode_t mode, oumask;
-
- if (stat (fname, &sb) < 0)
- {
- if (!noexec)
- error (0, errno, "cannot stat %s", fname);
- return;
- }
- oumask = umask (0);
- (void) umask (oumask);
- if (writable)
- {
- mode = sb.st_mode | (~oumask
- & (((sb.st_mode & S_IRUSR) ? S_IWUSR : 0)
- | ((sb.st_mode & S_IRGRP) ? S_IWGRP : 0)
- | ((sb.st_mode & S_IROTH) ? S_IWOTH : 0)));
- }
- else
- {
- mode = sb.st_mode & ~(S_IWRITE | S_IWGRP | S_IWOTH) & ~oumask;
- }
-
- if (trace)
-#ifdef SERVER_SUPPORT
- (void) fprintf (stderr, "%c-> chmod(%s,%o)\n",
- (server_active) ? 'S' : ' ', fname, mode);
-#else
- (void) fprintf (stderr, "-> chmod(%s,%o)\n", fname, mode);
-#endif
- if (noexec)
- return;
-
- if (chmod (fname, mode) < 0)
- error (0, errno, "cannot change mode of file %s", fname);
-}
-
-/*
- * Rename a file and die if it fails
- */
-void
-rename_file (from, to)
- const char *from;
- const char *to;
-{
- if (trace)
-#ifdef SERVER_SUPPORT
- (void) fprintf (stderr, "%c-> rename(%s,%s)\n",
- (server_active) ? 'S' : ' ', from, to);
-#else
- (void) fprintf (stderr, "-> rename(%s,%s)\n", from, to);
-#endif
- if (noexec)
- return;
-
- if (rename (from, to) < 0)
- error (1, errno, "cannot rename file %s to %s", from, to);
-}
-
-/*
- * link a file, if possible.
- */
-int
-link_file (from, to)
- const char *from;
- const char *to;
-{
- if (trace)
-#ifdef SERVER_SUPPORT
- (void) fprintf (stderr, "%c-> link(%s,%s)\n",
- (server_active) ? 'S' : ' ', from, to);
-#else
- (void) fprintf (stderr, "-> link(%s,%s)\n", from, to);
-#endif
- if (noexec)
- return (0);
-
- return (link (from, to));
-}
-
-/*
- * unlink a file, if possible.
- */
-int
-unlink_file (f)
- const char *f;
-{
- if (trace)
-#ifdef SERVER_SUPPORT
- (void) fprintf (stderr, "%c-> unlink(%s)\n",
- (server_active) ? 'S' : ' ', f);
-#else
- (void) fprintf (stderr, "-> unlink(%s)\n", f);
-#endif
- if (noexec)
- return (0);
-
- return (unlink (f));
-}
-
-/*
- * Unlink a file or dir, if possible. If it is a directory do a deep
- * removal of all of the files in the directory. Return -1 on error
- * (in which case errno is set).
- */
-int
-unlink_file_dir (f)
- const char *f;
-{
- if (trace)
-#ifdef SERVER_SUPPORT
- (void) fprintf (stderr, "%c-> unlink_file_dir(%s)\n",
- (server_active) ? 'S' : ' ', f);
-#else
- (void) fprintf (stderr, "-> unlink_file_dir(%s)\n", f);
-#endif
- if (noexec)
- return (0);
-
- if (unlink (f) != 0)
- {
- /* under NEXTSTEP errno is set to return EPERM if
- * the file is a directory,or if the user is not
- * allowed to read or write to the file.
- * [This is probably a bug in the O/S]
- * other systems will return EISDIR to indicate
- * that the path is a directory.
- */
- if (errno == EISDIR || errno == EPERM)
- return deep_remove_dir (f);
- else
- /* The file wasn't a directory and some other
- * error occured
- */
- return -1;
- }
- /* We were able to remove the file from the disk */
- return 0;
-}
-
-/* Remove a directory and everything it contains. Returns 0 for
- * success, -1 for failure (in which case errno is set).
- */
-
-static int
-deep_remove_dir (path)
- const char *path;
-{
- DIR *dirp;
- struct dirent *dp;
- char buf[PATH_MAX];
-
- if ( rmdir (path) != 0 && errno == ENOTEMPTY )
- {
- if ((dirp = opendir (path)) == NULL)
- /* If unable to open the directory return
- * an error
- */
- return -1;
-
- while ((dp = readdir (dirp)) != NULL)
- {
- if (strcmp (dp->d_name, ".") == 0 ||
- strcmp (dp->d_name, "..") == 0)
- continue;
-
- sprintf (buf, "%s/%s", path, dp->d_name);
-
- if (unlink (buf) != 0 )
- {
- if (errno == EISDIR || errno == EPERM)
- {
- if (deep_remove_dir (buf))
- {
- closedir (dirp);
- return -1;
- }
- }
- else
- {
- /* buf isn't a directory, or there are
- * some sort of permision problems
- */
- closedir (dirp);
- return -1;
- }
- }
- }
- closedir (dirp);
- return rmdir (path);
- }
- /* Was able to remove the directory return 0 */
- return 0;
-}
-
-/* Read NCHARS bytes from descriptor FD into BUF.
- Return the number of characters successfully read.
- The number returned is always NCHARS unless end-of-file or error. */
-static size_t
-block_read (fd, buf, nchars)
- int fd;
- char *buf;
- size_t nchars;
-{
- char *bp = buf;
- size_t nread;
-
- do
- {
- nread = read (fd, bp, nchars);
- if (nread == (size_t)-1)
- {
-#ifdef EINTR
- if (errno == EINTR)
- continue;
-#endif
- return (size_t)-1;
- }
-
- if (nread == 0)
- break;
-
- bp += nread;
- nchars -= nread;
- } while (nchars != 0);
-
- return bp - buf;
-}
-
-
-/*
- * Compare "file1" to "file2". Return non-zero if they don't compare exactly.
- */
-int
-xcmp (file1, file2)
- const char *file1;
- const char *file2;
-{
- char *buf1, *buf2;
- struct stat sb1, sb2;
- int fd1, fd2;
- int ret;
-
- if ((fd1 = open (file1, O_RDONLY)) < 0)
- error (1, errno, "cannot open file %s for comparing", file1);
- if ((fd2 = open (file2, O_RDONLY)) < 0)
- error (1, errno, "cannot open file %s for comparing", file2);
- if (fstat (fd1, &sb1) < 0)
- error (1, errno, "cannot fstat %s", file1);
- if (fstat (fd2, &sb2) < 0)
- error (1, errno, "cannot fstat %s", file2);
-
- /* A generic file compare routine might compare st_dev & st_ino here
- to see if the two files being compared are actually the same file.
- But that won't happen in CVS, so we won't bother. */
-
- if (sb1.st_size != sb2.st_size)
- ret = 1;
- else if (sb1.st_size == 0)
- ret = 0;
- else
- {
- /* FIXME: compute the optimal buffer size by computing the least
- common multiple of the files st_blocks field */
- size_t buf_size = 8 * 1024;
- size_t read1;
- size_t read2;
-
- buf1 = xmalloc (buf_size);
- buf2 = xmalloc (buf_size);
-
- do
- {
- read1 = block_read (fd1, buf1, buf_size);
- if (read1 == (size_t)-1)
- error (1, errno, "cannot read file %s for comparing", file1);
-
- read2 = block_read (fd2, buf2, buf_size);
- if (read2 == (size_t)-1)
- error (1, errno, "cannot read file %s for comparing", file2);
-
- /* assert (read1 == read2); */
-
- ret = memcmp(buf1, buf2, read1);
- } while (ret == 0 && read1 == buf_size);
-
- free (buf1);
- free (buf2);
- }
-
- (void) close (fd1);
- (void) close (fd2);
- return (ret);
-}
-
-#ifdef LOSING_TMPNAM_FUNCTION
-char *tmpnam(char *s)
-{
- static char value[L_tmpnam+1];
-
- if (s){
- strcpy(s,"/tmp/cvsXXXXXX");
- mktemp(s);
- return s;
- }else{
- strcpy(value,"/tmp/cvsXXXXXX");
- mktemp(s);
- return value;
- }
-}
-#endif
-
-/* Return non-zero iff FILENAME is absolute.
- Trivial under Unix, but more complicated under other systems. */
-int
-isabsolute (filename)
- const char *filename;
-{
- return filename[0] == '/';
-}
-
-
-/* Return a pointer into PATH's last component. */
-char *
-last_component (path)
- char *path;
-{
- char *last = strrchr (path, '/');
-
- if (last)
- return last + 1;
- else
- return path;
-}
diff --git a/gnu/usr.bin/cvs/lib/fnmatch.c b/gnu/usr.bin/cvs/lib/fnmatch.c
deleted file mode 100644
index 2a0543072d4e..000000000000
--- a/gnu/usr.bin/cvs/lib/fnmatch.c
+++ /dev/null
@@ -1,183 +0,0 @@
-/* Copyright (C) 1992 Free Software Foundation, Inc.
-This file is part of the GNU C Library.
-
-The GNU C Library is free software; you can redistribute it and/or
-modify it under the terms of the GNU Library General Public License as
-published by the Free Software Foundation; either version 2 of the
-License, or (at your option) any later version.
-
-The GNU C Library is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-Library General Public License for more details.
-
-You should have received a copy of the GNU Library General Public
-License along with the GNU C Library; see the file COPYING.LIB. If
-not, write to the Free Software Foundation, Inc., 675 Mass Ave,
-Cambridge, MA 02139, USA. */
-
-/* Modified slightly by Brian Berliner <berliner@sun.com> for CVS use */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-/* IGNORE(@ */
-/* #include <ansidecl.h> */
-/* @) */
-#include <errno.h>
-#include <fnmatch.h>
-
-#if !defined(__GNU_LIBRARY__) && !defined(STDC_HEADERS)
-extern int errno;
-#endif
-
-/* Match STRING against the filename pattern PATTERN, returning zero if
- it matches, nonzero if not. */
-int
-#if __STDC__
-fnmatch (const char *pattern, const char *string, int flags)
-#else
-fnmatch (pattern, string, flags)
- char *pattern;
- char *string;
- int flags;
-#endif
-{
- register const char *p = pattern, *n = string;
- register char c;
-
- if ((flags & ~__FNM_FLAGS) != 0)
- {
- errno = EINVAL;
- return -1;
- }
-
- while ((c = *p++) != '\0')
- {
- switch (c)
- {
- case '?':
- if (*n == '\0')
- return FNM_NOMATCH;
- else if ((flags & FNM_PATHNAME) && *n == '/')
- return FNM_NOMATCH;
- else if ((flags & FNM_PERIOD) && *n == '.' &&
- (n == string || ((flags & FNM_PATHNAME) && n[-1] == '/')))
- return FNM_NOMATCH;
- break;
-
- case '\\':
- if (!(flags & FNM_NOESCAPE))
- c = *p++;
- if (*n != c)
- return FNM_NOMATCH;
- break;
-
- case '*':
- if ((flags & FNM_PERIOD) && *n == '.' &&
- (n == string || ((flags & FNM_PATHNAME) && n[-1] == '/')))
- return FNM_NOMATCH;
-
- for (c = *p++; c == '?' || c == '*'; c = *p++, ++n)
- if (((flags & FNM_PATHNAME) && *n == '/') ||
- (c == '?' && *n == '\0'))
- return FNM_NOMATCH;
-
- if (c == '\0')
- return 0;
-
- {
- char c1 = (!(flags & FNM_NOESCAPE) && c == '\\') ? *p : c;
- for (--p; *n != '\0'; ++n)
- if ((c == '[' || *n == c1) &&
- fnmatch(p, n, flags & ~FNM_PERIOD) == 0)
- return 0;
- return FNM_NOMATCH;
- }
-
- case '[':
- {
- /* Nonzero if the sense of the character class is inverted. */
- register int not;
-
- if (*n == '\0')
- return FNM_NOMATCH;
-
- if ((flags & FNM_PERIOD) && *n == '.' &&
- (n == string || ((flags & FNM_PATHNAME) && n[-1] == '/')))
- return FNM_NOMATCH;
-
- not = (*p == '!' || *p == '^');
- if (not)
- ++p;
-
- c = *p++;
- for (;;)
- {
- register char cstart = c, cend = c;
-
- if (!(flags & FNM_NOESCAPE) && c == '\\')
- cstart = cend = *p++;
-
- if (c == '\0')
- /* [ (unterminated) loses. */
- return FNM_NOMATCH;
-
- c = *p++;
-
- if ((flags & FNM_PATHNAME) && c == '/')
- /* [/] can never match. */
- return FNM_NOMATCH;
-
- if (c == '-' && *p != ']')
- {
- cend = *p++;
- if (!(flags & FNM_NOESCAPE) && cend == '\\')
- cend = *p++;
- if (cend == '\0')
- return FNM_NOMATCH;
- c = *p++;
- }
-
- if (*n >= cstart && *n <= cend)
- goto matched;
-
- if (c == ']')
- break;
- }
- if (!not)
- return FNM_NOMATCH;
- break;
-
- matched:;
- /* Skip the rest of the [...] that already matched. */
- while (c != ']')
- {
- if (c == '\0')
- /* [... (unterminated) loses. */
- return FNM_NOMATCH;
-
- c = *p++;
- if (!(flags & FNM_NOESCAPE) && c == '\\')
- /* 1003.2d11 is unclear if this is right. %%% */
- ++p;
- }
- if (not)
- return FNM_NOMATCH;
- }
- break;
-
- default:
- if (c != *n)
- return FNM_NOMATCH;
- }
-
- ++n;
- }
-
- if (*n == '\0')
- return 0;
-
- return FNM_NOMATCH;
-}
diff --git a/gnu/usr.bin/cvs/lib/fnmatch.h b/gnu/usr.bin/cvs/lib/fnmatch.h
deleted file mode 100644
index a1e4f8702185..000000000000
--- a/gnu/usr.bin/cvs/lib/fnmatch.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/* Copyright (C) 1992 Free Software Foundation, Inc.
-This file is part of the GNU C Library.
-
-The GNU C Library is free software; you can redistribute it and/or
-modify it under the terms of the GNU Library General Public License as
-published by the Free Software Foundation; either version 2 of the
-License, or (at your option) any later version.
-
-The GNU C Library is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-Library General Public License for more details.
-
-You should have received a copy of the GNU Library General Public
-License along with the GNU C Library; see the file COPYING.LIB. If
-not, write to the Free Software Foundation, Inc., 675 Mass Ave,
-Cambridge, MA 02139, USA. */
-
-#ifndef _FNMATCH_H
-
-#define _FNMATCH_H 1
-
-/* Bits set in the FLAGS argument to `fnmatch'. */
-#undef FNM_PATHNAME
-#define FNM_PATHNAME (1 << 0)/* No wildcard can ever match `/'. */
-#undef FNM_NOESCAPE
-#define FNM_NOESCAPE (1 << 1)/* Backslashes don't quote special chars. */
-#undef FNM_PERIOD
-#define FNM_PERIOD (1 << 2)/* Leading `.' is matched only explicitly. */
-#undef __FNM_FLAGS
-#define __FNM_FLAGS (FNM_PATHNAME|FNM_NOESCAPE|FNM_PERIOD)
-
-/* Value returned by `fnmatch' if STRING does not match PATTERN. */
-#undef FNM_NOMATCH
-#define FNM_NOMATCH 1
-
-/* Match STRING against the filename pattern PATTERN,
- returning zero if it matches, FNM_NOMATCH if not. */
-#if __STDC__
-extern int fnmatch (const char *pattern, const char *string, int flags);
-#else
-extern int fnmatch ();
-#endif
-
-#endif /* fnmatch.h */
diff --git a/gnu/usr.bin/cvs/lib/ftruncate.c b/gnu/usr.bin/cvs/lib/ftruncate.c
deleted file mode 100644
index 13f20a382849..000000000000
--- a/gnu/usr.bin/cvs/lib/ftruncate.c
+++ /dev/null
@@ -1,76 +0,0 @@
-/* ftruncate emulations that work on some System V's.
- This file is in the public domain. */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <sys/types.h>
-#include <fcntl.h>
-
-#ifdef F_CHSIZE
-int
-ftruncate (fd, length)
- int fd;
- off_t length;
-{
- return fcntl (fd, F_CHSIZE, length);
-}
-#else
-#ifdef F_FREESP
-/* The following function was written by
- kucharsk@Solbourne.com (William Kucharski) */
-
-#include <sys/stat.h>
-#include <errno.h>
-#include <unistd.h>
-
-int
-ftruncate (fd, length)
- int fd;
- off_t length;
-{
- struct flock fl;
- struct stat filebuf;
-
- if (fstat (fd, &filebuf) < 0)
- return -1;
-
- if (filebuf.st_size < length)
- {
- /* Extend file length. */
- if (lseek (fd, (length - 1), SEEK_SET) < 0)
- return -1;
-
- /* Write a "0" byte. */
- if (write (fd, "", 1) != 1)
- return -1;
- }
- else
- {
- /* Truncate length. */
- fl.l_whence = 0;
- fl.l_len = 0;
- fl.l_start = length;
- fl.l_type = F_WRLCK; /* Write lock on file space. */
-
- /* This relies on the UNDOCUMENTED F_FREESP argument to
- fcntl, which truncates the file so that it ends at the
- position indicated by fl.l_start.
- Will minor miracles never cease? */
- if (fcntl (fd, F_FREESP, &fl) < 0)
- return -1;
- }
-
- return 0;
-}
-#else
-int
-ftruncate (fd, length)
- int fd;
- off_t length;
-{
- return chsize (fd, length);
-}
-#endif
-#endif
diff --git a/gnu/usr.bin/cvs/lib/getdate.y b/gnu/usr.bin/cvs/lib/getdate.y
deleted file mode 100644
index baa17315373c..000000000000
--- a/gnu/usr.bin/cvs/lib/getdate.y
+++ /dev/null
@@ -1,996 +0,0 @@
-%{
-/*
-** Originally written by Steven M. Bellovin <smb@research.att.com> while
-** at the University of North Carolina at Chapel Hill. Later tweaked by
-** a couple of people on Usenet. Completely overhauled by Rich $alz
-** <rsalz@bbn.com> and Jim Berets <jberets@bbn.com> in August, 1990;
-** send any email to Rich.
-**
-** This grammar has 10 shift/reduce conflicts.
-**
-** This code is in the public domain and has no copyright.
-*/
-/* SUPPRESS 287 on yaccpar_sccsid *//* Unused static variable */
-/* SUPPRESS 288 on yyerrlab *//* Label unused */
-
-#ifdef HAVE_CONFIG_H
-#if defined (emacs) || defined (CONFIG_BROKETS)
-#include <config.h>
-#else
-#include "config.h"
-#endif
-#endif
-
-/* Since the code of getdate.y is not included in the Emacs executable
- itself, there is no need to #define static in this file. Even if
- the code were included in the Emacs executable, it probably
- wouldn't do any harm to #undef it here; this will only cause
- problems if we try to write to a static variable, which I don't
- think this code needs to do. */
-#ifdef emacs
-#undef static
-#endif
-
-#include <stdio.h>
-#include <ctype.h>
-
-/* The code at the top of get_date which figures out the offset of the
- current time zone checks various CPP symbols to see if special
- tricks are need, but defaults to using the gettimeofday system call.
- Include <sys/time.h> if that will be used. */
-
-#if defined(vms)
-
-#include <types.h>
-#include <time.h>
-
-#else
-
-#include <sys/types.h>
-
-#ifdef TIME_WITH_SYS_TIME
-#include <sys/time.h>
-#include <time.h>
-#else
-#ifdef HAVE_SYS_TIME_H
-#include <sys/time.h>
-#else
-#include <time.h>
-#endif
-#endif
-
-#ifdef timezone
-#undef timezone /* needed for sgi */
-#endif
-
-#if defined(HAVE_SYS_TIMEB_H)
-#include <sys/timeb.h>
-#else
-/*
-** We use the obsolete `struct timeb' as part of our interface!
-** Since the system doesn't have it, we define it here;
-** our callers must do likewise.
-*/
-struct timeb {
- time_t time; /* Seconds since the epoch */
- unsigned short millitm; /* Field not used */
- short timezone; /* Minutes west of GMT */
- short dstflag; /* Field not used */
-};
-#endif /* defined(HAVE_SYS_TIMEB_H) */
-
-#endif /* defined(vms) */
-
-#if defined (STDC_HEADERS) || defined (USG)
-#include <string.h>
-#endif
-
-/* Some old versions of bison generate parsers that use bcopy.
- That loses on systems that don't provide the function, so we have
- to redefine it here. */
-#if !defined (HAVE_BCOPY) && defined (HAVE_MEMCPY) && !defined (bcopy)
-#define bcopy(from, to, len) memcpy ((to), (from), (len))
-#endif
-
-#if defined (STDC_HEADERS)
-#include <stdlib.h>
-#endif
-
-#if defined (HAVE_ALLOCA_H)
-#include <alloca.h>
-#endif
-
-extern struct tm *gmtime();
-extern struct tm *localtime();
-
-#define yyparse getdate_yyparse
-#define yylex getdate_yylex
-#define yyerror getdate_yyerror
-
-#if !defined(lint) && !defined(SABER)
-static char RCS[] = "$CVSid: @(#)getdate.y 1.11 94/09/21 $";
-#endif /* !defined(lint) && !defined(SABER) */
-
-static int yylex ();
-static int yyerror ();
-
-#define EPOCH 1970
-#define HOUR(x) ((time_t)(x) * 60)
-#define SECSPERDAY (24L * 60L * 60L)
-
-
-/*
-** An entry in the lexical lookup table.
-*/
-typedef struct _TABLE {
- char *name;
- int type;
- time_t value;
-} TABLE;
-
-
-/*
-** Daylight-savings mode: on, off, or not yet known.
-*/
-typedef enum _DSTMODE {
- DSTon, DSToff, DSTmaybe
-} DSTMODE;
-
-/*
-** Meridian: am, pm, or 24-hour style.
-*/
-typedef enum _MERIDIAN {
- MERam, MERpm, MER24
-} MERIDIAN;
-
-
-/*
-** Global variables. We could get rid of most of these by using a good
-** union as the yacc stack. (This routine was originally written before
-** yacc had the %union construct.) Maybe someday; right now we only use
-** the %union very rarely.
-*/
-static char *yyInput;
-static DSTMODE yyDSTmode;
-static time_t yyDayOrdinal;
-static time_t yyDayNumber;
-static int yyHaveDate;
-static int yyHaveDay;
-static int yyHaveRel;
-static int yyHaveTime;
-static int yyHaveZone;
-static time_t yyTimezone;
-static time_t yyDay;
-static time_t yyHour;
-static time_t yyMinutes;
-static time_t yyMonth;
-static time_t yySeconds;
-static time_t yyYear;
-static MERIDIAN yyMeridian;
-static time_t yyRelMonth;
-static time_t yyRelSeconds;
-
-%}
-
-%union {
- time_t Number;
- enum _MERIDIAN Meridian;
-}
-
-%token tAGO tDAY tDAYZONE tID tMERIDIAN tMINUTE_UNIT tMONTH tMONTH_UNIT
-%token tSEC_UNIT tSNUMBER tUNUMBER tZONE tDST
-
-%type <Number> tDAY tDAYZONE tMINUTE_UNIT tMONTH tMONTH_UNIT
-%type <Number> tSEC_UNIT tSNUMBER tUNUMBER tZONE
-%type <Meridian> tMERIDIAN o_merid
-
-%%
-
-spec : /* NULL */
- | spec item
- ;
-
-item : time {
- yyHaveTime++;
- }
- | zone {
- yyHaveZone++;
- }
- | date {
- yyHaveDate++;
- }
- | day {
- yyHaveDay++;
- }
- | rel {
- yyHaveRel++;
- }
- | number
- ;
-
-time : tUNUMBER tMERIDIAN {
- yyHour = $1;
- yyMinutes = 0;
- yySeconds = 0;
- yyMeridian = $2;
- }
- | tUNUMBER ':' tUNUMBER o_merid {
- yyHour = $1;
- yyMinutes = $3;
- yySeconds = 0;
- yyMeridian = $4;
- }
- | tUNUMBER ':' tUNUMBER tSNUMBER {
- yyHour = $1;
- yyMinutes = $3;
- yyMeridian = MER24;
- yyDSTmode = DSToff;
- yyTimezone = - ($4 % 100 + ($4 / 100) * 60);
- }
- | tUNUMBER ':' tUNUMBER ':' tUNUMBER o_merid {
- yyHour = $1;
- yyMinutes = $3;
- yySeconds = $5;
- yyMeridian = $6;
- }
- | tUNUMBER ':' tUNUMBER ':' tUNUMBER tSNUMBER {
- yyHour = $1;
- yyMinutes = $3;
- yySeconds = $5;
- yyMeridian = MER24;
- yyDSTmode = DSToff;
- yyTimezone = - ($6 % 100 + ($6 / 100) * 60);
- }
- ;
-
-zone : tZONE {
- yyTimezone = $1;
- yyDSTmode = DSToff;
- }
- | tDAYZONE {
- yyTimezone = $1;
- yyDSTmode = DSTon;
- }
- |
- tZONE tDST {
- yyTimezone = $1;
- yyDSTmode = DSTon;
- }
- ;
-
-day : tDAY {
- yyDayOrdinal = 1;
- yyDayNumber = $1;
- }
- | tDAY ',' {
- yyDayOrdinal = 1;
- yyDayNumber = $1;
- }
- | tUNUMBER tDAY {
- yyDayOrdinal = $1;
- yyDayNumber = $2;
- }
- ;
-
-date : tUNUMBER '/' tUNUMBER {
- yyMonth = $1;
- yyDay = $3;
- }
- | tUNUMBER '/' tUNUMBER '/' tUNUMBER {
- yyMonth = $1;
- yyDay = $3;
- yyYear = $5;
- }
- | tUNUMBER tSNUMBER tSNUMBER {
- /* ISO 8601 format. yyyy-mm-dd. */
- yyYear = $1;
- yyMonth = -$2;
- yyDay = -$3;
- }
- | tUNUMBER tMONTH tSNUMBER {
- /* e.g. 17-JUN-1992. */
- yyDay = $1;
- yyMonth = $2;
- yyYear = -$3;
- }
- | tMONTH tUNUMBER {
- yyMonth = $1;
- yyDay = $2;
- }
- | tMONTH tUNUMBER ',' tUNUMBER {
- yyMonth = $1;
- yyDay = $2;
- yyYear = $4;
- }
- | tUNUMBER tMONTH {
- yyMonth = $2;
- yyDay = $1;
- }
- | tUNUMBER tMONTH tUNUMBER {
- yyMonth = $2;
- yyDay = $1;
- yyYear = $3;
- }
- ;
-
-rel : relunit tAGO {
- yyRelSeconds = -yyRelSeconds;
- yyRelMonth = -yyRelMonth;
- }
- | relunit
- ;
-
-relunit : tUNUMBER tMINUTE_UNIT {
- yyRelSeconds += $1 * $2 * 60L;
- }
- | tSNUMBER tMINUTE_UNIT {
- yyRelSeconds += $1 * $2 * 60L;
- }
- | tMINUTE_UNIT {
- yyRelSeconds += $1 * 60L;
- }
- | tSNUMBER tSEC_UNIT {
- yyRelSeconds += $1;
- }
- | tUNUMBER tSEC_UNIT {
- yyRelSeconds += $1;
- }
- | tSEC_UNIT {
- yyRelSeconds++;
- }
- | tSNUMBER tMONTH_UNIT {
- yyRelMonth += $1 * $2;
- }
- | tUNUMBER tMONTH_UNIT {
- yyRelMonth += $1 * $2;
- }
- | tMONTH_UNIT {
- yyRelMonth += $1;
- }
- ;
-
-number : tUNUMBER {
- if (yyHaveTime && yyHaveDate && !yyHaveRel)
- yyYear = $1;
- else {
- if($1>10000) {
- yyHaveDate++;
- yyDay= ($1)%100;
- yyMonth= ($1/100)%100;
- yyYear = $1/10000;
- }
- else {
- yyHaveTime++;
- if ($1 < 100) {
- yyHour = $1;
- yyMinutes = 0;
- }
- else {
- yyHour = $1 / 100;
- yyMinutes = $1 % 100;
- }
- yySeconds = 0;
- yyMeridian = MER24;
- }
- }
- }
- ;
-
-o_merid : /* NULL */ {
- $$ = MER24;
- }
- | tMERIDIAN {
- $$ = $1;
- }
- ;
-
-%%
-
-/* Month and day table. */
-static TABLE const MonthDayTable[] = {
- { "january", tMONTH, 1 },
- { "february", tMONTH, 2 },
- { "march", tMONTH, 3 },
- { "april", tMONTH, 4 },
- { "may", tMONTH, 5 },
- { "june", tMONTH, 6 },
- { "july", tMONTH, 7 },
- { "august", tMONTH, 8 },
- { "september", tMONTH, 9 },
- { "sept", tMONTH, 9 },
- { "october", tMONTH, 10 },
- { "november", tMONTH, 11 },
- { "december", tMONTH, 12 },
- { "sunday", tDAY, 0 },
- { "monday", tDAY, 1 },
- { "tuesday", tDAY, 2 },
- { "tues", tDAY, 2 },
- { "wednesday", tDAY, 3 },
- { "wednes", tDAY, 3 },
- { "thursday", tDAY, 4 },
- { "thur", tDAY, 4 },
- { "thurs", tDAY, 4 },
- { "friday", tDAY, 5 },
- { "saturday", tDAY, 6 },
- { NULL }
-};
-
-/* Time units table. */
-static TABLE const UnitsTable[] = {
- { "year", tMONTH_UNIT, 12 },
- { "month", tMONTH_UNIT, 1 },
- { "fortnight", tMINUTE_UNIT, 14 * 24 * 60 },
- { "week", tMINUTE_UNIT, 7 * 24 * 60 },
- { "day", tMINUTE_UNIT, 1 * 24 * 60 },
- { "hour", tMINUTE_UNIT, 60 },
- { "minute", tMINUTE_UNIT, 1 },
- { "min", tMINUTE_UNIT, 1 },
- { "second", tSEC_UNIT, 1 },
- { "sec", tSEC_UNIT, 1 },
- { NULL }
-};
-
-/* Assorted relative-time words. */
-static TABLE const OtherTable[] = {
- { "tomorrow", tMINUTE_UNIT, 1 * 24 * 60 },
- { "yesterday", tMINUTE_UNIT, -1 * 24 * 60 },
- { "today", tMINUTE_UNIT, 0 },
- { "now", tMINUTE_UNIT, 0 },
- { "last", tUNUMBER, -1 },
- { "this", tMINUTE_UNIT, 0 },
- { "next", tUNUMBER, 2 },
- { "first", tUNUMBER, 1 },
-/* { "second", tUNUMBER, 2 }, */
- { "third", tUNUMBER, 3 },
- { "fourth", tUNUMBER, 4 },
- { "fifth", tUNUMBER, 5 },
- { "sixth", tUNUMBER, 6 },
- { "seventh", tUNUMBER, 7 },
- { "eighth", tUNUMBER, 8 },
- { "ninth", tUNUMBER, 9 },
- { "tenth", tUNUMBER, 10 },
- { "eleventh", tUNUMBER, 11 },
- { "twelfth", tUNUMBER, 12 },
- { "ago", tAGO, 1 },
- { NULL }
-};
-
-/* The timezone table. */
-/* Some of these are commented out because a time_t can't store a float. */
-static TABLE const TimezoneTable[] = {
- { "gmt", tZONE, HOUR( 0) }, /* Greenwich Mean */
- { "ut", tZONE, HOUR( 0) }, /* Universal (Coordinated) */
- { "utc", tZONE, HOUR( 0) },
- { "wet", tZONE, HOUR( 0) }, /* Western European */
- { "bst", tDAYZONE, HOUR( 0) }, /* British Summer */
- { "wat", tZONE, HOUR( 1) }, /* West Africa */
- { "at", tZONE, HOUR( 2) }, /* Azores */
-#if 0
- /* For completeness. BST is also British Summer, and GST is
- * also Guam Standard. */
- { "bst", tZONE, HOUR( 3) }, /* Brazil Standard */
- { "gst", tZONE, HOUR( 3) }, /* Greenland Standard */
-#endif
-#if 0
- { "nft", tZONE, HOUR(3.5) }, /* Newfoundland */
- { "nst", tZONE, HOUR(3.5) }, /* Newfoundland Standard */
- { "ndt", tDAYZONE, HOUR(3.5) }, /* Newfoundland Daylight */
-#endif
- { "ast", tZONE, HOUR( 4) }, /* Atlantic Standard */
- { "adt", tDAYZONE, HOUR( 4) }, /* Atlantic Daylight */
- { "est", tZONE, HOUR( 5) }, /* Eastern Standard */
- { "edt", tDAYZONE, HOUR( 5) }, /* Eastern Daylight */
- { "cst", tZONE, HOUR( 6) }, /* Central Standard */
- { "cdt", tDAYZONE, HOUR( 6) }, /* Central Daylight */
- { "mst", tZONE, HOUR( 7) }, /* Mountain Standard */
- { "mdt", tDAYZONE, HOUR( 7) }, /* Mountain Daylight */
- { "pst", tZONE, HOUR( 8) }, /* Pacific Standard */
- { "pdt", tDAYZONE, HOUR( 8) }, /* Pacific Daylight */
- { "yst", tZONE, HOUR( 9) }, /* Yukon Standard */
- { "ydt", tDAYZONE, HOUR( 9) }, /* Yukon Daylight */
- { "hst", tZONE, HOUR(10) }, /* Hawaii Standard */
- { "hdt", tDAYZONE, HOUR(10) }, /* Hawaii Daylight */
- { "cat", tZONE, HOUR(10) }, /* Central Alaska */
- { "ahst", tZONE, HOUR(10) }, /* Alaska-Hawaii Standard */
- { "nt", tZONE, HOUR(11) }, /* Nome */
- { "idlw", tZONE, HOUR(12) }, /* International Date Line West */
- { "cet", tZONE, -HOUR(1) }, /* Central European */
- { "met", tZONE, -HOUR(1) }, /* Middle European */
- { "mewt", tZONE, -HOUR(1) }, /* Middle European Winter */
- { "mest", tDAYZONE, -HOUR(1) }, /* Middle European Summer */
- { "swt", tZONE, -HOUR(1) }, /* Swedish Winter */
- { "sst", tDAYZONE, -HOUR(1) }, /* Swedish Summer */
- { "fwt", tZONE, -HOUR(1) }, /* French Winter */
- { "fst", tDAYZONE, -HOUR(1) }, /* French Summer */
- { "eet", tZONE, -HOUR(2) }, /* Eastern Europe, USSR Zone 1 */
- { "bt", tZONE, -HOUR(3) }, /* Baghdad, USSR Zone 2 */
-#if 0
- { "it", tZONE, -HOUR(3.5) },/* Iran */
-#endif
- { "zp4", tZONE, -HOUR(4) }, /* USSR Zone 3 */
- { "zp5", tZONE, -HOUR(5) }, /* USSR Zone 4 */
-#if 0
- { "ist", tZONE, -HOUR(5.5) },/* Indian Standard */
-#endif
- { "zp6", tZONE, -HOUR(6) }, /* USSR Zone 5 */
-#if 0
- /* For completeness. NST is also Newfoundland Stanard, and SST is
- * also Swedish Summer. */
- { "nst", tZONE, -HOUR(6.5) },/* North Sumatra */
- { "sst", tZONE, -HOUR(7) }, /* South Sumatra, USSR Zone 6 */
-#endif /* 0 */
- { "wast", tZONE, -HOUR(7) }, /* West Australian Standard */
- { "wadt", tDAYZONE, -HOUR(7) }, /* West Australian Daylight */
-#if 0
- { "jt", tZONE, -HOUR(7.5) },/* Java (3pm in Cronusland!) */
-#endif
- { "cct", tZONE, -HOUR(8) }, /* China Coast, USSR Zone 7 */
- { "jst", tZONE, -HOUR(9) }, /* Japan Standard, USSR Zone 8 */
-#if 0
- { "cast", tZONE, -HOUR(9.5) },/* Central Australian Standard */
- { "cadt", tDAYZONE, -HOUR(9.5) },/* Central Australian Daylight */
-#endif
- { "east", tZONE, -HOUR(10) }, /* Eastern Australian Standard */
- { "eadt", tDAYZONE, -HOUR(10) }, /* Eastern Australian Daylight */
- { "gst", tZONE, -HOUR(10) }, /* Guam Standard, USSR Zone 9 */
- { "nzt", tZONE, -HOUR(12) }, /* New Zealand */
- { "nzst", tZONE, -HOUR(12) }, /* New Zealand Standard */
- { "nzdt", tDAYZONE, -HOUR(12) }, /* New Zealand Daylight */
- { "idle", tZONE, -HOUR(12) }, /* International Date Line East */
- { NULL }
-};
-
-/* Military timezone table. */
-static TABLE const MilitaryTable[] = {
- { "a", tZONE, HOUR( 1) },
- { "b", tZONE, HOUR( 2) },
- { "c", tZONE, HOUR( 3) },
- { "d", tZONE, HOUR( 4) },
- { "e", tZONE, HOUR( 5) },
- { "f", tZONE, HOUR( 6) },
- { "g", tZONE, HOUR( 7) },
- { "h", tZONE, HOUR( 8) },
- { "i", tZONE, HOUR( 9) },
- { "k", tZONE, HOUR( 10) },
- { "l", tZONE, HOUR( 11) },
- { "m", tZONE, HOUR( 12) },
- { "n", tZONE, HOUR(- 1) },
- { "o", tZONE, HOUR(- 2) },
- { "p", tZONE, HOUR(- 3) },
- { "q", tZONE, HOUR(- 4) },
- { "r", tZONE, HOUR(- 5) },
- { "s", tZONE, HOUR(- 6) },
- { "t", tZONE, HOUR(- 7) },
- { "u", tZONE, HOUR(- 8) },
- { "v", tZONE, HOUR(- 9) },
- { "w", tZONE, HOUR(-10) },
- { "x", tZONE, HOUR(-11) },
- { "y", tZONE, HOUR(-12) },
- { "z", tZONE, HOUR( 0) },
- { NULL }
-};
-
-
-
-
-/* ARGSUSED */
-static int
-yyerror(s)
- char *s;
-{
- return 0;
-}
-
-
-static time_t
-ToSeconds(Hours, Minutes, Seconds, Meridian)
- time_t Hours;
- time_t Minutes;
- time_t Seconds;
- MERIDIAN Meridian;
-{
- if (Minutes < 0 || Minutes > 59 || Seconds < 0 || Seconds > 59)
- return -1;
- switch (Meridian) {
- case MER24:
- if (Hours < 0 || Hours > 23)
- return -1;
- return (Hours * 60L + Minutes) * 60L + Seconds;
- case MERam:
- if (Hours < 1 || Hours > 12)
- return -1;
- return (Hours * 60L + Minutes) * 60L + Seconds;
- case MERpm:
- if (Hours < 1 || Hours > 12)
- return -1;
- return ((Hours + 12) * 60L + Minutes) * 60L + Seconds;
- default:
- abort ();
- }
- /* NOTREACHED */
-}
-
-
-static time_t
-Convert(Month, Day, Year, Hours, Minutes, Seconds, Meridian, DSTmode)
- time_t Month;
- time_t Day;
- time_t Year;
- time_t Hours;
- time_t Minutes;
- time_t Seconds;
- MERIDIAN Meridian;
- DSTMODE DSTmode;
-{
- static int DaysInMonth[12] = {
- 31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
- };
- time_t tod;
- time_t Julian;
- int i;
-
- if (Year < 0)
- Year = -Year;
- if (Year < 100)
- Year += 1900;
- DaysInMonth[1] = Year % 4 == 0 && (Year % 100 != 0 || Year % 400 == 0)
- ? 29 : 28;
- if (Year < EPOCH || Year > 1999
- || Month < 1 || Month > 12
- /* Lint fluff: "conversion from long may lose accuracy" */
- || Day < 1 || Day > DaysInMonth[(int)--Month])
- return -1;
-
- for (Julian = Day - 1, i = 0; i < Month; i++)
- Julian += DaysInMonth[i];
- for (i = EPOCH; i < Year; i++)
- Julian += 365 + (i % 4 == 0);
- Julian *= SECSPERDAY;
- Julian += yyTimezone * 60L;
- if ((tod = ToSeconds(Hours, Minutes, Seconds, Meridian)) < 0)
- return -1;
- Julian += tod;
- if (DSTmode == DSTon
- || (DSTmode == DSTmaybe && localtime(&Julian)->tm_isdst))
- Julian -= 60 * 60;
- return Julian;
-}
-
-
-static time_t
-DSTcorrect(Start, Future)
- time_t Start;
- time_t Future;
-{
- time_t StartDay;
- time_t FutureDay;
-
- StartDay = (localtime(&Start)->tm_hour + 1) % 24;
- FutureDay = (localtime(&Future)->tm_hour + 1) % 24;
- return (Future - Start) + (StartDay - FutureDay) * 60L * 60L;
-}
-
-
-static time_t
-RelativeDate(Start, DayOrdinal, DayNumber)
- time_t Start;
- time_t DayOrdinal;
- time_t DayNumber;
-{
- struct tm *tm;
- time_t now;
-
- now = Start;
- tm = localtime(&now);
- now += SECSPERDAY * ((DayNumber - tm->tm_wday + 7) % 7);
- now += 7 * SECSPERDAY * (DayOrdinal <= 0 ? DayOrdinal : DayOrdinal - 1);
- return DSTcorrect(Start, now);
-}
-
-
-static time_t
-RelativeMonth(Start, RelMonth)
- time_t Start;
- time_t RelMonth;
-{
- struct tm *tm;
- time_t Month;
- time_t Year;
-
- if (RelMonth == 0)
- return 0;
- tm = localtime(&Start);
- Month = 12 * tm->tm_year + tm->tm_mon + RelMonth;
- Year = Month / 12;
- Month = Month % 12 + 1;
- return DSTcorrect(Start,
- Convert(Month, (time_t)tm->tm_mday, Year,
- (time_t)tm->tm_hour, (time_t)tm->tm_min, (time_t)tm->tm_sec,
- MER24, DSTmaybe));
-}
-
-
-static int
-LookupWord(buff)
- char *buff;
-{
- register char *p;
- register char *q;
- register const TABLE *tp;
- int i;
- int abbrev;
-
- /* Make it lowercase. */
- for (p = buff; *p; p++)
- if (isupper(*p))
- *p = tolower(*p);
-
- if (strcmp(buff, "am") == 0 || strcmp(buff, "a.m.") == 0) {
- yylval.Meridian = MERam;
- return tMERIDIAN;
- }
- if (strcmp(buff, "pm") == 0 || strcmp(buff, "p.m.") == 0) {
- yylval.Meridian = MERpm;
- return tMERIDIAN;
- }
-
- /* See if we have an abbreviation for a month. */
- if (strlen(buff) == 3)
- abbrev = 1;
- else if (strlen(buff) == 4 && buff[3] == '.') {
- abbrev = 1;
- buff[3] = '\0';
- }
- else
- abbrev = 0;
-
- for (tp = MonthDayTable; tp->name; tp++) {
- if (abbrev) {
- if (strncmp(buff, tp->name, 3) == 0) {
- yylval.Number = tp->value;
- return tp->type;
- }
- }
- else if (strcmp(buff, tp->name) == 0) {
- yylval.Number = tp->value;
- return tp->type;
- }
- }
-
- for (tp = TimezoneTable; tp->name; tp++)
- if (strcmp(buff, tp->name) == 0) {
- yylval.Number = tp->value;
- return tp->type;
- }
-
- if (strcmp(buff, "dst") == 0)
- return tDST;
-
- for (tp = UnitsTable; tp->name; tp++)
- if (strcmp(buff, tp->name) == 0) {
- yylval.Number = tp->value;
- return tp->type;
- }
-
- /* Strip off any plural and try the units table again. */
- i = strlen(buff) - 1;
- if (buff[i] == 's') {
- buff[i] = '\0';
- for (tp = UnitsTable; tp->name; tp++)
- if (strcmp(buff, tp->name) == 0) {
- yylval.Number = tp->value;
- return tp->type;
- }
- buff[i] = 's'; /* Put back for "this" in OtherTable. */
- }
-
- for (tp = OtherTable; tp->name; tp++)
- if (strcmp(buff, tp->name) == 0) {
- yylval.Number = tp->value;
- return tp->type;
- }
-
- /* Military timezones. */
- if (buff[1] == '\0' && isalpha(*buff)) {
- for (tp = MilitaryTable; tp->name; tp++)
- if (strcmp(buff, tp->name) == 0) {
- yylval.Number = tp->value;
- return tp->type;
- }
- }
-
- /* Drop out any periods and try the timezone table again. */
- for (i = 0, p = q = buff; *q; q++)
- if (*q != '.')
- *p++ = *q;
- else
- i++;
- *p = '\0';
- if (i)
- for (tp = TimezoneTable; tp->name; tp++)
- if (strcmp(buff, tp->name) == 0) {
- yylval.Number = tp->value;
- return tp->type;
- }
-
- return tID;
-}
-
-
-static int
-yylex()
-{
- register char c;
- register char *p;
- char buff[20];
- int Count;
- int sign;
-
- for ( ; ; ) {
- while (isspace(*yyInput))
- yyInput++;
-
- if (isdigit(c = *yyInput) || c == '-' || c == '+') {
- if (c == '-' || c == '+') {
- sign = c == '-' ? -1 : 1;
- if (!isdigit(*++yyInput))
- /* skip the '-' sign */
- continue;
- }
- else
- sign = 0;
- for (yylval.Number = 0; isdigit(c = *yyInput++); )
- yylval.Number = 10 * yylval.Number + c - '0';
- yyInput--;
- if (sign < 0)
- yylval.Number = -yylval.Number;
- return sign ? tSNUMBER : tUNUMBER;
- }
- if (isalpha(c)) {
- for (p = buff; isalpha(c = *yyInput++) || c == '.'; )
- if (p < &buff[sizeof buff - 1])
- *p++ = c;
- *p = '\0';
- yyInput--;
- return LookupWord(buff);
- }
- if (c != '(')
- return *yyInput++;
- Count = 0;
- do {
- c = *yyInput++;
- if (c == '\0')
- return c;
- if (c == '(')
- Count++;
- else if (c == ')')
- Count--;
- } while (Count > 0);
- }
-}
-
-#define TM_YEAR_ORIGIN 1900
-
-/* Yield A - B, measured in seconds. */
-static long
-difftm (a, b)
- struct tm *a, *b;
-{
- int ay = a->tm_year + (TM_YEAR_ORIGIN - 1);
- int by = b->tm_year + (TM_YEAR_ORIGIN - 1);
- int days = (
- /* difference in day of year */
- a->tm_yday - b->tm_yday
- /* + intervening leap days */
- + ((ay >> 2) - (by >> 2))
- - (ay/100 - by/100)
- + ((ay/100 >> 2) - (by/100 >> 2))
- /* + difference in years * 365 */
- + (long)(ay-by) * 365
- );
- return (60*(60*(24*days + (a->tm_hour - b->tm_hour))
- + (a->tm_min - b->tm_min))
- + (a->tm_sec - b->tm_sec));
-}
-
-time_t
-get_date(p, now)
- char *p;
- struct timeb *now;
-{
- struct tm *tm, gmt;
- struct timeb ftz;
- time_t Start;
- time_t tod;
-
- yyInput = p;
- if (now == NULL) {
- now = &ftz;
- (void)time(&ftz.time);
-
- if (! (tm = gmtime (&ftz.time)))
- return -1;
- gmt = *tm; /* Make a copy, in case localtime modifies *tm. */
-
- if (! (tm = localtime (&ftz.time)))
- return -1;
-
- ftz.timezone = difftm (&gmt, tm) / 60;
- if(tm->tm_isdst)
- ftz.timezone += 60;
- }
-
- tm = localtime(&now->time);
- yyYear = tm->tm_year;
- yyMonth = tm->tm_mon + 1;
- yyDay = tm->tm_mday;
- yyTimezone = now->timezone;
- yyDSTmode = DSTmaybe;
- yyHour = 0;
- yyMinutes = 0;
- yySeconds = 0;
- yyMeridian = MER24;
- yyRelSeconds = 0;
- yyRelMonth = 0;
- yyHaveDate = 0;
- yyHaveDay = 0;
- yyHaveRel = 0;
- yyHaveTime = 0;
- yyHaveZone = 0;
-
- if (yyparse()
- || yyHaveTime > 1 || yyHaveZone > 1 || yyHaveDate > 1 || yyHaveDay > 1)
- return -1;
-
- if (yyHaveDate || yyHaveTime || yyHaveDay) {
- Start = Convert(yyMonth, yyDay, yyYear, yyHour, yyMinutes, yySeconds,
- yyMeridian, yyDSTmode);
- if (Start < 0)
- return -1;
- }
- else {
- Start = now->time;
- if (!yyHaveRel)
- Start -= ((tm->tm_hour * 60L + tm->tm_min) * 60L) + tm->tm_sec;
- }
-
- Start += yyRelSeconds;
- Start += RelativeMonth(Start, yyRelMonth);
-
- if (yyHaveDay && !yyHaveDate) {
- tod = RelativeDate(Start, yyDayOrdinal, yyDayNumber);
- Start += tod;
- }
-
- /* Have to do *something* with a legitimate -1 so it's distinguishable
- * from the error return value. (Alternately could set errno on error.) */
- return Start == -1 ? 0 : Start;
-}
-
-
-#if defined(TEST)
-
-/* ARGSUSED */
-int
-main(ac, av)
- int ac;
- char *av[];
-{
- char buff[128];
- time_t d;
-
- (void)printf("Enter date, or blank line to exit.\n\t> ");
- (void)fflush(stdout);
- while (gets(buff) && buff[0]) {
- d = get_date(buff, (struct timeb *)NULL);
- if (d == -1)
- (void)printf("Bad format - couldn't convert.\n");
- else
- (void)printf("%s", ctime(&d));
- (void)printf("\t> ");
- (void)fflush(stdout);
- }
- exit(0);
- /* NOTREACHED */
-}
-#endif /* defined(TEST) */
diff --git a/gnu/usr.bin/cvs/lib/getline.c b/gnu/usr.bin/cvs/lib/getline.c
deleted file mode 100644
index c69946148f69..000000000000
--- a/gnu/usr.bin/cvs/lib/getline.c
+++ /dev/null
@@ -1,126 +0,0 @@
-/* getline.c -- Replacement for GNU C library function getline
-
-Copyright (C) 1993 Free Software Foundation, Inc.
-
-This program is free software; you can redistribute it and/or
-modify it under the terms of the GNU General Public License as
-published by the Free Software Foundation; either version 2 of the
-License, or (at your option) any later version.
-
-This program is distributed in the hope that it will be useful, but
-WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
-
-/* Written by Jan Brittenson, bson@gnu.ai.mit.edu. */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <sys/types.h>
-#include <stdio.h>
-#define NDEBUG
-#include <assert.h>
-
-#if STDC_HEADERS
-#include <stdlib.h>
-#else
-char *malloc (), *realloc ();
-#endif
-
-/* Always add at least this many bytes when extending the buffer. */
-#define MIN_CHUNK 64
-
-/* Read up to (and including) a TERMINATOR from STREAM into *LINEPTR
- + OFFSET (and null-terminate it). *LINEPTR is a pointer returned from
- malloc (or NULL), pointing to *N characters of space. It is realloc'd
- as necessary. Return the number of characters read (not including the
- null terminator), or -1 on error or EOF. */
-
-int
-getstr (lineptr, n, stream, terminator, offset)
- char **lineptr;
- size_t *n;
- FILE *stream;
- char terminator;
- int offset;
-{
- int nchars_avail; /* Allocated but unused chars in *LINEPTR. */
- char *read_pos; /* Where we're reading into *LINEPTR. */
- int ret;
-
- if (!lineptr || !n || !stream)
- return -1;
-
- if (!*lineptr)
- {
- *n = MIN_CHUNK;
- *lineptr = malloc (*n);
- if (!*lineptr)
- return -1;
- }
-
- nchars_avail = *n - offset;
- read_pos = *lineptr + offset;
-
- for (;;)
- {
- register int c = getc (stream);
-
- /* We always want at least one char left in the buffer, since we
- always (unless we get an error while reading the first char)
- NUL-terminate the line buffer. */
-
- assert(*n - nchars_avail == read_pos - *lineptr);
- if (nchars_avail < 2)
- {
- if (*n > MIN_CHUNK)
- *n *= 2;
- else
- *n += MIN_CHUNK;
-
- nchars_avail = *n + *lineptr - read_pos;
- *lineptr = realloc (*lineptr, *n);
- if (!*lineptr)
- return -1;
- read_pos = *n - nchars_avail + *lineptr;
- assert(*n - nchars_avail == read_pos - *lineptr);
- }
-
- if (c == EOF || ferror (stream))
- {
- /* Return partial line, if any. */
- if (read_pos == *lineptr)
- return -1;
- else
- break;
- }
-
- *read_pos++ = c;
- nchars_avail--;
-
- if (c == terminator)
- /* Return the line. */
- break;
- }
-
- /* Done - NUL terminate and return the number of chars read. */
- *read_pos = '\0';
-
- ret = read_pos - (*lineptr + offset);
- return ret;
-}
-
-int
-getline (lineptr, n, stream)
- char **lineptr;
- size_t *n;
- FILE *stream;
-{
- return getstr (lineptr, n, stream, '\n', 0);
-}
diff --git a/gnu/usr.bin/cvs/lib/getline.h b/gnu/usr.bin/cvs/lib/getline.h
deleted file mode 100644
index 30bcc258373d..000000000000
--- a/gnu/usr.bin/cvs/lib/getline.h
+++ /dev/null
@@ -1,15 +0,0 @@
-#ifndef _getline_h_
-#define _getline_h_ 1
-
-#include <stdio.h>
-
-#if defined (__GNUC__) || (defined (__STDC__) && __STDC__)
-#define __PROTO(args) args
-#else
-#define __PROTO(args) ()
-#endif /* GCC. */
-
-int
- getline __PROTO ((char **_lineptr, size_t *_n, FILE *_stream));
-
-#endif /* _getline_h_ */
diff --git a/gnu/usr.bin/cvs/lib/getopt.c b/gnu/usr.bin/cvs/lib/getopt.c
deleted file mode 100644
index f1d8dfa13450..000000000000
--- a/gnu/usr.bin/cvs/lib/getopt.c
+++ /dev/null
@@ -1,763 +0,0 @@
-/* Getopt for GNU.
- NOTE: getopt is now part of the C library, so if you don't know what
- "Keep this file name-space clean" means, talk to roland@gnu.ai.mit.edu
- before changing it!
-
- Copyright (C) 1987, 88, 89, 90, 91, 92, 93, 94
- Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License as published by the
- Free Software Foundation; either version 2, or (at your option) any
- later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
-
-/* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>.
- Ditto for AIX 3.2 and <stdlib.h>. */
-#ifndef _NO_PROTO
-#define _NO_PROTO
-#endif
-
-#ifdef HAVE_CONFIG_H
-#if defined (emacs) || defined (CONFIG_BROKETS)
-/* We use <config.h> instead of "config.h" so that a compilation
- using -I. -I$srcdir will use ./config.h rather than $srcdir/config.h
- (which it would do because it found this file in $srcdir). */
-#include <config.h>
-#else
-#include "config.h"
-#endif
-#endif
-
-#ifndef __STDC__
-/* This is a separate conditional since some stdc systems
- reject `defined (const)'. */
-#ifndef const
-#define const
-#endif
-#endif
-
-#include <stdio.h>
-
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
-
-/* Comment out all this code if we are using the GNU C Library, and are not
- actually compiling the library itself. This code is part of the GNU C
- Library, but also included in many other GNU distributions. Compiling
- and linking in this code is a waste when using the GNU C library
- (especially if it is a shared library). Rather than having every GNU
- program understand `configure --with-gnu-libc' and omit the object files,
- it is simpler to just do this in the source for each such file. */
-
-#if defined (_LIBC) || !defined (__GNU_LIBRARY__)
-
-
-/* This needs to come after some library #include
- to get __GNU_LIBRARY__ defined. */
-#ifdef __GNU_LIBRARY__
-/* Don't include stdlib.h for non-GNU C libraries because some of them
- contain conflicting prototypes for getopt. */
-#include <stdlib.h>
-#endif /* GNU C library. */
-
-/* This version of `getopt' appears to the caller like standard Unix `getopt'
- but it behaves differently for the user, since it allows the user
- to intersperse the options with the other arguments.
-
- As `getopt' works, it permutes the elements of ARGV so that,
- when it is done, all the options precede everything else. Thus
- all application programs are extended to handle flexible argument order.
-
- Setting the environment variable POSIXLY_CORRECT disables permutation.
- Then the behavior is completely standard.
-
- GNU application programs can use a third alternative mode in which
- they can distinguish the relative order of options and other arguments. */
-
-#ifndef lint
-static char rcsid[] = "$CVSid: @(#)getopt.c 1.10 94/09/21 $";
-#endif
-
-#include "getopt.h"
-
-/* For communication from `getopt' to the caller.
- When `getopt' finds an option that takes an argument,
- the argument value is returned here.
- Also, when `ordering' is RETURN_IN_ORDER,
- each non-option ARGV-element is returned here. */
-
-char *optarg = NULL;
-
-/* Index in ARGV of the next element to be scanned.
- This is used for communication to and from the caller
- and for communication between successive calls to `getopt'.
-
- On entry to `getopt', zero means this is the first call; initialize.
-
- When `getopt' returns EOF, this is the index of the first of the
- non-option elements that the caller should itself scan.
-
- Otherwise, `optind' communicates from one call to the next
- how much of ARGV has been scanned so far. */
-
-/* XXX 1003.2 says this must be 1 before any call. */
-int optind = 0;
-
-/* The next char to be scanned in the option-element
- in which the last option character we returned was found.
- This allows us to pick up the scan where we left off.
-
- If this is zero, or a null string, it means resume the scan
- by advancing to the next ARGV-element. */
-
-static char *nextchar;
-
-/* Callers store zero here to inhibit the error message
- for unrecognized options. */
-
-int opterr = 1;
-
-/* Set to an option character which was unrecognized.
- This must be initialized on some systems to avoid linking in the
- system's own getopt implementation. */
-
-int optopt = '?';
-
-/* Describe how to deal with options that follow non-option ARGV-elements.
-
- If the caller did not specify anything,
- the default is REQUIRE_ORDER if the environment variable
- POSIXLY_CORRECT is defined, PERMUTE otherwise.
-
- REQUIRE_ORDER means don't recognize them as options;
- stop option processing when the first non-option is seen.
- This is what Unix does.
- This mode of operation is selected by either setting the environment
- variable POSIXLY_CORRECT, or using `+' as the first character
- of the list of option characters.
-
- PERMUTE is the default. We permute the contents of ARGV as we scan,
- so that eventually all the non-options are at the end. This allows options
- to be given in any order, even with programs that were not written to
- expect this.
-
- RETURN_IN_ORDER is an option available to programs that were written
- to expect options and other ARGV-elements in any order and that care about
- the ordering of the two. We describe each non-option ARGV-element
- as if it were the argument of an option with character code 1.
- Using `-' as the first character of the list of option characters
- selects this mode of operation.
-
- The special argument `--' forces an end of option-scanning regardless
- of the value of `ordering'. In the case of RETURN_IN_ORDER, only
- `--' can cause `getopt' to return EOF with `optind' != ARGC. */
-
-static enum
-{
- REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
-} ordering;
-
-/* Value of POSIXLY_CORRECT environment variable. */
-static char *posixly_correct;
-
-#ifdef __GNU_LIBRARY__
-/* We want to avoid inclusion of string.h with non-GNU libraries
- because there are many ways it can cause trouble.
- On some systems, it contains special magic macros that don't work
- in GCC. */
-#include <string.h>
-#define my_index strchr
-#else
-
-/* Avoid depending on library functions or files
- whose names are inconsistent. */
-
-char *getenv ();
-
-static char *
-my_index (str, chr)
- const char *str;
- int chr;
-{
- while (*str)
- {
- if (*str == chr)
- return (char *) str;
- str++;
- }
- return 0;
-}
-
-/* If using GCC, we can safely declare strlen this way.
- If not using GCC, it is ok not to declare it. */
-#ifdef __GNUC__
-/* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h.
- That was relevant to code that was here before. */
-#ifndef __STDC__
-/* gcc with -traditional declares the built-in strlen to return int,
- and has done so at least since version 2.4.5. -- rms. */
-extern int strlen (const char *);
-#endif /* not __STDC__ */
-#endif /* __GNUC__ */
-
-#endif /* not __GNU_LIBRARY__ */
-
-/* Handle permutation of arguments. */
-
-/* Describe the part of ARGV that contains non-options that have
- been skipped. `first_nonopt' is the index in ARGV of the first of them;
- `last_nonopt' is the index after the last of them. */
-
-static int first_nonopt;
-static int last_nonopt;
-
-/* Exchange two adjacent subsequences of ARGV.
- One subsequence is elements [first_nonopt,last_nonopt)
- which contains all the non-options that have been skipped so far.
- The other is elements [last_nonopt,optind), which contains all
- the options processed since those non-options were skipped.
-
- `first_nonopt' and `last_nonopt' are relocated so that they describe
- the new indices of the non-options in ARGV after they are moved. */
-
-static void
-exchange (argv)
- char **argv;
-{
- int bottom = first_nonopt;
- int middle = last_nonopt;
- int top = optind;
- char *tem;
-
- /* Exchange the shorter segment with the far end of the longer segment.
- That puts the shorter segment into the right place.
- It leaves the longer segment in the right place overall,
- but it consists of two parts that need to be swapped next. */
-
- while (top > middle && middle > bottom)
- {
- if (top - middle > middle - bottom)
- {
- /* Bottom segment is the short one. */
- int len = middle - bottom;
- register int i;
-
- /* Swap it with the top part of the top segment. */
- for (i = 0; i < len; i++)
- {
- tem = argv[bottom + i];
- argv[bottom + i] = argv[top - (middle - bottom) + i];
- argv[top - (middle - bottom) + i] = tem;
- }
- /* Exclude the moved bottom segment from further swapping. */
- top -= len;
- }
- else
- {
- /* Top segment is the short one. */
- int len = top - middle;
- register int i;
-
- /* Swap it with the bottom part of the bottom segment. */
- for (i = 0; i < len; i++)
- {
- tem = argv[bottom + i];
- argv[bottom + i] = argv[middle + i];
- argv[middle + i] = tem;
- }
- /* Exclude the moved top segment from further swapping. */
- bottom += len;
- }
- }
-
- /* Update records for the slots the non-options now occupy. */
-
- first_nonopt += (optind - last_nonopt);
- last_nonopt = optind;
-}
-
-/* Initialize the internal data when the first call is made. */
-
-static const char *
-_getopt_initialize (optstring)
- const char *optstring;
-{
- /* Start processing options with ARGV-element 1 (since ARGV-element 0
- is the program name); the sequence of previously skipped
- non-option ARGV-elements is empty. */
-
- first_nonopt = last_nonopt = optind = 1;
-
- nextchar = NULL;
-
- posixly_correct = getenv ("POSIXLY_CORRECT");
-
- /* Determine how to handle the ordering of options and nonoptions. */
-
- if (optstring[0] == '-')
- {
- ordering = RETURN_IN_ORDER;
- ++optstring;
- }
- else if (optstring[0] == '+')
- {
- ordering = REQUIRE_ORDER;
- ++optstring;
- }
- else if (posixly_correct != NULL)
- ordering = REQUIRE_ORDER;
- else
- ordering = PERMUTE;
-
- return optstring;
-}
-
-/* Scan elements of ARGV (whose length is ARGC) for option characters
- given in OPTSTRING.
-
- If an element of ARGV starts with '-', and is not exactly "-" or "--",
- then it is an option element. The characters of this element
- (aside from the initial '-') are option characters. If `getopt'
- is called repeatedly, it returns successively each of the option characters
- from each of the option elements.
-
- If `getopt' finds another option character, it returns that character,
- updating `optind' and `nextchar' so that the next call to `getopt' can
- resume the scan with the following option character or ARGV-element.
-
- If there are no more option characters, `getopt' returns `EOF'.
- Then `optind' is the index in ARGV of the first ARGV-element
- that is not an option. (The ARGV-elements have been permuted
- so that those that are not options now come last.)
-
- OPTSTRING is a string containing the legitimate option characters.
- If an option character is seen that is not listed in OPTSTRING,
- return '?' after printing an error message. If you set `opterr' to
- zero, the error message is suppressed but we still return '?'.
-
- If a char in OPTSTRING is followed by a colon, that means it wants an arg,
- so the following text in the same ARGV-element, or the text of the following
- ARGV-element, is returned in `optarg'. Two colons mean an option that
- wants an optional arg; if there is text in the current ARGV-element,
- it is returned in `optarg', otherwise `optarg' is set to zero.
-
- If OPTSTRING starts with `-' or `+', it requests different methods of
- handling the non-option ARGV-elements.
- See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
-
- Long-named options begin with `--' instead of `-'.
- Their names may be abbreviated as long as the abbreviation is unique
- or is an exact match for some defined option. If they have an
- argument, it follows the option name in the same ARGV-element, separated
- from the option name by a `=', or else the in next ARGV-element.
- When `getopt' finds a long-named option, it returns 0 if that option's
- `flag' field is nonzero, the value of the option's `val' field
- if the `flag' field is zero.
-
- The elements of ARGV aren't really const, because we permute them.
- But we pretend they're const in the prototype to be compatible
- with other systems.
-
- LONGOPTS is a vector of `struct option' terminated by an
- element containing a name which is zero.
-
- LONGIND returns the index in LONGOPT of the long-named option found.
- It is only valid when a long-named option has been found by the most
- recent call.
-
- If LONG_ONLY is nonzero, '-' as well as '--' can introduce
- long-named options. */
-
-int
-_getopt_internal (argc, argv, optstring, longopts, longind, long_only)
- int argc;
- char *const *argv;
- const char *optstring;
- const struct option *longopts;
- int *longind;
- int long_only;
-{
- optarg = NULL;
-
- if (optind == 0)
- optstring = _getopt_initialize (optstring);
-
- if (nextchar == NULL || *nextchar == '\0')
- {
- /* Advance to the next ARGV-element. */
-
- if (ordering == PERMUTE)
- {
- /* If we have just processed some options following some non-options,
- exchange them so that the options come first. */
-
- if (first_nonopt != last_nonopt && last_nonopt != optind)
- exchange ((char **) argv);
- else if (last_nonopt != optind)
- first_nonopt = optind;
-
- /* Skip any additional non-options
- and extend the range of non-options previously skipped. */
-
- while (optind < argc
- && (argv[optind][0] != '-' || argv[optind][1] == '\0'))
- optind++;
- last_nonopt = optind;
- }
-
- /* The special ARGV-element `--' means premature end of options.
- Skip it like a null option,
- then exchange with previous non-options as if it were an option,
- then skip everything else like a non-option. */
-
- if (optind != argc && !strcmp (argv[optind], "--"))
- {
- optind++;
-
- if (first_nonopt != last_nonopt && last_nonopt != optind)
- exchange ((char **) argv);
- else if (first_nonopt == last_nonopt)
- first_nonopt = optind;
- last_nonopt = argc;
-
- optind = argc;
- }
-
- /* If we have done all the ARGV-elements, stop the scan
- and back over any non-options that we skipped and permuted. */
-
- if (optind == argc)
- {
- /* Set the next-arg-index to point at the non-options
- that we previously skipped, so the caller will digest them. */
- if (first_nonopt != last_nonopt)
- optind = first_nonopt;
- return EOF;
- }
-
- /* If we have come to a non-option and did not permute it,
- either stop the scan or describe it to the caller and pass it by. */
-
- if ((argv[optind][0] != '-' || argv[optind][1] == '\0'))
- {
- if (ordering == REQUIRE_ORDER)
- return EOF;
- optarg = argv[optind++];
- return 1;
- }
-
- /* We have found another option-ARGV-element.
- Skip the initial punctuation. */
-
- nextchar = (argv[optind] + 1
- + (longopts != NULL && argv[optind][1] == '-'));
- }
-
- /* Decode the current option-ARGV-element. */
-
- /* Check whether the ARGV-element is a long option.
-
- If long_only and the ARGV-element has the form "-f", where f is
- a valid short option, don't consider it an abbreviated form of
- a long option that starts with f. Otherwise there would be no
- way to give the -f short option.
-
- On the other hand, if there's a long option "fubar" and
- the ARGV-element is "-fu", do consider that an abbreviation of
- the long option, just like "--fu", and not "-f" with arg "u".
-
- This distinction seems to be the most useful approach. */
-
- if (longopts != NULL
- && (argv[optind][1] == '-'
- || (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1])))))
- {
- char *nameend;
- const struct option *p;
- const struct option *pfound = NULL;
- int exact = 0;
- int ambig = 0;
- int indfound;
- int option_index;
-
- for (nameend = nextchar; *nameend && *nameend != '='; nameend++)
- /* Do nothing. */ ;
-
- /* Test all long options for either exact match
- or abbreviated matches. */
- for (p = longopts, option_index = 0; p->name; p++, option_index++)
- if (!strncmp (p->name, nextchar, nameend - nextchar))
- {
- if (nameend - nextchar == (int) strlen (p->name))
- {
- /* Exact match found. */
- pfound = p;
- indfound = option_index;
- exact = 1;
- break;
- }
- else if (pfound == NULL)
- {
- /* First nonexact match found. */
- pfound = p;
- indfound = option_index;
- }
- else
- /* Second or later nonexact match found. */
- ambig = 1;
- }
-
- if (ambig && !exact)
- {
- if (opterr)
- fprintf (stderr, "%s: option `%s' is ambiguous\n",
- argv[0], argv[optind]);
- nextchar += strlen (nextchar);
- optind++;
- return '?';
- }
-
- if (pfound != NULL)
- {
- option_index = indfound;
- optind++;
- if (*nameend)
- {
- /* Don't test has_arg with >, because some C compilers don't
- allow it to be used on enums. */
- if (pfound->has_arg)
- optarg = nameend + 1;
- else
- {
- if (opterr)
- {
- if (argv[optind - 1][1] == '-')
- /* --option */
- fprintf (stderr,
- "%s: option `--%s' doesn't allow an argument\n",
- argv[0], pfound->name);
- else
- /* +option or -option */
- fprintf (stderr,
- "%s: option `%c%s' doesn't allow an argument\n",
- argv[0], argv[optind - 1][0], pfound->name);
- }
- nextchar += strlen (nextchar);
- return '?';
- }
- }
- else if (pfound->has_arg == 1)
- {
- if (optind < argc)
- optarg = argv[optind++];
- else
- {
- if (opterr)
- fprintf (stderr, "%s: option `%s' requires an argument\n",
- argv[0], argv[optind - 1]);
- nextchar += strlen (nextchar);
- return optstring[0] == ':' ? ':' : '?';
- }
- }
- nextchar += strlen (nextchar);
- if (longind != NULL)
- *longind = option_index;
- if (pfound->flag)
- {
- *(pfound->flag) = pfound->val;
- return 0;
- }
- return pfound->val;
- }
-
- /* Can't find it as a long option. If this is not getopt_long_only,
- or the option starts with '--' or is not a valid short
- option, then it's an error.
- Otherwise interpret it as a short option. */
- if (!long_only || argv[optind][1] == '-'
- || my_index (optstring, *nextchar) == NULL)
- {
- if (opterr)
- {
- if (argv[optind][1] == '-')
- /* --option */
- fprintf (stderr, "%s: unrecognized option `--%s'\n",
- argv[0], nextchar);
- else
- /* +option or -option */
- fprintf (stderr, "%s: unrecognized option `%c%s'\n",
- argv[0], argv[optind][0], nextchar);
- }
- nextchar = (char *) "";
- optind++;
- return '?';
- }
- }
-
- /* Look at and handle the next short option-character. */
-
- {
- char c = *nextchar++;
- char *temp = my_index (optstring, c);
-
- /* Increment `optind' when we start to process its last character. */
- if (*nextchar == '\0')
- ++optind;
-
- if (temp == NULL || c == ':')
- {
- if (opterr)
- {
- if (posixly_correct)
- /* 1003.2 specifies the format of this message. */
- fprintf (stderr, "%s: illegal option -- %c\n", argv[0], c);
- else
- fprintf (stderr, "%s: invalid option -- %c\n", argv[0], c);
- }
- optopt = c;
- return '?';
- }
- if (temp[1] == ':')
- {
- if (temp[2] == ':')
- {
- /* This is an option that accepts an argument optionally. */
- if (*nextchar != '\0')
- {
- optarg = nextchar;
- optind++;
- }
- else
- optarg = NULL;
- nextchar = NULL;
- }
- else
- {
- /* This is an option that requires an argument. */
- if (*nextchar != '\0')
- {
- optarg = nextchar;
- /* If we end this ARGV-element by taking the rest as an arg,
- we must advance to the next element now. */
- optind++;
- }
- else if (optind == argc)
- {
- if (opterr)
- {
- /* 1003.2 specifies the format of this message. */
- fprintf (stderr, "%s: option requires an argument -- %c\n",
- argv[0], c);
- }
- optopt = c;
- if (optstring[0] == ':')
- c = ':';
- else
- c = '?';
- }
- else
- /* We already incremented `optind' once;
- increment it again when taking next ARGV-elt as argument. */
- optarg = argv[optind++];
- nextchar = NULL;
- }
- }
- return c;
- }
-}
-
-int
-getopt (argc, argv, optstring)
- int argc;
- char *const *argv;
- const char *optstring;
-{
- return _getopt_internal (argc, argv, optstring,
- (const struct option *) 0,
- (int *) 0,
- 0);
-}
-
-#endif /* _LIBC or not __GNU_LIBRARY__. */
-
-#ifdef TEST
-
-/* Compile with -DTEST to make an executable for use in testing
- the above definition of `getopt'. */
-
-int
-main (argc, argv)
- int argc;
- char **argv;
-{
- int c;
- int digit_optind = 0;
-
- while (1)
- {
- int this_option_optind = optind ? optind : 1;
-
- c = getopt (argc, argv, "abc:d:0123456789");
- if (c == EOF)
- break;
-
- switch (c)
- {
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- if (digit_optind != 0 && digit_optind != this_option_optind)
- printf ("digits occur in two different argv-elements.\n");
- digit_optind = this_option_optind;
- printf ("option %c\n", c);
- break;
-
- case 'a':
- printf ("option a\n");
- break;
-
- case 'b':
- printf ("option b\n");
- break;
-
- case 'c':
- printf ("option c with value `%s'\n", optarg);
- break;
-
- case '?':
- break;
-
- default:
- printf ("?? getopt returned character code 0%o ??\n", c);
- }
- }
-
- if (optind < argc)
- {
- printf ("non-option ARGV-elements: ");
- while (optind < argc)
- printf ("%s ", argv[optind++]);
- printf ("\n");
- }
-
- exit (0);
-}
-
-#endif /* TEST */
diff --git a/gnu/usr.bin/cvs/lib/getopt.h b/gnu/usr.bin/cvs/lib/getopt.h
deleted file mode 100644
index f644aa15f465..000000000000
--- a/gnu/usr.bin/cvs/lib/getopt.h
+++ /dev/null
@@ -1,131 +0,0 @@
-/* Declarations for getopt.
- Copyright (C) 1989, 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License as published by the
- Free Software Foundation; either version 2, or (at your option) any
- later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
-
-/* $CVSid: @(#)getopt.h 1.7 94/09/21 $ */
-
-#ifndef _GETOPT_H
-#define _GETOPT_H 1
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* For communication from `getopt' to the caller.
- When `getopt' finds an option that takes an argument,
- the argument value is returned here.
- Also, when `ordering' is RETURN_IN_ORDER,
- each non-option ARGV-element is returned here. */
-
-extern char *optarg;
-
-/* Index in ARGV of the next element to be scanned.
- This is used for communication to and from the caller
- and for communication between successive calls to `getopt'.
-
- On entry to `getopt', zero means this is the first call; initialize.
-
- When `getopt' returns EOF, this is the index of the first of the
- non-option elements that the caller should itself scan.
-
- Otherwise, `optind' communicates from one call to the next
- how much of ARGV has been scanned so far. */
-
-extern int optind;
-
-/* Callers store zero here to inhibit the error message `getopt' prints
- for unrecognized options. */
-
-extern int opterr;
-
-/* Set to an option character which was unrecognized. */
-
-extern int optopt;
-
-/* Describe the long-named options requested by the application.
- The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector
- of `struct option' terminated by an element containing a name which is
- zero.
-
- The field `has_arg' is:
- no_argument (or 0) if the option does not take an argument,
- required_argument (or 1) if the option requires an argument,
- optional_argument (or 2) if the option takes an optional argument.
-
- If the field `flag' is not NULL, it points to a variable that is set
- to the value given in the field `val' when the option is found, but
- left unchanged if the option is not found.
-
- To have a long-named option do something other than set an `int' to
- a compiled-in constant, such as set a value from `optarg', set the
- option's `flag' field to zero and its `val' field to a nonzero
- value (the equivalent single-letter option character, if there is
- one). For long options that have a zero `flag' field, `getopt'
- returns the contents of the `val' field. */
-
-struct option
-{
-#if __STDC__
- const char *name;
-#else
- char *name;
-#endif
- /* has_arg can't be an enum because some compilers complain about
- type mismatches in all the code that assumes it is an int. */
- int has_arg;
- int *flag;
- int val;
-};
-
-/* Names for the values of the `has_arg' field of `struct option'. */
-
-#define no_argument 0
-#define required_argument 1
-#define optional_argument 2
-
-#if __STDC__
-#if defined(__GNU_LIBRARY__)
-/* Many other libraries have conflicting prototypes for getopt, with
- differences in the consts, in stdlib.h. To avoid compilation
- errors, only prototype getopt for the GNU C library. */
-extern int getopt (int argc, char *const *argv, const char *shortopts);
-#else /* not __GNU_LIBRARY__ */
-extern int getopt ();
-#endif /* not __GNU_LIBRARY__ */
-extern int getopt_long (int argc, char *const *argv, const char *shortopts,
- const struct option *longopts, int *longind);
-extern int getopt_long_only (int argc, char *const *argv,
- const char *shortopts,
- const struct option *longopts, int *longind);
-
-/* Internal only. Users should not call this directly. */
-extern int _getopt_internal (int argc, char *const *argv,
- const char *shortopts,
- const struct option *longopts, int *longind,
- int long_only);
-#else /* not __STDC__ */
-extern int getopt ();
-extern int getopt_long ();
-extern int getopt_long_only ();
-
-extern int _getopt_internal ();
-#endif /* not __STDC__ */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _GETOPT_H */
diff --git a/gnu/usr.bin/cvs/lib/getopt1.c b/gnu/usr.bin/cvs/lib/getopt1.c
deleted file mode 100644
index f784b5757c59..000000000000
--- a/gnu/usr.bin/cvs/lib/getopt1.c
+++ /dev/null
@@ -1,187 +0,0 @@
-/* getopt_long and getopt_long_only entry points for GNU getopt.
- Copyright (C) 1987, 88, 89, 90, 91, 92, 1993
- Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License as published by the
- Free Software Foundation; either version 2, or (at your option) any
- later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
-
-#ifdef HAVE_CONFIG_H
-#if defined (emacs) || defined (CONFIG_BROKETS)
-/* We use <config.h> instead of "config.h" so that a compilation
- using -I. -I$srcdir will use ./config.h rather than $srcdir/config.h
- (which it would do because it found this file in $srcdir). */
-#include <config.h>
-#else
-#include "config.h"
-#endif
-#endif
-
-#include "getopt.h"
-
-#ifndef __STDC__
-/* This is a separate conditional since some stdc systems
- reject `defined (const)'. */
-#ifndef const
-#define const
-#endif
-#endif
-
-#include <stdio.h>
-
-/* Comment out all this code if we are using the GNU C Library, and are not
- actually compiling the library itself. This code is part of the GNU C
- Library, but also included in many other GNU distributions. Compiling
- and linking in this code is a waste when using the GNU C library
- (especially if it is a shared library). Rather than having every GNU
- program understand `configure --with-gnu-libc' and omit the object files,
- it is simpler to just do this in the source for each such file. */
-
-#if defined (_LIBC) || !defined (__GNU_LIBRARY__)
-
-
-/* This needs to come after some library #include
- to get __GNU_LIBRARY__ defined. */
-#ifdef __GNU_LIBRARY__
-#include <stdlib.h>
-#else
-char *getenv ();
-#endif
-
-#ifndef NULL
-#define NULL 0
-#endif
-
-int
-getopt_long (argc, argv, options, long_options, opt_index)
- int argc;
- char *const *argv;
- const char *options;
- const struct option *long_options;
- int *opt_index;
-{
- return _getopt_internal (argc, argv, options, long_options, opt_index, 0);
-}
-
-/* Like getopt_long, but '-' as well as '--' can indicate a long option.
- If an option that starts with '-' (not '--') doesn't match a long option,
- but does match a short option, it is parsed as a short option
- instead. */
-
-int
-getopt_long_only (argc, argv, options, long_options, opt_index)
- int argc;
- char *const *argv;
- const char *options;
- const struct option *long_options;
- int *opt_index;
-{
- return _getopt_internal (argc, argv, options, long_options, opt_index, 1);
-}
-
-
-#endif /* _LIBC or not __GNU_LIBRARY__. */
-
-#ifdef TEST
-
-#include <stdio.h>
-
-int
-main (argc, argv)
- int argc;
- char **argv;
-{
- int c;
- int digit_optind = 0;
-
- while (1)
- {
- int this_option_optind = optind ? optind : 1;
- int option_index = 0;
- static struct option long_options[] =
- {
- {"add", 1, 0, 0},
- {"append", 0, 0, 0},
- {"delete", 1, 0, 0},
- {"verbose", 0, 0, 0},
- {"create", 0, 0, 0},
- {"file", 1, 0, 0},
- {0, 0, 0, 0}
- };
-
- c = getopt_long (argc, argv, "abc:d:0123456789",
- long_options, &option_index);
- if (c == EOF)
- break;
-
- switch (c)
- {
- case 0:
- printf ("option %s", long_options[option_index].name);
- if (optarg)
- printf (" with arg %s", optarg);
- printf ("\n");
- break;
-
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- if (digit_optind != 0 && digit_optind != this_option_optind)
- printf ("digits occur in two different argv-elements.\n");
- digit_optind = this_option_optind;
- printf ("option %c\n", c);
- break;
-
- case 'a':
- printf ("option a\n");
- break;
-
- case 'b':
- printf ("option b\n");
- break;
-
- case 'c':
- printf ("option c with value `%s'\n", optarg);
- break;
-
- case 'd':
- printf ("option d with value `%s'\n", optarg);
- break;
-
- case '?':
- break;
-
- default:
- printf ("?? getopt returned character code 0%o ??\n", c);
- }
- }
-
- if (optind < argc)
- {
- printf ("non-option ARGV-elements: ");
- while (optind < argc)
- printf ("%s ", argv[optind++]);
- printf ("\n");
- }
-
- exit (0);
-}
-
-#endif /* TEST */
diff --git a/gnu/usr.bin/cvs/lib/getwd.c b/gnu/usr.bin/cvs/lib/getwd.c
deleted file mode 100644
index 573a7889244d..000000000000
--- a/gnu/usr.bin/cvs/lib/getwd.c
+++ /dev/null
@@ -1,35 +0,0 @@
-/* getwd.c -- get current working directory pathname
- Copyright (C) 1992 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
-
-/* Some systems which include both getwd() and getcwd() have an implementation
- of getwd() which is much faster than getcwd(). As a result, we use the
- system's getwd() if it is available */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "system.h"
-
-/* Get the current working directory into PATHNAME */
-
-char *
-getwd (pathname)
- char *pathname;
-{
- return (getcwd(pathname, PATH_MAX));
-}
diff --git a/gnu/usr.bin/cvs/lib/hash.c b/gnu/usr.bin/cvs/lib/hash.c
deleted file mode 100644
index 8ac93237c380..000000000000
--- a/gnu/usr.bin/cvs/lib/hash.c
+++ /dev/null
@@ -1,400 +0,0 @@
-/*
- * Copyright (c) 1992, Brian Berliner and Jeff Polk
- *
- * You may distribute under the terms of the GNU General Public License as
- * specified in the README file that comes with the CVS 1.4 kit.
- *
- * Polk's hash list manager. So cool.
- */
-
-#include "cvs.h"
-
-#ifndef lint
-static const char rcsid[] = "$CVSid: @(#)hash.c 1.19 94/09/23 $";
-USE(rcsid);
-#endif
-
-/* global caches */
-static List *listcache = NULL;
-static Node *nodecache = NULL;
-
-static void freenode_mem PROTO((Node * p));
-
-/* hash function */
-static int
-hashp (key)
- const char *key;
-{
- unsigned int h = 0;
- unsigned int g;
-
- while (*key != 0)
- {
- h = (h << 4) + *key++;
- if ((g = h & 0xf0000000) != 0)
- h = (h ^ (g >> 24)) ^ g;
- }
-
- return (h % HASHSIZE);
-}
-
-/*
- * create a new list (or get an old one from the cache)
- */
-List *
-getlist ()
-{
- int i;
- List *list;
- Node *node;
-
- if (listcache != NULL)
- {
- /* get a list from the cache and clear it */
- list = listcache;
- listcache = listcache->next;
- list->next = (List *) NULL;
- for (i = 0; i < HASHSIZE; i++)
- list->hasharray[i] = (Node *) NULL;
- }
- else
- {
- /* make a new list from scratch */
- list = (List *) xmalloc (sizeof (List));
- memset ((char *) list, 0, sizeof (List));
- node = getnode ();
- list->list = node;
- node->type = HEADER;
- node->next = node->prev = node;
- }
- return (list);
-}
-
-/*
- * free up a list
- */
-void
-dellist (listp)
- List **listp;
-{
- int i;
- Node *p;
-
- if (*listp == (List *) NULL)
- return;
-
- p = (*listp)->list;
-
- /* free each node in the list (except header) */
- while (p->next != p)
- delnode (p->next);
-
- /* free any list-private data, without freeing the actual header */
- freenode_mem (p);
-
- /* free up the header nodes for hash lists (if any) */
- for (i = 0; i < HASHSIZE; i++)
- {
- if ((p = (*listp)->hasharray[i]) != (Node *) NULL)
- {
- /* put the nodes into the cache */
- p->type = UNKNOWN;
- p->next = nodecache;
- nodecache = p;
- }
- }
-
- /* put it on the cache */
- (*listp)->next = listcache;
- listcache = *listp;
- *listp = (List *) NULL;
-}
-
-/*
- * get a new list node
- */
-Node *
-getnode ()
-{
- Node *p;
-
- if (nodecache != (Node *) NULL)
- {
- /* get one from the cache */
- p = nodecache;
- nodecache = p->next;
- }
- else
- {
- /* make a new one */
- p = (Node *) xmalloc (sizeof (Node));
- }
-
- /* always make it clean */
- memset ((char *) p, 0, sizeof (Node));
- p->type = UNKNOWN;
-
- return (p);
-}
-
-/*
- * remove a node from it's list (maybe hash list too) and free it
- */
-void
-delnode (p)
- Node *p;
-{
- if (p == (Node *) NULL)
- return;
-
- /* take it out of the list */
- p->next->prev = p->prev;
- p->prev->next = p->next;
-
- /* if it was hashed, remove it from there too */
- if (p->hashnext != (Node *) NULL)
- {
- p->hashnext->hashprev = p->hashprev;
- p->hashprev->hashnext = p->hashnext;
- }
-
- /* free up the storage */
- freenode (p);
-}
-
-/*
- * free up the storage associated with a node
- */
-static void
-freenode_mem (p)
- Node *p;
-{
- if (p->delproc != (void (*) ()) NULL)
- p->delproc (p); /* call the specified delproc */
- else
- {
- if (p->data != NULL) /* otherwise free() it if necessary */
- free (p->data);
- }
- if (p->key != NULL) /* free the key if necessary */
- free (p->key);
-
- /* to be safe, re-initialize these */
- p->key = p->data = (char *) NULL;
- p->delproc = (void (*) ()) NULL;
-}
-
-/*
- * free up the storage associated with a node and recycle it
- */
-void
-freenode (p)
- Node *p;
-{
- /* first free the memory */
- freenode_mem (p);
-
- /* then put it in the cache */
- p->type = UNKNOWN;
- p->next = nodecache;
- nodecache = p;
-}
-
-/*
- * insert item p at end of list "list" (maybe hash it too) if hashing and it
- * already exists, return -1 and don't actually put it in the list
- *
- * return 0 on success
- */
-int
-addnode (list, p)
- List *list;
- Node *p;
-{
- int hashval;
- Node *q;
-
- if (p->key != NULL) /* hash it too? */
- {
- hashval = hashp (p->key);
- if (list->hasharray[hashval] == NULL) /* make a header for list? */
- {
- q = getnode ();
- q->type = HEADER;
- list->hasharray[hashval] = q->hashnext = q->hashprev = q;
- }
-
- /* put it into the hash list if it's not already there */
- for (q = list->hasharray[hashval]->hashnext;
- q != list->hasharray[hashval]; q = q->hashnext)
- {
- if (strcmp (p->key, q->key) == 0)
- return (-1);
- }
- q = list->hasharray[hashval];
- p->hashprev = q->hashprev;
- p->hashnext = q;
- p->hashprev->hashnext = p;
- q->hashprev = p;
- }
-
- /* put it into the regular list */
- p->prev = list->list->prev;
- p->next = list->list;
- list->list->prev->next = p;
- list->list->prev = p;
-
- return (0);
-}
-
-/*
- * look up an entry in hash list table and return a pointer to the
- * node. Return NULL on error or not found.
- */
-Node *
-findnode (list, key)
- List *list;
- const char *key;
-{
- Node *head, *p;
-
- if (list == (List *) NULL)
- return ((Node *) NULL);
-
- head = list->hasharray[hashp (key)];
- if (head == (Node *) NULL)
- return ((Node *) NULL);
-
- for (p = head->hashnext; p != head; p = p->hashnext)
- if (strcmp (p->key, key) == 0)
- return (p);
- return ((Node *) NULL);
-}
-
-/*
- * walk a list with a specific proc
- */
-int
-walklist (list, proc, closure)
- List *list;
- int (*proc) PROTO ((Node *, void *));
- void *closure;
-{
- Node *head, *p;
- int err = 0;
-
- if (list == NULL)
- return (0);
-
- head = list->list;
- for (p = head->next; p != head; p = p->next)
- err += proc (p, closure);
- return (err);
-}
-
-/*
- * sort the elements of a list (in place)
- */
-void
-sortlist (list, comp)
- List *list;
- int (*comp) PROTO ((const Node *, const Node *));
-{
- Node *head, *remain, *p, *q;
-
- /* save the old first element of the list */
- head = list->list;
- remain = head->next;
-
- /* make the header node into a null list of it's own */
- head->next = head->prev = head;
-
- /* while there are nodes remaining, do insert sort */
- while (remain != head)
- {
- /* take one from the list */
- p = remain;
- remain = remain->next;
-
- /* traverse the sorted list looking for the place to insert it */
- for (q = head->next; q != head; q = q->next)
- {
- if (comp (p, q) < 0)
- {
- /* p comes before q */
- p->next = q;
- p->prev = q->prev;
- p->prev->next = p;
- q->prev = p;
- break;
- }
- }
- if (q == head)
- {
- /* it belongs at the end of the list */
- p->next = head;
- p->prev = head->prev;
- p->prev->next = p;
- head->prev = p;
- }
- }
-}
-
-/* Debugging functions. Quite useful to call from within gdb. */
-
-char *
-nodetypestring (type)
- Ntype type;
-{
- switch (type) {
- case UNKNOWN: return("UNKNOWN");
- case HEADER: return("HEADER");
- case ENTRIES: return("ENTRIES");
- case FILES: return("FILES");
- case LIST: return("LIST");
- case RCSNODE: return("RCSNODE");
- case RCSVERS: return("RCSVERS");
- case DIRS: return("DIRS");
- case UPDATE: return("UPDATE");
- case LOCK: return("LOCK");
- case NDBMNODE: return("NDBMNODE");
- }
-
- return("<trash>");
-}
-
-static int printnode PROTO ((Node *, void *));
-static int
-printnode (node, closure)
- Node *node;
- void *closure;
-{
- if (node == NULL)
- {
- (void) printf("NULL node.\n");
- return(0);
- }
-
- (void) printf("Node at 0x%p: type = %s, key = 0x%p = \"%s\", data = 0x%p, next = 0x%p, prev = 0x%p\n",
- node, nodetypestring(node->type), node->key, node->key, node->data, node->next, node->prev);
-
- return(0);
-}
-
-void
-printlist (list)
- List *list;
-{
- if (list == NULL)
- {
- (void) printf("NULL list.\n");
- return;
- }
-
- (void) printf("List at 0x%p: list = 0x%p, HASHSIZE = %d, next = 0x%p\n",
- list, list->list, HASHSIZE, list->next);
-
- (void) walklist(list, printnode, NULL);
-
- return;
-}
diff --git a/gnu/usr.bin/cvs/lib/hash.h b/gnu/usr.bin/cvs/lib/hash.h
deleted file mode 100644
index e30511a2701e..000000000000
--- a/gnu/usr.bin/cvs/lib/hash.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/* $CVSid: @(#)hash.h 1.23 94/10/07 $ */
-
-/*
- * Copyright (c) 1992, Brian Berliner and Jeff Polk
- *
- * You may distribute under the terms of the GNU General Public License as
- * specified in the README file that comes with the CVS 1.4 kit.
- */
-
-/*
- * The number of buckets for the hash table contained in each list. This
- * should probably be prime.
- */
-#define HASHSIZE 151
-
-/*
- * Types of nodes
- */
-enum ntype
-{
- UNKNOWN, HEADER, ENTRIES, FILES, LIST, RCSNODE,
- RCSVERS, DIRS, UPDATE, LOCK, NDBMNODE
-};
-typedef enum ntype Ntype;
-
-struct node
-{
- Ntype type;
- struct node *next;
- struct node *prev;
- struct node *hashnext;
- struct node *hashprev;
- char *key;
- char *data;
- void (*delproc) ();
-};
-typedef struct node Node;
-
-struct list
-{
- Node *list;
- Node *hasharray[HASHSIZE];
- struct list *next;
-};
-typedef struct list List;
-
-List *getlist PROTO((void));
-Node *findnode PROTO((List * list, const char *key));
-Node *getnode PROTO((void));
-int addnode PROTO((List * list, Node * p));
-int walklist PROTO((List * list, int (*)(Node *n, void *closure), void *closure));
-void dellist PROTO((List ** listp));
-void delnode PROTO((Node * p));
-void freenode PROTO((Node * p));
-void sortlist PROTO((List * list, int (*)(const Node *, const Node *)));
diff --git a/gnu/usr.bin/cvs/lib/hostname.c b/gnu/usr.bin/cvs/lib/hostname.c
deleted file mode 100644
index 34be15e8b619..000000000000
--- a/gnu/usr.bin/cvs/lib/hostname.c
+++ /dev/null
@@ -1,49 +0,0 @@
-/* hostname.c -- use uname() to get the name of the host
- Copyright (C) 1992 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#if defined(STDC_HEADERS) || defined(USG)
-#include <string.h>
-#ifndef index
-#define index strchr
-#endif
-#else
-#include <strings.h>
-#endif
-
-#include <sys/utsname.h>
-
-/* Put this host's name into NAME, using at most NAMELEN characters */
-
-int
-gethostname(name, namelen)
- char *name;
- int namelen;
-{
- struct utsname ugnm;
-
- if (uname(&ugnm) < 0)
- return (-1);
-
- (void) strncpy(name, ugnm.nodename, namelen-1);
- name[namelen-1] = '\0';
-
- return (0);
-}
diff --git a/gnu/usr.bin/cvs/lib/md5.c b/gnu/usr.bin/cvs/lib/md5.c
deleted file mode 100644
index 4ad99cdc060e..000000000000
--- a/gnu/usr.bin/cvs/lib/md5.c
+++ /dev/null
@@ -1,277 +0,0 @@
-/*
- * This code implements the MD5 message-digest algorithm.
- * The algorithm is due to Ron Rivest. This code was
- * written by Colin Plumb in 1993, no copyright is claimed.
- * This code is in the public domain; do with it what you wish.
- *
- * Equivalent code is available from RSA Data Security, Inc.
- * This code has been tested against that, and is equivalent,
- * except that you don't need to include two pages of legalese
- * with every copy.
- *
- * To compute the message digest of a chunk of bytes, declare an
- * MD5Context structure, pass it to MD5Init, call MD5Update as
- * needed on buffers full of bytes, and then call MD5Final, which
- * will fill a supplied 16-byte array with the digest.
- */
-
-#include "config.h"
-
-#if HAVE_STRING_H || STDC_HEADERS
-#include <string.h> /* for memcpy() */
-#endif
-
-/* Add prototype support. */
-#ifndef PROTO
-#if defined (USE_PROTOTYPES) ? USE_PROTOTYPES : defined (__STDC__)
-#define PROTO(ARGS) ARGS
-#else
-#define PROTO(ARGS) ()
-#endif
-#endif
-
-#include "md5.h"
-
-void byteReverse PROTO ((unsigned char *buf, unsigned longs));
-
-#ifndef ASM_MD5
-/*
- * Note: this code is harmless on little-endian machines.
- */
-void byteReverse (buf, longs)
- unsigned char *buf;
- unsigned longs;
-{
- uint32 t;
- do {
- t = (uint32)((unsigned)buf[3]<<8 | buf[2]) << 16 |
- ((unsigned)buf[1]<<8 | buf[0]);
- *(uint32 *)buf = t;
- buf += 4;
- } while (--longs);
-}
-#endif
-
-/*
- * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
- * initialization constants.
- */
-void
-MD5Init(ctx)
- struct MD5Context *ctx;
-{
- ctx->buf[0] = 0x67452301;
- ctx->buf[1] = 0xefcdab89;
- ctx->buf[2] = 0x98badcfe;
- ctx->buf[3] = 0x10325476;
-
- ctx->bits[0] = 0;
- ctx->bits[1] = 0;
-}
-
-/*
- * Update context to reflect the concatenation of another buffer full
- * of bytes.
- */
-void
-MD5Update(ctx, buf, len)
- struct MD5Context *ctx;
- unsigned char const *buf;
- unsigned len;
-{
- uint32 t;
-
- /* Update bitcount */
-
- t = ctx->bits[0];
- if ((ctx->bits[0] = t + ((uint32)len << 3)) < t)
- ctx->bits[1]++; /* Carry from low to high */
- ctx->bits[1] += len >> 29;
-
- t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */
-
- /* Handle any leading odd-sized chunks */
-
- if ( t ) {
- unsigned char *p = (unsigned char *)ctx->in + t;
-
- t = 64-t;
- if (len < t) {
- memcpy(p, buf, len);
- return;
- }
- memcpy(p, buf, t);
- byteReverse(ctx->in, 16);
- MD5Transform(ctx->buf, (uint32 *)ctx->in);
- buf += t;
- len -= t;
- }
-
- /* Process data in 64-byte chunks */
-
- while (len >= 64) {
- memcpy(ctx->in, buf, 64);
- byteReverse(ctx->in, 16);
- MD5Transform(ctx->buf, (uint32 *)ctx->in);
- buf += 64;
- len -= 64;
- }
-
- /* Handle any remaining bytes of data. */
-
- memcpy(ctx->in, buf, len);
-}
-
-/*
- * Final wrapup - pad to 64-byte boundary with the bit pattern
- * 1 0* (64-bit count of bits processed, MSB-first)
- */
-void
-MD5Final(digest, ctx)
- unsigned char digest[16];
- struct MD5Context *ctx;
-{
- unsigned count;
- unsigned char *p;
-
- /* Compute number of bytes mod 64 */
- count = (ctx->bits[0] >> 3) & 0x3F;
-
- /* Set the first char of padding to 0x80. This is safe since there is
- always at least one byte free */
- p = ctx->in + count;
- *p++ = 0x80;
-
- /* Bytes of padding needed to make 64 bytes */
- count = 64 - 1 - count;
-
- /* Pad out to 56 mod 64 */
- if (count < 8) {
- /* Two lots of padding: Pad the first block to 64 bytes */
- memset(p, 0, count);
- byteReverse(ctx->in, 16);
- MD5Transform(ctx->buf, (uint32 *)ctx->in);
-
- /* Now fill the next block with 56 bytes */
- memset(ctx->in, 0, 56);
- } else {
- /* Pad block to 56 bytes */
- memset(p, 0, count-8);
- }
- byteReverse(ctx->in, 14);
-
- /* Append length in bits and transform */
- ((uint32 *)ctx->in)[ 14 ] = ctx->bits[0];
- ((uint32 *)ctx->in)[ 15 ] = ctx->bits[1];
-
- MD5Transform(ctx->buf, (uint32 *)ctx->in);
- byteReverse((unsigned char *)ctx->buf, 4);
- memcpy(digest, ctx->buf, 16);
- memset(ctx, 0, sizeof(ctx)); /* In case it's sensitive */
-}
-
-#ifndef ASM_MD5
-
-/* The four core functions - F1 is optimized somewhat */
-
-/* #define F1(x, y, z) (x & y | ~x & z) */
-#define F1(x, y, z) (z ^ (x & (y ^ z)))
-#define F2(x, y, z) F1(z, x, y)
-#define F3(x, y, z) (x ^ y ^ z)
-#define F4(x, y, z) (y ^ (x | ~z))
-
-/* This is the central step in the MD5 algorithm. */
-#define MD5STEP(f, w, x, y, z, data, s) \
- ( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x )
-
-/*
- * The core of the MD5 algorithm, this alters an existing MD5 hash to
- * reflect the addition of 16 longwords of new data. MD5Update blocks
- * the data and converts bytes into longwords for this routine.
- */
-void
-MD5Transform(buf, in)
- uint32 buf[4];
- uint32 const in[16];
-{
- register uint32 a, b, c, d;
-
- a = buf[0];
- b = buf[1];
- c = buf[2];
- d = buf[3];
-
- MD5STEP(F1, a, b, c, d, in[ 0]+0xd76aa478, 7);
- MD5STEP(F1, d, a, b, c, in[ 1]+0xe8c7b756, 12);
- MD5STEP(F1, c, d, a, b, in[ 2]+0x242070db, 17);
- MD5STEP(F1, b, c, d, a, in[ 3]+0xc1bdceee, 22);
- MD5STEP(F1, a, b, c, d, in[ 4]+0xf57c0faf, 7);
- MD5STEP(F1, d, a, b, c, in[ 5]+0x4787c62a, 12);
- MD5STEP(F1, c, d, a, b, in[ 6]+0xa8304613, 17);
- MD5STEP(F1, b, c, d, a, in[ 7]+0xfd469501, 22);
- MD5STEP(F1, a, b, c, d, in[ 8]+0x698098d8, 7);
- MD5STEP(F1, d, a, b, c, in[ 9]+0x8b44f7af, 12);
- MD5STEP(F1, c, d, a, b, in[10]+0xffff5bb1, 17);
- MD5STEP(F1, b, c, d, a, in[11]+0x895cd7be, 22);
- MD5STEP(F1, a, b, c, d, in[12]+0x6b901122, 7);
- MD5STEP(F1, d, a, b, c, in[13]+0xfd987193, 12);
- MD5STEP(F1, c, d, a, b, in[14]+0xa679438e, 17);
- MD5STEP(F1, b, c, d, a, in[15]+0x49b40821, 22);
-
- MD5STEP(F2, a, b, c, d, in[ 1]+0xf61e2562, 5);
- MD5STEP(F2, d, a, b, c, in[ 6]+0xc040b340, 9);
- MD5STEP(F2, c, d, a, b, in[11]+0x265e5a51, 14);
- MD5STEP(F2, b, c, d, a, in[ 0]+0xe9b6c7aa, 20);
- MD5STEP(F2, a, b, c, d, in[ 5]+0xd62f105d, 5);
- MD5STEP(F2, d, a, b, c, in[10]+0x02441453, 9);
- MD5STEP(F2, c, d, a, b, in[15]+0xd8a1e681, 14);
- MD5STEP(F2, b, c, d, a, in[ 4]+0xe7d3fbc8, 20);
- MD5STEP(F2, a, b, c, d, in[ 9]+0x21e1cde6, 5);
- MD5STEP(F2, d, a, b, c, in[14]+0xc33707d6, 9);
- MD5STEP(F2, c, d, a, b, in[ 3]+0xf4d50d87, 14);
- MD5STEP(F2, b, c, d, a, in[ 8]+0x455a14ed, 20);
- MD5STEP(F2, a, b, c, d, in[13]+0xa9e3e905, 5);
- MD5STEP(F2, d, a, b, c, in[ 2]+0xfcefa3f8, 9);
- MD5STEP(F2, c, d, a, b, in[ 7]+0x676f02d9, 14);
- MD5STEP(F2, b, c, d, a, in[12]+0x8d2a4c8a, 20);
-
- MD5STEP(F3, a, b, c, d, in[ 5]+0xfffa3942, 4);
- MD5STEP(F3, d, a, b, c, in[ 8]+0x8771f681, 11);
- MD5STEP(F3, c, d, a, b, in[11]+0x6d9d6122, 16);
- MD5STEP(F3, b, c, d, a, in[14]+0xfde5380c, 23);
- MD5STEP(F3, a, b, c, d, in[ 1]+0xa4beea44, 4);
- MD5STEP(F3, d, a, b, c, in[ 4]+0x4bdecfa9, 11);
- MD5STEP(F3, c, d, a, b, in[ 7]+0xf6bb4b60, 16);
- MD5STEP(F3, b, c, d, a, in[10]+0xbebfbc70, 23);
- MD5STEP(F3, a, b, c, d, in[13]+0x289b7ec6, 4);
- MD5STEP(F3, d, a, b, c, in[ 0]+0xeaa127fa, 11);
- MD5STEP(F3, c, d, a, b, in[ 3]+0xd4ef3085, 16);
- MD5STEP(F3, b, c, d, a, in[ 6]+0x04881d05, 23);
- MD5STEP(F3, a, b, c, d, in[ 9]+0xd9d4d039, 4);
- MD5STEP(F3, d, a, b, c, in[12]+0xe6db99e5, 11);
- MD5STEP(F3, c, d, a, b, in[15]+0x1fa27cf8, 16);
- MD5STEP(F3, b, c, d, a, in[ 2]+0xc4ac5665, 23);
-
- MD5STEP(F4, a, b, c, d, in[ 0]+0xf4292244, 6);
- MD5STEP(F4, d, a, b, c, in[ 7]+0x432aff97, 10);
- MD5STEP(F4, c, d, a, b, in[14]+0xab9423a7, 15);
- MD5STEP(F4, b, c, d, a, in[ 5]+0xfc93a039, 21);
- MD5STEP(F4, a, b, c, d, in[12]+0x655b59c3, 6);
- MD5STEP(F4, d, a, b, c, in[ 3]+0x8f0ccc92, 10);
- MD5STEP(F4, c, d, a, b, in[10]+0xffeff47d, 15);
- MD5STEP(F4, b, c, d, a, in[ 1]+0x85845dd1, 21);
- MD5STEP(F4, a, b, c, d, in[ 8]+0x6fa87e4f, 6);
- MD5STEP(F4, d, a, b, c, in[15]+0xfe2ce6e0, 10);
- MD5STEP(F4, c, d, a, b, in[ 6]+0xa3014314, 15);
- MD5STEP(F4, b, c, d, a, in[13]+0x4e0811a1, 21);
- MD5STEP(F4, a, b, c, d, in[ 4]+0xf7537e82, 6);
- MD5STEP(F4, d, a, b, c, in[11]+0xbd3af235, 10);
- MD5STEP(F4, c, d, a, b, in[ 2]+0x2ad7d2bb, 15);
- MD5STEP(F4, b, c, d, a, in[ 9]+0xeb86d391, 21);
-
- buf[0] += a;
- buf[1] += b;
- buf[2] += c;
- buf[3] += d;
-}
-#endif
diff --git a/gnu/usr.bin/cvs/lib/md5.h b/gnu/usr.bin/cvs/lib/md5.h
deleted file mode 100644
index bfe79ccd7f28..000000000000
--- a/gnu/usr.bin/cvs/lib/md5.h
+++ /dev/null
@@ -1,31 +0,0 @@
-#ifndef MD5_H
-#define MD5_H
-
-#if SIZEOF_LONG == 4
-typedef unsigned long uint32;
-#else
-#if SIZEOF_INT == 4
-typedef unsigned int uint32;
-#else
-Congratulations! You get to rewrite this code so that it does not require
-a 32-bit integer type! (Or maybe you just need to reconfigure.)
-#endif
-#endif
-
-struct MD5Context {
- uint32 buf[4];
- uint32 bits[2];
- unsigned char in[64];
-};
-
-void MD5Init PROTO((struct MD5Context *context));
-void MD5Update PROTO((struct MD5Context *context, unsigned char const *buf, unsigned len));
-void MD5Final PROTO((unsigned char digest[16], struct MD5Context *context));
-void MD5Transform PROTO((uint32 buf[4], uint32 const in[16]));
-
-/*
- * This is needed to make RSAREF happy on some MS-DOS compilers.
- */
-typedef struct MD5Context MD5_CTX;
-
-#endif /* !MD5_H */
diff --git a/gnu/usr.bin/cvs/lib/memmove.c b/gnu/usr.bin/cvs/lib/memmove.c
deleted file mode 100644
index 8818d46544c0..000000000000
--- a/gnu/usr.bin/cvs/lib/memmove.c
+++ /dev/null
@@ -1,57 +0,0 @@
-/* memmove -- copy memory regions of arbitary length
- Copyright (C) 1991 Free Software Foundation, Inc.
-
-This file is part of the libiberty library.
-Libiberty is free software; you can redistribute it and/or
-modify it under the terms of the GNU Library General Public
-License as published by the Free Software Foundation; either
-version 2 of the License, or (at your option) any later version.
-
-Libiberty is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-Library General Public License for more details.
-
-You should have received a copy of the GNU Library General Public
-License along with libiberty; see the file COPYING.LIB. If
-not, write to the Free Software Foundation, Inc., 675 Mass Ave,
-Cambridge, MA 02139, USA. */
-
-
-/*
-
-NAME
-
- memmove -- copy memory regions of arbitary length
-
-SYNOPSIS
-
- void memmove (void *out, const void *in, size_t n);
-
-DESCRIPTION
-
- Copy LENGTH bytes from memory region pointed to by IN to memory
- region pointed to by OUT.
-
- Regions can be overlapping.
-*/
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#ifdef __STDC__
-#include <stddef.h>
-#else
-#define size_t unsigned long
-#endif
-
-void *
-memmove (out, in, length)
- void *out;
- const void* in;
- size_t length;
-{
- bcopy(in, out, length);
- return out;
-}
diff --git a/gnu/usr.bin/cvs/lib/mkdir.c b/gnu/usr.bin/cvs/lib/mkdir.c
deleted file mode 100644
index a70c1d866199..000000000000
--- a/gnu/usr.bin/cvs/lib/mkdir.c
+++ /dev/null
@@ -1,129 +0,0 @@
-/* mkrmdir.c -- BSD compatible directory functions for System V
- Copyright (C) 1988, 1990 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <errno.h>
-#ifndef STDC_HEADERS
-extern int errno;
-#endif
-
-/* mkdir and rmdir adapted from GNU tar. */
-
-/* Make directory DPATH, with permission mode DMODE.
-
- Written by Robert Rother, Mariah Corporation, August 1985
- (sdcsvax!rmr or rmr@uscd). If you want it, it's yours.
-
- Severely hacked over by John Gilmore to make a 4.2BSD compatible
- subroutine. 11Mar86; hoptoad!gnu
-
- Modified by rmtodd@uokmax 6-28-87 -- when making an already existing dir,
- subroutine didn't return EEXIST. It does now. */
-
-int
-mkdir (dpath, dmode)
- char *dpath;
- int dmode;
-{
- int cpid, status;
- struct stat statbuf;
-
- if (stat (dpath, &statbuf) == 0)
- {
- errno = EEXIST; /* stat worked, so it already exists. */
- return -1;
- }
-
- /* If stat fails for a reason other than non-existence, return error. */
- if (errno != ENOENT)
- return -1;
-
- cpid = fork ();
- switch (cpid)
- {
- case -1: /* Cannot fork. */
- return -1; /* errno is set already. */
-
- case 0: /* Child process. */
- /* Cheap hack to set mode of new directory. Since this child
- process is going away anyway, we zap its umask.
- This won't suffice to set SUID, SGID, etc. on this
- directory, so the parent process calls chmod afterward. */
- status = umask (0); /* Get current umask. */
- umask (status | (0777 & ~dmode)); /* Set for mkdir. */
- execl ("/bin/mkdir", "mkdir", dpath, (char *) 0);
- _exit (1);
-
- default: /* Parent process. */
- while (wait (&status) != cpid) /* Wait for kid to finish. */
- /* Do nothing. */ ;
-
- if (status & 0xFFFF)
- {
- errno = EIO; /* /bin/mkdir failed. */
- return -1;
- }
- return chmod (dpath, dmode);
- }
-}
-
-/* Remove directory DPATH.
- Return 0 if successful, -1 if not. */
-
-int
-rmdir (dpath)
- char *dpath;
-{
- int cpid, status;
- struct stat statbuf;
-
- if (stat (dpath, &statbuf) != 0)
- return -1; /* stat set errno. */
-
- if ((statbuf.st_mode & S_IFMT) != S_IFDIR)
- {
- errno = ENOTDIR;
- return -1;
- }
-
- cpid = fork ();
- switch (cpid)
- {
- case -1: /* Cannot fork. */
- return -1; /* errno is set already. */
-
- case 0: /* Child process. */
- execl ("/bin/rmdir", "rmdir", dpath, (char *) 0);
- _exit (1);
-
- default: /* Parent process. */
- while (wait (&status) != cpid) /* Wait for kid to finish. */
- /* Do nothing. */ ;
-
- if (status & 0xFFFF)
- {
- errno = EIO; /* /bin/rmdir failed. */
- return -1;
- }
- return 0;
- }
-}
diff --git a/gnu/usr.bin/cvs/lib/myndbm.c b/gnu/usr.bin/cvs/lib/myndbm.c
deleted file mode 100644
index fef326576bde..000000000000
--- a/gnu/usr.bin/cvs/lib/myndbm.c
+++ /dev/null
@@ -1,213 +0,0 @@
-/*
- * Copyright (c) 1992, Brian Berliner
- *
- * You may distribute under the terms of the GNU General Public License as
- * specified in the README file that comes with the CVS 1.4 kit.
- *
- * A simple ndbm-emulator for CVS. It parses a text file of the format:
- *
- * key value
- *
- * at dbm_open time, and loads the entire file into memory. As such, it is
- * probably only good for fairly small modules files. Ours is about 30K in
- * size, and this code works fine.
- */
-
-#include "cvs.h"
-
-#ifdef MY_NDBM
-
-#ifndef lint
-static const char rcsid[] = "$CVSid: @(#)myndbm.c 1.7 94/09/23 $";
-USE(rcsid);
-#endif
-
-static void mydbm_load_file ();
-
-/* ARGSUSED */
-DBM *
-mydbm_open (file, flags, mode)
- char *file;
- int flags;
- int mode;
-{
- FILE *fp;
- DBM *db;
-
- if ((fp = fopen (file, "r")) == NULL)
- return ((DBM *) 0);
-
- db = (DBM *) xmalloc (sizeof (*db));
- db->dbm_list = getlist ();
-
- mydbm_load_file (fp, db->dbm_list);
- (void) fclose (fp);
- return (db);
-}
-
-void
-mydbm_close (db)
- DBM *db;
-{
- dellist (&db->dbm_list);
- free ((char *) db);
-}
-
-datum
-mydbm_fetch (db, key)
- DBM *db;
- datum key;
-{
- Node *p;
- char *s;
- datum val;
-
- /* make sure it's null-terminated */
- s = xmalloc (key.dsize + 1);
- (void) strncpy (s, key.dptr, key.dsize);
- s[key.dsize] = '\0';
-
- p = findnode (db->dbm_list, s);
- if (p)
- {
- val.dptr = p->data;
- val.dsize = strlen (p->data);
- }
- else
- {
- val.dptr = (char *) NULL;
- val.dsize = 0;
- }
- free (s);
- return (val);
-}
-
-datum
-mydbm_firstkey (db)
- DBM *db;
-{
- Node *head, *p;
- datum key;
-
- head = db->dbm_list->list;
- p = head->next;
- if (p != head)
- {
- key.dptr = p->key;
- key.dsize = strlen (p->key);
- }
- else
- {
- key.dptr = (char *) NULL;
- key.dsize = 0;
- }
- db->dbm_next = p->next;
- return (key);
-}
-
-datum
-mydbm_nextkey (db)
- DBM *db;
-{
- Node *head, *p;
- datum key;
-
- head = db->dbm_list->list;
- p = db->dbm_next;
- if (p != head)
- {
- key.dptr = p->key;
- key.dsize = strlen (p->key);
- }
- else
- {
- key.dptr = (char *) NULL;
- key.dsize = 0;
- }
- db->dbm_next = p->next;
- return (key);
-}
-
-static void
-mydbm_load_file (fp, list)
- FILE *fp;
- List *list;
-{
- char line[MAXLINELEN], value[MAXLINELEN];
- char *cp, *vp;
- int len, cont;
-
- for (cont = 0; fgets (line, sizeof (line), fp) != NULL;)
- {
- if ((cp = strrchr (line, '\n')) != NULL)
- *cp = '\0'; /* strip the newline */
-
- /*
- * Add the line to the value, at the end if this is a continuation
- * line; otherwise at the beginning, but only after any trailing
- * backslash is removed.
- */
- vp = value;
- if (cont)
- vp += strlen (value);
-
- /*
- * See if the line we read is a continuation line, and strip the
- * backslash if so.
- */
- len = strlen (line);
- if (len > 0)
- cp = &line[len - 1];
- else
- cp = line;
- if (*cp == '\\')
- {
- cont = 1;
- *cp = '\0';
- }
- else
- {
- cont = 0;
- }
- (void) strcpy (vp, line);
- if (value[0] == '#')
- continue; /* comment line */
- vp = value;
- while (*vp && isspace (*vp))
- vp++;
- if (*vp == '\0')
- continue; /* empty line */
-
- /*
- * If this was not a continuation line, add the entry to the database
- */
- if (!cont)
- {
- Node *p = getnode ();
- char *kp;
-
- kp = vp;
- while (*vp && !isspace (*vp))
- vp++;
- *vp++ = '\0'; /* NULL terminate the key */
- p->type = NDBMNODE;
- p->key = xstrdup (kp);
- while (*vp && isspace (*vp))
- vp++; /* skip whitespace to value */
- if (*vp == '\0')
- {
- error (0, 0, "warning: NULL value for key `%s'", p->key);
- freenode (p);
- continue;
- }
- p->data = xstrdup (vp);
- if (addnode (list, p) == -1)
- {
- error (0, 0, "duplicate key found for `%s'", p->key);
- freenode (p);
- }
- }
- }
-}
-
-#endif /* MY_NDBM */
diff --git a/gnu/usr.bin/cvs/lib/myndbm.h b/gnu/usr.bin/cvs/lib/myndbm.h
deleted file mode 100644
index 3af313055065..000000000000
--- a/gnu/usr.bin/cvs/lib/myndbm.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/* $CVSid: @(#)myndbm.h 1.4 94/09/21 $ */
-
-#ifdef MY_NDBM
-
-#define DBLKSIZ 4096
-
-typedef struct
-{
- List *dbm_list; /* cached database */
- Node *dbm_next; /* next key to return for nextkey() */
-} DBM;
-
-typedef struct
-{
- char *dptr;
- int dsize;
-} datum;
-
-/*
- * So as not to conflict with other dbm_open, etc., routines that may
- * be included by someone's libc, all of my emulation routines are prefixed
- * by "my" and we define the "standard" ones to be "my" ones here.
- */
-#define dbm_open mydbm_open
-#define dbm_close mydbm_close
-#define dbm_fetch mydbm_fetch
-#define dbm_firstkey mydbm_firstkey
-#define dbm_nextkey mydbm_nextkey
-
-DBM *mydbm_open PROTO((char *file, int flags, int mode));
-void mydbm_close PROTO((DBM * db));
-datum mydbm_fetch PROTO((DBM * db, datum key));
-datum mydbm_firstkey PROTO((DBM * db));
-datum mydbm_nextkey PROTO((DBM * db));
-
-#endif /* MY_NDBM */
diff --git a/gnu/usr.bin/cvs/lib/regex.h b/gnu/usr.bin/cvs/lib/regex.h
deleted file mode 100644
index 408dd210348f..000000000000
--- a/gnu/usr.bin/cvs/lib/regex.h
+++ /dev/null
@@ -1,490 +0,0 @@
-/* Definitions for data structures and routines for the regular
- expression library, version 0.12.
-
- Copyright (C) 1985, 1989, 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
-
-#ifndef __REGEXP_LIBRARY_H__
-#define __REGEXP_LIBRARY_H__
-
-/* POSIX says that <sys/types.h> must be included (by the caller) before
- <regex.h>. */
-
-#ifdef VMS
-/* VMS doesn't have `size_t' in <sys/types.h>, even though POSIX says it
- should be there. */
-#include <stddef.h>
-#endif
-
-
-/* The following bits are used to determine the regexp syntax we
- recognize. The set/not-set meanings are chosen so that Emacs syntax
- remains the value 0. The bits are given in alphabetical order, and
- the definitions shifted by one from the previous bit; thus, when we
- add or remove a bit, only one other definition need change. */
-typedef unsigned reg_syntax_t;
-
-/* If this bit is not set, then \ inside a bracket expression is literal.
- If set, then such a \ quotes the following character. */
-#define RE_BACKSLASH_ESCAPE_IN_LISTS (1)
-
-/* If this bit is not set, then + and ? are operators, and \+ and \? are
- literals.
- If set, then \+ and \? are operators and + and ? are literals. */
-#define RE_BK_PLUS_QM (RE_BACKSLASH_ESCAPE_IN_LISTS << 1)
-
-/* If this bit is set, then character classes are supported. They are:
- [:alpha:], [:upper:], [:lower:], [:digit:], [:alnum:], [:xdigit:],
- [:space:], [:print:], [:punct:], [:graph:], and [:cntrl:].
- If not set, then character classes are not supported. */
-#define RE_CHAR_CLASSES (RE_BK_PLUS_QM << 1)
-
-/* If this bit is set, then ^ and $ are always anchors (outside bracket
- expressions, of course).
- If this bit is not set, then it depends:
- ^ is an anchor if it is at the beginning of a regular
- expression or after an open-group or an alternation operator;
- $ is an anchor if it is at the end of a regular expression, or
- before a close-group or an alternation operator.
-
- This bit could be (re)combined with RE_CONTEXT_INDEP_OPS, because
- POSIX draft 11.2 says that * etc. in leading positions is undefined.
- We already implemented a previous draft which made those constructs
- invalid, though, so we haven't changed the code back. */
-#define RE_CONTEXT_INDEP_ANCHORS (RE_CHAR_CLASSES << 1)
-
-/* If this bit is set, then special characters are always special
- regardless of where they are in the pattern.
- If this bit is not set, then special characters are special only in
- some contexts; otherwise they are ordinary. Specifically,
- * + ? and intervals are only special when not after the beginning,
- open-group, or alternation operator. */
-#define RE_CONTEXT_INDEP_OPS (RE_CONTEXT_INDEP_ANCHORS << 1)
-
-/* If this bit is set, then *, +, ?, and { cannot be first in an re or
- immediately after an alternation or begin-group operator. */
-#define RE_CONTEXT_INVALID_OPS (RE_CONTEXT_INDEP_OPS << 1)
-
-/* If this bit is set, then . matches newline.
- If not set, then it doesn't. */
-#define RE_DOT_NEWLINE (RE_CONTEXT_INVALID_OPS << 1)
-
-/* If this bit is set, then . doesn't match NUL.
- If not set, then it does. */
-#define RE_DOT_NOT_NULL (RE_DOT_NEWLINE << 1)
-
-/* If this bit is set, nonmatching lists [^...] do not match newline.
- If not set, they do. */
-#define RE_HAT_LISTS_NOT_NEWLINE (RE_DOT_NOT_NULL << 1)
-
-/* If this bit is set, either \{...\} or {...} defines an
- interval, depending on RE_NO_BK_BRACES.
- If not set, \{, \}, {, and } are literals. */
-#define RE_INTERVALS (RE_HAT_LISTS_NOT_NEWLINE << 1)
-
-/* If this bit is set, +, ? and | aren't recognized as operators.
- If not set, they are. */
-#define RE_LIMITED_OPS (RE_INTERVALS << 1)
-
-/* If this bit is set, newline is an alternation operator.
- If not set, newline is literal. */
-#define RE_NEWLINE_ALT (RE_LIMITED_OPS << 1)
-
-/* If this bit is set, then `{...}' defines an interval, and \{ and \}
- are literals.
- If not set, then `\{...\}' defines an interval. */
-#define RE_NO_BK_BRACES (RE_NEWLINE_ALT << 1)
-
-/* If this bit is set, (...) defines a group, and \( and \) are literals.
- If not set, \(...\) defines a group, and ( and ) are literals. */
-#define RE_NO_BK_PARENS (RE_NO_BK_BRACES << 1)
-
-/* If this bit is set, then \<digit> matches <digit>.
- If not set, then \<digit> is a back-reference. */
-#define RE_NO_BK_REFS (RE_NO_BK_PARENS << 1)
-
-/* If this bit is set, then | is an alternation operator, and \| is literal.
- If not set, then \| is an alternation operator, and | is literal. */
-#define RE_NO_BK_VBAR (RE_NO_BK_REFS << 1)
-
-/* If this bit is set, then an ending range point collating higher
- than the starting range point, as in [z-a], is invalid.
- If not set, then when ending range point collates higher than the
- starting range point, the range is ignored. */
-#define RE_NO_EMPTY_RANGES (RE_NO_BK_VBAR << 1)
-
-/* If this bit is set, then an unmatched ) is ordinary.
- If not set, then an unmatched ) is invalid. */
-#define RE_UNMATCHED_RIGHT_PAREN_ORD (RE_NO_EMPTY_RANGES << 1)
-
-/* This global variable defines the particular regexp syntax to use (for
- some interfaces). When a regexp is compiled, the syntax used is
- stored in the pattern buffer, so changing this does not affect
- already-compiled regexps. */
-extern reg_syntax_t re_syntax_options;
-
-/* Define combinations of the above bits for the standard possibilities.
- (The [[[ comments delimit what gets put into the Texinfo file, so
- don't delete them!) */
-/* [[[begin syntaxes]]] */
-#define RE_SYNTAX_EMACS 0
-
-#define RE_SYNTAX_AWK \
- (RE_BACKSLASH_ESCAPE_IN_LISTS | RE_DOT_NOT_NULL \
- | RE_NO_BK_PARENS | RE_NO_BK_REFS \
- | RE_NO_BK_VBAR | RE_NO_EMPTY_RANGES \
- | RE_UNMATCHED_RIGHT_PAREN_ORD)
-
-#define RE_SYNTAX_POSIX_AWK \
- (RE_SYNTAX_POSIX_EXTENDED | RE_BACKSLASH_ESCAPE_IN_LISTS)
-
-#define RE_SYNTAX_GREP \
- (RE_BK_PLUS_QM | RE_CHAR_CLASSES \
- | RE_HAT_LISTS_NOT_NEWLINE | RE_INTERVALS \
- | RE_NEWLINE_ALT)
-
-#define RE_SYNTAX_EGREP \
- (RE_CHAR_CLASSES | RE_CONTEXT_INDEP_ANCHORS \
- | RE_CONTEXT_INDEP_OPS | RE_HAT_LISTS_NOT_NEWLINE \
- | RE_NEWLINE_ALT | RE_NO_BK_PARENS \
- | RE_NO_BK_VBAR)
-
-#define RE_SYNTAX_POSIX_EGREP \
- (RE_SYNTAX_EGREP | RE_INTERVALS | RE_NO_BK_BRACES)
-
-/* P1003.2/D11.2, section 4.20.7.1, lines 5078ff. */
-#define RE_SYNTAX_ED RE_SYNTAX_POSIX_BASIC
-
-#define RE_SYNTAX_SED RE_SYNTAX_POSIX_BASIC
-
-/* Syntax bits common to both basic and extended POSIX regex syntax. */
-#define _RE_SYNTAX_POSIX_COMMON \
- (RE_CHAR_CLASSES | RE_DOT_NEWLINE | RE_DOT_NOT_NULL \
- | RE_INTERVALS | RE_NO_EMPTY_RANGES)
-
-#define RE_SYNTAX_POSIX_BASIC \
- (_RE_SYNTAX_POSIX_COMMON | RE_BK_PLUS_QM)
-
-/* Differs from ..._POSIX_BASIC only in that RE_BK_PLUS_QM becomes
- RE_LIMITED_OPS, i.e., \? \+ \| are not recognized. Actually, this
- isn't minimal, since other operators, such as \`, aren't disabled. */
-#define RE_SYNTAX_POSIX_MINIMAL_BASIC \
- (_RE_SYNTAX_POSIX_COMMON | RE_LIMITED_OPS)
-
-#define RE_SYNTAX_POSIX_EXTENDED \
- (_RE_SYNTAX_POSIX_COMMON | RE_CONTEXT_INDEP_ANCHORS \
- | RE_CONTEXT_INDEP_OPS | RE_NO_BK_BRACES \
- | RE_NO_BK_PARENS | RE_NO_BK_VBAR \
- | RE_UNMATCHED_RIGHT_PAREN_ORD)
-
-/* Differs from ..._POSIX_EXTENDED in that RE_CONTEXT_INVALID_OPS
- replaces RE_CONTEXT_INDEP_OPS and RE_NO_BK_REFS is added. */
-#define RE_SYNTAX_POSIX_MINIMAL_EXTENDED \
- (_RE_SYNTAX_POSIX_COMMON | RE_CONTEXT_INDEP_ANCHORS \
- | RE_CONTEXT_INVALID_OPS | RE_NO_BK_BRACES \
- | RE_NO_BK_PARENS | RE_NO_BK_REFS \
- | RE_NO_BK_VBAR | RE_UNMATCHED_RIGHT_PAREN_ORD)
-/* [[[end syntaxes]]] */
-
-/* Maximum number of duplicates an interval can allow. Some systems
- (erroneously) define this in other header files, but we want our
- value, so remove any previous define. */
-#ifdef RE_DUP_MAX
-#undef RE_DUP_MAX
-#endif
-#define RE_DUP_MAX ((1 << 15) - 1)
-
-
-/* POSIX `cflags' bits (i.e., information for `regcomp'). */
-
-/* If this bit is set, then use extended regular expression syntax.
- If not set, then use basic regular expression syntax. */
-#define REG_EXTENDED 1
-
-/* If this bit is set, then ignore case when matching.
- If not set, then case is significant. */
-#define REG_ICASE (REG_EXTENDED << 1)
-
-/* If this bit is set, then anchors do not match at newline
- characters in the string.
- If not set, then anchors do match at newlines. */
-#define REG_NEWLINE (REG_ICASE << 1)
-
-/* If this bit is set, then report only success or fail in regexec.
- If not set, then returns differ between not matching and errors. */
-#define REG_NOSUB (REG_NEWLINE << 1)
-
-
-/* POSIX `eflags' bits (i.e., information for regexec). */
-
-/* If this bit is set, then the beginning-of-line operator doesn't match
- the beginning of the string (presumably because it's not the
- beginning of a line).
- If not set, then the beginning-of-line operator does match the
- beginning of the string. */
-#define REG_NOTBOL 1
-
-/* Like REG_NOTBOL, except for the end-of-line. */
-#define REG_NOTEOL (1 << 1)
-
-
-/* If any error codes are removed, changed, or added, update the
- `re_error_msg' table in regex.c. */
-typedef enum
-{
- REG_NOERROR = 0, /* Success. */
- REG_NOMATCH, /* Didn't find a match (for regexec). */
-
- /* POSIX regcomp return error codes. (In the order listed in the
- standard.) */
- REG_BADPAT, /* Invalid pattern. */
- REG_ECOLLATE, /* Not implemented. */
- REG_ECTYPE, /* Invalid character class name. */
- REG_EESCAPE, /* Trailing backslash. */
- REG_ESUBREG, /* Invalid back reference. */
- REG_EBRACK, /* Unmatched left bracket. */
- REG_EPAREN, /* Parenthesis imbalance. */
- REG_EBRACE, /* Unmatched \{. */
- REG_BADBR, /* Invalid contents of \{\}. */
- REG_ERANGE, /* Invalid range end. */
- REG_ESPACE, /* Ran out of memory. */
- REG_BADRPT, /* No preceding re for repetition op. */
-
- /* Error codes we've added. */
- REG_EEND, /* Premature end. */
- REG_ESIZE, /* Compiled pattern bigger than 2^16 bytes. */
- REG_ERPAREN /* Unmatched ) or \); not returned from regcomp. */
-} reg_errcode_t;
-
-/* This data structure represents a compiled pattern. Before calling
- the pattern compiler, the fields `buffer', `allocated', `fastmap',
- `translate', and `no_sub' can be set. After the pattern has been
- compiled, the `re_nsub' field is available. All other fields are
- private to the regex routines. */
-
-struct re_pattern_buffer
-{
-/* [[[begin pattern_buffer]]] */
- /* Space that holds the compiled pattern. It is declared as
- `unsigned char *' because its elements are
- sometimes used as array indexes. */
- unsigned char *buffer;
-
- /* Number of bytes to which `buffer' points. */
- unsigned long allocated;
-
- /* Number of bytes actually used in `buffer'. */
- unsigned long used;
-
- /* Syntax setting with which the pattern was compiled. */
- reg_syntax_t syntax;
-
- /* Pointer to a fastmap, if any, otherwise zero. re_search uses
- the fastmap, if there is one, to skip over impossible
- starting points for matches. */
- char *fastmap;
-
- /* Either a translate table to apply to all characters before
- comparing them, or zero for no translation. The translation
- is applied to a pattern when it is compiled and to a string
- when it is matched. */
- char *translate;
-
- /* Number of subexpressions found by the compiler. */
- size_t re_nsub;
-
- /* Zero if this pattern cannot match the empty string, one else.
- Well, in truth it's used only in `re_search_2', to see
- whether or not we should use the fastmap, so we don't set
- this absolutely perfectly; see `re_compile_fastmap' (the
- `duplicate' case). */
- unsigned can_be_null : 1;
-
- /* If REGS_UNALLOCATED, allocate space in the `regs' structure
- for `max (RE_NREGS, re_nsub + 1)' groups.
- If REGS_REALLOCATE, reallocate space if necessary.
- If REGS_FIXED, use what's there. */
-#define REGS_UNALLOCATED 0
-#define REGS_REALLOCATE 1
-#define REGS_FIXED 2
- unsigned regs_allocated : 2;
-
- /* Set to zero when `regex_compile' compiles a pattern; set to one
- by `re_compile_fastmap' if it updates the fastmap. */
- unsigned fastmap_accurate : 1;
-
- /* If set, `re_match_2' does not return information about
- subexpressions. */
- unsigned no_sub : 1;
-
- /* If set, a beginning-of-line anchor doesn't match at the
- beginning of the string. */
- unsigned not_bol : 1;
-
- /* Similarly for an end-of-line anchor. */
- unsigned not_eol : 1;
-
- /* If true, an anchor at a newline matches. */
- unsigned newline_anchor : 1;
-
-/* [[[end pattern_buffer]]] */
-};
-
-typedef struct re_pattern_buffer regex_t;
-
-
-/* search.c (search_buffer) in Emacs needs this one opcode value. It is
- defined both in `regex.c' and here. */
-#define RE_EXACTN_VALUE 1
-
-/* Type for byte offsets within the string. POSIX mandates this. */
-typedef int regoff_t;
-
-
-/* This is the structure we store register match data in. See
- regex.texinfo for a full description of what registers match. */
-struct re_registers
-{
- unsigned num_regs;
- regoff_t *start;
- regoff_t *end;
-};
-
-
-/* If `regs_allocated' is REGS_UNALLOCATED in the pattern buffer,
- `re_match_2' returns information about at least this many registers
- the first time a `regs' structure is passed. */
-#ifndef RE_NREGS
-#define RE_NREGS 30
-#endif
-
-
-/* POSIX specification for registers. Aside from the different names than
- `re_registers', POSIX uses an array of structures, instead of a
- structure of arrays. */
-typedef struct
-{
- regoff_t rm_so; /* Byte offset from string's start to substring's start. */
- regoff_t rm_eo; /* Byte offset from string's start to substring's end. */
-} regmatch_t;
-
-/* Declarations for routines. */
-
-/* To avoid duplicating every routine declaration -- once with a
- prototype (if we are ANSI), and once without (if we aren't) -- we
- use the following macro to declare argument types. This
- unfortunately clutters up the declarations a bit, but I think it's
- worth it. */
-
-#if __STDC__
-
-#define _RE_ARGS(args) args
-
-#else /* not __STDC__ */
-
-#define _RE_ARGS(args) ()
-
-#endif /* not __STDC__ */
-
-/* Sets the current default syntax to SYNTAX, and return the old syntax.
- You can also simply assign to the `re_syntax_options' variable. */
-extern reg_syntax_t re_set_syntax _RE_ARGS ((reg_syntax_t syntax));
-
-/* Compile the regular expression PATTERN, with length LENGTH
- and syntax given by the global `re_syntax_options', into the buffer
- BUFFER. Return NULL if successful, and an error string if not. */
-extern const char *re_compile_pattern
- _RE_ARGS ((const char *pattern, int length,
- struct re_pattern_buffer *buffer));
-
-
-/* Compile a fastmap for the compiled pattern in BUFFER; used to
- accelerate searches. Return 0 if successful and -2 if was an
- internal error. */
-extern int re_compile_fastmap _RE_ARGS ((struct re_pattern_buffer *buffer));
-
-
-/* Search in the string STRING (with length LENGTH) for the pattern
- compiled into BUFFER. Start searching at position START, for RANGE
- characters. Return the starting position of the match, -1 for no
- match, or -2 for an internal error. Also return register
- information in REGS (if REGS and BUFFER->no_sub are nonzero). */
-extern int re_search
- _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string,
- int length, int start, int range, struct re_registers *regs));
-
-
-/* Like `re_search', but search in the concatenation of STRING1 and
- STRING2. Also, stop searching at index START + STOP. */
-extern int re_search_2
- _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string1,
- int length1, const char *string2, int length2,
- int start, int range, struct re_registers *regs, int stop));
-
-
-/* Like `re_search', but return how many characters in STRING the regexp
- in BUFFER matched, starting at position START. */
-extern int re_match
- _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string,
- int length, int start, struct re_registers *regs));
-
-
-/* Relates to `re_match' as `re_search_2' relates to `re_search'. */
-extern int re_match_2
- _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string1,
- int length1, const char *string2, int length2,
- int start, struct re_registers *regs, int stop));
-
-
-/* Set REGS to hold NUM_REGS registers, storing them in STARTS and
- ENDS. Subsequent matches using BUFFER and REGS will use this memory
- for recording register information. STARTS and ENDS must be
- allocated with malloc, and must each be at least `NUM_REGS * sizeof
- (regoff_t)' bytes long.
-
- If NUM_REGS == 0, then subsequent matches should allocate their own
- register data.
-
- Unless this function is called, the first search or match using
- PATTERN_BUFFER will allocate its own register data, without
- freeing the old data. */
-extern void re_set_registers
- _RE_ARGS ((struct re_pattern_buffer *buffer, struct re_registers *regs,
- unsigned num_regs, regoff_t *starts, regoff_t *ends));
-
-/* 4.2 bsd compatibility. */
-extern char *re_comp _RE_ARGS ((const char *));
-extern int re_exec _RE_ARGS ((const char *));
-
-/* POSIX compatibility. */
-extern int regcomp _RE_ARGS ((regex_t *preg, const char *pattern, int cflags));
-extern int regexec
- _RE_ARGS ((const regex_t *preg, const char *string, size_t nmatch,
- regmatch_t pmatch[], int eflags));
-extern size_t regerror
- _RE_ARGS ((int errcode, const regex_t *preg, char *errbuf,
- size_t errbuf_size));
-extern void regfree _RE_ARGS ((regex_t *preg));
-
-#endif /* not __REGEXP_LIBRARY_H__ */
-
-/*
-Local variables:
-make-backup-files: t
-version-control: t
-trim-versions-without-asking: nil
-End:
-*/
diff --git a/gnu/usr.bin/cvs/lib/rename.c b/gnu/usr.bin/cvs/lib/rename.c
deleted file mode 100644
index 6c43cf6f698c..000000000000
--- a/gnu/usr.bin/cvs/lib/rename.c
+++ /dev/null
@@ -1,72 +0,0 @@
-/* rename.c -- BSD compatible directory function for System V
- Copyright (C) 1988, 1990 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <errno.h>
-#ifndef STDC_HEADERS
-extern int errno;
-#endif
-
-/* Rename file FROM to file TO.
- Return 0 if successful, -1 if not. */
-
-int
-rename (from, to)
- char *from;
- char *to;
-{
- struct stat from_stats;
- int pid, status;
-
- if (stat (from, &from_stats) == 0)
- {
- if (unlink (to) && errno != ENOENT)
- return -1;
- if ((from_stats.st_mode & S_IFMT) == S_IFDIR)
- {
- /* Need a setuid root process to link and unlink directories. */
- pid = fork ();
- switch (pid)
- {
- case -1: /* Error. */
- error (1, errno, "cannot fork");
-
- case 0: /* Child. */
- execl (MVDIR, "mvdir", from, to, (char *) 0);
- error (255, errno, "cannot run `%s'", MVDIR);
-
- default: /* Parent. */
- while (wait (&status) != pid)
- /* Do nothing. */ ;
-
- errno = 0; /* mvdir printed the system error message. */
- return status != 0 ? -1 : 0;
- }
- }
- else
- {
- if (link (from, to) == 0 && (unlink (from) == 0 || errno == ENOENT))
- return 0;
- }
- }
- return -1;
-}
diff --git a/gnu/usr.bin/cvs/lib/run.c b/gnu/usr.bin/cvs/lib/run.c
deleted file mode 100644
index 6a06a385e04b..000000000000
--- a/gnu/usr.bin/cvs/lib/run.c
+++ /dev/null
@@ -1,533 +0,0 @@
-/* run.c --- routines for executing subprocesses.
-
- This file is part of GNU CVS.
-
- GNU CVS is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License as published by the
- Free Software Foundation; either version 2, or (at your option) any
- later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
-
-#include "cvs.h"
-
-#ifdef HAVE_VPRINTF
-#if defined (USE_PROTOTYPES) ? USE_PROTOTYPES : defined (__STDC__)
-#include <stdarg.h>
-#define VA_START(args, lastarg) va_start(args, lastarg)
-#else
-#include <varargs.h>
-#define VA_START(args, lastarg) va_start(args)
-#endif
-#else
-#define va_alist a1, a2, a3, a4, a5, a6, a7, a8
-#define va_dcl char *a1, *a2, *a3, *a4, *a5, *a6, *a7, *a8;
-#endif
-
-static void run_add_arg PROTO((const char *s));
-static void run_init_prog PROTO((void));
-
-extern char *strtok ();
-
-/*
- * To exec a program under CVS, first call run_setup() to setup any initial
- * arguments. The options to run_setup are essentially like printf(). The
- * arguments will be parsed into whitespace separated words and added to the
- * global run_argv list.
- *
- * Then, optionally call run_arg() for each additional argument that you'd like
- * to pass to the executed program.
- *
- * Finally, call run_exec() to execute the program with the specified arguments.
- * The execvp() syscall will be used, so that the PATH is searched correctly.
- * File redirections can be performed in the call to run_exec().
- */
-static char *run_prog;
-static char **run_argv;
-static int run_argc;
-static int run_argc_allocated;
-
-/* VARARGS */
-#if defined (HAVE_VPRINTF) && (defined (USE_PROTOTYPES) ? USE_PROTOTYPES : defined (__STDC__))
-void
-run_setup (const char *fmt,...)
-#else
-void
-run_setup (fmt, va_alist)
- char *fmt;
- va_dcl
-#endif
-{
-#ifdef HAVE_VPRINTF
- va_list args;
-#endif
- char *cp;
- int i;
-
- run_init_prog ();
-
- /* clean out any malloc'ed values from run_argv */
- for (i = 0; i < run_argc; i++)
- {
- if (run_argv[i])
- {
- free (run_argv[i]);
- run_argv[i] = (char *) 0;
- }
- }
- run_argc = 0;
-
- /* process the varargs into run_prog */
-#ifdef HAVE_VPRINTF
- VA_START (args, fmt);
- (void) vsprintf (run_prog, fmt, args);
- va_end (args);
-#else
- (void) sprintf (run_prog, fmt, a1, a2, a3, a4, a5, a6, a7, a8);
-#endif
-
- /* put each word into run_argv, allocating it as we go */
- for (cp = strtok (run_prog, " \t"); cp; cp = strtok ((char *) NULL, " \t"))
- run_add_arg (cp);
-}
-
-void
-run_arg (s)
- const char *s;
-{
- run_add_arg (s);
-}
-
-/* VARARGS */
-#if defined (HAVE_VPRINTF) && (defined (USE_PROTOTYPES) ? USE_PROTOTYPES : defined (__STDC__))
-void
-run_args (const char *fmt,...)
-#else
-void
-run_args (fmt, va_alist)
- char *fmt;
- va_dcl
-#endif
-{
-#ifdef HAVE_VPRINTF
- va_list args;
-#endif
-
- run_init_prog ();
-
- /* process the varargs into run_prog */
-#ifdef HAVE_VPRINTF
- VA_START (args, fmt);
- (void) vsprintf (run_prog, fmt, args);
- va_end (args);
-#else
- (void) sprintf (run_prog, fmt, a1, a2, a3, a4, a5, a6, a7, a8);
-#endif
-
- /* and add the (single) argument to the run_argv list */
- run_add_arg (run_prog);
-}
-
-static void
-run_add_arg (s)
- const char *s;
-{
- /* allocate more argv entries if we've run out */
- if (run_argc >= run_argc_allocated)
- {
- run_argc_allocated += 50;
- run_argv = (char **) xrealloc ((char *) run_argv,
- run_argc_allocated * sizeof (char **));
- }
-
- if (s)
- run_argv[run_argc++] = xstrdup (s);
- else
- run_argv[run_argc] = (char *) 0; /* not post-incremented on purpose! */
-}
-
-static void
-run_init_prog ()
-{
- /* make sure that run_prog is allocated once */
- if (run_prog == (char *) 0)
- run_prog = xmalloc (10 * 1024); /* 10K of args for _setup and _arg */
-}
-
-int
-run_exec (stin, stout, sterr, flags)
- char *stin;
- char *stout;
- char *sterr;
- int flags;
-{
- int shin, shout, sherr;
- int mode_out, mode_err;
- int status;
- int rc = -1;
- int rerrno = 0;
- int pid, w;
-
-#ifdef POSIX_SIGNALS
- sigset_t sigset_mask, sigset_omask;
- struct sigaction act, iact, qact;
-
-#else
-#ifdef BSD_SIGNALS
- int mask;
- struct sigvec vec, ivec, qvec;
-
-#else
- RETSIGTYPE (*istat) (), (*qstat) ();
-#endif
-#endif
-
- if (trace)
- {
-#ifdef SERVER_SUPPORT
- (void) fprintf (stderr, "%c-> system(", (server_active) ? 'S' : ' ');
-#else
- (void) fprintf (stderr, "-> system(");
-#endif
- run_print (stderr);
- (void) fprintf (stderr, ")\n");
- }
- if (noexec && (flags & RUN_REALLY) == 0)
- return (0);
-
- /* make sure that we are null terminated, since we didn't calloc */
- run_add_arg ((char *) 0);
-
- /* setup default file descriptor numbers */
- shin = 0;
- shout = 1;
- sherr = 2;
-
- /* set the file modes for stdout and stderr */
- mode_out = mode_err = O_WRONLY | O_CREAT;
- mode_out |= ((flags & RUN_STDOUT_APPEND) ? O_APPEND : O_TRUNC);
- mode_err |= ((flags & RUN_STDERR_APPEND) ? O_APPEND : O_TRUNC);
-
- if (stin && (shin = open (stin, O_RDONLY)) == -1)
- {
- rerrno = errno;
- error (0, errno, "cannot open %s for reading (prog %s)",
- stin, run_argv[0]);
- goto out0;
- }
- if (stout && (shout = open (stout, mode_out, 0666)) == -1)
- {
- rerrno = errno;
- error (0, errno, "cannot open %s for writing (prog %s)",
- stout, run_argv[0]);
- goto out1;
- }
- if (sterr && (flags & RUN_COMBINED) == 0)
- {
- if ((sherr = open (sterr, mode_err, 0666)) == -1)
- {
- rerrno = errno;
- error (0, errno, "cannot open %s for writing (prog %s)",
- sterr, run_argv[0]);
- goto out2;
- }
- }
-
- /* Make sure we don't flush this twice, once in the subprocess. */
- fflush (stdout);
- fflush (stderr);
-
- /* The output files, if any, are now created. Do the fork and dups */
-#ifdef HAVE_VFORK
- pid = vfork ();
-#else
- pid = fork ();
-#endif
- if (pid == 0)
- {
- if (shin != 0)
- {
- (void) dup2 (shin, 0);
- (void) close (shin);
- }
- if (shout != 1)
- {
- (void) dup2 (shout, 1);
- (void) close (shout);
- }
- if (flags & RUN_COMBINED)
- (void) dup2 (1, 2);
- else if (sherr != 2)
- {
- (void) dup2 (sherr, 2);
- (void) close (sherr);
- }
-
- /* dup'ing is done. try to run it now */
- (void) execvp (run_argv[0], run_argv);
- error (0, errno, "cannot exec %s", run_argv[0]);
- _exit (127);
- }
- else if (pid == -1)
- {
- rerrno = errno;
- goto out;
- }
-
- /* the parent. Ignore some signals for now */
-#ifdef POSIX_SIGNALS
- if (flags & RUN_SIGIGNORE)
- {
- act.sa_handler = SIG_IGN;
- (void) sigemptyset (&act.sa_mask);
- act.sa_flags = 0;
- (void) sigaction (SIGINT, &act, &iact);
- (void) sigaction (SIGQUIT, &act, &qact);
- }
- else
- {
- (void) sigemptyset (&sigset_mask);
- (void) sigaddset (&sigset_mask, SIGINT);
- (void) sigaddset (&sigset_mask, SIGQUIT);
- (void) sigprocmask (SIG_SETMASK, &sigset_mask, &sigset_omask);
- }
-#else
-#ifdef BSD_SIGNALS
- if (flags & RUN_SIGIGNORE)
- {
- memset ((char *) &vec, 0, sizeof (vec));
- vec.sv_handler = SIG_IGN;
- (void) sigvec (SIGINT, &vec, &ivec);
- (void) sigvec (SIGQUIT, &vec, &qvec);
- }
- else
- mask = sigblock (sigmask (SIGINT) | sigmask (SIGQUIT));
-#else
- istat = signal (SIGINT, SIG_IGN);
- qstat = signal (SIGQUIT, SIG_IGN);
-#endif
-#endif
-
- /* wait for our process to die and munge return status */
-#ifdef POSIX_SIGNALS
- while ((w = waitpid (pid, &status, 0)) == -1 && errno == EINTR)
- ;
-#else
- while ((w = wait (&status)) != pid)
- {
- if (w == -1 && errno != EINTR)
- break;
- }
-#endif
- if (w == -1)
- {
- rc = -1;
- rerrno = errno;
- }
- else if (WIFEXITED (status))
- rc = WEXITSTATUS (status);
- else if (WIFSIGNALED (status))
- {
- if (WTERMSIG (status) == SIGPIPE)
- error (1, 0, "broken pipe");
- rc = 2;
- }
- else
- rc = 1;
-
- /* restore the signals */
-#ifdef POSIX_SIGNALS
- if (flags & RUN_SIGIGNORE)
- {
- (void) sigaction (SIGINT, &iact, (struct sigaction *) NULL);
- (void) sigaction (SIGQUIT, &qact, (struct sigaction *) NULL);
- }
- else
- (void) sigprocmask (SIG_SETMASK, &sigset_omask, (sigset_t *) NULL);
-#else
-#ifdef BSD_SIGNALS
- if (flags & RUN_SIGIGNORE)
- {
- (void) sigvec (SIGINT, &ivec, (struct sigvec *) NULL);
- (void) sigvec (SIGQUIT, &qvec, (struct sigvec *) NULL);
- }
- else
- (void) sigsetmask (mask);
-#else
- (void) signal (SIGINT, istat);
- (void) signal (SIGQUIT, qstat);
-#endif
-#endif
-
- /* cleanup the open file descriptors */
- out:
- if (sterr)
- (void) close (sherr);
- out2:
- if (stout)
- (void) close (shout);
- out1:
- if (stin)
- (void) close (shin);
-
- out0:
- if (rerrno)
- errno = rerrno;
- return (rc);
-}
-
-void
-run_print (fp)
- FILE *fp;
-{
- int i;
-
- for (i = 0; i < run_argc; i++)
- {
- (void) fprintf (fp, "'%s'", run_argv[i]);
- if (i != run_argc - 1)
- (void) fprintf (fp, " ");
- }
-}
-
-FILE *
-Popen (cmd, mode)
- const char *cmd;
- const char *mode;
-{
- if (trace)
-#ifdef SERVER_SUPPORT
- (void) fprintf (stderr, "%c-> Popen(%s,%s)\n",
- (server_active) ? 'S' : ' ', cmd, mode);
-#else
- (void) fprintf (stderr, "-> Popen(%s,%s)\n", cmd, mode);
-#endif
- if (noexec)
- return (NULL);
-
- return (popen (cmd, mode));
-}
-
-extern int evecvp PROTO((char *file, char **argv));
-
-int
-piped_child (command, tofdp, fromfdp)
- char **command;
- int *tofdp;
- int *fromfdp;
-{
- int pid;
- int to_child_pipe[2];
- int from_child_pipe[2];
-
- if (pipe (to_child_pipe) < 0)
- error (1, errno, "cannot create pipe");
- if (pipe (from_child_pipe) < 0)
- error (1, errno, "cannot create pipe");
-
- pid = fork ();
- if (pid < 0)
- error (1, errno, "cannot fork");
- if (pid == 0)
- {
- if (dup2 (to_child_pipe[0], STDIN_FILENO) < 0)
- error (1, errno, "cannot dup2");
- if (close (to_child_pipe[1]) < 0)
- error (1, errno, "cannot close");
- if (close (from_child_pipe[0]) < 0)
- error (1, errno, "cannot close");
- if (dup2 (from_child_pipe[1], STDOUT_FILENO) < 0)
- error (1, errno, "cannot dup2");
-
- execvp (command[0], command);
- error (1, errno, "cannot exec");
- }
- if (close (to_child_pipe[0]) < 0)
- error (1, errno, "cannot close");
- if (close (from_child_pipe[1]) < 0)
- error (1, errno, "cannot close");
-
- *tofdp = to_child_pipe[1];
- *fromfdp = from_child_pipe[0];
- return pid;
-}
-
-
-void
-close_on_exec (fd)
- int fd;
-{
-#if defined (FD_CLOEXEC) && defined (F_SETFD)
- if (fcntl (fd, F_SETFD, 1))
- error (1, errno, "can't set close-on-exec flag on %d", fd);
-#endif
-}
-
-/*
- * dir = 0 : main proc writes to new proc, which writes to oldfd
- * dir = 1 : main proc reads from new proc, which reads from oldfd
- */
-
-int
-filter_stream_through_program (oldfd, dir, prog, pidp)
- int oldfd, dir;
- char **prog;
- pid_t *pidp;
-{
- int p[2], newfd;
- pid_t newpid;
-
- if (pipe (p))
- error (1, errno, "cannot create pipe");
- newpid = fork ();
- if (pidp)
- *pidp = newpid;
- switch (newpid)
- {
- case -1:
- error (1, errno, "cannot fork");
- case 0:
- /* child */
- if (dir)
- {
- /* write to new pipe */
- close (p[0]);
- dup2 (oldfd, 0);
- dup2 (p[1], 1);
- }
- else
- {
- /* read from new pipe */
- close (p[1]);
- dup2 (p[0], 0);
- dup2 (oldfd, 1);
- }
- /* Should I be blocking some signals here? */
- execvp (prog[0], prog);
- error (1, errno, "couldn't exec %s", prog[0]);
- default:
- /* parent */
- close (oldfd);
- if (dir)
- {
- /* read from new pipe */
- close (p[1]);
- newfd = p[0];
- }
- else
- {
- /* write to new pipe */
- close (p[0]);
- newfd = p[1];
- }
- close_on_exec (newfd);
- return newfd;
- }
-}
diff --git a/gnu/usr.bin/cvs/lib/save-cwd.c b/gnu/usr.bin/cvs/lib/save-cwd.c
deleted file mode 100644
index 1bdf79115100..000000000000
--- a/gnu/usr.bin/cvs/lib/save-cwd.c
+++ /dev/null
@@ -1,141 +0,0 @@
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include <stdio.h>
-
-#ifdef STDC_HEADERS
-# include <stdlib.h>
-#endif
-
-#ifdef HAVE_UNISTD_H
-# include <unistd.h>
-#endif
-
-#ifdef HAVE_FCNTL_H
-# include <fcntl.h>
-#else
-# include <sys/file.h>
-#endif
-
-#ifdef HAVE_DIRECT_H
-# include <direct.h>
-#endif
-
-#ifdef HAVE_IO_H
-# include <io.h>
-#endif
-
-#include <errno.h>
-# ifndef errno
-extern int errno;
-#endif
-
-#include "save-cwd.h"
-#include "error.h"
-
-char *xgetwd __PROTO((void));
-
-/* Record the location of the current working directory in CWD so that
- the program may change to other directories and later use restore_cwd
- to return to the recorded location. This function may allocate
- space using malloc (via xgetwd) or leave a file descriptor open;
- use free_cwd to perform the necessary free or close. Upon failure,
- no memory is allocated, any locally opened file descriptors are
- closed; return non-zero -- in that case, free_cwd need not be
- called, but doing so is ok. Otherwise, return zero. */
-
-int
-save_cwd (cwd)
- struct saved_cwd *cwd;
-{
- static int have_working_fchdir = 1;
-
- cwd->desc = -1;
- cwd->name = NULL;
-
- if (have_working_fchdir)
- {
-#ifdef HAVE_FCHDIR
- cwd->desc = open (".", O_RDONLY);
- if (cwd->desc < 0)
- {
- error (0, errno, "cannot open current directory");
- return 1;
- }
-
-# if __sun__ || sun
- /* On SunOS 4, fchdir returns EINVAL if accounting is enabled,
- so we have to fall back to chdir. */
- if (fchdir (cwd->desc))
- {
- if (errno == EINVAL)
- {
- close (cwd->desc);
- cwd->desc = -1;
- have_working_fchdir = 0;
- }
- else
- {
- error (0, errno, "current directory");
- close (cwd->desc);
- cwd->desc = -1;
- return 1;
- }
- }
-# endif /* __sun__ || sun */
-#else
-#define fchdir(x) (abort (), 0)
- have_working_fchdir = 0;
-#endif
- }
-
- if (!have_working_fchdir)
- {
- cwd->name = xgetwd ();
- if (cwd->name == NULL)
- {
- error (0, errno, "cannot get current directory");
- return 1;
- }
- }
- return 0;
-}
-
-/* Change to recorded location, CWD, in directory hierarchy.
- If "saved working directory", NULL))
- */
-
-int
-restore_cwd (cwd, dest)
- const struct saved_cwd *cwd;
- const char *dest;
-{
- int fail = 0;
- if (cwd->desc >= 0)
- {
- if (fchdir (cwd->desc))
- {
- error (0, errno, "cannot return to %s",
- (dest ? dest : "saved working directory"));
- fail = 1;
- }
- }
- else if (chdir (cwd->name) < 0)
- {
- error (0, errno, "%s", cwd->name);
- fail = 1;
- }
- return fail;
-}
-
-void
-free_cwd (cwd)
- struct saved_cwd *cwd;
-{
- if (cwd->desc >= 0)
- close (cwd->desc);
- if (cwd->name)
- free (cwd->name);
-}
-
diff --git a/gnu/usr.bin/cvs/lib/save-cwd.h b/gnu/usr.bin/cvs/lib/save-cwd.h
deleted file mode 100644
index f9802f8ca2fa..000000000000
--- a/gnu/usr.bin/cvs/lib/save-cwd.h
+++ /dev/null
@@ -1,20 +0,0 @@
-#ifndef SAVE_CWD_H
-#define SAVE_CWD_H 1
-
-struct saved_cwd
- {
- int desc;
- char *name;
- };
-
-#if defined (__GNUC__) || (defined (__STDC__) && __STDC__)
-#define __PROTO(args) args
-#else
-#define __PROTO(args) ()
-#endif /* GCC. */
-
-int save_cwd __PROTO((struct saved_cwd *cwd));
-int restore_cwd __PROTO((const struct saved_cwd *cwd, const char *dest));
-void free_cwd __PROTO((struct saved_cwd *cwd));
-
-#endif /* SAVE_CWD_H */
diff --git a/gnu/usr.bin/cvs/lib/sighandle.c b/gnu/usr.bin/cvs/lib/sighandle.c
deleted file mode 100644
index a2259837d8b2..000000000000
--- a/gnu/usr.bin/cvs/lib/sighandle.c
+++ /dev/null
@@ -1,405 +0,0 @@
-/* sighandle.c -- Library routines for manipulating chains of signal handlers
- Copyright (C) 1992 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
-
-/* Written by Paul Sander, HaL Computer Systems, Inc. <paul@hal.com>
- Brian Berliner <berliner@Sun.COM> added POSIX support */
-
-/*************************************************************************
- *
- * signal.c -- This file contains code that manipulates chains of signal
- * handlers.
- *
- * Facilities are provided to register a signal handler for
- * any specific signal. When a signal is received, all of the
- * registered signal handlers are invoked in the reverse order
- * in which they are registered. Note that the signal handlers
- * must not themselves make calls to the signal handling
- * facilities.
- *
- * $CVSid: @(#)sighandle.c 1.13 94/10/07 $
- *
- *************************************************************************/
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-#include "system.h"
-
-#include <sys/types.h>
-#include <stdio.h>
-#include <signal.h>
-
-#ifdef STDC_HEADERS
-#include <stdlib.h>
-#else
-#if __STDC__
-char *calloc(unsigned nelem, unsigned size);
-char *malloc(unsigned size);
-#else
-char *calloc();
-char *malloc();
-#endif /* __STDC__ */
-#endif /* STDC_HEADERS */
-
-/* Define the highest signal number (usually) */
-#ifndef SIGMAX
-#define SIGMAX 64
-#endif
-
-/* Define linked list of signal handlers structure */
-struct SIG_hlist {
- RETSIGTYPE (*handler)();
- struct SIG_hlist *next;
-};
-
-/*
- * Define array of lists of signal handlers. Note that this depends on
- * the implementation to initialize each element to a null pointer.
- */
-
-static struct SIG_hlist **SIG_handlers;
-
-/* Define array of default signal vectors */
-
-#ifdef POSIX_SIGNALS
-static struct sigaction *SIG_defaults;
-#else
-#ifdef BSD_SIGNALS
-static struct sigvec *SIG_defaults;
-#else
-static RETSIGTYPE (**SIG_defaults)();
-#endif
-#endif
-
-/* Critical section housekeeping */
-static int SIG_crSectNest = 0; /* Nesting level */
-#ifdef POSIX_SIGNALS
-static sigset_t SIG_crSectMask; /* Signal mask */
-#else
-static int SIG_crSectMask; /* Signal mask */
-#endif
-
-/*
- * Initialize the signal handler arrays
- */
-
-static int SIG_init()
-{
- int i;
-#ifdef POSIX_SIGNALS
- sigset_t sigset_test;
-#endif
-
- if (SIG_defaults && SIG_handlers) /* already allocated */
- return (0);
-
-#ifdef POSIX_SIGNALS
- (void) sigfillset(&sigset_test);
- for (i = 1; i < SIGMAX && sigismember(&sigset_test, i) == 1; i++)
- ;
- if (i < SIGMAX)
- i = SIGMAX;
- i++;
- if (!SIG_defaults)
- SIG_defaults = (struct sigaction *)
- calloc(i, sizeof(struct sigaction));
- (void) sigemptyset(&SIG_crSectMask);
-#else
- i = SIGMAX+1;
-#ifdef BSD_SIGNALS
- if (!SIG_defaults)
- SIG_defaults = (struct sigvec *)
- calloc(i, sizeof(struct sigvec));
-#else
- if (!SIG_defaults)
- SIG_defaults = (RETSIGTYPE (**)())
- calloc(i, sizeof(RETSIGTYPE (**)()));
-#endif
- SIG_crSectMask = 0;
-#endif
- if (!SIG_handlers)
- SIG_handlers = (struct SIG_hlist **)
- calloc(i, sizeof(struct SIG_hlist *));
- return (!SIG_defaults || !SIG_handlers);
-}
-
-/*
- * The following invokes each signal handler in the reverse order in which
- * they were registered.
- */
-
-static RETSIGTYPE SIG_handle(sig)
-int sig;
-{
- struct SIG_hlist *this;
-
- /* Dispatch signal handlers */
- this = SIG_handlers[sig];
- while (this != (struct SIG_hlist *) NULL)
- {
- (*this->handler)(sig);
- this = this->next;
- }
-
- return;
-}
-
-/*
- * The following registers a signal handler. If the handler is already
- * registered, it is not registered twice, nor is the order in which signal
- * handlers are invoked changed. If this is the first signal handler
- * registered for a given signal, the old sigvec structure is saved for
- * restoration later.
- */
-
-int SIG_register(sig,fn)
-int sig;
-RETSIGTYPE (*fn)();
-{
- int val;
- struct SIG_hlist *this;
-#ifdef POSIX_SIGNALS
- struct sigaction act;
- sigset_t sigset_mask, sigset_omask;
-#else
-#ifdef BSD_SIGNALS
- struct sigvec vec;
- int mask;
-#endif
-#endif
-
- /* Initialize */
- if (SIG_init() != 0)
- return (-1);
- val = 0;
-
- /* Block this signal while we look at handler chain */
-#ifdef POSIX_SIGNALS
- (void) sigemptyset(&sigset_mask);
- (void) sigaddset(&sigset_mask, sig);
- (void) sigprocmask(SIG_BLOCK, &sigset_mask, &sigset_omask);
-#else
-#ifdef BSD_SIGNALS
- mask = sigblock(sigmask(sig));
-#endif
-#endif
-
- /* See if this handler was already registered */
- this = SIG_handlers[sig];
- while (this != (struct SIG_hlist *) NULL)
- {
- if (this->handler == fn) break;
- this = this->next;
- }
-
- /* Register the new handler only if it is not already registered. */
- if (this == (struct SIG_hlist *) NULL)
- {
-
- /*
- * If this is the first handler registered for this signal,
- * set up the signal handler dispatcher
- */
-
- if (SIG_handlers[sig] == (struct SIG_hlist *) NULL)
- {
-#ifdef POSIX_SIGNALS
- act.sa_handler = SIG_handle;
- (void) sigemptyset(&act.sa_mask);
- act.sa_flags = 0;
- val = sigaction(sig, &act, &SIG_defaults[sig]);
-#else
-#ifdef BSD_SIGNALS
- bzero((char *)&vec, sizeof(vec));
- vec.sv_handler = SIG_handle;
- val = sigvec(sig, &vec, &SIG_defaults[sig]);
-#else
- if ((SIG_defaults[sig] = signal(sig, SIG_handle)) ==
- (RETSIGTYPE (*)()) -1)
- val = -1;
-#endif
-#endif
- }
-
- /* If not, register it */
- if ((val == 0) && (this == (struct SIG_hlist *) NULL))
- {
- this = (struct SIG_hlist *)
- malloc(sizeof(struct SIG_hlist));
- if (this == NULL)
- {
- val = -1;
- }
- else
- {
- this->handler = fn;
- this->next = SIG_handlers[sig];
- SIG_handlers[sig] = this;
- }
- }
- }
-
- /* Unblock the signal */
-#ifdef POSIX_SIGNALS
- (void) sigprocmask(SIG_SETMASK, &sigset_omask, NULL);
-#else
-#ifdef BSD_SIGNALS
- (void) sigsetmask(mask);
-#endif
-#endif
-
- return val;
-}
-
-/*
- * The following deregisters a signal handler. If the last signal handler for
- * a given signal is deregistered, the default sigvec information is restored.
- */
-
-int SIG_deregister(sig,fn)
-int sig;
-RETSIGTYPE (*fn)();
-{
- int val;
- struct SIG_hlist *this;
- struct SIG_hlist *last;
-#ifdef POSIX_SIGNALS
- sigset_t sigset_mask, sigset_omask;
-#else
-#ifdef BSD_SIGNALS
- int mask;
-#endif
-#endif
-
- /* Initialize */
- if (SIG_init() != 0)
- return (-1);
- val = 0;
- last = (struct SIG_hlist *) NULL;
-
- /* Block this signal while we look at handler chain */
-#ifdef POSIX_SIGNALS
- (void) sigemptyset(&sigset_mask);
- (void) sigaddset(&sigset_mask, sig);
- (void) sigprocmask(SIG_BLOCK, &sigset_mask, &sigset_omask);
-#else
-#ifdef BSD_SIGNALS
- mask = sigblock(sigmask(sig));
-#endif
-#endif
-
- /* Search for the signal handler */
- this = SIG_handlers[sig];
- while ((this != (struct SIG_hlist *) NULL) && (this->handler != fn))
- {
- last = this;
- this = this->next;
- }
-
- /* If it was registered, remove it */
- if (this != (struct SIG_hlist *) NULL)
- {
- if (last == (struct SIG_hlist *) NULL)
- {
- SIG_handlers[sig] = this->next;
- }
- else
- {
- last->next = this->next;
- }
- free((char *) this);
- }
-
- /* Restore default behavior if there are no registered handlers */
- if (SIG_handlers[sig] == (struct SIG_hlist *) NULL)
- {
-#ifdef POSIX_SIGNALS
- val = sigaction(sig, &SIG_defaults[sig],
- (struct sigaction *) NULL);
-#else
-#ifdef BSD_SIGNALS
- val = sigvec(sig, &SIG_defaults[sig], (struct sigvec *) NULL);
-#else
- if (signal(sig, SIG_defaults[sig]) == (RETSIGTYPE (*)()) -1)
- val = -1;
-#endif
-#endif
- }
-
- /* Unblock the signal */
-#ifdef POSIX_SIGNALS
- (void) sigprocmask(SIG_SETMASK, &sigset_omask, NULL);
-#else
-#ifdef BSD_SIGNALS
- (void) sigsetmask(mask);
-#endif
-#endif
-
- return val;
-}
-
-/*
- * The following begins a critical section.
- */
-
-void SIG_beginCrSect()
-{
- if (SIG_init() == 0)
- {
- if (SIG_crSectNest == 0)
- {
-#ifdef POSIX_SIGNALS
- sigset_t sigset_mask;
-
- (void) sigfillset(&sigset_mask);
- (void) sigprocmask(SIG_SETMASK,
- &sigset_mask, &SIG_crSectMask);
-#else
-#ifdef BSD_SIGNALS
- SIG_crSectMask = sigblock(~0);
-#else
- /* TBD */
-#endif
-#endif
- }
- SIG_crSectNest++;
- }
-}
-
-/*
- * The following ends a critical section.
- */
-
-void SIG_endCrSect()
-{
- if (SIG_init() == 0)
- {
- SIG_crSectNest--;
- if (SIG_crSectNest == 0)
- {
-#ifdef POSIX_SIGNALS
- (void) sigprocmask(SIG_SETMASK, &SIG_crSectMask, NULL);
-#else
-#ifdef BSD_SIGNALS
- (void) sigsetmask(SIG_crSectMask);
-#else
- /* TBD */
-#endif
-#endif
- }
- }
-}
diff --git a/gnu/usr.bin/cvs/lib/strdup.c b/gnu/usr.bin/cvs/lib/strdup.c
deleted file mode 100644
index 46fc8a0d6dbc..000000000000
--- a/gnu/usr.bin/cvs/lib/strdup.c
+++ /dev/null
@@ -1,43 +0,0 @@
-/* strdup.c -- return a newly allocated copy of a string
- Copyright (C) 1990 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#ifdef STDC_HEADERS
-#include <string.h>
-#include <stdlib.h>
-#else
-char *malloc ();
-char *strcpy ();
-#endif
-
-/* Return a newly allocated copy of STR,
- or 0 if out of memory. */
-
-char *
-strdup (str)
- char *str;
-{
- char *newstr;
-
- newstr = (char *) malloc (strlen (str) + 1);
- if (newstr)
- strcpy (newstr, str);
- return newstr;
-}
diff --git a/gnu/usr.bin/cvs/lib/strerror.c b/gnu/usr.bin/cvs/lib/strerror.c
deleted file mode 100644
index b0bec1317a91..000000000000
--- a/gnu/usr.bin/cvs/lib/strerror.c
+++ /dev/null
@@ -1,813 +0,0 @@
-/* Extended support for using errno values.
- Copyright (C) 1992 Free Software Foundation, Inc.
- Written by Fred Fish. fnf@cygnus.com
-
-This file is part of the libiberty library.
-Libiberty is free software; you can redistribute it and/or
-modify it under the terms of the GNU Library General Public
-License as published by the Free Software Foundation; either
-version 2 of the License, or (at your option) any later version.
-
-Libiberty is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-Library General Public License for more details.
-
-You should have received a copy of the GNU Library General Public
-License along with libiberty; see the file COPYING.LIB. If
-not, write to the Free Software Foundation, Inc., 675 Mass Ave,
-Cambridge, MA 02139, USA. */
-
-#include "config.h"
-
-#ifndef NEED_sys_errlist
-/* Note that errno.h (not sure what OS) or stdio.h (BSD 4.4, at least)
- might declare sys_errlist in a way that the compiler might consider
- incompatible with our later declaration, perhaps by using const
- attributes. So we hide the declaration in errno.h (if any) using a
- macro. */
-#define sys_errlist sys_errlist__
-#endif
-
-#include <stdio.h>
-#include <errno.h>
-
-#ifndef NEED_sys_errlist
-#undef sys_errlist
-#endif
-
-/* Routines imported from standard C runtime libraries. */
-
-#ifdef __STDC__
-#include <stddef.h>
-extern void *malloc (size_t size); /* 4.10.3.3 */
-extern void *memset (void *s, int c, size_t n); /* 4.11.6.1 */
-#else /* !__STDC__ */
-extern char *malloc (); /* Standard memory allocater */
-extern char *memset ();
-#endif /* __STDC__ */
-
-#ifndef MAX
-# define MAX(a,b) ((a) > (b) ? (a) : (b))
-#endif
-
-/* Translation table for errno values. See intro(2) in most UNIX systems
- Programmers Reference Manuals.
-
- Note that this table is generally only accessed when it is used at runtime
- to initialize errno name and message tables that are indexed by errno
- value.
-
- Not all of these errnos will exist on all systems. This table is the only
- thing that should have to be updated as new error numbers are introduced.
- It's sort of ugly, but at least its portable. */
-
-struct error_info
-{
- int value; /* The numeric value from <errno.h> */
- char *name; /* The equivalent symbolic value */
-#ifdef NEED_sys_errlist
- char *msg; /* Short message about this value */
-#endif
-};
-
-#ifdef NEED_sys_errlist
-# define ENTRY(value, name, msg) {value, name, msg}
-#else
-# define ENTRY(value, name, msg) {value, name}
-#endif
-
-static const struct error_info error_table[] =
-{
-#if defined (EPERM)
- ENTRY(EPERM, "EPERM", "Not owner"),
-#endif
-#if defined (ENOENT)
- ENTRY(ENOENT, "ENOENT", "No such file or directory"),
-#endif
-#if defined (ESRCH)
- ENTRY(ESRCH, "ESRCH", "No such process"),
-#endif
-#if defined (EINTR)
- ENTRY(EINTR, "EINTR", "Interrupted system call"),
-#endif
-#if defined (EIO)
- ENTRY(EIO, "EIO", "I/O error"),
-#endif
-#if defined (ENXIO)
- ENTRY(ENXIO, "ENXIO", "No such device or address"),
-#endif
-#if defined (E2BIG)
- ENTRY(E2BIG, "E2BIG", "Arg list too long"),
-#endif
-#if defined (ENOEXEC)
- ENTRY(ENOEXEC, "ENOEXEC", "Exec format error"),
-#endif
-#if defined (EBADF)
- ENTRY(EBADF, "EBADF", "Bad file number"),
-#endif
-#if defined (ECHILD)
- ENTRY(ECHILD, "ECHILD", "No child processes"),
-#endif
-#if defined (EWOULDBLOCK) /* Put before EAGAIN, sometimes aliased */
- ENTRY(EWOULDBLOCK, "EWOULDBLOCK", "Operation would block"),
-#endif
-#if defined (EAGAIN)
- ENTRY(EAGAIN, "EAGAIN", "No more processes"),
-#endif
-#if defined (ENOMEM)
- ENTRY(ENOMEM, "ENOMEM", "Not enough space"),
-#endif
-#if defined (EACCES)
- ENTRY(EACCES, "EACCES", "Permission denied"),
-#endif
-#if defined (EFAULT)
- ENTRY(EFAULT, "EFAULT", "Bad address"),
-#endif
-#if defined (ENOTBLK)
- ENTRY(ENOTBLK, "ENOTBLK", "Block device required"),
-#endif
-#if defined (EBUSY)
- ENTRY(EBUSY, "EBUSY", "Device busy"),
-#endif
-#if defined (EEXIST)
- ENTRY(EEXIST, "EEXIST", "File exists"),
-#endif
-#if defined (EXDEV)
- ENTRY(EXDEV, "EXDEV", "Cross-device link"),
-#endif
-#if defined (ENODEV)
- ENTRY(ENODEV, "ENODEV", "No such device"),
-#endif
-#if defined (ENOTDIR)
- ENTRY(ENOTDIR, "ENOTDIR", "Not a directory"),
-#endif
-#if defined (EISDIR)
- ENTRY(EISDIR, "EISDIR", "Is a directory"),
-#endif
-#if defined (EINVAL)
- ENTRY(EINVAL, "EINVAL", "Invalid argument"),
-#endif
-#if defined (ENFILE)
- ENTRY(ENFILE, "ENFILE", "File table overflow"),
-#endif
-#if defined (EMFILE)
- ENTRY(EMFILE, "EMFILE", "Too many open files"),
-#endif
-#if defined (ENOTTY)
- ENTRY(ENOTTY, "ENOTTY", "Not a typewriter"),
-#endif
-#if defined (ETXTBSY)
- ENTRY(ETXTBSY, "ETXTBSY", "Text file busy"),
-#endif
-#if defined (EFBIG)
- ENTRY(EFBIG, "EFBIG", "File too large"),
-#endif
-#if defined (ENOSPC)
- ENTRY(ENOSPC, "ENOSPC", "No space left on device"),
-#endif
-#if defined (ESPIPE)
- ENTRY(ESPIPE, "ESPIPE", "Illegal seek"),
-#endif
-#if defined (EROFS)
- ENTRY(EROFS, "EROFS", "Read-only file system"),
-#endif
-#if defined (EMLINK)
- ENTRY(EMLINK, "EMLINK", "Too many links"),
-#endif
-#if defined (EPIPE)
- ENTRY(EPIPE, "EPIPE", "Broken pipe"),
-#endif
-#if defined (EDOM)
- ENTRY(EDOM, "EDOM", "Math argument out of domain of func"),
-#endif
-#if defined (ERANGE)
- ENTRY(ERANGE, "ERANGE", "Math result not representable"),
-#endif
-#if defined (ENOMSG)
- ENTRY(ENOMSG, "ENOMSG", "No message of desired type"),
-#endif
-#if defined (EIDRM)
- ENTRY(EIDRM, "EIDRM", "Identifier removed"),
-#endif
-#if defined (ECHRNG)
- ENTRY(ECHRNG, "ECHRNG", "Channel number out of range"),
-#endif
-#if defined (EL2NSYNC)
- ENTRY(EL2NSYNC, "EL2NSYNC", "Level 2 not synchronized"),
-#endif
-#if defined (EL3HLT)
- ENTRY(EL3HLT, "EL3HLT", "Level 3 halted"),
-#endif
-#if defined (EL3RST)
- ENTRY(EL3RST, "EL3RST", "Level 3 reset"),
-#endif
-#if defined (ELNRNG)
- ENTRY(ELNRNG, "ELNRNG", "Link number out of range"),
-#endif
-#if defined (EUNATCH)
- ENTRY(EUNATCH, "EUNATCH", "Protocol driver not attached"),
-#endif
-#if defined (ENOCSI)
- ENTRY(ENOCSI, "ENOCSI", "No CSI structure available"),
-#endif
-#if defined (EL2HLT)
- ENTRY(EL2HLT, "EL2HLT", "Level 2 halted"),
-#endif
-#if defined (EDEADLK)
- ENTRY(EDEADLK, "EDEADLK", "Deadlock condition"),
-#endif
-#if defined (ENOLCK)
- ENTRY(ENOLCK, "ENOLCK", "No record locks available"),
-#endif
-#if defined (EBADE)
- ENTRY(EBADE, "EBADE", "Invalid exchange"),
-#endif
-#if defined (EBADR)
- ENTRY(EBADR, "EBADR", "Invalid request descriptor"),
-#endif
-#if defined (EXFULL)
- ENTRY(EXFULL, "EXFULL", "Exchange full"),
-#endif
-#if defined (ENOANO)
- ENTRY(ENOANO, "ENOANO", "No anode"),
-#endif
-#if defined (EBADRQC)
- ENTRY(EBADRQC, "EBADRQC", "Invalid request code"),
-#endif
-#if defined (EBADSLT)
- ENTRY(EBADSLT, "EBADSLT", "Invalid slot"),
-#endif
-#if defined (EDEADLOCK)
- ENTRY(EDEADLOCK, "EDEADLOCK", "File locking deadlock error"),
-#endif
-#if defined (EBFONT)
- ENTRY(EBFONT, "EBFONT", "Bad font file format"),
-#endif
-#if defined (ENOSTR)
- ENTRY(ENOSTR, "ENOSTR", "Device not a stream"),
-#endif
-#if defined (ENODATA)
- ENTRY(ENODATA, "ENODATA", "No data available"),
-#endif
-#if defined (ETIME)
- ENTRY(ETIME, "ETIME", "Timer expired"),
-#endif
-#if defined (ENOSR)
- ENTRY(ENOSR, "ENOSR", "Out of streams resources"),
-#endif
-#if defined (ENONET)
- ENTRY(ENONET, "ENONET", "Machine is not on the network"),
-#endif
-#if defined (ENOPKG)
- ENTRY(ENOPKG, "ENOPKG", "Package not installed"),
-#endif
-#if defined (EREMOTE)
- ENTRY(EREMOTE, "EREMOTE", "Object is remote"),
-#endif
-#if defined (ENOLINK)
- ENTRY(ENOLINK, "ENOLINK", "Link has been severed"),
-#endif
-#if defined (EADV)
- ENTRY(EADV, "EADV", "Advertise error"),
-#endif
-#if defined (ESRMNT)
- ENTRY(ESRMNT, "ESRMNT", "Srmount error"),
-#endif
-#if defined (ECOMM)
- ENTRY(ECOMM, "ECOMM", "Communication error on send"),
-#endif
-#if defined (EPROTO)
- ENTRY(EPROTO, "EPROTO", "Protocol error"),
-#endif
-#if defined (EMULTIHOP)
- ENTRY(EMULTIHOP, "EMULTIHOP", "Multihop attempted"),
-#endif
-#if defined (EDOTDOT)
- ENTRY(EDOTDOT, "EDOTDOT", "RFS specific error"),
-#endif
-#if defined (EBADMSG)
- ENTRY(EBADMSG, "EBADMSG", "Not a data message"),
-#endif
-#if defined (ENAMETOOLONG)
- ENTRY(ENAMETOOLONG, "ENAMETOOLONG", "File name too long"),
-#endif
-#if defined (EOVERFLOW)
- ENTRY(EOVERFLOW, "EOVERFLOW", "Value too large for defined data type"),
-#endif
-#if defined (ENOTUNIQ)
- ENTRY(ENOTUNIQ, "ENOTUNIQ", "Name not unique on network"),
-#endif
-#if defined (EBADFD)
- ENTRY(EBADFD, "EBADFD", "File descriptor in bad state"),
-#endif
-#if defined (EREMCHG)
- ENTRY(EREMCHG, "EREMCHG", "Remote address changed"),
-#endif
-#if defined (ELIBACC)
- ENTRY(ELIBACC, "ELIBACC", "Can not access a needed shared library"),
-#endif
-#if defined (ELIBBAD)
- ENTRY(ELIBBAD, "ELIBBAD", "Accessing a corrupted shared library"),
-#endif
-#if defined (ELIBSCN)
- ENTRY(ELIBSCN, "ELIBSCN", ".lib section in a.out corrupted"),
-#endif
-#if defined (ELIBMAX)
- ENTRY(ELIBMAX, "ELIBMAX", "Attempting to link in too many shared libraries"),
-#endif
-#if defined (ELIBEXEC)
- ENTRY(ELIBEXEC, "ELIBEXEC", "Cannot exec a shared library directly"),
-#endif
-#if defined (EILSEQ)
- ENTRY(EILSEQ, "EILSEQ", "Illegal byte sequence"),
-#endif
-#if defined (ENOSYS)
- ENTRY(ENOSYS, "ENOSYS", "Operation not applicable"),
-#endif
-#if defined (ELOOP)
- ENTRY(ELOOP, "ELOOP", "Too many symbolic links encountered"),
-#endif
-#if defined (ERESTART)
- ENTRY(ERESTART, "ERESTART", "Interrupted system call should be restarted"),
-#endif
-#if defined (ESTRPIPE)
- ENTRY(ESTRPIPE, "ESTRPIPE", "Streams pipe error"),
-#endif
-#if defined (ENOTEMPTY)
- ENTRY(ENOTEMPTY, "ENOTEMPTY", "Directory not empty"),
-#endif
-#if defined (EUSERS)
- ENTRY(EUSERS, "EUSERS", "Too many users"),
-#endif
-#if defined (ENOTSOCK)
- ENTRY(ENOTSOCK, "ENOTSOCK", "Socket operation on non-socket"),
-#endif
-#if defined (EDESTADDRREQ)
- ENTRY(EDESTADDRREQ, "EDESTADDRREQ", "Destination address required"),
-#endif
-#if defined (EMSGSIZE)
- ENTRY(EMSGSIZE, "EMSGSIZE", "Message too long"),
-#endif
-#if defined (EPROTOTYPE)
- ENTRY(EPROTOTYPE, "EPROTOTYPE", "Protocol wrong type for socket"),
-#endif
-#if defined (ENOPROTOOPT)
- ENTRY(ENOPROTOOPT, "ENOPROTOOPT", "Protocol not available"),
-#endif
-#if defined (EPROTONOSUPPORT)
- ENTRY(EPROTONOSUPPORT, "EPROTONOSUPPORT", "Protocol not supported"),
-#endif
-#if defined (ESOCKTNOSUPPORT)
- ENTRY(ESOCKTNOSUPPORT, "ESOCKTNOSUPPORT", "Socket type not supported"),
-#endif
-#if defined (EOPNOTSUPP)
- ENTRY(EOPNOTSUPP, "EOPNOTSUPP", "Operation not supported on transport endpoint"),
-#endif
-#if defined (EPFNOSUPPORT)
- ENTRY(EPFNOSUPPORT, "EPFNOSUPPORT", "Protocol family not supported"),
-#endif
-#if defined (EAFNOSUPPORT)
- ENTRY(EAFNOSUPPORT, "EAFNOSUPPORT", "Address family not supported by protocol"),
-#endif
-#if defined (EADDRINUSE)
- ENTRY(EADDRINUSE, "EADDRINUSE", "Address already in use"),
-#endif
-#if defined (EADDRNOTAVAIL)
- ENTRY(EADDRNOTAVAIL, "EADDRNOTAVAIL","Cannot assign requested address"),
-#endif
-#if defined (ENETDOWN)
- ENTRY(ENETDOWN, "ENETDOWN", "Network is down"),
-#endif
-#if defined (ENETUNREACH)
- ENTRY(ENETUNREACH, "ENETUNREACH", "Network is unreachable"),
-#endif
-#if defined (ENETRESET)
- ENTRY(ENETRESET, "ENETRESET", "Network dropped connection because of reset"),
-#endif
-#if defined (ECONNABORTED)
- ENTRY(ECONNABORTED, "ECONNABORTED", "Software caused connection abort"),
-#endif
-#if defined (ECONNRESET)
- ENTRY(ECONNRESET, "ECONNRESET", "Connection reset by peer"),
-#endif
-#if defined (ENOBUFS)
- ENTRY(ENOBUFS, "ENOBUFS", "No buffer space available"),
-#endif
-#if defined (EISCONN)
- ENTRY(EISCONN, "EISCONN", "Transport endpoint is already connected"),
-#endif
-#if defined (ENOTCONN)
- ENTRY(ENOTCONN, "ENOTCONN", "Transport endpoint is not connected"),
-#endif
-#if defined (ESHUTDOWN)
- ENTRY(ESHUTDOWN, "ESHUTDOWN", "Cannot send after transport endpoint shutdown"),
-#endif
-#if defined (ETOOMANYREFS)
- ENTRY(ETOOMANYREFS, "ETOOMANYREFS", "Too many references: cannot splice"),
-#endif
-#if defined (ETIMEDOUT)
- ENTRY(ETIMEDOUT, "ETIMEDOUT", "Connection timed out"),
-#endif
-#if defined (ECONNREFUSED)
- ENTRY(ECONNREFUSED, "ECONNREFUSED", "Connection refused"),
-#endif
-#if defined (EHOSTDOWN)
- ENTRY(EHOSTDOWN, "EHOSTDOWN", "Host is down"),
-#endif
-#if defined (EHOSTUNREACH)
- ENTRY(EHOSTUNREACH, "EHOSTUNREACH", "No route to host"),
-#endif
-#if defined (EALREADY)
- ENTRY(EALREADY, "EALREADY", "Operation already in progress"),
-#endif
-#if defined (EINPROGRESS)
- ENTRY(EINPROGRESS, "EINPROGRESS", "Operation now in progress"),
-#endif
-#if defined (ESTALE)
- ENTRY(ESTALE, "ESTALE", "Stale NFS file handle"),
-#endif
-#if defined (EUCLEAN)
- ENTRY(EUCLEAN, "EUCLEAN", "Structure needs cleaning"),
-#endif
-#if defined (ENOTNAM)
- ENTRY(ENOTNAM, "ENOTNAM", "Not a XENIX named type file"),
-#endif
-#if defined (ENAVAIL)
- ENTRY(ENAVAIL, "ENAVAIL", "No XENIX semaphores available"),
-#endif
-#if defined (EISNAM)
- ENTRY(EISNAM, "EISNAM", "Is a named type file"),
-#endif
-#if defined (EREMOTEIO)
- ENTRY(EREMOTEIO, "EREMOTEIO", "Remote I/O error"),
-#endif
- ENTRY(0, NULL, NULL)
-};
-
-/* Translation table allocated and initialized at runtime. Indexed by the
- errno value to find the equivalent symbolic value. */
-
-static char **error_names;
-static int num_error_names = 0;
-
-/* Translation table allocated and initialized at runtime, if it does not
- already exist in the host environment. Indexed by the errno value to find
- the descriptive string.
-
- We don't export it for use in other modules because even though it has the
- same name, it differs from other implementations in that it is dynamically
- initialized rather than statically initialized. */
-
-#ifdef NEED_sys_errlist
-
-static int sys_nerr;
-static char **sys_errlist;
-
-#else
-
-extern int sys_nerr;
-extern char *sys_errlist[];
-
-#endif
-
-
-/*
-
-NAME
-
- init_error_tables -- initialize the name and message tables
-
-SYNOPSIS
-
- static void init_error_tables ();
-
-DESCRIPTION
-
- Using the error_table, which is initialized at compile time, generate
- the error_names and the sys_errlist (if needed) tables, which are
- indexed at runtime by a specific errno value.
-
-BUGS
-
- The initialization of the tables may fail under low memory conditions,
- in which case we don't do anything particularly useful, but we don't
- bomb either. Who knows, it might succeed at a later point if we free
- some memory in the meantime. In any case, the other routines know
- how to deal with lack of a table after trying to initialize it. This
- may or may not be considered to be a bug, that we don't specifically
- warn about this particular failure mode.
-
-*/
-
-static void
-init_error_tables ()
-{
- const struct error_info *eip;
- int nbytes;
-
- /* If we haven't already scanned the error_table once to find the maximum
- errno value, then go find it now. */
-
- if (num_error_names == 0)
- {
- for (eip = error_table; eip -> name != NULL; eip++)
- {
- if (eip -> value >= num_error_names)
- {
- num_error_names = eip -> value + 1;
- }
- }
- }
-
- /* Now attempt to allocate the error_names table, zero it out, and then
- initialize it from the statically initialized error_table. */
-
- if (error_names == NULL)
- {
- nbytes = num_error_names * sizeof (char *);
- if ((error_names = (char **) malloc (nbytes)) != NULL)
- {
- memset (error_names, 0, nbytes);
- for (eip = error_table; eip -> name != NULL; eip++)
- {
- error_names[eip -> value] = eip -> name;
- }
- }
- }
-
-#ifdef NEED_sys_errlist
-
- /* Now attempt to allocate the sys_errlist table, zero it out, and then
- initialize it from the statically initialized error_table. */
-
- if (sys_errlist == NULL)
- {
- nbytes = num_error_names * sizeof (char *);
- if ((sys_errlist = (char **) malloc (nbytes)) != NULL)
- {
- memset (sys_errlist, 0, nbytes);
- sys_nerr = num_error_names;
- for (eip = error_table; eip -> name != NULL; eip++)
- {
- sys_errlist[eip -> value] = eip -> msg;
- }
- }
- }
-
-#endif
-
-}
-
-/*
-
-NAME
-
- errno_max -- return the max errno value
-
-SYNOPSIS
-
- int errno_max ();
-
-DESCRIPTION
-
- Returns the maximum errno value for which a corresponding symbolic
- name or message is available. Note that in the case where
- we use the sys_errlist supplied by the system, it is possible for
- there to be more symbolic names than messages, or vice versa.
- In fact, the manual page for perror(3C) explicitly warns that one
- should check the size of the table (sys_nerr) before indexing it,
- since new error codes may be added to the system before they are
- added to the table. Thus sys_nerr might be smaller than value
- implied by the largest errno value defined in <errno.h>.
-
- We return the maximum value that can be used to obtain a meaningful
- symbolic name or message.
-
-*/
-
-int
-errno_max ()
-{
- int maxsize;
-
- if (error_names == NULL)
- {
- init_error_tables ();
- }
- maxsize = MAX (sys_nerr, num_error_names);
- return (maxsize - 1);
-}
-
-/*
-
-NAME
-
- strerror -- map an error number to an error message string
-
-SYNOPSIS
-
- char *strerror (int errnoval)
-
-DESCRIPTION
-
- Maps an errno number to an error message string, the contents of
- which are implementation defined. On systems which have the external
- variables sys_nerr and sys_errlist, these strings will be the same
- as the ones used by perror().
-
- If the supplied error number is within the valid range of indices
- for the sys_errlist, but no message is available for the particular
- error number, then returns the string "Error NUM", where NUM is the
- error number.
-
- If the supplied error number is not a valid index into sys_errlist,
- returns NULL.
-
- The returned string is only guaranteed to be valid only until the
- next call to strerror.
-
-*/
-
-char *
-strerror (errnoval)
- int errnoval;
-{
- char *msg;
- static char buf[32];
-
-#ifdef NEED_sys_errlist
-
- if (error_names == NULL)
- {
- init_error_tables ();
- }
-
-#endif
-
- if ((errnoval < 0) || (errnoval >= sys_nerr))
- {
- /* Out of range, just return NULL */
- msg = NULL;
- }
- else if ((sys_errlist == NULL) || (sys_errlist[errnoval] == NULL))
- {
- /* In range, but no sys_errlist or no entry at this index. */
- sprintf (buf, "Error %d", errnoval);
- msg = buf;
- }
- else
- {
- /* In range, and a valid message. Just return the message. */
- msg = sys_errlist[errnoval];
- }
-
- return (msg);
-}
-
-
-
-/*
-
-NAME
-
- strerrno -- map an error number to a symbolic name string
-
-SYNOPSIS
-
- char *strerrno (int errnoval)
-
-DESCRIPTION
-
- Given an error number returned from a system call (typically
- returned in errno), returns a pointer to a string containing the
- symbolic name of that error number, as found in <errno.h>.
-
- If the supplied error number is within the valid range of indices
- for symbolic names, but no name is available for the particular
- error number, then returns the string "Error NUM", where NUM is
- the error number.
-
- If the supplied error number is not within the range of valid
- indices, then returns NULL.
-
-BUGS
-
- The contents of the location pointed to are only guaranteed to be
- valid until the next call to strerrno.
-
-*/
-
-char *
-strerrno (errnoval)
- int errnoval;
-{
- char *name;
- static char buf[32];
-
- if (error_names == NULL)
- {
- init_error_tables ();
- }
-
- if ((errnoval < 0) || (errnoval >= num_error_names))
- {
- /* Out of range, just return NULL */
- name = NULL;
- }
- else if ((error_names == NULL) || (error_names[errnoval] == NULL))
- {
- /* In range, but no error_names or no entry at this index. */
- sprintf (buf, "Error %d", errnoval);
- name = buf;
- }
- else
- {
- /* In range, and a valid name. Just return the name. */
- name = error_names[errnoval];
- }
-
- return (name);
-}
-
-/*
-
-NAME
-
- strtoerrno -- map a symbolic errno name to a numeric value
-
-SYNOPSIS
-
- int strtoerrno (char *name)
-
-DESCRIPTION
-
- Given the symbolic name of a error number, map it to an errno value.
- If no translation is found, returns 0.
-
-*/
-
-int
-strtoerrno (name)
- char *name;
-{
- int errnoval = 0;
-
- if (name != NULL)
- {
- if (error_names == NULL)
- {
- init_error_tables ();
- }
- for (errnoval = 0; errnoval < num_error_names; errnoval++)
- {
- if ((error_names[errnoval] != NULL) &&
- (strcmp (name, error_names[errnoval]) == 0))
- {
- break;
- }
- }
- if (errnoval == num_error_names)
- {
- errnoval = 0;
- }
- }
- return (errnoval);
-}
-
-
-/* A simple little main that does nothing but print all the errno translations
- if MAIN is defined and this file is compiled and linked. */
-
-#ifdef MAIN
-
-main ()
-{
- int errn;
- int errnmax;
- char *name;
- char *msg;
- char *strerrno ();
- char *strerror ();
-
- errnmax = errno_max ();
- printf ("%d entries in names table.\n", num_error_names);
- printf ("%d entries in messages table.\n", sys_nerr);
- printf ("%d is max useful index.\n", errnmax);
-
- /* Keep printing values until we get to the end of *both* tables, not
- *either* table. Note that knowing the maximum useful index does *not*
- relieve us of the responsibility of testing the return pointer for
- NULL. */
-
- for (errn = 0; errn <= errnmax; errn++)
- {
- name = strerrno (errn);
- name = (name == NULL) ? "<NULL>" : name;
- msg = strerror (errn);
- msg = (msg == NULL) ? "<NULL>" : msg;
- printf ("%-4d%-18s%s\n", errn, name, msg);
- }
-}
-
-#endif
diff --git a/gnu/usr.bin/cvs/lib/strippath.c b/gnu/usr.bin/cvs/lib/strippath.c
deleted file mode 100644
index 39687f92b804..000000000000
--- a/gnu/usr.bin/cvs/lib/strippath.c
+++ /dev/null
@@ -1,80 +0,0 @@
-/* strippath.c -- remove unnecessary components from a path specifier
- Copyright (C) 1992 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#if STDC_HEADERS || HAVE_STRING_H
-#include <string.h>
-/* An ANSI string.h and pre-ANSI memory.h might conflict. */
-#if !STDC_HEADERS && HAVE_MEMORY_H
-#include <memory.h>
-#endif /* not STDC_HEADERS and HAVE_MEMORY_H */
-#else /* not STDC_HJEADERS and not HAVE_STRING_H */
-#include <strings.h>
-/* memory.h and strings.h conflict on some systems. */
-#endif /* not STDC_HEADERS and not HAVE_STRING_H */
-
-#include <stdio.h>
-
-#if __STDC__
-static void remove_component(char *beginc, char *endc);
-void strip_trailing_slashes(char *path);
-#else
-static void remove_component();
-void strip_trailing_slashes();
-#endif /* __STDC__ */
-
-/* Remove unnecessary components from PATH. */
-
-void
-strip_path (path)
- char *path;
-{
- int stripped = 0;
- char *cp, *slash;
-
- for (cp = path; (slash = strchr(cp, '/')) != NULL; cp = slash)
- {
- *slash = '\0';
- if ((!*cp && (cp != path || stripped)) ||
- strcmp(cp, ".") == 0 || strcmp(cp, "/") == 0)
- {
- stripped = 1;
- remove_component(cp, slash);
- slash = cp;
- }
- else
- {
- *slash++ = '/';
- }
- }
- strip_trailing_slashes(path);
-}
-
-/* Remove the component delimited by BEGINC and ENDC from the path */
-
-static void
-remove_component (beginc, endc)
- char *beginc;
- char *endc;
-{
- for (endc++; *endc; endc++)
- *beginc++ = *endc;
- *beginc = '\0';
-}
diff --git a/gnu/usr.bin/cvs/lib/stripslash.c b/gnu/usr.bin/cvs/lib/stripslash.c
deleted file mode 100644
index 265950e80f3a..000000000000
--- a/gnu/usr.bin/cvs/lib/stripslash.c
+++ /dev/null
@@ -1,44 +0,0 @@
-/* stripslash.c -- remove trailing slashes from a string
- Copyright (C) 1990 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#if STDC_HEADERS || HAVE_STRING_H
-#include <string.h>
-/* An ANSI string.h and pre-ANSI memory.h might conflict. */
-#if !STDC_HEADERS && HAVE_MEMORY_H
-#include <memory.h>
-#endif /* not STDC_HEADERS and HAVE_MEMORY_H */
-#else /* not STDC_HJEADERS and not HAVE_STRING_H */
-#include <strings.h>
-/* memory.h and strings.h conflict on some systems. */
-#endif /* not STDC_HEADERS and not HAVE_STRING_H */
-
-/* Remove trailing slashes from PATH. */
-
-void
-strip_trailing_slashes (path)
- char *path;
-{
- int last;
-
- last = strlen (path) - 1;
- while (last > 0 && path[last] == '/')
- path[last--] = '\0';
-}
diff --git a/gnu/usr.bin/cvs/lib/subr.c b/gnu/usr.bin/cvs/lib/subr.c
deleted file mode 100644
index 228581c5b1e0..000000000000
--- a/gnu/usr.bin/cvs/lib/subr.c
+++ /dev/null
@@ -1,322 +0,0 @@
-/*
- * Copyright (c) 1992, Brian Berliner and Jeff Polk
- * Copyright (c) 1989-1992, Brian Berliner
- *
- * You may distribute under the terms of the GNU General Public License as
- * specified in the README file that comes with the CVS 1.4 kit.
- *
- * Various useful functions for the CVS support code.
- */
-
-#include "cvs.h"
-
-#ifndef lint
-static const char rcsid[] = "$CVSid: @(#)subr.c 1.64 94/10/07 $";
-USE(rcsid);
-#endif
-
-extern char *getlogin ();
-
-/*
- * malloc some data and die if it fails
- */
-char *
-xmalloc (bytes)
- size_t bytes;
-{
- char *cp;
-
- /* Parts of CVS try to xmalloc zero bytes and then free it. Some
- systems have a malloc which returns NULL for zero byte
- allocations but a free which can't handle NULL, so compensate. */
- if (bytes == 0)
- bytes = 1;
-
- cp = malloc (bytes);
- if (cp == NULL)
- error (1, 0, "can not allocate %lu bytes", (unsigned long) bytes);
- return (cp);
-}
-
-/*
- * realloc data and die if it fails [I've always wanted to have "realloc" do
- * a "malloc" if the argument is NULL, but you can't depend on it. Here, I
- * can *force* it.
- */
-char *
-xrealloc (ptr, bytes)
- char *ptr;
- size_t bytes;
-{
- char *cp;
-
- if (!ptr)
- cp = malloc (bytes);
- else
- cp = realloc (ptr, bytes);
-
- if (cp == NULL)
- error (1, 0, "can not reallocate %lu bytes", (unsigned long) bytes);
- return (cp);
-}
-
-/*
- * Duplicate a string, calling xmalloc to allocate some dynamic space
- */
-char *
-xstrdup (str)
- const char *str;
-{
- char *s;
-
- if (str == NULL)
- return ((char *) NULL);
- s = xmalloc (strlen (str) + 1);
- (void) strcpy (s, str);
- return (s);
-}
-
-/* Remove trailing newlines from STRING, destructively. */
-void
-strip_trailing_newlines (str)
- char *str;
-{
- int len;
- len = strlen (str) - 1;
-
- while (str[len] == '\n')
- str[len--] = '\0';
-}
-
-/*
- * Recover the space allocated by Find_Names() and line2argv()
- */
-void
-free_names (pargc, argv)
- int *pargc;
- char **argv;
-{
- register int i;
-
- for (i = 0; i < *pargc; i++)
- { /* only do through *pargc */
- free (argv[i]);
- }
- *pargc = 0; /* and set it to zero when done */
-}
-
-/*
- * Convert a line into argc/argv components and return the result in the
- * arguments as passed. Use free_names() to return the memory allocated here
- * back to the free pool.
- */
-void
-line2argv (pargc, argv, line)
- int *pargc;
- char **argv;
- char *line;
-{
- char *cp;
-
- *pargc = 0;
- for (cp = strtok (line, " \t"); cp; cp = strtok ((char *) NULL, " \t"))
- {
- argv[*pargc] = xstrdup (cp);
- (*pargc)++;
- }
-}
-
-/*
- * Returns the number of dots ('.') found in an RCS revision number
- */
-int
-numdots (s)
- const char *s;
-{
- int dots = 0;
-
- for (; *s; s++)
- {
- if (*s == '.')
- dots++;
- }
- return (dots);
-}
-
-/*
- * Get the caller's login from his uid. If the real uid is "root" try LOGNAME
- * USER or getlogin(). If getlogin() and getpwuid() both fail, return
- * the uid as a string.
- */
-char *
-getcaller ()
-{
- static char uidname[20];
- struct passwd *pw;
- char *name;
- uid_t uid;
-
- uid = getuid ();
- if (uid == (uid_t) 0)
- {
- /* super-user; try getlogin() to distinguish */
- if (((name = getlogin ()) || (name = getenv("LOGNAME")) ||
- (name = getenv("USER"))) && *name)
- return (name);
- }
- if ((pw = (struct passwd *) getpwuid (uid)) == NULL)
- {
- (void) sprintf (uidname, "uid%lu", (unsigned long) uid);
- return (uidname);
- }
- return (pw->pw_name);
-}
-
-#ifdef lint
-#ifndef __GNUC__
-/* ARGSUSED */
-time_t
-get_date (date, now)
- char *date;
- struct timeb *now;
-{
- time_t foo = 0;
-
- return (foo);
-}
-#endif
-#endif
-
-/* Given two revisions, find their greatest common ancestor. If the
- two input revisions exist, then rcs guarantees that the gca will
- exist. */
-
-char *
-gca (rev1, rev2)
- char *rev1;
- char *rev2;
-{
- int dots;
- char gca[PATH_MAX];
- char *p[2];
- int j[2];
-
- if (rev1 == NULL || rev2 == NULL)
- {
- error (0, 0, "sanity failure in gca");
- abort();
- }
-
- /* walk the strings, reading the common parts. */
- gca[0] = '\0';
- p[0] = rev1;
- p[1] = rev2;
- do
- {
- int i;
- char c[2];
- char *s[2];
-
- for (i = 0; i < 2; ++i)
- {
- /* swap out the dot */
- s[i] = strchr (p[i], '.');
- if (s[i] != NULL) {
- c[i] = *s[i];
- }
-
- /* read an int */
- j[i] = atoi (p[i]);
-
- /* swap back the dot... */
- if (s[i] != NULL) {
- *s[i] = c[i];
- p[i] = s[i] + 1;
- }
- else
- {
- /* or mark us at the end */
- p[i] = NULL;
- }
-
- }
-
- /* use the lowest. */
- (void) sprintf (gca + strlen (gca), "%d.",
- j[0] < j[1] ? j[0] : j[1]);
-
- } while (j[0] == j[1]
- && p[0] != NULL
- && p[1] != NULL);
-
- /* back up over that last dot. */
- gca[strlen(gca) - 1] = '\0';
-
- /* numbers differ, or we ran out of strings. we're done with the
- common parts. */
-
- dots = numdots (gca);
- if (dots == 0)
- {
- /* revisions differ in trunk major number. */
-
- char *q;
- char *s;
-
- s = (j[0] < j[1]) ? p[0] : p[1];
-
- if (s == NULL)
- {
- /* we only got one number. this is strange. */
- error (0, 0, "bad revisions %s or %s", rev1, rev2);
- abort();
- }
- else
- {
- /* we have a minor number. use it. */
- q = gca + strlen (gca);
-
- *q++ = '.';
- for ( ; *s != '.' && *s != '\0'; )
- *q++ = *s++;
-
- *q = '\0';
- }
- }
- else if ((dots & 1) == 0)
- {
- /* if we have an even number of dots, then we have a branch.
- remove the last number in order to make it a revision. */
-
- char *s;
-
- s = strrchr(gca, '.');
- *s = '\0';
- }
-
- return (xstrdup (gca));
-}
-
-/*
- * Sanity checks and any required fix-up on message passed to RCS via '-m'.
- * RCS 5.7 requires that a non-total-whitespace, non-null message be provided
- * with '-m'.
- */
-char *
-make_message_rcslegal (message)
- char *message;
-{
- if ((message == NULL) || (*message == '\0') || isspace (*message))
- {
- char *t;
-
- if (message)
- for (t = message; *t; t++)
- if (!isspace (*t))
- return message;
-
- return "*** empty log message ***\n";
- }
-
- return message;
-}
diff --git a/gnu/usr.bin/cvs/lib/system.h b/gnu/usr.bin/cvs/lib/system.h
deleted file mode 100644
index 20539de772d1..000000000000
--- a/gnu/usr.bin/cvs/lib/system.h
+++ /dev/null
@@ -1,496 +0,0 @@
-/* system-dependent definitions for CVS.
- Copyright (C) 1989-1992 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
-
-/* $CVSid: @(#)system.h 1.18 94/09/25 $ */
-
-#ifdef __GNUC__
-#ifndef alloca
-#define alloca __builtin_alloca
-#endif
-#else
-#ifdef HAVE_ALLOCA_H
-#include <alloca.h>
-#else
-#ifdef _AIX
-/* AIX alloca decl has to be the first thing in the file, bletch! */
- #pragma alloca
-#else /* not _AIX */
-#ifdef ALLOCA_IN_STDLIB
- /* then we need do nothing */
-#else
-char *alloca ();
-#endif /* not ALLOCA_IN_STDLIB */
-#endif /* not _AIX */
-#endif /* not HAVE_ALLOCA_H */
-#endif /* not __GNUS__ */
-
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#ifdef STAT_MACROS_BROKEN
-#undef S_ISBLK
-#undef S_ISCHR
-#undef S_ISDIR
-#undef S_ISREG
-#undef S_ISFIFO
-#undef S_ISLNK
-#undef S_ISSOCK
-#undef S_ISMPB
-#undef S_ISMPC
-#undef S_ISNWK
-#endif
-
-/* Not all systems have S_IFMT, but we probably want to use it if we
- do. See ChangeLog for a more detailed discussion. */
-
-#if !defined(S_ISBLK) && defined(S_IFBLK)
-# if defined(S_IFMT)
-# define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK)
-# else
-# define S_ISBLK(m) ((m) & S_IFBLK)
-# endif
-#endif
-
-#if !defined(S_ISCHR) && defined(S_IFCHR)
-# if defined(S_IFMT)
-# define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR)
-# else
-# define S_ISCHR(m) ((m) & S_IFCHR)
-# endif
-#endif
-
-#if !defined(S_ISDIR) && defined(S_IFDIR)
-# if defined(S_IFMT)
-# define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
-# else
-# define S_ISDIR(m) ((m) & S_IFDIR)
-# endif
-#endif
-
-#if !defined(S_ISREG) && defined(S_IFREG)
-# if defined(S_IFMT)
-# define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
-# else
-# define S_ISREG(m) ((m) & S_IFREG)
-# endif
-#endif
-
-#if !defined(S_ISFIFO) && defined(S_IFIFO)
-# if defined(S_IFMT)
-# define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO)
-# else
-# define S_ISFIFO(m) ((m) & S_IFIFO)
-# endif
-#endif
-
-#if !defined(S_ISLNK) && defined(S_IFLNK)
-# if defined(S_IFMT)
-# define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
-# else
-# define S_ISLNK(m) ((m) & S_IFLNK)
-# endif
-#endif
-
-#if !defined(S_ISSOCK) && defined(S_IFSOCK)
-# if defined(S_IFMT)
-# define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK)
-# else
-# define S_ISSOCK(m) ((m) & S_IFSOCK)
-# endif
-#endif
-
-#if !defined(S_ISMPB) && defined(S_IFMPB) /* V7 */
-# if defined(S_IFMT)
-# define S_ISMPB(m) (((m) & S_IFMT) == S_IFMPB)
-# define S_ISMPC(m) (((m) & S_IFMT) == S_IFMPC)
-# else
-# define S_ISMPB(m) ((m) & S_IFMPB)
-# define S_ISMPC(m) ((m) & S_IFMPC)
-# endif
-#endif
-
-#if !defined(S_ISNWK) && defined(S_IFNWK) /* HP/UX */
-# if defined(S_IFMT)
-# define S_ISNWK(m) (((m) & S_IFMT) == S_IFNWK)
-# else
-# define S_ISNWK(m) ((m) & S_IFNWK)
-# endif
-#endif
-
-#if !defined(HAVE_MKFIFO)
-#define mkfifo(path, mode) (mknod ((path), (mode) | S_IFIFO, 0))
-#endif
-
-#ifdef NEED_DECOY_PERMISSIONS /* OS/2, really */
-
-#define S_IRUSR S_IREAD
-#define S_IWUSR S_IWRITE
-#define S_IXUSR S_IEXEC
-#define S_IRWXU (S_IRUSR | S_IWUSR | S_IXUSR)
-#define S_IRGRP S_IREAD
-#define S_IWGRP S_IWRITE
-#define S_IXGRP S_IEXEC
-#define S_IRWXG (S_IRGRP | S_IWGRP | S_IXGRP)
-#define S_IROTH S_IREAD
-#define S_IWOTH S_IWRITE
-#define S_IXOTH S_IEXEC
-#define S_IRWXO (S_IROTH | S_IWOTH | S_IXOTH)
-
-#else /* ! NEED_DECOY_PERMISSIONS */
-
-#ifndef S_IRUSR
-#define S_IRUSR 0400
-#define S_IWUSR 0200
-#define S_IXUSR 0100
-/* Read, write, and execute by owner. */
-#define S_IRWXU (S_IRUSR|S_IWUSR|S_IXUSR)
-
-#define S_IRGRP (S_IRUSR >> 3) /* Read by group. */
-#define S_IWGRP (S_IWUSR >> 3) /* Write by group. */
-#define S_IXGRP (S_IXUSR >> 3) /* Execute by group. */
-/* Read, write, and execute by group. */
-#define S_IRWXG (S_IRWXU >> 3)
-
-#define S_IROTH (S_IRGRP >> 3) /* Read by others. */
-#define S_IWOTH (S_IWGRP >> 3) /* Write by others. */
-#define S_IXOTH (S_IXGRP >> 3) /* Execute by others. */
-/* Read, write, and execute by others. */
-#define S_IRWXO (S_IRWXG >> 3)
-#endif /* !def S_IRUSR */
-#endif /* NEED_DECOY_PERMISSIONS */
-
-#if defined(POSIX) || defined(HAVE_UNISTD_H)
-#include <unistd.h>
-#include <limits.h>
-#else
-off_t lseek ();
-#endif
-
-#if TIME_WITH_SYS_TIME
-# include <sys/time.h>
-# include <time.h>
-#else
-# if HAVE_SYS_TIME_H
-# include <sys/time.h>
-# else
-# include <time.h>
-# endif
-#endif
-
-#ifdef HAVE_IO_H
-#include <io.h>
-#endif
-
-#ifdef HAVE_DIRECT_H
-#include <direct.h>
-#endif
-
-#ifdef timezone
-#undef timezone /* needed for sgi */
-#endif
-
-#ifdef HAVE_SYS_TIMEB_H
-#include <sys/timeb.h>
-#else
-struct timeb {
- time_t time; /* Seconds since the epoch */
- unsigned short millitm; /* Field not used */
- short timezone;
- short dstflag; /* Field not used */
-};
-#endif
-
-#if !defined(HAVE_FTIME) && !defined(HAVE_TIMEZONE)
-#if !defined(timezone)
-extern long timezone;
-#endif
-#endif
-
-
-/*
-** MAXPATHLEN and PATH_MAX
-**
-** On most systems MAXPATHLEN is defined in sys/param.h to be 1024. Of
-** those that this is not true, again most define PATH_MAX in limits.h
-** or sys/limits.h which usually gets included by limits.h. On the few
-** remaining systems that neither statement is true, _POSIX_PATH_MAX
-** is defined.
-**
-** So:
-** 1. If PATH_MAX is defined just use it.
-** 2. If MAXPATHLEN is defined but not PATH_MAX, then define
-** PATH_MAX in terms of MAXPATHLEN.
-** 3. If neither is defined, include limits.h and check for
-** PATH_MAX again.
-** 3.1 If we now have PATHSIZE, define PATH_MAX in terms of that.
-** and ignore the rest. Since _POSIX_PATH_MAX (checked for
-** next) is the *most* restrictive (smallest) value, if we
-** trust _POSIX_PATH_MAX, several of our buffers are too small.
-** 4. If PATH_MAX is still not defined but _POSIX_PATH_MAX is,
-** then define PATH_MAX in terms of _POSIX_PATH_MAX.
-** 5. And if even _POSIX_PATH_MAX doesn't exist just put in
-** a reasonable value.
-** *. All in all, this is an excellent argument for using pathconf()
-** when at all possible. Or better yet, dynamically allocate
-** our buffers and use getcwd() not getwd().
-**
-** This works on:
-** Sun Sparc 10 SunOS 4.1.3 & Solaris 1.2
-** HP 9000/700 HP/UX 8.07 & HP/UX 9.01
-** Tektronix XD88/10 UTekV 3.2e
-** IBM RS6000 AIX 3.2
-** Dec Alpha OSF 1 ????
-** Intel 386 BSDI BSD/386
-** Intel 386 SCO OpenServer Release 5
-** Apollo Domain 10.4
-** NEC SVR4
-*/
-
-/* On MOST systems this will get you MAXPATHLEN.
- Windows NT doesn't have this file, tho. */
-#ifdef HAVE_SYS_PARAM_H
-#include <sys/param.h>
-#endif
-
-#ifndef PATH_MAX
-# ifdef MAXPATHLEN
-# define PATH_MAX MAXPATHLEN
-# else
-# include <limits.h>
-# ifndef PATH_MAX
-# ifdef PATHSIZE
-# define PATH_MAX PATHSIZE
-# else /* no PATHSIZE */
-# ifdef _POSIX_PATH_MAX
-# define PATH_MAX _POSIX_PATH_MAX
-# else
-# define PATH_MAX 1024
-# endif /* no _POSIX_PATH_MAX */
-# endif /* no PATHSIZE */
-# endif /* no PATH_MAX */
-# endif /* MAXPATHLEN */
-#endif /* PATH_MAX */
-
-
-/* The NeXT (without _POSIX_SOURCE, which we don't want) has a utime.h
- which doesn't define anything. It would be cleaner to have configure
- check for struct utimbuf, but for now I'm checking NeXT here (so I don't
- have to debug the configure check across all the machines). */
-#if defined (HAVE_UTIME_H) && !defined (NeXT)
-#include <utime.h>
-#elif defined (HAVE_SYS_UTIME_H)
-# include <sys/utime.h>
-#else
-#ifndef ALTOS
-struct utimbuf
-{
- long actime;
- long modtime;
-};
-#endif
-int utime ();
-#endif
-
-#if STDC_HEADERS || HAVE_STRING_H
-#include <string.h>
-/* An ANSI string.h and pre-ANSI memory.h might conflict. */
-#if !STDC_HEADERS && HAVE_MEMORY_H
-#include <memory.h>
-#endif /* not STDC_HEADERS and HAVE_MEMORY_H */
-
-#ifndef index
-#define index strchr
-#endif /* index */
-
-#ifndef rindex
-#define rindex strrchr
-#endif /* rindex */
-
-#ifndef bcmp
-#define bcmp(s1, s2, n) memcmp ((s1), (s2), (n))
-#endif /* bcmp */
-
-#ifndef bzero
-#define bzero(s, n) memset ((s), 0, (n))
-#endif /* bzero */
-
-#else /* not STDC_HEADERS and not HAVE_STRING_H */
-#include <strings.h>
-/* memory.h and strings.h conflict on some systems. */
-#endif /* not STDC_HEADERS and not HAVE_STRING_H */
-
-#include <errno.h>
-
-/* Not all systems set the same error code on a non-existent-file
- error. This tries to ask the question somewhat portably.
- On systems that don't have ENOTEXIST, this should behave just like
- x == ENOENT. "x" is probably errno, of course. */
-
-#ifdef ENOTEXIST
-# ifdef EOS2ERR
-# define existence_error(x) \
- (((x) == ENOTEXIST) || ((x) == ENOENT) || ((x) == EOS2ERR))
-# else
-# define existence_error(x) \
- (((x) == ENOTEXIST) || ((x) == ENOENT))
-# endif
-#else
-# define existence_error(x) ((x) == ENOENT)
-#endif
-
-
-#ifdef STDC_HEADERS
-#include <stdlib.h>
-#else
-char *getenv ();
-char *malloc ();
-char *realloc ();
-char *calloc ();
-extern int errno;
-#endif
-
-#if defined(USG) || defined(POSIX)
-char *getcwd ();
-#else
-char *getwd ();
-#endif
-
-/* check for POSIX signals */
-#if defined(HAVE_SIGACTION) && defined(HAVE_SIGPROCMASK)
-# define POSIX_SIGNALS
-#endif
-
-/* MINIX 1.6 doesn't properly support sigaction */
-#if defined(_MINIX)
-# undef POSIX_SIGNALS
-#endif
-
-/* If !POSIX, try for BSD.. Reason: 4.4BSD implements these as wrappers */
-#if !defined(POSIX_SIGNALS)
-# if defined(HAVE_SIGVEC) && defined(HAVE_SIGSETMASK) && defined(HAVE_SIGBLOCK)
-# define BSD_SIGNALS
-# endif
-#endif
-
-/* Under OS/2, this must be included _after_ stdio.h; that's why we do
- it here. */
-#ifdef USE_OWN_TCPIP_H
-#include "tcpip.h"
-#endif
-
-#ifdef HAVE_FCNTL_H
-#include <fcntl.h>
-#else
-#include <sys/file.h>
-#endif
-
-#ifndef SEEK_SET
-#define SEEK_SET 0
-#define SEEK_CUR 1
-#define SEEK_END 2
-#endif
-
-#ifndef F_OK
-#define F_OK 0
-#define X_OK 1
-#define W_OK 2
-#define R_OK 4
-#endif
-
-#if HAVE_DIRENT_H
-# include <dirent.h>
-# define NAMLEN(dirent) strlen((dirent)->d_name)
-#else
-# define dirent direct
-# define NAMLEN(dirent) (dirent)->d_namlen
-# if HAVE_SYS_NDIR_H
-# include <sys/ndir.h>
-# endif
-# if HAVE_SYS_DIR_H
-# include <sys/dir.h>
-# endif
-# if HAVE_NDIR_H
-# include <ndir.h>
-# endif
-#endif
-
-/* Convert B 512-byte blocks to kilobytes if K is nonzero,
- otherwise return it unchanged. */
-#define convert_blocks(b, k) ((k) ? ((b) + 1) / 2 : (b))
-
-#ifndef S_ISLNK
-#define lstat stat
-#endif
-
-/*
- * Some UNIX distributions don't include these in their stat.h Defined here
- * because "config.h" is always included last.
- */
-#ifndef S_IWRITE
-#define S_IWRITE 0000200 /* write permission, owner */
-#endif
-#ifndef S_IWGRP
-#define S_IWGRP 0000020 /* write permission, grougroup */
-#endif
-#ifndef S_IWOTH
-#define S_IWOTH 0000002 /* write permission, other */
-#endif
-
-/* Under MS-DOS and its derivatives (like Windows NT), mkdir takes only one
- argument; permission is handled very differently on those systems than in
- in Unix. So we leave such systems a hook on which they can hang their
- own definitions. */
-#ifndef CVS_MKDIR
-#define CVS_MKDIR mkdir
-#endif
-
-/* Some file systems are case-insensitive. If FOLD_FN_CHAR is
- #defined, it maps the character C onto its "canonical" form. In a
- case-insensitive system, it would map all alphanumeric characters
- to lower case. Under Windows NT, / and \ are both path component
- separators, so FOLD_FN_CHAR would map them both to /. */
-#ifndef FOLD_FN_CHAR
-#define FOLD_FN_CHAR(c) (c)
-#define fnfold(filename) (filename)
-#define fncmp strcmp
-#endif
-
-/* Different file systems have different path component separators.
- For the VMS port we might need to abstract further back than this. */
-#ifndef ISDIRSEP
-#define ISDIRSEP(c) ((c) == '/')
-#endif
-
-
-/* On some systems, lines in text files should be terminated with CRLF,
- not just LF, and the read and write routines do this translation
- for you. LINES_CRLF_TERMINATED is #defined on such systems.
- - OPEN_BINARY is the flag to pass to the open function for
- untranslated I/O.
- - FOPEN_BINARY_READ is the string to pass to fopen to get
- untranslated reading.
- - FOPEN_BINARY_WRITE is the string to pass to fopen to get
- untranslated writing. */
-#if LINES_CRLF_TERMINATED
-#define OPEN_BINARY (O_BINARY)
-#define FOPEN_BINARY_READ ("rb")
-#define FOPEN_BINARY_WRITE ("wb")
-#else
-#define OPEN_BINARY (0)
-#define FOPEN_BINARY_READ ("r")
-#define FOPEN_BINARY_WRITE ("w")
-#endif
diff --git a/gnu/usr.bin/cvs/lib/version.c b/gnu/usr.bin/cvs/lib/version.c
deleted file mode 100644
index 2eb66cd709d5..000000000000
--- a/gnu/usr.bin/cvs/lib/version.c
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (c) 1994 david d `zoo' zuhn
- * Copyright (c) 1994 Free Software Foundation, Inc.
- * Copyright (c) 1992, Brian Berliner and Jeff Polk
- * Copyright (c) 1989-1992, Brian Berliner
- *
- * You may distribute under the terms of the GNU General Public License as
- * specified in the README file that comes with this CVS source distribution.
- *
- * version.c - the CVS version number
- */
-
-#include "cvs.h"
-
-#ifndef lint
-static const char rcsid[] = "$CVSid: @(#)version.c 1.15 94/10/03 $";
-USE(rcsid);
-#endif
-
-char *version_string = "\nConcurrent Versions System (CVS) 1.6.3";
-
-#ifdef CLIENT_SUPPORT
-#ifdef SERVER_SUPPORT
-char *config_string = " (client/server)\n";
-#else
-char *config_string = " (client)\n";
-#endif
-#else
-#ifdef SERVER_SUPPORT
-char *config_string = " (server)\n";
-#else
-char *config_string = "\n";
-#endif
-#endif
diff --git a/gnu/usr.bin/cvs/lib/wait.h b/gnu/usr.bin/cvs/lib/wait.h
deleted file mode 100644
index db60434144aa..000000000000
--- a/gnu/usr.bin/cvs/lib/wait.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/* wait.h -- POSIX macros for evaluating exit statuses
- Copyright (C) 1990 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
-
-#ifdef HAVE_SYS_WAIT_H
-#include <sys/types.h> /* For pid_t. */
-#ifdef HAVE_SYS_RESOURCE_H
-#include <sys/resource.h> /* for rusage */
-#endif
-#include <sys/wait.h>
-#else
-#define WIFSTOPPED(w) (((w) & 0xff) == 0x7f)
-#define WIFSIGNALED(w) (((w) & 0xff) != 0x7f && ((w) & 0xff) != 0)
-#define WIFEXITED(w) (((w) & 0xff) == 0)
-
-#define WSTOPSIG(w) (((w) >> 8) & 0xff)
-#define WTERMSIG(w) ((w) & 0x7f)
-#define WEXITSTATUS(w) (((w) >> 8) & 0xff)
-#endif
diff --git a/gnu/usr.bin/cvs/lib/xgetwd.c b/gnu/usr.bin/cvs/lib/xgetwd.c
deleted file mode 100644
index 8fe4ec18c2ef..000000000000
--- a/gnu/usr.bin/cvs/lib/xgetwd.c
+++ /dev/null
@@ -1,79 +0,0 @@
-/* xgetwd.c -- return current directory with unlimited length
- Copyright (C) 1992 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
-
-/* Derived from xgetcwd.c in e.g. the GNU sh-utils. */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "system.h"
-
-#include <stdio.h>
-#include <errno.h>
-#ifndef errno
-extern int errno;
-#endif
-#include <sys/types.h>
-
-#ifndef HAVE_GETWD
-char *getwd ();
-#define GETWD(buf, max) getwd (buf)
-#else
-char *getcwd ();
-#define GETWD(buf, max) getcwd (buf, max)
-#endif
-
-/* Amount by which to increase buffer size when allocating more space. */
-#define PATH_INCR 32
-
-char *xmalloc ();
-char *xrealloc ();
-
-/* Return the current directory, newly allocated, arbitrarily long.
- Return NULL and set errno on error. */
-
-char *
-xgetwd ()
-{
- char *cwd;
- char *ret;
- unsigned path_max;
-
- errno = 0;
- path_max = (unsigned) PATH_MAX;
- path_max += 2; /* The getcwd docs say to do this. */
-
- cwd = xmalloc (path_max);
-
- errno = 0;
- while ((ret = GETWD (cwd, path_max)) == NULL && errno == ERANGE)
- {
- path_max += PATH_INCR;
- cwd = xrealloc (cwd, path_max);
- errno = 0;
- }
-
- if (ret == NULL)
- {
- int save_errno = errno;
- free (cwd);
- errno = save_errno;
- return NULL;
- }
- return cwd;
-}
diff --git a/gnu/usr.bin/cvs/lib/yesno.c b/gnu/usr.bin/cvs/lib/yesno.c
deleted file mode 100644
index 7014803f4803..000000000000
--- a/gnu/usr.bin/cvs/lib/yesno.c
+++ /dev/null
@@ -1,41 +0,0 @@
-/* yesno.c -- read a yes/no response from stdin
- Copyright (C) 1990 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <stdio.h>
-
-/* Read one line from standard input
- and return nonzero if that line begins with y or Y,
- otherwise return 0. */
-
-int
-yesno ()
-{
- int c;
- int rv;
-
- fflush (stderr);
- c = getchar ();
- rv = (c == 'y') || (c == 'Y');
- while (c != EOF && c != '\n')
- c = getchar ();
-
- return rv;
-}
diff --git a/gnu/usr.bin/cvs/mkmodules/Makefile b/gnu/usr.bin/cvs/mkmodules/Makefile
deleted file mode 100644
index 9f66fdefc97f..000000000000
--- a/gnu/usr.bin/cvs/mkmodules/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
-PROG = mkmodules
-SRCS = mkmodules.c
-
-CFLAGS += -I${.CURDIR}/../cvs -I${.CURDIR}/../lib
-LDADD= -L${.CURDIR}/../lib/obj -lcvs
-
-.include <bsd.prog.mk>
-.include "../../Makefile.inc"
diff --git a/gnu/usr.bin/cvs/mkmodules/mkmodules.1 b/gnu/usr.bin/cvs/mkmodules/mkmodules.1
deleted file mode 100644
index 8196a47f137b..000000000000
--- a/gnu/usr.bin/cvs/mkmodules/mkmodules.1
+++ /dev/null
@@ -1,65 +0,0 @@
-.\"
-.\" $CVSid: @(#)mkmodules.1 1.3 92/01/30 $
-.\"
-.TH MKMODULES 1 "12 October 1991"
-.SH "NAME"
-mkmodules \- Rebuild modules database for CVS
-.SH "SYNOPSIS"
-.B mkmodules
-.I directory
-.SH "DESCRIPTION"
-.B mkmodules
-rebuilds the modules database that
-.BR cvs (1)
-uses.
-The
-.I directory
-specified is expected to contain the
-.BR modules,v " and " loginfo,v
-files.
-.B mkmodules
-carefully checks out the current head revisions of each of these files and
-reuilds the
-.BR ndbm (3)
-format modules database.
-A warning is generated if the modules file contains a duplicate key.
-.SH "FILES"
-.TP
-modules,v
-The modules
-.SM RCS
-file.
-.TP
-modules
-The checked out modules file.
-.TP
-loginfo,v
-The loginfo
-.SM RCS
-file.
-.TP
-loginfo
-The checked out loginfo file.
-.TP
-modules.dir, modules.pag
-The
-.BR ndbm (1)
-format modules database.
-.SH "ENVIRONMENT VARIABLES"
-.TP
-.SM RCSBIN
-Specifies the full pathname where to find
-.SM RCS
-programs, such as
-.BR co (1)
-and
-.BR ci (1).
-If not set, the default is
-.BR /usr/local/bin .
-.SH "SEE ALSO"
-.BR checkin (1),
-.BR co (1),
-.BR cvs (1),
-.BR ndbm (3),
-.BR rcs (1),
-.SH "BUGS"
diff --git a/gnu/usr.bin/cvs/mkmodules/mkmodules.c b/gnu/usr.bin/cvs/mkmodules/mkmodules.c
deleted file mode 100644
index 9b0e7bded00e..000000000000
--- a/gnu/usr.bin/cvs/mkmodules/mkmodules.c
+++ /dev/null
@@ -1,435 +0,0 @@
-/*
- * Copyright (c) 1992, Brian Berliner and Jeff Polk
- * Copyright (c) 1989-1992, Brian Berliner
- *
- * You may distribute under the terms of the GNU General Public License as
- * specified in the README file that comes with the CVS 1.4 kit.
- *
- * mkmodules
- *
- * Re-build the modules database for the CVS system. Accepts one argument,
- * which is the directory that the modules,v file lives in.
- */
-
-#include "cvs.h"
-
-#ifndef lint
-static const char rcsid[] = "$CVSid: @(#)mkmodules.c 1.45 94/09/30 $";
-USE(rcsid);
-#endif
-
-#ifndef DBLKSIZ
-#define DBLKSIZ 4096 /* since GNU ndbm doesn't define it */
-#endif
-
-char *program_name, *command_name;
-
-char *Rcsbin = RCSBIN_DFLT;
-char *CVSroot = CVSROOT_DFLT;
-int noexec = 0; /* Here only to satisfy use in subr.c */
-int trace = 0; /* Here only to satisfy use in subr.c */
-
-static int checkout_file PROTO((char *file, char *temp));
-static void make_tempfile PROTO((char *temp));
-static void mkmodules_usage PROTO((void));
-static void rename_rcsfile PROTO((char *temp, char *real));
-
-#ifndef MY_NDBM
-static void rename_dbmfile PROTO((char *temp));
-static void write_dbmfile PROTO((char *temp));
-#endif /* !MY_NDBM */
-
-
-int
-main (argc, argv)
- int argc;
- char **argv;
-{
- char temp[PATH_MAX];
- char *cp, *last, *fname;
-#ifdef MY_NDBM
- DBM *db;
-#endif
- FILE *fp;
- char line[512];
- static struct _checkout_file {
- char *filename;
- char *errormsg;
- } *fileptr, filelist[] = {
- {CVSROOTADM_LOGINFO,
- "no logging of 'cvs commit' messages is done without a %s file"},
- {CVSROOTADM_RCSINFO,
- "a %s file can be used to configure 'cvs commit' templates"},
- {CVSROOTADM_EDITINFO,
- "a %s file can be used to validate log messages"},
- {CVSROOTADM_COMMITINFO,
- "a %s file can be used to configure 'cvs commit' checking"},
- {CVSROOTADM_TAGINFO,
- "a %s file can be used to configure 'cvs tag' checking"},
- {CVSROOTADM_IGNORE,
- "a %s file can be used to specify files to ignore"},
- {CVSROOTADM_CHECKOUTLIST,
- "a %s file can specify extra CVSROOT files to auto-checkout"},
- {CVSROOTADM_WRAPPER,
- "a %s file can be used to specify files to treat as wrappers"},
- {NULL, NULL}};
-
- /*
- * Just save the last component of the path for error messages
- */
- program_name = last_component (argv[0]);
-
- if (argc != 2)
- mkmodules_usage ();
-
- if ((cp = getenv (RCSBIN_ENV)) != NULL)
- Rcsbin = cp;
-
- /*
- * If Rcsbin is set to something, make sure it is terminated with a slash
- * character. If not, add one.
- */
- if (Rcsbin[0] != '\0')
- {
- int len = strlen (Rcsbin);
- char *rcsbin;
-
- if (Rcsbin[len - 1] != '/')
- {
- rcsbin = Rcsbin;
- Rcsbin = xmalloc (len + 2); /* one for '/', one for NULL */
- (void) strcpy (Rcsbin, rcsbin);
- (void) strcat (Rcsbin, "/");
- }
- }
-
- if (chdir (argv[1]) < 0)
- error (1, errno, "cannot chdir to %s", argv[1]);
-
- /*
- * First, do the work necessary to update the "modules" database.
- */
- make_tempfile (temp);
- switch (checkout_file (CVSROOTADM_MODULES, temp))
- {
-
- case 0: /* everything ok */
-#ifdef MY_NDBM
- /* open it, to generate any duplicate errors */
- if ((db = dbm_open (temp, O_RDONLY, 0666)) != NULL)
- dbm_close (db);
-#else
- write_dbmfile (temp);
- rename_dbmfile (temp);
-#endif
- rename_rcsfile (temp, CVSROOTADM_MODULES);
- break;
-
- case -1: /* fork failed */
- (void) unlink_file (temp);
- exit (1);
- /* NOTREACHED */
-
- default:
- error (0, 0,
- "'cvs checkout' is less functional without a %s file",
- CVSROOTADM_MODULES);
- break;
- } /* switch on checkout_file() */
-
- (void) unlink_file (temp);
-
- /* Checkout the files that need it in CVSROOT dir */
- for (fileptr = filelist; fileptr && fileptr->filename; fileptr++) {
- make_tempfile (temp);
- if (checkout_file (fileptr->filename, temp) == 0)
- rename_rcsfile (temp, fileptr->filename);
-#if 0
- /*
- * If there was some problem other than the file not existing,
- * checkout_file already printed a real error message. If the
- * file does not exist, it is harmless--it probably just means
- * that the repository was created with an old version of CVS
- * which didn't have so many files in CVSROOT.
- */
- else if (fileptr->errormsg)
- error (0, 0, fileptr->errormsg, fileptr->filename);
-#endif
- (void) unlink_file (temp);
- }
-
- /* Use 'fopen' instead of 'open_file' because we want to ignore error */
- fp = fopen (CVSROOTADM_CHECKOUTLIST, "r");
- if (fp)
- {
- /*
- * File format:
- * [<whitespace>]<filename><whitespace><error message><end-of-line>
- *
- * comment lines begin with '#'
- */
- while (fgets (line, sizeof (line), fp) != NULL)
- {
- /* skip lines starting with # */
- if (line[0] == '#')
- continue;
-
- if ((last = strrchr (line, '\n')) != NULL)
- *last = '\0'; /* strip the newline */
-
- /* Skip leading white space. */
- for (fname = line; *fname && isspace(*fname); fname++)
- ;
-
- /* Find end of filename. */
- for (cp = fname; *cp && !isspace(*cp); cp++)
- ;
- *cp = '\0';
-
- make_tempfile (temp);
- if (checkout_file (fname, temp) == 0)
- {
- rename_rcsfile (temp, fname);
- }
- else
- {
- for (cp++; cp < last && *last && isspace(*last); cp++)
- ;
- if (cp < last && *cp)
- error (0, 0, cp, fname);
- }
- }
- (void) fclose (fp);
- }
-
- return (0);
-}
-
-/*
- * Yeah, I know, there are NFS race conditions here.
- */
-static void
-make_tempfile (temp)
- char *temp;
-{
- static int seed = 0;
- int fd;
-
- if (seed == 0)
- seed = getpid ();
- while (1)
- {
- (void) sprintf (temp, "%s%d", BAKPREFIX, seed++);
- if ((fd = open (temp, O_CREAT|O_EXCL|O_RDWR, 0666)) != -1)
- break;
- if (errno != EEXIST)
- error (1, errno, "cannot create temporary file %s", temp);
- }
- if (close(fd) < 0)
- error(1, errno, "cannot close temporary file %s", temp);
-}
-
-static int
-checkout_file (file, temp)
- char *file;
- char *temp;
-{
- char rcs[PATH_MAX];
- int retcode = 0;
-
- (void) sprintf (rcs, "%s%s", file, RCSEXT);
- if (!isfile (rcs))
- return (1);
- run_setup ("%s%s -q -p", Rcsbin, RCS_CO);
- run_arg (rcs);
- if ((retcode = run_exec (RUN_TTY, temp, RUN_TTY, RUN_NORMAL)) != 0)
- {
- error (0, retcode == -1 ? errno : 0, "failed to check out %s file", file);
- }
- return (retcode);
-}
-
-#ifndef MY_NDBM
-
-static void
-write_dbmfile (temp)
- char *temp;
-{
- char line[DBLKSIZ], value[DBLKSIZ];
- FILE *fp;
- DBM *db;
- char *cp, *vp;
- datum key, val;
- int len, cont, err = 0;
-
- fp = open_file (temp, "r");
- if ((db = dbm_open (temp, O_RDWR | O_CREAT | O_TRUNC, 0666)) == NULL)
- error (1, errno, "cannot open dbm file %s for creation", temp);
- for (cont = 0; fgets (line, sizeof (line), fp) != NULL;)
- {
- if ((cp = strrchr (line, '\n')) != NULL)
- *cp = '\0'; /* strip the newline */
-
- /*
- * Add the line to the value, at the end if this is a continuation
- * line; otherwise at the beginning, but only after any trailing
- * backslash is removed.
- */
- vp = value;
- if (cont)
- vp += strlen (value);
-
- /*
- * See if the line we read is a continuation line, and strip the
- * backslash if so.
- */
- len = strlen (line);
- if (len > 0)
- cp = &line[len - 1];
- else
- cp = line;
- if (*cp == '\\')
- {
- cont = 1;
- *cp = '\0';
- }
- else
- {
- cont = 0;
- }
- (void) strcpy (vp, line);
- if (value[0] == '#')
- continue; /* comment line */
- vp = value;
- while (*vp && isspace (*vp))
- vp++;
- if (*vp == '\0')
- continue; /* empty line */
-
- /*
- * If this was not a continuation line, add the entry to the database
- */
- if (!cont)
- {
- key.dptr = vp;
- while (*vp && !isspace (*vp))
- vp++;
- key.dsize = vp - key.dptr;
- *vp++ = '\0'; /* NULL terminate the key */
- while (*vp && isspace (*vp))
- vp++; /* skip whitespace to value */
- if (*vp == '\0')
- {
- error (0, 0, "warning: NULL value for key `%s'", key.dptr);
- continue;
- }
- val.dptr = vp;
- val.dsize = strlen (vp);
- if (dbm_store (db, key, val, DBM_INSERT) == 1)
- {
- error (0, 0, "duplicate key found for `%s'", key.dptr);
- err++;
- }
- }
- }
- dbm_close (db);
- (void) fclose (fp);
- if (err)
- {
- char dotdir[50], dotpag[50], dotdb[50];
-
- (void) sprintf (dotdir, "%s.dir", temp);
- (void) sprintf (dotpag, "%s.pag", temp);
- (void) sprintf (dotdb, "%s.db", temp);
- (void) unlink_file (dotdir);
- (void) unlink_file (dotpag);
- (void) unlink_file (dotdb);
- error (1, 0, "DBM creation failed; correct above errors");
- }
-}
-
-static void
-rename_dbmfile (temp)
- char *temp;
-{
- char newdir[50], newpag[50], newdb[50];
- char dotdir[50], dotpag[50], dotdb[50];
- char bakdir[50], bakpag[50], bakdb[50];
-
- (void) sprintf (dotdir, "%s.dir", CVSROOTADM_MODULES);
- (void) sprintf (dotpag, "%s.pag", CVSROOTADM_MODULES);
- (void) sprintf (dotdb, "%s.db", CVSROOTADM_MODULES);
- (void) sprintf (bakdir, "%s%s.dir", BAKPREFIX, CVSROOTADM_MODULES);
- (void) sprintf (bakpag, "%s%s.pag", BAKPREFIX, CVSROOTADM_MODULES);
- (void) sprintf (bakdb, "%s%s.db", BAKPREFIX, CVSROOTADM_MODULES);
- (void) sprintf (newdir, "%s.dir", temp);
- (void) sprintf (newpag, "%s.pag", temp);
- (void) sprintf (newdb, "%s.db", temp);
-
- (void) chmod (newdir, 0666);
- (void) chmod (newpag, 0666);
- (void) chmod (newdb, 0666);
-
- /* don't mess with me */
- SIG_beginCrSect ();
-
- (void) unlink_file (bakdir); /* rm .#modules.dir .#modules.pag */
- (void) unlink_file (bakpag);
- (void) unlink_file (bakdb);
- (void) rename (dotdir, bakdir); /* mv modules.dir .#modules.dir */
- (void) rename (dotpag, bakpag); /* mv modules.pag .#modules.pag */
- (void) rename (dotdb, bakdb); /* mv modules.db .#modules.db */
- (void) rename (newdir, dotdir); /* mv "temp".dir modules.dir */
- (void) rename (newpag, dotpag); /* mv "temp".pag modules.pag */
- (void) rename (newdb, dotdb); /* mv "temp".db modules.db */
-
- /* OK -- make my day */
- SIG_endCrSect ();
-}
-
-#endif /* !MY_NDBM */
-
-static void
-rename_rcsfile (temp, real)
- char *temp;
- char *real;
-{
- char bak[50];
- struct stat statbuf;
- char rcs[PATH_MAX];
-
- /* Set "x" bits if set in original. */
- (void) sprintf (rcs, "%s%s", real, RCSEXT);
- statbuf.st_mode = 0; /* in case rcs file doesn't exist, but it should... */
- (void) stat (rcs, &statbuf);
-
- if (chmod (temp, 0444 | (statbuf.st_mode & 0111)) < 0)
- error (0, errno, "warning: cannot chmod %s", temp);
- (void) sprintf (bak, "%s%s", BAKPREFIX, real);
- (void) unlink_file (bak); /* rm .#loginfo */
- (void) rename (real, bak); /* mv loginfo .#loginfo */
- (void) rename (temp, real); /* mv "temp" loginfo */
-}
-
-/*
- * For error() only
- */
-void
-Lock_Cleanup ()
-{
-}
-
-int server_active = 0;
-
-void
-server_cleanup (sig)
- int sig;
-{
-}
-
-static void
-mkmodules_usage ()
-{
- (void) fprintf (stderr, "Usage: %s modules-directory\n", program_name);
- exit (1);
-}