diff options
Diffstat (limited to 'gnu/usr.bin/cvs')
-rw-r--r-- | gnu/usr.bin/cvs/Makefile.in | 2 | ||||
-rw-r--r-- | gnu/usr.bin/cvs/configure | 116 | ||||
-rw-r--r-- | gnu/usr.bin/cvs/configure.in | 31 | ||||
-rw-r--r-- | gnu/usr.bin/cvs/src/Makefile.in | 3 | ||||
-rw-r--r-- | gnu/usr.bin/cvs/src/checkout.c | 15 | ||||
-rw-r--r-- | gnu/usr.bin/cvs/src/commit.c | 7 | ||||
-rw-r--r-- | gnu/usr.bin/cvs/src/cvs.h | 2 | ||||
-rw-r--r-- | gnu/usr.bin/cvs/src/main.c | 14 | ||||
-rw-r--r-- | gnu/usr.bin/cvs/src/mkmodules.c | 5 | ||||
-rw-r--r-- | gnu/usr.bin/cvs/src/parseinfo.c | 12 | ||||
-rw-r--r-- | gnu/usr.bin/cvs/src/rcs.c | 134 | ||||
-rw-r--r-- | gnu/usr.bin/cvs/src/rcscmds.c | 108 | ||||
-rw-r--r-- | gnu/usr.bin/cvs/src/server.c | 30 | ||||
-rw-r--r-- | gnu/usr.bin/cvs/src/update.c | 51 |
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); } |