Import cvs-1.10 onto vendor branch. Merge to follow shortly.

Obtained from:	cyclic.com
This commit is contained in:
Peter Wemm 1999-03-18 09:21:42 +00:00
parent 4b06c89291
commit 0008866e58
66 changed files with 5635 additions and 1892 deletions

View File

@ -15,20 +15,6 @@ similar file for the unix-like operating systems (not yet, at least).
This file also might contain some platform-specific bugs.
* One cannot specify some files as binary in a "cvs import" using
CVSROOT/cvswrappers (for why, note that client_process_import_file has
no way of knowing about CVSROOT/cvswrappers which is off on the
server).
* I don't think that "cvs add" honors any of the -k wrappers, at least
not in client/server mode. I would think it should. Getting
CVSROOT/cvswrappers to work would presumably best be done by keeping a
copy of it in the CVS directory on the client, as has also been
discussed for CVS/Template, &c. Getting a client-side .cvswrappers to
work is a separate issue.
* Need more work on the procedure for fixing it if a binary file is
accidentally added in text mode (sanity.sh test cases, better
documentation, probably update and/or admin -kb should update

View File

@ -1,3 +1,86 @@
1998-08-06 Jim Kingdon <kingdon@harvey.cyclic.com>
* INSTALL: Update for SCO OpenServer 5 (reported by Jeffery
Cann).
1998-08-01 Jim Kingdon <kingdon@harvey.cyclic.com>
* INSTALL: Add Unixware 7 (reported by Phillip Porch).
1998-07-29 Jim Kingdon <kingdon@harvey.cyclic.com>
* cvsnt.mak: For rcscmds.c, also include files from the diff
directory. Plus of course the usual voluminous "because Visual
C++ 4.0 feels like it" changes.
Tue Jul 28 22:16:48 1998 Noel Cragg <noel@swish.red-bean.com>
* Makefile.in (dist): unset the GZIP shell variable before calling
gzip to avoid invocation problems.
Sun Jul 26 16:22:21 1998 Noel Cragg <noel@swish.red-bean.com>
* NEWS: add info about TopLevelAdmin.
1998-07-20 Jim Kingdon <kingdon@harvey.cyclic.com>
* INSTALL: Update entries for HPUX and AIX (based on a submission
from Andreas Ley).
1998-06-25 Jim Kingdon <kingdon@harvey.cyclic.com>
* README.VMS: We generally don't need GNU patch any more.
1998-06-03 Jim Kingdon <kingdon@harvey.cyclic.com>
* TESTS: Don't mention the version of Solaris; Mark Borges says
that it applies to Solaris 2.5 as well as 2.6.
1998-06-02 Assar Westerlund <assar@sics.se>
* configure.in: Test for GSS_C_NT_HOSTBASED_SERVICE in gssapi.h.
* acconfig.h: Add undef for HAVE_GSS_C_NT_HOSTBASED_SERVICE.
* configure, config.h.in: Rebuild.
1998-06-01 Assar Westerlund <assar@sics.se>
and Ian Lance Taylor <ian@cygnus.com>
* configure.in: Check for GSSAPI headers individually. Use a
different set of GSSPI libraries if gssapi.h rather than
gssapi/gssapi.h is found. Adds Heimdal support.
* configure, config.h.in: Rebuild.
1998-05-25 Jim Kingdon <kingdon@harvey.cyclic.com>
* cvs.spec (%description): Rewrite to be slightly more verbose
about the basic features. Don't try to mention what CVS lacks.
1998-05-23 Jim Kingdon <kingdon@harvey.cyclic.com>
* BUGS: Remove items about binary file bugs which were fixed
approximately 6 months ago.
1998-04-28 Jim Kingdon <kingdon@harvey.cyclic.com>
* TESTS: Add note about Solaris sort program (reported by Mark
D. Baushke).
1998-03-16 Larry Jones <larry.jones@sdrc.com>
* configure.in: Simplify test for shadow password support since
the code now handles the case where shadow passwords are supported
but are not in use.
* configure: Regenerated.
1998-03-07 Jim Kingdon <kingdon@harvey.cyclic.com>
* TESTS: Remove note about SGI's XFS. Someone reports that it
works (I would assume due to the 13 Feb 1998, and earlier, changes
to sanity.sh).
* NEWS: Add item about PreservePermissions. Fix unclear wording
in gserver item.
1998-03-04 Jim Kingdon <kingdon@harvey.cyclic.com>
* acconfig.h, configure.in: Add PRESERVE_PERMISSIONS_SUPPORT and

View File

@ -118,14 +118,15 @@ HPPA:
HPPA running HP-UX 9 (1.8)
HPPA 1.1 running HP-UX A.09.03 (1.5.95) (footnote 8)
HPPA 1.1 running HP-UX A.09.04 (1.7.1)
HPPA 9000/735 running HP-UX A.09.05 (1.8.87)
HPPA running HP-UX 9.05 (1.9)
HPPA running HP-UX 10.01 (1.7)
HPPA running HP-UX 10.20 using gcc 2.7.2.2 (1.9.14)
HPPA running HP-UX 10.20 (1.9, 1.9.14)
NextSTEP 3.3 (1.7)
i386 family:
Solaris 2.4 using gcc (about 1.4A2)
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)
@ -133,7 +134,7 @@ i386 family:
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.8.86)
SCO OpenServer 5 (1.9.29)
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)
@ -164,7 +165,7 @@ MIPS:
PowerPC or RS/6000:
IBM RS/6000 running AIX 3.1 using gcc and cc (1.6.86)
IBM RS/6000 running AIX 3.2.5 (1.8)
IBM RS/6000 running AIX 4.1 using gcc and cc (about 1.4A2) (footnote 1)
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)
SPARC:
@ -179,11 +180,6 @@ VAX:
VAX running VMS 6.2 (1.9+patches, client-only)
(see README.VMS for information on necessary hacks).
(footnote 1)
AIX 4.1 systems fail to run "configure" due to bugs in their
"/bin/sh" implementation. You might want to try feeding the
configure script to "bash" ported to AIX 4.1. (about 1.4A2).
(footnote 2)
Some Irix 4.0 systems may core dump in malloc while running
CVS. We believe this is a bug in the Irix malloc. You can

View File

@ -222,7 +222,7 @@ dist: spec
${MAKE} dist-dir DISTDIR="$${DISTDIR}" \
); \
done
tar chf${TAR_VERBOSE} - `cat .fname` | ${GZIP} > "`cat .fname`.tar${GZIP_EXT}"
(unset GZIP; tar chf${TAR_VERBOSE} - `cat .fname` | ${GZIP} > "`cat .fname`.tar${GZIP_EXT}")
rm -rf `cat .fname` .fname .version
.PHONY: dist-dir

View File

@ -1,8 +1,19 @@
Changes since 1.9:
* There is a new feature, enabled by TopLevelAdmin in CVSROOT/config,
which tells CVS to modify the behavior of the "checkout" command. The
command now creates a CVS directory at the top level of the new
working directory, in addition to CVS directories created within
checked-out directories. See the Cederqvist for details.
* There is an optional set of features, enabled by PreservePermissions
in CVSROOT/config, which allow CVS to store unix-specific file
information such as permissions, file ownership, and links. See the
Cederqvist for details.
* One can now authenticate and encrypt using the GSSAPI network
security interface. For details see the description of :gserver: in
CVSROOT, and the -a global option.
security interface. For details see the Cederqvist's description of
specifying :gserver: in CVSROOT, and the -a global option.
* All access to RCS files is now implemented internally rather than by
calling RCS programs. The main user-visible consequence of this is
@ -50,10 +61,6 @@ cvs.texinfo for details, including a discussion of security issues.
Note that the requirement that read-only users be able to create locks
and write the history file still applies.
* The "checkout" command now creates a CVS directory at the top level
of the new working directory, in addition to CVS directories created
within checked-out directories.
* There is a new administrative file verifymsg which is like editinfo
but merely validates the message, rather than also getting it from the
user. It therefore works with client/server CVS or if one uses the -m

View File

@ -14,13 +14,14 @@ disks are slow or over-loaded.
The tests work in /tmp/cvs-sanity (which the tests create) by default.
If for some reason you want them to work in a different directory, you
can set the TESTDIR environment variable to the desired location
before running them. In particular, using SGI's Irix 6, the tests
will fail if TESTDIR is an XFS filesystem (which /tmp often is);
you'll want to set TESTDIR to a non-XFS filesystem.
before running them.
You will probably need GNU expr, which is part of the GNU sh-utils
package (this is just for running the tests; CVS itself doesn't use
expr).
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.
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

View File

@ -4,6 +4,10 @@
/* Define if you have GSSAPI with MIT Kerberos version 5 available. */
#undef HAVE_GSSAPI
/* Define if GSS_C_NT_HOSTBASED_SERVICE is defined in the gssapi.h
header file. Only relevant when using GSSAPI. */
#undef HAVE_GSS_C_NT_HOSTBASED_SERVICE
/* Define if you want CVS to be able to be a remote repository client. */
#undef CLIENT_SUPPORT

View File

@ -74,6 +74,10 @@
/* Define if you have GSSAPI with MIT Kerberos version 5 available. */
#undef HAVE_GSSAPI
/* Define if GSS_C_NT_HOSTBASED_SERVICE is defined in the gssapi.h
header file. Only relevant when using GSSAPI. */
#undef HAVE_GSS_C_NT_HOSTBASED_SERVICE
/* Define if you want CVS to be able to be a remote repository client. */
#undef CLIENT_SUPPORT
@ -191,6 +195,15 @@
/* Define if you have the <fcntl.h> header file. */
#undef HAVE_FCNTL_H
/* Define if you have the <gssapi.h> header file. */
#undef HAVE_GSSAPI_H
/* Define if you have the <gssapi/gssapi.h> header file. */
#undef HAVE_GSSAPI_GSSAPI_H
/* Define if you have the <gssapi/gssapi_generic.h> header file. */
#undef HAVE_GSSAPI_GSSAPI_GENERIC_H
/* Define if you have the <io.h> header file. */
#undef HAVE_IO_H

189
contrib/cvs/configure vendored
View File

@ -2126,11 +2126,7 @@ EOF
fi
echo $ac_n "checking for evidence of shadow passwords""... $ac_c" 1>&6
if test -f /etc/shadow \
|| test -f /etc/security/passwd.adjunct ; then
found="yes"
echo $ac_n "checking for -lsec""... $ac_c" 1>&6
echo $ac_n "checking for -lsec""... $ac_c" 1>&6
ac_lib_var=`echo sec'_'getspnam | tr './+\055' '__p_'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
@ -2138,7 +2134,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-lsec $LIBS"
cat > conftest.$ac_ext <<EOF
#line 2142 "configure"
#line 2138 "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
@ -2150,7 +2146,7 @@ int t() {
getspnam()
; return 0; }
EOF
if { (eval echo configure:2154: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
if { (eval echo configure:2150: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
@ -2174,14 +2170,14 @@ else
echo "$ac_t""no" 1>&6
fi
for ac_func in getspnam
for ac_func in getspnam
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
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 2185 "configure"
#line 2181 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@ -2205,7 +2201,7 @@ $ac_func();
; return 0; }
EOF
if { (eval echo configure:2209: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
if { (eval echo configure:2205: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
rm -rf conftest*
eval "ac_cv_func_$ac_func=yes"
else
@ -2227,10 +2223,6 @@ else
fi
done
else
found="no"
fi
echo "$ac_t""$found" 1>&6
echo $ac_n "checking whether utime accepts a null argument""... $ac_c" 1>&6
if eval "test \"`echo '$''{'ac_cv_func_utime_null'+set}'`\" = set"; then
@ -2242,7 +2234,7 @@ if test "$cross_compiling" = yes; then
ac_cv_func_utime_null=no
else
cat > conftest.$ac_ext <<EOF
#line 2246 "configure"
#line 2238 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <sys/stat.h>
@ -2253,7 +2245,7 @@ exit(!(stat ("conftestdata", &s) == 0 && utime("conftestdata", (long *)0) == 0
&& t.st_mtime - s.st_mtime < 120));
}
EOF
{ (eval echo configure:2257: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }
{ (eval echo configure:2249: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }
if test -s conftest && (./conftest; exit) 2>/dev/null; then
ac_cv_func_utime_null=yes
else
@ -2317,7 +2309,7 @@ else
ccvs_cv_sys_working_fnmatch=no
else
cat > conftest.$ac_ext <<EOF
#line 2321 "configure"
#line 2313 "configure"
#include "confdefs.h"
#include <fnmatch.h>
@ -2329,7 +2321,7 @@ main ()
? 0 : 1);
}
EOF
{ (eval echo configure:2333: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }
{ (eval echo configure:2325: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }
if test -s conftest && (./conftest; exit) 2>/dev/null; then
ccvs_cv_sys_working_fnmatch=yes
else
@ -2354,7 +2346,7 @@ if eval "test \"`echo '$''{'ac_cv_func_connect'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
#line 2358 "configure"
#line 2350 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char connect(); below. */
@ -2378,7 +2370,7 @@ connect();
; return 0; }
EOF
if { (eval echo configure:2382: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
if { (eval echo configure:2374: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
rm -rf conftest*
eval "ac_cv_func_connect=yes"
else
@ -2403,7 +2395,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-lnsl_s $LIBS"
cat > conftest.$ac_ext <<EOF
#line 2407 "configure"
#line 2399 "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
@ -2415,7 +2407,7 @@ int t() {
printf()
; return 0; }
EOF
if { (eval echo configure:2419: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
if { (eval echo configure:2411: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
@ -2450,7 +2442,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-lnsl $LIBS"
cat > conftest.$ac_ext <<EOF
#line 2454 "configure"
#line 2446 "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
@ -2462,7 +2454,7 @@ int t() {
printf()
; return 0; }
EOF
if { (eval echo configure:2466: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
if { (eval echo configure:2458: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
@ -2497,7 +2489,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-lsocket $LIBS"
cat > conftest.$ac_ext <<EOF
#line 2501 "configure"
#line 2493 "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
@ -2509,7 +2501,7 @@ int t() {
connect()
; return 0; }
EOF
if { (eval echo configure:2513: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
if { (eval echo configure:2505: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
@ -2544,7 +2536,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-linet $LIBS"
cat > conftest.$ac_ext <<EOF
#line 2548 "configure"
#line 2540 "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
@ -2556,7 +2548,7 @@ int t() {
connect()
; return 0; }
EOF
if { (eval echo configure:2560: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
if { (eval echo configure:2552: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
@ -2607,7 +2599,7 @@ if test "$cross_compiling" != yes && test -r $KRB4/include/krb.h; then
hold_cflags=$CFLAGS
CFLAGS="$CFLAGS -I$KRB4/include"
cat > conftest.$ac_ext <<EOF
#line 2611 "configure"
#line 2603 "configure"
#include "confdefs.h"
#include <krb.h>
int main() { return 0; }
@ -2615,14 +2607,14 @@ int t() {
int i;
; return 0; }
EOF
if { (eval echo configure:2619: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
if { (eval echo configure:2611: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
rm -rf conftest*
krb_h=yes krb_incdir=$KRB4/include
else
rm -rf conftest*
CFLAGS=$hold_cflags
cat > conftest.$ac_ext <<EOF
#line 2626 "configure"
#line 2618 "configure"
#include "confdefs.h"
#include <krb.h>
int main() { return 0; }
@ -2630,7 +2622,7 @@ int t() {
int i;
; return 0; }
EOF
if { (eval echo configure:2634: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
if { (eval echo configure:2626: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
rm -rf conftest*
krb_h=yes krb_incdir=
fi
@ -2642,7 +2634,7 @@ rm -f conftest*
CFLAGS=$hold_cflags
else
cat > conftest.$ac_ext <<EOF
#line 2646 "configure"
#line 2638 "configure"
#include "confdefs.h"
#include <krb.h>
int main() { return 0; }
@ -2650,7 +2642,7 @@ int t() {
int i;
; return 0; }
EOF
if { (eval echo configure:2654: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
if { (eval echo configure:2646: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
rm -rf conftest*
krb_h=yes krb_incdir=
fi
@ -2659,7 +2651,7 @@ rm -f conftest*
fi
if test -z "$krb_h"; then
cat > conftest.$ac_ext <<EOF
#line 2663 "configure"
#line 2655 "configure"
#include "confdefs.h"
#include <krb.h>
int main() { return 0; }
@ -2667,7 +2659,7 @@ int t() {
int i;
; return 0; }
EOF
if { (eval echo configure:2671: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
if { (eval echo configure:2663: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
rm -rf conftest*
krb_h=yes krb_incdir=
else
@ -2676,7 +2668,7 @@ else
hold_cflags=$CFLAGS
CFLAGS="$CFLAGS -I$KRB4/include/kerberosIV"
cat > conftest.$ac_ext <<EOF
#line 2680 "configure"
#line 2672 "configure"
#include "confdefs.h"
#include <krb.h>
int main() { return 0; }
@ -2684,7 +2676,7 @@ int t() {
int i;
; return 0; }
EOF
if { (eval echo configure:2688: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
if { (eval echo configure:2680: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
rm -rf conftest*
krb_h=yes krb_incdir=$KRB4/include/kerberosIV
fi
@ -2713,7 +2705,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-lkrb $LIBS"
cat > conftest.$ac_ext <<EOF
#line 2717 "configure"
#line 2709 "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
@ -2725,7 +2717,7 @@ int t() {
printf()
; return 0; }
EOF
if { (eval echo configure:2729: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
if { (eval echo configure:2721: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
@ -2752,7 +2744,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-lkrb $LIBS"
cat > conftest.$ac_ext <<EOF
#line 2756 "configure"
#line 2748 "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
@ -2764,7 +2756,7 @@ int t() {
open()
; return 0; }
EOF
if { (eval echo configure:2768: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
if { (eval echo configure:2760: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
@ -2794,7 +2786,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-lkrb $LIBS"
cat > conftest.$ac_ext <<EOF
#line 2798 "configure"
#line 2790 "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
@ -2806,7 +2798,7 @@ int t() {
printf()
; return 0; }
EOF
if { (eval echo configure:2810: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
if { (eval echo configure:2802: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
@ -2845,7 +2837,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-ldes $LIBS"
cat > conftest.$ac_ext <<EOF
#line 2849 "configure"
#line 2841 "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
@ -2857,7 +2849,7 @@ int t() {
printf()
; return 0; }
EOF
if { (eval echo configure:2861: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
if { (eval echo configure:2853: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
@ -2888,7 +2880,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 2892 "configure"
#line 2884 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@ -2912,7 +2904,7 @@ $ac_func();
; return 0; }
EOF
if { (eval echo configure:2916: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
if { (eval echo configure:2908: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
rm -rf conftest*
eval "ac_cv_func_$ac_func=yes"
else
@ -2945,21 +2937,22 @@ fi
echo "default place for GSSAPI is $GSSAPI"
echo $ac_n "checking for gssapi.h""... $ac_c" 1>&6
hold_cppflags=$CPPFLAGS
CPPFLAGS="$CPPFLAGS -I$GSSAPI/include "
ac_safe=`echo "gssapi/gssapi.h" | tr './\055' '___'`
echo $ac_n "checking for gssapi/gssapi.h""... $ac_c" 1>&6
for ac_hdr in 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
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
#line 2958 "configure"
#line 2951 "configure"
#include "confdefs.h"
#include <gssapi/gssapi.h>
#include <$ac_hdr>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
{ (eval echo configure:2963: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
{ (eval echo configure:2956: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out`
if test -z "$ac_err"; then
rm -rf conftest*
@ -2973,15 +2966,69 @@ rm -f conftest*
fi
if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
echo "$ac_t""yes" 1>&6
ac_tr_hdr=HAVE_`echo $ac_hdr | tr 'abcdefghijklmnopqrstuvwxyz./\055' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ___'`
cat >> confdefs.h <<EOF
#define $ac_tr_hdr 1
EOF
else
echo "$ac_t""no" 1>&6
fi
done
CPPFLAGS=$hold_cppflags
if 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
LIBS="$LIBS -L$GSSAPI/lib -lgssapi_krb5 -lkrb5 -lcrypto -lcom_err"
includeopt="${includeopt} -I$GSSAPI/include"
# This is necessary on Irix 5.3, in order to link against libkrb5 --
# there, an_to_ln.o refers to things defined only in -lgen.
echo $ac_n "checking for -lgen""... $ac_c" 1>&6
includeopt="${includeopt} -I$GSSAPI/include"
# FIXME: This is ugly, but these things don't seem to be standardized.
if test "$ac_cv_header_gssapi_h" = "yes"; then
LIBS="$LIBS -L$GSSAPI/lib -lgssapi -lkrb5 -lasn1 -ldes -lroken"
else
LIBS="$LIBS -L$GSSAPI/lib -lgssapi_krb5 -lkrb5 -lcrypto -lcom_err"
fi
save_CPPFLAGS=$CPPFLAGS
CPPFLAGS="-I$GSSAPI/include $CPPFLAGS"
if test "$ac_cv_header_gssapi_h" = "yes"; then
cat > conftest.$ac_ext <<EOF
#line 2998 "configure"
#include "confdefs.h"
#include <gssapi.h>
EOF
if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
egrep "GSS_C_NT_HOSTBASED_SERVICE" >/dev/null 2>&1; then
rm -rf conftest*
cat >> confdefs.h <<\EOF
#define HAVE_GSS_C_NT_HOSTBASED_SERVICE 1
EOF
fi
rm -f conftest*
else
cat > conftest.$ac_ext <<EOF
#line 3014 "configure"
#include "confdefs.h"
#include <gssapi/gssapi.h>
EOF
if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
egrep "GSS_C_NT_HOSTBASED_SERVICE" >/dev/null 2>&1; then
rm -rf conftest*
cat >> confdefs.h <<\EOF
#define HAVE_GSS_C_NT_HOSTBASED_SERVICE 1
EOF
fi
rm -f conftest*
fi
CPPFLAGS=$save_CPPFLAGS
# This is necessary on Irix 5.3, in order to link against libkrb5 --
# there, an_to_ln.o refers to things defined only in -lgen.
echo $ac_n "checking for -lgen""... $ac_c" 1>&6
ac_lib_var=`echo gen'_'compile | tr './+\055' '__p_'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
@ -2989,7 +3036,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-lgen $LIBS"
cat > conftest.$ac_ext <<EOF
#line 2993 "configure"
#line 3040 "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
@ -3001,7 +3048,7 @@ int t() {
compile()
; return 0; }
EOF
if { (eval echo configure:3005: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
if { (eval echo configure:3052: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
@ -3025,12 +3072,8 @@ else
echo "$ac_t""no" 1>&6
fi
else
echo "$ac_t""no" 1>&6
fi
CPPFLAGS=$hold_cppflags
# Check whether --enable-encryption or --disable-encryption was given.
if test "${enable_encryption+set}" = set; then
enableval="$enable_encryption"
@ -3055,7 +3098,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 3059 "configure"
#line 3102 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char gethostname(); below. */
@ -3079,7 +3122,7 @@ gethostname();
; return 0; }
EOF
if { (eval echo configure:3083: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
if { (eval echo configure:3126: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
rm -rf conftest*
eval "ac_cv_func_gethostname=yes"
else
@ -3156,7 +3199,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-lcrypt $LIBS"
cat > conftest.$ac_ext <<EOF
#line 3160 "configure"
#line 3203 "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
@ -3168,7 +3211,7 @@ int t() {
crypt()
; return 0; }
EOF
if { (eval echo configure:3172: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
if { (eval echo configure:3215: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
@ -3199,7 +3242,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 3203 "configure"
#line 3246 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@ -3223,7 +3266,7 @@ $ac_func();
; return 0; }
EOF
if { (eval echo configure:3227: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
if { (eval echo configure:3270: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
rm -rf conftest*
eval "ac_cv_func_$ac_func=yes"
else
@ -3264,7 +3307,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 3268 "configure"
#line 3311 "configure"
#include "confdefs.h"
int main() { return 0; }
@ -3272,7 +3315,7 @@ int t() {
return __CYGWIN32__;
; return 0; }
EOF
if { (eval echo configure:3276: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
if { (eval echo configure:3319: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ccvs_cv_sys_cygwin32=yes
else

View File

@ -91,24 +91,13 @@ AC_FUNC_VFORK
AC_FUNC_CLOSEDIR_VOID
dnl
dnl Look for shadow password files before we go ahead and set getspnam.
dnl On some systems (Linux), the C library has getspnam but shadow
dnl passwords might not be in use.
dnl Check for shadow password support.
dnl
dnl We used to check for the existence of the /etc/security directory
dnl here, but that's incorrect, since it's possible to have PAM installed
dnl without using shadow passwords.
dnl
AC_MSG_CHECKING([for evidence of shadow passwords])
if test -f /etc/shadow \
|| test -f /etc/security/passwd.adjunct ; then
found="yes"
AC_CHECK_LIB(sec, getspnam)
AC_CHECK_FUNCS(getspnam)
else
found="no"
fi
AC_MSG_RESULT([$found])
dnl We used to try to determine whether shadow passwords were actually in
dnl use or not, but the code has been changed to work right reguardless,
dnl so we can go back to a simple check.
AC_CHECK_LIB(sec, getspnam)
AC_CHECK_FUNCS(getspnam)
dnl We always use CVS's regular expression matcher.
dnl This is because:
@ -271,18 +260,33 @@ echo "default place for GSSAPI is $GSSAPI"
AC_SUBST(GSSAPI)])dnl
WITH_GSSAPI
AC_MSG_CHECKING([for gssapi.h])
hold_cppflags=$CPPFLAGS
CPPFLAGS="$CPPFLAGS -I$GSSAPI/include "
AC_CHECK_HEADER(gssapi/gssapi.h,
[AC_DEFINE(HAVE_GSSAPI)
LIBS="$LIBS -L$GSSAPI/lib -lgssapi_krb5 -lkrb5 -lcrypto -lcom_err"
includeopt="${includeopt} -I$GSSAPI/include"
# This is necessary on Irix 5.3, in order to link against libkrb5 --
# there, an_to_ln.o refers to things defined only in -lgen.
AC_CHECK_LIB(gen, compile)])
AC_CHECK_HEADERS(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
AC_DEFINE(HAVE_GSSAPI)
includeopt="${includeopt} -I$GSSAPI/include"
# FIXME: This is ugly, but these things don't seem to be standardized.
if test "$ac_cv_header_gssapi_h" = "yes"; then
LIBS="$LIBS -L$GSSAPI/lib -lgssapi -lkrb5 -lasn1 -ldes -lroken"
else
LIBS="$LIBS -L$GSSAPI/lib -lgssapi_krb5 -lkrb5 -lcrypto -lcom_err"
fi
save_CPPFLAGS=$CPPFLAGS
CPPFLAGS="-I$GSSAPI/include $CPPFLAGS"
if test "$ac_cv_header_gssapi_h" = "yes"; then
AC_EGREP_HEADER(GSS_C_NT_HOSTBASED_SERVICE, gssapi.h, AC_DEFINE(HAVE_GSS_C_NT_HOSTBASED_SERVICE))
else
AC_EGREP_HEADER(GSS_C_NT_HOSTBASED_SERVICE, gssapi/gssapi.h, AC_DEFINE(HAVE_GSS_C_NT_HOSTBASED_SERVICE))
fi
CPPFLAGS=$save_CPPFLAGS
# This is necessary on Irix 5.3, in order to link against libkrb5 --
# there, an_to_ln.o refers to things defined only in -lgen.
AC_CHECK_LIB(gen, compile)
fi
dnl
dnl Use --with-encryption to turn on encryption support
dnl

View File

@ -1,3 +1,7 @@
1998-05-11 W. Bradley Rubenstein
* log.pl: Check for errors from open and exec.
Sat Feb 21 21:59:45 1998 Ian Lance Taylor <ian@cygnus.com>
* Makefile.in (clean): Change "/bin/rm" to "rm".

View File

@ -145,7 +145,16 @@ if ($dostatus != 0) {
}
last;
}
open(RCS, "-|") || exec 'cvs', '-nQq', 'status', '-v', $file;
$pid = open(RCS, "-|");
if ( !defined $pid )
{
die "fork failed: $!";
}
if ($pid == 0)
{
exec 'cvs', '-nQq', 'status', '-v', $file;
die "cvs exec failed: $!";
}
while (<RCS>) {
print OUT;
if (MAIL) {

View File

@ -1,3 +1,56 @@
1998-08-06 David Masterson of kla-tencor.com
* util.c (flush_output): Don't prototype.
Thu Jul 2 16:34:38 1998 Ian Lance Taylor <ian@cygnus.com>
Simplify the callback interface:
* diffrun.h: Don't include <stdarg.h> or <varargs.h>.
(struct diff_callbacks): Remove printf_output field.
* util.c: Include <stdarg.h> or <varargs.h>.
(printf_output): Use vasprintf and write_output callback rather
than printf_output callback.
* diff3.c (read_diff): Don't set my_callbacks.printf_output.
Thu Jun 18 12:43:53 1998 Ian Lance Taylor <ian@cygnus.com>
* diffrun.h: New file.
* diff.h: Include diffrun.h.
(callbacks): New EXTERN variable.
(write_output, printf_output, flush_output): Declare.
* diff.c (diff_run): Add parameter callbacks_arg. Use callback
functions rather than writing to stdout. Don't open a file if
there is a write_output callback. Call perror_with_name rather
than perror.
(usage): Use callbacks if defined rather than writing to stdout.
(compare_files): Call flush_output rather than fflush (outfile).
* diff3.c: Include diffrun.h. Change several functions to use
output functions from util.c rather than direct printing. Use
diff_error and friends rather than printing to stderr. Set global
variable outfile.
(outfile, callbacks): Declare.
(write_output, printf_output, flush_output): Declare.
(diff3_run): Add parameter callbacks_arg. Use callback functions
rather than writing to stdout.
(usage): Use callbacks if defined rather than writing to stdout.
(read_diff): Preserve callbacks and outfile around call to
diff_run.
* util.c (perror_with_name): Use error callback if defined.
(pfatal_with_name, diff_error): Likewise.
(message5): Use printf_output and write_output.
(print_message_queue, print_1_line, output_1_line): Likewise.
(begin_output): Reject paginate_flag if there are output
callbacks.
(write_output, printf_output, flush_output): New functions.
* context.c: Change all output to outfile to use printf_output and
write_output.
* ed.c: Likewise.
* ifdef.c: Likewise.
* normal.c: Likewise.
* side.c: Likewise.
* Makefile.in (SOURCES): Add diffrun.h.
($(OBJECTS)): Depend upon diffrun.h.
Fri Jan 16 14:58:19 1998 Larry Jones <larry.jones@sdrc.com>
* diff.c, diff3.c: Plug memory leaks.

View File

@ -1,5 +1,5 @@
# Makefile for GNU DIFF
# Copyright (C) 1988,1989,1991,1992,1993,1994,1997 Free Software Foundation, Inc.
# Copyright (C) 1988,1989,1991,1992,1993,1994,1997,1998 Free Software Foundation, Inc.
#
# This file is part of GNU DIFF.
#
@ -43,7 +43,8 @@ SHELL = /bin/sh
# The source files for all of the programs.
SOURCES = diff.c diff3.c analyze.c cmpbuf.c cmpbuf.h io.c context.c ed.c \
normal.c ifdef.c util.c dir.c version.c diff.h side.c system.h
normal.c ifdef.c util.c dir.c version.c diff.h side.c system.h \
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
@ -66,7 +67,7 @@ libdiff libdiff.a: $(OBJECTS)
$(AR) cr libdiff.a $(OBJECTS)
-$(RANLIB) libdiff.a
$(OBJECTS): diff.h system.h
$(OBJECTS): diff.h diffrun.h system.h
analyze.o cmpbuf.o: cmpbuf.h
util.o: util.c

View File

@ -1,5 +1,5 @@
/* Context-format output routines for GNU DIFF.
Copyright (C) 1988,1989,1991,1992,1993,1994 Free Software Foundation, Inc.
Copyright (C) 1988,1989,1991,1992,1993,1994,1998 Free Software Foundation, Inc.
This file is part of GNU DIFF.
@ -43,14 +43,14 @@ print_context_label (mark, inf, label)
char const *label;
{
if (label)
fprintf (outfile, "%s %s\n", mark, label);
printf_output ("%s %s\n", mark, label);
else
{
char const *ct = ctime (&inf->stat.st_mtime);
if (!ct)
ct = "?\n";
/* See Posix.2 section 4.17.6.1.4 for this format. */
fprintf (outfile, "%s %s\t%s", mark, inf->name, ct);
printf_output ("%s %s\t%s", mark, inf->name, ct);
}
}
@ -116,9 +116,9 @@ print_context_number_range (file, a, b)
In this case, we should print the line number before the range,
which is B. */
if (trans_b > trans_a)
fprintf (outfile, "%d,%d", trans_a, trans_b);
printf_output ("%d,%d", trans_a, trans_b);
else
fprintf (outfile, "%d", trans_b);
printf_output ("%d", trans_b);
}
/* Print a portion of an edit script in context format.
@ -137,7 +137,6 @@ pr_context_hunk (hunk)
char const *prefix;
char const *function;
size_t function_length;
FILE *out;
/* Determine range of line numbers involved in each file. */
@ -160,21 +159,20 @@ pr_context_hunk (hunk)
find_function (&files[0], first0, &function, &function_length);
begin_output ();
out = outfile;
/* If we looked for and found a function this is part of,
include its name in the header of the diff section. */
fprintf (out, "***************");
printf_output ("***************");
if (function)
{
fprintf (out, " ");
fwrite (function, 1, min (function_length - 1, 40), out);
printf_output (" ");
write_output (function, min (function_length - 1, 40));
}
fprintf (out, "\n*** ");
printf_output ("\n*** ");
print_context_number_range (&files[0], first0, last0);
fprintf (out, " ****\n");
printf_output (" ****\n");
if (show_from)
{
@ -201,9 +199,9 @@ pr_context_hunk (hunk)
}
}
fprintf (out, "--- ");
printf_output ("--- ");
print_context_number_range (&files[1], first1, last1);
fprintf (out, " ----\n");
printf_output (" ----\n");
if (show_to)
{
@ -250,9 +248,9 @@ print_unidiff_number_range (file, a, b)
In this case, we should print the line number before the range,
which is B. */
if (trans_b <= trans_a)
fprintf (outfile, trans_b == trans_a ? "%d" : "%d,0", trans_b);
printf_output (trans_b == trans_a ? "%d" : "%d,0", trans_b);
else
fprintf (outfile, "%d,%d", trans_a, trans_b - trans_a + 1);
printf_output ("%d,%d", trans_a, trans_b - trans_a + 1);
}
/* Print a portion of an edit script in unidiff format.
@ -270,7 +268,6 @@ pr_unidiff_hunk (hunk)
struct change *next;
char const *function;
size_t function_length;
FILE *out;
/* Determine range of line numbers involved in each file. */
@ -293,23 +290,22 @@ pr_unidiff_hunk (hunk)
find_function (&files[0], first0, &function, &function_length);
begin_output ();
out = outfile;
fprintf (out, "@@ -");
printf_output ("@@ -");
print_unidiff_number_range (&files[0], first0, last0);
fprintf (out, " +");
printf_output (" +");
print_unidiff_number_range (&files[1], first1, last1);
fprintf (out, " @@");
printf_output (" @@");
/* If we looked for and found a function this is part of,
include its name in the header of the diff section. */
if (function)
{
putc (' ', out);
fwrite (function, 1, min (function_length - 1, 40), out);
write_output (" ", 1);
write_output (function, min (function_length - 1, 40));
}
putc ('\n', out);
write_output ("\n", 1);
next = hunk;
i = first0;
@ -322,7 +318,7 @@ pr_unidiff_hunk (hunk)
if (!next || i < next->line0)
{
putc (tab_align_flag ? '\t' : ' ', out);
write_output (tab_align_flag ? "\t" : " ", 1);
print_1_line (0, &files[0].linbuf[i++]);
j++;
}
@ -333,9 +329,9 @@ pr_unidiff_hunk (hunk)
k = next->deleted;
while (k--)
{
putc ('-', out);
write_output ("-", 1);
if (tab_align_flag)
putc ('\t', out);
write_output ("\t", 1);
print_1_line (0, &files[0].linbuf[i++]);
}
@ -344,9 +340,9 @@ pr_unidiff_hunk (hunk)
k = next->inserted;
while (k--)
{
putc ('+', out);
write_output ("+", 1);
if (tab_align_flag)
putc ('\t', out);
write_output ("\t", 1);
print_1_line (0, &files[1].linbuf[j++]);
}

View File

@ -1,5 +1,5 @@
/* GNU DIFF entry routine.
Copyright (C) 1988, 1989, 1992, 1993, 1994, 1997 Free Software Foundation, Inc.
Copyright (C) 1988, 1989, 1992, 1993, 1994, 1997, 1998 Free Software Foundation, Inc.
This file is part of GNU DIFF.
@ -231,10 +231,11 @@ static struct option const longopts[] =
};
int
diff_run (argc, argv, out)
diff_run (argc, argv, out, callbacks_arg)
int argc;
char *argv[];
char *out;
const struct diff_callbacks *callbacks_arg;
{
int val;
int c;
@ -242,6 +243,9 @@ diff_run (argc, argv, out)
int width = DEFAULT_WIDTH;
int show_c_function = 0;
int optind_old;
int opened_file = 0;
callbacks = callbacks_arg;
/* Do our initializations. */
initialize_main (&argc, &argv);
@ -476,7 +480,14 @@ diff_run (argc, argv, out)
break;
case 'v':
printf ("diff - GNU diffutils version %s\n", diff_version_string);
if (callbacks && callbacks->write_stdout)
{
(*callbacks->write_stdout) ("diff - GNU diffutils version ");
(*callbacks->write_stdout) (diff_version_string);
(*callbacks->write_stdout) ("\n");
}
else
printf ("diff - GNU diffutils version %s\n", diff_version_string);
return 0;
case 'w':
@ -555,7 +566,8 @@ diff_run (argc, argv, out)
case 141:
usage ();
check_output (stdout);
if (! callbacks || ! callbacks->write_stdout)
check_output (stdout);
return 0;
case 142:
@ -645,23 +657,35 @@ diff_run (argc, argv, out)
switch_string = option_list (argv + 1, optind - 1);
if (out == NULL)
outfile = stdout;
if (callbacks && callbacks->write_output)
{
if (out != NULL)
{
diff_error ("write callback with output file", 0, 0);
return 2;
}
}
else
{
#if HAVE_SETMODE
/* A diff which is full of ^Z and such isn't going to work
very well in text mode. */
if (binary_I_O)
outfile = fopen (out, "wb");
if (out == NULL)
outfile = stdout;
else
{
#if HAVE_SETMODE
/* A diff which is full of ^Z and such isn't going to work
very well in text mode. */
if (binary_I_O)
outfile = fopen (out, "wb");
else
#endif
outfile = fopen (out, "w");
if (outfile == NULL)
{
perror_with_name ("could not open output file");
return 2;
}
outfile = fopen (out, "w");
if (outfile == NULL)
{
perror_with_name ("could not open output file");
return 2;
}
opened_file = 1;
}
}
/* Set the jump buffer, so that diff may abort execution without
@ -669,7 +693,7 @@ diff_run (argc, argv, out)
if ((val = setjmp (diff_abort_buf)) != 0)
{
optind = optind_old;
if (outfile != stdout)
if (opened_file)
fclose (outfile);
return val;
}
@ -682,10 +706,14 @@ diff_run (argc, argv, out)
free (switch_string);
optind = optind_old;
check_output (outfile);
if (outfile != stdout)
if (! callbacks || ! callbacks->write_output)
check_output (outfile);
if (opened_file)
if (fclose (outfile) != 0)
perror ("close error on output file");
perror_with_name ("close error on output file");
return val;
}
@ -799,10 +827,27 @@ usage ()
{
char const * const *p;
printf ("Usage: %s [OPTION]... FILE1 FILE2\n\n", diff_program_name);
for (p = option_help; *p; p++)
printf (" %s\n", *p);
printf ("\nIf FILE1 or FILE2 is `-', read standard input.\n");
if (callbacks && callbacks->write_stdout)
{
(*callbacks->write_stdout) ("Usage: ");
(*callbacks->write_stdout) (diff_program_name);
(*callbacks->write_stdout) (" [OPTION]... FILE1 FILE2\n\n");
for (p = option_help; *p; p++)
{
(*callbacks->write_stdout) (" ");
(*callbacks->write_stdout) (*p);
(*callbacks->write_stdout) ("\n");
}
(*callbacks->write_stdout)
("\nIf FILE1 or FILE2 is `-', read standard input.\n");
}
else
{
printf ("Usage: %s [OPTION]... FILE1 FILE2\n\n", diff_program_name);
for (p = option_help; *p; p++)
printf (" %s\n", *p);
printf ("\nIf FILE1 or FILE2 is `-', read standard input.\n");
}
}
static int
@ -1147,7 +1192,7 @@ compare_files (dir0, name0, dir1, name1, depth)
inf[0].name, inf[1].name);
}
else
fflush (outfile);
flush_output ();
if (free0)
free (free0);

View File

@ -1,5 +1,5 @@
/* Shared definitions for GNU DIFF
Copyright (C) 1988, 89, 91, 92, 93, 97 Free Software Foundation, Inc.
Copyright (C) 1988, 89, 91, 92, 93, 97, 1998 Free Software Foundation, Inc.
This file is part of GNU DIFF.
@ -21,6 +21,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <stdio.h>
#include <setjmp.h>
#include "regex.h"
#include "diffrun.h"
#define TAB_WIDTH 8
@ -32,6 +33,9 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#define EXTERN
#endif
/* The callbacks to use for output. */
EXTERN const struct diff_callbacks *callbacks;
enum output_style {
/* Default output style. */
OUTPUT_NORMAL,
@ -329,6 +333,13 @@ void debug_script PARAMS((struct change *));
void diff_error PARAMS((char const *, char const *, char const *));
void fatal PARAMS((char const *));
void finish_output PARAMS((void));
void write_output PARAMS((char const *, size_t));
void printf_output PARAMS((char const *, ...))
#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 6)
__attribute__ ((__format__ (__printf__, 1, 2)))
#endif
;
void flush_output PARAMS((void));
void message PARAMS((char const *, char const *, char const *));
void message5 PARAMS((char const *, char const *, char const *, char const *, char const *));
void output_1_line PARAMS((char const *, char const *, char const *, char const *));

View File

@ -1,5 +1,5 @@
/* Three way file comparison program (diff3) for Project GNU.
Copyright (C) 1988, 1989, 1992, 1993, 1994, 1997 Free Software Foundation, Inc.
Copyright (C) 1988, 1989, 1992, 1993, 1994, 1997, 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
@ -22,6 +22,7 @@
#include <stdio.h>
#include <setjmp.h>
#include "getopt.h"
#include "diffrun.h"
/* diff3.c has a real initialize_main function. */
#ifdef initialize_main
@ -30,6 +31,18 @@
extern char const diff_version_string[];
extern FILE *outfile;
extern const struct diff_callbacks *callbacks;
void write_output PARAMS((char const *, size_t));
void printf_output PARAMS((char const *, ...))
#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 6)
__attribute__ ((__format__ (__printf__, 1, 2)))
#endif
;
void flush_output PARAMS((void));
/*
* Internal data structures and macros for the diff3 program; includes
* data structures for both diff3 diffs and normal diffs.
@ -186,9 +199,9 @@ static char *scan_diff_line PARAMS((char *, char **, size_t *, char *, int));
static enum diff_type process_diff_control PARAMS((char **, struct diff_block *));
static int compare_line_list PARAMS((char * const[], size_t const[], char * const[], size_t const[], int));
static int copy_stringlist PARAMS((char * const[], size_t const[], char *[], size_t[], int));
static int dotlines PARAMS((FILE *, struct diff3_block *, int));
static int output_diff3_edscript PARAMS((FILE *, struct diff3_block *, int const[3], int const[3], char const *, char const *, char const *));
static int output_diff3_merge PARAMS((FILE *, FILE *, struct diff3_block *, int const[3], int const[3], char const *, char const *, char const *));
static int dotlines PARAMS((struct diff3_block *, int));
static int output_diff3_edscript PARAMS((struct diff3_block *, int const[3], int const[3], char const *, char const *, char const *));
static int output_diff3_merge PARAMS((FILE *, struct diff3_block *, int const[3], int const[3], char const *, char const *, char const *));
static size_t myread PARAMS((int, char *, size_t));
static struct diff3_block *create_diff3_block PARAMS((int, int, int, int, int, int));
static struct diff3_block *make_3way_diff PARAMS((struct diff_block *, struct diff_block *));
@ -197,17 +210,16 @@ static struct diff3_block *using_to_diff3_block PARAMS((struct diff_block *[2],
static struct diff_block *process_diff PARAMS((char const *, char const *, struct diff_block **, char **));
static void check_output PARAMS((FILE *));
static void diff3_fatal PARAMS((char const *));
static void output_diff3 PARAMS((FILE *, struct diff3_block *, int const[3], int const[3]));
static void output_diff3 PARAMS((struct diff3_block *, int const[3], int const[3]));
static void diff3_perror_with_exit PARAMS((char const *));
static int try_help PARAMS((char const *));
static void undotlines PARAMS((FILE *, int, int, int));
static void undotlines PARAMS((int, int, int));
static void usage PARAMS((void));
static void initialize_main PARAMS((int *, char ***));
static void free_diff_blocks PARAMS((struct diff_block *));
static void free_diff3_blocks PARAMS((struct diff3_block *));
/* Functions provided in libdiff.a or other external sources. */
int diff_run PARAMS((int, char **, char *));
VOID *xmalloc PARAMS((size_t));
VOID *xrealloc PARAMS((VOID *, size_t));
void perror_with_name PARAMS((char const *));
@ -238,10 +250,11 @@ static struct option const longopts[] =
* combines the two diffs, and outputs them.
*/
int
diff3_run (argc, argv, outfile)
diff3_run (argc, argv, out, callbacks_arg)
int argc;
char **argv;
char *outfile;
char *out;
const struct diff_callbacks *callbacks_arg;
{
int c, i;
int mapping[3];
@ -258,7 +271,9 @@ diff3_run (argc, argv, outfile)
char **file;
struct stat statb;
int optind_old;
FILE *outstream;
int opened_file = 0;
callbacks = callbacks_arg;
initialize_main (&argc, &argv);
@ -303,11 +318,19 @@ diff3_run (argc, argv, outfile)
tab_align_flag = 1;
break;
case 'v':
printf ("diff3 - GNU diffutils version %s\n", diff_version_string);
if (callbacks && callbacks->write_stdout)
{
(*callbacks->write_stdout) ("diff3 - GNU diffutils version ");
(*callbacks->write_stdout) (diff_version_string);
(*callbacks->write_stdout) ("\n");
}
else
printf ("diff3 - GNU diffutils version %s\n", diff_version_string);
return 0;
case 129:
usage ();
check_output (stdout);
if (! callbacks || ! callbacks->write_stdout)
check_output (stdout);
return 0;
case 'L':
/* Handle up to three -L options. */
@ -383,22 +406,33 @@ diff3_run (argc, argv, outfile)
}
else if (S_ISDIR(statb.st_mode))
{
fprintf (stderr, "%s: %s: Is a directory\n",
diff_program_name, file[i]);
diff_error ("%s: Is a directory", file[i], 0);
return 2;
}
}
if (outfile == NULL)
outstream = stdout;
if (callbacks && callbacks->write_output)
{
if (out != NULL)
{
diff_error ("write callback with output file", 0, 0);
return 2;
}
}
else
{
outstream = fopen (outfile, "w");
if (outstream == NULL)
{
perror_with_name ("could not open output file");
return 2;
}
if (out == NULL)
outfile = stdout;
else
{
outfile = fopen (out, "w");
if (outfile == NULL)
{
perror_with_name ("could not open output file");
return 2;
}
opened_file = 1;
}
}
/* Set the jump buffer, so that diff may abort execution without
@ -421,21 +455,21 @@ diff3_run (argc, argv, outfile)
diff3 = make_3way_diff (thread0, thread1);
if (edscript)
conflicts_found
= output_diff3_edscript (outstream, diff3, mapping, rev_mapping,
= output_diff3_edscript (diff3, mapping, rev_mapping,
tag_strings[0], tag_strings[1], tag_strings[2]);
else if (merge)
{
if (! freopen (file[rev_mapping[FILE0]], "r", stdin))
diff3_perror_with_exit (file[rev_mapping[FILE0]]);
conflicts_found
= output_diff3_merge (stdin, outstream, diff3, mapping, rev_mapping,
= output_diff3_merge (stdin, diff3, mapping, rev_mapping,
tag_strings[0], tag_strings[1], tag_strings[2]);
if (ferror (stdin))
diff3_fatal ("read error");
}
else
{
output_diff3 (outstream, diff3, mapping, rev_mapping);
output_diff3 (diff3, mapping, rev_mapping);
conflicts_found = 0;
}
@ -445,10 +479,13 @@ diff3_run (argc, argv, outfile)
free_diff_blocks(thread1);
free_diff3_blocks(diff3);
check_output (outstream);
if (outstream != stdout)
if (fclose (outstream) != 0)
perror ("close error on output file");
if (! callbacks || ! callbacks->write_output)
check_output (outfile);
if (opened_file)
if (fclose (outfile) != 0)
perror_with_name ("close error on output file");
return conflicts_found;
}
@ -457,9 +494,8 @@ try_help (reason)
char const *reason;
{
if (reason)
fprintf (stderr, "%s: %s\n", diff_program_name, reason);
fprintf (stderr, "%s: Try `%s --help' for more information.\n",
diff_program_name, diff_program_name);
diff_error ("%s", reason, 0);
diff_error ("Try `%s --help' for more information.", diff_program_name, 0);
return 2;
}
@ -477,25 +513,52 @@ check_output (stream)
static void
usage ()
{
printf ("Usage: %s [OPTION]... MYFILE OLDFILE YOURFILE\n\n", diff_program_name);
if (callbacks && callbacks->write_stdout)
{
(*callbacks->write_stdout) ("Usage: ");
(*callbacks->write_stdout) (diff_program_name);
(*callbacks->write_stdout) (" [OPTION]... MYFILE OLDFILE YOURFILE\n\n");
printf ("%s", "\
(*callbacks->write_stdout) ("\
-e --ed Output unmerged changes from OLDFILE to YOURFILE into MYFILE.\n\
-E --show-overlap Output unmerged changes, bracketing conflicts.\n\
-A --show-all Output all changes, bracketing conflicts.\n\
-x --overlap-only Output overlapping changes.\n\
-X Output overlapping changes, bracketing them.\n\
-3 --easy-only Output unmerged nonoverlapping changes.\n\n");
printf ("%s", "\
(*callbacks->write_stdout) ("\
-m --merge Output merged file instead of ed script (default -A).\n\
-L LABEL --label=LABEL Use LABEL instead of file name.\n\
-i Append `w' and `q' commands to ed scripts.\n\
-a --text Treat all files as text.\n\
-T --initial-tab Make tabs line up by prepending a tab.\n\n");
printf ("%s", "\
(*callbacks->write_stdout) ("\
-v --version Output version info.\n\
--help Output this help.\n\n");
printf ("If a FILE is `-', read standard input.\n");
(*callbacks->write_stdout) ("If a FILE is `-', read standard input.\n");
}
else
{
printf ("Usage: %s [OPTION]... MYFILE OLDFILE YOURFILE\n\n", diff_program_name);
printf ("%s", "\
-e --ed Output unmerged changes from OLDFILE to YOURFILE into MYFILE.\n\
-E --show-overlap Output unmerged changes, bracketing conflicts.\n\
-A --show-all Output all changes, bracketing conflicts.\n\
-x --overlap-only Output overlapping changes.\n\
-X Output overlapping changes, bracketing them.\n\
-3 --easy-only Output unmerged nonoverlapping changes.\n\n");
printf ("%s", "\
-m --merge Output merged file instead of ed script (default -A).\n\
-L LABEL --label=LABEL Use LABEL instead of file name.\n\
-i Append `w' and `q' commands to ed scripts.\n\
-a --text Treat all files as text.\n\
-T --initial-tab Make tabs line up by prepending a tab.\n\n");
printf ("%s", "\
-v --version Output version info.\n\
--help Output this help.\n\n");
printf ("If a FILE is `-', read standard input.\n");
}
}
/*
@ -1011,12 +1074,13 @@ process_diff (filea, fileb, last_block, diff_contents)
dt = process_diff_control (&scan_diff, bptr);
if (dt == ERROR || *scan_diff != '\n')
{
fprintf (stderr, "%s: diff error: ", diff_program_name);
do
{
putc (*scan_diff, stderr);
}
while (*scan_diff++ != '\n');
char *serr;
for (serr = scan_diff; *serr != '\n'; serr++)
;
*serr = '\0';
diff_error ("diff error: %s", scan_diff, 0);
*serr = '\n';
DIFF3_ABORT (2);
}
scan_diff++;
@ -1185,6 +1249,10 @@ read_diff (filea, fileb, output_placement)
size_t bytes, current_chunk_size, total;
int fd, wstatus;
struct stat pipestat;
FILE *outfile_hold;
const struct diff_callbacks *callbacks_hold;
struct diff_callbacks my_callbacks;
struct diff_callbacks *my_callbacks_arg;
/* 302 / 1000 is log10(2.0) rounded up. Subtract 1 for the sign bit;
add 1 for integer division truncation; add 1 more for a minus sign. */
@ -1207,7 +1275,30 @@ read_diff (filea, fileb, output_placement)
*ap = 0;
diffout = tmpnam(NULL);
wstatus = diff_run (ap - argv, (char **) argv, diffout);
outfile_hold = outfile;
callbacks_hold = callbacks;
/* We want to call diff_run preserving any stdout and stderr
callbacks, but discarding any callbacks to handle file output,
since we want the file output to go to our temporary file.
FIXME: We should use callbacks to just read it into a memory
buffer; that's we do with the temporary file just below anyhow. */
if (callbacks == NULL)
my_callbacks_arg = NULL;
else
{
my_callbacks = *callbacks;
my_callbacks.write_output = NULL;
my_callbacks.flush_output = NULL;
my_callbacks_arg = &my_callbacks;
}
wstatus = diff_run (ap - argv, (char **) argv, diffout, my_callbacks_arg);
outfile = outfile_hold;
callbacks = callbacks_hold;
if (wstatus == 2)
diff3_fatal ("subsidiary diff failed");
@ -1282,17 +1373,25 @@ scan_diff_line (scan_ptr, set_start, set_length, limit, leadingchar)
*set_length = line_ptr - *set_start;
if (line_ptr < limit && *line_ptr == '\\')
{
if (edscript)
fprintf (stderr, "%s:", diff_program_name);
else
--*set_length;
line_ptr++;
do
if (! edscript)
{
if (edscript)
putc (*line_ptr, stderr);
--*set_length;
line_ptr++;
while (*line_ptr++ != '\n')
;
}
else
{
char *serr;
line_ptr++;
serr = line_ptr;
while (*line_ptr++ != '\n')
;
line_ptr[-1] = '\0';
diff_error ("%s", serr, 0);
line_ptr[-1] = '\n';
}
while (*line_ptr++ != '\n');
}
return line_ptr;
@ -1310,8 +1409,7 @@ scan_diff_line (scan_ptr, set_start, set_length, limit, leadingchar)
* REV_MAPPING is the inverse of MAPPING.
*/
static void
output_diff3 (outputfile, diff, mapping, rev_mapping)
FILE *outputfile;
output_diff3 (diff, mapping, rev_mapping)
struct diff3_block *diff;
int const mapping[3], rev_mapping[3];
{
@ -1348,7 +1446,7 @@ output_diff3 (outputfile, diff, mapping, rev_mapping)
default:
diff3_fatal ("internal error: invalid diff type passed to output");
}
fprintf (outputfile, "====%s\n", x);
printf_output ("====%s\n", x);
/* Go 0, 2, 1 if the first and third outputs are equivalent. */
for (i = 0; i < 3;
@ -1359,17 +1457,17 @@ output_diff3 (outputfile, diff, mapping, rev_mapping)
lowt = D_LOWLINE (ptr, realfile),
hight = D_HIGHLINE (ptr, realfile);
fprintf (outputfile, "%d:", i + 1);
printf_output ("%d:", i + 1);
switch (lowt - hight)
{
case 1:
fprintf (outputfile, "%da\n", lowt - 1);
printf_output ("%da\n", lowt - 1);
break;
case 0:
fprintf (outputfile, "%dc\n", lowt);
printf_output ("%dc\n", lowt);
break;
default:
fprintf (outputfile, "%d,%dc\n", lowt, hight);
printf_output ("%d,%dc\n", lowt, hight);
break;
}
@ -1380,14 +1478,14 @@ output_diff3 (outputfile, diff, mapping, rev_mapping)
line = 0;
do
{
fprintf (outputfile, line_prefix);
printf_output (line_prefix);
cp = D_RELNUM (ptr, realfile, line);
length = D_RELLEN (ptr, realfile, line);
fwrite (cp, sizeof (char), length, outputfile);
write_output (cp, length);
}
while (++line < hight - lowt + 1);
if (cp[length - 1] != '\n')
fprintf (outputfile, "\n\\ No newline at end of file\n");
printf_output ("\n\\ No newline at end of file\n");
}
}
}
@ -1395,12 +1493,11 @@ output_diff3 (outputfile, diff, mapping, rev_mapping)
/*
* Output to OUTPUTFILE the lines of B taken from FILENUM.
* Output the lines of B taken from FILENUM.
* Double any initial '.'s; yield nonzero if any initial '.'s were doubled.
*/
static int
dotlines (outputfile, b, filenum)
FILE *outputfile;
dotlines (b, filenum)
struct diff3_block *b;
int filenum;
{
@ -1415,10 +1512,9 @@ dotlines (outputfile, b, filenum)
if (line[0] == '.')
{
leading_dot = 1;
fprintf (outputfile, ".");
write_output (".", 1);
}
fwrite (line, sizeof (char),
D_RELLEN (b, filenum, i), outputfile);
write_output (line, D_RELLEN (b, filenum, i));
}
return leading_dot;
@ -1430,16 +1526,15 @@ dotlines (outputfile, b, filenum)
* starting with line START and continuing for NUM lines.
*/
static void
undotlines (outputfile, leading_dot, start, num)
FILE *outputfile;
undotlines (leading_dot, start, num)
int leading_dot, start, num;
{
fprintf (outputfile, ".\n");
write_output (".\n", 2);
if (leading_dot)
if (num == 1)
fprintf (outputfile, "%ds/^\\.//\n", start);
printf_output ("%ds/^\\.//\n", start);
else
fprintf (outputfile, "%d,%ds/^\\.//\n", start, start + num - 1);
printf_output ("%d,%ds/^\\.//\n", start, start + num - 1);
}
/*
@ -1465,9 +1560,7 @@ undotlines (outputfile, leading_dot, start, num)
*/
static int
output_diff3_edscript (outputfile, diff, mapping, rev_mapping,
file0, file1, file2)
FILE *outputfile;
output_diff3_edscript (diff, mapping, rev_mapping, file0, file1, file2)
struct diff3_block *diff;
int const mapping[3], rev_mapping[3];
char const *file0, *file1, *file2;
@ -1502,22 +1595,22 @@ output_diff3_edscript (outputfile, diff, mapping, rev_mapping,
/* Mark end of conflict. */
fprintf (outputfile, "%da\n", D_HIGHLINE (b, mapping[FILE0]));
printf_output ("%da\n", D_HIGHLINE (b, mapping[FILE0]));
leading_dot = 0;
if (type == DIFF_ALL)
{
if (show_2nd)
{
/* Append lines from FILE1. */
fprintf (outputfile, "||||||| %s\n", file1);
leading_dot = dotlines (outputfile, b, mapping[FILE1]);
printf_output ("||||||| %s\n", file1);
leading_dot = dotlines (b, mapping[FILE1]);
}
/* Append lines from FILE2. */
fprintf (outputfile, "=======\n");
leading_dot |= dotlines (outputfile, b, mapping[FILE2]);
printf_output ("=======\n");
leading_dot |= dotlines (b, mapping[FILE2]);
}
fprintf (outputfile, ">>>>>>> %s\n", file2);
undotlines (outputfile, leading_dot,
printf_output (">>>>>>> %s\n", file2);
undotlines (leading_dot,
D_HIGHLINE (b, mapping[FILE0]) + 2,
(D_NUMLINES (b, mapping[FILE1])
+ D_NUMLINES (b, mapping[FILE2]) + 1));
@ -1525,17 +1618,17 @@ output_diff3_edscript (outputfile, diff, mapping, rev_mapping,
/* Mark start of conflict. */
fprintf (outputfile, "%da\n<<<<<<< %s\n",
D_LOWLINE (b, mapping[FILE0]) - 1,
type == DIFF_ALL ? file0 : file1);
printf_output ("%da\n<<<<<<< %s\n",
D_LOWLINE (b, mapping[FILE0]) - 1,
type == DIFF_ALL ? file0 : file1);
leading_dot = 0;
if (type == DIFF_2ND)
{
/* Prepend lines from FILE1. */
leading_dot = dotlines (outputfile, b, mapping[FILE1]);
fprintf (outputfile, "=======\n");
leading_dot = dotlines (b, mapping[FILE1]);
printf_output ("=======\n");
}
undotlines (outputfile, leading_dot,
undotlines (leading_dot,
D_LOWLINE (b, mapping[FILE0]) + 1,
D_NUMLINES (b, mapping[FILE1]));
}
@ -1543,12 +1636,11 @@ output_diff3_edscript (outputfile, diff, mapping, rev_mapping,
/* Write out a delete */
{
if (D_NUMLINES (b, mapping[FILE0]) == 1)
fprintf (outputfile, "%dd\n",
D_LOWLINE (b, mapping[FILE0]));
printf_output ("%dd\n", D_LOWLINE (b, mapping[FILE0]));
else
fprintf (outputfile, "%d,%dd\n",
D_LOWLINE (b, mapping[FILE0]),
D_HIGHLINE (b, mapping[FILE0]));
printf_output ("%d,%dd\n",
D_LOWLINE (b, mapping[FILE0]),
D_HIGHLINE (b, mapping[FILE0]));
}
else
/* Write out an add or change */
@ -1556,33 +1648,32 @@ output_diff3_edscript (outputfile, diff, mapping, rev_mapping,
switch (D_NUMLINES (b, mapping[FILE0]))
{
case 0:
fprintf (outputfile, "%da\n",
D_HIGHLINE (b, mapping[FILE0]));
printf_output ("%da\n", D_HIGHLINE (b, mapping[FILE0]));
break;
case 1:
fprintf (outputfile, "%dc\n",
D_HIGHLINE (b, mapping[FILE0]));
printf_output ("%dc\n", D_HIGHLINE (b, mapping[FILE0]));
break;
default:
fprintf (outputfile, "%d,%dc\n",
D_LOWLINE (b, mapping[FILE0]),
D_HIGHLINE (b, mapping[FILE0]));
printf_output ("%d,%dc\n",
D_LOWLINE (b, mapping[FILE0]),
D_HIGHLINE (b, mapping[FILE0]));
break;
}
undotlines (outputfile, dotlines (outputfile, b, mapping[FILE2]),
undotlines (dotlines (b, mapping[FILE2]),
D_LOWLINE (b, mapping[FILE0]),
D_NUMLINES (b, mapping[FILE2]));
}
}
if (finalwrite) fprintf (outputfile, "w\nq\n");
if (finalwrite) printf_output ("w\nq\n");
return conflicts_found;
}
/*
* Read from INFILE and output to OUTPUTFILE a set of diff3_ blocks DIFF
* as a merged file. This acts like 'ed file0 <[output_diff3_edscript]',
* except that it works even for binary data or incomplete lines.
* Read from INFILE and output to the standard output file a set of
* diff3_ blocks DIFF as a merged file. This acts like 'ed file0
* <[output_diff3_edscript]', except that it works even for binary
* data or incomplete lines.
*
* As before, MAPPING maps from arg list file number to diff file number,
* REV_MAPPING is its inverse,
@ -1592,14 +1683,15 @@ output_diff3_edscript (outputfile, diff, mapping, rev_mapping,
*/
static int
output_diff3_merge (infile, outputfile, diff, mapping, rev_mapping,
output_diff3_merge (infile, diff, mapping, rev_mapping,
file0, file1, file2)
FILE *infile, *outputfile;
FILE *infile;
struct diff3_block *diff;
int const mapping[3], rev_mapping[3];
char const *file0, *file1, *file2;
{
int c, i;
char cc;
int conflicts_found = 0, conflict;
struct diff3_block *b;
int linesread = 0;
@ -1638,7 +1730,8 @@ output_diff3_merge (infile, outputfile, diff, mapping, rev_mapping,
diff3_perror_with_exit ("input file");
else if (feof (infile))
diff3_fatal ("input file shrank");
putc (c, outputfile);
cc = c;
write_output (&cc, 1);
}
while (c != '\n');
@ -1649,37 +1742,37 @@ output_diff3_merge (infile, outputfile, diff, mapping, rev_mapping,
if (type == DIFF_ALL)
{
/* Put in lines from FILE0 with bracket. */
fprintf (outputfile, "<<<<<<< %s\n", file0);
printf_output ("<<<<<<< %s\n", file0);
for (i = 0;
i < D_NUMLINES (b, mapping[FILE0]);
i++)
fwrite (D_RELNUM (b, mapping[FILE0], i), sizeof (char),
D_RELLEN (b, mapping[FILE0], i), outputfile);
write_output (D_RELNUM (b, mapping[FILE0], i),
D_RELLEN (b, mapping[FILE0], i));
}
if (show_2nd)
{
/* Put in lines from FILE1 with bracket. */
fprintf (outputfile, format_2nd, file1);
printf_output (format_2nd, file1);
for (i = 0;
i < D_NUMLINES (b, mapping[FILE1]);
i++)
fwrite (D_RELNUM (b, mapping[FILE1], i), sizeof (char),
D_RELLEN (b, mapping[FILE1], i), outputfile);
write_output (D_RELNUM (b, mapping[FILE1], i),
D_RELLEN (b, mapping[FILE1], i));
}
fprintf (outputfile, "=======\n");
printf_output ("=======\n");
}
/* Put in lines from FILE2. */
for (i = 0;
i < D_NUMLINES (b, mapping[FILE2]);
i++)
fwrite (D_RELNUM (b, mapping[FILE2], i), sizeof (char),
D_RELLEN (b, mapping[FILE2], i), outputfile);
write_output (D_RELNUM (b, mapping[FILE2], i),
D_RELLEN (b, mapping[FILE2], i));
if (conflict)
fprintf (outputfile, ">>>>>>> %s\n", file2);
printf_output (">>>>>>> %s\n", file2);
/* Skip I lines in file 0. */
i = D_NUMLINES (b, FILE0);
@ -1698,7 +1791,10 @@ output_diff3_merge (infile, outputfile, diff, mapping, rev_mapping,
}
/* Copy rest of common file. */
while ((c = getc (infile)) != EOF || !(ferror (infile) | feof (infile)))
putc (c, outputfile);
{
cc = c;
write_output (&cc, 1);
}
return conflicts_found;
}
@ -1737,7 +1833,7 @@ static void
diff3_fatal (string)
char const *string;
{
fprintf (stderr, "%s: %s\n", diff_program_name, string);
diff_error ("%s", string, 0);
DIFF3_ABORT (2);
}
@ -1745,10 +1841,7 @@ static void
diff3_perror_with_exit (string)
char const *string;
{
int e = errno;
fprintf (stderr, "%s: ", diff_program_name);
errno = e;
perror (string);
perror_with_name (string);
DIFF3_ABORT (2);
}
@ -1768,6 +1861,7 @@ initialize_main (argcp, argvp)
finalwrite = 0;
merge = 0;
diff_program_name = (*argvp)[0];
outfile = NULL;
}
static void

View File

@ -0,0 +1,69 @@
/* Interface header file for GNU DIFF library.
Copyright (C) 1998 Free Software Foundation, Inc.
This file is part of GNU DIFF.
GNU DIFF is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU DIFF is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU 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
/* This header file defines the interfaces used by the diff library.
It should be included by programs which use the diff library. */
#include <sys/types.h>
#if defined __STDC__ && __STDC__
#define DIFFPARAMS(args) args
#else
#define DIFFPARAMS(args) ()
#endif
/* The diff_callbacks structure is used to handle callbacks from the
diff library. All output goes through these callbacks. When a
pointer to this structure is passed in, it may be NULL. Also, any
of the individual callbacks may be NULL. This means that the
default action should be taken. */
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. */
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. */
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
message on stderr. */
void (*error) DIFFPARAMS((char const *, char const *, char const *));
};
/* Run a diff. */
extern int diff_run DIFFPARAMS((int, char **, char *,
const struct diff_callbacks *));
/* Run a diff3. */
extern int diff3_run DIFFPARAMS((int, char **, char *,
const struct diff_callbacks *));
#undef DIFFPARAMS
#endif /* DIFFRUN_H */

View File

@ -1,5 +1,5 @@
/* Output routines for ed-script format.
Copyright (C) 1988, 89, 91, 92, 93 Free Software Foundation, Inc.
Copyright (C) 1988, 89, 91, 92, 93, 1998 Free Software Foundation, Inc.
This file is part of GNU DIFF.
@ -57,7 +57,7 @@ print_ed_hunk (hunk)
/* Print out the line number header for this hunk */
print_number_range (',', &files[0], f0, l0);
fprintf (outfile, "%c\n", change_letter (inserts, deletes));
printf_output ("%c\n", change_letter (inserts, deletes));
/* Print new/changed lines from second file, if needed */
if (inserts)
@ -68,8 +68,8 @@ print_ed_hunk (hunk)
{
/* Resume the insert, if we stopped. */
if (! inserting)
fprintf (outfile, "%da\n",
i - f1 + translate_line_number (&files[0], f0) - 1);
printf_output ("%da\n",
i - f1 + translate_line_number (&files[0], f0) - 1);
inserting = 1;
/* If the file's line is just a dot, it would confuse `ed'.
@ -80,11 +80,11 @@ print_ed_hunk (hunk)
if (files[1].linbuf[i][0] == '.'
&& files[1].linbuf[i][1] == '\n')
{
fprintf (outfile, "..\n");
fprintf (outfile, ".\n");
printf_output ("..\n");
printf_output (".\n");
/* Now change that double dot to the desired single dot. */
fprintf (outfile, "%ds/^\\.\\././\n",
i - f1 + translate_line_number (&files[0], f0));
printf_output ("%ds/^\\.\\././\n",
i - f1 + translate_line_number (&files[0], f0));
inserting = 0;
}
else
@ -94,7 +94,7 @@ print_ed_hunk (hunk)
/* End insert mode, if we are still in it. */
if (inserting)
fprintf (outfile, ".\n");
printf_output (".\n");
}
}
@ -124,9 +124,9 @@ pr_forward_ed_hunk (hunk)
begin_output ();
fprintf (outfile, "%c", change_letter (inserts, deletes));
printf_output ("%c", change_letter (inserts, deletes));
print_number_range (' ', files, f0, l0);
fprintf (outfile, "\n");
printf_output ("\n");
/* If deletion only, print just the number range. */
@ -139,7 +139,7 @@ pr_forward_ed_hunk (hunk)
for (i = f1; i <= l1; i++)
print_1_line ("", &files[1].linbuf[i]);
fprintf (outfile, ".\n");
printf_output (".\n");
}
/* Print in a format somewhat like ed commands
@ -175,23 +175,23 @@ print_rcs_hunk (hunk)
if (deletes)
{
fprintf (outfile, "d");
printf_output ("d");
/* For deletion, print just the starting line number from file 0
and the number of lines deleted. */
fprintf (outfile, "%d %d\n",
tf0,
(tl0 >= tf0 ? tl0 - tf0 + 1 : 1));
printf_output ("%d %d\n",
tf0,
(tl0 >= tf0 ? tl0 - tf0 + 1 : 1));
}
if (inserts)
{
fprintf (outfile, "a");
printf_output ("a");
/* Take last-line-number from file 0 and # lines from file 1. */
translate_range (&files[1], f1, l1, &tf1, &tl1);
fprintf (outfile, "%d %d\n",
tl0,
(tl1 >= tf1 ? tl1 - tf1 + 1 : 1));
printf_output ("%d %d\n",
tl0,
(tl1 >= tf1 ? tl1 - tf1 + 1 : 1));
/* Print the inserted lines. */
for (i = f1; i <= l1; i++)

View File

@ -1,5 +1,5 @@
/* #ifdef-format output routines for GNU DIFF.
Copyright (C) 1989, 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
Copyright (C) 1989, 1991, 1992, 1993, 1994, 1998 Free Software Foundation, Inc.
This file is part of GNU DIFF.
@ -27,13 +27,13 @@ struct group
int from, upto; /* start and limit lines for this group of lines */
};
static char *format_group PARAMS((FILE *, char *, int, struct group const *));
static char *format_group PARAMS((int, char *, int, struct group const *));
static char *scan_char_literal PARAMS((char *, int *));
static char *scan_printf_spec PARAMS((char *));
static int groups_letter_value PARAMS((struct group const *, int));
static void format_ifdef PARAMS((char *, int, int, int, int));
static void print_ifdef_hunk PARAMS((struct change *));
static void print_ifdef_lines PARAMS((FILE *, char *, struct group const *));
static void print_ifdef_lines PARAMS((int, char *, struct group const *));
static int next_line;
@ -103,18 +103,18 @@ format_ifdef (format, beg0, end0, beg1, end1)
groups[1].file = &files[1];
groups[1].from = beg1;
groups[1].upto = end1;
format_group (outfile, format, '\0', groups);
format_group (1, format, '\0', groups);
}
/* Print to file OUT a set of lines according to FORMAT.
/* If DOIT is non-zero, output a set of lines according to FORMAT.
The format ends at the first free instance of ENDCHAR.
Yield the address of the terminating character.
GROUPS specifies which lines to print.
If OUT is zero, do not actually print anything; just scan the format. */
static char *
format_group (out, format, endchar, groups)
register FILE *out;
format_group (doit, format, endchar, groups)
int doit;
char *format;
int endchar;
struct group const *groups;
@ -137,7 +137,7 @@ format_group (out, format, endchar, groups)
/* Print if-then-else format e.g. `%(n=1?thenpart:elsepart)'. */
{
int i, value[2];
FILE *thenout, *elseout;
int thendoit, elsedoit;
for (i = 0; i < 2; i++)
{
@ -159,13 +159,13 @@ format_group (out, format, endchar, groups)
goto bad_format;
}
if (value[0] == value[1])
thenout = out, elseout = 0;
thendoit = doit, elsedoit = 0;
else
thenout = 0, elseout = out;
f = format_group (thenout, f, ':', groups);
thendoit = 0, elsedoit = doit;
f = format_group (thendoit, f, ':', groups);
if (*f)
{
f = format_group (elseout, f + 1, ')', groups);
f = format_group (elsedoit, f + 1, ')', groups);
if (*f)
f++;
}
@ -174,17 +174,17 @@ format_group (out, format, endchar, groups)
case '<':
/* Print lines deleted from first file. */
print_ifdef_lines (out, line_format[OLD], &groups[0]);
print_ifdef_lines (doit, line_format[OLD], &groups[0]);
continue;
case '=':
/* Print common lines. */
print_ifdef_lines (out, line_format[UNCHANGED], &groups[0]);
print_ifdef_lines (doit, line_format[UNCHANGED], &groups[0]);
continue;
case '>':
/* Print lines inserted from second file. */
print_ifdef_lines (out, line_format[NEW], &groups[1]);
print_ifdef_lines (doit, line_format[NEW], &groups[1]);
continue;
default:
@ -211,11 +211,11 @@ format_group (out, format, endchar, groups)
goto bad_format;
break;
}
if (out)
if (doit)
{
/* Temporarily replace e.g. "%3dnx" with "%3d\0x". */
*speclim = 0;
fprintf (out, spec - 1, value);
printf_output (spec - 1, value);
/* Undo the temporary replacement. */
*speclim = c;
}
@ -228,8 +228,12 @@ format_group (out, format, endchar, groups)
break;
}
}
if (out)
putc (c, out);
if (doit)
{
/* Don't take the address of a register variable. */
char cc = c;
write_output (&cc, 1);
}
}
return f;
}
@ -257,11 +261,11 @@ groups_letter_value (g, letter)
}
}
/* Print to file OUT, using FORMAT to print the line group GROUP.
But do nothing if OUT is zero. */
/* Output using FORMAT to print the line group GROUP.
But do nothing if DOIT is zero. */
static void
print_ifdef_lines (out, format, group)
register FILE *out;
print_ifdef_lines (doit, format, group)
int doit;
char *format;
struct group const *group;
{
@ -269,7 +273,7 @@ print_ifdef_lines (out, format, group)
char const * const *linbuf = file->linbuf;
int from = group->from, upto = group->upto;
if (!out)
if (!doit)
return;
/* If possible, use a single fwrite; it's faster. */
@ -277,15 +281,15 @@ print_ifdef_lines (out, format, group)
{
if (format[1] == 'l' && format[2] == '\n' && !format[3])
{
fwrite (linbuf[from], sizeof (char),
linbuf[upto] + (linbuf[upto][-1] != '\n') - linbuf[from],
out);
write_output (linbuf[from],
(linbuf[upto] + (linbuf[upto][-1] != '\n')
- linbuf[from]));
return;
}
if (format[1] == 'L' && !format[2])
{
fwrite (linbuf[from], sizeof (char),
linbuf[upto] - linbuf[from], out);
write_output (linbuf[from],
linbuf[upto] - linbuf[from]);
return;
}
}
@ -294,6 +298,7 @@ print_ifdef_lines (out, format, group)
{
register char c;
register char *f = format;
char cc;
while ((c = *f++) != 0)
{
@ -342,7 +347,7 @@ print_ifdef_lines (out, format, group)
}
/* Temporarily replace e.g. "%3dnx" with "%3d\0x". */
*speclim = 0;
fprintf (out, spec - 1, value);
printf_output (spec - 1, value);
/* Undo the temporary replacement. */
*speclim = c;
}
@ -354,7 +359,10 @@ print_ifdef_lines (out, format, group)
break;
}
}
putc (c, out);
/* Don't take the address of a register variable. */
cc = c;
write_output (&cc, 1);
}
}
}

View File

@ -1,5 +1,5 @@
/* Normal-format output routines for GNU DIFF.
Copyright (C) 1988, 1989, 1993 Free Software Foundation, Inc.
Copyright (C) 1988, 1989, 1993, 1998 Free Software Foundation, Inc.
This file is part of GNU DIFF.
@ -52,9 +52,9 @@ print_normal_hunk (hunk)
/* Print out the line number header for this hunk */
print_number_range (',', &files[0], first0, last0);
fprintf (outfile, "%c", change_letter (inserts, deletes));
printf_output ("%c", change_letter (inserts, deletes));
print_number_range (',', &files[1], first1, last1);
fprintf (outfile, "\n");
printf_output ("\n");
/* Print the lines that the first file has. */
if (deletes)
@ -62,7 +62,7 @@ print_normal_hunk (hunk)
print_1_line ("<", &files[0].linbuf[i]);
if (inserts && deletes)
fprintf (outfile, "---\n");
printf_output ("---\n");
/* Print the lines that the second file has. */
if (inserts)

View File

@ -1,5 +1,5 @@
/* sdiff-format output routines for GNU DIFF.
Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc.
Copyright (C) 1991, 1992, 1993, 1998 Free Software Foundation, Inc.
This file is part of GNU DIFF.
@ -50,17 +50,16 @@ static unsigned
tab_from_to (from, to)
unsigned from, to;
{
FILE *out = outfile;
unsigned tab;
if (! tab_expand_flag)
for (tab = from + TAB_WIDTH - from % TAB_WIDTH; tab <= to; tab += TAB_WIDTH)
{
putc ('\t', out);
write_output ("\t", 1);
from = tab;
}
while (from++ < to)
putc (' ', out);
write_output (" ", 1);
return to;
}
@ -74,7 +73,6 @@ print_half_line (line, indent, out_bound)
char const * const *line;
unsigned indent, out_bound;
{
FILE *out = outfile;
register unsigned in_position = 0, out_position = 0;
register char const
*text_pointer = line[0],
@ -83,6 +81,9 @@ print_half_line (line, indent, out_bound)
while (text_pointer < text_limit)
{
register unsigned char c = *text_pointer++;
/* We use CC to avoid taking the address of the register
variable C. */
char cc;
switch (c)
{
@ -97,13 +98,14 @@ print_half_line (line, indent, out_bound)
if (out_bound < tabstop)
tabstop = out_bound;
for (; out_position < tabstop; out_position++)
putc (' ', out);
write_output (" ", 1);
}
else
if (tabstop < out_bound)
{
out_position = tabstop;
putc (c, out);
cc = c;
write_output (&cc, 1);
}
}
in_position += spaces;
@ -112,7 +114,8 @@ print_half_line (line, indent, out_bound)
case '\r':
{
putc (c, out);
cc = c;
write_output (&cc, 1);
tab_from_to (0, indent);
in_position = out_position = 0;
}
@ -123,11 +126,12 @@ print_half_line (line, indent, out_bound)
if (out_position <= in_position)
/* Add spaces to make up for suppressed tab past out_bound. */
for (; out_position < in_position; out_position++)
putc (' ', out);
write_output (" ", 1);
else
{
out_position = in_position;
putc (c, out);
cc = c;
write_output (&cc, 1);
}
break;
@ -135,7 +139,10 @@ print_half_line (line, indent, out_bound)
case '\v':
control_char:
if (in_position < out_bound)
putc (c, out);
{
cc = c;
write_output (&cc, 1);
}
break;
default:
@ -146,7 +153,8 @@ print_half_line (line, indent, out_bound)
if (in_position++ < out_bound)
{
out_position = in_position;
putc (c, out);
cc = c;
write_output (&cc, 1);
}
break;
@ -170,7 +178,6 @@ print_1sdiff_line (left, sep, right)
int sep;
char const * const *right;
{
FILE *out = outfile;
unsigned hw = sdiff_half_width, c2o = sdiff_column2_offset;
unsigned col = 0;
int put_newline = 0;
@ -184,10 +191,13 @@ print_1sdiff_line (left, sep, right)
if (sep != ' ')
{
char cc;
col = tab_from_to (col, (hw + c2o - 1) / 2) + 1;
if (sep == '|' && put_newline != (right[1][-1] == '\n'))
sep = put_newline ? '/' : '\\';
putc (sep, out);
cc = sep;
write_output (&cc, 1);
}
if (right)
@ -202,7 +212,7 @@ print_1sdiff_line (left, sep, right)
}
if (put_newline)
putc ('\n', out);
write_output ("\n", 1);
}
/* Print lines common to both files in side-by-side format. */
@ -215,7 +225,7 @@ print_sdiff_common_lines (limit0, limit1)
if (! sdiff_skip_common_lines && (i0 != limit0 || i1 != limit1))
{
if (sdiff_help_sdiff)
fprintf (outfile, "i%d,%d\n", limit0 - i0, limit1 - i1);
printf_output ("i%d,%d\n", limit0 - i0, limit1 - i1);
if (! sdiff_left_only)
{
@ -252,7 +262,7 @@ print_sdiff_hunk (hunk)
print_sdiff_common_lines (first0, first1);
if (sdiff_help_sdiff)
fprintf (outfile, "c%d,%d\n", last0 - first0 + 1, last1 - first1 + 1);
printf_output ("c%d,%d\n", last0 - first0 + 1, last1 - first1 + 1);
/* Print ``xxx | xxx '' lines */
if (inserts && deletes)

View File

@ -1,5 +1,5 @@
/* Support routines for GNU DIFF.
Copyright (C) 1988, 1989, 1992, 1993, 1994, 1997 Free Software Foundation, Inc.
Copyright (C) 1988, 1989, 1992, 1993, 1994, 1997, 1998 Free Software Foundation, Inc.
This file is part of GNU DIFF.
@ -19,6 +19,16 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "diff.h"
#ifdef __STDC__
#include <stdarg.h>
#else
#include <varargs.h>
#endif
#ifndef strerror
extern char *strerror ();
#endif
/* Queue up one-line messages to be printed at the end,
when -l is specified. Each message is recorded with a `struct msg'. */
@ -48,9 +58,15 @@ perror_with_name (text)
char const *text;
{
int e = errno;
fprintf (stderr, "%s: ", diff_program_name);
errno = e;
perror (text);
if (callbacks && callbacks->error)
(*callbacks->error) ("%s: %s", text, strerror (e));
else
{
fprintf (stderr, "%s: ", diff_program_name);
errno = e;
perror (text);
}
}
/* Use when a system call returns non-zero status and that is fatal. */
@ -61,9 +77,14 @@ pfatal_with_name (text)
{
int e = errno;
print_message_queue ();
fprintf (stderr, "%s: ", diff_program_name);
errno = e;
perror (text);
if (callbacks && callbacks->error)
(*callbacks->error) ("%s: %s", text, strerror (e));
else
{
fprintf (stderr, "%s: ", diff_program_name);
errno = e;
perror (text);
}
DIFF_ABORT (2);
}
@ -74,9 +95,14 @@ void
diff_error (format, arg, arg1)
char const *format, *arg, *arg1;
{
fprintf (stderr, "%s: ", diff_program_name);
fprintf (stderr, format, arg, arg1);
fprintf (stderr, "\n");
if (callbacks && callbacks->error)
(*callbacks->error) (format, arg, arg1);
else
{
fprintf (stderr, "%s: ", diff_program_name);
fprintf (stderr, format, arg, arg1);
fprintf (stderr, "\n");
}
}
/* Print an error message containing the string TEXT, then exit. */
@ -119,8 +145,8 @@ message5 (format, arg1, arg2, arg3, arg4)
else
{
if (sdiff_help_sdiff)
putc (' ', outfile);
fprintf (outfile, format, arg1, arg2, arg3, arg4);
write_output (" ", 1);
printf_output (format, arg1, arg2, arg3, arg4);
}
}
@ -132,7 +158,7 @@ print_message_queue ()
struct msg *m;
for (m = msg_chain; m; m = m->next)
fprintf (outfile, m->format, m->arg1, m->arg2, m->arg3, m->arg4);
printf_output (m->format, m->arg1, m->arg2, m->arg3, m->arg4);
}
/* Call before outputting the results of comparing files NAME0 and NAME1
@ -180,6 +206,9 @@ begin_output ()
This requirement is silly and does not match historical practice. */
sprintf (name, "diff%s %s %s", switch_string, current_name0, current_name1);
if (paginate_flag && callbacks && callbacks->write_output)
fatal ("can't paginate when using library callbacks");
if (paginate_flag)
{
/* Make OUTFILE a pipe to a subsidiary `pr'. */
@ -243,7 +272,7 @@ begin_output ()
/* If handling multiple files (because scanning a directory),
print which files the following output is about. */
if (current_depth > 0)
fprintf (outfile, "%s\n", name);
printf_output ("%s\n", name);
}
free (name);
@ -293,6 +322,68 @@ finish_output ()
output_in_progress = 0;
}
/* Write something to the output file. */
void
write_output (text, len)
char const *text;
size_t len;
{
if (callbacks && callbacks->write_output)
(*callbacks->write_output) (text, len);
else if (len == 1)
putc (*text, outfile);
else
fwrite (text, sizeof (char), len, outfile);
}
/* Printf something to the output file. */
#ifdef __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__)
printf_output (const char *format, ...)
#else
printf_output (format, va_alist)
char const *format;
va_dcl
#endif
{
va_list args;
VA_START (args, format);
if (callbacks && callbacks->write_output)
{
char *p;
p = NULL;
vasprintf (&p, format, args);
if (p == NULL)
fatal ("out of memory");
(*callbacks->write_output) (p, strlen (p));
free (p);
}
else
vfprintf (outfile, format, args);
va_end (args);
}
/* Flush the output file. */
void
flush_output ()
{
if (callbacks && callbacks->flush_output)
(*callbacks->flush_output) ();
else
fflush (outfile);
}
/* Compare two lines (typically one from each input file)
according to the command line options.
@ -469,7 +560,6 @@ print_1_line (line_flag, line)
char const * const *line;
{
char const *text = line[0], *limit = line[1]; /* Help the compiler. */
FILE *out = outfile; /* Help the compiler some more. */
char const *flag_format = 0;
/* If -T was specified, use a Tab between the line-flag and the text.
@ -479,13 +569,13 @@ print_1_line (line_flag, line)
if (line_flag && *line_flag)
{
flag_format = tab_align_flag ? "%s\t" : "%s ";
fprintf (out, flag_format, line_flag);
printf_output (flag_format, line_flag);
}
output_1_line (text, limit, flag_format, line_flag);
if ((!line_flag || line_flag[0]) && limit[-1] != '\n')
fprintf (out, "\n\\ No newline at end of file\n");
printf_output ("\n\\ No newline at end of file\n");
}
/* Output a line from TEXT up to LIMIT. Without -t, output verbatim.
@ -498,13 +588,15 @@ output_1_line (text, limit, flag_format, line_flag)
char const *text, *limit, *flag_format, *line_flag;
{
if (!tab_expand_flag)
fwrite (text, sizeof (char), limit - text, outfile);
write_output (text, limit - text);
else
{
register FILE *out = outfile;
register unsigned char c;
register char const *t = text;
register unsigned column = 0;
/* CC is used to avoid taking the address of the register
variable C. */
char cc;
while (t < limit)
switch ((c = *t++))
@ -514,15 +606,15 @@ output_1_line (text, limit, flag_format, line_flag)
unsigned spaces = TAB_WIDTH - column % TAB_WIDTH;
column += spaces;
do
putc (' ', out);
write_output (" ", 1);
while (--spaces);
}
break;
case '\r':
putc (c, out);
write_output ("\r", 1);
if (flag_format && t < limit && *t != '\n')
fprintf (out, flag_format, line_flag);
printf_output (flag_format, line_flag);
column = 0;
break;
@ -530,13 +622,14 @@ output_1_line (text, limit, flag_format, line_flag)
if (column == 0)
continue;
column--;
putc (c, out);
write_output ("\b", 1);
break;
default:
if (ISPRINT (c))
column++;
putc (c, out);
cc = c;
write_output (&cc, 1);
break;
}
}
@ -598,9 +691,9 @@ print_number_range (sepchar, file, a, b)
In this case, we should print the line number before the range,
which is B. */
if (trans_b > trans_a)
fprintf (outfile, "%d%c%d", trans_a, sepchar, trans_b);
printf_output ("%d%c%d", trans_a, sepchar, trans_b);
else
fprintf (outfile, "%d", trans_b);
printf_output ("%d", trans_b);
}
/* Look at a hunk of edit script and report the range of lines in each file

View File

@ -1,3 +1,122 @@
Sun Jul 26 02:42:20 1998 Noel Cragg <noel@swish.red-bean.com>
* cvs.texinfo (config): TopLevelAdmin variable.
* cvsclient.texi (Requests): fix typo.
1998-07-14 Jim Kingdon <kingdon@harvey.cyclic.com>
* cvsclient.texi (Requests): "remove" is like "add" in the sense
that it is the "ci" request which does most of the work.
1998-06-23 Jim Kingdon <kingdon@harvey.cyclic.com>
* cvs.texinfo (Excluding directories): Fix order of
"!first-dir/sdir" and "first-dir" to match what CVS actually
accepts. Reported by Tim McIntosh of sterling.com.
1998-06-09 Jim Kingdon <kingdon@harvey.cyclic.com>
* cvs.texinfo (Using keywords): Rewrite to be less specific to
source code in C. The old text was worse than that; it was
specific to certain versions of GCC (not even current GCC's, I
don't think) (reported most recently by Mitchell Perilstein;
if memory serves by others before that).
1998-06-08 Jim Kingdon <kingdon@harvey.cyclic.com>
* cvs.texinfo (Concurrency): Also mention #cvs.lock. Don't
mention #cvs.tfl; it is quite old (before CVS 1.5).
(Locks, Backing up, Concurrency): Add more index entries.
1998-06-03 Ian Lance Taylor <ian@cygnus.com>
* cvs.texinfo (Tracking sources): Clarify that the vendor branch
is only made the head revision when you import a new file, not any
time you import a file.
1998-05-23 Jim Kingdon <kingdon@harvey.cyclic.com>
* cvs.texinfo (What is CVS?): info-cvs-request is now at gnu.org
and is no longer handled by a human (hallelujah).
1998-05-12 Jim Meyering <meyering@ascend.com>
* cvs.texinfo: Add an info dir entry.
Remove trailing white space.
1998-05-05 Jim Kingdon <kingdon@harvey.cyclic.com>
* cvs.texinfo (Wrappers): Be more explicit that -m 'COPY' has no
effect on binary files.
1998-05-02 Jim Kingdon <kingdon@harvey.cyclic.com>
* RCSFILES: Add more discussion of the order of the revisions.
1998-04-27 Jim Kingdon <kingdon@harvey.cyclic.com>
* cvs.texinfo (loginfo example): Also give example of sending
mail. Use internal variable $USER rather than expecting CVS to
set the environment variable $USER. Change unnecessary 'sed'
invocation to 'cat' (it suffered from the same problem in terms of
internal variables versus environment variables).
* cvs.texinfo (Error messages): Add "conflict: removed FILE was
modified by second party".
1998-04-20 Jim Kingdon <kingdon@harvey.cyclic.com>
* cvs.texinfo (Common options): Update comment about meaning of
HEAD in cvs diff.
1998-04-12 Jim Kingdon <kingdon@harvey.cyclic.com>
* cvsclient.texi (Dates): Also mention log -d.
* cvs.texinfo (Invoking CVS): No space is allowed between -r or -w
and its argument, for the log command.
1998-04-11 Jim Kingdon <kingdon@harvey.cyclic.com>
* cvsclient.texi (Dates): New section, explaining the deal with
date formats.
1998-04-09 Jim Kingdon <kingdon@harvey.cyclic.com>
* cvs.texinfo (Global options, Invoking CVS): Fix typo
("files files" -> "files").
(Invoking CVS): Make -q and -Q more concise.
(Invoking CVS): Use @var for metavariables in "diff -r".
1998-03-17 Jim Kingdon <kingdon@harvey.cyclic.com>
* cvs.texinfo (~/.cvsrc): In example, put "checkout" rather than
"co" into .cvsrc; we just finished explaining that only the former
works! Thanks to Lenny Foner for reporting this.
* cvs.texinfo (Copying): Remove this node. This basically
restores the status quo prior to 18 Oct 1996 (before then the node
existed but was empty).
(before Top): Adjust copyright notice accordingly.
1998-03-12 Tim Pierce <twp@skepsis.com>
* RCSFILES: Updated description of `hardlinks' newphrases.
1998-03-07 Jim Kingdon <kingdon@harvey.cyclic.com>
* cvs.texinfo (Tags, Sticky tags, Creating a branch, Accessing
branches): Rename release-0-1 tag to rel-0-1 and likewise for
release-0-1-patches and release-0-4. This fixes an overfull hbox.
(diff options): Reformat table to fix underfull hboxes and such.
1998-03-07 Tim Pierce <twp@skepsis.com>
* cvs.texinfo (Editing files, Special Files): Document hardlinks.
Various cleanups to PreservePermissions text.
* RCSFILES: Document PreservePermissions newphrases.
1998-03-04 Jim Kingdon <kingdon@harvey.cyclic.com>
* cvs.texinfo (Special Files): Add notes about client/server CVS
@ -213,13 +332,13 @@ Sun Nov 30 20:38:17 1997 Jim Kingdon <kingdon@harvey.cyclic.com>
* cvs.texinfo (Wrappers): Add comment: we don't document %s.
Mon Nov 24 23:00:09 1997 Karl Fogel <kfogel@floss.red-bean.com>
Mon Nov 24 23:00:09 1997 Karl Fogel <kfogel@floss.red-bean.com>
and Jim Kingdon <kingdon@harvey.cyclic.com>
* cvsclient.texi: Move Protocol Notes node to the end.
* cvsclient.texi (Request intro): new node/section.
(Protocol): added some introductory material.
(Protocol): added some introductory material.
Rearranged menu into General Conventions, Protocol specification,
and Example etc sections.
(File Modes): replaces Modes, for consistency.
@ -418,7 +537,7 @@ Sat Sep 6 11:29:15 1997 Jim Kingdon <kingdon@harvey.cyclic.com>
Fri Sep 5 14:42:39 1997 Jim Kingdon <kingdon@harvey.cyclic.com>
* cvs.texinfo (BUGS): Remove mention of unsupported resources page
on http://www.cyclic.com, as it might go away in a future
on http://www.cyclic.com, as it might go away in a future
reorganization.
* DIFFUTILS-2.7-BUG: Further info from Eggert.
@ -1229,7 +1348,7 @@ Tue Mar 18 15:50:47 1997 Jim Kingdon <kingdon@harvey.cyclic.com>
(A sample session): Add comment about how we need an introduction
and what might go into one. Also bring in the paragraph from
Basic concepts introducing modules, but comment it out.
(Viewing differences): Add comment about
(Viewing differences): Add comment about
(Basic concepts): Removed; its content has been farmed out as
described above, and as the comment said, it was fundamentally
flawed.
@ -1544,7 +1663,7 @@ Thu Nov 14 10:22:58 1996 Jim Kingdon <kingdon@harvey.cyclic.com>
chunks, and about atomicity to be focused more on the protocol
than the current implementation.
(Notes): Remove this node. The attempt to describe the basic
model has pretty much been replaced by the Introduction.
model has pretty much been replaced by the Introduction.
The material about how to start the client is incomplete and
better left to cvs.texinfo. And the item about the lack of
SERVER_FLOWCONTROL is obsolete now that SERVER_FLOWCONTROL is the
@ -1700,7 +1819,7 @@ Mon Sep 30 18:17:34 1996 Greg A. Woods <woods@most.weird.com>
GREPBIN.
(export examples): add one.
(import options): describe the effect of '-b 1'.
Mon Sep 30 08:09:53 1996 Jim Kingdon <kingdon@harvey.cyclic.com>
* cvs.texinfo: Adjust comments concerning A4 vs. US letter,
@ -2404,14 +2523,14 @@ Sun Dec 31 10:53:47 1995 Jim Kingdon <kingdon@harvey.cyclic.com>
Sun Dec 24 02:37:51 1995 Karl Fogel <kfogel@floss.cyclic.com>
* cvs.texinfo (Using the client with password authentication):
* cvs.texinfo (Using the client with password authentication):
tixed fypos.
Sun Dec 24 00:00:16 1995 Karl Fogel <kfogel@floss.cyclic.com>
* cvs.texinfo (Remote repositories): use @code{rsh} most places,
because it is the name of a program, and because I am a pedant.
Refer to new node "Password authenticated".
Refer to new node "Password authenticated".
(Password authenticated): new node.
(Setting up the server for password authentication): new node.
(Using the client with password authentication): new node.

View File

@ -24,12 +24,33 @@ several other output formats. If you just want some source code to
look at, the part of CVS which applies these is RCS_deltas in
src/rcs.c.
The first time I read rcsfile.5 I didn't really notice the part about
the order of the revisions. This order _is_ important and CVS relies
on it. It is documented but it would be clearer if the example in
rcsfile.5 also showed the order of the revisions (and the "next" and
"branch" fields and anything else where it would be useful to have an
example of how a revision tree is represented in an RCS file).
The rcsfile.5 documentation only _very_ briefly touches on the order
of the revisions. The order _is_ important and CVS relies on it.
Here is an example of what I was able to find, based on the join3
sanity.sh testcase (and the behavior I am documenting here seems to be
the same for RCS 5.7 and CVS 1.9.27):
1.1 -----------------> 1.2
\---> 1.1.2.1 \---> 1.2.2.1
Here is how this shows up in the RCS file (omitting irrelevant parts):
admin: head 1.2;
deltas:
1.2 branches 1.2.2.1; next 1.1;
1.1 branches 1.1.2.1; next;
1.1.2.1 branches; next;
1.2.2.1 branches; next;
deltatexts:
1.2
1.2.2.1
1.1
1.1.2.1
Yes, the order seems to differ between the deltas and the deltatexts.
I have no idea how much of this should actually be considered part of
the RCS file format, and how much programs reading it should expect to
encounter any order.
The rcsfile.5 grammar shows the {num} after "next" as optional; if it
is omitted then there is no next delta node (for example 1.1 or the
@ -62,6 +83,38 @@ rules.
the current CVS death support, which uses a state "dead"
rather than a "dead" newphrase.
CVS does use newphrases to implement the `PreservePermissions'
extension introduced in CVS 1.9.26. The following new keywords are
defined when PreservePermissions=yes:
owner
group
permissions
special
symlink
hardlinks
The contents of the `owner' and `group' field should be a numeric uid
and a numeric gid, respectively, representing the user and group who
own the file. The `permissions' field contains an octal integer,
representing the permissions that should be applied to the file. The
`special' field contains two words; the first must be either `block'
or `character', and the second is the file's device number. The
`symlink' field should be present only in files which are symbolic
links to other files, and absent on all regular files. The
`hardlinks' field contains a list of filenames to which the current
file is linked, in alphabetical order. Because files often contain
characters special to RCS, like `.' and sometimes even contain spaces
or eight-bit characters, the filenames in the hardlinks field will
usually be enclosed in RCS strings. For example:
hardlinks README @install.txt@ @Installation Notes@;
The hardlinks field should always include the name of the current
file. That is, in the repository file README,v, any hardlinks fields
in the delta nodes should include `README'; CVS will not operate
properly if this is not done.
The rules regarding keyword expansion are not documented along with
the rest of the RCS file format; they are documented in the co(1)
manpage in the RCS 5.7 distribution. See also the "Keyword

File diff suppressed because it is too large Load Diff

View File

@ -320,6 +320,7 @@ General protocol conventions:
* Filenames:: Conventions regarding filenames
* File transmissions:: How file contents are transmitted
* Strings:: Strings in various requests and responses
* Dates:: Times and dates
The protocol itself:
@ -468,6 +469,32 @@ existing practice is probably to just transmit whatever the user
specifies, and hope that everyone involved agrees which character set is
in use, or sticks to a common subset.
@node Dates
@section Dates
The protocol contains times and dates in various places.
For the @samp{-D} option to the @code{annotate}, @code{co}, @code{diff},
@code{export}, @code{history}, @code{rdiff}, @code{rtag}, @code{tag},
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}
5/26/1997 13:01:40 GMT ; @r{traditional}
@end example
The former format is preferred; the latter however is sent by the CVS
command line client (versions 1.5 through at least 1.9).
For the @samp{-d} option to the @code{log} request, servers should at
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.
For @code{Notify}, see the description of that request.
@node Request intro
@section Request intro
@ -517,7 +544,7 @@ for the original directory, then the command.
The @var{local-directory} is relative to
the top level at which the command is occurring (i.e. the last
@code{Directory} which is sent before the command);
to indicate that top level, @samp{.} should be send for
to indicate that top level, @samp{.} should be sent for
@var{local-directory}.
Here is an example of where a client gets @var{repository} and
@ -892,7 +919,6 @@ directory.
@itemx tag \n
@itemx status \n
@itemx log \n
@itemx remove \n
@itemx admin \n
@itemx history \n
@itemx watchers \n
@ -1034,6 +1060,23 @@ directories, as described above), use @samp{.} for
@var{local-directory} may not get an error, but it will get you strange
@code{Checked-in} responses from the buggy servers.
@item remove \n
Response expected: yes. Remove a file. 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.
Note that this request does not actually do anything to the repository;
the only effect of a successful @code{remove} request is to supply the
client with a new entries line containing @samp{-} to indicate a removed
file. In fact, the client probably could perform this operation without
contacting the server, although using @code{remove} may cause the server
to perform a few more checks.
The client sends a subsequent @code{ci} request to actually record the
removal in the repository.
@item watch-on \n
@itemx watch-off \n
@itemx watch-add \n

View File

@ -1,3 +1,7 @@
Tue Mar 24 16:08:00 1998 Ian Lance Taylor <ian@cygnus.com>
* Makefile.in (CFLAGS): Set to @CFLAGS@, not -g.
1998-02-20 Jim Kingdon <kingdon@harvey.cyclic.com>
* regex.c: Partial merge with version from emacs 20.2. Brings

View File

@ -77,7 +77,7 @@ DEFS = @DEFS@
RANLIB = @RANLIB@
CC = @CC@
CFLAGS = -g
CFLAGS = @CFLAGS@
CPPFLAGS=
YACC = @YACC@

View File

@ -1,3 +1,8 @@
1998-06-28 Jim Kingdon <kingdon@harvey.cyclic.com>
* cvs.1: Update various items which were out of date. Mostly
these related to CVS no longer calling external RCS programs.
Mon Jan 12 11:10:21 1998 Jim Kingdon <kingdon@harvey.cyclic.com>
* cvs.1: Refer to Cederqvist as Cederqvist not as cvs.texinfo.

View File

@ -35,19 +35,15 @@ described in the SEE ALSO section of this manpage).
.IX "release control system" "cvs command" "" "\fLcvs\fP \- concurrent versions system"
.IX "source control system" "cvs command" "" "\fLcvs\fP \- concurrent versions system"
.IX revisions "cvs command" "" "\fLcvs\fP \- source control"
.B cvs
is a front end to the
.BR rcs ( 1 )
revision control system which extends
the notion of revision control from a collection of files in a single
directory to a hierarchical collection of directories consisting of
revision controlled files.
These directories and files can be combined together to form a software
release.
.B cvs
provides the functions necessary to manage these software releases and to
control the concurrent editing of source files among multiple software
developers.
CVS is a version control system, which allows you to keep old versions
of files (usually source code), keep a log of who, when, and why
changes occurred, etc., like RCS or SCCS. Unlike the simpler systems,
CVS does not just operate on one file at a time or one directory at a
time, but operates on hierarchical collections of directories
consisting of version controlled files. CVS helps to manage releases
and to control the concurrent editing of source files among multiple
authors. CVS allows triggers to enable/log/control various
operations and works well over a wide area network.
.SP
.B cvs
keeps a single copy of the master sources.
@ -175,7 +171,7 @@ Use
.I bindir
as the directory where
.SM RCS
programs are located.
programs are located (CVS 1.9 and older).
Overrides the setting of the
.SM RCSBIN
environment variable.
@ -185,7 +181,6 @@ This value should be specified as an absolute pathname.
Use
.I CVS_root_directory
as the root directory pathname of the master
.SM RCS
source repository.
Overrides the setting of the
.SM CVSROOT
@ -318,7 +313,6 @@ working directory.)
.TP
.B admin
Execute
.SM RCS
control functions on the source repository. (Changes
repository directly; uses working directory without changing it.)
.TP
@ -366,7 +360,6 @@ as a ``vendor branch''. (Changes repository.)
.TP
.B log
Display
.SM RCS
log information.
(Does not change repository or working directory.)
.TP
@ -435,11 +428,8 @@ even with these standard options.
\fB\-D\fP \fIdate_spec\fP
Use the most recent revision no later than \fIdate_spec\fP (a single
argument, date description specifying a date in the
past). A wide variety of date formats are supported by the underlying
.SM RCS
facilities, similar to those described in
.BR co ( 1 ),
but not exactly the same.
past). A wide variety of date formats are supported, in particular
ISO ("1972-09-24 20:05") or Internet ("24 Sep 1972 20:05").
The \fIdate_spec\fP is interpreted as being in the local timezone, unless a
specific timezone is specified.
The specification is ``sticky'' when you use it to make a
@ -492,12 +482,8 @@ commands.
.TP
\fB\-k\fP \fIkflag\fP
Alter the default
.SM RCS
processing of keywords; all the
.B \-k
options described in
.BR co ( 1 )
are available. The \fB\-k\fP option is available with the
processing of keywords.
The \fB\-k\fP option is available with the
.BR add ", " checkout ", " diff ", " export ", "
.BR rdiff ", and " update
commands. Your \fIkflag\fP specification is ``sticky'' when you use
@ -507,10 +493,8 @@ this option with the \fBcheckout\fP or \fBupdate\fP commands,
continues to use it with future \fBupdate\fP commands on the same file
until you specify otherwise.
.SP
Some of the more useful \fIkflag\fPs are \-ko and \-kb (for binary files,
only compatible with
.SM RCS
version 5.7 or later), and \-kv which is useful for an
Some of the more useful \fIkflag\fPs are \-ko and \-kb (for binary files),
and \-kv which is useful for an
.B export
where you wish to retain keyword information after an
.B import
@ -600,9 +584,7 @@ make your own copy of a file: \fBcvs\fP remembers the \fItag\fP and
continues to use it on future \fBupdate\fP commands, until you specify
otherwise.
.I tag
can be either a symbolic or numeric tag, in
.SM RCS
fashion.
can be either a symbolic or numeric tag.
Specifying the
.B \-q
global option along with the
@ -659,7 +641,6 @@ working directory.
Use the
.B add
command to create a new file or directory in the
.SM RCS
source repository.
The files or directories specified with
.B add
@ -676,7 +657,6 @@ If the argument to
.` "cvs add"
refers to an immediate sub-directory, the directory is
created at the correct place in the
.SM RCS
source repository, and the necessary
.B cvs
administration files are created in your working directory.
@ -719,7 +699,6 @@ or
.` "cvs update -d".)
.SP
The added files are not placed in the
.SM RCS
source repository until you use
.` "cvs commit"
to make the change permanent.
@ -757,9 +736,8 @@ file and can be changed with
Specifying
.` "-ko"
is useful for checking in binaries that
shouldn't have the
.SM RCS
id strings expanded.
shouldn't have
keywords expanded.
.TP
\fBadmin\fP [\fIrcs-options\fP] \fIfiles.\|.\|.\fP
.I Requires:
@ -774,14 +752,9 @@ repository.
This is the
.B cvs
interface to assorted administrative
.SM RCS
facilities, documented in
facilities, similar to
.BR rcs ( 1 ).
.` "cvs admin"
simply passes all its options and arguments to the
.B rcs
command; it does no filtering or other processing.
This command does work recursively, however, so extreme care should be
This command works recursively, so extreme care should be
used.
.TP
\fBcheckout\fP [\fBoptions\fP] \fImodules\fP.\|.\|.
@ -820,7 +793,6 @@ You can then edit these source files at any time (regardless of whether
other software developers are editing their own copies of the sources);
update them to include new changes applied by others to the source
repository; or commit your work as a permanent change to the
.SM RCS
repository.
.SP
Note that
@ -987,7 +959,6 @@ the time is right.
.SP
When all is well, an editor is invoked to allow you to enter a log
message that will be written to one or more logging programs and placed in the
.SM RCS
source repository file.
You can instead specify the log message on the command line with the
.B \-m
@ -997,12 +968,8 @@ option to specify that the argument \fIfile\fP contains the log message.
.SP
The
.B \-r
option can be used to commit to a particular symbolic or numeric revision
within the
.SM RCS
file.
option can be used to commit to a particular symbolic or numeric revision.
For example, to bring all your files up to the
.SM RCS
revision ``3.0'' (including those that haven't changed), you might do:
.SP
.in +1i
@ -1154,7 +1121,6 @@ option is useful when
.B export
is used.
This causes any
.SM RCS
keywords to be expanded such that an
.B import
done at some other site will not lose the keyword revision information.
@ -1330,7 +1296,6 @@ For an up to date list of ignored file names, see the Cederqvist manual (as
described in the SEE ALSO section of this manpage).
.SP
The outside source is saved in a first-level
.SM RCS
branch, by default
.` "1.1.1".
Updates are leaves of this
@ -1390,13 +1355,7 @@ nothing.
.B rlog
.br
Display log information for \fIfiles\fP.
.` "cvs log"
calls
the
.SM RCS
utility \fBrlog\fP; all the options described in
.BR rlog ( 1 )
are available. Among the more useful \fBrlog\fP options are \fB\-h\fP
Among the more useful options are \fB\-h\fP
to display only the header (including tag definitions, but omitting
most of the full log); \fB\-r\fP to select logs on particular
revisions or ranges of revisions; and \fB\-d\fP to select particular
@ -1444,14 +1403,6 @@ command when patching the old sources, so that
.B patch
is able to find the files that are located in other directories.
.SP
If you use the option \fB\-V\fP \fIvn\fP,
.SM RCS
keywords are expanded according to the rules current in
.SM RCS
version \fIvn\fP (the expansion format changed with
.SM RCS
version 5).
.SP
The standard option \fIflags\fP \fB\-f\fP, and \fB\-l\fP
are available with this command. There are also several
special options flags:
@ -1769,7 +1720,6 @@ recent versions available in the repository.
\fBA\fP \fIfile\fP
The file has been \fIadded\fP to your private copy of the sources, and
will be added to the
.SM RCS
source repository when you run
.` "cvs commit"
on the file.
@ -1778,7 +1728,6 @@ This is a reminder to you that the file needs to be committed.
\fBR\fP \fIfile\fP
The file has been \fIremoved\fP from your private copy of the sources, and
will be removed from the
.SM RCS
source repository when you run
.` "cvs commit"
on the file.
@ -1797,14 +1746,12 @@ directory.
\fBC\fP \fIfile\fP
A \fIconflict\fP was detected while trying to merge your changes to
\fIfile\fP with changes from the source repository. \fIfile\fP (the
copy in your working directory) is now the output of the
.BR rcsmerge ( 1 )
command on the two versions; an unmodified copy of your file is also
copy in your working directory) is now the result of merging
the two versions; an unmodified copy of your file is also
in your working directory, with the name `\fB.#\fP\fIfile\fP\fB.\fP\fIversion\fP',
where
.I version
is the
.SM RCS
revision that your modified file started from.
(Note that some systems automatically purge files that begin with
\&
@ -2037,7 +1984,6 @@ Directory for removed source files.
A lock directory created by
.B cvs
when doing sensitive changes to the
.SM RCS
source repository.
.TP
#cvs.tfl.\fIpid\fP
@ -2082,9 +2028,8 @@ Specifies the full pathname where to find
programs, such as
.BR co ( 1 )
and
.BR ci ( 1 ).
If not set, a compiled-in value is used; see the display from
.` "cvs \-v".
.BR ci ( 1 )
(CVS 1.9 and older).
.TP
.SM CVSEDITOR
Specifies the program to use for recording log messages during
@ -2150,6 +2095,8 @@ module and vendor branch support and author of the
.BR checkin ( 1 )
shell script (the ancestor of
.` "cvs import").
.TP
And many others too numerous to mention here.
.SH "SEE ALSO"
The most comprehensive manual for CVS is
Version Management with CVS by Per Cederqvist et al. Depending on

View File

@ -1,5 +1,709 @@
Thu Aug 13 11:15:24 1998 Noel Cragg <noel@swish.red-bean.com>
* version.c: Change version number to 1.10 and name to `Halibut'.
* sanity.sh (rcslib): new tests to check behavior of symlinks in
the repository.
Wed Aug 12 15:39:38 1998 Noel Cragg <noel@swish.red-bean.com>
* main.c (lookup_command_attribute): the `annotate' command
shouldn't require access to the repository. Add comment about
commands that do not use the working directory.
Mon Aug 10 10:26:38 1998 Noel Cragg <noel@swish.red-bean.com>
* version.c: Change version number to 1.9.30.
Thu Aug 6 17:44:50 1998 Noel Cragg <noel@swish.red-bean.com>
* server.c (serve_rdiff): change the name of the command (for
error reporting, etc.) from "patch" to "rdiff."
(serve_remove): rename from "cvsremove" to "remove."
* main.c (lookup_command_attribute): the `rdiff' command shouldn't
require write access to the repository.
1998-08-06 David Masterson of kla-tencor.com
and Jim Kingdon
* commit.c (commit_filesdoneproc): Don't call strlen ("CVSROOT")
from within the assert statement. Apparently HP's cc compiler on
HPUX 10.20 has trouble with that.
1998-08-06 Jim Kingdon <kingdon@harvey.cyclic.com>
* rcs.c (RCS_checkin): When adding branch, if there is a lock on
the branchpoint owned by someone else, leave it alone. This
restores CVS 1.9 (RCS 5.7) behavior, fixing a core dump.
* sanity.sh (reserved): New tests reserved-16 through reserved-19
test for this fix.
1998-08-05 Jim Kingdon <kingdon@harvey.cyclic.com>
* sanity.sh (unedit-without-baserev): Use ${QUESTION} not "?".
This makes it work with GNU expr 1.12 as well as 1.16.
Sun Aug 2 20:27:44 1998 Noel Cragg <noel@swish.red-bean.com>
* mkmodules.c: add comment about TopLevelAdmin for the initial
contents of CVSROOT/config.
1998-07-29 Jim Kingdon <kingdon@harvey.cyclic.com>
* rcs.c (RCS_checkin): Only try to call xreadlink if HAVE_READLINK
is defined.
Tue Jul 28 19:33:08 1998 Noel Cragg <noel@swish.red-bean.com>
* version.c: Change version number to 1.9.29.
* rcs.c (RCS_checkin): add code to follow symbolic links in the
repository.
Sun Jul 26 05:14:41 1998 Noel Cragg <noel@swish.red-bean.com>
* This set of changes reverts the code to pre-1.9.2 behavior and
does not create CVS directories at top-level (except for the
obvious "cvs co ."). Added a new configuration option to switch
between 1.9 and 1.9.2 behavior.
* recurse.c (do_argument_proc): new function.
(start_recursion): in the case that we've done a command from
top-level but have no CVS directory there, the behavior should be
the same as "cvs <cmd> dir1 dir2 dir3...". Make sure that the
appropriate "Argument" commands are sent to the server by calling
walklist with do_argument_proc.
* client.c (call_in_directory): only create the top-level CVS
directory when we're checking out "." explicitly. The server will
force creation of this directory in all other cases.
* checkout.c (checkout_proc): only generate the top-level
directory when the TopLevelAdmin=yes. Also send a message to the
client to do the same.
* parseinfo.c (parse_config): handle TopLevelAdmin option. Set
top_level_admin.
* main.c: add new variable top_level_admin.
* cvs.h: add extern definition for above.
* sanity.sh: since we're reverting to pre 1.9.2 behavior for
top-level CVS directories, I needed to make changes to a bunch of
tests that made assumptions about said directories.
(preamble): make sure to add read and execute access to everything
in TMPDIR before removing, since some tests make things read-only.
(basicb-1a, basicb-1b, basicb-9a, basicb-9b): use dotest_fail
because these tests check for the non-existant top-level CVS
directory.
(basicc-3, emptydir-6, emptydir-7, crerepos-6): use "rm -rf" so it
won't complain when trying to remove the non-existant top-level
CVS directory.
(106.5): remove imported-f2-orig.tmp.
(modules2-10, emptydir-4, abspath-1ba, abspath-1bb): cd into the
directory where files exist before using the "add" command so cvs
can find CVSROOT in CVS/Root.
(cvsadm-2): look at a different CVS/Repository file, since the
top-level one doesn't exist.
(taginfo-3): create the directory in the repository directly
rather than relying on the fact that the top-level CVS directory
was created in a previous test.
(serverpatch-6): update first-dir explicity, rather than relying
on the non-existant top-level CVS/Entries file.
(crerepos-18): look at CVS/Repository in a subdirectory rather
than in the non-existant top-level CVS directory.
(toplevel): add code to set TopLevelAdmin=yes.
(toplevel2): new tests -- same as toplevel, but TopLevelAdmin=no.
1998-07-21 Jim Meyering <meyering@ascend.com>
* rcs.c (RCS_checkout): Hoist frees of rev and value.
Warn and return 1 in several cases rather than exiting via
`error (1, ...'. The latter could abort a multi-file commit
in mid-stream, leaving stale locks in the repository.
1998-07-16 Jim Kingdon <kingdon@harvey.cyclic.com>
* build_src.com (rcscmds.c): Also look for include files in
[-.diff], just like Ian's 1998-06-18 change to Makefile.in
1998-07-14 Jim Kingdon <kingdon@harvey.cyclic.com>
* tag.c (pretag_proc), rtag.c (pretag_proc): Don't pass RUN_REALLY
to run_exec. This means that taginfo does not get executed if the
global -n option is specified. Which makes it like loginfo, -i,
-e, -o, -t, -u in modules, editinfo, and verifymsg and unlike
commitinfo. The old behavior was pretty bad in the sense that it
doesn't provide any way to log only the tags which actually
happen.
* sanity.sh (taginfo): New tests taginfo-11 to taginfo-13, for this.
1998-07-12 Jim Kingdon <kingdon@harvey.cyclic.com>
* sanity.sh (ann-id): Write the test so that it tests for the
current (buggy) behavior.
* sanity.sh (taginfo): Also clean up cvsroot/first-dir.
1998-07-12 Jim Meyering <meyering@ascend.com>
* sanity.sh (ann-id): New (currently failing) test for bug in how
rcs keywords are expanded in the output of `cvs annotate'.
1998-07-12 Jim Kingdon <kingdon@harvey.cyclic.com>
* sanity.sh (taginfo): Write the TESTDIR into the script rather
than having the script look at the environment. This means that
it will work if TESTDIR is set by sanity.sh as well as if
sanity.sh finds TESTDIR in the environment.
1998-07-11 Jim Kingdon <kingdon@harvey.cyclic.com>
* tag.c (check_fileproc): Calculate the revision to be tagged the
same way that tag_fileproc does.
* sanity.sh (taginfo): New tests, test for this (before this fix,
brtag had said 1.1 not 1.1.2.1).
1998-07-10 Jim Kingdon <kingdon@harvey.cyclic.com>
* sanity.sh (unedit-without-baserev): Also clean up "2" directory.
1998-07-08 Jim Kingdon <kingdon@harvey.cyclic.com>
* edit.c (unedit_fileproc): If the Baserev file is missing, don't
get the working file from CVS/Base. The previous code could get
you version 1.1 of the working file and put 1.2 in CVS/Entries.
* sanity.sh (unedit-without-baserev): New tests test for this.
1998-07-02 Jim Kingdon <kingdon@harvey.cyclic.com>
* sanity.sh (unedit-without-baserev): Move the test itself to be
in the same order as in the "tests" variable.
1998-07-02 Ian Lance Taylor <ian@cygnus.com>
* rcscmds.c: Don't include <stdarg.h> or <vasprintf.h>. Don't
declare vasprintf.
(call_diff_printf_output): Remove.
(call_diff_stdout_callbacks): Don't initialize printf_output
field--it has been removed from the interface.
(call_diff_file_callbacks): Likewise.
1998-07-01 Jim Meyering <meyering@ascend.com>
* edit.c (unedit_fileproc): Handle the case in which base_get
returns a NULL baserev. That happens when a file being `unedit'ed
exists in the CVS/Base directory, but isn't listed in the CVS/Baserev
file. The one case I've seen had no Baserev file at all. The symptom
(if you're lucky) is a segmentation fault upon unedit. If you use
SunOS4.1.4 for which printf prints NULL pointers as `(null)', your
unedit command will complete normally, but it will have corrupted
your CVS/Entries file and a subsequent update may result in an
assertion failure, a core dump, and a stale lock in the repository.
* sanity.sh (unedit-without-baserev): New test for this.
1998-07-01 Andy Mortimer of aeat.co.uk
and Jim Kingdon <kingdon@harvey.cyclic.com>
* server.c (server_updated): Use a prototype if we are using them
for declarations.
1998-06-29 Jim Kingdon <kingdon@harvey.cyclic.com>
* sanity.sh (commit-readonly): Protect keyword against expansion
in sanity.sh itself. Keep the keyword in the file which we check
in (or else this fails to test for the RCS_checkout change).
1998-06-27 Jim Meyering <meyering@ascend.com>
* rcs.c (RCS_checkout): If opening the local workfile fails due to
lack of write access, try to chmod the file and retry the open.
Before, a commit could fail part way through merely because the
open to rewrite with newly expanded rcs keywords would fail. It's
easy to make this happen if you use `cvs -r' or CVSREAD and you
apply a patch to one of your read-only source files -- patch
preserves the read-only setting for the file and your next commit
will fail after committing that file, but before rewriting
(checking out) your working copy.
* sanity.sh (commit-readonly): New test for this.
1998-06-25 Jim Kingdon <kingdon@harvey.cyclic.com>
* update.c (patch_file): Update comments regarding context diffs
to reflect diff library.
1998-06-23 Jim Kingdon <kingdon@harvey.cyclic.com>
* sanity.sh (modules4): Add tests for reversing the order of the
"!first-dir/sdir" and "first-dir".
1998-06-23 Jim Kingdon <kingdon@harvey.cyclic.com>
and Dave Wolfe@Motorola.
* sanity.sh (modes2): Touch the file before chmod'ing it.
1998-06-21 Ian Lance Taylor <ian@cygnus.com>
* update.c (merge_files): Revert changes of 1998-06-19. Instead,
register a merged file with a dummy time stamp. Only set
last_register_time if we need to.
(join_file): Likewise. Always register a merged file, not just
when the merge fails.
1998-06-21 Jim Kingdon <kingdon@harvey.cyclic.com>
* call_diff_write_output, call_diff_printf_output,
call_diff_flush_output, call_diff_write_stdout, call_diff_error,
call_diff_stdout_callbacks, call_diff_file_callbacks): Re-indent.
1998-06-19 Ian Lance Taylor <ian@cygnus.com>
* update.c (merge_file): Make sure the time stamp of the file is
different from the time stamp we register in the Entries file.
(join_file): Likewise.
1998-06-18 Ian Lance Taylor <ian@cygnus.com>
* rcscmds.c: Include <stdio.h>. Include either <stdarg.h> or
<varargs.h>. Declare vasprintf.
(call_diff_write_output): New static function.
(call_diff_printf_output): New static function.
(call_diff_flush_output): New static function.
(call_diff_write_stdout): New static function.
(call_diff_error): New static function.
(call_diff_stdout_callbacks): New static variable.
(call_diff_file_callbacks): New static variable.
(call_diff): Don't sleep. Use a callback structure when calling
the diff library.
(call_diff3): Likewise.
* rcscmds.c: Include diffrun.h.
(call_diff, call_diff3): Pass NULL callback parameter.
(diff_run, diff3_run): Don't declare.
* Makefile.in (rcscmds.o): New target, to use -I for diff
directory.
(zlib.o): Depend upon zlib.h.
1998-06-09 Mike Sutton@SAIC
Make it compile with Sun's bundled K&R C compiler:
* rcs.c (count_delta_actions): Change to static to match
declaration.
* client.c (handle_wrapper_rcs_option): Rename error label to
handle_error to avoid clash with function name.
1998-06-09 Jim Kingdon <kingdon@harvey.cyclic.com>
* rcs.c (RCS_delete_revs): If we are trying to delete all
revisions, give an error rather than assertion failed.
* sanity.sh (basicb): New tests basicb-o* test for this.
1998-06-04 Jim Kingdon <kingdon@harvey.cyclic.com>
* add.c (add): Only send "Directory" requests if we need to.
1998-06-02 Assar Westerlund <assar@sics.se>
* client.c: Check for HAVE_GSS_C_NT_HOSTBASED_SERVICE rather than
assuming that GSS_C_NT_HOSTBASED_SERVICE is a macro.
* server.c: Likewise.
1998-06-02 Jim Kingdon <kingdon@harvey.cyclic.com>
* fileattr.c (fileattr_read): Check for NULL return from strchr.
* sanity.sh (devcom3): New test devcom3-10 checks for this.
1998-06-01 Assar Westerlund <assar@sics.se>
and Ian Lance Taylor <ian@cygnus.com>
* client.c: If HAVE_GSSAPI_H, include <gssapi.h>. Only include
<gssapi/gssapi.h> if HAVE_GSSAPI_GSSAPI_H. Only include
<gssapi/gssapi_generic.h> if HAVE_GSSAPI_GSSAPI_GENERIC_H.
(GSS_C_NT_HOSTBASED_SERVICE): Define if not defined.
(connect_to_gserver): Use GSS_C_NT_HOSTBASED_SERVICE instead of
gss_nt_service_name.
* server.c: Same header file changes.
(GSS_C_NT_HOSTBASED_SERVICE): Define if not defined.
(gserver_authenticate_connection): Use GSS_C_NT_HOSTBASED_SERVICE
instead of gss_nt_service_name.
1998-06-01 Jim Meyering <meyering@ascend.com>
* sanity.sh (tag8k): Add a test for the 1998-05-02 rcs.c bug fix.
1998-05-26 Jim Kingdon <kingdon@harvey.cyclic.com>
* rcs.c (annotate): Call tag_check_valid like the other functions
which have a -r option.
* sanity.sh (ann): New test ann-14 tests for this.
1998-05-24 Jim Kingdon <kingdon@harvey.cyclic.com>
* sanity.sh (importc): New tests importc-5 through importc-8 test
for a (fairly obscure) regression from CVS 1.9.
1998-05-23 Jim Kingdon <kingdon@harvey.cyclic.com>
* sanity.sh (modules2): Add comment listing cvs release tests.
(info): New test info-cleanup-0 tests "cvs -n release".
* rcs.c (rcsbuf_getid): Remove semicolon at end of #undef. I'm
kind of surprised that compilers accepted this at all, but
removing it squelches a warning for some compilers.
* version.c: Change version number to 1.9.28.1.
* Version 1.9.28.
1998-05-22 Jim Kingdon <kingdon@harvey.cyclic.com>
* rcs.c (RCS_cmp_file): Check for errors from CVS_FOPEN. This
restores the CVS 1.9 behavior (fatal error if we can't open the
file), and corrects an apparent oversight in Ian's 13 Apr 1997
change.
* sanity.sh (modes2): New test, tests for this.
1998-05-22 Ian Lance Taylor <ian@cygnus.com>
* server.c (server_updated): Correct test for whether to unlink
the file.
1998-05-20 Jim Kingdon <kingdon@harvey.cyclic.com>
* wrapper.c (wrap_add): Disable -t/-f wrappers at least until the
serious bug can be fixed.
1998-05-15 Jim Kingdon <kingdon@harvey.cyclic.com>
* checkout.c (checkout): Call server_pathname_check on the
argument to "cvs co -d".
* server.c (server_pathname_check): Add comment about how we could
be handling absolute pathnames.
* sanity.sh (abspath): Rewrite the tests which run "cvs co -d /foo"
for remote, to reflect this.
* sanity.sh (abspath): Also do the "cannot rename" work-around for
abspath-7d.
1998-05-13 Jim Kingdon <kingdon@harvey.cyclic.com>
* commit.c (commit_filesdoneproc): Free admin_dir when done with it.
1998-05-13 Jim Meyering <meyering@ascend.com>
* sanity.sh (editor): Change bogus sed command, `s/^/x&/g', to `s/^/x/'.
The former exercised a bug in GNU sed-3.01-beta3.
(emptydir-8): Add `Rebuilding administrative file database' message,
since now it does that.
* commit.c (commit_filesdoneproc): Pass only the admin directory
pathname to mkmodules.
Remove #if 0, now that it's fixed.
* status.c (cvsstatus): Rename from `status' to avoid shadowing
lots of locals and parameters by the same name.
* server.c (serve_status): Update caller.
* main.c (cmds[]): Update table entry.
* cvs.h: Update prototype.
* commit.c (commit_filesdoneproc): Remove trailing blanks.
(commit) [CLIENT_SUPPORT]: Remove unnecessary (and local-shadowing)
declaration of `err'.
Rename global `tag' to `saved_tag' to avoid overshadowing `tag'
parameters of three functions.
Rename global `message' to `saved_message' to avoid overshadowing
`message' parameter of a function.
Rename global `ulist' to `saved_ulist' and move dcl up with others.
1998-05-12 Jim Kingdon <kingdon@harvey.cyclic.com>
* commit.c (commit_filesdoneproc): #if 0 the new code until it can
be fixed.
* commit.c (commit_filesdoneproc): Add comment explaining last
change.
1998-05-12 Jim Meyering <meyering@ascend.com>
* commit.c (commit_filesdoneproc): Call mkmodules not just when
committing a file directly under CVSROOT, but also when committing
files in subdirectories of CVSROOT.
1998-05-08 Jim Meyering <meyering@ascend.com>
* filesubr.c (xreadlink): NUL-terminate the symbolic link name.
Use a much smaller initial buffer length.
Test errno only if readlink fails.
Use xstrdup then free the original link name so we don't waste space.
1998-05-02 Jim Meyering <meyering@ascend.com>
* rcs.c (rcsbuf_getword): Fix off-by-one error that would result in
an abort (the first one in rcsbuf_getkey) when operating on on some
,v files with over 8192 bytes of tag and branch info.
1998-05-04 Jim Kingdon <kingdon@harvey.cyclic.com>
* sanity.sh (ann): New tests ann-12 and ann-13 test for specifying
a numeric branch.
1998-05-02 Jim Kingdon <kingdon@harvey.cyclic.com>
* rcs.c: Add comments about getting rid of rcsbuf_getid,
rcsbuf_getword, and rcsbuf_getstring.
* sanity.sh (abspath): Revise the workarounds to deal with exit
status.
1998-04-30 Jim Kingdon <kingdon@harvey.cyclic.com>
* sanity.sh (abspath): Work around the "cannot rename" bug.
1998-04-27 Jim Kingdon <kingdon@harvey.cyclic.com>
* classify.c (Classify_File): Add comments about checking whether
command name is "update".
1998-04-22 Jim Kingdon <kingdon@harvey.cyclic.com>
* version.c: Change version number to 1.9.27.1.
* Version 1.9.27.
1998-04-20 Jim Kingdon <kingdon@harvey.cyclic.com>
(This diff was run by devel-cvs and everyone seemed to like it).
* diff.c (diff_file_nodiff): Make HEAD mean the head of the branch
which contains the sticky tag, not the sticky tag itself.
* rcs.c, rcs.h (RCS_branch_head): New function.
* sanity.sh (head): Update for this changed behavior.
1998-04-19 Jim Kingdon <kingdon@harvey.cyclic.com>
* sanity.sh: Move emptydir tests from basicb to new test emptydir.
This is because we now need a module definition to create Emptydir;
"co -d" doesn't cut it anymore.
1998-04-17 Petri Virkkula
* server.c (mkdir_p): Ignore EROFS error (like for EACCES).
1998-04-16 Jim Kingdon <kingdon@harvey.cyclic.com>
* checkout.c (checkout_proc): Don't create directories above the
last one specified in "co -d".
(build_dirs_and_chdir): Revert Noel's change of 17 Feb 1998.
(struct dir_to_build): New field just_chdir.
(build_dirs_and_chdir): Test it.
* sanity.sh (abspath): New tests abspath-7* test for a bug which
we fix, in which CVS would create bogus "D/////" entries in
CVS/Entries.
(abspath): Revise abspath-3* tests to test for the fact that we no
longer create directories above the last one specified in "co -d".
I checked that CVS 1.9 gives an error on this, so changing this
behavior back should be OK.
(cvsadm-2d3): Likewise (also checked CVS 1.9 for this case).
(cvsadm-2d3d): Likewise (also checked CVS 1.9 for this case).
(cvsadm-2d{4,5,6,7,8}, cvsadm-N2d{3,4,5,6,7,8}): Adjust for new
behavior (same case as cvsadm-2d3).
(cvsadm-2d{4,5,6,7,8}d, cvsadm-N2d{3,4,5,6,7,8}d): Remove test
(same case as cvsadm-2d3d).
(cvsadm): For remote, skip most these tests.
(abspath): When cleaning up, delete mod1 and mod2 rather than mod1
twice (longstanding bug, apparently only becomes visible if you
run the tests in a certain order).
1998-04-14 Wilfredo Sanchez <wsanchez@apple.com>
* rcs.c: variable "lockfile" was being referenced after being
free'd. Bad. Moved the free() call down.
1998-04-12 Jim Kingdon <kingdon@harvey.cyclic.com>
* sanity.sh (rcs): Add test for annotate and the year 2000.
* server.c (do_cvs_command): If there are partial lines left when
the child process is done, send them along.
* sanity.sh (rcs, rcs2): Enable all tests for remote; tests for
this fix.
1998-04-11 Jim Kingdon <kingdon@harvey.cyclic.com>
* client.c (client_senddate): Pass SDATEFORM not DATEFORM to
sscanf. This fixes a Y2K bug.
* history.c (history, select_hrec): Change since_date from time_t
to RCS format. Use the usual machinery (in particular, Make_Date
and client_senddate) so that it will work on VMS too.
* main.c, cvs.h (date_from_time_t): New function.
* sanity.sh (history): New test, to test that this didn't break
anything (also tests client_senddate fix).
1998-04-11 Norbert Kiesel <nk@iname.com>
* server.c (cvs_output_binary): Shut up "gcc -Wall" by removing
unnecessary else if test.
* server.c (check_password): Fix uninitialized memory read if
shadow passwords are used. Also added some comments.
* rcs.c (RCS_checkout): Make sure to call chown with -1 for uid or
gid if they should not be changed
1998-04-10 Jim Kingdon <kingdon@harvey.cyclic.com>
* sanity.sh (rcs2): New test, tests for various Y2K cases.
* rcs.c (getdelta): Value for "state" keyword is optional (bug
discovered incidentally in writing rcs2 test).
1998-04-09 Jim Kingdon <kingdon@harvey.cyclic.com>
* filesubr.c, cvs.h (link_file): Remove; no longer used.
1998-04-08 Jim Kingdon <kingdon@harvey.cyclic.com>
* recurse.c (do_dir_proc): Restore update_dir rather than a
computation which appears to, but does not necessarily, restore it
(reported by various people; this fix is from Greg Hudson).
* sanity.sh (importc): New test, tests for this fix.
1998-03-27 Jim Kingdon <kingdon@harvey.cyclic.com>
* rcs.c (RCS_lock): If the revision is already locked, give an
error rather than dumping core.
* sanity.sh (reserved): New test reserved-13c tests for this.
1998-03-25 Loren J. Rittle
* import.c (add_rev): Rewrite to use RCS_FLAGS_KEEPFILE option
of RCS_checkin() to avoid damage to imported files instead of
externally undoing damage after the fact. The side effect is
that callers of add_rev() may now incrementally walk the
entries of the current directory without seeing gratuitous
changes to the directory structure (under at least one file
system under at least one OS).
1998-03-18 Jim Kingdon <kingdon@harvey.cyclic.com>
* error.c (error): Save and restore errno. Should fix test case
conflicts3-23 on SCO 5.0.2. Reported by Steve Cameron.
* sanity.sh (admin): Rename admin-26-o* to admin-26-*; the "o"
stands for "cvs admin -o". Add comment about length of tests.
Use ${PLUS}.
1998-03-05 Dan Wilder <dan@gasboy.com>
* Fix problem with cvs admin in which -ntag:branch
option associated tag with the branch's head revision.
Should have used branch number. Entailed in this fix,
the following.
* Add new functions "RCS_exist_rev", "RCS_exist_tag",
"RCS_tag2rev", and "RCS_valid_rev" to rcs.c. RCS_tag2rev
is similar to RCS_gettag, but does less interpretation.
* Plug a small memory leak.
* Add tests admin-26 through admin-29 to sanity.sh,
to test "cvs admin -n".
1998-03-17 Samuel Tardieu <sam@inf.enst.fr>
* server.c (server_register): protect dereferencing timestamp in
the trace message when it is null, to avoid a segmentation fault.
1998-03-16 Jim Kingdon <kingdon@harvey.cyclic.com>
* options.h.in (MY_NDBM): Rewrite the comment explaining this
option. It was not clear to everyone who "my" referred to, for
example.
* hardlink.c (list_linked_files_on_disk): Remove unused variables
err and p.
(list_linked_files_on_disk): Add comment about memory allocation
of return value.
* rcs.c (rcsbuf_getword): Shut up gcc -Wall with a "return 0".
(RCS_checkin): Remove unused variable fullpath.
* sanity.sh (hardlinks): Remove comment about spurious warnings;
the warnings are gone.
1998-03-12 Tim Pierce <twp@skepsis.com>
New functions for parsing and writing hardlink fields.
* rcs.c [PRESERVE_PERMISSIONS_SUPPORT] (puthardlink_proc): New
function.
(putdelta) [PRESERVE_PERMISSIONS_SUPPORT]: Use it.
(rcsbuf_getid, rcsbuf_getstring, rcsbuf_getword): New functions.
(getdelta): Call them, storing `hardlinks' field in vnode->hardlinks.
(RCS_reparsercsfile): When setting rdata->desc, xstrdup value
rather than rcsbuf_valcopying it (due to changes in how getdelta
handles keys and values in newphrases).
* sanity.sh (hardlinks): Use uglier filenames. Checking out
hardlinked files no longer produces the same spurious diagnostics,
so fix that test.
(hardlinks-2.3): Renamed from hardlinks-2.2 (duplicate test name).
New infrastructure for managing hardlink lists internally...
* hardlink.c, hardlink.h (list_linked_files_on_disk,
compare_linkage_lists, find_checkedout_proc): New functions.
* rcs.h (struct rcsversnode) [PRESERVE_PERMISSIONS_SUPPORT]: New
member `hardlinks'.
* update.c (special_file_mismatch): Get hardlinks from
vp->hardlinks instead of from vp->other_delta.
* rcs.c (free_rcsvers_contents): Comment about freeing hardlinks
member.
(RCS_checkout) [PRESERVE_PERMISSIONS_SUPPORT]: Get hardlinks from
vers->hardlinks list instead of vers->other_delta.
... and removed obsolete code from earlier revs.
* hardlink.c, hardlink.h (list_files_linked_to,
cache_hardlinks_proc, list_files_proc, set_hardlink_field_proc):
Removed.
* hardlink.h: Removed `links' member from hardlink_info struct.
* commit.c (commit): Remove the call to cache_hardlinks_proc.
(check_fileproc) [PRESERVE_PERMISSIONS_SUPPORT]: Removed reference
to hlinfo->links.
* hardlink.c (update_hardlink_info): Same.
* update.c (get_linkinfo_proc): Same.
* rcs.c (RCS_checkout) [PRESERVE_PERMISSIONS_SUPPORT]: Use
vp->hardlinks and find_checkedout_proc to find recently-updated
files that may be hardlinked.
* update.c (special_file_mismatch): Use List * structures and
compare_linkage_lists for rev1_hardlinks and rev2_hardlinks.
1998-03-16 Larry Jones <larry.jones@sdrc.com>
* server.c (check_password): If shadow passwords are supported but no
entry is found in the shadow file, check the regular password file.
1998-03-07 Jim Kingdon <kingdon@harvey.cyclic.com>
* sanity.sh: Rename permissions test to perms since that is what
each of its individual tests are named.
* sanity.sh (perms symlinks hardlinks): Change CVSROOT to
CVSROOT_DIRNAME where appropriate.
(perms symlinks hardlinks): Disable/adjust the meat of the tests for
remote.
(symlinks): Link to ${TESTDIR}/fumble rather than
/fumble/mumble/grumble. We shouldn't be making assumptions about
what might exist in random directories outside ${TESTDIR}.
* hardlink.c (cache_hardlinks_proc): Add comment about trimming
whitespace.
1998-03-07 Tim Pierce <twp@skepsis.com>
* rcs.c (RCS_checkout): Negation bug when checking out symlinks:
existence_error should be !existence_error.
* sanity.sh (permissions symlinks hardlinks): New tests, for
PreservePermissions.
1998-03-04 Jim Kingdon <kingdon@harvey.cyclic.com>
* version.c: Change version number to 1.9.26.1.
* Version 1.9.26.
* entries.c, cvs.h (Entries_Open): New argument update_dir; use it
in error message.
* add.c, checkout.c, client.c, find_names.c, import.c, recurse.c,
@ -30,7 +734,7 @@
* update.c (special_file_mismatch): Compare the hard links of the
two revisions.
* rcs.c (RCS_checkout):
* rcs.c (RCS_checkout):
* hardlink.c, hardlink.h: New files.
(hardlink_info): New struct.
@ -235,7 +939,7 @@ Tue Feb 17 02:32:21 1998 Noel Cragg <noel@swish.red-bean.com>
[These mods make "checkout" work with "-d /absolute/pathname"
once again.]
* checkout.c (checkout_proc): the -d flag on the command line
should override the -d flag in the modules file if the latter is
an absolute path. The loop that assembles the list of directories
@ -255,7 +959,7 @@ Tue Feb 17 02:32:21 1998 Noel Cragg <noel@swish.red-bean.com>
* create_adm.c (Create_Admin): include the directory in the error
message.
1998-02-16 Jim Kingdon <kingdon@harvey.cyclic.com>
* diff.c (diff_fileproc), import.c (import, add_rcs_file), rcs.c
@ -294,7 +998,7 @@ Tue Feb 17 02:32:21 1998 Noel Cragg <noel@swish.red-bean.com>
Support for device special files, symbolic links, user and group
ownerships, and file permissions.
* parseinfo.c: (parse_config): Handle new config variable
`PreservePermissions'.
* mkmodules.c (config_contents): Add new PreservePermissions var.

View File

@ -177,7 +177,10 @@ cvsbug: cvsbug.sh $(srcdir)/version.c
$(OBJECTS): $(HEADERS) options.h
zlib.o: zlib.c
rcscmds.o: rcscmds.c $(top_srcdir)/diff/diffrun.h
$(CC) $(CPPFLAGS) $(INCLUDES) -I$(top_srcdir)/diff $(DEFS) $(CFLAGS) -c $(srcdir)/rcscmds.c
zlib.o: zlib.c $(top_srcdir)/zlib/zlib.h
$(CC) $(CPPFLAGS) $(INCLUDES) -I$(top_srcdir)/zlib $(DEFS) $(CFLAGS) -c $(srcdir)/zlib.c
subdir = src

View File

@ -56,6 +56,9 @@ add (argc, argv)
List *entries;
Vers_TS *vers;
struct saved_cwd cwd;
/* Nonzero if we found a slash, and are thus adding files in a
subdirectory. */
int found_slash = 0;
if (argc == 1 || argc == -1)
usage (add_usage);
@ -108,6 +111,20 @@ add (argc, argv)
error (0, 0, "cannot add special file `%s'; skipping", argv[i]);
skip_file = 1;
}
else
{
char *p;
p = argv[i];
while (*p != '\0')
{
if (ISDIRSEP (*p))
{
found_slash = 1;
break;
}
++p;
}
}
if (skip_file)
{
@ -143,9 +160,16 @@ add (argc, argv)
if (options) send_arg(options);
option_with_arg ("-m", message);
repository = Name_Repository (NULL, NULL);
send_a_repository ("", repository, "");
free (repository);
/* If !found_slash, refrain from sending "Directory", for
CVS 1.9 compatibility. If we only tried to deal with servers
which are at least CVS 1.9.26 or so, we wouldn't have to
special-case this. */
if (found_slash)
{
repository = Name_Repository (NULL, NULL);
send_a_repository ("", repository, "");
free (repository);
}
for (i = 0; i < argc; ++i)
/* FIXME: Does this erroneously call Create_Admin in error
@ -194,7 +218,8 @@ add (argc, argv)
Create_Admin (p, argv[i], rcsdir, tag, date,
nonbranch, 0);
send_a_repository ("", repository, update_dir);
if (found_slash)
send_a_repository ("", repository, update_dir);
if (restore_cwd (&cwd, NULL))
error_exit ();

View File

@ -701,15 +701,27 @@ admin_fileproc (callerdat, finfo)
rcs->path,
tag, n->data);
status = 1;
free (tag);
continue;
}
}
/* Expand rev if necessary. */
rev = RCS_gettag (rcs, p, 0, NULL);
RCS_settag (rcs, tag, rev);
if (rev != NULL)
/* Attempt to perform the requested tagging. */
if ((*p == 0 && (rev = RCS_head (rcs)))
|| (rev = RCS_tag2rev (rcs, p))) /* tag2rev may exit */
{
RCS_check_tag (tag); /* exit if not a valid tag */
RCS_settag (rcs, tag, rev);
free (rev);
}
else
{
error (0, 0,
"%s: Symbolic name or revision %s is undefined",
rcs->path, p);
status = 1;
}
free (tag);
break;
case 's':

View File

@ -242,6 +242,13 @@ checkout (argc, argv)
error (1, 0, "tag `%s' must be a symbolic tag", tag);
}
#ifdef SERVER_SUPPORT
if (server_active && where != NULL)
{
server_pathname_check (where);
}
#endif
if (!safe_location()) {
error(1, 0, "Cannot check out files into the repository itself");
}
@ -428,11 +435,15 @@ struct dir_to_build
/* The path to the directory. */
char *dirpath;
/* If set, don't build the directory, just change to it.
The caller will also want to set REPOSITORY to NULL. */
int just_chdir;
struct dir_to_build *next;
};
static int build_dirs_and_chdir PROTO ((struct dir_to_build *list,
int sticky, int check_existing_dirs));
int sticky));
static void build_one_dir PROTO ((char *, char *, int));
@ -723,6 +734,7 @@ internal error: %s doesn't start with %s in checkout_proc",
head->repository = NULL;
head->dirpath = xstrdup (where);
head->next = NULL;
head->just_chdir = 0;
/* Make a copy of the repository name to play with. */
@ -760,7 +772,26 @@ internal error: %s doesn't start with %s in checkout_proc",
assert (strlen (where));
strcpy (new->dirpath, "/");
}
new->next = head;
head = new;
/* If where consists of multiple pathname components,
then we want to just cd into it, without creating
directories or modifying CVS directories as we go.
In CVS 1.9 and earlier, the code actually does a
CVS_CHDIR up-front; I'm not going to try to go back
to that exact code but this is somewhat similar
in spirit. */
if (where_orig != NULL
&& cp - where < strlen (where_orig))
{
new->repository = NULL;
new->just_chdir = 1;
continue;
}
new->just_chdir = 0;
/* Now figure out what repository directory to generate.
The most complete case would be something like this:
@ -771,12 +802,13 @@ internal error: %s doesn't start with %s in checkout_proc",
cvs co -d what/ever -N foo
The results in the CVS/Repository files should be:
. -> . (this is where we executed the cmd)
what -> Emptydir (generated dir -- not in repos)
. -> (don't touch CVS/Repository)
(I think this case might be buggy currently)
what -> (don't touch CVS/Repository)
ever -> . (same as "cd what/ever; cvs co -N foo")
bar -> Emptydir (generated dir -- not in repos)
baz -> quux (finally!) */
if (strcmp (reposcopy, CVSroot_directory) == 0)
{
/* We can't walk up past CVSROOT. Instead, the
@ -835,9 +867,6 @@ internal error: %s doesn't start with %s in checkout_proc",
}
}
}
new->next = head;
head = new;
}
/* clean up */
@ -852,12 +881,29 @@ internal error: %s doesn't start with %s in checkout_proc",
may not have a thing to do with where the sources are
being checked out. If it does, build_dirs_and_chdir
will take care of creating adm files here. */
if (! where_is_absolute)
/* FIXME: checking where_is_absolute is a horrid kludge;
I suspect we probably can just skip the call to
build_one_dir whenever the -d command option was specified
to checkout. */
if (! where_is_absolute && top_level_admin)
{
/* It may be argued that we shouldn't set any sticky
bits for the top-level repository. FIXME? */
build_one_dir (CVSroot_directory, ".", *pargc <= 1);
#ifdef SERVER_SUPPORT
/* We _always_ want to have a top-level admin
directory. If we're running in client/server mode,
send a "Clear-static-directory" command to make
sure it is created on the client side. (See 5.10
in cvsclient.dvi to convince yourself that this is
OK.) If this is a duplicate command being sent, it
will be ignored on the client side. */
if (server_active)
server_clear_entstat (".", CVSroot_directory);
#endif
}
@ -866,8 +912,7 @@ internal error: %s doesn't start with %s in checkout_proc",
contain a CVS subdir yet, but all the others contain
CVS and Entries.Static files */
if (build_dirs_and_chdir (head, *pargc <= 1,
where_is_absolute) != 0)
if (build_dirs_and_chdir (head, *pargc <= 1) != 0)
{
error (0, 0, "ignoring module %s", omodule);
err = 1;
@ -1101,22 +1146,13 @@ emptydir_name ()
return repository;
}
/* Build all the dirs along the path to DIRS with CVS subdirs with
appropriate repositories. If ->repository is NULL, do not create a
CVSADM directory for that subdirectory; just CVS_CHDIR into it. If
check_existing_dirs is nonzero, don't create directories if they
already exist, and don't try to write adm files in directories
where we don't have write permission. We use this last option
primarily when a user has specified an absolute path for checkout
-- we will often not have permission to top-level directories, so
we shouldn't complain. */
/* Build all the dirs along the path to DIRS with CVS subdirs with appropriate
repositories. If ->repository is NULL, do not create a CVSADM directory
for that subdirectory; just CVS_CHDIR into it. */
static int
build_dirs_and_chdir (dirs, sticky, check_existing_dirs)
build_dirs_and_chdir (dirs, sticky)
struct dir_to_build *dirs;
int sticky;
int check_existing_dirs;
{
int retval = 0;
struct dir_to_build *nextdir;
@ -1124,16 +1160,12 @@ build_dirs_and_chdir (dirs, sticky, check_existing_dirs)
while (dirs != NULL)
{
char *dir = last_component (dirs->dirpath);
int dir_is_writeable;
if ((! check_existing_dirs) || (! isdir (dir)))
if (!dirs->just_chdir)
{
mkdir_if_needed (dir);
Subdir_Register (NULL, NULL, dir);
/* This is an expensive call -- only make it if necessary. */
if (check_existing_dirs)
dir_is_writeable = iswritable (dir);
Subdir_Register (NULL, NULL, dir);
}
if (CVS_CHDIR (dir) < 0)
{
@ -1141,14 +1173,11 @@ build_dirs_and_chdir (dirs, sticky, check_existing_dirs)
retval = 1;
goto out;
}
if ((dirs->repository != NULL)
&& ((! check_existing_dirs) || dir_is_writeable))
if (dirs->repository != NULL)
{
build_one_dir (dirs->repository, dirs->dirpath, sticky);
free (dirs->repository);
}
nextdir = dirs->next;
free (dirs->dirpath);
free (dirs);

View File

@ -288,6 +288,14 @@ conflict: %s created independently by second party",
* There is no user file, so note that it was lost and
* extract a new version
*/
/* Comparing the command_name against "update", in
addition to being an ugly way to operate, means
that this message does not get printed by the
server. That might be considered just a straight
bug, although there is one subtlety: that case also
gets hit when a patch fails and the client fetches
a file. I'm not sure there is currently any way
for the server to distinguish those two cases. */
if (strcmp (command_name, "update") == 0)
if (!really_quiet)
error (0, 0, "warning: %s was lost", finfo->fullname);
@ -367,6 +375,8 @@ conflict: %s created independently by second party",
{
/* There is no user file, so just get it */
/* See comment at other "update" compare, for more
thoughts on this comparison. */
if (strcmp (command_name, "update") == 0)
if (!really_quiet)
error (0, 0, "warning: %s was lost", finfo->fullname);

View File

@ -78,8 +78,19 @@ static Key_schedule sched;
#ifdef HAVE_GSSAPI
#ifdef HAVE_GSSAPI_H
#include <gssapi.h>
#endif
#ifdef HAVE_GSSAPI_GSSAPI_H
#include <gssapi/gssapi.h>
#endif
#ifdef HAVE_GSSAPI_GSSAPI_GENERIC_H
#include <gssapi/gssapi_generic.h>
#endif
#ifndef HAVE_GSS_C_NT_HOSTBASED_SERVICE
#define GSS_C_NT_HOSTBASED_SERVICE gss_nt_service_name
#endif
/* This is needed for GSSAPI encryption. */
static gss_ctx_id_t gcontext;
@ -949,17 +960,24 @@ call_in_directory (pathname, func, data)
error (1, errno, "could not chdir to %s", toplevel_wd);
newdir = 0;
/* Create the CVS directory at the top level if needed.
The isdir seems like an unneeded system call, but it *does*
need to be called both if the CVS_CHDIR below succeeds (e.g.
"cvs co .") or if it fails (e.g. basicb-1a in testsuite). */
/* Create the CVS directory at the top level if needed. The
isdir seems like an unneeded system call, but it *does*
need to be called both if the CVS_CHDIR below succeeds
(e.g. "cvs co .") or if it fails (e.g. basicb-1a in
testsuite). We only need to do this for the "." case,
since the server takes care of forcing this directory to be
created in all other cases. If we don't create CVSADM
here, the call to Entries_Open below will fail. FIXME:
perhaps this means that we should change our algorithm
below that calls Create_Admin instead of having this code
here? */
if (/* I think the reposdirname_absolute case has to do with
things like "cvs update /foo/bar". In any event, the
code below which tries to put toplevel_repos into
CVS/Repository is almost surely unsuited to
the reposdirname_absolute case. */
!reposdirname_absolute
&& (strcmp (dir_name, ".") == 0)
&& ! isdir (CVSADM))
{
char *repo;
@ -2909,19 +2927,19 @@ handle_wrapper_rcs_option (args, len)
as free-form as it looks. */
p = strchr (args, ' ');
if (p == NULL)
goto error;
goto handle_error;
if (*++p != '-'
|| *++p != 'k'
|| *++p != ' '
|| *++p != '\'')
goto error;
goto handle_error;
if (strchr (p, '\'') == NULL)
goto error;
goto handle_error;
/* Add server-side cvswrappers line to our wrapper list. */
wrap_add (args, 0);
return;
error:
handle_error:
error (0, errno, "protocol error: ignoring invalid wrappers %s", args);
}
@ -3861,7 +3879,8 @@ connect_to_gserver (sock, hostinfo)
sprintf (buf, "cvs@%s", hostinfo->h_name);
tok_in.length = strlen (buf);
tok_in.value = buf;
gss_import_name (&stat_min, &tok_in, gss_nt_service_name, &server_name);
gss_import_name (&stat_min, &tok_in, GSS_C_NT_HOSTBASED_SERVICE,
&server_name);
tok_in_ptr = GSS_C_NO_BUFFER;
gcontext = GSS_C_NO_CONTEXT;
@ -5442,13 +5461,16 @@ option_with_arg (option, arg)
send_arg (arg);
}
/*
* Send a date to the server. This will passed a string which is the
* result of Make_Date, and looks like YY.MM.DD.HH.MM.SS, where all
* the letters are single digits. The time will be GMT. getdate on
* the server can't parse that, so we turn it back into something
* which it can parse.
*/
/* Send a date to the server. The input DATE is in RCS format.
The time will be GMT.
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. */
void
client_senddate (date)
@ -5457,10 +5479,10 @@ client_senddate (date)
int year, month, day, hour, minute, second;
char buf[100];
if (sscanf (date, DATEFORM, &year, &month, &day, &hour, &minute, &second)
if (sscanf (date, SDATEFORM, &year, &month, &day, &hour, &minute, &second)
!= 6)
{
error (1, 0, "diff_client_senddate: sscanf failed on date");
error (1, 0, "client_senddate: sscanf failed on date");
}
sprintf (buf, "%d/%d/%d %d:%d:%d GMT", month, day, year,

View File

@ -1,17 +1,17 @@
/*
* Copyright (c) 1992, Brian Berliner and Jeff Polk
* Copyright (c) 1989-1992, Brian Berliner
*
*
* You may distribute under the terms of the GNU General Public License as
* specified in the README file that comes with the CVS source distribution.
*
*
* Commit Files
*
*
* "commit" commits the present version to the RCS repository, AFTER
* having done a test on conflicts.
*
* The call is: cvs commit [options] files...
*
*
*/
#include <assert.h>
@ -29,7 +29,7 @@ static int check_filesdoneproc PROTO ((void *callerdat, int err,
char *repos, char *update_dir,
List *entries));
static int checkaddfile PROTO((char *file, char *repository, char *tag,
char *options, RCSNode **rcsnode));
char *options, RCSNode **rcsnode));
static Dtype commit_direntproc PROTO ((void *callerdat, char *dir,
char *repos, char *update_dir,
List *entries));
@ -74,12 +74,13 @@ static int force_ci = 0;
static int got_message;
static int run_module_prog = 1;
static int aflag;
static char *tag;
static char *saved_tag;
static char *write_dirtag;
static int write_dirnonbranch;
static char *logfile;
static List *mulist;
static char *message;
static List *saved_ulist;
static char *saved_message;
static time_t last_register_time;
static const char *const commit_usage[] =
@ -247,7 +248,7 @@ find_fileproc (callerdat, finfo)
xfinfo.repository = NULL;
xfinfo.rcs = NULL;
vers = Version_TS (&xfinfo, NULL, tag, NULL, 0, 0);
vers = Version_TS (&xfinfo, NULL, saved_tag, NULL, 0, 0);
if (vers->ts_user == NULL
&& vers->vn_user != NULL
&& vers->vn_user[0] == '-')
@ -364,18 +365,18 @@ commit (argc, argv)
#else
use_editor = 0;
#endif
if (message)
if (saved_message)
{
free (message);
message = NULL;
free (saved_message);
saved_message = NULL;
}
message = xstrdup(optarg);
saved_message = xstrdup(optarg);
break;
case 'r':
if (tag)
free (tag);
tag = xstrdup (optarg);
if (saved_tag)
free (saved_tag);
saved_tag = xstrdup (optarg);
break;
case 'l':
local = 1;
@ -405,12 +406,12 @@ commit (argc, argv)
argv += optind;
/* numeric specified revision means we ignore sticky tags... */
if (tag && isdigit (*tag))
if (saved_tag && isdigit (*saved_tag))
{
aflag = 1;
/* strip trailing dots */
while (tag[strlen (tag) - 1] == '.')
tag[strlen (tag) - 1] = '\0';
while (saved_tag[strlen (saved_tag) - 1] == '.')
saved_tag[strlen (saved_tag) - 1] = '\0';
}
/* some checks related to the "-F logfile" option */
@ -419,7 +420,7 @@ commit (argc, argv)
int n, logfd;
struct stat statbuf;
if (message)
if (saved_message)
error (1, 0, "cannot specify both a message and a log file");
/* FIXME: Why is this binary? Needs more investigation. */
@ -429,21 +430,20 @@ commit (argc, argv)
if (fstat(logfd, &statbuf) < 0)
error (1, errno, "cannot find size of log file %s", logfile);
message = xmalloc (statbuf.st_size + 1);
saved_message = xmalloc (statbuf.st_size + 1);
/* FIXME: Should keep reading until EOF, rather than assuming the
first read gets the whole thing. */
if ((n = read (logfd, message, statbuf.st_size + 1)) < 0)
if ((n = read (logfd, saved_message, statbuf.st_size + 1)) < 0)
error (1, errno, "cannot read log message from %s", logfile);
(void) close (logfd);
message[n] = '\0';
saved_message[n] = '\0';
}
#ifdef CLIENT_SUPPORT
if (client_active)
if (client_active)
{
int err;
struct find_data find_args;
ign_setup ();
@ -458,7 +458,7 @@ commit (argc, argv)
I haven't really thought about it much.
Anyway, I suspect that setting it unnecessarily only causes
a little unneeded network traffic. */
find_args.force = force_ci || tag != NULL;
find_args.force = force_ci || saved_tag != NULL;
err = start_recursion (find_fileproc, find_filesdoneproc,
find_dirent_proc, (DIRLEAVEPROC) NULL,
@ -500,17 +500,17 @@ commit (argc, argv)
* The protocol is designed this way. This is a feature.
*/
if (use_editor)
do_editor (".", &message, (char *)NULL, find_args.ulist);
do_editor (".", &saved_message, (char *)NULL, find_args.ulist);
/* Run the user-defined script to verify/check information in
*the log message
*/
do_verify (message, (char *)NULL);
do_verify (saved_message, (char *)NULL);
/* We always send some sort of message, even if empty. */
/* FIXME: is that true? There seems to be some code in do_editor
which can leave the message NULL. */
option_with_arg ("-m", message);
option_with_arg ("-m", saved_message);
/* OK, now process all the questionable files we have been saving
up. */
@ -559,7 +559,7 @@ commit (argc, argv)
send_arg("-f");
if (!run_module_prog)
send_arg("-n");
option_with_arg ("-r", tag);
option_with_arg ("-r", saved_tag);
/* Sending only the names of the files which were modified, added,
or removed means that the server will only do an up-to-date
@ -582,7 +582,7 @@ commit (argc, argv)
send_to_server ("ci\012", 0);
err = get_responses_and_close ();
if (err != 0 && use_editor && message != NULL)
if (err != 0 && use_editor && saved_message != NULL)
{
/* If there was an error, don't nuke the user's carefully
constructed prose. This is something of a kludge; a better
@ -600,7 +600,8 @@ commit (argc, argv)
fp = CVS_FOPEN (fname, "w+");
if (fp == NULL)
error (1, 0, "cannot create temporary file %s", fname);
if (fwrite (message, 1, strlen (message), fp) != strlen (message))
if (fwrite (saved_message, 1, strlen (saved_message), fp)
!= strlen (saved_message))
error (1, errno, "cannot write temporary file %s", fname);
if (fclose (fp) < 0)
error (0, errno, "cannot close temporary file %s", fname);
@ -610,12 +611,12 @@ commit (argc, argv)
}
#endif
if (tag != NULL)
tag_check_valid (tag, argc, argv, local, aflag, "");
if (saved_tag != NULL)
tag_check_valid (saved_tag, argc, argv, local, aflag, "");
/* XXX - this is not the perfect check for this */
if (argc <= 0)
write_dirtag = tag;
write_dirtag = saved_tag;
wrap_setup ();
@ -651,17 +652,6 @@ commit (argc, argv)
error (1, 0, "correct above errors first!");
}
#ifdef PRESERVE_PERMISSIONS_SUPPORT
if (preserve_perms)
{
/* hardlist now includes a complete index of the files
to be committed, indexed by inode. For each inode,
compile a list of the files that are linked to it,
and save this list in each file's hardlink_info node. */
(void) walklist (hardlist, cache_hardlinks_proc, NULL);
}
#endif
/*
* Run the recursion processor to commit the files
*/
@ -683,7 +673,7 @@ commit (argc, argv)
time_t now;
(void) time (&now);
if (now == last_register_time)
if (now == last_register_time)
{
sleep (1); /* to avoid time-stamp races */
}
@ -713,10 +703,10 @@ classify_file_internal (finfo, vers)
noexec = quiet = really_quiet = 1;
/* handle specified numeric revision specially */
if (tag && isdigit (*tag))
if (saved_tag && isdigit (*saved_tag))
{
/* If the tag is for the trunk, make sure we're at the head */
if (numdots (tag) < 2)
if (numdots (saved_tag) < 2)
{
status = Classify_File (finfo, (char *) NULL, (char *) NULL,
(char *) NULL, 1, aflag, vers, 0);
@ -726,7 +716,7 @@ classify_file_internal (finfo, vers)
Ctype xstatus;
freevers_ts (vers);
xstatus = Classify_File (finfo, tag, (char *) NULL,
xstatus = Classify_File (finfo, saved_tag, (char *) NULL,
(char *) NULL, 1, aflag, vers, 0);
if (xstatus == T_REMOVE_ENTRY)
status = T_MODIFIED;
@ -744,7 +734,7 @@ classify_file_internal (finfo, vers)
* The revision is off the main trunk; make sure we're
* up-to-date with the head of the specified branch.
*/
xtag = xstrdup (tag);
xtag = xstrdup (saved_tag);
if ((numdots (xtag) & 1) != 0)
{
cp = strrchr (xtag, '.');
@ -765,12 +755,12 @@ classify_file_internal (finfo, vers)
}
/* now, muck with vers to make the tag correct */
free ((*vers)->tag);
(*vers)->tag = xstrdup (tag);
(*vers)->tag = xstrdup (saved_tag);
free (xtag);
}
}
else
status = Classify_File (finfo, tag, (char *) NULL, (char *) NULL,
status = Classify_File (finfo, saved_tag, (char *) NULL, (char *) NULL,
1, 0, vers, 0);
noexec = save_noexec;
quiet = save_quiet;
@ -796,7 +786,7 @@ check_fileproc (callerdat, finfo)
Vers_TS *vers;
struct commit_info *ci;
struct logfile_info *li;
status = classify_file_internal (finfo, &vers);
/*
@ -835,7 +825,7 @@ check_fileproc (callerdat, finfo)
* allow the commit if timestamp is identical or if we find
* an RCS_MERGE_PAT in the file.
*/
if (!tag || !isdigit (*tag))
if (!saved_tag || !isdigit (*saved_tag))
{
if (vers->date)
{
@ -1047,7 +1037,6 @@ warning: file `%s' seems to still contain conflict indicators",
hlinfo = (struct hardlink_info *)
xmalloc (sizeof (struct hardlink_info));
hlinfo->status = status;
hlinfo->links = NULL;
linkp->data = (char *) hlinfo;
}
}
@ -1114,7 +1103,6 @@ precommit_list_proc (p, closure)
/*
* Callback proc for pre-commit checking
*/
static List *ulist;
static int
precommit_proc (repository, filter)
char *repository;
@ -1124,7 +1112,7 @@ precommit_proc (repository, filter)
if (isabsolute (filter))
{
char *s, *cp;
s = xstrdup (filter);
for (cp = s; *cp; cp++)
if (isspace (*cp))
@ -1143,7 +1131,7 @@ precommit_proc (repository, filter)
run_setup (filter);
run_arg (repository);
(void) walklist (ulist, precommit_list_proc, NULL);
(void) walklist (saved_ulist, precommit_list_proc, NULL);
return (run_exec (RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL|RUN_REALLY));
}
@ -1165,12 +1153,12 @@ check_filesdoneproc (callerdat, err, repos, update_dir, entries)
/* find the update list for this dir */
p = findnode (mulist, update_dir);
if (p != NULL)
ulist = ((struct master_lists *) p->data)->ulist;
saved_ulist = ((struct master_lists *) p->data)->ulist;
else
ulist = (List *) NULL;
saved_ulist = (List *) NULL;
/* skip the checks if there's nothing to do */
if (ulist == NULL || ulist->list->next == ulist->list)
if (saved_ulist == NULL || saved_ulist->list->next == saved_ulist->list)
return (err);
/* run any pre-commit checks */
@ -1238,8 +1226,9 @@ commit_fileproc (callerdat, finfo)
{
got_message = 1;
if (use_editor)
do_editor (finfo->update_dir, &message, finfo->repository, ulist);
do_verify (message, finfo->repository);
do_editor (finfo->update_dir, &saved_message,
finfo->repository, ulist);
do_verify (saved_message, finfo->repository);
}
p = findnode (cilist, finfo->file);
@ -1279,7 +1268,7 @@ commit_fileproc (callerdat, finfo)
error (1, 0, "internal error: no parsed RCS file");
ci->rev = RCS_whatbranch (finfo->rcs, ci->tag);
err = Checkin ('A', finfo, finfo->rcs->path, ci->rev,
ci->tag, ci->options, message);
ci->tag, ci->options, saved_message);
if (err != 0)
{
unlockrcs (finfo->rcs);
@ -1319,7 +1308,7 @@ commit_fileproc (callerdat, finfo)
{
err = Checkin ('M', finfo,
finfo->rcs->path, ci->rev, ci->tag,
ci->options, message);
ci->options, saved_message);
(void) time (&last_register_time);
@ -1331,7 +1320,7 @@ commit_fileproc (callerdat, finfo)
}
else if (ci->status == T_REMOVED)
{
err = remove_file (finfo, ci->tag, message);
err = remove_file (finfo, ci->tag, saved_message);
#ifdef SERVER_SUPPORT
if (server_active) {
server_scratch_entry_only ();
@ -1371,7 +1360,7 @@ out:
been removed from the archive, which is not the behavior we
want for our commitlog messages; we want the old version
number and then "NONE." */
if (ci->status != T_REMOVED)
{
p = findnode (ulist, finfo->file);
@ -1379,7 +1368,7 @@ out:
{
Vers_TS *vers;
struct logfile_info *li;
(void) classify_file_internal (finfo, &vers);
li = (struct logfile_info *) p->data;
li->rev_new = xstrdup (vers->vn_rcs);
@ -1415,7 +1404,7 @@ commit_filesdoneproc (callerdat, err, repository, update_dir, entries)
got_message = 0;
Update_Logfile (repository, message, (FILE *) 0, ulist);
Update_Logfile (repository, saved_message, (FILE *) 0, ulist);
/* Build the administrative files if necessary. */
{
@ -1423,11 +1412,17 @@ commit_filesdoneproc (callerdat, err, repository, update_dir, entries)
if (strncmp (CVSroot_directory, repository,
strlen (CVSroot_directory)) != 0)
error (0, 0, "internal error: repository (%s) doesn't begin with root (%s)", repository, CVSroot_directory);
error (0, 0,
"internal error: repository (%s) doesn't begin with root (%s)",
repository, CVSroot_directory);
p = repository + strlen (CVSroot_directory);
if (*p == '/')
++p;
if (strcmp ("CVSROOT", p) == 0)
if (strcmp ("CVSROOT", p) == 0
/* Check for subdirectories because people may want to create
subdirectories and list files therein in checkoutlist. */
|| strncmp ("CVSROOT/", p, strlen ("CVSROOT/")) == 0
)
{
/* "Database" might a little bit grandiose and/or vague,
but "checked-out copies of administrative files, unless
@ -1435,11 +1430,21 @@ commit_filesdoneproc (callerdat, err, repository, update_dir, entries)
case modules.{pag,dir,db}" is verbose and excessively
focused on how the database is implemented. */
/* mkmodules requires the absolute name of the CVSROOT directory.
Remove anything after the `CVSROOT' component -- this is
necessary when committing in a subdirectory of CVSROOT. */
char *admin_dir = xstrdup (repository);
int cvsrootlen = strlen ("CVSROOT");
assert (admin_dir[p - repository + cvsrootlen] == '\0'
|| admin_dir[p - repository + cvsrootlen] == '/');
admin_dir[p - repository + cvsrootlen] = '\0';
cvs_output (program_name, 0);
cvs_output (" ", 1);
cvs_output (command_name, 0);
cvs_output (": Rebuilding administrative file database\n", 0);
mkmodules (repository);
mkmodules (admin_dir);
free (admin_dir);
}
}
@ -1452,7 +1457,7 @@ commit_filesdoneproc (callerdat, err, repository, update_dir, entries)
char *line;
int line_length;
size_t line_chars_allocated;
char *repository;
char *repos;
line = NULL;
line_chars_allocated = 0;
@ -1462,9 +1467,9 @@ commit_filesdoneproc (callerdat, err, repository, update_dir, entries)
/* Remove any trailing newline. */
if (line[line_length - 1] == '\n')
line[--line_length] = '\0';
repository = Name_Repository ((char *) NULL, update_dir);
repos = Name_Repository ((char *) NULL, update_dir);
run_setup (line);
run_arg (repository);
run_arg (repos);
cvs_output (program_name, 0);
cvs_output (" ", 1);
cvs_output (command_name, 0);
@ -1472,7 +1477,7 @@ commit_filesdoneproc (callerdat, err, repository, update_dir, entries)
run_print (stdout);
cvs_output ("'\n", 0);
(void) run_exec (RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL);
free (repository);
free (repos);
}
else
{
@ -1529,8 +1534,8 @@ commit_direntproc (callerdat, dir, repos, update_dir, entries)
real_repos = Name_Repository (dir, update_dir);
got_message = 1;
if (use_editor)
do_editor (update_dir, &message, real_repos, ulist);
do_verify (message, real_repos);
do_editor (update_dir, &saved_message, real_repos, ulist);
do_verify (saved_message, real_repos);
free (real_repos);
return (R_PROCESS);
}
@ -1622,7 +1627,7 @@ remove_file (finfo, tag, message)
if (tag && !(branch = RCS_nodeisbranch (finfo->rcs, tag)))
{
/* a symbolic tag is specified; just remove the tag from the file */
if ((retcode = RCS_deltag (finfo->rcs, tag)) != 0)
if ((retcode = RCS_deltag (finfo->rcs, tag)) != 0)
{
if (!quiet)
error (0, retcode == -1 ? errno : 0,
@ -1655,7 +1660,7 @@ remove_file (finfo, tag, message)
error (0, 0, "cannot find branch \"%s\".", tag);
return (1);
}
branchname = RCS_getbranch (finfo->rcs, rev, 1);
if (branchname == NULL)
{
@ -1676,12 +1681,12 @@ remove_file (finfo, tag, message)
/* Get current head revision of file. */
prev_rev = RCS_head (finfo->rcs);
}
/* if removing without a tag or a branch, then make sure the default
branch is the trunk. */
if (!tag && !branch)
{
if (RCS_setbranch (finfo->rcs, NULL) != 0)
if (RCS_setbranch (finfo->rcs, NULL) != 0)
{
error (0, 0, "cannot change branch to default for %s",
finfo->fullname);
@ -1740,7 +1745,7 @@ remove_file (finfo, tag, message)
if (!branch)
{
/* this was the head; really move it into the Attic */
tmp = xmalloc(strlen(finfo->repository) +
tmp = xmalloc(strlen(finfo->repository) +
sizeof('/') +
sizeof(CVSATTIC) +
sizeof('/') +
@ -1750,8 +1755,9 @@ remove_file (finfo, tag, message)
omask = umask (cvsumask);
(void) CVS_MKDIR (tmp, 0777);
(void) umask (omask);
(void) sprintf (tmp, "%s/%s/%s%s", finfo->repository, CVSATTIC, finfo->file, RCSEXT);
(void) sprintf (tmp, "%s/%s/%s%s", finfo->repository, CVSATTIC,
finfo->file, RCSEXT);
if (strcmp (finfo->rcs->path, tmp) != 0
&& CVS_RENAME (finfo->rcs->path, tmp) == -1
&& (isreadable (finfo->rcs->path) || !isreadable (tmp)))
@ -1794,7 +1800,7 @@ finaladd (finfo, rev, tag, options)
char *rcs;
rcs = locate_rcs (finfo->file, finfo->repository);
ret = Checkin ('A', finfo, rcs, rev, tag, options, message);
ret = Checkin ('A', finfo, rcs, rev, tag, options, saved_message);
if (ret == 0)
{
char *tmp = xmalloc (strlen (finfo->file) + sizeof (CVSADM)
@ -1931,7 +1937,7 @@ checkaddfile (file, repository, tag, options, rcsnode)
Attic. */
oldfile = xstrdup (rcs);
sprintf (rcs, "%s/%s%s", repository, file, RCSEXT);
if (strcmp (oldfile, rcs) == 0)
{
error (0, 0, "internal error: confused about attic for %s",
@ -2154,7 +2160,7 @@ internal error: `%s' didn't move out of the attic",
retval = 1;
goto out;
}
}
}
if (rcsnode && *rcsnode != rcsfile)
{
@ -2200,7 +2206,7 @@ lock_RCS (user, rcs, rev, repository)
* For a specified, numeric revision of the form "1" or "1.1", (or when
* no revision is specified ""), definitely move the branch to the trunk
* before locking the RCS file.
*
*
* The assumption is that if there is more than one revision on the trunk,
* the head points to the trunk, not a branch... and as such, it's not
* necessary to move the head in this case.

View File

@ -385,6 +385,8 @@ extern int trace; /* Show all commands */
extern int noexec; /* Don't modify disk anywhere */
extern int logoff; /* Don't write history entry */
extern int top_level_admin;
#ifdef AUTH_SERVER_SUPPORT
extern char *Pserver_Repos; /* used to check that same repos is
transmitted in pserver auth and in
@ -429,6 +431,8 @@ void Subdir_Register PROTO((List *, const char *, const char *));
void Subdir_Deregister PROTO((List *, const char *, const char *));
char *Make_Date PROTO((char *rawdate));
char *date_from_time_t PROTO ((time_t));
char *Name_Repository PROTO((char *dir, char *update_dir));
char *Short_Repository PROTO((char *repository));
void Sanitize_Repository_Name PROTO((char *repository));
@ -476,7 +480,6 @@ int numdots PROTO((const char *s));
char *increment_revnum PROTO ((const char *));
int compare_revnums PROTO ((const char *, const char *));
int unlink_file PROTO((const char *f));
int link_file PROTO ((const char *from, const char *to));
int unlink_file_dir PROTO((const char *f));
int update PROTO((int argc, char *argv[]));
int xcmp PROTO((const char *file1, const char *file2));
@ -834,7 +837,7 @@ extern int patch PROTO((int argc, char **argv));
extern int release PROTO((int argc, char **argv));
extern int cvsremove PROTO((int argc, char **argv));
extern int rtag PROTO((int argc, char **argv));
extern int status PROTO((int argc, char **argv));
extern int cvsstatus PROTO((int argc, char **argv));
extern int cvstag PROTO((int argc, char **argv));
extern unsigned long int lookup_command_attribute PROTO((char *));

View File

@ -434,7 +434,15 @@ diff_fileproc (callerdat, finfo)
exists = 0;
/* special handling for TAG_HEAD */
if (diff_rev1 && strcmp (diff_rev1, TAG_HEAD) == 0)
exists = vers->vn_rcs != NULL;
{
char *head =
(vers->vn_rcs == NULL
? NULL
: RCS_branch_head (vers->srcfile, vers->vn_rcs));
exists = head != NULL;
if (head != NULL)
free (head);
}
else
{
Vers_TS *xvers;
@ -814,7 +822,9 @@ diff_file_nodiff (finfo, vers, empty_file)
{
/* special handling for TAG_HEAD */
if (diff_rev1 && strcmp (diff_rev1, TAG_HEAD) == 0)
use_rev1 = xstrdup (vers->vn_rcs);
use_rev1 = ((vers->vn_rcs == NULL || vers->srcfile == NULL)
? NULL
: RCS_branch_head (vers->srcfile, vers->vn_rcs));
else
{
xvers = Version_TS (finfo, NULL, diff_rev1, diff_date1, 1, 0);
@ -827,7 +837,9 @@ diff_file_nodiff (finfo, vers, empty_file)
{
/* special handling for TAG_HEAD */
if (diff_rev2 && strcmp (diff_rev2, TAG_HEAD) == 0)
use_rev2 = xstrdup (vers->vn_rcs);
use_rev2 = ((vers->vn_rcs == NULL || vers->srcfile == NULL)
? NULL
: RCS_branch_head (vers->srcfile, vers->vn_rcs));
else
{
xvers = Version_TS (finfo, NULL, diff_rev2, diff_date2, 1, 0);

View File

@ -521,6 +521,26 @@ unedit_fileproc (callerdat, finfo)
if (node != NULL)
{
entdata = (Entnode *) node->data;
if (baserev == NULL)
{
/* This can only happen if the CVS/Baserev file got
corrupted. We suspect it might be possible if the
user interrupts CVS, although I haven't verified
that. */
error (0, 0, "%s not mentioned in %s", finfo->fullname,
CVSADM_BASEREV);
/* Since we don't know what revision the file derives from,
keeping it around would be asking for trouble. */
if (unlink_file (finfo->file) < 0)
error (0, errno, "cannot remove %s", finfo->fullname);
/* This is cheesy, in a sense; why shouldn't we do the
update for the user? However, doing that would require
contacting the server, so maybe this is OK. */
error (0, 0, "run update to complete the unedit");
return 0;
}
Register (finfo->entries, finfo->file, baserev, entdata->timestamp,
entdata->options, entdata->tag, entdata->date,
entdata->conflict);

View File

@ -89,7 +89,15 @@ error_exit PROTO ((void))
thing for the server, whether the normal server_active (child process)
case or the error_use_protocol (parent process) case. The one exception
is that STATUS nonzero for error_use_protocol probably doesn't work yet;
in that case still need to use the pending_error machinery in server.c. */
in that case still need to use the pending_error machinery in server.c.
error() does not molest errno; some code (e.g. Entries_Open) depends
on being able to say something like:
error (0, 0, "foo");
error (0, errno, "bar");
*/
/* VARARGS */
void
#if defined (HAVE_VPRINTF) && defined (__STDC__)
@ -102,6 +110,9 @@ 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')
{
@ -211,6 +222,7 @@ error (status, errnum, message, va_alist)
if (status)
error_exit ();
errno = save_errno;
}
/* Print the program name and error message MESSAGE, which is a printf-style

View File

@ -111,6 +111,10 @@ fileattr_read ()
Node *newnode;
p = strchr (line, '\t');
if (p == NULL)
error (1, 0,
"file attribute database corruption: tab missing in %s",
fname);
*p++ = '\0';
newnode = getnode ();
newnode->type = FILEATTR;
@ -130,6 +134,10 @@ fileattr_read ()
/* Currently nothing to skip here, but for future expansion,
ignore anything located here. */
p = strchr (line, '\t');
if (p == NULL)
error (1, 0,
"file attribute database corruption: tab missing in %s",
fname);
++p;
fileattr_default_attrs = xstrdup (p);
}

View File

@ -414,29 +414,6 @@ rename_file (from, to)
error (1, errno, "cannot rename file %s to %s", from, to);
}
/*
* link a file, if possible. Warning: the Windows NT version of this
* function just copies the file, so only use this function in ways
* that can deal with either a link or a copy.
*/
int
link_file (from, to)
const char *from;
const char *to;
{
if (trace)
#ifdef SERVER_SUPPORT
(void) fprintf (stderr, "%c-> link(%s,%s)\n",
(server_active) ? 'S' : ' ', from, to);
#else
(void) fprintf (stderr, "-> link(%s,%s)\n", from, to);
#endif
if (noexec)
return (0);
return (link (from, to));
}
/*
* unlink a file, if possible.
*/
@ -770,7 +747,9 @@ xreadlink (link)
const char *link;
{
char *file = NULL;
int buflen = BUFSIZ;
char *tfile;
int buflen = 128;
int link_name_len;
if (!islink (link))
return NULL;
@ -781,18 +760,21 @@ xreadlink (link)
do
{
file = xrealloc (file, buflen);
errno = 0;
readlink (link, file, buflen);
link_name_len = readlink (link, file, buflen - 1);
buflen *= 2;
}
while (errno == ENAMETOOLONG);
while (link_name_len < 0 && errno == ENAMETOOLONG);
if (errno)
if (link_name_len < 0)
error (1, errno, "cannot readlink %s", link);
return file;
}
file[link_name_len] = '\0';
tfile = xstrdup (file);
free (file);
return tfile;
}
/* Return a pointer into PATH's last component. */

View File

@ -41,96 +41,6 @@ List *hardlist; /* Record hardlink information for working files */
char *working_dir; /* The top-level working directory, used for
constructing full pathnames. */
/* For check_link_proc: list all of the files named in an inode list. */
static int
list_files_proc (node, vstrp)
Node *node;
void *vstrp;
{
char **strp, *file;
int len;
/* Get the file's basename. This is because -- VERY IMPORTANT --
the `hardlinks' field is presently defined only to include links
within a directory. So the hardlinks field might be `foo' or
`mumble grump flink', but not `foo bar com/baz' or `wham ../bam
../thank/you'. Someday it would be nice to extend this to
permit cross-directory links, but the issues involved are
hideous. */
file = strrchr (node->key, '/');
if (file)
++file;
else
file = node->key;
/* Is it safe to cast vstrp to (char **) here, and then play with
the contents? I think so, since vstrp will have started out
a char ** to begin with, so we should not have alignment bugs. */
strp = (char **) vstrp;
len = (*strp == NULL ? 0 : strlen (*strp));
*strp = (char *) xrealloc (*strp, len + strlen (file) + 2);
if (*strp == NULL)
{
error (0, errno, "could not allocate memory");
return 1;
}
if (sprintf (*strp + len, "%s ", file) < 0)
{
error (0, errno, "could not compile file list");
return 1;
}
return 0;
}
/* Set the link field of each hardlink_info node to `data', which is a
list of linked files. */
static int
set_hardlink_field_proc (node, data)
Node *node;
void *data;
{
struct hardlink_info *hlinfo = (struct hardlink_info *) node->data;
hlinfo->links = xstrdup ((char *) data);
return 0;
}
/* For each file being checked in, compile a list of the files linked
to it, and cache the list in the file's hardlink_info field. */
int
cache_hardlinks_proc (node, data)
Node *node;
void *data;
{
List *inode_links;
char *p, *linked_files = NULL;
int err;
inode_links = (List *) node->data;
/* inode->data is a list of hardlink_info structures: all the
files linked to this inode. We compile a string of each file
named in this list, in alphabetical order, separated by spaces.
Then store this string in the `links' field of each
hardlink_info structure, so that RCS_checkin can easily add
it to the `hardlinks' field of a new delta node. */
sortlist (inode_links, fsortcmp);
err = walklist (inode_links, list_files_proc, &linked_files);
if (err)
return err;
/* Trim trailing whitespace. */
p = linked_files + strlen(linked_files) - 1;
while (p > linked_files && isspace (*p))
*p-- = '\0';
err = walklist (inode_links, set_hardlink_field_proc, linked_files);
return err;
}
/* Return a pointer to FILEPATH's node in the hardlist. This means
looking up its inode, retrieving the list of files linked to that
inode, and then looking up FILE in that list. If the file doesn't
@ -237,26 +147,28 @@ update_hardlink_info (file)
hlinfo = (struct hardlink_info *) n->data;
hlinfo->status = T_UPTODATE;
hlinfo->checked_out = 1;
hlinfo->links = NULL;
}
/* Return a string listing all the files known to be linked to FILE in
/* Return a List with all the files known to be linked to FILE in
the working directory. Used by special_file_mismatch, to determine
whether it is safe to merge two files. */
char *
list_files_linked_to (file)
const char *file;
whether it is safe to merge two files.
FIXME: What is the memory allocation for the return value? We seem
to sometimes allocate a new list (getlist() call below) and sometimes
return an existing list (where we return n->data). */
List *
list_linked_files_on_disk (file)
char *file;
{
char *inodestr, *filelist, *path;
char *inodestr, *path;
struct stat sb;
Node *n;
int err;
/* If hardlist is NULL, we have not been doing an operation that
would permit us to know anything about the file's hardlinks
(cvs update, cvs commit, etc). Return an empty string. */
(cvs update, cvs commit, etc). Return an empty list. */
if (hardlist == NULL)
return xstrdup ("");
return getlist();
/* Get the full pathname of file (assuming the working directory) */
if (file[0] == '/')
@ -288,11 +200,107 @@ list_files_linked_to (file)
n = findnode (hardlist, inodestr);
sortlist ((List *) n->data, fsortcmp);
filelist = NULL;
err = walklist ((List *) n->data, list_files_proc, &filelist);
if (err)
error (1, 0, "cannot get list of hardlinks for %s", file);
free (inodestr);
return filelist;
return (List *) n->data;
}
/* Compare the files in the `key' fields of two lists, returning 1 if
the lists are equivalent and 0 otherwise.
Only the basenames of each file are compared. This is an awful hack
that exists because list_linked_files_on_disk returns full paths
and the `hardlinks' structure of a RCSVers node contains only
basenames. That in turn is a result of the awful hack that only
basenames are stored in the RCS file. If anyone ever solves the
problem of correctly managing cross-directory hardlinks, this
function (along with most functions in this file) must be fixed. */
int
compare_linkage_lists (links1, links2)
List *links1;
List *links2;
{
Node *n1, *n2;
char *p1, *p2;
sortlist (links1, fsortcmp);
sortlist (links2, fsortcmp);
n1 = links1->list->next;
n2 = links2->list->next;
while (n1 != links1->list && n2 != links2->list)
{
/* Get the basenames of both files. */
p1 = strrchr (n1->key, '/');
if (p1 == NULL)
p1 = n1->key;
else
++p1;
p2 = strrchr (n2->key, '/');
if (p2 == NULL)
p2 = n2->key;
else
++p2;
/* Compare the files' basenames. */
if (strcmp (p1, p2) != 0)
return 0;
n1 = n1->next;
n2 = n2->next;
}
/* At this point we should be at the end of both lists; if not,
one file has more links than the other, and return 1. */
return (n1 == links1->list && n2 == links2->list);
}
/* Find a checked-out file in a list of filenames. Used by RCS_checkout
when checking out a new hardlinked file, to decide whether this file
can be linked to any others that already exist. The return value
is not currently used. */
int
find_checkedout_proc (node, data)
Node *node;
void *data;
{
Node **uptodate = (Node **) data;
Node *link;
char *dir = xgetwd();
char *path;
struct hardlink_info *hlinfo;
/* If we have already found a file, don't do anything. */
if (*uptodate != NULL)
return 0;
/* Look at this file in the hardlist and see whether the checked_out
field is 1, meaning that it has been checked out during this CVS run. */
path = (char *)
xmalloc (sizeof(char) * (strlen (dir) + strlen (node->key) + 2));
sprintf (path, "%s/%s", dir, node->key);
link = lookup_file_by_inode (path);
free (path);
free (dir);
if (link == NULL)
{
/* We haven't seen this file -- maybe it hasn't been checked
out yet at all. */
return 0;
}
hlinfo = (struct hardlink_info *) link->data;
if (hlinfo->checked_out)
{
/* This file has been checked out recently, so it's safe to
link to it. */
*uptodate = link;
}
return 0;
}

View File

@ -21,13 +21,13 @@ struct hardlink_info
{
Ctype status; /* as returned from Classify_File() */
int checked_out; /* has this file been checked out lately? */
char *links; /* contents of `hardlinks' RCS field */
};
extern List *hardlist;
extern char *working_dir;
int cache_hardlinks_proc PROTO ((Node *, void *));
Node *lookup_file_by_inode PROTO ((const char *));
void update_hardlink_info PROTO ((const char *));
char *list_files_linked_to PROTO ((const char *));
List *list_linked_files_on_disk PROTO ((char *));
int compare_linkage_lists PROTO ((List *, List *));
int find_checkedout_proc PROTO ((Node *, void *));

View File

@ -200,7 +200,6 @@ static int accept_hrec PROTO((struct hrec * hr, struct hrec * lr));
static int select_hrec PROTO((struct hrec * hr));
static int sort_order PROTO((const PTR l, const PTR r));
static int within PROTO((char *find, char *string));
static time_t date_and_time PROTO((char *date_str));
static void expand_modules PROTO((void));
static void read_hrecs PROTO((char *fname));
static void report_hrecs PROTO((void));
@ -242,8 +241,8 @@ static char *tz_name = "+0000";
static char *since_rev;
static char *since_tag;
static char *backto;
/* -D option, or 0 if not specified. */
static time_t since_date;
/* -D option, or 0 if not specified. RCS format. */
static char * since_date;
static struct hrec *last_since_tag;
static struct hrec *last_backto;
@ -364,18 +363,6 @@ sort_order (l, r)
return (left->idx - right->idx);
}
static time_t
date_and_time (date_str)
char *date_str;
{
time_t t;
t = get_date (date_str, (struct timeb *) NULL);
if (t == (time_t) - 1)
error (1, 0, "Can't parse date/time: %s", date_str);
return (t);
}
int
history (argc, argv)
int argc;
@ -432,14 +419,16 @@ history (argc, argv)
error (0, 0, "date overriding rev/tag/backto");
*since_rev = *since_tag = *backto = '\0';
}
since_date = date_and_time (optarg);
since_date = Make_Date (optarg);
break;
case 'b': /* Since specified file/Repos */
if (since_date || *since_rev || *since_tag)
{
error (0, 0, "backto overriding date/rev/tag");
*since_rev = *since_tag = '\0';
since_date = 0;
if (since_date != NULL)
free (since_date);
since_date = NULL;
}
free (backto);
backto = xstrdup (optarg);
@ -461,7 +450,9 @@ history (argc, argv)
{
error (0, 0, "rev overriding date/tag/backto");
*since_tag = *backto = '\0';
since_date = 0;
if (since_date != NULL)
free (since_date);
since_date = NULL;
}
free (since_rev);
since_rev = xstrdup (optarg);
@ -471,7 +462,9 @@ history (argc, argv)
{
error (0, 0, "tag overriding date/marker/file/repos");
*since_rev = *backto = '\0';
since_date = 0;
if (since_date != NULL)
free (since_date);
since_date = NULL;
}
free (since_tag);
since_tag = xstrdup (optarg);
@ -564,7 +557,7 @@ history (argc, argv)
if (histfile)
send_arg("-X");
if (since_date)
option_with_arg ("-D", asctime (gmtime (&since_date)));
client_senddate (since_date);
if (backto[0] != '\0')
option_with_arg ("-b", backto);
for (f1 = file_list; f1 < &file_list[file_count]; ++f1)
@ -683,6 +676,8 @@ history (argc, argv)
qsort ((PTR) hrec_head, hrec_count, sizeof (struct hrec), sort_order);
report_hrecs ();
free (fname);
if (since_date != NULL)
free (since_date);
free (since_rev);
free (since_tag);
free (backto);
@ -1157,7 +1152,7 @@ select_hrec (hr)
/* "Since" checking: The argument parser guarantees that only one of the
* following four choices is set:
*
* 1. If "since_date" is set, it contains a Unix time_t specified on the
* 1. If "since_date" is set, it contains the date specified on the
* command line. hr->date fields earlier than "since_date" are ignored.
* 2. If "since_rev" is set, it contains either an RCS "dotted" revision
* number (which is of limited use) or a symbolic TAG. Each RCS file
@ -1177,8 +1172,12 @@ select_hrec (hr)
*/
if (since_date)
{
if (hr->date < since_date)
char *ourdate = date_from_time_t (hr->date);
if (RCS_datecmp (ourdate, since_date) < 0)
return (0);
free (ourdate);
}
else if (*since_rev)
{

View File

@ -20,8 +20,6 @@
#include "savecwd.h"
#include <assert.h>
#define FILE_HOLDER ".#cvsxxx"
static char *get_comment PROTO((char *user));
static int add_rev PROTO((char *message, RCSNode *rcs, char *vfile,
char *vers));
@ -655,39 +653,15 @@ add_rev (message, rcs, vfile, vers)
RCS_rewrite (rcs, NULL, NULL);
}
tocvsPath = wrap_tocvs_process_file (vfile);
if (tocvsPath == NULL)
{
/* We play with hard links rather than passing -u to ci to avoid
expanding RCS keywords (see test 106.5 in sanity.sh). */
if (link_file (vfile, FILE_HOLDER) < 0)
{
if (errno == EEXIST)
{
(void) unlink_file (FILE_HOLDER);
(void) link_file (vfile, FILE_HOLDER);
}
else
{
ierrno = errno;
fperror (logfp, 0, ierrno,
"ERROR: cannot create link to %s", vfile);
error (0, ierrno, "ERROR: cannot create link to %s", vfile);
return (1);
}
}
}
status = RCS_checkin (rcs, tocvsPath == NULL ? vfile : tocvsPath,
message, vbranch,
(RCS_FLAGS_QUIET
(RCS_FLAGS_QUIET | RCS_FLAGS_KEEPFILE
| (use_file_modtime ? RCS_FLAGS_MODTIME : 0)));
ierrno = errno;
if (tocvsPath == NULL)
rename_file (FILE_HOLDER, vfile);
else
if (unlink_file_dir (tocvsPath) < 0)
error (0, errno, "cannot remove %s", tocvsPath);
if ((tocvsPath != NULL) && (unlink_file_dir (tocvsPath) < 0))
error (0, errno, "cannot remove %s", tocvsPath);
if (status)
{

View File

@ -41,6 +41,12 @@ int quiet = 0;
int trace = 0;
int noexec = 0;
int logoff = 0;
/* Set if we should be writing CVSADM directories at top level. At
least for now we'll make the default be off (the CVS 1.9, not CVS
1.9.2, behavior). */
int top_level_admin = 0;
mode_t cvsumask = UMASK_DFLT;
char *CurDir;
@ -108,7 +114,7 @@ static const struct cmd
{ "rdiff", "patch", "pa", patch },
{ "release", "re", "rel", release },
{ "remove", "rm", "delete", cvsremove },
{ "status", "st", "stat", status },
{ "status", "st", "stat", cvsstatus },
{ "rtag", "rt", "rfreeze", rtag },
{ "tag", "ta", "freeze", cvstag },
{ "unedit", NULL, NULL, unedit },
@ -281,6 +287,10 @@ lookup_command_attribute (cmd_name)
}
/* The following commands do not use a checked-out working
directory. We conservatively assume that everything else does.
Feel free to add to this list if you are _certain_ something
something doesn't use the WD. */
if ((strcmp (cmd_name, "checkout") != 0) &&
(strcmp (cmd_name, "init") != 0) &&
(strcmp (cmd_name, "login") != 0) &&
@ -296,8 +306,10 @@ lookup_command_attribute (cmd_name)
/* The following commands do not modify the repository; we
conservatively assume that everything else does. Feel free to
add to this list if you are _certain_ something is safe. */
if ((strcmp (cmd_name, "checkout") != 0) &&
if ((strcmp (cmd_name, "annotate") != 0) &&
(strcmp (cmd_name, "checkout") != 0) &&
(strcmp (cmd_name, "diff") != 0) &&
(strcmp (cmd_name, "rdiff") != 0) &&
(strcmp (cmd_name, "update") != 0) &&
(strcmp (cmd_name, "history") != 0) &&
(strcmp (cmd_name, "editors") != 0) &&
@ -967,20 +979,37 @@ char *
Make_Date (rawdate)
char *rawdate;
{
struct tm *ftm;
time_t unixtime;
char date[MAXDATELEN];
char *ret;
unixtime = get_date (rawdate, (struct timeb *) NULL);
if (unixtime == (time_t) - 1)
error (1, 0, "Can't parse date/time: %s", rawdate);
return date_from_time_t (unixtime);
}
/* Convert a time_t to an RCS format date. This is mainly for the
use of "cvs history", because the CVSROOT/history file contains
time_t format dates; most parts of CVS will want to avoid using
time_t's directly, and instead use RCS_datecmp, Make_Date, &c.
Assuming that the time_t is in GMT (as it generally should be),
then the result will be in GMT too.
Returns a newly malloc'd string. */
char *
date_from_time_t (unixtime)
time_t unixtime;
{
struct tm *ftm;
char date[MAXDATELEN];
char *ret;
ftm = gmtime (&unixtime);
if (ftm == NULL)
/* This is a system, like VMS, where the system clock is in local
time. Hopefully using localtime here matches the "zero timezone"
hack I added to get_date. */
hack I added to get_date (get_date of course being the relevant
issue for Make_Date, and for history.c too I think). */
ftm = localtime (&unixtime);
(void) sprintf (date, DATEFORM,

View File

@ -283,6 +283,11 @@ static const char *const config_contents[] = {
"# Set `PreservePermissions' to `yes' to save file status information\n",
"# in the repository.\n",
"#PreservePermissions=no\n",
"\n",
"# Set `TopLevelAdmin' to `yes' to create a CVS directory at the top\n",
"# level of the new working directory when using the `cvs checkout'\n",
"# command.\n",
"#TopLevelAdmin=no\n",
NULL
};

View File

@ -15,13 +15,12 @@
* or the configure script directly. Sorry.
*/
/*
* For portability and heterogeneity reasons, CVS is shipped by
* default using my own text-file version of the ndbm database library
* in the src/myndbm.c file. If you want better performance and are
* not concerned about heterogeneous hosts accessing your modules
* file, turn this option off.
*/
/* By default, CVS stores its modules and other such items in flat
text files (MY_NDBM enables this). Turning off MY_NDBM causes CVS
to look for a system-supplied ndbm database library and use it
instead. That may speed things up, but the default setting
generally works fine too. */
#ifndef MY_NDBM
#define MY_NDBM
#endif

View File

@ -346,6 +346,18 @@ warning: this CVS does not support PreservePermissions");
goto error_return;
}
}
else if (strcmp (line, "TopLevelAdmin") == 0)
{
if (strcmp (p, "no") == 0)
top_level_admin = 0;
else if (strcmp (p, "yes") == 0)
top_level_admin = 1;
else
{
error (0, 0, "unrecognized value '%s' for TopLevelAdmin", p);
goto error_return;
}
}
else
{
/* We may be dealing with a keyword which was added in a

File diff suppressed because it is too large Load Diff

View File

@ -154,6 +154,10 @@ struct rcsversnode
List *other;
/* Newphrase fields from delta nodes. */
List *other_delta;
#ifdef PRESERVE_PERMISSIONS_SUPPORT
/* Hard link information for each revision. */
List *hardlinks;
#endif
};
typedef struct rcsversnode RCSVers;
@ -185,6 +189,9 @@ char *RCS_check_kflag PROTO((const char *arg));
char *RCS_getdate PROTO((RCSNode * rcs, char *date, int force_tag_match));
char *RCS_gettag PROTO((RCSNode * rcs, char *symtag, int force_tag_match,
int *simple_tag));
int RCS_exist_rev PROTO((RCSNode *rcs, char *rev));
int RCS_exist_tag PROTO((RCSNode *rcs, char *tag));
char *RCS_tag2rev PROTO((RCSNode *rcs, char *tag));
char *RCS_getversion PROTO((RCSNode * rcs, char *tag, char *date,
int force_tag_match, int *simple_tag));
char *RCS_magicrev PROTO((RCSNode *rcs, char *rev));
@ -196,9 +203,11 @@ int RCS_datecmp PROTO((char *date1, char *date2));
time_t RCS_getrevtime PROTO((RCSNode * rcs, char *rev, char *date, int fudge));
List *RCS_symbols PROTO((RCSNode *rcs));
void RCS_check_tag PROTO((const char *tag));
int RCS_valid_rev PROTO ((char *rev));
List *RCS_getlocks PROTO((RCSNode *rcs));
void freercsnode PROTO((RCSNode ** rnodep));
char *RCS_getbranch PROTO((RCSNode * rcs, char *tag, int force_tag_match));
char *RCS_branch_head PROTO ((RCSNode *rcs, char *rev));
int RCS_isdead PROTO((RCSNode *, const char *));
char *RCS_getexpand PROTO ((RCSNode *));

View File

@ -11,6 +11,8 @@
#include "cvs.h"
#include <assert.h>
#include <stdio.h>
#include "diffrun.h"
/* This file, rcs.h, and rcs.c, together sometimes known as the "RCS
library", are intended to define our interface to RCS files.
@ -75,6 +77,11 @@ static void call_diff_setup PROTO ((const char *prog));
static int call_diff PROTO ((char *out));
static int call_diff3 PROTO ((char *out));
static void call_diff_write_output PROTO((const char *, size_t));
static void call_diff_flush_output PROTO((void));
static void call_diff_write_stdout PROTO((const char *));
static void call_diff_error PROTO((const char *, const char *, const char *));
/* VARARGS */
static void
call_diff_setup (prog)
@ -132,51 +139,92 @@ call_diff_add_arg (s)
call_diff_argv[call_diff_argc] = (char *) 0;
}
/* diff_run is imported from libdiff.a. */
extern int diff_run PROTO ((int argc, char **argv, char *out));
/* Callback function for the diff library to write data to the output
file. This is used when we are producing output to stdout. */
static void
call_diff_write_output (text, len)
const char *text;
size_t len;
{
cvs_output (text, len);
}
/* Call back function for the diff library to flush the output file.
This is used when we are producing output to stdout. */
static void
call_diff_flush_output ()
{
cvs_flushout ();
}
/* Call back function for the diff library to write to stdout. */
static void
call_diff_write_stdout (text)
const char *text;
{
cvs_output (text, 0);
}
/* Call back function for the diff library to write to stderr. */
static void
call_diff_error (format, a1, a2)
const char *format;
const char *a1;
const char *a2;
{
/* FIXME: Should we somehow indicate that this error is coming from
the diff library? */
error (0, 0, format, a1, a2);
}
/* This set of callback functions is used if we are sending the diff
to stdout. */
static struct diff_callbacks call_diff_stdout_callbacks =
{
call_diff_write_output,
call_diff_flush_output,
call_diff_write_stdout,
call_diff_error
};
/* This set of callback functions is used if we are sending the diff
to a file. */
static struct diff_callbacks call_diff_file_callbacks =
{
(void (*) PROTO((const char *, size_t))) NULL,
(void (*) PROTO((void))) NULL,
call_diff_write_stdout,
call_diff_error
};
static int
call_diff (out)
char *out;
{
/* Try to keep the out-of-order bugs at bay (protocol_pipe for cvs_output
with has "Index: foo" and such; stdout and/or stderr for diff's
output). I think the only reason that this used to not be such
a problem is that the time spent on the fork() and exec() of diff
slowed us down enough to let the "Index:" make it through first.
The real fix, of course, will be to have the diff library do all
its output through callbacks (which CVS will supply as cvs_output
and cvs_outerr). */
sleep (1);
if (out == RUN_TTY)
return diff_run (call_diff_argc, call_diff_argv, NULL);
return diff_run (call_diff_argc, call_diff_argv, NULL,
&call_diff_stdout_callbacks);
else
return diff_run (call_diff_argc, call_diff_argv, out);
return diff_run (call_diff_argc, call_diff_argv, out,
&call_diff_file_callbacks);
}
extern int diff3_run PROTO ((int argc, char **argv, char *out));
static int
call_diff3 (out)
char *out;
{
/* Try to keep the out-of-order bugs at bay (protocol_pipe for cvs_output
with has "Index: foo" and such; stdout and/or stderr for diff's
output). I think the only reason that this used to not be such
a problem is that the time spent on the fork() and exec() of diff
slowed us down enough to let the "Index:" make it through first.
The real fix, of course, will be to have the diff library do all
its output through callbacks (which CVS will supply as cvs_output
and cvs_outerr). */
sleep (1);
if (out == RUN_TTY)
return diff3_run (call_diff_argc, call_diff_argv, NULL);
return diff3_run (call_diff_argc, call_diff_argv, NULL,
&call_diff_stdout_callbacks);
else
return diff3_run (call_diff_argc, call_diff_argv, out);
return diff3_run (call_diff_argc, call_diff_argv, out,
&call_diff_file_callbacks);
}

View File

@ -13,6 +13,9 @@
#include "fileattr.h"
#include "edit.h"
#ifdef CLIENT_SUPPORT
static int do_argument_proc PROTO((Node * p, void *closure));
#endif
static int do_dir_proc PROTO((Node * p, void *closure));
static int do_file_proc PROTO((Node * p, void *closure));
static void addlist PROTO((List ** listp, char *key));
@ -58,6 +61,24 @@ struct frame_and_entries {
List *entries;
};
#ifdef CLIENT_SUPPORT
/* This is a callback to send "Argument" commands to the server in the
case we've done a "cvs update" or "cvs commit" in a top-level
directory where there is no CVSADM directory. */
static int
do_argument_proc (p, closure)
Node *p;
void *closure;
{
char *dir = p->key;
send_to_server ("Argument ", 0);
send_to_server (dir, 0);
send_to_server ("\012", 1);
return 0;
}
#endif
/* Start a recursive command.
Command line arguments (ARGC, ARGV) dictate the directories and
@ -175,6 +196,19 @@ start_recursion (fileproc, filesdoneproc, direntproc, dirleaveproc, callerdat,
"there is no version here; run '%s checkout' first",
program_name);
}
#ifdef CLIENT_SUPPORT
else if (client_active && server_started)
{
/* In the the case "cvs update foo bar baz", a call to
send_file_names in update.c will have sent the
appropriate "Argument" commands to the server. In
this case, that won't have happened, so we need to
do it here. While this example uses "update", this
generalizes to other commands. */
err += walklist (dirlist, do_argument_proc, NULL);
}
#endif
}
else
addlist (&dirlist, ".");
@ -586,7 +620,6 @@ do_dir_proc (p, closure)
char *newrepos;
List *sdirlist;
char *srepository;
char *cp;
Dtype dir_return = R_PROCESS;
int stripped_dot = 0;
int err = 0;
@ -790,16 +823,8 @@ but CVS uses %s for its own purposes; skipping %s directory",
repository = srepository;
}
/* Put back update_dir. I think this is the same as just setting
update_dir back to saved_update_dir, but there are a few cases I'm
not sure about (in particular, if DIR is "." and update_dir is
not ""), so for conservatism I'm leaving this here. */
cp = last_component (update_dir);
if (cp > update_dir)
cp[-1] = '\0';
else
update_dir[0] = '\0';
free (saved_update_dir);
free (update_dir);
update_dir = saved_update_dir;
return (err);
}

View File

@ -477,7 +477,7 @@ pretag_proc(repository, filter)
run_arg (delete_flag ? "del" : force_tag_move ? "mov" : "add");
run_arg (repository);
walklist(tlist, pretag_list_proc, NULL);
return (run_exec(RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL|RUN_REALLY));
return (run_exec (RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL));
}
static void

File diff suppressed because it is too large Load Diff

View File

@ -42,8 +42,20 @@ static Key_schedule sched;
#ifdef HAVE_GSSAPI
#include <netdb.h>
#ifdef HAVE_GSSAPI_H
#include <gssapi.h>
#endif
#ifdef HAVE_GSSAPI_GSSAPI_H
#include <gssapi/gssapi.h>
#endif
#ifdef HAVE_GSSAPI_GSSAPI_GENERIC_H
#include <gssapi/gssapi_generic.h>
#endif
#ifndef HAVE_GSS_C_NT_HOSTBASED_SERVICE
#define GSS_C_NT_HOSTBASED_SERVICE gss_nt_service_name
#endif
/* We use Kerberos 5 routines to map the GSSAPI credential to a user
name. */
@ -366,7 +378,8 @@ mkdir_p (dir)
int saved_errno = errno;
if (saved_errno != EEXIST
&& (saved_errno != EACCES || !isdir (q)))
&& ((saved_errno != EACCES && saved_errno != EROFS)
|| !isdir (q)))
{
retval = saved_errno;
goto done;
@ -635,6 +648,18 @@ server_pathname_check (path)
and is unlikely to do us any good here. It also is probably capable
of being a security hole in the anonymous readonly case. */
if (isabsolute (path))
/* Giving an error is actually kind of a cop-out, in the sense
that it would be nice for "cvs co -d /foo/bar/baz" to work.
A quick fix in the server would be requiring Max-dotdot of
at least one if pathnames are absolute, and then putting
/abs/foo/bar/baz in the temp dir beside the /d/d/d stuff.
A cleaner fix in the server might be to decouple the
pathnames we pass back to the client from pathnames in our
temp directory (this would also probably remove the need
for Max-dotdot). A fix in the client would have the client
turn it into "cd /foo/bar; cvs co -d baz" (more or less).
This probably has some problems with pathnames which appear
in messages. */
error (1, 0, "absolute pathname `%s' illegal for server", path);
if (pathname_levels (path) > max_dotdot_limit)
{
@ -2256,6 +2281,9 @@ error \n");
/* We shouldn't have any partial lines from cvs_output and
cvs_outerr, but we handle them here in case there is a bug. */
/* FIXME: appending a newline, rather than using "MT" as we
do in the child process, is probably not really a very good
way to "handle" them. */
if (! buf_empty_p (saved_output))
{
buf_append_char (saved_output, '\n');
@ -2326,6 +2354,19 @@ error \n");
exitstatus = (*command) (argument_count, argument_vector);
/* Output any partial lines. If the client doesn't support
"MT", we just throw out the partial line, like old versions
of CVS did, since the protocol can't support this. */
if (supported_response ("MT") && ! buf_empty_p (saved_output))
{
buf_output0 (protocol, "MT text ");
buf_append_buffer (protocol, saved_output);
buf_output (protocol, "\n", 1);
buf_send_counted (protocol);
}
/* For now we just discard partial lines on stderr. I suspect
that CVS can't write such lines unless there is a bug. */
/*
* When we exit, that will close the pipes, giving an EOF to
* the parent.
@ -2840,8 +2881,9 @@ server_register (name, version, timestamp, options, tag, date, conflict)
(void) fprintf (stderr,
"%c-> server_register(%s, %s, %s, %s, %s, %s, %s)\n",
(server_active) ? 'S' : ' ', /* silly */
name, version, timestamp, options, tag ? tag : "",
date ? date : "", conflict ? conflict : "");
name, version, timestamp ? timestamp : "", options,
tag ? tag : "", date ? date : "",
conflict ? conflict : "");
}
if (entries_line != NULL)
@ -3071,21 +3113,21 @@ static void
serve_remove (arg)
char *arg;
{
do_cvs_command ("cvsremove", cvsremove);
do_cvs_command ("remove", cvsremove);
}
static void
serve_status (arg)
char *arg;
{
do_cvs_command ("status", status);
do_cvs_command ("status", cvsstatus);
}
static void
serve_rdiff (arg)
char *arg;
{
do_cvs_command ("patch", patch);
do_cvs_command ("rdiff", patch);
}
static void
@ -3354,6 +3396,17 @@ server_modtime (finfo, vers_ts)
/* See server.h for description. */
#if defined (USE_PROTOTYPES) ? USE_PROTOTYPES : defined (__STDC__)
/* Need to prototype because mode_t might be smaller than int. */
void
server_updated (
struct file_info *finfo,
Vers_TS *vers,
enum server_updated_arg4 updated,
mode_t mode,
unsigned char *checksum,
struct buffer *filebuf)
#else
void
server_updated (finfo, vers, updated, mode, checksum, filebuf)
struct file_info *finfo;
@ -3362,6 +3415,7 @@ server_updated (finfo, vers, updated, mode, checksum, filebuf)
mode_t mode;
unsigned char *checksum;
struct buffer *filebuf;
#endif
{
if (noexec)
{
@ -3580,7 +3634,7 @@ CVS server internal error: unhandled case in server_updated");
if ((updated == SERVER_UPDATED
|| updated == SERVER_PATCHED
|| updated == SERVER_RCS_DIFF)
&& filebuf != NULL
&& filebuf == NULL
/* But if we are joining, we'll need the file when we call
join_file. */
&& !joining ())
@ -4779,25 +4833,23 @@ check_password (username, password, repository)
/* No cvs password found, so try /etc/passwd. */
const char *found_passwd = NULL;
#ifdef HAVE_GETSPNAM
struct spwd *pw;
pw = getspnam (username);
if (pw != NULL)
{
found_passwd = pw->sp_pwdp;
}
#else
struct passwd *pw;
#ifdef HAVE_GETSPNAM
struct spwd *spw;
pw = getpwnam (username);
if (pw != NULL)
spw = getspnam (username);
if (spw != NULL)
{
found_passwd = spw->sp_pwdp;
}
#endif
if (found_passwd == NULL && (pw = getpwnam (username)) != NULL)
{
found_passwd = pw->pw_passwd;
}
#endif
if (pw == NULL)
if (found_passwd == NULL)
{
printf ("E Fatal error, aborting.\n\
error 0 %s: no such user\n", username);
@ -4815,8 +4867,9 @@ error 0 %s: no such user\n", username);
exit (EXIT_FAILURE);
}
if (found_passwd && *found_passwd)
if (*found_passwd)
{
/* user exists and has a password */
host_user = ((! strcmp (found_passwd,
crypt (password, found_passwd)))
? username : NULL);
@ -4824,11 +4877,14 @@ error 0 %s: no such user\n", username);
}
else if (password && *password)
{
/* user exists and has no system password, but we got
one as parameter */
host_user = username;
goto handle_return;
}
else
{
/* user exists but has no password at all */
host_user = NULL;
goto handle_return;
}
@ -5186,7 +5242,7 @@ gserver_authenticate_connection ()
tok_in.value = buf;
tok_in.length = strlen (buf);
if (gss_import_name (&stat_min, &tok_in, gss_nt_service_name,
if (gss_import_name (&stat_min, &tok_in, GSS_C_NT_HOSTBASED_SERVICE,
&server_name) != GSS_S_COMPLETE)
error (1, 0, "could not import GSSAPI service name %s", buf);
@ -5587,7 +5643,7 @@ cvs_output_binary (str, len)
if (error_use_protocol)
buf = buf_to_net;
else if (server_active)
else
buf = protocol;
if (!supported_response ("Mbinary"))

View File

@ -31,7 +31,7 @@ static const char *const status_usage[] =
};
int
status (argc, argv)
cvsstatus (argc, argv)
int argc;
char **argv;
{

View File

@ -275,8 +275,17 @@ check_fileproc (callerdat, finfo)
error (0, 0, "nothing known about %s", finfo->file);
return (1);
}
p->data = RCS_getversion(vers->srcfile, numtag, date, force_tag_match,
(int *) NULL);
/* Here we duplicate the calculation in tag_fileproc about which
version we are going to tag. There probably are some subtle races
(e.g. numtag is "foo" which gets moved between here and
tag_fileproc). */
if (numtag == NULL && date == NULL)
p->data = xstrdup (vers->vn_user);
else
p->data = RCS_getversion (vers->srcfile, numtag, date,
force_tag_match, NULL);
if (p->data != NULL)
{
int addit = 1;
@ -377,7 +386,7 @@ pretag_proc(repository, filter)
run_arg (delete_flag ? "del" : force_tag_move ? "mov" : "add");
run_arg (repository);
walklist(tlist, pretag_list_proc, NULL);
return (run_exec(RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL|RUN_REALLY));
return (run_exec (RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL));
}
static void

View File

@ -530,7 +530,6 @@ get_linkinfo_proc (callerdat, finfo)
hlinfo->status = (Ctype) 0; /* is this dumb? */
hlinfo->checked_out = 0;
hlinfo->links = NULL;
linkp->data = (char *) hlinfo;
@ -1639,8 +1638,6 @@ patch_file (finfo, vers_ts, docheckout, file_info, checksum)
{
char *diff_options;
/* FIXME: It might be better to come up with a diff library
which can be shared with the diffutils. */
/* If the client does not support the Rcs-diff command, we
send a context diff, and the client must invoke patch.
That approach was problematical for various reasons. The
@ -1649,8 +1646,10 @@ patch_file (finfo, vers_ts, docheckout, file_info, checksum)
program. */
if (! rcs_diff_patches)
{
/* We use -c, not -u, because we have no way of knowing
which DIFF is in use. */
/* We use -c, not -u, because that is what CVS has
traditionally used. Kind of a moot point, now that
Rcs-diff is preferred, so there is no point in making
the compatibility issues worse. */
diff_options = "-c";
}
else
@ -1922,14 +1921,21 @@ merge_file (finfo, vers)
if (strcmp (vers->options, "-V4") == 0)
vers->options[0] = '\0';
(void) time (&last_register_time);
/* This file is the result of a merge, which means that it has
been modified. We use a special timestamp string which will
not compare equal to any actual timestamp. */
{
char *cp = 0;
if (status)
{
(void) time (&last_register_time);
cp = time_stamp (finfo->file);
Register (finfo->entries, finfo->file, vers->vn_rcs, vers->ts_rcs, vers->options,
vers->tag, vers->date, cp);
}
Register (finfo->entries, finfo->file, vers->vn_rcs,
"Result of merge", vers->options, vers->tag,
vers->date, cp);
if (cp)
free (cp);
}
@ -2428,25 +2434,27 @@ join_file (finfo, vers)
free (rev1);
free (rev2);
#ifdef SERVER_SUPPORT
/*
* If we're in server mode, then we need to re-register the file
* even if there were no conflicts (status == 0).
* This tells server_updated() to send the modified file back to
* the client.
*/
if (status == 1 || (status == 0 && server_active))
#else
if (status == 1)
#endif
/* The file has changed, but if we just checked it out it may
still have the same timestamp it did when it was first
registered above in checkout_file. We register it again with a
dummy timestamp to make sure that later runs of CVS will
recognize that it has changed.
We don't actually need to register again if we called
RCS_checkout above, and we aren't running as the server.
However, that is not the normal case, and calling Register
again won't cost much in that case. */
{
char *cp = 0;
if (status)
{
(void) time (&last_register_time);
cp = time_stamp (finfo->file);
Register (finfo->entries, finfo->file,
vers->vn_rcs, vers->ts_rcs, vers->options,
vers->tag, vers->date, cp);
}
Register (finfo->entries, finfo->file, vers->vn_rcs,
"Result of merge", vers->options, vers->tag,
vers->date, cp);
if (cp)
free(cp);
}
@ -2494,8 +2502,8 @@ special_file_mismatch (finfo, rev1, rev2)
dev_t rev1_dev, rev2_dev;
char *rev1_symlink = NULL;
char *rev2_symlink = NULL;
char *rev1_hardlinks = NULL;
char *rev2_hardlinks = NULL;
List *rev1_hardlinks;
List *rev2_hardlinks;
int check_uids, check_gids, check_modes;
int result;
@ -2533,7 +2541,7 @@ special_file_mismatch (finfo, rev1, rev2)
if (S_ISBLK (rev1_mode) || S_ISCHR (rev1_mode))
rev1_dev = sb.st_rdev;
}
rev1_hardlinks = list_files_linked_to (finfo->file);
rev1_hardlinks = list_linked_files_on_disk (finfo->file);
}
else
{
@ -2584,11 +2592,9 @@ special_file_mismatch (finfo, rev1, rev2)
finfo->file, rev1, ftype);
}
n = findnode (vp->other_delta, "hardlinks");
if (n == NULL)
rev1_hardlinks = xstrdup ("");
else
rev1_hardlinks = xstrdup (n->data);
rev1_hardlinks = vp->hardlinks;
if (rev1_hardlinks == NULL)
rev1_hardlinks = getlist();
}
}
@ -2608,7 +2614,7 @@ special_file_mismatch (finfo, rev1, rev2)
if (S_ISBLK (rev2_mode) || S_ISCHR (rev2_mode))
rev2_dev = sb.st_rdev;
}
rev2_hardlinks = list_files_linked_to (finfo->file);
rev2_hardlinks = list_linked_files_on_disk (finfo->file);
}
else
{
@ -2659,11 +2665,9 @@ special_file_mismatch (finfo, rev1, rev2)
finfo->file, rev2, ftype);
}
n = findnode (vp->other_delta, "hardlinks");
if (n == NULL)
rev2_hardlinks = xstrdup ("");
else
rev2_hardlinks = xstrdup (n->data);
rev2_hardlinks = vp->hardlinks;
if (rev2_hardlinks == NULL)
rev2_hardlinks = getlist();
}
}
@ -2744,7 +2748,7 @@ special_file_mismatch (finfo, rev1, rev2)
}
/* Compare hard links. */
if (strcmp (rev1_hardlinks, rev2_hardlinks) != 0)
if (compare_linkage_lists (rev1_hardlinks, rev2_hardlinks) == 0)
{
error (0, 0, "%s: hard linkage of %s and %s do not match",
finfo->file,
@ -2759,9 +2763,9 @@ special_file_mismatch (finfo, rev1, rev2)
if (rev2_symlink != NULL)
free (rev2_symlink);
if (rev1_hardlinks != NULL)
free (rev1_hardlinks);
dellist (&rev1_hardlinks);
if (rev2_hardlinks != NULL)
free (rev2_hardlinks);
dellist (&rev2_hardlinks);
return result;
#else

View File

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

View File

@ -395,6 +395,11 @@ wrap_add (line, isTemp)
*line='\0';
switch(opt){
case 'f':
/* Before this is reenabled, need to address the problem in
commit.c (see http://www.cyclic.com/cvs/dev-wrap.txt). */
error (1, 0,
"-t/-f wrappers not supported by this version of CVS");
if(e.fromcvsFilter)
free(e.fromcvsFilter);
/* FIXME: error message should say where the bad value
@ -404,6 +409,11 @@ wrap_add (line, isTemp)
error (1, 0, "Correct above errors first");
break;
case 't':
/* Before this is reenabled, need to address the problem in
commit.c (see http://www.cyclic.com/cvs/dev-wrap.txt). */
error (1, 0,
"-t/-f wrappers not supported by this version of CVS");
if(e.tocvsFilter)
free(e.tocvsFilter);
/* FIXME: error message should say where the bad value