summaryrefslogtreecommitdiffstats
path: root/contrib/cvs/src
diff options
context:
space:
mode:
authorobrien <obrien@FreeBSD.org>2008-03-19 14:46:59 +0000
committerobrien <obrien@FreeBSD.org>2008-03-19 14:46:59 +0000
commitc54c20f64254351041b8ea9719450e4d774ac0a5 (patch)
tree0ae354b8af76926a31947d53202545980b36afe4 /contrib/cvs/src
parent5f43f46b30a84be45042a4dd83992110d7588aad (diff)
downloadFreeBSD-src-c54c20f64254351041b8ea9719450e4d774ac0a5.zip
FreeBSD-src-c54c20f64254351041b8ea9719450e4d774ac0a5.tar.gz
Import of 1.11 branch snapshot - using the 10-March-2008 code base.
Diffstat (limited to 'contrib/cvs/src')
-rw-r--r--contrib/cvs/src/ChangeLog269
-rw-r--r--contrib/cvs/src/Makefile.in106
-rw-r--r--contrib/cvs/src/add.c2
-rw-r--r--contrib/cvs/src/classify.c68
-rw-r--r--contrib/cvs/src/client.c46
-rw-r--r--contrib/cvs/src/client.h4
-rw-r--r--contrib/cvs/src/cvs.h1
-rw-r--r--contrib/cvs/src/edit.c6
-rw-r--r--contrib/cvs/src/edit.h4
-rw-r--r--contrib/cvs/src/filesubr.c2
-rw-r--r--contrib/cvs/src/hash.h18
-rw-r--r--contrib/cvs/src/import.c25
-rw-r--r--contrib/cvs/src/lock.c2
-rw-r--r--contrib/cvs/src/log.c12
-rw-r--r--contrib/cvs/src/login.c53
-rw-r--r--contrib/cvs/src/main.c4
-rw-r--r--contrib/cvs/src/mkmodules.c57
-rw-r--r--contrib/cvs/src/modules.c2
-rw-r--r--contrib/cvs/src/parseinfo.c20
-rw-r--r--contrib/cvs/src/rcs.c437
-rw-r--r--contrib/cvs/src/recurse.c5
-rw-r--r--contrib/cvs/src/root.c11
-rw-r--r--contrib/cvs/src/root.h1
-rwxr-xr-xcontrib/cvs/src/sanity.sh1460
-rw-r--r--contrib/cvs/src/server.c49
-rw-r--r--contrib/cvs/src/update.c147
-rw-r--r--contrib/cvs/src/vers_ts.c6
27 files changed, 2024 insertions, 793 deletions
diff --git a/contrib/cvs/src/ChangeLog b/contrib/cvs/src/ChangeLog
index 822f86d..4e7a422 100644
--- a/contrib/cvs/src/ChangeLog
+++ b/contrib/cvs/src/ChangeLog
@@ -1,3 +1,270 @@
+2008-03-10 Mark D. Baushke <mdb@gnu.org>
+
+ * mkmodules.c, parseinfo.c: Update copyright.
+
+ * parseinfo.c (parse_config): Add support for new
+ "IgnoreUnknownConfigKeys" configuration key.
+ * mkmodules.c (config_contents): Add text about the
+ "IgnoreUnknownConfigKeys" option.
+ * sanity.sh (config): Test that IgnoreUnknownConfigKeys=yes works.
+
+2008-01-30 Derek R. Price <derek@ximbiot.com>
+
+ * update.c (join_file): Use local copy to detect deletion conflicts,
+ as opposed to the base revision. Restore freeing of rev2 to its
+ original location. Use simpler conflict message.
+ * sanity.sh: Update to compensate.
+
+2008-01-29 Derek R. Price <derek@ximbiot.com>
+
+ * update.c (join_file): Remove trace that is no longer needed.
+
+2008-01-29 Derek R. Price <derek@ximbiot.com>
+ Paul Edwards <fight.subjugation@gmail.com>
+
+ * update.c (join_file): Detect deletion conflicts.
+ * sanity.sh (join, join4): Adjusted for this fix.
+ (join8, join9): Add new tests for conflicts.
+
+2008-01-27 Mark D. Baushke <mdb@gnu.org>
+
+ * filesubr.c (xreadlink): s/128/BUFSIZ/ avoid magic numbers.
+
+ * client.c (start_rsh_server): Use CVS_SSH for the :extssh:
+ method or fall back to "ssh" as set using the --with-ssh flag to
+ configure.
+
+ * client.h, log.c, main.c, recurse.c, root.c: Update copyright for
+ 2008.
+
+2008-01-24 Mark D. Baushke <mdb@gnu.org>
+
+ * log.c (cvslog): New -n option to revert the -N switch.
+ (log_usage): Add -n to the help string.
+ * main.c (cmds[]): Add "blame" as a synonym for the
+ "annotate" command.
+ * sanity.sh (cvs-log): New tests for 'cvs log -N -n' validation.
+ (ann-10w1blame): Test the 'cvs blame' synonym for annotate.
+ (Patch suggested by "David O'Brien" <obrien@FreeBSD.org>)
+
+ * edit.c (notify_check): Rename to...
+ (cvs_notify_check): ...this to avoid Mac OSX symbol conflicts.
+ * client.h, edit.h, recurse.c: Change all references.
+
+ * client.c (start_rsh_server): Use RSH_DFLT not a hardcoded "rsh"
+ * root.c (parse_cvsroot): Fix parsing for the :extssh: method.
+
+ * sanity.sh (expr_set_DASHDASH): Fix for non-POSIX expr
+ implementations.
+ (CVSROOTDIR): Use 'cvsrootdir' instead of 'cvsroot' to
+ avoid problems on case preserving and/or case insensitive
+ filesystems (e.g., HFS+).
+ (CVSROOT_DIRNAME): Use ${TESTDIR}/${CVSROOTDIR} instead of
+ ${TESTDIR}/cvsroot to avoid filesystem case sensitivity problems.
+ (crerepos-extssh): Clone of crerepos tests, but use the :extssh:
+ method.
+
+2007-12-19 Larry Jones <lawrence.jones@siemens.com>
+
+ * client.c, import.c, lock.c, login.c, mkmodules.c, modules.c,
+ rcs.c, server.c: Fix gcc -Wall warnings.
+
+2007-12-16 Larry Jones <lawrence.jones@siemens.com>
+
+ * rcs.c (HAVE_MMAP): Fall back to stdio if mmap fails.
+
+2007-12-13 Larry Jones <lawrence.jones@siemens.com>
+
+ * rcs.c (rcsbuf_ftell): Avoid potential overflow.
+
+2007-12-12 Larry Jones <lawrence.jones@siemens.com>
+
+ * vers_ts.c (time_stamp): Add warnings for [l]stat failures
+ other than no such file.
+
+2007-08-26 Derek Price <derek@ximbiot.com>
+
+ * mkmodules.c (in_root): Rename to...
+ (in_repository): ...this.
+
+2007-08-26 Larry Jones <lawrence.jones@ugs.com>
+
+ * mkmodules.c (in_root, init): Unmix declarations and code.
+
+2007-08-22 Derek Price <derek@ximbiot.com>
+
+ * add.c (add): Check last component of argument paths instead of the
+ entire argument.
+ * sanity.sh (add-restricted): Test indirect paths to `CVS' dir with
+ add.
+
+ * server.c (serve_init): Remove unnecessary argument to printf style
+ function.
+
+ * mkmodules.c (in_root): New function.
+ (init): Verify that new roots are not created inside others.
+ * sanity.sh (init-3): New test for same.
+
+2007-08-16 Derek Price <derek@ximbiot.com>
+
+ * root.c (root_allow_used): New function and...
+ * root.h (root_allow_used): ...its prototype.
+ * server.c (serve_root): Backport --allow-root test for `cvs server'.
+ * sanity.sh (server2-5, server2-6): New tests for the above.
+
+2007-06-18 Derek Price <derek@ximbiot.com>
+
+ * client.c (send_repository): Don't attempt to send metadata from CVS
+ subdirectories when importing.
+
+2007-06-15 Derek Price <derek@ximbiot.com>
+
+ * import.c (import): Check more carefully for files and directories
+ named "CVS".
+ * sanity.sh (import-1b): New test for same.
+ (import-2): Test files named "CVS", in addition to directories.
+
+2007-05-22 Larry Jones <lawrence.jones@ugs.com>
+
+ * rcs.c (RCS_fully_parse): Include revision in error message.
+
+2007-05-07 Derek Price <derek@ximbiot.com>
+
+ * mkmodules.c (init): Assert that the server is not active.
+ * server.c (serve_init): Send error message when the init command is
+ received from a client.
+
+ * sanity.sh (*): Avoid using remote init.
+ (skip_always, localonly, restore_adm): New convenience functions.
+
+2007-03-08 Larry Jones <lawrence.jones@ugs.com>
+
+ * rcs.c (findmagictag): Cast node->data before doing arithmetic
+ since it's now (void *).
+
+2007-03-05 Larry Jones <lawrence.jones@ugs.com>
+
+ * rcs.c (RCS_delete_revs): When checking for tagged revisions,
+ include magic branch tags.
+
+2007-03-01 Larry Jones <lawrence.jones@ugs.com>
+
+ * import.c (import_descend_dir): Correct error message.
+ * sanity.sh (pserver-3a): New test.
+
+2006-09-14 Derek Price <derek@ximbiot.com>
+
+ * sanity.sh (server3, client2): New tests.
+
+2006-09-07 Derek Price <derek@ximbiot.com>
+
+ [bug #17560]
+ * rcs.c (apply_rcs_changes): Improve comments. Restore repaired error
+ handling.
+
+2006-09-06 Larry Jones <lawrence.jones@ugs.com>
+
+ * rcs.c (apply_rcs_changes): Improve linked list handling. Remove
+ unused variables and unreachable error handling code. Avoid unneeded
+ dynamic allocation of temp linevector. Minor stylistic code clean up.
+
+2006-09-06 Derek Price <derek@ximbiot.com>
+
+ [bug #17560]
+ * rcs.c (apply_rcs_changes): Improve header block comment. Clean up
+ unused linevector on non-fatal error.
+
+2006-09-06 Derek Price <derek@ximbiot.com>
+
+ [bug #17560]
+ * rcs.c (apply_rcs_changes): Remove an unecessary memcpy. Avoid some
+ other processing on error.
+ (linevector_delete): Remove - it's no longer used.
+
+2006-09-06 Mark D. Baushke <mdb@gnu.org>
+
+ [bug #17560]
+ * rcs.c (apply_rcs_changes): Fix the merge algorithm from O(n^2)
+ to O(n).
+ (Based on a patch submitted by "Michael J. Smith"
+ <msmith@ideorlando.org>)
+
+2006-08-28 Derek Price <derek@ximbiot.com>
+
+ * recurse.c (do_recursion): Remove misguided assertion.
+ * sanity.sh (dottedroot-3): Add test for the above.
+ (Thanks to report from Paul Eggert <eggert@CS.UCLA.EDU>.)
+
+ [bug #17168]
+ * classify.c (Classify_File): Use T_PATCH for changed keywords instead
+ of T_CHECKOUT to conserver bandwidth. Don't sticky check when marking
+ files for update anyhow.
+ * sanity.sh: Update to compensate (s/^U /[UP] /).
+
+2006-08-25 Derek Price <derek@ximbiot.com>
+
+ [bug #17168]
+ * classify.c (Classify_file): Mark files with potential keyword
+ substitution changes as needing update.
+ * sanity.sh: Update to compensate.
+ (keyword, keywordname, serverpatch): Update to compensate, removing
+ the last few "checksum failed" tests.
+
+ * classify.c (Classify_File): Remove hacks which worked around checksum
+ failures from bug #17032.
+
+2006-08-24 Derek Price <derek@ximbiot.com>
+
+ [bug #17032]
+ * update.c (patch_file): Correctly recreate client working files
+ containing the RCS `Name' keyword before generating patches.
+ * sanity.sh (keyword-23r): Merge with local case to compensate.
+
+2006-08-17 Larry Jones <lawrence.jones@ugs.com>
+
+ * hash.h: Rename structs node and list to hashnode and hashlist
+ to avoid name clashes.
+
+2006-07-25 Mark D. Baushke <mdb@gnu.org>
+
+ * login.c (free_cvs_password): New function to control freeing of
+ the static get_cvs_passwd() returned storage.
+ (login): Call it.
+ * cvs.h (free_cvs_password): Add prototype for it.
+ * client.c (auth_server): Call it.
+ [Alter the previous NetBSD coverity cid-3404 patch.]
+
+2006-07-11 Larry Jones <lawrence.jones@ugs.com>
+
+ * log.c (log_usage): Fix misleading description of -b (it selects
+ revisions on the default branch *in addition to* revisions selected
+ with -r).
+
+2006-06-29 Derek Price <derek@ximbiot.com>
+
+ * client.c (is_arg_a_parent_or_listed_dir): Strip trailing slashes from
+ dir name defore searching for it. Partially addresses TODO #205.
+ * sanity.sh (trailingslashes): Update to compensate.
+
+2006-06-28 Derek Price <derek@ximbiot.com>
+
+ [bug #16961]
+ * login.c (get_cvs_password): Return copy of global variable.
+ (Patch from <mbarabas@redhat.com>.)
+
+2006-06-23 Larry Jones <lawrence.jones@ugs.com>
+
+ * server.c (do_cvs_command): Remove unused variable.
+
+2006-06-22 Larry Jones <lawrence.jones@ugs.com>
+
+ * mkmodules.c (modules_contents): Remove defunct -i option.
+
+2006-06-10 Derek Price <derek@ximbiot.com>
+
+ * sanity.sh (conflicts4): Don't expect specific file permissions. Use
+ $PLUS.
+
2006-06-08 Derek Price <derek@ximbiot.com>
* sanity.sh (conflicts4): Test that the client honors Empty-conflicts.
@@ -2042,7 +2309,7 @@
* ignore.c (ignore_files): Use CVS_LSTAT() instead of lstat().
* filesubr.c (xcmp): Make sure S_ISLNK exists before calling it.
- (Reported by Paul Edwards <kerravon@nosppaam.w3.to>.)
+ (Reported by Paul Edwards <fight.subjugation@gmail.com>.)
2003-10-31 Derek Price <derek@ximbiot.com>
diff --git a/contrib/cvs/src/Makefile.in b/contrib/cvs/src/Makefile.in
index 3765523..d88773c 100644
--- a/contrib/cvs/src/Makefile.in
+++ b/contrib/cvs/src/Makefile.in
@@ -1,8 +1,8 @@
-# Makefile.in generated by automake 1.9.6 from Makefile.am.
+# Makefile.in generated by automake 1.10 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005 Free Software Foundation, Inc.
+# 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
@@ -32,15 +32,11 @@
# GNU General Public License for more details.
-srcdir = @srcdir@
-top_srcdir = @top_srcdir@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
-top_builddir = ..
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
-INSTALL = @INSTALL@
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
@@ -89,7 +85,7 @@ cvs_OBJECTS = $(am_cvs_OBJECTS)
cvs_DEPENDENCIES = ../diff/libdiff.a ../lib/libcvs.a ../zlib/libz.a
binSCRIPT_INSTALL = $(INSTALL_SCRIPT)
SCRIPTS = $(bin_SCRIPTS)
-DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
+DEFAULT_INCLUDES = -I. -I$(top_builddir)@am__isrc@
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
@@ -102,8 +98,6 @@ ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
-AMDEP_FALSE = @AMDEP_FALSE@
-AMDEP_TRUE = @AMDEP_TRUE@
AMTAR = @AMTAR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
@@ -124,6 +118,8 @@ ECHO_T = @ECHO_T@
EDITOR = @EDITOR@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
+GREP = @GREP@
+INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
@@ -135,11 +131,8 @@ LIBS = @LIBS@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAINT = @MAINT@
-MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@
-MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@
MAKEINFO = @MAKEINFO@
-MAKE_TARGETS_IN_VPATH_FALSE = @MAKE_TARGETS_IN_VPATH_FALSE@
-MAKE_TARGETS_IN_VPATH_TRUE = @MAKE_TARGETS_IN_VPATH_TRUE@
+MKDIR_P = @MKDIR_P@
MKTEMP = @MKTEMP@
OBJEXT = @OBJEXT@
PACKAGE = @PACKAGE@
@@ -161,12 +154,13 @@ STRIP = @STRIP@
TEXI2DVI = @TEXI2DVI@
VERSION = @VERSION@
YACC = @YACC@
+YFLAGS = @YFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
ac_ct_CC = @ac_ct_CC@
-ac_ct_RANLIB = @ac_ct_RANLIB@
-ac_ct_STRIP = @ac_ct_STRIP@
ac_prefix_program = @ac_prefix_program@
-am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
-am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
@@ -174,26 +168,38 @@ am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build_alias = @build_alias@
+builddir = @builddir@
datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
exec_prefix = @exec_prefix@
host_alias = @host_alias@
+htmldir = @htmldir@
includedir = @includedir@
includeopt = @includeopt@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
+localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
+psdir = @psdir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
with_default_rsh = @with_default_rsh@
+with_default_ssh = @with_default_ssh@
# $(includeopt) is CVS specific and set by configure
# FIXME - This includes line is dependant on its order. This means there is
@@ -333,7 +339,7 @@ cvsbug: $(top_builddir)/config.status $(srcdir)/cvsbug.in
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
install-binPROGRAMS: $(bin_PROGRAMS)
@$(NORMAL_INSTALL)
- test -z "$(bindir)" || $(mkdir_p) "$(DESTDIR)$(bindir)"
+ test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)"
@list='$(bin_PROGRAMS)'; for p in $$list; do \
p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
if test -f $$p \
@@ -356,10 +362,10 @@ clean-binPROGRAMS:
-test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS)
cvs$(EXEEXT): $(cvs_OBJECTS) $(cvs_DEPENDENCIES)
@rm -f cvs$(EXEEXT)
- $(LINK) $(cvs_LDFLAGS) $(cvs_OBJECTS) $(cvs_LDADD) $(LIBS)
+ $(LINK) $(cvs_OBJECTS) $(cvs_LDADD) $(LIBS)
install-binSCRIPTS: $(bin_SCRIPTS)
@$(NORMAL_INSTALL)
- test -z "$(bindir)" || $(mkdir_p) "$(DESTDIR)$(bindir)"
+ test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)"
@list='$(bin_SCRIPTS)'; for p in $$list; do \
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
if test -f $$d$$p; then \
@@ -440,19 +446,18 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zlib.Po@am__quote@
.c.o:
-@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
-@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(COMPILE) -c $<
.c.obj:
-@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \
-@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
-uninstall-info-am:
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
@@ -503,22 +508,21 @@ distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(DISTFILES)
- @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
- topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
- list='$(DISTFILES)'; for file in $$list; do \
- case $$file in \
- $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
- $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
- esac; \
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
- dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
- if test "$$dir" != "$$file" && test "$$dir" != "."; then \
- dir="/$$dir"; \
- $(mkdir_p) "$(distdir)$$dir"; \
- else \
- dir=''; \
- fi; \
if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
fi; \
@@ -535,7 +539,7 @@ check: check-am
all-am: Makefile $(PROGRAMS) $(SCRIPTS)
installdirs:
for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(bindir)"; do \
- test -z "$$dir" || $(mkdir_p) "$$dir"; \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
done
install: install-am
install-exec: install-exec-am
@@ -584,12 +588,20 @@ info-am:
install-data-am:
+install-dvi: install-dvi-am
+
install-exec-am: install-binPROGRAMS install-binSCRIPTS
+install-html: install-html-am
+
install-info: install-info-am
install-man:
+install-pdf: install-pdf-am
+
+install-ps: install-ps-am
+
installcheck-am:
maintainer-clean: maintainer-clean-am
@@ -609,21 +621,23 @@ ps: ps-am
ps-am:
-uninstall-am: uninstall-binPROGRAMS uninstall-binSCRIPTS \
- uninstall-info-am
+uninstall-am: uninstall-binPROGRAMS uninstall-binSCRIPTS
+
+.MAKE: install-am install-strip
.PHONY: CTAGS GTAGS all all-am check check-am check-local clean \
clean-binPROGRAMS clean-generic ctags distclean \
distclean-compile distclean-generic distclean-tags distdir dvi \
dvi-am html html-am info info-am install install-am \
install-binPROGRAMS install-binSCRIPTS install-data \
- install-data-am install-exec install-exec-am install-info \
- install-info-am install-man install-strip installcheck \
+ install-data-am install-dvi install-dvi-am install-exec \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-man install-pdf install-pdf-am \
+ install-ps install-ps-am install-strip installcheck \
installcheck-am installdirs maintainer-clean \
maintainer-clean-generic mostlyclean mostlyclean-compile \
mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \
- uninstall-am uninstall-binPROGRAMS uninstall-binSCRIPTS \
- uninstall-info-am
+ uninstall-am uninstall-binPROGRAMS uninstall-binSCRIPTS
check-local: localcheck remotecheck
diff --git a/contrib/cvs/src/add.c b/contrib/cvs/src/add.c
index 820121b..228ae69 100644
--- a/contrib/cvs/src/add.c
+++ b/contrib/cvs/src/add.c
@@ -117,7 +117,7 @@ add (argc, argv)
strip_trailing_slashes (argv[i]);
if (strcmp (argv[i], ".") == 0
|| strcmp (argv[i], "..") == 0
- || fncmp (argv[i], CVSADM) == 0)
+ || fncmp (last_component(argv[i]), CVSADM) == 0)
{
if (!quiet)
error (0, 0, "cannot add special file `%s'; skipping", argv[i]);
diff --git a/contrib/cvs/src/classify.c b/contrib/cvs/src/classify.c
index 8bb471d..d8bf399 100644
--- a/contrib/cvs/src/classify.c
+++ b/contrib/cvs/src/classify.c
@@ -17,6 +17,50 @@
static void sticky_ck PROTO ((struct file_info *finfo, int aflag,
Vers_TS * vers));
+
+
+static inline int keywords_may_change PROTO ((int aflag, Vers_TS * vers));
+static inline int
+keywords_may_change (aflag, vers)
+ int aflag;
+ Vers_TS * vers;
+{
+ int retval;
+
+ if (/* Options are different... */
+ strcmp (vers->entdata->options, vers->options)
+ /* ...or... */
+ || (/* ...clearing stickies... */
+ aflag
+ /* ...and... */
+ && (/* ...there used to be a tag which subs in Name keys... */
+ (vers->entdata->tag && !isdigit (vers->entdata->tag[0]))
+ /* ...or there used to be a keyword mode which may be
+ * changed by -A...
+ */
+ || (strlen (vers->entdata->options)
+ && strcmp (vers->entdata->options, "-kkv")
+ && strcmp (vers->entdata->options, "-kb"))))
+ /* ...or... */
+ || (/* ...this is not commit... */
+ strcmp (cvs_cmd_name, "commit")
+ /* ...and... */
+ && (/* ...the tag is changing in a way that affects Name keys... */
+ (vers->entdata->tag && vers->tag
+ && strcmp (vers->entdata->tag, vers->tag)
+ && !(isdigit (vers->entdata->tag[0])
+ && isdigit (vers->entdata->tag[0])))
+ || (!vers->entdata->tag && vers->tag
+ && !isdigit (vers->tag[0])))))
+ retval = 1;
+ else
+ retval = 0;
+
+ return retval;
+}
+
+
+
/*
* Classify the state of a file
*/
@@ -297,15 +341,14 @@ Classify_File (finfo, tag, date, options, force_tag_match, aflag, versp,
*/
/* TODO: decide whether we need to check file permissions
for a mismatch, and return T_CONFLICT if so. */
- if (vers->entdata->options &&
- strcmp (vers->entdata->options, vers->options) != 0)
- ret = T_CHECKOUT;
+ if (keywords_may_change (aflag, vers))
+ ret = T_PATCH;
else if (vers->ts_conflict)
ret = T_CONFLICT;
else
{
- sticky_ck (finfo, aflag, vers);
ret = T_UPTODATE;
+ sticky_ck (finfo, aflag, vers);
}
}
else if (No_Difference (finfo, vers))
@@ -366,29 +409,14 @@ Classify_File (finfo, tag, date, options, force_tag_match, aflag, versp,
ret = T_CHECKOUT;
}
else if (strcmp (vers->ts_user, vers->ts_rcs) == 0)
- {
/*
* The user file is still unmodified, so just get it as well
*/
- if (strcmp (vers->entdata->options ?
- vers->entdata->options : "", vers->options) != 0
- || (vers->srcfile != NULL
- && (vers->srcfile->flags & INATTIC) != 0))
- ret = T_CHECKOUT;
- else
- ret = T_PATCH;
- }
+ ret = T_PATCH;
else if (No_Difference (finfo, vers))
/* really modified, needs to merge */
ret = T_NEEDS_MERGE;
- else if ((strcmp (vers->entdata->options ?
- vers->entdata->options : "", vers->options)
- != 0)
- || (vers->srcfile != NULL
- && (vers->srcfile->flags & INATTIC) != 0))
- /* not really modified, check it out */
- ret = T_CHECKOUT;
else
ret = T_PATCH;
}
diff --git a/contrib/cvs/src/client.c b/contrib/cvs/src/client.c
index 22384ed..78fc989 100644
--- a/contrib/cvs/src/client.c
+++ b/contrib/cvs/src/client.c
@@ -160,17 +160,22 @@ is_arg_a_parent_or_listed_dir (n, d)
void *d;
{
char *directory = n->key; /* name of the dir sent to server */
- char *this_argv_elem = (char *) d; /* this argv element */
+ char *this_argv_elem = xstrdup (d); /* this argv element */
+ int retval;
/* Say we should send this argument if the argument matches the
beginning of a directory name sent to the server. This way,
the server will know to start at the top of that directory
hierarchy and descend. */
+ strip_trailing_slashes (this_argv_elem);
if (strncmp (directory, this_argv_elem, strlen (this_argv_elem)) == 0)
- return 1;
+ retval = 1;
+ else
+ retval = 0;
- return 0;
+ free (this_argv_elem);
+ return retval;
}
static int arg_should_not_be_sent_to_server PROTO((char *));
@@ -2778,7 +2783,8 @@ send_repository (dir, repos, update_dir)
send_to_server (repos, 0);
send_to_server ("\012", 1);
- if (supported_request ("Static-directory"))
+ if (strcmp (cvs_cmd_name, "import")
+ && supported_request ("Static-directory"))
{
adm_name[0] = '\0';
if (dir[0] != '\0')
@@ -2792,7 +2798,8 @@ send_repository (dir, repos, update_dir)
send_to_server ("Static-directory\012", 0);
}
}
- if (supported_request ("Sticky"))
+ if (strcmp (cvs_cmd_name, "import")
+ && supported_request ("Sticky"))
{
FILE *f;
if (dir[0] == '\0')
@@ -3835,7 +3842,7 @@ auth_server (root, lto_server, lfrom_server, verify_only, do_gssapi, hostinfo)
int do_gssapi;
struct hostent *hostinfo;
{
- char *username; /* the username we use to connect */
+ char *username = ""; /* the username we use to connect */
char no_passwd = 0; /* gets set if no password found */
/* FIXME!!!!!!!!!!!!!!!!!!
@@ -3919,9 +3926,8 @@ auth_server (root, lto_server, lfrom_server, verify_only, do_gssapi, hostinfo)
send_to_server(end, 0);
send_to_server("\012", 1);
- /* Paranoia. */
- memset (password, 0, strlen (password));
- free (password);
+ free_cvs_password (password);
+ password = NULL;
# else /* ! AUTH_CLIENT_SUPPORT */
error (1, 0, "INTERNAL ERROR: This client does not support pserver authentication");
# endif /* AUTH_CLIENT_SUPPORT */
@@ -4720,15 +4726,20 @@ start_rsh_server (root, to_server, from_server)
/* If you're working through firewalls, you can set the
CVS_RSH environment variable to a script which uses rsh to
invoke another rsh on a proxy machine. */
- char *cvs_rsh = getenv ("CVS_RSH");
+ char *env_cvs_rsh = getenv ("CVS_RSH");
+ char *env_cvs_ssh = getenv ("CVS_SSH");
+ char *cvs_rsh;
char *cvs_server = getenv ("CVS_SERVER");
int i = 0;
/* This needs to fit "rsh", "-b", "-l", "USER", "host",
"cmd (w/ args)", and NULL. We leave some room to grow. */
char *rsh_argv[10];
- if (!cvs_rsh)
- cvs_rsh = RSH_DFLT;
+ if (root->method == extssh_method)
+ cvs_rsh = env_cvs_ssh ? env_cvs_ssh : SSH_DFLT;
+ else
+ cvs_rsh = env_cvs_rsh ? env_cvs_rsh : RSH_DFLT;
+
if (!cvs_server)
cvs_server = "cvs";
@@ -4782,14 +4793,19 @@ start_rsh_server (root, to_server, from_server)
/* If you're working through firewalls, you can set the
CVS_RSH environment variable to a script which uses rsh to
invoke another rsh on a proxy machine. */
- char *cvs_rsh = getenv ("CVS_RSH");
+ char *env_cvs_rsh = getenv ("CVS_RSH");
+ char *env_cvs_ssh = getenv ("CVS_SSH");
+ char *cvs_rsh;
char *cvs_server = getenv ("CVS_SERVER");
char *command;
int tofd, fromfd;
int child_pid;
- if (!cvs_rsh)
- cvs_rsh = "rsh";
+ if (root->method == extssh_method)
+ cvs_rsh = env_cvs_ssh ? env_cvs_ssh : SSH_DFLT;
+ else
+ cvs_rsh = env_cvs_rsh ? env_cvs_rsh : RSH_DFLT;
+
if (!cvs_server)
cvs_server = "cvs";
diff --git a/contrib/cvs/src/client.h b/contrib/cvs/src/client.h
index 3a99f4f..9afa4e7 100644
--- a/contrib/cvs/src/client.h
+++ b/contrib/cvs/src/client.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 1994-2005 The Free Software Foundation, Inc.
+ * Copyright (C) 1994-2008 The 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
@@ -65,7 +65,7 @@ extern struct buffer *cvs_gssapi_wrap_buffer_initialize ();
#ifdef CLIENT_SUPPORT
/*
* Flag variable for seeing whether the server has been started yet.
- * As of this writing, only edit.c:notify_check() uses it.
+ * As of this writing, only edit.c:cvs_notify_check() uses it.
*/
extern int server_started;
diff --git a/contrib/cvs/src/cvs.h b/contrib/cvs/src/cvs.h
index 15fd227..187a354 100644
--- a/contrib/cvs/src/cvs.h
+++ b/contrib/cvs/src/cvs.h
@@ -916,6 +916,7 @@ char *descramble PROTO ((char *str));
#ifdef AUTH_CLIENT_SUPPORT
char *get_cvs_password PROTO((void));
+void free_cvs_password PROTO((char *str));
int get_cvs_port_number PROTO((const cvsroot_t *root));
char *normalize_cvsroot PROTO((const cvsroot_t *root));
#endif /* AUTH_CLIENT_SUPPORT */
diff --git a/contrib/cvs/src/edit.c b/contrib/cvs/src/edit.c
index 4b1804a..4e0cf1e 100644
--- a/contrib/cvs/src/edit.c
+++ b/contrib/cvs/src/edit.c
@@ -147,8 +147,8 @@ dummy_fileproc (callerdat, finfo)
struct file_info *finfo;
{
/* This is a pretty hideous hack, but the gist of it is that recurse.c
- won't call notify_check unless there is a fileproc, so we can't just
- pass NULL for fileproc. */
+ won't call cvs_notify_check unless there is a fileproc, so we
+ can't just pass NULL for fileproc. */
return 0;
}
@@ -991,7 +991,7 @@ notify_do (type, filename, who, val, watches, repository)
#ifdef CLIENT_SUPPORT
/* Check and send notifications. This is only for the client. */
void
-notify_check (repository, update_dir)
+cvs_notify_check (repository, update_dir)
const char *repository;
const char *update_dir;
{
diff --git a/contrib/cvs/src/edit.h b/contrib/cvs/src/edit.h
index 5c8635a..9b20180 100644
--- a/contrib/cvs/src/edit.h
+++ b/contrib/cvs/src/edit.h
@@ -17,8 +17,8 @@ extern int watch_off PROTO ((int argc, char **argv));
/* Check to see if any notifications are sitting around in need of being
sent. These are the notifications stored in CVSADM_NOTIFY (edit,unedit);
commit calls notify_do directly. */
-extern void notify_check PROTO ((const char *repository,
- const char *update_dir));
+extern void cvs_notify_check PROTO ((const char *repository,
+ const char *update_dir));
#endif /* CLIENT_SUPPORT */
/* Issue a notification for file FILENAME. TYPE is 'E' for edit, 'U'
diff --git a/contrib/cvs/src/filesubr.c b/contrib/cvs/src/filesubr.c
index 14da6292..1e1f901 100644
--- a/contrib/cvs/src/filesubr.c
+++ b/contrib/cvs/src/filesubr.c
@@ -887,7 +887,7 @@ xreadlink (link)
const char *link;
{
char *file = NULL;
- size_t buflen = 128;
+ size_t buflen = BUFSIZ;
/* Get the name of the file to which `from' is linked. */
while (1)
diff --git a/contrib/cvs/src/hash.h b/contrib/cvs/src/hash.h
index a31fc5d..77d095a 100644
--- a/contrib/cvs/src/hash.h
+++ b/contrib/cvs/src/hash.h
@@ -27,26 +27,26 @@ enum ntype
};
typedef enum ntype Ntype;
-struct node
+struct hashnode
{
Ntype type;
- struct node *next;
- struct node *prev;
- struct node *hashnext;
- struct node *hashprev;
+ struct hashnode *next;
+ struct hashnode *prev;
+ struct hashnode *hashnext;
+ struct hashnode *hashprev;
char *key;
void *data;
void (*delproc) ();
};
-typedef struct node Node;
+typedef struct hashnode Node;
-struct list
+struct hashlist
{
Node *list;
Node *hasharray[HASHSIZE];
- struct list *next;
+ struct hashlist *next;
};
-typedef struct list List;
+typedef struct hashlist List;
List *getlist PROTO((void));
Node *findnode PROTO((List * list, const char *key));
diff --git a/contrib/cvs/src/import.c b/contrib/cvs/src/import.c
index ea65677..bc918e0 100644
--- a/contrib/cvs/src/import.c
+++ b/contrib/cvs/src/import.c
@@ -162,14 +162,21 @@ import (argc, argv)
* Could abstract this to valid_module_path, but I don't think we'll need
* to call it from anywhere else.
*/
- if ((cp = strstr(argv[0], "CVS")) && /* path contains "CVS" AND ... */
- ((cp == argv[0]) || ISDIRSEP(*(cp-1))) && /* /^CVS/ OR m#/CVS# AND ... */
- ((*(cp+3) == '\0') || ISDIRSEP(*(cp+3))) /* /CVS$/ OR m#CVS/# */
- )
+ /* for each "CVS" in path... */
+ cp = argv[0];
+ while ((cp = strstr(cp, "CVS")) != NULL)
{
- error (0, 0,
- "The word `CVS' is reserved by CVS and may not be used");
- error (1, 0, "as a directory in a path or as a file name.");
+ if ( /* /^CVS/ OR m#/CVS#... */
+ (cp == argv[0] || ISDIRSEP(*(cp-1)))
+ /* ...AND /CVS$/ OR m#CVS/# */
+ && (*(cp+3) == '\0' || ISDIRSEP(*(cp+3)))
+ )
+ {
+ error (0, 0,
+ "The word `CVS' is reserved by CVS and may not be used");
+ error (1, 0, "as a directory in a path or as a file name.");
+ }
+ cp += 3;
}
for (i = 1; i < argc; i++) /* check the tags for validity */
@@ -1601,8 +1608,8 @@ import_descend_dir (message, dir, vtag, targc, targv)
if ( CVS_CHDIR (dir) < 0)
{
ierrno = errno;
- fperrmsg (logfp, 0, ierrno, "ERROR: cannot chdir to %s", repository);
- error (0, ierrno, "ERROR: cannot chdir to %s", repository);
+ fperrmsg (logfp, 0, ierrno, "ERROR: cannot chdir to %s", dir);
+ error (0, ierrno, "ERROR: cannot chdir to %s", dir);
err = 1;
goto out;
}
diff --git a/contrib/cvs/src/lock.c b/contrib/cvs/src/lock.c
index 7a5e338..6f818da 100644
--- a/contrib/cvs/src/lock.c
+++ b/contrib/cvs/src/lock.c
@@ -173,7 +173,7 @@ lock_name (repository, name)
const char *p;
char *q;
const char *short_repos;
- mode_t save_umask;
+ mode_t save_umask = 0;
int saved_umask = 0;
if (lock_dir == NULL)
diff --git a/contrib/cvs/src/log.c b/contrib/cvs/src/log.c
index bb1dbde..1730874 100644
--- a/contrib/cvs/src/log.c
+++ b/contrib/cvs/src/log.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 1986-2005 The Free Software Foundation, Inc.
+ * Copyright (C) 1986-2008 The Free Software Foundation, Inc.
*
* Portions Copyright (C) 1998-2005 Derek Price, Ximbiot <http://ximbiot.com>,
* and others.
@@ -87,7 +87,7 @@ struct log_data
/* Nonzero if the -N option was seen, meaning that tag information
should not be printed. */
int notags;
- /* Nonzero if the -b option was seen, meaning that only revisions
+ /* Nonzero if the -b option was seen, meaning that revisions
on the default branch should be printed. */
int default_branch;
/* Nonzero if the -S option was seen, meaning that the header/name
@@ -156,11 +156,12 @@ static const char *const log_usage[] =
"Usage: %s %s [-lRhtNb] [-r[revisions]] [-d dates] [-s states]\n",
" [-w[logins]] [files...]\n",
"\t-l\tLocal directory only, no recursion.\n",
- "\t-b\tOnly list revisions on the default branch.\n",
+ "\t-b\tList revisions on the default branch.\n",
"\t-h\tOnly print header.\n",
"\t-R\tOnly print name of RCS file.\n",
"\t-t\tOnly print header and descriptive text.\n",
"\t-N\tDo not list tags.\n",
+ "\t-n\tList tags (default).\n",
"\t-S\tDo not print name/header if no revisions selected. -d, -r,\n",
"\t\t-s, & -w have little effect in conjunction with -b, -h, -R, and\n",
"\t\t-t without this option.\n",
@@ -242,7 +243,7 @@ cvslog (argc, argv)
prl = &log_data.revlist;
optind = 0;
- while ((c = getopt (argc, argv, "+bd:hlNSRr::s:tw::")) != -1)
+ while ((c = getopt (argc, argv, "+bd:hlNnSRr::s:tw::")) != -1)
{
switch (c)
{
@@ -261,6 +262,9 @@ cvslog (argc, argv)
case 'N':
log_data.notags = 1;
break;
+ case 'n':
+ log_data.notags = 0;
+ break;
case 'S':
log_data.sup_header = 1;
break;
diff --git a/contrib/cvs/src/login.c b/contrib/cvs/src/login.c
index fe95544..1d20c97 100644
--- a/contrib/cvs/src/login.c
+++ b/contrib/cvs/src/login.c
@@ -115,20 +115,20 @@ password_entry_parseline (cvsroot_canonical, warn, linenumber, linebuf)
{
/* Yes: slurp '^/\d+\D' and parse the rest of the line according to version number */
char *q;
- unsigned long int entry_version;
+ unsigned long int entry_version = 0;
if (isspace(*(linebuf + 1)))
+ {
/* special case since strtoul ignores leading white space */
q = linebuf + 1;
+ }
else
+ {
entry_version = strtoul (linebuf + 1, &q, 10);
-
- if (q == linebuf + 1)
- /* no valid digits found by strtoul */
- entry_version = 0;
- else
- /* assume a delimiting seperator */
- q++;
+ if (q != linebuf + 1)
+ /* assume a delimiting seperator */
+ q++;
+ }
switch (entry_version)
{
@@ -566,21 +566,40 @@ login (argc, argv)
password_entry_operation (password_entry_add, current_parsed_root,
typed_password);
- memset (typed_password, 0, strlen (typed_password));
- free (typed_password);
-
- free (cvs_password);
+ free_cvs_password (typed_password);
free (cvsroot_canonical);
- cvs_password = NULL;
return 0;
}
-/* Returns the _scrambled_ password. The server must descramble
- before hashing and comparing. If password file not found, or
- password not found in the file, just return NULL. */
+/* Free the password returned by get_cvs_password() and also free the
+ * saved cvs_password if they are different pointers. Be paranoid
+ * about the in-memory copy of the password and overwrite it with zero
+ * bytes before doing the free().
+ */
+void
+free_cvs_password (char *password)
+{
+ if (password && password != cvs_password)
+ {
+ memset (password, 0, strlen (password));
+ free (password);
+ }
+
+ if (cvs_password)
+ {
+ memset (cvs_password, 0, strlen (cvs_password));
+ free (cvs_password);
+ cvs_password = NULL;
+ }
+}
+
+/* Returns the _scrambled_ password in freshly allocated memory. The server
+ * must descramble before hashing and comparing. If password file not found,
+ * or password not found in the file, just return NULL.
+ */
char *
get_cvs_password ()
{
@@ -591,7 +610,7 @@ get_cvs_password ()
context, then assume they have supplied the correct, scrambled
password. */
if (cvs_password)
- return cvs_password;
+ return xstrdup (cvs_password);
if (getenv ("CVS_PASSWORD") != NULL)
{
diff --git a/contrib/cvs/src/main.c b/contrib/cvs/src/main.c
index c5911c3..3dace64 100644
--- a/contrib/cvs/src/main.c
+++ b/contrib/cvs/src/main.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 1986-2006 The Free Software Foundation, Inc.
+ * Copyright (C) 1986-2008 The Free Software Foundation, Inc.
*
* Portions Copyright (C) 1998-2006 Derek Price, Ximbiot <http://ximbiot.com>,
* and others.
@@ -108,7 +108,7 @@ static const struct cmd
{
{ "add", "ad", "new", add, CVS_CMD_MODIFIES_REPOSITORY | CVS_CMD_USES_WORK_DIR },
{ "admin", "adm", "rcs", admin, CVS_CMD_MODIFIES_REPOSITORY | CVS_CMD_USES_WORK_DIR },
- { "annotate", "ann", NULL, annotate, CVS_CMD_USES_WORK_DIR },
+ { "annotate", "ann", "blame", annotate, CVS_CMD_USES_WORK_DIR },
{ "checkout", "co", "get", checkout, 0 },
{ "commit", "ci", "com", commit, CVS_CMD_MODIFIES_REPOSITORY | CVS_CMD_USES_WORK_DIR },
{ "diff", "di", "dif", diff, CVS_CMD_USES_WORK_DIR },
diff --git a/contrib/cvs/src/mkmodules.c b/contrib/cvs/src/mkmodules.c
index 3ac06b3..751d4c7 100644
--- a/contrib/cvs/src/mkmodules.c
+++ b/contrib/cvs/src/mkmodules.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 1986-2005 The Free Software Foundation, Inc.
+ * Copyright (C) 1986-2008 The Free Software Foundation, Inc.
*
* Portions Copyright (C) 1998-2005 Derek Price, Ximbiot <http://ximbiot.com>,
* and others.
@@ -10,6 +10,7 @@
* You may distribute under the terms of the GNU General Public License as
* specified in the README file that comes with the CVS kit. */
+#include <assert.h>
#include "cvs.h"
#include "getline.h"
#include "history.h"
@@ -261,7 +262,6 @@ static const char *const modules_contents[] = {
"# key [options] directory files...\n",
"#\n",
"# Where \"options\" are composed of:\n",
- "# -i prog Run \"prog\" on \"cvs commit\" from top-level of module.\n",
"# -o prog Run \"prog\" on \"cvs checkout\" of module.\n",
"# -e prog Run \"prog\" on \"cvs export\" of module.\n",
"# -t prog Run \"prog\" on \"cvs rtag\" of module.\n",
@@ -288,6 +288,13 @@ static const char *const config_contents[] = {
"# Set this to \"no\" if pserver shouldn't check system users/passwords\n",
"#SystemAuth=yes\n",
"\n",
+ "# Set `IgnoreUnknownConfigKeys' to `yes' to ignore unknown config\n",
+ "# keys which are supported in a future version of CVS.\n",
+ "# This option is intended to be useful as a transition for read-only\n",
+ "# mirror sites when sites may need to be updated later than the\n",
+ "# primary CVS repository.\n",
+ "#IgnoreUnknownConfigKeys=no\n",
+ "\n",
"# Put CVS lock files in this directory rather than directly in the repository.\n",
"#LockDir=/var/lock/cvs\n",
"\n",
@@ -846,6 +853,41 @@ rename_rcsfile (temp, real)
free (bak);
}
+
+/*
+ * Walk PATH backwards to the root directory looking for the root of a
+ * repository.
+ */
+static char *
+in_repository (const char *path)
+{
+ char *cp = xstrdup (path);
+
+ for (;;)
+ {
+ if (isdir (cp))
+ {
+ int foundit;
+ char *adm = xmalloc (strlen(cp) + strlen(CVSROOTADM) + 2);
+ sprintf (adm, "%s/%s", cp, CVSROOTADM);
+ foundit = isdir (adm);
+ free (adm);
+ if (foundit) return cp;
+ }
+
+ /* If last_component() returns the empty string, then cp either
+ * points at the system root or is the empty string itself.
+ */
+ if (!*last_component (cp) || !strcmp (cp, ".")
+ || last_component(cp) == cp)
+ break;
+
+ cp[strlen(cp) - strlen(last_component(cp)) - 1] = '\0';
+ }
+
+ return NULL;
+}
+
const char *const init_usage[] = {
"Usage: %s %s\n",
@@ -867,8 +909,11 @@ init (argc, argv)
/* Exit status. */
int err = 0;
+ char *root_dir;
const struct admin_file *fileptr;
+ assert (!server_active);
+
umask (cvsumask);
if (argc == -1 || argc > 1)
@@ -885,6 +930,14 @@ init (argc, argv)
}
#endif /* CLIENT_SUPPORT */
+ root_dir = in_repository (current_parsed_root->directory);
+
+ if (root_dir && strcmp (root_dir, current_parsed_root->directory))
+ error (1, 0,
+ "Cannot initialize repository under existing CVSROOT: `%s'",
+ root_dir);
+ free (root_dir);
+
/* Note: we do *not* create parent directories as needed like the
old cvsinit.sh script did. Few utilities do that, and a
non-existent parent directory is as likely to be a typo as something
diff --git a/contrib/cvs/src/modules.c b/contrib/cvs/src/modules.c
index eed551e..5cbc2ec 100644
--- a/contrib/cvs/src/modules.c
+++ b/contrib/cvs/src/modules.c
@@ -129,7 +129,7 @@ my_module (db, mname, m_type, msg, callback_proc, where, shorten,
char *line;
int modargc;
int xmodargc;
- char **modargv;
+ char **modargv = NULL;
char **xmodargv = NULL;
/* Found entry from modules file, including options and such. */
char *value = NULL;
diff --git a/contrib/cvs/src/parseinfo.c b/contrib/cvs/src/parseinfo.c
index 0fe9c33..feccc71 100644
--- a/contrib/cvs/src/parseinfo.c
+++ b/contrib/cvs/src/parseinfo.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 1986-2005 The Free Software Foundation, Inc.
+ * Copyright (C) 1986-2008 The Free Software Foundation, Inc.
*
* Portions Copyright (C) 1998-2005 Derek Price, Ximbiot <http://ximbiot.com>,
* and others.
@@ -245,6 +245,7 @@ parse_config (cvsroot)
/* FIXME-reentrancy: If we do a multi-threaded server, this would need
to go to the per-connection data structures. */
static int parsed = 0;
+ int ignore_unknown_config_keys = 0;
/* Authentication code and serve_root might both want to call us.
Let this happen smoothly. */
@@ -415,6 +416,23 @@ warning: this CVS does not support PreservePermissions");
else if (strcmp (p, "stat") == 0)
RereadLogAfterVerify = LOGMSG_REREAD_STAT;
}
+ else if (strcmp (line, "IgnoreUnknownConfigKeys") == 0)
+ {
+ if (strcmp (p, "no") == 0 || strcmp (p, "false") == 0
+ || strcmp (p, "off") == 0 || strcmp (p, "0") == 0)
+ ignore_unknown_config_keys = 0;
+ else if (strcmp (p, "yes") == 0 || strcmp (p, "true") == 0
+ || strcmp (p, "on") == 0 || strcmp (p, "1") == 0)
+ ignore_unknown_config_keys = 1;
+ else
+ {
+ error (0, 0, "%s: unrecognized value '%s' for '%s'",
+ infopath, p, line);
+ goto error_return;
+ }
+ }
+ else if (ignore_unknown_config_keys)
+ ;
else
{
/* We may be dealing with a keyword which was added in a
diff --git a/contrib/cvs/src/rcs.c b/contrib/cvs/src/rcs.c
index e1d62ed..73ce8ea 100644
--- a/contrib/cvs/src/rcs.c
+++ b/contrib/cvs/src/rcs.c
@@ -30,6 +30,15 @@
# endif
#endif
+#ifdef MMAP_FALLBACK_TEST
+void *my_mmap(void *addr, size_t len, int prot, int flags, int fd, off_t offset)
+{
+ if (rand() & 1) return mmap(addr, len, prot, flags, fd, offset);
+ return NULL;
+}
+#define mmap my_mmap
+#endif
+
int preserve_perms = 0;
/* The RCS -k options, and a set of enums that must match the array.
@@ -65,6 +74,8 @@ struct rcsbuffer
this is non-zero, we must search the string for pairs of '@'
and convert them to a single '@'. */
int embedded_at;
+ /* Whether the buffer has been mmap'ed or not. */
+ int mmapped;
};
static RCSNode *RCS_parsercsfile_i PROTO((FILE * fp, const char *rcsfile));
@@ -76,10 +87,8 @@ static void rcsbuf_close PROTO ((struct rcsbuffer *));
static int rcsbuf_getkey PROTO ((struct rcsbuffer *, char **keyp,
char **valp));
static int rcsbuf_getrevnum PROTO ((struct rcsbuffer *, char **revp));
-#ifndef HAVE_MMAP
static char *rcsbuf_fill PROTO ((struct rcsbuffer *, char *ptr, char **keyp,
char **valp));
-#endif
static int rcsbuf_valcmp PROTO ((struct rcsbuffer *));
static char *rcsbuf_valcopy PROTO ((struct rcsbuffer *, char *val, int polish,
size_t *lenp));
@@ -829,8 +838,8 @@ warning: duplicate key `%s' in version `%s' of RCS file `%s'",
op = *cp++;
if (op != 'a' && op != 'd')
error (1, 0, "\
-unrecognized operation '\\x%x' in %s",
- op, rcs->path);
+unrecognized operation '\\x%x' in %s revision %s",
+ op, rcs->path, vnode->version);
(void) strtoul (cp, (char **) &cp, 10);
if (*cp++ != ' ')
error (1, 0, "space expected in %s revision %s",
@@ -1029,46 +1038,58 @@ rcsbuf_open (rcsbuf, fp, filename, pos)
const char *filename;
unsigned long pos;
{
+#ifdef HAVE_MMAP
+ void *p;
+ struct stat fs;
+ size_t mmap_off = 0;
+#endif
+
if (rcsbuf_inuse)
error (1, 0, "rcsbuf_open: internal error");
rcsbuf_inuse = 1;
#ifdef HAVE_MMAP
- {
- /* When we have mmap, it is much more efficient to let the system do the
- * buffering and caching for us
- */
- struct stat fs;
- size_t mmap_off = 0;
-
- if ( fstat (fileno(fp), &fs) < 0 )
- error ( 1, errno, "Could not stat RCS archive %s for mapping", filename );
+ /* When we have mmap, it is much more efficient to let the system do the
+ * buffering and caching for us
+ */
- if (pos)
- {
- size_t ps = getpagesize ();
- mmap_off = ( pos / ps ) * ps;
- }
+ if ( fstat (fileno(fp), &fs) < 0 )
+ error ( 1, errno, "Could not stat RCS archive %s for mapping", filename );
- /* Map private here since this particular buffer is read only */
- rcsbuf_buffer = mmap ( NULL, fs.st_size - mmap_off,
- PROT_READ | PROT_WRITE,
- MAP_PRIVATE, fileno(fp), mmap_off );
- if ( rcsbuf_buffer == NULL || rcsbuf_buffer == MAP_FAILED )
- error ( 1, errno, "Could not map memory to RCS archive %s", filename );
+ if (pos)
+ {
+ size_t ps = getpagesize ();
+ mmap_off = ( pos / ps ) * ps;
+ }
+ /* Map private here since this particular buffer is read only */
+ p = mmap ( NULL, fs.st_size - mmap_off, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE, fileno(fp), mmap_off );
+ if (p != NULL && p != MAP_FAILED)
+ {
+ if (rcsbuf_buffer) free (rcsbuf_buffer);
+ rcsbuf_buffer = p;
rcsbuf_buffer_size = fs.st_size - mmap_off;
+ rcsbuf->mmapped = 1;
rcsbuf->ptr = rcsbuf_buffer + pos - mmap_off;
rcsbuf->ptrend = rcsbuf_buffer + fs.st_size - mmap_off;
rcsbuf->pos = mmap_off;
}
-#else /* HAVE_MMAP */
- if (rcsbuf_buffer_size < RCSBUF_BUFSIZE)
+ else
+ {
+#ifndef MMAP_FALLBACK_TEST
+ error (0, errno, "Could not map memory to RCS archive %s", filename);
+#endif
+#endif /* HAVE_MMAP */
+ if (rcsbuf_buffer_size < RCSBUF_BUFSIZE)
expand_string (&rcsbuf_buffer, &rcsbuf_buffer_size, RCSBUF_BUFSIZE);
- rcsbuf->ptr = rcsbuf_buffer;
- rcsbuf->ptrend = rcsbuf_buffer;
- rcsbuf->pos = pos;
+ rcsbuf->mmapped = 0;
+ rcsbuf->ptr = rcsbuf_buffer;
+ rcsbuf->ptrend = rcsbuf_buffer;
+ rcsbuf->pos = pos;
+#ifdef HAVE_MMAP
+ }
#endif /* HAVE_MMAP */
rcsbuf->fp = fp;
rcsbuf->filename = filename;
@@ -1086,7 +1107,12 @@ rcsbuf_close (rcsbuf)
if (! rcsbuf_inuse)
error (1, 0, "rcsbuf_close: internal error");
#ifdef HAVE_MMAP
- munmap ( rcsbuf_buffer, rcsbuf_buffer_size );
+ if (rcsbuf->mmapped)
+ {
+ munmap ( rcsbuf_buffer, rcsbuf_buffer_size );
+ rcsbuf_buffer = NULL;
+ rcsbuf_buffer_size = 0;
+ }
#endif
rcsbuf_inuse = 0;
}
@@ -1131,11 +1157,10 @@ rcsbuf_getkey (rcsbuf, keyp, valp)
assert (ptr >= rcsbuf_buffer && ptr <= rcsbuf_buffer + rcsbuf_buffer_size);
assert (ptrend >= rcsbuf_buffer && ptrend <= rcsbuf_buffer + rcsbuf_buffer_size);
-#ifndef HAVE_MMAP
/* If the pointer is more than RCSBUF_BUFSIZE bytes into the
buffer, move back to the start of the buffer. This keeps the
buffer from growing indefinitely. */
- if (ptr - rcsbuf_buffer >= RCSBUF_BUFSIZE)
+ if (!rcsbuf->mmapped && ptr - rcsbuf_buffer >= RCSBUF_BUFSIZE)
{
int len;
@@ -1154,23 +1179,18 @@ rcsbuf_getkey (rcsbuf, keyp, valp)
ptrend = ptr + len;
rcsbuf->ptrend = ptrend;
}
-#endif /* ndef HAVE_MMAP */
/* Skip leading whitespace. */
while (1)
{
if (ptr >= ptrend)
-#ifndef HAVE_MMAP
{
ptr = rcsbuf_fill (rcsbuf, ptr, (char **) NULL, (char **) NULL);
if (ptr == NULL)
-#endif
return 0;
-#ifndef HAVE_MMAP
ptrend = rcsbuf->ptrend;
}
-#endif
c = *ptr;
if (! my_whitespace (c))
@@ -1189,17 +1209,13 @@ rcsbuf_getkey (rcsbuf, keyp, valp)
{
++ptr;
if (ptr >= ptrend)
-#ifndef HAVE_MMAP
{
ptr = rcsbuf_fill (rcsbuf, ptr, keyp, (char **) NULL);
if (ptr == NULL)
-#endif
error (1, 0, "EOF in key in RCS file %s",
rcsbuf->filename);
-#ifndef HAVE_MMAP
ptrend = rcsbuf->ptrend;
}
-#endif
c = *ptr;
if (c == ';' || my_whitespace (c))
break;
@@ -1228,17 +1244,13 @@ rcsbuf_getkey (rcsbuf, keyp, valp)
while (1)
{
if (ptr >= ptrend)
-#ifndef HAVE_MMAP
{
ptr = rcsbuf_fill (rcsbuf, ptr, keyp, (char **) NULL);
if (ptr == NULL)
-#endif
error (1, 0, "EOF while looking for value in RCS file %s",
rcsbuf->filename);
-#ifndef HAVE_MMAP
ptrend = rcsbuf->ptrend;
}
-#endif
c = *ptr;
if (c == ';')
{
@@ -1273,7 +1285,6 @@ rcsbuf_getkey (rcsbuf, keyp, valp)
while (1)
{
while ((pat = memchr (ptr, '@', ptrend - ptr)) == NULL)
-#ifndef HAVE_MMAP
{
/* Note that we pass PTREND as the PTR value to
rcsbuf_fill, so that we will wind up setting PTR to
@@ -1281,31 +1292,25 @@ rcsbuf_getkey (rcsbuf, keyp, valp)
that we don't search the same bytes again. */
ptr = rcsbuf_fill (rcsbuf, ptrend, keyp, valp);
if (ptr == NULL)
-#endif
error (1, 0,
"EOF while looking for end of string in RCS file %s",
rcsbuf->filename);
-#ifndef HAVE_MMAP
ptrend = rcsbuf->ptrend;
}
-#endif
/* Handle the special case of an '@' right at the end of
the known bytes. */
if (pat + 1 >= ptrend)
-#ifndef HAVE_MMAP
{
/* Note that we pass PAT, not PTR, here. */
pat = rcsbuf_fill (rcsbuf, pat, keyp, valp);
if (pat == NULL)
{
-#endif
/* EOF here is OK; it just means that the last
character of the file was an '@' terminating a
value for a key type which does not require a
trailing ';'. */
pat = rcsbuf->ptrend - 1;
-#ifndef HAVE_MMAP
}
ptrend = rcsbuf->ptrend;
@@ -1313,7 +1318,6 @@ rcsbuf_getkey (rcsbuf, keyp, valp)
/* Note that the value of PTR is bogus here. This is
OK, because we don't use it. */
}
-#endif
if (pat + 1 >= ptrend || pat[1] != '@')
break;
@@ -1363,17 +1367,13 @@ rcsbuf_getkey (rcsbuf, keyp, valp)
char n;
if (ptr >= ptrend)
-#ifndef HAVE_MMAP
{
ptr = rcsbuf_fill (rcsbuf, ptr, keyp, valp);
if (ptr == NULL)
-#endif
error (1, 0, "EOF in value in RCS file %s",
rcsbuf->filename);
-#ifndef HAVE_MMAP
ptrend = rcsbuf->ptrend;
}
-#endif
n = *ptr;
if (n == ';')
{
@@ -1408,7 +1408,6 @@ rcsbuf_getkey (rcsbuf, keyp, valp)
/* Find the ';' which must end the value. */
start = ptr;
while ((psemi = memchr (ptr, ';', ptrend - ptr)) == NULL)
-#ifndef HAVE_MMAP
{
int slen;
@@ -1419,13 +1418,10 @@ rcsbuf_getkey (rcsbuf, keyp, valp)
slen = start - *valp;
ptr = rcsbuf_fill (rcsbuf, ptrend, keyp, valp);
if (ptr == NULL)
-#endif
error (1, 0, "EOF in value in RCS file %s", rcsbuf->filename);
-#ifndef HAVE_MMAP
start = *valp + slen;
ptrend = rcsbuf->ptrend;
}
-#endif
/* See if there are any '@' strings in the value. */
pat = memchr (start, '@', psemi - start);
@@ -1469,7 +1465,6 @@ rcsbuf_getkey (rcsbuf, keyp, valp)
while (1)
{
while ((pat = memchr (ptr, '@', ptrend - ptr)) == NULL)
-#ifndef HAVE_MMAP
{
/* Note that we pass PTREND as the PTR value to
rcsbuff_fill, so that we will wind up setting PTR
@@ -1477,29 +1472,22 @@ rcsbuf_getkey (rcsbuf, keyp, valp)
that we don't search the same bytes again. */
ptr = rcsbuf_fill (rcsbuf, ptrend, keyp, valp);
if (ptr == NULL)
-#endif
error (1, 0,
"EOF while looking for end of string in RCS file %s",
rcsbuf->filename);
-#ifndef HAVE_MMAP
ptrend = rcsbuf->ptrend;
}
-#endif
/* Handle the special case of an '@' right at the end of
the known bytes. */
if (pat + 1 >= ptrend)
-#ifndef HAVE_MMAP
{
ptr = rcsbuf_fill (rcsbuf, ptr, keyp, valp);
if (ptr == NULL)
-#endif
error (1, 0, "EOF in value in RCS file %s",
rcsbuf->filename);
-#ifndef HAVE_MMAP
ptrend = rcsbuf->ptrend;
}
-#endif
if (pat[1] != '@')
break;
@@ -1542,16 +1530,12 @@ rcsbuf_getrevnum (rcsbuf, revp)
while (1)
{
if (ptr >= ptrend)
-#ifndef HAVE_MMAP
{
ptr = rcsbuf_fill (rcsbuf, ptr, (char **) NULL, (char **) NULL);
if (ptr == NULL)
-#endif
return 0;
-#ifndef HAVE_MMAP
ptrend = rcsbuf->ptrend;
}
-#endif
c = *ptr;
if (! whitespace (c))
@@ -1572,18 +1556,14 @@ unexpected '\\x%x' reading revision number in RCS file %s",
{
++ptr;
if (ptr >= ptrend)
-#ifndef HAVE_MMAP
{
ptr = rcsbuf_fill (rcsbuf, ptr, revp, (char **) NULL);
if (ptr == NULL)
-#endif
error (1, 0,
"unexpected EOF reading revision number in RCS file %s",
rcsbuf->filename);
-#ifndef HAVE_MMAP
ptrend = rcsbuf->ptrend;
}
-#endif
c = *ptr;
}
@@ -1601,7 +1581,6 @@ unexpected '\\x%x' reading revision number in RCS file %s",
return 1;
}
-#ifndef HAVE_MMAP
/* Fill RCSBUF_BUFFER with bytes from the file associated with RCSBUF,
updating PTR and the PTREND field. If KEYP and *KEYP are not NULL,
then *KEYP points into the buffer, and must be adjusted if the
@@ -1617,6 +1596,9 @@ rcsbuf_fill (rcsbuf, ptr, keyp, valp)
{
int got;
+ if (rcsbuf->mmapped)
+ return NULL;
+
if (rcsbuf->ptrend - rcsbuf_buffer + RCSBUF_BUFSIZE > rcsbuf_buffer_size)
{
int poff, peoff, koff, voff;
@@ -1649,7 +1631,6 @@ rcsbuf_fill (rcsbuf, ptr, keyp, valp)
return ptr;
}
-#endif /* HAVE_MMAP */
/* Test whether the last value returned by rcsbuf_getkey is a composite
value or not. */
@@ -1961,7 +1942,7 @@ static unsigned long
rcsbuf_ftell (rcsbuf)
struct rcsbuffer *rcsbuf;
{
- return rcsbuf->pos + rcsbuf->ptr - rcsbuf_buffer;
+ return rcsbuf->pos + (rcsbuf->ptr - rcsbuf_buffer);
}
/* Return a pointer to any data buffered for RCSBUF, along with the
@@ -2027,8 +2008,7 @@ rcsbuf_cache_open (rcs, pos, pfp, prcsbuf)
FILE **pfp;
struct rcsbuffer *prcsbuf;
{
-#ifndef HAVE_MMAP
- if (cached_rcs == rcs)
+ if (cached_rcs == rcs && !cached_rcsbuf.mmapped)
{
if (rcsbuf_ftell (&cached_rcsbuf) != pos)
{
@@ -2058,7 +2038,6 @@ rcsbuf_cache_open (rcs, pos, pfp, prcsbuf)
}
else
{
-#endif /* ifndef HAVE_MMAP */
/* FIXME: If these routines can be rewritten to not write to the
* rcs file buffer, there would be a considerably larger memory savings
* from using mmap since the shared file would never need be copied to
@@ -2073,17 +2052,13 @@ rcsbuf_cache_open (rcs, pos, pfp, prcsbuf)
*pfp = CVS_FOPEN (rcs->path, FOPEN_BINARY_READ);
if (*pfp == NULL)
error (1, 0, "unable to reopen `%s'", rcs->path);
-#ifndef HAVE_MMAP
if (pos != 0)
{
if (fseek (*pfp, pos, SEEK_SET) != 0)
error (1, 0, "cannot fseek RCS file %s", rcs->path);
}
-#endif /* ifndef HAVE_MMAP */
rcsbuf_open (prcsbuf, *pfp, rcs->path, pos);
-#ifndef HAVE_MMAP
}
-#endif /* ifndef HAVE_MMAP */
}
@@ -4165,7 +4140,8 @@ RCS_checkout (rcs, workfile, rev, nametag, options, sout, pfn, callerdat)
{
int free_rev = 0;
enum kflag expand;
- FILE *fp, *ofp;
+ FILE *fp;
+ FILE *ofp = NULL;
struct stat sb;
struct rcsbuffer rcsbuf;
char *key;
@@ -6284,6 +6260,25 @@ findtag (node, arg)
return 0;
}
+static int findmagictag PROTO ((Node *, void *));
+
+/* Return a nonzero value if a magic tag rooted at ARG is found. */
+
+static int
+findmagictag (node, arg)
+ Node *node;
+ void *arg;
+{
+ char *rev = (char *)arg;
+ size_t len = strlen (rev);
+
+ if (strncmp (node->data, rev, len) == 0 &&
+ strncmp ((char *)node->data + len, ".0.", 3) == 0)
+ return 1;
+ else
+ return 0;
+}
+
/* Delete revisions between REV1 and REV2. The changes between the two
revisions must be collapsed, and the result stored in the revision
immediately preceding the lower one. Return 0 for successful completion,
@@ -6543,8 +6538,9 @@ RCS_delete_revs (rcs, tag1, tag2, inclusive)
/* Doing this only for the :: syntax is for compatibility.
See cvs.texinfo for somewhat more discussion. */
- if (!inclusive
- && walklist (RCS_symbols (rcs), findtag, revp->version))
+ if (!inclusive &&
+ (walklist (RCS_symbols (rcs), findtag, revp->version) ||
+ walklist (RCS_symbols (rcs), findmagictag, revp->version)))
{
/* We don't print which file this happens to on the theory
that the caller will print the name of the file in a
@@ -7001,31 +6997,6 @@ linevector_add (vec, text, len, vers, pos)
return 1;
}
-static void linevector_delete PROTO ((struct linevector *, unsigned int,
- unsigned int));
-
-/* Remove NLINES lines from VEC at position POS (where line 0 is the
- first line). */
-static void
-linevector_delete (vec, pos, nlines)
- struct linevector *vec;
- unsigned int pos;
- unsigned int nlines;
-{
- unsigned int i;
- unsigned int last;
-
- last = vec->nlines - nlines;
- for (i = pos; i < pos + nlines; ++i)
- {
- if (--vec->vector[i]->refcount == 0)
- free (vec->vector[i]);
- }
- for (i = pos; i < last; ++i)
- vec->vector[i] = vec->vector[i + nlines];
- vec->nlines -= nlines;
-}
-
static void linevector_copy PROTO ((struct linevector *, struct linevector *));
/* Copy FROM to TO, copying the vectors but not the lines pointed to. */
@@ -7069,7 +7040,7 @@ linevector_free (vec)
if (vec->vector != NULL)
{
for (ln = 0; ln < vec->nlines; ++ln)
- if (--vec->vector[ln]->refcount == 0)
+ if (vec->vector[ln] && --vec->vector[ln]->refcount == 0)
free (vec->vector[ln]);
free (vec->vector);
@@ -7104,20 +7075,27 @@ apply_rcs_changes PROTO ((struct linevector *, const char *, size_t,
const char *, RCSVers *, RCSVers *));
/* Apply changes to the line vector LINES. DIFFBUF is a buffer of
- length DIFFLEN holding the change text from an RCS file (the output
- of diff -n). NAME is used in error messages. The VERS field of
- any line added is set to ADDVERS. The VERS field of any line
- deleted is set to DELVERS, unless DELVERS is NULL, in which case
- the VERS field of deleted lines is unchanged. The function returns
- non-zero if the change text is applied successfully. It returns
- zero if the change text does not appear to apply to LINES (e.g., a
- line number is invalid). If the change text is improperly
- formatted (e.g., it is not the output of diff -n), the function
- calls error with a status of 1, causing the program to exit. */
-
+ * length DIFFLEN holding the change text from an RCS file (the output
+ * of diff -n). NAME is used in error messages. The VERS field of
+ * any line added is set to ADDVERS. The VERS field of any line
+ * deleted is set to DELVERS, unless DELVERS is NULL, in which case
+ * the VERS field of deleted lines is unchanged.
+ *
+ * RETURNS
+ * Non-zero if the change text is applied successfully to ORIG_LINES.
+ *
+ * If the change text does not appear to apply to ORIG_LINES (e.g., a
+ * line number is invalid), this function will return zero and ORIG_LINES
+ * will remain unmolested.
+ *
+ * ERRORS
+ * If the change text is improperly formatted (e.g., it is not the output
+ * of diff -n), the function calls error with a status of 1, causing the
+ * program to exit.
+ */
static int
-apply_rcs_changes (lines, diffbuf, difflen, name, addvers, delvers)
- struct linevector *lines;
+apply_rcs_changes (orig_lines, diffbuf, difflen, name, addvers, delvers)
+ struct linevector *orig_lines;
const char *diffbuf;
size_t difflen;
const char *name;
@@ -7139,10 +7117,15 @@ apply_rcs_changes (lines, diffbuf, difflen, name, addvers, delvers)
struct deltafrag *next;
};
struct deltafrag *dfhead;
+ struct deltafrag **dftail;
struct deltafrag *df;
+ unsigned long numlines, lastmodline, offset;
+ struct linevector lines;
int err;
dfhead = NULL;
+ dftail = &dfhead;
+ numlines = orig_lines->nlines; /* start with init # of lines */
for (p = diffbuf; p != NULL && p < diffbuf + difflen; )
{
op = *p++;
@@ -7151,9 +7134,9 @@ apply_rcs_changes (lines, diffbuf, difflen, name, addvers, delvers)
of op determines the syntax. */
error (1, 0, "unrecognized operation '\\x%x' in %s",
op, name);
- df = (struct deltafrag *) xmalloc (sizeof (struct deltafrag));
- df->next = dfhead;
- dfhead = df;
+ *dftail = df = xmalloc (sizeof *df);
+ *(dftail = &df->next) = NULL;
+
df->pos = strtoul (p, (char **) &q, 10);
if (p == q)
@@ -7194,6 +7177,7 @@ apply_rcs_changes (lines, diffbuf, difflen, name, addvers, delvers)
df->len = q - p;
p = q;
+ numlines += df->nlines;
}
else
{
@@ -7203,41 +7187,155 @@ apply_rcs_changes (lines, diffbuf, difflen, name, addvers, delvers)
assert (op == 'd');
df->type = FRAG_DELETE;
+ numlines -= df->nlines;
}
}
+ /* New temp data structure to hold new org before
+ copy back into original structure. */
+ lines.nlines = lines.lines_alloced = numlines;
+ lines.vector = xmalloc (numlines * sizeof *lines.vector);
+
+ /* We changed the list order to first to last -- so the
+ list never gets larger than the size numlines. */
+ lastmodline = 0;
+
+ /* offset created when adding/removing lines
+ between new and original structure */
+ offset = 0;
err = 0;
- for (df = dfhead; df != NULL;)
+ for (df = dfhead; df != NULL; )
{
unsigned int ln;
+ unsigned long deltaend;
- /* Once an error is encountered, just free the rest of the list and
- * return.
- */
+ if (df->pos > orig_lines->nlines)
+ err = 1;
+
+ /* On error, just free the rest of the list. */
if (!err)
+ {
+ /* Here we need to get to the line where the next insert will
+ begin, which is DF->pos in ORIG_LINES. We will fill up to
+ DF->pos - OFFSET in LINES with original items. */
+ for (deltaend = df->pos - offset;
+ lastmodline < deltaend;
+ lastmodline++)
+ {
+ /* we need to copy from the orig structure into new one */
+ lines.vector[lastmodline] =
+ orig_lines->vector[lastmodline + offset];
+ lines.vector[lastmodline]->refcount++;
+ }
+
switch (df->type)
{
- case FRAG_ADD:
- if (! linevector_add (lines, df->new_lines, df->len, addvers,
- df->pos))
- err = 1;
- break;
- case FRAG_DELETE:
- if (df->pos > lines->nlines
- || df->pos + df->nlines > lines->nlines)
- return 0;
- if (delvers != NULL)
- for (ln = df->pos; ln < df->pos + df->nlines; ++ln)
- lines->vector[ln]->vers = delvers;
- linevector_delete (lines, df->pos, df->nlines);
- break;
+ case FRAG_ADD:
+ {
+ const char *textend, *p;
+ const char *nextline_text;
+ struct line *q;
+ int nextline_newline;
+ size_t nextline_len;
+
+ textend = df->new_lines + df->len;
+ nextline_newline = 0;
+ nextline_text = df->new_lines;
+ for (p = df->new_lines; p < textend; ++p)
+ {
+ if (*p == '\n')
+ {
+ nextline_newline = 1;
+ if (p + 1 == textend)
+ {
+ /* If there are no characters beyond the
+ last newline, we don't consider it
+ another line. */
+ break;
+ }
+
+ nextline_len = p - nextline_text;
+ q = xmalloc (sizeof *q + nextline_len);
+ q->vers = addvers;
+ q->text = (char *)(q + 1);
+ q->len = nextline_len;
+ q->has_newline = nextline_newline;
+ q->refcount = 1;
+ memcpy (q->text, nextline_text, nextline_len);
+ lines.vector[lastmodline++] = q;
+ offset--;
+
+ nextline_text = (char *)p + 1;
+ nextline_newline = 0;
+ }
+ }
+ nextline_len = p - nextline_text;
+ q = xmalloc (sizeof *q + nextline_len);
+ q->vers = addvers;
+ q->text = (char *)(q + 1);
+ q->len = nextline_len;
+ q->has_newline = nextline_newline;
+ q->refcount = 1;
+ memcpy (q->text, nextline_text, nextline_len);
+ lines.vector[lastmodline++] = q;
+
+ /* For each line we add the offset between the #'s
+ decreases. */
+ offset--;
+ break;
+ }
+
+ case FRAG_DELETE:
+ /* we are removing this many lines from the source. */
+ offset += df->nlines;
+
+ if (df->pos + df->nlines > orig_lines->nlines)
+ err = 1;
+ else if (delvers)
+ for (ln = df->pos; ln < df->pos + df->nlines; ++ln)
+ if (orig_lines->vector[ln]->refcount > 1)
+ /* Annotate needs this but, since the original
+ * vector is disposed of before returning from
+ * this function, we only need keep track if
+ * there are multiple references.
+ */
+ orig_lines->vector[ln]->vers = delvers;
+ break;
}
+ }
df = df->next;
free (dfhead);
dfhead = df;
}
+ if (err)
+ {
+ /* No reason to try and move a half-mutated and known invalid
+ * text into the output buffer.
+ */
+ linevector_free (&lines);
+ }
+ else
+ {
+ /* add the rest of the remaining lines to the data vector */
+ for (; lastmodline < numlines; lastmodline++)
+ {
+ /* we need to copy from the orig structure into new one */
+ lines.vector[lastmodline] = orig_lines->vector[lastmodline
+ + offset];
+ lines.vector[lastmodline]->refcount++;
+ }
+
+ /* Move the lines vector to the original structure for output,
+ * first deleting the old.
+ */
+ linevector_free (orig_lines);
+ orig_lines->vector = lines.vector;
+ orig_lines->lines_alloced = numlines;
+ orig_lines->nlines = lines.nlines;
+ }
+
return !err;
}
@@ -8310,10 +8408,8 @@ RCS_copydeltas (rcs, fin, rcsbufin, fout, newdtext, insertpt)
char *bufrest;
int nls;
size_t buflen;
-#ifndef HAVE_MMAP
char buf[8192];
int got;
-#endif
/* Count the number of versions for which we have to do some
special operation. */
@@ -8427,29 +8523,30 @@ RCS_copydeltas (rcs, fin, rcsbufin, fout, newdtext, insertpt)
fwrite (bufrest, 1, buflen, fout);
}
-#ifndef HAVE_MMAP
- /* This bit isn't necessary when using mmap since the entire file
- * will already be available via the RCS buffer. Besides, the
- * mmap code doesn't always keep the file pointer up to date, so
- * this adds some data twice.
- */
- while ((got = fread (buf, 1, sizeof buf, fin)) != 0)
+ if (!rcsbufin->mmapped)
{
- if (nls > 0
- && got >= nls
- && buf[0] == '\n'
- && strncmp (buf, "\n\n\n", nls) == 0)
- {
- fwrite (buf + 1, 1, got - 1, fout);
- }
- else
+ /* This bit isn't necessary when using mmap since the entire file
+ * will already be available via the RCS buffer. Besides, the
+ * mmap code doesn't always keep the file pointer up to date, so
+ * this adds some data twice.
+ */
+ while ((got = fread (buf, 1, sizeof buf, fin)) != 0)
{
- fwrite (buf, 1, got, fout);
- }
+ if (nls > 0
+ && got >= nls
+ && buf[0] == '\n'
+ && strncmp (buf, "\n\n\n", nls) == 0)
+ {
+ fwrite (buf + 1, 1, got - 1, fout);
+ }
+ else
+ {
+ fwrite (buf, 1, got, fout);
+ }
nls = 0;
+ }
}
-#endif /* HAVE_MMAP */
}
/* A helper procedure for RCS_copydeltas. This is called via walklist
diff --git a/contrib/cvs/src/recurse.c b/contrib/cvs/src/recurse.c
index 2416861..fb865a9 100644
--- a/contrib/cvs/src/recurse.c
+++ b/contrib/cvs/src/recurse.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 1986-2005 The Free Software Foundation, Inc.
+ * Copyright (C) 1986-2008 The Free Software Foundation, Inc.
*
* Portions Copyright (C) 1998-2005 Derek Price, Ximbiot <http://ximbiot.com>,
* and others.
@@ -662,7 +662,6 @@ do_recursion (frame)
{
repository = frame->repository;
assert (repository != NULL);
- assert (strstr (repository, "/./") == NULL);
}
fileattr_startdir (repository);
@@ -765,7 +764,7 @@ do_recursion (frame)
have writelocks in place, and there is no way to get writelocks
here. */
if (current_parsed_root->isremote)
- notify_check (repository, update_dir);
+ cvs_notify_check (repository, update_dir);
#endif /* CLIENT_SUPPORT */
finfo_struct.repository = repository;
diff --git a/contrib/cvs/src/root.c b/contrib/cvs/src/root.c
index 8e2380f..44d1f9a 100644
--- a/contrib/cvs/src/root.c
+++ b/contrib/cvs/src/root.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 1986-2005 The Free Software Foundation, Inc.
+ * Copyright (C) 1986-2008 The Free Software Foundation, Inc.
*
* Portions Copyright (C) 1998-2005 Derek Price, Ximbiot <http://ximbiot.com>,
* and others.
@@ -182,6 +182,12 @@ static int root_allow_count;
static char **root_allow_vector;
static int root_allow_size;
+int
+root_allow_used ()
+{
+ return root_allow_count;
+}
+
void
root_allow_add (arg)
char *arg;
@@ -438,6 +444,8 @@ parse_cvsroot (root_in)
newroot->method = server_method;
else if (strcmp (method, "ext") == 0)
newroot->method = ext_method;
+ else if (strcmp (method, "extssh") == 0)
+ newroot->method = extssh_method;
else if (strcmp (method, "fork") == 0)
newroot->method = fork_method;
else
@@ -667,6 +675,7 @@ parse_cvsroot (root_in)
# endif
case server_method:
case ext_method:
+ case extssh_method:
no_port = 1;
/* no_password already set */
check_hostname = 1;
diff --git a/contrib/cvs/src/root.h b/contrib/cvs/src/root.h
index b6edec4..089b694 100644
--- a/contrib/cvs/src/root.h
+++ b/contrib/cvs/src/root.h
@@ -54,3 +54,4 @@ void Create_Root PROTO((const char *dir, const char *rootdir));
void root_allow_add PROTO ((char *));
void root_allow_free PROTO ((void));
int root_allow_ok PROTO ((char *));
+int root_allow_used PROTO ((void));
diff --git a/contrib/cvs/src/sanity.sh b/contrib/cvs/src/sanity.sh
index ae0580e..dbcae19 100755
--- a/contrib/cvs/src/sanity.sh
+++ b/contrib/cvs/src/sanity.sh
@@ -527,7 +527,7 @@ expr=$1
if $expr 'a
b' : 'a
c' >/dev/null; then
- echo 'Warning: you are using a version of expr that does not correctly'
+ echo 'WARNING: you are using a version of expr that does not correctly'
echo 'match multi-line patterns. Some tests may spuriously pass or fail.'
echo 'You may wish to make sure GNU expr is in your path.'
return 1
@@ -553,13 +553,13 @@ test ! -f ${TESTDIR}/bar && expr_create_bar
if $expr "`cat ${TESTDIR}/bar`" : "`cat ${TESTDIR}/bar`" >/dev/null; then
: good, it works
else
- echo 'Warning: you are using a version of expr that does not correctly'
+ echo 'WARNING: you are using a version of expr that does not correctly'
echo 'match large patterns. Some tests may spuriously pass or fail.'
echo 'You may wish to make sure GNU expr is in your path.'
return 1
fi
if $expr "`cat ${TESTDIR}/bar`x" : "`cat ${TESTDIR}/bar`y" >/dev/null; then
- echo 'Warning: you are using a version of expr that does not correctly'
+ echo 'WARNING: you are using a version of expr that does not correctly'
echo 'match large patterns. Some tests may spuriously pass or fail.'
echo 'You may wish to make sure GNU expr is in your path.'
return 1
@@ -622,13 +622,46 @@ if $expr "`cat ${TESTDIR}/bar`" : "${DOTSTAR}xyzABC${DOTSTAR}$" >/dev/null; then
# good, it works
return 0
else
- echo 'Warning: you are using a version of expr that does not correctly'
+ echo 'WARNING: you are using a version of expr that does not correctly'
echo 'match large patterns. Some tests may spuriously pass or fail.'
echo 'You may wish to make sure GNU expr is in your path.'
return 77
fi
}
+# FreeBSD 5.2 and 6.1 support 'expr [-e] expression'
+# They get confused unless '--' is used before the expressions
+# when those expressions begin with a '-' character, such as the
+# output of an ls -l command. The EXPR_COMPAT environment variable may
+# be used to go back to the non-POSIX behavior as an alternative.
+# (GNU expr appears to accept the '--' argument and work correctly or
+# not have it and still get the results we want.)
+exprDASHDASH='false'
+expr_set_DASHDASH ()
+{
+expr=$1
+exprDASHDASH='false'
+# Not POSIX, but works on a lot of expr versions.
+if $expr "-rw-rw-r--" : "-rw-rw-r--" >/dev/null 2>&1; then
+ # good, it works
+ return 0
+else
+ # Do things in the POSIX manner.
+ if $expr -- "-rw-rw-r--" : "-rw-rw-r--" >/dev/null 2>&1; then
+ exprDASHDASH=':'
+ return 0
+ else
+ echo 'WARNING: Your $expr does not correctly handle'
+ echo 'leading "-" characters in regular expressions to'
+ echo 'be matched. You may wish to see if there is an'
+ echo 'environment variable or other setting to allow'
+ echo 'POSIX functionality to be enabled.'
+ return 77
+ fi
+fi
+}
+
+
EXPR=`find_tool ${EXPR}:gexpr \
version_test expr_tooltest1 expr_tooltest2 expr_tooltest3 \
expr_set_ENDANCHOR expr_set_DOTSTAR expr_tooltest_DOTSTAR`
@@ -637,6 +670,11 @@ expr_set_ENDANCHOR expr_set_DOTSTAR expr_tooltest_DOTSTAR`
expr_set_ENDANCHOR ${EXPR} >/dev/null
expr_tooltest_DOTSTAR ${EXPR} >/dev/null
+# Is $EXPR a POSIX or non-POSIX implementation
+# with regard to command-line arguments?
+expr_set_DASHDASH ${EXPR}
+$exprDASHDASH && EXPR="$EXPR --"
+
echo "Using EXPR=$EXPR" >>$LOGFILE
echo "Using ENDANCHOR=$ENDANCHOR" >>$LOGFILE
echo "Using DOTSTAR=$DOTSTAR" >>$LOGFILE
@@ -803,6 +841,13 @@ pass ()
passed=`expr $passed + 1`
}
+# Like skip(), but don't fail when $skipfail is set.
+skip_always ()
+{
+ echo "SKIP: $1${2+ ($2)}" >>$LOGFILE
+ skipped=`expr $skipped + 1`
+}
+
skip ()
{
if $skipfail; then
@@ -823,6 +868,12 @@ warn ()
warnings=`expr $warnings + 1`
}
+# Convenience function for skipping tests run only in local mode.
+localonly ()
+{
+ skip_always $1 "only tested in local mode"
+}
+
fail ()
{
echo "FAIL: $1" | tee -a ${LOGFILE}
@@ -853,6 +904,13 @@ verify_tmp_empty ()
fi
}
+# Restore changes to CVSROOT admin files.
+restore_adm ()
+{
+ rm -rf $CVSROOT_DIRNAME/CVSROOT
+ cp -Rp $TESTDIR/CVSROOT.save $CVSROOT_DIRNAME/CVSROOT
+}
+
# See dotest and dotest_fail for explanation (this is the parts
# of the implementation common to the two).
dotest_internal ()
@@ -1103,16 +1161,18 @@ if test x"$*" = x; then
tests="version basica basicb basicc basic1 deep basic2"
tests="${tests} parseroot parseroot2 files spacefiles commit-readonly"
tests="${tests} commit-add-missing"
+ tests="$tests add-restricted"
tests="${tests} status"
# Branching, tagging, removing, adding, multiple directories
tests="${tests} rdiff rdiff-short"
tests="${tests} rdiff2 diff diffnl death death2 death-rtag"
tests="${tests} rm-update-message rmadd rmadd2 rmadd3 resurrection"
- tests="${tests} dirs dirs2 branches branches2 tagc tagf tag-space"
+ tests="${tests} dirs dirs2 branches branches2 tagc tagf "
+ tests="${tests} tag-log tag-space"
tests="${tests} rcslib multibranch import importb importc import-CVS"
tests="$tests import-quirks"
tests="${tests} update-p import-after-initial branch-after-import"
- tests="${tests} join join2 join3 join4 join5 join6 join7"
+ tests="${tests} join join2 join3 join4 join5 join6 join7 join8 join9"
tests="${tests} join-readonly-conflict join-admin join-admin-2"
tests="${tests} join-rm"
tests="${tests} new newb conflicts conflicts2 conflicts3 conflicts4"
@@ -1133,7 +1193,7 @@ if test x"$*" = x; then
tests="${tests} serverpatch log log2 logopt ann ann-id"
# Repository Storage (RCS file format, CVS lock files, creating
# a repository without "cvs init", &c).
- tests="${tests} crerepos rcs rcs2 rcs3 rcs4 rcs5 rcs6"
+ tests="${tests} crerepos crerepos-extssh rcs rcs2 rcs3 rcs4 rcs5 rcs6"
tests="$tests lockfiles backuprecover"
tests="${tests} sshstdio"
# More history browsing, &c.
@@ -1153,7 +1213,8 @@ if test x"$*" = x; then
tests="${tests} recase"
# Multiple root directories and low-level protocol tests.
tests="${tests} multiroot multiroot2 multiroot3 multiroot4"
- tests="${tests} rmroot reposmv pserver server server2 client"
+ tests="$tests rmroot reposmv pserver server server2 server3"
+ tests="$tests client client2"
tests="${tests} dottedroot fork commit-d"
else
tests="$*"
@@ -2064,20 +2125,41 @@ newroot() {
# sensitive server and visa versa.
: ${CVS_SERVER=$testcvs}; export CVS_SERVER
+# Use a name which will be different than CVSROOT on case insensitive
+# filesystems (e.g., HFS+)
+CVSROOTDIR=cvsrootdir
if $linkroot; then
mkdir ${TESTDIR}/realcvsroot
- ln -s realcvsroot ${TESTDIR}/cvsroot
+ ln -s realcvsroot ${TESTDIR}/${CVSROOTDIR}
fi
-CVSROOT_DIRNAME=${TESTDIR}/cvsroot
+CVSROOT_DIRNAME=${TESTDIR}/${CVSROOTDIR}
CVSROOT=`newroot $CVSROOT_DIRNAME`; export CVSROOT
###
+### Init the repository.
+###
+dotest init-1 "$testcvs -d$CVSROOT_DIRNAME init"
+
+# Copy the admin files for restore_adm.
+cp -Rp $CVSROOT_DIRNAME/CVSROOT $TESTDIR/CVSROOT.save
+
+
+
+###
### The tests
###
-dotest 1 "${testcvs} init" ''
-dotest 1a "${testcvs} init" ''
+if $remote; then
+ localonly init-2
+ localonly init-3
+else
+ dotest init-2 "$testcvs init"
+ dotest_fail init-3 "$testcvs -d $CVSROOT/sdir init" \
+"$PROG \[init aborted\]: Cannot initialize repository under existing CVSROOT: \`$CVSROOT_DIRNAME'"
+fi
+
+
### The big loop
for what in $tests; do
@@ -2311,8 +2393,14 @@ ${PROG} commit: could not check in ssfile"
${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v <-- ssfile
new revision: 3\.1\.2\.1; previous revision: 3\.1
done"
+
+ # Verify that this file remains unchanged since up -A should not
+ # change the contents here.
+ cp ssfile $TESTDIR/ssfile.sav
# now get rid of the sticky tag and go back to the trunk
- dotest basica-8a5 "${testcvs} -q up -A ./" "[UP] ssfile"
+ dotest basica-8a5 "$testcvs -q up -A ./" '[UP] ssfile'
+ dotest basica-8a6 "cmp ssfile $TESTDIR/ssfile.sav"
+ rm $TESTDIR/ssfile.sav
cd ../..
dotest basica-8b "${testcvs} -q diff -r1.2 -r1.3"
@@ -4149,7 +4237,7 @@ ${CVSROOT_DIRNAME}/first-dir/tfile,v <-- tfile
initial revision: 1\.1
done"
dotest files-5 "${testcvs} -q tag -b C" "T tfile"
- dotest files-6 "${testcvs} -q update -r C" ""
+ dotest files-6 "$testcvs -q update -r C" "U tfile"
mkdir dir
dotest files-7 "${testcvs} add dir" \
"Directory ${CVSROOT_DIRNAME}/first-dir/dir added to the repository
@@ -5381,9 +5469,10 @@ U first-dir/file3'
fi
# and join
- dotest 95 "${testcvs} -q update -j HEAD" \
-"${PROG}"' update: file file1 has been modified, but has been removed in revision HEAD
-'"${PROG}"' update: file file3 exists, but has been added in revision HEAD'
+ dotest 95 "$testcvs -q update -j HEAD" \
+"$PROG update: file file1 has been removed in revision HEAD, but the destination is incompatibly modified
+C file1
+$PROG update: file file3 exists, but has been added in revision HEAD"
dotest_fail death-file4-7 "test -f file4" ''
@@ -5435,7 +5524,9 @@ T file4'
T file4'
# Switch over to the branch.
- dotest death2-6 "${testcvs} -q update -r branch" ''
+ dotest death2-6 "$testcvs -q update -r branch" \
+'[UP] file1
+[UP] file4'
# Delete the file on the branch.
rm file1
@@ -5735,9 +5826,10 @@ diff -N file1
${PLUS} first revision"
# now back to the trunk
- dotest death2-21 "${testcvs} -q update -A" \
-"U file2
-[UP] file4"
+ dotest death2-21 "$testcvs -q update -A" \
+'[UP] file1
+U file2
+U file4'
# test merging with a dead file
dotest death2-22 "${testcvs} -q co first-dir" \
@@ -6000,7 +6092,7 @@ ${PROG} add: use .${PROG} commit. to add this file permanently"
"${testcvs} -q ci -r mynonbranch -m add file4" \
"${PROG} \[commit aborted\]: no such tag mynonbranch"
# Now make CVS write val-tags for real.
- dotest rmadd-20 "${testcvs} -q update -r mynonbranch file1" ""
+ dotest rmadd-20 "$testcvs -q update -r mynonbranch file1" '[UP] file1'
# Oops - CVS isn't distinguishing between a branch tag and
# a non-branch tag.
dotest rmadd-21 \
@@ -6084,9 +6176,10 @@ initial revision: 1\.1
done"
# lose the branch
- dotest rmadd-29 "${testcvs} -q up -A" \
-"${PROG} update: file3 is no longer in the repository
-${PROG} update: file4 is no longer in the repository"
+ dotest rmadd-29 "$testcvs -q up -A" \
+"[UP] file1
+$PROG update: file3 is no longer in the repository
+$PROG update: file4 is no longer in the repository"
# -f disables recursion
dotest rmadd-30 "${testcvs} -q ci -f -r9 -m." \
@@ -6656,9 +6749,12 @@ T file1
T file2
T file3
T file4'
- dotest branches-5 "${testcvs} update -r br1" \
-"${PROG} update: Updating \.
-M file1"
+ dotest branches-5 "$testcvs update -r br1" \
+"$PROG update: Updating \.
+M file1
+[UP] file2
+[UP] file3
+[UP] file4"
echo 2:br1 >file2
echo 4:br1 >file4
dotest branches-6 "${testcvs} -q ci -m modify" \
@@ -6678,7 +6774,11 @@ done"
T file2
T file3
T file4'
- dotest branches-8 "${testcvs} -q update -r brbr" ''
+ dotest branches-8 "$testcvs -q update -r brbr" \
+'[UP] file1
+[UP] file2
+[UP] file3
+[UP] file4'
echo 1:brbr >file1
echo 4:brbr >file4
dotest branches-9 "${testcvs} -q ci -m modify" \
@@ -6694,9 +6794,11 @@ done"
2:br1
3:ancest
4:brbr'
- dotest branches-11 "${testcvs} -q update -r br1" \
-'[UP] file1
-[UP] file4'
+ dotest branches-11 "$testcvs -q update -r br1" \
+'U file1
+[UP] file2
+[UP] file3
+U file4'
dotest branches-12 "cat file1 file2 file3 file4" '1:br1
2:br1
3:ancest
@@ -6707,9 +6809,11 @@ done"
${CVSROOT_DIRNAME}/first-dir/file4,v <-- file4
new revision: 1\.2\.2\.2; previous revision: 1\.2\.2\.1
done"
- dotest branches-13 "${testcvs} -q update -A" '[UP] file1
-[UP] file2
-[UP] file4'
+ dotest branches-13 "${testcvs} -q update -A" \
+'U file1
+U file2
+[UP] file3
+U file4'
dotest branches-14 "cat file1 file2 file3 file4" '1:ancest
2:ancest
3:ancest
@@ -7243,8 +7347,9 @@ v1"
# to return to the state of being on the trunk with a $file
# that we can then remove.
dotest update-p-undead-0 "$testcvs update -A" \
-"${PROG} update: Updating \.
-${PROG} update: warning: new-born $file has disappeared"
+"$PROG update: Updating \.
+$PROG update: warning: new-born $file has disappeared
+[UP] unused-file"
dotest update-p-undead-1 "$testcvs update" \
"${PROG} update: Updating \.
U $file"
@@ -7303,7 +7408,9 @@ done"
# Now create a branch and commit a revision there.
dotest tagf-5 "${testcvs} -q tag -b br" "T file1
T file2"
- dotest tagf-6 "${testcvs} -q update -r br" ""
+ dotest tagf-6 "$testcvs -q update -r br" \
+'U file1
+U file2'
echo brmod >> file1
echo brmod >> file2
dotest tagf-7 "${testcvs} -q ci -m modify" \
@@ -7489,6 +7596,103 @@ ${PROG} rtag: first-dir/file1: Not moving non-branch tag .regulartag. from 1\.1
rm -rf ${CVSROOT_DIRNAME}/first-dir
;;
+ tag-log)
+ # Test log output for tags
+ mkdir 1; cd 1
+ dotest tag-log-init-1 "$testcvs -q co -l ."
+ mkdir first-dir
+ dotest tag-log-init-2 "$testcvs add first-dir" \
+"Directory $CVSROOT_DIRNAME/first-dir added to the repository"
+ cd first-dir
+ touch file1
+ dotest tag-log-init-3 "$testcvs add file1" \
+"${PROG}"' add: scheduling file `file1'\'' for addition
+'"${PROG}"' add: use .'"${PROG}"' commit. to add this file permanently'
+ dotest tag-log-init-4 "$testcvs -Q ci -m add" \
+"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v
+done
+Checking in file1;
+${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1
+initial revision: 1\.1
+done"
+
+ dotest tag-log-1 "$testcvs -Q tag mytag file1" ''
+ dotest tag-log-2 "$testcvs log -N file1" \
+"
+RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v
+Working file: file1
+head: 1\.1
+branch:
+locks: strict
+access list:
+keyword substitution: kv
+total revisions: 1; selected revisions: 1
+description:
+----------------------------
+revision 1\.1
+date: [0-9/]* [0-9:]*; author: ${username}; state: Exp;
+add
+============================================================================="
+ dotest tag-log-3 "$testcvs log -N -n file1" \
+"
+RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v
+Working file: file1
+head: 1\.1
+branch:
+locks: strict
+access list:
+symbolic names:
+ mytag: 1\.1
+keyword substitution: kv
+total revisions: 1; selected revisions: 1
+description:
+----------------------------
+revision 1\.1
+date: [0-9/]* [0-9:]*; author: ${username}; state: Exp;
+add
+============================================================================="
+ dotest tag-log-4 "$testcvs log file1" \
+"
+RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v
+Working file: file1
+head: 1\.1
+branch:
+locks: strict
+access list:
+symbolic names:
+ mytag: 1\.1
+keyword substitution: kv
+total revisions: 1; selected revisions: 1
+description:
+----------------------------
+revision 1\.1
+date: [0-9/]* [0-9:]*; author: ${username}; state: Exp;
+add
+============================================================================="
+ dotest tag-log-5 "$testcvs log -n file1" \
+"
+RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v
+Working file: file1
+head: 1\.1
+branch:
+locks: strict
+access list:
+symbolic names:
+ mytag: 1\.1
+keyword substitution: kv
+total revisions: 1; selected revisions: 1
+description:
+----------------------------
+revision 1\.1
+date: [0-9/]* [0-9:]*; author: ${username}; state: Exp;
+add
+============================================================================="
+
+ cd ../..
+ rm -fr 1
+ rm -rf ${CVSROOT_DIRNAME}/first-dir
+ ;;
+
tag-space)
# Test tags with spaces in the names.
#
@@ -8063,7 +8267,7 @@ T file1"
dotest multibranch-5 "${testcvs} tag -b br2" \
"${PROG} tag: Tagging \.
T file1"
- dotest multibranch-6 "${testcvs} -q update -r br1" ''
+ dotest multibranch-6 "$testcvs -q update -r br1" '[UP] file1'
echo on-br1 >file1
dotest multibranch-7 "${testcvs} -q ci -m modify-on-br1" \
"Checking in file1;
@@ -8235,10 +8439,12 @@ first-import
============================================================================="
# update into the vendor branch.
- dotest import-102 "${testcvs} update -rvendor-branch" \
-"${PROG} update: Updating .
-[UP] imported-f1
-[UP] imported-f2"
+ dotest import-102 "$testcvs update -rvendor-branch" \
+"$PROG update: Updating .
+U imported-f1
+[UP] imported-f2
+[UP] imported-f3
+[UP] imported-f4"
# remove file4 on the vendor branch
rm imported-f4
@@ -8255,9 +8461,10 @@ new revision: delete; previous revision: 1\.1\.1\.1
done"
# update to main line
- dotest import-105 "${testcvs} -q update -A" \
-"${PROG} update: imported-f1 is no longer in the repository
-[UP] imported-f2"
+ dotest import-105 "$testcvs -q update -A" \
+"$PROG update: imported-f1 is no longer in the repository
+[UP] imported-f2
+[UP] imported-f3"
# second import - file4 deliberately unchanged
cd ../import-dir
@@ -8302,16 +8509,20 @@ Use the following command to help the merge:"
done
# check vendor branch for file4
- dotest import-110 "${testcvs} -q update -rvendor-branch" \
-"[UP] imported-f1
-[UP] imported-f2"
+ dotest import-110 "$testcvs -q update -rvendor-branch" \
+'U imported-f1
+[UP] imported-f2
+[UP] imported-f3
+[UP] imported-f4'
dotest import-111 "test -f imported-f4" ''
# update to main line
- dotest import-112 "${testcvs} -q update -A" \
-"${PROG} update: imported-f1 is no longer in the repository
-[UP] imported-f2"
+ dotest import-112 "$testcvs -q update -A" \
+"$PROG update: imported-f1 is no longer in the repository
+[UP] imported-f2
+[UP] imported-f3
+[UP] imported-f4"
cd ..
@@ -8499,7 +8710,12 @@ ${PROG} update: Updating bdir/subdir"
echo modify >>cdir/cfile
dotest importc-5 \
"${testcvs} -q rtag -b -r release wip_test first-dir" ""
- dotest importc-6 "${testcvs} -q update -r wip_test" "M cdir/cfile"
+ dotest importc-6 "$testcvs -q update -r wip_test" \
+'U adir/sub1/file1
+U adir/sub1/ssdir/ssfile
+U adir/sub2/file2
+U bdir/subdir/file1
+M cdir/cfile'
# This used to fail in local mode
dotest importc-7 "${testcvs} -q ci -m modify -r wip_test" \
@@ -8585,12 +8801,16 @@ import-it
mkdir import-CVS
cd import-CVS
touch file1 file2 file3
- dotest_fail import-CVS-1 "$testcvs import CVS vtag rtag" \
+ dotest_fail import-CVS-1 "$testcvs import -mimport CVS vtag rtag" \
+"$PROG import: The word \`CVS' is reserved by CVS and may not be used
+$PROG \[import aborted\]: as a directory in a path or as a file name\."
+ dotest_fail import-CVS-1b \
+"$testcvs import -mimport CVS-/CVS vtag rtag" \
"$PROG import: The word \`CVS' is reserved by CVS and may not be used
$PROG \[import aborted\]: as a directory in a path or as a file name\."
mkdir sdir
mkdir sdir/CVS
- touch sdir/CVS/file4 sdir/CVS/file5 sdir/file6 sdir/file7
+ touch CVS sdir/CVS/file4 sdir/CVS/file5 sdir/file6 sdir/file7
# Calling the imported directory import-CVS is dual purpose in the
# following test. It makes sure the path test which matched above
# wasn't too strict.
@@ -8598,6 +8818,7 @@ $PROG \[import aborted\]: as a directory in a path or as a file name\."
"$testcvs import -I! -mimport import-CVS vtag rtag" \
"
+I import-CVS/CVS
I import-CVS/sdir/CVS
N import-CVS/file1
N import-CVS/file2
@@ -8776,8 +8997,9 @@ U first-dir/file2'
"${testcvs} tag -b TESTTOTRON file1" \
'T file1'
dotest branch-after-import-4 \
-"${testcvs} -q update -r TESTTOTRON" \
-"${PROG} update: file2 is no longer in the repository"
+"$testcvs -q update -r TESTTOTRON" \
+"[UP] file1
+$PROG update: file2 is no longer in the repository"
cp ../imp-dir/file2 .
dotest branch-after-import-5 \
@@ -9119,40 +9341,42 @@ T file9'
cd ../..
mkdir 3
cd 3
- dotest join-16 "${testcvs} -q co -jT1 -jT2 first-dir" \
-'U first-dir/file1
+ dotest join-16 "$testcvs -q co -jT1 -jT2 first-dir" \
+"U first-dir/file1
U first-dir/file2
-'"${PROG}"' checkout: file first-dir/file2 exists, but has been added in revision T2
+$PROG checkout: file first-dir/file2 exists, but has been added in revision T2
U first-dir/file3
-'"${PROG}"' checkout: scheduling first-dir/file3 for removal
+$PROG checkout: scheduling first-dir/file3 for removal
U first-dir/file4
-'"${PROG}"' checkout: scheduling first-dir/file4 for removal
+$PROG checkout: file first-dir/file4 has been removed in revision T2, but the destination is incompatibly modified
+C first-dir/file4
U first-dir/file7
-'"${PROG}"' checkout: file first-dir/file9 does not exist, but is present in revision T2'
+$PROG checkout: file first-dir/file9 does not exist, but is present in revision T2"
# Verify that the right changes have been scheduled.
cd first-dir
- dotest join-17 "${testcvs} -q update" \
+ dotest_fail join-17 "$testcvs -q update" \
'A file1
R file3
-R file4'
+C file4'
# Modify file4 locally, and do an update with a merge.
cd ../../1/first-dir
echo 'third revision of file4' > file4
- dotest join-18 "${testcvs} -q update -jT1 -jT2 ." \
-'U file1
-'"${PROG}"' update: file file2 exists, but has been added in revision T2
-'"${PROG}"' update: scheduling file3 for removal
+ dotest join-18 "$testcvs -q update -jT1 -jT2 ." \
+"U file1
+$PROG update: file file2 exists, but has been added in revision T2
+$PROG update: scheduling file3 for removal
M file4
-'"${PROG}"' update: file file4 is locally modified, but has been removed in revision T2
-'"${PROG}"' update: file file9 does not exist, but is present in revision T2'
+$PROG update: file file4 has been removed in revision T2, but the destination is incompatibly modified
+C file4
+$PROG update: file file9 does not exist, but is present in revision T2"
# Verify that the right changes have been scheduled.
- dotest join-19 "${testcvs} -q update" \
+ dotest_fail join-19 "$testcvs -q update" \
'A file1
R file3
-M file4'
+C file4'
# Do a checkout with a merge from a single revision.
@@ -9167,27 +9391,29 @@ M file4'
# on branches.
cd ../../3
rm -r first-dir
- dotest join-20 "${testcvs} -q co -jbranch first-dir" \
+ dotest join-20 "$testcvs -q co -jbranch first-dir" \
"U first-dir/file1
U first-dir/file2
-RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v
+RCS file: $CVSROOT_DIRNAME/first-dir/file2,v
retrieving revision 1\.1
retrieving revision 1\.1\.2\.2
Merging differences between 1\.1 and 1\.1\.2\.2 into file2
U first-dir/file3
-${PROG} checkout: scheduling first-dir/file3 for removal
+$PROG checkout: scheduling first-dir/file3 for removal
U first-dir/file4
-${PROG} checkout: file first-dir/file4 has been modified, but has been removed in revision branch
+$PROG checkout: file first-dir/file4 has been removed in revision branch, but the destination is incompatibly modified
+C first-dir/file4
U first-dir/file7
-${PROG} checkout: file first-dir/file9 does not exist, but is present in revision branch"
+$PROG checkout: file first-dir/file9 does not exist, but is present in revision branch"
# Verify that the right changes have been scheduled.
# The M file2 line is a bug; see above join-20.
cd first-dir
- dotest join-21 "${testcvs} -q update" \
+ dotest_fail join-21 "$testcvs -q update" \
'A file1
M file2
-R file3'
+R file3
+C file4'
# Checkout the main line again.
cd ../../1
@@ -9203,24 +9429,25 @@ U first-dir/file7'
# The file2 handling is a bug; see above join-20.
cd first-dir
echo 'third revision of file4' > file4
- dotest join-23 "${testcvs} -q update -jbranch ." \
+ dotest join-23 "$testcvs -q update -jbranch ." \
"U file1
-RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v
+RCS file: $CVSROOT_DIRNAME/first-dir/file2,v
retrieving revision 1\.1
retrieving revision 1\.1\.2\.2
Merging differences between 1\.1 and 1\.1\.2\.2 into file2
-${PROG} update: scheduling file3 for removal
+$PROG update: scheduling file3 for removal
M file4
-${PROG} update: file file4 is locally modified, but has been removed in revision branch
-${PROG} update: file file9 does not exist, but is present in revision branch"
+$PROG update: file file4 has been removed in revision branch, but the destination is incompatibly modified
+C file4
+$PROG update: file file9 does not exist, but is present in revision branch"
# Verify that the right changes have been scheduled.
# The M file2 line is a bug; see above join-20
- dotest join-24 "${testcvs} -q update" \
+ dotest_fail join-24 "$testcvs -q update" \
'A file1
M file2
R file3
-M file4'
+C file4'
cd ..
@@ -9238,25 +9465,31 @@ U first-dir/file7'
T file3
T file4
T file7"
- dotest join-27 "${testcvs} -q update -r br2" ""
+ dotest join-27 "$testcvs -q update -r br2" \
+'[UP] file2
+[UP] file3
+[UP] file4
+[UP] file7'
# The handling of file8 and file9 here look fishy to me. I don't
# see why it should be different from the case where we merge to
# the trunk (e.g. join-23).
- dotest join-28 "${testcvs} -q update -j branch" \
+ dotest join-28 "$testcvs -q update -j branch" \
"U file1
-RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v
-retrieving revision 1.1
-retrieving revision 1.1.2.2
-Merging differences between 1.1 and 1.1.2.2 into file2
-${PROG} update: scheduling file3 for removal
-${PROG} update: file file4 has been modified, but has been removed in revision branch
+RCS file: $CVSROOT_DIRNAME/first-dir/file2,v
+retrieving revision 1\.1
+retrieving revision 1\.1\.2\.2
+Merging differences between 1\.1 and 1\.1\.2\.2 into file2
+$PROG update: scheduling file3 for removal
+$PROG update: file file4 has been removed in revision branch, but the destination is incompatibly modified
+C file4
U file8
U file9"
# Verify that the right changes have been scheduled.
- dotest join-29 "${testcvs} -q update" \
+ dotest_fail join-29 "$testcvs -q update" \
"A file1
M file2
R file3
+C file4
A file8
A file9"
@@ -9267,35 +9500,37 @@ A file9"
# once that if the file was removed in the update then it wouldn't be
# readded in the merge
cd ..
- rm -r first-dir
+ rm -rf first-dir
dotest join-twobranch-1 "${testcvs} -q co -rbranch first-dir" \
'U first-dir/file1
U first-dir/file2
U first-dir/file8
U first-dir/file9'
cd first-dir
- dotest join-twobranch-2 "${testcvs} -q update -rbr2 -jbranch" \
-"${PROG} update: file1 is no longer in the repository
+ dotest join-twobranch-2 "$testcvs -q update -rbr2 -jbranch" \
+"$PROG update: file1 is no longer in the repository
U file1
U file2
-RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v
+RCS file: $CVSROOT_DIRNAME/first-dir/file2,v
retrieving revision 1\.1
retrieving revision 1\.1\.2\.2
Merging differences between 1\.1 and 1\.1\.2\.2 into file2
U file3
-${PROG} update: scheduling file3 for removal
+$PROG update: scheduling file3 for removal
U file4
-${PROG} update: file file4 has been modified, but has been removed in revision branch
+$PROG update: file file4 has been removed in revision branch, but the destination is incompatibly modified
+C file4
U file7
-${PROG} update: file8 is no longer in the repository
+$PROG update: file8 is no longer in the repository
U file8
-${PROG} update: file9 is no longer in the repository
+$PROG update: file9 is no longer in the repository
U file9"
# Verify that the right changes have been scheduled.
- dotest join-twobranch-3 "${testcvs} -q update" \
+ dotest_fail join-twobranch-3 "$testcvs -q update" \
"A file1
M file2
R file3
+C file4
A file8
A file9"
@@ -9385,7 +9620,7 @@ ${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1
initial revision: 1\.1
done"
dotest join2-5 "${testcvs} -q tag -b br1" "T file1"
- dotest join2-6 "${testcvs} -q update -r br1" ""
+ dotest join2-6 "$testcvs -q update -r br1" '[UP] file1'
echo 'modify on branch' >>file1
touch bradd
dotest join2-6a "${testcvs} add bradd" \
@@ -9502,7 +9737,7 @@ ${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1
initial revision: 1\.1
done"
dotest join3-5 "${testcvs} -q tag -b br1" "T file1"
- dotest join3-6 "${testcvs} -q update -r br1" ""
+ dotest join3-6 "$testcvs -q update -r br1" '[UP] file1'
echo 'br1:line1' >>file1
dotest join3-7 "${testcvs} -q ci -m modify" \
"Checking in file1;
@@ -9798,27 +10033,28 @@ T file9'
# Modify file4 locally, and do an update with a merge.
cd ../../1/first-dir
echo 'third revision of file4' > file4
- dotest join4-18 "${testcvs} -q update -jT1 -jT2 ." \
-'U file1
+ dotest join4-18 "$testcvs -q update -jT1 -jT2 ." \
+"U file1
R file10
A file2
-'"${PROG}"' update: file file2 exists, but has been added in revision T2
-'"${PROG}"' update: scheduling file3 for removal
+$PROG update: file file2 exists, but has been added in revision T2
+$PROG update: scheduling file3 for removal
M file4
-'"${PROG}"' update: file file4 is locally modified, but has been removed in revision T2
+$PROG update: file file4 has been removed in revision T2, but the destination is incompatibly modified
+C file4
R file6
A file7
R file8
R file9
-'"${PROG}"' update: file file9 does not exist, but is present in revision T2'
+$PROG update: file file9 does not exist, but is present in revision T2"
# Verify that the right changes have been scheduled.
- dotest join4-19 "${testcvs} -q update" \
+ dotest_fail join4-19 "${testcvs} -q update" \
'A file1
R file10
A file2
R file3
-M file4
+C file4
R file6
A file7
R file8
@@ -10143,6 +10379,138 @@ rcsmerge: warning: conflicts during merge"
+ join8)
+ # In this test case, we have 2 projects, one called "pvcs" and one
+ # called "project". The "pvcs" project has modified the file, while
+ # the "project" project has caused a deletion. When "project" is
+ # merged into "pvcs", we expect CVS to detect a conflict.
+ mkdir join8; cd join8
+ mkdir combine
+ mkdir base
+ mkdir pvcs
+ mkdir project
+
+ echo "aaa" >base/file.txt
+ echo "bbb" >pvcs/file.txt
+ echo "ccc" >project/xxx.txt
+
+ cd base
+ dotest join8-1 \
+"$testcvs import -b 1.1.101 -ko -m 'base import' join8 base base-1" \
+"N join8/file\.txt
+
+No conflicts created by this import"
+
+ cd ../pvcs
+ dotest join8-2 \
+"$testcvs import -b 1.1.201 -ko -m 'pvcs import' join8 pvcs pvcs-1" \
+"C join8/file\.txt
+
+1 conflicts created by this import.
+Use the following command to help the merge:
+
+ $PROG checkout -j<prev_rel_tag> -jpvcs-1 join8"
+
+ cd ../project
+ dotest join8-3 \
+"$testcvs import -b 1.1.301 -ko -m 'project import' join8 project project-1" \
+"N join8/xxx\.txt
+
+No conflicts created by this import"
+
+ cd ..
+ dotest join8-4 \
+"$testcvs checkout -r pvcs-1 -j base-1 -j project-1 -d combine join8" \
+"$PROG checkout: Updating combine
+U combine/file\.txt
+$PROG checkout: file combine/file\.txt has been removed in revision project-1, but the destination is incompatibly modified
+C combine/file.txt
+U combine/xxx\.txt"
+
+ dotest join8-5 \
+"$testcvs -Q up -pr base-1 combine/file.txt >combine/file.txt"
+
+ dotest join8-6 \
+"$testcvs up -j base-1 -j project-1 combine" \
+"$PROG update: Updating combine
+M combine/file\.txt
+$PROG update: scheduling combine/file\.txt for removal
+A combine/xxx\.txt
+$PROG update: file combine/xxx\.txt exists, but has been added in revision project-1"
+ cd ..
+
+ if $keep; then
+ echo Keeping $TESTDIR and exiting due to --keep
+ exit 0
+ fi
+
+ rm -r join8
+ rm -rf $CVSROOT_DIRNAME/join8
+ ;;
+
+
+
+ join9)
+ # In this test case, we have 2 projects, one called "pvcs" and one
+ # called "project". The "pvcs" project has not modified the file,
+ # while the "project" project has caused a deletion. When "project"
+ # is merged into "pvcs", we expect CVS to remove the file without
+ # fuss, as there is no conflict.
+ mkdir join9; cd join9
+ mkdir combine
+ mkdir base
+ mkdir pvcs
+ mkdir project
+
+ echo "aaa" >base/file.txt
+ echo "aaa" >pvcs/file.txt
+ echo "ccc" >project/xxx.txt
+
+ cd base
+ dotest join9-1 \
+"$testcvs import -b 1.1.101 -ko -m 'base import' join9 base base-1" \
+"N join9/file\.txt
+
+No conflicts created by this import"
+
+ cd ../pvcs
+ dotest join9-2 \
+"$testcvs import -b 1.1.201 -ko -m 'pvcs import' join9 pvcs pvcs-1" \
+"C join9/file\.txt
+
+1 conflicts created by this import.
+Use the following command to help the merge:
+
+ $PROG checkout -j<prev_rel_tag> -jpvcs-1 join9"
+
+ cd ../project
+ dotest join9-3 \
+"$testcvs import -b 1.1.301 -ko -m 'project import' join9 project project-1" \
+"N join9/xxx\.txt
+
+No conflicts created by this import"
+
+ cd ..
+ dotest join9-4 \
+"$testcvs checkout -r pvcs-1 -j base-1 -j project-1 -d combine join9" \
+"$PROG checkout: Updating combine
+U combine/file\.txt
+$PROG checkout: scheduling combine/file\.txt for removal
+U combine/xxx\.txt"
+
+ cd ..
+
+ if $keep; then
+ echo Keeping $TESTDIR and exiting due to --keep
+ exit 0
+ fi
+
+ rm -r join9
+ rm -rf $CVSROOT_DIRNAME/join9
+ ;;
+
+
+
join-readonly-conflict)
# Previously, only tests 1 & 11 were being tested. I added the
# intermediate dotest's to try and diagnose a different failure
@@ -10174,7 +10542,8 @@ initial revision: 1\.1
done"
dotest join-readonly-conflict-4 "$testcvs tag -b B $file" "T $file"
- dotest join-readonly-conflict-5 "$testcvs -q update -rB $file" ''
+ dotest join-readonly-conflict-5 "$testcvs -q update -rB $file" \
+"[UP] $file"
echo branch B > $file
dotest join-readonly-conflict-6 "$testcvs -q ci -m . $file" \
"Checking in $file;
@@ -10507,7 +10876,11 @@ done"
#
# FIXCVS: This update should merge the removal to the trunk. It does
# not.
- dotest join-rm-5 "$testcvs -q up -A" "U a"
+ dotest join-rm-5 "$testcvs -q up -A" \
+'U a
+U c
+U e
+U f'
# and verify that there is no sticky tag
dotest join-rm-6 "$testcvs status a" \
@@ -11402,9 +11775,9 @@ EOF
Argument --
Directory .
$CVSROOT_DIRNAME/first-dir
-Entry /file1/1.2/+=//
+Entry /file1/1.2/$PLUS=//
Modified file1
-u=rw,g=rw,o=r
+u=.*,g=.*,o=.*
59
baseline
""<<<<<<< file1
@@ -11436,7 +11809,7 @@ EOF
Argument --
Directory .
$CVSROOT_DIRNAME/first-dir
-Entry /file1/1.2/+=//
+Entry /file1/1.2/$PLUS=//
Unchanged file1
update"
@@ -14980,18 +15353,10 @@ done"
dotest trailingslashes-1 "$testcvs -q up CVSROOT"
dotest_fail trailingslashes-1a "test -f topfile"
- # FIXCVS:
- # Now the one that fails in remote mode.
- # This highlights one of the failure cases mentioned in TODO item
- # #205.
- if $remote; then
- dotest trailingslashes-2 "$testcvs -q up CVSROOT/" \
-"U topfile"
- dotest trailingslashes-2a "test -f topfile"
- else
- dotest trailingslashes-2 "$testcvs -q up CVSROOT/"
- dotest_fail trailingslashes-2a "test -f topfile"
- fi
+ # Now the one that used to fail in remote mode prior to 1.11.24
+ # & 1.12.14. Formerly TODO item #205.
+ dotest trailingslashes-2 "$testcvs -q up CVSROOT/"
+ dotest_fail trailingslashes-2a "test -f topfile"
if $keep; then
echo Keeping $TESTDIR and exiting due to --keep
@@ -15149,7 +15514,9 @@ initial revision: 1\.1
done"
dotest editor-5 "${testcvs} -q tag -b br" "T file1
T file2"
- dotest editor-6 "${testcvs} -q update -r br" ''
+ dotest editor-6 "$testcvs -q update -r br" \
+'U file1
+U file2'
echo modify >>file1
dotest editor-7 "${testcvs} -e ${TESTDIR}/editme -q ci" \
"Checking in file1;
@@ -15161,7 +15528,9 @@ done"
# without being on the branch, because there is not a revision
# already on the branch. If there were a revision on the branch,
# CVS would correctly give an up-to-date check failed.
- dotest editor-8 "${testcvs} -q update -A" "U file1"
+ dotest editor-8 "$testcvs -q update -A" \
+'U file1
+U file2'
echo add a line >>file2
dotest editor-9 "${testcvs} -q -e ${TESTDIR}/editme ci -rbr file2" \
"Checking in file2;
@@ -15416,12 +15785,7 @@ date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; lines: +0 -0
exit 0
fi
- # restore the default loginfo script
- rm -f ${CVSROOT_DIRNAME}/CVSROOT/loginfo,v \
- ${CVSROOT_DIRNAME}/CVSROOT/loginfo \
- ${CVSROOT_DIRNAME}/CVSROOT/commitlog
- dotest editor-emptylog-continue-cleanup-1 "${testcvs} init" ''
-
+ restore_adm
cd ../..
rm -r 1
rm ${TESTDIR}/editme
@@ -16604,7 +16968,8 @@ $CVSROOT_DIRNAME/ignore-on-branch/file2,v <-- file2
new revision: 1\.1\.2\.2; previous revision: 1\.1\.2\.1
done"
dotest ignore-on-branch-6 "$testcvs -q up -rbranch2" \
-"${PROG} update: file2 is no longer in the repository"
+"[UP] file1
+$PROG update: file2 is no longer in the repository"
dotest ignore-on-branch-7 "$testcvs -q up -jbranch" 'U file2'
cd ../..
@@ -16975,7 +17340,10 @@ done"
dotest binfiles2-2 "${testcvs} -q tag -b br" 'T brmod
T brmod-trmod
T brmod-wdmod'
- dotest binfiles2-3 "${testcvs} -q update -r br" ''
+ dotest binfiles2-3 "$testcvs -q update -r br" \
+'U brmod
+U brmod-trmod
+U brmod-wdmod'
cp ../binfile binfile.dat
dotest binfiles2-4 "${testcvs} add -kb binfile.dat" \
"${PROG} add: scheduling file .binfile\.dat. for addition on branch .br.
@@ -17258,7 +17626,11 @@ done"
T brmod
T brmod-trmod
T brmod-wdmod'
- dotest mcopy-3 "${testcvs} -q update -r br" ''
+ dotest mcopy-3 "$testcvs -q update -r br" \
+'U .cvswrappers
+U brmod
+U brmod-trmod
+U brmod-wdmod'
echo 'modify brmod on br' >brmod
echo 'modify brmod-trmod on br' >brmod-trmod
echo 'modify brmod-wdmod on br' >brmod-wdmod
@@ -17275,10 +17647,11 @@ Checking in brmod-wdmod;
${CVSROOT_DIRNAME}/first-dir/brmod-wdmod,v <-- brmod-wdmod
new revision: 1\.1\.2\.1; previous revision: 1\.1
done"
- dotest mcopy-6 "${testcvs} -q update -A" \
-"[UP] brmod
-[UP] brmod-trmod
-[UP] brmod-wdmod"
+ dotest mcopy-6 "$testcvs -q update -A" \
+'U .cvswrappers
+U brmod
+U brmod-trmod
+U brmod-wdmod'
dotest mcopy-7 "cat brmod brmod-trmod brmod-wdmod" \
"brmod initial contents
brmod-trmod initial contents
@@ -18201,7 +18574,7 @@ initial revision: 1\.1
done"
dotest taginfo-6 "${testcvs} -q tag tag1" "T file1"
dotest taginfo-7 "${testcvs} -q tag -b br" "T file1"
- dotest taginfo-8 "${testcvs} -q update -r br" ""
+ dotest taginfo-8 "$testcvs -q update -r br" '[UP] file1'
echo add text on branch >>file1
dotest taginfo-9 "${testcvs} -q ci -m modify-on-br" \
"Checking in file1;
@@ -18307,6 +18680,23 @@ new revision: 1\.[0-9]*; previous revision: 1\.[0-9]*
done
${PROG} commit: Rebuilding administrative file database"
dotest config-6 "${testcvs} -q update" ''
+ echo 'IgnoreUnknownConfigKeys=yes' > config
+ echo 'BogusOption=yes' >> config
+ dotest config-7 "${testcvs} -q ci -m change-to-comment" \
+"Checking in config;
+${CVSROOT_DIRNAME}/CVSROOT/config,v <-- config
+new revision: 1\.[0-9]*; previous revision: 1\.[0-9]*
+done
+${PROG} commit: Rebuilding administrative file database"
+ dotest config-8 "${testcvs} -q update" ''
+ echo '# No config is a good config' > config
+ dotest config-9 "${testcvs} -q ci -m change-to-comment" \
+"Checking in config;
+${CVSROOT_DIRNAME}/CVSROOT/config,v <-- config
+new revision: 1\.[0-9]*; previous revision: 1\.[0-9]*
+done
+${PROG} commit: Rebuilding administrative file database"
+ dotest config-10 "${testcvs} -q update" ''
cd ..
rm -r CVSROOT
@@ -18351,9 +18741,10 @@ done"
dotest serverpatch-5 "${testcvs} -q co -r tag first-dir" \
'U first-dir/file1'
- # Remove the tag. This will leave the tag string in the
+ # Remove the tag. Prior to 1.11.23, this left the tag string in the
# expansion of the Name keyword.
- dotest serverpatch-6 "${testcvs} -q update -A first-dir" ''
+ dotest serverpatch-6 "$testcvs -q update -A first-dir" \
+'U first-dir/file1'
# Modify and check in the first copy.
cd ../1/first-dir
@@ -18364,16 +18755,11 @@ ${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1
new revision: 1\.2; previous revision: 1\.1
done"
- # Now update the second copy. When using remote CVS, the
- # patch will fail, forcing the file to be refetched.
+ # Now update the second copy. Prior to 1.11.23, the patch would fail
+ # using remote CVS, forcing the file to be refetched.
cd ../../2/first-dir
dotest serverpatch-8 "${testcvs} -q update" \
-'U file1' \
-"P file1
-${PROG} update: checksum failure after patch to \./file1; will refetch
-${PROG} client: refetching unpatchable files
-${PROG} update: warning: file1 was lost
-U file1"
+'[UP] file1'
cd ../..
rm -r 1 2
@@ -19639,6 +20025,19 @@ Annotations for file1
1\.2 ($username8 *[0-9a-zA-Z-]*): a
1\.2 ($username8 *[0-9a-zA-Z-]*): blank
1\.2 ($username8 *[0-9a-zA-Z-]*): line"
+ dotest ann-10blame "${testcvs} blame" \
+"
+Annotations for file1
+\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
+1\.1 ($username8 *[0-9a-zA-Z-]*): this
+1\.1 ($username8 *[0-9a-zA-Z-]*): is
+1\.2 ($username8 *[0-9a-zA-Z-]*): a
+1\.3 ($username8 *[0-9a-zA-Z-]*): trunk file
+1\.2 ($username8 *[0-9a-zA-Z-]*):
+1\.2 ($username8 *[0-9a-zA-Z-]*): with
+1\.2 ($username8 *[0-9a-zA-Z-]*): a
+1\.2 ($username8 *[0-9a-zA-Z-]*): blank
+1\.2 ($username8 *[0-9a-zA-Z-]*): line"
dotest ann-11 "${testcvs} ann -r br" \
"
Annotations for file1
@@ -19871,16 +20270,6 @@ ${PROG} [a-z]*: Perhaps you entered a relative pathname${QUESTION}
${PROG} \[[a-z]* aborted\]: Bad CVSROOT: .:ext:${hostname}:\.\./crerepos.\."
cd ..
rm -r 1
-
- mkdir 1; cd 1
- dotest_fail crerepos-6b-r \
-"${testcvs} -d :ext:`hostname`:crerepos init" \
-"${PROG} [a-z]*: CVSROOT requires a path spec:
-${PROG} [a-z]*: :(gserver|kserver|pserver):\[\[user\]\[:password\]@\]host\[:\[port\]\]/path
-${PROG} [a-z]*: \[:(ext|server):\]\[\[user\]@\]host\[:\]/path
-${PROG} \[[a-z]* aborted\]: Bad CVSROOT: .:ext:${hostname}:crerepos.\."
- cd ..
- rm -r 1
else # local
# Test that CVS rejects a relative path in CVSROOT.
@@ -19982,6 +20371,202 @@ ${PROG} update: Updating crerepos-dir"
+ crerepos-extssh)
+ # Various tests relating to creating repositories, operating
+ # on repositories created with old versions of CVS, etc.
+
+ CVS_SERVER_save=$CVS_SERVER
+
+ # Because this test is all about -d options and such, it
+ # at least to some extent needs to be different for remote vs.
+ # local.
+ if $remote; then
+
+ # Use :extssh: rather than :fork:. Most of the tests use :fork:,
+ # so we want to make sure that we test :extssh: _somewhere_.
+ # Make sure 'ssh' works first.
+ depends_on_rsh "$CVS_RSH"
+ if test $? -eq 77; then
+ skip crerepos "$skipreason"
+ continue
+ fi
+
+ # For remote, just create the repository. We don't yet do
+ # the various other tests above for remote but that should be
+ # changed.
+ mkdir crerepos
+ mkdir crerepos/CVSROOT
+
+ # Make sure server ignores real ${HOME}/.cvsrc:
+ cat >$TESTDIR/cvs-setHome <<EOF
+#!/bin/sh
+HOME=$HOME
+export HOME
+exec $CVS_SERVER_save "\$@"
+EOF
+ chmod a+x $TESTDIR/cvs-setHome
+
+ # Note that we set CVS_SERVER at the beginning.
+ CVS_SERVER=$TESTDIR/cvs-setHome; export CVS_SERVER
+ CREREPOS_ROOT=:extssh:$host$TESTDIR/crerepos
+ else
+
+ # First, if the repository doesn't exist at all...
+ dotest_fail crerepos-extssh-1 \
+"${testcvs} -d ${TESTDIR}/crerepos co cvs-sanity" \
+"${PROG} \[checkout aborted\]: ${TESTDIR}/crerepos/CVSROOT: .*"
+ mkdir crerepos
+
+ # The repository exists but CVSROOT doesn't.
+ dotest_fail crerepos-extssh-2 \
+"${testcvs} -d ${TESTDIR}/crerepos co cvs-sanity" \
+"${PROG} \[checkout aborted\]: ${TESTDIR}/crerepos/CVSROOT: .*"
+ mkdir crerepos/CVSROOT
+
+ # Checkout of nonexistent module
+ dotest_fail crerepos-extssh-3 \
+"${testcvs} -d ${TESTDIR}/crerepos co cvs-sanity" \
+"${PROG} checkout: cannot find module .cvs-sanity. - ignored"
+
+ # Now test that CVS works correctly without a modules file
+ # or any of that other stuff. In particular, it *must*
+ # function if administrative files added to CVS recently (since
+ # CVS 1.3) do not exist, because the repository might have
+ # been created with an old version of CVS.
+ mkdir 1; cd 1
+ dotest crerepos-extssh-4 \
+"${testcvs} -q -d ${TESTDIR}/crerepos co CVSROOT" \
+''
+ if echo yes | \
+${testcvs} -d ${TESTDIR}/crerepos release -d CVSROOT >>${LOGFILE}; then
+ pass crerepos-extssh-5
+ else
+ fail crerepos-extssh-5
+ fi
+ rm -rf CVS
+ cd ..
+ # The directory 1 should be empty
+ dotest crerepos-extssh-6 "rmdir 1"
+
+ CREREPOS_ROOT=${TESTDIR}/crerepos
+
+ fi
+
+ if $remote; then
+ # Test that CVS rejects a relative path in CVSROOT.
+ mkdir 1; cd 1
+ # Note that having the client reject the pathname (as :fork:
+ # does), does _not_ test for the bugs we are trying to catch
+ # here. The point is that malicious clients might send all
+ # manner of things and the server better protect itself.
+ dotest_fail crerepos-extssh-6a-r \
+"${testcvs} -q -d :extssh:`hostname`:../crerepos get ." \
+"${PROG} [a-z]*: CVSROOT may only specify a positive, non-zero, integer port (not .\.\..)\.
+${PROG} [a-z]*: Perhaps you entered a relative pathname${QUESTION}
+${PROG} \[[a-z]* aborted\]: Bad CVSROOT: .:extssh:${hostname}:\.\./crerepos.\."
+ cd ..
+ rm -r 1
+ else # local
+ # Test that CVS rejects a relative path in CVSROOT.
+
+ mkdir 1; cd 1
+ # Set CVS_RSH=false since ocassionally (e.g. when CVS_RSH=ssh on
+ # some systems) some rsh implementations will block because they
+ # can look up '..' and want to ask the user about the unknown host
+ # key or somesuch. Which error message we get depends on whether
+ # false finishes running before we try to talk to it or not.
+ dotest_fail crerepos-extssh-6a "CVS_RSH=false ${testcvs} -q -d ../crerepos get ." \
+"${PROG} \[checkout aborted\]: .*" \
+"${PROG} checkout: CVSROOT is set for a remote access method but your
+${PROG} checkout: CVS executable doesn't support it\.
+${PROG} \[checkout aborted\]: Bad CVSROOT: .\.\./crerepos.\."
+ cd ..
+ rm -r 1
+
+ mkdir 1; cd 1
+ dotest_fail crerepos-extssh-6b "${testcvs} -d crerepos init" \
+"${PROG} init: CVSROOT must be an absolute pathname (not .crerepos.)
+${PROG} init: when using local access method\.
+${PROG} \[init aborted\]: Bad CVSROOT: .crerepos.\."
+ cd ..
+ rm -r 1
+ fi # end of tests to be skipped for remote
+
+ # CVS better not create a history file--if the administrator
+ # doesn't need it and wants to save on disk space, they just
+ # delete it.
+ dotest_fail crerepos-extssh-7 \
+"test -f ${TESTDIR}/crerepos/CVSROOT/history" ''
+
+ # Now test mixing repositories. This kind of thing tends to
+ # happen accidentally when people work with several repositories.
+ mkdir 1; cd 1
+ dotest crerepos-extssh-8 "${testcvs} -q co -l ." ''
+ mkdir first-dir
+ dotest crerepos-extssh-9 "${testcvs} add first-dir" \
+"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository"
+ cd first-dir
+ touch file1
+ dotest crerepos-extssh-10 "${testcvs} add file1" \
+"${PROG} add: scheduling file .file1. for addition
+${PROG} add: use .${PROG} commit. to add this file permanently"
+ dotest crerepos-extssh-11 "${testcvs} -q ci -m add-it" \
+"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v
+done
+Checking in file1;
+${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1
+initial revision: 1\.1
+done"
+ cd ../..
+ rm -r 1
+
+ mkdir 1; cd 1
+ dotest crerepos-extssh-12 "${testcvs} -d ${CREREPOS_ROOT} -q co -l ." ''
+ mkdir crerepos-dir
+ dotest crerepos-extssh-13 "${testcvs} add crerepos-dir" \
+"Directory ${TESTDIR}/crerepos/crerepos-dir added to the repository"
+ cd crerepos-dir
+ touch cfile
+ dotest crerepos-extssh-14 "${testcvs} add cfile" \
+"${PROG} add: scheduling file .cfile. for addition
+${PROG} add: use .${PROG} commit. to add this file permanently"
+ dotest crerepos-extssh-15 "${testcvs} -q ci -m add-it" \
+"RCS file: ${TESTDIR}/crerepos/crerepos-dir/cfile,v
+done
+Checking in cfile;
+${TESTDIR}/crerepos/crerepos-dir/cfile,v <-- cfile
+initial revision: 1\.1
+done"
+ cd ../..
+ rm -r 1
+
+ mkdir 1; cd 1
+ dotest crerepos-extssh-16 "${testcvs} co first-dir" \
+"${PROG} checkout: Updating first-dir
+U first-dir/file1"
+ dotest crerepos-extssh-17 "${testcvs} -d ${CREREPOS_ROOT} co crerepos-dir" \
+"${PROG} checkout: Updating crerepos-dir
+U crerepos-dir/cfile"
+ dotest crerepos-extssh-18 "${testcvs} update" \
+"${PROG} update: Updating first-dir
+${PROG} update: Updating crerepos-dir"
+
+ cd ..
+
+ CVS_SERVER=$CVS_SERVER_save; export CVS_SERVER
+
+ if $keep; then
+ echo Keeping ${TESTDIR} and exiting due to --keep
+ exit 0
+ fi
+
+ rm -f $TESTDIR/cvs-setHome
+ rm -r 1
+ rm -rf ${CVSROOT_DIRNAME}/first-dir ${TESTDIR}/crerepos
+ ;;
+
+
+
rcs)
# Test ability to import an RCS file. Note that this format
# is fixed--files written by RCS5, and other software which
@@ -20225,7 +20810,7 @@ EOF
# Check in a revision on the branch to force CVS to
# interpret every revision in the file.
- dotest rcs-6a "${testcvs} -q update -r branch file2" ""
+ dotest rcs-6a "$testcvs -q update -r branch file2" 'U file2'
echo "next branch revision" > file2
dotest rcs-6b "${testcvs} -q ci -m mod file2" \
"Checking in file2;
@@ -20969,7 +21554,8 @@ $PROG commit: \[[0-9:]*\] obtained lock in $CVSROOT_DIRNAME/CVSROOT"
(sleep 5; rmdir "$TESTDIR/locks/CVSROOT/#cvs.val-tags.lock")&
dotest lockfiles-22 "$testcvs -q up -r newtag first-dir" \
"$PROG update: \[[0-9:]*\] waiting for $username's lock in $CVSROOT_DIRNAME/CVSROOT
-$PROG update: \[[0-9:]*\] obtained lock in $CVSROOT_DIRNAME/CVSROOT"
+$PROG update: \[[0-9:]*\] obtained lock in $CVSROOT_DIRNAME/CVSROOT
+[UP] first-dir/sdir/ssdir/file1"
cd CVSROOT
echo "# nobody here but us comments" >config
@@ -21688,7 +22274,9 @@ done"
# set the same way (it is a different code path in CVS).
dotest modes-11 "${testcvs} -q tag -b br" 'T aa
T ab'
- dotest modes-12 "${testcvs} -q update -r br" ''
+ dotest modes-12 "$testcvs -q update -r br" \
+'[UP] aa
+U ab'
touch ac
dotest modes-13 "${testcvs} add ac" \
"${PROG} add: scheduling file .ac. for addition on branch .br.
@@ -22437,7 +23025,7 @@ xx"
1\.1 locked
done"
- dotest keyword-7 "${testcvs} update -kkv file1" "U file1"
+ dotest keyword-7 "$testcvs update -kkv file1" '[UP] file1'
dotest keyword-8 "cat file1" \
'\$'"Author: ${username} "'\$'"
"'\$'"Date: [0-9][0-9][0-9][0-9]/[0-9][0-9]/[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9] "'\$'"
@@ -22457,7 +23045,7 @@ xx Revision 1\.1 [0-9/]* [0-9:]* ${username}
xx add
xx"
- dotest keyword-9 "${testcvs} update -kkvl file1" "U file1"
+ dotest keyword-9 "$testcvs update -kkvl file1" '[UP] file1'
dotest keyword-10 "cat file1" \
'\$'"Author: ${username} "'\$'"
"'\$'"Date: [0-9][0-9][0-9][0-9]/[0-9][0-9]/[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9] "'\$'"
@@ -22477,7 +23065,7 @@ xx Revision 1\.1 [0-9/]* [0-9:]* ${username}
xx add
xx"
- dotest keyword-11 "${testcvs} update -kk file1" "U file1"
+ dotest keyword-11 "${testcvs} update -kk file1" '[UP] file1'
dotest keyword-12 "cat file1" \
'\$'"Author"'\$'"
"'\$'"Date"'\$'"
@@ -22497,7 +23085,7 @@ xx Revision 1\.1 [0-9/]* [0-9:]* ${username}
xx add
xx"
- dotest keyword-13 "${testcvs} update -kv file1" "U file1"
+ dotest keyword-13 "$testcvs update -kv file1" '[UP] file1'
dotest keyword-14 "cat file1" \
"${username}
[0-9][0-9][0-9][0-9]/[0-9][0-9]/[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9]
@@ -22551,30 +23139,17 @@ done"
${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1
new revision: 1\.3; previous revision: 1\.2
done"
- # FIXCVS - These unpatchable files are happening because the tag
- # associated with the current base version of the file in the
- # sandbox is not available in these cases. See the note in the
- # patch_file function in update.c.
- dotest keyword-21 "${testcvs} -q update -r tag1" "U file1" \
-"P file1
-${PROG} update: checksum failure after patch to \./file1; will refetch
-${PROG} client: refetching unpatchable files
-${PROG} update: warning: file1 was lost
-U file1"
+
+ # Prior to 1.11.23, remote CVS would fail the patch checksum test
+ # and refetch the file here, failing this test.
+ dotest keyword-21 "$testcvs -q update -r tag1" 'U file1'
dotest keyword-22 "cat file1" '\$'"Name: tag1 "'\$'
- if $remote; then
- # Like serverpatch-8. Not sure there is anything much we
- # can or should do about this.
- dotest keyword-23r "${testcvs} update -A file1" "P file1
-${PROG} update: checksum failure after patch to \./file1; will refetch
-${PROG} client: refetching unpatchable files
-${PROG} update: warning: file1 was lost
-U file1"
- else
- dotest keyword-23 "${testcvs} update -A file1" "[UP] file1"
- fi
+ # The update used to fail the first time with a checksum failure
+ # here, then the server would send the whole failure. This was fixed
+ # in 1.11.23.
+ dotest keyword-23 "$testcvs update -A file1" "U file1"
dotest keyword-24 "cat file1" '\$'"Name: "'\$'"
change"
@@ -22839,8 +23414,17 @@ Checking in file2;
${CVSROOT_DIRNAME}/first-dir/file2,v <-- file2
initial revision: 1\.3
done"
+ dotest keywordname-init-5b "cat file1" \
+'\$''Name: \$'
+ dotest keywordname-init-5c "cat file2" \
+'\$''Name: \$'
+
+ dotest keywordname-init-6 "$testcvs -q up -A"
+ dotest keywordname-init-6b "cat file1" \
+'\$''Name: \$'
+ dotest keywordname-init-6c "cat file2" \
+'\$''Name: \$'
- dotest keywordname-init-6 "${testcvs} -q up -A"
dotest keywordname-init-7 "${testcvs} -q tag -b br" \
"T file1
T file2"
@@ -22857,59 +23441,53 @@ done"
# There used to be a bug where static tags would be substituted for
# Name keywords but not branch tags.
#
- # FIXCVS - BUG
- # Why shouldn't the non-update case not cause a substitution?
- # An update -kk or -A will unsub and sub keywords without updates
- # being required.
- # FIXCVS - see note above keyword-21
- dotest keywordname-update-1 "${testcvs} -q up -rbr" "U file1" \
-"P file1
-${PROG} update: checksum failure after patch to \./file1; will refetch
-${PROG} client: refetching unpatchable files
-${PROG} update: warning: file1 was lost
-U file1"
- dotest keywordname-update-2 "cat file1" '\$'"Name: br "'\$'
- dotest keywordname-update-3 "cat file2" '\$'"Name: "'\$'
+ # Prior to 1.11.23, there also used to be a bug where keyword
+ # substitutions were not performed unless the file was otherwise
+ # updated. When this bug was present, keywordname-update-1 would
+ # report a patch checksum failure and refetch file1 in client/server
+ # mode and no `br' would have been substituted into Name's value for
+ # file2, meaning keywordname-update-3 would also fail.
+ dotest keywordname-update-1 "$testcvs -q up -rbr" \
+'U file1
+U file2'
+ dotest keywordname-update-2 "cat file1" '\$''Name: br \$'
+
+ # For the same reason keywordname-update-1 would fail above, no `br'
+ # would have been substituted into Name's value here prior to
+ # 1.11.23.
+ dotest keywordname-update-3 "cat file2" '\$''Name: br \$'
# Now verify that updating to the trunk leaves no substitution for
# $Name
dotest keywordname-update-4 "${testcvs} -q tag firsttag" \
"T file1
T file2"
- # FIXCVS - see note above keyword-21
- dotest keywordname-update-5 "${testcvs} -q up -A" "U file1" \
-"P file1
-${PROG} update: checksum failure after patch to \./file1; will refetch
-${PROG} client: refetching unpatchable files
-${PROG} update: warning: file1 was lost
-U file1"
+ # This used to fail in the same manner as keywordname-update-1.
+ dotest keywordname-update-5 "$testcvs -q up -A" \
+'U file1
+U file2'
dotest keywordname-update-6 "cat file1" \
-'\$'"Name: "'\$'"
-new data"
- dotest keywordname-update-7 "cat file2" '\$'"Name: "'\$'
-
- # But updating to a static tag does cause a substitution
- # FIXCVS - see same note above
- dotest keywordname-update-8 "${testcvs} -q up -rfirsttag" "U file1" \
-"P file1
-${PROG} update: checksum failure after patch to \./file1; will refetch
-${PROG} client: refetching unpatchable files
-${PROG} update: warning: file1 was lost
-U file1"
- dotest keywordname-update-9 "cat file1" '\$'"Name: firsttag "'\$'
- dotest keywordname-update-10 "cat file2" '\$'"Name: "'\$'
+'\$''Name: \$
+new data'
+ dotest keywordname-update-7 "cat file2" '\$''Name: \$'
+
+ # This used to fail in the same manner as keywordname-update-1.
+ dotest keywordname-update-8 "$testcvs -q up -rfirsttag" \
+'U file1
+U file2'
+ dotest keywordname-update-9 "cat file1" '\$''Name: firsttag \$'
+
+ # This used to fail in the same manner as keywordname-update-3.
+ dotest keywordname-update-10 "cat file2" '\$''Name: firsttag \$'
# And reverify the trunk update when the change is actually removed.
- dotest keywordname-update-11 "${testcvs} -q up -A" "[UP] file1" \
-"P file1
-${PROG} update: checksum failure after patch to ./file1; will refetch
-${PROG} client: refetching unpatchable files
-${PROG} update: warning: file1 was lost
-U file1"
+ dotest keywordname-update-11 "$testcvs -q up -A" \
+'U file1
+U file2'
dotest keywordname-update-12 "cat file1" \
-'\$'"Name: "'\$'"
-new data"
- dotest keywordname-update-13 "cat file2" '\$'"Name: "'\$'
+'\$''Name: \$
+new data'
+ dotest keywordname-update-13 "cat file2" '\$''Name: \$'
cd ../..
@@ -23003,7 +23581,9 @@ ${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1
new revision: 1\.2; previous revision: 1\.1
done"
- dotest keyword2-9 "${testcvs} -q update -r branch" '[UP] file1'
+ dotest keyword2-9 "$testcvs -q update -r branch" \
+'U binfile\.dat
+[UP] file1'
echo "what else do we have?" >>file1
dotest keyword2-10 "${testcvs} -q ci -m change" \
@@ -23013,9 +23593,10 @@ new revision: 1\.1\.2\.1; previous revision: 1\.1
done"
# Okay, first a conflict in file1 - should be okay with binfile.dat
- dotest keyword2-11 "${testcvs} -q update -A -j branch" \
-"U file1
-RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v
+ dotest keyword2-11 "$testcvs -q update -A -j branch" \
+"U binfile\.dat
+U file1
+RCS file: $CVSROOT_DIRNAME/first-dir/file1,v
retrieving revision 1\.1
retrieving revision 1\.1\.2\.1
Merging differences between 1\.1 and 1\.1\.2\.1 into file1
@@ -23064,7 +23645,9 @@ done"
dotest keyword2-17 "${testcvs} -q tag -b branch2" \
"T binfile\.dat
T file1"
- dotest keyword2-18 "${testcvs} -q update -r branch2" ''
+ dotest keyword2-18 "$testcvs -q update -r branch2" \
+'U binfile\.dat
+[UP] file1'
${AWK} 'BEGIN { printf "%c%c%c@%c%c", 2, 10, 137, 13, 10 }' \
</dev/null | ${TR} '@' '\000' >>binfile.dat
@@ -23131,7 +23714,9 @@ new revision: 1\.3; previous revision: 1\.2
done"
dotest head-6 "${testcvs} -q tag -b br1" "T file1
T file2"
- dotest head-7 "${testcvs} -q update -r br1" ""
+ dotest head-7 "$testcvs -q update -r br1" \
+'[UP] file1
+[UP] file2'
echo 'modify on branch' >>file1
dotest head-8 "${testcvs} -q ci -m modify" \
"Checking in file1;
@@ -23147,7 +23732,9 @@ ${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1
new revision: 1\.3\.2\.2; previous revision: 1\.3\.2\.1
done"
# With no sticky tags, HEAD is the head of the trunk.
- dotest head-trunk-setup "${testcvs} -q update -A" "[UP] file1"
+ dotest head-trunk-setup "$testcvs -q update -A" \
+'[UP] file1
+[UP] file2'
dotest head-trunk-update "${testcvs} -q update -r HEAD -p file1" \
"imported contents
add a line on trunk
@@ -23173,7 +23760,9 @@ ${PLUS} modify on branch
${PLUS} modify on branch after brtag"
# With a branch sticky tag, HEAD is the head of the trunk.
- dotest head-br1-setup "${testcvs} -q update -r br1" "[UP] file1"
+ dotest head-br1-setup "$testcvs -q update -r br1" \
+'[UP] file1
+[UP] file2'
dotest head-br1-update "${testcvs} -q update -r HEAD -p file1" \
"imported contents
add a line on trunk
@@ -23184,7 +23773,9 @@ add a line on trunk after trunktag"
# With a nonbranch sticky tag on a branch,
# HEAD is the head of the trunk
- dotest head-brtag-setup "${testcvs} -q update -r brtag" "[UP] file1"
+ dotest head-brtag-setup "$testcvs -q update -r brtag" \
+'[UP] file1
+[UP] file2'
dotest head-brtag-update "${testcvs} -q update -r HEAD -p file1" \
"imported contents
add a line on trunk
@@ -23197,8 +23788,9 @@ add a line on trunk after trunktag"
# With a nonbranch sticky tag on the trunk, HEAD is the head
# of the trunk, I think.
- dotest head-trunktag-setup "${testcvs} -q update -r trunktag" \
-"[UP] file1"
+ dotest head-trunktag-setup "$testcvs -q update -r trunktag" \
+'[UP] file1
+[UP] file2'
dotest head-trunktag-check "cat file1" "imported contents
add a line on trunk"
dotest head-trunktag-update "${testcvs} -q update -r HEAD -p file1" \
@@ -23755,7 +24347,9 @@ T file2"
dotest multibranch2-6 "${testcvs} -q tag -b B" "T file1
T file2"
- dotest multibranch2-7 "${testcvs} -q update -r B" ''
+ dotest multibranch2-7 "$testcvs -q update -r B" \
+'[UP] file1
+[UP] file2'
echo branch-B >file1
echo branch-B >file2
dotest multibranch2-8 "${testcvs} -q ci -m modify-on-B" \
@@ -23998,7 +24592,9 @@ initial revision: 1\.1
done"
dotest admin-7 "${testcvs} -q tag -b br" "T file1
T file2"
- dotest admin-8 "${testcvs} -q update -r br" ""
+ dotest admin-8 "$testcvs -q update -r br" \
+'U file1
+U file2'
echo 'add a line on the branch' >> file1
echo 'add a file on the branch' >> file3
dotest admin-9a "${testcvs} -q add file3" \
@@ -24014,9 +24610,10 @@ Checking in file3;
${CVSROOT_DIRNAME}/first-dir/Attic/file3,v <-- file3
new revision: 1\.1\.2\.1; previous revision: 1\.1
done"
- dotest admin-10 "${testcvs} -q update -A" \
+ dotest admin-10 "$testcvs -q update -A" \
"U file1
-${PROG} update: file3 is no longer in the repository"
+U file2
+$PROG update: file3 is no longer in the repository"
# Check that we can administer files in the repository that
# aren't in the working directory.
@@ -24289,7 +24886,7 @@ ${PROG} \[admin aborted\]: cannot continue"
# In the remote case, we are cd'd off into the temp directory
# and so these tests give "No such file or directory" errors.
if $remote; then :; else
- dotest admin-19a-admin "${testcvs} -q admin -A../../cvsroot/first-dir/file2,v file1" \
+ dotest admin-19a-admin "${testcvs} -q admin -A../../${CVSROOTDIR}/first-dir/file2,v file1" \
"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v
done"
dotest admin-19a-log "${testcvs} -q log -h -N file1" "
@@ -25118,7 +25715,7 @@ done"
"mv a-lock,v ${CVSROOT_DIRNAME}/first-dir/a-lock,v" ""
chmod 444 ${CVSROOT_DIRNAME}/first-dir/a-lock,v
dotest reserved-17 "${testcvs} -q tag -b br a-lock" "T a-lock"
- dotest reserved-18 "${testcvs} -q update -r br a-lock" ""
+ dotest reserved-18 "$testcvs -q update -r br a-lock" '[UP] a-lock'
echo edit it >>a-lock
dotest reserved-19 "${testcvs} -q ci -m modify a-lock" \
"Checking in a-lock;
@@ -26711,9 +27308,9 @@ C first-dir/FiLe"
testcvs1="${testcvs} -d ${CVSROOT1}"
testcvs2="${testcvs} -d ${CVSROOT2}"
- dotest multiroot-setup-1 "mkdir ${CVSROOT1_DIRNAME} ${CVSROOT2_DIRNAME}" ""
- dotest multiroot-setup-2 "${testcvs1} init" ""
- dotest multiroot-setup-3 "${testcvs2} init" ""
+ dotest multiroot-setup-1 "mkdir $CVSROOT1_DIRNAME $CVSROOT2_DIRNAME"
+ dotest multiroot-setup-2 "$testcvs -d$CVSROOT1_DIRNAME init"
+ dotest multiroot-setup-3 "$testcvs -d$CVSROOT2_DIRNAME init"
#
# create some directories in root1
@@ -27842,8 +28439,8 @@ anyone
CVSROOT1=`newroot $CVSROOT1_DIRNAME`
CVSROOT2=`newroot $CVSROOT2_DIRNAME`
- dotest multiroot2-1 "${testcvs} -d ${CVSROOT1} init" ""
- dotest multiroot2-2 "${testcvs} -d ${CVSROOT2} init" ""
+ dotest multiroot2-1 "$testcvs -d$CVSROOT1_DIRNAME init"
+ dotest multiroot2-2 "$testcvs -d$CVSROOT2_DIRNAME init"
mkdir imp-dir; cd imp-dir
echo file1 >file1
@@ -27985,12 +28582,12 @@ ${PLUS}change him too"
CVSROOT2=`newroot ${TESTDIR}/root2`
mkdir 1; cd 1
- dotest multiroot3-1 "${testcvs} -d ${CVSROOT1} init" ""
+ dotest multiroot3-1 "$testcvs -d$TESTDIR/root1 init"
dotest multiroot3-2 "${testcvs} -d ${CVSROOT1} -q co -l ." ""
mkdir dir1
dotest multiroot3-3 "${testcvs} add dir1" \
"Directory ${TESTDIR}/root1/dir1 added to the repository"
- dotest multiroot3-4 "${testcvs} -d ${CVSROOT2} init" ""
+ dotest multiroot3-4 "$testcvs -d$TESTDIR/root2 init"
rm -r CVS
dotest multiroot3-5 "${testcvs} -d ${CVSROOT2} -q co -l ." ""
mkdir dir2
@@ -28110,7 +28707,7 @@ $PROG \[checkout aborted\]: end of file from server (consult above messages if a
CVSROOT2=`newroot ${TESTDIR}/root2`
mkdir 1; cd 1
- dotest multiroot4-1 "${testcvs} -d ${CVSROOT1} init" ""
+ dotest multiroot4-1 "$testcvs -d$TESTDIR/root1 init"
dotest multiroot4-2 "${testcvs} -d ${CVSROOT1} -q co -l ." ""
mkdir dircom
dotest multiroot4-3 "${testcvs} add dircom" \
@@ -28129,7 +28726,7 @@ initial revision: 1\.1
done"
cd ../..
mkdir 2; cd 2
- dotest multiroot4-6 "${testcvs} -d ${CVSROOT2} init" ""
+ dotest multiroot4-6 "$testcvs -d$TESTDIR/root2 init"
dotest multiroot4-7 "${testcvs} -d ${CVSROOT2} -q co -l ." ""
mkdir dircom
dotest multiroot4-8 "${testcvs} add dircom" \
@@ -28216,7 +28813,7 @@ done"
CVSROOT1=`newroot ${TESTDIR}/root1`
CVSROOT_MOVED=`newroot ${TESTDIR}/root-moved`
- dotest reposmv-setup-1 "${testcvs} -d ${CVSROOT1} init" ""
+ dotest reposmv-setup-1 "$testcvs -d$TESTDIR/root1 init"
mkdir imp-dir; cd imp-dir
echo file1 >file1
dotest reposmv-setup-2 \
@@ -28340,6 +28937,16 @@ Ay::'d
END AUTH REQUEST
EOF
+ dotest_fail pserver-3a "${testcvs} --allow-root=${CVSROOT_DIRNAME} pserver" \
+"error 0 ${CVSROOT_DIRNAME}XXX: no such repository
+I HATE YOU" <<EOF
+BEGIN AUTH REQUEST
+${CVSROOT_DIRNAME}XXX
+testme
+Ay::'d
+END AUTH REQUEST
+EOF
+
# Confirm that not sending a newline during auth cannot constitute
# a denial-of-service attack. This assumes that PATH_MAX is less
# than 65536 bytes. If PATH_MAX is larger than 65535 bytes, this
@@ -28404,31 +29011,18 @@ Root ${TESTDIR}/1
noop
EOF
- dotest pserver-5a "${testcvs} --allow-root=${CVSROOT_DIRNAME} pserver" \
-"${DOTSTAR} LOVE YOU
-E Protocol error: init says \"${TESTDIR}/2\" but pserver says \"${CVSROOT_DIRNAME}\"
+ dotest pserver-5a "$testcvs --allow-root=$CVSROOT_DIRNAME pserver" \
+"$DOTSTAR LOVE YOU
+E init may not be run remotely
error " <<EOF
BEGIN AUTH REQUEST
-${CVSROOT_DIRNAME}
-testme
-Ay::'d
-END AUTH REQUEST
-init ${TESTDIR}/2
-EOF
- dotest_fail pserver-5b "test -d ${TESTDIR}/2" ''
-
- dotest pserver-5c "${testcvs} --allow-root=${CVSROOT_DIRNAME} pserver" \
-"${DOTSTAR} LOVE YOU
-E init xxx must be an absolute pathname
-error " <<EOF
-BEGIN AUTH REQUEST
-${CVSROOT_DIRNAME}
+$CVSROOT_DIRNAME
testme
Ay::'d
END AUTH REQUEST
-init xxx
+init $TESTDIR/2
EOF
- dotest_fail pserver-5d "test -d xxx" ''
+ dotest_fail pserver-5b "test -d $TESTDIR/2"
dotest_fail pserver-6 "${testcvs} --allow-root=${CVSROOT_DIRNAME} pserver" \
"I HATE YOU" <<EOF
@@ -28530,18 +29124,6 @@ Root ${CVSROOT_DIRNAME}
version
EOF
- dotest pserver-15 "${testcvs} --allow-root=${CVSROOT_DIRNAME} pserver" \
-"${DOTSTAR} LOVE YOU
-E ${PROG} \\[server aborted\\]: .init. requires write access to the repository
-error " <<EOF
-BEGIN AUTH REQUEST
-${CVSROOT_DIRNAME}
-anonymous
-Ay::'d
-END AUTH REQUEST
-init ${CVSROOT_DIRNAME}
-EOF
-
dotest pserver-16 "${testcvs} --allow-root=${CVSROOT_DIRNAME} pserver" \
"${DOTSTAR} LOVE YOU
M Concurrent Versions System (CVS) .*
@@ -28555,17 +29137,6 @@ Root ${CVSROOT_DIRNAME}
version
EOF
- dotest pserver-17 "${testcvs} --allow-root=${CVSROOT_DIRNAME} pserver" \
-"${DOTSTAR} LOVE YOU
-ok" <<EOF
-BEGIN AUTH REQUEST
-${CVSROOT_DIRNAME}
-testme
-Ay::'d
-END AUTH REQUEST
-init ${CVSROOT_DIRNAME}
-EOF
-
dotest pserver-18 "${testcvs} --allow-root=${CVSROOT_DIRNAME} pserver" \
"${DOTSTAR} LOVE YOU
M Concurrent Versions System (CVS) .*
@@ -28579,17 +29150,6 @@ Root ${CVSROOT_DIRNAME}
version
EOF
- dotest pserver-19 "${testcvs} --allow-root=${CVSROOT_DIRNAME} pserver" \
-"${DOTSTAR} LOVE YOU
-ok" <<EOF
-BEGIN AUTH REQUEST
-${CVSROOT_DIRNAME}
-${username}
-Anything
-END AUTH REQUEST
-init ${CVSROOT_DIRNAME}
-EOF
-
# Check that writers can write, everyone else can only read
# even if not listed in readers
@@ -28610,18 +29170,6 @@ Root ${CVSROOT_DIRNAME}
version
EOF
- dotest pserver-21 "${testcvs} --allow-root=${CVSROOT_DIRNAME} pserver" \
-"${DOTSTAR} LOVE YOU
-E ${PROG} \\[server aborted\\]: .init. requires write access to the repository
-error " <<EOF
-BEGIN AUTH REQUEST
-${CVSROOT_DIRNAME}
-anonymous
-Ay::'d
-END AUTH REQUEST
-init ${CVSROOT_DIRNAME}
-EOF
-
dotest pserver-22 "${testcvs} --allow-root=${CVSROOT_DIRNAME} pserver" \
"${DOTSTAR} LOVE YOU
M Concurrent Versions System (CVS) .*
@@ -28635,17 +29183,6 @@ Root ${CVSROOT_DIRNAME}
version
EOF
- dotest pserver-23 "${testcvs} --allow-root=${CVSROOT_DIRNAME} pserver" \
-"${DOTSTAR} LOVE YOU
-ok" <<EOF
-BEGIN AUTH REQUEST
-${CVSROOT_DIRNAME}
-testme
-Ay::'d
-END AUTH REQUEST
-init ${CVSROOT_DIRNAME}
-EOF
-
dotest pserver-24 "${testcvs} --allow-root=${CVSROOT_DIRNAME} pserver" \
"${DOTSTAR} LOVE YOU
M Concurrent Versions System (CVS) .*
@@ -28659,18 +29196,6 @@ Root ${CVSROOT_DIRNAME}
version
EOF
- dotest pserver-25 "${testcvs} --allow-root=${CVSROOT_DIRNAME} pserver" \
-"${DOTSTAR} LOVE YOU
-E ${PROG} \\[server aborted\\]: .init. requires write access to the repository
-error " <<EOF
-BEGIN AUTH REQUEST
-${CVSROOT_DIRNAME}
-${username}
-Anything
-END AUTH REQUEST
-init ${CVSROOT_DIRNAME}
-EOF
-
# Should work the same without readers
rm ${CVSROOT_DIRNAME}/CVSROOT/readers
@@ -28688,18 +29213,6 @@ Root ${CVSROOT_DIRNAME}
version
EOF
- dotest pserver-27 "${testcvs} --allow-root=${CVSROOT_DIRNAME} pserver" \
-"${DOTSTAR} LOVE YOU
-E ${PROG} \\[server aborted\\]: .init. requires write access to the repository
-error " <<EOF
-BEGIN AUTH REQUEST
-${CVSROOT_DIRNAME}
-anonymous
-Ay::'d
-END AUTH REQUEST
-init ${CVSROOT_DIRNAME}
-EOF
-
dotest pserver-28 "${testcvs} --allow-root=${CVSROOT_DIRNAME} pserver" \
"${DOTSTAR} LOVE YOU
M Concurrent Versions System (CVS) .*
@@ -28713,17 +29226,6 @@ Root ${CVSROOT_DIRNAME}
version
EOF
- dotest pserver-29 "${testcvs} --allow-root=${CVSROOT_DIRNAME} pserver" \
-"${DOTSTAR} LOVE YOU
-ok" <<EOF
-BEGIN AUTH REQUEST
-${CVSROOT_DIRNAME}
-testme
-Ay::'d
-END AUTH REQUEST
-init ${CVSROOT_DIRNAME}
-EOF
-
dotest pserver-30 "${testcvs} --allow-root=${CVSROOT_DIRNAME} pserver" \
"${DOTSTAR} LOVE YOU
M Concurrent Versions System (CVS) .*
@@ -28737,18 +29239,6 @@ Root ${CVSROOT_DIRNAME}
version
EOF
- dotest pserver-31 "${testcvs} --allow-root=${CVSROOT_DIRNAME} pserver" \
-"${DOTSTAR} LOVE YOU
-E ${PROG} \\[server aborted\\]: .init. requires write access to the repository
-error " <<EOF
-BEGIN AUTH REQUEST
-${CVSROOT_DIRNAME}
-${username}
-Anything
-END AUTH REQUEST
-init ${CVSROOT_DIRNAME}
-EOF
-
# pserver used to try and print from the NULL pointer
# in this error message in this case
dotest_fail pserver-bufinit "${testcvs} pserver" \
@@ -28781,12 +29271,16 @@ EOF
# Could also test for relative pathnames here (so that crerepos-6a
# and crerepos-6b can use :fork:).
- dotest server-2 "${testcvs} server" "ok" <<EOF
+ dotest server-2 "$testcvs server" \
+"E init may not be run remotely
+error " <<EOF
Set OTHER=variable
Set MYENV=env-value
init ${TESTDIR}/crerepos
EOF
- dotest server-3 "test -d ${TESTDIR}/crerepos/CVSROOT" ""
+ dotest_fail server-3 "test -d $TESTDIR/crerepos/CVSROOT"
+
+ dotest server-3a "$testcvs -d$TESTDIR/crerepos init"
# Now some tests of gzip-file-contents (used by jCVS).
${AWK} 'BEGIN { \
@@ -29000,7 +29494,7 @@ ${CVSROOT_DIRNAME}dir1
noop
EOF
- dotest 2-3 "${testcvs} server" \
+ dotest server2-3 "${testcvs} server" \
"E protocol error: directory '${TESTDIR}' not within root '${CVSROOT_DIRNAME}'
error " <<EOF
Root ${CVSROOT_DIRNAME}
@@ -29022,9 +29516,81 @@ ${CVSROOT_DIRNAME}
Unchanged foo/bar
noop
EOF
+ dotest server2-5 \
+"$testcvs --allow-root=$CVSROOT_DIRNAME.bad server" \
+"E Bad root $CVSROOT_DIRNAME
+error " <<EOF
+Root $CVSROOT_DIRNAME
+noop
+EOF
+ dotest server2-6 \
+"$testcvs --allow-root=$CVSROOT_DIRNAME server" \
+"ok" <<EOF
+Root $CVSROOT_DIRNAME
+noop
+EOF
fi
;;
+
+
+ server3)
+ # Test that various checks on the Root request generate the correct
+ # error messages.
+ if $remote; then
+ # As a control, a valid request.
+ dotest server3-1 "$testcvs server" 'ok' <<EOF
+Root $CVSROOT_DIRNAME
+Directory .
+$CVSROOT_DIRNAME
+Unchanged foo
+noop
+EOF
+
+ dotest server3-2 "$testcvs server" \
+"E Root somewhere/over/the/rainbow must be an absolute pathname
+error " <<EOF
+Root somewhere/over/the/rainbow
+noop
+EOF
+
+ dotest server3-3 "$testcvs server" \
+"E Protocol error: Duplicate Root request, for $CVSROOT_DIRNAME
+error " <<EOF
+Root $CVSROOT_DIRNAME
+Root $CVSROOT_DIRNAME
+noop
+EOF
+
+ dotest server3-4 "$testcvs server" \
+"E Protocol error: Duplicate Root request, for $CVSROOT_DIRNAME
+error " <<EOF
+Root $CVSROOT_DIRNAME
+Root $CVSROOT_DIRNAME
+Directory .
+$CVSROOT_DIRNAME
+Unchanged foo
+noop
+EOF
+
+ # These cascading errors seem odd, but the client should have hung
+ # up after the first.
+ dotest server3-5 "$testcvs server" \
+"E Root somewhere/over/the/rainbow must be an absolute pathname
+error
+E Protocol error: Root request missing
+error " <<EOF
+Root somewhere/over/the/rainbow
+Directory .
+somewhere/over/the/rainbow
+Unchanged foo
+noop
+EOF
+ fi
+ ;;
+
+
+
client)
# Some tests of the client (independent of the server).
if $remote; then
@@ -29351,6 +29917,68 @@ EOF
fi # skip the whole thing for local
;;
+
+
+ client2)
+ # Test how the client handles error messages from the server.
+ if $remote; then
+ cat >$TESTDIR/serveme <<EOF
+#!$TESTSHELL
+# This is just as cheesy as the "client" tests made it out to be.
+echo "Valid-requests Root Valid-responses valid-requests Directory Entry Modified Unchanged Argument Argumentx ci co update"
+echo "E Root somewhere/over/the/rainbow must be an absolute pathname"
+echo "error "
+echo "E Protocol error: Root request missing"
+echo "error "
+cat >/dev/null
+EOF
+ # Cygwin. Pthffffffffft!
+ if test -n "$remotehost"; then
+ $CVS_RSH $remotehost "chmod +x $TESTDIR/serveme"
+ else
+ chmod +x $TESTDIR/serveme
+ fi
+ save_CVS_SERVER=$CVS_SERVER
+ CVS_SERVER=$TESTDIR/serveme; export CVS_SERVER
+ mkdir client2; cd client2
+ dotest_fail client2-1 "$testcvs co first-dir" \
+"Root somewhere/over/the/rainbow must be an absolute pathname"
+
+ cat >$TESTDIR/serveme <<EOF
+#!$TESTSHELL
+# This is just as cheesy as the "client" tests made it out to be.
+echo "Valid-requests Root Valid-responses valid-requests Directory Entry Modified Unchanged Argument Argumentx ci co update"
+echo "E Root somewhere/over/the/rainbow must be an absolute pathname"
+echo
+echo "error "
+echo "E Protocol error: Root request missing"
+echo "error "
+cat >/dev/null
+EOF
+ # Cygwin. Pthffffffffft!
+ if test -n "$remotehost"; then
+ $CVS_RSH $remotehost "chmod +x $TESTDIR/serveme"
+ else
+ chmod +x $TESTDIR/serveme
+ fi
+ dotest_fail client2-2 "$testcvs co first-dir" \
+"Root somewhere/over/the/rainbow must be an absolute pathname
+$PROG checkout: warning: unrecognized response \`' from cvs server"
+
+ if $keep; then
+ echo Keeping $TESTDIR and exiting due to --keep
+ exit 0
+ fi
+
+ cd ..
+ rm -r client2
+ rm $TESTDIR/serveme
+ CVS_SERVER=$save_CVS_SERVER; export CVS_SERVER
+ fi # skip the whole thing for local
+ ;;
+
+
+
dottedroot)
# Check that a CVSROOT with a "." in the name will work.
CVSROOT_save=${CVSROOT}
@@ -29358,7 +29986,7 @@ EOF
CVSROOT_DIRNAME=${TESTDIR}/cvs.root
CVSROOT=`newroot ${CVSROOT_DIRNAME}`
- dotest dottedroot-init-1 "${testcvs} init" ""
+ dotest dottedroot-init-1 "$testcvs -d$CVSROOT_DIRNAME init"
mkdir dir1
mkdir dir1/dir2
echo version1 >dir1/dir2/file1
@@ -29377,10 +30005,15 @@ No conflicts created by this import"
${PROG} [a-z]*: Updating module1/dir2
U module1/dir2/file1"
- if $keep; then
- echo Keeping ${TESTDIR} and exiting due to --keep
- exit 0
- fi
+ # This also triggered the assertion failure above prior to 1.11.23.
+ dotest dottedroot-3 \
+"$testcvs -q co -prINITIAL module1/./dir2/file1" \
+'version1'
+
+ if $keep; then
+ echo Keeping $TESTDIR and exiting due to --keep
+ exit 0
+ fi
rm -rf ${CVSROOT_DIRNAME}
rm -r dir1 module1
@@ -29447,6 +30080,37 @@ ${PROG} \[commit aborted\]: correct above errors first!"
rm -rf ${CVSROOT_DIRNAME}/$module
;;
+ add-restricted)
+ # Verify that `sdir/CVS' may not be explicitly added.
+ mkdir add-restricted; cd add-restricted
+
+ mkdir import; cd import
+ : > junk
+ dotest add-restricted-init-1 \
+"$testcvs -Q import -m. add-restricted X Y"
+ cd ..
+
+ dotest add-restricted-init-2 "$testcvs -Q co add-restricted"
+ cd add-restricted
+
+ # errmsg2-3 tests the specific message here.
+ dotest_fail add-restricted-1 "$testcvs -Q add CVS"
+
+ mkdir sdir
+ dotest add-restricted-2 "$testcvs -Q add sdir"
+ dotest_fail add-restricted-3 "$testcvs add sdir/CVS" \
+"$PROG add: cannot add special file \`sdir/CVS'; skipping"
+
+ if $keep; then
+ echo Keeping $TESTDIR and exiting due to --keep
+ exit 0
+ fi
+ cd ../..
+ rm -rf add-restricted $CVSROOT_DIRNAME/add-restricted
+ ;;
+
+
+
commit-d)
# Check that top-level commits work when CVS/Root
# is overridden by cvs -d.
diff --git a/contrib/cvs/src/server.c b/contrib/cvs/src/server.c
index 29aab00..374c7d3 100644
--- a/contrib/cvs/src/server.c
+++ b/contrib/cvs/src/server.c
@@ -759,6 +759,19 @@ serve_root (arg)
return;
}
+ /* We need to check :ext: server here, :pserver: checks happen below. */
+ if (root_allow_used() && !root_allow_ok (arg)
+# ifdef AUTH_SERVER_SUPPORT
+ && Pserver_Repos == NULL
+# endif
+ )
+ {
+ if (alloc_pending (80 + strlen (arg)))
+ sprintf (pending_error_text,
+ "E Bad root %s", arg);
+ return;
+ }
+
#ifdef AUTH_SERVER_SUPPORT
if (Pserver_Repos != NULL)
{
@@ -2754,7 +2767,7 @@ do_cvs_command (cmd_name, command)
int dev_null_fd = -1;
- int errs;
+ int errs = 0;
command_pid = -1;
stdout_pipe[0] = -1;
@@ -2953,9 +2966,8 @@ error \n");
#ifdef SERVER_FLOWCONTROL
{
char junk;
- ssize_t status;
set_block_fd (flowcontrol_pipe[0]);
- while ((status = read (flowcontrol_pipe[0], &junk, 1)) > 0);
+ while (read (flowcontrol_pipe[0], &junk, 1) > 0);
}
/* FIXME: No point in printing an error message with error(),
* as STDERR is already closed, but perhaps this could be syslogged?
@@ -3987,38 +3999,11 @@ static void
serve_init (arg)
char *arg;
{
- cvsroot_t *saved_parsed_root;
-
- if (!isabsolute (arg))
- {
- if (alloc_pending (80 + strlen (arg)))
- sprintf (pending_error_text,
- "E init %s must be an absolute pathname", arg);
- }
-#ifdef AUTH_SERVER_SUPPORT
- else if (Pserver_Repos != NULL)
- {
- if (strcmp (Pserver_Repos, arg) != 0)
- {
- if (alloc_pending (80 + strlen (Pserver_Repos) + strlen (arg)))
- /* The explicitness is to aid people who are writing clients.
- I don't see how this information could help an
- attacker. */
- sprintf (pending_error_text, "\
-E Protocol error: init says \"%s\" but pserver says \"%s\"",
- arg, Pserver_Repos);
- }
- }
-#endif
+ if (alloc_pending (80 + strlen (arg)))
+ sprintf (pending_error_text, "E init may not be run remotely");
if (print_pending_error ())
return;
-
- saved_parsed_root = current_parsed_root;
- current_parsed_root = local_cvsroot (arg);
- do_cvs_command ("init", init);
- free_cvsroot_t (current_parsed_root);
- current_parsed_root = saved_parsed_root;
}
static void serve_annotate PROTO ((char *));
diff --git a/contrib/cvs/src/update.c b/contrib/cvs/src/update.c
index 6f1c937..117561a 100644
--- a/contrib/cvs/src/update.c
+++ b/contrib/cvs/src/update.c
@@ -1435,8 +1435,10 @@ VERS: ", 0);
/* fix up the vers structure, in case it is used by join */
if (join_rev1)
{
- /* FIXME: Throwing away the original revision info is almost
- certainly wrong -- what if join_rev1 is "BASE"? */
+ /* FIXME: It seems like we should be preserving ts_user
+ * & ts_rcs here, but setting them causes problems in
+ * join_file().
+ */
if (vers_ts->vn_user != NULL)
free (vers_ts->vn_user);
if (vers_ts->vn_rcs != NULL)
@@ -1645,21 +1647,11 @@ patch_file (finfo, vers_ts, docheckout, file_info, checksum)
data.final_nl = 0;
data.compute_checksum = 0;
- /* FIXME - Passing vers_ts->tag here is wrong in the least number
- * of cases. Since we don't know whether vn_user was checked out
- * using a tag, we pass vers_ts->tag, which, assuming the user did
- * not specify a new TAG to -r, will be the branch we are on.
- *
- * The only thing it is used for is to substitute in for the Name
- * RCS keyword, so in the error case, the patch fails to apply on
- * the client end and we end up resending the whole file.
- *
- * At least, if we are keeping track of the tag vn_user came from,
- * I don't know where yet. -DRP
+ /* Duplicating the client working file, so use the original sticky options.
*/
retcode = RCS_checkout (vers_ts->srcfile, (char *) NULL,
- vers_ts->vn_user, vers_ts->tag,
- vers_ts->options, RUN_TTY,
+ vers_ts->vn_user, vers_ts->entdata->tag,
+ vers_ts->entdata->options, RUN_TTY,
patch_file_write, (void *) &data);
if (fclose (e) < 0)
@@ -2217,6 +2209,7 @@ join_file (finfo, vers)
if (rev2 == NULL || RCS_isdead (vers->srcfile, rev2))
{
char *mrev;
+ short conflict = 0;
if (rev2 != NULL)
free (rev2);
@@ -2267,8 +2260,7 @@ join_file (finfo, vers)
|| vers->vn_user[0] == '-'
|| RCS_isdead (vers->srcfile, vers->vn_user))
{
- if (rev1 != NULL)
- free (rev1);
+ free (rev1);
return;
}
@@ -2277,56 +2269,107 @@ join_file (finfo, vers)
resolve. No_Difference will already have been called in
this case, so comparing the timestamps is sufficient to
determine whether the file is locally modified. */
- if (strcmp (vers->vn_user, "0") == 0
- || (vers->ts_user != NULL
- && strcmp (vers->ts_user, vers->ts_rcs) != 0))
+ if (/* may have changed on destination branch */
+ /* file added locally */
+ !strcmp (vers->vn_user, "0")
+ || /* destination branch modified in repository */
+ strcmp (rev1, vers->vn_user)
+ || /* locally modified */
+ vers->ts_user && strcmp (vers->ts_user, vers->ts_rcs))
{
- if (jdate2 != NULL)
- error (0, 0,
- "file %s is locally modified, but has been removed in revision %s as of %s",
- finfo->fullname, jrev2, jdate2);
- else
- error (0, 0,
- "file %s is locally modified, but has been removed in revision %s",
- finfo->fullname, jrev2);
-
- /* FIXME: Should we arrange to return a non-zero exit
- status? */
-
- if (rev1 != NULL)
- free (rev1);
-
- return;
+ /* The removal should happen if either the file has never changed
+ * on the destination or the file has changed to be identical to
+ * the first join revision.
+ *
+ * ------R-----------D
+ * |
+ * \----J1---J2-----S
+ *
+ * So:
+ *
+ * J2 is dead.
+ * D is destination.
+ * R is source branch root/GCA.
+ * if J1 == D removal should happen
+ * if D == R removal should happen
+ * otherwise, fail.
+ *
+ * (In the source, J2 = REV2, D = user file (potentially VN_USER),
+ * R = GCA computed below)
+ */
+ char *gca_rev1 = gca (rev1, vers->vn_user);
+#ifdef SERVER_SUPPORT
+ if (server_active && !isreadable (finfo->file))
+ {
+ int retcode;
+ /* The file is up to date. Need to check out the current
+ * contents.
+ */
+ /* FIXME - see the FIXME comment above the call to RCS_checkout
+ * in the patch_file function.
+ */
+ retcode = RCS_checkout (vers->srcfile, finfo->file,
+ vers->vn_user, vers->tag,
+ NULL, RUN_TTY, NULL, NULL);
+ if (retcode)
+ error (1, 0,
+ "failed to check out %s file", finfo->fullname);
+ }
+#endif
+ if (/* genuinely changed on destination branch */
+ RCS_cmp_file (vers->srcfile, gca_rev1, NULL,
+ NULL, vers->options, finfo->file)
+ && /* genuinely different from REV1 */
+ RCS_cmp_file (vers->srcfile, rev1, NULL,
+ NULL, vers->options, finfo->file))
+ conflict = 1;
}
- /* If only one join tag was specified, and the user file has
- been changed since the greatest common ancestor (rev1),
- then there is a conflict we can not resolve. See above for
- the rationale. */
- if (join_rev2 == NULL
- && strcmp (rev1, vers->vn_user) != 0)
+ free (rev1);
+
+ if (conflict)
{
- if (jdate2 != NULL)
+ char *cp;
+
+ if (jdate2)
error (0, 0,
- "file %s has been modified, but has been removed in revision %s as of %s",
+ "file %s has been removed in revision %s as of %s, but the destination is incompatibly modified",
finfo->fullname, jrev2, jdate2);
else
error (0, 0,
- "file %s has been modified, but has been removed in revision %s",
+ "file %s has been removed in revision %s, but the destination is incompatibly modified",
finfo->fullname, jrev2);
- /* FIXME: Should we arrange to return a non-zero exit
- status? */
+ /* Register the conflict with the client. */
- if (rev1 != NULL)
- free (rev1);
+ /* FIXME: vers->ts_user should always be set here but sometimes
+ * isn't, namely when checkout_file() has just created the file,
+ * but simply setting it in checkout_file() appears to cause other
+ * problems.
+ */
+ if (isfile (finfo->file))
+ cp = time_stamp (finfo->file);
+ else
+ cp = xstrdup (vers->ts_user);
+
+ Register (finfo->entries, finfo->file, vers->vn_user,
+ "Result of merge", vers->options, vers->tag, vers->date,
+ cp);
+ write_letter (finfo, 'C');
+ free (cp);
+
+#ifdef SERVER_SUPPORT
+ /* Abuse server_checked_in() to send the updated entry without
+ * needing to update the file.
+ */
+ if (server_active)
+ server_checked_in (finfo->file, finfo->update_dir,
+ finfo->repository);
+#endif
return;
}
- if (rev1 != NULL)
- free (rev1);
-
/* The user file exists and has not been modified. Mark it
for removal. FIXME: If we are doing a checkout, this has
the effect of first checking out the file, and then
diff --git a/contrib/cvs/src/vers_ts.c b/contrib/cvs/src/vers_ts.c
index 2115dd5..1bf880a 100644
--- a/contrib/cvs/src/vers_ts.c
+++ b/contrib/cvs/src/vers_ts.c
@@ -361,6 +361,9 @@ time_stamp (file)
{
mtime = sb.st_mtime;
}
+ else if (! existence_error (errno))
+ error (0, errno, "cannot lstat %s", file);
+
/* If it's a symlink, return whichever is the newest mtime of
the link and its target, for safety.
*/
@@ -369,6 +372,9 @@ time_stamp (file)
if (mtime < sb.st_mtime)
mtime = sb.st_mtime;
}
+ else if (! existence_error (errno))
+ error (0, errno, "cannot stat %s", file);
+
if (mtime)
{
struct tm *tm_p;
OpenPOWER on IntegriCloud