summaryrefslogtreecommitdiff
path: root/gnu/usr.bin/cvs
diff options
context:
space:
mode:
Diffstat (limited to 'gnu/usr.bin/cvs')
-rw-r--r--gnu/usr.bin/cvs/Makefile.in2
-rw-r--r--gnu/usr.bin/cvs/configure116
-rw-r--r--gnu/usr.bin/cvs/configure.in31
-rw-r--r--gnu/usr.bin/cvs/src/Makefile.in3
-rw-r--r--gnu/usr.bin/cvs/src/checkout.c15
-rw-r--r--gnu/usr.bin/cvs/src/commit.c7
-rw-r--r--gnu/usr.bin/cvs/src/cvs.h2
-rw-r--r--gnu/usr.bin/cvs/src/main.c14
-rw-r--r--gnu/usr.bin/cvs/src/mkmodules.c5
-rw-r--r--gnu/usr.bin/cvs/src/parseinfo.c12
-rw-r--r--gnu/usr.bin/cvs/src/rcs.c134
-rw-r--r--gnu/usr.bin/cvs/src/rcscmds.c108
-rw-r--r--gnu/usr.bin/cvs/src/server.c30
-rw-r--r--gnu/usr.bin/cvs/src/update.c51
14 files changed, 409 insertions, 121 deletions
diff --git a/gnu/usr.bin/cvs/Makefile.in b/gnu/usr.bin/cvs/Makefile.in
index 8a5258ec937..970a5196745 100644
--- a/gnu/usr.bin/cvs/Makefile.in
+++ b/gnu/usr.bin/cvs/Makefile.in
@@ -228,7 +228,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
diff --git a/gnu/usr.bin/cvs/configure b/gnu/usr.bin/cvs/configure
index 36b6f2cc13c..2d09bf31f89 100644
--- a/gnu/usr.bin/cvs/configure
+++ b/gnu/usr.bin/cvs/configure
@@ -3132,20 +3132,20 @@ fi
echo "default place for GSSAPI is $GSSAPI"
-echo $ac_n "checking for gssapi.h""... $ac_c" 1>&6
-echo "configure:3137: checking for gssapi.h" >&5
hold_cppflags=$CPPFLAGS
CPPFLAGS="$CPPFLAGS -I$GSSAPI/include "
-ac_safe=`echo "gssapi/gssapi.h" | sed 'y%./+-%__p_%'`
-echo $ac_n "checking for gssapi/gssapi.h""... $ac_c" 1>&6
-echo "configure:3142: checking for gssapi/gssapi.h" >&5
+for ac_hdr in gssapi.h gssapi/gssapi.h gssapi/gssapi_generic.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:3142: checking for $ac_hdr" >&5
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 3147 "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:3152: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
@@ -3164,16 +3164,70 @@ 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 | sed 'y%abcdefghijklmnopqrstuvwxyz./-%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 compile in -lgen""... $ac_c" 1>&6
-echo "configure:3177: checking for compile in -lgen" >&5
+ 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 3196 "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 3212 "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 compile in -lgen""... $ac_c" 1>&6
+echo "configure:3231: checking for compile in -lgen" >&5
ac_lib_var=`echo gen'_'compile | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
@@ -3181,7 +3235,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-lgen $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 3185 "configure"
+#line 3239 "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
@@ -3192,7 +3246,7 @@ int main() {
compile()
; return 0; }
EOF
-if { (eval echo configure:3196: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:3250: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
@@ -3219,12 +3273,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"
@@ -3245,12 +3295,12 @@ EOF
fi
echo $ac_n "checking for gethostname""... $ac_c" 1>&6
-echo "configure:3249: checking for gethostname" >&5
+echo "configure:3299: checking for gethostname" >&5
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 3254 "configure"
+#line 3304 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char gethostname(); below. */
@@ -3273,7 +3323,7 @@ gethostname();
; return 0; }
EOF
-if { (eval echo configure:3277: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:3327: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
rm -rf conftest*
eval "ac_cv_func_gethostname=yes"
else
@@ -3352,12 +3402,12 @@ if test "$enable_server" = yes; then
for ac_func in crypt
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:3356: checking for $ac_func" >&5
+echo "configure:3406: checking for $ac_func" >&5
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 3361 "configure"
+#line 3411 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -3380,7 +3430,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:3384: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:3434: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
rm -rf conftest*
eval "ac_cv_func_$ac_func=yes"
else
@@ -3406,7 +3456,7 @@ done
if test "$ac_cv_func_crypt" = no; then
echo $ac_n "checking for crypt in -lcrypt""... $ac_c" 1>&6
-echo "configure:3410: checking for crypt in -lcrypt" >&5
+echo "configure:3460: checking for crypt in -lcrypt" >&5
ac_lib_var=`echo crypt'_'crypt | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
@@ -3414,7 +3464,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-lcrypt $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 3418 "configure"
+#line 3468 "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
@@ -3425,7 +3475,7 @@ int main() {
crypt()
; return 0; }
EOF
-if { (eval echo configure:3429: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:3479: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
@@ -3455,12 +3505,12 @@ fi
for ac_func in crypt
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:3459: checking for $ac_func" >&5
+echo "configure:3509: checking for $ac_func" >&5
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 3464 "configure"
+#line 3514 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -3483,7 +3533,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:3487: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:3537: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
rm -rf conftest*
eval "ac_cv_func_$ac_func=yes"
else
@@ -3523,19 +3573,19 @@ EOF
echo $ac_n "checking for cygwin32""... $ac_c" 1>&6
-echo "configure:3527: checking for cygwin32" >&5
+echo "configure:3577: checking for cygwin32" >&5
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 3532 "configure"
+#line 3582 "configure"
#include "confdefs.h"
int main() {
return __CYGWIN32__;
; return 0; }
EOF
-if { (eval echo configure:3539: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:3589: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ccvs_cv_sys_cygwin32=yes
else
diff --git a/gnu/usr.bin/cvs/configure.in b/gnu/usr.bin/cvs/configure.in
index ce4f852a498..dd6172d7956 100644
--- a/gnu/usr.bin/cvs/configure.in
+++ b/gnu/usr.bin/cvs/configure.in
@@ -268,18 +268,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
diff --git a/gnu/usr.bin/cvs/src/Makefile.in b/gnu/usr.bin/cvs/src/Makefile.in
index 471d9dd8724..af0c72d2f80 100644
--- a/gnu/usr.bin/cvs/src/Makefile.in
+++ b/gnu/usr.bin/cvs/src/Makefile.in
@@ -180,6 +180,9 @@ cvsbug: cvsbug.sh $(srcdir)/version.c
$(OBJECTS): $(HEADERS) options.h
+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
$(CC) $(CPPFLAGS) $(INCLUDES) ${ZLIB_INCLUDES} $(DEFS) $(CFLAGS) -c $(srcdir)/zlib.c
diff --git a/gnu/usr.bin/cvs/src/checkout.c b/gnu/usr.bin/cvs/src/checkout.c
index c866abf8bb3..c6a81221d9d 100644
--- a/gnu/usr.bin/cvs/src/checkout.c
+++ b/gnu/usr.bin/cvs/src/checkout.c
@@ -886,11 +886,24 @@ internal error: %s doesn't start with %s in checkout_proc",
build_one_dir whenever the -d command option was specified
to checkout. */
- if (! where_is_absolute)
+ 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
}
diff --git a/gnu/usr.bin/cvs/src/commit.c b/gnu/usr.bin/cvs/src/commit.c
index 2201407a7d3..75d2e5ae7b6 100644
--- a/gnu/usr.bin/cvs/src/commit.c
+++ b/gnu/usr.bin/cvs/src/commit.c
@@ -1434,9 +1434,10 @@ commit_filesdoneproc (callerdat, err, repository, update_dir, entries)
Remove anything after the `CVSROOT' component -- this is
necessary when committing in a subdirectory of CVSROOT. */
char *admin_dir = xstrdup (repository);
- assert (admin_dir[p - repository + strlen ("CVSROOT")] == '\0'
- || admin_dir[p - repository + strlen ("CVSROOT")] == '/');
- admin_dir[p - repository + strlen ("CVSROOT")] = '\0';
+ 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);
diff --git a/gnu/usr.bin/cvs/src/cvs.h b/gnu/usr.bin/cvs/src/cvs.h
index 49dbded4358..c2d9efa0c8e 100644
--- a/gnu/usr.bin/cvs/src/cvs.h
+++ b/gnu/usr.bin/cvs/src/cvs.h
@@ -389,6 +389,8 @@ extern int noexec; /* Don't modify disk anywhere */
extern int readonlyfs; /* fail on all write locks; succeed all read locks */
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
diff --git a/gnu/usr.bin/cvs/src/main.c b/gnu/usr.bin/cvs/src/main.c
index d2d3824d17e..eca5f4fae4f 100644
--- a/gnu/usr.bin/cvs/src/main.c
+++ b/gnu/usr.bin/cvs/src/main.c
@@ -42,6 +42,12 @@ int trace = 0;
int noexec = 0;
int readonlyfs = 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 *RCS_citag = NULL;
@@ -283,6 +289,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) &&
@@ -298,8 +308,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) &&
diff --git a/gnu/usr.bin/cvs/src/mkmodules.c b/gnu/usr.bin/cvs/src/mkmodules.c
index 2ec62d2aff3..01b0e26bbfd 100644
--- a/gnu/usr.bin/cvs/src/mkmodules.c
+++ b/gnu/usr.bin/cvs/src/mkmodules.c
@@ -284,6 +284,11 @@ static const char *const config_contents[] = {
"# 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",
+ "\n",
"# Set this to the name of a local tag to use in addition to Id\n",
"#tag=OurTag\n",
"\n",
diff --git a/gnu/usr.bin/cvs/src/parseinfo.c b/gnu/usr.bin/cvs/src/parseinfo.c
index 6ae074e4e4f..b2ec65d9a81 100644
--- a/gnu/usr.bin/cvs/src/parseinfo.c
+++ b/gnu/usr.bin/cvs/src/parseinfo.c
@@ -370,6 +370,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
diff --git a/gnu/usr.bin/cvs/src/rcs.c b/gnu/usr.bin/cvs/src/rcs.c
index 65fb0702f6c..a93d7a035ff 100644
--- a/gnu/usr.bin/cvs/src/rcs.c
+++ b/gnu/usr.bin/cvs/src/rcs.c
@@ -1404,7 +1404,7 @@ rcsbuf_getid (rcsbuf, idp)
rcsbuf->ptr = ptr;
return 1;
-#undef my_whitespace;
+#undef my_whitespace
}
/* Read an RCS @-delimited string. Store the result in STRP. */
@@ -4478,6 +4478,9 @@ RCS_checkout (rcs, workfile, rev, nametag, options, sout, pfn, callerdat)
}
}
+ if (free_rev)
+ free (rev);
+
if (log != NULL)
{
free (log);
@@ -4547,9 +4550,25 @@ RCS_checkout (rcs, workfile, rev, nametag, options, sout, pfn, callerdat)
if (islink (workfile))
if (unlink_file (workfile) < 0)
error (1, errno, "cannot remove %s", workfile);
+
ofp = CVS_FOPEN (workfile, expand == KFLAG_B ? "wb" : "w");
+
+ /* If the open failed because the existing workfile was not
+ writable, try to chmod the file and retry the open. */
+ if (ofp == NULL && errno == EACCES
+ && isfile (workfile) && !iswritable (workfile))
+ {
+ xchmod (workfile, 1);
+ ofp = CVS_FOPEN (workfile, expand == KFLAG_B ? "wb" : "w");
+ }
+
if (ofp == NULL)
- error (1, errno, "cannot open %s", workfile);
+ {
+ error (0, errno, "cannot open %s", workfile);
+ if (free_value)
+ free (value);
+ return 1;
+ }
}
if (workfile == NULL && sout == RUN_TTY)
@@ -4581,10 +4600,15 @@ RCS_checkout (rcs, workfile, rev, nametag, options, sout, pfn, callerdat)
while (nleft > 0)
{
if (fwrite (p, 1, nstep, ofp) != nstep)
- error (1, errno, "cannot write %s",
+ {
+ error (0, errno, "cannot write %s",
(workfile != NULL
? workfile
: (sout != RUN_TTY ? sout : "stdout")));
+ if (free_value)
+ free (value);
+ return 1;
+ }
p += nstep;
nleft -= nstep;
if (nleft < nstep)
@@ -4593,13 +4617,19 @@ RCS_checkout (rcs, workfile, rev, nametag, options, sout, pfn, callerdat)
}
}
+ if (free_value)
+ free (value);
+
if (workfile != NULL)
{
int ret;
#ifdef PRESERVE_PERMISSIONS_SUPPORT
if (!special_file && fclose (ofp) < 0)
- error (1, errno, "cannot close %s", workfile);
+ {
+ error (0, errno, "cannot close %s", workfile);
+ return 1;
+ }
if (change_rcs_owner_or_group)
{
@@ -4614,7 +4644,10 @@ RCS_checkout (rcs, workfile, rev, nametag, options, sout, pfn, callerdat)
: sb.st_mode & ~(S_IWRITE | S_IWGRP | S_IWOTH));
#else
if (fclose (ofp) < 0)
- error (1, errno, "cannot close %s", workfile);
+ {
+ error (0, errno, "cannot close %s", workfile);
+ return 1;
+ }
ret = chmod (workfile,
sb.st_mode & ~(S_IWRITE | S_IWGRP | S_IWOTH));
@@ -4632,7 +4665,10 @@ RCS_checkout (rcs, workfile, rev, nametag, options, sout, pfn, callerdat)
!special_file &&
#endif
fclose (ofp) < 0)
- error (1, errno, "cannot close %s", sout);
+ {
+ error (0, errno, "cannot close %s", sout);
+ return 1;
+ }
}
#ifdef PRESERVE_PERMISSIONS_SUPPORT
@@ -4642,11 +4678,6 @@ RCS_checkout (rcs, workfile, rev, nametag, options, sout, pfn, callerdat)
update_hardlink_info (workfile);
#endif
- if (free_value)
- free (value);
- if (free_rev)
- free (rev);
-
return 0;
}
@@ -4973,6 +5004,7 @@ RCS_checkin (rcs, workfile, message, rev, flags)
int status, checkin_quiet, allocated_workfile;
struct tm *ftm;
time_t modtime;
+ int adding_branch = 0;
commitpt = NULL;
@@ -4993,6 +5025,41 @@ RCS_checkin (rcs, workfile, message, rev, flags)
allocated_workfile = 1;
}
+ /* Is the backend file a symbolic link? Follow it and replace the
+ filename with the destination of the link. */
+
+ while (islink (rcs->path))
+ {
+ char *newname;
+#ifdef HAVE_READLINK
+ /* The clean thing to do is probably to have each filesubr.c
+ implement this (with an error if not supported by the
+ platform, in which case islink would presumably return 0).
+ But that would require editing each filesubr.c and so the
+ expedient hack seems to be looking at HAVE_READLINK. */
+ newname = xreadlink (rcs->path);
+#else
+ error (1, 0, "internal error: islink doesn't like readlink");
+#endif
+
+ if (isabsolute (newname))
+ {
+ free (rcs->path);
+ rcs->path = newname;
+ }
+ else
+ {
+ char *oldname = last_component (rcs->path);
+ int dirlen = oldname - rcs->path;
+ char *fullnewname = xmalloc (dirlen + strlen (newname) + 1);
+ strncpy (fullnewname, rcs->path, dirlen);
+ strcpy (fullnewname + dirlen, newname);
+ free (newname);
+ free (rcs->path);
+ rcs->path = fullnewname;
+ }
+ }
+
checkin_quiet = flags & RCS_FLAGS_QUIET;
if (!checkin_quiet)
{
@@ -5267,6 +5334,7 @@ RCS_checkin (rcs, workfile, message, rev, flags)
goto checkin_done;
}
delta->version = RCS_addbranch (rcs, branch);
+ adding_branch = 1;
p = strrchr (branch, '.');
*p = '\0';
tip = xstrdup (branch);
@@ -5312,13 +5380,26 @@ RCS_checkin (rcs, workfile, message, rev, flags)
{
if (! STREQ (nodep->data, delta->author))
{
- error (0, 0, "%s: revision %s locked by %s",
- rcs->path,
- nodep->key, nodep->data);
- status = 1;
- goto checkin_done;
+ /* If we are adding a branch, then leave the old lock around.
+ That is sensible in the sense that when adding a branch,
+ we don't need to use the lock to tell us where to check
+ in. It is fishy in the sense that if it is our own lock,
+ we break it. However, this is the RCS 5.7 behavior (at
+ the end of addbranch in ci.c in RCS 5.7, it calls
+ removelock only if it is our own lock, not someone
+ else's). */
+
+ if (!adding_branch)
+ {
+ error (0, 0, "%s: revision %s locked by %s",
+ rcs->path,
+ nodep->key, nodep->data);
+ status = 1;
+ goto checkin_done;
+ }
}
- delnode (nodep);
+ else
+ delnode (nodep);
}
dtext->version = xstrdup (delta->version);
@@ -6404,6 +6485,18 @@ RCS_delete_revs (rcs, tag1, tag2, inclusive)
goto delrev_done;
}
+ if (after == NULL && before == NULL)
+ {
+ /* The user is trying to delete all revisions. While an
+ RCS file without revisions makes sense to RCS (e.g. the
+ state after "rcs -i"), CVS has never been able to cope with
+ it. So at least for now we just make this an error.
+
+ We don't include rcs->path in the message since "cvs admin"
+ already printed "RCS file:" and the name. */
+ error (1, 0, "attempt to delete all revisions");
+ }
+
/* The conditionals at this point get really hairy. Here is the
general idea:
@@ -6416,8 +6509,6 @@ RCS_delete_revs (rcs, tag1, tag2, inclusive)
RCS_exec_rcsdiff with some changes, like being able
to suppress diagnostic messages and to direct output. */
- assert (before != NULL || after != NULL);
-
if (after != NULL)
{
char *diffbuf;
@@ -8196,7 +8287,7 @@ RCS_copydeltas (rcs, fin, rcsbufin, fout, newdtext, insertpt)
to count the number of RCS revisions for which some special action
is required. */
-int
+static int
count_delta_actions (np, ignore)
Node *np;
void *ignore;
@@ -8536,6 +8627,9 @@ annotate (argc, argv)
}
#endif /* CLIENT_SUPPORT */
+ if (tag != NULL)
+ tag_check_valid (tag, argc, argv, local, 0, "");
+
return start_recursion (annotate_fileproc, (FILESDONEPROC) NULL,
(DIRENTPROC) NULL, (DIRLEAVEPROC) NULL, NULL,
argc, argv, local, W_LOCAL, 0, 1, (char *)NULL,
diff --git a/gnu/usr.bin/cvs/src/rcscmds.c b/gnu/usr.bin/cvs/src/rcscmds.c
index 3086b57e10c..f8892338b42 100644
--- a/gnu/usr.bin/cvs/src/rcscmds.c
+++ b/gnu/usr.bin/cvs/src/rcscmds.c
@@ -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);
}
diff --git a/gnu/usr.bin/cvs/src/server.c b/gnu/usr.bin/cvs/src/server.c
index 0bcc9a225fa..1e024f4c7a8 100644
--- a/gnu/usr.bin/cvs/src/server.c
+++ b/gnu/usr.bin/cvs/src/server.c
@@ -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. */
@@ -3101,7 +3113,7 @@ static void
serve_remove (arg)
char *arg;
{
- do_cvs_command ("cvsremove", cvsremove);
+ do_cvs_command ("remove", cvsremove);
}
static void
@@ -3115,7 +3127,7 @@ static void
serve_rdiff (arg)
char *arg;
{
- do_cvs_command ("patch", patch);
+ do_cvs_command ("rdiff", patch);
}
static void
@@ -3384,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;
@@ -3392,6 +3415,7 @@ server_updated (finfo, vers, updated, mode, checksum, filebuf)
mode_t mode;
unsigned char *checksum;
struct buffer *filebuf;
+#endif
{
if (noexec)
{
@@ -5221,7 +5245,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);
diff --git a/gnu/usr.bin/cvs/src/update.c b/gnu/usr.bin/cvs/src/update.c
index fbd4995b009..a376a02c12c 100644
--- a/gnu/usr.bin/cvs/src/update.c
+++ b/gnu/usr.bin/cvs/src/update.c
@@ -1639,8 +1639,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 +1647,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
@@ -1932,14 +1932,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);
}
@@ -2438,25 +2445,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);
}