summaryrefslogtreecommitdiffstats
path: root/contrib/cvs/src
diff options
context:
space:
mode:
authorobrien <obrien@FreeBSD.org>2008-01-13 05:49:32 +0000
committerobrien <obrien@FreeBSD.org>2008-01-13 05:49:32 +0000
commit55b663837dd12bbe5836969ac2a3f052a9028ea5 (patch)
tree8d8aae4a8bb167db64e23bb7f76f39014f36d45f /contrib/cvs/src
parent8416bda1d23bda4666a5b880a9d78eccaa640036 (diff)
downloadFreeBSD-src-55b663837dd12bbe5836969ac2a3f052a9028ea5.zip
FreeBSD-src-55b663837dd12bbe5836969ac2a3f052a9028ea5.tar.gz
Import cvs-1.11.22 onto vendor branch.
Diffstat (limited to 'contrib/cvs/src')
-rw-r--r--contrib/cvs/src/ChangeLog1088
-rw-r--r--contrib/cvs/src/Makefile.am8
-rw-r--r--contrib/cvs/src/Makefile.in274
-rw-r--r--contrib/cvs/src/add.c58
-rw-r--r--contrib/cvs/src/admin.c34
-rw-r--r--contrib/cvs/src/annotate.c10
-rw-r--r--contrib/cvs/src/buffer.c68
-rw-r--r--contrib/cvs/src/buffer.h14
-rw-r--r--contrib/cvs/src/checkin.c14
-rw-r--r--contrib/cvs/src/checkout.c22
-rw-r--r--contrib/cvs/src/classify.c22
-rw-r--r--contrib/cvs/src/client.c224
-rw-r--r--contrib/cvs/src/client.h19
-rw-r--r--contrib/cvs/src/commit.c190
-rw-r--r--contrib/cvs/src/create_adm.c9
-rw-r--r--contrib/cvs/src/cvs.h48
-rw-r--r--contrib/cvs/src/cvsrc.c11
-rw-r--r--contrib/cvs/src/diff.c124
-rw-r--r--contrib/cvs/src/edit.c36
-rw-r--r--contrib/cvs/src/entries.c10
-rw-r--r--contrib/cvs/src/expand_path.c173
-rw-r--r--contrib/cvs/src/fileattr.c3
-rw-r--r--contrib/cvs/src/filesubr.c94
-rw-r--r--contrib/cvs/src/find_names.c9
-rw-r--r--contrib/cvs/src/hardlink.c6
-rw-r--r--contrib/cvs/src/hardlink.h2
-rw-r--r--contrib/cvs/src/hash.c7
-rw-r--r--contrib/cvs/src/hash.h7
-rw-r--r--contrib/cvs/src/history.c77
-rw-r--r--contrib/cvs/src/history.h6
-rw-r--r--contrib/cvs/src/ignore.c27
-rw-r--r--contrib/cvs/src/import.c71
-rw-r--r--contrib/cvs/src/lock.c224
-rw-r--r--contrib/cvs/src/log.c94
-rw-r--r--contrib/cvs/src/login.c14
-rw-r--r--contrib/cvs/src/logmsg.c29
-rw-r--r--contrib/cvs/src/main.c246
-rw-r--r--contrib/cvs/src/mkmodules.c23
-rw-r--r--contrib/cvs/src/modules.c15
-rw-r--r--contrib/cvs/src/myndbm.c8
-rw-r--r--contrib/cvs/src/myndbm.h14
-rw-r--r--contrib/cvs/src/no_diff.c11
-rw-r--r--contrib/cvs/src/parseinfo.c24
-rw-r--r--contrib/cvs/src/patch.c79
-rw-r--r--contrib/cvs/src/rcs.c385
-rw-r--r--contrib/cvs/src/rcs.h12
-rw-r--r--contrib/cvs/src/rcscmds.c174
-rw-r--r--contrib/cvs/src/recurse.c161
-rw-r--r--contrib/cvs/src/release.c37
-rw-r--r--contrib/cvs/src/remove.c9
-rw-r--r--contrib/cvs/src/repos.c9
-rw-r--r--contrib/cvs/src/root.c56
-rw-r--r--contrib/cvs/src/root.h22
-rw-r--r--contrib/cvs/src/run.c160
-rwxr-xr-xcontrib/cvs/src/sanity.sh2647
-rw-r--r--contrib/cvs/src/server.c172
-rw-r--r--contrib/cvs/src/server.h18
-rw-r--r--contrib/cvs/src/stack.c7
-rw-r--r--contrib/cvs/src/stack.h5
-rw-r--r--contrib/cvs/src/status.c31
-rw-r--r--contrib/cvs/src/subr.c63
-rw-r--r--contrib/cvs/src/tag.c263
-rw-r--r--contrib/cvs/src/update.c205
-rw-r--r--contrib/cvs/src/vers_ts.c64
-rw-r--r--contrib/cvs/src/version.c14
-rw-r--r--contrib/cvs/src/watch.c23
-rw-r--r--contrib/cvs/src/wrapper.c10
-rw-r--r--contrib/cvs/src/zlib.c16
68 files changed, 6072 insertions, 2037 deletions
diff --git a/contrib/cvs/src/ChangeLog b/contrib/cvs/src/ChangeLog
index 87caf76..822f86d 100644
--- a/contrib/cvs/src/ChangeLog
+++ b/contrib/cvs/src/ChangeLog
@@ -1,3 +1,1075 @@
+2006-06-08 Derek Price <derek@ximbiot.com>
+
+ * sanity.sh (conflicts4): Test that the client honors Empty-conflicts.
+
+ * server.c (requests): Add "Empty-conflicts" marker.
+ * client.c (send_fileproc): Send contents of all files with conflicts
+ unless the server can handle the conflict marker in the Entry.
+
+ * sanity.sh (conflicts4): New tests.
+ (Original patch from Mark D. Baushke <mdb@gnu.org>.)
+
+2006-06-07 Mark D. Baushke <mdb@gnu.org>
+
+ * modules.c (my_module): Remove unused variable xvalue.
+ [Fixes NetBSD coverity cid-705.]
+
+2006-05-31 Mark D. Baushke <mdb@gnu.org>
+
+ * add.c (add): Fix memory leak.
+ [Fixes NetBSD coverity cid-3751.]
+ (add_directory): Fix memory leak.
+ [Fixes NetBSD coverity cid-3640.]
+
+ * checkin.c (Checkin): Avoid possible NULL dereference.
+ [Fixes NetBSD coverity cid-2425.]
+
+ * client.c (auth_server): Fix memory leak.
+ [Fixes NetBSD coverity cid-3404.]
+
+ * commit.c (remove_file): Fix memory leak.
+ [Fixes NetBSD coverity cid-3752.]
+
+ * rcs.c (RCS_checkin): Add assert (tip).
+ [Fixes NetBSD coverity cid-2424.]
+
+2006-05-26 Mark D. Baushke <mdb@gnu.org>
+
+ * add.c (add): Do not leak memory.
+ [Fixes NetBSD coverity cid-2199.]
+
+ * edit.c (onoff_fileproc): Do not leak memory.
+ [Fixes NetBSD coverity cid-2201.]
+
+ * edit.c (onoff_filesdoneproc): Do not leak memory.
+ [Fixes NetBSD coverity cid-2202.]
+
+ * lock.c (readers_exist): Add assert (lockdir).
+ [Fixes NetBSD coverity cid-2411.]
+
+ * rcs.c (RCS_findlock_or_tip): Do not leak memory.
+ [Fixes NetBSD coverity cid-2198.]
+
+ * rcs.c (RCS_getdate): Avoid possible NULL dereference.
+ [Fixes NetBSD coverity cid-2412.]
+
+ * server.c (serve_sticky): Do not leak file descriptors.
+ [Fixes NetBSD coverity cid-2197.]
+
+ * server.c (do_cvs_command): Do not leak memory.
+ [Fixes NetBSD coverity cid-2204.]
+
+ * tag.c (add_to_val_tags): Do not leak memory.
+ [Fixes NetBSD coverity cid-2071.]
+
+2006-05-25 Derek Price <derek@ximbiot.com>
+
+ * client.c (start_rsh_server): Default rsh client to RSH_DFLT. Remove
+ verbose comment attempting to justify the previous default.
+
+2006-05-24 Larry Jones <lawrence.jones@ugs.com>
+
+ * sanity.sh: Add -v|--verbose option to echo test names. Clean
+ up help message.
+ Remove val-tags files for cleanup instead of truncating since the
+ truncation code doesn't work right on Solaris. Always use -f when
+ removing val-tags.
+
+2006-05-22 Derek Price <derek@ximbiot.com>
+
+ * rcs.c (RCS_reparsercsfile, RCS_fully_parse, RCS_checkout, RCS_deltas,
+ RCS_getdeltatext, RCS_copydeltas): Verify input revision numbers.
+ (rcs6): Update to compensate.
+
+ * sanity.sh (rcs6): New test.
+
+2006-05-16 Derek Price <derek@ximbiot.com>
+
+ * main.c: Update copyright for 2006.
+
+2006-05-12 Mark D. Baushke <mdb@gnu.org>
+
+ * log.c (log_expand_revlist): Add assert (r->first). It should
+ only be possible for both r->first == NULL && r->last == NULL
+ which would have been handled.
+ [Fixes NetBSD coverity cid-1063.]
+
+ * server.c (do_cvs_command): Protect close (dev_null_fd) against
+ invalid fd value in error_exit.
+ [Fixes NetBSD coverity cid-1307.]
+
+ * rcs.c (RCS_isdead): Assert that the first argument is not NULL.
+ [Fixes NetBSD coverity cid-1058.]
+
+ * commit.c (checkaddfile): Do not dereference NULL on call to
+ error().
+ [Fixes NetBSD coverity cid-1061.]
+
+ * log.c (cvslog): Assert p->start && p->end instead of masking the
+ problem.
+ * server.c (server_updated): Assert findnode_fn results instead of
+ masking the problem.
+
+ * add.c (add_directory): Revert previous change. The xstrdup()
+ function already deals a NULL argument.
+ * client.c (handle_mt): Ditto.
+ * entries.c (Entnode_Create): Ditto.
+ (Entries_Open): Ditto.
+ * logmsg.c (fmt_proc): Ditto.
+ * vers_ts.c (Version_TS): Ditto.
+
+2006-05-11 Mark D. Baushke <mdb@gnu.org>
+
+ * add.c (add_directory): Protect tag from NULL dereference.
+ [Fixes NetBSD cid-1054.]
+
+ * client.c (handle_mt): Deal with missing text argument.
+ [Fixes NetBSD cid-924.]
+
+ * entries.c (Entnode_Create): Protect date, tag and ts_conflict
+ from possible NULL dereference.
+ [Fixes NetBSD coverity cid-994, cid-995, cid-1055, cid-1057.]
+
+ * entries.c (Entries_Open): Protect dirtag and dirdate from
+ possible NULL dereference.
+ [Fixes NetBSD coverity cid-996.]
+
+ * log.c (cvslog): Validate start and end args to
+ date_to_internet().
+ [Fixes NetBSD coverity cid-2427 and cid-2428.]
+
+ * logmsg.c (fmt_proc): Protect li->tag from NULL dereference.
+ [Fixes NetBSD coverity cid-997.]
+
+ * vers_ts.c (Version_TS): Protect tag and vers_ts->tag from NULL
+ dereference.
+ [Fixes NetBSD coverity cid-1053.]
+
+2006-05-04 Mark D. Baushke <mdb@gnu.org>
+
+ * filesubr.c (cvs_temp_file): Avoid keeping pointers to free()'d
+ storage laying around.
+ * commit.c (commit): Handle possible NULL filename values
+ returned from cvs_temp_file().
+ * filesubr.c (cvs_temp_name): Ditto.
+ * import.c (import): Ditto.
+ * login.c (password_entry_operation): Ditto.
+ * logmsg.c (do_verify): Ditto.
+ * patch.c (patch_fileproc): Ditto.
+ [Fixes NetBSD coverity cid-2545.]
+
+ * buffer.c (packetizing_buffer_output): Initialize outdata.
+ [Fixes NetBSD coverity cid-2474.]
+
+ * server.c (server_updated): Check for NULL return from
+ findnode_fn(). [Fixes NetBSD coverity cid-1352.]
+
+2006-04-19 Larry Jones <lawrence.jones@ugs.com>
+
+ * history.c (sort_order): Back out previous change - not needed.
+
+2006-04-15 Larry Jones <lawrence.jones@ugs.com>
+
+ * history.c (sort_order): Add prototype.
+ * server.c (template_proc): Add prototype and make args const.
+ * update.c (RegisterMerge): Make static to match prototype.
+
+2006-04-07 Derek Price <derek@ximbiot.com>
+
+ * client.c (strto_file_size): New function which checks for errors when
+ parsing protocol input.
+ (read_counted_file, update_entries, handle_mbinary): Use new function.
+ Remove FIXME.
+ (Thanks to a report from Brendan Harrison
+ <brendan.harrison@klocwork.com>.)
+
+ * client.c (send_a_repository): Add assertion.
+ (Thanks to an incorrect report from Brendan Harrison
+ <brendan.harrison@klocwork.com>.)
+
+2006-04-06 Derek Price <derek@ximbiot.com>
+
+ * filesubr.c (last_component, expand_wild), rcs.c (RCS_deltas,
+ RCS_rewrite), server.c (server_checked_in): Add assertions.
+ (Thanks to an incorrect report from Brendan Harrison
+ <brendan.harrison@klocwork.com>.)
+
+2006-03-31 Mark D. Baushke <mdb@gnu.org>
+
+ * cvsrc.c (read_cvsrc): Deal with \r\n (DOS) line endings in
+ .cvsrc files.
+
+2006-03-07 Derek Price <derek@ximbiot.com>
+
+ * tag.c (rtag_proc): Search the Attic when -F is used.
+ * sanity.sh (tests): Run death-rtag.
+ (death-rtag): Expect success.
+
+ * sanity.sh (death-rtag): Add failing force tag move test.
+
+2006-03-06 Derek Price <derek@ximbiot.com>
+
+ * tag.c (rtag_proc): Always search in the attic when -r is used.
+
+ * sanity.sh (death-rtag): New test.
+ (Original report from C. Michael Pilato <cmpilato@collab.net>.)
+
+2006-03-01 Derek Price <derek@ximbiot.com>
+
+ * sanity.sh: Set MALLOC_CHECK_ in hopes of exposing common memory
+ errors when CVS is linked with glibc 2.x.
+
+2006-02-27 Derek Price <derek@ximbiot.com>
+
+ * lock.c (internal_lock): Back out previous change, we don't change
+ user visible output on stable unless absolutely necessary.
+
+ * lock.c (internal_lock): Improve error message.
+
+2006-02-26 Derek Price <derek@ximbiot.com>
+
+ * client.c (call_in_directory): Remove unneeded code.
+ * sanity.sh (toplevel-12): Compensate by failing to expect a redundant
+ error message.
+
+2006-02-24 Mark D. Baushke <mdb@gnu.org>
+
+ * client.c (gzip_level): Move to...
+ * main.c (gzip_level): ...here.
+ (main): Revert previous change in '-z' argument processing and
+ remove CLIENT_SUPPORT ifdef/endif.
+ * sanity.h (crerepos-6a): Deal with --disable-client output.
+
+ * main.c (main): Validate the gzip compression level for
+ --disable-client configurations.
+
+2006-02-13 Derek Price <derek@ximbiot.com>
+
+ * server.c (do_cvs_command): Skip server_cleanup in the child process.
+
+ * sanity.sh (sshstdio-6): Rewrite using more portable sed script.
+
+2006-02-02 Derek Price <derek@ximbiot.com>
+
+ * sanity.sh (sshstdio): Attempt to ignore spurious SSH output.
+
+ * main.c (main), release.c (release), server.c (do_cvs_command): Always
+ call the cleanup hooks before exit.
+
+2006-02-01 Derek Price <derek@ximbiot.com>
+
+ * tag.c (add_to_val_tags): When a tag turns out to exist in the db when
+ it isn't expected, release the lock.
+
+ * history.c (save_user, save_file, save_mod, read_hrecs): Avoid
+ overflow.
+
+2006-01-30 Derek Price <derek@ximbiot.com>
+
+ * server.c (do_cvs_command): Set flow control pipe to blocking mode
+ before waiting for it to close.
+ (set_block_fd): New function.
+ (Original patch from Garrett Rooney <grooney@collab.net>.)
+
+2006-01-13 Larry Jones <lawrence.jones@ugs.com>
+
+ * mkmodules.c (config_contents): Change SystemAuth to yes to match
+ the default value. Add missing newline in RereadLogAfterVerify.
+
+2006-01-09 Larry Jones <lawrence.jones@ugs.com>
+
+ * commit.c (remove_file): Record correct revision in history file.
+ (Reported by Chris Reed <cr@progress.com>.)
+
+2005-12-07 Derek Price <derek@ximbiot.com>
+
+ * client.c (start_server), root.c (method_names), root.h (CVSmethod):
+ Handle :extssh: as a kindness to Eclipse users.
+ (Suggestion from Joseph P. Skudlarek <Jskud@Jskud.com>.)
+
+2005-12-06 Mark D. Baushke <mdb@gnu.org>
+
+ * buffer.c (stdio_buffer_shutdown): No longer assert() the
+ fstat(). Use error (0, ...) instead of error (1, ...) to avoid
+ infinite loops. (patch #4678)
+ Patch adapted from "Allan L. Bazinet" <allan.bazinet@gmail.com>
+
+2005-11-10 Larry Jones <lawrence.jones@ugs.com>
+
+ * commit.c (commit): Complain about obsolete -n option if not in
+ server mode.
+
+2005-11-09 Derek Price <derek@ximbiot.com>
+
+ * sanity.sh (pserver-4.2): Accept a "no such sytem user" message when
+ a root attempt is made.
+
+2005-09-30 Larry Jones <lawrence.jones@ugs.com>
+
+ * expand_path.c (expand_path): Fix memory leaks.
+
+2005-09-29 Paul Eggert <eggert@CS.UCLA.EDU>
+ Derek Price <derek@ximbiot.com>
+
+ * client.c (handle_m, handle_e): Remove incomplete workaround for
+ O_NONBLOCK problem; no longer needed because of the fix below.
+ (start_rsh_server): We need the O_NONBLOCK fix, so pass 'true' to
+ piped_child to enable the workaround.
+ * cvs.h (piped_child): New bool argument saying whether O_NONBLOCK
+ fix is needed. All uses changed.
+ * run.c (work_around_openssh_glitch): New function.
+ (piped_child): Use it if the fix is requested. Avoid call call to
+ vfork with undefined behavior.
+
+2005-09-26 Conrad T. Pino <Conrad@Pino.com>
+
+ * rcs.c: Use "#ifdef HAVE_FSYNC" just like every where else.
+
+2005-09-25 Derek Price <derek@ximbiot.com>
+
+ * rcs.c (rcs_internal_unlockfile): Fsync files before renaming them.
+ Patch from Rahul Bhargava <rahul@wandisco.com>.
+
+2005-09-24 Derek Price <derek@ximbiot.com>
+
+ * update.c (merge_file): Check for RCS_checkout errors.
+
+2005-09-23 Larry Jones <lawrence.jones@ugs.com>
+
+ * checkout.c (export_usage): Note that -r requires a tag.
+
+2005-09-22 Larry Jones <lawrence.jones@ugs.com>
+
+ * patch.c (patch_usage): Document -k option.
+
+2005-09-22 Derek Price <derek@ximbiot.com>
+
+ * classify.c (Classify_File): If a file had a conflict and the
+ timestamp hasn't changed, it still has a conflict. Add comment about
+ how T_MODIFIED could later turn out to have conflict markers and why
+ it should not be checked in this function.
+ * client.c (send_fileproc): Don't send contents for files known to have
+ conflicts unless this is for `cvs diff'.
+ * commit.c (check_fileproc): T_CONFLICT should be handled like
+ T_MODIFIED, since force could be requested. Simplify logic since
+ T_CONFLICT can now be trusted.
+ * cvs.h (file_has_conflict): Remove proto.
+ * rcs.c (RCS_Checkout): Comment noexec behavior in header block.
+ * server.c (serve_unchanged, serve_is_modified): Handle conflicts.
+ * status.c (status_fileproc): Trust T_CONFLICT to simplify.
+ * subr.c (file_has_conflict): Removed.
+ * update.c (update_fileproc): Trust T_CONFLICT.
+ (RegisterMerge): New function factored from...
+ (merge_file, join_file): ...these two functions.
+ * vers_ts.c (time_stamp_server): Handle = conflict timestamps in server
+ entdata.
+ * sanity.sh (files-12): Account for slight behavior improvement.
+ (status, conflicts, mwrap): Account for corrected behavior.
+ (join-readonly-conflict-10): Correct comment.
+ (binfiles-con1b): New test for correct behavior.
+
+2005-09-19 Derek Price <derek@ximbiot.com>
+
+ * sanity.sh (modules5-8): Rename...
+ (modules5-8r): ...to this and comment Mac OS X failure.
+ Comment Solaris 9 failure below with a `FIXME?' tag.
+
+ * sanity.sh: Remove previous hack in favor of setting TESTDIR on
+ Solaris (and Mac OS X) until problem is solved correctly.
+
+2005-09-15 Derek Price <derek@ximbiot.com>
+
+ * sanity.sh: Use /bin/pwd to verify current dir since Solaris 9 is
+ sometimes resolving symlinked paths.
+
+2005-09-14 Derek Price <derek@ximbiot.com>
+
+ * edit.c (edit_usage, unedit_usage, editors_usage), watch.c
+ (watch_usage, watchers_usage): Add quotes and reword for clarity and
+ consistency.
+
+ * edit.c (edit_usage): Add missing syntax. Reword description for
+ clarity. Mention default behavior.
+
+2005-09-13 Derek Price <derek@ximbiot.com>
+
+ * sanity.sh: Split $username into $username & $username8. Rename
+ $author as $anyusername.
+
+2005-09-12 Derek Price <derek@ximbiot.com>
+
+ * sanity.sh (binfiles-con1b): Back out accidental addition.
+
+ * sanity.sh (username): Cut $username down to 8 characters when longer,
+ since that is all that appears in output.
+
+2005-09-07 Derek Price <derek@ximbiot.com>
+
+ Close <http://savannah.nongnu.org/bugs/?func=detailitem&item_id=14462>.
+ * rcs.c (RCS_parse): Free variable *after* using it for the last time.
+
+2005-09-06 Derek Price <derek@ximbiot.com>
+
+ * rcs.c (RCS_putdtree): Remove unused variable.
+
+2005-09-06 Mark D. Baushke <mdb@gnu.org>
+
+ Close <https://savannah.nongnu.org/bugs/?func=detailitem&item_id=14435>.
+ * rcs.c (RCS_putdtree): Avoid stack overflow which may be
+ possible with excessive recursive calls to RCS_putdtree().
+ (Patch from Serg Masyutin.)
+
+2005-09-03 Derek Price <derek@ximbiot.com>
+
+ * add.c (add_usage): Standardize usage message somewhat.
+
+2005-09-02 Larry Jones <lawrence.jones@ugs.com>
+
+ * commit.c (checkaddfile): Improve error messages for lock_RCS failure.
+ * release.c (release): Improve error message for pclose failure.
+
+ * root.h (struct cvsroot_s): Always declare isremote to simplify
+ other code. Simplify referencing code.
+ * root.c (new_cvsroot_t): Always initialize isremote.
+ * server.h: Always declare server_active to simplify other code.
+ Simplify referencing code.
+ * server.c: Always define server_active.
+
+2005-09-01 Derek Price <derek@ximbiot.com>
+
+ * main.c, wrapper.c: Update links.
+
+2005-09-01 Derek Price <derek@ximbiot.com>
+
+ * recurse.c: Update bug report email address.
+
+2005-08-30 Larry Jones <lawrence.jones@ugs.com>
+
+ * import.c (import_descend): Lock repository directory during import.
+
+2005-07-12 Derek Price <derek@ximbiot.com>
+
+ * buffer.c, buffer.h, client.h, expand_path.c, history.c, myndbm.h,
+ release.c: Add copyright notices.
+
+2005-07-11 Derek Price <derek@ximbiot.com>
+
+ * buffer.c, buffer.h, client.h, expand_path.c, history.c, myndbm.h,
+ release.c: Update license notices.
+
+2005-06-22 Larry Jones <lawrence.jones@ugs.com>
+
+ * vers_ts (Version_TS): Don't allow command line keyword expansion
+ modes to override binary mode.
+ * sanity.sh (): Tests for the above.
+ (Merged from trunk.)
+
+2005-06-06 Conrad T. Pino <Conrad@Pino.com>
+
+ * cvs.h: Reverse patch committed 2005-05-27 by Conrad T. Pino.
+ * run.c: Reverse patch committed 2005-05-27 by Conrad T. Pino.
+
+2005-06-02 Derek Price <derek@ximbiot.com>
+
+ * zlib.c (compress_buffer_shutdown_input): Don't attempt to read EOF
+ from the client during shutdown. It might never be sent.
+ * sanity.sh (abspath2): Test for this.
+
+2005-05-31 Derek Price <derek@ximbiot.com>
+ for Alexander Taler <alex@0--0.org>
+
+ * rcscmds.c: Change type of call_diff_argc_allocated from int to
+ size_t, to match the prototype of run_add_arg_p(). This fixes a
+ bus error in OpenBSD 3.6 sparc64.
+
+2005-05-27 Conrad T. Pino <Conrad@Pino.com>
+
+ * cvs.h: Replace "run_arg" function with "#define run_arg run_add_arg",
+ add "run_add_arg" prototype, change "piped_child" prototype to be same
+ as feature branch to reflect "(os2,src,windows-NT)/run.c" changes.
+ * run.c: Remove "run_arg" to synchronize with "../windows-NT/run.c".
+ Function "run_add_arg" scope was "static" and is now "extern" scope.
+ Synchronize "piped_child" function arguments with feature branch.
+
+2005-05-27 Derek Price <derek@ximbiot.com>
+
+ * client.c (send_arg): Make arg const.
+ (send_option_string): Rename to...
+ (send_options): ...this and accept argc/argv in place of string.
+ * client.h: Update protos to match the changes to client.c.
+ * cvs.h (RCS_exec_rcsdiff, diff_exec): Update protos.
+ (run_add_arg_p, run_arg_free_p): New protos.
+ * diff.c (opts, opts_allocated): Replace with...
+ (diff_argv, diff_argc, diff_arg_allocated): ...these.
+ (add_diff_args): New convenience function.
+ (diff): Use new constructs and APIs.
+ * patch.c (patch_fileproc, RCS_checkin, RCS_delete_revs), rcscmds.c
+ (call_diff_add_arg, call_diff_setup, RCS_merge, RCS_exec_rcsdiff,
+ diff_exec, RCS_output_diff_options), update.c (patch_file): Use new
+ APIs.
+ * run.c (run_add_arg_p, run_arg_free_p): New functions.
+ (run_argc_allocated): Make size_t.
+ (run_setup, run_add_arg): Use new functions.
+ * sanity.sh: Accomodate above changes.
+ (rcslib-diffrgx-3): Slip in test for space splitting.
+
+2005-05-02 Derek Price <derek@ximbiot.com>
+
+ Remove unnecessary level of indirection.
+ * lock.c (L_HISTORY_LOCK, L_VAL_TAGS_LOCK): Remove macros.
+ (internal_lock, internal_clear_lock): Accept lock as argument.
+ (history_lock, clear_history_lock, val_tags_lock, clear_val_tags_lock):
+ Replace old macro arg with an actual lock pointer.
+
+2005-05-02 Derek Price <derek@ximbiot.com>
+
+ * lock.c (internal_lock, internal_clear_lock): Add protos.
+ (history_lock, val_tags_lock): Return the chartered true/false status.
+
+2005-05-02 Derek Price <derek@ximbiot.com>
+
+ * cvs.h (CVSHISTLCK): Rename macro to...
+ (CVSHISTORYLCK): ...this.
+ (CVSVALTAGSLCK): New macro.
+ (val_tags_lock, clear_val_tags_lock): New functions.
+ * lock.c (global_val_tags_lock): New global.
+ (Lock_Cleanup): Clean up after val-tags lock if necessary.
+ (L_HISTORY_LOCK, L_VAL_TAGS_LOCK): New local macros.
+ (internal_lock, internal_clear_lock, val_tags_lock,
+ clear_val_tags_lock): New functions.
+ (history_lock, clear_history_lock): Use new internal functions.
+ * tag.c (is_in_val_tags, add_to_val_tags): New functions using the
+ write-lock for val-tags and factored from...
+ (tag_check_valid): ...this function.
+ * sanity.sh (lockfiles-22): Add val-tags lock test.
+
+2005-04-28 Derek Price <derek@ximbiot.com>
+
+ * cvs.h (history_lock, clear_history_lock): New protos.
+ * lock.c (struct lock): Add lockdirname.
+ (global_history_lock): New global.
+ (global_read_lock): Initialize.
+ (lock_name): Handle const args.
+ (lock_simple_remove): Factor out code in favor of clear_lock call.
+ (set_lock): Handle variable lockdirname.
+ (lock_filesdoneproc): Set new lockdirname.
+ (history_lock, clear_history_lock): New functions.
+ (clear_lock): Avoid segfault on missing lock.
+ (Lock_Cleanup): Clean up history locks when necessary.
+ * history.c (history_write): Use new lock.
+ * sanity.sh (lockfiles-20): Test new lock.
+
+2005-04-28 Derek Price <derek@ximbiot.com>
+
+ * sanity.sh (lockfiles): Port some locking tests over from 1.12.x.
+
+2005-04-28 Derek Price <derek@ximbiot.com>
+
+ * lock.c (clear_lock): Improve comment.
+
+2005-04-28 Derek Price <derek@ximbiot.com>
+
+ * lock.c (struct lock): Store lockdir name.
+ (masterlock): Remove global.
+ (remove_lock_files, clear_lock, set_lock): Update to compensate.
+
+2005-04-20 Derek Price <derek@ximbiot.com>
+
+ * sanity.sh (rcs5): Minor cosmetic change.
+
+2005-04-20 Derek Price <derek@ximbiot.com>
+
+ * sanity.sh (tests): Add rcs4.
+ (rcs5): Add comments.
+
+2005-04-20 Derek Price <derek@ximbiot.com>
+
+ * rcs.c (expand_keywords): Avoid buffer overflow.
+ (Original patch from Stewart Brodie <stewart@eh.org>.)
+
+ * sanity.sh (rcs5): New tests for the above.
+
+2005-03-17 Derek Price <derek@ximbiot.com>
+
+ * login.c (password_entry_parseline): Avoid using uninitialized
+ variable.
+ * rcs.c (RCS_deltas): Avoid buffer overflow.
+ (RCS_checkout): Avoid using uninitialized loglen.
+ * patch.c (patch_fileproc): Free original pointer, not one that may
+ have been incremented.
+ (Thanks to report from Alen Zukich <alen.zukich@klocwork.com>.)
+
+2005-03-17 Derek Price <derek@ximbiot.com>
+
+ * commit.c (checkaddfile): Avoid dereferencing a NULL pointer in
+ response to a rare error.
+ * admin.c (admin_fileproc), log.c (log_expand_revlist), mkmodules.c
+ (checkout_file), rcs.c (RCS_getdate, RCS_deltas, RCS_findlock_or_tip,
+ RCS_tag2rev): Avoid dereferencing NULL pointer.
+ (Thanks to report from Alen Zukich <alen.zukich@klocwork.com>.)
+
+2005-03-17 Derek Price <derek@ximbiot.com>
+
+ * rcs.c (RCS_reparsercsfile): Avoid memory leak.
+ (Thanks to report from Alen Zukich <alen.zukich@klocwork.com>.)
+
+2005-03-17 Derek Price <derek@ximbiot.com>
+
+ * log.c (log_expand_revlist): Suppress message and not error handling
+ when really_quiet.
+
+2005-03-17 Derek Price <derek@ximbiot.com>
+
+ * client.c (call_in_directory): Put function call after var decls.
+
+2005-03-16 Derek Price <derek@ximbiot.com>
+
+ * client.c (call_in_directory), commit.c (commit_filesdoneproc), log.c
+ (log_expand_revlist, log_version), logmsg.c (logfile_write), modules
+ (my_module), no_diff.c (No_Difference), parseinfo.c (Parse_Info), rcs.c
+ (RCS_deltas, RCS_checkin, RCS_addbranch, do_locks, do_symbols),
+ rcscmds.c (RCS_merge), root.c (parse_cvsroot, normalize_cvsroot),
+ update.c (merge_file): Verify assumptions via assertions.
+ (Thanks to (probably) incorrect reports from Alen Zukich
+ <alen.zukich@klocwork.com>.)
+
+2005-03-16 Derek Price <derek@ximbiot.com>
+
+ * server.c (create_adm_p, serve_entry), tag.c (rtag_proc): Avoid memory
+ leaks.
+ (Thanks to report from Alen Zukich <alen.zukich@klocwork.com>.)
+
+2005-03-15 Mark D. Baushke <mdb@cvshome.org>
+
+ * history.c (select_hrec): Avoid possible memory leak.
+
+2005-03-15 Derek Price <derek@ximbiot.com>
+
+ * patch.c (patch_proc): Avoid memory leak.
+ (Thanks to report from Alen Zukich <alen.zukich@klocwork.com>.)
+
+2005-03-11 Mark D. Baushke <mdb@cvshome.org>
+
+ * modules.c (my_module): Protect against free (NULL) code path.
+
+2005-03-11 Derek Price <derek@ximbiot.com>
+
+ * annotate.c (rannotate_proc), fileattr.c (fileattr_write), rcs.c
+ (RCS_deltas), server.c (check_repository_password), update.c (update):
+ Avoid memory leaks.
+ (Thanks to report from Alen Zukich <alen.zukich@klocwork.com>.)
+
+2005-03-09 Derek Price <derek@ximbiot.com>
+
+ * add.c (add, add_directory), buffer.c (allocate_buffer_datas),
+ client.c (update_entries), commit.c (checkaddfile), entries.c
+ (Entries_Open), fileattr.c (fileattr_read), ignore.c (ign_add),
+ import.c (import), main.c (main), parseinfo.c (parse_config), rcs.c
+ (RCS_reparsercsfile, RCS_getbranchpoint, RCS_checkout,
+ RCS_delete_revs, apply_rcs_changes): Avoid memory leaks.
+ (Thanks to report from Alen Zukich <alen.zukich@klocwork.com>.)
+
+ * hardlink.c, hardlink.h: Avoid compiling entire contents of these
+ files w/o preserve permissions support.
+
+2005-03-09 Mark D. Baushke <mdb@cvshome.org>
+
+ * history.c (history, save_file): Cleanup the API to match the
+ comments.
+
+2005-02-27 Jim Meyering <jim@meyering.net>
+
+ * login.c (password_entry_operation): Exit nonzero when
+ failing to close a just-appended-to .cvspass file.
+
+2005-02-26 Larry Jones <lawrence.jones@ugs.com>
+
+ * release.c (release): Remove unneeded code.
+
+2005-02-22 Derek Price <derek@ximbiot.com>
+
+ * edit.c: Load watch settings before setting new ones with
+ `cvs watch on/off'.
+ (Original patch from Jim Hyslop <jhyslop@ieee.org>.)
+
+ * sanity.sh (watch6): New tests for same.
+ (Outline from Jim Hyslop <jhyslop@ieee.org>.)
+
+2005-02-21 Mark D. Baushke <mdb@cvshome.org>
+
+ * import.c (import): Avoid using assert with side effects it may
+ be configured away using NDEBUG.
+ (Patch from Frank Hemer <frank@hemer.org>.)
+
+2005-02-08 Derek Price <derek@ximbiot.com>
+
+ * build_src.com: Build stack.c on VMS.
+ (Suggestion from Piet Schuermans <pschuermans@mac.com>.)
+
+2005-02-01 Larry Jones <lawrence.jones@ugs.com>
+
+ * log.c (log_fileproc, log_expand_revlist): Add support for BASE tag.
+ * sanity.sh (log): New tests for above.
+
+2005-01-31 Derek Price <derek@ximbiot.com>
+
+ * main.c: Update year in copyright notice to match GNU standards.
+ * sanity.sh (version-1): Update to match.
+
+2005-01-31 Derek Price <derek@ximbiot.com>
+
+ * main.c: Rephrase --version message.
+ * sanity.sh (version-1): Update to match.
+
+2005-01-31 Derek Price <derek@ximbiot.com>
+
+ * Makefile.am, add.c, admin.c, annotate.c, checkin.c, checkout.c,
+ classify.c, commit.c, create_adm.c, cvs.h, cvsrc.c, diff.c, entries.c,
+ find_names.c, hash.c, hash.h, history.h, import.c, lock.c, log.c,
+ login.c, logmsg.c, main.c, mkmodules.c, modules.c, myndbm.c, no_diff.c,
+ parseinfo.c, patch.c, rcs.c, rcs.h, rcscmds.c, recurse.c, remove.c,
+ repos.c, root.c, root.h, server.h, stack.c, stack.h, status.c, subr.c,
+ tag.c, update.c, vers_ts.c, version.c: Update copyright notices.
+
+2005-01-29 Derek Price <derek@ximbiot.com>
+
+ * log.c (log_usage): Add note about using -S with revision info
+ supression and selection.
+ (Suggestion from Dan Peterson <dbpete@aol.com>.)
+
+2004-12-19 Larry Jones <lawrence.jones@ugs.com>
+
+ * expand_path.c (expand_path): Rewrite using offsets instead of
+ pointers to simplify and avoid reallocation bugs.
+ (Inspired by Jeremy Bopp <jeremy@motive.com>.)
+
+2004-12-09 Derek Price <derek@ximbiot.com>
+
+ * sanity.sh (tests): Add modules7.
+
+2004-12-09 Derek Price <derek@ximbiot.com>
+
+ * sanity.sh (modules7): New test group.
+ (Based on a patch from Mark D. Baushke <mdb@cvshome.org>, based on a
+ report from Richard Verhoeven <Richard_Verhoeven@WestLB.de>.)
+
+2004-11-18 Mark D. Baushke <mdb@cvshome.org>
+
+ * checkout.c (checkout_proc): Passing the repository to
+ tag_check_valid seems to stop the assertion failure in recurse.c
+ do_recursion.
+ * sanity.sh (basic2-21a): Removed.
+ (basic2-21b): Fixed.
+
+2004-11-17 Mark D. Baushke <mdb@cvshome.org>
+
+ * sanity.sh (basic2-21a): The val-tags file should have
+ at least 'rtagged-by-head y' in it.
+ (basic2-21b): New test showing a cvs bug when val-tags
+ is not properly updated.
+ (Report from "John Elgin" <John@JCElgin.com>.)
+
+2004-11-17 Mark D. Baushke <mdb@cvshome.org>
+
+ * client.c (handle_m, handle_e): Winsock is returning
+ SOCK_ERRNO == WSAENOTSOCK for select() problems and not
+ setting errno. Do not bother with printing an error from a
+ select() that is not returning an non-zero errno.
+ (Report from Conrad T. Pino <Conrad@Pino.com>.)
+
+2004-11-10 Derek Price <derek@ximbiot.com>
+
+ * sanity.sh: Maintain pass/skip/warn status and output at end.
+ (usage): Note new functionality of -e.
+ (warn): New function.
+ (verify_tmp_empty): Warn instead of failing. Delete turds if warn()
+ doesn't exit.
+
+2004-11-10 Derek Price <derek@ximbiot.com>
+
+ * sanity.sh (verify_tmp_empty): New function.
+ (dotest_internal_*): Call verify_tmp_empty as needed.
+
+2004-11-09 Mark D. Baushke <mdb@cvshome.org>
+
+ * sanity.sh: Backport find_tool changes from 1.12.9.1.
+ (SEARCHPATH): New list of PATH directories to search.
+ (Which): Use $SEARCHPATH. Support -a switch.
+ (badtools,set_bad_tool,is_bad_tool): Keep track of tools that do
+ not work for us.
+ (version_test): Obtain the version of tools under test if
+ possible.
+ (tool_find): Rewrite. API changed to allow a list of
+ tests to be used against a list of possible command names found on
+ the SEARCHPATH.
+ (id_tool_test): Check that 'id -u' and 'id -un' work.
+ (expr_tooltest1): Check for NextStep 3.3 expr bug.
+ (expr_tooltest2): Check for SunOS expr multi-line pattern bug.
+ (expr_create_bar): Create a test file for expr testing.
+ (expr_tooltest3): Use it and test for big multi-line identity
+ matches.
+ (expr_set_ENDANCHOR): Find and set the right value for ENDANCHOR.
+ (expr_set_DOTSTAR): Find and set the right value for DOTSTAR.
+ (expr_tooltest_DOTSTAR): Ensure that DOTSTAR works with big
+ matches.
+ (tr_tooltest1): Verify that tr handles NUL bytes.
+ (awk_tooltest1): Verify that awk the BEGIN clause works properly.
+ (awk_tooltest2): Verify that print %c format item works properly.
+
+2004-11-02 Mark D. Baushke <mdb@cvshome.org>
+
+ * filesubr.c (MAXSIZE): New macro.
+ (xreadlink): Ensure initial buffer size does not exceed MAXSIZE.
+ Avoid cast. If readlink fails with buffer size just under MAXSIZE,
+ try again with MAXSIZE.
+
+2004-11-02 Mark D. Baushke <mdb@cvshome.org>
+
+ * filesubr.c (xreadlink): AIX and HP-UX readlink() returns ERANGE
+ when there is not enough room in the buffer.
+
+2004-11-01 Derek Price <derek@ximbiot.com>
+
+ * sanity.sh (rcslib): Fix typo in path.
+
+2004-11-01 Derek Price <derek@ximbiot.com>
+
+ * sanity.sh (rcslib): Test a link to a path longer than 128
+ characters.
+
+2004-10-29 Derek Price <derek@ximbiot.com>
+
+ * filesubr.c (xreadlink): Make sure allocation is tried once at the
+ maximum buffer size. Protect against overflow.
+
+2004-10-29 Mark D. Baushke <mdb@cvshome.org>
+
+ * filesubr.c (SIZE_MAX, SSIZE_MAX): Use #include "xsize.h" instead.
+ (xreadlink): Use xrealloc instead of xmalloc/free.
+
+2004-10-29 Mark D. Baushke <mdb@cvshome.org>
+
+ * filesubr.c (SIZE_MAX, SSIZE_MAX): New constants.
+ (xreadlink): Deal with symlinks longer than 127 bytes.
+ (Problem reported as issue 190 by Gottfried Ganssauge
+ <gotti@cvshome.org>.)
+
+2004-10-28 Mark D. Baushke <mdb@cvshome.org>
+
+ * release.c (release): Allow builds of cvs with --disable-server
+ --disable-client both used for local installation configuration.
+ * root.c (Name_Root): Ditto.
+ * update.c (checkout_file): Ditto.
+ (Problem reported by Jean Olivier Caron <jecar@mlab.t.u-tokyo.ac.jp>.)
+
+2004-10-27 Mark D. Baushke <mdb@cvshome.org>
+
+ * cvs.h (RCS_FLAGS_USETIME): New flag.
+ * rcs.c (RCS_checkin): Add citime argument.
+ * rcs.h (RCS_checkin): Ditto.
+ * checkin.c (Checkin): Pass new RCS_checkin argument.
+ * commit.c (remove_file, checkaddfile): Ditto.
+ * import.c (add_rev): Ditto.
+
+ * sanity.sh (tagdate): Delete tagdate-19b as an incorrect test.
+
+2004-10-27 Mark D. Baushke <mdb@cvshome.org>
+
+ * sanity.sh (tagdate): Provide more output.
+
+2004-10-26 Mark D. Baushke <mdb@cvshome.org>
+
+ * commit.c (checkaddfile): Create a dead version for a new file
+ added to a branch. Fixes FIXCVS for tagdate tests.
+ * sanity.sh (tagdate): Update to expect correct results.
+ (death2, branch-after-import, join, ignore-on-branch): Ditto.
+
+2004-10-26 Derek Price <derek@ximbiot.com>
+
+ * client.c (connect_to_gserver): Avoid truncating error messages from
+ the GSSAPI server.
+ (Report from Dan Peterson <dbpete@aol.com>.)
+
+2004-10-26 Derek Price <derek@ximbiot.com>
+
+ * sanity.sh (import-quirks): Test an even branch number.
+
+2004-10-25 Derek Price <derek@ximbiot.com>
+
+ * import.c (import): Repair regex for regressions introduced in last
+ commit.
+ * sanity.sh (import-quirks): Test a few branch numbers import shouldn't
+ have a problem with.
+
+2004-10-25 Derek Price <derek@ximbiot.com>
+
+ * import.c (import): Anchor and simplify branch verification regex.
+ * sanity.sh (import-quirks): Test another pattern that should fail.
+
+2004-10-25 Mark D. Baushke <mdb@cvshome.org>
+
+ * sanity.sh (tagdate): Added some additional tests and FIXCVS
+ comments for dealing properly with a 'cvs add' of a file to
+ a branch that already exists on the mainline.
+ (Problem reported by Renny Barrett <rbarrett@curamsoftware.com>.)
+
+ * sanity.sh (getrlogdate): New shell function.
+ (tagdate-{13,14,16}): Use it to avoid 'sleep 60' by using
+ the exact 1.1.4.1 timestamp for tagdate-14 and tagdate-16.
+
+2004-10-22 Mark D. Baushke <mdb@cvshome.org>
+
+ * sanity.sh (tagdate): Fix typo.
+
+2004-10-19 Derek Price <derek@ximbiot.com>
+
+ * add.c (add): Avoid attempting to resurrect a dead rev 1.1.
+ * sanity.sh (resurrection): Add test for the above.
+ (Report from Dan Peterson <dbpete@aol.com>.)
+
+2004-10-14 Derek Price <derek@ximbiot.com>
+
+ * import.c (import): Verify branch specifications more thoroughly.
+ * sanity.sh (importb): Adapt to new error message.
+ (import-quirks): New test.
+
+2004-10-04 Derek Price <derek@ximbiot.com>
+
+ * cvs.h (CVSROOT_DFLT): Undef rather than defining to NULL.
+ * main.c (main): Untangle parsing of CVSROOT, eliminating several
+ variables in the process. Simplify xmalloc/sprintf with asnprintf.
+
+2004-10-01 Mark D. Baushke <mdb@cvshome.org>
+
+ * main.c (main): Initialize CVSroot before it is used.
+ (Report and patch by Martin Neitzel <neitzel@sco.gaertner.de>.)
+ * sanity.sh (status): Test it.
+
+2004-09-25 Mark D. Baushke <mdb@cvshome.org>
+
+ * sanity.sh (parseroot2): Correct two test names. Restore CVSROOT.
+
+ * sanity.sh (parseroot2): Expand dokeep inline.
+
+2004-09-24 Derek Price <derek@ximbiot.com>
+
+ * sanity.sh (tests): Add parseroot2.
+
+2004-09-24 Derek Price <derek@ximbiot.com>
+
+ * sanity.sh (parseroot2): New test for root parsing consistency.
+ (Original patch from Alexander Taler <dissent@cvshome.org>.)
+
+ * cvs.h (Name_Root, free_cvsroot_t, parse_cvsroot, local_cvsroot,
+ Create_Root, root_allow_add, root_allow_free, root_allow_ok): Move
+ these protos to...
+ * root.h: ...here.
+ * client.c (arg_should_not_be_sent_to_server), recurse.c
+ (start_recusrion, do_recursion): Use new Name_Root API.
+ * main.c (current_root): Remove global.
+ (set_root_directory): Set current_parsed_root directly.
+ (main): Use new Name_Root API. Restore deletion of root directories
+ list.
+ * root.c (Name_Root): Return a parsed cvsroot_t rather than a string.
+
+2004-09-23 Derek Price <derek@ximbiot.com>
+
+ * sanity.sh (depends_on_ssh, sshstdio): Don't use skip() to skip
+ remote-only tests.
+
+2004-09-23 Mark D. Baushke <mdb@cvshome.org>
+
+ * server.c (cvs_output, cvs_output_binary): fflush (stderr)
+ here to avoid problems with 'cvs status 2>&1'.
+ (Report by Frank Hemer <frank@hemer.org>.)
+
+2004-09-23 Derek Price <derek@ximbiot.com>
+
+ * sanity.sh (crerepos, sshstdio): Minor modifications to make use of
+ the new depends_on_?sh API.
+
+2004-09-23 Derek Price <derek@ximbiot.com>
+
+ * sanity.sh: Accept new -e option to interpret non-fatal calls to skip
+ as errors.
+ (skip, depends_on_rsh, depends_on_ssh): New functions.
+
+2004-09-12 Mark D. Baushke <mdb@cvshome.org>
+
+ * rcs.c (RCS_checkout): Allow noexec to do checkouts when
+ server_active is true.
+ * sanity.sh (join7): Test above change (fixes a FIXCVS).
+
+2004-09-08 Mark D. Baushke <mdb@cvshome.org>
+
+ * sanity.sh (join7): Fix if-then-else conditional.
+
+ * server.c (server_updated): Deal with cvs -n update -jt1 -jt2
+ "protocol error: uncounted data discarded" problem.
+ * sanity.sh (join7): New test for this case.
+
+2004-08-24 Derek Price <derek@ximbiot.com>
+
+ * recurse.c (start_recursion): Don't shorten //. to / (use //).
+
+2004-08-24 Derek Price <derek@ximbiot.com>
+
+ * recurse.c (start_recursion): Strip trailing CWD indirections on
+ repository.
+ * sanity.sh (rstar-toplevel): Update to account for new behavior.
+ (Report from Dan Peterson <dbpete@aol.com>.)
+
+2004-08-24 Mark D. Baushke <mdb@cvshome.org>
+
+ * recurse.c (do_recursion): Correct test for calling
+ server_pause_check to occur when locktype != CVS_LOCK_WRITE.
+ (Patch suggested by Ian Lance Taylor <ian@wasabisystems.com>
+ in bug#198).
+
+2004-08-24 Derek Price <derek@ximbiot.com>
+
+ * rcs.c (translate_symtag): Prevent infinite loop.
+ * tag.c (tag_check_valid): Check tag syntax before searching for tags.
+ * sanity.sh (tag-space): Some tests for the above.
+ (Report from Dan Peterson <dbpete@aol.com>.)
+
+2004-08-24 Mark D. Baushke <mdb@cvshome.org>
+
+ * ignore.c (ignore_directory): Include the terminating NUL
+ character in the directory name comparison to avoid matching
+ substrings of directories by accident.
+ (Report and suggested fix from James E Wilson
+ <wilson@specifixinc.com>.)
+ * sanity.sh (modules4): Add some more tests testing the above
+ change.
+
+2004-08-17 Mark D. Baushke <mdb@cvshome.org>
+
+ * sanity.sh (sshstdio): Fix comment typo plus gratuitous
+ reformatting.
+
+ * client.c (handle_m): Workaround to deal with stdio getting put
+ into non-blocking via redirection of stderr and interaction with
+ ssh on some platforms. On those boxes, stdio can put stdout
+ unexpectedly into non-blocking mode which may lead to fwrite() or
+ fflush() failing with EAGAIN, but cvs not checking for the error.
+ (Patch suggested by Frank Hemer <frank@hemer.org>.)
+
+ * client.c (handle_e): Similar fix for stderr.
+ * sanity.sh (sshstdio): New test for non-blocking stdio via ssh.
+
+2004-08-11 Derek Price <derek@ximbiot.com>
+
+ * sanity.sh (basicc): Work around a problem in Linux 2.2 & Bash 2.05b
+ which prevents a `cd ..' from a deleted directory from working.
+ (Original patch from Matthew Ogilvie <mmo9317bd@mailcan.com>.)
+
+2004-06-22 Derek Price <derek@ximbiot.com>
+
+ * wrapper.c: Add explicit "void" return type to "wrap_clean_fmt_str"
+ definition.
+ (Patch from Conrad T. Pino <Conrad@Pino.com>.)
+
2004-06-09 Derek Price <derek@ximbiot.com>
* commit.c, filesubr.c, history.c, server.c, wrapper.c: Various
@@ -531,7 +1603,7 @@
* tag.c (tag_fileproc): Ditto.
* update.c (checkout_file): Ditto.
* server.c (server_updated): Do not buf_free (filebuf) here.
-
+
2004-02-13 Larry Jones <lawrence.jones@ugsplm.com>
* rcs.c (locate_rcs): Remove unused variables.
@@ -749,7 +1821,7 @@
"Protocol error: uncounted data discarded" messages in some
circumstances.
(Problem reported by "Jim.Hyslop" <Jim.Hyslop@Leitch.com>.)
-
+
2003-12-03 Derek Price <derek@ximbiot.com>
* sanity.sh (recase-8csss): rename to...
@@ -945,7 +2017,7 @@
CVSROOT files being in the way since the client skips destination
validity checks since it should be rare that a client is running
in client/server mode on the server and CVS has no current way to
- check if it is running on the server.
+ check if it is running on the server.
(check_repository-3): Test renamed to checkout_repository-3.
(dottedroot): New test to check that a CVSROOT with a "." in the
name will work.
@@ -1005,7 +2077,7 @@
2003-10-25 Mark D. Baushke <mdb@cvshome.org>
* sanity.sh (parseroot): Perform this test in a subdirectory.
- It should avoid problems on case-insensitive systems where
+ It should avoid problems on case-insensitive systems where
CVSROOT and cvsroot are the same directory (eg, MacOS X).
2003-10-24 Derek Price <derek@ximbiot.com>
@@ -1025,7 +2097,7 @@
* sanity.sh (join6): New testcase for above.
(Suggested by Paul Edwards, from somewhere in Australia.)
(import): Fix collateral damage.
-
+
2003-10-23 Derek Price <derek@ximbiot.com>
* sanity.sh (fail): Refer the user to the `TESTS' and `check.log' files
@@ -1046,7 +2118,7 @@
exists.
(Reported by Rodolfo Schulz de Lima <rodolfo@rodsoft.org>.)
* sanity.sh (admin): Test these changes.
-
+
2003-10-17 Mark D. Baushke <mdb@cvshome.org>
* admin.c (admin_fileproc): Force tag match on admin
@@ -1653,7 +2725,7 @@
rtag' as various parts of cvs "know" how to automatically branch files
(eg: cvs add). Trying to remember state is getting "Too Hard (TM)")
* sanity.sh (branches3): Test the CVS_LOCAL_BRANCH_NUM feature.
-
+
2003-03-04 Derek Price <derek@ximbiot.com>
* history.c (history_write): Remove unneeded O_CREAT in the call to
@@ -1708,7 +2780,7 @@
This bug was discovered and fixed for FreeBSD cvs. See v 1.21 of
<http://www.freebsd.org/cgi/cvsweb.cgi/src/contrib/cvs/src/rcs.c.diff>
- for more information.
+ for more information.
* sanity.sh (rcs4): Tests for same.
(Patch from Mark D. Baushke <mdb@cvshome.org>.)
diff --git a/contrib/cvs/src/Makefile.am b/contrib/cvs/src/Makefile.am
index c0ab617..63e6b18 100644
--- a/contrib/cvs/src/Makefile.am
+++ b/contrib/cvs/src/Makefile.am
@@ -1,8 +1,10 @@
## Process this file with automake to produce Makefile.in
# Makefile for GNU CVS program.
-# Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994,
-# 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
-# Free Software Foundation, Inc.
+#
+# Copyright (C) 1986-2005 The Free Software Foundation, Inc.
+#
+# Portions Copyright (C) 1998-2005 Derek Price, Ximbiot <http://ximbiot.com>,
+# and others.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/contrib/cvs/src/Makefile.in b/contrib/cvs/src/Makefile.in
index c3aa0fc..3765523 100644
--- a/contrib/cvs/src/Makefile.in
+++ b/contrib/cvs/src/Makefile.in
@@ -1,8 +1,8 @@
-# Makefile.in generated by automake 1.7.9 from Makefile.am.
+# Makefile.in generated by automake 1.9.6 from Makefile.am.
# @configure_input@
-# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
-# Free Software Foundation, Inc.
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
@@ -15,9 +15,11 @@
@SET_MAKE@
# Makefile for GNU CVS program.
-# Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994,
-# 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
-# Free Software Foundation, Inc.
+#
+# Copyright (C) 1986-2005 The Free Software Foundation, Inc.
+#
+# Portions Copyright (C) 1998-2005 Derek Price, Ximbiot <http://ximbiot.com>,
+# and others.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -29,6 +31,7 @@
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
+
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
@@ -36,7 +39,6 @@ pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = ..
-
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
INSTALL = @INSTALL@
install_sh_DATA = $(install_sh) -c -m 644
@@ -50,6 +52,55 @@ POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
+bin_PROGRAMS = cvs$(EXEEXT)
+subdir = src
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
+ $(srcdir)/cvsbug.in ChangeLog
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
+ $(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES = cvsbug
+am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(bindir)"
+binPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
+PROGRAMS = $(bin_PROGRAMS)
+am_cvs_OBJECTS = add.$(OBJEXT) admin.$(OBJEXT) annotate.$(OBJEXT) \
+ buffer.$(OBJEXT) checkin.$(OBJEXT) checkout.$(OBJEXT) \
+ classify.$(OBJEXT) client.$(OBJEXT) commit.$(OBJEXT) \
+ create_adm.$(OBJEXT) cvsrc.$(OBJEXT) diff.$(OBJEXT) \
+ edit.$(OBJEXT) entries.$(OBJEXT) error.$(OBJEXT) \
+ expand_path.$(OBJEXT) fileattr.$(OBJEXT) filesubr.$(OBJEXT) \
+ find_names.$(OBJEXT) hardlink.$(OBJEXT) hash.$(OBJEXT) \
+ history.$(OBJEXT) ignore.$(OBJEXT) import.$(OBJEXT) \
+ lock.$(OBJEXT) log.$(OBJEXT) login.$(OBJEXT) logmsg.$(OBJEXT) \
+ main.$(OBJEXT) mkmodules.$(OBJEXT) modules.$(OBJEXT) \
+ myndbm.$(OBJEXT) no_diff.$(OBJEXT) parseinfo.$(OBJEXT) \
+ patch.$(OBJEXT) rcs.$(OBJEXT) rcscmds.$(OBJEXT) \
+ recurse.$(OBJEXT) release.$(OBJEXT) remove.$(OBJEXT) \
+ repos.$(OBJEXT) root.$(OBJEXT) run.$(OBJEXT) \
+ scramble.$(OBJEXT) server.$(OBJEXT) stack.$(OBJEXT) \
+ status.$(OBJEXT) subr.$(OBJEXT) tag.$(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
+binSCRIPT_INSTALL = $(INSTALL_SCRIPT)
+SCRIPTS = $(bin_SCRIPTS)
+DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+SOURCES = $(cvs_SOURCES)
+DIST_SOURCES = $(cvs_SOURCES)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMDEP_FALSE = @AMDEP_FALSE@
AMDEP_TRUE = @AMDEP_TRUE@
@@ -105,7 +156,6 @@ RANLIB = @RANLIB@
ROFF = @ROFF@
SENDMAIL = @SENDMAIL@
SET_MAKE = @SET_MAKE@
-
SHELL = /bin/sh
STRIP = @STRIP@
TEXI2DVI = @TEXI2DVI@
@@ -120,6 +170,8 @@ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
bindir = @bindir@
build_alias = @build_alias@
datadir = @datadir@
@@ -133,6 +185,7 @@ libdir = @libdir@
libexecdir = @libexecdir@
localstatedir = @localstatedir@
mandir = @mandir@
+mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
prefix = @prefix@
program_transform_name = @program_transform_name@
@@ -140,6 +193,7 @@ sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
+with_default_rsh = @with_default_rsh@
# $(includeopt) is CVS specific and set by configure
# FIXME - This includes line is dependant on its order. This means there is
@@ -147,8 +201,6 @@ target_alias = @target_alias@
# try and remove naming ocnflicts and fix Automake to allow particular includes
# to be attached only to particular object files. Short term fix is either or.
INCLUDES = -I$(top_srcdir)/lib -I$(top_srcdir)/diff -I$(top_srcdir)/zlib $(includeopt)
-
-bin_PROGRAMS = cvs
bin_SCRIPTS = cvsbug
# The cvs executable
@@ -224,7 +276,6 @@ cvs_SOURCES = \
update.h \
watch.h
-
cvs_LDADD = \
../diff/libdiff.a \
../lib/libcvs.a \
@@ -245,99 +296,51 @@ EXTRA_DIST = \
build_src.com \
sanity.sh
-subdir = src
-ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
-CONFIG_HEADER = $(top_builddir)/config.h
-CONFIG_CLEAN_FILES = cvsbug
-bin_PROGRAMS = cvs$(EXEEXT)
-PROGRAMS = $(bin_PROGRAMS)
-
-am_cvs_OBJECTS = add.$(OBJEXT) admin.$(OBJEXT) annotate.$(OBJEXT) \
- buffer.$(OBJEXT) checkin.$(OBJEXT) checkout.$(OBJEXT) \
- classify.$(OBJEXT) client.$(OBJEXT) commit.$(OBJEXT) \
- create_adm.$(OBJEXT) cvsrc.$(OBJEXT) diff.$(OBJEXT) \
- edit.$(OBJEXT) entries.$(OBJEXT) error.$(OBJEXT) \
- expand_path.$(OBJEXT) fileattr.$(OBJEXT) filesubr.$(OBJEXT) \
- find_names.$(OBJEXT) hardlink.$(OBJEXT) hash.$(OBJEXT) \
- history.$(OBJEXT) ignore.$(OBJEXT) import.$(OBJEXT) \
- lock.$(OBJEXT) log.$(OBJEXT) login.$(OBJEXT) logmsg.$(OBJEXT) \
- main.$(OBJEXT) mkmodules.$(OBJEXT) modules.$(OBJEXT) \
- myndbm.$(OBJEXT) no_diff.$(OBJEXT) parseinfo.$(OBJEXT) \
- patch.$(OBJEXT) rcs.$(OBJEXT) rcscmds.$(OBJEXT) \
- recurse.$(OBJEXT) release.$(OBJEXT) remove.$(OBJEXT) \
- repos.$(OBJEXT) root.$(OBJEXT) run.$(OBJEXT) scramble.$(OBJEXT) \
- server.$(OBJEXT) stack.$(OBJEXT) status.$(OBJEXT) \
- subr.$(OBJEXT) tag.$(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
-cvs_LDFLAGS =
-SCRIPTS = $(bin_SCRIPTS)
-
-
-DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
-depcomp = $(SHELL) $(top_srcdir)/depcomp
-am__depfiles_maybe = depfiles
-@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/add.Po ./$(DEPDIR)/admin.Po \
-@AMDEP_TRUE@ ./$(DEPDIR)/annotate.Po ./$(DEPDIR)/buffer.Po \
-@AMDEP_TRUE@ ./$(DEPDIR)/checkin.Po ./$(DEPDIR)/checkout.Po \
-@AMDEP_TRUE@ ./$(DEPDIR)/classify.Po ./$(DEPDIR)/client.Po \
-@AMDEP_TRUE@ ./$(DEPDIR)/commit.Po ./$(DEPDIR)/create_adm.Po \
-@AMDEP_TRUE@ ./$(DEPDIR)/cvsrc.Po ./$(DEPDIR)/diff.Po \
-@AMDEP_TRUE@ ./$(DEPDIR)/edit.Po ./$(DEPDIR)/entries.Po \
-@AMDEP_TRUE@ ./$(DEPDIR)/error.Po ./$(DEPDIR)/expand_path.Po \
-@AMDEP_TRUE@ ./$(DEPDIR)/fileattr.Po ./$(DEPDIR)/filesubr.Po \
-@AMDEP_TRUE@ ./$(DEPDIR)/find_names.Po ./$(DEPDIR)/hardlink.Po \
-@AMDEP_TRUE@ ./$(DEPDIR)/hash.Po ./$(DEPDIR)/history.Po \
-@AMDEP_TRUE@ ./$(DEPDIR)/ignore.Po ./$(DEPDIR)/import.Po \
-@AMDEP_TRUE@ ./$(DEPDIR)/lock.Po ./$(DEPDIR)/log.Po \
-@AMDEP_TRUE@ ./$(DEPDIR)/login.Po ./$(DEPDIR)/logmsg.Po \
-@AMDEP_TRUE@ ./$(DEPDIR)/main.Po ./$(DEPDIR)/mkmodules.Po \
-@AMDEP_TRUE@ ./$(DEPDIR)/modules.Po ./$(DEPDIR)/myndbm.Po \
-@AMDEP_TRUE@ ./$(DEPDIR)/no_diff.Po ./$(DEPDIR)/parseinfo.Po \
-@AMDEP_TRUE@ ./$(DEPDIR)/patch.Po ./$(DEPDIR)/rcs.Po \
-@AMDEP_TRUE@ ./$(DEPDIR)/rcscmds.Po ./$(DEPDIR)/recurse.Po \
-@AMDEP_TRUE@ ./$(DEPDIR)/release.Po ./$(DEPDIR)/remove.Po \
-@AMDEP_TRUE@ ./$(DEPDIR)/repos.Po ./$(DEPDIR)/root.Po \
-@AMDEP_TRUE@ ./$(DEPDIR)/run.Po ./$(DEPDIR)/scramble.Po \
-@AMDEP_TRUE@ ./$(DEPDIR)/server.Po ./$(DEPDIR)/stack.Po \
-@AMDEP_TRUE@ ./$(DEPDIR)/status.Po ./$(DEPDIR)/subr.Po \
-@AMDEP_TRUE@ ./$(DEPDIR)/tag.Po ./$(DEPDIR)/update.Po \
-@AMDEP_TRUE@ ./$(DEPDIR)/vers_ts.Po ./$(DEPDIR)/version.Po \
-@AMDEP_TRUE@ ./$(DEPDIR)/watch.Po ./$(DEPDIR)/wrapper.Po \
-@AMDEP_TRUE@ ./$(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 $@
-DIST_SOURCES = $(cvs_SOURCES)
-DIST_COMMON = $(srcdir)/Makefile.in ChangeLog Makefile.am cvsbug.in
-SOURCES = $(cvs_SOURCES)
-
all: all-am
.SUFFIXES:
.SUFFIXES: .c .o .obj
-$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/Makefile'; \
cd $(top_srcdir) && \
$(AUTOMAKE) --gnu src/Makefile
-Makefile: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.in $(top_builddir)/config.status
- cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)
-cvsbug: $(top_builddir)/config.status cvsbug.in
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+cvsbug: $(top_builddir)/config.status $(srcdir)/cvsbug.in
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
-binPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
install-binPROGRAMS: $(bin_PROGRAMS)
@$(NORMAL_INSTALL)
- $(mkinstalldirs) $(DESTDIR)$(bindir)
+ test -z "$(bindir)" || $(mkdir_p) "$(DESTDIR)$(bindir)"
@list='$(bin_PROGRAMS)'; for p in $$list; do \
p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
if test -f $$p \
; then \
f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \
- echo " $(INSTALL_PROGRAM_ENV) $(binPROGRAMS_INSTALL) $$p $(DESTDIR)$(bindir)/$$f"; \
- $(INSTALL_PROGRAM_ENV) $(binPROGRAMS_INSTALL) $$p $(DESTDIR)$(bindir)/$$f || exit 1; \
+ echo " $(INSTALL_PROGRAM_ENV) $(binPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(bindir)/$$f'"; \
+ $(INSTALL_PROGRAM_ENV) $(binPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(bindir)/$$f" || exit 1; \
else :; fi; \
done
@@ -345,8 +348,8 @@ uninstall-binPROGRAMS:
@$(NORMAL_UNINSTALL)
@list='$(bin_PROGRAMS)'; for p in $$list; do \
f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \
- echo " rm -f $(DESTDIR)$(bindir)/$$f"; \
- rm -f $(DESTDIR)$(bindir)/$$f; \
+ echo " rm -f '$(DESTDIR)$(bindir)/$$f'"; \
+ rm -f "$(DESTDIR)$(bindir)/$$f"; \
done
clean-binPROGRAMS:
@@ -354,16 +357,15 @@ clean-binPROGRAMS:
cvs$(EXEEXT): $(cvs_OBJECTS) $(cvs_DEPENDENCIES)
@rm -f cvs$(EXEEXT)
$(LINK) $(cvs_LDFLAGS) $(cvs_OBJECTS) $(cvs_LDADD) $(LIBS)
-binSCRIPT_INSTALL = $(INSTALL_SCRIPT)
install-binSCRIPTS: $(bin_SCRIPTS)
@$(NORMAL_INSTALL)
- $(mkinstalldirs) $(DESTDIR)$(bindir)
+ test -z "$(bindir)" || $(mkdir_p) "$(DESTDIR)$(bindir)"
@list='$(bin_SCRIPTS)'; for p in $$list; do \
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
if test -f $$d$$p; then \
f=`echo "$$p" | sed 's|^.*/||;$(transform)'`; \
- echo " $(binSCRIPT_INSTALL) $$d$$p $(DESTDIR)$(bindir)/$$f"; \
- $(binSCRIPT_INSTALL) $$d$$p $(DESTDIR)$(bindir)/$$f; \
+ echo " $(binSCRIPT_INSTALL) '$$d$$p' '$(DESTDIR)$(bindir)/$$f'"; \
+ $(binSCRIPT_INSTALL) "$$d$$p" "$(DESTDIR)$(bindir)/$$f"; \
else :; fi; \
done
@@ -371,12 +373,12 @@ uninstall-binSCRIPTS:
@$(NORMAL_UNINSTALL)
@list='$(bin_SCRIPTS)'; for p in $$list; do \
f=`echo "$$p" | sed 's|^.*/||;$(transform)'`; \
- echo " rm -f $(DESTDIR)$(bindir)/$$f"; \
- rm -f $(DESTDIR)$(bindir)/$$f; \
+ echo " rm -f '$(DESTDIR)$(bindir)/$$f'"; \
+ rm -f "$(DESTDIR)$(bindir)/$$f"; \
done
mostlyclean-compile:
- -rm -f *.$(OBJEXT) core *.core
+ -rm -f *.$(OBJEXT)
distclean-compile:
-rm -f *.tab.c
@@ -438,36 +440,20 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zlib.Po@am__quote@
.c.o:
-@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \
-@am__fastdepCC_TRUE@ -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<; \
-@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \
-@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
-@am__fastdepCC_TRUE@ fi
+@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(COMPILE) -c `test -f '$<' || echo '$(srcdir)/'`$<
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
.c.obj:
-@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \
-@am__fastdepCC_TRUE@ -c -o $@ `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi`; \
-@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \
-@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
-@am__fastdepCC_TRUE@ fi
+@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(COMPILE) -c `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi`
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
uninstall-info-am:
-ETAGS = etags
-ETAGSFLAGS =
-
-CTAGS = ctags
-CTAGSFLAGS =
-
-tags: TAGS
-
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
@@ -476,6 +462,7 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
mkid -fID $$unique
+tags: TAGS
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
@@ -487,10 +474,11 @@ TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
- test -z "$(ETAGS_ARGS)$$tags$$unique" \
- || $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
- $$tags $$unique
-
+ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique; \
+ fi
ctags: CTAGS
CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
@@ -513,10 +501,6 @@ GTAGS:
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
-DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
-
-top_distdir = ..
-distdir = $(top_distdir)/$(PACKAGE)-$(VERSION)
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
@@ -530,7 +514,7 @@ distdir: $(DISTFILES)
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
dir="/$$dir"; \
- $(mkinstalldirs) "$(distdir)$$dir"; \
+ $(mkdir_p) "$(distdir)$$dir"; \
else \
dir=''; \
fi; \
@@ -549,9 +533,10 @@ check-am: all-am
$(MAKE) $(AM_MAKEFLAGS) check-local
check: check-am
all-am: Makefile $(PROGRAMS) $(SCRIPTS)
-
installdirs:
- $(mkinstalldirs) $(DESTDIR)$(bindir) $(DESTDIR)$(bindir)
+ for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(bindir)"; do \
+ test -z "$$dir" || $(mkdir_p) "$$dir"; \
+ done
install: install-am
install-exec: install-exec-am
install-data: install-data-am
@@ -571,7 +556,7 @@ mostlyclean-generic:
clean-generic:
distclean-generic:
- -rm -f $(CONFIG_CLEAN_FILES)
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES)
maintainer-clean-generic:
@@ -591,6 +576,8 @@ dvi: dvi-am
dvi-am:
+html: html-am
+
info: info-am
info-am:
@@ -628,14 +615,15 @@ uninstall-am: uninstall-binPROGRAMS uninstall-binSCRIPTS \
.PHONY: CTAGS GTAGS all all-am check check-am check-local clean \
clean-binPROGRAMS clean-generic ctags distclean \
distclean-compile distclean-generic distclean-tags distdir dvi \
- dvi-am 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 pdf pdf-am ps ps-am \
- tags uninstall uninstall-am uninstall-binPROGRAMS \
- uninstall-binSCRIPTS uninstall-info-am
+ dvi-am html html-am info info-am install install-am \
+ install-binPROGRAMS install-binSCRIPTS install-data \
+ install-data-am install-exec install-exec-am install-info \
+ install-info-am install-man install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \
+ uninstall-am uninstall-binPROGRAMS uninstall-binSCRIPTS \
+ uninstall-info-am
check-local: localcheck remotecheck
diff --git a/contrib/cvs/src/add.c b/contrib/cvs/src/add.c
index 4f3f55e..820121b 100644
--- a/contrib/cvs/src/add.c
+++ b/contrib/cvs/src/add.c
@@ -1,6 +1,11 @@
/*
- * Copyright (c) 1992, Brian Berliner and Jeff Polk
- * Copyright (c) 1989-1992, Brian Berliner
+ * Copyright (C) 1986-2005 The Free Software Foundation, Inc.
+ *
+ * Portions Copyright (C) 1998-2005 Derek Price, Ximbiot <http://ximbiot.com>,
+ * and others.
+ *
+ * Portions Copyright (c) 1992, Brian Berliner and Jeff Polk
+ * Portions Copyright (c) 1989-1992, Brian Berliner
*
* You may distribute under the terms of the GNU General Public License as
* specified in the README file that comes with the CVS source distribution.
@@ -37,8 +42,9 @@ static int build_entry PROTO((const char *repository, const char *user,
static const char *const add_usage[] =
{
"Usage: %s %s [-k rcs-kflag] [-m message] files...\n",
- "\t-k\tUse \"rcs-kflag\" to add the file with the specified kflag.\n",
- "\t-m\tUse \"message\" for the creation log.\n",
+ "\t-k rcs-kflag\tUse \"rcs-kflag\" to add the file with the specified\n",
+ "\t\t\tkflag.\n",
+ "\t-m message\tUse \"message\" for the creation log.\n",
"(Specify the --help global option for a list of other help options)\n",
NULL
};
@@ -75,12 +81,12 @@ add (argc, argv)
switch (c)
{
case 'k':
- if (options)
- free (options);
+ if (options) free (options);
options = RCS_check_kflag (optarg);
break;
case 'm':
+ if (message) free (message);
message = xstrdup (optarg);
break;
case '?':
@@ -155,11 +161,17 @@ add (argc, argv)
int j;
if (argc == 0)
+ {
/* We snipped out all the arguments in the above sanity
check. We can just forget the whole thing (and we
better, because if we fired up the server and passed it
nothing, it would spit back a usage message). */
+ if (options)
+ free (options);
+ if (message)
+ free (message);
return err;
+ }
start_server ();
ign_setup ();
@@ -469,7 +481,25 @@ same name already exists in the repository.");
char *prev = previous_rev (vers->srcfile,
vers->vn_rcs);
int status;
- assert (prev != NULL);
+ if (prev == NULL)
+ {
+ /* There is no previous revision. Either:
+ *
+ * * Revision 1.1 was dead, as when a file was
+ * inititially added on a branch,
+ *
+ * or
+ *
+ * * All previous revisions have been deleted.
+ * For instance, via `admin -o'.
+ */
+ if (!really_quiet)
+ error (0, 0,
+"File `%s' has no previous revision to resurrect.",
+ finfo.fullname);
+ free (prev);
+ goto skip_this_file;
+ }
if (!quiet)
error (0, 0,
"Resurrecting file `%s' from revision %s.",
@@ -665,6 +695,8 @@ cannot resurrect %s; RCS file removed by second party", finfo.fullname);
server_checked_in (finfo.file, finfo.update_dir, repository);
#endif
}
+
+skip_this_file:
free (repository);
Entries_Close (entries);
@@ -745,11 +777,7 @@ add_directory (finfo)
error (0, errno, "cannot chdir to %s", finfo->fullname);
return 1;
}
-#ifdef SERVER_SUPPORT
if (!server_active && isfile (CVSADM))
-#else
- if (isfile (CVSADM))
-#endif
{
error (0, 0, "%s/%s already exists", finfo->fullname, CVSADM);
goto out;
@@ -818,7 +846,10 @@ add_directory (finfo)
fileattr_write ();
fileattr_free ();
if (attrs != NULL)
+ {
free (attrs);
+ attrs = NULL;
+ }
/*
* Set up an update list with a single title node for Update_Logfile
@@ -838,9 +869,7 @@ add_directory (finfo)
dellist (&ulist);
}
-#ifdef SERVER_SUPPORT
if (!server_active)
-#endif
Create_Admin (".", finfo->fullname, rcsdir, tag, date, nonbranch, 0, 1);
if (tag)
free (tag);
@@ -858,6 +887,8 @@ add_directory (finfo)
free (rcsdir);
free (message);
+ if (attrs != NULL)
+ free (attrs);
return 0;
@@ -865,6 +896,7 @@ out:
if (restore_cwd (&cwd, NULL))
error_exit ();
free_cwd (&cwd);
+ if (message) free (message);
if (rcsdir != NULL)
free (rcsdir);
return 0;
diff --git a/contrib/cvs/src/admin.c b/contrib/cvs/src/admin.c
index 05067b8..186e27c 100644
--- a/contrib/cvs/src/admin.c
+++ b/contrib/cvs/src/admin.c
@@ -1,6 +1,11 @@
/*
- * Copyright (c) 1992, Brian Berliner and Jeff Polk
- * Copyright (c) 1989-1992, Brian Berliner
+ * Copyright (C) 1986-2005 The Free Software Foundation, Inc.
+ *
+ * Portions Copyright (C) 1998-2005 Derek Price, Ximbiot <http://ximbiot.com>,
+ * and others.
+ *
+ * Portions Copyright (c) 1992, Brian Berliner and Jeff Polk
+ * Portions Copyright (c) 1989-1992, Brian Berliner
*
* You may distribute under the terms of the GNU General Public License as
* specified in the README file that comes with the CVS source distribution.
@@ -379,17 +384,13 @@ admin (argc, argv)
/* The use of `cvs admin -k' is unrestricted. However, any other
option is restricted if the group CVS_ADMIN_GROUP exists on the
server. */
- if (
-# ifdef CLIENT_SUPPORT
- /* This is only "secure" on the server, since the user could edit the
- * RCS file on a local host, but some people like this kind of
- * check anyhow. The alternative would be to check only when
- * (server_active) rather than when not on the client.
- */
- !current_parsed_root->isremote &&
-# endif /* CLIENT_SUPPORT */
- !only_k_option
- && (grp = getgrnam(CVS_ADMIN_GROUP)) != NULL)
+ /* This is only "secure" on the server, since the user could edit the
+ * RCS file on a local host, but some people like this kind of
+ * check anyhow. The alternative would be to check only when
+ * (server_active) rather than when not on the client.
+ */
+ if (!current_parsed_root->isremote && !only_k_option &&
+ (grp = getgrnam(CVS_ADMIN_GROUP)) != NULL)
{
#ifdef HAVE_GETGROUPS
gid_t *grps;
@@ -816,6 +817,13 @@ admin_fileproc (callerdat, finfo)
{
tag = xstrdup (arg + 2);
rev = RCS_head (rcs);
+ if (!rev)
+ {
+ error (0, 0, "No head revision in archive file `%s'.",
+ rcs->path);
+ status = 1;
+ continue;
+ }
}
else
{
diff --git a/contrib/cvs/src/annotate.c b/contrib/cvs/src/annotate.c
index 8bf330f..d6d0acc 100644
--- a/contrib/cvs/src/annotate.c
+++ b/contrib/cvs/src/annotate.c
@@ -1,6 +1,11 @@
/*
- * Copyright (c) 1992, Brian Berliner and Jeff Polk
- * Copyright (c) 1989-1992, Brian Berliner
+ * Copyright (C) 1986-2005 The Free Software Foundation, Inc.
+ *
+ * Portions Copyright (C) 1998-2005 Derek Price, Ximbiot <http://ximbiot.com>,
+ * and others.
+ *
+ * Portions Copyright (c) 1992, Brian Berliner and Jeff Polk
+ * Portions Copyright (c) 1989-1992, Brian Berliner
*
* You may distribute under the terms of the GNU General Public License as
* specified in the README file that comes with the CVS source distribution.
@@ -222,6 +227,7 @@ rannotate_proc (argc, argv, xwhere, mwhere, mfile, shorten, local, mname, msg)
{
error (0, errno, "cannot chdir to %s", repository);
free (repository);
+ free (where);
return (1);
}
/* End section which is identical to patch_proc. */
diff --git a/contrib/cvs/src/buffer.c b/contrib/cvs/src/buffer.c
index fb98e11..8e66355 100644
--- a/contrib/cvs/src/buffer.c
+++ b/contrib/cvs/src/buffer.c
@@ -1,3 +1,17 @@
+/*
+ * Copyright (C) 1996-2005 The Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
/* Code for the buffer data structure. */
#include <assert.h>
@@ -110,11 +124,13 @@ allocate_buffer_datas ()
/* Allocate buffer_data structures in blocks of 16. */
#define ALLOC_COUNT (16)
- alc = ((struct buffer_data *)
- xmalloc (ALLOC_COUNT * sizeof (struct buffer_data)));
+ alc = xmalloc (ALLOC_COUNT * sizeof (struct buffer_data));
space = (char *) valloc (ALLOC_COUNT * BUFFER_DATA_SIZE);
- if (alc == NULL || space == NULL)
+ if (!space)
+ {
+ free (alc);
return;
+ }
for (i = 0; i < ALLOC_COUNT; i++, alc++, space += BUFFER_DATA_SIZE)
{
alc->next = free_buffer_data;
@@ -1406,10 +1422,16 @@ stdio_buffer_shutdown (buf)
{
struct stdio_buffer_closure *bc = buf->closure;
struct stat s;
- int closefp = 1;
+ int closefp, statted;
- /* Must be a pipe or a socket. What could go wrong? */
- assert (fstat (fileno (bc->fp), &s) != -1);
+ /* Must be a pipe or a socket. What could go wrong?
+ * Well, apparently for disconnected clients under AIX, the
+ * fstat() will return -1 on the server if the client has gone
+ * away.
+ */
+ if (fstat(fileno(bc->fp), &s) == -1) statted = 0;
+ else statted = 1;
+ closefp = statted;
/* Flush the buffer if we can */
if (buf->flush)
@@ -1432,7 +1454,7 @@ stdio_buffer_shutdown (buf)
# ifndef NO_SOCKET_TO_FD
{
/* shutdown() sockets */
- if (S_ISSOCK (s.st_mode))
+ if (statted && S_ISSOCK (s.st_mode))
shutdown (fileno (bc->fp), 0);
}
# endif /* NO_SOCKET_TO_FD */
@@ -1440,7 +1462,7 @@ stdio_buffer_shutdown (buf)
/* Can't be set with SHUTDOWN_SERVER defined */
else if (pclose (bc->fp) == EOF)
{
- error (1, errno, "closing connection to %s",
+ error (0, errno, "closing connection to %s",
current_parsed_root->hostname);
closefp = 0;
}
@@ -1460,7 +1482,7 @@ stdio_buffer_shutdown (buf)
# endif
# ifndef NO_SOCKET_TO_FD
/* shutdown() sockets */
- if (S_ISSOCK (s.st_mode))
+ if (statted && S_ISSOCK (s.st_mode))
shutdown (fileno (bc->fp), 1);
# else
{
@@ -1473,19 +1495,19 @@ stdio_buffer_shutdown (buf)
buf->output = NULL;
}
- if (closefp && fclose (bc->fp) == EOF)
+ if (statted && closefp && fclose (bc->fp) == EOF)
{
- if (0
-# ifdef SERVER_SUPPORT
- || server_active
-# endif /* SERVER_SUPPORT */
- )
+ if (server_active)
{
/* Syslog this? */
}
# ifdef CLIENT_SUPPORT
+ /* We are already closing the connection.
+ * On error, print a warning and try to
+ * continue to avoid infinte loops.
+ */
else
- error (1, errno,
+ error (0, errno,
"closing down connection to %s",
current_parsed_root->hostname);
# endif /* CLIENT_SUPPORT */
@@ -1499,8 +1521,13 @@ stdio_buffer_shutdown (buf)
do
w = waitpid (bc->child_pid, (int *) 0, 0);
while (w == -1 && errno == EINTR);
+
+ /* We are already closing the connection.
+ * On error, print a warning and try to
+ * continue to avoid infinte loops.
+ */
if (w == -1)
- error (1, errno, "waiting for process %d", bc->child_pid);
+ error (0, errno, "waiting for process %d", bc->child_pid);
}
return 0;
}
@@ -1833,7 +1860,7 @@ packetizing_buffer_output (closure, data, have, wrote)
struct packetizing_buffer *pb = (struct packetizing_buffer *) closure;
char inbuf[BUFFER_DATA_SIZE + 2];
char stack_outbuf[BUFFER_DATA_SIZE + PACKET_SLOP + 4];
- struct buffer_data *outdata;
+ struct buffer_data *outdata = NULL;
char *outbuf;
int size, status, translated;
@@ -1888,6 +1915,11 @@ packetizing_buffer_output (closure, data, have, wrote)
buf_output (pb->buf, outbuf, translated + 2);
else
{
+ /* if ((have + PACKET_SLOP + 4) > BUFFER_DATA_SIZE), then
+ outdata may be NULL. */
+ if (outdata == NULL)
+ abort ();
+
outdata->size = translated + 2;
buf_append_data (pb->buf, outdata, outdata);
}
diff --git a/contrib/cvs/src/buffer.h b/contrib/cvs/src/buffer.h
index 11d9aeb..3459058 100644
--- a/contrib/cvs/src/buffer.h
+++ b/contrib/cvs/src/buffer.h
@@ -1,3 +1,17 @@
+/*
+ * Copyright (C) 1996-2005 The Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
/* Declarations concerning the buffer data structure. */
#if defined (SERVER_SUPPORT) || defined (CLIENT_SUPPORT)
diff --git a/contrib/cvs/src/checkin.c b/contrib/cvs/src/checkin.c
index 938b717..06d431f 100644
--- a/contrib/cvs/src/checkin.c
+++ b/contrib/cvs/src/checkin.c
@@ -1,6 +1,11 @@
/*
- * Copyright (c) 1992, Brian Berliner and Jeff Polk
- * Copyright (c) 1989-1992, Brian Berliner
+ * Copyright (C) 1986-2005 The Free Software Foundation, Inc.
+ *
+ * Portions Copyright (C) 1998-2005 Derek Price, Ximbiot <http://ximbiot.com>,
+ * and others.
+ *
+ * Portions Copyright (C) 1992, Brian Berliner and Jeff Polk
+ * Portions Copyright (C) 1989-1992, Brian Berliner
*
* You may distribute under the terms of the GNU General Public License as
* specified in the README file that comes with the CVS source distribution.
@@ -60,7 +65,7 @@ Checkin (type, finfo, rev, tag, options, message)
*/
assert (finfo->rcs != NULL);
- switch (RCS_checkin (finfo->rcs, finfo->file, message, rev,
+ switch (RCS_checkin (finfo->rcs, finfo->file, message, rev, 0,
RCS_FLAGS_KEEPFILE))
{
case 0: /* everything normal */
@@ -74,7 +79,8 @@ Checkin (type, finfo, rev, tag, options, message)
changes is if the file contains RCS keywords. So we if
we are not expanding RCS keywords, we are done. */
- if (strcmp (options, "-V4") == 0) /* upgrade to V5 now */
+ if (options != NULL
+ && strcmp (options, "-V4") == 0) /* upgrade to V5 now */
options[0] = '\0';
/* FIXME: If PreservePermissions is on, RCS_cmp_file is
diff --git a/contrib/cvs/src/checkout.c b/contrib/cvs/src/checkout.c
index ee3bcb2..e4d80ea 100644
--- a/contrib/cvs/src/checkout.c
+++ b/contrib/cvs/src/checkout.c
@@ -1,6 +1,11 @@
/*
- * Copyright (c) 1992, Brian Berliner and Jeff Polk
- * Copyright (c) 1989-1992, Brian Berliner
+ * Copyright (C) 1986-2005 The Free Software Foundation, Inc.
+ *
+ * Portions Copyright (C) 1998-2005 Derek Price, Ximbiot <http://ximbiot.com>,
+ * and others.
+ *
+ * Portions Copyright (C) 1992, Brian Berliner and Jeff Polk
+ * Portions Copyright (C) 1989-1992, Brian Berliner
*
* You may distribute under the terms of the GNU General Public License as
* specified in the README file that comes with the CVS source distribution.
@@ -67,13 +72,13 @@ static const char *const checkout_usage[] =
static const char *const export_usage[] =
{
- "Usage: %s %s [-NRfln] [-r rev] [-D date] [-d dir] [-k kopt] module...\n",
+ "Usage: %s %s [-NRfln] [-r tag] [-D date] [-d dir] [-k kopt] module...\n",
"\t-N\tDon't shorten module paths if -d specified.\n",
"\t-f\tForce a head revision match if tag/date not found.\n",
"\t-l\tLocal directory only, not recursive\n",
"\t-R\tProcess directories recursively (default).\n",
"\t-n\tDo not run module program (if any).\n",
- "\t-r rev\tExport revision or tag.\n",
+ "\t-r tag\tExport tagged revisions.\n",
"\t-D date\tExport revisions as of date.\n",
"\t-d dir\tExport into dir instead of module name.\n",
"\t-k kopt\tUse RCS kopt -k option on checkout.\n",
@@ -170,11 +175,9 @@ checkout (argc, argv)
break;
case 'Q':
case 'q':
-#ifdef SERVER_SUPPORT
/* The CVS 1.5 client sends these options (in addition to
Global_option requests), so we must ignore them. */
if (!server_active)
-#endif
error (1, 0,
"-q or -Q must be specified before \"%s\"",
cvs_cmd_name);
@@ -428,10 +431,8 @@ safe_location (where)
CLIENT_SERVER_STR,
where ? where : "(null)");
-#ifdef CLIENT_SUPPORT
/* Don't compare remote CVSROOTs to our destination directory. */
- if ( current_parsed_root->isremote ) return 1;
-#endif /* CLIENT_SUPPORT */
+ if (current_parsed_root->isremote) return 1;
/* set current - even if where is set we'll need to cd back... */
current = xgetwd ();
@@ -1053,7 +1054,8 @@ internal error: %s doesn't start with %s in checkout_proc",
which = W_REPOS;
if (tag != NULL && !tag_validated)
{
- tag_check_valid (tag, argc - 1, argv + 1, 0, aflag, NULL);
+ tag_check_valid (tag, argc - 1, argv + 1, 0, aflag,
+ repository);
tag_validated = 1;
}
}
diff --git a/contrib/cvs/src/classify.c b/contrib/cvs/src/classify.c
index 7ce8235..8bb471d 100644
--- a/contrib/cvs/src/classify.c
+++ b/contrib/cvs/src/classify.c
@@ -1,6 +1,11 @@
/*
- * Copyright (c) 1992, Brian Berliner and Jeff Polk
- * Copyright (c) 1989-1992, Brian Berliner
+ * Copyright (C) 1986-2005 The Free Software Foundation, Inc.
+ *
+ * Portions Copyright (C) 1998-2005 Derek Price, Ximbiot <http://ximbiot.com>,
+ * and others.
+ *
+ * Portions Copyright (C) 1992, Brian Berliner and Jeff Polk
+ * Portions Copyright (C) 1989-1992, Brian Berliner
*
* You may distribute under the terms of the GNU General Public License as
* specified in the README file that comes with the CVS source distribution.
@@ -279,7 +284,9 @@ Classify_File (finfo, tag, date, options, force_tag_match, aflag, versp,
error (0, 0, "warning: %s was lost", finfo->fullname);
ret = T_CHECKOUT;
}
- else if (strcmp (vers->ts_user, vers->ts_rcs) == 0)
+ else if (!strcmp (vers->ts_user,
+ vers->ts_conflict
+ ? vers->ts_conflict : vers->ts_rcs))
{
/*
@@ -293,6 +300,8 @@ Classify_File (finfo, tag, date, options, force_tag_match, aflag, versp,
if (vers->entdata->options &&
strcmp (vers->entdata->options, vers->options) != 0)
ret = T_CHECKOUT;
+ else if (vers->ts_conflict)
+ ret = T_CONFLICT;
else
{
sticky_ck (finfo, aflag, vers);
@@ -313,6 +322,13 @@ Classify_File (finfo, tag, date, options, force_tag_match, aflag, versp,
else
ret = T_NEEDS_MERGE;
#else
+ /* Files with conflict markers and new timestamps fall through
+ * here, but they need to. T_CONFLICT is an error in
+ * commit_fileproc, whereas T_CONFLICT with conflict markers
+ * is caught but only warned about. Similarly, update_fileproc
+ * currently reregisters a file that was conflicted but lost
+ * its markers.
+ */
ret = T_MODIFIED;
sticky_ck (finfo, aflag, vers);
#endif
diff --git a/contrib/cvs/src/client.c b/contrib/cvs/src/client.c
index 91c61a4..22384ed 100644
--- a/contrib/cvs/src/client.c
+++ b/contrib/cvs/src/client.c
@@ -221,7 +221,8 @@ arg_should_not_be_sent_to_server (arg)
/* Try to decide whether we should send arg to the server by
checking the contents of the corresponding CVSADM directory. */
{
- char *t, *this_root;
+ char *t, *root_string;
+ cvsroot_t *this_root = NULL;
/* Calculate "dirname arg" */
for (t = arg + strlen (arg) - 1; t >= arg; t--)
@@ -251,25 +252,31 @@ arg_should_not_be_sent_to_server (arg)
/* Since we didn't find it in the list, check the CVSADM
files on disk. */
this_root = Name_Root (arg, (char *) NULL);
+ root_string = this_root->original;
*t = c;
}
else
{
/* We're at the beginning of the string. Look at the
CVSADM files in cwd. */
- this_root = (CVSroot_cmdline ? xstrdup(CVSroot_cmdline)
- : Name_Root ((char *) NULL, (char *) NULL));
+ if (CVSroot_cmdline)
+ root_string = CVSroot_cmdline;
+ else
+ {
+ this_root = Name_Root ((char *) NULL, (char *) NULL);
+ root_string = this_root->original;
+ }
}
/* Now check the value for root. */
- if (this_root && current_parsed_root
- && (strcmp (this_root, current_parsed_root->original) != 0))
+ if (root_string && current_parsed_root
+ && (strcmp (root_string, current_parsed_root->original) != 0))
{
/* Don't send this, since the CVSROOTs don't match. */
- free (this_root);
+ if (this_root) free_cvsroot_t (this_root);
return 1;
}
- free (this_root);
+ if (this_root) free_cvsroot_t (this_root);
}
/* OK, let's send it. */
@@ -886,12 +893,6 @@ read_line (resultp)
#if defined(CLIENT_SUPPORT) || defined(SERVER_SUPPORT)
/*
- * Zero if compression isn't supported or requested; non-zero to indicate
- * a compression level to request from gzip.
- */
-int gzip_level;
-
-/*
* Level of compression to use when running gzip on a single file.
*/
int file_gzip_level;
@@ -1113,6 +1114,8 @@ call_in_directory (pathname, func, data)
int reposdirname_absolute;
int newdir = 0;
+ assert (pathname);
+
reposname = NULL;
read_line (&reposname);
assert (reposname != NULL);
@@ -1194,44 +1197,6 @@ call_in_directory (pathname, func, data)
if (CVS_CHDIR (toplevel_wd) < 0)
error (1, errno, "could not chdir to %s", toplevel_wd);
- /* Create the CVS directory at the top level if needed. The
- isdir seems like an unneeded system call, but it *does*
- need to be called both if the CVS_CHDIR below succeeds
- (e.g. "cvs co .") or if it fails (e.g. basicb-1a in
- testsuite). We only need to do this for the "." case,
- since the server takes care of forcing this directory to be
- created in all other cases. If we don't create CVSADM
- here, the call to Entries_Open below will fail. FIXME:
- perhaps this means that we should change our algorithm
- below that calls Create_Admin instead of having this code
- here? */
- if (/* I think the reposdirname_absolute case has to do with
- things like "cvs update /foo/bar". In any event, the
- code below which tries to put toplevel_repos into
- CVS/Repository is almost surely unsuited to
- the reposdirname_absolute case. */
- !reposdirname_absolute
- && (strcmp (dir_name, ".") == 0)
- && ! isdir (CVSADM))
- {
- char *repo;
- char *r;
-
- newdir = 1;
-
- repo = xmalloc (strlen (toplevel_repos)
- + 10);
- strcpy (repo, toplevel_repos);
- r = repo + strlen (repo);
- if (r[-1] != '.' || r[-2] != '/')
- strcpy (r, "/.");
-
- Create_Admin (".", ".", repo, (char *) NULL,
- (char *) NULL, 0, 1, 1);
-
- free (repo);
- }
-
if (CVS_CHDIR (dir_name) < 0)
{
char *dir;
@@ -1492,7 +1457,44 @@ handle_copy_file (args, len)
{
call_in_directory (args, copy_a_file, (char *)NULL);
}
-
+
+
+
+/* Attempt to read a file size from a string. Accepts base 8 (0N), base 16
+ * (0xN), or base 10. Exits on error.
+ *
+ * RETURNS
+ * The file size, in a size_t.
+ *
+ * FATAL ERRORS
+ * 1. As strtoul().
+ * 2. If the number read exceeds SIZE_MAX.
+ */
+static size_t
+strto_file_size (const char *s)
+{
+ unsigned long tmp;
+ char *endptr;
+
+ /* Read it. */
+ errno = 0;
+ tmp = strtoul (s, &endptr, 0);
+
+ /* Check for errors. */
+ if (errno || endptr == s)
+ error (1, errno, "Server sent invalid file size `%s'", s);
+ if (*endptr != '\0')
+ error (1, 0,
+ "Server sent trailing characters in file size `%s'",
+ endptr);
+ if (tmp > SIZE_MAX)
+ error (1, 0, "Server sent file size exceeding client max.");
+
+ /* Return it. */
+ return (size_t)tmp;
+}
+
+
static void read_counted_file PROTO ((char *, char *));
@@ -1525,9 +1527,7 @@ read_counted_file (filename, fullname)
if (size_string[0] == 'z')
error (1, 0, "\
protocol error: compressed files not supported for that operation");
- /* FIXME: should be doing more error checking, probably. Like using
- strtoul and making sure we used up the whole line. */
- size = atoi (size_string);
+ size = strto_file_size (size_string);
free (size_string);
/* A more sophisticated implementation would use only a limited amount
@@ -1809,11 +1809,12 @@ update_entries (data_arg, ent_list, short_pathname, filename)
{
char *size_string;
char *mode_string;
- int size;
+ size_t size;
char *buf;
char *temp_filename;
int use_gzip;
int patch_failed;
+ char *s;
read_line (&mode_string);
@@ -1821,13 +1822,14 @@ update_entries (data_arg, ent_list, short_pathname, filename)
if (size_string[0] == 'z')
{
use_gzip = 1;
- size = atoi (size_string+1);
+ s = size_string + 1;
}
else
{
use_gzip = 0;
- size = atoi (size_string);
+ s = size_string;
}
+ size = strto_file_size (s);
free (size_string);
/* Note that checking this separately from writing the file is
@@ -1928,7 +1930,7 @@ update_entries (data_arg, ent_list, short_pathname, filename)
#ifdef USE_VMS_FILENAMES
/* A VMS rename of "blah.dat" to "foo" to implies a
destination of "foo.dat" which is unfortinate for CVS */
- sprintf (temp_filename, "%s_new_", filename);
+ sprintf (temp_filename, "%s_new_", filename);
#else
#ifdef _POSIX_NO_TRUNC
sprintf (temp_filename, ".new.%.9s", filename);
@@ -1981,6 +1983,8 @@ update_entries (data_arg, ent_list, short_pathname, filename)
entirely possible that future files will not have
the same problem. */
error (0, errno, "cannot write %s", short_pathname);
+ free (temp_filename);
+ free (buf);
goto discard_file_and_return;
}
@@ -2837,7 +2841,10 @@ send_a_repository (dir, repository, update_dir_in)
const char *repository;
const char *update_dir_in;
{
- char *update_dir = xstrdup (update_dir_in);
+ char *update_dir;
+
+ assert (update_dir_in);
+ update_dir = xstrdup (update_dir_in);
if (toplevel_repos == NULL && repository != NULL)
{
@@ -3097,7 +3104,7 @@ handle_mbinary (args, len)
/* Get the size. */
read_line (&size_string);
- size = atoi (size_string);
+ size = strto_file_size (size_string);
free (size_string);
/* OK, now get all the data. The algorithm here is that we read
@@ -3246,7 +3253,7 @@ handle_mt (args, len)
else if (importmergecmd.seen)
{
if (strcmp (tag, "conflicts") == 0)
- importmergecmd.conflicts = atoi (text);
+ importmergecmd.conflicts = text ? atoi (text) : -1;
else if (strcmp (tag, "mergetag1") == 0)
importmergecmd.mergetag1 = xstrdup (text);
else if (strcmp (tag, "mergetag2") == 0)
@@ -3914,6 +3921,7 @@ auth_server (root, lto_server, lfrom_server, verify_only, do_gssapi, hostinfo)
/* Paranoia. */
memset (password, 0, strlen (password));
+ free (password);
# else /* ! AUTH_CLIENT_SUPPORT */
error (1, 0, "INTERNAL ERROR: This client does not support pserver authentication");
# endif /* AUTH_CLIENT_SUPPORT */
@@ -4028,7 +4036,7 @@ connect_to_forked_server (to_server, from_server)
fprintf (stderr, " -> Forking server: %s %s\n", command[0], command[1]);
}
- child_pid = piped_child (command, &tofd, &fromfd);
+ child_pid = piped_child (command, &tofd, &fromfd, 0);
if (child_pid < 0)
error (1, 0, "could not fork server process");
@@ -4232,7 +4240,8 @@ connect_to_gserver (root, sock, hostinfo)
if (need > sizeof buf)
{
- int got;
+ ssize_t got;
+ size_t total;
/* This usually means that the server sent us an error
message. Read it byte by byte and print it out.
@@ -4241,13 +4250,19 @@ connect_to_gserver (root, sock, hostinfo)
want to do this to work with older servers. */
buf[0] = cbuf[0];
buf[1] = cbuf[1];
- got = recv (sock, buf + 2, sizeof buf - 2, 0);
- if (got < 0)
- error (1, 0, "recv() from server %s: %s",
- root->hostname, SOCK_STRERROR (SOCK_ERRNO));
- buf[got + 2] = '\0';
- if (buf[got + 1] == '\n')
- buf[got + 1] = '\0';
+ total = 2;
+ while (got = recv (sock, buf + total, sizeof buf - total, 0))
+ {
+ if (got < 0)
+ error (1, 0, "recv() from server %s: %s",
+ root->hostname, SOCK_STRERROR (SOCK_ERRNO));
+ total += got;
+ if (strrchr (buf + total - got, '\n'))
+ break;
+ }
+ buf[total] = '\0';
+ if (buf[total - 1] == '\n')
+ buf[total - 1] = '\0';
error (1, 0, "error from server %s: %s", root->hostname,
buf);
}
@@ -4328,6 +4343,7 @@ start_server ()
#endif /* HAVE_GSSAPI */
case ext_method:
+ case extssh_method:
#ifdef NO_EXT_METHOD
error (0, 0, ":ext: method not supported by this port of CVS");
error (1, 0, "try :server: instead");
@@ -4712,27 +4728,7 @@ start_rsh_server (root, to_server, from_server)
char *rsh_argv[10];
if (!cvs_rsh)
- /* People sometimes suggest or assume that this should default
- to "remsh" on systems like HPUX in which that is the
- system-supplied name for the rsh program. However, that
- causes various problems (keep in mind that systems such as
- HPUX might have non-system-supplied versions of "rsh", like
- a Kerberized one, which one might want to use). If we
- based the name on what is found in the PATH of the person
- who runs configure, that would make it harder to
- consistently produce the same result in the face of
- different people producing binary distributions. If we
- based it on "remsh" always being the default for HPUX
- (e.g. based on uname), that might be slightly better but
- would require us to keep track of what the defaults are for
- each system type, and probably would cope poorly if the
- existence of remsh or rsh varies from OS version to OS
- version. Therefore, it seems best to have the default
- remain "rsh", and tell HPUX users to specify remsh, for
- example in CVS_RSH or other such mechanisms to be devised,
- if that is what they want (the manual already tells them
- that). */
- cvs_rsh = "rsh";
+ cvs_rsh = RSH_DFLT;
if (!cvs_server)
cvs_server = "cvs";
@@ -4837,7 +4833,7 @@ start_rsh_server (root, to_server, from_server)
fprintf (stderr, "%s ", argv[i]);
putc ('\n', stderr);
}
- child_pid = piped_child (argv, &tofd, &fromfd);
+ child_pid = piped_child (argv, &tofd, &fromfd, 1);
if (child_pid < 0)
error (1, errno, "cannot start server via rsh");
@@ -4856,10 +4852,10 @@ start_rsh_server (root, to_server, from_server)
/* Send an argument STRING. */
void
send_arg (string)
- char *string;
+ const char *string;
{
char buf[1];
- char *p = string;
+ const char *p = string;
send_to_server ("Argument ", 0);
@@ -5151,7 +5147,10 @@ warning: ignoring -k options due to server limitations");
}
else if (vers->ts_rcs == NULL
|| args->force
- || strcmp (vers->ts_user, vers->ts_rcs) != 0)
+ || strcmp (vers->ts_conflict
+ && supported_request ("Empty-conflicts")
+ ? vers->ts_conflict : vers->ts_rcs, vers->ts_user)
+ || (vers->ts_conflict && !strcmp (cvs_cmd_name, "diff")))
{
if (args->no_contents
&& supported_request ("Is-modified"))
@@ -5357,36 +5356,15 @@ send_dirleave_proc (callerdat, dir, err, update_dir, entries)
}
/*
- * Send each option in a string to the server, one by one.
- * This assumes that the options are separated by spaces, for example
- * STRING might be "--foo -C5 -y".
+ * Send each option in an array to the server, one by one.
+ * argv might be "--foo=bar", "-C", "5", "-y".
*/
-
void
-send_option_string (string)
- char *string;
+send_options (int argc, char *const *argv)
{
- char *copy;
- char *p;
-
- copy = xstrdup (string);
- p = copy;
- while (1)
- {
- char *s;
- char l;
-
- for (s = p; *s != ' ' && *s != '\0'; s++)
- ;
- l = *s;
- *s = '\0';
- if (s != p)
- send_arg (p);
- if (l == '\0')
- break;
- p = s + 1;
- }
- free (copy);
+ int i;
+ for (i = 0; i < argc; i++)
+ send_arg (argv[i]);
}
diff --git a/contrib/cvs/src/client.h b/contrib/cvs/src/client.h
index cdc880e..3a99f4f 100644
--- a/contrib/cvs/src/client.h
+++ b/contrib/cvs/src/client.h
@@ -1,3 +1,17 @@
+/*
+ * Copyright (C) 1994-2005 The Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
/* Interface between the client and the rest of CVS. */
/* Stuff shared with the server. */
@@ -119,11 +133,10 @@ send_files PROTO((int argc, char **argv, int local, int aflag,
/* Send an argument to the remote server. */
void
-send_arg PROTO((char *string));
+send_arg PROTO((const char *string));
/* Send a string of single-char options to the remote server, one by one. */
-void
-send_option_string PROTO((char *string));
+void send_options PROTO ((int argc, char * const *argv));
extern void send_a_repository PROTO ((const char *, const char *,
const char *));
diff --git a/contrib/cvs/src/commit.c b/contrib/cvs/src/commit.c
index 86c8106..7d168c3 100644
--- a/contrib/cvs/src/commit.c
+++ b/contrib/cvs/src/commit.c
@@ -1,6 +1,11 @@
/*
- * Copyright (c) 1992, Brian Berliner and Jeff Polk
- * Copyright (c) 1989-1992, Brian Berliner
+ * Copyright (C) 1986-2005 The Free Software Foundation, Inc.
+ *
+ * Portions Copyright (C) 1998-2005 Derek Price, Ximbiot <http://ximbiot.com>,
+ * and others.
+ *
+ * Portions Copyright (C) 1992, Brian Berliner and Jeff Polk
+ * Portions Copyright (C) 1989-1992, Brian Berliner
*
* You may distribute under the terms of the GNU General Public License as
* specified in the README file that comes with the CVS source distribution.
@@ -383,12 +388,8 @@ commit (argc, argv)
/* FIXME: Shouldn't this check be much more closely related to the
readonly user stuff (CVSROOT/readers, &c). That is, why should
root be able to "cvs init", "cvs import", &c, but not "cvs ci"? */
- if (geteuid () == (uid_t) 0
-# ifdef CLIENT_SUPPORT
- /* Who we are on the client side doesn't affect logging. */
- && !current_parsed_root->isremote
-# endif
- )
+ /* Who we are on the client side doesn't affect logging. */
+ if (geteuid () == (uid_t) 0 && !current_parsed_root->isremote)
{
struct passwd *pw;
@@ -411,6 +412,7 @@ commit (argc, argv)
/* Silently ignore -n for compatibility with old
* clients.
*/
+ if (!server_active) error(0, 0, "the `-n' option is obsolete");
break;
#endif /* SERVER_SUPPORT */
case 'm':
@@ -641,7 +643,8 @@ commit (argc, argv)
fp = cvs_temp_file (&fname);
if (fp == NULL)
- error (1, 0, "cannot create temporary file %s", fname);
+ error (1, 0, "cannot create temporary file %s",
+ fname ? fname : "(null)");
if (fwrite (saved_message, 1, strlen (saved_message), fp)
!= strlen (saved_message))
error (1, errno, "cannot write temporary file %s", fname);
@@ -712,10 +715,8 @@ commit (argc, argv)
Lock_Cleanup ();
dellist (&mulist);
-#ifdef SERVER_SUPPORT
if (server_active)
return err;
-#endif
/* see if we need to sleep before returning to avoid time-stamp races */
if (last_register_time)
@@ -870,11 +871,11 @@ check_fileproc (callerdat, finfo)
case T_CHECKOUT:
case T_PATCH:
case T_NEEDS_MERGE:
- case T_CONFLICT:
case T_REMOVE_ENTRY:
error (0, 0, "Up-to-date check failed for `%s'", finfo->fullname);
freevers_ts (&vers);
return 1;
+ case T_CONFLICT:
case T_MODIFIED:
case T_ADDED:
case T_REMOVED:
@@ -912,40 +913,30 @@ check_fileproc (callerdat, finfo)
return 1;
}
}
- if (status == T_MODIFIED && !force_ci && vers->ts_conflict)
+ if (status == T_CONFLICT && !force_ci)
{
- /*
- * We found a "conflict" marker.
- *
- * If the timestamp on the file is the same as the
- * timestamp stored in the Entries file, we block the commit.
- */
- if ( file_has_conflict ( finfo, vers->ts_conflict ) )
- {
- error (0, 0,
- "file `%s' had a conflict and has not been modified",
- finfo->fullname);
- freevers_ts (&vers);
- return 1;
- }
-
- if (file_has_markers (finfo))
- {
- /* Make this a warning, not an error, because we have
- no way of knowing whether the "conflict indicators"
- are really from a conflict or whether they are part
- of the document itself (cvs.texinfo and sanity.sh in
- CVS itself, for example, tend to want to have strings
- like ">>>>>>>" at the start of a line). Making people
- kludge this the way they need to kludge keyword
- expansion seems undesirable. And it is worse than
- keyword expansion, because there is no -ko
- analogue. */
- error (0, 0,
- "\
+ error (0, 0,
+ "file `%s' had a conflict and has not been modified",
+ finfo->fullname);
+ freevers_ts (&vers);
+ return 1;
+ }
+ if (status == T_MODIFIED && !force_ci && file_has_markers (finfo))
+ {
+ /* Make this a warning, not an error, because we have
+ no way of knowing whether the "conflict indicators"
+ are really from a conflict or whether they are part
+ of the document itself (cvs.texinfo and sanity.sh in
+ CVS itself, for example, tend to want to have strings
+ like ">>>>>>>" at the start of a line). Making people
+ kludge this the way they need to kludge keyword
+ expansion seems undesirable. And it is worse than
+ keyword expansion, because there is no -ko
+ analogue. */
+ error (0, 0,
+ "\
warning: file `%s' seems to still contain conflict indicators",
- finfo->fullname);
- }
+ finfo->fullname);
}
if (status == T_REMOVED)
@@ -1284,11 +1275,7 @@ commit_fileproc (callerdat, finfo)
if (!got_message)
{
got_message = 1;
- if (
-#ifdef SERVER_SUPPORT
- !server_active &&
-#endif
- use_editor)
+ if (!server_active && use_editor)
do_editor (finfo->update_dir, &saved_message,
finfo->repository, ulist);
do_verify (&saved_message, finfo->repository);
@@ -1474,6 +1461,8 @@ commit_filesdoneproc (callerdat, err, repository, update_dir, entries)
Node *p;
List *ulist;
+ assert (repository);
+
p = findnode (mulist, update_dir);
if (p == NULL)
return err;
@@ -1564,11 +1553,7 @@ commit_direntproc (callerdat, dir, repos, update_dir, entries)
/* get commit message */
real_repos = Name_Repository (dir, update_dir);
got_message = 1;
- if (
-#ifdef SERVER_SUPPORT
- !server_active &&
-#endif
- use_editor)
+ if (!server_active && use_editor)
do_editor (update_dir, &saved_message, real_repos, ulist);
do_verify (&saved_message, real_repos);
free (real_repos);
@@ -1752,18 +1737,22 @@ remove_file (finfo, tag, message)
if (corev != NULL)
free (corev);
- retcode = RCS_checkin (finfo->rcs, finfo->file, message, rev,
+ retcode = RCS_checkin (finfo->rcs, finfo->file, message, rev, 0,
RCS_FLAGS_DEAD | RCS_FLAGS_QUIET);
if (retcode != 0)
{
if (!quiet)
error (0, retcode == -1 ? errno : 0,
"failed to commit dead revision for `%s'", finfo->fullname);
+ if (prev_rev != NULL)
+ free (prev_rev);
return 1;
}
/* At this point, the file has been committed as removed. We should
probably tell the history file about it */
- history_write ('R', NULL, finfo->rcs->head, finfo->file, finfo->repository);
+ corev = rev ? RCS_getbranch (finfo->rcs, rev, 1) : RCS_head (finfo->rcs);
+ history_write ('R', NULL, corev, finfo->file, finfo->repository);
+ free (corev);
if (rev != NULL)
free (rev);
@@ -2085,7 +2074,8 @@ checkaddfile (file, repository, tag, options, rcsnode)
/* and lock it */
if (lock_RCS (file, rcs, rev, repository))
{
- error (0, 0, "cannot lock `%s'.", rcs->path);
+ error (0, 0, "cannot lock revision %s in `%s'.",
+ rev ? rev : tag ? tag : "HEAD", rcs->path);
if (rev != NULL)
free (rev);
goto out;
@@ -2123,13 +2113,14 @@ checkaddfile (file, repository, tag, options, rcsnode)
/* commit a dead revision. */
(void) sprintf (tmp, "file %s was initially added on branch %s.",
file, tag);
- retcode = RCS_checkin (rcs, NULL, tmp, NULL,
+ retcode = RCS_checkin (rcs, NULL, tmp, NULL, 0,
RCS_FLAGS_DEAD | RCS_FLAGS_QUIET);
free (tmp);
if (retcode != 0)
{
error (retcode == -1 ? 1 : 0, retcode == -1 ? errno : 0,
"could not create initial dead revision %s", rcs->path);
+ free (fname);
goto out;
}
@@ -2142,7 +2133,7 @@ checkaddfile (file, repository, tag, options, rcsnode)
rcs = RCS_parse (file, repository);
if (rcs == NULL)
{
- error (0, 0, "could not read %s", rcs->path);
+ error (0, 0, "could not read %s in %s", file, repository);
goto out;
}
*rcsnode = rcs;
@@ -2150,7 +2141,8 @@ checkaddfile (file, repository, tag, options, rcsnode)
/* and lock it once again. */
if (lock_RCS (file, rcs, NULL, repository))
{
- error (0, 0, "cannot lock `%s'.", rcs->path);
+ error (0, 0, "cannot lock initial revision in `%s'.",
+ rcs->path);
goto out;
}
}
@@ -2163,12 +2155,25 @@ checkaddfile (file, repository, tag, options, rcsnode)
char *head;
char *magicrev;
int retcode;
+ time_t headtime = -1;
+ char *revnum, *tmp;
+ FILE *fp;
+ time_t t = -1;
+ struct tm *ct;
fixbranch (rcs, sbranch);
head = RCS_getversion (rcs, NULL, NULL, 0, (int *) NULL);
+ if (!head)
+ error (1, 0, "No head revision in archive file `%s'.",
+ rcs->path);
magicrev = RCS_magicrev (rcs, head);
+ /* If this is not a new branch, then we will want a dead
+ version created before this one. */
+ if (!newfile)
+ headtime = RCS_getrevtime (rcs, head, 0, 0);
+
retcode = RCS_settag (rcs, tag, magicrev);
RCS_rewrite (rcs, NULL, NULL);
@@ -2181,13 +2186,76 @@ checkaddfile (file, repository, tag, options, rcsnode)
"could not stub branch %s for %s", tag, rcs->path);
goto out;
}
+ /* We need to add a dead version here to avoid -rtag -Dtime
+ checkout problems between when the head version was
+ created and now. */
+ if (!newfile && headtime != -1)
+ {
+ /* move the new file out of the way. */
+ fname = xmalloc (strlen (file) + sizeof (CVSADM)
+ + sizeof (CVSPREFIX) + 10);
+ (void) sprintf (fname, "%s/%s%s", CVSADM, CVSPREFIX, file);
+ rename_file (file, fname);
+
+ /* Create empty FILE. Can't use copy_file with a DEVNULL
+ argument -- copy_file now ignores device files. */
+ fp = fopen (file, "w");
+ if (fp == NULL)
+ error (1, errno, "cannot open %s for writing", file);
+ if (fclose (fp) < 0)
+ error (0, errno, "cannot close %s", file);
+
+ /* As we will be hacking the delta date, put the time
+ this was added into the log message. */
+ t = time(NULL);
+ ct = gmtime(&t);
+ tmp = xmalloc (strlen (file) + strlen (tag) + 80);
+
+ (void) sprintf (tmp,
+ "file %s was added on branch %s on %d-%02d-%02d %02d:%02d:%02d +0000",
+ file, tag,
+ ct->tm_year + (ct->tm_year < 100 ? 0 : 1900),
+ ct->tm_mon + 1, ct->tm_mday,
+ ct->tm_hour, ct->tm_min, ct->tm_sec);
+
+ /* commit a dead revision. */
+ revnum = RCS_whatbranch (rcs, tag);
+ retcode = RCS_checkin (rcs, NULL, tmp, revnum, headtime,
+ RCS_FLAGS_DEAD |
+ RCS_FLAGS_QUIET |
+ RCS_FLAGS_USETIME);
+ free (revnum);
+ free (tmp);
+
+ if (retcode != 0)
+ {
+ error (retcode == -1 ? 1 : 0, retcode == -1 ? errno : 0,
+ "could not created dead stub %s for %s", tag,
+ rcs->path);
+ goto out;
+ }
+
+ /* put the new file back where it was */
+ rename_file (fname, file);
+ free (fname);
+
+ /* double-check that the file was written correctly */
+ freercsnode (&rcs);
+ rcs = RCS_parse (file, repository);
+ if (rcs == NULL)
+ {
+ error (0, 0, "could not read %s", rcs->path);
+ goto out;
+ }
+ *rcsnode = rcs;
+ }
}
else
{
/* lock the branch. (stubbed branches need not be locked.) */
if (lock_RCS (file, rcs, NULL, repository))
{
- error (0, 0, "cannot lock `%s'.", rcs->path);
+ error (0, 0, "cannot lock head revision in `%s'.", rcs->path);
goto out;
}
}
diff --git a/contrib/cvs/src/create_adm.c b/contrib/cvs/src/create_adm.c
index bccb4a2..ccf744f 100644
--- a/contrib/cvs/src/create_adm.c
+++ b/contrib/cvs/src/create_adm.c
@@ -1,6 +1,11 @@
/*
- * Copyright (c) 1992, Brian Berliner and Jeff Polk
- * Copyright (c) 1989-1992, Brian Berliner
+ * Copyright (C) 1986-2005 The Free Software Foundation, Inc.
+ *
+ * Portions Copyright (C) 1998-2005 Derek Price, Ximbiot <http://ximbiot.com>,
+ * and others.
+ *
+ * Portions Copyright (C) 1992, Brian Berliner and Jeff Polk
+ * Portions Copyright (C) 1989-1992, Brian Berliner
*
* You may distribute under the terms of the GNU General Public License as
* specified in the README file that comes with the CVS source distribution.
diff --git a/contrib/cvs/src/cvs.h b/contrib/cvs/src/cvs.h
index 9f601ce..15fd227 100644
--- a/contrib/cvs/src/cvs.h
+++ b/contrib/cvs/src/cvs.h
@@ -1,6 +1,11 @@
/*
- * Copyright (c) 1992, Brian Berliner and Jeff Polk
- * Copyright (c) 1989-1992, Brian Berliner
+ * Copyright (C) 1986-2005 The Free Software Foundation, Inc.
+ *
+ * Portions Copyright (C) 1998-2005 Derek Price, Ximbiot <http://ximbiot.com>,
+ * and others.
+ *
+ * Portions Copyright (C) 1992, Brian Berliner and Jeff Polk
+ * Portions 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.
@@ -207,6 +212,8 @@ extern int errno;
#define CVSATTIC "Attic"
#define CVSLCK "#cvs.lock"
+#define CVSHISTORYLCK "#cvs.history.lock"
+#define CVSVALTAGSLCK "#cvs.val-tags.lock"
#define CVSRFL "#cvs.rfl"
#define CVSWFL "#cvs.wfl"
#define CVSRFLPAT "#cvs.rfl.*" /* wildcard expr to match read locks */
@@ -270,7 +277,10 @@ extern int errno;
#define EDITOR3_ENV "EDITOR" /* which editor to use */
#define CVSROOT_ENV "CVSROOT" /* source directory root */
-#define CVSROOT_DFLT NULL /* No dflt; must set for checkout */
+/* Define CVSROOT_DFLT to a fallback value for CVSROOT.
+ *
+#undef CVSROOT_DFL
+ */
#define IGNORE_ENV "CVSIGNORE" /* More files to ignore */
#define WRAPPER_ENV "CVSWRAPPERS" /* name of the wrapper file */
@@ -419,15 +429,18 @@ int RCS_merge PROTO((RCSNode *, const char *, const char *, const char *,
#define RCS_FLAGS_QUIET 4
#define RCS_FLAGS_MODTIME 8
#define RCS_FLAGS_KEEPFILE 16
+#define RCS_FLAGS_USETIME 32
-extern int RCS_exec_rcsdiff PROTO ((RCSNode *rcsfile,
- const char *opts, const char *options,
+extern int RCS_exec_rcsdiff PROTO ((RCSNode *rcsfile, int diff_argc,
+ char *const *diff_argv,
+ const char *options,
const char *rev1, const char *rev1_cache,
const char *rev2, const char *label1,
const char *label2, const char *workfile));
extern int diff_exec PROTO ((const char *file1, const char *file2,
const char *label1, const char *label2,
- const char *options, const char *out));
+ int diff_argc, char *const *diff_argv,
+ const char *out));
#include "error.h"
@@ -451,15 +464,6 @@ char *Name_Repository PROTO((const char *dir, const char *update_dir));
const char *Short_Repository PROTO((const char *repository));
void Sanitize_Repository_Name PROTO((char *repository));
-char *Name_Root PROTO((char *dir, char *update_dir));
-void free_cvsroot_t PROTO((cvsroot_t *root_in));
-cvsroot_t *parse_cvsroot PROTO((const char *root));
-cvsroot_t *local_cvsroot PROTO((const char *dir));
-void Create_Root PROTO((const char *dir, const char *rootdir));
-void root_allow_add PROTO ((char *));
-void root_allow_free PROTO ((void));
-int root_allow_ok PROTO ((char *));
-
char *previous_rev PROTO ((RCSNode *rcs, const char *rev));
char *gca PROTO ((const char *rev1, const char *rev2));
extern void check_numeric PROTO ((const char *, int, char **));
@@ -568,6 +572,14 @@ void lock_tree_for_write PROTO ((int argc, char **argv, int local, int which,
/* See lock.c for description. */
extern void lock_dir_for_write PROTO ((char *));
+/* Get a write lock for the history file. */
+int history_lock PROTO ((const char *));
+void clear_history_lock PROTO ((void));
+
+/* Get a write lock for the val-tags file. */
+int val_tags_lock PROTO ((const char *));
+void clear_val_tags_lock PROTO ((void));
+
/* LockDir setting from CVSROOT/config. */
extern char *lock_dir;
@@ -667,8 +679,6 @@ int SIG_inCrSect PROTO((void));
void read_cvsrc PROTO((int *argc, char ***argv, const char *cmdname));
char *make_message_rcslegal PROTO((const char *message));
-extern int file_has_conflict PROTO ((const struct file_info *,
- const char *ts_conflict));
extern int file_has_markers PROTO ((const struct file_info *));
extern void get_file PROTO ((const char *, const char *, const char *,
char **, size_t *, size_t *));
@@ -686,6 +696,8 @@ void sleep_past PROTO ((time_t desttime));
#define RUN_SIGIGNORE 0x0010 /* ignore interrupts for command */
#define RUN_TTY (char *)0 /* for the benefit of lint */
+void run_add_arg_p PROTO ((int *, size_t *, char ***, const char *s));
+void run_arg_free_p PROTO ((int, char **));
void run_arg PROTO((const char *s));
void run_print PROTO((FILE * fp));
void run_setup PROTO ((const char *prog));
@@ -694,7 +706,7 @@ int run_exec PROTO((const char *stin, const char *stout, const char *sterr,
/* other similar-minded stuff from run.c. */
FILE *run_popen PROTO((const char *, const char *));
-int piped_child PROTO((const char **, int *, int *));
+int piped_child PROTO((const char **, int *, int *, int));
void close_on_exec PROTO((int));
pid_t waitpid PROTO((pid_t, int *, int));
diff --git a/contrib/cvs/src/cvsrc.c b/contrib/cvs/src/cvsrc.c
index 9aed694..60de909 100644
--- a/contrib/cvs/src/cvsrc.c
+++ b/contrib/cvs/src/cvsrc.c
@@ -1,5 +1,10 @@
/*
- * Copyright (c) 1993 david d zuhn
+ * Copyright (C) 1986-2005 The Free Software Foundation, Inc.
+ *
+ * Portions Copyright (C) 1998-2005 Derek Price, Ximbiot <http://ximbiot.com>,
+ * and others.
+ *
+ * Portions Copyright (C) 1993 david d zuhn
*
* Written by david d `zoo' zuhn while at Cygnus Support
*
@@ -120,9 +125,9 @@ read_cvsrc (argc, argv, cmdname)
if (found)
{
/* skip over command in the options line */
- for (optstart = strtok (line + command_len, "\t \n");
+ for (optstart = strtok (line + command_len, "\t \n\r");
optstart;
- optstart = strtok (NULL, "\t \n"))
+ optstart = strtok (NULL, "\t \n\r"))
{
new_argv [new_argc++] = xstrdup (optstart);
diff --git a/contrib/cvs/src/diff.c b/contrib/cvs/src/diff.c
index 2e7aea2..a5ca2d0 100644
--- a/contrib/cvs/src/diff.c
+++ b/contrib/cvs/src/diff.c
@@ -1,6 +1,11 @@
/*
- * Copyright (c) 1992, Brian Berliner and Jeff Polk
- * Copyright (c) 1989-1992, Brian Berliner
+ * Copyright (C) 1986-2005 The Free Software Foundation, Inc.
+ *
+ * Portions Copyright (C) 1998-2005 Derek Price, Ximbiot <http://ximbiot.com>,
+ * and others.
+ *
+ * Portions Copyright (C) 1992, Brian Berliner and Jeff Polk
+ * Portions Copyright (C) 1989-1992, Brian Berliner
*
* You may distribute under the terms of the GNU General Public License as
* specified in the README file that comes with the CVS source distribution.
@@ -60,8 +65,9 @@ static int have_rev1_label, have_rev2_label;
static char *user_file_rev;
static char *options;
-static char *opts;
-static size_t opts_allocated = 1;
+static char **diff_argv;
+static int diff_argc;
+static size_t diff_arg_allocated;
static int diff_errors;
static int empty_files = 0;
@@ -206,6 +212,54 @@ static struct option const longopts[] =
{0, 0, 0, 0}
};
+
+
+/* Add one of OPT or LONGOPT, and ARGUMENT, when present, to global DIFF_ARGV.
+ *
+ * INPUTS
+ * opt A character option representation.
+ * longopt A long option name.
+ * argument Optional option argument.
+ *
+ * GLOBALS
+ * diff_argc The number of arguments in DIFF_ARGV.
+ * diff_argv Array of argument strings.
+ * diff_arg_allocated Allocated length of DIFF_ARGV.
+ *
+ * NOTES
+ * Behavior when both OPT & LONGOPT are provided is undefined.
+ *
+ * RETURNS
+ * Nothing.
+ */
+static void
+add_diff_args (char opt, const char *longopt, const char *argument)
+{
+ char *tmp;
+
+ /* Add opt or longopt to diff_arv. */
+ assert (opt || (longopt && *longopt));
+ assert (!(opt && (longopt && *longopt)));
+ if (opt)
+ {
+ tmp = xmalloc (3);
+ sprintf (tmp, "-%c", opt);
+ }
+ else
+ {
+ tmp = xmalloc (3 + strlen (longopt));
+ sprintf (tmp, "--%s", longopt);
+ }
+ run_add_arg_p (&diff_argc, &diff_arg_allocated, &diff_argv, tmp);
+ free (tmp);
+
+ /* When present, add ARGUMENT to DIFF_ARGV. */
+ if (argument)
+ run_add_arg_p (&diff_argc, &diff_arg_allocated, &diff_argv, argument);
+}
+
+
+
/* CVS 1.9 and similar versions seemed to have pretty weird handling
of -y and -T. In the cases where it called rcsdiff,
they would have the meanings mentioned below. In the cases where it
@@ -242,7 +296,6 @@ diff (argc, argv)
int argc;
char **argv;
{
- char tmp[50];
int c, err = 0;
int local = 0;
int which;
@@ -262,12 +315,11 @@ diff (argc, argv)
/* Clean out our global variables (multiroot can call us multiple
times and the server can too, if the client sends several
diff commands). */
- if (opts == NULL)
+ if (diff_argc)
{
- opts_allocated = 1;
- opts = xmalloc (opts_allocated);
+ run_arg_free_p (diff_argc, diff_argv);
+ diff_argc = 0;
}
- opts[0] = '\0';
diff_rev1 = NULL;
diff_rev2 = NULL;
diff_date1 = NULL;
@@ -288,7 +340,7 @@ diff (argc, argv)
switch (c)
{
case 'y':
- xrealloc_and_strcat (&opts, &opts_allocated, " --side-by-side");
+ add_diff_args (0, "side-by-side", NULL);
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':
@@ -296,8 +348,7 @@ diff (argc, argv)
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);
- xrealloc_and_strcat (&opts, &opts_allocated, tmp);
+ add_diff_args (c, NULL, NULL);
break;
case 'L':
if (have_rev1_label++)
@@ -306,33 +357,15 @@ diff (argc, argv)
error (0, 0, "extra -L arguments ignored");
break;
}
-
- xrealloc_and_strcat (&opts, &opts_allocated, " -L");
- xrealloc_and_strcat (&opts, &opts_allocated, optarg);
- break;
+ /* Fall through. */
case 'C': case 'F': case 'I': case 'U': case 'W':
- (void) sprintf (tmp, " -%c", (char) c);
- xrealloc_and_strcat (&opts, &opts_allocated, tmp);
- xrealloc_and_strcat (&opts, &opts_allocated, optarg);
+ add_diff_args (c, NULL, optarg);
break;
- case 131:
- /* --ifdef. */
- 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 129: case 130: case 131: 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 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))
- {
- xrealloc_and_strcat (&opts, &opts_allocated, "=");
- xrealloc_and_strcat (&opts, &opts_allocated, optarg);
- }
+ add_diff_args (0, longopts[option_index].name,
+ longopts[option_index].has_arg ? optarg : NULL);
break;
case 'R':
local = 0;
@@ -390,7 +423,7 @@ diff (argc, argv)
send_arg("-l");
if (empty_files)
send_arg("-N");
- send_option_string (opts);
+ send_options (diff_argc, diff_argv);
if (options[0] != '\0')
send_arg (options);
if (diff_rev1)
@@ -700,8 +733,8 @@ RCS file: ", 0);
if (empty_file == DIFF_ADDED)
{
if (use_rev2 == NULL)
- status = diff_exec (DEVNULL, finfo->file, label1, label2, opts,
- RUN_TTY);
+ status = diff_exec (DEVNULL, finfo->file, label1, label2,
+ diff_argc, diff_argv, RUN_TTY);
else
{
int retcode;
@@ -717,7 +750,8 @@ RCS file: ", 0);
if( retcode != 0 )
goto out;
- status = diff_exec (DEVNULL, tmp, label1, label2, opts, RUN_TTY);
+ status = diff_exec (DEVNULL, tmp, label1, label2,
+ diff_argc, diff_argv, RUN_TTY);
}
}
else
@@ -733,16 +767,16 @@ RCS file: ", 0);
if (retcode != 0)
goto out;
- status = diff_exec (tmp, DEVNULL, label1, label2, opts, RUN_TTY);
+ status = diff_exec (tmp, DEVNULL, label1, label2,
+ diff_argc, diff_argv, RUN_TTY);
}
}
else
{
- status = RCS_exec_rcsdiff(vers->srcfile, opts,
- *options ? options : vers->options,
- use_rev1, rev1_cache, use_rev2,
- label1, label2,
- finfo->file);
+ status = RCS_exec_rcsdiff (vers->srcfile, diff_argc, diff_argv,
+ *options ? options : vers->options,
+ use_rev1, rev1_cache, use_rev2,
+ label1, label2, finfo->file);
}
diff --git a/contrib/cvs/src/edit.c b/contrib/cvs/src/edit.c
index fe4c21f..4b1804a 100644
--- a/contrib/cvs/src/edit.c
+++ b/contrib/cvs/src/edit.c
@@ -32,7 +32,10 @@ onoff_fileproc (callerdat, finfo)
void *callerdat;
struct file_info *finfo;
{
+ char *watched = fileattr_get0 (finfo->file, "_watched");
fileattr_set (finfo->file, "_watched", turning_on ? "" : NULL);
+ if (watched != NULL)
+ free (watched);
return 0;
}
@@ -50,7 +53,12 @@ onoff_filesdoneproc (callerdat, err, repository, update_dir, entries)
List *entries;
{
if (setting_default)
+ {
+ char *watched = fileattr_get0 (NULL, "_watched");
fileattr_set (NULL, "_watched", turning_on ? "" : NULL);
+ if (watched != NULL)
+ free (watched);
+ }
return err;
}
@@ -357,12 +365,12 @@ edit_fileproc (callerdat, finfo)
static const char *const edit_usage[] =
{
- "Usage: %s %s [-lR] [files...]\n",
- "-l: Local directory only, not recursive\n",
- "-R: Process directories recursively\n",
- "-a: Specify what actions for temporary watch, one of\n",
- " edit,unedit,commit,all,none\n",
- "(Specify the --help global option for a list of other help options)\n",
+ "Usage: %s %s [-lR] [-a <action>]... [<file>]...\n",
+ "-l\tLocal directory only, not recursive.\n",
+ "-R\tProcess directories recursively (default).\n",
+ "-a\tSpecify action to register for temporary watch, one of:\n",
+ " \t`edit', `unedit', `commit', `all', or `none' (defaults to `all').\n",
+ "(Specify the --help global option for a list of other help options.)\n",
NULL
};
@@ -572,10 +580,10 @@ unedit_fileproc (callerdat, finfo)
static const char *const unedit_usage[] =
{
- "Usage: %s %s [-lR] [files...]\n",
- "-l: Local directory only, not recursive\n",
- "-R: Process directories recursively\n",
- "(Specify the --help global option for a list of other help options)\n",
+ "Usage: %s %s [-lR] [<file>]...\n",
+ "-l\tLocal directory only, not recursive.\n",
+ "-R\tProcess directories recursively (default).\n",
+ "(Specify the --help global option for a list of other help options.)\n",
NULL
};
@@ -1041,10 +1049,10 @@ notify_check (repository, update_dir)
static const char *const editors_usage[] =
{
- "Usage: %s %s [-lR] [files...]\n",
- "\t-l\tProcess this directory only (not recursive).\n",
- "\t-R\tProcess directories recursively.\n",
- "(Specify the --help global option for a list of other help options)\n",
+ "Usage: %s %s [-lR] [<file>]...\n",
+ "-l\tProcess this directory only (not recursive).\n",
+ "-R\tProcess directories recursively (default).\n",
+ "(Specify the --help global option for a list of other help options.)\n",
NULL
};
diff --git a/contrib/cvs/src/entries.c b/contrib/cvs/src/entries.c
index fe927d3..c346fb6 100644
--- a/contrib/cvs/src/entries.c
+++ b/contrib/cvs/src/entries.c
@@ -1,6 +1,11 @@
/*
- * Copyright (c) 1992, Brian Berliner and Jeff Polk
- * Copyright (c) 1989-1992, Brian Berliner
+ * Copyright (C) 1986-2005 The Free Software Foundation, Inc.
+ *
+ * Portions Copyright (C) 1998-2005 Derek Price, Ximbiot <http://ximbiot.com>,
+ * and others.
+ *
+ * Portions Copyright (C) 1992, Brian Berliner and Jeff Polk
+ * Portions Copyright (C) 1989-1992, Brian Berliner
*
* You may distribute under the terms of the GNU General Public License as
* specified in the README file that comes with the CVS source distribution.
@@ -537,6 +542,7 @@ Entries_Open (aflag, update_dir)
break;
default:
/* Ignore unrecognized commands. */
+ Entnode_Destroy (ent);
break;
}
}
diff --git a/contrib/cvs/src/expand_path.c b/contrib/cvs/src/expand_path.c
index 5aa1063..1c960f3 100644
--- a/contrib/cvs/src/expand_path.c
+++ b/contrib/cvs/src/expand_path.c
@@ -1,5 +1,17 @@
/* expand_path.c -- expand environmental variables in passed in string
*
+ * Copyright (C) 1995-2005 The Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
* The main routine is expand_path(), it is the routine that handles
* the '~' character in four forms:
* ~name
@@ -97,16 +109,14 @@ expand_path (name, file, line)
const char *file;
int line;
{
- const char *s;
- char *d;
+ size_t s, d, p;
+ char *e;
char *mybuf = NULL;
size_t mybuf_size = 0;
char *buf = NULL;
size_t buf_size = 0;
- size_t doff;
-
char *result;
/* Sorry this routine is so ugly; it is a head-on collision
@@ -117,82 +127,74 @@ expand_path (name, file, line)
thusly. */
/* First copy from NAME to MYBUF, expanding $<foo> as we go. */
- s = name;
- d = mybuf;
- doff = d - mybuf;
- expand_string (&mybuf, &mybuf_size, doff + 1);
- d = mybuf + doff;
- while ((*d++ = *s))
+ s = d = 0;
+ while (name[s] != '\0')
{
- if (*s++ == '$')
+ if (name[s] == '$')
{
- char *p = d;
- char *e;
- int flag = (*s == '{');
-
- doff = d - mybuf;
- expand_string (&mybuf, &mybuf_size, doff + 1);
- d = mybuf + doff;
- for (; (*d++ = *s); s++)
+ p = d;
+ if (name[++s] == '{')
+ {
+ while (name[++s] != '}' && name[s] != '\0')
+ {
+ expand_string (&mybuf, &mybuf_size, p + 1);
+ mybuf[p++] = name[s];
+ }
+ if (name[s] != '\0') ++s;
+ }
+ else
{
- if (flag
- ? *s =='}'
- : isalnum ((unsigned char) *s) == 0 && *s != '_')
- break;
- doff = d - mybuf;
- expand_string (&mybuf, &mybuf_size, doff + 1);
- d = mybuf + doff;
+ while (isalnum ((unsigned char) name[s]) || name[s] == '_')
+ {
+ expand_string (&mybuf, &mybuf_size, p + 1);
+ mybuf[p++] = name[s++];
+ }
}
- *--d = '\0';
- e = expand_variable (&p[flag], file, line);
+ expand_string (&mybuf, &mybuf_size, p + 1);
+ mybuf[p] = '\0';
+ e = expand_variable (mybuf + d, file, line);
if (e)
{
- doff = d - mybuf;
- expand_string (&mybuf, &mybuf_size, doff + 1);
- d = mybuf + doff;
- for (d = &p[-1]; (*d++ = *e++);)
- {
- doff = d - mybuf;
- expand_string (&mybuf, &mybuf_size, doff + 1);
- d = mybuf + doff;
- }
- --d;
- if (flag && *s)
- s++;
+ p = strlen(e);
+ expand_string (&mybuf, &mybuf_size, d + p);
+ memcpy(mybuf + d, e, p);
+ d += p;
}
else
/* expand_variable has already printed an error message. */
goto error_exit;
}
- doff = d - mybuf;
- expand_string (&mybuf, &mybuf_size, doff + 1);
- d = mybuf + doff;
+ else
+ {
+ expand_string (&mybuf, &mybuf_size, d + 1);
+ mybuf[d++] = name[s++];
+ }
}
- doff = d - mybuf;
- expand_string (&mybuf, &mybuf_size, doff + 1);
- d = mybuf + doff;
- *d = '\0';
+ expand_string (&mybuf, &mybuf_size, d + 1);
+ mybuf[d++] = '\0';
/* Then copy from MYBUF to BUF, expanding ~. */
- s = mybuf;
- d = buf;
+ s = d = 0;
/* If you don't want ~username ~/ to be expanded simply remove
* This entire if statement including the else portion
*/
- if (*s++ == '~')
+ if (mybuf[s] == '~')
{
- char *t;
- char *p, *pstart;
- pstart = p = xstrdup (s);
- if (*pstart=='/' || *pstart==0)
- t = get_homedir ();
+ p = d;
+ while (mybuf[++s] != '/' && mybuf[s] != '\0')
+ {
+ expand_string (&buf, &buf_size, p + 1);
+ buf[p++] = name[s];
+ }
+ expand_string (&buf, &buf_size, p + 1);
+ buf[p] = '\0';
+
+ if (p == d)
+ e = get_homedir ();
else
{
#ifdef GETPWNAM_MISSING
- for (; *p!='/' && *p; p++)
- ;
- *p = 0;
if (line != 0)
error (0, 0,
"%s:%d:tilde expansion not supported on this system",
@@ -200,57 +202,34 @@ expand_path (name, file, line)
else
error (0, 0, "%s:tilde expansion not supported on this system",
file);
- return NULL;
+ goto error_exit;
#else
struct passwd *ps;
- for (; *p!='/' && *p; p++)
- ;
- *p = 0;
- ps = getpwnam (pstart);
- if (ps == 0)
+ ps = getpwnam (buf + d);
+ if (ps == NULL)
{
if (line != 0)
error (0, 0, "%s:%d: no such user %s",
- file, line, pstart);
+ file, line, buf + d);
else
- error (0, 0, "%s: no such user %s", file, pstart);
- return NULL;
+ error (0, 0, "%s: no such user %s", file, buf + d);
+ goto error_exit;
}
- t = ps->pw_dir;
+ e = ps->pw_dir;
#endif
}
- if (t == NULL)
+ if (e == NULL)
error (1, 0, "cannot find home directory");
- doff = d - buf;
- expand_string (&buf, &buf_size, doff + 1);
- d = buf + doff;
- while ((*d++ = *t++))
- {
- doff = d - buf;
- expand_string (&buf, &buf_size, doff + 1);
- d = buf + doff;
- }
- --d;
- s+=p-pstart;
- free (pstart);
- }
- else
- --s;
- /* Kill up to here */
- doff = d - buf;
- expand_string (&buf, &buf_size, doff + 1);
- d = buf + doff;
- while ((*d++ = *s++))
- {
- doff = d - buf;
- expand_string (&buf, &buf_size, doff + 1);
- d = buf + doff;
+ p = strlen(e);
+ expand_string (&buf, &buf_size, d + p);
+ memcpy(buf + d, e, p);
+ d += p;
}
- doff = d - buf;
- expand_string (&buf, &buf_size, doff + 1);
- d = buf + doff;
- *d = '\0';
+ /* Kill up to here */
+ p = strlen(mybuf + s) + 1;
+ expand_string (&buf, &buf_size, d + p);
+ memcpy(buf + d, mybuf + s, p);
/* OK, buf contains the value we want to return. Clean up and return
it. */
diff --git a/contrib/cvs/src/fileattr.c b/contrib/cvs/src/fileattr.c
index 9b10851..ca6bd0e 100644
--- a/contrib/cvs/src/fileattr.c
+++ b/contrib/cvs/src/fileattr.c
@@ -139,6 +139,7 @@ fileattr_read ()
"file attribute database corruption: tab missing in %s",
fname);
++p;
+ if (fileattr_default_attrs) free (fileattr_default_attrs);
fileattr_default_attrs = xstrdup (p);
}
else
@@ -589,6 +590,7 @@ fileattr_write ()
{
error (0, errno, "cannot make directory %s", repname);
(void) umask (omask);
+ free (fname);
free (repname);
return;
}
@@ -600,6 +602,7 @@ fileattr_write ()
{
error (0, errno, "cannot write %s", fname);
(void) umask (omask);
+ free (fname);
return;
}
}
diff --git a/contrib/cvs/src/filesubr.c b/contrib/cvs/src/filesubr.c
index 8b5990a..14da6292 100644
--- a/contrib/cvs/src/filesubr.c
+++ b/contrib/cvs/src/filesubr.c
@@ -20,6 +20,8 @@
#include <assert.h>
#include "cvs.h"
+#include "xsize.h"
+
static int deep_remove_dir PROTO((const char *path));
/*
@@ -105,7 +107,7 @@ copy_file (from, to)
error (1, errno, "cannot close %s", to);
}
- /* now, set the times for the copied file to match those of the original */
+ /* preserve last access & modification times */
memset ((char *) &t, 0, sizeof (t));
t.actime = sb.st_atime;
t.modtime = sb.st_mtime;
@@ -433,14 +435,10 @@ unlink_file_dir (f)
{
struct stat sb;
- if (trace
-#ifdef SERVER_SUPPORT
- /* This is called by the server parent process in contexts where
- it is not OK to send output (e.g. after we sent "ok" to the
- client). */
- && !server_active
-#endif
- )
+ /* This is called by the server parent process in contexts where
+ it is not OK to send output (e.g. after we sent "ok" to the
+ client). */
+ if (trace && !server_active)
(void) fprintf (stderr, "-> unlink_file_dir(%s)\n", f);
if (noexec)
@@ -704,7 +702,8 @@ cvs_temp_name ()
fp = cvs_temp_file (&fn);
if (fp == NULL)
- error (1, errno, "Failed to create temporary file");
+ error (1, errno, "Failed to create temporary file %s",
+ fn ? fn : "(null)");
if (fclose (fp) == EOF)
error (0, errno, "Failed to close temporary file %s", fn);
return fn;
@@ -741,7 +740,8 @@ cvs_temp_name ()
* NFS locking thing, but until I hear of more problems, I'm not going to
* bother.
*/
-FILE *cvs_temp_file (filename)
+FILE *
+cvs_temp_file (filename)
char **filename;
{
char *fn;
@@ -780,7 +780,11 @@ FILE *cvs_temp_file (filename)
errno = save_errno;
}
- if (fp == NULL) free (fn);
+ if (fp == NULL)
+ {
+ free (fn);
+ fn = NULL;
+ }
/* mkstemp is defined to open mode 0600 using glibc 2.0.7+ */
/* FIXME - configure can probably tell us which version of glibc we are
* linking to and not chmod for 2.0.7+
@@ -795,7 +799,11 @@ FILE *cvs_temp_file (filename)
fn = tempnam (Tmpdir, "cvs");
if (fn == NULL) fp = NULL;
- else if ((fp = CVS_FOPEN (fn, "w+")) == NULL) free (fn);
+ else if ((fp = CVS_FOPEN (fn, "w+")) == NULL)
+ {
+ free (fn);
+ fn = NULL;
+ }
else chmod (fn, 0600);
/* tempnam returns a pointer to a newly malloc'd string, so there's
@@ -845,6 +853,11 @@ FILE *cvs_temp_file (filename)
#endif
*filename = fn;
+ if (fn == NULL && fp != NULL)
+ {
+ fclose (fp);
+ fp = NULL;
+ }
return fp;
}
@@ -867,31 +880,48 @@ FILE *cvs_temp_file (filename)
* This function exits with a fatal error if it fails to read the link for
* any reason.
*/
+#define MAXSIZE (SIZE_MAX < SSIZE_MAX ? SIZE_MAX : SSIZE_MAX)
+
char *
xreadlink (link)
const char *link;
{
char *file = NULL;
- int buflen = 128;
- int link_name_len;
+ size_t buflen = 128;
- /* Get the name of the file to which `from' is linked.
- FIXME: what portability issues arise here? Are readlink &
- ENAMETOOLONG defined on all systems? -twp */
- do
+ /* Get the name of the file to which `from' is linked. */
+ while (1)
{
+ ssize_t r;
+ size_t link_name_len;
+
file = xrealloc (file, buflen);
- link_name_len = readlink (link, file, buflen - 1);
- buflen *= 2;
- }
- while (link_name_len < 0 && errno == ENAMETOOLONG);
+ r = readlink (link, file, buflen);
+ link_name_len = r;
- if (link_name_len < 0)
- error (1, errno, "cannot readlink %s", link);
+ if (r < 0
+#ifdef ERANGE
+ /* AIX 4 and HP-UX report ERANGE if the buffer is too small. */
+ && errno != ERANGE
+#endif
+ )
+ error (1, errno, "cannot readlink %s", link);
- file[link_name_len] = '\0';
+ /* If there is space for the NUL byte, set it and return. */
+ if (r >= 0 && link_name_len < buflen)
+ {
+ file[link_name_len] = '\0';
+ return file;
+ }
- return file;
+ if (buflen <= MAXSIZE / 2)
+ buflen *= 2;
+ else if (buflen < MAXSIZE)
+ buflen = MAXSIZE;
+ else
+ /* Our buffer cannot grow any bigger. */
+ error (1, ENAMETOOLONG, "cannot readlink %s", link);
+ }
}
#endif /* HAVE_READLINK */
@@ -944,7 +974,8 @@ last_component (path)
const char *path;
{
const char *last = strrchr (path, '/');
-
+
+ assert (path);
if (last && (last != path))
return last + 1;
else
@@ -984,11 +1015,7 @@ get_homedir ()
if (home != NULL)
return home;
- if (
-#ifdef SERVER_SUPPORT
- !server_active &&
-#endif
- (env = getenv ("HOME")) != NULL)
+ if (!server_active && (env = getenv ("HOME")) != NULL)
home = env;
else if ((pw = (struct passwd *) getpwuid (getuid ()))
&& pw->pw_dir)
@@ -1029,6 +1056,7 @@ expand_wild (argc, argv, pargc, pargv)
char ***pargv;
{
int i;
+ assert (argv || !argc);
if (size_overflow_p (xtimes (argc, sizeof (char *)))) {
*pargc = 0;
*pargv = NULL;
diff --git a/contrib/cvs/src/find_names.c b/contrib/cvs/src/find_names.c
index cff0de1..5bfd895 100644
--- a/contrib/cvs/src/find_names.c
+++ b/contrib/cvs/src/find_names.c
@@ -1,6 +1,11 @@
/*
- * Copyright (c) 1992, Brian Berliner and Jeff Polk
- * Copyright (c) 1989-1992, Brian Berliner
+ * Copyright (C) 1986-2005 The Free Software Foundation, Inc.
+ *
+ * Portions Copyright (C) 1998-2005 Derek Price, Ximbiot <http://ximbiot.com>,
+ * and others.
+ *
+ * Portions Copyright (C) 1992, Brian Berliner and Jeff Polk
+ * Portions Copyright (C) 1989-1992, Brian Berliner
*
* You may distribute under the terms of the GNU General Public License as
* specified in the README file that comes with the CVS source distribution.
diff --git a/contrib/cvs/src/hardlink.c b/contrib/cvs/src/hardlink.c
index 5cd9c37..ed05033 100644
--- a/contrib/cvs/src/hardlink.c
+++ b/contrib/cvs/src/hardlink.c
@@ -11,7 +11,9 @@
/* Collect and manage hardlink info associated with a particular file. */
#include "cvs.h"
-#include "hardlink.h"
+
+#ifdef PRESERVE_PERMISSIONS_SUPPORT
+# include "hardlink.h"
/* The structure currently used to manage hardlink info is a list.
Therefore, most of the functions which manipulate hardlink data
@@ -302,4 +304,4 @@ find_checkedout_proc (node, data)
return 0;
}
-
+#endif /* PRESERVE_PERMISSIONS_SUPPORT */
diff --git a/contrib/cvs/src/hardlink.h b/contrib/cvs/src/hardlink.h
index f9df344..b227968 100644
--- a/contrib/cvs/src/hardlink.h
+++ b/contrib/cvs/src/hardlink.h
@@ -17,6 +17,7 @@
when files are being checked out or updated. It is used only when
hardlinked files are being checked out. */
+#ifdef PRESERVE_PERMISSIONS_SUPPORT
struct hardlink_info
{
Ctype status; /* as returned from Classify_File() */
@@ -31,3 +32,4 @@ void update_hardlink_info PROTO ((const char *));
List *list_linked_files_on_disk PROTO ((char *));
int compare_linkage_lists PROTO ((List *, List *));
int find_checkedout_proc PROTO ((Node *, void *));
+#endif /* PRESERVE_PERMISSIONS_SUPPORT */
diff --git a/contrib/cvs/src/hash.c b/contrib/cvs/src/hash.c
index 4a97784..d9bc12c 100644
--- a/contrib/cvs/src/hash.c
+++ b/contrib/cvs/src/hash.c
@@ -1,5 +1,10 @@
/*
- * Copyright (c) 1992, Brian Berliner and Jeff Polk
+ * Copyright (C) 1986-2005 The Free Software Foundation, Inc.
+ *
+ * Portions Copyright (C) 1998-2005 Derek Price, Ximbiot <http://ximbiot.com>,
+ * and others.
+ *
+ * Portions Copyright (C) 1992, Brian Berliner and Jeff Polk
*
* You may distribute under the terms of the GNU General Public License as
* specified in the README file that comes with the CVS source distribution.
diff --git a/contrib/cvs/src/hash.h b/contrib/cvs/src/hash.h
index edfee46..a31fc5d 100644
--- a/contrib/cvs/src/hash.h
+++ b/contrib/cvs/src/hash.h
@@ -1,5 +1,10 @@
/*
- * Copyright (c) 1992, Brian Berliner and Jeff Polk
+ * Copyright (C) 1986-2005 The Free Software Foundation, Inc.
+ *
+ * Portions Copyright (C) 1998-2005 Derek Price, Ximbiot <http://ximbiot.com>,
+ * and others.
+ *
+ * Portions Copyright (C) 1992, Brian Berliner and Jeff Polk
*
* You may distribute under the terms of the GNU General Public License as
* specified in the README file that comes with the CVS source distribution.
diff --git a/contrib/cvs/src/history.c b/contrib/cvs/src/history.c
index 154c2de..78fa0fe 100644
--- a/contrib/cvs/src/history.c
+++ b/contrib/cvs/src/history.c
@@ -1,9 +1,18 @@
/*
+ * Copyright (C) 1994-2005 The Free Software Foundation, Inc.
*
- * You may distribute under the terms of the GNU General Public License
- * as specified in the README file that comes with the CVS 1.0 kit.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
*
- * **************** History of Users and Module ****************
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/* **************** History of Users and Module ****************
*
* LOGGING: Append record to "${CVSROOT}/CVSROOTADM/CVSROOTADM_HISTORY".
*
@@ -236,7 +245,7 @@ static short tz_local;
static time_t tz_seconds_east_of_GMT;
static char *tz_name = "+0000";
-char *logHistory = ALL_HISTORY_REC_TYPES;
+char *logHistory;
/* -r, -t, or -b options, malloc'd. These are "" if the option in
question is not specified or is overridden by another option. The
@@ -257,24 +266,24 @@ static struct hrec *last_backto;
we do. */
static char *rec_types;
-static int hrec_count;
-static int hrec_max;
+static size_t hrec_count;
+static size_t hrec_max;
static char **user_list; /* Ptr to array of ptrs to user names */
-static int user_max; /* Number of elements allocated */
-static int user_count; /* Number of elements used */
+static size_t user_max; /* Number of elements allocated */
+static size_t user_count; /* Number of elements used */
static struct file_list_str
{
char *l_file;
char *l_module;
} *file_list; /* Ptr to array file name structs */
-static int file_max; /* Number of elements allocated */
-static int file_count; /* Number of elements used */
+static size_t file_max; /* Number of elements allocated */
+static size_t file_count; /* Number of elements used */
static char **mod_list; /* Ptr to array of ptrs to module names */
-static int mod_max; /* Number of elements allocated */
-static int mod_count; /* Number of elements used */
+static size_t mod_max; /* Number of elements allocated */
+static size_t mod_count; /* Number of elements used */
static char *histfile; /* Ptr to the history file name */
@@ -442,7 +451,7 @@ history (argc, argv)
backto = xstrdup (optarg);
break;
case 'f': /* For specified file */
- save_file ("", optarg, (char *) NULL);
+ save_file (NULL, optarg, NULL);
break;
case 'm': /* Full module report */
if (!module_report++) report_count++;
@@ -451,7 +460,7 @@ history (argc, argv)
save_module (optarg);
break;
case 'p': /* For specified directory */
- save_file (optarg, "", (char *) NULL);
+ save_file (optarg, NULL, NULL);
break;
case 'r': /* Since specified Tag/Rev */
if (since_date || *since_tag || *backto)
@@ -534,7 +543,7 @@ history (argc, argv)
argc -= optind;
argv += optind;
for (i = 0; i < argc; i++)
- save_file ("", argv[i], (char *) NULL);
+ save_file (NULL, argv[i], NULL);
/* ================ Now analyze the arguments a bit */
@@ -724,9 +733,10 @@ history_write (type, update_dir, revs, name, repository)
* readonlyfs.
*/
return;
- if ( strchr(logHistory, type) == NULL )
+ if (strchr (logHistory, type) == NULL)
return;
- fname = xmalloc (strlen (current_parsed_root->directory) + sizeof (CVSROOTADM)
+ fname = xmalloc (strlen (current_parsed_root->directory)
+ + sizeof (CVSROOTADM)
+ sizeof (CVSROOTADM_HISTORY) + 3);
(void) sprintf (fname, "%s/%s/%s", current_parsed_root->directory,
CVSROOTADM, CVSROOTADM_HISTORY);
@@ -752,6 +762,11 @@ history_write (type, update_dir, revs, name, repository)
CLIENT_SERVER_STR, fname);
if (noexec)
goto out;
+
+ if (!history_lock (current_parsed_root->directory))
+ /* history_lock() will already have printed an error on failure. */
+ goto out;
+
fd = CVS_OPEN (fname, O_WRONLY | O_APPEND | OPEN_BINARY, 0666);
if (fd < 0)
{
@@ -789,7 +804,7 @@ history_write (type, update_dir, revs, name, repository)
if (save_cwd (&cwd))
error_exit ();
- if ( CVS_CHDIR (pwdir) < 0 || (homedir = xgetwd ()) == NULL)
+ if (CVS_CHDIR (pwdir) < 0 || (homedir = xgetwd ()) == NULL)
homedir = pwdir;
if (restore_cwd (&cwd, NULL))
@@ -896,6 +911,7 @@ history_write (type, update_dir, revs, name, repository)
error (1, errno, "cannot close history file: %s", fname);
free (workdir);
out:
+ clear_history_lock ();
free (fname);
}
@@ -910,7 +926,8 @@ save_user (name)
if (user_count == user_max)
{
user_max = xsum (user_max, USER_INCREMENT);
- if (size_overflow_p (xtimes (user_max, sizeof (char *))))
+ if (user_count == user_max
+ || size_overflow_p (xtimes (user_max, sizeof (char *))))
{
error (0, 0, "save_user: too many users");
return;
@@ -944,7 +961,8 @@ save_file (dir, name, module)
if (file_count == file_max)
{
file_max = xsum (file_max, FILE_INCREMENT);
- if (size_overflow_p (xtimes (file_max, sizeof (*fl))))
+ if (file_count == file_max
+ || size_overflow_p (xtimes (file_max, sizeof (*fl))))
{
error (0, 0, "save_file: too many files");
return;
@@ -952,7 +970,9 @@ save_file (dir, name, module)
file_list = xrealloc (file_list, xtimes (file_max, sizeof (*fl)));
}
fl = &file_list[file_count++];
- fl->l_file = cp = xmalloc (strlen (dir) + strlen (name) + 2);
+ fl->l_file = cp = xmalloc (dir ? strlen (dir) : 0
+ + name ? strlen (name) : 0
+ + 2);
fl->l_module = module;
if (dir && *dir)
@@ -989,7 +1009,8 @@ save_module (module)
if (mod_count == mod_max)
{
mod_max = xsum (mod_max, MODULE_INCREMENT);
- if (size_overflow_p (xtimes (mod_max, sizeof (char *))))
+ if (mod_count == mod_max
+ || size_overflow_p (xtimes (mod_max, sizeof (char *))))
{
error (0, 0, "save_module: too many modules");
return;
@@ -1142,9 +1163,13 @@ read_hrecs (fname)
{
struct hrec *old_head = hrec_head;
- hrec_max += HREC_INCREMENT;
- hrec_head = xrealloc ((char *) hrec_head,
- hrec_max * sizeof (struct hrec));
+ hrec_max = xsum (hrec_max, HREC_INCREMENT);
+ if (hrec_count == hrec_max
+ || size_overflow_p (xtimes (hrec_max, sizeof (struct hrec))))
+ error (1, 0, "Too many history records in history file.");
+
+ hrec_head = xrealloc (hrec_head,
+ xtimes (hrec_max, sizeof (struct hrec)));
if (last_since_tag)
last_since_tag = hrec_head + (last_since_tag - old_head);
if (last_backto)
@@ -1393,6 +1418,8 @@ select_hrec (hr)
if (within (cp, cp2))
{
hr->mod = fl->l_module;
+ if (cmpfile != NULL)
+ free (cmpfile);
break;
}
if (cmpfile != NULL)
diff --git a/contrib/cvs/src/history.h b/contrib/cvs/src/history.h
index fd65951..dadc421 100644
--- a/contrib/cvs/src/history.h
+++ b/contrib/cvs/src/history.h
@@ -1,6 +1,8 @@
/*
- * Copyright (c) 2003, Derek Price, Ximbiot <http://ximbiot.com>,
- * and the Free Software Foundation
+ * Copyright (C) 2003-2005 The Free Software Foundation, Inc.
+ *
+ * Portions Copyright (C) 2003-2005 Derek Price, Ximbiot <http://ximbiot.com>,
+ * and others.
*
* You may distribute under the terms of the GNU General Public License
* as specified in the README file that comes with the CVS source
diff --git a/contrib/cvs/src/ignore.c b/contrib/cvs/src/ignore.c
index e9bcf79..65b2260 100644
--- a/contrib/cvs/src/ignore.c
+++ b/contrib/cvs/src/ignore.c
@@ -65,13 +65,11 @@ ign_setup ()
ign_add (tmp, 0);
free (tmp);
-#ifdef CLIENT_SUPPORT
/* The client handles another way, by (after it does its own ignore file
processing, and only if !ign_inhibit_server), letting the server
know about the files and letting it decide whether to ignore
them based on CVSROOOTADM_IGNORE. */
if (!current_parsed_root->isremote)
-#endif
{
char *file = xmalloc (strlen (current_parsed_root->directory) + sizeof (CVSROOTADM)
+ sizeof (CVSROOTADM_IGNORE) + 10);
@@ -237,10 +235,25 @@ ign_add (ign, hold)
free (ign_list[i]);
ign_hold = -1;
}
- s_ign_list = (char **) xmalloc (ign_count * sizeof (char *));
- for (i = 0; i < ign_count; i++)
- s_ign_list[i] = ign_list[i];
- s_ign_count = ign_count;
+ if (s_ign_list)
+ {
+ /* Don't save the ignore list twice - if there are two
+ * bangs in a local .cvsignore file then we don't want to
+ * save the new list the first bang created.
+ *
+ * We still need to free the "new" ignore list.
+ */
+ for (i = 0; i < ign_count; i++)
+ free (ign_list[i]);
+ }
+ else
+ {
+ /* Save the ignore list for later. */
+ s_ign_list = xmalloc (ign_count * sizeof (char *));
+ for (i = 0; i < ign_count; i++)
+ s_ign_list[i] = ign_list[i];
+ s_ign_count = ign_count;
+ }
ign_count = 1;
/* Always ignore the "CVS" directory. */
ign_list[0] = xstrdup ("CVS");
@@ -331,7 +344,7 @@ ignore_directory (name)
i = dir_ign_current;
while (i--)
{
- if (strncmp (name, dir_ign_list[i], strlen (dir_ign_list[i])) == 0)
+ if (strncmp (name, dir_ign_list[i], strlen (dir_ign_list[i])+1) == 0)
return 1;
}
diff --git a/contrib/cvs/src/import.c b/contrib/cvs/src/import.c
index 1eb02cf..ea65677 100644
--- a/contrib/cvs/src/import.c
+++ b/contrib/cvs/src/import.c
@@ -1,6 +1,11 @@
/*
- * Copyright (c) 1992, Brian Berliner and Jeff Polk
- * Copyright (c) 1989-1992, Brian Berliner
+ * Copyright (C) 1986-2005 The Free Software Foundation, Inc.
+ *
+ * Portions Copyright (C) 1998-2005 Derek Price, Ximbiot <http://ximbiot.com>,
+ * and others.
+ *
+ * Portions Copyright (C) 1992, Brian Berliner and Jeff Polk
+ * Portions Copyright (C) 1989-1992, Brian Berliner
*
* You may distribute under the terms of the GNU General Public License as
* specified in the README file that comes with the CVS source distribution.
@@ -84,17 +89,14 @@ import (argc, argv)
{
case 'Q':
case 'q':
-#ifdef SERVER_SUPPORT
/* The CVS 1.5 client sends these options (in addition to
Global_option requests), so we must ignore them. */
if (!server_active)
-#endif
error (1, 0,
"-q or -Q must be specified before \"%s\"",
cvs_cmd_name);
break;
case 'd':
-#ifdef SERVER_SUPPORT
if (server_active)
{
/* CVS 1.10 and older clients will send this, but it
@@ -104,7 +106,6 @@ import (argc, argv)
"warning: not setting the time of import from the file");
error (0, 0, "due to client limitations");
}
-#endif
use_file_modtime = 1;
break;
case 'b':
@@ -117,6 +118,7 @@ import (argc, argv)
#else
use_editor = 0;
#endif
+ if (message) free (message);
message = xstrdup(optarg);
break;
case 'I':
@@ -143,7 +145,6 @@ import (argc, argv)
if (argc < 3)
usage (import_usage);
-#ifdef SERVER_SUPPORT
/* This is for handling the Checkin-time request. It might seem a
bit odd to enable the use_file_modtime code even in the case
where Checkin-time was not sent for a particular file. The
@@ -155,7 +156,6 @@ import (argc, argv)
if (server_active)
use_file_modtime = 1;
-#endif
/* Don't allow "CVS" as any directory in module path.
*
@@ -212,11 +212,22 @@ import (argc, argv)
* support branching to a single level, so the specified vendor branch
* must only have two dots in it (like "1.1.1").
*/
- for (cp = vbranch; *cp != '\0'; cp++)
- if (!isdigit ((unsigned char) *cp) && *cp != '.')
- error (1, 0, "%s is not a numeric branch", vbranch);
- if (numdots (vbranch) != 2)
- error (1, 0, "Only branches with two dots are supported: %s", vbranch);
+ {
+ regex_t pat;
+ int ret = regcomp (&pat, "^[1-9][0-9]*\\.[1-9][0-9]*\\.[1-9][0-9]*$",
+ REG_EXTENDED);
+ assert (!ret);
+ if (regexec (&pat, vbranch, 0, NULL, 0))
+ {
+ error (1, 0,
+"Only numeric branch specifications with two dots are\n"
+"supported by import, not `%s'. For example: `1.1.1'.",
+ vbranch);
+ }
+ regfree (&pat);
+ }
+
+ /* Set vhead to the branch's parent. */
vhead = xstrdup (vbranch);
cp = strrchr (vhead, '.');
*cp = '\0';
@@ -230,17 +241,10 @@ import (argc, argv)
}
#endif
- if (
-#ifdef SERVER_SUPPORT
- !server_active &&
-#endif
- use_editor)
+ if (!server_active && use_editor)
{
do_editor ((char *) NULL, &message,
-#ifdef CLIENT_SUPPORT
- current_parsed_root->isremote ? (char *) NULL :
-#endif
- repository,
+ current_parsed_root->isremote ? (char *) NULL : repository,
(List *) NULL);
}
do_verify (&message, repository);
@@ -313,7 +317,8 @@ import (argc, argv)
/* Create the logfile that will be logged upon completion */
if ((logfp = cvs_temp_file (&tmpfile)) == NULL)
- error (1, errno, "cannot create temporary file `%s'", tmpfile);
+ error (1, errno, "cannot create temporary file `%s'",
+ tmpfile ? tmpfile : "(null)");
/* On systems where we can unlink an open file, do so, so it will go
away no matter how we exit. FIXME-maybe: Should be checking for
errors but I'm not sure which error(s) we get if we are on a system
@@ -434,6 +439,9 @@ import_descend (message, vtag, targc, targv)
ign_add_file (CVSDOTIGNORE, 1);
wrap_add_file (CVSDOTWRAPPER, 1);
+ if (!current_parsed_root->isremote)
+ lock_dir_for_write (repository);
+
if ((dirp = CVS_OPENDIR (".")) == NULL)
{
error (0, errno, "cannot open directory");
@@ -446,13 +454,13 @@ import_descend (message, vtag, targc, targv)
{
if (strcmp (dp->d_name, ".") == 0 || strcmp (dp->d_name, "..") == 0)
goto one_more_time_boys;
-#ifdef SERVER_SUPPORT
+
/* CVS directories are created in the temp directory by
server.c because it doesn't special-case import. So
don't print a message about them, regardless of -I!. */
if (server_active && strcmp (dp->d_name, CVSADM) == 0)
goto one_more_time_boys;
-#endif
+
if (ign_name (dp->d_name))
{
add_log ('I', dp->d_name);
@@ -516,6 +524,9 @@ import_descend (message, vtag, targc, targv)
(void) CVS_CLOSEDIR (dirp);
}
+ if (!current_parsed_root->isremote)
+ Lock_Cleanup ();
+
if (dirlist != NULL)
{
Node *head, *p;
@@ -748,7 +759,7 @@ add_rev (message, rcs, vfile, vers)
tocvsPath = wrap_tocvs_process_file (vfile);
status = RCS_checkin (rcs, tocvsPath == NULL ? vfile : tocvsPath,
- message, vbranch,
+ message, vbranch, 0,
(RCS_FLAGS_QUIET | RCS_FLAGS_KEEPFILE
| (use_file_modtime ? RCS_FLAGS_MODTIME : 0)));
ierrno = errno;
@@ -1584,11 +1595,7 @@ import_descend_dir (message, dir, vtag, targc, targv)
repository = new;
}
-#ifdef CLIENT_SUPPORT
if (!quiet && !current_parsed_root->isremote)
-#else
- if (!quiet)
-#endif
error (0, 0, "Importing %s", repository);
if ( CVS_CHDIR (dir) < 0)
@@ -1599,11 +1606,7 @@ import_descend_dir (message, dir, vtag, targc, targv)
err = 1;
goto out;
}
-#ifdef CLIENT_SUPPORT
if (!current_parsed_root->isremote && !isdir (repository))
-#else
- if (!isdir (repository))
-#endif
{
rcs = xmalloc (strlen (repository) + sizeof (RCSEXT) + 5);
(void) sprintf (rcs, "%s%s", repository, RCSEXT);
diff --git a/contrib/cvs/src/lock.c b/contrib/cvs/src/lock.c
index 16e99d8..7a5e338 100644
--- a/contrib/cvs/src/lock.c
+++ b/contrib/cvs/src/lock.c
@@ -1,6 +1,11 @@
/*
- * Copyright (c) 1992, Brian Berliner and Jeff Polk
- * Copyright (c) 1989-1992, Brian Berliner
+ * Copyright (C) 1986-2005 The Free Software Foundation, Inc.
+ *
+ * Portions Copyright (C) 1998-2005 Derek Price, Ximbiot <http://ximbiot.com>,
+ * and others.
+ *
+ * Portions Copyright (C) 1992, Brian Berliner and Jeff Polk
+ * Portions Copyright (C) 1989-1992, Brian Berliner
*
* You may distribute under the terms of the GNU General Public License as
* specified in the README file that comes with the CVS source distribution.
@@ -85,8 +90,17 @@ struct lock {
case of writelocks, it is just a pointer to the storage allocated
for the ->key field. */
char *repository;
- /* Do we have a lock named CVSLCK? */
- int have_lckdir;
+
+ /* The name of the master lock dir. Usually CVSLCK. */
+ const char *lockdirname;
+
+ /* The full path to the lock dir, if we are currently holding it.
+ *
+ * This will be LOCKDIRNAME catted onto REPOSITORY. We waste a little
+ * space by storing it, but save a later malloc/free.
+ */
+ char *lockdir;
+
/* Note there is no way of knowing whether the readlock and writelock
exist. The code which sets the locks doesn't use SIG_beginCrSect
to set a flag like we do for CVSLCK. */
@@ -115,7 +129,6 @@ static char *readlock;
static char *writelock;
/* Malloc'd array specifying the name of a CVSLCK file (absolute pathname).
Will always be non-NULL in the cases where it is used. */
-static char *masterlock;
static List *locklist;
#define L_OK 0 /* success */
@@ -124,7 +137,10 @@ static List *locklist;
/* This is the (single) readlock which is set by Reader_Lock. The
repository field is NULL if there is no such lock. */
-static struct lock global_readlock;
+static struct lock global_readlock = {NULL, CVSLCK, NULL};
+
+static struct lock global_history_lock = {NULL, CVSHISTORYLCK, NULL};
+static struct lock global_val_tags_lock = {NULL, CVSVALTAGSLCK, NULL};
/* List of locks set by lock_tree_for_write. This is redundant
with locklist, sort of. */
@@ -140,7 +156,7 @@ static List *locked_list;
/* LockDir from CVSROOT/config. */
char *lock_dir;
-static char *lock_name PROTO ((char *repository, char *name));
+static char *lock_name PROTO ((const char *repository, const char *name));
/* Return a newly malloc'd string containing the name of the lock for the
repository REPOSITORY and the lock file name within that directory
@@ -150,13 +166,13 @@ static char *lock_name PROTO ((char *repository, char *name));
things simple). */
static char *
lock_name (repository, name)
- char *repository;
- char *name;
+ const char *repository;
+ const char *name;
{
char *retval;
- char *p;
+ const char *p;
char *q;
- char *short_repos;
+ const char *short_repos;
mode_t save_umask;
int saved_umask = 0;
@@ -311,6 +327,10 @@ Lock_Cleanup ()
locked_dir = NULL;
locked_list = NULL;
}
+
+ if (global_history_lock.repository) clear_history_lock ();
+ if (global_val_tags_lock.repository) clear_val_tags_lock ();
+
in_lock_cleanup = 0;
}
@@ -347,6 +367,8 @@ unlock_proc (p, closure)
return (0);
}
+
+
/* Remove the lock files. */
static void
lock_simple_remove (lock)
@@ -361,7 +383,7 @@ lock_simple_remove (lock)
if (readlock != NULL)
{
tmp = lock_name (lock->repository, readlock);
- if ( CVS_UNLINK (tmp) < 0 && ! existence_error (errno))
+ if (CVS_UNLINK (tmp) < 0 && ! existence_error (errno))
error (0, errno, "failed to remove lock %s", tmp);
free (tmp);
}
@@ -373,21 +395,12 @@ lock_simple_remove (lock)
if (writelock != NULL)
{
tmp = lock_name (lock->repository, writelock);
- if ( CVS_UNLINK (tmp) < 0 && ! existence_error (errno))
+ if (CVS_UNLINK (tmp) < 0 && ! existence_error (errno))
error (0, errno, "failed to remove lock %s", tmp);
free (tmp);
}
- if (lock->have_lckdir)
- {
- tmp = lock_name (lock->repository, CVSLCK);
- SIG_beginCrSect ();
- if (CVS_RMDIR (tmp) < 0)
- error (0, errno, "failed to remove lock dir %s", tmp);
- lock->have_lckdir = 0;
- SIG_endCrSect ();
- free (tmp);
- }
+ clear_lock (lock);
}
@@ -655,6 +668,9 @@ readers_exist (repository)
#endif
lockdir = lock_name (repository, "");
+
+ assert (lockdir != NULL);
+
lockdir[strlen (lockdir) - 1] = '\0'; /* remove trailing slash */
do {
@@ -761,13 +777,13 @@ set_lock (lock, will_wait)
long us;
struct stat sb;
mode_t omask;
+ char *masterlock;
+ int status;
#ifdef CVS_FUDGELOCKS
time_t now;
#endif
- if (masterlock != NULL)
- free (masterlock);
- masterlock = lock_name (lock->repository, CVSLCK);
+ masterlock = lock_name (lock->repository, lock->lockdirname);
/*
* Note that it is up to the callers of set_lock() to arrange for signal
@@ -776,33 +792,33 @@ set_lock (lock, will_wait)
*/
waited = 0;
us = 1;
- lock->have_lckdir = 0;
for (;;)
{
- int status = -1;
+ status = -1;
omask = umask (cvsumask);
SIG_beginCrSect ();
if (CVS_MKDIR (masterlock, 0777) == 0)
{
- lock->have_lckdir = 1;
+ lock->lockdir = masterlock;
SIG_endCrSect ();
status = L_OK;
if (waited)
lock_obtained (lock->repository);
- goto out;
+ goto after_sig_unblock;
}
SIG_endCrSect ();
- out:
+ after_sig_unblock:
(void) umask (omask);
if (status != -1)
- return status;
+ goto done;
if (errno != EEXIST)
{
error (0, errno,
"failed to create lock directory for `%s' (%s)",
lock->repository, masterlock);
- return (L_ERROR);
+ status = L_ERROR;
+ goto done;
}
/* Find out who owns the lock. If the lock directory is
@@ -814,7 +830,8 @@ set_lock (lock, will_wait)
continue;
error (0, errno, "couldn't stat lock directory `%s'", masterlock);
- return (L_ERROR);
+ status = L_ERROR;
+ goto done;
}
#ifdef CVS_FUDGELOCKS
@@ -836,7 +853,10 @@ set_lock (lock, will_wait)
/* if he wasn't willing to wait, return an error */
if (!will_wait)
- return (L_LOCKED);
+ {
+ status = L_LOCKED;
+ goto done;
+ }
/* if possible, try a very short sleep without a message */
if (!waited && us < 1000)
@@ -867,23 +887,45 @@ set_lock (lock, will_wait)
lock_wait (lock->repository);
waited = 1;
}
+done:
+ if (!lock->lockdir) free (masterlock);
+ return status;
}
+
+
/*
- * Clear master lock. We don't have to recompute the lock name since
- * clear_lock is never called except after a successful set_lock().
+ * Clear master lock.
+ *
+ * INPUTS
+ * lock The lock information.
+ *
+ * OUTPUTS
+ * Sets LOCK->lockdir to NULL after removing the directory it names and
+ * freeing the storage.
+ *
+ * ASSUMPTIONS
+ * If we own the master lock directory, its name is stored in LOCK->lockdir.
+ * We may free LOCK->lockdir.
+ *
*/
static void
clear_lock (lock)
struct lock *lock;
{
SIG_beginCrSect ();
- if (CVS_RMDIR (masterlock) < 0)
- error (0, errno, "failed to remove lock dir `%s'", masterlock);
- lock->have_lckdir = 0;
+ if (lock->lockdir)
+ {
+ if (CVS_RMDIR (lock->lockdir) < 0)
+ error (0, errno, "failed to remove lock dir `%s'", lock->lockdir);
+ free (lock->lockdir);
+ lock->lockdir = NULL;
+ }
SIG_endCrSect ();
}
+
+
/*
* Print out a message that the lock is still held, then sleep a while.
*/
@@ -958,7 +1000,8 @@ lock_filesdoneproc (callerdat, err, repository, update_dir, entries)
p->key = xstrdup (repository);
p->data = xmalloc (sizeof (struct lock));
((struct lock *)p->data)->repository = p->key;
- ((struct lock *)p->data)->have_lckdir = 0;
+ ((struct lock *)p->data)->lockdirname = CVSLCK;
+ ((struct lock *)p->data)->lockdir = NULL;
/* FIXME-KRP: this error condition should not simply be passed by. */
if (p->key == NULL || addnode (lock_tree_list, p) != 0)
@@ -1011,9 +1054,106 @@ lock_dir_for_write (repository)
node->key = xstrdup (repository);
node->data = xmalloc (sizeof (struct lock));
((struct lock *)node->data)->repository = node->key;
- ((struct lock *)node->data)->have_lckdir = 0;
+ ((struct lock *)node->data)->lockdirname = CVSLCK;
+ ((struct lock *)node->data)->lockdir = NULL;
(void) addnode (locked_list, node);
Writer_Lock (locked_list);
}
}
+
+
+
+/* This is the internal implementation behind history_lock & val_tags_lock. It
+ * gets a write lock for the history or val-tags file.
+ *
+ * RETURNS
+ * true, on success
+ * false, on error
+ */
+static int internal_lock PROTO ((struct lock *lock, const char *xrepository));
+static int
+internal_lock (lock, xrepository)
+ struct lock *lock;
+ const char *xrepository;
+{
+ /* remember what we're locking (for Lock_Cleanup) */
+ assert (!lock->repository);
+ lock->repository = xmalloc (strlen (xrepository) + sizeof (CVSROOTADM) + 2);
+ sprintf (lock->repository, "%s/%s", xrepository, CVSROOTADM);
+
+ /* get the lock dir for our own */
+ if (set_lock (lock, 1) != L_OK)
+ {
+ if (!really_quiet)
+ error (0, 0, "failed to obtain history lock in repository `%s'",
+ xrepository);
+
+ return 0;
+ }
+
+ return 1;
+}
+
+
+
+/* This is the internal implementation behind history_lock & val_tags_lock. It
+ * removes the write lock for the history or val-tags file, when it exists.
+ */
+static void internal_clear_lock PROTO((struct lock *lock));
+static void
+internal_clear_lock (lock)
+ struct lock *lock;
+{
+ SIG_beginCrSect ();
+ if (lock->repository)
+ {
+ free (lock->repository);
+ lock->repository = NULL;
+ }
+ SIG_endCrSect ();
+
+ clear_lock (lock);
+}
+
+
+
+/* Lock the CVSROOT/history file for write.
+ */
+int
+history_lock (xrepository)
+ const char *xrepository;
+{
+ return internal_lock (&global_history_lock, xrepository);
+}
+
+
+
+/* Remove the CVSROOT/history lock, if it exists.
+ */
+void
+clear_history_lock ()
+{
+ internal_clear_lock (&global_history_lock);
+}
+
+
+
+/* Lock the CVSROOT/val-tags file for write.
+ */
+int
+val_tags_lock (xrepository)
+ const char *xrepository;
+{
+ return internal_lock (&global_val_tags_lock, xrepository);
+}
+
+
+
+/* Remove the CVSROOT/val-tags lock, if it exists.
+ */
+void
+clear_val_tags_lock ()
+{
+ internal_clear_lock (&global_val_tags_lock);
+}
diff --git a/contrib/cvs/src/log.c b/contrib/cvs/src/log.c
index 9e10bd9..bb1dbde 100644
--- a/contrib/cvs/src/log.c
+++ b/contrib/cvs/src/log.c
@@ -1,6 +1,11 @@
/*
- * Copyright (c) 1992, Brian Berliner and Jeff Polk
- * Copyright (c) 1989-1992, Brian Berliner
+ * Copyright (C) 1986-2005 The Free Software Foundation, Inc.
+ *
+ * Portions Copyright (C) 1998-2005 Derek Price, Ximbiot <http://ximbiot.com>,
+ * and others.
+ *
+ * Portions Copyright (C) 1992, Brian Berliner and Jeff Polk
+ * Portions Copyright (C) 1989-1992, Brian Berliner
*
* You may distribute under the terms of the GNU General Public License as
* specified in the README file that comes with the CVS source distribution.
@@ -13,6 +18,7 @@
*/
#include "cvs.h"
+#include <assert.h>
/* This structure holds information parsed from the -r option. */
@@ -123,7 +129,7 @@ static int log_fileproc PROTO ((void *callerdat, struct file_info *finfo));
static struct option_revlist *log_parse_revlist PROTO ((const char *));
static void log_parse_date PROTO ((struct log_data *, const char *));
static void log_parse_list PROTO ((List **, const char *));
-static struct revlist *log_expand_revlist PROTO ((RCSNode *,
+static struct revlist *log_expand_revlist PROTO ((RCSNode *, char *,
struct option_revlist *,
int));
static void log_free_revlist PROTO ((struct revlist *));
@@ -150,12 +156,14 @@ static const char *const log_usage[] =
"Usage: %s %s [-lRhtNb] [-r[revisions]] [-d dates] [-s states]\n",
" [-w[logins]] [files...]\n",
"\t-l\tLocal directory only, no recursion.\n",
- "\t-R\tOnly print name of RCS file.\n",
+ "\t-b\tOnly list revisions on the default branch.\n",
"\t-h\tOnly print header.\n",
+ "\t-R\tOnly print name of RCS file.\n",
"\t-t\tOnly print header and descriptive text.\n",
"\t-N\tDo not list tags.\n",
- "\t-S\tDo not print name/header if no revisions selected.\n",
- "\t-b\tOnly list revisions on the default branch.\n",
+ "\t-S\tDo not print name/header if no revisions selected. -d, -r,\n",
+ "\t\t-s, & -w have little effect in conjunction with -b, -h, -R, and\n",
+ "\t\t-t without this option.\n",
"\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.\n",
@@ -308,6 +316,7 @@ cvslog (argc, argv)
{
p = log_data.datelist;
log_data.datelist = p->next;
+ assert (p->start != NULL && p->end != NULL);
send_to_server ("Argument -d\012", 0);
send_to_server ("Argument ", 0);
date_to_internet (datetmp, p->start);
@@ -319,23 +328,21 @@ cvslog (argc, argv)
date_to_internet (datetmp, p->end);
send_to_server (datetmp, 0);
send_to_server ("\012", 0);
- if (p->start)
- free (p->start);
- if (p->end)
- free (p->end);
+ free (p->start);
+ free (p->end);
free (p);
}
while (log_data.singledatelist != NULL)
{
p = log_data.singledatelist;
log_data.singledatelist = p->next;
+ assert (p->end != NULL);
send_to_server ("Argument -d\012", 0);
send_to_server ("Argument ", 0);
date_to_internet (datetmp, p->end);
send_to_server (datetmp, 0);
send_to_server ("\012", 0);
- if (p->end)
- free (p->end);
+ free (p->end);
free (p);
}
@@ -808,21 +815,30 @@ log_fileproc (callerdat, finfo)
{
struct log_data *log_data = (struct log_data *) callerdat;
Node *p;
+ char *baserev;
int selrev = -1;
RCSNode *rcsfile;
char buf[50];
struct revlist *revlist = NULL;
struct log_data_and_rcs log_data_and_rcs;
- if ((rcsfile = finfo->rcs) == NULL)
+ rcsfile = finfo->rcs;
+ p = findnode (finfo->entries, finfo->file);
+ if (p != NULL)
+ {
+ Entnode *e = p->data;
+ baserev = e->version;
+ if (baserev[0] == '-') ++baserev;
+ }
+ else
+ baserev = NULL;
+
+ if (rcsfile == NULL)
{
/* no rcs file. What *do* we know about this file? */
- p = findnode (finfo->entries, finfo->file);
- if (p != NULL)
+ if (baserev != NULL)
{
- Entnode *e = p->data;
-
- if (e->version[0] == '0' && e->version[1] == '\0')
+ if (baserev[0] == '0' && baserev[1] == '\0')
{
if (!really_quiet)
error (0, 0, "%s has been added, but not committed",
@@ -845,7 +861,7 @@ log_fileproc (callerdat, finfo)
/* Turn any symbolic revisions in the revision list into numeric
revisions. */
- revlist = log_expand_revlist (rcsfile, log_data->revlist,
+ revlist = log_expand_revlist (rcsfile, baserev, log_data->revlist,
log_data->default_branch);
if (log_data->sup_header
|| (!log_data->header && !log_data->long_header))
@@ -1035,8 +1051,9 @@ log_fileproc (callerdat, finfo)
* Expand any symbolic revisions.
*/
static struct revlist *
-log_expand_revlist (rcs, revlist, default_branch)
+log_expand_revlist (rcs, baserev, revlist, default_branch)
RCSNode *rcs;
+ char *baserev;
struct option_revlist *revlist;
int default_branch;
{
@@ -1057,13 +1074,26 @@ log_expand_revlist (rcs, revlist, default_branch)
/* If both first and last are NULL, it means that we want
just the head of the default branch, which is RCS_head. */
nr->first = RCS_head (rcs);
- nr->last = xstrdup (nr->first);
- nr->fields = numdots (nr->first) + 1;
+ if (!nr->first)
+ {
+ if (!really_quiet)
+ error (0, 0, "No head revision in archive `%s'.",
+ rcs->path);
+ nr->last = NULL;
+ nr->fields = 0;
+ }
+ else
+ {
+ nr->last = xstrdup (nr->first);
+ nr->fields = numdots (nr->first) + 1;
+ }
}
else if (r->branchhead)
{
char *branch;
+ assert (r->first != NULL);
+
/* Print just the head of the branch. */
if (isdigit ((unsigned char) r->first[0]))
nr->first = RCS_getbranch (rcs, r->first, 1);
@@ -1078,10 +1108,11 @@ log_expand_revlist (rcs, revlist, default_branch)
free (branch);
}
}
- if (nr->first == NULL && !really_quiet)
+ if (!nr->first)
{
- error (0, 0, "warning: no branch `%s' in `%s'",
- r->first, rcs->path);
+ if (!really_quiet)
+ error (0, 0, "warning: no branch `%s' in `%s'",
+ r->first, rcs->path);
nr->last = NULL;
nr->fields = 0;
}
@@ -1097,7 +1128,9 @@ log_expand_revlist (rcs, revlist, default_branch)
nr->first = xstrdup (r->first);
else
{
- if (RCS_nodeisbranch (rcs, r->first))
+ if (baserev && strcmp (r->first, TAG_BASE) == 0)
+ nr->first = xstrdup (baserev);
+ else if (RCS_nodeisbranch (rcs, r->first))
nr->first = RCS_whatbranch (rcs, r->first);
else
nr->first = RCS_gettag (rcs, r->first, 1, (int *) NULL);
@@ -1115,7 +1148,9 @@ log_expand_revlist (rcs, revlist, default_branch)
nr->last = xstrdup (r->last);
else
{
- if (RCS_nodeisbranch (rcs, r->last))
+ if (baserev && strcmp (r->last, TAG_BASE) == 0)
+ nr->last = xstrdup (baserev);
+ else if (RCS_nodeisbranch (rcs, r->last))
nr->last = RCS_whatbranch (rcs, r->last);
else
nr->last = RCS_gettag (rcs, r->last, 1, (int *) NULL);
@@ -1141,6 +1176,7 @@ log_expand_revlist (rcs, revlist, default_branch)
nr->first = xstrdup (nr->last);
cp = strrchr (nr->first, '.');
+ assert (cp);
strcpy (cp + 1, "0");
}
}
@@ -1155,6 +1191,7 @@ log_expand_revlist (rcs, revlist, default_branch)
char *cp;
cp = strrchr (nr->last, '.');
+ assert (cp);
*cp = '\0';
}
}
@@ -1254,7 +1291,9 @@ log_expand_revlist (rcs, revlist, default_branch)
char *cp;
nr->first = xstrdup (rcs->head);
+ assert (nr->first);
cp = strrchr (nr->first, '.');
+ assert (cp);
*cp = '\0';
}
nr->last = xstrdup (nr->first);
@@ -1642,6 +1681,7 @@ log_version (log_data, revlist, rcs, ver, trunk)
if (padd != NULL)
{
+ assert (pdel);
cvs_output (" lines: +", 0);
cvs_output (padd->data, 0);
cvs_output (" -", 2);
diff --git a/contrib/cvs/src/login.c b/contrib/cvs/src/login.c
index 49622e8..fe95544 100644
--- a/contrib/cvs/src/login.c
+++ b/contrib/cvs/src/login.c
@@ -1,5 +1,10 @@
/*
- * Copyright (c) 1995, Cyclic Software, Bloomington, IN, USA
+ * Copyright (C) 1986-2005 The Free Software Foundation, Inc.
+ *
+ * Portions Copyright (C) 1998-2005 Derek Price, Ximbiot <http://ximbiot.com>,
+ * and others.
+ *
+ * Portions Copyright (c) 1995, Cyclic Software, Bloomington, IN, USA
*
* You may distribute under the terms of the GNU General Public License as
* specified in the README file that comes with CVS.
@@ -114,7 +119,7 @@ password_entry_parseline (cvsroot_canonical, warn, linenumber, linebuf)
if (isspace(*(linebuf + 1)))
/* special case since strtoul ignores leading white space */
- entry_version = 0;
+ q = linebuf + 1;
else
entry_version = strtoul (linebuf + 1, &q, 10);
@@ -382,7 +387,8 @@ process:
/* create and open a temp file */
if ((tmp_fp = cvs_temp_file (&tmp_name)) == NULL)
- error (1, errno, "unable to open temp file %s", tmp_name);
+ error (1, errno, "unable to open temp file %s",
+ tmp_name ? tmp_name : "(null)");
line = 0;
while ((line_length = getline (&linebuf, &linebuf_len, fp)) >= 0)
@@ -455,7 +461,7 @@ process:
if (fprintf (fp, "/1 %s %s\n", cvsroot_canonical, newpassword) == EOF)
error (1, errno, "cannot write %s", passfile);
if (fclose (fp) < 0)
- error (0, errno, "cannot close %s", passfile);
+ error (1, errno, "cannot close %s", passfile);
}
/* Utter, total, raving paranoia, I know. */
diff --git a/contrib/cvs/src/logmsg.c b/contrib/cvs/src/logmsg.c
index 52a025a..5ac4b0e 100644
--- a/contrib/cvs/src/logmsg.c
+++ b/contrib/cvs/src/logmsg.c
@@ -1,6 +1,11 @@
/*
- * Copyright (c) 1992, Brian Berliner and Jeff Polk
- * Copyright (c) 1989-1992, Brian Berliner
+ * Copyright (C) 1986-2005 The Free Software Foundation, Inc.
+ *
+ * Portions Copyright (C) 1998-2005 Derek Price, Ximbiot <http://ximbiot.com>,
+ * and others.
+ *
+ * Portions Copyright (C) 1992, Brian Berliner and Jeff Polk
+ * Portions Copyright (C) 1989-1992, Brian Berliner
*
* You may distribute under the terms of the GNU General Public License as
* specified in the README file that comes with the CVS source distribution.
@@ -196,11 +201,7 @@ do_editor (dir, messagep, repository, changes)
struct stat pre_stbuf, post_stbuf;
int retcode = 0;
-#ifdef CLIENT_SUPPORT
assert (!current_parsed_root->isremote != !repository);
-#else
- assert (repository);
-#endif
if (noexec || reuse_log_message)
return;
@@ -290,12 +291,7 @@ do_editor (dir, messagep, repository, changes)
if (editinfo_editor)
free (editinfo_editor);
editinfo_editor = (char *) NULL;
-#ifdef CLIENT_SUPPORT
- if (current_parsed_root->isremote)
- ; /* nothing, leave editinfo_editor NULL */
- else
-#endif
- if (repository != NULL)
+ if (!current_parsed_root->isremote && repository != NULL)
(void) Parse_Info (CVSROOTADM_EDITINFO, repository, editinfo_proc, 0);
/* run the editor */
@@ -422,11 +418,9 @@ do_verify (messagep, repository)
struct stat pre_stbuf, post_stbuf;
-#ifdef CLIENT_SUPPORT
if (current_parsed_root->isremote)
/* The verification will happen on the server. */
return;
-#endif
/* FIXME? Do we really want to skip this on noexec? What do we do
for the other administrative files? */
@@ -445,7 +439,8 @@ do_verify (messagep, repository)
temp file, and close the file. */
if ((fp = cvs_temp_file (&fname)) == NULL)
- error (1, errno, "cannot create temporary file %s", fname);
+ error (1, errno, "cannot create temporary file %s",
+ fname ? fname : "(null)");
if (*messagep != NULL)
fputs (*messagep, fp);
@@ -551,7 +546,7 @@ do_verify (messagep, repository)
if (unlink_file (fname) < 0)
error (0, errno, "cannot remove %s", fname);
free (fname);
- free( verifymsg_script );
+ free (verifymsg_script);
verifymsg_script = NULL;
}
@@ -747,6 +742,8 @@ logfile_write (repository, filter, message, logfp, changes)
char *fmt_percent; /* the location of the percent sign
that starts the format string. */
+ assert (repository);
+
/* The user may specify a format string as part of the filter.
Originally, `%s' was the only valid string. The string that
was substituted for it was:
diff --git a/contrib/cvs/src/main.c b/contrib/cvs/src/main.c
index 2bd7d88..c5911c3 100644
--- a/contrib/cvs/src/main.c
+++ b/contrib/cvs/src/main.c
@@ -1,9 +1,14 @@
/*
- * Copyright (c) 1992, Brian Berliner and Jeff Polk
- * Copyright (c) 1989-1992, Brian Berliner
+ * Copyright (C) 1986-2006 The Free Software Foundation, Inc.
*
- * You may distribute under the terms of the GNU General Public License
- * as specified in the README file that comes with the CVS source distribution.
+ * Portions Copyright (C) 1998-2006 Derek Price, Ximbiot <http://ximbiot.com>,
+ * and others.
+ *
+ * Portions Copyright (C) 1992, Brian Berliner and Jeff Polk
+ * Portions Copyright (C) 1989-1992, Brian Berliner
+ *
+ * You may distribute under the terms of the GNU General Public License
+ * as specified in the README file that comes with the CVS source distribution.
*
* This is the main C driver for the CVS system.
*
@@ -43,6 +48,12 @@ int trace = 0;
int noexec = 0;
int logoff = 0;
+/*
+ * Zero if compression isn't supported or requested; non-zero to indicate
+ * a compression level to request from gzip.
+ */
+int gzip_level;
+
/* Set if we should be writing CVSADM directories at top level. At
least for now we'll make the default be off (the CVS 1.9, not CVS
1.9.2, behavior). */
@@ -63,15 +74,6 @@ char *Editor = EDITOR_DFLT;
values in CVS/Root files, we maintain a list of them. */
List *root_directories = NULL;
-/* We step through the above values. This variable is set to reflect
- * the currently active value.
- *
- * Now static. FIXME - this variable should be removable (well, localizable)
- * with a little more work.
- */
-static char *current_root = NULL;
-
-
static const struct cmd
{
char *fullname; /* Full name of the function (e.g. "commit") */
@@ -187,8 +189,7 @@ static const char *const usg[] =
version control means. */
"For CVS updates and additional information, see\n",
- " the CVS home page at http://www.cvshome.org/ or\n",
- " Pascal Molli's CVS site at http://www.loria.fr/~molli/cvs-index.html\n",
+ " the CVS home page at http://cvs.nongnu.org/\n",
NULL,
};
@@ -272,9 +273,9 @@ set_root_directory (p, ignored)
Node *p;
void *ignored;
{
- if (current_root == NULL && p->data == NULL)
+ if (current_parsed_root == NULL && p->data != NULL)
{
- current_root = p->key;
+ current_parsed_root = p->data;
return 1;
}
return 0;
@@ -394,12 +395,12 @@ main (argc, argv)
int argc;
char **argv;
{
- char *CVSroot = CVSROOT_DFLT;
+ cvsroot_t *CVSroot_parsed = NULL;
+ int cvsroot_update_env = 1;
char *cp, *end;
const struct cmd *cm;
int c, err = 0;
- int tmpdir_update_env, cvs_update_env;
- int free_CVSroot = 0;
+ int tmpdir_update_env;
int free_Editor = 0;
int free_Tmpdir = 0;
@@ -449,7 +450,6 @@ main (argc, argv)
* Query the environment variables up-front, so that
* they can be overridden by command line arguments
*/
- cvs_update_env = 0;
tmpdir_update_env = *Tmpdir; /* TMPDIR_DFLT must be set */
if ((cp = getenv (TMPDIR_ENV)) != NULL)
{
@@ -462,11 +462,6 @@ main (argc, argv)
Editor = cp;
else if ((cp = getenv (EDITOR3_ENV)) != NULL)
Editor = cp;
- if ((cp = getenv (CVSROOT_ENV)) != NULL)
- {
- CVSroot = cp;
- cvs_update_env = 0; /* it's already there */
- }
if (getenv (CVSREAD_ENV) != NULL)
cvswrite = 0;
@@ -543,8 +538,12 @@ main (argc, argv)
version (0, (char **) NULL);
(void) fputs ("\n", stdout);
(void) fputs ("\
-Copyright (c) 1989-2004 Brian Berliner, david d `zoo' zuhn, \n\
- Jeff Polk, and other authors\n", stdout);
+Copyright (C) 2006 Free Software Foundation, Inc.\n\
+\n\
+Senior active maintainers include Larry Jones, Derek R. Price,\n\
+and Mark D. Baushke. Please see the AUTHORS and README files from the CVS\n\
+distribution kit for a complete list of contributors and copyrights.\n",
+ stdout);
(void) fputs ("\n", stdout);
(void) fputs ("CVS may be copied only under the terms of the GNU General Public License,\n", stdout);
(void) fputs ("a copy of which can be found with the CVS distribution kit.\n", stdout);
@@ -552,6 +551,12 @@ Copyright (c) 1989-2004 Brian Berliner, david d `zoo' zuhn, \n\
(void) fputs ("Specify the --help option for further information about CVS\n", stdout);
+#ifdef SYSTEM_CLEANUP
+ /* Hook for OS-specific behavior, for example socket subsystems
+ * on NT and OS2 or dealing with windows and arguments on Mac.
+ */
+ SYSTEM_CLEANUP ();
+#endif
exit (0);
break;
case 'b':
@@ -562,11 +567,13 @@ Copyright (c) 1989-2004 Brian Berliner, david d `zoo' zuhn, \n\
either new or old CVS. */
break;
case 'T':
+ if (free_Tmpdir) free (Tmpdir);
Tmpdir = xstrdup (optarg);
free_Tmpdir = 1;
tmpdir_update_env = 1; /* need to update environment */
break;
case 'e':
+ if (free_Editor) free (Editor);
Editor = xstrdup (optarg);
free_Editor = 1;
break;
@@ -574,11 +581,6 @@ Copyright (c) 1989-2004 Brian Berliner, david d `zoo' zuhn, \n\
if (CVSroot_cmdline != NULL)
free (CVSroot_cmdline);
CVSroot_cmdline = xstrdup (optarg);
- if (free_CVSroot)
- free (CVSroot);
- CVSroot = xstrdup (optarg);
- free_CVSroot = 1;
- cvs_update_env = 1; /* need to update environment */
break;
case 'H':
help = 1;
@@ -587,12 +589,10 @@ Copyright (c) 1989-2004 Brian Berliner, david d `zoo' zuhn, \n\
use_cvsrc = 0; /* unnecessary, since we've done it above */
break;
case 'z':
-#ifdef CLIENT_SUPPORT
gzip_level = strtol (optarg, &end, 10);
if (*end != '\0' || gzip_level < 0 || gzip_level > 9)
error (1, 0,
"gzip compression level must be between 0 and 9");
-#endif /* CLIENT_SUPPORT */
/* If no CLIENT_SUPPORT, we just silently ignore the gzip
* level, so that users can have it in their .cvsrc and not
* cause any trouble.
@@ -716,21 +716,18 @@ Copyright (c) 1989-2004 Brian Berliner, david d `zoo' zuhn, \n\
cvs_cmd_name = "server";
}
# endif /* AUTH_SERVER_SUPPORT || HAVE_GSSAPI */
+#endif /* SERVER_SUPPORT */
server_active = strcmp (cvs_cmd_name, "server") == 0;
-#endif /* SERVER_SUPPORT */
-
/* This is only used for writing into the history file. For
remote connections, it might be nice to have hostname
and/or remote path, on the other hand I'm not sure whether
it is worth the trouble. */
-#ifdef SERVER_SUPPORT
if (server_active)
CurDir = xstrdup ("<remote>");
else
-#endif
{
CurDir = xgetwd ();
if (CurDir == NULL)
@@ -738,7 +735,10 @@ Copyright (c) 1989-2004 Brian Berliner, david d `zoo' zuhn, \n\
}
if (Tmpdir == NULL || Tmpdir[0] == '\0')
+ {
+ if (free_Tmpdir) free (Tmpdir);
Tmpdir = "/tmp";
+ }
#ifdef HAVE_PUTENV
if (tmpdir_update_env)
@@ -786,68 +786,66 @@ Copyright (c) 1989-2004 Brian Berliner, david d `zoo' zuhn, \n\
if (use_cvsrc)
read_cvsrc (&argc, &argv, cvs_cmd_name);
-#ifdef SERVER_SUPPORT
/* Fiddling with CVSROOT doesn't make sense if we're running
- in server mode, since the client will send the repository
- directory after the connection is made. */
-
+ * in server mode, since the client will send the repository
+ * directory after the connection is made.
+ */
if (!server_active)
-#endif
{
- char *CVSADM_Root;
-
- /* See if we are able to find a 'better' value for CVSroot
- in the CVSADM_ROOT directory. */
-
- CVSADM_Root = NULL;
-
- /* "cvs import" shouldn't check CVS/Root; in general it
- ignores CVS directories and CVS/Root is likely to
- specify a different repository than the one we are
- importing to. */
-
- if (!(cm->attr & CVS_CMD_IGNORE_ADMROOT)
-
- /* -d overrides CVS/Root, so don't give an error if the
- latter points to a nonexistent repository. */
- && CVSroot_cmdline == NULL)
+ /* First check if a root was set via the command line. */
+ if (CVSroot_cmdline)
{
- CVSADM_Root = Name_Root((char *) NULL, (char *) NULL);
+ if (!(CVSroot_parsed = parse_cvsroot (CVSroot_cmdline)))
+ error (1, 0, "Bad CVSROOT: `%s'.", CVSroot_cmdline);
}
- if (CVSADM_Root != NULL)
+ /* See if we are able to find a 'better' value for CVSroot
+ * in the CVSADM_ROOT directory.
+ *
+ * "cvs import" shouldn't check CVS/Root; in general it
+ * ignores CVS directories and CVS/Root is likely to
+ * specify a different repository than the one we are
+ * importing to, but if this is not import and no root was
+ * specified on the command line, set the root from the
+ * CVS/Root file.
+ */
+ if (!CVSroot_parsed
+ && !(cm->attr & CVS_CMD_IGNORE_ADMROOT)
+ )
+ CVSroot_parsed = Name_Root (NULL, NULL);
+
+ /* Now, if there is no root on the command line and we didn't find
+ * one in a file, set it via the $CVSROOT env var.
+ */
+ if (!CVSroot_parsed)
{
- if (CVSroot == NULL || !cvs_update_env)
+ char *tmp = getenv (CVSROOT_ENV);
+ if (tmp)
{
- CVSroot = CVSADM_Root;
- cvs_update_env = 1; /* need to update environment */
+ if (!(CVSroot_parsed = parse_cvsroot (tmp)))
+ error (1, 0, "Bad CVSROOT: `%s'.", tmp);
+ cvsroot_update_env = 0;
}
}
+#ifdef CVSROOT_DFLT
+ if (!CVSroot_parsed)
+ {
+ if (!(CVSroot_parsed = parse_cvsroot (CVSROOT_DFLT)))
+ error (1, 0, "Bad CVSROOT: `%s'.", CVSROOT_DFLT);
+ }
+#endif /* CVSROOT_DFLT */
+
/* Now we've reconciled CVSROOT from the command line, the
CVS/Root file, and the environment variable. Do the
last sanity checks on the variable. */
-
- if (! CVSroot)
+ if (!CVSroot_parsed)
{
error (0, 0,
"No CVSROOT specified! Please use the `-d' option");
error (1, 0,
"or set the %s environment variable.", CVSROOT_ENV);
}
-
- if (! *CVSroot)
- {
- error (0, 0,
- "CVSROOT is set but empty! Make sure that the");
- error (0, 0,
- "specification of CVSROOT is valid, either via the");
- error (0, 0,
- "`-d' option, the %s environment variable, or the",
- CVSROOT_ENV);
- error (1, 0,
- "CVS/Root file (if any).");
- }
}
/* Here begins the big loop over unique cvsroot values. We
@@ -859,19 +857,19 @@ Copyright (c) 1989-2004 Brian Berliner, david d `zoo' zuhn, \n\
root_directories = getlist ();
/* Prime it. */
- if (CVSroot != NULL)
+ if (CVSroot_parsed)
{
Node *n;
n = getnode ();
n->type = NT_UNKNOWN;
- n->key = xstrdup (CVSroot);
- n->data = NULL;
+ n->key = xstrdup (CVSroot_parsed->original);
+ n->data = CVSroot_parsed;
if (addnode (root_directories, n))
error (1, 0, "cannot add initial CVSROOT %s", n->key);
}
- assert (current_root == NULL);
+ assert (current_parsed_root == NULL);
/* If we're running the server, we want to execute this main
loop once and only once (we won't be serving multiple roots
@@ -879,70 +877,58 @@ Copyright (c) 1989-2004 Brian Berliner, david d `zoo' zuhn, \n\
once). To get out of the loop, we perform a "break" at the
end of things. */
- while (
-#ifdef SERVER_SUPPORT
- server_active ||
-#endif
- walklist (root_directories, set_root_directory, NULL)
- )
+ while (server_active ||
+ walklist (root_directories, set_root_directory, NULL))
{
-#ifdef SERVER_SUPPORT
/* Fiddling with CVSROOT doesn't make sense if we're running
in server mode, since the client will send the repository
directory after the connection is made. */
if (!server_active)
-#endif
{
/* Now we're 100% sure that we have a valid CVSROOT
variable. Parse it to see if we're supposed to do
remote accesses or use a special access method. */
- 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: `%s'.", current_root);
-
if (trace)
fprintf (stderr, "%s-> main loop with CVSROOT=%s\n",
- CLIENT_SERVER_STR, current_root);
+ CLIENT_SERVER_STR, current_parsed_root->original);
/*
* Check to see if the repository exists.
*/
-#ifdef CLIENT_SUPPORT
if (!current_parsed_root->isremote)
-#endif /* CLIENT_SUPPORT */
{
char *path;
int save_errno;
path = xmalloc (strlen (current_parsed_root->directory)
- + sizeof (CVSROOTADM)
- + 2);
- (void) sprintf (path, "%s/%s", current_parsed_root->directory, CVSROOTADM);
+ + strlen (CVSROOTADM) + 2);
+ sprintf (path, "%s/%s", current_parsed_root->directory,
+ CVSROOTADM);
if (!isaccessible (path, R_OK | X_OK))
{
save_errno = errno;
- /* If this is "cvs init", the root need not exist yet. */
- if (strcmp (cvs_cmd_name, "init") != 0)
- {
+ /* If this is "cvs init", the root need not exist yet.
+ */
+ if (strcmp (cvs_cmd_name, "init"))
error (1, save_errno, "%s", path);
}
- }
free (path);
}
#ifdef HAVE_PUTENV
- /* Update the CVSROOT environment variable if necessary. */
- /* FIXME (njc): should we always set this with the CVSROOT from the command line? */
- if (cvs_update_env)
+ /* Update the CVSROOT environment variable. */
+ if (cvsroot_update_env)
{
static char *prev;
char *env;
- env = xmalloc (strlen (CVSROOT_ENV) + strlen (CVSroot)
- + 1 + 1);
- (void) sprintf (env, "%s=%s", CVSROOT_ENV, CVSroot);
+
+ env = xmalloc (strlen (CVSROOT_ENV)
+ + strlen (current_parsed_root->original)
+ + 2);
+ sprintf (env, "%s=%s", CVSROOT_ENV,
+ current_parsed_root->original);
(void) putenv (env);
/* do not free env yet, as putenv has control of it */
/* but do free the previous value, if any */
@@ -960,14 +946,7 @@ Copyright (c) 1989-2004 Brian Berliner, david d `zoo' zuhn, \n\
predetermine whether CVSROOT/config overrides things from
read_cvsrc and other such places or vice versa. That sort
of thing probably needs more thought. */
- if (1
-#ifdef SERVER_SUPPORT
- && !server_active
-#endif
-#ifdef CLIENT_SUPPORT
- && !current_parsed_root->isremote
-#endif
- )
+ if (!server_active && !current_parsed_root->isremote)
{
/* If there was an error parsing the config file, parse_config
already printed an error. We keep going. Why? Because
@@ -994,31 +973,28 @@ Copyright (c) 1989-2004 Brian Berliner, david d `zoo' zuhn, \n\
err = (*(cm->func)) (argc, argv);
/* Mark this root directory as done. When the server is
- active, current_root will be NULL -- don't try and
+ active, our list will be empty -- don't try and
remove it from the list. */
- if (current_root != NULL)
+ if (!server_active)
{
- Node *n = findnode (root_directories, current_root);
+ Node *n = findnode (root_directories,
+ current_parsed_root->original);
assert (n != NULL);
- n->data = (void *) 1;
- current_root = NULL;
+ assert (n->data != NULL);
+ free_cvsroot_t (n->data);
+ n->data = NULL;
+ current_parsed_root = NULL;
}
-
-#if 0
- /* This will not work yet, since it tries to free (void *) 1. */
- dellist (&root_directories);
-#endif
-#ifdef SERVER_SUPPORT
if (server_active)
{
server_active = 0;
break;
}
-#endif
} /* end of loop for cvsroot values */
+ dellist (&root_directories);
} /* end of stuff that gets done if the user DOESN'T ask for help */
Lock_Cleanup ();
@@ -1030,8 +1006,6 @@ Copyright (c) 1989-2004 Brian Berliner, david d `zoo' zuhn, \n\
free ((char *)program_path);
if (CVSroot_cmdline != NULL)
free (CVSroot_cmdline);
- if (free_CVSroot)
- free (CVSroot);
if (free_Editor)
free (Editor);
if (free_Tmpdir)
diff --git a/contrib/cvs/src/mkmodules.c b/contrib/cvs/src/mkmodules.c
index 4ed3291..3ac06b3 100644
--- a/contrib/cvs/src/mkmodules.c
+++ b/contrib/cvs/src/mkmodules.c
@@ -1,6 +1,11 @@
/*
- * Copyright (c) 1992, Brian Berliner and Jeff Polk
- * Copyright (c) 1989-1992, Brian Berliner
+ * Copyright (C) 1986-2005 The Free Software Foundation, Inc.
+ *
+ * Portions Copyright (C) 1998-2005 Derek Price, Ximbiot <http://ximbiot.com>,
+ * and others.
+ *
+ * Portions Copyright (C) 1992, Brian Berliner and Jeff Polk
+ * Portions 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. */
@@ -281,7 +286,7 @@ static const char *const modules_contents[] = {
static const char *const config_contents[] = {
"# Set this to \"no\" if pserver shouldn't check system users/passwords\n",
- "#SystemAuth=no\n",
+ "#SystemAuth=yes\n",
"\n",
"# Put CVS lock files in this directory rather than directly in the repository.\n",
"#LockDir=/var/lock/cvs\n",
@@ -302,7 +307,7 @@ static const char *const config_contents[] = {
"#LogHistory=" ALL_HISTORY_REC_TYPES "\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",
+ "# script to change the log message. Set it to `stat' to force CVS to verify\n",
"# 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",
@@ -576,7 +581,17 @@ checkout_file (file, temp)
free (rcs);
return (1);
}
+
rcsnode = RCS_parsercsfile (rcs);
+ if (!rcsnode)
+ {
+ /* Probably not necessary (?); RCS_parsercsfile already printed a
+ message. */
+ error (0, 0, "Failed to parse `%s'.", rcs);
+ free (rcs);
+ return 1;
+ }
+
retcode = RCS_checkout (rcsnode, NULL, NULL, NULL, NULL, temp,
(RCSCHECKOUTPROC) NULL, (void *) NULL);
if (retcode != 0)
diff --git a/contrib/cvs/src/modules.c b/contrib/cvs/src/modules.c
index a784a86..eed551e 100644
--- a/contrib/cvs/src/modules.c
+++ b/contrib/cvs/src/modules.c
@@ -1,6 +1,11 @@
/*
- * Copyright (c) 1992, Brian Berliner and Jeff Polk
- * Copyright (c) 1989-1992, Brian Berliner
+ * Copyright (C) 1986-2005 The Free Software Foundation, Inc.
+ *
+ * Portions Copyright (C) 1998-2005 Derek Price, Ximbiot <http://ximbiot.com>,
+ * and others.
+ *
+ * Portions Copyright (C) 1992, Brian Berliner and Jeff Polk
+ * Portions Copyright (C) 1989-1992, Brian Berliner
*
* You may distribute under the terms of the GNU General Public License
* as specified in the README file that comes with the CVS source
@@ -131,7 +136,6 @@ my_module (db, mname, m_type, msg, callback_proc, where, shorten,
char *mwhere = NULL;
char *mfile = NULL;
char *spec_opt = NULL;
- char *xvalue = NULL;
int alias = 0;
datum key, val;
char *cp;
@@ -371,6 +375,7 @@ my_module (db, mname, m_type, msg, callback_proc, where, shorten,
/* mwhere gets just the module name */
mwhere = xstrdup (mname);
mfile = cp + 1;
+ assert (strlen (mfile));
/* put the / back in mname */
*cp = '/';
@@ -744,7 +749,7 @@ module `%s' is a request for a file in a module which is not a directory",
err += run_exec (RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL);
free (expanded_path);
}
- free (real_prog);
+ if (real_prog) free (real_prog);
}
}
@@ -765,8 +770,6 @@ module `%s' is a request for a file in a module which is not a directory",
if (value != NULL)
free (value);
- if (xvalue != NULL)
- free (xvalue);
return (err);
}
diff --git a/contrib/cvs/src/myndbm.c b/contrib/cvs/src/myndbm.c
index a5afcce..cb99cc2 100644
--- a/contrib/cvs/src/myndbm.c
+++ b/contrib/cvs/src/myndbm.c
@@ -1,5 +1,11 @@
/*
- * Copyright (c) 1992, Brian Berliner
+ * Copyright (C) 1986-2005 The Free Software Foundation, Inc.
+ *
+ * Portions Copyright (C) 1998-2005 Derek Price, Ximbiot <http://ximbiot.com>,
+ * and others.
+ *
+ * Portions Copyright (C) 1992, Brian Berliner and Jeff Polk
+ * Portions Copyright (C) 1989-1992, Brian Berliner
*
* You may distribute under the terms of the GNU General Public License as
* specified in the README file that comes with the CVS source distribution.
diff --git a/contrib/cvs/src/myndbm.h b/contrib/cvs/src/myndbm.h
index 2bce739..de23519 100644
--- a/contrib/cvs/src/myndbm.h
+++ b/contrib/cvs/src/myndbm.h
@@ -1,3 +1,17 @@
+/*
+ * Copyright (C) 1994-2005 The Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
#ifdef MY_NDBM
#define DBLKSIZ 4096
diff --git a/contrib/cvs/src/no_diff.c b/contrib/cvs/src/no_diff.c
index ebddcd3..45847a1 100644
--- a/contrib/cvs/src/no_diff.c
+++ b/contrib/cvs/src/no_diff.c
@@ -1,6 +1,11 @@
/*
- * Copyright (c) 1992, Brian Berliner and Jeff Polk
- * Copyright (c) 1989-1992, Brian Berliner
+ * Copyright (C) 1986-2005 The Free Software Foundation, Inc.
+ *
+ * Portions Copyright (C) 1998-2005 Derek Price, Ximbiot <http://ximbiot.com>,
+ * and others.
+ *
+ * Portions Copyright (C) 1992, Brian Berliner and Jeff Polk
+ * Portions Copyright (C) 1989-1992, Brian Berliner
*
* You may distribute under the terms of the GNU General Public License as
* specified in the README file that comes with the CVS source distribution.
@@ -15,6 +20,7 @@
*/
#include "cvs.h"
+#include <assert.h>
int
No_Difference (finfo, vers)
@@ -71,6 +77,7 @@ No_Difference (finfo, vers)
/* update the entdata pointer in the vers_ts structure */
p = findnode (finfo->entries, finfo->file);
+ assert (p);
vers->entdata = p->data;
ret = 0;
diff --git a/contrib/cvs/src/parseinfo.c b/contrib/cvs/src/parseinfo.c
index 27f7d79..0fe9c33 100644
--- a/contrib/cvs/src/parseinfo.c
+++ b/contrib/cvs/src/parseinfo.c
@@ -1,6 +1,11 @@
/*
- * Copyright (c) 1992, Brian Berliner and Jeff Polk
- * Copyright (c) 1989-1992, Brian Berliner
+ * Copyright (C) 1986-2005 The Free Software Foundation, Inc.
+ *
+ * Portions Copyright (C) 1998-2005 Derek Price, Ximbiot <http://ximbiot.com>,
+ * and others.
+ *
+ * Portions Copyright (C) 1992, Brian Berliner and Jeff Polk
+ * Portions Copyright (C) 1989-1992, Brian Berliner
*
* You may distribute under the terms of the GNU General Public License as
* specified in the README file that comes with the CVS source distribution.
@@ -9,6 +14,7 @@
#include "cvs.h"
#include "getline.h"
#include <assert.h>
+#include "history.h"
extern char *logHistory;
@@ -40,6 +46,8 @@ Parse_Info (infofile, repository, callproc, all)
const char *srepos;
const char *regex_err;
+ assert (repository);
+
if (current_parsed_root == NULL)
{
/* XXX - should be error maybe? */
@@ -270,8 +278,7 @@ parse_config (cvsroot)
value, currently at least. */
error (0, errno, "cannot open %s", infopath);
}
- free (infopath);
- return 0;
+ goto set_defaults_and_return;
}
while (getline (&line, &line_allocated, fp_info) >= 0)
@@ -395,8 +402,8 @@ warning: this CVS does not support PreservePermissions");
{
if (strcmp (p, "all") != 0)
{
- logHistory=xmalloc(strlen (p) + 1);
- strcpy (logHistory, p);
+ if (logHistory) free (logHistory);
+ logHistory = xstrdup (p);
}
}
else if (strcmp (line, "RereadLogAfterVerify") == 0)
@@ -436,12 +443,17 @@ warning: this CVS does not support PreservePermissions");
error (0, errno, "cannot close %s", infopath);
goto error_return;
}
+set_defaults_and_return:
+ if (!logHistory)
+ logHistory = xstrdup (ALL_HISTORY_REC_TYPES);
free (infopath);
if (line != NULL)
free (line);
return 0;
error_return:
+ if (!logHistory)
+ logHistory = xstrdup (ALL_HISTORY_REC_TYPES);
if (infopath != NULL)
free (infopath);
if (line != NULL)
diff --git a/contrib/cvs/src/patch.c b/contrib/cvs/src/patch.c
index cba6a8a..9af10a6 100644
--- a/contrib/cvs/src/patch.c
+++ b/contrib/cvs/src/patch.c
@@ -1,6 +1,11 @@
/*
- * Copyright (c) 1992, Brian Berliner and Jeff Polk
- * Copyright (c) 1989-1992, Brian Berliner
+ * Copyright (C) 1986-2005 The Free Software Foundation, Inc.
+ *
+ * Portions Copyright (C) 1998-2005 Derek Price, Ximbiot <http://ximbiot.com>,
+ * and others.
+ *
+ * Portions Copyright (C) 1992, Brian Berliner and Jeff Polk
+ * Portions Copyright (C) 1989-1992, Brian Berliner
*
* You may distribute under the terms of the GNU General Public License as
* specified in the README file that comes with the CVS source distribution.
@@ -42,7 +47,7 @@ static int unidiff = 0;
static const char *const patch_usage[] =
{
- "Usage: %s %s [-flR] [-c|-u] [-s|-t] [-V %%d]\n",
+ "Usage: %s %s [-flR] [-c|-u] [-s|-t] [-V %%d] [-k kopt]\n",
" -r rev|-D date [-r rev2 | -D date2] modules...\n",
"\t-f\tForce a head revision match if tag/date not found.\n",
"\t-l\tLocal directory only, not recursive\n",
@@ -51,9 +56,10 @@ static const char *const patch_usage[] =
"\t-u\tUnidiff format.\n",
"\t-s\tShort patch - one liner per file.\n",
"\t-t\tTop two diffs - last change made to the file.\n",
+ "\t-V vers\tUse RCS Version \"vers\" for keyword expansion.\n",
+ "\t-k kopt\tSpecify keyword expansion mode.\n",
"\t-D date\tDate.\n",
"\t-r rev\tRevision - symbolic or numeric.\n",
- "\t-V vers\tUse RCS Version \"vers\" for keyword expansion.\n",
"(Specify the --help global option for a list of other help options)\n",
NULL
};
@@ -81,11 +87,9 @@ patch (argc, argv)
{
case 'Q':
case 'q':
-#ifdef SERVER_SUPPORT
/* The CVS 1.5 client sends these options (in addition to
Global_option requests), so we must ignore them. */
if (!server_active)
-#endif
error (1, 0,
"-q or -Q must be specified before \"%s\"",
cvs_cmd_name);
@@ -338,6 +342,7 @@ patch_proc (argc, argv, xwhere, mwhere, mfile, shorten, local_specified,
{
error (0, errno, "cannot chdir to %s", repository);
free (repository);
+ free (where);
return 1;
}
@@ -385,6 +390,7 @@ patch_fileproc (callerdat, finfo)
struct utimbuf t;
char *vers_tag, *vers_head;
char *rcs = NULL;
+ char *rcs_orig = NULL;
RCSNode *rcsfile;
FILE *fp1, *fp2, *fp3;
int ret = 0;
@@ -399,6 +405,9 @@ patch_fileproc (callerdat, finfo)
char *cp1, *cp2;
FILE *fp;
int line_length;
+ int dargc = 0;
+ size_t darg_allocated = 0;
+ char **dargv = NULL;
line1 = NULL;
line1_chars_allocated = 0;
@@ -415,7 +424,7 @@ patch_fileproc (callerdat, finfo)
if ((rcsfile->flags & VALID) && (rcsfile->flags & INATTIC))
isattic = 1;
- rcs = xmalloc (strlen (finfo->file) + sizeof (RCSEXT) + 5);
+ rcs_orig = rcs = xmalloc (strlen (finfo->file) + sizeof (RCSEXT) + 5);
(void) sprintf (rcs, "%s%s", finfo->file, RCSEXT);
/* if vers_head is NULL, may have been removed from the release */
@@ -509,7 +518,8 @@ patch_fileproc (callerdat, finfo)
*/
if ((fp1 = cvs_temp_file (&tmpfile1)) == NULL)
{
- error (0, errno, "cannot create temporary file %s", tmpfile1);
+ error (0, errno, "cannot create temporary file %s",
+ tmpfile1 ? tmpfile1 : "(null)");
ret = 1;
goto out;
}
@@ -518,7 +528,8 @@ patch_fileproc (callerdat, finfo)
error (0, errno, "warning: cannot close %s", tmpfile1);
if ((fp2 = cvs_temp_file (&tmpfile2)) == NULL)
{
- error (0, errno, "cannot create temporary file %s", tmpfile2);
+ error (0, errno, "cannot create temporary file %s",
+ tmpfile2 ? tmpfile2 : "(null)");
ret = 1;
goto out;
}
@@ -527,7 +538,8 @@ patch_fileproc (callerdat, finfo)
error (0, errno, "warning: cannot close %s", tmpfile2);
if ((fp3 = cvs_temp_file (&tmpfile3)) == NULL)
{
- error (0, errno, "cannot create temporary file %s", tmpfile3);
+ error (0, errno, "cannot create temporary file %s",
+ tmpfile3 ? tmpfile3 : "(null)");
ret = 1;
goto out;
}
@@ -578,8 +590,10 @@ patch_fileproc (callerdat, finfo)
(void)utime (tmpfile2, &t);
}
- switch (diff_exec (tmpfile1, tmpfile2, NULL, NULL, unidiff ? "-u" : "-c",
- tmpfile3))
+ if (unidiff) run_add_arg_p (&dargc, &darg_allocated, &dargv, "-u");
+ else run_add_arg_p (&dargc, &darg_allocated, &dargv, "-c");
+ switch (diff_exec (tmpfile1, tmpfile2, NULL, NULL, dargc, dargv,
+ tmpfile3))
{
case -1: /* fork/wait failure */
error (1, errno, "fork for diff failed on %s", rcs);
@@ -741,24 +755,41 @@ failed to read diff file header %s for %s: end of file", tmpfile3, rcs);
free (line1);
if (line2)
free (line2);
- if (CVS_UNLINK (tmpfile1) < 0)
- error (0, errno, "cannot unlink %s", tmpfile1);
- if (CVS_UNLINK (tmpfile2) < 0)
- error (0, errno, "cannot unlink %s", tmpfile2);
- if (CVS_UNLINK (tmpfile3) < 0)
- error (0, errno, "cannot unlink %s", tmpfile3);
- free (tmpfile1);
- free (tmpfile2);
- free (tmpfile3);
- tmpfile1 = tmpfile2 = tmpfile3 = NULL;
+ if (tmpfile1 != NULL)
+ {
+ if (CVS_UNLINK (tmpfile1) < 0)
+ error (0, errno, "cannot unlink %s", tmpfile1);
+ free (tmpfile1);
+ tmpfile1 = NULL;
+ }
+ if (tmpfile2 != NULL)
+ {
+ if (CVS_UNLINK (tmpfile2) < 0)
+ error (0, errno, "cannot unlink %s", tmpfile2);
+ free (tmpfile2);
+ tmpfile2 = NULL;
+ }
+ if (tmpfile3 != NULL)
+ {
+ if (CVS_UNLINK (tmpfile3) < 0)
+ error (0, errno, "cannot unlink %s", tmpfile3);
+ free (tmpfile3);
+ tmpfile3 = NULL;
+ }
+
+ if (dargc)
+ {
+ run_arg_free_p (dargc, dargv);
+ free (dargv);
+ }
out2:
if (vers_tag != NULL)
free (vers_tag);
if (vers_head != NULL)
free (vers_head);
- if (rcs != NULL)
- free (rcs);
+ if (rcs_orig)
+ free (rcs_orig);
return ret;
}
diff --git a/contrib/cvs/src/rcs.c b/contrib/cvs/src/rcs.c
index 607a879..e1d62ed 100644
--- a/contrib/cvs/src/rcs.c
+++ b/contrib/cvs/src/rcs.c
@@ -1,5 +1,11 @@
/*
- * Copyright (c) 1992, Brian Berliner and Jeff Polk
+ * Copyright (C) 1986-2005 The Free Software Foundation, Inc.
+ *
+ * Portions Copyright (C) 1998-2005 Derek Price, Ximbiot <http://ximbiot.com>,
+ * and others.
+ *
+ * Portions Copyright (C) 1992, Brian Berliner and Jeff Polk
+ * Portions Copyright (C) 1989-1992, Brian Berliner
*
* You may distribute under the terms of the GNU General Public License as
* specified in the README file that comes with the CVS source distribution.
@@ -298,8 +304,8 @@ RCS_parse (file, repos)
}
else if (! existence_error (errno))
{
- free ( rcsfile );
error (0, errno, "cannot open %s", rcsfile);
+ free (rcsfile);
}
return retval;
@@ -495,8 +501,13 @@ RCS_reparsercsfile (rdata, pfp, rcsbufp)
RCS_addaccess expects nothing but spaces. FIXME:
It would be easy and more efficient to change
RCS_addaccess. */
- rdata->access = rcsbuf_valcopy (&rcsbuf, value, 1,
- (size_t *) NULL);
+ if (rdata->access)
+ {
+ error (0, 0,
+ "Duplicate `access' keyword found in RCS file.");
+ free (rdata->access);
+ }
+ rdata->access = rcsbuf_valcopy (&rcsbuf, value, 1, NULL);
}
continue;
}
@@ -506,8 +517,15 @@ RCS_reparsercsfile (rdata, pfp, rcsbufp)
if (STREQ (key, "locks"))
{
if (value != NULL)
- rdata->locks_data = rcsbuf_valcopy (&rcsbuf, value, 0,
- (size_t *) NULL);
+ {
+ if (rdata->locks_data)
+ {
+ error (0, 0,
+ "Duplicate `locks' keyword found in RCS file.");
+ free (rdata->locks_data);
+ }
+ rdata->locks_data = rcsbuf_valcopy (&rcsbuf, value, 0, NULL);
+ }
if (! rcsbuf_getkey (&rcsbuf, &key, &value))
{
error (1, 0, "premature end of file reading %s", rcsfile);
@@ -524,8 +542,16 @@ RCS_reparsercsfile (rdata, pfp, rcsbufp)
if (STREQ (RCSSYMBOLS, key))
{
if (value != NULL)
- rdata->symbols_data = rcsbuf_valcopy (&rcsbuf, value, 0,
- (size_t *) NULL);
+ {
+ if (rdata->symbols_data)
+ {
+ error (0, 0,
+ "Duplicate `%s' keyword found in RCS file.",
+ RCSSYMBOLS);
+ free (rdata->symbols_data);
+ }
+ rdata->symbols_data = rcsbuf_valcopy (&rcsbuf, value, 0, NULL);
+ }
continue;
}
@@ -549,8 +575,14 @@ RCS_reparsercsfile (rdata, pfp, rcsbufp)
if (STREQ (key, "comment"))
{
- rdata->comment = rcsbuf_valcopy (&rcsbuf, value, 0,
- (size_t *) NULL);
+ if (rdata->comment)
+ {
+ error (0, 0,
+ "warning: duplicate key `%s' in RCS file `%s'",
+ key, rcsfile);
+ free (rdata->comment);
+ }
+ rdata->comment = rcsbuf_valcopy (&rcsbuf, value, 0, NULL);
continue;
}
if (rdata->other == NULL)
@@ -584,14 +616,9 @@ RCS_reparsercsfile (rdata, pfp, rcsbufp)
q->key = vnode->version;
/* add the nodes to the list */
- if (addnode (rdata->versions, q) != 0)
- {
-#if 0
- purify_printf("WARNING: Adding duplicate version: %s (%s)\n",
- q->key, rcsfile);
- freenode (q);
-#endif
- }
+ if (addnode (rdata->versions, q))
+ error (1, 0, "Multiple %s revision deltas found in `%s'",
+ q->key, rcsfile);
}
/* Here KEY and VALUE are whatever caused getdelta to return NULL. */
@@ -745,10 +772,10 @@ RCS_fully_parse (rcs)
break;
vers = findnode (rcs->versions, key);
- if (vers == NULL)
+ if (!vers)
error (1, 0,
- "mismatch in rcs file %s between deltas and deltatexts (%s)",
- rcs->path, key);
+ "Delta text %s without revision information in `%s'.",
+ key, rcs->path);
vnode = vers->data;
@@ -2072,6 +2099,8 @@ do_symbols (list, val)
char *cp = val;
char *tag, *rev;
+ assert (cp);
+
for (;;)
{
/* skip leading whitespace */
@@ -2114,6 +2143,8 @@ do_locks (list, val)
char *cp = val;
char *user, *rev;
+ assert (cp);
+
for (;;)
{
/* skip leading whitespace */
@@ -2298,6 +2329,12 @@ RCS_tag2rev (rcs, tag)
* the 0 in some other position -- <dan@gasboy.com>
*/
pa = strrchr (rev, '.');
+ if (!pa)
+ /* This might happen, for instance, if an RCS file only contained
+ * revisions 2.x and higher, and REV == "1".
+ */
+ error (1, 0, "revision `%s' does not exist", tag);
+
pb = xmalloc (strlen (rev) + 3);
*pa++ = 0;
(void) sprintf (pb, "%s.%d.%s", rev, RCS_MAGIC_BRANCH, pa);
@@ -2872,8 +2909,9 @@ RCS_getbranchpoint (rcs, target)
vp = findnode (rcs->versions, branch);
if (vp == NULL)
- {
+ {
error (0, 0, "%s: can't find branch point %s", rcs->path, target);
+ free (branch);
return NULL;
}
rev = vp->data;
@@ -3007,6 +3045,8 @@ RCS_getdate (rcs, date, force_tag_match)
{
char *date_1_1 = vers->date;
+ assert (p->data != NULL);
+
vers = p->data;
if (RCS_datecmp (vers->date, date_1_1) != 0)
return xstrdup ("1.1");
@@ -3024,8 +3064,7 @@ RCS_getdate (rcs, date, force_tag_match)
if (retval != NULL)
return (retval);
- if (!force_tag_match ||
- (vers != NULL && RCS_datecmp (vers->date, date) <= 0))
+ if (vers && (!force_tag_match || RCS_datecmp (vers->date, date) <= 0))
return xstrdup (vers->version);
else
return NULL;
@@ -3276,7 +3315,7 @@ translate_symtag (rcs, tag)
if (rcs->symbols_data != NULL)
{
size_t len;
- char *cp;
+ char *cp, *last;
/* Look through the RCS symbols information. This is like
do_symbols, but we don't add the information to a list. In
@@ -3285,8 +3324,16 @@ translate_symtag (rcs, tag)
len = strlen (tag);
cp = rcs->symbols_data;
+ /* Keeping track of LAST below isn't strictly necessary, now that tags
+ * should be parsed for validity before they are accepted, but tags
+ * with spaces used to cause the code below to loop indefintely, so
+ * I have corrected for that. Now, in the event that I missed
+ * something, the server cannot be hung. -DRP
+ */
+ last = NULL;
while ((cp = strchr (cp, tag[0])) != NULL)
{
+ if (cp == last) break;
if ((cp == rcs->symbols_data || whitespace (cp[-1]))
&& strncmp (cp, tag, len) == 0
&& cp[len] == ':')
@@ -3309,6 +3356,7 @@ translate_symtag (rcs, tag)
++cp;
if (*cp == '\0')
break;
+ last = cp;
}
}
@@ -3436,6 +3484,8 @@ RCS_isdead (rcs, tag)
Node *p;
RCSVers *version;
+ assert (rcs != NULL);
+
if (rcs->flags & PARTIAL)
RCS_reparsercsfile (rcs, (FILE **) NULL, (struct rcsbuffer *) NULL);
@@ -3896,6 +3946,13 @@ expand_keywords (rcs, ver, name, log, loglen, expand, buf, len, retbuf, retlen)
if (*snl == '\n')
++cnl;
+ /* If the log message did not end in a newline, increment
+ * the newline count so we have space for the extra leader.
+ * Failure to do so results in a buffer overrun.
+ */
+ if (loglen && snl[-1] != '\n')
+ ++cnl;
+
date = printable_date (ver->date);
sub = xrealloc (sub,
(sublen
@@ -3904,6 +3961,10 @@ expand_keywords (rcs, ver, name, log, loglen, expand, buf, len, retbuf, retlen)
+ strlen (date)
+ strlen (ver->author)
+ loglen
+ /* Use CNL + 2 below: One leader for each log
+ * line, plus the Revision/Author/Date line,
+ * plus a trailing blank line.
+ */
+ (cnl + 2) * leader_len
+ 20));
if (expand != KFLAG_V)
@@ -3943,6 +4004,14 @@ expand_keywords (rcs, ver, name, log, loglen, expand, buf, len, retbuf, retlen)
++slnl;
memcpy (sub + sublen, sl, slnl - sl);
sublen += slnl - sl;
+ if (slnl == logend && slnl[-1] != '\n')
+ {
+ /* There was no EOL at the end of the log message. Add
+ * one.
+ */
+ sub[sublen] = '\n';
+ ++sublen;
+ }
sl = slnl;
}
}
@@ -4061,7 +4130,8 @@ expand_keywords (rcs, ver, name, log, loglen, expand, buf, len, retbuf, retlen)
Otherwise, if WORKFILE is NULL, check out the revision to SOUT. If
SOUT is RUN_TTY, then write the contents of the revision to
standard output. When using SOUT, the output is generally a
- temporary file; don't bother to get the file modes correct.
+ temporary file; don't bother to get the file modes correct. When
+ NOEXEC is set, WORKFILEs are not written but SOUTs are.
REV is the numeric revision to check out. It may be NULL, which
means to check out the head of the default branch.
@@ -4103,7 +4173,7 @@ RCS_checkout (rcs, workfile, rev, nametag, options, sout, pfn, callerdat)
size_t len;
int free_value = 0;
char *log = NULL;
- size_t loglen;
+ size_t loglen = 0;
Node *vp = NULL;
#ifdef PRESERVE_PERMISSIONS_SUPPORT
uid_t rcs_owner = (uid_t) -1;
@@ -4136,7 +4206,7 @@ RCS_checkout (rcs, workfile, rev, nametag, options, sout, pfn, callerdat)
assert (rev == NULL || isdigit ((unsigned char) *rev));
- if (noexec && workfile != NULL)
+ if (noexec && !server_active && workfile != NULL)
return 0;
assert (sout == RUN_TTY || workfile == NULL);
@@ -4166,10 +4236,23 @@ RCS_checkout (rcs, workfile, rev, nametag, options, sout, pfn, callerdat)
gothead = 0;
if (! rcsbuf_getrevnum (&rcsbuf, &key))
error (1, 0, "unexpected EOF reading %s", rcs->path);
+
+ if (!STREQ (rcs->head, key))
+ error (1, 0, "Expected head revision %s, found %s.",
+ rcs->head, key);
+
while (rcsbuf_getkey (&rcsbuf, &key, &value))
{
if (STREQ (key, "log"))
+ {
+ if (log)
+ {
+ error (0, 0,
+"Duplicate log keyword found for head revision in RCS file.");
+ free (log);
+ }
log = rcsbuf_valcopy (&rcsbuf, value, 0, &loglen);
+ }
else if (STREQ (key, "text"))
{
gothead = 1;
@@ -4669,6 +4752,7 @@ RCS_findlock_or_tip (rcs)
char *user = getcaller();
Node *lock, *p;
List *locklist;
+ char *defaultrev = NULL;
/* Find unique delta locked by caller. This code is very similar
to the code in RCS_unlock -- perhaps it could be abstracted
@@ -4714,7 +4798,17 @@ RCS_findlock_or_tip (rcs)
those error checks are to make users lock before a checkin, and we do
that in other ways if at all anyway (e.g. rcslock.pl). */
- p = findnode (rcs->versions, RCS_getbranch (rcs, rcs->branch, 0));
+ defaultrev = RCS_getbranch (rcs, rcs->branch, 0);
+ p = findnode (rcs->versions, defaultrev);
+ if (defaultrev != NULL)
+ free (defaultrev);
+ if (!p)
+ {
+ error (0, 0, "RCS file `%s' does not contain its default revision.",
+ rcs->path);
+ return NULL;
+ }
+
return p->data;
}
@@ -4828,6 +4922,8 @@ RCS_addbranch (rcs, branch)
Node *marker;
RCSVers *branchnode;
+ assert (branch);
+
/* Append to end by default. */
marker = NULL;
@@ -4946,18 +5042,21 @@ RCS_addbranch (rcs, branch)
or zero for success. */
int
-RCS_checkin (rcs, workfile_in, message, rev, flags)
+RCS_checkin (rcs, workfile_in, message, rev, citime, flags)
RCSNode *rcs;
const char *workfile_in;
const char *message;
const char *rev;
+ time_t citime;
int flags;
{
RCSVers *delta, *commitpt;
Deltatext *dtext;
Node *nodep;
char *tmpfile, *changefile;
- char *diffopts;
+ int dargc = 0;
+ size_t darg_allocated = 0;
+ char **dargv = NULL;
size_t bufsize;
int status, checkin_quiet;
struct tm *ftm;
@@ -4979,6 +5078,7 @@ RCS_checkin (rcs, workfile_in, message, rev, flags)
{
char *p;
int extlen = strlen (RCSEXT);
+ assert (rcs->path);
workfile = xstrdup (last_component (rcs->path));
p = workfile + (strlen (workfile) - extlen);
assert (strncmp (p, RCSEXT, extlen) == 0);
@@ -5013,6 +5113,8 @@ RCS_checkin (rcs, workfile_in, message, rev, flags)
}
modtime = ws.st_mtime;
}
+ else if (flags & RCS_FLAGS_USETIME)
+ modtime = citime;
else
(void) time (&modtime);
ftm = gmtime (&modtime);
@@ -5254,6 +5356,7 @@ workfile);
if (dots == 0)
{
tip = xstrdup (rcs->head);
+ assert (tip != NULL);
if (atoi (tip) != atoi (branch))
{
newrev = (char *) xrealloc (newrev, strlen (newrev) + 3);
@@ -5383,9 +5486,10 @@ workfile);
/* Diff options should include --binary if the RCS file has -kb set
in its `expand' field. */
- diffopts = (rcs->expand != NULL && STREQ (rcs->expand, "b")
- ? "-a -n --binary"
- : "-a -n");
+ run_add_arg_p (&dargc, &darg_allocated, &dargv, "-a");
+ run_add_arg_p (&dargc, &darg_allocated, &dargv, "-n");
+ if (rcs->expand && STREQ (rcs->expand, "b"))
+ run_add_arg_p (&dargc, &darg_allocated, &dargv, "--binary");
if (STREQ (commitpt->version, rcs->head) &&
numdots (delta->version) == 1)
@@ -5408,7 +5512,8 @@ workfile);
memset (commitpt->text, 0, sizeof (Deltatext));
bufsize = 0;
- switch (diff_exec (workfile, tmpfile, NULL, NULL, diffopts, changefile))
+ switch (diff_exec (workfile, tmpfile, NULL, NULL,
+ dargc, dargv, changefile))
{
case 0:
case 1:
@@ -5456,7 +5561,8 @@ workfile);
/* This file is not being inserted at the head, but on a side
branch somewhere. Make a diff from the previous revision
to the working file. */
- switch (diff_exec (tmpfile, workfile, NULL, NULL, diffopts, changefile))
+ switch (diff_exec (tmpfile, workfile, NULL, NULL,
+ dargc, dargv, changefile))
{
case 0:
case 1:
@@ -5483,6 +5589,9 @@ workfile);
}
}
+ run_arg_free_p (dargc, dargv);
+ free (dargv);
+
/* Update DELTA linkage. It is important not to do this before
the very end of RCS_checkin; if an error arises that forces
us to abort checking in, we must not have malformed deltas
@@ -5555,7 +5664,13 @@ workfile);
freedeltatext (dtext);
if (status != 0)
+ {
+ /* If delta has not been added to a List, then freeing the Node key
+ * won't free delta->version.
+ */
+ if (delta->version) free (delta->version);
free_rcsvers_contents (delta);
+ }
return status;
}
@@ -6257,7 +6372,12 @@ RCS_delete_revs (rcs, tag1, tag2, inclusive)
/* A range consisting of a branch number means the latest revision
on that branch. */
if (RCS_isbranch (rcs, rev1) && STREQ (rev1, rev2))
- rev1 = rev2 = RCS_getbranch (rcs, rev1, 0);
+ {
+ char *tmp = RCS_getbranch (rcs, rev1, 0);
+ free (rev1);
+ free (rev2);
+ rev1 = rev2 = tmp;
+ }
else
{
/* Make sure REV1 and REV2 are ordered correctly (in the
@@ -6545,6 +6665,10 @@ RCS_delete_revs (rcs, tag1, tag2, inclusive)
}
else
{
+ int dargc = 0;
+ size_t darg_allocated = 0;
+ char **dargv = NULL;
+
beforefile = cvs_temp_name();
status = RCS_checkout (rcs, NULL, before, NULL, "-ko", beforefile,
(RCSCHECKOUTPROC)0, NULL);
@@ -6552,7 +6676,12 @@ RCS_delete_revs (rcs, tag1, tag2, inclusive)
goto delrev_done;
outfile = cvs_temp_name();
- status = diff_exec (beforefile, afterfile, NULL, NULL, "-an", outfile);
+ run_add_arg_p (&dargc, &darg_allocated, &dargv, "-a");
+ run_add_arg_p (&dargc, &darg_allocated, &dargv, "-n");
+ status = diff_exec (beforefile, afterfile, NULL, NULL,
+ dargc, dargv, outfile);
+ run_arg_free_p (dargc, dargv);
+ free (dargv);
if (status == 2)
{
@@ -6650,7 +6779,7 @@ RCS_delete_revs (rcs, tag1, tag2, inclusive)
delrev_done:
if (rev1 != NULL)
free (rev1);
- if (rev2 != NULL)
+ if (rev2 && rev2 != rev1)
free (rev2);
if (branchpoint != NULL)
free (branchpoint);
@@ -7011,6 +7140,7 @@ apply_rcs_changes (lines, diffbuf, difflen, name, addvers, delvers)
};
struct deltafrag *dfhead;
struct deltafrag *df;
+ int err;
dfhead = NULL;
for (p = diffbuf; p != NULL && p < diffbuf + difflen; )
@@ -7076,33 +7206,39 @@ apply_rcs_changes (lines, diffbuf, difflen, name, addvers, delvers)
}
}
+ err = 0;
for (df = dfhead; df != NULL;)
{
unsigned int ln;
- switch (df->type)
- {
- case FRAG_ADD:
- if (! linevector_add (lines, df->new_lines, df->len, addvers,
- df->pos))
- return 0;
- break;
- case FRAG_DELETE:
- if (df->pos > lines->nlines
- || df->pos + df->nlines > lines->nlines)
- return 0;
- if (delvers != NULL)
- for (ln = df->pos; ln < df->pos + df->nlines; ++ln)
- lines->vector[ln]->vers = delvers;
- linevector_delete (lines, df->pos, df->nlines);
- break;
- }
+ /* Once an error is encountered, just free the rest of the list and
+ * return.
+ */
+ if (!err)
+ switch (df->type)
+ {
+ case FRAG_ADD:
+ if (! linevector_add (lines, df->new_lines, df->len, addvers,
+ df->pos))
+ err = 1;
+ break;
+ case FRAG_DELETE:
+ if (df->pos > lines->nlines
+ || df->pos + df->nlines > lines->nlines)
+ return 0;
+ if (delvers != NULL)
+ for (ln = df->pos; ln < df->pos + df->nlines; ++ln)
+ lines->vector[ln]->vers = delvers;
+ linevector_delete (lines, df->pos, df->nlines);
+ break;
+ }
+
df = df->next;
free (dfhead);
dfhead = df;
}
- return 1;
+ return !err;
}
/* Apply an RCS change text to a buffer. The function name starts
@@ -7220,12 +7356,18 @@ RCS_deltas (rcs, fp, rcsbuf, version, op, text, len, log, loglen)
struct linevector trunklines;
int foundhead;
+ assert (version);
+
if (fp == NULL)
{
rcsbuf_cache_open (rcs, rcs->delta_pos, &fp, &rcsbuf_local);
rcsbuf = &rcsbuf_local;
}
+ assert (rcsbuf);
+
+ if (log) *log = NULL;
+
ishead = 1;
vers = NULL;
prev_vers = NULL;
@@ -7253,6 +7395,13 @@ RCS_deltas (rcs, fp, rcsbuf, version, op, text, len, log, loglen)
if (! rcsbuf_getrevnum (rcsbuf, &key))
error (1, 0, "unexpected EOF reading RCS file %s", rcs->path);
+ /* look up the revision */
+ node = findnode (rcs->versions, key);
+ if (!node)
+ error (1, 0,
+ "Delta text %s without revision information in `%s'.",
+ key, rcs->path);
+
if (next != NULL && ! STREQ (next, key))
{
/* This is not the next version we need. It is a branch
@@ -7264,13 +7413,6 @@ RCS_deltas (rcs, fp, rcsbuf, version, op, text, len, log, loglen)
{
isnext = 1;
- /* look up the revision */
- node = findnode (rcs->versions, key);
- if (node == NULL)
- error (1, 0,
- "mismatch in rcs file %s between deltas and deltatexts (%s)",
- rcs->path, key);
-
/* Stash the previous version. */
prev_vers = vers;
@@ -7296,6 +7438,12 @@ RCS_deltas (rcs, fp, rcsbuf, version, op, text, len, log, loglen)
&& STREQ (key, "log")
&& STREQ (branchversion, version))
{
+ if (*log != NULL)
+ {
+ error (0, 0, "Duplicate `log' keyword in RCS file (`%s').",
+ rcs->path);
+ free (*log);
+ }
*log = rcsbuf_valcopy (rcsbuf, value, 0, loglen);
}
@@ -7377,6 +7525,9 @@ RCS_deltas (rcs, fp, rcsbuf, version, op, text, len, log, loglen)
if (vers->branches == NULL)
error (1, 0, "missing expected branches in %s",
rcs->path);
+ if (!cpversion)
+ error (1, 0, "Invalid revision number in `%s'.",
+ rcs->path);
*cpversion = '.';
++cpversion;
cpversion = strchr (cpversion, '.');
@@ -7421,7 +7572,7 @@ RCS_deltas (rcs, fp, rcsbuf, version, op, text, len, log, loglen)
for (ln = 0; ln < headlines.nlines; ++ln)
{
- char buf[80];
+ char *buf;
/* Period which separates year from month in date. */
char *ym;
/* Period which separates month from day in date. */
@@ -7432,10 +7583,12 @@ RCS_deltas (rcs, fp, rcsbuf, version, op, text, len, log, loglen)
if (prvers == NULL)
prvers = vers;
+ buf = xmalloc (strlen (prvers->version) + 24);
sprintf (buf, "%-12s (%-8.8s ",
prvers->version,
prvers->author);
cvs_output (buf, 0);
+ free (buf);
/* Now output the date. */
ym = strchr (prvers->date, '.');
@@ -7760,9 +7913,10 @@ 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 (%s)",
- rcs->path, num);
+ if (!p)
+ error (1, 0,
+ "Delta text %s without revision information in `%s'.",
+ num, rcs->path);
d = (Deltatext *) xmalloc (sizeof (Deltatext));
d->version = xstrdup (num);
@@ -8027,31 +8181,65 @@ RCS_putdtree (rcs, rev, fp)
RCSVers *versp;
Node *p, *branch;
+ /* Previously, this function used a recursive implementation, but
+ if the trunk has a huge number of revisions and the program
+ stack is not big, a stack overflow could occur, so this
+ nonrecursive version was developed to be more safe. */
+ Node *branchlist, *onebranch;
+ List *branches;
+ List *onebranchlist;
+
if (rev == NULL)
return;
- /* Find the delta node for this revision. */
- p = findnode (rcs->versions, rev);
- if (p == NULL)
+ branches = getlist();
+
+ for (; rev != NULL;)
{
- error (1, 0,
- "error parsing repository file %s, file may be corrupt.",
- rcs->path);
- }
+ /* Find the delta node for this revision. */
+ p = findnode (rcs->versions, rev);
+ if (p == NULL)
+ {
+ error (1, 0,
+ "error parsing repository file %s, file may be corrupt.",
+ rcs->path);
+ }
- versp = p->data;
+ versp = p->data;
+
+ /* Print the delta node and go for its `next' node. This
+ prints the trunk. If there are any branches printed on this
+ revision, mark we have some. */
+ putdelta (versp, fp);
+ /* Store branch information into branch list so to write its
+ trunk afterwards */
+ if (versp->branches != NULL)
+ {
+ branch = getnode();
+ branch->data = versp->branches;
+
+ addnode(branches, branch);
+ }
+
+ rev = versp->next;
+ }
- /* Print the delta node and recurse on its `next' node. This prints
- the trunk. If there are any branches printed on this revision,
+ /* If there are any branches printed on this revision,
print those trunks as well. */
- putdelta (versp, fp);
- RCS_putdtree (rcs, versp->next, fp);
- if (versp->branches != NULL)
- {
- branch = versp->branches->list;
- for (p = branch->next; p != branch; p = p->next)
+ branchlist = branches->list;
+ for (branch = branchlist->next;
+ branch != branchlist;
+ branch = branch->next)
+ {
+ onebranchlist = (List *)(branch->data);
+ onebranch = onebranchlist->list;
+ for (p = onebranch->next; p != onebranch; p = p->next)
RCS_putdtree (rcs, p->key, fp);
+
+ branch->data = NULL; /* so to prevent its freeing on dellist */
}
+
+ dellist(&branches);
}
static void
@@ -8156,6 +8344,11 @@ RCS_copydeltas (rcs, fin, rcsbufin, fout, newdtext, insertpt)
}
np = findnode (rcs->versions, dtext->version);
+ if (!np)
+ error (1, 0,
+ "Delta text %s without revision information in `%s'.",
+ dtext->version, rcs->path);
+
dadmin = np->data;
/* If this revision has been outdated, just skip it. */
@@ -8443,6 +8636,28 @@ rcs_internal_unlockfile (fp, rcsfile)
real solution is to check each call to fprintf rather than waiting
until the end like this. */
error (1, errno, "error writing to lock file %s", rcs_lockfile);
+
+ /* Flush and sync the file, or the user may be told the commit completed,
+ * while a server crash/power failure could still cause the data to be
+ * lost.
+ *
+ * Invoking rename(",<file>," , "<file>,v") on Linux and almost all UNIXs
+ * only flushes the inode for the target file to disk, it does not
+ * guarantee flush of the kernel buffers allocated for the ,<file>,.
+ * Depending upon the load on the machine, the Linux kernel's flush daemon
+ * process may not flush for a while. In the meantime the CVS transaction
+ * could have been declared committed to the end CVS user (CVS process has
+ * returned the final "OK"). If the machine crashes prior to syncing the
+ * changes to disk, the committed transaction can be lost.
+ */
+ if (fflush (fp) != 0)
+ error (1, errno, "error flushing file `%s' to kernel buffers",
+ rcs_lockfile);
+#ifdef HAVE_FSYNC
+ if (fsync (rcs_lockfd) < 0)
+ error (1, errno, "error fsyncing file `%s'", rcs_lockfile);
+#endif
+
if (fclose (fp) == EOF)
error (1, errno, "error closing lock file %s", rcs_lockfile);
rcs_lockfd = -1;
@@ -8497,6 +8712,8 @@ RCS_rewrite (rcs, newdtext, insertpt)
FILE *fin, *fout;
struct rcsbuffer rcsbufin;
+ assert (rcs);
+
if (noexec)
return;
diff --git a/contrib/cvs/src/rcs.h b/contrib/cvs/src/rcs.h
index 4a6d2a5..3a66640 100644
--- a/contrib/cvs/src/rcs.h
+++ b/contrib/cvs/src/rcs.h
@@ -1,6 +1,11 @@
/*
- * Copyright (c) 1992, Brian Berliner and Jeff Polk
- * Copyright (c) 1989-1992, Brian Berliner
+ * Copyright (C) 1986-2005 The Free Software Foundation, Inc.
+ *
+ * Portions Copyright (C) 1998-2005 Derek Price, Ximbiot <http://ximbiot.com>,
+ * and others.
+ *
+ * Portions Copyright (C) 1992, Brian Berliner and Jeff Polk
+ * Portions Copyright (C) 1989-1992, Brian Berliner
*
* You may distribute under the terms of the GNU General Public License as
* specified in the README file that comes with the CVS source distribution.
@@ -224,7 +229,8 @@ void RCS_setexpand PROTO ((RCSNode *, const char *));
int RCS_checkout PROTO ((RCSNode *, const char *, const char *, const char *,
const char *, const char *, RCSCHECKOUTPROC, void *));
int RCS_checkin PROTO ((RCSNode *rcs, const char *workfile,
- const char *message, const char *rev, int flags));
+ const char *message, const char *rev, time_t citime,
+ int flags));
int RCS_cmp_file PROTO((RCSNode *, const char *, char **, const char *,
const char *, const char *));
int RCS_settag PROTO ((RCSNode *, const char *, const char *));
diff --git a/contrib/cvs/src/rcscmds.c b/contrib/cvs/src/rcscmds.c
index 52e3a9a..a9e576a 100644
--- a/contrib/cvs/src/rcscmds.c
+++ b/contrib/cvs/src/rcscmds.c
@@ -1,6 +1,11 @@
/*
- * Copyright (c) 1992, Brian Berliner and Jeff Polk
- * Copyright (c) 1989-1992, Brian Berliner
+ * Copyright (C) 1986-2005 The Free Software Foundation, Inc.
+ *
+ * Portions Copyright (C) 1998-2005 Derek Price, Ximbiot <http://ximbiot.com>,
+ * and others.
+ *
+ * Portions Copyright (C) 1992, Brian Berliner and Jeff Polk
+ * Portions Copyright (C) 1989-1992, Brian Berliner
*
* You may distribute under the terms of the GNU General Public License as
* specified in the README file that comes with the CVS source distribution.
@@ -51,8 +56,8 @@
On a related note, see the comments at diff_exec, later in this file,
for more on the diff library. */
-static void RCS_output_diff_options PROTO ((const char *, const char *,
- const char *, const char *));
+static void RCS_output_diff_options PROTO ((int, char *const *, const char *,
+ const char *, const char *));
/* Stuff to deal with passing arguments the way libdiff.a wants to deal
@@ -64,17 +69,18 @@ static void RCS_output_diff_options PROTO ((const char *, const char *,
argument will be parsed into whitespace separated words and added
to the global call_diff_argv list.
- Then, optionally, call call_diff_arg for each additional argument
+ Then, optionally, call call_diff_add_arg for each additional argument
that you'd like to pass to the diff library.
Finally, call call_diff or call_diff3 to produce the diffs. */
static char **call_diff_argv;
static int call_diff_argc;
-static int call_diff_argc_allocated;
+static size_t call_diff_argc_allocated;
static void call_diff_add_arg PROTO ((const char *));
-static void call_diff_setup PROTO ((const char *prog));
+static void call_diff_setup PROTO ((const char *prog,
+ int argc, char * const *argv));
static int call_diff PROTO ((const char *out));
static int call_diff3 PROTO ((char *out));
@@ -83,62 +89,37 @@ static void call_diff_flush_output PROTO((void));
static void call_diff_write_stdout PROTO((const char *));
static void call_diff_error PROTO((const char *, const char *, const char *));
+
+
+static void
+call_diff_add_arg (s)
+ const char *s;
+{
+ run_add_arg_p (&call_diff_argc, &call_diff_argc_allocated, &call_diff_argv,
+ s);
+}
+
+
+
/* VARARGS */
static void
-call_diff_setup (prog)
+call_diff_setup (prog, argc, argv)
const char *prog;
+ int argc;
+ char * const *argv;
{
- char *cp;
int i;
- char *call_diff_prog;
/* clean out any malloc'ed values from call_diff_argv */
- for (i = 0; i < call_diff_argc; i++)
- {
- if (call_diff_argv[i])
- {
- free (call_diff_argv[i]);
- call_diff_argv[i] = (char *) 0;
- }
- }
+ run_arg_free_p (call_diff_argc, call_diff_argv);
call_diff_argc = 0;
- call_diff_prog = xstrdup (prog);
-
/* put each word into call_diff_argv, allocating it as we go */
- for (cp = strtok (call_diff_prog, " \t");
- cp != NULL;
- cp = strtok ((char *) NULL, " \t"))
- call_diff_add_arg (cp);
- free (call_diff_prog);
-}
-
-static void
-call_diff_arg (s)
- const char *s;
-{
- call_diff_add_arg (s);
+ call_diff_add_arg (prog);
+ for (i = 0; i < argc; i++)
+ call_diff_add_arg (argv[i]);
}
-static void
-call_diff_add_arg (s)
- const char *s;
-{
- /* allocate more argv entries if we've run out */
- if (call_diff_argc >= call_diff_argc_allocated)
- {
- call_diff_argc_allocated += 50;
- call_diff_argv = (char **)
- xrealloc ((char *) call_diff_argv,
- call_diff_argc_allocated * sizeof (char **));
- }
-
- if (s)
- call_diff_argv[call_diff_argc++] = xstrdup (s);
- else
- /* Not post-incremented on purpose! */
- call_diff_argv[call_diff_argc] = (char *) 0;
-}
/* Callback function for the diff library to write data to the output
file. This is used when we are producing output to stdout. */
@@ -211,6 +192,8 @@ static int
call_diff (out)
const char *out;
{
+ call_diff_add_arg (NULL);
+
if (out == RUN_TTY)
return diff_run (call_diff_argc, call_diff_argv, NULL,
&call_diff_stdout_callbacks);
@@ -262,6 +245,7 @@ RCS_merge(rcs, path, workfile, options, rev1, rev2)
symbolic). */
xrev1 = RCS_gettag (rcs, rev1, 0, NULL);
xrev2 = RCS_gettag (rcs, rev2, 0, NULL);
+ assert (xrev1 && xrev2);
/* Check out chosen revisions. The error message when RCS_checkout
fails is not very informative -- it is taken verbatim from RCS 5.7,
@@ -302,21 +286,21 @@ RCS_merge(rcs, path, workfile, options, rev1, rev2)
/* Remember that the first word in the `call_diff_setup' string is used now
only for diagnostic messages -- CVS no longer forks to run diff3. */
diffout = cvs_temp_name();
- call_diff_setup ("diff3");
- call_diff_arg ("-E");
- call_diff_arg ("-am");
-
- call_diff_arg ("-L");
- call_diff_arg (workfile);
- call_diff_arg ("-L");
- call_diff_arg (xrev1);
- call_diff_arg ("-L");
- call_diff_arg (xrev2);
-
- call_diff_arg ("--");
- call_diff_arg (workfile);
- call_diff_arg (tmp1);
- call_diff_arg (tmp2);
+ call_diff_setup ("diff3", 0, NULL);
+ call_diff_add_arg ("-E");
+ call_diff_add_arg ("-am");
+
+ call_diff_add_arg ("-L");
+ call_diff_add_arg (workfile);
+ call_diff_add_arg ("-L");
+ call_diff_add_arg (xrev1);
+ call_diff_add_arg ("-L");
+ call_diff_add_arg (xrev2);
+
+ call_diff_add_arg ("--");
+ call_diff_add_arg (workfile);
+ call_diff_add_arg (tmp1);
+ call_diff_add_arg (tmp2);
retval = call_diff3 (diffout);
@@ -382,10 +366,11 @@ RCS_merge(rcs, path, workfile, options, rev1, rev2)
about this--any such features are undocumented in the context of
CVS, and I'm not sure how important to users. */
int
-RCS_exec_rcsdiff(rcsfile, opts, options, rev1, rev1_cache, rev2,
- label1, label2, workfile )
+RCS_exec_rcsdiff (rcsfile, diff_argc, diff_argv, options, rev1, rev1_cache,
+ rev2, label1, label2, workfile)
RCSNode *rcsfile;
- const char *opts;
+ int diff_argc;
+ char * const *diff_argv;
const char *options;
const char *rev1;
const char *rev1_cache;
@@ -465,8 +450,9 @@ RCS file: ", 0);
use_file2 = tmpfile2;
}
- RCS_output_diff_options (opts, rev1, rev2, workfile);
- status = diff_exec( use_file1, use_file2, label1, label2, opts, RUN_TTY );
+ RCS_output_diff_options (diff_argc, diff_argv, rev1, rev2, workfile);
+ status = diff_exec (use_file1, use_file2, label1, label2,
+ diff_argc, diff_argv, RUN_TTY);
if (status >= 0)
{
retval = status;
@@ -545,16 +531,15 @@ RCS file: ", 0);
message on stderr. */
int
-diff_exec (file1, file2, label1, label2, options, out)
+diff_exec (file1, file2, label1, label2, dargc, dargv, out)
const char *file1;
const char *file2;
const char *label1;
const char *label2;
- const char *options;
+ int dargc;
+ char * const *dargv;
const char *out;
{
- char *args;
-
#ifdef PRESERVE_PERMISSIONS_SUPPORT
/* If either file1 or file2 are special files, pretend they are
/dev/null. Reason: suppose a file that represents a block
@@ -588,18 +573,15 @@ diff_exec (file1, file2, label1, label2, options, out)
}
#endif
- args = xmalloc (strlen (options) + 10);
- /* The first word in this string is used only for error reporting. */
- sprintf (args, "diff %s", options);
- call_diff_setup (args);
+ /* The first arg to call_diff_setup is used only for error reporting. */
+ call_diff_setup ("diff", dargc, dargv);
if (label1)
- call_diff_arg (label1);
+ call_diff_add_arg (label1);
if (label2)
- call_diff_arg (label2);
- call_diff_arg ("--");
- call_diff_arg (file1);
- call_diff_arg (file2);
- free (args);
+ call_diff_add_arg (label2);
+ call_diff_add_arg ("--");
+ call_diff_add_arg (file1);
+ call_diff_add_arg (file2);
return call_diff (out);
}
@@ -611,19 +593,23 @@ diff_exec (file1, file2, label1, label2, options, out)
that I have seen. */
static void
-RCS_output_diff_options (opts, rev1, rev2, workfile)
- const char *opts;
+RCS_output_diff_options (diff_argc, diff_argv, rev1, rev2, workfile)
+ int diff_argc;
+ char * const *diff_argv;
const char *rev1;
const char *rev2;
const char *workfile;
{
- char *tmp;
-
- tmp = (char *) xmalloc (strlen (opts) + strlen (rev1) + 10);
-
- sprintf (tmp, "diff%s -r%s", opts, rev1);
- cvs_output (tmp, 0);
- free (tmp);
+ int i;
+
+ cvs_output ("diff", 0);
+ for (i = 0; i < diff_argc; i++)
+ {
+ cvs_output (" ", 1);
+ cvs_output (diff_argv[i], 0);
+ }
+ cvs_output (" -r", 3);
+ cvs_output (rev1, 0);
if (rev2)
{
diff --git a/contrib/cvs/src/recurse.c b/contrib/cvs/src/recurse.c
index b807e2d..2416861 100644
--- a/contrib/cvs/src/recurse.c
+++ b/contrib/cvs/src/recurse.c
@@ -1,5 +1,11 @@
/*
- * Copyright (c) 1992, Brian Berliner and Jeff Polk
+ * Copyright (C) 1986-2005 The Free Software Foundation, Inc.
+ *
+ * Portions Copyright (C) 1998-2005 Derek Price, Ximbiot <http://ximbiot.com>,
+ * and others.
+ *
+ * Portions Copyright (C) 1992, Brian Berliner and Jeff Polk
+ * Portions Copyright (C) 1989-1992, Brian Berliner
*
* You may distribute under the terms of the GNU General Public License as
* specified in the README file that comes with the CVS source distribution.
@@ -134,6 +140,25 @@ start_recursion (fileproc, filesdoneproc, direntproc, dirleaveproc, callerdat,
frame.aflag = aflag;
frame.locktype = locktype;
frame.dosrcs = dosrcs;
+
+ /* If our repository_in has a trailing "/.", remove it before storing it
+ * for do_recursion().
+ *
+ * FIXME: This is somewhat of a hack in the sense that many of our callers
+ * painstakingly compute and add the trailing '.' we now remove.
+ */
+ while (repository_in && strlen (repository_in) >= 2
+ && repository_in[strlen (repository_in) - 2] == '/'
+ && repository_in[strlen (repository_in) - 1] == '.')
+ {
+ /* Beware the case where the string is exactly "/." or "//.".
+ * Paths with a leading "//" are special on some early UNIXes.
+ */
+ if (strlen (repository_in) == 2 || strlen (repository_in) == 3)
+ repository_in[strlen (repository_in) - 1] = '\0';
+ else
+ repository_in[strlen (repository_in) - 2] = '\0';
+ }
frame.repository = repository_in;
expand_wild (argc, argv, &argc, &argv);
@@ -171,21 +196,24 @@ start_recursion (fileproc, filesdoneproc, direntproc, dirleaveproc, callerdat,
&& CVSroot_cmdline == NULL
&& current_parsed_root->isremote)
{
- char *root = Name_Root (NULL, update_dir);
- if (root && strcmp (root, current_parsed_root->original) != 0)
- /* We're skipping this directory because it is for
- a different root. Therefore, we just want to
- do the subdirectories only. Processing files would
- cause a working directory from one repository to be
- processed against a different repository, which could
- cause all kinds of spurious conflicts and such.
-
- Question: what about the case of "cvs update foo"
- where we process foo/bar and not foo itself? That
- seems to be handled somewhere (else) but why should
- it be a separate case? Needs investigation... */
- just_subdirs = 1;
- free (root);
+ cvsroot_t *root = Name_Root (NULL, update_dir);
+ if (root)
+ {
+ if (strcmp (root->original, current_parsed_root->original))
+ /* We're skipping this directory because it is for
+ * a different root. Therefore, we just want to
+ * do the subdirectories only. Processing files would
+ * cause a working directory from one repository to be
+ * processed against a different repository, which could
+ * cause all kinds of spurious conflicts and such.
+ *
+ * Question: what about the case of "cvs update foo"
+ * where we process foo/bar and not foo itself? That
+ * seems to be handled somewhere (else) but why should
+ * it be a separate case? Needs investigation... */
+ just_subdirs = 1;
+ free_cvsroot_t (root);
+ }
}
#endif
@@ -306,11 +334,8 @@ start_recursion (fileproc, filesdoneproc, direntproc, dirleaveproc, callerdat,
addfile (&files_by_dir, dir, comp);
else if (isdir (dir))
{
- if ((which & W_LOCAL) && isdir (CVSADM)
-#ifdef CLIENT_SUPPORT
- && !current_parsed_root->isremote
-#endif
- )
+ if ((which & W_LOCAL) && isdir (CVSADM) &&
+ !current_parsed_root->isremote)
{
/* otherwise, look for it in the repository. */
char *tmp_update_dir;
@@ -566,7 +591,7 @@ do_recursion (frame)
* generating data, to give the buffers a chance to drain to the
* remote client. We should not have locks active at this point,
* but if there are writelocks around, we cannot pause here. */
- if (server_active && locktype != CVS_LOCK_NONE)
+ if (server_active && locktype != CVS_LOCK_WRITE)
server_pause_check();
#endif
@@ -582,43 +607,41 @@ do_recursion (frame)
directories, since we're guaranteed to have only one CVSROOT --
our own. */
- if (
- /* If -d was specified, it should override CVS/Root.
-
- In the single-repository case, it is long-standing CVS behavior
- and makes sense - the user might want another access method,
- another server (which mounts the same repository), &c.
+ /* If -d was specified, it should override CVS/Root.
- In the multiple-repository case, -d overrides all CVS/Root
- files. That is the only plausible generalization I can
- think of. */
- CVSroot_cmdline == NULL
+ In the single-repository case, it is long-standing CVS behavior
+ and makes sense - the user might want another access method,
+ another server (which mounts the same repository), &c.
-#ifdef SERVER_SUPPORT
- && ! server_active
-#endif
- )
+ In the multiple-repository case, -d overrides all CVS/Root
+ files. That is the only plausible generalization I can
+ think of. */
+ if (CVSroot_cmdline == NULL && !server_active)
{
- char *this_root = Name_Root ((char *) NULL, update_dir);
+ cvsroot_t *this_root = Name_Root ((char *) NULL, update_dir);
if (this_root != NULL)
{
- if (findnode (root_directories, this_root) == NULL)
+ if (findnode (root_directories, this_root->original))
+ {
+ process_this_directory = !strcmp (current_parsed_root->original,
+ this_root->original);
+ free_cvsroot_t (this_root);
+ }
+ else
{
/* Add it to our list. */
Node *n = getnode ();
n->type = NT_UNKNOWN;
- n->key = xstrdup (this_root);
+ n->key = xstrdup (this_root->original);
+ n->data = this_root;
if (addnode (root_directories, n))
- error (1, 0, "cannot add new CVSROOT %s", this_root);
-
- }
-
- process_this_directory =
- (strcmp (current_parsed_root->original, this_root) == 0);
+ error (1, 0, "cannot add new CVSROOT %s",
+ this_root->original);
- free (this_root);
+ process_this_directory = 0;
+ }
}
}
@@ -681,7 +704,8 @@ do_recursion (frame)
if (repository == NULL)
{
Name_Repository ((char *) NULL, update_dir);
- assert (!"Not reached. Please report this problem to <bug-cvs@gnu.org>");
+ assert (!"Not reached. Please report this problem to <"
+ PACKAGE_BUGREPORT ">");
}
/* find the files and fill in entries if appropriate */
@@ -1030,42 +1054,41 @@ but CVS uses %s for its own purposes; skipping %s directory",
/* Only process this directory if the root matches. This nearly
duplicates code in do_recursion. */
- if (
- /* If -d was specified, it should override CVS/Root.
-
- In the single-repository case, it is long-standing CVS behavior
- and makes sense - the user might want another access method,
- another server (which mounts the same repository), &c.
+ /* If -d was specified, it should override CVS/Root.
- In the multiple-repository case, -d overrides all CVS/Root
- files. That is the only plausible generalization I can
- think of. */
- CVSroot_cmdline == NULL
+ In the single-repository case, it is long-standing CVS behavior
+ and makes sense - the user might want another access method,
+ another server (which mounts the same repository), &c.
-#ifdef SERVER_SUPPORT
- && ! server_active
-#endif
- )
+ In the multiple-repository case, -d overrides all CVS/Root
+ files. That is the only plausible generalization I can
+ think of. */
+ if (CVSroot_cmdline == NULL && !server_active)
{
- char *this_root = Name_Root (dir, update_dir);
+ cvsroot_t *this_root = Name_Root (dir, update_dir);
if (this_root != NULL)
{
- if (findnode (root_directories, this_root) == NULL)
+ if (findnode (root_directories, this_root->original))
+ {
+ process_this_directory = !strcmp (current_parsed_root->original,
+ this_root->original);
+ free_cvsroot_t (this_root);
+ }
+ else
{
/* Add it to our list. */
Node *n = getnode ();
n->type = NT_UNKNOWN;
- n->key = xstrdup (this_root);
+ n->key = xstrdup (this_root->original);
+ n->data = this_root;
if (addnode (root_directories, n))
- error (1, 0, "cannot add new CVSROOT %s", this_root);
+ error (1, 0, "cannot add new CVSROOT %s",
+ this_root->original);
+ process_this_directory = 0;
}
-
- process_this_directory = (strcmp (current_parsed_root->original, this_root) == 0);
-
- free (this_root);
}
}
diff --git a/contrib/cvs/src/release.c b/contrib/cvs/src/release.c
index 2d8c72c..27a16c0 100644
--- a/contrib/cvs/src/release.c
+++ b/contrib/cvs/src/release.c
@@ -1,4 +1,18 @@
/*
+ * Copyright (C) 1994-2005 The Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/*
* Release: "cancel" a checkout in the history log.
*
* - Enter a line in the history log indicating the "release". - If asked to,
@@ -67,7 +81,6 @@ release (argc, argv)
{
FILE *fp;
int i, c;
- char *repository;
char *line = NULL;
size_t line_allocated = 0;
char *update_cmd;
@@ -124,8 +137,12 @@ release (argc, argv)
+ 1 + 3 + 3 + 16 + 1);
sprintf (update_cmd, "%s %s%s-n -q -d %s update",
program_path,
+#if defined (CLIENT_SUPPORT) || defined (SERVER_SUPPORT)
cvsauthenticate ? "-a " : "",
cvsencrypt ? "-x " : "",
+#else
+ "", "",
+#endif
current_parsed_root->original);
#ifdef CLIENT_SUPPORT
@@ -173,11 +190,9 @@ release (argc, argv)
continue;
}
- repository = Name_Repository ((char *) NULL, (char *) NULL);
-
if (!really_quiet)
{
- int line_length;
+ int line_length, status;
/* The "release" command piggybacks on "update", which
does the real work of finding out if anything is not
@@ -204,10 +219,10 @@ release (argc, argv)
complain and go on to the next arg. Especially, we do
not want to delete the local copy, since it's obviously
not what the user thinks it is. */
- if ((pclose (fp)) != 0)
+ status = pclose (fp);
+ if (status != 0)
{
- error (0, 0, "unable to release `%s'", thisarg);
- free (repository);
+ error (0, 0, "unable to release `%s' (%d)", thisarg, status);
if (restore_cwd (&cwd, NULL))
error_exit ();
continue;
@@ -222,7 +237,6 @@ release (argc, argv)
{
(void) fprintf (stderr, "** `%s' aborted by user choice.\n",
cvs_cmd_name);
- free (repository);
if (restore_cwd (&cwd, NULL))
error_exit ();
continue;
@@ -236,9 +250,8 @@ release (argc, argv)
CVS/Entries file in the wrong directory. See release-17
through release-23. */
- free (repository);
if (restore_cwd (&cwd, NULL))
- exit (EXIT_FAILURE);
+ error_exit ();
if (1
#ifdef CLIENT_SUPPORT
@@ -255,7 +268,7 @@ release (argc, argv)
argv[2] = NULL;
err += unedit (argc, argv);
if (restore_cwd (&cwd, NULL))
- exit (EXIT_FAILURE);
+ error_exit ();
}
#ifdef CLIENT_SUPPORT
@@ -293,7 +306,7 @@ release (argc, argv)
err += get_server_responses ();
if (restore_cwd (&cwd, NULL))
- exit (EXIT_FAILURE);
+ error_exit ();
}
#endif /* CLIENT_SUPPORT */
}
diff --git a/contrib/cvs/src/remove.c b/contrib/cvs/src/remove.c
index 2a3545a..a09cfd4 100644
--- a/contrib/cvs/src/remove.c
+++ b/contrib/cvs/src/remove.c
@@ -1,6 +1,11 @@
/*
- * Copyright (c) 1992, Brian Berliner and Jeff Polk
- * Copyright (c) 1989-1992, Brian Berliner
+ * Copyright (C) 1986-2005 The Free Software Foundation, Inc.
+ *
+ * Portions Copyright (C) 1998-2005 Derek Price, Ximbiot <http://ximbiot.com>,
+ * and others.
+ *
+ * Portions Copyright (C) 1992, Brian Berliner and Jeff Polk
+ * Portions Copyright (C) 1989-1992, Brian Berliner
*
* You may distribute under the terms of the GNU General Public License as
* specified in the README file that comes with the CVS source distribution.
diff --git a/contrib/cvs/src/repos.c b/contrib/cvs/src/repos.c
index 2c7a3bc..202d92d 100644
--- a/contrib/cvs/src/repos.c
+++ b/contrib/cvs/src/repos.c
@@ -1,6 +1,11 @@
/*
- * Copyright (c) 1992, Brian Berliner and Jeff Polk
- * Copyright (c) 1989-1992, Brian Berliner
+ * Copyright (C) 1986-2005 The Free Software Foundation, Inc.
+ *
+ * Portions Copyright (C) 1998-2005 Derek Price, Ximbiot <http://ximbiot.com>,
+ * and others.
+ *
+ * Portions Copyright (C) 1992, Brian Berliner and Jeff Polk
+ * Portions Copyright (C) 1989-1992, Brian Berliner
*
* You may distribute under the terms of the GNU General Public License as
* specified in the README file that comes with the CVS source distribution.
diff --git a/contrib/cvs/src/root.c b/contrib/cvs/src/root.c
index 05aa0bd..8e2380f 100644
--- a/contrib/cvs/src/root.c
+++ b/contrib/cvs/src/root.c
@@ -1,6 +1,10 @@
/*
- * Copyright (c) 1992, Mark D. Baushke
- * Copyright (c) 2002, Derek R. Price
+ * Copyright (C) 1986-2005 The Free Software Foundation, Inc.
+ *
+ * Portions Copyright (C) 1998-2005 Derek Price, Ximbiot <http://ximbiot.com>,
+ * and others.
+ *
+ * Poritons Copyright (c) 1992, Mark D. Baushke
*
* You may distribute under the terms of the GNU General Public License as
* specified in the README file that comes with the CVS source distribution.
@@ -11,6 +15,7 @@
*/
#include "cvs.h"
+#include <assert.h>
#include "getline.h"
/* Printable names for things in the current_parsed_root->method enum variable.
@@ -18,18 +23,19 @@
const char method_names[][16] = {
"undefined", "local", "server (rsh)", "pserver",
- "kserver", "gserver", "ext", "fork"
+ "kserver", "gserver", "ext", "extssh", "fork"
};
#ifndef DEBUG
-char *
+cvsroot_t *
Name_Root (dir, update_dir)
- char *dir;
- char *update_dir;
+ const char *dir;
+ const char *update_dir;
{
FILE *fpin;
- char *ret, *xupdate_dir;
+ cvsroot_t *ret;
+ const char *xupdate_dir;
char *root = NULL;
size_t root_allocated = 0;
char *tmp;
@@ -87,7 +93,7 @@ Name_Root (dir, update_dir)
goto out;
}
fclose (fpin);
- cp = root + (len - 1);
+ cp = root + len - 1;
if (*cp == '\n')
*cp = '\0'; /* strip the newline */
@@ -96,43 +102,34 @@ Name_Root (dir, update_dir)
* absolute pathname or specify a remote server.
*/
- if (
-#ifdef CLIENT_SUPPORT
- (strchr (root, ':') == NULL) &&
-#endif
- ! isabsolute (root))
+ ret = parse_cvsroot (root);
+ if (ret == NULL)
{
error (0, 0, "in directory %s:", xupdate_dir);
error (0, 0,
- "ignoring %s because it does not contain an absolute pathname.",
+ "ignoring %s because it does not contain a valid root.",
CVSADM_ROOT);
- ret = NULL;
goto out;
}
-#ifdef CLIENT_SUPPORT
- if ((strchr (root, ':') == NULL) && !isdir (root))
-#else /* ! CLIENT_SUPPORT */
- if (!isdir (root))
-#endif /* CLIENT_SUPPORT */
+ if (!ret->isremote && !isdir (ret->directory))
{
error (0, 0, "in directory %s:", xupdate_dir);
error (0, 0,
"ignoring %s because it specifies a non-existent repository %s",
CVSADM_ROOT, root);
+ free_cvsroot_t (ret);
ret = NULL;
goto out;
}
- /* allocate space to return and fill it in */
- strip_trailing_slashes (root);
- ret = xstrdup (root);
+
out:
free (cvsadm);
free (tmp);
if (root != NULL)
free (root);
- return (ret);
+ return ret;
}
@@ -293,6 +290,7 @@ new_cvsroot_t ()
newroot->original = NULL;
newroot->method = null_method;
+ newroot->isremote = 0;
#ifdef CLIENT_SUPPORT
newroot->username = NULL;
newroot->password = NULL;
@@ -301,7 +299,6 @@ new_cvsroot_t ()
newroot->directory = NULL;
newroot->proxy_hostname = NULL;
newroot->proxy_port = 0;
- newroot->isremote = 0;
#endif /* CLIENT_SUPPORT */
return newroot;
@@ -376,6 +373,8 @@ parse_cvsroot (root_in)
int check_hostname, no_port, no_password;
#endif /* CLIENT_SUPPORT */
+ assert (root_in);
+
/* allocate some space */
newroot = new_cvsroot_t();
@@ -411,7 +410,7 @@ parse_cvsroot (root_in)
* We don't handle these, but we like to try and warn the user that
* they are being ignored.
*/
- if (p = strchr (method, ';'))
+ if ((p = strchr (method, ';')) != NULL)
{
*p++ = '\0';
if (!really_quiet)
@@ -457,10 +456,7 @@ parse_cvsroot (root_in)
: local_method);
}
-#ifdef CLIENT_SUPPORT
newroot->isremote = (newroot->method != local_method);
-#endif /* CLIENT_SUPPORT */
-
if ((newroot->method != local_method)
&& (newroot->method != fork_method))
@@ -743,6 +739,8 @@ normalize_cvsroot (root)
char *p, *hostname, *username;
char port_s[64];
+ assert (root && root->hostname && root->directory);
+
/* get the appropriate port string */
sprintf (port_s, "%d", get_cvs_port_number (root));
diff --git a/contrib/cvs/src/root.h b/contrib/cvs/src/root.h
index b812eef..b6edec4 100644
--- a/contrib/cvs/src/root.h
+++ b/contrib/cvs/src/root.h
@@ -1,7 +1,11 @@
/*
- * Copyright (c) 2001, Derek Price and others
- * Copyright (c) 1992, Brian Berliner and Jeff Polk
- * Copyright (c) 1989-1992, Brian Berliner
+ * Copyright (C) 1986-2005 The Free Software Foundation, Inc.
+ *
+ * Portions Copyright (C) 1998-2005 Derek Price, Ximbiot <http://ximbiot.com>,
+ * and others.
+ *
+ * Portions Copyright (C) 1992, Brian Berliner and Jeff Polk
+ * Portions 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.
@@ -18,6 +22,7 @@ typedef enum {
kserver_method,
gserver_method,
ext_method,
+ extssh_method,
fork_method
} CVSmethod;
extern const char method_names[][16]; /* change this in root.c if you change
@@ -27,6 +32,7 @@ typedef struct cvsroot_s {
char *original; /* The complete source CVSroot string. */
CVSmethod method; /* One of the enum values above. */
char *directory; /* The directory name. */
+ unsigned char isremote; /* Nonzero if we are doing remote access. */
#ifdef CLIENT_SUPPORT
char *username; /* The username or NULL if method == local. */
char *password; /* The password or NULL if method == local. */
@@ -37,6 +43,14 @@ typedef struct cvsroot_s {
* used.
*/
int proxy_port; /* The port of the proxy or zero, as above. */
- unsigned char isremote; /* Nonzero if we are doing remote access. */
#endif /* CLIENT_SUPPORT */
} cvsroot_t;
+
+cvsroot_t *Name_Root PROTO((const char *dir, const char *update_dir));
+void free_cvsroot_t PROTO((cvsroot_t *root_in));
+cvsroot_t *parse_cvsroot PROTO((const char *root));
+cvsroot_t *local_cvsroot PROTO((const char *dir));
+void Create_Root PROTO((const char *dir, const char *rootdir));
+void root_allow_add PROTO ((char *));
+void root_allow_free PROTO ((void));
+int root_allow_ok PROTO ((char *));
diff --git a/contrib/cvs/src/run.c b/contrib/cvs/src/run.c
index b03d683..98ae911 100644
--- a/contrib/cvs/src/run.c
+++ b/contrib/cvs/src/run.c
@@ -36,7 +36,19 @@ extern char *strtok ();
*/
static char **run_argv;
static int run_argc;
-static int run_argc_allocated;
+static size_t run_argc_allocated;
+
+
+
+void
+run_arg_free_p (int argc, char **argv)
+{
+ int i;
+ for (i = 0; i < argc; i++)
+ free (argv[i]);
+}
+
+
/* VARARGS */
void
@@ -44,18 +56,10 @@ run_setup (prog)
const char *prog;
{
char *cp;
- int i;
char *run_prog;
/* clean out any malloc'ed values from run_argv */
- for (i = 0; i < run_argc; i++)
- {
- if (run_argv[i])
- {
- free (run_argv[i]);
- run_argv[i] = (char *) 0;
- }
- }
+ run_arg_free_p (run_argc, run_argv);
run_argc = 0;
run_prog = xstrdup (prog);
@@ -73,22 +77,35 @@ run_arg (s)
run_add_arg (s);
}
-static void
-run_add_arg (s)
+
+
+void
+run_add_arg_p (iargc, iarg_allocated, iargv, s)
+ int *iargc;
+ size_t *iarg_allocated;
+ char ***iargv;
const char *s;
{
/* allocate more argv entries if we've run out */
- if (run_argc >= run_argc_allocated)
+ if (*iargc >= *iarg_allocated)
{
- run_argc_allocated += 50;
- run_argv = (char **) xrealloc ((char *) run_argv,
- run_argc_allocated * sizeof (char **));
+ *iarg_allocated += 50;
+ *iargv = xrealloc (*iargv, *iarg_allocated * sizeof (char **));
}
if (s)
- run_argv[run_argc++] = xstrdup (s);
+ (*iargv)[(*iargc)++] = xstrdup (s);
else
- run_argv[run_argc] = (char *) 0; /* not post-incremented on purpose! */
+ (*iargv)[*iargc] = NULL; /* not post-incremented on purpose! */
+}
+
+
+
+static void
+run_add_arg (s)
+ const char *s;
+{
+ run_add_arg_p (&run_argc, &run_argc_allocated, &run_argv, s);
}
@@ -400,11 +417,107 @@ run_popen (cmd, mode)
return (popen (cmd, mode));
}
+
+
+/* Work around an OpenSSH problem: it can put its standard file
+ descriptors into nonblocking mode, which will mess us up if we
+ share file descriptions with it. The simplest workaround is
+ to create an intervening process between OpenSSH and the
+ actual stderr. */
+
+static void
+work_around_openssh_glitch (void)
+{
+ pid_t pid;
+ int stderr_pipe[2];
+ struct stat sb;
+
+ /* Do nothing unless stderr is a file that is affected by
+ nonblocking mode. */
+ if (!(fstat (STDERR_FILENO, &sb) == 0
+ && (S_ISFIFO (sb.st_mode) || S_ISSOCK (sb.st_mode)
+ || S_ISCHR (sb.st_mode) || S_ISBLK (sb.st_mode))))
+ return;
+
+ if (pipe (stderr_pipe) < 0)
+ error (1, errno, "cannot create pipe");
+ pid = fork ();
+ if (pid < 0)
+ error (1, errno, "cannot fork");
+ if (pid != 0)
+ {
+ /* Still in child of original process. Act like "cat -u". */
+ char buf[1 << 13];
+ ssize_t inbytes;
+ pid_t w;
+ int status;
+
+ if (close (stderr_pipe[1]) < 0)
+ error (1, errno, "cannot close pipe");
+
+ while ((inbytes = read (stderr_pipe[0], buf, sizeof buf)) != 0)
+ {
+ size_t outbytes = 0;
+
+ if (inbytes < 0)
+ {
+ if (errno == EINTR)
+ continue;
+ error (1, errno, "reading from pipe");
+ }
+
+ do
+ {
+ ssize_t w = write (STDERR_FILENO,
+ buf + outbytes, inbytes - outbytes);
+ if (w < 0)
+ {
+ if (errno == EINTR)
+ w = 0;
+ if (w < 0)
+ _exit (1);
+ }
+ outbytes += w;
+ }
+ while (inbytes != outbytes);
+ }
+
+ /* Done processing output from grandchild. Propagate
+ its exit status back to the parent. */
+ while ((w = waitpid (pid, &status, 0)) == -1 && errno == EINTR)
+ continue;
+ if (w < 0)
+ error (1, errno, "waiting for child");
+ if (!WIFEXITED (status))
+ {
+ if (WIFSIGNALED (status))
+ raise (WTERMSIG (status));
+ error (1, errno, "child did not exit cleanly");
+ }
+ _exit (WEXITSTATUS (status));
+ }
+
+ /* Grandchild of original process. */
+ if (close (stderr_pipe[0]) < 0)
+ error (1, errno, "cannot close pipe");
+
+ if (stderr_pipe[1] != STDERR_FILENO)
+ {
+ if (dup2 (stderr_pipe[1], STDERR_FILENO) < 0)
+ error (1, errno, "cannot dup2 pipe");
+ if (close (stderr_pipe[1]) < 0)
+ error (1, errno, "cannot close pipe");
+ }
+}
+
+
+
int
-piped_child (command, tofdp, fromfdp)
+piped_child (command, tofdp, fromfdp, fix_stderr)
const char **command;
int *tofdp;
int *fromfdp;
+ int fix_stderr;
{
int pid;
int to_child_pipe[2];
@@ -422,11 +535,7 @@ piped_child (command, tofdp, fromfdp)
setmode (from_child_pipe[1], O_BINARY);
#endif
-#ifdef HAVE_VFORK
- pid = vfork ();
-#else
pid = fork ();
-#endif
if (pid < 0)
error (1, errno, "cannot fork");
if (pid == 0)
@@ -440,7 +549,10 @@ piped_child (command, tofdp, fromfdp)
if (dup2 (from_child_pipe[1], STDOUT_FILENO) < 0)
error (1, errno, "cannot dup2 pipe");
- /* Okay to cast out const below - execvp don't return anyhow. */
+ if (fix_stderr)
+ work_around_openssh_glitch ();
+
+ /* Okay to cast out const below - execvp don't return nohow. */
execvp ((char *)command[0], (char **)command);
error (1, errno, "cannot exec %s", command[0]);
}
diff --git a/contrib/cvs/src/sanity.sh b/contrib/cvs/src/sanity.sh
index acbb8d0..ae0580e 100755
--- a/contrib/cvs/src/sanity.sh
+++ b/contrib/cvs/src/sanity.sh
@@ -22,7 +22,7 @@
usage ()
{
echo "Usage: `basename $0` --help"
- echo "Usage: `basename $0` [-klr] [-f FROM-TEST] [-h HOSTNAME] CVS-TO-TEST [TESTS-TO-RUN...]"
+ echo "Usage: `basename $0` [-eklrv] [-f FROM-TEST] [-h HOSTNAME] CVS-TO-TEST [TESTS-TO-RUN...]"
}
exit_usage ()
@@ -35,22 +35,27 @@ exit_help ()
{
usage
echo
- echo "-H|--help display this text"
- echo "-l|--link-root"
- echo " test CVS using a symlink to a real CVSROOT"
- echo "-r|--remote test remote instead of local cvs"
+ echo "-H|--help Display this text."
+ echo "-e|--skipfail Treat tests that would otherwise be nonfatally skipped"
+ echo " for reasons like missing tools as failures, exiting"
+ echo " with an error message. Also treat warnings as"
+ echo " failures."
+ echo "-f FROM-TEST Run TESTS-TO-RUN, skipping all tests in the list before"
+ echo " FROM-TEST."
echo "-h HOSTNAME Use :ext:HOSTNAME to run remote tests rather than"
echo " :fork:. Implies --remote and assumes that \$TESTDIR"
echo " resolves to the same directory on both the client and"
echo " the server."
- echo "-k|--keep try to keep directories created by individual tests"
- echo " around, exiting after the first test which supports"
- echo " --keep"
- echo "-f FROM-TEST run TESTS-TO-RUN, skipping all tests in the list before"
- echo " FROM-TEST"
+ echo "-k|--keep Try to keep directories created by individual tests"
+ echo " around, exiting after the first test which supports"
+ echo " --keep."
+ echo "-l|--link-root"
+ echo " Test CVS using a symlink to a real CVSROOT."
+ echo "-r|--remote Test remote instead of local cvs."
+ echo "-v|--verbose List test names as they are executed."
echo
- echo "CVS-TO-TEST the path to the CVS executable to be tested"
- echo "TESTS-TO-RUN the names of the tests to run (defaults to all tests)"
+ echo "CVS-TO-TEST The path to the CVS executable to be tested."
+ echo "TESTS-TO-RUN The names of the tests to run (defaults to all tests)."
exit 2
}
@@ -59,6 +64,10 @@ exit_help ()
# required to make this script work properly.
unset CVSREAD
+# This will cause malloc to run slower but should also catch some common errors
+# when CVS is linked with glibc 2.x.
+MALLOC_CHECK_=2; export MALLOC_CHECK_
+
# We want to invoke a predictable set of i18n behaviors, not whatever
# the user running this script might have set.
# In particular:
@@ -71,6 +80,14 @@ LC_ALL=C
export LC_ALL
+#
+# Initialize the test counts.
+#
+passed=0
+skipped=0
+warnings=0
+
+
#
# read our options
@@ -80,7 +97,9 @@ unset remotehost
keep=false
linkroot=false
remote=false
-while getopts f:h:Hklr-: option ; do
+skipfail=false
+verbose=false
+while getopts ef:h:Hklrv-: option ; do
# convert the long opts to short opts
if test x$option = x-; then
case "$OPTARG" in
@@ -100,12 +119,23 @@ while getopts f:h:Hklr-: option ; do
option=k;
OPTARG=
;;
+ s|sk|ski|skip|skipf|skipfa|skipfai|skipfail)
+ option=e
+ OPTARG=
+ ;;
+ v|ve|ver|verb|verbo|verbos|verbose)
+ option=v
+ OPTARG=
+ ;;
*)
option=\?
OPTARG=
esac
fi
case "$option" in
+ e)
+ skipfail=:
+ ;;
f)
fromtest="$OPTARG"
;;
@@ -133,6 +163,9 @@ while getopts f:h:Hklr-: option ; do
r)
remote=:
;;
+ v)
+ verbose=:
+ ;;
\?)
exit_usage
;;
@@ -183,7 +216,8 @@ echo 'This test should produce no other output than this message, and a final "O
echo '(Note that the test can take an hour or more to run and periodically stops'
echo 'for as long as one minute. Do not assume there is a problem just because'
echo 'nothing seems to happen for a long time. If you cannot live without'
-echo "running status, try the command: \`tail -f check.log' from another window.)"
+echo 'running status, use the -v option or try the command:'
+echo "\`tail -f check.log' from another window.)"
# Regexp to match what CVS will call itself in output that it prints.
# FIXME: we don't properly quote this--if the name contains . we'll
@@ -191,11 +225,7 @@ echo "running status, try the command: \`tail -f check.log' from another window.
# special characters we are probably in big trouble.
PROG=`basename ${testcvs}`
-# Regexp to match an author name. I'm not really sure what characters
-# should be here. a-zA-Z obviously. People complained when 0-9 were
-# not allowed in usernames. Other than that I'm not sure.
-username="[-a-zA-Z0-9][-a-zA-Z0-9]*"
-author="[-a-zA-Z0-9][-a-zA-Z0-9]*"
+# Match the hostname
hostname="[-_.a-zA-Z0-9]*"
# Regexp to match the name of a temporary file (from cvs_temp_name).
@@ -211,11 +241,41 @@ RFCDATE_EPOCH="1 Jan 1970 00:00:00 -0000"
# than diff does
DATE="[a-zA-Z]* [a-zA-Z]* [ 1-3][0-9] [0-9:]* [0-9]*"
+# Which directories should Which and find_tool search for executables?
+SEARCHPATH=$PATH:/usr/local/bin:/usr/contrib/bin:/usr/contrib:/usr/gnu/bin:/local/bin:/local/gnu/bin:/gnu/bin:/sw/bin:/usr/pkg/bin
+
+# Do not assume that `type -p cmd` is portable
+# Usage: Which [-a] [-x|-f|-r] prog [$SEARCHPATH:/with/directories:/to/search]
+Which() {
+ # Optional first argument for file type, defaults to -x.
+ # Second argument is the file or directory to be found.
+ # Third argument is the PATH to search.
+ # By default, print only the first file that matches,
+ # -a will cause all matches to be printed.
+ notevery=:
+ if [ "x$1" = "x-a" ]; then notevery=false; shift; fi
+ case "$1" in
+ -*) t=$1; shift ;;
+ *) t=-x ;;
+ esac
+ case "$1" in
+ # FIXME: Someday this may need to be fixed
+ # to deal better with C:\some\path\to\ssh values...
+ /*) test $t $1 && echo $1 ;;
+ *) for d in `IFS=:; echo ${2-$SEARCHPATH}`
+ do
+ test $t $d/$1 && { echo $d/$1; if $notevery; then break; fi; }
+ done
+ ;;
+ esac
+}
+
+
# On cygwin32, we may not have /bin/sh.
if test -r /bin/sh; then
TESTSHELL="/bin/sh"
else
- TESTSHELL=`type -p sh 2>/dev/null`
+ TESTSHELL=`Which -f sh`
if test ! -r "$TESTSHELL"; then
TESTSHELL="/bin/sh"
fi
@@ -245,6 +305,12 @@ fi
# which makes for a lot of failed `tail -f' attempts.
touch check.log
+# Workaround any X11Forwarding by ssh. Otherwise this text:
+# Warning: No xauth data; using fake authentication data for X11 forwarding.
+# has been known to end up in the test results below
+# causing the test to fail.
+[ -n "$DISPLAY" ] && unset DISPLAY
+
# The default value of /tmp/cvs-sanity for TESTDIR is dubious,
# because it loses if two people/scripts try to run the tests
# at the same time. Some possible solutions:
@@ -326,40 +392,103 @@ fi
: ${ID=id}
: ${TR=tr}
+# Keep track of tools that are found, but do NOT work as we hope
+# in order to avoid them in future
+badtools=
+set_bad_tool ()
+{
+ badtools=$badtools:$1
+}
+is_bad_tool ()
+{
+ case ":$badtools:" in *:$1:*) return 0 ;; *) return 1 ; esac
+}
+
+version_test ()
+{
+ vercmd=$1
+ verbad=:
+ if RES=`$vercmd --version </dev/null 2>&1`; then
+ if test "X$RES" != "X--version" && test "X$RES" != "X" ; then
+ echo "$RES"
+ verbad=false
+ fi
+ fi
+ if $verbad; then
+ echo "The command \`$vercmd' does not support the --version option."
+ fi
+ # It does not really matter that --version is not supported
+ return 0
+}
+
+# Try to find a tool that satisfies all of the tests.
+# Usage: list:of:colon:separated:alternatives test1 test2 test3 test4...
+# Example: find_tool awk:gawk:nawk awk_tooltest1 awk_tooltest2
find_tool ()
{
- GLOCS="`echo $PATH | sed 's/:/ /g'` /usr/local/bin /usr/contrib/bin /usr/gnu/bin /local/bin /local/gnu/bin /gnu/bin"
+ default_TOOL=$1
+ echo find_tool: ${1+"$@"} >>$LOGFILE
+ cmds="`IFS=:; echo $1`"; shift; tooltests="${1+$@}"
+ if test -z "$tooltests"; then tooltests=version_test; fi
+ clist=; for cmd in $cmds; do clist="$clist `Which -a $cmd`"; done
+ # Make sure the default tool is just the first real command name
+ for default_TOOL in $clist `IFS=:; echo $default_TOOL`; do break; done
TOOL=""
- for path in $GLOCS ; do
- if test -x $path/g$1 ; then
- RES="`$path/g$1 --version </dev/null 2>/dev/null`"
- if test "X$RES" != "X--version" && test "X$RES" != "X" ; then
- TOOL=$path/g$1
- break
+ for trytool in $clist ; do
+ pass=:
+ for tooltest in $tooltests; do
+ result=`eval $tooltest $trytool`
+ rc=$?
+ echo "Running $tooltest $trytool" >>$LOGFILE
+ if test -n "$result"; then
+ echo "$result" >>$LOGFILE
fi
- fi
- if test -x $path/$1 ; then
- RES="`$path/$1 --version </dev/null 2>/dev/null`"
- if test "X$RES" != "X--version" && test "X$RES" != "X" ; then
- TOOL=$path/$1
- break
+ if test "$rc" = "0"; then
+ echo "PASS: $tooltest $trytool" >>$LOGFILE
+ elif test "$rc" = "77"; then
+ echo "MARGINAL: $tooltest $trytool; rc=$rc" >>$LOGFILE
+ TOOL=$trytool
+ pass=false
+ else
+ set_bad_tool $trytool
+ echo "FAIL: $tooltest $trytool; rc=$rc" >>$LOGFILE
+ pass=false
fi
+ done
+ if $pass; then
+ echo $trytool
+ return 0
fi
done
- if test -z "$TOOL"; then
- :
+ if test -n "$TOOL"; then
+ echo "Notice: The default version of \`$default_TOOL' is defective." >>$LOGFILE
+ echo "using \`$TOOL' and hoping for the best." >>$LOGFILE
+ echo "Notice: The default version of \`$default_TOOL' is defective." >&2
+ echo "using \`$TOOL' and hoping for the best." >&2
+ echo $TOOL
else
- echo "Notice: The default version of \`$1' is defective, using" >&2
- echo "\`$TOOL' instead." >&2
+ echo $default_TOOL
fi
- echo "$TOOL"
}
+id_tool_test ()
+{
+ id=$1
+ if $id -u >/dev/null 2>&1 && $id -un >/dev/null 2>&1; then
+ return 0
+ else
+ echo "Running these tests requires an \`id' program that understands the"
+ echo "-u and -n flags. Make sure that such an id (GNU, or many but not"
+ echo "all vendor-supplied versions) is in your path."
+ return 1
+ fi
+}
+
+ID=`find_tool id version_test id_tool_test`
+echo "Using ID=$ID" >>$LOGFILE
+
# You can't run CVS as root; print a nice error message here instead
# of somewhere later, after making a mess.
-#
-# FIXME - find_tool() finds the 'gid' from GNU id-utils if I pull 'id' out of
-# my path.
for pass in false :; do
case "`$ID -u 2>/dev/null`" in
"0")
@@ -367,18 +496,6 @@ for pass in false :; do
exit 1
;;
- "")
- if $pass; then :; else
- ID=`find_tool id`
- fi
- if $pass || test -z "$ID" ; then
- echo "Running these tests requires an \`id' program that understands the" >&2
- echo "-u and -n flags. Make sure that such an id (GNU, or many but not" >&2
- echo "all vendor-supplied versions) is in your path." >&2
- exit 1
- fi
- ;;
-
*)
break
;;
@@ -386,63 +503,70 @@ for pass in false :; do
done
# Cause NextStep 3.3 users to lose in a more graceful fashion.
-if $EXPR 'abc
+expr_tooltest1 ()
+{
+expr=$1
+if $expr 'abc
def' : 'abc
def' >/dev/null; then
- : good, it works
+ # good, it works
+ return 0
else
- EXPR=`find_tool expr`
- if test -z "$EXPR" ; then
- echo 'Running these tests requires an "expr" program that can handle' >&2
- echo 'multi-line patterns. Make sure that such an expr (GNU, or many but' >&2
- echo 'not all vendor-supplied versions) is in your path.' >&2
- exit 1
- fi
+ echo 'Running these tests requires an "expr" program that can handle'
+ echo 'multi-line patterns. Make sure that such an expr (GNU, or many but'
+ echo 'not all vendor-supplied versions) is in your path.'
+ return 1
fi
+}
# Warn SunOS, SysVr3.2, etc., users that they may be partially losing
# if we can't find a GNU expr to ease their troubles...
-if $EXPR 'a
+expr_tooltest2 ()
+{
+expr=$1
+if $expr 'a
b' : 'a
c' >/dev/null; then
- EXPR=`find_tool expr`
- if test -z "$EXPR" ; then
- echo 'Warning: you are using a version of expr that does not correctly'
- echo 'match multi-line patterns. Some tests may spuriously pass or fail.'
- echo 'You may wish to make sure GNU expr is in your path.'
- EXPR=expr
- fi
+ echo 'Warning: you are using a version of expr that does not correctly'
+ echo 'match multi-line patterns. Some tests may spuriously pass or fail.'
+ echo 'You may wish to make sure GNU expr is in your path.'
+ return 1
else
- : good, it works
+ return 0
fi
+}
-# More SunOS lossage...
+expr_create_bar ()
+{
echo 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' >${TESTDIR}/foo
cat ${TESTDIR}/foo ${TESTDIR}/foo ${TESTDIR}/foo ${TESTDIR}/foo >${TESTDIR}/bar
cat ${TESTDIR}/bar ${TESTDIR}/bar ${TESTDIR}/bar ${TESTDIR}/bar >${TESTDIR}/foo
cat ${TESTDIR}/foo ${TESTDIR}/foo ${TESTDIR}/foo ${TESTDIR}/foo >${TESTDIR}/bar
-if $EXPR "`cat ${TESTDIR}/bar`" : "`cat ${TESTDIR}/bar`" >/dev/null; then
+rm -f ${TESTDIR}/foo
+}
+
+expr_tooltest3 ()
+{
+expr=$1
+# More SunOS lossage...
+test ! -f ${TESTDIR}/bar && expr_create_bar
+if $expr "`cat ${TESTDIR}/bar`" : "`cat ${TESTDIR}/bar`" >/dev/null; then
: good, it works
else
- EXPR=`find_tool expr`
- if test -z "$EXPR" ; then
- echo 'Warning: you are using a version of expr that does not correctly'
- echo 'match large patterns. Some tests may spuriously pass or fail.'
- echo 'You may wish to make sure GNU expr is in your path.'
- EXPR=expr
- fi
+ echo 'Warning: you are using a version of expr that does not correctly'
+ echo 'match large patterns. Some tests may spuriously pass or fail.'
+ echo 'You may wish to make sure GNU expr is in your path.'
+ return 1
fi
-if $EXPR "`cat ${TESTDIR}/bar`x" : "`cat ${TESTDIR}/bar`y" >/dev/null; then
- EXPR=`find_tool expr`
- if test -z "$EXPR" ; then
- echo 'Warning: you are using a version of expr that does not correctly'
- echo 'match large patterns. Some tests may spuriously pass or fail.'
- echo 'You may wish to make sure GNU expr is in your path.'
- EXPR=expr
- fi
-else
- : good, it works
+if $expr "`cat ${TESTDIR}/bar`x" : "`cat ${TESTDIR}/bar`y" >/dev/null; then
+ echo 'Warning: you are using a version of expr that does not correctly'
+ echo 'match large patterns. Some tests may spuriously pass or fail.'
+ echo 'You may wish to make sure GNU expr is in your path.'
+ return 1
fi
+# good, it works
+return 0
+}
# That we should have to do this is total bogosity, but GNU expr
# version 1.9.4-1.12 uses the emacs definition of "$" instead of the unix
@@ -450,10 +574,18 @@ fi
# next release of GNU expr after 1.12 (but we still have to cater to the old
# ones for some time because they are in many linux distributions).
ENDANCHOR="$"
-if $EXPR 'abc
+expr_set_ENDANCHOR ()
+{
+expr=$1
+ENDANCHOR="$"
+if $expr 'abc
def' : 'abc$' >/dev/null; then
ENDANCHOR='\'\'
+ echo "Notice: An ENDANCHOR of dollar does not work."
+ echo "Using a workaround for GNU expr versions 1.9.4 thru 1.12"
fi
+return 0
+}
# Work around another GNU expr (version 1.10-1.12) bug/incompatibility.
# "." doesn't appear to match a newline (it does with SunOS 4.1.3 expr).
@@ -464,28 +596,53 @@ fi
# next release of GNU expr after 1.12 (but we still have to cater to the old
# ones for some time because they are in many linux distributions).
DOTSTAR='.*'
-if $EXPR 'abc
+expr_set_DOTSTAR ()
+{
+expr=$1
+DOTSTAR='.*'
+if $expr 'abc
def' : "a${DOTSTAR}f" >/dev/null; then
: good, it works
else
DOTSTAR='\(.\|
\)*'
+ echo "Notice: DOTSTAR changed from sane \`.*' value to \`$DOTSTAR\`"
+ echo "to workaround GNU expr version 1.10 thru 1.12 bug where \`.'"
+ echo "does not match a newline."
fi
+return 0
+}
# Now that we have DOTSTAR, make sure it works with big matches
-if $EXPR "`cat ${TESTDIR}/bar`" : "${DOTSTAR}xyzABC${DOTSTAR}$" >/dev/null; then
- : good, it works
+expr_tooltest_DOTSTAR ()
+{
+expr=$1
+test ! -f ${TESTDIR}/bar && expr_create_bar
+if $expr "`cat ${TESTDIR}/bar`" : "${DOTSTAR}xyzABC${DOTSTAR}$" >/dev/null; then
+ # good, it works
+ return 0
else
- EXPR=`find_tool expr`
- if test -z "$EXPR" ; then
- echo 'Warning: you are using a version of expr that does not correctly'
- echo 'match large patterns. Some tests may spuriously pass or fail.'
- echo 'You may wish to make sure GNU expr is in your path.'
- EXPR=expr
- fi
+ echo 'Warning: you are using a version of expr that does not correctly'
+ echo 'match large patterns. Some tests may spuriously pass or fail.'
+ echo 'You may wish to make sure GNU expr is in your path.'
+ return 77
fi
+}
+
+EXPR=`find_tool ${EXPR}:gexpr \
+ version_test expr_tooltest1 expr_tooltest2 expr_tooltest3 \
+expr_set_ENDANCHOR expr_set_DOTSTAR expr_tooltest_DOTSTAR`
+
+# Set the ENDANCHOR and DOTSTAR for the chosen expr version.
+expr_set_ENDANCHOR ${EXPR} >/dev/null
+expr_tooltest_DOTSTAR ${EXPR} >/dev/null
-rm -f ${TESTDIR}/foo ${TESTDIR}/bar
+echo "Using EXPR=$EXPR" >>$LOGFILE
+echo "Using ENDANCHOR=$ENDANCHOR" >>$LOGFILE
+echo "Using DOTSTAR=$DOTSTAR" >>$LOGFILE
+
+# Cleanup
+rm -f ${TESTDIR}/bar
# Work around yet another GNU expr (version 1.10) bug/incompatibility.
# "+" is a special character, yet for unix expr (e.g. SunOS 4.1.3)
@@ -519,22 +676,151 @@ else
exit 1
fi
+# Only 8 characters of $username appear in some output.
+if test `echo $username |wc -c` -gt 8; then
+ username8=`echo $username |sed 's/^\(........\).*/\1/'`
+else
+ username8=$username
+fi
+
+# Rarely, we need to match any username, not just the name of the user
+# running this test.
+#
+# I'm not really sure what characters should be here. a-zA-Z obviously.
+# People complained when 0-9 were not allowed in usernames. Other than that
+# I'm not sure.
+anyusername="[-a-zA-Z0-9][-a-zA-Z0-9]*"
+
# now make sure that tr works on NULs
-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'
- echo 'handle NUL bytes. Some tests may spuriously pass or fail.'
- echo 'You may wish to make sure GNU tr is in your path.'
- TR=tr
- fi
+tr_tooltest1 ()
+{
+tr=$1
+if $EXPR `echo "123" | $tr '2' '\0'` : "123" >/dev/null 2>&1; then
+ echo 'Warning: you are using a version of tr which does not correctly'
+ echo 'handle NUL bytes. Some tests may spuriously pass or fail.'
+ echo 'You may wish to make sure GNU tr is in your path.'
+ return 77
+fi
+# good, it works
+return 0
+}
+
+TR=`find_tool ${TR}:gtr version_test tr_tooltest1`
+echo "Using TR=$TR" >>$LOGFILE
+
+# Awk testing
+
+awk_tooltest1 ()
+{
+awk=$1
+$awk 'BEGIN {printf("one\ntwo\nthree\nfour\nfive\nsix")}' </dev/null >abc
+if $EXPR "`cat abc`" : \
+'one
+two
+three
+four
+five
+six'; then
+ rm abc
+ return 0
else
- : good, it works
+ rm abc
+ echo "Notice: awk BEGIN clause or printf is not be working properly."
+ return 1
+fi
+}
+
+# Format item %c check
+awk_tooltest2 ()
+{
+awk=$1
+$awk 'BEGIN { printf "%c%c%c", 2, 3, 4 }' </dev/null \
+ | ${TR} '\002\003\004' '123' >abc
+if $EXPR "`cat abc`" : "123" ; then
+ : good, found it
+else
+ echo "Notice: awk format %c string may not be working properly."
+ rm abc
+ return 77
fi
+rm abc
+return 0
+}
+
+AWK=`find_tool gawk:nawk:awk version_test awk_tooltest1 awk_tooltest2`
+echo "Using AWK=$AWK" >>$LOGFILE
+
+# Test that $1 works as a remote shell. If so, set $host, $CVS_RSH, &
+# $save_CVS_RSH to match and return 0. Otherwise, set $skipreason and return
+# 77.
+depends_on_rsh ()
+{
+ host=${remotehost-"`hostname`"}
+ result=`$1 $host 'echo test'`
+ rc=$?
+ if test $? != 0 || test "x$result" != "xtest"; then
+ skipreason="\`$1 $host' failed rc=$rc result=$result"
+ return 77
+ fi
+
+ save_CVS_RSH=$CVS_RSH
+ CVS_RSH=$1; export CVS_RSH
+ return 0
+}
+
+# Find a usable SSH. When a usable ssh is found, set $host, $CVS_RSH, and
+# $save_CVS_RSH and return 0. Otherwise, set $skipreason and return 77.
+depends_on_ssh ()
+{
+ case "$CVS_RSH" in
+ *ssh*|*putty*)
+ tryssh=`Which $CVS_RSH`
+ if [ ! -n "$tryssh" ]; then
+ skipreason="Unable to find CVS_RSH=$CVS_RSH executable"
+ return 77
+ elif [ ! -x "$tryssh" ]; then
+ skipreason="Unable to execute $tryssh program"
+ return 77
+ fi
+ ;;
+ *)
+ # Look in the user's PATH for "ssh"
+ tryssh=`Which ssh`
+ if test ! -r "$tryssh"; then
+ skipreason="Unable to find ssh program"
+ return 77
+ fi
+ ;;
+ esac
+
+ depends_on_rsh "$tryssh"
+ return $?
+}
pass ()
{
echo "PASS: $1" >>${LOGFILE}
+ passed=`expr $passed + 1`
+}
+
+skip ()
+{
+ if $skipfail; then
+ fail "$1${2+ ($2)}"
+ else
+ echo "SKIP: $1${2+ ($2)}" >>$LOGFILE
+ fi
+ skipped=`expr $skipped + 1`
+}
+
+warn ()
+{
+ if $skipfail; then
+ fail "$1${2+ ($2)}"
+ else
+ echo "WARNING: $1${2+ ($2)}" >>$LOGFILE
+ fi
+ warnings=`expr $warnings + 1`
}
fail ()
@@ -545,6 +831,28 @@ fail ()
exit 1
}
+verify_tmp_empty ()
+{
+ # Test our temp directory for cvs-serv* directories and cvsXXXXXX temp
+ # files. We would like to not leave any behind.
+ if $remote && ls $TMPDIR/cvs-serv* >/dev/null 2>&1; then
+ # A true value means ls found files/directories with these names.
+ # Give the server some time to finish, then retry.
+ sleep 1
+ if ls $TMPDIR/cvs-serv* >/dev/null 2>&1; then
+ warn "$1" "Found cvs-serv* directories in $TMPDIR."
+ # The above will exit if $skipfail
+ rm -rf $TMPDIR/cvs-serv*
+ fi
+ fi
+ if ls $TMPDIR/cvs?????? >/dev/null 2>&1; then
+ # A true value means ls found files/directories with these names.
+ warn "$1" "Found cvsXXXXXX temp files in $TMPDIR."
+ # The above will exit if $skipfail
+ rm -f ls $TMPDIR/cvs??????
+ fi
+}
+
# See dotest and dotest_fail for explanation (this is the parts
# of the implementation common to the two).
dotest_internal ()
@@ -562,14 +870,17 @@ dotest_internal ()
# surely use a somewhat non-specific pattern).
cat ${TESTDIR}/dotest.tmp >>${LOGFILE}
pass "$1"
+ verify_tmp_empty "$1"
# expr can't distinguish between "zero characters matched" and "no match",
# so special-case it.
elif test -z "$3" && test ! -s ${TESTDIR}/dotest.tmp; then
pass "$1"
+ verify_tmp_empty "$1"
elif test x"$4" != x; then
if $EXPR "`cat ${TESTDIR}/dotest.tmp`" : "$4${ENDANCHOR}" >/dev/null; then
cat ${TESTDIR}/dotest.tmp >>${LOGFILE}
pass "$1"
+ verify_tmp_empty "$1"
else
echo "** expected: " >>${LOGFILE}
echo "$3" >>${LOGFILE}
@@ -644,17 +955,20 @@ dotest_internal_debug ()
fail "$1"
else
pass "$1"
+ verify_tmp_empty "$1"
fi
else
echo "$3" > ${TESTDIR}/dotest.exp
if dotest_line_by_line "$1" "$2"; then
pass "$1"
+ verify_tmp_empty "$1"
else
if test x"$4" != x; then
mv ${TESTDIR}/dotest.exp ${TESTDIR}/dotest.ex1
echo "$4" > ${TESTDIR}/dotest.exp
if dotest_line_by_line "$1" "$2"; then
pass "$1"
+ verify_tmp_empty "$1"
else
mv ${TESTDIR}/dotest.exp ${TESTDIR}/dotest.ex2
echo "** expected: " >>${LOGFILE}
@@ -716,6 +1030,7 @@ dotest_lit ()
cat >${TESTDIR}/dotest.exp
if cmp ${TESTDIR}/dotest.exp ${TESTDIR}/dotest.tmp >/dev/null 2>&1; then
pass "$1"
+ verify_tmp_empty "$1"
else
echo "** expected: " >>${LOGFILE}
cat ${TESTDIR}/dotest.exp >>${LOGFILE}
@@ -754,6 +1069,19 @@ dotest_sort ()
dotest_internal "$@"
}
+# A function for fetching the timestamp of a revison of a file
+getrlogdate () {
+ ${testcvs} -n rlog -N ${1+"$@"} |
+ while read token value; do
+ case "$token" in
+ date:)
+ echo $value | sed "s,;.*,,"
+ break;
+ ;;
+ esac
+ done
+}
+
# Avoid picking up any stray .cvsrc, etc., from the user running the tests
mkdir home
HOME=${TESTDIR}/home; export HOME
@@ -773,30 +1101,31 @@ RCSINIT=; export RCSINIT
if test x"$*" = x; then
# Basic/miscellaneous functionality
tests="version basica basicb basicc basic1 deep basic2"
- tests="${tests} parseroot files spacefiles commit-readonly"
+ tests="${tests} parseroot parseroot2 files spacefiles commit-readonly"
tests="${tests} commit-add-missing"
tests="${tests} status"
# Branching, tagging, removing, adding, multiple directories
tests="${tests} rdiff rdiff-short"
- tests="${tests} rdiff2 diff diffnl death death2"
+ tests="${tests} rdiff2 diff diffnl death death2 death-rtag"
tests="${tests} rm-update-message rmadd rmadd2 rmadd3 resurrection"
- tests="${tests} dirs dirs2 branches branches2 tagc tagf"
+ tests="${tests} dirs dirs2 branches branches2 tagc tagf tag-space"
tests="${tests} rcslib multibranch import importb importc import-CVS"
+ tests="$tests import-quirks"
tests="${tests} update-p import-after-initial branch-after-import"
- tests="${tests} join join2 join3 join4 join5 join6"
+ tests="${tests} join join2 join3 join4 join5 join6 join7"
tests="${tests} join-readonly-conflict join-admin join-admin-2"
tests="${tests} join-rm"
- tests="${tests} new newb conflicts conflicts2 conflicts3"
+ tests="${tests} new newb conflicts conflicts2 conflicts3 conflicts4"
tests="${tests} clean"
# Checking out various places (modules, checkout -d, &c)
tests="${tests} modules modules2 modules3 modules4 modules5 modules6"
- tests="${tests} mkmodules co-d"
+ tests="${tests} modules7 mkmodules co-d"
tests="${tests} cvsadm emptydir abspath abspath2 toplevel toplevel2"
tests="${tests} rstar-toplevel trailingslashes checkout_repository"
# Log messages, error messages.
tests="${tests} mflag editor errmsg1 errmsg2 adderrmsg opterrmsg"
# Watches, binary files, history browsing, &c.
- tests="${tests} devcom devcom2 devcom3 watch4 watch5"
+ tests="${tests} devcom devcom2 devcom3 watch4 watch5 watch6"
tests="${tests} unedit-without-baserev"
tests="${tests} ignore ignore-on-branch binfiles binfiles2 binfiles3"
tests="${tests} mcopy binwrap binwrap2"
@@ -804,7 +1133,9 @@ if test x"$*" = x; then
tests="${tests} serverpatch log log2 logopt ann ann-id"
# Repository Storage (RCS file format, CVS lock files, creating
# a repository without "cvs init", &c).
- tests="${tests} crerepos rcs rcs2 rcs3 lockfiles backuprecover"
+ tests="${tests} crerepos rcs rcs2 rcs3 rcs4 rcs5 rcs6"
+ tests="$tests lockfiles backuprecover"
+ tests="${tests} sshstdio"
# More history browsing, &c.
tests="${tests} history"
tests="${tests} big modes modes2 modes3 stamps"
@@ -1757,6 +2088,11 @@ for what in $tests; do
continue
fi
fi
+
+ if $verbose; then
+ echo "$what:"
+ fi
+
case $what in
version)
@@ -1766,8 +2102,11 @@ for what in $tests; do
'
Concurrent Versions System (CVS) [0-9.]*.*
-Copyright (c) [-0-9]* Brian Berliner, david d .zoo. zuhn,
- Jeff Polk, and other authors
+Copyright (C) [0-9]* Free Software Foundation, Inc.
+
+Senior active maintainers include Larry Jones, Derek R. Price,
+and Mark D. Baushke. Please see the AUTHORS and README files from the CVS
+distribution kit for a complete list of contributors and copyrights.
CVS may be copied only under the terms of the GNU General Public License,
a copy of which can be found with the CVS distribution kit.
@@ -1895,7 +2234,7 @@ ${PLUS} ssfile line 2"
===================================================================
RCS file: ${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v
retrieving revision 1\.1
-diff -c -C3isacrowd -r1\.1 ssfile
+diff -c -C 3isacrowd -r1\.1 ssfile
${PROG} diff: invalid context length argument"
dotest basica-7 "${testcvs} -q ci -m modify-it" \
"Checking in sdir/ssdir/ssfile;
@@ -1992,8 +2331,8 @@ done"
'
Annotations for sdir/ssdir/ssfile
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
-1\.1 .'"${username}"' *[0-9a-zA-Z-]*.: ssfile
-1\.2 .'"${username}"' *[0-9a-zA-Z-]*.: ssfile line 2'
+1\.1 .'"$username8"' *[0-9a-zA-Z-]*.: ssfile
+1\.2 .'"$username8"' *[0-9a-zA-Z-]*.: ssfile line 2'
# Test resurrecting with strange revision numbers
cd sdir/ssdir
@@ -2381,7 +2720,8 @@ ${PROG} update: Updating second-dir"
# On Linux 2.2 systems, the cwd may be gone, so we recreate it
# to allow basicc-11 to actually happen
if test ! -d ../first-dir; then
- cd ..
+ # Apparently `cd ..' doesn't work with Linux 2.2 & Bash 2.05b.
+ cd $TESTDIR/1
mkdir ./first-dir
cd ./first-dir
fi
@@ -2389,8 +2729,7 @@ ${PROG} update: Updating second-dir"
"" "${PROG} release: deletion of directory \./\. failed: .*"
dotest basicc-11a "test -d ../second-dir" ""
- cd ..
- cd ..
+ cd ../..
mkdir 2; cd 2
dotest basicc-12 "${testcvs} -Q co ." ""
@@ -3433,7 +3772,17 @@ Are you sure you want to release (and delete) directory .first-dir.: "
"${PROG} rtag: Tagging first-dir
${PROG} rtag: Tagging first-dir/dir1
${PROG} rtag: Tagging first-dir/dir1/dir2"
-
+ # The next test used to cause an assert failure
+ # something like:
+ # cvs: ./recurse.c:667: do_recursion: Assertion `repository != ((void *)0)' failed.
+ dotest basic2-21b "${testcvs} co -p -r rtagged-by-head first-dir/file6" \
+"===================================================================
+Checking out first-dir/file6
+RCS: $CVSROOT_DIRNAME/first-dir/file6,v
+VERS: 1\.2
+\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
+file6
+file6"
# tag by tag
dotest basic2-22 "${testcvs} rtag -r rtagged-by-head rtagged-by-tag first-dir" \
"${PROG} rtag: Tagging first-dir
@@ -3772,6 +4121,8 @@ $PROG logout: Entry not found\."
rm -r 1
;;
+
+
files)
# Test of how we specify files on the command line
# (recurse.c and that sort of thing). Vaguely similar to
@@ -3847,26 +4198,25 @@ ${CVSROOT_DIRNAME}/first-dir/dir/sdir/ssdir/Attic/\.file,v <-- \.file
new revision: 1\.1\.2\.2; previous revision: 1\.1\.2\.1
done"
if $remote; then
+ # FIXCVS:
# This is a bug, looks like that toplevel_repos cruft in
# client.c is coming back to haunt us.
# May want to think about the whole issue, toplevel_repos
# has always been crufty and trying to patch it up again
# might be a mistake.
- dotest_fail files-12 \
+ dotest files-12 \
"${testcvs} commit -f -m test ./sdir/ssdir/.file ./.file" \
-"${PROG} commit: Up-to-date check failed for .\.file'
-${PROG} \[commit aborted\]: correct above errors first!"
+"Checking in \./sdir/ssdir/\.file;
+${CVSROOT_DIRNAME}/first-dir/dir/sdir/ssdir/Attic/\.file,v <-- \.file
+new revision: 1\.1\.2\.3; previous revision: 1\.1\.2\.2
+done"
# Sync up the version numbers so that the rest of the
# tests don't need to expect different numbers based
# local or remote.
dotest files-12-workaround \
-"${testcvs} commit -f -m test sdir/ssdir/.file .file" \
-"Checking in sdir/ssdir/\.file;
-${CVSROOT_DIRNAME}/first-dir/dir/sdir/ssdir/Attic/\.file,v <-- \.file
-new revision: 1\.1\.2\.3; previous revision: 1\.1\.2\.2
-done
-Checking in \.file;
+"${testcvs} commit -f -m test .file" \
+"Checking in \.file;
${CVSROOT_DIRNAME}/first-dir/dir/Attic/\.file,v <-- \.file
new revision: 1\.1\.2\.3; previous revision: 1\.1\.2\.2
done"
@@ -4053,7 +4403,7 @@ C tfile"
# Now note our status
dotest status-1 "${testcvs} status tfile" \
"===================================================================
-File: tfile Status: File had conflicts on merge
+File: tfile Status: Unresolved Conflict
Working revision: 1\.2.*
Repository revision: 1\.2 ${CVSROOT_DIRNAME}/first-dir/tfile,v
@@ -4086,6 +4436,21 @@ File: tfile Status: Locally Modified
Sticky Date: (none)
Sticky Options: (none)"
+ # Check that there are no problems just using CVS/Root too.
+ save_CVSROOT=$CVSROOT
+ unset CVSROOT
+ dotest status-3a "${testcvs} status tfile" \
+"===================================================================
+File: tfile Status: Locally Modified
+
+ Working revision: 1\.2.*
+ Repository revision: 1\.2 ${CVSROOT_DIRNAME}/first-dir/tfile,v
+ Sticky Tag: (none)
+ Sticky Date: (none)
+ Sticky Options: (none)"
+ CVSROOT=$save_CVSROOT
+ export CVSROOT
+
# FIXCVS:
# Update is supposed to re-Register() the file when it
# finds resolved conflicts:
@@ -4477,7 +4842,7 @@ done"
===================================================================
RCS file: ${CVSROOT_DIRNAME}/first-dir/abc,v
retrieving revision 1\.2
-diff --ifdef=HAVE_WINSOCK_H -r1\.2 abc
+diff --ifdef HAVE_WINSOCK_H -r1\.2 abc
#ifndef HAVE_WINSOCK_H
extern int gethostname ();
#else /\* HAVE_WINSOCK_H \*/
@@ -5248,7 +5613,7 @@ ${PROG} update: file4 is no longer in the repository"
dotest death2-16 "${testcvs} -q commit -m add" \
"Checking in file2;
${CVSROOT_DIRNAME}/first-dir/file2,v <-- file2
-new revision: 1\.1\.2\.1; previous revision: 1\.1
+new revision: 1\.1\.2\.2; previous revision: 1\.1\.2\.1
done"
# Add a new file on the branch.
@@ -5398,6 +5763,103 @@ C file4"
cd .. ; rm -rf first-dir ${CVSROOT_DIRNAME}/first-dir
;;
+
+
+ death-rtag)
+ # This documents a bug in CVS that prevents rtag from tagging files
+ # in the Attic.
+ mkdir $CVSROOT_DIRNAME/death-rtag
+ dotest death-rtag-init-1 "$testcvs -Q co death-rtag"
+ cd death-rtag
+ echo "This is the file foo" > foo
+ echo "This is the file bar" > bar
+ dotest death-rtag-init-2 "$testcvs -Q add foo bar"
+ dotest death-rtag-init-3 "$testcvs -Q ci -m 'Add foo and bar.'" \
+"RCS file: $CVSROOT_DIRNAME/death-rtag/bar,v
+done
+Checking in bar;
+$CVSROOT_DIRNAME/death-rtag/bar,v <-- bar
+initial revision: 1\.[0-9]*
+done
+RCS file: $CVSROOT_DIRNAME/death-rtag/foo,v
+done
+Checking in foo;
+$CVSROOT_DIRNAME/death-rtag/foo,v <-- foo
+initial revision: 1\.[0-9]*
+done"
+ dotest death-rtag-init-5 "$testcvs -Q tag -b mybranch"
+
+ dotest death-rtag-1 "$testcvs -q rtag -rmybranch willtag death-rtag"
+ dotest death-rtag-2 "$testcvs -Q rm -f foo"
+ dotest death-rtag-3 "$testcvs -Q ci -m 'Remove foo.'" \
+"Removing foo;
+$CVSROOT_DIRNAME/death-rtag/foo,v <-- foo
+new revision: delete; previous revision: 1\.[0-9]*
+done"
+ # commit something on the branch so that the moving tag is visible.
+ dotest death-rtag-3.2 "$testcvs -Q up -rmybranch"
+ echo some branch content >>foo
+ echo some branch content >>bar
+ dotest death-rtag-3.3 "$testcvs -Q ci -m 'Change foo.'" \
+"Checking in bar;
+$CVSROOT_DIRNAME/death-rtag/bar,v <-- bar
+new revision: 1\.1\.2\.1; previous revision: 1\.1
+done
+Checking in foo;
+$CVSROOT_DIRNAME/death-rtag/Attic/foo,v <-- foo
+new revision: 1\.1\.2\.1; previous revision: 1\.1
+done"
+ dotest death-rtag-3.4 \
+"$testcvs -q rtag -rmybranch wontmove death-rtag"
+ dotest death-rtag-3.5 "$testcvs -q rtag -F wontmove death-rtag"
+
+ cd ..
+ # Removing -f below avoids this bug.
+ dotest death-rtag-4 "$testcvs -q rtag -frmybranch wonttag death-rtag"
+
+ # When the bug existed, `wonttag' would not have been present in
+ # foo,v.
+ #
+ # A second bug prevented `wontmove' from moving from the branch to
+ # the dead revision on the trunk (death-rtag-3.4 & death-rtag-3.5).
+ dotest death-rtag-5 "$testcvs -q rlog death-rtag" \
+"
+RCS file: $CVSROOT_DIRNAME/death-rtag/bar,v
+head: 1.[0-9]*
+branch:
+locks: strict
+access list:
+symbolic names:
+ wonttag: 1\.1\.2\.1
+ wontmove: 1\.1
+ willtag: 1\.1
+ mybranch: 1\.1.0\.2
+keyword substitution: kv
+$DOTSTAR
+RCS file: $CVSROOT_DIRNAME/death-rtag/Attic/foo,v
+head: 1.[0-9]*
+branch:
+locks: strict
+access list:
+symbolic names:
+ wonttag: 1\.1\.2\.1
+ wontmove: 1\.2
+ willtag: 1\.1
+ mybranch: 1\.1.0\.2
+keyword substitution: kv
+$DOTSTAR"
+
+ if $keep; then
+ echo Keeping $TESTDIR and exiting due to --keep
+ exit 0
+ fi
+
+ rm -r death-rtag
+ rm -rf $CVSROOT_DIRNAME/death-rtag
+ ;;
+
+
+
rm-update-message)
# FIXME
# local CVS prints a warning message when update notices a missing
@@ -5860,8 +6322,8 @@ done"
dotest resurrection-init5 "$testcvs -Q rm -f file1"
- # The first test is that `cvs add' will resurrect a file before it
- # has been committed.
+ # The first test is that `cvs add' will resurrect a file before its
+ # removal has been committed.
dotest_sort resurrection-1 "$testcvs add file1" \
"U file1
$PROG add: file1, version 1\.1, resurrected"
@@ -5909,6 +6371,24 @@ $PROG add: use 'cvs commit' to add this file permanently"
$CVSROOT_DIRNAME/first-dir/file1,v <-- file1
new revision: 1\.1\.2\.2; previous revision: 1\.1\.2\.1
done"
+
+ # The next few tests verify that an attempted resurrection of a file
+ # with no previous revision on the trunk fails.
+ touch file2
+ dotest resurrection-9 "$testcvs -Q add file2"
+ dotest resurrection-10 "$testcvs -Q ci -mnew-file2" \
+"RCS file: $CVSROOT_DIRNAME/first-dir/Attic/file2,v
+done
+Checking in file2;
+$CVSROOT_DIRNAME/first-dir/Attic/file2,v <-- file2
+new revision: 1\.1\.2\.1; previous revision: 1\.1
+done"
+ dotest resurrection-11 "$testcvs -Q up -A"
+
+ # This command once caused an assertion failure.
+ dotest resurrection-12 "$testcvs add file2" \
+"$PROG add: File \`file2' has no previous revision to resurrect\."
+
if $keep; then
echo Keeping $TESTDIR and exiting due to --keep
exit 0
@@ -7009,6 +7489,160 @@ ${PROG} rtag: first-dir/file1: Not moving non-branch tag .regulartag. from 1\.1
rm -rf ${CVSROOT_DIRNAME}/first-dir
;;
+ tag-space)
+ # Test tags with spaces in the names.
+ #
+ # Prior to releases 1.11.18 & 1.12.10, some commands used with
+ # tags with spaces in the names could hang CVS.
+
+ # Setup; check in first-dir/file1
+ mkdir 1; cd 1
+ dotest tag-space-init-1 "$testcvs -q co -l ."
+ mkdir first-dir
+ dotest tag-space-init-2 "$testcvs add first-dir" \
+"Directory $CVSROOT_DIRNAME/first-dir added to the repository"
+ cd first-dir
+ touch file1
+ dotest tag-space-init-3 "$testcvs add file1" \
+"$PROG add: scheduling file \`file1' for addition
+$PROG add: use '$PROG commit' to add this file permanently"
+ dotest tag-space-init-4 "$testcvs -Q ci -m add" \
+"RCS file: $CVSROOT_DIRNAME/first-dir/file1,v
+done
+Checking in file1;
+$CVSROOT_DIRNAME/first-dir/file1,v <-- file1
+initial revision: 1\.1
+done"
+
+ # Reportedly, the following two tags make it past WinCVS.
+ dotest_fail tag-space-1 "$testcvs tag ' spacetag '" \
+"$PROG \[tag aborted\]: tag \` spacetag ' must start with a letter"
+ dotest_fail tag-space-2 "$testcvs tag 'spacetag '" \
+"$PROG \[tag aborted\]: tag \`spacetag ' has non-visible graphic characters"
+
+ if $remote; then
+ # Verify that this isn't a client check.
+ dotest tag-space-3 "$testcvs server" \
+"E $PROG \[tag aborted\]: tag \` spacetag ' must start with a letter
+error " <<EOF
+Root $CVSROOT_DIRNAME
+UseUnchanged
+Argument --
+Argument spacetag
+Directory .
+$CVSROOT_DIRNAME/first-dir
+Entry /file1/1.1///
+Unchanged file1
+tag
+EOF
+
+ dotest tag-space-4 "$testcvs server" \
+"E $PROG \[tag aborted\]: tag \`spacetag ' has non-visible graphic characters
+error " <<EOF
+Root $CVSROOT_DIRNAME
+UseUnchanged
+Argument --
+Argument spacetag
+Directory .
+$CVSROOT_DIRNAME/first-dir
+Entry /file1/1.1///
+Unchanged file1
+tag
+EOF
+ fi # $remote
+
+ # Any number of normal tags and branches were handled correctly.
+ dotest tag-space-5 "$testcvs -Q tag t1"
+ dotest tag-space-5b "$testcvs -Q tag t2"
+ dotest tag-space-5c "$testcvs -Q tag -b b1"
+
+ cd ../..
+ mkdir 2; cd 2
+
+ # But once a vendor branch exists, it's all over.
+ mkdir project; cd project
+ touch file1
+ dotest tag-space-init-4 \
+"$testcvs -Q import -mimport second-dir VENDOR RELEASE"
+
+ cd ..
+
+ dotest_fail tag-space-6 "$testcvs -Q co -r ' spacetag ' first-dir" \
+"$PROG \[checkout aborted\]: tag \` spacetag ' must start with a letter"
+
+ # But when any files were imported, this test hung prior to CVS
+ # versions 1.11.18 & 1.12.10.
+ dotest_fail tag-space-7 "$testcvs -Q co -r ' spacetag ' second-dir" \
+"$PROG \[checkout aborted\]: tag \` spacetag ' must start with a letter"
+
+ if $remote; then
+ # I based the client input in the next two tests on actual input
+ # from WinCVS 1.2.
+ dotest tag-space-8 "$testcvs server" \
+"E $PROG \[checkout aborted\]: tag \` spacetag ' must start with a letter
+error " <<EOF
+Root $CVSROOT_DIRNAME
+Argument -P
+Argument -r
+Argument spacetag
+Argument first-dir
+Directory .
+$CVSROOT_DIRNAME
+co
+EOF
+
+ # Verify the test is not on the client side.
+ dotest tag-space-9 "$testcvs server" \
+"E $PROG \[checkout aborted\]: tag \` spacetag ' must start with a letter
+error " <<EOF
+Root $CVSROOT_DIRNAME
+Argument -P
+Argument -r
+Argument spacetag
+Argument second-dir
+Directory .
+$CVSROOT_DIRNAME
+co
+EOF
+ fi # $remote
+
+ dotest tag-space-10 "$testcvs -Q co second-dir"
+ cd second-dir
+
+ # This test would also hang.
+ dotest_fail tag-space-11 "$testcvs -Q up -r ' spacetag '" \
+"$PROG \[update aborted\]: tag \` spacetag ' must start with a letter"
+
+ if $remote; then
+ dotest tag-space-12 "$testcvs server" \
+"E $PROG \[update aborted\]: tag \` spacetag ' must start with a letter
+error " <<EOF
+Root $CVSROOT_DIRNAME
+Argument -r
+Argument spacetag
+Argument -u
+Argument --
+Directory .
+$CVSROOT_DIRNAME
+Unchanged file1
+update
+EOF
+ fi # $remote
+
+ # I'm skipping tests for other commands that may have had the same
+ # problem. Hopefully, if a new issue arises, one of the above tests
+ # will catch the problem.
+
+ if $keep; then
+ echo Keeping $TESTDIR and exiting due to --keep
+ exit 0
+ fi
+
+ cd ../..
+ rm -r 1 2
+ rm -rf $CVSROOT_DIRNAME/first-dir $CVSROOT_DIRNAME/second-dir
+ ;;
+
rcslib)
# Test librarification of RCS.
# First: test whether `cvs diff' handles $Name expansion
@@ -7115,12 +7749,12 @@ mumble;
}
EOF
# Use dotest_fail because exit status from `cvs diff' must be 1.
- dotest_fail rcslib-diffrgx-3 "${testcvs} diff -c -F'.*(' rgx.c" \
+ dotest_fail rcslib-diffrgx-3 "${testcvs} diff -c -F'.* (' rgx.c" \
"Index: rgx\.c
===================================================================
RCS file: ${CVSROOT_DIRNAME}/first-dir/rgx\.c,v
retrieving revision 1\.1
-diff -c -F\.\*( -r1\.1 rgx\.c
+diff -c -F \.\* ( -r1\.1 rgx\.c
\*\*\* rgx\.c ${RFCDATE} 1\.1
--- rgx\.c ${RFCDATE}
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* test_regex (whiz, bang)
@@ -7334,15 +7968,59 @@ done"
"${PROG} rtag: could not read RCS file for file2
${PROG} rtag: could not read RCS file for first-dir/file2
${PROG} rtag: could not read RCS file for first-dir/file2"
- cd ..
- cd ..
+ # Restore file1 for the next test.
+ dotest rcslib-long-symlink-init-1 "$testcvs -Q up -A"
+ dotest rcslib-long-symlink-init-2 "$testcvs -Q add file1"
+ dotest rcslib-long-symlink-init-3 "$testcvs -Q ci -mback" \
+"Checking in file1;
+$CVSROOT_DIRNAME/first-dir/file1,v <-- file1
+new revision: 1\.4; previous revision: 1\.3
+done"
+
+ cd ../.. # $TESTDIR
+
+ # CVS has a hard-coded default link path size of 127 characters.
+ # Make sure it knows how to exceed that.
+ longpath=$CVSROOT_DIRNAME
+ count=0
+ while test $count -lt 10; do
+ count=`expr $count + 1`
+ longpath=$longpath/123456789012345678901234567890
+ mkdir $longpath
+ done
+ cp $CVSROOT_DIRNAME/first-dir/file1,v $longpath
+ mkdir $CVSROOT_DIRNAME/second-dir
+
+ # Switch as for rcslib-symlink-1
+ if test -n "$remotehost"; then
+ dotest rcslib-long-symlink-1rh \
+"$CVS_RSH $remotehost 'ln -s $longpath/file1,v $CVSROOT_DIRNAME/second-dir/fileX,v'"
+ else
+ dotest rcslib-long-symlink-1 \
+"ln -s $longpath/file1,v $CVSROOT_DIRNAME/second-dir/fileX,v"
+ fi
+
+ dotest rcslib-long-symlink-2 "$testcvs co second-dir" \
+"$PROG checkout: Updating second-dir
+U second-dir/fileX"
+
+ cd second-dir
+ echo change-it >>fileX
+
+ # Writes actually cause symlinks to be resolved.
+ dotest rcslib-long-symlink-3 "$testcvs -q ci -mwrite-it" \
+"Checking in fileX;
+$CVSROOT_DIRNAME/123456789012345678901234567890/123456789012345678901234567890/123456789012345678901234567890/123456789012345678901234567890/123456789012345678901234567890/123456789012345678901234567890/123456789012345678901234567890/123456789012345678901234567890/123456789012345678901234567890/123456789012345678901234567890/file1,v <-- fileX
+new revision: 1\.5; previous revision: 1\.4
+done"
if $keep; then
echo Keeping ${TESTDIR} and exiting due to --keep
exit 0
fi
+ cd ..
# Must remove the symlink first. Samba doesn't appear to show
# broken symlink across the SMB share, and rm -rf by itself
# will remove file1,v first and leave file2,v a broken link and the
@@ -7353,10 +8031,12 @@ ${PROG} rtag: could not read RCS file for first-dir/file2"
# rcslib-symlink-3j works fine, but the next one doesn't unless run
# remotely under Cygwin and using a TESTDIR on a Samba share.
if test -n "$remotehost"; then
- $CVS_RSH $remotehost "rm -f ${CVSROOT_DIRNAME}/first-dir/file2,v"
+ $CVS_RSH $remotehost \
+"rm -f $CVSROOT_DIRNAME/first-dir/file2,v $CVSROOT_DIRNAME/second-dir/fileX,v"
fi
- rm -rf ${CVSROOT_DIRNAME}/first-dir
- rm -r first-dir 2
+ rm -rf $CVSROOT_DIRNAME/first-dir $CVSROOT_DIRNAME/second-dir \
+ $CVSROOT_DIRNAME/123456789012345678901234567890
+ rm -r first-dir second-dir 2
;;
multibranch)
@@ -7457,6 +8137,7 @@ modify-on-br1
# head -- intended to test vendor branches and HEAD,
# although it doesn't really do it yet.
# import-CVS -- refuse to import directories named "CVS".
+ # import-quirks -- short tests of import quirks.
# import
mkdir import-dir ; cd import-dir
@@ -7717,7 +8398,8 @@ Use the following command to help the merge:"
echo 'my own stuff' >mine2.c
dotest_fail importb-3 \
"${testcvs} import -m add -b 1 second-dir dummy really_dumb_y" \
-"${PROG} \[[a-z]* aborted\]: Only branches with two dots are supported: 1"
+"$PROG \[import aborted\]: Only numeric branch specifications with two dots are
+supported by import, not \`1'\. For example: \`1\.1\.1'\."
: when we implement main-branch import, should be \
"N second-dir/mine1\.c
N second-dir/mine2\.c
@@ -7935,6 +8617,72 @@ $PROG import: Importing $CVSROOT_DIRNAME/import-CVS/sdir"
rm -rf $CVSROOT_DIRNAME/import-CVS
;;
+
+
+ import-quirks)
+ # Short tests of quirky import behavior.
+ #
+ # For a list of other import tests with short descriptions, see the
+ # comment header of the "import" test.
+ mkdir import-quirks
+ cd import-quirks
+ touch file1 file2 file3
+
+ # CVS prior to 1.11.18 and 1.12.10 used to happily import to
+ # "branch 1.1", creating RCS archives with revisions like,
+ # "1.1..1". That double-dot is *not* a typo.
+ dotest_fail import-quirks-1 \
+"$testcvs import -b1.1. -mbad-bad-bad import-quirks VB RT" \
+"$PROG \[import aborted\]: Only numeric branch specifications with two dots are
+supported by import, not \`1\.1\.'\. For example: \`1\.1\.1'\."
+
+ dotest_fail import-quirks-2 \
+"$testcvs import -b1.1.1.. -mbad-bad-bad import-quirks VB RT" \
+"$PROG \[import aborted\]: Only numeric branch specifications with two dots are
+supported by import, not \`1\.1\.1\.\.'\. For example: \`1\.1\.1'\."
+
+ # Try a few odd numbers. This is hardly comprehensive.
+ dotest_sort import-quirks-2 \
+"$testcvs import -b10.10.101 -mthis-ones-ok import-quirks-2 VB RT" \
+"
+
+N import-quirks-2/file1
+N import-quirks-2/file2
+N import-quirks-2/file3
+No conflicts created by this import"
+
+ dotest_sort import-quirks-3 \
+"$testcvs import -b2345678901.2345678901.2345678901 -mthis-ones-ok import-quirks-3 VB RT" \
+"
+
+N import-quirks-3/file1
+N import-quirks-3/file2
+N import-quirks-3/file3
+No conflicts created by this import"
+
+ dotest_sort import-quirks-4 \
+"$testcvs import -b1.1.2 -mthis-ones-ok import-quirks-4 VB RT" \
+"
+
+N import-quirks-4/file1
+N import-quirks-4/file2
+N import-quirks-4/file3
+No conflicts created by this import"
+
+ if $keep; then
+ echo Keeping $TESTDIR and exiting due to --keep
+ exit 0
+ fi
+
+ cd ..
+ rm -r import-quirks
+ rm -rf $CVSROOT_DIRNAME/import-quirks-2 \
+ $CVSROOT_DIRNAME/import-quirks-3 \
+ $CVSROOT_DIRNAME/import-quirks-4
+ ;;
+
+
+
import-after-initial)
# Properly handle the case in which the first version of a
# file is created by a regular cvs add and commit, and there
@@ -8041,7 +8789,7 @@ ${PROG} add: use .${PROG} commit. to add this file permanently"
"${testcvs} commit -m cvs-add file2" \
"Checking in file2;
${CVSROOT_DIRNAME}/first-dir/file2,v <-- file2
-new revision: 1\.1\.1\.1\.2\.1; previous revision: 1\.1\.1\.1
+new revision: 1\.1\.1\.1\.2\.2; previous revision: 1\.1\.1\.1\.2\.1
done"
if $keep; then
@@ -8337,7 +9085,7 @@ new revision: 1\.1\.2\.1; previous revision: 1\.1
done
Checking in file2;
${CVSROOT_DIRNAME}/first-dir/file2,v <-- file2
-new revision: 1\.1\.2\.1; previous revision: 1\.1
+new revision: 1\.1\.2\.2; previous revision: 1\.1\.2\.1
done
Removing file3;
${CVSROOT_DIRNAME}/first-dir/file3,v <-- file3
@@ -8424,8 +9172,8 @@ M file4'
U first-dir/file2
RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v
retrieving revision 1\.1
-retrieving revision 1\.1\.2\.1
-Merging differences between 1\.1 and 1\.1\.2\.1 into file2
+retrieving revision 1\.1\.2\.2
+Merging differences between 1\.1 and 1\.1\.2\.2 into file2
U first-dir/file3
${PROG} checkout: scheduling first-dir/file3 for removal
U first-dir/file4
@@ -8459,8 +9207,8 @@ U first-dir/file7'
"U file1
RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v
retrieving revision 1\.1
-retrieving revision 1\.1\.2\.1
-Merging differences between 1\.1 and 1\.1\.2\.1 into file2
+retrieving revision 1\.1\.2\.2
+Merging differences between 1\.1 and 1\.1\.2\.2 into file2
${PROG} update: scheduling file3 for removal
M file4
${PROG} update: file file4 is locally modified, but has been removed in revision branch
@@ -8498,8 +9246,8 @@ T file7"
"U file1
RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v
retrieving revision 1.1
-retrieving revision 1.1.2.1
-Merging differences between 1.1 and 1.1.2.1 into file2
+retrieving revision 1.1.2.2
+Merging differences between 1.1 and 1.1.2.2 into file2
${PROG} update: scheduling file3 for removal
${PROG} update: file file4 has been modified, but has been removed in revision branch
U file8
@@ -8532,8 +9280,8 @@ U file1
U file2
RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v
retrieving revision 1\.1
-retrieving revision 1\.1\.2\.1
-Merging differences between 1\.1 and 1\.1\.2\.1 into file2
+retrieving revision 1\.1\.2\.2
+Merging differences between 1\.1 and 1\.1\.2\.2 into file2
U file3
${PROG} update: scheduling file3 for removal
U file4
@@ -9335,6 +10083,66 @@ U temp2\.txt
rm -rf ${CVSROOT_DIRNAME}/join6
;;
+ join7)
+ # This test deals with joins that happen with the -n switch
+ mkdir join7; cd join7
+ mkdir impdir; cd impdir
+ echo aaa >temp.txt
+ echo bbb >>temp.txt
+ echo ccc >>temp.txt
+ dotest join7-1 \
+"${testcvs} -Q import -minitial join7 vendor vers-1" \
+""
+ cd ..
+ dotest join7-2 "${testcvs} -Q co join7" ""
+ cd join7
+ echo ddd >> temp.txt
+ dotest join7-3 "${testcvs} -Q ci -madded-line temp.txt" \
+"Checking in temp.txt;
+$CVSROOT_DIRNAME/join7/temp.txt,v <-- temp.txt
+new revision: 1\.2; previous revision: 1\.1
+done"
+ cd ../impdir
+ echo aaaa >temp.txt
+ echo bbbb >>temp.txt
+ echo ccc >>temp.txt
+ echo eee >>temp.txt
+ dotest join7-4 \
+"${testcvs} -Q import -minitial join7 vendor vers-2" \
+""
+ cd ../join7
+ dotest join7-5 \
+"${testcvs} -n update -jvers-1 -jvers-2 temp.txt" \
+"RCS file: $CVSROOT_DIRNAME/join7/temp.txt,v
+retrieving revision 1\.1\.1\.1
+retrieving revision 1\.1\.1\.2
+Merging differences between 1\.1\.1\.1 and 1\.1\.1\.2 into temp.txt
+rcsmerge: warning: conflicts during merge"
+ touch temp.txt
+ dotest join7-6 "${testcvs} -n update -jvers-1 -jvers-2 temp.txt" \
+"RCS file: $CVSROOT_DIRNAME/join7/temp.txt,v
+retrieving revision 1\.1\.1\.1
+retrieving revision 1\.1\.1\.2
+Merging differences between 1\.1\.1\.1 and 1\.1\.1\.2 into temp.txt
+rcsmerge: warning: conflicts during merge" \
+"RCS file: $CVSROOT_DIRNAME/join7/temp.txt,v
+retrieving revision 1\.1\.1\.1
+retrieving revision 1\.1\.1\.2
+Merging differences between 1\.1\.1\.1 and 1\.1\.1\.2 into temp.txt
+rcsmerge: warning: conflicts during merge"
+
+ if $keep; then
+ echo Keeping ${TESTDIR} and exiting due to --keep
+ exit 0
+ fi
+
+ cd ../..
+ rm -r join7
+ rm -rf $CVSROOT_DIRNAME/join7
+ ;;
+
+
+
join-readonly-conflict)
# Previously, only tests 1 & 11 were being tested. I added the
# intermediate dotest's to try and diagnose a different failure
@@ -9397,7 +10205,7 @@ C $file"
# (and read-only) .# file for writing.
echo conflict > $file
- # verify that the backup file is writable
+ # verify that the backup file is not writable
if test -w ".#$file.1.1"; then
fail "join-readonly-conflict-10 : .#$file.1.1 is writable"
else
@@ -9985,7 +10793,7 @@ C a"
dotest conflicts-status-1 "${testcvs} status a" \
"===================================================================
-File: a Status: File had conflicts on merge
+File: a Status: Unresolved Conflict
Working revision: 1\.2.*
Repository revision: 1\.2 ${CVSROOT_DIRNAME}/first-dir/a,v
@@ -10522,6 +11330,129 @@ done"
rm -rf ${CVSROOT_DIRNAME}/first-dir
;;
+ conflicts4)
+ mkdir conflicts4; cd conflicts4
+ mkdir 1; cd 1
+ dotest conflicts4-1 "$testcvs -q co -l ."
+ mkdir first-dir
+ dotest conflicts4-2 "${testcvs} add first-dir" \
+"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository"
+ cd ..
+ mkdir 2; cd 2
+ dotest conflicts4-3 "${testcvs} -q co -l first-dir" ''
+ cd ../1/first-dir
+ echo baseline >file1
+ dotest conflicts4-4 "${testcvs} -q add file1" \
+"$PROG add: use .$PROG commit. to add this file permanently"
+ dotest conflicts4-5 "${testcvs} -q ci -m add-it" \
+"RCS file: $CVSROOT_DIRNAME/first-dir/file1,v
+done
+Checking in file1;
+$CVSROOT_DIRNAME/first-dir/file1,v <-- file1
+initial revision: 1\.1
+done"
+ cd ../../2/first-dir
+ dotest conflicts4-6 "${testcvs} -q update" "U file1"
+ # Make a local change
+ echo wibble2 >> file1
+ dotest conflicts4-7 "${testcvs} -q ci -m update2" \
+"Checking in file1;
+$CVSROOT_DIRNAME/first-dir/file1,v <-- file1
+new revision: 1\.2; previous revision: 1\.1
+done"
+ cd ../../1/first-dir
+ echo wibble1 >>file1
+ dotest conflicts4-8 "${testcvs} -Q update" \
+"RCS file: $CVSROOT_DIRNAME/first-dir/file1,v
+retrieving revision 1\.1
+retrieving revision 1\.2
+Merging differences between 1\.1 and 1\.2 into file1
+rcsmerge: warning: conflicts during merge
+cvs update: conflicts found in file1"
+ dotest_fail conflicts4-9 "${testcvs} -q update" \
+"C file1"
+
+ if $remote; then
+ cat >$TESTDIR/conflicts4/serveme <<EOF
+#!$TESTSHELL
+# This is admittedly a bit cheezy, in the sense that we make lots
+# of assumptions about what the client is going to send us.
+# We don't mention Repository, because current clients don't require it.
+# Sending these at our own pace, rather than waiting for the client to
+# make the requests, is bogus, but hopefully we can get away with it.
+echo "Valid-requests Root Valid-responses valid-requests Directory Entry Modified Unchanged Argument Argumentx ci co update Global_option"
+echo "ok"
+echo "MT text C "
+echo "MT fname file1"
+echo "MT newline"
+echo "error "
+cat >$TESTDIR/conflicts4/client.out
+EOF
+ # Cygwin. Pthffffffffft!
+ if test -n "$remotehost"; then
+ $CVS_RSH $remotehost "chmod +x $TESTDIR/conflicts4/serveme"
+ else
+ chmod +x $TESTDIR/conflicts4/serveme
+ fi
+ save_CVS_SERVER=$CVS_SERVER
+ CVS_SERVER=$TESTDIR/conflicts4/serveme; export CVS_SERVER
+ dotest_fail conflicts4-10r "$testcvs -q up" "C file1"
+ dotest conflicts4-11r "cat $TESTDIR/conflicts4/client.out" \
+"$DOTSTAR
+Argument --
+Directory .
+$CVSROOT_DIRNAME/first-dir
+Entry /file1/1.2/+=//
+Modified file1
+u=rw,g=rw,o=r
+59
+baseline
+""<<<<<<< file1
+wibble1
+""=======
+wibble2
+"">>>>>>> 1.2
+update"
+
+ cat >$TESTDIR/conflicts4/serveme <<EOF
+#!$TESTSHELL
+# This is admittedly a bit cheezy, in the sense that we make lots
+# of assumptions about what the client is going to send us.
+# We don't mention Repository, because current clients don't require it.
+# Sending these at our own pace, rather than waiting for the client to
+# make the requests, is bogus, but hopefully we can get away with it.
+echo "Valid-requests Root Valid-responses valid-requests Directory Entry Modified Unchanged Argument Argumentx ci co update Global_option Empty-conflicts"
+echo "ok"
+echo "MT text C "
+echo "MT fname file1"
+echo "MT newline"
+echo "error "
+cat >$TESTDIR/conflicts4/client.out
+EOF
+
+ dotest_fail conflicts4-12r "$testcvs -q up" "C file1"
+ dotest conflicts4-13r "cat $TESTDIR/conflicts4/client.out" \
+"$DOTSTAR
+Argument --
+Directory .
+$CVSROOT_DIRNAME/first-dir
+Entry /file1/1.2/+=//
+Unchanged file1
+update"
+
+ CVS_SERVER=$save_CVS_SERVER; export CVS_SERVER
+ fi
+
+ if $keep; then
+ echo Keeping $TESTDIR and exiting due to --keep
+ exit 0
+ fi
+
+ cd ../../..
+ rm -rf conflicts4
+ rm -rf $CVSROOT_DIRNAME/first-dir
+ ;;
+
clean)
# Test update -C (overwrite local mods w/ repository copies)
mkdir 1; cd 1
@@ -11430,9 +12361,10 @@ done"
"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository"
cd first-dir
- mkdir subdir
- dotest modules4-3 "${testcvs} add subdir" \
-"Directory ${CVSROOT_DIRNAME}/first-dir/subdir added to the repository"
+ mkdir subdir subdir_long
+ dotest modules4-3 "${testcvs} add subdir subdir_long" \
+"Directory ${CVSROOT_DIRNAME}/first-dir/subdir added to the repository
+Directory ${CVSROOT_DIRNAME}/first-dir/subdir_long added to the repository"
echo file1 > file1
dotest modules4-4 "${testcvs} add file1" \
@@ -11444,7 +12376,12 @@ done"
"${PROG}"' add: scheduling file `subdir/file2'\'' for addition
'"${PROG}"' add: use .'"${PROG}"' commit. to add this file permanently'
- dotest modules4-6 "${testcvs} -q ci -m add-it" \
+ echo file3 > subdir_long/file3
+ dotest modules4-6 "${testcvs} add subdir_long/file3" \
+"${PROG}"' add: scheduling file `subdir_long/file3'\'' for addition
+'"${PROG}"' add: use .'"${PROG}"' commit. to add this file permanently'
+
+ dotest modules4-7 "${testcvs} -q ci -m add-it" \
"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v
done
Checking in file1;
@@ -11456,19 +12393,26 @@ done
Checking in subdir/file2;
${CVSROOT_DIRNAME}/first-dir/subdir/file2,v <-- file2
initial revision: 1\.1
+done
+RCS file: ${CVSROOT_DIRNAME}/first-dir/subdir_long/file3,v
+done
+Checking in subdir_long/file3;
+${CVSROOT_DIRNAME}/first-dir/subdir_long/file3,v <-- file3
+initial revision: 1\.1
done"
cd ..
- dotest modules4-7 "${testcvs} -q update -d CVSROOT" \
+ dotest modules4-8 "${testcvs} -q update -d CVSROOT" \
"U CVSROOT${DOTSTAR}"
cd CVSROOT
cat >modules <<EOF
all -a first-dir
some -a !first-dir/subdir first-dir
+other -a !first-dir/subdir !first-dir/subdir_long first-dir
somewhat -a first-dir !first-dir/subdir
EOF
- dotest modules4-8 "${testcvs} -q ci -m add-modules" \
+ dotest modules4-9 "${testcvs} -q ci -m add-modules" \
"Checking in modules;
${CVSROOT_DIRNAME}/CVSROOT/modules,v <-- modules
new revision: 1\.[0-9]*; previous revision: 1\.[0-9]*
@@ -11479,39 +12423,56 @@ ${PROG} commit: Rebuilding administrative file database"
cd ..
mkdir 2; cd 2
- dotest modules4-9 "${testcvs} -q co all" \
+ dotest modules4-10 "${testcvs} -q co all" \
"U first-dir/file1
-U first-dir/subdir/file2"
+U first-dir/subdir/file2
+U first-dir/subdir_long/file3"
rm -r first-dir
- dotest modules4-10 "${testcvs} -q co some" "U first-dir/file1"
- dotest_fail modules4-11 "test -d first-dir/subdir" ''
+ dotest modules4-11 "${testcvs} -q co some" \
+"U first-dir/file1
+U first-dir/subdir_long/file3"
+ dotest_fail modules4-12 "test -d first-dir/subdir" ''
+ dotest modules4-13 "test -d first-dir/subdir_long" ''
rm -r first-dir
if $remote; then
# But remote seems to do it the other way.
- dotest modules4-11a "${testcvs} -q co somewhat" "U first-dir/file1"
- dotest_fail modules4-11b "test -d first-dir/subdir" ''
+ dotest modules4-14r-1 "${testcvs} -q co somewhat" \
+"U first-dir/file1
+U first-dir/subdir_long/file3"
+ dotest_fail modules4-14r-2 "test -d first-dir/subdir" ''
+ dotest modules4-14r-3 "test -d first-dir/subdir_long" ''
else
# This is strange behavior, in that the order of the
# "!first-dir/subdir" and "first-dir" matter, and it isn't
# clear that they should. I suspect it is long-standing
# strange behavior but I haven't verified that.
- dotest modules4-11a "${testcvs} -q co somewhat" \
+ dotest modules4-14-1 "${testcvs} -q co somewhat" \
"U first-dir/file1
-U first-dir/subdir/file2"
+U first-dir/subdir/file2
+U first-dir/subdir_long/file3"
+ dotest modules4-14-2 "test -d first-dir/subdir" ''
+ dotest modules4-14-3 "test -d first-dir/subdir_long" ''
fi
rm -r first-dir
+ dotest modules4-15 "${testcvs} -q co other" \
+"U first-dir/file1"
+ dotest_fail modules4-16 "test -d first-dir/subdir" ''
+ dotest_fail modules4-17 "test -d first-dir/subdir_long" ''
+ rm -r first-dir
+
cd ..
rm -r 2
- dotest modules4-12 "${testcvs} rtag tag some" \
+ dotest modules4-18 "${testcvs} rtag tag some" \
"${PROG} rtag: Tagging first-dir
-${PROG} rtag: Ignoring first-dir/subdir"
+${PROG} rtag: Ignoring first-dir/subdir
+${PROG} rtag: Tagging first-dir/subdir_long"
cd 1/first-dir/subdir
- dotest modules4-13 "${testcvs} log file2" "
+ dotest modules4-19 "${testcvs} log file2" "
RCS file: ${CVSROOT_DIRNAME}/first-dir/subdir/file2,v
Working file: file2
head: 1\.1
@@ -11528,6 +12489,11 @@ date: [0-9/]* [0-9:]*; author: ${username}; state: Exp;
add-it
============================================================================="
+ if $keep; then
+ echo Keeping $TESTDIR and exiting due to --keep
+ exit 0
+ fi
+
cd ../../..
rm -r 1
@@ -11623,7 +12589,14 @@ ${PROG} commit: Rebuilding administrative file database"
# Test that real modules check out to realmodule/a, not subdir/a.
if $remote; then
- dotest modules5-8 "${testcvs} co realmodule" \
+ # FIXCVS?
+ # Mac OSX 10.3 (Darwin ppc-osx1 5.5) fails here when $TMPDIR
+ # contains a symlink (it does not fail the local modules5-8).
+ # Since no other platforms are exhibiting the same problem, I
+ # suspect an issue with OSX and fork() or the like dereferencing
+ # the symlink, but it is possible it is something that could be
+ # fixed or worked around in CVS.
+ dotest modules5-8r "$testcvs co realmodule" \
"U realmodule/a
${PROG} checkout: Executing ..${CVSROOT_DIRNAME}/checkout\.sh. .realmodule..
checkout script invoked in ${TMPDIR}/cvs-serv[0-9a-z]*
@@ -11992,6 +12965,78 @@ ${PROG} commit: Rebuilding administrative file database"
fi
;;
+
+
+ modules7)
+ #
+ # Test tag problems vs an empty CVSROOT/val-tags file
+ #
+ # See the header comment for the `modules' test for an index of
+ # the complete suite of modules tests.
+ #
+ mkdir modules7
+ cd modules7
+ dotest modules7-1 "$testcvs -Q co -d top ."
+ cd top
+ mkdir zero one
+ dotest modules7-2 "$testcvs -Q add zero one"
+ cd one
+ echo 'file1 contents' > file1
+ dotest modules7-2 "$testcvs -Q add file1"
+ dotest modules7-3 "$testcvs -Q ci -mnew file1" \
+"RCS file: $CVSROOT_DIRNAME/one/file1,v
+done
+Checking in file1;
+$CVSROOT_DIRNAME/one/file1,v <-- file1
+initial revision: 1\.1
+done"
+ dotest modules7-4 "$testcvs -Q tag mytag file1"
+ cd ../CVSROOT
+ echo 'all -a zero one' > modules
+ dotest modules7-5 "$testcvs -Q ci -mall-module" \
+"Checking in modules;
+$CVSROOT_DIRNAME/CVSROOT/modules,v <-- modules
+new revision: [0-9.]*; previous revision: [0-9.]*
+done
+$PROG commit: Rebuilding administrative file database"
+ cd ../..
+ mkdir myexport
+ cd myexport
+ # FIXCVS: The export should NOT be aborted here
+ dotest_fail modules7-6 "$testcvs export -rmytag all" \
+"$PROG \[export aborted\]: no such tag mytag"
+ cd ..
+ rm -fr myexport
+ mkdir myexport
+ cd myexport
+ # FIXCVS: Workaround is to have mytag listed in val-tags
+ echo 'mytag y' > $CVSROOT_DIRNAME/CVSROOT/val-tags
+ dotest modules7-7 "$testcvs export -rmytag all" \
+"$PROG export: Updating zero
+$PROG export: Updating one
+U one/file1"
+ dotest modules7-8 'cat one/file1' 'file1 contents'
+
+ if $keep; then
+ echo Keeping $TESTDIR and exiting due to --keep
+ exit 0
+ fi
+
+ # cleanup
+ cd ../top/CVSROOT
+ echo "# empty modules file" >modules
+ dotest modules7-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 commit: Rebuilding administrative file database"
+ cd ../../..
+ rm -fr modules7
+ rm -rf $CVSROOT_DIRNAME/zero $CVSROOT_DIRNAME/one
+ ;;
+
+
mkmodules)
# When a file listed in checkoutlist doesn't exist, cvs-1.10.4
# would fail to remove the CVSROOT/.#[0-9]* temporary file it
@@ -13651,7 +14696,11 @@ ${PROG} \[checkout aborted\]: than the 0 which Max-dotdot specified"
# cvs checkout: warning: cannot make directory CVS in /: Permission denied
# cvs [checkout aborted]: cannot make directory /foo: Permission denied
# $
- dotest_fail abspath2-1 "${testcvs} co /foo" \
+ #
+ # The -z9 in this test also checks for an old server bug where the
+ # server would block indefinitely attempting to read an EOF from the
+ # client in the compression buffer shutdown routine.
+ dotest_fail abspath2-1 "$testcvs -z9 co /foo" \
"$PROG \[checkout aborted\]: Absolute module reference invalid: \`/foo'" \
"$PROG \[server aborted\]: Absolute module reference invalid: \`/foo'
$PROG \[checkout aborted\]: end of file from server (consult above messages if any)"
@@ -13772,7 +14821,6 @@ U top-dir/file1"
"${PROG} checkout: warning: cannot make directory CVS in \.: Permission denied
${PROG} checkout: Updating top-dir" \
"${PROG} checkout: warning: cannot make directory CVS in \.: Permission denied
-${PROG} checkout: warning: cannot make directory CVS in \.: Permission denied
${PROG} checkout: in directory \.:
${PROG} checkout: cannot open CVS/Entries for reading: No such file or directory
${PROG} checkout: Updating top-dir"
@@ -13893,14 +14941,14 @@ ${PROG} commit: Rebuilding administrative file database"
rstar-toplevel)
- # FIXCVS:
- # This test confirms a bug that exists in the r* commands currently
- # when run against the top-level project.
+ # This test used to confirm a bug that existed in the r* commands
+ # run against the top-level project prior to CVS 1.11.18 & 1.12.10.
#
- # The assertion failure is something like:
+ # The assertion failure was something like:
# do_recursion: Assertion \`strstr (repository, \"/\./\") == ((void \*)0)' failed\..*"
- dotest_fail rstar-toplevel-1 "$testcvs rlog ." \
-"${DOTSTAR}ssertion.*failed${DOTSTAR}" "${DOTSTAR}failed assertion${DOTSTAR}"
+ dotest rstar-toplevel-1 "$testcvs -q rlog ." \
+"
+RCS file: $CVSROOT_DIRNAME/CVSROOT$DOTSTAR"
if $keep; then
echo Keeping ${TESTDIR} and exiting due to --keep
@@ -14798,7 +15846,7 @@ U first-dir/abc'
# Now do it again, after removing the val-tags file created
# by devcom-t1 to force CVS to search the repository
# containing CVS directories.
- rm ${CVSROOT_DIRNAME}/CVSROOT/val-tags
+ rm -f ${CVSROOT_DIRNAME}/CVSROOT/val-tags
mkdir 3
cd 3
dotest devcom-t3 "${testcvs} -q co -rtag first-dir" \
@@ -15183,6 +16231,94 @@ done"
rm -rf ${CVSROOT_DIRNAME}/first-dir
;;
+
+
+ watch6)
+ # Check that `cvs watch on' does not reset the fileattr file.
+ mkdir watch6; cd watch6
+
+ dotest watch6-setup-1 "$testcvs -Q co -ldtop ."
+ cd top
+ mkdir watch6
+ dotest watch6-setup-2 "$testcvs -Q add watch6"
+
+ cd ..
+ dotest watch6-setup-3 "$testcvs -Q co watch6"
+ cd watch6
+
+ mkdir subdir
+ dotest watch6-setup-4 "$testcvs -Q add subdir"
+ cd subdir
+
+ # START watch add/remove sequence
+ dotest watch6-1 "$testcvs -Q watch add"
+ dotest watch6-2 \
+"grep '_watchers' $CVSROOT_DIRNAME/watch6/subdir/CVS/fileattr >/dev/null"
+
+ dotest watch6-3 "$testcvs watch on"
+ dotest watch6-4 \
+"grep '_watchers' $CVSROOT_DIRNAME/watch6/subdir/CVS/fileattr >/dev/null"
+ dotest watch6-5 \
+"grep '_watched' $CVSROOT_DIRNAME/watch6/subdir/CVS/fileattr >/dev/null"
+
+ dotest watch6-6 "$testcvs watch off"
+ dotest watch6-7 \
+"grep '_watchers' $CVSROOT_DIRNAME/watch6/subdir/CVS/fileattr >/dev/null"
+ dotest_fail watch6-8 \
+"grep '_watched' $CVSROOT_DIRNAME/watch6/subdir/CVS/fileattr >/dev/null"
+
+ dotest watch6-9 "$testcvs watch remove"
+ dotest_fail watch6-10 \
+"test -d $CVSROOT_DIRNAME/test-directory/subdir/CVS"
+ dotest_fail watch6-11 \
+"test -f $CVSROOT_DIRNAME/test-directory/subdir/CVS/fileattr"
+ # END watch add/remove sequence
+
+ echo Hi there >afile
+ dotest watch6-12 "$testcvs -Q add afile"
+ dotest watch6-13 "$testcvs ci -m 'A file' afile" \
+"RCS file: $CVSROOT_DIRNAME/watch6/subdir/afile,v
+done
+Checking in afile;
+$CVSROOT_DIRNAME/watch6/subdir/afile,v <-- afile
+initial revision: 1\.1
+done"
+
+ # START watch add/remove sequence
+ dotest watch6-14 "$testcvs -Q watch add"
+ dotest watch6-15 \
+"grep '_watchers' $CVSROOT_DIRNAME/watch6/subdir/CVS/fileattr >/dev/null"
+
+ dotest watch6-16 "$testcvs watch on"
+ dotest watch6-17 \
+"grep '_watchers' $CVSROOT_DIRNAME/watch6/subdir/CVS/fileattr >/dev/null"
+ dotest watch6-18 \
+"grep '_watched' $CVSROOT_DIRNAME/watch6/subdir/CVS/fileattr >/dev/null"
+
+ dotest watch6-19 "$testcvs watch off"
+ dotest watch6-20 \
+"grep '_watchers' $CVSROOT_DIRNAME/watch6/subdir/CVS/fileattr >/dev/null"
+ dotest_fail watch6-21 \
+"grep '_watched' $CVSROOT_DIRNAME/watch6/subdir/CVS/fileattr >/dev/null"
+
+ dotest watch6-22 "$testcvs watch remove"
+ dotest_fail watch6-23 \
+"test -d $CVSROOT_DIRNAME/test-directory/subdir/CVS"
+ dotest_fail watch6-24 \
+"test -f $CVSROOT_DIRNAME/test-directory/subdir/CVS/fileattr"
+ # END watch add/remove sequence
+
+ if $keep; then
+ echo Keeping $TESTDIR and exiting due to --keep
+ exit 0
+ fi
+ cd ../../..
+ rm -r watch6
+ rm -rf $CVSROOT_DIRNAME/watch6
+ ;;
+
+
+
unedit-without-baserev)
mkdir 1; cd 1
module=x
@@ -15465,7 +16601,7 @@ T file1'
dotest ignore-on-branch-5 "$testcvs -q ci -mbranch file2" \
"Checking in file2;
$CVSROOT_DIRNAME/ignore-on-branch/file2,v <-- file2
-new revision: 1\.1\.2\.1; previous revision: 1\.1
+new revision: 1\.1\.2\.2; previous revision: 1\.1\.2\.1
done"
dotest ignore-on-branch-6 "$testcvs -q up -rbranch2" \
"${PROG} update: file2 is no longer in the repository"
@@ -15523,6 +16659,24 @@ File: binfile Status: Up-to-date
Sticky Date: (none)
Sticky Options: -kb"
+ # Test that "-kk" does not override "-kb"
+ cd ../..
+ mkdir 2a; cd 2a
+ dotest binfiles-5.5a0 "${testcvs} -q co -kk first-dir" 'U first-dir/binfile'
+ cd first-dir
+ # Testing that sticky options is -kb is the closest thing we have
+ # to testing that binary files work right on non-unix machines
+ # (until there is automated testing for such machines, of course).
+ dotest binfiles-5.5a1 "${testcvs} status binfile" \
+"===================================================================
+File: binfile Status: Up-to-date
+
+ Working revision: 1\.1.*
+ Repository revision: 1\.1 ${CVSROOT_DIRNAME}/first-dir/binfile,v
+ Sticky Tag: (none)
+ Sticky Date: (none)
+ Sticky Options: -kb"
+
# Test whether the default options from the RCS file are
# also used when operating on files instead of whole
# directories
@@ -15542,6 +16696,22 @@ File: binfile Status: Up-to-date
Sticky Options: -kb"
cd ../..
rm -r 3
+ # test that "-kk" does not override "-kb"
+ mkdir 3; cd 3
+ dotest binfiles-5.5c0 "${testcvs} -q co -kk first-dir/binfile" \
+'U first-dir/binfile'
+ cd first-dir
+ dotest binfiles-5.5c1 "${testcvs} status binfile" \
+"===================================================================
+File: binfile Status: Up-to-date
+
+ Working revision: 1\.1.*
+ Repository revision: 1\.1 ${CVSROOT_DIRNAME}/first-dir/binfile,v
+ Sticky Tag: (none)
+ Sticky Date: (none)
+ Sticky Options: -kb"
+ cd ../..
+ rm -r 3
cd 2/first-dir
cp ../../1/binfile2.dat binfile
@@ -15564,11 +16734,13 @@ done"
cd ../../2/first-dir
echo 'edits in dir 2' >binfile
dotest binfiles-con1 "${testcvs} -q update" \
-"U binfile
-${PROG} update: nonmergeable file needs merge
+"$PROG update: nonmergeable file needs merge
${PROG} update: revision 1\.3 from repository is now in binfile
${PROG} update: file from working directory is now in \.#binfile\.1\.2
C binfile"
+
+ dotest_fail binfiles-con1b "$testcvs -q up" "C binfile"
+
dotest binfiles-con2 "cmp binfile ../../1/binfile.dat" ''
dotest binfiles-con3 "cat .#binfile.1.2" 'edits in dir 2'
@@ -15582,9 +16754,11 @@ done"
dotest binfiles-con5 "${testcvs} -q update" '[UP] binfile'
dotest binfiles-9 "${testcvs} -q update -A" ''
- dotest binfiles-10 "${testcvs} -q update -kk" '[UP] binfile'
+ # "-kk" no longer does anything with "-kb"
+ dotest binfiles-10 "${testcvs} -q update -kk" ''
dotest binfiles-11 "${testcvs} -q update" ''
- dotest binfiles-12 "${testcvs} -q update -A" '[UP] binfile'
+ # "-kk" no longer does anything with "-kb"
+ dotest binfiles-12 "${testcvs} -q update -A" ''
dotest binfiles-13 "${testcvs} -q update -A" ''
cd ../..
@@ -16590,27 +17764,13 @@ done"
cd ../..
cd m1/first-dir
echo "changed in m1" >aa
- if $remote; then
- # The tagged text code swallows up "U aa" but isn't yet up to
- # trying to figure out how it interacts with the "C aa" and
- # other stuff. The whole deal of having both is pretty iffy.
- dotest mwrap-7 "${testcvs} -nq update" \
+ dotest mwrap-7 "$testcvs -nq update" \
"${PROG} update: nonmergeable file needs merge
${PROG} update: revision 1\.2 from repository is now in aa
${PROG} update: file from working directory is now in \.#aa\.1\.1
-C aa
-U aa"
- else
- dotest mwrap-7 "${testcvs} -nq update" \
-"U aa
-${PROG} update: nonmergeable file needs merge
-${PROG} update: revision 1\.2 from repository is now in aa
-${PROG} update: file from working directory is now in \.#aa\.1\.1
C aa"
- fi
dotest mwrap-8 "${testcvs} -q update" \
-"U aa
-${PROG} update: nonmergeable file needs merge
+"$PROG update: nonmergeable file needs merge
${PROG} update: revision 1\.2 from repository is now in aa
${PROG} update: file from working directory is now in \.#aa\.1\.1
C aa"
@@ -17594,6 +18754,28 @@ ${log_rev3}
${log_rev2}
${log_trailer}"
+ # Test BASE pseudotag
+ dotest log-23 "${testcvs} log -rBASE file1" \
+"${log_header1}
+${log_tags1}
+${log_keyword}
+total revisions: 5; selected revisions: 1
+description:
+${log_rev2b}
+${log_trailer}"
+
+ dotest log-24 "${testcvs} -q up -r1.2 file1" "[UP] file1"
+ dotest log-25 "${testcvs} log -rBASE file1" \
+"${log_header1}
+${log_tags1}
+${log_keyword}
+total revisions: 5; selected revisions: 1
+description:
+${log_rev2}
+${log_trailer}"
+
+ dotest log-26 "${testcvs} -q up -rbranch file1" "[UP] file1"
+
# Now the same tests but with rlog
dotest log-r11 "${testcvs} rlog first-dir/file1" \
@@ -17817,6 +18999,26 @@ ${log_rev3}
${log_rev2}
${log_trailer}"
+ # Test BASE pseudotag
+ dotest log-r23 "${testcvs} rlog -rBASE first-dir/file1" \
+"${PROG} rlog: warning: no revision .BASE. in .${CVSROOT_DIRNAME}/first-dir/file1,v.
+${rlog_header1}
+${log_tags1}
+${log_keyword}
+total revisions: 5; selected revisions: 0
+description:
+${log_trailer}"
+
+ dotest log-r24 "${testcvs} -q up -r1.2 file1" "[UP] file1"
+ dotest log-r25 "${testcvs} rlog -rBASE first-dir/file1" \
+"${PROG} rlog: warning: no revision .BASE. in .${CVSROOT_DIRNAME}/first-dir/file1,v.
+${rlog_header1}
+${log_tags1}
+${log_keyword}
+total revisions: 5; selected revisions: 0
+description:
+${log_trailer}"
+
# Test when head is dead
dotest log-d0 "${testcvs} -q up -A" \
@@ -18428,47 +19630,47 @@ done"
"
Annotations for file1
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
-1\.1 (${username} *[0-9a-zA-Z-]*): this
-1\.1 (${username} *[0-9a-zA-Z-]*): is
-1\.2 (${username} *[0-9a-zA-Z-]*): a
-1\.3 (${username} *[0-9a-zA-Z-]*): trunk file
-1\.2 (${username} *[0-9a-zA-Z-]*):
-1\.2 (${username} *[0-9a-zA-Z-]*): with
-1\.2 (${username} *[0-9a-zA-Z-]*): a
-1\.2 (${username} *[0-9a-zA-Z-]*): blank
-1\.2 (${username} *[0-9a-zA-Z-]*): line"
+1\.1 ($username8 *[0-9a-zA-Z-]*): this
+1\.1 ($username8 *[0-9a-zA-Z-]*): is
+1\.2 ($username8 *[0-9a-zA-Z-]*): a
+1\.3 ($username8 *[0-9a-zA-Z-]*): trunk file
+1\.2 ($username8 *[0-9a-zA-Z-]*):
+1\.2 ($username8 *[0-9a-zA-Z-]*): with
+1\.2 ($username8 *[0-9a-zA-Z-]*): a
+1\.2 ($username8 *[0-9a-zA-Z-]*): blank
+1\.2 ($username8 *[0-9a-zA-Z-]*): line"
dotest ann-11 "${testcvs} ann -r br" \
"
Annotations for file1
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
-1\.1 (${username} *[0-9a-zA-Z-]*): this
-1\.1 (${username} *[0-9a-zA-Z-]*): is
-1\.2 (${username} *[0-9a-zA-Z-]*): a
-1\.1 (${username} *[0-9a-zA-Z-]*): file
-1\.2 (${username} *[0-9a-zA-Z-]*):
-1\.2 (${username} *[0-9a-zA-Z-]*): with
-1\.2 (${username} *[0-9a-zA-Z-]*): a
-1\.2 (${username} *[0-9a-zA-Z-]*): blank
-1\.2 (${username} *[0-9a-zA-Z-]*): line
-1\.2\.2\.1 (${username} *[0-9a-zA-Z-]*): and some
-1\.2\.2\.1 (${username} *[0-9a-zA-Z-]*): branched content"
+1\.1 ($username8 *[0-9a-zA-Z-]*): this
+1\.1 ($username8 *[0-9a-zA-Z-]*): is
+1\.2 ($username8 *[0-9a-zA-Z-]*): a
+1\.1 ($username8 *[0-9a-zA-Z-]*): file
+1\.2 ($username8 *[0-9a-zA-Z-]*):
+1\.2 ($username8 *[0-9a-zA-Z-]*): with
+1\.2 ($username8 *[0-9a-zA-Z-]*): a
+1\.2 ($username8 *[0-9a-zA-Z-]*): blank
+1\.2 ($username8 *[0-9a-zA-Z-]*): line
+1\.2\.2\.1 ($username8 *[0-9a-zA-Z-]*): and some
+1\.2\.2\.1 ($username8 *[0-9a-zA-Z-]*): branched content"
# 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
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
-1\.1 (${username} *[0-9a-zA-Z-]*): this
-1\.1 (${username} *[0-9a-zA-Z-]*): is
-1\.2 (${username} *[0-9a-zA-Z-]*): a
-1\.1 (${username} *[0-9a-zA-Z-]*): file
-1\.2 (${username} *[0-9a-zA-Z-]*):
-1\.2 (${username} *[0-9a-zA-Z-]*): with
-1\.2 (${username} *[0-9a-zA-Z-]*): a
-1\.2 (${username} *[0-9a-zA-Z-]*): blank
-1\.2 (${username} *[0-9a-zA-Z-]*): line
-1\.2\.2\.1 (${username} *[0-9a-zA-Z-]*): and some
-1\.2\.2\.1 (${username} *[0-9a-zA-Z-]*): branched content"
+1\.1 ($username8 *[0-9a-zA-Z-]*): this
+1\.1 ($username8 *[0-9a-zA-Z-]*): is
+1\.2 ($username8 *[0-9a-zA-Z-]*): a
+1\.1 ($username8 *[0-9a-zA-Z-]*): file
+1\.2 ($username8 *[0-9a-zA-Z-]*):
+1\.2 ($username8 *[0-9a-zA-Z-]*): with
+1\.2 ($username8 *[0-9a-zA-Z-]*): a
+1\.2 ($username8 *[0-9a-zA-Z-]*): blank
+1\.2 ($username8 *[0-9a-zA-Z-]*): line
+1\.2\.2\.1 ($username8 *[0-9a-zA-Z-]*): and some
+1\.2\.2\.1 ($username8 *[0-9a-zA-Z-]*): branched content"
dotest_fail ann-14 "${testcvs} ann -r bill-clintons-chastity file1" \
"${PROG} \[annotate aborted\]: no such tag bill-clintons-chastity"
@@ -18480,46 +19682,46 @@ Annotations for file1
"
Annotations for first-dir/file1
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
-1\.1 (${username} *[0-9a-zA-Z-]*): this
-1\.1 (${username} *[0-9a-zA-Z-]*): is
-1\.2 (${username} *[0-9a-zA-Z-]*): a
-1\.3 (${username} *[0-9a-zA-Z-]*): trunk file
-1\.2 (${username} *[0-9a-zA-Z-]*):
-1\.2 (${username} *[0-9a-zA-Z-]*): with
-1\.2 (${username} *[0-9a-zA-Z-]*): a
-1\.2 (${username} *[0-9a-zA-Z-]*): blank
-1\.2 (${username} *[0-9a-zA-Z-]*): line"
+1\.1 ($username8 *[0-9a-zA-Z-]*): this
+1\.1 ($username8 *[0-9a-zA-Z-]*): is
+1\.2 ($username8 *[0-9a-zA-Z-]*): a
+1\.3 ($username8 *[0-9a-zA-Z-]*): trunk file
+1\.2 ($username8 *[0-9a-zA-Z-]*):
+1\.2 ($username8 *[0-9a-zA-Z-]*): with
+1\.2 ($username8 *[0-9a-zA-Z-]*): a
+1\.2 ($username8 *[0-9a-zA-Z-]*): blank
+1\.2 ($username8 *[0-9a-zA-Z-]*): line"
dotest ann-r11 "${testcvs} rann -r br first-dir" \
"
Annotations for first-dir/file1
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
-1\.1 (${username} *[0-9a-zA-Z-]*): this
-1\.1 (${username} *[0-9a-zA-Z-]*): is
-1\.2 (${username} *[0-9a-zA-Z-]*): a
-1\.1 (${username} *[0-9a-zA-Z-]*): file
-1\.2 (${username} *[0-9a-zA-Z-]*):
-1\.2 (${username} *[0-9a-zA-Z-]*): with
-1\.2 (${username} *[0-9a-zA-Z-]*): a
-1\.2 (${username} *[0-9a-zA-Z-]*): blank
-1\.2 (${username} *[0-9a-zA-Z-]*): line
-1\.2\.2\.1 (${username} *[0-9a-zA-Z-]*): and some
-1\.2\.2\.1 (${username} *[0-9a-zA-Z-]*): branched content"
+1\.1 ($username8 *[0-9a-zA-Z-]*): this
+1\.1 ($username8 *[0-9a-zA-Z-]*): is
+1\.2 ($username8 *[0-9a-zA-Z-]*): a
+1\.1 ($username8 *[0-9a-zA-Z-]*): file
+1\.2 ($username8 *[0-9a-zA-Z-]*):
+1\.2 ($username8 *[0-9a-zA-Z-]*): with
+1\.2 ($username8 *[0-9a-zA-Z-]*): a
+1\.2 ($username8 *[0-9a-zA-Z-]*): blank
+1\.2 ($username8 *[0-9a-zA-Z-]*): line
+1\.2\.2\.1 ($username8 *[0-9a-zA-Z-]*): and some
+1\.2\.2\.1 ($username8 *[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
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
-1\.1 (${username} *[0-9a-zA-Z-]*): this
-1\.1 (${username} *[0-9a-zA-Z-]*): is
-1\.2 (${username} *[0-9a-zA-Z-]*): a
-1\.1 (${username} *[0-9a-zA-Z-]*): file
-1\.2 (${username} *[0-9a-zA-Z-]*):
-1\.2 (${username} *[0-9a-zA-Z-]*): with
-1\.2 (${username} *[0-9a-zA-Z-]*): a
-1\.2 (${username} *[0-9a-zA-Z-]*): blank
-1\.2 (${username} *[0-9a-zA-Z-]*): line
-1\.2\.2\.1 (${username} *[0-9a-zA-Z-]*): and some
-1\.2\.2\.1 (${username} *[0-9a-zA-Z-]*): branched content"
+1\.1 ($username8 *[0-9a-zA-Z-]*): this
+1\.1 ($username8 *[0-9a-zA-Z-]*): is
+1\.2 ($username8 *[0-9a-zA-Z-]*): a
+1\.1 ($username8 *[0-9a-zA-Z-]*): file
+1\.2 ($username8 *[0-9a-zA-Z-]*):
+1\.2 ($username8 *[0-9a-zA-Z-]*): with
+1\.2 ($username8 *[0-9a-zA-Z-]*): a
+1\.2 ($username8 *[0-9a-zA-Z-]*): blank
+1\.2 ($username8 *[0-9a-zA-Z-]*): line
+1\.2\.2\.1 ($username8 *[0-9a-zA-Z-]*): and some
+1\.2\.2\.1 ($username8 *[0-9a-zA-Z-]*): branched content"
dotest_fail ann-r14 "${testcvs} rann -r bill-clintons-chastity first-dir/file1" \
"${PROG} \[rannotate aborted\]: no such tag bill-clintons-chastity"
@@ -18566,8 +19768,8 @@ done"
"
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"
+1.2 ($username8 *[0-9a-zA-Z-]*): "'\$'"Id: $file,v 1.1 [0-9/]* [0-9:]* $username Exp "'\$'"
+1.2 ($username8 *[0-9a-zA-Z-]*): line2"
cd ../..
rm -rf 1
@@ -18585,24 +19787,22 @@ Annotations for $file
# local.
if $remote; then
+ # Use :ext: rather than :fork:. Most of the tests use :fork:,
+ # so we want to make sure that we test :ext: _somewhere_.
+ # Make sure 'rsh' works first.
+ depends_on_rsh "$CVS_RSH"
+ if test $? -eq 77; then
+ skip crerepos "$skipreason"
+ continue
+ fi
+
# For remote, just create the repository. We don't yet do
# the various other tests above for remote but that should be
# changed.
mkdir crerepos
mkdir crerepos/CVSROOT
- # Use :ext: rather than :fork:. Most of the tests use :fork:,
- # so we want to make sure that we test :ext: _somewhere_.
-
- # Maybe a bit dubious in the sense that people need to
- # have rsh working to run the tests, but at least it
- # isn't inetd :-). Might want to think harder about this -
- # maybe try :ext:, and if it fails, print a (single, nice)
- # message and fall back to :fork:. Maybe testing :ext:
- # with our own CVS_RSH rather than worrying about a system one
- # would do the trick.
-
- # Make sure server ignores real ${HOME}/.cvsrc:
+ # Make sure server ignores real ${HOME}/.cvsrc:
cat >$TESTDIR/cvs-setHome <<EOF
#!/bin/sh
HOME=$HOME
@@ -18613,20 +19813,7 @@ EOF
# Note that we set CVS_SERVER at the beginning.
CVS_SERVER=$TESTDIR/cvs-setHome; export CVS_SERVER
-
- if test -n "$remotehost"; then
- CREREPOS_ROOT=:ext:$remotehost${TESTDIR}/crerepos
- else
- CREREPOS_ROOT=:ext:`hostname`:${TESTDIR}/crerepos
- fi
-
- # If we're going to do remote testing, make sure 'rsh' works first.
- host="`hostname`"
- if test "x`${CVS_RSH} $host -n 'echo hi'`" != "xhi"; then
- echo "ERROR: cannot test remote CVS, because \`${CVS_RSH} $host' fails." >&2
- exit 1
- fi
-
+ CREREPOS_ROOT=:ext:$host$TESTDIR/crerepos
else
# First, if the repository doesn't exist at all...
@@ -18704,8 +19891,10 @@ ${PROG} \[[a-z]* aborted\]: Bad CVSROOT: .:ext:${hostname}:crerepos.\."
# 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} \[checkout aborted\]: end of file from server (consult above messages if any)" \
-"${PROG} \[checkout aborted\]: received broken pipe signal"
+"${PROG} \[checkout aborted\]: .*" \
+"${PROG} checkout: CVSROOT is set for a remote access method but your
+${PROG} checkout: CVS executable doesn't support it\.
+${PROG} \[checkout aborted\]: Bad CVSROOT: .\.\./crerepos.\."
cd ..
rm -r 1
@@ -19514,6 +20703,125 @@ File: file1 Status: Up-to-date
rm -rf ${CVSROOT_DIRNAME}/rcs4-dir
;;
+
+
+ rcs5)
+ # Some tests of the $Log keyword and log message without a trailing
+ # EOL. This used to look ugly and, in the worst case, could cause
+ # a seg fault due to a buffer overflow.
+ #
+ # Note that it should not be possible to create this situation via a
+ # CVS server (and any client), since the server itself inserts the
+ # trailing EOL onto log messages that are missing one. Still, we
+ # shouldn't segfault due to a corrupt RCS file and I think that a log
+ # message without the trailing EOL doesn't actually violate the RCS
+ # spec, though it doesn't appear to be possible to create such a log
+ # message using RCS 5.7.
+
+ mkdir $CVSROOT_DIRNAME/rcs5
+ cat <<\EOF >$CVSROOT_DIRNAME/rcs5/file1,v
+head 1.1;
+access;
+symbols;
+locks;
+expand kv;
+
+1.1 date 2007.03.20.04.03.02; author jeremiah; state Ext; branches; next;
+
+desc
+@@
+
+1.1
+log
+@he always had very fine wine@
+text
+@line1
+/*
+EOF
+echo ' * Revision history: $''Log$' >>$CVSROOT_DIRNAME/rcs5/file1,v
+ cat <<\EOF >>$CVSROOT_DIRNAME/rcs5/file1,v
+ */
+line5
+@
+EOF
+
+ mkdir rcs5
+ cd rcs5
+ dotest rcs5-1 "$testcvs -Q co rcs5"
+ dotest rcs5-2 "cat rcs5/file1" \
+"line1
+/\\*
+ \\* Revision history: "'\$'"Log: file1,v "'\$'"
+ \\* Revision history: Revision 1\.1 2007/03/20 04:03:02 jeremiah
+ \\* Revision history: he always had very fine wine
+ \\* Revision history:
+ \\*/
+line5"
+
+ cd ..
+ rm -r rcs5
+ rm -rf $CVSROOT_DIRNAME/rcs5
+ ;;
+
+
+
+ rcs6)
+ # Test that CVS notices a specific type of corruption in the RCS
+ # archive. In the past, this type of corruption had turned up after
+ # a user ineptly attempted to delete a revision from an arcvhive
+ # manually.
+ mkdir rcs6; cd rcs6
+
+ # Make the project.
+ dotest rcs6-init-1 "$testcvs -Q co -ld top .; cd top"
+ mkdir rcs6
+ dotest rcs6-init-2 "$testcvs -Q add rcs6"
+ cd rcs6
+
+ # Populate it.
+ echo some words >afile
+ dotest rcs6-init-3 "$testcvs -Q add afile"
+ dotest rcs6-init-4 "$testcvs -Q ci -mnewfile afile" \
+"RCS file: $CVSROOT_DIRNAME/rcs6/afile,v
+done
+Checking in afile;
+$CVSROOT_DIRNAME/rcs6/afile,v <-- afile
+initial revision: 1\.1
+done"
+ echo more words >>afile
+ dotest rcs6-init-5 "$testcvs -Q ci -mrev2 afile" \
+"Checking in afile;
+$CVSROOT_DIRNAME/rcs6/afile,v <-- afile
+new revision: 1\.2; previous revision: 1\.1
+done"
+
+ # Corrupt the archive.
+ sed -e '8,12d' \
+ -e 's/^head 1\.2/head 1.1/' \
+ <$CVSROOT_DIRNAME/rcs6/afile,v \
+ >$CVSROOT_DIRNAME/rcs6/cfile,v
+
+ # Update used to work.
+ dotest_fail rcs6-1 "$testcvs -q up" \
+"$PROG \[update aborted\]: Expected head revision 1\.1, found 1\.2\."
+
+ # Then a commit hosed the archive further without any warnings.
+ # Updating to an old revision (e.g. 1.1) would have reported the
+ # corruption. A second commit would have deleted data from the
+ # file.
+
+ if $keep; then
+ echo Keeping $TESTDIR and exiting due to --keep
+ exit 0
+ fi
+
+ cd ../../..
+ rm -r rcs6
+ rm -rf $CVSROOT_DIRNAME/rcs6
+ ;;
+
+
+
lockfiles)
# Tests of CVS lock files.
# TODO-maybe: Add a test where we arrange for a loginfo
@@ -19583,6 +20891,86 @@ ${PROG} \[update aborted\]: cannot stat ${TESTDIR}/locks: No such file or direct
dotest lockfiles-8 "${testcvs} -q update" ""
dotest lockfiles-9 "${testcvs} -q co -l ." ""
+ ###
+ ### There are race conditions in the following tests, but hopefully
+ ### the 5 seconds the first process waits to remove the lockdir and
+ ### the 30 seconds CVS waits betweens checks will be significant
+ ### enough to render the case moot.
+ ###
+ # Considers the following cases:
+ #
+ # Lock Present
+ # Operation Allowed (case #)
+ #
+ # Read Write
+ # _______ ______
+ # Read |Yes (1) No (3)
+ # Write |No (7) No (9)
+ #
+ # Tests do not appear in same ordering as table. The odd numbering
+ # scheme maintains correspondance with a larger table on 1.12.x:
+ # 1. Read when read locks are present...
+ # 3. Don't read when write locks present...
+ # 7. Don't write when read locks are present...
+ # 9. Don't write when write locks are present...
+
+ # 3. Don't read when write locks present...
+ mkdir "$TESTDIR/locks/first-dir/#cvs.lock"
+ (sleep 5; rmdir "$TESTDIR/locks/first-dir/#cvs.lock")&
+ dotest lockfiles-10 "$testcvs -q co -l first-dir" \
+"$PROG checkout: \[[0-9:]*\] waiting for $username's lock in $CVSROOT_DIRNAME/first-dir
+$PROG checkout: \[[0-9:]*\] obtained lock in $CVSROOT_DIRNAME/first-dir"
+
+ # 1. Read when read locks are present...
+ touch "$TESTDIR/locks/first-dir/#cvs.rfl.test.lock"
+ dotest lockfiles-11 "$testcvs -q co -l first-dir"
+ rm "$TESTDIR/locks/first-dir/#cvs.rfl.test.lock"
+
+ # 7. Don't write when read locks are present...
+ echo I always have trouble coming up with witty text for the test files >>first-dir/sdir/ssdir/file1
+ touch "$TESTDIR/locks/first-dir/sdir/ssdir/#cvs.rfl.test.lock"
+ (sleep 5; rm "$TESTDIR/locks/first-dir/sdir/ssdir/#cvs.rfl.test.lock")&
+ dotest lockfiles-13 "$testcvs -q ci -mconflict first-dir" \
+"$PROG commit: \[[0-9:]*\] waiting for $username's lock in $CVSROOT_DIRNAME/first-dir/sdir/ssdir
+$PROG commit: \[[0-9:]*\] obtained lock in $CVSROOT_DIRNAME/first-dir/sdir/ssdir
+Checking in first-dir/sdir/ssdir/file1;
+$CVSROOT_DIRNAME/first-dir/sdir/ssdir/file1,v <-- file1
+new revision: 1\.2; previous revision: 1\.1
+done"
+
+ # 9. Don't write when write locks are present...
+ echo yet this poem would probably only give longfellow bile >>first-dir/sdir/ssdir/file1
+ mkdir "$TESTDIR/locks/first-dir/sdir/ssdir/#cvs.lock"
+ (sleep 5; rmdir "$TESTDIR/locks/first-dir/sdir/ssdir/#cvs.lock")&
+ dotest lockfiles-19 "$testcvs -q ci -mnot-up-to-date first-dir" \
+"$PROG commit: \[[0-9:]*\] waiting for $username's lock in $CVSROOT_DIRNAME/first-dir/sdir/ssdir
+$PROG commit: \[[0-9:]*\] obtained lock in $CVSROOT_DIRNAME/first-dir/sdir/ssdir
+Checking in first-dir/sdir/ssdir/file1;
+$CVSROOT_DIRNAME/first-dir/sdir/ssdir/file1,v <-- file1
+new revision: 1\.3; previous revision: 1\.2
+done"
+
+ # 10. Don't write when history locks are present...
+ echo have you ever heard a poem quite so vile\? >>first-dir/sdir/ssdir/file1
+ mkdir "$TESTDIR/locks/CVSROOT/#cvs.history.lock"
+ (sleep 5; rmdir "$TESTDIR/locks/CVSROOT/#cvs.history.lock")&
+ dotest lockfiles-20 "$testcvs -q ci -mnot-up-to-date first-dir" \
+"Checking in first-dir/sdir/ssdir/file1;
+$CVSROOT_DIRNAME/first-dir/sdir/ssdir/file1,v <-- file1
+new revision: 1\.4; previous revision: 1\.3
+done
+$PROG commit: \[[0-9:]*\] waiting for $username's lock in $CVSROOT_DIRNAME/CVSROOT
+$PROG commit: \[[0-9:]*\] obtained lock in $CVSROOT_DIRNAME/CVSROOT"
+
+ dotest lockfiles-21 "$testcvs -Q tag newtag first-dir"
+
+ rm -f $CVSROOT_DIRNAME/CVSROOT/val-tags
+ mkdir "$TESTDIR/locks/CVSROOT/#cvs.val-tags.lock"
+ (sleep 5; rmdir "$TESTDIR/locks/CVSROOT/#cvs.val-tags.lock")&
+ dotest lockfiles-22 "$testcvs -q up -r newtag first-dir" \
+"$PROG update: \[[0-9:]*\] waiting for $username's lock in $CVSROOT_DIRNAME/CVSROOT
+$PROG update: \[[0-9:]*\] obtained lock in $CVSROOT_DIRNAME/CVSROOT"
+
cd CVSROOT
echo "# nobody here but us comments" >config
dotest lockfiles-cleanup-1 "${testcvs} -q ci -m config-it" \
@@ -19892,6 +21280,149 @@ done"
rm -rf ${CVSROOT_DIRNAME}/first-dir
;;
+
+
+ sshstdio)
+ # CVS_RSH=ssh can have a problem with a non-blocking stdio
+ # in some cases. So, this test is all about testing :ext:
+ # with CVS_RSH=ssh. The problem is that not all machines
+ # will necessarily have ssh available, so be prepared to
+ # skip this test.
+
+ # Are we able to run find and use an ssh?
+ if $remote; then :; else
+ continue
+ fi
+
+ depends_on_ssh
+ if test $? -eq 77; then
+ skip sshstdio "$skipreason"
+ continue
+ fi
+
+ SSHSTDIO_ROOT=:ext:$host$CVSROOT_DIRNAME
+
+ mkdir sshstdio; cd sshstdio
+ dotest sshstdio-1 "$testcvs -d $SSHSTDIO_ROOT -q co -l ."
+ mkdir first-dir
+ dotest sshstdio-2 "$testcvs add first-dir" \
+ "Directory $CVSROOT_DIRNAME/first-dir added to the repository"
+ cd first-dir
+ a='aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
+ c='aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
+ # Generate 1024 lines of $a
+ cnt=0
+ echo $a > aaa
+ while [ $cnt -lt 5 ] ; do
+ cnt=`expr $cnt + 1` ;
+ mv aaa aaa.old
+ cat aaa.old aaa.old aaa.old aaa.old > aaa
+ done
+ dotest sshstdio-3 "$testcvs -q add aaa" \
+"$PROG add: use .$PROG commit. to add this file permanently"
+ dotest sshstdio-4 "$testcvs -q ci -mcreate aaa" \
+"RCS file: $CVSROOT_DIRNAME/first-dir/aaa,v
+done
+Checking in aaa;
+$CVSROOT_DIRNAME/first-dir/aaa,v <-- aaa
+initial revision: 1\.1
+done"
+ # replace lines 1, 512, 513, 1024 with $c
+ sed 510q < aaa > aaa.old
+ (echo $c; cat aaa.old; echo $c; \
+ echo $c; cat aaa.old; echo $c) > aaa
+ dotest sshstdio-5 "$testcvs -q ci -mmodify-it aaa" \
+"Checking in aaa;
+$CVSROOT_DIRNAME/first-dir/aaa,v <-- aaa
+new revision: 1\.2; previous revision: 1\.1
+done"
+ cat > wrapper.sh <<EOF
+#!$TESTSHELL
+exec "\$@" 2>&1 < /dev/null | cat
+EOF
+ chmod +x wrapper.sh
+ ./wrapper.sh \
+ $testcvs -z5 -Q diff --side-by-side -W 500 -r 1.1 -r 1.2 \
+ aaa \
+ |sed -e \
+'/^Write failed flushing stdout buffer\. $/d;
+ /^write stdout: Broken pipe $/d;
+ :retry;
+ /Write failed flushing stdout buffer\. $/{
+ N;
+ s/Write failed flushing stdout buffer\. \n//;
+ b retry;
+}
+ /write stdout: Broken pipe $/{
+ N;
+ s/write stdout: Broken pipe \n//;
+ b retry;
+}' \
+ > wrapper.dif
+
+ $testcvs -z5 -Q diff --side-by-side -W 500 -r 1.1 -r 1.2 \
+ aaa > good.dif
+
+ dotest sshstdio-6 "cmp wrapper.dif good.dif"
+
+ if $keep; then
+ echo Keeping $TESTDIR and exiting due to --keep
+ exit 0
+ fi
+
+ cd ../..
+ CVS_RSH=$save_CVS_RSH; export CVS_RSH
+ rm -r sshstdio
+ rm -rf $CVSROOT_DIRNAME/first-dir
+ ;;
+
+
+
+ parseroot2)
+ # Test some :ext: roots for consistancy.
+ if $remote; then :; else
+ continue
+ fi
+
+ depends_on_rsh "$CVS_RSH"
+ if test $? -eq 77; then
+ skip parseroot2 "$skipreason"
+ continue
+ fi
+
+ # Test checking out and subsequently updating with some different
+ # CVSROOTs.
+
+ # A standard case, hostname:dirname.
+ mkdir parseroot2; cd parseroot2
+ save_CVSROOT=$CVSROOT
+ CVSROOT=$host:$CVSROOT_DIRNAME
+ dotest parseroot2-1 "$testcvs -Q co CVSROOT"
+ cd CVSROOT
+ dotest parseroot2-2 "$testcvs -Q up"
+ cd ..
+
+ # A degenerate remote case, just the server name and the directory
+ # name, with no :'s to help parsing. It can be mistaken for a
+ # relative directory name.
+ rm -r CVSROOT
+ CVSROOT=$host$CVSROOT_DIRNAME
+ dotest parseroot2-3 "$testcvs -Q co CVSROOT"
+ cd CVSROOT
+ dotest parseroot2-4 "$testcvs -Q up"
+
+ if $keep; then
+ echo Keeping $TESTDIR and exiting due to --keep
+ exit 0
+ fi
+
+ cd ../..
+ CVSROOT=$save_CVSROOT
+ rm -r parseroot2
+ ;;
+
+
+
history)
# CVSROOT/history tests:
# history: various "cvs history" invocations
@@ -21226,24 +22757,24 @@ xx"
"
Annotations for file1
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
-1\.3 (${username} *[0-9a-zA-Z-]*): initial
-1\.4\.2\.1 (${username} *[0-9a-zA-Z-]*): xx "'\$'"Log: file1,v "'\$'"
-1\.4\.2\.1 (${username} *[0-9a-zA-Z-]*): xx Revision 1\.4 [0-9/]* [0-9:]* ${username}
-1\.4\.2\.1 (${username} *[0-9a-zA-Z-]*): xx First log line
-1\.4\.2\.1 (${username} *[0-9a-zA-Z-]*): xx Second log line
-1\.4\.2\.1 (${username} *[0-9a-zA-Z-]*): xx
-1\.4\.2\.1 (${username} *[0-9a-zA-Z-]*): br-change"
+1\.3 ($username8 *[0-9a-zA-Z-]*): initial
+1\.4\.2\.1 ($username8 *[0-9a-zA-Z-]*): xx "'\$'"Log: file1,v "'\$'"
+1\.4\.2\.1 ($username8 *[0-9a-zA-Z-]*): xx Revision 1\.4 [0-9/]* [0-9:]* $username
+1\.4\.2\.1 ($username8 *[0-9a-zA-Z-]*): xx First log line
+1\.4\.2\.1 ($username8 *[0-9a-zA-Z-]*): xx Second log line
+1\.4\.2\.1 ($username8 *[0-9a-zA-Z-]*): xx
+1\.4\.2\.1 ($username8 *[0-9a-zA-Z-]*): br-change"
dotest keywordlog-23 "${testcvs} ann -r HEAD file1" \
"
Annotations for file1
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
-1\.3 (${username} *[0-9a-zA-Z-]*): initial
-1\.5 (${username} *[0-9a-zA-Z-]*): xx "'\$'"Log: file1,v "'\$'"
-1\.5 (${username} *[0-9a-zA-Z-]*): xx Revision 1\.4 [0-9/]* [0-9:]* ${username}
-1\.5 (${username} *[0-9a-zA-Z-]*): xx First log line
-1\.5 (${username} *[0-9a-zA-Z-]*): xx Second log line
-1\.5 (${username} *[0-9a-zA-Z-]*): xx
-1\.5 (${username} *[0-9a-zA-Z-]*): change"
+1\.3 ($username8 *[0-9a-zA-Z-]*): initial
+1\.5 ($username8 *[0-9a-zA-Z-]*): xx "'\$'"Log: file1,v "'\$'"
+1\.5 ($username8 *[0-9a-zA-Z-]*): xx Revision 1\.4 [0-9/]* [0-9:]* $username
+1\.5 ($username8 *[0-9a-zA-Z-]*): xx First log line
+1\.5 ($username8 *[0-9a-zA-Z-]*): xx Second log line
+1\.5 ($username8 *[0-9a-zA-Z-]*): xx
+1\.5 ($username8 *[0-9a-zA-Z-]*): change"
cd ../..
#
@@ -21508,8 +23039,7 @@ diff -r1\.2 file1
# Here's the problem... shouldn't -kk a binary file...
rm file1
dotest keyword2-13 "${testcvs} -q update -A -kk -j branch" \
-"U binfile\.dat
-${PROG} update: warning: file1 was lost
+"${PROG} update: warning: file1 was lost
U file1
RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v
retrieving revision 1\.1
@@ -21524,13 +23054,13 @@ ${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1
new revision: 1\.3; previous revision: 1\.2
done"
- dotest_fail keyword2-15 "cmp binfile.dat ../binfile.dat" \
-"binfile\.dat \.\./binfile\.dat differ: char 13, line 2"
+ # "-kk" no longer corrupts binary files
+ dotest keyword2-15 "cmp binfile.dat ../binfile.dat" ''
# Okay, restore everything and make CVS try and merge a binary file...
+ # "-kk" no longer affects binary files
dotest keyword2-16 "${testcvs} -q update -A" \
-"[UP] binfile.dat
-[UP] file1"
+"[UP] file1"
dotest keyword2-17 "${testcvs} -q tag -b branch2" \
"T binfile\.dat
T file1"
@@ -21543,16 +23073,15 @@ T file1"
${CVSROOT_DIRNAME}/first-dir/binfile\.dat,v <-- binfile\.dat
new revision: 1\.1\.4\.1; previous revision: 1\.1
done"
+ # "-kk" no longer affects binary files
+
+ # XXXX: do not ask, why we get the "U binfile.dat" line twice
+ # looks like a bug!
dotest keyword2-20 "${testcvs} -q update -A -kk -j branch2" \
"U binfile\.dat
-RCS file: ${CVSROOT_DIRNAME}/first-dir/binfile\.dat,v
-retrieving revision 1\.1
-retrieving revision 1\.1\.4\.1
-Merging differences between 1\.1 and 1\.1\.4\.1 into binfile\.dat
+U binfile\.dat
U file1"
- # Yep, it's broke, 'cept for that gal in Hodunk who uses -kk
- # so that some files only merge when she says so. Time to clean up...
cd ../..
rm -r 1
rm -rf ${CVSROOT_DIRNAME}/first-dir
@@ -21744,6 +23273,8 @@ done"
# for checkout and update as well.
#
mkdir 1; cd 1
+ save_TZ=$TZ
+ TZ=UTC; export TZ
dotest tagdate-1 "${testcvs} -q co -l ." ''
mkdir first-dir
dotest tagdate-2 "${testcvs} add first-dir" \
@@ -21761,6 +23292,8 @@ Checking in file1;
${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1
initial revision: 1\.1
done"
+ date_T1=`getrlogdate -r1.1 first-dir/file1`
+
dotest tagdate-5 "${testcvs} -q tag -b br1" "T file1"
dotest tagdate-6 "${testcvs} -q tag -b br2" "T file1"
echo trunk-2 >file1
@@ -21769,6 +23302,8 @@ done"
${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1
new revision: 1\.2; previous revision: 1\.1
done"
+ date_T2=`getrlogdate -r1.2 first-dir/file1`
+
# We are testing -r -D where br1 is a (magic) branch without
# any revisions. First the case where br2 doesn't have any
# revisions either:
@@ -21780,6 +23315,7 @@ done"
${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1
new revision: 1\.1\.4\.1; previous revision: 1\.1
done"
+ date_T3=`getrlogdate -r1.1.4.1 first-dir/file1`
# Then the case where br2 does have revisions:
dotest tagdate-11 "${testcvs} -q update -p -r br1 -D now" "trunk-1"
@@ -21789,52 +23325,397 @@ done"
"${PROG} \[update aborted\]: argument to join may not contain a date specifier without a tag"
# And check export
- # Wish some shorter sleep interval would suffice, but I need to
- # guarantee that the point in time specified by the argument to -D
- # in tagdate-14 and tagdate-16
- # falls in the space of time between commits to br2 and I
- # figure 60 seconds is probably a large enough range to
- # account for most network file system delays and such...
- # as it stands, it takes between 1 and 2 seconds between
- # calling CVS on my machine and the -D argument being used to
- # recall the file revision and this timing will certainly vary
- # by several seconds between machines - dependant on CPUspeeds,
- # I/O speeds, load, etc.
- sleep 60
-
echo br2-2 >file1
dotest tagdate-13 "${testcvs} -q ci -m modify-2-on-br2" \
"Checking in file1;
${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1
new revision: 1\.1\.4\.2; previous revision: 1\.1\.4\.1
done"
+ date_T4=`getrlogdate -r1.1.4.2 first-dir/file1`
+
cd ../..
- mkdir 2; cd
- dotest tagdate-14 "${testcvs} -q export -r br2 -D'1 minute ago' first-dir" \
+ mkdir 2; cd 2
+ dotest tagdate-14 "${testcvs} -q export -r br2 -D'$date_T3' first-dir" \
"[UP] first-dir/file1"
dotest tagdate-15 "cat first-dir/file1" "br2-1"
# Now for annotate
cd ../1/first-dir
- dotest tagdate-16 "${testcvs} annotate -rbr2 -D'1 minute ago'" \
+ dotest tagdate-16 "${testcvs} annotate -rbr2 -D'$date_T3'" \
"
Annotations for file1
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
-1\.1\.4\.1 (${username} *[0-9a-zA-Z-]*): br2-1"
+1\.1\.4\.1 ($username8 *[0-9a-zA-Z-]*): br2-1"
dotest tagdate-17 "${testcvs} annotate -rbr2 -Dnow" \
"
Annotations for file1
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
-1\.1\.4\.2 (${username} *[0-9a-zA-Z-]*): br2-2"
+1\.1\.4\.2 ($username8 *[0-9a-zA-Z-]*): br2-2"
+
+ # Now check to see what happens when we add files to br2 and trunk
+ echo br2-1 > file3
+ dotest tagdate-18 "${testcvs} add file3" \
+"${PROG} add: scheduling file \`file3' for addition on branch \`br2'
+${PROG} add: use .${PROG} commit. to add this file permanently"
+ dotest tagdate-19 "${testcvs} -q ci -m add 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"
+ date_T5=`getrlogdate -r1.1 first-dir/file3`
+ date_T6=`getrlogdate -r1.1.2.1 first-dir/file3`
+
+ cd ../..
+ mkdir 3; cd 3
+ dotest tagdate-20 "${testcvs} -Q co first-dir" ''
+ cd first-dir
+ echo trunk-1 > file2
+ dotest tagdate-21 "${testcvs} add file2" \
+"${PROG} add: scheduling file .file2. for addition
+${PROG} add: use .${PROG} commit. to add this file permanently"
+ dotest tagdate-22 "${testcvs} -q ci -m add file2" \
+"RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v
+done
+Checking in file2;
+${CVSROOT_DIRNAME}/first-dir/file2,v <-- file2
+initial revision: 1\.1
+done"
+ date_T7=`getrlogdate -r1.1 first-dir/file2`
+ echo "trunk-2" >file2
+ dotest tagdate-23 "${testcvs} -q ci -m update file2" \
+"Checking in file2;
+${CVSROOT_DIRNAME}/first-dir/file2,v <-- file2
+new revision: 1\.2; previous revision: 1\.1
+done"
+ date_T8=`getrlogdate -r1.2 first-dir/file2`
+
+ cd ../../1/first-dir
+ echo br2-1 > file2
+ dotest tagdate-24 "${testcvs} add file2" \
+"${PROG} add: scheduling file \`file2' for addition on branch \`br2'
+${PROG} add: use .${PROG} commit. to add this file permanently"
+ dotest tagdate-25 "${testcvs} -q ci -m add file2" \
+"Checking in file2;
+${CVSROOT_DIRNAME}/first-dir/file2,v <-- file2
+new revision: 1\.2\.2\.2; previous revision: 1\.2\.2\.1
+done"
+ date_T9=`getrlogdate -r1.2.2.2 first-dir/file2`
+ cd ../..
+
+ # Time Rev Branch Comments
+ # T0 trunk first-dir created
+ # T1 1.1 trunk first-dir/file1 committed "trunk-1"
+ # br1 branch created
+ # br2 branch created
+ # T2 1.2 trunk first-dir/file1 committed "trunk-2"
+ # T3 1.1.4.1 br2 first-dir/file1 committed "br2-1"
+ # +60s
+ # T4 1.1.4.2 br2 first-dir/file1 committed "br2-2"
+ # T5 1.1 trunk first-dir/file3 dead
+ # T6 1.1.2.1 br2 first-dir/file3 committed "br2-1"
+ # T7 1.1 trunk first-dir/file2 committed "trunk-1"
+ # T8 1.2 trunk first-dir/file2 committed "trunk-2"
+ # T8 1.2.2.1 br2 first-dir/file2 dead
+ # T9 1.2.2.2 br2 first-dir/file2 committed "br2-1"
+ #
+
+ mkdir 4; cd 4
+ (echo Dates for tagdate-26-* are:;\
+ echo " date_T1='$date_T1'";\
+ echo " date_T2='$date_T2'";\
+ echo " date_T3='$date_T3'";\
+ echo " date_T4='$date_T4'";\
+ echo " date_T5='$date_T5'";\
+ echo " date_T6='$date_T6'";\
+ echo " date_T7='$date_T7'";\
+ echo " date_T8='$date_T8'";\
+ echo " date_T9='$date_T9'") >>$LOGFILE
+ dotest tagdate-26-trunk-t1 \
+"${testcvs} co -D'$date_T1' -d first-dir-trunk-t1 first-dir" \
+"${PROG} checkout: Updating first-dir-trunk-t1
+U first-dir-trunk-t1/file1"
+ dotest tagdate-26-br2-t1 \
+"${testcvs} co -r br2 -D'$date_T1' -d first-dir-br2-t1 first-dir" \
+"${PROG} checkout: Updating first-dir-br2-t1
+U first-dir-br2-t1/file1"
+ dotest tagdate-26-trunk-t2 \
+"${testcvs} co -D'$date_T2' -d first-dir-trunk-t2 first-dir" \
+"${PROG} checkout: Updating first-dir-trunk-t2
+U first-dir-trunk-t2/file1"
+ dotest tagdate-26-br2-t2 \
+"${testcvs} co -r br2 -D'$date_T2' -d first-dir-br2-t2 first-dir" \
+"${PROG} checkout: Updating first-dir-br2-t2
+U first-dir-br2-t2/file1"
+ dotest tagdate-26-br2-t3 \
+"${testcvs} co -r br2 -D'$date_T3' -d first-dir-br2-t3 first-dir" \
+"${PROG} checkout: Updating first-dir-br2-t3
+U first-dir-br2-t3/file1"
+ dotest tagdate-26-br2-t4 \
+"${testcvs} co -r br2 -D'$date_T4' -d first-dir-br2-t4 first-dir" \
+"${PROG} checkout: Updating first-dir-br2-t4
+U first-dir-br2-t4/file1"
+ dotest tagdate-26-br2-t6 \
+"${testcvs} co -r br2 -D'$date_T6' -d first-dir-br2-t6 first-dir" \
+"${PROG} checkout: Updating first-dir-br2-t6
+U first-dir-br2-t6/file1
+U first-dir-br2-t6/file3"
+ dotest tagdate-26-trunk-t7 \
+"${testcvs} co -D'$date_T7' -d first-dir-trunk-t7 first-dir" \
+"${PROG} checkout: Updating first-dir-trunk-t7
+U first-dir-trunk-t7/file1
+U first-dir-trunk-t7/file2"
+ dotest tagdate-26-br2-t7 \
+"${testcvs} co -r br2 -D'$date_T7' -d first-dir-br2-t7 first-dir" \
+"${PROG} checkout: Updating first-dir-br2-t7
+U first-dir-br2-t7/file1
+U first-dir-br2-t7/file3"
+ dotest tagdate-26-trunk-t8 \
+"${testcvs} co -D'$date_T8' -d first-dir-trunk-t8 first-dir" \
+"${PROG} checkout: Updating first-dir-trunk-t8
+U first-dir-trunk-t8/file1
+U first-dir-trunk-t8/file2"
+ dotest tagdate-26-br2-t8 \
+"${testcvs} co -r br2 -D'$date_T8' -d first-dir-br2-t8 first-dir" \
+"${PROG} checkout: Updating first-dir-br2-t8
+U first-dir-br2-t8/file1
+U first-dir-br2-t8/file3"
+ dotest tagdate-26-br2-t9 \
+"${testcvs} co -r br2 -D'$date_T9' -d first-dir-br2-t9 first-dir" \
+"${PROG} checkout: Updating first-dir-br2-t9
+U first-dir-br2-t9/file1
+U first-dir-br2-t9/file2
+U first-dir-br2-t9/file3"
+ dotest tagdate-27-trunk-t1 \
+"${testcvs} status first-dir-trunk-t1" \
+"${PROG} status: Examining first-dir-trunk-t1
+===================================================================
+File: file1 Status: Up-to-date
+
+ Working revision: 1\.1[^.]*
+ Repository revision: 1\.1 ${CVSROOT_DIRNAME}/first-dir/file1,v
+ Sticky Tag: (none)
+ Sticky Date: [0-9.]*
+ Sticky Options: (none)"
+ dotest tagdate-27-br2-t1 \
+"${testcvs} status first-dir-br2-t1" \
+"${PROG} status: Examining first-dir-br2-t1
+===================================================================
+File: file1 Status: Needs Patch
+
+ Working revision: 1\.1[^.]*
+ Repository revision: 1\.1\.4\.2 ${CVSROOT_DIRNAME}/first-dir/file1,v
+ Sticky Tag: br2 (branch: 1\.1\.4)
+ Sticky Date: (none)
+ Sticky Options: (none)"
+ dotest tagdate-27-trunk-t2 \
+"${testcvs} status first-dir-trunk-t2" \
+"${PROG} status: Examining first-dir-trunk-t2
+===================================================================
+File: file1 Status: Up-to-date
+
+ Working revision: 1\.2[^.]*
+ Repository revision: 1\.2 ${CVSROOT_DIRNAME}/first-dir/file1,v
+ Sticky Tag: (none)
+ Sticky Date: [0-9.]*
+ Sticky Options: (none)"
+ dotest tagdate-27-br2-t2 \
+"${testcvs} status first-dir-br2-t2" \
+"${PROG} status: Examining first-dir-br2-t2
+===================================================================
+File: file1 Status: Needs Patch
+
+ Working revision: 1\.1[^.]*
+ Repository revision: 1\.1\.4\.2 ${CVSROOT_DIRNAME}/first-dir/file1,v
+ Sticky Tag: br2 (branch: 1\.1\.4)
+ Sticky Date: (none)
+ Sticky Options: (none)"
+ dotest tagdate-27-br2-t3 \
+"${testcvs} status first-dir-br2-t3" \
+"${PROG} status: Examining first-dir-br2-t3
+===================================================================
+File: file1 Status: Needs Patch
+
+ Working revision: 1\.1\.4\.1[^.]*
+ Repository revision: 1\.1\.4\.2 ${CVSROOT_DIRNAME}/first-dir/file1,v
+ Sticky Tag: br2 (branch: 1\.1\.4)
+ Sticky Date: (none)
+ Sticky Options: (none)"
+ dotest tagdate-27-br2-t4 \
+"${testcvs} status first-dir-br2-t4" \
+"${PROG} status: Examining first-dir-br2-t4
+===================================================================
+File: file1 Status: Up-to-date
+
+ Working revision: 1\.1\.4\.2[^.]*
+ Repository revision: 1\.1\.4\.2 ${CVSROOT_DIRNAME}/first-dir/file1,v
+ Sticky Tag: br2 (branch: 1\.1\.4)
+ Sticky Date: (none)
+ Sticky Options: (none)"
+ dotest tagdate-27-br2-t6 \
+"${testcvs} status first-dir-br2-t6" \
+"${PROG} status: Examining first-dir-br2-t6
+===================================================================
+File: file1 Status: Up-to-date
+
+ Working revision: 1\.1\.4\.2[^.]*
+ Repository revision: 1\.1\.4\.2 ${CVSROOT_DIRNAME}/first-dir/file1,v
+ Sticky Tag: br2 (branch: 1\.1\.4)
+ Sticky Date: (none)
+ Sticky Options: (none)
+
+===================================================================
+File: file3 Status: Up-to-date
+
+ Working revision: 1\.1\.2\.1[^.]*
+ Repository revision: 1\.1\.2\.1 ${CVSROOT_DIRNAME}/first-dir/Attic/file3,v
+ Sticky Tag: br2 (branch: 1\.1\.2)
+ Sticky Date: (none)
+ Sticky Options: (none)"
+ dotest tagdate-27-trunk-t7 \
+"${testcvs} status first-dir-trunk-t7" \
+"${PROG} status: Examining first-dir-trunk-t7
+===================================================================
+File: file1 Status: Up-to-date
+
+ Working revision: 1\.2[^.]*
+ Repository revision: 1\.2 ${CVSROOT_DIRNAME}/first-dir/file1,v
+ Sticky Tag: (none)
+ Sticky Date: [0-9.]*
+ Sticky Options: (none)
+
+===================================================================
+File: file2 Status: Up-to-date
+
+ Working revision: 1\.1[^.]*
+ Repository revision: 1\.1 ${CVSROOT_DIRNAME}/first-dir/file2,v
+ Sticky Tag: (none)
+ Sticky Date: [0-9.]*
+ Sticky Options: (none)"
+ dotest tagdate-27-br2-t7 \
+"${testcvs} status first-dir-br2-t7" \
+"${PROG} status: Examining first-dir-br2-t7
+===================================================================
+File: file1 Status: Up-to-date
+
+ Working revision: 1\.1\.4\.2[^.]*
+ Repository revision: 1\.1\.4\.2 ${CVSROOT_DIRNAME}/first-dir/file1,v
+ Sticky Tag: br2 (branch: 1\.1\.4)
+ Sticky Date: (none)
+ Sticky Options: (none)
+
+===================================================================
+File: file3 Status: Up-to-date
+
+ Working revision: 1\.1\.2\.1[^.]*
+ Repository revision: 1\.1\.2\.1 ${CVSROOT_DIRNAME}/first-dir/Attic/file3,v
+ Sticky Tag: br2 (branch: 1\.1\.2)
+ Sticky Date: (none)
+ Sticky Options: (none)"
+ dotest tagdate-27-trunk-t8 \
+"${testcvs} status first-dir-trunk-t8" \
+"${PROG} status: Examining first-dir-trunk-t8
+===================================================================
+File: file1 Status: Up-to-date
+
+ Working revision: 1\.2[^.]*
+ Repository revision: 1\.2 ${CVSROOT_DIRNAME}/first-dir/file1,v
+ Sticky Tag: (none)
+ Sticky Date: [0-9.]*
+ Sticky Options: (none)
+
+===================================================================
+File: file2 Status: Up-to-date
+
+ Working revision: 1\.2[^.]*
+ Repository revision: 1\.2 ${CVSROOT_DIRNAME}/first-dir/file2,v
+ Sticky Tag: (none)
+ Sticky Date: [0-9.]*
+ Sticky Options: (none)"
+ dotest tagdate-27-br2-t8 \
+"${testcvs} status first-dir-br2-t8" \
+"${PROG} status: Examining first-dir-br2-t8
+===================================================================
+File: file1 Status: Up-to-date
+
+ Working revision: 1\.1\.4\.2[^.]*
+ Repository revision: 1\.1\.4\.2 ${CVSROOT_DIRNAME}/first-dir/file1,v
+ Sticky Tag: br2 (branch: 1\.1\.4)
+ Sticky Date: (none)
+ Sticky Options: (none)
+
+===================================================================
+File: file3 Status: Up-to-date
+
+ Working revision: 1\.1\.2\.1[^.]*
+ Repository revision: 1\.1\.2\.1 ${CVSROOT_DIRNAME}/first-dir/Attic/file3,v
+ Sticky Tag: br2 (branch: 1\.1\.2)
+ Sticky Date: (none)
+ Sticky Options: (none)"
+ dotest tagdate-27-br2-t9 \
+"${testcvs} status first-dir-br2-t9" \
+"${PROG} status: Examining first-dir-br2-t9
+===================================================================
+File: file1 Status: Up-to-date
+
+ Working revision: 1\.1\.4\.2[^.]*
+ Repository revision: 1\.1\.4\.2 ${CVSROOT_DIRNAME}/first-dir/file1,v
+ Sticky Tag: br2 (branch: 1\.1\.4)
+ Sticky Date: (none)
+ Sticky Options: (none)
+
+===================================================================
+File: file2 Status: Up-to-date
+
+ Working revision: 1\.2\.2\.2[^.]*
+ Repository revision: 1\.2\.2\.2 ${CVSROOT_DIRNAME}/first-dir/file2,v
+ Sticky Tag: br2 (branch: 1\.2\.2)
+ Sticky Date: (none)
+ Sticky Options: (none)
+
+===================================================================
+File: file3 Status: Up-to-date
+
+ Working revision: 1\.1\.2\.1[^.]*
+ Repository revision: 1\.1\.2\.1 ${CVSROOT_DIRNAME}/first-dir/Attic/file3,v
+ Sticky Tag: br2 (branch: 1\.1\.2)
+ Sticky Date: (none)
+ Sticky Options: (none)"
+
+ # Now check the contents of the files
+ dotest tagdate-28-trunk-t1 'cat first-dir-trunk-t1/file1' 'trunk-1'
+ dotest tagdate-28-br2-t1 'cat first-dir-br2-t1/file1' 'trunk-1'
+ dotest tagdate-28-trunk-t2 'cat first-dir-trunk-t2/file1' 'trunk-2'
+ dotest tagdate-28-br2-t2 'cat first-dir-br2-t2/file1' 'trunk-1'
+ dotest tagdate-28-br2-t3 'cat first-dir-br2-t3/file1' 'br2-1'
+ dotest tagdate-28-br2-t4 'cat first-dir-br2-t4/file1' 'br2-2'
+ dotest tagdate-28-br2-t6a 'cat first-dir-br2-t6/file1' "br2-2"
+ dotest tagdate-28-br2-t6b 'cat first-dir-br2-t6/file3' "br2-1"
+ dotest tagdate-28-trunk-t7a 'cat first-dir-trunk-t7/file1' "trunk-2"
+ dotest tagdate-28-trunk-t7b 'cat first-dir-trunk-t7/file2' "trunk-1"
+ dotest tagdate-28-br2-t7a 'cat first-dir-br2-t7/file1' "br2-2"
+ dotest tagdate-28-br2-t7b 'cat first-dir-br2-t7/file3' "br2-1"
+ dotest tagdate-28-trunk-t8a 'cat first-dir-trunk-t8/file1' "trunk-2"
+ dotest tagdate-28-trunk-t8b 'cat first-dir-trunk-t8/file2' "trunk-2"
+ dotest tagdate-28-br2-t8a 'cat first-dir-br2-t8/file1' "br2-2"
+ dotest tagdate-28-br2-t8c 'cat first-dir-br2-t8/file3' "br2-1"
+ dotest tagdate-28-br2-t9a 'cat first-dir-br2-t9/file1' "br2-2"
+ dotest tagdate-28-br2-t9b 'cat first-dir-br2-t9/file2' "br2-1"
+ dotest tagdate-28-br2-t9c 'cat first-dir-br2-t9/file3' "br2-1"
+ cd ..
+
+ unset date_T1 date_T2 date_T3 date_T4 date_T5
+ unset date_T6 date_T7 date_T8 date_T9
+ TZ=$save_TZ
if $keep; then
echo Keeping ${TESTDIR} and exiting due to --keep
exit 0
fi
- cd ../..
- rm -r 1 2
+ rm -r 1 2 3 4
rm -rf ${CVSROOT_DIRNAME}/first-dir
;;
@@ -23143,13 +25024,13 @@ add
cat >${TESTDIR}/lockme <<EOF
#!${TESTSHELL}
-line=\`grep <\$1/\$2,v 'locks ${author}:1\.[0-9];'\`
+line=\`grep <\$1/\$2,v 'locks $anyusername:1\.[0-9];'\`
if test -z "\$line"; then
# It isn't locked
exit 0
else
- user=\`echo \$line | sed -e 's/locks \\(${author}\\):[0-9.]*;.*/\\1/'\`
- version=\`echo \$line | sed -e 's/locks ${author}:\\([0-9.]*\\);.*/\\1/'\`
+ user=\`echo \$line | sed -e 's/locks \\($anyusername\\):[0-9.]*;.*/\\1/'\`
+ version=\`echo \$line | sed -e 's/locks $anyusername:\\([0-9.]*\\);.*/\\1/'\`
echo "\$user has file a-lock locked for version \$version" >&2
exit 1
fi
@@ -26496,9 +28377,13 @@ Root ${CVSROOT_DIRNAME}
noop
EOF
+ # The "no such system user" error is occurring on at least one of
+ # our BSD 2.0.2 nightly test platforms.
dotest_fail pserver-4.2 \
"${testcvs} --allow-root=${CVSROOT_DIRNAME} pserver" \
-"error 0: root not allowed" <<EOF
+"error 0: root not allowed" \
+"E Fatal error, aborting\.
+error 0 root: no such system user" <<EOF
BEGIN AUTH REQUEST
${CVSROOT_DIRNAME}
dontroot
@@ -27596,28 +29481,56 @@ done"
#
# Test our exit directory so that tests that exit in an incorrect directory
# are noticed during single test runs.
+ #
+ # FIXME?
+ # Sparc Solaris 9 is dereferencing paths here as if /bin/pwd were
+ # called when /tmp is a symlink. This might be a new problem with this
+ # test, but since this was recently tested I think it more likely to be
+ # A Solaris issue.
if test "x$TESTDIR" != "x`pwd`"; then
fail "cleanup: PWD != TESTDIR (\``pwd`' != \`$TESTDIR')"
fi
- # Test our temp directory for cvs-serv* directories and cvsXXXXXX temp
- # files. We would like to not leave any behind.
- if $remote && ls $TMPDIR/cvs-serv* >/dev/null 2>&1; then
- # A true value means ls found files/directories with these names.
- # Give the server some time to finish, then retry.
- sleep 1
- if ls $TMPDIR/cvs-serv* >/dev/null 2>&1; then
- fail "Found cvs-serv* directories in $TMPDIR."
- fi
- fi
- if ls $TMPDIR/cvs?????? >/dev/null 2>&1; then
- # A true value means ls found files/directories with these names.
- fail "Found cvsXXXXXX temp files in $TMPDIR."
- fi
+ # Reset val-tags to a pristine state.
+ rm -f $CVSROOT_DIRNAME/CVSROOT/val-tags
+
+ verify_tmp_empty "post $what"
done # The big loop
-echo "OK, all tests completed."
+# Set up summary data for output.
+skippedoutput=
+warningsoutput=
+extendedinfo=
+if test $skipped -ne 0; then
+ skippedoutput="$skipped test group"
+ if test $skipped -ne 1; then
+ skippedoutput="${skippedoutput}s"
+ fi
+ skippedoutput="$skippedoutput skipped"
+fi
+if test $warnings -ne 0; then
+ warningsoutput="$warnings test"
+ if test $warnings -ne 1; then
+ warningsoutput="${warningsoutput}s"
+ fi
+ warningsoutput="$warningsoutput passed with warnings"
+fi
+if test -n "$skippedoutput" || test -n "$warningsoutput"; then
+ extendedinfo=" ("
+ if test -n "$skippedoutput"; then
+ extendedinfo="$extendedinfo$skippedoutput"
+ fi
+ if test -n "$skippedoutput" && test -n "$warningsoutput"; then
+ extendedinfo="$extendedinfo and "
+ fi
+ if test -n "$warningsoutput"; then
+ extendedinfo="$extendedinfo$warningsoutput"
+ fi
+ extendedinfo="$extendedinfo)"
+fi
+
+echo "OK, all $passed tests passed$extendedinfo."
# TODO:
# * Test `cvs update -d foo' (where foo does not exist).
diff --git a/contrib/cvs/src/server.c b/contrib/cvs/src/server.c
index bc6578d..29aab00 100644
--- a/contrib/cvs/src/server.c
+++ b/contrib/cvs/src/server.c
@@ -16,6 +16,8 @@
#include "getline.h"
#include "buffer.h"
+int server_active = 0;
+
#if defined(SERVER_SUPPORT) || defined(CLIENT_SUPPORT)
# ifdef HAVE_GSSAPI
/* This stuff isn't included solely with SERVER_SUPPORT since some of these
@@ -356,13 +358,20 @@ create_adm_p (base_dir, dir)
dir_where_cvsadm_lives = xmalloc (strlen (base_dir) + strlen (dir) + 100);
if (dir_where_cvsadm_lives == NULL)
+ {
+ free (p);
return ENOMEM;
+ }
/* Allocate some space for the temporary string in which we will
construct filenames. */
tmp = xmalloc (strlen (base_dir) + strlen (dir) + 100);
if (tmp == NULL)
+ {
+ free (p);
+ free (dir_where_cvsadm_lives);
return ENOMEM;
+ }
/* We make several passes through this loop. On the first pass,
@@ -1227,6 +1236,7 @@ serve_sticky (arg)
if (alloc_pending (80 + strlen (CVSADM_TAG)))
sprintf (pending_error_text, "E cannot write to %s", CVSADM_TAG);
pending_error = save_errno;
+ (void) fclose (f);
return;
}
if (fclose (f) == EOF)
@@ -1675,7 +1685,9 @@ serve_unchanged (arg)
* is allowed, but broken versions of WinCVS & TortoiseCVS rely on
* this behavior.
*/
- *timefield = '=';
+ if (*timefield != '+')
+ /* Skip this for entries with conflict markers. */
+ *timefield = '=';
break;
}
}
@@ -1746,7 +1758,10 @@ serve_is_modified (arg)
* is allowed, but broken versions of WinCVS & TortoiseCVS rely on
* this behavior.
*/
- *timefield = 'M';
+ if (*timefield != '+')
+ /* Skip this for entries with conflict markers. */
+ *timefield = 'M';
+
if (kopt != NULL)
{
if (alloc_pending (strlen (name) + 80))
@@ -1833,6 +1848,7 @@ serve_entry (arg)
cp = xmalloc (strlen (arg) + 2);
if (cp == NULL)
{
+ free (p);
pending_error = ENOMEM;
return;
}
@@ -2696,6 +2712,25 @@ set_nonblock_fd (fd)
+/*
+ * Set buffer FD to blocking I/O. Returns 0 for success or errno code.
+ */
+int
+set_block_fd (fd)
+ int fd;
+{
+ int flags;
+
+ flags = fcntl (fd, F_GETFL, 0);
+ if (flags < 0)
+ return errno;
+ if (fcntl (fd, F_SETFL, flags & ~O_NONBLOCK) < 0)
+ return errno;
+ return 0;
+}
+
+
+
static void
do_cvs_command (cmd_name, command)
char *cmd_name;
@@ -2919,22 +2954,31 @@ error \n");
{
char junk;
ssize_t status;
- while ((status = read (flowcontrol_pipe[0], &junk, 1)) > 0
- || (status == -1 && errno == EAGAIN));
+ set_block_fd (flowcontrol_pipe[0]);
+ while ((status = read (flowcontrol_pipe[0], &junk, 1)) > 0);
}
/* FIXME: No point in printing an error message with error(),
* as STDERR is already closed, but perhaps this could be syslogged?
*/
#endif
+ rcs_cleanup ();
+ Lock_Cleanup ();
+ /* Don't call server_cleanup - the parent will handle that. */
+#ifdef SYSTEM_CLEANUP
+ /* Hook for OS-specific behavior, for example socket subsystems on
+ NT and OS2 or dealing with windows and arguments on Mac. */
+ SYSTEM_CLEANUP ();
+#endif
exit (exitstatus);
}
/* OK, sit around getting all the input from the child. */
{
- struct buffer *stdoutbuf;
- struct buffer *stderrbuf;
- struct buffer *protocol_inbuf;
+ struct buffer *stdoutbuf = NULL;
+ struct buffer *stderrbuf = NULL;
+ struct buffer *protocol_inbuf = NULL;
+ int err_exit = 0;
/* Number of file descriptors to check in select (). */
int num_to_check;
int count_needed = 1;
@@ -2987,7 +3031,8 @@ error \n");
{
buf_output0 (buf_to_net, "E close failed\n");
print_error (errno);
- goto error_exit;
+ err_exit = 1;
+ goto child_finish;
}
stdout_pipe[1] = -1;
@@ -2995,7 +3040,8 @@ error \n");
{
buf_output0 (buf_to_net, "E close failed\n");
print_error (errno);
- goto error_exit;
+ err_exit = 1;
+ goto child_finish;
}
stderr_pipe[1] = -1;
@@ -3003,7 +3049,8 @@ error \n");
{
buf_output0 (buf_to_net, "E close failed\n");
print_error (errno);
- goto error_exit;
+ err_exit = 1;
+ goto child_finish;
}
protocol_pipe[1] = -1;
@@ -3012,7 +3059,8 @@ error \n");
{
buf_output0 (buf_to_net, "E close failed\n");
print_error (errno);
- goto error_exit;
+ err_exit = 1;
+ goto child_finish;
}
flowcontrol_pipe[0] = -1;
#endif /* SERVER_FLOWCONTROL */
@@ -3021,7 +3069,9 @@ error \n");
{
buf_output0 (buf_to_net, "E close failed\n");
print_error (errno);
- goto error_exit;
+ dev_null_fd = -1; /* Do not try to close it again. */
+ err_exit = 1;
+ goto child_finish;
}
dev_null_fd = -1;
@@ -3108,7 +3158,8 @@ error \n");
{
buf_output0 (buf_to_net, "E select failed\n");
print_error (errno);
- goto error_exit;
+ err_exit = 1;
+ goto child_finish;
}
} while (numfds < 0);
@@ -3141,7 +3192,8 @@ error \n");
{
buf_output0 (buf_to_net, "E buf_input_data failed\n");
print_error (status);
- goto error_exit;
+ err_exit = 1;
+ goto child_finish;
}
/*
@@ -3215,7 +3267,8 @@ error \n");
{
buf_output0 (buf_to_net, "E buf_input_data failed\n");
print_error (status);
- goto error_exit;
+ err_exit = 1;
+ goto child_finish;
}
/* What should we do with errors? syslog() them? */
@@ -3240,7 +3293,8 @@ error \n");
{
buf_output0 (buf_to_net, "E buf_input_data failed\n");
print_error (status);
- goto error_exit;
+ err_exit = 1;
+ goto child_finish;
}
/* What should we do with errors? syslog() them? */
@@ -3320,21 +3374,33 @@ E CVS locks may need cleaning up.\n");
command_pid = -1;
}
+ child_finish:
/*
* OK, we've waited for the child. By now all CVS locks are free
* and it's OK to block on the network.
*/
set_block (buf_to_net);
buf_flush (buf_to_net, 1);
- buf_shutdown (protocol_inbuf);
- buf_free (protocol_inbuf);
- protocol_inbuf = NULL;
- buf_shutdown (stderrbuf);
- buf_free (stderrbuf);
- stderrbuf = NULL;
- buf_shutdown (stdoutbuf);
- buf_free (stdoutbuf);
- stdoutbuf = NULL;
+ if (protocol_inbuf)
+ {
+ buf_shutdown (protocol_inbuf);
+ buf_free (protocol_inbuf);
+ protocol_inbuf = NULL;
+ }
+ if (stderrbuf)
+ {
+ buf_shutdown (stderrbuf);
+ buf_free (stderrbuf);
+ stderrbuf = NULL;
+ }
+ if (stdoutbuf)
+ {
+ buf_shutdown (stdoutbuf);
+ buf_free (stdoutbuf);
+ stdoutbuf = NULL;
+ }
+ if (err_exit)
+ goto error_exit;
}
if (errs)
@@ -3358,7 +3424,8 @@ E CVS locks may need cleaning up.\n");
command_pid = -1;
}
- close (dev_null_fd);
+ if (dev_null_fd >= 0)
+ close (dev_null_fd);
close (protocol_pipe[0]);
close (protocol_pipe[1]);
close (stderr_pipe[0]);
@@ -3686,6 +3753,10 @@ server_checked_in (file, update_dir, repository)
const char *update_dir;
const char *repository;
{
+ assert (file);
+ assert (update_dir);
+ assert (repository);
+
if (noexec)
return;
if (scratched_file != NULL && entries_line == NULL)
@@ -4119,6 +4190,7 @@ server_updated (finfo, vers, updated, mode, checksum, filebuf)
free (scratched_file);
scratched_file = NULL;
}
+ buf_send_counted (protocol);
return;
}
@@ -4197,7 +4269,6 @@ CVS server internal error: no mode in server_updated");
if (updated == SERVER_UPDATED)
{
Node *node;
- Entnode *entnode;
if (!(supported_response ("Created")
&& supported_response ("Update-existing")))
@@ -4215,9 +4286,13 @@ CVS server internal error: no mode in server_updated");
in case we end up processing it again (e.g. modules3-6
in the testsuite). */
node = findnode_fn (finfo->entries, finfo->file);
- entnode = node->data;
- free (entnode->timestamp);
- entnode->timestamp = xstrdup ("=");
+ assert (node != NULL);
+ if (node != NULL)
+ {
+ Entnode *entnode = node->data;
+ free (entnode->timestamp);
+ entnode->timestamp = xstrdup ("=");
+ }
}
else if (updated == SERVER_MERGED)
buf_output0 (protocol, "Merged ");
@@ -4505,9 +4580,12 @@ struct template_proc_data
static struct template_proc_data *tpd;
static int
+template_proc PROTO((const char *repository, const char *template));
+
+static int
template_proc (repository, template)
- char *repository;
- char *template;
+ const char *repository;
+ const char *template;
{
FILE *fp;
char buf[1024];
@@ -4785,6 +4863,7 @@ struct request requests[] =
REQ_LINE("Checkin-time", serve_checkin_time, 0),
REQ_LINE("Modified", serve_modified, RQ_ESSENTIAL),
REQ_LINE("Is-modified", serve_is_modified, 0),
+ REQ_LINE("Empty-conflicts", serve_noop, 0),
/* The client must send this request to interoperate with CVS 1.5
through 1.9 servers. The server must support it (although it can
@@ -5039,8 +5118,6 @@ server_cleanup (sig)
}
}
-int server_active = 0;
-
int
server (argc, argv)
int argc;
@@ -5472,6 +5549,7 @@ check_repository_password (username, password, repository, host_user_ptr)
{
if (!existence_error (errno))
error (0, errno, "cannot open %s", filename);
+ free (filename);
return 0;
}
@@ -5902,6 +5980,8 @@ pserver_authenticate_connection ()
printf ("I LOVE YOU\n");
fflush (stdout);
+ /* It's okay to skip rcs_cleanup() and Lock_Cleanup() here. */
+
#ifdef SYSTEM_CLEANUP
/* Hook for OS-specific behavior, for example socket subsystems on
NT and OS2 or dealing with windows and arguments on Mac. */
@@ -6415,12 +6495,10 @@ cvs_output (str, len)
size_t to_write = len;
const char *p = str;
- /* For symmetry with cvs_outerr we would call fflush (stderr)
- here. I guess the assumption is that stderr will be
- unbuffered, so we don't need to. That sounds like a sound
- assumption from the manpage I looked at, but if there was
- something fishy about it, my guess is that calling fflush
- would not produce a significant performance problem. */
+ /* Local users that do 'cvs status 2>&1' on a local repository
+ may see the informational messages out-of-order with the
+ status messages unless we use the fflush (stderr) here. */
+ fflush (stderr);
while (to_write > 0)
{
@@ -6477,16 +6555,16 @@ this client does not support writing binary files to stdout");
size_t written;
size_t to_write = len;
const char *p = str;
-
- /* For symmetry with cvs_outerr we would call fflush (stderr)
- here. I guess the assumption is that stderr will be
- unbuffered, so we don't need to. That sounds like a sound
- assumption from the manpage I looked at, but if there was
- something fishy about it, my guess is that calling fflush
- would not produce a significant performance problem. */
#ifdef USE_SETMODE_STDOUT
int oldmode;
+#endif
+ /* Local users that do 'cvs status 2>&1' on a local repository
+ may see the informational messages out-of-order with the
+ status messages unless we use the fflush (stderr) here. */
+ fflush (stderr);
+
+#ifdef USE_SETMODE_STDOUT
/* It is possible that this should be the same ifdef as
USE_SETMODE_BINARY but at least for the moment we keep them
separate. Mostly this is just laziness and/or a question
diff --git a/contrib/cvs/src/server.h b/contrib/cvs/src/server.h
index 20152d8..4c32386 100644
--- a/contrib/cvs/src/server.h
+++ b/contrib/cvs/src/server.h
@@ -1,8 +1,8 @@
/*
- * Copyright (c) 2003 The Free Software Foundation.
+ * Copyright (C) 1986-2005 The Free Software Foundation, Inc.
*
- * Portions Copyright (c) 2003 Derek Price
- * and Ximbiot <http://ximbiot.com>,
+ * Portions Copyright (C) 1998-2005 Derek Price, Ximbiot <http://ximbiot.com>,
+ * and others.
*
* You may distribute under the terms of the GNU General Public License as
* specified in the README file that comes with the CVS kit.
@@ -21,6 +21,12 @@
/*
+ * Nonzero if we are using the server. Used by various places to call
+ * server-specific functions.
+ */
+extern int server_active;
+
+/*
* Expand to `S', ` ', or the empty string. Used in `%s-> ...' trace printfs.
*/
#ifdef SERVER_SUPPORT
@@ -31,12 +37,6 @@
#ifdef SERVER_SUPPORT
-/*
- * Nonzero if we are using the server. Used by various places to call
- * server-specific functions.
- */
-extern int server_active;
-
/* Server functions exported to the rest of CVS. */
/* Run the server. */
diff --git a/contrib/cvs/src/stack.c b/contrib/cvs/src/stack.c
index edba905..22a1088 100644
--- a/contrib/cvs/src/stack.c
+++ b/contrib/cvs/src/stack.c
@@ -1,7 +1,8 @@
/*
- * Copyright (c) 2004, Free Software Foundation,
- * Derek Price,
- * & Ximbiot <http://ximbiot.com>.
+ * Copyright (C) 2004-2005 The Free Software Foundation, Inc.
+ *
+ * Portions Copyright (C) 2004-2005 Derek Price, Ximbiot <http://ximbiot.com>,
+ * and others.
*
* You may distribute under the terms of the GNU General Public License as
* specified in the README file that comes with the CVS source distribution.
diff --git a/contrib/cvs/src/stack.h b/contrib/cvs/src/stack.h
index 49ebdf8..822010b 100644
--- a/contrib/cvs/src/stack.h
+++ b/contrib/cvs/src/stack.h
@@ -1,7 +1,6 @@
/*
- * Copyright (c) 2004, Free Software Foundation,
- * Derek Price,
- * & Ximbiot <http://ximbiot.com>.
+ * Copyright (c) 2004-2005 The Free Software Foundation,
+ * Derek Price, and Ximbiot <http://ximbiot.com>.
*
* You may distribute under the terms of the GNU General Public License as
* specified in the README file that comes with the CVS source distribution.
diff --git a/contrib/cvs/src/status.c b/contrib/cvs/src/status.c
index 2e2957e..7a828ae 100644
--- a/contrib/cvs/src/status.c
+++ b/contrib/cvs/src/status.c
@@ -1,6 +1,11 @@
/*
- * Copyright (c) 1992, Brian Berliner and Jeff Polk
- * Copyright (c) 1989-1992, Brian Berliner
+ * Copyright (C) 1986-2005 The Free Software Foundation, Inc.
+ *
+ * Portions Copyright (C) 1998-2005 Derek Price, Ximbiot <http://ximbiot.com>,
+ * and others.
+ *
+ * Portions Copyright (C) 1992, Brian Berliner and Jeff Polk
+ * Portions Copyright (C) 1989-1992, Brian Berliner
*
* You may distribute under the terms of the GNU General Public License as
* specified in the README file that comes with the CVS source distribution.
@@ -141,9 +146,6 @@ status_fileproc (callerdat, finfo)
sstat = "Needs Patch";
break;
case T_CONFLICT:
- /* I _think_ that "unresolved" is correct; that if it has
- been resolved then the status will change. But I'm not
- sure about that. */
sstat = "Unresolved Conflict";
break;
case T_ADDED:
@@ -153,9 +155,7 @@ status_fileproc (callerdat, finfo)
sstat = "Locally Removed";
break;
case T_MODIFIED:
- if ( vers->ts_conflict
- && ( file_has_conflict ( finfo, vers->ts_conflict )
- || file_has_markers ( finfo ) ) )
+ if (file_has_markers (finfo))
sstat = "File had conflicts on merge";
else
/* Note that we do not re Register() the file when we spot
@@ -206,20 +206,15 @@ status_fileproc (callerdat, finfo)
}
else if (vers->vn_user[0] == '0' && vers->vn_user[1] == '\0')
cvs_output (" Working revision:\tNew file!\n", 0);
-#ifdef SERVER_SUPPORT
- else if (server_active)
- {
- cvs_output (" Working revision:\t", 0);
- cvs_output (vers->vn_user, 0);
- cvs_output ("\n", 0);
- }
-#endif
else
{
cvs_output (" Working revision:\t", 0);
cvs_output (vers->vn_user, 0);
- cvs_output ("\t", 0);
- cvs_output (vers->ts_rcs, 0);
+ if (!server_active)
+ {
+ cvs_output ("\t", 0);
+ cvs_output (vers->ts_rcs, 0);
+ }
cvs_output ("\n", 0);
}
diff --git a/contrib/cvs/src/subr.c b/contrib/cvs/src/subr.c
index da8d478..faa988a 100644
--- a/contrib/cvs/src/subr.c
+++ b/contrib/cvs/src/subr.c
@@ -1,6 +1,11 @@
/*
- * Copyright (c) 1992, Brian Berliner and Jeff Polk
- * Copyright (c) 1989-1992, Brian Berliner
+ * Copyright (C) 1986-2005 The Free Software Foundation, Inc.
+ *
+ * Portions Copyright (C) 1998-2005 Derek Price, Ximbiot <http://ximbiot.com>,
+ * and others.
+ *
+ * Portions Copyright (C) 1992, Brian Berliner and Jeff Polk
+ * Portions Copyright (C) 1989-1992, Brian Berliner
*
* You may distribute under the terms of the GNU General Public License as
* specified in the README file that comes with the CVS source distribution.
@@ -319,7 +324,6 @@ increment_revnum (rev)
const char *rev;
{
char *newrev, *p;
- int lastfield;
size_t len = strlen (rev);
newrev = xmalloc (len + 2);
@@ -645,59 +649,6 @@ make_message_rcslegal (message)
-/*
- * file_has_conflict
- *
- * This function compares the timestamp of a file with ts_conflict set
- * to the timestamp on the actual file and returns TRUE or FALSE based
- * on the results.
- *
- * This function does not check for actual markers in the file and
- * file_has_markers() function should be called when that is interesting.
- *
- * ASSUMPTIONS
- * The ts_conflict field is not NULL.
- *
- * RETURNS
- * TRUE ts_conflict matches the current timestamp.
- * FALSE The ts_conflict field does not match the file's
- * timestamp.
- */
-int
-file_has_conflict (finfo, ts_conflict)
- const struct file_info *finfo;
- const char *ts_conflict;
-{
- char *filestamp;
- int retcode;
-
- /* If ts_conflict is NULL, there was no merge since the last
- * commit and there can be no conflict.
- */
- assert (ts_conflict);
-
- /*
- * If the timestamp has changed and no
- * conflict indicators are found, it isn't a
- * conflict any more.
- */
-
-#ifdef SERVER_SUPPORT
- if (server_active)
- retcode = ts_conflict[0] == '=';
- else
-#endif /* SERVER_SUPPORT */
- {
- filestamp = time_stamp (finfo->file);
- retcode = !strcmp (ts_conflict, filestamp);
- free (filestamp);
- }
-
- return retcode;
-}
-
-
-
/* Does the file FINFO contain conflict markers? The whole concept
of looking at the contents of the file to figure out whether there are
unresolved conflicts is kind of bogus (people do want to manage files
diff --git a/contrib/cvs/src/tag.c b/contrib/cvs/src/tag.c
index ab4992f..6525eb2 100644
--- a/contrib/cvs/src/tag.c
+++ b/contrib/cvs/src/tag.c
@@ -1,6 +1,11 @@
/*
- * Copyright (c) 1992, Brian Berliner and Jeff Polk
- * Copyright (c) 1989-1992, Brian Berliner
+ * Copyright (C) 1986-2005 The Free Software Foundation, Inc.
+ *
+ * Portions Copyright (C) 1998-2005 Derek Price, Ximbiot <http://ximbiot.com>,
+ * and others.
+ *
+ * Portions Copyright (C) 1992, Brian Berliner and Jeff Polk
+ * Portions Copyright (C) 1989-1992, Brian Berliner
*
* You may distribute under the terms of the GNU General Public License as
* specified in the README file that comes with the CVS source distribution.
@@ -150,11 +155,9 @@ cvstag (argc, argv)
break;
case 'Q':
case 'q':
-#ifdef SERVER_SUPPORT
/* The CVS 1.5 client sends these options (in addition to
Global_option requests), so we must ignore them. */
if (!server_active)
-#endif
error (1, 0,
"-q or -Q must be specified before \"%s\"",
cvs_cmd_name);
@@ -352,11 +355,12 @@ rtag_proc (argc, argv, xwhere, mwhere, mfile, shorten, local_specified,
{
error (0, errno, "cannot chdir to %s", repository);
free (repository);
+ free (where);
return (1);
}
/* End section which is identical to patch_proc. */
- if (delete_flag || attic_too || (force_tag_match && numtag))
+ if (delete_flag || force_tag_move || attic_too || numtag)
which = W_REPOS | W_ATTIC;
else
which = W_REPOS;
@@ -1132,6 +1136,170 @@ val_fileproc (callerdat, finfo)
+/* This routine determines whether a tag appears in CVSROOT/val-tags.
+ *
+ * The val-tags file will be open read-only when IDB is NULL. Since writes to
+ * val-tags always append to it, the lack of locking is okay. The worst case
+ * race condition might misinterpret a partially written "foobar" matched, for
+ * instance, a request for "f", "foo", of "foob". Such a mismatch would be
+ * caught harmlessly later.
+ *
+ * Before CVS adds a tag to val-tags, it will lock val-tags for write and
+ * verify that the tag is still not present to avoid adding it twice.
+ *
+ * NOTES
+ * This function expects its parent to handle any necessary locking of the
+ * val-tags file.
+ *
+ * INPUTS
+ * idb When this value is NULL, the val-tags file is opened in
+ * in read-only mode. When present, the val-tags file is opened
+ * in read-write mode and the DBM handle is stored in *IDB.
+ * name The tag to search for.
+ *
+ * OUTPUTS
+ * *idb The val-tags file opened for read/write, or NULL if it couldn't
+ * be opened.
+ *
+ * ERRORS
+ * Exits with an error message if the val-tags file cannot be opened for
+ * read (failure to open val-tags read/write is harmless - see below).
+ *
+ * RETURNS
+ * true 1. If NAME exists in val-tags.
+ * 2. If IDB is non-NULL and val-tags cannot be opened for write.
+ * This allows callers to ignore the harmless inability to
+ * update the val-tags cache.
+ * false If the file could be opened and the tag is not present.
+ */
+static int is_in_val_tags PROTO((DBM **idb, const char *name));
+static int
+is_in_val_tags (idb, name)
+ DBM **idb;
+ const char *name;
+{
+ DBM *db = NULL;
+ char *valtags_filename;
+ datum mytag;
+ int status;
+
+ /* Casting out const should be safe here - input datums are not
+ * written to by the myndbm functions.
+ */
+ mytag.dptr = (char *)name;
+ mytag.dsize = strlen (name);
+
+ valtags_filename = xmalloc (strlen (current_parsed_root->directory)
+ + sizeof CVSROOTADM
+ + sizeof CVSROOTADM_VALTAGS + 3);
+ sprintf (valtags_filename, "%s/%s/%s", current_parsed_root->directory,
+ CVSROOTADM, CVSROOTADM_VALTAGS);
+
+ if (idb)
+ {
+ db = dbm_open (valtags_filename, O_RDWR, 0666);
+ if (!db)
+ {
+ mode_t omask;
+
+ if (!existence_error (errno))
+ {
+ error (0, errno, "warning: cannot open %s read/write",
+ valtags_filename);
+ *idb = NULL;
+ return 1;
+ }
+
+ omask = umask (cvsumask);
+ db = dbm_open (valtags_filename, O_RDWR | O_CREAT | O_TRUNC, 0666);
+ umask (omask);
+ if (!db)
+ {
+ error (0, errno, "warning: cannot create %s",
+ valtags_filename);
+ *idb = NULL;
+ return 1;
+ }
+
+ *idb = db;
+ return 0;
+ }
+
+ *idb = db;
+ }
+ else
+ {
+ db = dbm_open (valtags_filename, O_RDONLY, 0444);
+ if (!db && !existence_error (errno))
+ error (1, errno, "cannot read %s", valtags_filename);
+ }
+
+ /* If the file merely fails to exist, we just keep going and create
+ it later if need be. */
+
+ status = 0;
+ if (db)
+ {
+ datum val;
+
+ val = dbm_fetch (db, mytag);
+ if (val.dptr != NULL)
+ /* Found. The tag is valid. */
+ status = 1;
+
+ /* FIXME: should check errors somehow (add dbm_error to myndbm.c?). */
+
+ if (!idb) dbm_close (db);
+ }
+
+ free (valtags_filename);
+ return status;
+}
+
+
+
+/* Add a tag to the CVSROOT/val-tags cache. Establishes a write lock and
+ * reverifies that the tag does not exist before adding it.
+ */
+static void add_to_val_tags PROTO((const char *name));
+static void
+add_to_val_tags (name)
+ const char *name;
+{
+ DBM *db;
+ datum mytag;
+ datum value;
+
+ if (noexec) return;
+
+ val_tags_lock (current_parsed_root->directory);
+
+ /* Check for presence again since we have a lock now. */
+ if (is_in_val_tags (&db, name))
+ {
+ clear_val_tags_lock ();
+ if (db)
+ dbm_close (db);
+ return;
+ }
+
+ /* Casting out const should be safe here - input datums are not
+ * written to by the myndbm functions.
+ */
+ mytag.dptr = (char *)name;
+ mytag.dsize = strlen (name);
+ value.dptr = "y";
+ value.dsize = 1;
+
+ if (dbm_store (db, mytag, value, DBM_REPLACE) < 0)
+ error (0, errno, "failed to store %s into val-tags", name);
+ dbm_close (db);
+
+ clear_val_tags_lock ();
+}
+
+
+
static Dtype val_direntproc PROTO ((void *, const char *, const char *,
const char *, List *));
@@ -1173,10 +1341,6 @@ tag_check_valid (name, argc, argv, local, aflag, repository)
int aflag;
char *repository;
{
- DBM *db;
- char *valtags_filename;
- int nowrite = 0;
- datum mytag;
struct val_args the_val_args;
struct saved_cwd cwd;
int which;
@@ -1199,49 +1363,12 @@ Numeric tag %s contains characters other than digits and '.'", name);
|| strcmp (name, TAG_HEAD) == 0)
return;
- /* FIXME: This routine doesn't seem to do any locking whatsoever
- (and it is called from places which don't have locks in place).
- If two processes try to write val-tags at the same time, it would
- seem like we are in trouble. */
-
- mytag.dptr = name;
- mytag.dsize = strlen (name);
-
- valtags_filename = xmalloc (strlen (current_parsed_root->directory)
- + sizeof CVSROOTADM
- + sizeof CVSROOTADM_VALTAGS + 3);
- sprintf (valtags_filename, "%s/%s/%s", current_parsed_root->directory,
- CVSROOTADM, CVSROOTADM_VALTAGS);
- db = dbm_open (valtags_filename, O_RDWR, 0666);
- if (db == NULL)
- {
- if (!existence_error (errno))
- {
- error (0, errno, "warning: cannot open %s read/write",
- valtags_filename);
- db = dbm_open (valtags_filename, O_RDONLY, 0666);
- if (db != NULL)
- nowrite = 1;
- else if (!existence_error (errno))
- error (1, errno, "cannot read %s", valtags_filename);
- }
- /* If the file merely fails to exist, we just keep going and create
- it later if need be. */
- }
- if (db != NULL)
- {
- datum val;
+ /* Verify that the tag is valid syntactically. Some later code once made
+ * assumptions about this.
+ */
+ RCS_check_tag (name);
- val = dbm_fetch (db, mytag);
- if (val.dptr != NULL)
- {
- /* Found. The tag is valid. */
- dbm_close (db);
- free (valtags_filename);
- return;
- }
- /* FIXME: should check errors somehow (add dbm_error to myndbm.c?). */
- }
+ if (is_in_val_tags (NULL, name)) return;
/* We didn't find the tag in val-tags, so look through all the RCS files
to see whether it exists there. Yes, this is expensive, but there
@@ -1286,41 +1413,11 @@ Numeric tag %s contains characters other than digits and '.'", name);
if (!the_val_args.found)
error (1, 0, "no such tag %s", name);
else
- {
/* The tags is valid but not mentioned in val-tags. Add it. */
- datum value;
-
- if (noexec || nowrite)
- {
- if (db != NULL)
- dbm_close (db);
- free (valtags_filename);
- return;
- }
+ add_to_val_tags (name);
+}
- if (db == NULL)
- {
- mode_t omask;
- omask = umask (cvsumask);
- db = dbm_open (valtags_filename, O_RDWR | O_CREAT | O_TRUNC, 0666);
- (void)umask (omask);
- if (db == NULL)
- {
- error (0, errno, "warning: cannot create %s", valtags_filename);
- free (valtags_filename);
- return;
- }
- }
- value.dptr = "y";
- value.dsize = 1;
- if (dbm_store (db, mytag, value, DBM_REPLACE) < 0)
- error (0, errno, "cannot store %s into %s", name,
- valtags_filename);
- dbm_close (db);
- }
- free (valtags_filename);
-}
/*
* Check whether a join tag is valid. This is just like
diff --git a/contrib/cvs/src/update.c b/contrib/cvs/src/update.c
index 62a6c63..6f1c937 100644
--- a/contrib/cvs/src/update.c
+++ b/contrib/cvs/src/update.c
@@ -1,6 +1,11 @@
/*
- * Copyright (c) 1992, Brian Berliner and Jeff Polk
- * Copyright (c) 1989-1992, Brian Berliner
+ * Copyright (C) 1986-2005 The Free Software Foundation, Inc.
+ *
+ * Portions Copyright (C) 1998-2005 Derek Price, Ximbiot <http://ximbiot.com>,
+ * and others.
+ *
+ * Portions Copyright (C) 1992, Brian Berliner and Jeff Polk
+ * Portions Copyright (C) 1989-1992, Brian Berliner
*
* You may distribute under the terms of the GNU General Public License as
* specified in the README file that comes with the CVS source distribution.
@@ -34,6 +39,7 @@
*/
#include "cvs.h"
+#include <assert.h>
#include "savecwd.h"
#ifdef SERVER_SUPPORT
# include "md5.h"
@@ -176,11 +182,9 @@ update (argc, argv)
break;
case 'Q':
case 'q':
-#ifdef SERVER_SUPPORT
/* The CVS 1.5 client sends these options (in addition to
Global_option requests), so we must ignore them. */
if (!server_active)
-#endif
error (1, 0,
"-q or -Q must be specified before \"%s\"",
cvs_cmd_name);
@@ -195,6 +199,7 @@ update (argc, argv)
tag = optarg;
break;
case 'D':
+ if (date) free (date);
date = Make_Date (optarg);
break;
case 'P':
@@ -514,13 +519,8 @@ do_update (argc, argv, xoptions, xtag, xdate, xforce, local, xbuild, xaflag,
argc, argv, local, which, aflag, CVS_LOCK_READ,
preload_update_dir, 1, repository);
-#ifdef SERVER_SUPPORT
- if (server_active)
- return err;
-#endif
-
/* see if we need to sleep before returning to avoid time-stamp races */
- if (last_register_time)
+ if (!server_active && last_register_time)
{
sleep_past (last_register_time);
}
@@ -676,11 +676,7 @@ update_fileproc (callerdat, finfo)
bakname = backup_file (finfo->file, vers->vn_user);
/* This behavior is sufficiently unexpected to
justify overinformativeness, I think. */
-#ifdef SERVER_SUPPORT
- if ((! really_quiet) && (! server_active))
-#else /* ! SERVER_SUPPORT */
- if (! really_quiet)
-#endif /* SERVER_SUPPORT */
+ if (!really_quiet && !server_active)
(void) printf ("(Locally modified %s moved to %s)\n",
finfo->file, bakname);
free (bakname);
@@ -695,8 +691,7 @@ update_fileproc (callerdat, finfo)
{
if (vers->ts_conflict)
{
- if (file_has_conflict (finfo, vers->ts_conflict)
- || file_has_markers (finfo))
+ if (file_has_markers (finfo))
{
write_letter (finfo, 'C');
retval = 1;
@@ -847,11 +842,7 @@ update_filesdone_proc (callerdat, err, repository, update_dir, entries)
if (unlink_file_dir (CVSADM) < 0 && !existence_error (errno))
error (0, errno, "cannot remove %s directory", CVSADM);
}
-#ifdef SERVER_SUPPORT
else if (!server_active && !pipeout)
-#else
- else if (!pipeout)
-#endif /* SERVER_SUPPORT */
{
/* If there is no CVS/Root file, add one */
if (!isfile (CVSADM_ROOT))
@@ -904,15 +895,11 @@ update_dirent_proc (callerdat, dir, repository, update_dir, entries)
is when update -d is specified, and the working directory
is gone but the subdirectory is still mentioned in
CVS/Entries). */
- if (1
-#ifdef SERVER_SUPPORT
- /* In the remote case, the client should refrain from
- sending us the directory in the first place. So we
- want to continue to give an error, so clients make
- sure to do this. */
- && !server_active
-#endif
- && !isdir (repository))
+ /* In the remote case, the client should refrain from
+ sending us the directory in the first place. So we
+ want to continue to give an error, so clients make
+ sure to do this. */
+ if (!server_active && !isdir (repository))
return R_SKIP_ALL;
if (noexec)
@@ -1200,13 +1187,10 @@ scratch_file (finfo, vers)
#endif
if (unlink_file (finfo->file) < 0 && ! existence_error (errno))
error (0, errno, "unable to remove %s", finfo->fullname);
- else
-#ifdef SERVER_SUPPORT
+ else if (!server_active)
+ {
/* skip this step when the server is running since
* server_updated should have handled it */
- if (!server_active)
-#endif
- {
/* keep the vers structure up to date in case we do a join
* - if there isn't a file, it can't very well have a version number, can it?
*/
@@ -1248,11 +1232,7 @@ checkout_file (finfo, vers_ts, adding, merging, update_server)
/* Don't screw with backup files if we're going to stdout, or if
we are the server. */
- if (!pipeout
-#ifdef SERVER_SUPPORT
- && ! server_active
-#endif
- )
+ if (!pipeout && !server_active)
{
backup = xmalloc (strlen (finfo->file)
+ sizeof (CVSADM)
@@ -1344,7 +1324,9 @@ VERS: ", 0);
for us to stat. */
if (stat (vers_ts->srcfile->path, &sb) < 0)
{
+#if defined (SERVER_SUPPORT) || defined (CLIENT_SUPPORT)
buf_free (revbuf);
+#endif /* defined (SERVER_SUPPORT) || defined (CLIENT_SUPPORT) */
error (1, errno, "cannot stat %s",
vers_ts->srcfile->path);
}
@@ -1511,8 +1493,10 @@ VERS: ", 0);
free (backup);
}
+#if defined (SERVER_SUPPORT) || defined (CLIENT_SUPPORT)
if (revbuf != NULL)
buf_free (revbuf);
+#endif /* defined (SERVER_SUPPORT) || defined (CLIENT_SUPPORT) */
return retval;
}
@@ -1713,7 +1697,9 @@ patch_file (finfo, vers_ts, docheckout, file_info, checksum)
retcode = 0;
if (! fail)
{
- char *diff_options;
+ int dargc = 0;
+ size_t darg_allocated = 0;
+ char **dargv = NULL;
/* If the client does not support the Rcs-diff command, we
send a context diff, and the client must invoke patch.
@@ -1721,16 +1707,13 @@ patch_file (finfo, vers_ts, docheckout, file_info, checksum)
new approach only requires running diff in the server; the
client can handle everything without invoking an external
program. */
- if (! rcs_diff_patches)
- {
+ if (!rcs_diff_patches)
/* We use -c, not -u, because that is what CVS has
traditionally used. Kind of a moot point, now that
Rcs-diff is preferred, so there is no point in making
the compatibility issues worse. */
- diff_options = "-c";
- }
+ run_add_arg_p (&dargc, &darg_allocated, &dargv, "-c");
else
- {
/* Now that diff is librarified, we could be passing -a if
we wanted to. However, it is unclear to me whether we
would want to. Does diff -a, in any significant
@@ -1740,10 +1723,11 @@ patch_file (finfo, vers_ts, docheckout, file_info, checksum)
'binary'. Conversely, do they tend to be much larger
in the bad cases? This needs some more
thought/investigation, I suspect. */
-
- diff_options = "-n";
- }
- retcode = diff_exec (file1, file2, NULL, NULL, diff_options, finfo->file);
+ run_add_arg_p (&dargc, &darg_allocated, &dargv, "-n");
+ retcode = diff_exec (file1, file2, NULL, NULL, dargc, dargv,
+ finfo->file);
+ run_arg_free_p (dargc, dargv);
+ free (dargv);
/* A retcode of 0 means no differences. 1 means some differences. */
if (retcode != 0
@@ -1934,6 +1918,47 @@ write_letter (finfo, letter)
+/* Reregister a file after a merge. */
+static void
+RegisterMerge PROTO((struct file_info *finfo, Vers_TS *vers,
+ const char *backup, int has_conflicts));
+static void
+RegisterMerge (finfo, vers, backup, has_conflicts)
+ struct file_info *finfo;
+ Vers_TS *vers;
+ const char *backup;
+ int has_conflicts;
+{
+ /* This file is the result of a merge, which means that it has
+ been modified. We use a special timestamp string which will
+ not compare equal to any actual timestamp. */
+ char *cp = NULL;
+
+ if (has_conflicts)
+ {
+ time (&last_register_time);
+ cp = time_stamp (finfo->file);
+ }
+ Register (finfo->entries, finfo->file, vers->vn_rcs ? vers->vn_rcs : "0",
+ "Result of merge", vers->options, vers->tag, vers->date, cp);
+ if (cp)
+ free (cp);
+
+#ifdef SERVER_SUPPORT
+ /* Send the new contents of the file before the message. If we
+ wanted to be totally correct, we would have the client write
+ the message only after the file has safely been written. */
+ if (server_active)
+ {
+ server_copy_file (finfo->file, finfo->update_dir, finfo->repository,
+ backup);
+ server_updated (finfo, vers, SERVER_MERGED, (mode_t) -1, NULL, NULL);
+ }
+#endif
+}
+
+
+
/*
* Do all the magic associated with a file which needs to be merged
*/
@@ -1947,6 +1972,8 @@ merge_file (finfo, vers)
int retcode = 0;
int retval;
+ assert (vers->vn_user);
+
/*
* The users currently modified file is moved to a backup file name
* ".#filename.version", so that it will stay around for a few days
@@ -1984,13 +2011,21 @@ merge_file (finfo, vers)
thought needs to go into this, and in the meantime it is safe
to treat any such mismatch as an automatic conflict. -twp */
-#ifdef SERVER_SUPPORT
- if (server_active)
- server_copy_file (finfo->file, finfo->update_dir,
- finfo->repository, backup);
-#endif
+ retcode = RCS_checkout (finfo->rcs, finfo->file,
+ vers->vn_rcs, vers->tag,
+ vers->options, NULL, NULL, NULL);
+ if (retcode)
+ {
+ error (0, 0, "failed to check out `%s' file", finfo->fullname);
+ error (0, 0, "restoring `%s' from backup file `%s'",
+ finfo->fullname, backup);
+ rename_file (backup, finfo->file);
+ retval = 1;
+ goto out;
+ }
+ xchmod (finfo->file, 1);
- status = checkout_file (finfo, vers, 0, 1, 1);
+ RegisterMerge (finfo, vers, backup, 1);
/* Is there a better term than "nonmergeable file"? What we
really mean is, not something that CVS cannot or does not
@@ -2024,24 +2059,6 @@ merge_file (finfo, vers)
if (strcmp (vers->options, "-V4") == 0)
vers->options[0] = '\0';
- /* This file is the result of a merge, which means that it has
- been modified. We use a special timestamp string which will
- not compare equal to any actual timestamp. */
- {
- char *cp = 0;
-
- if (status)
- {
- (void) time (&last_register_time);
- cp = time_stamp (finfo->file);
- }
- Register (finfo->entries, finfo->file, vers->vn_rcs,
- "Result of merge", vers->options, vers->tag,
- vers->date, cp);
- if (cp)
- free (cp);
- }
-
/* fix up the vers structure, in case it is used by join */
if (join_rev1)
{
@@ -2052,19 +2069,7 @@ merge_file (finfo, vers)
vers->vn_user = xstrdup (vers->vn_rcs);
}
-#ifdef SERVER_SUPPORT
- /* Send the new contents of the file before the message. If we
- wanted to be totally correct, we would have the client write
- the message only after the file has safely been written. */
- if (server_active)
- {
- server_copy_file (finfo->file, finfo->update_dir, finfo->repository,
- backup);
- server_updated (finfo, vers, SERVER_MERGED,
- (mode_t) -1, (unsigned char *) NULL,
- (struct buffer *) NULL);
- }
-#endif
+ RegisterMerge (finfo, vers, backup, status);
/* FIXME: the noexec case is broken. RCS_merge could be doing the
xcmp on the temporary files without much hassle, I think. */
@@ -2658,31 +2663,7 @@ join_file (finfo, vers)
RCS_checkout above, and we aren't running as the server.
However, that is not the normal case, and calling Register
again won't cost much in that case. */
- {
- char *cp = 0;
-
- if (status)
- {
- (void) time (&last_register_time);
- cp = time_stamp (finfo->file);
- }
- Register (finfo->entries, finfo->file,
- vers->vn_rcs ? vers->vn_rcs : "0", "Result of merge",
- vers->options, vers->tag, vers->date, cp);
- if (cp)
- free(cp);
- }
-
-#ifdef SERVER_SUPPORT
- if (server_active)
- {
- server_copy_file (finfo->file, finfo->update_dir, finfo->repository,
- backup);
- server_updated (finfo, vers, SERVER_MERGED,
- (mode_t) -1, (unsigned char *) NULL,
- (struct buffer *) NULL);
- }
-#endif
+ RegisterMerge (finfo, vers, backup, status);
out:
free (rev1);
diff --git a/contrib/cvs/src/vers_ts.c b/contrib/cvs/src/vers_ts.c
index 69eaa4c..2115dd5 100644
--- a/contrib/cvs/src/vers_ts.c
+++ b/contrib/cvs/src/vers_ts.c
@@ -1,6 +1,11 @@
/*
- * Copyright (c) 1992, Brian Berliner and Jeff Polk
- * Copyright (c) 1989-1992, Brian Berliner
+ * Copyright (C) 1986-2005 The Free Software Foundation, Inc.
+ *
+ * Portions Copyright (C) 1998-2005 Derek Price, Ximbiot <http://ximbiot.com>,
+ * and others.
+ *
+ * Portions Copyright (C) 1992, Brian Berliner and Jeff Polk
+ * Portions Copyright (C) 1989-1992, Brian Berliner
*
* You may distribute under the terms of the GNU General Public License as
* specified in the README file that comes with the CVS source distribution.
@@ -35,6 +40,7 @@ Version_TS (finfo, options, tag, date, force_tag_match, set_time)
Vers_TS *vers_ts;
struct stickydirtag *sdtp;
Entnode *entdata;
+ char *rcsexpand = NULL;
#ifdef UTIME_EXPECTS_WRITABLE
int change_it_back = 0;
@@ -106,30 +112,39 @@ Version_TS (finfo, options, tag, date, force_tag_match, set_time)
}
}
+ /* Always look up the RCS keyword mode when we have an RCS archive. It
+ * will either be needed as a default or to avoid allowing the -k options
+ * specified on the command line from overriding binary mode (-kb).
+ */
+ if (finfo->rcs != NULL)
+ rcsexpand = RCS_getexpand (finfo->rcs);
+
/*
* -k options specified on the command line override (and overwrite)
- * options stored in the entries file
+ * options stored in the entries file and default options from the RCS
+ * archive, except for binary mode (-kb).
*/
if (options && *options != '\0')
- vers_ts->options = xstrdup (options);
- else if (!vers_ts->options || *vers_ts->options == '\0')
{
- if (finfo->rcs != NULL)
- {
- /* If no keyword expansion was specified on command line,
- use whatever was in the rcs file (if there is one). This
- is how we, if we are the server, tell the client whether
- a file is binary. */
- char *rcsexpand = RCS_getexpand (finfo->rcs);
- if (rcsexpand != NULL)
- {
- if (vers_ts->options != NULL)
- free (vers_ts->options);
- vers_ts->options = xmalloc (strlen (rcsexpand) + 3);
- strcpy (vers_ts->options, "-k");
- strcat (vers_ts->options, rcsexpand);
- }
- }
+ if (vers_ts->options != NULL)
+ free (vers_ts->options);
+ if (rcsexpand != NULL && strcmp (rcsexpand, "b") == 0)
+ vers_ts->options = xstrdup ("-kb");
+ else
+ vers_ts->options = xstrdup (options);
+ }
+ else if ((!vers_ts->options || *vers_ts->options == '\0')
+ && rcsexpand != NULL)
+ {
+ /* If no keyword expansion was specified on command line,
+ use whatever was in the rcs file (if there is one). This
+ is how we, if we are the server, tell the client whether
+ a file is binary. */
+ if (vers_ts->options != NULL)
+ free (vers_ts->options);
+ vers_ts->options = xmalloc (strlen (rcsexpand) + 3);
+ strcpy (vers_ts->options, "-k");
+ strcat (vers_ts->options, rcsexpand);
}
if (!vers_ts->options)
vers_ts->options = xstrdup ("");
@@ -287,6 +302,13 @@ time_stamp_server (file, vers_ts, entdata)
else if (entdata->timestamp
&& entdata->timestamp[0] == '=')
mark_unchanged (vers_ts);
+ else if (entdata->conflict
+ && entdata->conflict[0] == '=')
+ {
+ /* These just need matching content. Might as well minimize it. */
+ vers_ts->ts_user = xstrdup ("");
+ vers_ts->ts_conflict = xstrdup ("");
+ }
else if (entdata->timestamp
&& (entdata->timestamp[0] == 'M'
|| entdata->timestamp[0] == 'D')
diff --git a/contrib/cvs/src/version.c b/contrib/cvs/src/version.c
index 8c76a16..09f99f4 100644
--- a/contrib/cvs/src/version.c
+++ b/contrib/cvs/src/version.c
@@ -1,8 +1,12 @@
/*
- * 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
+ * Copyright (C) 1986-2005 The Free Software Foundation, Inc.
+ *
+ * Portions Copyright (C) 1998-2005 Derek Price, Ximbiot <http://ximbiot.com>,
+ * and others.
+ *
+ * Portions Copyright (C) 1994 david d `zoo' zuhn
+ * Portions Copyright (C) 1992, Brian Berliner and Jeff Polk
+ * Portions 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.
@@ -53,10 +57,8 @@ version (argc, argv)
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
diff --git a/contrib/cvs/src/watch.c b/contrib/cvs/src/watch.c
index 58442c4..0ef987c 100644
--- a/contrib/cvs/src/watch.c
+++ b/contrib/cvs/src/watch.c
@@ -18,14 +18,13 @@
const char *const watch_usage[] =
{
"Usage: %s %s {on|off|add|remove} [-lR] [-a <action>]... [<path>]...\n",
- "on/off: turn on/off read-only checkouts of files\n",
- "add/remove: add or remove notification on actions\n",
- "-l (on/off/add/remove): Local directory only, not recursive\n",
- "-R (on/off/add/remove): Process directories recursively (default)\n",
- "-a (add/remove): Specify what actions, one of\n",
- " edit,unedit,commit,all,none (defaults to all, multiple -a\n",
- " options are permitted)\n",
- "(Specify the --help global option for a list of other help options)\n",
+ "on/off: Turn on/off read-only checkouts of files.\n",
+ "add/remove: Add or remove notification on actions.\n",
+ "-l (on/off/add/remove): Local directory only, not recursive.\n",
+ "-R (on/off/add/remove): Process directories recursively (default).\n",
+ "-a (add/remove): Specify what actions, one of: `edit', `unedit',\n",
+ " `commit', `all', or `none' (defaults to `all').\n",
+ "(Specify the --help global option for a list of other help options.)\n",
NULL
};
@@ -407,10 +406,10 @@ watch (argc, argv)
static const char *const watchers_usage[] =
{
- "Usage: %s %s [-lR] [files...]\n",
- "\t-l\tProcess this directory only (not recursive).\n",
- "\t-R\tProcess directories recursively.\n",
- "(Specify the --help global option for a list of other help options)\n",
+ "Usage: %s %s [-lR] [<file>]...\n",
+ "-l\tProcess this directory only (not recursive).\n",
+ "-R\tProcess directories recursively (default).\n",
+ "(Specify the --help global option for a list of other help options.)\n",
NULL
};
diff --git a/contrib/cvs/src/wrapper.c b/contrib/cvs/src/wrapper.c
index 548b3a5..512e96c 100644
--- a/contrib/cvs/src/wrapper.c
+++ b/contrib/cvs/src/wrapper.c
@@ -93,9 +93,7 @@ void wrap_setup()
else
wrap_setup_already_done = 1;
-#ifdef CLIENT_SUPPORT
if (!current_parsed_root->isremote)
-#endif
{
char *file;
@@ -240,6 +238,7 @@ wrap_unparse_rcs_options (line, first_call_p)
* Remove fmt str specifier other than %% or %s. And allow
* only max_s %s specifiers
*/
+void
wrap_clean_fmt_str(char *fmt, int max_s)
{
while (*fmt) {
@@ -257,7 +256,6 @@ wrap_clean_fmt_str(char *fmt, int max_s)
}
fmt++;
}
- return;
}
/*
@@ -418,7 +416,8 @@ wrap_add (line, isTemp)
switch(opt){
case 'f':
/* Before this is reenabled, need to address the problem in
- commit.c (see http://www.cvshome.org/docs/infowrapper.html). */
+ commit.c (see
+ http://ximbiot.com/cvs/cvshome/docs/infowrapper.html). */
error (1, 0,
"-t/-f wrappers not supported by this version of CVS");
@@ -432,7 +431,8 @@ wrap_add (line, isTemp)
break;
case 't':
/* Before this is reenabled, need to address the problem in
- commit.c (see http://www.cvshome.org/docs/infowrapper.html). */
+ commit.c (see
+ http://ximbiot.com/cvs/cvshome/docs/infowrapper.html). */
error (1, 0,
"-t/-f wrappers not supported by this version of CVS");
diff --git a/contrib/cvs/src/zlib.c b/contrib/cvs/src/zlib.c
index 32c95e5..46ed0e6 100644
--- a/contrib/cvs/src/zlib.c
+++ b/contrib/cvs/src/zlib.c
@@ -361,18 +361,10 @@ compress_buffer_shutdown_input (buf)
struct compress_buffer *cb = (struct compress_buffer *) buf->closure;
int zstatus;
- /* Pick up any trailing data, such as the checksum. */
- while (1)
- {
- int status, nread;
- char buf[100];
-
- status = compress_buffer_input (cb, buf, 0, sizeof buf, &nread);
- if (status == -1)
- break;
- if (status != 0)
- return status;
- }
+ /* Don't make any attempt to pick up trailing data since we are shutting
+ * down. If the client doesn't know we are shutting down, we might not
+ * see the EOF we are expecting.
+ */
zstatus = inflateEnd (&cb->zstr);
if (zstatus != Z_OK)
OpenPOWER on IntegriCloud