This commit was generated by cvs2svn to compensate for changes in r54427,

which included commits to RCS files with non-trunk default branches.
This commit is contained in:
Peter Wemm 1999-12-11 12:24:21 +00:00
commit 6687a375a9
91 changed files with 10389 additions and 2102 deletions

View File

@ -95,8 +95,6 @@ file's description.
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.
* Defining RELATIVE_REPOS is said to not work with client/server CVS.
* From: "Charles M. Hannum" <mycroft@ai.mit.edu>
To: info-cvs@prep.ai.mit.edu
Subject: Still one more bug

View File

@ -1,9 +1,11 @@
[I have snipped the snail mail address of the FSF because it has
changed in the past and is likely to change again. The current
address should be at http://www.gnu.org/]
GNU GENERAL PUBLIC LICENSE
Version 1, February 1989
Copyright (C) 1989 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.
@ -217,7 +219,7 @@ the exclusion of warranty; and each file should have at least the
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.
Foundation, Inc.
Also add information on how to contact you by electronic and paper mail.

View File

@ -1,8 +1,11 @@
[I have snipped the snail mail address of the FSF because it has
changed in the past and is likely to change again. The current
address should be at http://www.gnu.org/]
GNU LIBRARY GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 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.
@ -464,7 +467,7 @@ convey the exclusion of warranty; and each file should have at least the
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
Software Foundation, Inc.
Also add information on how to contact you by electronic and paper mail.

View File

@ -1,3 +1,203 @@
1999-07-12 Larry Jones <larry.jones@sdrc.com>
* TESTS: Remove suspicion that setting LC_COLLATE has fixed the
problem with Solaris sort -- people are still reporting it.
1999-05-17 Jim Kingdon <http://www.cyclic.com>
(These changes were run by devel-cvs; feedback was "They look fine"
from Jim Meyering and "I concur" from Noel Cragg).
* HACKING (Submitting patches): Rewrite parts to try to sketch out
a process which is less centralized and hopefully describes the
status quo better (for example, I've mostly removed the word
"submit" because it describes a process of sending your patch to a
central authority rather than to whoever wants it). Update to
reflect some of the current practices/thinking regarding quality
and other matters. Try to be more concise where feasible.
1999-05-13 Jim Kingdon <http://www.cyclic.com>
* BUGS: Remove item about RELATIVE_REPOS not working with
client/server CVS; it must have been fixed because the testsuite
is working fine with RELATIVE_REPOS.
1999-05-07 Jim Kingdon <http://www.cyclic.com>
* TESTS: Add note about send-expect style interaction.
1999-04-26 Jim Kingdon
* cvsnt.mak: Revert to the version before today's changes
(modulo one "because the IDE feels like it" change). I
couldn't get O'Connor's cvsnt.mak to work with MSVC 4.0 at
all (I tried the IDE, which tried to wrap the makefile and
wouldn't build even with the wrap, and the command line NMAKE).
* .cvsignore: Add back cvsnt.mdp WinDebug WinRel, accordingly.
1999-04-26 Jim Kingdon <http://www.cyclic.com>
* Makefile.in (DISTFILES): Add cvsnt.dsw.
1999-04-26 (submitted 1999-03-24) John O'Connor <john@shore.net>
* cvsnt.dsw: new file. The workspace file used by MSVC 5+ to
manage multiple projects. It contains three projects: cvsnt,
zlib and diff.
* cvsnt.dsp: Fixed problem where CVS wouldn't build because of
file name conflicts. Removed all the files from zlib and diff
directories and moved to separate project files.
* cvsnt.mak: Re-generated due to the changes in cvsnt.dsp.
* .cvsignore: Removed un-used entries related to MSVC. Added
entries to cover all files generated by the NT build: *.ncb,
*.opt, *.plg, Debug and Release.
1999-04-09 Jim Kingdon <http://www.cyclic.com>
* HACKING: Add a sentence about sending patches somewhere other
than bug-cvs, while still granting permission for people to use
them under the GPL.
1999-04-08 Jim Kingdon <http://www.cyclic.com>
* configure.in (AC_OUTPUT): Remove macintosh/Makefile (overlooked
in change of 1999-02-26; thanks to Erik Bertelsen for reporting it).
* configure: Regenerated.
1999-02-26 Jim Kingdon <http://www.cyclic.com>
* macintosh: Remove this subdirectory and all its contents. It
contained MacCVS 2.x, but pretty much everyone has moved on to
MacCVS 3.x, MacCVS Pro, or MacCVSClient.
* Makefile.in (SUBDIRS): Remove macintosh.
1999-02-25 Mehul N. Sanghvi (and Jim Kingdon)
* INSTALL: Add MkLinux on PowerPC.
1999-02-18 Jim Kingdon
* cvsnt.mak: Remove vasprintf. Plus of course the usual
"because the IDE feels like it" changes.
1999-02-09 Jim Kingdon <http://www.cyclic.com>
* configure.in (AC_REPLACE_FUNCS): Remove vasprintf; see
lib/ChangeLog for rationale.
* configure: Regenerated.
1999-01-31 Assar Westerlund of sics.se
and Jim Kingdon
* configure.in: The GSSAPI code in CVS requires krb5.h which
Solaris 2.7 doesn't have. Check for it.
* configure: Regenerated.
1999-01-12 Jim Kingdon <http://www.cyclic.com>
* COPYING, COPYING.LIB: Remove obsolete snail address of the Free
Software Foundation.
1998-12-01 Jim Kingdon
* TODO (195): Check in a few clarifications from Andrew Tridgell,
the rsync author.
1998-11-11 Jim Kingdon
* HACKING: Change prep.ai.mit.edu to gnu.org.
1998-10-26 Jim Kingdon
* INSTALL: Add information for Sequent DYNIX/ptx4.0, from a report
by Marco Franzen.
1998-10-14 Jim Kingdon
* configure.in (AC_OUTPUT): Remove contrib/elib/Makefile.
* configure: Regenerated using autoconf 2.10.
1998-10-13 Jim Kingdon
* TODO (149): Update since -d doesn't rewrite CVS/Root any more.
1998-10-03 Jim Kingdon <kingdon@harvey.cyclic.com>
* TODO (31): Mention the ,foo.c, and SIGINT issue.
1998-09-25 Jim Kingdon <kingdon@harvey.cyclic.com>
* FAQ: Update from FAQ-O-Matic. This features fewer blank lines
and a few more minor formatting changes (not sure whether the
FAQ-O-Matic changed or whether this is because I upgraded Lynx).
I read through the diffs, and the real changes are: (A) In
/Advanced_Topics_/Setting_up_and_Manag/, #1, describe "cvs init",
don't describe committing modules file twice
(no longer needed now that mkmodules is not a separate program),
don't mention "cvs import" here. (B)
/Advanced_Topics_/Setting_up_and_Manag/, #5, describe special
issues with pserver and repository permissions,
(C), /Advanced_Topics_/Tricks_of_the_Trade/, renumber the question
"Why do timestamps sometimes get set to the date of the revision"
from #17 to #9. Renumber the questions between #9 and #17
accordingly, (D) /User_Tasks_/Less_Common_User_Tas/, "8. How do I
split a file into pieces, retaining revision histories?", include
a script which may help with this, (E)
/What_is_CVS_/How_does_CVS_differ_/, correct the name of SABLIME,
(F) /What_is_CVS_/Where_do_I_find_CVS_/, "2. Is there an archive
of CVS material?", note that http://www.delos.com/cvs doesn't
exist any more.
* NEWS: Mention :fork:.
1998-09-24 Jim Kingdon <kingdon@harvey.cyclic.com>
* INSTALL (Tested platforms): Update SCO OpenServer information,
from a report by Robert Lipe@DIGI.
1998-09-22 Jim Kingdon <kingdon@harvey.cyclic.com>
* NEWS: Add items about multiple roots and -d not updating
CVS/Root.
1998-09-09 Jim Kingdon <kingdon@harvey.cyclic.com>
* configure.in (AC_OUTPUT): Remove tools/pcl-cvs/Makefile.
* configure: Regenerated using autoconf 2.10.
1998-09-07 Jim Kingdon <kingdon@harvey.cyclic.com>
* NEWS: Add item about LockDir.
1998-08-31 Jim Kingdon <kingdon@harvey.cyclic.com>
* INSTALL (Tested platforms): Add Solaris x86 (reported by Jeremy of
exit109.com) and Irix 6.4 (reported by Russ Allbery).
* INSTALL (Tested platforms): Add Solaris 2.6 (reported by Russ
Allbery).
1998-08-28 Noel Cragg <noel@swish.red-bean.com>
* TODO (196): new item.
1998-08-26 Jim Kingdon <kingdon@harvey.cyclic.com>
* TESTS: Update comments concerning Solaris sort and LC_COLLATE.
1998-08-17 Jim Kingdon <kingdon@harvey.cyclic.com>
* INSTALL: Update Irix, Ultrix, and NetBSD/Alpha with test results
from Noel.
1998-08-14 Jim Kingdon <kingdon@harvey.cyclic.com>
* INSTALL: Add NetBSD/mac68k (reported by Hauke Fath of melog.de).
Add alpha-dec-osf4.0 and update SunOS and linux entries (reported
by Jim Kingdon and Noel Cragg).
1998-08-06 Jim Kingdon <kingdon@harvey.cyclic.com>
* INSTALL: Update for SCO OpenServer 5 (reported by Jeffery

View File

@ -126,12 +126,10 @@ molli@loria.fr
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
@ -142,7 +140,6 @@ molli@loria.fr
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".
@ -151,13 +148,11 @@ molli@loria.fr
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
@ -166,26 +161,22 @@ molli@loria.fr
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".
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
@ -358,11 +349,9 @@ molli@loria.fr
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".
@ -377,17 +366,13 @@ molli@loria.fr
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
@ -1445,13 +1430,11 @@ You can branch a branch.
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.
@ -1459,14 +1442,12 @@ You can branch a branch.
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>
@ -1487,12 +1468,10 @@ You can branch a branch.
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:
@ -1627,7 +1606,6 @@ You can branch a branch.
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.
@ -1738,11 +1716,9 @@ You can branch a branch.
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.
@ -1952,7 +1928,6 @@ You can branch a branch.
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.
@ -1980,21 +1955,13 @@ You can branch a branch.
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.)
Then create a Repository by executing "cvs -d init". (This works with
CVS 1.9.)
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". Change to your work directory and type:
cvs checkout CVSROOT
Then read the files that are checked out.
Now you can configure your repository by checking out CVSROOT: "cvs -d
checkout CVSROOT". Change into the created directory CVSROOT. Edit the
files you want to edit, and afterwards, commit the changes by typing
"cvs commit".
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
@ -2014,15 +1981,9 @@ You can branch a branch.
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.
Andreas Kostyrka
Try using the "import" command to insert the "junk" module and play
around until you are comfortable.
Last modified: _11/7/1997_
Last modified: _4/21/1998_
2. What are those files in $CVSROOT/CVSROOT?
@ -2115,20 +2076,19 @@ You can branch a branch.
5. What file permissions should I use on (and in) the Repository?
If you are using pserver (password-authenticated access), see below.
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
@ -2136,25 +2096,20 @@ You can branch a branch.
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>
u=rwx,g=rwx,o=rx,g+s dir&gt;
- 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
@ -2168,7 +2123,21 @@ You can branch a branch.
exec /usr/local/bin/cvs.real ${1+"$@"}
^D
Last modified: _6/13/1997_
Pserver (Password-Authenticated Access) &lt;blome@de.ibm.com&gt;
The above suggestions are not valid when you use the pserver facility.
Be sure to read and understand the manual section about this (should
be 4.6.something). Above all: do /not/ make the repository and CVSROOT
group writeable. In CVSROOT, make `history´ group or world writeable
instead.
I suggest creating one unix group per project group. In the
repository, you would then create one directory for each group, group
writeable. New projects must then be created in these group
directories. If you don't want to say &lt;group&gt;/&lt;project&gt; on
checkout, create a &lt;project&gt; module and point it there.
Last modified: _9/24/1998_
6. How do I structure my Repository?
@ -2189,7 +2158,6 @@ You can branch a branch.
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.
@ -2242,20 +2210,16 @@ You can branch a branch.
- "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.
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.
@ -2270,7 +2234,6 @@ You can branch a branch.
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
@ -2280,7 +2243,6 @@ You can branch a branch.
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:
@ -2302,11 +2264,9 @@ You can branch a branch.
"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.
@ -2446,7 +2406,6 @@ You can branch a branch.
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.
@ -2659,7 +2618,6 @@ kingdon@cyclic.com
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'
@ -2940,7 +2898,36 @@ kingdon@cyclic.com
Last modified: _6/13/1997_
9. While in the middle of a large "commit", how do I run other commands,
9. 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);
Last modified: _6/13/1997_
10. While in the middle of a large "commit", how do I run other commands,
like "diff" or "stat" without seeing lock errors?
Type:
@ -2977,7 +2964,7 @@ kingdon@cyclic.com
Last modified: _6/13/1997_
10. Where did the ./CVS/Entries.Static file come from? What is it for?
11. 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
@ -3014,7 +3001,7 @@ kingdon@cyclic.com
Last modified: _6/13/1997_
11. Why did I get the wrong Repository in the loginfo message?
12. Why did I get the wrong Repository in the loginfo message?
You probably:
@ -3038,7 +3025,7 @@ kingdon@cyclic.com
Last modified: _6/13/1997_
12. How do I run CVS setuid so I can only allow access through the CVS
13. 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
@ -3067,7 +3054,7 @@ kingdon@cyclic.com
Last modified: _6/13/1997_
13. How about using groups and setgid() then?
14. How about using groups and setgid() then?
Here is a way to run CVS setgid in some environments:
@ -3122,7 +3109,7 @@ kingdon@cyclic.com
Last modified: _6/13/1997_
14. How do I use the "commitinfo" file?
15. How do I use the "commitinfo" file?
Go read 4B.2 first.
@ -3133,7 +3120,6 @@ kingdon@cyclic.com
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.
@ -3141,7 +3127,6 @@ kingdon@cyclic.com
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
@ -3156,7 +3141,6 @@ kingdon@cyclic.com
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:
@ -3165,7 +3149,6 @@ kingdon@cyclic.com
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:
@ -3176,7 +3159,7 @@ kingdon@cyclic.com
Last modified: _6/13/1997_
15. How do I use the "loginfo" files?
16. How do I use the "loginfo" files?
See 4B.2 and the "commitinfo" question above.
@ -3196,7 +3179,7 @@ kingdon@cyclic.com
Last modified: _6/13/1997_
16. How can I keep people with restrictive umask values from blocking
17. 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),
@ -3219,35 +3202,6 @@ kingdon@cyclic.com
*loosening* security. It would be better for you all to talk about the
issue and decide how to work together.
Last modified: _6/13/1997_
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);
Last modified: _6/13/1997_
Category: /Commands_/
@ -4245,14 +4199,12 @@ kingdon@cyclic.com
Providing a list of files changed since
- A tagged release.
- Yesterday, last Thursday, or a specific date.
- Someone changed a specific file.
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?)
@ -4376,7 +4328,6 @@ kingdon@cyclic.com
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
@ -5939,15 +5890,12 @@ kingdon@cyclic.com
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
@ -7464,24 +7412,45 @@ kingdon@cyclic.com
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>.
Say you want to split , which already in the Repository, into three
pieces, , and .
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>
cp $CVSROOT//,v $CVSROOT//,v cp $CVSROOT//,v $CVSROOT//,v
cvs update
Then remove all the <tags> from the new files by using:
Then remove all the from the new files, either using:
cvs log <fileB> <fileC> # Save the list of <tag?>
cvs tag -d <tag1> <fileB> <fileC>
cvs tag -d <tag2> <fileB> <fileC>
cvs log # Save the list of
cvs tag -d
cvs tag -d
. . .
(eivind@freebsd.org) or using the following little script to
autmatically remove the tags directly from the repository files:
#!/bin/sh
for file in $*
do
TAGS=`rlog $file | awk '/^symbolic names:/,/^keyword subst/' | awk 'BEG
IN {FS=":"} /^\t/ {print $1}'`
echo The tags in $file are
echo $TAGS
echo Is it OK to remove these?
read confirm
if [ "$confirm" = "y" -o "$confirm" = "yes" ]
then
for tag in $TAGS
do
echo Removing $file:$tag
rcs -n$tag $file
done
fi
done
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.
@ -7491,8 +7460,8 @@ kingdon@cyclic.com
statements, which must be duplicated. And make sure the code
compiles.]
emacs <fileA> <fileB> <fileC>
cvs commit <fileA> <fileB> <fileC>
emacs
cvs commit
As in the "rename" case, by duplicating the files, you'll preserve the
change history and the ability to retrieve earlier revisions.
@ -7500,7 +7469,7 @@ kingdon@cyclic.com
Of course, you have to alter your build system (e.g. Makefiles) to
take the new names and the change in contents into account.
Last modified: _6/13/1997_
Last modified: _3/11/1998_
Category: /What_is_CVS_/
@ -7772,7 +7741,7 @@ kingdon@cyclic.com
Last modified: _6/13/1997_
10. How does CVS differ from Sublime?
10. How does CVS differ from SABLIME?
Produced by AT&T. Sablime uses SCCS as the underlying source code
control system. It uses some other control system (called sbcs I
@ -7790,7 +7759,7 @@ kingdon@cyclic.com
weight though, and the interface is not too polished and does not work
on windows (though that may have changed). rama@savera.com
Last modified: _12/12/1997_
Last modified: _7/30/1998_
11. How does CVS differ from PVCS?
@ -8457,7 +8426,7 @@ kingdon@cyclic.com
ftp ftp.delos.com
>>> User: anonymous
>>> Passwd: <Your Internet address>
>>> Passwd:
cd /pub/cvs
get README
get Index
@ -8467,7 +8436,9 @@ kingdon@cyclic.com
A WWW home page is also available at http://www.delos.com/cvs.
Last modified: _6/13/1997_
This Didn't Exist 6/23/1998
Last modified: _6/24/1998_
3. How do I get files out of the archive if I don't have FTP?
@ -8569,17 +8540,17 @@ kingdon@cyclic.com
Last modified: _9/6/1997_
_________________________________________________________________
[Add an answer to this category]
[Category /]
_________________________________________________________________
_Search the FAQ-O-Matic:_ ____________________ ______
_Search the FAQ-O-Matic:_ ____________________ Search
[matching all words]
Or look for questions modified in the last: [7.] ____
Or look for questions modified in the last: [7.] Days
_________________________________________________________________
The FAQ-O-Matic lives at http://gille.loria.fr:7000/cgi-bin/faqomatic.
The code was written by Jon Howell, and the content by folks from all
over the web.

View File

@ -98,32 +98,25 @@ Filenames for .c and .h files may contain _ but should not contain -
(the latter causes Visual C++ 2.1 to create makefiles which Visual C++
4.0 cannot use).
* Submitting patches (strategy)
* Writing patches (strategy)
Only some kinds of changes are suitable for inclusion in the
"official" CVS. Bugfixes, where CVS's behavior contradicts the
documentation and/or expectations that everyone agrees on, should be
OK (strategically). For features, the desirable attributes are that
the need is clear and that they fit nicely into the architecture of
CVS.
CVS. Is it worth the cost (in terms of complexity or any other
tradeoffs involved)? Are there better solutions?
However, if there is reason to think that a change would significantly
inconvenience any significant body of CVS users, or would be
controversial for other reasons, then the design should be re-thought.
Go back to the requirements (writing documentation might help, if you
write the documentation to explain why one would use the feature not
just what the feature does). Think about whether there is a behavior
which works in both your situation and the other situations. Make a
list of the issues (for example, submit a comment or documentation
change). Ask your coworkers, a newsgroup, or a mailing list, and see
what other people think. Distribute some experimental patches outside
the "official" CVS and see what people think. By this process, the
intention is that once-controversial changes can be refined to the
point where they are relatively uncontroversial before they are
actually checked in to the "official" CVS. Features like zlib,
encryption, and others have benefitted from this process in the past
by being mentioned in the documentation and/or discussed, before an
implementation was checked in.
If the design is not yet clear (which is true of most features), then
the design is likely to benefit from more work and community input.
Make a list of issues, or write documentation including rationales for
how one would use the feature. Discuss it with coworkers, a
newsgroup, or a mailing list, and see what other people think.
Distribute some experimental patches and see what people think. The
intention is arrive at some kind of rough community consensus before
changing the "official" CVS. Features like zlib, encryption, and
the RCS library have benefitted from this process in the past.
If longstanding CVS behavior, that people may be relying on, is
clearly deficient, it can be changed, but only slowly and carefully.
@ -131,37 +124,49 @@ For example, the global -q option was introduced in CVS 1.3 but the
command -q options, which the global -q replaced, were not removed
until CVS 1.6.
* Submitting patches (tactics)
* Writing patches (tactics)
Please include a ChangeLog entry (see the GNU coding standards for
information on writing one) with patches. Include a description of
what the patch does (sometimes the ChangeLog entry and/or comments in
the code are appropriate for this, but not always)--patches should not
be checked in unless there is some reason for them, and the
description may be helpful if there is a better way to solve the
problem. In addition to the ChangeLog entry, there should be a change
to the NEWS file and cvs.texinfo, if the change is a user-visible
change worth mentioning.
When you first distribute a patch it may be suitable to just put forth
a rough patch, or even just an idea. But before the end of the
process the following should exist:
It is nice to have a test case (see TESTS), especially for fixes which
involve subtle behaviors or twisted sections of the code.
- ChangeLog entry (see the GNU coding standards for details).
If you solve several unrelated problems, submit a separate
patch for each one. Patches should be tested before submission. Use
context diffs or unidiffs for patches.
- Changes to the NEWS file and cvs.texinfo, if the change is a
user-visible change worth mentioning.
Note that all submitted changes may be distributed under the terms of
the GNU Public License, so if you don't like this, don't submit them.
Submit changes to bug-cvs@gnu.org.
- Somewhere, a description of what the patch fixes (often in
comments in the code, or maybe the ChangeLog or documentation).
Generally speaking if you follow the guidelines in this file you can
expect a yes or no answer about whether your patch is accepted. But
even in this case there is no guarantee because wading through a bunch
of submissions can be time consuming, and noone has volunteered to
offer any such guarantee. If you don't receive an answer one way or
another within a month, feel free to ask what the status is. You can,
if you wish, distribute your patch on mailing lists or newsgroups, if
you want to make it available before it gets merged.
- Most of the time, a test case (see TESTS). It can be quite
frustrating to fix a bug only to see it reappear later, and adding
the case to the testsuite, where feasible, solves this and other
problems.
If you solve several unrelated problems, it is generally easier to
consider the desirability of the changes if there is a separate patch
for each issue. Use context diffs or unidiffs for patches.
Include words like "I grant permission to distribute this patch under
the terms of the GNU Public License" with your patch. By sending a
patch to bug-cvs@gnu.org, you implicitly grant this permission.
Submitting a patch to bug-cvs is the way to reach the people who have
signed up to receive such submissions (including CVS developers), but
there may or may not be much (or any) response. If you want to pursue
the matter further, you are probably best off working with the larger
CVS community. Distribute your patch as widely as desired (mailing
lists, newsgroups, web sites, whatever). Write a web page or other
information describing what the patch is for. It is neither practical
nor desirable for all/most contributions to be distributed through the
"official" (whatever that means) mechanisms of CVS releases and CVS
developers. Now, the "official" mechanisms do try to incorporate
those patches which seem most suitable for widespread usage, together
with test cases and documentation. So if a patch becomes sufficiently
popular in the CVS community, it is likely that one of the CVS
developers will eventually try to do something with it. But dealing
with the CVS developers may be the last step of the process rather
than the first.
* What is the schedule for the next release?
@ -195,5 +200,5 @@ list which users are requested to send bug reports to. Anyone can
subscribe; to do so send mail to bug-cvs-request@gnu.org.
Other CVS discussions take place on the info-cvs mailing list
(send mail to info-cvs-request@prep.ai.mit.edu to subscribe) or on
(send mail to info-cvs-request@gnu.org to subscribe) or on
the newsgroup comp.software.config-mgmt.

View File

@ -108,8 +108,10 @@ Alpha:
DEC Alpha running OSF/1 version 2.1 (about 1.4A2)
DEC Alpha running OSF/1 version 3.0 (1.5.95) (footnote 7)
DEC Alpha running OSF/1 version 3.2 (1.9)
Alpha running alpha-dec-osf4.0 (1.10)
DEC Alpha running Digital UNIX v4.0C using gcc 2.7.2.2 (1.9.14)
DEC Alpha running VMS 6.2 (1.8.85 client-only)
Alpha running NetBSD 1.2E (1.10)
Cray:
J90 (CVS 970215 snapshot)
T3E (CVS 970215 snapshot)
@ -124,17 +126,20 @@ HPPA:
NextSTEP 3.3 (1.7)
i386 family:
Solaris 2.4 using gcc (about 1.4A2)
Solaris 2.6 (1.9)
UnixWare v1.1.1 using gcc (about 1.4A2)
Unixware 2.1 (1.8.86)
Unixware 7 (1.9.29)
ISC 4.0.1 (1.8.87)
Linux (kernel 1.2.x) (1.8.86)
Linux (kernel 2.0.x, RedHat 4.2) (1.9)
Linux (kernel 2.0.x, RedHat 4.2) (1.10)
Linux (kernel 2.0.x, RedHat 5.x) (1.10)
BSDI 2.0 (1.4.93) (footnote 5)
FreeBSD 2.1.5-stable (1.8.87)
NextSTEP 3.3 (1.7)
SCO Unix 3.2.4.2, gcc 2.7.2 (1.8.87) (footnote 4)
SCO OpenServer 5 (1.9.29)
SCO OpenServer 5.0.5 (1.10.2)
Sequent DYNIX/ptx4.0 (1.10 or so) (remove -linet)
Sequent Dynix/PTX 4.1.4 (1.9.20 or so + patches)
Lynx 2.3.0 080695 (1.6.86) (footnote 9)
Windows NT 3.51 (1.8.86 client; 1.8.3 local)
@ -150,17 +155,19 @@ m68k:
Sun 3 running SunOS 4.1.1_U1 w/ bundled K&R /usr/5bin/cc (1.8.86+)
NextSTEP 3.3p1 (1.8.87)
Lynx 2.3.0 062695 (1.6.86) (footnote 9)
NetBSD/mac68k (1.9.28)
m88k:
Data General AViiON running dgux 5.4R2.10 (1.5)
Data General AViiON running dgux 5.4R3.10 (1.7.1)
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.8.85)
DECstation running Ultrix 4.3 (1.10)
SGI running Irix 4.0.5H using gcc and cc (about 1.4A2) (footnote 2)
SGI running Irix 5.3 using gcc 2.7.2 (1.8.87)
SGI running Irix 5.3 (1.10)
SGI running Irix 6.2 using SGI MIPSpro 6.2 and beta 7.2 compilers (1.9)
SGI running Irix-6.2 (1.9.8)
SGI running IRIX 6.4 (1.10)
Siemens-Nixdorf RM600 running SINIX-Y (1.6)
PowerPC or RS/6000:
IBM RS/6000 running AIX 3.1 using gcc and cc (1.6.86)
@ -168,12 +175,14 @@ PowerPC or RS/6000:
IBM RS/6000 running AIX 4.1 (1.9)
Lynx 2.3.1 120495 (1.6.86) (footnote 9)
Lynx 2.5 (1.9) (footnote 10)
MkLinux DR3 GENERIC #6 (1.10.5.1) (presumably LinuxPPC too)
SPARC:
Sun SPARC running SunOS 4.1.x using gcc 2.7.2.1 (1.9.14)
Sun SPARC running SunOS 4.1.x (1.10)
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 (1.8.87)
Sun SPARC running Solaris 2.5.1 using gcc 2.7.2.2 (1.9.14)
Sun UltraSPARC running Solaris 2.6 using gcc 2.8.1 (1.10)
NextSTEP 3.3 (1.7)
Sun SPARC running Linux 2.0.17, gcc 2.7.2 (1.8.87)
VAX:

View File

@ -89,7 +89,7 @@ DISTFILES = \
ChangeLog NEWS ChangeLog.zoo \
configure configure.in stamp-h.in config.h.in Makefile.in acconfig.h \
cvs-format.el mkinstalldirs install-sh \
cvsnt.mak cvsnt.dsp \
cvsnt.mak cvsnt.dsp cvsnt.dsw \
.cvsignore cvs.spec
### Subdirectories to run make in for the primary targets.
@ -97,7 +97,7 @@ DISTFILES = \
USOURCE_SUBDIRS = lib zlib diff src
# All other subdirs:
SUBDIRS = ${USOURCE_SUBDIRS} man doc contrib tools \
windows-NT os2 emx macintosh vms
windows-NT os2 emx vms
# Only make TAGS/tags files in these directories.
TSUBDIRS= src lib

View File

@ -1,4 +1,27 @@
Changes since 1.9:
Changes since 1.10:
* There is a new access method :fork: which is similar to :local:
except that it is implemented via the CVS remote protocol, and thus
has a somewhat different set of quirks and bugs.
* The -d command line option no longer updates the CVS/Root file. For
one thing, the CVS 1.9/1.10 behavior never had updated CVS/Root in
subdirectories, and for another, it didn't seem that popular in
general. So this change restores the CVS 1.8 behavior (which is also
the CVS 1.9/1.10 behavior if the environment variable
CVS_IGNORE_REMOTE_ROOT is set; with this change,
CVS_IGNORE_REMOTE_ROOT no longer has any effect).
* It is now possible for a single CVS command to recurse into several
CVS roots. This includes roots which are located on several servers,
or which are both remote and local. CVS will make connections to as
many servers as necessary.
* It is now possible to put the CVS lock files in a directory
set by the new LockDir option in CVSROOT/config. The default
continues to be to put the lock files in the repository itself.
Changes from 1.9 to 1.10:
* There is a new feature, enabled by TopLevelAdmin in CVSROOT/config,
which tells CVS to modify the behavior of the "checkout" command. The

View File

@ -17,11 +17,12 @@ can set the TESTDIR environment variable to the desired location
before running them.
You will probably need GNU expr, which is part of the GNU sh-utils
package. You may also need sort from the GNU textutils; Solaris
in particular has been reported to have a sort program which does not
behave the way that the testsuite expects (with Solaris, lines
starting with tabs sort before blank lines). These programs are just
for running the tests; CVS itself doesn't require expr or sort.
package. This is just for running the tests; CVS itself doesn't
require expr.
With CVS 1.10 people also had trouble with the Solaris sort program
not behaving the way that the testsuite expects (with Solaris, lines
starting with tabs sort before blank lines).
If there is some unexpected output, that is a failure which can be
somewhat hard to track down. Finding out which test is producing the
@ -144,3 +145,8 @@ workaround).
b. pass stdin to the program under test (sanity.sh, again, handles
this by bypassing dotest).
c. have a send-expect type dialog with the program under test
(e.g. see server-7 or pserver-4 which want to talk the CVS
protocol, or the many tests which need to answer the prompt of "cvs
release", e.g. deep-5).

View File

@ -11,6 +11,8 @@ too?). (perhaps should think a little harder about what this is
trying to accomplish and what the best way is -kingdon, Jul 1997).
31. Think hard about ^C recovery.
One particular issue: RCS removes the ,foo.c, file on ^C and CVS
doesn't.
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
@ -254,10 +256,10 @@ trying to accomplish and what the best way is -kingdon, Jul 1997).
probably want to give an error if it disagreed with CVS/Root, as
CVS 1.8 and earlier did). The other is the "reposmv"
functionality above (in which the two repositories really are the
same, and we want to update the CVS/Root files). A related issue
is that the fact that CVS only sets and looks at the CVS/Root
file in the directory where CVS is run; it doesn't do anything
about CVS/Root files in subdirectories.
same, and we want to update the CVS/Root files). In CVS 1.9 and
1.10, -d rewrites the CVS/Root file (but not in subdirectories).
This behavior was not particularly popular and has been since
reverted.
Note also RELATIVE_REPOS in options.h; it needs to be set for
changing CVS/Root (not CVS/Repository) to be sufficient in the
@ -767,7 +769,8 @@ or vice versa.
a. Cases in which the status quo already sends a diff. For most text
files, this is probably already close to optimal. For binary files,
and anomalous text files, it might be worth looking into other
and anomalous (?) text files (e.g. those in which it would help to do
moves, as well as adds and deletes), it might be worth looking into other
difference algorithms (see item #191).
b. Cases in which the status quo does not send a diff (e.g. "cvs
@ -777,9 +780,9 @@ b1. With some frequency, people suggest rsync or a similar algorithm
(see ftp://samba.anu.edu.au/pub/rsync/). This could speed things up,
and in some ways involves the most minimal changes to the default CVS
paradigm. There are some downsides though: (1) there is an extra
network turnaround, (2) the algorithm is not as efficient with network
bandwidth as difference type programs (it transmits a fair bit of data
to discover what a difference program discovers locally).
network turnaround, (2) the algorithm needs to transmit some data to
discover what difference type programs can discover locally (although
this is only about 1% of the size of the files).
b2. If one is willing to require that users use "cvs edit" before
editing a file on the client side (in some cases, a development
@ -788,3 +791,7 @@ request in the protocol could be extended to allow the client to just
send differences instead of entire files. In the degenerate case
(e.g. "cvs diff" without arguments) the required network traffic is
reduced to zero, and the client need not even contact the server.
196. Using a CVSROOT with a trailing slash will confuse CVS. I think
we need to add a call to strip_trailing_slashes in root.c
(parse_cvsroot), but I haven't considered all of the ramifications.

44
contrib/cvs/configure vendored
View File

@ -1782,7 +1782,7 @@ EOF
fi
for ac_func in mkdir rename strstr dup2 strerror valloc waitpid memmove vasprintf strtoul
for ac_func in mkdir rename strstr dup2 strerror valloc waitpid memmove strtoul
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
@ -2939,7 +2939,7 @@ echo "default place for GSSAPI is $GSSAPI"
hold_cppflags=$CPPFLAGS
CPPFLAGS="$CPPFLAGS -I$GSSAPI/include "
for ac_hdr in gssapi.h gssapi/gssapi.h gssapi/gssapi_generic.h
for ac_hdr in krb5.h gssapi.h gssapi/gssapi.h gssapi/gssapi_generic.h
do
ac_safe=`echo "$ac_hdr" | tr './\055' '___'`
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
@ -2978,7 +2978,9 @@ done
CPPFLAGS=$hold_cppflags
if test "$ac_cv_header_gssapi_h" = "yes" || test "$ac_cv_header_gssapi_gssapi_h" = "yes"; then
if test "$ac_cv_header_krb5_h" = "yes" &&
(test "$ac_cv_header_gssapi_h" = "yes" ||
test "$ac_cv_header_gssapi_gssapi_h" = "yes"); then
cat >> confdefs.h <<\EOF
#define HAVE_GSSAPI 1
EOF
@ -2994,7 +2996,7 @@ EOF
CPPFLAGS="-I$GSSAPI/include $CPPFLAGS"
if test "$ac_cv_header_gssapi_h" = "yes"; then
cat > conftest.$ac_ext <<EOF
#line 2998 "configure"
#line 3000 "configure"
#include "confdefs.h"
#include <gssapi.h>
EOF
@ -3010,7 +3012,7 @@ rm -f conftest*
else
cat > conftest.$ac_ext <<EOF
#line 3014 "configure"
#line 3016 "configure"
#include "confdefs.h"
#include <gssapi/gssapi.h>
EOF
@ -3036,7 +3038,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-lgen $LIBS"
cat > conftest.$ac_ext <<EOF
#line 3040 "configure"
#line 3042 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
@ -3048,7 +3050,7 @@ int t() {
compile()
; return 0; }
EOF
if { (eval echo configure:3052: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
if { (eval echo configure:3054: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
@ -3098,7 +3100,7 @@ if eval "test \"`echo '$''{'ac_cv_func_gethostname'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
#line 3102 "configure"
#line 3104 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char gethostname(); below. */
@ -3122,7 +3124,7 @@ gethostname();
; return 0; }
EOF
if { (eval echo configure:3126: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
if { (eval echo configure:3128: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
rm -rf conftest*
eval "ac_cv_func_gethostname=yes"
else
@ -3199,7 +3201,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-lcrypt $LIBS"
cat > conftest.$ac_ext <<EOF
#line 3203 "configure"
#line 3205 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
@ -3211,7 +3213,7 @@ int t() {
crypt()
; return 0; }
EOF
if { (eval echo configure:3215: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
if { (eval echo configure:3217: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
@ -3242,7 +3244,7 @@ if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
#line 3246 "configure"
#line 3248 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@ -3266,7 +3268,7 @@ $ac_func();
; return 0; }
EOF
if { (eval echo configure:3270: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
if { (eval echo configure:3272: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
rm -rf conftest*
eval "ac_cv_func_$ac_func=yes"
else
@ -3307,7 +3309,7 @@ if eval "test \"`echo '$''{'ccvs_cv_sys_cygwin32'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
#line 3311 "configure"
#line 3313 "configure"
#include "confdefs.h"
int main() { return 0; }
@ -3315,7 +3317,7 @@ int t() {
return __CYGWIN32__;
; return 0; }
EOF
if { (eval echo configure:3319: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
if { (eval echo configure:3321: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ccvs_cv_sys_cygwin32=yes
else
@ -3441,10 +3443,10 @@ ac_given_srcdir=$srcdir
ac_given_INSTALL="$INSTALL"
trap 'rm -fr `echo "Makefile lib/Makefile src/Makefile zlib/Makefile diff/Makefile doc/Makefile \
man/Makefile tools/Makefile tools/pcl-cvs/Makefile \
contrib/Makefile contrib/elib/Makefile \
man/Makefile tools/Makefile \
contrib/Makefile \
windows-NT/Makefile windows-NT/SCC/Makefile \
os2/Makefile emx/Makefile macintosh/Makefile vms/Makefile \
os2/Makefile emx/Makefile vms/Makefile \
stamp-h config.h src/options.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
EOF
cat >> $CONFIG_STATUS <<EOF
@ -3495,10 +3497,10 @@ EOF
cat >> $CONFIG_STATUS <<EOF
CONFIG_FILES=\${CONFIG_FILES-"Makefile lib/Makefile src/Makefile zlib/Makefile diff/Makefile doc/Makefile \
man/Makefile tools/Makefile tools/pcl-cvs/Makefile \
contrib/Makefile contrib/elib/Makefile \
man/Makefile tools/Makefile \
contrib/Makefile \
windows-NT/Makefile windows-NT/SCC/Makefile \
os2/Makefile emx/Makefile macintosh/Makefile vms/Makefile \
os2/Makefile emx/Makefile vms/Makefile \
stamp-h"}
EOF
cat >> $CONFIG_STATUS <<\EOF

View File

@ -63,7 +63,7 @@ AC_TYPE_MODE_T
AC_TYPE_SIZE_T
AC_TYPE_PID_T
AC_STRUCT_ST_BLKSIZE
AC_REPLACE_FUNCS(mkdir rename strstr dup2 strerror valloc waitpid memmove vasprintf strtoul)
AC_REPLACE_FUNCS(mkdir rename strstr dup2 strerror valloc waitpid memmove strtoul)
AC_CHECK_FUNCS(fchmod fsync ftime mktemp putenv vprintf ftruncate timezone getpagesize initgroups fchdir sigaction sigprocmask sigvec sigsetmask sigblock tempnam tzset readlink wait3)
dnl
@ -262,10 +262,12 @@ WITH_GSSAPI
hold_cppflags=$CPPFLAGS
CPPFLAGS="$CPPFLAGS -I$GSSAPI/include "
AC_CHECK_HEADERS(gssapi.h gssapi/gssapi.h gssapi/gssapi_generic.h)
AC_CHECK_HEADERS(krb5.h gssapi.h gssapi/gssapi.h gssapi/gssapi_generic.h)
CPPFLAGS=$hold_cppflags
if test "$ac_cv_header_gssapi_h" = "yes" || test "$ac_cv_header_gssapi_gssapi_h" = "yes"; then
if test "$ac_cv_header_krb5_h" = "yes" &&
(test "$ac_cv_header_gssapi_h" = "yes" ||
test "$ac_cv_header_gssapi_gssapi_h" = "yes"); then
AC_DEFINE(HAVE_GSSAPI)
includeopt="${includeopt} -I$GSSAPI/include"
# FIXME: This is ugly, but these things don't seem to be standardized.
@ -381,8 +383,8 @@ test -f src/options.h && (
)
AC_OUTPUT(Makefile lib/Makefile src/Makefile zlib/Makefile diff/Makefile doc/Makefile \
man/Makefile tools/Makefile tools/pcl-cvs/Makefile \
contrib/Makefile contrib/elib/Makefile \
man/Makefile tools/Makefile \
contrib/Makefile \
windows-NT/Makefile windows-NT/SCC/Makefile \
os2/Makefile emx/Makefile macintosh/Makefile vms/Makefile \
os2/Makefile emx/Makefile vms/Makefile \
stamp-h)

View File

@ -1,3 +1,47 @@
1999-01-19 Graham Stoney <greyham@research.canon.com.au>
* log.pl: The author commited the canonical perl "localtime" Y2K
offence, of printing "19$year" instead of (1900 + $year). Of
course, the result is non-compliance in year 2000. Fix it.
1998-10-14 Jim Kingdon
* ccvs-rsh.pl: Removed; it was not in DISTFILES so it didn't
actually get distributed. I'm going to move it to the web on the
theory that the web is a better place for such things.
* README: Don't mention it.
* Makefile.in (dist-dir, distclean): Remove references to elib.
* elib: Remove this subdirectory and all its contents. It went
with pcl-cvs, which is no longer distributed with CVS.
1998-09-22 Jim Kingdon <kingdon@harvey.cyclic.com>
* pvcs_to_rcs: Removed; it was not in DISTFILES so it didn't
actually get distributed. I'm going to move it to the web on the
theory that the web is a better place for such things.
* README: Don't mention it.
1998-09-10 Jim Kingdon
Check in Paul Eggert <eggert@twinsun.com>'s submission of
1998-08-15. I also ran "cvs admin -ko" on this file so that his
version number would be intact (not an ideal solution, because
people will import it into other repositories, but I don't feel
like hacking the master version).
* rcs2log.sh: Sync with master version at gnu.org.
1998-08-15 Jim Kingdon <kingdon@harvey.cyclic.com>
* README: Don't mention listener, since it was removed a while
ago.
* listen2.c, listen2.mak: Removed; because there is no easy way to
pass a socket (as opposed to file descriptor) from one process to
another on Windows, this isn't a promising approach (at least not
in this form).
* Makefile.in (DISTFILES): Remove them.
* .cvsignore: Remove listen2.ncb listen2.mdp Debug.
1998-05-11 W. Bradley Rubenstein
* log.pl: Check for errors from open and exec.

View File

@ -44,8 +44,7 @@ DISTFILES = \
Makefile.in clmerge.pl cln_hist.pl commit_prep.pl cvs2vendor.sh \
cvs_acls.pl cvscheck.sh cvscheck.man cvshelp.man descend.sh \
descend.man dirfns.shar log.pl log_accum.pl mfpipe.pl rcs-to-cvs.sh \
rcs2log.sh rcslock.pl sccs2rcs.csh rcs2sccs.sh \
listen2.c listen2.mak
rcs2log.sh rcslock.pl sccs2rcs.csh rcs2sccs.sh
# files installed in $(libdir)/cvs/contrib
#
@ -110,7 +109,7 @@ clean:
.PHONY: clean
distclean: clean
rm -f Makefile elib/Makefile $(PROGS) $(CONTRIB_PROGS)
rm -f Makefile $(PROGS) $(CONTRIB_PROGS)
.PHONY: distclean
realclean: distclean
@ -121,7 +120,6 @@ dist-dir:
for i in ${DISTFILES}; do \
ln $(srcdir)/$${i} ${DISTDIR}; \
done
cd elib; ${MAKE} dist-dir DISTDIR="../${DISTDIR}/elib"
.PHONY: dist-dir
subdir = contrib

View File

@ -64,9 +64,6 @@ An attempt at a table of Contents for this directory:
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.
@ -86,10 +83,6 @@ An attempt at a table of Contents for this directory:
into RCS files, retaining the info contained in the
SCCS file (like dates, author, and log message).
Contributed by Ken Cox <kenstir@viewlogic.com>.
pvcs_to_rcs A perl script that can convert (some) PVCS histories
into RCS files, retaining the info contained in the
PVCS history. See the comments at the start of the
file for more details.
intro.doc A user's view of what you need to know to get
started with CVS.
Contributed by <Steven.Pemberton@cwi.nl>.
@ -105,10 +98,6 @@ An attempt at a table of Contents for this directory:
clmerge A perl script to handle merge conflicts in GNU
style ChangeLog files .
Contributed by Tom Tromey <tromey@busco.lanl.gov>.
listener A program which listens to a TCP port, authenticates
by hostname, then runs a subprocess whose input/output
is redirected through the port.
Contributed by Benjamin J. Lee <benjamin@cyclic.com>
cvs2vendor A shell script to move changes from a repository
that was started without a vendor branch to one
that has a vendor branch.

View File

@ -2,7 +2,8 @@
# RCS to ChangeLog generator
# Generate a change log prefix from RCS files and the ChangeLog (if any).
# Generate a change log prefix from RCS files (perhaps in the CVS repository)
# 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.
@ -10,25 +11,49 @@
# Clump together log entries that start with `{topic} ',
# where `topic' contains neither white space nor `}'.
# Author: Paul Eggert <eggert@twinsun.com>
Help='The default FILEs are the files registered under the working directory.
Options:
# Copyright 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
-c CHANGELOG Output a change log prefix to CHANGELOG (default ChangeLog).
-h HOSTNAME Use HOSTNAME in change log entries (default current host).
-i INDENT Indent change log lines by INDENT spaces (default 8).
-l LENGTH Try to limit log lines to LENGTH characters (default 79).
-R If no FILEs are given and RCS is used, recurse through working directory.
-r OPTION Pass OPTION to subsidiary log command.
-t TABWIDTH Tab stops are every TABWIDTH characters (default 8).
-u "LOGIN<tab>FULLNAME<tab>MAILADDR" Assume LOGIN has FULLNAME and MAILADDR.
-v Append RCS revision to file names in log lines.
--help Output help.
--version Output version number.
Report bugs to <bug-gnu-emacs@gnu.org>.'
Id='$Id: rcs2log,v 1.45 1998/08/12 22:33:01 eggert Exp $'
# Copyright 1992, 93, 94, 95, 96, 97, 1998 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, Inc., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.
Copyright='Copyright 1998 Free Software Foundation, Inc.
This program comes with NO WARRANTY, to the extent permitted by law.
You may redistribute copies of this program
under the terms of the GNU General Public License.
For more information about these matters, see the files named COPYING.
Author: Paul Eggert <eggert@twinsun.com>'
tab=' '
nl='
'
@ -38,18 +63,23 @@ nl='
# defaults
: ${AWK=awk}
: ${TMPDIR=/tmp}
changelog=ChangeLog # change log file name
datearg= # rlog date option
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
logTZ= # time zone for log dates (if empty, use local time)
recursive= # t if we want recursive rlog
revision= # t if we want revision numbers
rlog_options= # options to pass to rlog
tabwidth=8 # width of horizontal tab
while :
do
case $1 in
-c) changelog=${2?}; shift;;
-i) indent=${2?}; shift;;
-h) hostname=${2?}; shift;;
-l) length=${2?}; shift;;
@ -60,7 +90,10 @@ do
echo >&2 "$0: -n '$2' '$3' '$4': tabs, newlines not allowed"
exit 1
esac
loginFullnameMailaddrs=$loginFullnameMailaddrs$nl$2$tab$3$tab$4
case $loginFullnameMailaddrs in
'') loginFullnameMailaddrs=$2$tab$3$tab$4;;
?*) loginFullnameMailaddrs=$loginFullnameMailaddrs$nl$2$tab$3$tab$4
esac
shift; shift; shift;;
-u)
# If $2 is not tab-separated, use colon for separator.
@ -83,19 +116,36 @@ do
echo >&2 "$0: -u '$2': not enough fields"
exit 1
esac
loginFullnameMailaddrs=$loginFullnameMailaddrs$nl$2
case $loginFullnameMailaddrs in
'') loginFullnameMailaddrs=$2;;
?*) loginFullnameMailaddrs=$loginFullnameMailaddrs$nl$2
esac
shift
esac
logins=$logins$nl$login
case $logins in
'') logins=$login;;
?*) logins=$logins$nl$login
esac
;;
-r) rlog_options=$rlog_options$nl${2?}; shift;;
-r)
case $rlog_options in
'') rlog_options=${2?};;
?*) rlog_options=$rlog_options$nl${2?}
esac
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;;
-v) revision=t;;
--version)
set $Id
rcs2logVersion=$3
echo >&2 "rcs2log (GNU Emacs) $rcs2logVersion$nl$Copyright"
exit 0;;
-*) echo >&2 "Usage: $0 [OPTION]... [FILE ...]$nl$Help"
case $1 in
--help) exit 0;;
*) exit 1
esac;;
*) break
esac
shift
@ -106,12 +156,6 @@ month_data='
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
'
@ -119,63 +163,59 @@ month_data='
# If no rlog options are given,
# log the revisions checked in since the first ChangeLog entry.
# Since ChangeLog is only by date, some of these revisions may be duplicates of
# what's already in ChangeLog; it's the user's responsibility to remove them.
case $rlog_options in
'')
date=1970-01-01
if test -s ChangeLog
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]/{
# ISO 8601 date
print $1
exit
}
/^... ... [ 0-9][0-9] [ 0-9][0-9]:[0-9][0-9]:[0-9][0-9] [0-9]+ /{
# old-fashioned date and time (Emacs 19.31 and earlier)
'"$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++
}
}
}
}
}
printf "%02d/%02d/%d %02d:%02d:%02d\n", i+1,dd,year,hh,mm,ss
printf "%d-%02d-%02d\n", year, i+1, dd
exit
}
'
d=`$AWK "$e" <ChangeLog` || exit
d=`$AWK "$e" <"$changelog"` || exit
case $d in
?*) date=$d
?*) datearg="-d>$d"
esac
fi
datearg="-d>$date"
esac
# Use TZ specified by ChangeLog local variable, if any.
if test -s "$changelog"
then
extractTZ='
/^.*change-log-time-zone-rule['"$tab"' ]*:['"$tab"' ]*"\([^"]*\)".*/{
s//\1/; p; q
}
/^.*change-log-time-zone-rule['"$tab"' ]*:['"$tab"' ]*t.*/{
s//UTC0/; p; q
}
'
logTZ=`tail "$changelog" | sed -n "$extractTZ"`
case $logTZ in
?*) TZ=$logTZ; export TZ
esac
fi
# 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'
rlog='cvs -q log'
repository=`sed 1q <CVS/Repository` || exit
test ! -f CVS/Root || CVSROOT=`cat <CVS/Root` || exit
case $CVSROOT in
@ -196,6 +236,16 @@ else
esac
fi
# Use $rlog's -zLT option, if $rlog supports it.
case `$rlog -zLT 2>&1` in
*' option'*) ;;
*)
case $rlog_options in
'') rlog_options=-zLT;;
?*) rlog_options=-zLT$nl$rlog_options
esac
esac
# With no arguments, examine all files under the RCS directory.
case $# in
0)
@ -210,7 +260,14 @@ case $# in
files=`
{
case $RCSdirs in
?*) find $RCSdirs -type f -print
?*) find $RCSdirs \
-type f \
! -name '*_' \
! -name ',*,' \
! -name '.*_' \
! -name .rcsfreeze.log \
! -name .rcsfreeze.ver \
-print
esac
find . -name '*,v' -print
} |
@ -222,10 +279,16 @@ case $# in
for file in RCS/.* RCS/* .*,v *,v
do
case $file in
RCS/. | RCS/..) continue;;
RCS/.\* | RCS/\* | .\*,v | \*,v) test -f "$file" || continue
RCS/. | RCS/.. | RCS/,*, | RCS/*_) continue;;
RCS/.rcsfreeze.log | RCS/.rcsfreeze.ver) continue;;
RCS/.\* | RCS/\* | .\*,v | \*,v) test -f "$file" || continue;;
RCS/*,v | RCS/.*,v) ;;
RCS/* | RCS/.*) test -f "$file" || continue
esac
case $files in
'') files=$file;;
?*) files=$files$nl$file
esac
files=$files$nl$file
done
case $files in
'') exit 0
@ -242,9 +305,9 @@ 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
case $datearg in
?*) $rlog $rlog_options "$datearg" ${1+"$@"} >$rlogout;;
'') $rlog $rlog_options ${1+"$@"} >$rlogout
esac || exit
@ -362,13 +425,16 @@ EOF
'
initialize_fullname=`
(
cat /etc/passwd
for author in $authors
do nismatch $author passwd.org_dir
done
ypmatch $authors passwd
) 2>/dev/null |
{
(getent passwd $authors) ||
(
cat /etc/passwd
for author in $authors
do NIS_PATH= nismatch $author passwd.org_dir
done
ypmatch $authors passwd
)
} 2>/dev/null |
$AWK -F: "$awkscript"
`$initialize_fullname
esac
@ -376,7 +442,7 @@ 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).
# `Log' is the log message (with \n replaced by \001).
# `files' contains the affected files.
printlogline='{
@ -392,13 +458,13 @@ printlogline='{
# 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
if ('"$length"' <= '"$indent"' + 1 + length(files) + index(Log, SOH)) 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) {
# Print each line of the log, transliterating \001 to \n.
while ((i = index(Log, SOH)) != 0) {
logline = substr(Log, 1, i-1)
if (logline ~ /[^'"$tab"' ]/) {
printf "%s%s\n", sep, logline
@ -410,6 +476,9 @@ printlogline='{
}
}'
# Pattern to match the `revision' line of rlog output.
rlog_revision_pattern='^revision [0-9]+\.[0-9]+(\.[0-9]+\.[0-9]+)*(['"$tab"' ]+locked by: [^'"$tab"' $,.0-9:;@]*[^'"$tab"' $,:;@][^'"$tab"' $,.0-9:;@]*;)?['"$tab"' ]*$'
case $hostname in
'')
hostname=`(
@ -433,7 +502,7 @@ 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.
# Transliterate \n to \001 so that multiline entries fit on a single line.
# Discard irrelevant rlog output.
$AWK <$rlogout '
BEGIN { repository = "'"$repository"'" }
@ -446,47 +515,66 @@ $AWK <$rlogout '
if (filename ~ /,v$/) {
filename = substr(filename, 1, length(filename) - 2)
}
if (filename ~ /(^|\/)Attic\/[^\/]*$/) {
i = length(filename)
while (substr(filename, i, 1) != "/") i--
filename = substr(filename, 1, i - 6) substr(filename, i + 1)
}
}
rev = "?"
}
/^Working file:/ { if (repository == "") filename = $3 }
/^date: /, /^(-----------*|===========*)$/ {
if ($0 ~ /^branches: /) { next }
if ($0 ~ /^date: [0-9][- +\/0-9:]*;/) {
/'"$rlog_revision_pattern"'/, /^(-----------*|===========*)$/ {
line = $0
if (line ~ /'"$rlog_revision_pattern"'/) {
rev = $2
next
}
if (line ~ /^date: [0-9][- +\/0-9:]*;/) {
date = $2
if (date ~ /-/) {
# An ISO format date. Replace all "-"s with "/"s.
if (date ~ /\//) {
# This is a traditional RCS format date YYYY/MM/DD.
# Replace "/"s with "-"s to get ISO format.
newdate = ""
while ((i = index(date, "-")) != 0) {
newdate = newdate substr(date, 1, i-1) "/"
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)
time = substr($3, 1, length($3) - 1)
author = substr($5, 1, length($5)-1)
printf "%s %s %s %s %c", filename, date, time, author, 13
printf "%s %s %s %s %s %c", filename, rev, date, time, author, 1
rev = "?"
next
}
if ($0 ~ /^(-----------*|===========*)$/) { print ""; next }
printf "%s%c", $0, 13
if (line ~ /^branches: /) { next }
if (line ~ /^(-----------*|===========*)$/) { print ""; next }
if (line == "Initial revision" || line ~ /^file .+ was initially added on branch .+\.$/) {
line = "New file."
}
printf "%s%c", line, 1
}
' |
# 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.
# FILENAME REVISION YYYY-MM-DD HH:MM:SS[+-TIMEZONE] AUTHOR \001LOG
# where \001 stands for a carriage return,
# and each line of the log is terminated by \001 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 |
# then by author, then by log entry, and finally by file name and revision
# (just in case).
sort +2 -4r +4 +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.
logTZ = "'"$logTZ"'"
revision = "'"$revision"'"
# Some awk variants do not understand "\001", so we have to
# put the char directly in the file.
SOH="" # <-- There is a single SOH (octal code 001) here.
# Initialize the fullname and mailaddr associative arrays.
'"$initialize_fullname"'
@ -500,28 +588,15 @@ $AWK '
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))
newlog = substr($0, 1 + index($0, SOH))
# Ignore log entries prefixed by "#".
if (newlog ~ /^#/) { next }
if (Log != newlog || date != $2 || author != $4) {
if (Log != newlog || date != $3 || author != $5) {
# The previous log and this log differ.
@ -552,33 +627,25 @@ $AWK '
filesknown[i] = 0
files = ""
}
if (date != $2 || author != $4) {
if (date != $3 || author != $5) {
# The previous date+author and this date+author differ.
# Print the new one.
date = $2
author = $4
date = $3
time = $4
author = $5
# 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
zone = ""
if (logTZ && ((i = index(time, "-")) || (i = index(time, "+"))))
zone = " " substr(time, i)
# Print "date fullname (email address)".
# Print "date[ timezone] 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
printf "%s%s %s ", date, zone, auth
if (mailaddr[author])
printf "<%s>\n\n", mailaddr[author]
else
@ -588,6 +655,7 @@ $AWK '
filesknown[$1] = 1
if (files == "") files = " " $1
else files = files ", " $1
if (revision && $2 != "?") files = files " " $2
}
}
END {
@ -603,3 +671,7 @@ $AWK '
# Exit successfully.
exec rm -f $llogout $rlogout
# Local Variables:
# tab-width:4
# End:

View File

@ -1,3 +1,70 @@
1999-05-06 Jim Kingdon <http://www.cyclic.com>
* Makefile.in (DISTFILES): Remove libdiff.mak.
* libdiff.mak: Removed; we are back to a single makefile for
Visual C++ version 4.
1999-04-29 Jim Kingdon <http://www.cyclic.com>
* diff.c (diff_run): Use separate statement for setjmp call and if
statement. This is better style in general (IMHO) but in the case
of setjmp the UNICOS compiler apparently cares (I don't have the
standard handy, but there are lots of legitimate restrictions on
how you can call setjmp).
1999-04-26 Jim Kingdon <http://www.cyclic.com>
* Makefile.in (DISTFILES): Add libdiff.dsp libdiff.mak .cvsignore.
1999-04-26 (submitted 1999-03-24) John O'Connor <john@shore.net>
* libdiff.dsp: new file. MSVC project file used to build the library.
* libdiff.mak: new file. Makefile for building from the command-line.
* .cvsignore: Removed un-used entries related to MSVC. Added
entries to ignore directories generated by the NT build, Debug
and Release.
1999-03-24 Larry Jones <larry.jones@sdrc.com>
and Olaf Brandes
* diff3.c (diff3_run): Use a separate stream for the input to
output_diff3_merge instead of reopening stdin to avoid problems
with leaving it open.
1999-02-17 Jim Kingdon <http://www.cyclic.com>
and Hallvard B Furuseth.
* util.c: Use __STDC__ consistently with ./system.h.
* system.h: Add comment about PARAMS.
1999-01-12 Jim Kingdon <http://www.cyclic.com>
* Makefile.in, analyze.c, cmpbuf.c, cmpbuf.h, context.c, diff.c,
diff.h, diff3.c, diffrun.h, dir.c, ed.c, io.c, normal.c, system.h,
util.c: Remove paragraph containing the old snail mail address of
the Free Software Foundation.
1998-09-21 Jim Kingdon <kingdon@harvey.cyclic.com>
* util.c (printf_output): Make msg static; avoids auto
initializer, which is not portable to SunOS4 /bin/cc.
Reported by Mike Sutton@SAIC.
1998-09-14 Jim Kingdon <kingdon@harvey.cyclic.com>
* Makefile.in (DISTFILES): Add diagmeet.note.
1998-08-15 Jim Kingdon <kingdon@harvey.cyclic.com>
* diffrun.h (struct diff_callbacks): Change calling convention of
write_output so that a zero length means to output zero bytes.
The cvs_output convention is just too ugly/error-prone.
* util.c (printf_output): Rewrite to parse format string
overselves rather than calling vasprintf, which cannot be
implemented in portable C.
1998-08-06 David Masterson of kla-tencor.com
* util.c (flush_output): Don't prototype.

View File

@ -12,10 +12,6 @@
# 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 DIFF; see the file COPYING. If not, write to
# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
#### Start of system configuration section. ####
@ -47,7 +43,8 @@ SOURCES = diff.c diff3.c analyze.c cmpbuf.c cmpbuf.h io.c context.c ed.c \
diffrun.h
OBJECTS = diff.o diff3.o analyze.o cmpbuf.o dir.o io.o util.o \
context.o ed.o ifdef.o normal.o side.o version.o
DISTFILES = $(SOURCES) ChangeLog build_diff.com Makefile.in
DISTFILES = $(SOURCES) ChangeLog build_diff.com Makefile.in diagmeet.note \
libdiff.dsp .cvsignore
all: libdiff.a

View File

@ -13,9 +13,7 @@ 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 DIFF; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
*/
/* The basic algorithm is described in:
"An O(ND) Difference Algorithm and its Variations", Eugene Myers,

View File

@ -11,9 +11,7 @@
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. */
*/
#include "system.h"
#include "cmpbuf.h"

View File

@ -13,8 +13,6 @@ 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 DIFF; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
*/
size_t buffer_lcm PARAMS((size_t, size_t));

View File

@ -13,9 +13,7 @@ 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 DIFF; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
*/
#include "diff.h"

View File

@ -13,9 +13,7 @@ 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 DIFF; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
*/
/* GNU DIFF was written by Mike Haertel, David Hayes,
Richard Stallman, Len Tower, and Paul Eggert. */
@ -690,7 +688,8 @@ diff_run (argc, argv, out, callbacks_arg)
/* Set the jump buffer, so that diff may abort execution without
terminating the process. */
if ((val = setjmp (diff_abort_buf)) != 0)
val = setjmp (diff_abort_buf);
if (val != 0)
{
optind = optind_old;
if (opened_file)

View File

@ -13,9 +13,7 @@ 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 DIFF; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
*/
#include "system.h"
#include <stdio.h>

View File

@ -11,9 +11,7 @@
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 Randy Smith */
/* Librarification by Tim Pierce */
@ -459,13 +457,15 @@ diff3_run (argc, argv, out, callbacks_arg)
tag_strings[0], tag_strings[1], tag_strings[2]);
else if (merge)
{
if (! freopen (file[rev_mapping[FILE0]], "r", stdin))
FILE *mfp = fopen (file[rev_mapping[FILE0]], "r");
if (! mfp)
diff3_perror_with_exit (file[rev_mapping[FILE0]]);
conflicts_found
= output_diff3_merge (stdin, diff3, mapping, rev_mapping,
conflicts_found = output_diff3_merge (mfp, diff3, mapping, rev_mapping,
tag_strings[0], tag_strings[1], tag_strings[2]);
if (ferror (stdin))
if (ferror (mfp))
diff3_fatal ("read error");
if (fclose(mfp) != 0)
perror_with_name (file[rev_mapping[FILE0]]);
}
else
{

View File

@ -13,9 +13,7 @@ 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 DIFF; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
*/
#ifndef DIFFRUN_H
#define DIFFRUN_H
@ -41,12 +39,14 @@ struct diff_callbacks
{
/* Write output. This function just writes a string of a given
length to the output file. The default is to fwrite to OUTFILE.
If this callback is defined, flush_output must also be defined. */
If this callback is defined, flush_output must also be defined.
If the length is zero, output zero bytes. */
void (*write_output) DIFFPARAMS((char const *, size_t));
/* Flush output. The default is to fflush OUTFILE. If this
callback is defined, write_output must also be defined. */
void (*flush_output) DIFFPARAMS((void));
/* Write to stdout. This is called for version and help messages. */
/* Write a '\0'-terminated string to stdout.
This is called for version and help messages. */
void (*write_stdout) DIFFPARAMS((char const *));
/* Print an error message. The first argument is a printf format,
and the next two are parameters. The default is to print a

View File

@ -13,9 +13,7 @@ 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 DIFF; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
*/
#include "diff.h"

View File

@ -13,9 +13,7 @@ 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 DIFF; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
*/
#include "diff.h"

View File

@ -13,9 +13,7 @@ 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 DIFF; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
*/
#include "diff.h"

View File

@ -13,9 +13,7 @@ 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 DIFF; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
*/
#include "diff.h"

View File

@ -13,9 +13,7 @@ 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 DIFF; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
*/
/* We must define `volatile' and `const' first (the latter inside config.h),
so that they're used consistently in all system includes. */
@ -29,6 +27,9 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <sys/types.h>
#include <sys/stat.h>
/* Note that PARAMS is just internal to the diff library; diffrun.h
has its own mechanism, which will hopefully be less likely to
conflict with the library's caller's namespace. */
#if __STDC__
#define PARAMS(args) args
#define VOID void

View File

@ -13,13 +13,11 @@ 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 DIFF; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
*/
#include "diff.h"
#ifdef __STDC__
#if __STDC__
#include <stdarg.h>
#else
#include <varargs.h>
@ -340,14 +338,14 @@ write_output (text, len)
/* Printf something to the output file. */
#ifdef __STDC__
#if __STDC__
#define VA_START(args, lastarg) va_start(args, lastarg)
#else /* ! __STDC__ */
#define VA_START(args, lastarg) va_start(args)
#endif /* __STDC__ */
void
#if defined (__STDC__)
#if __STDC__
printf_output (const char *format, ...)
#else
printf_output (format, va_alist)
@ -360,17 +358,51 @@ printf_output (format, va_alist)
VA_START (args, format);
if (callbacks && callbacks->write_output)
{
char *p;
/* We implement our own limited printf-like functionality (%s, %d,
and %c only). Callers who want something fancier can use
sprintf. */
const char *p = format;
char *q;
char *str;
int num;
int ch;
unsigned char buf[100];
p = NULL;
vasprintf (&p, format, args);
if (p == NULL)
fatal ("out of memory");
while ((q = strchr (p, '%')) != NULL)
{
static const char msg[] =
"\ninternal error: bad % in printf_output\n";
(*callbacks->write_output) (p, q - p);
switch (q[1])
{
case 's':
str = va_arg (args, char *);
(*callbacks->write_output) (str, strlen (str));
break;
case 'd':
num = va_arg (args, int);
sprintf (buf, "%d", num);
(*callbacks->write_output) (buf, strlen (buf));
break;
case 'c':
ch = va_arg (args, int);
buf[0] = ch;
(*callbacks->write_output) (buf, 1);
break;
default:
(*callbacks->write_output) (msg, sizeof (msg) - 1);
/* Don't just keep going, because q + 1 might point to the
terminating '\0'. */
goto out;
}
p = q + 2;
}
(*callbacks->write_output) (p, strlen (p));
free (p);
}
else
vfprintf (outfile, format, args);
out:
va_end (args);
}

View File

@ -1,3 +1,420 @@
1999-07-16 Tom Tromey <tromey@cygnus.com>
* cvs.texinfo (admin): Mention admin -k exception. Add cvsadmin
to index.
1999-07-14 Larry Jones <larry.jones@sdrc.com>
* cvs.texinfo (Password authentication server): Note inetd limits
and suggest using shell script to avoid.
1999-06-01 Jim Kingdon <http://www.cyclic.com>
* cvsclient.texi (Requests): For the import command, the
repository given to the Directory requests is ignored.
1999-05-27 Jim Kingdon <http://www.cyclic.com>
* cvsclient.texi (Requests): Clarify that Modified, Is-modified,
Notify and Unchanged must specify a file within the current
directory.
1999-05-24 Jim Kingdon <http://www.cyclic.com>
* cvs.texinfo (checkoutlist): New node, contains more complete
documentation of this feature.
(CVSROOT storage): Refer to the new node when mentioning
checkoutlist.
(Administrative files): Update the menu entry for Wrappers.
1999-05-17 Jim Kingdon <http://www.cyclic.com>
* cvsclient.texi (Requests): For Notify request, strike duplicate
"Response expected: no" and fix "a edit" -> "an edit".
1999-05-14 Jim Kingdon <http://www.cyclic.com>
* cvs.texinfo (Working directory storage): Try to be more clear
about the conflict field.
1999-05-11 Jim Kingdon <http://www.cyclic.com>
* cvs.texinfo (config): Use comma after @xref (thanks to Pavel
Roskin for the report/fix).
1999-05-10 Jim Kingdon <http://www.cyclic.com>
* cvsclient.texi (Requests): Document restrictions on characters
in Notify requests.
1999-05-04 Jim Kingdon <http://www.cyclic.com>
* cvs.texinfo (Password authentication security): Remove sentence
about how no one has audited pserver for holes; a lot of holes
have been closed, looking for, &c, since that was written.
In the summary, reword to reflect the fact that sniffing a
readonly password does not imply general system access (as far as
I know, of course).
* cvs.texinfo (Connection): Also suggest inetd -d.
1999-04-28 Jim Kingdon <http://www.cyclic.com>
* cvsclient.texi (Requests): Say what goes in the "watches" field
of the "Notify" request.
* cvs.texinfo (Common options): -r is for branches too.
* cvs.texinfo (Error messages): Add "no such tag" message.
(Common options): -f does not override val-tags check.
1999-04-26 Jim Kingdon <http://www.cyclic.com>
* cvs.texinfo (Locks): #cvs.rfl locks must start with "#cvs.rfl."
not just "#cvs.rfl". As far as I know CVS has always implemented
the former behavior, and this just fixes the documentation.
1999-04-23 Yoshiki Hayashi of u-tokyo.ac.jp
* cvs.texinfo (verifymsg): Correct wrong file name (bugid.edit ->
bugid.verify).
1999-04-22 Jim Kingdon <http://www.cyclic.com>
* cvsclient.texi (Responses): The text in the "M" response is not
designed for machine parsing. Likewise for "error" in regular
protocol. Likewise for "E" and "error" in authentication protocol.
1999-04-19 Jim Kingdon <http://www.cyclic.com>
* cvs.texinfo (Error messages): Add "Cannot check out files into
the repository itself".
1999-04-16 Jim Kingdon <http://www.cyclic.com>
* cvs.texinfo (Other problems): Add the Windows problem with home
directory ending in a slash.
1999-04-14 Jim Kingdon <http://www.cyclic.com>
* cvs.texinfo (CVS in repository): Include the format of the
fileattr file here, rather than referring to the CVS source code.
1999-04-09 Jim Kingdon <http://www.cyclic.com>
* cvs.texinfo (Working directory storage): Whether the timestamp
in CVS/Entries is local or universal actually depends on the system.
1999-04-05 Derek Price
<http://www-personal.engin.umich.edu/~oberon/resume.html>
* cvs.texinfo (export options): Remove notation that the -r
tag is sticky. 'cvs export' doesn't store that data.
1999-04-08 Jim Kingdon <http://www.cyclic.com>
* cvs.texinfo (Error messages): Add "EOF in RCS file" and
"unexpected EOF" (in RCS file) messages.
1999-03-25 Jim Kingdon <http://www.cyclic.com>
* cvs.texinfo (admin options): Say there can be no space between
-e and its argument (since the previous sentence said the argument
can be omitted, this is the only possibility).
1999-02-26 Jim Kingdon <http://www.cyclic.com>
* cvs.texinfo (Merging and keywords): When including conflict
markers, put @asis{} at the start of the line, in case this file
itself is in CVS. Thanks to Derek Price for pointing this out.
1999-02-25 Jim Kingdon <http://www.cyclic.com>
* cvs.texinfo: Refer to "keywords" not "RCS keywords". We had
only used the latter term in a few places, and it seems like a
somewhat odd term in that this style of keyword is by no means
specific to RCS.
(Merging a branch): Remove spurious ")". Use ref, not xref, after
"see".
(Merging a branch, Substitution modes): Make sure that @ref is
followed by comma, since info wants that.
(Merging and keywords): Use samp not code for "-kk". Something of
a judgement call, but the rest of the manual uses samp and that
seems better to me.
(Merging and keywords): Rewrite, to (a) better motivate the
discussion based on what the user wants to do, (b) fix up lots of
convoluted sentences, (c) move the discussion of the binary files
to the end, that is get across the basic idea first and then
embellish it. Remove a few unnecessary index entries. Expand
example. Just tell people to avoid -kk with binary files (comment
out the discussion of using -A after the commit).
1999-01-29 Derek Price
<http://www-personal.engin.umich.edu/~oberon/resume.html>
* cvs.texinfo: Added new node/section on merging and keywords. It
contains advice on how to avoid RCS keyword conflicts when merging
and avoid corrupting your binary files while doing it.
1999-02-24 Jim Kingdon <http://www.cyclic.com>
* cvsclient.texi (Request intro): Add paragraph about transmitting
more than one command.
1999-01-29 Jim Kingdon <http://www.cyclic.com>
* cvs.texinfo: Use EXAMPLE.COM EXAMPLE.ORG and EXAMPLE.NET instead
of domains which might conflict with actual (current or future)
domains. The EXAMPLE domains are registered for this purpose.
1999-01-22 Jim Kingdon <http://www.cyclic.com>
* cvs.texinfo (Sticky tags): Refer to -j as the better way to undo
a change.
(Merging two revisions): Also talk about undoing removals and
adds. Move the index entries to here.
1999-01-21 Jim Kingdon <http://www.cyclic.com>
* cvs.texinfo (Error messages): Add "waiting for USER's lock".
1999-01-16 Jim Kingdon <http://www.cyclic.com>
* cvs.texinfo (Wrappers): Comment out all the -t/-f documentation,
since that feature is currently disabled.
1999-01-14 Jim Kingdon <http://www.cyclic.com>
* cvs.texinfo (Connecting via rsh): Add some more index entries so
that people who want to use SSH and such are slightly less lost.
1999-01-12 Jim Kingdon <http://www.cyclic.com>
* cvs-paper.ms: Remove comments which contained the FSF's old
address; it has changed.
1998-12-29 Jim Kingdon <http://www.cyclic.com>
* cvsclient.texi (Dates): Numeric timezones are preferred.
Also mention the Checkin-time request.
1998-12-23 Jim Kingdon <http://www.cyclic.com>
* RCSFILES: Add clarification about certain character set issues
from Paul Eggert, the RCS maintainer. The last paragraph and the
change from Shift-JIS to JIS as an example of a character set
which contains 0x40 bytes which are not '@' characters are mine;
the rest is directly from Paul Eggert.
1998-12-22 Martin Buchholz <martin@xemacs.org>
* cvs.texinfo: Fixed various trivial typos.
1998-12-17 Jim Kingdon
* cvsclient.texi (Responses): Explicitly say that Mod-time need
not be sent for all files.
1998-12-16 Jim Kingdon
Thanks to Ram Rajadhyaksha of the MacCVS Pro team for raising the
following issues.
* cvs.texinfo (Working directory storage): The deal about storing
files as text files applies to all the CVS/* files, not just
CVS/Entries. State the rationale too.
Document CVSROOT/Emptydir in CVS/Repository.
There is no set order in CVS/Entries.
Explicitly say that writing Entries.Log is optional.
1998-12-03 Jim Kingdon
* cvs.texinfo (Error messages): Add "unrecognized auth response".
(Password authentication server): Remove comment about
"unrecognized auth response" and link to the troubleshooting
section.
1998-12-02 Jim Kingdon
* cvs.texinfo (Multiple repositories): Add an example.
1998-11-18 Jim Kingdon
* cvs.texinfo (Invoking CVS): Change "-r tag" to "-r rev". We
already use "tag" as the name of the tag we are adding.
1998-11-13 Jim Kingdon
* cvs.texinfo (CVS commands): Add comment about whether part of
the manual should be organized by command.
1998-11-06 Jim Kingdon
Clean up various confusions between modules and directories:
* cvs.texinfo: In "are you sure you want to release" message,
change module to directory. CVS was changed some time ago.
(Tags): "working copy of the module" -> "working directory".
(Merging two revisions): Remove unnecessary text "that make up a
module".
(Recursive behavior): Change "module" to "directory".
(Removing files): Likewise.
(Tracking sources): Remove "a module" from titles.
(Moving directories): Change "module" to "parent-dir".
(Inside): Remove "of the module".
(Inside): Change "module" to "dir".
(Rename by copying): Change "module" to "dir".
(Rename by copying): Remove "of the module".
(Moving directories): "copy of the module" -> "checked out copy of
the directory"; remove second "of the module". Change "check out
the module" to " check out again".
(Moving directories): Remove "of the module".
(Keyword substitution): "your working copy of a module" -> "a
working directory".
(CVS commands): Change "module" to "directory".
(release examples): "module" -> "tc directory".
(commitinfo): "relative path to the module" -> "directory in the
repository".
(verifymsg): Change "module" to "directory".
(Updating a file): "working copy of a module" -> "working directory".
1998-10-25 Jim Kingdon
* cvs.texinfo (Branches and revisions): Fix error in branch
numbering which was introduced with change of 4 May 1997.
1998-10-20 Jim Kingdon
* cvs.texinfo (Tags): Point to Invoking CVS node so people aren't
left wondering what the syntax is. When introducing -r option,
warn people about sticky tags right off.
(Tagging the working directory, Tagging by date/tag, Modifying
tags, Tagging add/remove): New sections.
(Invoking CVS): Adjust tag and rtag to point to the new sections,
and to add tag -c which had been omitted. Delete tag -n; there is
no such option.
(rtag, tag): Removed; no longer needed.
(commit examples): Update xref.
1998-10-15 Jim Kingdon
* cvsclient.texi (Requests): It is OK to send Set before Root.
1998-10-13 Jim Kingdon
* cvsclient.texi (Protocol Notes): Remove item about "cvs update"
sending modified files to the server; there are some better ideas
at http://www.cyclic.com/cvs/dev-update.txt
Add mention of www.cyclic.com.
1998-09-30 Jim Kingdon <kingdon@harvey.cyclic.com>
* cvs.texinfo (Committing your changes, Environment variables):
Document VISUAL.
1998-09-27 Jim Kingdon <kingdon@harvey.cyclic.com>
* cvs.texinfo (Password authentication server): Say explicitly
that you edit passwd directly, many users get confused by this.
1998-09-24 Jim Kingdon <kingdon@harvey.cyclic.com>
* cvs.texinfo (Connecting via fork): :fork: may be of interest to
users, for example those who prefer CVS to prompt for one log
message per checkin, rather than one per directory.
(Connecting via fork): Document CVS_SERVER.
1998-09-24 Noel Cragg <noel@swish.red-bean.com>
* cvs.texinfo (Connecting via fork): new node about the fork
access method.
1998-09-22 Jim Kingdon <kingdon@harvey.cyclic.com>
* cvs.texinfo (Environment variables): Document
CVS_IGNORE_REMOTE_ROOT in the CVS 1.10 context.
(Moving a repository): Update comments concerning surgery on
CVS/Root and CVS/Repository files.
1998-09-21 Noel Cragg <noel@swish.red-bean.com>
* cvs.texinfo (Environment variables): remove information about
CVS_IGNORE_REMOTE_ROOT, since it's no longer used.
1998-09-21 Jim Kingdon <kingdon@harvey.cyclic.com>
* cvs.texinfo (config): Mention that CVS 1.10 doesn't have
LockDir.
1998-09-18 Jim Kingdon <kingdon@harvey.cyclic.com>
* cvs.texinfo (Keyword list): Describe $Name and checking out with
a revision.
1998-09-16 Jim Kingdon <kingdon@harvey.cyclic.com>
* cvs.texinfo: RFC2346 is out; update comment.
1998-09-13 Jim Kingdon <kingdon@harvey.cyclic.com>
* cvs.texinfo (Keyword list, Substitution modes): In describing
$Locker and -kkvl, refer to cvs admin -l.
* cvsclient.texi (Requests): Re-word description of Sticky to
allow room for "Ntagname" (or other, future, values).
* cvs.texinfo (tag): Remove confusing wording about supplying
revision numbers "implicitly".
1998-09-10 Jim Kingdon <kingdon@harvey.cyclic.com>
* cvs.texinfo (rdiff options): Thanks to the diff library, -u is
supported regardless of your diff program.
1998-09-07 Jim Kingdon <kingdon@harvey.cyclic.com>
* cvs.texinfo (config): Add LockDir.
1998-09-01 Jim Kingdon <kingdon@harvey.cyclic.com>
* cvsclient.texi (Requests): "Directory" and "Argument" are
requests, not commands. Likewise for "other-request". A command,
roughly, is a request that uses "Argument"s, but we might want to
phase out the use of that term more so than codify it, I'm not sure.
1998-09-01 Noel Cragg <noel@swish.red-bean.com>
* cvsclient.texi (Requests): added a detailed explanation of the
Directory request and how it is handled, both for pre-1.10 and
post-1.10 servers.
1998-09-01 Jim Kingdon <kingdon@harvey.cyclic.com>
* cvs.texinfo (Multiple repositories): Also describe the CVS 1.10
behavior. Looking at a mismatched version of the manual seems to
be a reasonably common occurrence.
* cvs.texinfo (Environment variables): Revert change regarding
CVS_SERVER_SLEEP*; having that kind of debugging code in the main
CVS is getting out of hand.
1998-09-01 Noel Cragg <noel@swish.red-bean.com>
* cvs.texinfo (Multiple repositories): brief mention that cvs now
handles a working directory composed of multiple repositories.
(Environment variables): add note about CVS_SERVER_SLEEP2.
1998-08-21 Ian Lance Taylor <ian@cygnus.com>
* cvsclient.texi (Text tags): Document importmergecmd tag.
1998-08-20 Jim Kingdon <kingdon@harvey.cyclic.com>
* cvs.texinfo (Common options): Replace out of date URL concerning
ISO8601 dates with a more general statement and a few comments.
1998-08-18 Jim Kingdon <kingdon@harvey.cyclic.com>
* cvsclient.texi (Requests): Add "Checkin-time" request.
Sun Jul 26 02:42:20 1998 Noel Cragg <noel@swish.red-bean.com>
* cvs.texinfo (config): TopLevelAdmin variable.

View File

@ -136,6 +136,36 @@ Both RCS 5.7 and current versions of CVS handle the $Log keyword in a
different way if the log message starts with "checked in with -k by ".
I don't think this behavior is documented anywhere.
Here is a clarification regarding characters versus bytes in certain
character sets like JIS and Big5:
The RCS file format, as described in the rcsfile(5) man page, is
actually byte-oriented, not character-oriented, despite hints to
the contrary in the man page. This distinction is important for
multibyte characters. For example, if a multibyte character
contains a `@' byte, the `@' must be doubled within strings in RCS
files, since RCS uses `@' bytes as escapes.
This point is not an issue for encodings like ISO 8859, which do
not have multibyte characters. Nor is it an issue for encodings
like UTF-8 and EUC-JIS, which never uses ASCII bytes within a
multibyte character. It is an issue only for multibyte encodings
like JIS and BIG5, which _do_ usurp ASCII bytes.
If `@' doubling occurs within a multibyte char, the resulting RCS
file is not a properly encoded text file. Instead, it is a byte
stream that does not use a consistent character encoding that can
be understood by the usual text tools, since doubling `@' messes
up the encoding. This point affects only programs that examine
the RCS files -- it doesn't affect the external RCS interface, as
the RCS commands always give you the properly encoded text files
and logs (assuming that you always check in properly encoded
text).
CVS 1.10 (and earlier) probably has some bugs in this area on
systems where a C "char" is signed and where the data contains
bytes with the eighth bit set.
One common concern about the RCS file format is the fact that to get
the head of a branch, one must apply deltas from the head of the trunk
to the branchpoint, and then from the branchpoint to the head of the

View File

@ -14,10 +14,6 @@
.\" 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

File diff suppressed because it is too large Load Diff

View File

@ -217,6 +217,10 @@ The @var{text} should be supplied to the
user. Compatibility note: @sc{cvs} 1.9.10 and older clients will print
@code{unrecognized auth response} and @var{text}, and then exit, upon
receiving this response.
Note that @var{text} for this response, or the @var{text} in an @code{E}
response, is not designed for machine parsing. More vigorous use of
@var{code}, or future extensions, will be needed to prove a cleaner
machine-parseable indication of what the error was.
@end table
@c If you are thinking of putting samp or code around BEGIN AUTH REQUEST
@ -479,7 +483,7 @@ For the @samp{-D} option to the @code{annotate}, @code{co}, @code{diff},
and @code{update} requests, the server should support two formats:
@example
26 May 1997 13:01:40 GMT ; @r{RFC 822 as modified by RFC 1123}
26 May 1997 13:01:40 -0000 ; @r{RFC 822 as modified by RFC 1123}
5/26/1997 13:01:40 GMT ; @r{traditional}
@end example
@ -491,7 +495,9 @@ least support RFC 822/1123 format. Clients are encouraged to use this
format too (traditionally the command line CVS client has just passed
along the date format specified by the user, however).
For @code{Mod-time}, see the description of that response.
The @code{Mod-time} response and @code{Checkin-time} request use RFC
822/1123 format (see the descriptions of that response and request for
details).
For @code{Notify}, see the description of that request.
@ -504,6 +510,16 @@ exception is @samp{gzip-file-contents}. Unrecognized requests will
always elicit a response from the server, even if that request begins
with a capital letter.
The term @dfn{command} means a request which expects a response (except
@code{valid-requests}). The general model is that the client transmits
a great number of requests, but nothing happens until the very end when
the client transmits a command. Although the intention is that
transmitting several commands in one connection should be legal,
existing servers probably have some bugs with some combinations of more
than one command, and so clients may find it necessary to make several
connections in some cases. This should be thought of as a workaround
rather than a desired attribute of the protocol.
@node Requests
@section Requests
@ -521,7 +537,7 @@ in use, connection, authentication, etc., are already taken care of.
The @code{Root} request must be sent only once, and it must be sent
before any requests other than @code{Valid-responses},
@code{valid-requests}, @code{UseUnchanged}, or @code{init}.
@code{valid-requests}, @code{UseUnchanged}, @code{Set} or @code{init}.
@item Valid-responses @var{request-list} \n
Response expected: no.
@ -606,6 +622,99 @@ Each @code{Directory} request specifies a brand-new
@var{local-directory} and @var{repository} are never relative to paths
specified in any previous @code{Directory} request.
Here's a more complex example, in which we request an update of a
working directory which has been checked out from multiple places in the
repository.
@example
C: Argument dir1
C: Directory dir1
C: /home/foo/repos/mod1
. . .
C: Argument dir2
C: Directory dir2
C: /home/foo/repos/mod2
. . .
C: Argument dir3
C: Directory dir3/subdir3
C: /home/foo/repos/mod3
. . .
C: update
@end example
While directories @code{dir1} and @code{dir2} will be handled in similar
fashion to the other examples given above, @code{dir3} is slightly
different from the server's standpoint. Notice that module @code{mod3}
is actually checked out into @code{dir3/subdir3}, meaning that directory
@code{dir3} is either empty or does not contain data checked out from
this repository.
The above example will work correctly in @sc{cvs} 1.10.1 and later. The
server will descend the tree starting from all directories mentioned in
@code{Argument} requests and update those directories specifically
mentioned in @code{Directory} requests.
Previous versions of @sc{cvs} (1.10 and earlier) do not behave the same
way. While the descent of the tree begins at all directories mentioned
in @code{Argument} requests, descent into subdirectories only occurs if
a directory has been mentioned in a @code{Directory} request.
Therefore, the above example would succeed in updating @code{dir1} and
@code{dir2}, but would skip @code{dir3} because that directory was not
specifically mentioned in a @code{Directory} request. A functional
version of the above that would run on a 1.10 or earlier server is as
follows:
@example
C: Argument dir1
C: Directory dir1
C: /home/foo/repos/mod1
. . .
C: Argument dir2
C: Directory dir2
C: /home/foo/repos/mod2
. . .
C: Argument dir3
C: Directory dir3
C: /home/foo/repos/.
. . .
C: Directory dir3/subdir3
C: /home/foo/repos/mod3
. . .
C: update
@end example
Note the extra @code{Directory dir3} request. It might be better to use
@code{Emptydir} as the repository for the @code{dir3} directory, but the
above will certainly work.
One more peculiarity of the 1.10 and earlier protocol is the ordering of
@code{Directory} arguments. In order for a subdirectory to be
registered correctly for descent by the recursion processor, its parent
must be sent first. For example, the following would not work to update
@code{dir3/subdir3}:
@example
. . .
C: Argument dir3
C: Directory dir3/subdir3
C: /home/foo/repos/mod3
. . .
C: Directory dir3
C: /home/foo/repos/.
. . .
C: update
@end example
The implementation of the server in 1.10 and earlier writes the
administration files for a given directory at the time of the
@code{Directory} request. It also tries to register the directory with
its parent to mark it for recursion. In the above example, at the time
@code{dir3/subdir3} is created, the physical directory for @code{dir3}
will be created on disk, but the administration files will not have been
created. Therefore, when the server tries to register
@code{dir3/subdir3} for recursion, the operation will silently fail
because the administration files do not yet exist for @code{dir3}.
@item Max-dotdot @var{level} \n
Response expected: no.
Tell the server that @var{level} levels of directories above the
@ -627,9 +736,10 @@ responses.
@item Sticky @var{tagspec} \n
Response expected: no. Tell the server that the directory most recently
specified with @code{Directory} 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.
The first character of @var{tagspec} is @samp{T} for a tag, @samp{D}
for a date, or some other character supplied by a Set-sticky response
from a previous request to the server. The remainder of @var{tagspec}
contains the actual tag or date, again as supplied by Set-sticky.
The server should remember @code{Static-directory} and @code{Sticky}
requests for a particular directory; the client need not resend them
@ -672,10 +782,34 @@ Typically this will be a file being added via an @code{add} or
@code{import} request. The client may not send both @code{Kopt} and
@code{Entry} for the same file.
@item Checkin-time @var{time} \n
For the file specified by the next @code{Modified} request, use
@var{time} as the time of the checkin. The @var{time} is in the format
specified by RFC822 as modified by RFC1123. The client may specify any
timezone it chooses; servers will want to convert that to their own
timezone as appropriate. An example of this format is:
@example
26 May 1997 13:01:40 -0400
@end example
There is no requirement that the client and server clocks be
synchronized. The client just sends its recommendation for a timestamp
(based on file timestamps or whatever), and the server should just believe
it (this means that the time might be in the future, for example).
Note that this is not a general-purpose way to tell the server about the
timestamp of a file; that would be a separate request (if there are
servers which can maintain timestamp and time of checkin separately).
This request should affect the @code{import} request, and may optionally
affect the @code{ci} request or other relevant requests if any.
@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{Directory}. If
a file within the most recent directory sent with @code{Directory}; it
must not contain @samp{/}. 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.
@ -717,8 +851,9 @@ investigation, the more conservative course of action is to stick to
@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{Directory}.
modified in the checked out directory. The @var{filename} is
a file within the most recent directory sent with @code{Directory}; it
must not contain @samp{/}.
@item UseUnchanged \n
Response expected: no. To specify the version of the protocol described
@ -727,10 +862,13 @@ not do anything) and clients must issue it.
@item Notify @var{filename} \n
Response expected: no.
Tell the server that a @code{edit} or @code{unedit} command has taken
Tell the server that an @code{edit} or @code{unedit} command has taken
place. The server needs to send a @code{Notified} response, but such
response is deferred until the next time that the server is sending
responses. Response expected: no. Additional data:
responses.
The @var{filename} is a file within the most recent directory sent with
@code{Directory}; it must not contain @samp{/}.
Additional data:
@example
@var{notification-type} \t @var{time} \t @var{clienthost} \t
@var{working-dir} \t @var{watches} \n
@ -748,9 +886,17 @@ time as an opaque string rather than interpreting it).
@var{clienthost} is the name of the host on which the edit or unedit
took place, and @var{working-dir} is the pathname of the working
directory where the edit or unedit took place. @var{watches} are the
temporary watches to set. If @var{watches} is followed by \t then the
temporary watches, zero or more of the following characters in the
following order: @samp{E} for edit, @samp{U} for unedit, @samp{C} for
commit, and all other letters should be silently ignored for future
expansion. If @var{notification-type} is @samp{E} the temporary watches
are set; if it is @samp{U} they are cleared.
If @var{watches} is followed by \t then the
\t and the rest of the line should be ignored, for future expansion.
The @var{time}, @var{clienthost}, and @var{working-dir} fields may not
contain the characters @samp{+}, @samp{,}, @samp{>}, @samp{;}, or @samp{=}.
Note that a client may be capable of performing an @code{edit} or
@code{unedit} operation without connecting to the server at that time,
and instead connecting to the server when it is convenient (for example,
@ -982,7 +1128,9 @@ Response expected: yes. Actually do a @code{cvs import} command. This
uses any previous @code{Argument}, @code{Directory}, @code{Entry}, or
@code{Modified} requests, if they have been sent. The
last @code{Directory} sent specifies the working directory at the time
of the operation. The files to be imported are sent in @code{Modified}
of the operation - unlike most commands, the repository field of each
@code{Directory} request is ignored (it merely must point somewhere
within the root). The files to be imported are sent in @code{Modified}
requests (files which the client knows should be ignored are not sent;
the server must still process the CVSROOT/cvsignore file unless -I ! is
sent). A log message must have been specified with a @code{-m}
@ -1134,7 +1282,7 @@ 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.
a previous request which doesn't expect a response produced an error.
@end table
When the client is done, it drops the connection.
@ -1330,6 +1478,11 @@ synchronized. The server just sends its recommendation for a timestamp
(based on its own clock, presumably), and the client should just believe
it (this means that the time might be in the future, for example).
If the server does not send @code{Mod-time} for a given file, the client
should pick a modification time in the usual way (usually, just let the
operating system set the modification time to the time that the CVS
command is running).
@item Checksum @var{checksum}\n
The @var{checksum} applies to the next file sent (that is,
@code{Checksum} is a file update modifying response
@ -1433,6 +1586,13 @@ extending this one, for graceful handling of @code{Valid-responses}).
@item M @var{text} \n
A one-line message for the user.
Note that the format of @var{text} is not designed for machine parsing.
Although sometimes scripts and clients will have little choice, the
exact text which is output is subject to vary at the discretion of the
server and the example output given in this document is just that,
example output. Servers are encouraged to use the @samp{MT} response,
and future versions of this document will hopefully standardize more of
the @samp{MT} tags; see @ref{Text tags}.
@item Mbinary \n
Additional data: file transmission (note: compressed file transmissions
@ -1530,6 +1690,12 @@ 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.
The @var{text} is like the @code{M} response, in the sense that it is
not particularly intended to be machine-parsed; servers may wish to
print an error message with @code{MT} responses, and then issue a
@code{error} response without @var{text} (although it should be noted
that @code{MT} currently has no way of flagging the output as intended
for standard error, the way that the @code{E} response does).
@item ok \n
The command completed successfully.
@ -1564,6 +1730,23 @@ MT fname @var{name}
MT -updated
@end example
The @code{importmergecmd} tag is used when doing an import which has
conflicts. The client can use it to report how to merge in the newly
imported changes. The @var{count} is the number of conflicts. The
newly imported changes can be merged by running the following command:
@smallexample
cvs checkout -j @var{tag1} -j @var{tag2} @var{repository}
@end smallexample
@example
MT +importmergecmd
MT conflicts @var{count}
MT mergetag1 @var{tag1}
MT mergetag2 @var{tag2}
MT repository @var{repository}
MT -importmergecmd
@end example
@node Example
@section Example
@ -1751,6 +1934,8 @@ working directory, and the meaning of sending @code{Entries} without
A number of enhancements are possible. Also see the file @sc{todo} in
the @sc{cvs} source distribution, which has further ideas concerning
various aspects of @sc{cvs}, some of which impact the protocol.
Similarly, the @code{http://www.cyclic.com} site, in particular the
@cite{Development of CVS} page.
@itemize @bullet
@item
@ -1761,18 +1946,6 @@ of "cvs edit" in this case is the most sensible course (the "cvs edit"
could be handled by a package like VC for emacs). This would also allow
local operation of @code{cvs diff} without arguments.
@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 there is a multisite
capability (as noted in @sc{todo}), and therefore the rcsmerge can be
done with a repository which is connected via a fast connection.
@item
The fact that @code{pserver} requires an extra network turnaround in
order to perform authentication would be nice to avoid. This relates to

View File

@ -1,3 +1,45 @@
1999-03-26 Jim Kingdon <http://www.cyclic.com>
* getopt.h: Don't declare the arguments to getopt.
1999-02-09 Jim Kingdon <http://www.cyclic.com>
* vasprintf.c: Removed; there is apparently no clean, portable
solution to the VA_LIST_IS_ARRAY problem (C9X drafts have va_copy,
but we aren't even assuming C90 yet!).
* Makefile.in (SOURCES): Remove vasprintf.c.
* build_lib.com: Remove vasprintf.c and vasprintf.obj.
1999-01-26 Jim Kingdon <http://www.cyclic.com>
and Joerg Bullmann <http://www.glink.net.hk/~jb/MacCVSClient/>
* fnmatch.c: Use FOLD_FN_CHAR in two cases where it had been
omitted.
1999-01-22 Jim Kingdon <http://www.cyclic.com>
* fnmatch.c: Include system.h; FOLD_FN_CHAR has moved there from
config.h (from Alexey Milov). Don't define our own FOLD_FN_CHAR;
that just masks cases in which we got the includes tangled up.
1999-01-12 Jim Kingdon <http://www.cyclic.com>
* memmove.c: Remove paragraph which contained the FSF's old
snail mail address; it has changed.
1999-01-05 Jim Kingdon <http://www.cyclic.com>
* md5.c, md5.h: Rename all the external interfaces to start with
cvs_* to avoid namespace pollution problems. Include string.h
unconditionally, to avoid gcc -Wall warnings on memset.
1998-12-29 Jim Kingdon <http://www.cyclic.com>
* getdate.y (RelativeMonth): Add 1900 to tm_year, so that in 2000,
we pass 2000, not 100, to Convert.
(Convert): Add comment about Year argument.
* getdate.c: Regenerated using byacc.
Tue Mar 24 16:08:00 1998 Ian Lance Taylor <ian@cygnus.com>
* Makefile.in (CFLAGS): Set to @CFLAGS@, not -g.

View File

@ -46,7 +46,6 @@ SOURCES = \
stripslash.c \
strtoul.c \
valloc.c \
vasprintf.c \
waitpid.c \
xgetwd.c \
yesno.c

View File

@ -18,14 +18,7 @@ Library General Public License for more details. */
#include "config.h"
#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)
#endif
#include "system.h"
/* IGNORE(@ */
/* #include <ansidecl.h> */
@ -75,7 +68,7 @@ fnmatch (pattern, string, flags)
case '\\':
if (!(flags & FNM_NOESCAPE))
c = *p++;
if (*n != c)
if (FOLD_FN_CHAR (*n) != FOLD_FN_CHAR (c))
return FNM_NOMATCH;
break;
@ -95,7 +88,7 @@ fnmatch (pattern, string, flags)
{
char c1 = (!(flags & FNM_NOESCAPE) && c == '\\') ? *p : c;
for (--p; *n != '\0'; ++n)
if ((c == '[' || *n == c1) &&
if ((c == '[' || FOLD_FN_CHAR (*n) == FOLD_FN_CHAR (c1)) &&
fnmatch(p, n, flags & ~FNM_PERIOD) == 0)
return 0;
return FNM_NOMATCH;

View File

@ -619,6 +619,10 @@ ToSeconds(Hours, Minutes, Seconds, Meridian)
}
/* Year is either
* A negative number, which means to use its absolute value (why?)
* A number from 0 to 99, which means a year from 1900 to 1999, or
* The actual year (>=100). */
static time_t
Convert(Month, Day, Year, Hours, Minutes, Seconds, Meridian, DSTmode)
time_t Month;
@ -710,7 +714,7 @@ RelativeMonth(Start, RelMonth)
if (RelMonth == 0)
return 0;
tm = localtime(&Start);
Month = 12 * tm->tm_year + tm->tm_mon + RelMonth;
Month = 12 * (tm->tm_year + 1900) + tm->tm_mon + RelMonth;
Year = Month / 12;
Month = Month % 12 + 1;
return DSTcorrect(Start,

View File

@ -91,14 +91,14 @@ struct option
#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__ */
differences in the consts, in stdlib.h. We used to try to prototype
it if __GNU_LIBRARY__ but that wasn't problem free either (I'm not sure
exactly why), and there is no particular need to prototype it.
We really shouldn't be trampling on the system's namespace at all by
declaring getopt() but that is a bigger issue. */
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,

View File

@ -23,13 +23,16 @@
copyright in any changes I have made; this code remains in the
public domain. */
/* Note regarding cvs_* namespace: this avoids potential conflicts
with libraries such as some versions of Kerberos. No particular
need to worry about whether the system supplies an MD5 library, as
this file is only about 3k of object code. */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#if HAVE_STRING_H || STDC_HEADERS
#include <string.h> /* for memcpy() */
#endif
#include <string.h> /* for memcpy() and memset() */
/* Add prototype support. */
#ifndef PROTO
@ -43,12 +46,12 @@
#include "md5.h"
/* Little-endian byte-swapping routines. Note that these do not
depend on the size of datatypes such as uint32, nor do they require
depend on the size of datatypes such as cvs_uint32, nor do they require
us to detect the endianness of the machine we are running on. It
is possible they should be macros for speed, but I would be
surprised if they were a performance bottleneck for MD5. */
static uint32
static cvs_uint32
getu32 (addr)
const unsigned char *addr;
{
@ -58,7 +61,7 @@ getu32 (addr)
static void
putu32 (data, addr)
uint32 data;
cvs_uint32 data;
unsigned char *addr;
{
addr[0] = (unsigned char)data;
@ -72,8 +75,8 @@ putu32 (data, addr)
* initialization constants.
*/
void
MD5Init(ctx)
struct MD5Context *ctx;
cvs_MD5Init (ctx)
struct cvs_MD5Context *ctx;
{
ctx->buf[0] = 0x67452301;
ctx->buf[1] = 0xefcdab89;
@ -89,17 +92,17 @@ MD5Init(ctx)
* of bytes.
*/
void
MD5Update(ctx, buf, len)
struct MD5Context *ctx;
cvs_MD5Update (ctx, buf, len)
struct cvs_MD5Context *ctx;
unsigned char const *buf;
unsigned len;
{
uint32 t;
cvs_uint32 t;
/* Update bitcount */
t = ctx->bits[0];
if ((ctx->bits[0] = (t + ((uint32)len << 3)) & 0xffffffff) < t)
if ((ctx->bits[0] = (t + ((cvs_uint32)len << 3)) & 0xffffffff) < t)
ctx->bits[1]++; /* Carry from low to high */
ctx->bits[1] += len >> 29;
@ -116,7 +119,7 @@ MD5Update(ctx, buf, len)
return;
}
memcpy(p, buf, t);
MD5Transform(ctx->buf, ctx->in);
cvs_MD5Transform (ctx->buf, ctx->in);
buf += t;
len -= t;
}
@ -125,7 +128,7 @@ MD5Update(ctx, buf, len)
while (len >= 64) {
memcpy(ctx->in, buf, 64);
MD5Transform(ctx->buf, ctx->in);
cvs_MD5Transform (ctx->buf, ctx->in);
buf += 64;
len -= 64;
}
@ -140,9 +143,9 @@ MD5Update(ctx, buf, len)
* 1 0* (64-bit count of bits processed, MSB-first)
*/
void
MD5Final(digest, ctx)
cvs_MD5Final (digest, ctx)
unsigned char digest[16];
struct MD5Context *ctx;
struct cvs_MD5Context *ctx;
{
unsigned count;
unsigned char *p;
@ -162,7 +165,7 @@ MD5Final(digest, ctx)
if (count < 8) {
/* Two lots of padding: Pad the first block to 64 bytes */
memset(p, 0, count);
MD5Transform(ctx->buf, ctx->in);
cvs_MD5Transform (ctx->buf, ctx->in);
/* Now fill the next block with 56 bytes */
memset(ctx->in, 0, 56);
@ -175,7 +178,7 @@ MD5Final(digest, ctx)
putu32(ctx->bits[0], ctx->in + 56);
putu32(ctx->bits[1], ctx->in + 60);
MD5Transform(ctx->buf, ctx->in);
cvs_MD5Transform (ctx->buf, ctx->in);
putu32(ctx->buf[0], digest);
putu32(ctx->buf[1], digest + 4);
putu32(ctx->buf[2], digest + 8);
@ -203,12 +206,12 @@ MD5Final(digest, ctx)
* the data and converts bytes into longwords for this routine.
*/
void
MD5Transform(buf, inraw)
uint32 buf[4];
cvs_MD5Transform (buf, inraw)
cvs_uint32 buf[4];
const unsigned char inraw[64];
{
register uint32 a, b, c, d;
uint32 in[16];
register cvs_uint32 a, b, c, d;
cvs_uint32 in[16];
int i;
for (i = 0; i < 16; ++i)
@ -302,7 +305,7 @@ MD5Transform(buf, inraw)
int
main (int argc, char **argv)
{
struct MD5Context context;
struct cvs_MD5Context context;
unsigned char checksum[16];
int i;
int j;
@ -315,9 +318,9 @@ main (int argc, char **argv)
for (j = 1; j < argc; ++j)
{
printf ("MD5 (\"%s\") = ", argv[j]);
MD5Init (&context);
MD5Update (&context, argv[j], strlen (argv[j]));
MD5Final (checksum, &context);
cvs_MD5Init (&context);
cvs_MD5Update (&context, argv[j], strlen (argv[j]));
cvs_MD5Final (checksum, &context);
for (i = 0; i < 16; i++)
{
printf ("%02x", (unsigned int) checksum[i]);

View File

@ -8,22 +8,19 @@
bits instead of 64 is not important; speed is considerably more
important. ANSI guarantees that "unsigned long" will be big enough,
and always using it seems to have few disadvantages. */
typedef unsigned long uint32;
typedef unsigned long cvs_uint32;
struct MD5Context {
uint32 buf[4];
uint32 bits[2];
struct cvs_MD5Context {
cvs_uint32 buf[4];
cvs_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], const unsigned char in[64]));
/*
* This is needed to make RSAREF happy on some MS-DOS compilers.
*/
typedef struct MD5Context MD5_CTX;
void cvs_MD5Init PROTO ((struct cvs_MD5Context *context));
void cvs_MD5Update PROTO ((struct cvs_MD5Context *context,
unsigned char const *buf, unsigned len));
void cvs_MD5Final PROTO ((unsigned char digest[16],
struct cvs_MD5Context *context));
void cvs_MD5Transform PROTO ((cvs_uint32 buf[4], const unsigned char in[64]));
#endif /* !MD5_H */

View File

@ -12,10 +12,7 @@ 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. */
*/
/*

View File

@ -1,3 +1,7 @@
1999-01-19 Vitaly V Fedrushkov <willy@snowyowl.csu.ac.ru>
* Makefile.in (INSTALL_DATA): Wrong manpage permissions fixed.
1998-06-28 Jim Kingdon <kingdon@harvey.cyclic.com>
* cvs.1: Update various items which were out of date. Mostly

View File

@ -25,7 +25,7 @@ MANFILES = $(MAN1FILES) $(MAN5FILES) $(MAN8FILES)
DISTFILES = .cvsignore ChangeLog Makefile.in $(MANFILES)
INSTALL = @INSTALL@
INSTALL_DATA = $(INSTALL)
INSTALL_DATA = @INSTALL_DATA@
prefix = @prefix@
mandir = $(prefix)/man
man1dir = $(mandir)/man1

File diff suppressed because it is too large Load Diff

View File

@ -97,14 +97,10 @@ installdirs:
.PHONY: install installdirs
installcheck:
RCSBIN=$(bindir) ; export RCSBIN ; $(SHELL) $(srcdir)/sanity.sh $(bindir)/cvs
$(SHELL) $(srcdir)/sanity.sh $(bindir)/cvs
.PHONY: installcheck
check: all
if [ -x ../../rcs/src/rcs ] ; then \
RCSBIN=`pwd`/../../rcs/src ; \
export RCSBIN ; \
fi ; \
$(SHELL) $(srcdir)/sanity.sh `pwd`/cvs
.PHONY: check

View File

@ -172,9 +172,20 @@ add (argc, argv)
}
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? */
/* FIXME-also: if filenames are case-insensitive on the
client, and the directory in the repository already
exists and is named "foo", and the command is "cvs add
FOO", this call to Create_Admin puts the wrong thing in
CVS/Repository and so a subsequent "cvs update" will
give an error. The fix will be to have the server report
back what it actually did (e.g. use tagged text for the
"Directory %s added" message), and then Create_Admin,
which should also fix the error handling concerns. */
if (isdir (argv[i]))
{
char *tag;
@ -240,8 +251,9 @@ add (argc, argv)
free (repository);
free (filedir);
}
send_file_names (argc, argv, SEND_EXPAND_WILD);
}
send_files (argc, argv, 0, 0, SEND_BUILD_DIRS | SEND_NO_CONTENTS);
send_file_names (argc, argv, SEND_EXPAND_WILD);
send_to_server ("add\012", 0);
if (message)
free (message);
@ -258,6 +270,9 @@ add (argc, argv)
#endif
struct file_info finfo;
char *p;
#if defined (SERVER_SUPPORT) && !defined (FILENAMES_CASE_INSENSITIVE)
char *found_name;
#endif
memset (&finfo, 0, sizeof finfo);
@ -294,6 +309,60 @@ add (argc, argv)
finfo.repository = repository;
finfo.entries = entries;
#if defined (SERVER_SUPPORT) && !defined (FILENAMES_CASE_INSENSITIVE)
if (ign_case)
{
/* Need to check whether there is a directory with the
same name but different case. We'll check for files
with the same name later (when Version_TS calls
RCS_parse which calls fopen_case). If CVS some day
records directories in the RCS files, then we should be
able to skip the separate check here, which would be
cleaner. */
DIR *dirp;
struct dirent *dp;
dirp = CVS_OPENDIR (finfo.repository);
if (dirp == NULL)
error (1, errno, "cannot read directory %s", finfo.repository);
found_name = NULL;
errno = 0;
while ((dp = readdir (dirp)) != NULL)
{
if (cvs_casecmp (dp->d_name, finfo.file) == 0)
{
if (found_name != NULL)
error (1, 0, "%s is ambiguous; could mean %s or %s",
finfo.file, dp->d_name, found_name);
found_name = xstrdup (dp->d_name);
}
}
if (errno != 0)
error (1, errno, "cannot read directory %s", finfo.repository);
closedir (dirp);
if (found_name != NULL)
{
/* OK, we are about to patch up the name, so patch up
the temporary directory too to match. The isdir
should "always" be true (since files have ,v), but
I guess we might as well make some attempt to not
get confused by stray files in the repository. */
if (isdir (finfo.file))
{
if (CVS_MKDIR (found_name, 0777) < 0
&& errno != EEXIST)
error (0, errno, "cannot create %s", finfo.file);
}
/* OK, we found a directory with the same name, maybe in
a different case. Treat it as if the name were the
same. */
finfo.file = found_name;
}
}
#endif
/* We pass force_tag_match as 1. If the directory has a
sticky branch tag, and there is already an RCS file which
does not have that tag, then the head revision is
@ -420,7 +489,7 @@ file `%s' will be added on branch `%s' from version %s",
re-adding file %s (in place of dead revision %s)",
finfo.fullname, vers->vn_rcs);
Register (entries, finfo.file, "0", vers->ts_user,
NULL,
vers->options,
vers->tag, NULL, NULL);
++added_files;
}
@ -538,6 +607,10 @@ cannot resurrect %s; RCS file removed by second party", finfo.fullname);
free_cwd (&cwd);
free (finfo.fullname);
#if defined (SERVER_SUPPORT) && !defined (FILENAMES_CASE_INSENSITIVE)
if (ign_case && found_name != NULL)
free (found_name);
#endif
}
if (added_files)
error (0, 0, "use '%s commit' to add %s permanently",

View File

@ -120,35 +120,11 @@ admin (argc, argv)
struct admin_data admin_data;
int c;
int i;
int only_k_option;
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 ();
memset (&admin_data, 0, sizeof admin_data);
@ -157,9 +133,13 @@ admin (argc, argv)
example, admin_data->branch should be not `-bfoo' but simply `foo'. */
optind = 0;
only_k_option = 1;
while ((c = getopt (argc, argv,
"+ib::c:a:A:e:l::u::LUn:N:m:o:s:t::IqxV:k:")) != -1)
"+ib::c:a:A:e::l::u::LUn:N:m:o:s:t::IqxV:k:")) != -1)
{
if (c != 'k')
only_k_option = 0;
switch (c)
{
case 'i':
@ -211,6 +191,11 @@ admin (argc, argv)
break;
case 'e':
if (optarg == NULL)
{
error (1, 0,
"removing entire access list not yet implemented");
}
arg_add (&admin_data, 'e', optarg);
break;
@ -353,6 +338,33 @@ admin (argc, argv)
argc -= optind;
argv += optind;
#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;
/* The use of `cvs admin -k' is unrestricted. However, any
other option is restricted. */
int denied = ! only_k_option;
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
for (i = 0; i < admin_data.ac; ++i)
{
assert (admin_data.av[i][0] == '-');
@ -375,9 +387,9 @@ admin (argc, argv)
check_numeric (admin_data.delete_revs + 2, argc, argv);
p = strchr (admin_data.delete_revs + 2, ':');
if (p != NULL && isdigit (p[1]))
if (p != NULL && isdigit ((unsigned char) p[1]))
check_numeric (p + 1, argc, argv);
else if (p != NULL && p[1] == ':' && isdigit(p[2]))
else if (p != NULL && p[1] == ':' && isdigit ((unsigned char) p[2]))
check_numeric (p + 2, argc, argv);
}
@ -414,8 +426,8 @@ admin (argc, argv)
for (i = 0; i < admin_data.ac; ++i)
send_arg (admin_data.av[i]);
send_file_names (argc, argv, SEND_EXPAND_WILD);
send_files (argc, argv, 0, 0, SEND_NO_CONTENTS);
send_file_names (argc, argv, SEND_EXPAND_WILD);
send_to_server ("admin\012", 0);
err = get_responses_and_close ();
goto return_it;
@ -492,7 +504,7 @@ admin_fileproc (callerdat, finfo)
if (admin_data->branch != NULL)
{
char *branch = &admin_data->branch[2];
if (*branch != '\0' && ! isdigit (*branch))
if (*branch != '\0' && ! isdigit ((unsigned char) *branch))
{
branch = RCS_whatbranch (rcs, admin_data->branch + 2);
if (branch == NULL)
@ -604,12 +616,9 @@ admin_fileproc (callerdat, finfo)
if (admin_data->kflag != NULL)
{
char *kflag = admin_data->kflag + 2;
if (!rcs->expand || strcmp (rcs->expand, kflag) != 0)
{
if (rcs->expand)
free (rcs->expand);
rcs->expand = xstrdup (kflag);
}
char *oldexpand = RCS_getexpand (rcs);
if (oldexpand == NULL || strcmp (oldexpand, kflag) != 0)
RCS_setexpand (rcs, kflag);
}
/* Handle miscellaneous options. TODO: decide whether any or all

View File

@ -238,7 +238,7 @@ checkout (argc, argv)
if (!tag && !date)
error (1, 0, "must specify a tag or date");
if (tag && isdigit (tag[0]))
if (tag && isdigit ((unsigned char) tag[0]))
error (1, 0, "tag `%s' must be a symbolic tag", tag);
}

View File

@ -146,6 +146,139 @@ static void handle_f PROTO((char *, int));
static void handle_notified PROTO((char *, int));
static size_t try_read_from_server PROTO ((char *, size_t));
#endif /* CLIENT_SUPPORT */
#ifdef CLIENT_SUPPORT
/* We need to keep track of the list of directories we've sent to the
server. This list, along with the current CVSROOT, will help us
decide which command-line arguments to send. */
List *dirs_sent_to_server = NULL;
static int is_arg_a_parent_or_listed_dir PROTO((Node *, void *));
static int
is_arg_a_parent_or_listed_dir (n, d)
Node *n;
void *d;
{
char *directory = n->key; /* name of the dir sent to server */
char *this_argv_elem = (char *) d; /* this argv element */
/* Say we should send this argument if the argument matches the
beginning of a directory name sent to the server. This way,
the server will know to start at the top of that directory
hierarchy and descend. */
if (strncmp (directory, this_argv_elem, strlen (this_argv_elem)) == 0)
return 1;
return 0;
}
static int arg_should_not_be_sent_to_server PROTO((char *));
/* Return nonzero if this argument should not be sent to the
server. */
static int
arg_should_not_be_sent_to_server (arg)
char *arg;
{
/* Decide if we should send this directory name to the server. We
should always send argv[i] if:
1) the list of directories sent to the server is empty (as it
will be for checkout, etc.).
2) the argument is "."
3) the argument is a file in the cwd and the cwd is checked out
from the current root
4) the argument lies within one of the paths in
dirs_sent_to_server.
4) */
if (list_isempty (dirs_sent_to_server))
return 0; /* always send it */
if (strcmp (arg, ".") == 0)
return 0; /* always send it */
/* We should send arg if it is one of the directories sent to the
server or the parent of one; this tells the server to descend
the hierarchy starting at this level. */
if (isdir (arg))
{
if (walklist (dirs_sent_to_server, is_arg_a_parent_or_listed_dir, arg))
return 0;
/* If arg wasn't a parent, we don't know anything about it (we
would have seen something related to it during the
send_files phase). Don't send it. */
return 1;
}
/* Try to decide whether we should send arg to the server by
checking the contents of the corresponding CVSADM directory. */
{
char *t, *this_root;
/* Calculate "dirname arg" */
for (t = arg + strlen (arg) - 1; t >= arg; t--)
{
if (ISDIRSEP(*t))
break;
}
/* Now we're either poiting to the beginning of the
string, or we found a path separator. */
if (t >= arg)
{
/* Found a path separator. */
char c = *t;
*t = '\0';
/* First, check to see if we sent this directory to the
server, because it takes less time than actually
opening the stuff in the CVSADM directory. */
if (walklist (dirs_sent_to_server, is_arg_a_parent_or_listed_dir,
arg))
{
*t = c; /* make sure to un-truncate the arg */
return 0;
}
/* Since we didn't find it in the list, check the CVSADM
files on disk. */
this_root = Name_Root (arg, (char *) NULL);
*t = c;
}
else
{
/* We're at the beginning of the string. Look at the
CVSADM files in cwd. */
this_root = Name_Root ((char *) NULL, (char *) NULL);
}
/* Now check the value for root. */
if (this_root && current_root
&& (strcmp (this_root, current_root) != 0))
{
/* Don't send this, since the CVSROOTs don't match. */
free (this_root);
return 1;
}
free (this_root);
}
/* OK, let's send it. */
return 0;
}
#endif /* CLIENT_SUPPORT */
#if defined(CLIENT_SUPPORT) || defined(SERVER_SUPPORT)
@ -710,25 +843,6 @@ int gzip_level;
*/
int file_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[3] = { "gzip", "-d" };
return filter_stream_through_program (fd, dir, &gunzip_argv[0], pidp);
}
#endif /* CLIENT_SUPPORT or SERVER_SUPPORT */
#ifdef CLIENT_SUPPORT
@ -737,7 +851,7 @@ int filter_through_gunzip (fd, dir, pidp)
* 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;
static char *toplevel_repos = NULL;
/* Working directory when we first started. Note: we could speed things
up on some systems by using savecwd.h here instead of just always
@ -770,6 +884,13 @@ handle_error (args, len)
return;
}
++p;
/* Next we print the text of the message from the server. We
probably should be prefixing it with "server error" or some
such, because if it is something like "Out of memory", the
current behavior doesn't say which machine is out of
memory. */
len -= p - args;
something_printed = 0;
for (; len > 0; --len)
@ -807,7 +928,7 @@ handle_valid_requests (args, len)
;
else
{
if (rq->status == rq_enableme)
if (rq->flags & RQ_ENABLEME)
{
/*
* Server wants to know if we have this, to enable the
@ -817,16 +938,17 @@ handle_valid_requests (args, len)
send_to_server ("\012", 0);
}
else
rq->status = rq_supported;
rq->flags |= RQ_SUPPORTED;
}
p = q;
} while (q != NULL);
for (rq = requests; rq->name != NULL; ++rq)
{
if (rq->status == rq_essential)
if ((rq->flags & RQ_SUPPORTED)
|| (rq->flags & RQ_ENABLEME))
continue;
if (rq->flags & RQ_ESSENTIAL)
error (1, 0, "request `%s' not supported by server", rq->name);
else if (rq->status == rq_optional)
rq->status = rq_not_supported;
}
}
@ -1210,7 +1332,14 @@ copy_a_file (data, ent_list, short_pathname, filename)
for(p = newname; *p; p++)
if(*p == '.' || *p == '#') *p = '_';
#endif
/* cvsclient.texi has said for a long time that newname must be in the
same directory. Wouldn't want a malicious or buggy server overwriting
~/.profile, /etc/passwd, or anything like that. */
if (last_component (newname) != newname)
error (1, 0, "protocol error: Copy-file tried to specify directory");
if (unlink_file (newname) && !existence_error (errno))
error (0, errno, "unable to remove %s", newname);
copy_file (filename, newname);
free (newname);
}
@ -1317,6 +1446,23 @@ static int updated_seen;
/* Filename from an "fname" tagged response within +updated/-updated. */
static char *updated_fname;
/* This struct is used to hold data when reading the +importmergecmd
and -importmergecmd tags. We put the variables in a struct only
for namespace issues. FIXME: As noted above, we need to develop a
more systematic approach. */
static struct
{
/* Nonzero if we have seen +importmergecmd and not -importmergecmd. */
int seen;
/* Number of conflicts, from a "conflicts" tagged response. */
int conflicts;
/* First merge tag, from a "mergetag1" tagged response. */
char *mergetag1;
/* Second merge tag, from a "mergetag2" tagged response. */
char *mergetag2;
/* Repository, from a "repository" tagged response. */
char *repository;
} importmergecmd;
/* Nonzero if we should arrange to return with a failure exit status. */
static int failure_exit;
@ -1367,7 +1513,7 @@ handle_checksum (args, len)
stored_checksum_valid = 1;
}
static int stored_mode_valid;
/* Mode that we got in a "Mode" response (malloc'd), or NULL if none. */
static char *stored_mode;
static void handle_mode PROTO ((char *, int));
@ -1377,12 +1523,9 @@ handle_mode (args, len)
char *args;
int len;
{
if (stored_mode_valid)
error (1, 0, "protocol error: duplicate Mode");
if (stored_mode != NULL)
free (stored_mode);
error (1, 0, "protocol error: duplicate Mode");
stored_mode = xstrdup (args);
stored_mode_valid = 1;
}
/* Nonzero if time was specified in Mod-time. */
@ -1547,8 +1690,8 @@ update_entries (data_arg, ent_list, short_pathname, filename)
free (size_string);
/* Note that checking this separately from writing the file is
a race condition: if the existing or lack thereof of the
file changes between now and the actually calls which
a race condition: if the existence or lack thereof of the
file changes between now and the actual calls which
operate on it, we lose. However (a) there are so many
cases, I'm reluctant to try to fix them all, (b) in some
cases the system might not even have a system call which
@ -1622,9 +1765,11 @@ update_entries (data_arg, ent_list, short_pathname, filename)
/* The Mode, Mod-time, and Checksum responses should not carry
over to a subsequent Created (or whatever) response, even
in the error case. */
stored_mode_valid = 0;
if (stored_mode != NULL)
{
free (stored_mode);
stored_mode = NULL;
}
stored_modtime_valid = 0;
stored_checksum_valid = 0;
@ -1701,7 +1846,10 @@ update_entries (data_arg, ent_list, short_pathname, filename)
read_from_server (buf, size);
if (use_gzip)
gunzip_and_write (fd, short_pathname, buf, size);
{
if (gunzip_and_write (fd, short_pathname, buf, size))
error (1, 0, "aborting due to compression error");
}
else if (write (fd, buf, size) != size)
error (1, errno, "writing %s", short_pathname);
}
@ -1734,82 +1882,14 @@ update_entries (data_arg, ent_list, short_pathname, filename)
}
else if (data->contents == UPDATE_ENTRIES_PATCH)
{
#ifdef DONT_USE_PATCH
/* Hmm. We support only Rcs-diff, and the server supports
only Patched (or else it would have sent Rcs-diff instead).
/* You might think we could just leave Patched out of
Valid-responses and not get this response. However, if
memory serves, the CVS 1.9 server bases this on -u
(update-patches), and there is no way for us to send -u
or not based on whether the server supports "Rcs-diff".
Fall back to transmitting entire files. */
patch_failed = 1;
#else /* Use patch. */
int retcode;
char *backup;
struct stat s;
backup = xmalloc (strlen (filename) + 5);
strcpy (backup, filename);
strcat (backup, "~");
(void) unlink_file (backup);
if (!isfile (filename))
error (1, 0, "patch original file %s does not exist",
short_pathname);
if ( CVS_STAT (temp_filename, &s) < 0)
error (1, errno, "can't stat patch file %s", temp_filename);
if (s.st_size == 0)
retcode = 0;
else
{
/* This behavior (in which -b takes an argument) is
supported by GNU patch 2.1. Apparently POSIX.2
specifies a -b option without an argument. GNU
patch 2.1.5 implements this and therefore won't
work here. GNU patch versions after 2.1.5 are said
to have a kludge which checks if the last 4 args
are `-b SUFFIX ORIGFILE PATCHFILE' and if so emit a
warning (I think -s suppresses it), and then behave
as CVS expects.
Of course this is yet one more reason why in the long
run we want Rcs-diff to replace Patched. */
run_setup (PATCH_PROGRAM);
run_arg ("-f");
run_arg ("-s");
run_arg ("-b");
run_arg ("~");
run_arg (filename);
run_arg (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);
error (retcode == -1 ? 1 : 0, retcode == -1 ? old_errno : 0,
"could not patch %s%s", filename,
retcode == -1 ? "" : "; will refetch");
patch_failed = 1;
}
free (backup);
#endif /* Use patch. */
}
else
{
@ -1842,15 +1922,16 @@ update_entries (data_arg, ent_list, short_pathname, filename)
{
if (stored_checksum_valid)
{
struct MD5Context context;
struct cvs_MD5Context context;
unsigned char checksum[16];
/* We have a checksum. Check it before writing
the file out, so that we don't have to read it
back in again. */
MD5Init (&context);
MD5Update (&context, (unsigned char *) patchedbuf, patchedlen);
MD5Final (checksum, &context);
cvs_MD5Init (&context);
cvs_MD5Update (&context,
(unsigned char *) patchedbuf, patchedlen);
cvs_MD5Final (checksum, &context);
if (memcmp (checksum, stored_checksum, 16) != 0)
{
error (0, 0,
@ -1887,7 +1968,7 @@ update_entries (data_arg, ent_list, short_pathname, filename)
if (stored_checksum_valid && ! patch_failed)
{
FILE *e;
struct MD5Context context;
struct cvs_MD5Context context;
unsigned char buf[8192];
unsigned len;
unsigned char checksum[16];
@ -1906,12 +1987,12 @@ update_entries (data_arg, ent_list, short_pathname, filename)
if (e == NULL)
error (1, errno, "could not open %s", short_pathname);
MD5Init (&context);
cvs_MD5Init (&context);
while ((len = fread (buf, 1, sizeof buf, e)) != 0)
MD5Update (&context, buf, len);
cvs_MD5Update (&context, buf, len);
if (ferror (e))
error (1, errno, "could not read %s", short_pathname);
MD5Final (checksum, &context);
cvs_MD5Final (checksum, &context);
fclose (e);
@ -1958,10 +2039,13 @@ update_entries (data_arg, ent_list, short_pathname, filename)
free (buf);
}
if (stored_mode_valid)
if (stored_mode != NULL)
{
change_mode (filename, stored_mode, 1);
stored_mode_valid = 0;
free (stored_mode);
stored_mode = NULL;
}
if (stored_modtime_valid)
{
struct utimbuf t;
@ -2020,7 +2104,17 @@ update_entries (data_arg, ent_list, short_pathname, filename)
else if (local_timestamp == NULL)
{
local_timestamp = file_timestamp;
mark_up_to_date (filename);
/* Checking for command_name of "commit" doesn't seem like
the cleanest way to handle this, but it seem to roughly
parallel what the :local: code which calls
mark_up_to_date ends up amounting to. Some day, should
think more about what the Checked-in response means
vis-a-vis both Entries and Base and clarify
cvsclient.texi accordingly. */
if (!strcmp (command_name, "commit"))
mark_up_to_date (filename);
}
Register (ent_list, filename, vn, local_timestamp,
@ -2263,7 +2357,20 @@ set_sticky (data, ent_list, short_pathname, filename)
FILE *f;
read_line (&tagspec);
f = open_file (CVSADM_TAG, "w+");
/* FIXME-update-dir: error messages should include the directory. */
f = CVS_FOPEN (CVSADM_TAG, "w+");
if (f == NULL)
{
/* Making this non-fatal is a bit of a kludge (see dirs2
in testsuite). A better solution would be to avoid having
the server tell us about a directory we shouldn't be doing
anything with anyway (e.g. by handling directory
addition/removal better). */
error (0, errno, "cannot open %s", CVSADM_TAG);
free (tagspec);
return;
}
if (fprintf (f, "%s\n", tagspec) < 0)
error (1, errno, "writing %s", CVSADM_TAG);
if (fclose (f) == EOF)
@ -2568,6 +2675,22 @@ send_repository (dir, repos, update_dir)
if (client_prune_dirs)
add_prune_candidate (update_dir);
/* Add a directory name to the list of those sent to the
server. */
if (update_dir && (*update_dir != '\0')
&& (strcmp (update_dir, ".") != 0)
&& (findnode (dirs_sent_to_server, update_dir) == NULL))
{
Node *n;
n = getnode ();
n->type = UNKNOWN;
n->key = xstrdup (update_dir);
n->data = NULL;
if (addnode (dirs_sent_to_server, n))
error (1, 0, "cannot add directory %s to list", n->key);
}
/* 80 is large enough for any of CVSADM_*. */
adm_name = xmalloc (strlen (dir) + 80);
@ -2762,47 +2885,55 @@ send_a_repository (dir, repository, update_dir)
* directories (and cvs invoked on the containing
* directory). I'm not sure the latter case needs to
* work.
*
* 21 Aug 1998: Well, Mr. Above-Comment-Writer, it
* does need to work after all. When we are using the
* client in a multi-cvsroot environment, it will be
* fairly common that we have the above case (e.g.,
* cwd checked out from one repository but
* subdirectory checked out from another). We can't
* assume that by walking up a directory in our wd we
* necessarily walk up a directory in the repository.
*/
/*
* 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;
/*
* Strip trailing slashes from the name of the update directory.
* Otherwise, running `cvs update dir/' provokes the failure
* `protocol error: illegal directory syntax in dir/' when
* running in client/server mode.
*/
int repository_len, update_dir_len;
strip_trailing_slashes (update_dir);
slashes_in_update_dir = 0;
for (p = update_dir; *p != '\0'; ++p)
if (*p == '/')
++slashes_in_update_dir;
repository_len = strlen (repository);
update_dir_len = strlen (update_dir);
slashes_skipped = 0;
p = repository + strlen (repository);
while (1)
/* Try to remove the path components in UPDATE_DIR
from REPOSITORY. If the path elements don't exist
in REPOSITORY, or the removal of those path
elements mean that we "step above"
CVSroot_directory, set toplevel_repos to
CVSroot_directory. */
if ((repository_len > update_dir_len)
&& (strcmp (repository + repository_len - update_dir_len,
update_dir) == 0)
/* TOPLEVEL_REPOS shouldn't be above CVSroot_directory */
&& ((repository_len - update_dir_len)
> strlen (CVSroot_directory)))
{
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;
/* The repository name contains UPDATE_DIR. Set
toplevel_repos to the repository name without
UPDATE_DIR. */
toplevel_repos = xmalloc (repository_len - update_dir_len);
/* Note that we don't copy the trailing '/'. */
strncpy (toplevel_repos, repository,
repository_len - update_dir_len - 1);
toplevel_repos[repository_len - update_dir_len - 1] = '\0';
}
else
{
toplevel_repos = xstrdup (CVSroot_directory);
}
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';
}
}
}
@ -3047,10 +3178,61 @@ handle_mt (args, len)
case '+':
if (strcmp (tag, "+updated") == 0)
updated_seen = 1;
else if (strcmp (tag, "+importmergecmd") == 0)
importmergecmd.seen = 1;
break;
case '-':
if (strcmp (tag, "-updated") == 0)
updated_seen = 0;
else if (strcmp (tag, "-importmergecmd") == 0)
{
char buf[80];
/* Now that we have gathered the information, we can
output the suggested merge command. */
if (importmergecmd.conflicts == 0
|| importmergecmd.mergetag1 == NULL
|| importmergecmd.mergetag2 == NULL
|| importmergecmd.repository == NULL)
{
error (0, 0,
"invalid server: incomplete importmergecmd tags");
break;
}
sprintf (buf, "\n%d conflicts created by this import.\n",
importmergecmd.conflicts);
cvs_output (buf, 0);
cvs_output ("Use the following command to help the merge:\n\n",
0);
cvs_output ("\t", 1);
cvs_output (program_name, 0);
if (CVSroot_cmdline != NULL)
{
cvs_output (" -d ", 0);
cvs_output (CVSroot_cmdline, 0);
}
cvs_output (" checkout -j", 0);
cvs_output (importmergecmd.mergetag1, 0);
cvs_output (" -j", 0);
cvs_output (importmergecmd.mergetag2, 0);
cvs_output (" ", 1);
cvs_output (importmergecmd.repository, 0);
cvs_output ("\n\n", 0);
/* Clear the static variables so that everything is
ready for any subsequent importmergecmd tag. */
importmergecmd.conflicts = 0;
free (importmergecmd.mergetag1);
importmergecmd.mergetag1 = NULL;
free (importmergecmd.mergetag2);
importmergecmd.mergetag2 = NULL;
free (importmergecmd.repository);
importmergecmd.repository = NULL;
importmergecmd.seen = 0;
}
break;
default:
if (updated_seen)
@ -3073,6 +3255,21 @@ handle_mt (args, len)
or they reflect future extensions that we can
safely ignore. */
}
else if (importmergecmd.seen)
{
if (strcmp (tag, "conflicts") == 0)
importmergecmd.conflicts = atoi (text);
else if (strcmp (tag, "mergetag1") == 0)
importmergecmd.mergetag1 = xstrdup (text);
else if (strcmp (tag, "mergetag2") == 0)
importmergecmd.mergetag2 = xstrdup (text);
else if (strcmp (tag, "repository") == 0)
importmergecmd.repository = xstrdup (text);
/* Swallow all other tags. Either they are text for
which we are going to print our own version when we
see -importmergecmd, or they are future extensions
we can safely ignore. */
}
else if (strcmp (tag, "newline") == 0)
printf ("\n");
else if (text != NULL)
@ -3404,9 +3601,12 @@ get_responses_and_close ()
{
time_t now;
(void) time (&now);
if (now == last_register_time)
for (;;)
{
(void) time (&now);
if (now != last_register_time) break;
sleep (1); /* to avoid time-stamp races */
}
}
return errs;
@ -3424,7 +3624,7 @@ supported_request (name)
for (rq = requests; rq->name; rq++)
if (!strcmp (rq->name, name))
return rq->status == rq_supported;
return (rq->flags & RQ_SUPPORTED) != 0;
error (1, 0, "internal error: testing support for unknown option?");
/* NOTREACHED */
return 0;
@ -3490,7 +3690,6 @@ recv_line (sock, resultp)
int sock;
char **resultp;
{
int c;
char *result;
size_t input_index = 0;
size_t result_size = 80;
@ -3500,23 +3699,16 @@ recv_line (sock, resultp)
while (1)
{
char ch;
if (recv (sock, &ch, 1, 0) < 0)
int n;
n = recv (sock, &ch, 1, 0);
if (n <= 0)
error (1, 0, "recv() from server %s: %s", CVSroot_hostname,
SOCK_STRERROR (SOCK_ERRNO));
c = ch;
n == 0 ? "EOF" : SOCK_STRERROR (SOCK_ERRNO));
if (c == EOF)
{
free (result);
/* It's end of file. */
error (1, 0, "end of file from server");
}
if (c == '\012')
if (ch == '\012')
break;
result[input_index++] = c;
result[input_index++] = ch;
while (input_index + 1 >= result_size)
{
result_size *= 2;
@ -3535,6 +3727,28 @@ recv_line (sock, resultp)
return input_index;
}
/* Connect to a forked server process. */
void
connect_to_forked_server (tofdp, fromfdp)
int *tofdp, *fromfdp;
{
/* This is pretty simple. All we need to do is choose the correct
cvs binary and call piped_child. */
char *command[3];
command[0] = getenv ("CVS_SERVER");
if (! command[0])
command[0] = "cvs";
command[1] = "server";
command[2] = NULL;
if (! piped_child (command, tofdp, fromfdp))
error (1, 0, "could not fork server process");
}
/* Connect to the authenticating server.
If VERIFY_ONLY is non-zero, then just verify that the password is
@ -3960,6 +4174,13 @@ start_server ()
int tofd, fromfd;
char *log = getenv ("CVS_CLIENT_LOG");
/* Clear our static variables for this invocation. */
if (toplevel_repos != NULL)
free (toplevel_repos);
toplevel_repos = NULL;
/* Note that generally speaking we do *not* fall back to a different
way of connecting if the first one does not work. This is slow
(*really* slow on a 14.4kbps link); the clean way to have a CVS
@ -4020,6 +4241,10 @@ the :server: access method is not supported by this port of CVS");
#endif
break;
case fork_method:
connect_to_forked_server (&tofd, &fromfd);
break;
default:
error (1, 0, "\
(start_server internal error): unknown access method");
@ -4119,7 +4344,11 @@ the :server: access method is not supported by this port of CVS");
free (last_update_dir);
last_update_dir = NULL;
stored_checksum_valid = 0;
stored_mode_valid = 0;
if (stored_mode != NULL)
{
free (stored_mode);
stored_mode = NULL;
}
if (strcmp (command_name, "init") != 0)
{
@ -4648,9 +4877,10 @@ send_modified (file, short_pathname, vers)
{
size_t newsize = 0;
read_and_gzip (fd, short_pathname, (unsigned char **)&buf,
&bufsize, &newsize,
file_gzip_level);
if (read_and_gzip (fd, short_pathname, (unsigned char **)&buf,
&bufsize, &newsize,
file_gzip_level))
error (1, 0, "aborting due to compression error");
if (close (fd) < 0)
error (0, errno, "warning: can't close %s", short_pathname);
@ -5050,7 +5280,7 @@ send_file_names (argc, argv, flags)
int i;
int level;
int max_level;
/* The fact that we do this here as well as start_recursion is a bit
of a performance hit. Perhaps worth cleaning up someday. */
if (flags & SEND_EXPAND_WILD)
@ -5091,6 +5321,9 @@ send_file_names (argc, argv, flags)
char *p = argv[i];
char *line = NULL;
if (arg_should_not_be_sent_to_server (argv[i]))
continue;
#ifdef FILENAMES_CASE_INSENSITIVE
/* We want to send the file name as it appears
in CVS/Entries. We put this inside an ifdef
@ -5224,7 +5457,7 @@ client_import_setup (repository)
*/
int
client_process_import_file (message, vfile, vtag, targc, targv, repository,
all_files_binary)
all_files_binary, modtime)
char *message;
char *vfile;
char *vtag;
@ -5232,6 +5465,9 @@ client_process_import_file (message, vfile, vtag, targc, targv, repository,
char *targv[];
char *repository;
int all_files_binary;
/* Nonzero for "import -d". */
int modtime;
{
char *update_dir;
char *fullname;
@ -5281,6 +5517,28 @@ client_process_import_file (message, vfile, vtag, targc, targv, repository,
error (0, 0,
"warning: ignoring -k options due to server limitations");
}
if (modtime)
{
if (supported_request ("Checkin-time"))
{
struct stat sb;
char *rcsdate;
char netdate[MAXDATELEN];
if (CVS_STAT (vfile, &sb) < 0)
error (1, errno, "cannot stat %s", fullname);
rcsdate = date_from_time_t (sb.st_mtime);
date_to_internet (netdate, rcsdate);
free (rcsdate);
send_to_server ("Checkin-time ", 0);
send_to_server (netdate, 0);
send_to_server ("\012", 1);
}
else
error (0, 0,
"warning: ignoring -d option due to server limitations");
}
send_modified (vfile, fullname, &vers);
if (vers.options != NULL)
free (vers.options);
@ -5466,27 +5724,15 @@ option_with_arg (option, arg)
We then convert that to the format required in the protocol
(including the "-D" option) and send it. According to
cvsclient.texi, RFC 822/1123 format is preferred, but for now we
use the format that we always have, for
conservatism/laziness/paranoia. As far as I know all servers
support the RFC 822/1123 format, so probably there would be no
particular danger in switching. */
cvsclient.texi, RFC 822/1123 format is preferred. */
void
client_senddate (date)
const char *date;
{
int year, month, day, hour, minute, second;
char buf[100];
char buf[MAXDATELEN];
if (sscanf (date, SDATEFORM, &year, &month, &day, &hour, &minute, &second)
!= 6)
{
error (1, 0, "client_senddate: sscanf failed on date");
}
sprintf (buf, "%d/%d/%d %d:%d:%d GMT", month, day, year,
hour, minute, second);
date_to_internet (buf, (char *)date);
option_with_arg ("-D", buf);
}

View File

@ -6,8 +6,6 @@ extern int change_mode PROTO((char *, char *, int));
extern int gzip_level;
extern int file_gzip_level;
extern int filter_through_gzip PROTO((int, int, int, pid_t *));
extern int filter_through_gunzip PROTO((int, int, pid_t *));
#if defined (CLIENT_SUPPORT) || defined (SERVER_SUPPORT)
@ -195,7 +193,8 @@ 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, int all_files_binary));
int targc, char *targv[], char *repository, int all_files_binary,
int modtime));
extern void client_import_done PROTO((void));
extern void client_notify PROTO((char *, char *, char *, int, char *));
#endif /* CLIENT_SUPPORT */

View File

@ -36,15 +36,13 @@ Create_Admin (dir, update_dir, repository, tag, date, nonbranch, warn)
char *reposcopy;
char *tmp;
#ifdef SERVER_SUPPORT
if (trace)
{
fprintf (stderr, "%c-> Create_Admin (%s, %s, %s, %s, %s, %d, %d)\n",
(server_active) ? 'S' : ' ',
fprintf (stderr, "%s-> Create_Admin (%s, %s, %s, %s, %s, %d, %d)\n",
CLIENT_SERVER_STR,
dir, update_dir, repository, tag ? tag : "",
date ? date : "", nonbranch, warn);
}
#endif
if (noexec)
return 0;

View File

@ -65,6 +65,11 @@ read_cvsrc (argc, argv, cmdname)
/* determine filename for ~/.cvsrc */
homedir = get_homedir ();
/* If we can't find a home directory, ignore ~/.cvsrc. This may
make tracking down problems a bit of a pain, but on the other
hand it might be obnoxious to complain when CVS will function
just fine without .cvsrc (and many users won't even know what
.cvsrc is). */
if (!homedir)
return;
@ -96,7 +101,7 @@ read_cvsrc (argc, argv, cmdname)
/* stop if we match the current command */
if (!strncmp (line, cmdname, command_len)
&& isspace (*(line + command_len)))
&& isspace ((unsigned char) *(line + command_len)))
{
found = 1;
break;

View File

@ -89,8 +89,8 @@ watch_onoff (argc, argv)
if (local)
send_arg ("-l");
send_file_names (argc, argv, SEND_EXPAND_WILD);
send_files (argc, argv, local, 0, SEND_NO_CONTENTS);
send_file_names (argc, argv, SEND_EXPAND_WILD);
send_to_server (turning_on ? "watch-on\012" : "watch-off\012", 0);
return get_responses_and_close ();
}
@ -722,6 +722,9 @@ notify_proc (repository, filter)
return (pclose (pipefp));
}
/* FIXME: this function should have a way to report whether there was
an error so that server.c can know whether to report Notified back
to the client. */
void
notify_do (type, filename, who, val, watches, repository)
int type;
@ -743,6 +746,11 @@ notify_do (type, filename, who, val, watches, repository)
switch (type)
{
case 'E':
if (strpbrk (val, ",>;=\n") != NULL)
{
error (0, 0, "invalid character in editor value");
return;
}
editor_set (filename, who, val);
break;
case 'U':
@ -864,7 +872,14 @@ notify_do (type, filename, who, val, watches, repository)
{
char *cp;
args.notifyee = xstrdup (line + len + 1);
cp = strchr (args.notifyee, ':');
/* There may or may not be more
colon-separated fields added to this in the
future; in any case, we ignore them right
now, and if there are none we make sure to
chop off the final newline, if any. */
cp = strpbrk (args.notifyee, ":\n");
if (cp != NULL)
*cp = '\0';
break;
@ -876,7 +891,8 @@ notify_do (type, filename, who, val, watches, repository)
error (0, errno, "cannot close %s", usersname);
}
free (usersname);
free (line);
if (line != NULL)
free (line);
if (args.notifyee == NULL)
{
@ -1008,29 +1024,29 @@ editors_fileproc (callerdat, finfo)
if (them == NULL)
return 0;
fputs (finfo->fullname, stdout);
cvs_output (finfo->fullname, 0);
p = them;
while (1)
{
putc ('\t', stdout);
cvs_output ("\t", 1);
while (*p != '>' && *p != '\0')
putc (*p++, stdout);
cvs_output (p++, 1);
if (*p == '\0')
{
/* Only happens if attribute is misformed. */
putc ('\n', stdout);
cvs_output ("\n", 1);
break;
}
++p;
putc ('\t', stdout);
cvs_output ("\t", 1);
while (1)
{
while (*p != '+' && *p != ',' && *p != '\0')
putc (*p++, stdout);
cvs_output (p++, 1);
if (*p == '\0')
{
putc ('\n', stdout);
cvs_output ("\n", 1);
goto out;
}
if (*p == ',')
@ -1039,9 +1055,9 @@ editors_fileproc (callerdat, finfo)
break;
}
++p;
putc ('\t', stdout);
cvs_output ("\t", 1);
}
putc ('\n', stdout);
cvs_output ("\n", 1);
}
out:;
return 0;
@ -1086,8 +1102,8 @@ editors (argc, argv)
if (local)
send_arg ("-l");
send_file_names (argc, argv, SEND_EXPAND_WILD);
send_files (argc, argv, local, 0, SEND_NO_CONTENTS);
send_file_names (argc, argv, SEND_EXPAND_WILD);
send_to_server ("editors\012", 0);
return get_responses_and_close ();
}

View File

@ -157,7 +157,9 @@ write_entries (list)
rename_file (entfilename, CVSADM_ENT);
/* now, remove the log file */
unlink_file (CVSADM_ENTLOG);
if (unlink_file (CVSADM_ENTLOG) < 0
&& !existence_error (errno))
error (0, errno, "cannot remove %s", CVSADM_ENTLOG);
}
/*
@ -171,12 +173,8 @@ Scratch_Entry (list, 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
(void) fprintf (stderr, "%s-> Scratch_Entry(%s)\n",
CLIENT_SERVER_STR, fname);
/* hashlookup to see if it is there */
if ((node = findnode_fn (list, fname)) != NULL)
@ -231,18 +229,11 @@ Register (list, fname, vn, ts, options, tag, date, ts_conflict)
if (trace)
{
#ifdef SERVER_SUPPORT
(void) fprintf (stderr, "%c-> Register(%s, %s, %s%s%s, %s, %s %s)\n",
(server_active) ? 'S' : ' ',
(void) fprintf (stderr, "%s-> Register(%s, %s, %s%s%s, %s, %s %s)\n",
CLIENT_SERVER_STR,
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 (ENT_FILE, fname, vn, ts, options, tag, date,
@ -252,7 +243,15 @@ Register (list, fname, vn, ts, options, tag, date, ts_conflict)
if (!noexec)
{
entfilename = CVSADM_ENTLOG;
entfile = open_file (entfilename, "a");
entfile = CVS_FOPEN (entfilename, "a");
if (entfile == NULL)
{
/* Warning, not error, as in write_entries. */
/* FIXME-update-dir: should be including update_dir in message. */
error (0, errno, "cannot open %s", entfilename);
return;
}
if (fprintf (entfile, "A ") < 0)
error (1, errno, "cannot write %s", entfilename);
@ -507,7 +506,9 @@ Entries_Open (aflag, update_dir)
(void) AddEntryNode (entries, ent);
}
fclose (fpin);
if (fclose (fpin) < 0)
/* FIXME-update-dir: should include update_dir in message. */
error (0, errno, "cannot close %s", CVSADM_ENT);
}
fpin = CVS_FOPEN (CVSADM_ENTLOG, "r");
@ -535,7 +536,9 @@ Entries_Open (aflag, update_dir)
}
}
do_rewrite = 1;
fclose (fpin);
if (fclose (fpin) < 0)
/* FIXME-update-dir: should include update_dir in message. */
error (0, errno, "cannot close %s", CVSADM_ENTLOG);
}
/* Update the list private data to indicate whether subdirectory

View File

@ -61,8 +61,6 @@ void exit ();
extern char *strerror ();
#endif
extern int vasprintf ();
void
error_exit PROTO ((void))
{
@ -80,7 +78,10 @@ error_exit PROTO ((void))
}
/* Print the program name and error message MESSAGE, which is a printf-style
format string with optional args.
format string with optional args. This is a very limited printf subset:
%s, %d, %c, %x and %% only (without anything between the % and the s,
d, &c). Callers who want something fancier can use sprintf.
If ERRNUM is nonzero, print its corresponding system error message.
Exit with status EXIT_FAILURE if STATUS is nonzero. If MESSAGE is "",
no need to print a message.
@ -100,7 +101,7 @@ error_exit PROTO ((void))
/* VARARGS */
void
#if defined (HAVE_VPRINTF) && defined (__STDC__)
#if defined (__STDC__)
error (int status, int errnum, const char *message, ...)
#else
error (status, errnum, message, va_alist)
@ -110,116 +111,84 @@ error (status, errnum, message, va_alist)
va_dcl
#endif
{
/* Prevent strtoul (via int_vasprintf) from clobbering it. */
int save_errno = errno;
#ifdef HAVE_VPRINTF
if (message[0] != '\0')
{
va_list args;
char *mess = NULL;
char *entire;
size_t len;
VA_START (args, message);
vasprintf (&mess, message, args);
va_end (args);
if (mess == NULL)
{
entire = NULL;
status = 1;
}
else
{
len = strlen (mess) + strlen (program_name) + 80;
if (command_name != NULL)
len += strlen (command_name);
if (errnum != 0)
len += strlen (strerror (errnum));
entire = malloc (len);
if (entire == NULL)
{
free (mess);
status = 1;
}
else
{
strcpy (entire, program_name);
if (command_name != NULL && command_name[0] != '\0')
{
strcat (entire, " ");
if (status != 0)
strcat (entire, "[");
strcat (entire, command_name);
if (status != 0)
strcat (entire, " aborted]");
}
strcat (entire, ": ");
strcat (entire, mess);
if (errnum != 0)
{
strcat (entire, ": ");
strcat (entire, strerror (errnum));
}
strcat (entire, "\n");
free (mess);
}
}
cvs_outerr (entire ? entire : "out of memory\n", 0);
if (entire != NULL)
free (entire);
}
#else /* No HAVE_VPRINTF */
/* I think that all relevant systems have vprintf these days. But
just in case, I'm leaving this code here. */
if (message[0] != '\0')
{
FILE *out = stderr;
if (error_use_protocol)
{
out = stdout;
printf ("E ");
}
const char *p;
char *q;
char *str;
int num;
unsigned int unum;
int ch;
unsigned char buf[100];
cvs_outerr (program_name, 0);
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);
cvs_outerr (" ", 1);
if (status != 0)
cvs_outerr ("[", 1);
cvs_outerr (command_name, 0);
if (status != 0)
cvs_outerr (" aborted]", 0);
}
else
fprintf (out, "%s: ", program_name);
cvs_outerr (": ", 2);
#ifdef HAVE_VPRINTF
VA_START (args, message);
vfprintf (out, message, args);
p = message;
while ((q = strchr (p, '%')) != NULL)
{
static const char msg[] =
"\ninternal error: bad % in error()\n";
if (q - p > 0)
cvs_outerr (p, q - p);
switch (q[1])
{
case 's':
str = va_arg (args, char *);
cvs_outerr (str, strlen (str));
break;
case 'd':
num = va_arg (args, int);
sprintf (buf, "%d", num);
cvs_outerr (buf, strlen (buf));
break;
case 'x':
unum = va_arg (args, unsigned int);
sprintf (buf, "%x", unum);
cvs_outerr (buf, strlen (buf));
break;
case 'c':
ch = va_arg (args, int);
buf[0] = ch;
cvs_outerr (buf, 1);
break;
case '%':
cvs_outerr ("%", 1);
break;
default:
cvs_outerr (msg, sizeof (msg) - 1);
/* Don't just keep going, because q + 1 might point to the
terminating '\0'. */
goto out;
}
p = q + 2;
}
cvs_outerr (p, strlen (p));
out:
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);
/* In the error_use_protocol case, this probably does
something useful. In most other cases, I suspect it is a
noop (either stderr is line buffered or we haven't written
anything to stderr) or unnecessary (if stderr is not line
buffered, maybe there is a reason....). */
fflush (out);
if (errnum != 0)
{
cvs_outerr (": ", 2);
cvs_outerr (strerror (errnum), 0);
}
cvs_outerr ("\n", 1);
}
#endif /* No HAVE_VPRINTF */
if (status)
error_exit ();
errno = save_errno;

View File

@ -43,7 +43,7 @@ variable_set (nameval)
Node *node;
p = nameval;
while (isalnum (*p) || *p == '_')
while (isalnum ((unsigned char) *p) || *p == '_')
++p;
if (*p != '=')
error (1, 0, "illegal character in user variable name in %s", nameval);
@ -133,7 +133,7 @@ expand_path (name, file, line)
{
if (flag
? *s =='}'
: isalnum (*s) == 0 && *s != '_')
: isalnum ((unsigned char) *s) == 0 && *s != '_')
break;
doff = d - mybuf;
expand_string (&mybuf, &mybuf_size, doff + 1);
@ -214,6 +214,9 @@ expand_path (name, file, line)
t = ps->pw_dir;
#endif
}
if (t == NULL)
error (1, 0, "cannot find home directory");
doff = d - buf;
expand_string (&buf, &buf_size, doff + 1);
d = buf + doff;
@ -283,7 +286,7 @@ expand_variable (name, file, line)
return Editor;
else if (strcmp (name, "USER") == 0)
return getcaller ();
else if (isalpha (name[0]))
else if (isalpha ((unsigned char) name[0]))
{
/* These names are reserved for future versions of CVS,
so that is why it is an error. */

View File

@ -12,28 +12,24 @@
#ifndef FILEATTR_H
/* File containing per-file attributes. Format is a series of entries:
/* File containing per-file attributes. The format of this file is in
cvs.texinfo but here is a quick summary. The file contains a
series of entries:
ENT-TYPE FILENAME <tab> ATTRNAME = ATTRVAL
{; ATTRNAME = ATTRVAL} <linefeed>
ENT-TYPE is 'F' for a file, in which case the entry specifies the
attributes for that file.
ENT-TYPE is 'F' for a file.
ENT-TYPE is 'D', and FILENAME empty, to specify default attributes
to be used for newly added files.
ENT-TYPE is 'D', and FILENAME empty, for default attributes.
Other ENT-TYPE are reserved for future expansion. CVS 1.9 and older
will delete them any time it writes file attributes. Current versions
of CVS will preserve them.
Other ENT-TYPE are reserved for future expansion.
Note that the order of the line is not significant; CVS is free to
rearrange them at its convenience.
There is currently no way of quoting tabs or linefeeds in the
filename, '=' in ATTRNAME, ';' in ATTRVAL, etc. I'm not sure
whether I think we need one. Note: the current implementation also
doesn't handle '\0' in any of the fields.
FIXME: this implementation doesn't handle '\0' in any of the
fields. We are encouraged to fix this (by cvs.texinfo).
By convention, ATTRNAME starting with '_' is for an attribute given
special meaning by CVS; other ATTRNAMEs are for user-defined attributes

View File

@ -50,6 +50,11 @@ add_entries_proc (node, closure)
return (0);
}
/* Find files in the repository and/or working directory. On error,
may either print a nonfatal error and return NULL, or just give
a fatal error. On success, return non-NULL (even if it is an empty
list). */
List *
Find_Names (repository, which, aflag, optentries)
char *repository;
@ -85,7 +90,10 @@ Find_Names (repository, which, aflag, optentries)
{
/* search the repository */
if (find_rcs (repository, files) != 0)
error (1, errno, "cannot open directory %s", repository);
{
error (0, errno, "cannot open directory %s", repository);
goto error_exit;
}
/* search the attic too */
if (which & W_ATTIC)
@ -93,7 +101,11 @@ Find_Names (repository, which, aflag, optentries)
char *dir;
dir = xmalloc (strlen (repository) + sizeof (CVSATTIC) + 10);
(void) sprintf (dir, "%s/%s", repository, CVSATTIC);
(void) find_rcs (dir, files);
if (find_rcs (dir, files) != 0
&& !existence_error (errno))
/* For now keep this a fatal error, seems less useful
for access control than the case above. */
error (1, errno, "cannot open directory %s", dir);
free (dir);
}
}
@ -101,6 +113,9 @@ Find_Names (repository, which, aflag, optentries)
/* sort the list into alphabetical order and return it */
sortlist (files, fsortcmp);
return (files);
error_exit:
dellist (&files);
return NULL;
}
/*
@ -235,7 +250,9 @@ Find_Directories (repository, which, entries)
/*
* 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.
* cannot be opened, in which case errno is set to indicate the error.
* In the error case LIST is left in some reasonable state (unchanged, or
* containing the files which were found before the error occurred).
*/
static int
find_rcs (dir, list)
@ -251,6 +268,7 @@ find_rcs (dir, list)
return (1);
/* read the dir, grabbing the ,v files */
errno = 0;
while ((dp = readdir (dirp)) != NULL)
{
if (CVS_FNMATCH (RCSPAT, dp->d_name, 0) == 0)
@ -265,6 +283,14 @@ find_rcs (dir, list)
if (addnode (list, p) != 0)
freenode (p);
}
errno = 0;
}
if (errno != 0)
{
int save_errno = errno;
(void) closedir (dirp);
errno = save_errno;
return 1;
}
(void) closedir (dirp);
return (0);
@ -275,7 +301,7 @@ find_rcs (dir, list)
* the specified list. Sub-directories without a CVS administration
* directory are optionally ignored. If ENTRIES is not NULL, all
* files on the list are ignored. Returns 0 for success or 1 on
* error.
* error, in which case errno is set to indicate the error.
*/
static int
find_dirs (dir, list, checkadm, entries)
@ -305,6 +331,7 @@ find_dirs (dir, list, checkadm, entries)
return (1);
/* read the dir, grabbing sub-dirs */
errno = 0;
while ((dp = readdir (dirp)) != NULL)
{
if (strcmp (dp->d_name, ".") == 0 ||
@ -312,34 +339,34 @@ find_dirs (dir, list, checkadm, entries)
strcmp (dp->d_name, CVSATTIC) == 0 ||
strcmp (dp->d_name, CVSLCK) == 0 ||
strcmp (dp->d_name, CVSREP) == 0)
continue;
goto do_it_again;
/* findnode() is going to be significantly faster than stat()
because it involves no system calls. That is why we bother
with the entries argument, and why we check this first. */
if (entries != NULL && findnode (entries, dp->d_name) != NULL)
continue;
goto do_it_again;
if (skip_emptydir
&& strcmp (dp->d_name, CVSNULLREPOS) == 0)
continue;
goto do_it_again;
#ifdef DT_DIR
if (dp->d_type != DT_DIR)
{
if (dp->d_type != DT_UNKNOWN && dp->d_type != DT_LNK)
continue;
goto do_it_again;
#endif
/* don't bother stating ,v files */
if (CVS_FNMATCH (RCSPAT, dp->d_name, 0) == 0)
continue;
goto do_it_again;
expand_string (&tmp,
&tmp_size,
strlen (dir) + strlen (dp->d_name) + 10);
sprintf (tmp, "%s/%s", dir, dp->d_name);
if (!isdir (tmp))
continue;
goto do_it_again;
#ifdef DT_DIR
}
@ -354,12 +381,12 @@ find_dirs (dir, list, checkadm, entries)
{
/* we're either unknown or a symlink at this point */
if (dp->d_type == DT_LNK)
continue;
goto do_it_again;
#endif
/* Note that we only get here if we already set tmp
above. */
if (islink (tmp))
continue;
goto do_it_again;
#ifdef DT_DIR
}
#endif
@ -371,7 +398,7 @@ find_dirs (dir, list, checkadm, entries)
+ sizeof (CVSADM) + 10));
(void) sprintf (tmp, "%s/%s/%s", dir, dp->d_name, CVSADM);
if (!isdir (tmp))
continue;
goto do_it_again;
}
/* put it in the list */
@ -380,6 +407,16 @@ find_dirs (dir, list, checkadm, entries)
p->key = xstrdup (dp->d_name);
if (addnode (list, p) != 0)
freenode (p);
do_it_again:
errno = 0;
}
if (errno != 0)
{
int save_errno = errno;
(void) closedir (dirp);
errno = save_errno;
return 1;
}
(void) closedir (dirp);
if (tmp != NULL)

View File

@ -66,7 +66,7 @@ lookup_file_by_inode (filepath)
inodestr = (char *) xmalloc (2*sizeof(ino_t)*sizeof(char) + 1);
if (stat (file, &sb) < 0)
{
if (errno == ENOENT)
if (existence_error (errno))
{
/* The file doesn't exist; we may be doing an update on a
file that's been removed. A nonexistent file has no

View File

@ -719,12 +719,8 @@ history_write (type, update_dir, revs, name, repository)
}
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
fprintf (stderr, "%s-> fopen(%s,a)\n",
CLIENT_SERVER_STR, fname);
if (noexec)
goto out;
fd = CVS_OPEN (fname, O_WRONLY | O_APPEND | O_CREAT | OPEN_BINARY, 0666);
@ -971,7 +967,7 @@ expand_modules ()
* 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)
#define NEXT_BAR(here) do { while (isspace((unsigned char) *line)) line++; hr->here = line; while ((c = *line++) && c != '|') ; if (!c) return(rtn); *(line - 1) = '\0'; } while (0)
static char *
fill_hrec (line, hr)
@ -985,7 +981,7 @@ fill_hrec (line, hr)
unsigned long date;
memset ((char *) hr, 0, sizeof (*hr));
while (isspace (*line))
while (isspace ((unsigned char) *line))
line++;
if (!(rtn = strchr (line, '\n')))
return ("");
@ -1062,7 +1058,7 @@ read_hrecs (fname)
*(cp + i) = '\0';
for (cp2 = cp; cp2 - cp < i; cp2++)
{
if (*cp2 != '\n' && !isprint (*cp2))
if (*cp2 != '\n' && !isprint ((unsigned char) *cp2))
*cp2 = ' ';
}

View File

@ -82,6 +82,11 @@ ign_setup ()
/* Then add entries found in home dir, (if user has one) and file exists */
home_dir = get_homedir ();
/* If we can't find a home directory, ignore ~/.cvsignore. This may
make tracking down problems a bit of a pain, but on the other
hand it might be obnoxious to complain when CVS will function
just fine without .cvsignore (and many users won't even know what
.cvsignore is). */
if (home_dir)
{
char *file = xmalloc (strlen (home_dir) + sizeof (CVSDOTIGNORE) + 10);
@ -176,7 +181,7 @@ ign_add (ign, hold)
char save;
/* ignore whitespace before the token */
if (isspace (*ign))
if (isspace ((unsigned char) *ign))
continue;
/*
@ -184,7 +189,8 @@ ign_add (ign, hold)
* (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 ((!*(ign+1) || isspace ((unsigned char) *(ign+1)))
&& (*ign == '!' || *ign == '*'))
{
if (!hold)
{
@ -233,7 +239,7 @@ ign_add (ign, hold)
}
/* find the end of this token */
for (mark = ign; *mark && !isspace (*mark); mark++)
for (mark = ign; *mark && !isspace ((unsigned char) *mark); mark++)
/* do nothing */ ;
save = *mark;
@ -395,11 +401,15 @@ ignore_files (ilist, entries, update_dir, proc)
dirp = CVS_OPENDIR (".");
if (dirp == NULL)
{
error (0, errno, "cannot open current directory");
return;
}
ign_add_file (CVSDOTIGNORE, 1);
wrap_add_file (CVSDOTWRAPPER, 1);
errno = 0;
while ((dp = readdir (dirp)) != NULL)
{
file = dp->d_name;
@ -476,6 +486,9 @@ ignore_files (ilist, entries, update_dir, proc)
}
(*proc) (file, xdir);
errno = 0;
}
if (errno != 0)
error (0, errno, "error reading current directory");
(void) closedir (dirp);
}

View File

@ -7,9 +7,6 @@
*
* 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).
@ -233,8 +230,8 @@ cvslog (argc, argv)
for (i = 1; i < argc && argv[i][0] == '-'; i++)
send_arg (argv[i]);
send_file_names (argc - i, argv + i, SEND_EXPAND_WILD);
send_files (argc - i, argv + i, local, 0, SEND_NO_CONTENTS);
send_file_names (argc - i, argv + i, SEND_EXPAND_WILD);
send_to_server ("log\012", 0);
err = get_responses_and_close ();
@ -591,11 +588,11 @@ log_fileproc (callerdat, finfo)
cvs_output ("\n\t", 2);
cp2 = cp;
while (! isspace (*cp2) && *cp2 != '\0')
while (! isspace ((unsigned char) *cp2) && *cp2 != '\0')
++cp2;
cvs_output (cp, cp2 - cp);
cp = cp2;
while (isspace (*cp) && *cp != '\0')
while (isspace ((unsigned char) *cp) && *cp != '\0')
++cp;
}
}
@ -734,7 +731,7 @@ log_expand_revlist (rcs, revlist, default_branch)
char *branch;
/* Print just the head of the branch. */
if (isdigit (r->first[0]))
if (isdigit ((unsigned char) r->first[0]))
nr->first = RCS_getbranch (rcs, r->first, 1);
else
{
@ -761,7 +758,7 @@ log_expand_revlist (rcs, revlist, default_branch)
}
else
{
if (r->first == NULL || isdigit (r->first[0]))
if (r->first == NULL || isdigit ((unsigned char) r->first[0]))
nr->first = xstrdup (r->first);
else
{
@ -780,7 +777,7 @@ log_expand_revlist (rcs, revlist, default_branch)
if (r->last == r->first)
nr->last = xstrdup (nr->first);
else if (r->last == NULL || isdigit (r->last[0]))
else if (r->last == NULL || isdigit ((unsigned char) r->last[0]))
nr->last = xstrdup (r->last);
else
{
@ -1356,12 +1353,12 @@ version_compare (v1, v2, len)
while (*v1 == '0')
++v1;
for (d1 = 0; isdigit (v1[d1]); ++d1)
for (d1 = 0; isdigit ((unsigned char) v1[d1]); ++d1)
;
while (*v2 == '0')
++v2;
for (d2 = 0; isdigit (v2[d2]); ++d2)
for (d2 = 0; isdigit ((unsigned char) v2[d2]); ++d2)
;
if (d1 != d2)

View File

@ -20,6 +20,7 @@
* command line.
*/
#include <assert.h>
#include "cvs.h"
#include "savecwd.h"
@ -120,7 +121,8 @@ do_module (db, mname, m_type, msg, callback_proc, where,
int xmodargc;
char **modargv;
char **xmodargv;
char *value;
/* Found entry from modules file, including options and such. */
char *value = NULL;
char *zvalue = NULL;
char *mwhere = NULL;
char *mfile = NULL;
@ -147,8 +149,8 @@ do_module (db, mname, m_type, msg, callback_proc, where,
+ strlen (msg)
+ (where ? strlen (where) : 0)
+ (extra_arg ? strlen (extra_arg) : 0));
sprintf (buf, "%c-> do_module (%s, %s, %s, %s)\n",
(server_active) ? 'S' : ' ',
sprintf (buf, "%s-> do_module (%s, %s, %s, %s)\n",
CLIENT_SERVER_STR,
mname, msg, where ? where : "",
extra_arg ? extra_arg : "");
cvs_outerr (buf, 0);
@ -192,13 +194,13 @@ do_module (db, mname, m_type, msg, callback_proc, where,
{
do
*cp-- = '\0';
while (isspace (*cp));
while (isspace ((unsigned char) *cp));
}
else
{
/* Always strip trailing spaces */
cp = strchr (val.dptr, '\0');
while (cp > val.dptr && isspace(*--cp))
while (cp > val.dptr && isspace ((unsigned char) *--cp))
*cp = '\0';
}
@ -231,7 +233,9 @@ do_module (db, mname, m_type, msg, callback_proc, where,
if (isdir (file))
{
value = mname;
modargv = xmalloc (sizeof (*modargv));
modargv[0] = xstrdup (mname);
modargc = 1;
is_found = 1;
}
else
@ -242,14 +246,12 @@ do_module (db, mname, m_type, msg, callback_proc, where,
/* 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 */
xvalue = xmalloc (strlen (mname) + 2);
value = strcpy (xvalue, mname);
slashp = strrchr (value, '/');
*slashp = ' ';
modargv = xmalloc (2 * sizeof (*modargv));
modargv[0] = xmalloc (strlen (mname) + 2);
strncpy (modargv[0], mname, cp - mname);
modargv[0][cp - mname] = '\0';
modargv[1] = xstrdup (cp + 1);
modargc = 2;
}
else
{
@ -261,31 +263,54 @@ do_module (db, mname, m_type, msg, callback_proc, where,
if (cp == mname)
{
/* drop the leading / if specified */
xvalue = xmalloc (strlen (mname) + 10);
value = strcpy (xvalue, ". ");
(void) strcat (xvalue, mname + 1);
modargv = xmalloc (2 * sizeof (*modargv));
modargv[0] = xstrdup (".");
modargv[1] = xstrdup (mname + 1);
modargc = 2;
}
else
{
/* otherwise just copy it */
xvalue = xmalloc (strlen (mname) + 10);
value = strcpy (xvalue, ". ");
(void) strcat (xvalue, mname);
modargv = xmalloc (2 * sizeof (*modargv));
modargv[0] = xstrdup (".");
modargv[1] = xstrdup (mname);
modargc = 2;
}
}
is_found = 1;
}
else
{
/* This initialization suppresses a warning from gcc -Wall. */
value = NULL;
}
}
free (attic_file);
free (file);
if (is_found)
goto found;
{
assert (value == NULL);
/* OK, we have now set up modargv with the actual
file/directory we want to work on. We duplicate a
small amount of code here because the vast majority of
the code after the "found" label does not pertain to
the case where we found a file/directory rather than
finding an entry in the modules file. */
if (save_cwd (&cwd))
error_exit ();
cwd_saved = 1;
err += callback_proc (&modargc, modargv, where, mwhere, mfile,
shorten,
local_specified, mname, msg);
free_names (&modargc, modargv);
/* cd back to where we started. */
if (restore_cwd (&cwd, NULL))
error_exit ();
free_cwd (&cwd);
cwd_saved = 0;
goto do_module_return;
}
}
/* look up everything to the first / as a module */
@ -315,7 +340,7 @@ do_module (db, mname, m_type, msg, callback_proc, where,
{
do
*cp2-- = '\0';
while (isspace (*cp2));
while (isspace ((unsigned char) *cp2));
}
value = val.dptr;
@ -352,6 +377,7 @@ do_module (db, mname, m_type, msg, callback_proc, where,
/* copy value to our own string since if we go recursive we'll be
really screwed if we do another dbm lookup */
assert (value != NULL);
zvalue = xstrdup (value);
value = zvalue;
@ -362,7 +388,7 @@ do_module (db, mname, m_type, msg, callback_proc, where,
spec_opt = cp + 1; /* save the options for later */
if (cp != value) /* strip whitespace if necessary */
while (isspace (*--cp))
while (isspace ((unsigned char) *--cp))
*cp = '\0';
if (cp == value)
@ -609,13 +635,13 @@ module `%s' is a request for a file in a module which is not a directory",
/* strip whitespace off the end */
do
*cp = '\0';
while (isspace (*--cp));
while (isspace ((unsigned char) *--cp));
}
else
next_opt = NULL;
/* strip whitespace from front */
while (isspace (*spec_opt))
while (isspace ((unsigned char) *spec_opt))
spec_opt++;
if (*spec_opt == '\0')
@ -836,15 +862,15 @@ save_d (k, ks, d, ds)
cp = d;
*(cp + ds) = '\0'; /* Assumes an extra byte at end of static dbm buffer */
while (isspace (*cp))
while (isspace ((unsigned char) *cp))
cp++;
/* Turn <spaces> into one ' ' -- makes the rest of this routine simpler */
while (*cp)
{
if (isspace (*cp))
if (isspace ((unsigned char) *cp))
{
*cp2++ = ' ';
while (isspace (*cp))
while (isspace ((unsigned char) *cp))
cp++;
}
else

View File

@ -263,7 +263,7 @@ mydbm_load_file (fp, list)
if (value[0] == '#')
continue; /* comment line */
vp = value;
while (*vp && isspace (*vp))
while (*vp && isspace ((unsigned char) *vp))
vp++;
if (*vp == '\0')
continue; /* empty line */
@ -277,12 +277,12 @@ mydbm_load_file (fp, list)
char *kp;
kp = vp;
while (*vp && !isspace (*vp))
while (*vp && !isspace ((unsigned char) *vp))
vp++;
*vp++ = '\0'; /* NULL terminate the key */
p->type = NDBMNODE;
p->key = xstrdup (kp);
while (*vp && isspace (*vp))
while (*vp && isspace ((unsigned char) *vp))
vp++; /* skip whitespace to value */
if (*vp == '\0')
{

View File

@ -82,13 +82,8 @@ No_Difference (finfo, vers)
/* 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);
(void) fprintf (stderr, "%s-> unlink (%s)\n",
CLIENT_SERVER_STR, tocvsPath);
if ( CVS_UNLINK (tocvsPath) < 0)
error (0, errno, "could not remove %s", tocvsPath);
}

View File

@ -88,13 +88,12 @@
* repository, change the contents of CVS/Root files in your
* checked-out code, and CVS will work without problems.
*
* This is likely to be the default in the future, but we want to give
* people who may be relying on absolute pathnames time to update
* their scripts/software.
* Therefore, RELATIVE_REPOS is now the default. In the future, this
* is likely to disappear entirely as a compile-time (or other) option,
* so if you have other software which relies on absolute pathnames,
* update them.
*/
#ifndef RELATIVE_REPOS
/* #define RELATIVE_REPOS */
#endif
#define RELATIVE_REPOS 1
/*
* When committing or importing files, you must enter a log message.

View File

@ -77,7 +77,7 @@ Parse_Info (infofile, repository, callproc, all)
continue;
/* skip whitespace at beginning of line */
for (cp = line; *cp && isspace (*cp); cp++)
for (cp = line; *cp && isspace ((unsigned char) *cp); cp++)
;
/* if *cp is null, the whole line was blank */
@ -85,13 +85,13 @@ Parse_Info (infofile, repository, callproc, all)
continue;
/* the regular expression is everything up to the first space */
for (exp = cp; *cp && !isspace (*cp); cp++)
for (exp = cp; *cp && !isspace ((unsigned char) *cp); cp++)
;
if (*cp != '\0')
*cp++ = '\0';
/* skip whitespace up to the start of the matching value */
while (*cp && isspace (*cp))
while (*cp && isspace ((unsigned char) *cp))
cp++;
/* no value to match with the regular expression is an error */
@ -358,6 +358,15 @@ warning: this CVS does not support PreservePermissions");
goto error_return;
}
}
else if (strcmp (line, "LockDir") == 0)
{
if (lock_dir != NULL)
free (lock_dir);
lock_dir = xstrdup (p);
/* Could try some validity checking, like whether we can
opendir it or something, but I don't see any particular
reason to do that now rather than waiting until lock.c. */
}
else
{
/* We may be dealing with a keyword which was added in a

View File

@ -763,19 +763,29 @@ patch_dirproc (callerdat, dir, repos, update_dir, entries)
static RETSIGTYPE
patch_cleanup ()
{
/* Note that the checks for existence_error are because we are
called from a signal handler, without SIG_begincrsect, so
we don't know whether the files got created. */
if (tmpfile1 != NULL)
{
(void) unlink_file (tmpfile1);
if (unlink_file (tmpfile1) < 0
&& !existence_error (errno))
error (0, errno, "cannot remove %s", tmpfile1);
free (tmpfile1);
}
if (tmpfile2 != NULL)
{
(void) unlink_file (tmpfile2);
if (unlink_file (tmpfile2) < 0
&& !existence_error (errno))
error (0, errno, "cannot remove %s", tmpfile2);
free (tmpfile2);
}
if (tmpfile3 != NULL)
{
(void) unlink_file (tmpfile3);
if (unlink_file (tmpfile3) < 0
&& !existence_error (errno))
error (0, errno, "cannot remove %s", tmpfile3);
free (tmpfile3);
}
tmpfile1 = tmpfile2 = tmpfile3 = NULL;

View File

@ -6,10 +6,9 @@
*/
#include "cvs.h"
#include "savecwd.h"
#include "getline.h"
static void release_delete PROTO((char *dir));
static const char *const release_usage[] =
{
"Usage: %s %s [-d] directories...\n",
@ -76,6 +75,7 @@ release (argc, argv)
int arg_start_idx;
int err = 0;
short delete_flag = 0;
struct saved_cwd cwd;
#ifdef SERVER_SUPPORT
if (server_active)
@ -111,6 +111,10 @@ release (argc, argv)
/* 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.
* (Well, actually we ask no matter what. Our notion of "sufficiently
* unalarming" doesn't take into account "? foo.c" files, so it is
* up to the user to take note of them, at least currently
* (ignore-193 in testsuite)).
*/
/* Construct the update command. */
update_cmd = xmalloc (strlen (program_path)
@ -128,6 +132,12 @@ release (argc, argv)
}
#endif /* CLIENT_SUPPORT */
/* Remember the directory where "cvs release" was invoked because
all args are relative to this directory and we chdir around.
*/
if (save_cwd (&cwd))
error_exit ();
arg_start_idx = 0;
for (i = arg_start_idx; i < argc; i++)
@ -146,6 +156,8 @@ release (argc, argv)
{
if (!really_quiet)
error (0, 0, "no repository directory: %s", thisarg);
if (restore_cwd (&cwd, NULL))
error_exit ();
continue;
}
}
@ -190,6 +202,9 @@ release (argc, argv)
if ((pclose (fp)) != 0)
{
error (0, 0, "unable to release `%s'", thisarg);
free (repository);
if (restore_cwd (&cwd, NULL))
error_exit ();
continue;
}
@ -203,6 +218,8 @@ release (argc, argv)
(void) fprintf (stderr, "** `%s' aborted by user choice.\n",
command_name);
free (repository);
if (restore_cwd (&cwd, NULL))
error_exit ();
continue;
}
}
@ -239,7 +256,19 @@ release (argc, argv)
}
free (repository);
if (delete_flag) release_delete (thisarg);
if (restore_cwd (&cwd, NULL))
error_exit ();
if (delete_flag)
{
/* FIXME? Shouldn't this just delete the CVS-controlled
files and, perhaps, the files that would normally be
ignored and leave everything else? */
if (unlink_file_dir (thisarg) < 0)
error (0, errno, "deletion of directory %s failed", thisarg);
}
#ifdef CLIENT_SUPPORT
if (client_active)
@ -247,6 +276,10 @@ release (argc, argv)
#endif /* CLIENT_SUPPORT */
}
if (restore_cwd (&cwd, NULL))
error_exit ();
free_cwd (&cwd);
#ifdef CLIENT_SUPPORT
if (client_active)
{
@ -264,37 +297,3 @@ release (argc, argv)
free (line);
return err;
}
/* 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;
(void) CVS_STAT (".", &st);
ino = st.st_ino;
(void) CVS_CHDIR ("..");
(void) CVS_STAT (dir, &st);
if (ino != st.st_ino)
{
/* This test does not work on cygwin32, because under cygwin32
the st_ino field is not the same when you refer to a file
by a different name. This is a cygwin32 bug, but then I
don't see what the point of this test is anyhow. */
#ifndef __CYGWIN32__
error (0, 0,
"Parent dir on a different disk, delete of %s aborted", dir);
return;
#endif
}
/*
* XXX - shouldn't this just delete the CVS-controlled files and, perhaps,
* the files that would normally be ignored and leave everything else?
*/
if (unlink_file_dir (dir) < 0)
error (0, errno, "deletion of directory %s failed", dir);
}

View File

@ -100,9 +100,9 @@ cvsremove (argc, argv)
ign_setup ();
if (local)
send_arg("-l");
send_file_names (argc, argv, 0);
/* FIXME: Can't we set SEND_NO_CONTENTS here? Needs investigation. */
send_files (argc, argv, local, 0, 0);
send_file_names (argc, argv, 0);
send_to_server ("remove\012", 0);
return get_responses_and_close ();
}
@ -200,7 +200,9 @@ remove_fileproc (callerdat, finfo)
+ sizeof (CVSEXT_LOG)
+ 10);
(void) sprintf (fname, "%s/%s%s", CVSADM, finfo->file, CVSEXT_LOG);
(void) unlink_file (fname);
if (unlink_file (fname) < 0
&& !existence_error (errno))
error (0, errno, "cannot remove %s", CVSEXT_LOG);
if (!quiet)
error (0, 0, "removed `%s'", finfo->fullname);
@ -216,7 +218,7 @@ remove_fileproc (callerdat, finfo)
error (0, 0, "file `%s' already scheduled for removal",
finfo->fullname);
}
else if (vers->tag != NULL && isdigit (*vers->tag))
else if (vers->tag != NULL && isdigit ((unsigned char) *vers->tag))
{
/* Commit will just give an error, and so there seems to be
little reason to allow the remove. I mean, conflicts that

View File

@ -7,8 +7,6 @@
* 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"
@ -18,7 +16,7 @@
Watch out if the enum is changed in cvs.h! */
char *method_names[] = {
"local", "server (rsh)", "pserver", "kserver", "gserver", "ext"
"local", "server (rsh)", "pserver", "kserver", "gserver", "ext", "fork"
};
#ifndef DEBUG
@ -268,6 +266,11 @@ error 0 Server configuration missing --allow-root in inetd.conf\n");
return 0;
}
/* This global variable holds the global -d option. It is NULL if -d
was not used, which means that we must get the CVSroot information
from the CVSROOT environment variable or from a CVS/Root file. */
char *CVSroot_cmdline;
/* Parse a CVSROOT variable into its constituent parts -- method,
* username, hostname, directory. The prototypical CVSROOT variable
@ -287,30 +290,6 @@ char *CVSroot_username; /* the username or NULL if method == local */
char *CVSroot_hostname; /* the hostname or NULL if method == local */
char *CVSroot_directory; /* the directory name */
#ifdef AUTH_SERVER_SUPPORT
/* Die if CVSroot_directory and Pserver_Repos don't match. */
static void
check_root_consistent ()
{
/* FIXME: Should be using a deferred error, as the rest of
serve_root does. As it is now the call to error could conceivably
cause deadlock, as noted in server_cleanup. Best solution would
presumably be to write some code so that error() automatically
defers the error in those cases where that is needed. */
/* FIXME? Possible that the wording should be more clear (e.g.
Root says "%s" but pserver protocol says "%s"
or something which would aid people who are writing implementations
of the client side of the CVS protocol. I don't see any security
problem with revealing that information. */
if ((Pserver_Repos != NULL) && (CVSroot_directory != NULL))
if (strcmp (Pserver_Repos, CVSroot_directory) != 0)
error (1, 0, "repository mismatch: \"%s\" vs \"%s\"",
Pserver_Repos, CVSroot_directory);
}
#endif /* AUTH_SERVER_SUPPORT */
int
parse_cvsroot (CVSroot)
char *CVSroot;
@ -335,8 +314,9 @@ parse_cvsroot (CVSroot)
/* Access method specified, as in
* "cvs -d :pserver:user@host:/path",
* "cvs -d :local:e:\path", or
* "cvs -d :kserver:user@host:/path".
* "cvs -d :local:e:\path",
* "cvs -d :kserver:user@host:/path", or
* "cvs -d :fork:/path".
* We need to get past that part of CVSroot before parsing the
* rest of it.
*/
@ -363,6 +343,8 @@ parse_cvsroot (CVSroot)
CVSroot_method = server_method;
else if (strcmp (method, "ext") == 0)
CVSroot_method = ext_method;
else if (strcmp (method, "fork") == 0)
CVSroot_method = fork_method;
else
{
error (0, 0, "unknown method in CVSroot: %s", CVSroot);
@ -391,7 +373,8 @@ parse_cvsroot (CVSroot)
CVSroot_username = NULL;
CVSroot_hostname = NULL;
if (CVSroot_method != local_method)
if ((CVSroot_method != local_method)
&& (CVSroot_method != fork_method))
{
/* Check to see if there is a username in the string. */
@ -416,9 +399,6 @@ parse_cvsroot (CVSroot)
}
CVSroot_directory = cvsroot_copy;
#ifdef AUTH_SERVER_SUPPORT
check_root_consistent ();
#endif /* AUTH_SERVER_SUPPORT */
#if ! defined (CLIENT_SUPPORT) && ! defined (DEBUG)
if (CVSroot_method != local_method)
@ -442,10 +422,12 @@ parse_cvsroot (CVSroot)
switch (CVSroot_method)
{
case local_method:
case fork_method:
if (CVSroot_username || CVSroot_hostname)
{
error (0, 0, "can't specify hostname and username in CVSROOT");
error (0, 0, "when using local access method");
error (0, 0, "when using %s access method",
CVSroot_method == local_method ? "local" : "fork");
error (0, 0, "(%s)", CVSroot);
return 1;
}
@ -464,18 +446,20 @@ parse_cvsroot (CVSroot)
error (0, 0, "but your CVS executable doesn't support it");
error (0, 0, "(%s)", CVSroot);
return 1;
#endif
#else
check_hostname = 1;
break;
#endif
case gserver_method:
#ifndef HAVE_GSSAPI
error (0, 0, "Your CVSROOT is set for a GSSAPI access method");
error (0, 0, "but your CVS executable doesn't support it");
error (0, 0, "(%s)", CVSroot);
return 1;
#endif
#else
check_hostname = 1;
break;
#endif
case server_method:
case ext_method:
case pserver_method:
@ -504,18 +488,17 @@ parse_cvsroot (CVSroot)
/* Set up the global CVSroot* variables as if we're using the local
repository DIR. */
repository DIR. DIR must point to storage which will last for the
rest of the CVS invocation (for example, the caller might malloc it
and never free it, or free it just before exiting CVS). */
void
set_local_cvsroot (dir)
char *dir;
{
CVSroot_original = xstrdup (dir);
CVSroot_original = dir;
CVSroot_method = local_method;
CVSroot_directory = CVSroot_original;
#ifdef AUTH_SERVER_SUPPORT
check_root_consistent ();
#endif /* AUTH_SERVER_SUPPORT */
CVSroot_username = NULL;
CVSroot_hostname = NULL;
client_active = 0;
@ -523,7 +506,11 @@ set_local_cvsroot (dir)
#ifdef DEBUG
/* This is for testing the parsing function. */
/* This is for testing the parsing function. Use
gcc -I. -I.. -I../lib -DDEBUG root.c -o root
to compile. */
#include <stdio.h>
@ -531,6 +518,30 @@ char *CVSroot;
char *program_name = "testing";
char *command_name = "parse_cvsroot"; /* XXX is this used??? */
/* Toy versions of various functions when debugging under unix. Yes,
these make various bad assumptions, but they're pretty easy to
debug when something goes wrong. */
void
error_exit PROTO ((void))
{
exit (1);
}
char *
xstrdup (str)
const char *str;
{
return strdup (str);
}
int
isabsolute (dir)
const char *dir;
{
return (dir && (*dir == '/'));
}
void
main (argc, argv)
int argc;
@ -546,7 +557,7 @@ main (argc, argv)
if (parse_cvsroot (argv[1]))
{
fprintf (stderr, "%s: Parsing failed.", program_name);
fprintf (stderr, "%s: Parsing failed.\n", program_name);
exit (1);
}
printf ("CVSroot: %s\n", argv[1]);

View File

@ -64,7 +64,7 @@ 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",
"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",
@ -388,9 +388,16 @@ check_fileproc (callerdat, finfo)
{
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;
@ -458,7 +465,7 @@ pretag_proc(repository, filter)
s = xstrdup(filter);
for (cp=s; *cp; cp++)
{
if (isspace(*cp))
if (isspace ((unsigned char) *cp))
{
*cp = '\0';
break;
@ -583,7 +590,9 @@ rtag_fileproc (callerdat, finfo)
}
return (0);
}
if (numtag && isdigit (*numtag) && strcmp (numtag, version) != 0)
if (numtag
&& isdigit ((unsigned char) *numtag)
&& strcmp (numtag, version) != 0)
{
/*

View File

@ -175,10 +175,11 @@ run_exec (stin, stout, sterr, flags)
/* The output files, if any, are now created. Do the fork and dups.
We use vfork not so much for the sake of unices without
copy-on-write (such systems are rare these days), but for the
sake of systems without an MMU, which therefore can't do
copy-on-write (e.g. Amiga). The other solution is spawn (see
We use vfork not so much for a performance boost (the
performance boost, if any, is modest on most modern unices),
but for the sake of systems without a memory management unit,
which find it difficult or impossible to implement fork at all
(e.g. Amiga). The other solution is spawn (see
windows-NT/run.c). */
#ifdef HAVE_VFORK
@ -365,12 +366,8 @@ run_popen (cmd, mode)
const char *mode;
{
if (trace)
#ifdef SERVER_SUPPORT
(void) fprintf (stderr, "%c-> run_popen(%s,%s)\n",
(server_active) ? 'S' : ' ', cmd, mode);
#else
(void) fprintf (stderr, "-> run_popen(%s,%s)\n", cmd, mode);
#endif
(void) fprintf (stderr, "%s-> run_popen(%s,%s)\n",
CLIENT_SERVER_STR, cmd, mode);
if (noexec)
return (NULL);
@ -409,21 +406,21 @@ piped_child (command, tofdp, fromfdp)
if (pid == 0)
{
if (dup2 (to_child_pipe[0], STDIN_FILENO) < 0)
error (1, errno, "cannot dup2");
error (1, errno, "cannot dup2 pipe");
if (close (to_child_pipe[1]) < 0)
error (1, errno, "cannot close");
error (1, errno, "cannot close pipe");
if (close (from_child_pipe[0]) < 0)
error (1, errno, "cannot close");
error (1, errno, "cannot close pipe");
if (dup2 (from_child_pipe[1], STDOUT_FILENO) < 0)
error (1, errno, "cannot dup2");
error (1, errno, "cannot dup2 pipe");
execvp (command[0], command);
error (1, errno, "cannot exec");
error (1, errno, "cannot exec %s", command[0]);
}
if (close (to_child_pipe[0]) < 0)
error (1, errno, "cannot close");
error (1, errno, "cannot close pipe");
if (close (from_child_pipe[1]) < 0)
error (1, errno, "cannot close");
error (1, errno, "cannot close pipe");
*tofdp = to_child_pipe[1];
*fromfdp = from_child_pipe[0];
@ -436,81 +433,7 @@ 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);
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
*
* Returns: a file descriptor. On failure (i.e., the exec fails),
* then filter_stream_through_program() complains and dies.
*/
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");
#ifdef USE_SETMODE_BINARY
setmode (p[0], O_BINARY);
setmode (p[1], O_BINARY);
#endif
#ifdef HAVE_VFORK
newpid = vfork ();
#else
newpid = fork ();
#endif
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;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -7,6 +7,16 @@
#define STDERR_FILENO 2
#endif
/*
* Expand to `S', ` ', or the empty string. Used in `%s-> ...' trace printfs.
*/
#ifdef SERVER_SUPPORT
# define CLIENT_SERVER_STR ((server_active) ? "S" : " ")
#else
# define CLIENT_SERVER_STR ""
#endif
#ifdef SERVER_SUPPORT
/*
@ -139,38 +149,30 @@ struct request
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,
/* One or more of the RQ_* flags described below. */
int flags;
/* Some servers might lack this request. */
rq_optional,
/* If set, 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. */
#define RQ_ESSENTIAL 1
/*
* Set by the client to one of the following based on what this
* server actually supports.
*/
rq_supported,
rq_not_supported,
/* Set by the client if the server we are talking to supports it. */
#define RQ_SUPPORTED 2
/*
* If the server supports this request, and we do too, tell the
* server by making the request.
*/
rq_enableme
} status;
/* If set, and client and server both support the request, the
client should tell the server by making the request. */
#define RQ_ENABLEME 4
/* The server may accept this request before "Root". */
#define RQ_ROOTLESS 8
};
/* Table of requests ending with an entry with a NULL name. */
extern struct request requests[];
/* Gzip library, see zlib.c. */
extern void gunzip_and_write PROTO ((int, char *, unsigned char *, size_t));
extern void read_and_gzip PROTO ((int, char *, unsigned char **, size_t *,
size_t *, int));
extern int gunzip_and_write PROTO ((int, char *, unsigned char *, size_t));
extern int read_and_gzip PROTO ((int, char *, unsigned char **, size_t *,
size_t *, int));

View File

@ -67,37 +67,38 @@ cvsstatus (argc, argv)
wrap_setup ();
#ifdef CLIENT_SUPPORT
if (client_active) {
start_server ();
if (client_active)
{
start_server ();
ign_setup ();
ign_setup ();
if (long_format)
send_arg("-v");
if (local)
send_arg("-l");
if (long_format)
send_arg("-v");
if (local)
send_arg("-l");
send_file_names (argc, argv, SEND_EXPAND_WILD);
/* For a while, we tried setting SEND_NO_CONTENTS here so this
could be a fast operation. That prevents the
server from updating our timestamp if the timestamp is
changed but the file is unmodified. Worse, it is user-visible
(shows "locally modified" instead of "up to date" if
timestamp is changed but file is not). And there is no good
workaround (you might not want to run "cvs update"; "cvs -n
update" doesn't update CVS/Entries; "cvs diff --brief" or
something perhaps could be made to work but somehow that
seems nonintuitive to me even if so). Given that timestamps
seem to have the potential to get munged for any number of
reasons, it seems better to not rely too much on them. */
/* For a while, we tried setting SEND_NO_CONTENTS here so this
could be a fast operation. That prevents the
server from updating our timestamp if the timestamp is
changed but the file is unmodified. Worse, it is user-visible
(shows "locally modified" instead of "up to date" if
timestamp is changed but file is not). And there is no good
workaround (you might not want to run "cvs update"; "cvs -n
update" doesn't update CVS/Entries; "cvs diff --brief" or
something perhaps could be made to work but somehow that
seems nonintuitive to me even if so). Given that timestamps
seem to have the potential to get munged for any number of
reasons, it seems better to not rely too much on them. */
send_files (argc, argv, local, 0, 0);
send_files (argc, argv, local, 0, 0);
send_file_names (argc, argv, SEND_EXPAND_WILD);
send_to_server ("status\012", 0);
err = get_responses_and_close ();
send_to_server ("status\012", 0);
err = get_responses_and_close ();
return err;
return err;
}
#endif
@ -242,7 +243,7 @@ status_fileproc (callerdat, finfo)
}
else
{
if (isdigit (edata->tag[0]))
if (isdigit ((unsigned char) edata->tag[0]))
{
cvs_output (" Sticky Tag:\t\t", 0);
cvs_output (edata->tag, 0);
@ -288,20 +289,20 @@ status_fileproc (callerdat, finfo)
}
else if (!really_quiet)
cvs_output (" Sticky Options:\t(none)\n", 0);
}
if (long_format && vers->srcfile)
if (long_format && vers->srcfile)
{
List *symbols = RCS_symbols(vers->srcfile);
cvs_output ("\n Existing Tags:\n", 0);
if (symbols)
{
List *symbols = RCS_symbols(vers->srcfile);
cvs_output ("\n Existing Tags:\n", 0);
if (symbols)
{
xrcsnode = finfo->rcs;
(void) walklist (symbols, tag_list_proc, NULL);
}
else
cvs_output ("\tNo Tags Exist\n", 0);
xrcsnode = finfo->rcs;
(void) walklist (symbols, tag_list_proc, NULL);
}
else
cvs_output ("\tNo Tags Exist\n", 0);
}
cvs_output ("\n", 0);

View File

@ -16,7 +16,7 @@ extern char *getlogin ();
/*
* malloc some data and die if it fails
*/
char *
void *
xmalloc (bytes)
size_t bytes;
{
@ -30,8 +30,12 @@ xmalloc (bytes)
cp = malloc (bytes);
if (cp == NULL)
error (1, 0, "out of memory; can not allocate %lu bytes",
(unsigned long) bytes);
{
char buf[80];
sprintf (buf, "out of memory; can not allocate %lu bytes",
(unsigned long) bytes);
error (1, 0, buf);
}
return (cp);
}
@ -53,7 +57,12 @@ xrealloc (ptr, bytes)
cp = realloc (ptr, bytes);
if (cp == NULL)
error (1, 0, "can not reallocate %lu bytes", (unsigned long) bytes);
{
char buf[80];
sprintf (buf, "out of memory; can not reallocate %lu bytes",
(unsigned long) bytes);
error (1, 0, buf);
}
return (cp);
}
@ -64,7 +73,11 @@ xrealloc (ptr, bytes)
memory which is likely to get as big as MAX_INCR shouldn't be doing
it in one block which must be contiguous, but since getrcskey does
so, we might as well limit the wasted memory to MAX_INCR or so
bytes. */
bytes.
MIN_INCR and MAX_INCR should both be powers of two and we generally
try to keep our allocations to powers of two for the most part.
Most malloc implementations these days tend to like that. */
#define MIN_INCR 1024
#define MAX_INCR (2*1024*1024)
@ -84,11 +97,15 @@ expand_string (strptr, n, newsize)
while (*n < newsize)
{
if (*n < MIN_INCR)
*n += MIN_INCR;
else if (*n > MAX_INCR)
*n = MIN_INCR;
else if (*n >= MAX_INCR)
*n += MAX_INCR;
else
{
*n *= 2;
if (*n > MAX_INCR)
*n = MAX_INCR;
}
}
*strptr = xrealloc (*strptr, *n);
}
@ -487,7 +504,7 @@ check_numeric (rev, argc, argv)
int argc;
char **argv;
{
if (rev == NULL || !isdigit (*rev))
if (rev == NULL || !isdigit ((unsigned char) *rev))
return;
/* Note that the check for whether we are processing more than one
@ -534,7 +551,7 @@ make_message_rcslegal (message)
}
/* Backtrack to last non-space at end of string, and truncate. */
while (dp > dst && isspace (dp[-1]))
while (dp > dst && isspace ((unsigned char) dp[-1]))
--dp;
*dp = '\0';
@ -615,15 +632,14 @@ get_file (name, fullname, mode, buf, bufsize, len)
}
else
{
if (CVS_LSTAT (name, &s) < 0)
error (1, errno, "can't stat %s", fullname);
/* Although it would be cleaner in some ways to just read
until end of file, reallocating the buffer, this function
does get called on files in the working directory which can
be of arbitrary size, so I think we better do all that
extra allocation. */
/* Don't attempt to read special files or symlinks. */
if (!S_ISREG (s.st_mode))
{
*len = 0;
return;
}
if (CVS_STAT (name, &s) < 0)
error (1, errno, "can't stat %s", fullname);
/* Convert from signed to unsigned. */
filesize = s.st_size;
@ -652,9 +668,7 @@ get_file (name, fullname, mode, buf, bufsize, len)
if (feof (e))
break;
/* It's probably paranoid to think S.ST_SIZE might be
too small to hold the entire file contents, but we
handle it just in case. */
/* Allocate more space if needed. */
if (tobuf == *buf + *bufsize)
{
int c;
@ -684,3 +698,49 @@ get_file (name, fullname, mode, buf, bufsize, len)
(*buf)[nread] = '\0';
}
}
/* Follow a chain of symbolic links to its destination. FILENAME
should be a handle to a malloc'd block of memory which contains the
beginning of the chain. This routine will replace the contents of
FILENAME with the destination (a real file). */
void
resolve_symlink (filename)
char **filename;
{
if ((! filename) || (! *filename))
return;
while (islink (*filename))
{
char *newname;
#ifdef HAVE_READLINK
/* The clean thing to do is probably to have each filesubr.c
implement this (with an error if not supported by the
platform, in which case islink would presumably return 0).
But that would require editing each filesubr.c and so the
expedient hack seems to be looking at HAVE_READLINK. */
newname = xreadlink (*filename);
#else
error (1, 0, "internal error: islink doesn't like readlink");
#endif
if (isabsolute (newname))
{
free (*filename);
*filename = newname;
}
else
{
char *oldname = last_component (*filename);
int dirlen = oldname - *filename;
char *fullnewname = xmalloc (dirlen + strlen (newname) + 1);
strncpy (fullnewname, *filename, dirlen);
strcpy (fullnewname + dirlen, newname);
free (newname);
free (*filename);
*filename = fullnewname;
}
}
}

View File

@ -59,7 +59,7 @@ static List *tlist;
static const char *const tag_usage[] =
{
"Usage: %s %s [-lRF] [-b] [-d] [-c] [-r tag|-D date] tag [files...]\n",
"Usage: %s %s [-lRF] [-b] [-d] [-c] [-r rev|-D date] tag [files...]\n",
"\t-l\tLocal directory only, not recursive.\n",
"\t-R\tProcess directories recursively.\n",
"\t-d\tDelete the given tag.\n",
@ -178,15 +178,13 @@ cvstag (argc, argv)
send_arg (symtag);
send_files (argc, argv, local, 0,
/* I think the -c case is like "cvs status", in
which we really better be correct rather than
being fast; it is just too confusing otherwise. */
check_uptodate ? 0 : SEND_NO_CONTENTS);
send_file_names (argc, argv, SEND_EXPAND_WILD);
/* SEND_NO_CONTENTS has a mildly bizarre interaction with
check_uptodate; if the timestamp is modified but the file
is unmodified, the check will fail, only to have "cvs diff"
show no differences (and one must do "update" or something to
reset the client's notion of the timestamp). */
send_files (argc, argv, local, 0, SEND_NO_CONTENTS);
send_to_server ("tag\012", 0);
return get_responses_and_close ();
}
@ -297,9 +295,16 @@ check_fileproc (callerdat, finfo)
{
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;
@ -367,7 +372,7 @@ pretag_proc(repository, filter)
s = xstrdup(filter);
for (cp=s; *cp; cp++)
{
if (isspace(*cp))
if (isspace ((unsigned char) *cp))
{
*cp = '\0';
break;
@ -747,12 +752,12 @@ tag_check_valid (name, argc, argv, local, aflag, repository)
int which;
/* Numeric tags require only a syntactic check. */
if (isdigit (name[0]))
if (isdigit ((unsigned char) name[0]))
{
char *p;
for (p = name; *p != '\0'; ++p)
{
if (!(isdigit (*p) || *p == '.'))
if (!(isdigit ((unsigned char) *p) || *p == '.'))
error (1, 0, "\
Numeric tag %s contains characters other than digits and '.'", name);
}
@ -903,12 +908,19 @@ tag_check_valid_join (join_tag, argc, argv, local, aflag, repository)
s = strchr (c, ':');
if (s != NULL)
{
if (isdigit (join_tag[0]))
if (isdigit ((unsigned char) join_tag[0]))
error (1, 0,
"Numeric join tag %s may not contain a date specifier",
join_tag);
*s = '\0';
/* hmmm... I think it makes sense to allow -j:<date>, but
* for now this fixes a bug where CVS just spins and spins (I
* think in the RCS code) looking for a zero length tag.
*/
if (!*c)
error (1, 0,
"argument to join may not contain a date specifier without a tag");
}
tag_check_valid (c, argc, argv, local, aflag, repository);

View File

@ -34,6 +34,10 @@ Version_TS (finfo, options, tag, date, force_tag_match, set_time)
struct stickydirtag *sdtp;
Entnode *entdata;
#ifdef UTIME_EXPECTS_WRITABLE
int change_it_back = 0;
#endif
/* get a new Vers_TS struct */
vers_ts = (Vers_TS *) xmalloc (sizeof (Vers_TS));
memset ((char *) vers_ts, 0, sizeof (*vers_ts));
@ -209,12 +213,28 @@ Version_TS (finfo, options, tag, date, force_tag_match, set_time)
{
t.actime = t.modtime;
#ifdef UTIME_EXPECTS_WRITABLE
if (!iswritable (finfo->file))
{
xchmod (finfo->file, 1);
change_it_back = 1;
}
#endif /* UTIME_EXPECTS_WRITABLE */
/* This used to need to ignore existence_errors
(for cases like where update.c now clears
set_time if noexec, but didn't used to). I
think maybe now it doesn't (server_modtime does
not like those kinds of cases). */
(void) utime (finfo->file, &t);
#ifdef UTIME_EXPECTS_WRITABLE
if (change_it_back == 1)
{
xchmod (finfo->file, 0);
change_it_back = 0;
}
#endif /* UTIME_EXPECTS_WRITABLE */
}
}
}

View File

@ -12,8 +12,7 @@
#include "cvs.h"
/* NOTE: remember to remove `Halibut' when patching this code. */
char *version_string = "\nConcurrent Versions System (CVS) 1.10 `Halibut'";
char *version_string = "\nConcurrent Versions System (CVS) 1.10.7";
#ifdef CLIENT_SUPPORT
#ifdef SERVER_SUPPORT

View File

@ -337,8 +337,8 @@ watch_addremove (argc, argv)
send_arg ("-a");
send_arg ("none");
}
send_file_names (argc, argv, SEND_EXPAND_WILD);
send_files (argc, argv, local, 0, SEND_NO_CONTENTS);
send_file_names (argc, argv, SEND_EXPAND_WILD);
send_to_server (the_args.adding ?
"watch-add\012" : "watch-remove\012",
0);
@ -437,29 +437,29 @@ watchers_fileproc (callerdat, finfo)
if (them == NULL)
return 0;
fputs (finfo->fullname, stdout);
cvs_output (finfo->fullname, 0);
p = them;
while (1)
{
putc ('\t', stdout);
cvs_output ("\t", 1);
while (*p != '>' && *p != '\0')
putc (*p++, stdout);
cvs_output (p++, 1);
if (*p == '\0')
{
/* Only happens if attribute is misformed. */
putc ('\n', stdout);
cvs_output ("\n", 1);
break;
}
++p;
putc ('\t', stdout);
cvs_output ("\t", 1);
while (1)
{
while (*p != '+' && *p != ',' && *p != '\0')
putc (*p++, stdout);
cvs_output (p++, 1);
if (*p == '\0')
{
putc ('\n', stdout);
cvs_output ("\n", 1);
goto out;
}
if (*p == ',')
@ -468,9 +468,9 @@ watchers_fileproc (callerdat, finfo)
break;
}
++p;
putc ('\t', stdout);
cvs_output ("\t", 1);
}
putc ('\n', stdout);
cvs_output ("\n", 1);
}
out:;
return 0;
@ -515,8 +515,8 @@ watchers (argc, argv)
if (local)
send_arg ("-l");
send_file_names (argc, argv, SEND_EXPAND_WILD);
send_files (argc, argv, local, 0, SEND_NO_CONTENTS);
send_file_names (argc, argv, SEND_EXPAND_WILD);
send_to_server ("watchers\012", 0);
return get_responses_and_close ();
}

View File

@ -118,6 +118,11 @@ void wrap_setup()
/* Then add entries found in home dir, (if user has one) and file
exists. */
homedir = get_homedir ();
/* If we can't find a home directory, ignore ~/.cvswrappers. This may
make tracking down problems a bit of a pain, but on the other
hand it might be obnoxious to complain when CVS will function
just fine without .cvswrappers (and many users won't even know what
.cvswrappers is). */
if (homedir != NULL)
{
char *file;
@ -348,9 +353,11 @@ wrap_add (line, isTemp)
memset (&e, 0, sizeof(e));
/* Search for the wild card */
while(*line && isspace(*line))
while (*line && isspace ((unsigned char) *line))
++line;
for(temp=line;*line && !isspace(*line);++line)
for (temp = line;
*line && !isspace ((unsigned char) *line);
++line)
;
if(temp==line)
return;
@ -423,8 +430,6 @@ wrap_add (line, isTemp)
error (1, 0, "Correct above errors first");
break;
case 'm':
/* FIXME: look into whether this option is still relevant given
the 24 Jun 96 change to merge_file. */
if(*temp=='C' || *temp=='c')
e.mergeMethod=WRAP_COPY;
else

View File

@ -430,18 +430,14 @@ compress_buffer_shutdown_output (closure)
/* Here is our librarified gzip implementation. It is very minimal
but attempts to be RFC1952 compliant. */
/* Note that currently only the client uses the gzip library. If we
make the server use it too (which should be straightforward), then
filter_stream_through_program, filter_through_gzip, and
filter_through_gunzip can go away. */
/* BUF should contain SIZE bytes of gzipped data (RFC1952/RFC1951).
We are to uncompress the data and write the result to the file
descriptor FD. If something goes wrong, give an error message
mentioning FULLNAME as the name of the file for FD (and make it a
fatal error if we can't recover from it). */
descriptor FD. If something goes wrong, give a nonfatal error message
mentioning FULLNAME as the name of the file for FD. Return 1 if
it is an error we can't recover from. */
void
int
gunzip_and_write (fd, fullname, buf, size)
int fd;
char *fullname;
@ -455,9 +451,15 @@ gunzip_and_write (fd, fullname, buf, size)
unsigned long crc;
if (buf[0] != 31 || buf[1] != 139)
error (1, 0, "gzipped data does not start with gzip identification");
{
error (0, 0, "gzipped data does not start with gzip identification");
return 1;
}
if (buf[2] != 8)
error (1, 0, "only the deflate compression method is supported");
{
error (0, 0, "only the deflate compression method is supported");
return 1;
}
/* Skip over the fixed header, and then skip any of the variable-length
fields. */
@ -496,9 +498,15 @@ gunzip_and_write (fd, fullname, buf, size)
zstr.next_out = outbuf;
zstatus = inflate (&zstr, Z_NO_FLUSH);
if (zstatus != Z_STREAM_END && zstatus != Z_OK)
compress_error (1, zstatus, &zstr, fullname);
{
compress_error (0, zstatus, &zstr, fullname);
return 1;
}
if (write (fd, outbuf, sizeof (outbuf) - zstr.avail_out) < 0)
error (1, errno, "writing decompressed file %s", fullname);
{
error (0, errno, "writing decompressed file %s", fullname);
return 1;
}
crc = crc32 (crc, outbuf, sizeof (outbuf) - zstr.avail_out);
} while (zstatus != Z_STREAM_END);
zstatus = inflateEnd (&zstr);
@ -509,23 +517,31 @@ gunzip_and_write (fd, fullname, buf, size)
+ (buf[zstr.total_in + 11] << 8)
+ (buf[zstr.total_in + 12] << 16)
+ (buf[zstr.total_in + 13] << 24)))
error (1, 0, "CRC error uncompressing %s", fullname);
{
error (0, 0, "CRC error uncompressing %s", fullname);
return 1;
}
if (zstr.total_out != (buf[zstr.total_in + 14]
+ (buf[zstr.total_in + 15] << 8)
+ (buf[zstr.total_in + 16] << 16)
+ (buf[zstr.total_in + 17] << 24)))
error (1, 0, "invalid length uncompressing %s", fullname);
{
error (0, 0, "invalid length uncompressing %s", fullname);
return 1;
}
return 0;
}
/* Read all of FD and put the gzipped data (RFC1952/RFC1951) into *BUF,
replacing previous contents of *BUF. *BUF is malloc'd and *SIZE is
its allocated size. Put the actual number of bytes of data in
*LEN. If something goes wrong, give an error message mentioning
FULLNAME as the name of the file for FD (and make it a fatal error
if we can't recover from it). LEVEL is the compression level (1-9). */
*LEN. If something goes wrong, give a nonfatal error mentioning
FULLNAME as the name of the file for FD, and return 1 if we can't
recover from it). LEVEL is the compression level (1-9). */
void
int
read_and_gzip (fd, fullname, buf, size, len, level)
int fd;
char *fullname;
@ -542,8 +558,16 @@ read_and_gzip (fd, fullname, buf, size, len, level)
if (*size < 1024)
{
unsigned char *newbuf;
*size = 1024;
*buf = (unsigned char *) xrealloc (*buf, *size);
newbuf = realloc (*buf, *size);
if (newbuf == NULL)
{
error (0, 0, "out of memory");
return 1;
}
*buf = newbuf;
}
(*buf)[0] = 31;
(*buf)[1] = 139;
@ -559,7 +583,10 @@ read_and_gzip (fd, fullname, buf, size, len, level)
Z_DEFAULT_STRATEGY);
crc = crc32 (0, NULL, 0);
if (zstatus != Z_OK)
compress_error (1, zstatus, &zstr, fullname);
{
compress_error (0, zstatus, &zstr, fullname);
return 1;
}
zstr.avail_out = *size;
zstr.next_out = *buf + 10;
@ -569,7 +596,10 @@ read_and_gzip (fd, fullname, buf, size, len, level)
nread = read (fd, inbuf, sizeof inbuf);
if (nread < 0)
error (1, errno, "cannot read %s", fullname);
{
error (0, errno, "cannot read %s", fullname);
return 1;
}
else if (nread == 0)
/* End of file. */
finish = 1;
@ -588,9 +618,17 @@ read_and_gzip (fd, fullname, buf, size, len, level)
if (zstr.avail_out < 4096)
{
unsigned char *newbuf;
offset = zstr.next_out - *buf;
*size *= 2;
*buf = xrealloc (*buf, *size);
newbuf = realloc (*buf, *size);
if (newbuf == NULL)
{
error (0, 0, "out of memory");
return 1;
}
*buf = newbuf;
zstr.next_out = *buf + offset;
zstr.avail_out = *size - offset;
}
@ -618,5 +656,7 @@ read_and_gzip (fd, fullname, buf, size, len, level)
zstatus = deflateEnd (&zstr);
if (zstatus != Z_OK)
compress_error (0, zstatus, &zstr, fullname);
return 0;
}
#endif /* defined (SERVER_SUPPORT) || defined (CLIENT_SUPPORT) */

View File

@ -1,3 +1,9 @@
1998-09-09 Jim Kingdon <kingdon@harvey.cyclic.com>
* README: Update now that pcl-cvs is no longer here.
* pcl-cvs: Remove this subdirectory and all its contents.
* Makefile.in: Remove references to pcl-cvs directory.
Sat Feb 21 22:02:12 1998 Ian Lance Taylor <ian@cygnus.com>
* Makefile.in (clean): Change "/bin/rm" to "rm".

View File

@ -54,7 +54,7 @@ clean:
.PHONY: clean
distclean: clean
rm -f Makefile pcl-cvs/Makefile
rm -f Makefile
.PHONY: distclean
realclean: distclean
@ -65,7 +65,6 @@ dist-dir:
for i in ${DISTFILES}; do \
ln $(srcdir)/$${i} ${DISTDIR}; \
done
cd pcl-cvs; ${MAKE} dist-dir DISTDIR="../${DISTDIR}/pcl-cvs"
.PHONY: dist-dir
subdir = tools

View File

@ -1,5 +1,11 @@
This subdirectory contains tools that can be used with CVS.
Note that they will not necessarily be installed when you "make
install" from the top-level of the CVS source tree.
This subdirectory formerly contained tools that can be used with CVS.
In particular, it used to contain a copy of pcl-cvs version 1.x.
Pcl-cvs is an Emacs interface to CVS.
pcl-cvs ............................. an Emacs interface to CVS.
If you are looking for pcl-cvs, we'd suggest pcl-cvs version 2.x, at:
ftp://ftp.weird.com/pub/local/
Both of the following CVS sites have a page about pcl-cvs:
http://www.loria.fr/~molli/cvs-index.html
http://www.cyclic.com/
They also have much information about CVS tools more generally.