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:
commit
0cd931d4ff
@ -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
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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
|
||||
|
243
contrib/cvs/FAQ
243
contrib/cvs/FAQ
@ -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>
|
||||
|
||||
- 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) <blome@de.ibm.com>
|
||||
|
||||
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 <group>/<project> on
|
||||
checkout, create a <project> 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.
|
||||
|
@ -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.
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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).
|
||||
|
@ -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
44
contrib/cvs/configure
vendored
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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:
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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"
|
||||
|
@ -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));
|
||||
|
@ -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"
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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>
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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
|
||||
|
@ -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"
|
||||
|
||||
|
@ -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"
|
||||
|
||||
|
@ -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"
|
||||
|
||||
|
@ -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"
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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
@ -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
|
||||
|
@ -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.
|
||||
|
@ -46,7 +46,6 @@ SOURCES = \
|
||||
stripslash.c \
|
||||
strtoul.c \
|
||||
valloc.c \
|
||||
vasprintf.c \
|
||||
waitpid.c \
|
||||
xgetwd.c \
|
||||
yesno.c
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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]);
|
||||
|
@ -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 */
|
||||
|
@ -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. */
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
|
@ -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
|
||||
|
@ -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
@ -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
|
||||
|
||||
|
@ -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",
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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 ();
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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. */
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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 = ' ';
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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')
|
||||
{
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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]);
|
||||
|
@ -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)
|
||||
{
|
||||
|
||||
/*
|
||||
|
@ -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
@ -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));
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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 */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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 ();
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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) */
|
||||
|
@ -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".
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
Loading…
Reference in New Issue
Block a user