summaryrefslogtreecommitdiffstats
path: root/contrib/cvs/src
diff options
context:
space:
mode:
authorpeter <peter@FreeBSD.org>2002-09-02 05:50:28 +0000
committerpeter <peter@FreeBSD.org>2002-09-02 05:50:28 +0000
commitcf46dfb750863d760d19b9858b0a336b158275da (patch)
tree8440832ece5130fad994f5f3489b01676ab1ca4a /contrib/cvs/src
parent92c0df1bed708821e09e92931a5309cd3abd82fb (diff)
downloadFreeBSD-src-cf46dfb750863d760d19b9858b0a336b158275da.zip
FreeBSD-src-cf46dfb750863d760d19b9858b0a336b158275da.tar.gz
Import cvs-1.11.2 onto vendor branch
Obtained from: http://www.cvshome.org/
Diffstat (limited to 'contrib/cvs/src')
-rw-r--r--contrib/cvs/src/ChangeLog804
-rw-r--r--contrib/cvs/src/Makefile.am34
-rw-r--r--contrib/cvs/src/Makefile.in295
-rw-r--r--contrib/cvs/src/admin.c10
-rw-r--r--contrib/cvs/src/annotate.c32
-rw-r--r--contrib/cvs/src/buffer.c167
-rw-r--r--contrib/cvs/src/buffer.h6
-rw-r--r--contrib/cvs/src/checkout.c128
-rw-r--r--contrib/cvs/src/client.c755
-rw-r--r--contrib/cvs/src/client.h62
-rw-r--r--contrib/cvs/src/commit.c18
-rw-r--r--contrib/cvs/src/cvs.h38
-rw-r--r--contrib/cvs/src/diff.c120
-rw-r--r--contrib/cvs/src/error.h11
-rw-r--r--contrib/cvs/src/filesubr.c3
-rw-r--r--contrib/cvs/src/find_names.c7
-rw-r--r--contrib/cvs/src/history.c11
-rw-r--r--contrib/cvs/src/import.c25
-rw-r--r--contrib/cvs/src/lock.c11
-rw-r--r--contrib/cvs/src/log.c139
-rw-r--r--contrib/cvs/src/login.c14
-rw-r--r--contrib/cvs/src/logmsg.c167
-rw-r--r--contrib/cvs/src/main.c8
-rw-r--r--contrib/cvs/src/mkmodules.c12
-rw-r--r--contrib/cvs/src/modules.c25
-rw-r--r--contrib/cvs/src/myndbm.c23
-rw-r--r--contrib/cvs/src/parseinfo.c16
-rw-r--r--contrib/cvs/src/patch.c10
-rw-r--r--contrib/cvs/src/rcs.c249
-rw-r--r--contrib/cvs/src/recurse.c3
-rw-r--r--contrib/cvs/src/remove.c8
-rw-r--r--contrib/cvs/src/root.c63
-rw-r--r--contrib/cvs/src/root.h37
-rwxr-xr-xcontrib/cvs/src/sanity.sh1963
-rw-r--r--contrib/cvs/src/server.c176
-rw-r--r--contrib/cvs/src/server.h1
-rw-r--r--contrib/cvs/src/subr.c8
-rw-r--r--contrib/cvs/src/tag.c86
-rw-r--r--contrib/cvs/src/update.c20
-rw-r--r--contrib/cvs/src/vers_ts.c17
-rw-r--r--contrib/cvs/src/version.c85
-rw-r--r--contrib/cvs/src/version.h.in15
-rw-r--r--contrib/cvs/src/wrapper.c64
-rw-r--r--contrib/cvs/src/zlib.c16
44 files changed, 4381 insertions, 1381 deletions
diff --git a/contrib/cvs/src/ChangeLog b/contrib/cvs/src/ChangeLog
index f483a7b..727332c 100644
--- a/contrib/cvs/src/ChangeLog
+++ b/contrib/cvs/src/ChangeLog
@@ -1,3 +1,807 @@
+2002-04-17 Derek Price <oberon@umich.edu>
+
+ * version.h: Regenerated for 1.11.2.
+
+2002-04-03 Derek Price <oberon@umich.edu>
+
+ * stamp-h2.in: Regenerate with recent version of Autoconf.
+
+2002-04-03 Derek Price <oberon@umich.edu>
+
+ * sanity.sh (TR): Send the stderr of one of the tool setup (tr) tests
+ to /dev/null to avoid spurious output on some operating systems
+ (notably Mac OS X).
+
+2002-03-22 Larry Jones <larry.jones@sdrc.com>
+
+ * sanity.sh (rcslib): Correct new tests to use ${testcvs} instead
+ of cvs.
+
+2002-03-21 Derek Price <oberon@umich.edu>
+
+ * vers_ts.c (time_stamp): Return the timestamp for the newer of the
+ link and the link's source when the file is a link.
+ (Patch from RedHat cvs-1.11.1p1-7 SRPM.)
+
+ * sanity.sh (rcslib): Test for same.
+
+2002-03-17 Larry Jones <larry.jones@sdrc.com>
+
+ * log.c (cvslog, log_fileproc): Add -S option to suppress head or
+ file name if no revisions selected.
+ * sanity.sh (log): New tests for above.
+
+2002-03-13 Derek Price <oberon@umich.edu>
+
+ * main.c (usg): Correct a spelling mistake in a comment.
+ (Thanks to Matt Kraai <kraai@alumni.cmu.edu>.)
+
+2002-03-09 Larry Jones <larry.jones@sdrc.com>
+
+ * import.c (import): Change the suggested merge message to use
+ rev tags instead of the branch tag with a date.
+ * sanity.sh (import, importb): Change to match.
+
+ * remove.c (remove_fileproc): Disallow removing files with sticky
+ dates for the same reason we already disallow sticky numeric tags.
+ * sanity.sh (sticky): New test for above.
+
+2002-02-27 Larry Jones <larry.jones@sdrc.com>
+
+ * diff.c (diff_fileproc): Treat dead revisions as nonexistent.
+
+2002-02-26 Larry Jones <larry.jones@sdrc.com>
+
+ * diff.c (diff): Remove -V and --paginate options: they aren't valid.
+ (diff_usage): Document all the diff options.
+
+2002-02-13 Larry Jones <larry.jones@sdrc.com>
+
+ * rcs.c (RCS_gettag): Do not interpret an empty tag as HEAD (nothing
+ else does and I don't see any documentation that says it should).
+ (translate_symtag): Break out of loop at end of symbols to prevent
+ looping forever when tag is "".
+ (Reported by Alain ENOUT <aln00@udcast.com>
+ via Eric Gillespie <epg@pretzelnet.org>.)
+
+2002-02-11 Larry Jones <larry.jones@sdrc.com>
+
+ * server.c (server_cleanup): Set buf_to_net back to blocking mode
+ and flush it (in case there are any error messages pending) before
+ shutting down buf_from_net and again right before shutting it down.
+
+2002-02-08 Larry Jones <larry.jones@sdrc.com>
+
+ * main.c (lookup_command_attribute): Throw a fatal error if the
+ command is not found.
+ * server.c (server_tag): Use the correct command name.
+
+2002-01-30 Larry Jones <larry.jones@sdrc.com>
+
+ * error.h (error_exit): Remove unintended prototype.
+
+ * server.c (serve_root): Remove check for impossible condition.
+ (serve_init): Save and restore current_parsed_root.
+
+2002-01-29 Larry Jones <larry.jones@sdrc.com>
+
+ * error.h (error_exit): Declare __noreturn__ to avoid spurious
+ warnings.
+
+ * server.c (serve_root): If the specified root doesn't match the
+ pserver root, return before changing current_parsed_root to prevent
+ subsequent commands from accessing an unchecked root directory.
+ (server_init): Check specified root against the pserver root and
+ complain if they don't match. Also, if there are pending errors,
+ print them and return before changing current_parsed_root to prevent
+ subsequent commands from accessing an unchecked root directory.
+ * sanity.sh (pserver): New tests for above.
+
+2002-01-10 Larry Jones <larry.jones@sdrc.com>
+
+ * log.c (log_version_requested): Change :: in revision spec to be
+ exclusive just on the low end (so -r tag1::tag2 gives revisions
+ after tag1 but up to and including tag2), which is much more useful
+ than the previous (exclusive at both ends) behavior.
+ (log_usage): Update to match.
+ * sanity.sh (log): Update to match.
+
+2002-01-02 Larry Jones <larry.jones@sdrc.com>
+
+ * server.c (LOG_DAEMON): Define if needed.
+ (Patch from John David Anglin <dave@hiauly1.hia.nrc.ca>.)
+
+ * server.c (pserver_authenticate_connection): Add a specific error
+ message for EOF at protocol start and syslog if available.
+ * sanity.sh (pserver-bufinit): Update to match.
+
+2001-12-10 Larry Jones <larry.jones@sdrc.com>
+
+ * log.c (log_usage): Note that -r and -d take lists, not just a
+ single specification.
+ (log_expand_revlist): Don't dereference null pointers when one end
+ of a revision range is a non-existent tag.
+
+2001-12-03 Larry Jones <larry.jones@sdrc.com>
+
+ * annotate.c (annotate, annotate_fileproc): Don't annotate binary
+ files unless new -F option given.
+ * sanity.sh (basica, ann, ann-id, rcs, keywordlog, tagdate): Update
+ to match.
+
+2001-11-30 Larry Jones <larry.jones@sdrc.com>
+
+ * admin.c (admin): Allow unrestricted usage of -q in addition to -k.
+
+2001-10-25 Larry Jones <larry.jones@sdrc.com>
+
+ * log.c (log_expand_revlist): Make erroneous or inconsistent revision
+ specs select no revisions rather than all revisions.
+
+2001-10-23 Larry Jones <larry.jones@sdrc.com>
+
+ * import.c (add_rcs_file): Don't put an expand entry into the file
+ for the default expansion mode (kv).
+ * wrapper.c (wrap_send, wrap_unparse_rcs_options): Process entries
+ with default expansion mode since they may be needed to avoid matching
+ a more general entry later.
+ (wrap_add): Set rcsOption to NULL for default (kv).
+ (wrap_add_entry): Use structure assignment to copy entries rather
+ that copying members by hand.
+ * sanity.sh (binwrap3): Revise to test wrapper entries that don't
+ specify any non-default options but just prevent matching later,
+ more general entries.
+
+2001-10-02 Larry Jones <larry.jones@sdrc.com>
+
+ * rcs.c (RCS_fully_parse): Add revision number to more error messages.
+
+2001-09-27 Larry Jones <larry.jones@sdrc.com>
+
+ * rcs.c (RCS_fully_parse, RCS_getdeltatext): Add the missing revision
+ number to the "mismatch" error message.
+
+ * sanity.sh (multiroot2-9a): Update to match changes to lock.c.
+
+2001-09-26 Larry Jones <larry.jones@sdrc.com>
+
+ * lock.c (Lock_Cleanup, Reader_Lock, write_lock): Add trace messages.
+
+2001-09-24 Derek Price <dprice@collab.net>
+
+ * find_names.c (add_entries_proc): Leave closure specified as such in the
+ function definition for clarity.
+
+ * find_names.c (Find_Names): Use 'closure' feature of walklist()
+ to eliminate the static variable.
+ (add_entries_proc): Expect closure to be the file list.
+ (Patch from Alexey Mahotkin <alexm@hsys.msk.ru>.)
+
+2001-09-19 Derek Price <dprice@collab.net>
+
+ * rcs.c (rcsbuf_valpolish_internal): Restore one of the
+ "if ( ... ) abort();" sequences since it seems to check the validity of
+ the RCS file rather than for a programming error. Also added a FIXME
+ comment to the effect that we should explain the RCS file error to the
+ user as such if it is such.
+ (Thanks to Larry Jones <scjones@sdrc.com>.)
+
+2001-09-19 Derek Price <dprice@collab.net>
+
+ * rcs.c (rcsbuf_getkey, rcsbuf_valpolish_internal): Replace some code
+ of the form "if ( ... ) abort();" with equivalent calls to assert().
+
+2001-09-17 Derek Price <dprice@collab.net>
+
+ * myndbm.c (mydbm_load_file): Fix buffer overflow error and make error
+ messages more informative.
+ * sanity.sh (modules6): New test.
+ (Original report from Taska <taska@collab.net> and others.)
+
+2001-09-14 Derek Price <dprice@collab.net>
+
+ * logmsg.c (do_verify): Dispose memory when finished with it.
+
+2001-09-07 Larry Jones <larry.jones@sdrc.com>
+
+ * mkmodules.c (notify_contents): In the example, move the %s to
+ the end since many, if not most, versions of mail insist on
+ options coming before addresses.
+
+2001-09-06 Derek Price <dprice@collab.net>
+
+ * login.c (login): Deal with NULL return value from getpass.
+
+2001-09-04 Derek Price <dprice@collab.net>
+
+ * Makefile.in: Regenerated with automake 1.5.
+ * stamp-h2.in: Ditto.
+
+2001-09-04 Derek Price <dprice@collab.net>
+
+ * main.c (main): Fix empty CVSROOT message to specify `valid' instead
+ of `legal'.
+
+2001-09-04 Derek Price <dprice@collab.net>
+
+ * server.c (pserver_authenticate_connection): Back out changes from the
+ 30th and...
+ * getline.c (getstr): init the buffer instead.
+
+2001-08-31 Derek Price <dprice@collab.net>
+
+ * Makefile.in: Backed out accidental commit from yesterday.
+
+2001-08-30 Derek Price <dprice@collab.net>
+
+ * server.c (pserver_authenticate_connection): Don't print from the
+ NULL pointer in the error message string in the case where the client
+ didn't send any data.
+ * sanity.sh (pserver): Test for this case.
+ (Report from Mark Welch <mark@collab.net>).
+
+2001-08-24 Derek Price <dprice@collab.net>
+
+ * logmsg.c (do_editor): Add comment and assertion.
+ * import.c (import): Don't call do_editor with a repository argument
+ in client mode.
+ (Report and original patch from darkness <darkness@invado.com>.)
+
+2001-08-24 Larry Jones <larry.jones@sdrc.com>
+
+ * log.c (log_expand_revlist): Arrange for nil revision specs to
+ select nothing instead of everything.
+ * sanity.sh (log): New tests for above.
+
+2001-08-24 Derek Price <dprice@collab.net>
+
+ * parseinfo.c (Parse_Info): Change the function name in the trace
+ and add the client/server string.
+
+2001-08-24 Derek Price <dprice@collab.net>
+
+ * Implement RereadLogAfterVerify CVSROOT/config option to control
+ FreeBSD read-write of log messages in the verification script.
+ * logmsg.c: RereadLogAfterVerify defaults to LOGMSG_REREAD_NEVER
+ to preserve the status quo.
+ * parseinfo.c (parse_config): Add parsing for RereadLogAfterVerify
+ option. Possible values are: no | never | yes | always | stat
+ * cvs.h: Add extern for RereadLogAfterVerify and new value macros
+ LOGMSG_REREAD_NEVER, LOGMSG_REREAD_ALWAYS, LOGMSG_REREAD_STAT for
+ its values.
+ (Patch from Mark D. Baushke <mdb@cvshome.org>.)
+
+ * Apply changes from FreeBSD cvs sources to implement a read-write
+ user-defined verification script.
+ * logmsg.c (do_verify): Update do_verify to expect a pointer
+ to the saved message. The log file passed to the verifymsg_script
+ should be re-read after the user-defined verification script has
+ been run. The user-defined verification script is allowed to
+ modify the message. This allows the script to add extra
+ information to the log message or to remove template lines that
+ are not needed.
+ * cvs.h: Update prototype for do_verify prototype to expect a
+ pointer to the saved_message.
+ * commit.c (commit, commit_fileproc, commit_direntproc): Update
+ calls to do_verify as the saved_message arg is now read-write.
+ * import.c (import): Update calls to do_verify as the
+ saved_message arg is now read-write.
+ * sanity.sh (info-v4-[12]): Rename the old info-v4 test to info-v5
+ and add a new info-v4 test case have the verification script
+ modify the log message to test the above changes.
+ (Patch from Mark D. Baushke <mdb@cvshome.org>.)
+
+ * logmsg.c: Change RereadLogAfterVerify default to always.
+ (do_verify): Reformat and make minor fixes to Mark's patch.
+ * mkmodules.c (config_constants): Add comment about
+ RereadLogAfterVerify.
+ * sanity.sh (info-rereadlog): Rename the tests from Mark's patch and
+ reformat them a bit.
+
+2001-08-23 Derek Price <dprice@collab.net>
+
+ * sanity.sh (info): Demonstrate that the verifymsg scripts can
+ sometimes, but not always, retreive information on which directory is
+ being committed to.
+
+2001-08-22 Derek Price <dprice@collab.net>
+
+ * logmsg.c: Back out the last change - the repository which is passed
+ in is actually the directory and changes with each call to do_verify.
+ If a verifymsg script is using `pwd`, this could change the operation.
+ * cvs.h: Ditto.
+ * commit.c: Ditto.
+ * import.c: Ditto.
+
+2001-08-22 Derek Price <dprice@collab.net>
+
+ * logmsg.c (do_editor): Return reused_message.
+ (do_verify): Don't verify the same log message more than once.
+ * cvs.h: Update prototypes for do_verify and do_editor.
+ * commit.c (commit_fileproc, commit_direntproc): Use the new functionality.
+ * import.c (import): Ditto.
+
+2001-08-22 Derek Price <dprice@collab.net>
+
+ * logmsg.c (do_verify): Remove an unecessary "else" clause following an
+ exit and unindent the former contents.
+
+2001-08-22 Derek Price <dprice@collab.net>
+
+ * commit.c (commit): Don't call do_verify in client mode since we know
+ do_verify will just return anyhow.
+
+2001-08-20 Derek Price <dprice@collab.net>
+
+ * Makefile.am (cvs_SOURCES): Add version.c and version.h.
+ (BUILT_SOURCES): Add version.h.
+ (Maintainer Targets): Remove version.h.
+ * version.c: Remove @VERSION@ dependant bits.
+ * version.c.in: Removed.
+ * version.h.in: New file.
+ (Original patch from Alexey Mahotkin <alexm@hsys.msk.ru>.)
+
+ * Makefile.am: Various modifications to make Automake, make dist, and
+ windows targets work like they are supposed to.
+ * version.h: New (generated) file.
+
+ * Makefile.in: Regenerated.
+
+2001-08-09 Derek Price <dprice@collab.net>
+
+ * client.c (socket_buffer_shutdown): Use recv instead of read and
+ return 0 on success.
+ (Patch from "Manfred Klug" <manklu@web.de>.)
+
+2001-08-09 Derek Price <dprice@collab.net>
+
+ * buffer.c (stdio_buffer_shutdown): Assume the buffer is not a socket
+ when NO_SOCKET_TO_FD is defined.
+ * client.c (make_bufs_from_fds): Add is_sock argument and remove fstat
+ call and reference to S_ISSOCK since these functions aren't available
+ under Windows.
+ (connect_to_forked_server, connect_to_pserver, start_tcp_server,
+ start_server, start_rsh_server): Use new argument.
+ (Patch from "Manfred Klug" <manklu@web.de>.)
+
+ * buffer.c (stdio_buffer_shutdown): Various reformattings, fix bug
+ where rsh pipes weren't being closed.
+
+2001-08-09 Derek Price <dprice@collab.net>
+
+ * sanity.sh (rmadd, rm-update-message, join-two-branch,
+ ignore-on-branch): Change a few references to `cvs' to `$PROG'.
+
+2001-08-07 Derek Price <dprice@collab.net>
+
+ * build_src.com: Add annotate.c/annotate.obj,verify, correct zlib name.
+ * patch.c: VMS time_t appears to be unsigned. Add a cast when testing
+ for (time_t)-1.
+ * subr.c: #else,#endif for no symlinks should be moved.
+ (Patch from Mike Marciniszyn <Mike.Marciniszyn@sanchez.com>.)
+
+2001-08-06 Derek Price <dprice@collab.net>
+
+ * Makefile.in: Regenerated.
+
+2001-08-01 Derek Price <dprice@collab.net>
+
+ * diff.c (diff): Send long option for side-by-side diffs to the server
+ rather than '-y', for backwards compatibility with old servers.
+ (Original patch from Peter Mathiasson <peter@mathiasson.nu>.)
+
+2001-07-19 Larry Jones <larry.jones@sdrc.com>
+
+ * mkmodules.c (cvswrappers_contents): Remove -t/-f since they're
+ disabled in wrapper.c.
+
+ * checkout.c (checkout): Don't complain about checking out into the
+ repository when piping output.
+ (Reported by der Mouse <mouse@Rodents.Montreal.QC.CA>.)
+ * sanity.sh (checkout_repository): New tests for above.
+
+2001-07-10 Larry Jones <larry.jones@sdrc.com>
+
+ * sanity.sh (importc-7): Now works correctly in local mode.
+
+ * commit.c (commit_dirleaveproc): We're still in the directory when
+ this is called, so the first argument to Name_Repository needs to
+ be NULL, not dir.
+ * sanity.sh (rmadd): New tests for above.
+
+ * commit.c (commit): Reword error messages for committing as root.
+
+2001-07-08 Larry Jones <larry.jones@sdrc.com>
+
+ * rcs.c (RCS_checkout): Correct scanf format to allow for trailing
+ NUL terminator.
+ * update.c (special_file_mismatch): Ditto.
+ (Reported by Pekka Savola <pekkas@netcore.fi>.)
+
+2001-07-05 Larry Jones <larry.jones@sdrc.com>
+
+ * client.c, root.c: Fix -Wall warnings.
+
+ * buffer.c: #include socket header to declare shutdown().
+
+ * rcs.c (rcsbuf_open): Use getpagesize() instead of sysconf() for
+ portability.
+ (RCS_copydeltas, rcsbuf_fill): Fix -Wall warnings.
+
+2001-07-04 Derek Price <dprice@collab.net>
+
+ * Makefile.in: Regenerated with new Automake release candidate 1.4h.
+
+2001-07-03 Derek Price <dprice@collab.net>
+
+ * rcs.c (rcsbuf_open): Reduce memory consumption still further by not
+ mmapping the entire file when pos is specified.
+ (rcsbuf_cache_open): Add FIXME comment wrt read-only mmaps and rcsbuf
+ caching.
+
+2001-07-03 Derek Price <dprice@collab.net>
+
+ * rcs.c (rcsbuf_open): Use mmap when possible to reduce memory
+ consumption, especially with large (e.g. binary) files.
+ (rcsbuf_close): Call munmap.
+ (rcsbuf_getkey): Remove the buffer fill code when using mmap.
+ (rcsbuf_getrevnum): Ditto.
+ (rcsbuf_fill): Remove this function when using mmap.
+ (rcsbuf_cache_open): Mostly don't use this function with mmap.
+ (RCS_copydeltas): Don't depend on the file pointer with mmap.
+
+ * stamp-h2.in: Regenerated.
+
+2001-07-03 Derek Price <dprice@collab.net>
+
+ * update.c: Indent compiler directives.
+
+2001-07-02 Larry Jones <larry.jones@sdrc.com>
+
+ * import.c (update_rcs_file): Use -kb instead of -ko when comparing
+ binary files.
+ (Reported by Gyula Faller <gfaller@graphisoft.hu>.)
+
+2001-06-28 Larry Jones <larry.jones@sdrc.com>
+
+ * checkout.c (checkout): Explicitly initialize all the static options
+ so that multiple calls work right. Also fix potential memory leaks.
+ (Reported by Dr. Dieter Maurer <dieter@sz-sb.de>.)
+
+2001-06-28 Derek Price <dprice@collab.net>
+
+ * Makefile.in: Regenerated with new version of Automake.
+
+2001-06-28 Larry Jones <larry.jones@sdrc.com>
+
+ * checkout.c (checkout): Set history_name for export as well as
+ checkout.
+ (checkout_proc): Use it.
+
+ * checkout.c (safe_location): Add missing argument in error message.
+
+2001-06-26 Larry Jones <larry.jones@sdrc.com>
+
+ * recurse.c (start_recursion): Use strip_trailing_slashes instead
+ of doing it by hand.
+
+ * server.c (pserver_authenticate_connection): Don't clear out
+ descrambled_password until *after* it's (potentially) logged.
+ (Reported by Eric Hanchrow <offby1@blarg.net>.)
+
+2001-06-25 Larry Jones <larry.jones@sdrc.com>
+
+ * recurse.c (start_recursion): Deal with at least some of the cases
+ where trailing slashes cause confusion.
+ (Reported by Malcolm Fernandes <fernande@redback.com>.)
+ * sanity.sh (basica, basicb): Tweak existing tests to check this.
+
+2001-06-22 Larry Jones <larry.jones@sdrc.com>
+
+ * sanity.sh (modules5): New tests with -d on command line.
+
+2001-06-21 Larry Jones <larry.jones@sdrc.com>
+
+ * modules.c (do_module): Use run_module_prog and server_active to
+ determine when to call server_prog instead of using server_expanding
+ so that we get the right paths in the replies as long as we take
+ mwhere into account in addition to where.
+ (Reported by Pascal Bourguignon <pjb@informatimago.com>.)
+ * server.c (server_prog): Use protocol pipe instead of buf_to_net.
+ * sanity.sh (modules5): Remove FIXCVS comment and update to match.
+ * server.c, server.h: Remove server_expanding since now unused.
+
+2001-06-21 Larry Jones <larry.jones@sdrc.com>
+ for Stephen Rasku <stephen@tgivan.com>
+
+ * admin.c: Corrected spelling mistakes in help.
+
+2001-06-20 Derek Price <dprice@collab.net>
+
+ * client.c (socket_buffer_shutdown): Fix untested typos.
+ (Reported by "Jerzy Kaczorowski" <jerzyk@wndtabs.com>.)
+
+ * buffer.c (stdio_buffer_shutdown): Put the call to SHUTDOWN_SERVER in
+ the correct place.
+
+2001-06-20 Derek Price <dprice@collab.net>
+
+ * logmsg.c (do_editor): Abort in the case that the file has only
+ comment lines.
+ (Original patch from Mark Valentine <mark@thuvia.demon.co.uk>.)
+
+ * logmsg.c (do_editor): Fix rare memory leak.
+ * sanity.sh (editor): Add tests for aborted log messages.
+
+2001-06-20 Larry Jones <larry.jones@sdrc.com>
+
+ * server.c (switch_to_user): Only set $CVS_USER if
+ AUTH_SERVER_SUPPORT is defined.
+ (Reported by Nalin Dahyabhai <nalin@blade.devel.redhat.com>.)
+
+2001-06-13 Derek Price <dprice@collab.net>
+
+ * client.c: Fix incorrect fixed-size buffer usage in
+ connect_to_gserver().
+ (Minor changes to a patch from Alexey Mahotkin <alexm@hsys.msk.ru>.)
+
+2001-06-11 Derek Price <dprice@collab.net>
+
+ * main.c (main): Always print $CVSROOT when parse_cvsroot fails.
+ * root.c (parse_cvsroot): Tidy error messages and provide more
+ consistent behavior.
+ * sanity.sh (crerepos): Adapt to new error messages.
+ (Suggested by Alexey Mahotkin <alexm@hsys.msk.ru>.)
+
+2001-06-08 Derek Price <dprice@collab.net>
+
+ * sanity.sh (tagf-28): Use $CVSROOT_DIRNAME.
+
+2001-06-07 Larry Jones <larry.jones@sdrc.com>
+
+ * rcs.c (RCS_unlock): Reverse kj's change of 1999-10-18: a bare -u
+ should never break locks, you have to specify a specific revision
+ to do that. Also add an informative message for a bare -u when
+ the user doesn't hold any locks.
+ * commit.c (unlockrcs): Make RCS_unlock quiet, like RCS_lock.
+ * sanity.sh (rmadd-24): Update to match.
+
+ * sanity.sh (crerepos-6a): Set CVS_RSH for ${testcvs}, not for
+ dotest_fail. Allow for "broken pipe" rather than "end of file".
+
+2001-06-07 Derek Price <dprice@collab.net>
+
+ * sanity.sh (tagf): Use $CVSROOT_DIRNAME rather than
+ /tmp/cvs-sanity/cvsroot.
+
+2001-06-06 Derek Price <dprice@collab.net>
+
+ (Reformatting, bug fixes, tests, and comments to a
+ patch from Stephen Cameron <steve.cameron@compaq.com>.)
+
+ * tag.c: (rtag_fileproc, rtag_delete, tag_fileproc)
+ Changed behavior of "cvs tag -F", "cvs tag -d", "cvs rtag -F"
+ and "cvs rtag -d" so that they will not disturb existing
+ branch tags unless a new "-B" option is given.
+ * sanity.sh (tagf-16 - tagf-33): Added tests for new -B option
+ to "cvs tag" and "cvs rtag"
+
+2001-06-06 Derek Price <dprice@collab.net>
+
+ * sanity.sh (crerepos-6a): Set CVS_RSH=false and only for the actual
+ test call at Larry's suggestion. Also, test the error message since
+ it's fixed now.
+
+2001-06-05 Larry Jones <larry.jones@sdrc.com>
+
+ * rcs.c (RCS_unlock): Note when breaking someone else's lock.
+ (Reported by MURVAI-BUZOGANY Laszlo
+ <Laszlo.MURVAI-BUZOGANY@gt-systems.hu>.)
+ * sanity.sh (reserved-14): Update to match.
+
+2001-06-05 Derek Price <dprice@collab.net>
+
+ * sanity.sh (crerepos-6a): Set CVS_RSH=/bin/false... this is a local
+ mode only test anyhow.
+ (Thanks to Larry Jones and Morgan Burke <morgan@sitka.triumf.ca>.)
+
+2001-05-31 Derek Price <dprice@collab.net>
+
+ * sanity.sh (rcs2-7): Add today to the list of failure dates for rcs2-7
+ in the hopes that the data will eventually prove useful to someone
+ motivated enough to fix the problem.
+
+2001-05-30 Derek Price <dprice@collab.net>
+
+ * stamp-h2.in: Regenerated.
+
+2001-05-30 Derek Price <dprice@collab.net>
+
+ * *: Various bug fixes and comments for the following
+ patch from Donald Sharp <sharpd@cisco.com>:
+
+ * checkout.c (safe_location): cvs co -d <directory> still had
+ failure modes from the way the -d option works.
+ * sanity.sh: Misc error message resynching.
+
+2001-05-29 Derek Price <dprice@collab.net>
+
+ * Makefile.am (cvs_SOURCES): Add root.h.
+
+ * Makefile.in: Regenerated.
+ * stamp-h2.in: Regenerated.
+
+2001-05-29 Derek Price <dprice@collab.net>
+
+ * checkout.c (safe_location): Correct formatting.
+
+2001-05-29 Derek Price <dprice@collab.net>
+
+ * root.c (parse_cvsroot): Fix a comment.
+
+2001-05-26 Larry Jones <larry.jones@sdrc.com>
+
+ * checkout.c (safe_location): Use old-style definition to keep
+ non-ANSI compilers happy.
+
+ * sanity.sh (check_respository): Use ${CVSROOT_DIRNAME} instead
+ of /tmp/cvs-sanity/cvsroot.
+
+2001-05-25 Larry Jones <larry.jones@sdrc.com>
+
+ * sanity.sh (modules5): Add sleep to script to help avoid out of
+ order messages.
+
+ * filesubr.c (mkdir_if_needed): Return 1 if the directory exists
+ reguardless of what errno is set to.
+ (Reported by "Robinson, Greg" <greg.robinson@dsto.defence.gov.au>.)
+
+2001-05-25 Derek Price <dprice@collab.net>
+ for Donald Sharp <sharpd@cisco.com>
+
+ * checkout.c: Modified safe_location() to refuse checkout if
+ the -d option to co specifies inside of the repository.
+ * import.c: New parameter to safe_location needed to be added.
+ * cvs.h: New parameter to safe_location needed to be added.
+ * sanity.sh: Test case to test for failure mode.
+
+2001-05-23 Larry Jones <larry.jones@sdrc.com>
+
+ * checkout.c (checkout_proc): Don't build top_level_admin directory
+ when exporting.
+ (Reported by Tony Byrne <tonyb@directski.com>.)
+
+2001-05-21 Derek Price <dprice@collab.net>
+
+ * client.c: Fix a mispelling in a comment.
+ (Patch from Alexey Mahotkin <alexm@hsys.msk.ru>).
+
+2001-05-05 Larry Jones <larry.jones@sdrc.com>
+
+ * login.c (password_entry_operation): Only warn if unable to open
+ .cvspass for reading: may be initial login and it doesn't exist yet.
+
+2001-05-15 Derek Price <dprice@collab.net>
+
+ * client.c (start_tcp_server): Use the struct sockaddr_in declared in
+ the function.
+ (Reported by Emil Isberg <isberg@dynarc.se>.)
+
+2001-05-05 Larry Jones <larry.jones@sdrc.com>
+
+ * annotate.c (annotate): Pass local to do_module and rannotate_proc
+ so that -l actually works.
+ * log.c (cvslog): Ditto.
+ * patch.c (patch): Ditto; make local local instead of global.
+ (patch_proc): Use local_specified parameter instead of global.
+ * tag.c (cvstag, rtag_proc): Ditto.
+
+2001-05-05 Larry Jones <larry.jones@sdrc.com>
+
+ * client.h: Declare "struct buffer" outside prototype for __STDC__
+ compilers.
+
+2001-05-04 Derek Price <dprice@collab.net>
+
+ * client.c: General refactoring. Removed several global variables in
+ favor of passing locals and/or dynamic evaluation.
+ (recv_line): Removed this function.
+ (make_bufs_from_fds): New function with factored code.
+ (connect_to_forked_server): New prototype. Use new functions.
+ (connect_to_pserver): New prototype. Use new functions.
+ (connect_to_gserver): New prototype. Use new API.
+ (auth_server): Factored this portion of the pserver code so it can be
+ shared. Rewrote to use buffers rather than depending on a socket.
+ (start_rsh_server): New prototype. Use new API.
+ (start_tcp_server): New prototype. Use new API.
+ (start_server): Factor some code. Use new API.
+ * client.h: New prototypes.
+ * cvs.h: Gratuitous reformatting. Use new root.h.
+ * login.c (login): Use new connect_to_pserver API.
+ * root.h: New file. Contains some code that used to be in cvs.h.
+
+2001-05-04 Derek Price <dprice@collab.net>
+
+ * client.c: Gratuitous reformatting.
+ * client.h: Ditto.
+
+2001-05-04 Derek Price <dprice@collab.net>
+
+ * zlib.c (compress_buffer_shutdown_input): Use new buffer shutdown
+ prototype.
+ (compress_buffer_shutdown_output): Ditto.
+ (Thanks to Pavel Roskin <proski@gnu.org>.)
+
+2001-05-03 Derek Price <dprice@collab.net>
+
+ * buffer.c (struct stdio_buffer_closure): New structure to hold a
+ FILE * and the child's PID when necessary.
+ (stdio_buffer_initialize): Change proto to accept PID. Set up new
+ closure. Pass new stdio_buffer_shutdown to buf_initialize.
+ (stdio_buffer_input): Use new closure.
+ (stdio_buffer_output): Ditto.
+ (stdio_buffer_flush): Ditto.
+ (stdio_buffer_shutdown): New function. Teach buffer to close itself.
+ (packetizing_buffer_shutdown): Use new buffer shutdown proto.
+ * buffer.h (struct buffer): New buffer shutdown proto.
+ (stdio_buffer_initialize): New proto.
+ * client.c (log_buffer_shutdown): Use new proto.
+ (socket_buffer_initialize): Pass shutdown func.
+ (socket_buffer_shutdown): New function.
+ * server.c (get_responses_and_close): Remove most of the guts. Rely
+ on the buffer shutdown function from now on.
+ (start_rsh_server): Return child PID.
+
+2001-05-03 Larry Jones <larry.jones@sdrc.com>
+
+ * history.c (history_write): Handle the case where the user's home
+ directory doesn't exist gracefully instead of erroring out.
+ (Reported by David Hoover <dhoover@cadence.com>.)
+
+2001-05-03 Derek Price <dprice@collab.net>
+
+ * cvs.h: s/allocate_and_strcat/xrealloc_and_strcat/ since that is what
+ I wrote in the ChangeLog, oh, so long ago.
+ * diff.c (diff): Ditto.
+ * subr.c (allocate_and_strcat, xrealloc_and_strcat): Ditto.
+
+2001-05-02 Larry Jones <larry.jones@sdrc.com>
+
+ * rcs.c (RCS_getdate): Handle the (unusual!) case where we
+ can't find any revisions at all.
+ (Reported by Ryan Grow <rgrow@Dbdoctor.net>.)
+
+2001-04-30 Larry Jones <larry.jones@sdrc.com>
+
+ * sanity.sh (multiroot2-9a): Rename (from multiroot2-9) to avoid
+ duplicate names; fix to work without SERVER_SUPPORT defined.
+ (Reported by Pavel Roskin <proski@gnu.org>.)
+
+2001-04-29 Derek Price <dprice@collab.net>
+
+ * Makefile.am (check-local): Make dependent on localcheck and
+ remotecheck and move old check target...
+ (localcheck): here.
+
+ * Makefile.in: Regenerated.
+
+2001-04-27 Larry Jones <larry.jones@sdrc.com>
+
+ * sanity.sh (pserver): Add tests for readers and writers.
+
+2001-04-27 Derek Price <dprice@collab.net>
+
+ * sanity.sh (version-2r): Update to handle patch releases in version
+ numbers.
+
+2001-04-27 Derek Price <dprice@collab.net>
+
+ * version.c: Regenerated.
+
+2001-04-27 Derek Price <dprice@collab.net>
+
+ * version.c: Regenerated.
+
2001-04-27 Larry Jones <larry.jones@sdrc.com>
* main.c (lookup_command_attribute): Lookup specified command, not
diff --git a/contrib/cvs/src/Makefile.am b/contrib/cvs/src/Makefile.am
index 768d4f8..2020141 100644
--- a/contrib/cvs/src/Makefile.am
+++ b/contrib/cvs/src/Makefile.am
@@ -75,6 +75,7 @@ cvs_SOURCES = \
subr.c \
tag.c \
update.c \
+ version.c \
vers_ts.c \
watch.c \
wrapper.c \
@@ -89,15 +90,18 @@ cvs_SOURCES = \
hash.h \
myndbm.h \
rcs.h \
+ root.h \
server.h \
update.h \
+ version.h \
watch.h
+
+BUILT_SOURCES = version.h
+
cvs_LDADD = \
../diff/libdiff.a \
../lib/libcvs.a \
- ../zlib/libz.a \
- version.o
-cvs_EXTRA_DIST = version.c
+ ../zlib/libz.a
# extra clean targets
# wish this could be distclean-hdr-local but it's not part of automake
@@ -105,18 +109,18 @@ DISTCLEANFILES = options.h-SAVED check.log check.plog
# General
EXTRA_DIST = \
- $(cvs_EXTRA_DIST) \
.cvsignore \
ChangeLog-9194 \
ChangeLog-9395 \
ChangeLog-96 \
ChangeLog-97 \
build_src.com \
- sanity.sh \
- version.c \
- version.c.in
+ sanity.sh
+
+check-local: localcheck remotecheck
-check-local:
+.PHONY: localcheck
+localcheck:
$(SHELL) $(srcdir)/sanity.sh `pwd`/cvs
.PHONY: remotecheck
@@ -125,20 +129,6 @@ remotecheck: all
## MAINTAINER Targets
-# version.c
-# - build this here so that we can distribute it
-# - version.c needs to be updated only once, since it depends on
-# configure.in, not on the results of a 'configure' run.
-# - It is guaranteed (with GNU Make) that when the version in configure.in
-# is changed, acversion.m4 is built only after the new version number is
-# propagated to the Makefile. (Libtool uses the same guarantee.)
-# - need the explicit version.o dependency or else make won't match
-# $(srcdir)/version.c when looking for a dependency for version.c
-version.o: $(srcdir)/version.c
-$(srcdir)/version.c: $(srcdir)/version.c.in $(top_srcdir)/configure.in
- sed 's,@VERSION\@,$(VERSION),g' $(srcdir)/version.c.in >$(srcdir)/version.tc
- mv $(srcdir)/version.tc $(srcdir)/version.c
-
# for backwards compatibility with the old makefiles
.PHONY: realclean
realclean: maintainer-clean
diff --git a/contrib/cvs/src/Makefile.in b/contrib/cvs/src/Makefile.in
index c80deab..a4d5966 100644
--- a/contrib/cvs/src/Makefile.in
+++ b/contrib/cvs/src/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated automatically by automake 1.4e from Makefile.am.
+# Makefile.in generated automatically by automake 1.5 from Makefile.am.
# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
# Free Software Foundation, Inc.
@@ -45,11 +45,9 @@ infodir = @infodir@
mandir = @mandir@
includedir = @includedir@
oldincludedir = /usr/include
-
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
-
top_builddir = ..
ACLOCAL = @ACLOCAL@
@@ -63,7 +61,6 @@ INSTALL_DATA = @INSTALL_DATA@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_HEADER = $(INSTALL_DATA)
transform = @program_transform_name@
-
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
@@ -75,25 +72,22 @@ AWK = @AWK@
CC = @CC@
CSH = @CSH@
DEPDIR = @DEPDIR@
-ETAGS = @ETAGS@
-ETAGS_INCLUDE_OPTION = @ETAGS_INCLUDE_OPTION@
+EXEEXT = @EXEEXT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
-INSTALL_STRIP_PROGRAM_ENV = @INSTALL_STRIP_PROGRAM_ENV@
KRB4 = @KRB4@
LN_S = @LN_S@
-MAKEINFO = @MAKEINFO@
+OBJEXT = @OBJEXT@
PACKAGE = @PACKAGE@
PERL = @PERL@
PR = @PR@
PS2PDF = @PS2PDF@
RANLIB = @RANLIB@
ROFF = @ROFF@
-STRIP = @STRIP@
TEXI2DVI = @TEXI2DVI@
VERSION = @VERSION@
YACC = @YACC@
-_am_include = @_am_include@
-_am_quote = @_am_quote@
+am__include = @am__include@
+am__quote = @am__quote@
includeopt = @includeopt@
install_sh = @install_sh@
@@ -159,6 +153,7 @@ cvs_SOURCES = \
subr.c \
tag.c \
update.c \
+ version.c \
vers_ts.c \
watch.c \
wrapper.c \
@@ -173,17 +168,20 @@ cvs_SOURCES = \
hash.h \
myndbm.h \
rcs.h \
+ root.h \
server.h \
update.h \
+ version.h \
watch.h
+
+BUILT_SOURCES = version.h
+
cvs_LDADD = \
../diff/libdiff.a \
../lib/libcvs.a \
- ../zlib/libz.a \
- version.o
+ ../zlib/libz.a
-cvs_EXTRA_DIST = version.c
# extra clean targets
# wish this could be distclean-hdr-local but it's not part of automake
@@ -191,23 +189,18 @@ DISTCLEANFILES = options.h-SAVED check.log check.plog
# General
EXTRA_DIST = \
- $(cvs_EXTRA_DIST) \
.cvsignore \
ChangeLog-9194 \
ChangeLog-9395 \
ChangeLog-96 \
ChangeLog-97 \
build_src.com \
- sanity.sh \
- version.c \
- version.c.in
+ sanity.sh
-EXEEXT =
-OBJEXT = o
subdir = src
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_HEADER = $(top_builddir)/config.h options.h
-CONFIG_CLEAN_FILES = cvsbug
+CONFIG_CLEAN_FILES = cvsbug version.h
bin_PROGRAMS = cvs$(EXEEXT)
PROGRAMS = $(bin_PROGRAMS)
@@ -226,26 +219,19 @@ am_cvs_OBJECTS = add.$(OBJEXT) admin.$(OBJEXT) annotate.$(OBJEXT) \
recurse.$(OBJEXT) release.$(OBJEXT) remove.$(OBJEXT) \
repos.$(OBJEXT) root.$(OBJEXT) run.$(OBJEXT) scramble.$(OBJEXT) \
server.$(OBJEXT) status.$(OBJEXT) subr.$(OBJEXT) tag.$(OBJEXT) \
- update.$(OBJEXT) vers_ts.$(OBJEXT) watch.$(OBJEXT) \
- wrapper.$(OBJEXT) zlib.$(OBJEXT)
+ update.$(OBJEXT) version.$(OBJEXT) vers_ts.$(OBJEXT) \
+ watch.$(OBJEXT) wrapper.$(OBJEXT) zlib.$(OBJEXT)
cvs_OBJECTS = $(am_cvs_OBJECTS)
-cvs_DEPENDENCIES = ../diff/libdiff.a ../lib/libcvs.a ../zlib/libz.a \
- version.o
+cvs_DEPENDENCIES = ../diff/libdiff.a ../lib/libcvs.a ../zlib/libz.a
cvs_LDFLAGS =
SCRIPTS = $(bin_SCRIPTS)
-COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
- $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
-CFLAGS = @CFLAGS@
-CCLD = $(CC)
-LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
-DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir) -I.
DEFS = @DEFS@
+DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir) -I.
CPPFLAGS = @CPPFLAGS@
LDFLAGS = @LDFLAGS@
LIBS = @LIBS@
-DIST_SOURCES = $(cvs_SOURCES)
depcomp = $(SHELL) $(top_srcdir)/depcomp
@AMDEP_TRUE@DEP_FILES = $(DEPDIR)/add.Po $(DEPDIR)/admin.Po \
@AMDEP_TRUE@ $(DEPDIR)/annotate.Po $(DEPDIR)/buffer.Po \
@@ -272,28 +258,30 @@ depcomp = $(SHELL) $(top_srcdir)/depcomp
@AMDEP_TRUE@ $(DEPDIR)/server.Po $(DEPDIR)/status.Po \
@AMDEP_TRUE@ $(DEPDIR)/subr.Po $(DEPDIR)/tag.Po \
@AMDEP_TRUE@ $(DEPDIR)/update.Po $(DEPDIR)/vers_ts.Po \
-@AMDEP_TRUE@ $(DEPDIR)/watch.Po $(DEPDIR)/wrapper.Po \
-@AMDEP_TRUE@ $(DEPDIR)/zlib.Po
+@AMDEP_TRUE@ $(DEPDIR)/version.Po $(DEPDIR)/watch.Po \
+@AMDEP_TRUE@ $(DEPDIR)/wrapper.Po $(DEPDIR)/zlib.Po
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+CFLAGS = @CFLAGS@
+DIST_SOURCES = $(cvs_SOURCES)
DIST_COMMON = ./stamp-h2.in ChangeLog Makefile.am Makefile.in cvsbug.in \
- options.h.in
+ options.h.in version.h.in
SOURCES = $(cvs_SOURCES)
-OBJECTS = $(am_cvs_OBJECTS)
-all: options.h
+all: $(BUILT_SOURCES) options.h
$(MAKE) $(AM_MAKEFLAGS) all-am
.SUFFIXES:
.SUFFIXES: .c .o .obj
-
$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
cd $(top_srcdir) && \
$(AUTOMAKE) --gnu src/Makefile
-
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
cd $(top_builddir) && \
CONFIG_HEADERS= CONFIG_LINKS= \
CONFIG_FILES=$(subdir)/$@ $(SHELL) ./config.status
-
options.h: stamp-h2
@if test ! -f $@; then \
rm -f stamp-h2; \
@@ -321,12 +309,16 @@ distclean-hdr:
-rm -f options.h
cvsbug: $(top_builddir)/config.status cvsbug.in
cd $(top_builddir) && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= CONFIG_LINKS= $(SHELL) ./config.status
+version.h: $(top_builddir)/config.status version.h.in
+ cd $(top_builddir) && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= CONFIG_LINKS= $(SHELL) ./config.status
install-binPROGRAMS: $(bin_PROGRAMS)
@$(NORMAL_INSTALL)
$(mkinstalldirs) $(DESTDIR)$(bindir)
@list='$(bin_PROGRAMS)'; for p in $$list; do \
- if test -f $$p; then \
- f=`echo $$p|sed 's/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \
+ p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
+ if test -f $$p \
+ ; then \
+ f=`echo $$p1|sed '$(transform);s/$$/$(EXEEXT)/'`; \
echo " $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/$$f"; \
$(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/$$f; \
else :; fi; \
@@ -342,8 +334,7 @@ uninstall-binPROGRAMS:
clean-binPROGRAMS:
-test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS)
-
-cvs$(EXEEXT): $(cvs_OBJECTS) $(cvs_DEPENDENCIES)
+cvs$(EXEEXT): $(cvs_OBJECTS) $(cvs_DEPENDENCIES)
@rm -f cvs$(EXEEXT)
$(LINK) $(cvs_LDFLAGS) $(cvs_OBJECTS) $(cvs_LDADD) $(LIBS)
install-binSCRIPTS: $(bin_SCRIPTS)
@@ -374,6 +365,78 @@ mostlyclean-compile:
distclean-compile:
-rm -f *.tab.c
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/add.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/admin.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/annotate.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/buffer.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/checkin.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/checkout.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/classify.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/client.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/commit.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/create_adm.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/cvsrc.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/diff.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/edit.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/entries.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/error.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/expand_path.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/fileattr.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/filesubr.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/find_names.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/hardlink.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/hash.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/history.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/ignore.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/import.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/lock.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/log.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/login.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/logmsg.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/main.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/mkmodules.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/modules.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/myndbm.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/no_diff.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/parseinfo.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/patch.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/rcs.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/rcscmds.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/recurse.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/release.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/remove.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/repos.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/root.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/run.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/scramble.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/server.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/status.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/subr.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/tag.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/update.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/vers_ts.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/version.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/watch.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/wrapper.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/zlib.Po@am__quote@
+
+distclean-depend:
+ -rm -rf $(DEPDIR)
+
+.c.o:
+@AMDEP_TRUE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ $(COMPILE) -c `test -f $< || echo '$(srcdir)/'`$<
+
+.c.obj:
+@AMDEP_TRUE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ $(COMPILE) -c `cygpath -w $<`
+CCDEPMODE = @CCDEPMODE@
+uninstall-info-am:
+
tags: TAGS
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
@@ -390,93 +453,21 @@ TAGS: $(HEADERS) $(SOURCES) options.h.in $(TAGS_DEPENDENCIES) \
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(TAGS_FILES)'; \
- unique=`for i in $$list @CONFIG@; do \
+ unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
test -z "$(ETAGS_ARGS)options.h.in$$unique$(LISP)$$tags" \
- || $(ETAGS) $(ETAGS_ARGS) $$tags options.h.in $$unique $(LISP)
+ || etags $(ETAGS_ARGS) $$tags options.h.in $$unique $(LISP)
GTAGS:
here=`CDPATH=: && cd $(top_builddir) && pwd` \
&& cd $(top_srcdir) \
- && gtags -i $$here
+ && gtags -i $(GTAGS_ARGS) $$here
distclean-tags:
- -rm -f TAGS ID
-
-@_am_include@ @_am_quote@$(DEPDIR)/add.Po@_am_quote@
-@_am_include@ @_am_quote@$(DEPDIR)/admin.Po@_am_quote@
-@_am_include@ @_am_quote@$(DEPDIR)/annotate.Po@_am_quote@
-@_am_include@ @_am_quote@$(DEPDIR)/buffer.Po@_am_quote@
-@_am_include@ @_am_quote@$(DEPDIR)/checkin.Po@_am_quote@
-@_am_include@ @_am_quote@$(DEPDIR)/checkout.Po@_am_quote@
-@_am_include@ @_am_quote@$(DEPDIR)/classify.Po@_am_quote@
-@_am_include@ @_am_quote@$(DEPDIR)/client.Po@_am_quote@
-@_am_include@ @_am_quote@$(DEPDIR)/commit.Po@_am_quote@
-@_am_include@ @_am_quote@$(DEPDIR)/create_adm.Po@_am_quote@
-@_am_include@ @_am_quote@$(DEPDIR)/cvsrc.Po@_am_quote@
-@_am_include@ @_am_quote@$(DEPDIR)/diff.Po@_am_quote@
-@_am_include@ @_am_quote@$(DEPDIR)/edit.Po@_am_quote@
-@_am_include@ @_am_quote@$(DEPDIR)/entries.Po@_am_quote@
-@_am_include@ @_am_quote@$(DEPDIR)/error.Po@_am_quote@
-@_am_include@ @_am_quote@$(DEPDIR)/expand_path.Po@_am_quote@
-@_am_include@ @_am_quote@$(DEPDIR)/fileattr.Po@_am_quote@
-@_am_include@ @_am_quote@$(DEPDIR)/filesubr.Po@_am_quote@
-@_am_include@ @_am_quote@$(DEPDIR)/find_names.Po@_am_quote@
-@_am_include@ @_am_quote@$(DEPDIR)/hardlink.Po@_am_quote@
-@_am_include@ @_am_quote@$(DEPDIR)/hash.Po@_am_quote@
-@_am_include@ @_am_quote@$(DEPDIR)/history.Po@_am_quote@
-@_am_include@ @_am_quote@$(DEPDIR)/ignore.Po@_am_quote@
-@_am_include@ @_am_quote@$(DEPDIR)/import.Po@_am_quote@
-@_am_include@ @_am_quote@$(DEPDIR)/lock.Po@_am_quote@
-@_am_include@ @_am_quote@$(DEPDIR)/log.Po@_am_quote@
-@_am_include@ @_am_quote@$(DEPDIR)/login.Po@_am_quote@
-@_am_include@ @_am_quote@$(DEPDIR)/logmsg.Po@_am_quote@
-@_am_include@ @_am_quote@$(DEPDIR)/main.Po@_am_quote@
-@_am_include@ @_am_quote@$(DEPDIR)/mkmodules.Po@_am_quote@
-@_am_include@ @_am_quote@$(DEPDIR)/modules.Po@_am_quote@
-@_am_include@ @_am_quote@$(DEPDIR)/myndbm.Po@_am_quote@
-@_am_include@ @_am_quote@$(DEPDIR)/no_diff.Po@_am_quote@
-@_am_include@ @_am_quote@$(DEPDIR)/parseinfo.Po@_am_quote@
-@_am_include@ @_am_quote@$(DEPDIR)/patch.Po@_am_quote@
-@_am_include@ @_am_quote@$(DEPDIR)/rcs.Po@_am_quote@
-@_am_include@ @_am_quote@$(DEPDIR)/rcscmds.Po@_am_quote@
-@_am_include@ @_am_quote@$(DEPDIR)/recurse.Po@_am_quote@
-@_am_include@ @_am_quote@$(DEPDIR)/release.Po@_am_quote@
-@_am_include@ @_am_quote@$(DEPDIR)/remove.Po@_am_quote@
-@_am_include@ @_am_quote@$(DEPDIR)/repos.Po@_am_quote@
-@_am_include@ @_am_quote@$(DEPDIR)/root.Po@_am_quote@
-@_am_include@ @_am_quote@$(DEPDIR)/run.Po@_am_quote@
-@_am_include@ @_am_quote@$(DEPDIR)/scramble.Po@_am_quote@
-@_am_include@ @_am_quote@$(DEPDIR)/server.Po@_am_quote@
-@_am_include@ @_am_quote@$(DEPDIR)/status.Po@_am_quote@
-@_am_include@ @_am_quote@$(DEPDIR)/subr.Po@_am_quote@
-@_am_include@ @_am_quote@$(DEPDIR)/tag.Po@_am_quote@
-@_am_include@ @_am_quote@$(DEPDIR)/update.Po@_am_quote@
-@_am_include@ @_am_quote@$(DEPDIR)/vers_ts.Po@_am_quote@
-@_am_include@ @_am_quote@$(DEPDIR)/watch.Po@_am_quote@
-@_am_include@ @_am_quote@$(DEPDIR)/wrapper.Po@_am_quote@
-@_am_include@ @_am_quote@$(DEPDIR)/zlib.Po@_am_quote@
-
-distclean-depend:
- -rm -rf $(DEPDIR)
-
-CCDEPMODE = @CCDEPMODE@
-
-.c.o:
- source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
- depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
- $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- $(COMPILE) -c -o $@ `test -f $< || echo '$(srcdir)/'`$<
-
-.c.obj:
- source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
- depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
- $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- $(COMPILE) -c -o $@ `cygpath -w $<`
-
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
@@ -485,7 +476,11 @@ distdir = $(top_distdir)/$(PACKAGE)-$(VERSION)
distdir: $(DISTFILES)
@for file in $(DISTFILES); do \
- d=$(srcdir); \
+ if test -f $$file; then d=.; else d=$(srcdir); fi; \
+ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test "$$dir" != "$$file" && test "$$dir" != "."; then \
+ $(mkinstalldirs) "$(distdir)/$$dir"; \
+ fi; \
if test -d $$d/$$file; then \
cp -pR $$d/$$file $(distdir) \
|| exit 1; \
@@ -512,24 +507,22 @@ install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
-
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
- INSTALL_PROGRAM_ENV='$(INSTALL_STRIP_PROGRAM_ENV)' install
-
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
clean-generic:
distclean-generic:
- -rm -f Makefile $(CONFIG_CLEAN_FILES)
- -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+ -rm -f Makefile $(CONFIG_CLEAN_FILES) stamp-h stamp-h[0-9]*
-test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
- -rm -f Makefile.in
+ -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
clean: clean-am
clean-am: clean-binPROGRAMS clean-generic mostlyclean-am
@@ -539,11 +532,11 @@ distclean: distclean-am
distclean-am: clean-am distclean-compile distclean-depend \
distclean-generic distclean-hdr distclean-tags
-dvi:
+dvi: dvi-am
dvi-am:
-info:
+info: info-am
info-am:
@@ -551,7 +544,7 @@ install-data-am:
install-exec-am: install-binPROGRAMS install-binSCRIPTS
-install-info:
+install-info: install-info-am
install-man:
@@ -565,45 +558,35 @@ mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-compile mostlyclean-generic
-uninstall-am: uninstall-binPROGRAMS uninstall-binSCRIPTS
-
-.PHONY: all all-am check check-am check-local clean clean-binPROGRAMS \
- clean-generic distclean distclean-compile distclean-depend \
- distclean-generic distclean-hdr distclean-tags distdir dvi \
- dvi-am info info-am install install-am install-binPROGRAMS \
- install-binSCRIPTS install-data install-data-am install-exec \
- install-exec-am install-info install-man install-strip \
- installcheck installcheck-am installdirs maintainer-clean \
+uninstall-am: uninstall-binPROGRAMS uninstall-binSCRIPTS \
+ uninstall-info-am
+
+.PHONY: GTAGS all all-am check check-am check-local clean \
+ clean-binPROGRAMS clean-generic distclean distclean-compile \
+ distclean-depend distclean-generic distclean-hdr distclean-tags \
+ distdir dvi dvi-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 \
+ installcheck-am installdirs maintainer-clean \
maintainer-clean-generic mostlyclean mostlyclean-compile \
mostlyclean-generic tags uninstall uninstall-am \
- uninstall-binPROGRAMS uninstall-binSCRIPTS
+ uninstall-binPROGRAMS uninstall-binSCRIPTS uninstall-info-am
-check-local:
+check-local: localcheck remotecheck
+
+.PHONY: localcheck
+localcheck:
$(SHELL) $(srcdir)/sanity.sh `pwd`/cvs
.PHONY: remotecheck
remotecheck: all
$(SHELL) $(srcdir)/sanity.sh -r `pwd`/cvs
-# version.c
-# - build this here so that we can distribute it
-# - version.c needs to be updated only once, since it depends on
-# configure.in, not on the results of a 'configure' run.
-# - It is guaranteed (with GNU Make) that when the version in configure.in
-# is changed, acversion.m4 is built only after the new version number is
-# propagated to the Makefile. (Libtool uses the same guarantee.)
-# - need the explicit version.o dependency or else make won't match
-# $(srcdir)/version.c when looking for a dependency for version.c
-version.o: $(srcdir)/version.c
-$(srcdir)/version.c: $(srcdir)/version.c.in $(top_srcdir)/configure.in
- sed 's,@VERSION\@,$(VERSION),g' $(srcdir)/version.c.in >$(srcdir)/version.tc
- mv $(srcdir)/version.tc $(srcdir)/version.c
-
# for backwards compatibility with the old makefiles
.PHONY: realclean
realclean: maintainer-clean
-
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
diff --git a/contrib/cvs/src/admin.c b/contrib/cvs/src/admin.c
index 359bedf..2a35d71 100644
--- a/contrib/cvs/src/admin.c
+++ b/contrib/cvs/src/admin.c
@@ -31,12 +31,12 @@ static const char *const admin_usage[] =
"\t (all names if omitted).\n",
"\t-I Run interactively.\n",
"\t-k subst Set keyword substitution mode:\n",
- "\t kv (Default) Substitue keyword and value.\n",
- "\t kvl Substitue keyword, value, and locker (if any).\n",
- "\t k Substitue keyword only.\n",
+ "\t kv (Default) Substitute keyword and value.\n",
+ "\t kvl Substitute keyword, value, and locker (if any).\n",
+ "\t k Substitute keyword only.\n",
"\t o Preserve original string.\n",
"\t b Like o, but mark file as binary.\n",
- "\t v Substitue value only.\n",
+ "\t v Substitute value only.\n",
"\t-l[rev] Lock revision (latest revision on branch,\n",
"\t latest revision on trunk if omitted).\n",
"\t-L Set strict locking.\n",
@@ -169,7 +169,7 @@ admin (argc, argv)
while ((c = getopt (argc, argv,
"+ib::c:a:A:e::l::u::LUn:N:m:o:s:t::IqxV:k:")) != -1)
{
- if (c != 'k')
+ if (c != 'k' && c != 'q')
only_k_option = 0;
switch (c)
diff --git a/contrib/cvs/src/annotate.c b/contrib/cvs/src/annotate.c
index 827619d..41acdf7 100644
--- a/contrib/cvs/src/annotate.c
+++ b/contrib/cvs/src/annotate.c
@@ -17,6 +17,7 @@
/* Options from the command line. */
static int force_tag_match = 1;
+static int force_binary = 0;
static char *tag = NULL;
static int tag_validated;
static char *date = NULL;
@@ -30,10 +31,11 @@ static int rannotate_proc PROTO((int argc, char **argv, char *xwhere,
static const char *const annotate_usage[] =
{
- "Usage: %s %s [-lRf] [-r rev] [-D date] [files...]\n",
+ "Usage: %s %s [-lRfF] [-r rev] [-D date] [files...]\n",
"\t-l\tLocal directory only, no recursion.\n",
"\t-R\tProcess directories recursively.\n",
"\t-f\tUse head revision if tag/date not found.\n",
+ "\t-F\tAnnotate binary files.\n",
"\t-r rev\tAnnotate file as of specified revision/tag.\n",
"\t-D date\tAnnotate file as of specified date.\n",
"(Specify the --help global option for a list of other help options)\n",
@@ -58,7 +60,7 @@ annotate (argc, argv)
usage (annotate_usage);
optind = 0;
- while ((c = getopt (argc, argv, "+lr:D:fR")) != -1)
+ while ((c = getopt (argc, argv, "+lr:D:fFR")) != -1)
{
switch (c)
{
@@ -77,6 +79,9 @@ annotate (argc, argv)
case 'f':
force_tag_match = 0;
break;
+ case 'F':
+ force_binary = 1;
+ break;
case '?':
default:
usage (annotate_usage);
@@ -100,6 +105,8 @@ annotate (argc, argv)
send_arg ("-l");
if (!force_tag_match)
send_arg ("-f");
+ if (force_binary)
+ send_arg ("-F");
option_with_arg ("-r", tag);
if (date)
client_senddate (date);
@@ -128,14 +135,14 @@ annotate (argc, argv)
for (i = 0; i < argc; i++)
{
err += do_module (db, argv[i], MISC, "Annotating", rannotate_proc,
- (char *) NULL, 0, 0, 0, 0, (char *) NULL);
+ (char *) NULL, 0, local, 0, 0, (char *) NULL);
}
close_module (db);
}
else
{
err = rannotate_proc (argc + 1, argv - 1, (char *) NULL,
- (char *) NULL, (char *) NULL, 0, 0, (char *) NULL,
+ (char *) NULL, (char *) NULL, 0, local, (char *) NULL,
(char *) NULL);
}
@@ -251,7 +258,7 @@ annotate_fileproc (callerdat, finfo)
void *callerdat;
struct file_info *finfo;
{
- char *version;
+ char *expand, *version;
if (finfo->rcs == NULL)
return (1);
@@ -259,19 +266,28 @@ annotate_fileproc (callerdat, finfo)
if (finfo->rcs->flags & PARTIAL)
RCS_reparsercsfile (finfo->rcs, (FILE **) NULL, (struct rcsbuffer *) NULL);
+ expand = RCS_getexpand (finfo->rcs);
version = RCS_getversion (finfo->rcs, tag, date, force_tag_match,
(int *) NULL);
+
if (version == NULL)
return 0;
/* Distinguish output for various files if we are processing
several files. */
- cvs_outerr ("Annotations for ", 0);
+ cvs_outerr ("\nAnnotations for ", 0);
cvs_outerr (finfo->fullname, 0);
cvs_outerr ("\n***************\n", 0);
- RCS_deltas (finfo->rcs, (FILE *) NULL, (struct rcsbuffer *) NULL,
- version, RCS_ANNOTATE, NULL, NULL, NULL, NULL);
+ if (!force_binary && expand && expand[0] == 'b')
+ {
+ cvs_outerr ("Skipping binary file -- -F not specified.\n", 0);
+ }
+ else
+ {
+ RCS_deltas (finfo->rcs, (FILE *) NULL, (struct rcsbuffer *) NULL,
+ version, RCS_ANNOTATE, NULL, NULL, NULL, NULL);
+ }
free (version);
return 0;
}
diff --git a/contrib/cvs/src/buffer.c b/contrib/cvs/src/buffer.c
index 8f90545..0c13cde 100644
--- a/contrib/cvs/src/buffer.c
+++ b/contrib/cvs/src/buffer.c
@@ -6,6 +6,12 @@
#if defined (SERVER_SUPPORT) || defined (CLIENT_SUPPORT)
+#ifdef HAVE_WINSOCK_H
+# include <winsock.h>
+#else
+# include <sys/socket.h>
+#endif
+
/* OS/2 doesn't have EIO. FIXME: this whole notion of turning
a different error into EIO strikes me as pretty dubious. */
#if !defined (EIO)
@@ -28,7 +34,7 @@ buf_initialize (input, output, flush, block, shutdown, memory, closure)
int (*output) PROTO((void *, const char *, int, int *));
int (*flush) PROTO((void *));
int (*block) PROTO((void *, int));
- int (*shutdown) PROTO((void *));
+ int (*shutdown) PROTO((struct buffer *));
void (*memory) PROTO((struct buffer *));
void *closure;
{
@@ -73,7 +79,7 @@ buf_nonio_initialize (memory)
(int (*) PROTO((void *, const char *, int, int *))) NULL,
(int (*) PROTO((void *))) NULL,
(int (*) PROTO((void *, int))) NULL,
- (int (*) PROTO((void *))) NULL,
+ (int (*) PROTO((struct buffer *))) NULL,
memory,
(void *) NULL));
}
@@ -1198,7 +1204,7 @@ buf_shutdown (buf)
struct buffer *buf;
{
if (buf->shutdown)
- return (*buf->shutdown) (buf->closure);
+ return (*buf->shutdown) (buf);
return 0;
}
@@ -1210,22 +1216,35 @@ buf_shutdown (buf)
static int stdio_buffer_input PROTO((void *, char *, int, int, int *));
static int stdio_buffer_output PROTO((void *, const char *, int, int *));
static int stdio_buffer_flush PROTO((void *));
+static int stdio_buffer_shutdown PROTO((struct buffer *buf));
/* Initialize a buffer built on a stdio FILE. */
+struct stdio_buffer_closure
+{
+ FILE *fp;
+ int child_pid;
+};
+
struct buffer *
-stdio_buffer_initialize (fp, input, memory)
+stdio_buffer_initialize (fp, child_pid, input, memory)
FILE *fp;
+ int child_pid;
int input;
void (*memory) PROTO((struct buffer *));
{
+ struct stdio_buffer_closure *bc = malloc (sizeof (*bc));
+
+ bc->fp = fp;
+ bc->child_pid = child_pid;
+
return buf_initialize (input ? stdio_buffer_input : NULL,
input ? NULL : stdio_buffer_output,
input ? NULL : stdio_buffer_flush,
(int (*) PROTO((void *, int))) NULL,
- (int (*) PROTO((void *))) NULL,
+ stdio_buffer_shutdown,
memory,
- (void *) fp);
+ (void *) bc);
}
/* The buffer input function for a buffer built on a stdio FILE. */
@@ -1238,7 +1257,7 @@ stdio_buffer_input (closure, data, need, size, got)
int size;
int *got;
{
- FILE *fp = (FILE *) closure;
+ struct stdio_buffer_closure *bc = (struct stdio_buffer_closure *) closure;
int nbytes;
/* Since stdio does its own buffering, we don't worry about
@@ -1248,11 +1267,11 @@ stdio_buffer_input (closure, data, need, size, got)
{
int ch;
- ch = getc (fp);
+ ch = getc (bc->fp);
if (ch == EOF)
{
- if (feof (fp))
+ if (feof (bc->fp))
return -1;
else if (errno == 0)
return EIO;
@@ -1265,12 +1284,12 @@ stdio_buffer_input (closure, data, need, size, got)
return 0;
}
- nbytes = fread (data, 1, need, fp);
+ nbytes = fread (data, 1, need, bc->fp);
if (nbytes == 0)
{
*got = 0;
- if (feof (fp))
+ if (feof (bc->fp))
return -1;
else if (errno == 0)
return EIO;
@@ -1292,7 +1311,7 @@ stdio_buffer_output (closure, data, have, wrote)
int have;
int *wrote;
{
- FILE *fp = (FILE *) closure;
+ struct stdio_buffer_closure *bc = (struct stdio_buffer_closure *) closure;
*wrote = 0;
@@ -1300,7 +1319,7 @@ stdio_buffer_output (closure, data, have, wrote)
{
int nbytes;
- nbytes = fwrite (data, 1, have, fp);
+ nbytes = fwrite (data, 1, have, bc->fp);
if (nbytes != have)
{
@@ -1324,9 +1343,9 @@ static int
stdio_buffer_flush (closure)
void *closure;
{
- FILE *fp = (FILE *) closure;
+ struct stdio_buffer_closure *bc = (struct stdio_buffer_closure *) closure;
- if (fflush (fp) != 0)
+ if (fflush (bc->fp) != 0)
{
if (errno == 0)
return EIO;
@@ -1337,6 +1356,116 @@ stdio_buffer_flush (closure)
return 0;
}
+
+
+static int
+stdio_buffer_shutdown (buf)
+ struct buffer *buf;
+{
+ struct stdio_buffer_closure *bc = (struct stdio_buffer_closure *) buf->closure;
+ struct stat s;
+ int closefp = 1;
+
+ /* Must be a pipe or a socket. What could go wrong? */
+ assert (fstat ( fileno (bc->fp), &s ) != -1);
+
+ /* Flush the buffer if we can */
+ if (buf->flush)
+ {
+ buf_flush (buf, 1);
+ buf->flush = NULL;
+ }
+
+ if (buf->input)
+ {
+ if (! buf_empty_p (buf)
+ || getc (bc->fp) != EOF)
+ {
+# ifdef SERVER_SUPPORT
+ if (server_active)
+ /* FIXME: This should probably be sysloged since it doesn't
+ * have anywhere else to go at this point.
+ */
+ error (0, 0, "dying gasps from client unexpected");
+ else
+#endif
+ error (0, 0, "dying gasps from %s unexpected", current_parsed_root->hostname);
+ }
+ else if (ferror (bc->fp))
+ {
+# ifdef SERVER_SUPPORT
+ if (server_active)
+ /* FIXME: This should probably be sysloged since it doesn't
+ * have anywhere else to go at this point.
+ */
+ error (0, errno, "reading from client");
+ else
+#endif
+ error (0, errno, "reading from %s", current_parsed_root->hostname);
+ }
+
+# ifdef SHUTDOWN_SERVER
+ if (current_parsed_root->method != server_method)
+# endif
+# ifndef NO_SOCKET_TO_FD
+ {
+ /* shutdown() sockets */
+ if (S_ISSOCK(s.st_mode))
+ shutdown ( fileno (bc->fp), 0);
+ }
+# endif /* NO_SOCKET_TO_FD */
+# ifdef START_RSH_WITH_POPEN_RW
+ /* Can't be set with SHUTDOWN_SERVER defined */
+ else if (pclose (bc->fp) == EOF)
+ {
+ error (1, errno, "closing connection to %s",
+ current_parsed_root->hostname);
+ closefp = 0;
+ }
+# endif /* START_RSH_WITH_POPEN_RW */
+
+ buf->input = NULL;
+ }
+ else if (buf->output)
+ {
+# ifdef SHUTDOWN_SERVER
+ /* FIXME: Should have a SHUTDOWN_SERVER_INPUT &
+ * SHUTDOWN_SERVER_OUTPUT
+ */
+ if (current_parsed_root->method == server_method)
+ SHUTDOWN_SERVER ( fileno (bc->fp) );
+ else
+# endif
+# ifndef NO_SOCKET_TO_FD
+ /* shutdown() sockets */
+ if (S_ISSOCK(s.st_mode))
+ shutdown ( fileno (bc->fp), 1);
+# else
+ {
+ /* I'm not sure I like this empty block, but the alternative
+ * is a another nested NO_SOCKET_TO_FD switch above.
+ */
+ }
+# endif /* NO_SOCKET_TO_FD */
+
+ buf->output = NULL;
+ }
+
+ if (closefp && fclose (bc->fp) == EOF)
+ error (1, errno,
+ "closing down connection to %s",
+ current_parsed_root->hostname);
+
+ /* If we were talking to a process, make sure it exited */
+ if (bc->child_pid
+ && waitpid (bc->child_pid, (int *) 0, 0) == -1)
+ error (1, errno, "waiting for process %d", bc->child_pid);
+
+ return 0;
+}
+
+
+
/* Certain types of communication input and output data in packets,
where each packet is translated in some fashion. The packetizing
buffer type supports that, given a buffer which handles lower level
@@ -1398,7 +1527,7 @@ static int packetizing_buffer_input PROTO((void *, char *, int, int, int *));
static int packetizing_buffer_output PROTO((void *, const char *, int, int *));
static int packetizing_buffer_flush PROTO((void *));
static int packetizing_buffer_block PROTO((void *, int));
-static int packetizing_buffer_shutdown PROTO((void *));
+static int packetizing_buffer_shutdown PROTO((struct buffer *));
/* Create a packetizing buffer. */
@@ -1763,10 +1892,10 @@ packetizing_buffer_block (closure, block)
/* Shut down a packetizing buffer. */
static int
-packetizing_buffer_shutdown (closure)
- void *closure;
+packetizing_buffer_shutdown (buf)
+ struct buffer *buf;
{
- struct packetizing_buffer *pb = (struct packetizing_buffer *) closure;
+ struct packetizing_buffer *pb = (struct packetizing_buffer *) buf->closure;
return buf_shutdown (pb->buf);
}
diff --git a/contrib/cvs/src/buffer.h b/contrib/cvs/src/buffer.h
index 0556781..ebf1b7a 100644
--- a/contrib/cvs/src/buffer.h
+++ b/contrib/cvs/src/buffer.h
@@ -61,7 +61,7 @@ struct buffer
appropriate should be done at this point. This may be NULL.
It should return 0 on success, or an errno code. This entry
point exists for the compression code. */
- int (*shutdown) PROTO((void *closure));
+ int (*shutdown) PROTO((struct buffer *));
/* This field is passed to the INPUT, OUTPUT, and BLOCK functions. */
void *closure;
@@ -105,13 +105,13 @@ extern struct buffer *buf_initialize PROTO((int (*) (void *, char *, int,
int, int *),
int (*) (void *),
int (*) (void *, int),
- int (*) (void *),
+ int (*) (struct buffer *),
void (*) (struct buffer *),
void *));
extern void buf_free PROTO((struct buffer *));
extern struct buffer *buf_nonio_initialize PROTO((void (*) (struct buffer *)));
extern struct buffer *stdio_buffer_initialize
- PROTO((FILE *, int, void (*) (struct buffer *)));
+ PROTO((FILE *, int, int, void (*) (struct buffer *)));
extern struct buffer *compress_buffer_initialize
PROTO((struct buffer *, int, int, void (*) (struct buffer *)));
extern struct buffer *packetizing_buffer_initialize
diff --git a/contrib/cvs/src/checkout.c b/contrib/cvs/src/checkout.c
index 86dc951..6b1f769 100644
--- a/contrib/cvs/src/checkout.c
+++ b/contrib/cvs/src/checkout.c
@@ -82,18 +82,18 @@ static const char *const export_usage[] =
};
static int checkout_prune_dirs;
-static int force_tag_match = 1;
+static int force_tag_match;
static int pipeout;
static int aflag;
-static char *options = NULL;
-static char *tag = NULL;
-static int tag_validated = 0;
-static char *date = NULL;
-static char *join_rev1 = NULL;
-static char *join_rev2 = NULL;
-static int join_tags_validated = 0;
-static char *preload_update_dir = NULL;
-static char *history_name = NULL;
+static char *options;
+static char *tag;
+static int tag_validated;
+static char *date;
+static char *join_rev1;
+static char *join_rev2;
+static int join_tags_validated;
+static char *preload_update_dir;
+static char *history_name;
static enum mtype m_type;
int
@@ -112,6 +112,18 @@ checkout (argc, argv)
char *valid_options;
const char *const *valid_usage;
+ /* initialize static options */
+ force_tag_match = 1;
+ if (options)
+ {
+ free (options);
+ options = NULL;
+ }
+ tag = date = join_rev1 = join_rev2 = preload_update_dir = NULL;
+ history_name = NULL;
+ tag_validated = join_tags_validated = 0;
+
+
/*
* A smaller subset of options are allowed for the export command, which
* is essentially like checkout, except that it hard-codes certain
@@ -248,7 +260,7 @@ checkout (argc, argv)
}
#endif
- if (!cat && !safe_location()) {
+ if (!cat && !pipeout && !safe_location( where )) {
error(1, 0, "Cannot check out files into the repository itself");
}
@@ -333,7 +345,10 @@ checkout (argc, argv)
{
cat_module (status);
if (options)
+ {
free (options);
+ options = NULL;
+ }
return (0);
}
db = open_module ();
@@ -351,17 +366,17 @@ checkout (argc, argv)
/* If we will be calling history_write, work out the name to pass
it. */
- if (m_type == CHECKOUT && !pipeout)
+ if (!pipeout)
{
- if (tag && date)
+ if (!date)
+ history_name = tag;
+ else if (!tag)
+ history_name = date;
+ else
{
history_name = xmalloc (strlen (tag) + strlen (date) + 2);
sprintf (history_name, "%s:%s", tag, date);
}
- else if (tag)
- history_name = tag;
- else
- history_name = date;
}
@@ -371,7 +386,12 @@ checkout (argc, argv)
(char *) NULL);
close_module (db);
if (options)
+ {
free (options);
+ options = NULL;
+ }
+ if (history_name != tag && history_name != date && history_name != NULL)
+ free (history_name);
return (err);
}
@@ -379,9 +399,11 @@ checkout (argc, argv)
reasons, probably want to move them. */
int
-safe_location ()
+safe_location (where)
+ char *where;
{
char *current;
+ char *where_location;
char hardpath[PATH_MAX+5];
size_t hardpath_len;
int x;
@@ -403,9 +425,68 @@ safe_location ()
{
hardpath[x] = '\0';
}
+
+ /* set current - even if where is set we'll need to cd back... */
current = xgetwd ();
if (current == NULL)
error (1, errno, "could not get working directory");
+
+ /* if where is set, set current to where, where - last_component( where ),
+ * or fail, depending on whether the directories exist or not.
+ */
+ if( where != NULL )
+ {
+ if( chdir( where ) != -1 )
+ {
+ /* where */
+ where_location = xgetwd();
+ if( where_location == NULL )
+ error( 1, errno, "could not get working directory" );
+
+ if( chdir( current ) == -1 )
+ error( 1, errno, "could not change directory to `%s'", current );
+
+ free( current );
+ current = where_location;
+ }
+ else if( errno == ENOENT )
+ {
+ if ( last_component( where ) != where )
+ {
+ /* where - last_component( where ) */
+ char *parent;
+
+ /* strip the last_component */
+ where_location = strdup( where );
+ parent = last_component( where_location );
+ parent[-1] = '\0';
+
+ if( chdir( where_location ) != -1 )
+ {
+ where_location = xgetwd();
+ if( where_location == NULL )
+ error( 1, errno, "could not get working directory (nominally `%s')", where_location );
+
+ if( chdir( current ) == -1 )
+ error( 1, errno, "could not change directory to `%s'", current );
+
+ free( current );
+ current = where_location;
+ }
+ else
+ /* fail */
+ error( 1, errno, "could not change directory to requested checkout directory `%s'", where_location );
+ }
+ /* else: ERRNO == ENOENT & last_component(where) == where
+ * for example, 'cvs co -d newdir module', where newdir hasn't
+ * been created yet, so leave current set to '.' and check that
+ */
+ }
+ else
+ /* fail */
+ error( 1, errno, "could not change directory to requested checkout directory `%s'", where );
+ }
+
hardpath_len = strlen (hardpath);
if (strlen (current) >= hardpath_len
&& strncmp (current, hardpath, hardpath_len) == 0)
@@ -851,7 +932,7 @@ internal error: %s doesn't start with %s in checkout_proc",
build_one_dir whenever the -d command option was specified
to checkout. */
- if (! where_is_absolute && top_level_admin)
+ if (! where_is_absolute && top_level_admin && m_type == CHECKOUT)
{
/* It may be argued that we shouldn't set any sticky
bits for the top-level repository. FIXME? */
@@ -998,12 +1079,9 @@ internal error: %s doesn't start with %s in checkout_proc",
*/
if (!(local_specified || argc > 1))
{
- if (m_type == CHECKOUT && !pipeout)
- history_write ('O', preload_update_dir, history_name, where,
- repository);
- else if (m_type == EXPORT && !pipeout)
- history_write ('E', preload_update_dir, tag ? tag : date, where,
- repository);
+ if (!pipeout)
+ history_write (m_type == CHECKOUT ? 'O' : 'E', preload_update_dir,
+ history_name, where, repository);
err += do_update (0, (char **) NULL, options, tag, date,
force_tag_match, 0 /* !local */ ,
1 /* update -d */ , aflag, checkout_prune_dirs,
diff --git a/contrib/cvs/src/client.c b/contrib/cvs/src/client.c
index 184cf96..4773b4f 100644
--- a/contrib/cvs/src/client.c
+++ b/contrib/cvs/src/client.c
@@ -13,7 +13,7 @@
GNU General Public License for more details. */
#ifdef HAVE_CONFIG_H
-#include "config.h"
+# include "config.h"
#endif /* HAVE_CONFIG_H */
#include <assert.h>
@@ -24,68 +24,67 @@
#ifdef CLIENT_SUPPORT
-#include "md5.h"
-
-#if defined(AUTH_CLIENT_SUPPORT) || HAVE_KERBEROS || defined(SOCK_ERRNO) || defined(SOCK_STRERROR)
-# ifdef HAVE_WINSOCK_H
-# include <winsock.h>
-# else /* No winsock.h */
-# include <sys/socket.h>
-# include <netinet/in.h>
-# include <arpa/inet.h>
-# include <netdb.h>
-# endif /* No winsock.h */
-#endif
+# include "md5.h"
+
+# if defined(AUTH_CLIENT_SUPPORT) || HAVE_KERBEROS || defined(SOCK_ERRNO) || defined(SOCK_STRERROR)
+# ifdef HAVE_WINSOCK_H
+# include <winsock.h>
+# else /* No winsock.h */
+# include <sys/socket.h>
+# include <netinet/in.h>
+# include <arpa/inet.h>
+# include <netdb.h>
+# endif /* No winsock.h */
+# endif
/* If SOCK_ERRNO is defined, then send()/recv() and other socket calls
do not set errno, but that this macro should be used to obtain an
error code. This probably doesn't make sense unless
NO_SOCKET_TO_FD is also defined. */
-#ifndef SOCK_ERRNO
-#define SOCK_ERRNO errno
-#endif
+# ifndef SOCK_ERRNO
+# define SOCK_ERRNO errno
+# endif
/* If SOCK_STRERROR is defined, then the error codes returned by
socket operations are not known to strerror, and this macro must be
used instead to convert those error codes to strings. */
-#ifndef SOCK_STRERROR
-# define SOCK_STRERROR strerror
+# ifndef SOCK_STRERROR
+# define SOCK_STRERROR strerror
-# if STDC_HEADERS
-# include <string.h>
-# endif
+# if STDC_HEADERS
+# include <string.h>
+# endif
-# ifndef strerror
+# ifndef strerror
extern char *strerror ();
-# endif
-#endif /* ! SOCK_STRERROR */
+# endif
+# endif /* ! SOCK_STRERROR */
-#if HAVE_KERBEROS
-#define CVS_PORT 1999
+# if HAVE_KERBEROS
-#include <krb.h>
+# include <krb.h>
extern char *krb_realmofhost ();
-#ifndef HAVE_KRB_GET_ERR_TEXT
-#define krb_get_err_text(status) krb_err_txt[status]
-#endif /* HAVE_KRB_GET_ERR_TEXT */
+# ifndef HAVE_KRB_GET_ERR_TEXT
+# define krb_get_err_text(status) krb_err_txt[status]
+# endif /* HAVE_KRB_GET_ERR_TEXT */
/* Information we need if we are going to use Kerberos encryption. */
static C_Block kblock;
static Key_schedule sched;
-#endif /* HAVE_KERBEROS */
+# endif /* HAVE_KERBEROS */
-#ifdef HAVE_GSSAPI
+# ifdef HAVE_GSSAPI
-# include "xgssapi.h"
+# include "xgssapi.h"
/* This is needed for GSSAPI encryption. */
static gss_ctx_id_t gcontext;
-static int connect_to_gserver PROTO((int, struct hostent *));
+static int connect_to_gserver PROTO((cvsroot_t *, int, struct hostent *));
-#endif /* HAVE_GSSAPI */
+# endif /* HAVE_GSSAPI */
static void add_prune_candidate PROTO((char *));
@@ -134,9 +133,9 @@ static void handle_f PROTO((char *, int));
static void handle_notified PROTO((char *, int));
static size_t try_read_from_server PROTO ((char *, size_t));
-#endif /* CLIENT_SUPPORT */
-
-#ifdef CLIENT_SUPPORT
+
+static void auth_server PROTO ((cvsroot_t *, struct buffer *, struct buffer *,
+ int, int, struct hostent *));
/* We need to keep track of the list of directories we've sent to the
server. This list, along with the current CVSROOT, will help us
@@ -267,8 +266,11 @@ arg_should_not_be_sent_to_server (arg)
}
+
#endif /* CLIENT_SUPPORT */
-
+
+
+
#if defined(CLIENT_SUPPORT) || defined(SERVER_SUPPORT)
/* Shared with server. */
@@ -438,16 +440,9 @@ static List *ignlist = (List *) NULL;
/* Buffer to write to the server. */
static struct buffer *to_server;
-/* The stream underlying to_server, if we are using a stream. */
-static FILE *to_server_fp;
/* Buffer used to read from the server. */
static struct buffer *from_server;
-/* The stream underlying from_server, if we are using a stream. */
-static FILE *from_server_fp;
-
-/* Process ID of rsh subprocess. */
-static int rsh_pid = -1;
/* We want to be able to log data sent between us and the server. We
@@ -470,7 +465,7 @@ static int log_buffer_input PROTO((void *, char *, int, int, int *));
static int log_buffer_output PROTO((void *, const char *, int, int *));
static int log_buffer_flush PROTO((void *));
static int log_buffer_block PROTO((void *, int));
-static int log_buffer_shutdown PROTO((void *));
+static int log_buffer_shutdown PROTO((struct buffer *));
/* Create a log buffer. */
@@ -594,10 +589,10 @@ log_buffer_block (closure, block)
/* The shutdown function for a log buffer. */
static int
-log_buffer_shutdown (closure)
- void *closure;
+log_buffer_shutdown (buf)
+ struct buffer *buf;
{
- struct log_buffer *lb = (struct log_buffer *) closure;
+ struct log_buffer *lb = (struct log_buffer *) buf->closure;
int retval;
retval = buf_shutdown (lb->buf);
@@ -605,7 +600,7 @@ log_buffer_shutdown (closure)
error (0, errno, "closing log file");
return retval;
}
-
+
#ifdef NO_SOCKET_TO_FD
/* Under certain circumstances, we must communicate with the server
@@ -618,9 +613,6 @@ log_buffer_shutdown (closure)
in these cases. This is handled through the SOCK_ERRNO and
SOCK_STRERROR macros. */
-static int use_socket_style = 0;
-static int server_sock;
-
/* These routines implement a buffer structure which uses send and
recv. The buffer is always in blocking mode so we don't implement
the block routine. */
@@ -644,14 +636,17 @@ static struct buffer *socket_buffer_initialize
static int socket_buffer_input PROTO((void *, char *, int, int, int *));
static int socket_buffer_output PROTO((void *, const char *, int, int *));
static int socket_buffer_flush PROTO((void *));
+static int socket_buffer_shutdown PROTO((struct buffer *));
+
+
/* Create a buffer based on a socket. */
static struct buffer *
socket_buffer_initialize (socket, input, memory)
- int socket;
- int input;
- void (*memory) PROTO((struct buffer *));
+ int socket;
+ int input;
+ void (*memory) PROTO((struct buffer *));
{
struct socket_buffer *n;
@@ -661,11 +656,13 @@ socket_buffer_initialize (socket, input, memory)
input ? NULL : socket_buffer_output,
input ? NULL : socket_buffer_flush,
(int (*) PROTO((void *, int))) NULL,
- (int (*) PROTO((void *))) NULL,
+ socket_buffer_shutdown,
memory,
n);
}
+
+
/* The buffer input function for a buffer built on a socket. */
static int
@@ -725,6 +722,8 @@ socket_buffer_input (closure, data, need, size, got)
return 0;
}
+
+
/* The buffer output function for a buffer built on a socket. */
static int
@@ -764,6 +763,8 @@ socket_buffer_output (closure, data, have, wrote)
return 0;
}
+
+
/* The buffer flush function for a buffer built on a socket. */
/*ARGSUSED*/
@@ -775,8 +776,61 @@ socket_buffer_flush (closure)
return 0;
}
+
+
+static int
+socket_buffer_shutdown (buf)
+ struct buffer *buf;
+{
+ struct socket_buffer *n = (struct socket_buffer *) buf->closure;
+ char tmp;
+
+ /* no need to flush children of an endpoint buffer here */
+
+ if (buf->input)
+ {
+ int err = 0;
+ if (! buf_empty_p (buf)
+ || (err = recv (n->socket, &tmp, 1, 0)) > 0)
+ error (0, 0, "dying gasps from %s unexpected", current_parsed_root->hostname);
+ else if (err == -1)
+ error (0, 0, "reading from %s: %s", current_parsed_root->hostname, SOCK_STRERROR (SOCK_ERRNO));
+
+ /* shutdown() socket */
+# ifdef SHUTDOWN_SERVER
+ if (current_parsed_root->method != server_method)
+# endif
+ if (shutdown (n->socket, 0) < 0)
+ {
+ error (1, 0, "shutting down server socket: %s", SOCK_STRERROR (SOCK_ERRNO));
+ }
+
+ buf->input = NULL;
+ }
+ else if (buf->output)
+ {
+ /* shutdown() socket */
+# ifdef SHUTDOWN_SERVER
+ /* FIXME: Should have a SHUTDOWN_SERVER_INPUT &
+ * SHUTDOWN_SERVER_OUTPUT
+ */
+ if (current_parsed_root->method == server_method)
+ SHUTDOWN_SERVER (n->socket);
+ else
+# endif
+ if (shutdown (n->socket, 1) < 0)
+ {
+ error (1, 0, "shutting down server socket: %s", SOCK_STRERROR (SOCK_ERRNO));
+ }
+
+ buf->output = NULL;
+ }
+
+ return 0;
+}
+
#endif /* NO_SOCKET_TO_FD */
-
+
/*
* Read a line from the server. Result does not include the terminating \n.
*
@@ -3519,7 +3573,6 @@ get_server_responses ()
}
/* Get the responses and then close the connection. */
-int server_fd = -1;
/*
* Flag var; we'll set it in start_server() and not one of its
@@ -3548,79 +3601,18 @@ get_responses_and_close ()
if (client_prune_dirs)
process_prune_candidates ();
- /* The calls to buf_shutdown are currently only meaningful when we
- are using compression. First we shut down TO_SERVER. That
- tells the server that its input is finished. It then shuts
- down the buffer it is sending to us, at which point our shut
- down of FROM_SERVER will complete. */
+ /* First we shut down TO_SERVER. That tells the server that its input is
+ * finished. It then shuts down the buffer it is sending to us, at which
+ * point our shut down of FROM_SERVER will complete.
+ */
status = buf_shutdown (to_server);
if (status != 0)
- error (0, status, "shutting down buffer to server");
+ error (0, status, "shutting down buffer to server");
status = buf_shutdown (from_server);
if (status != 0)
error (0, status, "shutting down buffer from server");
-#ifdef NO_SOCKET_TO_FD
- if (use_socket_style)
- {
- if (shutdown (server_sock, 2) < 0)
- error (1, 0, "shutting down server socket: %s", SOCK_STRERROR (SOCK_ERRNO));
- }
- else
-#endif /* NO_SOCKET_TO_FD */
- {
-#if defined(HAVE_KERBEROS) || defined(AUTH_CLIENT_SUPPORT)
- if (server_fd != -1)
- {
- if (shutdown (server_fd, 1) < 0)
- error (1, 0, "shutting down connection to %s: %s",
- current_parsed_root->hostname, SOCK_STRERROR (SOCK_ERRNO));
- server_fd = -1;
- /*
- * This test will always be true because we dup the descriptor
- */
- if (fileno (from_server_fp) != fileno (to_server_fp))
- {
- if (fclose (to_server_fp) != 0)
- error (1, errno,
- "closing down connection to %s",
- current_parsed_root->hostname);
- }
- }
- else
-#endif
-
-#ifdef SHUTDOWN_SERVER
- SHUTDOWN_SERVER (fileno (to_server_fp));
-#else /* ! SHUTDOWN_SERVER */
- {
-
-#ifdef START_RSH_WITH_POPEN_RW
- if (pclose (to_server_fp) == EOF)
-#else /* ! START_RSH_WITH_POPEN_RW */
- if (fclose (to_server_fp) == EOF)
-#endif /* START_RSH_WITH_POPEN_RW */
- {
- error (1, errno, "closing connection to %s",
- current_parsed_root->hostname);
- }
- }
-
- if (! buf_empty_p (from_server)
- || getc (from_server_fp) != EOF)
- error (0, 0, "dying gasps from %s unexpected", current_parsed_root->hostname);
- else if (ferror (from_server_fp))
- error (0, errno, "reading from %s", current_parsed_root->hostname);
-
- fclose (from_server_fp);
-#endif /* SHUTDOWN_SERVER */
- }
-
- if (rsh_pid != -1
- && waitpid (rsh_pid, (int *) 0, 0) == -1)
- error (1, errno, "waiting for process %d", rsh_pid);
-
buf_free (to_server);
buf_free (from_server);
server_started = 0;
@@ -3635,7 +3627,7 @@ get_responses_and_close ()
}
#ifndef NO_EXT_METHOD
-static void start_rsh_server PROTO((int *, int *));
+static void start_rsh_server PROTO((cvsroot_t *, struct buffer **, struct buffer **));
#endif
int
@@ -3758,68 +3750,82 @@ get_cvs_port_number (root)
method_names[root->method]);
break;
}
+ /* NOTREACHED */
+ return -1;
}
-/* Read a line from socket SOCK. Result does not include the
- terminating linefeed. This is only used by the authentication
- protocol, which we call before we set up all the buffering stuff.
- It is possible it should use the buffers too, which would be faster
- (unlike the server, there isn't really a security issue in terms of
- separating authentication from the rest of the code).
-
- Space for the result is malloc'd and should be freed by the caller.
-
- Returns number of bytes read. */
-static int
-recv_line (sock, resultp)
- int sock;
- char **resultp;
+void
+make_bufs_from_fds (tofd, fromfd, child_pid, to_server, from_server, is_sock)
+ int tofd;
+ int fromfd;
+ int child_pid;
+ struct buffer **to_server;
+ struct buffer **from_server;
+ int is_sock;
{
- char *result;
- size_t input_index = 0;
- size_t result_size = 80;
-
- result = (char *) xmalloc (result_size);
+ FILE *to_server_fp;
+ FILE *from_server_fp;
- while (1)
+#ifdef NO_SOCKET_TO_FD
+ if (is_sock)
{
- char ch;
- int n;
- n = recv (sock, &ch, 1, 0);
- if (n <= 0)
- error (1, 0, "recv() from server %s: %s", current_parsed_root->hostname,
- n == 0 ? "EOF" : SOCK_STRERROR (SOCK_ERRNO));
-
- if (ch == '\012')
- break;
+ assert (tofd == fromfd);
+ *to_server = socket_buffer_initialize (tofd, 0,
+ (BUFMEMERRPROC) NULL);
+ *from_server = socket_buffer_initialize (tofd, 1,
+ (BUFMEMERRPROC) NULL);
+ }
+ else
+#endif /* NO_SOCKET_TO_FD */
+ {
+ /* todo: some OS's don't need these calls... */
+ close_on_exec (tofd);
+ close_on_exec (fromfd);
- result[input_index++] = ch;
- while (input_index + 1 >= result_size)
+ /* SCO 3 and AIX have a nasty bug in the I/O libraries which precludes
+ fdopening the same file descriptor twice, so dup it if it is the
+ same. */
+ if (tofd == fromfd)
{
- result_size *= 2;
- result = (char *) xrealloc (result, result_size);
+ fromfd = dup (tofd);
+ if (fromfd < 0)
+ error (1, errno, "cannot dup net connection");
}
- }
- if (resultp)
- *resultp = result;
-
- /* Terminate it just for kicks, but we *can* deal with embedded NULs. */
- result[input_index] = '\0';
+ /* These will use binary mode on systems which have it. */
+ /*
+ * Also, we know that from_server is shut down second, so we pass
+ * child_pid in there. In theory, it should be stored in both
+ * buffers with a ref count...
+ */
+ to_server_fp = fdopen (tofd, FOPEN_BINARY_WRITE);
+ if (to_server_fp == NULL)
+ error (1, errno, "cannot fdopen %d for write", tofd);
+ *to_server = stdio_buffer_initialize (to_server_fp, 0, 0,
+ (BUFMEMERRPROC) NULL);
- if (resultp == NULL)
- free (result);
- return input_index;
+ from_server_fp = fdopen (fromfd, FOPEN_BINARY_READ);
+ if (from_server_fp == NULL)
+ error (1, errno, "cannot fdopen %d for read", fromfd);
+ *from_server = stdio_buffer_initialize (from_server_fp, child_pid, 1,
+ (BUFMEMERRPROC) NULL);
+ }
}
+
+
/* Connect to a forked server process. */
void
-connect_to_forked_server (tofdp, fromfdp)
- int *tofdp, *fromfdp;
+connect_to_forked_server (to_server, from_server)
+ struct buffer **to_server;
+ struct buffer **from_server;
{
+ int tofd, fromfd;
+ int child_pid;
+
/* This is pretty simple. All we need to do is choose the correct
cvs binary and call piped_child. */
@@ -3836,8 +3842,12 @@ connect_to_forked_server (tofdp, fromfdp)
{
fprintf (stderr, " -> Forking server: %s %s\n", command[0], command[1]);
}
- if (! piped_child (command, tofdp, fromfdp))
+
+ child_pid = piped_child (command, &tofd, &fromfd);
+ if (child_pid < 0)
error (1, 0, "could not fork server process");
+
+ make_bufs_from_fds (tofd, fromfd, child_pid, to_server, from_server, 0);
}
/* Connect to the authenticating server.
@@ -3853,51 +3863,113 @@ connect_to_forked_server (tofdp, fromfdp)
If we fail to connect or if access is denied, then die with fatal
error. */
void
-connect_to_pserver (tofdp, fromfdp, verify_only, do_gssapi)
- int *tofdp, *fromfdp;
- int verify_only;
- int do_gssapi;
+connect_to_pserver (root, to_server_p, from_server_p, verify_only, do_gssapi)
+ cvsroot_t *root;
+ struct buffer **to_server_p;
+ struct buffer **from_server_p;
+ int verify_only;
+ int do_gssapi;
{
int sock;
-#ifndef NO_SOCKET_TO_FD
- int tofd, fromfd;
-#endif
int port_number;
- char *username; /* the username we use to connect */
struct sockaddr_in client_sai;
struct hostent *hostinfo;
- char no_passwd = 0; /* gets set if no password found */
+ struct buffer *to_server, *from_server;
sock = socket (AF_INET, SOCK_STREAM, 0);
if (sock == -1)
{
error (1, 0, "cannot create socket: %s", SOCK_STRERROR (SOCK_ERRNO));
}
- port_number = get_cvs_port_number (current_parsed_root);
- hostinfo = init_sockaddr (&client_sai, current_parsed_root->hostname, port_number);
+ port_number = get_cvs_port_number (root);
+ hostinfo = init_sockaddr (&client_sai, root->hostname, port_number);
if (trace)
{
fprintf (stderr, " -> Connecting to %s(%s):%d\n",
- current_parsed_root->hostname,
+ root->hostname,
inet_ntoa (client_sai.sin_addr), port_number);
}
if (connect (sock, (struct sockaddr *) &client_sai, sizeof (client_sai))
< 0)
error (1, 0, "connect to %s(%s):%d failed: %s",
- current_parsed_root->hostname,
+ root->hostname,
inet_ntoa (client_sai.sin_addr),
port_number, SOCK_STRERROR (SOCK_ERRNO));
+ make_bufs_from_fds (sock, sock, 0, &to_server, &from_server, 1);
+
+ auth_server (root, to_server, from_server, verify_only, do_gssapi, hostinfo);
+
+ if (verify_only)
+ {
+ int status;
+
+ status = buf_shutdown (to_server);
+ if (status != 0)
+ error (0, status, "shutting down buffer to server");
+ status = buf_shutdown (from_server);
+ if (status != 0)
+ error (0, status, "shutting down buffer from server");
+
+ buf_free (to_server);
+ buf_free (from_server);
+
+ /* Don't need to set server_started = 0 since we don't set it to 1
+ * until returning from this call.
+ */
+ }
+ else
+ {
+ *to_server_p = to_server;
+ *from_server_p = from_server;
+ }
+
+ return;
+}
+
+
+
+static void
+auth_server (root, lto_server, lfrom_server, verify_only, do_gssapi, hostinfo)
+ cvsroot_t *root;
+ struct buffer *lto_server;
+ struct buffer *lfrom_server;
+ int verify_only;
+ int do_gssapi;
+ struct hostent *hostinfo;
+{
+ char *username; /* the username we use to connect */
+ char no_passwd = 0; /* gets set if no password found */
+
+ /* FIXME!!!!!!!!!!!!!!!!!!
+ *
+ * THIS IS REALLY UGLY!
+ *
+ * I'm setting the globals here so we can make calls to send_to_server &
+ * read_line. This happens again _after_ we return if we're not in
+ * verify_only mode. We should be relying on the values we passed in, but
+ * sent_to_server and read_line don't require an outside buf yet.
+ */
+ to_server = lto_server;
+ from_server = lfrom_server;
+
/* Run the authorization mini-protocol before anything else. */
if (do_gssapi)
{
#ifdef HAVE_GSSAPI
- if (! connect_to_gserver (sock, hostinfo))
+ int fd = (int) lto_server->closure;
+ struct stat s;
+
+ if (fstat (fd, &s) < 0 || !S_ISSOCK(s.st_mode))
{
- error (0, 0,
+ error (1, 0, "gserver currently only enabled for socket connections");
+ }
+
+ if (! connect_to_gserver (root, fd, hostinfo))
+ {
+ error (1, 0,
"authorization failed: server %s rejected access to %s",
- current_parsed_root->hostname, current_parsed_root->directory);
- goto rejected;
+ root->hostname, root->directory);
}
#else
error (1, 0, "This client does not support GSSAPI authentication");
@@ -3911,48 +3983,42 @@ connect_to_pserver (tofdp, fromfdp, verify_only, do_gssapi)
if (verify_only)
{
- begin = "BEGIN VERIFICATION REQUEST\012";
- end = "END VERIFICATION REQUEST\012";
+ begin = "BEGIN VERIFICATION REQUEST";
+ end = "END VERIFICATION REQUEST";
}
else
{
- begin = "BEGIN AUTH REQUEST\012";
- end = "END AUTH REQUEST\012";
+ begin = "BEGIN AUTH REQUEST";
+ end = "END AUTH REQUEST";
}
/* Get the password, probably from ~/.cvspass. */
password = get_cvs_password ();
- username = current_parsed_root->username ? current_parsed_root->username : getcaller();
+ username = root->username ? root->username : getcaller();
- /* Send the empty string by default. This is so anonymous CVS
- access doesn't require client to have done "cvs login". */
- if (password == NULL)
- {
- no_passwd = 1;
- password = scramble ("");
- }
+ /* Send the empty string by default. This is so anonymous CVS
+ access doesn't require client to have done "cvs login". */
+ if (password == NULL)
+ {
+ no_passwd = 1;
+ password = scramble ("");
+ }
/* Announce that we're starting the authorization protocol. */
- if (send (sock, begin, strlen (begin), 0) < 0)
- error (1, 0, "cannot send: %s", SOCK_STRERROR (SOCK_ERRNO));
+ send_to_server(begin, 0);
+ send_to_server("\012", 1);
/* Send the data the server needs. */
- if (send (sock, current_parsed_root->directory, strlen (current_parsed_root->directory), 0) < 0)
- error (1, 0, "cannot send: %s", SOCK_STRERROR (SOCK_ERRNO));
- if (send (sock, "\012", 1, 0) < 0)
- error (1, 0, "cannot send: %s", SOCK_STRERROR (SOCK_ERRNO));
- if (send (sock, username, strlen (username), 0) < 0)
- error (1, 0, "cannot send: %s", SOCK_STRERROR (SOCK_ERRNO));
- if (send (sock, "\012", 1, 0) < 0)
- error (1, 0, "cannot send: %s", SOCK_STRERROR (SOCK_ERRNO));
- if (send (sock, password, strlen (password), 0) < 0)
- error (1, 0, "cannot send: %s", SOCK_STRERROR (SOCK_ERRNO));
- if (send (sock, "\012", 1, 0) < 0)
- error (1, 0, "cannot send: %s", SOCK_STRERROR (SOCK_ERRNO));
+ send_to_server(root->directory, 0);
+ send_to_server("\012", 1);
+ send_to_server(username, 0);
+ send_to_server("\012", 1);
+ send_to_server(password, 0);
+ send_to_server("\012", 1);
/* Announce that we're ending the authorization protocol. */
- if (send (sock, end, strlen (end), 0) < 0)
- error (1, 0, "cannot send: %s", SOCK_STRERROR (SOCK_ERRNO));
+ send_to_server(end, 0);
+ send_to_server("\012", 1);
/* Paranoia. */
memset (password, 0, strlen (password));
@@ -3964,7 +4030,7 @@ connect_to_pserver (tofdp, fromfdp, verify_only, do_gssapi)
/* Loop, getting responses from the server. */
while (1)
{
- recv_line (sock, &read_buf);
+ read_line (&read_buf);
if (strcmp (read_buf, "I HATE YOU") == 0)
{
@@ -3976,12 +4042,12 @@ connect_to_pserver (tofdp, fromfdp, verify_only, do_gssapi)
* can return 1 and we will not receive "I LOVE YOU" from the server, barring
* broken connections and garbled messages, of course).
*
- * i.e. This is a pserver specific error message and shoiuld be since
+ * i.e. This is a pserver specific error message and should be since
* GSSAPI doesn't use username.
*/
error (0, 0,
"authorization failed: server %s rejected access to %s for user %s",
- current_parsed_root->hostname, current_parsed_root->directory, username);
+ root->hostname, root->directory, username);
/* Output a special error message if authentication was attempted
with no password -- the user should be made aware that they may
@@ -3991,7 +4057,7 @@ connect_to_pserver (tofdp, fromfdp, verify_only, do_gssapi)
error (0, 0,
"used empty password; try \"cvs login\" with a real password");
}
- goto rejected;
+ error_exit();
}
else if (strncmp (read_buf, "E ", 2) == 0)
{
@@ -4014,7 +4080,7 @@ connect_to_pserver (tofdp, fromfdp, verify_only, do_gssapi)
/* Now output the text. */
fprintf (stderr, "%s\n", p);
- goto rejected;
+ error_exit();
}
else if (strcmp (read_buf, "I LOVE YOU") == 0)
{
@@ -4023,62 +4089,13 @@ connect_to_pserver (tofdp, fromfdp, verify_only, do_gssapi)
}
else
{
- /* Unrecognized response from server. */
- if (shutdown (sock, 2) < 0)
- {
- error (0, 0,
- "unrecognized auth response from %s: %s",
- current_parsed_root->hostname, read_buf);
- error (1, 0,
- "shutdown() failed, server %s: %s",
- current_parsed_root->hostname,
- SOCK_STRERROR (SOCK_ERRNO));
- }
error (1, 0,
"unrecognized auth response from %s: %s",
- current_parsed_root->hostname, read_buf);
+ root->hostname, read_buf);
}
free (read_buf);
}
}
-
- if (verify_only)
- {
- if (shutdown (sock, 2) < 0)
- error (0, 0, "shutdown() failed, server %s: %s", current_parsed_root->hostname,
- SOCK_STRERROR (SOCK_ERRNO));
- return;
- }
- else
- {
-#ifdef NO_SOCKET_TO_FD
- use_socket_style = 1;
- server_sock = sock;
- /* Try to break mistaken callers: */
- *tofdp = 0;
- *fromfdp = 0;
-#else /* ! NO_SOCKET_TO_FD */
- server_fd = sock;
- close_on_exec (server_fd);
- tofd = fromfd = sock;
- /* Hand them back to the caller. */
- *tofdp = tofd;
- *fromfdp = fromfd;
-#endif /* NO_SOCKET_TO_FD */
- }
-
- return;
-
- rejected:
- if (shutdown (sock, 2) < 0)
- {
- error (0, 0,
- "shutdown() failed (server %s): %s",
- current_parsed_root->hostname,
- SOCK_STRERROR (SOCK_ERRNO));
- }
-
- error_exit();
}
#endif /* AUTH_CLIENT_SUPPORT */
@@ -4090,10 +4107,12 @@ connect_to_pserver (tofdp, fromfdp, verify_only, do_gssapi)
(i.e., systems on which sockets cannot be converted to file
descriptors). The first person to try building a kerberos client
on such a system (OS/2, Windows 95, and maybe others) will have to
- make take care of this. */
+ take care of this. */
void
-start_tcp_server (tofdp, fromfdp)
- int *tofdp, *fromfdp;
+start_tcp_server (root, to_server, from_server)
+ cvsroot_t *root;
+ struct buffer **to_server;
+ struct buffer **from_server;
{
int s;
const char *portenv;
@@ -4106,9 +4125,9 @@ start_tcp_server (tofdp, fromfdp)
if (s < 0)
error (1, 0, "cannot create socket: %s", SOCK_STRERROR (SOCK_ERRNO));
- port = get_cvs_port_number (current_parsed_root);
+ port = get_cvs_port_number (root);
- hp = init_sockaddr (&sin, current_parsed_root->hostname, port);
+ hp = init_sockaddr (&sin, root->hostname, port);
hname = xmalloc (strlen (hp->h_name) + 1);
strcpy (hname, hp->h_name);
@@ -4116,13 +4135,13 @@ start_tcp_server (tofdp, fromfdp)
if (trace)
{
fprintf (stderr, " -> Connecting to %s(%s):%d\n",
- current_parsed_root->hostname,
+ root->hostname,
inet_ntoa (sin.sin_addr), port);
}
if (connect (s, (struct sockaddr *) &sin, sizeof sin) < 0)
error (1, 0, "connect to %s(%s):%d failed: %s",
- current_parsed_root->hostname,
+ root->hostname,
inet_ntoa (sin.sin_addr),
port, SOCK_STRERROR (SOCK_ERRNO));
@@ -4151,14 +4170,12 @@ start_tcp_server (tofdp, fromfdp)
memcpy (kblock, cred.session, sizeof (C_Block));
}
- server_fd = s;
- close_on_exec (server_fd);
+ close_on_exec (s);
free (hname);
/* Give caller the values it wants. */
- *tofdp = s;
- *fromfdp = s;
+ make_bufs_from_fds (s, s, 0, to_server, from_server, 1);
}
#endif /* HAVE_KERBEROS */
@@ -4189,13 +4206,29 @@ recv_bytes (sock, buf, need)
/* Connect to the server using GSSAPI authentication. */
+/* FIXME
+ *
+ * This really needs to be rewritten to use a buffer and not a socket.
+ * This would enable gserver to work with the SSL code I'm about to commit
+ * since the SSL connection is going to look like a FIFO and not a socket.
+ *
+ * I think, basically, it will need to use buf_output and buf_read directly
+ * since I don't think there is a read_bytes function - only read_line.
+ *
+ * recv_bytes could then be removed too.
+ *
+ * Besides, I added some cruft to reenable the socket which shouldn't be
+ * there. This would also enable its removal.
+ */
+#define BUFSIZE 1024
static int
-connect_to_gserver (sock, hostinfo)
- int sock;
- struct hostent *hostinfo;
+connect_to_gserver (root, sock, hostinfo)
+ cvsroot_t *root;
+ int sock;
+ struct hostent *hostinfo;
{
char *str;
- char buf[1024];
+ char buf[BUFSIZE];
gss_buffer_desc *tok_in_ptr, tok_in, tok_out;
OM_uint32 stat_min, stat_maj;
gss_name_t server_name;
@@ -4205,6 +4238,8 @@ connect_to_gserver (sock, hostinfo)
if (send (sock, str, strlen (str), 0) < 0)
error (1, 0, "cannot send: %s", SOCK_STRERROR (SOCK_ERRNO));
+ if (strlen (hostinfo->h_name) > BUFSIZE - 5)
+ error (1, 0, "Internal error: hostname exceeds length of buffer");
sprintf (buf, "cvs@%s", hostinfo->h_name);
tok_in.length = strlen (buf);
tok_in.value = buf;
@@ -4274,11 +4309,11 @@ connect_to_gserver (sock, hostinfo)
got = recv (sock, buf + 2, sizeof buf - 2, 0);
if (got < 0)
error (1, 0, "recv() from server %s: %s",
- current_parsed_root->hostname, SOCK_STRERROR (SOCK_ERRNO));
+ root->hostname, SOCK_STRERROR (SOCK_ERRNO));
buf[got + 2] = '\0';
if (buf[got + 1] == '\n')
buf[got + 1] = '\0';
- error (1, 0, "error from server %s: %s", current_parsed_root->hostname,
+ error (1, 0, "error from server %s: %s", root->hostname,
buf);
}
@@ -4315,10 +4350,9 @@ send_variable_proc (node, closure)
void
start_server ()
{
- int tofd, fromfd, rootless;
+ int rootless;
char *log = getenv ("CVS_CLIENT_LOG");
-
/* Clear our static variables for this invocation. */
if (toplevel_repos != NULL)
free (toplevel_repos);
@@ -4335,22 +4369,23 @@ start_server ()
#ifdef AUTH_CLIENT_SUPPORT
case pserver_method:
- /* Toss the return value. It will die with error if anything
- goes wrong anyway. */
- connect_to_pserver (&tofd, &fromfd, 0, 0);
+ /* Toss the return value. It will die with an error message if
+ * anything goes wrong anyway.
+ */
+ connect_to_pserver (current_parsed_root, &to_server, &from_server, 0, 0);
break;
#endif
#if HAVE_KERBEROS
case kserver_method:
- start_tcp_server (&tofd, &fromfd);
+ start_tcp_server (current_parsed_root, &to_server, &from_server);
break;
#endif
#ifdef HAVE_GSSAPI
case gserver_method:
/* GSSAPI authentication is handled by the pserver. */
- connect_to_pserver (&tofd, &fromfd, 0, 1);
+ connect_to_pserver (current_parsed_root, &to_server, &from_server, 0, 1);
break;
#endif
@@ -4359,34 +4394,34 @@ start_server ()
error (0, 0, ":ext: method not supported by this port of CVS");
error (1, 0, "try :server: instead");
#else
- start_rsh_server (&tofd, &fromfd);
+ start_rsh_server (current_parsed_root, &to_server, &from_server);
#endif
break;
case server_method:
#if defined(START_SERVER)
+ {
+ int tofd, fromfd;
START_SERVER (&tofd, &fromfd, getcaller (),
current_parsed_root->username, current_parsed_root->hostname,
current_parsed_root->directory);
-# if defined (START_SERVER_RETURNS_SOCKET) && defined (NO_SOCKET_TO_FD)
- /* This is a system on which we can only write to a socket
- using send/recv. Therefore its START_SERVER needs to
- return a socket. */
- use_socket_style = 1;
- server_sock = tofd;
-# endif
-
+# ifdef START_SERVER_RETURNS_SOCKET
+ make_bufs_from_fds (tofd, fromfd, 0, &to_server, &from_server, 1);
+# else
+ make_bufs_from_fds (tofd, fromfd, 0, &to_server, &from_server, 0);
+# endif /* START_SERVER_RETURNS_SOCKET */
+ }
#else
/* FIXME: It should be possible to implement this portably,
like pserver, which would get rid of the duplicated code
in {vms,windows-NT,...}/startserver.c. */
- error (1, 0, "\
-the :server: access method is not supported by this port of CVS");
+ error (1, 0,
+"the :server: access method is not supported by this port of CVS");
#endif
break;
case fork_method:
- connect_to_forked_server (&tofd, &fromfd);
+ connect_to_forked_server (&to_server, &from_server);
break;
default:
@@ -4398,46 +4433,11 @@ the :server: access method is not supported by this port of CVS");
/* "Hi, I'm Darlene and I'll be your server tonight..." */
server_started = 1;
-#ifdef NO_SOCKET_TO_FD
- if (use_socket_style)
- {
- to_server = socket_buffer_initialize (server_sock, 0,
- (BUFMEMERRPROC) NULL);
- from_server = socket_buffer_initialize (server_sock, 1,
- (BUFMEMERRPROC) NULL);
- }
- else
-#endif /* NO_SOCKET_TO_FD */
- {
- /* todo: some OS's don't need these calls... */
- close_on_exec (tofd);
- close_on_exec (fromfd);
-
- /* SCO 3 and AIX have a nasty bug in the I/O libraries which precludes
- fdopening the same file descriptor twice, so dup it if it is the
- same. */
- if (tofd == fromfd)
- {
- fromfd = dup (tofd);
- if (fromfd < 0)
- error (1, errno, "cannot dup net connection");
- }
-
- /* These will use binary mode on systems which have it. */
- to_server_fp = fdopen (tofd, FOPEN_BINARY_WRITE);
- if (to_server_fp == NULL)
- error (1, errno, "cannot fdopen %d for write", tofd);
- to_server = stdio_buffer_initialize (to_server_fp, 0,
- (BUFMEMERRPROC) NULL);
-
- from_server_fp = fdopen (fromfd, FOPEN_BINARY_READ);
- if (from_server_fp == NULL)
- error (1, errno, "cannot fdopen %d for read", fromfd);
- from_server = stdio_buffer_initialize (from_server_fp, 1,
- (BUFMEMERRPROC) NULL);
- }
-
- /* Set up logfiles, if any. */
+ /* Set up logfiles, if any.
+ *
+ * We do this _after_ authentication on purpose. Wouldn't really like to
+ * worry about logging passwords...
+ */
if (log)
{
int len = strlen (log);
@@ -4763,7 +4763,7 @@ the :server: access method is not supported by this port of CVS");
implementing piped_child)... but I'm doing something else at the
moment, and wish to make only one change at a time. -Karl */
-#ifdef START_RSH_WITH_POPEN_RW
+# ifdef START_RSH_WITH_POPEN_RW
/* This is actually a crock -- it's OS/2-specific, for no one else
uses it. If I get time, I want to make piped_child and all the
@@ -4771,10 +4771,13 @@ the :server: access method is not supported by this port of CVS");
up and running, and that's most important. */
static void
-start_rsh_server (tofdp, fromfdp)
- int *tofdp, *fromfdp;
+start_rsh_server (root, to_server, from_server)
+ cvsroot_t *root;
+ struct buffer **to_server;
+ struct buffer **from_server;
{
int pipes[2];
+ int child_pid;
/* If you're working through firewalls, you can set the
CVS_RSH environment variable to a script which uses rsh to
@@ -4814,19 +4817,19 @@ start_rsh_server (tofdp, fromfdp)
/* The command line starts out with rsh. */
rsh_argv[i++] = cvs_rsh;
-#ifdef RSH_NEEDS_BINARY_FLAG
+# ifdef RSH_NEEDS_BINARY_FLAG
/* "-b" for binary, under OS/2. */
rsh_argv[i++] = "-b";
-#endif /* RSH_NEEDS_BINARY_FLAG */
+# endif /* RSH_NEEDS_BINARY_FLAG */
/* Then we strcat more things on the end one by one. */
- if (current_parsed_root->username != NULL)
+ if (root->username != NULL)
{
rsh_argv[i++] = "-l";
- rsh_argv[i++] = current_parsed_root->username;
+ rsh_argv[i++] = root->username;
}
- rsh_argv[i++] = current_parsed_root->hostname;
+ rsh_argv[i++] = root->hostname;
rsh_argv[i++] = cvs_server;
rsh_argv[i++] = "server";
@@ -4842,21 +4845,21 @@ start_rsh_server (tofdp, fromfdp)
}
/* Do the deed. */
- rsh_pid = popenRW (rsh_argv, pipes);
- if (rsh_pid < 0)
+ child_pid = popenRW (rsh_argv, pipes);
+ if (child_pid < 0)
error (1, errno, "cannot start server via rsh");
- /* Give caller the file descriptors. */
- *tofdp = pipes[0];
- *fromfdp = pipes[1];
+ /* Give caller the file descriptors in a form it can deal with. */
+ make_bufs_from_fds (pipes[0], pipes[1], child_pid, to_server, from_server, 0);
}
-#else /* ! START_RSH_WITH_POPEN_RW */
+# else /* ! START_RSH_WITH_POPEN_RW */
static void
-start_rsh_server (tofdp, fromfdp)
- int *tofdp;
- int *fromfdp;
+start_rsh_server (root, to_server, from_server)
+ cvsroot_t *root;
+ struct buffer **to_server;
+ struct buffer **from_server;
{
/* If you're working through firewalls, you can set the
CVS_RSH environment variable to a script which uses rsh to
@@ -4864,6 +4867,8 @@ start_rsh_server (tofdp, fromfdp)
char *cvs_rsh = getenv ("CVS_RSH");
char *cvs_server = getenv ("CVS_SERVER");
char *command;
+ int tofd, fromfd;
+ int child_pid;
if (!cvs_rsh)
cvs_rsh = "rsh";
@@ -4874,9 +4879,7 @@ start_rsh_server (tofdp, fromfdp)
affect most rsh servers at all, and will pacify some buggy
versions of rsh that grab switches out of the middle of the
command (they're calling the GNU getopt routines incorrectly). */
- command = xmalloc (strlen (cvs_server)
- + strlen (current_parsed_root->directory)
- + 50);
+ command = xmalloc (strlen (cvs_server) + 8);
/* If you are running a very old (Nov 3, 1994, before 1.5)
* version of the server, you need to make sure that your .bashrc
@@ -4889,15 +4892,15 @@ start_rsh_server (tofdp, fromfdp)
char **p = argv;
*p++ = cvs_rsh;
- *p++ = current_parsed_root->hostname;
+ *p++ = root->hostname;
/* If the login names differ between client and server
* pass it on to rsh.
*/
- if (current_parsed_root->username != NULL)
+ if (root->username != NULL)
{
*p++ = "-l";
- *p++ = current_parsed_root->username;
+ *p++ = root->username;
}
*p++ = command;
@@ -4912,19 +4915,21 @@ start_rsh_server (tofdp, fromfdp)
fprintf (stderr, "%s ", argv[i]);
putc ('\n', stderr);
}
- rsh_pid = piped_child (argv, tofdp, fromfdp);
+ child_pid = piped_child (argv, &tofd, &fromfd);
- if (rsh_pid < 0)
+ if (child_pid < 0)
error (1, errno, "cannot start server via rsh");
}
free (command);
+
+ make_bufs_from_fds (tofd, fromfd, child_pid, to_server, from_server, 0);
}
-#endif /* START_RSH_WITH_POPEN_RW */
+# endif /* START_RSH_WITH_POPEN_RW */
#endif /* NO_EXT_METHOD */
-
+
/* Send an argument STRING. */
void
diff --git a/contrib/cvs/src/client.h b/contrib/cvs/src/client.h
index b4d404a..d7f3392 100644
--- a/contrib/cvs/src/client.h
+++ b/contrib/cvs/src/client.h
@@ -15,32 +15,36 @@ extern int cvsencrypt;
/* Whether the connection should use per-packet authentication. */
extern int cvsauthenticate;
-#ifdef ENCRYPTION
+#ifdef __STDC__
+struct buffer;
+#endif
+
+# ifdef ENCRYPTION
-#ifdef HAVE_KERBEROS
+# ifdef HAVE_KERBEROS
/* We can't declare the arguments without including krb.h, and I don't
want to do that in every file. */
extern struct buffer *krb_encrypt_buffer_initialize ();
-#endif /* HAVE_KERBEROS */
+# endif /* HAVE_KERBEROS */
-#ifdef HAVE_GSSAPI
+# ifdef HAVE_GSSAPI
/* Set this to turn on GSSAPI encryption. */
extern int cvs_gssapi_encrypt;
-#endif /* HAVE_GSSAPI */
+# endif /* HAVE_GSSAPI */
-#endif /* ENCRYPTION */
+# endif /* ENCRYPTION */
-#ifdef HAVE_GSSAPI
+# ifdef HAVE_GSSAPI
/* We can't declare the arguments without including gssapi.h, and I
don't want to do that in every file. */
extern struct buffer *cvs_gssapi_wrap_buffer_initialize ();
-#endif /* HAVE_GSSAPI */
+# endif /* HAVE_GSSAPI */
#endif /* defined (CLIENT_SUPPORT) || defined (SERVER_SUPPORT) */
@@ -54,22 +58,30 @@ extern int server_started;
/* Is the -P option to checkout or update specified? */
extern int client_prune_dirs;
-#ifdef AUTH_CLIENT_SUPPORT
+# ifdef AUTH_CLIENT_SUPPORT
extern int use_authenticating_server;
-void connect_to_pserver PROTO ((int *tofdp, int* fromfdp, int verify_only,
- int do_gssapi));
-# ifndef CVS_AUTH_PORT
-# define CVS_AUTH_PORT 2401
-# endif /* CVS_AUTH_PORT */
-#endif /* AUTH_CLIENT_SUPPORT */
-
-#if defined (AUTH_SERVER_SUPPORT) || (defined (SERVER_SUPPORT) && defined (HAVE_GSSAPI))
+void connect_to_pserver PROTO ((cvsroot_t *,
+ struct buffer **,
+ struct buffer **,
+ int, int ));
+# ifndef CVS_AUTH_PORT
+# define CVS_AUTH_PORT 2401
+# endif /* CVS_AUTH_PORT */
+# endif /* AUTH_CLIENT_SUPPORT */
+
+# if HAVE_KERBEROS
+# ifndef CVS_PORT
+# define CVS_PORT 1999
+# endif
+# endif /* HAVE_KERBEROS */
+
+# if defined (AUTH_SERVER_SUPPORT) || (defined (SERVER_SUPPORT) && defined (HAVE_GSSAPI))
extern void pserver_authenticate_connection PROTO ((void));
-#endif
+# endif
-#if defined (SERVER_SUPPORT) && defined (HAVE_KERBEROS)
+# if defined (SERVER_SUPPORT) && defined (HAVE_KERBEROS)
extern void kserver_authenticate_connection PROTO ((void));
-#endif
+# endif
/* Talking to the server. */
void send_to_server PROTO((char *str, size_t len));
@@ -94,7 +106,7 @@ send_file_names PROTO((int argc, char **argv, unsigned int flags));
/* Flags for send_file_names. */
/* Expand wild cards? */
-#define SEND_EXPAND_WILD 1
+# define SEND_EXPAND_WILD 1
/*
* Send Repository, Modified and Entry. argc and argv contain only
@@ -106,10 +118,10 @@ send_files PROTO((int argc, char **argv, int local, int aflag,
unsigned int flags));
/* Flags for send_files. */
-#define SEND_BUILD_DIRS 1
-#define SEND_FORCE 2
-#define SEND_NO_CONTENTS 4
-#define BACKUP_MODIFIED_FILES 8
+# define SEND_BUILD_DIRS 1
+# define SEND_FORCE 2
+# define SEND_NO_CONTENTS 4
+# define BACKUP_MODIFIED_FILES 8
/* Send an argument to the remote server. */
void
diff --git a/contrib/cvs/src/commit.c b/contrib/cvs/src/commit.c
index 149da7c..ba5dc5c 100644
--- a/contrib/cvs/src/commit.c
+++ b/contrib/cvs/src/commit.c
@@ -351,9 +351,10 @@ commit (argc, argv)
struct passwd *pw;
if ((pw = (struct passwd *) getpwnam (getcaller ())) == NULL)
- error (1, 0, "you are unknown to this system");
+ error (1, 0, "your apparent username (%s) is unknown to this system",
+ getcaller ());
if (pw->pw_uid == (uid_t) 0)
- error (1, 0, "cannot commit files as 'root'");
+ error (1, 0, "'root' is not allowed to commit files");
}
#endif /* CVS_BADROOT */
@@ -495,11 +496,6 @@ commit (argc, argv)
if (use_editor)
do_editor (".", &saved_message, (char *)NULL, find_args.ulist);
- /* Run the user-defined script to verify/check information in
- *the log message
- */
- do_verify (saved_message, (char *)NULL);
-
/* We always send some sort of message, even if empty. */
/* FIXME: is that true? There seems to be some code in do_editor
which can leave the message NULL. */
@@ -1230,7 +1226,7 @@ commit_fileproc (callerdat, finfo)
if (use_editor)
do_editor (finfo->update_dir, &saved_message,
finfo->repository, ulist);
- do_verify (saved_message, finfo->repository);
+ do_verify (&saved_message, finfo->repository);
}
p = findnode (cilist, finfo->file);
@@ -1552,7 +1548,7 @@ commit_direntproc (callerdat, dir, repos, update_dir, entries)
got_message = 1;
if (use_editor)
do_editor (update_dir, &saved_message, real_repos, ulist);
- do_verify (saved_message, real_repos);
+ do_verify (&saved_message, real_repos);
free (real_repos);
return (R_PROCESS);
}
@@ -1575,7 +1571,7 @@ commit_dirleaveproc (callerdat, dir, err, update_dir, entries)
this being a confusing feature! */
if (err == 0 && write_dirtag != NULL)
{
- char *repos = Name_Repository (dir, update_dir);
+ char *repos = Name_Repository (NULL, update_dir);
WriteTag (NULL, write_dirtag, NULL, write_dirnonbranch,
update_dir, repos);
free (repos);
@@ -1809,7 +1805,7 @@ unlockrcs (rcs)
{
int retcode;
- if ((retcode = RCS_unlock (rcs, NULL, 0)) != 0)
+ if ((retcode = RCS_unlock (rcs, NULL, 1)) != 0)
error (retcode == -1 ? 1 : 0, retcode == -1 ? errno : 0,
"could not unlock %s", rcs->path);
else
diff --git a/contrib/cvs/src/cvs.h b/contrib/cvs/src/cvs.h
index b4e3fa1..70e8a95 100644
--- a/contrib/cvs/src/cvs.h
+++ b/contrib/cvs/src/cvs.h
@@ -81,8 +81,11 @@ extern int errno;
#include "system.h"
#include "hash.h"
+
+#include "root.h"
+
#if defined(SERVER_SUPPORT) || defined(CLIENT_SUPPORT)
-#include "client.h"
+# include "client.h"
#endif
#ifdef MY_NDBM
@@ -364,26 +367,7 @@ extern int use_editor;
extern int cvswrite;
extern mode_t cvsumask;
-/* Access method specified in CVSroot. */
-typedef enum {
- null_method, local_method, server_method, pserver_method, kserver_method, gserver_method,
- ext_method, fork_method
-} CVSmethod;
-extern char *method_names[]; /* change this in root.c if you change
- the enum above */
-
-typedef struct cvsroot_s {
- char *original; /* the complete source CVSroot string */
- CVSmethod method; /* one of the enum values above */
- char *username; /* the username or NULL if method == local */
- char *password; /* the username or NULL if method == local */
- char *hostname; /* the hostname or NULL if method == local */
- int port; /* the port or zero if method == local */
- char *directory; /* the directory name */
-#ifdef CLIENT_SUPPORT
- unsigned char isremote; /* nonzero if we are doing remote access */
-#endif /* CLIENT_SUPPORT */
-} cvsroot_t;
+
/* This global variable holds the global -d option. It is NULL if -d
was not used, which means that we must get the CVSroot information
@@ -396,7 +380,7 @@ extern List *root_directories;
extern cvsroot_t *current_parsed_root;
extern char *emptydir_name PROTO ((void));
-extern int safe_location PROTO ((void));
+extern int safe_location PROTO ((char *));
extern int trace; /* Show all commands */
extern int noexec; /* Don't modify disk anywhere */
@@ -404,6 +388,12 @@ extern int logoff; /* Don't write history entry */
extern int top_level_admin;
+
+#define LOGMSG_REREAD_NEVER 0 /* do_verify - never reread message */
+#define LOGMSG_REREAD_ALWAYS 1 /* do_verify - always reread message */
+#define LOGMSG_REREAD_STAT 2 /* do_verify - reread message if changed */
+extern int RereadLogAfterVerify;
+
#ifdef CLIENT_SUPPORT
extern List *dirs_sent_to_server; /* used to decide which "Argument
xxx" commands to send to each
@@ -475,7 +465,7 @@ char *time_stamp PROTO((char *file));
void *xmalloc PROTO((size_t bytes));
void *xrealloc PROTO((void *ptr, size_t bytes));
void expand_string PROTO ((char **, size_t *, size_t));
-void allocate_and_strcat PROTO ((char **, size_t *, const char *));
+void xrealloc_and_strcat PROTO ((char **, size_t *, const char *));
char *xstrdup PROTO((const char *str));
void strip_trailing_newlines PROTO((char *str));
int pathname_levels PROTO ((char *path));
@@ -589,7 +579,7 @@ void Update_Logfile PROTO((char *repository, char *xmessage, FILE * xlogfp,
void do_editor PROTO((char *dir, char **messagep,
char *repository, List * changes));
-void do_verify PROTO((char *message, char *repository));
+void do_verify PROTO((char **messagep, char *repository));
typedef int (*CALLBACKPROC) PROTO((int argc, char *argv[], char *where,
char *mwhere, char *mfile, int shorten, int local_specified,
diff --git a/contrib/cvs/src/diff.c b/contrib/cvs/src/diff.c
index 9732f5d..c3d0e83 100644
--- a/contrib/cvs/src/diff.c
+++ b/contrib/cvs/src/diff.c
@@ -61,24 +61,71 @@ static size_t opts_allocated = 1;
static int diff_errors;
static int empty_files = 0;
-/* FIXME: should be documenting all the options here. They don't
- perfectly match rcsdiff options (for example, we always support
- --ifdef and --context, but rcsdiff only does if diff does). */
static const char *const diff_usage[] =
{
- "Usage: %s %s [-lNR] [rcsdiff-options]\n",
+ "Usage: %s %s [-lR] [-k kopt] [format_options]\n",
" [[-r rev1 | -D date1] [-r rev2 | -D date2]] [files...] \n",
"\t-l\tLocal directory only, not recursive\n",
"\t-R\tProcess directories recursively.\n",
+ "\t-k kopt\tSpecify keyword expansion mode.\n",
"\t-D d1\tDiff revision for date against working file.\n",
"\t-D d2\tDiff rev1/date1 against date2.\n",
- "\t-N\tinclude diffs for added and removed files.\n",
"\t-r rev1\tDiff revision for rev1 against working file.\n",
"\t-r rev2\tDiff rev1/date1 against rev2.\n",
- "\t--ifdef=arg\tOutput diffs in ifdef format.\n",
- "(consult the documentation for your diff program for rcsdiff-options.\n",
- "The most popular is -c for context diffs but there are many more).\n",
- "(Specify the --help global option for a list of other help options)\n",
+ "\nformat_options:\n",
+ " -i --ignore-case Consider upper- and lower-case to be the same.\n",
+ " -w --ignore-all-space Ignore all white space.\n",
+ " -b --ignore-space-change Ignore changes in the amount of white space.\n",
+ " -B --ignore-blank-lines Ignore changes whose lines are all blank.\n",
+ " -I RE --ignore-matching-lines=RE Ignore changes whose lines all match RE.\n",
+ " --binary Read and write data in binary mode.\n",
+ " -a --text Treat all files as text.\n\n",
+ " -c -C NUM --context[=NUM] Output NUM (default 2) lines of copied context.\n",
+ " -u -U NUM --unified[=NUM] Output NUM (default 2) lines of unified context.\n",
+ " -NUM Use NUM context lines.\n",
+ " -L LABEL --label LABEL Use LABEL instead of file name.\n",
+ " -p --show-c-function Show which C function each change is in.\n",
+ " -F RE --show-function-line=RE Show the most recent line matching RE.\n",
+ " --brief Output only whether files differ.\n",
+ " -e --ed Output an ed script.\n",
+ " -f --forward-ed Output something like an ed script in forward order.\n",
+ " -n --rcs Output an RCS format diff.\n",
+ " -y --side-by-side Output in two columns.\n",
+ " -W NUM --width=NUM Output at most NUM (default 130) characters per line.\n",
+ " --left-column Output only the left column of common lines.\n",
+ " --suppress-common-lines Do not output common lines.\n",
+ " --ifdef=NAME Output merged file to show `#ifdef NAME' diffs.\n",
+ " --GTYPE-group-format=GFMT Similar, but format GTYPE input groups with GFMT.\n",
+ " --line-format=LFMT Similar, but format all input lines with LFMT.\n",
+ " --LTYPE-line-format=LFMT Similar, but format LTYPE input lines with LFMT.\n",
+ " LTYPE is `old', `new', or `unchanged'. GTYPE is LTYPE or `changed'.\n",
+ " GFMT may contain:\n",
+ " %%< lines from FILE1\n",
+ " %%> lines from FILE2\n",
+ " %%= lines common to FILE1 and FILE2\n",
+ " %%[-][WIDTH][.[PREC]]{doxX}LETTER printf-style spec for LETTER\n",
+ " LETTERs are as follows for new group, lower case for old group:\n",
+ " F first line number\n",
+ " L last line number\n",
+ " N number of lines = L-F+1\n",
+ " E F-1\n",
+ " M L+1\n",
+ " LFMT may contain:\n",
+ " %%L contents of line\n",
+ " %%l contents of line, excluding any trailing newline\n",
+ " %%[-][WIDTH][.[PREC]]{doxX}n printf-style spec for input line number\n",
+ " Either GFMT or LFMT may contain:\n",
+ " %%%% %%\n",
+ " %%c'C' the single character C\n",
+ " %%c'\\OOO' the character with octal code OOO\n\n",
+ " -t --expand-tabs Expand tabs to spaces in output.\n",
+ " -T --initial-tab Make tabs line up by prepending a tab.\n\n",
+ " -N --new-file Treat absent files as empty.\n",
+ " -s --report-identical-files Report when two files are the same.\n",
+ " --horizon-lines=NUM Keep NUM lines of the common prefix and suffix.\n",
+ " -d --minimal Try hard to find a smaller set of changes.\n",
+ " -H --speed-large-files Assume large files and many scattered small changes.\n",
+ "\n(Specify the --help global option for a list of other help options)\n",
NULL
};
@@ -86,19 +133,20 @@ static const char *const diff_usage[] =
removing the following entries, none of which seem relevant to use
with CVS:
--help
- --version
- --recursive
- --unidirectional-new-file
- --starting-file
- --exclude
- --exclude-from
+ --version (-v)
+ --recursive (-r)
+ --unidirectional-new-file (-P)
+ --starting-file (-S)
+ --exclude (-x)
+ --exclude-from (-X)
--sdiff-merge-assist
+ --paginate (-l) (doesn't work with library callbacks)
I changed the options which take optional arguments (--context and
--unified) to return a number rather than a letter, so that the
optional argument could be handled more easily. I changed the
- --paginate and --brief options to return a number, since -l and -q
- mean something else to cvs diff.
+ --brief and --ifdef options to return numbers, since -q and -D mean
+ something else to cvs diff.
The numbers 129- that appear in the fourth element of some entries
tell the big switch in `diff' how to process those options. -- Ian
@@ -125,7 +173,6 @@ static struct option const longopts[] =
{"ed", 0, 0, 'e'},
{"forward-ed", 0, 0, 'f'},
{"ignore-case", 0, 0, 'i'},
- {"paginate", 0, 0, 144},
{"rcs", 0, 0, 'n'},
{"show-c-function", 0, 0, 'p'},
@@ -224,19 +271,22 @@ diff (argc, argv)
optind = 0;
while ((c = getopt_long (argc, argv,
- "+abcdefhilnpstuwy0123456789BHNRTC:D:F:I:L:U:V:W:k:r:",
+ "+abcdefhilnpstuwy0123456789BHNRTC:D:F:I:L:U:W:k:r:",
longopts, &option_index)) != -1)
{
switch (c)
{
+ case 'y':
+ xrealloc_and_strcat (&opts, &opts_allocated, " --side-by-side");
+ break;
case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
case 'h': case 'i': case 'n': case 'p': case 's': case 't':
- case 'u': case 'w': case 'y':
+ case 'u': case 'w':
case '0': case '1': case '2': case '3': case '4': case '5':
case '6': case '7': case '8': case '9':
case 'B': case 'H': case 'T':
(void) sprintf (tmp, " -%c", (char) c);
- allocate_and_strcat (&opts, &opts_allocated, tmp);
+ xrealloc_and_strcat (&opts, &opts_allocated, tmp);
break;
case 'L':
if (have_rev1_label++)
@@ -246,31 +296,31 @@ diff (argc, argv)
break;
}
- allocate_and_strcat (&opts, &opts_allocated, " -L");
- allocate_and_strcat (&opts, &opts_allocated, optarg);
+ xrealloc_and_strcat (&opts, &opts_allocated, " -L");
+ xrealloc_and_strcat (&opts, &opts_allocated, optarg);
break;
- case 'C': case 'F': case 'I': case 'U': case 'V': case 'W':
+ case 'C': case 'F': case 'I': case 'U': case 'W':
(void) sprintf (tmp, " -%c", (char) c);
- allocate_and_strcat (&opts, &opts_allocated, tmp);
- allocate_and_strcat (&opts, &opts_allocated, optarg);
+ xrealloc_and_strcat (&opts, &opts_allocated, tmp);
+ xrealloc_and_strcat (&opts, &opts_allocated, optarg);
break;
case 131:
/* --ifdef. */
- allocate_and_strcat (&opts, &opts_allocated, " --ifdef=");
- allocate_and_strcat (&opts, &opts_allocated, optarg);
+ xrealloc_and_strcat (&opts, &opts_allocated, " --ifdef=");
+ xrealloc_and_strcat (&opts, &opts_allocated, optarg);
break;
case 129: case 130: case 132: case 133: case 134:
case 135: case 136: case 137: case 138: case 139: case 140:
- case 141: case 142: case 143: case 144: case 145: case 146:
- allocate_and_strcat (&opts, &opts_allocated, " --");
- allocate_and_strcat (&opts, &opts_allocated,
+ case 141: case 142: case 143: case 145: case 146:
+ xrealloc_and_strcat (&opts, &opts_allocated, " --");
+ xrealloc_and_strcat (&opts, &opts_allocated,
longopts[option_index].name);
if (longopts[option_index].has_arg == 1
|| (longopts[option_index].has_arg == 2
&& optarg != NULL))
{
- allocate_and_strcat (&opts, &opts_allocated, "=");
- allocate_and_strcat (&opts, &opts_allocated, optarg);
+ xrealloc_and_strcat (&opts, &opts_allocated, "=");
+ xrealloc_and_strcat (&opts, &opts_allocated, optarg);
}
break;
case 'R':
@@ -437,7 +487,7 @@ diff_fileproc (callerdat, finfo)
(vers->vn_rcs == NULL
? NULL
: RCS_branch_head (vers->srcfile, vers->vn_rcs));
- exists = head != NULL;
+ exists = head != NULL && !RCS_isdead(vers->srcfile, head);
if (head != NULL)
free (head);
}
@@ -447,7 +497,7 @@ diff_fileproc (callerdat, finfo)
xvers = Version_TS (finfo, NULL, diff_rev1, diff_date1,
1, 0);
- exists = xvers->vn_rcs != NULL;
+ exists = xvers->vn_rcs != NULL && !RCS_isdead(xvers->srcfile, xvers->vn_rcs);
freevers_ts (&xvers);
}
if (exists)
diff --git a/contrib/cvs/src/error.h b/contrib/cvs/src/error.h
index c7268ce..1c8471d 100644
--- a/contrib/cvs/src/error.h
+++ b/contrib/cvs/src/error.h
@@ -32,8 +32,9 @@
/* The __-protected variants of `format' and `printf' attributes
are accepted by gcc versions 2.6.4 (effectively 2.7) and later. */
# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7)
-# define __format__ format
-# define __printf__ printf
+# define __format__ format
+# define __printf__ printf
+# define __noreturn__ noreturn
# endif
#endif
@@ -46,7 +47,11 @@ void error ();
/* Exit due to an error. Similar to error (1, 0, "message"), but call
it in the case where the message has already been printed. */
-extern void error_exit PROTO ((void));
+#ifdef __STDC__
+void error_exit (void) __attribute__ ((__noreturn__));
+#else
+void error_exit ();
+#endif
/* If non-zero, error will use the CVS protocol to report error
messages. This will only be set in the CVS server parent process;
diff --git a/contrib/cvs/src/filesubr.c b/contrib/cvs/src/filesubr.c
index 28575a3..5b9c076 100644
--- a/contrib/cvs/src/filesubr.c
+++ b/contrib/cvs/src/filesubr.c
@@ -331,8 +331,7 @@ mkdir_if_needed (name)
{
if (mkdir (name, 0777) < 0)
{
- if (!(errno == EEXIST
- || (errno == EACCES && isdir (name))))
+ if (errno != EEXIST && !isdir (name))
error (1, errno, "cannot make directory %s", name);
return 1;
}
diff --git a/contrib/cvs/src/find_names.c b/contrib/cvs/src/find_names.c
index e34232e..751ac67 100644
--- a/contrib/cvs/src/find_names.c
+++ b/contrib/cvs/src/find_names.c
@@ -24,8 +24,6 @@ static int find_rcs PROTO((char *dir, List * list));
static int add_subdir_proc PROTO((Node *, void *));
static int register_subdir_proc PROTO((Node *, void *));
-static List *filelist;
-
/*
* add the key from entry on entries list to the files list
*/
@@ -37,6 +35,7 @@ add_entries_proc (node, closure)
{
Entnode *entnode;
Node *fnode;
+ List *filelist = (List *) closure;
entnode = (Entnode *) node->data;
if (entnode->type != ENT_FILE)
@@ -66,7 +65,7 @@ Find_Names (repository, which, aflag, optentries)
List *files;
/* make a list for the files */
- files = filelist = getlist ();
+ files = getlist ();
/* look at entries (if necessary) */
if (which & W_LOCAL)
@@ -76,7 +75,7 @@ Find_Names (repository, which, aflag, optentries)
if (entries != NULL)
{
/* walk the entries file adding elements to the files list */
- (void) walklist (entries, add_entries_proc, NULL);
+ (void) walklist (entries, add_entries_proc, files);
/* if our caller wanted the entries list, return it; else free it */
if (optentries != NULL)
diff --git a/contrib/cvs/src/history.c b/contrib/cvs/src/history.c
index 4979398..40b5e14 100644
--- a/contrib/cvs/src/history.c
+++ b/contrib/cvs/src/history.c
@@ -770,11 +770,8 @@ history_write (type, update_dir, revs, name, repository)
if (save_cwd (&cwd))
error_exit ();
- if ( CVS_CHDIR (pwdir) < 0)
- error (1, errno, "can't chdir(%s)", pwdir);
- homedir = xgetwd ();
- if (homedir == NULL)
- error (1, errno, "can't getwd in %s", pwdir);
+ if ( CVS_CHDIR (pwdir) < 0 || (homedir = xgetwd ()) == NULL)
+ homedir = pwdir;
if (restore_cwd (&cwd, NULL))
error_exit ();
@@ -786,7 +783,9 @@ history_write (type, update_dir, revs, name, repository)
PrCurDir += i; /* Point to '/' separator */
tilde = "~";
}
- free (homedir);
+
+ if (homedir != pwdir)
+ free (homedir);
}
}
}
diff --git a/contrib/cvs/src/import.c b/contrib/cvs/src/import.c
index 6bd6abd..4d8ddce 100644
--- a/contrib/cvs/src/import.c
+++ b/contrib/cvs/src/import.c
@@ -218,10 +218,14 @@ import (argc, argv)
if (use_editor)
{
- do_editor ((char *) NULL, &message, repository,
+ do_editor ((char *) NULL, &message,
+#ifdef CLIENT_SUPPORT
+ current_parsed_root->isremote ? (char *) NULL :
+#endif
+ repository,
(List *) NULL);
}
- do_verify (message, repository);
+ do_verify (&message, repository);
msglen = message == NULL ? 0 : strlen (message);
if (msglen == 0 || message[msglen - 1] != '\n')
{
@@ -278,7 +282,7 @@ import (argc, argv)
}
#endif
- if (!safe_location ())
+ if (!safe_location ( NULL ))
{
error (1, 0, "attempt to import the repository");
}
@@ -311,7 +315,6 @@ import (argc, argv)
if (!really_quiet)
{
char buf[20];
- char *buf2;
cvs_output_tagged ("+importmergecmd", NULL);
cvs_output_tagged ("newline", NULL);
@@ -331,12 +334,9 @@ import (argc, argv)
cvs_output_tagged ("text", CVSroot_cmdline);
}
cvs_output_tagged ("text", " checkout -j");
- buf2 = xmalloc (strlen (argv[1]) + 20);
- sprintf (buf2, "%s:yesterday", argv[1]);
- cvs_output_tagged ("mergetag1", buf2);
- free (buf2);
+ cvs_output_tagged ("mergetag1", "<prev_rel_tag>");
cvs_output_tagged ("text", " -j");
- cvs_output_tagged ("mergetag2", argv[1]);
+ cvs_output_tagged ("mergetag2", argv[2]);
cvs_output_tagged ("text", " ");
cvs_output_tagged ("repository", argv[0]);
cvs_output_tagged ("newline", NULL);
@@ -618,6 +618,7 @@ update_rcs_file (message, vfile, vtag, targc, targv, inattic)
Vers_TS *vers;
int letter;
char *tocvsPath;
+ char *expand;
struct file_info finfo;
memset (&finfo, 0, sizeof finfo);
@@ -647,7 +648,9 @@ update_rcs_file (message, vfile, vtag, targc, targv, inattic)
tocvsPath = wrap_tocvs_process_file (vfile);
/* FIXME: Why don't we pass tocvsPath to RCS_cmp_file if it is
not NULL? */
- different = RCS_cmp_file (vers->srcfile, vers->vn_rcs, "-ko", vfile);
+ expand = vers->srcfile->expand != NULL &&
+ vers->srcfile->expand[0] == 'b' ? "-kb" : "-ko";
+ different = RCS_cmp_file (vers->srcfile, vers->vn_rcs, expand, vfile);
if (tocvsPath)
if (unlink_file_dir (tocvsPath) < 0)
error (0, errno, "cannot remove %s", tocvsPath);
@@ -1151,7 +1154,7 @@ add_rcs_file (message, rcs, user, add_vhead, key_opt,
goto write_error;
}
- if (local_opt != NULL)
+ if (local_opt != NULL && strcmp (local_opt, "kv") != 0)
{
if (fprintf (fprcs, "expand @%s@;\012", local_opt) < 0)
{
diff --git a/contrib/cvs/src/lock.c b/contrib/cvs/src/lock.c
index c05b83e..088f206 100644
--- a/contrib/cvs/src/lock.c
+++ b/contrib/cvs/src/lock.c
@@ -291,6 +291,9 @@ Lock_Cleanup ()
/* FIXME-reentrancy: the workaround isn't reentrant. */
static int in_lock_cleanup = 0;
+ if (trace)
+ (void) fprintf (stderr, "%s-> Lock_Cleanup()\n", CLIENT_SERVER_STR);
+
if (in_lock_cleanup)
return;
in_lock_cleanup = 1;
@@ -396,6 +399,10 @@ Reader_Lock (xrepository)
FILE *fp;
char *tmp;
+ if (trace)
+ (void) fprintf (stderr, "%s-> Reader_Lock(%s)\n", CLIENT_SERVER_STR,
+ xrepository);
+
if (noexec)
return (0);
@@ -554,6 +561,10 @@ write_lock (lock)
FILE *fp;
char *tmp;
+ if (trace)
+ (void) fprintf (stderr, "%s-> write_lock(%s)\n",
+ CLIENT_SERVER_STR, lock->repository);
+
if (writelock == NULL)
{
writelock = xmalloc (strlen (hostname) + sizeof (CVSWFL) + 40);
diff --git a/contrib/cvs/src/log.c b/contrib/cvs/src/log.c
index 1930ae5..ad780bb 100644
--- a/contrib/cvs/src/log.c
+++ b/contrib/cvs/src/log.c
@@ -84,6 +84,9 @@ struct log_data
/* Nonzero if the -b option was seen, meaning that only revisions
on the default branch should be printed. */
int default_branch;
+ /* Nonzero if the -S option was seen, meaning that the header/name
+ should be suppressed if no revisions are selected. */
+ int sup_header;
/* If not NULL, the value given for the -r option, which lists
sets of revisions to be printed. */
struct option_revlist *revlist;
@@ -150,18 +153,20 @@ static const char *const log_usage[] =
"\t-h\tOnly print header.\n",
"\t-t\tOnly print header and descriptive text.\n",
"\t-N\tDo not list tags.\n",
+ "\t-S\tDo not print name/header if no revisions selected.\n",
"\t-b\tOnly list revisions on the default branch.\n",
- "\t-r[revisions]\tSpecify revision(s)s to list.\n",
+ "\t-r[revisions]\tA comma-separated list of revisions to print:\n",
"\t rev1:rev2 Between rev1 and rev2, including rev1 and rev2.\n",
- "\t rev1::rev2 Between rev1 and rev2, excluding rev1 and rev2.\n",
+ "\t rev1::rev2 Between rev1 and rev2, excluding rev1.\n",
"\t rev: rev and following revisions on the same branch.\n",
"\t rev:: After rev on the same branch.\n",
"\t :rev rev and previous revisions on the same branch.\n",
- "\t ::rev Before rev on the same branch.\n",
+ "\t ::rev rev and previous revisions on the same branch.\n",
"\t rev Just rev.\n",
"\t branch All revisions on the branch.\n",
"\t branch. The last revision on the branch.\n",
- "\t-d dates\tSpecify dates (D1<D2 for range, D for latest before).\n",
+ "\t-d dates\tA semicolon-separated list of dates\n",
+ "\t \t(D1<D2 for range, D for latest before).\n",
"\t-s states\tOnly list revisions with specified states.\n",
"\t-w[logins]\tOnly list revisions checked in by specified logins.\n",
"(Specify the --help global option for a list of other help options)\n",
@@ -228,7 +233,7 @@ cvslog (argc, argv)
prl = &log_data.revlist;
optind = 0;
- while ((c = getopt (argc, argv, "+bd:hlNRr::s:tw::")) != -1)
+ while ((c = getopt (argc, argv, "+bd:hlNSRr::s:tw::")) != -1)
{
switch (c)
{
@@ -247,6 +252,9 @@ cvslog (argc, argv)
case 'N':
log_data.notags = 1;
break;
+ case 'S':
+ log_data.sup_header = 1;
+ break;
case 'R':
log_data.nameonly = 1;
break;
@@ -336,6 +344,8 @@ cvslog (argc, argv)
send_arg("-l");
if (log_data.notags)
send_arg("-N");
+ if (log_data.sup_header)
+ send_arg("-S");
if (log_data.nameonly)
send_arg("-R");
if (log_data.long_header)
@@ -405,14 +415,14 @@ cvslog (argc, argv)
for (i = 0; i < argc; i++)
{
err += do_module (db, argv[i], MISC, "Logging", rlog_proc,
- (char *) NULL, 0, 0, 0, 0, (char *) NULL);
+ (char *) NULL, 0, local, 0, 0, (char *) NULL);
}
close_module (db);
}
else
{
err = rlog_proc (argc + 1, argv - 1, (char *) NULL,
- (char *) NULL, (char *) NULL, 0, 0, (char *) NULL,
+ (char *) NULL, (char *) NULL, 0, local, (char *) NULL,
(char *) NULL);
}
@@ -782,6 +792,7 @@ log_fileproc (callerdat, finfo)
{
struct log_data *log_data = (struct log_data *) callerdat;
Node *p;
+ int selrev = -1;
RCSNode *rcsfile;
char buf[50];
struct revlist *revlist;
@@ -811,6 +822,38 @@ log_fileproc (callerdat, finfo)
return (1);
}
+ if (log_data->sup_header || !log_data->nameonly)
+ {
+
+ /* We will need all the information in the RCS file. */
+ RCS_fully_parse (rcsfile);
+
+ /* Turn any symbolic revisions in the revision list into numeric
+ revisions. */
+ revlist = log_expand_revlist (rcsfile, log_data->revlist,
+ log_data->default_branch);
+ if (log_data->sup_header || (!log_data->header && !log_data->long_header))
+ {
+ log_data_and_rcs.log_data = log_data;
+ log_data_and_rcs.revlist = revlist;
+ log_data_and_rcs.rcs = rcsfile;
+
+ /* If any single dates were specified, we need to identify the
+ revisions they select. Each one selects the single
+ revision, which is otherwise selected, of that date or
+ earlier. The log_fix_singledate routine will fill in the
+ start date for each specific revision. */
+ if (log_data->singledatelist != NULL)
+ walklist (rcsfile->versions, log_fix_singledate,
+ (void *) &log_data_and_rcs);
+
+ selrev = walklist (rcsfile->versions, log_count_print,
+ (void *) &log_data_and_rcs);
+ if (log_data->sup_header && selrev == 0) return 0;
+ }
+
+ }
+
if (log_data->nameonly)
{
cvs_output (rcsfile->path, 0);
@@ -818,14 +861,6 @@ log_fileproc (callerdat, finfo)
return 0;
}
- /* We will need all the information in the RCS file. */
- RCS_fully_parse (rcsfile);
-
- /* Turn any symbolic revisions in the revision list into numeric
- revisions. */
- revlist = log_expand_revlist (rcsfile, log_data->revlist,
- log_data->default_branch);
-
/* The output here is intended to be exactly compatible with the
output of rlog. I'm not sure whether this code should be here
or in rcs.c; I put it here because it is specific to the log
@@ -907,25 +942,10 @@ log_fileproc (callerdat, finfo)
sprintf (buf, "%d", walklist (rcsfile->versions, log_count, NULL));
cvs_output (buf, 0);
- if (! log_data->header && ! log_data->long_header)
+ if (selrev >= 0)
{
cvs_output (";\tselected revisions: ", 0);
-
- log_data_and_rcs.log_data = log_data;
- log_data_and_rcs.revlist = revlist;
- log_data_and_rcs.rcs = rcsfile;
-
- /* If any single dates were specified, we need to identify the
- revisions they select. Each one selects the single
- revision, which is otherwise selected, of that date or
- earlier. The log_fix_singledate routine will fill in the
- start date for each specific revision. */
- if (log_data->singledatelist != NULL)
- walklist (rcsfile->versions, log_fix_singledate,
- (void *) &log_data_and_rcs);
-
- sprintf (buf, "%d", walklist (rcsfile->versions, log_count_print,
- (void *) &log_data_and_rcs));
+ sprintf (buf, "%d", selrev);
cvs_output (buf, 0);
}
@@ -1029,24 +1049,25 @@ log_expand_revlist (rcs, revlist, default_branch)
{
branch = RCS_whatbranch (rcs, r->first);
if (branch == NULL)
+ nr->first = NULL;
+ else
{
- error (0, 0, "warning: `%s' is not a branch in `%s'",
- r->first, rcs->path);
- free (nr);
- continue;
+ nr->first = RCS_getbranch (rcs, branch, 1);
+ free (branch);
}
- nr->first = RCS_getbranch (rcs, branch, 1);
- free (branch);
}
if (nr->first == NULL)
{
- error (0, 0, "warning: no revision `%s' in `%s'",
+ error (0, 0, "warning: no branch `%s' in `%s'",
r->first, rcs->path);
- free (nr);
- continue;
+ nr->last = NULL;
+ nr->fields = 0;
+ }
+ else
+ {
+ nr->last = xstrdup (nr->first);
+ nr->fields = numdots (nr->first) + 1;
}
- nr->last = xstrdup (nr->first);
- nr->fields = numdots (nr->first) + 1;
}
else
{
@@ -1062,12 +1083,11 @@ log_expand_revlist (rcs, revlist, default_branch)
{
error (0, 0, "warning: no revision `%s' in `%s'",
r->first, rcs->path);
- free (nr);
- continue;
}
}
- if (r->last == r->first)
+ if (r->last == r->first || (r->last != NULL && r->first != NULL &&
+ strcmp (r->last, r->first) == 0))
nr->last = xstrdup (nr->first);
else if (r->last == NULL || isdigit ((unsigned char) r->last[0]))
nr->last = xstrdup (r->last);
@@ -1081,10 +1101,6 @@ log_expand_revlist (rcs, revlist, default_branch)
{
error (0, 0, "warning: no revision `%s' in `%s'",
r->last, rcs->path);
- if (nr->first != NULL)
- free (nr->first);
- free (nr);
- continue;
}
}
@@ -1092,7 +1108,7 @@ log_expand_revlist (rcs, revlist, default_branch)
does. This code is a bit cryptic for my tastes, but
keeping the same implementation as rlog ensures a
certain degree of compatibility. */
- if (r->first == NULL)
+ if (r->first == NULL && nr->last != NULL)
{
nr->fields = numdots (nr->last) + 1;
if (nr->fields < 2)
@@ -1106,7 +1122,7 @@ log_expand_revlist (rcs, revlist, default_branch)
strcpy (cp, ".0");
}
}
- else if (r->last == NULL)
+ else if (r->last == NULL && nr->first != NULL)
{
nr->fields = numdots (nr->first) + 1;
nr->last = xstrdup (nr->first);
@@ -1120,7 +1136,7 @@ log_expand_revlist (rcs, revlist, default_branch)
*cp = '\0';
}
}
- else
+ else if (nr->first != NULL && nr->last != NULL)
{
nr->fields = numdots (nr->first) + 1;
if (nr->fields != numdots (nr->last) + 1
@@ -1132,11 +1148,12 @@ log_expand_revlist (rcs, revlist, default_branch)
"invalid branch or revision pair %s:%s in `%s'",
r->first, r->last, rcs->path);
free (nr->first);
+ nr->first = NULL;
free (nr->last);
- free (nr);
- continue;
+ nr->last = NULL;
+ nr->fields = 0;
}
- if (version_compare (nr->first, nr->last, nr->fields) > 0)
+ else if (version_compare (nr->first, nr->last, nr->fields) > 0)
{
char *tmp;
@@ -1145,6 +1162,8 @@ log_expand_revlist (rcs, revlist, default_branch)
nr->last = tmp;
}
}
+ else
+ nr->fields = 0;
}
nr->next = NULL;
@@ -1288,11 +1307,9 @@ log_version_requested (log_data, revlist, rcs, vnode)
for (r = revlist; r != NULL; r = r->next)
{
if (vfields == r->fields + (r->fields & 1) &&
- (r->inclusive ?
- version_compare (v, r->first, r->fields) >= 0
- && version_compare (v, r->last, r->fields) <= 0 :
- version_compare (v, r->first, r->fields) > 0
- && version_compare (v, r->last, r->fields) < 0))
+ (r->inclusive ? version_compare (v, r->first, r->fields) >= 0 :
+ version_compare (v, r->first, r->fields) > 0)
+ && version_compare (v, r->last, r->fields) <= 0)
{
return 1;
}
diff --git a/contrib/cvs/src/login.c b/contrib/cvs/src/login.c
index 9289737..b23d767 100644
--- a/contrib/cvs/src/login.c
+++ b/contrib/cvs/src/login.c
@@ -322,8 +322,8 @@ password_entry_operation (operation, root, newpassword)
fp = CVS_FOPEN (passfile, "r");
if (fp == NULL)
{
- error (0, errno, "failed to open %s for reading", passfile);
- goto error_exit;
+ error (0, errno, "warning: failed to open %s for reading", passfile);
+ goto process;
}
cvsroot_canonical = normalize_cvsroot (root);
@@ -361,6 +361,8 @@ password_entry_operation (operation, root, newpassword)
password = xstrdup (password);
}
+process:
+
/* might as well return now */
if (operation == password_entry_lookup)
goto out;
@@ -550,6 +552,12 @@ login (argc, argv)
{
char *tmp;
tmp = GETPASS ("CVS password: ");
+ /* Must deal with a NULL return value here. I haven't managed to
+ * disconnect the CVS process from the tty and force a NULL return
+ * in sanity.sh, but the Linux version of getpass is documented
+ * to return NULL when it can't open /dev/tty...
+ */
+ if (!tmp) error (1, errno, "login: Failed to read password.");
typed_password = scramble (tmp);
memset (tmp, 0, strlen (tmp));
}
@@ -560,7 +568,7 @@ login (argc, argv)
* will get zeroed by connect_to_server(). */
cvs_password = xstrdup (typed_password);
- connect_to_pserver (NULL, NULL, 1, 0);
+ connect_to_pserver (current_parsed_root, NULL, NULL, 1, 0);
password_entry_operation (password_entry_add, current_parsed_root, typed_password);
diff --git a/contrib/cvs/src/logmsg.c b/contrib/cvs/src/logmsg.c
index d2ef806..f9d47cd 100644
--- a/contrib/cvs/src/logmsg.c
+++ b/contrib/cvs/src/logmsg.c
@@ -6,6 +6,8 @@
* specified in the README file that comes with the CVS source distribution.
*/
+#include <assert.h>
+
#include "cvs.h"
#include "getline.h"
@@ -27,6 +29,15 @@ static char *editinfo_editor;
static char *verifymsg_script;
static Ctype type;
+/*
+ * Should the logmsg be re-read during the do_verify phase?
+ * RereadLogAfterVerify=no|stat|yes
+ * LOGMSG_REREAD_NEVER - never re-read the logmsg
+ * LOGMSG_REREAD_STAT - re-read the logmsg only if it has changed
+ * LOGMSG_REREAD_ALWAYS - always re-read the logmsg
+ */
+int RereadLogAfterVerify = LOGMSG_REREAD_ALWAYS;
+
/*
* Puts a standard header on the output which is either being prepared for an
* editor session, or being sent to a logfile program. The modified, added,
@@ -166,7 +177,8 @@ fmt_proc (p, closure)
* stripped and the log message is stored in the "message" argument.
*
* If REPOSITORY is non-NULL, process rcsinfo for that repository; if it
- * is NULL, use the CVSADM_TEMPLATE file instead.
+ * is NULL, use the CVSADM_TEMPLATE file instead. REPOSITORY should be
+ * NULL when running in client mode.
*/
void
do_editor (dir, messagep, repository, changes)
@@ -183,6 +195,9 @@ do_editor (dir, messagep, repository, changes)
struct stat pre_stbuf, post_stbuf;
int retcode = 0;
+ assert (current_parsed_root->isremote && !repository
+ || !current_parsed_root->isremote && repository);
+
if (noexec || reuse_log_message)
return;
@@ -305,7 +320,7 @@ do_editor (dir, messagep, repository, changes)
/* On NT, we might read less than st_size bytes, but we won't
read more. So this works. */
*messagep = (char *) xmalloc (post_stbuf.st_size + 1);
- *messagep[0] = '\0';
+ (*messagep)[0] = '\0';
}
line = NULL;
@@ -338,8 +353,14 @@ do_editor (dir, messagep, repository, changes)
if (pre_stbuf.st_mtime == post_stbuf.st_mtime ||
*messagep == NULL ||
+ (*messagep)[0] == '\0' ||
strcmp (*messagep, "\n") == 0)
{
+ if (*messagep)
+ {
+ free (*messagep);
+ *messagep = NULL;
+ }
for (;;)
{
(void) printf ("\nLog message unchanged or not specified\n");
@@ -387,14 +408,16 @@ do_editor (dir, messagep, repository, changes)
independant of the running of an editor for getting a message.
*/
void
-do_verify (message, repository)
- char *message;
+do_verify (messagep, repository)
+ char **messagep;
char *repository;
{
FILE *fp;
char *fname;
int retcode = 0;
+ struct stat pre_stbuf, post_stbuf;
+
#ifdef CLIENT_SUPPORT
if (current_parsed_root->isremote)
/* The verification will happen on the server. */
@@ -408,7 +431,7 @@ do_verify (message, repository)
/* If there's no message, then we have nothing to verify. Can this
case happen? And if so why would we print a message? */
- if (message == NULL)
+ if (*messagep == NULL)
{
cvs_output ("No message to verify\n", 0);
return;
@@ -419,46 +442,122 @@ do_verify (message, repository)
if ((fp = cvs_temp_file (&fname)) == NULL)
error (1, errno, "cannot create temporary file %s", fname);
- else
+
+ fprintf (fp, "%s", *messagep);
+ if ((*messagep)[0] == '\0' ||
+ (*messagep)[strlen (*messagep) - 1] != '\n')
+ (void) fprintf (fp, "%s", "\n");
+ if (fclose (fp) == EOF)
+ error (1, errno, "%s", fname);
+
+ if (RereadLogAfterVerify == LOGMSG_REREAD_STAT)
{
- fprintf (fp, "%s", message);
- if ((message)[0] == '\0' ||
- (message)[strlen (message) - 1] != '\n')
- (void) fprintf (fp, "%s", "\n");
- if (fclose (fp) == EOF)
- error (1, errno, "%s", fname);
+ /* Remember the status of the temp file for later */
+ if ( CVS_STAT (fname, &pre_stbuf) != 0 )
+ error (1, errno, "cannot stat temp file %s", fname);
+
+ /*
+ * See if we need to sleep before running the verification
+ * script to avoid time-stamp races.
+ */
+ sleep_past (pre_stbuf.st_mtime);
+ }
- /* Get the name of the verification script to run */
+ /* Get the name of the verification script to run */
- if (repository != NULL)
- (void) Parse_Info (CVSROOTADM_VERIFYMSG, repository,
- verifymsg_proc, 0);
+ if (repository != NULL)
+ (void) Parse_Info (CVSROOTADM_VERIFYMSG, repository,
+ verifymsg_proc, 0);
- /* Run the verification script */
+ /* Run the verification script */
- if (verifymsg_script)
+ if (verifymsg_script)
+ {
+ run_setup (verifymsg_script);
+ run_arg (fname);
+ if ((retcode = run_exec (RUN_TTY, RUN_TTY, RUN_TTY,
+ RUN_NORMAL | RUN_SIGIGNORE)) != 0)
{
- run_setup (verifymsg_script);
- run_arg (fname);
- if ((retcode = run_exec (RUN_TTY, RUN_TTY, RUN_TTY,
- RUN_NORMAL | RUN_SIGIGNORE)) != 0)
- {
- /* Since following error() exits, delete the temp file
- now. */
- if (unlink_file (fname) < 0)
- error (0, errno, "cannot remove %s", fname);
+ /* Since following error() exits, delete the temp file now. */
+ if (unlink_file (fname) < 0)
+ error (0, errno, "cannot remove %s", fname);
- error (1, retcode == -1 ? errno : 0,
- "Message verification failed");
- }
+ error (1, retcode == -1 ? errno : 0,
+ "Message verification failed");
+ }
+ }
+
+ /* Get the mod time and size of the possibly new log message
+ * in always and stat modes.
+ */
+ if (RereadLogAfterVerify == LOGMSG_REREAD_ALWAYS ||
+ RereadLogAfterVerify == LOGMSG_REREAD_STAT)
+ {
+ if ( CVS_STAT (fname, &post_stbuf) != 0 )
+ error (1, errno, "cannot find size of temp file %s", fname);
+ }
+
+ /* And reread the log message in `always' mode or in `stat' mode when it's
+ * changed
+ */
+ if (RereadLogAfterVerify == LOGMSG_REREAD_ALWAYS ||
+ (RereadLogAfterVerify == LOGMSG_REREAD_STAT &&
+ (pre_stbuf.st_mtime != post_stbuf.st_mtime ||
+ pre_stbuf.st_size != post_stbuf.st_size)))
+ {
+ /* put the entire message back into the *messagep variable */
+ if ( (fp = open_file (fname, "r")) == NULL )
+ error (1, errno, "cannot open temporary file %s", fname);
+
+ if (*messagep) free (*messagep);
+
+ if (post_stbuf.st_size == 0)
+ *messagep = NULL;
+ else
+ {
+ /* On NT, we might read less than st_size bytes,
+ but we won't read more. So this works. */
+ *messagep = (char *) xmalloc (post_stbuf.st_size + 1);
+ *messagep[0] = '\0';
}
- /* Delete the temp file */
+ if (*messagep)
+ {
+ char *line = NULL;
+ int line_length;
+ size_t line_chars_allocated = 0;
+ char *p = *messagep;
- if (unlink_file (fname) < 0)
- error (0, errno, "cannot remove %s", fname);
- free (fname);
+ while (1)
+ {
+ line_length = getline (&line,
+ &line_chars_allocated,
+ fp);
+ if (line_length == -1)
+ {
+ if (ferror (fp))
+ /* Fail in this case because otherwise we will have no
+ * log message
+ */
+ error (1, errno, "cannot read %s", fname);
+ break;
+ }
+ if (strncmp (line, CVSEDITPREFIX, CVSEDITPREFIXLEN) == 0)
+ continue;
+ (void) strcpy (p, line);
+ p += line_length;
+ }
+ if (line) free (line);
+ }
+ if (fclose (fp) < 0)
+ error (0, errno, "warning: cannot close %s", fname);
}
+
+ /* Delete the temp file */
+
+ if (unlink_file (fname) < 0)
+ error (0, errno, "cannot remove %s", fname);
+ free (fname);
}
/*
diff --git a/contrib/cvs/src/main.c b/contrib/cvs/src/main.c
index 3a21916..6d7be2f 100644
--- a/contrib/cvs/src/main.c
+++ b/contrib/cvs/src/main.c
@@ -152,7 +152,7 @@ static const char *const usg[] =
putting metavariables in uppercase. I don't know whether that
is a good convention or not, but if it changes it would have to
change in all the usage messages. For now, they consistently
- use lowercase, as far as I know. Puncutation is pretty funky,
+ use lowercase, as far as I know. Punctuation is pretty funky,
though. Sometimes they use none, as here. Sometimes they use
single quotes (not the TeX-ish `' stuff), as in --help-options.
Sometimes they use double quotes, as in cvs -H add.
@@ -332,6 +332,8 @@ lookup_command_attribute (cmd_name)
if (strcmp (cmd_name, cm->fullname) == 0)
break;
}
+ if (!cm->fullname)
+ error (1, 0, "unknown command: %s", cmd_name);
return cm->attr;
}
@@ -834,7 +836,7 @@ Copyright (c) 1989-2001 Brian Berliner, david d `zoo' zuhn, \n\
error (0, 0,
"CVSROOT is set but empty! Make sure that the");
error (0, 0,
- "specification of CVSROOT is legal, either via the");
+ "specification of CVSROOT is valid, either via the");
error (0, 0,
"`-d' option, the %s environment variable, or the",
CVSROOT_ENV);
@@ -894,7 +896,7 @@ Copyright (c) 1989-2001 Brian Berliner, david d `zoo' zuhn, \n\
if (current_parsed_root != NULL)
free_cvsroot_t (current_parsed_root);
if ((current_parsed_root = parse_cvsroot (current_root)) == NULL)
- error (1, 0, "Bad CVSROOT.");
+ error (1, 0, "Bad CVSROOT: `%s'.", current_root);
if (trace)
fprintf (stderr, "%s-> main loop with CVSROOT=%s\n",
diff --git a/contrib/cvs/src/mkmodules.c b/contrib/cvs/src/mkmodules.c
index d1f7ac7..df6fea1 100644
--- a/contrib/cvs/src/mkmodules.c
+++ b/contrib/cvs/src/mkmodules.c
@@ -206,10 +206,12 @@ static const char *const checkoutlist_contents[] = {
static const char *const cvswrappers_contents[] = {
"# This file affects handling of files based on their names.\n",
"#\n",
+#if 0 /* see comments in wrap_add in wrapper.c */
"# The -t/-f options allow one to treat directories of files\n",
"# as a single file, or to transform a file in other ways on\n",
"# its way in and out of CVS.\n",
"#\n",
+#endif
"# The -m option specifies whether CVS attempts to merge files.\n",
"#\n",
"# The -k option specifies keyword expansion (e.g. -kb for binary).\n",
@@ -242,7 +244,7 @@ static const char *const notify_contents[] = {
"# \"ALL\" or \"DEFAULT\" can be used in place of the regular expression.\n",
"#\n",
"# For example:\n",
- "#ALL mail %s -s \"CVS notification\"\n",
+ "#ALL mail -s \"CVS notification\" %s\n",
NULL
};
@@ -297,6 +299,14 @@ static const char *const config_contents[] = {
"# Set `LogHistory' to `all' or `TOFEWGCMAR' to log all transactions to the\n",
"# history file, or a subset as needed (ie `TMAR' logs all write operations)\n",
"#LogHistory=TOFEWGCMAR\n",
+ "\n",
+ "# Set `RereadLogAfterVerify' to `always' (the default) to allow the verifymsg\n",
+ "# script to change the log message. Set it to `stat' to force CVS to verify",
+ "# that the file has changed before reading it (this can take up to an extra\n",
+ "# second per directory being committed, so it is not recommended for large\n",
+ "# repositories. Set it to `never' (the previous CVS behavior) to prevent\n",
+ "# verifymsg scripts from changing the log message.\n",
+ "#RereadLogAfterVerify=always\n",
NULL
};
diff --git a/contrib/cvs/src/modules.c b/contrib/cvs/src/modules.c
index d349530..b161e94 100644
--- a/contrib/cvs/src/modules.c
+++ b/contrib/cvs/src/modules.c
@@ -657,19 +657,19 @@ module `%s' is a request for a file in a module which is not a directory",
}
#endif
- /* write out the checkin/update prog files if necessary */
-#ifdef SERVER_SUPPORT
- if (err == 0 && !noexec && m_type == CHECKOUT && server_expanding)
- {
- if (checkin_prog != NULL)
- server_prog (where ? where : mname, checkin_prog, PROG_CHECKIN);
- if (update_prog != NULL)
- server_prog (where ? where : mname, update_prog, PROG_UPDATE);
- }
- else
-#endif
+ /* run/write out the checkin/update prog files if necessary */
if (err == 0 && !noexec && m_type == CHECKOUT && run_module_prog)
{
+#ifdef SERVER_SUPPORT
+ if (server_active) {
+ if (checkin_prog != NULL)
+ server_prog (where ? where : mwhere ? mwhere : mname, checkin_prog, PROG_CHECKIN);
+ if (update_prog != NULL)
+ server_prog (where ? where : mwhere ? mwhere : mname, update_prog, PROG_UPDATE);
+ }
+ else
+ {
+#endif
FILE *fp;
if (checkin_prog != NULL)
@@ -686,6 +686,9 @@ module `%s' is a request for a file in a module which is not a directory",
if (fclose (fp) == EOF)
error (1, errno, "cannot close %s", CVSADM_UPROG);
}
+#ifdef SERVER_SUPPORT
+ }
+#endif
}
/* cd back to where we started */
diff --git a/contrib/cvs/src/myndbm.c b/contrib/cvs/src/myndbm.c
index 7795f66..600b3aa 100644
--- a/contrib/cvs/src/myndbm.c
+++ b/contrib/cvs/src/myndbm.c
@@ -19,7 +19,7 @@
#ifdef MY_NDBM
-static void mydbm_load_file PROTO ((FILE *, List *));
+static void mydbm_load_file PROTO ((FILE *, List *, char *));
/* Returns NULL on error in which case errno has been set to indicate
the error. Can also call error() itself. */
@@ -44,7 +44,7 @@ mydbm_open (file, flags, mode)
if (fp != NULL)
{
- mydbm_load_file (fp, db->dbm_list);
+ mydbm_load_file (fp, db->dbm_list, file);
if (fclose (fp) < 0)
error (0, errno, "cannot close %s", file);
}
@@ -195,9 +195,10 @@ mydbm_store (db, key, value, flags)
}
static void
-mydbm_load_file (fp, list)
+mydbm_load_file (fp, list, filename)
FILE *fp;
List *list;
+ char *filename; /* Used in error messages. */
{
char *line = NULL;
size_t line_size;
@@ -206,14 +207,17 @@ mydbm_load_file (fp, list)
char *cp, *vp;
int cont;
int line_length;
+ int line_num;
value_allocated = 1;
value = xmalloc (value_allocated);
cont = 0;
+ line_num=0;
while ((line_length =
getstr (&line, &line_size, fp, '\012', 0, GETLINE_NO_LIMIT)) >= 0)
{
+ line_num++;
if (line_length > 0 && line[line_length - 1] == '\012')
{
/* Strip the newline. */
@@ -280,21 +284,28 @@ mydbm_load_file (fp, list)
kp = vp;
while (*vp && !isspace ((unsigned char) *vp))
vp++;
- *vp++ = '\0'; /* NULL terminate the key */
+ if (*vp)
+ *vp++ = '\0'; /* NULL terminate the key */
p->type = NDBMNODE;
p->key = xstrdup (kp);
while (*vp && isspace ((unsigned char) *vp))
vp++; /* skip whitespace to value */
if (*vp == '\0')
{
- error (0, 0, "warning: NULL value for key `%s'", p->key);
+ if (!really_quiet)
+ error (0, 0,
+ "warning: NULL value for key `%s' at line %d of `%s'",
+ p->key, line_num, filename);
freenode (p);
continue;
}
p->data = xstrdup (vp);
if (addnode (list, p) == -1)
{
- error (0, 0, "duplicate key found for `%s'", p->key);
+ if (!really_quiet)
+ error (0, 0,
+ "duplicate key found for `%s' at line %d of `%s'",
+ p->key, line_num, filename);
freenode (p);
}
}
diff --git a/contrib/cvs/src/parseinfo.c b/contrib/cvs/src/parseinfo.c
index 7efd638..e0eb3a5 100644
--- a/contrib/cvs/src/parseinfo.c
+++ b/contrib/cvs/src/parseinfo.c
@@ -65,7 +65,12 @@ Parse_Info (infofile, repository, callproc, all)
srepos = Short_Repository (repository);
if (trace)
- (void) fprintf (stderr, " -> ParseInfo(%s, %s, %s)\n",
+ (void) fprintf (stderr, "%s-> Parse_Info (%s, %s, %s)\n",
+#ifdef SERVER_SUPPORT
+ server_active ? "S" : " ",
+#else
+ "",
+#endif
infopath, srepos, all ? "ALL" : "not ALL");
/* search the info file for lines that match */
@@ -384,6 +389,15 @@ warning: this CVS does not support PreservePermissions");
strcpy (logHistory, p);
}
}
+ else if (strcmp (line, "RereadLogAfterVerify") == 0)
+ {
+ if (strcmp (p, "no") == 0 || strcmp (p, "never") == 0)
+ RereadLogAfterVerify = LOGMSG_REREAD_NEVER;
+ else if (strcmp (p, "yes") == 0 || strcmp (p, "always") == 0)
+ RereadLogAfterVerify = LOGMSG_REREAD_ALWAYS;
+ else if (strcmp (p, "stat") == 0)
+ RereadLogAfterVerify = LOGMSG_REREAD_STAT;
+ }
else
{
/* We may be dealing with a keyword which was added in a
diff --git a/contrib/cvs/src/patch.c b/contrib/cvs/src/patch.c
index 5a20877..8852f3d 100644
--- a/contrib/cvs/src/patch.c
+++ b/contrib/cvs/src/patch.c
@@ -28,7 +28,6 @@ static int patch_proc PROTO((int argc, char **argv, char *xwhere,
static int force_tag_match = 1;
static int patch_short = 0;
static int toptwo_diffs = 0;
-static int local = 0;
static char *options = NULL;
static char *rev1 = NULL;
static int rev1_validated = 0;
@@ -65,6 +64,7 @@ patch (argc, argv)
char **argv;
{
register int i;
+ int local = 0;
int c;
int err = 0;
DBM *db;
@@ -343,19 +343,19 @@ patch_proc (argc, argv, xwhere, mwhere, mfile, shorten, local_specified,
if (rev1 != NULL && !rev1_validated)
{
- tag_check_valid (rev1, argc - 1, argv + 1, local, 0, NULL);
+ tag_check_valid (rev1, argc - 1, argv + 1, local_specified, 0, NULL);
rev1_validated = 1;
}
if (rev2 != NULL && !rev2_validated)
{
- tag_check_valid (rev2, argc - 1, argv + 1, local, 0, NULL);
+ tag_check_valid (rev2, argc - 1, argv + 1, local_specified, 0, NULL);
rev2_validated = 1;
}
/* start the recursion processor */
err = start_recursion (patch_fileproc, (FILESDONEPROC) NULL, patch_dirproc,
(DIRLEAVEPROC) NULL, NULL,
- argc - 1, argv + 1, local,
+ argc - 1, argv + 1, local_specified,
which, 0, 1, where, 1);
free (where);
@@ -432,7 +432,7 @@ patch_fileproc (callerdat, finfo)
if (!date1)
date1 = xmalloc (MAXDATELEN);
*date1 = '\0';
- if (RCS_getrevtime (rcsfile, vers_head, date1, 1) == -1)
+ if (RCS_getrevtime (rcsfile, vers_head, date1, 1) == (time_t)-1)
{
if (!really_quiet)
error (0, 0, "cannot find date in rcs file %s revision %s",
diff --git a/contrib/cvs/src/rcs.c b/contrib/cvs/src/rcs.c
index 385eaf2..f087187 100644
--- a/contrib/cvs/src/rcs.c
+++ b/contrib/cvs/src/rcs.c
@@ -13,6 +13,14 @@
#include "edit.h"
#include "hardlink.h"
+/* These need to be source after cvs.h or HAVE_MMAP won't be set... */
+#ifdef HAVE_MMAP
+# include <sys/mman.h>
+# ifndef HAVE_GETPAGESIZE
+# include "getpagesize.h"
+# endif
+#endif
+
int preserve_perms = 0;
/* The RCS -k options, and a set of enums that must match the array.
@@ -58,8 +66,10 @@ 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));
@@ -730,8 +740,8 @@ RCS_fully_parse (rcs)
vers = findnode (rcs->versions, key);
if (vers == NULL)
error (1, 0,
- "mismatch in rcs file %s between deltas and deltatexts",
- rcs->path);
+ "mismatch in rcs file %s between deltas and deltatexts (%s)",
+ rcs->path, key);
vnode = (RCSVers *) vers->data;
@@ -789,12 +799,12 @@ unrecognized operation '\\x%x' in %s",
op, rcs->path);
(void) strtoul (cp, (char **) &cp, 10);
if (*cp++ != ' ')
- error (1, 0, "space expected in %s",
- rcs->path);
+ error (1, 0, "space expected in %s revision %s",
+ rcs->path, vnode->version);
count = strtoul (cp, (char **) &cp, 10);
if (*cp++ != '\012')
- error (1, 0, "linefeed expected in %s",
- rcs->path);
+ error (1, 0, "linefeed expected in %s revision %s",
+ rcs->path, vnode->version);
if (op == 'd')
del += count;
@@ -809,8 +819,8 @@ unrecognized operation '\\x%x' in %s",
{
if (count != 1)
error (1, 0, "\
-invalid rcs file %s: premature end of value",
- rcs->path);
+premature end of value in %s revision %s",
+ rcs->path, vnode->version);
else
break;
}
@@ -987,14 +997,45 @@ rcsbuf_open (rcsbuf, fp, filename, pos)
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 );
+
+ if (pos)
+ {
+ size_t ps = getpagesize ();
+ mmap_off = ( pos / ps ) * ps;
+ }
+
+ /* 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 );
+
+ rcsbuf_buffer_size = fs.st_size - mmap_off;
+ 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)
expand_string (&rcsbuf_buffer, &rcsbuf_buffer_size, RCSBUF_BUFSIZE);
rcsbuf->ptr = rcsbuf_buffer;
rcsbuf->ptrend = rcsbuf_buffer;
+ rcsbuf->pos = pos;
+#endif /* HAVE_MMAP */
rcsbuf->fp = fp;
rcsbuf->filename = filename;
- rcsbuf->pos = pos;
rcsbuf->vlen = 0;
rcsbuf->at_string = 0;
rcsbuf->embedded_at = 0;
@@ -1008,6 +1049,9 @@ rcsbuf_close (rcsbuf)
{
if (! rcsbuf_inuse)
error (1, 0, "rcsbuf_close: internal error");
+#ifdef HAVE_MMAP
+ munmap ( rcsbuf_buffer, rcsbuf_buffer_size );
+#endif
rcsbuf_inuse = 0;
}
@@ -1048,9 +1092,9 @@ rcsbuf_getkey (rcsbuf, keyp, valp)
ptrend = rcsbuf->ptrend;
/* Sanity check. */
- if (ptr < rcsbuf_buffer || ptr > rcsbuf_buffer + rcsbuf_buffer_size)
- abort ();
+ assert (ptr >= rcsbuf_buffer && ptr < 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. */
@@ -1062,8 +1106,7 @@ rcsbuf_getkey (rcsbuf, keyp, valp)
/* Sanity check: we don't read more than RCSBUF_BUFSIZE bytes
at a time, so we can't have more bytes than that past PTR. */
- if (len > RCSBUF_BUFSIZE)
- abort ();
+ assert (len <= RCSBUF_BUFSIZE);
/* Update the POS field, which holds the file offset of the
first byte in the RCSBUF_BUFFER buffer. */
@@ -1074,18 +1117,23 @@ 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))
@@ -1104,13 +1152,17 @@ 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;
@@ -1139,13 +1191,17 @@ 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 == ';')
{
@@ -1180,6 +1236,7 @@ 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
@@ -1187,25 +1244,31 @@ 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;
@@ -1213,6 +1276,7 @@ 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;
@@ -1262,13 +1326,17 @@ 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 == ';')
{
@@ -1303,6 +1371,7 @@ 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;
@@ -1313,10 +1382,13 @@ 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);
@@ -1360,6 +1432,7 @@ 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
@@ -1367,22 +1440,29 @@ 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;
@@ -1425,12 +1505,16 @@ 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))
@@ -1451,14 +1535,18 @@ 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;
}
@@ -1476,6 +1564,7 @@ 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
@@ -1527,6 +1616,7 @@ 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. */
@@ -1683,7 +1773,19 @@ rcsbuf_valpolish_internal (rcsbuf, to, from, lenp)
{
++from;
- /* Sanity check. */
+ /* Sanity check.
+ *
+ * FIXME: I restored this to an abort from an assert based on
+ * advice from Larry Jones that asserts should not be used to
+ * confirm the validity of an RCS file... This leaves two
+ * issues here: 1) I am uncertain that the fact that we will
+ * only find double '@'s hasn't already been confirmed; and:
+ * 2) If this is the proper place to spot the error in the RCS
+ * file, then we should print a much clearer error here for the
+ * user!!!!!!!
+ *
+ * - DRP
+ */
if (*from != '@' || clen == 0)
abort ();
@@ -1707,11 +1809,8 @@ rcsbuf_valpolish_internal (rcsbuf, to, from, lenp)
}
/* Sanity check. */
- if (from != orig_from + len
- || to != orig_to + (len - rcsbuf->embedded_at))
- {
- abort ();
- }
+ assert (from == orig_from + len
+ && to == orig_to + (len - rcsbuf->embedded_at));
*to = '\0';
}
@@ -1732,7 +1831,7 @@ rcsbuf_valword (rcsbuf, valp)
register char *ptr, *pat;
char c;
-#define my_whitespace(c) (my_spacetab[(unsigned char)c] != 0)
+# define my_whitespace(c) (my_spacetab[(unsigned char)c] != 0)
if (*valp == NULL)
return NULL;
@@ -1790,7 +1889,7 @@ rcsbuf_valword (rcsbuf, valp)
or an id. Make sure it is not another special character. */
if (c == '$' || c == '.' || c == ',')
{
- error (1, 0, "illegal special character in RCS field in %s",
+ error (1, 0, "invalid special character in RCS field in %s",
rcsbuf->filename);
}
@@ -1810,7 +1909,7 @@ rcsbuf_valword (rcsbuf, valp)
the character in its memory cell. Check to make sure that it
is a legitimate word delimiter -- whitespace or end. */
if (c != '\0' && !my_whitespace (c))
- error (1, 0, "illegal special character in RCS field in %s",
+ error (1, 0, "invalid special character in RCS field in %s",
rcsbuf->filename);
*pat = '\0';
@@ -1818,7 +1917,7 @@ rcsbuf_valword (rcsbuf, valp)
*valp = pat;
return xstrdup (ptr);
-#undef my_whitespace
+# undef my_whitespace
}
#endif
@@ -1829,7 +1928,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
@@ -1876,9 +1975,9 @@ rcsbuf_cache_close ()
{
if (cached_rcs != NULL)
{
+ rcsbuf_close (&cached_rcsbuf);
if (fclose (cached_rcsbuf.fp) != 0)
error (0, errno, "cannot close %s", cached_rcsbuf.filename);
- rcsbuf_close (&cached_rcsbuf);
freercsnode (&cached_rcs);
cached_rcs = NULL;
}
@@ -1895,6 +1994,7 @@ rcsbuf_cache_open (rcs, pos, pfp, prcsbuf)
FILE **pfp;
struct rcsbuffer *prcsbuf;
{
+#ifndef HAVE_MMAP
if (cached_rcs == rcs)
{
if (rcsbuf_ftell (&cached_rcsbuf) != pos)
@@ -1925,19 +2025,32 @@ 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
+ * process memory.
+ *
+ * If this happens, cached mmapped buffers would be usable, but don't
+ * forget to make sure rcs->pos < pos here...
+ */
if (cached_rcs != NULL)
rcsbuf_cache_close ();
*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 */
}
@@ -2235,7 +2348,7 @@ RCS_gettag (rcs, symtag, force_tag_match, simple_tag)
RCS_reparsercsfile (rcs, (FILE **) NULL, (struct rcsbuffer *) NULL);
/* If tag is "HEAD", special case to get head RCS revision */
- if (tag && (STREQ (tag, TAG_HEAD) || *tag == '\0'))
+ if (tag && STREQ (tag, TAG_HEAD))
#if 0 /* This #if 0 is only in the Cygnus code. Why? Death support? */
if (force_tag_match && (rcs->flags & VALID) && (rcs->flags & INATTIC))
return ((char *) NULL); /* head request for removed file */
@@ -2832,16 +2945,21 @@ RCS_getdate (rcs, date, force_tag_match)
/* if the head is on a branch, try the branch first */
if (rcs->branch != NULL)
+ {
retval = RCS_getdatebranch (rcs, date, rcs->branch);
-
- /* if we found a match, we are done */
- if (retval != NULL)
- return (retval);
+ if (retval != NULL)
+ return (retval);
+ }
/* otherwise if we have a trunk, try it */
if (rcs->head)
{
p = findnode (rcs->versions, rcs->head);
+ if (p == NULL)
+ {
+ error (0, 0, "%s: head revision %s doesn't exist", rcs->path,
+ rcs->head);
+ }
while (p != NULL)
{
/* if the date of this one is before date, take it */
@@ -2859,10 +2977,13 @@ RCS_getdate (rcs, date, force_tag_match)
p = (Node *) NULL;
}
}
+ else
+ error (0, 0, "%s: no head revision", rcs->path);
/*
* at this point, either we have the revision we want, or we have the
- * first revision on the trunk (1.1?) in our hands
+ * first revision on the trunk (1.1?) in our hands, or we've come up
+ * completely empty
*/
/* if we found what we're looking for, and it's not 1.1 return it */
@@ -2895,7 +3016,8 @@ RCS_getdate (rcs, date, force_tag_match)
if (retval != NULL)
return (retval);
- if (!force_tag_match || RCS_datecmp (vers->date, date) <= 0)
+ if (!force_tag_match ||
+ (vers != NULL && RCS_datecmp (vers->date, date) <= 0))
return (xstrdup (vers->version));
else
return (NULL);
@@ -3168,6 +3290,8 @@ translate_symtag (rcs, tag)
while (! whitespace (*cp) && *cp != '\0')
++cp;
+ if (*cp == '\0')
+ break;
}
}
@@ -4230,7 +4354,7 @@ RCS_checkout (rcs, workfile, rev, nametag, options, sout, pfn, callerdat)
/* If the size of `devtype' changes, fix the sscanf call also */
char devtype[16];
- if (sscanf (info->data, "%16s %lu",
+ if (sscanf (info->data, "%15s %lu",
devtype, &devnum_long) < 2)
error (1, 0, "%s:%s has bad `special' newphrase %s",
workfile, vers->version, info->data);
@@ -4295,7 +4419,7 @@ RCS_checkout (rcs, workfile, rev, nametag, options, sout, pfn, callerdat)
#ifdef PRESERVE_PERMISSIONS_SUPPORT
else if (special_file)
{
-#ifdef HAVE_MKNOD
+# ifdef HAVE_MKNOD
char *dest;
/* Can send either to WORKFILE or to SOUT, as long as SOUT is
@@ -4316,11 +4440,11 @@ RCS_checkout (rcs, workfile, rev, nametag, options, sout, pfn, callerdat)
if (mknod (dest, special_file, devnum) < 0)
error (1, errno, "could not create special file %s",
dest);
-#else
+# else
error (1, 0,
"cannot create %s: unable to create special files on this system",
workfile);
-#endif
+# endif
}
#endif
else
@@ -4923,7 +5047,7 @@ RCS_checkin (rcs, workfile, message, rev, flags)
case S_IFREG: break;
case S_IFCHR:
case S_IFBLK:
-#ifdef HAVE_ST_RDEV
+# ifdef HAVE_ST_RDEV
np = getnode();
np->type = RCSFIELD;
np->key = xstrdup ("special");
@@ -4933,11 +5057,11 @@ RCS_checkin (rcs, workfile, message, rev, flags)
(unsigned long) sb.st_rdev);
np->data = xstrdup (buf);
addnode (delta->other_delta, np);
-#else
+# else
error (0, 0,
"can't preserve %s: unable to save device files on this system",
workfile);
-#endif
+# endif
break;
default:
@@ -5788,7 +5912,9 @@ RCS_unlock (rcs, rev, unlock_quiet)
if (rcs->flags & PARTIAL)
RCS_reparsercsfile (rcs, (FILE **) NULL, (struct rcsbuffer *) NULL);
- /* If rev is NULL, unlock the latest revision (first in
+ /* If rev is NULL, unlock the revision held by the caller; if more
+ than one, make the user specify the revision explicitly. This
+ differs from RCS which unlocks the latest revision (first in
rcs->locks) held by the caller. */
if (rev == NULL)
{
@@ -5813,17 +5939,24 @@ RCS_unlock (rcs, rev, unlock_quiet)
lock = NULL;
for (p = locks->list->next; p != locks->list; p = p->next)
{
- if (lock != NULL)
+ if (STREQ (p->data, user))
{
- if (!unlock_quiet)
- error (0, 0, "\
+ if (lock != NULL)
+ {
+ if (!unlock_quiet)
+ error (0, 0, "\
%s: multiple revisions locked by %s; please specify one", rcs->path, user);
- return 1;
+ return 1;
+ }
+ lock = p;
}
- lock = p;
}
if (lock == NULL)
+ {
+ if (!unlock_quiet)
+ error (0, 0, "No locks are set for %s.\n", user);
return 0; /* no lock found, ergo nothing to do */
+ }
xrev = xstrdup (lock->key);
}
else
@@ -5851,6 +5984,9 @@ RCS_unlock (rcs, rev, unlock_quiet)
is called with a NULL revision, since that means "whatever
revision is currently locked by the caller." */
char *repos, *workfile;
+ if (!unlock_quiet)
+ error (0, 0, "\
+%s: revision %s locked by %s; breaking lock", rcs->path, xrev, lock->data);
repos = xstrdup (rcs->path);
workfile = strrchr (repos, '/');
*workfile++ = '\0';
@@ -7072,8 +7208,8 @@ RCS_deltas (rcs, fp, rcsbuf, version, op, text, len, log, loglen)
node = findnode (rcs->versions, key);
if (node == NULL)
error (1, 0,
- "mismatch in rcs file %s between deltas and deltatexts",
- rcs->path);
+ "mismatch in rcs file %s between deltas and deltatexts (%s)",
+ rcs->path, key);
/* Stash the previous version. */
prev_vers = vers;
@@ -7565,8 +7701,8 @@ RCS_getdeltatext (rcs, fp, rcsbuf)
p = findnode (rcs->versions, num);
if (p == NULL)
- error (1, 0, "mismatch in rcs file %s between deltas and deltatexts",
- rcs->path);
+ error (1, 0, "mismatch in rcs file %s between deltas and deltatexts (%s)",
+ rcs->path, num);
d = (Deltatext *) xmalloc (sizeof (Deltatext));
d->version = xstrdup (num);
@@ -7926,8 +8062,10 @@ 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. */
@@ -8036,7 +8174,12 @@ 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 (nls > 0
@@ -8053,6 +8196,7 @@ RCS_copydeltas (rcs, fin, rcsbufin, fout, newdtext, insertpt)
nls = 0;
}
+#endif /* HAVE_MMAP */
}
/* A helper procedure for RCS_copydeltas. This is called via walklist
@@ -8314,7 +8458,8 @@ RCS_rewrite (rcs, newdtext, insertpt)
/* Update delta_pos to the current position in the output file.
Do NOT move these statements: they must be done after fin has
been positioned at the old delta_pos, but before any delta
- texts have been written to fout. */
+ texts have been written to fout.
+ */
rcs->delta_pos = ftell (fout);
if (rcs->delta_pos == -1)
error (1, errno, "cannot ftell in RCS file %s", rcs->path);
@@ -8331,7 +8476,7 @@ RCS_rewrite (rcs, newdtext, insertpt)
fragile even if it happens to sometimes be true. The real
solution is to make sure that all the code which reads
from fin checks for errors itself (some does, some doesn't). */
- error (0, 0, "warning: when closing RCS file `%s'", rcs->path);
+ error (0, 0, "warning: ferror set while rewriting RCS file `%s'", rcs->path);
if (fclose (fin) < 0)
error (0, errno, "warning: closing RCS file `%s'", rcs->path);
diff --git a/contrib/cvs/src/recurse.c b/contrib/cvs/src/recurse.c
index 2235193..200cbf6 100644
--- a/contrib/cvs/src/recurse.c
+++ b/contrib/cvs/src/recurse.c
@@ -247,7 +247,10 @@ start_recursion (fileproc, filesdoneproc, direntproc, dirleaveproc, callerdat,
directories. */
if (!wrap_name_has (argv[i], WRAP_TOCVS) && isdir (argv[i]))
+ {
+ strip_trailing_slashes (argv[i]);
addlist (&dirlist, argv[i]);
+ }
else
{
/* otherwise, split argument into directory and component names. */
diff --git a/contrib/cvs/src/remove.c b/contrib/cvs/src/remove.c
index 63b61d3..691d141 100644
--- a/contrib/cvs/src/remove.c
+++ b/contrib/cvs/src/remove.c
@@ -235,6 +235,14 @@ remove_fileproc (callerdat, finfo)
cannot remove file `%s' which has a numeric sticky tag of `%s'",
finfo->fullname, vers->tag);
}
+ else if (vers->date != NULL)
+ {
+ /* Commit will just give an error, and so there seems to be
+ little reason to allow the remove. */
+ error (0, 0, "\
+cannot remove file `%s' which has a sticky date of `%s'",
+ finfo->fullname, vers->date);
+ }
else
{
char *fname;
diff --git a/contrib/cvs/src/root.c b/contrib/cvs/src/root.c
index 2d1261d..1a6d648 100644
--- a/contrib/cvs/src/root.c
+++ b/contrib/cvs/src/root.c
@@ -387,7 +387,7 @@ parse_cvsroot (root_in)
if (! (p = strchr (method, ':')))
{
- error (0, 0, "bad CVSroot: %s", root_in);
+ error (0, 0, "No closing `:' on method in CVSROOT.");
free (cvsroot_save);
goto error_exit;
}
@@ -412,7 +412,7 @@ parse_cvsroot (root_in)
newroot->method = fork_method;
else
{
- error (0, 0, "unknown method in CVSroot: %s", root_in);
+ error (0, 0, "Unknown method (`%s') in CVSROOT.", method);
free (cvsroot_save);
goto error_exit;
}
@@ -420,7 +420,7 @@ parse_cvsroot (root_in)
else
{
/* If the method isn't specified, assume
- SERVER_METHOD/EXT_METHOD if the string contains a colon or
+ SERVER_METHOD/EXT_METHOD if the string looks like a relative path or
LOCAL_METHOD otherwise. */
newroot->method = ((*cvsroot_copy != '/' && strchr (cvsroot_copy, '/'))
@@ -447,8 +447,7 @@ parse_cvsroot (root_in)
*/
if ((p = strchr (cvsroot_copy, '/')) == NULL)
{
- error (0, 0, "CVSROOT (\"%s\")", root_in);
- error (0, 0, "requires a path spec");
+ error (0, 0, "CVSROOT requires a path spec:");
error (0, 0, ":(gserver|kserver|pserver):[[user][:password]@]host[:[port]]/path");
error (0, 0, "[:(ext|server):][[user]@]host[:]/path");
free (cvsroot_save);
@@ -497,20 +496,18 @@ parse_cvsroot (root_in)
{
if (!isdigit(*q++))
{
- error(0, 0, "CVSROOT (\"%s\")", root_in);
- error(0, 0, "may only specify a positive, non-zero, integer port (not \"%s\").",
+ error (0, 0, "CVSROOT may only specify a positive, non-zero, integer port (not `%s').",
p);
- error(0, 0, "perhaps you entered a relative pathname?");
+ error (0, 0, "Perhaps you entered a relative pathname?");
free (cvsroot_save);
goto error_exit;
}
}
if ((newroot->port = atoi (p)) <= 0)
{
- error (0, 0, "CVSROOT (\"%s\")", root_in);
- error(0, 0, "may only specify a positive, non-zero, integer port (not \"%s\").",
+ error (0, 0, "CVSROOT may only specify a positive, non-zero, integer port (not `%s').",
p);
- error(0, 0, "perhaps you entered a relative pathname?");
+ error (0, 0, "Perhaps you entered a relative pathname?");
free (cvsroot_save);
goto error_exit;
}
@@ -540,9 +537,8 @@ parse_cvsroot (root_in)
#if ! defined (CLIENT_SUPPORT) && ! defined (DEBUG)
if (newroot->method != local_method)
{
- error (0, 0, "CVSROOT \"%s\"", root_in);
- error (0, 0, "is set for a remote access method but your");
- error (0, 0, "CVS executable doesn't support it");
+ error (0, 0, "CVSROOT is set for a remote access method but your");
+ error (0, 0, "CVS executable doesn't support it.");
goto error_exit;
}
#endif
@@ -550,16 +546,15 @@ parse_cvsroot (root_in)
#if ! defined (SERVER_SUPPORT) && ! defined (DEBUG)
if (newroot->method == fork_method)
{
- error (0, 0, "CVSROOT \"%s\"", root_in);
- error (0, 0, "is set to use the :fork: access method but your");
- error (0, 0, "CVS executable doesn't support it");
+ error (0, 0, "CVSROOT is set to use the :fork: access method but your");
+ error (0, 0, "CVS executable doesn't support it.");
goto error_exit;
}
#endif
if (newroot->username && ! newroot->hostname)
{
- error (0, 0, "missing hostname in CVSROOT: \"%s\"", root_in);
+ error (0, 0, "Missing hostname in CVSROOT.");
goto error_exit;
}
@@ -571,9 +566,8 @@ parse_cvsroot (root_in)
case local_method:
if (newroot->username || newroot->hostname)
{
- error (0, 0, "can't specify hostname and username in CVSROOT");
- error (0, 0, "(\"%s\")", root_in);
- error (0, 0, "when using local access method");
+ error (0, 0, "Can't specify hostname and username in CVSROOT");
+ error (0, 0, "when using local access method.");
goto error_exit;
}
/* cvs.texinfo has always told people that CVSROOT must be an
@@ -583,8 +577,9 @@ parse_cvsroot (root_in)
error. */
if (!isabsolute (newroot->directory))
{
- error (0, 0, "CVSROOT \"%s\" must be an absolute pathname",
+ error (0, 0, "CVSROOT must be an absolute pathname (not `%s')",
newroot->directory);
+ error (0, 0, "when using local access method.");
goto error_exit;
}
no_port = 1;
@@ -596,15 +591,15 @@ parse_cvsroot (root_in)
name is absolute -- let the server do it. */
if (newroot->username || newroot->hostname)
{
- error (0, 0, "can't specify hostname and username in CVSROOT");
- error (0, 0, "(\"%s\")", root_in);
- error (0, 0, "when using fork access method");
+ error (0, 0, "Can't specify hostname and username in CVSROOT");
+ error (0, 0, "when using fork access method.");
goto error_exit;
}
if (!isabsolute (newroot->directory))
{
- error (0, 0, "CVSROOT \"%s\" must be an absolute pathname",
+ error (0, 0, "CVSROOT must be an absolute pathname (not `%s')",
newroot->directory);
+ error (0, 0, "when using fork access method.");
goto error_exit;
}
no_port = 1;
@@ -612,9 +607,8 @@ parse_cvsroot (root_in)
break;
case kserver_method:
#ifndef HAVE_KERBEROS
- error (0, 0, "CVSROOT \"%s\"", root_in);
- error (0, 0, "is set for a kerberos access method but your");
- error (0, 0, "CVS executable doesn't support it");
+ error (0, 0, "CVSROOT is set for a kerberos access method but your");
+ error (0, 0, "CVS executable doesn't support it.");
goto error_exit;
#else
check_hostname = 1;
@@ -622,9 +616,8 @@ parse_cvsroot (root_in)
#endif
case gserver_method:
#ifndef HAVE_GSSAPI
- error (0, 0, "CVSROOT \"%s\"", root_in);
- error (0, 0, "is set for a GSSAPI access method but your");
- error (0, 0, "CVS executable doesn't support it");
+ error (0, 0, "CVSROOT is set for a GSSAPI access method but your");
+ error (0, 0, "CVS executable doesn't support it.");
goto error_exit;
#else
check_hostname = 1;
@@ -639,6 +632,8 @@ parse_cvsroot (root_in)
case pserver_method:
check_hostname = 1;
break;
+ default:
+ error (1, 0, "Invalid method found in parse_cvsroot");
}
if (no_password && newroot->password)
@@ -650,7 +645,7 @@ parse_cvsroot (root_in)
if (check_hostname && !newroot->hostname)
{
- error (0, 0, "didn't specify hostname in CVSROOT: %s", root_in);
+ error (0, 0, "Didn't specify hostname in CVSROOT.");
goto error_exit;
}
@@ -663,7 +658,7 @@ parse_cvsroot (root_in)
if (*newroot->directory == '\0')
{
- error (0, 0, "missing directory in CVSROOT: %s", root_in);
+ error (0, 0, "Missing directory in CVSROOT.");
goto error_exit;
}
diff --git a/contrib/cvs/src/root.h b/contrib/cvs/src/root.h
new file mode 100644
index 0000000..afe79b6
--- /dev/null
+++ b/contrib/cvs/src/root.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2001, Derek Price and others
+ * Copyright (c) 1992, Brian Berliner and Jeff Polk
+ * Copyright (c) 1989-1992, Brian Berliner
+ *
+ * You may distribute under the terms of the GNU General Public License as
+ * specified in the README file that comes with the CVS kit.
+ */
+
+/* CVSroot data structures */
+
+/* Access method specified in CVSroot. */
+typedef enum {
+ null_method,
+ local_method,
+ server_method,
+ pserver_method,
+ kserver_method,
+ gserver_method,
+ ext_method,
+ fork_method
+} CVSmethod;
+extern char *method_names[]; /* change this in root.c if you change
+ the enum above */
+
+typedef struct cvsroot_s {
+ char *original; /* the complete source CVSroot string */
+ CVSmethod method; /* one of the enum values above */
+ char *username; /* the username or NULL if method == local */
+ char *password; /* the username or NULL if method == local */
+ char *hostname; /* the hostname or NULL if method == local */
+ int port; /* the port or zero if method == local */
+ char *directory; /* the directory name */
+#ifdef CLIENT_SUPPORT
+ unsigned char isremote; /* nonzero if we are doing remote access */
+#endif /* CLIENT_SUPPORT */
+} cvsroot_t;
diff --git a/contrib/cvs/src/sanity.sh b/contrib/cvs/src/sanity.sh
index 727e33a..22c1a98 100755
--- a/contrib/cvs/src/sanity.sh
+++ b/contrib/cvs/src/sanity.sh
@@ -398,7 +398,7 @@ else
fi
# now make sure that tr works on NULs
-if $EXPR `echo "123" | ${TR} '2' '\0'` : "123" >/dev/null; then
+if $EXPR `echo "123" | ${TR} '2' '\0'` : "123" >/dev/null 2>&1; then
TR=`find_tool tr`
if test -z "$TR" ; then
echo 'Warning: you are using a version of tr which does not correctly'
@@ -674,9 +674,10 @@ if test x"$*" = x; then
tests="${tests} new newb conflicts conflicts2 conflicts3"
tests="${tests} clean"
# Checking out various places (modules, checkout -d, &c)
- tests="${tests} modules modules2 modules3 modules4 modules5"
+ tests="${tests} modules modules2 modules3 modules4 modules5 modules6"
tests="${tests} mkmodules-temp-file-removal"
tests="${tests} cvsadm emptydir abspath toplevel toplevel2"
+ tests="${tests} checkout_repository"
# Log messages, error messages.
tests="${tests} mflag editor errmsg1 errmsg2 adderrmsg"
# Watches, binary files, history browsing, &c.
@@ -1599,8 +1600,8 @@ Specify the --help option for further information about CVS'
if $remote; then
dotest version-2r "${testcvs} version" \
-'Client: Concurrent Versions System (CVS) [0-9.]* (client/server)
-Server: Concurrent Versions System (CVS) [0-9.]* (client/server)'
+'Client: Concurrent Versions System (CVS) [0-9p.]* (client/server)
+Server: Concurrent Versions System (CVS) [0-9p.]* (client/server)'
else
dotest version-2 "${testcvs} version" \
'Concurrent Versions System (CVS) [0-9.]*.*'
@@ -1633,6 +1634,8 @@ Server: Concurrent Versions System (CVS) [0-9.]* (client/server)'
dotest basica-1a0 "${testcvs} -q update" ''
dotest basica-1a1 "${testcvs} -q diff -c" ''
dotest basica-1a2 "${testcvs} -q status" ''
+ dotest basica-1a3 "${testcvs} -q update ." ''
+ dotest basica-1a4 "${testcvs} -q update ./" ''
mkdir sdir
# Remote CVS gives the "cannot open CVS/Entries" error, which is
@@ -1719,7 +1722,7 @@ done"
dotest_fail basica-nonexist "${testcvs} -q ci nonexist" \
"${PROG}"' [a-z]*: nothing known about `nonexist'\''
'"${PROG}"' \[[a-z]* aborted\]: correct above errors first!'
- dotest basica-8 "${testcvs} -q update" ''
+ dotest basica-8 "${testcvs} -q update ." ''
# Test the -f option to ci
cd sdir/ssdir
@@ -1754,7 +1757,7 @@ ${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v <-- ssfile
new revision: 3\.1\.2\.1; previous revision: 3\.1
done"
# 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"
cd ../..
dotest basica-8b "${testcvs} -q diff -r1.2 -r1.3" \
@@ -1784,7 +1787,8 @@ ${PROG} [a-z]*: invalid context length argument"
"${PROG} \[[a-z]* aborted\]: ${TESTDIR}/nonexist/CVSROOT: .*"
dotest basica-10 "${testcvs} annotate" \
-'Annotations for sdir/ssdir/ssfile
+'
+Annotations for sdir/ssdir/ssfile
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
1\.1 .'"${username}"' *[0-9a-zA-Z-]*.: ssfile
1\.2 .'"${username}"' *[0-9a-zA-Z-]*.: ssfile line 2'
@@ -1799,7 +1803,7 @@ ${PROG} [a-z]*: use .${PROG} commit. to remove this file permanently"
${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v <-- ssfile
new revision: delete; previous revision: 3\.1
done"
- dotest basica-r3 "${testcvs} -q up -p -r 3.1 ssfile >ssfile" ""
+ dotest basica-r3 "${testcvs} -q up -p -r 3.1 ./ssfile >ssfile" ""
dotest basica-r4 "${testcvs} add ssfile" \
"${PROG} [a-z]*: re-adding file ssfile (in place of dead revision 3\.2)
${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
@@ -1874,7 +1878,7 @@ revision 1\.1
date: [0-9/]* [0-9:]*; author: ${username}; state: Exp;
add-it
============================================================================="
- dotest basica-o8 "${testcvs} -q update -p -r 1.1 ssfile" "ssfile"
+ dotest basica-o8 "${testcvs} -q update -p -r 1.1 ./ssfile" "ssfile"
cd ../..
cd ..
@@ -2070,7 +2074,7 @@ sfile2 starts"
"U sub1/sub2/Emptydir/sfile1
U sub1/sub2/sdir2/sfile2"
cd sub1
- dotest basicb-12 "${testcvs} -q update" ''
+ dotest basicb-12 "${testcvs} -q update ./." ''
touch xx
dotest basicb-13 "${testcvs} add xx" fixme
cd ..
@@ -4641,7 +4645,7 @@ C file4"
file=x
echo >$file
dotest rm-update-message-setup-2 "$testcvs -q add $file" \
-"$PROG [a-z]*: use .cvs commit. to add this file permanently"
+"$PROG [a-z]*: use .$PROG commit. to add this file permanently"
dotest rm-update-message-setup-3 "$testcvs -q ci -mcreate $file" \
"RCS file: $CVSROOT_DIRNAME/rm-update-message/$file,v
done
@@ -4823,8 +4827,7 @@ done"
"Checking in file5;
${CVSROOT_DIRNAME}/first-dir/file5,v <-- file5
${PROG} [a-z]*: ${CVSROOT_DIRNAME}/first-dir/file5,v: revision 4\.8 too low; must be higher than 7\.1
-${PROG} [a-z]*: could not check in file5
-7\.1 unlocked"
+${PROG} [a-z]*: could not check in file5"
dotest rmadd-24a "${testcvs} -q ci -r 8.4 -m change file5" \
"Checking in file5;
${CVSROOT_DIRNAME}/first-dir/file5,v <-- file5
@@ -4842,6 +4845,69 @@ File: file5 Status: Up-to-date
Sticky Date: (none)
Sticky Options: (none)"
+ # now try forced revision with recursion
+ mkdir sub
+ dotest rmadd-26 "${testcvs} -q add sub" \
+"Directory ${CVSROOT_DIRNAME}/first-dir/sub added to the repository"
+ echo hello >sub/subfile
+ dotest rmadd-27 "${testcvs} -q add sub/subfile" \
+"${PROG} [a-z]*: use .$PROG commit. to add this file permanently"
+
+ dotest rmadd-28 "${testcvs} -q ci -m. sub" \
+"RCS file: ${CVSROOT_DIRNAME}/first-dir/sub/subfile,v
+done
+Checking in sub/subfile;
+${CVSROOT_DIRNAME}/first-dir/sub/subfile,v <-- subfile
+initial revision: 1\.1
+done"
+
+ # lose the branch
+ dotest rmadd-29 "${testcvs} -q up -A" \
+"${PROG} [a-z]*: file3 is no longer in the repository
+${PROG} [a-z]*: file4 is no longer in the repository"
+
+ # -f disables recursion
+ dotest rmadd-30 "${testcvs} -q ci -f -r9 -m." \
+"Checking in file1;
+${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1
+new revision: 9\.1; previous revision: 7\.1
+done
+Checking in file2;
+${CVSROOT_DIRNAME}/first-dir/file2,v <-- file2
+new revision: 9\.1; previous revision: 7\.1
+done
+Checking in file5;
+${CVSROOT_DIRNAME}/first-dir/file5,v <-- file5
+new revision: 9\.1; previous revision: 8\.4
+done"
+
+ # add -R to force recursion
+ dotest rmadd-31 "${testcvs} -q ci -f -r9 -R -m." \
+"Checking in file1;
+${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1
+new revision: 9\.2; previous revision: 9\.1
+done
+Checking in file2;
+${CVSROOT_DIRNAME}/first-dir/file2,v <-- file2
+new revision: 9\.2; previous revision: 9\.1
+done
+Checking in file5;
+${CVSROOT_DIRNAME}/first-dir/file5,v <-- file5
+new revision: 9\.2; previous revision: 9\.1
+done
+Checking in sub/subfile;
+${CVSROOT_DIRNAME}/first-dir/sub/subfile,v <-- subfile
+new revision: 9\.1; previous revision: 1\.1
+done"
+
+ if $remote; then
+ # as noted above, remote doesn't set a sticky tag
+ :
+ else
+ dotest rmadd-32 "cat CVS/Tag" "T9"
+ dotest rmadd-33 "cat sub/CVS/Tag" "T9"
+ fi
+
cd ../..
rm -r 1
rm -rf ${CVSROOT_DIRNAME}/first-dir
@@ -5685,7 +5751,7 @@ done"
;;
tagf)
- # More tagging tests, including using tag -F to convert a
+ # More tagging tests, including using tag -F -B to convert a
# branch tag to a regular tag and recovering thereof.
# Setup; check in first-dir/file1
@@ -5729,11 +5795,16 @@ Checking in file2;
${CVSROOT_DIRNAME}/first-dir/file2,v <-- file2
new revision: 1\.1\.2\.1; previous revision: 1\.1
done"
- # Here we make it a non-branch tag. Some think this should
- # be an error. But if -F means "I want to put this tag here,
- # never mind whether there was a tag of that name before", then
- # an error wouldn't fit.
- dotest tagf-8 "${testcvs} -q tag -F br" "T file1
+ # Here we try to make it a non-branch tag, but will
+ # succeed in getting only warnings, even with -F
+ # because converting a branch tag to non-branch
+ # is potentially catastrophic.
+ dotest tagf-8a "${testcvs} -q tag -F br" \
+"${PROG} [a-z]*: file1: Not moving branch tag .br. from 1\.1\.2\.1 to 1\.1\\.2\.1\.
+${PROG} [a-z]*: file2: Not moving branch tag .br. from 1\.1\.2\.1 to 1\.1\.2\.1\."
+ # however, if we *really* are sure we want to move a branch tag,
+ # "-F -B" will do the trick
+ dotest tagf-8 "${testcvs} -q tag -F -B br" "T file1
T file2"
echo moremod >> file1
echo moremod >> file2
@@ -5792,6 +5863,106 @@ Checking in file2;
${CVSROOT_DIRNAME}/first-dir/file2,v <-- file2
new revision: 1\.1\.2\.2; previous revision: 1\.1\.2\.1
done"
+ # try accidentally deleting branch tag, "tag -d"
+ dotest_fail tagf-16 "${testcvs} tag -d br" \
+"${PROG} [a-z]*: Untagging \.
+${PROG} [a-z]*: Not removing branch tag .br. from .${CVSROOT_DIRNAME}/first-dir/file1,v.\.
+${PROG} [a-z]*: Not removing branch tag .br. from .${CVSROOT_DIRNAME}/first-dir/file2,v.\."
+ # try accidentally deleting branch tag, "rtag -d"
+ dotest_fail tagf-17 "${testcvs} rtag -d br first-dir" \
+"${PROG} [a-z]*: Untagging first-dir
+${PROG} [a-z]*: Not removing branch tag .br. from .${CVSROOT_DIRNAME}/first-dir/file1,v.\.
+${PROG} [a-z]*: Not removing branch tag .br. from .${CVSROOT_DIRNAME}/first-dir/file2,v.\."
+ # try accidentally converting branch tag to non-branch tag "tag -F"
+ dotest tagf-18 "${testcvs} tag -r1.1 -F br file1" \
+"${PROG} [a-z]*: file1: Not moving branch tag .br. from 1\.1\.4\.1 to 1\.1\."
+ # try accidentally converting branch tag to non-branch tag "rtag -F"
+ dotest tagf-19 "${testcvs} rtag -r1.1 -F br first-dir" \
+"${PROG} [a-z]*: Tagging first-dir
+${PROG} [a-z]*: first-dir/file1: Not moving branch tag .br. from 1\.1\.4\.1 to 1\.1\.
+${PROG} [a-z]*: first-dir/file2: Not moving branch tag .br. from 1\.1\.2\.2 to 1\.1\."
+ # create a non-branch tag
+ dotest tagf-20 "${testcvs} rtag regulartag first-dir" \
+"${PROG} [a-z]*: Tagging first-dir"
+ # try accidentally converting non-branch tag to branch tag (tag -F -B -b)
+ dotest tagf-21 "${testcvs} tag -F -B -b regulartag file1" \
+"${PROG} [a-z]*: file1: Not moving non-branch tag .regulartag. from 1\.1 to 1\.1\.4\.1\.0\.2 due to .-B. option\."
+ # try accidentally converting non-branch tag to branch rtag (rtag -F -B -b)
+ dotest tagf-22 "${testcvs} rtag -F -B -b regulartag first-dir" \
+"${PROG} [a-z]*: Tagging first-dir
+${PROG} [a-z]*: first-dir/file1: Not moving non-branch tag .regulartag. from 1\.1 to 1\.1\.0\.6 due to .-B. option\.
+${PROG} [a-z]*: first-dir/file2: Not moving non-branch tag .regulartag. from 1\.1 to 1\.1\.0\.4 due to .-B. option\."
+ # Try accidentally deleting non-branch: (tag -d -B)
+ dotest_fail tagf-23 "${testcvs} tag -d -B regulartag file1" \
+"${PROG} [a-z]*: Not removing non-branch tag .regulartag. from .${CVSROOT_DIRNAME}/first-dir/file1,v. due to .-B. option\."
+ # Try accidentally deleting non-branch: (rtag -d -B)
+ dotest_fail tagf-24 \
+ "${testcvs} rtag -d -B regulartag first-dir" \
+"${PROG} [a-z]*: Untagging first-dir
+${PROG} [a-z]*: Not removing non-branch tag .regulartag. from .${CVSROOT_DIRNAME}/first-dir/file1,v. due to .-B. option\.
+${PROG} [a-z]*: Not removing non-branch tag .regulartag. from .${CVSROOT_DIRNAME}/first-dir/file2,v. due to .-B. option\."
+
+ # the following tests (throught the next commit) keep moving the same
+ # tag back and forth between 1.1.6 & 1.1.8 in file1 and between
+ # 1.1.4 and 1.1.6 in file2 since nothing was checked in on some of
+ # these branches and CVS only tracks branches via tags unless they contain data.
+
+ # try intentionally converting non-branch tag to branch tag (tag -F -b)
+ dotest tagf-25a "${testcvs} tag -F -b regulartag file1" "T file1"
+ # try intentionally moving a branch tag to a newly created branch (tag -F -b -B)
+ dotest tagf-25b "${testcvs} tag -F -B -b -r1.1 regulartag file1" \
+"T file1"
+ # try intentionally converting mixed tags to branch tags (rtag -F -b)
+ dotest tagf-26a "${testcvs} rtag -F -b regulartag first-dir" \
+"${PROG} [a-z]*: Tagging first-dir
+${PROG} [a-z]*: first-dir/file1: Not moving branch tag .regulartag. from 1\.1 to 1\.1\.0\.8\."
+ # try intentionally converting a branch to a new branch tag (rtag -F -b -B)
+ dotest tagf-26b "${testcvs} rtag -F -B -b -r1.1 regulartag first-dir" \
+"${PROG} [a-z]*: Tagging first-dir"
+ # update to our new branch
+ dotest tagf-27 "${testcvs} update -r regulartag" \
+"${PROG} [a-z]*: Updating \.
+U file1
+U file2"
+ # commit some changes and see that all rev numbers look right
+ echo changes >> file1
+ echo changes >> file2
+ dotest tagf-28 "${testcvs} ci -m changes" \
+"${PROG} [a-z]*: Examining \.
+Checking in file1;
+${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1
+new revision: 1\.1\.8\.1; previous revision: 1\.1
+done
+Checking in file2;
+${CVSROOT_DIRNAME}/first-dir/file2,v <-- file2
+new revision: 1\.1\.6\.1; previous revision: 1\.1
+done"
+ # try intentional branch to non-branch (tag -F -B)
+ dotest tagf-29 "${testcvs} tag -F -B -r1.1 regulartag file1" \
+"T file1"
+ # try non-branch to non-branch (tag -F -B)
+ dotest tagf-29a "${testcvs} tag -F -B -r br regulartag file1" \
+"${PROG} [a-z]*: file1: Not moving non-branch tag .regulartag. from 1\.1 to 1\.1\.4\.1 due to .-B. option\."
+ # try mixed-branch to non-branch (rtag -F -B )
+ dotest tagf-29b "${testcvs} rtag -F -B -r br regulartag first-dir" \
+"${PROG} [a-z]*: Tagging first-dir
+${PROG} [a-z]*: first-dir/file1: Not moving non-branch tag .regulartag. from 1\.1 to 1\.1\.4\.1 due to .-B. option\."
+ # at this point, regulartag is a regular tag within
+ # file1 and file2
+
+ # try intentional branch to non-branch (rtag -F -B)
+ dotest tagf-30 "${testcvs} rtag -F -B -r1.1 br first-dir" \
+"${PROG} [a-z]*: Tagging first-dir"
+ # create a branch tag so we can try to delete it.
+ dotest tagf-31 "${testcvs} rtag -b brtag first-dir" \
+"${PROG} [a-z]*: Tagging first-dir"
+
+ # try intentinal deletion of branch tag (tag -d -B)
+ dotest tagf-32 "${testcvs} tag -d -B brtag file1" "D file1"
+ # try intentinal deletion of branch tag (rtag -d -B)
+ dotest tagf-33 "${testcvs} rtag -d -B brtag first-dir" \
+"${PROG} [a-z]*: Untagging first-dir"
+
cd ../..
rm -r 1
@@ -6014,6 +6185,49 @@ new revision: 1\.1\.2\.2; previous revision: 1\.1\.2\.1
done"
dotest rcslib-symlink-4 "ls -l $CVSROOT_DIRNAME/first-dir/file2,v" \
".*$CVSROOT_DIRNAME/first-dir/file2,v -> file1,v"
+
+ # CVS was failing to check both the symlink and the file
+ # for timestamp changes for a while. Test that.
+ rm file1
+ if $remote; then
+ dotest rcslib-symlink-3ar "${testcvs} -q up file1" "U file1"
+ else
+ dotest rcslib-symlink-3a "${testcvs} -q up file1" \
+"${PROG} [a-z]*: warning: file1 was lost
+U file1"
+ fi
+ echo "This is a change" >> file1
+ dotest rcslib-symlink-3b "${testcvs} ci -m because file1" \
+"Checking in file1;
+${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1
+new revision: 1\.1\.2\.[0-9]*; previous revision: 1\.1\.2\.[0-9]*
+done"
+ dotest rcslib-symlink-3c "${testcvs} update file2" "[UP] file2"
+
+ echo some new text >file3
+ dotest rcslib-symlink-3d "${testcvs} -Q add file3" ''
+ dotest rcslib-symlink-3e "${testcvs} -Q ci -mtest file3" \
+"RCS file: ${CVSROOT_DIRNAME}/first-dir/Attic/file3,v
+done
+Checking in file3;
+${CVSROOT_DIRNAME}/first-dir/Attic/file3,v <-- file3
+new revision: 1\.1\.2\.1; previous revision: 1\.1
+done"
+ rm ${CVSROOT_DIRNAME}/first-dir/file2,v
+ dotest rcslib-symlink-3f "ln -s Attic/file3,v ${CVSROOT_DIRNAME}/first-dir/file2,v"
+ dotest rcslib-symlink-3g "${testcvs} update file2" "U file2"
+
+ # restore the link to file1 for the following tests
+ dotest rcslib-symlink-3i "${testcvs} -Q rm -f file3" ''
+ dotest rcslib-symlink-3j "${testcvs} -Q ci -mwhatever file3" \
+"Removing file3;
+${CVSROOT_DIRNAME}/first-dir/Attic/file3,v <-- file3
+new revision: delete; previous revision: 1\.1\.2\.1
+done"
+ rm ${CVSROOT_DIRNAME}/first-dir/file2,v
+ rm -f ${CVSROOT_DIRNAME}/first-dir/Attic/file3,v
+ dotest rcslib-symlink-3h "ln -s file1,v ${CVSROOT_DIRNAME}/first-dir/file2,v"
+
# Test 5 reveals a problem with having symlinks in the
# repository. CVS will try to tag both of the files
# separately. After processing one, it will do the same
@@ -6024,7 +6238,7 @@ done"
dotest rcslib-symlink-5 "${testcvs} tag the_tag" \
"${PROG} [a-z]*: Tagging .
T file1
-W file2 : the_tag already exists on version 1.1.2.1 : NOT MOVING tag to version 1.1.2.2"
+W file2 : the_tag already exists on version 1.1.2.3 : NOT MOVING tag to version 1.1.2.1"
dotest rcslib-symlink-6 "ls -l $CVSROOT_DIRNAME/first-dir/file2,v" \
".*$CVSROOT_DIRNAME/first-dir/file2,v -> file1,v"
@@ -6294,7 +6508,7 @@ done"
"
- ${PROG} checkout -jvendor-branch:yesterday -jvendor-branch first-dir
+ ${PROG} checkout -j<prev_rel_tag> -jjunk-2_0 first-dir
2 conflicts created by this import.
C first-dir/imported-f1
C first-dir/imported-f2
@@ -6404,7 +6618,7 @@ No conflicts created by this import"
"
- ${PROG} -d ${CVSROOT} checkout -jfreemunger:yesterday -jfreemunger first-dir
+ ${PROG} -d ${CVSROOT} checkout -j<prev_rel_tag> -jfreemunger-1_0 first-dir
2 conflicts created by this import.
C first-dir/file1
C first-dir/file2
@@ -6529,27 +6743,12 @@ ${PROG} [a-z]*: Updating bdir/subdir"
"${testcvs} -q rtag -b -r release wip_test first-dir" ""
dotest importc-6 "${testcvs} -q update -r wip_test" "M cdir/cfile"
- if $remote; then
- # Remote doesn't have the bug in the first place.
- dotest importc-7r "${testcvs} -q ci -m modify -r wip_test" \
+ # This used to fail in local mode
+ dotest importc-7 "${testcvs} -q ci -m modify -r wip_test" \
"Checking in cdir/cfile;
${CVSROOT_DIRNAME}/first-dir/cdir/cfile,v <-- cfile
new revision: 1\.1\.1\.1\.2\.1; previous revision: 1\.1\.1\.1
done"
- else
- # This checkin should just succeed. That it doesn't is a
- # bug (CVS 1.9.16 through the present seem to have it; CVS
- # 1.9 did not).
- dotest_fail importc-7 "${testcvs} -q ci -m modify -r wip_test" \
-"${PROG} [a-z]*: in directory adir/sub1/ssdir:
-${PROG} \[[a-z]* aborted\]: there is no version here; do .${PROG} checkout. first"
- # The workaround is to leave off the "-r wip_test".
- dotest importc-7a "${testcvs} -q ci -m modify" \
-"Checking in cdir/cfile;
-${CVSROOT_DIRNAME}/first-dir/cdir/cfile,v <-- cfile
-new revision: 1\.1\.1\.1\.2\.1; previous revision: 1\.1\.1\.1
-done"
- fi
# TODO: should also be testing "import -d" when we update
# an existing file.
@@ -7091,7 +7290,7 @@ U first-dir/file2
U first-dir/file8'
cd first-dir
dotest join-twobranch-2 "${testcvs} -q update -rbr2 -jbranch" \
-"cvs [a-z]*: file1 is no longer in the repository
+"$PROG [a-z]*: file1 is no longer in the repository
U file1
U file2
RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v
@@ -8509,6 +8708,7 @@ fish"
# -d: modules, modules3, cvsadm
# -i, -o, -u, -e, -t: modules5
# slashes in module names: modules3
+ # invalid module definitions: modules6
############################################################
# These tests are to make sure that administrative files get
@@ -9440,9 +9640,13 @@ U CVSROOT/rcsinfo
U CVSROOT/taginfo
U CVSROOT/verifymsg"
+ # FIXCVS: The sleep in the following script helps avoid out of
+ # order messages, but we really need to figure out how to fix
+ # cvs to prevent them in the first place.
for i in checkin checkout update export tag; do
cat >> ${CVSROOT_DIRNAME}/$i.sh <<EOF
#! /bin/sh
+sleep 1
echo "$i script invoked in \`pwd\`"
echo "args: \$@"
EOF
@@ -9466,12 +9670,13 @@ ${PROG} [a-z]*: Rebuilding administrative file database"
cd ..
rm -rf first-dir
+
# Test that real modules check out to realmodule/a, not subdir/a.
if $remote; then
dotest modules5-8 "${testcvs} co realmodule" \
"U realmodule/a
${PROG} [a-z]*: Executing ..${CVSROOT_DIRNAME}/checkout\.sh. .realmodule..
-checkout script invoked in .*
+checkout script invoked in ${tmp}/cvs-serv[0-9a-z]*
args: realmodule"
else
dotest modules5-8 "${testcvs} co realmodule" \
@@ -9484,11 +9689,11 @@ args: realmodule"
dotest_fail modules5-10 "test -f realmodule/b" ""
if $remote; then
dotest modules5-11 "${testcvs} -q co realmodule" \
-"checkout script invoked in .*
+"checkout script invoked in ${tmp}/cvs-serv[0-9a-z]*
args: realmodule"
dotest modules5-12 "${testcvs} -q update" \
"${PROG} [a-z]*: Executing ..${CVSROOT_DIRNAME}/update\.sh. .${CVSROOT_DIRNAME}/first-dir/subdir..
-update script invoked in /.*/realmodule
+update script invoked in ${tmp}/cvs-serv[0-9a-z]*/realmodule
args: ${CVSROOT_DIRNAME}/first-dir/subdir"
echo "change" >>realmodule/a
dotest modules5-13 "${testcvs} -q ci -m." \
@@ -9497,7 +9702,7 @@ ${CVSROOT_DIRNAME}/first-dir/subdir/a,v <-- a
new revision: 1\.2; previous revision: 1\.1
done
${PROG} [a-z]*: Executing ..${CVSROOT_DIRNAME}/checkin\.sh. .${CVSROOT_DIRNAME}/first-dir/subdir..
-checkin script invoked in /.*/realmodule
+checkin script invoked in ${tmp}/cvs-serv[0-9a-z]*/realmodule
args: ${CVSROOT_DIRNAME}/first-dir/subdir"
else
dotest modules5-11 "${testcvs} -q co realmodule" \
@@ -9523,12 +9728,12 @@ Are you sure you want to release (and delete) directory .realmodule.: "
dotest modules5-15 "${testcvs} -q rtag -Dnow MYTAG realmodule" \
"tag script invoked in ${TESTDIR}/1
args: realmodule MYTAG" \
-"tag script invoked in $tmp/cvs-serv[0-9a-z]*
+"tag script invoked in ${tmp}/cvs-serv[0-9a-z]*
args: realmodule MYTAG"
if $remote; then
dotest modules5-16 "${testcvs} -q export -r MYTAG realmodule" \
"U realmodule/a
-export script invoked in .*
+export script invoked in ${tmp}/cvs-serv[0-9a-z]*
args: realmodule"
else
dotest modules5-16 "${testcvs} -q export -r MYTAG realmodule" \
@@ -9536,57 +9741,87 @@ args: realmodule"
export script invoked in ${TESTDIR}/1
args: realmodule"
fi
+ rm -r realmodule
dotest_fail modules5-17 "${testcvs} co realmodule/a" \
"${PROG}"' [a-z]*: module `realmodule/a'\'' is a request for a file in a module which is not a directory' \
"${PROG}"' [a-z]*: module `realmodule/a'\'' is a request for a file in a module which is not a directory
'"${PROG}"' \[[a-z]* aborted\]: cannot expand modules'
- # FIXCVS: The client gets confused in these cases and tries to
- # store the scripts in the wrong places.
- if $remote; then :; else
- # Now test the ability to check out a single file from a directory
+ # Now test the ability to check out a single file from a directory
+ if $remote; then
+ dotest modules5-18 "${testcvs} co dirmodule/a" \
+"U dirmodule/a
+${PROG} [a-z]*: Executing ..${CVSROOT_DIRNAME}/checkout\.sh. .dirmodule..
+checkout script invoked in ${tmp}/cvs-serv[0-9a-z]*
+args: dirmodule"
+ else
dotest modules5-18 "${testcvs} co dirmodule/a" \
"U dirmodule/a
${PROG} [a-z]*: Executing ..${CVSROOT_DIRNAME}/checkout\.sh. .dirmodule..
checkout script invoked in ${TESTDIR}/1
args: dirmodule"
- dotest modules5-19 "test -d dirmodule && test -f dirmodule/a" ""
- dotest_fail modules5-20 "test -f dirmodule/b" ""
- dotest modules5-21 "echo yes | ${testcvs} release -d dirmodule" \
+ fi
+ dotest modules5-19 "test -d dirmodule && test -f dirmodule/a" ""
+ dotest_fail modules5-20 "test -f dirmodule/b" ""
+ dotest modules5-21 "echo yes | ${testcvs} release -d dirmodule" \
"You have \[0\] altered files in this repository\.
Are you sure you want to release (and delete) directory .dirmodule.: "
- # Now test the ability to correctly reject a non-existent filename.
- # For maximum studliness we would check that an error message is
- # being output.
- # We accept a zero exit status because it is what CVS does
- # (Dec 95). Probably the exit status should be nonzero,
- # however.
+ # Now test the ability to correctly reject a non-existent filename.
+ # For maximum studliness we would check that an error message is
+ # being output.
+ # We accept a zero exit status because it is what CVS does
+ # (Dec 95). Probably the exit status should be nonzero,
+ # however.
+ if $remote; then
+ dotest modules5-22 "${testcvs} co dirmodule/nonexist" \
+"${PROG} [a-z]*: warning: new-born dirmodule/nonexist has disappeared
+${PROG} [a-z]*: Executing ..${CVSROOT_DIRNAME}/checkout\.sh. .dirmodule..
+checkout script invoked in ${tmp}/cvs-serv[0-9a-z]*
+args: dirmodule"
+ else
dotest modules5-22 "${testcvs} co dirmodule/nonexist" \
"${PROG} [a-z]*: warning: new-born dirmodule/nonexist has disappeared
${PROG} [a-z]*: Executing ..${CVSROOT_DIRNAME}/checkout\.sh. .dirmodule..
checkout script invoked in ${TESTDIR}/1
args: dirmodule"
+ fi
+ # We tolerate the creation of the dirmodule directory, since that
+ # is what CVS does, not because we view that as preferable to not
+ # creating it.
+ dotest_fail modules5-23 "test -f dirmodule/a || test -f dirmodule/b" ""
+ rm -r dirmodule
- # We tolerate the creation of the dirmodule directory, since that
- # is what CVS does, not because we view that as preferable to not
- # creating it.
- dotest_fail modules5-23 "test -f dirmodule/a || test -f dirmodule/b" ""
- rm -r dirmodule
-
- # Now test that a module using -d checks out to the specified
- # directory.
+ # Now test that a module using -d checks out to the specified
+ # directory.
+ if $remote; then
+ dotest modules5-24 "${testcvs} -q co namedmodule" \
+"U nameddir/a
+U nameddir/b
+checkout script invoked in ${tmp}/cvs-serv[0-9a-z]*
+args: nameddir"
+ else
dotest modules5-24 "${testcvs} -q co namedmodule" \
"U nameddir/a
U nameddir/b
checkout script invoked in ${TESTDIR}/1
args: nameddir"
- dotest modules5-25 "test -f nameddir/a && test -f nameddir/b" ""
- echo add line >>nameddir/a
- # This seems suspicious: when we checkout an existing directory,
- # the checkout script gets executed in addition to the update
- # script. Is that by design or accident?
+ fi
+ dotest modules5-25 "test -f nameddir/a && test -f nameddir/b" ""
+ echo add line >>nameddir/a
+ # This seems suspicious: when we checkout an existing directory,
+ # the checkout script gets executed in addition to the update
+ # script. Is that by design or accident?
+ if $remote; then
+ dotest modules5-26 "${testcvs} -q co namedmodule" \
+"M nameddir/a
+${PROG} [a-z]*: Executing ..${CVSROOT_DIRNAME}/update\.sh. .${CVSROOT_DIRNAME}/first-dir/subdir..
+update script invoked in ${tmp}/cvs-serv[0-9a-z]*/nameddir
+args: ${CVSROOT_DIRNAME}/first-dir/subdir
+checkout script invoked in ${tmp}/cvs-serv[0-9a-z]*
+args: nameddir"
+ else
dotest modules5-26 "${testcvs} -q co namedmodule" \
"M nameddir/a
${PROG} [a-z]*: Executing ..${CVSROOT_DIRNAME}/update\.sh. .${CVSROOT_DIRNAME}/first-dir/subdir..
@@ -9594,7 +9829,18 @@ update script invoked in ${TESTDIR}/1/nameddir
args: ${CVSROOT_DIRNAME}/first-dir/subdir
checkout script invoked in ${TESTDIR}/1
args: nameddir"
- rm nameddir/a
+ fi
+ rm nameddir/a
+
+ if $remote; then
+ dotest modules5-27 "${testcvs} -q co namedmodule" \
+"U nameddir/a
+${PROG} [a-z]*: Executing ..${CVSROOT_DIRNAME}/update\.sh. .${CVSROOT_DIRNAME}/first-dir/subdir..
+update script invoked in ${tmp}/cvs-serv[0-9a-z]*/nameddir
+args: ${CVSROOT_DIRNAME}/first-dir/subdir
+checkout script invoked in ${tmp}/cvs-serv[0-9a-z]*
+args: nameddir"
+ else
dotest modules5-27 "${testcvs} -q co namedmodule" \
"U nameddir/a
${PROG} [a-z]*: Executing ..${CVSROOT_DIRNAME}/update\.sh. .${CVSROOT_DIRNAME}/first-dir/subdir..
@@ -9602,15 +9848,248 @@ update script invoked in ${TESTDIR}/1/nameddir
args: ${CVSROOT_DIRNAME}/first-dir/subdir
checkout script invoked in ${TESTDIR}/1
args: nameddir"
- dotest modules5-28 "echo yes | ${testcvs} release -d nameddir" \
+ fi
+ dotest modules5-28 "echo yes | ${testcvs} release -d nameddir" \
"You have \[0\] altered files in this repository\.
Are you sure you want to release (and delete) directory .nameddir.: "
+
+ # Now try the same tests with -d on command line
+ # FIXCVS? The manual says the modules programs get the module name,
+ # but they really get the directory name.
+ if $remote; then
+ dotest modules5-29 "${testcvs} co -d mydir realmodule" \
+"U mydir/a
+${PROG} [a-z]*: Executing ..${CVSROOT_DIRNAME}/checkout\.sh. .mydir..
+checkout script invoked in ${tmp}/cvs-serv[0-9a-z]*
+args: mydir"
+ else
+ dotest modules5-29 "${testcvs} co -d mydir realmodule" \
+"U mydir/a
+${PROG} [a-z]*: Executing ..${CVSROOT_DIRNAME}/checkout\.sh. .mydir..
+checkout script invoked in ${TESTDIR}/1
+args: mydir"
+ fi
+ dotest modules5-30 "test -d mydir && test -f mydir/a" ""
+ dotest_fail modules5-31 "test -d realmodule || test -f mydir/b" ""
+ if $remote; then
+ dotest modules5-32 "${testcvs} -q co -d mydir realmodule" \
+"checkout script invoked in ${tmp}/cvs-serv[0-9a-z]*
+args: mydir"
+ dotest modules5-33 "${testcvs} -q update" \
+"${PROG} [a-z]*: Executing ..${CVSROOT_DIRNAME}/update\.sh. .${CVSROOT_DIRNAME}/first-dir/subdir..
+update script invoked in ${tmp}/cvs-serv[0-9a-z]*/mydir
+args: ${CVSROOT_DIRNAME}/first-dir/subdir"
+ echo "change" >>mydir/a
+ dotest modules5-34 "${testcvs} -q ci -m." \
+"Checking in mydir/a;
+${CVSROOT_DIRNAME}/first-dir/subdir/a,v <-- a
+new revision: 1\.3; previous revision: 1\.2
+done
+${PROG} [a-z]*: Executing ..${CVSROOT_DIRNAME}/checkin\.sh. .${CVSROOT_DIRNAME}/first-dir/subdir..
+checkin script invoked in ${tmp}/cvs-serv[0-9a-z]*/mydir
+args: ${CVSROOT_DIRNAME}/first-dir/subdir"
+ else
+ dotest modules5-32 "${testcvs} -q co -d mydir realmodule" \
+"checkout script invoked in ${TESTDIR}/1
+args: mydir"
+ dotest modules5-33 "${testcvs} -q update" \
+"${PROG} [a-z]*: Executing ..${CVSROOT_DIRNAME}/update\.sh. .${CVSROOT_DIRNAME}/first-dir/subdir..
+update script invoked in ${TESTDIR}/1/mydir
+args: ${CVSROOT_DIRNAME}/first-dir/subdir"
+ echo "change" >>mydir/a
+ dotest modules5-34 "${testcvs} -q ci -m." \
+"Checking in mydir/a;
+${CVSROOT_DIRNAME}/first-dir/subdir/a,v <-- a
+new revision: 1\.3; previous revision: 1\.2
+done
+${PROG} [a-z]*: Executing ..${CVSROOT_DIRNAME}/checkin\.sh. .${CVSROOT_DIRNAME}/first-dir/subdir..
+checkin script invoked in ${TESTDIR}/1/mydir
+args: ${CVSROOT_DIRNAME}/first-dir/subdir"
+ fi
+ dotest modules5-35 "echo yes | ${testcvs} release -d mydir" \
+"You have \[0\] altered files in this repository\.
+Are you sure you want to release (and delete) directory .mydir.: "
+ if $remote; then
+ dotest modules5-36 "${testcvs} -q rtag -Dnow MYTAG2 realmodule" \
+"tag script invoked in ${tmp}/cvs-serv[0-9a-z]*
+args: realmodule MYTAG2"
+ dotest modules5-37 "${testcvs} -q export -r MYTAG2 -d mydir realmodule" \
+"U mydir/a
+export script invoked in ${tmp}/cvs-serv[0-9a-z]*
+args: mydir"
+ else
+ dotest modules5-36 "${testcvs} -q rtag -Dnow MYTAG2 realmodule" \
+"tag script invoked in ${TESTDIR}/1
+args: realmodule MYTAG2"
+ dotest modules5-37 "${testcvs} -q export -r MYTAG2 -d mydir realmodule" \
+"U mydir/a
+export script invoked in ${TESTDIR}/1
+args: mydir"
+ fi
+ rm -r mydir
+
+ # Now test the ability to check out a single file from a directory
+ if $remote; then
+ dotest modules5-38 "${testcvs} co -d mydir dirmodule/a" \
+"U mydir/a
+${PROG} [a-z]*: Executing ..${CVSROOT_DIRNAME}/checkout\.sh. .mydir..
+checkout script invoked in ${tmp}/cvs-serv[0-9a-z]*
+args: mydir"
+ else
+ dotest modules5-38 "${testcvs} co -d mydir dirmodule/a" \
+"U mydir/a
+${PROG} [a-z]*: Executing ..${CVSROOT_DIRNAME}/checkout\.sh. .mydir..
+checkout script invoked in ${TESTDIR}/1
+args: mydir"
+ fi
+ dotest modules5-39 "test -d mydir && test -f mydir/a" ""
+ dotest_fail modules5-40 "test -d dirmodule || test -f mydir/b" ""
+ dotest modules5-41 "echo yes | ${testcvs} release -d mydir" \
+"You have \[0\] altered files in this repository\.
+Are you sure you want to release (and delete) directory .mydir.: "
+
+ # Now test the ability to correctly reject a non-existent filename.
+ # For maximum studliness we would check that an error message is
+ # being output.
+ # We accept a zero exit status because it is what CVS does
+ # (Dec 95). Probably the exit status should be nonzero,
+ # however.
+ if $remote; then
+ dotest modules5-42 "${testcvs} co -d mydir dirmodule/nonexist" \
+"${PROG} [a-z]*: warning: new-born mydir/nonexist has disappeared
+${PROG} [a-z]*: Executing ..${CVSROOT_DIRNAME}/checkout\.sh. .mydir..
+checkout script invoked in ${tmp}/cvs-serv[0-9a-z]*
+args: mydir"
+ else
+ dotest modules5-42 "${testcvs} co -d mydir dirmodule/nonexist" \
+"${PROG} [a-z]*: warning: new-born mydir/nonexist has disappeared
+${PROG} [a-z]*: Executing ..${CVSROOT_DIRNAME}/checkout\.sh. .mydir..
+checkout script invoked in ${TESTDIR}/1
+args: mydir"
+ fi
+ # We tolerate the creation of the mydir directory, since that
+ # is what CVS does, not because we view that as preferable to not
+ # creating it.
+ dotest_fail modules5-43 "test -f mydir/a || test -f mydir/b" ""
+ rm -r mydir
+
+ if $remote; then
+ dotest modules5-44 "${testcvs} -q co -d mydir namedmodule" \
+"U mydir/a
+U mydir/b
+checkout script invoked in ${tmp}/cvs-serv[0-9a-z]*
+args: mydir"
+ else
+ dotest modules5-44 "${testcvs} -q co -d mydir namedmodule" \
+"U mydir/a
+U mydir/b
+checkout script invoked in ${TESTDIR}/1
+args: mydir"
+ fi
+ dotest modules5-45 "test -f mydir/a && test -f mydir/b" ""
+ dotest_fail modules5-46 "test -d namedir"
+ echo add line >>mydir/a
+ # This seems suspicious: when we checkout an existing directory,
+ # the checkout script gets executed in addition to the update
+ # script. Is that by design or accident?
+ if $remote; then
+ dotest modules5-47 "${testcvs} -q co -d mydir namedmodule" \
+"M mydir/a
+${PROG} [a-z]*: Executing ..${CVSROOT_DIRNAME}/update\.sh. .${CVSROOT_DIRNAME}/first-dir/subdir..
+update script invoked in ${tmp}/cvs-serv[0-9a-z]*/mydir
+args: ${CVSROOT_DIRNAME}/first-dir/subdir
+checkout script invoked in ${tmp}/cvs-serv[0-9a-z]*
+args: mydir"
+ else
+ dotest modules5-47 "${testcvs} -q co -d mydir namedmodule" \
+"M mydir/a
+${PROG} [a-z]*: Executing ..${CVSROOT_DIRNAME}/update\.sh. .${CVSROOT_DIRNAME}/first-dir/subdir..
+update script invoked in ${TESTDIR}/1/mydir
+args: ${CVSROOT_DIRNAME}/first-dir/subdir
+checkout script invoked in ${TESTDIR}/1
+args: mydir"
fi
+ rm mydir/a
+
+ if $remote; then
+ dotest modules5-48 "${testcvs} -q co -d mydir namedmodule" \
+"U mydir/a
+${PROG} [a-z]*: Executing ..${CVSROOT_DIRNAME}/update\.sh. .${CVSROOT_DIRNAME}/first-dir/subdir..
+update script invoked in ${tmp}/cvs-serv[0-9a-z]*/mydir
+args: ${CVSROOT_DIRNAME}/first-dir/subdir
+checkout script invoked in ${tmp}/cvs-serv[0-9a-z]*
+args: mydir"
+ else
+ dotest modules5-48 "${testcvs} -q co -d mydir namedmodule" \
+"U mydir/a
+${PROG} [a-z]*: Executing ..${CVSROOT_DIRNAME}/update\.sh. .${CVSROOT_DIRNAME}/first-dir/subdir..
+update script invoked in ${TESTDIR}/1/mydir
+args: ${CVSROOT_DIRNAME}/first-dir/subdir
+checkout script invoked in ${TESTDIR}/1
+args: mydir"
+ fi
+ dotest modules5-49 "echo yes | ${testcvs} release -d mydir" \
+"You have \[0\] altered files in this repository\.
+Are you sure you want to release (and delete) directory .mydir.: "
cd ..
rm -rf 1 ${CVSROOT_DIRNAME}/first-dir ${CVSROOT_DIRNAME}/*.sh
;;
+ modules6)
+ #
+ # Test invalid module definitions
+ #
+ # See the header comment for the `modules' test for an index of
+ # the complete suite of modules tests.
+ #
+
+ #
+ # There was a bug in CVS through 1.11.1p1 where a bad module name
+ # would cause the previous line to be parsed as the module
+ # definition. This test proves this doesn't happen anymore.
+ #
+ mkdir modules6
+ cd modules6
+ dotest module6-setup-1 "${testcvs} -Q co CVSROOT" ""
+ cd CVSROOT
+ echo "longmodulename who cares" >modules
+ echo "badname" >>modules
+ # This test almost isn't setup since it generates the error message
+ # we are looking for if `-Q' isn't specified, but I want to test the
+ # filename in the message later.
+ dotest modules6-setup-2 "${testcvs} -Q ci -mbad-modules" \
+"Checking in modules;
+${CVSROOT_DIRNAME}/CVSROOT/modules,v <-- modules
+new revision: [0-9.]*; previous revision: [0-9.]*
+done
+${PROG} [a-z]*: Rebuilding administrative file database"
+
+ # Here's where CVS would report not being able to find `lename'
+ cd ..
+ dotest_fail modules6-1 "${testcvs} -q co badname" \
+"${PROG} [a-z]*: warning: NULL value for key .badname. at line 2 of .${CVSROOT_DIRNAME}/CVSROOT/modules.
+${PROG} [a-z]*: cannot find module .badname. - ignored" \
+"${PROG} [a-z]*: warning: NULL value for key .badname. at line 2 of .${CVSROOT_DIRNAME}/CVSROOT/modules.
+${PROG} [a-z]*: cannot find module .badname. - ignored
+${PROG} \[checkout aborted\]: cannot expand modules"
+
+ # cleanup
+ cd CVSROOT
+ echo "# empty modules file" >modules
+ dotest modules6-cleanup-1 "${testcvs} -Q ci -mempty-modules" \
+"Checking in modules;
+${CVSROOT_DIRNAME}/CVSROOT/modules,v <-- modules
+new revision: [0-9.]*; previous revision: [0-9.]*
+done
+${PROG} [a-z]*: Rebuilding administrative file database"
+ cd ../..
+
+ if $keep; then :; else
+ rm -r modules6
+ fi
+ ;;
+
mkmodules-temp-file-removal)
# When a file listed in checkoutlist doesn't exist, cvs-1.10.4
# would fail to remove the CVSROOT/.#[0-9]* temporary file it
@@ -10759,8 +11238,7 @@ U dir/dir2d2-2/sub2d2-2/file2-2"
##################################################
dotest_fail cvsadm-2d3-1 "${testcvs} co -d dir/dir2 1mod" \
-"${PROG} [a-z]*: cannot chdir to dir: No such file or directory
-${PROG} [a-z]*: ignoring module 1mod"
+"${PROG} \[checkout aborted\]: could not change directory to requested checkout directory .dir.: No such file or directory"
if $remote; then :; else
# Remote can't handle this, even with the "mkdir dir".
@@ -11269,12 +11747,11 @@ U ${TESTDIR}/1/file1"
# this is the behavior of CVS 1.9 and earlier.
if $remote; then :; else
dotest_fail abspath-3.1 "${testcvs} co -d ${TESTDIR}/1/2 mod1" \
-"${PROG} [a-z]*: cannot chdir to 1: No such file or directory
-${PROG} [a-z]*: ignoring module mod1"
+"${PROG} \[checkout aborted\]: could not change directory to requested checkout directory .${TESTDIR}/1.: No such file or directory"
fi
dotest_fail abspath-3.2 "${testcvs} co -d 1/2 mod1" \
-"${PROG} [a-z]*: cannot chdir to 1: No such file or directory
-${PROG} [a-z]*: ignoring module mod1"
+"${PROG} \[checkout aborted\]: could not change directory to requested checkout directory .1.: No such file or directory"
+
mkdir 1
if $remote; then
@@ -11282,8 +11759,7 @@ ${PROG} [a-z]*: ignoring module mod1"
# a bug, it should only need to exist on the client side.
# See also cvsadm-2d3.
dotest_fail abspath-3a "${testcvs} co -d 1/2 mod1" \
-"${PROG} [a-z]*: cannot chdir to 1: No such file or directory
-${PROG} [a-z]*: ignoring module mod1"
+"${PROG} \[server aborted\]: could not change directory to requested checkout directory .1.: No such file or directory"
cd 1
dotest abspath-3a-try2 "${testcvs} co -d 2 mod1" \
"${PROG} [a-z]*: Updating 2
@@ -11652,6 +12128,21 @@ ${PROG} [a-z]*: Rebuilding administrative file database"
rm -rf ${CVSROOT_DIRNAME}/top-dir ${CVSROOT_DIRNAME}/second-dir
;;
+ checkout_repository)
+ dotest_fail check_repository-1 "${testcvs} co -d ${CVSROOT_DIRNAME} CVSROOT" \
+"${PROG} \[checkout aborted\]: Cannot check out files into the repository itself"
+ cd ${CVSROOT_DIRNAME}
+ dotest_fail check_repository-2 "${testcvs} co CVSROOT" \
+"${PROG} \[checkout aborted\]: Cannot check out files into the repository itself"
+ dotest check_repository-3 "${testcvs} co -p CVSROOT/modules >/dev/null" \
+"===================================================================
+Checking out CVSROOT/modules
+RCS: ${CVSROOT_DIRNAME}/CVSROOT/modules,v
+VERS: 1\.[0-9]*
+\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*"
+ cd ${TESTDIR}
+ ;;
+
mflag)
for message in '' ' ' '
' ' test' ; do
@@ -11874,6 +12365,63 @@ xCVS: Tag: br
xCVS: file2
xCVS: ----------------------------------------------------------------------
============================================================================="
+
+ # Test CVS's response to an unchanged log message
+ cat >${TESTDIR}/editme <<EOF
+#!${TESTSHELL}
+sleep 1
+exit 0
+EOF
+ chmod +x ${TESTDIR}/editme
+ dotest_fail editor-emptylog-1 "echo a |${testcvs} -e ${TESTDIR}/editme ci -f file1" \
+"
+Log message unchanged or not specified
+a)bort, c)ontinue, e)dit, !)reuse this message unchanged for remaining dirs
+Action: (continue) ${PROG} \[[a-z]* aborted\]: aborted by user"
+
+ # Test CVS's response to an empty log message
+ cat >${TESTDIR}/editme <<EOF
+#!${TESTSHELL}
+sleep 1
+cat /dev/null >\$1
+exit 0
+EOF
+ chmod +x ${TESTDIR}/editme
+ dotest_fail editor-emptylog-1 "echo a |${testcvs} -e ${TESTDIR}/editme ci -f file1" \
+"
+Log message unchanged or not specified
+a)bort, c)ontinue, e)dit, !)reuse this message unchanged for remaining dirs
+Action: (continue) ${PROG} \[[a-z]* aborted\]: aborted by user"
+
+ # Test CVS's response to a log message with one blank line
+ cat >${TESTDIR}/editme <<EOF
+#!${TESTSHELL}
+sleep 1
+echo >\$1
+exit 0
+EOF
+ chmod +x ${TESTDIR}/editme
+ dotest_fail editor-emptylog-1 "echo a |${testcvs} -e ${TESTDIR}/editme ci -f file1" \
+"
+Log message unchanged or not specified
+a)bort, c)ontinue, e)dit, !)reuse this message unchanged for remaining dirs
+Action: (continue) ${PROG} \[[a-z]* aborted\]: aborted by user"
+
+ # Test CVS's response to a log message with only comments
+ cat >${TESTDIR}/editme <<EOF
+#!${TESTSHELL}
+sleep 1
+cat \$1 >${TESTDIR}/edit.new
+mv ${TESTDIR}/edit.new \$1
+exit 0
+EOF
+ chmod +x ${TESTDIR}/editme
+ dotest_fail editor-emptylog-1 "echo a |${testcvs} -e ${TESTDIR}/editme ci -f file1" \
+"
+Log message unchanged or not specified
+a)bort, c)ontinue, e)dit, !)reuse this message unchanged for remaining dirs
+Action: (continue) ${PROG} \[[a-z]* aborted\]: aborted by user"
+
cd ../..
rm -r 1
rm ${TESTDIR}/editme
@@ -12931,7 +13479,7 @@ Are you sure you want to release (and delete) directory .second-dir': "
cd setup
echo file1 >file1
dotest ignore-on-branch-setup-2 "$testcvs -q add file1" \
-"$PROG [a-z]*: use .cvs commit. to add this file permanently"
+"$PROG [a-z]*: use .$PROG commit. to add this file permanently"
dotest ignore-on-branch-setup-3 "$testcvs -q ci -mfile1 file1" \
"RCS file: $CVSROOT_DIRNAME/ignore-on-branch/file1,v
done
@@ -12942,7 +13490,7 @@ done"
dotest ignore-on-branch-setup-4 "$testcvs -q tag -b branch" 'T file1'
echo file2 >file2
dotest ignore-on-branch-setup-5 "$testcvs -q add file2" \
-"$PROG [a-z]*: use .cvs commit. to add this file permanently"
+"$PROG [a-z]*: use .$PROG commit. to add this file permanently"
dotest ignore-on-branch-setup-6 "$testcvs -q ci -mtrunk file2" \
"RCS file: $CVSROOT_DIRNAME/ignore-on-branch/file2,v
done
@@ -12973,7 +13521,7 @@ T file1'
dotest ignore-on-branch-3 "$testcvs -q tag -b branch2" 'T file1'
fi
dotest ignore-on-branch-4 "$testcvs -q add file2" \
-"$PROG [a-z]*: use .cvs commit. to add this file permanently"
+"$PROG [a-z]*: use .$PROG commit. to add this file permanently"
dotest ignore-on-branch-5 "$testcvs -q ci -mbranch file2" \
"Checking in file2;
$CVSROOT_DIRNAME/ignore-on-branch/file2,v <-- file2
@@ -13830,33 +14378,45 @@ File: foo\.exe Status: Up-to-date
mkdir binwrap3/sub2
mkdir binwrap3/sub2/subsub
- echo "*.c0 -k 'b'" > binwrap3/.cvswrappers
+ echo "bar*" > binwrap3/.cvswrappers
+ echo "*.c0 -k 'b'" >> binwrap3/.cvswrappers
echo "whatever -k 'b'" >> binwrap3/.cvswrappers
echo ${binwrap3_text} > binwrap3/foo-b.c0
+ echo ${binwrap3_text} > binwrap3/bar-t.c0
echo ${binwrap3_text} > binwrap3/foo-b.sb
+ echo ${binwrap3_text} > binwrap3/foo-t.sb
echo ${binwrap3_text} > binwrap3/foo-t.c1
echo ${binwrap3_text} > binwrap3/foo-t.st
- echo "*.c1 -k 'b'" > binwrap3/sub1/.cvswrappers
+ echo "bar* -k 'kv'" > binwrap3/sub1/.cvswrappers
+ echo "*.c1 -k 'b'" >> binwrap3/sub1/.cvswrappers
echo "whatever -k 'b'" >> binwrap3/sub1/.cvswrappers
echo ${binwrap3_text} > binwrap3/sub1/foo-b.c1
+ echo ${binwrap3_text} > binwrap3/sub1/bar-t.c1
echo ${binwrap3_text} > binwrap3/sub1/foo-b.sb
+ echo ${binwrap3_text} > binwrap3/sub1/foo-t.sb
echo ${binwrap3_text} > binwrap3/sub1/foo-t.c0
echo ${binwrap3_text} > binwrap3/sub1/foo-t.st
- echo "*.st -k 'b'" > binwrap3/sub2/.cvswrappers
+ echo "bar*" > binwrap3/sub2/.cvswrappers
+ echo "*.st -k 'b'" >> binwrap3/sub2/.cvswrappers
echo ${binwrap3_text} > binwrap3/sub2/foo-b.sb
+ echo ${binwrap3_text} > binwrap3/sub2/foo-t.sb
echo ${binwrap3_text} > binwrap3/sub2/foo-b.st
+ echo ${binwrap3_text} > binwrap3/sub2/bar-t.st
echo ${binwrap3_text} > binwrap3/sub2/foo-t.c0
echo ${binwrap3_text} > binwrap3/sub2/foo-t.c1
echo ${binwrap3_text} > binwrap3/sub2/foo-t.c2
echo ${binwrap3_text} > binwrap3/sub2/foo-t.c3
- echo "*.c3 -k 'b'" > binwrap3/sub2/subsub/.cvswrappers
+ echo "bar* -k 'kv'" > binwrap3/sub2/subsub/.cvswrappers
+ echo "*.c3 -k 'b'" >> binwrap3/sub2/subsub/.cvswrappers
echo "foo -k 'b'" >> binwrap3/sub2/subsub/.cvswrappers
echo "c0* -k 'b'" >> binwrap3/sub2/subsub/.cvswrappers
echo ${binwrap3_text} > binwrap3/sub2/subsub/foo-b.c3
+ echo ${binwrap3_text} > binwrap3/sub2/subsub/bar-t.c3
echo ${binwrap3_text} > binwrap3/sub2/subsub/foo-b.sb
+ echo ${binwrap3_text} > binwrap3/sub2/subsub/foo-t.sb
echo ${binwrap3_text} > binwrap3/sub2/subsub/foo-t.c0
echo ${binwrap3_text} > binwrap3/sub2/subsub/foo-t.c1
echo ${binwrap3_text} > binwrap3/sub2/subsub/foo-t.c2
@@ -13868,7 +14428,8 @@ File: foo\.exe Status: Up-to-date
# This destroys anything currently in cvswrappers, but
# presumably other tests will take care of it themselves if
# they use cvswrappers:
- echo "foo*.sb -k 'b'" > cvswrappers
+ echo "foo-t.sb" > cvswrappers
+ echo "foo*.sb -k 'b'" >> cvswrappers
dotest binwrap3-2 "${testcvs} -q ci -m cvswrappers-mod" \
"Checking in cvswrappers;
${CVSROOT_DIRNAME}/CVSROOT/cvswrappers,v <-- cvswrappers
@@ -13941,6 +14502,12 @@ done"
dotest binwrap3-top4 "grep foo-t.st ./CVS/Entries" \
"/foo-t.st/1.1.1.1/[A-Za-z0-9 :]*//"
+ dotest binwrap3-top5 "grep foo-t.sb ./CVS/Entries" \
+ "/foo-t.sb/1.1.1.1/[A-Za-z0-9 :]*//"
+
+ dotest binwrap3-top6 "grep bar-t.c0 ./CVS/Entries" \
+ "/bar-t.c0/1.1.1.1/[A-Za-z0-9 :]*//"
+
dotest binwrap3-sub1-1 "grep foo-b.c1 sub1/CVS/Entries" \
"/foo-b.c1/1.1.1.1/[A-Za-z0-9 :]*/-kb/"
@@ -13953,6 +14520,12 @@ done"
dotest binwrap3-sub1-4 "grep foo-t.st sub1/CVS/Entries" \
"/foo-t.st/1.1.1.1/[A-Za-z0-9 :]*//"
+ dotest binwrap3-sub1-5 "grep foo-t.sb sub1/CVS/Entries" \
+ "/foo-t.sb/1.1.1.1/[A-Za-z0-9 :]*//"
+
+ dotest binwrap3-sub1-6 "grep bar-t.c1 sub1/CVS/Entries" \
+ "/bar-t.c1/1.1.1.1/[A-Za-z0-9 :]*//"
+
dotest binwrap3-sub2-1 "grep foo-b.sb sub2/CVS/Entries" \
"/foo-b.sb/1.1.1.1/[A-Za-z0-9 :]*/-kb/"
@@ -13971,6 +14544,12 @@ done"
dotest binwrap3-sub2-6 "grep foo-t.c3 sub2/CVS/Entries" \
"/foo-t.c3/1.1.1.1/[A-Za-z0-9 :]*//"
+ dotest binwrap3-sub2-7 "grep foo-t.sb sub2/CVS/Entries" \
+ "/foo-t.sb/1.1.1.1/[A-Za-z0-9 :]*//"
+
+ dotest binwrap3-sub2-8 "grep bar-t.st sub2/CVS/Entries" \
+ "/bar-t.st/1.1.1.1/[A-Za-z0-9 :]*//"
+
dotest binwrap3-subsub1 "grep foo-b.c3 sub2/subsub/CVS/Entries" \
"/foo-b.c3/1.1.1.1/[A-Za-z0-9 :]*/-kb/"
@@ -13989,6 +14568,12 @@ done"
dotest binwrap3-subsub6 "grep foo-t.st sub2/subsub/CVS/Entries" \
"/foo-t.st/1.1.1.1/[A-Za-z0-9 :]*//"
+ dotest binwrap3-subsub7 "grep foo-t.sb sub2/subsub/CVS/Entries" \
+ "/foo-t.sb/1.1.1.1/[A-Za-z0-9 :]*//"
+
+ dotest binwrap3-subsub8 "grep bar-t.c3 sub2/subsub/CVS/Entries" \
+ "/bar-t.c3/1.1.1.1/[A-Za-z0-9 :]*//"
+
dotest binwrap3-sub2-add1 "grep file1.newbin sub2/CVS/Entries" \
"/file1.newbin/1.1/[A-Za-z0-9 :]*/-kb/"
dotest binwrap3-sub2-add2 "grep file1.txt sub2/CVS/Entries" \
@@ -14212,14 +14797,33 @@ ${PROG} [a-z]*: Rebuilding administrative file database"
#!${TESTSHELL}
if head -1 < \$1 | grep '^BugId:[ ]*[0-9][0-9]*$' > /dev/null; then
exit 0
+elif head -1 < \$1 | grep '^BugId:[ ]*new$' > /dev/null; then
+ echo A new bugid was found. >> \$1
+ exit 0
else
echo "No BugId found."
sleep 1
exit 1
fi
EOF
- chmod +x ${TESTDIR}/vscript
- echo "^first-dir ${TESTDIR}/vscript" >>verifymsg
+ cat >${TESTDIR}/vscript2 <<EOF
+#!${TESTSHELL}
+if test -f CVS/Repository; then
+ repo=\`cat CVS/Repository\`
+else
+ repo=\`pwd\`
+fi
+echo \$repo
+if echo "\$repo" |grep yet-another/ >/dev/null 2>&1; then
+ exit 1
+else
+ exit 0
+fi
+EOF
+ chmod +x ${TESTDIR}/vscript*
+ echo "^first-dir/yet-another\\(/\\|\$\\) ${TESTDIR}/vscript2" >>verifymsg
+ echo "^first-dir\\(/\\|\$\\) ${TESTDIR}/vscript" >>verifymsg
+ # first test the directory independant verifymsg
dotest info-v1 "${testcvs} -q ci -m add-verification" \
"Checking in verifymsg;
${CVSROOT_DIRNAME}/CVSROOT/verifymsg,v <-- verifymsg
@@ -14242,6 +14846,8 @@ EOF
${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1
new revision: 1\.4; previous revision: 1\.3
done"
+ rm ${TESTDIR}/comment.tmp
+
cd ..
mkdir another-dir
cd another-dir
@@ -14250,18 +14856,142 @@ done"
"${testcvs} import -m bogus first-dir/another x y" \
"No BugId found\.
${PROG} \[[a-z]* aborted\]: Message verification failed"
+
+ # now verify that directory dependent verifymsgs work
+ dotest info-v5 \
+ "${testcvs} import -m bogus first-dir/yet-another x y" \
+"${TESTDIR}/wnt/another-dir
+N first-dir/yet-another/file2
+
+No conflicts created by this import" \
+"${CVSROOT_DIRNAME}/first-dir/yet-another
+N first-dir/yet-another/file2
+
+No conflicts created by this import"
+
+ # FIXMECVS
+ #
+ # note that in the local case the error message is the same as
+ # info-v5
+ #
+ # This means that the verifymsg scripts cannot reliably and
+ # consistantly obtain information on which directory is being
+ # committed to. Thus it is currently useless for them to be
+ # running in every dir. They should either be run once or
+ # directory information should be passed.
+ if $remote; then
+ dotest_fail info-v6r \
+ "${testcvs} import -m bogus first-dir/yet-another/and-another x y" \
+"${CVSROOT_DIRNAME}/first-dir/yet-another/and-another
+${PROG} \[[a-z]* aborted\]: Message verification failed"
+ else
+ dotest info-v6 \
+ "${testcvs} import -m bogus first-dir/yet-another/and-another x y" \
+"${TESTDIR}/wnt/another-dir
+N first-dir/yet-another/and-another/file2
+
+No conflicts created by this import"
+ fi
rm file2
cd ..
rmdir another-dir
cd CVSROOT
+ echo "RereadLogAfterVerify=always" >>config
+ dotest info-rereadlog-1 "${testcvs} -q ci -m add-RereadLogAfterVerify=always" \
+"Checking in config;
+${CVSROOT_DIRNAME}/CVSROOT/config,v <-- config
+new revision: 1\.[0-9]*; previous revision: 1\.[0-9]*
+done
+${PROG} [a-z]*: Rebuilding administrative file database"
+ cd ../first-dir
+ echo line3 >>file1
+ cat >${TESTDIR}/comment.tmp <<EOF
+BugId: new
+See what happens next.
+EOF
+ dotest info-reread-2 "${testcvs} -q ci -F ${TESTDIR}/comment.tmp" \
+"Checking in file1;
+${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1
+new revision: 1\.5; previous revision: 1\.4
+done"
+ dotest info-reread-3 "${testcvs} -q log -N -r1.5 file1" "
+.*
+BugId: new
+See what happens next.
+A new bugid was found.
+============================================================================="
+
+ cd ../CVSROOT
+ grep -v "RereadLogAfterVerify" config > config.new
+ mv config.new config
+ echo "RereadLogAfterVerify=stat" >>config
+ dotest info-reread-4 "${testcvs} -q ci -m add-RereadLogAfterVerify=stat" \
+"Checking in config;
+${CVSROOT_DIRNAME}/CVSROOT/config,v <-- config
+new revision: 1\.[0-9]*; previous revision: 1\.[0-9]*
+done
+${PROG} [a-z]*: Rebuilding administrative file database"
+ cd ../first-dir
+ echo line4 >>file1
+ cat >${TESTDIR}/comment.tmp <<EOF
+BugId: new
+See what happens next with stat.
+EOF
+ dotest info-reread-5 "${testcvs} -q ci -F ${TESTDIR}/comment.tmp" \
+"Checking in file1;
+${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1
+new revision: 1\.6; previous revision: 1\.5
+done"
+ dotest info-reread-6 "${testcvs} -q log -N -r1.6 file1" "
+.*
+BugId: new
+See what happens next with stat.
+A new bugid was found.
+============================================================================="
+
+ cd ../CVSROOT
+ grep -v "RereadLogAfterVerify" config > config.new
+ mv config.new config
+ echo "RereadLogAfterVerify=never" >>config
+ dotest info-reread-7 "${testcvs} -q ci -m add-RereadLogAfterVerify=never" \
+"Checking in config;
+${CVSROOT_DIRNAME}/CVSROOT/config,v <-- config
+new revision: 1\.[0-9]*; previous revision: 1\.[0-9]*
+done
+${PROG} [a-z]*: Rebuilding administrative file database"
+ cd ../first-dir
+ echo line5 >>file1
+ cat >${TESTDIR}/comment.tmp <<EOF
+BugId: new
+See what happens next.
+EOF
+ dotest info-reread-8 "${testcvs} -q ci -F ${TESTDIR}/comment.tmp" \
+"Checking in file1;
+${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1
+new revision: 1\.7; previous revision: 1\.6
+done"
+ dotest info-reread-6 "${testcvs} -q log -N -r1.7 file1" "
+.*
+BugId: new
+See what happens next.
+============================================================================="
+ cd ..
+
+ cd CVSROOT
echo '# do nothing' >verifymsg
+ echo '# defaults' >config
dotest info-cleanup-verifymsg "${testcvs} -q ci -m nuke-verifymsg" \
-"Checking in verifymsg;
+"Checking in config;
+${CVSROOT_DIRNAME}/CVSROOT/config,v <-- config
+new revision: 1\.[0-9]*; previous revision: 1\.[0-9]*
+done
+Checking in verifymsg;
${CVSROOT_DIRNAME}/CVSROOT/verifymsg,v <-- verifymsg
new revision: 1\.[0-9]*; previous revision: 1\.[0-9]*
done
${PROG} [a-z]*: Rebuilding administrative file database"
+ rm ${TESTDIR}/vscript*
cd ..
dotest_fail info-cleanup-0 "${testcvs} -n release -d CVSROOT" \
@@ -14531,9 +15261,11 @@ U file1'
dotest log-1 "${testcvs} -q co first-dir" ''
cd first-dir
echo 'first revision' > file1
- dotest log-2 "${testcvs} add file1" \
-"${PROG}"' [a-z]*: scheduling file `file1'\'' for addition
-'"${PROG}"' [a-z]*: use .'"${PROG}"' commit. to add this file permanently'
+ echo 'first revision' > file2
+ dotest log-2 "${testcvs} add file1 file2" \
+"${PROG} [a-z]*: scheduling file .file1. for addition
+${PROG} [a-z]*: scheduling file .file2. for addition
+${PROG} [a-z]*: use .${PROG} commit. to add these files permanently"
# While we're at it, check multi-line comments, input from file,
# and trailing whitespace trimming
@@ -14548,26 +15280,47 @@ done
Checking in file1;
${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1
initial revision: 1\.1
+done
+RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v
+done
+Checking in file2;
+${CVSROOT_DIRNAME}/first-dir/file2,v <-- file2
+initial revision: 1\.1
done"
rm -f ${TESTDIR}/comment.tmp
echo 'second revision' > file1
- dotest log-4 "${testcvs} -q ci -m2 file1" \
+ echo 'second revision' > file2
+ dotest log-4 "${testcvs} -q ci -m2 file1 file2" \
"Checking in file1;
${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1
new revision: 1\.2; previous revision: 1\.1
+done
+Checking in file2;
+${CVSROOT_DIRNAME}/first-dir/file2,v <-- file2
+new revision: 1\.2; previous revision: 1\.1
done"
dotest log-5 "${testcvs} -q tag -b branch file1" 'T file1'
+ dotest log-5a "${testcvs} -q tag tag1 file2" 'T file2'
echo 'third revision' > file1
- dotest log-6 "${testcvs} -q ci -m3 file1" \
+ echo 'third revision' > file2
+ dotest log-6 "${testcvs} -q ci -m3 file1 file2" \
"Checking in file1;
${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1
new revision: 1\.3; previous revision: 1\.2
+done
+Checking in file2;
+${CVSROOT_DIRNAME}/first-dir/file2,v <-- file2
+new revision: 1\.3; previous revision: 1\.2
done"
- dotest log-7 "${testcvs} -q update -r branch" '[UP] file1'
+ dotest log-6a "${testcvs} -q tag tag2 file2" 'T file2'
+
+ dotest log-7 "${testcvs} -q update -r branch" \
+"[UP] file1
+${PROG} [a-z]*: file2 is no longer in the repository"
echo 'first branch revision' > file1
dotest log-8 "${testcvs} -q ci -m1b file1" \
@@ -14587,23 +15340,23 @@ done"
# Set up a bunch of shell variables to make the later tests
# easier to describe.=
- log_header="
+ log_header1="
RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v
Working file: file1
head: 1\.3
branch:
locks: strict
access list:"
- rlog_header="
+ rlog_header1="
RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v
head: 1\.3
branch:
locks: strict
access list:"
- log_tags='symbolic names:
+ log_tags1='symbolic names:
tag: 1\.2\.2\.1
branch: 1\.2\.0\.2'
- log_header2='keyword substitution: kv'
+ log_keyword='keyword substitution: kv'
log_dash='----------------------------
revision'
log_date="date: [0-9/]* [0-9:]*; author: ${username}; state: Exp;"
@@ -14631,9 +15384,9 @@ ${log_date}${log_lines}
# Now, finally, test the log output.
dotest log-11 "${testcvs} log file1" \
-"${log_header}
-${log_tags}
-${log_header2}
+"${log_header1}
+${log_tags1}
+${log_keyword}
total revisions: 5; selected revisions: 5
description:
${log_rev3}
@@ -14644,8 +15397,8 @@ ${log_rev1b}
${log_trailer}"
dotest log-12 "${testcvs} log -N file1" \
-"${log_header}
-${log_header2}
+"${log_header1}
+${log_keyword}
total revisions: 5; selected revisions: 5
description:
${log_rev3}
@@ -14656,9 +15409,9 @@ ${log_rev1b}
${log_trailer}"
dotest log-13 "${testcvs} log -b file1" \
-"${log_header}
-${log_tags}
-${log_header2}
+"${log_header1}
+${log_tags1}
+${log_keyword}
total revisions: 5; selected revisions: 3
description:
${log_rev3}
@@ -14667,18 +15420,18 @@ ${log_rev1}
${log_trailer}"
dotest log-14 "${testcvs} log -r file1" \
-"${log_header}
-${log_tags}
-${log_header2}
+"${log_header1}
+${log_tags1}
+${log_keyword}
total revisions: 5; selected revisions: 1
description:
${log_rev3}
${log_trailer}"
dotest log-14a "${testcvs} log -rHEAD file1" \
-"${log_header}
-${log_tags}
-${log_header2}
+"${log_header1}
+${log_tags1}
+${log_keyword}
total revisions: 5; selected revisions: 1
description:
${log_rev3}
@@ -14689,9 +15442,9 @@ ${log_trailer}"
# might be confusing itself).
dotest_fail log-14b "${testcvs} log -r HEAD file1" \
"${PROG} [a-z]*: nothing known about HEAD
-${log_header}
-${log_tags}
-${log_header2}
+${log_header1}
+${log_tags1}
+${log_keyword}
total revisions: 5; selected revisions: 1
description:
${log_rev3}
@@ -14700,50 +15453,50 @@ ${log_trailer}"
# Check that unusual syntax works correctly.
dotest log-14c "${testcvs} log -r: file1" \
-"${log_header}
-${log_tags}
-${log_header2}
+"${log_header1}
+${log_tags1}
+${log_keyword}
total revisions: 5; selected revisions: 1
description:
${log_rev3}
${log_trailer}"
dotest log-14d "${testcvs} log -r, file1" \
-"${log_header}
-${log_tags}
-${log_header2}
+"${log_header1}
+${log_tags1}
+${log_keyword}
total revisions: 5; selected revisions: 1
description:
${log_rev3}
${log_trailer}"
dotest log-14e "${testcvs} log -r. file1" \
-"${log_header}
-${log_tags}
-${log_header2}
+"${log_header1}
+${log_tags1}
+${log_keyword}
total revisions: 5; selected revisions: 1
description:
${log_rev3}
${log_trailer}"
dotest log-14f "${testcvs} log -r:: file1" \
-"${log_header}
-${log_tags}
-${log_header2}
+"${log_header1}
+${log_tags1}
+${log_keyword}
total revisions: 5; selected revisions: 0
description:
${log_trailer}"
dotest log-15 "${testcvs} log -r1.2 file1" \
-"${log_header}
-${log_tags}
-${log_header2}
+"${log_header1}
+${log_tags1}
+${log_keyword}
total revisions: 5; selected revisions: 1
description:
${log_rev2}
${log_trailer}"
dotest log-16 "${testcvs} log -r1.2.2 file1" \
-"${log_header}
-${log_tags}
-${log_header2}
+"${log_header1}
+${log_tags1}
+${log_keyword}
total revisions: 5; selected revisions: 2
description:
${log_rev2b}
@@ -14753,9 +15506,9 @@ ${log_trailer}"
# This test would fail with the old invocation of rlog, but it
# works with the builtin log support.
dotest log-17 "${testcvs} log -rbranch file1" \
-"${log_header}
-${log_tags}
-${log_header2}
+"${log_header1}
+${log_tags1}
+${log_keyword}
total revisions: 5; selected revisions: 2
description:
${log_rev2b}
@@ -14763,9 +15516,9 @@ ${log_rev1b}
${log_trailer}"
dotest log-18 "${testcvs} log -r1.2.2. file1" \
-"${log_header}
-${log_tags}
-${log_header2}
+"${log_header1}
+${log_tags1}
+${log_keyword}
total revisions: 5; selected revisions: 1
description:
${log_rev2b}
@@ -14774,9 +15527,9 @@ ${log_trailer}"
# Multiple -r options are undocumented; see comments in
# cvs.texinfo about whether they should be deprecated.
dotest log-18a "${testcvs} log -r1.2.2.2 -r1.3:1.3 file1" \
-"${log_header}
-${log_tags}
-${log_header2}
+"${log_header1}
+${log_tags1}
+${log_keyword}
total revisions: 5; selected revisions: 2
description:
${log_rev3}
@@ -14786,18 +15539,18 @@ ${log_trailer}"
# This test would fail with the old invocation of rlog, but it
# works with the builtin log support.
dotest log-19 "${testcvs} log -rbranch. file1" \
-"${log_header}
-${log_tags}
-${log_header2}
+"${log_header1}
+${log_tags1}
+${log_keyword}
total revisions: 5; selected revisions: 1
description:
${log_rev2b}
${log_trailer}"
dotest log-20 "${testcvs} log -r1.2: file1" \
-"${log_header}
-${log_tags}
-${log_header2}
+"${log_header1}
+${log_tags1}
+${log_keyword}
total revisions: 5; selected revisions: 2
description:
${log_rev3}
@@ -14805,18 +15558,18 @@ ${log_rev2}
${log_trailer}"
dotest log-20a "${testcvs} log -r1.2:: file1" \
-"${log_header}
-${log_tags}
-${log_header2}
+"${log_header1}
+${log_tags1}
+${log_keyword}
total revisions: 5; selected revisions: 1
description:
${log_rev3}
${log_trailer}"
dotest log-21 "${testcvs} log -r:1.2 file1" \
-"${log_header}
-${log_tags}
-${log_header2}
+"${log_header1}
+${log_tags1}
+${log_keyword}
total revisions: 5; selected revisions: 2
description:
${log_rev2}
@@ -14824,18 +15577,19 @@ ${log_rev1}
${log_trailer}"
dotest log-21a "${testcvs} log -r::1.2 file1" \
-"${log_header}
-${log_tags}
-${log_header2}
-total revisions: 5; selected revisions: 1
+"${log_header1}
+${log_tags1}
+${log_keyword}
+total revisions: 5; selected revisions: 2
description:
+${log_rev2}
${log_rev1}
${log_trailer}"
dotest log-22 "${testcvs} log -r1.1:1.2 file1" \
-"${log_header}
-${log_tags}
-${log_header2}
+"${log_header1}
+${log_tags1}
+${log_keyword}
total revisions: 5; selected revisions: 2
description:
${log_rev2}
@@ -14843,28 +15597,30 @@ ${log_rev1}
${log_trailer}"
dotest log-22a "${testcvs} log -r1.1::1.2 file1" \
-"${log_header}
-${log_tags}
-${log_header2}
-total revisions: 5; selected revisions: 0
+"${log_header1}
+${log_tags1}
+${log_keyword}
+total revisions: 5; selected revisions: 1
description:
+${log_rev2}
${log_trailer}"
dotest log-22b "${testcvs} log -r1.1::1.3 file1" \
-"${log_header}
-${log_tags}
-${log_header2}
-total revisions: 5; selected revisions: 1
+"${log_header1}
+${log_tags1}
+${log_keyword}
+total revisions: 5; selected revisions: 2
description:
+${log_rev3}
${log_rev2}
${log_trailer}"
# Now the same tests but with rlog
dotest log-r11 "${testcvs} rlog first-dir/file1" \
-"${rlog_header}
-${log_tags}
-${log_header2}
+"${rlog_header1}
+${log_tags1}
+${log_keyword}
total revisions: 5; selected revisions: 5
description:
${log_rev3}
@@ -14875,8 +15631,8 @@ ${log_rev1b}
${log_trailer}"
dotest log-r12 "${testcvs} rlog -N first-dir/file1" \
-"${rlog_header}
-${log_header2}
+"${rlog_header1}
+${log_keyword}
total revisions: 5; selected revisions: 5
description:
${log_rev3}
@@ -14887,9 +15643,9 @@ ${log_rev1b}
${log_trailer}"
dotest log-r13 "${testcvs} rlog -b first-dir/file1" \
-"${rlog_header}
-${log_tags}
-${log_header2}
+"${rlog_header1}
+${log_tags1}
+${log_keyword}
total revisions: 5; selected revisions: 3
description:
${log_rev3}
@@ -14898,18 +15654,18 @@ ${log_rev1}
${log_trailer}"
dotest log-r14 "${testcvs} rlog -r first-dir/file1" \
-"${rlog_header}
-${log_tags}
-${log_header2}
+"${rlog_header1}
+${log_tags1}
+${log_keyword}
total revisions: 5; selected revisions: 1
description:
${log_rev3}
${log_trailer}"
dotest log-r14a "${testcvs} rlog -rHEAD first-dir/file1" \
-"${rlog_header}
-${log_tags}
-${log_header2}
+"${rlog_header1}
+${log_tags1}
+${log_keyword}
total revisions: 5; selected revisions: 1
description:
${log_rev3}
@@ -14917,59 +15673,59 @@ ${log_trailer}"
dotest_fail log-r14b "${testcvs} rlog -r HEAD first-dir/file1" \
"${PROG} [a-z]*: cannot find module .HEAD. - ignored
-${rlog_header}
-${log_tags}
-${log_header2}
+${rlog_header1}
+${log_tags1}
+${log_keyword}
total revisions: 5; selected revisions: 1
description:
${log_rev3}
${log_trailer}"
dotest log-r14c "${testcvs} rlog -r: first-dir/file1" \
-"${rlog_header}
-${log_tags}
-${log_header2}
+"${rlog_header1}
+${log_tags1}
+${log_keyword}
total revisions: 5; selected revisions: 1
description:
${log_rev3}
${log_trailer}"
dotest log-r14d "${testcvs} rlog -r, first-dir/file1" \
-"${rlog_header}
-${log_tags}
-${log_header2}
+"${rlog_header1}
+${log_tags1}
+${log_keyword}
total revisions: 5; selected revisions: 1
description:
${log_rev3}
${log_trailer}"
dotest log-r14e "${testcvs} rlog -r. first-dir/file1" \
-"${rlog_header}
-${log_tags}
-${log_header2}
+"${rlog_header1}
+${log_tags1}
+${log_keyword}
total revisions: 5; selected revisions: 1
description:
${log_rev3}
${log_trailer}"
dotest log-r14f "${testcvs} rlog -r:: first-dir/file1" \
-"${rlog_header}
-${log_tags}
-${log_header2}
+"${rlog_header1}
+${log_tags1}
+${log_keyword}
total revisions: 5; selected revisions: 0
description:
${log_trailer}"
dotest log-r15 "${testcvs} rlog -r1.2 first-dir/file1" \
-"${rlog_header}
-${log_tags}
-${log_header2}
+"${rlog_header1}
+${log_tags1}
+${log_keyword}
total revisions: 5; selected revisions: 1
description:
${log_rev2}
${log_trailer}"
dotest log-r16 "${testcvs} rlog -r1.2.2 first-dir/file1" \
-"${rlog_header}
-${log_tags}
-${log_header2}
+"${rlog_header1}
+${log_tags1}
+${log_keyword}
total revisions: 5; selected revisions: 2
description:
${log_rev2b}
@@ -14977,9 +15733,9 @@ ${log_rev1b}
${log_trailer}"
dotest log-r17 "${testcvs} rlog -rbranch first-dir/file1" \
-"${rlog_header}
-${log_tags}
-${log_header2}
+"${rlog_header1}
+${log_tags1}
+${log_keyword}
total revisions: 5; selected revisions: 2
description:
${log_rev2b}
@@ -14987,18 +15743,18 @@ ${log_rev1b}
${log_trailer}"
dotest log-r18 "${testcvs} rlog -r1.2.2. first-dir/file1" \
-"${rlog_header}
-${log_tags}
-${log_header2}
+"${rlog_header1}
+${log_tags1}
+${log_keyword}
total revisions: 5; selected revisions: 1
description:
${log_rev2b}
${log_trailer}"
dotest log-r18a "${testcvs} rlog -r1.2.2.2 -r1.3:1.3 first-dir/file1" \
-"${rlog_header}
-${log_tags}
-${log_header2}
+"${rlog_header1}
+${log_tags1}
+${log_keyword}
total revisions: 5; selected revisions: 2
description:
${log_rev3}
@@ -15006,18 +15762,18 @@ ${log_rev2b}
${log_trailer}"
dotest log-r19 "${testcvs} rlog -rbranch. first-dir/file1" \
-"${rlog_header}
-${log_tags}
-${log_header2}
+"${rlog_header1}
+${log_tags1}
+${log_keyword}
total revisions: 5; selected revisions: 1
description:
${log_rev2b}
${log_trailer}"
dotest log-r20 "${testcvs} rlog -r1.2: first-dir/file1" \
-"${rlog_header}
-${log_tags}
-${log_header2}
+"${rlog_header1}
+${log_tags1}
+${log_keyword}
total revisions: 5; selected revisions: 2
description:
${log_rev3}
@@ -15025,18 +15781,18 @@ ${log_rev2}
${log_trailer}"
dotest log-r20a "${testcvs} rlog -r1.2:: first-dir/file1" \
-"${rlog_header}
-${log_tags}
-${log_header2}
+"${rlog_header1}
+${log_tags1}
+${log_keyword}
total revisions: 5; selected revisions: 1
description:
${log_rev3}
${log_trailer}"
dotest log-r21 "${testcvs} rlog -r:1.2 first-dir/file1" \
-"${rlog_header}
-${log_tags}
-${log_header2}
+"${rlog_header1}
+${log_tags1}
+${log_keyword}
total revisions: 5; selected revisions: 2
description:
${log_rev2}
@@ -15044,18 +15800,19 @@ ${log_rev1}
${log_trailer}"
dotest log-r21a "${testcvs} rlog -r::1.2 first-dir/file1" \
-"${rlog_header}
-${log_tags}
-${log_header2}
-total revisions: 5; selected revisions: 1
+"${rlog_header1}
+${log_tags1}
+${log_keyword}
+total revisions: 5; selected revisions: 2
description:
+${log_rev2}
${log_rev1}
${log_trailer}"
dotest log-r22 "${testcvs} rlog -r1.1:1.2 first-dir/file1" \
-"${rlog_header}
-${log_tags}
-${log_header2}
+"${rlog_header1}
+${log_tags1}
+${log_keyword}
total revisions: 5; selected revisions: 2
description:
${log_rev2}
@@ -15063,51 +15820,375 @@ ${log_rev1}
${log_trailer}"
dotest log-r22a "${testcvs} rlog -r1.1::1.2 first-dir/file1" \
-"${rlog_header}
-${log_tags}
-${log_header2}
-total revisions: 5; selected revisions: 0
+"${rlog_header1}
+${log_tags1}
+${log_keyword}
+total revisions: 5; selected revisions: 1
description:
+${log_rev2}
${log_trailer}"
dotest log-r22b "${testcvs} rlog -r1.1::1.3 first-dir/file1" \
-"${rlog_header}
-${log_tags}
+"${rlog_header1}
+${log_tags1}
+${log_keyword}
+total revisions: 5; selected revisions: 2
+description:
+${log_rev3}
+${log_rev2}
+${log_trailer}"
+
+ # Test when head is dead
+
+ dotest log-d0 "${testcvs} -q up -A" \
+"[UP] file1
+U file2"
+ dotest log-d1 "${testcvs} -q rm -f file1" \
+"${PROG} [a-z]*: use .${PROG} commit. to remove this file permanently"
+ dotest log-d2 "${testcvs} -q ci -m4" \
+"Removing file1;
+${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1
+new revision: delete; previous revision: 1\.3
+done"
+
+ log_header1="
+RCS file: ${CVSROOT_DIRNAME}/first-dir/Attic/file1,v
+Working file: file1
+head: 1\.4
+branch:
+locks: strict
+access list:"
+ rlog_header1="
+RCS file: ${CVSROOT_DIRNAME}/first-dir/Attic/file1,v
+head: 1\.4
+branch:
+locks: strict
+access list:"
+ log_header2="
+RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v
+Working file: file2
+head: 1\.3
+branch:
+locks: strict
+access list:"
+ rlog_header2="
+RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v
+head: 1\.3
+branch:
+locks: strict
+access list:"
+ log_tags2='symbolic names:
+ tag2: 1\.3
+ tag1: 1\.2'
+ log_rev4="${log_dash} 1\.4
+date: [0-9/]* [0-9:]*; author: ${username}; state: dead; lines: ${PLUS}0 -0
+4"
+ log_rev22="${log_dash} 1\.2
+${log_date}${log_lines}
+2"
+
+ dotest log-d3 "${testcvs} log -rbranch file1" \
+"${log_header1}
+${log_tags1}
+${log_keyword}
+total revisions: 6; selected revisions: 2
+description:
+${log_rev2b}
+${log_rev1b}
+${log_trailer}"
+ dotest log-rd3 "${testcvs} rlog -rbranch first-dir/file1" \
+"${rlog_header1}
+${log_tags1}
+${log_keyword}
+total revisions: 6; selected revisions: 2
+description:
+${log_rev2b}
+${log_rev1b}
+${log_trailer}"
+ dotest log-d4 "${testcvs} -q log -rbranch" \
+"${log_header1}
+${log_tags1}
+${log_keyword}
+total revisions: 6; selected revisions: 2
+description:
+${log_rev2b}
+${log_rev1b}
+${log_trailer}
+${PROG} [a-z]*: warning: no revision .branch. in .${CVSROOT_DIRNAME}/first-dir/file2,v.
${log_header2}
-total revisions: 5; selected revisions: 1
+${log_tags2}
+${log_keyword}
+total revisions: 3; selected revisions: 0
+description:
+${log_trailer}"
+ dotest log-d4a "${testcvs} -q log -t -rbranch" \
+"${log_header1}
+${log_tags1}
+${log_keyword}
+total revisions: 6
+description:
+${log_trailer}
+${PROG} [a-z]*: warning: no revision .branch. in .${CVSROOT_DIRNAME}/first-dir/file2,v.
+${log_header2}
+${log_tags2}
+${log_keyword}
+total revisions: 3
+description:
+${log_trailer}"
+ dotest log-d4b "${testcvs} -q log -tS -rbranch" \
+"${log_header1}
+${log_tags1}
+${log_keyword}
+total revisions: 6; selected revisions: 2
description:
+${log_trailer}
+${PROG} [a-z]*: warning: no revision .branch. in .${CVSROOT_DIRNAME}/first-dir/file2,v."
+ dotest log-d4c "${testcvs} -q log -h -rbranch" \
+"${log_header1}
+${log_tags1}
+${log_keyword}
+total revisions: 6
+${log_trailer}
+${PROG} [a-z]*: warning: no revision .branch. in .${CVSROOT_DIRNAME}/first-dir/file2,v.
+${log_header2}
+${log_tags2}
+${log_keyword}
+total revisions: 3
+${log_trailer}"
+ dotest log-d4d "${testcvs} -q log -hS -rbranch" \
+"${log_header1}
+${log_tags1}
+${log_keyword}
+total revisions: 6; selected revisions: 2
+${log_trailer}
+${PROG} [a-z]*: warning: no revision .branch. in .${CVSROOT_DIRNAME}/first-dir/file2,v."
+ dotest log-d4e "${testcvs} -q log -R -rbranch" \
+"${CVSROOT_DIRNAME}/first-dir/Attic/file1,v
+${CVSROOT_DIRNAME}/first-dir/file2,v"
+ dotest log-d4f "${testcvs} -q log -R -S -rbranch" \
+"${CVSROOT_DIRNAME}/first-dir/Attic/file1,v
+${PROG} [a-z]*: warning: no revision .branch. in .${CVSROOT_DIRNAME}/first-dir/file2,v."
+ dotest log-rd4 "${testcvs} -q rlog -rbranch first-dir" \
+"${rlog_header1}
+${log_tags1}
+${log_keyword}
+total revisions: 6; selected revisions: 2
+description:
+${log_rev2b}
+${log_rev1b}
+${log_trailer}
+${PROG} [a-z]*: warning: no revision .branch. in .${CVSROOT_DIRNAME}/first-dir/file2,v.
+${rlog_header2}
+${log_tags2}
+${log_keyword}
+total revisions: 3; selected revisions: 0
+description:
+${log_trailer}"
+ dotest log-rd4a "${testcvs} -q rlog -t -rbranch first-dir" \
+"${rlog_header1}
+${log_tags1}
+${log_keyword}
+total revisions: 6
+description:
+${log_trailer}
+${PROG} [a-z]*: warning: no revision .branch. in .${CVSROOT_DIRNAME}/first-dir/file2,v.
+${rlog_header2}
+${log_tags2}
+${log_keyword}
+total revisions: 3
+description:
+${log_trailer}"
+ dotest log-rd4b "${testcvs} -q rlog -St -rbranch first-dir" \
+"${rlog_header1}
+${log_tags1}
+${log_keyword}
+total revisions: 6; selected revisions: 2
+description:
+${log_trailer}
+${PROG} [a-z]*: warning: no revision .branch. in .${CVSROOT_DIRNAME}/first-dir/file2,v."
+ dotest log-rd4c "${testcvs} -q rlog -h -rbranch first-dir" \
+"${rlog_header1}
+${log_tags1}
+${log_keyword}
+total revisions: 6
+${log_trailer}
+${PROG} [a-z]*: warning: no revision .branch. in .${CVSROOT_DIRNAME}/first-dir/file2,v.
+${rlog_header2}
+${log_tags2}
+${log_keyword}
+total revisions: 3
+${log_trailer}"
+ dotest log-rd4d "${testcvs} -q rlog -Sh -rbranch first-dir" \
+"${rlog_header1}
+${log_tags1}
+${log_keyword}
+total revisions: 6; selected revisions: 2
+${log_trailer}
+${PROG} [a-z]*: warning: no revision .branch. in .${CVSROOT_DIRNAME}/first-dir/file2,v."
+ dotest log-rd4e "${testcvs} -q rlog -R -rbranch first-dir" \
+"${CVSROOT_DIRNAME}/first-dir/Attic/file1,v
+${CVSROOT_DIRNAME}/first-dir/file2,v"
+ dotest log-rd4f "${testcvs} -q rlog -R -S -rbranch first-dir" \
+"${CVSROOT_DIRNAME}/first-dir/Attic/file1,v
+${PROG} [a-z]*: warning: no revision .branch. in .${CVSROOT_DIRNAME}/first-dir/file2,v."
+ dotest log-d5 "${testcvs} log -r1.2.2.1:1.2.2.2 file1" \
+"${log_header1}
+${log_tags1}
+${log_keyword}
+total revisions: 6; selected revisions: 2
+description:
+${log_rev2b}
+${log_rev1b}
+${log_trailer}"
+ dotest log-rd5 "${testcvs} rlog -r1.2.2.1:1.2.2.2 first-dir/file1" \
+"${rlog_header1}
+${log_tags1}
+${log_keyword}
+total revisions: 6; selected revisions: 2
+description:
+${log_rev2b}
+${log_rev1b}
+${log_trailer}"
+ dotest log-d6 "${testcvs} -q log -r1.2.2.1:1.2.2.2" \
+"${log_header1}
+${log_tags1}
+${log_keyword}
+total revisions: 6; selected revisions: 2
+description:
+${log_rev2b}
+${log_rev1b}
+${log_trailer}
+${log_header2}
+${log_tags2}
+${log_keyword}
+total revisions: 3; selected revisions: 0
+description:
+${log_trailer}"
+ dotest log-rd6 "${testcvs} -q rlog -r1.2.2.1:1.2.2.2 first-dir" \
+"${rlog_header1}
+${log_tags1}
+${log_keyword}
+total revisions: 6; selected revisions: 2
+description:
+${log_rev2b}
+${log_rev1b}
+${log_trailer}
+${rlog_header2}
+${log_tags2}
+${log_keyword}
+total revisions: 3; selected revisions: 0
+description:
+${log_trailer}"
+ dotest log-d7 "${testcvs} log -r1.2:1.3 file1" \
+"${log_header1}
+${log_tags1}
+${log_keyword}
+total revisions: 6; selected revisions: 2
+description:
+${log_rev3}
+${log_rev2}
+${log_trailer}"
+ dotest log-rd7 "${testcvs} -q rlog -r1.2:1.3 first-dir/file1" \
+"${rlog_header1}
+${log_tags1}
+${log_keyword}
+total revisions: 6; selected revisions: 2
+description:
+${log_rev3}
${log_rev2}
${log_trailer}"
+ dotest log-d8 "${testcvs} -q log -rtag1:tag2" \
+"${PROG} [a-z]*: warning: no revision .tag1. in .${CVSROOT_DIRNAME}/first-dir/Attic/file1,v.
+${PROG} [a-z]*: warning: no revision .tag2. in .${CVSROOT_DIRNAME}/first-dir/Attic/file1,v.
+${log_header1}
+${log_tags1}
+${log_keyword}
+total revisions: 6; selected revisions: 0
+description:
+${log_trailer}
+${log_header2}
+${log_tags2}
+${log_keyword}
+total revisions: 3; selected revisions: 2
+description:
+${log_rev3}
+${log_rev22}
+${log_trailer}"
+ dotest log-d8a "${testcvs} -q log -rtag1:tag2 -S" \
+"${PROG} [a-z]*: warning: no revision .tag1. in .${CVSROOT_DIRNAME}/first-dir/Attic/file1,v.
+${PROG} [a-z]*: warning: no revision .tag2. in .${CVSROOT_DIRNAME}/first-dir/Attic/file1,v.
+${log_header2}
+${log_tags2}
+${log_keyword}
+total revisions: 3; selected revisions: 2
+description:
+${log_rev3}
+${log_rev22}
+${log_trailer}"
+ dotest log-rd8 "${testcvs} -q rlog -rtag1:tag2 first-dir" \
+"${PROG} [a-z]*: warning: no revision .tag1. in .${CVSROOT_DIRNAME}/first-dir/Attic/file1,v.
+${PROG} [a-z]*: warning: no revision .tag2. in .${CVSROOT_DIRNAME}/first-dir/Attic/file1,v.
+${rlog_header1}
+${log_tags1}
+${log_keyword}
+total revisions: 6; selected revisions: 0
+description:
+${log_trailer}
+${rlog_header2}
+${log_tags2}
+${log_keyword}
+total revisions: 3; selected revisions: 2
+description:
+${log_rev3}
+${log_rev22}
+${log_trailer}"
+ dotest log-rd8a "${testcvs} -q rlog -rtag1:tag2 -S first-dir" \
+"${PROG} [a-z]*: warning: no revision .tag1. in .${CVSROOT_DIRNAME}/first-dir/Attic/file1,v.
+${PROG} [a-z]*: warning: no revision .tag2. in .${CVSROOT_DIRNAME}/first-dir/Attic/file1,v.
+${rlog_header2}
+${log_tags2}
+${log_keyword}
+total revisions: 3; selected revisions: 2
+description:
+${log_rev3}
+${log_rev22}
+${log_trailer}"
+
+ dotest log-d99 "${testcvs} -q up -rbranch" \
+"[UP] file1
+${PROG} [a-z]*: file2 is no longer in the repository"
# Now test outdating revisions
dotest log-o0 "${testcvs} admin -o 1.2.2.2:: file1" \
-"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v
+"RCS file: ${CVSROOT_DIRNAME}/first-dir/Attic/file1,v
done"
dotest log-o1 "${testcvs} admin -o ::1.2.2.1 file1" \
-"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v
+"RCS file: ${CVSROOT_DIRNAME}/first-dir/Attic/file1,v
done"
dotest log-o2 "${testcvs} admin -o 1.2.2.1:: file1" \
-"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v
+"RCS file: ${CVSROOT_DIRNAME}/first-dir/Attic/file1,v
deleting revision 1\.2\.2\.2
done"
dotest log-o3 "${testcvs} log file1" \
-"${log_header}
-${log_tags}
-${log_header2}
-total revisions: 4; selected revisions: 4
+"${log_header1}
+${log_tags1}
+${log_keyword}
+total revisions: 5; selected revisions: 5
description:
+${log_rev4}
${log_rev3}
${log_rev2}
${log_rev1}
${log_rev1b}
${log_trailer}"
dotest log-ro3 "${testcvs} rlog first-dir/file1" \
-"${rlog_header}
-${log_tags}
-${log_header2}
-total revisions: 4; selected revisions: 4
+"${rlog_header1}
+${log_tags1}
+${log_keyword}
+total revisions: 5; selected revisions: 5
description:
+${log_rev4}
${log_rev3}
${log_rev2}
${log_rev1}
@@ -15115,6 +16196,7 @@ ${log_rev1b}
${log_trailer}"
dotest log-o4 "${testcvs} -q update -p -r 1.2.2.1 file1" \
"first branch revision"
+
cd ..
rm -r first-dir
rm -rf ${CVSROOT_DIRNAME}/first-dir
@@ -15364,7 +16446,8 @@ done"
# fairly bogus, but it is the longstanding behavior for
# whatever that is worth.
dotest ann-10 "${testcvs} ann" \
-"Annotations for file1
+"
+Annotations for file1
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
1\.1 (${username} *[0-9a-zA-Z-]*): this
1\.1 (${username} *[0-9a-zA-Z-]*): is
@@ -15376,7 +16459,8 @@ done"
1\.2 (${username} *[0-9a-zA-Z-]*): blank
1\.2 (${username} *[0-9a-zA-Z-]*): line"
dotest ann-11 "${testcvs} ann -r br" \
-"Annotations for file1
+"
+Annotations for file1
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
1\.1 (${username} *[0-9a-zA-Z-]*): this
1\.1 (${username} *[0-9a-zA-Z-]*): is
@@ -15392,7 +16476,8 @@ done"
# FIXCVS: shouldn't "-r 1.2.0.2" be the same as "-r br"?
dotest ann-12 "${testcvs} ann -r 1.2.0.2 file1" ""
dotest ann-13 "${testcvs} ann -r 1.2.2 file1" \
-"Annotations for file1
+"
+Annotations for file1
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
1\.1 (${username} *[0-9a-zA-Z-]*): this
1\.1 (${username} *[0-9a-zA-Z-]*): is
@@ -15413,7 +16498,8 @@ done"
cd ../..
rm -r 1
dotest ann-r10 "${testcvs} rann first-dir" \
-"Annotations for first-dir/file1
+"
+Annotations for first-dir/file1
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
1\.1 (${username} *[0-9a-zA-Z-]*): this
1\.1 (${username} *[0-9a-zA-Z-]*): is
@@ -15425,7 +16511,8 @@ done"
1\.2 (${username} *[0-9a-zA-Z-]*): blank
1\.2 (${username} *[0-9a-zA-Z-]*): line"
dotest ann-r11 "${testcvs} rann -r br first-dir" \
-"Annotations for first-dir/file1
+"
+Annotations for first-dir/file1
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
1\.1 (${username} *[0-9a-zA-Z-]*): this
1\.1 (${username} *[0-9a-zA-Z-]*): is
@@ -15440,7 +16527,8 @@ done"
1\.2\.2\.1 (${username} *[0-9a-zA-Z-]*): branched content"
dotest ann-r12 "${testcvs} rann -r 1.2.0.2 first-dir/file1" ""
dotest ann-r13 "${testcvs} rann -r 1.2.2 first-dir/file1" \
-"Annotations for first-dir/file1
+"
+Annotations for first-dir/file1
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
1\.1 (${username} *[0-9a-zA-Z-]*): this
1\.1 (${username} *[0-9a-zA-Z-]*): is
@@ -15496,7 +16584,8 @@ done"
# The version number after $file,v should be `1.2'.
# 1.9.28.1 puts `1.1' there.
dotest ann-id-6 "$testcvs -Q ann $file" \
-"Annotations for $file
+"
+Annotations for $file
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
1.2 ($username *[0-9a-zA-Z-]*): "'\$'"Id: $file,v 1.1 [0-9/]* [0-9:]* $username Exp "'\$'"
1.2 ($username *[0-9a-zA-Z-]*): line2"
@@ -15594,36 +16683,41 @@ ${testcvs} -d ${TESTDIR}/crerepos release -d CVSROOT >>${LOGFILE}; then
# manner of things and the server better protect itself.
dotest_fail crerepos-6a-r \
"${testcvs} -q -d :ext:`hostname`:../crerepos get ." \
-"${PROG} [a-z]*: CVSROOT (\":ext:${hostname}:\.\./crerepos\")
-${PROG} [a-z]*: 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\."
+"${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: .: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 (\":ext:${hostname}:crerepos\")
-${PROG} [a-z]*: requires a path spec
+"${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\."
+${PROG} \[[a-z]* aborted\]: Bad CVSROOT: .:ext:${hostname}:crerepos.\."
cd ..
rm -r 1
else # local
# Test that CVS rejects a relative path in CVSROOT.
+
mkdir 1; cd 1
- # piping the output of this test to /dev/null since we have no way of knowing
- # what error messages different rsh implementations will output.
- dotest_fail crerepos-6a "${testcvs} -q -d ../crerepos get . >/dev/null 2>&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-6a "CVS_RSH=false ${testcvs} -q -d ../crerepos get ." \
+"$PROG \[[a-z]* aborted\]: end of file from server (consult above messages if any)" \
+"$PROG \[[a-z]* aborted\]: received broken pipe signal"
cd ..
rm -r 1
mkdir 1; cd 1
dotest_fail crerepos-6b "${testcvs} -d crerepos init" \
-"${PROG} [a-z]*: CVSROOT \"crerepos\" must be an absolute pathname
-${PROG} \[[a-z]* aborted\]: Bad CVSROOT\."
+"${PROG} [a-z]*: CVSROOT must be an absolute pathname (not .crerepos.)
+${PROG} [a-z]*: when using local access method\.
+${PROG} \[[a-z]* aborted\]: Bad CVSROOT: .crerepos.\."
cd ..
rm -r 1
fi # end of tests to be skipped for remote
@@ -15877,7 +16971,8 @@ add file1
# last two digits of the year. Make sure it does that rather
# than some bogosity like "100".
dotest rcs-4a "${testcvs} annotate file1" \
-"Annotations for file1
+"
+Annotations for file1
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
1\.1 (kingdon 24-Nov-96): This is the first line
1\.2 (kingdon 24-Nov-96): This is the third line
@@ -16255,7 +17350,7 @@ EOF
#
# Hmm, if this test is run on the 31st of the month, and 100
# months from now is a month with only 30 days (e.g. run on
- # 31 May 1999), it seems to fail.
+ # 31 May 1999, 31 May 2001), it seems to fail.
#
# Sigh.
dotest rcs2-7 "${testcvs} -q update -p -D '100 months' file1" \
@@ -17518,8 +18613,7 @@ U file2"
# Now try with a numeric revision.
dotest sticky-21 "${testcvs} -q update -r 1.1 file1" "U file1"
- rm file1
- dotest sticky-22 "${testcvs} rm file1" \
+ dotest sticky-22 "${testcvs} rm -f file1" \
"${PROG} [a-z]*: cannot remove file .file1. which has a numeric sticky tag of .1\.1."
# The old behavior was that remove allowed this and then commit
# gave an error, which was somewhat hard to clear. I mean, you
@@ -17528,11 +18622,19 @@ U file2"
# why CVS should have a concept of conflict that arises, not from
# parallel development, but from CVS's own sticky tags.
+ # Ditto with a sticky date.
+ #
# I'm kind of surprised that the "file1 was lost" doesn't crop
# up elsewhere in the testsuite. It is a long-standing
# discrepency between local and remote CVS and should probably
# be cleaned up at some point.
- dotest sticky-23 "${testcvs} -q update -A" \
+ dotest sticky-23 "${testcvs} -q update -Dnow file1" \
+"${PROG} [a-z]*: warning: file1 was lost
+U file1" "U file1"
+ dotest sticky-24 "${testcvs} rm -f file1" \
+"${PROG} [a-z]*: cannot remove file .file1. which has a sticky date of .[0-9.]*."
+
+ dotest sticky-25 "${testcvs} -q update -A" \
"${PROG} [a-z]*: warning: file1 was lost
U file1" "U file1"
@@ -17923,7 +19025,8 @@ xx"
# The same issue occurs with annotate and other keywords,
# I think, although it is particularly noticeable for $Log.
dotest keywordlog-22 "${testcvs} ann -r br file1" \
-"Annotations for file1
+"
+Annotations for file1
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
1\.3 (${username} *[0-9a-zA-Z-]*): initial
1\.4\.2\.1 (${username} *[0-9a-zA-Z-]*): xx "'\$'"Log: file1,v "'\$'"
@@ -17933,7 +19036,8 @@ xx"
1\.4\.2\.1 (${username} *[0-9a-zA-Z-]*): xx
1\.4\.2\.1 (${username} *[0-9a-zA-Z-]*): br-change"
dotest keywordlog-23 "${testcvs} ann -r HEAD file1" \
-"Annotations for file1
+"
+Annotations for file1
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
1\.3 (${username} *[0-9a-zA-Z-]*): initial
1\.5 (${username} *[0-9a-zA-Z-]*): xx "'\$'"Log: file1,v "'\$'"
@@ -18396,12 +19500,14 @@ done"
# Now for annotate
cd ../1/first-dir
dotest tagdate-16 "${testcvs} annotate -rbr2 -D'1 minute ago'" \
-"Annotations for file1
+"
+Annotations for file1
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
1\.1\.4\.1 (${username} *[0-9a-zA-Z-]*): br2-1"
dotest tagdate-17 "${testcvs} annotate -rbr2 -Dnow" \
-"Annotations for file1
+"
+Annotations for file1
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
1\.1\.4\.2 (${username} *[0-9a-zA-Z-]*): br2-2"
@@ -19601,6 +20707,7 @@ ${PROG} \[[a-z]* aborted\]: Revision 1\.1 is already locked by fred"
dotest reserved-14 "${testcvs} admin -u1.1 a-lock" \
"RCS file: ${CVSROOT_DIRNAME}/first-dir/a-lock,v
+${PROG} [a-z]*: ${CVSROOT_DIRNAME}/first-dir/a-lock,v: revision 1\.1 locked by fred; breaking lock
1\.1 unlocked
done"
dotest reserved-15 "${testcvs} -q ci -m success a-lock" \
@@ -21856,13 +22963,22 @@ ${PROG} server: Updating dir1/sdir/ssdir"
# messages are subject to out-of-order bugs (this one is hard
# to work around).
if $remote; then :; else
- dotest multiroot2-9 "${testcvs} -t update" \
-" -> main loop with CVSROOT=${TESTDIR}/root1
+ dotest multiroot2-9a "${testcvs} -t update" \
+" *-> main loop with CVSROOT=${TESTDIR}/root1
${PROG} update: Updating \.
+ *-> Reader_Lock(${TESTDIR}/root1)
+ *-> Lock_Cleanup()
${PROG} update: Updating dir1
- -> main loop with CVSROOT=${TESTDIR}/root2
+ *-> Reader_Lock(${TESTDIR}/root1/dir1)
+ *-> Lock_Cleanup()
+ *-> main loop with CVSROOT=${TESTDIR}/root2
${PROG} update: Updating dir1/sdir
-${PROG} update: Updating dir1/sdir/ssdir"
+ *-> Reader_Lock(${TESTDIR}/root2/sdir)
+ *-> Lock_Cleanup()
+${PROG} update: Updating dir1/sdir/ssdir
+ *-> Reader_Lock(${TESTDIR}/root2/sdir/ssdir)
+ *-> Lock_Cleanup()
+ *-> Lock_Cleanup()"
fi
dotest multiroot2-9 "${testcvs} -q tag tag1" \
@@ -22340,6 +23456,32 @@ 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}\"
+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}
+testme
+Ay::'d
+END AUTH REQUEST
+init xxx
+EOF
+ dotest_fail pserver-5d "test -d xxx" ''
+
dotest_fail pserver-6 "${testcvs} --allow-root=${CVSROOT_DIRNAME} pserver" \
"I HATE YOU" <<EOF
BEGIN AUTH REQUEST
@@ -22419,6 +23561,251 @@ Amquiteunabletocomeupwithinterestingpasswordsanymore
END AUTH REQUEST
EOF
+ # The following tests are for read-only access
+
+ # Check that readers can only read, everyone else can write
+
+ cat >${CVSROOT_DIRNAME}/CVSROOT/readers <<EOF
+anonymous
+EOF
+
+ dotest pserver-14 "${testcvs} --allow-root=${CVSROOT_DIRNAME} pserver" \
+"${DOTSTAR} LOVE YOU
+M Concurrent Versions System (CVS) .*
+ok" <<EOF
+BEGIN AUTH REQUEST
+${CVSROOT_DIRNAME}
+anonymous
+Ay::'d
+END AUTH REQUEST
+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) .*
+ok" <<EOF
+BEGIN AUTH REQUEST
+${CVSROOT_DIRNAME}
+testme
+Ay::'d
+END AUTH REQUEST
+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) .*
+ok" <<EOF
+BEGIN AUTH REQUEST
+${CVSROOT_DIRNAME}
+${username}
+Ay::'d
+END AUTH REQUEST
+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
+
+ cat >${CVSROOT_DIRNAME}/CVSROOT/writers <<EOF
+testme
+EOF
+
+ dotest pserver-20 "${testcvs} --allow-root=${CVSROOT_DIRNAME} pserver" \
+"${DOTSTAR} LOVE YOU
+M Concurrent Versions System (CVS) .*
+ok" <<EOF
+BEGIN AUTH REQUEST
+${CVSROOT_DIRNAME}
+anonymous
+Ay::'d
+END AUTH REQUEST
+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) .*
+ok" <<EOF
+BEGIN AUTH REQUEST
+${CVSROOT_DIRNAME}
+testme
+Ay::'d
+END AUTH REQUEST
+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) .*
+ok" <<EOF
+BEGIN AUTH REQUEST
+${CVSROOT_DIRNAME}
+${username}
+Ay::'d
+END AUTH REQUEST
+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
+
+ dotest pserver-26 "${testcvs} --allow-root=${CVSROOT_DIRNAME} pserver" \
+"${DOTSTAR} LOVE YOU
+M Concurrent Versions System (CVS) .*
+ok" <<EOF
+BEGIN AUTH REQUEST
+${CVSROOT_DIRNAME}
+anonymous
+Ay::'d
+END AUTH REQUEST
+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) .*
+ok" <<EOF
+BEGIN AUTH REQUEST
+${CVSROOT_DIRNAME}
+testme
+Ay::'d
+END AUTH REQUEST
+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) .*
+ok" <<EOF
+BEGIN AUTH REQUEST
+${CVSROOT_DIRNAME}
+${username}
+Ay::'d
+END AUTH REQUEST
+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" \
+"$PROG \[pserver aborted\]: bad auth protocol start: EOF" </dev/null
+
# Clean up.
echo "# comments only" >config
dotest pserver-cleanup-1 "${testcvs} -q ci -m config-it" \
@@ -22429,7 +23816,7 @@ done
${PROG} [a-z]*: Rebuilding administrative file database"
cd ../..
rm -r 1
- rm ${CVSROOT_DIRNAME}/CVSROOT/passwd
+ rm ${CVSROOT_DIRNAME}/CVSROOT/passwd ${CVSROOT_DIRNAME}/CVSROOT/writers
fi # skip the whole thing for local
;;
diff --git a/contrib/cvs/src/server.c b/contrib/cvs/src/server.c
index bb38f4d..76b5008 100644
--- a/contrib/cvs/src/server.c
+++ b/contrib/cvs/src/server.c
@@ -59,7 +59,10 @@ int cvs_gssapi_encrypt;
#endif
#ifdef HAVE_SYSLOG_H
-#include <syslog.h>
+# include <syslog.h>
+# ifndef LOG_DAEMON /* for ancient syslogs */
+# define LOG_DAEMON 0
+# endif
#endif
#ifdef HAVE_KERBEROS
@@ -159,7 +162,7 @@ static int fd_buffer_input PROTO((void *, char *, int, int, int *));
static int fd_buffer_output PROTO((void *, const char *, int, int *));
static int fd_buffer_flush PROTO((void *));
static int fd_buffer_block PROTO((void *, int));
-static int fd_buffer_shutdown PROTO((void *));
+static int fd_buffer_shutdown PROTO((struct buffer *));
/* Initialize a buffer built on a file descriptor. FD is the file
descriptor. INPUT is nonzero if this is for input, zero if this is
@@ -321,10 +324,10 @@ fd_buffer_block (closure, block)
/* The buffer shutdown function for a buffer built on a file descriptor. */
static int
-fd_buffer_shutdown (closure)
- void *closure;
+fd_buffer_shutdown (buf)
+ struct buffer *buf;
{
- free (closure);
+ free (buf->closure);
return 0;
}
@@ -360,7 +363,7 @@ create_adm_p (base_dir, dir)
if (tmp == NULL)
return ENOMEM;
-
+
/* We make several passes through this loop. On the first pass,
we simply create the CVSADM directory in the deepest directory.
For each subsequent pass, we try to remove the last path
@@ -423,8 +426,7 @@ create_adm_p (base_dir, dir)
}
(void) umask (omask);
}
-
-
+
f = CVS_FOPEN (tmp, "w");
if (f == NULL)
{
@@ -731,7 +733,7 @@ serve_root (arg)
{
char *env;
char *path;
-
+
if (error_pending()) return;
if (!isabsolute (arg))
@@ -769,12 +771,11 @@ serve_root (arg)
sprintf (pending_error_text, "\
E Protocol error: Root says \"%s\" but pserver says \"%s\"",
arg, Pserver_Repos);
+ return;
}
}
#endif
- if (current_parsed_root != NULL)
- free_cvsroot_t (current_parsed_root);
current_parsed_root = local_cvsroot (arg);
/* For pserver, this will already have happened, and the call will do
@@ -912,7 +913,7 @@ E protocol error: directory '%s' not within current directory",
}
return 0;
}
-
+
/*
* Add as many directories to the temp directory as the client tells us it
* will use "..", so we never try to access something outside the temp
@@ -1001,7 +1002,7 @@ dirswitch (dir, repos)
pending_error = ENOMEM;
return;
}
-
+
strcpy (dir_name, server_temp_dir);
strcat (dir_name, "/");
strcat (dir_name, dir);
@@ -2118,9 +2119,9 @@ serve_argument (arg)
char *arg;
{
char *p;
-
+
if (error_pending()) return;
-
+
if (argument_vector_size <= argument_count)
{
argument_vector_size *= 2;
@@ -2148,9 +2149,9 @@ serve_argumentx (arg)
char *arg;
{
char *p;
-
+
if (error_pending()) return;
-
+
p = argument_vector[argument_count - 1];
p = realloc (p, strlen (p) + 1 + strlen (arg) + 1);
if (p == NULL)
@@ -2472,7 +2473,7 @@ check_command_legal_p (cmd_name)
size_t flen;
FILE *fp;
int found_it = 0;
-
+
/* else */
flen = strlen (current_parsed_root->directory)
+ strlen (CVSROOTADM)
@@ -2564,7 +2565,7 @@ check_command_legal_p (cmd_name)
/* Chop newline by hand, for strcmp()'s sake. */
if (linebuf[num_red - 1] == '\n')
linebuf[num_red - 1] = '\0';
-
+
if (strcmp (linebuf, CVS_Username) == 0)
{
found_it = 1;
@@ -2631,7 +2632,7 @@ do_cvs_command (cmd_name, command)
* interleaved with data from stdout_pipe or stderr_pipe).
*/
int protocol_pipe[2];
-
+
int dev_null_fd = -1;
int errs;
@@ -3010,7 +3011,7 @@ error \n");
{
int status;
int count_read;
-
+
status = buf_input_data (protocol_inbuf, &count_read);
if (status == -1)
@@ -3168,7 +3169,7 @@ error \n");
*/
continue;
}
-
+
if (WIFEXITED (status))
errs += WEXITSTATUS (status);
else
@@ -3295,7 +3296,7 @@ server_pause_check()
FD_ZERO (&fds);
FD_SET (flowcontrol_pipe[0], &fds);
numtocheck = flowcontrol_pipe[0] + 1;
-
+
do {
numfds = select (numtocheck, &fds, (fd_set *)0,
(fd_set *)0, (struct timeval *)NULL);
@@ -3307,7 +3308,7 @@ server_pause_check()
return;
}
} while (numfds < 0);
-
+
if (FD_ISSET (flowcontrol_pipe[0], &fds))
{
int got;
@@ -3430,7 +3431,7 @@ server_register (name, version, timestamp, options, tag, date, conflict)
len += strlen (tag);
if (date)
len += strlen (date);
-
+
entries_line = xmalloc (len);
sprintf (entries_line, "/%s/%s/", name, version);
if (conflict != NULL)
@@ -3665,7 +3666,7 @@ static void
serve_tag (arg)
char *arg;
{
- do_cvs_command ("cvstag", cvstag);
+ do_cvs_command ("tag", cvstag);
}
static void
@@ -3790,20 +3791,38 @@ 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 Root %s must be an absolute pathname", arg);
- /* Fall through to do_cvs_command which will return the
- actual error. */
+ "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 (current_parsed_root != NULL)
- free_cvsroot_t (current_parsed_root);
- current_parsed_root = local_cvsroot (arg);
+ 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 *));
@@ -4567,7 +4586,6 @@ serve_expand_modules (arg)
DBM *db;
err = 0;
- server_expanding = 1;
db = open_module ();
for (i = 1; i < argument_count; i++)
err += do_module (db, argument_vector[i],
@@ -4575,7 +4593,6 @@ serve_expand_modules (arg)
NULL, 0, 0, 0, 0,
(char *) NULL);
close_module (db);
- server_expanding = 0;
{
/* argument_vector[0] is a dummy argument, we don't mess with it. */
char **cp;
@@ -4605,23 +4622,24 @@ server_prog (dir, name, which)
{
if (!supported_response ("Set-checkin-prog"))
{
- buf_output0 (buf_to_net, "E \
+ buf_output0 (protocol, "E \
warning: this client does not support -i or -u flags in the modules file.\n");
return;
}
switch (which)
{
case PROG_CHECKIN:
- buf_output0 (buf_to_net, "Set-checkin-prog ");
+ buf_output0 (protocol, "Set-checkin-prog ");
break;
case PROG_UPDATE:
- buf_output0 (buf_to_net, "Set-update-prog ");
+ buf_output0 (protocol, "Set-update-prog ");
break;
}
- buf_output0 (buf_to_net, dir);
- buf_append_char (buf_to_net, '\n');
- buf_output0 (buf_to_net, name);
- buf_append_char (buf_to_net, '\n');
+ buf_output0 (protocol, dir);
+ buf_append_char (protocol, '\n');
+ buf_output0 (protocol, name);
+ buf_append_char (protocol, '\n');
+ buf_send_counted (protocol);
}
static void
@@ -4855,32 +4873,33 @@ server_cleanup (sig)
if (buf_to_net != NULL)
{
- /* FIXME: If this is not the final call from server, this
- could deadlock, because the client might be blocked writing
- to us. This should not be a problem in practice, because
- we do not generate much output when the client is not
- waiting for it. */
+ /* Since we're done, go ahead and put BUF_TO_NET back into blocking
+ * mode and send any pending output. In the usual case there won't
+ * won't be any, but there might be if an error occured.
+ */
+
set_block (buf_to_net);
buf_flush (buf_to_net, 1);
- /* The calls to buf_shutdown are currently only meaningful
- when we are using compression. First we shut down
- BUF_FROM_NET. That will pick up the checksum generated
- when the client shuts down its buffer. Then, after we have
- generated any final output, we shut down BUF_TO_NET. */
+ /* Next we shut down BUF_FROM_NET. That will pick up the checksum
+ * generated when the client shuts down its buffer. Then, after we
+ * have generated any final output, we shut down BUF_TO_NET.
+ */
status = buf_shutdown (buf_from_net);
if (status != 0)
{
error (0, status, "shutting down buffer from client");
- buf_flush (buf_to_net, 1);
}
}
if (dont_delete_temp)
{
if (buf_to_net != NULL)
+ {
+ (void) buf_flush (buf_to_net, 1);
(void) buf_shutdown (buf_to_net);
+ }
return;
}
@@ -4978,11 +4997,13 @@ server_cleanup (sig)
noexec = save_noexec;
if (buf_to_net != NULL)
+ {
+ (void) buf_flush (buf_to_net, 1);
(void) buf_shutdown (buf_to_net);
+ }
}
int server_active = 0;
-int server_expanding = 0;
int
server (argc, argv)
@@ -5003,7 +5024,7 @@ server (argc, argv)
buf_to_net = fd_buffer_initialize (STDOUT_FILENO, 0,
outbuf_memory_error);
- buf_from_net = stdio_buffer_initialize (stdin, 1, outbuf_memory_error);
+ buf_from_net = stdio_buffer_initialize (stdin, 0, 1, outbuf_memory_error);
saved_output = buf_nonio_initialize (outbuf_memory_error);
saved_outerr = buf_nonio_initialize (outbuf_memory_error);
@@ -5183,7 +5204,7 @@ error ENOMEM Virtual memory exhausted.\n");
char *cmd, *orig_cmd;
struct request *rq;
int status;
-
+
status = buf_read_line (buf_from_net, &cmd, (int *) NULL);
if (status == -2)
{
@@ -5320,7 +5341,7 @@ error 0 %s: no such user\n", username);
error_exit ();
}
}
-
+
if (setuid (pw->pw_uid) < 0)
{
/* Note that this means that if run as a non-root user,
@@ -5344,12 +5365,12 @@ error 0 %s: no such user\n", username);
if (CVS_Username == NULL)
CVS_Username = xstrdup (username);
#endif
-
+
#if HAVE_PUTENV
/* Set LOGNAME, USER and CVS_USER in the environment, in case they
are already set to something else. */
{
- char *env, *cvs_user;
+ char *env;
env = xmalloc (sizeof "LOGNAME=" + strlen (username));
(void) sprintf (env, "LOGNAME=%s", username);
@@ -5359,10 +5380,11 @@ error 0 %s: no such user\n", username);
(void) sprintf (env, "USER=%s", username);
(void) putenv (env);
- cvs_user = NULL != CVS_Username ? CVS_Username : "";
- env = xmalloc (sizeof "CVS_USER=" + strlen (cvs_user));
- (void) sprintf (env, "CVS_USER=%s", cvs_user);
+#ifdef AUTH_SERVER_SUPPORT
+ env = xmalloc (sizeof "CVS_USER=" + strlen (CVS_Username));
+ (void) sprintf (env, "CVS_USER=%s", CVS_Username);
(void) putenv (env);
+#endif
}
#endif /* HAVE_PUTENV */
}
@@ -5373,7 +5395,7 @@ error 0 %s: no such user\n", username);
extern char *crypt PROTO((const char *, const char *));
-/*
+/*
* 0 means no entry found for this user.
* 1 means entry found and password matches (or found password is empty)
* 2 means entry found, but password does not match.
@@ -5442,7 +5464,7 @@ check_repository_password (username, password, repository, host_user_ptr)
char *found_password, *host_user_tmp;
char *non_cvsuser_portion;
- /* We need to make sure lines such as
+ /* We need to make sure lines such as
*
* "username::sysuser\n"
* "username:\n"
@@ -5572,7 +5594,7 @@ check_password (username, password, repository)
{
found_passwd = pw->pw_passwd;
}
-
+
if (found_passwd == NULL)
{
printf ("E Fatal error, aborting.\n\
@@ -5590,7 +5612,7 @@ error 0 %s: no such user\n", username);
exit (EXIT_FAILURE);
}
-
+
if (*found_passwd)
{
/* user exists and has a password */
@@ -5645,7 +5667,7 @@ error 0 %s: no such user\n", username);
handle_return:
if (host_user)
{
- /* Set CVS_Username here, in allocated space.
+ /* Set CVS_Username here, in allocated space.
It might or might not be the same as host_user. */
CVS_Username = xmalloc (strlen (username) + 1);
strcpy (CVS_Username, username);
@@ -5739,10 +5761,12 @@ pserver_authenticate_connection ()
/* Make sure the protocol starts off on the right foot... */
if (getline_safe (&tmp, &tmp_allocated, stdin, PATH_MAX) < 0)
- /* FIXME: what? We could try writing error/eof, but chances
- are the network connection is dead bidirectionally. log it
- somewhere? */
- ;
+ {
+#ifdef HAVE_SYSLOG_H
+ syslog (LOG_DAEMON | LOG_NOTICE, "bad auth protocol start: EOF");
+#endif
+ error (1, 0, "bad auth protocol start: EOF");
+ }
if (strcmp (tmp, "BEGIN VERIFICATION REQUEST\n") == 0)
verify_and_exit = 1;
@@ -5773,7 +5797,7 @@ pserver_authenticate_connection ()
getline_safe (&username, &username_allocated, stdin, PATH_MAX);
getline_safe (&password, &password_allocated, stdin, PATH_MAX);
- /* Make them pure. */
+ /* Make them pure. */
strip_trailing_newlines (repository);
strip_trailing_newlines (username);
strip_trailing_newlines (password);
@@ -5807,8 +5831,6 @@ pserver_authenticate_connection ()
/* We need the real cleartext before we hash it. */
descrambled_password = descramble (password);
host_user = check_password (username, descrambled_password, repository);
- memset (descrambled_password, 0, strlen (descrambled_password));
- free (descrambled_password);
if (host_user == NULL)
{
#ifdef HAVE_SYSLOG_H
@@ -5818,6 +5840,8 @@ pserver_authenticate_connection ()
username, descrambled_password, repository);
#endif
#endif
+ memset (descrambled_password, 0, strlen (descrambled_password));
+ free (descrambled_password);
i_hate_you:
printf ("I HATE YOU\n");
fflush (stdout);
@@ -5826,6 +5850,8 @@ pserver_authenticate_connection ()
yet. */
error_exit ();
}
+ memset (descrambled_password, 0, strlen (descrambled_password));
+ free (descrambled_password);
/* Don't go any farther if we're just responding to "cvs login". */
if (verify_and_exit)
@@ -6511,7 +6537,7 @@ cvs_flusherr ()
{
/* make sure stderr is flushed before we send the flush count on the
* protocol pipe
- */
+ */
fflush (stderr);
/* Send a special count to tell the parent to flush. */
buf_send_special_count (protocol, -2);
@@ -6541,7 +6567,7 @@ cvs_flushout ()
main.c, didn't get called in the server child process. But
in the future it is quite plausible that we'll want to make
this case work analogously to cvs_flusherr.
-
+
FIXME - DRP - I tried to implement this and triggered the following
error: "Protocol error: uncounted data discarded". I don't need
this feature right now, so I'm not going to bother with it yet.
diff --git a/contrib/cvs/src/server.h b/contrib/cvs/src/server.h
index caeff8a..31f23d51 100644
--- a/contrib/cvs/src/server.h
+++ b/contrib/cvs/src/server.h
@@ -24,7 +24,6 @@
* server-specific functions.
*/
extern int server_active;
-extern int server_expanding;
/* Server functions exported to the rest of CVS. */
diff --git a/contrib/cvs/src/subr.c b/contrib/cvs/src/subr.c
index 8211a77..75f26cb 100644
--- a/contrib/cvs/src/subr.c
+++ b/contrib/cvs/src/subr.c
@@ -123,7 +123,7 @@ expand_string (strptr, n, newsize)
/* *STR is a pointer to a malloc'd string. *LENP is its allocated
length. Add SRC to the end of it, reallocating if necessary. */
void
-allocate_and_strcat (str, lenp, src)
+xrealloc_and_strcat (str, lenp, src)
char **str;
size_t *lenp;
const char *src;
@@ -742,9 +742,6 @@ resolve_symlink (filename)
But that would require editing each filesubr.c and so the
expedient hack seems to be looking at HAVE_READLINK. */
newname = xreadlink (*filename);
-#else
- error (1, 0, "internal error: islink doesn't like readlink");
-#endif
if (isabsolute (newname))
{
@@ -762,6 +759,9 @@ resolve_symlink (filename)
free (*filename);
*filename = fullnewname;
}
+#else
+ error (1, 0, "internal error: islink doesn't like readlink");
+#endif
}
}
diff --git a/contrib/cvs/src/tag.c b/contrib/cvs/src/tag.c
index a2883c8..0b93e09 100644
--- a/contrib/cvs/src/tag.c
+++ b/contrib/cvs/src/tag.c
@@ -40,7 +40,7 @@ static char *date = NULL;
static char *symtag; /* tag to add or delete */
static int delete_flag; /* adding a tag by default */
static int branch_mode; /* make an automagic "branch" tag */
-static int local; /* recursive by default */
+static int disturb_branch_tags = 0; /* allow -F,-d to disturb branch tags */
static int force_tag_match = 1; /* force tag to match by default */
static int force_tag_move; /* don't force tag to move by default */
static int check_uptodate; /* no uptodate-check by default */
@@ -63,12 +63,13 @@ struct master_lists
static List *mtlist;
static List *tlist;
-static const char rtag_opts[] = "+abdFflnQqRr:D:";
+static const char rtag_opts[] = "+aBbdFflnQqRr:D:";
static const char *const rtag_usage[] =
{
"Usage: %s %s [-abdFflnR] [-r rev|-D date] tag modules...\n",
"\t-a\tClear tag from removed files that would not otherwise be tagged.\n",
"\t-b\tMake the tag a \"branch\" tag, allowing concurrent development.\n",
+ "\t-B\tAllows -F and -d to disturb branch tags. Use with extreme care.\n",
"\t-d\tDelete the given tag.\n",
"\t-F\tMove tag if it already exists.\n",
"\t-f\tForce a head revision match if tag/date not found.\n",
@@ -81,11 +82,12 @@ static const char *const rtag_usage[] =
NULL
};
-static const char tag_opts[] = "+bcdFflQqRr:D:";
+static const char tag_opts[] = "+BbcdFflQqRr:D:";
static const char *const tag_usage[] =
{
"Usage: %s %s [-bcdFflR] [-r rev|-D date] tag [files...]\n",
"\t-b\tMake the tag a \"branch\" tag, allowing concurrent development.\n",
+ "\t-B\tAllows -F and -d to disturb branch tags. Use with extreme care.\n",
"\t-c\tCheck that working files are unmodified.\n",
"\t-d\tDelete the given tag.\n",
"\t-F\tMove tag if it already exists.\n",
@@ -103,6 +105,7 @@ cvstag (argc, argv)
int argc;
char **argv;
{
+ int local = 0; /* recursive by default */
int c;
int err = 0;
int run_module_prog = 1;
@@ -123,6 +126,9 @@ cvstag (argc, argv)
case 'b':
branch_mode = 1;
break;
+ case 'B':
+ disturb_branch_tags = 1;
+ break;
case 'c':
check_uptodate = 1;
break;
@@ -196,6 +202,8 @@ cvstag (argc, argv)
send_arg("-a");
if (branch_mode)
send_arg("-b");
+ if (disturb_branch_tags)
+ send_arg("-B");
if (check_uptodate)
send_arg("-c");
if (delete_flag)
@@ -252,14 +260,14 @@ cvstag (argc, argv)
(date ? date : "A"))), symtag, argv[i], "");
err += do_module (db, argv[i], TAG,
delete_flag ? "Untagging" : "Tagging",
- rtag_proc, (char *) NULL, 0, 0, run_module_prog,
+ rtag_proc, (char *) NULL, 0, local, run_module_prog,
0, symtag);
}
close_module (db);
}
else
{
- err = rtag_proc (argc + 1, argv - 1, NULL, NULL, NULL, 0, 0, NULL,
+ err = rtag_proc (argc + 1, argv - 1, NULL, NULL, NULL, 0, local, NULL,
NULL);
}
@@ -362,7 +370,7 @@ rtag_proc (argc, argv, xwhere, mwhere, mfile, shorten, local_specified,
if (numtag != NULL && !numtag_validated)
{
- tag_check_valid (numtag, argc - 1, argv + 1, local, 0, repository);
+ tag_check_valid (numtag, argc - 1, argv + 1, local_specified, 0, repository);
numtag_validated = 1;
}
@@ -372,7 +380,7 @@ rtag_proc (argc, argv, xwhere, mwhere, mfile, shorten, local_specified,
mtlist = getlist();
err = start_recursion (check_fileproc, check_filesdoneproc,
(DIRENTPROC) NULL, (DIRLEAVEPROC) NULL, NULL,
- argc - 1, argv + 1, local, which, 0, 1,
+ argc - 1, argv + 1, local_specified, which, 0, 1,
where, 1);
if (err)
@@ -387,13 +395,13 @@ rtag_proc (argc, argv, xwhere, mwhere, mfile, shorten, local_specified,
cached in do_recursion isn't stale by the time we get around
to using it to rewrite the RCS file in the callback, and this
is the easiest way to accomplish that. */
- lock_tree_for_write (argc - 1, argv + 1, local, which, 0);
+ lock_tree_for_write (argc - 1, argv + 1, local_specified, which, 0);
/* start the recursion processor */
err = start_recursion (is_rtag ? rtag_fileproc : tag_fileproc,
(FILESDONEPROC) NULL, tag_dirproc,
(DIRLEAVEPROC) NULL, NULL, argc - 1, argv + 1,
- local, which, 0, 0, where, 1);
+ local_specified, which, 0, 0, where, 1);
Lock_Cleanup ();
dellist (&mtlist);
if (where != NULL)
@@ -738,6 +746,21 @@ rtag_fileproc (callerdat, finfo)
branch_mode ? "branch" : "version", rev);
free (oversion);
free (version);
+ if (branch_mode) free(rev);
+ return (0);
+ }
+ else /* force_tag_move is set and... */
+ if ((isbranch && !disturb_branch_tags) ||
+ (!isbranch && disturb_branch_tags))
+ {
+ error(0,0, "%s: Not moving %s tag `%s' from %s to %s%s.",
+ finfo->fullname,
+ isbranch ? "branch" : "non-branch",
+ symtag, oversion, rev,
+ isbranch ? "" : " due to `-B' option");
+ if (branch_mode) free(rev);
+ free (oversion);
+ free (version);
return (0);
}
free (oversion);
@@ -779,7 +802,7 @@ rtag_delete (rcsfile)
RCSNode *rcsfile;
{
char *version;
- int retcode;
+ int retcode, isbranch;
if (numtag)
{
@@ -796,6 +819,20 @@ rtag_delete (rcsfile)
return (0);
free (version);
+
+ isbranch = RCS_nodeisbranch (rcsfile, symtag);
+ if ((isbranch && !disturb_branch_tags) ||
+ (!isbranch && disturb_branch_tags))
+ {
+ if (!quiet)
+ error(0, 0,
+ "Not removing %s tag `%s' from `%s'%s.",
+ isbranch ? "branch" : "non-branch",
+ symtag, rcsfile->path,
+ isbranch ? "" : " due to `-B' option");
+ return (1);
+ }
+
if ((retcode = RCS_deltag(rcsfile, symtag)) != 0)
{
if (!quiet)
@@ -843,6 +880,7 @@ tag_fileproc (callerdat, finfo)
if (delete_flag)
{
+ int isbranch;
/*
* If -d is specified, "force_tag_match" is set, so that this call to
* RCS_getversion() will return a NULL version string if the symbolic
@@ -861,6 +899,20 @@ tag_fileproc (callerdat, finfo)
}
free (version);
+ isbranch = RCS_nodeisbranch (finfo->rcs, symtag);
+ if ((isbranch && !disturb_branch_tags) ||
+ (!isbranch && disturb_branch_tags))
+ {
+ if (!quiet)
+ error(0, 0,
+ "Not removing %s tag `%s' from `%s'%s.",
+ isbranch ? "branch" : "non-branch",
+ symtag, vers->srcfile->path,
+ isbranch ? "" : " due to `-B' option");
+ freevers_ts (&vers);
+ return (1);
+ }
+
if ((retcode = RCS_deltag(vers->srcfile, symtag)) != 0)
{
if (!quiet)
@@ -973,6 +1025,20 @@ tag_fileproc (callerdat, finfo)
freevers_ts (&vers);
return (0);
}
+ else /* force_tag_move == 1 and... */
+ if ((isbranch && !disturb_branch_tags) ||
+ (!isbranch && disturb_branch_tags))
+ {
+ error(0,0, "%s: Not moving %s tag `%s' from %s to %s%s.",
+ finfo->fullname,
+ isbranch ? "branch" : "non-branch",
+ symtag, oversion, rev,
+ isbranch ? "" : " due to `-B' option");
+ free (oversion);
+ if (branch_mode) free(rev);
+ freevers_ts (&vers);
+ return (0);
+ }
free (oversion);
}
diff --git a/contrib/cvs/src/update.c b/contrib/cvs/src/update.c
index f4b919f..3dbe26d 100644
--- a/contrib/cvs/src/update.c
+++ b/contrib/cvs/src/update.c
@@ -36,7 +36,7 @@
#include "cvs.h"
#include "savecwd.h"
#ifdef SERVER_SUPPORT
-#include "md5.h"
+# include "md5.h"
#endif
#include "watch.h"
#include "fileattr.h"
@@ -1779,7 +1779,7 @@ patch_file (finfo, vers_ts, docheckout, file_info, checksum)
}
else
{
-#define BINARY "Binary"
+# define BINARY "Binary"
char buf[sizeof BINARY];
unsigned int c;
@@ -2675,7 +2675,7 @@ special_file_mismatch (finfo, rev1, rev2)
rev1_symlink = xreadlink (finfo->file);
else
{
-#ifdef HAVE_ST_RDEV
+# ifdef HAVE_ST_RDEV
if (CVS_LSTAT (finfo->file, &sb) < 0)
error (1, errno, "could not get file information for %s",
finfo->file);
@@ -2684,10 +2684,10 @@ special_file_mismatch (finfo, rev1, rev2)
rev1_mode = sb.st_mode;
if (S_ISBLK (rev1_mode) || S_ISCHR (rev1_mode))
rev1_dev = sb.st_rdev;
-#else
+# else
error (1, 0, "cannot handle device files on this system (%s)",
finfo->file);
-#endif
+# endif
}
rev1_hardlinks = list_linked_files_on_disk (finfo->file);
}
@@ -2726,7 +2726,7 @@ special_file_mismatch (finfo, rev1, rev2)
{
/* If the size of `ftype' changes, fix the sscanf call also */
char ftype[16];
- if (sscanf (n->data, "%16s %lu", ftype,
+ if (sscanf (n->data, "%15s %lu", ftype,
&dev_long) < 2)
error (1, 0, "%s:%s has bad `special' newphrase %s",
finfo->file, rev1, n->data);
@@ -2753,7 +2753,7 @@ special_file_mismatch (finfo, rev1, rev2)
rev2_symlink = xreadlink (finfo->file);
else
{
-#ifdef HAVE_ST_RDEV
+# ifdef HAVE_ST_RDEV
if (CVS_LSTAT (finfo->file, &sb) < 0)
error (1, errno, "could not get file information for %s",
finfo->file);
@@ -2762,10 +2762,10 @@ special_file_mismatch (finfo, rev1, rev2)
rev2_mode = sb.st_mode;
if (S_ISBLK (rev2_mode) || S_ISCHR (rev2_mode))
rev2_dev = sb.st_rdev;
-#else
+# else
error (1, 0, "cannot handle device files on this system (%s)",
finfo->file);
-#endif
+# endif
}
rev2_hardlinks = list_linked_files_on_disk (finfo->file);
}
@@ -2804,7 +2804,7 @@ special_file_mismatch (finfo, rev1, rev2)
{
/* If the size of `ftype' changes, fix the sscanf call also */
char ftype[16];
- if (sscanf (n->data, "%16s %lu", ftype,
+ if (sscanf (n->data, "%15s %lu", ftype,
&dev_long) < 2)
error (1, 0, "%s:%s has bad `special' newphrase %s",
finfo->file, rev2, n->data);
diff --git a/contrib/cvs/src/vers_ts.c b/contrib/cvs/src/vers_ts.c
index 5524bab..c41affd 100644
--- a/contrib/cvs/src/vers_ts.c
+++ b/contrib/cvs/src/vers_ts.c
@@ -339,13 +339,22 @@ time_stamp (file)
{
struct stat sb;
char *cp;
- char *ts;
+ char *ts = NULL;
+ time_t mtime = 0L;
- if (CVS_LSTAT (file, &sb) < 0)
+ if (!CVS_LSTAT (file, &sb))
{
- ts = NULL;
+ mtime = sb.st_mtime;
}
- else
+ /* If it's a symlink, return whichever is the newest mtime of
+ the link and its target, for safety.
+ */
+ if (!CVS_STAT (file, &sb))
+ {
+ if (mtime < sb.st_mtime)
+ mtime = sb.st_mtime;
+ }
+ if (mtime)
{
struct tm *tm_p;
struct tm local_tm;
diff --git a/contrib/cvs/src/version.c b/contrib/cvs/src/version.c
new file mode 100644
index 0000000..aba91ae
--- /dev/null
+++ b/contrib/cvs/src/version.c
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 1994 david d `zoo' zuhn
+ * Copyright (c) 1994 Free Software Foundation, Inc.
+ * Copyright (c) 1992, Brian Berliner and Jeff Polk
+ * Copyright (c) 1989-1992, Brian Berliner
+ *
+ * You may distribute under the terms of the GNU General Public License as
+ * specified in the README file that comes with this CVS source distribution.
+ *
+ * version.c - the CVS version number
+ */
+
+#include "cvs.h"
+#include "version.h"
+
+#ifdef CLIENT_SUPPORT
+#ifdef SERVER_SUPPORT
+char *config_string = " (client/server)\n";
+#else
+char *config_string = " (client)\n";
+#endif
+#else
+#ifdef SERVER_SUPPORT
+char *config_string = " (server)\n";
+#else
+char *config_string = "\n";
+#endif
+#endif
+
+
+
+static const char *const version_usage[] =
+{
+ "Usage: %s %s\n",
+ NULL
+};
+
+
+
+/*
+ * Output a version string for the client and server.
+ *
+ * This function will output the simple version number (for the '--version'
+ * option) or the version numbers of the client and server (using the 'version'
+ * command).
+ */
+int
+version (argc, argv)
+ int argc;
+ char **argv;
+{
+ int err = 0;
+
+ if (argc == -1)
+ usage (version_usage);
+
+#ifdef CLIENT_SUPPORT
+ if (current_parsed_root && current_parsed_root->isremote)
+ (void) fputs ("Client: ", stdout);
+#endif
+
+ /* Having the year here is a good idea, so people have
+ some idea of how long ago their version of CVS was
+ released. */
+ (void) fputs (version_string, stdout);
+ (void) fputs (config_string, stdout);
+
+#ifdef CLIENT_SUPPORT
+ if (current_parsed_root && current_parsed_root->isremote)
+ {
+ (void) fputs ("Server: ", stdout);
+ start_server ();
+ if (supported_request ("version"))
+ send_to_server ("version\012", 0);
+ else
+ {
+ send_to_server ("noop\012", 0);
+ fputs ("(unknown)\n", stdout);
+ }
+ err = get_responses_and_close ();
+ }
+#endif
+ return err;
+}
+
diff --git a/contrib/cvs/src/version.h.in b/contrib/cvs/src/version.h.in
new file mode 100644
index 0000000..48580cb
--- /dev/null
+++ b/contrib/cvs/src/version.h.in
@@ -0,0 +1,15 @@
+/* -*- c -*-
+ *
+ * Copyright (c) 1992, Brian Berliner and Jeff Polk
+ * Copyright (c) 1989-1992, Brian Berliner
+ *
+ * You may distribute under the terms of the GNU General Public License as
+ * specified in the README file that comes with the CVS kit.
+ */
+
+#ifndef VERSION_H
+#define VERSION_H 1
+
+#define version_string "Concurrent Versions System (CVS) @VERSION@"
+
+#endif /* VERSION_H */
diff --git a/contrib/cvs/src/wrapper.c b/contrib/cvs/src/wrapper.c
index 039590a..bb071b1 100644
--- a/contrib/cvs/src/wrapper.c
+++ b/contrib/cvs/src/wrapper.c
@@ -178,14 +178,14 @@ wrap_send ()
and (more importantly) where we found it. */
error (0, 0, "\
-m wrapper option is not supported remotely; ignored");
+ send_to_server ("Argument -W\012Argument ", 0);
+ send_to_server (wrap_list[i]->wildCard, 0);
+ send_to_server (" -k '", 0);
if (wrap_list[i]->rcsOption != NULL)
- {
- send_to_server ("Argument -W\012Argument ", 0);
- send_to_server (wrap_list[i]->wildCard, 0);
- send_to_server (" -k '", 0);
send_to_server (wrap_list[i]->rcsOption, 0);
- send_to_server ("'\012", 0);
- }
+ else
+ send_to_server ("kv", 0);
+ send_to_server ("'\012", 0);
}
}
#endif /* CLIENT_SUPPORT */
@@ -216,32 +216,28 @@ wrap_unparse_rcs_options (line, first_call_p)
if (first_call_p)
i = 0;
- for (; i < wrap_count + wrap_tempcount; ++i)
- {
- if (wrap_list[i]->rcsOption != NULL)
- {
- *line = xmalloc (strlen (wrap_list[i]->wildCard)
- + strlen ("\t")
- + strlen (" -k '")
- + strlen (wrap_list[i]->rcsOption)
- + strlen ("'")
- + 1); /* leave room for '\0' */
-
- strcpy (*line, wrap_list[i]->wildCard);
- strcat (*line, " -k '");
- strcat (*line, wrap_list[i]->rcsOption);
- strcat (*line, "'");
-
- /* We're going to miss the increment because we return, so
- do it by hand. */
- ++i;
-
- return;
- }
+ if (i >= wrap_count + wrap_tempcount) {
+ *line = NULL;
+ return;
}
- *line = NULL;
- return;
+ *line = xmalloc (strlen (wrap_list[i]->wildCard)
+ + strlen ("\t")
+ + strlen (" -k '")
+ + (wrap_list[i]->rcsOption != NULL ?
+ strlen (wrap_list[i]->rcsOption) : 2)
+ + strlen ("'")
+ + 1); /* leave room for '\0' */
+
+ strcpy (*line, wrap_list[i]->wildCard);
+ strcat (*line, " -k '");
+ if (wrap_list[i]->rcsOption != NULL)
+ strcat (*line, wrap_list[i]->rcsOption);
+ else
+ strcat (*line, "kv");
+ strcat (*line, "'");
+
+ ++i;
}
#endif /* SERVER_SUPPORT || CLIENT_SUPPORT */
@@ -438,7 +434,7 @@ wrap_add (line, isTemp)
case 'k':
if (e.rcsOption)
free (e.rcsOption);
- e.rcsOption = xstrdup (temp);
+ e.rcsOption = strcmp (temp, "kv") ? xstrdup (temp) : NULL;
break;
default:
break;
@@ -471,11 +467,7 @@ wrap_add_entry(e, temp)
x=(temp ? wrap_count+(wrap_tempcount++):(wrap_count++));
wrap_list[x]=(WrapperEntry *)xmalloc(sizeof(WrapperEntry));
- wrap_list[x]->wildCard=e->wildCard;
- wrap_list[x]->fromcvsFilter=e->fromcvsFilter;
- wrap_list[x]->tocvsFilter=e->tocvsFilter;
- wrap_list[x]->mergeMethod=e->mergeMethod;
- wrap_list[x]->rcsOption = e->rcsOption;
+ *wrap_list[x]=*e;
}
/* Return 1 if the given filename is a wrapper filename */
diff --git a/contrib/cvs/src/zlib.c b/contrib/cvs/src/zlib.c
index 3bfc542..1fc7a72 100644
--- a/contrib/cvs/src/zlib.c
+++ b/contrib/cvs/src/zlib.c
@@ -51,8 +51,8 @@ static int compress_buffer_input PROTO((void *, char *, int, int, int *));
static int compress_buffer_output PROTO((void *, const char *, int, int *));
static int compress_buffer_flush PROTO((void *));
static int compress_buffer_block PROTO((void *, int));
-static int compress_buffer_shutdown_input PROTO((void *));
-static int compress_buffer_shutdown_output PROTO((void *));
+static int compress_buffer_shutdown_input PROTO((struct buffer *));
+static int compress_buffer_shutdown_output PROTO((struct buffer *));
/* Report an error from one of the zlib functions. */
@@ -355,10 +355,10 @@ compress_buffer_block (closure, block)
/* Shut down an input buffer. */
static int
-compress_buffer_shutdown_input (closure)
- void *closure;
+compress_buffer_shutdown_input (buf)
+ struct buffer *buf;
{
- struct compress_buffer *cb = (struct compress_buffer *) closure;
+ struct compress_buffer *cb = (struct compress_buffer *) buf->closure;
int zstatus;
/* Pick up any trailing data, such as the checksum. */
@@ -387,10 +387,10 @@ compress_buffer_shutdown_input (closure)
/* Shut down an output buffer. */
static int
-compress_buffer_shutdown_output (closure)
- void *closure;
+compress_buffer_shutdown_output (buf)
+ struct buffer *buf;
{
- struct compress_buffer *cb = (struct compress_buffer *) closure;
+ struct compress_buffer *cb = (struct compress_buffer *) buf->closure;
int zstatus, status;
do
OpenPOWER on IntegriCloud